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 --- bibtex/bst/context/cont-ab.bst | 1223 + bibtex/bst/context/cont-au.bst | 1223 + bibtex/bst/context/cont-no.bst | 1223 + bibtex/bst/context/cont-ti.bst | 1223 + context/data/scite/cont-cs-scite.properties | 1 + context/data/scite/cont-cz-scite.properties | 76 + context/data/scite/cont-de-scite.properties | 1 + context/data/scite/cont-en-scite.properties | 1 + context/data/scite/cont-fr-scite.properties | 1 + context/data/scite/cont-it-scite.properties | 1 + context/data/scite/cont-nl-scite.properties | 1 + context/data/scite/cont-pe-scite.properties | 1 + context/data/scite/cont-ro-scite.properties | 1 + context/data/scite/cont-xx-scite.properties | 178 + context/data/scite/context.properties | 559 + context/data/scite/cscite.rme | 50 + context/data/scite/latex-scite.properties | 2 + context/data/scite/metafun-scite.properties | 19 + context/data/scite/scite-ctx.lua | 838 + context/data/scite/scite-ctx.properties | 155 + context/data/scite/scite-ctx.readme | 19 + context/data/texfont/type-buy.dat | 146 + context/data/texfont/type-fsf.dat | 25 + context/data/texfont/type-ghz.dat | 78 + context/data/texfont/type-tmf.dat | 75 + context/data/textadept/context.lua | 710 + context/data/texworks/TUG/TeXworks.ini | 18 + context/data/texworks/completion/tw-context.txt | 1 + .../configuration/auto-indent-patterns.txt | 14 + .../texworks/configuration/delimiter-pairs.txt | 12 + .../texworks/configuration/smart-quotes-modes.txt | 21 + .../texworks/configuration/syntax-patterns.txt | 42 + .../data/texworks/configuration/tag-patterns.txt | 33 + .../texworks/configuration/texworks-config.txt | 22 + context/data/texworks/configuration/tools.ini | 35 + context/data/texworks/texworks-context.rme | 2 + context/data/texworks/texworks-setup.ini | 2 + doc/context/document/general/manuals/mreadme.pdf | Bin 0 -> 85996 bytes doc/context/document/general/manuals/tiptrick.pdf | Bin 0 -> 30607 bytes doc/context/manuals/allkind/mcommon.tex | 199 + doc/context/manuals/allkind/mreadme.tex | 361 + doc/fonts/hoekwater/koeieletters/koeieletters.rme | 45 + fonts/afm/hoekwater/context/contnav.afm | 44 + .../koeieletters/koeieletters-contour.afm | 879 + fonts/afm/hoekwater/koeieletters/koeieletters.afm | 879 + .../hoekwater/koeieletters/koeielogos-contour.afm | 47 + fonts/afm/hoekwater/koeieletters/koeielogos.afm | 47 + fonts/afm/hoekwater/koeieletters/koeien-ex.afm | 879 + fonts/afm/hoekwater/koeieletters/koeien-mi.afm | 879 + fonts/afm/hoekwater/koeieletters/koeien-sy.afm | 879 + fonts/afm/jmn/hans/hans-sh.afm | 164 + fonts/afm/jmn/hans/hans.afm | 164 + fonts/cid/fontforge/Adobe-CNS1-4.cidmap | 17467 +++ fonts/cid/fontforge/Adobe-GB1-4.cidmap | 13779 ++ fonts/cid/fontforge/Adobe-Identity-0.cidmap | 2 + fonts/cid/fontforge/Adobe-Japan1-5.cidmap | 13691 ++ fonts/cid/fontforge/Adobe-Japan1-6.cidmap | 15489 ++ fonts/cid/fontforge/Adobe-Japan2-0.cidmap | 4223 + fonts/cid/fontforge/Adobe-Korea1-2.cidmap | 8543 ++ fonts/enc/dvips/context/cmin.enc | 258 + fonts/enc/dvips/context/cmit.enc | 258 + fonts/enc/dvips/context/cmitt.enc | 258 + fonts/enc/dvips/context/cmrm.enc | 258 + fonts/enc/dvips/context/cmsc.enc | 258 + fonts/enc/dvips/context/cmtt.enc | 258 + fonts/enc/dvips/context/ec-2004.enc | 82 + fonts/enc/dvips/context/q-8r.enc | 264 + fonts/enc/dvips/context/teff-trinite.enc | 260 + fonts/enc/dvips/jmn/hans.enc | 258 + fonts/enc/pdftex/context/koeieletters-ex.enc | 259 + fonts/enc/pdftex/context/koeieletters-mi.enc | 271 + fonts/enc/pdftex/context/koeieletters-sy.enc | 271 + fonts/enc/pdftex/context/koeieletters.enc | 271 + fonts/enc/pdftex/context/koeielogos.enc | 258 + fonts/fea/context/greek-babel.fea | 294 + fonts/fea/context/test-features.fea | 20 + fonts/fea/context/texhistoric.fea | 42 + fonts/fea/context/verbose-digits.fea | 36 + fonts/map/dvips/context/contnav.map | 1 + fonts/map/dvips/jmn/hans.map | 2 + fonts/map/luatex/context/demo-font.lum | 70 + fonts/map/pdftex/context/8r-base.map | 135 + fonts/map/pdftex/context/ec-base.map | 135 + fonts/map/pdftex/context/ec-os-public-lm.map | 69 + fonts/map/pdftex/context/koeieletters.map | 8 + fonts/map/pdftex/context/mkiv-base.map | 252 + fonts/map/pdftex/context/mkiv-px.map | 51 + fonts/map/pdftex/context/mkiv-tx.map | 94 + fonts/map/pdftex/context/original-adobe-euro.map | 25 + fonts/map/pdftex/context/original-ams-base.map | 47 + fonts/map/pdftex/context/original-ams-cmr.map | 97 + fonts/map/pdftex/context/original-ams-euler.map | 25 + fonts/map/pdftex/context/original-base.map | 63 + .../map/pdftex/context/original-context-symbol.map | 3 + fonts/map/pdftex/context/original-dummy.map | 1 + fonts/map/pdftex/context/original-empty.map | 4 + .../context/original-micropress-informal.map | 7 + fonts/map/pdftex/context/original-public-csr.map | 56 + fonts/map/pdftex/context/original-public-lm.map | 182 + fonts/map/pdftex/context/original-public-plr.map | 77 + fonts/map/pdftex/context/original-public-vnr.map | 59 + fonts/map/pdftex/context/original-vogel-symbol.map | 2 + fonts/map/pdftex/context/original-wasy.map | 7 + fonts/map/pdftex/context/original-youngryu-px.map | 51 + fonts/map/pdftex/context/original-youngryu-tx.map | 94 + fonts/map/pdftex/context/qx-base.map | 55 + fonts/map/pdftex/context/qx-os-public-lm.map | 69 + fonts/map/pdftex/context/t5-base.map | 72 + fonts/map/pdftex/context/t5-os-public-lm.map | 69 + fonts/map/pdftex/context/texnansi-base.map | 142 + fonts/map/pdftex/context/texnansi-os-public-lm.map | 69 + fonts/misc/xetex/fontmapping/tlig.map | 16 + fonts/misc/xetex/fontmapping/tlig.tec | Bin 0 -> 199 bytes fonts/pfm/hoekwater/context/contnav.pfm | Bin 0 -> 482 bytes fonts/pfm/hoekwater/context/koeieletters.pfm | Bin 0 -> 2798 bytes fonts/pfm/jmn/hans/hans-sh.pfm | Bin 0 -> 754 bytes fonts/pfm/jmn/hans/hans.pfm | Bin 0 -> 748 bytes fonts/tfm/hoekwater/context/contnav.tfm | Bin 0 -> 1032 bytes .../hoekwater/koeieletters/koeielett-contour.tfm | Bin 0 -> 5604 bytes fonts/tfm/hoekwater/koeieletters/koeielett.tfm | Bin 0 -> 5604 bytes .../tfm/hoekwater/koeieletters/koeieletter-ex.tfm | Bin 0 -> 916 bytes .../tfm/hoekwater/koeieletters/koeieletter-mi.tfm | Bin 0 -> 3452 bytes .../tfm/hoekwater/koeieletters/koeieletter-sy.tfm | Bin 0 -> 1032 bytes .../tfm/hoekwater/koeieletters/koeieletter-syx.tfm | Bin 0 -> 1028 bytes .../koeieletters/koeieletters-contour.tfm | Bin 0 -> 1472 bytes fonts/tfm/hoekwater/koeieletters/koeieletters.tfm | Bin 0 -> 4548 bytes fonts/tfm/hoekwater/koeieletters/koeielettx.tfm | Bin 0 -> 5600 bytes .../hoekwater/koeieletters/koeielogos-contour.tfm | Bin 0 -> 412 bytes fonts/tfm/hoekwater/koeieletters/koeielogos.tfm | Bin 0 -> 412 bytes fonts/tfm/hoekwater/koeieletters/koeien-ex.tfm | Bin 0 -> 824 bytes fonts/tfm/hoekwater/koeieletters/koeien-mi.tfm | Bin 0 -> 792 bytes fonts/tfm/hoekwater/koeieletters/koeien-sy.tfm | Bin 0 -> 964 bytes fonts/tfm/jmn/hans/hans-sh.tfm | Bin 0 -> 1536 bytes fonts/tfm/jmn/hans/hans.tfm | Bin 0 -> 1512 bytes fonts/tfm/public/marvosym/fmvr8x.tfm | Bin 0 -> 1756 bytes .../hoekwater/lm/lmtypewriter10-regular.ttf | Bin 0 -> 128340 bytes fonts/type1/hoekwater/context/contnav.pfb | Bin 0 -> 6695 bytes .../koeieletters/koeieletters-contour.pfb | Bin 0 -> 44353 bytes .../type1/hoekwater/koeieletters/koeieletters.pfb | Bin 0 -> 323625 bytes .../hoekwater/koeieletters/koeielogos-contour.pfb | Bin 0 -> 41208 bytes fonts/type1/hoekwater/koeieletters/koeielogos.pfb | Bin 0 -> 255916 bytes fonts/type1/jmn/hans/hans-sh.pfb | Bin 0 -> 25050 bytes fonts/type1/jmn/hans/hans.pfb | Bin 0 -> 17187 bytes .../vf/hoekwater/koeieletters/koeielett-contour.vf | Bin 0 -> 1140 bytes fonts/vf/hoekwater/koeieletters/koeielett.vf | Bin 0 -> 1124 bytes fonts/vf/hoekwater/koeieletters/koeieletter-ex.vf | Bin 0 -> 388 bytes fonts/vf/hoekwater/koeieletters/koeieletter-mi.vf | Bin 0 -> 520 bytes fonts/vf/hoekwater/koeieletters/koeieletter-sy.vf | Bin 0 -> 416 bytes fonts/vf/hoekwater/koeieletters/koeieletter-syx.vf | Bin 0 -> 416 bytes fonts/vf/hoekwater/koeieletters/koeielettx.vf | Bin 0 -> 1136 bytes metapost/context/base/metafun.mp | 75 + metapost/context/base/mp-back.mp | 206 + metapost/context/base/mp-base.mp | 558 + metapost/context/base/mp-butt.mp | 75 + metapost/context/base/mp-char.mp | 999 + metapost/context/base/mp-chem.mp | 761 + metapost/context/base/mp-core.mp | 1418 + metapost/context/base/mp-figs.mp | 50 + metapost/context/base/mp-fobg.mp | 88 + metapost/context/base/mp-form.mp | 403 + metapost/context/base/mp-func.mp | 59 + metapost/context/base/mp-grid.mp | 145 + metapost/context/base/mp-grph.mp | 296 + metapost/context/base/mp-mlib.mp | 282 + metapost/context/base/mp-page.mp | 474 + metapost/context/base/mp-shap.mp | 307 + metapost/context/base/mp-spec.mp | 776 + metapost/context/base/mp-step.mp | 320 + metapost/context/base/mp-symb.mp | 351 + metapost/context/base/mp-text.mp | 269 + metapost/context/base/mp-tool.mp | 2566 + metapost/context/base/mp-txts.mp | 67 + metapost/context/font/punkfont.mp | 863 + scripts/context/lua/luatools.lua | 8185 + scripts/context/lua/luatools.rme | 3 + scripts/context/lua/mtx-babel.lua | 430 + scripts/context/lua/mtx-cache.lua | 96 + scripts/context/lua/mtx-chars.lua | 322 + scripts/context/lua/mtx-check.lua | 143 + scripts/context/lua/mtx-context.lua | 1554 + scripts/context/lua/mtx-convert.lua | 139 + scripts/context/lua/mtx-fonts.lua | 345 + scripts/context/lua/mtx-grep.lua | 114 + scripts/context/lua/mtx-interface.lua | 274 + scripts/context/lua/mtx-metatex.lua | 69 + scripts/context/lua/mtx-modules.lua | 167 + scripts/context/lua/mtx-mptopdf.lua | 127 + scripts/context/lua/mtx-mtxworks.lua | 14 + scripts/context/lua/mtx-package.lua | 68 + scripts/context/lua/mtx-patterns.lua | 366 + scripts/context/lua/mtx-profile.lua | 170 + scripts/context/lua/mtx-scite.lua | 166 + scripts/context/lua/mtx-server-ctx-fonttest.lua | 733 + scripts/context/lua/mtx-server-ctx-help.lua | 665 + scripts/context/lua/mtx-server-ctx-startup.lua | 39 + scripts/context/lua/mtx-server.lua | 361 + scripts/context/lua/mtx-texworks.lua | 99 + scripts/context/lua/mtx-timing.lua | 193 + scripts/context/lua/mtx-tools.lua | 176 + scripts/context/lua/mtx-unzip.lua | 101 + scripts/context/lua/mtx-update.lua | 580 + scripts/context/lua/mtx-watch.lua | 382 + scripts/context/lua/mtxrun.lua | 12639 ++ scripts/context/lua/mtxrun.rme | 18 + scripts/context/lua/x-ldx.lua | 322 + scripts/context/perl/makempy.pl | 361 + scripts/context/perl/mptopdf.pl | 160 + scripts/context/perl/path_tre.pm | 36 + scripts/context/perl/pdftrimwhite.pl | 525 + scripts/context/perl/texfind.pl | 270 + scripts/context/perl/texfont.pl | 1373 + scripts/context/ruby/base/ctx.rb | 462 + scripts/context/ruby/base/exa.rb | 407 + scripts/context/ruby/base/file.rb | 150 + scripts/context/ruby/base/kpse.rb | 389 + scripts/context/ruby/base/kpse/drb.rb | 57 + scripts/context/ruby/base/kpse/soap.rb | 79 + scripts/context/ruby/base/kpse/trees.rb | 84 + scripts/context/ruby/base/kpsedirect.rb | 34 + scripts/context/ruby/base/kpsefast.rb | 934 + scripts/context/ruby/base/kpseremote.rb | 116 + scripts/context/ruby/base/kpserunner.rb | 87 + scripts/context/ruby/base/logger.rb | 104 + scripts/context/ruby/base/merge.rb | 139 + scripts/context/ruby/base/mp.rb | 167 + scripts/context/ruby/base/pdf.rb | 75 + scripts/context/ruby/base/state.rb | 75 + scripts/context/ruby/base/switch.rb | 635 + scripts/context/ruby/base/system.rb | 121 + scripts/context/ruby/base/tex.rb | 2299 + scripts/context/ruby/base/texutil.rb | 1097 + scripts/context/ruby/base/tool.rb | 291 + scripts/context/ruby/base/variables.rb | 132 + scripts/context/ruby/concheck.rb | 471 + scripts/context/ruby/ctxtools.rb | 2785 + scripts/context/ruby/fcd_start.rb | 472 + scripts/context/ruby/graphics/gs.rb | 684 + scripts/context/ruby/graphics/inkscape.rb | 112 + scripts/context/ruby/graphics/magick.rb | 161 + scripts/context/ruby/imgtopdf.rb | 86 + scripts/context/ruby/mpstools.rb | 7 + scripts/context/ruby/mtxtools.rb | 475 + scripts/context/ruby/pdftools.rb | 861 + scripts/context/ruby/pstopdf.rb | 533 + scripts/context/ruby/rlxtools.rb | 368 + scripts/context/ruby/rscortool.rb | 63 + scripts/context/ruby/rsfiltool.rb | 341 + scripts/context/ruby/rslibtool.rb | 114 + scripts/context/ruby/runtools.rb | 506 + scripts/context/ruby/texexec.rb | 792 + scripts/context/ruby/texmfstart.rb | 1277 + scripts/context/ruby/texsync.rb | 206 + scripts/context/ruby/textools.rb | 1033 + scripts/context/ruby/texutil.rb | 93 + scripts/context/ruby/tmftools.rb | 165 + scripts/context/ruby/xmltools.rb | 656 + scripts/context/stubs/mswin/context.exe | Bin 0 -> 6144 bytes scripts/context/stubs/mswin/luatools.exe | Bin 0 -> 6144 bytes scripts/context/stubs/mswin/luatools.lua | 8185 + scripts/context/stubs/mswin/metatex.exe | Bin 0 -> 6144 bytes scripts/context/stubs/mswin/mtxrun.dll | Bin 0 -> 9216 bytes scripts/context/stubs/mswin/mtxrun.exe | Bin 0 -> 6144 bytes scripts/context/stubs/mswin/mtxrun.lua | 12639 ++ scripts/context/stubs/mswin/texexec.exe | Bin 0 -> 6144 bytes scripts/context/stubs/mswin/texmfstart.exe | Bin 0 -> 6144 bytes scripts/context/stubs/source/mtxrun_dll.c | 221 + scripts/context/stubs/source/mtxrun_exe.c | 8 + scripts/context/stubs/source/readme.txt | 36 + scripts/context/stubs/unix/context | 2 + scripts/context/stubs/unix/luatools | 8185 + scripts/context/stubs/unix/metatex | 2 + scripts/context/stubs/unix/mtxrun | 12639 ++ scripts/context/stubs/unix/texexec | 2 + scripts/context/stubs/unix/texmfstart | 2 + 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 + web2c/context.cnf | 259 + web2c/contextcnf.lua | 38 + web2c/natural.tcx | 181 + 1667 files changed, 1181101 insertions(+) create mode 100644 bibtex/bst/context/cont-ab.bst create mode 100644 bibtex/bst/context/cont-au.bst create mode 100644 bibtex/bst/context/cont-no.bst create mode 100644 bibtex/bst/context/cont-ti.bst create mode 100644 context/data/scite/cont-cs-scite.properties create mode 100644 context/data/scite/cont-cz-scite.properties create mode 100644 context/data/scite/cont-de-scite.properties create mode 100644 context/data/scite/cont-en-scite.properties create mode 100644 context/data/scite/cont-fr-scite.properties create mode 100644 context/data/scite/cont-it-scite.properties create mode 100644 context/data/scite/cont-nl-scite.properties create mode 100644 context/data/scite/cont-pe-scite.properties create mode 100644 context/data/scite/cont-ro-scite.properties create mode 100644 context/data/scite/cont-xx-scite.properties create mode 100644 context/data/scite/context.properties create mode 100644 context/data/scite/cscite.rme create mode 100644 context/data/scite/latex-scite.properties create mode 100644 context/data/scite/metafun-scite.properties create mode 100644 context/data/scite/scite-ctx.lua create mode 100644 context/data/scite/scite-ctx.properties create mode 100644 context/data/scite/scite-ctx.readme create mode 100644 context/data/texfont/type-buy.dat create mode 100644 context/data/texfont/type-fsf.dat create mode 100644 context/data/texfont/type-ghz.dat create mode 100644 context/data/texfont/type-tmf.dat create mode 100644 context/data/textadept/context.lua create mode 100644 context/data/texworks/TUG/TeXworks.ini create mode 100644 context/data/texworks/completion/tw-context.txt create mode 100644 context/data/texworks/configuration/auto-indent-patterns.txt create mode 100644 context/data/texworks/configuration/delimiter-pairs.txt create mode 100644 context/data/texworks/configuration/smart-quotes-modes.txt create mode 100644 context/data/texworks/configuration/syntax-patterns.txt create mode 100644 context/data/texworks/configuration/tag-patterns.txt create mode 100644 context/data/texworks/configuration/texworks-config.txt create mode 100644 context/data/texworks/configuration/tools.ini create mode 100644 context/data/texworks/texworks-context.rme create mode 100644 context/data/texworks/texworks-setup.ini create mode 100644 doc/context/document/general/manuals/mreadme.pdf create mode 100644 doc/context/document/general/manuals/tiptrick.pdf create mode 100644 doc/context/manuals/allkind/mcommon.tex create mode 100644 doc/context/manuals/allkind/mreadme.tex create mode 100644 doc/fonts/hoekwater/koeieletters/koeieletters.rme create mode 100644 fonts/afm/hoekwater/context/contnav.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeieletters-contour.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeieletters.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeielogos-contour.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeielogos.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeien-ex.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeien-mi.afm create mode 100644 fonts/afm/hoekwater/koeieletters/koeien-sy.afm create mode 100644 fonts/afm/jmn/hans/hans-sh.afm create mode 100644 fonts/afm/jmn/hans/hans.afm create mode 100644 fonts/cid/fontforge/Adobe-CNS1-4.cidmap create mode 100644 fonts/cid/fontforge/Adobe-GB1-4.cidmap create mode 100644 fonts/cid/fontforge/Adobe-Identity-0.cidmap create mode 100644 fonts/cid/fontforge/Adobe-Japan1-5.cidmap create mode 100644 fonts/cid/fontforge/Adobe-Japan1-6.cidmap create mode 100644 fonts/cid/fontforge/Adobe-Japan2-0.cidmap create mode 100644 fonts/cid/fontforge/Adobe-Korea1-2.cidmap create mode 100644 fonts/enc/dvips/context/cmin.enc create mode 100644 fonts/enc/dvips/context/cmit.enc create mode 100644 fonts/enc/dvips/context/cmitt.enc create mode 100644 fonts/enc/dvips/context/cmrm.enc create mode 100644 fonts/enc/dvips/context/cmsc.enc create mode 100644 fonts/enc/dvips/context/cmtt.enc create mode 100644 fonts/enc/dvips/context/ec-2004.enc create mode 100644 fonts/enc/dvips/context/q-8r.enc create mode 100644 fonts/enc/dvips/context/teff-trinite.enc create mode 100644 fonts/enc/dvips/jmn/hans.enc create mode 100644 fonts/enc/pdftex/context/koeieletters-ex.enc create mode 100644 fonts/enc/pdftex/context/koeieletters-mi.enc create mode 100644 fonts/enc/pdftex/context/koeieletters-sy.enc create mode 100644 fonts/enc/pdftex/context/koeieletters.enc create mode 100644 fonts/enc/pdftex/context/koeielogos.enc create mode 100644 fonts/fea/context/greek-babel.fea create mode 100644 fonts/fea/context/test-features.fea create mode 100644 fonts/fea/context/texhistoric.fea create mode 100644 fonts/fea/context/verbose-digits.fea create mode 100644 fonts/map/dvips/context/contnav.map create mode 100644 fonts/map/dvips/jmn/hans.map create mode 100644 fonts/map/luatex/context/demo-font.lum create mode 100644 fonts/map/pdftex/context/8r-base.map create mode 100644 fonts/map/pdftex/context/ec-base.map create mode 100644 fonts/map/pdftex/context/ec-os-public-lm.map create mode 100644 fonts/map/pdftex/context/koeieletters.map create mode 100644 fonts/map/pdftex/context/mkiv-base.map create mode 100644 fonts/map/pdftex/context/mkiv-px.map create mode 100644 fonts/map/pdftex/context/mkiv-tx.map create mode 100644 fonts/map/pdftex/context/original-adobe-euro.map create mode 100644 fonts/map/pdftex/context/original-ams-base.map create mode 100644 fonts/map/pdftex/context/original-ams-cmr.map create mode 100644 fonts/map/pdftex/context/original-ams-euler.map create mode 100644 fonts/map/pdftex/context/original-base.map create mode 100644 fonts/map/pdftex/context/original-context-symbol.map create mode 100644 fonts/map/pdftex/context/original-dummy.map create mode 100644 fonts/map/pdftex/context/original-empty.map create mode 100644 fonts/map/pdftex/context/original-micropress-informal.map create mode 100644 fonts/map/pdftex/context/original-public-csr.map create mode 100644 fonts/map/pdftex/context/original-public-lm.map create mode 100644 fonts/map/pdftex/context/original-public-plr.map create mode 100644 fonts/map/pdftex/context/original-public-vnr.map create mode 100644 fonts/map/pdftex/context/original-vogel-symbol.map create mode 100644 fonts/map/pdftex/context/original-wasy.map create mode 100644 fonts/map/pdftex/context/original-youngryu-px.map create mode 100644 fonts/map/pdftex/context/original-youngryu-tx.map create mode 100644 fonts/map/pdftex/context/qx-base.map create mode 100644 fonts/map/pdftex/context/qx-os-public-lm.map create mode 100644 fonts/map/pdftex/context/t5-base.map create mode 100644 fonts/map/pdftex/context/t5-os-public-lm.map create mode 100644 fonts/map/pdftex/context/texnansi-base.map create mode 100644 fonts/map/pdftex/context/texnansi-os-public-lm.map create mode 100644 fonts/misc/xetex/fontmapping/tlig.map create mode 100644 fonts/misc/xetex/fontmapping/tlig.tec create mode 100644 fonts/pfm/hoekwater/context/contnav.pfm create mode 100644 fonts/pfm/hoekwater/context/koeieletters.pfm create mode 100644 fonts/pfm/jmn/hans/hans-sh.pfm create mode 100644 fonts/pfm/jmn/hans/hans.pfm create mode 100644 fonts/tfm/hoekwater/context/contnav.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeielett-contour.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeielett.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeieletter-ex.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeieletter-mi.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeieletter-sy.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeieletter-syx.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeieletters-contour.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeieletters.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeielettx.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeielogos-contour.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeielogos.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeien-ex.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeien-mi.tfm create mode 100644 fonts/tfm/hoekwater/koeieletters/koeien-sy.tfm create mode 100644 fonts/tfm/jmn/hans/hans-sh.tfm create mode 100644 fonts/tfm/jmn/hans/hans.tfm create mode 100644 fonts/tfm/public/marvosym/fmvr8x.tfm create mode 100644 fonts/truetype/hoekwater/lm/lmtypewriter10-regular.ttf create mode 100644 fonts/type1/hoekwater/context/contnav.pfb create mode 100644 fonts/type1/hoekwater/koeieletters/koeieletters-contour.pfb create mode 100644 fonts/type1/hoekwater/koeieletters/koeieletters.pfb create mode 100644 fonts/type1/hoekwater/koeieletters/koeielogos-contour.pfb create mode 100644 fonts/type1/hoekwater/koeieletters/koeielogos.pfb create mode 100644 fonts/type1/jmn/hans/hans-sh.pfb create mode 100644 fonts/type1/jmn/hans/hans.pfb create mode 100644 fonts/vf/hoekwater/koeieletters/koeielett-contour.vf create mode 100644 fonts/vf/hoekwater/koeieletters/koeielett.vf create mode 100644 fonts/vf/hoekwater/koeieletters/koeieletter-ex.vf create mode 100644 fonts/vf/hoekwater/koeieletters/koeieletter-mi.vf create mode 100644 fonts/vf/hoekwater/koeieletters/koeieletter-sy.vf create mode 100644 fonts/vf/hoekwater/koeieletters/koeieletter-syx.vf create mode 100644 fonts/vf/hoekwater/koeieletters/koeielettx.vf create mode 100644 metapost/context/base/metafun.mp create mode 100644 metapost/context/base/mp-back.mp create mode 100644 metapost/context/base/mp-base.mp create mode 100644 metapost/context/base/mp-butt.mp create mode 100644 metapost/context/base/mp-char.mp create mode 100644 metapost/context/base/mp-chem.mp create mode 100644 metapost/context/base/mp-core.mp create mode 100644 metapost/context/base/mp-figs.mp create mode 100644 metapost/context/base/mp-fobg.mp create mode 100644 metapost/context/base/mp-form.mp create mode 100644 metapost/context/base/mp-func.mp create mode 100644 metapost/context/base/mp-grid.mp create mode 100644 metapost/context/base/mp-grph.mp create mode 100644 metapost/context/base/mp-mlib.mp create mode 100644 metapost/context/base/mp-page.mp create mode 100644 metapost/context/base/mp-shap.mp create mode 100644 metapost/context/base/mp-spec.mp create mode 100644 metapost/context/base/mp-step.mp create mode 100644 metapost/context/base/mp-symb.mp create mode 100644 metapost/context/base/mp-text.mp create mode 100644 metapost/context/base/mp-tool.mp create mode 100644 metapost/context/base/mp-txts.mp create mode 100644 metapost/context/font/punkfont.mp create mode 100644 scripts/context/lua/luatools.lua create mode 100644 scripts/context/lua/luatools.rme create mode 100644 scripts/context/lua/mtx-babel.lua create mode 100644 scripts/context/lua/mtx-cache.lua create mode 100644 scripts/context/lua/mtx-chars.lua create mode 100644 scripts/context/lua/mtx-check.lua create mode 100644 scripts/context/lua/mtx-context.lua create mode 100644 scripts/context/lua/mtx-convert.lua create mode 100644 scripts/context/lua/mtx-fonts.lua create mode 100644 scripts/context/lua/mtx-grep.lua create mode 100644 scripts/context/lua/mtx-interface.lua create mode 100644 scripts/context/lua/mtx-metatex.lua create mode 100644 scripts/context/lua/mtx-modules.lua create mode 100644 scripts/context/lua/mtx-mptopdf.lua create mode 100644 scripts/context/lua/mtx-mtxworks.lua create mode 100644 scripts/context/lua/mtx-package.lua create mode 100644 scripts/context/lua/mtx-patterns.lua create mode 100644 scripts/context/lua/mtx-profile.lua create mode 100644 scripts/context/lua/mtx-scite.lua create mode 100644 scripts/context/lua/mtx-server-ctx-fonttest.lua create mode 100644 scripts/context/lua/mtx-server-ctx-help.lua create mode 100644 scripts/context/lua/mtx-server-ctx-startup.lua create mode 100644 scripts/context/lua/mtx-server.lua create mode 100644 scripts/context/lua/mtx-texworks.lua create mode 100644 scripts/context/lua/mtx-timing.lua create mode 100644 scripts/context/lua/mtx-tools.lua create mode 100644 scripts/context/lua/mtx-unzip.lua create mode 100644 scripts/context/lua/mtx-update.lua create mode 100644 scripts/context/lua/mtx-watch.lua create mode 100644 scripts/context/lua/mtxrun.lua create mode 100644 scripts/context/lua/mtxrun.rme create mode 100644 scripts/context/lua/x-ldx.lua create mode 100644 scripts/context/perl/makempy.pl create mode 100644 scripts/context/perl/mptopdf.pl create mode 100644 scripts/context/perl/path_tre.pm create mode 100644 scripts/context/perl/pdftrimwhite.pl create mode 100644 scripts/context/perl/texfind.pl create mode 100644 scripts/context/perl/texfont.pl create mode 100644 scripts/context/ruby/base/ctx.rb create mode 100644 scripts/context/ruby/base/exa.rb create mode 100644 scripts/context/ruby/base/file.rb create mode 100644 scripts/context/ruby/base/kpse.rb create mode 100644 scripts/context/ruby/base/kpse/drb.rb create mode 100644 scripts/context/ruby/base/kpse/soap.rb create mode 100644 scripts/context/ruby/base/kpse/trees.rb create mode 100644 scripts/context/ruby/base/kpsedirect.rb create mode 100644 scripts/context/ruby/base/kpsefast.rb create mode 100644 scripts/context/ruby/base/kpseremote.rb create mode 100644 scripts/context/ruby/base/kpserunner.rb create mode 100644 scripts/context/ruby/base/logger.rb create mode 100644 scripts/context/ruby/base/merge.rb create mode 100644 scripts/context/ruby/base/mp.rb create mode 100644 scripts/context/ruby/base/pdf.rb create mode 100644 scripts/context/ruby/base/state.rb create mode 100644 scripts/context/ruby/base/switch.rb create mode 100644 scripts/context/ruby/base/system.rb create mode 100644 scripts/context/ruby/base/tex.rb create mode 100644 scripts/context/ruby/base/texutil.rb create mode 100644 scripts/context/ruby/base/tool.rb create mode 100644 scripts/context/ruby/base/variables.rb create mode 100644 scripts/context/ruby/concheck.rb create mode 100644 scripts/context/ruby/ctxtools.rb create mode 100644 scripts/context/ruby/fcd_start.rb create mode 100644 scripts/context/ruby/graphics/gs.rb create mode 100644 scripts/context/ruby/graphics/inkscape.rb create mode 100644 scripts/context/ruby/graphics/magick.rb create mode 100644 scripts/context/ruby/imgtopdf.rb create mode 100644 scripts/context/ruby/mpstools.rb create mode 100644 scripts/context/ruby/mtxtools.rb create mode 100644 scripts/context/ruby/pdftools.rb create mode 100644 scripts/context/ruby/pstopdf.rb create mode 100644 scripts/context/ruby/rlxtools.rb create mode 100644 scripts/context/ruby/rscortool.rb create mode 100644 scripts/context/ruby/rsfiltool.rb create mode 100644 scripts/context/ruby/rslibtool.rb create mode 100644 scripts/context/ruby/runtools.rb create mode 100644 scripts/context/ruby/texexec.rb create mode 100644 scripts/context/ruby/texmfstart.rb create mode 100644 scripts/context/ruby/texsync.rb create mode 100644 scripts/context/ruby/textools.rb create mode 100644 scripts/context/ruby/texutil.rb create mode 100644 scripts/context/ruby/tmftools.rb create mode 100644 scripts/context/ruby/xmltools.rb create mode 100644 scripts/context/stubs/mswin/context.exe create mode 100644 scripts/context/stubs/mswin/luatools.exe create mode 100644 scripts/context/stubs/mswin/luatools.lua create mode 100644 scripts/context/stubs/mswin/metatex.exe create mode 100644 scripts/context/stubs/mswin/mtxrun.dll create mode 100644 scripts/context/stubs/mswin/mtxrun.exe create mode 100644 scripts/context/stubs/mswin/mtxrun.lua create mode 100644 scripts/context/stubs/mswin/texexec.exe create mode 100644 scripts/context/stubs/mswin/texmfstart.exe create mode 100644 scripts/context/stubs/source/mtxrun_dll.c create mode 100644 scripts/context/stubs/source/mtxrun_exe.c create mode 100644 scripts/context/stubs/source/readme.txt create mode 100644 scripts/context/stubs/unix/context create mode 100644 scripts/context/stubs/unix/luatools create mode 100644 scripts/context/stubs/unix/metatex create mode 100644 scripts/context/stubs/unix/mtxrun create mode 100644 scripts/context/stubs/unix/texexec create mode 100644 scripts/context/stubs/unix/texmfstart 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 create mode 100644 web2c/context.cnf create mode 100644 web2c/contextcnf.lua create mode 100644 web2c/natural.tcx diff --git a/bibtex/bst/context/cont-ab.bst b/bibtex/bst/context/cont-ab.bst new file mode 100644 index 000000000..c524ff8ee --- /dev/null +++ b/bibtex/bst/context/cont-ab.bst @@ -0,0 +1,1223 @@ +% Written by Taco Hoekwater +% Donated to the Public Domain. Use at your own risk. +% Preliminary version, 19-aug-1999. +% New 17/9/2003: 'eprint' and 'doi' tags + +% This style produces citations in a format the ConTeXt can handle. +% It outputs a large collection of labels so that context can decide +% which one to use. +% +% Actually, there are a number of separate bst files that change in +% only two lines: the ITERATEs right before the two SORTs can +% have different values, sorting by either one of +% +% -------------------------- cont-master.bst author +% - the author (+year, title) : cont-au.bst author +% - the title (+author, year) : cont-ti.bst title +% - the short key a la abbrev : cont-ab.bst clabel +% - nothing at all (cite order): cont-no.bst none +% +% +% Output gives the following computed info: +% +% - the total number of bib entries +% - the longest short label +% +% And per entry: +% +% - the key +% - the entry type +% - the yeardata for crossrefs +% - the authordata for crossrefs +% - the short key +% - the .bib appearance number + +% Commands that may be written to the bbl file (not counting stuff the +% bib database defines itself): +% +% \setuppublicationlist +% \startpublication +% \stoppublication + +% Field entries with a strange format/appearance: +% +% \artauthor, +% \editor, +% \author: \xxx[junior]{firstnames}[inits]{von}{lastname} + +% \etalchar: appears in short keys sometimes +% \maybeyear: appears in \pubyear sometimes +% +% And these commands for the entries have only one argument, +% precisely matching the corresponding field. Note that there +% are more fields supported than in the standard bst files. +% +% \abstract +% \annotate +% \arttitle +% \chapter +% \city +% \comment +% \country +% \crossref +% \edition +% \isbn +% \issn +% \issue +% \journal +% \keyword +% \keywords +% \lang +% \month +% \names +% \note +% \notes +% \organization +% \pages +% \pubname +% \pubyear +% \series +% \size +% \thekey +% \title +% \bibtype +% \volume +% \eprint +% \doi +% \howpublished +% \biburl +% \lastchecked +% for ieee: + +% \nationality +% \assignee +% \bibnumber +% \day +% \dayfiled +% \monthfiled +% \yearfiled +% \revision + +ENTRY + { abstract + address + annotate + author + booktitle + chapter + comment + country + doi + edition + editor + eprint + howpublished + institution + isbn + issn + journal + key + keyword + keywords + language + lastchecked + month + names + note + notes + number + organization + pages + publisher + school + series + size + title + type + url + volume + year + nationality + assignee + bibnumber + day + dayfiled + monthfiled + yearfiled + revision + } + {} + { label extra.label sort.label clabel sort.clabel ordinal.label} + + +STRINGS { s t autype} + +STRINGS { last.label next.extra nlabel } + +STRINGS { longest.label last.sort.label} + +INTEGERS { longest.label.width last.extra.num ordinal.num } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { len } + + +FUNCTION {begin.bib} +{ #0 'ordinal.num := + preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\setuppublicationlist[samplesize={" write$ + longest.label "},totalnumber=" * write$ + nlabel "]" * write$ + newline$ +} + +FUNCTION {end.bib} +{ newline$ +} + + + +FUNCTION {do.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ * "}" * * write$ pop$ newline$ } + if$ +} + + +FUNCTION {do.t.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ "t" change.case$ * "}" * * write$ pop$ newline$ } + if$ +} + +FUNCTION {format.year} +{ year empty$ + 'skip$ + { "\pubyear{" year * write$ + extra.label empty$ + { "}" write$ } + { "\maybeyear{" extra.label * "}}" * write$ } + if$ + newline$ + } + if$ +} + +FUNCTION {start.entry} +{ ordinal.num #1 + 'ordinal.num := + newline$ + "\startpublication[" write$ + "k=" write$ + cite$ "," * write$ + "t=" write$ + type$ "," * write$ + newline$ + label write$ + "," write$ + doi empty$ + {} + { + "o={" write$ + doi write$ + "}," write$ + } if$ + newline$ + url empty$ + {} + { + "u={" write$ + url write$ + "}," write$ + newline$ + } if$ + "n=" write$ + ordinal.label write$ + ",s=" write$ + clabel write$ + "]" write$ + newline$ + "" "\lang" language do.out +} + +FUNCTION {stop.entry} +{ "" "\country" country do.out + "" "\note" note do.out + "" "\notes" notes do.out + "" "\annotate" annotate do.out + "" "\eprint" eprint do.out + "" "\doi" doi do.out + "" "\keyword" keyword do.out + "" "\keywords" keywords do.out + "" "\comment" comment do.out + "" "\abstract" abstract do.out + "" "\names" names do.out + "" "\size" size do.out + "" "\biburl" url do.out + "" "\lastchecked" lastchecked do.out + "\stoppublication" write$ + newline$ +} + + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + + +FUNCTION {format.names} +{ 's := 'autype := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { autype write$ + s nameptr "{jj}" format.name$ 't := + "[" t * "]" * write$ + s nameptr "{ff}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{f}" format.name$ add.period$ 't := + "[" t * "]" * write$ + s nameptr "{vv}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{ll}" format.name$ 't := + "{" t * "}" * write$ + newline$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + + +FUNCTION {format.key} +{ "" "\thekey" key do.out } + + +FUNCTION {format.artauthors} +{ author empty$ + { format.key } + { "\artauthor" author format.names } + if$ +} + +FUNCTION {format.authors} +{ author empty$ + { format.key } + { "\author" author format.names } + if$ +} + +FUNCTION {format.editors} +{ editor empty$ + { format.key } + { "\editor" editor format.names } + if$ +} + + +FUNCTION {format.title} +{ "" "\title" title do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.t.title} +{ "" "\title" title do.t.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.arttitle} +{ "" "\arttitle" title do.t.out } + +FUNCTION {format.journal} +{ "" "\journal" journal do.out + "" "\issn" issn do.out +} + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {format.volume} +{ "" "\volume" volume do.out +} + +FUNCTION {format.volume.issue} +{ "" "\volume" volume do.out + "" "\issue" number do.out +} + +FUNCTION {format.number.series} +{ "" "\series" series do.out + volume empty$ + { "" "\volume" number do.out + } + { "" "\volume" volume do.out + "" "\issue" number do.out } + if$ +} + +FUNCTION {format.edition} +{ "" "\edition" edition do.out + "" "\month" month do.out +} + +FUNCTION {format.pages} +{ "" "\pages" pages do.out } + + +FUNCTION {format.vol.num.pages} +{ format.volume.issue + format.pages +} + +FUNCTION {format.vol.num.page} +{ format.volume.issue + format.pages +} + +FUNCTION {format.type.chapter.pages} +{ chapter empty$ + 'format.pages + { "" "\bibtype" type do.out + "" "\chapter" chapter do.out + } + if$ + format.pages +} + +FUNCTION {format.booktitle} +{"" "\title" booktitle do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.in.ed.booktitle} +{ booktitle empty$ + 'skip$ + { format.booktitle } + if$ +} + +FUNCTION {format.in.booktitle.or.series} +{ "" "\series" series do.out + booktitle empty$ + 'skip$ + { editor empty$ + { format.booktitle } + { format.editors format.booktitle } + if$ + } + if$ +} + + +FUNCTION {format.tr.number} +{"" "\bibtype" type do.out + "" "\volume" number do.out +} + +FUNCTION {format.crossref} +{ "" "\crossref" crossref do.out +} + +FUNCTION {format.book.crossref} +{ + "" "\volume" volume do.out + format.crossref +} + +FUNCTION {format.incoll.inproc.crossref} +{ format.crossref +} + +FUNCTION {article} +{ start.entry + format.artauthors + format.year + format.arttitle + crossref missing$ + { format.journal + format.vol.num.pages + } + { format.crossref + format.pages + } + if$ + "" "\month" month do.out + stop.entry +} + +FUNCTION {book} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {booklet} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {inbook} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.type.chapter.pages + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { format.type.chapter.pages + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {incollection} +{ start.entry + format.artauthors + format.year + format.arttitle + format.editors + crossref missing$ + { format.in.ed.booktitle + format.number.series + "" "\city" address do.out + format.edition + format.type.chapter.pages + } + { format.incoll.inproc.crossref + format.type.chapter.pages + } + if$ + "" "\pubname" publisher do.out + stop.entry +} + +FUNCTION {inproceedings} +{ start.entry + format.authors + format.year + format.arttitle + crossref missing$ + { format.in.booktitle.or.series + format.number.series + "" "\city" address do.out + format.pages + } + { format.incoll.inproc.crossref + format.pages + } + if$ + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {conference} { inproceedings } + +FUNCTION {manual} +{ start.entry + format.authors + format.year + format.title + "" "\organization" organization do.out + "" "\city" address do.out + "" "\edition" edition do.out + stop.entry +} + +FUNCTION {mastersthesis} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibtype" type do.out + "" "\pubname" school do.out + "" "\month" month do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {misc} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\city" address do.out + "" "\month" month do.out + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + stop.entry +} + +FUNCTION {phdthesis} +{ start.entry + format.authors + format.title + format.year + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\pubname" school do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {proceedings} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {techreport} +{ start.entry + format.authors + format.year + format.t.title + format.tr.number + "" "\city" address do.out + "" "\pubname" institution do.out + stop.entry +} + +FUNCTION {unpublished} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + stop.entry +} + +% 4 additions from IEEEtran + +FUNCTION {electronic} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + "" "\city" address do.out + "" "\organization" organization do.out + "" "\howpublished" howpublished do.out + stop.entry +} +FUNCTION {patent} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibnumber" number do.out + "" "\city" address do.out + "" "\nationality" nationality do.out + "" "\assignee" assignee do.out + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\monthfiled" monthfiled do.out + "" "\yearfiled" yearfiled do.out + "" "\day" day do.out + "" "\dayfiled" dayfiled do.out + stop.entry +} +FUNCTION {periodical} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\bibnumber" number do.out + "" "\month" month do.out + "" "\organization" organization do.out + stop.entry +} +FUNCTION {standard} +{ start.entry + format.authors + format.year + format.title + "" "\bibtype" type do.out + "" "\organization" organization do.out + "" "\city" address do.out + "" "\revision" revision do.out + "" "\pubname" institution do.out + "" "\howpublished" howpublished do.out + "" "\bibnumber" number do.out + "" "\month" month do.out + stop.entry +} + +FUNCTION {IEEEtranBSTCTL} { } + + +FUNCTION {default.type} { misc } + +MACRO {jan} {"1"} +MACRO {feb} {"2"} +MACRO {mar} {"3"} +MACRO {apr} {"4"} +MACRO {may} {"5"} +MACRO {jun} {"6"} +MACRO {jul} {"7"} +MACRO {aug} {"8"} +MACRO {sep} {"9"} +MACRO {oct} {"10"} +MACRO {nov} {"11"} +MACRO {dec} {"12"} + +READ + +FUNCTION {initialize.ordinal.label} +{ #0 'ordinal.num := } + +FUNCTION {set.ordinal.label} { + #1 ordinal.num + 'ordinal.num := + ordinal.num int.to.str$ 'ordinal.label := +} + +EXECUTE {initialize.ordinal.label} + +ITERATE {set.ordinal.label} + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +FUNCTION {format.lab.names} +{ 's := + s #1 "{vv~}{ll}" format.name$ + "{" swap$ * "}" * + s num.names$ duplicate$ + #1 > + { pop$ "," * } + { pop$ } + if$ + s num.names$ duplicate$ + #2 > + { pop$ "{}" * } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{}" * } + { s #2 "{vv~}{ll}" format.name$ "{" swap$ * "}" * * } + if$ + } + if$ + } + if$ + "{" swap$ * "}," * +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.label} +{ editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.label} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.label + 'author.key.label + if$ + } + if$ + "a=" swap$ * "y=" * + year field.or.null purify$ #-1 #4 substring$ + * + 'label := +} + +INTEGERS { et.al.char.used } + +FUNCTION {initialize.et.al.char.used} +{ #0 'et.al.char.used := +} + +EXECUTE {initialize.et.al.char.used} + +FUNCTION {format.clab.names} +{ 's := + s num.names$ 'numnames := + numnames #1 > + { numnames #4 > + { #3 'namesleft := } + { numnames 'namesleft := } + if$ + #1 'nameptr := + "" + { namesleft #0 > } + { nameptr numnames = + { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + numnames #4 > + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + 'skip$ + if$ + } + { s #1 "{v{}}{l{}}" format.name$ + duplicate$ text.length$ #2 < + { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } + 'skip$ + if$ + } + if$ +} + +FUNCTION {author.key.clabel} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.editor.key.clabel} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.key.organization.clabel} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {editor.key.organization.clabel} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ +} + +FUNCTION {calc.clabel} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.clabel + { type$ "proceedings" = + 'editor.key.organization.clabel + { type$ "manual" = + 'author.key.organization.clabel + 'author.key.clabel + if$ + } + if$ + } + if$ + duplicate$ + year field.or.null purify$ #-1 #2 substring$ + * + 'clabel := + year field.or.null purify$ #-1 #4 substring$ + * + sortify 'sort.clabel := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ + s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { "et al" * } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.sort} +{ editor empty$ + { key empty$ + { "to sort, need editor or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {presort.title} +{ calc.label + calc.clabel + title field.or.null + sort.format.title + " " + * + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.author} +{ calc.clabel + calc.label + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.clabel} +{ calc.label + calc.clabel + clabel sortify + duplicate$ 'sort.label := + #1 entry.max$ substring$ + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {presort.none} +{ calc.label + calc.clabel + "" 'sort.label := + "" 'sort.key$ := +} + +ITERATE {presort.clabel} + +SORT + +FUNCTION {initialize.extra.label.stuff} +{ #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'last.extra.num := + #0 'ordinal.num := +} + +FUNCTION {forward.pass} +{ ordinal.num #1 + 'ordinal.num := + ordinal.num int.to.str$ 'nlabel := + last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ +} + +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + label extra.label * 'label := + clabel extra.label * 'clabel := + extra.label 'next.extra := + clabel width$ longest.label.width > + { clabel 'longest.label := + clabel width$ 'longest.label.width := + } + 'skip$ + if$ +} + +EXECUTE {initialize.extra.label.stuff} + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.sort.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := +} + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} + +REVERSE {reverse.pass} + +FUNCTION {bib.sort.order.author} +{ sort.label + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.title} +{ sort.label + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + * + " " + * + year field.or.null sortify + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.clabel} +{ sort.label + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.none} +{ sort.label 'sort.key$ := +} + +ITERATE {bib.sort.order.clabel} + +SORT + +EXECUTE {begin.bib} + +ITERATE {call.type$} + + +EXECUTE {end.bib} diff --git a/bibtex/bst/context/cont-au.bst b/bibtex/bst/context/cont-au.bst new file mode 100644 index 000000000..2eba98b0a --- /dev/null +++ b/bibtex/bst/context/cont-au.bst @@ -0,0 +1,1223 @@ +% Written by Taco Hoekwater +% Donated to the Public Domain. Use at your own risk. +% Preliminary version, 19-aug-1999. +% New 17/9/2003: 'eprint' and 'doi' tags + +% This style produces citations in a format the ConTeXt can handle. +% It outputs a large collection of labels so that context can decide +% which one to use. +% +% Actually, there are a number of separate bst files that change in +% only two lines: the ITERATEs right before the two SORTs can +% have different values, sorting by either one of +% +% -------------------------- cont-master.bst author +% - the author (+year, title) : cont-au.bst author +% - the title (+author, year) : cont-ti.bst title +% - the short key a la abbrev : cont-ab.bst clabel +% - nothing at all (cite order): cont-no.bst none +% +% +% Output gives the following computed info: +% +% - the total number of bib entries +% - the longest short label +% +% And per entry: +% +% - the key +% - the entry type +% - the yeardata for crossrefs +% - the authordata for crossrefs +% - the short key +% - the .bib appearance number + +% Commands that may be written to the bbl file (not counting stuff the +% bib database defines itself): +% +% \setuppublicationlist +% \startpublication +% \stoppublication + +% Field entries with a strange format/appearance: +% +% \artauthor, +% \editor, +% \author: \xxx[junior]{firstnames}[inits]{von}{lastname} + +% \etalchar: appears in short keys sometimes +% \maybeyear: appears in \pubyear sometimes +% +% And these commands for the entries have only one argument, +% precisely matching the corresponding field. Note that there +% are more fields supported than in the standard bst files. +% +% \abstract +% \annotate +% \arttitle +% \chapter +% \city +% \comment +% \country +% \crossref +% \edition +% \isbn +% \issn +% \issue +% \journal +% \keyword +% \keywords +% \lang +% \month +% \names +% \note +% \notes +% \organization +% \pages +% \pubname +% \pubyear +% \series +% \size +% \thekey +% \title +% \bibtype +% \volume +% \eprint +% \doi +% \howpublished +% \biburl +% \lastchecked +% for ieee: + +% \nationality +% \assignee +% \bibnumber +% \day +% \dayfiled +% \monthfiled +% \yearfiled +% \revision + +ENTRY + { abstract + address + annotate + author + booktitle + chapter + comment + country + doi + edition + editor + eprint + howpublished + institution + isbn + issn + journal + key + keyword + keywords + language + lastchecked + month + names + note + notes + number + organization + pages + publisher + school + series + size + title + type + url + volume + year + nationality + assignee + bibnumber + day + dayfiled + monthfiled + yearfiled + revision + } + {} + { label extra.label sort.label clabel sort.clabel ordinal.label} + + +STRINGS { s t autype} + +STRINGS { last.label next.extra nlabel } + +STRINGS { longest.label last.sort.label} + +INTEGERS { longest.label.width last.extra.num ordinal.num } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { len } + + +FUNCTION {begin.bib} +{ #0 'ordinal.num := + preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\setuppublicationlist[samplesize={" write$ + longest.label "},totalnumber=" * write$ + nlabel "]" * write$ + newline$ +} + +FUNCTION {end.bib} +{ newline$ +} + + + +FUNCTION {do.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ * "}" * * write$ pop$ newline$ } + if$ +} + + +FUNCTION {do.t.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ "t" change.case$ * "}" * * write$ pop$ newline$ } + if$ +} + +FUNCTION {format.year} +{ year empty$ + 'skip$ + { "\pubyear{" year * write$ + extra.label empty$ + { "}" write$ } + { "\maybeyear{" extra.label * "}}" * write$ } + if$ + newline$ + } + if$ +} + +FUNCTION {start.entry} +{ ordinal.num #1 + 'ordinal.num := + newline$ + "\startpublication[" write$ + "k=" write$ + cite$ "," * write$ + "t=" write$ + type$ "," * write$ + newline$ + label write$ + "," write$ + doi empty$ + {} + { + "o={" write$ + doi write$ + "}," write$ + } if$ + newline$ + url empty$ + {} + { + "u={" write$ + url write$ + "}," write$ + newline$ + } if$ + "n=" write$ + ordinal.label write$ + ",s=" write$ + clabel write$ + "]" write$ + newline$ + "" "\lang" language do.out +} + +FUNCTION {stop.entry} +{ "" "\country" country do.out + "" "\note" note do.out + "" "\notes" notes do.out + "" "\annotate" annotate do.out + "" "\eprint" eprint do.out + "" "\doi" doi do.out + "" "\keyword" keyword do.out + "" "\keywords" keywords do.out + "" "\comment" comment do.out + "" "\abstract" abstract do.out + "" "\names" names do.out + "" "\size" size do.out + "" "\biburl" url do.out + "" "\lastchecked" lastchecked do.out + "\stoppublication" write$ + newline$ +} + + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + + +FUNCTION {format.names} +{ 's := 'autype := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { autype write$ + s nameptr "{jj}" format.name$ 't := + "[" t * "]" * write$ + s nameptr "{ff}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{f}" format.name$ add.period$ 't := + "[" t * "]" * write$ + s nameptr "{vv}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{ll}" format.name$ 't := + "{" t * "}" * write$ + newline$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + + +FUNCTION {format.key} +{ "" "\thekey" key do.out } + + +FUNCTION {format.artauthors} +{ author empty$ + { format.key } + { "\artauthor" author format.names } + if$ +} + +FUNCTION {format.authors} +{ author empty$ + { format.key } + { "\author" author format.names } + if$ +} + +FUNCTION {format.editors} +{ editor empty$ + { format.key } + { "\editor" editor format.names } + if$ +} + + +FUNCTION {format.title} +{ "" "\title" title do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.t.title} +{ "" "\title" title do.t.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.arttitle} +{ "" "\arttitle" title do.t.out } + +FUNCTION {format.journal} +{ "" "\journal" journal do.out + "" "\issn" issn do.out +} + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {format.volume} +{ "" "\volume" volume do.out +} + +FUNCTION {format.volume.issue} +{ "" "\volume" volume do.out + "" "\issue" number do.out +} + +FUNCTION {format.number.series} +{ "" "\series" series do.out + volume empty$ + { "" "\volume" number do.out + } + { "" "\volume" volume do.out + "" "\issue" number do.out } + if$ +} + +FUNCTION {format.edition} +{ "" "\edition" edition do.out + "" "\month" month do.out +} + +FUNCTION {format.pages} +{ "" "\pages" pages do.out } + + +FUNCTION {format.vol.num.pages} +{ format.volume.issue + format.pages +} + +FUNCTION {format.vol.num.page} +{ format.volume.issue + format.pages +} + +FUNCTION {format.type.chapter.pages} +{ chapter empty$ + 'format.pages + { "" "\bibtype" type do.out + "" "\chapter" chapter do.out + } + if$ + format.pages +} + +FUNCTION {format.booktitle} +{"" "\title" booktitle do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.in.ed.booktitle} +{ booktitle empty$ + 'skip$ + { format.booktitle } + if$ +} + +FUNCTION {format.in.booktitle.or.series} +{ "" "\series" series do.out + booktitle empty$ + 'skip$ + { editor empty$ + { format.booktitle } + { format.editors format.booktitle } + if$ + } + if$ +} + + +FUNCTION {format.tr.number} +{"" "\bibtype" type do.out + "" "\volume" number do.out +} + +FUNCTION {format.crossref} +{ "" "\crossref" crossref do.out +} + +FUNCTION {format.book.crossref} +{ + "" "\volume" volume do.out + format.crossref +} + +FUNCTION {format.incoll.inproc.crossref} +{ format.crossref +} + +FUNCTION {article} +{ start.entry + format.artauthors + format.year + format.arttitle + crossref missing$ + { format.journal + format.vol.num.pages + } + { format.crossref + format.pages + } + if$ + "" "\month" month do.out + stop.entry +} + +FUNCTION {book} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {booklet} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {inbook} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.type.chapter.pages + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { format.type.chapter.pages + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {incollection} +{ start.entry + format.artauthors + format.year + format.arttitle + format.editors + crossref missing$ + { format.in.ed.booktitle + format.number.series + "" "\city" address do.out + format.edition + format.type.chapter.pages + } + { format.incoll.inproc.crossref + format.type.chapter.pages + } + if$ + "" "\pubname" publisher do.out + stop.entry +} + +FUNCTION {inproceedings} +{ start.entry + format.authors + format.year + format.arttitle + crossref missing$ + { format.in.booktitle.or.series + format.number.series + "" "\city" address do.out + format.pages + } + { format.incoll.inproc.crossref + format.pages + } + if$ + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {conference} { inproceedings } + +FUNCTION {manual} +{ start.entry + format.authors + format.year + format.title + "" "\organization" organization do.out + "" "\city" address do.out + "" "\edition" edition do.out + stop.entry +} + +FUNCTION {mastersthesis} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibtype" type do.out + "" "\pubname" school do.out + "" "\month" month do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {misc} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\city" address do.out + "" "\month" month do.out + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + stop.entry +} + +FUNCTION {phdthesis} +{ start.entry + format.authors + format.title + format.year + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\pubname" school do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {proceedings} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {techreport} +{ start.entry + format.authors + format.year + format.t.title + format.tr.number + "" "\city" address do.out + "" "\pubname" institution do.out + stop.entry +} + +FUNCTION {unpublished} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + stop.entry +} + +% 4 additions from IEEEtran + +FUNCTION {electronic} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + "" "\city" address do.out + "" "\organization" organization do.out + "" "\howpublished" howpublished do.out + stop.entry +} +FUNCTION {patent} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibnumber" number do.out + "" "\city" address do.out + "" "\nationality" nationality do.out + "" "\assignee" assignee do.out + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\monthfiled" monthfiled do.out + "" "\yearfiled" yearfiled do.out + "" "\day" day do.out + "" "\dayfiled" dayfiled do.out + stop.entry +} +FUNCTION {periodical} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\bibnumber" number do.out + "" "\month" month do.out + "" "\organization" organization do.out + stop.entry +} +FUNCTION {standard} +{ start.entry + format.authors + format.year + format.title + "" "\bibtype" type do.out + "" "\organization" organization do.out + "" "\city" address do.out + "" "\revision" revision do.out + "" "\pubname" institution do.out + "" "\howpublished" howpublished do.out + "" "\bibnumber" number do.out + "" "\month" month do.out + stop.entry +} + +FUNCTION {IEEEtranBSTCTL} { } + + +FUNCTION {default.type} { misc } + +MACRO {jan} {"1"} +MACRO {feb} {"2"} +MACRO {mar} {"3"} +MACRO {apr} {"4"} +MACRO {may} {"5"} +MACRO {jun} {"6"} +MACRO {jul} {"7"} +MACRO {aug} {"8"} +MACRO {sep} {"9"} +MACRO {oct} {"10"} +MACRO {nov} {"11"} +MACRO {dec} {"12"} + +READ + +FUNCTION {initialize.ordinal.label} +{ #0 'ordinal.num := } + +FUNCTION {set.ordinal.label} { + #1 ordinal.num + 'ordinal.num := + ordinal.num int.to.str$ 'ordinal.label := +} + +EXECUTE {initialize.ordinal.label} + +ITERATE {set.ordinal.label} + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +FUNCTION {format.lab.names} +{ 's := + s #1 "{vv~}{ll}" format.name$ + "{" swap$ * "}" * + s num.names$ duplicate$ + #1 > + { pop$ "," * } + { pop$ } + if$ + s num.names$ duplicate$ + #2 > + { pop$ "{}" * } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{}" * } + { s #2 "{vv~}{ll}" format.name$ "{" swap$ * "}" * * } + if$ + } + if$ + } + if$ + "{" swap$ * "}," * +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.label} +{ editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.label} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.label + 'author.key.label + if$ + } + if$ + "a=" swap$ * "y=" * + year field.or.null purify$ #-1 #4 substring$ + * + 'label := +} + +INTEGERS { et.al.char.used } + +FUNCTION {initialize.et.al.char.used} +{ #0 'et.al.char.used := +} + +EXECUTE {initialize.et.al.char.used} + +FUNCTION {format.clab.names} +{ 's := + s num.names$ 'numnames := + numnames #1 > + { numnames #4 > + { #3 'namesleft := } + { numnames 'namesleft := } + if$ + #1 'nameptr := + "" + { namesleft #0 > } + { nameptr numnames = + { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + numnames #4 > + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + 'skip$ + if$ + } + { s #1 "{v{}}{l{}}" format.name$ + duplicate$ text.length$ #2 < + { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } + 'skip$ + if$ + } + if$ +} + +FUNCTION {author.key.clabel} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.editor.key.clabel} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.key.organization.clabel} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {editor.key.organization.clabel} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ +} + +FUNCTION {calc.clabel} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.clabel + { type$ "proceedings" = + 'editor.key.organization.clabel + { type$ "manual" = + 'author.key.organization.clabel + 'author.key.clabel + if$ + } + if$ + } + if$ + duplicate$ + year field.or.null purify$ #-1 #2 substring$ + * + 'clabel := + year field.or.null purify$ #-1 #4 substring$ + * + sortify 'sort.clabel := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ + s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { "et al" * } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.sort} +{ editor empty$ + { key empty$ + { "to sort, need editor or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {presort.title} +{ calc.label + calc.clabel + title field.or.null + sort.format.title + " " + * + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.author} +{ calc.clabel + calc.label + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.clabel} +{ calc.label + calc.clabel + clabel sortify + duplicate$ 'sort.label := + #1 entry.max$ substring$ + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {presort.none} +{ calc.label + calc.clabel + "" 'sort.label := + "" 'sort.key$ := +} + +ITERATE {presort.author} + +SORT + +FUNCTION {initialize.extra.label.stuff} +{ #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'last.extra.num := + #0 'ordinal.num := +} + +FUNCTION {forward.pass} +{ ordinal.num #1 + 'ordinal.num := + ordinal.num int.to.str$ 'nlabel := + last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ +} + +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + label extra.label * 'label := + clabel extra.label * 'clabel := + extra.label 'next.extra := + clabel width$ longest.label.width > + { clabel 'longest.label := + clabel width$ 'longest.label.width := + } + 'skip$ + if$ +} + +EXECUTE {initialize.extra.label.stuff} + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.sort.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := +} + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} + +REVERSE {reverse.pass} + +FUNCTION {bib.sort.order.author} +{ sort.label + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.title} +{ sort.label + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + * + " " + * + year field.or.null sortify + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.clabel} +{ sort.label + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.none} +{ sort.label 'sort.key$ := +} + +ITERATE {bib.sort.order.author} + +SORT + +EXECUTE {begin.bib} + +ITERATE {call.type$} + + +EXECUTE {end.bib} diff --git a/bibtex/bst/context/cont-no.bst b/bibtex/bst/context/cont-no.bst new file mode 100644 index 000000000..dbeb8a45d --- /dev/null +++ b/bibtex/bst/context/cont-no.bst @@ -0,0 +1,1223 @@ +% Written by Taco Hoekwater +% Donated to the Public Domain. Use at your own risk. +% Preliminary version, 19-aug-1999. +% New 17/9/2003: 'eprint' and 'doi' tags + +% This style produces citations in a format the ConTeXt can handle. +% It outputs a large collection of labels so that context can decide +% which one to use. +% +% Actually, there are a number of separate bst files that change in +% only two lines: the ITERATEs right before the two SORTs can +% have different values, sorting by either one of +% +% -------------------------- cont-master.bst author +% - the author (+year, title) : cont-au.bst author +% - the title (+author, year) : cont-ti.bst title +% - the short key a la abbrev : cont-ab.bst clabel +% - nothing at all (cite order): cont-no.bst none +% +% +% Output gives the following computed info: +% +% - the total number of bib entries +% - the longest short label +% +% And per entry: +% +% - the key +% - the entry type +% - the yeardata for crossrefs +% - the authordata for crossrefs +% - the short key +% - the .bib appearance number + +% Commands that may be written to the bbl file (not counting stuff the +% bib database defines itself): +% +% \setuppublicationlist +% \startpublication +% \stoppublication + +% Field entries with a strange format/appearance: +% +% \artauthor, +% \editor, +% \author: \xxx[junior]{firstnames}[inits]{von}{lastname} + +% \etalchar: appears in short keys sometimes +% \maybeyear: appears in \pubyear sometimes +% +% And these commands for the entries have only one argument, +% precisely matching the corresponding field. Note that there +% are more fields supported than in the standard bst files. +% +% \abstract +% \annotate +% \arttitle +% \chapter +% \city +% \comment +% \country +% \crossref +% \edition +% \isbn +% \issn +% \issue +% \journal +% \keyword +% \keywords +% \lang +% \month +% \names +% \note +% \notes +% \organization +% \pages +% \pubname +% \pubyear +% \series +% \size +% \thekey +% \title +% \bibtype +% \volume +% \eprint +% \doi +% \howpublished +% \biburl +% \lastchecked +% for ieee: + +% \nationality +% \assignee +% \bibnumber +% \day +% \dayfiled +% \monthfiled +% \yearfiled +% \revision + +ENTRY + { abstract + address + annotate + author + booktitle + chapter + comment + country + doi + edition + editor + eprint + howpublished + institution + isbn + issn + journal + key + keyword + keywords + language + lastchecked + month + names + note + notes + number + organization + pages + publisher + school + series + size + title + type + url + volume + year + nationality + assignee + bibnumber + day + dayfiled + monthfiled + yearfiled + revision + } + {} + { label extra.label sort.label clabel sort.clabel ordinal.label} + + +STRINGS { s t autype} + +STRINGS { last.label next.extra nlabel } + +STRINGS { longest.label last.sort.label} + +INTEGERS { longest.label.width last.extra.num ordinal.num } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { len } + + +FUNCTION {begin.bib} +{ #0 'ordinal.num := + preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\setuppublicationlist[samplesize={" write$ + longest.label "},totalnumber=" * write$ + nlabel "]" * write$ + newline$ +} + +FUNCTION {end.bib} +{ newline$ +} + + + +FUNCTION {do.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ * "}" * * write$ pop$ newline$ } + if$ +} + + +FUNCTION {do.t.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ "t" change.case$ * "}" * * write$ pop$ newline$ } + if$ +} + +FUNCTION {format.year} +{ year empty$ + 'skip$ + { "\pubyear{" year * write$ + extra.label empty$ + { "}" write$ } + { "\maybeyear{" extra.label * "}}" * write$ } + if$ + newline$ + } + if$ +} + +FUNCTION {start.entry} +{ ordinal.num #1 + 'ordinal.num := + newline$ + "\startpublication[" write$ + "k=" write$ + cite$ "," * write$ + "t=" write$ + type$ "," * write$ + newline$ + label write$ + "," write$ + doi empty$ + {} + { + "o={" write$ + doi write$ + "}," write$ + } if$ + newline$ + url empty$ + {} + { + "u={" write$ + url write$ + "}," write$ + newline$ + } if$ + "n=" write$ + ordinal.label write$ + ",s=" write$ + clabel write$ + "]" write$ + newline$ + "" "\lang" language do.out +} + +FUNCTION {stop.entry} +{ "" "\country" country do.out + "" "\note" note do.out + "" "\notes" notes do.out + "" "\annotate" annotate do.out + "" "\eprint" eprint do.out + "" "\doi" doi do.out + "" "\keyword" keyword do.out + "" "\keywords" keywords do.out + "" "\comment" comment do.out + "" "\abstract" abstract do.out + "" "\names" names do.out + "" "\size" size do.out + "" "\biburl" url do.out + "" "\lastchecked" lastchecked do.out + "\stoppublication" write$ + newline$ +} + + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + + +FUNCTION {format.names} +{ 's := 'autype := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { autype write$ + s nameptr "{jj}" format.name$ 't := + "[" t * "]" * write$ + s nameptr "{ff}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{f}" format.name$ add.period$ 't := + "[" t * "]" * write$ + s nameptr "{vv}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{ll}" format.name$ 't := + "{" t * "}" * write$ + newline$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + + +FUNCTION {format.key} +{ "" "\thekey" key do.out } + + +FUNCTION {format.artauthors} +{ author empty$ + { format.key } + { "\artauthor" author format.names } + if$ +} + +FUNCTION {format.authors} +{ author empty$ + { format.key } + { "\author" author format.names } + if$ +} + +FUNCTION {format.editors} +{ editor empty$ + { format.key } + { "\editor" editor format.names } + if$ +} + + +FUNCTION {format.title} +{ "" "\title" title do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.t.title} +{ "" "\title" title do.t.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.arttitle} +{ "" "\arttitle" title do.t.out } + +FUNCTION {format.journal} +{ "" "\journal" journal do.out + "" "\issn" issn do.out +} + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {format.volume} +{ "" "\volume" volume do.out +} + +FUNCTION {format.volume.issue} +{ "" "\volume" volume do.out + "" "\issue" number do.out +} + +FUNCTION {format.number.series} +{ "" "\series" series do.out + volume empty$ + { "" "\volume" number do.out + } + { "" "\volume" volume do.out + "" "\issue" number do.out } + if$ +} + +FUNCTION {format.edition} +{ "" "\edition" edition do.out + "" "\month" month do.out +} + +FUNCTION {format.pages} +{ "" "\pages" pages do.out } + + +FUNCTION {format.vol.num.pages} +{ format.volume.issue + format.pages +} + +FUNCTION {format.vol.num.page} +{ format.volume.issue + format.pages +} + +FUNCTION {format.type.chapter.pages} +{ chapter empty$ + 'format.pages + { "" "\bibtype" type do.out + "" "\chapter" chapter do.out + } + if$ + format.pages +} + +FUNCTION {format.booktitle} +{"" "\title" booktitle do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.in.ed.booktitle} +{ booktitle empty$ + 'skip$ + { format.booktitle } + if$ +} + +FUNCTION {format.in.booktitle.or.series} +{ "" "\series" series do.out + booktitle empty$ + 'skip$ + { editor empty$ + { format.booktitle } + { format.editors format.booktitle } + if$ + } + if$ +} + + +FUNCTION {format.tr.number} +{"" "\bibtype" type do.out + "" "\volume" number do.out +} + +FUNCTION {format.crossref} +{ "" "\crossref" crossref do.out +} + +FUNCTION {format.book.crossref} +{ + "" "\volume" volume do.out + format.crossref +} + +FUNCTION {format.incoll.inproc.crossref} +{ format.crossref +} + +FUNCTION {article} +{ start.entry + format.artauthors + format.year + format.arttitle + crossref missing$ + { format.journal + format.vol.num.pages + } + { format.crossref + format.pages + } + if$ + "" "\month" month do.out + stop.entry +} + +FUNCTION {book} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {booklet} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {inbook} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.type.chapter.pages + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { format.type.chapter.pages + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {incollection} +{ start.entry + format.artauthors + format.year + format.arttitle + format.editors + crossref missing$ + { format.in.ed.booktitle + format.number.series + "" "\city" address do.out + format.edition + format.type.chapter.pages + } + { format.incoll.inproc.crossref + format.type.chapter.pages + } + if$ + "" "\pubname" publisher do.out + stop.entry +} + +FUNCTION {inproceedings} +{ start.entry + format.authors + format.year + format.arttitle + crossref missing$ + { format.in.booktitle.or.series + format.number.series + "" "\city" address do.out + format.pages + } + { format.incoll.inproc.crossref + format.pages + } + if$ + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {conference} { inproceedings } + +FUNCTION {manual} +{ start.entry + format.authors + format.year + format.title + "" "\organization" organization do.out + "" "\city" address do.out + "" "\edition" edition do.out + stop.entry +} + +FUNCTION {mastersthesis} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibtype" type do.out + "" "\pubname" school do.out + "" "\month" month do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {misc} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\city" address do.out + "" "\month" month do.out + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + stop.entry +} + +FUNCTION {phdthesis} +{ start.entry + format.authors + format.title + format.year + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\pubname" school do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {proceedings} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {techreport} +{ start.entry + format.authors + format.year + format.t.title + format.tr.number + "" "\city" address do.out + "" "\pubname" institution do.out + stop.entry +} + +FUNCTION {unpublished} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + stop.entry +} + +% 4 additions from IEEEtran + +FUNCTION {electronic} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + "" "\city" address do.out + "" "\organization" organization do.out + "" "\howpublished" howpublished do.out + stop.entry +} +FUNCTION {patent} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibnumber" number do.out + "" "\city" address do.out + "" "\nationality" nationality do.out + "" "\assignee" assignee do.out + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\monthfiled" monthfiled do.out + "" "\yearfiled" yearfiled do.out + "" "\day" day do.out + "" "\dayfiled" dayfiled do.out + stop.entry +} +FUNCTION {periodical} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\bibnumber" number do.out + "" "\month" month do.out + "" "\organization" organization do.out + stop.entry +} +FUNCTION {standard} +{ start.entry + format.authors + format.year + format.title + "" "\bibtype" type do.out + "" "\organization" organization do.out + "" "\city" address do.out + "" "\revision" revision do.out + "" "\pubname" institution do.out + "" "\howpublished" howpublished do.out + "" "\bibnumber" number do.out + "" "\month" month do.out + stop.entry +} + +FUNCTION {IEEEtranBSTCTL} { } + + +FUNCTION {default.type} { misc } + +MACRO {jan} {"1"} +MACRO {feb} {"2"} +MACRO {mar} {"3"} +MACRO {apr} {"4"} +MACRO {may} {"5"} +MACRO {jun} {"6"} +MACRO {jul} {"7"} +MACRO {aug} {"8"} +MACRO {sep} {"9"} +MACRO {oct} {"10"} +MACRO {nov} {"11"} +MACRO {dec} {"12"} + +READ + +FUNCTION {initialize.ordinal.label} +{ #0 'ordinal.num := } + +FUNCTION {set.ordinal.label} { + #1 ordinal.num + 'ordinal.num := + ordinal.num int.to.str$ 'ordinal.label := +} + +EXECUTE {initialize.ordinal.label} + +ITERATE {set.ordinal.label} + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +FUNCTION {format.lab.names} +{ 's := + s #1 "{vv~}{ll}" format.name$ + "{" swap$ * "}" * + s num.names$ duplicate$ + #1 > + { pop$ "," * } + { pop$ } + if$ + s num.names$ duplicate$ + #2 > + { pop$ "{}" * } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{}" * } + { s #2 "{vv~}{ll}" format.name$ "{" swap$ * "}" * * } + if$ + } + if$ + } + if$ + "{" swap$ * "}," * +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.label} +{ editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.label} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.label + 'author.key.label + if$ + } + if$ + "a=" swap$ * "y=" * + year field.or.null purify$ #-1 #4 substring$ + * + 'label := +} + +INTEGERS { et.al.char.used } + +FUNCTION {initialize.et.al.char.used} +{ #0 'et.al.char.used := +} + +EXECUTE {initialize.et.al.char.used} + +FUNCTION {format.clab.names} +{ 's := + s num.names$ 'numnames := + numnames #1 > + { numnames #4 > + { #3 'namesleft := } + { numnames 'namesleft := } + if$ + #1 'nameptr := + "" + { namesleft #0 > } + { nameptr numnames = + { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + numnames #4 > + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + 'skip$ + if$ + } + { s #1 "{v{}}{l{}}" format.name$ + duplicate$ text.length$ #2 < + { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } + 'skip$ + if$ + } + if$ +} + +FUNCTION {author.key.clabel} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.editor.key.clabel} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.key.organization.clabel} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {editor.key.organization.clabel} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ +} + +FUNCTION {calc.clabel} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.clabel + { type$ "proceedings" = + 'editor.key.organization.clabel + { type$ "manual" = + 'author.key.organization.clabel + 'author.key.clabel + if$ + } + if$ + } + if$ + duplicate$ + year field.or.null purify$ #-1 #2 substring$ + * + 'clabel := + year field.or.null purify$ #-1 #4 substring$ + * + sortify 'sort.clabel := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ + s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { "et al" * } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.sort} +{ editor empty$ + { key empty$ + { "to sort, need editor or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {presort.title} +{ calc.label + calc.clabel + title field.or.null + sort.format.title + " " + * + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.author} +{ calc.clabel + calc.label + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.clabel} +{ calc.label + calc.clabel + clabel sortify + duplicate$ 'sort.label := + #1 entry.max$ substring$ + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {presort.none} +{ calc.label + calc.clabel + "" 'sort.label := + "" 'sort.key$ := +} + +ITERATE {presort.none} + +SORT + +FUNCTION {initialize.extra.label.stuff} +{ #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'last.extra.num := + #0 'ordinal.num := +} + +FUNCTION {forward.pass} +{ ordinal.num #1 + 'ordinal.num := + ordinal.num int.to.str$ 'nlabel := + last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ +} + +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + label extra.label * 'label := + clabel extra.label * 'clabel := + extra.label 'next.extra := + clabel width$ longest.label.width > + { clabel 'longest.label := + clabel width$ 'longest.label.width := + } + 'skip$ + if$ +} + +EXECUTE {initialize.extra.label.stuff} + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.sort.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := +} + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} + +REVERSE {reverse.pass} + +FUNCTION {bib.sort.order.author} +{ sort.label + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.title} +{ sort.label + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + * + " " + * + year field.or.null sortify + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.clabel} +{ sort.label + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.none} +{ sort.label 'sort.key$ := +} + +ITERATE {bib.sort.order.none} + +SORT + +EXECUTE {begin.bib} + +ITERATE {call.type$} + + +EXECUTE {end.bib} diff --git a/bibtex/bst/context/cont-ti.bst b/bibtex/bst/context/cont-ti.bst new file mode 100644 index 000000000..734cbb4b6 --- /dev/null +++ b/bibtex/bst/context/cont-ti.bst @@ -0,0 +1,1223 @@ +% Written by Taco Hoekwater +% Donated to the Public Domain. Use at your own risk. +% Preliminary version, 19-aug-1999. +% New 17/9/2003: 'eprint' and 'doi' tags + +% This style produces citations in a format the ConTeXt can handle. +% It outputs a large collection of labels so that context can decide +% which one to use. +% +% Actually, there are a number of separate bst files that change in +% only two lines: the ITERATEs right before the two SORTs can +% have different values, sorting by either one of +% +% -------------------------- cont-master.bst author +% - the author (+year, title) : cont-au.bst author +% - the title (+author, year) : cont-ti.bst title +% - the short key a la abbrev : cont-ab.bst clabel +% - nothing at all (cite order): cont-no.bst none +% +% +% Output gives the following computed info: +% +% - the total number of bib entries +% - the longest short label +% +% And per entry: +% +% - the key +% - the entry type +% - the yeardata for crossrefs +% - the authordata for crossrefs +% - the short key +% - the .bib appearance number + +% Commands that may be written to the bbl file (not counting stuff the +% bib database defines itself): +% +% \setuppublicationlist +% \startpublication +% \stoppublication + +% Field entries with a strange format/appearance: +% +% \artauthor, +% \editor, +% \author: \xxx[junior]{firstnames}[inits]{von}{lastname} + +% \etalchar: appears in short keys sometimes +% \maybeyear: appears in \pubyear sometimes +% +% And these commands for the entries have only one argument, +% precisely matching the corresponding field. Note that there +% are more fields supported than in the standard bst files. +% +% \abstract +% \annotate +% \arttitle +% \chapter +% \city +% \comment +% \country +% \crossref +% \edition +% \isbn +% \issn +% \issue +% \journal +% \keyword +% \keywords +% \lang +% \month +% \names +% \note +% \notes +% \organization +% \pages +% \pubname +% \pubyear +% \series +% \size +% \thekey +% \title +% \bibtype +% \volume +% \eprint +% \doi +% \howpublished +% \biburl +% \lastchecked +% for ieee: + +% \nationality +% \assignee +% \bibnumber +% \day +% \dayfiled +% \monthfiled +% \yearfiled +% \revision + +ENTRY + { abstract + address + annotate + author + booktitle + chapter + comment + country + doi + edition + editor + eprint + howpublished + institution + isbn + issn + journal + key + keyword + keywords + language + lastchecked + month + names + note + notes + number + organization + pages + publisher + school + series + size + title + type + url + volume + year + nationality + assignee + bibnumber + day + dayfiled + monthfiled + yearfiled + revision + } + {} + { label extra.label sort.label clabel sort.clabel ordinal.label} + + +STRINGS { s t autype} + +STRINGS { last.label next.extra nlabel } + +STRINGS { longest.label last.sort.label} + +INTEGERS { longest.label.width last.extra.num ordinal.num } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { len } + + +FUNCTION {begin.bib} +{ #0 'ordinal.num := + preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\setuppublicationlist[samplesize={" write$ + longest.label "},totalnumber=" * write$ + nlabel "]" * write$ + newline$ +} + +FUNCTION {end.bib} +{ newline$ +} + + + +FUNCTION {do.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ * "}" * * write$ pop$ newline$ } + if$ +} + + +FUNCTION {do.t.out} +{ duplicate$ empty$ + { pop$ pop$ write$} + { "{" swap$ "t" change.case$ * "}" * * write$ pop$ newline$ } + if$ +} + +FUNCTION {format.year} +{ year empty$ + 'skip$ + { "\pubyear{" year * write$ + extra.label empty$ + { "}" write$ } + { "\maybeyear{" extra.label * "}}" * write$ } + if$ + newline$ + } + if$ +} + +FUNCTION {start.entry} +{ ordinal.num #1 + 'ordinal.num := + newline$ + "\startpublication[" write$ + "k=" write$ + cite$ "," * write$ + "t=" write$ + type$ "," * write$ + newline$ + label write$ + "," write$ + doi empty$ + {} + { + "o={" write$ + doi write$ + "}," write$ + } if$ + newline$ + url empty$ + {} + { + "u={" write$ + url write$ + "}," write$ + newline$ + } if$ + "n=" write$ + ordinal.label write$ + ",s=" write$ + clabel write$ + "]" write$ + newline$ + "" "\lang" language do.out +} + +FUNCTION {stop.entry} +{ "" "\country" country do.out + "" "\note" note do.out + "" "\notes" notes do.out + "" "\annotate" annotate do.out + "" "\eprint" eprint do.out + "" "\doi" doi do.out + "" "\keyword" keyword do.out + "" "\keywords" keywords do.out + "" "\comment" comment do.out + "" "\abstract" abstract do.out + "" "\names" names do.out + "" "\size" size do.out + "" "\biburl" url do.out + "" "\lastchecked" lastchecked do.out + "\stoppublication" write$ + newline$ +} + + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + + +FUNCTION {format.names} +{ 's := 'autype := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { autype write$ + s nameptr "{jj}" format.name$ 't := + "[" t * "]" * write$ + s nameptr "{ff}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{f}" format.name$ add.period$ 't := + "[" t * "]" * write$ + s nameptr "{vv}" format.name$ 't := + "{" t * "}" * write$ + s nameptr "{ll}" format.name$ 't := + "{" t * "}" * write$ + newline$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + + +FUNCTION {format.key} +{ "" "\thekey" key do.out } + + +FUNCTION {format.artauthors} +{ author empty$ + { format.key } + { "\artauthor" author format.names } + if$ +} + +FUNCTION {format.authors} +{ author empty$ + { format.key } + { "\author" author format.names } + if$ +} + +FUNCTION {format.editors} +{ editor empty$ + { format.key } + { "\editor" editor format.names } + if$ +} + + +FUNCTION {format.title} +{ "" "\title" title do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.t.title} +{ "" "\title" title do.t.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.arttitle} +{ "" "\arttitle" title do.t.out } + +FUNCTION {format.journal} +{ "" "\journal" journal do.out + "" "\issn" issn do.out +} + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {format.volume} +{ "" "\volume" volume do.out +} + +FUNCTION {format.volume.issue} +{ "" "\volume" volume do.out + "" "\issue" number do.out +} + +FUNCTION {format.number.series} +{ "" "\series" series do.out + volume empty$ + { "" "\volume" number do.out + } + { "" "\volume" volume do.out + "" "\issue" number do.out } + if$ +} + +FUNCTION {format.edition} +{ "" "\edition" edition do.out + "" "\month" month do.out +} + +FUNCTION {format.pages} +{ "" "\pages" pages do.out } + + +FUNCTION {format.vol.num.pages} +{ format.volume.issue + format.pages +} + +FUNCTION {format.vol.num.page} +{ format.volume.issue + format.pages +} + +FUNCTION {format.type.chapter.pages} +{ chapter empty$ + 'format.pages + { "" "\bibtype" type do.out + "" "\chapter" chapter do.out + } + if$ + format.pages +} + +FUNCTION {format.booktitle} +{"" "\title" booktitle do.out + "" "\isbn" isbn do.out +} + +FUNCTION {format.in.ed.booktitle} +{ booktitle empty$ + 'skip$ + { format.booktitle } + if$ +} + +FUNCTION {format.in.booktitle.or.series} +{ "" "\series" series do.out + booktitle empty$ + 'skip$ + { editor empty$ + { format.booktitle } + { format.editors format.booktitle } + if$ + } + if$ +} + + +FUNCTION {format.tr.number} +{"" "\bibtype" type do.out + "" "\volume" number do.out +} + +FUNCTION {format.crossref} +{ "" "\crossref" crossref do.out +} + +FUNCTION {format.book.crossref} +{ + "" "\volume" volume do.out + format.crossref +} + +FUNCTION {format.incoll.inproc.crossref} +{ format.crossref +} + +FUNCTION {article} +{ start.entry + format.artauthors + format.year + format.arttitle + crossref missing$ + { format.journal + format.vol.num.pages + } + { format.crossref + format.pages + } + if$ + "" "\month" month do.out + stop.entry +} + +FUNCTION {book} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {booklet} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {inbook} +{ start.entry + author empty$ + { format.editors + } + { format.authors + } + if$ + format.year + format.title + crossref missing$ + { format.type.chapter.pages + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + } + { format.type.chapter.pages + format.book.crossref + } + if$ + format.edition + stop.entry +} + +FUNCTION {incollection} +{ start.entry + format.artauthors + format.year + format.arttitle + format.editors + crossref missing$ + { format.in.ed.booktitle + format.number.series + "" "\city" address do.out + format.edition + format.type.chapter.pages + } + { format.incoll.inproc.crossref + format.type.chapter.pages + } + if$ + "" "\pubname" publisher do.out + stop.entry +} + +FUNCTION {inproceedings} +{ start.entry + format.authors + format.year + format.arttitle + crossref missing$ + { format.in.booktitle.or.series + format.number.series + "" "\city" address do.out + format.pages + } + { format.incoll.inproc.crossref + format.pages + } + if$ + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {conference} { inproceedings } + +FUNCTION {manual} +{ start.entry + format.authors + format.year + format.title + "" "\organization" organization do.out + "" "\city" address do.out + "" "\edition" edition do.out + stop.entry +} + +FUNCTION {mastersthesis} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibtype" type do.out + "" "\pubname" school do.out + "" "\month" month do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {misc} +{ start.entry + format.authors + format.year + format.t.title + format.key + "" "\city" address do.out + "" "\month" month do.out + "" "\pubname" publisher do.out + "" "\howpublished" howpublished do.out + stop.entry +} + +FUNCTION {phdthesis} +{ start.entry + format.authors + format.title + format.year + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\pubname" school do.out + "" "\city" address do.out + stop.entry +} + +FUNCTION {proceedings} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\city" address do.out + "" "\pubname" publisher do.out + "" "\organization" organization do.out + stop.entry +} + +FUNCTION {techreport} +{ start.entry + format.authors + format.year + format.t.title + format.tr.number + "" "\city" address do.out + "" "\pubname" institution do.out + stop.entry +} + +FUNCTION {unpublished} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + stop.entry +} + +% 4 additions from IEEEtran + +FUNCTION {electronic} +{ start.entry + format.authors + format.year + format.t.title + "" "\month" month do.out + "" "\city" address do.out + "" "\organization" organization do.out + "" "\howpublished" howpublished do.out + stop.entry +} +FUNCTION {patent} +{ start.entry + format.authors + format.year + format.t.title + "" "\bibnumber" number do.out + "" "\city" address do.out + "" "\nationality" nationality do.out + "" "\assignee" assignee do.out + "" "\bibtype" type do.out + "" "\month" month do.out + "" "\monthfiled" monthfiled do.out + "" "\yearfiled" yearfiled do.out + "" "\day" day do.out + "" "\dayfiled" dayfiled do.out + stop.entry +} +FUNCTION {periodical} +{ start.entry + format.editors + format.year + format.title + format.number.series + "" "\bibnumber" number do.out + "" "\month" month do.out + "" "\organization" organization do.out + stop.entry +} +FUNCTION {standard} +{ start.entry + format.authors + format.year + format.title + "" "\bibtype" type do.out + "" "\organization" organization do.out + "" "\city" address do.out + "" "\revision" revision do.out + "" "\pubname" institution do.out + "" "\howpublished" howpublished do.out + "" "\bibnumber" number do.out + "" "\month" month do.out + stop.entry +} + +FUNCTION {IEEEtranBSTCTL} { } + + +FUNCTION {default.type} { misc } + +MACRO {jan} {"1"} +MACRO {feb} {"2"} +MACRO {mar} {"3"} +MACRO {apr} {"4"} +MACRO {may} {"5"} +MACRO {jun} {"6"} +MACRO {jul} {"7"} +MACRO {aug} {"8"} +MACRO {sep} {"9"} +MACRO {oct} {"10"} +MACRO {nov} {"11"} +MACRO {dec} {"12"} + +READ + +FUNCTION {initialize.ordinal.label} +{ #0 'ordinal.num := } + +FUNCTION {set.ordinal.label} { + #1 ordinal.num + 'ordinal.num := + ordinal.num int.to.str$ 'ordinal.label := +} + +EXECUTE {initialize.ordinal.label} + +ITERATE {set.ordinal.label} + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +FUNCTION {format.lab.names} +{ 's := + s #1 "{vv~}{ll}" format.name$ + "{" swap$ * "}" * + s num.names$ duplicate$ + #1 > + { pop$ "," * } + { pop$ } + if$ + s num.names$ duplicate$ + #2 > + { pop$ "{}" * } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{}" * } + { s #2 "{vv~}{ll}" format.name$ "{" swap$ * "}" * * } + if$ + } + if$ + } + if$ + "{" swap$ * "}," * +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.label} +{ editor empty$ + { key empty$ + { "{" cite$ * "}," *} + { "{" key * "}," * } + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.label} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.label + 'author.key.label + if$ + } + if$ + "a=" swap$ * "y=" * + year field.or.null purify$ #-1 #4 substring$ + * + 'label := +} + +INTEGERS { et.al.char.used } + +FUNCTION {initialize.et.al.char.used} +{ #0 'et.al.char.used := +} + +EXECUTE {initialize.et.al.char.used} + +FUNCTION {format.clab.names} +{ 's := + s num.names$ 'numnames := + numnames #1 > + { numnames #4 > + { #3 'namesleft := } + { numnames 'namesleft := } + if$ + #1 'nameptr := + "" + { namesleft #0 > } + { nameptr numnames = + { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + } + { s nameptr "{v{}}{l{}}" format.name$ * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + numnames #4 > + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + 'skip$ + if$ + } + { s #1 "{v{}}{l{}}" format.name$ + duplicate$ text.length$ #2 < + { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } + 'skip$ + if$ + } + if$ +} + +FUNCTION {author.key.clabel} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.editor.key.clabel} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {author.key.organization.clabel} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { author format.clab.names } + if$ +} + +FUNCTION {editor.key.organization.clabel} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { editor format.clab.names } + if$ +} + +FUNCTION {calc.clabel} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.clabel + { type$ "proceedings" = + 'editor.key.organization.clabel + { type$ "manual" = + 'author.key.organization.clabel + 'author.key.clabel + if$ + } + if$ + } + if$ + duplicate$ + year field.or.null purify$ #-1 #2 substring$ + * + 'clabel := + year field.or.null purify$ #-1 #4 substring$ + * + sortify 'sort.clabel := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ + s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { "et al" * } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.sort} +{ editor empty$ + { key empty$ + { "to sort, need editor or key in " cite$ * warning$ + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {presort.title} +{ calc.label + calc.clabel + title field.or.null + sort.format.title + " " + * + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.author} +{ calc.clabel + calc.label + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + #1 entry.max$ substring$ + 'sort.label := + sort.label + 'sort.key$ := +} + +FUNCTION {presort.clabel} +{ calc.label + calc.clabel + clabel sortify + duplicate$ 'sort.label := + #1 entry.max$ substring$ + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {presort.none} +{ calc.label + calc.clabel + "" 'sort.label := + "" 'sort.key$ := +} + +ITERATE {presort.title} + +SORT + +FUNCTION {initialize.extra.label.stuff} +{ #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'last.extra.num := + #0 'ordinal.num := +} + +FUNCTION {forward.pass} +{ ordinal.num #1 + 'ordinal.num := + ordinal.num int.to.str$ 'nlabel := + last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ +} + +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + label extra.label * 'label := + clabel extra.label * 'clabel := + extra.label 'next.extra := + clabel width$ longest.label.width > + { clabel 'longest.label := + clabel width$ 'longest.label.width := + } + 'skip$ + if$ +} + +EXECUTE {initialize.extra.label.stuff} + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.sort.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := +} + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} + +REVERSE {reverse.pass} + +FUNCTION {bib.sort.order.author} +{ sort.label + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.title} +{ sort.label + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + * + " " + * + year field.or.null sortify + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.clabel} +{ sort.label + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +FUNCTION {bib.sort.order.none} +{ sort.label 'sort.key$ := +} + +ITERATE {bib.sort.order.title} + +SORT + +EXECUTE {begin.bib} + +ITERATE {call.type$} + + +EXECUTE {end.bib} diff --git a/context/data/scite/cont-cs-scite.properties b/context/data/scite/cont-cs-scite.properties new file mode 100644 index 000000000..ddf42aacd --- /dev/null +++ b/context/data/scite/cont-cs-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.cs=CAP Cap Caps MESIC Rimskecislice SLOVA SLOVO Slova Slovo VSEDNIDEN Znak Znaky aktualnicislonadpisu aktualnidatum appendix barva bilemisto bublinkovanapoveda bypassblocks cap cernalinka cernelinky chapter chem cisla cislonadpisu citace citovat completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms completeregister coupledregister crlf datum definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling definetype definetypeface definuj definujbarvu definujblok definujbloksekce definujbuffer definujfont definujformatodkazu definujinterakcnimenu definujinterakcnimenu definujkombinovanyseznam definujkonverzi definujlogo definujnadpis definujobrazeksymbol definujodkaz definujodsazovani definujodstavce definujopis definujoramovani definujoramovanytext definujpaletu definujplvouciobjekt definujpodpole definujpole definujpopis definujpopisek definujprekryv definujpreskok definujprofil definujprogram definujprostredizakladnihofontu definujrejstrik definujsablonutabulky definujsekci definujseznam definujseznamodkazu definujskupinubarev definujstartstop definujsymbol definujsynonumumfontu definujsynonyma definujtabelaci definujtext definujtrideni definujupravu definujvelikostpapiru definujverzi definujvycet definujvystup definujzakladnifont definujzasobnikpoli definujznaceni description dodrzujprofil dodrzujverzi dodrzujverziprofilu dvoustrannypapir emptylines enumeration externiobraz footnotetext forceblocks framedtext hl hlavnijazyk indentation ininner inouter instalacejazyka interakcnilista interakcnitlacitka jazyk jdidolu jdina jdinabox klonujpole komentar konvertujcislo kopirujpole korekcebilehomista labeling listsymbol loadsorts loadsynonyms mapfontsize marginalnilinka marginalnitext matematika mediaeval meritko mesic mezera mrizka nadpis nadruhyokraj name naokraj nastavbarvu nastavbarvy nastavbilamista nastavblok nastavbloksekce nastavbuffer nastavcernelinky nastavcislonadpisu nastavcislostrany nastavcislovani nastavcislovaniodstavcu nastavcislovaniradku nastavcislovanistran nastavcitaci nastavdefinicipoznamekpodcarou nastavdeleniplvoucichobjektu nastavdelitko nastavdolnitexty nastavexterniobrazy nastavhorejsek nastavhornitexty nastavinterakci nastavinterakcnilistu nastavinterakcnimenu nastavinterakcniobrazovku nastavjazyk nastavkapitalky nastavkombinovanyseznam nastavkomentar nastavlegendu nastavmarginalie nastavmarginalniblok nastavmarginalnilinky nastavmeziradkovoumezeru nastavnadpis nastavnadpisy nastavodkazovani nastavodsazeni nastavodsazovani nastavodstavce nastavopis nastavoramovanetexty nastavoramovani nastavorez nastavotoceni nastavpaletu nastavplvouciobjekt nastavplvouciobjekty nastavpodcislostrany nastavpodtrzeni nastavpole nastavpolozky nastavpopisek nastavpopisky nastavpopisy nastavpozadi nastavpozadi nastavpoznamkypodcarou nastavprechodstrany nastavpreskok nastavprofily nastavprogramy nastavprostredizakladnihofontu nastavpublikace nastavradkovani nastavradky nastavrastr nastavrejstrik nastavrovnice nastavsadusymbolu nastavsekci nastavseznam nastavseznamodkazu nastavsirkucary nastavsloupce nastavspodek nastavspojeni nastavsynchronizaci nastavsynchronizacnilistu nastavsynonyma nastavsystem nastavtab nastavtabelaci nastavtabulky nastavtenkelinky nastavtext nastavtexthlavicky nastavtextovelinky nastavtextpopisku nastavtexttexty nastavtextyupati nastavtextyzahlavi nastavtlacitka nastavtoleranci nastavtrideni nastavtype nastavumisteniprotejsku nastavumistovani nastavupati nastavupravu nastavurl nastavusporadani nastavvelikostpapiru nastavverze nastavvsechnapole nastavvycty nastavvyplnovelinky nastavvyplnoveradky nastavvystup nastavvzhled nastavzahlavi nastavzakladnifont nastavzarovnani nastavznaceni nastavzuzeni nastrane nejakyradek nekde nextsection nivy nizky nocap nop obrazovka odkaz odkaz odkaznadatum odkaznastranu odkaznatext odsazovani okr opis opissoubor oramovani oref orez otocit overbar overbars overstrike overstrikes oznacverzi paragraph parovastrana part pis placefloat placelistoffloats placelistofsorts placelistofsynonyms placereferencelist pol pole polozka polozky popisky porovnejpaletu porovnejskupinubarev pozadi pozice poznamka poznamkapodcarou pref prelozit premistinamrizku prepninazakladnifont preskoc prizpusobivepole prizpusobvzhled program propojeneznaceni propojenydokument propojenyrejstrik publikace ran ref register reservefloat reset resettextcontent resetznaceni rimskecislice rozdelplvouciobjekt rozpojeneznaceni roztazene schovejbloky section sedabarva seeregister settextcontent setupfonthandling setupfontsynonym setupforms setupinterlinespace2 setupitemgroup setuplistalternative setuppaper setupstrut sloupec slovovpravo sort spodek stanovcharakteristickuseznamu stanovcislonadpisu startalignment startbarva startbuffer startbuffer startcitace startcolumns startcombination startdescription startdocument startenumeration startfakt startfigure startfloattext startformula startframedtext starthiding startinteraktivnimenu startitemgroup startkomentar startkomponenta startlegend startline startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginalnilinka startmarginblock startnamemakeup startnarrower startopposite startoverlay startoverview startparagraph startpositioning startpostponing startpozadi startprodukt startprofile startprojekt startprostredi startregister startsymbolset startsynchronization starttable starttables starttabulate starttextovalinka starttyping startunpacked startverze startzhustene stopalignment stopbarva stopbuffer stopbuffer stopcitace stopcolumns stopcombination stopdescription stopdocument stopenumeration stopfakt stopfigure stopfloattext stopformula stopframedtext stophiding stopinteraktivnimenu stopitemgroup stopkomentar stopkomponenta stoplegend stopline stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginalnilinka stopmarginblock stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stoppozadi stopprodukt stopprofile stopprojekt stopprostredi stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptextovalinka stoptyping stopunpacked stopverze stopzhustene strana sub subject subsection subsubject subsubsection subsubsubject sym symbol synchronizacnilista synchronizovat synonym tab tecky tenkalinka tenkelinky tex texthlavicky textovalinka textpopisku title tlacitko tref tvrdemezery typebuffer typstrany ukazbarvu ukazexterniobrazy ukazmrizku ukaznastaveni ukazpaletu ukazpodpery ukazpole ukazpostredizakladnihofontu ukazramecek ukazsadusymbolu ukazskupinubarev ukazupravu ukazvytisk ukazvzhled ukazzakladnifont umistikombinovanyseznam umistikombinovanyseznam umistilegendu umistiloga umistilokalnipoznamkypodcarou umistinadsebe umistinamrizku umistipodrovnici umistipoznamkypodcarou umistirejstrik umistirejstrik umistirovnici umistiseznam umistivedlesebe umistizalozky underbar underbars usedirectory usetypescript usetypescriptfile uzijURL uzijbloky uzijexternidokument uzijexterniobraz uzijexternisoubor uzijexternisoubory uzijexternizvuk uzijkodovani uzijmodul uzijodkazy uzijprikazy uzijspeciality uzijsymbol verze vl vlasovalinka vlevo vpravo vradku vsedniden vyberbloky vyberpapir vyberverzi vyplnenytext vyplnovelinky vyplnovepole vyplnovyradek vysoky zablokujinterakcnimenu zachovejbloky zadnamezera zadnebilemisto zadnedalsibloky zadnedalsisoubory zadnehorniadolniradky zadneodsazovani zadnezahlaviaupati zadneznaceni zadnyseznam zalozka zapisdorejstriku zapisdoseznamu zapisdoseznamuodkazu zapismeziseznam zaramovani zarovnanonastred zarovnanovlevo zarovnanovpravo zasobnikpoli zaznamovepole zhustene ziskejbuffer ziskejznaceni zlomek znaceni znak znaky zpracujbloky zpracujstranu zrcadlit zref \ No newline at end of file diff --git a/context/data/scite/cont-cz-scite.properties b/context/data/scite/cont-cz-scite.properties new file mode 100644 index 000000000..256a4ea3b --- /dev/null +++ b/context/data/scite/cont-cz-scite.properties @@ -0,0 +1,76 @@ +keywordclass.macros.context.cz=\ + MESIC Rimskecislice SLOVA SLOVO Slova Slovo \ + VSEDNIDEN Znak Znaky aktualnicislonadpisu aktualnidatum arg \ + barva bilemisto bublinkovanapoveda bypassblocks cernalinka cernelinky \ + chem cisla cislonadpisu citace citovat completeregister \ + crlf datum definerawfont definerule definetextposition definetextvariable \ + definetype definuj definujbarvu definujblok definujbloksekce definujbuffer \ + definujfont definujformatodkazu definujinterakcnimenu definujkombinovanyseznam definujkonverzi definujlogo \ + definujnadpis definujobrazeksymbol definujodkaz definujodsazovani definujodstavce definujopis \ + definujoramovani definujoramovanytext definujpaletu definujplvouciobjekt definujpodpole definujpole \ + definujpopis definujpopisek definujprekryv definujpreskok definujprofil definujprogram \ + definujprostredizakladnihofontu definujrejstrik definujsablonutabulky definujsekci definujseznam definujseznamodkazu \ + definujskupinubarev definujstartstop definujsymbol definujsynonyma definujtabelaci definujtext \ + definujtrideni definujupravu definujvelikostpapiru definujverzi definujvycet definujvystup \ + definujzakladnifont definujzasobnikpoli definujznaceni dodrzujprofil dodrzujverzi dodrzujverziprofilu \ + dvoustrannypapir emptylines externiobraz footnotetext forceblocks hl \ + hlavnijazyk ininner inouter instalacejazyka interakcnilista interakcnitlacitka \ + jazyk jdidolu jdina jdinabox klonujpole komentar \ + konvertujcislo kopirujpole korekcebilehomista listsymbol marginalnilinka marginalnitext \ + matematika meritko mesic mezera mrizka nadpis \ + nadruhyokraj nadtrzeni nadtrzeno naokraj nastavbarvu nastavbarvy \ + nastavbilamista nastavblok nastavbloksekce nastavbuffer nastavcernelinky nastavcislonadpisu \ + nastavcislostrany nastavcislovani nastavcislovaniodstavcu nastavcislovaniradku nastavcislovanistran nastavcitaci \ + nastavdefinicipoznamekpodcarou nastavdeleniplvoucichobjektu nastavdelitko nastavdolnitexty nastavexterniobrazy nastavhorejsek \ + nastavhornitexty nastavinterakci nastavinterakcnilistu nastavinterakcniobrazovku nastavjazyk nastavkapitalky \ + nastavkombinovanyseznam nastavkomentar nastavlegendu nastavmarginalie nastavmarginalniblok nastavmarginalnilinky \ + nastavmeziradkovoumezeru nastavnadpis nastavnadpisy nastavodkazovani nastavodsazeni nastavodsazovani \ + nastavodstavce nastavopis nastavoramovanetexty nastavoramovani nastavorez nastavotoceni \ + nastavpaletu nastavplvouciobjekt nastavplvouciobjekty nastavpodcislostrany nastavpodtrzeni nastavpole \ + nastavpolozky nastavpopisek nastavpopisky nastavpopisy nastavpozadi nastavpoznamkypodcarou \ + nastavprechodstrany nastavpreskok nastavprofily nastavprogramy nastavprostredizakladnihofontu nastavpublikace \ + nastavradkovani nastavradky nastavrastr nastavrejstrik nastavsadusymbolu nastavsekci \ + nastavseznam nastavseznamodkazu nastavsirkucary nastavsloupce nastavspodek nastavspojeni \ + nastavsynchronizaci nastavsynchronizacnilistu nastavsynonyma nastavsystem nastavtab nastavtabelaci \ + nastavtabulky nastavtenkelinky nastavtext nastavtexthlavicky nastavtextovelinky nastavtextpopisku \ + nastavtexttexty nastavtextyupati nastavtextyzahlavi nastavtlacitka nastavtoleranci nastavtrideni \ + nastavtype nastavumisteniprotejsku nastavumistovani nastavupati nastavupravu nastavurl \ + nastavusporadani nastavvelikostpapiru nastavverze nastavvsechnapole nastavvycty nastavvyplnovelinky \ + nastavvyplnoveradky nastavvystup nastavvzhled nastavzahlavi nastavzakladnifont nastavzarovnani \ + nastavznaceni nastavzuzeni nastrane nejakyradek nekde nivy \ + nizky nop obrazovka odkaz odkaznadatum odkaznastranu \ + odkaznatext odsazovani okr opis opissoubor oramovani \ + oref orez otocit oznacverzi parovastrana pis \ + placefloat placereferencelist placerule placetextvariable podtrzeni podtrzeno \ + pol pole polozka polozky popisky porovnejpaletu \ + porovnejskupinubarev positiontext pozadi pozice poznamka poznamkapodcarou \ + pref prelozit premistinamrizku prepninazakladnifont preskoc preskrtnuti \ + preskrtnuto prizpusobivepole prizpusobvzhled program propojeneznaceni propojenydokument \ + propojenyrejstrik publikace ran ref reset resetznaceni \ + rimskecislice rozdelplvouciobjekt rozpojeneznaceni roztazene schovejbloky scitani \ + sedabarva settextcontent settextvariable setupforms setupitemgroup setuppaper \ + setuprule setupstrut setuptextposition setuptextvariable sloupec slovovpravo \ + spodek stanovcharakteristickuseznamu stanovcislonadpisu start startbarva startcitace \ + startfakt startinteraktivnimenu startkomentar startkomponenta startmarginalnilinka startpozadi \ + startprodukt startprojekt startprostredi starttextovalinka startverze startzhustene \ + stop stopbarva stopcitace stopfakt stopinteraktivnimenu stopkomentar \ + stopkomponenta stopmarginalnilinka stoppozadi stopprodukt stopprojekt stopprostredi \ + stoptextovalinka stopverze stopzhustene strana switchtorawfont sym \ + symbol synchronizacnilista synchronizovat tab tecky tenkalinka \ + tenkelinky tex texthlavicky textovalinka textpopisku textvariable \ + tlacitko tref tvrdemezery typebuffer typstrany ukazbarvu \ + ukazexterniobrazy ukazmrizku ukaznastaveni ukazpaletu ukazpodpery ukazpole \ + ukazpostredizakladnihofontu ukazramecek ukazsadusymbolu ukazskupinubarev ukazupravu ukazvytisk \ + ukazvzhled ukazzakladnifont umistikombinovanyseznam umistilegendu umistiloga umistilokalnipoznamkypodcarou \ + umistinadsebe umistinamrizku umistipodrovnici umistipoznamkypodcarou umistirejstrik umistirovnici \ + umistiseznam umistivedlesebe umistizalozky uzijURL uzijbloky uzijexternidokument \ + uzijexterniobraz uzijexternisoubor uzijexternisoubory uzijexternizvuk uzijkodovani uzijmodul \ + uzijodkazy uzijprikazy uzijspeciality uzijsymbol verze vl \ + vlasovalinka vlevo vpravo vradku vsedniden vyberbloky \ + vyberpapir vyberverzi vyplnenytext vyplnovelinky vyplnovepole vyplnovyradek \ + vysoky zablokujinterakcnimenu zachovejbloky zadnamezera zadnebilemisto zadnedalsibloky \ + zadnedalsisoubory zadnehorniadolniradky zadneodsazovani zadnezahlaviaupati zadneznaceni zadnyseznam \ + zadnytest zalozka zapisdorejstriku zapisdoseznamu zapisdoseznamuodkazu zapismeziseznam \ + zaramovani zarovnanonastred zarovnanovlevo zarovnanovpravo zasobnikpoli zaznamovepole \ + zhustene ziskejbuffer ziskejznaceni zlomek znaceni znak \ + znaky zpracujbloky zpracujstranu zrcadlit zref diff --git a/context/data/scite/cont-de-scite.properties b/context/data/scite/cont-de-scite.properties new file mode 100644 index 000000000..b0e05b91a --- /dev/null +++ b/context/data/scite/cont-de-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.de=Buchstabe Buchstaben CAP Cap Caps MONAT Roemischezahlen WOCHENTAG WOERTER WORT Woerter Wort amgitterausrichten amgitterneuausrichten appendix aufseite ausfuellfeld ausfuelltext ausschnitt bearbeitebloecke bearbeiteseite behaltebloecke bei benutzekodierung benutzespezielles beschrifteversion beschriftung bestimmekopfnummer bestimmelistencharakeristika bildschirm blanko bookmark bruch buchstabe buchstaben but bypassblocks cap chapter chem completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms completeregister coupledregister crlf datum definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling defineoutput defineschriftsynonym definetype definetypeface definiereabbsymbol definiereabsaetze definiereabschnitt definiereabschnittsblock definierebeschreibung definierebeschreibungen definierebeschriftung definiereblanko definiereblock definiereeinzug definierefarbe definierefarbengruppe definierefeld definierefeldstapel definierefliesstext definierefliesstextumgebung definieregleitobjekt definiereinteraktionsmenue definiereinteraktionsmenue definierekonversion definierelabel definiereliste definierelogo definieren definierenummerierung definiereoverlay definierepalette definierepapierformat definiereprofil definiereprogramme definierepuffer definierereferenz definierereferenzformat definierereferenzliste definiereregister definiereschrift definieresortieren definierestartstop definieresubfeld definieresymbol definieresynonyme definieretabellenvorlage definieretabulator definieretext definieretippen definiereueberschrift definiereumbruch definiereumrahmt definiereumrahmtertext definiereversion definierezusammengestellteliste description doppelseite doppelseitigespapier drehen duennelinie duennerumriss einezeile einziehen emptylines entknuepfebeschriftung enumeration externeabbildung farbe feld feldstapel festesspatium folgeprofil folgeprofilversion folgeversion footnotetext forceblocks format framedtext fussnote gefuelltesrechteck gefuelltezeile gestreckt gitter graufarbe haarlinie hauptsprache heutigesdatum heutigeskopfnummer hintergrund hl hoch holebeschriftung holepuffer imlinken imrechten imumriss in inaktiviereinteraktionsmenue inanderermarginale indentation ininner inmarginalie inouter installieresprache interaktionsbalken interaktionsknopfe inzeile irgendwo its keinebeschriftung keinebloeckemehr keinedateienmehr keinekopfundfusszeilen keineliste keinspatium keinzeilenobenundunten keinzwischenraum kleinerdurchschuss klonierefeld knopf kommentar konvertierezahl kopf kopfnummer kopierefeld korrigierezwischenraum labeling labels labeltext linksbuendig listsymbol loadsorts loadsynonyms mapfontsize mar marginallinie marginaltext mathematik mediaeval monat nachunten name nextsection nichteinziehen nocap nop notiz overbar overbars overstrike overstrikes paragraph part passelayoutan passendfeld placefloat placelistoffloats placelistofsorts placelistofsynonyms placereferencelist platzierebookmarks platziereformel platzierefussnoten platzierelegende platziereliste platzierelogo platzierelokalefussnoten platzierenebeneinander platziereregister platziereregister platziereuntereinander platziereunterformel platzierezusammengestellteliste platzierezusammengestellteliste pos position posten programm publikation punkt ran rechteck rechtecke rechtsbuendig ref referenz register registrierefelder reservefloat resettextcontent roemischezahlen ruecksetzten ruecksetztenbeschriftung schreibezumregister schreibezurliste schreibezurreferenzliste schreibezwischenliste section seeregister seite seitenreferenz seitentyp settext setupfonthandling setupfontsynonym setupforms setupinterlinespace2 setupitemgroup setuplistalternative setuppaper setupstrut showsymbolset sort spalte spatium spiegeln sprache startalignment startbuffer startbuffer startcolumns startcombination startdescription startdocument startenumeration startfarbe startfigure startfloattext startformula startframedtext startgeg starthiding starthintergrund startinteraktionsmenue startitemgroup startkleinerdurchschuss startkommentar startkomponente startlegend startline startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginallinie startmarginblock startnamemakeup startnarrower startopposite startoverlay startoverview startparagraph startpositioning startpostponing startprodukt startprofile startprojekt startregister startsymbolset startsynchronization starttable starttables starttabulate starttextlinie starttyping startumgebung startunpacked startversion startzitat stelleabsaetzeein stelleabsatznummerierungein stelleabschnittein stelleabschnittsblockein stelleanordnenein stelleausgabeein stelleausrichtungein stelleausschnittein stellebeschreibungein stellebeschriftungein stellebilderunterschriftein stellebildunterschriftein stellebindestrichein stelleblankoein stelleblockein stelledrehenein stelleduennerumrissein stelleeinziehenein stelleeinzuegein stelleengerein stelleexterneabbildungenein stellefarbeein stellefarbenein stellefeldein stellefelderin stellefliesstextein stellefliesstextumgebungein stelleformelnein stellefussnotendefinitionein stellefussnotenein stellefusszeileein stellefusszeilentextein stellegefuelltesrechteckein stellegefuelltezeileein stellegegenueberplatzierenein stellegleitobjekteein stellegleitobjektein stellehintergruendeein stellehintergrundein stelleinmarginalieein stelleinteraktionein stelleinteraktionsbalkenein stelleinteraktionsbildschirmein stelleinteraktionsmenueein stelleknopfein stellekombinationein stellekommentarein stellekopfzahlein stellekopfzeileein stellekopfzeilentextein stellelabeltextein stellelayoutein stellelegendeein stellelinienbreiteein stellelisteein stellemarginalblockein stellemarginallinieein stellenobenein stellenummerierungein stellepaletteein stellepapierformatein stelleplatziegeteiltegleitobjekt stellepositionierenein stellepostenein stelleprofilein stelleprogrammein stellepublikationein stellepufferein stellerasterein stellerechteckein stellereferenzierenein stellereferenzlisteein stelleregisterein stelleseitennummerein stelleseitennummeriernungein stelleseitenuebergangein stellesortierenein stellespaltenein stellespatiumein stellespracheein stellesymbolsetein stellesynchronisationein stellesynchronisationsbalkenein stellesynonymein stellesystemein stelletabein stelletabellenein stelletabulatorein stelletextein stelletextobenein stelletexttexteein stelletextumrissein stelletextuntenein stelletipein stelletippenein stelletoleranzein stelleueberschriftein stelleueberschriftenein stelleueberschrifttextein stelleumbruchein stelleumrahmtein stelleumrahmtetexteein stelleuntenein stelleunterseitennummerein stelleunterstreichenein stelleurlein stelleversalienein stelleversionein stellezeilenabstandein stellezeilenein stellezeilennumerierungein stellezitierenein stellezusammengestelltelisteein stellezwischenraumein stopalignment stopbuffer stopbuffer stopcolumns stopcombination stopdescription stopdocument stopenumeration stopfarbe stopfigure stopfloattext stopformula stopframedtext stopgeg stophiding stophintergrund stopinteraktionsmenue stopitemgroup stopkleinerdurchschuss stopkommentar stopkomponente stoplegend stopline stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginallinie stopmarginblock stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stopprodukt stopprofile stopprojekt stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptextlinie stoptyping stopumgebung stopunpacked stopversion stopzitat sub subject subsection subsubject subsubsection subsubsubject sym symbol synchronisationsbalken synchronisieren synonym tab teilegleitobjekt tex textlinie textreferenz tief tiho tip tippedatei tippen tippepuffer title tooltip ueber ueberschrifttext uebersetzten umrahmt underbar underbars usedirectory usetypescript usetypescriptfile verbergebloecke vergleichefarbengruppe vergleichepalette verknuepfebeschriftung verknuepfedokument verknuepfregister version verweis verweisdatum verwendeURL verwendebefehl verwendebloecke verwendeexteresdokument verwendeexterneabbildung verwendeexternedatei verwendeexternedateien verwendeexternestonstueck verwendemodul verwendereferenzen verwendesymbole vl von waehlebloeckeaus waehlepapieraus waehleversionaus wechselezumfliesstext wochentag wortrechts zeigedruck zeigeeinstellungen zeigeexterneabbildungen zeigefarbe zeigefarbengruppe zeigefelder zeigefliesstext zeigefliesstextumgebung zeigegitter zeigelayout zeigepalette zeigerahmen zeigestruts zeigeumbruch zentriert ziffern zitat zitieren zu zurbox zwischenraum \ No newline at end of file diff --git a/context/data/scite/cont-en-scite.properties b/context/data/scite/cont-en-scite.properties new file mode 100644 index 000000000..a83042bf6 --- /dev/null +++ b/context/data/scite/cont-en-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.en=CAP Cap Caps Character Characters MONTH Romannumerals WEEKDAY WORD WORDS Word Words about adaptlayout appendix at atpage background blackrule blackrules blank bookmark but button bypassblocks cap chapter character characters chem clip clonefield color column comment comparecolorgroup comparepalet completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms completeregister convertnumber copyfield correctwhitespace coupledocument coupledregister couplemarking couplepage couplepaper coupleregister crlf currentdate currentheadnumber date decouplemarking define defineblank defineblock definebodyfont definebodyfontDEF definebodyfontREF definebodyfontenvironment definebuffer definecolor definecolorgroup definecombinedlist defineconversion definedescription definedfont defineenumeration definefield definefieldstack definefiguresymbol definefloat definefont definefontfeature definefonthandling definefontsynonym defineframed defineframedtext definehead defineindenting defineinteractionmenu defineinteractionmenu definelabel definelist definelogo definemakeup definemarking defineoutput defineoverlay definepalet definepapersize defineparagraphs defineprofile defineprogram definereference definereferenceformat definereferencelist defineregister definesection definesectionblock definesorting definestartstop definesubfield definesymbol definesynonyms definetabletemplate definetabulate definetext definetype definetypeface definetyping defineversion description determineheadnumber determinelistcharacteristics disableinteractionmenu emptylines enumeration externalfigure field fieldstack fillinfield fillinline fillinrules fillintext fitfield fixedspaces followprofile followprofileversion followversion footnote footnotetext forceblocks fraction framed framedtext from getbuffer getmarking godown goto gotobox graycolor grid hairline head headnumber headtext hideblocks high hl in indentation indenting inframed ininner inleft inline inmargin inothermargin inouter inright installlanguage interactionbar interactionbuttons item items its keepblocks labeling labels labeltext language leftaligned listsymbol loadsorts loadsynonyms logfields lohi low mainlanguage mapfontsize mar marginrule margintext marking markversion mathematics mediaeval midaligned mirror month moveongrid name nextsection nocap noheaderandfooterlines noindenting nolist nomarking nomoreblocks nomorefiles nop nospace note notopandbottomlines nowhitespace numbers overbar overbars overstrike overstrikes packed page pagereference pagetype paragraph part periods placebookmarks placecombinedlist placecombinedlist placefloat placefootnotes placeformula placelegend placelist placelistoffloats placelistofsorts placelistofsynonyms placelocalfootnotes placelogos placeongrid placeontopofeachother placereferencelist placeregister placeregister placesidebyside placesubformula position processblocks processpage program publication quotation quote ran ref reference referral referraldate register reservefloat reset resetmarking resettextcontent rightaligned romannumerals rotate scale screen section seeregister selectblocks selectpaper selectversion settextcontent setupalign setuparranging setupbackground setupbackgrounds setupblackrules setupblank setupblock setupbodyfont setupbodyfontenvironment setupbottom setupbottomtexts setupbuffer setupbuttons setupcapitals setupcaption setupcaptions setupclipping setupcolor setupcolors setupcolumns setupcombinations setupcombinedlist setupcomment setupdescriptions setupenumerations setupexternalfigures setupfield setupfields setupfillinlines setupfillinrules setupfloat setupfloats setupfloatsplitting setupfonthandling setupfontsynonym setupfooter setupfootertexts setupfootnotedefinition setupfootnotes setupforms setupformulae setupframed setupframedtexts setuphead setupheader setupheadertexts setupheadnumber setupheads setupheadtext setuphyphenmark setupindentations setupindenting setupinmargin setupinteraction setupinteractionbar setupinteractionmenu setupinteractionscreen setupinterlinespace setupinterlinespace2 setupitemgroup setupitems setuplabeltext setuplanguage setuplayout setuplegend setuplinenumbering setuplines setuplinewidth setuplist setuplistalternative setupmakeup setupmarginblocks setupmarginrules setupmarking setupnarrower setupnumbering setupoppositeplacing setupoutput setuppagenumber setuppagenumbering setuppagetransitions setuppalet setuppaper setuppapersize setupparagraphnumbering setupparagraphs setuppositioning setupprofiles setupprograms setuppublications setupquote setupreferencelist setupreferencing setupregister setuprotate setupscreens setupsection setupsectionblock setupsorting setupspacing setupstrut setupsubpagenumber setupsymbolset setupsynchronization setupsynchronizationbar setupsynonyms setupsystem setuptab setuptables setuptabulate setuptext setuptextrules setuptexttexts setupthinrules setuptolerance setuptop setuptoptexts setuptype setuptyping setupunderbar setupurl setupversions setupwhitespace showbodyfont showbodyfontenvironment showcolor showcolorgroup showexternalfigures showfields showframe showgrid showlayout showmakeup showpalet showprint showsetups showstruts showsymbolset someline somewhere sort space splitfloat startalignment startbackground startbuffer startbuffer startcolor startcolumns startcombination startcomment startcomponent startdescription startdocument startenumeration startenvironment startfact startfigure startfloattext startformula startframedtext starthiding startinteractionmenu startitemgroup startlegend startline startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginblock startmarginrule startnamemakeup startnarrower startopposite startoverlay startoverview startpacked startparagraph startpositioning startpostponing startproduct startprofile startproject startquotation startregister startsymbolset startsynchronization starttable starttables starttabulate starttextrule starttyping startunpacked startversion stopalignment stopbackground stopbuffer stopbuffer stopcolor stopcolumns stopcombination stopcomment stopcomponent stopdescription stopdocument stopenumeration stopenvironment stopfact stopfigure stopfloattext stopformula stopframedtext stophiding stopinteractionmenu stopitemgroup stoplegend stopline stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginblock stopmarginrule stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stoppacked stopparagraph stoppositioning stoppostponing stopproduct stopprofile stopproject stopquotation stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptextrule stoptyping stopunpacked stopversion stretched sub subject subsection subsubject subsubsection subsubsubject switchtobodyfont sym symbol synchronizationbar synchronize synonym tab tex textreference textrule thinrule thinrules title tooltip translate typ type typebuffer typefile underbar underbars useURL useblocks usecommands usedirectory useencoding useexternaldocument useexternalfigure useexternalfile useexternalfiles useexternalsoundtrack usemodule usereferences usespecials usesymbols usetypescript usetypescriptfile version vl weekday whitespace wordright writebetweenlist writetolist writetoreferencelist writetoregister \ No newline at end of file diff --git a/context/data/scite/cont-fr-scite.properties b/context/data/scite/cont-fr-scite.properties new file mode 100644 index 000000000..606be2efa --- /dev/null +++ b/context/data/scite/cont-fr-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.fr=CAP Cap Caps Caractere Caracteres Chiffresromains JOURSEMAINE MOIS MOT MOTS Mot Mots a adaptedisposition ajustechamp alaligne alapage aligneadroite aligneagauche aligneaumilieu appendix arriereplan baha barreinteraction barresynchronisation bas bouton boutonsinteraction but cacheblocs cap caractere caracteres champ changepolicecorps chapter chem chiffresromains citation citer clip clonechamp colonne commentaire comparegroupecouleur comparepalette completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms completeregistre composeenalinea concernant convertitnumero copitchamp corrigeespaceblanc couleur couleurgrise coupledocument coupledregister couplemarquage couplepapier coupleregistre crlf dactylographier dans dansautremarge dansdroite dansgauche dansmarge date datecourante daterecommandation de decouplemarquage definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling defineframed defineframedtext definetypeface definit definitbloc definitblocsection definitbuffer definitchamp definitcompoalinea definitconversion definitcouleur definitdactylo definitdemarrestoppe definitdescription definitenumeration definitenvironnementpolicecorps definitetiquette definitflottant definitformatreference definitgroupecouleur definitliste definitlisteimbriquee definitlistereference definitlogo definitmakeup definitmarquage definitmenuinteraction definitmenuinteraction definitnotepdp definitpalette definitparagraphes definitpilechamp definitpolice definitpolicecorps definitprofil definitprogramme definitreference definitregistre definitrevetement definitsection definitsortie definitsouschamp definitsymbole definitsymbolefigure definitsynonymepolice definitsynonymes definittabulation definittaillepapier definittete definittexte definittrametableau definittri definittype definitversion definitvide definitvide demarreciter deplacesurgrille description determinecaracteristiqueliste determinenumerotete echelle ecran ecritdansliste ecritdanslistereference ecritentreliste ecritregistre el element elements emptylines enumeration espace espaceblanc espacesfixes etiquettes etire fichierdactylo figureexterne forceblocs fraction framed framedtext gardeblocs grille groupe haut hl indentation inframed inhibemenuinteraction ininner inouter installelangue joursemaine labeling labeltexte langue langueprincipale ligneh lignenoire ligneregleetexte lignesnoires listesymbole loadsorts loadsynonyms logchamp mapfontsize mar margereglee marquage marquageversion marquepage mathematique mediaeval mois montrecadre montrechamps montrecouleur montredisposition montreedition montreenvironnementpolicecorps montrefiguresexternes montregrille montregroupecouleur montrejeusymboles montremakeup montrepalette montrepolicecorps montrereglages montrestruts motdroit name nextsection nocap nop note notepdp numeros numerotete numerotetecourant obtientmarquage oriente overbar overbars overstrike overstrikes page pagedouble paragraph part pasplusdeblocs pasplusdefichiers periodes pilechamp placecoteacote placeflottant placeformule placelegende placelesunsaudessusdesautres placeliste placelisteinmbriquee placelisteinmbriquee placelistereference placelistoffloats placelistofsorts placelistofsynonyms placelogos placemarquespages placenotespdp placenotespdplocales placeregistre placeregistre placesousformule placesurgrille position prendbuffer programme publication qqpart ran raz razmarquage recommandation ref reference referencepage referencetexte reflete register reglealignement reglealineas reglearrangement reglearriereplan reglearriereplans reglebarreinteraction reglebarresynchronisation reglebloc regleblocmarge regleblocsection regleboutons reglebuffer reglecapitales reglechamp reglechamps regleclipping reglecolonnes reglecombinaisons reglecommentaire reglecompoetroite reglecomposeenalinea reglecouleur reglecouleurs regledactylo regledansmarge regledescriptions regledisposition regleecraninteraction regleecrans regleelements regleencadre regleentete regleenumerations regleenvironnementpolicecorps regleepaisseurligne regleespaceblanc regleespacement regleespacementinterligne reglefiguresexternes regleflottant regleflottants regleformulaires regleformules regleinf regleinteraction regleintitule regleintitules reglejeusymboles reglelabeltexte reglelangue reglelegende reglelignes reglelignesnoires reglelignesreglestexte regleliste reglelisteimbriquee reglelistereference reglemakeup reglemargereglee reglemarquage reglemarquagehyphenation reglemenuinteraction reglenotepdp reglenumeropage reglenumerotation reglenumerotationligne reglenumerotationpage reglenumerotationparagraphe reglenumerotete regleoriente reglepalette reglepapier regleparagraphes reglepdp regleplacementopposition reglepolicecorps reglepositionnement regleprofils regleprogrammes reglepublications reglereferencage regleregistre regleremplitligne regleremplitlignesreglees reglesection regleseparationflottant reglesortie reglesouslignage reglesousnumeropage reglestrut reglesup reglesynchronisation reglesynonymes reglesysteme regletab regletableaux regletabulation regletaillepapier regletete regletetes regletexte regletextesentete regletextesinf regletextespdp regletextessup regletextestexte regletextetete regletolerance regletraitsfins regletransitionspage regletri regletype regleurl regleversions remplitchamp remplitligne remplitlignesreglees remplittexte reservefloat resettextcontent sansalinea sansespace sansespaceblanc sanslignesenteteetpdp sanslignessupetinf sansliste sansmarquage sauteblocs section seeregister selectionneblocs selectionnepapier selectionneversion separeflottant settext setupfonthandling setupfontsynonym setupframedtexts setupinterlinespace2 setupitemgroup setuplistalternative sort startalignment startarriereplan startbuffer startbuffer startcitation startcolumns startcombination startcommentaire startcomposant startcouleur startdescription startdocument startenumeration startenvironement startfait startfigure startfloattext startformula startframedtext startgroupe starthiding startitemgroup startlegend startligneregleetexte startline startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmargereglee startmarginblock startmenuinteraction startnamemakeup startnarrower startopposite startoverlay startoverview startparagraph startpositioning startpostponing startproduit startprofile startprojet startregister startsymbolset startsynchronization starttable starttables starttabulate starttyping startunpacked startversion stopalignment stoparriereplan stopbuffer stopbuffer stopcitation stopcolumns stopcombination stopcommentaire stopcomposant stopcouleur stopdescription stopdocument stopenumeration stopenvironement stopfait stopfigure stopfloattext stopformula stopframedtext stopgroupe stophiding stopitemgroup stoplegend stopligneregleetexte stopline stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmargereglee stopmarginblock stopmenuinteraction stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stopproduit stopprofile stopprojet stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptyping stopunpacked stopversion sub subject subsection subsubject subsubsection subsubsubject suggestion suivantprofil suivantversion suivantversionprofil sym symbole synchronise synonym tab tapebuffer tapepage tete tex textemarge textenotepdp textetete title traduire traiteblocs traitepage traitfin traitsfins typ underbar underbars uneligne usedirectory usetypescript usetypescriptfile utiliseURL utiliseblocs utilisecommandes utilisedocumentexterne utiliseencodage utilisefichierexterne utilisefichiersexternes utilisefigureexterne utilisemodule utilisepsiteaudioexterne utilisereferences utilisespecialites utilisesymboles va vaalaboite vaenbas version vide vl \ No newline at end of file diff --git a/context/data/scite/cont-it-scite.properties b/context/data/scite/cont-it-scite.properties new file mode 100644 index 000000000..da5df2400 --- /dev/null +++ b/context/data/scite/cont-it-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.it=CAP Cap Caps GIORNOSETTIMANA Lettera Lettere MESE Numeriromani PAROLA PAROLE Parola Parole accoppiacarta accoppiadocumento accoppiamarcatura accoppiapagina accoppiaregistro adattacampo adattalayout al allineacentro allineadestra allineasinistra ap apagina appendix barrainterazione barrasincronizzazione bastablocchi bastafile cambiaafontdeltesto campi camporiempimento cap capello chapter chim circondato citazione clip clonacampo colonna colore coloregrigio commento completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms completeregister confrontagruppocolori confrontatavolozza convertinumero copiacampo correggispaziobianco coupledregister crlf da daqualcheparte data datadioggi datareferral definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling definetypeface definisci definisciambientefontdeltesto definisciblocco definiscibloccosezione definiscibuffer definiscicampo definiscicapoversi definiscicolore definisciconversione definiscidescrizione definiscidimensionicarta definiscielenco definiscielencocombinato definiscienumerazione definiscietichetta definiscifigurasimbolo definiscifont definiscifontdeltesto definisciformatoriferimento definiscigruppocolori definisciincorniciato definisciiniziatermina definiscilistariferimenti definiscilogo definiscimakeup definiscimarcatura definiscimenuinterazione definiscimenuinterazione definiscimodellotabella definiscioggettomobile definisciordinamento definiscioutput definisciprofilo definisciprogramma definisciregistro definiscirientro definisciriferimento definiscirigovuoto definiscisezione definiscisimbolo definiscisinonimi definiscisinonimofont definiscisottocampo definiscisovrapposizione definiscistackcampi definiscitabulato definiscitavolozza definiscitesta definiscitesto definiscitestoincorniciato definiscitype definiscityping definisciversion description determinacarattersticheelenco determinanumerotesta disabilitamenuinterazione el elaborablocchi elaborapagina elementi elemento emptylines enumeration etichette figuraesterna fondo forzablocchi framedtext frazione giornosettimana griglia hl impaccato impostaallineamento impostaambientefontdeltesto impostaampiezzariga impostabarrainterazione impostabarrasincronizzazione impostablocchimargine impostablocco impostabloccosezione impostabuffer impostacampi impostacampo impostacapoversi impostacaption impostacaptions impostacima impostaclippling impostacolonne impostacolore impostacolori impostacombinazioni impostacommento impostadefinizionenotepdp impostadescrizioni impostadimensionicarta impostaelementi impostaelenco impostaelencocombinato impostaenumerazioni impostafigureesterne impostafondo impostafontdeltesto impostaforms impostaformule impostaincorniciato impostainmargine impostainstestazione impostainterazione impostainterlinea impostalayout impostalegenda impostalineemargine impostalineenere impostalineeriempimento impostalineesottili impostalineetesto impostalingua impostalistariferimenti impostamaiuscole impostamakeup impostamarcatura impostamenuinterazione impostamenzione impostanotepdp impostanumerazione impostanumerazionecapoversi impostanumerazionepagina impostanumerazionerighe impostanumeropagina impostanumerosottopagina impostanumerotesta impostaoggettimobili impostaoggettomobile impostaordinamento impostaoutput impostaparranging impostapdp impostapiustretto impostaposizionamento impostaposizionamentoopposti impostaprofili impostaprogrammi impostapubblicazioni impostapulsanti impostaregistro impostarientri impostarientro impostariferimento impostarighe impostarigheriempimento impostarigovuoto impostarotazione impostaschermi impostaschermointerazione impostasegnosillabazione impostasetsimboli impostasezione impostasfondi impostasfondo impostasincronizzazione impostasinonimi impostasistema impostasottolinea impostaspaziatura impostaspaziobianco impostaspezzamentooggettomobile impostastrut impostatab impostatabelle impostatabulato impostatavolozza impostatesta impostateste impostatesticima impostatestifondo impostatestiincorniciati impostatestiintestazioni impostatestipdp impostatesto impostatestoetichette impostatestointestazioni impostatestotesti impostatolleranza impostatransizionepagina impostatype impostatyping impostaurl impostaversioni in inaltromargine incorniciato indentation indestra ininner inmargine inouter inriga insinistra installalingua intorno labeling lettera lettere lineamargine lineanera lineasottile lineatesto lineenere lineeriempimento lineesottili lingua linguaprincipale listsymbol loadsorts loadsynonyms logcampi mapfontsize mar marcatura marcaversione matematica mediaeval menzione mese mettielenco mettielencocombinato mettielencocombinato mettifiancoafianco mettiformula mettiingriglia mettilegenda mettiloghi mettinotepdp mettinotepdplocali mettiregistro mettiregistro mettisegnalibro mettisottoformula mettiunosullaltro mostraambientefontdeltesto mostracampi mostracolore mostracornice mostrafiguresterne mostrafontdeltesto mostragriglia mostragruppocolori mostraimpostazioni mostralyout mostramakeup mostrasetsimboli mostrastampa mostrastruts mostratavolozza name nascondiblocchi nextsection nienteelenco nientelineecimafondo nientelineintestazionepdp nientemarcatura nienterientro nientespazio nientespaziobianco nocap nop nota notapdp numeri numeriromani numerotesta numerotestacorrente overbar overbars overstrike overstrikes pagina paragraph paroladestra part ped pedap placefloat placelistoffloats placelistofsorts placelistofsynonyms placereferencelist posizione prendibuffer prendimarcatura programma pubblicazione pulsante pulsantinterazione punti qualcheriga ran referral register reimposta reimpostamarcatura reservefloat resettextcontent rientro rif riferimento riferimentopagina riferimentotesto riflessione rigariempimento rigovuoto ruota saltablocchi scala schermo scrividentroelenco scriviinelenco scriviinlistariferimenti scriviinregistro section seeregister segnalibro seguiprofilo seguiversione seguiversioneprofilo selezionablocchi selezionacarta selezionaversione separamarcatura settext setupfonthandling setupfontsynonym setupinterlinespace2 setupitemgroup setuplistalternative setuppaper sfondo sim simbolo sincronizza sort spazifissi spazio spaziobianco spezzaoggettomobile spostaagriglia stackcampi startalignment startambiente startbuffer startbuffer startcitazione startcolore startcolumns startcombination startcommento startcomponenet startdescription startdocument startenumeration startfatto startfigure startfloattext startformula startframedtext starthiding startimpaccato startitemgroup startlegend startline startlineamargine startlineatesto startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginblock startmenuinterattivo startnamemakeup startnarrower startopposite startoverlay startoverview startparagraph startpositioning startpostponing startprodotto startprofile startprogetto startregister startsfondo startsymbolset startsynchronization starttable starttables starttabulate starttyping startunpacked startversione stirato stopalignment stopambiente stopbuffer stopbuffer stopcitazione stopcolore stopcolumns stopcombination stopcommento stopcomponenet stopdescription stopdocument stopenumeration stopfatto stopfigure stopfloattext stopformula stopframedtext stophiding stopimpaccato stopitemgroup stoplegend stopline stoplineamargine stoplineatesto stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginblock stopmenuinterattivo stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stopprodotto stopprofile stopprogetto stopsfondo stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptyping stopunpacked stopversione sub subject subsection subsubject subsubsection subsubsubject synonym tab testa testoetichetta testoinmargine testoinstestazioni testonotapdp testoriempimento tex tieniblocchi tipopagina title tooltip traduci typ type typebuffer typefile underbar underbars usaURL usablocco usacodifica usacolonnasonoraesterna usacomandi usadocumentoesterno usafiguraesterna usafileesterni usafileesterno usamodulo usariferimenti usasimboli usaspecialita usedirectory usetypescript usetypescriptfile vaia vaiabox vaigiu versione vl \ No newline at end of file diff --git a/context/data/scite/cont-nl-scite.properties b/context/data/scite/cont-nl-scite.properties new file mode 100644 index 000000000..688c8a7c0 --- /dev/null +++ b/context/data/scite/cont-nl-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.nl=CAP Cap Caps Letter Letters MAAND Romeins WEEKDAG WOORD WOORDEN Woord Woorden about achtergrond appendix bepaalkopnummer bepaallijstkenmerken blanko blokje blokjes blokkeerinteractiemenu bookmark breuk but button cap chapter chem cijfers citaat citeer clip commentaar completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms converteernummer copieerveld corrigeerwitruimte coupledregister crlf datum definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling definetypeface definieer definieeralineas definieerbeeldmerk definieerblanko definieerblok definieerbuffer definieerconversie definieerfiguursymbool definieerfont definieerfontsynoniem definieerinteractiemenu definieerinteractiemenu definieerkadertekst definieerkleur definieerkleurgroep definieerkop definieerkorps definieerkorpsomgeving definieerlijst definieermarkering definieeromlijnd definieeropmaak definieeroverlay definieerpalet definieerpapierformaat definieerplaatsblok definieerprofiel definieerprogramma definieerreferentie definieerreferentieformaat definieerreferentielijst definieerregister definieersamengesteldelijst definieersectie definieersectieblok definieersorteren definieerstartstop definieersubveld definieersymbool definieersynoniemen definieertabelvorm definieertabulatie definieertekst definieertype definieertypen definieeruitvoer definieerveld definieerveldstapel definieerversie description doordefinieren doorlabelen doornummeren doorspringen dunnelijn dunnelijnen eenregel enumeration ergens externfiguur forceerblokken framedtext gebruikURL gebruikblokken gebruikcommandos gebruikexterndocument gebruikexternefile gebruikexternefiles gebruikexternfiguur gebruikexterngeluidsfragment gebruikmodule gebruikreferenties gebruikspecials gebruiksymbolen gebruiktypescript gebruiktypescriptfile geenblokkenmeer geenbovenenonderregels geenfilesmeer geenhoofdenvoetregels geenlijst geenmarkering geenspatie geenwitruimte grijskleur haalbuffer haalmarkering haarlijn handhaafblokken hl hoofdtaal hoog huidigedatum huidigekopnummer in inanderemarge inbinnen inbuiten indentation inlijnd inlinker inmarge inrechter inregel inspringen installeertaal interactiebalk interactiebuttons invullijnen invulregel invultekst invulveld items its kantlijn kenmerk kenmerkdatum kleur kloonveld kolom kop kopnummer koppeldocument koppelmarkering koppelpagina koppelpapier koppelregister koptekst laag labeling labels labeltekst laho legeregels letter letters lijstsymbool loadsorts loadsynonyms maand mapfontsize mar margetekst markeer markeerversie mediaeval naar naarbox name nextsection nietinspringen nocap noot nop omlaag omlijnd ontkoppelmarkering op opelkaar oppagina overbar overbars overstrike overstrikes pagina paginareferentie paragraph part paslayoutaan passeerblokken passendveld plaatsbeeldmerken plaatsbookmarks plaatsformule plaatslegenda plaatslijst plaatslokalevoetnoten plaatsnaastelkaar plaatsonderelkaar plaatsopgrid plaatsplaatsblok plaatsreferentielijst plaatsregister plaatsregister plaatssamengesteldelijst plaatssamengesteldelijst plaatssubformule plaatsvoetnoten placelistoffloats placelistofsorts placelistofsynonyms positioneer programma publicatie punten ran ref referentie regellinks regelmidden regelrechts register registreervelden reservefloat reset resetmarkering resettextcontent romeins rooster roteer schaal scherm schrijfnaarlijst schrijfnaarreferentielijst schrijfnaarregister schrijftussenlijst section seeregister selecteerblokken selecteerpapier selecteerversie setupfonthandling setupfontsynonym setupinterlinespace2 setuplistalternative som soortpagina sort spatie spiegel splitsplaatsblok startachtergrond startalignment startbuffer startbuffer startcitaat startcolumns startcombination startcommentaar startdescription startdocument startenumeration startfigure startfloattext startformula startframedtext startgeg starthiding startinteractiemenu startitemgroup startkantlijn startkleur startlegend startline startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginblock startnamemakeup startnarrower startomgeving startonderdeel startopelkaar startopposite startoverlay startoverview startparagraph startpositioning startpostponing startprodukt startprofile startprojekt startregister startsymbolset startsynchronization starttable starttables starttabulate starttekstlijn starttyping startunpacked startversie stelachtergrondenin stelachtergrondin stelalineasin stelarrangerenin stelblankoin stelblokin stelblokjesin stelblokkopjein stelblokkopjesin stelbovenin stelboventekstenin stelbufferin stelbuttonsin stelciterenin stelclipin stelcombinatiesin stelcommentaarin steldoordefinierenin steldoornummerenin steldoorspringenin steldunnelijnenin stelexternefigurenin stelformulesin stelformulierenin stelhoofdin stelhoofdtekstenin stelinmargein stelinspringenin stelinteractiebalkin stelinteractiein stelinteractiemenuin stelinteractieschermin stelinterliniein stelinvullijnenin stelinvulregelsin stelitemgroepin stelitemsin stelkadertekstenin stelkantlijnin stelkapitalenin stelkleurenin stelkleurin stelkolommenin stelkopin stelkopnummerin stelkoppeltekenin stelkoppenin stelkoptekstin stelkorpsin stelkorpsomgevingin stellabeltekstin stellayoutin stellegendain stellijndiktein stellijstin stelmargeblokkenin stelmarkeringin stelnaastplaatsenin stelnummerenin stelomlijndin stelonderin stelonderstrepenin stelondertekstenin stelopmaakin stelpaginanummerin stelpaginanummeringin stelpaginaovergangenin stelpaletin stelpapierformaatin stelpapierin stelparagraafnummerenin stelplaatsblokin stelplaatsblokkenin stelplaatsbloksplitsenin stelpositionerenin stelprofielenin stelprogrammasin stelpublicatiesin stelrastersin stelreferentielijstin stelrefererenin stelregelnummerenin stelregelsin stelregisterin stelroterenin stelsamengesteldelijstin stelsectieblokin stelsectiein stelsmallerin stelsorterenin stelspatieringin stelstrutin stelsubpaginanummerin stelsymboolsetin stelsynchronisatiebalkin stelsynchronisatiein stelsynoniemenin stelsysteemin steltaalin steltabellenin steltabin steltabulatiein steltekstin steltekstinhoudin steltekstlijnenin stelteksttekstenin steltolerantiein steltypein steltypenin steluitlijnenin steluitvoerin stelurlin stelveldenin stelveldin stelversiesin stelvoetin stelvoetnootdefinitiein stelvoetnotenin stelvoettekstenin stelwitruimtein stopachtergrond stopalignment stopbuffer stopbuffer stopcitaat stopcolumns stopcombination stopcommentaar stopdescription stopdocument stopenumeration stopfigure stopfloattext stopformula stopframedtext stopgeg stophiding stopinteractiemenu stopitemgroup stopkantlijn stopkleur stoplegend stopline stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginblock stopnamemakeup stopnarrower stopomgeving stoponderdeel stopopelkaar stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stopprodukt stopprofile stopprojekt stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptekstlijn stoptyping stopunpacked stopversie sub subject subsection subsubject subsubsection subsubsubject suggestie switchnaarkorps sym symbool synchronisatiebalk synchroniseer synonym taal tab tekstlijn tekstreferentie tex title toonexternefiguren toongrid tooninstellingen toonkader toonkleur toonkleurgroep toonkorps toonkorpsomgeving toonlayout toonopmaak toonpalet toonprint toonstruts toonsymboolset toonvelden typ type typebuffer typefile uit uitgerekt underbar underbars usecodering usedirectory vastespaties veld veldstapel verbergblokken vergelijkkleurgroep vergelijkpalet verplaatsopgrid versie vertaal verwerkblokken verwerkpagina vl voetnoot voetnoottekst volgprofiel volgprofielversie volgversie volledigregister weekdag wiskunde witruimte woordrechts \ No newline at end of file diff --git a/context/data/scite/cont-pe-scite.properties b/context/data/scite/cont-pe-scite.properties new file mode 100644 index 000000000..a17695725 --- /dev/null +++ b/context/data/scite/cont-pe-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.pe=CAP Cap Caps Character Characters MONTH Romannumerals WEEKDAY WORD WORDS Word Words appendix cap chapter chem completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms coupledregister crlf definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling definetypeface description enumeration framedtext indentation its labeling loadsorts loadsynonyms mapfontsize mediaeval name nextsection nocap overbar overbars overstrike overstrikes paragraph part placelistoffloats placelistofsorts placelistofsynonyms ran register reservefloat resettextcontent section seeregister setupcapitals setupfonthandling setupfontsynonym setupinterlinespace2 setuplistalternative setupurl sort startalignment startbuffer startbuffer startcolumns startcombination startdescription startdocument startenumeration startfigure startfloattext startformula startframedtext starthiding startitemgroup startlegend startline startlinecorrection startlinenumbering startlines startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginblock startnamemakeup startnarrower startopposite startoverlay startoverview startparagraph startpositioning startpostponing startprofile startregister startsymbolset startsynchronization starttable starttables starttabulate starttyping startunpacked startتوضیح startتولید startحقیقت startخط‌حاشیه startخط‌متن startرنگ startفشرده startمحیط startمنوی‌پانل startمولفه startنسخه startنقل‌قول startپروژه startپس‌زمینه stopalignment stopbuffer stopbuffer stopcolumns stopcombination stopdescription stopdocument stopenumeration stopfigure stopfloattext stopformula stopframedtext stophiding stopitemgroup stoplegend stopline stoplinecorrection stoplinenumbering stoplines stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginblock stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stopprofile stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptyping stopunpacked stopتوضیح stopتولید stopحقیقت stopخط‌حاشیه stopخط‌متن stopرنگ stopفشرده stopمحیط stopمنوی‌پانل stopمولفه stopنسخه stopنقل‌قول stopپروژه stopپس‌زمینه sub subject subsection subsubject subsubsection subsubsubject synonym title tooltip typ underbar underbars useURL usedirectory آیتم آیتمها آینه اجباربلوکها از ازکارانداختن‌منوی‌پانل استفاده‌بلوکها استفاده‌دستخط‌تایپ استفاده‌رمزینه استفاده‌شکل‌خارجی استفاده‌فرمانها استفاده‌قطعه‌موزیک‌خارجی استفاده‌مدول استفاده‌مرجعها استفاده‌نمادها استفاده‌نوشتارخارجی استفاده‌ویژگیها استفاده‌پرونده‌خارجی استفاده‌پرونده‌دستخط‌تایپ استفاده‌پرونده‌های‌خارجی اعدادلاتین اما انتخاب‌برگ انتخاب‌بلوکها انتخاب‌نسخه انتقال‌به‌توری بارگذاری‌آرایش بارگذاری‌آیتمها بارگذاری‌ارجاع بارگذاری‌اندازه‌برگ بارگذاری‌باریکتر بارگذاری‌بافر بارگذاری‌بالا بارگذاری‌بخش بارگذاری‌بردباری بارگذاری‌برنامه‌ها بارگذاری‌برگ بارگذاری‌بست بارگذاری‌بلوک بارگذاری‌بلوکهای‌حاشیه بارگذاری‌بلوک‌بخش بارگذاری‌تایپ بارگذاری‌تایپ‌کردن بارگذاری‌تب بارگذاری‌ترتیب بارگذاری‌ترتیب بارگذاری‌ترکیب‌ها بارگذاری‌تطابق بارگذاری‌تعریف‌پانوشت بارگذاری‌تنظیم بارگذاری‌ته‌برگ بارگذاری‌تورفتگی بارگذاری‌تورفتگیها بارگذاری‌توضیح بارگذاری‌ثبت بارگذاری‌جدولها بارگذاری‌جدول‌بندی بارگذاری‌خالی بارگذاری‌خروجی بارگذاری‌خطها بارگذاری‌خطهای‌حاشیه بارگذاری‌خطهای‌سیاه بارگذاری‌خطهای‌متن بارگذاری‌خطها‌ی‌نازک بارگذاری‌درج‌درخطها بارگذاری‌درج‌مخالف بارگذاری‌درون‌حاشیه بارگذاری‌دوران بارگذاری‌دکمه‌ها بارگذاری‌راهنما بارگذاری‌رنگ بارگذاری‌رنگها بارگذاری‌زبان بارگذاری‌ستونها بارگذاری‌سر بارگذاری‌سربرگ بارگذاری‌سرها بارگذاری‌سیستم بارگذاری‌شرح بارگذاری‌شرح بارگذاری‌شرحها بارگذاری‌شماره‌زیرصفحه بارگذاری‌شماره‌سر بارگذاری‌شماره‌صفحه بارگذاری‌شماره‌گذاری بارگذاری‌شماره‌گذاریها بارگذاری‌شماره‌گذاری‌صفحه بارگذاری‌شماره‌گذاری‌پاراگراف بارگذاری‌شماره‌‌گذاری‌خط بارگذاری‌شناور بارگذاری‌شناورها بارگذاری‌شکافتن‌شناورها بارگذاری‌شکلهای‌خارجی بارگذاری‌طرح بارگذاری‌طرح‌بندی بارگذاری‌عرض‌خط بارگذاری‌فاصله‌بین‌خط بارگذاری‌فرمولها بارگذاری‌فضای‌سفید بارگذاری‌فضا‌گذاری بارگذاری‌قالبی بارگذاری‌قلم‌متن بارگذاری‌لوح بارگذاری‌لیست بارگذاری‌لیست‌ترکیبی بارگذاری‌لیست‌مرجع بارگذاری‌مترادفها بارگذاری‌متن بارگذاری‌متنهای‌بالا بارگذاری‌متن‌سر بارگذاری‌متن‌سربرگ بارگذاری‌متن‌قالبی بارگذاری‌متن‌متنها بارگذاری‌متن‌پانوشت بارگذاری‌متن‌پایین بارگذاری‌مجموعه‌نماد بارگذاری‌محیط‌قلم‌متن بارگذاری‌منوی‌پانل بارگذاری‌مکان‌گذاری بارگذاری‌میدان بارگذاری‌میدانها بارگذاری‌میله‌تطابق بارگذاری‌میله‌زیر بارگذاری‌میله‌پانل بارگذاری‌نسخه‌ها بارگذاری‌نشانه‌شکستن بارگذاری‌نشانه‌گذاری بارگذاری‌نشرها بارگذاری‌نقل بارگذاری‌پاراگرافها بارگذاری‌پانل بارگذاری‌پانوشتها بارگذاری‌پایین بارگذاری‌پرده‌ها بارگذاری‌پرده‌پانل بارگذاری‌پروفایلها بارگذاری‌پرکردن‌خطها بارگذاری‌پس‌زمینه بارگذاری‌پس‌زمینه‌ها بارگذاری‌چیدن بارگذاری‌گذارصفحه بارگذاری‌گروه‌آیتم بازنشانی بازنشانی‌نشانه‌گذاری باگذاری‌متن‌برچسب بدون‌بلوکهای‌بیشتر بدون‌تورفتگی بدون‌خط‌بالاوپایین بدون‌خط‌سروته‌برگ بدون‌فایلهای‌بیشتر بدون‌فضا بدون‌فضای‌سفید بدون‌لیست بدون‌نشانه‌گذاری برنامه بروبه بروبه‌جعبه بروپایین برچسبها بلند بلوکهای‌پردازش بلوکها‌پنهان بنویس‌بین‌لیست بنویس‌درثبت بنویس‌درلیست‌مرجع بنویس‌در‌لیست تاریخ تاریخ‌جاری تاریخ‌رجوع تایپ تایپ‌بافر تایپ‌پرونده تب ترجمه تطابق تعریف تعریف‌آرایش تعریف‌آرم تعریف‌الگوی‌جدول تعریف‌اندازه‌برگ تعریف‌بافر تعریف‌بخش تعریف‌برنامه تعریف‌برچسب تعریف‌بلوک تعریف‌بلوک‌بخش تعریف‌تایپ تعریف‌تایپ‌کردن تعریف‌تبدیل تعریف‌ترتیب تعریف‌توده‌میدان تعریف‌تورفتگی تعریف‌ثبت تعریف‌جدول‌بندی تعریف‌خالی تعریف‌خروجی تعریف‌رنگ تعریف‌زیرمیدان تعریف‌سر تعریف‌شرح تعریف‌شروع‌پایان تعریف‌شماره‌بندی تعریف‌شمایل‌مرجع تعریف‌شناور تعریف‌قالبی تعریف‌قلم تعریف‌قلم‌متن تعریف‌لوح تعریف‌لیست تعریف‌لیست‌ترکیبی تعریف‌لیست‌مرجع تعریف‌مترادفها تعریف‌مترادف‌قلم تعریف‌متن تعریف‌متن‌قالبی تعریف‌محیط‌قلم‌بدنه تعریف‌مرجع تعریف‌منوی‌پانل تعریف‌منوی‌پانل تعریف‌میدان تعریف‌نسخه تعریف‌نشانه‌گذاری تعریف‌نماد تعریف‌نمادشکل تعریف‌پاراگرافها تعریف‌پروفایل تعریف‌پوشش تعریف‌گروه‌رنگ تعیین‌شماره‌سر تعیین‌محتوای‌متن تعیین‌مشخصات‌لیست تغییربه‌قلم‌بدنه تنظیم‌راست تنظیم‌طرح‌بندی تنظیم‌وسط تورفتگی توری توضیح تک ثبت‌زوج ثبت‌کامل جداسازی‌نشانه‌گذاری حاش حرف حرفها حفظ‌بلوکها خالی خطهای‌سیاه خطهای‌نازک خطها‌خالی خط‌حاشیه خط‌سیاه خط‌متن خط‌مو خط‌نازک خ‌ا خ‌ع در درج‌آرمها درج‌ثبت درج‌ثبت درج‌درخط درج‌درخطها درج‌درمتن درج‌درمیدان درج‌در‌بالای‌یکدیگر درج‌در‌توری درج‌راهنما درج‌زیرفرمول درج‌شناور درج‌فرمول درج‌لیست درج‌لیست‌مختلط درج‌لیست‌مختلط درج‌لیست‌مرجع درج‌پانوشتها درج‌پانوشتهای‌موضعی درج‌چوب‌خط درج‌کنار‌به‌کنار درحاشیه درحاشیه‌دیگر درخارجی درخط درداخلی درراست درصفحه درقالبی درمورد درون درچپ دریافت‌بافر دریافت‌نشانه دوران دکمه دکمه‌پانل رج رجوع رنگ رنگ‌خاکستری روزهفته ریاضی زبان زبان‌اصلی ستون سر شماره‌سر شماره‌سرجاری شماره‌مبدل شماره‌ها شکافتن‌شناور شکل‌خارجی صفحه صفحه‌زوج صفحه‌پردازش عبوربلوکها فشرده فضا فضاهای‌ثابت فضای‌سفید فضای‌سفیدصحیح قالبی لوح‌مقایسه ماه متن‌برچسب متن‌حاشیه متن‌سر متن‌پانوشت مرجع مرجع‌صفحه مرجع‌متن مقایسه‌گروه‌رنگ مقیاس منفی مکان میدان میدانهای‌گزارش میدان‌شبیه‌سازی میدان‌پشته میدان‌کپی میله‌تطابق میله‌پانل نسخه نسخه‌نشانه نشانه‌گذاری نشانه‌گذاری‌زوج نشر نصب‌زبان نقطه‌ها نقل نقل‌قول نم نماد نمادلیست نمایش‌آرایش نمایش‌بارگذاریها نمایش‌بستها نمایش‌توری نمایش‌رنگ نمایش‌شکلهای‌خارجی نمایش‌طرح‌بندی نمایش‌قالب نمایش‌قلم‌بدنه نمایش‌لوح نمایش‌مجموعه‌علامت نمایش‌محیط‌قلم‌بدنه نمایش‌میدانها نمایش‌چاپ نمایش‌گروه‌رنگ نوشتارزوج نوع‌صفحه پابا پانوشت پایین پرده پرکردن‌میدان پس‌زمینه پیروی‌نسخه پیروی‌نسخه‌پروفایل پیروی‌پروفایل چوبخط چپ‌چین کاغذزوج کسر کشیده کلمه‌راست گیره یادداشت یک‌جا یک‌خط \ No newline at end of file diff --git a/context/data/scite/cont-ro-scite.properties b/context/data/scite/cont-ro-scite.properties new file mode 100644 index 000000000..47fd2b9c3 --- /dev/null +++ b/context/data/scite/cont-ro-scite.properties @@ -0,0 +1 @@ +keywordclass.macros.context.ro=CAP CUVANT CUVINTE Cap Caps Cuvant Cuvinte LUNA Litera Litere Numereromane ZIDINSAPTAMANA adapteazaaspect adubuffer adumarcaje afiseazaaspect afiseazacampuri afiseazaculoare afiseazafiguriexterne afiseazafonttext afiseazagrid afiseazagrupculoare afiseazamakeup afiseazamediufonttext afiseazapaleta afiseazarama afiseazasetari afiseazasetsimboluri afiseazastruts afiseazatiparire aliniat aliniatcentru aliniatdreapta aliniatstanga appendix ascundeblocuri barainteractiune barasincronizare blanc but butoaneinteractiune buton camp campumplere cap chapter chem citat clip cloneazacamp coloana comentariu comparagrupculoare comparapaleta completecombinedlist completelistoffloats completelistofsorts completelistofsynonyms completeregister convertestenumar copiazacamp corecteazaspatiualb coupledregister crlf culoare culoaregri cupleazadocument cupleazamarcaje cupleazaregistru cuvantdreapta data datacurenta datareferit decupleazamarcaje definebodyfontDEF definebodyfontREF definedfont definefontfeature definefonthandling defineste definestealiat definesteantet definesteblanc definestebloc definesteblocsectiune definestebuffer definestecamp definesteconversie definesteculoare definestedescriere definestedimensiunehartie definesteenumerare definesteeticheta definestefloat definestefont definestefonttext definesteformatreferinte definestegrupculori definesteinconjurare definestelista definestelistacombinata definestelistareferinte definestelogo definestemakeup definestemarcaje definestemediulfonttext definestemeniuinteractiune definestemeniuinteractiune definesteoutput definesteoverlay definestepaleta definesteparagraf definesteprofil definesteprogram definestereferinte definesteregistru definestesablontabel definestesectiune definestesimbol definestesimbolfigura definestesinonim definestesinonimfont definestesortare definestestartstop definestestivacampuri definestesubcamp definestetabulatori definestetext definestetexteinconjurate definestetextinconjurat definestetyping definesteversiune definetype definetypeface description despre determinacaracteristicilelistei determinanumartitlu dezactiveazameniuinteractiune din dute dutebox ecran el element element emptylines enumeration etichete faraaliniat farafisiere faraliniiantetsisubsol faraliniisussijos faralista faramarcaje faraspatiu faraspatiualb figuraexterna firdepar folosesteURL folosestebloc folosestecodificarea folosestecomenzi folosestedocumentextern folosestefiguraexterna folosestefisiereexterne folosestefisierextern folosestemodul folosestemuzicaexterna folosestereferinte folosestesimboluri folosestespeciale footnotetext forteazablocuri fractie framed framedtext fundal gatablocuri grid hartiedubla hl impachetat impartefloat in inalt inaltamargine indentation indreapta inframed ininner injos inlinie inouter instalarelimba instanga intins jos jossus la labeling lapagina limba limbaprincipala liniemargine linieneagra liniesubtire linieumplere liniinegre liniisubtiri listsymbol litera litere loadsorts loadsynonyms logcampuri luna mapfontsize mar marcaje marcheazaversiune marginal matematica mediaeval minicitat mutapegrid name nextsection nocap nop nota notasubsol numartitlu numartitlucurent numere numereromane olinie overbar overbars overstrike overstrikes pagina paginadubla paragraph part pastreazablocuri placefloat placelistoffloats placelistofsorts placelistofsynonyms placereferencelist plaseazapegrid plaseazasemnecarte potrivestecamp pozitie proceseazabloc proceseazapagina program publicatie puncte punedeasuprafiecareia punefatainfata puneformula punelegenda punelista punelistacombinata punelistacombinata punelogouri punenotesubsol punenotesubsollocale puneregistru puneregistru punesubformula ran ref referinta referintapagina referintatext referit reflexie register reservefloat reset reseteazamarcaje resettextcontent riglatext rigleumplere roteste saripesteblocuri scala scriebuffer scrieinlista scrieinlistareferinte scrieinregistru scrieintreliste section seeregister selecteazablocuri selecteazahartie selecteazaversiune semncarte setarebarasincronizare setarelimba setareoutput setarepozitie setaresincronizare seteazaaliniat seteazaaliniate seteazaalinierea seteazaantet seteazaaranjareapag seteazaaspect seteazabarainteractiune seteazablanc seteazabloc seteazablocsectiune seteazablocurimarginale seteazabuffer seteazabutoane seteazacamp seteazacampuri seteazaclipping seteazacoloane seteazacombinari seteazacomentariu seteazaculoare seteazaculori seteazadefinireanotasubsol seteazadescriere seteazadimensiunihartie seteazaecrane seteazaecraninteractiune seteazaelemente seteazaenumerare seteazafiguriexterne seteazafloat seteazafloats seteazafonttext seteazaformulare seteazaformule seteazafundal seteazafundaluri seteazagrosimelinie seteazaimpartireafloat seteazainconjurat seteazaingust seteazainteractiunea seteazajos seteazalegenda seteazalegenda seteazalegendele seteazaliniesilabe seteazaliniesubtire seteazalinii seteazaliniimargine seteazaliniinegre seteazaliniiumplere seteazalista seteazalistacombinata seteazalistareferinte seteazamajuscule seteazamakeup seteazamarcaje seteazamarginal seteazamediulfonttext seteazameniuinteractiune seteazaminicitat seteazanotasubsol seteazanumarpagina seteazanumarsubpagina seteazanumartitlu seteazanumerotare seteazanumerotarelinii seteazanumerotarepagina seteazanumerotareparagrafe seteazapaleta seteazaparagrafe seteazaplasareaopozita seteazaprofile seteazaprograme seteazapublicatii seteazareferinte seteazaregistru seteazarigletext seteazarigleumplere seteazarotare seteazasectiune seteazasimbol seteazasinonime seteazasistem seteazasortare seteazaspatiu seteazaspatiualb seteazaspatiuinterliniar seteazastrut seteazasublinie seteazasubsol seteazasus seteazatab seteazatabele seteazatabulatori seteazatext seteazatexteantet seteazatextejos seteazatextesubsol seteazatextesus seteazatextetext seteazatexteticheta seteazatexttitlu seteazatitlu seteazatitluri seteazatoleranta seteazatranzitiepagina seteazatype seteazatyping seteazaurl seteazaversiuni settextcontent setupfonthandling setupfontsynonym setupinterlinespace2 setupitemgroup setuplistalternative setuppaper sim simbol sincronizeaza sort spatiifixate spatiu spatiualb startalignment startbuffer startbuffer startcitat startcolumns startcombination startcomentariu startcomponenta startculoare startdescription startdocument startenumeration startfact startfigure startfloattext startformula startframedtext startfundal starthiding startimpachetat startitemgroup startlegend startline startlinecorrection startlinenumbering startlines startliniemargine startlocal startlocalenvironment startlocalfootnotes startmakeup startmarginblock startmediu startmeniuinteractiune startnamemakeup startnarrower startopposite startoverlay startoverview startparagraph startpositioning startpostponing startprodus startprofile startproiect startregister startriglatext startsymbolset startsynchronization starttable starttables starttabulate starttyping startunpacked startversiune stivacampuri stopalignment stopbuffer stopbuffer stopcitat stopcolumns stopcombination stopcomentariu stopcomponenta stopculoare stopdescription stopdocument stopenumeration stopfact stopfigure stopfloattext stopformula stopframedtext stopfundal stophiding stopimpachetat stopitemgroup stoplegend stopline stoplinecorrection stoplinenumbering stoplines stopliniemargine stoplocal stoplocalenvironment stoplocalfootnotes stopmakeup stopmarginblock stopmediu stopmeniuinteractiune stopnamemakeup stopnarrower stopopposite stopoverlay stopoverview stopparagraph stoppositioning stoppostponing stopprodus stopprofile stopproiect stopriglatext stopsymbolset stopsynchronization stoptable stoptables stoptabulate stoptyping stopunpacked stopversiune sub subject subsection subsubject subsubsection subsubsubject synonym tab tex texteticheta textmarginal texttitlu textumplere tippagina title titlu tooltip traduce trecilafonttext typ type typefile underbar underbars undeva urmeazaprofil urmeazaversiune urmeazaversiuneprofil usedirectory usetypescript usetypescriptfile versiune vl zidinsaptamana \ No newline at end of file diff --git a/context/data/scite/cont-xx-scite.properties b/context/data/scite/cont-xx-scite.properties new file mode 100644 index 000000000..395062b7a --- /dev/null +++ b/context/data/scite/cont-xx-scite.properties @@ -0,0 +1,178 @@ +# low level (visible) support macros, english only + +keywordclass.macros.context.undocumented.support=\ + doif doifelse doifnot \ + doifnothing doifsomething doifelsenothing \ + doifvalue doifnotvalue doifelsevalue \ + doifdefined doifundefined doifundefinedelse doifdefinedelse \ + doifinset doifinsetelse doifnotinsetelse \ + doifcommon doifnotcommon doifcommonelse \ + doifnextcharelse \ + doiffieldelse \ + ifdefined ifundefined ifconditional \ + setstrut setfontstrut strut begstrut endstrut strutdepth strutheight showstruts verticalstrut \ + newcounter increment decrement doglobal \ + expanded protect unprotect unprotected unexpanded \ + digits \ + snaptogrid \ + hpos vpos \ + readfile \ + donothing \ + doiftextelse doiftext \ + forgetall setlocalhsize localhsize \ + dogotopar dowithnextbox dowithnextboxcontent nextbox \ + tbox bbox sbox struttedbox \ + definemeasure definehspace hspace dontleavehmode \ + convertargument convertcommand \ + appendtoks prependtoks to at and \ + scratchcounter scratchbox scratchdimen scratchskip \ + zeropoint zerocount zerodimen \ + empty emptytoks plusone plustwo \ + setvalue setxvalue setevalue setgvalue letvalue letgvalue globalletvalue getvalue \ + beforesplitstring aftersplitstring splitstring \ + processcommalist processcommacommand commalistelement \ + processaction processallactionsinset processfirstactioninset \ + iftrialtypesetting \ + startbaselinecorrection stopbaselinecorrection \ + startnointerference stopnointerference \ + dorecurse dostepwiserecurse doloop exitloop \ + doifnotflagged doifflagged setflag + +# xml specific commands, english only + +keywordclass.macros.context.undocumented.xml=\ + defineXMLsave defineXMLgsave defineXMLenvironment defineXMLargument \ + defineXMLignore defineXMLcommand defineXMLgrouped defineXMLpickup defineXMLnested \ + defineXMLstore defineXMLenvironmentsave defineXMLprocess defineXMLsingular \ + saveXMLelement defineXMLgstore saveXMLasdata gsaveXMLasdata defineXMLsavecontent \ + doifXMLdataelse doifXMLdata saveXMLdata processXMLelement startXMLdata stopXMLdata \ + XMLflush flushXMLelement XMLerase \ + XMLpar XMLop doifXMLparelse doifXMLop \ + defXMLstring \ + processXMLbuffer useXMLfilter \ + countXMLchildren \ + startXMLignore stopXMLignore startXMLmapping stopXMLmapping \ + processXMLfile processXMLfilegrouped + +# metafun specific commands, english only + +keywordclass.macros.context.undocumented.metafun=\ + startMPgraphic stopMPgraphic includeMPgraphic useMPlibrary setupMPvariables \ + startMPenvironment stopMPenvironment startMPinclusions stopMPinclusions \ + MPcolor MPvar MPx MPy MPw MPh MPd MPp \ + starttypescript stoptypescript usetypescript loadmapfile \ + startMPdrawing stopMPdrawing MPdrawingdonetrue getMPdrawing resetMPdrawing \ + startuseMPgraphic stopuseMPgraphic startusableMPgraphic stopusableMPgraphic useMPgraphic \ + startuniqueMPpagegraphic stopuniqueMPpagegraphic uniqueMPpagegraphic \ + startreusableMPgraphic stopreusableMPgraphic reuseMPgraphic \ + startuniqueMPgraphic stopuniqueMPgraphic uniqueMPgraphic + +# modules + +keywordclass.macros.context.undocumented.modules=\ + setupFLOWcharts setupFLOWshapes setupFLOWlines \ + startFLOWchart stopFLOWchart FLOWchart includeFLOWchart startFLOWcell stopFLOWcell + +# english only commands + +keywordclass.macros.context.undocumented.common=\ + start stop \ + ConTeXt \ + environment component product project \ + starttextdata stoptextdata \ + definedfont definefontsynonym setupfontsynonym \ + vfilll hfilll \ + startmode startnotmode stopmode stopnotmode doifmode doifnotmode doifmodeelse enablemode disablemode \ + resetlayer definelayer placelayer flushlayer tightlayer setuplayer setlayer setlayerframed \ + definelayerpreset \ + overlayfigure overlaybutton \ + startsetups stopsetups startlocalsetups stoplocalsetups setups \ + setvariables setevariables setgvariables setxvariables getvariable \ + loadmapfile definetypeface usetypescript usetypescriptfile \ + useJSscripts startJSscripts stopJSscripts startJSpreamble stopJSpreamble startJScode stopJScode \ + showfont showaccents showcharacters \ + showlayoutcomponents showgridsnapping showgridboxes \ + startTEXpage stopTEXpage startMPpage stopMPpage \ + bTABLE eTABLE bTR eTR bTD eTD bTH eTH setupTABLE \ + bTABLEhead eTABLEhead bTABLEnext eTABLEnext bTABLEfoot eTABLEfoot bTABLEbody eTABLEbody \ + NC NR VL HL AR SR FR MR LR EQ + +# dutch commands (nl) + +keywordclass.macros.context.undocumented.main.nl=\ + starttekst stoptekst startstandaardopmaak stopstandaardopmaak \ + definieerlayout \ + definieerplaats \ + omgeving onderdeel projekt produkt \ + startopsomming stopopsomming stelopsommingin definieeritemgroep \ + stelnummeringin + +# english commands (en) + +keywordclass.macros.context.undocumented.main.en=\ + starttext stoptext startstandardmakeup stopstandardmakeup \ + placefigure definelayout setupencoding \ + defineframedcontent startframedcontent stopframedcontent \ + getfiguredimensionsonly defineexternalfigure \ + definemainfield \ + includemenu \ + starthanging stophanging \ + setupattachments \ + definepagebreak \ + startitemize stopitemize \ + startfrontmatter stopfrontmatter startbackmatter stopbackmatter \ + startbodymatter stopbodymatter startappendices stopappendices \ + definetextbackground setuptextbackground starttextbackground stoptextbackground \ + definepushbutton definepushsymbol \ + setcollector definecollector flushcollector + +# german commands (de) + +keywordclass.macros.context.undocumented.main.de=\ + +# czech commands (cz) + +keywordclass.macros.context.undocumented.main.cz=\ + +# italian commands (it) + +keywordclass.macros.context.undocumented.main.it=\ + +# romanian commands (ro) + +keywordclass.macros.context.undocumented.main.ro=\ + +# common undocumented macros + +keywordclass.macros.context.undocumented.base=\ + $(keywordclass.macros.context.undocumented.support) \ + $(keywordclass.macros.context.undocumented.xml) \ + $(keywordclass.macros.context.undocumented.metafun) \ + $(keywordclass.macros.context.undocumented.modules) \ + $(keywordclass.macros.context.undocumented.common) + +# language specific undocumented macros + +keywordclass.macros.context.undocumented.nl=\ + $(keywordclass.macros.context.undocumented.base) \ + $(keywordclass.macros.context.undocumented.main.nl) + +keywordclass.macros.context.undocumented.en=\ + $(keywordclass.macros.context.undocumented.base) \ + $(keywordclass.macros.context.undocumented.main.en) + +keywordclass.macros.context.undocumented.de=\ + $(keywordclass.macros.context.undocumented.base) \ + $(keywordclass.macros.context.undocumented.main.de) + +keywordclass.macros.context.undocumented.cz=\ + $(keywordclass.macros.context.undocumented.base) \ + $(keywordclass.macros.context.undocumented.main.cz) + +keywordclass.macros.context.undocumented.it=\ + $(keywordclass.macros.context.undocumented.base) \ + $(keywordclass.macros.context.undocumented.main.it) + +keywordclass.macros.context.undocumented.ro=\ + $(keywordclass.macros.context.undocumented.base) \ + $(keywordclass.macros.context.undocumented.main.ro) \ No newline at end of file diff --git a/context/data/scite/context.properties b/context/data/scite/context.properties new file mode 100644 index 000000000..13fa079c0 --- /dev/null +++ b/context/data/scite/context.properties @@ -0,0 +1,559 @@ +# file : context.properties +# version : 18 august 2003 +# author : Hans Hagen / PRAGMA ADE / www.pragma-ade.com + +# there but not yet working: + +# comment.box.start.tex=\n\\starthiding\n +# comment.box.middle.tex= +# comment.box.end.tex=\n\\stophiding\n + +# comment.box.start.xml= + +# comment.block.start.xml= + +# calltip.*.end.definition=% + +# This is the new default for windows 2000+ per 1.56: +# +# if PLAT_WIN +# find.command=findstr /n /s $(find.what) $(find.files) +# +# uncomment this (or move to user properties) if needed: +# +# if PLAT_WIN +# find.command=fgrep -G -n $(find.what) $(find.files) + +# Just UTF-8 + +code.page=65001 +output.code.page=65001 + +textwrapper.margin=4 +textwrapper.length=68 + +# ConTeXt: suffixes (really needed) + +file.patterns.tex= +file.patterns.latex= +file.patterns.context=*.tex;*.tui;*.tuo;*.sty;*.mkii;*.mkiv; + +# ConTeXt : keywords (if not yet loaded already) + +import cont-cz-scite +import cont-de-scite +import cont-en-scite +import cont-nl-scite +import cont-ro-scite +import cont-xx-scite +import metafun-scite +import latex-scite + +# Example : patterns + +file.patterns.xml= +file.patterns.example=*.xml;*.xsl;*.xsd;*.fo;*.exa;*.rlb;*.rlg;*.rlv;*.rng;*.xfdf;*.xslt;*.dtd;*.lmx;*.ctx + +filter.example=eXaMpLe|$(file.patterns.example)| + +lexer.$(file.patterns.example)=xml + +# Lua : patterns + +file.patterns.lua=*.lua;*.luc;*.cld;*.tuc;*.luj + +filter.lua=Lua MkIV|$(file.patterns.lua)| +lexer.$(file.patterns.lua)=lua + +command.compile.$(file.patterns.lua)=mtxrun --script "$(FileNameExt)" +command.go.$(file.patterns.lua)=mtxrun --script "$(FileNameExt)" + +# Commands: some scripts + +if PLAT_WIN + name.context.console=cmd + name.context.console=$(ComSpec) + name.context.gsview=gsview32.exe + name.context.acrobat= + name.texexec.flag.pdfopen=--autopdf + +# consoles: rxvt,konsole | acrobat: acroread,xpdfopen +# +# name.texexec.flag.pdfopen=--autopdf --xpdf + +if PLAT_GTK + name.context.console=rxvt + name.context.gsview=gv + name.context.acrobat=acroread + name.texexec.flag.pdfopen=--autopdf + +name.metafun.console=$(name.context.console) +name.example.console=$(name.context.console) + +if PLAT_WIN + name.context.mtxrun=mtxrun --autogenerate + +if PLAT_GTK + name.context.mtxrun=mtxrun --autogenerate + +name.context.concheck=$(name.context.mtxrun) --script check +name.context.texexec=$(name.context.mtxrun) --script context $(name.texexec.flag.pdfopen) +name.context.texshow=$(name.context.mtxrun) texshow +name.context.purge=$(name.context.mtxrun) ctxtools --purge --all +name.context.update=$(name.context.mtxrun) texshow --update --force +name.context.showcase=$(name.context.mtxrun) --launch showcase.pdf + +name.context.backend=pdf + +name.example.xmlcheck=tidy -quiet -utf8 -xml -errors + +name.metafun.mptopdf=$(name.context.mtxrun) --script mptopdf + +# if needed one can set MTX_SERVER_ROOT to the root of the documentation + +if PLAT_WIN + name.context.wwwserver=cmd /c start /min "Context Documentation" $(name.context.mtxrun) --script server --auto + +if PLAT_GTK + name.context.wwwserver=$(name.context.mtxrun) --script server --start > ~/context-wwwserver.log & + +# Commands: help info, e:\websites\www.pragma-ade.com\showcase.pdf / todo: manuals + +command.help.$(file.patterns.context)=$(name.context.texshow) $(CurrentWord) +command.help.$(file.patterns.example)= +command.help.$(file.patterns.metafun)= + +command.help.subsystem.$(file.patterns.context)=2 + +# Commands: tools menu extensions + +context.distribution.writable=1 + +# for the moment using subsystem 1 for perl jobs is better (otherwise dangling jobs) + +command.save.before=1 + +# xml completion + +xml.auto.close.tags=1 + +# extensions + +import scite-ctx + +# hard coded compile / build / go + +command.compile.$(file.patterns.context)=$(name.context.concheck) $(FileNameExt) +command.compile.$(file.patterns.metafun)= +command.compile.$(file.patterns.example)=$(name.example.xmlcheck) $(FileNameExt) +command.compile.*.fo=$(name.example.xmlcheck) $(FileNameExt) + +#command.compile.subsystem.$(file.patterns.context)=1 +#command.compile.subsystem.$(file.patterns.metafun)=1 +#command.compile.subsystem.$(file.patterns.example)=1 + +command.build.$(file.patterns.context)=$(name.context.texexec) --$(name.context.backend) $(FileNameExt) +command.build.$(file.patterns.metafun)=$(name.metafun.mptopdf) $(FileNameExt) +command.build.$(file.patterns.example)=$(name.context.texexec) --$(name.context.backend) --xml $(FileNameExt) +command.build.*.fo=$(name.context.texexec) --$(name.context.backend) $(name.texexec.flag.pdfopen) --xml --use=foxet $(FileNameExt) + +command.build.subsystem.$(file.patterns.context)=1 +command.build.subsystem.$(file.patterns.metafun)=1 +command.build.subsystem.$(file.patterns.example)=1 +command.build.subsystem.*.fo=1 + +if PLAT_WIN + command.go.$(file.patterns.context)=$(FileName).pdf + command.go.$(file.patterns.metafun)=$(FileName).pdf + command.go.$(file.patterns.example)=$(FileName).pdf + command.go.*.fo=$(FileName).pdf + +if PLAT_GTK + command.go.$(file.patterns.context)=$(name.context.acrobat) $(FileName).pdf + command.go.$(file.patterns.metafun)=$(name.context.acrobat) $(FileName).pdf + command.go.$(file.patterns.example)=$(name.context.acrobat) $(FileName).pdf + command.go.*.fo=$(name.context.acrobat) $(FileName).pdf + +command.go.subsystem.$(file.patterns.context)=2 +command.go.subsystem.$(file.patterns.metafun)=2 +command.go.subsystem.$(file.patterns.example)=2 +command.go.subsystem.*.fo=2 + +# 0 : syntax checking + +command.name.0.$(file.patterns.context)=Check TeX File +command.name.0.$(file.patterns.metafun)= +command.name.0.$(file.patterns.example)=Check XML File + +command.0.$(file.patterns.context)=$(name.context.concheck) $(FileNameExt) +command.0.$(file.patterns.metafun)= +command.0.$(file.patterns.example)=$(name.example.xmlcheck) $(FileNameExt) + +# 1 : normal processing + +command.name.1.$(file.patterns.context)=Process TeX file +command.name.1.$(file.patterns.metafun)=Process METAPOST File +command.name.1.$(file.patterns.example)=Process XML File + +command.1.$(file.patterns.context)=$(name.context.texexec) --$(name.context.backend) $(FileNameExt) +command.1.$(file.patterns.metafun)=$(name.context.texexec) --$(name.context.backend) --mptex $(FileNameExt) +command.1.$(file.patterns.example)=$(name.context.texexec) --$(name.context.backend) --xml $(FileNameExt) + +command.1.subsystem.$(file.patterns.context)=1 +command.1.subsystem.$(file.patterns.metafun)=1 +command.1.subsystem.$(file.patterns.example)=1 + +# 2 : pdf viewing + +command.name.2.$(file.patterns.context)=View PDF File +command.name.2.$(file.patterns.metafun)= +command.name.2.$(file.patterns.example)=View PDF File + +command.2.$(file.patterns.context)=$(name.context.gsview) $(FileName).pdf +command.2.$(file.patterns.metafun)= +command.2.$(file.patterns.example)=$(name.context.gsview) $(FileName).pdf + +command.subsystem.2.$(file.patterns.context)=2 +command.subsystem.2.$(file.patterns.metafun)=2 +command.subsystem.2.$(file.patterns.example)=2 + +# 2 : postscript + +# command.name.2.$(file.patterns.context)=View PS File +# command.name.2.$(file.patterns.metafun)=View PS File (1) +# command.name.2.$(file.patterns.example)=View PS File + +# command.2.$(file.patterns.context)=$(name.context.gsview) $(FileName).ps +# command.2.$(file.patterns.metafun)=$(name.context.gsview) $(FileName).1 +# command.2.$(file.patterns.example)=$(name.context.gsview) $(FileName).ps + +# command.subsystem.2.$(file.patterns.context)=2 +# command.subsystem.2.$(file.patterns.metafun)=2 +# command.subsystem.2.$(file.patterns.example)=2 + +# 3 : clean up + +command.name.3.$(file.patterns.context)=Purge Files +command.name.3.$(file.patterns.metafun)=Purge Files +command.name.3.$(file.patterns.example)=Purge Files + +command.3.$(file.patterns.context)=$(name.context.purge) +command.3.$(file.patterns.metafun)=$(name.context.purge) +command.3.$(file.patterns.example)=$(name.context.purge) + +# 4 : documentation + +command.4.$(file.patterns.context)=$(name.context.showcase) +command.4.$(file.patterns.metafun)=$(name.context.showcase) +command.4.$(file.patterns.example)=$(name.context.showcase) + +command.name.4.$(file.patterns.context)=Show Documentation +command.name.4.$(file.patterns.metafun)=Show Documentation +command.name.4.$(file.patterns.example)=Show Documentation + +# 5 : example framework applications + +#~ command.5=$(name.context.examplap) +#~ command.5.$(file.patterns.context)=$(name.context.examplap) +#~ command.5.$(file.patterns.metafun)=$(name.context.examplap) +#~ command.5.$(file.patterns.example)=$(name.context.examplap) + +#~ command.name.5=Start Interfaces +#~ command.name.5.$(file.patterns.context)=Start Interfaces +#~ command.name.5.$(file.patterns.metafun)=Start Interfaces +#~ command.name.5.$(file.patterns.example)=Start Interfaces + +# 6 : console + +command.name.6=Start Console +command.name.6.$(file.patterns.context)=Start Console +command.name.6.$(file.patterns.metafun)=Start Console +command.name.6.$(file.patterns.example)=Start Console + +command.6=$(name.context.console) +command.6.$(file.patterns.context)=$(name.context.console) +command.6.$(file.patterns.metafun)=$(name.context.console) +command.6.$(file.patterns.example)=$(name.context.console) + +# 7 : listings + +command.name.7=Generate Listing +command.name.7.$(file.patterns.context)=Generate Listing +command.name.7.$(file.patterns.metafun)=Generate Listing +command.name.7.$(file.patterns.example)=Generate Listing + +command.7=$(name.context.texexec) --$(name.context.backend) --list --result=$(FileName) $(FileNameExt) +command.7.$(file.patterns.context)=$(name.context.texexec) --$(name.context.backend) --list --result=$(FileName) $(FileNameExt) +command.7.$(file.patterns.metafun)=$(name.context.texexec) --$(name.context.backend) --list --result=$(FileName) $(FileNameExt) +command.7.$(file.patterns.example)=$(name.context.texexec) --$(name.context.backend) --list --result=$(FileName) $(FileNameExt) + +command.7.subsystem=1 +command.7.subsystem.$(file.patterns.context)=1 +command.7.subsystem.$(file.patterns.metafun)=1 +command.7.subsystem.$(file.patterns.example)=1 + +# 8 : reserved + +command.name.8.$(file.patterns.context)= +command.name.8.$(file.patterns.metafun)= +command.name.8.$(file.patterns.example)= +command.8.$(file.patterns.context)= +command.8.$(file.patterns.metafun)= +command.8.$(file.patterns.example)= + +# 9 : reserved + +command.name.9= +command.name.9.$(file.patterns.context)= +command.name.9.$(file.patterns.metafun)= +command.name.9.$(file.patterns.example)= +command.9.$(file.patterns.context)= +command.9.$(file.patterns.metafun)= +command.9.$(file.patterns.example)= + +# 10: arranging + +command.name.10.$(file.patterns.context)=Process and Arrange +command.name.10.$(file.patterns.metafun)=Process and Arrange +command.name.10.$(file.patterns.example)=Process and Arrange +command.10.$(file.patterns.context)=$(name.context.texexec) --arrange --$(name.context.backend) $(FileNameExt) +command.10.$(file.patterns.metafun)=$(name.context.texexec) --$(name.context.backend) --mptex $(FileNameExt) +command.10.$(file.patterns.example)=$(name.context.texexec) --arrange --$(name.context.backend) --xml $(FileNameExt) +command.10.subsystem.$(file.patterns.context)=1 +command.10.subsystem.$(file.patterns.metafun)=1 +command.10.subsystem.$(file.patterns.example)=1 + +# 11: make + +command.name.11.$(file.patterns.context)=Generate Formats (pdfTeX) +command.name.11.$(file.patterns.metafun)=Generate Formats +command.name.11.$(file.patterns.example)=Generate Formats +command.11.$(file.patterns.context)=$(name.context.texexec) --make --all --pdftex +command.11.$(file.patterns.metafun)=$(name.context.texexec) --make --all +command.11.$(file.patterns.example)=$(name.context.texexec) --make --all +command.11.subsystem.$(file.patterns.context)=1 +command.11.subsystem.$(file.patterns.metafun)=1 +command.11.subsystem.$(file.patterns.example)=1 + +# 12: make + +command.name.12.$(file.patterns.context)=Generate Formats (luaTeX) +command.12.$(file.patterns.context)=$(name.context.texexec) --make --all --luatex +command.12.subsystem.$(file.patterns.context)=1 + +# 13: make + +command.name.13.$(file.patterns.context)=Generate Formats (XeTeX) +command.13.$(file.patterns.context)=$(name.context.texexec) --make --all --xetex +command.13.subsystem.$(file.patterns.context)=1 + +# 14: update + +command.name.14=Update ConTeXt +command.name.14.$(file.patterns.context)=Update ConTeXt +command.name.14.$(file.patterns.metafun)=Update ConTeXt +command.name.14.$(file.patterns.example)=Update ConTeXt + +command.14=$(name.context.update) +command.14.$(file.patterns.context)=$(name.context.update) +command.14.$(file.patterns.metafun)=$(name.context.update) +command.14.$(file.patterns.example)=$(name.context.update) + +# 15: example + +command.name.15=Documentation Server +command.name.15.$(file.patterns.context)=Documentation Service +command.name.15.$(file.patterns.metafun)=Documentation Service +command.name.15.$(file.patterns.example)=Documentation Service + +command.15=$(name.context.wwwserver) +command.15.$(file.patterns.context)=$(name.context.wwwserver) +command.15.$(file.patterns.metafun)=$(name.context.wwwserver) +command.15.$(file.patterns.example)=$(name.context.wwwserver) + +# Editor: syntax highlighting + +view.indentation.guides=1 +highlight.indentation.guides=1 + +# Editor: keys + +user.shortcuts=\ +F12|IDM_COMPILE|\ +Ctrl+F12|IDM_BUILD|\ +Shift+F12|IDM_GO|\ +Alt+F12|IDM_STOPEXECUTE|\ + +# Editor: fonts (16.5/11.5) + +# install: fonts/truetype/hoekwater/lm/LMTypewriter10-Regular.ttf + +if PLAT_WIN + font.monospace=font:LMTypewriter10-Regular,size:14 + font.errorfont=font:LMTypewriter10-Regular,size:12 + +if PLAT_GTK + font.monospace=font:!lm mono 10 regular,size:14 + font.errorfont=font:!lm mono 10 regular,size:12 + +#~ if PLAT_WIN + #~ font.monospace=font:Lucida Console,size:12 + #~ font.monospace=font:Lucida Sans Unicode,size:12 + #~ font.monospace=font:OpenSymbol,size:17 + +font.base=$(font.monospace) +#~ font.small=$(font.monospace) +font.comment=$(font.monospace) +font.text=$(font.monospace) +font.text.comment=$(font.monospace) +font.embedded.base=$(font.monospace) +font.embedded.comment=$(font.monospace) +font.vbs=$(font.monospace) + +# Editor: colors + +color.back.linepanel=back:#A7A7A7 +color.back.textpanel=back:#CFCFCF +color.back.logpanel=back:#EFEFEF +color.back.selection=#F7F7F7 + +color.fore.red=fore:#7F0000 +color.fore.green=fore:#007F00 +color.fore.blue=fore:#00007F +color.fore.cyan=fore:#007F7F +color.fore.magenta=fore:#7F007F +color.fore.yellow=fore:#7F7F00 + +# Editor: fast switching between files + +tabbar.visible=1 +tabbar.hide.one=0 +tabbar.multiline=1 + +buffers=100 +load.on.activate=1 +check.if.already.open=1 +tabbar.multiline=1 + +# Editor: handy anyway + +line.margin.visible=1 +#~ line.numbers=6 +line.margin.width=3+ +title.full.path=1 +strip.trailing.spaces=1 +save.session=1 +save.recent=1 +open.dialog.in.file.directory=1 + +# Editor: tabbing + +tabsize=4 +indent.size=4 +use.tabs=0 +indent.automatic=1 +indent.opening=0 +indent.closing=0 + +# Editor: misc + +# edge.mode=0 +# edge.column=80 + +error.marker.fore=#FFFFFF +error.marker.back=#007F7F + +# Editor: status + +statusbar.visible=1 +statusbar.number=1 +statusbar.text.1=$(FileNameExt) | $(FileDate) $(FileTime) | line $(LineNumber) column $(ColumnNumber) | mode $(OverType) | eol $(EOLMode) | $(FileDate) $(FileTime) + +# Editor: searching + +find.files= +find.what= + +find.replace.regexp.posix=1 +find.files=*.tex *.xml *.mp + +if PLAT_WIN + find.command=fgrep -n $(find.what) $(find.files) + +source.files=$(file.patterns.context);$(file.patterns.metafun);$(file.patterns.example);*.pl;*.rb + +# Editor: printing + +if PLAT_WIN + print.colour.mode=1 + print.margins=750,750,750,750 + print.header.format=$(FileNameExt) Printed on $(CurrentDate), $(CurrentTime) Page $(CurrentPage) + print.footer.format=$(FilePath) File date: $(FileDate) File time: $(FileTime) + print.header.style=font:LMTypewriter10,size:10 + print.footer.style=font:LMTypewriter10,size:10 + +# Editor: processing + +clear.before.execute=1 +wrap.output=0 + +if PLAT_WIN + eol.mode=CRLF + +ensure.final.line.end=1 +ensure.consistent.line.ends=1 + +# Editor: file type + +default.file.ext=.tex + +# Editor: auto completion + +autocompleteword.automatic=1 +autocomplete.choose.single=0 + +api.*.tex=t:\sources\cont-en-scite.api + +# Logging + +style.errorlist.32=$(font.errorfont) + +# Default +style.errorlist.0=fore:#000000 +# python Error +style.errorlist.1=$(color.fore.red) +# gcc Error +style.errorlist.2=$(color.fore.red) +# Microsoft Error +style.errorlist.3=$(color.fore.red) +# command or return status +style.errorlist.4=$(color.fore.green) +# Borland error and warning messages +style.errorlist.5=$(color.fore.red) +# perl error and warning messages +style.errorlist.6=$(color.fore.red) +# .NET tracebacks +style.errorlist.7=$(color.fore.red) +# Lua error and warning messages +style.errorlist.8=$(color.fore.red) +# ctags +style.errorlist.9=$(color.fore.red) +# diff changed ! +style.errorlist.10=$(color.fore.green) +# diff addition + +style.errorlist.11=$(color.fore.blue) +# diff deletion - +style.errorlist.12=$(color.fore.cyan) +# diff message --- +style.errorlist.13=$(color.fore.red) +# PHP error +style.errorlist.14=$(color.fore.red) +# Essential Lahey Fortran 90 error +style.errorlist.15=$(color.fore.red) +# Intel Fortran Compiler error +style.errorlist.16=$(color.fore.red) + +# Context: end of file diff --git a/context/data/scite/cscite.rme b/context/data/scite/cscite.rme new file mode 100644 index 000000000..f084100c9 --- /dev/null +++ b/context/data/scite/cscite.rme @@ -0,0 +1,50 @@ +Files: + +cont-nl-scite.properties : keywords for the dutch user interface +cont-en-scite.properties : keywords for the english user interface +cont-de-scite.properties : keywords for the german user interface +cont-cz-scite.properties : keywords for the czech user interface +cont-it-scite.properties : keywords for the italian user interface +cont-ro-scite.properties : keywords for the romanian user interface +cont-xx-scite.properties : additional keywords +metafun-scite.properties : keywords for the metafun collection + +context.properties : a configuration suitable for context + + +Method 1: + +Copy the property files to the path where your local "SciTEUser.properties" +file lives. Add the following entries to "SciTEUser.properties": + +import cont-nl-scite +import cont-en-scite +import cont-de-scite +import cont-cz-scite +import cont-it-scite +import cont-ro-scite +import cont-xx-scite +import metafun-scite + +import context + +If you want latex syntax higlighting as well, you should also import the file +"latex-scite.properties" (no suffix needed). + + +Method 2: + +Copy the property files to the path where your local "SciTEGlobal.properties" +file lives. + +Copy the files "context.properties to the path where "SciTEUser.properties" +lives. Add the following entries to "SciTEUser.properties": + +import context + + +Info: + +Hans Hagen +PRAGMA ADE, Hasselt NL +http://www.pragma-ade.com \ No newline at end of file diff --git a/context/data/scite/latex-scite.properties b/context/data/scite/latex-scite.properties new file mode 100644 index 000000000..15e3579a7 --- /dev/null +++ b/context/data/scite/latex-scite.properties @@ -0,0 +1,2 @@ +keywordclass.macros.latex.all=\ + begin end documentstyle documentclass \ No newline at end of file diff --git a/context/data/scite/metafun-scite.properties b/context/data/scite/metafun-scite.properties new file mode 100644 index 000000000..55b7ae607 --- /dev/null +++ b/context/data/scite/metafun-scite.properties @@ -0,0 +1,19 @@ +keywordclass.metafun.all=\ + 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 \ + 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 \ No newline at end of file diff --git a/context/data/scite/scite-ctx.lua b/context/data/scite/scite-ctx.lua new file mode 100644 index 000000000..8e6b6ebab --- /dev/null +++ b/context/data/scite/scite-ctx.lua @@ -0,0 +1,838 @@ +-- version : 1.0.0 - 07/2005 (2008: lua 5.1) +-- author : Hans Hagen - PRAGMA ADE - www.pragma-ade.com +-- copyright : public domain or whatever suits +-- remark : part of the context distribution, my first lua code + +-- todo: name space for local functions + +-- loading: scite-ctx.properties + +-- # environment variable +-- # +-- # CTXSPELLPATH=t:/spell +-- # +-- # auto language detection +-- # +-- # % version =1.0 language=uk +-- # + +-- ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua +-- +-- # extension.$(file.patterns.context)=scite-ctx.lua +-- # extension.$(file.patterns.example)=scite-ctx.lua +-- +-- # ext.lua.reset=1 +-- # ext.lua.auto.reload=1 +-- # ext.lua.startup.script=t:/lua/scite-ctx.lua +-- +-- ctx.menulist.default=\ +-- wrap=wrap_text|\ +-- unwrap=unwrap_text|\ +-- sort=sort_text|\ +-- document=document_text|\ +-- quote=quote_text|\ +-- compound=compound_text|\ +-- check=check_text +-- +-- ctx.spellcheck.language=auto +-- ctx.spellcheck.wordsize=4 +-- ctx.spellcheck.wordpath=ENV(CTXSPELLPATH) +-- +-- ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt +-- +-- ctx.spellcheck.wordfile.uk=spell-uk.txt +-- ctx.spellcheck.wordfile.nl=spell-nl.txt +-- ctx.spellcheck.wordsize.uk=4 +-- ctx.spellcheck.wordsize.nl=4 +-- +-- command.name.21.*=CTX Action List +-- command.subsystem.21.*=3 +-- command.21.*=show_menu $(ctx.menulist.default) +-- command.groupundo.21.*=yes +-- command.shortcut.21.*=Shift+F11 +-- +-- command.name.22.*=CTX Check Text +-- command.subsystem.22.*=3 +-- command.22.*=check_text +-- command.groupundo.22.*=yes +-- command.shortcut.22.*=Ctrl+L +-- +-- command.name.23.*=CTX Wrap Text +-- command.subsystem.23.*=3 +-- command.23.*=wrap_text +-- command.groupundo.23.*=yes +-- command.shortcut.23.*=Ctrl+M +-- +-- # command.21.*=check_text +-- # command.21.*=dofile e:\context\lua\scite-ctx.lua + +-- generic functions + +props = props or { } -- setmetatable(props,{ __index = function(k,v) props[k] = "unknown" return "unknown" end } ) + +local byte, lower, upper, gsub, sub, find, rep, match, gmatch = string.byte, string.lower, string.upper, string.gsub, string.sub, string.find, string.rep, string.match, string.gmatch +local sort, concat = table.sort, table.concat + +local crlf = "\n" + +function traceln(str) + trace(str .. crlf) + io.flush() +end + +function string:grab(delimiter) + local list = {} + for snippet in self:gmatch(delimiter) do + list[#list+1] = snippet + end + return list +end + +function string:expand() + return (self:gsub("ENV%((%w+)%)", os.envvar)) +end + +function string:strip() + return (self:gsub("^%s*(.-)%s*$", "%1")) +end + +function table.alphasort(list,i) + if i and i > 0 then + local function alphacmp(a,b) + return lower(gsub(sub(a,i),'0',' ')) < lower(gsub(sub(b,i),'0',' ')) + end + sort(list,alphacmp) + else + local function alphacmp(a,b) + return lower(a) < lower(b) + end + sort(list,alphacmp) + end +end + +function io.exists(filename) + local ok, result, message = pcall(io.open,filename) + if result then + io.close(result) + return true + else + return false + end +end + +function os.envvar(str) + local s = os.getenv(str) + if s ~= '' then + return s + end + s = os.getenv(upper(str)) + if s ~= '' then + return s + end + s = os.getenv(lower(str)) + if s ~= '' then + return s + end +end + +-- support functions, maybe editor namespace + +-- function column_of_position(position) +-- local line = editor:LineFromPosition(position) +-- local oldposition = editor.CurrentPos +-- local column = 0 +-- editor:GotoPos(position) +-- while editor.CurrentPos ~= 0 and line == editor:LineFromPosition(editor.CurrentPos) do +-- editor:CharLeft() +-- column = column + 1 +-- end +-- editor:GotoPos(oldposition) +-- if line > 0 then +-- return column -1 +-- else +-- return column +-- end +-- end + +-- function line_of_position(position) +-- return editor:LineFromPosition(position) +-- end + +function extend_to_start() + local selectionstart = editor.SelectionStart + local selectionend = editor.SelectionEnd + local line = editor:LineFromPosition(selectionstart) + if line > 0 then + while line == editor:LineFromPosition(selectionstart-1) do + selectionstart = selectionstart - 1 + editor:SetSel(selectionstart,selectionend) + end + else + selectionstart = 0 + end + editor:SetSel(selectionstart,selectionend) + return selectionstart +end + +function extend_to_end() -- editor:LineEndExtend() does not work + local selectionstart = editor.SelectionStart + local selectionend = editor.SelectionEnd + local line = editor:LineFromPosition(selectionend) + while line == editor:LineFromPosition(selectionend+1) do + selectionend = selectionend + 1 + editor:SetSel(selectionstart,selectionend) + end + editor:SetSel(selectionstart,selectionend) + return selectionend +end + +function getfiletype() + local firstline = editor:GetLine(0) + if editor.Lexer == SCLEX_TEX then + return 'tex' + elseif editor.Lexer == SCLEX_XML then + return 'xml' + elseif find(firstline,"^%%") then + return 'tex' + elseif find(firstline,"^<%?xml") then + return 'xml' + else + return 'unknown' + end +end + +-- inspired by LuaExt's scite_Files + +function get_dir_list(mask) + local f + if props['PLAT_GTK'] and props['PLAT_GTK'] ~= "" then + f = io.popen('ls -1 ' .. mask) + else + mask = gsub(mask,'/','\\') + local tmpfile = 'scite-ctx.tmp' + local cmd = 'dir /b "' .. mask .. '" > ' .. tmpfile + os.execute(cmd) + f = io.open(tmpfile) + end + local files = {} + if not f then -- path check added + return files + end + for line in f:lines() do + files[#files+1] = line + end + f:close() + return files +end + +-- banner + +do + + print("loading scite-ctx.lua definition file\n") + print("- see scite-ctx.properties for configuring info\n") + print("- ctx.spellcheck.wordpath set to " .. props['ctx.spellcheck.wordpath']) + if find(lower(props['ctx.spellcheck.wordpath']),"ctxspellpath") then + if os.getenv('ctxspellpath') then + print("- ctxspellpath set to " .. os.getenv('CTXSPELLPATH')) + else + print("- 'ctxspellpath is not set") + end + print("- ctx.spellcheck.wordpath expands to " .. string.expand(props['ctx.spellcheck.wordpath'])) + end + print("\n- ctx.wraptext.length is set to " .. props['ctx.wraptext.length']) + if props['ctx.helpinfo'] ~= '' then + print("\n- key bindings:\n") + print((gsub(string.strip(props['ctx.helpinfo']),"%s*\|%s*","\n"))) + end + print("\n- recognized first lines:\n") + print("xml ", 2) + +function wrap_text() + + -- We always go to the end of a line, so in fact some of + -- the variables set next are not needed. + + local length = props["ctx.wraptext.length"] + + if length == '' then length = 80 else length = tonumber(length) end + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + editor:LineEndExtend() + + startposition = editor.SelectionStart + endposition = editor.SelectionEnd + + -- local startline = line_of_position(startposition) + -- local endline = line_of_position(endposition) + -- local startcolumn = column_of_position(startposition) + -- local endcolumn = column_of_position(endposition) + -- + -- editor:SetSel(startposition,endposition) + + local startline = props['SelectionStartLine'] + local endline = props['SelectionEndLine'] + local startcolumn = props['SelectionStartColumn'] - 1 + local endcolumn = props['SelectionEndColumn'] - 1 + + local replacement = { } + local templine = '' + local indentation = rep(' ',startcolumn) + local selection = editor:GetSelText() + + selection = gsub(selection,"[\n\r][\n\r]","\n") + selection = gsub(selection,"\n\n+",' ' .. magicstring .. ' ') + selection = gsub(selection,"^%s",'') + + for snippet in gmatch(selection,"%S+") do + if snippet == magicstring then + replacement[#replacement+1] = templine + replacement[#replacement+1] = "" + templine = '' + elseif #templine + #snippet > length then + replacement[#replacement+1] = templine + templine = indentation .. snippet + elseif #templine == 0 then + templine = indentation .. snippet + else + templine = templine .. ' ' .. snippet + end + end + + replacement[#replacement+1] = templine + replacement[1] = gsub(replacement[1],"^%s+",'') + + if endcolumn == 0 then + replacement[#replacement+1] = "" + end + + editor:ReplaceSel(concat(replacement,"\n")) + +end + +function unwrap_text() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + editor:HomeExtend() + editor:LineEndExtend() + + startposition = editor.SelectionStart + endposition = editor.SelectionEnd + + local magicstring = rep("", 2) + local selection = gsub(editor:GetSelText(),"[\n\r][\n\r]+", ' ' .. magicstring .. ' ') + local replacement = '' + + for snippet in gmatch(selection,"%S+") do + if snippet == magicstring then + replacement = replacement .. "\n" + else + replacement = replacement .. snippet .. "\n" + end + end + + if endcolumn == 0 then replacement = replacement .. "\n" end + + editor:ReplaceSel(replacement) + +end + +function sort_text() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + -- local startcolumn = column_of_position(startposition) + -- local endcolumn = column_of_position(endposition) + -- + -- editor:SetSel(startposition,endposition) + + local startline = props['SelectionStartLine'] + local endline = props['SelectionEndLine'] + local startcolumn = props['SelectionStartColumn'] - 1 + local endcolumn = props['SelectionEndColumn'] - 1 + + startposition = extend_to_start() + endposition = extend_to_end() + + local selection = gsub(editor:GetSelText(), "%s*$", '') + + list = string.grab(selection,"[^\n\r]+") + table.alphasort(list, startcolumn) + local replacement = concat(list, "\n") + + editor:GotoPos(startposition) + editor:SetSel(startposition,endposition) + + if endcolumn == 0 then replacement = replacement .. "\n" end + + editor:ReplaceSel(replacement) + +end + +function uncomment_xml() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + local selection = gsub(editor:GetSelText(), "%<%!%-%-.-%-%-%>", '') + + editor:GotoPos(startposition) + editor:SetSel(startposition,endposition) + + editor:ReplaceSel(selection) + editor:GotoPos(startposition) + +end + +function document_text() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + startposition = extend_to_start() + endposition = extend_to_end() + + editor:SetSel(startposition,endposition) + + local filetype = getfiletype() + + local replacement = '' + for i = editor:LineFromPosition(startposition), editor:LineFromPosition(endposition) do + local str = editor:GetLine(i) + if filetype == 'xml' then + if find(str,"^<%!%-%- .* %-%->%s*$") then + replacement = replacement .. gsub(str,"^<%!%-%- (.*) %-%->(%s*)$","%1\n") + elseif find(str,"%S") then + replacement = replacement .. '\n" + else + replacement = replacement .. str + end + else + if find(str,"^%%D%s+$") then + replacement = replacement .. "\n" + elseif find(str,"^%%D ") then + replacement = replacement .. gsub(str,"^%%D ",'') + else + replacement = replacement .. '%D ' .. str + end + end + end + + editor:ReplaceSel(gsub(replacement,"[\n\r]$",'')) + +end + +function quote_text() + + local filetype, leftquotation, rightquotation = getfiletype(), '', '' + + if filetype == 'xml' then + leftquotation, rightquotation = "", "" + leftquote, rightquote = "", "" + else + leftquotation, rightquotation = "\\quotation {", "}" + leftquote, rightquote = "\\quote {", "}" + end + + local replacement = editor:GetSelText() + replacement = gsub(replacement,"\`\`(.-)\'\'", leftquotation .. "%1" .. rightquotation) + replacement = gsub(replacement,"\"(.-)\"", leftquotation .. "%1" .. rightquotation) + replacement = gsub(replacement,"\`(.-)\'", leftquote .. "%1" .. rightquote ) + replacement = gsub(replacement,"\'(.-)\'", leftquote .. "%1" .. rightquote ) + editor:ReplaceSel(replacement) + +end + +function compound_text() + + local filetype = getfiletype() + + if filetype == 'xml' then + editor:ReplaceSel(gsub(editor:GetSelText(),"(>[^<%-][^<%-]+)([-\/])(%w%w+)","%1%3")) + else + editor:ReplaceSel(gsub(editor:GetSelText(),"([^\|])([-\/]+)([^\|])","%1|%2|%3")) + end + +end + +-- written while listening to Alanis Morissette's acoustic +-- Jagged Little Pill and Tori Amos' Beekeeper after +-- reinstalling on my good old ATH-7 + +local language = props["ctx.spellcheck.language"] +local wordsize = props["ctx.spellcheck.wordsize"] +local wordpath = props["ctx.spellcheck.wordpath"] + +if language == '' then language = 'uk' end +if wordsize == '' then wordsize = 4 else wordsize = tonumber(wordsize) end + +local wordfile = "" +local wordlist = {} +local worddone = 0 + +-- we use wordlist as a hash so that we can add entries without the +-- need to sort and also use a fast (built in) search + +-- function kpsewhich_file(filename,filetype,progname) +-- local progflag, typeflag = '', '' +-- local tempname = os.tmpname() +-- if progname then +-- progflag = " --progname=" .. progname .. " " +-- end +-- if filetype then +-- typeflag = " --format=" .. filetype .. " " +-- end +-- local command = "kpsewhich" .. progflag .. typeflag .. " " .. filename .. " > " .. tempname +-- os.execute(command) +-- for line in io.lines(tempname) do +-- return gsub(line, "\s*$", '') +-- end +-- end + +function check_text() + + local dlanguage = props["ctx.spellcheck.language"] + local dwordsize = props["ctx.spellcheck.wordsize"] + local dwordpath = props["ctx.spellcheck.wordpath"] + + if dlanguage ~= '' then dlanguage = tostring(language) end + if dwordsize ~= '' then dwordsize = tonumber(wordsize) end + + local firstline, skipfirst = editor:GetLine(0), false + local filetype, wordskip, wordgood = getfiletype(), '', '' + + if filetype == 'tex' then + wordskip = "\\" + elseif filetype == 'xml' then + wordskip = "<" + wordgood = ">" + end + + if props["ctx.spellcheck.language"] == 'auto' then + if filetype == 'tex' then + -- % version =1.0 language=uk + firstline = gsub(firstline,"^%%%s*",'') + firstline = gsub(firstline,"%s*$",'') + for key, val in gmatch(firstline,"(%w+)=(%w+)") do + if key == "language" then + language = val + traceln("auto document language " .. "'" .. language .. "' (tex)") + end + end + skipfirst = true + elseif filetype == 'xml' then + -- + firstline = gsub(firstline,"^%<%?xml%s*", '') + firstline = gsub(firstline,"%s*%?%>%s*$", '') + for key, val in gmatch(firstline,"(%w+)=[\"\'](.-)[\"\']") do + if key == "language" then + language = val + traceln("auto document language " .. "'" .. language .. "' (xml)") + end + end + skipfirst = true + end + end + + local fname = props["ctx.spellcheck.wordfile." .. language] + local fsize = props["ctx.spellcheck.wordsize." .. language] + + if fsize ~= '' then wordsize = tonumber(fsize) end + + if fname ~= '' and fname ~= wordfile then + wordfile, worddone, wordlist = fname, 0, {} + for filename in gmatch(wordfile,"[^%,]+") do + if wordpath ~= '' then + filename = string.expand(wordpath) .. '/' .. filename + end + if io.exists(filename) then + traceln("loading " .. filename) + for line in io.lines(filename) do + if not find(line,"^[\%\#\-]") then + str = gsub(line,"%s*$", '') + rawset(wordlist,str,true) + worddone = worddone + 1 + end + end + else + traceln("unknown file '" .. filename .."'") + end + end + traceln(worddone .. " words loaded") + end + + reset_text() + + if worddone == 0 then + traceln("no (valid) language or wordfile specified") + else + traceln("start checking") + if wordskip ~= '' then + traceln("ignoring " .. wordskip .. "..." .. wordgood) + end + local i, j, lastpos, startpos, endpos, snippet, len, first = 0, 0, -1, 0, 0, '', 0, 0 + local ok, skip, ch = false, false, '' + if skipfirst then first = #firstline end + for k = first, editor.TextLength do + ch = editor:textrange(k,k+1) + if wordgood ~= '' and ch == wordgood then + skip = false + elseif ch == wordskip then + skip = true + end + if find(ch,"%w") and not find(ch,"%d") then + if not skip then + if ok then + endpos = k + else + startpos = k + endpos = k + ok = true + end + end + elseif ok and not skip then + len = endpos - startpos + 1 + if len >= wordsize then + snippet = editor:textrange(startpos,endpos+1) + i = i + 1 + if wordlist[snippet] or wordlist[lower(snippet)] then + j = j + 1 + else + editor:StartStyling(startpos,INDICS_MASK) + editor:SetStyling(len,INDIC2_MASK) -- INDIC0_MASK+2 + end + end + ok = false + elseif wordgood == '' then + skip = (ch == wordskip) + end + end + traceln(i .. " words checked, " .. (i-j) .. " errors") + end + +end + +function reset_text() + editor:StartStyling(0,INDICS_MASK) + editor:SetStyling(editor.TextLength,INDIC_PLAIN) +end + +-- menu + +local menuactions = {} +local menufunctions = {} + +function UserListShow(menutrigger, menulist) + local menuentries = {} + local list = string.grab(menulist,"[^%|]+") + menuactions = {} + for i=1, #list do + if list[i] ~= '' then + for key, val in gmatch(list[i],"%s*(.+)=(.+)%s*") do + menuentries[#menuentries+1] = key + menuactions[key] = val + end + end + end + local menustring = concat(menuentries,'|') + if menustring == "" then + traceln("There are no templates defined for this file type.") + else + editor.AutoCSeparator = byte('|') + editor:UserListShow(menutrigger,menustring) + editor.AutoCSeparator = byte(' ') + end +end + +function OnUserListSelection(trigger,choice) + if menufunctions[trigger] and menuactions[choice] then + return menufunctions[trigger](menuactions[choice]) + else + return false + end +end + +-- main menu + +local menutrigger = 12 + +function show_menu(menulist) + UserListShow(menutrigger, menulist) +end + +function process_menu(action) + if not find(action,"%(%)$") then + assert(loadstring(action .. "()"))() + else + assert(loadstring(action))() + end +end + +menufunctions[12] = process_menu + +-- templates + +local templatetrigger = 13 + +local ctx_template_paths = { "./ctx-templates", "../ctx-templates", "../../ctx-templates" } +local ctx_auto_templates = false +local ctx_template_list = "" + +local ctx_path_list = {} +local ctx_path_done = {} +local ctx_path_name = {} + +function ctx_list_loaded(path) + return ctx_path_list[path] and #ctx_path_list[path] > 0 +end + +function insert_template(templatelist) + if props["ctx.template.scan"] == "yes" then + local path = props["FileDir"] + local rescan = props["ctx.template.rescan"] == "yes" + local suffix = props["ctx.template.suffix." .. props["FileExt"]] -- alas, no suffix expansion here + local current = path .. "+" .. props["FileExt"] + if rescan then + print("re-scanning enabled") + end + ctx_template_list = "" + if not ctx_path_done[path] or rescan then + local pattern = "*.*" + for i, pathname in ipairs(ctx_template_paths) do + print("scanning " .. gsub(path,"\\","/") .. "/" .. pathname) + ctx_path_name[path] = pathname + ctx_path_list[path] = get_dir_list(pathname .. "/" .. pattern) + if ctx_list_loaded(path) then + print("finished locating template files") + break + end + end + if ctx_list_loaded(path) then + print(#ctx_path_list[path] .. " template files found") + else + print("no template files found") + end + end + if ctx_list_loaded(path) then + ctx_template_list = "" + local pattern = "%." .. suffix .. "$" + local n = 0 + for j, filename in ipairs(ctx_path_list[path]) do + if find(filename,pattern) then + n = n + 1 + local menuname = gsub(filename,"%..-$","") + if ctx_template_list ~= "" then + ctx_template_list = ctx_template_list .. "|" + end + ctx_template_list = ctx_template_list .. menuname .. "=" .. ctx_path_name[path] .. "/" .. filename + end + end + if not ctx_path_done[path] then + print(n .. " suitable template files found") + end + end + ctx_path_done[path] = true + if ctx_template_list == "" then + ctx_auto_templates = false + else + ctx_auto_templates = true + templatelist = ctx_template_list + end + else + ctx_auto_templates = false + end + if templatelist ~= "" then + UserListShow(templatetrigger, templatelist) + end +end + + +-- ctx.template.[whatever].[filetype] +-- ctx.template.[whatever].data.[filetype] +-- ctx.template.[whatever].file.[filetype] +-- ctx.template.[whatever].list.[filetype] + +function process_template_one(action) + local text = nil + if ctx_auto_templates then + local f = io.open(action,"r") + if f then + text = gsub(f:read("*all"),"\n$","") + f:close() + else + print("unable to auto load template file " .. text) + text = nil + end + end + if not text or text == "" then + text = props["ctx.template." .. action .. ".file"] + if not text or text == "" then + text = props["ctx.template." .. action .. ".data"] + if not text or text == "" then + text = props["ctx.template." .. action] + end + else + local f = io.open(text,"r") + if f then + text = gsub(f:read("*all"),"\n$","") + f:close() + else + print("unable to load template file " .. text) + text = nil + end + end + end + if text then + text = gsub(text,"\\n","\n") + local pos = find(text,"%?") + text = gsub(text,"%?","") + editor:insert(editor.CurrentPos,text) + if pos then + editor.CurrentPos = editor.CurrentPos + pos - 1 + editor.SelectionStart = editor.CurrentPos + editor.SelectionEnd = editor.CurrentPos + editor:GotoPos(editor.CurrentPos) + end + end +end + +menufunctions[13] = process_template_one +menufunctions[14] = process_template_two + +-- command.name.26.*=Open Logfile +-- command.subsystem.26.*=3 +-- command.26.*=open_log +-- command.save.before.26.*=2 +-- command.groupundo.26.*=yes +-- command.shortcut.26.*=Ctrl+E + +function open_log() + scite.Open(props['FileName'] .. ".log") +end diff --git a/context/data/scite/scite-ctx.properties b/context/data/scite/scite-ctx.properties new file mode 100644 index 000000000..f23508aca --- /dev/null +++ b/context/data/scite/scite-ctx.properties @@ -0,0 +1,155 @@ +# author +# +# Hans Hagen - PRAGMA ADE - www.pragma-ade.com +# +# environment variable +# +# CTXSPELLPATH=t:/spell +# +# auto language detection +# +# % version =1.0 language=uk +# + +ext.lua.auto.reload=1 +#~ ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua +ext.lua.startup.script=$(SciteUserHome)/scite-ctx.lua + +#~ extension.$(file.patterns.context)=scite-ctx.lua +#~ extension.$(file.patterns.example)=scite-ctx.lua + +#~ ext.lua.reset=1 +#~ ext.lua.auto.reload=1 +#~ ext.lua.startup.script=t:/lua/scite-ctx.lua + +ctx.menulist.default=\ + wrap=wrap_text|\ + unwrap=unwrap_text|\ + sort=sort_text|\ + check=check_text|\ + reset=reset_text + +ctx.menulist.context=\ + wrap=wrap_text|\ + unwrap=unwrap_text|\ + sort=sort_text|\ + document=document_text|\ + quote=quote_text|\ + compound=compound_text|\ + check=check_text|\ + reset=reset_text + +ctx.menulist.example=\ + wrap=wrap_text|\ + unwrap=unwrap_text|\ + sort=sort_text|\ + uncomment=uncomment_xml|\ + document=document_text|\ + quote=quote_text|\ + compound=compound_text|\ + check=check_text|\ + reset=reset_text + +ctx.wraptext.length=65 + +ctx.spellcheck.language=auto +ctx.spellcheck.wordsize=4 +ctx.spellcheck.wordpath=ENV(CTXSPELLPATH) + +ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt + +ctx.spellcheck.wordfile.uk=spell-uk.txt +ctx.spellcheck.wordfile.nl=spell-nl.txt +ctx.spellcheck.wordsize.uk=4 +ctx.spellcheck.wordsize.nl=4 + +ctx.helpinfo=\ + Shift + F11 pop up menu with ctx options|\ + |\ + Ctrl + B check spelling|\ + Ctrl + M wrap text (auto indent)|\ + Ctrl + R reset spelling results|\ + Ctrl + I insert template|\ + Ctrl + E open log file + +command.name.21.$(file.patterns.context)=CTX Action List +command.subsystem.21.$(file.patterns.context)=3 +command.21.$(file.patterns.context)=show_menu $(ctx.menulist.context) +command.groupundo.21.$(file.patterns.context)=yes +command.save.before.21.$(file.patterns.context)=2 +command.shortcut.21.$(file.patterns.context)=Shift+F11 + +command.name.21.$(file.patterns.example)=CTX Action List +command.subsystem.21.$(file.patterns.example)=3 +command.21.$(file.patterns.example)=show_menu $(ctx.menulist.example) +command.groupundo.21.$(file.patterns.example)=yes +command.save.before.21.$(file.patterns.example)=2 +command.shortcut.21.$(file.patterns.example)=Shift+F11 + +#~ command.name.21.*=CTX Action List +#~ command.subsystem.21.*=3 +#~ command.21.*=show_menu $(ctx.menulist.default) +#~ command.groupundo.21.*=yes +#~ command.save.before.21.*=2 +#~ command.shortcut.21.*=Shift+F11 + +command.name.22.*=CTX Check Text +command.subsystem.22.*=3 +command.22.*=check_text +command.groupundo.22.*=yes +command.save.before.22.*=2 +command.shortcut.22.*=Ctrl+B + +command.name.23.*=CTX Wrap Text +command.subsystem.23.*=3 +command.23.*=wrap_text +command.groupundo.23.*=yes +command.save.before.23.*=2 +command.shortcut.23.*=Ctrl+M + +command.name.24.*=CTX Reset Text +command.subsystem.24.*=3 +command.24.*=reset_text +command.groupundo.24.*=yes +command.save.before.24.*=2 +command.shortcut.24.*=Ctrl+R + +command.name.25.*=CTX Template +command.subsystem.25.*=3 +command.save.before.25.*=2 +command.groupundo.25.*=yes +command.shortcut.25.*=Ctrl+I + +# command.25.$(file.patterns.context)=insert_template $(ctx.template.list.context) +# command.25.$(file.patterns.example)=insert_template $(ctx.template.list.example) +# +# ctx.template.list.example=\ +# foo=mathadore.foo|\ +# bar=mathadore.bar +# +# ctx.template.mathadore.foo.file=./ctx-templates/foo.xml +# ctx.template.mathadore.bar.data=bar bar bar +# +# paths: ./ctx-templates, ../ctx-templates, ../../ctx-templates + +command.name.26.*=Open Logfile +command.subsystem.26.*=3 +command.26.*=open_log +command.save.before.26.*=2 +command.groupundo.26.*=yes +command.shortcut.26.*=Ctrl+E + +import scite-ctx-context +import scite-ctx-example + +ctx.template.scan=yes +ctx.template.rescan=no + +ctx.template.suffix.tex=tex +ctx.template.suffix.xml=xml + +command.name.27.*=XML Uncomment +command.subsystem.27.*=3 +command.27.*=uncomment_xml +command.save.before.27.*=2 +command.groupundo.27.*=yes diff --git a/context/data/scite/scite-ctx.readme b/context/data/scite/scite-ctx.readme new file mode 100644 index 000000000..c5f5977a6 --- /dev/null +++ b/context/data/scite/scite-ctx.readme @@ -0,0 +1,19 @@ +installation: + +-- download scite and install it (take the normal scite, not one that ships with ruby) +-- copy the texmf-context\context\data\scite\*.properties to c:\users\ +-- copy the texmf-context\context\data\scite\*.lua to the place where scite has its own support files (wscite) +-- add the line "import context" to your user properties file (entry under menu Options) + +running context: + +-- add texmf-mswin\bin to your path + +or + +-- start scite from a cmd that also calls setuptex + +spellchecking: + +-- create a path for spell files and put spell files there (these are files with just words) +-- set the environment variable CTXSPELLPATH to this path diff --git a/context/data/texfont/type-buy.dat b/context/data/texfont/type-buy.dat new file mode 100644 index 000000000..a65d2e806 --- /dev/null +++ b/context/data/texfont/type-buy.dat @@ -0,0 +1,146 @@ +# itc officina + +--en=? --ve=itc --co=officina --re +--en=? --ve=itc --co=officina --so=itc/officina --ma --in + +--en=? --ve=itc --co=officina --so=itc/officina --ca=* --pattern=ovbk_* +--en=? --ve=itc --co=officina --so=itc/officina --sl=* --pattern=ovbk_* +--en=? --ve=itc --co=officina --so=itc/officina --sl=* --pattern=ovb_* + +--en=? --ve=itc --co=officina --so=itc/officina --ca=* --pattern=owbk_* +--en=? --ve=itc --co=officina --so=itc/officina --sl=* --pattern=owbk_* +--en=? --ve=itc --co=officina --so=itc/officina --sl=* --pattern=owb_* + +# bh lucida + +--en=? --ve=bh --co=lucida --re +--en=? --ve=bh --co=lucida --so=bh/lucida --ma --in --expert + +# fontfont meta + +--en=? --ve=fontfont --co=meta --re +--en=? --ve=fontfont --co=meta --so=fontfont/meta-1 --ma --in --expert +--en=? --ve=fontfont --co=meta --so=fontfont/meta-2 --ma --in --expert + +--en=? --ve=fontfont --co=meta --so=fontfont/meta-1 --sl=* --pattern=mtbk_* +--en=? --ve=fontfont --co=meta --so=fontfont/meta-1 --sl=* --pattern=mtbd_* + +# lucas sun + +--en=? --ve=lucas --co=sun --re +--en=? --ve=lucas --co=sun --so=lucas/sun --ma --in + +# lucas antiqua + +--en=? --ve=lucas --co=antiqua --re +--en=? --ve=lucas --co=antiqua --so=lucas/antiqua --ma --in + +# lucas thesans + +--en=? --ve=lucas --co=thesans --re +--en=? --ve=lucas --co=thesans --so=lucas/thesans --ma --in +--en=? --ve=lucas --co=thesans --so=lucas/thesans --ma --in --expert + +# creative arcadia + +--en=? --ve=creative --co=arcadia --re +--en=? --ve=creative --co=arcadia --so=creative/arcadia --ma --in + +# creative industria + +--en=? --ve=creative --co=industria --re +--en=? --ve=creative --co=industria --so=creative/industria --ma --in + +# creative insignia + +--en=? --ve=creative --co=insignia --re +--en=? --ve=creative --co=insignia --so=creative/insignia --ma --in + +# fontfont din + +--en=? --ve=fontfont --co=din --re +--en=? --ve=fontfont --co=din --so=fontfont/din --ma --in + +# adobe myriad + +--en=? --so=adobe/myriad --weight=400 --width=600 MyriadMM +--en=? --so=adobe/myriad --weight=700 --width=600 MyriadMM +--en=? --so=adobe/myriad --weight=400 --width=600 MyriadMM-It +--en=? --so=adobe/myriad --weight=700 --width=600 MyriadMM-It + +--en=? --ve=adobe --co=myriad --so=adobe/myriad --ma --in --pattern=MyriadMM-we* +--en=? --ve=adobe --co=myriad --so=adobe/myriad --ma --in --pattern=MyriadMM-It-we* + +--en=? --ve=adobe --co=myriad --so=adobe/myriad --sl=* --pattern=MyriadMM-we* +--en=? --ve=adobe --co=myriad --so=adobe/myriad --ca=* --pattern=MyriadMM-we* + +# adobe frutiger + +--en=? --ve=adobe --co=frutiger --re +--en=? --ve=adobe --co=frutiger --so=adobe/frutiger --ma --in + +# itc mendoza + +--en=? --ve=itc --co=mendoza --re +--en=? --ve=itc --co=mendoza --so=itc/mendoza --ma --in + +# linotype univers + +--en=? --ve=linotype --co=univers --re +--en=? --ve=linotype --co=univers --so=linotype/univers --ma --in + +# linotype linoletter + +--en=? --ve=linotype --co=linoletter --re +--en=? --ve=linotype --co=linoletter --so=linotype/linoletter --ma --in + +# adobe utopia +# +# --en=? --ve=adobe --co=utopia --re +# --en=? --ve=adobe --co=utopia --so=adobe/utopia --ma --in + +# itc kabel + +--en=? --ve=itc --co=kabel --re +--en=? --ve=itc --co=kabel --so=itc/kabel --ma --in + +# monotype sabon + +--en=? --ve=monotype --co=sabon --re +--en=? --ve=monotype --co=sabon --so=monotype/sabon --ma --in + +# linotype industria + +--en=? --ve=linotype --co=industria --re +--en=? --ve=linotype --co=industria --so=linotype/industria --ma --in + +# itc stone + +--en=? --ve=itc --co=stone --re +--en=? --ve=itc --co=stone --so=itc/stone --ma --in + +# itc bauhaus + +--en=? --ve=itc --co=bauhaus --re +--en=? --ve=itc --co=bauhaus --so=itc/bauhaus --ma --in +--en=? --ve=itc --co=bauhaus --so=itc/bauhaus --sl=* --pattern=bh* + +# ef swift + +--en=? --ve=ef --co=swift --re +--en=? --ve=ef --co=swift --so=ef/swift --ma --in --pattern=sw* + +# linotype optima-nova + +--en=? --ve=linotype --co=optima-nova --re +--en=? --ve=linotype --co=optima-nova --so=linotype/optima-nova --ma --in + +# linotype palatino-nova + +--en=? --ve=linotype --co=palatino-nova --re +--en=? --ve=linotype --co=palatino-nova --so=linotype/palatino-nova --ma --in + +# linotype syntax + +--en=? --ve=linotype --co=syntax --re +--en=? --ve=linotype --co=syntax --so=linotype/syntax --ma --in diff --git a/context/data/texfont/type-fsf.dat b/context/data/texfont/type-fsf.dat new file mode 100644 index 000000000..c303bdcd8 --- /dev/null +++ b/context/data/texfont/type-fsf.dat @@ -0,0 +1,25 @@ +# Please use the originals instead ! ! ! ! ! + +# fontsite opus + +--en=? --ve=fontsite --co=opus --re +--en=? --ve=fontsite --co=opus --so=fsf/all --ma --in --pattern=opus* + +--en=? --ve=fontsite --co=opus --so=fsf/all --sl=* --pattern=opusrg_* +--en=? --ve=fontsite --co=opus --so=fsf/all --sl=* --pattern=opusb_* + +# fontsite typewriter + +--en=? --ve=fontsite --co=typewriter --re +--en=? --ve=fontsite --co=typewriter --so=fsf/all --ma --in --pattern=type* + +--en=? --ve=fontsite --co=typewriter --so=fsf/all --sl=* --pattern=typerg_* +--en=? --ve=fontsite --co=typewriter --so=fsf/all --sl=* --pattern=typeb_* + +# fontsite garamond + +--en=? --ve=fontsite --co=garamond --re +--en=? --ve=fontsite --co=garamond --so=fsf/all --ma --in --pattern=gara* + +--en=? --ve=fontsite --co=garamond --so=fsf/all --sl=* --pattern=garamond* +--en=? --ve=fontsite --co=garamond --so=fsf/all --sl=* --pattern=garab_* diff --git a/context/data/texfont/type-ghz.dat b/context/data/texfont/type-ghz.dat new file mode 100644 index 000000000..37ce5d6f9 --- /dev/null +++ b/context/data/texfont/type-ghz.dat @@ -0,0 +1,78 @@ +# Gudrun and Hermann Zapf Collection + +# linotype alcuin + +# linotype aldus + +# linotype ams-euler + +# linotype ariadne + +# linotype aurelia + +# linotype carmina + +# linotype colombine + +# linotype diotima + +# linotype edison + +# linotype itc-zapf-book + +# linotype itc-zapf-chancery + +# linotype itc-zapf-dingbats + +# linotype itc-zapf-international-lt + +# linotype kompakt + +# linotype zapfino + +--en=? --ve=linotype --co=zapfino --re +--en=? --ve=linotype --co=zapfino --so=ghz/linotype-zapfino --ma --in + +# linotype marconi + +# linotype medici-script + +# linotype melior + +--en=? --ve=linotype --co=melior --re +--en=? --ve=linotype --co=melior --so=ghz/melior --ma --in + +# linotype noris + +# linotype optima + +--en=? --ve=linotype --co=optima --re +--en=? --ve=linotype --co=optima --so=ghz/optima --ma --in + +# linotype optima-nova + +--en=? --ve=linotype --co=optima-nova --re +--en=? --ve=linotype --co=optima-nova --so=linotype/optima-nova --ma --in + +# linotype orion + +# linotype palatino + +--en=? --ve=linotype --co=palatino --re +--en=? --ve=linotype --co=palatino --so=ghz/palatino --ma --in + +# linotype saphir + +# linotype shakespeare + +# linotype sistina + +# linotype smaragd + +# linotype vario + +# linotype venture-script + +# linotype zapf-essentials-lt + +# linotype zapf-renaissance-antiqua diff --git a/context/data/texfont/type-tmf.dat b/context/data/texfont/type-tmf.dat new file mode 100644 index 000000000..a226e9362 --- /dev/null +++ b/context/data/texfont/type-tmf.dat @@ -0,0 +1,75 @@ +# You can process this file as follows, using texfont.pl: +# +# texfont --encoding=ec --batch texfont.dat +# +# where 'ec' can be replaced by 'texnansi', '8r' or otherwise. +# +# The TEXMFTE and TEXMFGW paths are used by gwtex. + + +# public antp + +--en=? --ve=public --co=antp --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# no longer needed, public antt +# +# --en=? --ve=public --co=antt --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# urw helvetica + +--en=? --ve=urw --co=helvetica --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# urw courier + +--en=? --ve=urw --co=courier --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# urw zapfchan + +--en=? --ve=urw --co=zapfchan --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# urw times + +--en=? --ve=urw --co=times --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=times --so=auto --ca=* utmr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=times --so=auto --sl=* utmr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=times --so=auto --sl=* utmb8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# urw palatino + +--en=? --ve=urw --co=palatino --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=palatino --so=auto --ca=* uplr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=palatino --so=auto --sl=* uplr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=palatino --so=auto --sl=* uplb8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# adobe utopia + +--en=? --ve=adobe --co=utopia --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=adobe --co=utopia --so=auto --ca=* putr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=adobe --co=utopia --so=auto --sl=* putr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=adobe --co=utopia --so=auto --sl=* putb8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +--en=? --ve=adobe --co=utopia --so=auto --ro=TEXMFMAIN,TEXMFEXTRA,TEXMFTE,TEXMFGW +--en=? --ve=adobe --co=utopia --so=auto --ca=* putr8a --ro=TEXMFMAIN,TEXMFEXTRA,TEXMFTE,TEXMFGW +--en=? --ve=adobe --co=utopia --so=auto --sl=* putr8a --ro=TEXMFMAIN,TEXMFEXTRA,TEXMFTE,TEXMFGW +--en=? --ve=adobe --co=utopia --so=auto --sl=* putb8a --ro=TEXMFMAIN,TEXMFEXTRA,TEXMFTE,TEXMFGW + +# bitstream charter + +--en=? --ve=bitstrea --co=charter --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=bitstrea --co=charter --so=auto --ca=* bchr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=bitstrea --co=charter --so=auto --sl=* bchr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=bitstrea --co=charter --so=auto --sl=* bchb8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# uwr bookman + +--en=? --ve=urw --co=bookman --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=bookman --so=auto --ca=* ubkl8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=bookman --so=auto --sl=* ubkl8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=bookman --so=auto --sl=* ubkd8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW + +# uwr schoolbook + +--en=? --ve=urw --co=ncntrsbk --so=auto --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=ncntrsbk --so=auto --ca=* uncr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=ncntrsbk --so=auto --sl=* uncr8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW +--en=? --ve=urw --co=ncntrsbk --so=auto --sl=* uncb8a --ro=TEXMFMAIN,TEXMFTE,TEXMFGW diff --git a/context/data/textadept/context.lua b/context/data/textadept/context.lua new file mode 100644 index 000000000..f386eb87d --- /dev/null +++ b/context/data/textadept/context.lua @@ -0,0 +1,710 @@ +--[[ + Preliminary ConTeXT lexer + + % ConTeXt + tex context + mkii context + mkiv context + + experiment dd 2009/10/28 .. todo: + + -- figure out if tabs instead of splits are possible + -- locate an option to enter name in file dialogue (like windows permits) + -- nesting of lua somehow does not re-lex while typing (backtrack till begin_...) + -- find trick to overload latex lexer (mime_types, metatype trickery) + -- convert scite lua scripts to textadept + -- check linux and osx versions + -- figure out why loading a file fails (lfs too) + + so, this is just an experiment + +]]-- + +local textadept = _G.textadept + +module(..., package.seeall) + +local context = context +local lua = require 'lua' + +local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V + +--~ local some_words = { "starttext", "stoptext", "writestatus" } + +local some_words = { + "CAP", + "Cap", + "Caps", + "Character", + "Characters", + "MONTH", + "Romannumerals", + "WEEKDAY", + "WORD", + "WORDS", + "Word", + "Words", + "about", + "adaptlayout", + "adding", + "appendix", + "arg", + "at", + "atpage", + "background", + "blackrule", + "blackrules", + "blank", + "bookmark", + "but", + "button", + "bypassblocks", + "cap", + "chapter", + "character", + "characters", + "chem", + "clip", + "clonefield", + "color", + "column", + "comment", + "comparecolorgroup", + "comparepalet", + "completecombinedlist", + "completelistoffloats", + "completelistofsorts", + "completelistofsynonyms", + "completeregister", + "convertnumber", + "copyfield", + "correctwhitespace", + "coupledocument", + "coupledregister", + "couplemarking", + "couplepage", + "couplepaper", + "coupleregister", + "crlf", + "currentdate", + "currentheadnumber", + "date", + "decouplemarking", + "define", + "defineblank", + "defineblock", + "definebodyfont", + "definebodyfontenvironment", + "definebuffer", + "definecolor", + "definecolorgroup", + "definecombinedlist", + "defineconversion", + "definedescription", + "defineenumeration", + "definefield", + "definefieldstack", + "definefiguresymbol", + "definefloat", + "definefont", + "defineframed", + "defineframedtext", + "definehead", + "defineindenting", + "defineinteractionmenu", + "defineinteractionmenu", + "definelabel", + "definelist", + "definelogo", + "definemakeup", + "definemarking", + "defineoutput", + "defineoverlay", + "definepalet", + "definepapersize", + "defineparagraphs", + "defineprofile", + "defineprogram", + "definerawfont", + "definereference", + "definereferenceformat", + "definereferencelist", + "defineregister", + "definerule", + "definesection", + "definesectionblock", + "definesorting", + "definestartstop", + "definesubfield", + "definesymbol", + "definesynonyms", + "definetabletemplate", + "definetabulate", + "definetext", + "definetextposition", + "definetextvariable", + "definetype", + "definetyping", + "defineversion", + "description", + "determineheadnumber", + "determinelistcharacteristics", + "disableinteractionmenu", + "donttest", + "emptylines", + "enumeration", + "externalfigure", + "field", + "fieldstack", + "fillinfield", + "fillinline", + "fillinrules", + "fillintext", + "fitfield", + "fixedspaces", + "followprofile", + "followprofileversion", + "followversion", + "footnote", + "footnotetext", + "forceblocks", + "fraction", + "framed", + "framedtext", + "from", + "getbuffer", + "getmarking", + "godown", + "goto", + "gotobox", + "graycolor", + "grid", + "hairline", + "head", + "headnumber", + "headtext", + "hideblocks", + "high", + "hl", + "in", + "indentation", + "indenting", + "inframed", + "ininner", + "inleft", + "inline", + "inmargin", + "inothermargin", + "inouter", + "inright", + "installlanguage", + "interactionbar", + "interactionbuttons", + "item", + "items", + "its", + "keepblocks", + "labeling", + "labels", + "labeltext", + "language", + "leftaligned", + "listsymbol", + "loadsorts", + "loadsynonyms", + "logfields", + "lohi", + "low", + "mainlanguage", + "mar", + "marginrule", + "margintext", + "marking", + "markversion", + "mathematics", + "mediaeval", + "midaligned", + "mirror", + "month", + "moveongrid", + "name", + "nextsection", + "nocap", + "noheaderandfooterlines", + "noindenting", + "nolist", + "nomarking", + "nomoreblocks", + "nomorefiles", + "nop", + "nospace", + "note", + "notopandbottomlines", + "nowhitespace", + "numbers", + "overbar", + "overbars", + "overstrike", + "overstrikes", + "packed", + "page", + "pagereference", + "pagetype", + "paragraph", + "part", + "periods", + "placebookmarks", + "placecombinedlist", + "placecombinedlist", + "placefloat", + "placefootnotes", + "placeformula", + "placelegend", + "placelist", + "placelistoffloats", + "placelistofsorts", + "placelistofsynonyms", + "placelocalfootnotes", + "placelogos", + "placeongrid", + "placeontopofeachother", + "placereferencelist", + "placeregister", + "placeregister", + "placerule", + "placesidebyside", + "placesubformula", + "placetextvariable", + "position", + "positiontext", + "processblocks", + "processpage", + "program", + "publication", + "quotation", + "quote", + "ran", + "ref", + "reference", + "referral", + "referraldate", + "register", + "reservefloat", + "reset", + "resetmarking", + "resettextcontent", + "rightaligned", + "romannumerals", + "rotate", + "scale", + "screen", + "section", + "seeregister", + "selectblocks", + "selectpaper", + "selectversion", + "settextcontent", + "settextvariable", + "setupalign", + "setuparranging", + "setupbackground", + "setupbackgrounds", + "setupblackrules", + "setupblank", + "setupblock", + "setupbodyfont", + "setupbodyfontenvironment", + "setupbottom", + "setupbottomtexts", + "setupbuffer", + "setupbuttons", + "setupcapitals", + "setupcaption", + "setupcaptions", + "setupclipping", + "setupcolor", + "setupcolors", + "setupcolumns", + "setupcombinations", + "setupcombinedlist", + "setupcomment", + "setupdescriptions", + "setupenumerations", + "setupexternalfigures", + "setupfield", + "setupfields", + "setupfillinlines", + "setupfillinrules", + "setupfloat", + "setupfloats", + "setupfloatsplitting", + "setupfooter", + "setupfootertexts", + "setupfootnotedefinition", + "setupfootnotes", + "setupforms", + "setupformulae", + "setupframed", + "setupframedtexts", + "setuphead", + "setupheader", + "setupheadertexts", + "setupheadnumber", + "setupheads", + "setupheadtext", + "setuphyphenmark", + "setupindentations", + "setupindenting", + "setupinmargin", + "setupinteraction", + "setupinteractionbar", + "setupinteractionscreen", + "setupinterlinespace", + "setupinterlinespace", + "setupitemgroup", + "setupitems", + "setuplabeltext", + "setuplanguage", + "setuplayout", + "setuplegend", + "setuplinenumbering", + "setuplines", + "setuplinewidth", + "setuplist", + "setuplistalternative", + "setupmakeup", + "setupmarginblocks", + "setupmarginrules", + "setupmarking", + "setupnarrower", + "setupnumbering", + "setupoppositeplacing", + "setupoutput", + "setuppagenumber", + "setuppagenumbering", + "setuppagetransitions", + "setuppalet", + "setuppaper", + "setuppapersize", + "setupparagraphnumbering", + "setupparagraphs", + "setuppositioning", + "setupprofiles", + "setupprograms", + "setuppublications", + "setupquote", + "setupreferencelist", + "setupreferencing", + "setupregister", + "setuprotate", + "setuprule", + "setupscreens", + "setupsection", + "setupsectionblock", + "setupsorting", + "setupspacing", + "setupstrut", + "setupsubpagenumber", + "setupsymbolset", + "setupsynchronization", + "setupsynchronizationbar", + "setupsynonyms", + "setupsystem", + "setuptab", + "setuptables", + "setuptabulate", + "setuptext", + "setuptextposition", + "setuptextrules", + "setuptexttexts", + "setuptextvariable", + "setupthinrules", + "setuptolerance", + "setuptop", + "setuptoptexts", + "setuptype", + "setuptyping", + "setupunderbar", + "setupurl", + "setupversions", + "setupwhitespace", + "showbodyfont", + "showbodyfontenvironment", + "showcolor", + "showcolorgroup", + "showexternalfigures", + "showfields", + "showframe", + "showgrid", + "showlayout", + "showmakeup", + "showpalet", + "showprint", + "showsetups", + "showstruts", + "showsymbolset", + "someline", + "somewhere", + "sort", + "space", + "splitfloat", + "startalignment", + "startbackground", + "startbuffer", + "startcolor", + "startcolumns", + "startcombination", + "startcomment", + "startcomponent", + "startdescription", + "startdocument", + "startenumeration", + "startenvironment", + "startfact", + "startfigure", + "startfloattext", + "startformula", + "startframedtext", + "starthiding", + "startinteractionmenu", + "startitemgroup", + "startlegend", + "startline", + "startlinecorrection", + "startlinenumbering", + "startlines", + "startlocal", + "startlocalenvironment", + "startlocalfootnotes", + "startmakeup", + "startmarginblock", + "startmarginrule", + "startnamemakeup", + "startnarrower", + "startopposite", + "startoverlay", + "startoverview", + "startpacked", + "startparagraph", + "startpositioning", + "startpostponing", + "startproduct", + "startprofile", + "startproject", + "startquotation", + "startregister", + "startsymbolset", + "startsynchronization", + "starttable", + "starttables", + "starttabulate", + "starttextrule", + "starttyping", + "startunpacked", + "startversion", + "stopalignment", + "stopbackground", + "stopbuffer", + "stopcolor", + "stopcolumns", + "stopcombination", + "stopcomment", + "stopcomponent", + "stopdescription", + "stopdocument", + "stopenumeration", + "stopenvironment", + "stopfact", + "stopfigure", + "stopfloattext", + "stopformula", + "stopframedtext", + "stophiding", + "stopinteractionmenu", + "stopitemgroup", + "stoplegend", + "stopline", + "stoplinecorrection", + "stoplinenumbering", + "stoplines", + "stoplocal", + "stoplocalenvironment", + "stoplocalfootnotes", + "stopmakeup", + "stopmarginblock", + "stopmarginrule", + "stopnamemakeup", + "stopnarrower", + "stopopposite", + "stopoverlay", + "stopoverview", + "stoppacked", + "stopparagraph", + "stoppositioning", + "stoppostponing", + "stopproduct", + "stopprofile", + "stopproject", + "stopquotation", + "stopsymbolset", + "stopsynchronization", + "stoptable", + "stoptables", + "stoptabulate", + "stoptextrule", + "stoptyping", + "stopunpacked", + "stopversion", + "stretched", + "sub", + "subject", + "subsection", + "subsubject", + "subsubsection", + "subsubsubject", + "switchtobodyfont", + "switchtorawfont", + "sym", + "symbol", + "synchronizationbar", + "synchronize", + "synonym", + "tab", + "tex", + "textreference", + "textrule", + "textvariable", + "thinrule", + "thinrules", + "title", + "tooltip", + "translate", + "typ", + "type", + "typebuffer", + "typefile", + "underbar", + "underbars", + "useURL", + "useblocks", + "usecommands", + "usedirectory", + "useencoding", + "useexternaldocument", + "useexternalfigure", + "useexternalfile", + "useexternalfiles", + "useexternalsoundtrack", + "usemodule", + "usereferences", + "usespecials", + "usesymbols", + "version", + "vl", + "weekday", + "whitespace", + "wordright", + "writebetweenlist", + "writetolist", + "writetoreferencelist", + "writetoregister", +} + +local tex_word_match = word_match(word_list(some_words)) + +--~ local function tex_preamble_match() +--~ return P(function(input, index) +--~ if index < 10 then +--~ local s, e, word = input:find('^(.+)[\n\r]',index) +--~ if word then +--~ local interface = word:match("interface=(..)") +--~ if interface then +--~ local name = "c:/data/develop/context/lua/textadept/cont-" .. interface .. "-scite.lua" +--~ --~ local f = io.open(name,"rb") -- fails +--~ if f then +--~ local data = f:read("*all") +--~ data = data and loadstring(data) +--~ data = data and data() +--~ if data and type(data) == "table" then +--~ some_words = word_list(data) +--~ context.LoadTokens() +--~ -- InitLexer(context) +--~ end +--~ f:close() +--~ end +--~ end +--~ end +--~ end +--~ return false +--~ end) +--~ end + +local spacing = token('whitespace', S(" \n\r\t\f")^1) +--~ local preamble = token('preamble', P('%') * tex_preamble_match()) +local comment = token('comment', P('%') * (1-S("\n\r"))^0) +local keyword = token('keyword', P('\\') * tex_word_match) +local command = token('command', P('\\') * ((R("az","AZ")+S("@!?"))^1 + P(1))) +local grouping = token('grouping', S("{$}")) +local specials = token('specials', S("#()[]<>=\"")) +local extras = token('extras', S("`~%^&_-+/\'|")) + +-- LexByLine = true + +local startluacode = token("grouping", P("\\startluacode")) +local stopluacode = token("grouping", P("\\stopluacode")) +--~ local startctxlua = token("grouping", P("\\ctxlua") * spacing^0 * P("{")) +--~ local stopctxlua = token("grouping", P("}")) + +--~ local startMPcode = token("grouping", P("\\startMPcode")) +--~ local stopMPcode = token("grouping", P("\\stopMPcode")) +--~ local startuseMPgraphic = token("grouping", P("\\startuseMPgraphic")) +--~ local stopuseMPgraphic = token("grouping", P("\\stopuseMPgraphic")) +--~ local startreusableMPgraphic = token("grouping", P("\\startreusableMPgraphic")) +--~ local stopreusableMPgraphic = token("grouping", P("\\stopreusableMPgraphic")) +--~ local startuniqueMPgraphic = token("grouping", P("\\startuniqueMPgraphic")) +--~ local stopuniqueMPgraphic = token("grouping", P("\\stopuniqueMPgraphic")) + +function LoadTokens() + + lua.LoadTokens() + + add_token(context, 'whitespace', spacing) +--~ add_token(context, 'preamble', preamble) + add_token(context, 'comment', comment) + add_token(context, 'keyword', keyword) + add_token(context, 'command', command) + add_token(context, 'grouping', grouping) + add_token(context, 'specials', specials) + add_token(context, 'extras', extras) + add_token(context, 'any_char', any_char) + + lua.TokenPatterns.any_char = token('default', 1 - stopluacode) + + make_embeddable(lua, context, startluacode, stopluacode) +-- make_embeddable(lua, context, startctxlua, stopctxlua) -- no multiple embeddables unless more complex anychar + embed_language(context, lua) + +-- metapost.LoadTokens() +-- metapost.TokenPatterns.any_char = token('any_char', 1 - stopMPcode - stopuseMPgraphic - stopreusableMPgraphic - stopuniqueMPgraphic) +-- make_embeddable(metapost, context, startMPcode, stopMPcode ) +-- make_embeddable(metapost, context, startuseMPgraphic, stopuseMPgraphic ) +-- make_embeddable(metapost, context, startreusableMPgraphic, stopreusableMPgraphic) +-- make_embeddable(metapost, context, startuniqueMPgraphic, stopuniqueMPgraphic ) +end + +local bold = true +local italic = true + +function LoadStyles() + add_style('preamble', style_nothing .. { fore = colors.yellow, bold = bold }) + add_style('comment', style_nothing .. { fore = colors.yellow, bold = bold }) + add_style('keyword', style_nothing .. { fore = colors.green, bold = bold, italic = italic }) + add_style('command', style_nothing .. { fore = colors.green, bold = bold }) + add_style('grouping', style_nothing .. { fore = colors.red, bold = bold }) + add_style('specials', style_nothing .. { fore = colors.blue, bold = bold }) + add_style('extras', style_nothing .. { fore = colors.yellow, bold = bold }) +end + +--~ textadept.mime_types.extensions["tex"] = context +--~ textadept.mime_types.extensions["mkii"] = context +--~ textadept.mime_types.extensions["mkiv"] = context diff --git a/context/data/texworks/TUG/TeXworks.ini b/context/data/texworks/TUG/TeXworks.ini new file mode 100644 index 000000000..8c0a4a43d --- /dev/null +++ b/context/data/texworks/TUG/TeXworks.ini @@ -0,0 +1,18 @@ +[General] +launchOption=1 +locale=en +syntaxColoring=ConTeXt TeX +autoIndent=None +wrapLines=false +tabWidth=32 +font="Lucida Console,10,-1,5,50,0,0,0,0,0" +language=None +scaleOption=1 +previewScale=200 +magnifierSize=2 +circularMagnifier=true +defaultEngine=ConTeXt MkIV +binaryPaths= +autoHideConsole=false +openDialogDir= +recentFileList= diff --git a/context/data/texworks/completion/tw-context.txt b/context/data/texworks/completion/tw-context.txt new file mode 100644 index 000000000..59f52c870 --- /dev/null +++ b/context/data/texworks/completion/tw-context.txt @@ -0,0 +1 @@ +%%!TEX encoding = UTF-8 Unicode diff --git a/context/data/texworks/configuration/auto-indent-patterns.txt b/context/data/texworks/configuration/auto-indent-patterns.txt new file mode 100644 index 000000000..e0e331dac --- /dev/null +++ b/context/data/texworks/configuration/auto-indent-patterns.txt @@ -0,0 +1,14 @@ +# TeXworks: Patterns for auto-indent modes + +# Each entry consists of two fields: +# "name" + +# "name" is a name for the mode, which will appear in the Auto-Indent submenu. +# This is enclosed in "double quotes", and followed by whitespace to separate it from . + +# is the regular expression; if this matches the start of the current line when +# is pressed, then the new line will be given the same prefix. The regex is not quoted. +# (Using ^ at the start of the pattern is not strictly necessary, but improves efficiency.) + +# "Whitespace only" ^\s+ +# "TeX comments" ^(\s+|\s*%+\s*) diff --git a/context/data/texworks/configuration/delimiter-pairs.txt b/context/data/texworks/configuration/delimiter-pairs.txt new file mode 100644 index 000000000..1ee56dcd6 --- /dev/null +++ b/context/data/texworks/configuration/delimiter-pairs.txt @@ -0,0 +1,12 @@ +# TeXworks: Paired delimiters for matching/balancing + +# Each line gives a pair opening and closing delimiters (a single Unicode character each), +# separated by whitespace. + +( ) +[ ] +{ } +« » +‹ › +“ ” +‘ ’ diff --git a/context/data/texworks/configuration/smart-quotes-modes.txt b/context/data/texworks/configuration/smart-quotes-modes.txt new file mode 100644 index 000000000..9f7f95d69 --- /dev/null +++ b/context/data/texworks/configuration/smart-quotes-modes.txt @@ -0,0 +1,21 @@ +# TeXworks: "Smart Quotes" modes + +# Each mode has a label (in [square brackets]), followed by lines specifying the +# behavior for each quote keystroke. These lines have three fields: +# +# +# +# separated by whitespace. + +# [TeX ligatures] +# ' ` ' +# " `` '' +# + +[TeX commands] +' \quote{ } +" \quotation{ } + +# [Unicode characters] +# ' ‘ ’ +# " “ ” diff --git a/context/data/texworks/configuration/syntax-patterns.txt b/context/data/texworks/configuration/syntax-patterns.txt new file mode 100644 index 000000000..687fae887 --- /dev/null +++ b/context/data/texworks/configuration/syntax-patterns.txt @@ -0,0 +1,42 @@ +# TeXworks: Patterns for syntax coloring + +# Each entry consists of three whitespace-separated fields: +# + +# is a color name from the list defined in the SVG standard; +# see http://www.w3.org/TR/SVG/types.html#ColorKeywords + +# is a flag controlling whether this style is subject to spell-checking; +# "Y" or "y" for yes, "N" (or anything else, actually) for no. + +# is the regular expression to match. + +# Note that order of rules may be important if several rules could match at the same position; +# this is why the generic "control sequence" rule comes AFTER the specific \begin/\end one. + +[ConTeXt TeX] + +darkred N [\$\{\}] + +darkblue N [\<\>\"\'\[\]\=\#] +goldenrod N [\~\`\%\^\&\-\+\|] +darkgreen N \\(?:[\w\@\?\!]+|.) +darkgray N %.* + +[ConTeXt XML] + +# todo: attributes + +darkred N \<\?xml.*\?\> +darkblue N \<\!\-\-.*\-\-\> +darkblue N [\"\'] +goldenrod N \<\?.*\?\> +darkgreen N \<\/*[a-zA-Z\_\-]*\:*[a-zA-Z\_\-]+ +darkgreen N \/\> +darkgreen N \> +darkred N \&[a-zA-Z\_\-]+\; + +# other possibilities to be added.... +# [BibTeX] +# [Metapost] +# etc diff --git a/context/data/texworks/configuration/tag-patterns.txt b/context/data/texworks/configuration/tag-patterns.txt new file mode 100644 index 000000000..7e3837da2 --- /dev/null +++ b/context/data/texworks/configuration/tag-patterns.txt @@ -0,0 +1,33 @@ +# TeXworks: Patterns for tag recognition + +# Each entry consists of two whitespace-separated fields: +# + +# is the position in the document structure hierarchy, with 1 being the top level. +# is the regular expression to match. + +# If there is a (capture group) in the regex, this is the fragment that will be used +# as the actual tag text; if there is no group, the entire match will be used. + +# Patterns for ConTeXt sectioning commands: + +1 ^\s*\\part\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +2 ^\s*\\chapter\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +2 ^\s*\\title\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +3 ^\s*\\section\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +3 ^\s*\\subject\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +4 ^\s*\\subsection\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +4 ^\s*\\subsubject\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +5 ^\s*\\subsubsection\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +5 ^\s*\\subsubsubject\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +6 ^\s*\\subsubsubsection\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +6 ^\s*\\subsubsubsubject\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +6 ^\s*\\subsubsubsubsection\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} +6 ^\s*\\subsubsubsubsubject\s*(?:\[[^]]*\]\s*)?\{([^}]*)\} + +# Tags with level = 0 are special bookmarks that are separate from the hierarchy +# and collected in a separate flat list. +0 ^\s*\\environment\s+([\S]+) +0 ^\s*\\component\s+([\S]+) +0 ^\s*\\project\s+([\S]+) +0 ^\s*\\product\s+([\S]+) diff --git a/context/data/texworks/configuration/texworks-config.txt b/context/data/texworks/configuration/texworks-config.txt new file mode 100644 index 000000000..b925b2801 --- /dev/null +++ b/context/data/texworks/configuration/texworks-config.txt @@ -0,0 +1,22 @@ +# TeXworks: Miscellaneous configuration options that don't show up in the Preferences + +# Template commands to insert for files dragged into the editor window +# Note that %1 represents the filename; #RET# represents a newline + +include-text: \include{%1}#RET# + +include-postscript: \includegraphics[]{%1}#RET# +include-pdf: \includegraphics[]{%1}#RET# +include-image: \includegraphics[]{%1}#RET# + +# Patterns for the Remove Aux Files command; entries are cumulative +# (any occurrence of $jobname will be replaced by the root file name) + +cleanup-patterns: *.aux +cleanup-patterns: $jobname.blg $jobname.brf $jobname.ccs $jobname.ent $jobname.fff +cleanup-patterns: $jobname.glo $jobname.idx $jobname.idv $jobname.ilg $jobname.ind $jobname.ioa +cleanup-patterns: $jobname.lg $jobname.lof $jobname.log $jobname.lot +cleanup-patterns: $jobname.mte $jobname.mlf $jobname.out $jobname.pdfsync +cleanup-patterns: $jobname.toc $jobname.ttt $jobname.wrm $jobname.xref +cleanup-patterns: $jobname.4ct $jobname.4tc + diff --git a/context/data/texworks/configuration/tools.ini b/context/data/texworks/configuration/tools.ini new file mode 100644 index 000000000..73071028b --- /dev/null +++ b/context/data/texworks/configuration/tools.ini @@ -0,0 +1,35 @@ +[001] +name=ConTeXt MkIV +program=mtxrun +arguments=--autogenerate, --script, context, $fullname +showPdf=true + +[002] +name=ConTeXt MkIV Check +program=mtxrun +arguments=--autogenerate, --script, check, $fullname +showPdf=false + +[003] +name=ConTeXt MkIV Purge +program=mtxrun +arguments=--autogenerate, --script, context, --purgeall +showPdf=false + +[004] +name=ConTeXt MkIV Server +program=cmd.exe +arguments=/c, start, mtxrun, --autogenerate, --script, server, --auto +showPdf=false + +[005] +name=ConTeXt MkIV Update +program=mtxrun +arguments=--autogenerate, --script, update, --force, --make +showPdf=false + +[006] +name=ConTeXt MkIV Make +program=mtxrun +arguments=--autogenerate, --script, context, --generate, --make +showPdf=false diff --git a/context/data/texworks/texworks-context.rme b/context/data/texworks/texworks-context.rme new file mode 100644 index 000000000..7019cb78e --- /dev/null +++ b/context/data/texworks/texworks-context.rme @@ -0,0 +1,2 @@ +This is just a placeholder. We need to make sure that we end +up here in case of multiple texworks ini files. diff --git a/context/data/texworks/texworks-setup.ini b/context/data/texworks/texworks-setup.ini new file mode 100644 index 000000000..6357e775b --- /dev/null +++ b/context/data/texworks/texworks-setup.ini @@ -0,0 +1,2 @@ +inipath=. +libpath=. diff --git a/doc/context/document/general/manuals/mreadme.pdf b/doc/context/document/general/manuals/mreadme.pdf new file mode 100644 index 000000000..338008015 Binary files /dev/null and b/doc/context/document/general/manuals/mreadme.pdf differ diff --git a/doc/context/document/general/manuals/tiptrick.pdf b/doc/context/document/general/manuals/tiptrick.pdf new file mode 100644 index 000000000..3ced360e1 Binary files /dev/null and b/doc/context/document/general/manuals/tiptrick.pdf differ diff --git a/doc/context/manuals/allkind/mcommon.tex b/doc/context/manuals/allkind/mcommon.tex new file mode 100644 index 000000000..f0c22cff4 --- /dev/null +++ b/doc/context/manuals/allkind/mcommon.tex @@ -0,0 +1,199 @@ +% content=tex +% +% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa + +\startenvironment mcommon + +% modules + +\usemodule[abr-02] + +% layout + +\startmode[screen] + \setuppapersize[S6][S6] + \setupinteraction[state=start] + \setupinteractionscreen[options=max] +\stopmode + +\setuplayout + [footer=0cm, + width=middle, + height=middle] + +% fonts + +\startmode[atpragma] + + \startMPenvironment[global] + \usetypescriptfile[type-buy] + \usetypescript[lucida][texnansi] + \setupbodyfont[lucida,10pt] + \stopMPenvironment + + \setupbodyfont[11pt] + +\stopmode + +\startnotmode[atpragma] + + \startMPenvironment[global] + \usetypescript[palatino][ec] + \setupbodyfont[palatino,10pt] + \stopMPenvironment + + \setupbodyfont[11pt] + +\stopnotmode + +\definefont [BigFont] [SansBold at 60pt] +\definefont [MedFont] [SansBold at 30pt] + +% colors + +\setupcolors + [state=start] + +\definecolor [NopColor] [r=.6,g=.4,b=.5] +\definecolor [AltColor] [r=.4,g=.6,b=.5] +\definecolor [TheColor] [r=.4,g=.5,b=.6] +\definecolor [TmpColor] [r=.6,g=.5,b=.4] + +\definecolor [red] [NopColor] +\definecolor [green] [AltColor] +\definecolor [blue] [TheColor] +\definecolor [yellow][TmpColor] + +% spacing + +\setupwhitespace + [big] + +\setuptolerance + [verytolerant,stretch] + +% verbatim + +\setuptype + [color=AltColor] + +\setuptyping + [color=AltColor] + +% structure + +\setupitemize + [each] + [color=TheColor] + +\definedescription + [switch] + [headstyle=type, + headcolor=TheColor, + location=serried, + width=broad] + +\defineenumeration + [topic] + [location=serried, + width=broad, + headstyle=, + headcolor=TheColor, + text=, + left={[}, + right={]}] + +\setuphead + [section] + [style=\ss\bfb, + color=TheColor] + +\setuplist + [section] + [alternative=c, + color=TheColor, + textcolor=black, + pagecolor=black] + +% whatever + +\setupsystem + [random=medium] + +\setupfloats + [ntop=100] + +\setupinteraction + [style=, + color=NopColor, + contrastcolor=NopColor] + +% tables and frames + +\setuptabulate + [rulethickness=.5pt, + rulecolor=AltColor] + +\setuptables + [rulethickness=.5pt, + rulecolor=AltColor] + +\setupframedtexts + [rulethickness=.5pt, + framecolor=TheColor, + width=\textwidth] + +% quick reference things + +\usemodule[set-11] \loadsetups + +\setupframedtexts + [setuptext] + [rulethickness=.5pt, + framecolor=AltColor] + +% basic titlepage and colofon, a bit old fashioned approach, but let's not +% modernize everything now + +\def\TitlePage#1#2#3#4#5% number/name angle title author screen + {\doifnumberelse{#1} + {\ifcase#1 + \defineoverlay + [logo] + [\useMPgraphic{titlepage}{width=\overlaywidth,height=\overlayheight}] + \else + \startMPrun + logo_type := #1 ; mpgraph := #1 ; input mp-cont ; + \stopMPrun + \defineoverlay + [logo] + [{\externalfigure + [\MPrunfile{#1}] + [width=\overlaywidth,height=\overlayheight]}] + \fi} + {\defineoverlay + [logo] + [\useMPgraphic{#1}{width=\overlaywidth,height=\overlayheight}]} + \setupbackgrounds + [page] + [background=logo] + \definecolor[Gray][s=#5] + \startstandardmakeup + \dontcomplain + \BigFont \setupinterlinespace \vfill \setupalign[left] \let\\=\par + \ifcase#2\relax + \noindent\color[Gray]{#3}\par + \else + \noindent\rotate[rotation=#2]{\color[Gray]{#3}}\par + \fi + \stopstandardmakeup + \setupbackgrounds + [page] + [background=]} + +\def\ColofonPage + {\startstandardmakeup + \vfill \setups [pragma-colofon] + \stopstandardmakeup} + +\stopenvironment diff --git a/doc/context/manuals/allkind/mreadme.tex b/doc/context/manuals/allkind/mreadme.tex new file mode 100644 index 000000000..22af40afe --- /dev/null +++ b/doc/context/manuals/allkind/mreadme.tex @@ -0,0 +1,361 @@ +% interface=en output=pdftex language=uk +% +% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa + +\environment mcommon + +\useurl[gpl-simple] [http://creativecommons.org/licenses/GPL/2.0/] +\useurl[gpl-legal] [http://creativecommons.org/licenses/GPL/2.0/legalcode] +\useurl[byncsa-simple][http://creativecommons.org/licenses/by-nc-sa/2.5/] +\useurl[byncsa-legal] [http://creativecommons.org/licenses/by-nc-sa/2.5/legalcode] + +\useurl[garden] [http://contextgarden.net] +\useurl[contextlist] [http://www.ntg.nl/mailman/listinfo/ntg-context] +\useurl[development] [http://www.ntg.nl/mailman/listinfo/dev-context] +\useurl[announce] [http://www.ntg.nl/mailman/listinfo/ann-context] +\useurl[collector] [http://context.literatesolutions.com] +\useurl[pragma] [http://www.pragma-ade.com] +\useurl[mirror] [http://context.aanhet.net] + +\setupinteraction[state=start] + +% copied from cont-log: readme_logo + +\startuseMPgraphic{titlepage}{width,height} + numeric width ; width = \MPvar{width} ; + numeric height ; height = \MPvar{height} ; + numeric delta ; delta := width/10 ; + numeric circle ; circle := 2.5delta ; + color c ; c := (.2,.4,.6) ; + path p, q, r ; + p := unitsquare xscaled width yscaled height ; + z1 = (delta,height-2delta) ; + z2 = (width-delta,height-delta) ; + z3 = (width/2-delta,2delta+circle) ; + z4 = (x3,delta+circle/2) ; + q := z1 { dir -15 } .. z2 & + z2 { dir -105 } .. z3 & + z3 { dir 135 } .. z1 & + cycle ; + r := fullcircle xscaled circle yscaled (.85circle) rotated 15 shifted z4 ; + pickup pencircle scaled (delta/1.5) ; + fill p withcolor .50c ; + fill q withcolor .75c ; + fill r withcolor .75c ; + draw p withcolor c ; + draw q withcolor c ; + pickup pencircle scaled (delta/2) ; + draw r withcolor c ; + setbounds currentpicture to p ; +\stopuseMPgraphic + +\starttext + +\TitlePage{titlepage}{90}{Read Me First}{}{1} + +\subject {Introduction} + +What licence suits best for a \TEX\ like system is a matter of +taste. Personally we dislike any licence that needs more than a few +pages of dense legal code to get the message accross. A \TEX\ +related system like \CONTEXT\ is a hybrid of programs, scripts +and|/|or macro code as well as documentation and sample code, +including graphics. \TEX\ related systems also have a long +standing tradition of providing support structures for users. In +order to make support feasable, a \TEX\ based system like +\CONTEXT\ assumes a certain logic and structure in the way the +related files are named and organized in a tree structure. Even a +small change in one of the elements may let such a system behave +differently than manuals suggest. Swap a font, change some style +defaults, leave out some pieces, and users may end up in +confusion. A licence does not give a user any guarantees! + +In order to satisfy those responsible for distributing \CONTEXT, +we need to choose a licence that makes them feel comfortable. +Unfortunately we don't feel that comfortable with a licence that does +not provide the guarantees that a system will not be adapted in +such ways that the advertised behaviour changes. On the +other hand, it is the responsibility of those distributing and +extending the system to make sure that this does not happen. +However, users should not automatically assume that what they get +shipped is the same as the original, which is why we stress that +support (from our side) will only be given on unaltered systems. + +First of all, what is \CONTEXT ? It's just a bunch of macros, +written in \TEX\ and \METAPOST, meant for typesetting documents. +The macros are accompanied by some scripts, written in \PERL\ (mainly +the older scripts) \RUBY\ (the official ones) and \LUA\ (for +embedded usage). The \CONTEXT\ distribution comes with a few fonts, +files that help manage resources (e.g.\ map files), as well as +patterns (based on official ones, so this is a derived work). + +The \CONTEXT\ distribution is packaged in a zip file organized in +the \TDS\ structure. + +\starttabulate +\NC \type {cont-tmf.zip} \NC The main distribution. \NC \NR +\NC \type {cont-img.zip} \NC A few extra resources. \NC \NR +\NC \type {cont-ext.zip} \NC Third party modules. \NC \NR +\stoptabulate + +When we talk about \CONTEXT\ we also mean its graphical companion +\METAFUN\ and \FOXET, an \XML\ related product. All these are +included in the main distribution archive. + +The documentation can be downloaded from our website, one of its +mirrors, the \TEX\ collection as distributed by \TEX\ user groups. +For some manuals, source code is available in a subversion +repository. The archives are also kept on \CTAN. + +That said, what licence does apply? We need to distinguish between +things that resemble a program on the one hand and documentation +on the other hand. We (currently) use a different licence for +either of them. + +\subject {The Code} + +The program code (i.e. anything not under the \type {/doc} +subtree) is distributed under the + +\startnarrower +\goto{Creative Commons GNU GPL}[url(gpl-simple)] +\stopnarrower + +For practical purposes distributers may also choose the \LATEX\ +project licence, which is considered to be a bit more \TEX\ +friendly. (BSD alike licences, the Ruby Licence and the Apache +are all licences that apply well for \CONTEXT.) + +In practice, users may forget about the legal part, if only +because I haven't even read (and understood) it completely myself, +so let's stick to what Creative Commons makes of it: + +\startcolor[blue] +The GNU General Public License is a Free Software license. Like +any Free Software license, it grants to you the four following +freedoms: + +\startitemize +\item The freedom to run the program for any purpose. +\item The freedom to study how the program works and adapt it to + your needs. +\item The freedom to redistribute copies so you can help your neighbour. +\item The freedom to improve the program and release your improvements + to the public, so that the whole community benefits. +\stopitemize + +You may exercise the freedoms specified here provided that you +comply with the express conditions of this license. The principal +conditions are: + +You must conspicuously and appropriately publish on each copy +distributed an appropriate copyright notice and disclaimer of +warranty and keep intact all the notices that refer to this +License and to the absence of any warranty; and give any other +recipients of the Program a copy of the GNU General Public License +along with the Program. Any translation of the GNU General Public +License must be accompanied by the GNU General Public License. + +If you modify your copy or copies of the program or any portion of +it, or develop a program based upon it, you may distribute the +resulting work provided you do so under the GNU General Public +License. Any translation of the GNU General Public License must be +accompanied by the GNU General Public License. + +If you copy or distribute the program, you must accompany it with +the complete corresponding machine-readable source code or with a +written offer, valid for at least three years, to furnish the +complete corresponding machine-readable source code. + +Any of these conditions can be waived if you get permission from +the copyright holder. + +Your fair use and other rights are in no way affected by the above. +\stopcolor + +\subject {Recommendations} + +Here are a few recommendations in case you want to distribute, +extend of embed \CONTEXT\ in applications: + +\startitemize + +\item You can best leave the code base untouched. Most of +\CONTEXT\ provides hooks and it's relatively easy to overload +code. Leave the lower level system code untouched: changes may +backfire when you update. Asking for more hooks is the best way to +go. + +\item Put your own code in the right subpaths, i.e.\ modules +approved by the development team under \type {.../third}, and +styles and whatever else under \type {.../user}. This way your +code will not interfere with existing code and updating will give +less problems. Keep in mind that \TEX\ systems have their own way +and order in locating files, and the load order often matters. + +\item Don't copy styles and change a few lines, but load the base one +and built|/|patch on top of that. In the end you may benefit from +improvements to the base style. + +\item Be original. The whole idea behind \CONTEXT\ is that you can +write your own styles. On the \CONTEXT\ mailing list as well as on +the Wiki there are enough advanced users to help you make a start. + +\item Don't hesitate to submit bugs reports and ask for +extensions. It may even be that what you want is already present +but yet undocumented. + +\item If things don't work as expected, check to what extend your +system matches the (more or less) standard. We provide so called +minimal \CONTEXT\ trees that can serve as a reference. Because +\CONTEXT\ evolves, make sure your system is up to date. + +\item The scripts can best be called using \type {texmfstart}. This +lessens dependencies on the location in the tree and ensures upward +compatibility. It also prevents clashes with similary named scripts. + +\item Some scripts depend on each other. Don't mess around with the +existing functionality and names of the scripts and then feed them +back into the standard distributions. + +\stopitemize + +\subject {Documents} + +The documentation is provided under another Creative Commons licence + +\startnarrower +\goto{Attribution NonCommercial ShareAlike}[url(byncsa-simple)] +\stopnarrower + +This one says: + +\startcolor[blue] +You are free: + +\startitemize +\item to copy, distribute, display, and perform the work +\item to make derivative works +\stopitemize + +{\sc Attribution:} You must attribute the work in the manner +specified by the author or licensor. + +{\sc NonCommercial:} You may not use this work for commercial +purposes. + +{\sc Share Alike:} If you alter, transform, or build upon this +work, you may distribute the resulting work only under a license +identical to this one. + +\startitemize +\item For any reuse or distribution, you must make clear to others + the license terms of this work. +\item Any of these conditions can be waived if you get permission from + the copyright holder. +\stopitemize + +Your fair use and other rights are in no way affected by the above. +\stopcolor + +The non||commercial part is mostly a safeguard. We don't mind if +user groups distribute printed copies, publish (parts of) manuals +and|/|or if authors use example code in manuals and books about +\CONTEXT. + +If you distribute \CONTEXT\ and related software on electronic media +as part of \TEX\ distributions (either or not for money), you may +also distribute the manuals and their sources in electronic form, +preferable as provided by the maintainers of \CONTEXT. + +Keep in mind that logos and cover designs are not meant to be +copied. We provide the source code for some manuals, but we don't +always provide all graphics and other resources. For instance, in +some manuals we use commercial fonts and you have to buy those +yourself. + +We provide the typeset manuals at our website. Those are the official +ones. We appreciate it if you do not to distribute manuals compiled +on your own system as substitutes. The manuals are a showcase for what +\CONTEXT\ provides. Help us to assure the quality. + +\subject {More information} + +We're not going to fill \mathematics{n}~pages with legal stuff, so if +you want to know more, you have to consult the web for the legalities +mentioned. Here are a few starting points: + +\startlines +\goto{\url[gpl-simple]}[url(gpl-simple)] +\goto{\url[gpl-legal]}[url(gpl-legal)] +\stoplines + +\startlines +\goto{\url[byncsa-simple]}[url(byncsa-simple)] +\goto{\url[byncsa-legal]}[url(byncsa-legal)] +\stoplines + +\CONTEXT\ itself can be fetched from the main site or its primary mirror: + +\startlines +\goto{\url[pragma]}[url(pragma)] +\goto{\url[mirror]}[url(mirror)] +\stoplines + +A starting point for support can be found at: + +\startlines +\goto{\url[contextlist]}[url(contextlist)] +\goto{\url[garden]}[url(garden)] +\stoplines + +Bugs and feature requests can be registered at the collector: + +\startlines +\goto{\url[collector]}[url(collector)] +\stoplines + +Releases are announced at: + +\startlines +\goto{\url[announce]}[url(announce)] +\stoplines + +The developers can be met at: + +\startlines +\goto{\url[development]}[url(development)] +\stoplines + +\subject {Disclaimer} + +To play safe we include a disclaimer here, taken from the BSD style +licence. For some reason such a text is in capitals, so \unknown + +\start \sc \blue +THIS SOFTWARE IS PROVIDED BY THE AUTHOR \quotation {AS IS} AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\stop + +\unknown\ and don't bother discussing licence issues and related things +with us for the mere sake of discussing licence stuff. + +\blank[2*big] + +\startlines +Hans Hagen +PRAGMA ADE +Hasselt NL +\stoplines + +\ColofonPage + +\stoptext diff --git a/doc/fonts/hoekwater/koeieletters/koeieletters.rme b/doc/fonts/hoekwater/koeieletters/koeieletters.rme new file mode 100644 index 000000000..4be11cce8 --- /dev/null +++ b/doc/fonts/hoekwater/koeieletters/koeieletters.rme @@ -0,0 +1,45 @@ +Remarks + +The Koeieletters font is copyrighted (2006) by Hans Hagen +and Taco Hoekwater. The font is based on original drawings +by Duane Bibby. + +The Koeieletters font is distributed under the Creative +Commons Attribution No Derivative Works licence. A summary +of this licence can be found at the bottom of this file. The +complete version of the licence can be found at: + + http://creativecommons.org/licenses/by-nd/2.5/legalcode + +The font is supported by ConTeXt and more information about +its history, evolution and usage can be found in the manual +at www.pragma-ade.com. + +==== http://creativecommons.org/licenses/by-nd/2.5/ ==== + +Attribution-NoDerivs 2.5 + +You are free: + + * to copy, distribute, display, and perform the work + * to make commercial use of the work + +Under the following conditions: + + Attribution: You must attribute the work in the manner + specified by the author or licensor. + + Derivative Works: You may not alter, transform, or + build upon this work. + + * For any reuse or distribution, you must make clear + to others the license terms of this work. + * Any of these conditions can be waived if you get + permission from the copyright holder. + +Your fair use and other rights are in no way affected +by the above. + +==== end of copy ======================================= + + diff --git a/fonts/afm/hoekwater/context/contnav.afm b/fonts/afm/hoekwater/context/contnav.afm new file mode 100644 index 000000000..1c78d99bc --- /dev/null +++ b/fonts/afm/hoekwater/context/contnav.afm @@ -0,0 +1,44 @@ +StartFontMetrics 2.0 +Comment AFM Generated by Ghostscript/pf2afm +FontName ContextNavigation +FullName ContextNavigation +FamilyName ContextNavigation +Weight Medium +Notice Copyright (c) Pragma, Taco Hoekwater, 1998. All rights reserved. +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 50 +Version 1.0 +EncodingScheme FontSpecific +FontBBox -25 -64 780 602 +StartCharMetrics 27 +C 1 ; WX 507 ; N char01 ; B -18 -64 532 564 ; +C 2 ; WX 507 ; N char02 ; B -25 -64 525 564 ; +C 3 ; WX 625 ; N char03 ; B -25 -64 650 564 ; +C 4 ; WX 625 ; N char04 ; B -25 -64 650 564 ; +C 5 ; WX 755 ; N char05 ; B -20 -64 780 564 ; +C 6 ; WX 755 ; N char06 ; B -25 -64 775 564 ; +C 7 ; WX 577 ; N char07 ; B -25 -25 602 602 ; +C 8 ; WX 192 ; N char08 ; B -25 -25 217 602 ; +C 9 ; WX 531 ; N char09 ; B -25 -25 556 602 ; +C 101 ; WX 507 ; N char65 ; B -18 -64 532 564 ; +C 102 ; WX 507 ; N char66 ; B -25 -64 525 564 ; +C 103 ; WX 625 ; N char67 ; B -25 -64 650 564 ; +C 104 ; WX 625 ; N char68 ; B -25 -64 650 564 ; +C 105 ; WX 755 ; N char69 ; B -20 -64 780 564 ; +C 106 ; WX 755 ; N char6a ; B -25 -64 775 564 ; +C 107 ; WX 577 ; N char6b ; B -25 -25 602 602 ; +C 108 ; WX 192 ; N char6c ; B -25 -25 217 602 ; +C 109 ; WX 531 ; N char6d ; B -25 -25 556 602 ; +C 201 ; WX 507 ; N charc9 ; B -18 -64 532 564 ; +C 202 ; WX 507 ; N charca ; B -25 -64 525 564 ; +C 203 ; WX 625 ; N charcb ; B -25 -64 650 564 ; +C 204 ; WX 625 ; N charcc ; B -25 -64 650 564 ; +C 205 ; WX 755 ; N charcd ; B -20 -64 780 564 ; +C 206 ; WX 755 ; N charce ; B -25 -64 775 564 ; +C 207 ; WX 577 ; N charcf ; B -25 -25 602 602 ; +C 208 ; WX 192 ; N chard0 ; B -25 -25 217 602 ; +C 209 ; WX 531 ; N chard1 ; B -25 -25 556 602 ; +EndCharMetrics +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeieletters-contour.afm b/fonts/afm/hoekwater/koeieletters/koeieletters-contour.afm new file mode 100644 index 000000000..1bd7ec716 --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeieletters-contour.afm @@ -0,0 +1,879 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 20:11:09 2006 +FontName koeieletters-contour +FullName koeieletters-contour +FamilyName koeieletters-contour +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox -8 -2066 1146 821 +CapHeight 636 +XHeight 540 +Ascender 533 +StartCharMetrics 187 +C 0 ; WX 321 ; N parenleft.big ; B 25 -1001 295 39 ; +C 1 ; WX 323 ; N parenright.big ; B 25 -999 298 42 ; +C 2 ; WX 585 ; N slash.big ; B 25 -825 560 39 ; +C 3 ; WX 382 ; N bracketleft.big ; B 25 -988 357 52 ; +C 4 ; WX 502 ; N backslash.big ; B 25 -820 477 44 ; +C 5 ; WX 376 ; N bracketright.big ; B 25 -990 351 50 ; +C 6 ; WX 332 ; N braceleft.big ; B 25 -1008 307 52 ; +C 7 ; WX 243 ; N bar.big ; B 25 -982 218 49 ; +C 8 ; WX 323 ; N braceright.big ; B 24 -1013 298 61 ; +C 9 ; WX 656 ; N integral.big ; B 25 -1159 631 0 ; +C 10 ; WX 1014 ; N summation.big ; B 29 -1049 988 0 ; +C 11 ; WX 701 ; N radical.big ; B 25 -892 709 74 ; +C 12 ; WX 743 ; N radical.bigg ; B 25 -1267 751 74 ; +C 13 ; WX 731 ; N radical.Bigg ; B 25 -1666 739 74 ; +C 14 ; WX 664 ; N radical.BIGG ; B 25 -2066 672 74 ; +C 15 ; WX 122 ; N radical.end ; B -8 0 122 74 ; +C 16 ; WX 8 ; N radical.extender ; B -8 0 17 74 ; +C 17 ; WX 644 ; N radical.alt ; B 25 -717 652 74 ; +C 18 ; WX 613 ; N integral.alt ; B 25 -809 588 0 ; +C 19 ; WX 814 ; N summation.alt ; B 25 -699 788 0 ; +C 20 ; WX 321 ; N parenleft.bigg ; B 25 -1351 295 39 ; +C 21 ; WX 323 ; N parenright.bigg ; B 25 -1349 298 42 ; +C 22 ; WX 714 ; N slash.bigg ; B 25 -1175 689 39 ; +C 23 ; WX 382 ; N bracketleft.bigg ; B 25 -1338 357 52 ; +C 24 ; WX 596 ; N backslash.bigg ; B 25 -1170 571 44 ; +C 25 ; WX 376 ; N bracketright.bigg ; B 25 -1340 351 50 ; +C 26 ; WX 332 ; N braceleft.bigg ; B 25 -1358 307 52 ; +C 27 ; WX 243 ; N bar.bigg ; B 25 -1332 218 49 ; +C 28 ; WX 323 ; N braceright.bigg ; B 24 -1363 298 61 ; +C 29 ; WX 195 ; N bar.begin ; B 0 0 203 74 ; +C 32 ; WX 500 ; N space ; B 0 0 0 0 ; +C 33 ; WX 345 ; N exclam ; B 25 0 319 530 ; +C 34 ; WX 460 ; N quotedbl ; B 25 338 435 544 ; +C 39 ; WX 239 ; N quotesingle ; B 25 338 214 544 ; +C 40 ; WX 321 ; N parenleft ; B 25 -64 295 651 ; +C 41 ; WX 323 ; N parenright ; B 25 -65 298 651 ; +C 42 ; WX 414 ; N asterisk ; B 25 32 389 404 ; +C 43 ; WX 461 ; N plus ; B 25 44 436 404 ; +C 44 ; WX 232 ; N comma ; B 25 -66 207 140 ; +C 45 ; WX 355 ; N hyphen ; B 25 176 330 294 ; +C 46 ; WX 231 ; N period ; B 25 0 206 151 ; +C 47 ; WX 539 ; N slash ; B 25 0 513 514 ; +C 48 ; WX 499 ; N zero ; B 25 0 474 526 ; +C 49 ; WX 488 ; N one ; B 25 0 463 530 ; +C 50 ; WX 539 ; N two ; B 25 0 513 528 ; +C 51 ; WX 501 ; N three ; B 25 0 476 517 ; +C 52 ; WX 514 ; N four ; B 25 0 489 510 ; +C 53 ; WX 521 ; N five ; B 25 0 494 515 ; +C 54 ; WX 513 ; N six ; B 25 0 489 514 ; +C 55 ; WX 540 ; N seven ; B 25 -1 514 526 ; +C 56 ; WX 498 ; N eight ; B 25 -1 474 511 ; +C 57 ; WX 495 ; N nine ; B 23 0 468 513 ; +C 58 ; WX 234 ; N colon ; B 25 52 209 460 ; +C 59 ; WX 245 ; N semicolon ; B 25 -10 219 461 ; +C 60 ; WX 544 ; N less ; B 25 81 519 456 ; +C 61 ; WX 460 ; N equal ; B 25 88 435 404 ; +C 62 ; WX 581 ; N greater ; B 25 66 556 448 ; +C 63 ; WX 518 ; N question ; B 25 -5 493 536 ; +C 64 ; WX 585 ; N at ; B 25 -4 560 479 ; +C 65 ; WX 676 ; N A ; B 30 -8 646 630 ; +C 66 ; WX 654 ; N B ; B 30 -8 622 631 ; +C 67 ; WX 729 ; N C ; B 30 0 679 640 ; +C 68 ; WX 674 ; N D ; B 30 0 643 626 ; +C 69 ; WX 676 ; N E ; B 30 0 645 634 ; +C 70 ; WX 686 ; N F ; B 30 -8 656 638 ; +C 71 ; WX 663 ; N G ; B 30 0 652 643 ; +C 72 ; WX 716 ; N H ; B 30 0 685 642 ; +C 73 ; WX 554 ; N I ; B 30 0 519 636 ; +C 74 ; WX 732 ; N J ; B 30 0 702 652 ; +C 75 ; WX 740 ; N K ; B 30 -4 689 637 ; +C 76 ; WX 626 ; N L ; B 30 -9 595 638 ; +C 77 ; WX 730 ; N M ; B 30 -8 699 631 ; +C 78 ; WX 708 ; N N ; B 30 -1 676 666 ; +C 79 ; WX 783 ; N O ; B 30 -6 704 653 ; +C 80 ; WX 722 ; N P ; B 30 -1 691 646 ; +C 81 ; WX 731 ; N Q ; B 30 0 699 642 ; +C 82 ; WX 703 ; N R ; B 30 -9 672 657 ; +C 83 ; WX 750 ; N S ; B 30 -8 711 648 ; +C 84 ; WX 758 ; N T ; B 30 -9 728 642 ; +C 85 ; WX 687 ; N U ; B 30 0 656 657 ; +C 86 ; WX 728 ; N V ; B 30 -6 692 627 ; +C 87 ; WX 712 ; N W ; B 30 -9 686 639 ; +C 88 ; WX 716 ; N X ; B 30 -6 684 646 ; +C 89 ; WX 726 ; N Y ; B 30 -26 693 642 ; +C 90 ; WX 685 ; N Z ; B 30 -19 651 632 ; +C 91 ; WX 382 ; N bracketleft ; B 25 -73 357 642 ; +C 92 ; WX 489 ; N backslash ; B 25 0 464 514 ; +C 93 ; WX 376 ; N bracketright ; B 25 -73 351 642 ; +C 94 ; WX 480 ; N asciicircum ; B 25 322 455 515 ; +C 95 ; WX 579 ; N underscore ; B 25 -183 554 -51 ; +C 96 ; WX 338 ; N grave ; B 25 570 312 762 ; +C 97 ; WX 565 ; N a ; B 25 -7 540 526 ; +C 98 ; WX 545 ; N b ; B 25 -8 520 526 ; +C 99 ; WX 593 ; N c ; B 25 0 566 535 ; +C 100 ; WX 562 ; N d ; B 25 0 537 523 ; +C 101 ; WX 564 ; N e ; B 25 0 539 530 ; +C 102 ; WX 572 ; N f ; B 25 -8 548 532 ; +C 103 ; WX 570 ; N g ; B 25 0 545 536 ; +C 104 ; WX 597 ; N h ; B 25 0 572 536 ; +C 105 ; WX 462 ; N i ; B 25 -1 434 531 ; +C 106 ; WX 610 ; N j ; B 25 -6 586 545 ; +C 107 ; WX 600 ; N k ; B 25 -5 575 531 ; +C 108 ; WX 522 ; N l ; B 25 -9 497 533 ; +C 109 ; WX 609 ; N m ; B 25 -8 584 528 ; +C 110 ; WX 590 ; N n ; B 25 -1 565 556 ; +C 111 ; WX 613 ; N o ; B 25 -5 588 546 ; +C 112 ; WX 602 ; N p ; B 25 -1 577 540 ; +C 113 ; WX 609 ; N q ; B 25 0 584 536 ; +C 114 ; WX 586 ; N r ; B 25 -8 561 549 ; +C 115 ; WX 625 ; N s ; B 25 -13 594 541 ; +C 116 ; WX 632 ; N t ; B 25 -8 608 536 ; +C 117 ; WX 573 ; N u ; B 25 0 548 549 ; +C 118 ; WX 607 ; N v ; B 25 -5 578 524 ; +C 119 ; WX 602 ; N w ; B 25 -8 573 534 ; +C 120 ; WX 597 ; N x ; B 25 -5 571 540 ; +C 121 ; WX 605 ; N y ; B 25 -28 579 536 ; +C 122 ; WX 571 ; N z ; B 25 -19 544 528 ; +C 123 ; WX 332 ; N braceleft ; B 25 -88 307 625 ; +C 124 ; WX 243 ; N bar ; B 25 0 218 681 ; +C 125 ; WX 323 ; N braceright ; B 24 -74 298 650 ; +C 126 ; WX 592 ; N asciitilde ; B 25 198 568 388 ; +C 156 ; WX 448 ; N dieresis ; B 25 557 423 711 ; +C 168 ; WX 336 ; N acute ; B 25 569 312 754 ; +C 203 ; WX 468 ; N multiply ; B 25 41 443 409 ; +C 244 ; WX 770 ; N infinity ; B 25 87 745 427 ; +C 245 ; WX 645 ; N arrowleft ; B 25 49 620 433 ; +C 246 ; WX 683 ; N arrowright ; B 25 53 658 433 ; +C 247 ; WX 460 ; N minus ; B 25 154 435 302 ; +C 248 ; WX 414 ; N asteriskmath ; B 25 32 389 404 ; +C 249 ; WX 613 ; N integral ; B 25 -155 588 654 ; +C 250 ; WX 814 ; N summation ; B 25 -116 788 583 ; +C 251 ; WX 614 ; N equivalence ; B 25 58 590 426 ; +C 252 ; WX 592 ; N similar ; B 23 198 568 388 ; +C 253 ; WX 224 ; N minute ; B 25 197 199 514 ; +C 254 ; WX 763 ; N emdash ; B 25 165 738 297 ; +C 255 ; WX 534 ; N endash ; B 25 165 509 297 ; +C -1 ; WX 512 ; N hungarumlaut ; B 50 581 487 778 ; +C -1 ; WX 460 ; N quotedblright ; B 25 358 435 564 ; +C -1 ; WX 256 ; N quoteright ; B 25 358 231 564 ; +C -1 ; WX 237 ; N quoteleft ; B 25 357 212 564 ; +C -1 ; WX 465 ; N breve ; B 25 611 440 799 ; +C -1 ; WX 451 ; N quotedblleft ; B 25 358 426 564 ; +C -1 ; WX 256 ; N quotesinglbase ; B 25 -58 231 148 ; +C -1 ; WX 460 ; N quotedblbase ; B 24 -65 435 141 ; +C -1 ; WX 378 ; N second ; B 25 197 353 514 ; +C -1 ; WX 530 ; N radical ; B 25 -62 1146 729 ; +C -1 ; WX 480 ; N circumflex ; B 25 561 455 754 ; +C -1 ; WX 521 ; N tilde ; B 25 564 495 728 ; +C -1 ; WX 462 ; N dotlessi ; B 25 -1 434 531 ; +C -1 ; WX 610 ; N dotlessj ; B 25 -6 586 545 ; +C -1 ; WX 496 ; N plus.alt ; B 25 62 470 464 ; +C -1 ; WX 481 ; N minus.alt ; B 25 174 457 356 ; +C -1 ; WX 552 ; N zero.alt ; B 25 -9 526 528 ; +C -1 ; WX 554 ; N one.alt ; B 25 -12 527 545 ; +C -1 ; WX 569 ; N two.alt ; B 25 -16 546 523 ; +C -1 ; WX 563 ; N three.alt ; B 25 -18 540 532 ; +C -1 ; WX 595 ; N four.alt ; B 25 -14 570 525 ; +C -1 ; WX 573 ; N five.alt ; B 25 -18 553 540 ; +C -1 ; WX 558 ; N six.alt ; B 25 -7 535 536 ; +C -1 ; WX 594 ; N seven.alt ; B 25 -4 568 525 ; +C -1 ; WX 544 ; N eight.alt ; B 25 -19 520 530 ; +C -1 ; WX 594 ; N nine.alt ; B 25 -19 568 536 ; +C -1 ; WX 231 ; N periodcentered ; B 25 153 206 304 ; +C -1 ; WX 231 ; N dotaccent ; B 25 611 206 762 ; +C -1 ; WX 321 ; N parenleft.top ; B 25 -500 278 39 ; +C -1 ; WX 323 ; N parenright.top ; B 25 -500 298 42 ; +C -1 ; WX 321 ; N parenleft.ex ; B 25 -504 223 8 ; +C -1 ; WX 323 ; N parenright.ex ; B 99 -504 298 8 ; +C -1 ; WX 321 ; N parenleft.bot ; B 25 -493 295 8 ; +C -1 ; WX 323 ; N parenright.bot ; B 35 -491 298 8 ; +C -1 ; WX 382 ; N bracketleft.top ; B 25 -500 357 52 ; +C -1 ; WX 376 ; N bracketright.top ; B 41 -500 351 50 ; +C -1 ; WX 382 ; N bracketleft.ex ; B 25 -504 271 8 ; +C -1 ; WX 376 ; N bracketright.ex ; B 116 -504 351 8 ; +C -1 ; WX 382 ; N bracketleft.bot ; B 25 -480 339 8 ; +C -1 ; WX 376 ; N bracketright.bot ; B 25 -482 351 8 ; +C -1 ; WX 465 ; N caron ; B 25 611 440 821 ; +C -1 ; WX 534 ; N macron ; B 25 575 509 707 ; +C -1 ; WX 483 ; N ringaccent ; B 160 560 370 719 ; +C -1 ; WX 547 ; N arrowleft.lft ; B 25 49 555 433 ; +C -1 ; WX 369 ; N arrowright.lft ; B 25 176 377 316 ; +C -1 ; WX 137 ; N arrowleft.rt ; B -8 176 112 316 ; +C -1 ; WX 325 ; N arrowright.rt ; B -8 53 300 433 ; +C -1 ; WX 300 ; N arrow.mid ; B -8 176 308 316 ; +C -1 ; WX 476 ; N radical.bot ; B 25 -1666 413 8 ; +C -1 ; WX 476 ; N radical.top ; B 258 -208 484 74 ; +C -1 ; WX 476 ; N radical.mid ; B 258 -208 413 8 ; +EndCharMetrics +StartKernData +StartKernPairs 667 +KPX C a -31 +KPX C j -31 +KPX C s -30 +KPX C x -23 +KPX C period -35 +KPX C comma -38 +KPX C hyphen -44 +KPX D x -36 +KPX D period -32 +KPX D comma -40 +KPX E a -52 +KPX E b -29 +KPX E c -56 +KPX E e -27 +KPX E f -32 +KPX E g -66 +KPX E h -45 +KPX E j -52 +KPX E k -20 +KPX E l -26 +KPX E m -23 +KPX E n -21 +KPX E o -67 +KPX E p -20 +KPX E q -46 +KPX E s -59 +KPX E x -26 +KPX E z -23 +KPX E period -51 +KPX E comma -52 +KPX E colon -27 +KPX E semicolon -26 +KPX E hyphen -88 +KPX F a -86 +KPX F b -29 +KPX F c -47 +KPX F e -29 +KPX F f -35 +KPX F g -58 +KPX F h -45 +KPX F j -101 +KPX F k -20 +KPX F l -28 +KPX F m -26 +KPX F n -21 +KPX F o -61 +KPX F p -22 +KPX F q -43 +KPX F s -89 +KPX F x -27 +KPX F z -23 +KPX F period -166 +KPX F comma -166 +KPX F colon -30 +KPX F semicolon -30 +KPX F hyphen -115 +KPX G x -32 +KPX G z -24 +KPX G period -32 +KPX G comma -37 +KPX H x -31 +KPX H period -26 +KPX H comma -31 +KPX I a -46 +KPX I b -32 +KPX I c -34 +KPX I d -20 +KPX I e -31 +KPX I f -29 +KPX I g -30 +KPX I h -40 +KPX I j -45 +KPX I k -22 +KPX I l -28 +KPX I m -26 +KPX I n -22 +KPX I o -35 +KPX I p -24 +KPX I q -29 +KPX I s -43 +KPX I x -28 +KPX I z -24 +KPX I period -51 +KPX I comma -54 +KPX I colon -30 +KPX I semicolon -30 +KPX I hyphen -41 +KPX J a -35 +KPX J b -31 +KPX J c -23 +KPX J e -26 +KPX J g -22 +KPX J h -29 +KPX J j -34 +KPX J k -23 +KPX J n -29 +KPX J o -24 +KPX J p -20 +KPX J r -20 +KPX J s -32 +KPX J x -42 +KPX J z -29 +KPX J period -44 +KPX J comma -48 +KPX J hyphen -26 +KPX K a -70 +KPX K b -33 +KPX K c -38 +KPX K d -22 +KPX K e -33 +KPX K f -31 +KPX K g -41 +KPX K h -45 +KPX K j -73 +KPX K k -24 +KPX K l -30 +KPX K m -28 +KPX K n -24 +KPX K o -44 +KPX K p -25 +KPX K q -32 +KPX K s -74 +KPX K x -29 +KPX K z -27 +KPX K period -73 +KPX K comma -74 +KPX K colon -28 +KPX K semicolon -28 +KPX K hyphen -73 +KPX L t -56 +KPX L v -24 +KPX L y -59 +KPX L quoteright -50 +KPX L quotedblright -50 +KPX M a -26 +KPX M j -25 +KPX M s -22 +KPX M x -28 +KPX M period -29 +KPX M comma -32 +KPX M hyphen -21 +KPX N a -32 +KPX N b -32 +KPX N c -28 +KPX N d -22 +KPX N e -30 +KPX N f -24 +KPX N g -28 +KPX N h -31 +KPX N j -31 +KPX N k -26 +KPX N l -23 +KPX N m -23 +KPX N n -28 +KPX N o -28 +KPX N p -25 +KPX N q -25 +KPX N s -30 +KPX N x -38 +KPX N z -29 +KPX N period -35 +KPX N comma -38 +KPX N hyphen -27 +KPX O x -33 +KPX O period -41 +KPX O comma -47 +KPX P a -60 +KPX P b -33 +KPX P c -33 +KPX P d -22 +KPX P e -35 +KPX P f -27 +KPX P g -32 +KPX P h -40 +KPX P j -60 +KPX P k -24 +KPX P l -27 +KPX P m -27 +KPX P n -25 +KPX P o -36 +KPX P p -27 +KPX P q -28 +KPX P s -72 +KPX P x -34 +KPX P z -26 +KPX P period -175 +KPX P comma -175 +KPX P colon -25 +KPX P semicolon -25 +KPX P hyphen -50 +KPX Q a -22 +KPX Q j -23 +KPX Q s -23 +KPX Q x -34 +KPX Q period -34 +KPX Q comma -34 +KPX R a -36 +KPX R j -36 +KPX R s -42 +KPX R x -23 +KPX R period -47 +KPX R comma -49 +KPX R hyphen -33 +KPX S a -54 +KPX S b -28 +KPX S c -43 +KPX S e -21 +KPX S f -28 +KPX S g -48 +KPX S h -40 +KPX S j -53 +KPX S l -21 +KPX S o -51 +KPX S q -36 +KPX S s -51 +KPX S x -21 +KPX S z -21 +KPX S period -60 +KPX S comma -63 +KPX S hyphen -50 +KPX T a -81 +KPX T b -28 +KPX T c -56 +KPX T e -23 +KPX T f -29 +KPX T g -54 +KPX T h -40 +KPX T j -80 +KPX T l -23 +KPX T m -21 +KPX T o -57 +KPX T q -38 +KPX T s -89 +KPX T x -23 +KPX T z -22 +KPX T period -158 +KPX T comma -159 +KPX T hyphen -71 +KPX U x -25 +KPX U comma -24 +KPX V a -62 +KPX V b -28 +KPX V c -38 +KPX V e -23 +KPX V f -29 +KPX V g -36 +KPX V h -41 +KPX V j -62 +KPX V l -25 +KPX V o -38 +KPX V q -33 +KPX V s -67 +KPX V x -23 +KPX V z -22 +KPX V period -93 +KPX V comma -97 +KPX V hyphen -47 +KPX W a -30 +KPX W b -30 +KPX W c -26 +KPX W e -27 +KPX W f -23 +KPX W g -25 +KPX W h -28 +KPX W j -29 +KPX W k -22 +KPX W l -23 +KPX W m -23 +KPX W n -22 +KPX W o -26 +KPX W p -21 +KPX W q -24 +KPX W s -27 +KPX W x -25 +KPX W z -25 +KPX W period -41 +KPX W comma -47 +KPX W colon -25 +KPX W semicolon -24 +KPX W hyphen -25 +KPX X g -22 +KPX X o -25 +KPX X hyphen -46 +KPX Y a -72 +KPX Y b -28 +KPX Y c -46 +KPX Y e -24 +KPX Y f -29 +KPX Y g -44 +KPX Y h -40 +KPX Y j -71 +KPX Y l -24 +KPX Y m -21 +KPX Y o -48 +KPX Y q -40 +KPX Y s -88 +KPX Y x -24 +KPX Y z -22 +KPX Y period -154 +KPX Y comma -154 +KPX Y colon -20 +KPX Y semicolon -20 +KPX Y hyphen -68 +KPX Z a -43 +KPX Z b -28 +KPX Z c -44 +KPX Z e -21 +KPX Z f -24 +KPX Z g -44 +KPX Z h -40 +KPX Z j -43 +KPX Z l -20 +KPX Z o -50 +KPX Z q -35 +KPX Z s -43 +KPX Z x -20 +KPX Z z -21 +KPX Z period -44 +KPX Z comma -44 +KPX Z hyphen -47 +KPX c a -31 +KPX c j -31 +KPX c s -30 +KPX c x -23 +KPX c period -35 +KPX c comma -38 +KPX c hyphen -44 +KPX d x -36 +KPX d period -32 +KPX d comma -40 +KPX e a -52 +KPX e b -29 +KPX e c -56 +KPX e e -27 +KPX e f -32 +KPX e g -66 +KPX e h -45 +KPX e j -52 +KPX e k -20 +KPX e l -26 +KPX e m -23 +KPX e n -21 +KPX e o -67 +KPX e p -20 +KPX e q -46 +KPX e s -59 +KPX e x -26 +KPX e z -23 +KPX e period -51 +KPX e comma -52 +KPX e colon -27 +KPX e semicolon -26 +KPX e hyphen -88 +KPX f a -86 +KPX f b -29 +KPX f c -47 +KPX f e -29 +KPX f f -35 +KPX f g -58 +KPX f h -45 +KPX f j -101 +KPX f k -20 +KPX f l -28 +KPX f m -26 +KPX f n -21 +KPX f o -61 +KPX f p -22 +KPX f q -43 +KPX f s -89 +KPX f x -27 +KPX f z -23 +KPX f period -166 +KPX f comma -166 +KPX f colon -30 +KPX f semicolon -30 +KPX f hyphen -115 +KPX g x -32 +KPX g z -24 +KPX g period -32 +KPX g comma -37 +KPX h x -31 +KPX h period -26 +KPX h comma -31 +KPX i a -46 +KPX i b -32 +KPX i c -34 +KPX i d -20 +KPX i e -31 +KPX i f -29 +KPX i g -30 +KPX i h -40 +KPX i j -45 +KPX i k -22 +KPX i l -28 +KPX i m -26 +KPX i n -22 +KPX i o -35 +KPX i p -24 +KPX i q -29 +KPX i s -43 +KPX i x -28 +KPX i z -24 +KPX i period -51 +KPX i comma -54 +KPX i colon -30 +KPX i semicolon -30 +KPX i hyphen -41 +KPX j a -35 +KPX j b -31 +KPX j c -23 +KPX j e -26 +KPX j g -22 +KPX j h -29 +KPX j j -34 +KPX j k -23 +KPX j n -29 +KPX j o -24 +KPX j p -20 +KPX j r -20 +KPX j s -32 +KPX j x -42 +KPX j z -29 +KPX j period -44 +KPX j comma -48 +KPX j hyphen -26 +KPX k a -71 +KPX k b -32 +KPX k c -38 +KPX k e -28 +KPX k f -31 +KPX k g -42 +KPX k h -45 +KPX k j -72 +KPX k k -22 +KPX k l -28 +KPX k m -26 +KPX k n -22 +KPX k o -46 +KPX k p -22 +KPX k q -32 +KPX k s -73 +KPX k x -27 +KPX k z -25 +KPX k period -72 +KPX k comma -73 +KPX k colon -25 +KPX k semicolon -25 +KPX k hyphen -74 +KPX l t -56 +KPX l v -24 +KPX l y -59 +KPX l quoteright -50 +KPX l quotedblright -50 +KPX m a -26 +KPX m j -25 +KPX m s -22 +KPX m x -28 +KPX m period -29 +KPX m comma -32 +KPX m hyphen -21 +KPX n a -32 +KPX n b -32 +KPX n c -28 +KPX n d -22 +KPX n e -30 +KPX n f -24 +KPX n g -28 +KPX n h -31 +KPX n j -31 +KPX n k -26 +KPX n l -23 +KPX n m -23 +KPX n n -28 +KPX n o -28 +KPX n p -25 +KPX n q -25 +KPX n s -30 +KPX n x -38 +KPX n z -29 +KPX n period -35 +KPX n comma -38 +KPX n hyphen -27 +KPX o x -33 +KPX o period -41 +KPX o comma -47 +KPX p a -60 +KPX p b -33 +KPX p c -33 +KPX p d -22 +KPX p e -35 +KPX p f -27 +KPX p g -32 +KPX p h -40 +KPX p j -60 +KPX p k -24 +KPX p l -27 +KPX p m -27 +KPX p n -25 +KPX p o -36 +KPX p p -27 +KPX p q -28 +KPX p s -72 +KPX p x -34 +KPX p z -26 +KPX p period -175 +KPX p comma -175 +KPX p colon -25 +KPX p semicolon -25 +KPX p hyphen -50 +KPX q a -22 +KPX q j -23 +KPX q s -23 +KPX q x -34 +KPX q period -34 +KPX q comma -34 +KPX r a -36 +KPX r j -36 +KPX r s -42 +KPX r x -23 +KPX r period -47 +KPX r comma -49 +KPX r hyphen -33 +KPX s a -54 +KPX s b -28 +KPX s c -43 +KPX s e -21 +KPX s f -28 +KPX s g -48 +KPX s h -40 +KPX s j -53 +KPX s l -21 +KPX s o -51 +KPX s q -36 +KPX s s -51 +KPX s x -21 +KPX s z -21 +KPX s period -60 +KPX s comma -63 +KPX s hyphen -50 +KPX t a -81 +KPX t b -28 +KPX t c -56 +KPX t e -23 +KPX t f -29 +KPX t g -54 +KPX t h -40 +KPX t j -80 +KPX t l -23 +KPX t m -21 +KPX t o -57 +KPX t q -38 +KPX t s -89 +KPX t x -23 +KPX t z -22 +KPX t period -158 +KPX t comma -159 +KPX t hyphen -71 +KPX u x -25 +KPX u comma -24 +KPX v a -62 +KPX v b -28 +KPX v c -38 +KPX v e -23 +KPX v f -29 +KPX v g -36 +KPX v h -41 +KPX v j -62 +KPX v l -25 +KPX v o -38 +KPX v q -33 +KPX v s -67 +KPX v x -23 +KPX v z -22 +KPX v period -93 +KPX v comma -97 +KPX v hyphen -47 +KPX w a -30 +KPX w b -30 +KPX w c -26 +KPX w e -27 +KPX w f -23 +KPX w g -25 +KPX w h -28 +KPX w j -29 +KPX w k -22 +KPX w l -23 +KPX w m -23 +KPX w n -22 +KPX w o -26 +KPX w p -21 +KPX w q -24 +KPX w s -27 +KPX w x -25 +KPX w z -25 +KPX w period -41 +KPX w comma -47 +KPX w colon -25 +KPX w semicolon -24 +KPX w hyphen -25 +KPX x g -22 +KPX x o -25 +KPX x hyphen -46 +KPX y a -72 +KPX y b -28 +KPX y c -46 +KPX y e -24 +KPX y f -29 +KPX y g -44 +KPX y h -40 +KPX y j -71 +KPX y l -24 +KPX y m -21 +KPX y o -48 +KPX y q -40 +KPX y s -88 +KPX y x -24 +KPX y z -22 +KPX y period -154 +KPX y comma -154 +KPX y colon -20 +KPX y semicolon -20 +KPX y hyphen -68 +KPX z a -43 +KPX z b -28 +KPX z c -44 +KPX z e -21 +KPX z f -24 +KPX z g -44 +KPX z h -40 +KPX z j -43 +KPX z l -20 +KPX z o -50 +KPX z q -35 +KPX z s -43 +KPX z x -20 +KPX z z -21 +KPX z period -44 +KPX z comma -44 +KPX z hyphen -47 +KPX quoteleft a -50 +KPX quoteleft j -50 +KPX quoteleft A -50 +KPX quoteleft J -50 +KPX quoteleft c -30 +KPX quoteleft g -30 +KPX quoteleft o -30 +KPX quoteleft q -30 +KPX quoteleft s -30 +KPX quoteleft C -30 +KPX quoteleft G -30 +KPX quoteleft O -30 +KPX quoteleft Q -30 +KPX quoteleft S -30 +KPX quotedblleft a -50 +KPX quotedblleft j -50 +KPX quotedblleft A -50 +KPX quotedblleft J -50 +KPX quotedblleft c -30 +KPX quotedblleft g -30 +KPX quotedblleft o -30 +KPX quotedblleft q -30 +KPX quotedblleft s -30 +KPX quotedblleft C -30 +KPX quotedblleft G -30 +KPX quotedblleft O -30 +KPX quotedblleft Q -30 +KPX quotedblleft S -30 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeieletters.afm b/fonts/afm/hoekwater/koeieletters/koeieletters.afm new file mode 100644 index 000000000..477546211 --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeieletters.afm @@ -0,0 +1,879 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 13:49:26 2006 +FontName koeieletters +FullName koeieletters +FamilyName koeieletters +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox -12 -2066 1146 821 +CapHeight 636 +XHeight 540 +Ascender 533 +StartCharMetrics 187 +C 0 ; WX 321 ; N parenleft.big ; B 25 -1001 295 39 ; +C 1 ; WX 323 ; N parenright.big ; B 25 -999 298 42 ; +C 2 ; WX 585 ; N slash.big ; B 25 -825 560 39 ; +C 3 ; WX 382 ; N bracketleft.big ; B 25 -988 357 52 ; +C 4 ; WX 502 ; N backslash.big ; B 25 -820 477 44 ; +C 5 ; WX 376 ; N bracketright.big ; B 25 -990 351 50 ; +C 6 ; WX 332 ; N braceleft.big ; B 25 -1008 307 52 ; +C 7 ; WX 243 ; N bar.big ; B 25 -982 218 49 ; +C 8 ; WX 323 ; N braceright.big ; B 24 -1013 298 61 ; +C 9 ; WX 656 ; N integral.big ; B 25 -1159 631 0 ; +C 10 ; WX 1014 ; N summation.big ; B 29 -1049 988 0 ; +C 11 ; WX 701 ; N radical.big ; B 25 -892 709 74 ; +C 12 ; WX 743 ; N radical.bigg ; B 25 -1267 751 74 ; +C 13 ; WX 731 ; N radical.Bigg ; B 25 -1666 739 74 ; +C 14 ; WX 664 ; N radical.BIGG ; B 25 -2066 672 74 ; +C 15 ; WX 122 ; N radical.end ; B -8 0 122 74 ; +C 16 ; WX 8 ; N radical.extender ; B -12 0 21 74 ; +C 17 ; WX 644 ; N radical.alt ; B 25 -717 652 74 ; +C 18 ; WX 613 ; N integral.alt ; B 25 -809 588 0 ; +C 19 ; WX 814 ; N summation.alt ; B 25 -699 788 0 ; +C 20 ; WX 321 ; N parenleft.bigg ; B 25 -1351 295 39 ; +C 21 ; WX 323 ; N parenright.bigg ; B 25 -1349 298 42 ; +C 22 ; WX 714 ; N slash.bigg ; B 25 -1175 689 39 ; +C 23 ; WX 382 ; N bracketleft.bigg ; B 25 -1338 357 52 ; +C 24 ; WX 596 ; N backslash.bigg ; B 25 -1170 571 44 ; +C 25 ; WX 376 ; N bracketright.bigg ; B 25 -1340 351 50 ; +C 26 ; WX 332 ; N braceleft.bigg ; B 25 -1358 307 52 ; +C 27 ; WX 243 ; N bar.bigg ; B 25 -1332 218 49 ; +C 28 ; WX 323 ; N braceright.bigg ; B 24 -1363 298 61 ; +C 29 ; WX 195 ; N bar.begin ; B 0 0 203 74 ; +C 32 ; WX 500 ; N space ; B 0 0 0 0 ; +C 33 ; WX 345 ; N exclam ; B 25 0 319 530 ; +C 34 ; WX 460 ; N quotedbl ; B 25 338 435 544 ; +C 39 ; WX 239 ; N quotesingle ; B 25 338 214 544 ; +C 40 ; WX 321 ; N parenleft ; B 25 -64 295 651 ; +C 41 ; WX 323 ; N parenright ; B 25 -65 298 651 ; +C 42 ; WX 414 ; N asterisk ; B 25 32 389 404 ; +C 43 ; WX 461 ; N plus ; B 25 44 436 404 ; +C 44 ; WX 232 ; N comma ; B 25 -66 207 140 ; +C 45 ; WX 355 ; N hyphen ; B 25 176 330 294 ; +C 46 ; WX 231 ; N period ; B 25 0 206 151 ; +C 47 ; WX 539 ; N slash ; B 25 0 513 514 ; +C 48 ; WX 499 ; N zero ; B 25 0 474 526 ; +C 49 ; WX 488 ; N one ; B 25 0 463 530 ; +C 50 ; WX 539 ; N two ; B 25 0 513 528 ; +C 51 ; WX 501 ; N three ; B 25 0 476 517 ; +C 52 ; WX 514 ; N four ; B 25 0 489 510 ; +C 53 ; WX 521 ; N five ; B 25 0 494 515 ; +C 54 ; WX 513 ; N six ; B 25 0 489 514 ; +C 55 ; WX 540 ; N seven ; B 25 -1 514 526 ; +C 56 ; WX 498 ; N eight ; B 25 -1 474 511 ; +C 57 ; WX 495 ; N nine ; B 23 0 468 513 ; +C 58 ; WX 234 ; N colon ; B 25 52 209 460 ; +C 59 ; WX 245 ; N semicolon ; B 25 -10 219 461 ; +C 60 ; WX 544 ; N less ; B 25 81 519 456 ; +C 61 ; WX 460 ; N equal ; B 25 88 435 404 ; +C 62 ; WX 581 ; N greater ; B 25 66 556 448 ; +C 63 ; WX 518 ; N question ; B 25 -5 493 536 ; +C 64 ; WX 585 ; N at ; B 25 -4 560 479 ; +C 65 ; WX 676 ; N A ; B 30 -8 646 630 ; +C 66 ; WX 654 ; N B ; B 30 -8 622 631 ; +C 67 ; WX 729 ; N C ; B 30 0 679 640 ; +C 68 ; WX 674 ; N D ; B 30 0 643 626 ; +C 69 ; WX 676 ; N E ; B 30 0 645 634 ; +C 70 ; WX 686 ; N F ; B 30 -8 656 638 ; +C 71 ; WX 663 ; N G ; B 30 0 652 643 ; +C 72 ; WX 716 ; N H ; B 30 0 685 642 ; +C 73 ; WX 554 ; N I ; B 30 0 519 636 ; +C 74 ; WX 732 ; N J ; B 30 0 702 652 ; +C 75 ; WX 740 ; N K ; B 30 -4 689 637 ; +C 76 ; WX 626 ; N L ; B 30 -9 595 638 ; +C 77 ; WX 730 ; N M ; B 30 -8 699 631 ; +C 78 ; WX 708 ; N N ; B 30 -1 676 666 ; +C 79 ; WX 783 ; N O ; B 30 -6 704 653 ; +C 80 ; WX 722 ; N P ; B 30 -1 691 646 ; +C 81 ; WX 731 ; N Q ; B 30 0 699 642 ; +C 82 ; WX 703 ; N R ; B 30 -9 672 657 ; +C 83 ; WX 750 ; N S ; B 30 -8 711 648 ; +C 84 ; WX 758 ; N T ; B 30 -9 728 642 ; +C 85 ; WX 687 ; N U ; B 30 0 656 657 ; +C 86 ; WX 728 ; N V ; B 30 -6 692 627 ; +C 87 ; WX 712 ; N W ; B 30 -9 686 639 ; +C 88 ; WX 716 ; N X ; B 30 -6 684 646 ; +C 89 ; WX 726 ; N Y ; B 30 -26 693 642 ; +C 90 ; WX 685 ; N Z ; B 30 -19 651 632 ; +C 91 ; WX 382 ; N bracketleft ; B 25 -73 357 642 ; +C 92 ; WX 489 ; N backslash ; B 25 0 464 514 ; +C 93 ; WX 376 ; N bracketright ; B 25 -73 351 642 ; +C 94 ; WX 480 ; N asciicircum ; B 25 322 455 515 ; +C 95 ; WX 579 ; N underscore ; B 25 -183 554 -51 ; +C 96 ; WX 338 ; N grave ; B 25 570 312 762 ; +C 97 ; WX 565 ; N a ; B 25 -7 540 526 ; +C 98 ; WX 545 ; N b ; B 25 -8 520 526 ; +C 99 ; WX 593 ; N c ; B 25 0 566 535 ; +C 100 ; WX 562 ; N d ; B 25 0 537 523 ; +C 101 ; WX 564 ; N e ; B 25 0 539 530 ; +C 102 ; WX 572 ; N f ; B 25 -8 548 532 ; +C 103 ; WX 570 ; N g ; B 25 0 545 536 ; +C 104 ; WX 597 ; N h ; B 25 0 572 536 ; +C 105 ; WX 462 ; N i ; B 25 -1 434 531 ; +C 106 ; WX 610 ; N j ; B 25 -6 586 545 ; +C 107 ; WX 600 ; N k ; B 25 -5 575 531 ; +C 108 ; WX 522 ; N l ; B 25 -9 497 533 ; +C 109 ; WX 609 ; N m ; B 25 -8 584 528 ; +C 110 ; WX 590 ; N n ; B 25 -1 565 556 ; +C 111 ; WX 613 ; N o ; B 25 -5 588 546 ; +C 112 ; WX 602 ; N p ; B 25 -1 577 540 ; +C 113 ; WX 609 ; N q ; B 25 0 584 536 ; +C 114 ; WX 586 ; N r ; B 25 -8 561 549 ; +C 115 ; WX 625 ; N s ; B 25 -13 594 541 ; +C 116 ; WX 632 ; N t ; B 25 -8 608 536 ; +C 117 ; WX 573 ; N u ; B 25 0 548 549 ; +C 118 ; WX 607 ; N v ; B 25 -5 578 524 ; +C 119 ; WX 602 ; N w ; B 25 -8 573 534 ; +C 120 ; WX 597 ; N x ; B 25 -5 571 540 ; +C 121 ; WX 605 ; N y ; B 25 -28 579 536 ; +C 122 ; WX 571 ; N z ; B 25 -19 544 528 ; +C 123 ; WX 332 ; N braceleft ; B 25 -88 307 625 ; +C 124 ; WX 243 ; N bar ; B 25 0 218 681 ; +C 125 ; WX 323 ; N braceright ; B 24 -74 298 650 ; +C 126 ; WX 592 ; N asciitilde ; B 25 198 568 388 ; +C 156 ; WX 448 ; N dieresis ; B 25 557 423 711 ; +C 168 ; WX 336 ; N acute ; B 25 569 312 754 ; +C 203 ; WX 468 ; N multiply ; B 25 41 443 409 ; +C 244 ; WX 770 ; N infinity ; B 25 87 745 427 ; +C 245 ; WX 645 ; N arrowleft ; B 25 49 620 433 ; +C 246 ; WX 683 ; N arrowright ; B 25 53 658 433 ; +C 247 ; WX 460 ; N minus ; B 25 154 435 302 ; +C 248 ; WX 414 ; N asteriskmath ; B 25 32 389 404 ; +C 249 ; WX 613 ; N integral ; B 25 -155 588 654 ; +C 250 ; WX 814 ; N summation ; B 25 -116 788 583 ; +C 251 ; WX 614 ; N equivalence ; B 25 58 590 426 ; +C 252 ; WX 592 ; N similar ; B 23 198 568 388 ; +C 253 ; WX 224 ; N minute ; B 25 197 199 514 ; +C 254 ; WX 763 ; N emdash ; B 25 165 738 297 ; +C 255 ; WX 534 ; N endash ; B 25 165 509 297 ; +C -1 ; WX 512 ; N hungarumlaut ; B 50 581 487 778 ; +C -1 ; WX 460 ; N quotedblright ; B 25 358 435 564 ; +C -1 ; WX 256 ; N quoteright ; B 25 358 231 564 ; +C -1 ; WX 237 ; N quoteleft ; B 25 357 212 564 ; +C -1 ; WX 465 ; N breve ; B 25 611 440 799 ; +C -1 ; WX 451 ; N quotedblleft ; B 25 358 426 564 ; +C -1 ; WX 256 ; N quotesinglbase ; B 25 -58 231 148 ; +C -1 ; WX 460 ; N quotedblbase ; B 24 -65 435 141 ; +C -1 ; WX 378 ; N second ; B 25 197 353 514 ; +C -1 ; WX 530 ; N radical ; B 25 -62 1146 729 ; +C -1 ; WX 480 ; N circumflex ; B 25 561 455 754 ; +C -1 ; WX 521 ; N tilde ; B 25 564 495 728 ; +C -1 ; WX 462 ; N dotlessi ; B 25 -1 434 531 ; +C -1 ; WX 610 ; N dotlessj ; B 25 -6 586 545 ; +C -1 ; WX 496 ; N plus.alt ; B 25 62 470 464 ; +C -1 ; WX 481 ; N minus.alt ; B 25 174 457 356 ; +C -1 ; WX 552 ; N zero.alt ; B 25 -9 526 528 ; +C -1 ; WX 554 ; N one.alt ; B 25 -12 527 545 ; +C -1 ; WX 569 ; N two.alt ; B 25 -16 546 523 ; +C -1 ; WX 563 ; N three.alt ; B 25 -18 540 532 ; +C -1 ; WX 595 ; N four.alt ; B 25 -14 570 525 ; +C -1 ; WX 573 ; N five.alt ; B 25 -18 553 540 ; +C -1 ; WX 558 ; N six.alt ; B 25 -7 535 536 ; +C -1 ; WX 594 ; N seven.alt ; B 25 -4 568 525 ; +C -1 ; WX 544 ; N eight.alt ; B 25 -19 520 530 ; +C -1 ; WX 594 ; N nine.alt ; B 25 -19 568 536 ; +C -1 ; WX 231 ; N periodcentered ; B 25 153 206 304 ; +C -1 ; WX 231 ; N dotaccent ; B 25 611 206 762 ; +C -1 ; WX 321 ; N parenleft.top ; B 25 -500 278 39 ; +C -1 ; WX 323 ; N parenright.top ; B 25 -500 298 42 ; +C -1 ; WX 321 ; N parenleft.ex ; B 25 -504 223 8 ; +C -1 ; WX 323 ; N parenright.ex ; B 99 -504 298 8 ; +C -1 ; WX 321 ; N parenleft.bot ; B 25 -493 295 8 ; +C -1 ; WX 323 ; N parenright.bot ; B 35 -491 298 8 ; +C -1 ; WX 382 ; N bracketleft.top ; B 25 -500 357 52 ; +C -1 ; WX 376 ; N bracketright.top ; B 41 -500 351 50 ; +C -1 ; WX 382 ; N bracketleft.ex ; B 25 -504 271 8 ; +C -1 ; WX 376 ; N bracketright.ex ; B 116 -504 351 8 ; +C -1 ; WX 382 ; N bracketleft.bot ; B 25 -480 339 8 ; +C -1 ; WX 376 ; N bracketright.bot ; B 25 -482 351 8 ; +C -1 ; WX 465 ; N caron ; B 25 611 440 821 ; +C -1 ; WX 534 ; N macron ; B 25 575 509 707 ; +C -1 ; WX 483 ; N ringaccent ; B 160 560 370 719 ; +C -1 ; WX 547 ; N arrowleft.lft ; B 25 49 555 433 ; +C -1 ; WX 369 ; N arrowright.lft ; B 25 176 377 316 ; +C -1 ; WX 137 ; N arrowleft.rt ; B -8 176 112 316 ; +C -1 ; WX 325 ; N arrowright.rt ; B -8 53 300 433 ; +C -1 ; WX 300 ; N arrow.mid ; B -8 176 308 316 ; +C -1 ; WX 476 ; N radical.bot ; B 25 -1666 413 8 ; +C -1 ; WX 476 ; N radical.top ; B 258 -208 484 74 ; +C -1 ; WX 476 ; N radical.mid ; B 258 -208 413 8 ; +EndCharMetrics +StartKernData +StartKernPairs 667 +KPX C a -31 +KPX C j -31 +KPX C s -30 +KPX C x -23 +KPX C period -35 +KPX C comma -38 +KPX C hyphen -44 +KPX D x -36 +KPX D period -32 +KPX D comma -40 +KPX E a -52 +KPX E b -29 +KPX E c -56 +KPX E e -27 +KPX E f -32 +KPX E g -66 +KPX E h -45 +KPX E j -52 +KPX E k -20 +KPX E l -26 +KPX E m -23 +KPX E n -21 +KPX E o -67 +KPX E p -20 +KPX E q -46 +KPX E s -59 +KPX E x -26 +KPX E z -23 +KPX E period -51 +KPX E comma -52 +KPX E colon -27 +KPX E semicolon -26 +KPX E hyphen -88 +KPX F a -86 +KPX F b -29 +KPX F c -47 +KPX F e -29 +KPX F f -35 +KPX F g -58 +KPX F h -45 +KPX F j -101 +KPX F k -20 +KPX F l -28 +KPX F m -26 +KPX F n -21 +KPX F o -61 +KPX F p -22 +KPX F q -43 +KPX F s -89 +KPX F x -27 +KPX F z -23 +KPX F period -166 +KPX F comma -166 +KPX F colon -30 +KPX F semicolon -30 +KPX F hyphen -115 +KPX G x -32 +KPX G z -24 +KPX G period -32 +KPX G comma -37 +KPX H x -31 +KPX H period -26 +KPX H comma -31 +KPX I a -46 +KPX I b -32 +KPX I c -34 +KPX I d -20 +KPX I e -31 +KPX I f -29 +KPX I g -30 +KPX I h -40 +KPX I j -45 +KPX I k -22 +KPX I l -28 +KPX I m -26 +KPX I n -22 +KPX I o -35 +KPX I p -24 +KPX I q -29 +KPX I s -43 +KPX I x -28 +KPX I z -24 +KPX I period -51 +KPX I comma -54 +KPX I colon -30 +KPX I semicolon -30 +KPX I hyphen -41 +KPX J a -35 +KPX J b -31 +KPX J c -23 +KPX J e -26 +KPX J g -22 +KPX J h -29 +KPX J j -34 +KPX J k -23 +KPX J n -29 +KPX J o -24 +KPX J p -20 +KPX J r -20 +KPX J s -32 +KPX J x -42 +KPX J z -29 +KPX J period -44 +KPX J comma -48 +KPX J hyphen -26 +KPX K a -70 +KPX K b -33 +KPX K c -38 +KPX K d -22 +KPX K e -33 +KPX K f -31 +KPX K g -41 +KPX K h -45 +KPX K j -73 +KPX K k -24 +KPX K l -30 +KPX K m -28 +KPX K n -24 +KPX K o -44 +KPX K p -25 +KPX K q -32 +KPX K s -74 +KPX K x -29 +KPX K z -27 +KPX K period -73 +KPX K comma -74 +KPX K colon -28 +KPX K semicolon -28 +KPX K hyphen -73 +KPX L t -56 +KPX L v -24 +KPX L y -59 +KPX L quoteright -50 +KPX L quotedblright -50 +KPX M a -26 +KPX M j -25 +KPX M s -22 +KPX M x -28 +KPX M period -29 +KPX M comma -32 +KPX M hyphen -21 +KPX N a -32 +KPX N b -32 +KPX N c -28 +KPX N d -22 +KPX N e -30 +KPX N f -24 +KPX N g -28 +KPX N h -31 +KPX N j -31 +KPX N k -26 +KPX N l -23 +KPX N m -23 +KPX N n -28 +KPX N o -28 +KPX N p -25 +KPX N q -25 +KPX N s -30 +KPX N x -38 +KPX N z -29 +KPX N period -35 +KPX N comma -38 +KPX N hyphen -27 +KPX O x -33 +KPX O period -41 +KPX O comma -47 +KPX P a -60 +KPX P b -33 +KPX P c -33 +KPX P d -22 +KPX P e -35 +KPX P f -27 +KPX P g -32 +KPX P h -40 +KPX P j -60 +KPX P k -24 +KPX P l -27 +KPX P m -27 +KPX P n -25 +KPX P o -36 +KPX P p -27 +KPX P q -28 +KPX P s -72 +KPX P x -34 +KPX P z -26 +KPX P period -175 +KPX P comma -175 +KPX P colon -25 +KPX P semicolon -25 +KPX P hyphen -50 +KPX Q a -22 +KPX Q j -23 +KPX Q s -23 +KPX Q x -34 +KPX Q period -34 +KPX Q comma -34 +KPX R a -36 +KPX R j -36 +KPX R s -42 +KPX R x -23 +KPX R period -47 +KPX R comma -49 +KPX R hyphen -33 +KPX S a -54 +KPX S b -28 +KPX S c -43 +KPX S e -21 +KPX S f -28 +KPX S g -48 +KPX S h -40 +KPX S j -53 +KPX S l -21 +KPX S o -51 +KPX S q -36 +KPX S s -51 +KPX S x -21 +KPX S z -21 +KPX S period -60 +KPX S comma -63 +KPX S hyphen -50 +KPX T a -81 +KPX T b -28 +KPX T c -56 +KPX T e -23 +KPX T f -29 +KPX T g -54 +KPX T h -40 +KPX T j -80 +KPX T l -23 +KPX T m -21 +KPX T o -57 +KPX T q -38 +KPX T s -89 +KPX T x -23 +KPX T z -22 +KPX T period -158 +KPX T comma -159 +KPX T hyphen -71 +KPX U x -25 +KPX U comma -24 +KPX V a -62 +KPX V b -28 +KPX V c -38 +KPX V e -23 +KPX V f -29 +KPX V g -36 +KPX V h -41 +KPX V j -62 +KPX V l -25 +KPX V o -38 +KPX V q -33 +KPX V s -67 +KPX V x -23 +KPX V z -22 +KPX V period -93 +KPX V comma -97 +KPX V hyphen -47 +KPX W a -30 +KPX W b -30 +KPX W c -26 +KPX W e -27 +KPX W f -23 +KPX W g -25 +KPX W h -28 +KPX W j -29 +KPX W k -22 +KPX W l -23 +KPX W m -23 +KPX W n -22 +KPX W o -26 +KPX W p -21 +KPX W q -24 +KPX W s -27 +KPX W x -25 +KPX W z -25 +KPX W period -41 +KPX W comma -47 +KPX W colon -25 +KPX W semicolon -24 +KPX W hyphen -25 +KPX X g -22 +KPX X o -25 +KPX X hyphen -46 +KPX Y a -72 +KPX Y b -28 +KPX Y c -46 +KPX Y e -24 +KPX Y f -29 +KPX Y g -44 +KPX Y h -40 +KPX Y j -71 +KPX Y l -24 +KPX Y m -21 +KPX Y o -48 +KPX Y q -40 +KPX Y s -88 +KPX Y x -24 +KPX Y z -22 +KPX Y period -154 +KPX Y comma -154 +KPX Y colon -20 +KPX Y semicolon -20 +KPX Y hyphen -68 +KPX Z a -43 +KPX Z b -28 +KPX Z c -44 +KPX Z e -21 +KPX Z f -24 +KPX Z g -44 +KPX Z h -40 +KPX Z j -43 +KPX Z l -20 +KPX Z o -50 +KPX Z q -35 +KPX Z s -43 +KPX Z x -20 +KPX Z z -21 +KPX Z period -44 +KPX Z comma -44 +KPX Z hyphen -47 +KPX c a -31 +KPX c j -31 +KPX c s -30 +KPX c x -23 +KPX c period -35 +KPX c comma -38 +KPX c hyphen -44 +KPX d x -36 +KPX d period -32 +KPX d comma -40 +KPX e a -52 +KPX e b -29 +KPX e c -56 +KPX e e -27 +KPX e f -32 +KPX e g -66 +KPX e h -45 +KPX e j -52 +KPX e k -20 +KPX e l -26 +KPX e m -23 +KPX e n -21 +KPX e o -67 +KPX e p -20 +KPX e q -46 +KPX e s -59 +KPX e x -26 +KPX e z -23 +KPX e period -51 +KPX e comma -52 +KPX e colon -27 +KPX e semicolon -26 +KPX e hyphen -88 +KPX f a -86 +KPX f b -29 +KPX f c -47 +KPX f e -29 +KPX f f -35 +KPX f g -58 +KPX f h -45 +KPX f j -101 +KPX f k -20 +KPX f l -28 +KPX f m -26 +KPX f n -21 +KPX f o -61 +KPX f p -22 +KPX f q -43 +KPX f s -89 +KPX f x -27 +KPX f z -23 +KPX f period -166 +KPX f comma -166 +KPX f colon -30 +KPX f semicolon -30 +KPX f hyphen -115 +KPX g x -32 +KPX g z -24 +KPX g period -32 +KPX g comma -37 +KPX h x -31 +KPX h period -26 +KPX h comma -31 +KPX i a -46 +KPX i b -32 +KPX i c -34 +KPX i d -20 +KPX i e -31 +KPX i f -29 +KPX i g -30 +KPX i h -40 +KPX i j -45 +KPX i k -22 +KPX i l -28 +KPX i m -26 +KPX i n -22 +KPX i o -35 +KPX i p -24 +KPX i q -29 +KPX i s -43 +KPX i x -28 +KPX i z -24 +KPX i period -51 +KPX i comma -54 +KPX i colon -30 +KPX i semicolon -30 +KPX i hyphen -41 +KPX j a -35 +KPX j b -31 +KPX j c -23 +KPX j e -26 +KPX j g -22 +KPX j h -29 +KPX j j -34 +KPX j k -23 +KPX j n -29 +KPX j o -24 +KPX j p -20 +KPX j r -20 +KPX j s -32 +KPX j x -42 +KPX j z -29 +KPX j period -44 +KPX j comma -48 +KPX j hyphen -26 +KPX k a -71 +KPX k b -32 +KPX k c -38 +KPX k e -28 +KPX k f -31 +KPX k g -42 +KPX k h -45 +KPX k j -72 +KPX k k -22 +KPX k l -28 +KPX k m -26 +KPX k n -22 +KPX k o -46 +KPX k p -22 +KPX k q -32 +KPX k s -73 +KPX k x -27 +KPX k z -25 +KPX k period -72 +KPX k comma -73 +KPX k colon -25 +KPX k semicolon -25 +KPX k hyphen -74 +KPX l t -56 +KPX l v -24 +KPX l y -59 +KPX l quoteright -50 +KPX l quotedblright -50 +KPX m a -26 +KPX m j -25 +KPX m s -22 +KPX m x -28 +KPX m period -29 +KPX m comma -32 +KPX m hyphen -21 +KPX n a -32 +KPX n b -32 +KPX n c -28 +KPX n d -22 +KPX n e -30 +KPX n f -24 +KPX n g -28 +KPX n h -31 +KPX n j -31 +KPX n k -26 +KPX n l -23 +KPX n m -23 +KPX n n -28 +KPX n o -28 +KPX n p -25 +KPX n q -25 +KPX n s -30 +KPX n x -38 +KPX n z -29 +KPX n period -35 +KPX n comma -38 +KPX n hyphen -27 +KPX o x -33 +KPX o period -41 +KPX o comma -47 +KPX p a -60 +KPX p b -33 +KPX p c -33 +KPX p d -22 +KPX p e -35 +KPX p f -27 +KPX p g -32 +KPX p h -40 +KPX p j -60 +KPX p k -24 +KPX p l -27 +KPX p m -27 +KPX p n -25 +KPX p o -36 +KPX p p -27 +KPX p q -28 +KPX p s -72 +KPX p x -34 +KPX p z -26 +KPX p period -175 +KPX p comma -175 +KPX p colon -25 +KPX p semicolon -25 +KPX p hyphen -50 +KPX q a -22 +KPX q j -23 +KPX q s -23 +KPX q x -34 +KPX q period -34 +KPX q comma -34 +KPX r a -36 +KPX r j -36 +KPX r s -42 +KPX r x -23 +KPX r period -47 +KPX r comma -49 +KPX r hyphen -33 +KPX s a -54 +KPX s b -28 +KPX s c -43 +KPX s e -21 +KPX s f -28 +KPX s g -48 +KPX s h -40 +KPX s j -53 +KPX s l -21 +KPX s o -51 +KPX s q -36 +KPX s s -51 +KPX s x -21 +KPX s z -21 +KPX s period -60 +KPX s comma -63 +KPX s hyphen -50 +KPX t a -81 +KPX t b -28 +KPX t c -56 +KPX t e -23 +KPX t f -29 +KPX t g -54 +KPX t h -40 +KPX t j -80 +KPX t l -23 +KPX t m -21 +KPX t o -57 +KPX t q -38 +KPX t s -89 +KPX t x -23 +KPX t z -22 +KPX t period -158 +KPX t comma -159 +KPX t hyphen -71 +KPX u x -25 +KPX u comma -24 +KPX v a -62 +KPX v b -28 +KPX v c -38 +KPX v e -23 +KPX v f -29 +KPX v g -36 +KPX v h -41 +KPX v j -62 +KPX v l -25 +KPX v o -38 +KPX v q -33 +KPX v s -67 +KPX v x -23 +KPX v z -22 +KPX v period -93 +KPX v comma -97 +KPX v hyphen -47 +KPX w a -30 +KPX w b -30 +KPX w c -26 +KPX w e -27 +KPX w f -23 +KPX w g -25 +KPX w h -28 +KPX w j -29 +KPX w k -22 +KPX w l -23 +KPX w m -23 +KPX w n -22 +KPX w o -26 +KPX w p -21 +KPX w q -24 +KPX w s -27 +KPX w x -25 +KPX w z -25 +KPX w period -41 +KPX w comma -47 +KPX w colon -25 +KPX w semicolon -24 +KPX w hyphen -25 +KPX x g -22 +KPX x o -25 +KPX x hyphen -46 +KPX y a -72 +KPX y b -28 +KPX y c -46 +KPX y e -24 +KPX y f -29 +KPX y g -44 +KPX y h -40 +KPX y j -71 +KPX y l -24 +KPX y m -21 +KPX y o -48 +KPX y q -40 +KPX y s -88 +KPX y x -24 +KPX y z -22 +KPX y period -154 +KPX y comma -154 +KPX y colon -20 +KPX y semicolon -20 +KPX y hyphen -68 +KPX z a -43 +KPX z b -28 +KPX z c -44 +KPX z e -21 +KPX z f -24 +KPX z g -44 +KPX z h -40 +KPX z j -43 +KPX z l -20 +KPX z o -50 +KPX z q -35 +KPX z s -43 +KPX z x -20 +KPX z z -21 +KPX z period -44 +KPX z comma -44 +KPX z hyphen -47 +KPX quoteleft a -50 +KPX quoteleft j -50 +KPX quoteleft A -50 +KPX quoteleft J -50 +KPX quoteleft c -30 +KPX quoteleft g -30 +KPX quoteleft o -30 +KPX quoteleft q -30 +KPX quoteleft s -30 +KPX quoteleft C -30 +KPX quoteleft G -30 +KPX quoteleft O -30 +KPX quoteleft Q -30 +KPX quoteleft S -30 +KPX quotedblleft a -50 +KPX quotedblleft j -50 +KPX quotedblleft A -50 +KPX quotedblleft J -50 +KPX quotedblleft c -30 +KPX quotedblleft g -30 +KPX quotedblleft o -30 +KPX quotedblleft q -30 +KPX quotedblleft s -30 +KPX quotedblleft C -30 +KPX quotedblleft G -30 +KPX quotedblleft O -30 +KPX quotedblleft Q -30 +KPX quotedblleft S -30 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeielogos-contour.afm b/fonts/afm/hoekwater/koeieletters/koeielogos-contour.afm new file mode 100644 index 000000000..78aa803e3 --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeielogos-contour.afm @@ -0,0 +1,47 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 13:58:23 2006 +FontName koeielogos-contour +FullName koeielogos-contour +FamilyName koeielogos-contour +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox 25 -199 4833 813 +StartCharMetrics 29 +C 0 ; WX 4858 ; N P_r_a_g_m_a_A_d_e ; B 25 -48 4833 708 ; +C 1 ; WX 4382 ; N p_r_a_g_m_a_a_d_e ; B 25 -64 4357 548 ; +C 2 ; WX 3411 ; N c_o_n_t_e_x_t ; B 25 -53 3386 618 ; +C 3 ; WX 3411 ; N contextlogo ; B 25 -28 3386 765 ; +C 4 ; WX 3411 ; N contextlogo.shadow ; B 183 -28 3074 24 ; +C 5 ; WX 3411 ; N contextlogo.contour ; B 28 98 3383 762 ; +C 6 ; WX 3411 ; N contextlogo.skeleton ; B 25 94 3387 765 ; +C 7 ; WX 3411 ; N contextlogo.dots ; B 42 414 3096 714 ; +C 8 ; WX 1108 ; N M_P ; B 25 -34 1083 599 ; +C 9 ; WX 1108 ; N mplogo ; B 25 -27 1083 677 ; +C 10 ; WX 1167 ; N T_e_X ; B 25 -199 1142 571 ; +C 11 ; WX 1167 ; N texlogo ; B 25 -27 1142 813 ; +C 12 ; WX 1640 ; N boo ; B 25 69 1615 422 ; +C 13 ; WX 1642 ; N cow ; B 25 60 1617 420 ; +C 14 ; WX 3302 ; N examplelogo ; B 25 -29 3277 717 ; +C 15 ; WX 2584 ; N foxetlogo ; B 25 -28 2559 740 ; +C 16 ; WX 2727 ; N m_e_t_a_f_u_n ; B 25 -51 2703 584 ; +C 17 ; WX 2727 ; N metafunlogo ; B 25 -28 2703 700 ; +C 18 ; WX 1386 ; N texlogo.alt ; B 25 -26 1361 745 ; +C 19 ; WX 1811 ; N wikilogo ; B 25 -27 1786 702 ; +C 20 ; WX 4858 ; N PragmaADElogo ; B 25 -34 4833 808 ; +C 21 ; WX 4382 ; N pragmaadelogo ; B 25 -28 4357 648 ; +C 22 ; WX 3302 ; N E_x_a_m_p_l_e ; B 25 -60 3277 592 ; +C 23 ; WX 2584 ; N F_o_X_e_t ; B 25 -42 2559 580 ; +C 24 ; WX 1386 ; N T_E_X ; B 25 -34 1361 625 ; +C 25 ; WX 1811 ; N W_i_k_i ; B 25 -25 1786 582 ; +C 26 ; WX 3459 ; N cowtextlogo ; B 25 -28 3434 765 ; +C 27 ; WX 3459 ; N C_o_w_t_e_x_t ; B 25 -23 3434 620 ; +C -1 ; WX 500 ; N space ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeielogos.afm b/fonts/afm/hoekwater/koeieletters/koeielogos.afm new file mode 100644 index 000000000..6b11b3aa3 --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeielogos.afm @@ -0,0 +1,47 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 13:47:15 2006 +FontName koeielogos +FullName koeielogos +FamilyName koeielogos +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox 25 -199 4833 813 +StartCharMetrics 29 +C 0 ; WX 4858 ; N P_r_a_g_m_a_A_d_e ; B 25 -48 4833 708 ; +C 1 ; WX 4382 ; N p_r_a_g_m_a_a_d_e ; B 25 -64 4357 548 ; +C 2 ; WX 3411 ; N c_o_n_t_e_x_t ; B 25 -53 3386 618 ; +C 3 ; WX 3411 ; N contextlogo ; B 25 -28 3386 765 ; +C 4 ; WX 3411 ; N contextlogo.shadow ; B 183 -28 3074 24 ; +C 5 ; WX 3411 ; N contextlogo.contour ; B 28 98 3383 762 ; +C 6 ; WX 3411 ; N contextlogo.skeleton ; B 25 94 3387 765 ; +C 7 ; WX 3411 ; N contextlogo.dots ; B 42 414 3096 714 ; +C 8 ; WX 1108 ; N M_P ; B 25 -34 1083 599 ; +C 9 ; WX 1108 ; N mplogo ; B 25 -27 1083 677 ; +C 10 ; WX 1167 ; N T_e_X ; B 25 -199 1142 571 ; +C 11 ; WX 1167 ; N texlogo ; B 25 -27 1142 813 ; +C 12 ; WX 1640 ; N boo ; B 25 69 1615 422 ; +C 13 ; WX 1642 ; N cow ; B 25 60 1617 420 ; +C 14 ; WX 3302 ; N examplelogo ; B 25 -29 3277 717 ; +C 15 ; WX 2584 ; N foxetlogo ; B 25 -28 2559 740 ; +C 16 ; WX 2727 ; N m_e_t_a_f_u_n ; B 25 -51 2703 584 ; +C 17 ; WX 2727 ; N metafunlogo ; B 25 -28 2703 700 ; +C 18 ; WX 1386 ; N texlogo.alt ; B 25 -26 1361 745 ; +C 19 ; WX 1811 ; N wikilogo ; B 25 -27 1786 702 ; +C 20 ; WX 4858 ; N PragmaADElogo ; B 25 -34 4833 808 ; +C 21 ; WX 4382 ; N pragmaadelogo ; B 25 -28 4357 648 ; +C 22 ; WX 3302 ; N E_x_a_m_p_l_e ; B 25 -60 3277 592 ; +C 23 ; WX 2584 ; N F_o_X_e_t ; B 25 -42 2559 580 ; +C 24 ; WX 1386 ; N T_E_X ; B 25 -34 1361 625 ; +C 25 ; WX 1811 ; N W_i_k_i ; B 25 -25 1786 582 ; +C 26 ; WX 3459 ; N cowtextlogo ; B 25 -28 3434 765 ; +C 27 ; WX 3459 ; N C_o_w_t_e_x_t ; B 25 -23 3434 620 ; +C -1 ; WX 500 ; N space ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeien-ex.afm b/fonts/afm/hoekwater/koeieletters/koeien-ex.afm new file mode 100644 index 000000000..3827ec33c --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeien-ex.afm @@ -0,0 +1,879 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 13:49:26 2006 +FontName koeieletters +FullName koeieletters +FamilyName koeieletters +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox -12 -2066 1146 821 +CapHeight 636 +XHeight 540 +Ascender 533 +StartCharMetrics 187 +C 0 ; WX 321 ; N parenleft.big ; B 25 -1001 295 39 ; +C 1 ; WX 323 ; N parenright.big ; B 25 -999 298 42 ; +C 2 ; WX 585 ; N slash.big ; B 25 -825 560 39 ; +C 3 ; WX 382 ; N bracketleft.big ; B 25 -988 357 52 ; +C 4 ; WX 502 ; N backslash.big ; B 25 -820 477 44 ; +C 5 ; WX 376 ; N bracketright.big ; B 25 -990 351 50 ; +C 6 ; WX 332 ; N braceleft.big ; B 25 -1008 307 52 ; +C 7 ; WX 243 ; N bar.big ; B 25 -982 218 49 ; +C 8 ; WX 323 ; N braceright.big ; B 24 -1013 298 61 ; +C 9 ; WX 656 ; N integral.big ; B 25 -1159 631 0 ; +C 10 ; WX 1014 ; N summation.big ; B 29 -1049 988 0 ; +C 11 ; WX 701 ; N radical.big ; B 25 -892 709 74 ; +C 12 ; WX 743 ; N radical.bigg ; B 25 -1267 751 74 ; +C 13 ; WX 731 ; N radical.Bigg ; B 25 -1666 739 74 ; +C 14 ; WX 664 ; N radical.BIGG ; B 25 -2066 672 74 ; +C 15 ; WX 122 ; N radical.end ; B -8 0 122 74 ; +C 16 ; WX 8 ; N radical.extender ; B -12 0 21 74 ; +C 17 ; WX 644 ; N radical.alt ; B 25 -717 652 74 ; +C 18 ; WX 613 ; N integral.alt ; B 25 -809 588 0 ; +C 19 ; WX 814 ; N summation.alt ; B 25 -699 788 0 ; +C 20 ; WX 321 ; N parenleft.bigg ; B 25 -1351 295 39 ; +C 21 ; WX 323 ; N parenright.bigg ; B 25 -1349 298 42 ; +C 22 ; WX 714 ; N slash.bigg ; B 25 -1175 689 39 ; +C 23 ; WX 382 ; N bracketleft.bigg ; B 25 -1338 357 52 ; +C 24 ; WX 596 ; N backslash.bigg ; B 25 -1170 571 44 ; +C 25 ; WX 376 ; N bracketright.bigg ; B 25 -1340 351 50 ; +C 26 ; WX 332 ; N braceleft.bigg ; B 25 -1358 307 52 ; +C 27 ; WX 243 ; N bar.bigg ; B 25 -1332 218 49 ; +C 28 ; WX 323 ; N braceright.bigg ; B 24 -1363 298 61 ; +C 29 ; WX 195 ; N bar.begin ; B 0 0 203 74 ; +C 32 ; WX 500 ; N space ; B 0 0 0 0 ; +C 33 ; WX 345 ; N exclam ; B 25 0 319 530 ; +C 34 ; WX 460 ; N quotedbl ; B 25 338 435 544 ; +C 39 ; WX 239 ; N quotesingle ; B 25 338 214 544 ; +C 40 ; WX 321 ; N parenleft ; B 25 -64 295 651 ; +C 41 ; WX 323 ; N parenright ; B 25 -65 298 651 ; +C 42 ; WX 414 ; N asterisk ; B 25 32 389 404 ; +C 43 ; WX 461 ; N plus ; B 25 44 436 404 ; +C 44 ; WX 232 ; N comma ; B 25 -66 207 140 ; +C 45 ; WX 355 ; N hyphen ; B 25 176 330 294 ; +C 46 ; WX 231 ; N period ; B 25 0 206 151 ; +C 47 ; WX 539 ; N slash ; B 25 0 513 514 ; +C 48 ; WX 499 ; N zero ; B 25 0 474 526 ; +C 49 ; WX 488 ; N one ; B 25 0 463 530 ; +C 50 ; WX 539 ; N two ; B 25 0 513 528 ; +C 51 ; WX 501 ; N three ; B 25 0 476 517 ; +C 52 ; WX 514 ; N four ; B 25 0 489 510 ; +C 53 ; WX 521 ; N five ; B 25 0 494 515 ; +C 54 ; WX 513 ; N six ; B 25 0 489 514 ; +C 55 ; WX 540 ; N seven ; B 25 -1 514 526 ; +C 56 ; WX 498 ; N eight ; B 25 -1 474 511 ; +C 57 ; WX 495 ; N nine ; B 23 0 468 513 ; +C 58 ; WX 234 ; N colon ; B 25 52 209 460 ; +C 59 ; WX 245 ; N semicolon ; B 25 -10 219 461 ; +C 60 ; WX 544 ; N less ; B 25 81 519 456 ; +C 61 ; WX 460 ; N equal ; B 25 88 435 404 ; +C 62 ; WX 581 ; N greater ; B 25 66 556 448 ; +C 63 ; WX 518 ; N question ; B 25 -5 493 536 ; +C 64 ; WX 585 ; N at ; B 25 -4 560 479 ; +C 65 ; WX 676 ; N A ; B 30 -8 646 630 ; +C 66 ; WX 654 ; N B ; B 30 -8 622 631 ; +C 67 ; WX 729 ; N C ; B 30 0 679 640 ; +C 68 ; WX 674 ; N D ; B 30 0 643 626 ; +C 69 ; WX 676 ; N E ; B 30 0 645 634 ; +C 70 ; WX 686 ; N F ; B 30 -8 656 638 ; +C 71 ; WX 663 ; N G ; B 30 0 652 643 ; +C 72 ; WX 716 ; N H ; B 30 0 685 642 ; +C 73 ; WX 554 ; N I ; B 30 0 519 636 ; +C 74 ; WX 732 ; N J ; B 30 0 702 652 ; +C 75 ; WX 740 ; N K ; B 30 -4 689 637 ; +C 76 ; WX 626 ; N L ; B 30 -9 595 638 ; +C 77 ; WX 730 ; N M ; B 30 -8 699 631 ; +C 78 ; WX 708 ; N N ; B 30 -1 676 666 ; +C 79 ; WX 783 ; N O ; B 30 -6 704 653 ; +C 80 ; WX 722 ; N P ; B 30 -1 691 646 ; +C 81 ; WX 731 ; N Q ; B 30 0 699 642 ; +C 82 ; WX 703 ; N R ; B 30 -9 672 657 ; +C 83 ; WX 750 ; N S ; B 30 -8 711 648 ; +C 84 ; WX 758 ; N T ; B 30 -9 728 642 ; +C 85 ; WX 687 ; N U ; B 30 0 656 657 ; +C 86 ; WX 728 ; N V ; B 30 -6 692 627 ; +C 87 ; WX 712 ; N W ; B 30 -9 686 639 ; +C 88 ; WX 716 ; N X ; B 30 -6 684 646 ; +C 89 ; WX 726 ; N Y ; B 30 -26 693 642 ; +C 90 ; WX 685 ; N Z ; B 30 -19 651 632 ; +C 91 ; WX 382 ; N bracketleft ; B 25 -73 357 642 ; +C 92 ; WX 489 ; N backslash ; B 25 0 464 514 ; +C 93 ; WX 376 ; N bracketright ; B 25 -73 351 642 ; +C 94 ; WX 480 ; N asciicircum ; B 25 322 455 515 ; +C 95 ; WX 579 ; N underscore ; B 25 -183 554 -51 ; +C 96 ; WX 338 ; N grave ; B 25 570 312 762 ; +C 97 ; WX 565 ; N a ; B 25 -7 540 526 ; +C 98 ; WX 545 ; N b ; B 25 -8 520 526 ; +C 99 ; WX 593 ; N c ; B 25 0 566 535 ; +C 100 ; WX 562 ; N d ; B 25 0 537 523 ; +C 101 ; WX 564 ; N e ; B 25 0 539 530 ; +C 102 ; WX 572 ; N f ; B 25 -8 548 532 ; +C 103 ; WX 570 ; N g ; B 25 0 545 536 ; +C 104 ; WX 597 ; N h ; B 25 0 572 536 ; +C 105 ; WX 462 ; N i ; B 25 -1 434 531 ; +C 106 ; WX 610 ; N j ; B 25 -6 586 545 ; +C 107 ; WX 600 ; N k ; B 25 -5 575 531 ; +C 108 ; WX 522 ; N l ; B 25 -9 497 533 ; +C 109 ; WX 609 ; N m ; B 25 -8 584 528 ; +C 110 ; WX 590 ; N n ; B 25 -1 565 556 ; +C 111 ; WX 613 ; N o ; B 25 -5 588 546 ; +C 112 ; WX 602 ; N p ; B 25 -1 577 540 ; +C 113 ; WX 609 ; N q ; B 25 0 584 536 ; +C 114 ; WX 586 ; N r ; B 25 -8 561 549 ; +C 115 ; WX 625 ; N s ; B 25 -13 594 541 ; +C 116 ; WX 632 ; N t ; B 25 -8 608 536 ; +C 117 ; WX 573 ; N u ; B 25 0 548 549 ; +C 118 ; WX 607 ; N v ; B 25 -5 578 524 ; +C 119 ; WX 602 ; N w ; B 25 -8 573 534 ; +C 120 ; WX 597 ; N x ; B 25 -5 571 540 ; +C 121 ; WX 605 ; N y ; B 25 -28 579 536 ; +C 122 ; WX 571 ; N z ; B 25 -19 544 528 ; +C 123 ; WX 332 ; N braceleft ; B 25 -88 307 625 ; +C 124 ; WX 243 ; N bar ; B 25 0 218 681 ; +C 125 ; WX 323 ; N braceright ; B 24 -74 298 650 ; +C 126 ; WX 592 ; N asciitilde ; B 25 198 568 388 ; +C 156 ; WX 448 ; N dieresis ; B 25 557 423 711 ; +C 168 ; WX 336 ; N acute ; B 25 569 312 754 ; +C 203 ; WX 468 ; N multiply ; B 25 41 443 409 ; +C 244 ; WX 770 ; N infinity ; B 25 87 745 427 ; +C 245 ; WX 645 ; N arrowleft ; B 25 49 620 433 ; +C 246 ; WX 683 ; N arrowright ; B 25 53 658 433 ; +C 247 ; WX 460 ; N minus ; B 25 154 435 302 ; +C 248 ; WX 414 ; N asteriskmath ; B 25 32 389 404 ; +C 249 ; WX 613 ; N integral ; B 25 -155 588 654 ; +C 250 ; WX 814 ; N summation ; B 25 -116 788 583 ; +C 251 ; WX 614 ; N equivalence ; B 25 58 590 426 ; +C 252 ; WX 592 ; N similar ; B 23 198 568 388 ; +C 253 ; WX 224 ; N minute ; B 25 197 199 514 ; +C 254 ; WX 763 ; N emdash ; B 25 165 738 297 ; +C 255 ; WX 534 ; N endash ; B 25 165 509 297 ; +C -1 ; WX 512 ; N hungarumlaut ; B 50 581 487 778 ; +C -1 ; WX 460 ; N quotedblright ; B 25 358 435 564 ; +C -1 ; WX 256 ; N quoteright ; B 25 358 231 564 ; +C -1 ; WX 237 ; N quoteleft ; B 25 357 212 564 ; +C -1 ; WX 465 ; N breve ; B 25 611 440 799 ; +C -1 ; WX 451 ; N quotedblleft ; B 25 358 426 564 ; +C -1 ; WX 256 ; N quotesinglbase ; B 25 -58 231 148 ; +C -1 ; WX 460 ; N quotedblbase ; B 24 -65 435 141 ; +C -1 ; WX 378 ; N second ; B 25 197 353 514 ; +C -1 ; WX 530 ; N radical ; B 25 -62 1146 729 ; +C -1 ; WX 480 ; N circumflex ; B 25 561 455 754 ; +C -1 ; WX 521 ; N tilde ; B 25 564 495 728 ; +C -1 ; WX 462 ; N dotlessi ; B 25 -1 434 531 ; +C -1 ; WX 610 ; N dotlessj ; B 25 -6 586 545 ; +C -1 ; WX 496 ; N plus.alt ; B 25 62 470 464 ; +C -1 ; WX 481 ; N minus.alt ; B 25 174 457 356 ; +C -1 ; WX 552 ; N zero.alt ; B 25 -9 526 528 ; +C -1 ; WX 554 ; N one.alt ; B 25 -12 527 545 ; +C -1 ; WX 569 ; N two.alt ; B 25 -16 546 523 ; +C -1 ; WX 563 ; N three.alt ; B 25 -18 540 532 ; +C -1 ; WX 595 ; N four.alt ; B 25 -14 570 525 ; +C -1 ; WX 573 ; N five.alt ; B 25 -18 553 540 ; +C -1 ; WX 558 ; N six.alt ; B 25 -7 535 536 ; +C -1 ; WX 594 ; N seven.alt ; B 25 -4 568 525 ; +C -1 ; WX 544 ; N eight.alt ; B 25 -19 520 530 ; +C -1 ; WX 594 ; N nine.alt ; B 25 -19 568 536 ; +C -1 ; WX 231 ; N periodcentered ; B 25 153 206 304 ; +C -1 ; WX 231 ; N dotaccent ; B 25 611 206 762 ; +C -1 ; WX 321 ; N parenleft.top ; B 25 -500 278 39 ; +C -1 ; WX 323 ; N parenright.top ; B 25 -500 298 42 ; +C -1 ; WX 321 ; N parenleft.ex ; B 25 -504 223 8 ; +C -1 ; WX 323 ; N parenright.ex ; B 99 -504 298 8 ; +C -1 ; WX 321 ; N parenleft.bot ; B 25 -493 295 8 ; +C -1 ; WX 323 ; N parenright.bot ; B 35 -491 298 8 ; +C -1 ; WX 382 ; N bracketleft.top ; B 25 -500 357 52 ; +C -1 ; WX 376 ; N bracketright.top ; B 41 -500 351 50 ; +C -1 ; WX 382 ; N bracketleft.ex ; B 25 -504 271 8 ; +C -1 ; WX 376 ; N bracketright.ex ; B 116 -504 351 8 ; +C -1 ; WX 382 ; N bracketleft.bot ; B 25 -480 339 8 ; +C -1 ; WX 376 ; N bracketright.bot ; B 25 -482 351 8 ; +C -1 ; WX 465 ; N hacek ; B 25 611 440 821 ; +C -1 ; WX 534 ; N macron ; B 25 575 509 707 ; +C -1 ; WX 483 ; N ringaccent ; B 160 560 370 719 ; +C -1 ; WX 547 ; N arrowleft.lft ; B 25 49 555 433 ; +C -1 ; WX 369 ; N arrowright.lft ; B 25 176 377 316 ; +C -1 ; WX 137 ; N arrowleft.rt ; B -8 176 112 316 ; +C -1 ; WX 325 ; N arrowright.rt ; B -8 53 300 433 ; +C -1 ; WX 300 ; N arrow.mid ; B -8 176 308 316 ; +C -1 ; WX 476 ; N radical.bot ; B 25 -1666 413 8 ; +C -1 ; WX 476 ; N radical.top ; B 258 -208 484 74 ; +C -1 ; WX 476 ; N radical.mid ; B 258 -208 413 8 ; +EndCharMetrics +StartKernData +StartKernPairs 667 +KPX C a -31 +KPX C j -31 +KPX C s -30 +KPX C x -23 +KPX C period -35 +KPX C comma -38 +KPX C hyphen -44 +KPX D x -36 +KPX D period -32 +KPX D comma -40 +KPX E a -52 +KPX E b -29 +KPX E c -56 +KPX E e -27 +KPX E f -32 +KPX E g -66 +KPX E h -45 +KPX E j -52 +KPX E k -20 +KPX E l -26 +KPX E m -23 +KPX E n -21 +KPX E o -67 +KPX E p -20 +KPX E q -46 +KPX E s -59 +KPX E x -26 +KPX E z -23 +KPX E period -51 +KPX E comma -52 +KPX E colon -27 +KPX E semicolon -26 +KPX E hyphen -88 +KPX F a -86 +KPX F b -29 +KPX F c -47 +KPX F e -29 +KPX F f -35 +KPX F g -58 +KPX F h -45 +KPX F j -101 +KPX F k -20 +KPX F l -28 +KPX F m -26 +KPX F n -21 +KPX F o -61 +KPX F p -22 +KPX F q -43 +KPX F s -89 +KPX F x -27 +KPX F z -23 +KPX F period -166 +KPX F comma -166 +KPX F colon -30 +KPX F semicolon -30 +KPX F hyphen -115 +KPX G x -32 +KPX G z -24 +KPX G period -32 +KPX G comma -37 +KPX H x -31 +KPX H period -26 +KPX H comma -31 +KPX I a -46 +KPX I b -32 +KPX I c -34 +KPX I d -20 +KPX I e -31 +KPX I f -29 +KPX I g -30 +KPX I h -40 +KPX I j -45 +KPX I k -22 +KPX I l -28 +KPX I m -26 +KPX I n -22 +KPX I o -35 +KPX I p -24 +KPX I q -29 +KPX I s -43 +KPX I x -28 +KPX I z -24 +KPX I period -51 +KPX I comma -54 +KPX I colon -30 +KPX I semicolon -30 +KPX I hyphen -41 +KPX J a -35 +KPX J b -31 +KPX J c -23 +KPX J e -26 +KPX J g -22 +KPX J h -29 +KPX J j -34 +KPX J k -23 +KPX J n -29 +KPX J o -24 +KPX J p -20 +KPX J r -20 +KPX J s -32 +KPX J x -42 +KPX J z -29 +KPX J period -44 +KPX J comma -48 +KPX J hyphen -26 +KPX K a -70 +KPX K b -33 +KPX K c -38 +KPX K d -22 +KPX K e -33 +KPX K f -31 +KPX K g -41 +KPX K h -45 +KPX K j -73 +KPX K k -24 +KPX K l -30 +KPX K m -28 +KPX K n -24 +KPX K o -44 +KPX K p -25 +KPX K q -32 +KPX K s -74 +KPX K x -29 +KPX K z -27 +KPX K period -73 +KPX K comma -74 +KPX K colon -28 +KPX K semicolon -28 +KPX K hyphen -73 +KPX L t -56 +KPX L v -24 +KPX L y -59 +KPX L quoteright -50 +KPX L quotedblright -50 +KPX M a -26 +KPX M j -25 +KPX M s -22 +KPX M x -28 +KPX M period -29 +KPX M comma -32 +KPX M hyphen -21 +KPX N a -32 +KPX N b -32 +KPX N c -28 +KPX N d -22 +KPX N e -30 +KPX N f -24 +KPX N g -28 +KPX N h -31 +KPX N j -31 +KPX N k -26 +KPX N l -23 +KPX N m -23 +KPX N n -28 +KPX N o -28 +KPX N p -25 +KPX N q -25 +KPX N s -30 +KPX N x -38 +KPX N z -29 +KPX N period -35 +KPX N comma -38 +KPX N hyphen -27 +KPX O x -33 +KPX O period -41 +KPX O comma -47 +KPX P a -60 +KPX P b -33 +KPX P c -33 +KPX P d -22 +KPX P e -35 +KPX P f -27 +KPX P g -32 +KPX P h -40 +KPX P j -60 +KPX P k -24 +KPX P l -27 +KPX P m -27 +KPX P n -25 +KPX P o -36 +KPX P p -27 +KPX P q -28 +KPX P s -72 +KPX P x -34 +KPX P z -26 +KPX P period -175 +KPX P comma -175 +KPX P colon -25 +KPX P semicolon -25 +KPX P hyphen -50 +KPX Q a -22 +KPX Q j -23 +KPX Q s -23 +KPX Q x -34 +KPX Q period -34 +KPX Q comma -34 +KPX R a -36 +KPX R j -36 +KPX R s -42 +KPX R x -23 +KPX R period -47 +KPX R comma -49 +KPX R hyphen -33 +KPX S a -54 +KPX S b -28 +KPX S c -43 +KPX S e -21 +KPX S f -28 +KPX S g -48 +KPX S h -40 +KPX S j -53 +KPX S l -21 +KPX S o -51 +KPX S q -36 +KPX S s -51 +KPX S x -21 +KPX S z -21 +KPX S period -60 +KPX S comma -63 +KPX S hyphen -50 +KPX T a -81 +KPX T b -28 +KPX T c -56 +KPX T e -23 +KPX T f -29 +KPX T g -54 +KPX T h -40 +KPX T j -80 +KPX T l -23 +KPX T m -21 +KPX T o -57 +KPX T q -38 +KPX T s -89 +KPX T x -23 +KPX T z -22 +KPX T period -158 +KPX T comma -159 +KPX T hyphen -71 +KPX U x -25 +KPX U comma -24 +KPX V a -62 +KPX V b -28 +KPX V c -38 +KPX V e -23 +KPX V f -29 +KPX V g -36 +KPX V h -41 +KPX V j -62 +KPX V l -25 +KPX V o -38 +KPX V q -33 +KPX V s -67 +KPX V x -23 +KPX V z -22 +KPX V period -93 +KPX V comma -97 +KPX V hyphen -47 +KPX W a -30 +KPX W b -30 +KPX W c -26 +KPX W e -27 +KPX W f -23 +KPX W g -25 +KPX W h -28 +KPX W j -29 +KPX W k -22 +KPX W l -23 +KPX W m -23 +KPX W n -22 +KPX W o -26 +KPX W p -21 +KPX W q -24 +KPX W s -27 +KPX W x -25 +KPX W z -25 +KPX W period -41 +KPX W comma -47 +KPX W colon -25 +KPX W semicolon -24 +KPX W hyphen -25 +KPX X g -22 +KPX X o -25 +KPX X hyphen -46 +KPX Y a -72 +KPX Y b -28 +KPX Y c -46 +KPX Y e -24 +KPX Y f -29 +KPX Y g -44 +KPX Y h -40 +KPX Y j -71 +KPX Y l -24 +KPX Y m -21 +KPX Y o -48 +KPX Y q -40 +KPX Y s -88 +KPX Y x -24 +KPX Y z -22 +KPX Y period -154 +KPX Y comma -154 +KPX Y colon -20 +KPX Y semicolon -20 +KPX Y hyphen -68 +KPX Z a -43 +KPX Z b -28 +KPX Z c -44 +KPX Z e -21 +KPX Z f -24 +KPX Z g -44 +KPX Z h -40 +KPX Z j -43 +KPX Z l -20 +KPX Z o -50 +KPX Z q -35 +KPX Z s -43 +KPX Z x -20 +KPX Z z -21 +KPX Z period -44 +KPX Z comma -44 +KPX Z hyphen -47 +KPX c a -31 +KPX c j -31 +KPX c s -30 +KPX c x -23 +KPX c period -35 +KPX c comma -38 +KPX c hyphen -44 +KPX d x -36 +KPX d period -32 +KPX d comma -40 +KPX e a -52 +KPX e b -29 +KPX e c -56 +KPX e e -27 +KPX e f -32 +KPX e g -66 +KPX e h -45 +KPX e j -52 +KPX e k -20 +KPX e l -26 +KPX e m -23 +KPX e n -21 +KPX e o -67 +KPX e p -20 +KPX e q -46 +KPX e s -59 +KPX e x -26 +KPX e z -23 +KPX e period -51 +KPX e comma -52 +KPX e colon -27 +KPX e semicolon -26 +KPX e hyphen -88 +KPX f a -86 +KPX f b -29 +KPX f c -47 +KPX f e -29 +KPX f f -35 +KPX f g -58 +KPX f h -45 +KPX f j -101 +KPX f k -20 +KPX f l -28 +KPX f m -26 +KPX f n -21 +KPX f o -61 +KPX f p -22 +KPX f q -43 +KPX f s -89 +KPX f x -27 +KPX f z -23 +KPX f period -166 +KPX f comma -166 +KPX f colon -30 +KPX f semicolon -30 +KPX f hyphen -115 +KPX g x -32 +KPX g z -24 +KPX g period -32 +KPX g comma -37 +KPX h x -31 +KPX h period -26 +KPX h comma -31 +KPX i a -46 +KPX i b -32 +KPX i c -34 +KPX i d -20 +KPX i e -31 +KPX i f -29 +KPX i g -30 +KPX i h -40 +KPX i j -45 +KPX i k -22 +KPX i l -28 +KPX i m -26 +KPX i n -22 +KPX i o -35 +KPX i p -24 +KPX i q -29 +KPX i s -43 +KPX i x -28 +KPX i z -24 +KPX i period -51 +KPX i comma -54 +KPX i colon -30 +KPX i semicolon -30 +KPX i hyphen -41 +KPX j a -35 +KPX j b -31 +KPX j c -23 +KPX j e -26 +KPX j g -22 +KPX j h -29 +KPX j j -34 +KPX j k -23 +KPX j n -29 +KPX j o -24 +KPX j p -20 +KPX j r -20 +KPX j s -32 +KPX j x -42 +KPX j z -29 +KPX j period -44 +KPX j comma -48 +KPX j hyphen -26 +KPX k a -71 +KPX k b -32 +KPX k c -38 +KPX k e -28 +KPX k f -31 +KPX k g -42 +KPX k h -45 +KPX k j -72 +KPX k k -22 +KPX k l -28 +KPX k m -26 +KPX k n -22 +KPX k o -46 +KPX k p -22 +KPX k q -32 +KPX k s -73 +KPX k x -27 +KPX k z -25 +KPX k period -72 +KPX k comma -73 +KPX k colon -25 +KPX k semicolon -25 +KPX k hyphen -74 +KPX l t -56 +KPX l v -24 +KPX l y -59 +KPX l quoteright -50 +KPX l quotedblright -50 +KPX m a -26 +KPX m j -25 +KPX m s -22 +KPX m x -28 +KPX m period -29 +KPX m comma -32 +KPX m hyphen -21 +KPX n a -32 +KPX n b -32 +KPX n c -28 +KPX n d -22 +KPX n e -30 +KPX n f -24 +KPX n g -28 +KPX n h -31 +KPX n j -31 +KPX n k -26 +KPX n l -23 +KPX n m -23 +KPX n n -28 +KPX n o -28 +KPX n p -25 +KPX n q -25 +KPX n s -30 +KPX n x -38 +KPX n z -29 +KPX n period -35 +KPX n comma -38 +KPX n hyphen -27 +KPX o x -33 +KPX o period -41 +KPX o comma -47 +KPX p a -60 +KPX p b -33 +KPX p c -33 +KPX p d -22 +KPX p e -35 +KPX p f -27 +KPX p g -32 +KPX p h -40 +KPX p j -60 +KPX p k -24 +KPX p l -27 +KPX p m -27 +KPX p n -25 +KPX p o -36 +KPX p p -27 +KPX p q -28 +KPX p s -72 +KPX p x -34 +KPX p z -26 +KPX p period -175 +KPX p comma -175 +KPX p colon -25 +KPX p semicolon -25 +KPX p hyphen -50 +KPX q a -22 +KPX q j -23 +KPX q s -23 +KPX q x -34 +KPX q period -34 +KPX q comma -34 +KPX r a -36 +KPX r j -36 +KPX r s -42 +KPX r x -23 +KPX r period -47 +KPX r comma -49 +KPX r hyphen -33 +KPX s a -54 +KPX s b -28 +KPX s c -43 +KPX s e -21 +KPX s f -28 +KPX s g -48 +KPX s h -40 +KPX s j -53 +KPX s l -21 +KPX s o -51 +KPX s q -36 +KPX s s -51 +KPX s x -21 +KPX s z -21 +KPX s period -60 +KPX s comma -63 +KPX s hyphen -50 +KPX t a -81 +KPX t b -28 +KPX t c -56 +KPX t e -23 +KPX t f -29 +KPX t g -54 +KPX t h -40 +KPX t j -80 +KPX t l -23 +KPX t m -21 +KPX t o -57 +KPX t q -38 +KPX t s -89 +KPX t x -23 +KPX t z -22 +KPX t period -158 +KPX t comma -159 +KPX t hyphen -71 +KPX u x -25 +KPX u comma -24 +KPX v a -62 +KPX v b -28 +KPX v c -38 +KPX v e -23 +KPX v f -29 +KPX v g -36 +KPX v h -41 +KPX v j -62 +KPX v l -25 +KPX v o -38 +KPX v q -33 +KPX v s -67 +KPX v x -23 +KPX v z -22 +KPX v period -93 +KPX v comma -97 +KPX v hyphen -47 +KPX w a -30 +KPX w b -30 +KPX w c -26 +KPX w e -27 +KPX w f -23 +KPX w g -25 +KPX w h -28 +KPX w j -29 +KPX w k -22 +KPX w l -23 +KPX w m -23 +KPX w n -22 +KPX w o -26 +KPX w p -21 +KPX w q -24 +KPX w s -27 +KPX w x -25 +KPX w z -25 +KPX w period -41 +KPX w comma -47 +KPX w colon -25 +KPX w semicolon -24 +KPX w hyphen -25 +KPX x g -22 +KPX x o -25 +KPX x hyphen -46 +KPX y a -72 +KPX y b -28 +KPX y c -46 +KPX y e -24 +KPX y f -29 +KPX y g -44 +KPX y h -40 +KPX y j -71 +KPX y l -24 +KPX y m -21 +KPX y o -48 +KPX y q -40 +KPX y s -88 +KPX y x -24 +KPX y z -22 +KPX y period -154 +KPX y comma -154 +KPX y colon -20 +KPX y semicolon -20 +KPX y hyphen -68 +KPX z a -43 +KPX z b -28 +KPX z c -44 +KPX z e -21 +KPX z f -24 +KPX z g -44 +KPX z h -40 +KPX z j -43 +KPX z l -20 +KPX z o -50 +KPX z q -35 +KPX z s -43 +KPX z x -20 +KPX z z -21 +KPX z period -44 +KPX z comma -44 +KPX z hyphen -47 +KPX quoteleft a -50 +KPX quoteleft j -50 +KPX quoteleft A -50 +KPX quoteleft J -50 +KPX quoteleft c -30 +KPX quoteleft g -30 +KPX quoteleft o -30 +KPX quoteleft q -30 +KPX quoteleft s -30 +KPX quoteleft C -30 +KPX quoteleft G -30 +KPX quoteleft O -30 +KPX quoteleft Q -30 +KPX quoteleft S -30 +KPX quotedblleft a -50 +KPX quotedblleft j -50 +KPX quotedblleft A -50 +KPX quotedblleft J -50 +KPX quotedblleft c -30 +KPX quotedblleft g -30 +KPX quotedblleft o -30 +KPX quotedblleft q -30 +KPX quotedblleft s -30 +KPX quotedblleft C -30 +KPX quotedblleft G -30 +KPX quotedblleft O -30 +KPX quotedblleft Q -30 +KPX quotedblleft S -30 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeien-mi.afm b/fonts/afm/hoekwater/koeieletters/koeien-mi.afm new file mode 100644 index 000000000..3827ec33c --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeien-mi.afm @@ -0,0 +1,879 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 13:49:26 2006 +FontName koeieletters +FullName koeieletters +FamilyName koeieletters +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox -12 -2066 1146 821 +CapHeight 636 +XHeight 540 +Ascender 533 +StartCharMetrics 187 +C 0 ; WX 321 ; N parenleft.big ; B 25 -1001 295 39 ; +C 1 ; WX 323 ; N parenright.big ; B 25 -999 298 42 ; +C 2 ; WX 585 ; N slash.big ; B 25 -825 560 39 ; +C 3 ; WX 382 ; N bracketleft.big ; B 25 -988 357 52 ; +C 4 ; WX 502 ; N backslash.big ; B 25 -820 477 44 ; +C 5 ; WX 376 ; N bracketright.big ; B 25 -990 351 50 ; +C 6 ; WX 332 ; N braceleft.big ; B 25 -1008 307 52 ; +C 7 ; WX 243 ; N bar.big ; B 25 -982 218 49 ; +C 8 ; WX 323 ; N braceright.big ; B 24 -1013 298 61 ; +C 9 ; WX 656 ; N integral.big ; B 25 -1159 631 0 ; +C 10 ; WX 1014 ; N summation.big ; B 29 -1049 988 0 ; +C 11 ; WX 701 ; N radical.big ; B 25 -892 709 74 ; +C 12 ; WX 743 ; N radical.bigg ; B 25 -1267 751 74 ; +C 13 ; WX 731 ; N radical.Bigg ; B 25 -1666 739 74 ; +C 14 ; WX 664 ; N radical.BIGG ; B 25 -2066 672 74 ; +C 15 ; WX 122 ; N radical.end ; B -8 0 122 74 ; +C 16 ; WX 8 ; N radical.extender ; B -12 0 21 74 ; +C 17 ; WX 644 ; N radical.alt ; B 25 -717 652 74 ; +C 18 ; WX 613 ; N integral.alt ; B 25 -809 588 0 ; +C 19 ; WX 814 ; N summation.alt ; B 25 -699 788 0 ; +C 20 ; WX 321 ; N parenleft.bigg ; B 25 -1351 295 39 ; +C 21 ; WX 323 ; N parenright.bigg ; B 25 -1349 298 42 ; +C 22 ; WX 714 ; N slash.bigg ; B 25 -1175 689 39 ; +C 23 ; WX 382 ; N bracketleft.bigg ; B 25 -1338 357 52 ; +C 24 ; WX 596 ; N backslash.bigg ; B 25 -1170 571 44 ; +C 25 ; WX 376 ; N bracketright.bigg ; B 25 -1340 351 50 ; +C 26 ; WX 332 ; N braceleft.bigg ; B 25 -1358 307 52 ; +C 27 ; WX 243 ; N bar.bigg ; B 25 -1332 218 49 ; +C 28 ; WX 323 ; N braceright.bigg ; B 24 -1363 298 61 ; +C 29 ; WX 195 ; N bar.begin ; B 0 0 203 74 ; +C 32 ; WX 500 ; N space ; B 0 0 0 0 ; +C 33 ; WX 345 ; N exclam ; B 25 0 319 530 ; +C 34 ; WX 460 ; N quotedbl ; B 25 338 435 544 ; +C 39 ; WX 239 ; N quotesingle ; B 25 338 214 544 ; +C 40 ; WX 321 ; N parenleft ; B 25 -64 295 651 ; +C 41 ; WX 323 ; N parenright ; B 25 -65 298 651 ; +C 42 ; WX 414 ; N asterisk ; B 25 32 389 404 ; +C 43 ; WX 461 ; N plus ; B 25 44 436 404 ; +C 44 ; WX 232 ; N comma ; B 25 -66 207 140 ; +C 45 ; WX 355 ; N hyphen ; B 25 176 330 294 ; +C 46 ; WX 231 ; N period ; B 25 0 206 151 ; +C 47 ; WX 539 ; N slash ; B 25 0 513 514 ; +C 48 ; WX 499 ; N zero ; B 25 0 474 526 ; +C 49 ; WX 488 ; N one ; B 25 0 463 530 ; +C 50 ; WX 539 ; N two ; B 25 0 513 528 ; +C 51 ; WX 501 ; N three ; B 25 0 476 517 ; +C 52 ; WX 514 ; N four ; B 25 0 489 510 ; +C 53 ; WX 521 ; N five ; B 25 0 494 515 ; +C 54 ; WX 513 ; N six ; B 25 0 489 514 ; +C 55 ; WX 540 ; N seven ; B 25 -1 514 526 ; +C 56 ; WX 498 ; N eight ; B 25 -1 474 511 ; +C 57 ; WX 495 ; N nine ; B 23 0 468 513 ; +C 58 ; WX 234 ; N colon ; B 25 52 209 460 ; +C 59 ; WX 245 ; N semicolon ; B 25 -10 219 461 ; +C 60 ; WX 544 ; N less ; B 25 81 519 456 ; +C 61 ; WX 460 ; N equal ; B 25 88 435 404 ; +C 62 ; WX 581 ; N greater ; B 25 66 556 448 ; +C 63 ; WX 518 ; N question ; B 25 -5 493 536 ; +C 64 ; WX 585 ; N at ; B 25 -4 560 479 ; +C 65 ; WX 676 ; N A ; B 30 -8 646 630 ; +C 66 ; WX 654 ; N B ; B 30 -8 622 631 ; +C 67 ; WX 729 ; N C ; B 30 0 679 640 ; +C 68 ; WX 674 ; N D ; B 30 0 643 626 ; +C 69 ; WX 676 ; N E ; B 30 0 645 634 ; +C 70 ; WX 686 ; N F ; B 30 -8 656 638 ; +C 71 ; WX 663 ; N G ; B 30 0 652 643 ; +C 72 ; WX 716 ; N H ; B 30 0 685 642 ; +C 73 ; WX 554 ; N I ; B 30 0 519 636 ; +C 74 ; WX 732 ; N J ; B 30 0 702 652 ; +C 75 ; WX 740 ; N K ; B 30 -4 689 637 ; +C 76 ; WX 626 ; N L ; B 30 -9 595 638 ; +C 77 ; WX 730 ; N M ; B 30 -8 699 631 ; +C 78 ; WX 708 ; N N ; B 30 -1 676 666 ; +C 79 ; WX 783 ; N O ; B 30 -6 704 653 ; +C 80 ; WX 722 ; N P ; B 30 -1 691 646 ; +C 81 ; WX 731 ; N Q ; B 30 0 699 642 ; +C 82 ; WX 703 ; N R ; B 30 -9 672 657 ; +C 83 ; WX 750 ; N S ; B 30 -8 711 648 ; +C 84 ; WX 758 ; N T ; B 30 -9 728 642 ; +C 85 ; WX 687 ; N U ; B 30 0 656 657 ; +C 86 ; WX 728 ; N V ; B 30 -6 692 627 ; +C 87 ; WX 712 ; N W ; B 30 -9 686 639 ; +C 88 ; WX 716 ; N X ; B 30 -6 684 646 ; +C 89 ; WX 726 ; N Y ; B 30 -26 693 642 ; +C 90 ; WX 685 ; N Z ; B 30 -19 651 632 ; +C 91 ; WX 382 ; N bracketleft ; B 25 -73 357 642 ; +C 92 ; WX 489 ; N backslash ; B 25 0 464 514 ; +C 93 ; WX 376 ; N bracketright ; B 25 -73 351 642 ; +C 94 ; WX 480 ; N asciicircum ; B 25 322 455 515 ; +C 95 ; WX 579 ; N underscore ; B 25 -183 554 -51 ; +C 96 ; WX 338 ; N grave ; B 25 570 312 762 ; +C 97 ; WX 565 ; N a ; B 25 -7 540 526 ; +C 98 ; WX 545 ; N b ; B 25 -8 520 526 ; +C 99 ; WX 593 ; N c ; B 25 0 566 535 ; +C 100 ; WX 562 ; N d ; B 25 0 537 523 ; +C 101 ; WX 564 ; N e ; B 25 0 539 530 ; +C 102 ; WX 572 ; N f ; B 25 -8 548 532 ; +C 103 ; WX 570 ; N g ; B 25 0 545 536 ; +C 104 ; WX 597 ; N h ; B 25 0 572 536 ; +C 105 ; WX 462 ; N i ; B 25 -1 434 531 ; +C 106 ; WX 610 ; N j ; B 25 -6 586 545 ; +C 107 ; WX 600 ; N k ; B 25 -5 575 531 ; +C 108 ; WX 522 ; N l ; B 25 -9 497 533 ; +C 109 ; WX 609 ; N m ; B 25 -8 584 528 ; +C 110 ; WX 590 ; N n ; B 25 -1 565 556 ; +C 111 ; WX 613 ; N o ; B 25 -5 588 546 ; +C 112 ; WX 602 ; N p ; B 25 -1 577 540 ; +C 113 ; WX 609 ; N q ; B 25 0 584 536 ; +C 114 ; WX 586 ; N r ; B 25 -8 561 549 ; +C 115 ; WX 625 ; N s ; B 25 -13 594 541 ; +C 116 ; WX 632 ; N t ; B 25 -8 608 536 ; +C 117 ; WX 573 ; N u ; B 25 0 548 549 ; +C 118 ; WX 607 ; N v ; B 25 -5 578 524 ; +C 119 ; WX 602 ; N w ; B 25 -8 573 534 ; +C 120 ; WX 597 ; N x ; B 25 -5 571 540 ; +C 121 ; WX 605 ; N y ; B 25 -28 579 536 ; +C 122 ; WX 571 ; N z ; B 25 -19 544 528 ; +C 123 ; WX 332 ; N braceleft ; B 25 -88 307 625 ; +C 124 ; WX 243 ; N bar ; B 25 0 218 681 ; +C 125 ; WX 323 ; N braceright ; B 24 -74 298 650 ; +C 126 ; WX 592 ; N asciitilde ; B 25 198 568 388 ; +C 156 ; WX 448 ; N dieresis ; B 25 557 423 711 ; +C 168 ; WX 336 ; N acute ; B 25 569 312 754 ; +C 203 ; WX 468 ; N multiply ; B 25 41 443 409 ; +C 244 ; WX 770 ; N infinity ; B 25 87 745 427 ; +C 245 ; WX 645 ; N arrowleft ; B 25 49 620 433 ; +C 246 ; WX 683 ; N arrowright ; B 25 53 658 433 ; +C 247 ; WX 460 ; N minus ; B 25 154 435 302 ; +C 248 ; WX 414 ; N asteriskmath ; B 25 32 389 404 ; +C 249 ; WX 613 ; N integral ; B 25 -155 588 654 ; +C 250 ; WX 814 ; N summation ; B 25 -116 788 583 ; +C 251 ; WX 614 ; N equivalence ; B 25 58 590 426 ; +C 252 ; WX 592 ; N similar ; B 23 198 568 388 ; +C 253 ; WX 224 ; N minute ; B 25 197 199 514 ; +C 254 ; WX 763 ; N emdash ; B 25 165 738 297 ; +C 255 ; WX 534 ; N endash ; B 25 165 509 297 ; +C -1 ; WX 512 ; N hungarumlaut ; B 50 581 487 778 ; +C -1 ; WX 460 ; N quotedblright ; B 25 358 435 564 ; +C -1 ; WX 256 ; N quoteright ; B 25 358 231 564 ; +C -1 ; WX 237 ; N quoteleft ; B 25 357 212 564 ; +C -1 ; WX 465 ; N breve ; B 25 611 440 799 ; +C -1 ; WX 451 ; N quotedblleft ; B 25 358 426 564 ; +C -1 ; WX 256 ; N quotesinglbase ; B 25 -58 231 148 ; +C -1 ; WX 460 ; N quotedblbase ; B 24 -65 435 141 ; +C -1 ; WX 378 ; N second ; B 25 197 353 514 ; +C -1 ; WX 530 ; N radical ; B 25 -62 1146 729 ; +C -1 ; WX 480 ; N circumflex ; B 25 561 455 754 ; +C -1 ; WX 521 ; N tilde ; B 25 564 495 728 ; +C -1 ; WX 462 ; N dotlessi ; B 25 -1 434 531 ; +C -1 ; WX 610 ; N dotlessj ; B 25 -6 586 545 ; +C -1 ; WX 496 ; N plus.alt ; B 25 62 470 464 ; +C -1 ; WX 481 ; N minus.alt ; B 25 174 457 356 ; +C -1 ; WX 552 ; N zero.alt ; B 25 -9 526 528 ; +C -1 ; WX 554 ; N one.alt ; B 25 -12 527 545 ; +C -1 ; WX 569 ; N two.alt ; B 25 -16 546 523 ; +C -1 ; WX 563 ; N three.alt ; B 25 -18 540 532 ; +C -1 ; WX 595 ; N four.alt ; B 25 -14 570 525 ; +C -1 ; WX 573 ; N five.alt ; B 25 -18 553 540 ; +C -1 ; WX 558 ; N six.alt ; B 25 -7 535 536 ; +C -1 ; WX 594 ; N seven.alt ; B 25 -4 568 525 ; +C -1 ; WX 544 ; N eight.alt ; B 25 -19 520 530 ; +C -1 ; WX 594 ; N nine.alt ; B 25 -19 568 536 ; +C -1 ; WX 231 ; N periodcentered ; B 25 153 206 304 ; +C -1 ; WX 231 ; N dotaccent ; B 25 611 206 762 ; +C -1 ; WX 321 ; N parenleft.top ; B 25 -500 278 39 ; +C -1 ; WX 323 ; N parenright.top ; B 25 -500 298 42 ; +C -1 ; WX 321 ; N parenleft.ex ; B 25 -504 223 8 ; +C -1 ; WX 323 ; N parenright.ex ; B 99 -504 298 8 ; +C -1 ; WX 321 ; N parenleft.bot ; B 25 -493 295 8 ; +C -1 ; WX 323 ; N parenright.bot ; B 35 -491 298 8 ; +C -1 ; WX 382 ; N bracketleft.top ; B 25 -500 357 52 ; +C -1 ; WX 376 ; N bracketright.top ; B 41 -500 351 50 ; +C -1 ; WX 382 ; N bracketleft.ex ; B 25 -504 271 8 ; +C -1 ; WX 376 ; N bracketright.ex ; B 116 -504 351 8 ; +C -1 ; WX 382 ; N bracketleft.bot ; B 25 -480 339 8 ; +C -1 ; WX 376 ; N bracketright.bot ; B 25 -482 351 8 ; +C -1 ; WX 465 ; N hacek ; B 25 611 440 821 ; +C -1 ; WX 534 ; N macron ; B 25 575 509 707 ; +C -1 ; WX 483 ; N ringaccent ; B 160 560 370 719 ; +C -1 ; WX 547 ; N arrowleft.lft ; B 25 49 555 433 ; +C -1 ; WX 369 ; N arrowright.lft ; B 25 176 377 316 ; +C -1 ; WX 137 ; N arrowleft.rt ; B -8 176 112 316 ; +C -1 ; WX 325 ; N arrowright.rt ; B -8 53 300 433 ; +C -1 ; WX 300 ; N arrow.mid ; B -8 176 308 316 ; +C -1 ; WX 476 ; N radical.bot ; B 25 -1666 413 8 ; +C -1 ; WX 476 ; N radical.top ; B 258 -208 484 74 ; +C -1 ; WX 476 ; N radical.mid ; B 258 -208 413 8 ; +EndCharMetrics +StartKernData +StartKernPairs 667 +KPX C a -31 +KPX C j -31 +KPX C s -30 +KPX C x -23 +KPX C period -35 +KPX C comma -38 +KPX C hyphen -44 +KPX D x -36 +KPX D period -32 +KPX D comma -40 +KPX E a -52 +KPX E b -29 +KPX E c -56 +KPX E e -27 +KPX E f -32 +KPX E g -66 +KPX E h -45 +KPX E j -52 +KPX E k -20 +KPX E l -26 +KPX E m -23 +KPX E n -21 +KPX E o -67 +KPX E p -20 +KPX E q -46 +KPX E s -59 +KPX E x -26 +KPX E z -23 +KPX E period -51 +KPX E comma -52 +KPX E colon -27 +KPX E semicolon -26 +KPX E hyphen -88 +KPX F a -86 +KPX F b -29 +KPX F c -47 +KPX F e -29 +KPX F f -35 +KPX F g -58 +KPX F h -45 +KPX F j -101 +KPX F k -20 +KPX F l -28 +KPX F m -26 +KPX F n -21 +KPX F o -61 +KPX F p -22 +KPX F q -43 +KPX F s -89 +KPX F x -27 +KPX F z -23 +KPX F period -166 +KPX F comma -166 +KPX F colon -30 +KPX F semicolon -30 +KPX F hyphen -115 +KPX G x -32 +KPX G z -24 +KPX G period -32 +KPX G comma -37 +KPX H x -31 +KPX H period -26 +KPX H comma -31 +KPX I a -46 +KPX I b -32 +KPX I c -34 +KPX I d -20 +KPX I e -31 +KPX I f -29 +KPX I g -30 +KPX I h -40 +KPX I j -45 +KPX I k -22 +KPX I l -28 +KPX I m -26 +KPX I n -22 +KPX I o -35 +KPX I p -24 +KPX I q -29 +KPX I s -43 +KPX I x -28 +KPX I z -24 +KPX I period -51 +KPX I comma -54 +KPX I colon -30 +KPX I semicolon -30 +KPX I hyphen -41 +KPX J a -35 +KPX J b -31 +KPX J c -23 +KPX J e -26 +KPX J g -22 +KPX J h -29 +KPX J j -34 +KPX J k -23 +KPX J n -29 +KPX J o -24 +KPX J p -20 +KPX J r -20 +KPX J s -32 +KPX J x -42 +KPX J z -29 +KPX J period -44 +KPX J comma -48 +KPX J hyphen -26 +KPX K a -70 +KPX K b -33 +KPX K c -38 +KPX K d -22 +KPX K e -33 +KPX K f -31 +KPX K g -41 +KPX K h -45 +KPX K j -73 +KPX K k -24 +KPX K l -30 +KPX K m -28 +KPX K n -24 +KPX K o -44 +KPX K p -25 +KPX K q -32 +KPX K s -74 +KPX K x -29 +KPX K z -27 +KPX K period -73 +KPX K comma -74 +KPX K colon -28 +KPX K semicolon -28 +KPX K hyphen -73 +KPX L t -56 +KPX L v -24 +KPX L y -59 +KPX L quoteright -50 +KPX L quotedblright -50 +KPX M a -26 +KPX M j -25 +KPX M s -22 +KPX M x -28 +KPX M period -29 +KPX M comma -32 +KPX M hyphen -21 +KPX N a -32 +KPX N b -32 +KPX N c -28 +KPX N d -22 +KPX N e -30 +KPX N f -24 +KPX N g -28 +KPX N h -31 +KPX N j -31 +KPX N k -26 +KPX N l -23 +KPX N m -23 +KPX N n -28 +KPX N o -28 +KPX N p -25 +KPX N q -25 +KPX N s -30 +KPX N x -38 +KPX N z -29 +KPX N period -35 +KPX N comma -38 +KPX N hyphen -27 +KPX O x -33 +KPX O period -41 +KPX O comma -47 +KPX P a -60 +KPX P b -33 +KPX P c -33 +KPX P d -22 +KPX P e -35 +KPX P f -27 +KPX P g -32 +KPX P h -40 +KPX P j -60 +KPX P k -24 +KPX P l -27 +KPX P m -27 +KPX P n -25 +KPX P o -36 +KPX P p -27 +KPX P q -28 +KPX P s -72 +KPX P x -34 +KPX P z -26 +KPX P period -175 +KPX P comma -175 +KPX P colon -25 +KPX P semicolon -25 +KPX P hyphen -50 +KPX Q a -22 +KPX Q j -23 +KPX Q s -23 +KPX Q x -34 +KPX Q period -34 +KPX Q comma -34 +KPX R a -36 +KPX R j -36 +KPX R s -42 +KPX R x -23 +KPX R period -47 +KPX R comma -49 +KPX R hyphen -33 +KPX S a -54 +KPX S b -28 +KPX S c -43 +KPX S e -21 +KPX S f -28 +KPX S g -48 +KPX S h -40 +KPX S j -53 +KPX S l -21 +KPX S o -51 +KPX S q -36 +KPX S s -51 +KPX S x -21 +KPX S z -21 +KPX S period -60 +KPX S comma -63 +KPX S hyphen -50 +KPX T a -81 +KPX T b -28 +KPX T c -56 +KPX T e -23 +KPX T f -29 +KPX T g -54 +KPX T h -40 +KPX T j -80 +KPX T l -23 +KPX T m -21 +KPX T o -57 +KPX T q -38 +KPX T s -89 +KPX T x -23 +KPX T z -22 +KPX T period -158 +KPX T comma -159 +KPX T hyphen -71 +KPX U x -25 +KPX U comma -24 +KPX V a -62 +KPX V b -28 +KPX V c -38 +KPX V e -23 +KPX V f -29 +KPX V g -36 +KPX V h -41 +KPX V j -62 +KPX V l -25 +KPX V o -38 +KPX V q -33 +KPX V s -67 +KPX V x -23 +KPX V z -22 +KPX V period -93 +KPX V comma -97 +KPX V hyphen -47 +KPX W a -30 +KPX W b -30 +KPX W c -26 +KPX W e -27 +KPX W f -23 +KPX W g -25 +KPX W h -28 +KPX W j -29 +KPX W k -22 +KPX W l -23 +KPX W m -23 +KPX W n -22 +KPX W o -26 +KPX W p -21 +KPX W q -24 +KPX W s -27 +KPX W x -25 +KPX W z -25 +KPX W period -41 +KPX W comma -47 +KPX W colon -25 +KPX W semicolon -24 +KPX W hyphen -25 +KPX X g -22 +KPX X o -25 +KPX X hyphen -46 +KPX Y a -72 +KPX Y b -28 +KPX Y c -46 +KPX Y e -24 +KPX Y f -29 +KPX Y g -44 +KPX Y h -40 +KPX Y j -71 +KPX Y l -24 +KPX Y m -21 +KPX Y o -48 +KPX Y q -40 +KPX Y s -88 +KPX Y x -24 +KPX Y z -22 +KPX Y period -154 +KPX Y comma -154 +KPX Y colon -20 +KPX Y semicolon -20 +KPX Y hyphen -68 +KPX Z a -43 +KPX Z b -28 +KPX Z c -44 +KPX Z e -21 +KPX Z f -24 +KPX Z g -44 +KPX Z h -40 +KPX Z j -43 +KPX Z l -20 +KPX Z o -50 +KPX Z q -35 +KPX Z s -43 +KPX Z x -20 +KPX Z z -21 +KPX Z period -44 +KPX Z comma -44 +KPX Z hyphen -47 +KPX c a -31 +KPX c j -31 +KPX c s -30 +KPX c x -23 +KPX c period -35 +KPX c comma -38 +KPX c hyphen -44 +KPX d x -36 +KPX d period -32 +KPX d comma -40 +KPX e a -52 +KPX e b -29 +KPX e c -56 +KPX e e -27 +KPX e f -32 +KPX e g -66 +KPX e h -45 +KPX e j -52 +KPX e k -20 +KPX e l -26 +KPX e m -23 +KPX e n -21 +KPX e o -67 +KPX e p -20 +KPX e q -46 +KPX e s -59 +KPX e x -26 +KPX e z -23 +KPX e period -51 +KPX e comma -52 +KPX e colon -27 +KPX e semicolon -26 +KPX e hyphen -88 +KPX f a -86 +KPX f b -29 +KPX f c -47 +KPX f e -29 +KPX f f -35 +KPX f g -58 +KPX f h -45 +KPX f j -101 +KPX f k -20 +KPX f l -28 +KPX f m -26 +KPX f n -21 +KPX f o -61 +KPX f p -22 +KPX f q -43 +KPX f s -89 +KPX f x -27 +KPX f z -23 +KPX f period -166 +KPX f comma -166 +KPX f colon -30 +KPX f semicolon -30 +KPX f hyphen -115 +KPX g x -32 +KPX g z -24 +KPX g period -32 +KPX g comma -37 +KPX h x -31 +KPX h period -26 +KPX h comma -31 +KPX i a -46 +KPX i b -32 +KPX i c -34 +KPX i d -20 +KPX i e -31 +KPX i f -29 +KPX i g -30 +KPX i h -40 +KPX i j -45 +KPX i k -22 +KPX i l -28 +KPX i m -26 +KPX i n -22 +KPX i o -35 +KPX i p -24 +KPX i q -29 +KPX i s -43 +KPX i x -28 +KPX i z -24 +KPX i period -51 +KPX i comma -54 +KPX i colon -30 +KPX i semicolon -30 +KPX i hyphen -41 +KPX j a -35 +KPX j b -31 +KPX j c -23 +KPX j e -26 +KPX j g -22 +KPX j h -29 +KPX j j -34 +KPX j k -23 +KPX j n -29 +KPX j o -24 +KPX j p -20 +KPX j r -20 +KPX j s -32 +KPX j x -42 +KPX j z -29 +KPX j period -44 +KPX j comma -48 +KPX j hyphen -26 +KPX k a -71 +KPX k b -32 +KPX k c -38 +KPX k e -28 +KPX k f -31 +KPX k g -42 +KPX k h -45 +KPX k j -72 +KPX k k -22 +KPX k l -28 +KPX k m -26 +KPX k n -22 +KPX k o -46 +KPX k p -22 +KPX k q -32 +KPX k s -73 +KPX k x -27 +KPX k z -25 +KPX k period -72 +KPX k comma -73 +KPX k colon -25 +KPX k semicolon -25 +KPX k hyphen -74 +KPX l t -56 +KPX l v -24 +KPX l y -59 +KPX l quoteright -50 +KPX l quotedblright -50 +KPX m a -26 +KPX m j -25 +KPX m s -22 +KPX m x -28 +KPX m period -29 +KPX m comma -32 +KPX m hyphen -21 +KPX n a -32 +KPX n b -32 +KPX n c -28 +KPX n d -22 +KPX n e -30 +KPX n f -24 +KPX n g -28 +KPX n h -31 +KPX n j -31 +KPX n k -26 +KPX n l -23 +KPX n m -23 +KPX n n -28 +KPX n o -28 +KPX n p -25 +KPX n q -25 +KPX n s -30 +KPX n x -38 +KPX n z -29 +KPX n period -35 +KPX n comma -38 +KPX n hyphen -27 +KPX o x -33 +KPX o period -41 +KPX o comma -47 +KPX p a -60 +KPX p b -33 +KPX p c -33 +KPX p d -22 +KPX p e -35 +KPX p f -27 +KPX p g -32 +KPX p h -40 +KPX p j -60 +KPX p k -24 +KPX p l -27 +KPX p m -27 +KPX p n -25 +KPX p o -36 +KPX p p -27 +KPX p q -28 +KPX p s -72 +KPX p x -34 +KPX p z -26 +KPX p period -175 +KPX p comma -175 +KPX p colon -25 +KPX p semicolon -25 +KPX p hyphen -50 +KPX q a -22 +KPX q j -23 +KPX q s -23 +KPX q x -34 +KPX q period -34 +KPX q comma -34 +KPX r a -36 +KPX r j -36 +KPX r s -42 +KPX r x -23 +KPX r period -47 +KPX r comma -49 +KPX r hyphen -33 +KPX s a -54 +KPX s b -28 +KPX s c -43 +KPX s e -21 +KPX s f -28 +KPX s g -48 +KPX s h -40 +KPX s j -53 +KPX s l -21 +KPX s o -51 +KPX s q -36 +KPX s s -51 +KPX s x -21 +KPX s z -21 +KPX s period -60 +KPX s comma -63 +KPX s hyphen -50 +KPX t a -81 +KPX t b -28 +KPX t c -56 +KPX t e -23 +KPX t f -29 +KPX t g -54 +KPX t h -40 +KPX t j -80 +KPX t l -23 +KPX t m -21 +KPX t o -57 +KPX t q -38 +KPX t s -89 +KPX t x -23 +KPX t z -22 +KPX t period -158 +KPX t comma -159 +KPX t hyphen -71 +KPX u x -25 +KPX u comma -24 +KPX v a -62 +KPX v b -28 +KPX v c -38 +KPX v e -23 +KPX v f -29 +KPX v g -36 +KPX v h -41 +KPX v j -62 +KPX v l -25 +KPX v o -38 +KPX v q -33 +KPX v s -67 +KPX v x -23 +KPX v z -22 +KPX v period -93 +KPX v comma -97 +KPX v hyphen -47 +KPX w a -30 +KPX w b -30 +KPX w c -26 +KPX w e -27 +KPX w f -23 +KPX w g -25 +KPX w h -28 +KPX w j -29 +KPX w k -22 +KPX w l -23 +KPX w m -23 +KPX w n -22 +KPX w o -26 +KPX w p -21 +KPX w q -24 +KPX w s -27 +KPX w x -25 +KPX w z -25 +KPX w period -41 +KPX w comma -47 +KPX w colon -25 +KPX w semicolon -24 +KPX w hyphen -25 +KPX x g -22 +KPX x o -25 +KPX x hyphen -46 +KPX y a -72 +KPX y b -28 +KPX y c -46 +KPX y e -24 +KPX y f -29 +KPX y g -44 +KPX y h -40 +KPX y j -71 +KPX y l -24 +KPX y m -21 +KPX y o -48 +KPX y q -40 +KPX y s -88 +KPX y x -24 +KPX y z -22 +KPX y period -154 +KPX y comma -154 +KPX y colon -20 +KPX y semicolon -20 +KPX y hyphen -68 +KPX z a -43 +KPX z b -28 +KPX z c -44 +KPX z e -21 +KPX z f -24 +KPX z g -44 +KPX z h -40 +KPX z j -43 +KPX z l -20 +KPX z o -50 +KPX z q -35 +KPX z s -43 +KPX z x -20 +KPX z z -21 +KPX z period -44 +KPX z comma -44 +KPX z hyphen -47 +KPX quoteleft a -50 +KPX quoteleft j -50 +KPX quoteleft A -50 +KPX quoteleft J -50 +KPX quoteleft c -30 +KPX quoteleft g -30 +KPX quoteleft o -30 +KPX quoteleft q -30 +KPX quoteleft s -30 +KPX quoteleft C -30 +KPX quoteleft G -30 +KPX quoteleft O -30 +KPX quoteleft Q -30 +KPX quoteleft S -30 +KPX quotedblleft a -50 +KPX quotedblleft j -50 +KPX quotedblleft A -50 +KPX quotedblleft J -50 +KPX quotedblleft c -30 +KPX quotedblleft g -30 +KPX quotedblleft o -30 +KPX quotedblleft q -30 +KPX quotedblleft s -30 +KPX quotedblleft C -30 +KPX quotedblleft G -30 +KPX quotedblleft O -30 +KPX quotedblleft Q -30 +KPX quotedblleft S -30 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/fonts/afm/hoekwater/koeieletters/koeien-sy.afm b/fonts/afm/hoekwater/koeieletters/koeien-sy.afm new file mode 100644 index 000000000..3827ec33c --- /dev/null +++ b/fonts/afm/hoekwater/koeieletters/koeien-sy.afm @@ -0,0 +1,879 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20050809 +Comment Creation Date: Thu Aug 3 13:49:26 2006 +FontName koeieletters +FullName koeieletters +FamilyName koeieletters +Weight Medium +Notice (Copyright 2006 Hans Hagen, Taco Hoekwater. Based on original drawings by Duane Bibby.) +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 16 +Version 001.002 +EncodingScheme FontSpecific +FontBBox -12 -2066 1146 821 +CapHeight 636 +XHeight 540 +Ascender 533 +StartCharMetrics 187 +C 0 ; WX 321 ; N parenleft.big ; B 25 -1001 295 39 ; +C 1 ; WX 323 ; N parenright.big ; B 25 -999 298 42 ; +C 2 ; WX 585 ; N slash.big ; B 25 -825 560 39 ; +C 3 ; WX 382 ; N bracketleft.big ; B 25 -988 357 52 ; +C 4 ; WX 502 ; N backslash.big ; B 25 -820 477 44 ; +C 5 ; WX 376 ; N bracketright.big ; B 25 -990 351 50 ; +C 6 ; WX 332 ; N braceleft.big ; B 25 -1008 307 52 ; +C 7 ; WX 243 ; N bar.big ; B 25 -982 218 49 ; +C 8 ; WX 323 ; N braceright.big ; B 24 -1013 298 61 ; +C 9 ; WX 656 ; N integral.big ; B 25 -1159 631 0 ; +C 10 ; WX 1014 ; N summation.big ; B 29 -1049 988 0 ; +C 11 ; WX 701 ; N radical.big ; B 25 -892 709 74 ; +C 12 ; WX 743 ; N radical.bigg ; B 25 -1267 751 74 ; +C 13 ; WX 731 ; N radical.Bigg ; B 25 -1666 739 74 ; +C 14 ; WX 664 ; N radical.BIGG ; B 25 -2066 672 74 ; +C 15 ; WX 122 ; N radical.end ; B -8 0 122 74 ; +C 16 ; WX 8 ; N radical.extender ; B -12 0 21 74 ; +C 17 ; WX 644 ; N radical.alt ; B 25 -717 652 74 ; +C 18 ; WX 613 ; N integral.alt ; B 25 -809 588 0 ; +C 19 ; WX 814 ; N summation.alt ; B 25 -699 788 0 ; +C 20 ; WX 321 ; N parenleft.bigg ; B 25 -1351 295 39 ; +C 21 ; WX 323 ; N parenright.bigg ; B 25 -1349 298 42 ; +C 22 ; WX 714 ; N slash.bigg ; B 25 -1175 689 39 ; +C 23 ; WX 382 ; N bracketleft.bigg ; B 25 -1338 357 52 ; +C 24 ; WX 596 ; N backslash.bigg ; B 25 -1170 571 44 ; +C 25 ; WX 376 ; N bracketright.bigg ; B 25 -1340 351 50 ; +C 26 ; WX 332 ; N braceleft.bigg ; B 25 -1358 307 52 ; +C 27 ; WX 243 ; N bar.bigg ; B 25 -1332 218 49 ; +C 28 ; WX 323 ; N braceright.bigg ; B 24 -1363 298 61 ; +C 29 ; WX 195 ; N bar.begin ; B 0 0 203 74 ; +C 32 ; WX 500 ; N space ; B 0 0 0 0 ; +C 33 ; WX 345 ; N exclam ; B 25 0 319 530 ; +C 34 ; WX 460 ; N quotedbl ; B 25 338 435 544 ; +C 39 ; WX 239 ; N quotesingle ; B 25 338 214 544 ; +C 40 ; WX 321 ; N parenleft ; B 25 -64 295 651 ; +C 41 ; WX 323 ; N parenright ; B 25 -65 298 651 ; +C 42 ; WX 414 ; N asterisk ; B 25 32 389 404 ; +C 43 ; WX 461 ; N plus ; B 25 44 436 404 ; +C 44 ; WX 232 ; N comma ; B 25 -66 207 140 ; +C 45 ; WX 355 ; N hyphen ; B 25 176 330 294 ; +C 46 ; WX 231 ; N period ; B 25 0 206 151 ; +C 47 ; WX 539 ; N slash ; B 25 0 513 514 ; +C 48 ; WX 499 ; N zero ; B 25 0 474 526 ; +C 49 ; WX 488 ; N one ; B 25 0 463 530 ; +C 50 ; WX 539 ; N two ; B 25 0 513 528 ; +C 51 ; WX 501 ; N three ; B 25 0 476 517 ; +C 52 ; WX 514 ; N four ; B 25 0 489 510 ; +C 53 ; WX 521 ; N five ; B 25 0 494 515 ; +C 54 ; WX 513 ; N six ; B 25 0 489 514 ; +C 55 ; WX 540 ; N seven ; B 25 -1 514 526 ; +C 56 ; WX 498 ; N eight ; B 25 -1 474 511 ; +C 57 ; WX 495 ; N nine ; B 23 0 468 513 ; +C 58 ; WX 234 ; N colon ; B 25 52 209 460 ; +C 59 ; WX 245 ; N semicolon ; B 25 -10 219 461 ; +C 60 ; WX 544 ; N less ; B 25 81 519 456 ; +C 61 ; WX 460 ; N equal ; B 25 88 435 404 ; +C 62 ; WX 581 ; N greater ; B 25 66 556 448 ; +C 63 ; WX 518 ; N question ; B 25 -5 493 536 ; +C 64 ; WX 585 ; N at ; B 25 -4 560 479 ; +C 65 ; WX 676 ; N A ; B 30 -8 646 630 ; +C 66 ; WX 654 ; N B ; B 30 -8 622 631 ; +C 67 ; WX 729 ; N C ; B 30 0 679 640 ; +C 68 ; WX 674 ; N D ; B 30 0 643 626 ; +C 69 ; WX 676 ; N E ; B 30 0 645 634 ; +C 70 ; WX 686 ; N F ; B 30 -8 656 638 ; +C 71 ; WX 663 ; N G ; B 30 0 652 643 ; +C 72 ; WX 716 ; N H ; B 30 0 685 642 ; +C 73 ; WX 554 ; N I ; B 30 0 519 636 ; +C 74 ; WX 732 ; N J ; B 30 0 702 652 ; +C 75 ; WX 740 ; N K ; B 30 -4 689 637 ; +C 76 ; WX 626 ; N L ; B 30 -9 595 638 ; +C 77 ; WX 730 ; N M ; B 30 -8 699 631 ; +C 78 ; WX 708 ; N N ; B 30 -1 676 666 ; +C 79 ; WX 783 ; N O ; B 30 -6 704 653 ; +C 80 ; WX 722 ; N P ; B 30 -1 691 646 ; +C 81 ; WX 731 ; N Q ; B 30 0 699 642 ; +C 82 ; WX 703 ; N R ; B 30 -9 672 657 ; +C 83 ; WX 750 ; N S ; B 30 -8 711 648 ; +C 84 ; WX 758 ; N T ; B 30 -9 728 642 ; +C 85 ; WX 687 ; N U ; B 30 0 656 657 ; +C 86 ; WX 728 ; N V ; B 30 -6 692 627 ; +C 87 ; WX 712 ; N W ; B 30 -9 686 639 ; +C 88 ; WX 716 ; N X ; B 30 -6 684 646 ; +C 89 ; WX 726 ; N Y ; B 30 -26 693 642 ; +C 90 ; WX 685 ; N Z ; B 30 -19 651 632 ; +C 91 ; WX 382 ; N bracketleft ; B 25 -73 357 642 ; +C 92 ; WX 489 ; N backslash ; B 25 0 464 514 ; +C 93 ; WX 376 ; N bracketright ; B 25 -73 351 642 ; +C 94 ; WX 480 ; N asciicircum ; B 25 322 455 515 ; +C 95 ; WX 579 ; N underscore ; B 25 -183 554 -51 ; +C 96 ; WX 338 ; N grave ; B 25 570 312 762 ; +C 97 ; WX 565 ; N a ; B 25 -7 540 526 ; +C 98 ; WX 545 ; N b ; B 25 -8 520 526 ; +C 99 ; WX 593 ; N c ; B 25 0 566 535 ; +C 100 ; WX 562 ; N d ; B 25 0 537 523 ; +C 101 ; WX 564 ; N e ; B 25 0 539 530 ; +C 102 ; WX 572 ; N f ; B 25 -8 548 532 ; +C 103 ; WX 570 ; N g ; B 25 0 545 536 ; +C 104 ; WX 597 ; N h ; B 25 0 572 536 ; +C 105 ; WX 462 ; N i ; B 25 -1 434 531 ; +C 106 ; WX 610 ; N j ; B 25 -6 586 545 ; +C 107 ; WX 600 ; N k ; B 25 -5 575 531 ; +C 108 ; WX 522 ; N l ; B 25 -9 497 533 ; +C 109 ; WX 609 ; N m ; B 25 -8 584 528 ; +C 110 ; WX 590 ; N n ; B 25 -1 565 556 ; +C 111 ; WX 613 ; N o ; B 25 -5 588 546 ; +C 112 ; WX 602 ; N p ; B 25 -1 577 540 ; +C 113 ; WX 609 ; N q ; B 25 0 584 536 ; +C 114 ; WX 586 ; N r ; B 25 -8 561 549 ; +C 115 ; WX 625 ; N s ; B 25 -13 594 541 ; +C 116 ; WX 632 ; N t ; B 25 -8 608 536 ; +C 117 ; WX 573 ; N u ; B 25 0 548 549 ; +C 118 ; WX 607 ; N v ; B 25 -5 578 524 ; +C 119 ; WX 602 ; N w ; B 25 -8 573 534 ; +C 120 ; WX 597 ; N x ; B 25 -5 571 540 ; +C 121 ; WX 605 ; N y ; B 25 -28 579 536 ; +C 122 ; WX 571 ; N z ; B 25 -19 544 528 ; +C 123 ; WX 332 ; N braceleft ; B 25 -88 307 625 ; +C 124 ; WX 243 ; N bar ; B 25 0 218 681 ; +C 125 ; WX 323 ; N braceright ; B 24 -74 298 650 ; +C 126 ; WX 592 ; N asciitilde ; B 25 198 568 388 ; +C 156 ; WX 448 ; N dieresis ; B 25 557 423 711 ; +C 168 ; WX 336 ; N acute ; B 25 569 312 754 ; +C 203 ; WX 468 ; N multiply ; B 25 41 443 409 ; +C 244 ; WX 770 ; N infinity ; B 25 87 745 427 ; +C 245 ; WX 645 ; N arrowleft ; B 25 49 620 433 ; +C 246 ; WX 683 ; N arrowright ; B 25 53 658 433 ; +C 247 ; WX 460 ; N minus ; B 25 154 435 302 ; +C 248 ; WX 414 ; N asteriskmath ; B 25 32 389 404 ; +C 249 ; WX 613 ; N integral ; B 25 -155 588 654 ; +C 250 ; WX 814 ; N summation ; B 25 -116 788 583 ; +C 251 ; WX 614 ; N equivalence ; B 25 58 590 426 ; +C 252 ; WX 592 ; N similar ; B 23 198 568 388 ; +C 253 ; WX 224 ; N minute ; B 25 197 199 514 ; +C 254 ; WX 763 ; N emdash ; B 25 165 738 297 ; +C 255 ; WX 534 ; N endash ; B 25 165 509 297 ; +C -1 ; WX 512 ; N hungarumlaut ; B 50 581 487 778 ; +C -1 ; WX 460 ; N quotedblright ; B 25 358 435 564 ; +C -1 ; WX 256 ; N quoteright ; B 25 358 231 564 ; +C -1 ; WX 237 ; N quoteleft ; B 25 357 212 564 ; +C -1 ; WX 465 ; N breve ; B 25 611 440 799 ; +C -1 ; WX 451 ; N quotedblleft ; B 25 358 426 564 ; +C -1 ; WX 256 ; N quotesinglbase ; B 25 -58 231 148 ; +C -1 ; WX 460 ; N quotedblbase ; B 24 -65 435 141 ; +C -1 ; WX 378 ; N second ; B 25 197 353 514 ; +C -1 ; WX 530 ; N radical ; B 25 -62 1146 729 ; +C -1 ; WX 480 ; N circumflex ; B 25 561 455 754 ; +C -1 ; WX 521 ; N tilde ; B 25 564 495 728 ; +C -1 ; WX 462 ; N dotlessi ; B 25 -1 434 531 ; +C -1 ; WX 610 ; N dotlessj ; B 25 -6 586 545 ; +C -1 ; WX 496 ; N plus.alt ; B 25 62 470 464 ; +C -1 ; WX 481 ; N minus.alt ; B 25 174 457 356 ; +C -1 ; WX 552 ; N zero.alt ; B 25 -9 526 528 ; +C -1 ; WX 554 ; N one.alt ; B 25 -12 527 545 ; +C -1 ; WX 569 ; N two.alt ; B 25 -16 546 523 ; +C -1 ; WX 563 ; N three.alt ; B 25 -18 540 532 ; +C -1 ; WX 595 ; N four.alt ; B 25 -14 570 525 ; +C -1 ; WX 573 ; N five.alt ; B 25 -18 553 540 ; +C -1 ; WX 558 ; N six.alt ; B 25 -7 535 536 ; +C -1 ; WX 594 ; N seven.alt ; B 25 -4 568 525 ; +C -1 ; WX 544 ; N eight.alt ; B 25 -19 520 530 ; +C -1 ; WX 594 ; N nine.alt ; B 25 -19 568 536 ; +C -1 ; WX 231 ; N periodcentered ; B 25 153 206 304 ; +C -1 ; WX 231 ; N dotaccent ; B 25 611 206 762 ; +C -1 ; WX 321 ; N parenleft.top ; B 25 -500 278 39 ; +C -1 ; WX 323 ; N parenright.top ; B 25 -500 298 42 ; +C -1 ; WX 321 ; N parenleft.ex ; B 25 -504 223 8 ; +C -1 ; WX 323 ; N parenright.ex ; B 99 -504 298 8 ; +C -1 ; WX 321 ; N parenleft.bot ; B 25 -493 295 8 ; +C -1 ; WX 323 ; N parenright.bot ; B 35 -491 298 8 ; +C -1 ; WX 382 ; N bracketleft.top ; B 25 -500 357 52 ; +C -1 ; WX 376 ; N bracketright.top ; B 41 -500 351 50 ; +C -1 ; WX 382 ; N bracketleft.ex ; B 25 -504 271 8 ; +C -1 ; WX 376 ; N bracketright.ex ; B 116 -504 351 8 ; +C -1 ; WX 382 ; N bracketleft.bot ; B 25 -480 339 8 ; +C -1 ; WX 376 ; N bracketright.bot ; B 25 -482 351 8 ; +C -1 ; WX 465 ; N hacek ; B 25 611 440 821 ; +C -1 ; WX 534 ; N macron ; B 25 575 509 707 ; +C -1 ; WX 483 ; N ringaccent ; B 160 560 370 719 ; +C -1 ; WX 547 ; N arrowleft.lft ; B 25 49 555 433 ; +C -1 ; WX 369 ; N arrowright.lft ; B 25 176 377 316 ; +C -1 ; WX 137 ; N arrowleft.rt ; B -8 176 112 316 ; +C -1 ; WX 325 ; N arrowright.rt ; B -8 53 300 433 ; +C -1 ; WX 300 ; N arrow.mid ; B -8 176 308 316 ; +C -1 ; WX 476 ; N radical.bot ; B 25 -1666 413 8 ; +C -1 ; WX 476 ; N radical.top ; B 258 -208 484 74 ; +C -1 ; WX 476 ; N radical.mid ; B 258 -208 413 8 ; +EndCharMetrics +StartKernData +StartKernPairs 667 +KPX C a -31 +KPX C j -31 +KPX C s -30 +KPX C x -23 +KPX C period -35 +KPX C comma -38 +KPX C hyphen -44 +KPX D x -36 +KPX D period -32 +KPX D comma -40 +KPX E a -52 +KPX E b -29 +KPX E c -56 +KPX E e -27 +KPX E f -32 +KPX E g -66 +KPX E h -45 +KPX E j -52 +KPX E k -20 +KPX E l -26 +KPX E m -23 +KPX E n -21 +KPX E o -67 +KPX E p -20 +KPX E q -46 +KPX E s -59 +KPX E x -26 +KPX E z -23 +KPX E period -51 +KPX E comma -52 +KPX E colon -27 +KPX E semicolon -26 +KPX E hyphen -88 +KPX F a -86 +KPX F b -29 +KPX F c -47 +KPX F e -29 +KPX F f -35 +KPX F g -58 +KPX F h -45 +KPX F j -101 +KPX F k -20 +KPX F l -28 +KPX F m -26 +KPX F n -21 +KPX F o -61 +KPX F p -22 +KPX F q -43 +KPX F s -89 +KPX F x -27 +KPX F z -23 +KPX F period -166 +KPX F comma -166 +KPX F colon -30 +KPX F semicolon -30 +KPX F hyphen -115 +KPX G x -32 +KPX G z -24 +KPX G period -32 +KPX G comma -37 +KPX H x -31 +KPX H period -26 +KPX H comma -31 +KPX I a -46 +KPX I b -32 +KPX I c -34 +KPX I d -20 +KPX I e -31 +KPX I f -29 +KPX I g -30 +KPX I h -40 +KPX I j -45 +KPX I k -22 +KPX I l -28 +KPX I m -26 +KPX I n -22 +KPX I o -35 +KPX I p -24 +KPX I q -29 +KPX I s -43 +KPX I x -28 +KPX I z -24 +KPX I period -51 +KPX I comma -54 +KPX I colon -30 +KPX I semicolon -30 +KPX I hyphen -41 +KPX J a -35 +KPX J b -31 +KPX J c -23 +KPX J e -26 +KPX J g -22 +KPX J h -29 +KPX J j -34 +KPX J k -23 +KPX J n -29 +KPX J o -24 +KPX J p -20 +KPX J r -20 +KPX J s -32 +KPX J x -42 +KPX J z -29 +KPX J period -44 +KPX J comma -48 +KPX J hyphen -26 +KPX K a -70 +KPX K b -33 +KPX K c -38 +KPX K d -22 +KPX K e -33 +KPX K f -31 +KPX K g -41 +KPX K h -45 +KPX K j -73 +KPX K k -24 +KPX K l -30 +KPX K m -28 +KPX K n -24 +KPX K o -44 +KPX K p -25 +KPX K q -32 +KPX K s -74 +KPX K x -29 +KPX K z -27 +KPX K period -73 +KPX K comma -74 +KPX K colon -28 +KPX K semicolon -28 +KPX K hyphen -73 +KPX L t -56 +KPX L v -24 +KPX L y -59 +KPX L quoteright -50 +KPX L quotedblright -50 +KPX M a -26 +KPX M j -25 +KPX M s -22 +KPX M x -28 +KPX M period -29 +KPX M comma -32 +KPX M hyphen -21 +KPX N a -32 +KPX N b -32 +KPX N c -28 +KPX N d -22 +KPX N e -30 +KPX N f -24 +KPX N g -28 +KPX N h -31 +KPX N j -31 +KPX N k -26 +KPX N l -23 +KPX N m -23 +KPX N n -28 +KPX N o -28 +KPX N p -25 +KPX N q -25 +KPX N s -30 +KPX N x -38 +KPX N z -29 +KPX N period -35 +KPX N comma -38 +KPX N hyphen -27 +KPX O x -33 +KPX O period -41 +KPX O comma -47 +KPX P a -60 +KPX P b -33 +KPX P c -33 +KPX P d -22 +KPX P e -35 +KPX P f -27 +KPX P g -32 +KPX P h -40 +KPX P j -60 +KPX P k -24 +KPX P l -27 +KPX P m -27 +KPX P n -25 +KPX P o -36 +KPX P p -27 +KPX P q -28 +KPX P s -72 +KPX P x -34 +KPX P z -26 +KPX P period -175 +KPX P comma -175 +KPX P colon -25 +KPX P semicolon -25 +KPX P hyphen -50 +KPX Q a -22 +KPX Q j -23 +KPX Q s -23 +KPX Q x -34 +KPX Q period -34 +KPX Q comma -34 +KPX R a -36 +KPX R j -36 +KPX R s -42 +KPX R x -23 +KPX R period -47 +KPX R comma -49 +KPX R hyphen -33 +KPX S a -54 +KPX S b -28 +KPX S c -43 +KPX S e -21 +KPX S f -28 +KPX S g -48 +KPX S h -40 +KPX S j -53 +KPX S l -21 +KPX S o -51 +KPX S q -36 +KPX S s -51 +KPX S x -21 +KPX S z -21 +KPX S period -60 +KPX S comma -63 +KPX S hyphen -50 +KPX T a -81 +KPX T b -28 +KPX T c -56 +KPX T e -23 +KPX T f -29 +KPX T g -54 +KPX T h -40 +KPX T j -80 +KPX T l -23 +KPX T m -21 +KPX T o -57 +KPX T q -38 +KPX T s -89 +KPX T x -23 +KPX T z -22 +KPX T period -158 +KPX T comma -159 +KPX T hyphen -71 +KPX U x -25 +KPX U comma -24 +KPX V a -62 +KPX V b -28 +KPX V c -38 +KPX V e -23 +KPX V f -29 +KPX V g -36 +KPX V h -41 +KPX V j -62 +KPX V l -25 +KPX V o -38 +KPX V q -33 +KPX V s -67 +KPX V x -23 +KPX V z -22 +KPX V period -93 +KPX V comma -97 +KPX V hyphen -47 +KPX W a -30 +KPX W b -30 +KPX W c -26 +KPX W e -27 +KPX W f -23 +KPX W g -25 +KPX W h -28 +KPX W j -29 +KPX W k -22 +KPX W l -23 +KPX W m -23 +KPX W n -22 +KPX W o -26 +KPX W p -21 +KPX W q -24 +KPX W s -27 +KPX W x -25 +KPX W z -25 +KPX W period -41 +KPX W comma -47 +KPX W colon -25 +KPX W semicolon -24 +KPX W hyphen -25 +KPX X g -22 +KPX X o -25 +KPX X hyphen -46 +KPX Y a -72 +KPX Y b -28 +KPX Y c -46 +KPX Y e -24 +KPX Y f -29 +KPX Y g -44 +KPX Y h -40 +KPX Y j -71 +KPX Y l -24 +KPX Y m -21 +KPX Y o -48 +KPX Y q -40 +KPX Y s -88 +KPX Y x -24 +KPX Y z -22 +KPX Y period -154 +KPX Y comma -154 +KPX Y colon -20 +KPX Y semicolon -20 +KPX Y hyphen -68 +KPX Z a -43 +KPX Z b -28 +KPX Z c -44 +KPX Z e -21 +KPX Z f -24 +KPX Z g -44 +KPX Z h -40 +KPX Z j -43 +KPX Z l -20 +KPX Z o -50 +KPX Z q -35 +KPX Z s -43 +KPX Z x -20 +KPX Z z -21 +KPX Z period -44 +KPX Z comma -44 +KPX Z hyphen -47 +KPX c a -31 +KPX c j -31 +KPX c s -30 +KPX c x -23 +KPX c period -35 +KPX c comma -38 +KPX c hyphen -44 +KPX d x -36 +KPX d period -32 +KPX d comma -40 +KPX e a -52 +KPX e b -29 +KPX e c -56 +KPX e e -27 +KPX e f -32 +KPX e g -66 +KPX e h -45 +KPX e j -52 +KPX e k -20 +KPX e l -26 +KPX e m -23 +KPX e n -21 +KPX e o -67 +KPX e p -20 +KPX e q -46 +KPX e s -59 +KPX e x -26 +KPX e z -23 +KPX e period -51 +KPX e comma -52 +KPX e colon -27 +KPX e semicolon -26 +KPX e hyphen -88 +KPX f a -86 +KPX f b -29 +KPX f c -47 +KPX f e -29 +KPX f f -35 +KPX f g -58 +KPX f h -45 +KPX f j -101 +KPX f k -20 +KPX f l -28 +KPX f m -26 +KPX f n -21 +KPX f o -61 +KPX f p -22 +KPX f q -43 +KPX f s -89 +KPX f x -27 +KPX f z -23 +KPX f period -166 +KPX f comma -166 +KPX f colon -30 +KPX f semicolon -30 +KPX f hyphen -115 +KPX g x -32 +KPX g z -24 +KPX g period -32 +KPX g comma -37 +KPX h x -31 +KPX h period -26 +KPX h comma -31 +KPX i a -46 +KPX i b -32 +KPX i c -34 +KPX i d -20 +KPX i e -31 +KPX i f -29 +KPX i g -30 +KPX i h -40 +KPX i j -45 +KPX i k -22 +KPX i l -28 +KPX i m -26 +KPX i n -22 +KPX i o -35 +KPX i p -24 +KPX i q -29 +KPX i s -43 +KPX i x -28 +KPX i z -24 +KPX i period -51 +KPX i comma -54 +KPX i colon -30 +KPX i semicolon -30 +KPX i hyphen -41 +KPX j a -35 +KPX j b -31 +KPX j c -23 +KPX j e -26 +KPX j g -22 +KPX j h -29 +KPX j j -34 +KPX j k -23 +KPX j n -29 +KPX j o -24 +KPX j p -20 +KPX j r -20 +KPX j s -32 +KPX j x -42 +KPX j z -29 +KPX j period -44 +KPX j comma -48 +KPX j hyphen -26 +KPX k a -71 +KPX k b -32 +KPX k c -38 +KPX k e -28 +KPX k f -31 +KPX k g -42 +KPX k h -45 +KPX k j -72 +KPX k k -22 +KPX k l -28 +KPX k m -26 +KPX k n -22 +KPX k o -46 +KPX k p -22 +KPX k q -32 +KPX k s -73 +KPX k x -27 +KPX k z -25 +KPX k period -72 +KPX k comma -73 +KPX k colon -25 +KPX k semicolon -25 +KPX k hyphen -74 +KPX l t -56 +KPX l v -24 +KPX l y -59 +KPX l quoteright -50 +KPX l quotedblright -50 +KPX m a -26 +KPX m j -25 +KPX m s -22 +KPX m x -28 +KPX m period -29 +KPX m comma -32 +KPX m hyphen -21 +KPX n a -32 +KPX n b -32 +KPX n c -28 +KPX n d -22 +KPX n e -30 +KPX n f -24 +KPX n g -28 +KPX n h -31 +KPX n j -31 +KPX n k -26 +KPX n l -23 +KPX n m -23 +KPX n n -28 +KPX n o -28 +KPX n p -25 +KPX n q -25 +KPX n s -30 +KPX n x -38 +KPX n z -29 +KPX n period -35 +KPX n comma -38 +KPX n hyphen -27 +KPX o x -33 +KPX o period -41 +KPX o comma -47 +KPX p a -60 +KPX p b -33 +KPX p c -33 +KPX p d -22 +KPX p e -35 +KPX p f -27 +KPX p g -32 +KPX p h -40 +KPX p j -60 +KPX p k -24 +KPX p l -27 +KPX p m -27 +KPX p n -25 +KPX p o -36 +KPX p p -27 +KPX p q -28 +KPX p s -72 +KPX p x -34 +KPX p z -26 +KPX p period -175 +KPX p comma -175 +KPX p colon -25 +KPX p semicolon -25 +KPX p hyphen -50 +KPX q a -22 +KPX q j -23 +KPX q s -23 +KPX q x -34 +KPX q period -34 +KPX q comma -34 +KPX r a -36 +KPX r j -36 +KPX r s -42 +KPX r x -23 +KPX r period -47 +KPX r comma -49 +KPX r hyphen -33 +KPX s a -54 +KPX s b -28 +KPX s c -43 +KPX s e -21 +KPX s f -28 +KPX s g -48 +KPX s h -40 +KPX s j -53 +KPX s l -21 +KPX s o -51 +KPX s q -36 +KPX s s -51 +KPX s x -21 +KPX s z -21 +KPX s period -60 +KPX s comma -63 +KPX s hyphen -50 +KPX t a -81 +KPX t b -28 +KPX t c -56 +KPX t e -23 +KPX t f -29 +KPX t g -54 +KPX t h -40 +KPX t j -80 +KPX t l -23 +KPX t m -21 +KPX t o -57 +KPX t q -38 +KPX t s -89 +KPX t x -23 +KPX t z -22 +KPX t period -158 +KPX t comma -159 +KPX t hyphen -71 +KPX u x -25 +KPX u comma -24 +KPX v a -62 +KPX v b -28 +KPX v c -38 +KPX v e -23 +KPX v f -29 +KPX v g -36 +KPX v h -41 +KPX v j -62 +KPX v l -25 +KPX v o -38 +KPX v q -33 +KPX v s -67 +KPX v x -23 +KPX v z -22 +KPX v period -93 +KPX v comma -97 +KPX v hyphen -47 +KPX w a -30 +KPX w b -30 +KPX w c -26 +KPX w e -27 +KPX w f -23 +KPX w g -25 +KPX w h -28 +KPX w j -29 +KPX w k -22 +KPX w l -23 +KPX w m -23 +KPX w n -22 +KPX w o -26 +KPX w p -21 +KPX w q -24 +KPX w s -27 +KPX w x -25 +KPX w z -25 +KPX w period -41 +KPX w comma -47 +KPX w colon -25 +KPX w semicolon -24 +KPX w hyphen -25 +KPX x g -22 +KPX x o -25 +KPX x hyphen -46 +KPX y a -72 +KPX y b -28 +KPX y c -46 +KPX y e -24 +KPX y f -29 +KPX y g -44 +KPX y h -40 +KPX y j -71 +KPX y l -24 +KPX y m -21 +KPX y o -48 +KPX y q -40 +KPX y s -88 +KPX y x -24 +KPX y z -22 +KPX y period -154 +KPX y comma -154 +KPX y colon -20 +KPX y semicolon -20 +KPX y hyphen -68 +KPX z a -43 +KPX z b -28 +KPX z c -44 +KPX z e -21 +KPX z f -24 +KPX z g -44 +KPX z h -40 +KPX z j -43 +KPX z l -20 +KPX z o -50 +KPX z q -35 +KPX z s -43 +KPX z x -20 +KPX z z -21 +KPX z period -44 +KPX z comma -44 +KPX z hyphen -47 +KPX quoteleft a -50 +KPX quoteleft j -50 +KPX quoteleft A -50 +KPX quoteleft J -50 +KPX quoteleft c -30 +KPX quoteleft g -30 +KPX quoteleft o -30 +KPX quoteleft q -30 +KPX quoteleft s -30 +KPX quoteleft C -30 +KPX quoteleft G -30 +KPX quoteleft O -30 +KPX quoteleft Q -30 +KPX quoteleft S -30 +KPX quotedblleft a -50 +KPX quotedblleft j -50 +KPX quotedblleft A -50 +KPX quotedblleft J -50 +KPX quotedblleft c -30 +KPX quotedblleft g -30 +KPX quotedblleft o -30 +KPX quotedblleft q -30 +KPX quotedblleft s -30 +KPX quotedblleft C -30 +KPX quotedblleft G -30 +KPX quotedblleft O -30 +KPX quotedblleft Q -30 +KPX quotedblleft S -30 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/fonts/afm/jmn/hans/hans-sh.afm b/fonts/afm/jmn/hans/hans-sh.afm new file mode 100644 index 000000000..9ca07d39e --- /dev/null +++ b/fonts/afm/jmn/hans/hans-sh.afm @@ -0,0 +1,164 @@ +StartFontMetrics 2.0 +Generated by MetaType1 (a MetaPost-based engine) +Comment Creation Date: 19.08.2004 +Notice Design by Janusz M. Nowacki, 2004. +FontName Hans-sh-Regular +FullName Hans-sh-Regular +FamilyName Hans-sh +Weight Normal +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -200 +UnderlineThickness 40 +Version 1.0 +EncodingScheme FontSpecific +FontBBox 0 -469 1420 939 +CapHeight 700 +XHeight 500 +Descender -200 +Ascender 700 +Comment TFM designsize: 10 (in points) +Comment TFM fontdimen 1: 0 (slant) +Comment TFM fontdimen 2: 3.33 (space) +Comment TFM fontdimen 3: 1.67 (space stretch) +Comment TFM fontdimen 4: 1.11 (space shrink) +Comment TFM fontdimen 5: 5 (xheight) +Comment TFM fontdimen 6: 10 (quad) +Comment TFM fontdimen 7: 1.11 (extra space) +Comment TFM fontdimen 8: 0.4 (math rule) +Comment TFM fontdimen 22: 2.5 (math axis) +Comment TFM headerbyte 9: FontSpecific +Comment TFM headerbyte 49: Hans-sh +Comment TFM headerbyte 72: 234 +StartCharMetrics 129 +C 32 ; WX 333 ; N space ; B 0 0 0 0 ; +C 64 ; WX 580 ; N at ; B 40 0 540 500 ; +C 65 ; WX 660 ; N A ; B 30 -65 630 535 ; L A AA ; L at A.alt ; +C 66 ; WX 660 ; N B ; B 30 -65 630 535 ; L B BB ; L at B.alt ; +C 67 ; WX 660 ; N C ; B 30 -65 630 535 ; L C CC ; L at C.alt ; +C 68 ; WX 660 ; N D ; B 30 -65 630 535 ; L D DD ; L at D.alt ; +C 69 ; WX 703 ; N E ; B 30 -86 673 556 ; L E EE ; L at E.alt ; +C 70 ; WX 703 ; N F ; B 30 -86 673 556 ; L F FF ; L at F.alt ; +C 71 ; WX 703 ; N G ; B 30 -86 673 556 ; L G GG ; L at G.alt ; +C 72 ; WX 703 ; N H ; B 30 -86 673 556 ; L H HH ; L at H.alt ; +C 73 ; WX 723 ; N I ; B 30 -66 693 536 ; L I II ; L at I.alt ; +C 74 ; WX 687 ; N J ; B 30 -66 657 536 ; L J JJ ; L at J.alt ; +C 75 ; WX 723 ; N K ; B 30 -66 693 536 ; L K KK ; L at K.alt ; +C 76 ; WX 687 ; N L ; B 30 -66 657 536 ; L L LL ; L at L.alt ; +C 77 ; WX 410 ; N M ; B 30 60 380 410 ; L M MM ; +C 78 ; WX 410 ; N N ; B 30 60 380 410 ; L N NN ; +C 79 ; WX 410 ; N O ; B 30 60 380 410 ; L O OO ; +C 80 ; WX 410 ; N P ; B 30 60 380 410 ; L P PP ; +C 81 ; WX 410 ; N Q ; B 30 60 380 410 ; L Q QQ ; +C 82 ; WX 410 ; N R ; B 30 60 380 410 ; L R RR ; +C 83 ; WX 410 ; N S ; B 30 60 380 410 ; L S SS ; +C 84 ; WX 412 ; N T ; B 30 59 382 411 ; L T TT ; +C 85 ; WX 410 ; N U ; B 30 60 380 410 ; L U UU ; +C 86 ; WX 410 ; N V ; B 30 60 380 410 ; L V VV ; +C 87 ; WX 515 ; N W ; B 30 7 486 463 ; L W WW ; +C 88 ; WX 515 ; N X ; B 30 7 486 463 ; L X XX ; +C 89 ; WX 544 ; N Y ; B 30 -7 514 477 ; L Y YY ; +C 90 ; WX 544 ; N Z ; B 30 -7 514 477 ; L Z ZZ ; +C 97 ; WX 660 ; N a ; B 30 -65 630 535 ; L a aa ; +C 98 ; WX 660 ; N b ; B 30 -65 630 535 ; L b bb ; +C 99 ; WX 660 ; N c ; B 30 -65 630 535 ; L c cc ; +C 100 ; WX 660 ; N d ; B 30 -65 630 535 ; L d dd ; +C 101 ; WX 703 ; N e ; B 30 -77 673 565 ; L e ee ; +C 102 ; WX 703 ; N f ; B 30 -95 673 547 ; L f ff ; +C 103 ; WX 703 ; N g ; B 30 -77 673 565 ; L g gg ; +C 104 ; WX 703 ; N h ; B 30 -95 673 547 ; L h hh ; +C 105 ; WX 662 ; N i ; B 30 -86 632 578 ; L i ii ; +C 106 ; WX 656 ; N j ; B 30 -108 626 556 ; L j jj ; +C 107 ; WX 662 ; N k ; B 30 -86 632 578 ; L k kk ; +C 108 ; WX 656 ; N l ; B 30 -108 626 556 ; L l ll ; +C 128 ; WX 1035 ; N AA ; B 30 -65 1005 535 ; L A AAA ; +C 129 ; WX 1407 ; N AAA ; B 30 -65 1377 535 ; +C 130 ; WX 1035 ; N BB ; B 30 -65 1005 535 ; L B BBB ; +C 131 ; WX 1407 ; N BBB ; B 30 -65 1377 535 ; +C 132 ; WX 1035 ; N CC ; B 30 -65 1005 535 ; L C CCC ; +C 133 ; WX 1407 ; N CCC ; B 30 -65 1377 535 ; +C 134 ; WX 1035 ; N DD ; B 30 -65 1005 535 ; L D DDD ; +C 135 ; WX 1407 ; N DDD ; B 30 -65 1377 535 ; +C 136 ; WX 1078 ; N EE ; B 30 -86 1048 556 ; L E EEE ; +C 137 ; WX 1450 ; N EEE ; B 30 -86 1420 556 ; +C 138 ; WX 1078 ; N FF ; B 30 -86 1048 556 ; L F FFF ; +C 139 ; WX 1450 ; N FFF ; B 30 -86 1420 556 ; +C 140 ; WX 1078 ; N GG ; B 30 -86 1048 556 ; L G GGG ; +C 141 ; WX 1450 ; N GGG ; B 30 -86 1420 556 ; +C 142 ; WX 1078 ; N HH ; B 30 -86 1048 556 ; L H HHH ; +C 143 ; WX 1450 ; N HHH ; B 30 -86 1420 556 ; +C 144 ; WX 1058 ; N II ; B 30 -66 1028 536 ; L I III ; +C 145 ; WX 1391 ; N III ; B 30 -66 1361 536 ; +C 146 ; WX 1021 ; N JJ ; B 30 -66 991 536 ; L J JJJ ; +C 147 ; WX 1354 ; N JJJ ; B 30 -66 1324 536 ; +C 148 ; WX 1058 ; N KK ; B 30 -66 1028 536 ; L K KKK ; +C 149 ; WX 1391 ; N KKK ; B 30 -66 1361 536 ; +C 150 ; WX 1021 ; N LL ; B 30 -66 991 536 ; L L LLL ; +C 151 ; WX 1354 ; N LLL ; B 30 -66 1324 536 ; +C 152 ; WX 660 ; N MM ; B 30 -65 630 535 ; L M MMM ; +C 153 ; WX 910 ; N MMM ; B 30 -190 880 660 ; +C 154 ; WX 660 ; N NN ; B 30 -65 630 535 ; L N NNN ; +C 155 ; WX 910 ; N NNN ; B 30 -190 880 660 ; +C 156 ; WX 660 ; N OO ; B 30 -65 630 535 ; L O OOO ; +C 157 ; WX 910 ; N OOO ; B 30 -190 880 660 ; +C 158 ; WX 660 ; N PP ; B 30 -65 630 535 ; L P PPP ; +C 159 ; WX 910 ; N PPP ; B 30 -190 880 660 ; +C 160 ; WX 660 ; N QQ ; B 30 -65 630 535 ; L Q QQQ ; +C 161 ; WX 910 ; N QQQ ; B 30 -190 880 660 ; +C 162 ; WX 660 ; N RR ; B 30 -65 630 535 ; L R RRR ; +C 163 ; WX 910 ; N RRR ; B 30 -190 880 660 ; +C 164 ; WX 660 ; N SS ; B 30 -65 630 535 ; L S SSS ; +C 165 ; WX 910 ; N SSS ; B 30 -190 880 660 ; +C 166 ; WX 662 ; N TT ; B 30 -66 632 536 ; L T TTT ; +C 167 ; WX 912 ; N TTT ; B 30 -191 882 661 ; +C 168 ; WX 660 ; N UU ; B 30 -65 630 535 ; L U UUU ; +C 169 ; WX 910 ; N UUU ; B 30 -190 880 660 ; +C 170 ; WX 660 ; N VV ; B 30 -65 630 535 ; L V VVV ; +C 171 ; WX 910 ; N VVV ; B 30 -190 880 660 ; +C 172 ; WX 869 ; N WW ; B 30 -170 840 640 ; L W WWW ; +C 173 ; WX 1221 ; N WWW ; B 30 -346 1192 816 ; +C 174 ; WX 869 ; N XX ; B 30 -170 840 640 ; L X XXX ; +C 175 ; WX 1221 ; N XXX ; B 30 -346 1192 816 ; +C 176 ; WX 898 ; N YY ; B 30 -184 868 654 ; L Y YYY ; +C 177 ; WX 1252 ; N YYY ; B 30 -361 1222 831 ; +C 178 ; WX 898 ; N ZZ ; B 30 -184 868 654 ; L Z ZZZ ; +C 179 ; WX 1252 ; N ZZZ ; B 30 -361 1222 831 ; +C 180 ; WX 660 ; N aa ; B 30 -252 630 723 ; L a aaa ; +C 181 ; WX 660 ; N aaa ; B 30 -438 630 908 ; +C 182 ; WX 660 ; N bb ; B 30 -252 630 723 ; L b bbb ; +C 183 ; WX 660 ; N bbb ; B 30 -438 630 908 ; +C 184 ; WX 660 ; N cc ; B 30 -252 630 723 ; L c ccc ; +C 185 ; WX 660 ; N ccc ; B 30 -438 630 908 ; +C 186 ; WX 660 ; N dd ; B 30 -252 630 723 ; L d ddd ; +C 187 ; WX 660 ; N ddd ; B 30 -438 630 908 ; +C 188 ; WX 703 ; N ee ; B 30 -265 673 753 ; L e eee ; +C 189 ; WX 702 ; N eee ; B 30 -451 672 939 ; +C 190 ; WX 703 ; N ff ; B 30 -283 673 735 ; L f fff ; +C 191 ; WX 702 ; N fff ; B 30 -469 672 921 ; +C 192 ; WX 703 ; N gg ; B 30 -265 673 753 ; L g ggg ; +C 193 ; WX 702 ; N ggg ; B 30 -451 672 939 ; +C 194 ; WX 703 ; N hh ; B 30 -283 673 735 ; L h hhh ; +C 195 ; WX 702 ; N hhh ; B 30 -469 672 921 ; +C 196 ; WX 662 ; N ii ; B 30 -253 632 745 ; L i iii ; +C 197 ; WX 663 ; N iii ; B 30 -418 633 911 ; +C 198 ; WX 662 ; N jj ; B 30 -275 632 723 ; L j jjj ; +C 199 ; WX 663 ; N jjj ; B 30 -441 633 888 ; +C 200 ; WX 662 ; N kk ; B 30 -253 632 745 ; L k kkk ; +C 201 ; WX 663 ; N kkk ; B 30 -418 633 911 ; +C 202 ; WX 662 ; N ll ; B 30 -275 632 723 ; L l lll ; +C 203 ; WX 663 ; N lll ; B 30 -441 633 888 ; +C 204 ; WX 1160 ; N A.alt ; B 30 -65 1130 535 ; +C 205 ; WX 1160 ; N B.alt ; B 30 -65 1130 535 ; +C 206 ; WX 1160 ; N C.alt ; B 30 -65 1130 535 ; +C 207 ; WX 1160 ; N D.alt ; B 30 -65 1130 535 ; +C 208 ; WX 1203 ; N E.alt ; B 30 -86 1173 556 ; +C 209 ; WX 1203 ; N F.alt ; B 30 -86 1173 556 ; +C 210 ; WX 1203 ; N G.alt ; B 30 -86 1173 556 ; +C 211 ; WX 1203 ; N H.alt ; B 30 -86 1173 556 ; +C 212 ; WX 1223 ; N I.alt ; B 30 -67 1193 537 ; +C 213 ; WX 1186 ; N J.alt ; B 30 -67 1156 537 ; +C 214 ; WX 1223 ; N K.alt ; B 30 -67 1193 537 ; +C 215 ; WX 1186 ; N L.alt ; B 30 -67 1156 537 ; +C -1 ; WX 333 ; N nbspace ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/fonts/afm/jmn/hans/hans.afm b/fonts/afm/jmn/hans/hans.afm new file mode 100644 index 000000000..5defa752e --- /dev/null +++ b/fonts/afm/jmn/hans/hans.afm @@ -0,0 +1,164 @@ +StartFontMetrics 2.0 +Generated by MetaType1 (a MetaPost-based engine) +Comment Creation Date: 18.08.2004 +Notice Design by Janusz M. Nowacki, 2004. +FontName Hans-Regular +FullName Hans-Regular +FamilyName Hans +Weight Normal +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -200 +UnderlineThickness 40 +Version 1.0 +EncodingScheme FontSpecific +FontBBox 0 -406 1352 906 +CapHeight 700 +XHeight 500 +Descender -200 +Ascender 700 +Comment TFM designsize: 10 (in points) +Comment TFM fontdimen 1: 0 (slant) +Comment TFM fontdimen 2: 3.33 (space) +Comment TFM fontdimen 3: 1.67 (space stretch) +Comment TFM fontdimen 4: 1.11 (space shrink) +Comment TFM fontdimen 5: 5 (xheight) +Comment TFM fontdimen 6: 10 (quad) +Comment TFM fontdimen 7: 1.11 (extra space) +Comment TFM fontdimen 8: 0.4 (math rule) +Comment TFM fontdimen 22: 2.5 (math axis) +Comment TFM headerbyte 9: FontSpecific +Comment TFM headerbyte 49: Hans +Comment TFM headerbyte 72: 234 +StartCharMetrics 129 +C 32 ; WX 333 ; N space ; B 0 0 0 0 ; +C 64 ; WX 580 ; N at ; B 40 0 540 500 ; +C 65 ; WX 620 ; N A ; B 40 -20 580 520 ; L A AA ; L at A.alt ; +C 66 ; WX 620 ; N B ; B 40 -20 580 520 ; L B BB ; L at B.alt ; +C 67 ; WX 620 ; N C ; B 40 -20 580 520 ; L C CC ; L at C.alt ; +C 68 ; WX 620 ; N D ; B 40 -20 580 520 ; L D DD ; L at D.alt ; +C 69 ; WX 645 ; N E ; B 40 -32 605 532 ; L E EE ; L at E.alt ; +C 70 ; WX 645 ; N F ; B 40 -32 605 532 ; L F FF ; L at F.alt ; +C 71 ; WX 645 ; N G ; B 40 -32 605 532 ; L G GG ; L at G.alt ; +C 72 ; WX 645 ; N H ; B 40 -32 605 532 ; L H HH ; L at H.alt ; +C 73 ; WX 652 ; N I ; B 40 -17 612 517 ; L I II ; L at I.alt ; +C 74 ; WX 652 ; N J ; B 40 -17 612 517 ; L J JJ ; L at J.alt ; +C 75 ; WX 652 ; N K ; B 40 -17 612 517 ; L K KK ; L at K.alt ; +C 76 ; WX 652 ; N L ; B 40 -17 612 517 ; L L LL ; L at L.alt ; +C 77 ; WX 370 ; N M ; B 40 105 330 395 ; L M MM ; +C 78 ; WX 370 ; N N ; B 40 105 330 395 ; L N NN ; +C 79 ; WX 370 ; N O ; B 40 105 330 395 ; L O OO ; +C 80 ; WX 370 ; N P ; B 40 105 330 395 ; L P PP ; +C 81 ; WX 370 ; N Q ; B 40 105 330 395 ; L Q QQ ; +C 82 ; WX 370 ; N R ; B 40 105 330 395 ; L R RR ; +C 83 ; WX 370 ; N S ; B 40 105 330 395 ; L S SS ; +C 84 ; WX 358 ; N T ; B 40 111 318 389 ; L T TT ; +C 85 ; WX 370 ; N U ; B 40 105 330 395 ; L U UU ; +C 86 ; WX 370 ; N V ; B 40 105 330 395 ; L V VV ; +C 87 ; WX 474 ; N W ; B 40 53 434 447 ; L W WW ; +C 88 ; WX 474 ; N X ; B 40 53 434 447 ; L X XX ; +C 89 ; WX 490 ; N Y ; B 40 45 450 455 ; L Y YY ; +C 90 ; WX 490 ; N Z ; B 40 45 450 455 ; L Z ZZ ; +C 97 ; WX 620 ; N a ; B 40 -20 580 520 ; L a aa ; +C 98 ; WX 620 ; N b ; B 40 -20 580 520 ; L b bb ; +C 99 ; WX 620 ; N c ; B 40 -20 580 520 ; L c cc ; +C 100 ; WX 620 ; N d ; B 40 -20 580 520 ; L d dd ; +C 101 ; WX 645 ; N e ; B 40 -32 605 532 ; L e ee ; +C 102 ; WX 645 ; N f ; B 40 -32 605 532 ; L f ff ; +C 103 ; WX 645 ; N g ; B 40 -32 605 532 ; L g gg ; +C 104 ; WX 645 ; N h ; B 40 -32 605 532 ; L h hh ; +C 105 ; WX 614 ; N i ; B 40 -36 574 536 ; L i ii ; +C 106 ; WX 614 ; N j ; B 40 -36 574 536 ; L j jj ; +C 107 ; WX 614 ; N k ; B 40 -36 574 536 ; L k kk ; +C 108 ; WX 614 ; N l ; B 40 -36 574 536 ; L l ll ; +C 128 ; WX 995 ; N AA ; B 40 -20 955 520 ; L A AAA ; +C 129 ; WX 1367 ; N AAA ; B 40 -20 1327 520 ; +C 130 ; WX 995 ; N BB ; B 40 -20 955 520 ; L B BBB ; +C 131 ; WX 1367 ; N BBB ; B 40 -20 1327 520 ; +C 132 ; WX 995 ; N CC ; B 40 -20 955 520 ; L C CCC ; +C 133 ; WX 1367 ; N CCC ; B 40 -20 1327 520 ; +C 134 ; WX 995 ; N DD ; B 40 -20 955 520 ; L D DDD ; +C 135 ; WX 1367 ; N DDD ; B 40 -20 1327 520 ; +C 136 ; WX 1020 ; N EE ; B 40 -32 980 532 ; L E EEE ; +C 137 ; WX 1391 ; N EEE ; B 40 -32 1352 532 ; +C 138 ; WX 1020 ; N FF ; B 40 -32 980 532 ; L F FFF ; +C 139 ; WX 1391 ; N FFF ; B 40 -32 1352 532 ; +C 140 ; WX 1020 ; N GG ; B 40 -32 980 532 ; L G GGG ; +C 141 ; WX 1391 ; N GGG ; B 40 -32 1352 532 ; +C 142 ; WX 1020 ; N HH ; B 40 -32 980 532 ; L H HHH ; +C 143 ; WX 1391 ; N HHH ; B 40 -32 1352 532 ; +C 144 ; WX 985 ; N II ; B 40 -17 946 517 ; L I III ; +C 145 ; WX 1319 ; N III ; B 40 -17 1279 517 ; +C 146 ; WX 985 ; N JJ ; B 40 -17 946 517 ; L J JJJ ; +C 147 ; WX 1319 ; N JJJ ; B 40 -17 1279 517 ; +C 148 ; WX 985 ; N KK ; B 40 -17 946 517 ; L K KKK ; +C 149 ; WX 1319 ; N KKK ; B 40 -17 1279 517 ; +C 150 ; WX 985 ; N LL ; B 40 -17 946 517 ; L L LLL ; +C 151 ; WX 1319 ; N LLL ; B 40 -17 1279 517 ; +C 152 ; WX 620 ; N MM ; B 40 -20 580 520 ; L M MMM ; +C 153 ; WX 870 ; N MMM ; B 40 -145 830 645 ; +C 154 ; WX 620 ; N NN ; B 40 -20 580 520 ; L N NNN ; +C 155 ; WX 870 ; N NNN ; B 40 -145 830 645 ; +C 156 ; WX 620 ; N OO ; B 40 -20 580 520 ; L O OOO ; +C 157 ; WX 870 ; N OOO ; B 40 -145 830 645 ; +C 158 ; WX 620 ; N PP ; B 40 -20 580 520 ; L P PPP ; +C 159 ; WX 870 ; N PPP ; B 40 -145 830 645 ; +C 160 ; WX 620 ; N QQ ; B 40 -20 580 520 ; L Q QQQ ; +C 161 ; WX 870 ; N QQQ ; B 40 -145 830 645 ; +C 162 ; WX 620 ; N RR ; B 40 -20 580 520 ; L R RRR ; +C 163 ; WX 870 ; N RRR ; B 40 -145 830 645 ; +C 164 ; WX 620 ; N SS ; B 40 -20 580 520 ; L S SSS ; +C 165 ; WX 870 ; N SSS ; B 40 -145 830 645 ; +C 166 ; WX 608 ; N TT ; B 40 -14 568 514 ; L T TTT ; +C 167 ; WX 858 ; N TTT ; B 40 -139 818 639 ; +C 168 ; WX 620 ; N UU ; B 40 -20 580 520 ; L U UUU ; +C 169 ; WX 870 ; N UUU ; B 40 -145 830 645 ; +C 170 ; WX 620 ; N VV ; B 40 -20 580 520 ; L V VVV ; +C 171 ; WX 870 ; N VVV ; B 40 -145 830 645 ; +C 172 ; WX 827 ; N WW ; B 40 -124 788 624 ; L W WWW ; +C 173 ; WX 1181 ; N WWW ; B 40 -300 1140 800 ; +C 174 ; WX 827 ; N XX ; B 40 -124 788 624 ; L X XXX ; +C 175 ; WX 1181 ; N XXX ; B 40 -300 1140 800 ; +C 176 ; WX 844 ; N YY ; B 40 -132 804 632 ; L Y YYY ; +C 177 ; WX 1197 ; N YYY ; B 40 -309 1158 809 ; +C 178 ; WX 844 ; N ZZ ; B 40 -132 804 632 ; L Z ZZZ ; +C 179 ; WX 1197 ; N ZZZ ; B 40 -309 1158 809 ; +C 180 ; WX 620 ; N aa ; B 41 -207 581 708 ; L a aaa ; +C 181 ; WX 620 ; N aaa ; B 40 -393 580 893 ; +C 182 ; WX 620 ; N bb ; B 41 -207 581 708 ; L b bbb ; +C 183 ; WX 620 ; N bbb ; B 40 -393 580 893 ; +C 184 ; WX 620 ; N cc ; B 41 -207 581 708 ; L c ccc ; +C 185 ; WX 620 ; N ccc ; B 40 -393 580 893 ; +C 186 ; WX 620 ; N dd ; B 41 -207 581 708 ; L d ddd ; +C 187 ; WX 620 ; N ddd ; B 40 -393 580 893 ; +C 188 ; WX 645 ; N ee ; B 40 -220 605 720 ; L e eee ; +C 189 ; WX 645 ; N eee ; B 40 -406 604 906 ; +C 190 ; WX 645 ; N ff ; B 40 -220 605 720 ; L f fff ; +C 191 ; WX 645 ; N fff ; B 40 -406 604 906 ; +C 192 ; WX 645 ; N gg ; B 40 -220 605 720 ; L g ggg ; +C 193 ; WX 645 ; N ggg ; B 40 -406 604 906 ; +C 194 ; WX 645 ; N hh ; B 40 -220 605 720 ; L h hhh ; +C 195 ; WX 645 ; N hhh ; B 40 -406 604 906 ; +C 196 ; WX 614 ; N ii ; B 40 -203 574 703 ; L i iii ; +C 197 ; WX 614 ; N iii ; B 40 -369 574 869 ; +C 198 ; WX 614 ; N jj ; B 40 -203 574 703 ; L j jjj ; +C 199 ; WX 614 ; N jjj ; B 40 -369 574 869 ; +C 200 ; WX 614 ; N kk ; B 40 -203 574 703 ; L k kkk ; +C 201 ; WX 614 ; N kkk ; B 40 -369 574 869 ; +C 202 ; WX 614 ; N ll ; B 40 -203 574 703 ; L l lll ; +C 203 ; WX 614 ; N lll ; B 40 -369 574 869 ; +C 204 ; WX 1120 ; N A.alt ; B 40 -20 1080 520 ; +C 205 ; WX 1120 ; N B.alt ; B 40 -20 1080 520 ; +C 206 ; WX 1120 ; N C.alt ; B 40 -20 1080 520 ; +C 207 ; WX 1120 ; N D.alt ; B 40 -20 1080 520 ; +C 208 ; WX 1145 ; N E.alt ; B 40 -32 1105 532 ; +C 209 ; WX 1145 ; N F.alt ; B 40 -32 1105 532 ; +C 210 ; WX 1145 ; N G.alt ; B 40 -32 1105 532 ; +C 211 ; WX 1145 ; N H.alt ; B 40 -32 1105 532 ; +C 212 ; WX 1156 ; N I.alt ; B 40 -17 1116 517 ; +C 213 ; WX 1156 ; N J.alt ; B 40 -17 1116 517 ; +C 214 ; WX 1156 ; N K.alt ; B 40 -17 1116 517 ; +C 215 ; WX 1156 ; N L.alt ; B 40 -17 1116 517 ; +C -1 ; WX 333 ; N nbspace ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/fonts/cid/fontforge/Adobe-CNS1-4.cidmap b/fonts/cid/fontforge/Adobe-CNS1-4.cidmap new file mode 100644 index 000000000..1a214e2af --- /dev/null +++ b/fonts/cid/fontforge/Adobe-CNS1-4.cidmap @@ -0,0 +1,17467 @@ +18964 18964 +0 /.notdef +1..95 0020 +99 3000 +100 ff0c +101..102 3001 +103 ff0e +104 2022 +105 ff1b +106 ff1a +107 ff1f +108 ff01 +109 fe30 +110 2026 +111 2025 +112 fe50 +113 ff64 +114 fe52 +115 00b7 +116..119 fe54 +120 ff5c +121 /CNS1.120.vert +122 fe31 +123 /CNS1.122.vert +125 /CNS1.124.vert +127 /CNS1.126.vert +128..129 ff08 +130 /CNS1.128.vert +131 /CNS1.129.vert +132 ff5b +133 ff5d +134 /CNS1.132.vert +135 /CNS1.133.vert +136..137 3014 +138 /CNS1.136.vert +139 /CNS1.137.vert +140..141 3010 +142 /CNS1.140.vert +143 /CNS1.141.vert +144..145 300a +146 /CNS1.144.vert +147 /CNS1.145.vert +148..149 3008 +150 /CNS1.148.vert +151 /CNS1.149.vert +152..153 300c +154 /CNS1.152.vert +155 /CNS1.153.vert +156..157 300e +158 /CNS1.156.vert +159 /CNS1.157.vert +160..165 fe59 +166..167 2018 +168..169 201c +170..171 301d +172 2035 +173 2032 +174 ff03 +175 ff06 +176 ff0a +177 203b +178 00a7 +179 3003 +180 25cb +181 25cf +182 25b3 +183 25b2 +184 25ce +185 2606 +186 2605 +187 25c7 +188 25c6 +189 25a1 +190 25a0 +191 25bd +192 25bc +193 32a3 +194 2105 +195 00af +196 ffe3 +197 ff3f +198 02cd +199..200 fe49 +201..202 fe4d +203..204 fe4b +205..207 fe5f +208 ff0b +209 ff0d +210 00d7 +211 00f7 +212 00b1 +213 221a +214 ff1c +215 ff1e +216 ff1d +217..218 2266 +219 2260 +220 221e +221 2252 +222 2261 +223..227 fe62 +228 223c +229..230 2229 +231 22a5 +232 2220 +233 221f +234 22bf +235 33d2 +236 33d1 +237 222b +238 222e +239 2235 +240 2234 +241 2640 +242 2642 +243 2295 +244 2299 +245 2191 +246 2193 +247 2192 +248 2190 +249..250 2196 +251 2199 +252 2198 +253 2225 +254 2223 +257 2215 +258 fe68 +259 ff04 +260 00a5 +261 3012 +262..263 00a2 +264 ff05 +265 ff20 +266 2103 +267 2109 +268..270 fe69 +271 33d5 +272..274 339c +275 33ce +276 33a1 +277..278 338e +279 33c4 +280 00b0 +281 5159 +282 515b +283 515e +284 515d +285 5161 +286 5163 +287 55e7 +288 74e9 +289 7cce +290..297 2581 +298 258f +299 258e +300 258d +301 258c +302 258b +303 258a +304 2589 +305 253c +306 2534 +307 252c +308 2524 +309 251c +310 2594 +311 2500 +312 2502 +313 2595 +314 250c +315 2510 +316 2514 +317 2518 +318..319 256d +320 2570 +321 256f +322 2550 +323 255e +324 256a +325 2561 +326..327 25e2 +328 25e5 +329 25e4 +330..332 2571 +333..342 ff10 +343..352 2160 +353..361 3021 +362 3038 +363 5344 +364 303a +365..390 ff21 +391..416 ff41 +417..433 0391 +434..440 03a3 +441..457 03b1 +458..464 03c3 +465..501 3105 +502 02d9 +503 02ca +504 02c7 +505 02cb +506..515 2460 +516..525 2474 +526..535 2170 +536 4e28 +537 4e36 +538 4e3f +539 4e85 +540 4ea0 +541 5182 +542 5196 +543 51ab +544 52f9 +545 5338 +546 5369 +547 53b6 +548 5902 +549 5b80 +550 5ddb +551 5e7a +552 5e7f +553 5ef4 +554 5f50 +555 5f61 +556 6534 +557 65e0 +558 7592 +559 7676 +560 8fb5 +561 96b6 +562..593 2400 +594 2421 +595 4e00 +596 4e59 +597 4e01 +598 4e03 +599 4e43 +600 4e5d +601 4e86 +602 4e8c +603 4eba +604 513f +605 5165 +606 516b +607 51e0 +608..609 5200 +610 529b +611 5315 +612 5341 +613 535c +614 53c8 +615 4e09 +616 4e0b +617 4e08 +618 4e0a +619 4e2b +620 4e38 +621 51e1 +622 4e45 +623 4e48 +624 4e5f +625 4e5e +626 4e8e +627 4ea1 +628 5140 +629 5203 +630 52fa +631 5343 +632 53c9 +633 53e3 +634 571f +635 58eb +636 5915 +637 5927 +638 5973 +639..640 5b50 +641 5b53 +642 5bf8 +643 5c0f +644 5c22 +645 5c38 +646 5c71 +647 5ddd +648 5de5 +649..651 5df1 +652 5dfe +653 5e72 +654 5efe +655 5f0b +656 5f13 +657 624d +658 4e11 +659 4e10 +660 4e0d +661 4e2d +662 4e30 +663 4e39 +664 4e4b +665 5c39 +666 4e88 +667 4e91 +668 4e95 +669 4e92 +670 4e94 +671 4ea2 +672 4ec1 +673 4ec0 +674 4ec3 +675..676 4ec6 +677 4ecd +678..679 4eca +680 4ec4 +681 5143 +682 5141 +683 5167 +684..685 516d +686 516c +687 5197 +688 51f6 +689..691 5206 +692 52fb +693..694 52fe +695 5316 +696 5339 +697 5348 +698 5347 +699 5345 +700 535e +701 5384 +702 53cb +703 53ca +704 53cd +705 58ec +706 5929 +707 592b +708 592a +709 592d +710 5b54 +711 5c11 +712 5c24 +713 5c3a +714 5c6f +715 5df4 +716 5e7b +717 5eff +718..719 5f14 +720 5fc3 +721 6208 +722 6236 +723 624b +724 624e +725 652f +726 6587 +727 6597 +728 65a4 +729 65b9 +730 65e5 +731 66f0 +732 6708 +733 6728 +734 6b20 +735 6b62 +736 6b79 +737 6bcb +738 6bd4 +739 6bdb +740 6c0f +741 6c34 +742 706b +743 722a +744 7236 +745 723b +746 7247 +747 7259 +748 725b +749 72ac +750 738b +751 4e19 +752 4e16 +753 4e15 +754 4e14 +755 4e18 +756 4e3b +757 4e4d +758 4e4f +759 4e4e +760 4ee5 +761 4ed8 +762..765 4ed4 +766..767 4ee3 +768 4ed9 +769 4ede +770 5145 +771 5144 +772..773 5189 +774 51ac +775..776 51f9 +777 51f8 +778 520a +779 52a0 +780 529f +781 e05b +782 5306 +783 5317 +784 531d +785 4edf +786 534a +787 5349 +788 5361 +789 5360 +790 536f +791 536e +792 53bb +793 53ef +794 53e4 +795 53f3 +796 53ec +797 53ee +798 53e9 +799 53e8 +800 53fc +801 53f8 +802 53f5 +803 53eb +804 53e6 +805 53ea +806 53f2 +807 53f1 +808 53f0 +809 53e5 +810 53ed +811 53fb +812 56db +813 56da +814 5916 +815 592e +816 5931 +817 5974 +818 5976 +819 5b55 +820 5b83 +821 5c3c +822 5de8 +823 5de7 +824 5de6 +825..826 5e02 +827 5e73 +828 5e7c +829 5f01 +830 5f18 +831 5f17 +832 5fc5 +833 620a +834..835 6253 +836 6252 +837 6251 +838 65a5 +839 65e6 +840 672e +841 672c +842..843 672a +844 672d +845 6b63 +846 6bcd +847 6c11 +848 6c10 +849 6c38 +850 6c41 +851 6c40 +852 6c3e +853 72af +854 7384 +855 7389 +856 74dc +857 74e6 +858 7518 +859 751f +860..861 7528 +862..865 7530 +866 758b +867 767d +868 76ae +869 76bf +870 76ee +871 77db +872 77e2 +873 77f3 +874 793a +875 79be +876 7a74 +877 7acb +878..879 4e1e +880..881 4e52 +882 4e69 +883 4e99 +884 4ea4 +885 4ea6 +886 4ea5 +887 4eff +888 4f09 +889 4f19 +890 4f0a +891 4f15 +892 4f0d +893..894 4f10 +895 4f0f +896 4ef2 +897 4ef6 +898 4efb +899 4ef0 +900 4ef3 +901 4efd +902 4f01 +903 4f0b +904 5149 +905 5147 +906 5146 +907 5148 +908 5168 +909 5171 +910 518d +911 51b0 +912 5217 +913..914 5211 +915 520e +916 5216 +917 52a3 +918 5308 +919 5321 +920 5320 +921..922 5370 +923 5409 +924 540f +925 540c +926 540a +927 5410 +928 5401 +929 540b +930 5404 +931 5411 +932 540d +933 5408 +934 5403 +935 540e +936 5406 +937 5412 +938 56e0 +939 56de +940 56dd +941 5733 +942 5730 +943 5728 +944 572d +945 572c +946 572f +947 5729 +948..949 5919 +950..951 5937 +952 5984 +953 5978 +954 5983 +955 597d +956 5979 +957 5982 +958 5981 +959..960 5b57 +961..962 5b87 +963 5b85 +964 5b89 +965 5bfa +966 5c16 +967 5c79 +968 5dde +969 5e06 +970 5e76 +971 5e74 +972 5f0f +973 5f1b +974 5fd9 +975 5fd6 +976 620e +977..978 620c +979 6210 +980 6263 +981 625b +982 6258 +983 6536 +984 65e9 +985 65e8 +986..987 65ec +988..989 66f2 +990 6709 +991 673d +992 6734 +993 6731 +994 6735 +995 6b21 +996 6b64 +997 6b7b +998 6c16 +999 6c5d +1000 6c57 +1001 6c59 +1002..1003 6c5f +1004 6c50 +1005 6c55 +1006 6c61 +1007 6c5b +1008..1009 6c4d +1010 7070 +1011 725f +1012 725d +1013 767e +1014 7af9 +1015 7c73 +1016 7cf8 +1017 7f36 +1018 7f8a +1019 7fbd +1020 8001 +1021 8003 +1022 800c +1023 8012 +1024 8033 +1025 807f +1026 8089 +1027..1028 808b +1029 81e3 +1030 81ea +1031 81f3 +1032 81fc +1033 820c +1034 821b +1035 821f +1036 826e +1037 8272 +1038 827e +1039 866b +1040 8840 +1041 884c +1042 8863 +1043 897f +1044 9621 +1045 4e32 +1046 4ea8 +1047 4f4d +1048 4f4f +1049 4f47 +1050 4f57 +1051 4f5e +1052 4f34 +1053 4f5b +1054 4f55 +1055 4f30 +1056..1057 4f50 +1058 4f3d +1059 4f3a +1060 4f38 +1061 4f43 +1062 4f54 +1063 4f3c +1064 4f46 +1065 4f63 +1066 4f5c +1067 4f60 +1068 4f2f +1069 4f4e +1070 4f36 +1071 4f59 +1072 4f5d +1073 4f48 +1074 4f5a +1075 514c +1076 514b +1077 514d +1078 5175 +1079..1080 51b6 +1081 5225 +1082 5224 +1083..1084 5229 +1085 5228 +1086 52ab +1087..1088 52a9 +1089 52ac +1090 5323 +1091 5373 +1092 5375 +1093 541d +1094 542d +1095 541e +1096 543e +1097 5426 +1098 544e +1099 5427 +1100 5446 +1101 5443 +1102 5433 +1103 5448 +1104 5442 +1105 541b +1106 5429 +1107 544a +1108 5439 +1109 543b +1110 5438 +1111 542e +1112..1113 5435 +1114 5420 +1115 543c +1116 5440 +1117 5431 +1118 542b +1119 541f +1120 542c +1121 56ea +1122 56f0 +1123 56e4 +1124 56eb +1125 574a +1126 5751 +1127 5740 +1128 574d +1129 5747 +1130 574e +1131 573e +1132 5750 +1133 574f +1134 573b +1135 58ef +1136 593e +1137 599d +1138 5992 +1139 59a8 +1140 599e +1141 59a3 +1142 5999 +1143 5996 +1144 598d +1145 59a4 +1146 5993 +1147 598a +1148 59a5 +1149 5b5d +1150 5b5c +1151..1152 5b5a +1153 5b8c +1154 5b8b +1155 5b8f +1156 5c2c +1157..1158 5c40 +1159 5c3f +1160 5c3e +1161..1162 5c90 +1163 5c94 +1164 5c8c +1165 5deb +1166 5e0c +1167 5e8f +1168 5e87 +1169 5e8a +1170 5ef7 +1171 5f04 +1172 5f1f +1173 5f64 +1174 5f62 +1175 5f77 +1176 5f79 +1177 5fd8 +1178 5fcc +1179 5fd7 +1180 5fcd +1181 5ff1 +1182 5feb +1183 5ff8 +1184 5fea +1185 6212 +1186 6211 +1187 6284 +1188 6297 +1189 6296 +1190 6280 +1191 6276 +1192 6289 +1193 626d +1194 628a +1195 627c +1196 627e +1197 6279 +1198 6273 +1199 6292 +1200 626f +1201 6298 +1202 626e +1203 6295 +1204 6293 +1205 6291 +1206 6286 +1207 6539 +1208 653b +1209 6538 +1210 65f1 +1211 66f4 +1212 675f +1213..1216 674e +1217 675c +1218 6756 +1219 675e +1220 6749 +1221 6746 +1222 6760 +1223 6753 +1224 6757 +1225 6b65 +1226 6bcf +1227 6c42 +1228 6c5e +1229 6c99 +1230 6c81 +1231..1232 6c88 +1233 6c85 +1234 6c9b +1235 6c6a +1236 6c7a +1237 6c90 +1238 6c70 +1239 6c8c +1240 6c68 +1241 6c96 +1242 6c92 +1243 6c7d +1244 6c83 +1245 6c72 +1246 6c7e +1247 6c74 +1248 6c86 +1249 6c76 +1250 6c8d +1251 6c94 +1252 6c98 +1253 6c82 +1254 7076 +1255..1256 707c +1257 7078 +1258 7262 +1259 7261 +1260 7260 +1261 72c4 +1262 72c2 +1263 7396 +1264 752c +1265 752b +1266..1267 7537 +1268 7682 +1269 76ef +1270 77e3 +1271 79c1 +1272 79c0 +1273 79bf +1274 7a76 +1275 7cfb +1276 7f55 +1277 8096 +1278 8093 +1279 809d +1280 8098 +1281 809b +1282 809a +1283 80b2 +1284 826f +1285 8292 +1286 828b +1287 828d +1288 898b +1289 89d2 +1290 8a00 +1291 8c37 +1292 8c46 +1293 8c55 +1294 8c9d +1295 8d64 +1296 8d70 +1297 8db3 +1298 8eab +1299 8eca +1300 8f9b +1301 8fb0 +1302 8fc2 +1303 8fc6 +1304 8fc5 +1305 8fc4 +1306 5de1 +1307 9091 +1308 90a2 +1309 90aa +1310 90a6 +1311 90a3 +1312 9149 +1313 91c6 +1314 91cc +1315 9632 +1316 962e +1317 9631 +1318 962a +1319 962c +1320 4e26 +1321 4e56 +1322 4e73 +1323 4e8b +1324 4e9b +1325 4e9e +1326..1327 4eab +1328 4f6f +1329 4f9d +1330 4f8d +1331 4f73 +1332 4f7f +1333 4f6c +1334 4f9b +1335 4f8b +1336 4f86 +1337 4f83 +1338 4f70 +1339 4f75 +1340 4f88 +1341 4f69 +1342 4f7b +1343 4f96 +1344 4f7e +1345 4f8f +1346 4f91 +1347 4f7a +1348 5154 +1349 5152 +1350 5155 +1351 5169 +1352 5177 +1353 5176 +1354 5178 +1355 51bd +1356 51fd +1357 523b +1358 5238 +1359 5237 +1360 523a +1361 5230 +1362 522e +1363 5236 +1364 5241 +1365 52be +1366 52bb +1367 5352 +1368 5354 +1369 5353 +1370 5351 +1371 5366 +1372..1374 5377 +1375 53d6 +1376 53d4 +1377 53d7 +1378 5473 +1379 5475 +1380 5496 +1381 5478 +1382 5495 +1383 5480 +1384 547b +1385 5477 +1386 5484 +1387 5492 +1388 5486 +1389 547c +1390 5490 +1391 5471 +1392 5476 +1393 548c +1394 549a +1395 5462 +1396 5468 +1397 548b +1398 547d +1399 548e +1400 56fa +1401 5783 +1402 5777 +1403 576a +1404 5769 +1405 5761 +1406 5766 +1407 5764 +1408 577c +1409 591c +1410 5949 +1411..1412 5947 +1413 5944 +1414 5954 +1415 59be +1416 59bb +1417 59d4 +1418 59b9 +1419 59ae +1420 59d1 +1421 59c6 +1422 59d0 +1423 59cd +1424 59cb +1425 59d3 +1426 59ca +1427 59af +1428 59b3 +1429 59d2 +1430 59c5 +1431 5b5f +1432 5b64 +1433 5b63 +1434 5b97 +1435 5b9a +1436 5b98 +1437 5b9c +1438 5b99 +1439 5b9b +1440 5c1a +1441 5c48 +1442..1443 5c45 +1444 5cb7 +1445 5ca1 +1446 5cb8 +1447 5ca9 +1448 5cab +1449 5cb1 +1450 5cb3 +1451 5e18 +1452 5e1a +1453 5e16 +1454 5e15 +1455 5e1b +1456 5e11 +1457 5e78 +1458 5e9a +1459 5e97 +1460 5e9c +1461..1462 5e95 +1463 5ef6 +1464..1465 5f26 +1466 5f29 +1467..1468 5f80 +1469 5f7f +1470 5f7c +1471 5fdd +1472 5fe0 +1473 5ffd +1474 5ff5 +1475 5fff +1476 600f +1477 6014 +1478 602f +1479 6035 +1480 6016 +1481 602a +1482 6015 +1483 6021 +1484 6027 +1485 6029 +1486 602b +1487 601b +1488 6216 +1489 6215 +1490 623f +1491 623e +1492 6240 +1493 627f +1494 62c9 +1495 62cc +1496 62c4 +1497 62bf +1498 62c2 +1499 62b9 +1500 62d2 +1501 62db +1502 62ab +1503..1504 62d3 +1505 62cb +1506 62c8 +1507 62a8 +1508 62bd +1509 62bc +1510 62d0 +1511 62d9 +1512 62c7 +1513 62cd +1514 62b5 +1515 62da +1516 62b1 +1517 62d8 +1518..1519 62d6 +1520 62c6 +1521 62ac +1522 62ce +1523 653e +1524 65a7 +1525 65bc +1526 65fa +1527 6614 +1528 6613 +1529 660c +1530 6606 +1531 6602 +1532 660e +1533 6600 +1534 660f +1535 6615 +1536 660a +1537 6607 +1538 670d +1539 670b +1540 676d +1541 678b +1542 6795 +1543 6771 +1544 679c +1545 6773 +1546 6777 +1547 6787 +1548 679d +1549 6797 +1550..1551 676f +1552 677f +1553 6789 +1554 677e +1555 6790 +1556 6775 +1557 679a +1558 6793 +1559 677c +1560 676a +1561 6772 +1562 6b23 +1563..1564 6b66 +1565 6b7f +1566 6c13 +1567 6c1b +1568 6ce3 +1569 6ce8 +1570 6cf3 +1571 6cb1 +1572 6ccc +1573 6ce5 +1574 6cb3 +1575..1576 6cbd +1577 6cbc +1578 6ce2 +1579 6cab +1580 6cd5 +1581 6cd3 +1582 6cb8 +1583 6cc4 +1584 6cb9 +1585 6cc1 +1586 6cae +1587 6cd7 +1588 6cc5 +1589 6cf1 +1590 6cbf +1591 6cbb +1592 6ce1 +1593 6cdb +1594 6cca +1595 6cac +1596 6cef +1597 6cdc +1598 6cd6 +1599 6ce0 +1600 7095 +1601 708e +1602 7092 +1603 708a +1604 7099 +1605..1606 722c +1607 7238 +1608 7248 +1609 7267 +1610 7269 +1611 72c0 +1612 72ce +1613 72d9 +1614 72d7 +1615 72d0 +1616 73a9 +1617 73a8 +1618 739f +1619 73ab +1620 73a5 +1621 753d +1622 759d +1623..1624 7599 +1625 7684 +1626 76c2 +1627 76f2 +1628 76f4 +1629 77e5 +1630 77fd +1631 793e +1632..1633 7940 +1634 79c9 +1635 79c8 +1636 7a7a +1637 7a79 +1638 7afa +1639 7cfe +1640 7f54 +1641 7f8c +1642 7f8b +1643 8005 +1644 80ba +1645 80a5 +1646 80a2 +1647 80b1 +1648 80a1 +1649 80ab +1650 80a9 +1651 80b4 +1652 80aa +1653 80af +1654 81e5 +1655 81fe +1656 820d +1657 82b3 +1658 829d +1659 8299 +1660 82ad +1661 82bd +1662 829f +1663 82b9 +1664 82b1 +1665 82ac +1666 82a5 +1667 82af +1668 82b8 +1669 82a3 +1670 82b0 +1671 82be +1672 82b7 +1673 864e +1674 8671 +1675 521d +1676 8868 +1677 8ecb +1678 8fce +1679 8fd4 +1680 8fd1 +1681 90b5 +1682 90b8 +1683 90b1 +1684 90b6 +1685 91c7 +1686 91d1 +1687 9577 +1688 9580 +1689 961c +1690 9640 +1691 963f +1692 963b +1693 9644 +1694 9642 +1695 96b9 +1696 96e8 +1697 9752 +1698 975e +1699 4e9f +1700..1701 4ead +1702 4fe1 +1703 4fb5 +1704 4faf +1705 4fbf +1706 4fe0 +1707 4fd1 +1708 4fcf +1709 4fdd +1710 4fc3 +1711 4fb6 +1712 4fd8 +1713 4fdf +1714 4fca +1715 4fd7 +1716 4fae +1717 4fd0 +1718 4fc4 +1719 4fc2 +1720 4fda +1721 4fce +1722 4fde +1723 4fb7 +1724 5157 +1725 5192 +1726 5191 +1727 51a0 +1728 524e +1729 5243 +1730 524a +1731 524d +1732 524c +1733 524b +1734 5247 +1735 52c7 +1736 52c9 +1737 52c3 +1738 52c1 +1739 530d +1740 5357 +1741 537b +1742 539a +1743 53db +1744 54ac +1745 54c0 +1746 54a8 +1747 54ce +1748 54c9 +1749 54b8 +1750 54a6 +1751 54b3 +1752 54c7 +1753 54c2 +1754 54bd +1755 54aa +1756 54c1 +1757 54c4 +1758 54c8 +1759 54af +1760 54ab +1761 54b1 +1762 54bb +1763 54a9 +1764 54a7 +1765 54bf +1766 56ff +1767 5782 +1768 578b +1769 57a0 +1770 57a3 +1771 57a2 +1772 57ce +1773 57ae +1774 5793 +1775 5955 +1776 5951 +1777 594f +1778 594e +1779 5950 +1780 59dc +1781 59d8 +1782 59ff +1783 59e3 +1784 59e8 +1785 5a03 +1786 59e5 +1787 59ea +1788 59da +1789 59e6 +1790 5a01 +1791 59fb +1792 5b69 +1793 5ba3 +1794 5ba6 +1795 5ba4 +1796 5ba2 +1797 5ba5 +1798 5c01 +1799..1800 5c4e +1801 5c4d +1802 5c4b +1803 5cd9 +1804 5cd2 +1805 5df7 +1806 5e1d +1807 5e25 +1808 5e1f +1809 5e7d +1810 5ea0 +1811 5ea6 +1812 5efa +1813 5f08 +1814 5f2d +1815 5f65 +1816 5f88 +1817 5f85 +1818..1819 5f8a +1820 5f87 +1821 5f8c +1822 5f89 +1823 6012 +1824 601d +1825 6020 +1826 6025 +1827 600e +1828 6028 +1829 604d +1830 6070 +1831 6068 +1832 6062 +1833 6046 +1834 6043 +1835 606c +1836 606b +1837 606a +1838 6064 +1839 6241 +1840 62dc +1841 6316 +1842 6309 +1843 62fc +1844 62ed +1845 6301 +1846 62ee +1847 62fd +1848 6307 +1849 62f1 +1850 62f7 +1851 62ef +1852 62ec +1853 62fe +1854 62f4 +1855 6311 +1856 6302 +1857 653f +1858 6545 +1859 65ab +1860 65bd +1861 65e2 +1862 6625 +1863 662d +1864 6620 +1865 6627 +1866 662f +1867 661f +1868 6628 +1869 6631 +1870 6624 +1871 66f7 +1872 67ff +1873 67d3 +1874 67f1 +1875 67d4 +1876 67d0 +1877 67ec +1878 67b6 +1879 67af +1880 67f5 +1881 67e9 +1882 67ef +1883 67c4 +1884 67d1 +1885 67b4 +1886 67da +1887 67e5 +1888 67b8 +1889 67cf +1890 67de +1891 67f3 +1892 67b0 +1893 67d9 +1894 67e2 +1895 67dd +1896 67d2 +1897 6b6a +1898 6b83 +1899 6b86 +1900 6bb5 +1901 6bd2 +1902 6bd7 +1903 6c1f +1904 6cc9 +1905 6d0b +1906 6d32 +1907 6d2a +1908 6d41 +1909 6d25 +1910 6d0c +1911 6d31 +1912 6d1e +1913 6d17 +1914 6d3b +1915..1916 6d3d +1917 6d36 +1918 6d1b +1919 6cf5 +1920 6d39 +1921 6d27 +1922 6d38 +1923 6d29 +1924 6d2e +1925 6d35 +1926 6d0e +1927 6d2b +1928 70ab +1929 70ba +1930 70b3 +1931 70ac +1932 70af +1933 70ad +1934 70b8 +1935 70ae +1936 70a4 +1937 7230 +1938 7272 +1939 726f +1940 7274 +1941 72e9 +1942..1943 72e0 +1944 73b7 +1945 73ca +1946 73bb +1947 73b2 +1948 73cd +1949 73c0 +1950 73b3 +1951 751a +1952 752d +1953 754f +1954 754c +1955 754e +1956 754b +1957 75ab +1958..1959 75a4 +1960..1961 75a2 +1962 7678 +1963..1965 7686 +1966 76c8 +1967 76c6 +1968 76c3 +1969 76c5 +1970 7701 +1971 76f9 +1972 76f8 +1973 7709 +1974 770b +1975 76fe +1976 76fc +1977 7707 +1978 77dc +1979 7802 +1980 7814 +1981..1982 780c +1983 7946 +1984 7949 +1985 7948 +1986 7947 +1987..1988 79b9 +1989..1990 79d1 +1991 79cb +1992 7a7f +1993 7a81 +1994 7aff +1995 7afd +1996 7c7d +1997 7d02 +1998 7d05 +1999 7d00 +2000 7d09 +2001 7d07 +2002 7d04 +2003 7d06 +2004 7f38 +2005 7f8e +2006 7fbf +2007 8010 +2008 800d +2009 8011 +2010 8036 +2011 80d6 +2012 80e5 +2013 80da +2014..2015 80c3 +2016 80cc +2017 80e1 +2018 80db +2019 80ce +2020 80de +2021 80e4 +2022 80dd +2023 81f4 +2024 8222 +2025 82e7 +2026 8303 +2027 8305 +2028 82e3 +2029 82db +2030 82e6 +2031 8304 +2032 82e5 +2033 8302 +2034 8309 +2035 82d2 +2036 82d7 +2037 82f1 +2038 8301 +2039 82dc +2040 82d4 +2041 82d1 +2042 82de +2043 82d3 +2044 82df +2045 82ef +2046 8306 +2047 8650 +2048 8679 +2049 867b +2050 867a +2051 884d +2052 886b +2053 8981 +2054 89d4 +2055 8a08 +2056..2057 8a02 +2058 8c9e +2059 8ca0 +2060 8d74 +2061 8d73 +2062 8db4 +2063 8ecd +2064 8ecc +2065 8ff0 +2066 8fe6 +2067 8fe2 +2068 8fea +2069 8fe5 +2070 8fed +2071 8feb +2072 8fe4 +2073 8fe8 +2074 90ca +2075 90ce +2076 90c1 +2077 90c3 +2078 914b +2079 914a +2080 91cd +2081 9582 +2082 9650 +2083..2085 964b +2086 9762 +2087 9769 +2088 97cb +2089 97ed +2090 97f3 +2091 9801 +2092 98a8 +2093 98db +2094 98df +2095 9996 +2096 9999 +2097 4e58 +2098 4eb3 +2099..2100 500c +2101 5023 +2102 4fef +2103 5026 +2104 5025 +2105 4ff8 +2106 5029 +2107 5016 +2108 5006 +2109 503c +2110 501f +2111 501a +2112 5012 +2113 5011 +2114 4ffa +2115 5000 +2116 5014 +2117 5028 +2118 4ff1 +2119 5021 +2120 500b +2121 5019 +2122 5018 +2123 4ff3 +2124 4fee +2125 502d +2126 502a +2127 4ffe +2128 502b +2129 5009 +2130 517c +2131..2132 51a4 +2133 51a2 +2134 51cd +2135 51cc +2136 51c6 +2137 51cb +2138 5256 +2139 525c +2140 5254 +2141 525b +2142 525d +2143 532a +2144 537f +2145 539f +2146 539d +2147 53df +2148 54e8 +2149 5510 +2150 5501 +2151 5537 +2152 54fc +2153 54e5 +2154 54f2 +2155 5506 +2156 54fa +2157 5514 +2158 54e9 +2159 54ed +2160 54e1 +2161 5509 +2162 54ee +2163 54ea +2164 54e6 +2165 5527 +2166 5507 +2167 54fd +2168 550f +2169..2170 5703 +2171 57c2 +2172 57d4 +2173 57cb +2174 57c3 +2175 5809 +2176 590f +2177..2178 5957 +2179 595a +2180 5a11 +2181 5a18 +2182 5a1c +2183 5a1f +2184 5a1b +2185 5a13 +2186 59ec +2187 5a20 +2188 5a23 +2189 5a29 +2190 5a25 +2191 5a0c +2192 5a09 +2193 5b6b +2194 5c58 +2195 5bb0 +2196 5bb3 +2197 5bb6 +2198 5bb4 +2199 5bae +2200 5bb5 +2201 5bb9 +2202 5bb8 +2203 5c04 +2204 5c51 +2205 5c55 +2206 5c50 +2207 5ced +2208 5cfd +2209 5cfb +2210 5cea +2211 5ce8 +2212 5cf0 +2213 5cf6 +2214 5d01 +2215 5cf4 +2216 5dee +2217 5e2d +2218 5e2b +2219 5eab +2220 5ead +2221 5ea7 +2222 5f31 +2223 5f92 +2224 5f91 +2225 5f90 +2226 6059 +2227 6063 +2228 6065 +2229 6050 +2230 6055 +2231 606d +2232 6069 +2233 606f +2234 6084 +2235 609f +2236 609a +2237 608d +2238 6094 +2239 608c +2240 6085 +2241 6096 +2242 6247 +2243 62f3 +2244 6308 +2245 62ff +2246 634e +2247 633e +2248 632f +2249 6355 +2250 6342 +2251 6346 +2252 634f +2253 6349 +2254 633a +2255 6350 +2256 633d +2257..2258 632a +2259 6328 +2260 634d +2261 634c +2262..2263 6548 +2264 6599 +2265 65c1 +2266 65c5 +2267 6642 +2268 6649 +2269 664f +2270 6643 +2271 6652 +2272 664c +2273 6645 +2274 6641 +2275 66f8 +2276..2277 6714 +2278 6717 +2279 6821 +2280 6838 +2281 6848 +2282 6846 +2283 6853 +2284 6839 +2285 6842 +2286 6854 +2287 6829 +2288 68b3 +2289 6817 +2290 684c +2291 6851 +2292 683d +2293 67f4 +2294 6850 +2295 6840 +2296 683c +2297 6843 +2298 682a +2299 6845 +2300 6813 +2301 6818 +2302 6841 +2303 6b8a +2304 6b89 +2305 6bb7 +2306 6c23 +2307..2308 6c27 +2309 6c26 +2310 6c24 +2311 6cf0 +2312 6d6a +2313 6d95 +2314 6d88 +2315 6d87 +2316 6d66 +2317 6d78 +2318 6d77 +2319 6d59 +2320 6d93 +2321 6d6c +2322 6d89 +2323 6d6e +2324 6d5a +2325 6d74 +2326 6d69 +2327 6d8c +2328 6d8a +2329 6d79 +2330 6d85 +2331 6d65 +2332 6d94 +2333 70ca +2334 70d8 +2335 70e4 +2336 70d9 +2337 70c8 +2338 70cf +2339 7239 +2340 7279 +2341 72fc +2342 72f9 +2343 72fd +2344 72f8 +2345 72f7 +2346 7386 +2347 73ed +2348 7409 +2349 73ee +2350 73e0 +2351 73ea +2352 73de +2353 7554 +2354 755d +2355 755c +2356 755a +2357 7559 +2358 75be +2359 75c5 +2360 75c7 +2361..2362 75b2 +2363 75bd +2364 75bc +2365 75b9 +2366 75c2 +2367 75b8 +2368 768b +2369 76b0 +2370 76ca +2371..2372 76cd +2373 7729 +2374..2375 771f +2376 7728 +2377 77e9 +2378 7830 +2379 7827 +2380 7838 +2381 781d +2382 7834 +2383 7837 +2384 7825 +2385 782d +2386 7820 +2387 781f +2388 7832 +2389 7955 +2390 7950 +2391 7960 +2392 795f +2393 7956 +2394 795e +2395 795d +2396 7957 +2397 795a +2398 79e4 +2399 79e3 +2400 79e7 +2401 79df +2402 79e6 +2403 79e9 +2404 79d8 +2405 7a84 +2406 7a88 +2407 7ad9 +2408 7b06 +2409 7b11 +2410 7c89 +2411 7d21 +2412 7d17 +2413 7d0b +2414 7d0a +2415 7d20 +2416 7d22 +2417 7d14 +2418 7d10 +2419 7d15 +2420 7d1a +2421 7d1c +2422 7d0d +2423 7d19 +2424 7d1b +2425 7f3a +2426 7f5f +2427 7f94 +2428 7fc5 +2429 7fc1 +2430 8006 +2431 8004 +2432 8018 +2433 8015 +2434 8019 +2435 8017 +2436 803d +2437 803f +2438 80f1 +2439 8102 +2440 80f0 +2441 8105 +2442 80ed +2443 80f4 +2444 8106 +2445 80f8 +2446 80f3 +2447 8108 +2448 80fd +2449 810a +2450 80fc +2451 80ef +2452 81ed +2453 81ec +2454 8200 +2455 8210 +2456..2457 822a +2458 8228 +2459 822c +2460 82bb +2461 832b +2462 8352 +2463 8354 +2464 834a +2465 8338 +2466 8350 +2467 8349 +2468 8335 +2469 8334 +2470 834f +2471 8332 +2472 8339 +2473 8336 +2474 8317 +2475 8340 +2476 8331 +2477 8328 +2478 8343 +2479 8654 +2480 868a +2481 86aa +2482 8693 +2483 86a4 +2484 86a9 +2485 868c +2486 86a3 +2487 869c +2488 8870 +2489 8877 +2490..2491 8881 +2492 887d +2493 8879 +2494 8a18 +2495 8a10 +2496 8a0e +2497 8a0c +2498 8a15 +2499 8a0a +2500 8a17 +2501 8a13 +2502 8a16 +2503 8a0f +2504 8a11 +2505 8c48 +2506 8c7a +2507 8c79 +2508..2509 8ca1 +2510 8d77 +2511 8eac +2512 8ed2 +2513 8ed4 +2514 8ecf +2515 8fb1 +2516 9001 +2517 9006 +2518 8ff7 +2519 9000 +2520 8ffa +2521 8ff4 +2522 9003 +2523 8ffd +2524 9005 +2525 8ff8 +2526 9095 +2527 90e1 +2528 90dd +2529 90e2 +2530 9152 +2531 914d +2532 914c +2533 91d8 +2534 91dd +2535 91d7 +2536 91dc +2537 91d9 +2538 9583 +2539..2540 9662 +2541 9661 +2542 965b +2543 965d +2544 9664 +2545 9658 +2546 965e +2547 96bb +2548 98e2 +2549 99ac +2550 9aa8 +2551 9ad8 +2552 9b25 +2553 9b32 +2554 9b3c +2555 4e7e +2556 507a +2557 507d +2558 505c +2559 5047 +2560 5043 +2561 504c +2562 505a +2563 5049 +2564 5065 +2565 5076 +2566 504e +2567 5055 +2568 5075 +2569 5074 +2570 5077 +2571 504f +2572 500f +2573 506f +2574 506d +2575 515c +2576 5195 +2577 51f0 +2578 526a +2579 526f +2580 52d2 +2581 52d9 +2582 52d8 +2583 52d5 +2584 5310 +2585 530f +2586 5319 +2587..2588 533f +2589 533e +2590 53c3 +2591 66fc +2592 5546 +2593 556a +2594 5566 +2595 5544 +2596 555e +2597 5561 +2598 5543 +2599 554a +2600 5531 +2601 5556 +2602 554f +2603 5555 +2604 552f +2605 5564 +2606 5538 +2607 552e +2608 555c +2609 552c +2610 5563 +2611 5533 +2612 5541 +2613 5557 +2614 5708 +2615 570b +2616 5709 +2617 57df +2618 5805 +2619 580a +2620 5806 +2621 57e0 +2622 57e4 +2623 57fa +2624 5802 +2625 5835 +2626 57f7 +2627 57f9 +2628 5920 +2629 5962 +2630 5a36 +2631 5a41 +2632 5a49 +2633 5a66 +2634 5a6a +2635 5a40 +2636 5a3c +2637 5a62 +2638 5a5a +2639 5a46 +2640 5a4a +2641 5b70 +2642 5bc7 +2643 5bc5 +2644 5bc4 +2645 5bc2 +2646 5bbf +2647 5bc6 +2648 5c09 +2649 5c08 +2650 5c07 +2651 5c60 +2652..2653 5c5c +2654 5d07 +2655 5d06 +2656 5d0e +2657 5d1b +2658 5d16 +2659 5d22 +2660 5d11 +2661 5d29 +2662 5d14 +2663 5d19 +2664 5d24 +2665 5d27 +2666 5d17 +2667 5de2 +2668 5e38 +2669 5e36 +2670 5e33 +2671 5e37 +2672..2673 5eb7 +2674 5eb6 +2675 5eb5 +2676 5ebe +2677 5f35 +2678 5f37 +2679 5f57 +2680 5f6c +2681 5f69 +2682 5f6b +2683 5f97 +2684 5f99 +2685 5f9e +2686 5f98 +2687 5fa1 +2688 5fa0 +2689 5f9c +2690 607f +2691 60a3 +2692 6089 +2693 60a0 +2694 60a8 +2695 60cb +2696 60b4 +2697 60e6 +2698 60bd +2699 60c5 +2700 60bb +2701 60b5 +2702 60dc +2703 60bc +2704 60d8 +2705 60d5 +2706 60c6 +2707 60df +2708 60b8 +2709 60da +2710 60c7 +2711..2712 621a +2713 6248 +2714 63a0 +2715 63a7 +2716 6372 +2717 6396 +2718 63a2 +2719 63a5 +2720 6377 +2721 6367 +2722 6398 +2723 63aa +2724 6371 +2725 63a9 +2726 6389 +2727 6383 +2728 639b +2729 636b +2730 63a8 +2731 6384 +2732 6388 +2733 6399 +2734 63a1 +2735 63ac +2736 6392 +2737 638f +2738 6380 +2739 637b +2740 6369 +2741 6368 +2742 637a +2743 655d +2744 6556 +2745 6551 +2746 6559 +2747 6557 +2748 555f +2749 654f +2750 6558 +2751 6555 +2752 6554 +2753 659c +2754 659b +2755 65ac +2756 65cf +2757..2758 65cb +2759 65ce +2760 665d +2761 665a +2762 6664 +2763 6668 +2764 6666 +2765 665e +2766 66f9 +2767 52d7 +2768 671b +2769 6881 +2770 68af +2771 68a2 +2772 6893 +2773 68b5 +2774 687f +2775 6876 +2776 68b1 +2777 68a7 +2778 6897 +2779 68b0 +2780 6883 +2781 68c4 +2782 68ad +2783 6886 +2784 6885 +2785 6894 +2786 689d +2787 68a8 +2788 689f +2789 68a1 +2790 6882 +2791 6b32 +2792 6bba +2793..2794 6beb +2795 6c2b +2796 6d8e +2797 6dbc +2798 6df3 +2799 6dd9 +2800 6db2 +2801 6de1 +2802 6dcc +2803 6de4 +2804 6dfb +2805 6dfa +2806 6e05 +2807 6dc7 +2808 6dcb +2809 6daf +2810 6dd1 +2811 6dae +2812 6dde +2813 6df9 +2814 6db8 +2815 6df7 +2816 6df5 +2817 6dc5 +2818 6dd2 +2819 6e1a +2820 6db5 +2821 6dda +2822 6deb +2823 6dd8 +2824 6dea +2825 6df1 +2826 6dee +2827 6de8 +2828 6dc6 +2829 6dc4 +2830 6daa +2831 6dec +2832 6dbf +2833 6de6 +2834 70f9 +2835..2836 7109 +2837 70fd +2838 70ef +2839 723d +2840 727d +2841 7281 +2842 731c +2843 731b +2844 7316 +2845 7313 +2846 7319 +2847 7387 +2848 7405 +2849 740a +2850 7403 +2851 7406 +2852 73fe +2853 740d +2854 74e0 +2855..2856 74f6 +2857 751c +2858 7522 +2859..2860 7565 +2861 7562 +2862 7570 +2863 758f +2864..2865 75d4 +2866 75b5 +2867 75ca +2868 75cd +2869 768e +2870 76d4 +2871 76d2 +2872 76db +2873 7737 +2874 773e +2875 773c +2876 7736 +2877 7738 +2878 773a +2879 786b +2880 7843 +2881 784e +2882 7965 +2883 7968 +2884 796d +2885 79fb +2886 7a92 +2887 7a95 +2888 7b20 +2889 7b28 +2890 7b1b +2891 7b2c +2892 7b26 +2893 7b19 +2894 7b1e +2895 7b2e +2896 7c92 +2897 7c97 +2898 7c95 +2899 7d46 +2900 7d43 +2901 7d71 +2902 7d2e +2903 7d39 +2904 7d3c +2905 7d40 +2906 7d30 +2907 7d33 +2908 7d44 +2909 7d2f +2910 7d42 +2911 7d32 +2912 7d31 +2913 7f3d +2914 7f9e +2915 7f9a +2916 7fcc +2917 7fce +2918 7fd2 +2919 801c +2920 804a +2921 8046 +2922 812f +2923 8116 +2924 8123 +2925 812b +2926 8129 +2927 8130 +2928 8124 +2929 8202 +2930 8235 +2931 8237 +2932 8236 +2933 8239 +2934 838e +2935 839e +2936 8398 +2937 8378 +2938 83a2 +2939 8396 +2940 83bd +2941 83ab +2942 8392 +2943 838a +2944 8393 +2945 8389 +2946 83a0 +2947 8377 +2948..2949 837b +2950 8386 +2951 83a7 +2952 8655 +2953 5f6a +2954 86c7 +2955 86c0 +2956 86b6 +2957 86c4 +2958 86b5 +2959 86c6 +2960 86cb +2961 86b1 +2962 86af +2963 86c9 +2964 8853 +2965 889e +2966 8888 +2967 88ab +2968 8892 +2969 8896 +2970 888d +2971 888b +2972 8993 +2973 898f +2974 8a2a +2975 8a1d +2976 8a23 +2977 8a25 +2978 8a31 +2979 8a2d +2980 8a1f +2981 8a1b +2982 8a22 +2983 8c49 +2984 8c5a +2985 8ca9 +2986 8cac +2987 8cab +2988 8ca8 +2989 8caa +2990 8ca7 +2991 8d67 +2992 8d66 +2993 8dbe +2994 8dba +2995 8edb +2996 8edf +2997 9019 +2998 900d +2999 901a +3000 9017 +3001 9023 +3002 901f +3003 901d +3004 9010 +3005 9015 +3006 901e +3007 9020 +3008 900f +3009 9022 +3010 9016 +3011 901b +3012 9014 +3013 90e8 +3014 90ed +3015 90fd +3016 9157 +3017 91ce +3018 91f5 +3019 91e6 +3020 91e3 +3021 91e7 +3022 91ed +3023 91e9 +3024 9589 +3025 966a +3026 9675 +3027 9673 +3028 9678 +3029 9670 +3030 9674 +3031..3032 9676 +3033 966c +3034 96c0 +3035 96ea +3036 96e9 +3037 7ae0 +3038 7adf +3039..3040 9802 +3041 9b5a +3042 9ce5 +3043 9e75 +3044 9e7f +3045 9ea5 +3046 9ebb +3047 50a2 +3048 508d +3049 5085 +3050 5099 +3051 5091 +3052 5080 +3053 5096 +3054 5098 +3055 509a +3056 6700 +3057 51f1 +3058 5272 +3059..3060 5274 +3061 5269 +3062 52de +3063 52dd +3064 52db +3065 535a +3066 53a5 +3067 557b +3068 5580 +3069 55a7 +3070 557c +3071 558a +3072 559d +3073 5598 +3074 5582 +3075 559c +3076 55aa +3077 5594 +3078 5587 +3079 558b +3080 5583 +3081 55b3 +3082 55ae +3083 559f +3084 553e +3085 55b2 +3086 559a +3087 55bb +3088 55ac +3089 55b1 +3090 557e +3091 5589 +3092 55ab +3093 5599 +3094 570d +3095 582f +3096 582a +3097 5834 +3098 5824 +3099..3100 5830 +3101 5821 +3102 581d +3103 5820 +3104..3105 58f9 +3106 5960 +3107 5a77 +3108 5a9a +3109 5a7f +3110 5a92 +3111 5a9b +3112 5aa7 +3113 5b73 +3114 5b71 +3115 5bd2 +3116 5bcc +3117 5bd3 +3118 5bd0 +3119..3120 5c0a +3121 5c31 +3122 5d4c +3123 5d50 +3124 5d34 +3125 5d47 +3126 5dfd +3127 5e45 +3128 5e3d +3129 5e40 +3130 5e43 +3131 5e7e +3132 5eca +3133..3134 5ec1 +3135 5ec4 +3136 5f3c +3137 5f6d +3138..3139 5fa9 +3140 5fa8 +3141 60d1 +3142 60e1 +3143 60b2 +3144 60b6 +3145 60e0 +3146 611c +3147 6123 +3148 60fa +3149 6115 +3150 60f0 +3151 60fb +3152 60f4 +3153 6168 +3154 60f1 +3155 610e +3156 60f6 +3157 6109 +3158 6100 +3159 6112 +3160 621f +3161 6249 +3162 63a3 +3163 638c +3164 63cf +3165 63c0 +3166 63e9 +3167 63c9 +3168 63c6 +3169 63cd +3170 63d2 +3171 63e3 +3172 63d0 +3173 63e1 +3174 63d6 +3175..3176 63ed +3177 6376 +3178 63f4 +3179 63ea +3180 63db +3181 6452 +3182 63da +3183 63f9 +3184 655e +3185 6566 +3186..3187 6562 +3188 6591 +3189 6590 +3190 65af +3191 666e +3192 6670 +3193 6674 +3194 6676 +3195 666f +3196 6691 +3197 667a +3198 667e +3199 6677 +3200..3201 66fe +3202 671f +3203 671d +3204 68fa +3205 68d5 +3206 68e0 +3207 68d8 +3208 68d7 +3209 6905 +3210 68df +3211 68f5 +3212 68ee +3213 68e7 +3214 68f9 +3215 68d2 +3216 68f2 +3217 68e3 +3218 68cb +3219 68cd +3220 690d +3221 6912 +3222 690e +3223 68c9 +3224 68da +3225 696e +3226 68fb +3227 6b3e +3228 6b3a +3229 6b3d +3230 6b98 +3231 6b96 +3232 6bbc +3233 6bef +3234..3235 6c2e +3236 6c2c +3237 6e2f +3238 6e38 +3239 6e54 +3240 6e21 +3241 6e32 +3242 6e67 +3243 6e4a +3244 6e20 +3245 6e25 +3246 6e23 +3247 6e1b +3248 6e5b +3249 6e58 +3250 6e24 +3251 6e56 +3252 6e6e +3253 6e2d +3254 6e26 +3255 6e6f +3256 6e34 +3257 6e4d +3258 6e3a +3259 6e2c +3260 6e43 +3261 6e1d +3262 6e3e +3263 6ecb +3264 6e89 +3265 6e19 +3266 6e4e +3267 6e63 +3268 6e44 +3269 6e72 +3270 6e69 +3271 6e5f +3272..3273 7119 +3274 7126 +3275 7130 +3276 7121 +3277 7136 +3278 716e +3279 711c +3280 724c +3281 7284 +3282 7280 +3283 7336 +3284 7325 +3285 7334 +3286 7329 +3287 743a +3288 742a +3289 7433 +3290 7422 +3291 7425 +3292..3293 7435 +3294 7434 +3295 742f +3296 741b +3297 7426 +3298 7428 +3299..3300 7525 +3301 756b +3302 756a +3303 75e2 +3304 75db +3305 75e3 +3306 75d9 +3307 75d8 +3308 75de +3309 75e0 +3310..3311 767b +3312 7696 +3313 7693 +3314 76b4 +3315 76dc +3316 774f +3317 77ed +3318 785d +3319 786c +3320 786f +3321 7a0d +3322 7a08 +3323 7a0b +3324 7a05 +3325 7a00 +3326 7a98 +3327 7a97 +3328 7a96 +3329 7ae5 +3330 7ae3 +3331 7b49 +3332 7b56 +3333 7b46 +3334 7b50 +3335 7b52 +3336 7b54 +3337 7b4d +3338 7b4b +3339 7b4f +3340 7b51 +3341 7c9f +3342 7ca5 +3343 7d5e +3344 7d50 +3345 7d68 +3346 7d55 +3347 7d2b +3348 7d6e +3349 7d72 +3350 7d61 +3351 7d66 +3352 7d62 +3353 7d70 +3354 7d73 +3355 5584 +3356..3357 7fd4 +3358 800b +3359 8052 +3360 8085 +3361 8155 +3362 8154 +3363 814b +3364 8151 +3365 814e +3366 8139 +3367 8146 +3368 813e +3369 814c +3370 8153 +3371 8174 +3372 8212 +3373 821c +3374 83e9 +3375 8403 +3376 83f8 +3377 840d +3378 83e0 +3379 83c5 +3380 840b +3381 83c1 +3382 83ef +3383 83f1 +3384 83f4 +3385 8457 +3386 840a +3387 83f0 +3388 840c +3389 83cc +3390 83fd +3391 83f2 +3392 83ca +3393 8438 +3394 840e +3395 8404 +3396 83dc +3397 8407 +3398 83d4 +3399 83df +3400 865b +3401 86df +3402 86d9 +3403 86ed +3404 86d4 +3405 86db +3406 86e4 +3407 86d0 +3408 86de +3409 8857 +3410..3411 88c1 +3412 88b1 +3413 8983 +3414 8996 +3415 8a3b +3416 8a60 +3417 8a55 +3418 8a5e +3419 8a3c +3420 8a41 +3421 8a54 +3422 8a5b +3423 8a50 +3424 8a46 +3425 8a34 +3426 8a3a +3427 8a36 +3428 8a56 +3429 8c61 +3430 8c82 +3431 8caf +3432 8cbc +3433 8cb3 +3434 8cbd +3435 8cc1 +3436 8cbb +3437 8cc0 +3438 8cb4 +3439 8cb7 +3440 8cb6 +3441 8cbf +3442 8cb8 +3443 8d8a +3444 8d85 +3445 8d81 +3446 8dce +3447 8ddd +3448 8dcb +3449 8dda +3450 8dd1 +3451 8dcc +3452 8ddb +3453 8dc6 +3454 8efb +3455 8ef8 +3456 8efc +3457 8f9c +3458 902e +3459 9035 +3460 9031 +3461 9038 +3462 9032 +3463 9036 +3464 9102 +3465 90f5 +3466 9109 +3467 90fe +3468 9163 +3469 9165 +3470 91cf +3471..3472 9214 +3473 9223 +3474 9209 +3475 921e +3476 920d +3477 9210 +3478 9207 +3479 9211 +3480 9594 +3481 958f +3482 958b +3483 9591 +3484 9593 +3485 9592 +3486 958e +3487 968a +3488 968e +3489 968b +3490 967d +3491..3492 9685 +3493 968d +3494 9672 +3495 9684 +3496 96c1 +3497 96c5 +3498 96c4 +3499..3500 96c6 +3501 96ef +3502 96f2 +3503 97cc +3504..3505 9805 +3506 9808 +3507 98e7 +3508 98ea +3509 98ef +3510 98e9 +3511 98f2 +3512 98ed +3513 99ae +3514 99ad +3515 9ec3 +3516 9ecd +3517 9ed1 +3518 4e82 +3519 50ad +3520 50b5 +3521..3522 50b2 +3523 50c5 +3524 50be +3525 50ac +3526 50b7 +3527 50bb +3528 50af +3529 50c7 +3530 527f +3531 5277 +3532 527d +3533 52df +3534 52e6 +3535 52e4 +3536..3537 52e2 +3538 532f +3539 55df +3540 55e8 +3541 55d3 +3542 55e6 +3543 55ce +3544 55dc +3545 55c7 +3546 55d1 +3547..3548 55e3 +3549 55ef +3550 55da +3551 55e1 +3552..3553 55c5 +3554 55e5 +3555 55c9 +3556..3557 5712 +3558 585e +3559 5851 +3560 5858 +3561 5857 +3562 585a +3563 5854 +3564 586b +3565 584c +3566 586d +3567 584a +3568 5862 +3569 5852 +3570 584b +3571 5967 +3572 5ac1 +3573 5ac9 +3574 5acc +3575 5abe +3576 5abd +3577 5abc +3578 5ab3 +3579 5ac2 +3580 5ab2 +3581 5d69 +3582 5d6f +3583 5e4c +3584 5e79 +3585 5ec9 +3586 5ec8 +3587 5f12 +3588 5f59 +3589 5fac +3590 5fae +3591 611a +3592 610f +3593 6148 +3594 611f +3595 60f3 +3596 611b +3597 60f9 +3598 6101 +3599 6108 +3600 614e +3601 614c +3602 6144 +3603 614d +3604 613e +3605 6134 +3606 6127 +3607 610d +3608 6106 +3609 6137 +3610..3611 6221 +3612 6413 +3613 643e +3614 641e +3615 642a +3616 642d +3617 643d +3618 642c +3619 640f +3620 641c +3621 6414 +3622 640d +3623 6436 +3624..3625 6416 +3626 6406 +3627 656c +3628 659f +3629 65b0 +3630 6697 +3631 6689 +3632..3633 6687 +3634 6696 +3635 6684 +3636 6698 +3637 668d +3638 6703 +3639 6994 +3640 696d +3641 695a +3642 6977 +3643 6960 +3644 6954 +3645 6975 +3646 6930 +3647 6982 +3648 694a +3649 6968 +3650 696b +3651 695e +3652 6953 +3653 6979 +3654 6986 +3655 695d +3656 6963 +3657 695b +3658 6b47 +3659 6b72 +3660 6bc0 +3661 6bbf +3662 6bd3 +3663 6bfd +3664 6ea2 +3665 6eaf +3666 6ed3 +3667 6eb6 +3668 6ec2 +3669 6e90 +3670 6e9d +3671 6ec7 +3672 6ec5 +3673 6ea5 +3674 6e98 +3675 6ebc +3676 6eba +3677 6eab +3678 6ed1 +3679 6e96 +3680 6e9c +3681 6ec4 +3682 6ed4 +3683 6eaa +3684 6ea7 +3685 6eb4 +3686 714e +3687 7159 +3688 7169 +3689 7164 +3690 7149 +3691 7167 +3692 715c +3693 716c +3694 7166 +3695 714c +3696 7165 +3697 715e +3698 7146 +3699 7168 +3700 7156 +3701 723a +3702 7252 +3703 7337 +3704 7345 +3705 733f +3706 733e +3707 746f +3708 745a +3709 7455 +3710 745f +3711 745e +3712 7441 +3713 743f +3714 7459 +3715 745b +3716 e2a3 +3717 7576 +3718 7578 +3719 7600 +3720 75f0 +3721 7601 +3722 75f2 +3723 75f1 +3724 75fa +3725 75ff +3726 75f4 +3727 75f3 +3728..3729 76de +3730 775b +3731 776b +3732 7766 +3733 775e +3734 7763 +3735 7779 +3736 776a +3737 776c +3738 775c +3739 7765 +3740 7768 +3741 7762 +3742 77ee +3743 788e +3744 78b0 +3745..3746 7897 +3747 788c +3748 7889 +3749 787c +3750 7891 +3751 7893 +3752 787f +3753 797a +3754 797f +3755 7981 +3756 842c +3757 79bd +3758 7a1c +3759 7a1a +3760 7a20 +3761 7a14 +3762 7a1f +3763 7a1e +3764..3765 7a9f +3766 7b77 +3767 7bc0 +3768 7b60 +3769 7b6e +3770 7b67 +3771 7cb1 +3772 7cb3 +3773 7cb5 +3774 7d93 +3775 7d79 +3776 7d91 +3777 7d81 +3778 7d8f +3779 7d5b +3780 7f6e +3781..3782 7f69 +3783 7f72 +3784 7fa9 +3785 7fa8 +3786 7fa4 +3787 8056 +3788 8058 +3789 8086 +3790 8084 +3791 8171 +3792 8170 +3793 8178 +3794 8165 +3795 816e +3796 8173 +3797 816b +3798..3799 8179 +3800 8166 +3801 8205 +3802 8247 +3803 8482 +3804 8477 +3805 843d +3806 8431 +3807 8475 +3808 8466 +3809 846b +3810 8449 +3811 846c +3812 845b +3813 843c +3814 8435 +3815 8461 +3816 8463 +3817 8469 +3818 846d +3819 8446 +3820 865e +3821 865c +3822 865f +3823 86f9 +3824 8713 +3825 8708 +3826 8707 +3827 8700 +3828 86fe +3829 86fb +3830..3831 8702 +3832 8706 +3833 870a +3834 8859 +3835 88df +3836 88d4 +3837 88d9 +3838 88dc +3839 88d8 +3840 88dd +3841 88e1 +3842 88ca +3843 88d5 +3844 88d2 +3845 899c +3846 89e3 +3847 8a6b +3848..3849 8a72 +3850 8a66 +3851 8a69 +3852 8a70 +3853 8a87 +3854 8a7c +3855 8a63 +3856 8aa0 +3857 8a71 +3858 8a85 +3859 8a6d +3860 8a62 +3861 8a6e +3862 8a6c +3863 8a79 +3864 8a7b +3865 8a3e +3866 8a68 +3867 8c62 +3868 8c8a +3869 8c89 +3870 8cca +3871..3872 8cc7 +3873 8cc4 +3874 8cb2 +3875 8cc3 +3876 8cc2 +3877 8cc5 +3878 8de1 +3879 8ddf +3880 8de8 +3881 8def +3882 8df3 +3883 8dfa +3884 8dea +3885 8de4 +3886 8de6 +3887 8eb2 +3888 8f03 +3889 8f09 +3890 8efe +3891 8f0a +3892 8f9f +3893 8fb2 +3894 904b +3895 904a +3896 9053 +3897 9042 +3898 9054 +3899 903c +3900 9055 +3901 9050 +3902 9047 +3903 904f +3904 904e +3905 904d +3906 9051 +3907 903e +3908 9041 +3909 9112 +3910 9117 +3911 916c +3912 916a +3913 9169 +3914 91c9 +3915 9237 +3916 9257 +3917 9238 +3918 923d +3919 9240 +3920 923e +3921 925b +3922 924b +3923 9264 +3924 9251 +3925 9234 +3926 9249 +3927 924d +3928 9245 +3929 9239 +3930 923f +3931 925a +3932 9598 +3933 9698 +3934..3935 9694 +3936 96cd +3937 96cb +3938..3939 96c9 +3940 96f7 +3941 96fb +3942 96f9 +3943 96f6 +3944 9756 +3945 9774 +3946 9776 +3947..3948 9810 +3949 9813 +3950 980a +3951 9812 +3952 980c +3953 98fc +3954 98f4 +3955..3956 98fd +3957 99b3 +3958 99b1 +3959 99b4 +3960 9ae1 +3961 9ce9 +3962 9e82 +3963 9f0e +3964 9f13 +3965 9f20 +3966 50e7 +3967 50ee +3968 50e5 +3969 50d6 +3970 50ed +3971 50da +3972 50d5 +3973 50cf +3974 50d1 +3975 50f1 +3976 50ce +3977 50e9 +3978 5162 +3979 51f3 +3980 5283 +3981 5282 +3982 5331 +3983 53ad +3984 55fe +3985 5600 +3986 561b +3987 5617 +3988 55fd +3989 5614 +3990 5606 +3991 5609 +3992..3993 560d +3994 55f7 +3995 5616 +3996 561f +3997 5608 +3998 5610 +3999 55f6 +4000 5718 +4001 5716 +4002 5875 +4003 587e +4004 5883 +4005 5893 +4006 588a +4007 5879 +4008 5885 +4009 587d +4010 58fd +4011 5925 +4012 5922 +4013 5924 +4014 596a +4015 5969 +4016 5ae1 +4017 5ae6 +4018 5ae9 +4019 5ad7 +4020 5ad6 +4021 5ad8 +4022 5ae3 +4023 5b75 +4024 5bde +4025 5be7 +4026 5be1 +4027..4028 5be5 +4029 5be8 +4030 5be2 +4031 5be4 +4032 5bdf +4033 5c0d +4034 5c62 +4035 5d84 +4036 5d87 +4037 5e5b +4038 5e63 +4039 5e55 +4040 5e57 +4041 5e54 +4042 5ed3 +4043 5ed6 +4044 5f0a +4045 5f46 +4046 5f70 +4047 5fb9 +4048 6147 +4049 613f +4050 614b +4051 6177 +4052..4053 6162 +4054 615f +4055 615a +4056 6158 +4057 6175 +4058 622a +4059 6487 +4060 6458 +4061 6454 +4062 64a4 +4063 6478 +4064 645f +4065 647a +4066 6451 +4067 6467 +4068 6434 +4069 646d +4070 647b +4071 6572 +4072 65a1 +4073 65d7 +4074 65d6 +4075 66a2 +4076 66a8 +4077 669d +4078 699c +4079 69a8 +4080 6995 +4081 69c1 +4082 69ae +4083 69d3 +4084 69cb +4085 699b +4086 69b7 +4087 69bb +4088 69ab +4089 69b4 +4090 69d0 +4091 69cd +4092 69ad +4093 69cc +4094 69a6 +4095 69c3 +4096 69a3 +4097 6b49 +4098 6b4c +4099 6c33 +4100 6f33 +4101 6f14 +4102 6efe +4103 6f13 +4104 6ef4 +4105 6f29 +4106 6f3e +4107 6f20 +4108 6f2c +4109 6f0f +4110 6f02 +4111 6f22 +4112 6eff +4113 6eef +4114 6f06 +4115 6f31 +4116 6f38 +4117 6f32 +4118 6f23 +4119 6f15 +4120 6f2b +4121 6f2f +4122 6f88 +4123 6f2a +4124 6eec +4125 6f01 +4126 6ef2 +4127 6ecc +4128 6ef7 +4129 7194 +4130 7199 +4131 717d +4132 718a +4133 7184 +4134 7192 +4135 723e +4136 7292 +4137 7296 +4138 7344 +4139 7350 +4140 7464 +4141 7463 +4142 746a +4143 7470 +4144 746d +4145 7504 +4146 7591 +4147 7627 +4148 760d +4149 760b +4150 7609 +4151 7613 +4152 76e1 +4153 76e3 +4154 7784 +4155 777d +4156 777f +4157 7761 +4158 78c1 +4159 789f +4160 78a7 +4161 78b3 +4162 78a9 +4163 78a3 +4164..4165 798e +4166 798d +4167 7a2e +4168 7a31 +4169 7aaa +4170 7aa9 +4171 7aed +4172 7aef +4173 7ba1 +4174 7b95 +4175 7b8b +4176 7b75 +4177 7b97 +4178 7b9d +4179 7b94 +4180 7b8f +4181 7bb8 +4182 7b87 +4183 7b84 +4184 7cb9 +4185..4186 7cbd +4187 7dbb +4188 7db0 +4189 7d9c +4190..4191 7dbd +4192 7da0 +4193 7dca +4194 7db4 +4195 7db2 +4196 7db1 +4197 7dba +4198 7da2 +4199 7dbf +4200 7db5 +4201 7db8 +4202 7dad +4203 7dd2 +4204 7dc7 +4205 7dac +4206 7f70 +4207..4208 7fe0 +4209 7fdf +4210 805e +4211 805a +4212 8087 +4213 8150 +4214 8180 +4215 818f +4216 8188 +4217 818a +4218 817f +4219 8182 +4220 81e7 +4221 81fa +4222 8207 +4223 8214 +4224 821e +4225 824b +4226 84c9 +4227 84bf +4228 84c6 +4229 84c4 +4230 8499 +4231 849e +4232 84b2 +4233 849c +4234 84cb +4235 84b8 +4236 84c0 +4237 84d3 +4238 8490 +4239 84bc +4240 84d1 +4241 84ca +4242 873f +4243 871c +4244 873b +4245 8722 +4246 8725 +4247 8734 +4248 8718 +4249 8755 +4250 8737 +4251 8729 +4252 88f3 +4253 8902 +4254 88f4 +4255 88f9 +4256 88f8 +4257 88fd +4258 88e8 +4259 891a +4260 88ef +4261 8aa6 +4262 8a8c +4263 8a9e +4264 8aa3 +4265 8a8d +4266 8aa1 +4267 8a93 +4268 8aa4 +4269 8aaa +4270 8aa5 +4271 8aa8 +4272 8a98 +4273 8a91 +4274 8a9a +4275 8aa7 +4276 8c6a +4277 8c8d +4278 8c8c +4279 8cd3 +4280..4281 8cd1 +4282 8d6b +4283 8d99 +4284 8d95 +4285 8dfc +4286 8f14 +4287 8f12 +4288 8f15 +4289 8f13 +4290 8fa3 +4291 9060 +4292 9058 +4293 905c +4294 9063 +4295 9059 +4296 905e +4297 9062 +4298 905d +4299 905b +4300 9119 +4301 9118 +4302 911e +4303 9175 +4304 9178 +4305 9177 +4306 9174 +4307 9278 +4308 92ac +4309 9280 +4310 9285 +4311 9298 +4312 9296 +4313 927b +4314 9293 +4315 929c +4316 92a8 +4317 927c +4318 9291 +4319 95a1 +4320..4321 95a8 +4322 95a3 +4323 95a5 +4324 95a4 +4325 9699 +4326 969c +4327 969b +4328 96cc +4329 96d2 +4330 9700 +4331 977c +4332 9785 +4333 97f6 +4334..4335 9817 +4336 98af +4337 98b1 +4338 9903 +4339 9905 +4340 990c +4341 9909 +4342 99c1 +4343..4344 9aaf +4345 9ae6 +4346..4347 9b41 +4348 9cf4 +4349 9cf6 +4350 9cf3 +4351 9ebc +4352 9f3b +4353 9f4a +4354 5104 +4355 5100 +4356 50fb +4357 50f5 +4358 50f9 +4359 5102 +4360..4361 5108 +4362 5105 +4363 51dc +4364..4366 5287 +4367 528d +4368 528a +4369 52f0 +4370 53b2 +4371 562e +4372 563b +4373 5639 +4374 5632 +4375 563f +4376 5634 +4377 5629 +4378 5653 +4379 564e +4380 5657 +4381 5674 +4382 5636 +4383..4384 562f +4385 5880 +4386 589f +4387 589e +4388 58b3 +4389 589c +4390 58ae +4391 58a9 +4392 58a6 +4393 596d +4394 5b09 +4395 5afb +4396 5b0b +4397 5af5 +4398 5b0c +4399 5b08 +4400 5bee +4401 5bec +4402 5be9 +4403 5beb +4404..4405 5c64 +4406 5d9d +4407 5d94 +4408 5e62 +4409 5e5f +4410 5e61 +4411 5ee2 +4412 5eda +4413 5edf +4414 5edd +4415 5ee3 +4416 5ee0 +4417 5f48 +4418 5f71 +4419 5fb7 +4420 5fb5 +4421 6176 +4422 6167 +4423 616e +4424 615d +4425 6155 +4426 6182 +4427 617c +4428 6170 +4429 616b +4430 617e +4431 61a7 +4432 6190 +4433 61ab +4434 618e +4435 61ac +4436 619a +4437 61a4 +4438 6194 +4439 61ae +4440 622e +4441 6469 +4442 646f +4443 6479 +4444 649e +4445 64b2 +4446 6488 +4447 6490 +4448 64b0 +4449 64a5 +4450 6493 +4451 6495 +4452 64a9 +4453 6492 +4454 64ae +4455 64ad +4456 64ab +4457 649a +4458 64ac +4459 6499 +4460 64a2 +4461 64b3 +4462 6575 +4463..4464 6577 +4465 66ae +4466 66ab +4467 66b4 +4468 66b1 +4469 6a23 +4470 6a1f +4471 69e8 +4472 6a01 +4473 6a1e +4474 6a19 +4475 69fd +4476 6a21 +4477 6a13 +4478 6a0a +4479 69f3 +4480 6a02 +4481 6a05 +4482 69ed +4483 6a11 +4484 6b50 +4485 6b4e +4486 6ba4 +4487..4488 6bc5 +4489 6f3f +4490 6f7c +4491 6f84 +4492 6f51 +4493 6f66 +4494 6f54 +4495 6f86 +4496 6f6d +4497 6f5b +4498 6f78 +4499 6f6e +4500 6f8e +4501 6f7a +4502 6f70 +4503 6f64 +4504 6f97 +4505 6f58 +4506 6ed5 +4507 6f6f +4508 6f60 +4509 6f5f +4510 719f +4511 71ac +4512 71b1 +4513 71a8 +4514 7256 +4515 729b +4516 734e +4517 7357 +4518 7469 +4519 748b +4520 7483 +4521 747e +4522 7480 +4523 757f +4524 7620 +4525 7629 +4526 761f +4527 7624 +4528 7626 +4529..4530 7621 +4531 769a +4532 76ba +4533 76e4 +4534 778e +4535 7787 +4536 778c +4537 7791 +4538 778b +4539 78cb +4540 78c5 +4541 78ba +4542 78ca +4543 78be +4544 78d5 +4545 78bc +4546 78d0 +4547 7a3f +4548 7a3c +4549 7a40 +4550 7a3d +4551 7a37 +4552 7a3b +4553 7aaf +4554 7aae +4555 7bad +4556 7bb1 +4557 7bc4 +4558 7bb4 +4559..4560 7bc6 +4561 7bc1 +4562 7ba0 +4563 7bcc +4564 7cca +4565 7de0 +4566 7df4 +4567 7def +4568 7dfb +4569 7dd8 +4570 7dec +4571 7ddd +4572 7de8 +4573 7de3 +4574 7dda +4575 7dde +4576 7de9 +4577 7d9e +4578 7dd9 +4579 7df2 +4580 7df9 +4581 7f75 +4582 7f77 +4583 7faf +4584 7fe9 +4585 8026 +4586..4588 819b +4589 81a0 +4590 819a +4591 8198 +4592 8517 +4593 853d +4594 851a +4595 84ee +4596..4597 852c +4598 8513 +4599 8511 +4600 8523 +4601 8521 +4602 8514 +4603 84ec +4604 8525 +4605 84ff +4606 8506 +4607 8782 +4608 8774 +4609 8776 +4610 8760 +4611 8766 +4612 8778 +4613 8768 +4614 8759 +4615 8757 +4616 874c +4617 8753 +4618 885b +4619 885d +4620 8910 +4621 8907 +4622..4623 8912 +4624 8915 +4625 890a +4626 8abc +4627 8ad2 +4628 8ac7 +4629 8ac4 +4630 8a95 +4631 8acb +4632 8af8 +4633 8ab2 +4634 8ac9 +4635 8ac2 +4636 8abf +4637 8ab0 +4638 8ad6 +4639 8acd +4640 8ab6 +4641 8ab9 +4642 8adb +4643 8c4c +4644 8c4e +4645 8c6c +4646 8ce0 +4647 8cde +4648 8ce6 +4649 8ce4 +4650..4651 8cec +4652..4653 8ce2 +4654 8cdc +4655 8cea +4656 8ce1 +4657 8d6d +4658 8d9f +4659 8da3 +4660 8e2b +4661 8e10 +4662 8e1d +4663 8e22 +4664 8e0f +4665 8e29 +4666 8e1f +4667 8e21 +4668 8e1e +4669 8eba +4670 8f1d +4671 8f1b +4672 8f1f +4673 8f29 +4674 8f26 +4675 8f2a +4676 8f1c +4677 8f1e +4678 8f25 +4679 9069 +4680 906e +4681 9068 +4682 906d +4683 9077 +4684 9130 +4685 912d +4686 9127 +4687 9131 +4688 9187 +4689 9189 +4690 918b +4691 9183 +4692 92c5 +4693 92bb +4694 92b7 +4695 92ea +4696 92e4 +4697 92c1 +4698 92b3 +4699 92bc +4700 92d2 +4701 92c7 +4702 92f0 +4703 92b2 +4704 95ad +4705 95b1 +4706 9704 +4707..4708 9706 +4709 9709 +4710 9760 +4711 978d +4712 978b +4713 978f +4714 9821 +4715 982b +4716 981c +4717 98b3 +4718 990a +4719 9913 +4720 9912 +4721 9918 +4722 99dd +4723 99d0 +4724 99df +4725 99db +4726 99d1 +4727 99d5 +4728 99d2 +4729 99d9 +4730 9ab7 +4731..4732 9aee +4733 9b27 +4734 9b45 +4735 9b44 +4736 9b77 +4737 9b6f +4738 9d06 +4739 9d09 +4740 9d03 +4741 9ea9 +4742 9ebe +4743 9ece +4744 58a8 +4745 9f52 +4746 5112 +4747 5118 +4748 5114 +4749 5110 +4750 5115 +4751 5180 +4752 51aa +4753 51dd +4754 5291 +4755 5293 +4756 52f3 +4757 5659 +4758 566b +4759 5679 +4760 5669 +4761 5664 +4762 5678 +4763 566a +4764 5668 +4765 5665 +4766 5671 +4767 566f +4768 566c +4769 5662 +4770 5676 +4771 58c1 +4772 58be +4773 58c7 +4774 58c5 +4775 596e +4776 5b1d +4777 5b34 +4778 5b78 +4779 5bf0 +4780 5c0e +4781 5f4a +4782 61b2 +4783 6191 +4784 61a9 +4785 618a +4786 61cd +4787 61b6 +4788 61be +4789 61ca +4790 61c8 +4791 6230 +4792 64c5 +4793 64c1 +4794 64cb +4795..4796 64bb +4797 64da +4798 64c4 +4799 64c7 +4800 64c2 +4801 64cd +4802 64bf +4803 64d2 +4804 64d4 +4805 64be +4806 6574 +4807 66c6 +4808 66c9 +4809 66b9 +4810 66c4 +4811 66c7 +4812 66b8 +4813 6a3d +4814 6a38 +4815 6a3a +4816 6a59 +4817 6a6b +4818 6a58 +4819 6a39 +4820 6a44 +4821 6a62 +4822 6a61 +4823 6a4b +4824 6a47 +4825 6a35 +4826 6a5f +4827 6a48 +4828 6b59 +4829 6b77 +4830 6c05 +4831 6fc2 +4832 6fb1 +4833 6fa1 +4834 6fc3 +4835 6fa4 +4836 6fc1 +4837 6fa7 +4838 6fb3 +4839 6fc0 +4840 6fb9 +4841 6fb6 +4842 6fa6 +4843 6fa0 +4844 6fb4 +4845 71be +4846 71c9 +4847 71d0 +4848 71d2 +4849 71c8 +4850 71d5 +4851 71b9 +4852 71ce +4853 71d9 +4854 71dc +4855..4856 71c3 +4857 7368 +4858 749c +4859 74a3 +4860 7498 +4861 749f +4862 749e +4863 74e2 +4864..4865 750c +4866 7634 +4867 7638 +4868 763a +4869 76e7 +4870 76e5 +4871 77a0 +4872..4873 779e +4874 77a5 +4875 78e8 +4876 78da +4877 78ec +4878 78e7 +4879 79a6 +4880..4881 7a4d +4882 7a46 +4883 7a4c +4884 7a4b +4885 7aba +4886 7bd9 +4887 7c11 +4888 7bc9 +4889 7be4 +4890 7bdb +4891 7be1 +4892 7be9 +4893 7be6 +4894..4895 7cd5 +4896 7e0a +4897 7e11 +4898 7e08 +4899 7e1b +4900 7e23 +4901 7e1e +4902 7e1d +4903 7e09 +4904 7e10 +4905 7f79 +4906 7fb2 +4907..4908 7ff0 +4909 7fee +4910 8028 +4911 81b3 +4912 81a9 +4913 81a8 +4914 81fb +4915 8208 +4916..4917 8258 +4918 854a +4919 8559 +4920 8548 +4921..4922 8568 +4923 8543 +4924 8549 +4925 856d +4926 856a +4927 855e +4928 8783 +4929 879f +4930 879e +4931 87a2 +4932 878d +4933 8861 +4934 892a +4935 8932 +4936 8925 +4937 892b +4938 8921 +4939 89aa +4940 89a6 +4941 8ae6 +4942 8afa +4943 8aeb +4944 8af1 +4945 8b00 +4946 8adc +4947 8ae7 +4948 8aee +4949 8afe +4950..4951 8b01 +4952 8af7 +4953 8aed +4954 8af3 +4955 8af6 +4956 8afc +4957 8c6b +4958 8c6d +4959 8c93 +4960 8cf4 +4961 8e44 +4962 8e31 +4963 8e34 +4964 8e42 +4965 8e39 +4966 8e35 +4967 8f3b +4968 8f2f +4969 8f38 +4970 8f33 +4971 8fa8 +4972 8fa6 +4973 9075 +4974 9074 +4975 9078 +4976 9072 +4977 907c +4978 907a +4979 9134 +4980 9192 +4981 9320 +4982 9336 +4983 92f8 +4984 9333 +4985 932f +4986 9322 +4987 92fc +4988 932b +4989 9304 +4990 931a +4991 9310 +4992 9326 +4993 9321 +4994 9315 +4995 932e +4996 9319 +4997 95bb +4998..4999 96a7 +5000 96aa +5001 96d5 +5002 970e +5003 9711 +5004 9716 +5005 970d +5006 9713 +5007 970f +5008 975b +5009 e4c5 +5010 9766 +5011 9798 +5012 9830 +5013 9838 +5014 983b +5015 9837 +5016 982d +5017 9839 +5018 9824 +5019 9910 +5020 9928 +5021 991e +5022 991b +5023 9921 +5024 991a +5025 99ed +5026 99e2 +5027 99f1 +5028 9ab8 +5029 9abc +5030 9afb +5031 9aed +5032 9b28 +5033 9b91 +5034 9d15 +5035 9d23 +5036 9d26 +5037 9d28 +5038 9d12 +5039 9d1b +5040 9ed8 +5041 9ed4 +5042 9f8d +5043 9f9c +5044 512a +5045 511f +5046 5121 +5047 5132 +5048 52f5 +5049 568e +5050 5680 +5051 5690 +5052 5685 +5053 5687 +5054 568f +5055 58d5 +5056 58d3 +5057 58d1 +5058 58ce +5059 5b30 +5060 5b2a +5061 5b24 +5062 5b7a +5063 5c37 +5064 5c68 +5065 5dbc +5066 5dba +5067 5dbd +5068 5db8 +5069 5e6b +5070 5f4c +5071 5fbd +5072 61c9 +5073 61c2 +5074 61c7 +5075 61e6 +5076 61cb +5077 6232 +5078 6234 +5079 64ce +5080 64ca +5081 64d8 +5082 64e0 +5083 64f0 +5084 64e6 +5085 64ec +5086 64f1 +5087 64e2 +5088 64ed +5089..5090 6582 +5091 66d9 +5092 66d6 +5093 6a80 +5094 6a94 +5095 6a84 +5096 6aa2 +5097 6a9c +5098 6adb +5099 6aa3 +5100 6a7e +5101 6a97 +5102 6a90 +5103 6aa0 +5104 6b5c +5105 6bae +5106 6bda +5107 6c08 +5108 6fd8 +5109 6ff1 +5110..5111 6fdf +5112 6fdb +5113 6fe4 +5114 6feb +5115 6fef +5116 6f80 +5117 6fec +5118 6fe1 +5119 6fe9 +5120 6fd5 +5121 6fee +5122 6ff0 +5123 71e7 +5124 71df +5125 71ee +5126 71e6 +5127 71e5 +5128 71ed +5129 71ec +5130 71f4 +5131 71e0 +5132 7235 +5133 7246 +5134 7370 +5135 7372 +5136 74a9 +5137 74b0 +5138 74a6 +5139 74a8 +5140 7646 +5141 7642 +5142 764c +5143 76ea +5144 77b3 +5145 77aa +5146 77b0 +5147 77ac +5148 77a7 +5149 77ad +5150 77ef +5151 78f7 +5152 78fa +5153 78f4 +5154 78ef +5155 7901 +5156 79a7 +5157 79aa +5158 7a57 +5159 7abf +5160 7c07 +5161 7c0d +5162 7bfe +5163 7bf7 +5164 7c0c +5165 7be0 +5166 7ce0 +5167 7cdc +5168 7cde +5169 7ce2 +5170 7cdf +5171 7cd9 +5172 7cdd +5173 7e2e +5174 7e3e +5175 7e46 +5176 7e37 +5177 7e32 +5178 7e43 +5179 7e2b +5180 7e3d +5181 7e31 +5182 7e45 +5183 7e41 +5184 7e34 +5185 7e39 +5186 7e48 +5187 7e35 +5188 7e3f +5189 7e2f +5190 7f44 +5191 7ff3 +5192 7ffc +5193..5194 8071 +5195 8070 +5196 806f +5197 8073 +5198 81c6 +5199 81c3 +5200 81ba +5201 81c2 +5202 81c0 +5203 81bf +5204 81bd +5205 81c9 +5206 81be +5207 81e8 +5208 8209 +5209 8271 +5210 85aa +5211 8584 +5212 857e +5213 859c +5214 8591 +5215 8594 +5216 85af +5217 859b +5218 8587 +5219 85a8 +5220 858a +5221 85a6 +5222 8667 +5223 87c0 +5224 87d1 +5225 87b3 +5226 87d2 +5227 87c6 +5228 87ab +5229 87bb +5230 87ba +5231 87c8 +5232 87cb +5233 893b +5234 8936 +5235 8944 +5236 8938 +5237 893d +5238 89ac +5239 8b0e +5240 8b17 +5241 8b19 +5242 8b1b +5243 8b0a +5244 8b20 +5245 8b1d +5246 8b04 +5247 8b10 +5248 8c41 +5249 8c3f +5250 8c73 +5251 8cfa +5252 8cfd +5253 8cfc +5254 8cf8 +5255 8cfb +5256 8da8 +5257 8e49 +5258 8e4b +5259 8e48 +5260 8e4a +5261 8f44 +5262 8f3e +5263 8f42 +5264 8f45 +5265 8f3f +5266 907f +5267 907d +5268 9084 +5269..5270 9081 +5271 9080 +5272 9139 +5273 91a3 +5274 919e +5275 919c +5276 934d +5277 9382 +5278 9328 +5279 9375 +5280 934a +5281 9365 +5282 934b +5283 9318 +5284 937e +5285 936c +5286 935b +5287 9370 +5288 935a +5289 9354 +5290..5292 95ca +5293 95c8 +5294 95c6 +5295 96b1 +5296 96b8 +5297 96d6 +5298 971c +5299 971e +5300 97a0 +5301 97d3 +5302 9846 +5303 98b6 +5304 9935 +5305 9a01 +5306 99ff +5307 9bae +5308 9bab +5309 9baa +5310 9bad +5311 9d3b +5312 9d3f +5313 9e8b +5314 9ecf +5315 9ede +5316..5317 9edc +5318 9edb +5319 9f3e +5320 9f4b +5321 53e2 +5322 5695 +5323 56ae +5324 58d9 +5325 58d8 +5326 5b38 +5327 5f5d +5328 61e3 +5329 6233 +5330 64f4 +5331 64f2 +5332 64fe +5333 6506 +5334..5335 64fa +5336 64f7 +5337 65b7 +5338 66dc +5339 6726 +5340 6ab3 +5341 6aac +5342 6ac3 +5343 6abb +5344 6ab8 +5345 6ac2 +5346..5347 6aae +5348 6b5f +5349 6b78 +5350 6baf +5351 7009 +5352 700b +5353 6ffe +5354 7006 +5355 6ffa +5356 7011 +5357 700f +5358..5359 71fb +5360 71fe +5361 71f8 +5362 7377 +5363 7375 +5364 74a7 +5365 74bf +5366 7515 +5367 7656 +5368 7658 +5369 7652 +5370 77bd +5371 77bf +5372..5373 77bb +5374 790e +5375 79ae +5376..5377 7a61 +5378 7a60 +5379..5380 7ac4 +5381 7c2b +5382 7c27 +5383 7c2a +5384 7c1e +5385 7c23 +5386 7c21 +5387 7ce7 +5388..5389 7e54 +5390 7e5e +5391 7e5a +5392 7e61 +5393 7e52 +5394 7e59 +5395 7f48 +5396 7ff9 +5397 7ffb +5398 8077 +5399 8076 +5400 81cd +5401 81cf +5402 820a +5403 85cf +5404 85a9 +5405 85cd +5406 85d0 +5407 85c9 +5408 85b0 +5409 85ba +5410 85b9 +5411 87ef +5412 87ec +5413 87f2 +5414 87e0 +5415 8986 +5416 89b2 +5417 89f4 +5418 8b28 +5419 8b39 +5420 8b2c +5421 8b2b +5422 8c50 +5423 8d05 +5424 8e59 +5425 8e63 +5426 8e66 +5427 8e64 +5428 8e5f +5429 8e55 +5430 8ec0 +5431 8f49 +5432 8f4d +5433 9087 +5434 9083 +5435 9088 +5436..5437 91ab +5438 91d0 +5439 9394 +5440 938a +5441 9396 +5442 93a2 +5443 93b3 +5444 93ae +5445 93ac +5446 93b0 +5447 9398 +5448 939a +5449 9397 +5450 95d4 +5451 95d6 +5452 95d0 +5453 95d5 +5454 96e2 +5455 96dc +5456 96d9 +5457 96db +5458 96de +5459 9724 +5460 97a3 +5461 97a6 +5462 97ad +5463 97f9 +5464 984d +5465 984f +5466 984c +5467 984e +5468 9853 +5469 98ba +5470..5471 993e +5472 993d +5473 992e +5474 99a5 +5475 9a0e +5476 9ac1 +5477 9b03 +5478 9b06 +5479 9b4f +5480 9b4e +5481 9b4d +5482 9bca +5483 9bc9 +5484 9bfd +5485 9bc8 +5486 9bc0 +5487 9d51 +5488 9d5d +5489 9d60 +5490 9ee0 +5491 9f15 +5492 9f2c +5493 5133 +5494 56a5 +5495 56a8 +5496..5497 58de +5498 58e2 +5499 5bf5 +5500 9f90 +5501 5eec +5502 61f2 +5503 61f7 +5504 61f6 +5505 61f5 +5506 6500 +5507 650f +5508 66e0 +5509 66dd +5510 6ae5 +5511 6add +5512 6ada +5513 6ad3 +5514 701b +5515 701f +5516 7028 +5517 701a +5518 701d +5519 7015 +5520 7018 +5521 7206 +5522 720d +5523 7258 +5524 72a2 +5525 7378 +5526 737a +5527 74bd +5528 74ca +5529 74e3 +5530 7587 +5531 7586 +5532 765f +5533 7661 +5534 77c7 +5535 7919 +5536 79b1 +5537 7a6b +5538 7a69 +5539..5540 7c3e +5541 7c38 +5542 7c3d +5543 7c37 +5544 7c40 +5545 7e6b +5546 7e6d +5547 7e79 +5548..5549 7e69 +5550 7e73 +5551 7f85 +5552 7fb6 +5553 7fb9 +5554 7fb8 +5555 81d8 +5556 85e9 +5557 85dd +5558 85ea +5559 85d5 +5560..5561 85e4 +5562 85f7 +5563 87fb +5564 8805 +5565 880d +5566 87f9 +5567 87fe +5568 8960 +5569 895f +5570 8956 +5571 895e +5572 8b41 +5573 8b5c +5574 8b58 +5575 8b49 +5576 8b5a +5577..5578 8b4e +5579 8b46 +5580 8b59 +5581 8d08 +5582 8d0a +5583 8e7c +5584 8e72 +5585 8e87 +5586 8e76 +5587 8e6c +5588 8e7a +5589 8e74 +5590 8f54 +5591 8f4e +5592 8fad +5593..5594 908a +5595 91b1 +5596 91ae +5597 93e1 +5598 93d1 +5599 93df +5600 93c3 +5601 93c8 +5602..5603 93dc +5604 93d6 +5605 93e2 +5606 93cd +5607 93d8 +5608 93e4 +5609 93d7 +5610 93e8 +5611 95dc +5612 96b4 +5613 96e3 +5614 972a +5615 9727 +5616 9761 +5617 97dc +5618 97fb +5619 985e +5620 9858 +5621 985b +5622 98bc +5623 9945 +5624 9949 +5625 9a16 +5626 9a19 +5627 9b0d +5628 9be8 +5629 9be7 +5630 9bd6 +5631 9bdb +5632 9d89 +5633 9d61 +5634 9d72 +5635 9d6a +5636 9d6c +5637 9e92 +5638 9e97 +5639 9e93 +5640 9eb4 +5641 52f8 +5642 56b7 +5643 56b6 +5644 56b4 +5645 56bc +5646 58e4 +5647 5b40 +5648 5b43 +5649 5b7d +5650 5bf6 +5651 5dc9 +5652 61f8 +5653 61fa +5654 6518 +5655 6514 +5656 6519 +5657 66e6 +5658 6727 +5659 6aec +5660 703e +5661 7030 +5662 7032 +5663 7210 +5664 737b +5665 74cf +5666 7662 +5667 7665 +5668 7926 +5669 792a +5670 792c +5671 792b +5672 7ac7 +5673 7af6 +5674 7c4c +5675 7c43 +5676 7c4d +5677..5678 7cef +5679 8fae +5680 7e7d +5681 7e7c +5682 7e82 +5683 7f4c +5684 8000 +5685 81da +5686 8266 +5687 85fb +5688 85f9 +5689 8611 +5690 85fa +5691 8606 +5692 860b +5693 8607 +5694 860a +5695..5696 8814 +5697 8964 +5698 89ba +5699 89f8 +5700 8b70 +5701 8b6c +5702 8b66 +5703 8b6f +5704 8b5f +5705 8b6b +5706 8d0f +5707 8d0d +5708 8e89 +5709 8e81 +5710 8e85 +5711 8e82 +5712 91b4 +5713 91cb +5714 9418 +5715 9403 +5716 93fd +5717 95e1 +5718 9730 +5719 98c4 +5720 9952 +5721 9951 +5722 99a8 +5723 9a2b +5724 9a30 +5725 9a37 +5726 9a35 +5727 9c13 +5728 9c0d +5729 9e79 +5730 9eb5 +5731 9ee8 +5732 9f2f +5733 9f5f +5734 9f63 +5735 9f61 +5736..5737 5137 +5738 56c1 +5739 56c0 +5740 56c2 +5741 5914 +5742 5c6c +5743 5dcd +5744 61fc +5745 61fe +5746 651d +5747 651c +5748 6595 +5749 66e9 +5750 6afb +5751 6b04 +5752 6afa +5753 6bb2 +5754 704c +5755 721b +5756 72a7 +5757 74d6 +5758 74d4 +5759 7669 +5760 77d3 +5761 7c50 +5762 7e8f +5763 7e8c +5764 7fbc +5765 8617 +5766 862d +5767 861a +5768 8823 +5769 8822 +5770 8821 +5771 881f +5772 896a +5773 896c +5774 89bd +5775 8b74 +5776 8b77 +5777 8b7d +5778 8d13 +5779 8e8a +5780 8e8d +5781 8e8b +5782 8f5f +5783 8faf +5784 91ba +5785 942e +5786 9433 +5787 9435 +5788 943a +5789 9438 +5790 9432 +5791 942b +5792 95e2 +5793..5794 9738 +5795 9732 +5796 97ff +5797 9867 +5798 9865 +5799 9957 +5800 9a45 +5801 9a43 +5802 9a40 +5803 9a3e +5804 9acf +5805 9b54 +5806 9b51 +5807 9c2d +5808 9c25 +5809 9daf +5810 9db4 +5811 9dc2 +5812 9db8 +5813 9e9d +5814 9eef +5815 9f19 +5816 9f5c +5817..5818 9f66 +5819 513c +5820 513b +5821 56c8 +5822 56ca +5823 56c9 +5824 5b7f +5825 5dd4 +5826 5dd2 +5827 5f4e +5828 61ff +5829 6524 +5830 6b0a +5831 6b61 +5832 7051 +5833 7058 +5834 7380 +5835 74e4 +5836 758a +5837 766e +5838 766c +5839 79b3 +5840 7c60 +5841 7c5f +5842 807e +5843 807d +5844 81df +5845 8972 +5846 896f +5847 89fc +5848 8b80 +5849..5850 8d16 +5851 8e91 +5852 8e93 +5853 8f61 +5854 9148 +5855 9444 +5856..5857 9451 +5858..5859 973d +5860 97c3 +5861 97c1 +5862 986b +5863 9955 +5864 9a55 +5865 9a4d +5866 9ad2 +5867 9b1a +5868 9c49 +5869 9c31 +5870 9c3e +5871 9c3b +5872 9dd3 +5873 9dd7 +5874 9f34 +5875 9f6c +5876 9f6a +5877 9f94 +5878 56cc +5879 5dd6 +5880 6200 +5881 6523 +5882 652b +5883 652a +5884 66ec +5885 6b10 +5886 74da +5887 7aca +5888 7c64 +5889 7c63 +5890 7c65 +5891 7e93 +5892 7e96 +5893 7e94 +5894 81e2 +5895 8638 +5896 863f +5897 8831 +5898 8b8a +5899 9090 +5900 908f +5901 9463 +5902 9460 +5903 9464 +5904 9768 +5905 986f +5906 995c +5907..5908 9a5a +5909 9a57 +5910..5911 9ad3 +5912 9ad1 +5913 9c54 +5914 9c57 +5915 9c56 +5916 9de5 +5917 9e9f +5918 9ef4 +5919 56d1 +5920 58e9 +5921 652c +5922 705e +5923..5924 7671 +5925 77d7 +5926 7f50 +5927 7f88 +5928 8836 +5929 8839 +5930 8862 +5931 8b93 +5932 8b92 +5933 8b96 +5934 8277 +5935 8d1b +5936 91c0 +5937 946a +5938 9742 +5939 9748 +5940 9744 +5941 97c6 +5942 9870 +5943 9a5f +5944 9b22 +5945 9b58 +5946 9c5f +5947..5948 9df9 +5949..5950 9e7c +5951 9f07 +5952 9f77 +5953 9f72 +5954 5ef3 +5955 6b16 +5956 7063 +5957 7c6c +5958 7c6e +5959 883b +5960 89c0 +5961 8ea1 +5962 91c1 +5963 9472 +5964 9470 +5965 9871 +5966 995e +5967 9ad6 +5968 9b23 +5969 9ecc +5970 7064 +5971 77da +5972 8b9a +5973 9477 +5974 97c9 +5975 9a62 +5976 9a65 +5977 7e9c +5978 8b9c +5979 8eaa +5980 91c5 +5981..5982 947d +5983 947c +5984..5985 9c77 +5986 9ef7 +5987 8c54 +5988 947f +5989 9e1a +5990 7228 +5991 9a6a +5992 9b31 +5993 9e1b +5994 9e1e +5995 7c72 +5996 4e42 +5997 4e5c +5998 51f5 +5999 531a +6000 5382 +6001 4e07 +6002 4e0c +6003 4e47 +6004 4e8d +6005 56d7 +6006 5c6e +6007 5f73 +6008 4e0f +6009 5187 +6010 4e0e +6011 4e2e +6012 4e93 +6013 4ec2 +6014 4ec9 +6015 4ec8 +6016 5198 +6017 52fc +6018 536c +6019 53b9 +6020 5720 +6021 5903 +6022 592c +6023 5c10 +6024 5dff +6025 65e1 +6026 6bb3 +6027 6bcc +6028 6c14 +6029 723f +6030 4e31 +6031 4e3c +6032 4ee8 +6033 4edc +6034 4ee9 +6035 4ee1 +6036 4edd +6037 4eda +6038 520c +6039 5209 +6040 531c +6041 534c +6042..6043 5722 +6044 5917 +6045 592f +6046 5b81 +6047 5b84 +6048 5c12 +6049 5c3b +6050 5c74 +6051 5c73 +6052 5e04 +6053 5e80 +6054 5e82 +6055 5fc9 +6056 6209 +6057 6250 +6058 6c15 +6059 6c36 +6060 6c43 +6061 6c3f +6062 6c3b +6063 72ae +6064 72b0 +6065 738a +6066 79b8 +6067 808a +6068 961e +6069 4f0e +6070 4f18 +6071 4f2c +6072 4ef5 +6073 4f14 +6074 4ef1 +6075 4f00 +6076 4ef7 +6077 4f08 +6078 4f1d +6079 4f02 +6080 4f05 +6081 4f22 +6082 4f13 +6083 4f04 +6084 4ef4 +6085 4f12 +6086 51b1 +6087 5213 +6088 5210 +6089 52a6 +6090 5322 +6091 531f +6092 534d +6093 538a +6094 5407 +6095 56e1 +6096 56df +6097 572e +6098 572a +6099 5734 +6100 593c +6101 5980 +6102 597c +6103 5985 +6104 597b +6105 597e +6106 5977 +6107 597f +6108 5b56 +6109 5c15 +6110 5c25 +6111 5c7c +6112..6113 5c7a +6114 5c7e +6115 5ddf +6116 5e75 +6117 5e84 +6118 5f02 +6119 5f1a +6120 5f74 +6121 5fd5 +6122 5fd4 +6123 5fcf +6124 625c +6125 625e +6126 6264 +6127 6261 +6128 6266 +6129 6262 +6130 6259 +6131 6260 +6132 625a +6133 6265 +6134 6537 +6135 65ef +6136 65ee +6137 673e +6138 6739 +6139 6738 +6140 673b +6141 673a +6142 673f +6143 673c +6144 6733 +6145 6c18 +6146 6c46 +6147 6c52 +6148 6c5c +6149 6c4f +6150 6c4a +6151 6c54 +6152..6153 6c4b +6154 7071 +6155 725e +6156..6157 72b4 +6158 738e +6159 752a +6160 767f +6161 7a75 +6162 7f51 +6163 8278 +6164 827c +6165 8280 +6166 827d +6167 827f +6168 864d +6169 897e +6170 9099 +6171 e7d3 +6172 9098 +6173 909b +6174 9094 +6175 9622 +6176 9624 +6177 9620 +6178 9623 +6179 4f56 +6180 4f3b +6181 4f62 +6182 4f49 +6183 4f53 +6184 4f64 +6185 4f3e +6186 4f67 +6187 4f52 +6188 4f5f +6189 4f41 +6190 4f58 +6191 4f2d +6192 4f33 +6193 4f3f +6194 4f61 +6195 518f +6196 51b9 +6197 521c +6198 521e +6199 5221 +6200..6201 52ad +6202 5309 +6203 5363 +6204 5372 +6205..6206 538e +6207 5430 +6208 5437 +6209 542a +6210 5454 +6211 5445 +6212 5419 +6213 541c +6214 5425 +6215 5418 +6216 543d +6217 544f +6218 5441 +6219 5428 +6220 5424 +6221 5447 +6222 56ee +6223 56e7 +6224 56e5 +6225 5741 +6226 5745 +6227 574c +6228 5749 +6229 574b +6230 5752 +6231 5906 +6232 5940 +6233 59a6 +6234 5998 +6235 59a0 +6236 5997 +6237 598e +6238 59a2 +6239 5990 +6240 598f +6241 59a7 +6242 59a1 +6243 5b8e +6244 5b92 +6245 5c28 +6246 5c2a +6247 5c8d +6248 5c8f +6249 5c88 +6250 5c8b +6251 5c89 +6252 5c92 +6253 5c8a +6254 5c86 +6255 5c93 +6256 5c95 +6257 5de0 +6258 5e0a +6259 5e0e +6260 5e8b +6261 5e89 +6262 5e8c +6263 5e88 +6264 5e8d +6265 5f05 +6266 5f1d +6267 5f78 +6268 5f76 +6269 5fd2 +6270 5fd1 +6271 5fd0 +6272 5fed +6273 5fe8 +6274 5fee +6275 5ff3 +6276 5fe1 +6277 5fe4 +6278 5fe3 +6279 5ffa +6280 5fef +6281 5ff7 +6282 5ffb +6283 6000 +6284 5ff4 +6285 623a +6286 6283 +6287 628c +6288..6289 628e +6290 6294 +6291 6287 +6292 6271 +6293 627b +6294 627a +6295 6270 +6296 6281 +6297 6288 +6298 6277 +6299 627d +6300 6272 +6301 6274 +6302 65f0 +6303 65f4 +6304 65f3 +6305 65f2 +6306 65f5 +6307 6745 +6308 6747 +6309 6759 +6310 6755 +6311 674c +6312 6748 +6313 675d +6314 674d +6315 675a +6316 674b +6317 6bd0 +6318..6319 6c19 +6320 6c78 +6321 6c67 +6322 6c6b +6323 6c84 +6324 6c8b +6325 6c8f +6326 6c71 +6327 6c6f +6328 6c69 +6329 6c9a +6330 6c6d +6331 6c87 +6332 6c95 +6333 6c9c +6334 6c66 +6335 6c73 +6336 6c65 +6337 6c7b +6338 6c8e +6339 7074 +6340 707a +6341 7263 +6342 72bf +6343 72bd +6344 72c3 +6345 72c6 +6346 72c1 +6347 72ba +6348 72c5 +6349 7395 +6350 7397 +6351..6352 7393 +6353 7392 +6354 753a +6355 7539 +6356..6357 7594 +6358 7681 +6359 793d +6360 8034 +6361 8095 +6362 8099 +6363 8090 +6364 8092 +6365 809c +6366 8290 +6367 828f +6368 8285 +6369 828e +6370 8291 +6371 8293 +6372 828a +6373..6374 8283 +6375 8c78 +6376 8fc9 +6377 8fbf +6378 909f +6379 90a1 +6380 90a5 +6381 909e +6382 90a7 +6383 90a0 +6384 9630 +6385 9628 +6386 962f +6387 962d +6388 4e33 +6389 4f98 +6390 4f7c +6391 4f85 +6392 4f7d +6393 4f80 +6394 4f87 +6395 4f76 +6396 4f74 +6397 4f89 +6398 4f84 +6399 4f77 +6400 4f4c +6401 4f97 +6402 4f6a +6403 4f9a +6404 4f79 +6405 4f81 +6406 4f78 +6407 4f90 +6408 4f9c +6409 4f94 +6410 4f9e +6411 4f92 +6412 4f82 +6413 4f95 +6414 4f6b +6415 4f6e +6416 519e +6417 51bc +6418 51be +6419 5235 +6420..6421 5232 +6422 5246 +6423 5231 +6424 52bc +6425..6426 530a +6427 533c +6428 5392 +6429 5394 +6430 5487 +6431 547f +6432 5481 +6433 5491 +6434 5482 +6435 5488 +6436 546b +6437 547a +6438 547e +6439 5465 +6440 546c +6441 5474 +6442 5466 +6443 548d +6444 546f +6445 5461 +6446 5460 +6447 5498 +6448 5463 +6449 5467 +6450 5464 +6451 56f7 +6452 56f9 +6453 576f +6454 5772 +6455 576d +6456 576b +6457 5771 +6458 5770 +6459 5776 +6460 5780 +6461 5775 +6462 577b +6463..6464 5773 +6465 5762 +6466 5768 +6467 577d +6468 590c +6469 5945 +6470 59b5 +6471 59ba +6472 59cf +6473 59ce +6474 59b2 +6475 59cc +6476 59c1 +6477 59b6 +6478 59bc +6479 59c3 +6480 59d6 +6481 59b1 +6482 59bd +6483 59c0 +6484 59c8 +6485 59b4 +6486 59c7 +6487 5b62 +6488 5b65 +6489 5b93 +6490 5b95 +6491 5c44 +6492 5c47 +6493 5cae +6494 5ca4 +6495 5ca0 +6496 5cb5 +6497 5caf +6498 5ca8 +6499 5cac +6500 5c9f +6501 5ca3 +6502 5cad +6503 5ca2 +6504 5caa +6505 5ca7 +6506 5c9d +6507 5ca5 +6508 5cb6 +6509 5cb0 +6510 5ca6 +6511 5e17 +6512 5e14 +6513 5e19 +6514 5f28 +6515..6517 5f22 +6518 5f54 +6519 5f82 +6520 5f7e +6521 5f7d +6522 5fde +6523 5fe5 +6524 602d +6525 6026 +6526 6019 +6527 6032 +6528 600b +6529 6034 +6530 600a +6531 6017 +6532 6033 +6533 601a +6534 601e +6535 602c +6536 6022 +6537 600d +6538 6010 +6539 602e +6540 6013 +6541 6011 +6542 600c +6543 6009 +6544 601c +6545 6214 +6546 623d +6547 62ad +6548 62b4 +6549 62d1 +6550 62be +6551 62aa +6552 62b6 +6553 62ca +6554 62ae +6555 62b3 +6556 62af +6557 62bb +6558 62a9 +6559 62b0 +6560 62b8 +6561 653d +6562 65a8 +6563 65bb +6564 6609 +6565 65fc +6566 6604 +6567 6612 +6568 6608 +6569 65fb +6570 6603 +6571 660b +6572 660d +6573 6605 +6574 65fd +6575 6611 +6576 6610 +6577 66f6 +6578 670a +6579 6785 +6580 676c +6581 678e +6582 6792 +6583 6776 +6584 677b +6585 6798 +6586 6786 +6587 6784 +6588 6774 +6589 678d +6590 678c +6591 677a +6592 679f +6593 6791 +6594 6799 +6595 6783 +6596 677d +6597 6781 +6598..6599 6778 +6600 6794 +6601 6b25 +6602 6b80 +6603 6b7e +6604 6bde +6605 6c1d +6606 6c93 +6607 6cec +6608 6ceb +6609 6cee +6610 6cd9 +6611 6cb6 +6612 6cd4 +6613 6cad +6614 6ce7 +6615 6cb7 +6616 6cd0 +6617 6cc2 +6618 6cba +6619 6cc3 +6620 6cc6 +6621 6ced +6622 6cf2 +6623 6cd2 +6624 6cdd +6625 6cb4 +6626 6c8a +6627 6c9d +6628 6c80 +6629 6cde +6630 6cc0 +6631 6d30 +6632 6ccd +6633 6cc7 +6634 6cb0 +6635 6cf9 +6636 6ccf +6637 6ce9 +6638 6cd1 +6639 7094 +6640 7098 +6641 7085 +6642 7093 +6643 7086 +6644 7084 +6645 7091 +6646 7096 +6647 7082 +6648 709a +6649 7083 +6650 726a +6651 72d6 +6652 72cb +6653 72d8 +6654 72c9 +6655 72dc +6656 72d2 +6657 72d4 +6658 72da +6659 72cc +6660 72d1 +6661 73a4 +6662 73a1 +6663 73ad +6664 73a6 +6665 73a2 +6666 73a0 +6667 73ac +6668 739d +6669 74dd +6670 74e8 +6671..6672 753f +6673 753e +6674 758c +6675 7598 +6676 76af +6677 76f3 +6678 76f1 +6679 76f0 +6680 76f5 +6681 77f8 +6682 77fc +6683 77f9 +6684 77fb +6685 77fa +6686 77f7 +6687 7942 +6688 793f +6689 79c5 +6690 7a78 +6691 7a7b +6692 7afb +6693 7c75 +6694 7cfd +6695 8035 +6696 808f +6697 80ae +6698 80a3 +6699 80b8 +6700 80b5 +6701 80ad +6702 8220 +6703 82a0 +6704 82c0 +6705 82ab +6706 829a +6707 8298 +6708 829b +6709 82b5 +6710 82a7 +6711 82ae +6712 82bc +6713 829e +6714 82ba +6715 82b4 +6716 82a8 +6717 82a1 +6718 82a9 +6719 82c2 +6720 82a4 +6721 82c3 +6722 82b6 +6723 82a2 +6724 8670 +6725 866f +6726..6727 866d +6728 8c56 +6729 8fd2 +6730 8fcb +6731 8fd3 +6732 8fcd +6733 8fd6 +6734 8fd5 +6735 8fd7 +6736 90b2 +6737 90b4 +6738 90af +6739 90b3 +6740 90b0 +6741 9639 +6742 963d +6743 963c +6744 963a +6745 9643 +6746 4fcd +6747 4fc5 +6748 4fd3 +6749 4fb2 +6750 4fc9 +6751 4fcb +6752 4fc1 +6753 4fd4 +6754 4fdc +6755 4fd9 +6756 4fbb +6757 4fb3 +6758 4fdb +6759 4fc7 +6760 4fd6 +6761 4fba +6762 4fc0 +6763 4fb9 +6764 4fec +6765 5244 +6766 5249 +6767 52c0 +6768 52c2 +6769 533d +6770 537c +6771 5397 +6772 5396 +6773 5399 +6774 5398 +6775 54ba +6776 54a1 +6777 54ad +6778 54a5 +6779 54cf +6780 54c3 +6781 830d +6782 54b7 +6783 54ae +6784 54d6 +6785 54b6 +6786..6787 54c5 +6788 54a0 +6789 5470 +6790 54bc +6791 54a2 +6792 54be +6793 5472 +6794 54de +6795 54b0 +6796 57b5 +6797..6798 579e +6799 57a4 +6800 578c +6801 5797 +6802 579d +6803 579b +6804 5794 +6805 5798 +6806 578f +6807 5799 +6808 57a5 +6809 579a +6810 5795 +6811 58f4 +6812 590d +6813 5953 +6814 59e1 +6815 59de +6816 59ee +6817 5a00 +6818 59f1 +6819 59dd +6820 59fa +6821 59fd +6822 59fc +6823 59f6 +6824 59e4 +6825 59f2 +6826 59f7 +6827 59db +6828 59e9 +6829 59f3 +6830 59f5 +6831 59e0 +6832 59fe +6833 59f4 +6834 59ed +6835 5ba8 +6836 5c4c +6837 5cd0 +6838 5cd8 +6839 5ccc +6840 5cd7 +6841 5ccb +6842 5cdb +6843 5cde +6844 5cda +6845 5cc9 +6846 5cc7 +6847 5cca +6848 5cd6 +6849..6850 5cd3 +6851 5ccf +6852 5cc8 +6853 5cc6 +6854 5cce +6855 5cdf +6856 5cf8 +6857 5df9 +6858..6860 5e21 +6861 5e20 +6862 5e24 +6863 5eb0 +6864 5ea4 +6865 5ea2 +6866 5e9b +6867 5ea3 +6868 5ea5 +6869 5f07 +6870 5f2e +6871 5f56 +6872 5f86 +6873 6037 +6874 6039 +6875 6054 +6876 6072 +6877 605e +6878 6045 +6879 6053 +6880 6047 +6881 6049 +6882 605b +6883 604c +6884 6040 +6885 6042 +6886 605f +6887 6024 +6888 6044 +6889 6058 +6890 6066 +6891 606e +6892..6893 6242 +6894 62cf +6895 630d +6896 630b +6897 62f5 +6898 630e +6899 6303 +6900 62eb +6901 62f9 +6902 630f +6903 630c +6904 62f8 +6905 62f6 +6906 6300 +6907..6908 6313 +6909 62fa +6910 6315 +6911 62fb +6912 62f0 +6913 6541 +6914 6543 +6915 65aa +6916 65bf +6917 6636 +6918 6621 +6919 6632 +6920 6635 +6921 661c +6922 6626 +6923 6622 +6924 6633 +6925 662b +6926 663a +6927 661d +6928 6634 +6929 6639 +6930 662e +6931..6932 670f +6933 67c1 +6934 67f2 +6935 67c8 +6936 67ba +6937 67dc +6938 67bb +6939 67f8 +6940 67d8 +6941 67c0 +6942 67b7 +6943 67c5 +6944 67eb +6945 67e4 +6946 67df +6947 67b5 +6948 67cd +6949 67b3 +6950 67f7 +6951 67f6 +6952 67ee +6953 67e3 +6954 67c2 +6955 67b9 +6956 67ce +6957 67e7 +6958 67f0 +6959 67b2 +6960 67fc +6961 67c6 +6962 67ed +6963 67cc +6964 67ae +6965 67e6 +6966 67db +6967 67fa +6968..6969 67c9 +6970 67c3 +6971 67ea +6972 67cb +6973 6b28 +6974 6b82 +6975 6b84 +6976 6bb6 +6977 6bd6 +6978 6bd8 +6979 6be0 +6980..6981 6c20 +6982 6d28 +6983 6d34 +6984 6d2d +6985 6d1f +6986 6d3c +6987 6d3f +6988 6d12 +6989 6d0a +6990 6cda +6991 6d33 +6992 6d04 +6993 6d19 +6994 6d3a +6995 6d1a +6996 6d11 +6997 6d00 +6998 6d1d +6999 6d42 +7000 6d01 +7001 6d18 +7002 6d37 +7003 6d03 +7004 6d0f +7005 6d40 +7006 6d07 +7007 6d20 +7008 6d2c +7009 6d08 +7010 6d22 +7011 6d09 +7012 6d10 +7013 70b7 +7014 709f +7015 70be +7016 70b1 +7017 70b0 +7018 70a1 +7019..7020 70b4 +7021 70a9 +7022 7241 +7023..7024 7249 +7025 726c +7026 7270 +7027 7273 +7028 726e +7029 72ca +7030 72e4 +7031 72e8 +7032 72eb +7033 72df +7034 72ea +7035 72e6 +7036 72e3 +7037 7385 +7038 73cc +7039 73c2 +7040 73c8 +7041 73c5 +7042 73b9 +7043 73b6 +7044 73b5 +7045 73b4 +7046 73eb +7047 73bf +7048 73c7 +7049 73be +7050 73c3 +7051 73c6 +7052 73b8 +7053 73cb +7054 74ec +7055 74ee +7056 752e +7057..7058 7547 +7059 75a7 +7060 75aa +7061 7679 +7062 76c4 +7063 7708 +7064..7066 7703 +7067 770a +7068 76f7 +7069 76fb +7070 76fa +7071..7072 77e7 +7073 7806 +7074..7075 7811 +7076 7805 +7077 7810 +7078 780f +7079 780e +7080 7809 +7081 7803 +7082 7813 +7083 794a +7084 794c +7085 794b +7086 7945 +7087 7944 +7088 79d5 +7089 79cd +7090 79cf +7091 79d6 +7092 79ce +7093 7a80 +7094 7a7e +7095 7ad1 +7096..7097 7b00 +7098 7c7a +7099..7100 7c78 +7101..7103 7c7f +7104 7d03 +7105 7d08 +7106 7d01 +7107 7f58 +7108 7f91 +7109 7f8d +7110 7fbe +7111 8007 +7112..7113 800e +7114 8014 +7115 8037 +7116 80d8 +7117 80c7 +7118 80e0 +7119 80d1 +7120 80c8 +7121 80c2 +7122 80d0 +7123 80c5 +7124 80e3 +7125 80d9 +7126 80dc +7127 80ca +7128 80d5 +7129 80c9 +7130 80cf +7131 80d7 +7132 80e6 +7133 80cd +7134 81ff +7135 8221 +7136 8294 +7137 82d9 +7138 82fe +7139 82f9 +7140 8307 +7141 82e8 +7142 8300 +7143 82d5 +7144 833a +7145 82eb +7146 82d6 +7147 82f4 +7148 82ec +7149 82e1 +7150 82f2 +7151 82f5 +7152 830c +7153 82fb +7154 82f6 +7155 82f0 +7156 82ea +7157 82e4 +7158 82e0 +7159 82fa +7160 82f3 +7161 82ed +7162 8677 +7163 8674 +7164 867c +7165 8673 +7166 8841 +7167 884e +7168 8867 +7169 886a +7170 8869 +7171 89d3 +7172 8a04 +7173 8a07 +7174 8d72 +7175 8fe3 +7176 8fe1 +7177 8fee +7178 8fe0 +7179 90f1 +7180 90bd +7181 90bf +7182 90d5 +7183 90c5 +7184 90be +7185 90c7 +7186 90cb +7187 90c8 +7188 91d4 +7189 91d3 +7190 9654 +7191 964f +7192 9651 +7193 9653 +7194 964a +7195 964e +7196 501e +7197 5005 +7198 5007 +7199 5013 +7200 5022 +7201 5030 +7202 501b +7203 4ff5 +7204 4ff4 +7205 5033 +7206 5037 +7207 502c +7208..7209 4ff6 +7210 5017 +7211 501c +7212 5020 +7213 5027 +7214 5035 +7215 502f +7216 5031 +7217 500e +7218 515a +7219 5194 +7220 5193 +7221 51ca +7222..7223 51c4 +7224 51c8 +7225 51ce +7226 5261 +7227 525a +7228 5252 +7229..7230 525e +7231 5255 +7232 5262 +7233 52cd +7234 530e +7235 539e +7236 5526 +7237 54e2 +7238 5517 +7239 5512 +7240 54e7 +7241 54f3 +7242 54e4 +7243 551a +7244 54ff +7245 5504 +7246 5508 +7247 54eb +7248 5511 +7249 5505 +7250 54f1 +7251 550a +7252 54fb +7253..7254 54f7 +7255 54e0 +7256 550e +7257 5503 +7258 550b +7259..7260 5701 +7261 57cc +7262 5832 +7263 57d5 +7264 57d2 +7265 57ba +7266 57c6 +7267 57bd +7268 57bc +7269 57b8 +7270 57b6 +7271 57bf +7272 57c7 +7273 57d0 +7274 57b9 +7275 57c1 +7276 590e +7277 594a +7278 5a19 +7279 5a16 +7280..7281 5a2d +7282 5a15 +7283 5a0f +7284 5a17 +7285 5a0a +7286 5a1e +7287 5a33 +7288 5b6c +7289 5ba7 +7290 5bad +7291 5bac +7292 5c03 +7293 5c56 +7294 5c54 +7295 5cec +7296 5cff +7297 5cee +7298 5cf1 +7299 5cf7 +7300 5d00 +7301 5cf9 +7302 5e29 +7303 5e28 +7304 5ea8 +7305 5eae +7306 5eaa +7307 5eac +7308 5f33 +7309 5f30 +7310 5f67 +7311 605d +7312 605a +7313 6067 +7314 6041 +7315 60a2 +7316 6088 +7317 6080 +7318 6092 +7319 6081 +7320 609d +7321 6083 +7322 6095 +7323 609b +7324 6097 +7325 6087 +7326 609c +7327 608e +7328 6219 +7329 6246 +7330 62f2 +7331 6310 +7332 6356 +7333 632c +7334..7335 6344 +7336 6336 +7337 6343 +7338 63e4 +7339 6339 +7340 634b +7341 634a +7342 633c +7343 6329 +7344 6341 +7345 6334 +7346 6358 +7347 6354 +7348 6359 +7349 632d +7350 6347 +7351 6333 +7352 635a +7353 6351 +7354 6338 +7355 6357 +7356 6340 +7357 6348 +7358 654a +7359 6546 +7360 65c6 +7361..7362 65c3 +7363 65c2 +7364 664a +7365 665f +7366 6647 +7367 6651 +7368..7369 6712 +7370 681f +7371 681a +7372 6849 +7373..7374 6832 +7375 683b +7376 684b +7377 684f +7378 6816 +7379 6831 +7380 681c +7381 6835 +7382 682b +7383 682d +7384 682f +7385 684e +7386 6844 +7387 6834 +7388 681d +7389 6812 +7390 6814 +7391 6826 +7392 6828 +7393 682e +7394 684d +7395 683a +7396 6825 +7397 6820 +7398 6b2c +7399 6b2f +7400 6b2d +7401 6b31 +7402 6b34 +7403 6b6d +7404 8082 +7405 6b88 +7406 6be6 +7407 6be4 +7408 6be8 +7409 6be3 +7410 6be2 +7411 6be7 +7412 6c25 +7413 6d7a +7414..7415 6d63 +7416 6d76 +7417 6d0d +7418 6d61 +7419 6d92 +7420 6d58 +7421 6d62 +7422 6d6d +7423 6d6f +7424 6d91 +7425 6d8d +7426 6def +7427 6d7f +7428 6d86 +7429 6d5e +7430 6d67 +7431 6d60 +7432 6d97 +7433 6d70 +7434 6d7c +7435 6d5f +7436 6d82 +7437 6d98 +7438 6d2f +7439 6d68 +7440 6d8b +7441 6d7e +7442 6d80 +7443 6d84 +7444 6d16 +7445 6d83 +7446 6d7b +7447 6d7d +7448 6d75 +7449 6d90 +7450 70dc +7451 70d3 +7452 70d1 +7453 70dd +7454 70cb +7455 7f39 +7456 70e2 +7457 70d7 +7458 70d2 +7459 70de +7460 70e0 +7461 70d4 +7462 70cd +7463..7465 70c5 +7466 70da +7467 70ce +7468 70e1 +7469 7242 +7470 7278 +7471 7277 +7472 7276 +7473 7300 +7474 72fa +7475 72f4 +7476 72fe +7477 72f6 +7478 72f3 +7479 72fb +7480 7301 +7481 73d3 +7482 73d9 +7483 73e5 +7484 73d6 +7485 73bc +7486 73e7 +7487 73e3 +7488 73e9 +7489 73dc +7490 73d2 +7491 73db +7492 73d4 +7493 73dd +7494 73da +7495..7496 73d7 +7497 73e8 +7498..7499 74de +7500..7501 74f4 +7502 7521 +7503 755b +7504 755f +7505 75b0 +7506 75c1 +7507 75bb +7508 75c4 +7509 75c0 +7510 75bf +7511 75b6 +7512 75ba +7513 768a +7514 76c9 +7515 771d +7516 771b +7517 7710 +7518 7713 +7519 7712 +7520 7723 +7521 7711 +7522 7715 +7523..7524 7719 +7525 7722 +7526 7727 +7527 7823 +7528 782c +7529 7822 +7530 7835 +7531 782f +7532 7828 +7533 782e +7534 782b +7535 7821 +7536 7829 +7537 7833 +7538 782a +7539 7831 +7540 7954 +7541 795b +7542 794f +7543 795c +7544 7953 +7545 7952 +7546 7951 +7547..7548 79eb +7549 79e0 +7550 79ee +7551 79ed +7552 79ea +7553 79dc +7554 79de +7555 79dd +7556 7a86 +7557 7a89 +7558 7a85 +7559..7560 7a8b +7561 7a8a +7562 7a87 +7563 7ad8 +7564 7b10 +7565 7b04 +7566 7b13 +7567 7b05 +7568 7b0f +7569 7b08 +7570 7b0a +7571 7b0e +7572 7b09 +7573 7b12 +7574 7c84 +7575 7c91 +7576 7c8a +7577 7c8c +7578 7c88 +7579 7c8d +7580 7c85 +7581 7d1e +7582 7d1d +7583 7d11 +7584 7d0e +7585 7d18 +7586 7d16 +7587 7d13 +7588 7d1f +7589 7d12 +7590 7d0f +7591 7d0c +7592 7f5c +7593 7f61 +7594 7f5e +7595 7f60 +7596 7f5d +7597 7f5b +7598 7f96 +7599 7f92 +7600 7fc3 +7601 7fc2 +7602 7fc0 +7603 8016 +7604 803e +7605 8039 +7606 80fa +7607 80f2 +7608 80f9 +7609 80f5 +7610 8101 +7611 80fb +7612 8100 +7613 8201 +7614 822f +7615 8225 +7616 8333 +7617 832d +7618 8344 +7619 8319 +7620 8351 +7621 8325 +7622 8356 +7623 833f +7624 8341 +7625 8326 +7626 831c +7627 8322 +7628 8342 +7629 834e +7630 831b +7631 832a +7632 8308 +7633 833c +7634 834d +7635 8316 +7636 8324 +7637 8320 +7638 8337 +7639 832f +7640 8329 +7641 8347 +7642 8345 +7643 834c +7644 8353 +7645 831e +7646 832c +7647 834b +7648 8327 +7649 8348 +7650 8653 +7651 8652 +7652 86a2 +7653 86a8 +7654 8696 +7655 868d +7656 8691 +7657 869e +7658 8687 +7659 8697 +7660 8686 +7661 868b +7662 869a +7663 8685 +7664 86a5 +7665 8699 +7666 86a1 +7667 86a7 +7668 8695 +7669 8698 +7670 868e +7671 869d +7672 8690 +7673 8694 +7674..7675 8843 +7676 886d +7677..7678 8875 +7679 8872 +7680 8880 +7681 8871 +7682 887f +7683 886f +7684 8883 +7685 887e +7686 8874 +7687 887c +7688 8a12 +7689 8c47 +7690 8c57 +7691 8c7b +7692 8ca4 +7693 8ca3 +7694 8d76 +7695 8d78 +7696 8db5 +7697 8db7 +7698 8db6 +7699 8ed1 +7700 8ed3 +7701 8ffe +7702 8ff5 +7703 9002 +7704 8fff +7705 8ffb +7706 9004 +7707 8ffc +7708 8ff6 +7709 90d6 +7710 90e0 +7711..7712 90d9 +7713 90e3 +7714 90df +7715 90e5 +7716 90d8 +7717 90db +7718 90d7 +7719 90dc +7720 90e4 +7721 9150 +7722..7723 914e +7724 91d5 +7725 91e2 +7726 91da +7727 965c +7728 965f +7729 96bc +7730 98e3 +7731 9adf +7732 9b2f +7733 4e7f +7734 5070 +7735 506a +7736 5061 +7737 505e +7738 5060 +7739 5053 +7740 504b +7741 505d +7742 5072 +7743 5048 +7744 504d +7745 5041 +7746 505b +7747 504a +7748 5062 +7749 5015 +7750 5045 +7751 505f +7752 5069 +7753 506b +7754..7755 5063 +7756 5046 +7757 5040 +7758 506e +7759 5073 +7760 5057 +7761 5051 +7762 51d0 +7763 526b +7764 526d +7765 526c +7766 526e +7767 52d6 +7768 52d3 +7769 532d +7770 539c +7771..7772 5575 +7773 553c +7774 554d +7775 5550 +7776 5534 +7777 552a +7778 5551 +7779 5562 +7780 5536 +7781 5535 +7782 5530 +7783 5552 +7784 5545 +7785 550c +7786 5532 +7787 5565 +7788 554e +7789 5539 +7790 5548 +7791 552d +7792 553b +7793 5540 +7794 554b +7795 570a +7796 5707 +7797 57fb +7798 5814 +7799 57e2 +7800 57f6 +7801 57dc +7802 57f4 +7803 5800 +7804 57ed +7805 57fd +7806 5808 +7807 57f8 +7808 580b +7809 57f3 +7810 57cf +7811 5807 +7812 57ee +7813 57e3 +7814 57f2 +7815 57e5 +7816 57ec +7817 57e1 +7818 580e +7819 57fc +7820 5810 +7821 57e7 +7822 5801 +7823 580c +7824 57f1 +7825 57e9 +7826 57f0 +7827 580d +7828 5804 +7829 595c +7830 5a60 +7831 5a58 +7832 5a55 +7833 5a67 +7834 5a5e +7835 5a38 +7836 5a35 +7837 5a6d +7838 5a50 +7839 5a5f +7840 5a65 +7841 5a6c +7842 5a53 +7843 5a64 +7844 5a57 +7845 5a43 +7846 5a5d +7847 5a52 +7848 5a44 +7849 5a5b +7850 5a48 +7851 5a8e +7852 5a3e +7853 5a4d +7854 5a39 +7855 5a4c +7856 5a70 +7857 5a69 +7858 5a47 +7859 5a51 +7860 5a56 +7861 5a42 +7862 5a5c +7863 5b72 +7864 5b6e +7865 5bc1 +7866 5bc0 +7867 5c59 +7868 5d1e +7869 5d0b +7870 5d1d +7871 5d1a +7872 5d20 +7873 5d0c +7874 5d28 +7875 5d0d +7876 5d26 +7877 5d25 +7878 5d0f +7879 5d30 +7880 5d12 +7881 5d23 +7882 5d1f +7883 5d2e +7884 5e3e +7885 5e34 +7886 5eb1 +7887 5eb4 +7888 5eb9 +7889..7890 5eb2 +7891 5f36 +7892 5f38 +7893 5f9b +7894 5f96 +7895 5f9f +7896 608a +7897 6090 +7898 6086 +7899 60be +7900 60b0 +7901 60ba +7902..7903 60d3 +7904 60cf +7905 60e4 +7906 60d9 +7907 60dd +7908 60c8 +7909 60b1 +7910 60db +7911 60b7 +7912 60ca +7913 60bf +7914 60c3 +7915 60cd +7916 60c0 +7917 6332 +7918 6365 +7919 638a +7920 6382 +7921 637d +7922 63bd +7923 639e +7924 63ad +7925 639d +7926 6397 +7927 63ab +7928 638e +7929 636f +7930 6387 +7931 6390 +7932 636e +7933 63af +7934 6375 +7935 639c +7936 636d +7937 63ae +7938 637c +7939 63a4 +7940 633b +7941 639f +7942 6378 +7943 6385 +7944 6381 +7945 6391 +7946 638d +7947 6370 +7948 6553 +7949 65cd +7950 6665 +7951 6661 +7952 665b +7953 6659 +7954 665c +7955 6662 +7956 6718 +7957 6879 +7958 6887 +7959 6890 +7960 689c +7961..7962 686d +7963 68ae +7964 68ab +7965 6956 +7966 686f +7967 68a3 +7968 68ac +7969 68a9 +7970 6875 +7971 6874 +7972 68b2 +7973 688f +7974 6877 +7975 6892 +7976 687c +7977 686b +7978 6872 +7979 68aa +7980 6880 +7981 6871 +7982 687e +7983 689b +7984 6896 +7985 688b +7986 68a0 +7987 6889 +7988 68a4 +7989 6878 +7990 687b +7991 6891 +7992 688c +7993 688a +7994 687d +7995 6b36 +7996 6b33 +7997..7998 6b37 +7999 6b91 +8000 6b8f +8001..8002 6b8d +8003 6b8c +8004 6c2a +8005 6dc0 +8006 6dab +8007 6db4 +8008 6db3 +8009 6e74 +8010 6dac +8011 6de9 +8012 6de2 +8013 6db7 +8014 6df6 +8015 6dd4 +8016 6e00 +8017 6dc8 +8018 6de0 +8019 6ddf +8020 6dd6 +8021 6dbe +8022 6de5 +8023..8024 6ddc +8025 6ddb +8026 6df4 +8027 6dca +8028 6dbd +8029 6ded +8030 6df0 +8031 6dba +8032 6dd5 +8033 6dc2 +8034 6dcf +8035 6dc9 +8036 6dd0 +8037 6df2 +8038 6dd3 +8039 6dfd +8040 6dd7 +8041 6dcd +8042 6de3 +8043 6dbb +8044 70fa +8045 710d +8046 70f7 +8047 7117 +8048 70f4 +8049 710c +8050 70f0 +8051 7104 +8052 70f3 +8053 7110 +8054 70fc +8055 70ff +8056 7106 +8057 7113 +8058 7100 +8059 70f8 +8060 70f6 +8061 710b +8062 7102 +8063 710e +8064 727e +8065..8066 727b +8067 727f +8068 731d +8069 7317 +8070 7307 +8071 7311 +8072 7318 +8073 730a +8074 7308 +8075 72ff +8076 730f +8077 731e +8078 7388 +8079 73f6 +8080 73f8 +8081 73f5 +8082 7404 +8083 7401 +8084 73fd +8085 7407 +8086 7400 +8087 73fa +8088 73fc +8089 73ff +8090 740c +8091 740b +8092 73f4 +8093 7408 +8094 7564 +8095 7563 +8096 75ce +8097 75d2 +8098 75cf +8099..8100 75cb +8101 75d1 +8102 75d0 +8103 768f +8104 7689 +8105 76d3 +8106 7739 +8107 772f +8108 772d +8109..8110 7731 +8111 7734 +8112 7733 +8113 773d +8114 7725 +8115 773b +8116 7735 +8117 7848 +8118 7852 +8119 7849 +8120 784d +8121 784a +8122 784c +8123 7826 +8124 7845 +8125 7850 +8126 7964 +8127 7967 +8128..8129 7969 +8130 7963 +8131 796b +8132 7961 +8133 79bb +8134 79fa +8135 79f8 +8136..8137 79f6 +8138 7a8f +8139 7a94 +8140 7a90 +8141 7b35 +8142 7b3b +8143 7b34 +8144 7b25 +8145 7b30 +8146 7b22 +8147 7b24 +8148 7b33 +8149 7b18 +8150 7b2a +8151 7b1d +8152 7b31 +8153 7b2b +8154 7b2d +8155 7b2f +8156 7b32 +8157 7b38 +8158 7b1a +8159 7b23 +8160 7c94 +8161 7c98 +8162 7c96 +8163 7ca3 +8164 7d35 +8165 7d3d +8166 7d38 +8167 7d36 +8168 7d3a +8169 7d45 +8170 7d2c +8171 7d29 +8172 7d41 +8173 7d47 +8174..8175 7d3e +8176 7d4a +8177 7d3b +8178 7d28 +8179 7f63 +8180 7f95 +8181..8182 7f9c +8183 7f9b +8184..8185 7fca +8186 7fcd +8187..8188 7fd0 +8189 7fc7 +8190 7fcf +8191 7fc9 +8192 801f +8193 801e +8194 801b +8195 8047 +8196 8043 +8197 8048 +8198 8118 +8199 8125 +8200 8119 +8201 811b +8202 812d +8203 811f +8204 812c +8205 811e +8206 8121 +8207 8115 +8208 8127 +8209 811d +8210 8122 +8211 8211 +8212 8238 +8213 8233 +8214 823a +8215 8234 +8216 8232 +8217 8274 +8218 8390 +8219 83a3 +8220 83a8 +8221 838d +8222 837a +8223 8373 +8224 83a4 +8225 8374 +8226 838f +8227 8381 +8228 8395 +8229 8399 +8230 8375 +8231 8394 +8232 83a9 +8233 837d +8234 8383 +8235 838c +8236 839d +8237 839b +8238 83aa +8239 838b +8240 837e +8241 83a5 +8242 83af +8243 8388 +8244 8397 +8245 83b0 +8246 837f +8247 83a6 +8248 8387 +8249 83ae +8250 8376 +8251 8659 +8252 8656 +8253 86bf +8254 86b7 +8255 86c2 +8256 86c1 +8257 86c5 +8258 86ba +8259 86b0 +8260 86c8 +8261 86b9 +8262 86b3 +8263 86b8 +8264 86cc +8265 86b4 +8266..8267 86bb +8268 86c3 +8269..8270 86bd +8271 8852 +8272 8889 +8273 8895 +8274 88a8 +8275 88a2 +8276 88aa +8277 889a +8278 8891 +8279 88a1 +8280 889f +8281 8898 +8282 88a7 +8283 8899 +8284 889b +8285 8897 +8286 88a4 +8287 88ac +8288 888c +8289 8893 +8290 888e +8291 8982 +8292 89d6 +8293 89d9 +8294 89d5 +8295 8a30 +8296 8a27 +8297 8a2c +8298 8a1e +8299 8c39 +8300 8c3b +8301..8302 8c5c +8303 8c7d +8304 8ca5 +8305 8d7d +8306 8d7b +8307 8d79 +8308 8dbc +8309 8dc2 +8310 8db9 +8311 8dbf +8312 8dc1 +8313 8ed8 +8314 8ede +8315 8edd +8316 8edc +8317 8ed7 +8318..8319 8ee0 +8320 9024 +8321 900b +8322 9011 +8323 901c +8324 900c +8325 9021 +8326 90ef +8327 90ea +8328 90f0 +8329 90f4 +8330..8331 90f2 +8332 90d4 +8333..8334 90eb +8335 90e9 +8336 9156 +8337 9158 +8338 915a +8339 9153 +8340 9155 +8341 91ec +8342 91f4 +8343 91f1 +8344 91f3 +8345 91f8 +8346 91e4 +8347 91f9 +8348..8349 91ea +8350 91f7 +8351 91e8 +8352 91ee +8353 957a +8354 9586 +8355 9588 +8356 967c +8357 966d +8358 966b +8359 9671 +8360 966f +8361 96bf +8362 976a +8363 9804 +8364 98e5 +8365 9997 +8366 509b +8367 5095 +8368 5094 +8369 509e +8370 508b +8371 50a3 +8372 5083 +8373 508c +8374 508e +8375 509d +8376 5068 +8377 509c +8378 5092 +8379 5082 +8380 5087 +8381 515f +8382 51d4 +8383 5312 +8384 5311 +8385 53a4 +8386 53a7 +8387 5591 +8388 55a8 +8389 55a5 +8390 55ad +8391 5577 +8392 5645 +8393 55a2 +8394 5593 +8395 5588 +8396 558f +8397 55b5 +8398 5581 +8399 55a3 +8400 5592 +8401 55a4 +8402 557d +8403 558c +8404 55a6 +8405 557f +8406 5595 +8407 55a1 +8408 558e +8409 570c +8410 5829 +8411 5837 +8412 5819 +8413 581e +8414 5827 +8415 5823 +8416 5828 +8417 57f5 +8418 5848 +8419 5825 +8420 581c +8421 581b +8422 5833 +8423 583f +8424 5836 +8425 582e +8426 5839 +8427 5838 +8428 582d +8429 582c +8430 583b +8431 5961 +8432 5aaf +8433 5a94 +8434 5a9f +8435 5a7a +8436 5aa2 +8437 5a9e +8438 5a78 +8439 5aa6 +8440 5a7c +8441 5aa5 +8442 5aac +8443 5a95 +8444 5aae +8445 5a37 +8446 5a84 +8447 5a8a +8448 5a97 +8449 5a83 +8450 5a8b +8451 5aa9 +8452 5a7b +8453 5a7d +8454 5a8c +8455 5a9c +8456 5a8f +8457 5a93 +8458 5a9d +8459 5bea +8460 5bcd +8461 5bcb +8462 5bd4 +8463 5bd1 +8464 5bca +8465 5bce +8466 5c0c +8467 5c30 +8468 5d37 +8469 5d43 +8470 5d6b +8471 5d41 +8472 5d4b +8473 5d3f +8474 5d35 +8475 5d51 +8476 5d4e +8477 5d55 +8478 5d33 +8479 5d3a +8480 5d52 +8481 5d3d +8482 5d31 +8483 5d59 +8484 5d42 +8485 5d39 +8486 5d49 +8487 5d38 +8488 5d3c +8489 5d32 +8490 5d36 +8491 5d40 +8492 5d45 +8493 5e44 +8494 5e41 +8495 5f58 +8496 5fa6 +8497 5fa5 +8498 5fab +8499 60c9 +8500 60b9 +8501 60cc +8502 60e2 +8503 60ce +8504 60c4 +8505 6114 +8506 60f2 +8507 610a +8508 6116 +8509 6105 +8510 60f5 +8511 6113 +8512 60f8 +8513 60fc +8514 60fe +8515 60c1 +8516 6103 +8517 6118 +8518 611d +8519 6110 +8520 60ff +8521 6104 +8522 610b +8523 624a +8524 6394 +8525 63b1 +8526 63b0 +8527 63ce +8528 63e5 +8529 63e8 +8530 63ef +8531 63c3 +8532 649d +8533 63f3 +8534 63ca +8535 63e0 +8536 63f6 +8537 63d5 +8538 63f2 +8539 63f5 +8540 6461 +8541 63df +8542 63be +8543 63dd +8544 63dc +8545 63c4 +8546 63d8 +8547 63d3 +8548 63c2 +8549 63c7 +8550 63cc +8551 63cb +8552 63c8 +8553 63f0 +8554 63d7 +8555 63d9 +8556 6532 +8557 6567 +8558 656a +8559 6564 +8560 655c +8561 6568 +8562 6565 +8563 658c +8564..8565 659d +8566 65ae +8567 65d0 +8568 65d2 +8569 667c +8570 666c +8571 667b +8572 6680 +8573 6671 +8574 6679 +8575 666a +8576 6672 +8577 6701 +8578 690c +8579 68d3 +8580 6904 +8581 68dc +8582 692a +8583 68ec +8584 68ea +8585 68f1 +8586 690f +8587 68d6 +8588 68f7 +8589 68eb +8590 68e4 +8591 68f6 +8592 6913 +8593 6910 +8594 68f3 +8595 68e1 +8596 6907 +8597 68cc +8598 6908 +8599 6970 +8600 68b4 +8601 6911 +8602 68ef +8603 68c6 +8604 6914 +8605 68f8 +8606 68d0 +8607 68fd +8608 68fc +8609 68e8 +8610 690b +8611 690a +8612 6917 +8613 68ce +8614 68c8 +8615..8616 68dd +8617 68e6 +8618 68f4 +8619 68d1 +8620 6906 +8621 68d4 +8622 68e9 +8623 6915 +8624 6925 +8625 68c7 +8626 6b39 +8627 6b3b +8628 6b3f +8629 6b3c +8630 6b94 +8631 6b97 +8632 6b99 +8633 6b95 +8634 6bbd +8635 6bf0 +8636..8637 6bf2 +8638 6c30 +8639 6dfc +8640..8641 6e46 +8642 6e1f +8643 6e49 +8644 6e88 +8645..8646 6e3c +8647 6e45 +8648 6e62 +8649 6e2b +8650 6e3f +8651 6e41 +8652 6e5d +8653 6e73 +8654 6e1c +8655 6e33 +8656 6e4b +8657 6e40 +8658 6e51 +8659 6e3b +8660 6e03 +8661 6e2e +8662 6e5e +8663 6e68 +8664 6e5c +8665 6e61 +8666 6e31 +8667 6e28 +8668 6e60 +8669 6e71 +8670 6e6b +8671 6e39 +8672 6e22 +8673 6e30 +8674 6e53 +8675 6e65 +8676 6e27 +8677 6e78 +8678 6e64 +8679 6e77 +8680 6e55 +8681 6e79 +8682 6e52 +8683 6e66 +8684..8685 6e35 +8686 6e5a +8687 7120 +8688 711e +8689 712f +8690 70fb +8691 712e +8692 7131 +8693 7123 +8694 7125 +8695 7122 +8696 7132 +8697 711f +8698 7128 +8699 713a +8700 711b +8701 724b +8702 725a +8703..8704 7288 +8705 7286 +8706 7285 +8707 728b +8708 7312 +8709 730b +8710 7330 +8711 7322 +8712 7331 +8713 7333 +8714 7327 +8715 7332 +8716 732d +8717 7326 +8718 7323 +8719 7335 +8720 730c +8721 742e +8722 742c +8723 7430 +8724 742b +8725 7416 +8726 741a +8727 7421 +8728 742d +8729 7431 +8730 7424 +8731 7423 +8732 741d +8733 7429 +8734 7420 +8735 7432 +8736 74fb +8737 752f +8738 756f +8739 756c +8740 75e7 +8741 75da +8742 75e1 +8743 75e6 +8744 75dd +8745 75df +8746 75e4 +8747 75d7 +8748 7695 +8749 7692 +8750 76da +8751..8752 7746 +8753 7744 +8754 774d +8755 7745 +8756 774a +8757 774e +8758..8759 774b +8760 77de +8761 77ec +8762 7860 +8763..8764 7864 +8765 785c +8766 786d +8767 7871 +8768 786a +8769 786e +8770 7870 +8771 7869 +8772 7868 +8773 785e +8774 7862 +8775 7974 +8776 7973 +8777 7972 +8778 7970 +8779 7a02 +8780 7a0a +8781 7a03 +8782 7a0c +8783 7a04 +8784 7a99 +8785 7ae6 +8786 7ae4 +8787 7b4a +8788 7b47 +8789 7b44 +8790 7b48 +8791 7b4c +8792 7b4e +8793 7b40 +8794 7b58 +8795 7b45 +8796 7ca2 +8797 7c9e +8798 7ca8 +8799 7ca1 +8800 7d58 +8801 7d6f +8802 7d63 +8803 7d53 +8804 7d56 +8805 7d67 +8806 7d6a +8807 7d4f +8808 7d6d +8809 7d5c +8810 7d6b +8811 7d52 +8812 7d54 +8813 7d69 +8814 7d51 +8815 7d5f +8816 7d4e +8817..8818 7f3e +8819..8820 7f65 +8821 7fa2 +8822..8823 7fa0 +8824 7fd7 +8825 8051 +8826..8827 804f +8828 80fe +8829 80d4 +8830 8143 +8831 814a +8832 8152 +8833 814f +8834 8147 +8835 813d +8836 814d +8837 813a +8838 81e6 +8839 81ee +8840..8842 81f7 +8843 8204 +8844..8845 823c +8846 823f +8847 8275 +8848 833b +8849 83cf +8850 83f9 +8851 8423 +8852 83c0 +8853 83e8 +8854 8412 +8855 83e7 +8856 83e4 +8857 83fc +8858 83f6 +8859 8410 +8860 83c6 +8861 83c8 +8862 83eb +8863 83e3 +8864 83bf +8865 8401 +8866 83dd +8867 83e5 +8868 83d8 +8869 83ff +8870 83e1 +8871 83cb +8872 83ce +8873 83d6 +8874 83f5 +8875 83c9 +8876 8409 +8877 840f +8878 83de +8879 8411 +8880 8406 +8881 83c2 +8882 83f3 +8883 83d5 +8884 83fa +8885 83c7 +8886 83d1 +8887 83ea +8888 8413 +8889 839a +8890 83c3 +8891 83ec +8892 83ee +8893 83c4 +8894 83fb +8895 83d7 +8896 83e2 +8897 841b +8898 83db +8899 83fe +8900 86d8 +8901 86e2 +8902 86e6 +8903 86d3 +8904 86e3 +8905 86da +8906 86ea +8907 86dd +8908 86eb +8909 86dc +8910 86ec +8911 86e9 +8912 86d7 +8913 86e8 +8914 86d1 +8915 8848 +8916 8856 +8917 8855 +8918 88ba +8919 88d7 +8920 88b9 +8921 88b8 +8922 88c0 +8923 88be +8924 88b6 +8925 88bc +8926 88b7 +8927 88bd +8928 88b2 +8929 8901 +8930 88c9 +8931 8995 +8932 8998 +8933 8997 +8934 89dd +8935..8936 89da +8937 8a4e +8938 8a4d +8939 8a39 +8940 8a59 +8941 8a40 +8942..8943 8a57 +8944..8945 8a44 +8946 8a52 +8947 8a48 +8948 8a51 +8949 8a4a +8950 8a4c +8951 8a4f +8952 8c5f +8953 8c81 +8954 8c80 +8955 8cba +8956 8cbe +8957 8cb0 +8958 8cb9 +8959 8cb5 +8960 8d84 +8961 8d80 +8962 8d89 +8963 8dd8 +8964 8dd3 +8965 8dcd +8966 8dc7 +8967 8dd6 +8968 8ddc +8969 8dcf +8970 8dd5 +8971 8dd9 +8972 8dc8 +8973 8dd7 +8974 8dc5 +8975 8eef +8976 8ef7 +8977 8efa +8978 8ef9 +8979 8ee6 +8980 8eee +8981 8ee5 +8982 8ef5 +8983..8984 8ee7 +8985 8ef6 +8986 8eeb +8987 8ef1 +8988 8eec +8989 8ef4 +8990 8ee9 +8991 902d +8992 9034 +8993 902f +8994 9106 +8995 912c +8996 9104 +8997 90ff +8998 90fc +8999 9108 +9000 90f9 +9001 90fb +9002 9101 +9003 9100 +9004 9107 +9005 9105 +9006 9103 +9007 9161 +9008 9164 +9009 915f +9010 9162 +9011 9160 +9012 9201 +9013 920a +9014 9225 +9015 9203 +9016 921a +9017 9226 +9018 920f +9019 920c +9020 9200 +9021 9212 +9022 91ff +9023 91fd +9024 9206 +9025 9204 +9026 9227 +9027 9202 +9028 921c +9029 9224 +9030 9219 +9031 9217 +9032 9205 +9033 9216 +9034 957b +9035 958d +9036 958c +9037 9590 +9038 9687 +9039 967e +9040..9041 9688 +9042 9683 +9043 9680 +9044 96c2 +9045 96c8 +9046 96c3 +9047 96f1 +9048 96f0 +9049 976c +9050 9770 +9051 976e +9052 9807 +9053 98a9 +9054 98eb +9055 9ce6 +9056 9ef9 +9057..9058 4e83 +9059 4eb6 +9060 50bd +9061 50bf +9062 50c6 +9063 50ae +9064 50c4 +9065 50ca +9066 50b4 +9067 50c8 +9068 50c2 +9069 50b0 +9070 50c1 +9071 50ba +9072 50b1 +9073 50cb +9074 50c9 +9075 50b6 +9076 50b8 +9077 51d7 +9078 527a +9079 5278 +9080..9081 527b +9082 55c3 +9083 55db +9084 55cc +9085 55d0 +9086 55cb +9087 55ca +9088 55dd +9089 55c0 +9090 55d4 +9091 55c4 +9092 55e9 +9093 55bf +9094 55d2 +9095 558d +9096 55cf +9097 55d5 +9098 55e2 +9099 55d6 +9100 55c8 +9101 55f2 +9102 55cd +9103 55d9 +9104 55c2 +9105 5714 +9106 5853 +9107 5868 +9108 5864 +9109 584f +9110 584d +9111 5849 +9112 586f +9113 5855 +9114 584e +9115 585d +9116 5859 +9117 5865 +9118 585b +9119 583d +9120 5863 +9121 5871 +9122 58fc +9123 5ac7 +9124 5ac4 +9125 5acb +9126 5aba +9127 5ab8 +9128 5ab1 +9129 5ab5 +9130 5ab0 +9131 5abf +9132 5ac8 +9133 5abb +9134 5ac6 +9135 5ab7 +9136 5ac0 +9137 5aca +9138 5ab4 +9139 5ab6 +9140 5acd +9141 5ab9 +9142 5a90 +9143 5bd6 +9144..9145 5bd8 +9146 5c1f +9147 5c33 +9148 5d71 +9149 5d63 +9150 5d4a +9151 5d65 +9152 5d72 +9153 5d6c +9154 5d5e +9155 5d68 +9156 5d67 +9157 5d62 +9158 5df0 +9159 5e4f +9160 5e4e +9161 5e4a +9162 5e4d +9163 5e4b +9164 5ec5 +9165 5ecc +9166 5ec6 +9167 5ecb +9168 5ec7 +9169 5f40 +9170 5faf +9171 5fad +9172 60f7 +9173..9174 6149 +9175 612b +9176 6145 +9177 6136 +9178 6132 +9179 612e +9180 6146 +9181 612f +9182 614f +9183 6129 +9184 6140 +9185 6220 +9186 9168 +9187 6223 +9188 6225 +9189 6224 +9190 63c5 +9191 63f1 +9192 63eb +9193 6410 +9194 6412 +9195 6409 +9196 6420 +9197 6424 +9198 6433 +9199 6443 +9200 641f +9201 6415 +9202 6418 +9203 6439 +9204 6437 +9205..9206 6422 +9207 640c +9208 6426 +9209 6430 +9210 6428 +9211 6441 +9212 6435 +9213 642f +9214 640a +9215 641a +9216 6440 +9217 6425 +9218 6427 +9219 640b +9220 63e7 +9221 641b +9222 642e +9223 6421 +9224 640e +9225 656f +9226 6592 +9227 65d3 +9228 6686 +9229 668c +9230 6695 +9231 6690 +9232 668b +9233 668a +9234 6699 +9235 6694 +9236 6678 +9237 6720 +9238 6966 +9239 695f +9240 6938 +9241 694e +9242 6962 +9243 6971 +9244 693f +9245 6945 +9246 696a +9247 6939 +9248 6942 +9249 6957 +9250 6959 +9251 697a +9252..9253 6948 +9254 6935 +9255 696c +9256 6933 +9257 693d +9258 6965 +9259 68f0 +9260 6978 +9261 6934 +9262 6969 +9263 6940 +9264 696f +9265 6944 +9266 6976 +9267 6958 +9268 6941 +9269 6974 +9270 694c +9271 693b +9272 694b +9273 6937 +9274 695c +9275 694f +9276 6951 +9277 6932 +9278 6952 +9279 692f +9280 697b +9281 693c +9282 6b46 +9283 6b45 +9284 6b43 +9285 6b42 +9286 6b48 +9287 6b41 +9288 6b9b +9289..9290 6bfb +9291 6bf9 +9292..9293 6bf7 +9294 6e9b +9295 6ed6 +9296 6ec8 +9297 6e8f +9298 6ec0 +9299 6e9f +9300..9301 6e93 +9302 6ea0 +9303 6eb1 +9304 6eb9 +9305 6ec6 +9306 6ed2 +9307 6ebd +9308 6ec1 +9309 6e9e +9310 6ec9 +9311 6eb7 +9312 6eb0 +9313 6ecd +9314 6ea6 +9315 6ecf +9316 6eb2 +9317 6ebe +9318 6ec3 +9319 6edc +9320 6ed8 +9321 6e99 +9322 6e92 +9323 6e8e +9324 6e8d +9325 6ea4 +9326 6ea1 +9327 6ebf +9328 6eb3 +9329 6ed0 +9330 6eca +9331 6e97 +9332 6eae +9333 6ea3 +9334 7147 +9335 7154 +9336 7152 +9337 7163 +9338 7160 +9339 7141 +9340 715d +9341 7162 +9342 7172 +9343 7178 +9344 716a +9345 7161 +9346 7142 +9347 7158 +9348 7143 +9349 714b +9350 7170 +9351 715f +9352 7150 +9353 7153 +9354 7144 +9355 714d +9356 715a +9357 724f +9358 728d +9359 728c +9360 7291 +9361 7290 +9362 728e +9363 733c +9364 7342 +9365 733b +9366 733a +9367 7340 +9368 734a +9369 7349 +9370 7444 +9371..9372 744a +9373 7452 +9374 7451 +9375 7457 +9376 7440 +9377..9378 744f +9379 744e +9380 7442 +9381 7446 +9382 744d +9383 7454 +9384 74e1 +9385 74ff +9386 74fe +9387 74fd +9388 751d +9389 7579 +9390 7577 +9391 6983 +9392 75ef +9393 760f +9394 7603 +9395 75f7 +9396 75fe +9397 75fc +9398 75f9 +9399 75f8 +9400 7610 +9401 75fb +9402 75f6 +9403 75ed +9404 75f5 +9405 75fd +9406 7699 +9407 76b5 +9408 76dd +9409 7755 +9410..9411 775f +9412 7752 +9413 7756 +9414 775a +9415 7769 +9416 7767 +9417 7754 +9418 7759 +9419 776d +9420 77e0 +9421 7887 +9422 789a +9423 7894 +9424 788f +9425 7884 +9426 7895 +9427..9428 7885 +9429 78a1 +9430 7883 +9431 7879 +9432 7899 +9433 7880 +9434 7896 +9435 787b +9436 797c +9437 7982 +9438 797d +9439 7979 +9440 7a11 +9441..9442 7a18 +9443 7a12 +9444 7a17 +9445 7a15 +9446 7a22 +9447 7a13 +9448 7a1b +9449 7a10 +9450 7aa3 +9451 7aa2 +9452 7a9e +9453 7aeb +9454 7b66 +9455 7b64 +9456 7b6d +9457 7b74 +9458 7b69 +9459 7b72 +9460 7b65 +9461 7b73 +9462 7b71 +9463 7b70 +9464 7b61 +9465 7b78 +9466 7b76 +9467 7b63 +9468 7cb2 +9469 7cb4 +9470 7caf +9471 7d88 +9472 7d86 +9473 7d80 +9474 7d8d +9475 7d7f +9476 7d85 +9477 7d7a +9478 7d8e +9479 7d7b +9480 7d83 +9481 7d7c +9482 7d8c +9483 7d94 +9484 7d84 +9485 7d7d +9486 7d92 +9487 7f6d +9488 7f6b +9489..9490 7f67 +9491 7f6c +9492 7fa6 +9493 7fa5 +9494 7fa7 +9495..9496 7fdb +9497 8021 +9498 8164 +9499 8160 +9500 8177 +9501 815c +9502 8169 +9503 815b +9504 8162 +9505 8172 +9506 6721 +9507 815e +9508 8176 +9509 8167 +9510 816f +9511 8144 +9512 8161 +9513 821d +9514 8249 +9515 8244 +9516 8240 +9517 8242 +9518 8245 +9519 84f1 +9520 843f +9521 8456 +9522 8476 +9523 8479 +9524 848f +9525 848d +9526 8465 +9527 8451 +9528 8440 +9529 8486 +9530 8467 +9531 8430 +9532 844d +9533 847d +9534 845a +9535 8459 +9536 8474 +9537 8473 +9538 845d +9539 8507 +9540 845e +9541 8437 +9542 843a +9543 8434 +9544 847a +9545 8443 +9546 8478 +9547 8432 +9548 8445 +9549 8429 +9550 83d9 +9551 844b +9552 842f +9553 8442 +9554 842d +9555 845f +9556 8470 +9557 8439 +9558 844e +9559 844c +9560 8452 +9561 846f +9562 84c5 +9563 848e +9564 843b +9565 8447 +9566 8436 +9567 8433 +9568 8468 +9569 847e +9570 8444 +9571 842b +9572 8460 +9573 8454 +9574 846e +9575 8450 +9576 870b +9577 8704 +9578 86f7 +9579 870c +9580 86fa +9581 86d6 +9582 86f5 +9583 874d +9584 86f8 +9585 870e +9586 8709 +9587 8701 +9588 86f6 +9589 870d +9590 8705 +9591 88d6 +9592 88cb +9593..9594 88cd +9595 88de +9596 88db +9597 88da +9598 88cc +9599 88d0 +9600 8985 +9601 899b +9602 89df +9603 89e5 +9604 89e4 +9605 89e1 +9606 89e0 +9607 89e2 +9608 89dc +9609 89e6 +9610 8a76 +9611 8a86 +9612 8a7f +9613 8a61 +9614 8a3f +9615 8a77 +9616 8a82 +9617 8a84 +9618 8a75 +9619 8a83 +9620 8a81 +9621 8a74 +9622 8a7a +9623 8c3c +9624 8c4b +9625 8c4a +9626 8c65 +9627 8c64 +9628 8c66 +9629 8c86 +9630..9631 8c84 +9632 8ccc +9633..9634 8d68 +9635 8d91 +9636 8d8c +9637..9638 8d8e +9639 8d8d +9640..9641 8d93 +9642 8d90 +9643 8d92 +9644 8df0 +9645 8de0 +9646 8dec +9647 8df1 +9648 8dee +9649 8dd0 +9650 8de9 +9651 8de3 +9652 8de2 +9653 8de7 +9654 8df2 +9655 8deb +9656 8df4 +9657 8f06 +9658 8eff +9659 8f01 +9660 8f00 +9661 8f05 +9662..9663 8f07 +9664 8f02 +9665 8f0b +9666 9052 +9667 903f +9668 9044 +9669 9049 +9670 903d +9671 9110 +9672 910d +9673 910f +9674 9111 +9675 9116 +9676 9114 +9677 910b +9678 910e +9679..9680 916e +9681 9248 +9682 9252 +9683 9230 +9684 923a +9685 9266 +9686 9233 +9687 9265 +9688 925e +9689 9283 +9690 922e +9691 924a +9692 9246 +9693 926d +9694 926c +9695 924f +9696 9260 +9697 9267 +9698 926f +9699 9236 +9700 9261 +9701 9270 +9702 9231 +9703 9254 +9704 9263 +9705 9250 +9706 9272 +9707 924e +9708 9253 +9709 924c +9710 9256 +9711 9232 +9712 959f +9713 959c +9714 959e +9715 959b +9716..9717 9692 +9718 9691 +9719 9697 +9720 96ce +9721 96fa +9722 96fd +9723 96f8 +9724 96f5 +9725 9773 +9726..9727 9777 +9728 9772 +9729 980f +9730..9731 980d +9732 98ac +9733 98f6 +9734 98f9 +9735 99af +9736 99b2 +9737 99b0 +9738 99b5 +9739 9aad +9740 9aab +9741 9b5b +9742 9cea +9743 9ced +9744 9ce7 +9745 9e80 +9746 9efd +9747 50e6 +9748 50d4 +9749 50d7 +9750 50e8 +9751 50f3 +9752 50db +9753 50ea +9754 50dd +9755 50e4 +9756 50d3 +9757 50ec +9758 50f0 +9759 50ef +9760 50e3 +9761 50e0 +9762 51d8 +9763..9764 5280 +9765 52e9 +9766 52eb +9767 5330 +9768 53ac +9769 5627 +9770 5615 +9771 560c +9772 5612 +9773 55fc +9774 560f +9775 561c +9776 5601 +9777 5613 +9778 5602 +9779 55fa +9780 561d +9781 5604 +9782 55ff +9783 55f9 +9784 5889 +9785 587c +9786 5890 +9787 5898 +9788 5886 +9789 5881 +9790 587f +9791 5874 +9792 588b +9793 587a +9794 5887 +9795 5891 +9796 588e +9797 5876 +9798 5882 +9799 5888 +9800 587b +9801 5894 +9802 588f +9803 58fe +9804 596b +9805 5adc +9806 5aee +9807 5ae5 +9808 5ad5 +9809 5aea +9810 5ada +9811 5aed +9812 5aeb +9813 5af3 +9814 5ae2 +9815 5ae0 +9816 5adb +9817 5aec +9818 5ade +9819 5add +9820 5ad9 +9821 5ae8 +9822 5adf +9823 5b77 +9824 5be0 +9825 5be3 +9826 5c63 +9827 5d82 +9828 5d80 +9829 5d7d +9830 5d86 +9831 5d7a +9832 5d81 +9833 5d77 +9834 5d8a +9835 5d89 +9836 5d88 +9837 5d7e +9838 5d7c +9839 5d8d +9840 5d79 +9841 5d7f +9842..9843 5e58 +9844 5e53 +9845 5ed8 +9846 5ed1 +9847 5ed7 +9848 5ece +9849 5edc +9850 5ed5 +9851 5ed9 +9852 5ed2 +9853 5ed4 +9854 5f44 +9855 5f43 +9856 5f6f +9857 5fb6 +9858 612c +9859 6128 +9860 6141 +9861 615e +9862 6171 +9863 6173 +9864..9865 6152 +9866 6172 +9867 616c +9868 6180 +9869 6174 +9870 6154 +9871 617a +9872 615b +9873 6165 +9874 613b +9875 616a +9876 6161 +9877 6156 +9878 6229 +9879 6227 +9880 622b +9881 642b +9882 644d +9883 645b +9884 645d +9885 6474 +9886 6476 +9887..9888 6472 +9889 647d +9890 6475 +9891 6466 +9892 64a6 +9893 644e +9894 6482 +9895 645e +9896 645c +9897 644b +9898 6453 +9899 6460 +9900 6450 +9901 647f +9902 643f +9903 646c +9904 646b +9905 6459 +9906 6465 +9907 6477 +9908 6573 +9909 65a0 +9910 66a1 +9911 66a0 +9912 669f +9913 6705 +9914 6704 +9915 6722 +9916 69b1 +9917 69b6 +9918 69c9 +9919 69a0 +9920 69ce +9921 6996 +9922 69b0 +9923 69ac +9924 69bc +9925 6991 +9926 6999 +9927 698e +9928 69a7 +9929 698d +9930 69a9 +9931 69be +9932 69af +9933 69bf +9934 69c4 +9935 69bd +9936 69a4 +9937 69d4 +9938 69b9 +9939 69ca +9940 699a +9941 69cf +9942 69b3 +9943 6993 +9944 69aa +9945 69a1 +9946 699e +9947 69d9 +9948 6997 +9949 6990 +9950 69c2 +9951 69b5 +9952 69a5 +9953 69c6 +9954 6b4a +9955 6b4d +9956 6b4b +9957..9959 6b9e +9960..9961 6bc3 +9962 6bfe +9963 6ece +9964 6ef5 +9965 6ef1 +9966 6f03 +9967 6f25 +9968 6ef8 +9969 6f37 +9970 6efb +9971 6f2e +9972 6f09 +9973 6f4e +9974..9975 6f19 +9976 6f27 +9977 6f18 +9978 6f3b +9979 6f12 +9980 6eed +9981 6f0a +9982 6f36 +9983 6f73 +9984 6ef9 +9985 6eee +9986 6f2d +9987 6f40 +9988 6f30 +9989 6f3c +9990 6f35 +9991 6eeb +9992 6f07 +9993 6f0e +9994 6f43 +9995 6f05 +9996 6efd +9997 6ef6 +9998 6f39 +9999 6f1c +10000 6efc +10001 6f3a +10002 6f1f +10003 6f0d +10004 6f1e +10005 6f08 +10006 6f21 +10007 7187 +10008 7190 +10009 7189 +10010 7180 +10011 7185 +10012 7182 +10013 718f +10014 717b +10015 7186 +10016 7181 +10017 7197 +10018 7244 +10019 7253 +10020 7297 +10021 7295 +10022 7293 +10023 7343 +10024 734d +10025 7351 +10026 734c +10027 7462 +10028 7473 +10029 7471 +10030 7475 +10031 7472 +10032 7467 +10033 746e +10034 7500 +10035..10036 7502 +10037 757d +10038 7590 +10039 7616 +10040 7608 +10041 760c +10042 7615 +10043 7611 +10044 760a +10045 7614 +10046 76b8 +10047 7781 +10048 777c +10049 7785 +10050 7782 +10051 776e +10052 7780 +10053 776f +10054 777e +10055 7783 +10056 78b2 +10057 78aa +10058 78b4 +10059 78ad +10060 78a8 +10061 787e +10062 78ab +10063 789e +10064 78a5 +10065 78a0 +10066 78ac +10067 78a2 +10068 78a4 +10069 7998 +10070..10071 798a +10072 7996 +10073 7995 +10074 7994 +10075 7993 +10076 7997 +10077 7988 +10078 7992 +10079 7990 +10080 7a2b +10081 7a4a +10082 7a30 +10083 7a2f +10084 7a28 +10085 7a26 +10086 7aa8 +10087..10088 7aab +10089 7aee +10090 7b88 +10091 7b9c +10092 7b8a +10093 7b91 +10094 7b90 +10095 7b96 +10096 7b8d +10097 7b8c +10098 7b9b +10099 7b8e +10100 7b85 +10101 7b98 +10102 5284 +10103 7b99 +10104 7ba4 +10105 7b82 +10106 7cbb +10107 7cbf +10108 7cbc +10109 7cba +10110 7da7 +10111 7db7 +10112 7dc2 +10113 7da3 +10114 7daa +10115 7dc1 +10116 7dc0 +10117 7dc5 +10118 7d9d +10119 7dce +10120 7dc4 +10121 7dc6 +10122..10123 7dcb +10124 7daf +10125 7db9 +10126 7d96 +10127 7dbc +10128 7d9f +10129 7da6 +10130 7dae +10131 7da9 +10132 7da1 +10133 7dc9 +10134 7f73 +10135..10136 7fe2 +10137 7fe5 +10138 7fde +10139 8024 +10140 805d +10141 805c +10142 8189 +10143 8186 +10144 8183 +10145 8187 +10146 818d +10147 818c +10148 818b +10149 8215 +10150 8497 +10151 84a4 +10152 84a1 +10153 849f +10154 84ba +10155 84ce +10156 84c2 +10157 84ac +10158 84ae +10159 84ab +10160 84b9 +10161 84b4 +10162 84c1 +10163 84cd +10164 84aa +10165 849a +10166 84b1 +10167 84d0 +10168 849d +10169 84a7 +10170 84bb +10171 84a2 +10172 8494 +10173 84c7 +10174 84cc +10175 849b +10176 84a9 +10177 84af +10178 84a8 +10179 84d6 +10180 8498 +10181 84b6 +10182 84cf +10183 84a0 +10184 84d7 +10185 84d4 +10186 84d2 +10187 84db +10188 84b0 +10189 8491 +10190 8661 +10191 8733 +10192 8723 +10193 8728 +10194 876b +10195 8740 +10196 872e +10197 871e +10198 8721 +10199 8719 +10200 871b +10201 8743 +10202 872c +10203 8741 +10204 873e +10205 8746 +10206 8720 +10207 8732 +10208 872a +10209 872d +10210 873c +10211 8712 +10212 873a +10213 8731 +10214 8735 +10215 8742 +10216..10217 8726 +10218 8738 +10219 8724 +10220 871a +10221 8730 +10222 8711 +10223 88f7 +10224 88e7 +10225..10226 88f1 +10227 88fa +10228 88fe +10229 88ee +10230 88fc +10231 88f6 +10232 88fb +10233 88f0 +10234 88ec +10235 88eb +10236 899d +10237 89a1 +10238 899f +10239 899e +10240 89e9 +10241 89eb +10242 89e8 +10243 8aab +10244 8a99 +10245 8a8b +10246 8a92 +10247 8a8f +10248 8a96 +10249 8c3d +10250..10251 8c68 +10252 8cd5 +10253 8ccf +10254 8cd7 +10255 8d96 +10256 8e09 +10257 8e02 +10258 8dff +10259 8e0d +10260 8dfd +10261 8e0a +10262 8e03 +10263 8e07 +10264 8e06 +10265 8e05 +10266 8dfe +10267 8e00 +10268 8e04 +10269..10270 8f10 +10271 8f0e +10272 8f0d +10273 9123 +10274 911c +10275 9120 +10276 9122 +10277 911f +10278 911d +10279 911a +10280 9124 +10281 9121 +10282 911b +10283 917a +10284 9172 +10285 9179 +10286 9173 +10287 92a5 +10288 92a4 +10289 9276 +10290 929b +10291 927a +10292 92a0 +10293 9294 +10294 92aa +10295 928d +10296 92a6 +10297 929a +10298 92ab +10299 9279 +10300 9297 +10301 927f +10302 92a3 +10303 92ee +10304 928e +10305 9282 +10306 9295 +10307 92a2 +10308 927d +10309 9288 +10310 92a1 +10311 928a +10312 9286 +10313 928c +10314 9299 +10315 92a7 +10316 927e +10317 9287 +10318 92a9 +10319 929d +10320 928b +10321 922d +10322 969e +10323 96a1 +10324 96ff +10325 9758 +10326 977d +10327 977a +10328 977e +10329 9783 +10330 9780 +10331 9782 +10332 977b +10333 9784 +10334 9781 +10335 977f +10336 97ce +10337 97cd +10338 9816 +10339..10340 98ad +10341 9902 +10342 9900 +10343 9907 +10344 999d +10345 999c +10346 99c3 +10347 99b9 +10348 99bb +10349 99ba +10350 99c2 +10351 99bd +10352 99c7 +10353 9ab1 +10354 9ae3 +10355 9ae7 +10356..10357 9b3e +10358..10359 9b60 +10360 9b5f +10361..10362 9cf1 +10363 9cf5 +10364 9ea7 +10365 50ff +10366 5103 +10367 5130 +10368 50f8 +10369..10370 5106 +10371 50f6 +10372 50fe +10373..10374 510b +10375 50fd +10376 510a +10377..10378 528b +10379 52f1 +10380 52ef +10381 5648 +10382 5642 +10383 564c +10384 5635 +10385 5641 +10386 564a +10387 5649 +10388 5646 +10389 5658 +10390 565a +10391 5640 +10392 5633 +10393 563d +10394 562c +10395 563e +10396 5638 +10397 562a +10398 563a +10399 571a +10400 58ab +10401 589d +10402 58b1 +10403 58a0 +10404 58a3 +10405 58af +10406 58ac +10407 58a5 +10408 58a1 +10409 58ff +10410 5aff +10411 5af4 +10412 5afd +10413 5af7 +10414 5af6 +10415 5b03 +10416 5af8 +10417 5b02 +10418 5af9 +10419 5b01 +10420 5b07 +10421 5b05 +10422 5b0f +10423 5c67 +10424 5d99 +10425 5d97 +10426 5d9f +10427 5d92 +10428 5da2 +10429 5d93 +10430 5d95 +10431 5da0 +10432 5d9c +10433 5da1 +10434 5d9a +10435 5d9e +10436 5e69 +10437 5e5d +10438 5e60 +10439 5e5c +10440 7df3 +10441 5edb +10442 5ede +10443 5ee1 +10444 5f49 +10445 5fb2 +10446 618b +10447 6183 +10448 6179 +10449 61b1 +10450 61b0 +10451 61a2 +10452 6189 +10453 619b +10454 6193 +10455 61af +10456 61ad +10457 619f +10458 6192 +10459 61aa +10460 61a1 +10461 618d +10462 6166 +10463 61b3 +10464 622d +10465 646e +10466 6470 +10467 6496 +10468 64a0 +10469 6485 +10470 6497 +10471 649c +10472 648f +10473 648b +10474 648a +10475 648c +10476 64a3 +10477 649f +10478 6468 +10479 64b1 +10480 6498 +10481 6576 +10482 657a +10483 6579 +10484 657b +10485..10486 65b2 +10487 66b5 +10488 66b0 +10489 66a9 +10490 66b2 +10491 66b7 +10492 66aa +10493 66af +10494 6a00 +10495 6a06 +10496 6a17 +10497 69e5 +10498 69f8 +10499 6a15 +10500 69f1 +10501 69e4 +10502 6a20 +10503 69ff +10504 69ec +10505 69e2 +10506 6a1b +10507 6a1d +10508 69fe +10509 6a27 +10510 69f2 +10511 69ee +10512 6a14 +10513 69f7 +10514 69e7 +10515 6a40 +10516 6a08 +10517 69e6 +10518 69fb +10519 6a0d +10520 69fc +10521 69eb +10522 6a09 +10523 6a04 +10524 6a18 +10525 6a25 +10526 6a0f +10527 69f6 +10528 6a26 +10529 6a07 +10530 69f4 +10531 6a16 +10532 6b51 +10533 6ba5 +10534 6ba3 +10535 6ba2 +10536 6ba6 +10537 6c01 +10538 6c00 +10539 6bff +10540 6c02 +10541 6f41 +10542 6f26 +10543 6f7e +10544 6f87 +10545 6fc6 +10546 6f92 +10547 6f8d +10548 6f89 +10549 6f8c +10550 6f62 +10551 6f4f +10552 6f85 +10553 6f5a +10554 6f96 +10555 6f76 +10556 6f6c +10557 6f82 +10558 6f55 +10559 6f72 +10560 6f52 +10561 6f50 +10562 6f57 +10563 6f94 +10564 6f93 +10565 6f5d +10566 6f00 +10567 6f61 +10568 6f6b +10569 6f7d +10570 6f67 +10571 6f90 +10572 6f53 +10573 6f8b +10574 6f69 +10575 6f7f +10576 6f95 +10577 6f63 +10578 6f77 +10579 6f6a +10580 6f7b +10581 71b2 +10582 71af +10583 719b +10584 71b0 +10585 71a0 +10586 719a +10587 71a9 +10588 71b5 +10589 719d +10590 71a5 +10591 719e +10592 71a4 +10593 71a1 +10594 71aa +10595 719c +10596 71a7 +10597 71b3 +10598 7298 +10599 729a +10600 7358 +10601 7352 +10602..10604 735e +10605 735d +10606 735b +10607 7361 +10608 735a +10609 7359 +10610 7362 +10611 7487 +10612..10613 7489 +10614 7486 +10615 7481 +10616 747d +10617 7485 +10618 7488 +10619 747c +10620 7479 +10621 7508 +10622 7507 +10623 757e +10624 7625 +10625 761e +10626 7619 +10627 761d +10628 761c +10629 7623 +10630 761a +10631 7628 +10632 761b +10633..10635 769c +10636 769b +10637 778d +10638 778f +10639 7789 +10640 7788 +10641 78cd +10642 78bb +10643 78cf +10644 78cc +10645 78d1 +10646 78ce +10647 78d4 +10648 78c8 +10649..10650 78c3 +10651 78c9 +10652 799a +10653 79a1 +10654 79a0 +10655 799c +10656 79a2 +10657 799b +10658 6b76 +10659 7a39 +10660 7ab2 +10661 7ab4 +10662 7ab3 +10663 7bb7 +10664 7bcb +10665 7bbe +10666 7bac +10667 7bce +10668 7baf +10669 7bb9 +10670 7bca +10671 7bb5 +10672 7cc5 +10673 7cc8 +10674 7ccc +10675 7ccb +10676 7df7 +10677 7ddb +10678 7dea +10679 7de7 +10680 7dd7 +10681 7de1 +10682 7e03 +10683 7dfa +10684 7de6 +10685 7df6 +10686 7df1 +10687 7df0 +10688 7dee +10689 7ddf +10690 7f76 +10691 7fac +10692 7fb0 +10693 7fad +10694 7fed +10695 7feb +10696 7fea +10697 7fec +10698 7fe6 +10699 7fe8 +10700 8064 +10701 8067 +10702 81a3 +10703 819f +10704 819e +10705 8195 +10706 81a2 +10707 8199 +10708 8197 +10709 8216 +10710 824f +10711 8253 +10712 8252 +10713 8250 +10714 824e +10715 8251 +10716 8524 +10717 853b +10718 850f +10719 8500 +10720 8529 +10721 850e +10722 8509 +10723 850d +10724 851f +10725 850a +10726 8527 +10727 851c +10728 84fb +10729 852b +10730 84fa +10731 8508 +10732 850c +10733 84f4 +10734 852a +10735 84f2 +10736 8515 +10737 84f7 +10738 84eb +10739 84f3 +10740 84fc +10741 8512 +10742 84ea +10743 84e9 +10744 8516 +10745 84fe +10746 8528 +10747 851d +10748 852e +10749 8502 +10750 84fd +10751 851e +10752 84f6 +10753 8531 +10754 8526 +10755..10756 84e7 +10757 84f0 +10758 84ef +10759 84f9 +10760 8518 +10761 8520 +10762 8530 +10763 850b +10764 8519 +10765 852f +10766 8662 +10767 8756 +10768..10769 8763 +10770 8777 +10771 87e1 +10772 8773 +10773 8758 +10774 8754 +10775 875b +10776 8752 +10777 8761 +10778 875a +10779 8751 +10780 875e +10781 876d +10782 876a +10783 8750 +10784 874e +10785 875f +10786 875d +10787 876f +10788 876c +10789 877a +10790 876e +10791 875c +10792 8765 +10793 874f +10794 877b +10795 8775 +10796 8762 +10797 8767 +10798 8769 +10799 885a +10800 8905 +10801 890c +10802 8914 +10803 890b +10804..10806 8917 +10807 8906 +10808 8916 +10809 8911 +10810 890e +10811 8909 +10812 89a2 +10813 89a4 +10814 89a3 +10815 89ed +10816 89f0 +10817 89ec +10818 8acf +10819 8ac6 +10820 8ab8 +10821 8ad3 +10822 8ad1 +10823..10824 8ad4 +10825 8abb +10826 8ad7 +10827 8abe +10828 8ac0 +10829 8ac5 +10830 8ad8 +10831 8ac3 +10832 8aba +10833 8abd +10834 8ad9 +10835 8c3e +10836 8c4d +10837 8c8f +10838 8ce5 +10839 8cdf +10840 8cd9 +10841 8ce8 +10842 8cda +10843 8cdd +10844 8ce7 +10845 8da0 +10846 8d9c +10847 8da1 +10848 8d9b +10849 8e20 +10850 8e23 +10851 8e25 +10852 8e24 +10853 8e2e +10854 8e15 +10855 8e1b +10856 8e16 +10857 8e11 +10858 8e19 +10859..10860 8e26 +10861 8e14 +10862 8e12 +10863 8e18 +10864 8e13 +10865 8e1c +10866 8e17 +10867 8e1a +10868 8f2c +10869 8f24 +10870 8f18 +10871 8f1a +10872 8f20 +10873 8f23 +10874..10875 8f16 +10876 9073 +10877 9070 +10878 906f +10879 9067 +10880 906b +10881 912f +10882 912b +10883..10884 9129 +10885 9132 +10886 9126 +10887 912e +10888..10889 9185 +10890 918a +10891..10892 9181 +10893 9184 +10894 9180 +10895 92d0 +10896..10897 92c3 +10898 92c0 +10899 92d9 +10900 92b6 +10901 92cf +10902 92f1 +10903 92df +10904 92d8 +10905 92e9 +10906 92d7 +10907 92dd +10908 92cc +10909 92ef +10910 92c2 +10911 92e8 +10912 92ca +10913 92c8 +10914 92ce +10915 92e6 +10916 92cd +10917 92d5 +10918 92c9 +10919 92e0 +10920 92de +10921 92e7 +10922 92d1 +10923 92d3 +10924 92b5 +10925 92e1 +10926 9325 +10927 92c6 +10928 92b4 +10929 957c +10930 95ac +10931 95ab +10932 95ae +10933 95b0 +10934 96a4 +10935 96a2 +10936 96d3 +10937 9705 +10938 9708 +10939 9702 +10940 975a +10941 978a +10942 978e +10943 9788 +10944 97d0 +10945 97cf +10946 981e +10947 981d +10948 9826 +10949 9829 +10950 9828 +10951 9820 +10952 981b +10953 9827 +10954 98b2 +10955 9908 +10956 98fa +10957 9911 +10958 9914 +10959..10960 9916 +10961 9915 +10962 99dc +10963 99cd +10964 99cf +10965..10966 99d3 +10967 99ce +10968 99c9 +10969 99d6 +10970 99d8 +10971 99cb +10972 99d7 +10973 99cc +10974 9ab3 +10975 9aec +10976 9aeb +10977 9af3 +10978 9af2 +10979 9af1 +10980 9b46 +10981 9b43 +10982 9b67 +10983 9b74 +10984 9b71 +10985 9b66 +10986 9b76 +10987 9b75 +10988 9b70 +10989 9b68 +10990 9b64 +10991 9b6c +10992 9cfc +10993 9cfa +10994 9cfd +10995 9cff +10996 9cf7 +10997 9d07 +10998 9d00 +10999 9cf9 +11000 9cfb +11001 9d08 +11002 9d05 +11003 9d04 +11004 9e83 +11005 9ed3 +11006..11007 9f0f +11008 511c +11009 5113 +11010 5117 +11011 511a +11012 5111 +11013 51de +11014 5334 +11015 53e1 +11016 5670 +11017 5660 +11018 566e +11019 5673 +11020 5666 +11021 5663 +11022 566d +11023 5672 +11024 565e +11025 5677 +11026 571c +11027 571b +11028 58c8 +11029 58bd +11030 58c9 +11031 58bf +11032 58ba +11033 58c2 +11034 58bc +11035 58c6 +11036 5b17 +11037 5b19 +11038 5b1b +11039 5b21 +11040 5b14 +11041 5b13 +11042 5b10 +11043 5b16 +11044 5b28 +11045 5b1a +11046 5b20 +11047 5b1e +11048 5bef +11049 5dac +11050 5db1 +11051 5da9 +11052 5da7 +11053 5db5 +11054 5db0 +11055 5dae +11056 5daa +11057 5da8 +11058 5db2 +11059 5dad +11060 5daf +11061 5db4 +11062..11063 5e67 +11064 5e66 +11065 5e6f +11066 5ee9 +11067 5ee7 +11068 5ee6 +11069 5ee8 +11070 5ee5 +11071 5f4b +11072 5fbc +11073 5fbb +11074 619d +11075 61a8 +11076 6196 +11077 61c5 +11078 61b4 +11079 61c6 +11080 61c1 +11081 61cc +11082 61ba +11083 61bf +11084 61b8 +11085 618c +11086 64d7 +11087 64d6 +11088 64d0 +11089 64cf +11090 64c9 +11091 64bd +11092 6489 +11093 64c3 +11094 64db +11095 64f3 +11096 64d9 +11097 6533 +11098 657f +11099 657c +11100 65a2 +11101 66c8 +11102 66be +11103 66c0 +11104..11105 66ca +11106 66cf +11107 66bd +11108 66bb +11109 66ba +11110 66cc +11111 6723 +11112 6a34 +11113 6a66 +11114 6a49 +11115 6a67 +11116 6a32 +11117 6a68 +11118 6a3e +11119 6a5d +11120 6a6d +11121 6a76 +11122 6a5b +11123 6a51 +11124 6a28 +11125 6a5a +11126 6a3b +11127 6a3f +11128 6a41 +11129 6a6a +11130 6a64 +11131 6a50 +11132 6a4f +11133 6a54 +11134 6a6f +11135 6a69 +11136 6a60 +11137 6a3c +11138 6a5e +11139 6a56 +11140 6a55 +11141..11142 6a4d +11143 6a46 +11144 6b55 +11145 6b54 +11146 6b56 +11147 6ba7 +11148..11149 6baa +11150 6bc8 +11151 6bc7 +11152 6c04 +11153 6c03 +11154 6c06 +11155 6fad +11156 6fcb +11157 6fa3 +11158 6fc7 +11159 6fbc +11160 6fce +11161 6fc8 +11162 6f5e +11163 6fc4 +11164 6fbd +11165 6f9e +11166 6fca +11167 6fa8 +11168 7004 +11169 6fa5 +11170 6fae +11171 6fba +11172 6fac +11173 6faa +11174 6fcf +11175 6fbf +11176 6fb8 +11177 6fa2 +11178 6fc9 +11179 6fab +11180 6fcd +11181 6faf +11182 6fb2 +11183 6fb0 +11184 71c5 +11185 71c2 +11186 71bf +11187 71b8 +11188 71d6 +11189..11190 71c0 +11191 71cb +11192 71d4 +11193 71ca +11194 71c7 +11195 71cf +11196 71bd +11197 71d8 +11198 71bc +11199 71c6 +11200..11201 71da +11202..11203 729d +11204 7369 +11205..11206 7366 +11207 736c +11208 7365 +11209 736b +11210 736a +11211 747f +11212 749a +11213 74a0 +11214 7494 +11215 7492 +11216 7495 +11217 74a1 +11218 750b +11219 7580 +11220 762f +11221 762d +11222 7631 +11223 763d +11224 7633 +11225 763c +11226 7635 +11227 7632 +11228 7630 +11229 76bb +11230 76e6 +11231 779a +11232 779d +11233 77a1 +11234 779c +11235 779b +11236..11237 77a2 +11238 7795 +11239 7799 +11240 7797 +11241 78dd +11242 78e9 +11243 78e5 +11244 78ea +11245 78de +11246 78e3 +11247 78db +11248..11249 78e1 +11250 78ed +11251..11252 78df +11253 79a4 +11254 7a44 +11255 7a48 +11256 7a47 +11257 7ab6 +11258 7ab8 +11259 7ab5 +11260 7ab1 +11261 7ab7 +11262 7bde +11263 7be3 +11264 7be7 +11265 7bdd +11266 7bd5 +11267 7be5 +11268 7bda +11269 7be8 +11270 7bf9 +11271 7bd4 +11272 7bea +11273 7be2 +11274 7bdc +11275 7beb +11276 7bd8 +11277 7bdf +11278 7cd2 +11279 7cd4 +11280 7cd7 +11281..11282 7cd0 +11283 7e12 +11284 7e21 +11285 7e17 +11286 7e0c +11287..11288 7e1f +11289 7e13 +11290 7e0e +11291 7e1c +11292 7e15 +11293 7e1a +11294 7e22 +11295 7e0b +11296 7e0f +11297 7e16 +11298 7e0d +11299 7e14 +11300 7e25 +11301 7e24 +11302 7f43 +11303..11304 7f7b +11305 7f7a +11306 7fb1 +11307 7fef +11308 802a +11309 8029 +11310 806c +11311 81b1 +11312 81a6 +11313 81ae +11314 81b9 +11315 81b5 +11316 81ab +11317 81b0 +11318 81ac +11319 81b4 +11320 81b2 +11321 81b7 +11322 81a7 +11323 81f2 +11324..11326 8255 +11327 8556 +11328 8545 +11329 856b +11330 854d +11331 8553 +11332 8561 +11333 8558 +11334 8540 +11335 8546 +11336 8564 +11337 8541 +11338 8562 +11339 8544 +11340 8551 +11341 8547 +11342 8563 +11343 853e +11344 855b +11345 8571 +11346 854e +11347 856e +11348 8575 +11349 8555 +11350 8567 +11351 8560 +11352 858c +11353 8566 +11354 855d +11355 8554 +11356 8565 +11357 856c +11358 8663 +11359 8665 +11360 8664 +11361 87a4 +11362 879b +11363 878f +11364 8797 +11365 8793 +11366 8792 +11367 8788 +11368 8781 +11369 8796 +11370 8798 +11371 8779 +11372 8787 +11373 87a3 +11374 8785 +11375..11376 8790 +11377 879d +11378 8784 +11379 8794 +11380 879c +11381 879a +11382 8789 +11383 891e +11384 8926 +11385 8930 +11386..11387 892d +11388 8927 +11389 8931 +11390 8922 +11391 8929 +11392 8923 +11393 892f +11394 892c +11395 891f +11396 89f1 +11397 8ae0 +11398 8ae2 +11399 8af2 +11400..11401 8af4 +11402 8add +11403 8b14 +11404 8ae4 +11405 8adf +11406 8af0 +11407 8ac8 +11408 8ade +11409 8ae1 +11410 8ae8 +11411 8aff +11412 8aef +11413 8afb +11414..11415 8c91 +11416 8c90 +11417 8cf5 +11418 8cee +11419 8cf1 +11420 8cf0 +11421 8cf3 +11422 8d6c +11423 8d6e +11424 8da5 +11425 8da7 +11426 8e33 +11427 8e3e +11428 8e38 +11429 8e40 +11430 8e45 +11431 8e36 +11432..11433 8e3c +11434 8e41 +11435 8e30 +11436 8e3f +11437 8ebd +11438 8f36 +11439 8f2e +11440 8f35 +11441 8f32 +11442 8f39 +11443 8f37 +11444 8f34 +11445 9076 +11446 9079 +11447 907b +11448 9086 +11449 90fa +11450 9133 +11451..11452 9135 +11453 9193 +11454..11455 9190 +11456 918d +11457 918f +11458 9327 +11459 931e +11460 9308 +11461 931f +11462 9306 +11463 930f +11464 937a +11465 9338 +11466 933c +11467 931b +11468 9323 +11469 9312 +11470 9301 +11471 9346 +11472 932d +11473 930e +11474 930d +11475 92cb +11476 931d +11477 92fa +11478 9313 +11479 92f9 +11480 92f7 +11481 9334 +11482 9302 +11483 9324 +11484 92ff +11485 9329 +11486 9339 +11487 9335 +11488 932a +11489 9314 +11490 930c +11491 930b +11492 92fe +11493 9309 +11494 9300 +11495 92fb +11496 9316 +11497 95bc +11498 95cd +11499 95be +11500..11501 95b9 +11502 95b6 +11503 95bf +11504 95b5 +11505 95bd +11506 96a9 +11507 96d4 +11508 970b +11509 9712 +11510 9710 +11511 9799 +11512 9797 +11513 9794 +11514 97f0 +11515 97f8 +11516 9835 +11517 982f +11518 9832 +11519 9924 +11520 991f +11521 9927 +11522 9929 +11523 999e +11524 99ee +11525 99ec +11526 99e5 +11527 99e4 +11528 99f0 +11529 99e3 +11530 99ea +11531 99e9 +11532 99e7 +11533 9ab9 +11534 9abf +11535 9ab4 +11536 9abb +11537 9af6 +11538 9afa +11539 9af9 +11540 9af7 +11541 9b33 +11542 9b80 +11543 9b85 +11544 9b87 +11545 9b7c +11546 9b7e +11547 9b7b +11548 9b82 +11549 9b93 +11550 9b92 +11551 9b90 +11552 9b7a +11553 9b95 +11554 9b7d +11555 9b88 +11556 9d25 +11557 9d17 +11558 9d20 +11559 9d1e +11560 9d14 +11561 9d29 +11562 9d1d +11563 9d18 +11564 9d22 +11565 9d10 +11566 9d19 +11567 9d1f +11568 9e88 +11569..11570 9e86 +11571 9eae +11572 9ead +11573..11574 9ed5 +11575 9efa +11576 9f12 +11577 9f3d +11578 5126 +11579 5125 +11580 5122 +11581 5124 +11582 5120 +11583 5129 +11584 52f4 +11585 5693 +11586..11587 568c +11588 5686 +11589 5684 +11590 5683 +11591 567e +11592 5682 +11593 567f +11594 5681 +11595 58d6 +11596 58d4 +11597 58cf +11598 58d2 +11599 5b2d +11600 5b25 +11601 5b32 +11602 5b23 +11603 5b2c +11604 5b27 +11605 5b26 +11606 5b2f +11607 5b2e +11608 5b7b +11609..11610 5bf1 +11611 5db7 +11612 5e6c +11613 5e6a +11614 5fbe +11615 61c3 +11616 61b5 +11617 61bc +11618 61e7 +11619 61e0 +11620 61e5 +11621 61e4 +11622 61e8 +11623 61de +11624 64ef +11625 64e9 +11626 64e3 +11627 64eb +11628 64e4 +11629 64e8 +11630 6581 +11631 6580 +11632 65b6 +11633 65da +11634 66d2 +11635 6a8d +11636 6a96 +11637 6a81 +11638 6aa5 +11639 6a89 +11640 6a9f +11641 6a9b +11642 6aa1 +11643 6a9e +11644 6a87 +11645 6a93 +11646 6a8e +11647 6a95 +11648 6a83 +11649 6aa8 +11650 6aa4 +11651 6a91 +11652 6a7f +11653 6aa6 +11654 6a9a +11655 6a85 +11656 6a8c +11657 6a92 +11658 6b5b +11659 6bad +11660 6c09 +11661 6fcc +11662 6fa9 +11663 6ff4 +11664 6fd4 +11665 6fe3 +11666 6fdc +11667 6fed +11668 6fe7 +11669 6fe6 +11670 6fde +11671 6ff2 +11672 6fdd +11673 6fe2 +11674 6fe8 +11675 71e1 +11676 71f1 +11677 71e8 +11678 71f2 +11679 71e4 +11680 71f0 +11681 71e2 +11682 7373 +11683..11684 736e +11685 7497 +11686 74b2 +11687 74ab +11688 7490 +11689 74aa +11690 74ad +11691 74b1 +11692 74a5 +11693 74af +11694..11696 7510 +11697 750f +11698 7584 +11699 7643 +11700..11701 7648 +11702 7647 +11703 76a4 +11704 76e9 +11705 77b5 +11706 77ab +11707 77b2 +11708 77b7 +11709 77b6 +11710 77b4 +11711 77b1 +11712 77a8 +11713 77f0 +11714 78f3 +11715 78fd +11716 7902 +11717..11718 78fb +11719 78ff +11720 78f2 +11721 7905 +11722 78f9 +11723 78fe +11724 7904 +11725 79ab +11726 79a8 +11727 7a5c +11728 7a5b +11729 7a56 +11730 7a58 +11731 7a54 +11732 7a5a +11733 7abe +11734..11735 7ac0 +11736 7c05 +11737 7c0f +11738 7bf2 +11739 7c00 +11740 7bff +11741 7bfb +11742 7c0e +11743 7bf4 +11744 7c0b +11745 7bf3 +11746 7c02 +11747 7c09 +11748 7c03 +11749 7c01 +11750 7bf8 +11751 7bfd +11752 7c06 +11753..11754 7bf0 +11755 7c10 +11756 7c0a +11757 7ce8 +11758 7e2d +11759 7e3c +11760 7e42 +11761 7e33 +11762 9848 +11763 7e38 +11764 7e2a +11765 7e49 +11766 7e40 +11767 7e47 +11768 7e29 +11769 7e4c +11770 7e30 +11771 7e3b +11772 7e36 +11773 7e44 +11774 7e3a +11775 7f45 +11776 7f7f +11777 7f7e +11778 7f7d +11779 7ff4 +11780 7ff2 +11781 802c +11782 81bb +11783 81c4 +11784 81cc +11785 81ca +11786 81c5 +11787 81c7 +11788 81bc +11789 81e9 +11790 825b +11791 825a +11792 825c +11793 8583 +11794 8580 +11795 858f +11796 85a7 +11797 8595 +11798 85a0 +11799 858b +11800 85a3 +11801 857b +11802 85a4 +11803 859a +11804 859e +11805 8577 +11806 857c +11807 8589 +11808 85a1 +11809 857a +11810 8578 +11811 8557 +11812 858e +11813 8596 +11814 8586 +11815 858d +11816 8599 +11817 859d +11818 8581 +11819 85a2 +11820 8582 +11821 8588 +11822 8585 +11823 8579 +11824 8576 +11825 8598 +11826 8590 +11827 859f +11828 8668 +11829 87be +11830 87aa +11831 87ad +11832 87c5 +11833 87b0 +11834 87ac +11835 87b9 +11836 87b5 +11837 87bc +11838 87ae +11839 87c9 +11840 87c3 +11841 87c2 +11842 87cc +11843 87b7 +11844 87af +11845 87c4 +11846 87ca +11847 87b4 +11848 87b6 +11849 87bf +11850 87b8 +11851 87bd +11852 87de +11853 87b2 +11854 8935 +11855 8933 +11856 893c +11857 893e +11858 8941 +11859 8952 +11860 8937 +11861 8942 +11862 89ad +11863 89af +11864 89ae +11865..11866 89f2 +11867 8b1e +11868 8b18 +11869 8b16 +11870 8b11 +11871 8b05 +11872 8b0b +11873 8b22 +11874 8b0f +11875 8b12 +11876 8b15 +11877 8b07 +11878 8b0d +11879 8b08 +11880 8b06 +11881 8b1c +11882 8b13 +11883 8b1a +11884 8c4f +11885 8c70 +11886 8c72 +11887 8c71 +11888 8c6f +11889 8c95 +11890 8c94 +11891 8cf9 +11892 8d6f +11893 8e4e +11894 8e4d +11895 8e53 +11896 8e50 +11897 8e4c +11898 8e47 +11899 8f43 +11900 8f40 +11901 9085 +11902 907e +11903 9138 +11904 919a +11905 91a2 +11906 919b +11907 9199 +11908 919f +11909 91a1 +11910 919d +11911 91a0 +11912 93a1 +11913 9383 +11914 93af +11915 9364 +11916 9356 +11917 9347 +11918 937c +11919 9358 +11920 935c +11921 9376 +11922 9349 +11923..11924 9350 +11925 9360 +11926 936d +11927 938f +11928 934c +11929 936a +11930 9379 +11931 9357 +11932 9355 +11933 9352 +11934 934f +11935 9371 +11936 9377 +11937 937b +11938 9361 +11939 935e +11940 9363 +11941 9367 +11942 934e +11943 9359 +11944 95c7 +11945 95c0 +11946 95c9 +11947 95c3 +11948 95c5 +11949 95b7 +11950 96ae +11951 96b0 +11952 96ac +11953 9720 +11954 971f +11955 9718 +11956 971d +11957 9719 +11958 979a +11959 97a1 +11960 979c +11961 979e +11962 979d +11963 97d5 +11964 97d4 +11965 97f1 +11966 9841 +11967 9844 +11968 984a +11969 9849 +11970 9845 +11971 9843 +11972 9925 +11973..11974 992b +11975 992a +11976 9933 +11977 9932 +11978 992f +11979 992d +11980 9931 +11981 9930 +11982 9998 +11983 99a3 +11984 99a1 +11985 9a02 +11986 99fa +11987 99f4 +11988 99f7 +11989 99f9 +11990 99f8 +11991 99f6 +11992 99fb +11993..11994 99fd +11995 99fc +11996 9a03 +11997 9abe +11998 9afe +11999 9afd +12000 9b01 +12001 9afc +12002 9b48 +12003 9b9a +12004 9ba8 +12005 9b9e +12006 9b9b +12007 9ba6 +12008 9ba1 +12009 9ba5 +12010 9ba4 +12011 9b86 +12012 9ba2 +12013 9ba0 +12014 9baf +12015 9d33 +12016 9d41 +12017 9d67 +12018 9d36 +12019..12020 9d2e +12021 9d31 +12022 9d38 +12023 9d30 +12024 9d45 +12025..12026 9d42 +12027 9d3e +12028 9d37 +12029 9d40 +12030 9d3d +12031 7ff5 +12032 9d2d +12033 9e8a +12034 9e89 +12035 9e8d +12036 9eb0 +12037 9ec8 +12038 9eda +12039 9efb +12040 9eff +12041 9f24 +12042 9f23 +12043 9f22 +12044 9f54 +12045 9fa0 +12046 5131 +12047..12048 512d +12049 5698 +12050 569c +12051 5697 +12052 569a +12053 569d +12054 5699 +12055 5970 +12056 5b3c +12057..12058 5c69 +12059 5dc0 +12060..12061 5e6d +12062 61d8 +12063 61df +12064..12065 61ed +12066 61f1 +12067 61ea +12068 61f0 +12069 61eb +12070 61d6 +12071 61e9 +12072 64ff +12073 6504 +12074 64fd +12075 64f8 +12076 6501 +12077 6503 +12078 64fc +12079 6594 +12080 65db +12081..12082 66da +12083 66d8 +12084 6ac5 +12085 6ab9 +12086 6abd +12087 6ae1 +12088 6ac6 +12089 6aba +12090..12091 6ab6 +12092 6ac7 +12093 6ab4 +12094 6aad +12095 6b5e +12096 6bc9 +12097 6c0b +12098 7007 +12099..12100 700c +12101 7001 +12102 7005 +12103 7014 +12104 700e +12105..12106 6fff +12107 6ffb +12108 7026 +12109 6ffc +12110 6ff7 +12111 700a +12112 7201 +12113 71ff +12114 71f9 +12115 7203 +12116 71fd +12117 7376 +12118 74b8 +12119 74c0 +12120 74b5 +12121 74c1 +12122 74be +12123 74b6 +12124 74bb +12125 74c2 +12126 7514 +12127 7513 +12128 765c +12129 7664 +12130 7659 +12131 7650 +12132 7653 +12133 7657 +12134 765a +12135 76a6 +12136 76bd +12137 76ec +12138 77c2 +12139 77ba +12140 790c +12141..12142 7913 +12143 7909 +12144 7910 +12145 7912 +12146 7911 +12147 79ad +12148 79ac +12149 7a5f +12150 7c1c +12151 7c29 +12152 7c19 +12153 7c20 +12154 7c1f +12155 7c2d +12156 7c1d +12157 7c26 +12158 7c28 +12159 7c22 +12160 7c25 +12161 7c30 +12162 7e5c +12163 7e50 +12164 7e56 +12165 7e63 +12166 7e58 +12167 7e62 +12168 7e5f +12169 7e51 +12170 7e60 +12171 7e57 +12172 7e53 +12173 7fb5 +12174 7fb3 +12175..12176 7ff7 +12177 8075 +12178..12179 81d1 +12180 81d0 +12181 825f +12182 825e +12183 85b4 +12184 85c6 +12185 85c0 +12186 85c3 +12187 85c2 +12188 85b3 +12189 85b5 +12190 85bd +12191 85c7 +12192 85c4 +12193 85bf +12194 85cb +12195 85ce +12196 85c8 +12197 85c5 +12198 85b1 +12199 85b6 +12200 85d2 +12201 8624 +12202 85b8 +12203 85b7 +12204 85be +12205 8669 +12206 87e7 +12207 87e6 +12208 87e2 +12209 87db +12210 87eb +12211 87ea +12212 87e5 +12213 87df +12214 87f3 +12215 87e4 +12216 87d4 +12217 87dc +12218 87d3 +12219 87ed +12220 87d8 +12221 87e3 +12222 87d7 +12223 87d9 +12224 8801 +12225 87f4 +12226 87e8 +12227 87dd +12228 8953 +12229 894b +12230 894f +12231 894c +12232 8946 +12233..12234 8950 +12235 8949 +12236 8b2a +12237 8b27 +12238 8b23 +12239 8b33 +12240 8b30 +12241 8b35 +12242 8b47 +12243 8b2f +12244 8b3c +12245 8b3e +12246 8b31 +12247 8b25 +12248 8b37 +12249 8b26 +12250 8b36 +12251 8b2e +12252 8b24 +12253 8b3b +12254 8b3d +12255 8b3a +12256 8c42 +12257 8c75 +12258 8c99 +12259 8c98 +12260 8c97 +12261 8cfe +12262 8d04 +12263 8d02 +12264 8d00 +12265 8e5c +12266 8e62 +12267 8e60 +12268 8e57 +12269 8e56 +12270 8e5e +12271 8e65 +12272 8e67 +12273 8e5b +12274 8e5a +12275 8e61 +12276 8e5d +12277 8e69 +12278 8e54 +12279..12281 8f46 +12282 8f4b +12283 9128 +12284..12285 913a +12286 913e +12287 91a8 +12288 91a5 +12289 91a7 +12290 91af +12291 91aa +12292 93b5 +12293 938c +12294 9392 +12295 93b7 +12296 939b +12297 939d +12298 9389 +12299 93a7 +12300 938e +12301 93aa +12302 939e +12303 93a6 +12304 9395 +12305 9388 +12306 9399 +12307 939f +12308 9380 +12309 938d +12310 93b1 +12311 9391 +12312 93b2 +12313 93a4 +12314 93a8 +12315 93b4 +12316 93a3 +12317..12318 95d2 +12319 95d1 +12320 96b3 +12321 96d7 +12322 96da +12323 5dc2 +12324 96df +12325 96d8 +12326 96dd +12327 9723 +12328 9722 +12329 9725 +12330 97ac +12331 97ae +12332 97a8 +12333 97ab +12334 97a4 +12335 97aa +12336 97a2 +12337 97a5 +12338 97d7 +12339 97d9 +12340 97d6 +12341 97d8 +12342 97fa +12343..12345 9850 +12346 98b8 +12347 9941 +12348 993c +12349 993a +12350 9a0f +12351 9a0b +12352 9a09 +12353 9a0d +12354 9a04 +12355 9a11 +12356 9a0a +12357 9a05 +12358 9a07 +12359 9a06 +12360 9ac0 +12361 9adc +12362 9b08 +12363..12364 9b04 +12365 9b29 +12366 9b35 +12367 9b4a +12368 9b4c +12369 9b4b +12370 9bc7 +12371 9bc6 +12372 9bc3 +12373 9bbf +12374 9bc1 +12375 9bb5 +12376 9bb8 +12377 9bd3 +12378 9bb6 +12379 9bc4 +12380 9bb9 +12381 9bbd +12382 9d5c +12383 9d53 +12384 9d4f +12385 9d4a +12386 9d5b +12387 9d4b +12388 9d59 +12389 9d56 +12390 9d4c +12391 9d57 +12392 9d52 +12393 9d54 +12394 9d5f +12395 9d58 +12396 9d5a +12397 9e8e +12398 9e8c +12399 9edf +12400 9f01 +12401 9f00 +12402 9f16 +12403 9f25 +12404 9f2b +12405 9f2a +12406 9f29 +12407 9f28 +12408 9f4c +12409 9f55 +12410..12411 5134 +12412 5296 +12413 52f7 +12414 53b4 +12415 56ab +12416 56ad +12417..12418 56a6 +12419 56aa +12420 56ac +12421 58da +12422 58dd +12423 58db +12424 5912 +12425..12427 5b3d +12428 5dc3 +12429 5e70 +12430 5fbf +12431 61fb +12432 6507 +12433 6510 +12434 650d +12435 6509 +12436 650c +12437 650e +12438 6584 +12439 65de +12440 65dd +12441 66de +12442 6ae7 +12443 6ae0 +12444 6acc +12445 6ad1 +12446 6ad9 +12447 6acb +12448 6adf +12449 6adc +12450 6ad0 +12451 6aeb +12452 6acf +12453 6acd +12454 6ade +12455 6b60 +12456 6bb0 +12457 6c0c +12458 7019 +12459 7027 +12460 7020 +12461 7016 +12462 702b +12463..12465 7021 +12466 7029 +12467 7017 +12468 7024 +12469 701c +12470 720c +12471 720a +12472 7207 +12473 7202 +12474 7205 +12475..12476 72a5 +12477 72a4 +12478 72a3 +12479 72a1 +12480 74cb +12481 74c5 +12482 74b7 +12483 74c3 +12484 7516 +12485 7660 +12486..12487 77c9 +12488 77c4 +12489 77f1 +12490 791d +12491 791b +12492 7921 +12493 791c +12494 7917 +12495 791e +12496 79b0 +12497..12498 7a67 +12499 7c33 +12500 7c3c +12501 7c39 +12502 7c2c +12503 7c3b +12504 7cec +12505 7cea +12506 7e76 +12507 7e75 +12508 7e78 +12509 7e70 +12510 7e77 +12511 7e6f +12512 7e7a +12513 7e72 +12514 7e74 +12515 7e68 +12516 7f4b +12517 7f4a +12518 7f83 +12519 7f86 +12520 7fb7 +12521..12522 7ffd +12523 8078 +12524 81d7 +12525 81d5 +12526 820b +12527 8264 +12528 8261 +12529 8263 +12530 85eb +12531 85f1 +12532 85ed +12533 85d9 +12534 85e1 +12535 85e8 +12536 85da +12537 85d7 +12538 85ec +12539 85f2 +12540 85f8 +12541 85d8 +12542 85df +12543 85e3 +12544 85dc +12545 85d1 +12546 85f0 +12547 85e6 +12548 85ef +12549 85de +12550 85e2 +12551 8800 +12552 87fa +12553 8803 +12554..12555 87f6 +12556 8809 +12557 880c +12558 880b +12559 8806 +12560 87fc +12561 8808 +12562 87ff +12563 880a +12564 8802 +12565 8962 +12566..12567 895a +12568 8957 +12569 8961 +12570 895c +12571 8958 +12572 895d +12573 8959 +12574 8988 +12575 89b7 +12576 89b6 +12577 89f6 +12578 8b50 +12579 8b48 +12580 8b4a +12581 8b40 +12582 8b53 +12583 8b56 +12584 8b54 +12585 8b4b +12586 8b55 +12587 8b51 +12588 8b42 +12589 8b52 +12590 8b57 +12591 8c43 +12592 8c77 +12593 8c76 +12594 8c9a +12595..12596 8d06 +12597 8d09 +12598 8dac +12599 8daa +12600 8dad +12601 8dab +12602 8e6d +12603 8e78 +12604 8e73 +12605 8e6a +12606 8e6f +12607 8e7b +12608 8ec2 +12609 8f52 +12610 8f51 +12611..12612 8f4f +12613 8f53 +12614 8fb4 +12615 9140 +12616 913f +12617 91b0 +12618 91ad +12619 93de +12620 93c7 +12621 93cf +12622 93c2 +12623 93da +12624 93d0 +12625 93f9 +12626 93ec +12627 93cc +12628 93d9 +12629 93a9 +12630 93e6 +12631 93ca +12632 93d4 +12633 93ee +12634 93e3 +12635 93d5 +12636 93c4 +12637 93ce +12638 93c0 +12639 93d2 +12640 93a5 +12641 93e7 +12642 957d +12643..12644 95da +12645 96e1 +12646 9729 +12647..12648 972b +12649 9728 +12650 9726 +12651 97b3 +12652 97b7 +12653 97b6 +12654..12656 97dd +12657 985c +12658 9859 +12659 985d +12660 9857 +12661 98bf +12662 98bd +12663 98bb +12664 98be +12665 9948 +12666 9947 +12667 9943 +12668..12669 99a6 +12670 9a1a +12671 9a15 +12672 9a25 +12673 9a1d +12674 9a24 +12675 9a1b +12676 9a22 +12677 9a20 +12678 9a27 +12679 9a23 +12680 9a1e +12681 9a1c +12682 9a14 +12683 9ac2 +12684 9b0b +12685 9b0a +12686 9b0e +12687 9b0c +12688 9b37 +12689..12690 9bea +12691 9be0 +12692 9bde +12693 9be4 +12694 9be6 +12695 9be2 +12696 9bf0 +12697 9bd4 +12698 9bd7 +12699 9bec +12700 9bdc +12701 9bd9 +12702 9be5 +12703 9bd5 +12704 9be1 +12705 9bda +12706 9d77 +12707 9d81 +12708 9d8a +12709 9d84 +12710 9d88 +12711 9d71 +12712 9d80 +12713 9d78 +12714 9d86 +12715..12716 9d8b +12717 9d7d +12718 9d6b +12719..12720 9d74 +12721 9d70 +12722 9d69 +12723 9d85 +12724 9d73 +12725 9d7b +12726 9d82 +12727 9d6f +12728 9d79 +12729 9d7f +12730 9d87 +12731 9d68 +12732 9e94 +12733 9e91 +12734 9ec0 +12735 9efc +12736 9f2d +12737..12738 9f40 +12739 9f4d +12740..12742 9f56 +12743 5337 +12744 56b2 +12745 56b5 +12746 56b3 +12747 58e3 +12748 5b45 +12749..12750 5dc6 +12751..12752 5eee +12753..12754 5fc0 +12755 61f9 +12756 6517 +12757 6516 +12758 6515 +12759 6513 +12760 65df +12761 66e8 +12762..12763 66e3 +12764 6af3 +12765 6af0 +12766 6aea +12767 6ae8 +12768 6af9 +12769 6af1 +12770..12771 6aee +12772 703c +12773 7035 +12774 702f +12775 7037 +12776 7034 +12777 7031 +12778 7042 +12779 7038 +12780 703f +12781 703a +12782 7039 +12783 702a +12784 7040 +12785 703b +12786 7033 +12787 7041 +12788..12789 7213 +12790 72a8 +12791 737d +12792 737c +12793 74ba +12794 76ab +12795 76aa +12796 76be +12797 76ed +12798 77cc +12799..12800 77ce +12801 77cd +12802 77f2 +12803 7925 +12804 7923 +12805..12806 7927 +12807 7924 +12808 7929 +12809 79b2 +12810 7a6e +12811..12812 7a6c +12813 7af7 +12814 7c49 +12815 7c48 +12816 7c4a +12817 7c47 +12818 7c45 +12819 7cee +12820 7e7b +12821 7e7e +12822 7e81 +12823 7e80 +12824 7fba +12825 7fff +12826 8079 +12827 81db +12828 81d9 +12829..12830 8268 +12831 8622 +12832 85ff +12833 8601 +12834 85fe +12835 861b +12836 8600 +12837 85f6 +12838 8604 +12839 8609 +12840 8605 +12841 860c +12842 85fd +12843 8819 +12844..12845 8810 +12846 8817 +12847 8813 +12848 8816 +12849 8963 +12850 8966 +12851 89b9 +12852 89f7 +12853 8b60 +12854 8b6a +12855 8b5d +12856 8b68 +12857 8b63 +12858 8b65 +12859 8b67 +12860 8b6d +12861 8dae +12862 8e86 +12863 8e88 +12864 8e84 +12865 8f59 +12866..12867 8f56 +12868 8f55 +12869 8f58 +12870 8f5a +12871 908d +12872 9143 +12873 9141 +12874 91b7 +12875 91b5 +12876..12877 91b2 +12878 940b +12879 9413 +12880 93fb +12881 9420 +12882 940f +12883 9414 +12884 93fe +12885 9415 +12886 9410 +12887 9428 +12888 9419 +12889 940d +12890 93f5 +12891 9400 +12892 93f7 +12893 9407 +12894 940e +12895 9416 +12896 9412 +12897 93fa +12898 9409 +12899 93f8 +12900 943c +12901 940a +12902 93ff +12903 93fc +12904 940c +12905 93f6 +12906 9411 +12907 9406 +12908 95de +12909 95e0 +12910 95df +12911..12912 972e +12913 97b9 +12914 97bb +12915..12916 97fd +12917 9860 +12918..12919 9862 +12920 985f +12921..12922 98c1 +12923 9950 +12924 994e +12925 9959 +12926 994c +12927 994b +12928 9953 +12929 9a32 +12930 9a34 +12931 9a31 +12932 9a2c +12933 9a2a +12934 9a36 +12935 9a29 +12936 9a2e +12937 9a38 +12938 9a2d +12939 9ac7 +12940 9aca +12941 9ac6 +12942 9b10 +12943 9b12 +12944 9b11 +12945 9c0b +12946 9c08 +12947 9bf7 +12948 9c05 +12949 9c12 +12950 9bf8 +12951 9c40 +12952 9c07 +12953 9c0e +12954 9c06 +12955 9c17 +12956 9c14 +12957 9c09 +12958 9d9f +12959 9d99 +12960 9da4 +12961 9d9d +12962 9d92 +12963 9d98 +12964 9d90 +12965 9d9b +12966 9da0 +12967 9d94 +12968 9d9c +12969 9daa +12970 9d97 +12971 9da1 +12972 9d9a +12973 9da2 +12974 9da8 +12975 9d9e +12976 9da3 +12977 9dbf +12978 9da9 +12979 9d96 +12980..12981 9da6 +12982 9e99 +12983 9e9b +12984 9e9a +12985 9ee5 +12986 9ee4 +12987 9ee7 +12988 9ee6 +12989 9f30 +12990 9f2e +12991 9f5b +12992 9f60 +12993 9f5e +12994 9f5d +12995 9f59 +12996 9f91 +12997 513a +12998 5139 +12999 5298 +13000 5297 +13001 56c3 +13002..13003 56bd +13004 5b48 +13005 5b47 +13006 5dcb +13007 5dcf +13008 5ef1 +13009 61fd +13010 651b +13011 6b02 +13012 6afc +13013 6b03 +13014 6af8 +13015 6b00 +13016..13017 7043 +13018 704a +13019..13020 7048 +13021..13022 7045 +13023 721d +13024 721a +13025 7219 +13026 737e +13027 7517 +13028 766a +13029 77d0 +13030 792d +13031 7931 +13032 792f +13033 7c54 +13034 7c53 +13035 7cf2 +13036 7e8a +13037 eb45 +13038 7e88 +13039 7e8b +13040 7e86 +13041 7e8d +13042 7f4d +13043 7fbb +13044 8030 +13045 81dd +13046 8618 +13047 862a +13048 8626 +13049 861f +13050 8623 +13051 861c +13052 8619 +13053 8627 +13054 862e +13055 8621 +13056 8620 +13057 8629 +13058 861e +13059 8625 +13060 8829 +13061 881d +13062 881b +13063 8820 +13064 8824 +13065 881c +13066 882b +13067 884a +13068 896d +13069 8969 +13070 896e +13071 896b +13072 89fa +13073 8b79 +13074 8b78 +13075 8b45 +13076..13077 8b7a +13078 8d10 +13079 8d14 +13080 8daf +13081 8e8e +13082 8e8c +13083 8f5e +13084 8f5b +13085 8f5d +13086 9146 +13087..13088 9144 +13089 91b9 +13090 943f +13091 943b +13092 9436 +13093 9429 +13094 943d +13095 9430 +13096 9439 +13097 942a +13098 9437 +13099 942c +13100 9440 +13101 9431 +13102 95e5 +13103 95e4 +13104 95e3 +13105 9735 +13106 973a +13107 97bf +13108 97e1 +13109 9864 +13110 98c9 +13111 98c6 +13112 98c0 +13113 9958 +13114 9956 +13115 9a39 +13116 9a3d +13117 9a46 +13118 9a44 +13119 9a42 +13120 9a41 +13121 9a3a +13122 9a3f +13123 9acd +13124 9b15 +13125..13126 9b17 +13127 9b16 +13128 9b3a +13129 9b52 +13130 9c2b +13131 9c1d +13132 9c1c +13133 9c2c +13134 9c23 +13135..13136 9c28 +13137 9c24 +13138 9c21 +13139 9db7 +13140 9db6 +13141 9dbc +13142 9dc1 +13143 9dc7 +13144 9dca +13145 9dcf +13146 9dbe +13147 9dc5 +13148 9dc3 +13149 9dbb +13150 9db5 +13151 9dce +13152..13153 9db9 +13154 9dac +13155 9dc8 +13156 9db1 +13157 9dad +13158 9dcc +13159 9db3 +13160 9dcd +13161 9db2 +13162 9e7a +13163 9e9c +13164 9eeb +13165 9eee +13166 9eed +13167 9f1b +13168 9f18 +13169 9f1a +13170 9f31 +13171 9f4e +13172 9f65 +13173 9f64 +13174 9f92 +13175 4eb9 +13176 56c6 +13177 56c5 +13178 56cb +13179 5971 +13180..13181 5b4b +13182 5dd5 +13183 5dd1 +13184 5ef2 +13185 6521 +13186 6520 +13187 6526 +13188 6522 +13189 6b0b +13190..13191 6b08 +13192 6c0d +13193..13195 7055 +13196 7052 +13197..13198 721e +13199 72a9 +13200 737f +13201 74d8 +13202 74d5 +13203 74d9 +13204 74d7 +13205 766d +13206 76ad +13207 7935 +13208 79b4 +13209..13210 7a70 +13211 7c57 +13212 7c5c +13213 7c59 +13214 7c5b +13215 7c5a +13216 7cf4 +13217 7cf1 +13218 7e91 +13219 7f4f +13220 7f87 +13221 81de +13222 826b +13223..13224 8634 +13225 8633 +13226 862c +13227 8632 +13228 8636 +13229 882c +13230 8828 +13231 8826 +13232 882a +13233 8825 +13234 8971 +13235 89bf +13236 89be +13237 89fb +13238 8b7e +13239 8b84 +13240 8b82 +13241 8b86 +13242 8b85 +13243 8b7f +13244 8d15 +13245 8e95 +13246 8e94 +13247 8e9a +13248 8e92 +13249 8e90 +13250..13251 8e96 +13252 8f60 +13253 8f62 +13254 9147 +13255 944c +13256 9450 +13257..13258 944a +13259 944f +13260 9447 +13261 9445 +13262..13263 9448 +13264 9446 +13265 973f +13266 97e3 +13267 986a +13268 9869 +13269 98cb +13270 9954 +13271 995b +13272 9a4e +13273..13274 9a53 +13275 9a4c +13276 9a4f +13277 9a48 +13278 9a4a +13279 9a49 +13280 9a52 +13281 9a50 +13282 9ad0 +13283 9b19 +13284 9b2b +13285 9b3b +13286 9b56 +13287 9b55 +13288 9c46 +13289 9c48 +13290 9c3f +13291 9c44 +13292 9c39 +13293 9c33 +13294 9c41 +13295 9c3c +13296 9c37 +13297 9c34 +13298 9c32 +13299 9c3d +13300 9c36 +13301 9ddb +13302 9dd2 +13303 9dde +13304 9dda +13305 9dcb +13306 9dd0 +13307 9ddc +13308 9dd1 +13309 9ddf +13310 9de9 +13311 9dd9 +13312 9dd8 +13313 9dd6 +13314 9df5 +13315 9dd5 +13316 9ddd +13317 9eb6 +13318 9ef0 +13319 9f35 +13320 9f33 +13321 9f32 +13322 9f42 +13323 9f6b +13324 9f95 +13325 9fa2 +13326 513d +13327 5299 +13328 58e8 +13329 58e7 +13330 5972 +13331 5b4d +13332 5dd8 +13333 882f +13334 5f4f +13335 6201 +13336..13337 6203 +13338 6529 +13339 6525 +13340 6596 +13341 66eb +13342..13343 6b11 +13344 6b0f +13345 6bca +13346 705b +13347 705a +13348 7222 +13349 7382 +13350 7381 +13351 7383 +13352 7670 +13353 77d4 +13354 7c67 +13355 7c66 +13356 7e95 +13357 826c +13358 863a +13359 8640 +13360 8639 +13361 863c +13362 8631 +13363 863b +13364 863e +13365 8830 +13366 8832 +13367 882e +13368 8833 +13369 8976 +13370 8974 +13371 8973 +13372 89fe +13373 8b8c +13374 8b8e +13375 8b8b +13376 8b88 +13377 8c45 +13378 8d19 +13379 8e98 +13380 8f64 +13381 8f63 +13382 91bc +13383 9462 +13384 9455 +13385 945d +13386 9457 +13387 945e +13388..13389 97c4 +13390 9800 +13391 9a56 +13392 9a59 +13393..13395 9b1e +13396 9c52 +13397 9c58 +13398 9c50 +13399 9c4a +13400 9c4d +13401 9c4b +13402 9c55 +13403 9c59 +13404 9c4c +13405 9c4e +13406 9dfb +13407 9df7 +13408 9def +13409 9de3 +13410 9deb +13411 9df8 +13412 9de4 +13413 9df6 +13414 9de1 +13415 9dee +13416 9de6 +13417 9df2 +13418 9df0 +13419 9de2 +13420 9dec +13421 9df4 +13422 9df3 +13423 9de8 +13424 9ded +13425 9ec2 +13426 9ed0 +13427..13428 9ef2 +13429 9f06 +13430 9f1c +13431 9f38 +13432 9f37 +13433 9f36 +13434 9f43 +13435 9f4f +13436 9f71 +13437 9f70 +13438..13439 9f6e +13440 56d3 +13441 56cd +13442 5b4e +13443 5c6d +13444 652d +13445..13446 66ed +13447 6b13 +13448 705f +13449 7061 +13450 705d +13451 7060 +13452 7223 +13453 74db +13454 74e5 +13455 77d5 +13456 7938 +13457 79b7 +13458 79b6 +13459 7c6a +13460 7e97 +13461 7f89 +13462 826d +13463 8643 +13464 8838 +13465 8837 +13466 8835 +13467 884b +13468..13469 8b94 +13470..13472 8e9e +13473 8e9d +13474 91be +13475 91bd +13476 91c2 +13477 946b +13478..13479 9468 +13480 96e5 +13481 9746 +13482 9743 +13483 9747 +13484 97c7 +13485 97e5 +13486 9a5e +13487 9ad5 +13488 9b59 +13489 9c63 +13490 9c67 +13491 9c66 +13492 9c62 +13493 9c5e +13494 9c60 +13495 9e02 +13496 9dfe +13497 9e07 +13498 9e03 +13499 9e06 +13500 9e05 +13501..13502 9e00 +13503 9e09 +13504 9dff +13505 9dfd +13506 9e04 +13507 9ea0 +13508 9f1e +13509 9f46 +13510..13512 9f74 +13513 56d4 +13514 652e +13515 65b8 +13516..13517 6b18 +13518 6b17 +13519 6b1a +13520 7062 +13521 7226 +13522 72aa +13523..13524 77d8 +13525 7939 +13526 7c69 +13527 7c6b +13528 7cf6 +13529 7e9a +13530 7e98 +13531 7e9b +13532 7e99 +13533..13534 81e0 +13535..13537 8646 +13538..13539 8979 +13540 897c +13541 897b +13542 89ff +13543..13544 8b98 +13545 8ea5 +13546 8ea4 +13547 8ea3 +13548 946e +13549 946d +13550 946f +13551 9471 +13552 9473 +13553 9749 +13554 9872 +13555 995f +13556 9c68 +13557 9c6e +13558 9c6d +13559 9e0b +13560 9e0d +13561 9e10 +13562 9e0f +13563 9e12 +13564 9e11 +13565 9ea1 +13566 9ef5 +13567 9f09 +13568 9f47 +13569 9f78 +13570 9f7b +13571 9f7a +13572 9f79 +13573 571e +13574 7066 +13575 7c6f +13576 883c +13577 8db2 +13578 8ea6 +13579 91c3 +13580 9474 +13581 9478 +13582 9476 +13583 9475 +13584 9a60 +13585 9b2e +13586 9c74 +13587 9c73 +13588 9c71 +13589 9c75 +13590 9e14 +13591 9e13 +13592 9ef6 +13593 9f0a +13594 9fa4 +13595 7068 +13596 7065 +13597 7cf7 +13598 866a +13599 883e +13600 883d +13601 883f +13602 8b9e +13603 8c9c +13604 8ea9 +13605 8ec9 +13606 974b +13607..13608 9873 +13609 98cc +13610 9961 +13611 99ab +13612 9a64 +13613..13614 9a66 +13615 9b24 +13616 9e15 +13617 9e17 +13618 9f48 +13619 6207 +13620 6b1e +13621 7227 +13622 864c +13623 8ea8 +13624 9482 +13625..13626 9480 +13627 9a69 +13628 9a68 +13629 9e19 +13630 864b +13631 8b9f +13632 9483 +13633 9c79 +13634 9eb7 +13635 7675 +13636 9a6b +13637 9c7a +13638 9e1d +13639..13640 7069 +13641 7229 +13642 9ea4 +13643 9f7e +13644 9f49 +13645 9f98 +13648 /uni0020.hw +13649 /uni0021.hw +13650 /uni0022.hw +13651 /uni0023.hw +13652 /uni0024.hw +13653 /uni0025.hw +13654 /uni0026.hw +13655 /uni0027.hw +13656 /uni0028.hw +13657 /uni0029.hw +13658 /uni002A.hw +13659 /uni002B.hw +13660 /uni002C.hw +13661 /uni002D.hw +13662 /uni002E.hw +13663 /uni002F.hw +13664 /uni0030.hw +13665 /uni0031.hw +13666 /uni0032.hw +13667 /uni0033.hw +13668 /uni0034.hw +13669 /uni0035.hw +13670 /uni0036.hw +13671 /uni0037.hw +13672 /uni0038.hw +13673 /uni0039.hw +13674 /uni003A.hw +13675 /uni003B.hw +13676 /uni003C.hw +13677 /uni003D.hw +13678 /uni003E.hw +13679 /uni003F.hw +13680 /uni0040.hw +13681 /uni0041.hw +13682 /uni0042.hw +13683 /uni0043.hw +13684 /uni0044.hw +13685 /uni0045.hw +13686 /uni0046.hw +13687 /uni0047.hw +13688 /uni0048.hw +13689 /uni0049.hw +13690 /uni004A.hw +13691 /uni004B.hw +13692 /uni004C.hw +13693 /uni004D.hw +13694 /uni004E.hw +13695 /uni004F.hw +13696 /uni0050.hw +13697 /uni0051.hw +13698 /uni0052.hw +13699 /uni0053.hw +13700 /uni0054.hw +13701 /uni0055.hw +13702 /uni0056.hw +13703 /uni0057.hw +13704 /uni0058.hw +13705 /uni0059.hw +13706 /uni005A.hw +13707 /uni005B.hw +13708 /uni005C.hw +13709 /uni005D.hw +13710 /uni005E.hw +13711 /uni005F.hw +13712 /uni0060.hw +13713 /uni0061.hw +13714 /uni0062.hw +13715 /uni0063.hw +13716 /uni0064.hw +13717 /uni0065.hw +13718 /uni0066.hw +13719 /uni0067.hw +13720 /uni0068.hw +13721 /uni0069.hw +13722 /uni006A.hw +13723 /uni006B.hw +13724 /uni006C.hw +13725 /uni006D.hw +13726 /uni006E.hw +13727 /uni006F.hw +13728 /uni0070.hw +13729 /uni0071.hw +13730 /uni0072.hw +13731 /uni0073.hw +13732 /uni0074.hw +13733 /uni0075.hw +13734 /uni0076.hw +13735 /uni0077.hw +13736 /uni0078.hw +13737 /uni0079.hw +13738 /uni007A.hw +13739 /uni007B.hw +13740 /uni007C.hw +13741 /uni007D.hw +13743 fe33 +13744 2574 +13745 fe34 +13746 fe4f +13747 00a8 +13748 02c6 +13749..13750 30fd +13751..13752 309d +13754..13756 3005 +13757 30fc +13758 ff3b +13759 ff3d +13760 273d +13761..13843 3041 +13844..13929 30a1 +13930..13935 0410 +13936 0401 +13937..13968 0416 +13969 0451 +13970..13995 0436 +13996 21e7 +13997..13998 21b8 +13999 4e41 +14000 200cc +14001 4e5a +14002 2008a +14003 5202 +14004 4491 +14005 f7eb +14006 5188 +14007 361d +14008 27607 +14049 00ac +14050 ffe4 +14051 ff07 +14052 ff02 +14053 3231 +14054 2116 +14055 2121 +14056 7881 +14057 92b9 +14058 88cf +14059 58bb +14060 6052 +14061 7ca7 +14062 5afa +14063 2554 +14064 2566 +14065 2557 +14066 2560 +14067 256c +14068 2563 +14069 255a +14070 2569 +14071 255d +14072 2552 +14073 2564 +14074 2555 +14078 2558 +14079 2567 +14080 255b +14081 2553 +14082 2565 +14083 2556 +14084 255f +14085 256b +14086 2562 +14087 2559 +14088 2568 +14089 255c +14090 2551 +14096 2593 +14123 23ed7 +14124 57be +14125 26ed3 +14126 713e +14127 257e0 +14128 69a2 +14129 28be9 +14130 5b74 +14131 7a49 +14132 258e1 +14133 294d9 +14134 7a65 +14135 7a7d +14136 259ac +14137 7abb +14138 7ab0 +14139..14140 7ac2 +14141 71d1 +14142 2648d +14143 e326 +14144 7ada +14145 7add +14146 7aea +14147 e32a +14148 54b2 +14149 25c01 +14150 7b0b +14151 7b55 +14152 7b29 +14153 2530e +14154 25cfe +14155 7ba2 +14156 7b6f +14157 839c +14158 25bb4 +14159 26c7f +14160 7bd0 +14161 8421 +14162 7b92 +14164 e33b +14166 8492 +14167 7bfa +14169 7c35 +14170 25cc1 +14171 7c44 +14172 7c83 +14173 24882 +14174 7ca6 +14175 24578 +14176 7cc9 +14177 7cc7 +14178 7ce6 +14180 7cf3 +14181 7cf5 +14182 7e67 +14183 e351 +14184 26e44 +14185 7d5d +14186 26ed6 +14187 7d89 +14188 7dab +14189 7135 +14190 7db3 +14191 7dd6 +14192 24057 +14193 26029 +14194 7de4 +14195 e35e +14196 7df5 +14197 217f9 +14198 7de5 +14199 2836d +14201 26121 +14202 2615a +14203 7e6e +14205 e368 +14206 946c +14207 7e27 +14208..14209 7f40 +14210 7f47 +14211 7936 +14212 262d0 +14213 99e1 +14214 7f97 +14215 26351 +14216 7fa3 +14217 21661 +14218 20068 +14219 e376 +14220 23766 +14221 2833a +14222 7ffa +14223 26489 +14225 8008 +14226 801d +14228 802f +14229 2a087 +14230 26cc3 +14231..14232 803b +14233 8061 +14234 22714 +14235 e387 +14236 26626 +14237 23de3 +14238 266e8 +14239 6725 +14240 80a7 +14241 28a48 +14242 8107 +14243 811a +14244 58b0 +14245 226f6 +14246 6c7f +14247 26498 +14248 64e7 +14249 2148a +14250 8218 +14251 2185e +14252 6a53 +14253 24a65 +14254 24a95 +14255 e39c +14256 8229 +14257 26a52 +14258 23d7e +14259 4ff9 +14260 214fd +14261 84e2 +14262 8362 +14264 249a7 +14265 23530 +14266 21773 +14267 23df8 +14268 82aa +14269 691b +14270 2f994 +14271 e3ad +14272 854b +14273 82d0 +14274 831a +14275 20e16 +14276 217b4 +14277 e3b3 +14278 2317d +14279 2355a +14280 827b +14281 82e2 +14282 8318 +14283 23e8b +14284 26da3 +14285 26b05 +14286 26b97 +14287 235ce +14288 e3be +14289 831d +14290 55ec +14291 8385 +14292 e3c2 +14293 26da5 +14294 83ac +14296 83d3 +14297 26ed4 +14298 6a57 +14299 855a +14300 e3cb +14301 26e42 +14302 8458 +14303 25be4 +14304 8471 +14305..14306 e3d1 +14307 6aa7 +14308 844a +14309 7958 +14311 26b96 +14312 26e77 +14313 26e43 +14314 84de +14316 8391 +14317 e3de +14318 8493 +14319 84e4 +14320 25c91 +14321 e3e2 +14322 25cc0 +14323 e3e4 +14324 8534 +14325 5af2 +14327 e3e8 +14328 8573 +14329 e3ea +14330 67bf +14331 8616 +14332 28625 +14333 2863b +14334 85c1 +14335 27088 +14336 8602 +14337 21582 +14338 270cd +14339 2f9b2 +14340 e3f5 +14341 8628 +14342 e3f7 +14343 218a2 +14344 53f7 +14345 2739a +14346 867e +14348 2a0f8 +14349 87ee +14350 22c27 +14351 87b1 +14352 87da +14353 880f +14354 5661 +14355 866c +14356 6856 +14357 e406 +14358..14359 8845 +14360 275e0 +14361 23db9 +14362 275e4 +14363 885e +14364 889c +14365 e40e +14366..14367 88b4 +14368 88c5 +14369 2770f +14370 8987 +14374 89a7 +14375 89bc +14376 28a25 +14377 89e7 +14378 27924 +14379 27abd +14380 8a9c +14381 7793 +14382 91fe +14383 8a90 +14384 27a59 +14385 7ae9 +14386 27b3a +14387 e427 +14388 27b38 +14389 717c +14390 8b0c +14391 8b1f +14392 25430 +14393 25565 +14394 8b3f +14396 8b4d +14397 8aa9 +14398 24a7a +14399 8b90 +14400 8b9b +14401 8aaf +14402 216df +14403 e437 +14404 884f +14405 8c9b +14406 27d54 +14407 27d8f +14408 2f9d4 +14409 e43d +14410 27d53 +14411 8cd6 +14412 27d98 +14413 27dbd +14414 8d12 +14415 8d03 +14416 21910 +14417 8cdb +14418 705c +14419 8d11 +14420 e449 +14422 8da9 +14423 28002 +14424 21014 +14425 2498a +14426 e44f +14427 281bc +14428 2710c +14429 7ae7 +14430 8ead +14431 8eb6 +14432 8ec3 +14433 92d4 +14434 8f19 +14435 8f2d +14436 28365 +14437 28412 +14438 8fa5 +14439 9303 +14440 2a29f +14441 20a50 +14442 8fb3 +14444 289de +14445 2853d +14446 23dbb +14447 5ef8 +14448 23262 +14449 8ff9 +14451 22325 +14452 e46b +14453 26ed7 +14454 9037 +14455 2853c +14456 27abe +14457 9061 +14458 2856c +14459 2860b +14460 90a8 +14461 28713 +14462 90c4 +14463 286e6 +14464 90ae +14466 9167 +14467 91a9 +14468 91c4 +14469 7cac +14470 28933 +14471 21e89 +14472 920e +14473 6c9f +14474 9241 +14475 9262 +14476 255b9 +14477 28ac6 +14478 23c9b +14479 28b0c +14480 255db +14481 20d31 +14482 932c +14483 936b +14484 28ae1 +14485 28beb +14486 5ac3 +14487 28ae2 +14488 28ae5 +14489 e493 +14490 9244 +14491 28bec +14492 28c39 +14493 28bff +14494 9373 +14495 945b +14496 8ebc +14497 9585 +14498 95a6 +14499 9426 +14500 95a0 +14501 6ff6 +14502 e4a0 +14503 286d8 +14504 2127c +14505 23e2e +14506 e4a5 +14507 6c1c +14508 967b +14509 9696 +14510 e4a9 +14511 96a3 +14512 26ed5 +14513 61da +14514 e4ad +14515 78f5 +14516 28ae0 +14517 96bd +14518 53cc +14519 e4b2 +14520 26cb8 +14521 20274 +14522 26410 +14523 290af +14524 290e5 +14525 24ad1 +14526 21915 +14527 2330a +14528 9731 +14529 8642 +14530 9736 +14531..14533 e4be +14534 24ae9 +14535 7075 +14536 5b41 +14537 971b +14539 291d5 +14540 9757 +14541 5b4a +14542 291eb +14543 975f +14544 9425 +14545 50d0 +14546 230b7 +14547 230bc +14548 9789 +14549 979f +14550 97b1 +14551 97be +14552 97c0 +14553 97d2 +14554 97e0 +14555 2546c +14556 97ee +14557 741c +14558 29433 +14560 97f5 +14561 2941d +14562 2797a +14563 e4de +14564 9834 +14565 9833 +14566 984b +14567 9866 +14568 e4e3 +14569 27175 +14570 e4e5 +14571 20630 +14572 2415c +14573 25706 +14574 98ca +14575 98b7 +14576 98c8 +14577 98c7 +14578 e4ed +14579 26d27 +14580 216d3 +14581 55b0 +14582 98e1 +14583 98e6 +14584 98ec +14585 9378 +14586 9939 +14587 24a29 +14588 e4f7 +14589 29857 +14590 29905 +14591 99f5 +14592 9a0c +14593 9a3b +14594 9a10 +14595 9a58 +14596 25725 +14597 e500 +14598 290b1 +14599 29bd5 +14600 9ae0 +14601 9ae2 +14602 29b05 +14603 9af4 +14604 e507 +14605 9b14 +14606 9b2d +14607 28600 +14608 5034 +14609 9b34 +14610 e50e +14611 2307d +14612 9b50 +14613 9b40 +14614 29d3e +14615 5a45 +14616 21863 +14617 9b8e +14618 9c02 +14619 9bff +14620 9c0c +14621 29e68 +14622 9dd4 +14623 29fb7 +14624 2a192 +14625 2a1ab +14626 2a0e1 +14627 2a123 +14628 2a1df +14629 9d7e +14630 9d83 +14631 2a134 +14632 9e0e +14633 9dc4 +14634 2a193 +14635 2a220 +14636 2193b +14637 2a233 +14638 9d39 +14639 2a0b9 +14640 2a2b4 +14641 9e90 +14642 9e95 +14643 9e9e +14644 9ea2 +14645 e534 +14646 9eaa +14647 9eaf +14648 24364 +14649 9ec1 +14650..14652 e539 +14653 4f32 +14654 e53d +14655 28c2b +14656 9f02 +14657 9f08 +14658 e541 +14659 9424 +14660 26da2 +14661 9f17 +14663 9f39 +14664 569f +14665 568a +14666 9f45 +14667 99b8 +14668 2908b +14669 97f2 +14670 847f +14672 9f69 +14673 7adc +14674 9f8e +14675 7216 +14676 e553 +14677 24975 +14678 249bb +14679 7177 +14680 249f8 +14681 24348 +14682 24a51 +14683 739e +14684 28bda +14685 218fa +14686 799f +14687 2897e +14688 28e36 +14689 9369 +14690 93f3 +14691 28a44 +14692 92ec +14693 9381 +14694 93cb +14695 2896c +14696 244b9 +14697 7217 +14698 e569 +14699 7772 +14700 7a43 +14701 70d0 +14702 24473 +14703 243f8 +14704 717e +14705 217ef +14706 70a3 +14707 218be +14708 23599 +14709 e574 +14710 21885 +14711 2542f +14712 217f8 +14713 e578 +14714 216fb +14715 21839 +14716 e57b +14717 21774 +14718 218d1 +14719 25f4b +14720 e57f +14721 216c0 +14722 575b +14723 24a25 +14724 213fe +14725 212a8 +14726 213c6 +14727 214b6 +14728 8503 +14729 236a6 +14731 8455 +14732 24994 +14733 27165 +14734 23e31 +14735 2555c +14736 23efb +14737 27052 +14738 e591 +14739 236ee +14740 2999d +14741 26f26 +14742 67f9 +14743..14745 e596 +14746 586c +14747 21922 +14748 6810 +14749 e59c +14750 2373f +14751 240e1 +14752 2408b +14753 2410f +14754 26c21 +14755 54cb +14756 569e +14757 266b1 +14758 5692 +14759 20fdf +14760 20ba8 +14761 20e0d +14763 28b13 +14764 939c +14765 4ef8 +14766 512b +14767 e5ae +14768 24436 +14769 4ebc +14770 20465 +14772 4f4b +14773 4f8a +14774 25651 +14775 5a68 +14776 201ab +14777 203cb +14778 e5b9 +14779 2030a +14780 20414 +14781 e5bc +14782 4f29 +14783 202c0 +14784 28eb3 +14785 20275 +14786 8ada +14787 2020c +14788 4e98 +14789 50cd +14790 510d +14791 4fa2 +14792 4f03 +14793 24a0e +14794 23e8a +14795 4f42 +14796 502e +14797 506c +14798 5081 +14799 4fcc +14800 4fe5 +14801 5058 +14802 50fc +14803 6e76 +14804 23595 +14805 23e39 +14806 23ebf +14807 6d72 +14808 21884 +14809 23e89 +14810 51a8 +14811 51c3 +14812 205e0 +14813 e5e0 +14814 204a3 +14815 20492 +14816 20491 +14817 8d7a +14818 28a9c +14819 2070e +14820 5259 +14821 52a4 +14822 20873 +14823 52e1 +14825 e5ec +14826 718c +14827 2438c +14828 20c20 +14829 249ac +14830 210e4 +14831 69d1 +14832 20e1d +14834 e5f5 +14835 7499 +14836 7414 +14837 7456 +14838 7398 +14839 e5fa +14840 24abc +14841 2408d +14842 53d0 +14843 e5fe +14844 720f +14845 240c9 +14846 55b4 +14847 20345 +14848 54cd +14849 20bc6 +14850 571d +14851 925d +14852 96f4 +14853 57dd +14854 578d +14855 577f +14856 e60c +14857 58cb +14858 5a99 +14859 28a46 +14860 216fa +14861 2176f +14862 21710 +14863 5a2c +14864 59b8 +14865 5a7e +14866 5acf +14867 5a12 +14868 25946 +14869 219f3 +14870 21861 +14871 24295 +14872 e61d +14873 6d05 +14874 7443 +14875 5a21 +14876 25e83 +14877 5a81 +14878 28bd7 +14879 20413 +14880 93e0 +14881 748c +14882 21303 +14883 7105 +14884 e629 +14885 9408 +14886 289fb +14887 93bd +14888 e62d +14889 5c1e +14890 5c9e +14891 5e5e +14892 5e48 +14893 21996 +14894 2197c +14895 23aee +14896 5ecd +14897 5b4f +14898..14900 e637 +14901 218a0 +14902 e63b +14903 216fe +14904 e63d +14905 812a +14906 28a47 +14907 21dba +14908 23472 +14909 289a8 +14910 5f0c +14911 5f0e +14912 21927 +14913 217ab +14914 5a6b +14915 2173b +14916 5b44 +14917 275fd +14918 8860 +14919 607e +14920 22860 +14921 2262b +14922 5fdb +14923 e651 +14924 225af +14925 225be +14926 29088 +14927 26f73 +14928 61c0 +14929 2003e +14930 20046 +14931 2261b +14932 6199 +14933 6198 +14934 6075 +14935 22c9b +14936 22d07 +14937 246d4 +14938 2914d +14939 6471 +14940 24665 +14941 22b6a +14942 e664 +14943 22b22 +14944 23450 +14945 298ea +14946 22e78 +14947 6337 +14948 64b6 +14949 6331 +14950 63d1 +14951 249e3 +14952 22d67 +14953 62a4 +14954 22ca1 +14955 643b +14956 656b +14957 6972 +14958 e675 +14959 2308e +14960 232ad +14961 24989 +14962 232ab +14963 550d +14964 232e0 +14965 218d9 +14966 2943f +14967 66ce +14968 23289 +14969 231b3 +14970 e681 +14971 25584 +14972 28b22 +14973 2558f +14974 216fc +14975 2555b +14976 25425 +14977 78ee +14978 23103 +14979 2182a +14980 23234 +14981 e68d +14982 2320f +14983 23182 +14984 242c9 +14985 668e +14986 26d24 +14987 666b +14988 e694 +14989 6630 +14990 27870 +14991 21deb +14992 6663 +14993 232d2 +14994 232e1 +14995 661e +14996 25872 +14997 e69d +14998 2383a +14999 237bc +15000 e6a0 +15001 237a2 +15002 233fe +15003 74d0 +15004 e6a4 +15005 2462a +15006 68b6 +15008 e6a9 +15009 6abe +15010 237d5 +15011 24487 +15012 6a33 +15013 6a52 +15014 6ac9 +15015 6b05 +15016 21912 +15017 6511 +15018 6898 +15019 6a4c +15020 e6b6 +15021 6a7a +15022 6b57 +15023 23fc0 +15024 23c9a +15025 93a0 +15026 92f2 +15027 28bea +15028 28acb +15029 9289 +15030 2801e +15031 289dc +15032 9467 +15033 6da5 +15034 6f0b +15036 23f7f +15037 e6c8 +15038 6e04 +15039 2403c +15040 5a3d +15041 6e0a +15042 5847 +15043 6d24 +15044 7842 +15045 713b +15046 2431a +15047 24276 +15048 70f1 +15049 7250 +15050 7287 +15051 7294 +15052 2478f +15053 24725 +15054 5179 +15055 24aa4 +15056 205eb +15057 747a +15058 23ef8 +15059 2365f +15060 24a4a +15061 24917 +15062 25fe1 +15063..15064 e6e2 +15065 24adf +15066 28c23 +15067 23f35 +15068 60a7 +15069 e6e8 +15070 74cc +15071 743c +15072 9387 +15073 7437 +15074 e6ed +15075 26dea +15076 e6ef +15077 7583 +15078 e6f1 +15079 24cd9 +15080 24d06 +15081 e6f4 +15082 7555 +15083 7673 +15084 2a5c6 +15086 7468 +15087 28acc +15088 249ab +15089 2498e +15090..15091 e6fd +15092 24a4e +15093 e700 +15094 249c5 +15095 248f3 +15096 91fa +15097 5732 +15098 9342 +15099 28ae3 +15100 21864 +15101 50df +15102 25221 +15103 251e7 +15104 7778 +15105 23232 +15106..15107 770e +15108 777b +15109 24697 +15110 23781 +15111 e712 +15112 248f0 +15113 7438 +15114 749b +15115 e716 +15116 24aba +15117 24ac7 +15118 e719 +15119 24a96 +15120 261ae +15121 9307 +15122 25581 +15123 781e +15124 788d +15125 7888 +15126 78d2 +15127 73d0 +15128 7959 +15129 27741 +15130 256e3 +15131 e726 +15134 79a5 +15135 6a2d +15136 23efa +15137 7a3a +15138 79f4 +15139 e72e +15140 216e6 +15141 e730 +15142 9235 +15143 79f1 +15144 20d4c +15145 2498c +15146 20299 +15147 23dba +15148 2176e +15149 e738 +15150 556b +15151..15152 e73a +15153 201d4 +15154 20c0d +15155 7ae2 +15156 5a59 +15157 226f5 +15158 25aaf +15159 25a9c +15160 5a0d +15161 2025b +15162 78f0 +15163 5a2a +15164 25bc6 +15165 7afe +15166 e749 +15167 7c5d +15168 7c6d +15169 e74c +15170 25bb3 +15171 25ebc +15172 25ea6 +15173 7ccd +15174 249f9 +15175 217b0 +15176 7c8e +15177 7c7c +15178 7cae +15179 6ab2 +15180 7ddc +15181 7e07 +15182 7dd3 +15183 7f4e +15184 26261 +15185 2615c +15186 27b48 +15187 7d97 +15188 25e82 +15189 e760 +15190 26b75 +15191 20916 +15192 67d6 +15193 2004e +15194 235cf +15195 57c4 +15196 26412 +15197 263f8 +15198 7fdd +15199 7b27 +15200 2082c +15201 25ae9 +15202 25d43 +15203 7b0c +15204 25e0e +15205 99e6 +15206 8645 +15207 9a63 +15208 6a1c +15209 2343f +15210 249f7 +15211 265ad +15212 9a1f +15213 265a0 +15215 27127 +15216 26cd1 +15217 e77e +15218 8137 +15219 e780 +15220 80c6 +15221 8109 +15222 8142 +15223 267b4 +15224 98c3 +15225 26a42 +15226 8262 +15227 8265 +15228 26a51 +15229 8453 +15230 26da7 +15231 8610 +15232 2721b +15233 5a86 +15234 e78f +15235 21840 +15236 5b2b +15237 218a1 +15238 5ae4 +15239 218d8 +15240 86a0 +15241 2f9bc +15242 23d8f +15243 882d +15244 27422 +15245 5a02 +15246 886e +15247 4f45 +15248 8887 +15249 88bf +15250 88e6 +15251 8965 +15252 894d +15253 25683 +15254 8954 +15255 27785 +15256 27784 +15257 28bf5 +15258 28bd9 +15259 28b9c +15260 289f9 +15261 e7aa +15262 84a3 +15263..15265 e7ac +15266 8a3d +15267 8a1c +15268 29448 +15269 5f4d +15270 922b +15271 24284 +15272 65d4 +15273 7129 +15274 70c4 +15275 21845 +15276 9d6d +15277 8c9f +15278 8ce9 +15279 27ddc +15280 599a +15281 77c3 +15282 59f0 +15283 e7c1 +15284 8e2a +15285 8ea7 +15286 24c09 +15287 8f30 +15288 8f4a +15289 e7c7 +15290 6c58 +15291 6fbb +15292 22321 +15293 e7cb +15294 6f79 +15295 6e8b +15296 217da +15297 9be9 +15298 e7d0 +15299 2492f +15300 90bb +15302 5571 +15303 e7d5 +15304 91bb +15305 9404 +15306 28a4b +15307 e7d9 +15308 28afc +15309 9427 +15310 28c1d +15311 28c3b +15312 84e5 +15313 8a2b +15314 9599 +15315 95a7 +15316 9597 +15317 9596 +15318 28d34 +15319 7445 +15320 e7e6 +15321 248ff +15322 24a42 +15323 243ea +15324 e7ea +15325 23225 +15326 968f +15327 28ee7 +15328 28e66 +15329 28e65 +15330 e7f0 +15331 249ed +15332 24a78 +15333 23fee +15334 7412 +15335 746b +15336 e7f6 +15337 9741 +15338 290b0 +15339 6847 +15340 e7fa +15341 29093 +15342 257df +15344 9368 +15345 28989 +15346 28c26 +15347 28b2f +15348 263be +15349 92ba +15350 5b11 +15351 8b69 +15352 e806 +15353 73f9 +15354 2421b +15355 979b +15357 9938 +15358 20f26 +15359 5dc1 +15360 28bc5 +15361 24ab2 +15362 981f +15363 294da +15364 92f6 +15365 295d7 +15366 91e5 +15367 e815 +15368 28b50 +15369 24a67 +15370 28b64 +15371 98dc +15372 28a45 +15373 e81b +15374 922a +15375 e81d +15376 8414 +15377 993b +15378 994d +15379 27b06 +15380 e822 +15382 e824 +15383 99aa +15384 9a5c +15385 28b65 +15386 258c8 +15387 6a8f +15388 9a21 +15389 5afe +15390 9a2f +15391 298f1 +15392 e82e +15393 29948 +15394 99bc +15395..15396 e831 +15397 937d +15398 5872 +15399 21302 +15400 5822 +15401 249b8 +15402 214e8 +15403 7844 +15404 2271f +15405 23db8 +15406 68c5 +15407 e83d +15408 9458 +15409 e83f +15410 6150 +15411 22781 +15412 2296b +15413 6107 +15414 9c4f +15415 9c53 +15416 9c7b +15417 9c35 +15418 9c10 +15419 9b7f +15420 9bcf +15421 29e2d +15422 9b9f +15423 2a1f5 +15424 2a0fe +15425 9d21 +15426 e850 +15427 24104 +15428 9e18 +15429 e853 +15430 9d0c +15431 2a1b4 +15432 2a0ed +15433 2a0f3 +15434 2992f +15435 9da5 +15436 84bd +15437 26e12 +15438 26fdf +15439 26b82 +15440 85fc +15441 e85f +15442 26da4 +15443 26e84 +15444 26df0 +15445 8420 +15446 85ee +15447 26e00 +15448 237d7 +15449 26064 +15450 79e2 +15451 2359c +15452 23640 +15453 249de +15454 e86d +15455 93db +15456 92be +15457 9348 +15458 202bf +15459 78b9 +15460 9277 +15461 944d +15462 4fe4 +15463 e876 +15464 9064 +15465 2555d +15466 783d +15467 7854 +15468 78b6 +15469 784b +15470 21757 +15471 231c9 +15472 24941 +15473 e880 +15474 4f72 +15475 6fda +15476 6fd9 +15478 701e +15479 5414 +15480 241b5 +15481 57bb +15482 58f3 +15483 578a +15484 9d16 +15485 57d7 +15486 7134 +15487 e88e +15488 241ac +15489 71eb +15490 26c40 +15491 24f97 +15493 217b5 +15494 28a49 +15495 610c +15496 5ace +15497 5a0b +15498 e899 +15499 24488 +15500..15501 e89b +15502 289fc +15503 93bb +15504 93b8 +15505 218d6 +15506 20f1d +15507 8472 +15508 26cc0 +15509 21413 +15510 242fa +15511 22c26 +15512 243c1 +15513 5994 +15514 23db7 +15515 26741 +15516 7da8 +15517 2615b +15518 260a4 +15519 249b9 +15520 2498b +15521 289fa +15522 92e5 +15523 73e2 +15524 e8b3 +15525 74b4 +15526 28b63 +15527 2189f +15528 e8b7 +15529 24ab3 +15530 6ad8 +15531 73f3 +15532 73fb +15533 e8bc +15534 24a3e +15535 24a94 +15536 217d9 +15537 24a66 +15538 203a7 +15539 21424 +15540 249e5 +15541 7448 +15542 24916 +15543 70a5 +15544 24976 +15545 9284 +15546 73e6 +15547 935f +15548 204fe +15549 9331 +15550 28ace +15551 28a16 +15552 9386 +15553 28be7 +15554 255d5 +15555 e8d2 +15556 28a82 +15557 716b +15558 24943 +15559 20cff +15560 56a4 +15561 2061a +15562 20beb +15563 20cb8 +15564 5502 +15565 79c4 +15566 217fa +15567 7dfe +15568 216c2 +15569 24a50 +15570 21852 +15571 e8e2 +15572 9401 +15573 e8e4 +15574 28ac0 +15575 249ad +15576 59b0 +15577 218bf +15578 21883 +15579 27484 +15580 5aa1 +15581 e8ec +15582 23d5b +15583 e8ee +15584 925f +15585 5a79 +15586 28a81 +15587 21862 +15588 9374 +15589 e8f4 +15590 20ab4 +15591..15592 e8f6 +15593 50f4 +15594..15595 e8f9 +15596 2139c +15597 7175 +15598 e8fd +15599 28218 +15600 6e0f +15601 290e4 +15602 e901 +15603 6d57 +15604 27e4f +15605 7067 +15606 6caf +15607 e906 +15608 23fed +15609 23e2d +15610 6e02 +15611 6f0c +15612 e90b +15613 203f5 +15614 7551 +15615..15619 e90e +15620 59c4 +15621 926e +15622 e915 +15623 8f41 +15624 28c1c +15625 26bc0 +15626 5812 +15627 57c8 +15628 e91b +15629 21452 +15630 70fe +15631 24362 +15632 24a71 +15633 22fe3 +15634 212b0 +15635 223bd +15636 68b9 +15637 6967 +15638 21398 +15639 234e5 +15640 27bf4 +15641 236df +15642 28a83 +15643 237d6 +15644 233fa +15645 24c9f +15646 6a1a +15647 236ad +15648 26cb7 +15649 843e +15650..15651 e931 +15652 26d26 +15653 26d51 +15654 26c82 +15655 26fde +15658 833d +15659 2173a +15660 83ed +15661 26c80 +15662 27053 +15663 217db +15664 5989 +15665 5a82 +15666 217b3 +15667 5a61 +15668 5a71 +15669 21905 +15670 241fc +15671 e946 +15672 59ef +15673 2173c +15674 e949 +15675 718e +15676 9390 +15677 669a +15678 242a5 +15679 5a6e +15680 5a2b +15681 24293 +15682 6a2b +15683 23ef9 +15684 27736 +15685 2445b +15686 242ca +15687 711d +15688 24259 +15689 289e1 +15690 4fb0 +15691 26d28 +15692 5cc2 +15693 244ce +15694 27e4d +15695 243bd +15696 6a0c +15697 24256 +15698 21304 +15700 7133 +15701 243e9 +15702 e965 +15703 6cdf +15704 2f825 +15705 59eb +15706 5f5c +15707 e974 +15708 7cd3 +15709 e987 +15710 e98a +15711 27b18 +15712 906c +15713 81f6 +15714 770c +15715 6ca2 +15716 56fd +15717 5869 +15718 6761 +15719 5c5e +15720 58f2 +15721 70b9 +15722 6803 +15723 e9d3 +15724 e9d5 +15725 4e21 +15726 7b39 +15727 e9fe +15728 732a +15729 7560 +15730 583a +15731 82a6 +15732 698a +15733 60e3 +15734 4eee +15735 99c4 +15736 9ebf +15737 5301 +15738 67a0 +15739 60e8 +15740 51b4 +15741 7a83 +15742 9c3a +15743 7ac8 +15744 691a +15745 59ac +15746 5840 +15747 546a +15748 60e7 +15749 567a +15750 6955 +15751 9c2f +15752 87a5 +15753 5c20 +15754 5e0b +15755 671e +15756 84ad +15757 8b81 +15758 4e78 +15759 62c3 +15760 6855 +15762 82fd +15763 89a5 +15764 8fa0 +15765 97b8 +15766 9847 +15767 9abd +15768 5fb1 +15769 6648 +15770 66bf +15771 27a79 +15773 eb41 +15776 eb46 +15777 670e +15778 6918 +15779 27657 +15780 25fe2 +15781 275fe +15782 2209a +15783..15784 eb51 +15785 eb54 +15786 eb57 +15787 24a45 +15788 205ca +15789 51d2 +15790 20611 +15791 599f +15792 21ea8 +15793 eb60 +15794 23cff +15795 eb66 +15796 285e8 +15797 299c9 +15798 eb6a +15799 221c3 +15800 8b5e +15801 28b4e +15803 7209 +15804 eb74 +15805 20779 +15806 8eda +15807 528f +15808 7171 +15809 23f4a +15810 24aa7 +15811 55bc +15812 eb85 +15813 eb87 +15814 eb89 +15815 eb8b +15816 eb8f +15817 5066 +15818 eb92 +15819 233cc +15821 eb96 +15822 28948 +15823 eb9b +15825 27c12 +15826 9056 +15827 24f9a +15828 8b62 +15829 5d5b +15830 26bf7 +15832 2191c +15833 8aea +15834 249f6 +15835 ebaf +15836 ebb1 +15837 2271b +15838 9465 +15839 257e1 +15840 6195 +15841 5a27 +15842 2f8cd +15844 ebbc +15845 4e6a +15846 24934 +15847 9656 +15848 6d8f +15849 26cbd +15850 8977 +15851 ebc7 +15853 7b42 +15854 290c0 +15855 20a11 +15857 7a45 +15858 9a26 +15859 ebd6 +15860 26469 +15861 20021 +15862 7983 +15863 5d2c +15864 23519 +15866 ebe0 +15867 753b +15868 8865 +15869 58b6 +15870 ebe6 +15871 2258d +15872 ebea +15873 9281 +15874 2217a +15875 9330 +15876 249d0 +15877 6c39 +15878 20ef8 +15879 8827 +15880 88f5 +15881 22926 +15882 28473 +15883 217b1 +15884 6eb8 +15885 24a2a +15886 21820 +15887 ebff +15890 ec03 +15891 66b6 +15892 29cad +15893 298a4 +15894 8943 +15895 ec0b +15896 2160a +15897 ec0d +15898 2372f +15899 280e8 +15900 213c5 +15901 71ad +15902 8366 +15903 ec14 +15905 ec16 +15906 270af +15907 289ab +15908 2417a +15909 7b43 +15910 797e +15911 6fb5 +15912 2a2df +15913 6a03 +15914 28318 +15915 53a2 +15916 26e07 +15917 93bf +15918 6836 +15919 975d +15920 2816f +15921 269b5 +15922 213ed +15923 2322f +15924 5d85 +15925 28c30 +15926 5715 +15927 9823 +15928 28949 +15929 5dab +15930 24988 +15931 65be +15932 69d5 +15933 53d2 +15934 24aa5 +15935 23f81 +15936 ec3d +15937 6736 +15938 ec42 +15939 ec4a +15940 ec4d +15942 7808 +15943 9255 +15944 ec53 +15945 ec55 +15946 59f8 +15948 568b +15949 ec68 +15950 9012 +15951 55c1 +15952 ec87 +15953 7e7f +15954 6f56 +15955 6ab1 +15956 ec8c +15957 2789d +15958 ec8f +15960 ec92 +15961 ec95 +15962 ec97 +15963 ec99 +15964 26258 +15965 56bf +15966 8e0e +15967 5b6d +15968 63de +15970 6530 +15971 562d +15972 541a +15973 29d98 +15974 ecb0 +15975 5622 +15976 561e +15977 7f49 +15978 5975 +15979 23d40 +15980 8770 +15981 8117 +15982 9d5e +15983 8d18 +15984 763b +15985 9c45 +15986 764e +15987 77b9 +15988 9345 +15989 5432 +15990 8148 +15991 82f7 +15992 5625 +15993 8132 +15994 8418 +15995 80bd +15996 55ea +15997 7962 +15998 5643 +15999 5416 +16000 20e9d +16001 ecd0 +16002 5605 +16003 55f1 +16004 66f1 +16005 282e2 +16006 ecd5 +16007 7534 +16008 55f0 +16009 55ba +16010 5497 +16011 5572 +16012 20c41 +16013 20c96 +16014 5ed0 +16015 20e76 +16016 22c62 +16017 20ea2 +16018 9eab +16019 7d5a +16021 21075 +16022 629d +16023 976d +16024 5494 +16025 8ccd +16026 71f6 +16027 9176 +16028 63fc +16029 63b9 +16030 63fe +16031 5569 +16032 22b43 +16033 9c72 +16034 22eb3 +16035 519a +16036 ecf4 +16037 20da7 +16038 51a7 +16039 544d +16040 551e +16041 5513 +16042 7666 +16043 8e2d +16044 2688a +16045 75b1 +16046 80b6 +16047 8804 +16049 88c7 +16050 81b6 +16051 841c +16052 ed05 +16053 7304 +16054 830b +16055 567b +16056 9170 +16057 9208 +16058 20ef9 +16059 7266 +16060 ed1b +16061 ed1d +16062 ed1f +16063 9c5d +16064 651f +16065 ed23 +16066 247e0 +16067 29d7c +16069 ed29 +16070 ed2b +16071 26048 +16072 71a3 +16073 7e8e +16074 9d50 +16075 ed33 +16076 6cb2 +16077 5367 +16078 ed38 +16079 ed3b +16080 822d +16081 544b +16082..16083 ed43 +16084 7374 +16085 29eac +16086 ed48 +16087 9bed +16089 ed4c +16090 29fde +16091 845c +16092 ed52 +16093 632e +16094 7d25 +16095 ed59 +16096 9008 +16097 52cc +16098..16100 ed5c +16101 2048e +16102 7640 +16103 5af0 +16104 20eb6 +16105 787a +16106 ed64 +16107 58a7 +16108 ed66 +16109 567c +16110 9b8b +16111 5d74 +16112 7654 +16113 2a434 +16114 9e85 +16115 ed6d +16117 ed6f +16118 6119 +16119 243f2 +16120 ed73 +16121 565d +16122 29e06 +16123 5234 +16124 ed7b +16126 9d7c +16127 7c56 +16128 9b39 +16129 57de +16130 5c53 +16131 64d3 +16132 294d0 +16133 26335 +16134 86ad +16135 20d28 +16136 20d71 +16137 ed8c +16138 51fe +16139 21f0f +16140 5d8e +16141 9703 +16142 21dd1 +16143 9e81 +16144 904c +16145 7b1f +16146 9b02 +16147 5cd1 +16148 7ba3 +16149 6268 +16150 6335 +16151 9aff +16152 7bcf +16153 9b2a +16154 7c7e +16156 7c42 +16157 7c86 +16158 9c15 +16159 7bfc +16160 9b09 +16162 9c2e +16163 9f5a +16164 5573 +16165 5bc3 +16166 4ffd +16167 9e98 +16168 4ff2 +16169 5260 +16170 52d1 +16171 5767 +16172 5056 +16173 59b7 +16174 5e12 +16175 97c8 +16176 9dab +16177 8f5c +16178 5469 +16179 97b4 +16180 9940 +16181 97ba +16182 532c +16183 6130 +16184 692c +16185 53da +16186 9c0a +16187 9d02 +16188 edc1 +16189 9641 +16190 6980 +16191 50a6 +16192 7546 +16193 2176d +16194 99da +16195 5273 +16196 edc9 +16197 9159 +16198 9681 +16199 915c +16200 edcd +16201 9151 +16202 28e97 +16203 637f +16204 6aca +16205 5611 +16206 918e +16207 757a +16208 6285 +16209 734f +16210 7c70 +16211 25c21 +16212 eddc +16213 76d6 +16214 9b9d +16215 4e2a +16216 20cd4 +16217 83be +16218 8842 +16219 ede4 +16220 5c4a +16221 69c0 +16224 521f +16225 5df5 +16226 4ece +16227 6c31 +16228 201f2 +16229 4f39 +16230 549c +16232 529a +16233 8d82 +16234 edf3 +16236..16237 edf5 +16238 6b52 +16239 917c +16240 9fa5 +16241 9b97 +16242 982e +16243 98b4 +16244 9aba +16245 9ea8 +16246 9e84 +16247 7b14 +16248 ee02 +16249 6bfa +16250 8818 +16251 7f78 +16252 ee06 +16253 5620 +16254 2a64a +16255 8e77 +16256 9f53 +16257 ee0b +16258 8dd4 +16259 8e4f +16260 9e1c +16261 8e01 +16262 6282 +16263 2837d +16264 8e28 +16265 8e75 +16266 7ad3 +16267 7a3e +16268 78d8 +16269 6cea +16270 8a67 +16271 7607 +16272 9f26 +16273 6cce +16274 87d6 +16275 75c3 +16276 2a2b2 +16277 7853 +16278 8d0c +16279 72e2 +16280 7371 +16281 8b2d +16282 7302 +16283 74f1 +16284 8ceb +16285 24abb +16286 862f +16287 5fba +16288 88a0 +16289..16290 ee2e +16291 26e05 +16292 ee32 +16293 8a7e +16294 2251b +16295 ee35 +16296 60fd +16297 7667 +16298 9ad7 +16299 9d44 +16300 936e +16301 9b8f +16302 87f5 +16303 ee3d +16305 8cf7 +16306 732c +16307 9721 +16308 9bb0 +16309 ee43 +16310 72b2 +16311 ee45 +16312 7c51 +16313 994a +16314 6159 +16315 ee4a +16316 9e96 +16317 617d +16318 ee4d +16319 575f +16320 616f +16321 62a6 +16322 6239 +16324 ee53 +16325 61e2 +16326 53aa +16327 6364 +16328 6802 +16329 ee59 +16330 5d57 +16331 8fda +16332 28e39 +16333 ee5e +16334 50d9 +16335 7906 +16336 5332 +16337 9638 +16338 20f3b +16339..16340 ee65 +16341 77fe +16342 ee68 +16343 7cc2 +16344 25f1a +16345 7cda +16346 7a2d +16347 8066 +16348 8063 +16349 7d4d +16350 7505 +16351 74f2 +16352 8994 +16353 821a +16354 670c +16355 8062 +16356 27486 +16357 805b +16358 74f0 +16359 8103 +16360 7724 +16361 8989 +16362 267cc +16363 7553 +16364 87a9 +16365 87ce +16366 81c8 +16367 878c +16368 8a49 +16369 8cad +16370 8b43 +16371 772b +16372 74f8 +16373 84da +16374 69b2 +16375 8da6 +16376 ee8c +16377 89a9 +16379 6db9 +16380 87c1 +16381 24011 +16382 74e7 +16383 ee93 +16384 7176 +16385 60a4 +16386 619c +16387 ee97 +16389 6077 +16390 ee9a +16391 7f71 +16393 60e9 +16394 ee9f +16395 20547 +16396 92db +16397 205df +16398 23fc5 +16399 854c +16400 e005 +16401 73ef +16402 51b5 +16403 e008 +16404 24942 +16405 289e4 +16406 9344 +16407 219db +16408 82ee +16409 23cc8 +16410 783c +16411 6744 +16412 62df +16413 24933 +16414 289aa +16415 202a0 +16416 26bb3 +16417 21305 +16418 4fab +16419 224ed +16420 5008 +16421 26d29 +16422 27a84 +16423 23600 +16424 24ab1 +16425 22513 +16427 2037e +16428 5fa4 +16429 20380 +16430 20347 +16431 6edb +16432 2041f +16433 50de +16434 5101 +16435 e028 +16436 510e +16437 986c +16438 e02b +16439 8416 +16440 249a4 +16441 20487 +16442 5160 +16443 233b4 +16444 516a +16445 20bff +16446 220fc +16447 202e5 +16448 22530 +16449 2058e +16450 23233 +16451 21983 +16452 5b82 +16453 877d +16454 205b3 +16455 23c99 +16456 51b2 +16457 51b8 +16458 9d34 +16459 51c9 +16460 51cf +16461 51d1 +16462 e043 +16463 51d3 +16464 24aa6 +16465 51b3 +16468 51ed +16469 83cd +16470 693e +16471 2372d +16472 5f7b +16473 520b +16474 5226 +16475 523c +16476 52b5 +16477 5257 +16478 5294 +16479 52b9 +16480 52c5 +16481 7c15 +16482 8542 +16483 52e0 +16484 860d +16485 26b13 +16487 28ade +16488 5549 +16489 6ed9 +16490 23f80 +16491 20954 +16492 23fec +16493 5333 +16495 20be2 +16496 6ccb +16497 21726 +16498 681b +16499 73d5 +16500 604a +16501..16502 e06a +16503 216e8 +16504 71dd +16505 e06e +16506 536d +16507 5374 +16508 286ab +16509 537e +16511 21596 +16512 21613 +16513 77e6 +16514 5393 +16515 28a9b +16516 53a0 +16517 53ab +16518 53ae +16519 73a7 +16520 25772 +16521 e07e +16522 739c +16523 53c1 +16524 53c5 +16525 6c49 +16526 4e49 +16527 57fe +16528 53d9 +16529 e086 +16530 20b8f +16531 53e0 +16532 23feb +16533 22da3 +16534 53f6 +16535 20c77 +16536 5413 +16537 7079 +16538 552b +16539 6657 +16540 6d5b +16541 546d +16542 26b53 +16543 20d74 +16544 555d +16545 548f +16546 54a4 +16547 e098 +16548 2170d +16549 20edd +16550 e09b +16551 20d4d +16552 289bc +16553 22698 +16554 5547 +16555 e0a0 +16556 542f +16557 7417 +16558 5586 +16559 55a9 +16561 218d7 +16562 2403a +16563 e0a8 +16564 24435 +16565 66b3 +16566 210b4 +16567 5637 +16568 66cd +16569 2328a +16570 66a4 +16572 564d +16573 564f +16574 78f1 +16575 56f1 +16576 9787 +16577 53fe +16578 5700 +16579 56ef +16580 56ed +16581 28b66 +16582 e0bb +16583 2124f +16584 5746 +16585 241a5 +16586 6c6e +16587 708b +16588 5742 +16589 e0c2 +16590 26c7e +16591 57e6 +16592 21416 +16593 5803 +16594 21454 +16595 24363 +16596 5826 +16597 24bf5 +16599 58aa +16600 e0cd +16601 58e0 +16602 58dc +16603 2123c +16604 58fb +16605 5bff +16606 5743 +16607 2a150 +16608 24278 +16609 93d3 +16610 e0d7 +16611 591f +16612 68a6 +16613 e0da +16614 6e59 +16615 2163e +16616 5a24 +16618 21692 +16619 8505 +16620 59c9 +16621 20d4e +16622 26c81 +16623 26d2a +16624 217dc +16625 59d9 +16626 217fb +16627 217b2 +16628 26da6 +16629 6d71 +16630 21828 +16631 216d5 +16632 59f9 +16633 26e45 +16634 5aab +16635 5a63 +16636 e0f1 +16637 249a9 +16639 e0f4 +16640 5a96 +16641 7465 +16642 5ad3 +16643 26fa1 +16644 22554 +16645 21911 +16646 e0fc +16647 216b8 +16648 5e83 +16649 52d0 +16650 5b76 +16651 6588 +16652 5b7c +16653 27a0e +16654..16655 e104 +16656 20204 +16657 5bd5 +16658 21a34 +16659 259cc +16660 205a5 +16661 5bf3 +16662 5b9d +16663 e10e +16664 5c05 +16665 21b44 +16666 5c13 +16667 73ce +16668 5c14 +16669 21ca5 +16670 26b28 +16671 5c49 +16672 e117 +16673 5c85 +16674 5ce9 +16675 5cef +16676 5d8b +16677 21df9 +16678 21e37 +16679 5d10 +16680 5d18 +16681 5d46 +16682 21ea4 +16683 5cba +16684 5dd7 +16685 82fc +16686 e125 +16687 24901 +16688 22049 +16689 22173 +16690 8287 +16691..16692 e12a +16693 5e2e +16694 6a8a +16696 e12f +16697 244bc +16698 20cd3 +16699 53a6 +16700 4eb7 +16702 53a8 +16703 21771 +16704 5e09 +16705 e138 +16706 28482 +16707 5ef9 +16708 5efb +16709 e13c +16710 5efc +16711 683e +16712 941b +16713 5f0d +16714 201c1 +16715 2f894 +16716 e143 +16717 2133a +16718 5f3a +16719 26888 +16720 223d0 +16721 22471 +16722 5f63 +16723 26e6e +16724 5f72 +16725 9340 +16726 28a36 +16727 5fa7 +16728 5db6 +16729 e153 +16730 25250 +16731 21f6a +16732 270f8 +16733 22668 +16734 91d6 +16735 2029e +16736 28a29 +16737 6031 +16738 6685 +16739..16741 e15e +16742 5790 +16743 227b4 +16744 7971 +16745 e164 +16746 609e +16749 24982 +16750 2498f +16751 27a53 +16752 74a4 +16753 50e1 +16754 5aa0 +16755 6164 +16756 6142 +16757 2f8a6 +16758 26ed2 +16759 6181 +16760 51f4 +16761 20656 +16762 6187 +16763 5baa +16764 23fb7 +16765 2285f +16766 61d3 +16767 28b9d +16768 2995d +16769 61d0 +16770 e17e +16771 22980 +16772 228c1 +16773 6023 +16774 615c +16775 651e +16776 638b +16777 20118 +16778 62c5 +16779 21770 +16780 62d5 +16781 22e0d +16782 636c +16783 249df +16784 e18c +16785 6438 +16786 63f8 +16787 2138e +16788 217fc +16789 6f8a +16790 22e36 +16792 2571d +16793 64e1 +16794 64e5 +16795 947b +16796 e19a +16797 643a +16798 e19c +16799 654d +16800 6f16 +16801 24a28 +16802 24a23 +16803 6585 +16804 656d +16805 655f +16807 65b5 +16808 24940 +16809 e1a7 +16810 65d1 +16811 e1a9 +16812 21829 +16813 e1ab +16814 65e3 +16815 5fdf +16816 23400 +16817 6618 +16818..16819 e1b0 +16820 6644 +16821..16822 e1b3 +16823 664b +16824 20e75 +16825 6667 +16826 251e6 +16827 6673 +16829 23231 +16830 285f4 +16831 231c8 +16832 25313 +16833 77c5 +16834 228f7 +16835 99a4 +16836 6702 +16837 2439c +16838 24a21 +16839 69fa +16840 237c2 +16842 6767 +16843 6762 +16844 241cd +16845 290ed +16846 67d7 +16847 e1cf +16848 6822 +16849 6e50 +16850 923c +16851 6801 +16852 233e6 +16853 26da0 +16854 685d +16855 2346f +16856 69e1 +16857 6a0b +16858 28adf +16859 6973 +16860 68c3 +16861 235cd +16862 6901 +16863 6900 +16864 e1e1 +16865 2363c +16866 e1e3 +16867 67ac +16868 6961 +16869 28a4a +16870 e1e7 +16871 6936 +16872 6998 +16873 e1ea +16874 203c9 +16875 8363 +16876 5090 +16877 69f9 +16878 23659 +16879 2212a +16880 6a45 +16881 23703 +16882 6a9d +16883 e1f4 +16884 67b1 +16885 6ac8 +16886 2919c +16887 e1f8 +16888 6b1d +16889 20923 +16890 60de +16891 6b35 +16892 6b74 +16893 227cd +16894 6eb5 +16895 e200 +16897 21958 +16898 e203 +16899 5421 +16900 23b5a +16901 6be1 +16902 23efc +16903 6bdc +16904 6c37 +16905 2248b +16906 248f1 +16907 26b51 +16908 6c5a +16909 8226 +16910 6c79 +16911 23dbc +16912 e211 +16913 23dbd +16914 241a4 +16915 2490c +16916 24900 +16917 23cc9 +16918..16919 e217 +16920 20d32 +16921 9b83 +16922 231f9 +16923 22491 +16924 7f8f +16925 6837 +16926 26d25 +16927 26da1 +16928 26deb +16929 6d96 +16930 6d5c +16931 6e7c +16932 6f04 +16933 2497f +16934 24085 +16935 26e72 +16936 8533 +16937 26f74 +16938 51c7 +16941 842e +16942 28b21 +16944 23e2f +16945 7453 +16946 23f82 +16947 79cc +16948 6e4f +16949 5a91 +16950 2304b +16951 6ff8 +16952 e239 +16953 6f9d +16954 23e30 +16955 6efa +16956 21497 +16957 2403d +16958 e23f +16959 93f0 +16960 6f44 +16961 6f5c +16962 e243 +16963 6f74 +16964 29170 +16965 e246 +16966 6f9f +16967 24144 +16968 6fd3 +16969 24091 +16970 24155 +16971 24039 +16972 23ff0 +16973 23fb4 +16974 2413f +16975 51df +16976..16977 e251 +16978 24140 +16979 261dd +16980 704b +16981 707e +16982 70a7 +16984 70cc +16985..16986 70d5 +16987 70df +16988..16989 e25d +16990 71b4 +16991 7196 +16992 24277 +16993 712b +16994 7145 +16995 5a88 +16996 714a +16998 24365 +16999 714f +17000 9362 +17001 242c1 +17002 712c +17003 2445a +17004 24a27 +17005 24a22 +17006 71ba +17007 28be8 +17008 70bd +17009 720e +17010 9442 +17011 7215 +17012 5911 +17013 9443 +17014 7224 +17015 9341 +17016 25605 +17017 722e +17018 7240 +17019 24974 +17020 68bd +17021 7255 +17022 7257 +17023 e281 +17024 23044 +17025 680d +17026 6f3d +17027 7282 +17029 732b +17030 24823 +17031 2882b +17032 e28a +17033 28804 +17034 7328 +17035 732e +17036 73cf +17037 73aa +17038 20c3a +17039 26a2e +17040 73c9 +17041 7449 +17042 241e2 +17043 216e7 +17044 24a24 +17045 6623 +17046 e298 +17047 249b7 +17048 2498d +17049 249fb +17050 73f7 +17051 7415 +17052 6903 +17053 24a26 +17054 7439 +17055 e2a2 +17057 228ad +17058 7460 +17059 28eb2 +17060 7447 +17061 73e4 +17062 7476 +17063 83b9 +17064 746c +17065 7474 +17066 93f1 +17067 6a2c +17068 7482 +17069 e2b1 +17070 24a8c +17071 2415f +17072 24a79 +17073 28b8f +17074 5b46 +17075 28c03 +17076 2189e +17077 74c8 +17078 21988 +17079 750e +17080 751e +17081 28ed9 +17082 21a4b +17083 5bd7 +17084 28eac +17085 9385 +17086 754d +17087 754a +17088 7567 +17089 756e +17090 24f82 +17091 e2c8 +17092 24d13 +17093 758e +17094 745d +17095 759e +17096 75b4 +17097 7602 +17098 762c +17099 7651 +17100 764f +17101 766f +17102 e2d3 +17103 263f5 +17104 7690 +17105 81ef +17106 e2d7 +17107 26911 +17108 2690e +17109 76a1 +17110 76a5 +17111 76b7 +17112 76cc +17113 26f9f +17114 8462 +17115 2509d +17116 2517d +17117 21e1c +17118 771e +17119 7726 +17120 7740 +17121 64af +17122 25220 +17123 7758 +17124 232ac +17125 77af +17126 28964 +17127 28968 +17128 216c1 +17129 77f4 +17131 68ca +17132 78af +17133 78c7 +17134 78d3 +17135 96a5 +17136 792e +17137 255e0 +17138 78d7 +17139 7934 +17140 78b1 +17141 2760c +17142 8fb8 +17143 8884 +17144 2261c +17145 7986 +17146 8900 +17147 6902 +17148 7980 +17149 25857 +17150 799d +17151 27b39 +17152 793c +17153 79a9 +17154 6e2a +17155 27126 +17156 e30d +17157 79c6 +17158 2910d +17159 79d4 +17161 5525 +17163 20c42 +17164 20d15 +17165 2512b +17166 5590 +17167 22cc6 +17168 39ec +17169 20341 +17170 8e46 +17171 24db8 +17172 294e5 +17174 280be +17175 777a +17176 22c38 +17177 3a34 +17178 47d5 +17179 2815d +17180 269f2 +17181 24dea +17182 64dd +17183 20d7c +17184 20fb4 +17185 20cd5 +17187 648d +17188 8e7e +17189 20e96 +17191 20f64 +17192 22ca9 +17193 28256 +17194 244d3 +17196 20d46 +17197 29a4d +17198 280e9 +17199 47f4 +17200 24ea7 +17201 22cc2 +17202 9ab2 +17203 3a67 +17204 295f4 +17205 3fed +17206 3506 +17207 252c7 +17208 297d4 +17210 22d44 +17211 9d6e +17212 9815 +17214 43d9 +17216 64b4 +17217 54e3 +17219 22bca +17221 39fb +17223 266da +17224 26716 +17225 279a0 +17226 64ea +17227 25052 +17228 20c43 +17229 8e68 +17231 28b4c +17232 20731 +17234 480b +17235 201a9 +17236 3ffa +17237 5873 +17238 22d8d +17240 245c8 +17241 204fc +17242 26097 +17243 20f4c +17245 5579 +17247 43ba +17249 4ab4 +17250 22a66 +17251 2109d +17252 81aa +17253 98f5 +17254 20d9c +17255 6379 +17256 39fe +17257 22775 +17258 8dc0 +17259 56a1 +17260 647c +17261 3e43 +17263 2a601 +17264 20e09 +17265 22acf +17268 210c8 +17269 239c2 +17270 3992 +17271 3a06 +17272 2829b +17273 3578 +17274 25e49 +17275 220c7 +17278 22cb2 +17279 29720 +17280 34bc +17281 6c3d +17282 24e3b +17285 27574 +17286 22e8b +17287 22208 +17288 2a65b +17289 28ccd +17290 20e7a +17291 20c34 +17292 27639 +17293 22bce +17294 22c51 +17295 3a18 +17296 210c7 +17297 2a632 +17298 28cd2 +17299 28d99 +17300 28cca +17301 95aa +17303 2775e +17304 7140 +17306 5156 +17308 5088 +17310 3493 +17311 5186 +17312 5e42 +17313 5205 +17314 5227 +17315 5279 +17317 3553 +17318 53c2 +17319 535f +17321 553f +17323 55d8 +17324 35dd +17325 5621 +17327 5654 +17328 eaf4 +17330 eaf9 +17332 eea7 +17335 eac8 +17336 5cc1 +17337 5d15 +17338 5d56 +17339 3838 +17340 4e81 +17341 5ebd +17342 3914 +17343 61b9 +17344 6290 +17345 6318 +17346 645a +17347 6491 +17348 816d +17349 8184 +17350 8193 +17351 6800 +17352 3bbc +17353 728f +17354 72cd +17356 7339 +17357 7542 +17358 75dc +17359 e9aa +17360 eb76 +17361 e9ac +17363 7680 +17364 768c +17365 e9c5 +17366 7839 +17367 e9cf +17368 7a91 +17369 7c1b +17370 7ced +17371 7f93 +17372 7fae +17374 82ff +17375 585f +17376 86b2 +17378 878b +17379 8947 +17381 8a29 +17383 8e71 +17384 ec44 +17385 8eb0 +17387 915e +17388 918c +17389 990e +17390 991c +17393 9b81 +17394 9dc0 +17395 9d93 +17396 9eac +17397 ec7c +17399 93ba +17400 9e7b +17401 7089 +17402 7348 +17404 7999 +17405 8fb7 +17407 9942 +17408 /CNS1.1.vert +17409 /CNS1.2.vert +17410 /CNS1.3.vert +17411 /CNS1.4.vert +17412 /CNS1.5.vert +17413 /CNS1.6.vert +17414 /CNS1.7.vert +17415 /CNS1.8.vert +17416 /CNS1.9.vert +17417 /CNS1.10.vert +17418 /CNS1.11.vert +17419 /CNS1.12.vert +17420 /CNS1.13.vert +17421 /CNS1.14.vert +17422 /CNS1.15.vert +17423 /CNS1.16.vert +17424 /CNS1.17.vert +17425 /CNS1.18.vert +17426 /CNS1.19.vert +17427 /CNS1.20.vert +17428 /CNS1.21.vert +17429 /CNS1.22.vert +17430 /CNS1.23.vert +17431 /CNS1.24.vert +17432 /CNS1.25.vert +17433 /CNS1.26.vert +17434 /CNS1.27.vert +17435 /CNS1.28.vert +17436 /CNS1.29.vert +17437 /CNS1.30.vert +17438 /CNS1.31.vert +17439 /CNS1.32.vert +17440 /CNS1.33.vert +17441 /CNS1.34.vert +17442 /CNS1.35.vert +17443 /CNS1.36.vert +17444 /CNS1.37.vert +17445 /CNS1.38.vert +17446 /CNS1.39.vert +17447 /CNS1.40.vert +17448 /CNS1.41.vert +17449 /CNS1.42.vert +17450 /CNS1.43.vert +17451 /CNS1.44.vert +17452 /CNS1.45.vert +17453 /CNS1.46.vert +17454 /CNS1.47.vert +17455 /CNS1.48.vert +17456 /CNS1.49.vert +17457 /CNS1.50.vert +17458 /CNS1.51.vert +17459 /CNS1.52.vert +17460 /CNS1.53.vert +17461 /CNS1.54.vert +17462 /CNS1.55.vert +17463 /CNS1.56.vert +17464 /CNS1.57.vert +17465 /CNS1.58.vert +17466 /CNS1.59.vert +17467 /CNS1.60.vert +17468 /CNS1.61.vert +17469 /CNS1.62.vert +17470 /CNS1.63.vert +17471 /CNS1.64.vert +17472 /CNS1.65.vert +17473 /CNS1.66.vert +17474 /CNS1.67.vert +17475 /CNS1.68.vert +17476 /CNS1.69.vert +17477 /CNS1.70.vert +17478 /CNS1.71.vert +17479 /CNS1.72.vert +17480 /CNS1.73.vert +17481 /CNS1.74.vert +17482 /CNS1.75.vert +17483 /CNS1.76.vert +17484 /CNS1.77.vert +17485 /CNS1.78.vert +17486 /CNS1.79.vert +17487 /CNS1.80.vert +17488 /CNS1.81.vert +17489 /CNS1.82.vert +17490 /CNS1.83.vert +17491 /CNS1.84.vert +17492 /CNS1.85.vert +17493 /CNS1.86.vert +17494 /CNS1.87.vert +17495 /CNS1.88.vert +17496 /CNS1.89.vert +17497 /CNS1.90.vert +17498 /CNS1.91.vert +17499 /CNS1.92.vert +17500 /CNS1.93.vert +17501 /CNS1.94.vert +17502 /CNS1.95.vert +17503 /CNS1.96.vert +17504 /CNS1.97.vert +17505 /CNS1.98.vert +17506 /CNS1.13648.vert +17507 /CNS1.13649.vert +17508 /CNS1.13650.vert +17509 /CNS1.13651.vert +17510 /CNS1.13652.vert +17511 /CNS1.13653.vert +17512 /CNS1.13654.vert +17513 /CNS1.13655.vert +17514 /CNS1.13656.vert +17515 /CNS1.13657.vert +17516 /CNS1.13658.vert +17517 /CNS1.13659.vert +17518 /CNS1.13660.vert +17519 /CNS1.13661.vert +17520 /CNS1.13662.vert +17521 /CNS1.13663.vert +17522 /CNS1.13664.vert +17523 /CNS1.13665.vert +17524 /CNS1.13666.vert +17525 /CNS1.13667.vert +17526 /CNS1.13668.vert +17527 /CNS1.13669.vert +17528 /CNS1.13670.vert +17529 /CNS1.13671.vert +17530 /CNS1.13672.vert +17531 /CNS1.13673.vert +17532 /CNS1.13674.vert +17533 /CNS1.13675.vert +17534 /CNS1.13676.vert +17535 /CNS1.13677.vert +17536 /CNS1.13678.vert +17537 /CNS1.13679.vert +17538 /CNS1.13680.vert +17539 /CNS1.13681.vert +17540 /CNS1.13682.vert +17541 /CNS1.13683.vert +17542 /CNS1.13684.vert +17543 /CNS1.13685.vert +17544 /CNS1.13686.vert +17545 /CNS1.13687.vert +17546 /CNS1.13688.vert +17547 /CNS1.13689.vert +17548 /CNS1.13690.vert +17549 /CNS1.13691.vert +17550 /CNS1.13692.vert +17551 /CNS1.13693.vert +17552 /CNS1.13694.vert +17553 /CNS1.13695.vert +17554 /CNS1.13696.vert +17555 /CNS1.13697.vert +17556 /CNS1.13698.vert +17557 /CNS1.13699.vert +17558 /CNS1.13700.vert +17559 /CNS1.13701.vert +17560 /CNS1.13702.vert +17561 /CNS1.13703.vert +17562 /CNS1.13704.vert +17563 /CNS1.13705.vert +17564 /CNS1.13706.vert +17565 /CNS1.13707.vert +17566 /CNS1.13708.vert +17567 /CNS1.13709.vert +17568 /CNS1.13710.vert +17569 /CNS1.13711.vert +17570 /CNS1.13712.vert +17571 /CNS1.13713.vert +17572 /CNS1.13714.vert +17573 /CNS1.13715.vert +17574 /CNS1.13716.vert +17575 /CNS1.13717.vert +17576 /CNS1.13718.vert +17577 /CNS1.13719.vert +17578 /CNS1.13720.vert +17579 /CNS1.13721.vert +17580 /CNS1.13722.vert +17581 /CNS1.13723.vert +17582 /CNS1.13724.vert +17583 /CNS1.13725.vert +17584 /CNS1.13726.vert +17585 /CNS1.13727.vert +17586 /CNS1.13728.vert +17587 /CNS1.13729.vert +17588 /CNS1.13730.vert +17589 /CNS1.13731.vert +17590 /CNS1.13732.vert +17591 /CNS1.13733.vert +17592 /CNS1.13734.vert +17593 /CNS1.13735.vert +17594 /CNS1.13736.vert +17595 /CNS1.13737.vert +17596 /CNS1.13738.vert +17597 /CNS1.13739.vert +17598 /CNS1.13740.vert +17599 /CNS1.13741.vert +17601 20ac +17604 /CNS1.17601.vert +17605 /CNS1.17603.vert +17606..17607 309b +17608 f820 +17609..17613 f303 +17614 2010c +17615 f309 +17616 200d1 +17617 200cd +17618..17619 f30c +17620 200cb +17621 21fe8 +17622 f310 +17623 200ca +17624..17627 f312 +17628 2010e +17629..17630 f317 +17631..17632 f538 +17633 21bc1 +17634 2f878 +17635 9751 +17636 20086 +17637 4e5b +17638 4ebb +17639 353e +17640 5c23 +17641 5f51 +17642 5fc4 +17643 38fa +17644 624c +17645 6535 +17646 6b7a +17647 6c35 +17648 6c3a +17649 706c +17650 722b +17651 4e2c +17652 72ad +17653 248e9 +17654 7f52 +17655 793b +17656 7cf9 +17657 7f53 +17658 2626a +17659 34c1 +17660 2634b +17661 8002 +17662 8080 +17663 26612 +17664 26951 +17665 535d +17666 8864 +17667 89c1 +17668 278b2 +17669 8ba0 +17670 8d1d +17671 9485 +17672 9578 +17673 957f +17674 95e8 +17675 28e0f +17676 97e6 +17677 9875 +17678 98ce +17679 98de +17680 9963 +17681 29810 +17682 9c7c +17683 9e1f +17684 9ec4 +17685 6b6f +17686 f907 +17687 4e37 +17688 20087 +17689 961d +17690 6237 +17691 94a2 +17692..17700 f821 +17701..17708 f82b +17709..17715 f834 +17716 2a3a9 +17717 21145 +17718 650a +17719 4e3d +17720 6edd +17721 9d4e +17722 91df +17723 27735 +17724 4f1a +17725 4f28 +17726 4fa8 +17727 5174 +17728 519c +17729 51e4 +17730 52a1 +17731 52a8 +17732 533b +17733 534e +17734 53d1 +17735 53d8 +17736 56e2 +17737 58f0 +17738 5904 +17739 5907 +17740 5932 +17741 5934 +17742 5b66 +17743..17744 5b9e +17745 5c9a +17746 5e86 +17747 603b +17748 6589 +17749 67fe +17750 6804 +17751 6865 +17752 6d4e +17753 70bc +17754 7535 +17755 7ea4 +17756 7eac +17757 7eba +17758 7ec7 +17759 7ecf +17760 7edf +17761 7f06 +17762 7f37 +17763 827a +17764 82cf +17765 836f +17766 89c6 +17767 8bbe +17768 8be2 +17769..17770 8f66 +17771 8f6e +17772 7411 +17773 7cfc +17774 7dcd +17775 6946 +17776 7ac9 +17777 78b8 +17778 80bc +17779 8d0b +17780 80f6 +17781 209e7 +17782 809f +17783 9ec7 +17784 4ccd +17785 9dc9 +17786 9e0c +17787 4c3e +17788 29df6 +17789 2700e +17790 9e0a +17791 2a133 +17792 35c1 +17793 6e9a +17794 823e +17795 7519 +17796 4911 +17797 9a6c +17798 9a8f +17799 9f99 +17800 7987 +17801 2846c +17802 21dca +17803 205d0 +17804 22ae6 +17805 4e24 +17806 4e80 +17807 4e87 +17808 4ebf +17809 4eeb +17810 4f37 +17811 344c +17812 4fbd +17813 3e48 +17814 5003 +17815 347d +17816 34a5 +17817 5905 +17818 51db +17819 51fc +17820 4e89 +17821 5290 +17822 5327 +17823 35c7 +17824 53a9 +17825 3551 +17826 53b0 +17827 5423 +17828 356d +17829 3572 +17830 3681 +17831 5493 +17832 54a3 +17833 54b4 +17834 54b9 +17835 54d0 +17836 54ef +17837 5518 +17838 5523 +17839 5528 +17840 3598 +17841 35a5 +17842 35bf +17843 55d7 +17844 35c5 +17845 27d84 +17846 4053 +17847 210f4 +17848 20c0b +17849 278c8 +17850 260a5 +17851 22d4c +17852 21077 +17853 2106f +17854 221a1 +17855 20d96 +17856 40bb +17857 22cc9 +17858 5652 +17859 20f31 +17860 2681c +17861 210cf +17862 22803 +17863 22939 +17864 35fb +17865 251e3 +17866 20e8c +17867 20f8d +17868 20eaa +17869 3f93 +17870 20f30 +17871 20d47 +17872 2114f +17873 20e4c +17874 20eab +17875 20ba9 +17876 20d48 +17877 210c0 +17878 2113d +17879 3ff9 +17880 22696 +17881 6432 +17882 20fad +17883 233f4 +17884..17885 20d7e +17886 22c55 +17887 20e98 +17888 20f2e +17889 26b50 +17890 54cc +17891 82c4 +17892 55b9 +17893 29ec3 +17894 9c26 +17895 9ab6 +17896 22dee +17897 80ec +17898 5c1c +17899 26572 +17900 8134 +17901 3797 +17902 280bd +17903 91b6 +17904 20efa +17905 20e0f +17906 20e77 +17907 20efb +17908 24deb +17909 3609 +17910 20cd6 +17911 56af +17912 227b5 +17913 210c9 +17914 20e10 +17915 20e78 +17916 21078 +17917 21148 +17918 28207 +17919 21455 +17920 20e79 +17921 24e50 +17922 22da4 +17923 5a54 +17924..17925 2101d +17926..17927 210f5 +17928 579c +17929 20e11 +17930 27694 +17931 282cd +17932 20fb5 +17933 20e7b +17934 2517e +17935 3703 +17936 20fb6 +17937 21180 +17938 252d8 +17939 2a2bd +17940 249da +17941 2183a +17942 24177 +17943 2827c +17944 5899 +17945 5268 +17946 361a +17947 2573d +17948 7bb2 +17949 5b68 +17950 4800 +17951 4b2c +17952 9f27 +17953 49e7 +17954 9c1f +17955 9b8d +17956 25b74 +17957 2313d +17958 55fb +17959 35f2 +17960 5689 +17961 5d3e +17962 5d48 +17963 3dfc +17964 380f +17965 5da4 +17966 5db9 +17967 3820 +17968 5f25 +17969 5f83 +17970 3908 +17971 393f +17972 394d +17973 60d7 +17974 613d +17975 5ce5 +17976 3989 +17977 61b7 +17978 61cf +17979 39b8 +17980 622c +17981 62e5 +17982 39f8 +17983 56b1 +17984 3a03 +17985 63e2 +17986 63fb +17987 6407 +17988 3a4b +17989 64c0 +17990 9f9f +17991 3a97 +17992 6586 +17993 3abd +17994 65ff +17995 6653 +17996 3af2 +17997 6692 +17998 3b22 +17999 6716 +18000 3b42 +18001 67a4 +18002 3b58 +18003 684a +18004 6884 +18005 3b72 +18006 3b71 +18007 3b7b +18008 6909 +18009 6943 +18010 725c +18011 6964 +18012 699f +18013 6985 +18014 69d6 +18015 3bdd +18016 6a65 +18017 6a74 +18018 6a71 +18019 6a82 +18020 3bec +18021 6a99 +18022 3bf2 +18023 6aab +18024 6ab5 +18025 6ad4 +18026 6af6 +18027 6b81 +18028 6bc1 +18029 6bea +18030 6c75 +18031 6caa +18032 3ccb +18033 6d02 +18034 6d06 +18035 6d26 +18036 6d81 +18037 3cef +18038 6da4 +18039 6db1 +18040 6e15 +18041 6e18 +18042 6e29 +18043 6e86 +18044 289c0 +18045 6ebb +18046 6ee2 +18047 6eda +18048 9f7f +18049..18050 6ee8 +18051 6f24 +18052 6f34 +18053 3d46 +18054 23f41 +18055 6f81 +18056 6fbe +18057 3d6a +18058 3d75 +18059 71b7 +18060 5c99 +18061 3d8a +18062 702c +18063 3d91 +18064 7050 +18065 7054 +18066 706f +18067 707f +18068 20325 +18069 43c1 +18070 35f1 +18071 20ed8 +18072 e316 +18073 e33c +18074 25c65 +18075 667d +18076 7c74 +18077 748d +18078 7e92 +18079 e378 +18080 e394 +18081 e39e +18082 e3a5 +18083 e3c7 +18084 e3cd +18085 e3d5 +18086 e3e7 +18087 8771 +18088 63c1 +18089 7777 +18090 898a +18091 e426 +18092 8b4c +18093 e448 +18094 e460 +18095 2a014 +18096 286bc +18097 28501 +18098 e47a +18099 708f +18100 e4a1 +18101 e50d +18102 e516 +18103 6888 +18104 e528 +18105 9f62 +18106 93c6 +18107 e5b2 +18108 9366 +18109 928f +18110 8614 +18111 e66a +18112 e682 +18113 678f +18114 681e +18115 e6ab +18116 e6c5 +18117 e6f8 +18118 8496 +18119 e769 +18120 e776 +18121 8480 +18122 e7c0 +18123 9771 +18124 999b +18125 e86b +18126 6f17 +18127 27109 +18128 70a6 +18129 24a4f +18130 7e65 +18131 5d2f +18132 e96c +18133 24a5d +18134 217df +18135 7da4 +18136 8426 +18137 5485 +18138 23afa +18139 20214 +18140 577e +18141 208d5 +18142 20619 +18143 e979 +18144 21f9e +18145 2a2b6 +18146 7003 +18147 2915b +18148 5d70 +18149 738f +18150 28a59 +18151 29420 +18152 4fc8 +18153 7fe7 +18154 7310 +18155 7338 +18156 7341 +18157 e98d +18158 71f5 +18159 248f2 +18160 73e1 +18161 e994 +18162 e996 +18163 7419 +18164..18165 741e +18166..18169 e99c +18170 74d3 +18171..18172 e9a1 +18173 756d +18174 7572 +18175 758d +18176 e9a7 +18177 75c8 +18178 764d +18179 7674 +18180 e9ae +18181 767a +18182 7188 +18183 5623 +18184 8980 +18185 e9b5 +18186 7743 +18187 e9b7 +18188..18189 e9b9 +18190 7798 +18191..18192 e9bc +18193 77be +18194 77cb +18195 7818 +18196 781c +18197 7847 +18198 7851 +18199 7866 +18200 8448 +18201 25535 +18202 7933 +18203 7932 +18204 e9d0 +18205 7991 +18206 7a06 +18207 e9d6 +18208 e9d8 +18209 7abc +18210 8279 +18211 e9db +18212 7acf +18213 7adb +18214 e9de +18215 7b62 +18216 7b6c +18217 7b7b +18218 7c12 +18219..18220 e9e5 +18221 7c7b +18222 7c9c +18223 e9e9 +18224 7cb8 +18225 e9eb +18226 8f93 +18227 70c0 +18228 20ccf +18229 7dcf +18230 7dd4 +18231 7dd0 +18232 7dfd +18233 7fb4 +18234 729f +18235 e9f7 +18236 8020 +18237 8025 +18238 802e +18239 8031 +18240 8054 +18241 57b4 +18242 70a0 +18243 80b7 +18244 80e9 +18245 ea03 +18246 810c +18247 810e +18248 8112 +18249 8114 +18250..18251 ea0a +18252 8156 +18253..18254 8159 +18255 ea0f +18256 817c +18257 ea13 +18258 ea15 +18259 81a5 +18260 57ef +18261 81c1 +18262 81e4 +18263 8254 +18264 ea1b +18265 8276 +18266 82ca +18267 82d8 +18268 ea21 +18269 8357 +18270 9669 +18271 8405 +18272 70f5 +18273 8464 +18274 8488 +18275 ea2a +18276 84be +18277 84e1 +18278 84f8 +18279 8510 +18280 8538 +18281 8552 +18282 ea31 +18283..18284 856f +18285 85e0 +18286 ea35 +18287 8672 +18288 8692 +18289 86ef +18290 9645 +18291..18292 ea3c +18293 88ae +18294 88ff +18295 8924 +18296 8991 +18297 27967 +18298 8a38 +18299 8a94 +18300 8ab4 +18301 8c51 +18302 8cd4 +18303 8cf2 +18304 8d1c +18305 ea4c +18306 8dc3 +18307 ea4f +18308 8e3a +18309 5754 +18310 55f5 +18311 ea57 +18312 8ece +18313 8ee2 +18314 8ee4 +18315 8eed +18316 8ef2 +18317 8fc1 +18318 8fca +18319 8fcc +18320 9033 +18321 ea63 +18322 98e0 +18323 9213 +18324 ea66 +18325 9228 +18326 9258 +18327 926b +18328 92b1 +18329 92ae +18330 92bf +18331 92e3 +18332 92eb +18333..18334 92f3 +18335 92fd +18336 9343 +18337 9384 +18338 93ad +18339..18340 ea75 +18341 9417 +18342 941d +18343 942d +18344 943e +18345 ea7d +18346 9454 +18347 9479 +18348 952d +18349 95a2 +18350 ea82 +18351 95f4 +18352 9633 +18353 ea85 +18354 ea87 +18355 9740 +18356 ea89 +18357 97b2 +18358 97c2 +18359 ea8d +18360 98b9 +18361 ea90 +18362 98f1 +18363 5844 +18364 9919 +18365 9937 +18366 995d +18367 9962 +18368 ea9b +18369 99c5 +18370 ea9d +18371 9a3c +18372 9b0f +18373 9b69 +18374 9bdd +18375 9bf1 +18376 9bf4 +18377 eaa6 +18378 9c20 +18379 eaa8 +18380 21bc2 +18381 9d49 +18382 9efe +18383 5650 +18384 9dbd +18385 9dfc +18386 94f6 +18387 8fb6 +18388 9eb1 +18389 9ebd +18390 9ec6 +18391 94dc +18392 9ee2 +18393 9ef1 +18394 9ef8 +18395 9f44 +18396 20094 +18397 202b7 +18398 203a0 +18399 94c3 +18400 eac5 +18401 94c1 +18402 205d5 +18403 20615 +18404 20676 +18405 216ba +18406 5757 +18407 7173 +18408 20ac2 +18409 20acd +18410 20bbf +18411 2f83b +18412 20bcb +18413 549e +18414 20bfb +18415 20c3b +18416 20c53 +18417 20c65 +18418 20c7c +18419 eadc +18420 20cb5 +18421 20cdd +18422 20ced +18423 20d6f +18424 20db2 +18425 20dc8 +18426 20e04 +18427 20e0e +18428 20ed7 +18429 20f90 +18430 20f2d +18431 20e73 +18432 eaee +18433 2105c +18434 2104f +18435 21076 +18436 21088 +18437 21096 +18438 eaf7 +18439 210bf +18440 2112f +18441 2113b +18442 5364 +18443 212e3 +18444 21375 +18445 eb00 +18446 21577 +18447 21619 +18448 217c3 +18449 217c7 +18450 70bb +18451 2182d +18452 2196a +18453 21a2d +18454 21a45 +18455 21c2a +18456 21c70 +18457 21cac +18458 21ec8 +18459 21ed5 +18460 21f15 +18461 7198 +18462 22045 +18463 69e9 +18464 eb17 +18465 2227c +18466 223d7 +18467 223fa +18468 2272a +18469 22871 +18470 2294f +18471 22967 +18472 22993 +18473 22ad5 +18474 eb23 +18475 eb25 +18476 eb27 +18477 eb2a +18478 22c88 +18479 22cb7 +18480 25be8 +18481 22d08 +18482 22d12 +18483 22db7 +18484 22d95 +18485 22e42 +18486 22f74 +18487 22fcc +18488 23033 +18489 23066 +18490 2331f +18491 233de +18492 23567 +18493 235f3 +18494 2361a +18495 23716 +18496 58b5 +18497 eb4a +18498 23e11 +18499 23eb9 +18500 eb53 +18501 242ee +18502 2430d +18503 24334 +18504 24396 +18505 24404 +18506 244d6 +18507 5788 +18508 24674 +18509 eb67 +18510 24812 +18511 248fb +18512 24a15 +18513 eb73 +18514 5965 +18515 eb77 +18516 eb7a +18517 573f +18518 25299 +18519 25419 +18520 25446 +18521 2546e +18522 eb88 +18523 eb8a +18524 25562 +18525 25566 +18526 257c7 +18527 eb90 +18528 eb95 +18529 25aae +18530 25b89 +18531 25c06 +18532 57a1 +18533 7151 +18534 eb9f +18535 eba2 +18536 26402 +18537 2644a +18538 ebaa +18539 ebae +18540 ebb0 +18541 265bf +18542 266b5 +18543 56b9 +18544 ebbd +18545 ebc3 +18546 26799 +18547 2686e +18548 ebc8 +18549 ebca +18550 ebce +18551 ebd0 +18552 ebd3 +18553 ebd5 +18554 26a34 +18555 26b5b +18556 ebdf +18557 ebe1 +18558 ebe4 +18559 2704b +18560 271cd +18561 27280 +18562 27285 +18563 ebef +18564 ebf1 +18565 949f +18566 27450 +18567 ec00 +18568 277cc +18569 27858 +18570 56d6 +18571 ec13 +18572 279fd +18573 27a0a +18574 27b0b +18575 27d66 +18576 ec20 +18577 ec2b +18578 ec2f +18579 ec32 +18580 28090 +18581 280f4 +18582 2812e +18583 ec43 +18584 281af +18585 2821a +18586 28306 +18587 2832f +18588 2838a +18589 28468 +18590 286aa +18591 63e6 +18592 28956 +18593 ec52 +18594 ec54 +18595 ec56 +18596 28b46 +18597 28bd4 +18598 ec5a +18599 28fc5 +18600 290ec +18601 29110 +18602 2913c +18603 ec61 +18604 2915e +18605 24aca +18606 8fd0 +18607 ec67 +18608 295b0 +18609 295b8 +18610 29732 +18611 298d1 +18612 29949 +18613 2996a +18614 299c3 +18615 29a28 +18616 29b0e +18617 29d5a +18618 29d9b +18619 7e9f +18620 29ef8 +18621 29f23 +18622 ec77 +18623 9547 +18624 2a293 +18625 71a2 +18626 2a2ff +18627 2a5cb +18628 ec7f +18629 20c9c +18630 8fbe +18631 8fba +18632 224b0 +18633 8fb9 +18634 24a93 +18635 4eea +18636 ec8d +18637 8e80 +18638 217f5 +18639 28b6c +18640 28b99 +18641 ec96 +18642 ec98 +18643 25635 +18644 25956 +18645 4e9a +18646 25e81 +18647 eca0 +18648 23e88 +18649 24c9e +18650 217f6 +18651 2187b +18652 ecab +18653 25311 +18654 ecae +18655 ecb4 +18656 4e1c +18657 20fea +18658 20d49 +18659 236ba +18660 ecde +18661 55de +18662 8786 +18663 ed04 +18664 24706 +18665 5b90 +18666 ed0a +18667 226f4 +18668 27d2f +18669 241a3 +18670 27d73 +18671 26ed0 +18672 272b6 +18673 ed13 +18674 23cfc +18675 2a6a9 +18676 20eac +18677 ed1a +18678 ed1c +18679 ed1e +18680 ed22 +18681 20fec +18682 20e0a +18683 ed2a +18684 ed2d +18685 4e1a +18686 4e04 +18687 5b0d +18688 ed37 +18689 537d +18690 ed3a +18691 589a +18692 24b6e +18693 57aa +18694 25a95 +18695 20979 +18696 ed45 +18697 23cfe +18698 29f30 +18699 24fa9 +18700 2959e +18701 ed51 +18702 267b3 +18703 23720 +18704 23ef7 +18705 23e2c +18706 ed71 +18707 212a9 +18708 57a7 +18709 24963 +18710 ed7a +18711 ed81 +18712 ed86 +18713 26d22 +18714 24ae2 +18715 9c1b +18716 2493e +18717 edae +18718 edd1 +18719 edd7 +18720 eddb +18721 eddd +18722 577a +18723 54da +18724 717a +18725 ee15 +18726 ee1b +18727 ee22 +18728 ee30 +18729 ee48 +18730 ee56 +18731 ee5b +18732 ee60 +18733 ee7e +18734 ee89 +18735 ee9c +18736 5220 +18737 eea1 +18738 23cc7 +18739 25ed7 +18740 27656 +18741 25531 +18742 21944 +18743 29903 +18744 26ddc +18745 270ad +18746 261ad +18747 28a0f +18748 23677 +18749 200ee +18750 26846 +18751 24f0e +18752 eeb2 +18753 5b1f +18754 2634c +18755 9f50 +18756 9ea6 +18757 2626b +18758 51e2 +18759 5342 +18760 66ad +18761 585c +18762 5553 +18763 e0fa +18764 6160 +18765 e144 +18766 97bd +18767 e15d +18768 60b3 +18769 8424 +18770 9814 +18771 2408c +18772 e1a4 +18773 e1bb +18774 e1c6 +18775 e1e0 +18776 e201 +18777 7081 +18778 5c9c +18779 e2a1 +18780 e2ac +18781 21376 +18782 24a12 +18783..18784 e2ff +18785 0100 +18786 00c1 +18787 01cd +18788 00c0 +18789 0112 +18790 00c9 +18791 011a +18792 00c8 +18793 014c +18794 00d3 +18795 01d1 +18796 00d2 +18797 f325 +18798 1ebe +18799 f327 +18800 1ec0 +18801 00ca +18802 0101 +18803 00e1 +18804 01ce +18805 00e0 +18806 0251 +18807 0113 +18808 00e9 +18809 011b +18810 00e8 +18811 012b +18812 00ed +18813 01d0 +18814 00ec +18815 014d +18816 00f3 +18817 01d2 +18818 00f2 +18819 016b +18820 00fa +18821 01d4 +18822 00f9 +18823 01d6 +18824 01d8 +18825 01da +18826 01dc +18827 00fc +18828 f344 +18829 1ebf +18830 f346 +18831 1ec1 +18832 00ea +18833 0261 +18834 0283 +18835 0250 +18836 025b +18837 0254 +18838 0275 +18839 0153 +18840 00f8 +18841 014b +18842 028a +18843 026a +18844..18845 f34a +18846 f82a +18847 f833 +18848 f83b +18849 503b +18850 6dfe +18851 29c73 +18852 f57a +18853 3dc9 +18854 888f +18855 2414e +18856 7077 +18857 5cf5 +18858 4b20 +18859 251cd +18860 3559 +18861 25d30 +18862 6122 +18863 28a32 +18864 8fa7 +18865 91f6 +18866 7191 +18867 6719 +18868 73ba +18869 23281 +18870 2a107 +18871 3c8b +18872 21980 +18873 4b10 +18874 78e4 +18875 7402 +18876 51ae +18877 2870f +18878 4009 +18879 6a63 +18880 2a2ba +18881 4223 +18882 860f +18883 7a2a +18884 29947 +18885 28aea +18886 9755 +18887 704d +18888 5324 +18889 2207e +18890 93f4 +18891 76d9 +18892 289e3 +18893 f5a4 +18894 77dd +18895 4ea3 +18896 4ff0 +18897 50bc +18898 4e2f +18899 4f17 +18900 f5ab +18901 5434 +18902 7d8b +18903 5892 +18904 58d0 +18905 21db6 +18906 5e92 +18907 5e99 +18908 5fc2 +18909 22712 +18910 658b +18911 233f9 +18912 6919 +18913 6a43 +18914 23c63 +18915 6cff +18916 7200 +18917 24505 +18918 738c +18919 3edb +18920 24a13 +18921 5b15 +18922 74b9 +18923 8b83 +18924 25ca4 +18925 25695 +18926 7a93 +18927 7bec +18928 7cc3 +18929 7e6c +18930 82f8 +18931 8597 +18932 f5cc +18933 8890 +18934 f5ce +18935 8eb9 +18936 f5d0 +18937 8fcf +18938 855f +18939 99e0 +18940 9221 +18941 f5d5 +18942 28db9 +18943 2143f +18944 4071 +18945 42a2 +18946 5a1a +18947 9868 +18948 676b +18949 4276 +18950 573d +18951 85d6 +18952 2497b +18953 82bf +18954 2710d +18955 4c81 +18956 26d74 +18957 5d7b +18958 26b15 +18959 26fbe +18960..18961 f5ec +18962 5b96 +18963 f5ef +18964 7e5b diff --git a/fonts/cid/fontforge/Adobe-GB1-4.cidmap b/fonts/cid/fontforge/Adobe-GB1-4.cidmap new file mode 100644 index 000000000..29089512e --- /dev/null +++ b/fonts/cid/fontforge/Adobe-GB1-4.cidmap @@ -0,0 +1,13779 @@ +29063 29063 +0 /.notdef +1..95 0020 +96..98 3000 +99 30fb +100 02c9 +101 02c7 +102 00a8 +103 3003 +104 3005 +105 2014 +106 ff5e +107 2016 +108 2026 +109..110 2018 +111..112 201c +113..114 3014 +115..122 3008 +123..124 3016 +125..126 3010 +127 00b1 +128 00d7 +129 00f7 +130 2236 +131..132 2227 +133 2211 +134 220f +135 222a +136 2229 +137 2208 +138 2237 +139 221a +140 22a5 +141 2225 +142 2220 +143 2312 +144 2299 +145 222b +146 222e +147 2261 +148 224c +149 2248 +150 223d +151 221d +152 2260 +153..154 226e +155..156 2264 +157 221e +158 2235 +159 2234 +160 2642 +161 2640 +162 00b0 +163..164 2032 +165 2103 +166 ff04 +167 00a4 +168..169 ffe0 +170 2030 +171 00a7 +172 2116 +173 2606 +174 2605 +175 25cb +176 25cf +177 25ce +178 25c7 +179 25c6 +180 25a1 +181 25a0 +182 25b3 +183 25b2 +184 203b +185 2192 +186..187 2190 +188 2193 +189 3013 +190..209 2488 +210..229 2474 +230..239 2460 +240..249 3220 +250..261 2160 +262..264 ff01 +265 ffe5 +266..354 ff05 +355 ffe3 +356..438 3041 +439..524 30a1 +525..541 0391 +542..548 03a3 +549..565 03b1 +566..572 03c3 +573..579 e78d +580..581 fe35 +582..583 fe39 +584..585 fe3f +586..587 fe3d +588..591 fe41 +592..593 e794 +594..595 fe3b +596..597 fe37 +598 fe31 +599 e796 +600..601 fe33 +602..607 0410 +608 0401 +609..640 0416 +641 0451 +642..667 0436 +668 0101 +669 00e1 +670 01ce +671 00e0 +672 0113 +673 00e9 +674 011b +675 00e8 +676 012b +677 00ed +678 01d0 +679 00ec +680 014d +681 00f3 +682 01d2 +683 00f2 +684 016b +685 00fa +686 01d4 +687 00f9 +688 01d6 +689 01d8 +690 01da +691 01dc +692 00fc +693 00ea +694 0251 +695 1e3f +696 0144 +697 0148 +698 01f9 +699 0261 +700..736 3105 +738..813 2500 +940 554a +941 963f +942 57c3 +943 6328 +944 54ce +945 5509 +946 54c0 +947 7691 +948 764c +949 853c +950 77ee +951 827e +952 788d +953 7231 +954 9698 +955 978d +956 6c28 +957 5b89 +958 4ffa +959 6309 +960 6697 +961 5cb8 +962 80fa +963 6848 +964 80ae +965 6602 +966 76ce +967 51f9 +968 6556 +969 71ac +970 7ff1 +971 8884 +972 50b2 +973 5965 +974 61ca +975 6fb3 +976 82ad +977 634c +978 6252 +979 53ed +980 5427 +981 7b06 +982 516b +983 75a4 +984 5df4 +985 62d4 +986 8dcb +987 9776 +988 628a +989 8019 +990 575d +991 9738 +992 7f62 +993 7238 +994 767d +995 67cf +996 767e +997 6446 +998 4f70 +999 8d25 +1000 62dc +1001 7a17 +1002 6591 +1003 73ed +1004 642c +1005 6273 +1006 822c +1007 9881 +1008 677f +1009 7248 +1010 626e +1011 62cc +1012 4f34 +1013 74e3 +1014 534a +1015 529e +1016 7eca +1017 90a6 +1018 5e2e +1019 6886 +1020 699c +1021 8180 +1022 7ed1 +1023 68d2 +1024 78c5 +1025 868c +1026 9551 +1027 508d +1028 8c24 +1029 82de +1030 80de +1031 5305 +1032 8912 +1033 5265 +1034 8584 +1035 96f9 +1036 4fdd +1037 5821 +1038 9971 +1039 5b9d +1040 62b1 +1041 62a5 +1042 66b4 +1043 8c79 +1044 9c8d +1045 7206 +1046 676f +1047 7891 +1048 60b2 +1049 5351 +1050 5317 +1051 8f88 +1052 80cc +1053 8d1d +1054 94a1 +1055 500d +1056 72c8 +1057 5907 +1058 60eb +1059 7119 +1060 88ab +1061 5954 +1062 82ef +1063 672c +1064 7b28 +1065 5d29 +1066 7ef7 +1067 752d +1068 6cf5 +1069 8e66 +1070 8ff8 +1071 903c +1072 9f3b +1073 6bd4 +1074 9119 +1075 7b14 +1076 5f7c +1077 78a7 +1078 84d6 +1079 853d +1080 6bd5 +1081 6bd9 +1082 6bd6 +1083 5e01 +1084 5e87 +1085 75f9 +1086 95ed +1087 655d +1088 5f0a +1089 5fc5 +1090 8f9f +1091 58c1 +1092 81c2 +1093 907f +1094 965b +1095 97ad +1096 8fb9 +1097 7f16 +1098 8d2c +1099 6241 +1100 4fbf +1101 53d8 +1102 535e +1103..1104 8fa8 +1105 8fab +1106 904d +1107 6807 +1108 5f6a +1109 8198 +1110 8868 +1111 9cd6 +1112 618b +1113 522b +1114 762a +1115 5f6c +1116 658c +1117 6fd2 +1118 6ee8 +1119 5bbe +1120 6448 +1121 5175 +1122 51b0 +1123 67c4 +1124 4e19 +1125 79c9 +1126 997c +1127 70b3 +1128 75c5 +1129 5e76 +1130 73bb +1131 83e0 +1132 64ad +1133 62e8 +1134 94b5 +1135 6ce2 +1136 535a +1137 52c3 +1138 640f +1139 94c2 +1140 7b94 +1141 4f2f +1142 5e1b +1143 8236 +1144 8116 +1145 818a +1146 6e24 +1147 6cca +1148 9a73 +1149 6355 +1150 535c +1151 54fa +1152 8865 +1153 57e0 +1154 4e0d +1155 5e03 +1156 6b65 +1157 7c3f +1158 90e8 +1159 6016 +1160 64e6 +1161 731c +1162 88c1 +1163 6750 +1164 624d +1165 8d22 +1166 776c +1167 8e29 +1168 91c7 +1169 5f69 +1170 83dc +1171 8521 +1172 9910 +1173 53c2 +1174 8695 +1175 6b8b +1176 60ed +1177 60e8 +1178 707f +1179 82cd +1180 8231 +1181 4ed3 +1182 6ca7 +1183 85cf +1184 64cd +1185 7cd9 +1186 69fd +1187 66f9 +1188 8349 +1189 5395 +1190 7b56 +1191 4fa7 +1192 518c +1193 6d4b +1194 5c42 +1195 8e6d +1196 63d2 +1197 53c9 +1198 832c +1199 8336 +1200 67e5 +1201 78b4 +1202 643d +1203 5bdf +1204 5c94 +1205 5dee +1206 8be7 +1207 62c6 +1208 67f4 +1209 8c7a +1210 6400 +1211 63ba +1212 8749 +1213 998b +1214 8c17 +1215 7f20 +1216 94f2 +1217 4ea7 +1218 9610 +1219 98a4 +1220 660c +1221 7316 +1222 573a +1223 5c1d +1224 5e38 +1225 957f +1226 507f +1227 80a0 +1228 5382 +1229 655e +1230 7545 +1231 5531 +1232 5021 +1233 8d85 +1234 6284 +1235 949e +1236 671d +1237 5632 +1238 6f6e +1239 5de2 +1240 5435 +1241 7092 +1242 8f66 +1243 626f +1244 64a4 +1245 63a3 +1246 5f7b +1247 6f88 +1248 90f4 +1249 81e3 +1250 8fb0 +1251 5c18 +1252 6668 +1253 5ff1 +1254 6c89 +1255 9648 +1256 8d81 +1257 886c +1258 6491 +1259 79f0 +1260 57ce +1261 6a59 +1262 6210 +1263 5448 +1264 4e58 +1265 7a0b +1266 60e9 +1267 6f84 +1268 8bda +1269 627f +1270 901e +1271 9a8b +1272 79e4 +1273 5403 +1274 75f4 +1275 6301 +1276 5319 +1277 6c60 +1278 8fdf +1279 5f1b +1280 9a70 +1281 803b +1282 9f7f +1283 4f88 +1284 5c3a +1285 8d64 +1286 7fc5 +1287 65a5 +1288 70bd +1289 5145 +1290 51b2 +1291 866b +1292 5d07 +1293 5ba0 +1294 62bd +1295 916c +1296 7574 +1297 8e0c +1298 7a20 +1299 6101 +1300 7b79 +1301 4ec7 +1302 7ef8 +1303 7785 +1304 4e11 +1305 81ed +1306 521d +1307 51fa +1308 6a71 +1309 53a8 +1310 8e87 +1311 9504 +1312 96cf +1313 6ec1 +1314 9664 +1315 695a +1316 7840 +1317 50a8 +1318 77d7 +1319 6410 +1320 89e6 +1321 5904 +1322 63e3 +1323 5ddd +1324 7a7f +1325 693d +1326 4f20 +1327 8239 +1328 5598 +1329 4e32 +1330 75ae +1331 7a97 +1332 5e62 +1333 5e8a +1334 95ef +1335 521b +1336 5439 +1337 708a +1338 6376 +1339 9524 +1340 5782 +1341 6625 +1342 693f +1343 9187 +1344 5507 +1345 6df3 +1346 7eaf +1347 8822 +1348 6233 +1349 7ef0 +1350 75b5 +1351 8328 +1352 78c1 +1353 96cc +1354 8f9e +1355 6148 +1356 74f7 +1357 8bcd +1358 6b64 +1359 523a +1360 8d50 +1361 6b21 +1362 806a +1363 8471 +1364 56f1 +1365 5306 +1366 4ece +1367 4e1b +1368 51d1 +1369 7c97 +1370 918b +1371 7c07 +1372 4fc3 +1373 8e7f +1374 7be1 +1375 7a9c +1376 6467 +1377 5d14 +1378 50ac +1379 8106 +1380 7601 +1381 7cb9 +1382 6dec +1383 7fe0 +1384 6751 +1385 5b58 +1386 5bf8 +1387 78cb +1388 64ae +1389 6413 +1390 63aa +1391 632b +1392 9519 +1393 642d +1394 8fbe +1395 7b54 +1396 7629 +1397 6253 +1398 5927 +1399 5446 +1400 6b79 +1401 50a3 +1402 6234 +1403 5e26 +1404 6b86 +1405 4ee3 +1406 8d37 +1407 888b +1408 5f85 +1409 902e +1410 6020 +1411 803d +1412 62c5 +1413 4e39 +1414 5355 +1415 90f8 +1416 63b8 +1417 80c6 +1418 65e6 +1419 6c2e +1420 4f46 +1421 60ee +1422 6de1 +1423 8bde +1424 5f39 +1425 86cb +1426 5f53 +1427 6321 +1428 515a +1429 8361 +1430 6863 +1431 5200 +1432 6363 +1433 8e48 +1434 5012 +1435 5c9b +1436 7977 +1437 5bfc +1438 5230 +1439 7a3b +1440 60bc +1441 9053 +1442 76d7 +1443 5fb7 +1444 5f97 +1445 7684 +1446 8e6c +1447 706f +1448 767b +1449 7b49 +1450 77aa +1451 51f3 +1452 9093 +1453 5824 +1454 4f4e +1455 6ef4 +1456 8fea +1457 654c +1458 7b1b +1459 72c4 +1460 6da4 +1461 7fdf +1462 5ae1 +1463 62b5 +1464 5e95 +1465 5730 +1466 8482 +1467 7b2c +1468 5e1d +1469 5f1f +1470 9012 +1471 7f14 +1472 98a0 +1473 6382 +1474 6ec7 +1475 7898 +1476 70b9 +1477 5178 +1478 975b +1479 57ab +1480 7535 +1481 4f43 +1482 7538 +1483 5e97 +1484 60e6 +1485 5960 +1486 6dc0 +1487 6bbf +1488 7889 +1489 53fc +1490 96d5 +1491 51cb +1492 5201 +1493 6389 +1494 540a +1495 9493 +1496 8c03 +1497 8dcc +1498 7239 +1499 789f +1500 8776 +1501 8fed +1502 8c0d +1503 53e0 +1504 4e01 +1505 76ef +1506 53ee +1507 9489 +1508 9876 +1509 9f0e +1510 952d +1511 5b9a +1512 8ba2 +1513 4e22 +1514 4e1c +1515 51ac +1516 8463 +1517 61c2 +1518 52a8 +1519 680b +1520 4f97 +1521 606b +1522 51bb +1523 6d1e +1524 515c +1525 6296 +1526 6597 +1527 9661 +1528 8c46 +1529 9017 +1530 75d8 +1531 90fd +1532 7763 +1533 6bd2 +1534 728a +1535 72ec +1536 8bfb +1537 5835 +1538 7779 +1539 8d4c +1540 675c +1541 9540 +1542 809a +1543 5ea6 +1544 6e21 +1545 5992 +1546 7aef +1547 77ed +1548 953b +1549 6bb5 +1550 65ad +1551 7f0e +1552 5806 +1553 5151 +1554 961f +1555 5bf9 +1556 58a9 +1557 5428 +1558 8e72 +1559 6566 +1560 987f +1561 56e4 +1562 949d +1563 76fe +1564 9041 +1565 6387 +1566 54c6 +1567 591a +1568 593a +1569 579b +1570 8eb2 +1571 6735 +1572 8dfa +1573 8235 +1574 5241 +1575 60f0 +1576 5815 +1577 86fe +1578 5ce8 +1579 9e45 +1580 4fc4 +1581 989d +1582 8bb9 +1583 5a25 +1584 6076 +1585 5384 +1586 627c +1587 904f +1588 9102 +1589 997f +1590 6069 +1591 800c +1592 513f +1593 8033 +1594 5c14 +1595 9975 +1596 6d31 +1597 4e8c +1598 8d30 +1599 53d1 +1600 7f5a +1601 7b4f +1602 4f10 +1603 4e4f +1604 9600 +1605 6cd5 +1606 73d0 +1607 85e9 +1608 5e06 +1609 756a +1610 7ffb +1611 6a0a +1612 77fe +1613 9492 +1614 7e41 +1615 51e1 +1616 70e6 +1617 53cd +1618 8fd4 +1619 8303 +1620 8d29 +1621 72af +1622 996d +1623 6cdb +1624 574a +1625 82b3 +1626 65b9 +1627 80aa +1628 623f +1629 9632 +1630 59a8 +1631 4eff +1632 8bbf +1633 7eba +1634 653e +1635 83f2 +1636 975e +1637 5561 +1638 98de +1639 80a5 +1640 532a +1641 8bfd +1642 5420 +1643 80ba +1644 5e9f +1645 6cb8 +1646 8d39 +1647 82ac +1648 915a +1649 5429 +1650 6c1b +1651 5206 +1652 7eb7 +1653 575f +1654 711a +1655 6c7e +1656 7c89 +1657 594b +1658 4efd +1659 5fff +1660 6124 +1661 7caa +1662 4e30 +1663 5c01 +1664 67ab +1665 8702 +1666 5cf0 +1667 950b +1668 98ce +1669 75af +1670 70fd +1671 9022 +1672 51af +1673 7f1d +1674 8bbd +1675 5949 +1676 51e4 +1677 4f5b +1678 5426 +1679 592b +1680 6577 +1681 80a4 +1682 5b75 +1683 6276 +1684 62c2 +1685 8f90 +1686 5e45 +1687 6c1f +1688 7b26 +1689 4f0f +1690 4fd8 +1691 670d +1692 6d6e +1693 6daa +1694 798f +1695 88b1 +1696 5f17 +1697 752b +1698 629a +1699 8f85 +1700 4fef +1701 91dc +1702 65a7 +1703 812f +1704 8151 +1705 5e9c +1706 8150 +1707 8d74 +1708 526f +1709 8986 +1710 8d4b +1711 590d +1712 5085 +1713 4ed8 +1714 961c +1715 7236 +1716 8179 +1717 8d1f +1718 5bcc +1719 8ba3 +1720 9644 +1721 5987 +1722 7f1a +1723 5490 +1724 5676 +1725 560e +1726 8be5 +1727 6539 +1728 6982 +1729 9499 +1730 76d6 +1731 6e89 +1732 5e72 +1733 7518 +1734 6746 +1735 67d1 +1736 7aff +1737 809d +1738 8d76 +1739 611f +1740 79c6 +1741 6562 +1742 8d63 +1743 5188 +1744 521a +1745 94a2 +1746 7f38 +1747 809b +1748 7eb2 +1749 5c97 +1750 6e2f +1751 6760 +1752 7bd9 +1753 768b +1754 9ad8 +1755 818f +1756 7f94 +1757 7cd5 +1758 641e +1759 9550 +1760 7a3f +1761 544a +1762 54e5 +1763 6b4c +1764 6401 +1765 6208 +1766 9e3d +1767 80f3 +1768 7599 +1769 5272 +1770 9769 +1771 845b +1772 683c +1773 86e4 +1774 9601 +1775 9694 +1776 94ec +1777 4e2a +1778 5404 +1779 7ed9 +1780 6839 +1781 8ddf +1782 8015 +1783 66f4 +1784 5e9a +1785 7fb9 +1786 57c2 +1787 803f +1788 6897 +1789 5de5 +1790 653b +1791 529f +1792 606d +1793 9f9a +1794 4f9b +1795 8eac +1796 516c +1797 5bab +1798 5f13 +1799 5de9 +1800 6c5e +1801 62f1 +1802 8d21 +1803 5171 +1804 94a9 +1805 52fe +1806 6c9f +1807 82df +1808 72d7 +1809 57a2 +1810 6784 +1811 8d2d +1812 591f +1813 8f9c +1814 83c7 +1815 5495 +1816 7b8d +1817 4f30 +1818 6cbd +1819 5b64 +1820 59d1 +1821 9f13 +1822 53e4 +1823 86ca +1824 9aa8 +1825 8c37 +1826 80a1 +1827 6545 +1828 987e +1829 56fa +1830 96c7 +1831 522e +1832 74dc +1833 5250 +1834 5be1 +1835 6302 +1836 8902 +1837 4e56 +1838 62d0 +1839 602a +1840 68fa +1841 5173 +1842 5b98 +1843 51a0 +1844 89c2 +1845 7ba1 +1846 9986 +1847 7f50 +1848 60ef +1849 704c +1850 8d2f +1851 5149 +1852 5e7f +1853 901b +1854 7470 +1855 89c4 +1856 572d +1857 7845 +1858 5f52 +1859 9f9f +1860 95fa +1861 8f68 +1862 9b3c +1863 8be1 +1864 7678 +1865 6842 +1866 67dc +1867 8dea +1868 8d35 +1869 523d +1870 8f8a +1871 6eda +1872 68cd +1873 9505 +1874 90ed +1875 56fd +1876 679c +1877 88f9 +1878 8fc7 +1879 54c8 +1880 9ab8 +1881 5b69 +1882 6d77 +1883 6c26 +1884 4ea5 +1885 5bb3 +1886 9a87 +1887 9163 +1888 61a8 +1889 90af +1890 97e9 +1891 542b +1892 6db5 +1893 5bd2 +1894 51fd +1895 558a +1896 7f55 +1897 7ff0 +1898 64bc +1899 634d +1900 65f1 +1901 61be +1902 608d +1903 710a +1904 6c57 +1905 6c49 +1906 592f +1907 676d +1908 822a +1909 58d5 +1910 568e +1911 8c6a +1912 6beb +1913 90dd +1914 597d +1915 8017 +1916 53f7 +1917 6d69 +1918 5475 +1919 559d +1920 8377 +1921 83cf +1922 6838 +1923 79be +1924 548c +1925 4f55 +1926 5408 +1927 76d2 +1928 8c89 +1929 9602 +1930 6cb3 +1931 6db8 +1932 8d6b +1933 8910 +1934 9e64 +1935 8d3a +1936 563f +1937 9ed1 +1938 75d5 +1939 5f88 +1940 72e0 +1941 6068 +1942 54fc +1943 4ea8 +1944 6a2a +1945 8861 +1946 6052 +1947 8f70 +1948 54c4 +1949 70d8 +1950 8679 +1951 9e3f +1952 6d2a +1953 5b8f +1954 5f18 +1955 7ea2 +1956 5589 +1957 4faf +1958 7334 +1959 543c +1960 539a +1961 5019 +1962 540e +1963 547c +1964 4e4e +1965 5ffd +1966 745a +1967 58f6 +1968 846b +1969 80e1 +1970 8774 +1971 72d0 +1972 7cca +1973 6e56 +1974 5f27 +1975 864e +1976 552c +1977 62a4 +1978 4e92 +1979 6caa +1980 6237 +1981 82b1 +1982 54d7 +1983 534e +1984 733e +1985 6ed1 +1986 753b +1987 5212 +1988 5316 +1989 8bdd +1990 69d0 +1991 5f8a +1992 6000 +1993 6dee +1994 574f +1995 6b22 +1996 73af +1997 6853 +1998 8fd8 +1999 7f13 +2000 6362 +2001 60a3 +2002 5524 +2003 75ea +2004 8c62 +2005 7115 +2006 6da3 +2007 5ba6 +2008 5e7b +2009 8352 +2010 614c +2011 9ec4 +2012 78fa +2013 8757 +2014 7c27 +2015 7687 +2016 51f0 +2017 60f6 +2018 714c +2019 6643 +2020 5e4c +2021 604d +2022 8c0e +2023 7070 +2024 6325 +2025 8f89 +2026 5fbd +2027 6062 +2028 86d4 +2029 56de +2030 6bc1 +2031 6094 +2032 6167 +2033 5349 +2034 60e0 +2035 6666 +2036 8d3f +2037 79fd +2038 4f1a +2039 70e9 +2040 6c47 +2041 8bb3 +2042 8bf2 +2043 7ed8 +2044 8364 +2045 660f +2046 5a5a +2047 9b42 +2048 6d51 +2049 6df7 +2050 8c41 +2051 6d3b +2052 4f19 +2053 706b +2054 83b7 +2055 6216 +2056 60d1 +2057 970d +2058 8d27 +2059 7978 +2060 51fb +2061 573e +2062 57fa +2063 673a +2064 7578 +2065 7a3d +2066 79ef +2067 7b95 +2068 808c +2069 9965 +2070 8ff9 +2071 6fc0 +2072 8ba5 +2073 9e21 +2074 59ec +2075 7ee9 +2076 7f09 +2077 5409 +2078 6781 +2079 68d8 +2080 8f91 +2081 7c4d +2082 96c6 +2083 53ca +2084 6025 +2085 75be +2086 6c72 +2087 5373 +2088 5ac9 +2089 7ea7 +2090 6324 +2091 51e0 +2092 810a +2093 5df1 +2094 84df +2095 6280 +2096 5180 +2097 5b63 +2098 4f0e +2099 796d +2100 5242 +2101 60b8 +2102 6d4e +2103 5bc4 +2104 5bc2 +2105 8ba1 +2106 8bb0 +2107 65e2 +2108 5fcc +2109 9645 +2110 5993 +2111 7ee7 +2112 7eaa +2113 5609 +2114 67b7 +2115 5939 +2116 4f73 +2117 5bb6 +2118 52a0 +2119 835a +2120 988a +2121 8d3e +2122 7532 +2123 94be +2124 5047 +2125 7a3c +2126 4ef7 +2127 67b6 +2128 9a7e +2129 5ac1 +2130 6b7c +2131 76d1 +2132 575a +2133 5c16 +2134 7b3a +2135 95f4 +2136 714e +2137 517c +2138 80a9 +2139 8270 +2140 5978 +2141 7f04 +2142 8327 +2143 68c0 +2144 67ec +2145 78b1 +2146 7877 +2147 62e3 +2148 6361 +2149 7b80 +2150 4fed +2151 526a +2152 51cf +2153 8350 +2154 69db +2155 9274 +2156 8df5 +2157 8d31 +2158 89c1 +2159 952e +2160 7bad +2161 4ef6 +2162 5065 +2163 8230 +2164 5251 +2165 996f +2166 6e10 +2167 6e85 +2168 6da7 +2169 5efa +2170 50f5 +2171 59dc +2172 5c06 +2173 6d46 +2174 6c5f +2175 7586 +2176 848b +2177 6868 +2178 5956 +2179 8bb2 +2180 5320 +2181 9171 +2182 964d +2183 8549 +2184 6912 +2185 7901 +2186 7126 +2187 80f6 +2188 4ea4 +2189 90ca +2190 6d47 +2191 9a84 +2192 5a07 +2193 56bc +2194 6405 +2195 94f0 +2196 77eb +2197 4fa5 +2198 811a +2199 72e1 +2200 89d2 +2201 997a +2202 7f34 +2203 7ede +2204 527f +2205 6559 +2206 9175 +2207 8f7f +2208 8f83 +2209 53eb +2210 7a96 +2211 63ed +2212 63a5 +2213 7686 +2214 79f8 +2215 8857 +2216 9636 +2217 622a +2218 52ab +2219 8282 +2220 6854 +2221 6770 +2222 6377 +2223 776b +2224 7aed +2225 6d01 +2226 7ed3 +2227 89e3 +2228 59d0 +2229 6212 +2230 85c9 +2231 82a5 +2232 754c +2233 501f +2234 4ecb +2235 75a5 +2236 8beb +2237 5c4a +2238 5dfe +2239 7b4b +2240 65a4 +2241 91d1 +2242 4eca +2243 6d25 +2244 895f +2245 7d27 +2246 9526 +2247 4ec5 +2248 8c28 +2249 8fdb +2250 9773 +2251 664b +2252 7981 +2253 8fd1 +2254 70ec +2255 6d78 +2256 5c3d +2257 52b2 +2258 8346 +2259 5162 +2260 830e +2261 775b +2262 6676 +2263 9cb8 +2264 4eac +2265 60ca +2266 7cbe +2267 7cb3 +2268 7ecf +2269 4e95 +2270 8b66 +2271 666f +2272 9888 +2273 9759 +2274 5883 +2275 656c +2276 955c +2277 5f84 +2278 75c9 +2279 9756 +2280 7adf +2281 7ade +2282 51c0 +2283 70af +2284 7a98 +2285 63ea +2286 7a76 +2287 7ea0 +2288 7396 +2289 97ed +2290 4e45 +2291 7078 +2292 4e5d +2293 9152 +2294 53a9 +2295 6551 +2296 65e7 +2297 81fc +2298 8205 +2299 548e +2300 5c31 +2301 759a +2302 97a0 +2303 62d8 +2304 72d9 +2305 75bd +2306 5c45 +2307 9a79 +2308 83ca +2309 5c40 +2310 5480 +2311 77e9 +2312 4e3e +2313 6cae +2314 805a +2315 62d2 +2316 636e +2317 5de8 +2318 5177 +2319 8ddd +2320 8e1e +2321 952f +2322 4ff1 +2323 53e5 +2324 60e7 +2325 70ac +2326 5267 +2327 6350 +2328 9e43 +2329 5a1f +2330 5026 +2331 7737 +2332 5377 +2333 7ee2 +2334 6485 +2335 652b +2336 6289 +2337 6398 +2338 5014 +2339 7235 +2340 89c9 +2341 51b3 +2342 8bc0 +2343 7edd +2344 5747 +2345 83cc +2346 94a7 +2347 519b +2348 541b +2349 5cfb +2350 4fca +2351 7ae3 +2352 6d5a +2353 90e1 +2354 9a8f +2355 5580 +2356 5496 +2357 5361 +2358 54af +2359 5f00 +2360 63e9 +2361 6977 +2362 51ef +2363 6168 +2364 520a +2365 582a +2366 52d8 +2367 574e +2368 780d +2369 770b +2370 5eb7 +2371 6177 +2372 7ce0 +2373 625b +2374 6297 +2375 4ea2 +2376 7095 +2377 8003 +2378 62f7 +2379 70e4 +2380 9760 +2381 5777 +2382 82db +2383 67ef +2384 68f5 +2385 78d5 +2386 9897 +2387 79d1 +2388 58f3 +2389 54b3 +2390 53ef +2391 6e34 +2392 514b +2393 523b +2394 5ba2 +2395 8bfe +2396 80af +2397 5543 +2398 57a6 +2399 6073 +2400 5751 +2401 542d +2402 7a7a +2403 6050 +2404 5b54 +2405 63a7 +2406 62a0 +2407 53e3 +2408 6263 +2409 5bc7 +2410 67af +2411 54ed +2412 7a9f +2413 82e6 +2414 9177 +2415 5e93 +2416 88e4 +2417 5938 +2418 57ae +2419 630e +2420 8de8 +2421 80ef +2422 5757 +2423 7b77 +2424 4fa9 +2425 5feb +2426 5bbd +2427 6b3e +2428 5321 +2429 7b50 +2430 72c2 +2431 6846 +2432 77ff +2433 7736 +2434 65f7 +2435 51b5 +2436 4e8f +2437 76d4 +2438 5cbf +2439 7aa5 +2440 8475 +2441 594e +2442 9b41 +2443 5080 +2444 9988 +2445 6127 +2446 6e83 +2447 5764 +2448 6606 +2449 6346 +2450 56f0 +2451 62ec +2452 6269 +2453 5ed3 +2454 9614 +2455 5783 +2456 62c9 +2457 5587 +2458 8721 +2459 814a +2460 8fa3 +2461 5566 +2462 83b1 +2463 6765 +2464 8d56 +2465 84dd +2466 5a6a +2467 680f +2468 62e6 +2469 7bee +2470 9611 +2471 5170 +2472 6f9c +2473 8c30 +2474 63fd +2475 89c8 +2476 61d2 +2477 7f06 +2478 70c2 +2479 6ee5 +2480 7405 +2481 6994 +2482 72fc +2483 5eca +2484 90ce +2485 6717 +2486 6d6a +2487 635e +2488 52b3 +2489 7262 +2490 8001 +2491 4f6c +2492 59e5 +2493 916a +2494 70d9 +2495 6d9d +2496 52d2 +2497 4e50 +2498 96f7 +2499 956d +2500 857e +2501 78ca +2502 7d2f +2503 5121 +2504 5792 +2505 64c2 +2506 808b +2507 7c7b +2508 6cea +2509 68f1 +2510 695e +2511 51b7 +2512 5398 +2513 68a8 +2514 7281 +2515 9ece +2516 7bf1 +2517 72f8 +2518 79bb +2519 6f13 +2520 7406 +2521 674e +2522 91cc +2523 9ca4 +2524 793c +2525 8389 +2526 8354 +2527 540f +2528 6817 +2529 4e3d +2530 5389 +2531 52b1 +2532 783e +2533 5386 +2534 5229 +2535 5088 +2536 4f8b +2537 4fd0 +2538 75e2 +2539 7acb +2540 7c92 +2541 6ca5 +2542 96b6 +2543 529b +2544 7483 +2545 54e9 +2546 4fe9 +2547 8054 +2548 83b2 +2549 8fde +2550 9570 +2551 5ec9 +2552 601c +2553 6d9f +2554 5e18 +2555 655b +2556 8138 +2557 94fe +2558 604b +2559 70bc +2560 7ec3 +2561 7cae +2562 51c9 +2563 6881 +2564 7cb1 +2565 826f +2566 4e24 +2567 8f86 +2568 91cf +2569 667e +2570 4eae +2571 8c05 +2572 64a9 +2573 804a +2574 50da +2575 7597 +2576 71ce +2577 5be5 +2578 8fbd +2579 6f66 +2580 4e86 +2581 6482 +2582 9563 +2583 5ed6 +2584 6599 +2585 5217 +2586 88c2 +2587 70c8 +2588 52a3 +2589 730e +2590 7433 +2591 6797 +2592 78f7 +2593 9716 +2594 4e34 +2595 90bb +2596 9cde +2597 6dcb +2598 51db +2599 8d41 +2600 541d +2601 62ce +2602 73b2 +2603 83f1 +2604 96f6 +2605 9f84 +2606 94c3 +2607 4f36 +2608 7f9a +2609 51cc +2610 7075 +2611 9675 +2612 5cad +2613 9886 +2614 53e6 +2615 4ee4 +2616 6e9c +2617 7409 +2618 69b4 +2619 786b +2620 998f +2621 7559 +2622 5218 +2623 7624 +2624 6d41 +2625 67f3 +2626 516d +2627 9f99 +2628 804b +2629 5499 +2630 7b3c +2631 7abf +2632 9686 +2633 5784 +2634 62e2 +2635 9647 +2636 697c +2637 5a04 +2638 6402 +2639 7bd3 +2640 6f0f +2641 964b +2642 82a6 +2643 5362 +2644 9885 +2645 5e90 +2646 7089 +2647 63b3 +2648 5364 +2649 864f +2650 9c81 +2651 9e93 +2652 788c +2653 9732 +2654 8def +2655 8d42 +2656 9e7f +2657 6f5e +2658 7984 +2659 5f55 +2660 9646 +2661 622e +2662 9a74 +2663 5415 +2664 94dd +2665 4fa3 +2666 65c5 +2667 5c65 +2668 5c61 +2669 7f15 +2670 8651 +2671 6c2f +2672 5f8b +2673 7387 +2674 6ee4 +2675 7eff +2676 5ce6 +2677 631b +2678 5b6a +2679 6ee6 +2680 5375 +2681 4e71 +2682 63a0 +2683 7565 +2684 62a1 +2685 8f6e +2686 4f26 +2687 4ed1 +2688 6ca6 +2689 7eb6 +2690 8bba +2691 841d +2692 87ba +2693 7f57 +2694 903b +2695 9523 +2696 7ba9 +2697 9aa1 +2698 88f8 +2699 843d +2700 6d1b +2701 9a86 +2702 7edc +2703 5988 +2704 9ebb +2705 739b +2706 7801 +2707 8682 +2708 9a6c +2709 9a82 +2710 561b +2711 5417 +2712 57cb +2713 4e70 +2714 9ea6 +2715 5356 +2716 8fc8 +2717 8109 +2718 7792 +2719 9992 +2720 86ee +2721 6ee1 +2722 8513 +2723 66fc +2724 6162 +2725 6f2b +2726 8c29 +2727 8292 +2728 832b +2729 76f2 +2730 6c13 +2731 5fd9 +2732 83bd +2733 732b +2734 8305 +2735 951a +2736 6bdb +2737 77db +2738 94c6 +2739 536f +2740 8302 +2741 5192 +2742 5e3d +2743 8c8c +2744 8d38 +2745 4e48 +2746 73ab +2747 679a +2748 6885 +2749 9176 +2750 9709 +2751 7164 +2752 6ca1 +2753 7709 +2754 5a92 +2755 9541 +2756 6bcf +2757 7f8e +2758 6627 +2759 5bd0 +2760 59b9 +2761 5a9a +2762 95e8 +2763 95f7 +2764 4eec +2765 840c +2766 8499 +2767 6aac +2768 76df +2769 9530 +2770 731b +2771 68a6 +2772 5b5f +2773 772f +2774 919a +2775 9761 +2776 7cdc +2777 8ff7 +2778 8c1c +2779 5f25 +2780 7c73 +2781 79d8 +2782 89c5 +2783 6ccc +2784 871c +2785 5bc6 +2786 5e42 +2787 68c9 +2788 7720 +2789 7ef5 +2790 5195 +2791 514d +2792 52c9 +2793 5a29 +2794 7f05 +2795 9762 +2796 82d7 +2797 63cf +2798 7784 +2799 85d0 +2800 79d2 +2801 6e3a +2802 5e99 +2803 5999 +2804 8511 +2805 706d +2806 6c11 +2807 62bf +2808 76bf +2809 654f +2810 60af +2811 95fd +2812 660e +2813 879f +2814 9e23 +2815 94ed +2816 540d +2817 547d +2818 8c2c +2819..2820 6478 +2821 8611 +2822 6a21 +2823 819c +2824 78e8 +2825 6469 +2826 9b54 +2827 62b9 +2828 672b +2829 83ab +2830 58a8 +2831 9ed8 +2832 6cab +2833 6f20 +2834 5bde +2835 964c +2836 8c0b +2837 725f +2838 67d0 +2839 62c7 +2840 7261 +2841 4ea9 +2842 59c6 +2843 6bcd +2844 5893 +2845 66ae +2846 5e55 +2847 52df +2848 6155 +2849 6728 +2850 76ee +2851 7766 +2852 7267 +2853 7a46 +2854 62ff +2855 54ea +2856 5450 +2857 94a0 +2858 90a3 +2859 5a1c +2860 7eb3 +2861 6c16 +2862 4e43 +2863 5976 +2864 8010 +2865 5948 +2866 5357 +2867 7537 +2868 96be +2869 56ca +2870 6320 +2871 8111 +2872 607c +2873 95f9 +2874 6dd6 +2875 5462 +2876 9981 +2877 5185 +2878 5ae9 +2879 80fd +2880 59ae +2881 9713 +2882 502a +2883 6ce5 +2884 5c3c +2885 62df +2886 4f60 +2887 533f +2888 817b +2889 9006 +2890 6eba +2891 852b +2892 62c8 +2893 5e74 +2894 78be +2895 64b5 +2896 637b +2897 5ff5 +2898 5a18 +2899 917f +2900 9e1f +2901 5c3f +2902 634f +2903 8042 +2904 5b7d +2905 556e +2906 954a +2907 954d +2908 6d85 +2909 60a8 +2910 67e0 +2911 72de +2912 51dd +2913 5b81 +2914 62e7 +2915 6cde +2916 725b +2917 626d +2918 94ae +2919 7ebd +2920 8113 +2921 6d53 +2922 519c +2923 5f04 +2924 5974 +2925 52aa +2926 6012 +2927 5973 +2928 6696 +2929 8650 +2930 759f +2931 632a +2932 61e6 +2933 7cef +2934 8bfa +2935 54e6 +2936 6b27 +2937 9e25 +2938 6bb4 +2939 85d5 +2940 5455 +2941 5076 +2942 6ca4 +2943 556a +2944 8db4 +2945 722c +2946 5e15 +2947 6015 +2948 7436 +2949 62cd +2950 6392 +2951 724c +2952 5f98 +2953 6e43 +2954 6d3e +2955 6500 +2956 6f58 +2957 76d8 +2958 78d0 +2959 76fc +2960 7554 +2961 5224 +2962 53db +2963 4e53 +2964 5e9e +2965 65c1 +2966 802a +2967 80d6 +2968 629b +2969 5486 +2970 5228 +2971 70ae +2972 888d +2973 8dd1 +2974 6ce1 +2975 5478 +2976 80da +2977 57f9 +2978 88f4 +2979 8d54 +2980 966a +2981 914d +2982 4f69 +2983 6c9b +2984 55b7 +2985 76c6 +2986 7830 +2987 62a8 +2988 70f9 +2989 6f8e +2990 5f6d +2991 84ec +2992 68da +2993 787c +2994 7bf7 +2995 81a8 +2996 670b +2997 9e4f +2998 6367 +2999 78b0 +3000 576f +3001 7812 +3002 9739 +3003 6279 +3004 62ab +3005 5288 +3006 7435 +3007 6bd7 +3008 5564 +3009 813e +3010 75b2 +3011 76ae +3012 5339 +3013 75de +3014 50fb +3015 5c41 +3016 8b6c +3017 7bc7 +3018 504f +3019 7247 +3020 9a97 +3021 98d8 +3022 6f02 +3023 74e2 +3024 7968 +3025 6487 +3026 77a5 +3027 62fc +3028 9891 +3029 8d2b +3030 54c1 +3031 8058 +3032 4e52 +3033 576a +3034 82f9 +3035 840d +3036 5e73 +3037 51ed +3038 74f6 +3039 8bc4 +3040 5c4f +3041 5761 +3042 6cfc +3043 9887 +3044 5a46 +3045 7834 +3046 9b44 +3047 8feb +3048 7c95 +3049 5256 +3050 6251 +3051 94fa +3052 4ec6 +3053 8386 +3054 8461 +3055 83e9 +3056 84b2 +3057 57d4 +3058 6734 +3059 5703 +3060 666e +3061 6d66 +3062 8c31 +3063 66dd +3064 7011 +3065 671f +3066 6b3a +3067 6816 +3068 621a +3069 59bb +3070 4e03 +3071 51c4 +3072 6f06 +3073 67d2 +3074 6c8f +3075 5176 +3076 68cb +3077 5947 +3078 6b67 +3079 7566 +3080 5d0e +3081 8110 +3082 9f50 +3083 65d7 +3084 7948 +3085 7941 +3086 9a91 +3087 8d77 +3088 5c82 +3089 4e5e +3090 4f01 +3091 542f +3092 5951 +3093 780c +3094 5668 +3095 6c14 +3096 8fc4 +3097 5f03 +3098 6c7d +3099 6ce3 +3100 8bab +3101 6390 +3102 6070 +3103 6d3d +3104 7275 +3105 6266 +3106 948e +3107 94c5 +3108 5343 +3109 8fc1 +3110 7b7e +3111 4edf +3112 8c26 +3113 4e7e +3114 9ed4 +3115 94b1 +3116 94b3 +3117 524d +3118 6f5c +3119 9063 +3120 6d45 +3121 8c34 +3122 5811 +3123 5d4c +3124 6b20 +3125 6b49 +3126 67aa +3127 545b +3128 8154 +3129 7f8c +3130 5899 +3131 8537 +3132 5f3a +3133 62a2 +3134 6a47 +3135 9539 +3136 6572 +3137 6084 +3138 6865 +3139 77a7 +3140 4e54 +3141 4fa8 +3142 5de7 +3143 9798 +3144 64ac +3145 7fd8 +3146 5ced +3147 4fcf +3148 7a8d +3149 5207 +3150 8304 +3151 4e14 +3152 602f +3153 7a83 +3154 94a6 +3155 4fb5 +3156 4eb2 +3157 79e6 +3158 7434 +3159 52e4 +3160 82b9 +3161 64d2 +3162 79bd +3163 5bdd +3164 6c81 +3165 9752 +3166 8f7b +3167 6c22 +3168 503e +3169 537f +3170 6e05 +3171 64ce +3172 6674 +3173 6c30 +3174 60c5 +3175 9877 +3176 8bf7 +3177 5e86 +3178 743c +3179 7a77 +3180 79cb +3181 4e18 +3182 90b1 +3183 7403 +3184 6c42 +3185 56da +3186 914b +3187 6cc5 +3188 8d8b +3189 533a +3190 86c6 +3191 66f2 +3192 8eaf +3193 5c48 +3194 9a71 +3195 6e20 +3196 53d6 +3197 5a36 +3198 9f8b +3199 8da3 +3200 53bb +3201 5708 +3202 98a7 +3203 6743 +3204 919b +3205 6cc9 +3206 5168 +3207 75ca +3208 62f3 +3209 72ac +3210 5238 +3211 529d +3212 7f3a +3213 7094 +3214 7638 +3215 5374 +3216 9e4a +3217 69b7 +3218 786e +3219 96c0 +3220 88d9 +3221 7fa4 +3222 7136 +3223 71c3 +3224 5189 +3225 67d3 +3226 74e4 +3227 58e4 +3228 6518 +3229 56b7 +3230 8ba9 +3231 9976 +3232 6270 +3233 7ed5 +3234 60f9 +3235 70ed +3236 58ec +3237 4ec1 +3238 4eba +3239 5fcd +3240 97e7 +3241 4efb +3242 8ba4 +3243 5203 +3244 598a +3245 7eab +3246 6254 +3247 4ecd +3248 65e5 +3249 620e +3250 8338 +3251 84c9 +3252 8363 +3253 878d +3254 7194 +3255 6eb6 +3256 5bb9 +3257 7ed2 +3258 5197 +3259 63c9 +3260 67d4 +3261 8089 +3262 8339 +3263 8815 +3264 5112 +3265 5b7a +3266 5982 +3267 8fb1 +3268 4e73 +3269 6c5d +3270 5165 +3271 8925 +3272 8f6f +3273 962e +3274 854a +3275 745e +3276 9510 +3277 95f0 +3278 6da6 +3279 82e5 +3280 5f31 +3281 6492 +3282 6d12 +3283 8428 +3284 816e +3285 9cc3 +3286 585e +3287 8d5b +3288 4e09 +3289 53c1 +3290 4f1e +3291 6563 +3292 6851 +3293 55d3 +3294 4e27 +3295 6414 +3296 9a9a +3297 626b +3298 5ac2 +3299 745f +3300 8272 +3301 6da9 +3302 68ee +3303 50e7 +3304 838e +3305 7802 +3306 6740 +3307 5239 +3308 6c99 +3309 7eb1 +3310 50bb +3311 5565 +3312 715e +3313 7b5b +3314 6652 +3315 73ca +3316 82eb +3317 6749 +3318 5c71 +3319 5220 +3320 717d +3321 886b +3322 95ea +3323 9655 +3324 64c5 +3325 8d61 +3326 81b3 +3327 5584 +3328 6c55 +3329 6247 +3330 7f2e +3331 5892 +3332 4f24 +3333 5546 +3334 8d4f +3335 664c +3336 4e0a +3337 5c1a +3338 88f3 +3339 68a2 +3340 634e +3341 7a0d +3342 70e7 +3343 828d +3344 52fa +3345 97f6 +3346 5c11 +3347 54e8 +3348 90b5 +3349 7ecd +3350 5962 +3351 8d4a +3352 86c7 +3353..3354 820c +3355 8d66 +3356 6444 +3357 5c04 +3358 6151 +3359 6d89 +3360 793e +3361 8bbe +3362 7837 +3363 7533 +3364 547b +3365 4f38 +3366 8eab +3367 6df1 +3368 5a20 +3369 7ec5 +3370 795e +3371 6c88 +3372 5ba1 +3373 5a76 +3374 751a +3375 80be +3376 614e +3377 6e17 +3378 58f0 +3379 751f +3380 7525 +3381 7272 +3382 5347 +3383 7ef3 +3384 7701 +3385 76db +3386 5269 +3387 80dc +3388 5723 +3389 5e08 +3390 5931 +3391 72ee +3392 65bd +3393 6e7f +3394 8bd7 +3395 5c38 +3396 8671 +3397 5341 +3398 77f3 +3399 62fe +3400 65f6 +3401 4ec0 +3402 98df +3403 8680 +3404 5b9e +3405 8bc6 +3406 53f2 +3407 77e2 +3408 4f7f +3409 5c4e +3410 9a76 +3411 59cb +3412 5f0f +3413 793a +3414 58eb +3415 4e16 +3416 67ff +3417 4e8b +3418 62ed +3419 8a93 +3420 901d +3421 52bf +3422 662f +3423 55dc +3424 566c +3425 9002 +3426 4ed5 +3427 4f8d +3428 91ca +3429 9970 +3430 6c0f +3431 5e02 +3432 6043 +3433 5ba4 +3434 89c6 +3435 8bd5 +3436 6536 +3437 624b +3438 9996 +3439 5b88 +3440 5bff +3441 6388 +3442 552e +3443 53d7 +3444 7626 +3445 517d +3446 852c +3447 67a2 +3448 68b3 +3449 6b8a +3450 6292 +3451 8f93 +3452 53d4 +3453 8212 +3454 6dd1 +3455 758f +3456 4e66 +3457 8d4e +3458 5b70 +3459 719f +3460 85af +3461 6691 +3462 66d9 +3463 7f72 +3464 8700 +3465 9ecd +3466 9f20 +3467 5c5e +3468 672f +3469 8ff0 +3470 6811 +3471 675f +3472 620d +3473 7ad6 +3474 5885 +3475 5eb6 +3476 6570 +3477 6f31 +3478 6055 +3479 5237 +3480 800d +3481 6454 +3482 8870 +3483 7529 +3484 5e05 +3485 6813 +3486 62f4 +3487 971c +3488 53cc +3489 723d +3490 8c01 +3491 6c34 +3492 7761 +3493 7a0e +3494 542e +3495 77ac +3496 987a +3497 821c +3498 8bf4 +3499 7855 +3500 6714 +3501 70c1 +3502 65af +3503 6495 +3504 5636 +3505 601d +3506 79c1 +3507 53f8 +3508 4e1d +3509 6b7b +3510 8086 +3511 5bfa +3512 55e3 +3513 56db +3514 4f3a +3515 4f3c +3516 9972 +3517 5df3 +3518 677e +3519 8038 +3520 6002 +3521 9882 +3522 9001 +3523 5b8b +3524 8bbc +3525 8bf5 +3526 641c +3527 8258 +3528 64de +3529 55fd +3530 82cf +3531 9165 +3532 4fd7 +3533 7d20 +3534 901f +3535 7c9f +3536 50f3 +3537 5851 +3538 6eaf +3539 5bbf +3540 8bc9 +3541 8083 +3542 9178 +3543 849c +3544 7b97 +3545 867d +3546 968b +3547 968f +3548 7ee5 +3549 9ad3 +3550 788e +3551 5c81 +3552 7a57 +3553 9042 +3554 96a7 +3555 795f +3556 5b59 +3557 635f +3558 7b0b +3559 84d1 +3560 68ad +3561 5506 +3562 7f29 +3563 7410 +3564 7d22 +3565 9501 +3566 6240 +3567 584c +3568 4ed6 +3569 5b83 +3570 5979 +3571 5854 +3572 736d +3573 631e +3574 8e4b +3575 8e0f +3576 80ce +3577 82d4 +3578 62ac +3579 53f0 +3580 6cf0 +3581 915e +3582 592a +3583 6001 +3584 6c70 +3585 574d +3586 644a +3587 8d2a +3588 762b +3589 6ee9 +3590 575b +3591 6a80 +3592 75f0 +3593 6f6d +3594 8c2d +3595 8c08 +3596 5766 +3597 6bef +3598 8892 +3599 78b3 +3600 63a2 +3601 53f9 +3602 70ad +3603 6c64 +3604 5858 +3605 642a +3606 5802 +3607 68e0 +3608 819b +3609 5510 +3610 7cd6 +3611 5018 +3612 8eba +3613 6dcc +3614 8d9f +3615 70eb +3616 638f +3617 6d9b +3618 6ed4 +3619 7ee6 +3620 8404 +3621 6843 +3622 9003 +3623 6dd8 +3624 9676 +3625 8ba8 +3626 5957 +3627 7279 +3628 85e4 +3629 817e +3630 75bc +3631 8a8a +3632 68af +3633 5254 +3634 8e22 +3635 9511 +3636 63d0 +3637 9898 +3638 8e44 +3639 557c +3640 4f53 +3641 66ff +3642 568f +3643 60d5 +3644 6d95 +3645 5243 +3646 5c49 +3647 5929 +3648 6dfb +3649 586b +3650 7530 +3651 751c +3652 606c +3653 8214 +3654 8146 +3655 6311 +3656 6761 +3657 8fe2 +3658 773a +3659 8df3 +3660 8d34 +3661 94c1 +3662 5e16 +3663 5385 +3664 542c +3665 70c3 +3666 6c40 +3667 5ef7 +3668 505c +3669 4ead +3670 5ead +3671 633a +3672 8247 +3673 901a +3674 6850 +3675 916e +3676 77b3 +3677 540c +3678 94dc +3679 5f64 +3680 7ae5 +3681 6876 +3682 6345 +3683 7b52 +3684 7edf +3685 75db +3686 5077 +3687 6295 +3688 5934 +3689 900f +3690 51f8 +3691 79c3 +3692 7a81 +3693 56fe +3694 5f92 +3695 9014 +3696 6d82 +3697 5c60 +3698 571f +3699 5410 +3700 5154 +3701 6e4d +3702 56e2 +3703 63a8 +3704 9893 +3705 817f +3706 8715 +3707 892a +3708 9000 +3709 541e +3710 5c6f +3711 81c0 +3712 62d6 +3713 6258 +3714 8131 +3715 9e35 +3716 9640 +3717 9a6e +3718 9a7c +3719 692d +3720 59a5 +3721 62d3 +3722 553e +3723 6316 +3724 54c7 +3725 86d9 +3726 6d3c +3727 5a03 +3728 74e6 +3729 889c +3730 6b6a +3731 5916 +3732 8c4c +3733 5f2f +3734 6e7e +3735 73a9 +3736 987d +3737 4e38 +3738 70f7 +3739 5b8c +3740 7897 +3741 633d +3742 665a +3743 7696 +3744 60cb +3745 5b9b +3746 5a49 +3747 4e07 +3748 8155 +3749 6c6a +3750 738b +3751 4ea1 +3752 6789 +3753 7f51 +3754 5f80 +3755 65fa +3756 671b +3757 5fd8 +3758 5984 +3759 5a01 +3760 5dcd +3761 5fae +3762 5371 +3763 97e6 +3764 8fdd +3765 6845 +3766 56f4 +3767 552f +3768 60df +3769 4e3a +3770 6f4d +3771 7ef4 +3772 82c7 +3773 840e +3774 59d4 +3775 4f1f +3776 4f2a +3777 5c3e +3778 7eac +3779 672a +3780 851a +3781 5473 +3782 754f +3783 80c3 +3784 5582 +3785 9b4f +3786 4f4d +3787 6e2d +3788 8c13 +3789 5c09 +3790 6170 +3791 536b +3792 761f +3793 6e29 +3794 868a +3795 6587 +3796 95fb +3797 7eb9 +3798 543b +3799 7a33 +3800 7d0a +3801 95ee +3802 55e1 +3803 7fc1 +3804 74ee +3805 631d +3806 8717 +3807 6da1 +3808 7a9d +3809 6211 +3810 65a1 +3811 5367 +3812 63e1 +3813 6c83 +3814 5deb +3815 545c +3816 94a8 +3817 4e4c +3818 6c61 +3819 8bec +3820 5c4b +3821 65e0 +3822 829c +3823 68a7 +3824 543e +3825 5434 +3826 6bcb +3827 6b66 +3828 4e94 +3829 6342 +3830 5348 +3831 821e +3832 4f0d +3833 4fae +3834 575e +3835 620a +3836 96fe +3837 6664 +3838 7269 +3839 52ff +3840 52a1 +3841 609f +3842 8bef +3843 6614 +3844 7199 +3845 6790 +3846 897f +3847 7852 +3848 77fd +3849 6670 +3850 563b +3851 5438 +3852 9521 +3853 727a +3854 7a00 +3855 606f +3856 5e0c +3857 6089 +3858 819d +3859 5915 +3860 60dc +3861 7184 +3862 70ef +3863 6eaa +3864 6c50 +3865 7280 +3866 6a84 +3867 88ad +3868 5e2d +3869 4e60 +3870 5ab3 +3871 559c +3872 94e3 +3873 6d17 +3874 7cfb +3875 9699 +3876 620f +3877 7ec6 +3878 778e +3879 867e +3880 5323 +3881 971e +3882 8f96 +3883 6687 +3884 5ce1 +3885 4fa0 +3886 72ed +3887 4e0b +3888 53a6 +3889 590f +3890 5413 +3891 6380 +3892 9528 +3893 5148 +3894 4ed9 +3895 9c9c +3896 7ea4 +3897 54b8 +3898 8d24 +3899 8854 +3900 8237 +3901 95f2 +3902 6d8e +3903 5f26 +3904 5acc +3905 663e +3906 9669 +3907 73b0 +3908 732e +3909 53bf +3910 817a +3911 9985 +3912 7fa1 +3913 5baa +3914 9677 +3915 9650 +3916 7ebf +3917 76f8 +3918 53a2 +3919 9576 +3920 9999 +3921 7bb1 +3922 8944 +3923 6e58 +3924 4e61 +3925 7fd4 +3926 7965 +3927 8be6 +3928 60f3 +3929 54cd +3930 4eab +3931 9879 +3932 5df7 +3933 6a61 +3934 50cf +3935 5411 +3936 8c61 +3937 8427 +3938 785d +3939 9704 +3940 524a +3941 54ee +3942 56a3 +3943 9500 +3944 6d88 +3945 5bb5 +3946 6dc6 +3947 6653 +3948 5c0f +3949 5b5d +3950 6821 +3951 8096 +3952 5578 +3953 7b11 +3954 6548 +3955 6954 +3956 4e9b +3957 6b47 +3958 874e +3959 978b +3960 534f +3961 631f +3962 643a +3963 90aa +3964 659c +3965 80c1 +3966 8c10 +3967 5199 +3968 68b0 +3969 5378 +3970 87f9 +3971 61c8 +3972 6cc4 +3973 6cfb +3974 8c22 +3975 5c51 +3976 85aa +3977 82af +3978 950c +3979 6b23 +3980 8f9b +3981 65b0 +3982 5ffb +3983 5fc3 +3984 4fe1 +3985 8845 +3986 661f +3987 8165 +3988 7329 +3989 60fa +3990 5174 +3991 5211 +3992 578b +3993 5f62 +3994 90a2 +3995 884c +3996 9192 +3997 5e78 +3998 674f +3999 6027 +4000 59d3 +4001 5144 +4002 51f6 +4003 80f8 +4004 5308 +4005 6c79 +4006 96c4 +4007 718a +4008 4f11 +4009 4fee +4010 7f9e +4011 673d +4012 55c5 +4013 9508 +4014 79c0 +4015 8896 +4016 7ee3 +4017 589f +4018 620c +4019 9700 +4020 865a +4021 5618 +4022 987b +4023 5f90 +4024 8bb8 +4025 84c4 +4026 9157 +4027 53d9 +4028 65ed +4029 5e8f +4030 755c +4031 6064 +4032 7d6e +4033 5a7f +4034 7eea +4035 7eed +4036 8f69 +4037 55a7 +4038 5ba3 +4039 60ac +4040 65cb +4041 7384 +4042 9009 +4043 7663 +4044 7729 +4045 7eda +4046 9774 +4047 859b +4048 5b66 +4049 7a74 +4050 96ea +4051 8840 +4052 52cb +4053 718f +4054 5faa +4055 65ec +4056 8be2 +4057 5bfb +4058 9a6f +4059 5de1 +4060 6b89 +4061 6c5b +4062 8bad +4063 8baf +4064 900a +4065 8fc5 +4066 538b +4067 62bc +4068 9e26 +4069 9e2d +4070 5440 +4071 4e2b +4072 82bd +4073 7259 +4074 869c +4075 5d16 +4076 8859 +4077 6daf +4078 96c5 +4079 54d1 +4080 4e9a +4081 8bb6 +4082 7109 +4083 54bd +4084 9609 +4085 70df +4086 6df9 +4087 76d0 +4088 4e25 +4089 7814 +4090 8712 +4091 5ca9 +4092 5ef6 +4093 8a00 +4094 989c +4095 960e +4096 708e +4097 6cbf +4098 5944 +4099 63a9 +4100 773c +4101 884d +4102 6f14 +4103 8273 +4104 5830 +4105 71d5 +4106 538c +4107 781a +4108 96c1 +4109 5501 +4110 5f66 +4111 7130 +4112 5bb4 +4113 8c1a +4114 9a8c +4115 6b83 +4116 592e +4117 9e2f +4118 79e7 +4119 6768 +4120 626c +4121 4f6f +4122 75a1 +4123 7f8a +4124 6d0b +4125 9633 +4126 6c27 +4127 4ef0 +4128 75d2 +4129 517b +4130 6837 +4131 6f3e +4132 9080 +4133 8170 +4134 5996 +4135 7476 +4136 6447 +4137 5c27 +4138 9065 +4139 7a91 +4140 8c23 +4141 59da +4142 54ac +4143 8200 +4144 836f +4145 8981 +4146 8000 +4147 6930 +4148 564e +4149 8036 +4150 7237 +4151 91ce +4152 51b6 +4153 4e5f +4154 9875 +4155 6396 +4156 4e1a +4157 53f6 +4158 66f3 +4159 814b +4160 591c +4161 6db2 +4162 4e00 +4163 58f9 +4164 533b +4165 63d6 +4166 94f1 +4167 4f9d +4168 4f0a +4169 8863 +4170 9890 +4171 5937 +4172 9057 +4173 79fb +4174 4eea +4175 80f0 +4176 7591 +4177 6c82 +4178 5b9c +4179 59e8 +4180 5f5d +4181 6905 +4182 8681 +4183 501a +4184 5df2 +4185 4e59 +4186 77e3 +4187 4ee5 +4188 827a +4189 6291 +4190 6613 +4191 9091 +4192 5c79 +4193 4ebf +4194 5f79 +4195 81c6 +4196 9038 +4197 8084 +4198 75ab +4199 4ea6 +4200 88d4 +4201 610f +4202 6bc5 +4203 5fc6 +4204 4e49 +4205 76ca +4206 6ea2 +4207 8be3 +4208 8bae +4209 8c0a +4210 8bd1 +4211 5f02 +4212 7ffc +4213 7fcc +4214 7ece +4215 8335 +4216 836b +4217 56e0 +4218 6bb7 +4219 97f3 +4220 9634 +4221 59fb +4222 541f +4223 94f6 +4224 6deb +4225 5bc5 +4226 996e +4227 5c39 +4228 5f15 +4229 9690 +4230 5370 +4231 82f1 +4232 6a31 +4233 5a74 +4234 9e70 +4235 5e94 +4236 7f28 +4237 83b9 +4238..4239 8424 +4240 8367 +4241 8747 +4242 8fce +4243 8d62 +4244 76c8 +4245 5f71 +4246 9896 +4247 786c +4248 6620 +4249 54df +4250 62e5 +4251 4f63 +4252 81c3 +4253 75c8 +4254 5eb8 +4255 96cd +4256 8e0a +4257 86f9 +4258 548f +4259 6cf3 +4260 6d8c +4261 6c38 +4262 607f +4263 52c7 +4264 7528 +4265 5e7d +4266 4f18 +4267 60a0 +4268 5fe7 +4269 5c24 +4270 7531 +4271 90ae +4272 94c0 +4273 72b9 +4274 6cb9 +4275 6e38 +4276 9149 +4277 6709 +4278 53cb +4279 53f3 +4280 4f51 +4281 91c9 +4282 8bf1 +4283 53c8 +4284 5e7c +4285 8fc2 +4286 6de4 +4287 4e8e +4288 76c2 +4289 6986 +4290 865e +4291 611a +4292 8206 +4293 4f59 +4294 4fde +4295 903e +4296 9c7c +4297 6109 +4298 6e1d +4299 6e14 +4300 9685 +4301 4e88 +4302 5a31 +4303 96e8 +4304 4e0e +4305 5c7f +4306 79b9 +4307 5b87 +4308 8bed +4309 7fbd +4310 7389 +4311 57df +4312 828b +4313 90c1 +4314 5401 +4315 9047 +4316 55bb +4317 5cea +4318 5fa1 +4319 6108 +4320 6b32 +4321 72f1 +4322 80b2 +4323 8a89 +4324 6d74 +4325 5bd3 +4326 88d5 +4327 9884 +4328 8c6b +4329 9a6d +4330 9e33 +4331 6e0a +4332 51a4 +4333 5143 +4334 57a3 +4335 8881 +4336 539f +4337 63f4 +4338 8f95 +4339 56ed +4340 5458 +4341 5706 +4342 733f +4343 6e90 +4344 7f18 +4345 8fdc +4346 82d1 +4347 613f +4348 6028 +4349 9662 +4350 66f0 +4351 7ea6 +4352 8d8a +4353 8dc3 +4354 94a5 +4355 5cb3 +4356 7ca4 +4357 6708 +4358 60a6 +4359 9605 +4360 8018 +4361 4e91 +4362 90e7 +4363 5300 +4364 9668 +4365 5141 +4366 8fd0 +4367 8574 +4368 915d +4369 6655 +4370 97f5 +4371 5b55 +4372 531d +4373 7838 +4374 6742 +4375 683d +4376 54c9 +4377 707e +4378 5bb0 +4379 8f7d +4380 518d +4381 5728 +4382 54b1 +4383 6512 +4384 6682 +4385 8d5e +4386 8d43 +4387 810f +4388 846c +4389 906d +4390 7cdf +4391 51ff +4392 85fb +4393 67a3 +4394 65e9 +4395 6fa1 +4396 86a4 +4397 8e81 +4398 566a +4399 9020 +4400 7682 +4401 7076 +4402 71e5 +4403 8d23 +4404 62e9 +4405 5219 +4406 6cfd +4407 8d3c +4408 600e +4409 589e +4410 618e +4411 66fe +4412 8d60 +4413 624e +4414 55b3 +4415 6e23 +4416 672d +4417 8f67 +4418 94e1 +4419 95f8 +4420 7728 +4421 6805 +4422 69a8 +4423 548b +4424 4e4d +4425 70b8 +4426 8bc8 +4427 6458 +4428 658b +4429 5b85 +4430 7a84 +4431 503a +4432 5be8 +4433 77bb +4434 6be1 +4435 8a79 +4436 7c98 +4437 6cbe +4438 76cf +4439 65a9 +4440 8f97 +4441 5d2d +4442 5c55 +4443 8638 +4444 6808 +4445 5360 +4446 6218 +4447 7ad9 +4448 6e5b +4449 7efd +4450 6a1f +4451 7ae0 +4452 5f70 +4453 6f33 +4454 5f20 +4455 638c +4456 6da8 +4457 6756 +4458 4e08 +4459 5e10 +4460 8d26 +4461 4ed7 +4462 80c0 +4463 7634 +4464 969c +4465 62db +4466 662d +4467 627e +4468 6cbc +4469 8d75 +4470 7167 +4471 7f69 +4472 5146 +4473 8087 +4474 53ec +4475 906e +4476 6298 +4477 54f2 +4478 86f0 +4479 8f99 +4480 8005 +4481 9517 +4482 8517 +4483 8fd9 +4484 6d59 +4485 73cd +4486 659f +4487 771f +4488 7504 +4489 7827 +4490 81fb +4491 8d1e +4492 9488 +4493 4fa6 +4494 6795 +4495 75b9 +4496 8bca +4497 9707 +4498 632f +4499 9547 +4500 9635 +4501 84b8 +4502 6323 +4503 7741 +4504 5f81 +4505 72f0 +4506 4e89 +4507 6014 +4508 6574 +4509 62ef +4510 6b63 +4511 653f +4512 5e27 +4513 75c7 +4514 90d1 +4515 8bc1 +4516 829d +4517 679d +4518 652f +4519 5431 +4520 8718 +4521 77e5 +4522 80a2 +4523 8102 +4524 6c41 +4525 4e4b +4526 7ec7 +4527 804c +4528 76f4 +4529 690d +4530 6b96 +4531 6267 +4532 503c +4533 4f84 +4534 5740 +4535 6307 +4536 6b62 +4537 8dbe +4538 53ea +4539 65e8 +4540 7eb8 +4541 5fd7 +4542 631a +4543 63b7 +4544..4545 81f3 +4546 7f6e +4547 5e1c +4548 5cd9 +4549 5236 +4550 667a +4551 79e9 +4552 7a1a +4553 8d28 +4554 7099 +4555 75d4 +4556 6ede +4557 6cbb +4558 7a92 +4559 4e2d +4560 76c5 +4561 5fe0 +4562 949f +4563 8877 +4564 7ec8 +4565 79cd +4566 80bf +4567 91cd +4568 4ef2 +4569 4f17 +4570 821f +4571 5468 +4572 5dde +4573 6d32 +4574 8bcc +4575 7ca5 +4576 8f74 +4577 8098 +4578 5e1a +4579 5492 +4580 76b1 +4581 5b99 +4582 663c +4583 9aa4 +4584 73e0 +4585 682a +4586 86db +4587 6731 +4588 732a +4589 8bf8 +4590 8bdb +4591 9010 +4592 7af9 +4593 70db +4594 716e +4595 62c4 +4596 77a9 +4597 5631 +4598 4e3b +4599 8457 +4600 67f1 +4601 52a9 +4602 86c0 +4603 8d2e +4604 94f8 +4605 7b51 +4606 4f4f +4607 6ce8 +4608 795d +4609 9a7b +4610 6293 +4611 722a +4612 62fd +4613 4e13 +4614 7816 +4615 8f6c +4616 64b0 +4617 8d5a +4618 7bc6 +4619 6869 +4620 5e84 +4621 88c5 +4622 5986 +4623 649e +4624 58ee +4625 72b6 +4626 690e +4627 9525 +4628 8ffd +4629 8d58 +4630 5760 +4631 7f00 +4632 8c06 +4633 51c6 +4634 6349 +4635 62d9 +4636 5353 +4637 684c +4638 7422 +4639 8301 +4640 914c +4641 5544 +4642 7740 +4643 707c +4644 6d4a +4645 5179 +4646 54a8 +4647 8d44 +4648 59ff +4649 6ecb +4650 6dc4 +4651 5b5c +4652 7d2b +4653 4ed4 +4654 7c7d +4655 6ed3 +4656 5b50 +4657 81ea +4658 6e0d +4659 5b57 +4660 9b03 +4661 68d5 +4662 8e2a +4663 5b97 +4664 7efc +4665 603b +4666 7eb5 +4667 90b9 +4668 8d70 +4669 594f +4670 63cd +4671 79df +4672 8db3 +4673 5352 +4674 65cf +4675 7956 +4676 8bc5 +4677 963b +4678 7ec4 +4679 94bb +4680 7e82 +4681 5634 +4682 9189 +4683 6700 +4684 7f6a +4685 5c0a +4686 9075 +4687 6628 +4688 5de6 +4689 4f50 +4690 67de +4691 505a +4692 4f5c +4693 5750 +4694 5ea7 +4695 4e8d +4696 4e0c +4697 5140 +4698 4e10 +4699 5eff +4700 5345 +4701 4e15 +4702 4e98 +4703 4e1e +4704 9b32 +4705 5b6c +4706 5669 +4707 4e28 +4708 79ba +4709 4e3f +4710 5315 +4711 4e47 +4712 592d +4713 723b +4714 536e +4715 6c10 +4716 56df +4717 80e4 +4718 9997 +4719 6bd3 +4720 777e +4721 9f17 +4722 4e36 +4723 4e9f +4724 9f10 +4725 4e5c +4726 4e69 +4727 4e93 +4728 8288 +4729 5b5b +4730 556c +4731 560f +4732 4ec4 +4733 538d +4734 539d +4735 53a3 +4736 53a5 +4737 53ae +4738 9765 +4739 8d5d +4740 531a +4741 53f5 +4742 5326 +4743 532e +4744 533e +4745 8d5c +4746 5366 +4747 5363 +4748 5202 +4749 5208 +4750 520e +4751 522d +4752 5233 +4753..4754 523f +4755 524c +4756 525e +4757 5261 +4758 525c +4759 84af +4760 527d +4761 5282 +4762 5281 +4763 5290 +4764 5293 +4765 5182 +4766 7f54 +4767 4ebb +4768 4ec3 +4769 4ec9 +4770 4ec2 +4771 4ee8 +4772 4ee1 +4773 4eeb +4774 4ede +4775 4f1b +4776 4ef3 +4777 4f22 +4778 4f64 +4779 4ef5 +4780 4f25 +4781 4f27 +4782 4f09 +4783 4f2b +4784 4f5e +4785 4f67 +4786 6538 +4787 4f5a +4788 4f5d +4789 4f5f +4790 4f57 +4791 4f32 +4792 4f3d +4793 4f76 +4794 4f74 +4795 4f91 +4796 4f89 +4797 4f83 +4798 4f8f +4799 4f7e +4800 4f7b +4801 4faa +4802 4f7c +4803 4fac +4804 4f94 +4805 4fe6 +4806 4fe8 +4807 4fea +4808 4fc5 +4809 4fda +4810 4fe3 +4811 4fdc +4812 4fd1 +4813 4fdf +4814 4ff8 +4815 5029 +4816 504c +4817 4ff3 +4818 502c +4819 500f +4820 502e +4821 502d +4822 4ffe +4823 501c +4824 500c +4825 5025 +4826 5028 +4827 507e +4828 5043 +4829 5055 +4830 5048 +4831 504e +4832 506c +4833 507b +4834 50a5 +4835 50a7 +4836 50a9 +4837 50ba +4838 50d6 +4839 5106 +4840 50ed +4841 50ec +4842 50e6 +4843 50ee +4844 5107 +4845 510b +4846 4edd +4847 6c3d +4848 4f58 +4849 4f65 +4850 4fce +4851 9fa0 +4852 6c46 +4853 7c74 +4854 516e +4855 5dfd +4856 9ec9 +4857 9998 +4858 5181 +4859 5914 +4860 52f9 +4861 530d +4862 8a07 +4863 5310 +4864 51eb +4865 5919 +4866 5155 +4867 4ea0 +4868 5156 +4869 4eb3 +4870 886e +4871 88a4 +4872 4eb5 +4873 8114 +4874 88d2 +4875 7980 +4876 5b34 +4877 8803 +4878 7fb8 +4879 51ab +4880 51b1 +4881 51bd +4882 51bc +4883 51c7 +4884 5196 +4885 51a2 +4886 51a5 +4887 8ba0 +4888..4889 8ba6 +4890 8baa +4891..4892 8bb4 +4893 8bb7 +4894..4895 8bc2 +4896 8bcb +4897 8bcf +4898 8bce +4899..4901 8bd2 +4902 8bd6 +4903..4904 8bd8 +4905 8bdc +4906..4907 8bdf +4908 8be4 +4909..4910 8be8 +4911 8bee +4912 8bf0 +4913 8bf3 +4914 8bf6 +4915 8bf9 +4916 8bfc +4917..4918 8bff +4919 8c02 +4920 8c04 +4921 8c07 +4922 8c0c +4923 8c0f +4924..4925 8c11 +4926..4928 8c14 +4929 8c19 +4930 8c1b +4931 8c18 +4932 8c1d +4933..4935 8c1f +4936 8c25 +4937 8c27 +4938..4939 8c2a +4940..4941 8c2e +4942..4943 8c32 +4944..4945 8c35 +4946 5369 +4947 537a +4948 961d +4949 9622 +4950 9621 +4951 9631 +4952 962a +4953 963d +4954 963c +4955 9642 +4956 9649 +4957 9654 +4958 965f +4959 9667 +4960 966c +4961 9672 +4962 9674 +4963 9688 +4964 968d +4965 9697 +4966 96b0 +4967 9097 +4968 909b +4969 909d +4970 9099 +4971 90ac +4972 90a1 +4973 90b4 +4974 90b3 +4975 90b6 +4976 90ba +4977 90b8 +4978 90b0 +4979 90cf +4980 90c5 +4981 90be +4982 90d0 +4983 90c4 +4984 90c7 +4985 90d3 +4986 90e6 +4987 90e2 +4988 90dc +4989 90d7 +4990 90db +4991 90eb +4992 90ef +4993 90fe +4994 9104 +4995 9122 +4996 911e +4997 9123 +4998 9131 +4999 912f +5000 9139 +5001 9143 +5002 9146 +5003 520d +5004 5942 +5005 52a2 +5006..5007 52ac +5008 52be +5009 54ff +5010 52d0 +5011 52d6 +5012 52f0 +5013 53df +5014 71ee +5015 77cd +5016 5ef4 +5017 51f5 +5018 51fc +5019 9b2f +5020 53b6 +5021 5f01 +5022 755a +5023 5def +5024 574c +5025 57a9 +5026 57a1 +5027 587e +5028 58bc +5029 58c5 +5030 58d1 +5031 5729 +5032 572c +5033 572a +5034 5733 +5035 5739 +5036..5037 572e +5038 575c +5039 573b +5040 5742 +5041 5769 +5042 5785 +5043 576b +5044 5786 +5045 577c +5046 577b +5047 5768 +5048 576d +5049 5776 +5050 5773 +5051 57ad +5052 57a4 +5053 578c +5054 57b2 +5055 57cf +5056 57a7 +5057 57b4 +5058 5793 +5059 57a0 +5060 57d5 +5061 57d8 +5062 57da +5063 57d9 +5064 57d2 +5065 57b8 +5066 57f4 +5067 57ef +5068 57f8 +5069 57e4 +5070 57dd +5071 580b +5072 580d +5073 57fd +5074 57ed +5075 5800 +5076 581e +5077 5819 +5078 5844 +5079 5820 +5080 5865 +5081 586c +5082 5881 +5083 5889 +5084 589a +5085 5880 +5086 99a8 +5087 9f19 +5088 61ff +5089 8279 +5090 827d +5091 827f +5092 828f +5093 828a +5094 82a8 +5095 8284 +5096 828e +5097 8291 +5098 8297 +5099 8299 +5100 82ab +5101 82b8 +5102 82be +5103 82b0 +5104 82c8 +5105 82ca +5106 82e3 +5107 8298 +5108 82b7 +5109 82ae +5110..5111 82cb +5112 82c1 +5113 82a9 +5114 82b4 +5115 82a1 +5116 82aa +5117 829f +5118 82c4 +5119 82ce +5120 82a4 +5121 82e1 +5122 8309 +5123 82f7 +5124 82e4 +5125 830f +5126 8307 +5127 82dc +5128 82f4 +5129 82d2 +5130 82d8 +5131 830c +5132 82fb +5133 82d3 +5134 8311 +5135 831a +5136 8306 +5137..5138 8314 +5139 82e0 +5140 82d5 +5141 831c +5142 8351 +5143..5144 835b +5145 8308 +5146 8392 +5147 833c +5148 8334 +5149 8331 +5150 839b +5151 835e +5152 832f +5153 834f +5154 8347 +5155 8343 +5156 835f +5157 8340 +5158 8317 +5159 8360 +5160 832d +5161 833a +5162 8333 +5163 8366 +5164 8365 +5165 8368 +5166 831b +5167 8369 +5168 836c +5169 836a +5170..5171 836d +5172 83b0 +5173 8378 +5174..5175 83b3 +5176 83a0 +5177 83aa +5178 8393 +5179 839c +5180 8385 +5181 837c +5182 83b6 +5183 83a9 +5184 837d +5185 83b8 +5186 837b +5187 8398 +5188 839e +5189 83a8 +5190 83ba +5191 83bc +5192 83c1 +5193 8401 +5194 83e5 +5195 83d8 +5196 5807 +5197 8418 +5198 840b +5199 83dd +5200 83fd +5201 83d6 +5202 841c +5203 8438 +5204 8411 +5205 8406 +5206 83d4 +5207 83df +5208 840f +5209 8403 +5210..5211 83f8 +5212 83ea +5213 83c5 +5214 83c0 +5215 8426 +5216 83f0 +5217 83e1 +5218 845c +5219 8451 +5220 845a +5221 8459 +5222 8473 +5223..5224 8487 +5225 847a +5226 8489 +5227 8478 +5228 843c +5229 8446 +5230 8469 +5231 8476 +5232 848c +5233 848e +5234 8431 +5235 846d +5236 84c1 +5237 84cd +5238 84d0 +5239 84e6 +5240 84bd +5241 84d3 +5242 84ca +5243 84bf +5244 84ba +5245 84e0 +5246 84a1 +5247 84b9 +5248 84b4 +5249 8497 +5250 84e5 +5251 84e3 +5252 850c +5253 750d +5254 8538 +5255 84f0 +5256 8539 +5257 851f +5258 853a +5259 8556 +5260 853b +5261 84ff +5262 84fc +5263 8559 +5264 8548 +5265 8568 +5266 8564 +5267 855e +5268 857a +5269 77a2 +5270 8543 +5271 8572 +5272 857b +5273 85a4 +5274 85a8 +5275 8587 +5276 858f +5277 8579 +5278 85ae +5279 859c +5280 8585 +5281 85b9 +5282 85b7 +5283 85b0 +5284 85d3 +5285 85c1 +5286 85dc +5287 85ff +5288 8627 +5289 8605 +5290 8629 +5291 8616 +5292 863c +5293 5efe +5294 5f08 +5295 593c +5296 5941 +5297 8037 +5298 5955 +5299 595a +5300 5958 +5301 530f +5302 5c22 +5303 5c25 +5304 5c2c +5305 5c34 +5306 624c +5307 626a +5308 629f +5309 62bb +5310 62ca +5311 62da +5312 62d7 +5313 62ee +5314 6322 +5315 62f6 +5316 6339 +5317 634b +5318 6343 +5319 63ad +5320 63f6 +5321 6371 +5322 637a +5323 638e +5324 63b4 +5325 636d +5326 63ac +5327 638a +5328 6369 +5329 63ae +5330 63bc +5331 63f2 +5332 63f8 +5333 63e0 +5334 63ff +5335 63c4 +5336 63de +5337 63ce +5338 6452 +5339 63c6 +5340 63be +5341 6445 +5342 6441 +5343 640b +5344 641b +5345 6420 +5346 640c +5347 6426 +5348 6421 +5349 645e +5350 6484 +5351 646d +5352 6496 +5353 647a +5354..5355 64b7 +5356 6499 +5357 64ba +5358 64c0 +5359 64d0 +5360 64d7 +5361 64e4 +5362 64e2 +5363 6509 +5364 6525 +5365 652e +5366 5f0b +5367 5fd2 +5368 7519 +5369 5f11 +5370 535f +5371 53f1 +5372 53fd +5373 53e9 +5374 53e8 +5375 53fb +5376 5412 +5377 5416 +5378 5406 +5379 544b +5380..5382 5452 +5383 5456 +5384 5443 +5385 5421 +5386 5457 +5387 5459 +5388 5423 +5389 5432 +5390 5482 +5391 5494 +5392 5477 +5393 5471 +5394 5464 +5395..5396 549a +5397 5484 +5398 5476 +5399 5466 +5400 549d +5401 54d0 +5402 54ad +5403 54c2 +5404 54b4 +5405 54d2 +5406 54a7 +5407 54a6 +5408..5409 54d3 +5410 5472 +5411 54a3 +5412 54d5 +5413 54bb +5414 54bf +5415 54cc +5416..5417 54d9 +5418 54dc +5419..5420 54a9 +5421 54a4 +5422 54dd +5423 54cf +5424 54de +5425 551b +5426 54e7 +5427 5520 +5428 54fd +5429 5514 +5430 54f3 +5431..5432 5522 +5433 550f +5434 5511 +5435 5527 +5436 552a +5437 5567 +5438 558f +5439 55b5 +5440 5549 +5441 556d +5442 5541 +5443 5555 +5444 553f +5445 5550 +5446 553c +5447 5537 +5448 5556 +5449..5451 5575 +5452 5533 +5453 5530 +5454 555c +5455 558b +5456 55d2 +5457 5583 +5458 55b1 +5459 55b9 +5460 5588 +5461 5581 +5462 559f +5463 557e +5464 55d6 +5465 5591 +5466 557b +5467 55df +5468..5469 55bd +5470 5594 +5471 5599 +5472 55ea +5473 55f7 +5474 55c9 +5475 561f +5476 55d1 +5477..5478 55eb +5479 55d4 +5480 55e6 +5481 55dd +5482 55c4 +5483 55ef +5484 55e5 +5485..5486 55f2 +5487..5488 55cc +5489 55e8 +5490 55f5 +5491 55e4 +5492 8f94 +5493 561e +5494 5608 +5495 560c +5496 5601 +5497 5624 +5498 5623 +5499 55fe +5500 5600 +5501 5627 +5502 562d +5503 5658 +5504 5639 +5505 5657 +5506 562c +5507 564d +5508 5662 +5509 5659 +5510 565c +5511 564c +5512 5654 +5513 5686 +5514 5664 +5515 5671 +5516 566b +5517..5518 567b +5519 5685 +5520 5693 +5521 56af +5522 56d4 +5523 56d7 +5524 56dd +5525 56e1 +5526 56f5 +5527 56eb +5528 56f9 +5529 56ff +5530 5704 +5531 570a +5532 5709 +5533 571c +5534 5e0f +5535 5e19 +5536 5e14 +5537 5e11 +5538 5e31 +5539..5540 5e3b +5541 5e37 +5542 5e44 +5543 5e54 +5544 5e5b +5545 5e5e +5546 5e61 +5547 5c8c +5548 5c7a +5549 5c8d +5550 5c90 +5551 5c96 +5552 5c88 +5553..5554 5c98 +5555 5c91 +5556 5c9a +5557 5c9c +5558 5cb5 +5559 5ca2 +5560 5cbd +5561 5cac +5562 5cab +5563 5cb1 +5564 5ca3 +5565 5cc1 +5566 5cb7 +5567 5cc4 +5568 5cd2 +5569 5ce4 +5570 5ccb +5571 5ce5 +5572..5573 5d02 +5574 5d27 +5575 5d26 +5576 5d2e +5577 5d24 +5578 5d1e +5579 5d06 +5580 5d1b +5581 5d58 +5582 5d3e +5583 5d34 +5584 5d3d +5585 5d6c +5586 5d5b +5587 5d6f +5588 5d5d +5589 5d6b +5590 5d4b +5591 5d4a +5592 5d69 +5593 5d74 +5594 5d82 +5595 5d99 +5596 5d9d +5597 8c73 +5598 5db7 +5599 5dc5 +5600 5f73 +5601 5f77 +5602 5f82 +5603 5f87 +5604 5f89 +5605 5f8c +5606 5f95 +5607 5f99 +5608 5f9c +5609 5fa8 +5610 5fad +5611 5fb5 +5612 5fbc +5613 8862 +5614 5f61 +5615 72ad +5616 72b0 +5617 72b4 +5618..5619 72b7 +5620 72c3 +5621 72c1 +5622 72ce +5623 72cd +5624 72d2 +5625 72e8 +5626 72ef +5627 72e9 +5628 72f2 +5629 72f4 +5630 72f7 +5631 7301 +5632 72f3 +5633 7303 +5634..5635 72fa +5636 7317 +5637 7313 +5638 7321 +5639 730a +5640 731e +5641 731d +5642 7315 +5643 7322 +5644 7339 +5645 7325 +5646 732c +5647 7338 +5648 7331 +5649 7350 +5650 734d +5651 7357 +5652 7360 +5653 736c +5654 736f +5655 737e +5656 821b +5657 5925 +5658 98e7 +5659 5924 +5660 5902 +5661 9963 +5662..5667 9967 +5668 9974 +5669 9977 +5670 997d +5671 9980 +5672 9984 +5673 9987 +5674 998a +5675 998d +5676..5677 9990 +5678..5680 9993 +5681 5e80 +5682 5e91 +5683 5e8b +5684 5e96 +5685 5ea5 +5686 5ea0 +5687 5eb9 +5688 5eb5 +5689 5ebe +5690 5eb3 +5691 8d53 +5692 5ed2 +5693 5ed1 +5694 5edb +5695 5ee8 +5696 5eea +5697 81ba +5698 5fc4 +5699 5fc9 +5700 5fd6 +5701 5fcf +5702 6003 +5703 5fee +5704 6004 +5705 5fe1 +5706 5fe4 +5707 5ffe +5708..5709 6005 +5710 5fea +5711 5fed +5712 5ff8 +5713 6019 +5714 6035 +5715 6026 +5716 601b +5717 600f +5718 600d +5719 6029 +5720 602b +5721 600a +5722 603f +5723 6021 +5724..5725 6078 +5726 607b +5727 607a +5728 6042 +5729 606a +5730 607d +5731 6096 +5732 609a +5733 60ad +5734 609d +5735 6083 +5736 6092 +5737 608c +5738 609b +5739 60ec +5740 60bb +5741 60b1 +5742 60dd +5743 60d8 +5744 60c6 +5745 60da +5746 60b4 +5747 6120 +5748 6126 +5749 6115 +5750 6123 +5751 60f4 +5752 6100 +5753 610e +5754 612b +5755 614a +5756 6175 +5757 61ac +5758 6194 +5759 61a7 +5760 61b7 +5761 61d4 +5762 61f5 +5763 5fdd +5764 96b3 +5765 95e9 +5766 95eb +5767 95f1 +5768 95f3 +5769..5770 95f5 +5771 95fc +5772 95fe +5773..5774 9603 +5775 9606 +5776 9608 +5777..5780 960a +5781 960f +5782 9612 +5783..5785 9615 +5786..5787 9619 +5788 4e2c +5789 723f +5790 6215 +5791 6c35 +5792 6c54 +5793 6c5c +5794 6c4a +5795 6ca3 +5796 6c85 +5797 6c90 +5798 6c94 +5799 6c8c +5800..5801 6c68 +5802 6c74 +5803 6c76 +5804 6c86 +5805 6ca9 +5806 6cd0 +5807 6cd4 +5808 6cad +5809..5810 6cf7 +5811 6cf1 +5812 6cd7 +5813 6cb2 +5814 6ce0 +5815 6cd6 +5816 6cfa +5817 6ceb +5818 6cee +5819 6cb1 +5820 6cd3 +5821 6cef +5822 6cfe +5823 6d39 +5824 6d27 +5825 6d0c +5826 6d43 +5827 6d48 +5828 6d07 +5829 6d04 +5830 6d19 +5831 6d0e +5832 6d2b +5833 6d4d +5834 6d2e +5835 6d35 +5836 6d1a +5837 6d4f +5838 6d52 +5839 6d54 +5840 6d33 +5841 6d91 +5842 6d6f +5843 6d9e +5844 6da0 +5845 6d5e +5846..5847 6d93 +5848 6d5c +5849 6d60 +5850 6d7c +5851 6d63 +5852 6e1a +5853 6dc7 +5854 6dc5 +5855 6dde +5856 6e0e +5857 6dbf +5858 6de0 +5859 6e11 +5860 6de6 +5861 6ddd +5862 6dd9 +5863 6e16 +5864 6dab +5865 6e0c +5866 6dae +5867 6e2b +5868 6e6e +5869 6e4e +5870 6e6b +5871 6eb2 +5872 6e5f +5873 6e86 +5874..5875 6e53 +5876 6e32 +5877 6e25 +5878 6e44 +5879 6edf +5880 6eb1 +5881 6e98 +5882 6ee0 +5883 6f2d +5884 6ee2 +5885 6ea5 +5886 6ea7 +5887 6ebd +5888 6ebb +5889 6eb7 +5890 6ed7 +5891 6eb4 +5892 6ecf +5893 6e8f +5894 6ec2 +5895 6e9f +5896 6f62 +5897..5898 6f46 +5899 6f24 +5900 6f15 +5901 6ef9 +5902 6f2f +5903 6f36 +5904 6f4b +5905 6f74 +5906 6f2a +5907 6f09 +5908 6f29 +5909 6f89 +5910 6f8d +5911 6f8c +5912 6f78 +5913 6f72 +5914 6f7c +5915 6f7a +5916 6fd1 +5917 6fc9 +5918 6fa7 +5919 6fb9 +5920 6fb6 +5921 6fc2 +5922 6fe1 +5923 6fee +5924 6fde +5925 6fe0 +5926 6fef +5927 701a +5928 7023 +5929 701b +5930 7039 +5931 7035 +5932 704f +5933 705e +5934 5b80 +5935 5b84 +5936 5b95 +5937 5b93 +5938 5ba5 +5939 5bb8 +5940 752f +5941 9a9e +5942 6434 +5943 5be4 +5944 5bee +5945 8930 +5946 5bf0 +5947 8e47 +5948 8b07 +5949 8fb6 +5950 8fd3 +5951 8fd5 +5952 8fe5 +5953 8fee +5954 8fe4 +5955 8fe9 +5956 8fe6 +5957 8ff3 +5958 8fe8 +5959 9005 +5960 9004 +5961 900b +5962 9026 +5963 9011 +5964 900d +5965 9016 +5966 9021 +5967..5968 9035 +5969 902d +5970 902f +5971 9044 +5972..5973 9051 +5974 9050 +5975 9068 +5976 9058 +5977 9062 +5978 905b +5979 66b9 +5980 9074 +5981 907d +5982 9082 +5983 9088 +5984 9083 +5985 908b +5986 5f50 +5987 5f57 +5988 5f56 +5989 5f58 +5990 5c3b +5991 54ab +5992 5c50 +5993 5c59 +5994 5b71 +5995 5c63 +5996 5c66 +5997 7fbc +5998 5f2a +5999 5f29 +6000 5f2d +6001 8274 +6002 5f3c +6003 9b3b +6004 5c6e +6005 5981 +6006 5983 +6007 598d +6008..6009 59a9 +6010 59a3 +6011 5997 +6012 59ca +6013 59ab +6014 599e +6015 59a4 +6016 59d2 +6017 59b2 +6018 59af +6019 59d7 +6020 59be +6021..6022 5a05 +6023 59dd +6024 5a08 +6025 59e3 +6026 59d8 +6027 59f9 +6028 5a0c +6029 5a09 +6030 5a32 +6031 5a34 +6032 5a11 +6033 5a23 +6034 5a13 +6035 5a40 +6036 5a67 +6037 5a4a +6038 5a55 +6039 5a3c +6040 5a62 +6041 5a75 +6042 80ec +6043 5aaa +6044 5a9b +6045 5a77 +6046 5a7a +6047 5abe +6048 5aeb +6049 5ab2 +6050 5ad2 +6051 5ad4 +6052 5ab8 +6053 5ae0 +6054 5ae3 +6055 5af1 +6056 5ad6 +6057 5ae6 +6058 5ad8 +6059 5adc +6060 5b09 +6061 5b17 +6062 5b16 +6063 5b32 +6064 5b37 +6065 5b40 +6066 5c15 +6067 5c1c +6068 5b5a +6069 5b65 +6070 5b73 +6071 5b51 +6072 5b53 +6073 5b62 +6074 9a75 +6075..6076 9a77 +6077 9a7a +6078 9a7f +6079 9a7d +6080..6081 9a80 +6082 9a85 +6083 9a88 +6084 9a8a +6085 9a90 +6086..6087 9a92 +6088 9a96 +6089 9a98 +6090..6092 9a9b +6093..6094 9a9f +6095..6096 9aa2 +6097 9aa5 +6098 9aa7 +6099 7e9f +6100 7ea1 +6101 7ea3 +6102 7ea5 +6103..6104 7ea8 +6105 7ead +6106 7eb0 +6107 7ebe +6108..6110 7ec0 +6111 7ec9 +6112..6113 7ecb +6114 7ed0 +6115 7ed4 +6116 7ed7 +6117 7edb +6118..6119 7ee0 +6120 7ee8 +6121 7eeb +6122..6123 7eee +6124..6125 7ef1 +6126 7f0d +6127 7ef6 +6128..6129 7efa +6130 7efe +6131..6133 7f01 +6134..6135 7f07 +6136..6137 7f0b +6138 7f0f +6139..6140 7f11 +6141 7f17 +6142 7f19 +6143 7f1c +6144 7f1b +6145 7f1f +6146..6152 7f21 +6153..6156 7f2a +6157..6161 7f2f +6162 7f35 +6163 5e7a +6164 757f +6165 5ddb +6166 753e +6167 9095 +6168 738e +6169 7391 +6170 73ae +6171 73a2 +6172 739f +6173 73cf +6174 73c2 +6175 73d1 +6176 73b7 +6177 73b3 +6178 73c0 +6179 73c9 +6180 73c8 +6181 73e5 +6182 73d9 +6183 987c +6184 740a +6185 73e9 +6186 73e7 +6187 73de +6188 73ba +6189 73f2 +6190 740f +6191 742a +6192 745b +6193 7426 +6194 7425 +6195 7428 +6196 7430 +6197 742e +6198 742c +6199 741b +6200 741a +6201 7441 +6202 745c +6203 7457 +6204 7455 +6205 7459 +6206 7477 +6207 746d +6208 747e +6209 749c +6210 748e +6211..6212 7480 +6213 7487 +6214 748b +6215 749e +6216..6217 74a8 +6218 7490 +6219 74a7 +6220 74d2 +6221 74ba +6222..6224 97ea +6225 674c +6226 6753 +6227 675e +6228 6748 +6229 6769 +6230 67a5 +6231 6787 +6232 676a +6233 6773 +6234 6798 +6235 67a7 +6236 6775 +6237 67a8 +6238 679e +6239 67ad +6240 678b +6241 6777 +6242 677c +6243 67f0 +6244 6809 +6245 67d8 +6246 680a +6247 67e9 +6248 67b0 +6249 680c +6250 67d9 +6251 67b5 +6252 67da +6253 67b3 +6254 67dd +6255 6800 +6256 67c3 +6257 67b8 +6258 67e2 +6259 680e +6260 67c1 +6261 67fd +6262..6263 6832 +6264..6265 6860 +6266 684e +6267 6862 +6268 6844 +6269 6864 +6270 6883 +6271 681d +6272 6855 +6273 6866 +6274 6841 +6275 6867 +6276 6840 +6277 683e +6278 684a +6279 6849 +6280 6829 +6281 68b5 +6282 688f +6283 6874 +6284 6877 +6285 6893 +6286 686b +6287 68c2 +6288 696e +6289 68fc +6290..6291 691f +6292 68f9 +6293 6924 +6294 68f0 +6295 690b +6296 6901 +6297 6957 +6298 68e3 +6299 6910 +6300 6971 +6301 6939 +6302 6960 +6303 6942 +6304 695d +6305 6984 +6306 696b +6307 6980 +6308 6998 +6309 6978 +6310 6934 +6311 69cc +6312..6313 6987 +6314 69ce +6315 6989 +6316 6966 +6317 6963 +6318 6979 +6319 699b +6320 69a7 +6321 69bb +6322 69ab +6323 69ad +6324 69d4 +6325 69b1 +6326 69c1 +6327 69ca +6328 69df +6329 6995 +6330 69e0 +6331 698d +6332 69ff +6333 6a2f +6334 69ed +6335..6336 6a17 +6337 6a65 +6338 69f2 +6339 6a44 +6340 6a3e +6341 6aa0 +6342 6a50 +6343 6a5b +6344 6a35 +6345 6a8e +6346 6a79 +6347 6a3d +6348 6a28 +6349 6a58 +6350 6a7c +6351 6a91 +6352 6a90 +6353 6aa9 +6354 6a97 +6355 6aab +6356 7337 +6357 7352 +6358..6359 6b81 +6360 6b87 +6361 6b84 +6362..6363 6b92 +6364 6b8d +6365..6366 6b9a +6367 6ba1 +6368 6baa +6369 8f6b +6370 8f6d +6371..6373 8f71 +6374..6375 8f75 +6376 8f78 +6377 8f77 +6378..6379 8f79 +6380 8f7c +6381 8f7e +6382..6383 8f81 +6384 8f84 +6385 8f87 +6386 8f8b +6387..6389 8f8d +6390 8f98 +6391 8f9a +6392 8ece +6393 620b +6394 6217 +6395 621b +6396 621f +6397 6222 +6398 6221 +6399 6225 +6400 6224 +6401 622c +6402 81e7 +6403 74ef +6404 74f4 +6405 74ff +6406 750f +6407 7511 +6408 7513 +6409 6534 +6410..6412 65ee +6413 660a +6414 6619 +6415 6772 +6416 6603 +6417 6615 +6418 6600 +6419 7085 +6420 66f7 +6421 661d +6422 6634 +6423 6631 +6424 6636 +6425 6635 +6426 8006 +6427 665f +6428 6654 +6429 6641 +6430 664f +6431 6656 +6432 6661 +6433 6657 +6434 6677 +6435 6684 +6436 668c +6437 66a7 +6438 669d +6439 66be +6440..6441 66db +6442 66e6 +6443 66e9 +6444..6445 8d32 +6446 8d36 +6447 8d3b +6448 8d3d +6449 8d40 +6450..6451 8d45 +6452..6453 8d48 +6454 8d47 +6455 8d4d +6456 8d55 +6457 8d59 +6458 89c7 +6459..6461 89ca +6462..6465 89ce +6466 726e +6467 729f +6468 725d +6469 7266 +6470 726f +6471..6472 727e +6473 7284 +6474 728b +6475 728d +6476 728f +6477 7292 +6478 6308 +6479 6332 +6480 63b0 +6481 643f +6482 64d8 +6483 8004 +6484 6bea +6485 6bf3 +6486 6bfd +6487 6bf5 +6488 6bf9 +6489 6c05 +6490 6c07 +6491 6c06 +6492 6c0d +6493 6c15 +6494..6496 6c18 +6497 6c21 +6498 6c29 +6499 6c24 +6500 6c2a +6501 6c32 +6502 6535 +6503 6555 +6504 656b +6505 724d +6506 7252 +6507 7256 +6508 7230 +6509 8662 +6510 5216 +6511 809f +6512 809c +6513 8093 +6514 80bc +6515 670a +6516 80bd +6517 80b1 +6518 80ab +6519 80ad +6520 80b4 +6521 80b7 +6522..6525 80e7 +6526 80db +6527 80c2 +6528 80c4 +6529 80d9 +6530 80cd +6531 80d7 +6532 6710 +6533 80dd +6534 80eb +6535 80f1 +6536 80f4 +6537 80ed +6538..6539 810d +6540 80f2 +6541 80fc +6542 6715 +6543 8112 +6544 8c5a +6545 8136 +6546 811e +6547 812c +6548 8118 +6549 8132 +6550 8148 +6551 814c +6552 8153 +6553 8174 +6554..6555 8159 +6556 8171 +6557 8160 +6558 8169 +6559..6560 817c +6561 816d +6562 8167 +6563 584d +6564 5ab5 +6565 8188 +6566 8182 +6567 8191 +6568 6ed5 +6569 81a3 +6570 81aa +6571 81cc +6572 6726 +6573 81ca +6574 81bb +6575 81c1 +6576 81a6 +6577 6b24 +6578 6b37 +6579 6b39 +6580 6b43 +6581 6b46 +6582 6b59 +6583..6585 98d1 +6586 98d5 +6587..6588 98d9 +6589 6bb3 +6590 5f40 +6591 6bc2 +6592 89f3 +6593 6590 +6594 9f51 +6595 6593 +6596 65bc +6597 65c6 +6598 65c4 +6599 65c3 +6600 65cc +6601 65ce +6602 65d2 +6603 65d6 +6604 7080 +6605 709c +6606 7096 +6607 709d +6608 70bb +6609 70c0 +6610 70b7 +6611 70ab +6612 70b1 +6613 70e8 +6614 70ca +6615 7110 +6616 7113 +6617 7116 +6618 712f +6619 7131 +6620 7173 +6621 715c +6622 7168 +6623 7145 +6624 7172 +6625 714a +6626 7178 +6627 717a +6628 7198 +6629 71b3 +6630 71b5 +6631 71a8 +6632 71a0 +6633 71e0 +6634 71d4 +6635 71e7 +6636 71f9 +6637 721d +6638 7228 +6639 706c +6640 7118 +6641 7166 +6642 71b9 +6643 623e +6644 623d +6645 6243 +6646..6647 6248 +6648 793b +6649 7940 +6650 7946 +6651 7949 +6652..6653 795b +6654 7953 +6655 795a +6656 7962 +6657 7957 +6658 7960 +6659 796f +6660 7967 +6661 797a +6662 7985 +6663 798a +6664 799a +6665 79a7 +6666 79b3 +6667 5fd1 +6668 5fd0 +6669 603c +6670 605d +6671 605a +6672 6067 +6673 6041 +6674 6059 +6675 6063 +6676 60ab +6677 6106 +6678 610d +6679 615d +6680 61a9 +6681 619d +6682 61cb +6683 61d1 +6684 6206 +6685 8080 +6686 807f +6687 6c93 +6688 6cf6 +6689 6dfc +6690 77f6 +6691 77f8 +6692 7800 +6693 7809 +6694..6695 7817 +6696 7811 +6697 65ab +6698 782d +6699..6700 781c +6701..6703 7839 +6704 781f +6705 783c +6706 7825 +6707 782c +6708 7823 +6709 7829 +6710 784e +6711 786d +6712..6713 7856 +6714 7826 +6715 7850 +6716 7847 +6717 784c +6718 786a +6719 789b +6720 7893 +6721 789a +6722 7887 +6723 789c +6724 78a1 +6725 78a3 +6726 78b2 +6727 78b9 +6728 78a5 +6729 78d4 +6730 78d9 +6731 78c9 +6732 78ec +6733 78f2 +6734 7905 +6735 78f4 +6736 7913 +6737 7924 +6738 791e +6739 7934 +6740 9f9b +6741 9ef9 +6742..6743 9efb +6744 76f1 +6745 7704 +6746 770d +6747 76f9 +6748..6749 7707 +6750 771a +6751 7722 +6752 7719 +6753 772d +6754 7726 +6755 7735 +6756 7738 +6757..6758 7750 +6759 7747 +6760 7743 +6761 775a +6762 7768 +6763 7762 +6764 7765 +6765 777f +6766 778d +6767 777d +6768 7780 +6769 778c +6770 7791 +6771..6772 779f +6773 77b0 +6774 77b5 +6775 77bd +6776 753a +6777 7540 +6778 754e +6779 754b +6780 7548 +6781 755b +6782 7572 +6783 7579 +6784 7583 +6785 7f58 +6786 7f61 +6787 7f5f +6788 8a48 +6789 7f68 +6790 7f74 +6791 7f71 +6792 7f79 +6793 7f81 +6794 7f7e +6795 76cd +6796 76e5 +6797 8832 +6798..6800 9485 +6801 948b +6802 948a +6803..6804 948c +6805..6806 948f +6807 9494 +6808 9497 +6809 9495 +6810..6812 949a +6813..6814 94a3 +6815 94ab +6816 94aa +6817 94ad +6818 94ac +6819..6820 94af +6821 94b2 +6822 94b4 +6823..6827 94b6 +6828..6829 94bc +6830 94bf +6831 94c4 +6832..6838 94c8 +6839..6841 94d0 +6842..6844 94d5 +6845 94d9 +6846 94d8 +6847 94db +6848..6850 94de +6851 94e2 +6852..6853 94e4 +6854..6855 94e7 +6856 94ea +6857 94e9 +6858 94eb +6859..6860 94ee +6861..6863 94f3 +6864 94f7 +6865 94f9 +6866..6867 94fc +6868 94ff +6869 9503 +6870 9502 +6871..6872 9506 +6873..6874 9509 +6875..6877 950d +6878..6882 9512 +6883 9518 +6884 951b +6885..6887 951d +6888 9522 +6889..6890 952a +6891 9529 +6892 952c +6893..6894 9531 +6895 9534 +6896..6898 9536 +6899 953c +6900..6901 953e +6902 9542 +6903 9535 +6904..6906 9544 +6907 9549 +6908 954c +6909..6910 954e +6911..6913 9552 +6914..6917 9556 +6918 955b +6919..6920 955e +6921 955d +6922..6923 9561 +6924..6932 9564 +6933 956f +6934..6936 9571 +6937 953a +6938 77e7 +6939 77ec +6940 96c9 +6941 79d5 +6942 79ed +6943 79e3 +6944 79eb +6945 7a06 +6946 5d47 +6947 7a03 +6948 7a02 +6949 7a1e +6950 7a14 +6951 7a39 +6952 7a37 +6953 7a51 +6954 9ecf +6955 99a5 +6956 7a70 +6957 7688 +6958 768e +6959 7693 +6960 7699 +6961 76a4 +6962 74de +6963 74e0 +6964 752c +6965 9e20 +6966 9e22 +6967..6971 9e28 +6972 9e32 +6973 9e31 +6974 9e36 +6975 9e38 +6976 9e37 +6977..6978 9e39 +6979 9e3e +6980..6981 9e41 +6982 9e44 +6983..6986 9e46 +6987..6988 9e4b +6989 9e4e +6990 9e51 +6991 9e55 +6992 9e57 +6993..6995 9e5a +6996 9e5e +6997 9e63 +6998..7004 9e66 +7005 9e71 +7006 9e6d +7007 9e73 +7008 7592 +7009 7594 +7010 7596 +7011 75a0 +7012 759d +7013 75ac +7014 75a3 +7015..7016 75b3 +7017 75b8 +7018 75c4 +7019 75b1 +7020 75b0 +7021 75c3 +7022 75c2 +7023 75d6 +7024 75cd +7025 75e3 +7026 75e8 +7027 75e6 +7028 75e4 +7029 75eb +7030 75e7 +7031 7603 +7032 75f1 +7033 75fc +7034 75ff +7035 7610 +7036 7600 +7037 7605 +7038 760c +7039 7617 +7040 760a +7041 7625 +7042 7618 +7043 7615 +7044 7619 +7045 761b +7046 763c +7047 7622 +7048 7620 +7049 7640 +7050 762d +7051 7630 +7052 763f +7053 7635 +7054 7643 +7055 763e +7056 7633 +7057 764d +7058 765e +7059 7654 +7060 765c +7061 7656 +7062 766b +7063 766f +7064 7fca +7065 7ae6 +7066..7067 7a78 +7068 7a80 +7069 7a86 +7070 7a88 +7071 7a95 +7072 7aa6 +7073 7aa0 +7074 7aac +7075 7aa8 +7076 7aad +7077 7ab3 +7078 8864 +7079 8869 +7080 8872 +7081 887d +7082 887f +7083 8882 +7084 88a2 +7085 88c6 +7086 88b7 +7087 88bc +7088 88c9 +7089 88e2 +7090 88ce +7091 88e3 +7092 88e5 +7093 88f1 +7094 891a +7095 88fc +7096 88e8 +7097 88fe +7098 88f0 +7099 8921 +7100 8919 +7101 8913 +7102 891b +7103 890a +7104 8934 +7105 892b +7106 8936 +7107 8941 +7108 8966 +7109 897b +7110 758b +7111 80e5 +7112 76b2 +7113 76b4 +7114 77dc +7115 8012 +7116 8014 +7117 8016 +7118 801c +7119 8020 +7120 8022 +7121..7123 8025 +7124 8029 +7125 8028 +7126 8031 +7127 800b +7128 8035 +7129 8043 +7130 8046 +7131 804d +7132 8052 +7133 8069 +7134 8071 +7135 8983 +7136 9878 +7137 9880 +7138 9883 +7139 9889 +7140..7141 988c +7142 988f +7143 9894 +7144..7145 989a +7146..7147 989e +7148..7149 98a1 +7150..7151 98a5 +7152 864d +7153 8654 +7154 866c +7155 866e +7156 867f +7157 867a +7158 867c +7159 867b +7160 86a8 +7161 868d +7162 868b +7163 86ac +7164 869d +7165 86a7 +7166 86a3 +7167 86aa +7168 8693 +7169 86a9 +7170 86b6 +7171 86c4 +7172 86b5 +7173 86ce +7174 86b0 +7175 86ba +7176 86b1 +7177 86af +7178 86c9 +7179 86cf +7180 86b4 +7181 86e9 +7182..7183 86f1 +7184 86ed +7185 86f3 +7186 86d0 +7187 8713 +7188 86de +7189 86f4 +7190 86df +7191 86d8 +7192 86d1 +7193 8703 +7194 8707 +7195 86f8 +7196 8708 +7197 870a +7198 870d +7199 8709 +7200 8723 +7201 873b +7202 871e +7203 8725 +7204 872e +7205 871a +7206 873e +7207 8748 +7208 8734 +7209 8731 +7210 8729 +7211 8737 +7212 873f +7213 8782 +7214 8722 +7215..7216 877d +7217 877b +7218 8760 +7219 8770 +7220 874c +7221 876e +7222 878b +7223 8753 +7224 8763 +7225 877c +7226 8764 +7227 8759 +7228 8765 +7229 8793 +7230 87af +7231 87a8 +7232 87d2 +7233 87c6 +7234 8788 +7235 8785 +7236 87ad +7237 8797 +7238 8783 +7239 87ab +7240 87e5 +7241 87ac +7242 87b5 +7243 87b3 +7244 87cb +7245 87d3 +7246 87bd +7247 87d1 +7248 87c0 +7249 87ca +7250 87db +7251 87ea +7252 87e0 +7253 87ee +7254 8816 +7255 8813 +7256 87fe +7257 880a +7258 881b +7259 8821 +7260 8839 +7261 883c +7262 7f36 +7263 7f42 +7264..7265 7f44 +7266 8210 +7267 7afa +7268 7afd +7269 7b08 +7270..7271 7b03 +7272 7b15 +7273 7b0a +7274 7b2b +7275 7b0f +7276 7b47 +7277 7b38 +7278 7b2a +7279 7b19 +7280 7b2e +7281 7b31 +7282 7b20 +7283 7b25 +7284 7b24 +7285 7b33 +7286 7b3e +7287 7b1e +7288 7b58 +7289 7b5a +7290 7b45 +7291 7b75 +7292 7b4c +7293 7b5d +7294 7b60 +7295 7b6e +7296 7b7b +7297 7b62 +7298 7b72 +7299 7b71 +7300 7b90 +7301..7302 7ba6 +7303 7bb8 +7304 7bac +7305 7b9d +7306 7ba8 +7307 7b85 +7308 7baa +7309 7b9c +7310 7ba2 +7311 7bab +7312 7bb4 +7313 7bd1 +7314 7bc1 +7315 7bcc +7316 7bdd +7317 7bda +7318..7319 7be5 +7320 7bea +7321 7c0c +7322 7bfe +7323 7bfc +7324 7c0f +7325 7c16 +7326 7c0b +7327 7c1f +7328 7c2a +7329 7c26 +7330 7c38 +7331 7c41 +7332 7c40 +7333 81fe +7334..7335 8201 +7336 8204 +7337 81ec +7338 8844 +7339..7341 8221 +7342 822d +7343 822f +7344 8228 +7345 822b +7346 8238 +7347 823b +7348..7349 8233 +7350 823e +7351 8244 +7352 8249 +7353 824b +7354 824f +7355 825a +7356 825f +7357 8268 +7358 887e +7359 8885 +7360 8888 +7361 88d8 +7362 88df +7363 895e +7364 7f9d +7365 7f9f +7366 7fa7 +7367..7368 7faf +7369 7fb2 +7370 7c7c +7371 6549 +7372 7c91 +7373 7c9d +7374 7c9c +7375 7c9e +7376 7ca2 +7377 7cb2 +7378..7379 7cbc +7380 7cc1 +7381 7cc7 +7382..7383 7ccc +7384 7cc8 +7385 7cc5 +7386 7cd7 +7387 7ce8 +7388 826e +7389 66a8 +7390 7fbf +7391 7fce +7392 7fd5 +7393 7fe5 +7394 7fe1 +7395 7fe6 +7396 7fe9 +7397 7fee +7398 7ff3 +7399 7cf8 +7400 7d77 +7401 7da6 +7402 7dae +7403 7e47 +7404 7e9b +7405 9eb8 +7406 9eb4 +7407 8d73 +7408 8d84 +7409 8d94 +7410 8d91 +7411 8db1 +7412 8d67 +7413 8d6d +7414 8c47 +7415 8c49 +7416 914a +7417 9150 +7418..7419 914e +7420 9164 +7421 9162 +7422 9161 +7423 9170 +7424 9169 +7425 916f +7426..7427 917d +7428 9172 +7429 9174 +7430 9179 +7431 918c +7432 9185 +7433 9190 +7434 918d +7435 9191 +7436..7437 91a2 +7438 91aa +7439..7441 91ad +7442 91b5 +7443 91b4 +7444 91ba +7445 8c55 +7446 9e7e +7447 8db8 +7448 8deb +7449 8e05 +7450 8e59 +7451 8e69 +7452 8db5 +7453 8dbf +7454 8dbc +7455 8dba +7456 8dc4 +7457..7458 8dd6 +7459 8dda +7460 8dde +7461..7462 8dce +7463 8ddb +7464 8dc6 +7465 8dec +7466..7467 8df7 +7468 8de3 +7469 8df9 +7470 8dfb +7471 8de4 +7472 8e09 +7473 8dfd +7474 8e14 +7475 8e1d +7476 8e1f +7477 8e2c +7478 8e2e +7479 8e23 +7480 8e2f +7481 8e3a +7482 8e40 +7483 8e39 +7484 8e35 +7485 8e3d +7486 8e31 +7487 8e49 +7488..7489 8e41 +7490..7491 8e51 +7492 8e4a +7493 8e70 +7494 8e76 +7495 8e7c +7496 8e6f +7497 8e74 +7498 8e85 +7499 8e8f +7500 8e94 +7501 8e90 +7502 8e9c +7503 8e9e +7504 8c78 +7505 8c82 +7506 8c8a +7507 8c85 +7508 8c98 +7509 8c94 +7510 659b +7511 89d6 +7512 89de +7513 89da +7514 89dc +7515 89e5 +7516 89eb +7517 89ef +7518 8a3e +7519 8b26 +7520 9753 +7521 96e9 +7522 96f3 +7523 96ef +7524 9706 +7525 9701 +7526 9708 +7527 970f +7528 970e +7529 972a +7530 972d +7531 9730 +7532 973e +7533 9f80 +7534 9f83 +7535..7540 9f85 +7541 9f8c +7542 9efe +7543 9f0b +7544 9f0d +7545 96b9 +7546..7547 96bc +7548 96ce +7549 96d2 +7550 77bf +7551 96e0 +7552 928e +7553 92ae +7554 92c8 +7555 933e +7556 936a +7557 93ca +7558 938f +7559 943e +7560 946b +7561 9c7f +7562 9c82 +7563..7566 9c85 +7567 7a23 +7568 9c8b +7569 9c8e +7570..7572 9c90 +7573..7574 9c94 +7575..7576 9c9a +7577..7582 9c9e +7583..7587 9ca5 +7588 9cab +7589..7590 9cad +7591..7598 9cb0 +7599..7602 9cba +7603..7606 9cc4 +7607..7613 9cca +7614..7616 9cd3 +7617..7619 9cd7 +7620..7621 9cdc +7622 9cdf +7623 9ce2 +7624 977c +7625 9785 +7626..7627 9791 +7628 9794 +7629 97af +7630 97ab +7631 97a3 +7632 97b2 +7633 97b4 +7634 9ab1 +7635 9ab0 +7636 9ab7 +7637 9e58 +7638 9ab6 +7639 9aba +7640 9abc +7641 9ac1 +7642 9ac0 +7643 9ac5 +7644 9ac2 +7645..7646 9acb +7647 9ad1 +7648 9b45 +7649 9b43 +7650 9b47 +7651 9b49 +7652 9b48 +7653 9b4d +7654 9b51 +7655 98e8 +7656 990d +7657 992e +7658 9955 +7659 9954 +7660 9adf +7661 9ae1 +7662 9ae6 +7663 9aef +7664 9aeb +7665 9afb +7666 9aed +7667 9af9 +7668 9b08 +7669 9b0f +7670 9b13 +7671 9b1f +7672 9b23 +7673..7674 9ebd +7675 7e3b +7676 9e82 +7677..7678 9e87 +7679 9e8b +7680 9e92 +7681 93d6 +7682 9e9d +7683 9e9f +7684..7686 9edb +7687 9ee0 +7688 9edf +7689 9ee2 +7690 9ee9 +7691 9ee7 +7692 9ee5 +7693 9eea +7694 9eef +7695 9f22 +7696 9f2c +7697 9f2f +7698 9f39 +7699 9f37 +7700..7701 9f3d +7702 9f44 +7703 3007 +7704 /GB1.106.vert +7706 /GB1.189.vert +7707 /GB1.275.vert +7708 /GB1.141.vert +7709 /GB1.320.vert +7710 /GB1.322.vert +7711 /GB1.355.vert +7717 769a +7718 85f9 +7719 7919 +7720 611b +7721 9aaf +7722 8956 +7723 58e9 +7724 7f77 +7725 64fa +7726 6557 +7727 9812 +7728 8fa6 +7729 7d46 +7730 5e6b +7731 7d81 +7732 938a +7733 8b17 +7734 98fd +7735 5bf6 +7736 5831 +7737 9b91 +7738 8f29 +7739 8c9d +7740 92c7 +7741 72fd +7742 5099 +7743 618a +7744 7db3 +7745 7b46 +7746 7562 +7747 6583 +7748 5e63 +7749 9589 +7750 908a +7751 7de8 +7752 8cb6 +7753 8b8a +7754 8faf +7755 8fae +7756 6a19 +7757 9c49 +7758 765f +7759 7015 +7760 6ff1 +7761 8cd3 +7762 64ef +7763 9905 +7764 64a5 +7765 9262 +7766 9251 +7767 99c1 +7768 88dc +7769 8ca1 +7770 53c3 +7771 8836 +7772 6b98 +7773 615a +7774 6158 +7775 71e6 +7776 84bc +7777 8259 +7778 5009 +7779 6ec4 +7780 53a0 +7781 5074 +7782 6e2c +7783 5c64 +7784 8a6b +7785 6519 +7786 647b +7787 87ec +7788 995e +7789 8b92 +7790 7e8f +7791 93df +7792 7523 +7793 95e1 +7794 986b +7795 5834 +7796 5617 +7797 9577 +7798 511f +7799 8178 +7800 5ee0 +7801 66a2 +7802 9214 +7803 8eca +7804 5fb9 +7805 5875 +7806 9673 +7807 896f +7808 7a31 +7809 61f2 +7810 8aa0 +7811 9a01 +7812 9072 +7813 99b3 +7814 9f52 +7815 71be +7816 885d +7817 87f2 +7818 5bf5 +7819 7587 +7820 8e8a +7821 7c4c +7822 7da2 +7823 919c +7824 92e4 +7825 96db +7826 790e +7827 5132 +7828 89f8 +7829 8655 +7830 50b3 +7831 7621 +7832 95d6 +7833 5275 +7834 9318 +7835 7d14 +7836 7dbd +7837 8fad +7838 8a5e +7839 8cdc +7840 8070 +7841 5f9e +7842 53e2 +7843 8ea5 +7844 7ac4 +7845 932f +7846 9054 +7847 5e36 +7848 8cb8 +7849 64d4 +7850 55ae +7851 9132 +7852 64a3 +7853 81bd +7854 619a +7855 8a95 +7856 5f48 +7857 7576 +7858 64cb +7859 9ee8 +7860 8569 +7861 6a94 +7862 6417 +7863 5cf6 +7864 79b1 +7865 5c0e +7866 71c8 +7867 9127 +7868 6575 +7869 6ecc +7870 905e +7871 7de0 +7872 985b +7873 9ede +7874 588a +7875 96fb +7876 6fb1 +7877 91e3 +7878 8abf +7879 8adc +7880 91d8 +7881 9802 +7882 9320 +7883 8a02 +7884 6771 +7885 52d5 +7886 68df +7887 51cd +7888 9b25 +7889 72a2 +7890 7368 +7891 8b80 +7892 8ced +7893 934d +7894 935b +7895 65b7 +7896 7dde +7897 968a +7898 5c0d +7899 5678 +7900 9813 +7901 920d +7902 596a +7903 58ae +7904 9d5d +7905 984d +7906 8a1b +7907 60e1 +7908 9913 +7909 5152 +7910 723e +7911 990c +7912 8cb3 +7913 767c +7914 7f70 +7915 95a5 +7916 792c +7917 91e9 +7918 7169 +7919 7bc4 +7920 8ca9 +7921 98ef +7922 8a2a +7923 7d21 +7924 98db +7925 8ab9 +7926 5ee2 +7927 8cbb +7928 7d1b +7929 58b3 +7930 596e +7931 61a4 +7932 7cde +7933 8c50 +7934 6953 +7935 92d2 +7936 98a8 +7937 760b +7938 99ae +7939 7e2b +7940 8af7 +7941 9cf3 +7942 819a +7943 8f3b +7944 64ab +7945 8f14 +7946 8ce6 +7947 5fa9 +7948 8ca0 +7949 8a03 +7950 5a66 +7951 7e1b +7952 8a72 +7953 9223 +7954 84cb +7955 5e79 +7956 8d95 +7957 8d1b +7958 5ca1 +7959 525b +7960 92fc +7961 7db1 +7962 5d17 +7963 93ac +7964 64f1 +7965 9d3f +7966 95a3 +7967 927b +7968 500b +7969 7d66 +7970 9f94 +7971 978f +7972 8ca2 +7973 920e +7974 6e9d +7975 69cb +7976 8cfc +7977 8831 +7978 9867 +7979 526e +7980 95dc +7981 89c0 +7982 9928 +7983 6163 +7984 8cab +7985 5ee3 +7986 898f +7987 6b78 +7988 9f9c +7989 95a8 +7990 8ecc +7991 8a6d +7992 6ac3 +7993 8cb4 +7994 528a +7995 8f25 +7996 934b +7997 570b +7998 904e +7999 99ed +8000 97d3 +8001 6f22 +8002 865f +8003 95a1 +8004 9db4 +8005 8cc0 +8006 8f5f +8007 9d3b +8008 7d05 +8009 58fa +8010 8b77 +8011 6eec +8012 5629 +8013 83ef +8014 756b +8015 5283 +8016 8a71 +8017 61f7 +8018 58de +8019 6b61 +8020 74b0 +8021 9084 +8022 7de9 +8023 8b0a +8024 63ee +8025 8f1d +8026 8cc4 +8027 7a62 +8028 6703 +8029 71f4 +8030 532f +8031 8af1 +8032 8aa8 +8033 7e6a +8034 8477 +8035 6e3e +8036 7372 +8037 8ca8 +8038 798d +8039 64ca +8040 6a5f +8041 7a4d +8042 9951 +8043 8b4f +8044 9dc4 +8045 7e3e +8046 7ddd +8047 6975 +8048 8f2f +8049 7d1a +8050 64e0 +8051 5e7e +8052 858a +8053 5291 +8054 6fdf +8055 8a08 +8056 8a18 +8057 969b +8058 7e7c +8059 7d00 +8060 593e +8061 83a2 +8062 9830 +8063 8cc8 +8064 9240 +8065 50f9 +8066 99d5 +8067 6bb2 +8068 76e3 +8069 5805 +8070 7b8b +8071 9593 +8072 8271 +8073 7dd8 +8074 7e6d +8075 6aa2 +8076 9e7c +8077 63c0 +8078 64bf +8079 7c21 +8080 5109 +8081 85a6 +8082 6abb +8083 9452 +8084 8e10 +8085 8ce4 +8086 898b +8087 9375 +8088 8266 +8089 528d +8090 991e +8091 6f38 +8092 6ffa +8093 6f97 +8094 5c07 +8095 6f3f +8096 8523 +8097 69f3 +8098 596c +8099 8b1b +8100 91ac +8101 81a0 +8102 6f86 +8103 9a55 +8104 5b0c +8105 652a +8106 9278 +8107 77ef +8108 50e5 +8109 9903 +8110 7e73 +8111 7d5e +8112 8f4e +8113 8f03 +8114 968e +8115 7bc0 +8116 6f54 +8117 7d50 +8118 8aa1 +8119 7dca +8120 9326 +8121 50c5 +8122 8b39 +8123 9032 +8124 71fc +8125 76e1 +8126 52c1 +8127 8396 +8128 9be8 +8129 9a5a +8130 7d93 +8131 9838 +8132 93e1 +8133 5f91 +8134 75d9 +8135 7af6 +8136 7cfe +8137 820a +8138 99d2 +8139 8209 +8140 64da +8141 92f8 +8142 61fc +8143 5287 +8144 9d51 +8145 7d79 +8146 89ba +8147 8a23 +8148 7d76 +8149 921e +8150 8ecd +8151 99ff +8152 958b +8153 51f1 +8154 9846 +8155 6bbb +8156 8ab2 +8157 58be +8158 61c7 +8159 6473 +8160 5eab +8161 8932 +8162 8a87 +8163 584a +8164 5108 +8165 5bec +8166 7926 +8167 66e0 +8168 8667 +8169 5dcb +8170 7aba +8171 994b +8172 6f70 +8173 64f4 +8174 95ca +8175 881f +8176 81d8 +8177 840a +8178 4f86 +8179 8cf4 +8180 85cd +8181 6b04 +8182 6514 +8183 7c43 +8184 95cc +8185 862d +8186 703e +8187 8b95 +8188 652c +8189 89bd +8190 61f6 +8191 7e9c +8192 721b +8193 6feb +8194 6488 +8195 52de +8196 6f87 +8197 6a02 +8198 9433 +8199 58d8 +8200 985e +8201 7c6c +8202 96e2 +8203 7055 +8204 88cf +8205 9bc9 +8206 79ae +8207 9e97 +8208 53b2 +8209 52f5 +8210 792b +8211 6b77 +8212 701d +8213 96b8 +8214 5006 +8215 806f +8216 84ee +8217 9023 +8218 942e +8219 6190 +8220 6f23 +8221 7c3e +8222 6582 +8223 81c9 +8224 93c8 +8225 6200 +8226 7149 +8227 7df4 +8228 7ce7 +8229 5169 +8230 8f1b +8231 8ad2 +8232 7642 +8233 907c +8234 9410 +8235 7375 +8236 81e8 +8237 9130 +8238 9c57 +8239 8cc3 +8240 9f61 +8241 9234 +8242 9748 +8243 5dba +8244 9818 +8245 993e +8246 5289 +8247 9f8d +8248 807e +8249 56a8 +8250 7c60 +8251 58df +8252 650f +8253 96b4 +8254 6a13 +8255 5a41 +8256 645f +8257 7c0d +8258 8606 +8259 76e7 +8260 9871 +8261 5eec +8262 7210 +8263 64c4 +8264 6ef7 +8265 865c +8266 9b6f +8267 8cc2 +8268 9332 +8269 9678 +8270 9a62 +8271 92c1 +8272 5c62 +8273 7e37 +8274 616e +8275 6ffe +8276 7dd1 +8277 5dd2 +8278 6523 +8279 5b7f +8280 7064 +8281 4e82 +8282 6384 +8283 8f2a +8284 502b +8285 4f96 +8286 6dea +8287 7db8 +8288 8ad6 +8289 863f +8290 7f85 +8291 908f +8292 947c +8293 7c6e +8294 9a3e +8295 99f1 +8296 7d61 +8297 5abd +8298 746a +8299 78bc +8300 879e +8301 99ac +8302 99e1 +8303 55ce +8304 8cb7 +8305 9ea5 +8306 8ce3 +8307 9081 +8308 779e +8309 9945 +8310 883b +8311 6eff +8312 8b3e +8313 9328 +8314 925a +8315 8cbf +8316 9382 +8317 9580 +8318 60b6 +8319 5011 +8320 9333 +8321 5922 +8322 8b0e +8323 5f4c +8324 8993 +8325 7dbf +8326 7dec +8327 5edf +8328 6ec5 +8329 61ab +8330 95a9 +8331 9cf4 +8332 9298 +8333 8b2c +8334 8b00 +8335 755d +8336 9209 +8337 7d0d +8338 96e3 +8339 6493 +8340 8166 +8341 60f1 +8342 9b27 +8343 9912 +8344 64ec +8345 81a9 +8346 6506 +8347 91c0 +8348 9ce5 +8349 8076 +8350 5699 +8351 9477 +8352 93b3 +8353 6ab8 +8354 7370 +8355 5be7 +8356 64f0 +8357 6fd8 +8358 9215 +8359 7d10 +8360 81bf +8361 6fc3 +8362 8fb2 +8363 7627 +8364 8afe +8365 6b50 +8366 9dd7 +8367 6bc6 +8368 5614 +8369 6f1a +8370 76e4 +8371 9f90 +8372 8ce0 +8373 5674 +8374 9d6c +8375 9a19 +8376 98c4 +8377 983b +8378 8ca7 +8379 860b +8380 6191 +8381 8a55 +8382 6f51 +8383 9817 +8384 64b2 +8385 92ea +8386 50d5 +8387 6a38 +8388 8b5c +8389 81cd +8390 9f4a +8391 9a0e +8392 8c48 +8393 5553 +8394 6c23 +8395 8a16 +8396 727d +8397 91fa +8398 925b +8399 9077 +8400 7c3d +8401 8b19 +8402 9322 +8403 9257 +8404 6dfa +8405 8b74 +8406 5879 +8407 69cd +8408 55c6 +8409 58bb +8410 8594 +8411 6436 +8412 936c +8413 6a4b +8414 55ac +8415 50d1 +8416 7ff9 +8417 7ac5 +8418 7aca +8419 6b3d +8420 89aa +8421 5be2 +8422 8f15 +8423 6c2b +8424 50be +8425 9803 +8426 8acb +8427 6176 +8428 74ca +8429 7aae +8430 8da8 +8431 5340 +8432 8ec0 +8433 9a45 +8434 9f72 +8435 9874 +8436 6b0a +8437 52f8 +8438 9d72 +8439 78ba +8440 8b93 +8441 9952 +8442 64fe +8443 7e5e +8444 71b1 +8445 97cc +8446 8a8d +8447 7d09 +8448 69ae +8449 7d68 +8450 8edf +8451 92ed +8452 958f +8453 6f64 +8454 7051 +8455 85a9 +8456 9c13 +8457 8cfd +8458 5098 +8459 55aa +8460 9a37 +8461 6383 +8462 6f80 +8463 6bba +8464 7d17 +8465 7be9 +8466 66ec +8467 9583 +8468 965d +8469 8d0d +8470 7e55 +8471 50b7 +8472 8cde +8473 71d2 +8474 7d39 +8475 8cd2 +8476 6368 +8477 651d +8478 61fe +8479 8a2d +8480 7d33 +8481 5be9 +8482 5b38 +8483 814e +8484 6ef2 +8485 8072 +8486 7e69 +8487 52dd +8488 8056 +8489 5e2b +8490 7345 +8491 6fd5 +8492 8a69 +8493 6642 +8494 8755 +8495 5be6 +8496 8b58 +8497 99db +8498 52e2 +8499 9069 +8500 91cb +8501 98fe +8502 8996 +8503 8a66 +8504 58fd +8505 7378 +8506 6a1e +8507 8f38 +8508 66f8 +8509 8d16 +8510 5c6c +8511 8853 +8512 6a39 +8513 7aea +8514 6578 +8515 5e25 +8516 96d9 +8517 8ab0 +8518 9806 +8519 8aac +8520 78a9 +8521 720d +8522 7d72 +8523 98fc +8524 9b06 +8525 8073 +8526 616b +8527 980c +8528 8a1f +8529 8aa6 +8530 64fb +8531 8607 +8532 8a34 +8533 8085 +8534 96d6 +8535 96a8 +8536 7d8f +8537 6b72 +8538 5b6b +8539 640d +8540 7e2e +8541 7463 +8542 9396 +8543 737a +8544 64bb +8545 81fa +8546 614b +8547 6524 +8548 8caa +8549 7671 +8550 7058 +8551 58c7 +8552 8b5a +8553 8ac7 +8554 5606 +8555 6e6f +8556 71d9 +8557 6fe4 +8558 7e27 +8559 8a0e +8560 9a30 +8561 8b04 +8562 92bb +8563 984c +8564 9ad4 +8565 689d +8566 8cbc +8567 9435 +8568 5ef3 +8569 807d +8570 70f4 +8571 9285 +8572 7d71 +8573 982d +8574 5716 +8575 5857 +8576 5718 +8577 983d +8578 9d15 +8579 99b1 +8580 99dd +8581 6a62 +8582 7aaa +8583 896a +8584 5f4e +8585 7063 +8586 9811 +8587 842c +8588 7db2 +8589 97cb +8590 9055 +8591 570d +8592 7232 +8593 6ff0 +8594 7dad +8595 8466 +8596 5049 +8597 50de +8598 7def +8599 8b02 +8600 885b +8601 805e +8602 7d0b +8603 7a69 +8604 554f +8605 64be +8606 8778 +8607 6e26 +8608 7aa9 +8609 55da +8610 93a2 +8611 70cf +8612 8aa3 +8613 7121 +8614 856a +8615 5862 +8616 9727 +8617 52d9 +8618 8aa4 +8619 932b +8620 72a7 +8621 8972 +8622 7fd2 +8623 9291 +8624 6232 +8625 7d30 +8626 8766 +8627 8f44 +8628 5cfd +8629 4fe0 +8630 72f9 +8631 5687 +8632 9341 +8633 9bae +8634 7e96 +8635 8ce2 +8636 929c +8637 9591 +8638 986f +8639 96aa +8640 73fe +8641 737b +8642 7e23 +8643 9921 +8644 61b2 +8645 7dab +8646 9472 +8647 9109 +8648 8a73 +8649 97ff +8650 9805 +8651 856d +8652 56c2 +8653 92b7 +8654 66c9 +8655 562f +8656 5354 +8657 633e +8658 8105 +8659 8ae7 +8660 5beb +8661 7009 +8662 8b1d +8663 92c5 +8664 91c1 +8665 8208 +8666 92b9 +8667 7d89 +8668 9808 +8669 8a31 +8670 7dd2 +8671 7e8c +8672 8ed2 +8673 61f8 +8674 9078 +8675 766c +8676 7d62 +8677 5b78 +8678 52db +8679 8a62 +8680 5c0b +8681 99b4 +8682 8a13 +8683 8a0a +8684 905c +8685 58d3 +8686 9d09 +8687 9d28 +8688 555e +8689 4e9e +8690 8a1d +8691 95b9 +8692 9e7d +8693 56b4 +8694 9854 +8695 95bb +8696 8277 +8697 53ad +8698 786f +8699 8afa +8700 9a57 +8701 9d26 +8702 694a +8703 63da +8704 760d +8705 967d +8706 7662 +8707 990a +8708 6a23 +8709 582f +8710 8b21 +8711 85e5 +8712 723a +8713 9801 +8714 696d +8715 8449 +8716 91ab +8717 92a5 +8718 9824 +8719 907a +8720 5100 +8721 87fb +8722 85dd +8723 5104 +8724 61b6 +8725 7fa9 +8726 8a63 +8727 8b70 +8728 8abc +8729 8b6f +8730 7e79 +8731 852d +8732 9670 +8733 9280 +8734 98f2 +8735 96b1 +8736 6afb +8737 5b30 +8738 9df9 +8739 61c9 +8740 7e93 +8741 7469 +8742 87a2 +8743 71df +8744 7192 +8745 8805 +8746 8d0f +8747 7a4e +8748 55b2 +8749 64c1 +8750 50ad +8751 7670 +8752 8e34 +8753 512a +8754 6182 +8755 90f5 +8756 923e +8757 7336 +8758 8a98 +8759 8f3f +8760 9918 +8761 9b5a +8762 6f01 +8763 8207 +8764 5dbc +8765 8a9e +8766 9b31 +8767 7344 +8768 8b7d +8769 9810 +8770 99ad +8771 9d1b +8772 6df5 +8773 8f45 +8774 5712 +8775 54e1 +8776 5713 +8777 7de3 +8778 9060 +8779 9858 +8780 7d04 +8781 8e8d +8782 9470 +8783 95b2 +8784 96f2 +8785 9116 +8786 9695 +8787 904b +8788 85f4 +8789 9196 +8790 6688 +8791 96dc +8792 8f09 +8793 6522 +8794 66ab +8795 8d0a +8796 8d1c +8797 81df +8798 947f +8799 68d7 +8800 7ac8 +8801 8cac +8802 64c7 +8803 5247 +8804 6fa4 +8805 8cca +8806 8d08 +8807 8ecb +8808 9358 +8809 9598 +8810 8a50 +8811 9f4b +8812 50b5 +8813 6c08 +8814 76de +8815 65ac +8816 8f3e +8817 5d84 +8818 68e7 +8819 6230 +8820 7dbb +8821 5f35 +8822 6f32 +8823 5e33 +8824 8cec +8825 8139 +8826 8d99 +8827 87c4 +8828 8f4d +8829 937a +8830 9019 +8831 8c9e +8832 91dd +8833 5075 +8834 8a3a +8835 93ae +8836 9663 +8837 5e40 +8838 7665 +8839 912d +8840 8b49 +8841 7e54 +8842 8077 +8843 57f7 +8844 8879 +8845 7d19 +8846 646f +8847 64f2 +8848 5e5f +8849 8cea +8850 6eef +8851 9418 +8852 7d42 +8853 7a2e +8854 816b +8855 8846 +8856 8b05 +8857 8ef8 +8858 76ba +8859 665d +8860 9a5f +8861 8af8 +8862 8a85 +8863 71ed +8864 77da +8865 56d1 +8866 8caf +8867 9444 +8868 7bc9 +8869 99d0 +8870 5c08 +8871 78da +8872 8f49 +8873 8cfa +8874 6a01 +8875 838a +8876 88dd +8877 599d +8878 58ef +8879 72c0 +8880 9310 +8881 8d05 +8882 589c +8883 7db4 +8884 8ac4 +8885 6e96 +8886 6fc1 +8887 8cc7 +8888 6f2c +8889 7d9c +8890 7e3d +8891 7e31 +8892 9112 +8893 8a5b +8894 7d44 +8895 947d +8896 55c7 +8897 5399 +8898 53b4 +8899 9768 +8900 8d0b +8901 532d +8902 5331 +8903 8cfe +8904 5244 +8905 528c +8906 5274 +8907 50b4 +8908 5000 +8909 5096 +8910 5115 +8911 5102 +8912 5114 +8913 513c +8914 5137 +8915 50e8 +8916 50c2 +8917 513b +8918 5110 +8919 513a +8920 50c9 +8921 7cf4 +8922 9ecc +8923 56c5 +8924 9cec +8925 893b +8926 81e0 +8927 8a01 +8928 8a10 +8929 8a0c +8930 8a15 +8931 8b33 +8932 8a4e +8933 8a25 +8934 8a41 +8935 8a36 +8936 8a46 +8937 8a54 +8938 8a58 +8939 8a52 +8940 8a86 +8941 8a84 +8942 8a7f +8943 8a70 +8944 8a7c +8945 8a75 +8946 8a6c +8947 8a6e +8948 8acd +8949 8ae2 +8950 8a61 +8951 8a9a +8952 8aa5 +8953..8954 8a91 +8955 8acf +8956 8ad1 +8957 8ac9 +8958 8adb +8959 8ad7 +8960 8ac2 +8961 8ab6 +8962 8af6 +8963 8aeb +8964 8b14 +8965 8b01 +8966 8ae4 +8967 8aed +8968 8afc +8969 8af3 +8970 8ae6 +8971 8aee +8972 8ade +8973 8b28 +8974 8b9c +8975 8b16 +8976 8b1a +8977 8b10 +8978 8b2b +8979 8b2d +8980 8b56 +8981 8b59 +8982 8b4e +8983 8b9e +8984 8b6b +8985 8b96 +8986 9658 +8987 913a +8988 9114 +8989 9134 +8990 90df +8991 9136 +8992 9106 +8993 9148 +8994 82bb +8995 52f1 +8996 5df0 +8997 580a +8998 58d9 +8999 58e2 +9000 58e0 +9001 58da +9002 57e1 +9003 584f +9004 5816 +9005 5852 +9006 581d +9007 5864 +9008 858c +9009 8553 +9010 85f6 +9011 83a7 +9012 8407 +9013 84ef +9014 82e7 +9015 8622 +9016 8526 +9017 584b +9018 7162 +9019 8558 +9020 84fd +9021 854e +9022 8588 +9023 85ba +9024 7296 +9025 6ece +9026 8541 +9027 85ce +9028 8552 +9029 84c0 +9030 8452 +9031 8464 +9032 8494 +9033 8435 +9034 859f +9035 8555 +9036 9daf +9037 8493 +9038 7e08 +9039 8546 +9040 8562 +9041 851e +9042 9a40 +9043 863a +9044 93a3 +9045 8577 +9046 861e +9047 85fa +9048 8604 +9049 85ea +9050 861a +9051 5969 +9052 5c37 +9053 636b +9054 6476 +9055 649f +9056 6451 +9057 645c +9058 64b3 +9059 6504 +9060 6516 +9061 64f7 +9062 64fc +9063 651b +9064 5630 +9065 5638 +9066 56c8 +9067 56a6 +9068 5504 +9069 54bc +9070 5680 +9071 565d +9072 5660 +9073 5635 +9074 55f6 +9075 5666 +9076 5672 +9077 568c +9078 5665 +9079 561c +9080 562e +9081 55e9 +9082 5616 +9083 56c0 +9084 560d +9085 56b3 +9086 56c1 +9087 566f +9088 8f61 +9089 56b6 +9090 5695 +9091 5707 +9092 5e43 +9093 5e6c +9094 5e58 +9095 5e57 +9096 5d87 +9097 5cf4 +9098 5d50 +9099 5d2c +9100 5da7 +9101 5da0 +9102 5d97 +9103 5d0d +9104 5db8 +9105 5d81 +9106 5dd4 +9107 5fa0 +9108 7377 +9109 7341 +9110 736a +9111 733b +9112 736b +9113 7380 +9114 737c +9115 98e0 +9116 9933 +9117 98e9 +9118 993c +9119..9120 98ea +9121 98ed +9122 98f4 +9123 9909 +9124 9911 +9125 991b +9126 9937 +9127 993f +9128 9943 +9129..9131 9948 +9132 994c +9133 9962 +9134 5ee1 +9135 8ce1 +9136 61fa +9137 61ae +9138 616a +9139 613e +9140 60b5 +9141 6134 +9142 61cc +9143 615f +9144 61e8 +9145 60fb +9146 6137 +9147 60f2 +9148 6173 +9149 611c +9150 6192 +9151 9582 +9152 9586 +9153 95c8 +9154 958e +9155 9594 +9156 958c +9157 95e5 +9158 95ad +9159 95ab +9160 9b2e +9161 95ac +9162 95be +9163 95b6 +9164 9b29 +9165 95bf +9166 95bd +9167 95bc +9168 95c3 +9169 95cb +9170 95d4 +9171 95d0 +9172 95d5 +9173 95de +9174 7043 +9175 6f59 +9176 7027 +9177 7018 +9178 6ffc +9179 6d87 +9180 6d79 +9181 6e5e +9182 6fae +9183 700f +9184 6ef8 +9185 6f6f +9186 6df6 +9187 6f7f +9188 7006 +9189 6fa0 +9190 700b +9191 7067 +9192 7044 +9193 7005 +9194 6f77 +9195 7020 +9196 701f +9197 7032 +9198 7028 +9199 705d +9200 9a2b +9201 9087 +9202 9015 +9203 9090 +9204 5c68 +9205 5f33 +9206 5af5 +9207 5ad7 +9208 5b00 +9209 5a6d +9210 5b08 +9211 5b4c +9212 5aa7 +9213 5afb +9214 5b0b +9215 5b21 +9216 5b2a +9217 5b19 +9218 99d4 +9219 99df +9220 99d9 +9221 9a36 +9222 9a5b +9223 99d1 +9224 99d8 +9225 9a4d +9226 9a4a +9227 99e2 +9228 9a6a +9229 9a0f +9230 9a0d +9231 9a05 +9232 9a42 +9233 9a2d +9234 9a16 +9235 9a41 +9236 9a2e +9237 9a38 +9238..9239 9a43 +9240 9a4f +9241 9a65 +9242 9a64 +9243 7cf9 +9244 7d06 +9245 7d02 +9246..9247 7d07 +9248 7e8a +9249 7d1c +9250 7d15 +9251 7d13 +9252 7d3a +9253 7d32 +9254 7d31 +9255 7e10 +9256 7d3c +9257 7d40 +9258 7d3f +9259 7d5d +9260 7d4e +9261 7d73 +9262 7d86 +9263 7d83 +9264 7d88 +9265 7dbe +9266 7dba +9267 7dcb +9268 7dd4 +9269 7dc4 +9270 7d9e +9271 7dac +9272 7db9 +9273 7da3 +9274 7db0 +9275 7dc7 +9276 7dd9 +9277 7dd7 +9278 7df9 +9279 7df2 +9280 7e62 +9281 7de6 +9282 7df6 +9283 7df1 +9284 7e0b +9285 7de1 +9286 7e09 +9287 7e1d +9288 7e1f +9289 7e1e +9290 7e2d +9291 7e0a +9292 7e11 +9293 7e7d +9294 7e39 +9295 7e35 +9296 7e32 +9297 7e46 +9298 7e45 +9299 7e88 +9300 7e5a +9301 7e52 +9302 7e6e +9303 7e7e +9304 7e70 +9305 7e6f +9306 7e98 +9307 74a3 +9308 744b +9309 74cf +9310 980a +9311 74bd +9312 743f +9313 7489 +9314 74a6 +9315 74d4 +9316 74da +9317 97d9 +9318 97de +9319 97dc +9320 69aa +9321 6aea +9322 6898 +9323 68d6 +9324 6a05 +9325 689f +9326 6adb +9327 6af3 +9328 6ae8 +9329 6adf +9330 6a89 +9331 690f +9332 6a48 +9333 6968 +9334 69bf +9335 6a3a +9336 6a9c +9337 6b12 +9338 6b1e +9339 6add +9340 69e7 +9341 6b0f +9342 6b16 +9343 6aec +9344 6ada +9345 6af8 +9346 6ab3 +9347 6ae7 +9348 6aa3 +9349 6ad3 +9350 6ade +9351 6ba4 +9352 6b9e +9353 6bae +9354 6bab +9355 6baf +9356 8ed4 +9357 8edb +9358 8ef2 +9359 8efb +9360 8f64 +9361 8ef9 +9362 8efc +9363 8eeb +9364 8ee4 +9365 8f62 +9366 8efa +9367 8efe +9368 8f0a +9369 8f07 +9370 8f05 +9371 8f12 +9372 8f26 +9373..9374 8f1e +9375 8f1c +9376 8f33 +9377 8f46 +9378 8f54 +9379 6214 +9380 6227 +9381 750c +9382 66c7 +9383 66c4 +9384 6689 +9385 66d6 +9386 8cc1 +9387 8cb0 +9388 8cba +9389 8cbd +9390 8d04 +9391 8cb2 +9392 8cc5 +9393 8d10 +9394 8cd1 +9395 8cda +9396 8cd5 +9397 8ceb +9398 8ce7 +9399 8cfb +9400 8998 +9401 89ac +9402 89a1 +9403 89bf +9404 89a6 +9405 89af +9406 89b2 +9407 89b7 +9408 6bff +9409 6c0c +9410 6c2c +9411 7258 +9412 6727 +9413 8156 +9414 81da +9415 811b +9416 81be +9417 8161 +9418 81cf +9419 6b5f +9420..9421 98ae +9422 98b6 +9423 98bc +9424 98c6 +9425 98c8 +9426 8f42 +9427 9f4f +9428 6595 +9429 716c +9430 7152 +9431 7197 +9432 71c1 +9433 71dc +9434 71fe +9435 79b0 +9436 798e +9437 79aa +9438 61df +9439 6164 +9440 61e3 +9441 6207 +9442 6fa9 +9443 78ef +9444 78ad +9445 7868 +9446 78b8 +9447 792a +9448 7931 +9449 7864 +9450 78fd +9451 78e7 +9452 78e3 +9453 9f95 +9454 7798 +9455 775e +9456 77bc +9457 7f86 +9458 7f88 +9459..9461 91d2 +9462 91d9 +9463 91d7 +9464 91d5 +9465 91f7 +9466 91e7 +9467 91e4 +9468 9346 +9469 91f5 +9470 91f9 +9471 9208 +9472 9226 +9473 9245 +9474 9211 +9475 9210 +9476 9201 +9477 9227 +9478 9204 +9479 9225 +9480 9200 +9481 923a +9482 9266 +9483 9237 +9484 9233 +9485 9255 +9486 923d +9487 9238 +9488 925e +9489..9490 926c +9491 923f +9492 9460 +9493 9230 +9494 9249 +9495 9248 +9496 924d +9497 922e +9498 9239 +9499 9438 +9500 92ac +9501 92a0 +9502 927a +9503 92aa +9504 92ee +9505 92cf +9506 9403 +9507 92e3 +9508 943a +9509 92b1 +9510 92a6 +9511 93a7 +9512 9296 +9513 92cc +9514 92a9 +9515 93f5 +9516 9293 +9517 927f +9518 93a9 +9519 929a +9520 931a +9521 92ab +9522 9283 +9523 940b +9524 92a8 +9525 92a3 +9526 9412 +9527 9338 +9528 92f1 +9529 93d7 +9530 92e5 +9531 92f0 +9532 92ef +9533 92e8 +9534 92bc +9535 92dd +9536 92f6 +9537..9538 9426 +9539 92c3 +9540 92df +9541 92e6 +9542 9312 +9543 9306 +9544 9369 +9545 931b +9546 9340 +9547 9301 +9548 9315 +9549 932e +9550 9343 +9551..9552 9307 +9553 931f +9554 9319 +9555 9365 +9556 9347 +9557 9376 +9558 9354 +9559 9364 +9560 93aa +9561 9370 +9562 9384 +9563 93e4 +9564 93d8 +9565 9428 +9566 9387 +9567 93cc +9568 9398 +9569 93b8 +9570 93bf +9571 93a6 +9572 93b0 +9573 93b5 +9574 944c +9575 93e2 +9576..9577 93dc +9578 93cd +9579 93de +9580 93c3 +9581 93c7 +9582 93d1 +9583 9414 +9584 941d +9585 93f7 +9586 9465 +9587 9413 +9588 946d +9589 9420 +9590 9479 +9591 93f9 +9592 9419 +9593 944a +9594 9432 +9595 943f +9596 9454 +9597 9463 +9598 937e +9599 7a61 +9600 9ce9 +9601 9cf6 +9602 9d07 +9603 9d06 +9604 9d23 +9605 9d87 +9606 9e15 +9607 9d1d +9608 9d1f +9609 9de5 +9610 9d2f +9611 9dd9 +9612 9d30 +9613 9d42 +9614 9e1e +9615 9d53 +9616 9e1d +9617 9d60 +9618 9d52 +9619 9df3 +9620 9d5c +9621 9d61 +9622 9d93 +9623 9d6a +9624 9d6f +9625 9d89 +9626 9d98 +9627 9d9a +9628 9dc0 +9629 9da5 +9630 9da9 +9631 9dc2 +9632 9dbc +9633 9e1a +9634 9dd3 +9635 9dda +9636 9def +9637 9de6 +9638 9df2 +9639 9df8 +9640 9e0c +9641 9dfa +9642 9e1b +9643 7664 +9644 7658 +9645 7667 +9646 7602 +9647..9648 7646 +9649 7649 +9650 761e +9651 763b +9652..9653 766d +9654 7669 +9655 7672 +9656 7ac7 +9657 7ab6 +9658 8960 +9659 8933 +9660 895d +9661 8947 +9662 8938 +9663 8964 +9664 76b8 +9665 802e +9666 802c +9667 8079 +9668 8075 +9669 9807 +9670..9671 980e +9672 9821 +9673 981c +9674 6f41 +9675 9826 +9676 9837 +9677 984e +9678 9853 +9679 9873 +9680 9862 +9681 9859 +9682 9865 +9683 986c +9684 9870 +9685 87e3 +9686 8806 +9687 8706 +9688 8823 +9689 87f6 +9690 86fa +9691 87ef +9692 8784 +9693 8810 +9694 87c8 +9695 8811 +9696 87bb +9697 87ce +9698 7f4c +9699 7be4 +9700 7b67 +9701 7c69 +9702 7bf3 +9703 7c00 +9704 7bcb +9705 7c5c +9706 7c1e +9707 7c2b +9708 7c23 +9709 7c6a +9710 7c5f +9711 8264 +9712 826b +9713 88ca +9714 7fa5 +9715 7cf2 +9716 7cf6 +9717 7cdd +9718 7e36 +9719 9ea9 +9720 8db2 +9721 91c5 +9722 91c3 +9723 9e7a +9724 8e89 +9725 8e4c +9726 8e92 +9727 8e7a +9728 8e55 +9729 8e9a +9730 8e8b +9731 8e93 +9732 8e91 +9733 8ea1 +9734 8e63 +9735 8eaa +9736 8ea6 +9737 89f4 +9738 89f6 +9739 975a +9740 9742 +9741 973d +9742 9744 +9743 9f54 +9744 9f5f +9745 9f59 +9746 9f60 +9747 9f5c +9748 9f66 +9749 9f6c +9750 9f6a +9751 9f77 +9752 9efd +9753 9eff +9754 9f09 +9755 8b8e +9756 947e +9757 93e8 +9758 9b77 +9759 9b74 +9760 9b81 +9761 9b83 +9762 9b8e +9763 9c78 +9764 7a4c +9765 9b92 +9766 9c5f +9767 9b90 +9768 9bad +9769 9b9a +9770 9baa +9771 9b9e +9772 9c6d +9773 9bab +9774 9b9d +9775 9c58 +9776 9bc1 +9777 9c7a +9778 9c31 +9779 9c39 +9780 9c23 +9781 9c37 +9782 9bc0 +9783 9bca +9784 9bc7 +9785 9bfd +9786 9bd6 +9787..9788 9bea +9789 9be1 +9790 9be4 +9791 9be7 +9792 9bdd +9793 9be2 +9794 9bf0 +9795 9bdb +9796 9bf4 +9797 9bd4 +9798 9c5d +9799 9c08 +9800 9c10 +9801 9c0d +9802 9c12 +9803 9c09 +9804 9bff +9805 9c20 +9806 9c32 +9807 9c2d +9808 9c28 +9809 9c25 +9810 9c29 +9811 9c33 +9812 9c3e +9813 9c48 +9814 9c3b +9815 9c35 +9816 9c45 +9817 9c56 +9818 9c54 +9819 9c52 +9820 9c67 +9821 97c3 +9822 97bd +9823 97c9 +9824 9dbb +9825 9acf +9826 9ad6 +9827 9ad5 +9828 9b58 +9829 9b4e +9830 9957 +9831 995c +9832 9b22 +9833 9ef7 +9834 9ef2 +9835 896c +9836 95c6 +9837 9336 +9838 5f46 +9839 8514 +9840 7e94 +9841 9f63 +9842 5679 +9843 9f15 +9844 5641 +9845 9aee +9846 8907 +9847 7a40 +9848 98b3 +9849 95a4 +9850 9b0d +9851 8ff4 +9852 5f59 +9853 7a6b +9854 98e2 +9855 50a2 +9856 8591 +9857 5118 +9858 6372 +9859 524b +9860 774f +9861 7e8d +9862 66c6 +9863 77ad +9864 9e75 +9865 56c9 +9866 9ef4 +9867 6fdb +9868 61de +9869 77c7 +9870 7030 +9871 9eb5 +9872 884a +9873 95e2 +9874 97c6 +9875 7c64 +9876 7e34 +9877 97a6 +9878 9eaf +9879 56cc +9880 98b1 +9881 6aaf +9882 7f4e +9883 7cf0 +9884 4fc2 +9885 7e6b +9886 9e79 +9887 56ae +9888 9b1a +9889 846f +9890 79a6 +9891 7c72 +9892 9ad2 +9893 96bb +9894 7dfb +9895 88fd +9896 7843 +9897..9906 2170 +9907..9908 02ca +9909 02d9 +9910 2013 +9911 2015 +9912 2025 +9913 2035 +9914 2105 +9915 2109 +9916..9919 2196 +9920 2215 +9921 221f +9922 2223 +9923 2252 +9924..9925 2266 +9926 22bf +9927..9962 2550 +9963..9977 2581 +9978..9980 2593 +9981..9982 25bc +9983..9986 25e2 +9987 2609 +9988 2295 +9989 3012 +9990..9991 301d +9992..10000 3021 +10001 32a3 +10002..10003 338e +10004..10006 339c +10007 33a1 +10008 33c4 +10009 33ce +10010..10011 33d1 +10012 33d5 +10013 fe30 +10014 ffe2 +10015 ffe4 +10016 2121 +10017 3231 +10018 2010 +10019 30fc +10020..10021 309b +10022..10023 30fd +10024 3006 +10025..10026 309d +10027..10036 fe49 +10037..10040 fe54 +10041..10054 fe59 +10055..10058 fe68 +10059 303e +10060..10071 2ff0 +10072 4e02 +10073..10075 4e04 +10076 4e0f +10077 4e12 +10078 4e17 +10079..10081 4e1f +10082 4e23 +10083 4e26 +10084 4e29 +10085..10086 4e2e +10087 4e31 +10088 4e33 +10089 4e35 +10090 4e37 +10091 4e3c +10092..10094 4e40 +10095 4e44 +10096 4e46 +10097 4e4a +10098 4e51 +10099 4e55 +10100 4e57 +10101..10102 4e5a +10103..10106 4e62 +10107..10108 4e67 +10109..10114 4e6a +10115 4e72 +10116..10125 4e74 +10126..10128 4e7f +10129..10131 4e83 +10132 4e87 +10133 4e8a +10134 4e90 +10135..10136 4e96 +10137 4e99 +10138..10139 4e9c +10140 4ea3 +10141 4eaa +10142..10144 4eaf +10145 4eb4 +10146..10149 4eb6 +10150..10152 4ebc +10153 4ec8 +10154 4ecc +10155..10156 4ecf +10157 4ed2 +10158..10160 4eda +10161 4ee0 +10162 4ee2 +10163..10164 4ee6 +10165 4ee9 +10166..10168 4eed +10169 4ef1 +10170 4ef4 +10171..10173 4ef8 +10174 4efc +10175 4efe +10176 4f00 +10177..10183 4f02 +10184..10185 4f0b +10186..10190 4f12 +10191..10192 4f1c +10193 4f21 +10194 4f23 +10195..10196 4f28 +10197..10199 4f2c +10200 4f31 +10201 4f33 +10202 4f35 +10203 4f37 +10204 4f39 +10205 4f3b +10206..10210 4f3e +10211..10212 4f44 +10213..10218 4f47 +10219 4f52 +10220 4f54 +10221 4f56 +10222..10223 4f61 +10224 4f66 +10225 4f68 +10226..10227 4f6a +10228..10229 4f6d +10230..10231 4f71 +10232 4f75 +10233..10236 4f77 +10237 4f7d +10238..10240 4f80 +10241 4f85 +10242 4f87 +10243 4f8a +10244 4f8c +10245 4f8e +10246 4f90 +10247..10248 4f92 +10249 4f95 +10250..10252 4f98 +10253 4f9c +10254..10255 4f9e +10256..10257 4fa1 +10258 4fa4 +10259 4fab +10260 4fad +10261..10265 4fb0 +10266..10274 4fb6 +10275..10276 4fc0 +10277..10280 4fc6 +10281..10283 4fcb +10284..10288 4fd2 +10289 4fd9 +10290 4fdb +10291 4fe2 +10292..10293 4fe4 +10294 4fe7 +10295..10296 4feb +10297 4ff0 +10298 4ff2 +10299..10302 4ff4 +10303 4ff9 +10304..10306 4ffb +10307 4fff +10308..10312 5001 +10313..10314 5007 +10315 500a +10316 500e +10317 5010 +10318 5013 +10319..10321 5015 +10322 501b +10323..10324 501d +10325 5020 +10326..10328 5022 +10329 5027 +10330..10340 502f +10341 503b +10342 503d +10343..10346 503f +10347..10349 5044 +10350..10351 504a +10352 504d +10353..10357 5050 +10358..10361 5056 +10362 505b +10363..10370 505d +10371..10376 5066 +10377..10383 506d +10384..10386 5078 +10387..10388 507c +10389..10392 5081 +10393..10394 5086 +10395..10398 5089 +10399..10406 508e +10407 5097 +10408..10415 509a +10416 50a4 +10417 50a6 +10418..10419 50aa +10420..10423 50ae +10424 50b6 +10425..10426 50b8 +10427..10428 50bc +10429..10431 50bf +10432..10433 50c3 +10434..10436 50c6 +10437..10441 50ca +10442 50d0 +10443..10445 50d2 +10446..10448 50d7 +10449..10451 50db +10452..10457 50df +10458..10460 50e9 +10461..10464 50ef +10465 50f4 +10466..10468 50f6 +10469 50fa +10470..10473 50fc +10474 5101 +10475 5103 +10476 5105 +10477 510a +10478..10481 510c +10482 5111 +10483 5113 +10484..10485 5116 +10486..10491 5119 +10492 5120 +10493..10500 5122 +10501..10507 512b +10508..10511 5133 +10512..10513 5138 +10514..10515 513d +10516 5142 +10517 5147 +10518 514a +10519 514c +10520..10522 514e +10523 5153 +10524..10526 5157 +10527 515b +10528..10532 515d +10533..10534 5163 +10535..10536 5166 +10537 516a +10538 516f +10539 5172 +10540 517a +10541..10542 517e +10543..10544 5183 +10545..10546 5186 +10547..10548 518a +10549..10552 518e +10553..10554 5193 +10555 5198 +10556 519a +10557..10559 519d +10560 51a1 +10561 51a3 +10562..10566 51a6 +10567..10568 51ad +10569 51b4 +10570..10572 51b8 +10573..10574 51be +10575..10577 51c1 +10578 51c5 +10579 51c8 +10580 51ca +10581 51ce +10582 51d0 +10583..10591 51d2 +10592 51dc +10593..10594 51de +10595..10596 51e2 +10597..10602 51e5 +10603 51ec +10604 51ee +10605 51f2 +10606 51f4 +10607 51f7 +10608 51fe +10609..10610 5204 +10611 5209 +10612..10613 520b +10614..10615 520f +10616..10618 5213 +10619 521c +10620..10621 521e +10622..10624 5221 +10625..10627 5225 +10628 522a +10629 522c +10630 522f +10631..10632 5231 +10633..10634 5234 +10635 523c +10636 523e +10637..10638 5245 +10639..10640 5248 +10641..10642 524e +10643..10644 5252 +10645 5255 +10646..10649 5257 +10650 525d +10651..10652 525f +10653..10655 5262 +10656 5266 +10657 5268 +10658..10660 526b +10661..10662 5270 +10663 5273 +10664..10670 5276 +10671 527e +10672 5280 +10673..10675 5284 +10676 528b +10677..10678 528e +10679 5292 +10680..10686 5294 +10687 529c +10688..10691 52a4 +10692..10694 52ae +10695..10704 52b4 +10705 52c0 +10706 52c2 +10707..10709 52c4 +10710 52c8 +10711 52ca +10712..10715 52cc +10716 52d1 +10717..10718 52d3 +10719 52d7 +10720 52da +10721 52dc +10722..10723 52e0 +10724 52e3 +10725..10735 52e5 +10736..10738 52f2 +10739..10740 52f6 +10741..10743 52fb +10744..10747 5301 +10748 5307 +10749..10752 5309 +10753 530e +10754..10757 5311 +10758 5318 +10759..10760 531b +10761..10762 531e +10763 5322 +10764..10765 5324 +10766..10768 5327 +10769..10770 532b +10771 5330 +10772..10778 5332 +10779..10780 533c +10781 5342 +10782 5344 +10783 5346 +10784..10786 534b +10787 5350 +10788..10789 5358 +10790 535b +10791 535d +10792 5365 +10793 5368 +10794 536a +10795..10796 536c +10797 5372 +10798 5376 +10799 5379 +10800..10803 537b +10804..10805 5380 +10806 5383 +10807..10808 5387 +10809 538a +10810..10816 538e +10817..10818 5396 +10819..10820 539b +10821 539e +10822 53a1 +10823 53a4 +10824 53a7 +10825..10827 53aa +10828..10830 53af +10831 53b3 +10832 53b5 +10833..10836 53b7 +10837..10839 53bc +10840 53c0 +10841..10844 53c4 +10845..10847 53ce +10848..10849 53d2 +10850 53d5 +10851 53da +10852..10854 53dc +10855 53e1 +10856 53e7 +10857 53f4 +10858 53fa +10859..10861 53fe +10862 5402 +10863 5405 +10864 5407 +10865 540b +10866 5414 +10867..10869 5418 +10870 541c +10871 5422 +10872..10873 5424 +10874 542a +10875 5430 +10876 5433 +10877..10878 5436 +10879 543a +10880 543d +10881 543f +10882..10883 5441 +10884..10885 5444 +10886 5447 +10887 5449 +10888..10891 544c +10892 5451 +10893 545a +10894..10898 545d +10899 5463 +10900 5465 +10901 5467 +10902..10909 5469 +10910 5474 +10911..10912 5479 +10913..10914 547e +10915 5481 +10916 5483 +10917 5485 +10918..10921 5487 +10922 548d +10923 5491 +10924 5493 +10925..10926 5497 +10927 549c +10928..10932 549e +10933 54a5 +10934 54ae +10935 54b0 +10936 54b2 +10937..10939 54b5 +10940..10941 54b9 +10942 54be +10943 54c3 +10944 54c5 +10945..10946 54ca +10947 54d6 +10948 54d8 +10949 54db +10950 54e0 +10951..10953 54e2 +10954..10955 54eb +10956..10958 54ef +10959..10964 54f4 +10965 54fb +10966 54fe +10967 5500 +10968..10969 5502 +10970 5505 +10971 5508 +10972..10976 550a +10977..10978 5512 +10979..10984 5515 +10985..10988 551c +10989 5521 +10990..10991 5525 +10992..10993 5528 +10994 552b +10995 552d +10996 5532 +10997..10999 5534 +11000..11003 5538 +11004 553d +11005 5540 +11006 5542 +11007 5545 +11008..11009 5547 +11010..11013 554b +11014..11015 5551 +11016 5554 +11017..11021 5557 +11022 555d +11023..11024 555f +11025..11026 5562 +11027..11028 5568 +11029 556b +11030..11035 556f +11036..11037 5579 +11038 557d +11039 557f +11040..11041 5585 +11042..11044 558c +11045 5590 +11046..11047 5592 +11048..11050 5595 +11051..11052 559a +11053 559e +11054..11060 55a0 +11061..11062 55a8 +11063 55ab +11064 55ad +11065..11066 55af +11067 55b4 +11068 55b6 +11069 55b8 +11070 55ba +11071 55bc +11072..11076 55bf +11077 55c8 +11078..11079 55ca +11080..11081 55cf +11082 55d5 +11083..11085 55d7 +11086 55db +11087 55de +11088 55e0 +11089 55e2 +11090 55e7 +11091..11092 55ed +11093..11094 55f0 +11095 55f4 +11096..11100 55f8 +11101 55ff +11102..11105 5602 +11106 5607 +11107..11108 560a +11109..11112 5610 +11113 5615 +11114..11115 5619 +11116 561d +11117..11119 5620 +11120..11121 5625 +11122 5628 +11123..11124 562a +11125 5633 +11126 5637 +11127 563a +11128..11130 563c +11131 5640 +11132..11141 5642 +11142..11146 564f +11147..11148 5655 +11149..11150 565a +11151..11152 565e +11153 5661 +11154 5663 +11155 5667 +11156..11157 566d +11158 5670 +11159 5673 +11160 5675 +11161 5677 +11162 567a +11163..11165 567d +11166..11169 5681 +11170..11173 5688 +11174 568d +11175..11177 5690 +11178 5694 +11179..11181 5696 +11182..11190 569a +11191..11192 56a4 +11193 56a7 +11194..11198 56a9 +11199..11201 56b0 +11202 56b5 +11203..11206 56b8 +11207..11209 56bd +11210..11211 56c3 +11212..11213 56c6 +11214 56cb +11215..11218 56cd +11219..11220 56d2 +11221..11222 56d5 +11223..11224 56d8 +11225 56dc +11226 56e3 +11227..11232 56e5 +11233 56ec +11234..11235 56ee +11236..11237 56f2 +11238..11240 56f6 +11241..11242 56fb +11243..11245 5700 +11246 5705 +11247 570c +11248..11251 570e +11252..11253 5714 +11254 5717 +11255..11257 5719 +11258..11259 571d +11260..11262 5720 +11263..11266 5724 +11267 572b +11268..11269 5731 +11270..11274 5734 +11275..11276 573c +11277 573f +11278 5741 +11279..11282 5743 +11283..11284 5748 +11285 574b +11286..11290 5752 +11291..11292 5758 +11293..11294 5762 +11295 5765 +11296 5767 +11297 576c +11298 576e +11299..11301 5770 +11302..11303 5774 +11304..11306 5778 +11307..11311 577d +11312..11315 5787 +11316..11320 578d +11321..11327 5794 +11328..11331 579c +11332 57a5 +11333 57a8 +11334 57aa +11335 57ac +11336..11338 57af +11339 57b3 +11340..11342 57b5 +11343..11351 57b9 +11352..11358 57c4 +11359..11360 57cc +11361..11362 57d0 +11363 57d3 +11364..11365 57d6 +11366..11367 57db +11368 57de +11369..11370 57e2 +11371..11378 57e5 +11379 57ee +11380..11383 57f0 +11384..11385 57f5 +11386..11387 57fb +11388..11389 57fe +11390 5801 +11391..11392 5803 +11393..11394 5808 +11395 580c +11396..11398 580e +11399..11401 5812 +11402..11403 5817 +11404..11406 581a +11407 581f +11408..11409 5822 +11410..11414 5825 +11415..11418 582b +11419..11420 5832 +11421..11434 5836 +11435..11439 5845 +11440 584e +11441 5850 +11442 5853 +11443..11444 5855 +11445..11449 5859 +11450..11452 585f +11453 5863 +11454..11458 5866 +11459..11466 586d +11467..11469 5876 +11470..11473 587a +11474 587f +11475 5882 +11476 5884 +11477..11479 5886 +11480..11486 588b +11487..11491 5894 +11492 589b +11493 589d +11494..11501 58a0 +11502..11505 58aa +11506..11509 58af +11510..11516 58b4 +11517 58bd +11518..11519 58bf +11520..11522 58c2 +11523 58c6 +11524..11532 58c8 +11533 58d2 +11534 58d4 +11535..11536 58d6 +11537..11539 58db +11540 58e1 +11541 58e3 +11542..11545 58e5 +11546 58ea +11547 58ed +11548..11549 58f1 +11550..11551 58f4 +11552..11553 58f7 +11554..11555 58fb +11556..11559 58fe +11560 5903 +11561..11562 5905 +11563..11567 5908 +11568 590e +11569..11572 5910 +11573..11574 5917 +11575 591b +11576..11577 591d +11578..11579 5920 +11580 5923 +11581 5926 +11582 5928 +11583 592c +11584 5930 +11585..11586 5932 +11587..11588 5935 +11589 593b +11590 593d +11591..11592 593f +11593 5943 +11594..11595 5945 +11596 594a +11597..11598 594c +11599 5950 +11600..11601 5952 +11602 5959 +11603..11607 595b +11608 5961 +11609..11610 5963 +11611..11613 5966 +11614 596b +11615 596d +11616..11619 596f +11620 5975 +11621 5977 +11622..11624 597a +11625..11627 597e +11628 5985 +11629 5989 +11630..11631 598b +11632..11635 598e +11636..11637 5994 +11638 5998 +11639..11641 599a +11642..11645 599f +11646..11647 59a6 +11648..11649 59ac +11650..11651 59b0 +11652..11657 59b3 +11658 59ba +11659..11660 59bc +11661..11667 59bf +11668..11670 59c7 +11671..11674 59cc +11675..11676 59d5 +11677 59d9 +11678 59db +11679..11683 59de +11684 59e4 +11685..11686 59e6 +11687..11689 59e9 +11690..11701 59ed +11702 59fa +11703..11705 59fc +11706 5a00 +11707 5a02 +11708..11709 5a0a +11710..11713 5a0d +11714 5a12 +11715..11718 5a14 +11719..11721 5a19 +11722..11723 5a1d +11724..11725 5a21 +11726 5a24 +11727..11729 5a26 +11730..11736 5a2a +11737 5a33 +11738 5a35 +11739..11743 5a37 +11744..11746 5a3d +11747..11750 5a42 +11751..11752 5a47 +11753..11762 5a4b +11763..11766 5a56 +11767..11773 5a5b +11774..11776 5a63 +11777..11778 5a68 +11779..11780 5a6b +11781..11786 5a6e +11787..11788 5a78 +11789..11792 5a7b +11793..11810 5a80 +11811..11817 5a93 +11818..11828 5a9c +11829..11830 5aa8 +11831..11837 5aab +11838 5ab4 +11839..11840 5ab6 +11841..11844 5ab9 +11845..11846 5abf +11847..11852 5ac3 +11853..11854 5aca +11855..11859 5acd +11860 5ad3 +11861 5ad5 +11862..11864 5ad9 +11865..11867 5add +11868 5ae2 +11869..11870 5ae4 +11871..11872 5ae7 +11873 5aea +11874..11878 5aec +11879..11881 5af2 +11882..11886 5af6 +11887..11890 5afc +11891..11897 5b01 +11898 5b0a +11899..11907 5b0d +11908 5b18 +11909..11915 5b1a +11916..11923 5b22 +11924..11928 5b2b +11929 5b31 +11930 5b33 +11931..11932 5b35 +11933..11939 5b39 +11940..11950 5b41 +11951..11953 5b4d +11954 5b52 +11955 5b56 +11956 5b5e +11957..11958 5b60 +11959..11960 5b67 +11961..11963 5b6d +11964 5b72 +11965 5b74 +11966..11967 5b76 +11968 5b79 +11969..11970 5b7b +11971 5b7e +11972 5b82 +11973 5b86 +11974 5b8a +11975..11976 5b8d +11977..11979 5b90 +11980 5b94 +11981 5b96 +11982 5b9f +11983..11985 5ba7 +11986..11989 5bac +11990..11991 5bb1 +11992 5bb7 +11993..11995 5bba +11996..11997 5bc0 +11998 5bc3 +11999..12002 5bc8 +12003..12005 5bcd +12006 5bd1 +12007..12015 5bd4 +12016 5be0 +12017 5be3 +12018 5bea +12019 5bed +12020 5bef +12021..12024 5bf1 +12025 5bf7 +12026..12027 5bfd +12028 5c00 +12029..12030 5c02 +12031 5c05 +12032 5c0c +12033 5c10 +12034..12035 5c12 +12036 5c17 +12037 5c19 +12038 5c1b +12039..12042 5c1e +12043 5c23 +12044 5c26 +12045..12048 5c28 +12049..12052 5c2d +12053..12054 5c32 +12055..12056 5c35 +12057..12058 5c43 +12059..12060 5c46 +12061..12062 5c4c +12063..12065 5c52 +12066..12068 5c56 +12069..12072 5c5a +12073 5c5f +12074 5c67 +12075..12077 5c69 +12078 5c6d +12079 5c70 +12080..12086 5c72 +12087..12090 5c7b +12091 5c80 +12092..12096 5c83 +12097..12099 5c89 +12100..12101 5c8e +12102..12103 5c92 +12104 5c95 +12105..12108 5c9d +12109..12113 5ca4 +12114 5caa +12115..12117 5cae +12118 5cb2 +12119 5cb4 +12120 5cb6 +12121..12124 5cb9 +12125 5cbe +12126 5cc0 +12127..12128 5cc2 +12129..12134 5cc5 +12135..12140 5ccc +12141..12146 5cd3 +12147..12153 5cda +12154..12155 5ce2 +12156 5ce7 +12157 5ce9 +12158..12159 5ceb +12160..12161 5cee +12162..12164 5cf1 +12165 5cf5 +12166..12169 5cf7 +12170 5cfc +12171..12174 5cfe +12175..12176 5d04 +12177..12181 5d08 +12182..12186 5d0f +12187 5d15 +12188..12190 5d18 +12191..12192 5d1c +12193..12197 5d1f +12198 5d25 +12199 5d28 +12200..12201 5d2a +12202..12206 5d2f +12207..12214 5d35 +12215..12222 5d3f +12223..12224 5d48 +12225..12227 5d4d +12228..12234 5d51 +12235..12236 5d59 +12237 5d5c +12238..12248 5d5e +12249 5d6a +12250..12251 5d6d +12252..12255 5d70 +12256..12267 5d75 +12268 5d83 +12269..12270 5d85 +12271..12285 5d88 +12286 5d98 +12287..12289 5d9a +12290..12291 5d9e +12292..12297 5da1 +12298..12312 5da8 +12313 5db9 +12314 5dbb +12315..12322 5dbd +12323..12327 5dc6 +12328 5dcc +12329..12332 5dce +12333 5dd3 +12334..12339 5dd5 +12340 5ddc +12341..12342 5ddf +12343..12344 5de3 +12345 5dea +12346..12347 5dec +12348..12349 5df5 +12350..12354 5df8 +12355..12356 5dff +12357 5e04 +12358 5e07 +12359..12361 5e09 +12362..12363 5e0d +12364..12365 5e12 +12366 5e17 +12367..12373 5e1e +12374..12376 5e28 +12377 5e2c +12378..12379 5e2f +12380 5e32 +12381..12382 5e34 +12383..12384 5e39 +12385..12386 5e3e +12387 5e41 +12388..12393 5e46 +12394..12400 5e4d +12401 5e56 +12402..12403 5e59 +12404..12405 5e5c +12406 5e60 +12407..12413 5e64 +12414..12418 5e6d +12419 5e75 +12420 5e77 +12421..12423 5e81 +12424 5e85 +12425..12426 5e88 +12427..12429 5e8c +12430 5e92 +12431 5e98 +12432 5e9b +12433 5e9d +12434..12437 5ea1 +12438..12440 5ea8 +12441 5eac +12442..12446 5eae +12447 5eb4 +12448..12451 5eba +12452..12461 5ebf +12462..12467 5ecb +12468..12469 5ed4 +12470..12473 5ed7 +12474..12476 5edc +12477..12480 5ee4 +12481 5ee9 +12482 5eeb +12483..12488 5eed +12489 5ef5 +12490..12491 5ef8 +12492..12494 5efb +12495..12497 5f05 +12498 5f09 +12499..12501 5f0c +12502 5f10 +12503 5f12 +12504 5f14 +12505 5f16 +12506..12507 5f19 +12508..12510 5f1c +12511..12514 5f21 +12515 5f28 +12516..12517 5f2b +12518 5f2e +12519 5f30 +12520 5f32 +12521 5f34 +12522..12524 5f36 +12525 5f3b +12526..12528 5f3d +12529..12533 5f41 +12534 5f47 +12535..12537 5f49 +12538 5f4d +12539 5f4f +12540 5f51 +12541 5f54 +12542..12544 5f5a +12545..12547 5f5e +12548 5f63 +12549 5f65 +12550..12551 5f67 +12552 5f6b +12553..12554 5f6e +12555 5f72 +12556..12558 5f74 +12559 5f78 +12560 5f7a +12561..12563 5f7d +12564 5f83 +12565 5f86 +12566..12568 5f8d +12569..12570 5f93 +12571 5f96 +12572..12573 5f9a +12574 5f9d +12575 5f9f +12576..12581 5fa2 +12582..12583 5fab +12584..12589 5faf +12590 5fb6 +12591 5fb8 +12592..12593 5fba +12594..12598 5fbe +12599..12600 5fc7 +12601..12602 5fca +12603 5fce +12604..12606 5fd3 +12607..12609 5fda +12610..12611 5fde +12612..12613 5fe2 +12614..12615 5fe5 +12616..12617 5fe8 +12618 5fec +12619..12620 5fef +12621..12623 5ff2 +12624..12625 5ff6 +12626..12627 5ff9 +12628 5ffc +12629..12631 6007 +12632..12633 600b +12634..12635 6010 +12636 6013 +12637..12638 6017 +12639 601a +12640..12641 601e +12642..12644 6022 +12645..12647 602c +12648..12652 6030 +12653..12657 6036 +12658..12659 603d +12660 6040 +12661..12667 6044 +12668 604c +12669..12670 604e +12671 6051 +12672..12673 6053 +12674..12676 6056 +12677..12678 605b +12679..12682 605e +12683..12684 6065 +12685 606e +12686..12687 6071 +12688..12689 6074 +12690 6077 +12691 607e +12692..12694 6080 +12695..12698 6085 +12699..12700 608a +12701..12704 608e +12705 6093 +12706 6095 +12707..12709 6097 +12710 609c +12711 609e +12712..12713 60a1 +12714..12715 60a4 +12716 60a7 +12717..12718 60a9 +12719 60ae +12720 60b0 +12721 60b3 +12722 60b7 +12723..12724 60b9 +12725..12732 60bd +12733..12735 60c7 +12736..12740 60cc +12741..12743 60d2 +12744..12745 60d6 +12746 60d9 +12747 60db +12748 60de +12749..12752 60e2 +12753 60ea +12754 60f5 +12755..12756 60f7 +12757..12760 60fc +12761..12764 6102 +12765 6107 +12766..12768 610a +12769..12773 6110 +12774..12777 6116 +12778..12779 611d +12780..12781 6121 +12782 6125 +12783..12785 6128 +12786..12793 612c +12794..12795 6135 +12796..12801 6138 +12802..12809 6140 +12810 6149 +12811 614d +12812..12813 614f +12814..12816 6152 +12817..12818 6156 +12819 6159 +12820..12821 615b +12822 615e +12823..12824 6160 +12825..12826 6165 +12827 6169 +12828..12829 616c +12830 616f +12831..12832 6171 +12833 6174 +12834..12843 6178 +12844..12850 6183 +12851..12852 618c +12853 618f +12854 6193 +12855..12859 6195 +12860..12861 619b +12862..12867 619e +12868..12869 61a5 +12870 61aa +12871 61ad +12872..12874 61af +12875..12877 61b3 +12878..12883 61b8 +12884..12886 61bf +12887..12890 61c3 +12891..12894 61cd +12895 61d3 +12896..12904 61d5 +12905..12907 61e0 +12908..12909 61e4 +12910 61e7 +12911..12919 61e9 +12920..12921 61f3 +12922 61f9 +12923 61fb +12924 61fd +12925..12929 6201 +12930 6209 +12931 6213 +12932 6219 +12933..12935 621c +12936 6220 +12937 6223 +12938 6226 +12939..12940 6228 +12941 622b +12942 622d +12943 622f +12944 6231 +12945..12946 6235 +12947..12951 6238 +12952 6242 +12953..12955 6244 +12956 624a +12957..12958 624f +12959..12961 6255 +12962..12963 6259 +12964..12970 625c +12971..12972 6264 +12973 6268 +12974..12975 6271 +12976..12977 6274 +12978..12979 6277 +12980..12981 627a +12982 627d +12983..12985 6281 +12986..12989 6285 +12990..12995 628b +12996 6294 +12997 6299 +12998..13000 629c +13001 62a3 +13002..13003 62a6 +13004..13005 62a9 +13006..13009 62ad +13010..13012 62b2 +13013..13015 62b6 +13016 62ba +13017 62be +13018..13019 62c0 +13020 62c3 +13021 62cb +13022 62cf +13023 62d1 +13024 62d5 +13025..13026 62dd +13027..13028 62e0 +13029 62e4 +13030..13031 62ea +13032 62f0 +13033 62f2 +13034 62f5 +13035..13038 62f8 +13039 6300 +13040..13043 6303 +13044..13047 630a +13048..13049 630f +13050..13053 6312 +13054..13056 6317 +13057 631c +13058..13059 6326 +13060 6329 +13061..13063 632c +13064..13065 6330 +13066..13071 6333 +13072..13073 633b +13074..13076 633f +13077 6344 +13078..13079 6347 +13080 634a +13081..13084 6351 +13085..13092 6356 +13093 6360 +13094..13096 6364 +13097 636a +13098 636c +13099..13100 636f +13101..13103 6373 +13104..13105 6378 +13106..13109 637c +13110 6381 +13111..13112 6385 +13113 638b +13114 638d +13115 6391 +13116..13118 6393 +13119 6397 +13120..13126 6399 +13127 63a1 +13128 63a4 +13129 63a6 +13130 63ab +13131 63af +13132..13133 63b1 +13134..13135 63b5 +13136 63b9 +13137 63bb +13138 63bd +13139 63bf +13140..13142 63c1 +13143 63c5 +13144..13145 63c7 +13146..13148 63ca +13149 63d1 +13150..13152 63d3 +13153..13155 63d7 +13156..13158 63db +13159 63df +13160 63e2 +13161..13165 63e4 +13166..13167 63eb +13168..13170 63ef +13171 63f3 +13172 63f5 +13173 63f7 +13174..13177 63f9 +13178 63fe +13179..13180 6403 +13181..13185 6406 +13186 640e +13187..13188 6411 +13189..13190 6415 +13191..13193 6418 +13194 641d +13195 641f +13196..13199 6422 +13200..13202 6427 +13203 642b +13204..13209 642e +13210 6435 +13211..13213 6437 +13214..13215 643b +13216 643e +13217 6440 +13218..13219 6442 +13220 6449 +13221..13226 644b +13227 6453 +13228..13230 6455 +13231..13233 6459 +13234 645d +13235..13241 6460 +13242 6468 +13243..13245 646a +13246 646e +13247..13249 6470 +13250..13251 6474 +13252 6477 +13253..13258 647c +13259 6483 +13260 6486 +13261..13268 6489 +13269 6494 +13270..13271 6497 +13272..13275 649a +13276..13278 64a0 +13279..13281 64a6 +13282 64aa +13283 64af +13284 64b1 +13285 64b4 +13286 64b6 +13287 64b9 +13288 64bd +13289 64c3 +13290 64c6 +13291..13292 64c8 +13293 64cc +13294 64cf +13295 64d1 +13296 64d3 +13297..13298 64d5 +13299 64d9 +13300..13302 64db +13303 64df +13304 64e1 +13305 64e3 +13306 64e5 +13307..13311 64e7 +13312..13313 64ed +13314 64f3 +13315..13316 64f5 +13317..13318 64f8 +13319 64fd +13320 64ff +13321..13323 6501 +13324 6505 +13325..13326 6507 +13327..13331 650a +13332..13333 6510 +13334 6513 +13335 6515 +13336 6517 +13337 651a +13338 651c +13339..13342 651e +13343..13346 6526 +13347 652d +13348..13351 6530 +13352 6537 +13353 653a +13354..13355 653c +13356..13360 6540 +13361..13362 6546 +13363..13364 654a +13365..13366 654d +13367 6550 +13368..13370 6552 +13371 6558 +13372 655a +13373 655c +13374..13376 655f +13377..13378 6564 +13379..13382 6567 +13383..13385 656d +13386 6571 +13387 6573 +13388 6576 +13389..13397 6579 +13398..13400 6584 +13401..13403 6588 +13404..13406 658d +13407 6592 +13408 6594 +13409 6596 +13410 6598 +13411 659a +13412..13413 659d +13414 65a0 +13415..13416 65a2 +13417 65a6 +13418 65a8 +13419 65aa +13420 65ae +13421..13426 65b1 +13427 65b8 +13428..13429 65ba +13430..13432 65be +13433 65c2 +13434..13437 65c7 +13438 65cd +13439..13440 65d0 +13441..13443 65d3 +13444..13451 65d8 +13452 65e1 +13453..13454 65e3 +13455..13456 65ea +13457..13460 65f2 +13461..13462 65f8 +13463..13467 65fb +13468 6601 +13469..13470 6604 +13471..13473 6607 +13474 660b +13475 660d +13476..13478 6610 +13479..13481 6616 +13482..13484 661a +13485 661e +13486..13489 6621 +13490 6626 +13491..13494 6629 +13495 662e +13496 6630 +13497..13498 6632 +13499..13503 6637 +13504 663d +13505..13506 663f +13507..13513 6644 +13514..13515 664d +13516..13517 6650 +13518..13519 6658 +13520..13521 665b +13522 665e +13523 6660 +13524..13525 6662 +13526 6665 +13527 6667 +13528..13532 6669 +13533..13535 6671 +13536 6675 +13537..13538 6678 +13539..13541 667b +13542..13544 667f +13545 6683 +13546..13547 6685 +13548..13549 668a +13550..13553 668d +13554..13557 6692 +13558..13562 6698 +13563..13566 669e +13567..13570 66a3 +13571..13572 66a9 +13573..13574 66ac +13575..13579 66af +13580..13583 66b5 +13584..13587 66ba +13588..13592 66bf +13593 66c5 +13594 66c8 +13595..13606 66ca +13607..13608 66d7 +13609 66da +13610..13611 66de +13612..13616 66e1 +13617..13618 66e7 +13619..13620 66ea +13621..13623 66ed +13624 66f1 +13625..13626 66f5 +13627..13628 66fa +13629 66fd +13630..13631 6701 +13632..13635 6704 +13636 670c +13637..13638 670e +13639..13641 6711 +13642 6716 +13643..13645 6718 +13646 671c +13647 671e +13648..13653 6720 +13654 6729 +13655 672e +13656 6730 +13657..13658 6732 +13659..13662 6736 +13663..13664 673b +13665..13666 673e +13667 6741 +13668..13669 6744 +13670 6747 +13671..13672 674a +13673 674d +13674 6752 +13675..13676 6754 +13677..13681 6757 +13682 675d +13683..13685 6762 +13686..13687 6766 +13688..13689 676b +13690 676e +13691 6774 +13692 6776 +13693..13696 6778 +13697 677d +13698 6780 +13699..13700 6782 +13701..13702 6785 +13703 6788 +13704 678a +13705..13708 678c +13709..13712 6791 +13713 6796 +13714 6799 +13715 679b +13716..13718 679f +13719 67a4 +13720 67a6 +13721 67a9 +13722 67ac +13723 67ae +13724..13725 67b1 +13726 67b4 +13727..13734 67b9 +13735 67c2 +13736..13745 67c5 +13746..13748 67d5 +13749 67db +13750 67df +13751 67e1 +13752..13753 67e3 +13754..13756 67e6 +13757..13758 67ea +13759..13760 67ed +13761 67f2 +13762..13769 67f5 +13770 67fe +13771..13774 6801 +13775 6806 +13776 680d +13777 6810 +13778 6812 +13779..13780 6814 +13781..13785 6818 +13786..13788 681e +13789..13795 6822 +13796..13802 682b +13803..13805 6834 +13806..13807 683a +13808 683f +13809 6847 +13810 684b +13811 684d +13812 684f +13813 6852 +13814..13823 6856 +13824 686a +13825..13832 686c +13833 6875 +13834..13842 6878 +13843 6882 +13844 6884 +13845..13852 6887 +13853..13855 6890 +13856..13858 6894 +13859..13862 6899 +13863 689e +13864..13865 68a0 +13866..13868 68a3 +13869..13872 68a9 +13873 68ae +13874..13875 68b1 +13876 68b4 +13877..13886 68b6 +13887 68c1 +13888..13893 68c3 +13894 68ca +13895 68cc +13896..13899 68ce +13900..13901 68d3 +13902 68d9 +13903..13906 68db +13907..13908 68e1 +13909..13911 68e4 +13912..13917 68e8 +13918 68ef +13919..13921 68f2 +13922..13924 68f6 +13925 68fb +13926..13929 68fd +13930..13932 6902 +13933..13937 6906 +13938 690c +13939 6911 +13940..13951 6913 +13952..13954 6921 +13955..13962 6925 +13963..13964 692e +13965..13967 6931 +13968..13971 6935 +13972..13974 693a +13975 693e +13976..13977 6940 +13978..13984 6943 +13985..13992 694b +13993..13994 6955 +13995..13996 6958 +13997..13998 695b +13999 695f +14000..14001 6961 +14002..14003 6964 +14004 6967 +14005..14006 6969 +14007 696c +14008..14009 696f +14010..14012 6972 +14013 6976 +14014..14015 697a +14016..14018 697d +14019 6981 +14020 6983 +14021 6985 +14022..14024 698a +14025..14030 698e +14031..14032 6996 +14033..14034 6999 +14035..14044 699d +14045 69a9 +14046 69ac +14047..14048 69af +14049..14050 69b2 +14051..14052 69b5 +14053..14055 69b8 +14056..14058 69bc +14059 69c0 +14060..14067 69c2 +14068 69cf +14069..14071 69d1 +14072..14077 69d5 +14078..14080 69dc +14081..14086 69e1 +14087..14091 69e8 +14092..14095 69ee +14096..14104 69f4 +14105 69fe +14106 6a00 +14107..14108 6a03 +14109..14112 6a06 +14113..14120 6a0b +14121..14123 6a14 +14124..14127 6a1a +14128 6a20 +14129 6a22 +14130..14133 6a24 +14134 6a29 +14135..14138 6a2b +14139 6a30 +14140..14142 6a32 +14143..14144 6a36 +14145..14146 6a3b +14147..14151 6a3f +14152..14153 6a45 +14154..14155 6a49 +14156..14159 6a4c +14160..14166 6a51 +14167 6a5a +14168..14170 6a5c +14171 6a60 +14172..14173 6a63 +14174..14184 6a66 +14185..14191 6a72 +14192..14193 6a7a +14194..14196 6a7d +14197..14199 6a81 +14200..14203 6a85 +14204..14207 6a8a +14208 6a8f +14209..14210 6a92 +14211..14212 6a95 +14213..14216 6a98 +14217..14219 6a9d +14220 6aa1 +14221..14225 6aa4 +14226 6aaa +14227..14228 6aad +14229..14231 6ab0 +14232..14235 6ab4 +14236..14237 6ab9 +14238..14244 6abc +14245..14259 6ac4 +14260..14265 6ad4 +14266 6adc +14267..14273 6ae0 +14274 6ae9 +14275 6aeb +14276..14281 6aed +14282..14285 6af4 +14286..14287 6af9 +14288..14295 6afc +14296..14300 6b05 +14301..14304 6b0b +14305..14306 6b10 +14307..14309 6b13 +14310..14316 6b17 +14317 6b1f +14318..14319 6b25 +14320..14329 6b28 +14330..14333 6b33 +14334 6b38 +14335..14336 6b3b +14337..14340 6b3f +14341..14342 6b44 +14343 6b48 +14344..14345 6b4a +14346..14348 6b4d +14349..14356 6b51 +14357..14361 6b5a +14362 6b60 +14363..14364 6b68 +14365..14371 6b6b +14372..14375 6b73 +14376 6b7a +14377..14380 6b7d +14381 6b85 +14382 6b88 +14383 6b8c +14384..14387 6b8e +14388..14389 6b94 +14390 6b97 +14391 6b99 +14392..14393 6b9c +14394..14395 6b9f +14396..14397 6ba2 +14398..14402 6ba5 +14403..14404 6bac +14405..14406 6bb0 +14407 6bb6 +14408..14409 6bb8 +14410..14412 6bbc +14413 6bc0 +14414..14415 6bc3 +14416..14419 6bc7 +14420 6bcc +14421 6bce +14422..14423 6bd0 +14424 6bd8 +14425 6bda +14426..14430 6bdc +14431..14438 6be2 +14439..14441 6bec +14442..14444 6bf0 +14445 6bf4 +14446..14448 6bf6 +14449..14451 6bfa +14452 6bfe +14453..14457 6c00 +14458..14460 6c09 +14461 6c0e +14462 6c12 +14463 6c17 +14464..14466 6c1c +14467 6c20 +14468 6c25 +14469 6c2d +14470 6c31 +14471 6c33 +14472..14473 6c36 +14474..14477 6c39 +14478..14479 6c3e +14480..14482 6c43 +14483 6c48 +14484..14488 6c4b +14489..14491 6c51 +14492 6c56 +14493..14495 6c58 +14496..14497 6c62 +14498..14500 6c65 +14501..14505 6c6b +14506 6c71 +14507 6c73 +14508 6c75 +14509..14510 6c77 +14511..14513 6c7a +14514..14515 6c7f +14516 6c84 +14517 6c87 +14518..14519 6c8a +14520..14521 6c8d +14522..14523 6c91 +14524..14527 6c95 +14528 6c9a +14529..14531 6c9c +14532 6ca0 +14533 6ca2 +14534 6ca8 +14535 6cac +14536..14537 6caf +14538..14541 6cb4 +14542 6cba +14543..14546 6cc0 +14547..14549 6cc6 +14550 6ccb +14551..14553 6ccd +14554..14555 6cd1 +14556..14558 6cd8 +14559..14560 6cdc +14561 6cdf +14562 6ce4 +14563..14564 6ce6 +14565 6ce9 +14566..14567 6cec +14568 6cf2 +14569 6cf4 +14570 6cf9 +14571..14572 6cff +14573..14574 6d02 +14575..14576 6d05 +14577..14579 6d08 +14580 6d0d +14581..14583 6d0f +14584..14587 6d13 +14588 6d18 +14589..14590 6d1c +14591..14596 6d1f +14597 6d26 +14598..14599 6d28 +14600..14601 6d2c +14602..14603 6d2f +14604 6d34 +14605..14607 6d36 +14608 6d3a +14609..14610 6d3f +14611 6d42 +14612 6d44 +14613 6d49 +14614 6d4c +14615 6d50 +14616..14619 6d55 +14620 6d5b +14621 6d5d +14622 6d5f +14623..14624 6d61 +14625..14626 6d64 +14627..14628 6d67 +14629..14631 6d6b +14632..14635 6d70 +14636..14637 6d75 +14638..14639 6d7a +14640..14644 6d7d +14645..14646 6d83 +14647 6d86 +14648..14649 6d8a +14650 6d8d +14651..14652 6d8f +14653 6d92 +14654..14658 6d96 +14659 6d9c +14660 6da2 +14661 6da5 +14662..14663 6dac +14664..14665 6db0 +14666..14667 6db3 +14668..14669 6db6 +14670..14675 6db9 +14676..14678 6dc1 +14679..14681 6dc8 +14682..14685 6dcd +14686..14689 6dd2 +14690 6dd7 +14691..14693 6dda +14694 6ddf +14695..14696 6de2 +14697 6de5 +14698..14700 6de7 +14701 6ded +14702..14703 6def +14704 6df2 +14705 6df4 +14706 6df8 +14707..14714 6dfd +14715..14718 6e06 +14719 6e0b +14720 6e0f +14721..14722 6e12 +14723 6e15 +14724..14725 6e18 +14726..14727 6e1b +14728..14729 6e1e +14730 6e22 +14731..14732 6e27 +14733 6e2a +14734 6e2e +14735..14736 6e30 +14737 6e33 +14738..14740 6e35 +14741 6e39 +14742..14744 6e3b +14745..14748 6e3f +14749..14756 6e45 +14757..14760 6e4f +14761 6e55 +14762 6e57 +14763..14764 6e59 +14765..14766 6e5c +14767..14777 6e60 +14778..14779 6e6c +14780..14793 6e70 +14794..14796 6e80 +14797 6e84 +14798..14799 6e87 +14800..14804 6e8a +14805..14809 6e91 +14810 6e97 +14811..14813 6e99 +14814 6e9e +14815..14816 6ea0 +14817..14818 6ea3 +14819 6ea6 +14820..14821 6ea8 +14822..14825 6eab +14826 6eb0 +14827 6eb3 +14828 6eb5 +14829..14830 6eb8 +14831 6ebc +14832..14834 6ebe +14835 6ec3 +14836 6ec6 +14837..14839 6ec8 +14840 6ecd +14841 6ed0 +14842 6ed2 +14843 6ed6 +14844..14845 6ed8 +14846..14848 6edb +14849 6ee3 +14850 6ee7 +14851..14852 6eea +14853..14854 6eed +14855..14856 6ef0 +14857 6ef3 +14858..14859 6ef5 +14860..14864 6efa +14865 6f00 +14866..14868 6f03 +14869..14870 6f07 +14871..14875 6f0a +14876..14878 6f10 +14879..14882 6f16 +14883..14887 6f1b +14888 6f21 +14889..14892 6f25 +14893 6f2e +14894 6f30 +14895..14896 6f34 +14897 6f37 +14898..14902 6f39 +14903 6f40 +14904..14907 6f42 +14908..14910 6f48 +14911 6f4c +14912..14914 6f4e +14915..14916 6f52 +14917..14919 6f55 +14920..14921 6f5a +14922 6f5d +14923..14925 6f5f +14926 6f63 +14927 6f65 +14928..14933 6f67 +14934 6f71 +14935 6f73 +14936..14937 6f75 +14938 6f79 +14939 6f7b +14940..14941 6f7d +14942..14944 6f81 +14945 6f85 +14946..14947 6f8a +14948..14955 6f8f +14956..14959 6f98 +14960..14962 6f9d +14963..14964 6fa2 +14965..14966 6fa5 +14967 6fa8 +14968..14971 6faa +14972..14973 6faf +14974 6fb2 +14975..14976 6fb4 +14977..14978 6fb7 +14979..14984 6fba +14985..14989 6fc4 +14990..14996 6fca +14997..14998 6fd3 +14999..15000 6fd6 +15001..15002 6fd9 +15003..15004 6fdc +15005..15006 6fe2 +15007..15012 6fe5 +15013..15014 6fec +15015..15022 6ff2 +15023 6ffb +15024 6ffd +15025..15030 6fff +15031..15032 7007 +15033 700a +15034..15036 700c +15037 7010 +15038..15040 7012 +15041..15042 7016 +15043 7019 +15044 701c +15045 701e +15046..15047 7021 +15048..15050 7024 +15051..15057 7029 +15058 7031 +15059..15060 7033 +15061..15063 7036 +15064..15067 703a +15068..15071 703f +15072..15078 7045 +15079..15080 704d +15081 7050 +15082..15084 7052 +15085..15086 7056 +15087..15090 7059 +15091..15094 705f +15095..15096 7065 +15097..15099 7068 +15100 706e +15101..15104 7071 +15105 7077 +15106..15108 7079 +15109 707d +15110..15113 7081 +15114..15116 7086 +15117..15119 708b +15120..15122 708f +15123 7093 +15124..15125 7097 +15126..15127 709a +15128..15140 709e +15141 70b0 +15142 70b2 +15143..15145 70b4 +15146 70ba +15147..15148 70be +15149..15152 70c4 +15153 70c9 +15154..15157 70cb +15158..15165 70d0 +15166 70da +15167..15169 70dc +15170..15173 70e0 +15174 70e5 +15175 70ea +15176 70ee +15177..15180 70f0 +15181..15182 70f5 +15183 70f8 +15184..15186 70fa +15187..15197 70fe +15198..15202 710b +15203..15204 7111 +15205 7114 +15206 7117 +15207..15212 711b +15213..15216 7122 +15217..15224 7127 +15225..15228 7132 +15229..15242 7137 +15243..15245 7146 +15246 714b +15247 714d +15248..15250 714f +15251..15259 7153 +15260 715d +15261..15263 715f +15264 7163 +15265 7165 +15266..15267 716a +15268 716d +15269..15271 716f +15272..15275 7174 +15276 7179 +15277..15278 717b +15279..15284 717e +15285..15289 7185 +15290..15293 718b +15294..15295 7190 +15296 7193 +15297..15298 7195 +15299..15303 719a +15304..15310 71a1 +15311..15313 71a9 +15314..15317 71ad +15318 71b2 +15319 71b4 +15320..15322 71b6 +15323..15326 71ba +15327..15328 71bf +15329 71c2 +15330..15333 71c4 +15334..15338 71c9 +15339..15341 71cf +15342 71d3 +15343..15345 71d6 +15346..15347 71da +15348..15349 71dd +15350..15353 71e1 +15354..15358 71e8 +15359..15363 71ef +15364..15367 71f5 +15368..15369 71fa +15370 71fd +15371..15377 71ff +15378..15383 7207 +15384..15385 720e +15386..15395 7211 +15396 721c +15397..15406 721e +15407 7229 +15408 722b +15409..15411 722d +15412..15413 7233 +15414 723c +15415..15421 7240 +15422..15424 7249 +15425..15428 724e +15429..15431 7253 +15432 7257 +15433 725a +15434 725c +15435 725e +15436 7260 +15437..15439 7263 +15440 7268 +15441..15444 726a +15445..15446 7270 +15447..15448 7273 +15449..15451 7276 +15452..15453 727b +15454..15455 7282 +15456..15460 7285 +15461 728c +15462 728e +15463..15464 7290 +15465..15467 7293 +15468..15475 7297 +15476..15477 72a0 +15478..15481 72a3 +15482..15485 72a8 +15486 72ae +15487..15489 72b1 +15490 72b5 +15491..15496 72ba +15497..15499 72c5 +15500..15503 72c9 +15504 72cf +15505 72d1 +15506..15509 72d3 +15510 72d8 +15511..15514 72da +15515 72df +15516..15521 72e2 +15522..15523 72ea +15524..15525 72f5 +15526..15528 72fe +15529 7302 +15530..15535 7304 +15536..15538 730b +15539..15542 730f +15543 7314 +15544..15546 7318 +15547..15548 731f +15549..15550 7323 +15551..15553 7326 +15554 732d +15555..15556 732f +15557..15558 7332 +15559 7335 +15560 733a +15561..15562 733c +15563 7340 +15564..15565 7342 +15566..15572 7346 +15573..15574 734e +15575 7351 +15576..15579 7353 +15580..15587 7358 +15588..15594 7361 +15595 7369 +15596 736e +15597 7371 +15598..15599 7373 +15600 7376 +15601 7379 +15602 737d +15603 737f +15604..15606 7381 +15607..15608 7385 +15609 7388 +15610 738a +15611..15612 738c +15613..15614 738f +15615..15618 7392 +15619..15622 7397 +15623..15625 739c +15626..15627 73a0 +15628..15633 73a3 +15634 73aa +15635..15636 73ac +15637 73b1 +15638..15640 73b4 +15641..15642 73b8 +15643..15646 73bc +15647 73c1 +15648..15652 73c3 +15653..15654 73cb +15655 73ce +15656..15662 73d2 +15663..15666 73da +15667 73df +15668..15671 73e1 +15672 73e6 +15673 73e8 +15674..15676 73ea +15677..15680 73ee +15681..15691 73f3 +15692..15695 73ff +15696 7404 +15697..15698 7407 +15699..15702 740b +15703..15711 7411 +15712..15717 741c +15718..15719 7423 +15720 7427 +15721 7429 +15722 742b +15723 742d +15724 742f +15725..15726 7431 +15727..15731 7437 +15732..15733 743d +15734 7440 +15735..15743 7442 +15744..15752 744c +15753 7456 +15754 7458 +15755 745d +15756..15758 7460 +15759..15763 7464 +15764..15765 746b +15766..15767 746e +15768..15772 7471 +15773..15778 7478 +15779 747f +15780 7482 +15781..15783 7484 +15784 7488 +15785 748a +15786..15787 748c +15788 748f +15789..15799 7491 +15800 749d +15801..15804 749f +15805..15806 74a4 +15807..15812 74aa +15813..15821 74b1 +15822..15823 74bb +15824..15835 74be +15836..15839 74cb +15840..15841 74d0 +15842 74d3 +15843..15847 74d5 +15848 74db +15849 74dd +15850 74df +15851 74e1 +15852 74e5 +15853..15859 74e7 +15860..15863 74f0 +15864 74f5 +15865..15871 74f8 +15872..15875 7500 +15876..15882 7505 +15883 750e +15884 7510 +15885 7512 +15886..15889 7514 +15890 751b +15891..15892 751d +15893..15895 7520 +15896 7524 +15897..15898 7526 +15899 752a +15900 752e +15901 7534 +15902 7536 +15903 7539 +15904..15905 753c +15906 753f +15907..15910 7541 +15911..15912 7546 +15913..15914 7549 +15915 754d +15916..15919 7550 +15920..15923 7555 +15924..15927 755e +15928..15929 7563 +15930..15932 7567 +15933..15938 756c +15939 7573 +15940 7575 +15941 7577 +15942..15946 757a +15947..15949 7580 +15950..15951 7584 +15952..15954 7588 +15955..15957 758c +15958 7590 +15959 7593 +15960 7595 +15961 7598 +15962..15963 759b +15964 759e +15965 75a2 +15966..15970 75a6 +15971 75ad +15972..15973 75b6 +15974..15975 75ba +15976..15978 75bf +15979 75c6 +15980..15981 75cb +15982..15985 75ce +15986 75d3 +15987 75d7 +15988 75da +15989..15990 75dc +15991..15993 75df +15994 75e5 +15995 75e9 +15996..15999 75ec +16000..16001 75f2 +16002..16005 75f5 +16006..16007 75fa +16008..16009 75fd +16010 7604 +16011..16014 7606 +16015..16016 760e +16017..16020 7611 +16021 7616 +16022 761a +16023..16024 761c +16025 7623 +16026 7628 +16027 762c +16028..16029 762e +16030..16031 7631 +16032..16033 7636 +16034..16035 7639 +16036 763d +16037 7641 +16038..16039 7644 +16040 7648 +16041..16042 764a +16043..16048 764e +16049 7655 +16050 7657 +16051..16053 7659 +16054 765d +16055..16056 7660 +16057 7666 +16058 7668 +16059 766a +16060..16064 7673 +16065..16066 7679 +16067..16069 767f +16070 7683 +16071 7685 +16072..16073 7689 +16074..16075 768c +16076..16077 768f +16078 7692 +16079..16080 7694 +16081..16082 7697 +16083..16091 769b +16092..16100 76a5 +16101..16102 76af +16103 76b3 +16104..16106 76b5 +16107 76b9 +16108..16111 76bb +16112..16113 76c0 +16114..16115 76c3 +16116 76c7 +16117 76c9 +16118..16119 76cb +16120 76d3 +16121 76d5 +16122..16123 76d9 +16124..16125 76dc +16126 76e0 +16127 76e2 +16128 76e6 +16129..16134 76e8 +16135 76f0 +16136 76f3 +16137..16139 76f5 +16140..16141 76fa +16142 76fd +16143..16144 76ff +16145..16146 7702 +16147..16148 7705 +16149 770a +16150 770c +16151..16161 770e +16162..16165 771b +16166 7721 +16167..16169 7723 +16170 7727 +16171..16173 772a +16174 772e +16175..16179 7730 +16180 7739 +16181 773b +16182..16184 773d +16185 7742 +16186..16188 7744 +16189..16195 7748 +16196..16203 7752 +16204..16205 775c +16206..16207 775f +16208 7764 +16209 7767 +16210..16211 7769 +16212..16223 776d +16224..16226 777a +16227..16229 7781 +16230..16235 7786 +16236..16237 778f +16238..16242 7793 +16243..16247 7799 +16248 77a1 +16249..16250 77a3 +16251 77a6 +16252 77a8 +16253 77ab +16254..16255 77ae +16256..16257 77b1 +16258 77b4 +16259..16263 77b6 +16264 77be +16265..16271 77c0 +16272..16276 77c8 +16277..16285 77ce +16286..16287 77d8 +16288..16292 77dd +16293 77e4 +16294 77e6 +16295 77e8 +16296 77ea +16297..16299 77f0 +16300..16301 77f4 +16302 77f7 +16303..16306 77f9 +16307..16312 7803 +16313..16314 780a +16315..16317 780e +16318 7813 +16319 7815 +16320 7819 +16321 781b +16322 781e +16323..16325 7820 +16326 7824 +16327 7828 +16328..16329 782a +16330..16331 782e +16332..16334 7831 +16335..16336 7835 +16337 783d +16338 783f +16339..16340 7841 +16341 7844 +16342 7846 +16343..16346 7848 +16347 784d +16348 784f +16349 7851 +16350..16351 7853 +16352..16356 7858 +16357..16362 785e +16363..16365 7865 +16366 7869 +16367..16373 7870 +16374..16377 7878 +16378..16387 787d +16388 7888 +16389..16390 788a +16391..16392 788f +16393 7892 +16394..16396 7894 +16397 7899 +16398..16399 789d +16400 78a0 +16401 78a2 +16402 78a4 +16403 78a6 +16404 78a8 +16405..16407 78aa +16408..16409 78ae +16410..16412 78b5 +16413 78bb +16414 78bd +16415..16416 78bf +16417..16419 78c2 +16420..16422 78c6 +16423..16426 78cc +16427..16429 78d1 +16430..16432 78d6 +16433..16440 78db +16441..16443 78e4 +16444..16446 78e9 +16447..16448 78ed +16449..16450 78f0 +16451 78f3 +16452..16453 78f5 +16454..16455 78f8 +16456..16457 78fb +16458..16460 78fe +16461..16463 7902 +16464..16471 7906 +16472..16475 790f +16476..16480 7914 +16481..16484 791a +16485..16489 791f +16490 7925 +16491..16493 7927 +16494..16497 792d +16498..16499 7932 +16500..16504 7935 +16505 793d +16506 793f +16507..16510 7942 +16511 7947 +16512..16520 794a +16521..16522 7954 +16523..16524 7958 +16525 7961 +16526..16527 7963 +16528 7966 +16529..16532 7969 +16533 796e +16534..16540 7970 +16541 7979 +16542..16546 797b +16547..16548 7982 +16549..16552 7986 +16553..16554 798b +16555..16564 7990 +16565..16575 799b +16576..16577 79a8 +16578..16580 79ab +16581 79af +16582 79b2 +16583..16587 79b4 +16588 79bc +16589 79bf +16590 79c2 +16591..16592 79c4 +16593..16594 79c7 +16595 79ca +16596 79cc +16597..16599 79ce +16600..16601 79d3 +16602..16603 79d6 +16604..16609 79d9 +16610..16612 79e0 +16613 79e5 +16614 79e8 +16615 79ea +16616 79ec +16617 79ee +16618..16624 79f1 +16625..16626 79f9 +16627 79fc +16628..16629 79fe +16630 7a01 +16631..16632 7a04 +16633..16636 7a07 +16637 7a0c +16638..16642 7a0f +16643..16644 7a15 +16645..16646 7a18 +16647..16649 7a1b +16650 7a1f +16651..16652 7a21 +16653..16662 7a24 +16663..16664 7a2f +16665 7a32 +16666..16668 7a34 +16669 7a38 +16670 7a3a +16671 7a3e +16672..16676 7a41 +16677..16681 7a47 +16682..16683 7a4f +16684..16688 7a52 +16689..16697 7a58 +16698..16703 7a63 +16704 7a6a +16705..16708 7a6c +16709..16711 7a71 +16712 7a75 +16713..16716 7a7b +16717 7a82 +16718 7a85 +16719 7a87 +16720..16723 7a89 +16724..16726 7a8e +16727..16728 7a93 +16729..16731 7a99 +16732 7a9e +16733..16736 7aa1 +16737 7aa7 +16738 7aab +16739..16742 7aaf +16743..16744 7ab4 +16745..16747 7ab7 +16748..16751 7abb +16752..16755 7ac0 +16756 7ac6 +16757 7ac9 +16758..16767 7acc +16768..16769 7ad7 +16770..16773 7ada +16774..16775 7ae1 +16776 7ae4 +16777..16779 7ae7 +16780..16781 7aeb +16782 7aee +16783..16788 7af0 +16789..16790 7af7 +16791..16792 7afb +16793 7afe +16794..16796 7b00 +16797 7b05 +16798 7b07 +16799 7b09 +16800..16802 7b0c +16803 7b10 +16804..16805 7b12 +16806..16808 7b16 +16809 7b1a +16810..16811 7b1c +16812 7b1f +16813..16815 7b21 +16816 7b27 +16817 7b29 +16818 7b2d +16819..16820 7b2f +16821 7b32 +16822..16825 7b34 +16826 7b39 +16827 7b3b +16828 7b3d +16829..16834 7b3f +16835 7b48 +16836 7b4a +16837..16838 7b4d +16839 7b53 +16840 7b55 +16841 7b57 +16842 7b59 +16843 7b5c +16844..16845 7b5e +16846 7b61 +16847..16850 7b63 +16851..16856 7b68 +16857..16858 7b6f +16859..16860 7b73 +16861 7b76 +16862 7b78 +16863 7b7a +16864..16865 7b7c +16866 7b7f +16867..16870 7b81 +16871..16875 7b86 +16876 7b8c +16877..16878 7b8e +16879..16881 7b91 +16882 7b96 +16883..16886 7b98 +16887..16889 7b9e +16890..16892 7ba3 +16893..16895 7bae +16896..16897 7bb2 +16898..16900 7bb5 +16901..16907 7bb9 +16908..16909 7bc2 +16910 7bc5 +16911 7bc8 +16912 7bca +16913..16916 7bcd +16917 7bd2 +16918..16922 7bd4 +16923..16924 7bdb +16925..16927 7bde +16928..16929 7be2 +16930..16931 7be7 +16932..16934 7beb +16935..16936 7bef +16937 7bf2 +16938..16940 7bf4 +16941..16944 7bf8 +16945 7bfd +16946 7bff +16947..16952 7c01 +16953..16955 7c08 +16956 7c0e +16957..16962 7c10 +16963..16969 7c17 +16970 7c20 +16971 7c22 +16972..16973 7c24 +16974..16975 7c28 +16976..16987 7c2c +16988..16991 7c39 +16992 7c42 +16993..17000 7c44 +17001..17014 7c4e +17015..17016 7c5d +17017..17019 7c61 +17020..17023 7c65 +17024 7c6b +17025 7c6d +17026..17028 7c6f +17029..17034 7c75 +17035..17045 7c7e +17046..17052 7c8a +17053..17054 7c93 +17055 7c96 +17056..17058 7c99 +17059..17060 7ca0 +17061 7ca3 +17062..17065 7ca6 +17066..17068 7cab +17069..17070 7caf +17071..17075 7cb4 +17076..17077 7cba +17078..17079 7cbf +17080..17082 7cc2 +17083 7cc6 +17084 7cc9 +17085 7ccb +17086..17092 7cce +17093 7cd8 +17094..17095 7cda +17096..17101 7ce1 +17102..17107 7ce9 +17108 7cf1 +17109 7cf3 +17110 7cf5 +17111 7cf7 +17112 7cfa +17113..17114 7cfc +17115 7cff +17116 7d01 +17117 7d03 +17118 7d0c +17119..17120 7d0e +17121..17122 7d11 +17123 7d16 +17124 7d18 +17125..17127 7d1d +17128..17131 7d23 +17132..17134 7d28 +17135..17137 7d2c +17138..17142 7d34 +17143 7d3b +17144..17145 7d3d +17146 7d41 +17147 7d43 +17148 7d45 +17149..17155 7d47 +17156 7d4f +17157..17168 7d51 +17169..17170 7d5f +17171..17173 7d63 +17174 7d67 +17175..17179 7d69 +17180..17181 7d6f +17182..17183 7d74 +17184 7d78 +17185..17191 7d7a +17192 7d82 +17193..17194 7d84 +17195 7d87 +17196..17200 7d8a +17201..17203 7d90 +17204..17211 7d94 +17212 7d9d +17213..17215 7d9f +17216..17217 7da4 +17218..17221 7da7 +17222 7daf +17223..17225 7db5 +17226 7dbc +17227..17230 7dc0 +17231..17232 7dc5 +17233..17234 7dc8 +17235..17239 7dcc +17240 7dd3 +17241..17242 7dd5 +17243..17245 7dda +17246 7ddf +17247 7de2 +17248..17249 7de4 +17250 7de7 +17251..17252 7dea +17253..17254 7ded +17255 7df0 +17256 7df3 +17257 7df5 +17258..17259 7df7 +17260 7dfa +17261..17272 7dfc +17273..17276 7e0c +17277..17285 7e12 +17286 7e1c +17287..17289 7e20 +17290..17292 7e24 +17293..17295 7e28 +17296 7e2c +17297..17298 7e2f +17299 7e33 +17300 7e38 +17301 7e3a +17302 7e3c +17303..17304 7e3f +17305..17307 7e42 +17308..17317 7e48 +17318 7e53 +17319..17322 7e56 +17323..17325 7e5b +17326..17328 7e5f +17329..17334 7e63 +17335 7e6c +17336..17337 7e71 +17338..17342 7e74 +17343..17344 7e7a +17345..17347 7e7f +17348..17352 7e83 +17353 7e89 +17354 7e8b +17355 7e8e +17356..17358 7e90 +17359 7e95 +17360 7e97 +17361..17362 7e99 +17363..17364 7e9d +17365 7eae +17366 7eb4 +17367..17368 7ebb +17369 7ed6 +17370 7ee4 +17371 7eec +17372 7ef9 +17373 7f0a +17374 7f10 +17375 7f1e +17376 7f37 +17377 7f39 +17378..17384 7f3b +17385 7f43 +17386..17391 7f46 +17392 7f4d +17393 7f4f +17394..17395 7f52 +17396 7f56 +17397 7f59 +17398..17401 7f5b +17402 7f60 +17403..17407 7f63 +17408..17410 7f6b +17411 7f6f +17412 7f73 +17413..17414 7f75 +17415 7f78 +17416..17419 7f7a +17420..17421 7f7f +17422..17424 7f82 +17425 7f87 +17426 7f89 +17427 7f8b +17428 7f8d +17429..17433 7f8f +17434..17438 7f95 +17439..17440 7f9b +17441 7fa0 +17442..17443 7fa2 +17444 7fa6 +17445 7fa8 +17446..17450 7faa +17451 7fb1 +17452..17456 7fb3 +17457..17458 7fba +17459 7fbe +17460 7fc0 +17461..17463 7fc2 +17464..17467 7fc6 +17468 7fcb +17469 7fcd +17470..17472 7fcf +17473 7fd3 +17474..17475 7fd6 +17476..17481 7fd9 +17482..17484 7fe2 +17485..17486 7fe7 +17487..17490 7fea +17491 7fef +17492 7ff2 +17493..17497 7ff4 +17498 7ffa +17499..17501 7ffd +17502 8002 +17503..17506 8007 +17507..17508 800e +17509 8011 +17510 8013 +17511..17512 801a +17513..17515 801d +17516 8021 +17517..17518 8023 +17519 802b +17520 802d +17521..17522 802f +17523 8032 +17524 8034 +17525..17526 8039 +17527 803c +17528 803e +17529..17530 8040 +17531..17532 8044 +17533..17535 8047 +17536..17539 804e +17540 8053 +17541 8055 +17542 8057 +17543 8059 +17544..17546 805b +17547..17556 805f +17557..17560 806b +17561 8074 +17562 8078 +17563..17565 807a +17566..17567 8081 +17568 8088 +17569 808a +17570..17575 808d +17576..17577 8094 +17578 8097 +17579 8099 +17580 809e +17581 80a3 +17582..17584 80a6 +17585 80ac +17586 80b0 +17587 80b3 +17588..17589 80b5 +17590..17591 80b8 +17592 80bb +17593 80c5 +17594..17598 80c7 +17599..17605 80cf +17606 80d8 +17607..17608 80df +17609..17610 80e2 +17611 80e6 +17612 80ee +17613 80f5 +17614 80f7 +17615 80f9 +17616 80fb +17617..17620 80fe +17621..17622 8103 +17623..17624 8107 +17625..17626 810b +17627 8115 +17628 8117 +17629 8119 +17630..17631 811c +17632..17644 811f +17645..17646 812d +17647 8130 +17648..17650 8133 +17651 8137 +17652..17655 813a +17656..17662 813f +17663 8147 +17664 8149 +17665 814d +17666 814f +17667 8152 +17668..17669 8157 +17670..17674 815b +17675..17677 8162 +17678 8168 +17679 816a +17680 816c +17681 816f +17682..17683 8172 +17684..17686 8175 +17687 8181 +17688..17692 8183 +17693 8189 +17694..17697 818b +17698 8190 +17699..17704 8192 +17705 8199 +17706..17707 819e +17708..17709 81a1 +17710..17711 81a4 +17712 81a7 +17713..17720 81ab +17721..17726 81b4 +17727 81bc +17728..17729 81c4 +17730..17731 81c7 +17732 81cb +17733 81ce +17734..17741 81d0 +17742 81d9 +17743..17746 81db +17747..17748 81e1 +17749..17751 81e4 +17752 81e9 +17753 81eb +17754..17758 81ee +17759..17763 81f5 +17764 81fd +17765 81ff +17766 8203 +17767 820b +17768..17769 820e +17770 8211 +17771 8213 +17772..17777 8215 +17778 821d +17779 8220 +17780..17783 8224 +17784 8229 +17785 822e +17786 8232 +17787 823a +17788..17789 823c +17790..17794 823f +17795..17796 8245 +17797 8248 +17798 824a +17799..17801 824c +17802..17809 8250 +17810..17813 825b +17814..17817 8260 +17818 8265 +17819 8267 +17820..17821 8269 +17822..17823 826c +17824..17825 8275 +17826 8278 +17827..17828 827b +17829..17830 8280 +17831 8283 +17832..17834 8285 +17835 8289 +17836 828c +17837 8290 +17838..17841 8293 +17842..17843 829a +17844 829e +17845 82a0 +17846..17847 82a2 +17848 82a7 +17849 82b2 +17850..17851 82b5 +17852 82ba +17853 82bc +17854..17855 82bf +17856..17857 82c2 +17858..17859 82c5 +17860 82c9 +17861 82d0 +17862 82d6 +17863..17864 82d9 +17865 82dd +17866 82e2 +17867..17869 82e8 +17870..17872 82ec +17873 82f0 +17874..17875 82f2 +17876..17877 82f5 +17878 82f8 +17879 82fa +17880..17884 82fc +17885..17886 830a +17887 830d +17888 8310 +17889..17890 8312 +17891 8316 +17892..17893 8318 +17894..17903 831d +17904..17905 8329 +17906 832e +17907 8330 +17908 8332 +17909 8337 +17910 833b +17911..17913 833d +17914..17915 8341 +17916..17917 8344 +17918 8348 +17919..17923 834a +17924 8353 +17925..17929 8355 +17930 835d +17931 8362 +17932..17938 8370 +17939..17940 8379 +17941..17947 837e +17948..17949 8387 +17950..17952 838b +17953..17955 838f +17956..17957 8394 +17958 8397 +17959..17960 8399 +17961 839d +17962 839f +17963 83a1 +17964..17967 83a3 +17968..17971 83ac +17972 83b5 +17973 83bb +17974..17975 83be +17976..17978 83c2 +17979 83c6 +17980..17981 83c8 +17982 83cb +17983..17984 83cd +17985..17988 83d0 +17989 83d5 +17990 83d7 +17991..17993 83d9 +17994 83de +17995..17997 83e2 +17998..18000 83e6 +18001..18004 83eb +18005..18009 83f3 +18010..18012 83fa +18013..18015 83fe +18016 8402 +18017 8405 +18018..18019 8408 +18020 8410 +18021..18026 8412 +18027..18029 8419 +18030..18035 841e +18036..18038 8429 +18039..18042 842d +18043..18045 8432 +18046..18047 8436 +18048..18050 8439 +18051..18058 843e +18059..18060 8447 +18061..18067 844a +18068..18071 8453 +18072 8458 +18073..18076 845d +18077 8462 +18078 8465 +18079..18080 8467 +18081 846a +18082 846e +18083 8470 +18084 8472 +18085 8474 +18086 8479 +18087..18093 847b +18094..18097 8483 +18098 848a +18099 848d +18100..18103 848f +18104..18105 8495 +18106 8498 +18107..18108 849a +18109..18112 849d +18113..18125 84a2 +18126..18127 84b0 +18128 84b3 +18129..18131 84b5 +18132 84bb +18133 84be +18134..18135 84c2 +18136..18139 84c5 +18140 84cc +18141..18142 84ce +18143 84d2 +18144..18145 84d4 +18146..18151 84d7 +18152 84de +18153..18154 84e1 +18155 84e4 +18156..18160 84e7 +18161 84ed +18162..18172 84f1 +18173 84fe +18174..18185 8500 +18186..18189 850d +18190 8512 +18191..18192 8515 +18193..18194 8518 +18195..18197 851b +18198 8520 +18199 8522 +18200..18201 8524 +18202..18205 8527 +18206..18214 852e +18215..18217 853e +18218 8542 +18219..18220 8544 +18221 8547 +18222..18224 854b +18225..18227 854f +18228 8554 +18229 8557 +18230..18233 855a +18234..18236 855f +18237 8563 +18238..18240 8565 +18241..18242 856b +18243..18246 856e +18247 8573 +18248..18249 8575 +18250 8578 +18251..18252 857c +18253..18257 857f +18258 8586 +18259 8589 +18260 858b +18261..18262 858d +18263 8590 +18264..18265 8592 +18266..18271 8595 +18272..18273 859d +18274..18277 85a0 +18278 85a5 +18279 85a7 +18280..18282 85ab +18283..18288 85b1 +18289 85b8 +18290..18295 85bb +18296..18302 85c2 +18303..18305 85ca +18306..18307 85d1 +18308 85d4 +18309..18314 85d6 +18315..18320 85de +18321..18323 85e6 +18324..18332 85eb +18333 85f5 +18334..18335 85f7 +18336..18338 85fc +18339..18342 8600 +18343..18345 8608 +18346..18350 860c +18351..18354 8612 +18355..18357 8617 +18358..18360 861b +18361..18363 861f +18364..18367 8623 +18368 8628 +18369..18371 862a +18372..18381 862e +18382 8639 +18383 863b +18384..18385 863d +18386..18398 8640 +18399..18400 8652 +18401..18404 8656 +18405 865b +18406 865d +18407..18408 8660 +18409..18412 8663 +18413..18415 8668 +18416 866d +18417..18418 866f +18419..18425 8672 +18426..18432 8683 +18433..18437 868e +18438 8694 +18439..18444 8696 +18445..18449 869e +18450..18451 86a5 +18452 86ab +18453..18454 86ad +18455..18456 86b2 +18457..18459 86b7 +18460..18464 86bb +18465..18467 86c1 +18468 86c5 +18469 86c8 +18470..18471 86cc +18472..18473 86d2 +18474..18476 86d5 +18477 86da +18478..18479 86dc +18480..18483 86e0 +18484..18487 86e5 +18488..18490 86ea +18491 86ef +18492..18494 86f5 +18495..18497 86fb +18498 86ff +18499 8701 +18500..18501 8704 +18502..18503 870b +18504..18507 870e +18508 8714 +18509 8716 +18510 8719 +18511 871b +18512 871d +18513..18514 871f +18515 8724 +18516..18518 8726 +18519..18522 872a +18523..18524 872f +18525..18526 8732 +18527..18528 8735 +18529..18531 8738 +18532..18533 873c +18534..18540 8740 +18541..18542 874a +18543 874d +18544..18547 874f +18548 8754 +18549 8756 +18550 8758 +18551..18556 875a +18557..18558 8761 +18559..18565 8767 +18566 876f +18567..18569 8771 +18570 8775 +18571 8777 +18572..18573 8779 +18574..18576 877f +18577..18578 8786 +18579..18580 8789 +18581 878c +18582..18586 878e +18587..18589 8794 +18590..18595 8798 +18596..18597 87a0 +18598..18602 87a3 +18603..18604 87a9 +18605 87ae +18606..18608 87b0 +18609 87b4 +18610..18613 87b6 +18614 87bc +18615..18616 87be +18617..18619 87c1 +18620 87c5 +18621 87c7 +18622 87c9 +18623..18624 87cc +18625..18626 87cf +18627..18633 87d4 +18634..18637 87dc +18638..18639 87e1 +18640 87e4 +18641..18644 87e6 +18645 87eb +18646 87ed +18647..18648 87f0 +18649..18651 87f3 +18652..18653 87f7 +18654 87fa +18655..18656 87fc +18657..18660 87ff +18661 8804 +18662..18664 8807 +18665..18669 880b +18670 8812 +18671 8814 +18672..18675 8817 +18676..18678 881c +18679 8820 +18680..18692 8824 +18693..18695 8833 +18696..18697 8837 +18698 883a +18699..18701 883d +18702..18704 8841 +18705..18707 8847 +18708 884b +18709..18713 884e +18714..18715 8855 +18716 8858 +18717 885a +18718 885c +18719..18721 885e +18722..18723 8866 +18724 886a +18725 886d +18726 886f +18727 8871 +18728..18731 8873 +18732 8878 +18733..18735 887a +18736 8880 +18737 8883 +18738..18739 8886 +18740..18741 8889 +18742 888c +18743..18746 888e +18747..18749 8893 +18750..18754 8897 +18755..18759 889d +18760 88a3 +18761..18766 88a5 +18767 88ac +18768..18770 88ae +18771..18775 88b2 +18776..18779 88b8 +18780..18783 88bd +18784..18785 88c3 +18786..18787 88c7 +18788..18790 88cb +18791..18792 88d0 +18793 88d3 +18794..18795 88d6 +18796..18797 88da +18798 88de +18799..18800 88e0 +18801..18802 88e6 +18803..18809 88e9 +18810 88f2 +18811..18813 88f5 +18814..18815 88fa +18816..18818 88ff +18819..18822 8903 +18823..18824 8908 +18825..18829 890b +18830 8911 +18831..18835 8914 +18836..18840 891c +18841..18843 8922 +18844..18847 8926 +18848..18851 892c +18852 8931 +18853 8935 +18854 8937 +18855..18856 8939 +18857..18861 893c +18862..18863 8942 +18864..18865 8945 +18866..18879 8948 +18880..18885 8957 +18886..18888 8961 +18889 8965 +18890..18892 8967 +18893 896b +18894..18895 896d +18896..18897 8970 +18898..18905 8973 +18906..18908 897c +18909 8980 +18910 8982 +18911..18912 8984 +18913..18916 8987 +18917..18919 898c +18920..18922 8990 +18923..18924 8994 +18925 8997 +18926..18933 8999 +18934..18937 89a2 +18938..18940 89a7 +18941 89ab +18942..18943 89ad +18944..18945 89b0 +18946..18949 89b3 +18950..18951 89b8 +18952..18953 89bb +18954 89be +18955 89c3 +18956 89cd +18957..18959 89d3 +18960..18962 89d7 +18963 89db +18964 89dd +18965..18968 89df +18969 89e4 +18970..18973 89e7 +18974..18976 89ec +18977..18979 89f0 +18980 89f5 +18981 89f7 +18982..18988 89f9 +18989..18991 8a04 +18992 8a09 +18993 8a0b +18994 8a0d +18995 8a0f +18996..18997 8a11 +18998 8a14 +18999 8a17 +19000..19001 8a19 +19002 8a1c +19003 8a1e +19004..19006 8a20 +19007 8a24 +19008..19011 8a26 +19012..19013 8a2b +19014..19016 8a2e +19017..19018 8a32 +19019 8a35 +19020..19022 8a37 +19023..19025 8a3b +19026..19027 8a3f +19028..19031 8a42 +19032 8a47 +19033..19037 8a49 +19038 8a4f +19039 8a51 +19040 8a53 +19041..19042 8a56 +19043..19044 8a59 +19045..19046 8a5c +19047..19048 8a5f +19049..19050 8a64 +19051..19052 8a67 +19053 8a6a +19054 8a6f +19055 8a74 +19056..19058 8a76 +19059..19060 8a7a +19061..19062 8a7d +19063..19066 8a80 +19067 8a88 +19068..19069 8a8b +19070..19072 8a8e +19073 8a94 +19074..19075 8a96 +19076 8a99 +19077..19079 8a9b +19080 8a9f +19081 8aa2 +19082 8aa7 +19083..19085 8aa9 +19086..19088 8aad +19089 8ab1 +19090..19092 8ab3 +19093..19094 8ab7 +19095..19096 8aba +19097..19098 8abd +19099..19100 8ac0 +19101 8ac3 +19102..19103 8ac5 +19104 8ac8 +19105 8aca +19106 8acc +19107 8ace +19108 8ad0 +19109..19111 8ad3 +19112..19114 8ad8 +19115 8add +19116..19118 8adf +19119 8ae3 +19120 8ae5 +19121..19123 8ae8 +19124 8aec +19125..19126 8aef +19127 8af2 +19128..19129 8af4 +19130 8af9 +19131 8afb +19132 8afd +19133 8aff +19134 8b03 +19135 8b06 +19136..19137 8b08 +19138..19140 8b0b +19141 8b0f +19142..19144 8b11 +19145 8b15 +19146 8b18 +19147 8b1c +19148..19150 8b1e +19151..19154 8b22 +19155 8b27 +19156..19157 8b29 +19158..19162 8b2e +19163..19167 8b34 +19168..19171 8b3a +19172..19181 8b3f +19182..19185 8b4a +19186..19191 8b50 +19192 8b57 +19193 8b5b +19194..19202 8b5d +19203..19206 8b67 +19207..19208 8b6d +19209..19211 8b71 +19212..19213 8b75 +19214..19218 8b78 +19219..19220 8b7e +19221..19229 8b81 +19230..19232 8b8b +19233..19235 8b8f +19236 8b94 +19237..19241 8b97 +19242 8b9d +19243 8b9f +19244 8bac +19245 8bb1 +19246 8bbb +19247 8bc7 +19248 8bd0 +19249 8bea +19250 8c09 +19251 8c1e +19252..19260 8c38 +19261..19264 8c42 +19265..19266 8c4a +19267..19269 8c4d +19270..19273 8c51 +19274..19277 8c56 +19278..19283 8c5b +19284..19290 8c63 +19291..19297 8c6c +19298..19301 8c74 +19302..19308 8c7b +19309..19310 8c83 +19311..19313 8c86 +19314 8c8b +19315..19321 8c8d +19322..19324 8c95 +19325..19328 8c99 +19329 8c9f +19330..19333 8ca3 +19334..19335 8cad +19336 8cb1 +19337 8cb5 +19338 8cb9 +19339 8cbe +19340 8cc6 +19341 8cc9 +19342..19347 8ccb +19348 8cd4 +19349..19352 8cd6 +19353 8cdb +19354 8cdd +19355 8cdf +19356 8ce5 +19357..19358 8ce8 +19359..19364 8cee +19365..19369 8cf5 +19370..19374 8cff +19375..19376 8d06 +19377 8d09 +19378 8d0c +19379 8d0e +19380..19384 8d11 +19385..19388 8d17 +19389 8d20 +19390..19391 8d51 +19392 8d57 +19393 8d5f +19394 8d65 +19395..19397 8d68 +19398 8d6c +19399..19400 8d6e +19401..19402 8d71 +19403..19411 8d78 +19412..19413 8d82 +19414..19417 8d86 +19418..19422 8d8c +19423..19424 8d92 +19425..19427 8d96 +19428..19432 8d9a +19433..19435 8da0 +19436..19439 8da4 +19440..19447 8da9 +19448..19449 8db6 +19450 8db9 +19451 8dbb +19452 8dbd +19453..19455 8dc0 +19456 8dc5 +19457..19460 8dc7 +19461 8dcd +19462 8dd0 +19463..19466 8dd2 +19467..19468 8dd8 +19469 8ddc +19470..19472 8de0 +19473..19475 8de5 +19476 8de9 +19477..19478 8ded +19479..19481 8df0 +19482 8df4 +19483 8df6 +19484 8dfc +19485..19491 8dfe +19492..19494 8e06 +19495 8e0b +19496..19497 8e0d +19498..19500 8e11 +19501..19508 8e15 +19509..19510 8e20 +19511..19515 8e24 +19516 8e2b +19517 8e2d +19518 8e30 +19519..19520 8e32 +19521..19523 8e36 +19524..19525 8e3b +19526..19527 8e3e +19528 8e43 +19529..19530 8e45 +19531..19534 8e4d +19535..19536 8e53 +19537..19539 8e56 +19540..19548 8e5a +19549..19550 8e64 +19551..19552 8e67 +19553..19554 8e6a +19555 8e6e +19556 8e71 +19557 8e73 +19558 8e75 +19559..19561 8e77 +19562 8e7b +19563..19564 8e7d +19565 8e80 +19566..19568 8e82 +19569 8e86 +19570 8e88 +19571 8e8c +19572 8e8e +19573..19577 8e95 +19578 8e9b +19579 8e9d +19580..19581 8e9f +19582..19584 8ea2 +19585..19587 8ea7 +19588..19589 8ead +19590..19591 8eb0 +19592..19598 8eb3 +19599..19603 8ebb +19604..19612 8ec1 +19613..19615 8ecf +19616 8ed3 +19617..19622 8ed5 +19623..19625 8edc +19626..19629 8ee0 +19630..19635 8ee5 +19636..19641 8eec +19642..19646 8ef3 +19647 8efd +19648..19651 8eff +19652 8f04 +19653 8f06 +19654 8f08 +19655..19661 8f0b +19662 8f13 +19663..19667 8f16 +19668..19672 8f20 +19673..19674 8f27 +19675..19678 8f2b +19679..19681 8f30 +19682..19685 8f34 +19686..19687 8f39 +19688..19689 8f3c +19690..19691 8f40 +19692 8f43 +19693..19694 8f47 +19695..19697 8f4a +19698..19702 8f4f +19703..19712 8f55 +19713 8f60 +19714 8f63 +19715 8f65 +19716 8f6a +19717 8f80 +19718 8f8c +19719 8f92 +19720 8f9d +19721..19723 8fa0 +19724..19725 8fa4 +19726 8fa7 +19727 8faa +19728 8fac +19729..19731 8fb3 +19732..19733 8fb7 +19734..19736 8fba +19737..19738 8fbf +19739 8fc3 +19740 8fc6 +19741..19745 8fc9 +19746 8fcf +19747 8fd2 +19748..19749 8fd6 +19750 8fda +19751..19752 8fe0 +19753 8fe3 +19754 8fe7 +19755 8fec +19756 8fef +19757..19758 8ff1 +19759..19760 8ff5 +19761..19763 8ffa +19764..19765 8ffe +19766..19767 9007 +19768 900c +19769 900e +19770 9013 +19771 9018 +19772 901c +19773..19774 9024 +19775..19780 9027 +19781..19782 9030 +19783..19784 9033 +19785 9037 +19786..19787 9039 +19788 903d +19789..19790 903f +19791 9043 +19792..19793 9045 +19794..19796 9048 +19797 904c +19798 9056 +19799..19800 9059 +19801 905d +19802 905f +19803 9061 +19804 9064 +19805..19806 9066 +19807..19809 906a +19810..19812 906f +19813 9073 +19814 9076 +19815 9079 +19816 907b +19817 907e +19818..19819 9085 +19820 9089 +19821..19823 908c +19824 9092 +19825 9094 +19826 9096 +19827 9098 +19828 909a +19829 909c +19830..19832 909e +19833..19834 90a4 +19835..19837 90a7 +19838 90ab +19839 90ad +19840 90b2 +19841 90b7 +19842..19843 90bc +19844..19845 90bf +19846..19847 90c2 +19848 90c6 +19849..19850 90c8 +19851..19853 90cb +19854 90d2 +19855..19857 90d4 +19858..19860 90d8 +19861 90de +19862 90e0 +19863..19865 90e3 +19866..19867 90e9 +19868 90ec +19869 90ee +19870..19873 90f0 +19874..19875 90f6 +19876..19879 90f9 +19880..19882 90ff +19883 9103 +19884 9105 +19885..19886 9107 +19887..19894 910a +19895 9113 +19896 9115 +19897..19898 9117 +19899..19902 911a +19903..19905 911f +19906..19908 9124 +19909..19913 9128 +19914 912e +19915 9133 +19916 9135 +19917..19918 9137 +19919..19926 913b +19927..19928 9144 +19929 9147 +19930 9151 +19931..19934 9153 +19935..19936 9158 +19937..19938 915b +19939..19940 915f +19941..19943 9166 +19944 916b +19945 916d +19946 9173 +19947..19949 917a +19950..19954 9180 +19955 9186 +19956 9188 +19957 918a +19958..19959 918e +19960..19962 9193 +19963..19965 9197 +19966..19970 919d +19971..19976 91a4 +19977..19980 91b0 +19981..19984 91b6 +19985..19989 91bb +19990 91c2 +19991 91c4 +19992 91c6 +19993 91c8 +19994 91d0 +19995 91d6 +19996..19997 91da +19998..20002 91de +20003..20004 91e5 +20005 91e8 +20006..20016 91ea +20017 91f6 +20018 91f8 +20019..20023 91fb +20024..20025 9202 +20026..20028 9205 +20029..20031 920a +20032 920f +20033..20034 9212 +20035..20042 9216 +20043..20046 921f +20047 9224 +20048..20053 9228 +20054 922f +20055..20056 9231 +20057..20058 9235 +20059..20060 923b +20061..20064 9241 +20065..20066 9246 +20067..20069 924a +20070..20072 924e +20073..20075 9252 +20076 9256 +20077..20078 9258 +20079..20080 925c +20081..20083 925f +20084..20086 9263 +20087..20091 9267 +20092..20097 926e +20098..20100 9275 +20101 9279 +20102..20104 927c +20105..20106 9281 +20107 9284 +20108..20115 9286 +20116..20117 928f +20118 9292 +20119..20120 9294 +20121 9297 +20122 9299 +20123 929b +20124..20126 929d +20127..20128 92a1 +20129 92a4 +20130 92a7 +20131 92ad +20132..20133 92af +20134..20138 92b2 +20139 92b8 +20140 92ba +20141..20144 92bd +20145 92c2 +20146 92c4 +20147 92c6 +20148..20150 92c9 +20151..20152 92cd +20153..20154 92d0 +20155..20164 92d3 +20165 92de +20166..20168 92e0 +20169 92e7 +20170 92e9 +20171..20172 92eb +20173..20176 92f2 +20177 92f7 +20178..20180 92f9 +20181..20184 92fd +20185..20188 9302 +20189..20195 9309 +20196 9311 +20197..20198 9313 +20199..20200 9316 +20201..20203 931c +20204 9321 +20205..20207 9323 +20208 9327 +20209..20210 9329 +20211..20212 932c +20213..20214 9330 +20215..20216 9334 +20217 9337 +20218..20222 9339 +20223 933f +20224 9342 +20225..20226 9344 +20227..20229 9348 +20230 934c +20231..20236 934e +20237..20239 9355 +20240..20241 9359 +20242..20249 935c +20250..20252 9366 +20253 936b +20254..20256 936d +20257..20260 9371 +20261..20263 9377 +20264..20266 937b +20267..20269 937f +20270 9383 +20271..20272 9385 +20273..20274 9388 +20275..20278 938b +20279..20284 9390 +20285 9397 +20286..20294 9399 +20295..20296 93a4 +20297 93a8 +20298 93ab +20299 93ad +20300 93af +20301..20302 93b1 +20303 93b4 +20304..20305 93b6 +20306..20311 93b9 +20312..20314 93c0 +20315..20317 93c4 +20318 93c9 +20319 93cb +20320..20322 93ce +20323..20326 93d2 +20327..20329 93d9 +20330 93e0 +20331 93e3 +20332..20334 93e5 +20335..20346 93e9 +20347 93f6 +20348 93f8 +20349..20357 93fa +20358..20364 9404 +20365..20368 940c +20369 9411 +20370..20372 9415 +20373..20375 941a +20376..20377 941e +20378..20382 9421 +20383..20387 9429 +20388..20390 942f +20391 9434 +20392..20393 9436 +20394 9439 +20395..20397 943b +20398..20401 9440 +20402..20406 9445 +20407 944b +20408..20412 944d +20413 9453 +20414..20424 9455 +20425..20426 9461 +20427 9464 +20428..20432 9466 +20433 946c +20434..20435 946e +20436 9471 +20437..20440 9473 +20441 9478 +20442..20443 947a +20444..20448 9480 +20449 9491 +20450 9496 +20451 9498 +20452 94c7 +20453 94cf +20454..20455 94d3 +20456 94da +20457 94e6 +20458 94fb +20459 951c +20460 9520 +20461 9527 +20462 9533 +20463 953d +20464 9543 +20465 9548 +20466 954b +20467 9555 +20468 955a +20469 9560 +20470 956e +20471..20472 9574 +20473..20479 9578 +20480 9581 +20481..20482 9584 +20483..20484 9587 +20485 958a +20486 958d +20487 9590 +20488 9592 +20489..20491 9595 +20492..20499 9599 +20500 95a2 +20501..20502 95a6 +20503 95aa +20504..20507 95ae +20508..20510 95b3 +20511..20512 95b7 +20513 95ba +20514..20516 95c0 +20517..20518 95c4 +20519 95c7 +20520 95c9 +20521..20523 95cd +20524..20526 95d1 +20527..20531 95d7 +20532 95dd +20533..20534 95df +20535..20536 95e3 +20537..20538 95e6 +20539 95ec +20540 95ff +20541 9607 +20542 9613 +20543 9618 +20544 961b +20545 961e +20546 9620 +20547..20553 9623 +20554..20556 962b +20557..20558 962f +20559..20562 9637 +20563 963e +20564 9641 +20565 9643 +20566 964a +20567..20568 964e +20569..20571 9651 +20572..20573 9656 +20574..20575 9659 +20576 965c +20577 965e +20578 9660 +20579..20580 9665 +20581 966b +20582..20584 966d +20585 9671 +20586..20589 9679 +20590..20596 967e +20597 9687 +20598 9689 +20599 968c +20600..20602 9691 +20603 9696 +20604 969a +20605..20614 969d +20615 96a9 +20616..20620 96ab +20621 96b2 +20622 96b5 +20623 96b7 +20624 96ba +20625 96bf +20626..20627 96c2 +20628 96c8 +20629..20630 96ca +20631..20632 96d0 +20633..20634 96d3 +20635..20636 96d7 +20637 96da +20638..20640 96dd +20641 96e1 +20642..20645 96e4 +20646..20649 96eb +20650..20651 96f0 +20652..20653 96f4 +20654 96f8 +20655 96fa +20656..20657 96fc +20658 96ff +20659..20660 9702 +20661 9705 +20662..20664 970a +20665..20667 9710 +20668..20669 9714 +20670..20674 9717 +20675 971d +20676..20683 971f +20684..20685 9728 +20686..20687 972b +20688..20689 972e +20690 9731 +20691..20695 9733 +20696..20698 973a +20699..20701 973f +20702 9743 +20703..20705 9745 +20706..20714 9749 +20715..20716 9754 +20717..20718 9757 +20719..20720 975c +20721 975f +20722..20723 9763 +20724..20725 9766 +20726..20734 976a +20735 9775 +20736..20740 9777 +20741..20748 977d +20749..20753 9786 +20754 978c +20755 978e +20756 9790 +20757 9793 +20758..20760 9795 +20761..20767 9799 +20768..20769 97a1 +20770..20771 97a4 +20772..20775 97a7 +20776 97ac +20777 97ae +20778..20779 97b0 +20780 97b3 +20781..20788 97b5 +20789..20793 97be +20794..20795 97c4 +20796..20797 97c7 +20798 97ca +20799..20804 97cd +20805..20809 97d4 +20810..20811 97da +20812 97dd +20813..20819 97df +20820 97e8 +20821..20825 97ee +20826 97f4 +20827..20834 97f7 +20835 9800 +20836 9804 +20837 9809 +20838 980b +20839 980d +20840..20842 9814 +20843..20845 9819 +20846..20849 981d +20850..20851 9822 +20852 9825 +20853..20858 9827 +20859..20860 982e +20861..20866 9831 +20867..20868 9839 +20869 983c +20870..20877 983e +20878..20882 9847 +20883..20886 984f +20887..20889 9855 +20890 985a +20891..20892 985c +20893..20895 985f +20896..20897 9863 +20898 9866 +20899..20901 9868 +20902..20903 986d +20904 9872 +20905 988b +20906 988e +20907 9892 +20908 9895 +20909 9899 +20910 98a3 +20911..20915 98a9 +20916 98b0 +20917 98b2 +20918..20919 98b4 +20920..20924 98b7 +20925..20931 98bd +20932 98c5 +20933 98c7 +20934..20938 98c9 +20939..20940 98cf +20941 98d4 +20942..20943 98d6 +20944..20945 98dc +20946 98e1 +20947..20950 98e3 +20951 98ec +20952 98ee +20953..20954 98f0 +20955 98f3 +20956..20962 98f5 +20963..20966 98ff +20967 9904 +20968..20970 9906 +20971 990b +20972..20973 990e +20974..20977 9914 +20978..20979 9919 +20980..20981 991c +20982..20983 991f +20984..20989 9922 +20990..20994 9929 +20995..20998 992f +20999..21001 9934 +21002..21005 9938 +21006 993d +21007..21009 9940 +21010 9944 +21011..21012 9946 +21013..21016 994d +21017 9953 +21018 9956 +21019..21022 9958 +21023 995d +21024..21026 995f +21027 9964 +21028 9966 +21029 9973 +21030..21031 9978 +21032 997b +21033 997e +21034..21035 9982 +21036 9989 +21037 998c +21038 998e +21039..21049 999a +21050..21051 99a6 +21052..21054 99a9 +21055..21056 99af +21057 99b2 +21058..21069 99b5 +21070..21083 99c2 +21084 99d3 +21085..21086 99d6 +21087 99da +21088 99dc +21089 99de +21090 99e0 +21091..21100 99e3 +21101..21103 99ee +21104..21116 99f2 +21117 9a00 +21118..21120 9a02 +21121..21127 9a06 +21128..21133 9a10 +21134..21135 9a17 +21136..21152 9a1a +21153 9a2c +21154 9a2f +21155..21159 9a31 +21160..21164 9a39 +21165 9a3f +21166..21169 9a46 +21170..21171 9a4b +21172 9a4e +21173..21177 9a50 +21178 9a56 +21179..21180 9a58 +21181..21183 9a5c +21184..21185 9a60 +21186 9a63 +21187..21190 9a66 +21191 9a6b +21192 9a72 +21193 9a83 +21194 9a89 +21195..21196 9a8d +21197..21198 9a94 +21199 9a99 +21200 9aa6 +21201..21206 9aa9 +21207..21210 9ab2 +21211 9ab9 +21212 9abb +21213..21215 9abd +21216..21217 9ac3 +21218..21222 9ac6 +21223..21224 9acd +21225 9ad0 +21226 9ad7 +21227..21232 9ad9 +21233 9ae0 +21234..21237 9ae2 +21238..21241 9ae7 +21242 9aec +21243..21251 9af0 +21252 9afa +21253..21259 9afc +21260..21261 9b04 +21262 9b07 +21263..21266 9b09 +21267 9b0e +21268..21270 9b10 +21271..21276 9b14 +21277..21280 9b1b +21281..21282 9b20 +21283 9b24 +21284 9b26 +21285 9b28 +21286..21289 9b2a +21290 9b30 +21291..21298 9b33 +21299..21302 9b3d +21303 9b46 +21304..21306 9b4a +21307 9b50 +21308..21309 9b52 +21310..21312 9b55 +21313 9b59 +21314..21333 9b5b +21334..21337 9b70 +21338..21339 9b75 +21340..21348 9b78 +21349 9b82 +21350..21359 9b84 +21360 9b8f +21361..21367 9b93 +21368..21369 9b9b +21370..21380 9b9f +21381 9bac +21382..21398 9baf +21399..21403 9bc2 +21404 9bc8 +21405..21413 9bcb +21414 9bd5 +21415..21418 9bd7 +21419 9bdc +21420..21422 9bde +21423 9be3 +21424..21425 9be5 +21426 9be9 +21427..21430 9bec +21431..21433 9bf1 +21434..21441 9bf5 +21442 9bfe +21443..21450 9c00 +21451..21453 9c0a +21454..21455 9c0e +21456 9c11 +21457..21468 9c14 +21469..21470 9c21 +21471 9c24 +21472..21473 9c26 +21474..21476 9c2a +21477..21479 9c2e +21480 9c34 +21481 9c36 +21482 9c38 +21483 9c3a +21484..21485 9c3c +21486..21491 9c3f +21492..21493 9c46 +21494..21501 9c4a +21502 9c53 +21503 9c55 +21504..21507 9c59 +21508 9c5e +21509..21515 9c60 +21516..21520 9c68 +21521..21530 9c6e +21531 9c79 +21532 9c7b +21533..21534 9c7d +21535 9c80 +21536..21537 9c83 +21538..21539 9c89 +21540 9c8c +21541 9c8f +21542 9c93 +21543..21546 9c96 +21547 9c9d +21548 9caa +21549 9cac +21550 9caf +21551 9cb9 +21552..21556 9cbe +21557..21558 9cc8 +21559..21560 9cd1 +21561..21562 9cda +21563..21564 9ce0 +21565..21566 9ce3 +21567..21569 9ce6 +21570..21571 9cea +21572..21577 9ced +21578 9cf5 +21579..21593 9cf7 +21594 9d08 +21595..21605 9d0a +21606..21610 9d16 +21611 9d1c +21612 9d1e +21613..21615 9d20 +21616..21617 9d24 +21618 9d27 +21619..21624 9d29 +21625..21634 9d31 +21635..21637 9d3c +21638..21639 9d40 +21640..21653 9d43 +21654..21661 9d54 +21662..21663 9d5e +21664..21671 9d62 +21672 9d6b +21673..21674 9d6d +21675..21676 9d70 +21677..21696 9d73 +21697 9d88 +21698..21706 9d8a +21707..21710 9d94 +21711 9d99 +21712..21721 9d9b +21722..21724 9da6 +21725..21729 9daa +21730..21733 9db0 +21734..21739 9db5 +21740..21742 9dbd +21743 9dc1 +21744 9dc3 +21745..21758 9dc5 +21759..21761 9dd4 +21762 9dd8 +21763..21772 9ddb +21773..21780 9de7 +21781..21782 9df0 +21783..21786 9df4 +21787..21803 9dfb +21804..21811 9e0d +21812..21815 9e16 +21816 9e1c +21817 9e24 +21818 9e27 +21819 9e2e +21820 9e30 +21821 9e34 +21822..21823 9e3b +21824 9e40 +21825 9e4d +21826 9e50 +21827..21829 9e52 +21830 9e56 +21831 9e59 +21832 9e5d +21833..21836 9e5f +21837 9e65 +21838..21839 9e6e +21840 9e72 +21841 9e74 +21842..21844 9e76 +21845 9e7b +21846..21847 9e80 +21848..21851 9e83 +21852..21853 9e89 +21854..21859 9e8c +21860..21862 9e94 +21863..21867 9e98 +21868 9e9e +21869..21873 9ea0 +21874..21875 9ea7 +21876..21880 9eaa +21881..21884 9eb0 +21885..21886 9eb6 +21887..21888 9eb9 +21889 9ebc +21890..21894 9ebf +21895..21898 9ec5 +21899..21900 9eca +21901 9ed0 +21902..21903 9ed2 +21904..21906 9ed5 +21907..21908 9ed9 +21909 9ee1 +21910..21911 9ee3 +21912 9ee6 +21913..21916 9eeb +21917..21918 9ef0 +21919 9ef3 +21920..21921 9ef5 +21922 9ef8 +21923 9efa +21924..21932 9f00 +21933 9f0a +21934 9f0c +21935 9f0f +21936..21937 9f11 +21938 9f14 +21939 9f16 +21940 9f18 +21941..21946 9f1a +21947 9f21 +21948..21956 9f23 +21957..21958 9f2d +21959..21965 9f30 +21966 9f38 +21967 9f3a +21968 9f3c +21969..21973 9f3f +21974..21978 9f45 +21979..21981 9f4c +21982 9f53 +21983..21986 9f55 +21987..21988 9f5a +21989..21990 9f5d +21991 9f62 +21992..21993 9f64 +21994..21996 9f67 +21997 9f6b +21998..22002 9f6d +22003..22006 9f73 +22007..22013 9f78 +22014..22015 9f81 +22016..22017 9f8e +22018..22020 9f91 +22021..22023 9f96 +22024..22025 9f9d +22026..22030 9fa1 +22031 f92c +22032..22034 fa0d +22035 fa11 +22036..22037 fa13 +22038 fa18 +22039..22041 fa1f +22042..22043 fa23 +22044..22046 fa27 +22047 2e81 +22048 20087 +22049 20089 +22050 200cc +22051 2e84 +22052 3473 +22053 3447 +22054 2e88 +22055 2e8b +22056 e81e +22057 359e +22058 361a +22059 360e +22060 2e8c +22061 2e97 +22062 396e +22063 3918 +22064 e826 +22065 39cf +22066 39df +22067 3a73 +22068 39d0 +22069..22070 e82b +22071 3b4e +22072 3c6e +22073 3ce0 +22074 2ea7 +22075 215d7 +22076 e832 +22077 2eaa +22078 4056 +22079 415f +22080 2eae +22081 4337 +22082 2eb3 +22083..22084 2eb6 +22085 e83b +22086 43b1 +22087 43ac +22088 2ebb +22089 43dd +22090 44d6 +22091 4661 +22092 464c +22093 e843 +22094 4723 +22095 4729 +22096 477c +22097 478d +22098 2eca +22099 4947 +22100 497a +22101 497d +22102..22103 4982 +22104..22105 4985 +22106 499f +22107 499b +22108 49b7 +22109 49b6 +22110 2099d +22111 241fe +22112 4ca3 +22113..22115 4c9f +22116 4c77 +22117 4ca2 +22118..22124 4d13 +22125 4dae +22126 e864 +22127 /GB1.1.vert +22128 /GB1.2.vert +22129 /GB1.3.vert +22130 /GB1.4.vert +22131 /GB1.5.vert +22132 /GB1.6.vert +22133 /GB1.7.vert +22134 /GB1.8.vert +22135 /GB1.9.vert +22136 /GB1.10.vert +22137 /GB1.11.vert +22138 /GB1.12.vert +22139 /GB1.13.vert +22140 /GB1.14.vert +22141 /GB1.15.vert +22142 /GB1.16.vert +22143 /GB1.17.vert +22144 /GB1.18.vert +22145 /GB1.19.vert +22146 /GB1.20.vert +22147 /GB1.21.vert +22148 /GB1.22.vert +22149 /GB1.23.vert +22150 /GB1.24.vert +22151 /GB1.25.vert +22152 /GB1.26.vert +22153 /GB1.27.vert +22154 /GB1.28.vert +22155 /GB1.29.vert +22156 /GB1.30.vert +22157 /GB1.31.vert +22158 /GB1.32.vert +22159 /GB1.33.vert +22160 /GB1.34.vert +22161 /GB1.35.vert +22162 /GB1.36.vert +22163 /GB1.37.vert +22164 /GB1.38.vert +22165 /GB1.39.vert +22166 /GB1.40.vert +22167 /GB1.41.vert +22168 /GB1.42.vert +22169 /GB1.43.vert +22170 /GB1.44.vert +22171 /GB1.45.vert +22172 /GB1.46.vert +22173 /GB1.47.vert +22174 /GB1.48.vert +22175 /GB1.49.vert +22176 /GB1.50.vert +22177 /GB1.51.vert +22178 /GB1.52.vert +22179 /GB1.53.vert +22180 /GB1.54.vert +22181 /GB1.55.vert +22182 /GB1.56.vert +22183 /GB1.57.vert +22184 /GB1.58.vert +22185 /GB1.59.vert +22186 /GB1.60.vert +22187 /GB1.61.vert +22188 /GB1.62.vert +22189 /GB1.63.vert +22190 /GB1.64.vert +22191 /GB1.65.vert +22192 /GB1.66.vert +22193 /GB1.67.vert +22194 /GB1.68.vert +22195 /GB1.69.vert +22196 /GB1.70.vert +22197 /GB1.71.vert +22198 /GB1.72.vert +22199 /GB1.73.vert +22200 /GB1.74.vert +22201 /GB1.75.vert +22202 /GB1.76.vert +22203 /GB1.77.vert +22204 /GB1.78.vert +22205 /GB1.79.vert +22206 /GB1.80.vert +22207 /GB1.81.vert +22208 /GB1.82.vert +22209 /GB1.83.vert +22210 /GB1.84.vert +22211 /GB1.85.vert +22212 /GB1.86.vert +22213 /GB1.87.vert +22214 /GB1.88.vert +22215 /GB1.89.vert +22216 /GB1.90.vert +22217 /GB1.91.vert +22218 /GB1.92.vert +22219 /GB1.93.vert +22220 /GB1.94.vert +22221 /GB1.95.vert +22226 /GB1.814.vert +22227 /GB1.815.vert +22228 /GB1.816.vert +22229 /GB1.817.vert +22230 /GB1.818.vert +22231 /GB1.819.vert +22232 /GB1.820.vert +22233 /GB1.821.vert +22234 /GB1.822.vert +22235 /GB1.823.vert +22236 /GB1.824.vert +22237 /GB1.825.vert +22238 /GB1.826.vert +22239 /GB1.827.vert +22240 /GB1.828.vert +22241 /GB1.829.vert +22242 /GB1.830.vert +22243 /GB1.831.vert +22244 /GB1.832.vert +22245 /GB1.833.vert +22246 /GB1.834.vert +22247 /GB1.835.vert +22248 /GB1.836.vert +22249 /GB1.837.vert +22250 /GB1.838.vert +22251 /GB1.839.vert +22252 /GB1.840.vert +22253 /GB1.841.vert +22254 /GB1.842.vert +22255 /GB1.843.vert +22256 /GB1.844.vert +22257 /GB1.845.vert +22258 /GB1.846.vert +22259 /GB1.847.vert +22260 /GB1.848.vert +22261 /GB1.849.vert +22262 /GB1.850.vert +22263 /GB1.851.vert +22264 /GB1.852.vert +22265 /GB1.853.vert +22266 /GB1.854.vert +22267 /GB1.855.vert +22268 /GB1.856.vert +22269 /GB1.857.vert +22270 /GB1.858.vert +22271 /GB1.859.vert +22272 /GB1.860.vert +22273 /GB1.861.vert +22274 /GB1.862.vert +22275 /GB1.863.vert +22276 /GB1.864.vert +22277 /GB1.865.vert +22278 /GB1.866.vert +22279 /GB1.867.vert +22280 /GB1.868.vert +22281 /GB1.869.vert +22282 /GB1.870.vert +22283 /GB1.871.vert +22284 /GB1.872.vert +22285 /GB1.873.vert +22286 /GB1.874.vert +22287 /GB1.875.vert +22288 /GB1.876.vert +22289 /GB1.877.vert +22290 /GB1.878.vert +22291 /GB1.879.vert +22292 /GB1.880.vert +22293 /GB1.881.vert +22294 /GB1.882.vert +22295 /GB1.883.vert +22296 /GB1.884.vert +22297 /GB1.885.vert +22298 /GB1.886.vert +22299 /GB1.887.vert +22300 /GB1.888.vert +22301 /GB1.889.vert +22302 /GB1.890.vert +22303 /GB1.891.vert +22304 /GB1.892.vert +22305 /GB1.893.vert +22306 /GB1.894.vert +22307 /GB1.895.vert +22308 /GB1.896.vert +22309 /GB1.897.vert +22310 /GB1.898.vert +22311 /GB1.899.vert +22312 /GB1.900.vert +22313 /GB1.901.vert +22314 /GB1.902.vert +22315 /GB1.903.vert +22316 /GB1.904.vert +22317 /GB1.905.vert +22318 /GB1.906.vert +22319 /GB1.907.vert +22353 20ac +22354 00a5 +22357 303f +22375 3094 +22390 30f7 +22391 30f9 +22392 30f8 +22393 30fa +22395..22397 3033 +22398..22400 3038 +22401..22403 312a +22404..22427 31a0 +22428 2e80 +22429..22430 2e82 +22431..22433 2e85 +22434..22435 2e89 +22436..22445 2e8d +22446..22447 2e98 +22448..22459 2e9b +22460..22461 2ea8 +22462..22464 2eab +22465..22468 2eaf +22469..22470 2eb4 +22471..22473 2eb8 +22474..22487 2ebc +22488..22528 2ecb +22529..22599 3400 +22600..22642 3448 +22643..22940 3474 +22941..23051 359f +23052..23062 360f +23063..23827 361b +23828..23912 3919 +23913..24008 396f +24009..24022 39d1 +24023..24169 39e0 +24170..24387 3a74 +24388..24674 3b4f +24675..24787 3c6f +24788..25672 3ce1 +25673..25936 4057 +25937..26407 4160 +26408..26523 4338 +26524..26527 43ad +26528..26570 43b2 +26571..26818 43de +26819..27191 44d7 +27192..27211 464d +27212..27404 4662 +27405..27409 4724 +27410..27491 472a +27492..27507 477d +27508..27948 478e +27949..27998 4948 +27999..28000 497b +28001..28004 497e +28005 4984 +28006..28025 4987 +28026..28028 499c +28029..28050 49a0 +28051..28753 49b8 +28754..28792 4c78 +28793..28903 4ca4 +28904..29051 4d1a +29052..29058 4daf +29059 /GB1.22353.vert +29060 /GB1.22354.vert +29061 /GB1.22355.vert +29062 /GB1.22356.vert +29063 /GB1.22357.vert diff --git a/fonts/cid/fontforge/Adobe-Identity-0.cidmap b/fonts/cid/fontforge/Adobe-Identity-0.cidmap new file mode 100644 index 000000000..3615a8f56 --- /dev/null +++ b/fonts/cid/fontforge/Adobe-Identity-0.cidmap @@ -0,0 +1,2 @@ +65535 65535 +0..65535 0 diff --git a/fonts/cid/fontforge/Adobe-Japan1-5.cidmap b/fonts/cid/fontforge/Adobe-Japan1-5.cidmap new file mode 100644 index 000000000..829bf3d30 --- /dev/null +++ b/fonts/cid/fontforge/Adobe-Japan1-5.cidmap @@ -0,0 +1,13691 @@ +20316 20316 +0 /.notdef +1 00a0 +2..13 0021 +14 2011 +15..60 002e +61 00a5 +62..63 005d +64 0332 +65 0300 +66..92 0061 +93 00a6 +94 007d +95 02dc +96 02bc +97 005c +98 02bb +99 007c +100 007e +101..103 00a1 +104 2044 +105 0192 +107 00a4 +108 201c +109 00ab +110..111 2039 +112..113 fb01 +114 2012 +117 00b7 +119 2022 +120 201a +121 201e +122 201d +123 00bb +124 2026 +126 00bf +127..128 0301 +129 00af +130..132 0306 +133 030a +134 00b8 +135 030b +136 0328 +137 030c +138 0336 +139 00c6 +140 00aa +141 0141 +142 00d8 +143 0152 +144 00ba +145 00e6 +146 0131 +147 0142 +148 00f8 +149 0153 +150 00df +151 00ad +152 00a9 +153 00ac +154 00ae +157..158 00b2 +159 00b5 +160 00b9 +161..163 00bc +164..169 00c0 +170..185 00c7 +187..192 00d9 +193..198 00e0 +199..214 00e7 +216..222 00f9 +223 0160 +224 0178 +225 017d +226 0305 +227 0161 +228 2122 +229 017e +231 2002 +232 /uni0021.hw +233 /uni0022.hw +234 /uni0023.hw +235 /uni0024.hw +236 /uni0025.hw +237 /uni0026.hw +238 /uni0027.hw +239 /uni0028.hw +240 /uni0029.hw +241 /uni002A.hw +242 /uni002B.hw +243 /uni002C.hw +244 /uni002D.hw +245 /uni002E.hw +246 /uni002F.hw +247 /uni0030.hw +248 /uni0031.hw +249 /uni0032.hw +250 /uni0033.hw +251 /uni0034.hw +252 /uni0035.hw +253 /uni0036.hw +254 /uni0037.hw +255 /uni0038.hw +256 /uni0039.hw +257 /uni003A.hw +258 /uni003B.hw +259 /uni003C.hw +260 /uni003D.hw +261 /uni003E.hw +262 /uni003F.hw +263 /uni0040.hw +264 /uni0041.hw +265 /uni0042.hw +266 /uni0043.hw +267 /uni0044.hw +268 /uni0045.hw +269 /uni0046.hw +270 /uni0047.hw +271 /uni0048.hw +272 /uni0049.hw +273 /uni004A.hw +274 /uni004B.hw +275 /uni004C.hw +276 /uni004D.hw +277 /uni004E.hw +278 /uni004F.hw +279 /uni0050.hw +280 /uni0051.hw +281 /uni0052.hw +282 /uni0053.hw +283 /uni0054.hw +284 /uni0055.hw +285 /uni0056.hw +286 /uni0057.hw +287 /uni0058.hw +288 /uni0059.hw +289 /uni005A.hw +290 /uni005B.hw +291 /uni00A5.hw +292 /uni005D.hw +293 /uni005E.hw +294 /uni005F.hw +295 /uni0060.hw +296 /uni0061.hw +297 /uni0062.hw +298 /uni0063.hw +299 /uni0064.hw +300 /uni0065.hw +301 /uni0066.hw +302 /uni0067.hw +303 /uni0068.hw +304 /uni0069.hw +305 /uni006A.hw +306 /uni006B.hw +307 /uni006C.hw +308 /uni006D.hw +309 /uni006E.hw +310 /uni006F.hw +311 /uni0070.hw +312 /uni0071.hw +313 /uni0072.hw +314 /uni0073.hw +315 /uni0074.hw +316 /uni0075.hw +317 /uni0076.hw +318 /uni0077.hw +319 /uni0078.hw +320 /uni0079.hw +321 /uni007A.hw +322 /uni007B.hw +323 /uniFFE8.hw +324 /uni007D.hw +325 /uni203E.hw +326 /cid-326.hw +327..389 ff61 +390 /cid-646.hw +391 /cid-1004.hw +392 /cid-1005.hw +393 /cid-1002.hw +394 /cid-1009.hw +395 /cid-1010.hw +396 /cid-1008.hw +397 /cid-936.hw +398 /cid-938.hw +399 /cid-940.hw +400 /cid-942.hw +401 /cid-944.hw +402 /cid-946.hw +403 /cid-948.hw +404 /cid-950.hw +405 /cid-952.hw +406 /cid-954.hw +407 /cid-956.hw +408 /cid-958.hw +409 /cid-961.hw +410 /cid-963.hw +411 /cid-965.hw +412 /cid-972.hw +413 /cid-973.hw +414 /cid-975.hw +415 /cid-976.hw +416 /cid-978.hw +417 /cid-979.hw +418 /cid-981.hw +419 /cid-982.hw +420 /cid-984.hw +421 /cid-421.hw +422 /cid-422.hw +423 /cid-423.hw +424 /cid-424.hw +425 /uni2500.hw +426 /uni2501.hw +427 /uni2502.hw +428 /uni2503.hw +429 /uni2504.hw +430 /uni2505.hw +431 /uni2506.hw +432 /uni2507.hw +433 /uni2508.hw +434 /uni2509.hw +435 /uni250A.hw +436 /uni250B.hw +437 /uni250C.hw +438 /uni250D.hw +439 /uni250E.hw +440 /uni250F.hw +441 /uni2510.hw +442 /uni2511.hw +443 /uni2512.hw +444 /uni2513.hw +445 /uni2514.hw +446 /uni2515.hw +447 /uni2516.hw +448 /uni2517.hw +449 /uni2518.hw +450 /uni2519.hw +451 /uni251A.hw +452 /uni251B.hw +453 /uni251C.hw +454 /uni251D.hw +455 /uni251E.hw +456 /uni251F.hw +457 /uni2520.hw +458 /uni2521.hw +459 /uni2522.hw +460 /uni2523.hw +461 /uni2524.hw +462 /uni2525.hw +463 /uni2526.hw +464 /uni2527.hw +465 /uni2528.hw +466 /uni2529.hw +467 /uni252A.hw +468 /uni252B.hw +469 /uni252C.hw +470 /uni252D.hw +471 /uni252E.hw +472 /uni252F.hw +473 /uni2530.hw +474 /uni2531.hw +475 /uni2532.hw +476 /uni2533.hw +477 /uni2534.hw +478 /uni2535.hw +479 /uni2536.hw +480 /uni2537.hw +481 /uni2538.hw +482 /uni2539.hw +483 /uni253A.hw +484 /uni253B.hw +485 /uni253C.hw +486 /uni253D.hw +487 /uni253E.hw +488 /uni253F.hw +489 /uni2540.hw +490 /uni2541.hw +491 /uni2542.hw +492 /uni2543.hw +493 /uni2544.hw +494 /uni2545.hw +495 /uni2546.hw +496 /uni2547.hw +497 /uni2548.hw +498 /uni2549.hw +499 /uni254A.hw +500 /uni254B.hw +501 /cid-645.hw +502 /cid-647.hw +503 /cid-672.hw +504 /uni3014.hw +505 /uni3015.hw +506 /uni3008.hw +507 /uni3009.hw +508 /uni300A.hw +509 /uni300B.hw +510 /uni300C.hw +511 /uni300D.hw +512 /uni300E.hw +513 /uni300F.hw +514 /cid-514.hw +515 /cid-515.hw +516 /cid-923.hw +517 /cid-842.hw +518 /cid-844.hw +519 /cid-846.hw +520 /cid-848.hw +521 /cid-850.hw +522 /cid-908.hw +523 /cid-910.hw +524 /cid-912.hw +525 /cid-876.hw +526 /cid-843.hw +527 /cid-845.hw +528 /cid-847.hw +529 /cid-849.hw +530 /cid-851.hw +531 /cid-852.hw +532 /cid-854.hw +533 /cid-856.hw +534 /cid-858.hw +535 /cid-860.hw +536 /cid-862.hw +537 /cid-864.hw +538 /cid-866.hw +539 /cid-868.hw +540 /cid-870.hw +541 /cid-872.hw +542 /cid-874.hw +543 /cid-877.hw +544 /cid-879.hw +545 /cid-881.hw +546 /cid-883.hw +547 /cid-884.hw +548 /cid-885.hw +549 /cid-886.hw +550 /cid-887.hw +551 /cid-888.hw +552 /cid-891.hw +553 /cid-894.hw +554 /cid-897.hw +555 /cid-900.hw +556 /cid-903.hw +557 /cid-904.hw +558 /cid-905.hw +559 /cid-906.hw +560 /cid-907.hw +561 /cid-909.hw +562 /cid-911.hw +563 /cid-913.hw +564 /cid-914.hw +565 /cid-915.hw +566 /cid-916.hw +567 /cid-917.hw +568 /cid-918.hw +569 /cid-920.hw +570 /cid-924.hw +571 /cid-921.hw +572 /cid-922.hw +573 /cid-919.hw +574 /cid-853.hw +575 /cid-855.hw +576 /cid-857.hw +577 /cid-859.hw +578 /cid-861.hw +579 /cid-863.hw +580 /cid-865.hw +581 /cid-867.hw +582 /cid-869.hw +583 /cid-871.hw +584 /cid-873.hw +585 /cid-875.hw +586 /cid-878.hw +587 /cid-880.hw +588 /cid-882.hw +589 /cid-889.hw +590 /cid-890.hw +591 /cid-892.hw +592 /cid-893.hw +593 /cid-895.hw +594 /cid-896.hw +595 /cid-898.hw +596 /cid-899.hw +597 /cid-901.hw +598 /cid-902.hw +599 /uni00C4.hw +600 /uni00F9.hw +601 /uni00E9.hw +602 /uni00ED.hw +603 /uni00DF.hw +604 /uni00E7.hw +605 /uni00C7.hw +606 /uni00D1.hw +607 /uni00F1.hw +608 /uni00A2.hw +609 /uni00A3.hw +610 /uni00F3.hw +611 /uni00FA.hw +612 /uni00A1.hw +613 /uni00BF.hw +614 /uni00BD.hw +615 /uni00D6.hw +616 /uni00DC.hw +617 /uni00E4.hw +618 /uni00EB.hw +619 /uni00EF.hw +620 /uni00F6.hw +621 /uni00FC.hw +622 /uni00E2.hw +623 /uni00EA.hw +624 /uni00EE.hw +625 /uni00F4.hw +626 /uni00FB.hw +627 /uni00E0.hw +628 /uni00E8.hw +629 /cid-629.hw +630 /uni00E1.hw +631 /cid-631.hw +632 /uni00D8.hw +633 2003 +634..635 3001 +636 ff0c +637 ff0e +638 30fb +639..640 ff1a +641 ff1f +642 ff01 +643..644 309b +645 00b4 +646 ff40 +647 00a8 +648 ff3e +649 ffe3 +650 ff3f +651..652 30fd +653..654 309d +655 3003 +656 4edd +657..659 3005 +660 30fc +661 2015 +662 2010 +663 ff0f +664 ff3c +665 301c +666 2016 +667 ff5c +668 /uni2026.dup2 +669 2025 +670..671 2018 +672 /uni201C.dup2 +673 /uni201D.dup2 +674..675 ff08 +676..677 3014 +678 ff3b +679 ff3d +680 ff5b +681 ff5d +682..691 3008 +692 ff0b +693 2212 +694 00b1 +695 00d7 +696 00f7 +697 ff1d +698 2260 +699 ff1c +700 ff1e +701..702 2266 +703 221e +704 2234 +705 2642 +706 2640 +707 00b0 +708..709 2032 +710 2103 +711 ffe5 +712 ff04 +713..714 ffe0 +715 ff05 +716 ff03 +717 ff06 +718 ff0a +719 ff20 +720 00a7 +721 2606 +722 2605 +723 25cb +724 25cf +725 25ce +726 25c7 +727 25c6 +728 25a1 +729 25a0 +730 25b3 +731 25b2 +732 25bd +733 25bc +734 203b +735 3012 +736 2192 +737..738 2190 +739 2193 +740 3013 +741 2208 +742 220b +743..744 2286 +745..746 2282 +747 222a +748 2229 +749..750 2227 +751 ffe2 +752 21d2 +753 21d4 +754 2200 +755 2203 +756 2220 +757 22a5 +758 2312 +759 2202 +760 2207 +761 2261 +762 2252 +763..764 226a +765 221a +766 223d +767 221d +768 2235 +769..770 222b +771 212b +772 2030 +773 266f +774 266d +775 266a +776..777 2020 +778 00b6 +779 25ef +780..789 ff10 +790..815 ff21 +816..841 ff41 +842..924 3041 +925..1010 30a1 +1011..1027 0391 +1028..1034 03a3 +1035..1051 03b1 +1052..1058 03c3 +1059..1064 0410 +1065 0401 +1066..1097 0416 +1098 0451 +1099..1124 0436 +1125 4e9c +1126 5516 +1127 5a03 +1128 963f +1129 54c0 +1130 611b +1131 6328 +1132 59f6 +1133 9022 +1134 8475 +1135 831c +1136 7a50 +1137 60aa +1138 63e1 +1139 6e25 +1140 65ed +1141 8466 +1142 82a6 +1143 9bf5 +1144 6893 +1145 5727 +1146 65a1 +1147 6271 +1148 5b9b +1149 59d0 +1150 867b +1151 98f4 +1152 7d62 +1153 7dbe +1154 9b8e +1155 6216 +1156 7c9f +1157 88b7 +1158 5b89 +1159 5eb5 +1160 6309 +1161 6697 +1162 6848 +1163 95c7 +1164 978d +1165 674f +1166 4ee5 +1167 4f0a +1168 4f4d +1169 4f9d +1170 5049 +1171 56f2 +1172 5937 +1173 59d4 +1174 5a01 +1175 5c09 +1176 60df +1177 610f +1178 6170 +1179 6613 +1180 6905 +1181 70ba +1182 754f +1183 7570 +1184 79fb +1185 7dad +1186 7def +1187 80c3 +1188 840e +1189 8863 +1190 8b02 +1191 9055 +1192 907a +1193 533b +1194 4e95 +1195 4ea5 +1196 57df +1197 80b2 +1198 90c1 +1199 78ef +1200 4e00 +1201 58f1 +1202 6ea2 +1203 9038 +1204 7a32 +1205 8328 +1206 828b +1207 9c2f +1208 5141 +1209 5370 +1210 54bd +1211 54e1 +1212 56e0 +1213 59fb +1214 5f15 +1215 98f2 +1216 6deb +1217 80e4 +1218 852d +1219 9662 +1220 9670 +1221 96a0 +1222 97fb +1223 540b +1224 53f3 +1225 5b87 +1226 70cf +1227 7fbd +1228 8fc2 +1229 96e8 +1230 536f +1231 9d5c +1232 7aba +1233 4e11 +1234 7893 +1235 81fc +1236 6e26 +1237 5618 +1238 5504 +1239 6b1d +1240 851a +1241 9c3b +1242 59e5 +1243 53a9 +1244 6d66 +1245 74dc +1246 958f +1247 5642 +1248 4e91 +1249 904b +1250 96f2 +1251 834f +1252 990c +1253 53e1 +1254 55b6 +1255 5b30 +1256 5f71 +1257 6620 +1258 66f3 +1259 6804 +1260 6c38 +1261 6cf3 +1262 6d29 +1263 745b +1264 76c8 +1265 7a4e +1266 9834 +1267 82f1 +1268 885b +1269 8a60 +1270 92ed +1271 6db2 +1272 75ab +1273 76ca +1274 99c5 +1275 60a6 +1276 8b01 +1277 8d8a +1278 95b2 +1279 698e +1280 53ad +1281 5186 +1282 5712 +1283 5830 +1284 5944 +1285 5bb4 +1286 5ef6 +1287 6028 +1288 63a9 +1289 63f4 +1290 6cbf +1291 6f14 +1292 708e +1293 7114 +1294 7159 +1295 71d5 +1296 733f +1297 7e01 +1298 8276 +1299 82d1 +1300 8597 +1301 9060 +1302 925b +1303 9d1b +1304 5869 +1305 65bc +1306 6c5a +1307 7525 +1308 51f9 +1309 592e +1310 5965 +1311 5f80 +1312 5fdc +1313 62bc +1314 65fa +1315 6a2a +1316 6b27 +1317 6bb4 +1318 738b +1319 7fc1 +1320 8956 +1321 9d2c +1322 9d0e +1323 9ec4 +1324 5ca1 +1325 6c96 +1326 837b +1327 5104 +1328 5c4b +1329 61b6 +1330 81c6 +1331 6876 +1332 7261 +1333 4e59 +1334 4ffa +1335 5378 +1336 6069 +1337 6e29 +1338 7a4f +1339 97f3 +1340 4e0b +1341 5316 +1342 4eee +1343 4f55 +1344 4f3d +1345 4fa1 +1346 4f73 +1347 52a0 +1348 53ef +1349 5609 +1350 590f +1351 5ac1 +1352 5bb6 +1353 5be1 +1354 79d1 +1355 6687 +1356 679c +1357 67b6 +1358 6b4c +1359 6cb3 +1360 706b +1361 73c2 +1362 798d +1363 79be +1364 7a3c +1365 7b87 +1366 82b1 +1367 82db +1368 8304 +1369 8377 +1370 83ef +1371 83d3 +1372 8766 +1373 8ab2 +1374 5629 +1375 8ca8 +1376 8fe6 +1377 904e +1378 971e +1379 868a +1380 4fc4 +1381 5ce8 +1382 6211 +1383 7259 +1384 753b +1385 81e5 +1386 82bd +1387 86fe +1388 8cc0 +1389 96c5 +1390 9913 +1391 99d5 +1392 4ecb +1393 4f1a +1394 89e3 +1395 56de +1396 584a +1397 58ca +1398 5efb +1399 5feb +1400 602a +1401 6094 +1402 6062 +1403 61d0 +1404 6212 +1405 62d0 +1406 6539 +1407 9b41 +1408 6666 +1409 68b0 +1410 6d77 +1411 7070 +1412 754c +1413 7686 +1414 7d75 +1415 82a5 +1416 87f9 +1417 958b +1418 968e +1419 8c9d +1420 51f1 +1421 52be +1422 5916 +1423 54b3 +1424 5bb3 +1425 5d16 +1426 6168 +1427 6982 +1428 6daf +1429 788d +1430 84cb +1431 8857 +1432 8a72 +1433 93a7 +1434 9ab8 +1435 6d6c +1436 99a8 +1437 86d9 +1438 57a3 +1439 67ff +1440 86ce +1441 920e +1442 5283 +1443 5687 +1444 5404 +1445 5ed3 +1446 62e1 +1447 64b9 +1448 683c +1449 6838 +1450 6bbb +1451 7372 +1452 78ba +1453 7a6b +1454 899a +1455 89d2 +1456 8d6b +1457 8f03 +1458 90ed +1459 95a3 +1460 9694 +1461 9769 +1462 5b66 +1463 5cb3 +1464 697d +1465..1466 984d +1467 639b +1468 7b20 +1469 6a2b +1470 6a7f +1471 68b6 +1472 9c0d +1473 6f5f +1474 5272 +1475 559d +1476 6070 +1477 62ec +1478 6d3b +1479 6e07 +1480 6ed1 +1481 845b +1482 8910 +1483 8f44 +1484 4e14 +1485 9c39 +1486 53f6 +1487 691b +1488 6a3a +1489 9784 +1490 682a +1491 515c +1492 7ac3 +1493 84b2 +1494 91dc +1495 938c +1496 565b +1497 9d28 +1498 6822 +1499 8305 +1500 8431 +1501 7ca5 +1502 5208 +1503 82c5 +1504 74e6 +1505 4e7e +1506 4f83 +1507 51a0 +1508 5bd2 +1509 520a +1510 52d8 +1511 52e7 +1512 5dfb +1513 559a +1514 582a +1515 59e6 +1516 5b8c +1517 5b98 +1518 5bdb +1519 5e72 +1520 5e79 +1521 60a3 +1522 611f +1523 6163 +1524 61be +1525 63db +1526 6562 +1527 67d1 +1528 6853 +1529 68fa +1530 6b3e +1531 6b53 +1532 6c57 +1533 6f22 +1534 6f97 +1535 6f45 +1536 74b0 +1537 7518 +1538 76e3 +1539 770b +1540 7aff +1541 7ba1 +1542 7c21 +1543 7de9 +1544 7f36 +1545 7ff0 +1546 809d +1547 8266 +1548 839e +1549 89b3 +1550 8acc +1551 8cab +1552 9084 +1553 9451 +1554 9593 +1555 9591 +1556 95a2 +1557 9665 +1558 97d3 +1559 9928 +1560 8218 +1561 4e38 +1562 542b +1563 5cb8 +1564 5dcc +1565 73a9 +1566 764c +1567 773c +1568 5ca9 +1569 7feb +1570 8d0b +1571 96c1 +1572 9811 +1573 9854 +1574 9858 +1575 4f01 +1576 4f0e +1577 5371 +1578 559c +1579 5668 +1580 57fa +1581 5947 +1582 5b09 +1583 5bc4 +1584 5c90 +1585 5e0c +1586 5e7e +1587 5fcc +1588 63ee +1589 673a +1590 65d7 +1591 65e2 +1592 671f +1593 68cb +1594 68c4 +1595 6a5f +1596 5e30 +1597 6bc5 +1598 6c17 +1599 6c7d +1600 757f +1601 7948 +1602 5b63 +1603 7a00 +1604 7d00 +1605 5fbd +1606 898f +1607 8a18 +1608 8cb4 +1609 8d77 +1610 8ecc +1611 8f1d +1612 98e2 +1613 9a0e +1614 9b3c +1615 4e80 +1616 507d +1617 5100 +1618 5993 +1619 5b9c +1620 622f +1621 6280 +1622 64ec +1623 6b3a +1624 72a0 +1625 7591 +1626 7947 +1627 7fa9 +1628 87fb +1629 8abc +1630 8b70 +1631 63ac +1632 83ca +1633 97a0 +1634 5409 +1635 5403 +1636 55ab +1637 6854 +1638 6a58 +1639 8a70 +1640 7827 +1641 6775 +1642 9ecd +1643 5374 +1644 5ba2 +1645 811a +1646 8650 +1647 9006 +1648 4e18 +1649 4e45 +1650 4ec7 +1651 4f11 +1652 53ca +1653 5438 +1654 5bae +1655 5f13 +1656 6025 +1657 6551 +1658 673d +1659 6c42 +1660 6c72 +1661 6ce3 +1662 7078 +1663 7403 +1664 7a76 +1665 7aae +1666 7b08 +1667 7d1a +1668 7cfe +1669 7d66 +1670 65e7 +1671 725b +1672 53bb +1673 5c45 +1674 5de8 +1675 62d2 +1676 62e0 +1677 6319 +1678 6e20 +1679 865a +1680 8a31 +1681 8ddd +1682 92f8 +1683 6f01 +1684 79a6 +1685 9b5a +1686 4ea8 +1687..1688 4eab +1689 4f9b +1690 4fa0 +1691 50d1 +1692 5147 +1693 7af6 +1694 5171 +1695 51f6 +1696 5354 +1697 5321 +1698 537f +1699 53eb +1700 55ac +1701 5883 +1702 5ce1 +1703 5f37 +1704 5f4a +1705 602f +1706 6050 +1707 606d +1708 631f +1709 6559 +1710 6a4b +1711 6cc1 +1712 72c2 +1713 72ed +1714 77ef +1715 80f8 +1716 8105 +1717 8208 +1718 854e +1719 90f7 +1720 93e1 +1721 97ff +1722 9957 +1723 9a5a +1724 4ef0 +1725 51dd +1726 5c2d +1727 6681 +1728 696d +1729 5c40 +1730 66f2 +1731 6975 +1732 7389 +1733 6850 +1734 7c81 +1735 50c5 +1736 52e4 +1737 5747 +1738 5dfe +1739 9326 +1740 65a4 +1741 6b23 +1742 6b3d +1743 7434 +1744 7981 +1745 79bd +1746 7b4b +1747 7dca +1748 82b9 +1749 83cc +1750 887f +1751 895f +1752 8b39 +1753 8fd1 +1754 91d1 +1755 541f +1756 9280 +1757 4e5d +1758 5036 +1759 53e5 +1760 533a +1761 72d7 +1762 7396 +1763 77e9 +1764 82e6 +1765 8eaf +1766 99c6 +1767 99c8 +1768 99d2 +1769 5177 +1770 611a +1771 865e +1772 55b0 +1773 7a7a +1774 5076 +1775 5bd3 +1776 9047 +1777 9685 +1778 4e32 +1779 6adb +1780 91e7 +1781 5c51 +1782 5c48 +1783 6398 +1784 7a9f +1785 6c93 +1786 9774 +1787 8f61 +1788 7aaa +1789 718a +1790 9688 +1791 7c82 +1792 6817 +1793 7e70 +1794 6851 +1795 936c +1796 52f2 +1797 541b +1798 85ab +1799 8a13 +1800 7fa4 +1801 8ecd +1802 90e1 +1803 5366 +1804 8888 +1805 7941 +1806 4fc2 +1807 50be +1808 5211 +1809 5144 +1810 5553 +1811 572d +1812 73ea +1813 578b +1814 5951 +1815 5f62 +1816 5f84 +1817 6075 +1818 6176 +1819 6167 +1820 61a9 +1821 63b2 +1822 643a +1823 656c +1824 666f +1825 6842 +1826 6e13 +1827 7566 +1828 7a3d +1829 7cfb +1830 7d4c +1831 7d99 +1832 7e4b +1833 7f6b +1834 830e +1835 834a +1836 86cd +1837 8a08 +1838 8a63 +1839 8b66 +1840 8efd +1841 981a +1842 9d8f +1843 82b8 +1844 8fce +1845 9be8 +1846 5287 +1847 621f +1848 6483 +1849 6fc0 +1850 9699 +1851 6841 +1852 5091 +1853 6b20 +1854 6c7a +1855 6f54 +1856 7a74 +1857 7d50 +1858 8840 +1859 8a23 +1860 6708 +1861 4ef6 +1862 5039 +1863 5026 +1864 5065 +1865 517c +1866 5238 +1867 5263 +1868 55a7 +1869 570f +1870 5805 +1871 5acc +1872 5efa +1873 61b2 +1874 61f8 +1875 62f3 +1876 6372 +1877 691c +1878 6a29 +1879 727d +1880 72ac +1881 732e +1882 7814 +1883 786f +1884 7d79 +1885 770c +1886 80a9 +1887 898b +1888 8b19 +1889 8ce2 +1890 8ed2 +1891 9063 +1892 9375 +1893 967a +1894 9855 +1895 9a13 +1896 9e78 +1897 5143 +1898 539f +1899 53b3 +1900 5e7b +1901 5f26 +1902 6e1b +1903 6e90 +1904 7384 +1905 73fe +1906 7d43 +1907 8237 +1908 8a00 +1909 8afa +1910 9650 +1911 4e4e +1912 500b +1913 53e4 +1914 547c +1915 56fa +1916 59d1 +1917 5b64 +1918 5df1 +1919 5eab +1920 5f27 +1921 6238 +1922 6545 +1923 67af +1924 6e56 +1925 72d0 +1926 7cca +1927 88b4 +1928 80a1 +1929 80e1 +1930 83f0 +1931 864e +1932 8a87 +1933 8de8 +1934 9237 +1935 96c7 +1936 9867 +1937 9f13 +1938 4e94 +1939 4e92 +1940 4f0d +1941 5348 +1942 5449 +1943 543e +1944 5a2f +1945 5f8c +1946 5fa1 +1947 609f +1948 68a7 +1949 6a8e +1950 745a +1951 7881 +1952 8a9e +1953 8aa4 +1954 8b77 +1955 9190 +1956 4e5e +1957 9bc9 +1958 4ea4 +1959 4f7c +1960 4faf +1961 5019 +1962 5016 +1963 5149 +1964 516c +1965 529f +1966 52b9 +1967 52fe +1968 539a +1969 53e3 +1970 5411 +1971 540e +1972 5589 +1973 5751 +1974 57a2 +1975 597d +1976 5b54 +1977 5b5d +1978 5b8f +1979 5de5 +1980 5de7 +1981 5df7 +1982 5e78 +1983 5e83 +1984 5e9a +1985 5eb7 +1986 5f18 +1987 6052 +1988 614c +1989 6297 +1990 62d8 +1991 63a7 +1992 653b +1993 6602 +1994 6643 +1995 66f4 +1996 676d +1997 6821 +1998 6897 +1999 69cb +2000 6c5f +2001 6d2a +2002 6d69 +2003 6e2f +2004 6e9d +2005 7532 +2006 7687 +2007 786c +2008 7a3f +2009 7ce0 +2010 7d05 +2011 7d18 +2012 7d5e +2013 7db1 +2014 8015 +2015 8003 +2016 80af +2017 80b1 +2018 8154 +2019 818f +2020 822a +2021 8352 +2022 884c +2023 8861 +2024 8b1b +2025 8ca2 +2026 8cfc +2027 90ca +2028 9175 +2029 9271 +2030 783f +2031 92fc +2032 95a4 +2033 964d +2034 9805 +2035 9999 +2036 9ad8 +2037 9d3b +2038 525b +2039 52ab +2040 53f7 +2041 5408 +2042 58d5 +2043 62f7 +2044 6fe0 +2045 8c6a +2046 8f5f +2047 9eb9 +2048 514b +2049 523b +2050 544a +2051 56fd +2052 7a40 +2053 9177 +2054 9d60 +2055 9ed2 +2056 7344 +2057 6f09 +2058 8170 +2059 7511 +2060 5ffd +2061 60da +2062 9aa8 +2063 72db +2064 8fbc +2065 6b64 +2066 9803 +2067 4eca +2068 56f0 +2069 5764 +2070 58be +2071 5a5a +2072 6068 +2073 61c7 +2074 660f +2075 6606 +2076 6839 +2077 68b1 +2078 6df7 +2079 75d5 +2080 7d3a +2081 826e +2082 9b42 +2083 4e9b +2084 4f50 +2085 53c9 +2086 5506 +2087 5d6f +2088 5de6 +2089 5dee +2090 67fb +2091 6c99 +2092 7473 +2093 7802 +2094 8a50 +2095 9396 +2096 88df +2097 5750 +2098 5ea7 +2099 632b +2100 50b5 +2101 50ac +2102 518d +2103 6700 +2104 54c9 +2105 585e +2106 59bb +2107 5bb0 +2108 5f69 +2109 624d +2110 63a1 +2111 683d +2112 6b73 +2113 6e08 +2114 707d +2115 91c7 +2116 7280 +2117 7815 +2118 7826 +2119 796d +2120 658e +2121 7d30 +2122 83dc +2123 88c1 +2124 8f09 +2125 969b +2126 5264 +2127 5728 +2128 6750 +2129 7f6a +2130 8ca1 +2131 51b4 +2132 5742 +2133 962a +2134 583a +2135 698a +2136 80b4 +2137 54b2 +2138 5d0e +2139 57fc +2140 7895 +2141 9dfa +2142 4f5c +2143 524a +2144 548b +2145 643e +2146 6628 +2147 6714 +2148 67f5 +2149 7a84 +2150 7b56 +2151 7d22 +2152 932f +2153 685c +2154 9bad +2155 7b39 +2156 5319 +2157 518a +2158 5237 +2159 5bdf +2160 62f6 +2161 64ae +2162 64e6 +2163 672d +2164 6bba +2165 85a9 +2166 96d1 +2167 7690 +2168 9bd6 +2169 634c +2170 9306 +2171 9bab +2172 76bf +2173 6652 +2174 4e09 +2175 5098 +2176 53c2 +2177 5c71 +2178 60e8 +2179 6492 +2180 6563 +2181 685f +2182 71e6 +2183 73ca +2184 7523 +2185 7b97 +2186 7e82 +2187 8695 +2188 8b83 +2189 8cdb +2190 9178 +2191 9910 +2192 65ac +2193 66ab +2194 6b8b +2195 4ed5 +2196 4ed4 +2197 4f3a +2198 4f7f +2199 523a +2200 53f8 +2201 53f2 +2202 55e3 +2203 56db +2204 58eb +2205 59cb +2206 59c9 +2207 59ff +2208 5b50 +2209 5c4d +2210 5e02 +2211 5e2b +2212 5fd7 +2213 601d +2214 6307 +2215 652f +2216 5b5c +2217 65af +2218 65bd +2219 65e8 +2220 679d +2221 6b62 +2222 6b7b +2223 6c0f +2224 7345 +2225 7949 +2226 79c1 +2227 7cf8 +2228 7d19 +2229 7d2b +2230 80a2 +2231 8102 +2232 81f3 +2233 8996 +2234 8a5e +2235 8a69 +2236 8a66 +2237 8a8c +2238 8aee +2239 8cc7 +2240 8cdc +2241 96cc +2242 98fc +2243 6b6f +2244 4e8b +2245 4f3c +2246 4f8d +2247 5150 +2248 5b57 +2249 5bfa +2250 6148 +2251 6301 +2252 6642 +2253 6b21 +2254 6ecb +2255 6cbb +2256 723e +2257 74bd +2258 75d4 +2259 78c1 +2260 793a +2261 800c +2262 8033 +2263 81ea +2264 8494 +2265 8f9e +2266 6c50 +2267 9e7f +2268 5f0f +2269 8b58 +2270 9d2b +2271 7afa +2272 8ef8 +2273 5b8d +2274 96eb +2275 4e03 +2276 53f1 +2277 57f7 +2278 5931 +2279 5ac9 +2280 5ba4 +2281 6089 +2282 6e7f +2283 6f06 +2284 75be +2285 8cea +2286 5b9f +2287 8500 +2288 7be0 +2289 5072 +2290 67f4 +2291 829d +2292 5c61 +2293 854a +2294 7e1e +2295 820e +2296 5199 +2297 5c04 +2298 6368 +2299 8d66 +2300 659c +2301 716e +2302 793e +2303 7d17 +2304 8005 +2305 8b1d +2306 8eca +2307 906e +2308 86c7 +2309 90aa +2310 501f +2311 52fa +2312 5c3a +2313 6753 +2314 707c +2315 7235 +2316 914c +2317 91c8 +2318 932b +2319 82e5 +2320 5bc2 +2321 5f31 +2322 60f9 +2323 4e3b +2324 53d6 +2325 5b88 +2326 624b +2327 6731 +2328 6b8a +2329 72e9 +2330 73e0 +2331 7a2e +2332 816b +2333 8da3 +2334 9152 +2335 9996 +2336 5112 +2337 53d7 +2338 546a +2339 5bff +2340 6388 +2341 6a39 +2342 7dac +2343 9700 +2344 56da +2345 53ce +2346 5468 +2347 5b97 +2348 5c31 +2349 5dde +2350 4fee +2351 6101 +2352 62fe +2353 6d32 +2354 79c0 +2355 79cb +2356 7d42 +2357 7e4d +2358 7fd2 +2359 81ed +2360 821f +2361 8490 +2362 8846 +2363 8972 +2364 8b90 +2365 8e74 +2366 8f2f +2367 9031 +2368 914b +2369 916c +2370 96c6 +2371 919c +2372 4ec0 +2373 4f4f +2374 5145 +2375 5341 +2376 5f93 +2377 620e +2378 67d4 +2379 6c41 +2380 6e0b +2381 7363 +2382 7e26 +2383 91cd +2384 9283 +2385 53d4 +2386 5919 +2387 5bbf +2388 6dd1 +2389 795d +2390 7e2e +2391 7c9b +2392 587e +2393 719f +2394 51fa +2395 8853 +2396 8ff0 +2397 4fca +2398 5cfb +2399 6625 +2400 77ac +2401 7ae3 +2402 821c +2403 99ff +2404 51c6 +2405 5faa +2406 65ec +2407 696f +2408 6b89 +2409 6df3 +2410 6e96 +2411 6f64 +2412 76fe +2413 7d14 +2414 5de1 +2415 9075 +2416 9187 +2417 9806 +2418 51e6 +2419 521d +2420 6240 +2421 6691 +2422 66d9 +2423 6e1a +2424 5eb6 +2425 7dd2 +2426 7f72 +2427 66f8 +2428 85af +2429 85f7 +2430 8af8 +2431 52a9 +2432 53d9 +2433 5973 +2434 5e8f +2435 5f90 +2436 6055 +2437 92e4 +2438 9664 +2439 50b7 +2440 511f +2441 52dd +2442 5320 +2443 5347 +2444 53ec +2445 54e8 +2446 5546 +2447 5531 +2448 5617 +2449 5968 +2450 59be +2451 5a3c +2452 5bb5 +2453 5c06 +2454 5c0f +2455 5c11 +2456 5c1a +2457 5e84 +2458 5e8a +2459 5ee0 +2460 5f70 +2461 627f +2462 6284 +2463 62db +2464 638c +2465 6377 +2466 6607 +2467 660c +2468 662d +2469 6676 +2470 677e +2471 68a2 +2472 6a1f +2473 6a35 +2474 6cbc +2475 6d88 +2476 6e09 +2477 6e58 +2478 713c +2479 7126 +2480 7167 +2481 75c7 +2482 7701 +2483 785d +2484 7901 +2485 7965 +2486 79f0 +2487 7ae0 +2488 7b11 +2489 7ca7 +2490 7d39 +2491 8096 +2492 83d6 +2493 848b +2494 8549 +2495 885d +2496 88f3 +2497 8a1f +2498 8a3c +2499 8a54 +2500 8a73 +2501 8c61 +2502 8cde +2503 91a4 +2504 9266 +2505 937e +2506 9418 +2507 969c +2508 9798 +2509 4e0a +2510 4e08 +2511 4e1e +2512 4e57 +2513 5197 +2514 5270 +2515 57ce +2516 5834 +2517 58cc +2518 5b22 +2519 5e38 +2520 60c5 +2521 64fe +2522 6761 +2523 6756 +2524 6d44 +2525 72b6 +2526 7573 +2527 7a63 +2528 84b8 +2529 8b72 +2530 91b8 +2531 9320 +2532 5631 +2533 57f4 +2534 98fe +2535 62ed +2536 690d +2537 6b96 +2538 71ed +2539 7e54 +2540 8077 +2541 8272 +2542 89e6 +2543 98df +2544 8755 +2545 8fb1 +2546 5c3b +2547 4f38 +2548 4fe1 +2549 4fb5 +2550 5507 +2551 5a20 +2552 5bdd +2553 5be9 +2554 5fc3 +2555 614e +2556 632f +2557 65b0 +2558 664b +2559 68ee +2560 699b +2561 6d78 +2562 6df1 +2563 7533 +2564 75b9 +2565 771f +2566 795e +2567 79e6 +2568 7d33 +2569 81e3 +2570 82af +2571 85aa +2572 89aa +2573 8a3a +2574 8eab +2575 8f9b +2576 9032 +2577 91dd +2578 9707 +2579 4eba +2580 4ec1 +2581 5203 +2582 5875 +2583 58ec +2584 5c0b +2585 751a +2586 5c3d +2587 814e +2588 8a0a +2589 8fc5 +2590 9663 +2591 976d +2592 7b25 +2593 8acf +2594 9808 +2595 9162 +2596 56f3 +2597 53a8 +2598 9017 +2599 5439 +2600 5782 +2601 5e25 +2602 63a8 +2603 6c34 +2604 708a +2605 7761 +2606 7c8b +2607 7fe0 +2608 8870 +2609 9042 +2610 9154 +2611 9310 +2612 9318 +2613 968f +2614 745e +2615 9ac4 +2616 5d07 +2617 5d69 +2618 6570 +2619 67a2 +2620 8da8 +2621 96db +2622 636e +2623 6749 +2624 6919 +2625 83c5 +2626 9817 +2627 96c0 +2628 88fe +2629 6f84 +2630 647a +2631 5bf8 +2632 4e16 +2633 702c +2634 755d +2635 662f +2636 51c4 +2637 5236 +2638 52e2 +2639 59d3 +2640 5f81 +2641 6027 +2642 6210 +2643 653f +2644 6574 +2645 661f +2646 6674 +2647 68f2 +2648 6816 +2649 6b63 +2650 6e05 +2651 7272 +2652 751f +2653 76db +2654 7cbe +2655 8056 +2656 58f0 +2657 88fd +2658 897f +2659 8aa0 +2660 8a93 +2661 8acb +2662 901d +2663 9192 +2664 9752 +2665 9759 +2666 6589 +2667 7a0e +2668 8106 +2669 96bb +2670 5e2d +2671 60dc +2672 621a +2673 65a5 +2674 6614 +2675 6790 +2676 77f3 +2677 7a4d +2678 7c4d +2679 7e3e +2680 810a +2681 8cac +2682 8d64 +2683 8de1 +2684 8e5f +2685 78a9 +2686 5207 +2687 62d9 +2688 63a5 +2689 6442 +2690 6298 +2691 8a2d +2692 7a83 +2693 7bc0 +2694 8aac +2695 96ea +2696 7d76 +2697 820c +2698 8749 +2699 4ed9 +2700 5148 +2701 5343 +2702 5360 +2703 5ba3 +2704 5c02 +2705 5c16 +2706 5ddd +2707 6226 +2708 6247 +2709 64b0 +2710 6813 +2711 6834 +2712 6cc9 +2713 6d45 +2714 6d17 +2715 67d3 +2716 6f5c +2717 714e +2718 717d +2719 65cb +2720 7a7f +2721 7bad +2722 7dda +2723 7e4a +2724 7fa8 +2725 817a +2726 821b +2727 8239 +2728 85a6 +2729 8a6e +2730 8cce +2731 8df5 +2732 9078 +2733 9077 +2734 92ad +2735 9291 +2736 9583 +2737 9bae +2738 524d +2739 5584 +2740 6f38 +2741 7136 +2742 5168 +2743 7985 +2744 7e55 +2745 81b3 +2746 7cce +2747 564c +2748 5851 +2749 5ca8 +2750 63aa +2751 66fe +2752 66fd +2753 695a +2754 72d9 +2755 758f +2756 758e +2757 790e +2758 7956 +2759 79df +2760 7c97 +2761 7d20 +2762 7d44 +2763 8607 +2764 8a34 +2765 963b +2766 9061 +2767 9f20 +2768 50e7 +2769 5275 +2770 53cc +2771 53e2 +2772 5009 +2773 55aa +2774 58ee +2775 594f +2776 723d +2777 5b8b +2778 5c64 +2779 531d +2780 60e3 +2781 60f3 +2782 635c +2783 6383 +2784 633f +2785 63bb +2786 64cd +2787 65e9 +2788 66f9 +2789 5de3 +2790 69cd +2791 69fd +2792 6f15 +2793 71e5 +2794 4e89 +2795 75e9 +2796 76f8 +2797 7a93 +2798 7cdf +2799 7dcf +2800 7d9c +2801 8061 +2802 8349 +2803 8358 +2804 846c +2805 84bc +2806 85fb +2807 88c5 +2808 8d70 +2809 9001 +2810 906d +2811 9397 +2812 971c +2813 9a12 +2814 50cf +2815 5897 +2816 618e +2817 81d3 +2818 8535 +2819 8d08 +2820 9020 +2821 4fc3 +2822 5074 +2823 5247 +2824 5373 +2825 606f +2826 6349 +2827 675f +2828 6e2c +2829 8db3 +2830 901f +2831 4fd7 +2832 5c5e +2833 8cca +2834 65cf +2835 7d9a +2836 5352 +2837 8896 +2838 5176 +2839 63c3 +2840 5b58 +2841 5b6b +2842 5c0a +2843 640d +2844 6751 +2845 905c +2846 4ed6 +2847 591a +2848 592a +2849 6c70 +2850 8a51 +2851 553e +2852 5815 +2853 59a5 +2854 60f0 +2855 6253 +2856 67c1 +2857 8235 +2858 6955 +2859 9640 +2860 99c4 +2861 9a28 +2862 4f53 +2863 5806 +2864 5bfe +2865 8010 +2866 5cb1 +2867 5e2f +2868 5f85 +2869 6020 +2870 614b +2871 6234 +2872 66ff +2873 6cf0 +2874 6ede +2875 80ce +2876 817f +2877 82d4 +2878 888b +2879 8cb8 +2880 9000 +2881 902e +2882 968a +2883 9edb +2884 9bdb +2885 4ee3 +2886 53f0 +2887 5927 +2888 7b2c +2889 918d +2890 984c +2891 9df9 +2892 6edd +2893 7027 +2894 5353 +2895 5544 +2896 5b85 +2897 6258 +2898 629e +2899 62d3 +2900 6ca2 +2901 6fef +2902 7422 +2903 8a17 +2904 9438 +2905 6fc1 +2906 8afe +2907 8338 +2908 51e7 +2909 86f8 +2910 53ea +2911 53e9 +2912 4f46 +2913 9054 +2914 8fb0 +2915 596a +2916 8131 +2917 5dfd +2918 7aea +2919 8fbf +2920 68da +2921 8c37 +2922 72f8 +2923 9c48 +2924 6a3d +2925 8ab0 +2926 4e39 +2927 5358 +2928 5606 +2929 5766 +2930 62c5 +2931 63a2 +2932 65e6 +2933 6b4e +2934 6de1 +2935 6e5b +2936 70ad +2937 77ed +2938 7aef +2939 7baa +2940 7dbb +2941 803d +2942 80c6 +2943 86cb +2944 8a95 +2945 935b +2946 56e3 +2947 58c7 +2948 5f3e +2949 65ad +2950 6696 +2951 6a80 +2952 6bb5 +2953 7537 +2954 8ac7 +2955 5024 +2956 77e5 +2957 5730 +2958 5f1b +2959 6065 +2960 667a +2961 6c60 +2962 75f4 +2963 7a1a +2964 7f6e +2965 81f4 +2966 8718 +2967 9045 +2968 99b3 +2969 7bc9 +2970 755c +2971 7af9 +2972 7b51 +2973 84c4 +2974 9010 +2975 79e9 +2976 7a92 +2977 8336 +2978 5ae1 +2979 7740 +2980 4e2d +2981 4ef2 +2982 5b99 +2983 5fe0 +2984 62bd +2985 663c +2986 67f1 +2987 6ce8 +2988 866b +2989 8877 +2990 8a3b +2991 914e +2992 92f3 +2993 99d0 +2994 6a17 +2995 7026 +2996 732a +2997 82e7 +2998 8457 +2999 8caf +3000 4e01 +3001 5146 +3002 51cb +3003 558b +3004 5bf5 +3005 5e16 +3006 5e33 +3007 5e81 +3008 5f14 +3009 5f35 +3010 5f6b +3011 5fb4 +3012 61f2 +3013 6311 +3014 66a2 +3015 671d +3016 6f6e +3017 7252 +3018 753a +3019 773a +3020 8074 +3021 8139 +3022 8178 +3023 8776 +3024 8abf +3025 8adc +3026 8d85 +3027 8df3 +3028 929a +3029 9577 +3030 9802 +3031 9ce5 +3032 52c5 +3033 6357 +3034 76f4 +3035 6715 +3036 6c88 +3037 73cd +3038 8cc3 +3039 93ae +3040 9673 +3041 6d25 +3042 589c +3043 690e +3044 69cc +3045 8ffd +3046 939a +3047 75db +3048 901a +3049 585a +3050 6802 +3051 63b4 +3052 69fb +3053 4f43 +3054 6f2c +3055 67d8 +3056 8fbb +3057 8526 +3058 7db4 +3059 9354 +3060 693f +3061 6f70 +3062 576a +3063 58f7 +3064 5b2c +3065 7d2c +3066 722a +3067 540a +3068 91e3 +3069 9db4 +3070 4ead +3071 4f4e +3072 505c +3073 5075 +3074 5243 +3075 8c9e +3076 5448 +3077 5824 +3078 5b9a +3079 5e1d +3080 5e95 +3081 5ead +3082 5ef7 +3083 5f1f +3084 608c +3085 62b5 +3086 633a +3087 63d0 +3088 68af +3089 6c40 +3090 7887 +3091 798e +3092 7a0b +3093 7de0 +3094 8247 +3095 8a02 +3096 8ae6 +3097 8e44 +3098 9013 +3099 90b8 +3100 912d +3101 91d8 +3102 9f0e +3103 6ce5 +3104 6458 +3105 64e2 +3106 6575 +3107 6ef4 +3108 7684 +3109 7b1b +3110 9069 +3111 93d1 +3112 6eba +3113 54f2 +3114 5fb9 +3115 64a4 +3116 8f4d +3117 8fed +3118 9244 +3119 5178 +3120 586b +3121 5929 +3122 5c55 +3123 5e97 +3124 6dfb +3125 7e8f +3126 751c +3127 8cbc +3128 8ee2 +3129 985b +3130 70b9 +3131 4f1d +3132 6bbf +3133 6fb1 +3134 7530 +3135 96fb +3136 514e +3137 5410 +3138 5835 +3139 5857 +3140 59ac +3141 5c60 +3142 5f92 +3143 6597 +3144 675c +3145 6e21 +3146 767b +3147 83df +3148 8ced +3149 9014 +3150 90fd +3151 934d +3152 7825 +3153 783a +3154 52aa +3155 5ea6 +3156 571f +3157 5974 +3158 6012 +3159 5012 +3160 515a +3161 51ac +3162 51cd +3163 5200 +3164 5510 +3165 5854 +3166 5858 +3167 5957 +3168 5b95 +3169 5cf6 +3170 5d8b +3171 60bc +3172 6295 +3173 642d +3174 6771 +3175 6843 +3176 68bc +3177 68df +3178 76d7 +3179 6dd8 +3180 6e6f +3181 6d9b +3182 706f +3183 71c8 +3184 5f53 +3185 75d8 +3186 7977 +3187 7b49 +3188 7b54 +3189 7b52 +3190 7cd6 +3191 7d71 +3192 5230 +3193 8463 +3194 8569 +3195 85e4 +3196 8a0e +3197 8b04 +3198 8c46 +3199 8e0f +3200 9003 +3201 900f +3202 9419 +3203 9676 +3204 982d +3205 9a30 +3206 95d8 +3207 50cd +3208 52d5 +3209 540c +3210 5802 +3211 5c0e +3212 61a7 +3213 649e +3214 6d1e +3215 77b3 +3216 7ae5 +3217 80f4 +3218 8404 +3219 9053 +3220 9285 +3221 5ce0 +3222 9d07 +3223 533f +3224 5f97 +3225 5fb3 +3226 6d9c +3227 7279 +3228 7763 +3229 79bf +3230 7be4 +3231 6bd2 +3232 72ec +3233 8aad +3234 6803 +3235 6a61 +3236 51f8 +3237 7a81 +3238 6934 +3239 5c4a +3240 9cf6 +3241 82eb +3242 5bc5 +3243 9149 +3244 701e +3245 5678 +3246 5c6f +3247 60c7 +3248 6566 +3249 6c8c +3250 8c5a +3251 9041 +3252 9813 +3253 5451 +3254 66c7 +3255 920d +3256 5948 +3257 90a3 +3258 5185 +3259 4e4d +3260 51ea +3261 8599 +3262 8b0e +3263 7058 +3264 637a +3265 934b +3266 6962 +3267 99b4 +3268 7e04 +3269 7577 +3270 5357 +3271 6960 +3272 8edf +3273 96e3 +3274 6c5d +3275 4e8c +3276 5c3c +3277 5f10 +3278 8fe9 +3279 5302 +3280 8cd1 +3281 8089 +3282 8679 +3283 5eff +3284 65e5 +3285 4e73 +3286 5165 +3287 5982 +3288 5c3f +3289 97ee +3290 4efb +3291 598a +3292 5fcd +3293 8a8d +3294 6fe1 +3295 79b0 +3296 7962 +3297 5be7 +3298 8471 +3299 732b +3300 71b1 +3301 5e74 +3302 5ff5 +3303 637b +3304 649a +3305 71c3 +3306 7c98 +3307 4e43 +3308 5efc +3309 4e4b +3310 57dc +3311 56a2 +3312 60a9 +3313 6fc3 +3314 7d0d +3315 80fd +3316 8133 +3317 81bf +3318 8fb2 +3319 8997 +3320 86a4 +3321 5df4 +3322 628a +3323 64ad +3324 8987 +3325 6777 +3326 6ce2 +3327 6d3e +3328 7436 +3329 7834 +3330 5a46 +3331 7f75 +3332 82ad +3333 99ac +3334 4ff3 +3335 5ec3 +3336 62dd +3337 6392 +3338 6557 +3339 676f +3340 76c3 +3341 724c +3342 80cc +3343 80ba +3344 8f29 +3345 914d +3346 500d +3347 57f9 +3348 5a92 +3349 6885 +3350 6973 +3351 7164 +3352 72fd +3353 8cb7 +3354 58f2 +3355 8ce0 +3356 966a +3357 9019 +3358 877f +3359 79e4 +3360 77e7 +3361 8429 +3362 4f2f +3363 5265 +3364 535a +3365 62cd +3366 67cf +3367 6cca +3368 767d +3369 7b94 +3370 7c95 +3371 8236 +3372 8584 +3373 8feb +3374 66dd +3375 6f20 +3376 7206 +3377 7e1b +3378 83ab +3379 99c1 +3380 9ea6 +3381 51fd +3382 7bb1 +3383 7872 +3384 7bb8 +3385 8087 +3386 7b48 +3387 6ae8 +3388 5e61 +3389 808c +3390 7551 +3391 7560 +3392 516b +3393 9262 +3394 6e8c +3395 767a +3396 9197 +3397 9aea +3398 4f10 +3399 7f70 +3400 629c +3401 7b4f +3402 95a5 +3403 9ce9 +3404 567a +3405 5859 +3406 86e4 +3407 96bc +3408 4f34 +3409 5224 +3410 534a +3411 53cd +3412 53db +3413 5e06 +3414 642c +3415 6591 +3416 677f +3417 6c3e +3418 6c4e +3419 7248 +3420 72af +3421 73ed +3422 7554 +3423 7e41 +3424 822c +3425 85e9 +3426 8ca9 +3427 7bc4 +3428 91c6 +3429 7169 +3430 9812 +3431 98ef +3432 633d +3433 6669 +3434 756a +3435 76e4 +3436 78d0 +3437 8543 +3438 86ee +3439 532a +3440 5351 +3441 5426 +3442 5983 +3443 5e87 +3444 5f7c +3445 60b2 +3446 6249 +3447 6279 +3448 62ab +3449 6590 +3450 6bd4 +3451 6ccc +3452 75b2 +3453 76ae +3454 7891 +3455 79d8 +3456 7dcb +3457 7f77 +3458 80a5 +3459 88ab +3460 8ab9 +3461 8cbb +3462 907f +3463 975e +3464 98db +3465 6a0b +3466 7c38 +3467 5099 +3468 5c3e +3469 5fae +3470 6787 +3471 6bd8 +3472 7435 +3473 7709 +3474 7f8e +3475 9f3b +3476 67ca +3477 7a17 +3478 5339 +3479 758b +3480 9aed +3481 5f66 +3482 819d +3483 83f1 +3484 8098 +3485 5f3c +3486 5fc5 +3487 7562 +3488 7b46 +3489 903c +3490 6867 +3491 59eb +3492 5a9b +3493 7d10 +3494 767e +3495 8b2c +3496 4ff5 +3497 5f6a +3498 6a19 +3499 6c37 +3500 6f02 +3501 74e2 +3502 7968 +3503 8868 +3504 8a55 +3505 8c79 +3506 5edf +3507 63cf +3508 75c5 +3509 79d2 +3510 82d7 +3511 9328 +3512 92f2 +3513 849c +3514 86ed +3515 9c2d +3516 54c1 +3517 5f6c +3518 658c +3519 6d5c +3520 7015 +3521 8ca7 +3522 8cd3 +3523 983b +3524 654f +3525 74f6 +3526 4e0d +3527 4ed8 +3528 57e0 +3529 592b +3530 5a66 +3531 5bcc +3532 51a8 +3533 5e03 +3534 5e9c +3535 6016 +3536 6276 +3537 6577 +3538 65a7 +3539 666e +3540 6d6e +3541 7236 +3542 7b26 +3543 8150 +3544 819a +3545 8299 +3546 8b5c +3547 8ca0 +3548 8ce6 +3549 8d74 +3550 961c +3551 9644 +3552 4fae +3553 64ab +3554 6b66 +3555 821e +3556 8461 +3557 856a +3558 90e8 +3559 5c01 +3560 6953 +3561 98a8 +3562 847a +3563 8557 +3564 4f0f +3565 526f +3566 5fa9 +3567 5e45 +3568 670d +3569 798f +3570 8179 +3571 8907 +3572 8986 +3573 6df5 +3574 5f17 +3575 6255 +3576 6cb8 +3577 4ecf +3578 7269 +3579 9b92 +3580 5206 +3581 543b +3582 5674 +3583 58b3 +3584 61a4 +3585 626e +3586 711a +3587 596e +3588 7c89 +3589 7cde +3590 7d1b +3591 96f0 +3592 6587 +3593 805e +3594 4e19 +3595 4f75 +3596 5175 +3597 5840 +3598 5e63 +3599 5e73 +3600 5f0a +3601 67c4 +3602 4e26 +3603 853d +3604 9589 +3605 965b +3606 7c73 +3607 9801 +3608 50fb +3609 58c1 +3610 7656 +3611 78a7 +3612 5225 +3613 77a5 +3614 8511 +3615 7b86 +3616 504f +3617 5909 +3618 7247 +3619 7bc7 +3620 7de8 +3621 8fba +3622 8fd4 +3623 904d +3624 4fbf +3625 52c9 +3626 5a29 +3627 5f01 +3628 97ad +3629 4fdd +3630 8217 +3631 92ea +3632 5703 +3633 6355 +3634 6b69 +3635 752b +3636 88dc +3637 8f14 +3638 7a42 +3639 52df +3640 5893 +3641 6155 +3642 620a +3643 66ae +3644 6bcd +3645 7c3f +3646 83e9 +3647 5023 +3648 4ff8 +3649 5305 +3650 5446 +3651 5831 +3652 5949 +3653 5b9d +3654 5cf0 +3655 5cef +3656 5d29 +3657 5e96 +3658 62b1 +3659 6367 +3660 653e +3661 65b9 +3662 670b +3663 6cd5 +3664 6ce1 +3665 70f9 +3666 7832 +3667 7e2b +3668 80de +3669 82b3 +3670 840c +3671 84ec +3672 8702 +3673 8912 +3674 8a2a +3675 8c4a +3676 90a6 +3677 92d2 +3678 98fd +3679 9cf3 +3680 9d6c +3681 4e4f +3682 4ea1 +3683 508d +3684 5256 +3685 574a +3686 59a8 +3687 5e3d +3688..3689 5fd8 +3690 623f +3691 66b4 +3692 671b +3693 67d0 +3694 68d2 +3695 5192 +3696 7d21 +3697 80aa +3698 81a8 +3699 8b00 +3700 8c8c +3701 8cbf +3702 927e +3703 9632 +3704 5420 +3705 982c +3706 5317 +3707 50d5 +3708 535c +3709 58a8 +3710 64b2 +3711 6734 +3712 7267 +3713 7766 +3714 7a46 +3715 91e6 +3716 52c3 +3717 6ca1 +3718 6b86 +3719 5800 +3720 5e4c +3721 5954 +3722 672c +3723 7ffb +3724 51e1 +3725 76c6 +3726 6469 +3727 78e8 +3728 9b54 +3729 9ebb +3730 57cb +3731 59b9 +3732 6627 +3733 679a +3734 6bce +3735 54e9 +3736 69d9 +3737 5e55 +3738 819c +3739 6795 +3740 9baa +3741 67fe +3742 9c52 +3743 685d +3744 4ea6 +3745 4fe3 +3746 53c8 +3747 62b9 +3748 672b +3749 6cab +3750 8fc4 +3751 4fad +3752 7e6d +3753 9ebf +3754 4e07 +3755 6162 +3756 6e80 +3757 6f2b +3758 8513 +3759 5473 +3760 672a +3761 9b45 +3762 5df3 +3763 7b95 +3764 5cac +3765 5bc6 +3766 871c +3767 6e4a +3768 84d1 +3769 7a14 +3770 8108 +3771 5999 +3772 7c8d +3773 6c11 +3774 7720 +3775 52d9 +3776 5922 +3777 7121 +3778 725f +3779 77db +3780 9727 +3781 9d61 +3782 690b +3783 5a7f +3784 5a18 +3785 51a5 +3786 540d +3787 547d +3788 660e +3789 76df +3790 8ff7 +3791 9298 +3792 9cf4 +3793 59ea +3794 725d +3795 6ec5 +3796 514d +3797 68c9 +3798 7dbf +3799 7dec +3800 9762 +3801 9eba +3802 6478 +3803 6a21 +3804 8302 +3805 5984 +3806 5b5f +3807 6bdb +3808 731b +3809 76f2 +3810 7db2 +3811 8017 +3812 8499 +3813 5132 +3814 6728 +3815 9ed9 +3816 76ee +3817 6762 +3818 52ff +3819 9905 +3820 5c24 +3821 623b +3822 7c7e +3823 8cb0 +3824 554f +3825 60b6 +3826 7d0b +3827 9580 +3828 5301 +3829 4e5f +3830 51b6 +3831 591c +3832 723a +3833 8036 +3834 91ce +3835 5f25 +3836 77e2 +3837 5384 +3838 5f79 +3839 7d04 +3840 85ac +3841 8a33 +3842 8e8d +3843 9756 +3844 67f3 +3845 85ae +3846 9453 +3847 6109 +3848 6108 +3849 6cb9 +3850 7652 +3851 8aed +3852 8f38 +3853 552f +3854 4f51 +3855 512a +3856 52c7 +3857 53cb +3858 5ba5 +3859 5e7d +3860 60a0 +3861 6182 +3862 63d6 +3863 6709 +3864 67da +3865 6e67 +3866 6d8c +3867..3868 7336 +3869 7531 +3870 7950 +3871 88d5 +3872 8a98 +3873 904a +3874 9091 +3875 90f5 +3876 96c4 +3877 878d +3878 5915 +3879 4e88 +3880 4f59 +3881 4e0e +3882 8a89 +3883 8f3f +3884 9810 +3885 50ad +3886 5e7c +3887 5996 +3888 5bb9 +3889 5eb8 +3890 63da +3891 63fa +3892 64c1 +3893 66dc +3894 694a +3895 69d8 +3896 6d0b +3897 6eb6 +3898 7194 +3899 7528 +3900 7aaf +3901 7f8a +3902 8000 +3903 8449 +3904 84c9 +3905 8981 +3906 8b21 +3907 8e0a +3908 9065 +3909 967d +3910 990a +3911 617e +3912 6291 +3913 6b32 +3914 6c83 +3915 6d74 +3916 7fcc +3917 7ffc +3918 6dc0 +3919 7f85 +3920 87ba +3921 88f8 +3922 6765 +3923 83b1 +3924 983c +3925 96f7 +3926 6d1b +3927 7d61 +3928 843d +3929 916a +3930 4e71 +3931 5375 +3932 5d50 +3933 6b04 +3934 6feb +3935 85cd +3936 862d +3937 89a7 +3938 5229 +3939 540f +3940 5c65 +3941 674e +3942 68a8 +3943 7406 +3944 7483 +3945 75e2 +3946 88cf +3947 88e1 +3948 91cc +3949 96e2 +3950 9678 +3951 5f8b +3952 7387 +3953 7acb +3954 844e +3955 63a0 +3956 7565 +3957 5289 +3958 6d41 +3959 6e9c +3960 7409 +3961 7559 +3962 786b +3963 7c92 +3964 9686 +3965 7adc +3966 9f8d +3967 4fb6 +3968 616e +3969 65c5 +3970 865c +3971 4e86 +3972 4eae +3973 50da +3974 4e21 +3975 51cc +3976 5bee +3977 6599 +3978 6881 +3979 6dbc +3980 731f +3981 7642 +3982 77ad +3983 7a1c +3984 7ce7 +3985 826f +3986 8ad2 +3987 907c +3988 91cf +3989 9675 +3990 9818 +3991 529b +3992 7dd1 +3993 502b +3994 5398 +3995 6797 +3996 6dcb +3997 71d0 +3998 7433 +3999 81e8 +4000 8f2a +4001 96a3 +4002 9c57 +4003 9e9f +4004 7460 +4005 5841 +4006 6d99 +4007 7d2f +4008 985e +4009 4ee4 +4010 4f36 +4011 4f8b +4012 51b7 +4013 52b1 +4014 5dba +4015 601c +4016 73b2 +4017 793c +4018 82d3 +4019 9234 +4020 96b7 +4021 96f6 +4022 970a +4023 9e97 +4024 9f62 +4025 66a6 +4026 6b74 +4027 5217 +4028 52a3 +4029 70c8 +4030 88c2 +4031 5ec9 +4032 604b +4033 6190 +4034 6f23 +4035 7149 +4036 7c3e +4037 7df4 +4038 806f +4039 84ee +4040 9023 +4041 932c +4042 5442 +4043 9b6f +4044 6ad3 +4045 7089 +4046 8cc2 +4047 8def +4048 9732 +4049 52b4 +4050 5a41 +4051 5eca +4052 5f04 +4053 6717 +4054 697c +4055 6994 +4056 6d6a +4057 6f0f +4058 7262 +4059 72fc +4060 7bed +4061 8001 +4062 807e +4063 874b +4064 90ce +4065 516d +4066 9e93 +4067 7984 +4068 808b +4069 9332 +4070 8ad6 +4071 502d +4072 548c +4073 8a71 +4074 6b6a +4075 8cc4 +4076 8107 +4077 60d1 +4078 67a0 +4079 9df2 +4080 4e99 +4081 4e98 +4082 9c10 +4083 8a6b +4084 85c1 +4085 8568 +4086 6900 +4087 6e7e +4088 7897 +4089 8155 +4090 5f0c +4091 4e10 +4092 4e15 +4093 4e2a +4094 4e31 +4095 4e36 +4096 4e3c +4097 4e3f +4098 4e42 +4099 4e56 +4100 4e58 +4101 4e82 +4102 4e85 +4103 8c6b +4104 4e8a +4105 8212 +4106 5f0d +4107 4e8e +4108..4110 4e9e +4111 4ea2 +4112 4eb0 +4113 4eb3 +4114 4eb6 +4115 4ece +4116 4ecd +4117 4ec4 +4118 4ec6 +4119 4ec2 +4120 4ed7 +4121 4ede +4122 4eed +4123 4edf +4124 4ef7 +4125 4f09 +4126 4f5a +4127 4f30 +4128 4f5b +4129 4f5d +4130 4f57 +4131 4f47 +4132 4f76 +4133 4f88 +4134 4f8f +4135 4f98 +4136 4f7b +4137 4f69 +4138 4f70 +4139 4f91 +4140 4f6f +4141 4f86 +4142 4f96 +4143 5118 +4144 4fd4 +4145 4fdf +4146 4fce +4147 4fd8 +4148 4fdb +4149 4fd1 +4150 4fda +4151 4fd0 +4152..4153 4fe4 +4154 501a +4155 5028 +4156 5014 +4157 502a +4158 5025 +4159 5005 +4160 4f1c +4161 4ff6 +4162 5021 +4163 5029 +4164 502c +4165 4ffe +4166 4fef +4167 5011 +4168 5006 +4169 5043 +4170 5047 +4171 6703 +4172 5055 +4173 5050 +4174 5048 +4175 505a +4176 5056 +4177 506c +4178 5078 +4179 5080 +4180 509a +4181 5085 +4182 50b4 +4183 50b2 +4184..4185 50c9 +4186 50b3 +4187 50c2 +4188 50d6 +4189 50de +4190 50e5 +4191 50ed +4192 50e3 +4193 50ee +4194 50f9 +4195 50f5 +4196 5109 +4197..4198 5101 +4199 5116 +4200 5115 +4201 5114 +4202 511a +4203 5121 +4204 513a +4205 5137 +4206 513c +4207 513b +4208..4209 513f +4210 5152 +4211 514c +4212 5154 +4213 5162 +4214 7af8 +4215..4216 5169 +4217 516e +4218 5180 +4219 5182 +4220 56d8 +4221 518c +4222 5189 +4223 518f +4224 5191 +4225 5193 +4226..4227 5195 +4228 51a4 +4229 51a6 +4230 51a2 +4231..4233 51a9 +4234 51b3 +4235..4236 51b1 +4237 51b0 +4238 51b5 +4239 51bd +4240 51c5 +4241 51c9 +4242 51db +4243 51e0 +4244 8655 +4245 51e9 +4246 51ed +4247 51f0 +4248 51f5 +4249 51fe +4250 5204 +4251 520b +4252 5214 +4253 520e +4254 5227 +4255 522a +4256 522e +4257 5233 +4258 5239 +4259 524f +4260 5244 +4261..4262 524b +4263 525e +4264 5254 +4265 526a +4266 5274 +4267 5269 +4268 5273 +4269 527f +4270 527d +4271 528d +4272 5294 +4273 5292 +4274 5271 +4275 5288 +4276 5291 +4277 8fa8 +4278 8fa7 +4279..4280 52ac +4281 52bc +4282 52b5 +4283 52c1 +4284 52cd +4285 52d7 +4286 52de +4287 52e3 +4288 52e6 +4289 98ed +4290 52e0 +4291 52f3 +4292 52f5 +4293..4294 52f8 +4295 5306 +4296 5308 +4297 7538 +4298 530d +4299 5310 +4300 530f +4301 5315 +4302 531a +4303 5323 +4304 532f +4305 5331 +4306 5333 +4307 5338 +4308 5340 +4309 5346 +4310 5345 +4311 4e17 +4312 5349 +4313 534d +4314 51d6 +4315 535e +4316 5369 +4317 536e +4318 5918 +4319 537b +4320 5377 +4321 5382 +4322 5396 +4323 53a0 +4324 53a6 +4325 53a5 +4326 53ae +4327 53b0 +4328 53b6 +4329 53c3 +4330 7c12 +4331 96d9 +4332 53df +4333 66fc +4334 71ee +4335 53ee +4336 53e8 +4337 53ed +4338 53fa +4339 5401 +4340 543d +4341 5440 +4342..4343 542c +4344 543c +4345 542e +4346 5436 +4347 5429 +4348 541d +4349 544e +4350 548f +4351 5475 +4352 548e +4353 545f +4354 5471 +4355 5477 +4356 5470 +4357 5492 +4358 547b +4359 5480 +4360 5476 +4361 5484 +4362 5490 +4363 5486 +4364 54c7 +4365 54a2 +4366 54b8 +4367 54a5 +4368 54ac +4369 54c4 +4370 54c8 +4371 54a8 +4372 54ab +4373 54c2 +4374 54a4 +4375 54be +4376 54bc +4377 54d8 +4378..4379 54e5 +4380 550f +4381 5514 +4382 54fd +4383 54ee +4384 54ed +4385 54fa +4386 54e2 +4387 5539 +4388 5540 +4389 5563 +4390 554c +4391 552e +4392 555c +4393 5545 +4394..4395 5556 +4396 5538 +4397 5533 +4398 555d +4399 5599 +4400 5580 +4401 54af +4402 558a +4403 559f +4404 557b +4405 557e +4406 5598 +4407 559e +4408 55ae +4409 557c +4410 5583 +4411 55a9 +4412 5587 +4413 55a8 +4414 55da +4415 55c5 +4416 55df +4417 55c4 +4418 55dc +4419 55e4 +4420 55d4 +4421 5614 +4422 55f7 +4423 5616 +4424 55fe +4425 55fd +4426 561b +4427 55f9 +4428 564e +4429 5650 +4430 71df +4431 5634 +4432 5636 +4433 5632 +4434 5638 +4435 566b +4436 5664 +4437 562f +4438 566c +4439 566a +4440 5686 +4441 5680 +4442 568a +4443 56a0 +4444 5694 +4445 568f +4446 56a5 +4447 56ae +4448 56b6 +4449 56b4 +4450 56c2 +4451 56bc +4452 56c1 +4453 56c3 +4454 56c0 +4455 56c8 +4456 56ce +4457 56d1 +4458 56d3 +4459 56d7 +4460 56ee +4461 56f9 +4462 5700 +4463 56ff +4464 5704 +4465 5709 +4466 5708 +4467 570b +4468 570d +4469 5713 +4470 5718 +4471 5716 +4472 55c7 +4473 571c +4474 5726 +4475..4476 5737 +4477 574e +4478 573b +4479 5740 +4480 574f +4481 5769 +4482 57c0 +4483 5788 +4484 5761 +4485 577f +4486 5789 +4487 5793 +4488 57a0 +4489 57b3 +4490 57a4 +4491 57aa +4492 57b0 +4493 57c3 +4494 57c6 +4495 57d4 +4496..4497 57d2 +4498 580a +4499 57d6 +4500 57e3 +4501 580b +4502 5819 +4503 581d +4504 5872 +4505 5821 +4506 5862 +4507 584b +4508 5870 +4509 6bc0 +4510 5852 +4511 583d +4512 5879 +4513 5885 +4514 58b9 +4515 589f +4516 58ab +4517 58ba +4518 58de +4519 58bb +4520 58b8 +4521 58ae +4522 58c5 +4523 58d3 +4524 58d1 +4525 58d7 +4526 58d9 +4527 58d8 +4528 58e5 +4529 58dc +4530 58e4 +4531 58df +4532 58ef +4533 58fa +4534 58f9 +4535..4537 58fb +4538 5902 +4539 590a +4540 5910 +4541 591b +4542 68a6 +4543 5925 +4544..4545 592c +4546 5932 +4547 5938 +4548 593e +4549 7ad2 +4550 5955 +4551 5950 +4552 594e +4553 595a +4554 5958 +4555 5962 +4556 5960 +4557 5967 +4558 596c +4559 5969 +4560 5978 +4561 5981 +4562 599d +4563 4f5e +4564 4fab +4565 59a3 +4566 59b2 +4567 59c6 +4568 59e8 +4569 59dc +4570 598d +4571..4572 59d9 +4573 5a25 +4574 5a1f +4575 5a11 +4576 5a1c +4577 5a09 +4578 5a1a +4579 5a40 +4580 5a6c +4581 5a49 +4582..4583 5a35 +4584 5a62 +4585 5a6a +4586 5a9a +4587 5abc +4588 5abe +4589 5acb +4590 5ac2 +4591 5abd +4592 5ae3 +4593 5ad7 +4594 5ae6 +4595 5ae9 +4596 5ad6 +4597..4598 5afa +4599 5b0c +4600 5b0b +4601 5b16 +4602 5b32 +4603 5ad0 +4604 5b2a +4605 5b36 +4606 5b3e +4607 5b43 +4608 5b45 +4609 5b40 +4610 5b51 +4611 5b55 +4612..4613 5b5a +4614 5b65 +4615 5b69 +4616 5b70 +4617 5b73 +4618 5b75 +4619 5b78 +4620 6588 +4621 5b7a +4622 5b80 +4623 5b83 +4624 5ba6 +4625 5bb8 +4626 5bc3 +4627 5bc7 +4628 5bc9 +4629 5bd4 +4630 5bd0 +4631 5be4 +4632 5be6 +4633 5be2 +4634 5bde +4635 5be5 +4636 5beb +4637 5bf0 +4638 5bf6 +4639 5bf3 +4640 5c05 +4641..4642 5c07 +4643 5c0d +4644 5c13 +4645 5c20 +4646 5c22 +4647 5c28 +4648..4649 5c38 +4650 5c41 +4651 5c46 +4652 5c4e +4653 5c53 +4654 5c50 +4655 5c4f +4656 5b71 +4657 5c6c +4658 5c6e +4659 4e62 +4660 5c76 +4661 5c79 +4662 5c8c +4663 5c91 +4664 5c94 +4665 599b +4666 5cab +4667 5cbb +4668 5cb6 +4669 5cbc +4670 5cb7 +4671 5cc5 +4672 5cbe +4673 5cc7 +4674 5cd9 +4675 5ce9 +4676 5cfd +4677 5cfa +4678 5ced +4679 5d8c +4680 5cea +4681 5d0b +4682 5d15 +4683 5d17 +4684 5d5c +4685 5d1f +4686 5d1b +4687 5d11 +4688 5d14 +4689 5d22 +4690 5d1a +4691 5d19 +4692 5d18 +4693 5d4c +4694 5d52 +4695 5d4e +4696 5d4b +4697 5d6c +4698 5d73 +4699 5d76 +4700 5d87 +4701 5d84 +4702 5d82 +4703 5da2 +4704 5d9d +4705 5dac +4706 5dae +4707 5dbd +4708 5d90 +4709 5db7 +4710 5dbc +4711 5dc9 +4712 5dcd +4713 5dd3 +4714 5dd2 +4715 5dd6 +4716 5ddb +4717 5deb +4718 5df2 +4719 5df5 +4720 5e0b +4721 5e1a +4722 5e19 +4723 5e11 +4724 5e1b +4725..4726 5e36 +4727 5e44 +4728 5e43 +4729 5e40 +4730 5e4e +4731 5e57 +4732 5e54 +4733 5e5f +4734 5e62 +4735 5e64 +4736 5e47 +4737..4738 5e75 +4739 5e7a +4740 9ebc +4741 5e7f +4742 5ea0 +4743..4744 5ec1 +4745 5ec8 +4746 5ed0 +4747 5ecf +4748 5ed6 +4749 5ee3 +4750 5edd +4751..4752 5eda +4753 5ee2 +4754 5ee1 +4755..4756 5ee8 +4757 5eec +4758 5ef1 +4759 5ef3 +4760 5ef0 +4761 5ef4 +4762 5ef8 +4763 5efe +4764 5f03 +4765 5f09 +4766 5f5d +4767 5f5c +4768 5f0b +4769 5f11 +4770 5f16 +4771 5f29 +4772 5f2d +4773 5f38 +4774 5f41 +4775 5f48 +4776 5f4c +4777 5f4e +4778 5f2f +4779 5f51 +4780..4781 5f56 +4782 5f59 +4783 5f61 +4784 5f6d +4785 5f73 +4786 5f77 +4787 5f83 +4788 5f82 +4789 5f7f +4790 5f8a +4791 5f88 +4792 5f91 +4793 5f87 +4794 5f9e +4795 5f99 +4796 5f98 +4797 5fa0 +4798 5fa8 +4799 5fad +4800 5fbc +4801 5fd6 +4802 5ffb +4803 5fe4 +4804 5ff8 +4805 5ff1 +4806 5fdd +4807 60b3 +4808 5fff +4809 6021 +4810 6060 +4811 6019 +4812 6010 +4813 6029 +4814 600e +4815 6031 +4816 601b +4817 6015 +4818 602b +4819 6026 +4820 600f +4821 603a +4822 605a +4823 6041 +4824 606a +4825 6077 +4826 605f +4827 604a +4828 6046 +4829 604d +4830 6063 +4831 6043 +4832 6064 +4833 6042 +4834 606c +4835 606b +4836 6059 +4837 6081 +4838 608d +4839 60e7 +4840 6083 +4841 609a +4842 6084 +4843 609b +4844..4845 6096 +4846 6092 +4847 60a7 +4848 608b +4849 60e1 +4850 60b8 +4851 60e0 +4852 60d3 +4853 60b4 +4854 5ff0 +4855 60bd +4856 60c6 +4857 60b5 +4858 60d8 +4859 614d +4860 6115 +4861 6106 +4862..4863 60f6 +4864 6100 +4865 60f4 +4866 60fa +4867 6103 +4868 6121 +4869 60fb +4870 60f1 +4871..4872 610d +4873 6147 +4874 613e +4875 6128 +4876 6127 +4877 614a +4878 613f +4879 613c +4880 612c +4881 6134 +4882 613d +4883 6142 +4884 6144 +4885 6173 +4886 6177 +4887..4889 6158 +4890 616b +4891 6174 +4892 616f +4893 6165 +4894 6171 +4895 615f +4896 615d +4897 6153 +4898 6175 +4899 6199 +4900 6196 +4901 6187 +4902 61ac +4903 6194 +4904 619a +4905 618a +4906 6191 +4907 61ab +4908 61ae +4909 61cc +4910 61ca +4911 61c9 +4912 61f7 +4913 61c8 +4914 61c3 +4915 61c6 +4916 61ba +4917 61cb +4918 7f79 +4919 61cd +4920 61e6 +4921 61e3 +4922 61f6 +4923 61fa +4924 61f4 +4925 61ff +4926 61fd +4927 61fc +4928 61fe +4929 6200 +4930..4931 6208 +4932 620d +4933 620c +4934 6214 +4935 621b +4936 621e +4937 6221 +4938 622a +4939 622e +4940 6230 +4941..4942 6232 +4943 6241 +4944 624e +4945 625e +4946 6263 +4947 625b +4948 6260 +4949 6268 +4950 627c +4951 6282 +4952 6289 +4953 627e +4954..4955 6292 +4956 6296 +4957 62d4 +4958 6283 +4959 6294 +4960 62d7 +4961 62d1 +4962 62bb +4963 62cf +4964 62ff +4965 62c6 +4966 64d4 +4967 62c8 +4968 62dc +4969 62cc +4970 62ca +4971 62c2 +4972 62c7 +4973 629b +4974 62c9 +4975 630c +4976 62ee +4977 62f1 +4978 6327 +4979 6302 +4980 6308 +4981 62ef +4982 62f5 +4983 6350 +4984 633e +4985 634d +4986 641c +4987 634f +4988 6396 +4989 638e +4990 6380 +4991 63ab +4992 6376 +4993 63a3 +4994 638f +4995 6389 +4996 639f +4997 63b5 +4998 636b +4999 6369 +5000 63be +5001 63e9 +5002 63c0 +5003 63c6 +5004 63e3 +5005 63c9 +5006 63d2 +5007 63f6 +5008 63c4 +5009 6416 +5010 6434 +5011 6406 +5012 6413 +5013 6426 +5014 6436 +5015 651d +5016 6417 +5017 6428 +5018 640f +5019 6467 +5020 646f +5021 6476 +5022 644e +5023 652a +5024 6495 +5025 6493 +5026 64a5 +5027 64a9 +5028 6488 +5029 64bc +5030 64da +5031 64d2 +5032 64c5 +5033 64c7 +5034 64bb +5035 64d8 +5036 64c2 +5037 64f1 +5038 64e7 +5039 8209 +5040..5041 64e0 +5042 62ac +5043 64e3 +5044 64ef +5045 652c +5046 64f6 +5047 64f4 +5048 64f2 +5049 64fa +5050 6500 +5051 64fd +5052 6518 +5053 651c +5054 6505 +5055 6524 +5056 6523 +5057 652b +5058..5059 6534 +5060 6537 +5061 6536 +5062 6538 +5063 754b +5064 6548 +5065 6556 +5066 6555 +5067 654d +5068 6558 +5069 655e +5070 655d +5071 6572 +5072 6578 +5073..5074 6582 +5075 8b8a +5076 659b +5077 659f +5078 65ab +5079 65b7 +5080 65c3 +5081 65c6 +5082 65c1 +5083 65c4 +5084 65cc +5085 65d2 +5086 65db +5087 65d9 +5088..5089 65e0 +5090 65f1 +5091 6772 +5092 660a +5093 6603 +5094 65fb +5095 6773 +5096..5097 6635 +5098 6634 +5099 661c +5100 664f +5101 6644 +5102 6649 +5103 6641 +5104 665e +5105 665d +5106 6664 +5107..5108 6667 +5109 665f +5110 6662 +5111 6670 +5112 6683 +5113 6688 +5114 668e +5115 6689 +5116 6684 +5117 6698 +5118 669d +5119 66c1 +5120 66b9 +5121 66c9 +5122 66be +5123 66bc +5124 66c4 +5125 66b8 +5126 66d6 +5127 66da +5128 66e0 +5129 663f +5130 66e6 +5131 66e9 +5132 66f0 +5133 66f5 +5134 66f7 +5135 670f +5136 6716 +5137 671e +5138..5139 6726 +5140 9738 +5141 672e +5142 673f +5143 6736 +5144 6741 +5145 6738 +5146 6737 +5147 6746 +5148 675e +5149 6760 +5150 6759 +5151..5152 6763 +5153 6789 +5154 6770 +5155 67a9 +5156 677c +5157 676a +5158 678c +5159 678b +5160 67a6 +5161 67a1 +5162 6785 +5163 67b7 +5164 67ef +5165 67b4 +5166 67ec +5167 67b3 +5168 67e9 +5169 67b8 +5170 67e4 +5171 67de +5172 67dd +5173 67e2 +5174 67ee +5175 67b9 +5176 67ce +5177 67c6 +5178 67e7 +5179 6a9c +5180 681e +5181 6846 +5182 6829 +5183 6840 +5184 684d +5185 6832 +5186 684e +5187 68b3 +5188 682b +5189 6859 +5190 6863 +5191 6877 +5192 687f +5193 689f +5194 688f +5195 68ad +5196 6894 +5197 689d +5198 689b +5199 6883 +5200 6aae +5201 68b9 +5202 6874 +5203 68b5 +5204 68a0 +5205 68ba +5206 690f +5207 688d +5208 687e +5209 6901 +5210 68ca +5211 6908 +5212 68d8 +5213 6922 +5214 6926 +5215 68e1 +5216 690c +5217 68cd +5218 68d4 +5219 68e7 +5220 68d5 +5221 6936 +5222 6912 +5223 6904 +5224 68d7 +5225 68e3 +5226 6925 +5227 68f9 +5228 68e0 +5229 68ef +5230 6928 +5231 692a +5232 691a +5233 6923 +5234 6921 +5235 68c6 +5236 6979 +5237 6977 +5238 695c +5239 6978 +5240 696b +5241 6954 +5242 697e +5243 696e +5244 6939 +5245 6974 +5246 693d +5247 6959 +5248 6930 +5249 6961 +5250 695e +5251 695d +5252 6981 +5253 696a +5254 69b2 +5255 69ae +5256 69d0 +5257 69bf +5258 69c1 +5259 69d3 +5260 69be +5261 69ce +5262 5be8 +5263 69ca +5264 69dd +5265 69bb +5266 69c3 +5267 69a7 +5268 6a2e +5269 6991 +5270 69a0 +5271 699c +5272 6995 +5273 69b4 +5274 69de +5275 69e8 +5276 6a02 +5277 6a1b +5278 69ff +5279 6b0a +5280 69f9 +5281 69f2 +5282 69e7 +5283 6a05 +5284 69b1 +5285 6a1e +5286 69ed +5287 6a14 +5288 69eb +5289 6a0a +5290 6a12 +5291 6ac1 +5292 6a23 +5293 6a13 +5294 6a44 +5295 6a0c +5296 6a72 +5297 6a36 +5298 6a78 +5299 6a47 +5300 6a62 +5301 6a59 +5302 6a66 +5303 6a48 +5304 6a38 +5305 6a22 +5306 6a90 +5307 6a8d +5308 6aa0 +5309 6a84 +5310..5311 6aa2 +5312 6a97 +5313 8617 +5314 6abb +5315 6ac3 +5316 6ac2 +5317 6ab8 +5318 6ab3 +5319 6aac +5320 6ade +5321 6ad1 +5322 6adf +5323 6aaa +5324 6ada +5325 6aea +5326 6afb +5327 6b05 +5328 8616 +5329 6afa +5330 6b12 +5331 6b16 +5332 9b31 +5333 6b1f +5334 6b38 +5335 6b37 +5336 76dc +5337 6b39 +5338 98ee +5339 6b47 +5340 6b43 +5341 6b49 +5342 6b50 +5343 6b59 +5344 6b54 +5345 6b5b +5346 6b5f +5347 6b61 +5348..5349 6b78 +5350..5351 6b7f +5352 6b84 +5353 6b83 +5354 6b8d +5355 6b98 +5356 6b95 +5357 6b9e +5358 6ba4 +5359..5360 6baa +5361 6baf +5362 6bb2 +5363 6bb1 +5364 6bb3 +5365 6bb7 +5366 6bbc +5367 6bc6 +5368 6bcb +5369 6bd3 +5370 6bdf +5371 6bec +5372 6beb +5373 6bf3 +5374 6bef +5375 9ebe +5376 6c08 +5377..5378 6c13 +5379 6c1b +5380 6c24 +5381 6c23 +5382 6c5e +5383 6c55 +5384 6c62 +5385 6c6a +5386 6c82 +5387 6c8d +5388 6c9a +5389 6c81 +5390 6c9b +5391 6c7e +5392 6c68 +5393 6c73 +5394 6c92 +5395 6c90 +5396 6cc4 +5397 6cf1 +5398 6cd3 +5399 6cbd +5400 6cd7 +5401 6cc5 +5402 6cdd +5403 6cae +5404 6cb1 +5405 6cbe +5406 6cba +5407 6cdb +5408 6cef +5409 6cd9 +5410 6cea +5411 6d1f +5412 884d +5413 6d36 +5414 6d2b +5415 6d3d +5416 6d38 +5417 6d19 +5418 6d35 +5419 6d33 +5420 6d12 +5421 6d0c +5422 6d63 +5423 6d93 +5424 6d64 +5425 6d5a +5426 6d79 +5427 6d59 +5428 6d8e +5429 6d95 +5430 6fe4 +5431 6d85 +5432 6df9 +5433 6e15 +5434 6e0a +5435 6db5 +5436 6dc7 +5437 6de6 +5438 6db8 +5439 6dc6 +5440 6dec +5441 6dde +5442 6dcc +5443 6de8 +5444 6dd2 +5445 6dc5 +5446 6dfa +5447 6dd9 +5448 6de4 +5449 6dd5 +5450 6dea +5451 6dee +5452 6e2d +5453 6e6e +5454 6e2e +5455 6e19 +5456 6e72 +5457 6e5f +5458 6e3e +5459 6e23 +5460 6e6b +5461 6e2b +5462 6e76 +5463 6e4d +5464 6e1f +5465 6e43 +5466 6e3a +5467 6e4e +5468 6e24 +5469 6eff +5470 6e1d +5471 6e38 +5472 6e82 +5473 6eaa +5474 6e98 +5475 6ec9 +5476 6eb7 +5477 6ed3 +5478 6ebd +5479 6eaf +5480 6ec4 +5481 6eb2 +5482..5483 6ed4 +5484 6e8f +5485 6ea5 +5486 6ec2 +5487 6e9f +5488 6f41 +5489 6f11 +5490 704c +5491 6eec +5492 6ef8 +5493 6efe +5494 6f3f +5495 6ef2 +5496 6f31 +5497 6eef +5498 6f32 +5499 6ecc +5500 6f3e +5501 6f13 +5502 6ef7 +5503 6f86 +5504 6f7a +5505 6f78 +5506 6f81 +5507 6f80 +5508 6f6f +5509 6f5b +5510 6ff3 +5511 6f6d +5512 6f82 +5513 6f7c +5514 6f58 +5515 6f8e +5516 6f91 +5517 6fc2 +5518 6f66 +5519 6fb3 +5520 6fa3 +5521 6fa1 +5522 6fa4 +5523 6fb9 +5524 6fc6 +5525 6faa +5526 6fdf +5527 6fd5 +5528 6fec +5529 6fd4 +5530 6fd8 +5531 6ff1 +5532 6fee +5533 6fdb +5534 7009 +5535 700b +5536 6ffa +5537 7011 +5538 7001 +5539 700f +5540 6ffe +5541 701b +5542 701a +5543 6f74 +5544 701d +5545 7018 +5546 701f +5547 7030 +5548 703e +5549 7032 +5550 7051 +5551 7063 +5552 7099 +5553 7092 +5554 70af +5555 70f1 +5556 70ac +5557 70b8 +5558 70b3 +5559 70ae +5560 70df +5561 70cb +5562 70dd +5563 70d9 +5564 7109 +5565 70fd +5566 711c +5567 7119 +5568 7165 +5569 7155 +5570 7188 +5571 7166 +5572 7162 +5573 714c +5574 7156 +5575 716c +5576 718f +5577 71fb +5578 7184 +5579 7195 +5580 71a8 +5581 71ac +5582 71d7 +5583 71b9 +5584 71be +5585 71d2 +5586 71c9 +5587 71d4 +5588 71ce +5589 71e0 +5590 71ec +5591 71e7 +5592 71f5 +5593 71fc +5594 71f9 +5595 71ff +5596 720d +5597 7210 +5598 721b +5599 7228 +5600 722d +5601 722c +5602 7230 +5603 7232 +5604..5605 723b +5606..5607 723f +5608 7246 +5609 724b +5610 7258 +5611 7274 +5612 727e +5613 7282 +5614 7281 +5615 7287 +5616 7292 +5617 7296 +5618 72a2 +5619 72a7 +5620 72b9 +5621 72b2 +5622 72c3 +5623 72c6 +5624 72c4 +5625 72ce +5626 72d2 +5627 72e2 +5628..5629 72e0 +5630 72f9 +5631 72f7 +5632 500f +5633 7317 +5634 730a +5635 731c +5636 7316 +5637 731d +5638 7334 +5639 732f +5640 7329 +5641 7325 +5642 733e +5643..5644 734e +5645 9ed8 +5646 7357 +5647 736a +5648 7368 +5649 7370 +5650 7378 +5651 7375 +5652 737b +5653 737a +5654 73c8 +5655 73b3 +5656 73ce +5657 73bb +5658 73c0 +5659 73e5 +5660 73ee +5661 73de +5662 74a2 +5663 7405 +5664 746f +5665 7425 +5666 73f8 +5667 7432 +5668 743a +5669 7455 +5670 743f +5671 745f +5672 7459 +5673 7441 +5674 745c +5675 7469 +5676 7470 +5677 7463 +5678 746a +5679 7476 +5680 747e +5681 748b +5682 749e +5683 74a7 +5684 74ca +5685 74cf +5686 74d4 +5687 73f1 +5688 74e0 +5689 74e3 +5690 74e7 +5691 74e9 +5692 74ee +5693 74f2 +5694..5695 74f0 +5696 74f8 +5697 74f7 +5698 7504 +5699 7503 +5700 7505 +5701 750c +5702 750e +5703 750d +5704 7515 +5705 7513 +5706 751e +5707 7526 +5708 752c +5709 753c +5710 7544 +5711 754d +5712 754a +5713 7549 +5714 755b +5715 7546 +5716 755a +5717 7569 +5718 7564 +5719 7567 +5720 756b +5721 756d +5722 7578 +5723 7576 +5724..5725 7586 +5726 7574 +5727 758a +5728 7589 +5729 7582 +5730 7594 +5731 759a +5732 759d +5733 75a5 +5734 75a3 +5735 75c2 +5736 75b3 +5737 75c3 +5738 75b5 +5739 75bd +5740 75b8 +5741 75bc +5742 75b1 +5743 75cd +5744 75ca +5745 75d2 +5746 75d9 +5747 75e3 +5748 75de +5749..5750 75fe +5751 75fc +5752 7601 +5753 75f0 +5754 75fa +5755..5756 75f2 +5757 760b +5758 760d +5759 7609 +5760 761f +5761 7627 +5762..5764 7620 +5765 7624 +5766 7634 +5767 7630 +5768 763b +5769..5770 7647 +5771 7646 +5772 765c +5773 7658 +5774..5775 7661 +5776..5778 7668 +5779 7667 +5780 766c +5781 7670 +5782 7672 +5783 7676 +5784 7678 +5785 767c +5786 7680 +5787 7683 +5788 7688 +5789 768b +5790 768e +5791 7696 +5792 7693 +5793..5794 7699 +5795 76b0 +5796 76b4 +5797..5799 76b8 +5800 76c2 +5801 76cd +5802 76d6 +5803 76d2 +5804 76de +5805 76e1 +5806 76e5 +5807 76e7 +5808 76ea +5809 862f +5810 76fb +5811 7708 +5812 7707 +5813 7704 +5814 7729 +5815 7724 +5816 771e +5817..5818 7725 +5819 771b +5820..5821 7737 +5822 7747 +5823 775a +5824 7768 +5825 776b +5826 775b +5827 7765 +5828 777f +5829 777e +5830 7779 +5831 778e +5832 778b +5833 7791 +5834 77a0 +5835 779e +5836 77b0 +5837 77b6 +5838 77b9 +5839 77bf +5840..5841 77bc +5842 77bb +5843 77c7 +5844 77cd +5845 77d7 +5846 77da +5847 77dc +5848 77e3 +5849 77ee +5850 77fc +5851 780c +5852 7812 +5853 7926 +5854 7820 +5855 792a +5856 7845 +5857 788e +5858 7874 +5859 7886 +5860 787c +5861 789a +5862 788c +5863 78a3 +5864 78b5 +5865 78aa +5866 78af +5867 78d1 +5868 78c6 +5869 78cb +5870 78d4 +5871 78be +5872 78bc +5873 78c5 +5874 78ca +5875 78ec +5876 78e7 +5877 78da +5878 78fd +5879 78f4 +5880 7907 +5881 7912 +5882 7911 +5883 7919 +5884 792c +5885 792b +5886 7940 +5887 7960 +5888 7957 +5889 795f +5890 795a +5891 7955 +5892 7953 +5893 797a +5894 797f +5895 798a +5896 799d +5897 79a7 +5898 9f4b +5899 79aa +5900 79ae +5901 79b3 +5902..5903 79b9 +5904 79c9 +5905 79d5 +5906 79e7 +5907 79ec +5908 79e1 +5909 79e3 +5910 7a08 +5911 7a0d +5912..5913 7a18 +5914 7a20 +5915 7a1f +5916 7980 +5917 7a31 +5918 7a3b +5919 7a3e +5920 7a37 +5921 7a43 +5922 7a57 +5923 7a49 +5924..5925 7a61 +5926 7a69 +5927 9f9d +5928 7a70 +5929 7a79 +5930 7a7d +5931 7a88 +5932 7a97 +5933 7a95 +5934 7a98 +5935 7a96 +5936 7aa9 +5937 7ac8 +5938 7ab0 +5939 7ab6 +5940 7ac5 +5941 7ac4 +5942 7abf +5943 9083 +5944 7ac7 +5945 7aca +5946 7acd +5947 7acf +5948 7ad5 +5949 7ad3 +5950..5951 7ad9 +5952 7add +5953..5954 7ae1 +5955 7ae6 +5956 7aed +5957 7af0 +5958 7b02 +5959 7b0f +5960 7b0a +5961 7b06 +5962 7b33 +5963..5964 7b18 +5965 7b1e +5966 7b35 +5967 7b28 +5968 7b36 +5969 7b50 +5970 7b7a +5971 7b04 +5972 7b4d +5973 7b0b +5974 7b4c +5975 7b45 +5976 7b75 +5977 7b65 +5978 7b74 +5979 7b67 +5980..5981 7b70 +5982 7b6c +5983 7b6e +5984 7b9d +5985 7b98 +5986 7b9f +5987 7b8d +5988 7b9c +5989 7b9a +5990 7b8b +5991 7b92 +5992 7b8f +5993 7b5d +5994 7b99 +5995 7bcb +5996 7bc1 +5997 7bcc +5998 7bcf +5999 7bb4 +6000 7bc6 +6001 7bdd +6002 7be9 +6003 7c11 +6004 7c14 +6005 7be6 +6006 7be5 +6007 7c60 +6008 7c00 +6009 7c07 +6010 7c13 +6011 7bf3 +6012 7bf7 +6013 7c17 +6014 7c0d +6015 7bf6 +6016 7c23 +6017 7c27 +6018 7c2a +6019 7c1f +6020 7c37 +6021 7c2b +6022 7c3d +6023 7c4c +6024 7c43 +6025 7c54 +6026 7c4f +6027 7c40 +6028 7c50 +6029 7c58 +6030 7c5f +6031 7c64 +6032 7c56 +6033 7c65 +6034 7c6c +6035 7c75 +6036 7c83 +6037 7c90 +6038 7ca4 +6039 7cad +6040 7ca2 +6041 7cab +6042 7ca1 +6043 7ca8 +6044 7cb3 +6045 7cb2 +6046 7cb1 +6047 7cae +6048 7cb9 +6049 7cbd +6050 7cc0 +6051 7cc5 +6052 7cc2 +6053 7cd8 +6054 7cd2 +6055 7cdc +6056 7ce2 +6057 9b3b +6058 7cef +6059 7cf2 +6060 7cf4 +6061 7cf6 +6062 7cfa +6063 7d06 +6064 7d02 +6065 7d1c +6066 7d15 +6067 7d0a +6068 7d45 +6069 7d4b +6070 7d2e +6071 7d32 +6072 7d3f +6073 7d35 +6074 7d46 +6075 7d73 +6076 7d56 +6077 7d4e +6078 7d72 +6079 7d68 +6080 7d6e +6081 7d4f +6082 7d63 +6083 7d93 +6084 7d89 +6085 7d5b +6086 7d8f +6087 7d7d +6088 7d9b +6089 7dba +6090 7dae +6091 7da3 +6092 7db5 +6093 7dc7 +6094 7dbd +6095 7dab +6096 7e3d +6097 7da2 +6098 7daf +6099 7ddc +6100 7db8 +6101 7d9f +6102 7db0 +6103 7dd8 +6104 7ddd +6105 7de4 +6106 7dde +6107 7dfb +6108 7df2 +6109 7de1 +6110 7e05 +6111 7e0a +6112 7e23 +6113 7e21 +6114 7e12 +6115 7e31 +6116 7e1f +6117 7e09 +6118 7e0b +6119 7e22 +6120 7e46 +6121 7e66 +6122 7e3b +6123 7e35 +6124 7e39 +6125 7e43 +6126 7e37 +6127 7e32 +6128 7e3a +6129 7e67 +6130 7e5d +6131 7e56 +6132 7e5e +6133..6134 7e59 +6135 7e79 +6136 7e6a +6137 7e69 +6138 7e7c +6139 7e7b +6140 7e83 +6141 7dd5 +6142 7e7d +6143 8fae +6144 7e7f +6145..6146 7e88 +6147 7e8c +6148 7e92 +6149 7e90 +6150..6151 7e93 +6152 7e96 +6153 7e8e +6154..6155 7e9b +6156 7f38 +6157 7f3a +6158 7f45 +6159..6161 7f4c +6162..6163 7f50 +6164 7f55 +6165 7f54 +6166 7f58 +6167..6168 7f5f +6169..6170 7f68 +6171 7f67 +6172 7f78 +6173 7f82 +6174 7f86 +6175 7f83 +6176 7f88 +6177 7f87 +6178 7f8c +6179 7f94 +6180 7f9e +6181 7f9d +6182 7f9a +6183 7fa3 +6184 7faf +6185 7fb2 +6186 7fb9 +6187 7fae +6188 7fb6 +6189 7fb8 +6190 8b71 +6191..6192 7fc5 +6193 7fca +6194 7fd5 +6195 7fd4 +6196 7fe1 +6197 7fe6 +6198 7fe9 +6199 7ff3 +6200 7ff9 +6201 98dc +6202 8006 +6203 8004 +6204 800b +6205 8012 +6206..6207 8018 +6208 801c +6209 8021 +6210 8028 +6211 803f +6212 803b +6213 804a +6214 8046 +6215 8052 +6216 8058 +6217 805a +6218 805f +6219 8062 +6220 8068 +6221 8073 +6222 8072 +6223 8070 +6224 8076 +6225 8079 +6226 807d +6227 807f +6228 8084 +6229 8086 +6230 8085 +6231 809b +6232 8093 +6233 809a +6234 80ad +6235 5190 +6236 80ac +6237 80db +6238 80e5 +6239 80d9 +6240 80dd +6241 80c4 +6242 80da +6243 80d6 +6244 8109 +6245 80ef +6246 80f1 +6247 811b +6248 8129 +6249 8123 +6250 812f +6251 814b +6252 968b +6253 8146 +6254 813e +6255 8153 +6256 8151 +6257 80fc +6258 8171 +6259 816e +6260..6261 8165 +6262 8174 +6263 8183 +6264 8188 +6265 818a +6266 8180 +6267 8182 +6268 81a0 +6269 8195 +6270 81a4 +6271 81a3 +6272 815f +6273 8193 +6274 81a9 +6275 81b0 +6276 81b5 +6277 81be +6278 81b8 +6279 81bd +6280 81c0 +6281 81c2 +6282 81ba +6283 81c9 +6284 81cd +6285 81d1 +6286 81d9 +6287 81d8 +6288 81c8 +6289 81da +6290..6291 81df +6292 81e7 +6293..6294 81fa +6295 81fe +6296..6297 8201 +6298 8205 +6299 8207 +6300 820a +6301 820d +6302 8210 +6303 8216 +6304 8229 +6305 822b +6306 8238 +6307 8233 +6308 8240 +6309 8259 +6310 8258 +6311 825d +6312 825a +6313 825f +6314 8264 +6315 8262 +6316 8268 +6317..6318 826a +6319 822e +6320 8271 +6321..6322 8277 +6323 827e +6324 828d +6325 8292 +6326 82ab +6327 829f +6328 82bb +6329 82ac +6330 82e1 +6331 82e3 +6332 82df +6333 82d2 +6334 82f4 +6335 82f3 +6336 82fa +6337 8393 +6338 8303 +6339 82fb +6340 82f9 +6341 82de +6342 8306 +6343 82dc +6344 8309 +6345 82d9 +6346 8335 +6347 8334 +6348 8316 +6349 8332 +6350 8331 +6351 8340 +6352 8339 +6353 8350 +6354 8345 +6355 832f +6356 832b +6357..6358 8317 +6359 8385 +6360 839a +6361 83aa +6362 839f +6363 83a2 +6364 8396 +6365 8323 +6366 838e +6367 8387 +6368 838a +6369 837c +6370 83b5 +6371 8373 +6372 8375 +6373 83a0 +6374 8389 +6375 83a8 +6376 83f4 +6377 8413 +6378 83eb +6379 83ce +6380 83fd +6381 8403 +6382 83d8 +6383 840b +6384 83c1 +6385 83f7 +6386 8407 +6387 83e0 +6388 83f2 +6389 840d +6390 8422 +6391 8420 +6392 83bd +6393 8438 +6394 8506 +6395 83fb +6396 846d +6397 842a +6398 843c +6399 855a +6400 8484 +6401 8477 +6402 846b +6403 84ad +6404 846e +6405 8482 +6406 8469 +6407 8446 +6408 842c +6409 846f +6410 8479 +6411 8435 +6412 84ca +6413 8462 +6414 84b9 +6415 84bf +6416 849f +6417 84d9 +6418 84cd +6419 84bb +6420 84da +6421 84d0 +6422 84c1 +6423 84c6 +6424 84d6 +6425 84a1 +6426 8521 +6427 84ff +6428 84f4 +6429..6430 8517 +6431 852c +6432 851f +6433 8515 +6434 8514 +6435 84fc +6436 8540 +6437 8563 +6438 8558 +6439 8548 +6440 8541 +6441 8602 +6442 854b +6443 8555 +6444 8580 +6445 85a4 +6446 8588 +6447 8591 +6448 858a +6449 85a8 +6450 856d +6451 8594 +6452 859b +6453 85ea +6454 8587 +6455 859c +6456 8577 +6457 857e +6458 8590 +6459 85c9 +6460 85ba +6461 85cf +6462 85b9 +6463 85d0 +6464 85d5 +6465 85dd +6466 85e5 +6467 85dc +6468 85f9 +6469 860a +6470 8613 +6471 860b +6472 85fe +6473 85fa +6474 8606 +6475 8622 +6476 861a +6477 8630 +6478 863f +6479 864d +6480 4e55 +6481 8654 +6482 865f +6483 8667 +6484 8671 +6485 8693 +6486 86a3 +6487..6488 86a9 +6489..6490 868b +6491 86b6 +6492 86af +6493 86c4 +6494 86c6 +6495 86b0 +6496 86c9 +6497 8823 +6498 86ab +6499 86d4 +6500 86de +6501 86e9 +6502 86ec +6503 86df +6504 86db +6505 86ef +6506 8712 +6507 8706 +6508 8708 +6509 8700 +6510 8703 +6511 86fb +6512 8711 +6513 8709 +6514 870d +6515 86f9 +6516 870a +6517 8734 +6518 873f +6519 8737 +6520 873b +6521 8725 +6522 8729 +6523 871a +6524 8760 +6525 875f +6526 8778 +6527 874c +6528 874e +6529 8774 +6530 8757 +6531 8768 +6532 876e +6533 8759 +6534 8753 +6535 8763 +6536 876a +6537 8805 +6538 87a2 +6539 879f +6540 8782 +6541 87af +6542 87cb +6543 87bd +6544 87c0 +6545 87d0 +6546 96d6 +6547 87ab +6548 87c4 +6549 87b3 +6550 87c7 +6551 87c6 +6552 87bb +6553 87ef +6554 87f2 +6555 87e0 +6556 880f +6557 880d +6558 87fe +6559..6560 87f6 +6561 880e +6562 87d2 +6563 8811 +6564 8816 +6565 8815 +6566 8822 +6567 8821 +6568 8831 +6569 8836 +6570 8839 +6571 8827 +6572 883b +6573 8844 +6574 8842 +6575 8852 +6576 8859 +6577 885e +6578 8862 +6579 886b +6580 8881 +6581 887e +6582 889e +6583 8875 +6584 887d +6585 88b5 +6586 8872 +6587 8882 +6588 8897 +6589 8892 +6590 88ae +6591 8899 +6592 88a2 +6593 888d +6594 88a4 +6595 88b0 +6596 88bf +6597 88b1 +6598..6599 88c3 +6600 88d4 +6601..6602 88d8 +6603 88dd +6604 88f9 +6605 8902 +6606 88fc +6607 88f4 +6608 88e8 +6609 88f2 +6610 8904 +6611 890c +6612 890a +6613 8913 +6614 8943 +6615 891e +6616 8925 +6617..6618 892a +6619 8941 +6620 8944 +6621 893b +6622 8936 +6623 8938 +6624 894c +6625 891d +6626 8960 +6627 895e +6628 8966 +6629 8964 +6630 896d +6631 896a +6632 896f +6633 8974 +6634 8977 +6635 897e +6636 8983 +6637 8988 +6638 898a +6639 8993 +6640 8998 +6641 89a1 +6642 89a9 +6643 89a6 +6644 89ac +6645 89af +6646 89b2 +6647 89ba +6648 89bd +6649..6650 89bf +6651 89da +6652..6653 89dc +6654 89e7 +6655 89f4 +6656 89f8 +6657 8a03 +6658 8a16 +6659 8a10 +6660 8a0c +6661 8a1b +6662 8a1d +6663 8a25 +6664 8a36 +6665 8a41 +6666 8a5b +6667 8a52 +6668 8a46 +6669 8a48 +6670 8a7c +6671 8a6d +6672 8a6c +6673 8a62 +6674 8a85 +6675 8a82 +6676 8a84 +6677 8aa8 +6678 8aa1 +6679 8a91 +6680..6681 8aa5 +6682 8a9a +6683 8aa3 +6684 8ac4 +6685 8acd +6686 8ac2 +6687 8ada +6688 8aeb +6689 8af3 +6690 8ae7 +6691 8ae4 +6692 8af1 +6693 8b14 +6694 8ae0 +6695 8ae2 +6696 8af7 +6697 8ade +6698 8adb +6699 8b0c +6700 8b07 +6701 8b1a +6702 8ae1 +6703 8b16 +6704 8b10 +6705 8b17 +6706 8b20 +6707 8b33 +6708 97ab +6709 8b26 +6710 8b2b +6711 8b3e +6712 8b28 +6713 8b41 +6714 8b4c +6715 8b4f +6716 8b4e +6717 8b49 +6718 8b56 +6719 8b5b +6720 8b5a +6721 8b6b +6722 8b5f +6723 8b6c +6724 8b6f +6725 8b74 +6726 8b7d +6727 8b80 +6728 8b8c +6729 8b8e +6730..6731 8b92 +6732 8b96 +6733..6734 8b99 +6735 8c3a +6736 8c41 +6737 8c3f +6738 8c48 +6739 8c4c +6740 8c4e +6741 8c50 +6742 8c55 +6743 8c62 +6744 8c6c +6745 8c78 +6746 8c7a +6747 8c82 +6748 8c89 +6749 8c85 +6750 8c8a +6751..6752 8c8d +6753 8c94 +6754 8c7c +6755 8c98 +6756 621d +6757 8cad +6758 8caa +6759 8cbd +6760..6761 8cb2 +6762 8cae +6763 8cb6 +6764 8cc8 +6765 8cc1 +6766 8ce4 +6767 8ce3 +6768 8cda +6769 8cfd +6770..6771 8cfa +6772..6773 8d04 +6774 8d0a +6775 8d07 +6776 8d0f +6777 8d0d +6778 8d10 +6779 9f4e +6780 8d13 +6781 8ccd +6782 8d14 +6783 8d16 +6784 8d67 +6785 8d6d +6786 8d71 +6787 8d73 +6788 8d81 +6789 8d99 +6790 8dc2 +6791 8dbe +6792 8dba +6793 8dcf +6794 8dda +6795 8dd6 +6796 8dcc +6797 8ddb +6798 8dcb +6799..6800 8dea +6801 8ddf +6802 8de3 +6803 8dfc +6804..6805 8e08 +6806 8dff +6807..6808 8e1d +6809 8e10 +6810 8e1f +6811 8e42 +6812 8e35 +6813 8e30 +6814 8e34 +6815 8e4a +6816 8e47 +6817 8e49 +6818 8e4c +6819 8e50 +6820 8e48 +6821 8e59 +6822 8e64 +6823 8e60 +6824 8e2a +6825 8e63 +6826 8e55 +6827 8e76 +6828 8e72 +6829 8e7c +6830 8e81 +6831 8e87 +6832 8e85 +6833 8e84 +6834 8e8b +6835 8e8a +6836 8e93 +6837 8e91 +6838 8e94 +6839 8e99 +6840 8eaa +6841 8ea1 +6842 8eac +6843 8eb0 +6844 8ec6 +6845 8eb1 +6846 8ebe +6847 8ec5 +6848 8ec8 +6849 8ecb +6850 8edb +6851 8ee3 +6852 8efc +6853 8efb +6854 8eeb +6855 8efe +6856 8f0a +6857 8f05 +6858 8f15 +6859 8f12 +6860 8f19 +6861 8f13 +6862 8f1c +6863 8f1f +6864 8f1b +6865 8f0c +6866 8f26 +6867 8f33 +6868 8f3b +6869 8f39 +6870 8f45 +6871 8f42 +6872 8f3e +6873 8f4c +6874 8f49 +6875 8f46 +6876 8f4e +6877 8f57 +6878 8f5c +6879..6881 8f62 +6882 8f9c +6883 8f9f +6884 8fa3 +6885 8fad +6886 8faf +6887 8fb7 +6888 8fda +6889 8fe5 +6890 8fe2 +6891 8fea +6892 8fef +6893 9087 +6894 8ff4 +6895 9005 +6896..6897 8ff9 +6898 9011 +6899 9015 +6900 9021 +6901 900d +6902 901e +6903 9016 +6904 900b +6905 9027 +6906 9036 +6907 9035 +6908 9039 +6909 8ff8 +6910..6913 904f +6914 900e +6915 9049 +6916 903e +6917 9056 +6918 9058 +6919 905e +6920 9068 +6921 906f +6922 9076 +6923 96a8 +6924 9072 +6925 9082 +6926 907d +6927 9081 +6928 9080 +6929 908a +6930 9089 +6931 908f +6932 90a8 +6933 90af +6934 90b1 +6935 90b5 +6936 90e2 +6937 90e4 +6938 6248 +6939 90db +6940 9102 +6941 9112 +6942 9119 +6943 9132 +6944 9130 +6945 914a +6946 9156 +6947 9158 +6948 9163 +6949 9165 +6950 9169 +6951 9173 +6952 9172 +6953 918b +6954 9189 +6955 9182 +6956 91a2 +6957 91ab +6958 91af +6959 91aa +6960 91b5 +6961 91b4 +6962 91ba +6963..6964 91c0 +6965 91c9 +6966 91cb +6967 91d0 +6968 91d6 +6969 91df +6970 91e1 +6971 91db +6972 91fc +6973..6974 91f5 +6975 921e +6976 91ff +6977 9214 +6978 922c +6979 9215 +6980 9211 +6981 925e +6982 9257 +6983 9245 +6984 9249 +6985 9264 +6986 9248 +6987 9295 +6988 923f +6989 924b +6990 9250 +6991 929c +6992 9296 +6993 9293 +6994 929b +6995 925a +6996 92cf +6997 92b9 +6998 92b7 +6999 92e9 +7000 930f +7001 92fa +7002 9344 +7003 932e +7004 9319 +7005 9322 +7006 931a +7007 9323 +7008 933a +7009 9335 +7010 933b +7011 935c +7012 9360 +7013 937c +7014 936e +7015 9356 +7016 93b0 +7017..7018 93ac +7019 9394 +7020 93b9 +7021..7022 93d6 +7023 93e8 +7024 93e5 +7025 93d8 +7026 93c3 +7027 93dd +7028 93d0 +7029 93c8 +7030 93e4 +7031 941a +7032 9414 +7033 9413 +7034 9403 +7035 9407 +7036 9410 +7037 9436 +7038 942b +7039 9435 +7040 9421 +7041 943a +7042 9441 +7043 9452 +7044 9444 +7045 945b +7046 9460 +7047 9462 +7048 945e +7049 946a +7050 9229 +7051 9470 +7052 9475 +7053 9477 +7054 947d +7055 945a +7056 947c +7057 947e +7058 9481 +7059 947f +7060 9582 +7061 9587 +7062 958a +7063 9594 +7064 9596 +7065..7066 9598 +7067 95a0 +7068 95a8 +7069 95a7 +7070 95ad +7071 95bc +7072 95bb +7073 95b9 +7074 95be +7075 95ca +7076 6ff6 +7077 95c3 +7078 95cd +7079 95cc +7080 95d5 +7081 95d4 +7082 95d6 +7083 95dc +7084 95e1 +7085 95e5 +7086 95e2 +7087 9621 +7088 9628 +7089..7090 962e +7091 9642 +7092 964c +7093 964f +7094 964b +7095 9677 +7096 965c +7097 965e +7098 965d +7099 965f +7100 9666 +7101 9672 +7102 966c +7103 968d +7104 9698 +7105 9695 +7106 9697 +7107 96aa +7108 96a7 +7109..7110 96b1 +7111 96b0 +7112 96b4 +7113 96b6 +7114..7115 96b8 +7116 96ce +7117 96cb +7118 96c9 +7119 96cd +7120 894d +7121 96dc +7122 970d +7123 96d5 +7124 96f9 +7125 9704 +7126 9706 +7127 9708 +7128 9713 +7129 970e +7130 9711 +7131 970f +7132 9716 +7133 9719 +7134 9724 +7135 972a +7136 9730 +7137 9739 +7138..7139 973d +7140 9744 +7141 9746 +7142 9748 +7143 9742 +7144 9749 +7145 975c +7146 9760 +7147 9764 +7148 9766 +7149 9768 +7150 52d2 +7151 976b +7152 9771 +7153 9779 +7154 9785 +7155 977c +7156 9781 +7157 977a +7158 9786 +7159 978b +7160..7161 978f +7162 979c +7163 97a8 +7164 97a6 +7165 97a3 +7166..7167 97b3 +7168 97c3 +7169 97c6 +7170 97c8 +7171 97cb +7172 97dc +7173 97ed +7174 9f4f +7175 97f2 +7176 7adf +7177 97f6 +7178 97f5 +7179 980f +7180 980c +7181 9838 +7182 9824 +7183 9821 +7184 9837 +7185 983d +7186 9846 +7187 984f +7188 984b +7189 986b +7190..7192 986f +7193 9874 +7194 9873 +7195 98aa +7196 98af +7197 98b1 +7198 98b6 +7199 98c4 +7200 98c3 +7201 98c6 +7202 98e9 +7203 98eb +7204 9903 +7205 9909 +7206 9912 +7207 9914 +7208 9918 +7209 9921 +7210..7211 991d +7212 9924 +7213 9920 +7214 992c +7215 992e +7216..7217 993d +7218 9942 +7219 9949 +7220 9945 +7221 9950 +7222 994b +7223..7224 9951 +7225 994c +7226 9955 +7227..7228 9997 +7229 99a5 +7230..7231 99ad +7232 99bc +7233 99df +7234 99db +7235 99dd +7236 99d8 +7237 99d1 +7238..7239 99ed +7240..7241 99f1 +7242 99fb +7243 99f8 +7244 9a01 +7245 9a0f +7246 9a05 +7247 99e2 +7248 9a19 +7249 9a2b +7250 9a37 +7251 9a45 +7252 9a42 +7253 9a40 +7254 9a43 +7255 9a3e +7256 9a55 +7257 9a4d +7258 9a5b +7259 9a57 +7260 9a5f +7261 9a62 +7262 9a65 +7263 9a64 +7264 9a69 +7265 9a6b +7266 9a6a +7267 9aad +7268 9ab0 +7269 9abc +7270 9ac0 +7271 9acf +7272 9ad1 +7273..7274 9ad3 +7275..7276 9ade +7277..7278 9ae2 +7279 9ae6 +7280 9aef +7281 9aeb +7282 9aee +7283 9af4 +7284 9af1 +7285 9af7 +7286 9afb +7287 9b06 +7288 9b18 +7289 9b1a +7290 9b1f +7291..7292 9b22 +7293 9b25 +7294..7297 9b27 +7298..7299 9b2e +7300 9b32 +7301 9b44 +7302 9b43 +7303 9b4f +7304..7305 9b4d +7306 9b51 +7307 9b58 +7308 9b74 +7309 9b93 +7310 9b83 +7311 9b91 +7312..7313 9b96 +7314..7315 9b9f +7316 9ba8 +7317 9bb4 +7318 9bc0 +7319 9bca +7320 9bb9 +7321 9bc6 +7322 9bcf +7323..7324 9bd1 +7325 9be3 +7326 9be2 +7327 9be4 +7328 9bd4 +7329 9be1 +7330 9c3a +7331 9bf2 +7332 9bf1 +7333 9bf0 +7334 9c15 +7335 9c14 +7336 9c09 +7337 9c13 +7338 9c0c +7339 9c06 +7340 9c08 +7341 9c12 +7342 9c0a +7343 9c04 +7344 9c2e +7345 9c1b +7346 9c25 +7347 9c24 +7348 9c21 +7349 9c30 +7350 9c47 +7351 9c32 +7352 9c46 +7353 9c3e +7354 9c5a +7355 9c60 +7356 9c67 +7357 9c76 +7358 9c78 +7359 9ce7 +7360 9cec +7361 9cf0 +7362 9d09 +7363 9d08 +7364 9ceb +7365 9d03 +7366 9d06 +7367 9d2a +7368 9d26 +7369 9daf +7370 9d23 +7371 9d1f +7372 9d44 +7373 9d15 +7374 9d12 +7375 9d41 +7376 9d3f +7377 9d3e +7378 9d46 +7379 9d48 +7380..7381 9d5d +7382 9d64 +7383 9d51 +7384 9d50 +7385 9d59 +7386 9d72 +7387 9d89 +7388 9d87 +7389 9dab +7390 9d6f +7391 9d7a +7392 9d9a +7393 9da4 +7394 9da9 +7395 9db2 +7396 9dc4 +7397 9dc1 +7398 9dbb +7399 9db8 +7400 9dba +7401 9dc6 +7402 9dcf +7403 9dc2 +7404 9dd9 +7405 9dd3 +7406 9df8 +7407 9de6 +7408 9ded +7409 9def +7410 9dfd +7411..7412 9e1a +7413 9e1e +7414 9e75 +7415 9e79 +7416 9e7d +7417 9e81 +7418 9e88 +7419..7420 9e8b +7421 9e92 +7422 9e95 +7423 9e91 +7424 9e9d +7425 9ea5 +7426 9ea9 +7427 9eb8 +7428 9eaa +7429 9ead +7430 9761 +7431 9ecc +7432..7434 9ece +7435 9ed4 +7436 9edc +7437 9ede +7438 9edd +7439 9ee0 +7440 9ee5 +7441 9ee8 +7442 9eef +7443 9ef4 +7444..7445 9ef6 +7446 9ef9 +7447..7449 9efb +7450..7451 9f07 +7452 76b7 +7453 9f15 +7454 9f21 +7455 9f2c +7456 9f3e +7457 9f4a +7458 9f52 +7459 9f54 +7460 9f63 +7461..7463 9f5f +7464..7465 9f66 +7466 9f6c +7467 9f6a +7468 9f77 +7469 9f72 +7470 9f76 +7471 9f95 +7472 9f9c +7473 9fa0 +7474 582f +7475 69c7 +7476 9059 +7477 7464 +7479..7554 2500 +7555..7574 2460 +7575..7584 2160 +7585 3349 +7586 3314 +7588 334d +7590 3327 +7592 3336 +7593 3351 +7595 330d +7596 3326 +7598 332b +7599 334a +7601..7603 339c +7604..7605 338e +7606 33c4 +7607 33a1 +7608 301d +7609 301f +7610 2116 +7611 33cd +7613..7617 32a4 +7618..7619 3231 +7620 3239 +7621 337e +7622 337d +7623 337c +7624 222e +7625 2211 +7629 221f +7630 22bf +7633 555e +7641 28cdd +7644 7130 +7646 9dd7 +7651 fa36 +7654 5699 +7655 3d4e +7660 4fe0 +7663 8ec0 +7665 2f8ed +7670 25874 +7671 7e6b +7672 8346 +7673 28ef6 +7677 9e7c +7680 663b +7682 9eb4 +7687 6805 +7693 5c62 +7695 2f8dc +7697 7e61 +7700 fa46 +7706 8523 +7707 91ac +7715 87ec +7724 6414 +7725 7626 +7727 9a52 +7732 fa4a +7734 2f884 +7739 7c1e +7746 fa10 +7747 6451 +7750 f9ec +7751 5861 +7752 985a +7754 2f877 +7758 79b1 +7760 7006 +7770 56ca +7774 525d +7776 6f51 +7777 91b1 +7788 fa6a +7795 9830 +7797 9eb5 +7807 840a +7808 f9c3 +7809..7810 f992 +7811 f999 +7813 881f +7814 2f80f +7816 2f8d3 +7817 2f818 +7825 21a1a +7826 5c5b +7831 6522 +7834 67fa +7836 688e +7838 243d0 +7839 2f920 +7861 853e +7877 7762 +7887 /uni3001.vert +7888 /uni3002.vert +7889 /uniFFE3.vert +7890 /uniFE33.vert +7891 /uni30FC.vert +7892 /uniFE31.vert +7893 /uniFE32.vert +7894 /cid-665.vert +7895 /cid-666.vert +7896 /cid-667.vert +7897 /cid-668.vert +7898 /cid-669.vert +7899 /cid-674.vert +7900 /cid-675.vert +7901 /cid-676.vert +7902 /cid-677.vert +7903 /cid-678.vert +7904 /cid-679.vert +7905 /cid-680.vert +7906 /cid-681.vert +7907 /cid-682.vert +7908 /cid-683.vert +7909 /cid-684.vert +7910 /cid-685.vert +7911 /cid-686.vert +7912 /cid-687.vert +7913 /cid-688.vert +7914 /cid-689.vert +7915 /cid-690.vert +7916 /cid-691.vert +7917 /cid-697.vert +7918 /cid-842.vert +7919 /cid-844.vert +7920 /cid-846.vert +7921 /cid-848.vert +7922 /cid-850.vert +7923 /cid-876.vert +7924 /cid-908.vert +7925 /cid-910.vert +7926 /cid-912.vert +7927 /cid-919.vert +7928 /cid-925.vert +7929 /cid-927.vert +7930 /cid-929.vert +7931 /cid-931.vert +7932 /cid-933.vert +7933 /cid-959.vert +7934 /cid-991.vert +7935 /cid-993.vert +7936 /cid-995.vert +7937 /cid-1002.vert +7938 /cid-1009.vert +7939 /cid-1010.vert +7940 /cid-7585.vert +7941 /cid-7586.vert +7943 /cid-7588.vert +7945 /cid-7590.vert +7947 /cid-7592.vert +7948 /cid-7593.vert +7950 /cid-7595.vert +7951 /cid-7596.vert +7953 /cid-7598.vert +7954 /cid-7599.vert +7956 /cid-7608.vert +7957 /cid-7609.vert +7958..7960 3094 +7963 5653 +8005 ffe4 +8006 ff07 +8007 ff02 +8009 25c1 +8010 25b7 +8011 21e9 +8012 21e7 +8013 21e6 +8014 21e8 +8015 25a2 +8016 2667 +8017 2661 +8018 2664 +8019 2662 +8020 33a0 +8021 33a2 +8022..8023 33a4 +8024 3397 +8025 2113 +8026 3398 +8027 33b3 +8028 33b2 +8029 33b1 +8030 33b0 +8031..8033 3385 +8034 33cb +8035 3390 +8036 33d4 +8037 3396 +8038 3322 +8039 3316 +8040 3318 +8041 3315 +8042 3303 +8043 3323 +8044 3357 +8045 3342 +8046 3339 +8047 333b +8048 3300 +8049 3331 +8050 3347 +8051 331e +8052 332a +8054 337f +8055 2121 +8056 260e +8057 3036 +8058 3020 +8062..8070 2488 +8071..8090 2474 +8091 3251 +8092..8101 2170 +8102..8111 3252 +8112..8137 249c +8138 3243 +8139 323d +8140 323f +8141 3234 +8142 3238 +8143 3233 +8144 323c +8145 3242 +8146 323e +8147 3236 +8148 3235 +8149 323b +8150 3240 +8151 323a +8152 32b0 +8153 32ad +8154 32a9 +8155 32af +8156 3294 +8157 32aa +8158 3298 +8159 32ab +8160 3292 +8161 3291 +8162 3293 +8163 32ac +8164 32ae +8165 3296 +8166 /cid-8180.vert +8167 /cid-8179.vert +8168 /cid-8178.vert +8170 /cid-8176.vert +8171 /cid-8175.vert +8172 /cid-8174.vert +8174..8176 23ab +8178..8180 23a7 +8182 33cc +8183 3305 +8186 339f +8187 33a3 +8188 33a6 +8191 329e +8192..8193 3388 +8194 33c8 +8195 222d +8197 3230 +8198..8203 322a +8204 3237 +8205 3241 +8206 27a1 +8209 /cid-8206.vert +8210 25c9 +8211 2660 +8212 2665 +8213 2663 +8214 2666 +8215..8218 2600 +8219 261e +8220..8221 261c +8222 261f +8223 3299 +8224 24ea +8225..8226 216a +8230..8237 2581 +8238 258f +8239 258e +8240 258d +8241 258c +8242 258b +8243 258a +8244 2589 +8245..8246 2594 +8247..8248 256d +8249 2570 +8250 256f +8251 2550 +8252 255e +8253 256a +8254 2561 +8255..8256 25e2 +8257 25e5 +8258 25e4 +8261..8263 2571 +8264 /cid-7959.vert +8265 /cid-7960.vert +8268 /cid-636.vert +8269 /cid-707.vert +8270 /cid-740.vert +8271 /cid-644.vert +8272 /cid-643.vert +8273 /cid-708.vert +8274 /cid-637.vert +8279 /cid-108.vert +8280 /cid-122.vert +8281 /cid-670.vert +8282 /cid-671.vert +8283 /cid-709.vert +8284 51dc +8285 7199 +8286..8294 2776 +8298..8299 217a +8303 217f +8304 210a +8305 2109 +8308 3004 +8309 21c6 +8310..8311 21c4 +8312 /cid-8309.vert +8313..8316 30f7 +8319 329d +8323 337b +8324 /cid-8054.vert +8327 3333 +8328 334e +8329 /cid-8038.vert +8330 /cid-8039.vert +8333 /cid-8183.vert +8334 /cid-8327.vert +8337 /cid-8328.vert +8338 /cid-8042.vert +8339 /cid-8040.vert +8340 /cid-8041.vert +8343 /cid-8046.vert +8344 /cid-8044.vert +8347 /cid-8045.vert +8348 /cid-8043.vert +8349 /cid-8047.vert +8350 /cid-8048.vert +8353 /cid-8051.vert +8356 /cid-8052.vert +8357 /cid-8050.vert +8358 /cid-8049.vert +8359 7e8a +8360 891c +8361 9348 +8362 9288 +8363 84dc +8364 4fc9 +8365 70bb +8366 6631 +8367 68c8 +8368 92f9 +8369 66fb +8370 5f45 +8371 4e28 +8372 4ee1 +8373 4efc +8374 4f00 +8375 4f03 +8376 4f39 +8377 4f56 +8378 4f92 +8379 4f8a +8380 4f9a +8381 4f94 +8382 4fcd +8383 5040 +8384 5022 +8385 4fff +8386 501e +8387 5046 +8388 5070 +8389 5042 +8390 5094 +8391 50f4 +8392 50d8 +8393 514a +8394 5164 +8395 519d +8396 51be +8397 51ec +8398 5215 +8399 529c +8400 52a6 +8401 52c0 +8402 52db +8403 5300 +8404 5307 +8405 5324 +8406 5372 +8407 5393 +8408 53b2 +8409 53dd +8410 fa0e +8411 549c +8412 548a +8413 54a9 +8414 54ff +8415 5586 +8416 5759 +8417 5765 +8418 57ac +8419 57c8 +8420 57c7 +8421 fa0f +8422 /uniFA10.dup2 +8423 589e +8424 58b2 +8425 590b +8426 5953 +8427 595b +8428 595d +8429 5963 +8430 59a4 +8431 59ba +8432 5b56 +8433 5bc0 +8434 752f +8435 5bd8 +8436 5bec +8437 5c1e +8438 5ca6 +8439 5cba +8440 5cf5 +8441 5d27 +8442 5d53 +8443 fa11 +8444 5d42 +8445 5d6d +8446..8447 5db8 +8448 5dd0 +8449 5f21 +8450 5f34 +8451 5f67 +8452 5fb7 +8453 5fde +8454 605d +8455 6085 +8456 608a +8457 60de +8458 60d5 +8459 6120 +8460 60f2 +8461 6111 +8462 6137 +8463 6130 +8464 6198 +8465 6213 +8466 62a6 +8467 63f5 +8468 6460 +8469 649d +8470 64ce +8471 654e +8472 6600 +8473 6615 +8474 6609 +8475 662e +8476 661e +8477 6624 +8478 6665 +8479 6657 +8480 6659 +8481 fa12 +8482 6673 +8483 6699 +8484 66a0 +8485 66b2 +8486 66bf +8487 66fa +8488 670e +8489 f929 +8490 6766 +8491 67bb +8492 6852 +8493 67c0 +8494 6801 +8495 6844 +8496 68cf +8497 fa13 +8498 6968 +8499 fa14 +8500 6998 +8501 69e2 +8502 6a30 +8503 6a6b +8504 6a46 +8505 6a73 +8506 6a7e +8507 6ae2 +8508 6ae4 +8509 6bd6 +8510 6c3f +8511 6c5c +8512 6c86 +8513 6c6f +8514 6cda +8515 6d04 +8516 6d87 +8517 6d6f +8518 6d96 +8519 6dac +8520 6dcf +8521 6df8 +8522 6df2 +8523 6dfc +8524 6e39 +8525 6e5c +8526 6e27 +8527 6e3c +8528 6ebf +8529 6f88 +8530 6fb5 +8531 6ff5 +8532 7005 +8533 7007 +8534 7028 +8535 7085 +8536 70ab +8537 710f +8538 7104 +8539 715c +8540..8541 7146 +8542 fa15 +8543 71c1 +8544 71fe +8545 72b1 +8546 72be +8547 7324 +8548 fa16 +8549 7377 +8550 73bd +8551 73c9 +8552 73d6 +8553 73e3 +8554 73d2 +8555 7407 +8556 73f5 +8557 7426 +8558 742a +8559 7429 +8560 742e +8561 7462 +8562 7489 +8563 749f +8564 7501 +8565 756f +8566 7682 +8567 769c +8568 769e +8569 769b +8570 76a6 +8571 fa17 +8572 7746 +8573 52af +8574 7821 +8575 784e +8576 7864 +8577 787a +8578 7930 +8579..8581 fa18 +8582 7994 +8583 fa1b +8584 799b +8585 7ad1 +8586 7ae7 +8587 fa1c +8588 7aeb +8589 7b9e +8590 fa1d +8591 7d48 +8592 7d5c +8593 7db7 +8594 7da0 +8595 7dd6 +8596 7e52 +8597 7f47 +8598 7fa1 +8599 fa1e +8600 8301 +8601 8362 +8602 837f +8603 83c7 +8604 83f6 +8605 8448 +8606 84b4 +8607 8553 +8608 8559 +8609 856b +8610 fa1f +8611 85b0 +8612..8613 fa20 +8614 8807 +8615 88f5 +8616 8a12 +8617 8a37 +8618 8a79 +8619 8aa7 +8620 8abe +8621 8adf +8622 fa22 +8623 8af6 +8624 8b53 +8625 8b7f +8626 8cf0 +8627 8cf4 +8628 8d12 +8629 8d76 +8630 fa23 +8631 8ecf +8632..8633 fa24 +8634 9067 +8635 90de +8636 fa26 +8637 9115 +8638 9127 +8639 91da +8640 91d7 +8641 91de +8642..8643 91ed +8644..8645 91e4 +8646 9206 +8647 9210 +8648 920a +8649 923a +8650 9240 +8651 923c +8652 924e +8653 9259 +8654 9251 +8655 9239 +8656 9267 +8657 92a7 +8658..8659 9277 +8660 92e7 +8661 92d7 +8662 92d9 +8663 92d0 +8664 fa27 +8665 92d5 +8666 92e0 +8667 92d3 +8668 9325 +8669 9321 +8670 92fb +8671 fa28 +8672 931e +8673 92ff +8674 931d +8675 9302 +8676 9370 +8677 9357 +8678 93a4 +8679 93c6 +8680 93de +8681 93f8 +8682 9431 +8683 9445 +8684 9448 +8685 9592 +8686 f9dc +8687 fa29 +8688 969d +8689 96af +8690 9733 +8691 973b +8692 9743 +8693 974d +8694 974f +8695 9751 +8696 9755 +8697 9857 +8698 9865 +8699..8700 fa2a +8701 9927 +8702 fa2c +8703 999e +8704 9a4e +8705 9ad9 +8706 9adc +8707 9b75 +8708 9b72 +8709 9b8f +8710 9bb1 +8711 9bbb +8712 9c00 +8713 9d70 +8714 9d6b +8715 fa2d +8716 9e19 +8717 9ed1 +8719 /uni005C.hw +8720 /cid-1.vert +8721 /cid-2.vert +8722 /cid-3.vert +8723 /cid-4.vert +8724 /cid-5.vert +8725 /cid-6.vert +8726 /cid-7.vert +8727 /cid-8.vert +8728 /cid-9.vert +8729 /cid-10.vert +8730 /cid-11.vert +8731 /cid-12.vert +8732 /cid-13.vert +8733 /cid-14.vert +8734 /cid-15.vert +8735 /cid-16.vert +8736 /cid-17.vert +8737 /cid-18.vert +8738 /cid-19.vert +8739 /cid-20.vert +8740 /cid-21.vert +8741 /cid-22.vert +8742 /cid-23.vert +8743 /cid-24.vert +8744 /cid-25.vert +8745 /cid-26.vert +8746 /cid-27.vert +8747 /cid-28.vert +8748 /cid-29.vert +8749 /cid-30.vert +8750 /cid-31.vert +8751 /cid-32.vert +8752 /cid-33.vert +8753 /cid-34.vert +8754 /cid-35.vert +8755 /cid-36.vert +8756 /cid-37.vert +8757 /cid-38.vert +8758 /cid-39.vert +8759 /cid-40.vert +8760 /cid-41.vert +8761 /cid-42.vert +8762 /cid-43.vert +8763 /cid-44.vert +8764 /cid-45.vert +8765 /cid-46.vert +8766 /cid-47.vert +8767 /cid-48.vert +8768 /cid-49.vert +8769 /cid-50.vert +8770 /cid-51.vert +8771 /cid-52.vert +8772 /cid-53.vert +8773 /cid-54.vert +8774 /cid-55.vert +8775 /cid-56.vert +8776 /cid-57.vert +8777 /cid-58.vert +8778 /cid-59.vert +8779 /cid-60.vert +8780 /cid-61.vert +8781 /cid-62.vert +8782 /cid-63.vert +8783 /cid-64.vert +8784 /cid-65.vert +8785 /cid-66.vert +8786 /cid-67.vert +8787 /cid-68.vert +8788 /cid-69.vert +8789 /cid-70.vert +8790 /cid-71.vert +8791 /cid-72.vert +8792 /cid-73.vert +8793 /cid-74.vert +8794 /cid-75.vert +8795 /cid-76.vert +8796 /cid-77.vert +8797 /cid-78.vert +8798 /cid-79.vert +8799 /cid-80.vert +8800 /cid-81.vert +8801 /cid-82.vert +8802 /cid-83.vert +8803 /cid-84.vert +8804 /cid-85.vert +8805 /cid-86.vert +8806 /cid-87.vert +8807 /cid-88.vert +8808 /cid-89.vert +8809 /cid-90.vert +8810 /cid-91.vert +8811 /cid-92.vert +8812 /cid-93.vert +8813 /cid-94.vert +8814 /cid-95.vert +8815 /cid-96.vert +8816 /cid-97.vert +8817 /cid-98.vert +8818 /cid-99.vert +8819 /cid-100.vert +8820 /cid-101.vert +8821 /cid-102.vert +8822 /cid-103.vert +8823 /cid-104.vert +8824 /cid-105.vert +8825 /cid-106.vert +8826 /cid-107.vert +8827 /cid-108.vert +8828 /cid-109.vert +8829 /cid-110.vert +8830 /cid-111.vert +8831 /cid-112.vert +8832 /cid-113.vert +8833 /cid-114.vert +8834 /cid-115.vert +8835 /cid-116.vert +8836 /cid-117.vert +8837 /cid-118.vert +8838 /cid-119.vert +8839 /cid-120.vert +8840 /cid-121.vert +8841 /cid-122.vert +8842 /cid-123.vert +8843 /cid-124.vert +8844 /cid-125.vert +8845 /cid-126.vert +8846 /cid-127.vert +8847 /cid-128.vert +8848 /cid-129.vert +8849 /cid-130.vert +8850 /cid-131.vert +8851 /cid-132.vert +8852 /cid-133.vert +8853 /cid-134.vert +8854 /cid-135.vert +8855 /cid-136.vert +8856 /cid-137.vert +8857 /cid-138.vert +8858 /cid-139.vert +8859 /cid-140.vert +8860 /cid-141.vert +8861 /cid-142.vert +8862 /cid-143.vert +8863 /cid-144.vert +8864 /cid-145.vert +8865 /cid-146.vert +8866 /cid-147.vert +8867 /cid-148.vert +8868 /cid-149.vert +8869 /cid-150.vert +8870 /cid-151.vert +8871 /cid-152.vert +8872 /cid-153.vert +8873 /cid-154.vert +8874 /cid-155.vert +8875 /cid-156.vert +8876 /cid-157.vert +8877 /cid-158.vert +8878 /cid-159.vert +8879 /cid-160.vert +8880 /cid-161.vert +8881 /cid-162.vert +8882 /cid-163.vert +8883 /cid-164.vert +8884 /cid-165.vert +8885 /cid-166.vert +8886 /cid-167.vert +8887 /cid-168.vert +8888 /cid-169.vert +8889 /cid-170.vert +8890 /cid-171.vert +8891 /cid-172.vert +8892 /cid-173.vert +8893 /cid-174.vert +8894 /cid-175.vert +8895 /cid-176.vert +8896 /cid-177.vert +8897 /cid-178.vert +8898 /cid-179.vert +8899 /cid-180.vert +8900 /cid-181.vert +8901 /cid-182.vert +8902 /cid-183.vert +8903 /cid-184.vert +8904 /cid-185.vert +8905 /cid-186.vert +8906 /cid-187.vert +8907 /cid-188.vert +8908 /cid-189.vert +8909 /cid-190.vert +8910 /cid-191.vert +8911 /cid-192.vert +8912 /cid-193.vert +8913 /cid-194.vert +8914 /cid-195.vert +8915 /cid-196.vert +8916 /cid-197.vert +8917 /cid-198.vert +8918 /cid-199.vert +8919 /cid-200.vert +8920 /cid-201.vert +8921 /cid-202.vert +8922 /cid-203.vert +8923 /cid-204.vert +8924 /cid-205.vert +8925 /cid-206.vert +8926 /cid-207.vert +8927 /cid-208.vert +8928 /cid-209.vert +8929 /cid-210.vert +8930 /cid-211.vert +8931 /cid-212.vert +8932 /cid-213.vert +8933 /cid-214.vert +8934 /cid-215.vert +8935 /cid-216.vert +8936 /cid-217.vert +8937 /cid-218.vert +8938 /cid-219.vert +8939 /cid-220.vert +8940 /cid-221.vert +8941 /cid-222.vert +8942 /cid-223.vert +8943 /cid-224.vert +8944 /cid-225.vert +8945 /cid-226.vert +8946 /cid-227.vert +8947 /cid-228.vert +8948 /cid-229.vert +8949 /cid-230.vert +8950 /cid-231.vert +8951 /cid-232.vert +8952 /cid-233.vert +8953 /cid-234.vert +8954 /cid-235.vert +8955 /cid-236.vert +8956 /cid-237.vert +8957 /cid-238.vert +8958 /cid-239.vert +8959 /cid-240.vert +8960 /cid-241.vert +8961 /cid-242.vert +8962 /cid-243.vert +8963 /cid-244.vert +8964 /cid-245.vert +8965 /cid-246.vert +8966 /cid-247.vert +8967 /cid-248.vert +8968 /cid-249.vert +8969 /cid-250.vert +8970 /cid-251.vert +8971 /cid-252.vert +8972 /cid-253.vert +8973 /cid-254.vert +8974 /cid-255.vert +8975 /cid-256.vert +8976 /cid-257.vert +8977 /cid-258.vert +8978 /cid-259.vert +8979 /cid-260.vert +8980 /cid-261.vert +8981 /cid-262.vert +8982 /cid-263.vert +8983 /cid-264.vert +8984 /cid-265.vert +8985 /cid-266.vert +8986 /cid-267.vert +8987 /cid-268.vert +8988 /cid-269.vert +8989 /cid-270.vert +8990 /cid-271.vert +8991 /cid-272.vert +8992 /cid-273.vert +8993 /cid-274.vert +8994 /cid-275.vert +8995 /cid-276.vert +8996 /cid-277.vert +8997 /cid-278.vert +8998 /cid-279.vert +8999 /cid-280.vert +9000 /cid-281.vert +9001 /cid-282.vert +9002 /cid-283.vert +9003 /cid-284.vert +9004 /cid-285.vert +9005 /cid-286.vert +9006 /cid-287.vert +9007 /cid-288.vert +9008 /cid-289.vert +9009 /cid-290.vert +9010 /cid-291.vert +9011 /cid-292.vert +9012 /cid-293.vert +9013 /cid-294.vert +9014 /cid-295.vert +9015 /cid-296.vert +9016 /cid-297.vert +9017 /cid-298.vert +9018 /cid-299.vert +9019 /cid-300.vert +9020 /cid-301.vert +9021 /cid-302.vert +9022 /cid-303.vert +9023 /cid-304.vert +9024 /cid-305.vert +9025 /cid-306.vert +9026 /cid-307.vert +9027 /cid-308.vert +9028 /cid-309.vert +9029 /cid-310.vert +9030 /cid-311.vert +9031 /cid-312.vert +9032 /cid-313.vert +9033 /cid-314.vert +9034 /cid-315.vert +9035 /cid-316.vert +9036 /cid-317.vert +9037 /cid-318.vert +9038 /cid-319.vert +9039 /cid-320.vert +9040 /cid-321.vert +9041 /cid-322.vert +9042 /cid-323.vert +9043 /cid-324.vert +9044 /cid-325.vert +9045 /cid-599.vert +9046 /cid-600.vert +9047 /cid-601.vert +9048 /cid-602.vert +9049 /cid-603.vert +9050 /cid-604.vert +9051 /cid-605.vert +9052 /cid-606.vert +9053 /cid-607.vert +9054 /cid-608.vert +9055 /cid-609.vert +9056 /cid-610.vert +9057 /cid-611.vert +9058 /cid-612.vert +9059 /cid-613.vert +9060 /cid-614.vert +9061 /cid-615.vert +9062 /cid-616.vert +9063 /cid-617.vert +9064 /cid-618.vert +9065 /cid-619.vert +9066 /cid-620.vert +9067 /cid-621.vert +9068 /cid-622.vert +9069 /cid-623.vert +9070 /cid-624.vert +9071 /cid-625.vert +9072 /cid-626.vert +9073 /cid-627.vert +9074 /cid-628.vert +9075 /cid-629.vert +9076 /cid-630.vert +9077 /cid-631.vert +9078 /cid-632.vert +9079 /cid-630.vert +9080 /cid-631.vert +9081 /cid-632.vert +9083 /cid-8719.vert +9084 /cid-326.vert +9085 /cid-327.vert +9086 /cid-328.vert +9087 /cid-329.vert +9088 /cid-330.vert +9089 /cid-331.vert +9090 /cid-332.vert +9091 /cid-333.vert +9092 /cid-334.vert +9093 /cid-335.vert +9094 /cid-336.vert +9095 /cid-337.vert +9096 /cid-338.vert +9097 /cid-339.vert +9098 /cid-340.vert +9099 /cid-341.vert +9100 /cid-342.vert +9101 /cid-343.vert +9102 /cid-344.vert +9103 /cid-345.vert +9104 /cid-346.vert +9105 /cid-347.vert +9106 /cid-348.vert +9107 /cid-349.vert +9108 /cid-350.vert +9109 /cid-351.vert +9110 /cid-352.vert +9111 /cid-353.vert +9112 /cid-354.vert +9113 /cid-355.vert +9114 /cid-356.vert +9115 /cid-357.vert +9116 /cid-358.vert +9117 /cid-359.vert +9118 /cid-360.vert +9119 /cid-361.vert +9120 /cid-362.vert +9121 /cid-363.vert +9122 /cid-364.vert +9123 /cid-365.vert +9124 /cid-366.vert +9125 /cid-367.vert +9126 /cid-368.vert +9127 /cid-369.vert +9128 /cid-370.vert +9129 /cid-371.vert +9130 /cid-372.vert +9131 /cid-373.vert +9132 /cid-374.vert +9133 /cid-375.vert +9134 /cid-376.vert +9135 /cid-377.vert +9136 /cid-378.vert +9137 /cid-379.vert +9138 /cid-380.vert +9139 /cid-381.vert +9140 /cid-382.vert +9141 /cid-383.vert +9142 /cid-384.vert +9143 /cid-385.vert +9144 /cid-386.vert +9145 /cid-387.vert +9146 /cid-388.vert +9147 /cid-389.vert +9148 /cid-391.vert +9149 /cid-392.vert +9150 /cid-393.vert +9151 /cid-394.vert +9152 /cid-395.vert +9153 /cid-396.vert +9154 /cid-397.vert +9155 /cid-398.vert +9156 /cid-399.vert +9157 /cid-400.vert +9158 /cid-401.vert +9159 /cid-402.vert +9160 /cid-403.vert +9161 /cid-404.vert +9162 /cid-405.vert +9163 /cid-406.vert +9164 /cid-407.vert +9165 /cid-408.vert +9166 /cid-409.vert +9167 /cid-410.vert +9168 /cid-411.vert +9169 /cid-412.vert +9170 /cid-413.vert +9171 /cid-414.vert +9172 /cid-415.vert +9173 /cid-416.vert +9174 /cid-417.vert +9175 /cid-418.vert +9176 /cid-419.vert +9177 /cid-420.vert +9178 /cid-421.vert +9179 /cid-515.vert +9180 /cid-516.vert +9181 /cid-517.vert +9182 /cid-518.vert +9183 /cid-519.vert +9184 /cid-520.vert +9185 /cid-521.vert +9186 /cid-522.vert +9187 /cid-523.vert +9188 /cid-524.vert +9189 /cid-525.vert +9190 /cid-526.vert +9191 /cid-527.vert +9192 /cid-528.vert +9193 /cid-529.vert +9194 /cid-530.vert +9195 /cid-531.vert +9196 /cid-532.vert +9197 /cid-533.vert +9198 /cid-534.vert +9199 /cid-535.vert +9200 /cid-536.vert +9201 /cid-537.vert +9202 /cid-538.vert +9203 /cid-539.vert +9204 /cid-540.vert +9205 /cid-541.vert +9206 /cid-542.vert +9207 /cid-543.vert +9208 /cid-544.vert +9209 /cid-545.vert +9210 /cid-546.vert +9211 /cid-547.vert +9212 /cid-548.vert +9213 /cid-549.vert +9214 /cid-550.vert +9215 /cid-551.vert +9216 /cid-552.vert +9217 /cid-553.vert +9218 /cid-554.vert +9219 /cid-555.vert +9220 /cid-556.vert +9221 /cid-557.vert +9222 /cid-558.vert +9223 /cid-559.vert +9224 /cid-560.vert +9225 /cid-561.vert +9226 /cid-562.vert +9227 /cid-563.vert +9228 /cid-564.vert +9229 /cid-565.vert +9230 /cid-566.vert +9231 /cid-567.vert +9232 /cid-568.vert +9233 /cid-569.vert +9234 /cid-570.vert +9235 /cid-571.vert +9236 /cid-572.vert +9237 /cid-573.vert +9238 /cid-574.vert +9239 /cid-575.vert +9240 /cid-576.vert +9241 /cid-577.vert +9242 /cid-578.vert +9243 /cid-579.vert +9244 /cid-580.vert +9245 /cid-581.vert +9246 /cid-582.vert +9247 /cid-583.vert +9248 /cid-584.vert +9249 /cid-585.vert +9250 /cid-586.vert +9251 /cid-587.vert +9252 /cid-588.vert +9253 /cid-589.vert +9254 /cid-590.vert +9255 /cid-591.vert +9256 /cid-592.vert +9257 /cid-593.vert +9258 /cid-594.vert +9259 /cid-595.vert +9260 /cid-596.vert +9261 /cid-597.vert +9262 /cid-598.vert +9263 /cid-423.vert +9264 /cid-424.vert +9265 /cid-425.vert +9266 /cid-426.vert +9267 /cid-427.vert +9268 /cid-428.vert +9269 /cid-429.vert +9270 /cid-430.vert +9271 /cid-431.vert +9272 /cid-432.vert +9273 /cid-433.vert +9274 /cid-434.vert +9275 /cid-514.vert +9276 /cid-515.vert +9277 /cid-425.vert +9278 /cid-426.vert +9279 /cid-427.vert +9280 /cid-428.vert +9281 /cid-429.vert +9282 /cid-430.vert +9283 /cid-431.vert +9284 /cid-432.vert +9285 /cid-433.vert +9286 /cid-434.vert +9287 /cid-435.vert +9288 /cid-436.vert +9289 /cid-437.vert +9290 /cid-438.vert +9291 /cid-439.vert +9292 /cid-440.vert +9293 /cid-441.vert +9294 /cid-442.vert +9295 /cid-443.vert +9296 /cid-444.vert +9297 /cid-445.vert +9298 /cid-446.vert +9299 /cid-447.vert +9300 /cid-448.vert +9301 /cid-449.vert +9302 /cid-450.vert +9303 /cid-451.vert +9304 /cid-452.vert +9305 /cid-453.vert +9306 /cid-454.vert +9307 /cid-455.vert +9308 /cid-456.vert +9309 /cid-457.vert +9310 /cid-458.vert +9311 /cid-459.vert +9312 /cid-460.vert +9313 /cid-461.vert +9314 /cid-462.vert +9315 /cid-463.vert +9316 /cid-464.vert +9317 /cid-465.vert +9318 /cid-466.vert +9319 /cid-467.vert +9320 /cid-468.vert +9321 /cid-469.vert +9322 /cid-470.vert +9323 /cid-471.vert +9324 /cid-472.vert +9325 /cid-473.vert +9326 /cid-474.vert +9327 /cid-475.vert +9328 /cid-476.vert +9329 /cid-477.vert +9330 /cid-478.vert +9331 /cid-479.vert +9332 /cid-480.vert +9333 /cid-481.vert +9334 /cid-482.vert +9335 /cid-483.vert +9336 /cid-484.vert +9337 /cid-485.vert +9338 /cid-486.vert +9339 /cid-487.vert +9340 /cid-488.vert +9341 /cid-489.vert +9342 /cid-490.vert +9343 /cid-491.vert +9344 /cid-492.vert +9345 /cid-493.vert +9346 /cid-494.vert +9347 /cid-495.vert +9348 /cid-496.vert +9349 /cid-497.vert +9350 /cid-498.vert +9351 /cid-499.vert +9352 /cid-500.vert +9353 /cid-501.vert +9354 20ac +9355 2126 +9358 fb00 +9359..9360 fb03 +9361 0101 +9362 012b +9363 016b +9364 0113 +9365 014d +9366 0100 +9367 012a +9368 016a +9369 0112 +9370 014c +9371..9374 215b +9375..9376 2153 +9377 2070 +9378..9383 2074 +9384..9393 2080 +9394 01cd +9395 011a +9397 1ebc +9398 01cf +9400 0128 +9401 01d1 +9403 01d3 +9404 016e +9405 0168 +9406 01ce +9407 011b +9409 1ebd +9410 01d0 +9412 0129 +9413 01d2 +9415 01d4 +9416 016f +9417 0169 +9418 0251 +9419 1f71 +9420 1f70 +9421 01fd +9423 0254 +9426 0259 +9429 025a +9432 025b +9433 1f73 +9434 1f72 +9435 f6be +9436 014b +9437 0275 +9438 028c +9441 0292 +9442 0283 +9443 02d0 +9444 /uni0020.italic +9445 /uni0021.italic +9446 /uni0022.italic +9447 /uni0023.italic +9448 /uni0024.italic +9449 /uni0025.italic +9450 /uni0026.italic +9451 /uni0027.italic +9452 /uni0028.italic +9453 /uni0029.italic +9454 /uni002A.italic +9455 /uni002B.italic +9456 /uni002C.italic +9457 /uni002D.italic +9458 /uni002E.italic +9459 /uni002F.italic +9460 /uni0030.italic +9461 /uni0031.italic +9462 /uni0032.italic +9463 /uni0033.italic +9464 /uni0034.italic +9465 /uni0035.italic +9466 /uni0036.italic +9467 /uni0037.italic +9468 /uni0038.italic +9469 /uni0039.italic +9470 /uni003A.italic +9471 /uni003B.italic +9472 /uni003C.italic +9473 /uni003D.italic +9474 /uni003E.italic +9475 /uni003F.italic +9476 /uni0040.italic +9477 /uni0041.italic +9478 /uni0042.italic +9479 /uni0043.italic +9480 /uni0044.italic +9481 /uni0045.italic +9482 /uni0046.italic +9483 /uni0047.italic +9484 /uni0048.italic +9485 /uni0049.italic +9486 /uni004A.italic +9487 /uni004B.italic +9488 /uni004C.italic +9489 /uni004D.italic +9490 /uni004E.italic +9491 /uni004F.italic +9492 /uni0050.italic +9493 /uni0051.italic +9494 /uni0052.italic +9495 /uni0053.italic +9496 /uni0054.italic +9497 /uni0055.italic +9498 /uni0056.italic +9499 /uni0057.italic +9500 /uni0058.italic +9501 /uni0059.italic +9502 /uni005A.italic +9503 /uni005B.italic +9504 /uni00A5.italic +9505 /uni005D.italic +9506 /uni005E.italic +9507 /uni005F.italic +9508 /uni0060.italic +9509 /uni0061.italic +9510 /uni0062.italic +9511 /uni0063.italic +9512 /uni0064.italic +9513 /uni0065.italic +9514 /uni0066.italic +9515 /uni0067.italic +9516 /uni0068.italic +9517 /uni0069.italic +9518 /uni006A.italic +9519 /uni006B.italic +9520 /uni006C.italic +9521 /uni006D.italic +9522 /uni006E.italic +9523 /uni006F.italic +9524 /uni0070.italic +9525 /uni0071.italic +9526 /uni0072.italic +9527 /uni0073.italic +9528 /uni0074.italic +9529 /uni0075.italic +9530 /uni0076.italic +9531 /uni0077.italic +9532 /uni0078.italic +9533 /uni0079.italic +9534 /uni007A.italic +9535 /uni007B.italic +9536 /uni007C.italic +9537 /uni007D.italic +9540 /uni005C.italic +9544 /uni00A1.italic +9545 /uni00A2.italic +9546 /uni00A3.italic +9549 /uni00A7.italic +9550 /uni00A4.italic +9551 /uni201C.italic +9552 /uni00AB.italic +9553 /uni2039.italic +9554 /uni203A.italic +9555 /uniFB01.italic +9556 /uniFB02.italic +9558 /uni2020.italic +9559 /uni2021.italic +9560 /uni00B7.italic +9561 /uni00B6.italic +9562 /uni2022.italic +9563 /uni201A.italic +9564 /uni201E.italic +9565 /uni201D.italic +9566 /uni00BB.italic +9567 /uni2026.italic +9568 /uni2030.italic +9569 /uni00BF.italic +9570 /uni02CA.italic +9571 /uni02C6.italic +9572 /uni00AF.italic +9573 /uni02D8.italic +9574 /uni02D9.italic +9575 /uni00A8.italic +9576 /uni02DA.italic +9577 /uni00B8.italic +9578 /uni02DD.italic +9579 /uni02DB.italic +9580 /uni02C7.italic +9581 /uni2014.italic +9582 /uni00C6.italic +9583 /uni00AA.italic +9584 /uni0141.italic +9585 /uni00D8.italic +9586 /uni0152.italic +9587 /uni00BA.italic +9588 /uni00E6.italic +9589 /uni0131.italic +9590 /uni0142.italic +9591 /uni00F8.italic +9592 /uni0153.italic +9593 /uni00DF.italic +9595 /uni00A9.italic +9596 /uni00AC.italic +9597 /uni00AE.italic +9598 /uni00B0.italic +9599 /uni00B1.italic +9600 /uni00B2.italic +9601 /uni00B3.italic +9602 /uni00B5.italic +9603 /uni00B9.italic +9604 /uni00BC.italic +9605 /uni00BD.italic +9606 /uni00BE.italic +9607 /uni00C0.italic +9608 /uni00C1.italic +9609 /uni00C2.italic +9610 /uni00C3.italic +9611 /uni00C4.italic +9612 /uni00C5.italic +9613 /uni00C7.italic +9614 /uni00C8.italic +9615 /uni00C9.italic +9616 /uni00CA.italic +9617 /uni00CB.italic +9618 /uni00CC.italic +9619 /uni00CD.italic +9620 /uni00CE.italic +9621 /uni00CF.italic +9622 /uni00D0.italic +9623 /uni00D1.italic +9624 /uni00D2.italic +9625 /uni00D3.italic +9626 /uni00D4.italic +9627 /uni00D5.italic +9628 /uni00D6.italic +9629 /uni00D7.italic +9630 /uni00D9.italic +9631 /uni00DA.italic +9632 /uni00DB.italic +9633 /uni00DC.italic +9634 /uni00DD.italic +9635 /uni00DE.italic +9636 /uni00DF.italic +9637 /uni00E0.italic +9638 /uni00E1.italic +9639 /uni00E2.italic +9640 /uni00E3.italic +9641 /uni00E4.italic +9642 /uni00E7.italic +9643 /uni00E8.italic +9644 /uni00E9.italic +9645 /uni00EA.italic +9646 /uni00EB.italic +9647 /uni00EC.italic +9648 /uni00ED.italic +9649 /uni00EE.italic +9650 /uni00EF.italic +9651 /uni00F0.italic +9652 /uni00F1.italic +9653 /uni00F2.italic +9654 /uni00F3.italic +9655 /uni00F4.italic +9656 /uni00F5.italic +9657 /uni00F6.italic +9658 /uni00F7.italic +9659 /uni00F9.italic +9660 /uni00FA.italic +9661 /uni00FB.italic +9662 /uni00FC.italic +9663 /uni00FD.italic +9664 /uni00FE.italic +9665 /uni00FF.italic +9666 /uni0160.italic +9667 /uni0178.italic +9668 /uni017D.italic +9670 /uni0160.italic +9671 /uni2122.italic +9672 /uni017E.italic +9673 /uni00D8.italic +9674 /uni20AC.italic +9675 /uni2126.italic +9676 /uni2032.italic +9677 /uni2033.italic +9678 /uniFB00.italic +9679 /uniFB03.italic +9680 /uniFB04.italic +9681 /uni0101.italic +9682 /uni012B.italic +9683 /uni016B.italic +9684 /uni0113.italic +9685 /uni014D.italic +9686 /uni0100.italic +9687 /uni012A.italic +9688 /uni016A.italic +9689 /uni0112.italic +9690 /uni014C.italic +9691 /uni2158.italic +9692 /uni2159.italic +9693 /uni215A.italic +9694 /uni215B.italic +9695 /uni2153.italic +9696 /uni2154.italic +9697 /uni2070.italic +9698 /uni2074.italic +9699 /uni2075.italic +9700 /uni2076.italic +9701 /uni2077.italic +9702 /uni2078.italic +9703 /uni2079.italic +9704 /uni2080.italic +9705 /uni2081.italic +9706 /uni2082.italic +9707 /uni2083.italic +9708 /uni2084.italic +9709 /uni2085.italic +9710 /uni2086.italic +9711 /uni2087.italic +9712 /uni2088.italic +9713 /uni2089.italic +9714 /uni01CD.italic +9715 /uni011A.italic +9717 /uni1EBC.italic +9718 /uni01CF.italic +9721 /uni01D1.italic +9723 /uni01D3.italic +9724 /uni016E.italic +9725 /uni0168.italic +9726 /uni01CE.italic +9727 /uni011B.italic +9729 /uni1EBD.italic +9730 /uni01D0.italic +9733 /uni01D2.italic +9735 /uni01D4.italic +9736 /uni016F.italic +9737 /uni0169.italic +10126..10135 3220 +10244..10247 325c +10248..10262 32b1 +10313..10338 24d0 +10339..10364 24b6 +10413..10459 32d0 +10461..10470 3280 +10471 3290 +10472..10477 328a +10479 329f +10486..10487 32a0 +10488 329b +10489 329a +10490 32a3 +10491 32a2 +10492 3297 +10494 329c +10495 3295 +10502 25cc +10514 277f +10515..10524 24eb +11035 20de +11851 33da +11855 2100 +11856 33c2 +11859 2105 +11861 3371 +11864 338d +11865 339b +11869..11870 33d7 +11874..11875 3301 +11876 3304 +11877 3306 +11879 3308 +11881 3307 +11882 330a +11884 3309 +11886 330b +11888 330c +11889..11894 330e +11896 3317 +11898 3319 +11900..11903 331a +11904..11906 331f +11907 3324 +11909 3325 +11912..11913 3328 +11915 332d +11918..11920 332e +11921 3332 +11924..11925 3334 +11926 333c +11930 3337 +11932 3338 +11933 333a +11934 333d +11935 3341 +11936..11938 333e +11939..11942 3343 +11943 3348 +11944..11945 334b +11946..11947 334f +11950 3352 +11951 3354 +11954 3353 +11955..11956 3355 +11958 /cid-11874.vert +11959 /cid-11875.vert +11960 /cid-11876.vert +11961 /cid-11877.vert +11963 /cid-11879.vert +11965 /cid-11881.vert +11966 /cid-11882.vert +11968 /cid-11884.vert +11970 /cid-11886.vert +11972 /cid-11888.vert +11973 /cid-11889.vert +11974 /cid-11890.vert +11975 /cid-11891.vert +11976 /cid-11892.vert +11977 /cid-11893.vert +11978 /cid-11894.vert +11980 /cid-11896.vert +11982 /cid-11898.vert +11984 /cid-11900.vert +11985 /cid-11901.vert +11986 /cid-11902.vert +11987 /cid-11903.vert +11988 /cid-11904.vert +11989 /cid-11905.vert +11990 /cid-11906.vert +11991 /cid-11907.vert +11993 /cid-11909.vert +11996 /cid-11912.vert +11997 /cid-11913.vert +11999 /cid-11915.vert +12002 /cid-11918.vert +12003 /cid-11919.vert +12004 /cid-11920.vert +12005 /cid-11921.vert +12008 /cid-11924.vert +12009 /cid-11925.vert +12010 /cid-11926.vert +12014 /cid-11930.vert +12016 /cid-11932.vert +12017 /cid-11933.vert +12018 /cid-11934.vert +12019 /cid-11935.vert +12020 /cid-11936.vert +12021 /cid-11937.vert +12022 /cid-11938.vert +12023 /cid-11939.vert +12024 /cid-11940.vert +12025 /cid-11941.vert +12026 /cid-11942.vert +12027 /cid-11943.vert +12028 /cid-11944.vert +12029 /cid-11945.vert +12030 /cid-11946.vert +12031 /cid-11947.vert +12034 /cid-11950.vert +12035 /cid-11951.vert +12038 /cid-11954.vert +12039 /cid-11955.vert +12040 /cid-11956.vert +12089 2135 +12090 03d0 +12091 220a +12092 210f +12094 03d5 +12095 03db +12096 03d1 +12098..12099 2668 +12100 266c +12106 303b +12107 /cid-12106.vert +12108..12110 3033 +12111 203c +12112 2049 +12116 244a +12118 2213 +12120 2243 +12121..12122 2272 +12129..12130 3018 +12131..12132 ff5f +12139 /cid-12129.vert +12140 /cid-12130.vert +12141 /cid-12131.vert +12142 /cid-12132.vert +12143 239b +12144..12145 239d +12146 23a0 +12147 /cid-12144.vert +12148 /cid-12143.vert +12149 /cid-12146.vert +12150 /cid-12145.vert +12151 23a1 +12152..12153 23a3 +12154 23a6 +12155 /cid-12152.vert +12156 /cid-12151.vert +12157 /cid-12154.vert +12158 /cid-12153.vert +12167 239c +12168 /cid-12167.vert +12176 2702 +12178 /cid-12176.vert +12179 303d +12181 309f +12184 2205 +12185 22a0 +12186 2296 +12187 2298 +12188 2295 +12189 2297 +12190 229e +12194 25c0 +12195 25b6 +12200 21d0 +12201 2194 +12202..12203 2198 +12204..12205 2196 +12206 21cc +12207 21cb +12214 /cid-12215.vert +12215 2195 +12218 3030 +12219 2307 +12228 2740 +12229 273f +12237 25ab +12239 25aa +12241 271a +12254 25e6 +12259 2756 +12639..12640 fe45 +12870 /cid-9354.vert +12871 /cid-9355.vert +12872 /cid-9356.vert +12873 /cid-9357.vert +12874 /cid-9358.vert +12875 /cid-9359.vert +12876 /cid-9360.vert +12877 /cid-9361.vert +12878 /cid-9362.vert +12879 /cid-9363.vert +12880 /cid-9364.vert +12881 /cid-9365.vert +12882 /cid-9366.vert +12883 /cid-9367.vert +12884 /cid-9368.vert +12885 /cid-9369.vert +12886 /cid-9370.vert +12887 /cid-9371.vert +12888 /cid-9372.vert +12889 /cid-9373.vert +12890 /cid-9374.vert +12891 /cid-9375.vert +12892 /cid-9376.vert +12893 /cid-9377.vert +12894 /cid-9378.vert +12895 /cid-9379.vert +12896 /cid-9380.vert +12897 /cid-9381.vert +12898 /cid-9382.vert +12899 /cid-9383.vert +12900 /cid-9384.vert +12901 /cid-9385.vert +12902 /cid-9386.vert +12903 /cid-9387.vert +12904 /cid-9388.vert +12905 /cid-9389.vert +12906 /cid-9390.vert +12907 /cid-9391.vert +12908 /cid-9392.vert +12909 /cid-9393.vert +12910 /cid-9394.vert +12911 /cid-9395.vert +12912 /cid-9396.vert +12913 /cid-9397.vert +12914 /cid-9398.vert +12915 /cid-9399.vert +12916 /cid-9400.vert +12917 /cid-9401.vert +12918 /cid-9402.vert +12919 /cid-9403.vert +12920 /cid-9404.vert +12921 /cid-9405.vert +12922 /cid-9406.vert +12923 /cid-9407.vert +12924 /cid-9408.vert +12925 /cid-9409.vert +12926 /cid-9410.vert +12927 /cid-9411.vert +12928 /cid-9412.vert +12929 /cid-9413.vert +12930 /cid-9414.vert +12931 /cid-9415.vert +12932 /cid-9416.vert +12933 /cid-9417.vert +12934 /cid-9418.vert +12935 /cid-9419.vert +12936 /cid-9420.vert +12937 /cid-9421.vert +12938 /cid-9422.vert +12939 /cid-9423.vert +12940 /cid-9424.vert +12941 /cid-9425.vert +12942 /cid-9426.vert +12943 /cid-9427.vert +12944 /cid-9428.vert +12945 /cid-9429.vert +12946 /cid-9430.vert +12947 /cid-9431.vert +12948 /cid-9432.vert +12949 /cid-9433.vert +12950 /cid-9434.vert +12951 /cid-9435.vert +12952 /cid-9436.vert +12953 /cid-9437.vert +12954 /cid-9438.vert +12955 /cid-9439.vert +12956 /cid-9440.vert +12957 /cid-9441.vert +12958 /cid-9442.vert +12959 /cid-9443.vert +12960 /cid-9444.vert +12961 /cid-9445.vert +12962 /cid-9446.vert +12963 /cid-9447.vert +12964 /cid-9448.vert +12965 /cid-9449.vert +12966 /cid-9450.vert +12967 /cid-9451.vert +12968 /cid-9452.vert +12969 /cid-9453.vert +12970 /cid-9454.vert +12971 /cid-9455.vert +12972 /cid-9456.vert +12973 /cid-9457.vert +12974 /cid-9458.vert +12975 /cid-9459.vert +12976 /cid-9460.vert +12977 /cid-9461.vert +12978 /cid-9462.vert +12979 /cid-9463.vert +12980 /cid-9464.vert +12981 /cid-9465.vert +12982 /cid-9466.vert +12983 /cid-9467.vert +12984 /cid-9468.vert +12985 /cid-9469.vert +12986 /cid-9470.vert +12987 /cid-9471.vert +12988 /cid-9472.vert +12989 /cid-9473.vert +12990 /cid-9474.vert +12991 /cid-9475.vert +12992 /cid-9476.vert +12993 /cid-9477.vert +12994 /cid-9478.vert +12995 /cid-9479.vert +12996 /cid-9480.vert +12997 /cid-9481.vert +12998 /cid-9482.vert +12999 /cid-9483.vert +13000 /cid-9484.vert +13001 /cid-9485.vert +13002 /cid-9486.vert +13003 /cid-9487.vert +13004 /cid-9488.vert +13005 /cid-9489.vert +13006 /cid-9490.vert +13007 /cid-9491.vert +13008 /cid-9492.vert +13009 /cid-9493.vert +13010 /cid-9494.vert +13011 /cid-9495.vert +13012 /cid-9496.vert +13013 /cid-9497.vert +13014 /cid-9498.vert +13015 /cid-9499.vert +13016 /cid-9500.vert +13017 /cid-9501.vert +13018 /cid-9502.vert +13019 /cid-9503.vert +13020 /cid-9504.vert +13021 /cid-9505.vert +13022 /cid-9506.vert +13023 /cid-9507.vert +13024 /cid-9508.vert +13025 /cid-9509.vert +13026 /cid-9510.vert +13027 /cid-9511.vert +13028 /cid-9512.vert +13029 /cid-9513.vert +13030 /cid-9514.vert +13031 /cid-9515.vert +13032 /cid-9516.vert +13033 /cid-9517.vert +13034 /cid-9518.vert +13035 /cid-9519.vert +13036 /cid-9520.vert +13037 /cid-9521.vert +13038 /cid-9522.vert +13039 /cid-9523.vert +13040 /cid-9524.vert +13041 /cid-9525.vert +13042 /cid-9526.vert +13043 /cid-9527.vert +13044 /cid-9528.vert +13045 /cid-9529.vert +13046 /cid-9530.vert +13047 /cid-9531.vert +13048 /cid-9532.vert +13049 /cid-9533.vert +13050 /cid-9534.vert +13051 /cid-9535.vert +13052 /cid-9536.vert +13053 /cid-9537.vert +13054 /cid-9538.vert +13055 /cid-9539.vert +13056 /cid-9540.vert +13057 /cid-9541.vert +13058 /cid-9542.vert +13059 /cid-9543.vert +13060 /cid-9544.vert +13061 /cid-9545.vert +13062 /cid-9546.vert +13063 /cid-9547.vert +13064 /cid-9548.vert +13065 /cid-9549.vert +13066 /cid-9550.vert +13067 /cid-9551.vert +13068 /cid-9552.vert +13069 /cid-9553.vert +13070 /cid-9554.vert +13071 /cid-9555.vert +13072 /cid-9556.vert +13073 /cid-9557.vert +13074 /cid-9558.vert +13075 /cid-9559.vert +13076 /cid-9560.vert +13077 /cid-9561.vert +13078 /cid-9562.vert +13079 /cid-9563.vert +13080 /cid-9564.vert +13081 /cid-9565.vert +13082 /cid-9566.vert +13083 /cid-9567.vert +13084 /cid-9568.vert +13085 /cid-9569.vert +13086 /cid-9570.vert +13087 /cid-9571.vert +13088 /cid-9572.vert +13089 /cid-9573.vert +13090 /cid-9574.vert +13091 /cid-9575.vert +13092 /cid-9576.vert +13093 /cid-9577.vert +13094 /cid-9578.vert +13095 /cid-9579.vert +13096 /cid-9580.vert +13097 /cid-9581.vert +13098 /cid-9582.vert +13099 /cid-9583.vert +13100 /cid-9584.vert +13101 /cid-9585.vert +13102 /cid-9586.vert +13103 /cid-9587.vert +13104 /cid-9588.vert +13105 /cid-9589.vert +13106 /cid-9590.vert +13107 /cid-9591.vert +13108 /cid-9592.vert +13109 /cid-9593.vert +13110 /cid-9594.vert +13111 /cid-9595.vert +13112 /cid-9596.vert +13113 /cid-9597.vert +13114 /cid-9598.vert +13115 /cid-9599.vert +13116 /cid-9600.vert +13117 /cid-9601.vert +13118 /cid-9602.vert +13119 /cid-9603.vert +13120 /cid-9604.vert +13121 /cid-9605.vert +13122 /cid-9606.vert +13123 /cid-9607.vert +13124 /cid-9608.vert +13125 /cid-9609.vert +13126 /cid-9610.vert +13127 /cid-9611.vert +13128 /cid-9612.vert +13129 /cid-9613.vert +13130 /cid-9614.vert +13131 /cid-9615.vert +13132 /cid-9616.vert +13133 /cid-9617.vert +13134 /cid-9618.vert +13135 /cid-9619.vert +13136 /cid-9620.vert +13137 /cid-9621.vert +13138 /cid-9622.vert +13139 /cid-9623.vert +13140 /cid-9624.vert +13141 /cid-9625.vert +13142 /cid-9626.vert +13143 /cid-9627.vert +13144 /cid-9628.vert +13145 /cid-9629.vert +13146 /cid-9630.vert +13147 /cid-9631.vert +13148 /cid-9632.vert +13149 /cid-9633.vert +13150 /cid-9634.vert +13151 /cid-9635.vert +13152 /cid-9636.vert +13153 /cid-9637.vert +13154 /cid-9638.vert +13155 /cid-9639.vert +13156 /cid-9640.vert +13157 /cid-9641.vert +13158 /cid-9642.vert +13159 /cid-9643.vert +13160 /cid-9644.vert +13161 /cid-9645.vert +13162 /cid-9646.vert +13163 /cid-9647.vert +13164 /cid-9648.vert +13165 /cid-9649.vert +13166 /cid-9650.vert +13167 /cid-9651.vert +13168 /cid-9652.vert +13169 /cid-9653.vert +13170 /cid-9654.vert +13171 /cid-9655.vert +13172 /cid-9656.vert +13173 /cid-9657.vert +13174 /cid-9658.vert +13175 /cid-9659.vert +13176 /cid-9660.vert +13177 /cid-9661.vert +13178 /cid-9662.vert +13179 /cid-9663.vert +13180 /cid-9664.vert +13181 /cid-9665.vert +13182 /cid-9666.vert +13183 /cid-9667.vert +13184 /cid-9668.vert +13185 /cid-9669.vert +13186 /cid-9670.vert +13187 /cid-9671.vert +13188 /cid-9672.vert +13189 /cid-9673.vert +13190 /cid-9674.vert +13191 /cid-9675.vert +13192 /cid-9676.vert +13193 /cid-9677.vert +13194 /cid-9678.vert +13195 /cid-9679.vert +13196 /cid-9680.vert +13197 /cid-9681.vert +13198 /cid-9682.vert +13199 /cid-9683.vert +13200 /cid-9684.vert +13201 /cid-9685.vert +13202 /cid-9686.vert +13203 /cid-9687.vert +13204 /cid-9688.vert +13205 /cid-9689.vert +13206 /cid-9690.vert +13207 /cid-9691.vert +13208 /cid-9692.vert +13209 /cid-9693.vert +13210 /cid-9694.vert +13211 /cid-9695.vert +13212 /cid-9696.vert +13213 /cid-9697.vert +13214 /cid-9698.vert +13215 /cid-9699.vert +13216 /cid-9700.vert +13217 /cid-9701.vert +13218 /cid-9702.vert +13219 /cid-9703.vert +13220 /cid-9704.vert +13221 /cid-9705.vert +13222 /cid-9706.vert +13223 /cid-9707.vert +13224 /cid-9708.vert +13225 /cid-9709.vert +13226 /cid-9710.vert +13227 /cid-9711.vert +13228 /cid-9712.vert +13229 /cid-9713.vert +13230 /cid-9714.vert +13231 /cid-9715.vert +13232 /cid-9716.vert +13233 /cid-9717.vert +13234 /cid-9718.vert +13235 /cid-9719.vert +13236 /cid-9720.vert +13237 /cid-9721.vert +13238 /cid-9722.vert +13239 /cid-9723.vert +13240 /cid-9724.vert +13241 /cid-9725.vert +13242 /cid-9726.vert +13243 /cid-9727.vert +13244 /cid-9728.vert +13245 /cid-9729.vert +13246 /cid-9730.vert +13247 /cid-9731.vert +13248 /cid-9732.vert +13249 /cid-9733.vert +13250 /cid-9734.vert +13251 /cid-9735.vert +13252 /cid-9736.vert +13253 /cid-9737.vert +13254 /cid-9738.vert +13255 /cid-9739.vert +13256 /cid-9740.vert +13257 /cid-9741.vert +13258 /cid-9742.vert +13259 /cid-9743.vert +13260 /cid-9744.vert +13261 /cid-9745.vert +13262 /cid-9746.vert +13263 /cid-9747.vert +13264 /cid-9748.vert +13265 /cid-9749.vert +13266 /cid-9750.vert +13267 /cid-9751.vert +13268 /cid-9752.vert +13269 /cid-9753.vert +13270 /cid-9754.vert +13271 /cid-9755.vert +13272 /cid-9756.vert +13273 /cid-9757.vert +13274 /cid-9758.vert +13275 /cid-9759.vert +13276 /cid-9760.vert +13277 /cid-9761.vert +13278 /cid-9762.vert +13279 /cid-9763.vert +13280 /cid-9764.vert +13281 /cid-9765.vert +13282 /cid-9766.vert +13283 /cid-9767.vert +13284 /cid-9768.vert +13285 /cid-9769.vert +13286 /cid-9770.vert +13287 /cid-9771.vert +13288 /cid-9772.vert +13289 /cid-9773.vert +13290 /cid-9774.vert +13291 /cid-9775.vert +13292 /cid-9776.vert +13293 /cid-9777.vert +13294 /cid-9778.vert +13320 fa67 +13321 fa62 +13322 7de3 +13323 9ec3 +13324 6eab +13325 fa52 +13326 fa3d +13327 fa45 +13328 fa3e +13329 69ea +13330 6e34 +13331 fa60 +13332 fa47 +13333 fa38 +13334 fa42 +13335 fa4e +13336 865b +13337 fa69 +13338 fa34 +13339 fa63 +13340 63ed +13341 64ca +13342 784f +13343 fa54 +13344 f970 +13345 fa4d +13346 fa61 +13347 fa48 +13348 fa4c +13349..13350 fa5b +13351 fa51 +13352 fa43 +13353 fa5a +13354 6d89 +13355 72c0 +13357 2f945 +13358 fa56 +13359 fa50 +13360 fa31 +13361 fa3b +13362 5de2 +13363 fa3f +13364 fa65 +13365 537d +13366 fa37 +13367 fa5f +13368 5fb5 +13369 fa40 +13371 fa53 +13372 9b2d +13373 fa55 +13374 fa68 +13375 fa44 +13376 fa59 +13377 665a +13378 fa35 +13379 fa4b +13380 fa64 +13381 fa41 +13382 fa30 +13383 5002 +13384 fa39 +13385 fa33 +13386 6b65 +13387 fa3a +13388 6bcf +13389 fa32 +13390 623e +13391 fa4f +13392 f91d +13393 /uniF9DC.dup2 +13394 f936 +13395 6dda +13396 f9d0 +13397 66c6 +13398 6b77 +13399 fa57 +13400 934a +13402 9304 +13523 2090e +13644 8c9f +13645 2ed7 +13646 26951 +13652 92b3 +13653 95b1 +13656 2f8fc +13670 2f995 +13679 2f8ea +13681 676e +13682 2ec6 +13684 2f822 +13698 3402 +13701 65e3 +13706 20bb7 +13717 29d4b +13719 2f833 +13720 5f3a +13729 2ea9 +13731 4ff1 +13739 f909 +13747 2ebc +13750 2f8ac +13751 6743 +13755 20a64 +13756 8a01 +13757 6236 +13760 5433 +13761 5a1b +13765 6285 +13768 2f903 +13775 543f +13785 6b72 +13790 7522 +13791 4b38 +13794 5dff +13801 2f90b +13802 73ba +13803 20b9f +13807 2f828 +13809 2f921 +13815 2f83f +13832 2f873 +13833..13834 2e8c +13835 5c19 +13839 2000b +13840 5b82 +13841 2f852 +13847 2edd +13848 98e0 +13849 2967f +13850 378d +13852 38fa +13854 2f947 +13856 4ebb +13857 201a2 +13865 351f +13867 2f8b2 +13870 8980 +13875 7a05 +13880 8aaa +13882 7d55 +13884 6f98 +13892 63f7 +13893 /uni7626.dup2 +13898 27fb7 +13904 23cfe +13910 3427 +13913 812b +13916 2f91a +13922 2eae +13928 2f89a +13932 2f90f +13952 5721 +13953 2123d +13954 2f81a +13956 fa03 +13964 541e +13965 3b88 +13966 5167 +13971 f95f +13981 4e37 +13995 24d14 +13996 5f65 +13997 59ec +13998 2f862 +14000 5e99 +14047 3468 +14056 52d0 +14066 /uni6801.dup2 +14068 2f9d0 +14069 2f9df +14075 2567f +14078 2eb7 +14083 8eb6 +14084 f91f +14088 f983 +14094 7c7b +14095 f9a2 +14097 f99a +14099 8002 +14100 266b0 +14105 20628 +14108 2008a +14109 2f82c +14110 353e +14115 5455 +14117 5939 +14120 5b76 +14121 2f86d +14122 5c14 +14123 37e2 +14124 5ce6 +14126 4e48 +14129 2f8b6 +14134 26999 +14135 631b +14138 6663 +14140 2f8db +14143 69f6 +14144 6986 +14148 6bcc +14150 6e17 +14153 6caa +14157 4e2c +14160 74ef +14161 7575 +14162 75ec +14163 764e +14164 3fb1 +14165 776a +14166 77a9 +14173 7b53 +14176 4264 +14180 2f96c +14183 7e48 +14189 2eb3 +14194 8141 +14195 4453 +14197 8279 +14198 fa5e +14199 fa5d +14201 5179 +14202 835a +14206 4525 +14208 85f4 +14209 200b0 +14214 867d +14216 342e +14217 88c6 +14224 47e6 +14233 8fc8 +14253 28987 +14256 28e17 +14259 9839 +14266 9a08 +14271 9bdf +14282 242ee +14288 5389 +14290 /uniFA11.dup2 +14291 2f8e1 +14293 23cbe +14294 20611 +14296..14297 4e04 +14298 4e1f +14299 4e2b +14300..14301 4e2f +14302..14303 4e40 +14304 4e44 +14305 4e5a +14306 4e7f +14307 4e8d +14308 4e96 +14309 4eb9 +14310 4ed0 +14311 4ee0 +14312 4efd +14313 4eff +14314 4f0b +14315 4f15 +14316 4f60 +14317 4f3b +14318 4f49 +14319 4f54 +14320 4f7a +14321..14322 4f7d +14323 4f97 +14324 4fbe +14325 4fcf +14326 4ffd +14327..14328 5000 +14329 5010 +14330 501b +14331 5027 +14332 502e +14333 5057 +14334 5066 +14335 506a +14336 503b +14337 508f +14338 5096 +14339 509c +14340 50cc +14341 50e6 +14342 50e9 +14343 50ef +14344 5108 +14345 510b +14346 5110 +14347 511b +14348 511e +14349 515f +14350 51a1 +14351 51bc +14352 51de +14353 51ee +14354 51f4 +14355..14356 5201 +14357 5213 +14358 5249 +14359 5261 +14360 5266 +14361 5293 +14362 52c8 +14363 52f0 +14364..14365 530a +14366 533e +14367 534c +14368 534b +14369 5361 +14370 536c +14371 53ab +14372 53da +14373 53e6 +14374 53f5 +14375 5427 +14376 544d +14377 5466 +14378 546b +14379 5474 +14380 548d +14381 5496 +14382 54a1 +14383 54ad +14384 54b9 +14385 54bf +14386 54c6 +14387 54cd +14388 550e +14389 552b +14390 5535 +14391 554a +14392..14393 5560 +14394 5588 +14395 558e +14396 5608 +14397..14398 560e +14399 5637 +14400 563f +14401 5649 +14402 564b +14403 564f +14404 5666 +14405 5669 +14406 566f +14407..14408 5671 +14409 5695 +14410 569a +14411..14412 56ac +14413 56b1 +14414 56c9 +14415 56dd +14416 56e4 +14417 570a +14418 5715 +14419 5723 +14420 572f +14421..14422 5733 +14423 574c +14424 5770 +14425 578c +14426 579c +14427 57b8 +14428 57e6 +14429 57ed +14430..14431 57f5 +14432 57ff +14433 5809 +14434 5820 +14435 5832 +14436 587c +14437 5880 +14438 58a9 +14439 58ce +14440 58d0 +14441 58d4 +14442 58da +14443 58e9 +14444 590c +14445 5924 +14446 592f +14447 5961 +14448 596d +14449 59ca +14450 59d2 +14451 59dd +14452..14453 59e3 +14454 5a04 +14455 5a0c +14456 5a23 +14457 5a47 +14458 5a55 +14459 5a63 +14460 5a6d +14461 5a7e +14462 5a9e +14463 5aa7 +14464 5aac +14465 5ab3 +14466 5ae0 +14467 5b00 +14468 5b19 +14469 5b25 +14470 5b2d +14471 5b41 +14472 5b7c +14473..14474 5b7e +14475 5b8a +14476 5c23 +14477 5c2b +14478 5c30 +14479 5c63 +14480 5c69 +14481 5c7c +14482 5ccb +14483 5cd2 +14484 5cf4 +14485 5d24 +14486 5d26 +14487 5d43 +14488 5d46 +14489 5d4a +14490 5d92 +14491 5d94 +14492 5d99 +14493 5da0 +14494 5dd8 +14495 5de0 +14496 5df8 +14497 5e00 +14498 5e12 +14499..14500 5e14 +14501 5e18 +14502 5e2e +14503 5e58 +14504..14505 5e6b +14506 5ea8 +14507 5eaa +14508..14509 5ebe +14510 5ecb +14511 5ed2 +14512 5f07 +14513 5f0e +14514..14515 5f1c +14516 5f22 +14517 5f28 +14518 5f36 +14519 5f3b +14520 5f40 +14521 5f50 +14522 5f58 +14523 5f64 +14524 5f89 +14525 5f9c +14526 5fa7 +14527 5fa4 +14528 5faf +14529 5fb8 +14530 5fc4 +14531 5fc9 +14532 5fe1 +14533 5fe9 +14534 5fed +14535 5ffc +14536 6017 +14537 601a +14538 6033 +14539 6061 +14540 607f +14541 609e +14542 60a4 +14543 60b0 +14544 60cb +14545 60db +14546 60f8 +14547..14549 6112 +14550 611c +14551 617c +14552 618d +14553 619f +14554 61a8 +14555 61c2 +14556 61df +14557 6215 +14558 6229 +14559 6243 +14560 6246 +14561 624c +14562 6251 +14563 6256 +14564 62c4 +14565 62fc +14566 630a +14567 630d +14568 6318 +14569 6339 +14570..14571 6342 +14572 6365 +14573 6374 +14574 637d +14575 6384 +14576 6387 +14577 6390 +14578 639e +14579 63d1 +14580 63dc +14581 6409 +14582 6410 +14583 6422 +14584 6454 +14585 645b +14586 646d +14587 647b +14588..14589 64be +14590 64e5 +14591 64f7 +14592 64fb +14593 6504 +14594 6516 +14595 6519 +14596 6547 +14597 6567 +14598 6581 +14599 6585 +14600 65c2 +14601 65f0 +14602 65f2 +14603 662c +14604 664c +14605..14606 665b +14607 6661 +14608 666b +14609 6677 +14610 66a4 +14611 66c8 +14612 66ec +14613 6705 +14614 6713 +14615 6733 +14616 6748 +14617 674c +14618 6776 +14619 677b +14620 67b0 +14621 67b2 +14622 67f9 +14623 67d7 +14624 67d9 +14625 67f0 +14626 682c +14627..14628 6830 +14629 685b +14630 6872 +14631 6875 +14632 687a +14633 6884 +14634 68a5 +14635 68b2 +14636 68d0 +14637 68d6 +14638 68e8 +14639 68ed +14640..14641 68f0 +14642 68fc +14643 6911 +14644 6913 +14645 6935 +14646 693b +14647 6957 +14648 6963 +14649 6972 +14650..14651 697f +14652 69a6 +14653 69ad +14654 69b7 +14655..14656 69d6 +14657 6a01 +14658 6a0f +14659 6a15 +14660 6a28 +14661 6a34 +14662 6a3e +14663 6a45 +14664..14665 6a50 +14666 6a56 +14667 6a5b +14668 6a83 +14669 6a89 +14670 6a91 +14671..14673 6a9d +14674 6adc +14675 6ae7 +14676 6aec +14677 6b1e +14678 6b24 +14679 6b35 +14680 6b46 +14681 6b56 +14682 6b60 +14683 6b82 +14684 6bbe +14685 6be1 +14686 6bf1 +14687 6c10 +14688 6c33 +14689 6c35 +14690 2ea2 +14691 6c59 +14692 6c76 +14693 6c7b +14694 6c85 +14695 6c95 +14696 6c9c +14697 6cd0 +14698 6cd4 +14699 6cd6 +14700 6ce0 +14701..14702 6ceb +14703 6cee +14704 6d0a +14705 6d0e +14706 6d11 +14707 6d2e +14708 6d57 +14709 6d5e +14710 6d65 +14711 6d82 +14712 6dbf +14713 6dc4 +14714 6dca +14715 6dd6 +14716 6de9 +14717 6e22 +14718 6e51 +14719 6ec7 +14720 6eca +14721 6ece +14722 6efd +14723 6f1a +14724 6f2a +14725 6f2f +14726 6f33 +14727 6f5a +14728 6f5e +14729 6f62 +14730 6f7d +14731 6f8b +14732 6f8d +14733 6f92 +14734 6f94 +14735 6f9a +14736..14737 6fa7 +14738 6fb6 +14739 6fda +14740 6fde +14741 6ff9 +14742 7039 +14743 703c +14744 704a +14745 7054 +14746..14747 705d +14748 7064 +14749 706c +14750 707e +14751 7081 +14752 7095 +14753 70b7 +14754..14755 70d3 +14756 70d8 +14757 70dc +14758 7107 +14759 7120 +14760 7131 +14761 714a +14762 7152 +14763 7160 +14764 7179 +14765 7192 +14766 71b3 +14767 71cb +14768 71d3 +14769 71d6 +14770 7200 +14771 721d +14772 722b +14773 7238 +14774 7241 +14775 7253 +14776..14777 7255 +14778 725c +14779 728d +14780 72ad +14781 72b4 +14782 72c7 +14783 72fb +14784..14785 7304 +14786 7328 +14787 7331 +14788 7343 +14789 736c +14790 737c +14791 7383 +14792..14793 7385 +14794 7395 +14795..14797 739e +14798 73a6 +14799 73ab +14800 73b5 +14801 73b7 +14802 73bc +14803 73cf +14804 73d9 +14805 73e9 +14806 73f4 +14807 73fd +14808 7404 +14809 740a +14810..14811 741a +14812 7424 +14813 7428 +14814 742c +14815..14817 742f +14818 7439 +14819 7444 +14820 7447 +14821 744b +14822 744d +14823 7451 +14824 7457 +14825 7466 +14826 746b +14827 7471 +14828 7480 +14829..14831 7485 +14832 7490 +14833 7498 +14834 749c +14835 74a0 +14836 74a3 +14837 74a8 +14838 74ab +14839 74b5 +14840 74bf +14841 74c8 +14842 74da +14843 74de +14844 754e +14845 7579 +14846 7581 +14847 7590 +14848..14849 7592 +14850 75b4 +14851 75e4 +14852 75f9 +14853 7600 +14854 760a +14855..14856 7615 +14857 7619 +14858 761e +14859 762d +14860 7635 +14861 7643 +14862 764b +14863 7665 +14864 766d +14865 766f +14866 7671 +14867 7674 +14868..14869 76a4 +14870 76c5 +14871 76cc +14872 76ec +14873 76fc +14874 7734 +14875 7736 +14876 775c +14877..14878 775f +14879 7772 +14880 777d +14881 7795 +14882 77aa +14883 77e6 +14884 77f0 +14885 77f4 +14886 7806 +14887 7822 +14888..14889 782d +14890 7830 +14891 7835 +14892 7868 +14893 789e +14894 78c8 +14895 78cc +14896 78ce +14897 78e4 +14898..14899 78e0 +14900 78f2 +14901 78f7 +14902 78fb +14903 7931 +14904 7934 +14905 793b +14906 793d +14907 7945 +14908..14909 795b +14910 798b +14911 7996 +14912 7998 +14913 79b8 +14914 79bb +14915 79ca +14916 79da +14917 7a03 +14918 7a09 +14919 7a11 +14920 7a1e +14921 7a2d +14922 7a39 +14923 7a45 +14924 7a4c +14925 7a5d +14926 7a60 +14927 7a6d +14928 7a78 +14929 7aa0 +14930 7aa3 +14931 7ab3 +14932..14933 7abb +14934 7ac6 +14935 7b07 +14936 7b14 +14937 7b27 +14938 7b31 +14939 7b47 +14940 7b4e +14941 7b60 +14942 7b69 +14943 7b6d +14944 7b72 +14945 7b91 +14946 7baf +14947 7bd7 +14948 7bd9 +14949 7c0b +14950 7c0f +14951 7c20 +14952 7c26 +14953 7c31 +14954 7c36 +14955 7c51 +14956 7c59 +14957 7c67 +14958 7c6e +14959 7c70 +14960 7cbc +14961 7cbf +14962..14963 7cc8 +14964 7cd7 +14965 7cd9 +14966 7cdd +14967 7ceb +14968..14970 7d07 +14971 7d13 +14972 7d1d +14973 7d23 +14974 7d41 +14975 7d53 +14976 7d59 +14977 7d5d +14978 7d7a +14979 7d86 +14980..14981 7d8b +14982 7dcc +14983 7deb +14984 7df1 +14985 7df9 +14986 7e08 +14987 7e11 +14988 7e15 +14989 7e20 +14990 7e47 +14991 7e62 +14992 7e6e +14993 7e73 +14994 7e8d +14995 7e91 +14996 7e98 +14997 7f44 +14998 7f4f +14999..15000 7f52 +15001 7f61 +15002 7f91 +15003 7fbf +15004 7fce +15005 7fdf +15006 7fe5 +15007 7fec +15008..15009 7fee +15010 7ffa +15011 800e +15012 8011 +15013 8014 +15014 8024 +15015 8026 +15016 803a +15017 803c +15018 8060 +15019 8071 +15020 8075 +15021 809e +15022 80a6 +15023 80ab +15024..15025 80d7 +15026 8116 +15027 8118 +15028 813a +15029 814a +15030 814c +15031 8181 +15032 8184 +15033 81b4 +15034 81cf +15035 81f9 +15036 8203 +15037 8221 +15038 8232 +15039 8234 +15040 8246 +15041 824b +15042 824f +15043 828e +15044 82ae +15045 82b7 +15046 82be +15047 82c6 +15048 82fe +15049 8343 +15050 8351 +15051 8355 +15052 8386 +15053 838d +15054 8392 +15055 8398 +15056 83a9 +15057..15058 83bf +15059 83ea +15060 840f +15061 8411 +15062 844a +15063 8476 +15064 84a8 +15065 84af +15066 84c0 +15067 84c2 +15068 84f0 +15069 84fd +15070 850c +15071 8534 +15072 855e +15073 858f +15074 85b7 +15075 85ce +15076 85ad +15077 8612 +15078 8629 +15079 8652 +15080 8663 +15081 866c +15082 866f +15083 867a +15084 868d +15085 8691 +15086 8698 +15087..15088 86a7 +15089 86fa +15090 86fd +15091 870b +15092 8713 +15093 8719 +15094 871e +15095 8728 +15096 873e +15097 8771 +15098 8788 +15099 8799 +15100..15101 87ac +15102 87b5 +15103 87d6 +15104 87eb +15105 87ed +15106 8801 +15107 8803 +15108 8806 +15109 880b +15110 8814 +15111 881c +15112 8856 +15113 885f +15114 8864 +15115 8898 +15116 88aa +15117..15118 88bd +15119 88ca +15120 88d2 +15121 88db +15122..15123 88f0 +15124 8906 +15125..15127 8918 +15128 8927 +15129 8930 +15130 893e +15131 897b +15132 89d4 +15133 89d6 +15134 89e5 +15135 89f1 +15136 8a07 +15137 8a0f +15138 8a15 +15139 8a22 +15140 8a4e +15141 8a7f +15142 8af4 +15143 8b1f +15144 8b37 +15145..15146 8b43 +15147 8b54 +15148 8b9c +15149 8b9e +15150 8c47 +15151 8c54 +15152 8c73 +15153 8ca4 +15154 8cd9 +15155 8ce1 +15156 8cf8 +15157 8cfe +15158 8d1b +15159 8d69 +15160 8d6c +15161 8d84 +15162 8d8d +15163 8d95 +15164 8da6 +15165 8dc6 +15166 8dce +15167 8de4 +15168 8dec +15169 8e20 +15170 8e4b +15171 8e6c +15172 8e70 +15173 8e7a +15174 8e92 +15175 8eae +15176 8eb3 +15177 8ed1 +15178 8ed4 +15179 8ef9 +15180 8f17 +15181 8f36 +15182 8fa6 +15183..15184 8fb5 +15185 8fc6 +15186 8fe0 +15187 8fe4 +15188 8ff6 +15189 9002 +15190 902c +15191 9044 +15192 9088 +15193 9095 +15194 9099 +15195 909b +15196 90a2 +15197 90b4 +15198 90d7 +15199 90dd +15200 90f4 +15201 9117 +15202 911c +15203 9131 +15204 913a +15205 913d +15206 9148 +15207 915b +15208 9161 +15209 9164 +15210 918e +15211 919e +15212 91a8 +15213..15214 91ad +15215 91b2 +15216 91bc +15217 91f0 +15218 91f7 +15219 91fb +15220 9207 +15221 9228 +15222 9233 +15223 9238 +15224 9243 +15225 9247 +15226 924f +15227 9260 +15228 92c2 +15229..15230 92cb +15231 92df +15232 930d +15233 9315 +15234 931f +15235 9327 +15236 9347 +15237 9352 +15238 9365 +15239 936a +15240 936d +15241 939b +15242 93ba +15243 93a9 +15244 93c1 +15245 93ca +15246 93e2 +15247 93fa +15248 93fd +15249 940f +15250 9434 +15251 943f +15252 9455 +15253 946b +15254 9472 +15255 9578 +15256 95a6 +15257 95a9 +15258 95ab +15259 95b4 +15260 95bd +15261 95da +15262 961d +15263 9641 +15264 9658 +15265 9684 +15266 96a4 +15267 96a9 +15268 96d2 +15269 2f9f4 +15270 96de +15271 96e9 +15272 96f1 +15273 9702 +15274 9709 +15275 975a +15276 9763 +15277 976e +15278 9773 +15279 979a +15280 97a2 +15281..15282 97b5 +15283 97d9 +15284 97de +15285 97f4 +15286 980a +15287 980e +15288 981e +15289 9823 +15290 982b +15291 983e +15292..15293 9852 +15294 9859 +15295 986c +15296 98b8 +15297 98ba +15298 98bf +15299 98c8 +15300 98e5 +15301..15302 9932 +15303 9940 +15304 994d +15305 995c +15306 995f +15307 99b1 +15308..15309 99b9 +15310 99c9 +15311 9a02 +15312 9a16 +15313 9a24 +15314 9a27 +15315..15316 9a2d +15317 9a36 +15318 9a38 +15319 9a4a +15320 9a56 +15321..15322 9ab5 +15323 9af9 +15324 9b03 +15325 9b20 +15326..15327 9b33 +15328 9b73 +15329 9b79 +15330 9ba7 +15331 9bc1 +15332 9bc7 +15333 9bd7 +15334 9be7 +15335 9beb +15336 9bf7 +15337 9bfa +15338 9bfd +15339 9c0b +15340 9c27 +15341 9c2a +15342 9c36 +15343 9c41 +15344 9c53 +15345 9c63 +15346 9c70 +15347 9c77 +15348 9d02 +15349 9d42 +15350 9d47 +15351 9d63 +15352 9d69 +15353 9d7c +15354 9d7e +15355 9d8d +15356 9db1 +15357 9dc3 +15358 9dc7 +15359 9dd6 +15360 9ddf +15361 9deb +15362 9df4 +15363 9e15 +15364 9e1d +15365 9ea4 +15366 9ea8 +15367 9eac +15368 9ee7 +15369 9eee +15370 9f10 +15371 9f12 +15372 9f17 +15373 9f19 +15374 9f2f +15375 9f37 +15376 9f39 +15377 9f41 +15378 9f45 +15379 9f57 +15380 9f68 +15381 9f71 +15382 9f75 +15383 9f90 +15384 9f94 +15385 9fa2 +15387 3405 +15388 2f804 +15389 5620 +15390 /uni5ECB.dup2 +15391 2e95 +15393 2363a +15395 /uni6FF9.dup2 +15396 6ee6 +15397 /uni71B3.dup2 +15398 fa49 +15403 fa66 +15405 5db2 +15407 4fd3 +15408 50d9 +15409 50f0 +15410 51c3 +15411 5676 +15412 6a54 +15413 6d01 +15414 6dd0 +15415 6e42 +15416 6ed9 +15417 73e4 +15418 7421 +15419 756c +15420 7851 +15421 87f5 +15422 233fe +15423 73a8 +15424 3af3 +15425 34db +15426 440c +15427 3e8a +15430 4be8 +15432 3eda +15433 3b22 +15435 457a +15436 4093 +15438 4665 +15439 4103 +15440 4293 +15441 46ae +15442 3488 +15443 22609 +15444..15446 f860 +15447 f87a +15448 f87f +15472..15473 2284 +15474..15475 228a +15476 2209 +15478..15479 2305 +15489..15490 2225 +15505 2262 +15507 2245 +15508 2248 +15509..15510 2276 +15515 2127 +15725..15726 22da +15727 2155 +15728 2318 +15729..15730 1e3e +15731..15732 01f8 +15733 01d6 +15734 01d8 +15735 01da +15736 01dc +15737 0104 +15738 02d8 +15739 013d +15740 015a +15741 015e +15742 0164 +15743 0179 +15744 017b +15745 0105 +15746 02db +15747 013e +15748 015b +15749 02c7 +15750 015f +15751 0165 +15752 017a +15753 02dd +15754 017c +15755 0154 +15756 0102 +15757 0139 +15758 0106 +15759 010c +15760 0118 +15761 010e +15762 0143 +15763 0147 +15764 0150 +15765 0158 +15766 0170 +15767 0162 +15768 0155 +15769 0103 +15770 013a +15771 0107 +15772 010d +15773 0119 +15774 010f +15775 0111 +15776 0144 +15777 0148 +15778 0151 +15779 0159 +15780 0171 +15781 0163 +15782 02d9 +15783 0108 +15784 011c +15785 0124 +15786 0134 +15787 015c +15788 016c +15789 0109 +15790 011d +15791 0125 +15792 0135 +15793 015d +15794 016d +15795 0271 +15796 028b +15797 027e +15798 026c +15799 026e +15800 0279 +15801 0288 +15802 0256 +15803 0273 +15804 027d +15805 0282 +15806 0290 +15807 027b +15808 026d +15809 025f +15810 0272 +15811 029d +15812 028e +15813 0261 +15814 0270 +15815 0281 +15816 0127 +15817 0295 +15818 0294 +15819 0266 +15820 0298 +15821 01c2 +15822 0253 +15823 0257 +15824 0284 +15825 0260 +15826 0193 +15827 0268 +15828 0289 +15829 0258 +15830 025c +15831 025e +15832 0250 +15833 026f +15834 028a +15835 0264 +15836 0252 +15837 028d +15838 0265 +15839 02a2 +15840 02a1 +15841 0255 +15842 0291 +15843 027a +15844 0267 +15845 0361 +15846 02c8 +15847 02cc +15848 02d1 +15849 203f +15850 030f +15851..15855 02e5 +15858 0325 +15859 032c +15860 0339 +15861 031c +15862..15863 031f +15864 033d +15865 0329 +15866 032f +15867 02de +15868 0324 +15869 0330 +15870 033c +15871 0334 +15872..15873 031d +15874..15875 0318 +15876 032a +15877..15878 033a +15879 031a +15883..15884 0262 +15885 026a +15886 0274 +15887 0276 +15888 0278 +15889 0280 +15890 028f +15891 0299 +15892 029c +15893 029f +15894 02b0 +15895 02b2 +15896 02b7 +15897 02c0 +15898..15899 02e0 +15906 /uni229E.dup2 +16194 303c +16195 30ff +16197..16198 3016 +16199 266e +16200 266b +16201..16202 2934 +16203 29bf +16205 30a0 +16207..16208 29fa +16222 03c2 +16223..16232 24f5 +16233..16234 2616 +16235 25b1 +16236..16245 31f0 +16247..16252 31fa +16253..16267 23be +16270 2713 +16272 2423 +16273 23ce +16274..16277 25d0 +16278..16279 2047 +16281 2051 +16282 2042 +16283..16298 3190 +16312..16313 23b0 +16314..16325 2672 +16326..16327 3099 +16328 20dd +16329 /cid-16197.vert +16330 /cid-16198.vert +16331 /cid-16205.vert +16333 /cid-16236.vert +16334 /cid-16237.vert +16335 /cid-16238.vert +16336 /cid-16239.vert +16337 /cid-16240.vert +16338 /cid-16241.vert +16339 /cid-16242.vert +16340 /cid-16243.vert +16341 /cid-16244.vert +16342 /cid-16245.vert +16344 /cid-16247.vert +16345 /cid-16248.vert +16346 /cid-16249.vert +16347 /cid-16250.vert +16348 /cid-16251.vert +16349 /cid-16252.vert +16350 /cid-16312.vert +16351 /cid-16313.vert +16779 4f48 +16780 4f5f +16781 4f6a +16782 4f6c +16783 500e +16784 5018 +16785 5041 +16786 50f2 +16787 50d0 +16788 5106 +16789 5103 +16790 5135 +16791 5155 +16792 5157 +16793 34b5 +16794 51ca +16795 51e2 +16796 5257 +16797 52cc +16798 52d6 +16799 52fb +16800 531c +16801 5363 +16802 539d +16803 5412 +16804 547f +16805 5488 +16806 5550 +16807 5581 +16808 55ad +16809 55ce +16810 563b +16811 569e +16812 56a9 +16813 56b3 +16814 5777 +16815 577c +16816 2131b +16817 57cf +16818 57e4 +16819 5864 +16820 5889 +16821 2146e +16822 58d2 +16823 58e0 +16824 8641 +16825 598b +16826 5992 +16827 59c3 +16828 5a13 +16829 5a67 +16830 5a77 +16831 5a84 +16832 5ac4 +16833 218bd +16834 5b7d +16835 5b93 +16836 5c12 +16837 fa3c +16838 216b4 +16839 5c7a +16840 5c8f +16841 5c9f +16842 5ca3 +16843 5caa +16844 5cd0 +16845 21e34 +16846 5d0d +16847 5d47 +16848 5d81 +16849 5da4 +16850 5da7 +16851 5dcb +16852 5e5e +16853 5ef9 +16854 5f00 +16855 5f02 +16856 5f23 +16857 5f3d +16858 5f54 +16859 5f7d +16860 600d +16861 6014 +16862 6018 +16863 6035 +16864 6047 +16865 609d +16866 60d4 +16867 60dd +16868 612b +16869 61bc +16870 61b9 +16871 6222 +16872 625a +16873 626f +16874 62d6 +16875 637c +16876 63e5 +16877 6479 +16878 64c4 +16879 64d0 +16880 6529 +16881 659d +16882 663a +16883 6622 +16884 662b +16885 6630 +16886 6633 +16887 6648 +16888 231c4 +16889 /uni6677.dup2 +16890 6678 +16891 668d +16892 66bb +16893 66db +16894 66e8 +16895 6747 +16896 6781 +16897 6793 +16898 6798 +16899 679b +16900 67fc +16901 681d +16902 68a3 +16903 690a +16904 6949 +16905 235c4 +16906 6942 +16907 6964 +16908 69a5 +16909 69cf +16910 3bb6 +16911 3bc3 +16912 69e9 +16913 69f5 +16914 2373f +16915 6a3b +16916 23763 +16917 6a94 +16918 6aa5 +16919 3c0f +16920 6b1b +16921 6b2c +16922 6b67 +16923 6ba9 +16924 6bad +16925 6bd7 +16926 6bff +16927 6c05 +16928 6c74 +16929 6c98 +16930 6cfb +16931 6cc6 +16932 6d31 +16933 6d39 +16934 6d3f +16935 6d58 +16936 6d94 +16937 6daa +16938 6ddb +16939 6ddd +16940 6e44 +16941 6e5e +16942 6eb1 +16943 6ec1 +16944 6f10 +16945 6f59 +16946 6f61 +16947 6f7e +16948 6f8c +16949 6fa0 +16950 6fbc +16951 6fc7 +16952 6fca +16953 6ff0 +16954 704e +16955 7075 +16956 70a4 +16957 70e4 +16958 712b +16959 711e +16960 712e +16961 7151 +16962 7168 +16963 7185 +16964 7187 +16965 71ba +16966 71c4 +16967 7215 +16968 3e3f +16969 729b +16970 247f1 +16971 7327 +16972 7350 +16973 7366 +16974 73a2 +16975 742b +16976 7446 +16977 /uni7462.dup2 +16978 746d +16979 74a6 +16980 74a9 +16981 74c9 +16982 74ff +16983 7517 +16984 3f72 +16985 75ce +16986 7602 +16987 7608 +16988 7664 +16989 7681 +16990 769d +16991 76aa +16992 76b6 +16993 76ce +16994 76d4 +16995 76e6 +16996 76f1 +16997 770a +16998 7719 +16999..17000 774d +17001 777a +17002 7780 +17003 7794 +17004 77e0 +17005 2548e +17006 7843 +17007 786e +17008 78b0 +17009 2550e +17010 78ad +17011 7900 +17012 791c +17013 792e +17014 /uni7934.dup2 +17015 7946 +17016 7979 +17017 79c8 +17018 25771 +17019 79d4 +17020 79de +17021 79eb +17022 79ed +17023 7a85 +17024 259c4 +17025 7ace +17026 7afd +17027 7b12 +17028 7b2d +17029 7b3b +17030 7b6f +17031 7c01 +17032 7c33 +17033 25da1 +17034 7c6d +17035 7c79 +17036 7c8f +17037 7c94 +17038 7ca0 +17039 7cd5 +17040 7d31 +17041 /uni7D5C.dup2 +17042 7d83 +17043 7da6 +17044 7dc2 +17045 7e28 +17046 7f97 +17047 7fdb +17048 8035 +17049 8037 +17050 80ca +17051 80e0 +17052 80f3 +17053 8160 +17054..17055 8167 +17056 816d +17057 81bb +17058 81ca +17059 81d7 +17060 445b +17061 8260 +17062 8274 +17063 26aff +17064 82a1 +17065..17066 82a3 +17067 82a9 +17068 82bf +17069 82d5 +17070 82fd +17071 8300 +17072 8322 +17073 832d +17074 833a +17075 8347 +17076 837d +17077 83a7 +17078 83cf +17079 83d1 +17080 83e1 +17081 8401 +17082 8406 +17083 845f +17084 8470 +17085 8473 +17086 8485 +17087 849e +17088 84ba +17089 26e40 +17090 8532 +17091 851e +17092 852f +17093 8564 +17094 857a +17095 858c +17096 85a2 +17097 85cb +17098 85ed +17099 85ff +17100..17101 8604 +17102 8610 +17103 270f4 +17104 8618 +17105 8638 +17106 8657 +17107 8662 +17108 459d +17109 8675 +17110 86b8 +17111 86fc +17112 8787 +17113 45ea +17114 880a +17115 8810 +17116 88ce +17117 27684 +17118 8932 +17119 8939 +17120 8940 +17121 8994 +17122 89f6 +17123 8a47 +17124 8a5d +17125 8a61 +17126 8a75 +17127 8ad0 +17128 8b46 +17129 8b59 +17130 8b69 +17131 8b9d +17132 8c49 +17133 8c68 +17134 8daf +17135 8dd1 +17136 8dd7 +17137 8e23 +17138 8e3d +17139 8e7b +17140 28277 +17141 4844 +17142 8efa +17143 8f1e +17144 8f2d +17145 8f54 +17146 283cd +17147 8fe8 +17148 8fee +17149 9008 +17150 902d +17151 9097 +17152 90b3 +17153 90be +17154..17155 90c4 +17156 90c7 +17157 90ef +17158 9114 +17159 9116 +17160..17161 9122 +17162 912f +17163 9134 +17164 9183 +17165 91f1 +17166 9349 +17167 9364 +17168 /uni9365.dup2 +17169 93a3 +17170 93df +17171 9404 +17172 9433 +17173 944a +17174 9463 +17175 9471 +17176 958e +17177 959f +17178 95ac +17179 95b6 +17180 95cb +17181 95d0 +17182 95d3 +17183 49b0 +17184 95de +17185 96a5 +17186 96ef +17187 974e +17188 9795 +17189 97ae +17190 97ba +17191 97c1 +17192 97c9 +17193 97db +17194 9856 +17195 98e7 +17196 9958 +17197 9a03 +17198 9ac1 +17199 9ac3 +17200 9ace +17201 9ad6 +17202 9b02 +17203 9b08 +17204 4c17 +17205 /uni9B2D.dup2 +17206 9b5e +17207 9b66 +17208 9b84 +17209 9b8a +17210 9b9e +17211 9bce +17212 9be5 +17213 9bf8 +17214 9c23 +17215..17216 9c4f +17217 9c65 +17218..17219 9d1d +17220 9d43 +17221 9d52 +17222 9d8a +17223 9d96 +17224 9dc0 +17225 9dac +17226 9dbc +17227 2a190 +17228 9de7 +17229 9e07 +17230 9e9e +17231 9eaf +17232 9f97 +17233 20089 +17234 4e02 +17235 4e0f +17236 4e12 +17237 4e29 +17238 4e2e +17239 4e47 +17240 200a2 +17241 4e51 +17242 3406 +17243 200a4 +17244 4e69 +17245 4e9d +17246 342c +17247 4ebc +17248 4ec3 +17249 4ec8 +17250 4eeb +17251 4eda +17252 4ef1 +17253 4ef5 +17254 4f16 +17255 4f64 +17256 4f37 +17257 4f3e +17258 4f58 +17259 20213 +17260..17261 4f77 +17262 4f82 +17263 4f85 +17264 4fe6 +17265 4fb2 +17266 4fc5 +17267 4fcb +17268 4fd2 +17269 346a +17270 4ff2 +17271 5013 +17272 501c +17273 504e +17274 5053 +17275 5063 +17276 50a3 +17277 5088 +17278..17279 5092 +17280 5095 +17281 50aa +17282 2032b +17283 50b1 +17284..17285 50ba +17286 50c4 +17287 50c7 +17288 50f3 +17289 20381 +17290 50ce +17291 20371 +17292 50d4 +17293 50e1 +17294 3492 +17295 203f9 +17296 5117 +17297 2044a +17298 5160 +17299 20509 +17300 5173 +17301 5183 +17302 518b +17303 34bc +17304 5198 +17305 51a3 +17306 51ad +17307 34c7 +17308 205d6 +17309 51f3 +17310 5212 +17311 5216 +17312 2074f +17313 5255 +17314 525c +17315 526c +17316 5277 +17317 5284 +17318 5282 +17319 20807 +17320 5298 +17321 2083a +17322 52a4 +17323..17324 52ba +17325 52ca +17326 52d1 +17327 208b9 +17328 52f7 +17329 5335 +17330 5342 +17331 2097c +17332 2099d +17333 5367 +17334 537a +17335 53a4 +17336 53b4 +17337 20ad3 +17338 53b7 +17339 53c0 +17340 20b1d +17341..17342 355d +17343 53d5 +17344 3563 +17345 53f4 +17346 5424 +17347 5428 +17348 356e +17349 5443 +17350 5462 +17351 546c +17352 5495 +17353 54a0 +17354 54a6 +17355 54ae +17356 54b7 +17357 54ba +17358 54c3 +17359 20d45 +17360 54ec +17361 54ef +17362 54f1 +17363 54f3 +17364..17365 5500 +17366 5509 +17367 553c +17368 5541 +17369 35a6 +17370 5547 +17371 35a8 +17372 5564 +17373 20de1 +17374 557d +17375 5582 +17376 5591 +17377 35c5 +17378 55d2 +17379 20e95 +17380 20e6d +17381 55bf +17382 55c9 +17383 55cc +17384 55d1 +17385 55dd +17386 35da +17387 55e2 +17388 20e64 +17389 55e9 +17390 5628 +17391 20f5f +17392 5607 +17393 5610 +17394 5630 +17395 35f4 +17396 563d +17397 5640 +17398 5647 +17399 565e +17400 5660 +17401 566d +17402 3605 +17403 5688 +17404 568c +17405 569d +17406 56a8 +17407 56b2 +17408 56c5 +17409 56cd +17410 56df +17411 56e8 +17412..17413 56f6 +17414 21201 +17415 21255 +17416 5729 +17417 2127b +17418..17419 5745 +17420 574d +17421 21274 +17422 5768 +17423 576f +17424..17426 5773 +17427 577b +17428 212e4 +17429 212d7 +17430 579a +17431..17432 579d +17433 57a8 +17434 57d7 +17435 212fd +17436 57cc +17437 21336 +17438 21344 +17439 57de +17440 57f0 +17441 364a +17442 57f8 +17443 57fb +17444 57fd +17445 5804 +17446 581e +17447 5827 +17448 5839 +17449 213c4 +17450 5849 +17451 584c +17452 5867 +17453..17454 588a +17455 588d +17456..17457 588f +17458 5894 +17459 589d +17460 58aa +17461 58b1 +17462 2146d +17463 58c3 +17464 58cd +17465 58e2 +17466..17467 58f3 +17468..17469 5905 +17470 590d +17471 5914 +17472 215d7 +17473 3691 +17474 593d +17475 3699 +17476 5946 +17477 3696 +17478 26c29 +17479 595f +17480 21647 +17481..17482 5975 +17483 597c +17484 599f +17485 59ae +17486 59bc +17487 59c8 +17488 59cd +17489 59de +17490 59e7 +17491 59ee +17492 21706 +17493 21742 +17494 36cf +17495 5a0d +17496 5a17 +17497 5a27 +17498 5a2d +17499 5a65 +17500 5a7a +17501 5a8b +17502 5a9c +17503..17504 5a9f +17505 5aa2 +17506 5ab1 +17507 5ab5 +17508 5aba +17509 5abf +17510 5ada +17511 5adc +17512 5ae5 +17513 5af0 +17514 5aee +17515 5af5 +17516 5b08 +17517 5b17 +17518 5b34 +17519 5b4c +17520 5b52 +17521 5b68 +17522 5b6f +17523 5b81 +17524 5b84 +17525 219c3 +17526 5b96 +17527 5bac +17528..17529 3761 +17530 5bce +17531 5bd6 +17532 376c +17533 376b +17534 5bf1 +17535 5bfd +17536 3775 +17537 5c03 +17538 5c29 +17539 21c56 +17540 5c5f +17541..17542 5c67 +17543 5c70 +17544 21d2d +17545 21d45 +17546 21d78 +17547 21d62 +17548 5c88 +17549 5c8a +17550 37c1 +17551 21da1 +17552 21d9c +17553 5ca0 +17554 5ca2 +17555 5ca7 +17556 21d92 +17557 5cad +17558 5cb5 +17559 21db7 +17560 5cc9 +17561 21de0 +17562 21e33 +17563 5d06 +17564 5d10 +17565 5d2b +17566 5d1d +17567 5d20 +17568 5d31 +17569 5d39 +17570 37e8 +17571 5d61 +17572 5d6a +17573 37f4 +17574 5d70 +17575 21f1e +17576 37fd +17577 5d88 +17578 3800 +17579 5d97 +17580 5db0 +17581 5db4 +17582 21f76 +17583 5dd1 +17584 5dd7 +17585 21ffa +17586 5de4 +17587 5de9 +17588 382f +17589 3836 +17590 3840 +17591 5e1f +17592 5e3e +17593 5e49 +17594 385c +17595 5e56 +17596 3861 +17597..17598 5e6d +17599 2217b +17600 5ea5 +17601 5eac +17602 5eb9 +17603 5ec6 +17604 5ed9 +17605 2231e +17606 5efd +17607 5f08 +17608 223ad +17609 5f1e +17610 5f47 +17611 5f63 +17612 5f72 +17613 5f7e +17614 5f8f +17615 5fa2 +17616 5fc7 +17617 5fcb +17618..17620 5fd2 +17621 5fe2 +17622..17623 5fee +17624 5ff3 +17625 3917 +17626 6022 +17627 6024 +17628 391a +17629 604c +17630 6095 +17631 60a8 +17632 226f3 +17633 60b1 +17634 60be +17635 60c8 +17636 60d9 +17637 60ee +17638 60f5 +17639 6110 +17640 6119 +17641 611e +17642 613a +17643 396f +17644 6141 +17645 6146 +17646 6160 +17647 2285b +17648..17649 6192 +17650 6197 +17651 61a5 +17652 61ad +17653 228ab +17654 61d5 +17655 61dd +17656 61f5 +17657 2298f +17658 6223 +17659 6252 +17660 6261 +17661 6264 +17662 627b +17663 626d +17664 6273 +17665 6299 +17666 62d5 +17667 22ab8 +17668 62fd +17669 6303 +17670 6310 +17671..17672 22b4f +17673 6332 +17674 6335 +17675..17676 633b +17677 6341 +17678 6344 +17679 634e +17680 22b46 +17681 6359 +17682 22c1d +17683 22ba6 +17684 636c +17685 6399 +17686 22c24 +17687 6394 +17688 63bd +17689..17690 63d4 +17691 63e0 +17692..17693 63eb +17694 63f2 +17695 641e +17696 6425 +17697 6429 +17698 642f +17699 645a +17700 645d +17701 6473 +17702 647d +17703 6487 +17704 6491 +17705 649f +17706..17707 64cb +17708 64d5 +17709 64d7 +17710 22de1 +17711 64e4 +17712 64ff +17713 3a6e +17714 650f +17715 6514 +17716 3a73 +17717 651e +17718 6532 +17719 6544 +17720 6554 +17721 656b +17722 657a +17723 6584 +17724 658a +17725 65b2 +17726 65b5 +17727 65b8 +17728 65bf +17729 65c9 +17730 65d4 +17731 3ad6 +17732 65f9 +17733 65fc +17734 6604 +17735 6608 +17736 6621 +17737 662a +17738 6645 +17739 6651 +17740 664e +17741 3aea +17742 231c3 +17743 231f5 +17744 231b6 +17745 666a +17746..17747 666c +17748 667b +17749 6680 +17750 6690 +17751 6692 +17752 3b0e +17753 66ad +17754 66b1 +17755 66b5 +17756 3b1a +17757 3b1c +17758 3ad7 +17759 6701 +17760 6712 +17761 23372 +17762 6719 +17763 233d3 +17764 233d2 +17765 674d +17766 6754 +17767 675d +17768 233d0 +17769 233e4 +17770 233d5 +17771 6774 +17772 233da +17773 6792 +17774 233df +17775 8363 +17776 6810 +17777 67c3 +17778 67c8 +17779 67d2 +17780 67db +17781 67f7 +17782 2344a +17783 23451 +17784 2344b +17785 6818 +17786 681f +17787 682d +17788 23465 +17789 6833 +17790 683b +17791 683e +17792 6845 +17793 6849 +17794 684c +17795 6855 +17796 6857 +17797 3b77 +17798 686b +17799 686e +17800 687c +17801 6882 +17802 6890 +17803 6896 +17804 3b6d +17805..17807 6898 +17808 689c +17809..17810 68aa +17811 68b4 +17812 68bb +17813 68fb +17814 234e4 +17815 2355a +17816 68c3 +17817 68c5 +17818 68cc +17819 68d9 +17820..17821 68e4 +17822 68ec +17823 68f7 +17824 6903 +17825 6907 +17826 3b87 +17827 23594 +17828 3b8d +17829 6946 +17830 6969 +17831 696c +17832 697a +17833 6992 +17834 3ba4 +17835 6996 +17836 69b0 +17837 69ba +17838 69bc +17839 69c0 +17840 69d1 +17841 23639 +17842 23647 +17843 23638 +17844 69e3 +17845..17846 69ee +17847 69f3 +17848 3bcd +17849 69f4 +17850 69fe +17851 6a11 +17852 6a1a +17853 6a1d +17854 2371c +17855..17856 6a32 +17857 6a3f +17858 6a49 +17859 6a7a +17860 6a4e +17861 6a52 +17862 6a64 +17863 2370c +17864 6a8b +17865 3bf0 +17866 6aa1 +17867 23764 +17868 6aab +17869 6abd +17870 6ac6 +17871 6ad4 +17872 6ad0 +17873 6add +17874 237ff +17875 237e7 +17876..17878 6af1 +17879 6afd +17880 23824 +17881 6b0b +17882..17884 6b0f +17885 2383d +17886 6b17 +17887 3c26 +17888 6b2f +17889 6b4a +17890 6b58 +17891 6b6c +17892 6b75 +17893 6b7a +17894 6b81 +17895 6b9b +17896 6bae +17897 23a98 +17898 6bbd +17899..17901 6bc7 +17902 6bda +17903..17904 6be6 +17905 6bee +17906 6c02 +17907 6c0a +17908 6c0e +17909 6c36 +17910 23c7f +17911 6c4d +17912 6c5b +17913 6c6d +17914 6c84 +17915 6c89 +17916 3cc3 +17917 6c94 +17918 6c97 +17919 6cad +17920 6cc2 +17921 3cd2 +17922 6cdc +17923 6ce9 +17924 6ced +17925 23d00 +17926 6d00 +17927 6d24 +17928..17929 6d26 +17930 6c67 +17931 6d2f +17932 6d3c +17933 6d5b +17934 6d60 +17935 6d70 +17936..17937 6d80 +17938 6d8a +17939 6d8d +17940 6d91 +17941 6d98 +17942 23d40 +17943 23dfa +17944 23df9 +17945 23dd3 +17946 6dab +17947 6dae +17948 6db4 +17949 6dc2 +17950 6d34 +17951 6dc8 +17952 6dce +17953 6ddf +17954 6df6 +17955 6e36 +17956 6e1e +17957 3d11 +17958 6e32 +17959..17960 6e48 +17961..17962 6e4b +17963 6e4f +17964..17965 6e53 +17966 6e57 +17967 6e63 +17968 3d1e +17969 6e93 +17970 6ea7 +17971 6eb4 +17972 6ec3 +17973 6f35 +17974 6eeb +17975 6ef9 +17976 6efb +17977 6f0a +17978 6f0c +17979 6f18 +17980 6f25 +17981 6f36 +17982 6f3c +17983 23f7e +17984 6f52 +17985 6f57 +17986 6f60 +17987 6f68 +17988 6f90 +17989 6f96 +17990 6fbe +17991 6f9f +17992 6fa5 +17993 6faf +17994 3d64 +17995..17996 6fc8 +17997 6fe9 +17998 24096 +17999 6ffc +18000 7000 +18001 700a +18002 7023 +18003 24103 +18004 703a +18005 7043 +18006 7047 +18007 704b +18008 3d9a +18009 7065 +18010 7069 +18011 706e +18012 7076 +18013 7086 +18014 7097 +18015 241c6 +18016 709f +18017 70b1 +18018 241fe +18019 70ec +18020 70ca +18021 70d1 +18022 7103 +18023 7106 +18024 7108 +18025 710c +18026 3dc0 +18027 712f +18028 7150 +18029 7153 +18030 715e +18031 3dd4 +18032 7196 +18033 7180 +18034 719b +18035 71a0 +18036 71a2 +18037..18038 71ae +18039 243bc +18040 71d9 +18041 71dc +18042 7207 +18043 3e05 +18044 7234 +18045 7239 +18046 7242 +18047 7257 +18048 7263 +18049 24629 +18050..18051 726e +18052 7278 +18053 727f +18054 728e +18055 246a5 +18056 72ae +18057 72b0 +18058 72c1 +18059 3e60 +18060 72cc +18061 3e66 +18062 3e68 +18063 72f3 +18064 72fa +18065 7307 +18066 7312 +18067..18068 7318 +18069 3e83 +18070 7339 +18071 732c +18072 7333 +18073 733d +18074 7352 +18075 3e94 +18076 736b +18077 24896 +18078..18079 736e +18080 7371 +18081 7381 +18082 738a +18083 7394 +18084 7398 +18085 739c +18086 73a5 +18087 73b9 +18088 73bf +18089 73c5 +18090 73cb +18091 73e1 +18092 73e7 +18093 73f9 +18094 7413 +18095 73fa +18096 7401 +18097 7453 +18098 7440 +18099 7443 +18100 7452 +18101 745d +18102 7481 +18103 7488 +18104 24a4d +18105 7492 +18106 7497 +18107 7499 +18108 74a1 +18109 74a5 +18110 74aa +18111 74b9 +18112 74bb +18113 74ba +18114 74d6 +18115 74d8 +18116 74eb +18117 24b56 +18118 74fa +18119 24b6f +18120 7520 +18121 7524 +18122 752a +18123 3f57 +18124 24c16 +18125..18126 753d +18127 7540 +18128 7548 +18129 7550 +18130 7552 +18131 7572 +18132 7571 +18133 757a +18134..18135 757d +18136 758c +18137 3f75 +18138 75a2 +18139 3f77 +18140 75b0 +18141 75b7 +18142..18143 75bf +18144 75c6 +18145 75cf +18146 75d3 +18147 75dd +18148..18149 75df +18150 75e7 +18151 75ee +18152 75f1 +18153 7603 +18154 7618 +18155 7607 +18156 760f +18157 3fae +18158 24e0e +18159 7613 +18160..18161 761b +18162 24e37 +18163 7625 +18164 7628 +18165 763c +18166 7633 +18167 24e6a +18168 3fc9 +18169 7641 +18170 24e8b +18171 7649 +18172 7655 +18173 3fd7 +18174 766e +18175 7695 +18176 76a1 +18177 76a0 +18178..18179 76a7 +18180 76af +18181 2504a +18182 76c9 +18183 25055 +18184 76e8 +18185 25122 +18186 7717 +18187 771a +18188 772d +18189 7735 +18190 251a9 +18191 4039 +18192 251e5 +18193 251cd +18194 7758 +18195 2521e +18196 777c +18197 2524c +18198 4058 +18199 779a +18200 779f +18201 77a2 +18202 77a4 +18203..18204 77de +18205 77e4 +18206 77ea +18207 77ec +18208 77fb +18209 2542e +18210 7805 +18211 7809 +18212 780d +18213 7819 +18214 782c +18215 7847 +18216 786a +18217 254d9 +18218 788a +18219 7894 +18220 78a4 +18221 789d +18222 789f +18223 78bb +18224 78d5 +18225 78e6 +18226..18227 78f9 +18228 78fe +18229 255a7 +18230 7910 +18231 791b +18232 7925 +18233 794a +18234 7958 +18235 4105 +18236 7967 +18237 7972 +18238 7995 +18239 79a1 +18240 79a9 +18241 79b4 +18242 79c2 +18243 79c7 +18244..18245 79cc +18246 79d6 +18247 4148 +18248 257a9 +18249 257b4 +18250 414f +18251 7a0a +18252 7a15 +18253 7a1b +18254 4163 +18255 7a38 +18256 7a47 +18257 7a56 +18258 7a59 +18259 7a5c +18260 7a5f +18261 7a67 +18262 7a6a +18263 7a75 +18264 7a82 +18265 7a8a +18266 7a90 +18267 7aac +18268 259d4 +18269 41b4 +18270 7ab9 +18271 7abe +18272 41bf +18273 7acc +18274 7ae8 +18275 7af4 +18276 25ae4 +18277 25ae3 +18278 25af1 +18279 7b3d +18280 7b2a +18281..18282 7b2e +18283 41e6 +18284 41f3 +18285 7b7f +18286 7b41 +18287 41ee +18288 7b55 +18289 7b79 +18290 7b64 +18291 7b66 +18292 7b73 +18293 25bb2 +18294 4207 +18295 7b90 +18296 7b9b +18297 420e +18298 7bb5 +18299 7bbc +18300 7bc5 +18301 7bca +18302 25c4b +18303 25c64 +18304 7bd4 +18305 7bd6 +18306 7bda +18307 7bea +18308 7bf0 +18309 7c03 +18310 7c0e +18311 7c45 +18312 7c4a +18313 7c57 +18314 7c5e +18315 7c61 +18316 7c69 +18317 7c6f +18318 25e2e +18319 25e56 +18320 25e65 +18321 7ca6 +18322 25e62 +18323..18324 7cb6 +18325 25ed8 +18326 7cc4 +18327 25ec2 +18328 7ccd +18329 25ee8 +18330 25f23 +18331 7ce6 +18332 25f5c +18333 7cf5 +18334 7d03 +18335 42c6 +18336 7d12 +18337 7d1e +18338 25fe0 +18339 25fd4 +18340..18341 7d3d +18342 7d40 +18343 7d47 +18344 2600c +18345 25ffb +18346 42d6 +18347 7d5a +18348 7d6a +18349 7d70 +18350 42dd +18351 7d7f +18352 26017 +18353 7d88 +18354 7d97 +18355 26060 +18356 7d9d +18357 7da7 +18358 7daa +18359 7db6 +18360 7dc0 +18361 7dd7 +18362 7dd9 +18363 7de6 +18364 4302 +18365 260ed +18366 fa58 +18367 7e10 +18368 7e17 +18369 7e1d +18370 7e27 +18371 7e2c +18372 7e45 +18373 7e75 +18374 7e7e +18375..18376 7e86 +18377 432b +18378 7e9a +18379 4343 +18380 7f3c +18381 7f3b +18382 7f3e +18383 7f43 +18384 34c1 +18385 26270 +18386 26286 +18387..18388 7f63 +18389 7f6d +18390..18391 7f7d +18392 7f90 +18393 517b +18394 23d0e +18395 7f96 +18396 7f9c +18397 7fad +18398 26402 +18399 7fc3 +18400 7fcf +18401 7fe3 +18402 7ff2 +18403 800a +18404 8008 +18405 8016 +18406 802c +18407 8030 +18408 8043 +18409 8066 +18410 807b +18411 8099 +18412 809c +18413 80a4 +18414 80a7 +18415 80b8 +18416 2667e +18417 80c5 +18418 80d5 +18419 80e6 +18420 810d +18421 80f5 +18422 80fb +18423 43ee +18424 8135 +18425 811e +18426 43f0 +18427 8124 +18428 8127 +18429 812c +18430 2671d +18431 813d +18432 4408 +18433 8169 +18434 4417 +18435 441c +18436 8185 +18437 4422 +18438 8198 +18439 81b2 +18440 81c1 +18441 81c3 +18442 81d6 +18443 81db +18444 268dd +18445 81e4 +18446 268ea +18447 81ec +18448 81fd +18449 81ff +18450 2696f +18451 8204 +18452 269dd +18453 8219 +18454 8222 +18455 26a1e +18456 823c +18457 8249 +18458 8245 +18459 26a58 +18460 4476 +18461 447a +18462 8257 +18463 26a8c +18464 825c +18465 8263 +18466 26ab7 +18467 4491 +18468 827d +18469 827f +18470 8283 +18471 828a +18472 8293 +18473..18474 82a7 +18475 82b2 +18476 82b4 +18477 82ba +18478 82bc +18479 82e2 +18480 82e8 +18481 82f7 +18482..18483 8307 +18484 830c +18485 8354 +18486 831b +18487 831d +18488 8330 +18489 833c +18490 8344 +18491 8357 +18492 44be +18493 44d4 +18494 44b3 +18495..18496 8394 +18497 839b +18498 839d +18499 83c9 +18500 83d0 +18501 83d4 +18502 83dd +18503 83e5 +18504 83f9 +18505 8415 +18506 26c73 +18507 8417 +18508 8439 +18509 844f +18510..18511 8451 +18512..18513 8459 +18514 845c +18515 26cdd +18516 8465 +18517 8478 +18518 847c +18519 8481 +18520 450d +18521 8497 +18522 84a6 +18523 84be +18524 4508 +18525..18526 84ce +18527 84d3 +18528 26e65 +18529 84e7 +18530 84ea +18531 84ef +18532 84f1 +18533 84fa +18534 851b +18535..18536 8524 +18537 852b +18538 854f +18539 856f +18540 4543 +18541 8551 +18542..18543 8561 +18544 26f94 +18545 857b +18546 857d +18547 857f +18548 8581 +18549 8586 +18550 8593 +18551 859d +18552 859f +18553 26ff8 +18554..18555 26ff6 +18556 85bc +18557 85c7 +18558 85ca +18559..18560 85d8 +18561 85df +18562 85e1 +18563 85e6 +18564 85f6 +18565 8600 +18566 8611 +18567 861e +18568 8621 +18569 8624 +18570 8627 +18571 2710d +18572 8639 +18573 863c +18574 27139 +18575 8640 +18576 8653 +18577 8656 +18578 8677 +18579 8687 +18580 8689 +18581..18582 869c +18583 86b1 +18584 86b3 +18585 86c1 +18586 86c3 +18587 86d1 +18588 86d5 +18589 86d7 +18590 86e3 +18591 86e6 +18592 45b8 +18593 8705 +18594 8707 +18595 870e +18596 8710 +18597 871f +18598 8721 +18599 8723 +18600 8731 +18601 873a +18602 8740 +18603 8743 +18604 8751 +18605 8758 +18606..18607 8764 +18608 8772 +18609 877c +18610 273db +18611 273da +18612 87a7 +18613 8789 +18614 878b +18615 8793 +18616 87a0 +18617 273fe +18618 45e5 +18619 87be +18620 27410 +18621 87c1 +18622 87ce +18623 87df +18624 27449 +18625 87e3 +18626..18627 87e5 +18628 87ea +18629 8813 +18630 8828 +18631 882e +18632 8832 +18633 883c +18634 460f +18635 884a +18636 8858 +18637 27615 +18638 27614 +18639 8869 +18640 27631 +18641 886f +18642 88a0 +18643 88bc +18644 88c0 +18645 27693 +18646 88d1 +18647 88d3 +18648 4641 +18649 8901 +18650 2770e +18651 8937 +18652 27723 +18653 8942 +18654 8945 +18655 8949 +18656 27752 +18657 8962 +18658 8989 +18659 8990 +18660 899f +18661 89b0 +18662 89b7 +18663 89d8 +18664 89eb +18665 46a1 +18666 89f3 +18667 89fd +18668 89ff +18669 46af +18670 8a11 +18671 8a14 +18672 27985 +18673 8a21 +18674 8a35 +18675 8a3e +18676 8a45 +18677 8a4d +18678 8a58 +18679 8aae +18680 8a90 +18681 8ab7 +18682 8ad7 +18683 8afc +18684 27a84 +18685 8b0a +18686 8b05 +18687 8b0d +18688 8b1c +18689 8b2d +18690 470c +18691 8b51 +18692 8b5e +18693 8b76 +18694 8b81 +18695 8b8b +18696..18697 8b94 +18698 8c39 +18699 27bb3 +18700 8c3d +18701 27bbe +18702 27bc7 +18703 8c45 +18704 8c4f +18705 8c57 +18706 8c69 +18707 8c6d +18708 27cb8 +18709 8c93 +18710 8c92 +18711 8c99 +18712 4764 +18713 8c9b +18714 8cd6 +18715 8cd5 +18716 27da0 +18717 8cf1 +18718 27e10 +18719 8d09 +18720 8d0e +18721 8dc8 +18722 8dd9 +18723 8e0c +18724 47fd +18725 8dfd +18726 8e06 +18727 2808a +18728 8e14 +18729 8e16 +18730..18731 8e21 +18732 8e27 +18733 280bb +18734 4816 +18735 8e36 +18736 8e39 +18737 8e54 +18738 8e62 +18739 8e6d +18740 8e6f +18741 8e98 +18742 8e9e +18743 8eb5 +18744 8ebb +18745 28282 +18746 484e +18747 282f3 +18748 8f00 +18749 8f08 +18750 8f2b +18751 8f40 +18752 8f4a +18753 8f58 +18754 2840c +18755 8fa4 +18756 8fb4 +18757 28455 +18758 8fc1 +18759 /uni8FC6.dup2 +18760 /uniFA24.dup2 +18761 8fca +18762 8fcd +18763 8fd3 +18764 8fd5 +18765 8ff1 +18766 8ff5 +18767 8ffb +18768 900c +18769 9037 +18770 2856b +18771 9043 +18772 905d +18773..18774 285c8 +18775 9085 +18776 908c +18777 9090 +18778 90a1 +18779 48b5 +18780 90b0 +18781 90b6 +18782 90c3 +18783 90c8 +18784 286d7 +18785 90dc +18786 90df +18787 286fa +18788 90f6 +18789 90f2 +18790 9100 +18791 90eb +18792..18793 90fe +18794 9104 +18795 9106 +18796 9118 +18797 911e +18798 9137 +18799 9139 +18800..18801 9146 +18802 9157 +18803 9159 +18804 9174 +18805 9179 +18806 9185 +18807 91b3 +18808 91b6 +18809..18810 91c3 +18811 28949 +18812 28946 +18813 91ec +18814 9201 +18815..18816 9216 +18817 2896b +18818 9242 +18819 924a +18820 9256 +18821 9261 +18822 9265 +18823 9268 +18824 28988 +18825..18826 927c +18827 927f +18828 9289 +18829 928d +18830 9297 +18831 9299 +18832 929f +18833 92ab +18834..18835 289ba +18836 92b2 +18837..18838 92bf +18839 92c6 +18840 92ce +18841 92e5 +18842 9311 +18843 28a1e +18844 28a29 +18845 92f7 +18846 9329 +18847 28a71 +18848 28a43 +18849 9351 +18850 935a +18851 936b +18852 9371 +18853 9373 +18854 93a1 +18855 28a99 +18856 28acd +18857 9388 +18858 938b +18859 938f +18860 939e +18861 93f5 +18862 28ae4 +18863 28add +18864 93f1 +18865 93c7 +18866 93dc +18867 93e7 +18868 9409 +18869..18870 9416 +18871 93fb +18872 9432 +18873 943b +18874 28bc1 +18875 28bef +18876 946d +18877 946f +18878 9579 +18879 9586 +18880..18881 958c +18882 28d10 +18883 28d71 +18884 95c8 +18885 28dfb +18886 28e1f +18887 962c +18888..18889 9633 +18890 28e36 +18891 963c +18892 9661 +18893 28e89 +18894 9682 +18895 28eeb +18896 969a +18897 28f32 +18898 49e7 +18899 96b3 +18900 96ba +18901 96bd +18902 49fa +18903 28ff8 +18904 96d8 +18905 96da +18906 96dd +18907 4a04 +18908 9714 +18909 9723 +18910 4a29 +18911 9736 +18912 9741 +18913 9747 +18914 9757 +18915 975b +18916 976a +18917 292a0 +18918 292b1 +18919 9796 +18920 979e +18921..18922 97b1 +18923 97be +18924 97cc +18925 97d1 +18926 97d4 +18927 97d8 +18928 97e1 +18929 97f1 +18930 9804 +18931 980d +18932 9814 +18933 9816 +18934 4abc +18935 29490 +18936..18937 9832 +18938 9825 +18939 9847 +18940 9866 +18941 98ab +18942 98ad +18943 98b0 +18944 295cf +18945 98b7 +18946..18947 98bb +18948 98c2 +18949 98c7 +18950 98cb +18951 98e1 +18952 98e3 +18953 98ea +18954..18955 98f0 +18956 98f3 +18957 9908 +18958 4b3b +18959 296f0 +18960..18961 9916 +18962 29719 +18963..18965 991a +18966 29750 +18967 9931 +18968..18970 993a +18971 9941 +18972 9946 +18973 994e +18974 9960 +18975 99a3 +18976 99a6 +18977 99bd +18978 99bf +18979 99c3 +18980 99d4 +18981 99d9 +18982 99de +18983 298c6 +18984 99f0 +18985 99f9 +18986 99fc +18987 9a0a +18988 9a11 +18989 9a1a +18990 9a20 +18991 9a31 +18992 9a44 +18993 9a4c +18994 9a58 +18995 4bc2 +18996 9aaf +18997 4bca +18998 9ab7 +18999 4bd2 +19000 9ab9 +19001 29a72 +19002 9ac6 +19003 9ad0 +19004 9ad2 +19005 9ad5 +19006 9ae0 +19007 9ae5 +19008 9ae9 +19009 9b0c +19010 9b10 +19011 9b12 +19012 9b16 +19013 9b1c +19014 9b2b +19015 9b3d +19016 4c20 +19017 9b4b +19018 9b63 +19019 9b65 +19020..19021 9b6b +19022..19023 9b76 +19024 9ba6 +19025 9bac +19026 29ddb +19027 9bb2 +19028 9bb8 +19029 9bbe +19030 9bf3 +19031 9bd8 +19032 9bdd +19033 9bea +19034 9bef +19035 9bee +19036 29e15 +19037 29e8a +19038 29e49 +19039 9c16 +19040..19042 9c18 +19043 9c1d +19044 9c22 +19045 9c29 +19046 29ec4 +19047 9c31 +19048 9c37 +19049 9c45 +19050 9c5c +19051 29ee9 +19052..19053 9c49 +19054 29edb +19055 9c54 +19056 9c58 +19057 9c5b +19058 9c5d +19059 9c5f +19060..19062 9c69 +19063..19064 9c6d +19065 9c72 +19066 9c75 +19067 9c7a +19068 9ce6 +19069 9cf2 +19070 9d0b +19071 29fd7 +19072 9d11 +19073..19074 9d17 +19075 2a02f +19076 4cc4 +19077 2a01a +19078 9d32 +19079 4cd1 +19080 9d4a +19081 9d5f +19082 9d62 +19083 2a0f9 +19084 2a082 +19085 9d73 +19086..19087 9d76 +19088 9d84 +19089 9d99 +19090 9da1 +19091 9dbf +19092 9db5 +19093 9db9 +19094 9dbd +19095 9dc9 +19096 9dda +19097 9de0 +19098 9de3 +19099 4d07 +19100 9e0a +19101 9e02 +19102 9e0d +19103 9e1c +19104 9e7b +19105 22218 +19106 9e80 +19107 9e85 +19108 9e9b +19109 2a38c +19110 9ebd +19111 2a437 +19112 9edf +19113 9eff +19114 9f02 +19115 4d77 +19116 9f03 +19117 9f3a +19118 9f3d +19119 9f46 +19120 9f53 +19121 9f55 +19122 9f58 +19123 2a5f1 +19124 9f5d +19125 2a602 +19126 9f69 +19127 9f6d +19128 9f70 +19129 2a6b2 +19130 2eac +19131 3614 +19132 38ad +19133 3dcc +19134 3fdc +19135 45be +19136 4610 +19137 4b7e +19138 4c38 +19139 4ce1 +19140 4e0c +19141..19142 4e23 +19143 4e79 +19144 4ef3 +19145 4f0c +19146 4f19 +19147 4f2b +19148 4f2e +19149 4f31 +19150 4f84 +19151 4f9e +19152 4fb7 +19153 5004 +19154 500c +19155 504c +19156 505f +19157 5062 +19158 5077 +19159 508e +19160 509e +19161 50a2 +19162 50c3 +19163 50e8 +19164 50f1 +19165 50fe +19166 5107 +19167..19169 510c +19170 5133 +19171 5138 +19172 5174 +19173 5184 +19174 51b8 +19175 51ba +19176 51c8 +19177 51cf +19178 51d1 +19179..19180 51d3 +19181 51d8 +19182 51df +19183 5205 +19184 5226 +19185 5228 +19186 522b +19187..19188 5231 +19189 5235 +19190 523c +19191 525a +19192 5260 +19193 526e +19194..19195 5278 +19196 528a +19197 528c +19198 52e1 +19199 52e9 +19200 52f1 +19201 5303 +19202 5311 +19203 531f +19204 532d +19205 5332 +19206 533d +19207 5365 +19208 536d +19209 5379 +19210 537e +19211 5394 +19212 5399 +19213 53aa +19214 53af +19215 53ba +19216 53c1 +19217..19218 53c4 +19219 53e0 +19220 5413 +19221 542a +19222 5431 +19223..19224 5434 +19225 544c +19226 54a7 +19227 54aa +19228 54b1 +19229 54bb +19230 54ce +19231 54ea +19232 54fc +19233 5505 +19234 5508 +19235 5515 +19236 5527 +19237 552a +19238 5536 +19239 5551 +19240 5566 +19241 558f +19242 5592 +19243 5594 +19244 55a4 +19245 55b2 +19246 55c3 +19247 55c6 +19248 55d3 +19249 55db +19250 55ec +19251 55ee +19252 55f1 +19253 55f6 +19254 55f8 +19255 5605 +19256 560d +19257..19258 5611 +19259 562c +19260 5635 +19261 5639 +19262 564d +19263 5654 +19264 5685 +19265 569f +19266 56a6 +19267 56b7 +19268 56cc +19269 56cf +19270 56d9 +19271 56e1 +19272 56eb +19273 56ed +19274 56f1 +19275 5707 +19276 570c +19277..19278 571a +19279 571d +19280 572c +19281 572e +19282..19283 573d +19284 575f +19285 576b +19286 576d +19287 577a +19288 5783 +19289 5797 +19290 57ae +19291 57d5 +19292 57e7 +19293 580d +19294 5826 +19295 584d +19296 584f +19297 585f +19298 586d +19299 587f +19300 5881 +19301 5898 +19302 58bc +19303 591f +19304 5923 +19305 5959 +19306 5979 +19307 5997 +19308 59af +19309 59b3 +19310 59df +19311 59f1 +19312 59f8 +19313 5ab2 +19314 5ab8 +19315 5aea +19316 5af6 +19317 5b1b +19318 5b1d +19319 5b21 +19320 5b38 +19321 5bb7 +19322 5bd7 +19323 5be0 +19324 5c1f +19325 5c2a +19326 5c2c +19327 5c36 +19328 5c59 +19329 5c5c +19330 5c6d +19331 5cdd +19332 5d01 +19333 5d34 +19334 5d3d +19335 5d59 +19336 5d7e +19337 5d83 +19338 5dc7 +19339 5df9 +19340 5e28 +19341 5e32 +19342 5e35 +19343 5e5b +19344 5e68 +19345 5e6a +19346 5e77 +19347 5e80 +19348 5e8b +19349 5eb3 +19350 5ebd +19351 5ed1 +19352..19353 5ed4 +19354 5f4d +19355 5fac +19356 5fea +19357 6007 +19358 6049 +19359 6054 +19360 6067 +19361 60bb +19362 60c4 +19363 60fd +19364 610a +19365 6116 +19366 612a +19367 6136 +19368 615e +19369 6164 +19370 617b +19371 617d +19372 617f +19373 619d +19374 61b8 +19375 61dc +19376 61e2 +19377 61e5 +19378 61e8 +19379 6204 +19380 6207 +19381 6231 +19382 6239 +19383 623d +19384 627a +19385 6290 +19386 62a8 +19387 62da +19388 62f4 +19389 6316 +19390 632a +19391 6336 +19392 6346 +19393 634b +19394 6353 +19395 6371 +19396 6375 +19397 637f +19398 6382 +19399 638a +19400..19401 63ae +19402 63ea +19403..19404 63f8 +19405 6412 +19406 6418 +19407 6420 +19408 6424 +19409 642a +19410 6435 +19411 643d +19412 643f +19413 6452 +19414 645f +19415 6474 +19416 6490 +19417..19418 6498 +19419 64ac +19420 64b3 +19421 64ed +19422 64f0 +19423 651b +19424 651f +19425 652e +19426 6549 +19427 6560 +19428 6592 +19429 6595 +19430 65b4 +19431 65be +19432 65c8 +19433 65ce +19434 65d0 +19435 65df +19436 667e +19437..19438 668b +19439 66b3 +19440 66c0 +19441 66cf +19442 6725 +19443 6735 +19444 6755 +19445 6780 +19446 678f +19447 6791 +19448 67a4 +19449 67b1 +19450 67b5 +19451 67be +19452 6828 +19453 6886 +19454 68eb +19455 68f5 +19456 6917 +19457 6933 +19458 6938 +19459 695b +19460 6965 +19461 69a8 +19462 69ab +19463 69af +19464 69e5 +19465 69f1 +19466 6a4a +19467 6a55 +19468 6a67 +19469 6a71 +19470 6aaf +19471..19472 6ac8 +19473 6b03 +19474 6b3b +19475 6b3f +19476..19477 6b7d +19478 6bb0 +19479 6bf7 +19480 6bf9 +19481 6c04 +19482 6c09 +19483 6c0d +19484 6c2c +19485 6c4a +19486 6c52 +19487 6c54 +19488 6c79 +19489 6cac +19490 6cb4 +19491 6cd2 +19492 6d61 +19493 6d7c +19494 6db9 +19495 6df0 +19496 6e45 +19497 6e73 +19498 6e7b +19499 6e7d +19500 6e89 +19501 6ebc +19502..19503 6eda +19504 6f26 +19505 6f29 +19506 6f30 +19507 6f87 +19508 6f9d +19509 6fae +19510 6fb7 +19511 700d +19512 7020 +19513 7049 +19514 7098 +19515 70b0 +19516..19517 70d5 +19518 7145 +19519 71b2 +19520 71f4 +19521 7217 +19522 721f +19523 7243 +19524..19525 724f +19526 725a +19527 7260 +19528 7268 +19529 7277 +19530 7284 +19531 72c9 +19532 72e5 +19533 72f4 +19534 7302 +19535 730b +19536 731e +19537 7322 +19538..19539 733a +19540 734d +19541 7358 +19542 7367 +19543 7472 +19544 74af +19545 74df +19546 74e4 +19547 74f4 +19548 74fb +19549 7516 +19550 7521 +19551 753f +19552 755e +19553 7599 +19554 75a4 +19555 75c1 +19556 75c4 +19557 75cc +19558 75d7 +19559 75dc +19560 75e1 +19561 75ef +19562 7604 +19563 760c +19564 761d +19565 7632 +19566 7638 +19567 7645 +19568 764a +19569 765f +19570 76ad +19571 76bd +19572 76d9 +19573 76eb +19574 76f0 +19575 76f9 +19576 7700 +19577 770e +19578 7722 +19579 7728 +19580 772f +19581 7739 +19582 773e +19583 7745 +19584 774a +19585 774f +19586 775e +19587 7764 +19588 7767 +19589 776c +19590 7784 +19591..19592 778c +19593 7796 +19594 77a7 +19595 77af +19596 77b7 +19597 77be +19598 77c9 +19599 77d1 +19600 77d9 +19601 77f1 +19602 7837 +19603 785c +19604 787e +19605 7898 +19606 78a1 +19607 78b1 +19608 78b3 +19609 78c9 +19610 78d3 +19611 790c +19612 791f +19613..19614 7927 +19615 793f +19616 7942 +19617 7954 +19618 796b +19619 797c +19620 79ab +19621 79c4 +19622 79ea +19623 7a02 +19624 7a0c +19625 7a30 +19626 7a3a +19627 7a44 +19628 7a80 +19629 7a86 +19630 7a94 +19631 7ab5 +19632 7abd +19633 7afe +19634 7b2b +19635 7b77 +19636 7ba0 +19637 7bac +19638 7bb0 +19639 7be8 +19640 7bf2 +19641 7bf8 +19642 7bfc +19643 7bfe +19644 7c09 +19645 7c28 +19646 7c2f +19647 7c42 +19648..19649 7c52 +19650..19652 7c5b +19653 7c72 +19654 7c7d +19655 7c87 +19656 7c9e +19657 7cba +19658 7cc7 +19659 7cd3 +19660 7cda +19661 7d3c +19662 7d4d +19663 7d82 +19664 7d85 +19665 7d8d +19666 7d91 +19667 7d9e +19668 7db3 +19669 7db9 +19670 7dd0 +19671 7de5 +19672..19673 7df5 +19674 7e2f +19675 7e36 +19676 7e44 +19677 7e6f +19678 7e78 +19679 7e81 +19680 7f3d +19681 7f5b +19682 7f5d +19683 7f65 +19684 7f71 +19685..19686 7f7f +19687 7f8b +19688 7fa2 +19689..19691 7ffd +19692 8007 +19693 800d +19694 801e +19695 8039 +19696 8088 +19697 808e +19698 80cf +19699 80d4 +19700 80ed +19701 80f0 +19702 80f7 +19703 80fa +19704 80fe +19705 8103 +19706 8117 +19707 8130 +19708 8157 +19709 816f +19710 8173 +19711 818b +19712 8190 +19713 819b +19714 819e +19715 81cb +19716 81d5 +19717..19718 81dd +19719 81e1 +19720 81ef +19721 81f6 +19722 8200 +19723 820b +19724..19725 8213 +19726 821a +19727 823a +19728 8244 +19729 826d +19730 8284 +19731 8289 +19732 8291 +19733 82aa +19734 82b0 +19735 82d0 +19736 82ea +19737 82ef +19738 82f6 +19739 8356 +19740 8378 +19741 83f8 +19742 83fc +19743 8458 +19744 8493 +19745 84b1 +19746 84bd +19747 84fb +19748 8546 +19749 8556 +19750 855d +19751 8585 +19752 8598 +19753 8642 +19754 8646 +19755 86c0 +19756 8714 +19757 8722 +19758 872e +19759 8739 +19760 875d +19761 877b +19762 878c +19763 878e +19764..19765 8797 +19766 879e +19767 87a3 +19768 87ae +19769 87bf +19770 87c9 +19771 87da +19772 8818 +19773 881b +19774 882d +19775 883a +19776 8845 +19777 884b +19778 884e +19779 8855 +19780 885a +19781 886e +19782..19784 889a +19785 88cd +19786 88e0 +19787 88ef +19788..19789 890e +19790 8926 +19791 8935 +19792 895a +19793 895c +19794 896b +19795 8970 +19796 897c +19797 89a5 +19798 89b5 +19799 89bc +19800 89d5 +19801 8a49 +19802 8a57 +19803 8a67 +19804 8a7e +19805 8a86 +19806 8a96 +19807 8ab6 +19808 8ac9 +19809 8ad1 +19810 8add +19811 8aec +19812 8af5 +19813 8b06 +19814 8b0f +19815 8b11 +19816 8b45 +19817 8b52 +19818 8b6d +19819 8b78 +19820 8b7c +19821 8b7e +19822 8b85 +19823 8b9f +19824 8c4b +19825 8c53 +19826 8c7b +19827 8cba +19828 8cc5 +19829 8cc9 +19830 8cd2 +19831 8cec +19832 8cf5 +19833 8cf7 +19834 8d01 +19835 8d03 +19836 8d17 +19837 8d1c +19838 8d6e +19839 8d91 +19840 8d9f +19841 8dab +19842 8db2 +19843 8dd5 +19844 8de7 +19845..19846 8df1 +19847 8df4 +19848 8e01 +19849 8e0b +19850 8e26 +19851 8e31 +19852..19853 8e40 +19854 8e4d +19855 8e4f +19856 8e5c +19857 8e61 +19858 8e69 +19859 8e71 +19860 8e75 +19861 8e77 +19862 8e89 +19863 8e90 +19864 8e95 +19865 8e9a +19866 8ea7 +19867 8ea9 +19868 8ead +19869 8ee8 +19870 8ef0 +19871 8f07 +19872 8f18 +19873 8f25 +19874 8f27 +19875 8f2c +19876 8f35 +19877 8f3a +19878 8f43 +19879 8f47 +19880 8f51 +19881 8f55 +19882..19884 8fa0 +19885 8fa5 +19886 9004 +19887 901b +19888 902f +19889 904c +19890 905b +19891 9070 +19892 9074 +19893 9079 +19894 908b +19895 9098 +19896 90a0 +19897 90b2 +19898 90bd +19899 90c9 +19900 90f0 +19901 9105 +19902 9125 +19903 915a +19904 9167 +19905 917a +19906 918a +19907 9191 +19908 9195 +19909 91b0 +19910 91bb +19911 91bd +19912 91c2 +19913 91c5 +19914 9200 +19915 9209 +19916 9223 +19917 9276 +19918 928e +19919 92af +19920..19921 92bb +19922 92c1 +19923 92c3 +19924 92c5 +19925 92c8 +19926 9314 +19927 9333 +19928 9336 +19929 9358 +19930 937f +19931 9382 +19932 938a +19933 93bb +19934 93cc +19935 93e6 +19936 93f9 +19937 9402 +19938..19939 940d +19940 942e +19941 944c +19942 9588 +19943 95a1 +19944 95bf +19945 95c6 +19946 95c9 +19947..19948 95d1 +19949 95e0 +19950 95e4 +19951 95e6 +19952 9624 +19953 9631 +19954 9638 +19955 963d +19956 9654 +19957 9674 +19958 967b +19959 967f +19960 9681 +19961 9683 +19962 9689 +19963 9696 +19964 96ae +19965 9703 +19966 971b +19967..19968 9721 +19969 9728 +19970 9731 +19971 9767 +19972 9776 +19973 977d +19974 977f +19975 9799 +19976 979f +19977 97ac +19978 97b9 +19979 97cd +19980 97e0 +19981 97ef +19982 9807 +19983 9826 +19984 982e +19985..19986 9862 +19987 98b4 +19988 98c5 +19989 9902 +19990 9911 +19991 9915 +19992 9935 +19993 9948 +19994 9954 +19995 995e +19996 99e1 +19997 9a0c +19998 9a10 +19999 9a23 +20000 9a41 +20001 9a51 +20002..20003 9abd +20004 9b01 +20005 9b09 +20006 9b0b +20007..20008 9b0d +20009 9b19 +20010 9b35 +20011 9b48 +20012 9b55 +20013 9b68 +20014 9b80 +20015 9b86 +20016 9b90 +20017 9b9d +20018 9bb0 +20019 9bbf +20020 9bc8 +20021 9bff +20022 9c02 +20023 9c1c +20024 9c35 +20025 9c44 +20026 9c56 +20027 9c61 +20028 9c68 +20029 9d30 +20030 9d3d +20031 9d6a +20032 9d7b +20033 9de5 +20034 9de9 +20035 9df3 +20036 9e7a +20037..20039 9e82 +20040 9eb0 +20041 9ee4 +20042 9ef0 +20043 9ef2 +20044 9f09 +20045 9f0f +20046 9f14 +20047 9f1b +20048 9f22 +20049 9f26 +20050..20051 9f2a +20052 9f34 +20053 9f5a +20054 9f6f +20055 9f9e +20056 9fa5 +20057 200f5 +20058 24e04 +20059 24ff2 +20060 27d73 +20061 2f815 +20062 2f846 +20063 2f899 +20064 2f8a6 +20065 2f8e5 +20066 2f9de +20067 35de +20072 2a2b2 +20075 20158 +20080 205b1 +20083 206ec +20090 20d58 +20112 259cc +20122 39a4 +20123 39b8 +20124 22e42 +20127 3a5c +20130 22feb +20133 279b4 +20135 3ac4 +20136 3acb +20142 3a85 +20151 3bf3 +20152 6af8 +20158 3d31 +20168 2404b +20170 3e40 +20171 38a1 +20206 26c9e +20219 471f +20220 27c3c +20225 481e +20297 9b1d +20298 9b2c +20299 /uni5002.dup2 +20300 /uni51DE.dup2 +20301 /uni5307.dup2 +20302 /uni5BEC.dup2 +20303 f928 +20304 /uni661E.dup2 +20305 /uniF929.dup2 +20306 /uni704A.dup2 +20307 /uniFA15.dup2 +20308 /uni5561.dup2 +20309 6c3a +20310 /uni7A60.dup2 +20311 2634c +20312 /uni8803.dup2 +20313 /uni95AB.dup2 +20314 /uni9755.dup2 +20315 29e3d +20316 2a61a diff --git a/fonts/cid/fontforge/Adobe-Japan1-6.cidmap b/fonts/cid/fontforge/Adobe-Japan1-6.cidmap new file mode 100644 index 000000000..be4fc4833 --- /dev/null +++ b/fonts/cid/fontforge/Adobe-Japan1-6.cidmap @@ -0,0 +1,15489 @@ +23057 23057 +0 /.notdef +1..60 0020 +61 00a5 +62..92 005d +93 00a6 +94 007d +95 02dc +96 02bc +97 005c +98 02bb +99 007c +100 007e +101..103 00a1 +104 2044 +105 0192 +107 00a4 +108 201c +109 00ab +110..111 2039 +112..113 fb01 +114 2012 +117 00b7 +119 2022 +120 201a +121 201e +122 201d +123 00bb +124 2026 +126 00bf +127 0301 +128 02c6 +129 00af +130..132 0306 +133 02da +134 00b8 +135 030b +136 0328 +137 030c +138 0336 +139 00c6 +140 00aa +141 0141 +142 00d8 +143 0152 +144 00ba +145 00e6 +146 0131 +147 0142 +148 00f8 +149 0153 +150 00df +151 00ad +152 00a9 +153 00ac +154 00ae +157..158 00b2 +159 00b5 +160 00b9 +161..163 00bc +164..169 00c0 +170..185 00c7 +187..192 00d9 +193..198 00e0 +199..214 00e7 +216..222 00f9 +223 0160 +224 0178 +225 017d +226 0305 +227 0161 +228 2122 +229 017e +231 2002 +232 /uni0021.hw +233 /uni0022.hw +234 /uni0023.hw +235 /uni0024.hw +236 /uni0025.hw +237 /uni0026.hw +238 /uni0027.hw +239 /uni0028.hw +240 /uni0029.hw +241 /uni002A.hw +242 /uni002B.hw +243 /uni002C.hw +244 /uni002D.hw +245 /uni002E.hw +246 /uni002F.hw +247 /uni0030.hw +248 /uni0031.hw +249 /uni0032.hw +250 /uni0033.hw +251 /uni0034.hw +252 /uni0035.hw +253 /uni0036.hw +254 /uni0037.hw +255 /uni0038.hw +256 /uni0039.hw +257 /uni003A.hw +258 /uni003B.hw +259 /uni003C.hw +260 /uni003D.hw +261 /uni003E.hw +262 /uni003F.hw +263 /uni0040.hw +264 /uni0041.hw +265 /uni0042.hw +266 /uni0043.hw +267 /uni0044.hw +268 /uni0045.hw +269 /uni0046.hw +270 /uni0047.hw +271 /uni0048.hw +272 /uni0049.hw +273 /uni004A.hw +274 /uni004B.hw +275 /uni004C.hw +276 /uni004D.hw +277 /uni004E.hw +278 /uni004F.hw +279 /uni0050.hw +280 /uni0051.hw +281 /uni0052.hw +282 /uni0053.hw +283 /uni0054.hw +284 /uni0055.hw +285 /uni0056.hw +286 /uni0057.hw +287 /uni0058.hw +288 /uni0059.hw +289 /uni005A.hw +290 /uni005B.hw +291 /uni00A5.hw +292 /uni005D.hw +293 /uni005E.hw +294 /uni005F.hw +295 /uni0060.hw +296 /uni0061.hw +297 /uni0062.hw +298 /uni0063.hw +299 /uni0064.hw +300 /uni0065.hw +301 /uni0066.hw +302 /uni0067.hw +303 /uni0068.hw +304 /uni0069.hw +305 /uni006A.hw +306 /uni006B.hw +307 /uni006C.hw +308 /uni006D.hw +309 /uni006E.hw +310 /uni006F.hw +311 /uni0070.hw +312 /uni0071.hw +313 /uni0072.hw +314 /uni0073.hw +315 /uni0074.hw +316 /uni0075.hw +317 /uni0076.hw +318 /uni0077.hw +319 /uni0078.hw +320 /uni0079.hw +321 /uni007A.hw +322 /uni007B.hw +323 /uniFFE8.hw +324 /uni007D.hw +325 /uni203E.hw +326 /Japan1.326.hw +327..389 ff61 +390 /Japan1.646.hw +391 /Japan1.1004.hw +392 /Japan1.1005.hw +393 /Japan1.1002.hw +394 /Japan1.1009.hw +395 /Japan1.1010.hw +396 /Japan1.1008.hw +397 /Japan1.936.hw +398 /Japan1.938.hw +399 /Japan1.940.hw +400 /Japan1.942.hw +401 /Japan1.944.hw +402 /Japan1.946.hw +403 /Japan1.948.hw +404 /Japan1.950.hw +405 /Japan1.952.hw +406 /Japan1.954.hw +407 /Japan1.956.hw +408 /Japan1.958.hw +409 /Japan1.961.hw +410 /Japan1.963.hw +411 /Japan1.965.hw +412 /Japan1.972.hw +413 /Japan1.973.hw +414 /Japan1.975.hw +415 /Japan1.976.hw +416 /Japan1.978.hw +417 /Japan1.979.hw +418 /Japan1.981.hw +419 /Japan1.982.hw +420 /Japan1.984.hw +421 /Japan1.421.hw +422 /Japan1.422.hw +423 /Japan1.423.hw +424 /Japan1.424.hw +425 /uni2500.hw +426 /uni2501.hw +427 /uni2502.hw +428 /uni2503.hw +429 /uni2504.hw +430 /uni2505.hw +431 /uni2506.hw +432 /uni2507.hw +433 /uni2508.hw +434 /uni2509.hw +435 /uni250A.hw +436 /uni250B.hw +437 /uni250C.hw +438 /uni250D.hw +439 /uni250E.hw +440 /uni250F.hw +441 /uni2510.hw +442 /uni2511.hw +443 /uni2512.hw +444 /uni2513.hw +445 /uni2514.hw +446 /uni2515.hw +447 /uni2516.hw +448 /uni2517.hw +449 /uni2518.hw +450 /uni2519.hw +451 /uni251A.hw +452 /uni251B.hw +453 /uni251C.hw +454 /uni251D.hw +455 /uni251E.hw +456 /uni251F.hw +457 /uni2520.hw +458 /uni2521.hw +459 /uni2522.hw +460 /uni2523.hw +461 /uni2524.hw +462 /uni2525.hw +463 /uni2526.hw +464 /uni2527.hw +465 /uni2528.hw +466 /uni2529.hw +467 /uni252A.hw +468 /uni252B.hw +469 /uni252C.hw +470 /uni252D.hw +471 /uni252E.hw +472 /uni252F.hw +473 /uni2530.hw +474 /uni2531.hw +475 /uni2532.hw +476 /uni2533.hw +477 /uni2534.hw +478 /uni2535.hw +479 /uni2536.hw +480 /uni2537.hw +481 /uni2538.hw +482 /uni2539.hw +483 /uni253A.hw +484 /uni253B.hw +485 /uni253C.hw +486 /uni253D.hw +487 /uni253E.hw +488 /uni253F.hw +489 /uni2540.hw +490 /uni2541.hw +491 /uni2542.hw +492 /uni2543.hw +493 /uni2544.hw +494 /uni2545.hw +495 /uni2546.hw +496 /uni2547.hw +497 /uni2548.hw +498 /uni2549.hw +499 /uni254A.hw +500 /uni254B.hw +501 /Japan1.645.hw +502 /Japan1.647.hw +503 /Japan1.672.hw +504 /uni3014.hw +505 /uni3015.hw +506 /uni3008.hw +507 /uni3009.hw +508 /uni300A.hw +509 /uni300B.hw +510 /uni300C.hw +511 /uni300D.hw +512 /uni300E.hw +513 /uni300F.hw +514 /Japan1.514.hw +515 /Japan1.515.hw +516 /Japan1.923.hw +517 /Japan1.842.hw +518 /Japan1.844.hw +519 /Japan1.846.hw +520 /Japan1.848.hw +521 /Japan1.850.hw +522 /Japan1.908.hw +523 /Japan1.910.hw +524 /Japan1.912.hw +525 /Japan1.876.hw +526 /Japan1.843.hw +527 /Japan1.845.hw +528 /Japan1.847.hw +529 /Japan1.849.hw +530 /Japan1.851.hw +531 /Japan1.852.hw +532 /Japan1.854.hw +533 /Japan1.856.hw +534 /Japan1.858.hw +535 /Japan1.860.hw +536 /Japan1.862.hw +537 /Japan1.864.hw +538 /Japan1.866.hw +539 /Japan1.868.hw +540 /Japan1.870.hw +541 /Japan1.872.hw +542 /Japan1.874.hw +543 /Japan1.877.hw +544 /Japan1.879.hw +545 /Japan1.881.hw +546 /Japan1.883.hw +547 /Japan1.884.hw +548 /Japan1.885.hw +549 /Japan1.886.hw +550 /Japan1.887.hw +551 /Japan1.888.hw +552 /Japan1.891.hw +553 /Japan1.894.hw +554 /Japan1.897.hw +555 /Japan1.900.hw +556 /Japan1.903.hw +557 /Japan1.904.hw +558 /Japan1.905.hw +559 /Japan1.906.hw +560 /Japan1.907.hw +561 /Japan1.909.hw +562 /Japan1.911.hw +563 /Japan1.913.hw +564 /Japan1.914.hw +565 /Japan1.915.hw +566 /Japan1.916.hw +567 /Japan1.917.hw +568 /Japan1.918.hw +569 /Japan1.920.hw +570 /Japan1.924.hw +571 /Japan1.921.hw +572 /Japan1.922.hw +573 /Japan1.919.hw +574 /Japan1.853.hw +575 /Japan1.855.hw +576 /Japan1.857.hw +577 /Japan1.859.hw +578 /Japan1.861.hw +579 /Japan1.863.hw +580 /Japan1.865.hw +581 /Japan1.867.hw +582 /Japan1.869.hw +583 /Japan1.871.hw +584 /Japan1.873.hw +585 /Japan1.875.hw +586 /Japan1.878.hw +587 /Japan1.880.hw +588 /Japan1.882.hw +589 /Japan1.889.hw +590 /Japan1.890.hw +591 /Japan1.892.hw +592 /Japan1.893.hw +593 /Japan1.895.hw +594 /Japan1.896.hw +595 /Japan1.898.hw +596 /Japan1.899.hw +597 /Japan1.901.hw +598 /Japan1.902.hw +599 /uni00C4.hw +600 /uni00F9.hw +601 /uni00E9.hw +602 /uni00ED.hw +603 /uni00DF.hw +604 /uni00E7.hw +605 /uni00C7.hw +606 /uni00D1.hw +607 /uni00F1.hw +608 /uni00A2.hw +609 /uni00A3.hw +610 /uni00F3.hw +611 /uni00FA.hw +612 /uni00A1.hw +613 /uni00BF.hw +614 /uni00BD.hw +615 /uni00D6.hw +616 /uni00DC.hw +617 /uni00E4.hw +618 /uni00EB.hw +619 /uni00EF.hw +620 /uni00F6.hw +621 /uni00FC.hw +622 /uni00E2.hw +623 /uni00EA.hw +624 /uni00EE.hw +625 /uni00F4.hw +626 /uni00FB.hw +627 /uni00E0.hw +628 /uni00E8.hw +629 /Japan1.629.hw +630 /uni00E1.hw +631 /Japan1.631.hw +632 /uni00D8.hw +633 2003 +634..635 3001 +636 ff0c +637 ff0e +638 30fb +639..640 ff1a +641 ff1f +642 ff01 +643..644 309b +645 00b4 +646 ff40 +647 00a8 +648 ff3e +649 ffe3 +650 ff3f +651..652 30fd +653..654 309d +655 3003 +656 4edd +657..659 3005 +660 30fc +661 2015 +662 2010 +663 ff0f +664 ff3c +665 301c +666 2016 +667 ff5c +668 /uni2026.dup2 +669 2025 +670..671 2018 +672 /uni201C.dup2 +673 /uni201D.dup2 +674..675 ff08 +676..677 3014 +678 ff3b +679 ff3d +680 ff5b +681 ff5d +682..691 3008 +692 ff0b +693 2212 +694 00b1 +695 00d7 +696 00f7 +697 ff1d +698 2260 +699 ff1c +700 ff1e +701..702 2266 +703 221e +704 2234 +705 2642 +706 2640 +707 00b0 +708..709 2032 +710 2103 +711 ffe5 +712 ff04 +713..714 ffe0 +715 ff05 +716 ff03 +717 ff06 +718 ff0a +719 ff20 +720 00a7 +721 2606 +722 2605 +723 25cb +724 25cf +725 25ce +726 25c7 +727 25c6 +728 25a1 +729 25a0 +730 25b3 +731 25b2 +732 25bd +733 25bc +734 203b +735 3012 +736 2192 +737..738 2190 +739 2193 +740 3013 +741 2208 +742 220b +743..744 2286 +745..746 2282 +747 222a +748 2229 +749..750 2227 +751 ffe2 +752 21d2 +753 21d4 +754 2200 +755 2203 +756 2220 +757 22a5 +758 2312 +759 2202 +760 2207 +761 2261 +762 2252 +763..764 226a +765 221a +766 223d +767 221d +768 2235 +769..770 222b +771 212b +772 2030 +773 266f +774 266d +775 266a +776..777 2020 +778 00b6 +779 25ef +780..789 ff10 +790..815 ff21 +816..841 ff41 +842..924 3041 +925..1010 30a1 +1011..1027 0391 +1028..1034 03a3 +1035..1051 03b1 +1052..1058 03c3 +1059..1064 0410 +1065 0401 +1066..1097 0416 +1098 0451 +1099..1124 0436 +1125 4e9c +1126 5516 +1127 5a03 +1128 963f +1129 54c0 +1130 611b +1131 6328 +1132 59f6 +1133 9022 +1134 8475 +1135 831c +1136 7a50 +1137 60aa +1138 63e1 +1139 6e25 +1140 65ed +1141 8466 +1142 82a6 +1143 9bf5 +1144 6893 +1145 5727 +1146 65a1 +1147 6271 +1148 5b9b +1149 59d0 +1150 867b +1151 98f4 +1152 7d62 +1153 7dbe +1154 9b8e +1155 6216 +1156 7c9f +1157 88b7 +1158 5b89 +1159 5eb5 +1160 6309 +1161 6697 +1162 6848 +1163 95c7 +1164 978d +1165 674f +1166 4ee5 +1167 4f0a +1168 4f4d +1169 4f9d +1170 5049 +1171 56f2 +1172 5937 +1173 59d4 +1174 5a01 +1175 5c09 +1176 60df +1177 610f +1178 6170 +1179 6613 +1180 6905 +1181 70ba +1182 754f +1183 7570 +1184 79fb +1185 7dad +1186 7def +1187 80c3 +1188 840e +1189 8863 +1190 8b02 +1191 9055 +1192 907a +1193 533b +1194 4e95 +1195 4ea5 +1196 57df +1197 80b2 +1198 90c1 +1199 78ef +1200 4e00 +1201 58f1 +1202 6ea2 +1203 9038 +1204 7a32 +1205 8328 +1206 828b +1207 9c2f +1208 5141 +1209 5370 +1210 54bd +1211 54e1 +1212 56e0 +1213 59fb +1214 5f15 +1215 98f2 +1216 6deb +1217 80e4 +1218 852d +1219 9662 +1220 9670 +1221 96a0 +1222 97fb +1223 540b +1224 53f3 +1225 5b87 +1226 70cf +1227 7fbd +1228 8fc2 +1229 96e8 +1230 536f +1231 9d5c +1232 7aba +1233 4e11 +1234 7893 +1235 81fc +1236 6e26 +1237 5618 +1238 5504 +1239 6b1d +1240 851a +1241 9c3b +1242 59e5 +1243 53a9 +1244 6d66 +1245 74dc +1246 958f +1247 5642 +1248 4e91 +1249 904b +1250 96f2 +1251 834f +1252 990c +1253 53e1 +1254 55b6 +1255 5b30 +1256 5f71 +1257 6620 +1258 66f3 +1259 6804 +1260 6c38 +1261 6cf3 +1262 6d29 +1263 745b +1264 76c8 +1265 7a4e +1266 9834 +1267 82f1 +1268 885b +1269 8a60 +1270 92ed +1271 6db2 +1272 75ab +1273 76ca +1274 99c5 +1275 60a6 +1276 8b01 +1277 8d8a +1278 95b2 +1279 698e +1280 53ad +1281 5186 +1282 5712 +1283 5830 +1284 5944 +1285 5bb4 +1286 5ef6 +1287 6028 +1288 63a9 +1289 63f4 +1290 6cbf +1291 6f14 +1292 708e +1293 7114 +1294 7159 +1295 71d5 +1296 733f +1297 7e01 +1298 8276 +1299 82d1 +1300 8597 +1301 9060 +1302 925b +1303 9d1b +1304 5869 +1305 65bc +1306 6c5a +1307 7525 +1308 51f9 +1309 592e +1310 5965 +1311 5f80 +1312 5fdc +1313 62bc +1314 65fa +1315 6a2a +1316 6b27 +1317 6bb4 +1318 738b +1319 7fc1 +1320 8956 +1321 9d2c +1322 9d0e +1323 9ec4 +1324 5ca1 +1325 6c96 +1326 837b +1327 5104 +1328 5c4b +1329 61b6 +1330 81c6 +1331 6876 +1332 7261 +1333 4e59 +1334 4ffa +1335 5378 +1336 6069 +1337 6e29 +1338 7a4f +1339 97f3 +1340 4e0b +1341 5316 +1342 4eee +1343 4f55 +1344 4f3d +1345 4fa1 +1346 4f73 +1347 52a0 +1348 53ef +1349 5609 +1350 590f +1351 5ac1 +1352 5bb6 +1353 5be1 +1354 79d1 +1355 6687 +1356 679c +1357 67b6 +1358 6b4c +1359 6cb3 +1360 706b +1361 73c2 +1362 798d +1363 79be +1364 7a3c +1365 7b87 +1366 82b1 +1367 82db +1368 8304 +1369 8377 +1370 83ef +1371 83d3 +1372 8766 +1373 8ab2 +1374 5629 +1375 8ca8 +1376 8fe6 +1377 904e +1378 971e +1379 868a +1380 4fc4 +1381 5ce8 +1382 6211 +1383 7259 +1384 753b +1385 81e5 +1386 82bd +1387 86fe +1388 8cc0 +1389 96c5 +1390 9913 +1391 99d5 +1392 4ecb +1393 4f1a +1394 89e3 +1395 56de +1396 584a +1397 58ca +1398 5efb +1399 5feb +1400 602a +1401 6094 +1402 6062 +1403 61d0 +1404 6212 +1405 62d0 +1406 6539 +1407 9b41 +1408 6666 +1409 68b0 +1410 6d77 +1411 7070 +1412 754c +1413 7686 +1414 7d75 +1415 82a5 +1416 87f9 +1417 958b +1418 968e +1419 8c9d +1420 51f1 +1421 52be +1422 5916 +1423 54b3 +1424 5bb3 +1425 5d16 +1426 6168 +1427 6982 +1428 6daf +1429 788d +1430 84cb +1431 8857 +1432 8a72 +1433 93a7 +1434 9ab8 +1435 6d6c +1436 99a8 +1437 86d9 +1438 57a3 +1439 67ff +1440 86ce +1441 920e +1442 5283 +1443 5687 +1444 5404 +1445 5ed3 +1446 62e1 +1447 64b9 +1448 683c +1449 6838 +1450 6bbb +1451 7372 +1452 78ba +1453 7a6b +1454 899a +1455 89d2 +1456 8d6b +1457 8f03 +1458 90ed +1459 95a3 +1460 9694 +1461 9769 +1462 5b66 +1463 5cb3 +1464 697d +1465..1466 984d +1467 639b +1468 7b20 +1469 6a2b +1470 6a7f +1471 68b6 +1472 9c0d +1473 6f5f +1474 5272 +1475 559d +1476 6070 +1477 62ec +1478 6d3b +1479 6e07 +1480 6ed1 +1481 845b +1482 8910 +1483 8f44 +1484 4e14 +1485 9c39 +1486 53f6 +1487 691b +1488 6a3a +1489 9784 +1490 682a +1491 515c +1492 7ac3 +1493 84b2 +1494 91dc +1495 938c +1496 565b +1497 9d28 +1498 6822 +1499 8305 +1500 8431 +1501 7ca5 +1502 5208 +1503 82c5 +1504 74e6 +1505 4e7e +1506 4f83 +1507 51a0 +1508 5bd2 +1509 520a +1510 52d8 +1511 52e7 +1512 5dfb +1513 559a +1514 582a +1515 59e6 +1516 5b8c +1517 5b98 +1518 5bdb +1519 5e72 +1520 5e79 +1521 60a3 +1522 611f +1523 6163 +1524 61be +1525 63db +1526 6562 +1527 67d1 +1528 6853 +1529 68fa +1530 6b3e +1531 6b53 +1532 6c57 +1533 6f22 +1534 6f97 +1535 6f45 +1536 74b0 +1537 7518 +1538 76e3 +1539 770b +1540 7aff +1541 7ba1 +1542 7c21 +1543 7de9 +1544 7f36 +1545 7ff0 +1546 809d +1547 8266 +1548 839e +1549 89b3 +1550 8acc +1551 8cab +1552 9084 +1553 9451 +1554 9593 +1555 9591 +1556 95a2 +1557 9665 +1558 97d3 +1559 9928 +1560 8218 +1561 4e38 +1562 542b +1563 5cb8 +1564 5dcc +1565 73a9 +1566 764c +1567 773c +1568 5ca9 +1569 7feb +1570 8d0b +1571 96c1 +1572 9811 +1573 9854 +1574 9858 +1575 4f01 +1576 4f0e +1577 5371 +1578 559c +1579 5668 +1580 57fa +1581 5947 +1582 5b09 +1583 5bc4 +1584 5c90 +1585 5e0c +1586 5e7e +1587 5fcc +1588 63ee +1589 673a +1590 65d7 +1591 65e2 +1592 671f +1593 68cb +1594 68c4 +1595 6a5f +1596 5e30 +1597 6bc5 +1598 6c17 +1599 6c7d +1600 757f +1601 7948 +1602 5b63 +1603 7a00 +1604 7d00 +1605 5fbd +1606 898f +1607 8a18 +1608 8cb4 +1609 8d77 +1610 8ecc +1611 8f1d +1612 98e2 +1613 9a0e +1614 9b3c +1615 4e80 +1616 507d +1617 5100 +1618 5993 +1619 5b9c +1620 622f +1621 6280 +1622 64ec +1623 6b3a +1624 72a0 +1625 7591 +1626 7947 +1627 7fa9 +1628 87fb +1629 8abc +1630 8b70 +1631 63ac +1632 83ca +1633 97a0 +1634 5409 +1635 5403 +1636 55ab +1637 6854 +1638 6a58 +1639 8a70 +1640 7827 +1641 6775 +1642 9ecd +1643 5374 +1644 5ba2 +1645 811a +1646 8650 +1647 9006 +1648 4e18 +1649 4e45 +1650 4ec7 +1651 4f11 +1652 53ca +1653 5438 +1654 5bae +1655 5f13 +1656 6025 +1657 6551 +1658 673d +1659 6c42 +1660 6c72 +1661 6ce3 +1662 7078 +1663 7403 +1664 7a76 +1665 7aae +1666 7b08 +1667 7d1a +1668 7cfe +1669 7d66 +1670 65e7 +1671 725b +1672 53bb +1673 5c45 +1674 5de8 +1675 62d2 +1676 62e0 +1677 6319 +1678 6e20 +1679 865a +1680 8a31 +1681 8ddd +1682 92f8 +1683 6f01 +1684 79a6 +1685 9b5a +1686 4ea8 +1687..1688 4eab +1689 4f9b +1690 4fa0 +1691 50d1 +1692 5147 +1693 7af6 +1694 5171 +1695 51f6 +1696 5354 +1697 5321 +1698 537f +1699 53eb +1700 55ac +1701 5883 +1702 5ce1 +1703 5f37 +1704 5f4a +1705 602f +1706 6050 +1707 606d +1708 631f +1709 6559 +1710 6a4b +1711 6cc1 +1712 72c2 +1713 72ed +1714 77ef +1715 80f8 +1716 8105 +1717 8208 +1718 854e +1719 90f7 +1720 93e1 +1721 97ff +1722 9957 +1723 9a5a +1724 4ef0 +1725 51dd +1726 5c2d +1727 6681 +1728 696d +1729 5c40 +1730 66f2 +1731 6975 +1732 7389 +1733 6850 +1734 7c81 +1735 50c5 +1736 52e4 +1737 5747 +1738 5dfe +1739 9326 +1740 65a4 +1741 6b23 +1742 6b3d +1743 7434 +1744 7981 +1745 79bd +1746 7b4b +1747 7dca +1748 82b9 +1749 83cc +1750 887f +1751 895f +1752 8b39 +1753 8fd1 +1754 91d1 +1755 541f +1756 9280 +1757 4e5d +1758 5036 +1759 53e5 +1760 533a +1761 72d7 +1762 7396 +1763 77e9 +1764 82e6 +1765 8eaf +1766 99c6 +1767 99c8 +1768 99d2 +1769 5177 +1770 611a +1771 865e +1772 55b0 +1773 7a7a +1774 5076 +1775 5bd3 +1776 9047 +1777 9685 +1778 4e32 +1779 6adb +1780 91e7 +1781 5c51 +1782 5c48 +1783 6398 +1784 7a9f +1785 6c93 +1786 9774 +1787 8f61 +1788 7aaa +1789 718a +1790 9688 +1791 7c82 +1792 6817 +1793 7e70 +1794 6851 +1795 936c +1796 52f2 +1797 541b +1798 85ab +1799 8a13 +1800 7fa4 +1801 8ecd +1802 90e1 +1803 5366 +1804 8888 +1805 7941 +1806 4fc2 +1807 50be +1808 5211 +1809 5144 +1810 5553 +1811 572d +1812 73ea +1813 578b +1814 5951 +1815 5f62 +1816 5f84 +1817 6075 +1818 6176 +1819 6167 +1820 61a9 +1821 63b2 +1822 643a +1823 656c +1824 666f +1825 6842 +1826 6e13 +1827 7566 +1828 7a3d +1829 7cfb +1830 7d4c +1831 7d99 +1832 7e4b +1833 7f6b +1834 830e +1835 834a +1836 86cd +1837 8a08 +1838 8a63 +1839 8b66 +1840 8efd +1841 981a +1842 9d8f +1843 82b8 +1844 8fce +1845 9be8 +1846 5287 +1847 621f +1848 6483 +1849 6fc0 +1850 9699 +1851 6841 +1852 5091 +1853 6b20 +1854 6c7a +1855 6f54 +1856 7a74 +1857 7d50 +1858 8840 +1859 8a23 +1860 6708 +1861 4ef6 +1862 5039 +1863 5026 +1864 5065 +1865 517c +1866 5238 +1867 5263 +1868 55a7 +1869 570f +1870 5805 +1871 5acc +1872 5efa +1873 61b2 +1874 61f8 +1875 62f3 +1876 6372 +1877 691c +1878 6a29 +1879 727d +1880 72ac +1881 732e +1882 7814 +1883 786f +1884 7d79 +1885 770c +1886 80a9 +1887 898b +1888 8b19 +1889 8ce2 +1890 8ed2 +1891 9063 +1892 9375 +1893 967a +1894 9855 +1895 9a13 +1896 9e78 +1897 5143 +1898 539f +1899 53b3 +1900 5e7b +1901 5f26 +1902 6e1b +1903 6e90 +1904 7384 +1905 73fe +1906 7d43 +1907 8237 +1908 8a00 +1909 8afa +1910 9650 +1911 4e4e +1912 500b +1913 53e4 +1914 547c +1915 56fa +1916 59d1 +1917 5b64 +1918 5df1 +1919 5eab +1920 5f27 +1921 6238 +1922 6545 +1923 67af +1924 6e56 +1925 72d0 +1926 7cca +1927 88b4 +1928 80a1 +1929 80e1 +1930 83f0 +1931 864e +1932 8a87 +1933 8de8 +1934 9237 +1935 96c7 +1936 9867 +1937 9f13 +1938 4e94 +1939 4e92 +1940 4f0d +1941 5348 +1942 5449 +1943 543e +1944 5a2f +1945 5f8c +1946 5fa1 +1947 609f +1948 68a7 +1949 6a8e +1950 745a +1951 7881 +1952 8a9e +1953 8aa4 +1954 8b77 +1955 9190 +1956 4e5e +1957 9bc9 +1958 4ea4 +1959 4f7c +1960 4faf +1961 5019 +1962 5016 +1963 5149 +1964 516c +1965 529f +1966 52b9 +1967 52fe +1968 539a +1969 53e3 +1970 5411 +1971 540e +1972 5589 +1973 5751 +1974 57a2 +1975 597d +1976 5b54 +1977 5b5d +1978 5b8f +1979 5de5 +1980 5de7 +1981 5df7 +1982 5e78 +1983 5e83 +1984 5e9a +1985 5eb7 +1986 5f18 +1987 6052 +1988 614c +1989 6297 +1990 62d8 +1991 63a7 +1992 653b +1993 6602 +1994 6643 +1995 66f4 +1996 676d +1997 6821 +1998 6897 +1999 69cb +2000 6c5f +2001 6d2a +2002 6d69 +2003 6e2f +2004 6e9d +2005 7532 +2006 7687 +2007 786c +2008 7a3f +2009 7ce0 +2010 7d05 +2011 7d18 +2012 7d5e +2013 7db1 +2014 8015 +2015 8003 +2016 80af +2017 80b1 +2018 8154 +2019 818f +2020 822a +2021 8352 +2022 884c +2023 8861 +2024 8b1b +2025 8ca2 +2026 8cfc +2027 90ca +2028 9175 +2029 9271 +2030 783f +2031 92fc +2032 95a4 +2033 964d +2034 9805 +2035 9999 +2036 9ad8 +2037 9d3b +2038 525b +2039 52ab +2040 53f7 +2041 5408 +2042 58d5 +2043 62f7 +2044 6fe0 +2045 8c6a +2046 8f5f +2047 9eb9 +2048 514b +2049 523b +2050 544a +2051 56fd +2052 7a40 +2053 9177 +2054 9d60 +2055 9ed2 +2056 7344 +2057 6f09 +2058 8170 +2059 7511 +2060 5ffd +2061 60da +2062 9aa8 +2063 72db +2064 8fbc +2065 6b64 +2066 9803 +2067 4eca +2068 56f0 +2069 5764 +2070 58be +2071 5a5a +2072 6068 +2073 61c7 +2074 660f +2075 6606 +2076 6839 +2077 68b1 +2078 6df7 +2079 75d5 +2080 7d3a +2081 826e +2082 9b42 +2083 4e9b +2084 4f50 +2085 53c9 +2086 5506 +2087 5d6f +2088 5de6 +2089 5dee +2090 67fb +2091 6c99 +2092 7473 +2093 7802 +2094 8a50 +2095 9396 +2096 88df +2097 5750 +2098 5ea7 +2099 632b +2100 50b5 +2101 50ac +2102 518d +2103 6700 +2104 54c9 +2105 585e +2106 59bb +2107 5bb0 +2108 5f69 +2109 624d +2110 63a1 +2111 683d +2112 6b73 +2113 6e08 +2114 707d +2115 91c7 +2116 7280 +2117 7815 +2118 7826 +2119 796d +2120 658e +2121 7d30 +2122 83dc +2123 88c1 +2124 8f09 +2125 969b +2126 5264 +2127 5728 +2128 6750 +2129 7f6a +2130 8ca1 +2131 51b4 +2132 5742 +2133 962a +2134 583a +2135 698a +2136 80b4 +2137 54b2 +2138 5d0e +2139 57fc +2140 7895 +2141 9dfa +2142 4f5c +2143 524a +2144 548b +2145 643e +2146 6628 +2147 6714 +2148 67f5 +2149 7a84 +2150 7b56 +2151 7d22 +2152 932f +2153 685c +2154 9bad +2155 7b39 +2156 5319 +2157 518a +2158 5237 +2159 5bdf +2160 62f6 +2161 64ae +2162 64e6 +2163 672d +2164 6bba +2165 85a9 +2166 96d1 +2167 7690 +2168 9bd6 +2169 634c +2170 9306 +2171 9bab +2172 76bf +2173 6652 +2174 4e09 +2175 5098 +2176 53c2 +2177 5c71 +2178 60e8 +2179 6492 +2180 6563 +2181 685f +2182 71e6 +2183 73ca +2184 7523 +2185 7b97 +2186 7e82 +2187 8695 +2188 8b83 +2189 8cdb +2190 9178 +2191 9910 +2192 65ac +2193 66ab +2194 6b8b +2195 4ed5 +2196 4ed4 +2197 4f3a +2198 4f7f +2199 523a +2200 53f8 +2201 53f2 +2202 55e3 +2203 56db +2204 58eb +2205 59cb +2206 59c9 +2207 59ff +2208 5b50 +2209 5c4d +2210 5e02 +2211 5e2b +2212 5fd7 +2213 601d +2214 6307 +2215 652f +2216 5b5c +2217 65af +2218 65bd +2219 65e8 +2220 679d +2221 6b62 +2222 6b7b +2223 6c0f +2224 7345 +2225 7949 +2226 79c1 +2227 7cf8 +2228 7d19 +2229 7d2b +2230 80a2 +2231 8102 +2232 81f3 +2233 8996 +2234 8a5e +2235 8a69 +2236 8a66 +2237 8a8c +2238 8aee +2239 8cc7 +2240 8cdc +2241 96cc +2242 98fc +2243 6b6f +2244 4e8b +2245 4f3c +2246 4f8d +2247 5150 +2248 5b57 +2249 5bfa +2250 6148 +2251 6301 +2252 6642 +2253 6b21 +2254 6ecb +2255 6cbb +2256 723e +2257 74bd +2258 75d4 +2259 78c1 +2260 793a +2261 800c +2262 8033 +2263 81ea +2264 8494 +2265 8f9e +2266 6c50 +2267 9e7f +2268 5f0f +2269 8b58 +2270 9d2b +2271 7afa +2272 8ef8 +2273 5b8d +2274 96eb +2275 4e03 +2276 53f1 +2277 57f7 +2278 5931 +2279 5ac9 +2280 5ba4 +2281 6089 +2282 6e7f +2283 6f06 +2284 75be +2285 8cea +2286 5b9f +2287 8500 +2288 7be0 +2289 5072 +2290 67f4 +2291 829d +2292 5c61 +2293 854a +2294 7e1e +2295 820e +2296 5199 +2297 5c04 +2298 6368 +2299 8d66 +2300 659c +2301 716e +2302 793e +2303 7d17 +2304 8005 +2305 8b1d +2306 8eca +2307 906e +2308 86c7 +2309 90aa +2310 501f +2311 52fa +2312 5c3a +2313 6753 +2314 707c +2315 7235 +2316 914c +2317 91c8 +2318 932b +2319 82e5 +2320 5bc2 +2321 5f31 +2322 60f9 +2323 4e3b +2324 53d6 +2325 5b88 +2326 624b +2327 6731 +2328 6b8a +2329 72e9 +2330 73e0 +2331 7a2e +2332 816b +2333 8da3 +2334 9152 +2335 9996 +2336 5112 +2337 53d7 +2338 546a +2339 5bff +2340 6388 +2341 6a39 +2342 7dac +2343 9700 +2344 56da +2345 53ce +2346 5468 +2347 5b97 +2348 5c31 +2349 5dde +2350 4fee +2351 6101 +2352 62fe +2353 6d32 +2354 79c0 +2355 79cb +2356 7d42 +2357 7e4d +2358 7fd2 +2359 81ed +2360 821f +2361 8490 +2362 8846 +2363 8972 +2364 8b90 +2365 8e74 +2366 8f2f +2367 9031 +2368 914b +2369 916c +2370 96c6 +2371 919c +2372 4ec0 +2373 4f4f +2374 5145 +2375 5341 +2376 5f93 +2377 620e +2378 67d4 +2379 6c41 +2380 6e0b +2381 7363 +2382 7e26 +2383 91cd +2384 9283 +2385 53d4 +2386 5919 +2387 5bbf +2388 6dd1 +2389 795d +2390 7e2e +2391 7c9b +2392 587e +2393 719f +2394 51fa +2395 8853 +2396 8ff0 +2397 4fca +2398 5cfb +2399 6625 +2400 77ac +2401 7ae3 +2402 821c +2403 99ff +2404 51c6 +2405 5faa +2406 65ec +2407 696f +2408 6b89 +2409 6df3 +2410 6e96 +2411 6f64 +2412 76fe +2413 7d14 +2414 5de1 +2415 9075 +2416 9187 +2417 9806 +2418 51e6 +2419 521d +2420 6240 +2421 6691 +2422 66d9 +2423 6e1a +2424 5eb6 +2425 7dd2 +2426 7f72 +2427 66f8 +2428 85af +2429 85f7 +2430 8af8 +2431 52a9 +2432 53d9 +2433 5973 +2434 5e8f +2435 5f90 +2436 6055 +2437 92e4 +2438 9664 +2439 50b7 +2440 511f +2441 52dd +2442 5320 +2443 5347 +2444 53ec +2445 54e8 +2446 5546 +2447 5531 +2448 5617 +2449 5968 +2450 59be +2451 5a3c +2452 5bb5 +2453 5c06 +2454 5c0f +2455 5c11 +2456 5c1a +2457 5e84 +2458 5e8a +2459 5ee0 +2460 5f70 +2461 627f +2462 6284 +2463 62db +2464 638c +2465 6377 +2466 6607 +2467 660c +2468 662d +2469 6676 +2470 677e +2471 68a2 +2472 6a1f +2473 6a35 +2474 6cbc +2475 6d88 +2476 6e09 +2477 6e58 +2478 713c +2479 7126 +2480 7167 +2481 75c7 +2482 7701 +2483 785d +2484 7901 +2485 7965 +2486 79f0 +2487 7ae0 +2488 7b11 +2489 7ca7 +2490 7d39 +2491 8096 +2492 83d6 +2493 848b +2494 8549 +2495 885d +2496 88f3 +2497 8a1f +2498 8a3c +2499 8a54 +2500 8a73 +2501 8c61 +2502 8cde +2503 91a4 +2504 9266 +2505 937e +2506 9418 +2507 969c +2508 9798 +2509 4e0a +2510 4e08 +2511 4e1e +2512 4e57 +2513 5197 +2514 5270 +2515 57ce +2516 5834 +2517 58cc +2518 5b22 +2519 5e38 +2520 60c5 +2521 64fe +2522 6761 +2523 6756 +2524 6d44 +2525 72b6 +2526 7573 +2527 7a63 +2528 84b8 +2529 8b72 +2530 91b8 +2531 9320 +2532 5631 +2533 57f4 +2534 98fe +2535 62ed +2536 690d +2537 6b96 +2538 71ed +2539 7e54 +2540 8077 +2541 8272 +2542 89e6 +2543 98df +2544 8755 +2545 8fb1 +2546 5c3b +2547 4f38 +2548 4fe1 +2549 4fb5 +2550 5507 +2551 5a20 +2552 5bdd +2553 5be9 +2554 5fc3 +2555 614e +2556 632f +2557 65b0 +2558 664b +2559 68ee +2560 699b +2561 6d78 +2562 6df1 +2563 7533 +2564 75b9 +2565 771f +2566 795e +2567 79e6 +2568 7d33 +2569 81e3 +2570 82af +2571 85aa +2572 89aa +2573 8a3a +2574 8eab +2575 8f9b +2576 9032 +2577 91dd +2578 9707 +2579 4eba +2580 4ec1 +2581 5203 +2582 5875 +2583 58ec +2584 5c0b +2585 751a +2586 5c3d +2587 814e +2588 8a0a +2589 8fc5 +2590 9663 +2591 976d +2592 7b25 +2593 8acf +2594 9808 +2595 9162 +2596 56f3 +2597 53a8 +2598 9017 +2599 5439 +2600 5782 +2601 5e25 +2602 63a8 +2603 6c34 +2604 708a +2605 7761 +2606 7c8b +2607 7fe0 +2608 8870 +2609 9042 +2610 9154 +2611 9310 +2612 9318 +2613 968f +2614 745e +2615 9ac4 +2616 5d07 +2617 5d69 +2618 6570 +2619 67a2 +2620 8da8 +2621 96db +2622 636e +2623 6749 +2624 6919 +2625 83c5 +2626 9817 +2627 96c0 +2628 88fe +2629 6f84 +2630 647a +2631 5bf8 +2632 4e16 +2633 702c +2634 755d +2635 662f +2636 51c4 +2637 5236 +2638 52e2 +2639 59d3 +2640 5f81 +2641 6027 +2642 6210 +2643 653f +2644 6574 +2645 661f +2646 6674 +2647 68f2 +2648 6816 +2649 6b63 +2650 6e05 +2651 7272 +2652 751f +2653 76db +2654 7cbe +2655 8056 +2656 58f0 +2657 88fd +2658 897f +2659 8aa0 +2660 8a93 +2661 8acb +2662 901d +2663 9192 +2664 9752 +2665 9759 +2666 6589 +2667 7a0e +2668 8106 +2669 96bb +2670 5e2d +2671 60dc +2672 621a +2673 65a5 +2674 6614 +2675 6790 +2676 77f3 +2677 7a4d +2678 7c4d +2679 7e3e +2680 810a +2681 8cac +2682 8d64 +2683 8de1 +2684 8e5f +2685 78a9 +2686 5207 +2687 62d9 +2688 63a5 +2689 6442 +2690 6298 +2691 8a2d +2692 7a83 +2693 7bc0 +2694 8aac +2695 96ea +2696 7d76 +2697 820c +2698 8749 +2699 4ed9 +2700 5148 +2701 5343 +2702 5360 +2703 5ba3 +2704 5c02 +2705 5c16 +2706 5ddd +2707 6226 +2708 6247 +2709 64b0 +2710 6813 +2711 6834 +2712 6cc9 +2713 6d45 +2714 6d17 +2715 67d3 +2716 6f5c +2717 714e +2718 717d +2719 65cb +2720 7a7f +2721 7bad +2722 7dda +2723 7e4a +2724 7fa8 +2725 817a +2726 821b +2727 8239 +2728 85a6 +2729 8a6e +2730 8cce +2731 8df5 +2732 9078 +2733 9077 +2734 92ad +2735 9291 +2736 9583 +2737 9bae +2738 524d +2739 5584 +2740 6f38 +2741 7136 +2742 5168 +2743 7985 +2744 7e55 +2745 81b3 +2746 7cce +2747 564c +2748 5851 +2749 5ca8 +2750 63aa +2751 66fe +2752 66fd +2753 695a +2754 72d9 +2755 758f +2756 758e +2757 790e +2758 7956 +2759 79df +2760 7c97 +2761 7d20 +2762 7d44 +2763 8607 +2764 8a34 +2765 963b +2766 9061 +2767 9f20 +2768 50e7 +2769 5275 +2770 53cc +2771 53e2 +2772 5009 +2773 55aa +2774 58ee +2775 594f +2776 723d +2777 5b8b +2778 5c64 +2779 531d +2780 60e3 +2781 60f3 +2782 635c +2783 6383 +2784 633f +2785 63bb +2786 64cd +2787 65e9 +2788 66f9 +2789 5de3 +2790 69cd +2791 69fd +2792 6f15 +2793 71e5 +2794 4e89 +2795 75e9 +2796 76f8 +2797 7a93 +2798 7cdf +2799 7dcf +2800 7d9c +2801 8061 +2802 8349 +2803 8358 +2804 846c +2805 84bc +2806 85fb +2807 88c5 +2808 8d70 +2809 9001 +2810 906d +2811 9397 +2812 971c +2813 9a12 +2814 50cf +2815 5897 +2816 618e +2817 81d3 +2818 8535 +2819 8d08 +2820 9020 +2821 4fc3 +2822 5074 +2823 5247 +2824 5373 +2825 606f +2826 6349 +2827 675f +2828 6e2c +2829 8db3 +2830 901f +2831 4fd7 +2832 5c5e +2833 8cca +2834 65cf +2835 7d9a +2836 5352 +2837 8896 +2838 5176 +2839 63c3 +2840 5b58 +2841 5b6b +2842 5c0a +2843 640d +2844 6751 +2845 905c +2846 4ed6 +2847 591a +2848 592a +2849 6c70 +2850 8a51 +2851 553e +2852 5815 +2853 59a5 +2854 60f0 +2855 6253 +2856 67c1 +2857 8235 +2858 6955 +2859 9640 +2860 99c4 +2861 9a28 +2862 4f53 +2863 5806 +2864 5bfe +2865 8010 +2866 5cb1 +2867 5e2f +2868 5f85 +2869 6020 +2870 614b +2871 6234 +2872 66ff +2873 6cf0 +2874 6ede +2875 80ce +2876 817f +2877 82d4 +2878 888b +2879 8cb8 +2880 9000 +2881 902e +2882 968a +2883 9edb +2884 9bdb +2885 4ee3 +2886 53f0 +2887 5927 +2888 7b2c +2889 918d +2890 984c +2891 9df9 +2892 6edd +2893 7027 +2894 5353 +2895 5544 +2896 5b85 +2897 6258 +2898 629e +2899 62d3 +2900 6ca2 +2901 6fef +2902 7422 +2903 8a17 +2904 9438 +2905 6fc1 +2906 8afe +2907 8338 +2908 51e7 +2909 86f8 +2910 53ea +2911 53e9 +2912 4f46 +2913 9054 +2914 8fb0 +2915 596a +2916 8131 +2917 5dfd +2918 7aea +2919 8fbf +2920 68da +2921 8c37 +2922 72f8 +2923 9c48 +2924 6a3d +2925 8ab0 +2926 4e39 +2927 5358 +2928 5606 +2929 5766 +2930 62c5 +2931 63a2 +2932 65e6 +2933 6b4e +2934 6de1 +2935 6e5b +2936 70ad +2937 77ed +2938 7aef +2939 7baa +2940 7dbb +2941 803d +2942 80c6 +2943 86cb +2944 8a95 +2945 935b +2946 56e3 +2947 58c7 +2948 5f3e +2949 65ad +2950 6696 +2951 6a80 +2952 6bb5 +2953 7537 +2954 8ac7 +2955 5024 +2956 77e5 +2957 5730 +2958 5f1b +2959 6065 +2960 667a +2961 6c60 +2962 75f4 +2963 7a1a +2964 7f6e +2965 81f4 +2966 8718 +2967 9045 +2968 99b3 +2969 7bc9 +2970 755c +2971 7af9 +2972 7b51 +2973 84c4 +2974 9010 +2975 79e9 +2976 7a92 +2977 8336 +2978 5ae1 +2979 7740 +2980 4e2d +2981 4ef2 +2982 5b99 +2983 5fe0 +2984 62bd +2985 663c +2986 67f1 +2987 6ce8 +2988 866b +2989 8877 +2990 8a3b +2991 914e +2992 92f3 +2993 99d0 +2994 6a17 +2995 7026 +2996 732a +2997 82e7 +2998 8457 +2999 8caf +3000 4e01 +3001 5146 +3002 51cb +3003 558b +3004 5bf5 +3005 5e16 +3006 5e33 +3007 5e81 +3008 5f14 +3009 5f35 +3010 5f6b +3011 5fb4 +3012 61f2 +3013 6311 +3014 66a2 +3015 671d +3016 6f6e +3017 7252 +3018 753a +3019 773a +3020 8074 +3021 8139 +3022 8178 +3023 8776 +3024 8abf +3025 8adc +3026 8d85 +3027 8df3 +3028 929a +3029 9577 +3030 9802 +3031 9ce5 +3032 52c5 +3033 6357 +3034 76f4 +3035 6715 +3036 6c88 +3037 73cd +3038 8cc3 +3039 93ae +3040 9673 +3041 6d25 +3042 589c +3043 690e +3044 69cc +3045 8ffd +3046 939a +3047 75db +3048 901a +3049 585a +3050 6802 +3051 63b4 +3052 69fb +3053 4f43 +3054 6f2c +3055 67d8 +3056 8fbb +3057 8526 +3058 7db4 +3059 9354 +3060 693f +3061 6f70 +3062 576a +3063 58f7 +3064 5b2c +3065 7d2c +3066 722a +3067 540a +3068 91e3 +3069 9db4 +3070 4ead +3071 4f4e +3072 505c +3073 5075 +3074 5243 +3075 8c9e +3076 5448 +3077 5824 +3078 5b9a +3079 5e1d +3080 5e95 +3081 5ead +3082 5ef7 +3083 5f1f +3084 608c +3085 62b5 +3086 633a +3087 63d0 +3088 68af +3089 6c40 +3090 7887 +3091 798e +3092 7a0b +3093 7de0 +3094 8247 +3095 8a02 +3096 8ae6 +3097 8e44 +3098 9013 +3099 90b8 +3100 912d +3101 91d8 +3102 9f0e +3103 6ce5 +3104 6458 +3105 64e2 +3106 6575 +3107 6ef4 +3108 7684 +3109 7b1b +3110 9069 +3111 93d1 +3112 6eba +3113 54f2 +3114 5fb9 +3115 64a4 +3116 8f4d +3117 8fed +3118 9244 +3119 5178 +3120 586b +3121 5929 +3122 5c55 +3123 5e97 +3124 6dfb +3125 7e8f +3126 751c +3127 8cbc +3128 8ee2 +3129 985b +3130 70b9 +3131 4f1d +3132 6bbf +3133 6fb1 +3134 7530 +3135 96fb +3136 514e +3137 5410 +3138 5835 +3139 5857 +3140 59ac +3141 5c60 +3142 5f92 +3143 6597 +3144 675c +3145 6e21 +3146 767b +3147 83df +3148 8ced +3149 9014 +3150 90fd +3151 934d +3152 7825 +3153 783a +3154 52aa +3155 5ea6 +3156 571f +3157 5974 +3158 6012 +3159 5012 +3160 515a +3161 51ac +3162 51cd +3163 5200 +3164 5510 +3165 5854 +3166 5858 +3167 5957 +3168 5b95 +3169 5cf6 +3170 5d8b +3171 60bc +3172 6295 +3173 642d +3174 6771 +3175 6843 +3176 68bc +3177 68df +3178 76d7 +3179 6dd8 +3180 6e6f +3181 6d9b +3182 706f +3183 71c8 +3184 5f53 +3185 75d8 +3186 7977 +3187 7b49 +3188 7b54 +3189 7b52 +3190 7cd6 +3191 7d71 +3192 5230 +3193 8463 +3194 8569 +3195 85e4 +3196 8a0e +3197 8b04 +3198 8c46 +3199 8e0f +3200 9003 +3201 900f +3202 9419 +3203 9676 +3204 982d +3205 9a30 +3206 95d8 +3207 50cd +3208 52d5 +3209 540c +3210 5802 +3211 5c0e +3212 61a7 +3213 649e +3214 6d1e +3215 77b3 +3216 7ae5 +3217 80f4 +3218 8404 +3219 9053 +3220 9285 +3221 5ce0 +3222 9d07 +3223 533f +3224 5f97 +3225 5fb3 +3226 6d9c +3227 7279 +3228 7763 +3229 79bf +3230 7be4 +3231 6bd2 +3232 72ec +3233 8aad +3234 6803 +3235 6a61 +3236 51f8 +3237 7a81 +3238 6934 +3239 5c4a +3240 9cf6 +3241 82eb +3242 5bc5 +3243 9149 +3244 701e +3245 5678 +3246 5c6f +3247 60c7 +3248 6566 +3249 6c8c +3250 8c5a +3251 9041 +3252 9813 +3253 5451 +3254 66c7 +3255 920d +3256 5948 +3257 90a3 +3258 5185 +3259 4e4d +3260 51ea +3261 8599 +3262 8b0e +3263 7058 +3264 637a +3265 934b +3266 6962 +3267 99b4 +3268 7e04 +3269 7577 +3270 5357 +3271 6960 +3272 8edf +3273 96e3 +3274 6c5d +3275 4e8c +3276 5c3c +3277 5f10 +3278 8fe9 +3279 5302 +3280 8cd1 +3281 8089 +3282 8679 +3283 5eff +3284 65e5 +3285 4e73 +3286 5165 +3287 5982 +3288 5c3f +3289 97ee +3290 4efb +3291 598a +3292 5fcd +3293 8a8d +3294 6fe1 +3295 79b0 +3296 7962 +3297 5be7 +3298 8471 +3299 732b +3300 71b1 +3301 5e74 +3302 5ff5 +3303 637b +3304 649a +3305 71c3 +3306 7c98 +3307 4e43 +3308 5efc +3309 4e4b +3310 57dc +3311 56a2 +3312 60a9 +3313 6fc3 +3314 7d0d +3315 80fd +3316 8133 +3317 81bf +3318 8fb2 +3319 8997 +3320 86a4 +3321 5df4 +3322 628a +3323 64ad +3324 8987 +3325 6777 +3326 6ce2 +3327 6d3e +3328 7436 +3329 7834 +3330 5a46 +3331 7f75 +3332 82ad +3333 99ac +3334 4ff3 +3335 5ec3 +3336 62dd +3337 6392 +3338 6557 +3339 676f +3340 76c3 +3341 724c +3342 80cc +3343 80ba +3344 8f29 +3345 914d +3346 500d +3347 57f9 +3348 5a92 +3349 6885 +3350 6973 +3351 7164 +3352 72fd +3353 8cb7 +3354 58f2 +3355 8ce0 +3356 966a +3357 9019 +3358 877f +3359 79e4 +3360 77e7 +3361 8429 +3362 4f2f +3363 5265 +3364 535a +3365 62cd +3366 67cf +3367 6cca +3368 767d +3369 7b94 +3370 7c95 +3371 8236 +3372 8584 +3373 8feb +3374 66dd +3375 6f20 +3376 7206 +3377 7e1b +3378 83ab +3379 99c1 +3380 9ea6 +3381 51fd +3382 7bb1 +3383 7872 +3384 7bb8 +3385 8087 +3386 7b48 +3387 6ae8 +3388 5e61 +3389 808c +3390 7551 +3391 7560 +3392 516b +3393 9262 +3394 6e8c +3395 767a +3396 9197 +3397 9aea +3398 4f10 +3399 7f70 +3400 629c +3401 7b4f +3402 95a5 +3403 9ce9 +3404 567a +3405 5859 +3406 86e4 +3407 96bc +3408 4f34 +3409 5224 +3410 534a +3411 53cd +3412 53db +3413 5e06 +3414 642c +3415 6591 +3416 677f +3417 6c3e +3418 6c4e +3419 7248 +3420 72af +3421 73ed +3422 7554 +3423 7e41 +3424 822c +3425 85e9 +3426 8ca9 +3427 7bc4 +3428 91c6 +3429 7169 +3430 9812 +3431 98ef +3432 633d +3433 6669 +3434 756a +3435 76e4 +3436 78d0 +3437 8543 +3438 86ee +3439 532a +3440 5351 +3441 5426 +3442 5983 +3443 5e87 +3444 5f7c +3445 60b2 +3446 6249 +3447 6279 +3448 62ab +3449 6590 +3450 6bd4 +3451 6ccc +3452 75b2 +3453 76ae +3454 7891 +3455 79d8 +3456 7dcb +3457 7f77 +3458 80a5 +3459 88ab +3460 8ab9 +3461 8cbb +3462 907f +3463 975e +3464 98db +3465 6a0b +3466 7c38 +3467 5099 +3468 5c3e +3469 5fae +3470 6787 +3471 6bd8 +3472 7435 +3473 7709 +3474 7f8e +3475 9f3b +3476 67ca +3477 7a17 +3478 5339 +3479 758b +3480 9aed +3481 5f66 +3482 819d +3483 83f1 +3484 8098 +3485 5f3c +3486 5fc5 +3487 7562 +3488 7b46 +3489 903c +3490 6867 +3491 59eb +3492 5a9b +3493 7d10 +3494 767e +3495 8b2c +3496 4ff5 +3497 5f6a +3498 6a19 +3499 6c37 +3500 6f02 +3501 74e2 +3502 7968 +3503 8868 +3504 8a55 +3505 8c79 +3506 5edf +3507 63cf +3508 75c5 +3509 79d2 +3510 82d7 +3511 9328 +3512 92f2 +3513 849c +3514 86ed +3515 9c2d +3516 54c1 +3517 5f6c +3518 658c +3519 6d5c +3520 7015 +3521 8ca7 +3522 8cd3 +3523 983b +3524 654f +3525 74f6 +3526 4e0d +3527 4ed8 +3528 57e0 +3529 592b +3530 5a66 +3531 5bcc +3532 51a8 +3533 5e03 +3534 5e9c +3535 6016 +3536 6276 +3537 6577 +3538 65a7 +3539 666e +3540 6d6e +3541 7236 +3542 7b26 +3543 8150 +3544 819a +3545 8299 +3546 8b5c +3547 8ca0 +3548 8ce6 +3549 8d74 +3550 961c +3551 9644 +3552 4fae +3553 64ab +3554 6b66 +3555 821e +3556 8461 +3557 856a +3558 90e8 +3559 5c01 +3560 6953 +3561 98a8 +3562 847a +3563 8557 +3564 4f0f +3565 526f +3566 5fa9 +3567 5e45 +3568 670d +3569 798f +3570 8179 +3571 8907 +3572 8986 +3573 6df5 +3574 5f17 +3575 6255 +3576 6cb8 +3577 4ecf +3578 7269 +3579 9b92 +3580 5206 +3581 543b +3582 5674 +3583 58b3 +3584 61a4 +3585 626e +3586 711a +3587 596e +3588 7c89 +3589 7cde +3590 7d1b +3591 96f0 +3592 6587 +3593 805e +3594 4e19 +3595 4f75 +3596 5175 +3597 5840 +3598 5e63 +3599 5e73 +3600 5f0a +3601 67c4 +3602 4e26 +3603 853d +3604 9589 +3605 965b +3606 7c73 +3607 9801 +3608 50fb +3609 58c1 +3610 7656 +3611 78a7 +3612 5225 +3613 77a5 +3614 8511 +3615 7b86 +3616 504f +3617 5909 +3618 7247 +3619 7bc7 +3620 7de8 +3621 8fba +3622 8fd4 +3623 904d +3624 4fbf +3625 52c9 +3626 5a29 +3627 5f01 +3628 97ad +3629 4fdd +3630 8217 +3631 92ea +3632 5703 +3633 6355 +3634 6b69 +3635 752b +3636 88dc +3637 8f14 +3638 7a42 +3639 52df +3640 5893 +3641 6155 +3642 620a +3643 66ae +3644 6bcd +3645 7c3f +3646 83e9 +3647 5023 +3648 4ff8 +3649 5305 +3650 5446 +3651 5831 +3652 5949 +3653 5b9d +3654 5cf0 +3655 5cef +3656 5d29 +3657 5e96 +3658 62b1 +3659 6367 +3660 653e +3661 65b9 +3662 670b +3663 6cd5 +3664 6ce1 +3665 70f9 +3666 7832 +3667 7e2b +3668 80de +3669 82b3 +3670 840c +3671 84ec +3672 8702 +3673 8912 +3674 8a2a +3675 8c4a +3676 90a6 +3677 92d2 +3678 98fd +3679 9cf3 +3680 9d6c +3681 4e4f +3682 4ea1 +3683 508d +3684 5256 +3685 574a +3686 59a8 +3687 5e3d +3688..3689 5fd8 +3690 623f +3691 66b4 +3692 671b +3693 67d0 +3694 68d2 +3695 5192 +3696 7d21 +3697 80aa +3698 81a8 +3699 8b00 +3700 8c8c +3701 8cbf +3702 927e +3703 9632 +3704 5420 +3705 982c +3706 5317 +3707 50d5 +3708 535c +3709 58a8 +3710 64b2 +3711 6734 +3712 7267 +3713 7766 +3714 7a46 +3715 91e6 +3716 52c3 +3717 6ca1 +3718 6b86 +3719 5800 +3720 5e4c +3721 5954 +3722 672c +3723 7ffb +3724 51e1 +3725 76c6 +3726 6469 +3727 78e8 +3728 9b54 +3729 9ebb +3730 57cb +3731 59b9 +3732 6627 +3733 679a +3734 6bce +3735 54e9 +3736 69d9 +3737 5e55 +3738 819c +3739 6795 +3740 9baa +3741 67fe +3742 9c52 +3743 685d +3744 4ea6 +3745 4fe3 +3746 53c8 +3747 62b9 +3748 672b +3749 6cab +3750 8fc4 +3751 4fad +3752 7e6d +3753 9ebf +3754 4e07 +3755 6162 +3756 6e80 +3757 6f2b +3758 8513 +3759 5473 +3760 672a +3761 9b45 +3762 5df3 +3763 7b95 +3764 5cac +3765 5bc6 +3766 871c +3767 6e4a +3768 84d1 +3769 7a14 +3770 8108 +3771 5999 +3772 7c8d +3773 6c11 +3774 7720 +3775 52d9 +3776 5922 +3777 7121 +3778 725f +3779 77db +3780 9727 +3781 9d61 +3782 690b +3783 5a7f +3784 5a18 +3785 51a5 +3786 540d +3787 547d +3788 660e +3789 76df +3790 8ff7 +3791 9298 +3792 9cf4 +3793 59ea +3794 725d +3795 6ec5 +3796 514d +3797 68c9 +3798 7dbf +3799 7dec +3800 9762 +3801 9eba +3802 6478 +3803 6a21 +3804 8302 +3805 5984 +3806 5b5f +3807 6bdb +3808 731b +3809 76f2 +3810 7db2 +3811 8017 +3812 8499 +3813 5132 +3814 6728 +3815 9ed9 +3816 76ee +3817 6762 +3818 52ff +3819 9905 +3820 5c24 +3821 623b +3822 7c7e +3823 8cb0 +3824 554f +3825 60b6 +3826 7d0b +3827 9580 +3828 5301 +3829 4e5f +3830 51b6 +3831 591c +3832 723a +3833 8036 +3834 91ce +3835 5f25 +3836 77e2 +3837 5384 +3838 5f79 +3839 7d04 +3840 85ac +3841 8a33 +3842 8e8d +3843 9756 +3844 67f3 +3845 85ae +3846 9453 +3847 6109 +3848 6108 +3849 6cb9 +3850 7652 +3851 8aed +3852 8f38 +3853 552f +3854 4f51 +3855 512a +3856 52c7 +3857 53cb +3858 5ba5 +3859 5e7d +3860 60a0 +3861 6182 +3862 63d6 +3863 6709 +3864 67da +3865 6e67 +3866 6d8c +3867..3868 7336 +3869 7531 +3870 7950 +3871 88d5 +3872 8a98 +3873 904a +3874 9091 +3875 90f5 +3876 96c4 +3877 878d +3878 5915 +3879 4e88 +3880 4f59 +3881 4e0e +3882 8a89 +3883 8f3f +3884 9810 +3885 50ad +3886 5e7c +3887 5996 +3888 5bb9 +3889 5eb8 +3890 63da +3891 63fa +3892 64c1 +3893 66dc +3894 694a +3895 69d8 +3896 6d0b +3897 6eb6 +3898 7194 +3899 7528 +3900 7aaf +3901 7f8a +3902 8000 +3903 8449 +3904 84c9 +3905 8981 +3906 8b21 +3907 8e0a +3908 9065 +3909 967d +3910 990a +3911 617e +3912 6291 +3913 6b32 +3914 6c83 +3915 6d74 +3916 7fcc +3917 7ffc +3918 6dc0 +3919 7f85 +3920 87ba +3921 88f8 +3922 6765 +3923 83b1 +3924 983c +3925 96f7 +3926 6d1b +3927 7d61 +3928 843d +3929 916a +3930 4e71 +3931 5375 +3932 5d50 +3933 6b04 +3934 6feb +3935 85cd +3936 862d +3937 89a7 +3938 5229 +3939 540f +3940 5c65 +3941 674e +3942 68a8 +3943 7406 +3944 7483 +3945 75e2 +3946 88cf +3947 88e1 +3948 91cc +3949 96e2 +3950 9678 +3951 5f8b +3952 7387 +3953 7acb +3954 844e +3955 63a0 +3956 7565 +3957 5289 +3958 6d41 +3959 6e9c +3960 7409 +3961 7559 +3962 786b +3963 7c92 +3964 9686 +3965 7adc +3966 9f8d +3967 4fb6 +3968 616e +3969 65c5 +3970 865c +3971 4e86 +3972 4eae +3973 50da +3974 4e21 +3975 51cc +3976 5bee +3977 6599 +3978 6881 +3979 6dbc +3980 731f +3981 7642 +3982 77ad +3983 7a1c +3984 7ce7 +3985 826f +3986 8ad2 +3987 907c +3988 91cf +3989 9675 +3990 9818 +3991 529b +3992 7dd1 +3993 502b +3994 5398 +3995 6797 +3996 6dcb +3997 71d0 +3998 7433 +3999 81e8 +4000 8f2a +4001 96a3 +4002 9c57 +4003 9e9f +4004 7460 +4005 5841 +4006 6d99 +4007 7d2f +4008 985e +4009 4ee4 +4010 4f36 +4011 4f8b +4012 51b7 +4013 52b1 +4014 5dba +4015 601c +4016 73b2 +4017 793c +4018 82d3 +4019 9234 +4020 96b7 +4021 96f6 +4022 970a +4023 9e97 +4024 9f62 +4025 66a6 +4026 6b74 +4027 5217 +4028 52a3 +4029 70c8 +4030 88c2 +4031 5ec9 +4032 604b +4033 6190 +4034 6f23 +4035 7149 +4036 7c3e +4037 7df4 +4038 806f +4039 84ee +4040 9023 +4041 932c +4042 5442 +4043 9b6f +4044 6ad3 +4045 7089 +4046 8cc2 +4047 8def +4048 9732 +4049 52b4 +4050 5a41 +4051 5eca +4052 5f04 +4053 6717 +4054 697c +4055 6994 +4056 6d6a +4057 6f0f +4058 7262 +4059 72fc +4060 7bed +4061 8001 +4062 807e +4063 874b +4064 90ce +4065 516d +4066 9e93 +4067 7984 +4068 808b +4069 9332 +4070 8ad6 +4071 502d +4072 548c +4073 8a71 +4074 6b6a +4075 8cc4 +4076 8107 +4077 60d1 +4078 67a0 +4079 9df2 +4080 4e99 +4081 4e98 +4082 9c10 +4083 8a6b +4084 85c1 +4085 8568 +4086 6900 +4087 6e7e +4088 7897 +4089 8155 +4090 5f0c +4091 4e10 +4092 4e15 +4093 4e2a +4094 4e31 +4095 4e36 +4096 4e3c +4097 4e3f +4098 4e42 +4099 4e56 +4100 4e58 +4101 4e82 +4102 4e85 +4103 8c6b +4104 4e8a +4105 8212 +4106 5f0d +4107 4e8e +4108..4110 4e9e +4111 4ea2 +4112 4eb0 +4113 4eb3 +4114 4eb6 +4115 4ece +4116 4ecd +4117 4ec4 +4118 4ec6 +4119 4ec2 +4120 4ed7 +4121 4ede +4122 4eed +4123 4edf +4124 4ef7 +4125 4f09 +4126 4f5a +4127 4f30 +4128 4f5b +4129 4f5d +4130 4f57 +4131 4f47 +4132 4f76 +4133 4f88 +4134 4f8f +4135 4f98 +4136 4f7b +4137 4f69 +4138 4f70 +4139 4f91 +4140 4f6f +4141 4f86 +4142 4f96 +4143 5118 +4144 4fd4 +4145 4fdf +4146 4fce +4147 4fd8 +4148 4fdb +4149 4fd1 +4150 4fda +4151 4fd0 +4152..4153 4fe4 +4154 501a +4155 5028 +4156 5014 +4157 502a +4158 5025 +4159 5005 +4160 4f1c +4161 4ff6 +4162 5021 +4163 5029 +4164 502c +4165 4ffe +4166 4fef +4167 5011 +4168 5006 +4169 5043 +4170 5047 +4171 6703 +4172 5055 +4173 5050 +4174 5048 +4175 505a +4176 5056 +4177 506c +4178 5078 +4179 5080 +4180 509a +4181 5085 +4182 50b4 +4183 50b2 +4184..4185 50c9 +4186 50b3 +4187 50c2 +4188 50d6 +4189 50de +4190 50e5 +4191 50ed +4192 50e3 +4193 50ee +4194 50f9 +4195 50f5 +4196 5109 +4197..4198 5101 +4199 5116 +4200 5115 +4201 5114 +4202 511a +4203 5121 +4204 513a +4205 5137 +4206 513c +4207 513b +4208..4209 513f +4210 5152 +4211 514c +4212 5154 +4213 5162 +4214 7af8 +4215..4216 5169 +4217 516e +4218 5180 +4219 5182 +4220 56d8 +4221 518c +4222 5189 +4223 518f +4224 5191 +4225 5193 +4226..4227 5195 +4228 51a4 +4229 51a6 +4230 51a2 +4231..4233 51a9 +4234 51b3 +4235..4236 51b1 +4237 51b0 +4238 51b5 +4239 51bd +4240 51c5 +4241 51c9 +4242 51db +4243 51e0 +4244 8655 +4245 51e9 +4246 51ed +4247 51f0 +4248 51f5 +4249 51fe +4250 5204 +4251 520b +4252 5214 +4253 520e +4254 5227 +4255 522a +4256 522e +4257 5233 +4258 5239 +4259 524f +4260 5244 +4261..4262 524b +4263 525e +4264 5254 +4265 526a +4266 5274 +4267 5269 +4268 5273 +4269 527f +4270 527d +4271 528d +4272 5294 +4273 5292 +4274 5271 +4275 5288 +4276 5291 +4277 8fa8 +4278 8fa7 +4279..4280 52ac +4281 52bc +4282 52b5 +4283 52c1 +4284 52cd +4285 52d7 +4286 52de +4287 52e3 +4288 52e6 +4289 98ed +4290 52e0 +4291 52f3 +4292 52f5 +4293..4294 52f8 +4295 5306 +4296 5308 +4297 7538 +4298 530d +4299 5310 +4300 530f +4301 5315 +4302 531a +4303 5323 +4304 532f +4305 5331 +4306 5333 +4307 5338 +4308 5340 +4309 5346 +4310 5345 +4311 4e17 +4312 5349 +4313 534d +4314 51d6 +4315 535e +4316 5369 +4317 536e +4318 5918 +4319 537b +4320 5377 +4321 5382 +4322 5396 +4323 53a0 +4324 53a6 +4325 53a5 +4326 53ae +4327 53b0 +4328 53b6 +4329 53c3 +4330 7c12 +4331 96d9 +4332 53df +4333 66fc +4334 71ee +4335 53ee +4336 53e8 +4337 53ed +4338 53fa +4339 5401 +4340 543d +4341 5440 +4342..4343 542c +4344 543c +4345 542e +4346 5436 +4347 5429 +4348 541d +4349 544e +4350 548f +4351 5475 +4352 548e +4353 545f +4354 5471 +4355 5477 +4356 5470 +4357 5492 +4358 547b +4359 5480 +4360 5476 +4361 5484 +4362 5490 +4363 5486 +4364 54c7 +4365 54a2 +4366 54b8 +4367 54a5 +4368 54ac +4369 54c4 +4370 54c8 +4371 54a8 +4372 54ab +4373 54c2 +4374 54a4 +4375 54be +4376 54bc +4377 54d8 +4378..4379 54e5 +4380 550f +4381 5514 +4382 54fd +4383 54ee +4384 54ed +4385 54fa +4386 54e2 +4387 5539 +4388 5540 +4389 5563 +4390 554c +4391 552e +4392 555c +4393 5545 +4394..4395 5556 +4396 5538 +4397 5533 +4398 555d +4399 5599 +4400 5580 +4401 54af +4402 558a +4403 559f +4404 557b +4405 557e +4406 5598 +4407 559e +4408 55ae +4409 557c +4410 5583 +4411 55a9 +4412 5587 +4413 55a8 +4414 55da +4415 55c5 +4416 55df +4417 55c4 +4418 55dc +4419 55e4 +4420 55d4 +4421 5614 +4422 55f7 +4423 5616 +4424 55fe +4425 55fd +4426 561b +4427 55f9 +4428 564e +4429 5650 +4430 71df +4431 5634 +4432 5636 +4433 5632 +4434 5638 +4435 566b +4436 5664 +4437 562f +4438 566c +4439 566a +4440 5686 +4441 5680 +4442 568a +4443 56a0 +4444 5694 +4445 568f +4446 56a5 +4447 56ae +4448 56b6 +4449 56b4 +4450 56c2 +4451 56bc +4452 56c1 +4453 56c3 +4454 56c0 +4455 56c8 +4456 56ce +4457 56d1 +4458 56d3 +4459 56d7 +4460 56ee +4461 56f9 +4462 5700 +4463 56ff +4464 5704 +4465 5709 +4466 5708 +4467 570b +4468 570d +4469 5713 +4470 5718 +4471 5716 +4472 55c7 +4473 571c +4474 5726 +4475..4476 5737 +4477 574e +4478 573b +4479 5740 +4480 574f +4481 5769 +4482 57c0 +4483 5788 +4484 5761 +4485 577f +4486 5789 +4487 5793 +4488 57a0 +4489 57b3 +4490 57a4 +4491 57aa +4492 57b0 +4493 57c3 +4494 57c6 +4495 57d4 +4496..4497 57d2 +4498 580a +4499 57d6 +4500 57e3 +4501 580b +4502 5819 +4503 581d +4504 5872 +4505 5821 +4506 5862 +4507 584b +4508 5870 +4509 6bc0 +4510 5852 +4511 583d +4512 5879 +4513 5885 +4514 58b9 +4515 589f +4516 58ab +4517 58ba +4518 58de +4519 58bb +4520 58b8 +4521 58ae +4522 58c5 +4523 58d3 +4524 58d1 +4525 58d7 +4526 58d9 +4527 58d8 +4528 58e5 +4529 58dc +4530 58e4 +4531 58df +4532 58ef +4533 58fa +4534 58f9 +4535..4537 58fb +4538 5902 +4539 590a +4540 5910 +4541 591b +4542 68a6 +4543 5925 +4544..4545 592c +4546 5932 +4547 5938 +4548 593e +4549 7ad2 +4550 5955 +4551 5950 +4552 594e +4553 595a +4554 5958 +4555 5962 +4556 5960 +4557 5967 +4558 596c +4559 5969 +4560 5978 +4561 5981 +4562 599d +4563 4f5e +4564 4fab +4565 59a3 +4566 59b2 +4567 59c6 +4568 59e8 +4569 59dc +4570 598d +4571..4572 59d9 +4573 5a25 +4574 5a1f +4575 5a11 +4576 5a1c +4577 5a09 +4578 5a1a +4579 5a40 +4580 5a6c +4581 5a49 +4582..4583 5a35 +4584 5a62 +4585 5a6a +4586 5a9a +4587 5abc +4588 5abe +4589 5acb +4590 5ac2 +4591 5abd +4592 5ae3 +4593 5ad7 +4594 5ae6 +4595 5ae9 +4596 5ad6 +4597..4598 5afa +4599 5b0c +4600 5b0b +4601 5b16 +4602 5b32 +4603 5ad0 +4604 5b2a +4605 5b36 +4606 5b3e +4607 5b43 +4608 5b45 +4609 5b40 +4610 5b51 +4611 5b55 +4612..4613 5b5a +4614 5b65 +4615 5b69 +4616 5b70 +4617 5b73 +4618 5b75 +4619 5b78 +4620 6588 +4621 5b7a +4622 5b80 +4623 5b83 +4624 5ba6 +4625 5bb8 +4626 5bc3 +4627 5bc7 +4628 5bc9 +4629 5bd4 +4630 5bd0 +4631 5be4 +4632 5be6 +4633 5be2 +4634 5bde +4635 5be5 +4636 5beb +4637 5bf0 +4638 5bf6 +4639 5bf3 +4640 5c05 +4641..4642 5c07 +4643 5c0d +4644 5c13 +4645 5c20 +4646 5c22 +4647 5c28 +4648..4649 5c38 +4650 5c41 +4651 5c46 +4652 5c4e +4653 5c53 +4654 5c50 +4655 5c4f +4656 5b71 +4657 5c6c +4658 5c6e +4659 4e62 +4660 5c76 +4661 5c79 +4662 5c8c +4663 5c91 +4664 5c94 +4665 599b +4666 5cab +4667 5cbb +4668 5cb6 +4669 5cbc +4670 5cb7 +4671 5cc5 +4672 5cbe +4673 5cc7 +4674 5cd9 +4675 5ce9 +4676 5cfd +4677 5cfa +4678 5ced +4679 5d8c +4680 5cea +4681 5d0b +4682 5d15 +4683 5d17 +4684 5d5c +4685 5d1f +4686 5d1b +4687 5d11 +4688 5d14 +4689 5d22 +4690 5d1a +4691 5d19 +4692 5d18 +4693 5d4c +4694 5d52 +4695 5d4e +4696 5d4b +4697 5d6c +4698 5d73 +4699 5d76 +4700 5d87 +4701 5d84 +4702 5d82 +4703 5da2 +4704 5d9d +4705 5dac +4706 5dae +4707 5dbd +4708 5d90 +4709 5db7 +4710 5dbc +4711 5dc9 +4712 5dcd +4713 5dd3 +4714 5dd2 +4715 5dd6 +4716 5ddb +4717 5deb +4718 5df2 +4719 5df5 +4720 5e0b +4721 5e1a +4722 5e19 +4723 5e11 +4724 5e1b +4725..4726 5e36 +4727 5e44 +4728 5e43 +4729 5e40 +4730 5e4e +4731 5e57 +4732 5e54 +4733 5e5f +4734 5e62 +4735 5e64 +4736 5e47 +4737..4738 5e75 +4739 5e7a +4740 9ebc +4741 5e7f +4742 5ea0 +4743..4744 5ec1 +4745 5ec8 +4746 5ed0 +4747 5ecf +4748 5ed6 +4749 5ee3 +4750 5edd +4751..4752 5eda +4753 5ee2 +4754 5ee1 +4755..4756 5ee8 +4757 5eec +4758 5ef1 +4759 5ef3 +4760 5ef0 +4761 5ef4 +4762 5ef8 +4763 5efe +4764 5f03 +4765 5f09 +4766 5f5d +4767 5f5c +4768 5f0b +4769 5f11 +4770 5f16 +4771 5f29 +4772 5f2d +4773 5f38 +4774 5f41 +4775 5f48 +4776 5f4c +4777 5f4e +4778 5f2f +4779 5f51 +4780..4781 5f56 +4782 5f59 +4783 5f61 +4784 5f6d +4785 5f73 +4786 5f77 +4787 5f83 +4788 5f82 +4789 5f7f +4790 5f8a +4791 5f88 +4792 5f91 +4793 5f87 +4794 5f9e +4795 5f99 +4796 5f98 +4797 5fa0 +4798 5fa8 +4799 5fad +4800 5fbc +4801 5fd6 +4802 5ffb +4803 5fe4 +4804 5ff8 +4805 5ff1 +4806 5fdd +4807 60b3 +4808 5fff +4809 6021 +4810 6060 +4811 6019 +4812 6010 +4813 6029 +4814 600e +4815 6031 +4816 601b +4817 6015 +4818 602b +4819 6026 +4820 600f +4821 603a +4822 605a +4823 6041 +4824 606a +4825 6077 +4826 605f +4827 604a +4828 6046 +4829 604d +4830 6063 +4831 6043 +4832 6064 +4833 6042 +4834 606c +4835 606b +4836 6059 +4837 6081 +4838 608d +4839 60e7 +4840 6083 +4841 609a +4842 6084 +4843 609b +4844..4845 6096 +4846 6092 +4847 60a7 +4848 608b +4849 60e1 +4850 60b8 +4851 60e0 +4852 60d3 +4853 60b4 +4854 5ff0 +4855 60bd +4856 60c6 +4857 60b5 +4858 60d8 +4859 614d +4860 6115 +4861 6106 +4862..4863 60f6 +4864 6100 +4865 60f4 +4866 60fa +4867 6103 +4868 6121 +4869 60fb +4870 60f1 +4871..4872 610d +4873 6147 +4874 613e +4875 6128 +4876 6127 +4877 614a +4878 613f +4879 613c +4880 612c +4881 6134 +4882 613d +4883 6142 +4884 6144 +4885 6173 +4886 6177 +4887..4889 6158 +4890 616b +4891 6174 +4892 616f +4893 6165 +4894 6171 +4895 615f +4896 615d +4897 6153 +4898 6175 +4899 6199 +4900 6196 +4901 6187 +4902 61ac +4903 6194 +4904 619a +4905 618a +4906 6191 +4907 61ab +4908 61ae +4909 61cc +4910 61ca +4911 61c9 +4912 61f7 +4913 61c8 +4914 61c3 +4915 61c6 +4916 61ba +4917 61cb +4918 7f79 +4919 61cd +4920 61e6 +4921 61e3 +4922 61f6 +4923 61fa +4924 61f4 +4925 61ff +4926 61fd +4927 61fc +4928 61fe +4929 6200 +4930..4931 6208 +4932 620d +4933 620c +4934 6214 +4935 621b +4936 621e +4937 6221 +4938 622a +4939 622e +4940 6230 +4941..4942 6232 +4943 6241 +4944 624e +4945 625e +4946 6263 +4947 625b +4948 6260 +4949 6268 +4950 627c +4951 6282 +4952 6289 +4953 627e +4954..4955 6292 +4956 6296 +4957 62d4 +4958 6283 +4959 6294 +4960 62d7 +4961 62d1 +4962 62bb +4963 62cf +4964 62ff +4965 62c6 +4966 64d4 +4967 62c8 +4968 62dc +4969 62cc +4970 62ca +4971 62c2 +4972 62c7 +4973 629b +4974 62c9 +4975 630c +4976 62ee +4977 62f1 +4978 6327 +4979 6302 +4980 6308 +4981 62ef +4982 62f5 +4983 6350 +4984 633e +4985 634d +4986 641c +4987 634f +4988 6396 +4989 638e +4990 6380 +4991 63ab +4992 6376 +4993 63a3 +4994 638f +4995 6389 +4996 639f +4997 63b5 +4998 636b +4999 6369 +5000 63be +5001 63e9 +5002 63c0 +5003 63c6 +5004 63e3 +5005 63c9 +5006 63d2 +5007 63f6 +5008 63c4 +5009 6416 +5010 6434 +5011 6406 +5012 6413 +5013 6426 +5014 6436 +5015 651d +5016 6417 +5017 6428 +5018 640f +5019 6467 +5020 646f +5021 6476 +5022 644e +5023 652a +5024 6495 +5025 6493 +5026 64a5 +5027 64a9 +5028 6488 +5029 64bc +5030 64da +5031 64d2 +5032 64c5 +5033 64c7 +5034 64bb +5035 64d8 +5036 64c2 +5037 64f1 +5038 64e7 +5039 8209 +5040..5041 64e0 +5042 62ac +5043 64e3 +5044 64ef +5045 652c +5046 64f6 +5047 64f4 +5048 64f2 +5049 64fa +5050 6500 +5051 64fd +5052 6518 +5053 651c +5054 6505 +5055 6524 +5056 6523 +5057 652b +5058..5059 6534 +5060 6537 +5061 6536 +5062 6538 +5063 754b +5064 6548 +5065 6556 +5066 6555 +5067 654d +5068 6558 +5069 655e +5070 655d +5071 6572 +5072 6578 +5073..5074 6582 +5075 8b8a +5076 659b +5077 659f +5078 65ab +5079 65b7 +5080 65c3 +5081 65c6 +5082 65c1 +5083 65c4 +5084 65cc +5085 65d2 +5086 65db +5087 65d9 +5088..5089 65e0 +5090 65f1 +5091 6772 +5092 660a +5093 6603 +5094 65fb +5095 6773 +5096..5097 6635 +5098 6634 +5099 661c +5100 664f +5101 6644 +5102 6649 +5103 6641 +5104 665e +5105 665d +5106 6664 +5107..5108 6667 +5109 665f +5110 6662 +5111 6670 +5112 6683 +5113 6688 +5114 668e +5115 6689 +5116 6684 +5117 6698 +5118 669d +5119 66c1 +5120 66b9 +5121 66c9 +5122 66be +5123 66bc +5124 66c4 +5125 66b8 +5126 66d6 +5127 66da +5128 66e0 +5129 663f +5130 66e6 +5131 66e9 +5132 66f0 +5133 66f5 +5134 66f7 +5135 670f +5136 6716 +5137 671e +5138..5139 6726 +5140 9738 +5141 672e +5142 673f +5143 6736 +5144 6741 +5145 6738 +5146 6737 +5147 6746 +5148 675e +5149 6760 +5150 6759 +5151..5152 6763 +5153 6789 +5154 6770 +5155 67a9 +5156 677c +5157 676a +5158 678c +5159 678b +5160 67a6 +5161 67a1 +5162 6785 +5163 67b7 +5164 67ef +5165 67b4 +5166 67ec +5167 67b3 +5168 67e9 +5169 67b8 +5170 67e4 +5171 67de +5172 67dd +5173 67e2 +5174 67ee +5175 67b9 +5176 67ce +5177 67c6 +5178 67e7 +5179 6a9c +5180 681e +5181 6846 +5182 6829 +5183 6840 +5184 684d +5185 6832 +5186 684e +5187 68b3 +5188 682b +5189 6859 +5190 6863 +5191 6877 +5192 687f +5193 689f +5194 688f +5195 68ad +5196 6894 +5197 689d +5198 689b +5199 6883 +5200 6aae +5201 68b9 +5202 6874 +5203 68b5 +5204 68a0 +5205 68ba +5206 690f +5207 688d +5208 687e +5209 6901 +5210 68ca +5211 6908 +5212 68d8 +5213 6922 +5214 6926 +5215 68e1 +5216 690c +5217 68cd +5218 68d4 +5219 68e7 +5220 68d5 +5221 6936 +5222 6912 +5223 6904 +5224 68d7 +5225 68e3 +5226 6925 +5227 68f9 +5228 68e0 +5229 68ef +5230 6928 +5231 692a +5232 691a +5233 6923 +5234 6921 +5235 68c6 +5236 6979 +5237 6977 +5238 695c +5239 6978 +5240 696b +5241 6954 +5242 697e +5243 696e +5244 6939 +5245 6974 +5246 693d +5247 6959 +5248 6930 +5249 6961 +5250 695e +5251 695d +5252 6981 +5253 696a +5254 69b2 +5255 69ae +5256 69d0 +5257 69bf +5258 69c1 +5259 69d3 +5260 69be +5261 69ce +5262 5be8 +5263 69ca +5264 69dd +5265 69bb +5266 69c3 +5267 69a7 +5268 6a2e +5269 6991 +5270 69a0 +5271 699c +5272 6995 +5273 69b4 +5274 69de +5275 69e8 +5276 6a02 +5277 6a1b +5278 69ff +5279 6b0a +5280 69f9 +5281 69f2 +5282 69e7 +5283 6a05 +5284 69b1 +5285 6a1e +5286 69ed +5287 6a14 +5288 69eb +5289 6a0a +5290 6a12 +5291 6ac1 +5292 6a23 +5293 6a13 +5294 6a44 +5295 6a0c +5296 6a72 +5297 6a36 +5298 6a78 +5299 6a47 +5300 6a62 +5301 6a59 +5302 6a66 +5303 6a48 +5304 6a38 +5305 6a22 +5306 6a90 +5307 6a8d +5308 6aa0 +5309 6a84 +5310..5311 6aa2 +5312 6a97 +5313 8617 +5314 6abb +5315 6ac3 +5316 6ac2 +5317 6ab8 +5318 6ab3 +5319 6aac +5320 6ade +5321 6ad1 +5322 6adf +5323 6aaa +5324 6ada +5325 6aea +5326 6afb +5327 6b05 +5328 8616 +5329 6afa +5330 6b12 +5331 6b16 +5332 9b31 +5333 6b1f +5334 6b38 +5335 6b37 +5336 76dc +5337 6b39 +5338 98ee +5339 6b47 +5340 6b43 +5341 6b49 +5342 6b50 +5343 6b59 +5344 6b54 +5345 6b5b +5346 6b5f +5347 6b61 +5348..5349 6b78 +5350..5351 6b7f +5352 6b84 +5353 6b83 +5354 6b8d +5355 6b98 +5356 6b95 +5357 6b9e +5358 6ba4 +5359..5360 6baa +5361 6baf +5362 6bb2 +5363 6bb1 +5364 6bb3 +5365 6bb7 +5366 6bbc +5367 6bc6 +5368 6bcb +5369 6bd3 +5370 6bdf +5371 6bec +5372 6beb +5373 6bf3 +5374 6bef +5375 9ebe +5376 6c08 +5377..5378 6c13 +5379 6c1b +5380 6c24 +5381 6c23 +5382 6c5e +5383 6c55 +5384 6c62 +5385 6c6a +5386 6c82 +5387 6c8d +5388 6c9a +5389 6c81 +5390 6c9b +5391 6c7e +5392 6c68 +5393 6c73 +5394 6c92 +5395 6c90 +5396 6cc4 +5397 6cf1 +5398 6cd3 +5399 6cbd +5400 6cd7 +5401 6cc5 +5402 6cdd +5403 6cae +5404 6cb1 +5405 6cbe +5406 6cba +5407 6cdb +5408 6cef +5409 6cd9 +5410 6cea +5411 6d1f +5412 884d +5413 6d36 +5414 6d2b +5415 6d3d +5416 6d38 +5417 6d19 +5418 6d35 +5419 6d33 +5420 6d12 +5421 6d0c +5422 6d63 +5423 6d93 +5424 6d64 +5425 6d5a +5426 6d79 +5427 6d59 +5428 6d8e +5429 6d95 +5430 6fe4 +5431 6d85 +5432 6df9 +5433 6e15 +5434 6e0a +5435 6db5 +5436 6dc7 +5437 6de6 +5438 6db8 +5439 6dc6 +5440 6dec +5441 6dde +5442 6dcc +5443 6de8 +5444 6dd2 +5445 6dc5 +5446 6dfa +5447 6dd9 +5448 6de4 +5449 6dd5 +5450 6dea +5451 6dee +5452 6e2d +5453 6e6e +5454 6e2e +5455 6e19 +5456 6e72 +5457 6e5f +5458 6e3e +5459 6e23 +5460 6e6b +5461 6e2b +5462 6e76 +5463 6e4d +5464 6e1f +5465 6e43 +5466 6e3a +5467 6e4e +5468 6e24 +5469 6eff +5470 6e1d +5471 6e38 +5472 6e82 +5473 6eaa +5474 6e98 +5475 6ec9 +5476 6eb7 +5477 6ed3 +5478 6ebd +5479 6eaf +5480 6ec4 +5481 6eb2 +5482..5483 6ed4 +5484 6e8f +5485 6ea5 +5486 6ec2 +5487 6e9f +5488 6f41 +5489 6f11 +5490 704c +5491 6eec +5492 6ef8 +5493 6efe +5494 6f3f +5495 6ef2 +5496 6f31 +5497 6eef +5498 6f32 +5499 6ecc +5500 6f3e +5501 6f13 +5502 6ef7 +5503 6f86 +5504 6f7a +5505 6f78 +5506 6f81 +5507 6f80 +5508 6f6f +5509 6f5b +5510 6ff3 +5511 6f6d +5512 6f82 +5513 6f7c +5514 6f58 +5515 6f8e +5516 6f91 +5517 6fc2 +5518 6f66 +5519 6fb3 +5520 6fa3 +5521 6fa1 +5522 6fa4 +5523 6fb9 +5524 6fc6 +5525 6faa +5526 6fdf +5527 6fd5 +5528 6fec +5529 6fd4 +5530 6fd8 +5531 6ff1 +5532 6fee +5533 6fdb +5534 7009 +5535 700b +5536 6ffa +5537 7011 +5538 7001 +5539 700f +5540 6ffe +5541 701b +5542 701a +5543 6f74 +5544 701d +5545 7018 +5546 701f +5547 7030 +5548 703e +5549 7032 +5550 7051 +5551 7063 +5552 7099 +5553 7092 +5554 70af +5555 70f1 +5556 70ac +5557 70b8 +5558 70b3 +5559 70ae +5560 70df +5561 70cb +5562 70dd +5563 70d9 +5564 7109 +5565 70fd +5566 711c +5567 7119 +5568 7165 +5569 7155 +5570 7188 +5571 7166 +5572 7162 +5573 714c +5574 7156 +5575 716c +5576 718f +5577 71fb +5578 7184 +5579 7195 +5580 71a8 +5581 71ac +5582 71d7 +5583 71b9 +5584 71be +5585 71d2 +5586 71c9 +5587 71d4 +5588 71ce +5589 71e0 +5590 71ec +5591 71e7 +5592 71f5 +5593 71fc +5594 71f9 +5595 71ff +5596 720d +5597 7210 +5598 721b +5599 7228 +5600 722d +5601 722c +5602 7230 +5603 7232 +5604..5605 723b +5606..5607 723f +5608 7246 +5609 724b +5610 7258 +5611 7274 +5612 727e +5613 7282 +5614 7281 +5615 7287 +5616 7292 +5617 7296 +5618 72a2 +5619 72a7 +5620 72b9 +5621 72b2 +5622 72c3 +5623 72c6 +5624 72c4 +5625 72ce +5626 72d2 +5627 72e2 +5628..5629 72e0 +5630 72f9 +5631 72f7 +5632 500f +5633 7317 +5634 730a +5635 731c +5636 7316 +5637 731d +5638 7334 +5639 732f +5640 7329 +5641 7325 +5642 733e +5643..5644 734e +5645 9ed8 +5646 7357 +5647 736a +5648 7368 +5649 7370 +5650 7378 +5651 7375 +5652 737b +5653 737a +5654 73c8 +5655 73b3 +5656 73ce +5657 73bb +5658 73c0 +5659 73e5 +5660 73ee +5661 73de +5662 74a2 +5663 7405 +5664 746f +5665 7425 +5666 73f8 +5667 7432 +5668 743a +5669 7455 +5670 743f +5671 745f +5672 7459 +5673 7441 +5674 745c +5675 7469 +5676 7470 +5677 7463 +5678 746a +5679 7476 +5680 747e +5681 748b +5682 749e +5683 74a7 +5684 74ca +5685 74cf +5686 74d4 +5687 73f1 +5688 74e0 +5689 74e3 +5690 74e7 +5691 74e9 +5692 74ee +5693 74f2 +5694..5695 74f0 +5696 74f8 +5697 74f7 +5698 7504 +5699 7503 +5700 7505 +5701 750c +5702 750e +5703 750d +5704 7515 +5705 7513 +5706 751e +5707 7526 +5708 752c +5709 753c +5710 7544 +5711 754d +5712 754a +5713 7549 +5714 755b +5715 7546 +5716 755a +5717 7569 +5718 7564 +5719 7567 +5720 756b +5721 756d +5722 7578 +5723 7576 +5724..5725 7586 +5726 7574 +5727 758a +5728 7589 +5729 7582 +5730 7594 +5731 759a +5732 759d +5733 75a5 +5734 75a3 +5735 75c2 +5736 75b3 +5737 75c3 +5738 75b5 +5739 75bd +5740 75b8 +5741 75bc +5742 75b1 +5743 75cd +5744 75ca +5745 75d2 +5746 75d9 +5747 75e3 +5748 75de +5749..5750 75fe +5751 75fc +5752 7601 +5753 75f0 +5754 75fa +5755..5756 75f2 +5757 760b +5758 760d +5759 7609 +5760 761f +5761 7627 +5762..5764 7620 +5765 7624 +5766 7634 +5767 7630 +5768 763b +5769..5770 7647 +5771 7646 +5772 765c +5773 7658 +5774..5775 7661 +5776..5778 7668 +5779 7667 +5780 766c +5781 7670 +5782 7672 +5783 7676 +5784 7678 +5785 767c +5786 7680 +5787 7683 +5788 7688 +5789 768b +5790 768e +5791 7696 +5792 7693 +5793..5794 7699 +5795 76b0 +5796 76b4 +5797..5799 76b8 +5800 76c2 +5801 76cd +5802 76d6 +5803 76d2 +5804 76de +5805 76e1 +5806 76e5 +5807 76e7 +5808 76ea +5809 862f +5810 76fb +5811 7708 +5812 7707 +5813 7704 +5814 7729 +5815 7724 +5816 771e +5817..5818 7725 +5819 771b +5820..5821 7737 +5822 7747 +5823 775a +5824 7768 +5825 776b +5826 775b +5827 7765 +5828 777f +5829 777e +5830 7779 +5831 778e +5832 778b +5833 7791 +5834 77a0 +5835 779e +5836 77b0 +5837 77b6 +5838 77b9 +5839 77bf +5840..5841 77bc +5842 77bb +5843 77c7 +5844 77cd +5845 77d7 +5846 77da +5847 77dc +5848 77e3 +5849 77ee +5850 77fc +5851 780c +5852 7812 +5853 7926 +5854 7820 +5855 792a +5856 7845 +5857 788e +5858 7874 +5859 7886 +5860 787c +5861 789a +5862 788c +5863 78a3 +5864 78b5 +5865 78aa +5866 78af +5867 78d1 +5868 78c6 +5869 78cb +5870 78d4 +5871 78be +5872 78bc +5873 78c5 +5874 78ca +5875 78ec +5876 78e7 +5877 78da +5878 78fd +5879 78f4 +5880 7907 +5881 7912 +5882 7911 +5883 7919 +5884 792c +5885 792b +5886 7940 +5887 7960 +5888 7957 +5889 795f +5890 795a +5891 7955 +5892 7953 +5893 797a +5894 797f +5895 798a +5896 799d +5897 79a7 +5898 9f4b +5899 79aa +5900 79ae +5901 79b3 +5902..5903 79b9 +5904 79c9 +5905 79d5 +5906 79e7 +5907 79ec +5908 79e1 +5909 79e3 +5910 7a08 +5911 7a0d +5912..5913 7a18 +5914 7a20 +5915 7a1f +5916 7980 +5917 7a31 +5918 7a3b +5919 7a3e +5920 7a37 +5921 7a43 +5922 7a57 +5923 7a49 +5924..5925 7a61 +5926 7a69 +5927 9f9d +5928 7a70 +5929 7a79 +5930 7a7d +5931 7a88 +5932 7a97 +5933 7a95 +5934 7a98 +5935 7a96 +5936 7aa9 +5937 7ac8 +5938 7ab0 +5939 7ab6 +5940 7ac5 +5941 7ac4 +5942 7abf +5943 9083 +5944 7ac7 +5945 7aca +5946 7acd +5947 7acf +5948 7ad5 +5949 7ad3 +5950..5951 7ad9 +5952 7add +5953..5954 7ae1 +5955 7ae6 +5956 7aed +5957 7af0 +5958 7b02 +5959 7b0f +5960 7b0a +5961 7b06 +5962 7b33 +5963..5964 7b18 +5965 7b1e +5966 7b35 +5967 7b28 +5968 7b36 +5969 7b50 +5970 7b7a +5971 7b04 +5972 7b4d +5973 7b0b +5974 7b4c +5975 7b45 +5976 7b75 +5977 7b65 +5978 7b74 +5979 7b67 +5980..5981 7b70 +5982 7b6c +5983 7b6e +5984 7b9d +5985 7b98 +5986 7b9f +5987 7b8d +5988 7b9c +5989 7b9a +5990 7b8b +5991 7b92 +5992 7b8f +5993 7b5d +5994 7b99 +5995 7bcb +5996 7bc1 +5997 7bcc +5998 7bcf +5999 7bb4 +6000 7bc6 +6001 7bdd +6002 7be9 +6003 7c11 +6004 7c14 +6005 7be6 +6006 7be5 +6007 7c60 +6008 7c00 +6009 7c07 +6010 7c13 +6011 7bf3 +6012 7bf7 +6013 7c17 +6014 7c0d +6015 7bf6 +6016 7c23 +6017 7c27 +6018 7c2a +6019 7c1f +6020 7c37 +6021 7c2b +6022 7c3d +6023 7c4c +6024 7c43 +6025 7c54 +6026 7c4f +6027 7c40 +6028 7c50 +6029 7c58 +6030 7c5f +6031 7c64 +6032 7c56 +6033 7c65 +6034 7c6c +6035 7c75 +6036 7c83 +6037 7c90 +6038 7ca4 +6039 7cad +6040 7ca2 +6041 7cab +6042 7ca1 +6043 7ca8 +6044 7cb3 +6045 7cb2 +6046 7cb1 +6047 7cae +6048 7cb9 +6049 7cbd +6050 7cc0 +6051 7cc5 +6052 7cc2 +6053 7cd8 +6054 7cd2 +6055 7cdc +6056 7ce2 +6057 9b3b +6058 7cef +6059 7cf2 +6060 7cf4 +6061 7cf6 +6062 7cfa +6063 7d06 +6064 7d02 +6065 7d1c +6066 7d15 +6067 7d0a +6068 7d45 +6069 7d4b +6070 7d2e +6071 7d32 +6072 7d3f +6073 7d35 +6074 7d46 +6075 7d73 +6076 7d56 +6077 7d4e +6078 7d72 +6079 7d68 +6080 7d6e +6081 7d4f +6082 7d63 +6083 7d93 +6084 7d89 +6085 7d5b +6086 7d8f +6087 7d7d +6088 7d9b +6089 7dba +6090 7dae +6091 7da3 +6092 7db5 +6093 7dc7 +6094 7dbd +6095 7dab +6096 7e3d +6097 7da2 +6098 7daf +6099 7ddc +6100 7db8 +6101 7d9f +6102 7db0 +6103 7dd8 +6104 7ddd +6105 7de4 +6106 7dde +6107 7dfb +6108 7df2 +6109 7de1 +6110 7e05 +6111 7e0a +6112 7e23 +6113 7e21 +6114 7e12 +6115 7e31 +6116 7e1f +6117 7e09 +6118 7e0b +6119 7e22 +6120 7e46 +6121 7e66 +6122 7e3b +6123 7e35 +6124 7e39 +6125 7e43 +6126 7e37 +6127 7e32 +6128 7e3a +6129 7e67 +6130 7e5d +6131 7e56 +6132 7e5e +6133..6134 7e59 +6135 7e79 +6136 7e6a +6137 7e69 +6138 7e7c +6139 7e7b +6140 7e83 +6141 7dd5 +6142 7e7d +6143 8fae +6144 7e7f +6145..6146 7e88 +6147 7e8c +6148 7e92 +6149 7e90 +6150..6151 7e93 +6152 7e96 +6153 7e8e +6154..6155 7e9b +6156 7f38 +6157 7f3a +6158 7f45 +6159..6161 7f4c +6162..6163 7f50 +6164 7f55 +6165 7f54 +6166 7f58 +6167..6168 7f5f +6169..6170 7f68 +6171 7f67 +6172 7f78 +6173 7f82 +6174 7f86 +6175 7f83 +6176 7f88 +6177 7f87 +6178 7f8c +6179 7f94 +6180 7f9e +6181 7f9d +6182 7f9a +6183 7fa3 +6184 7faf +6185 7fb2 +6186 7fb9 +6187 7fae +6188 7fb6 +6189 7fb8 +6190 8b71 +6191..6192 7fc5 +6193 7fca +6194 7fd5 +6195 7fd4 +6196 7fe1 +6197 7fe6 +6198 7fe9 +6199 7ff3 +6200 7ff9 +6201 98dc +6202 8006 +6203 8004 +6204 800b +6205 8012 +6206..6207 8018 +6208 801c +6209 8021 +6210 8028 +6211 803f +6212 803b +6213 804a +6214 8046 +6215 8052 +6216 8058 +6217 805a +6218 805f +6219 8062 +6220 8068 +6221 8073 +6222 8072 +6223 8070 +6224 8076 +6225 8079 +6226 807d +6227 807f +6228 8084 +6229 8086 +6230 8085 +6231 809b +6232 8093 +6233 809a +6234 80ad +6235 5190 +6236 80ac +6237 80db +6238 80e5 +6239 80d9 +6240 80dd +6241 80c4 +6242 80da +6243 80d6 +6244 8109 +6245 80ef +6246 80f1 +6247 811b +6248 8129 +6249 8123 +6250 812f +6251 814b +6252 968b +6253 8146 +6254 813e +6255 8153 +6256 8151 +6257 80fc +6258 8171 +6259 816e +6260..6261 8165 +6262 8174 +6263 8183 +6264 8188 +6265 818a +6266 8180 +6267 8182 +6268 81a0 +6269 8195 +6270 81a4 +6271 81a3 +6272 815f +6273 8193 +6274 81a9 +6275 81b0 +6276 81b5 +6277 81be +6278 81b8 +6279 81bd +6280 81c0 +6281 81c2 +6282 81ba +6283 81c9 +6284 81cd +6285 81d1 +6286 81d9 +6287 81d8 +6288 81c8 +6289 81da +6290..6291 81df +6292 81e7 +6293..6294 81fa +6295 81fe +6296..6297 8201 +6298 8205 +6299 8207 +6300 820a +6301 820d +6302 8210 +6303 8216 +6304 8229 +6305 822b +6306 8238 +6307 8233 +6308 8240 +6309 8259 +6310 8258 +6311 825d +6312 825a +6313 825f +6314 8264 +6315 8262 +6316 8268 +6317..6318 826a +6319 822e +6320 8271 +6321..6322 8277 +6323 827e +6324 828d +6325 8292 +6326 82ab +6327 829f +6328 82bb +6329 82ac +6330 82e1 +6331 82e3 +6332 82df +6333 82d2 +6334 82f4 +6335 82f3 +6336 82fa +6337 8393 +6338 8303 +6339 82fb +6340 82f9 +6341 82de +6342 8306 +6343 82dc +6344 8309 +6345 82d9 +6346 8335 +6347 8334 +6348 8316 +6349 8332 +6350 8331 +6351 8340 +6352 8339 +6353 8350 +6354 8345 +6355 832f +6356 832b +6357..6358 8317 +6359 8385 +6360 839a +6361 83aa +6362 839f +6363 83a2 +6364 8396 +6365 8323 +6366 838e +6367 8387 +6368 838a +6369 837c +6370 83b5 +6371 8373 +6372 8375 +6373 83a0 +6374 8389 +6375 83a8 +6376 83f4 +6377 8413 +6378 83eb +6379 83ce +6380 83fd +6381 8403 +6382 83d8 +6383 840b +6384 83c1 +6385 83f7 +6386 8407 +6387 83e0 +6388 83f2 +6389 840d +6390 8422 +6391 8420 +6392 83bd +6393 8438 +6394 8506 +6395 83fb +6396 846d +6397 842a +6398 843c +6399 855a +6400 8484 +6401 8477 +6402 846b +6403 84ad +6404 846e +6405 8482 +6406 8469 +6407 8446 +6408 842c +6409 846f +6410 8479 +6411 8435 +6412 84ca +6413 8462 +6414 84b9 +6415 84bf +6416 849f +6417 84d9 +6418 84cd +6419 84bb +6420 84da +6421 84d0 +6422 84c1 +6423 84c6 +6424 84d6 +6425 84a1 +6426 8521 +6427 84ff +6428 84f4 +6429..6430 8517 +6431 852c +6432 851f +6433 8515 +6434 8514 +6435 84fc +6436 8540 +6437 8563 +6438 8558 +6439 8548 +6440 8541 +6441 8602 +6442 854b +6443 8555 +6444 8580 +6445 85a4 +6446 8588 +6447 8591 +6448 858a +6449 85a8 +6450 856d +6451 8594 +6452 859b +6453 85ea +6454 8587 +6455 859c +6456 8577 +6457 857e +6458 8590 +6459 85c9 +6460 85ba +6461 85cf +6462 85b9 +6463 85d0 +6464 85d5 +6465 85dd +6466 85e5 +6467 85dc +6468 85f9 +6469 860a +6470 8613 +6471 860b +6472 85fe +6473 85fa +6474 8606 +6475 8622 +6476 861a +6477 8630 +6478 863f +6479 864d +6480 4e55 +6481 8654 +6482 865f +6483 8667 +6484 8671 +6485 8693 +6486 86a3 +6487..6488 86a9 +6489..6490 868b +6491 86b6 +6492 86af +6493 86c4 +6494 86c6 +6495 86b0 +6496 86c9 +6497 8823 +6498 86ab +6499 86d4 +6500 86de +6501 86e9 +6502 86ec +6503 86df +6504 86db +6505 86ef +6506 8712 +6507 8706 +6508 8708 +6509 8700 +6510 8703 +6511 86fb +6512 8711 +6513 8709 +6514 870d +6515 86f9 +6516 870a +6517 8734 +6518 873f +6519 8737 +6520 873b +6521 8725 +6522 8729 +6523 871a +6524 8760 +6525 875f +6526 8778 +6527 874c +6528 874e +6529 8774 +6530 8757 +6531 8768 +6532 876e +6533 8759 +6534 8753 +6535 8763 +6536 876a +6537 8805 +6538 87a2 +6539 879f +6540 8782 +6541 87af +6542 87cb +6543 87bd +6544 87c0 +6545 87d0 +6546 96d6 +6547 87ab +6548 87c4 +6549 87b3 +6550 87c7 +6551 87c6 +6552 87bb +6553 87ef +6554 87f2 +6555 87e0 +6556 880f +6557 880d +6558 87fe +6559..6560 87f6 +6561 880e +6562 87d2 +6563 8811 +6564 8816 +6565 8815 +6566 8822 +6567 8821 +6568 8831 +6569 8836 +6570 8839 +6571 8827 +6572 883b +6573 8844 +6574 8842 +6575 8852 +6576 8859 +6577 885e +6578 8862 +6579 886b +6580 8881 +6581 887e +6582 889e +6583 8875 +6584 887d +6585 88b5 +6586 8872 +6587 8882 +6588 8897 +6589 8892 +6590 88ae +6591 8899 +6592 88a2 +6593 888d +6594 88a4 +6595 88b0 +6596 88bf +6597 88b1 +6598..6599 88c3 +6600 88d4 +6601..6602 88d8 +6603 88dd +6604 88f9 +6605 8902 +6606 88fc +6607 88f4 +6608 88e8 +6609 88f2 +6610 8904 +6611 890c +6612 890a +6613 8913 +6614 8943 +6615 891e +6616 8925 +6617..6618 892a +6619 8941 +6620 8944 +6621 893b +6622 8936 +6623 8938 +6624 894c +6625 891d +6626 8960 +6627 895e +6628 8966 +6629 8964 +6630 896d +6631 896a +6632 896f +6633 8974 +6634 8977 +6635 897e +6636 8983 +6637 8988 +6638 898a +6639 8993 +6640 8998 +6641 89a1 +6642 89a9 +6643 89a6 +6644 89ac +6645 89af +6646 89b2 +6647 89ba +6648 89bd +6649..6650 89bf +6651 89da +6652..6653 89dc +6654 89e7 +6655 89f4 +6656 89f8 +6657 8a03 +6658 8a16 +6659 8a10 +6660 8a0c +6661 8a1b +6662 8a1d +6663 8a25 +6664 8a36 +6665 8a41 +6666 8a5b +6667 8a52 +6668 8a46 +6669 8a48 +6670 8a7c +6671 8a6d +6672 8a6c +6673 8a62 +6674 8a85 +6675 8a82 +6676 8a84 +6677 8aa8 +6678 8aa1 +6679 8a91 +6680..6681 8aa5 +6682 8a9a +6683 8aa3 +6684 8ac4 +6685 8acd +6686 8ac2 +6687 8ada +6688 8aeb +6689 8af3 +6690 8ae7 +6691 8ae4 +6692 8af1 +6693 8b14 +6694 8ae0 +6695 8ae2 +6696 8af7 +6697 8ade +6698 8adb +6699 8b0c +6700 8b07 +6701 8b1a +6702 8ae1 +6703 8b16 +6704 8b10 +6705 8b17 +6706 8b20 +6707 8b33 +6708 97ab +6709 8b26 +6710 8b2b +6711 8b3e +6712 8b28 +6713 8b41 +6714 8b4c +6715 8b4f +6716 8b4e +6717 8b49 +6718 8b56 +6719 8b5b +6720 8b5a +6721 8b6b +6722 8b5f +6723 8b6c +6724 8b6f +6725 8b74 +6726 8b7d +6727 8b80 +6728 8b8c +6729 8b8e +6730..6731 8b92 +6732 8b96 +6733..6734 8b99 +6735 8c3a +6736 8c41 +6737 8c3f +6738 8c48 +6739 8c4c +6740 8c4e +6741 8c50 +6742 8c55 +6743 8c62 +6744 8c6c +6745 8c78 +6746 8c7a +6747 8c82 +6748 8c89 +6749 8c85 +6750 8c8a +6751..6752 8c8d +6753 8c94 +6754 8c7c +6755 8c98 +6756 621d +6757 8cad +6758 8caa +6759 8cbd +6760..6761 8cb2 +6762 8cae +6763 8cb6 +6764 8cc8 +6765 8cc1 +6766 8ce4 +6767 8ce3 +6768 8cda +6769 8cfd +6770..6771 8cfa +6772..6773 8d04 +6774 8d0a +6775 8d07 +6776 8d0f +6777 8d0d +6778 8d10 +6779 9f4e +6780 8d13 +6781 8ccd +6782 8d14 +6783 8d16 +6784 8d67 +6785 8d6d +6786 8d71 +6787 8d73 +6788 8d81 +6789 8d99 +6790 8dc2 +6791 8dbe +6792 8dba +6793 8dcf +6794 8dda +6795 8dd6 +6796 8dcc +6797 8ddb +6798 8dcb +6799..6800 8dea +6801 8ddf +6802 8de3 +6803 8dfc +6804..6805 8e08 +6806 8dff +6807..6808 8e1d +6809 8e10 +6810 8e1f +6811 8e42 +6812 8e35 +6813 8e30 +6814 8e34 +6815 8e4a +6816 8e47 +6817 8e49 +6818 8e4c +6819 8e50 +6820 8e48 +6821 8e59 +6822 8e64 +6823 8e60 +6824 8e2a +6825 8e63 +6826 8e55 +6827 8e76 +6828 8e72 +6829 8e7c +6830 8e81 +6831 8e87 +6832 8e85 +6833 8e84 +6834 8e8b +6835 8e8a +6836 8e93 +6837 8e91 +6838 8e94 +6839 8e99 +6840 8eaa +6841 8ea1 +6842 8eac +6843 8eb0 +6844 8ec6 +6845 8eb1 +6846 8ebe +6847 8ec5 +6848 8ec8 +6849 8ecb +6850 8edb +6851 8ee3 +6852 8efc +6853 8efb +6854 8eeb +6855 8efe +6856 8f0a +6857 8f05 +6858 8f15 +6859 8f12 +6860 8f19 +6861 8f13 +6862 8f1c +6863 8f1f +6864 8f1b +6865 8f0c +6866 8f26 +6867 8f33 +6868 8f3b +6869 8f39 +6870 8f45 +6871 8f42 +6872 8f3e +6873 8f4c +6874 8f49 +6875 8f46 +6876 8f4e +6877 8f57 +6878 8f5c +6879..6881 8f62 +6882 8f9c +6883 8f9f +6884 8fa3 +6885 8fad +6886 8faf +6887 8fb7 +6888 8fda +6889 8fe5 +6890 8fe2 +6891 8fea +6892 8fef +6893 9087 +6894 8ff4 +6895 9005 +6896..6897 8ff9 +6898 9011 +6899 9015 +6900 9021 +6901 900d +6902 901e +6903 9016 +6904 900b +6905 9027 +6906 9036 +6907 9035 +6908 9039 +6909 8ff8 +6910..6913 904f +6914 900e +6915 9049 +6916 903e +6917 9056 +6918 9058 +6919 905e +6920 9068 +6921 906f +6922 9076 +6923 96a8 +6924 9072 +6925 9082 +6926 907d +6927 9081 +6928 9080 +6929 908a +6930 9089 +6931 908f +6932 90a8 +6933 90af +6934 90b1 +6935 90b5 +6936 90e2 +6937 90e4 +6938 6248 +6939 90db +6940 9102 +6941 9112 +6942 9119 +6943 9132 +6944 9130 +6945 914a +6946 9156 +6947 9158 +6948 9163 +6949 9165 +6950 9169 +6951 9173 +6952 9172 +6953 918b +6954 9189 +6955 9182 +6956 91a2 +6957 91ab +6958 91af +6959 91aa +6960 91b5 +6961 91b4 +6962 91ba +6963..6964 91c0 +6965 91c9 +6966 91cb +6967 91d0 +6968 91d6 +6969 91df +6970 91e1 +6971 91db +6972 91fc +6973..6974 91f5 +6975 921e +6976 91ff +6977 9214 +6978 922c +6979 9215 +6980 9211 +6981 925e +6982 9257 +6983 9245 +6984 9249 +6985 9264 +6986 9248 +6987 9295 +6988 923f +6989 924b +6990 9250 +6991 929c +6992 9296 +6993 9293 +6994 929b +6995 925a +6996 92cf +6997 92b9 +6998 92b7 +6999 92e9 +7000 930f +7001 92fa +7002 9344 +7003 932e +7004 9319 +7005 9322 +7006 931a +7007 9323 +7008 933a +7009 9335 +7010 933b +7011 935c +7012 9360 +7013 937c +7014 936e +7015 9356 +7016 93b0 +7017..7018 93ac +7019 9394 +7020 93b9 +7021..7022 93d6 +7023 93e8 +7024 93e5 +7025 93d8 +7026 93c3 +7027 93dd +7028 93d0 +7029 93c8 +7030 93e4 +7031 941a +7032 9414 +7033 9413 +7034 9403 +7035 9407 +7036 9410 +7037 9436 +7038 942b +7039 9435 +7040 9421 +7041 943a +7042 9441 +7043 9452 +7044 9444 +7045 945b +7046 9460 +7047 9462 +7048 945e +7049 946a +7050 9229 +7051 9470 +7052 9475 +7053 9477 +7054 947d +7055 945a +7056 947c +7057 947e +7058 9481 +7059 947f +7060 9582 +7061 9587 +7062 958a +7063 9594 +7064 9596 +7065..7066 9598 +7067 95a0 +7068 95a8 +7069 95a7 +7070 95ad +7071 95bc +7072 95bb +7073 95b9 +7074 95be +7075 95ca +7076 6ff6 +7077 95c3 +7078 95cd +7079 95cc +7080 95d5 +7081 95d4 +7082 95d6 +7083 95dc +7084 95e1 +7085 95e5 +7086 95e2 +7087 9621 +7088 9628 +7089..7090 962e +7091 9642 +7092 964c +7093 964f +7094 964b +7095 9677 +7096 965c +7097 965e +7098 965d +7099 965f +7100 9666 +7101 9672 +7102 966c +7103 968d +7104 9698 +7105 9695 +7106 9697 +7107 96aa +7108 96a7 +7109..7110 96b1 +7111 96b0 +7112 96b4 +7113 96b6 +7114..7115 96b8 +7116 96ce +7117 96cb +7118 96c9 +7119 96cd +7120 894d +7121 96dc +7122 970d +7123 96d5 +7124 96f9 +7125 9704 +7126 9706 +7127 9708 +7128 9713 +7129 970e +7130 9711 +7131 970f +7132 9716 +7133 9719 +7134 9724 +7135 972a +7136 9730 +7137 9739 +7138..7139 973d +7140 9744 +7141 9746 +7142 9748 +7143 9742 +7144 9749 +7145 975c +7146 9760 +7147 9764 +7148 9766 +7149 9768 +7150 52d2 +7151 976b +7152 9771 +7153 9779 +7154 9785 +7155 977c +7156 9781 +7157 977a +7158 9786 +7159 978b +7160..7161 978f +7162 979c +7163 97a8 +7164 97a6 +7165 97a3 +7166..7167 97b3 +7168 97c3 +7169 97c6 +7170 97c8 +7171 97cb +7172 97dc +7173 97ed +7174 9f4f +7175 97f2 +7176 7adf +7177 97f6 +7178 97f5 +7179 980f +7180 980c +7181 9838 +7182 9824 +7183 9821 +7184 9837 +7185 983d +7186 9846 +7187 984f +7188 984b +7189 986b +7190..7192 986f +7193 9874 +7194 9873 +7195 98aa +7196 98af +7197 98b1 +7198 98b6 +7199 98c4 +7200 98c3 +7201 98c6 +7202 98e9 +7203 98eb +7204 9903 +7205 9909 +7206 9912 +7207 9914 +7208 9918 +7209 9921 +7210..7211 991d +7212 9924 +7213 9920 +7214 992c +7215 992e +7216..7217 993d +7218 9942 +7219 9949 +7220 9945 +7221 9950 +7222 994b +7223..7224 9951 +7225 994c +7226 9955 +7227..7228 9997 +7229 99a5 +7230..7231 99ad +7232 99bc +7233 99df +7234 99db +7235 99dd +7236 99d8 +7237 99d1 +7238..7239 99ed +7240..7241 99f1 +7242 99fb +7243 99f8 +7244 9a01 +7245 9a0f +7246 9a05 +7247 99e2 +7248 9a19 +7249 9a2b +7250 9a37 +7251 9a45 +7252 9a42 +7253 9a40 +7254 9a43 +7255 9a3e +7256 9a55 +7257 9a4d +7258 9a5b +7259 9a57 +7260 9a5f +7261 9a62 +7262 9a65 +7263 9a64 +7264 9a69 +7265 9a6b +7266 9a6a +7267 9aad +7268 9ab0 +7269 9abc +7270 9ac0 +7271 9acf +7272 9ad1 +7273..7274 9ad3 +7275..7276 9ade +7277..7278 9ae2 +7279 9ae6 +7280 9aef +7281 9aeb +7282 9aee +7283 9af4 +7284 9af1 +7285 9af7 +7286 9afb +7287 9b06 +7288 9b18 +7289 9b1a +7290 9b1f +7291..7292 9b22 +7293 9b25 +7294..7297 9b27 +7298..7299 9b2e +7300 9b32 +7301 9b44 +7302 9b43 +7303 9b4f +7304..7305 9b4d +7306 9b51 +7307 9b58 +7308 9b74 +7309 9b93 +7310 9b83 +7311 9b91 +7312..7313 9b96 +7314..7315 9b9f +7316 9ba8 +7317 9bb4 +7318 9bc0 +7319 9bca +7320 9bb9 +7321 9bc6 +7322 9bcf +7323..7324 9bd1 +7325 9be3 +7326 9be2 +7327 9be4 +7328 9bd4 +7329 9be1 +7330 9c3a +7331 9bf2 +7332 9bf1 +7333 9bf0 +7334 9c15 +7335 9c14 +7336 9c09 +7337 9c13 +7338 9c0c +7339 9c06 +7340 9c08 +7341 9c12 +7342 9c0a +7343 9c04 +7344 9c2e +7345 9c1b +7346 9c25 +7347 9c24 +7348 9c21 +7349 9c30 +7350 9c47 +7351 9c32 +7352 9c46 +7353 9c3e +7354 9c5a +7355 9c60 +7356 9c67 +7357 9c76 +7358 9c78 +7359 9ce7 +7360 9cec +7361 9cf0 +7362 9d09 +7363 9d08 +7364 9ceb +7365 9d03 +7366 9d06 +7367 9d2a +7368 9d26 +7369 9daf +7370 9d23 +7371 9d1f +7372 9d44 +7373 9d15 +7374 9d12 +7375 9d41 +7376 9d3f +7377 9d3e +7378 9d46 +7379 9d48 +7380..7381 9d5d +7382 9d64 +7383 9d51 +7384 9d50 +7385 9d59 +7386 9d72 +7387 9d89 +7388 9d87 +7389 9dab +7390 9d6f +7391 9d7a +7392 9d9a +7393 9da4 +7394 9da9 +7395 9db2 +7396 9dc4 +7397 9dc1 +7398 9dbb +7399 9db8 +7400 9dba +7401 9dc6 +7402 9dcf +7403 9dc2 +7404 9dd9 +7405 9dd3 +7406 9df8 +7407 9de6 +7408 9ded +7409 9def +7410 9dfd +7411..7412 9e1a +7413 9e1e +7414 9e75 +7415 9e79 +7416 9e7d +7417 9e81 +7418 9e88 +7419..7420 9e8b +7421 9e92 +7422 9e95 +7423 9e91 +7424 9e9d +7425 9ea5 +7426 9ea9 +7427 9eb8 +7428 9eaa +7429 9ead +7430 9761 +7431 9ecc +7432..7434 9ece +7435 9ed4 +7436 9edc +7437 9ede +7438 9edd +7439 9ee0 +7440 9ee5 +7441 9ee8 +7442 9eef +7443 9ef4 +7444..7445 9ef6 +7446 9ef9 +7447..7449 9efb +7450..7451 9f07 +7452 76b7 +7453 9f15 +7454 9f21 +7455 9f2c +7456 9f3e +7457 9f4a +7458 9f52 +7459 9f54 +7460 9f63 +7461..7463 9f5f +7464..7465 9f66 +7466 9f6c +7467 9f6a +7468 9f77 +7469 9f72 +7470 9f76 +7471 9f95 +7472 9f9c +7473 9fa0 +7474 582f +7475 69c7 +7476 9059 +7477 7464 +7479..7554 2500 +7555..7574 2460 +7575..7584 2160 +7585 3349 +7586 3314 +7588 334d +7590 3327 +7592 3336 +7593 3351 +7595 330d +7596 3326 +7598 332b +7599 334a +7601..7603 339c +7604..7605 338e +7606 33c4 +7607 33a1 +7608 301d +7609 301f +7610 2116 +7611 33cd +7613..7617 32a4 +7618..7619 3231 +7620 3239 +7621 337e +7622 337d +7623 337c +7624 222e +7625 2211 +7629 221f +7630 22bf +7633 555e +7641 28cdd +7644 7130 +7646 9dd7 +7651 fa36 +7654 5699 +7655 3d4e +7660 4fe0 +7663 8ec0 +7665 2f8ed +7670 25874 +7671 7e6b +7672 8346 +7673 28ef6 +7677 9e7c +7680 663b +7682 9eb4 +7687 6805 +7693 5c62 +7695 2f8dc +7697 7e61 +7700 fa46 +7706 8523 +7707 91ac +7715 87ec +7724 6414 +7725 7626 +7727 9a52 +7732 fa4a +7734 2f884 +7739 7c1e +7746 fa10 +7747 6451 +7750 f9ec +7751 5861 +7752 985a +7754 2f877 +7758 79b1 +7760 7006 +7770 56ca +7774 525d +7776 6f51 +7777 91b1 +7788 fa6a +7795 9830 +7797 9eb5 +7807 840a +7808 f9c3 +7809..7810 f992 +7811 f999 +7813 881f +7814 2f80f +7816 2f8d3 +7817 2f818 +7825 21a1a +7826 5c5b +7831 6522 +7834 67fa +7836 688e +7838 243d0 +7839 2f920 +7861 853e +7877 7762 +7887 /uni3001.vert +7888 /uni3002.vert +7889 /uniFFE3.vert +7890 /uniFE33.vert +7891 /uni30FC.vert +7892 /uniFE31.vert +7893 /uniFE32.vert +7894 /Japan1.665.vert +7895 /Japan1.666.vert +7896 /Japan1.667.vert +7897 /Japan1.668.vert +7898 /Japan1.669.vert +7899 /Japan1.674.vert +7900 /Japan1.675.vert +7901 /Japan1.676.vert +7902 /Japan1.677.vert +7903 /Japan1.678.vert +7904 /Japan1.679.vert +7905 /Japan1.680.vert +7906 /Japan1.681.vert +7907 /Japan1.682.vert +7908 /Japan1.683.vert +7909 /Japan1.684.vert +7910 /Japan1.685.vert +7911 /Japan1.686.vert +7912 /Japan1.687.vert +7913 /Japan1.688.vert +7914 /Japan1.689.vert +7915 /Japan1.690.vert +7916 /Japan1.691.vert +7917 /Japan1.697.vert +7918 /Japan1.842.vert +7919 /Japan1.844.vert +7920 /Japan1.846.vert +7921 /Japan1.848.vert +7922 /Japan1.850.vert +7923 /Japan1.876.vert +7924 /Japan1.908.vert +7925 /Japan1.910.vert +7926 /Japan1.912.vert +7927 /Japan1.919.vert +7928 /Japan1.925.vert +7929 /Japan1.927.vert +7930 /Japan1.929.vert +7931 /Japan1.931.vert +7932 /Japan1.933.vert +7933 /Japan1.959.vert +7934 /Japan1.991.vert +7935 /Japan1.993.vert +7936 /Japan1.995.vert +7937 /Japan1.1002.vert +7938 /Japan1.1009.vert +7939 /Japan1.1010.vert +7940 /Japan1.7585.vert +7941 /Japan1.7586.vert +7943 /Japan1.7588.vert +7945 /Japan1.7590.vert +7947 /Japan1.7592.vert +7948 /Japan1.7593.vert +7950 /Japan1.7595.vert +7951 /Japan1.7596.vert +7953 /Japan1.7598.vert +7954 /Japan1.7599.vert +7956 /Japan1.7608.vert +7957 /Japan1.7609.vert +7958..7960 3094 +7963 5653 +8005 ffe4 +8006 ff07 +8007 ff02 +8009 25c1 +8010 25b7 +8011 21e9 +8012 21e7 +8013 21e6 +8014 21e8 +8015 25a2 +8016 2667 +8017 2661 +8018 2664 +8019 2662 +8020 33a0 +8021 33a2 +8022..8023 33a4 +8024 3397 +8025 2113 +8026 3398 +8027 33b3 +8028 33b2 +8029 33b1 +8030 33b0 +8031..8033 3385 +8034 33cb +8035 3390 +8036 33d4 +8037 3396 +8038 3322 +8039 3316 +8040 3318 +8041 3315 +8042 3303 +8043 3323 +8044 3357 +8045 3342 +8046 3339 +8047 333b +8048 3300 +8049 3331 +8050 3347 +8051 331e +8052 332a +8054 337f +8055 2121 +8056 260e +8057 3036 +8058 3020 +8062..8070 2488 +8071..8090 2474 +8091 3251 +8092..8101 2170 +8102..8111 3252 +8112..8137 249c +8138 3243 +8139 323d +8140 323f +8141 3234 +8142 3238 +8143 3233 +8144 323c +8145 3242 +8146 323e +8147 3236 +8148 3235 +8149 323b +8150 3240 +8151 323a +8152 32b0 +8153 32ad +8154 32a9 +8155 32af +8156 3294 +8157 32aa +8158 3298 +8159 32ab +8160 3292 +8161 3291 +8162 3293 +8163 32ac +8164 32ae +8165 3296 +8166 /Japan1.8180.vert +8167 /Japan1.8179.vert +8168 /Japan1.8178.vert +8170 /Japan1.8176.vert +8171 /Japan1.8175.vert +8172 /Japan1.8174.vert +8174..8176 23ab +8178..8180 23a7 +8182 33cc +8183 3305 +8186 339f +8187 33a3 +8188 33a6 +8191 329e +8192..8193 3388 +8194 33c8 +8195 222d +8197 3230 +8198..8203 322a +8204 3237 +8205 3241 +8206 27a1 +8207..8209 2b05 +8210 25c9 +8211 2660 +8212 2665 +8213 2663 +8214 2666 +8215..8218 2600 +8219 261e +8220..8221 261c +8222 261f +8223 3299 +8224 24ea +8225..8226 216a +8230..8237 2581 +8238 258f +8239 258e +8240 258d +8241 258c +8242 258b +8243 258a +8244 2589 +8245..8246 2594 +8247..8248 256d +8249 2570 +8250 256f +8251 2550 +8252 255e +8253 256a +8254 2561 +8255..8256 25e2 +8257 25e5 +8258 25e4 +8261..8263 2571 +8264 /Japan1.7959.vert +8265 /Japan1.7960.vert +8268 /Japan1.636.vert +8269 /Japan1.707.vert +8270 /Japan1.740.vert +8271 /Japan1.644.vert +8272 /Japan1.643.vert +8273 /Japan1.708.vert +8274 /Japan1.637.vert +8279 /Japan1.108.vert +8280 /Japan1.122.vert +8281 /Japan1.670.vert +8282 /Japan1.671.vert +8283 /Japan1.709.vert +8284 51dc +8285 7199 +8286..8294 2776 +8298..8299 217a +8303 217f +8304 210a +8305 2109 +8307 213b +8308 3004 +8309 21c6 +8310..8311 21c4 +8312 /Japan1.8309.vert +8313..8316 30f7 +8319 329d +8323 337b +8324 /Japan1.8054.vert +8327 3333 +8328 334e +8329 /Japan1.8038.vert +8330 /Japan1.8039.vert +8333 /Japan1.8183.vert +8334 /Japan1.8327.vert +8337 /Japan1.8328.vert +8338 /Japan1.8042.vert +8339 /Japan1.8040.vert +8340 /Japan1.8041.vert +8343 /Japan1.8046.vert +8344 /Japan1.8044.vert +8347 /Japan1.8045.vert +8348 /Japan1.8043.vert +8349 /Japan1.8047.vert +8350 /Japan1.8048.vert +8353 /Japan1.8051.vert +8356 /Japan1.8052.vert +8357 /Japan1.8050.vert +8358 /Japan1.8049.vert +8359 7e8a +8360 891c +8361 9348 +8362 9288 +8363 84dc +8364 4fc9 +8365 70bb +8366 6631 +8367 68c8 +8368 92f9 +8369 66fb +8370 5f45 +8371 4e28 +8372 4ee1 +8373 4efc +8374 4f00 +8375 4f03 +8376 4f39 +8377 4f56 +8378 4f92 +8379 4f8a +8380 4f9a +8381 4f94 +8382 4fcd +8383 5040 +8384 5022 +8385 4fff +8386 501e +8387 5046 +8388 5070 +8389 5042 +8390 5094 +8391 50f4 +8392 50d8 +8393 514a +8394 5164 +8395 519d +8396 51be +8397 51ec +8398 5215 +8399 529c +8400 52a6 +8401 52c0 +8402 52db +8403 5300 +8404 5307 +8405 5324 +8406 5372 +8407 5393 +8408 53b2 +8409 53dd +8410 fa0e +8411 549c +8412 548a +8413 54a9 +8414 54ff +8415 5586 +8416 5759 +8417 5765 +8418 57ac +8419 57c8 +8420 57c7 +8421 fa0f +8422 /uniFA10.dup2 +8423 589e +8424 58b2 +8425 590b +8426 5953 +8427 595b +8428 595d +8429 5963 +8430 59a4 +8431 59ba +8432 5b56 +8433 5bc0 +8434 752f +8435 5bd8 +8436 5bec +8437 5c1e +8438 5ca6 +8439 5cba +8440 5cf5 +8441 5d27 +8442 5d53 +8443 fa11 +8444 5d42 +8445 5d6d +8446..8447 5db8 +8448 5dd0 +8449 5f21 +8450 5f34 +8451 5f67 +8452 5fb7 +8453 5fde +8454 605d +8455 6085 +8456 608a +8457 60de +8458 60d5 +8459 6120 +8460 60f2 +8461 6111 +8462 6137 +8463 6130 +8464 6198 +8465 6213 +8466 62a6 +8467 63f5 +8468 6460 +8469 649d +8470 64ce +8471 654e +8472 6600 +8473 6615 +8474 6609 +8475 662e +8476 661e +8477 6624 +8478 6665 +8479 6657 +8480 6659 +8481 fa12 +8482 6673 +8483 6699 +8484 66a0 +8485 66b2 +8486 66bf +8487 66fa +8488 670e +8489 f929 +8490 6766 +8491 67bb +8492 6852 +8493 67c0 +8494 6801 +8495 6844 +8496 68cf +8497 fa13 +8498 6968 +8499 fa14 +8500 6998 +8501 69e2 +8502 6a30 +8503 6a6b +8504 6a46 +8505 6a73 +8506 6a7e +8507 6ae2 +8508 6ae4 +8509 6bd6 +8510 6c3f +8511 6c5c +8512 6c86 +8513 6c6f +8514 6cda +8515 6d04 +8516 6d87 +8517 6d6f +8518 6d96 +8519 6dac +8520 6dcf +8521 6df8 +8522 6df2 +8523 6dfc +8524 6e39 +8525 6e5c +8526 6e27 +8527 6e3c +8528 6ebf +8529 6f88 +8530 6fb5 +8531 6ff5 +8532 7005 +8533 7007 +8534 7028 +8535 7085 +8536 70ab +8537 710f +8538 7104 +8539 715c +8540..8541 7146 +8542 fa15 +8543 71c1 +8544 71fe +8545 72b1 +8546 72be +8547 7324 +8548 fa16 +8549 7377 +8550 73bd +8551 73c9 +8552 73d6 +8553 73e3 +8554 73d2 +8555 7407 +8556 73f5 +8557 7426 +8558 742a +8559 7429 +8560 742e +8561 7462 +8562 7489 +8563 749f +8564 7501 +8565 756f +8566 7682 +8567 769c +8568 769e +8569 769b +8570 76a6 +8571 fa17 +8572 7746 +8573 52af +8574 7821 +8575 784e +8576 7864 +8577 787a +8578 7930 +8579..8581 fa18 +8582 7994 +8583 fa1b +8584 799b +8585 7ad1 +8586 7ae7 +8587 fa1c +8588 7aeb +8589 7b9e +8590 fa1d +8591 7d48 +8592 7d5c +8593 7db7 +8594 7da0 +8595 7dd6 +8596 7e52 +8597 7f47 +8598 7fa1 +8599 fa1e +8600 8301 +8601 8362 +8602 837f +8603 83c7 +8604 83f6 +8605 8448 +8606 84b4 +8607 8553 +8608 8559 +8609 856b +8610 fa1f +8611 85b0 +8612..8613 fa20 +8614 8807 +8615 88f5 +8616 8a12 +8617 8a37 +8618 8a79 +8619 8aa7 +8620 8abe +8621 8adf +8622 fa22 +8623 8af6 +8624 8b53 +8625 8b7f +8626 8cf0 +8627 8cf4 +8628 8d12 +8629 8d76 +8630 fa23 +8631 8ecf +8632..8633 fa24 +8634 9067 +8635 90de +8636 fa26 +8637 9115 +8638 9127 +8639 91da +8640 91d7 +8641 91de +8642..8643 91ed +8644..8645 91e4 +8646 9206 +8647 9210 +8648 920a +8649 923a +8650 9240 +8651 923c +8652 924e +8653 9259 +8654 9251 +8655 9239 +8656 9267 +8657 92a7 +8658..8659 9277 +8660 92e7 +8661 92d7 +8662 92d9 +8663 92d0 +8664 fa27 +8665 92d5 +8666 92e0 +8667 92d3 +8668 9325 +8669 9321 +8670 92fb +8671 fa28 +8672 931e +8673 92ff +8674 931d +8675 9302 +8676 9370 +8677 9357 +8678 93a4 +8679 93c6 +8680 93de +8681 93f8 +8682 9431 +8683 9445 +8684 9448 +8685 9592 +8686 f9dc +8687 fa29 +8688 969d +8689 96af +8690 9733 +8691 973b +8692 9743 +8693 974d +8694 974f +8695 9751 +8696 9755 +8697 9857 +8698 9865 +8699..8700 fa2a +8701 9927 +8702 fa2c +8703 999e +8704 9a4e +8705 9ad9 +8706 9adc +8707 9b75 +8708 9b72 +8709 9b8f +8710 9bb1 +8711 9bbb +8712 9c00 +8713 9d70 +8714 9d6b +8715 fa2d +8716 9e19 +8717 9ed1 +8719 /uni005C.hw +8720 /Japan1.1.vert +8721 /Japan1.2.vert +8722 /Japan1.3.vert +8723 /Japan1.4.vert +8724 /Japan1.5.vert +8725 /Japan1.6.vert +8726 /Japan1.7.vert +8727 /Japan1.8.vert +8728 /Japan1.9.vert +8729 /Japan1.10.vert +8730 /Japan1.11.vert +8731 /Japan1.12.vert +8732 /Japan1.13.vert +8733 /Japan1.14.vert +8734 /Japan1.15.vert +8735 /Japan1.16.vert +8736 /Japan1.17.vert +8737 /Japan1.18.vert +8738 /Japan1.19.vert +8739 /Japan1.20.vert +8740 /Japan1.21.vert +8741 /Japan1.22.vert +8742 /Japan1.23.vert +8743 /Japan1.24.vert +8744 /Japan1.25.vert +8745 /Japan1.26.vert +8746 /Japan1.27.vert +8747 /Japan1.28.vert +8748 /Japan1.29.vert +8749 /Japan1.30.vert +8750 /Japan1.31.vert +8751 /Japan1.32.vert +8752 /Japan1.33.vert +8753 /Japan1.34.vert +8754 /Japan1.35.vert +8755 /Japan1.36.vert +8756 /Japan1.37.vert +8757 /Japan1.38.vert +8758 /Japan1.39.vert +8759 /Japan1.40.vert +8760 /Japan1.41.vert +8761 /Japan1.42.vert +8762 /Japan1.43.vert +8763 /Japan1.44.vert +8764 /Japan1.45.vert +8765 /Japan1.46.vert +8766 /Japan1.47.vert +8767 /Japan1.48.vert +8768 /Japan1.49.vert +8769 /Japan1.50.vert +8770 /Japan1.51.vert +8771 /Japan1.52.vert +8772 /Japan1.53.vert +8773 /Japan1.54.vert +8774 /Japan1.55.vert +8775 /Japan1.56.vert +8776 /Japan1.57.vert +8777 /Japan1.58.vert +8778 /Japan1.59.vert +8779 /Japan1.60.vert +8780 /Japan1.61.vert +8781 /Japan1.62.vert +8782 /Japan1.63.vert +8783 /Japan1.64.vert +8784 /Japan1.65.vert +8785 /Japan1.66.vert +8786 /Japan1.67.vert +8787 /Japan1.68.vert +8788 /Japan1.69.vert +8789 /Japan1.70.vert +8790 /Japan1.71.vert +8791 /Japan1.72.vert +8792 /Japan1.73.vert +8793 /Japan1.74.vert +8794 /Japan1.75.vert +8795 /Japan1.76.vert +8796 /Japan1.77.vert +8797 /Japan1.78.vert +8798 /Japan1.79.vert +8799 /Japan1.80.vert +8800 /Japan1.81.vert +8801 /Japan1.82.vert +8802 /Japan1.83.vert +8803 /Japan1.84.vert +8804 /Japan1.85.vert +8805 /Japan1.86.vert +8806 /Japan1.87.vert +8807 /Japan1.88.vert +8808 /Japan1.89.vert +8809 /Japan1.90.vert +8810 /Japan1.91.vert +8811 /Japan1.92.vert +8812 /Japan1.93.vert +8813 /Japan1.94.vert +8814 /Japan1.95.vert +8815 /Japan1.96.vert +8816 /Japan1.97.vert +8817 /Japan1.98.vert +8818 /Japan1.99.vert +8819 /Japan1.100.vert +8820 /Japan1.101.vert +8821 /Japan1.102.vert +8822 /Japan1.103.vert +8823 /Japan1.104.vert +8824 /Japan1.105.vert +8825 /Japan1.106.vert +8826 /Japan1.107.vert +8827 /Japan1.108.vert +8828 /Japan1.109.vert +8829 /Japan1.110.vert +8830 /Japan1.111.vert +8831 /Japan1.112.vert +8832 /Japan1.113.vert +8833 /Japan1.114.vert +8834 /Japan1.115.vert +8835 /Japan1.116.vert +8836 /Japan1.117.vert +8837 /Japan1.118.vert +8838 /Japan1.119.vert +8839 /Japan1.120.vert +8840 /Japan1.121.vert +8841 /Japan1.122.vert +8842 /Japan1.123.vert +8843 /Japan1.124.vert +8844 /Japan1.125.vert +8845 /Japan1.126.vert +8846 /Japan1.127.vert +8847 /Japan1.128.vert +8848 /Japan1.129.vert +8849 /Japan1.130.vert +8850 /Japan1.131.vert +8851 /Japan1.132.vert +8852 /Japan1.133.vert +8853 /Japan1.134.vert +8854 /Japan1.135.vert +8855 /Japan1.136.vert +8856 /Japan1.137.vert +8857 /Japan1.138.vert +8858 /Japan1.139.vert +8859 /Japan1.140.vert +8860 /Japan1.141.vert +8861 /Japan1.142.vert +8862 /Japan1.143.vert +8863 /Japan1.144.vert +8864 /Japan1.145.vert +8865 /Japan1.146.vert +8866 /Japan1.147.vert +8867 /Japan1.148.vert +8868 /Japan1.149.vert +8869 /Japan1.150.vert +8870 /Japan1.151.vert +8871 /Japan1.152.vert +8872 /Japan1.153.vert +8873 /Japan1.154.vert +8874 /Japan1.155.vert +8875 /Japan1.156.vert +8876 /Japan1.157.vert +8877 /Japan1.158.vert +8878 /Japan1.159.vert +8879 /Japan1.160.vert +8880 /Japan1.161.vert +8881 /Japan1.162.vert +8882 /Japan1.163.vert +8883 /Japan1.164.vert +8884 /Japan1.165.vert +8885 /Japan1.166.vert +8886 /Japan1.167.vert +8887 /Japan1.168.vert +8888 /Japan1.169.vert +8889 /Japan1.170.vert +8890 /Japan1.171.vert +8891 /Japan1.172.vert +8892 /Japan1.173.vert +8893 /Japan1.174.vert +8894 /Japan1.175.vert +8895 /Japan1.176.vert +8896 /Japan1.177.vert +8897 /Japan1.178.vert +8898 /Japan1.179.vert +8899 /Japan1.180.vert +8900 /Japan1.181.vert +8901 /Japan1.182.vert +8902 /Japan1.183.vert +8903 /Japan1.184.vert +8904 /Japan1.185.vert +8905 /Japan1.186.vert +8906 /Japan1.187.vert +8907 /Japan1.188.vert +8908 /Japan1.189.vert +8909 /Japan1.190.vert +8910 /Japan1.191.vert +8911 /Japan1.192.vert +8912 /Japan1.193.vert +8913 /Japan1.194.vert +8914 /Japan1.195.vert +8915 /Japan1.196.vert +8916 /Japan1.197.vert +8917 /Japan1.198.vert +8918 /Japan1.199.vert +8919 /Japan1.200.vert +8920 /Japan1.201.vert +8921 /Japan1.202.vert +8922 /Japan1.203.vert +8923 /Japan1.204.vert +8924 /Japan1.205.vert +8925 /Japan1.206.vert +8926 /Japan1.207.vert +8927 /Japan1.208.vert +8928 /Japan1.209.vert +8929 /Japan1.210.vert +8930 /Japan1.211.vert +8931 /Japan1.212.vert +8932 /Japan1.213.vert +8933 /Japan1.214.vert +8934 /Japan1.215.vert +8935 /Japan1.216.vert +8936 /Japan1.217.vert +8937 /Japan1.218.vert +8938 /Japan1.219.vert +8939 /Japan1.220.vert +8940 /Japan1.221.vert +8941 /Japan1.222.vert +8942 /Japan1.223.vert +8943 /Japan1.224.vert +8944 /Japan1.225.vert +8945 /Japan1.226.vert +8946 /Japan1.227.vert +8947 /Japan1.228.vert +8948 /Japan1.229.vert +8949 /Japan1.230.vert +8950 /Japan1.231.vert +8951 /Japan1.232.vert +8952 /Japan1.233.vert +8953 /Japan1.234.vert +8954 /Japan1.235.vert +8955 /Japan1.236.vert +8956 /Japan1.237.vert +8957 /Japan1.238.vert +8958 /Japan1.239.vert +8959 /Japan1.240.vert +8960 /Japan1.241.vert +8961 /Japan1.242.vert +8962 /Japan1.243.vert +8963 /Japan1.244.vert +8964 /Japan1.245.vert +8965 /Japan1.246.vert +8966 /Japan1.247.vert +8967 /Japan1.248.vert +8968 /Japan1.249.vert +8969 /Japan1.250.vert +8970 /Japan1.251.vert +8971 /Japan1.252.vert +8972 /Japan1.253.vert +8973 /Japan1.254.vert +8974 /Japan1.255.vert +8975 /Japan1.256.vert +8976 /Japan1.257.vert +8977 /Japan1.258.vert +8978 /Japan1.259.vert +8979 /Japan1.260.vert +8980 /Japan1.261.vert +8981 /Japan1.262.vert +8982 /Japan1.263.vert +8983 /Japan1.264.vert +8984 /Japan1.265.vert +8985 /Japan1.266.vert +8986 /Japan1.267.vert +8987 /Japan1.268.vert +8988 /Japan1.269.vert +8989 /Japan1.270.vert +8990 /Japan1.271.vert +8991 /Japan1.272.vert +8992 /Japan1.273.vert +8993 /Japan1.274.vert +8994 /Japan1.275.vert +8995 /Japan1.276.vert +8996 /Japan1.277.vert +8997 /Japan1.278.vert +8998 /Japan1.279.vert +8999 /Japan1.280.vert +9000 /Japan1.281.vert +9001 /Japan1.282.vert +9002 /Japan1.283.vert +9003 /Japan1.284.vert +9004 /Japan1.285.vert +9005 /Japan1.286.vert +9006 /Japan1.287.vert +9007 /Japan1.288.vert +9008 /Japan1.289.vert +9009 /Japan1.290.vert +9010 /Japan1.291.vert +9011 /Japan1.292.vert +9012 /Japan1.293.vert +9013 /Japan1.294.vert +9014 /Japan1.295.vert +9015 /Japan1.296.vert +9016 /Japan1.297.vert +9017 /Japan1.298.vert +9018 /Japan1.299.vert +9019 /Japan1.300.vert +9020 /Japan1.301.vert +9021 /Japan1.302.vert +9022 /Japan1.303.vert +9023 /Japan1.304.vert +9024 /Japan1.305.vert +9025 /Japan1.306.vert +9026 /Japan1.307.vert +9027 /Japan1.308.vert +9028 /Japan1.309.vert +9029 /Japan1.310.vert +9030 /Japan1.311.vert +9031 /Japan1.312.vert +9032 /Japan1.313.vert +9033 /Japan1.314.vert +9034 /Japan1.315.vert +9035 /Japan1.316.vert +9036 /Japan1.317.vert +9037 /Japan1.318.vert +9038 /Japan1.319.vert +9039 /Japan1.320.vert +9040 /Japan1.321.vert +9041 /Japan1.322.vert +9042 /Japan1.323.vert +9043 /Japan1.324.vert +9044 /Japan1.325.vert +9045 /Japan1.599.vert +9046 /Japan1.600.vert +9047 /Japan1.601.vert +9048 /Japan1.602.vert +9049 /Japan1.603.vert +9050 /Japan1.604.vert +9051 /Japan1.605.vert +9052 /Japan1.606.vert +9053 /Japan1.607.vert +9054 /Japan1.608.vert +9055 /Japan1.609.vert +9056 /Japan1.610.vert +9057 /Japan1.611.vert +9058 /Japan1.612.vert +9059 /Japan1.613.vert +9060 /Japan1.614.vert +9061 /Japan1.615.vert +9062 /Japan1.616.vert +9063 /Japan1.617.vert +9064 /Japan1.618.vert +9065 /Japan1.619.vert +9066 /Japan1.620.vert +9067 /Japan1.621.vert +9068 /Japan1.622.vert +9069 /Japan1.623.vert +9070 /Japan1.624.vert +9071 /Japan1.625.vert +9072 /Japan1.626.vert +9073 /Japan1.627.vert +9074 /Japan1.628.vert +9075 /Japan1.629.vert +9076 /Japan1.630.vert +9077 /Japan1.631.vert +9078 /Japan1.632.vert +9079 /Japan1.630.vert +9080 /Japan1.631.vert +9081 /Japan1.632.vert +9083 /Japan1.8719.vert +9084 /Japan1.326.vert +9085 /Japan1.327.vert +9086 /Japan1.328.vert +9087 /Japan1.329.vert +9088 /Japan1.330.vert +9089 /Japan1.331.vert +9090 /Japan1.332.vert +9091 /Japan1.333.vert +9092 /Japan1.334.vert +9093 /Japan1.335.vert +9094 /Japan1.336.vert +9095 /Japan1.337.vert +9096 /Japan1.338.vert +9097 /Japan1.339.vert +9098 /Japan1.340.vert +9099 /Japan1.341.vert +9100 /Japan1.342.vert +9101 /Japan1.343.vert +9102 /Japan1.344.vert +9103 /Japan1.345.vert +9104 /Japan1.346.vert +9105 /Japan1.347.vert +9106 /Japan1.348.vert +9107 /Japan1.349.vert +9108 /Japan1.350.vert +9109 /Japan1.351.vert +9110 /Japan1.352.vert +9111 /Japan1.353.vert +9112 /Japan1.354.vert +9113 /Japan1.355.vert +9114 /Japan1.356.vert +9115 /Japan1.357.vert +9116 /Japan1.358.vert +9117 /Japan1.359.vert +9118 /Japan1.360.vert +9119 /Japan1.361.vert +9120 /Japan1.362.vert +9121 /Japan1.363.vert +9122 /Japan1.364.vert +9123 /Japan1.365.vert +9124 /Japan1.366.vert +9125 /Japan1.367.vert +9126 /Japan1.368.vert +9127 /Japan1.369.vert +9128 /Japan1.370.vert +9129 /Japan1.371.vert +9130 /Japan1.372.vert +9131 /Japan1.373.vert +9132 /Japan1.374.vert +9133 /Japan1.375.vert +9134 /Japan1.376.vert +9135 /Japan1.377.vert +9136 /Japan1.378.vert +9137 /Japan1.379.vert +9138 /Japan1.380.vert +9139 /Japan1.381.vert +9140 /Japan1.382.vert +9141 /Japan1.383.vert +9142 /Japan1.384.vert +9143 /Japan1.385.vert +9144 /Japan1.386.vert +9145 /Japan1.387.vert +9146 /Japan1.388.vert +9147 /Japan1.389.vert +9148 /Japan1.391.vert +9149 /Japan1.392.vert +9150 /Japan1.393.vert +9151 /Japan1.394.vert +9152 /Japan1.395.vert +9153 /Japan1.396.vert +9154 /Japan1.397.vert +9155 /Japan1.398.vert +9156 /Japan1.399.vert +9157 /Japan1.400.vert +9158 /Japan1.401.vert +9159 /Japan1.402.vert +9160 /Japan1.403.vert +9161 /Japan1.404.vert +9162 /Japan1.405.vert +9163 /Japan1.406.vert +9164 /Japan1.407.vert +9165 /Japan1.408.vert +9166 /Japan1.409.vert +9167 /Japan1.410.vert +9168 /Japan1.411.vert +9169 /Japan1.412.vert +9170 /Japan1.413.vert +9171 /Japan1.414.vert +9172 /Japan1.415.vert +9173 /Japan1.416.vert +9174 /Japan1.417.vert +9175 /Japan1.418.vert +9176 /Japan1.419.vert +9177 /Japan1.420.vert +9178 /Japan1.421.vert +9179 /Japan1.515.vert +9180 /Japan1.516.vert +9181 /Japan1.517.vert +9182 /Japan1.518.vert +9183 /Japan1.519.vert +9184 /Japan1.520.vert +9185 /Japan1.521.vert +9186 /Japan1.522.vert +9187 /Japan1.523.vert +9188 /Japan1.524.vert +9189 /Japan1.525.vert +9190 /Japan1.526.vert +9191 /Japan1.527.vert +9192 /Japan1.528.vert +9193 /Japan1.529.vert +9194 /Japan1.530.vert +9195 /Japan1.531.vert +9196 /Japan1.532.vert +9197 /Japan1.533.vert +9198 /Japan1.534.vert +9199 /Japan1.535.vert +9200 /Japan1.536.vert +9201 /Japan1.537.vert +9202 /Japan1.538.vert +9203 /Japan1.539.vert +9204 /Japan1.540.vert +9205 /Japan1.541.vert +9206 /Japan1.542.vert +9207 /Japan1.543.vert +9208 /Japan1.544.vert +9209 /Japan1.545.vert +9210 /Japan1.546.vert +9211 /Japan1.547.vert +9212 /Japan1.548.vert +9213 /Japan1.549.vert +9214 /Japan1.550.vert +9215 /Japan1.551.vert +9216 /Japan1.552.vert +9217 /Japan1.553.vert +9218 /Japan1.554.vert +9219 /Japan1.555.vert +9220 /Japan1.556.vert +9221 /Japan1.557.vert +9222 /Japan1.558.vert +9223 /Japan1.559.vert +9224 /Japan1.560.vert +9225 /Japan1.561.vert +9226 /Japan1.562.vert +9227 /Japan1.563.vert +9228 /Japan1.564.vert +9229 /Japan1.565.vert +9230 /Japan1.566.vert +9231 /Japan1.567.vert +9232 /Japan1.568.vert +9233 /Japan1.569.vert +9234 /Japan1.570.vert +9235 /Japan1.571.vert +9236 /Japan1.572.vert +9237 /Japan1.573.vert +9238 /Japan1.574.vert +9239 /Japan1.575.vert +9240 /Japan1.576.vert +9241 /Japan1.577.vert +9242 /Japan1.578.vert +9243 /Japan1.579.vert +9244 /Japan1.580.vert +9245 /Japan1.581.vert +9246 /Japan1.582.vert +9247 /Japan1.583.vert +9248 /Japan1.584.vert +9249 /Japan1.585.vert +9250 /Japan1.586.vert +9251 /Japan1.587.vert +9252 /Japan1.588.vert +9253 /Japan1.589.vert +9254 /Japan1.590.vert +9255 /Japan1.591.vert +9256 /Japan1.592.vert +9257 /Japan1.593.vert +9258 /Japan1.594.vert +9259 /Japan1.595.vert +9260 /Japan1.596.vert +9261 /Japan1.597.vert +9262 /Japan1.598.vert +9263 /Japan1.423.vert +9264 /Japan1.424.vert +9265 /Japan1.504.vert +9266 /Japan1.505.vert +9267 /Japan1.506.vert +9268 /Japan1.507.vert +9269 /Japan1.508.vert +9270 /Japan1.509.vert +9271 /Japan1.510.vert +9272 /Japan1.511.vert +9273 /Japan1.512.vert +9274 /Japan1.513.vert +9275 /Japan1.514.vert +9276 /Japan1.515.vert +9277 /Japan1.425.vert +9278 /Japan1.426.vert +9279 /Japan1.427.vert +9280 /Japan1.428.vert +9281 /Japan1.429.vert +9282 /Japan1.430.vert +9283 /Japan1.431.vert +9284 /Japan1.432.vert +9285 /Japan1.433.vert +9286 /Japan1.434.vert +9287 /Japan1.435.vert +9288 /Japan1.436.vert +9289 /Japan1.437.vert +9290 /Japan1.438.vert +9291 /Japan1.439.vert +9292 /Japan1.440.vert +9293 /Japan1.441.vert +9294 /Japan1.442.vert +9295 /Japan1.443.vert +9296 /Japan1.444.vert +9297 /Japan1.445.vert +9298 /Japan1.446.vert +9299 /Japan1.447.vert +9300 /Japan1.448.vert +9301 /Japan1.449.vert +9302 /Japan1.450.vert +9303 /Japan1.451.vert +9304 /Japan1.452.vert +9305 /Japan1.453.vert +9306 /Japan1.454.vert +9307 /Japan1.455.vert +9308 /Japan1.456.vert +9309 /Japan1.457.vert +9310 /Japan1.458.vert +9311 /Japan1.459.vert +9312 /Japan1.460.vert +9313 /Japan1.461.vert +9314 /Japan1.462.vert +9315 /Japan1.463.vert +9316 /Japan1.464.vert +9317 /Japan1.465.vert +9318 /Japan1.466.vert +9319 /Japan1.467.vert +9320 /Japan1.468.vert +9321 /Japan1.469.vert +9322 /Japan1.470.vert +9323 /Japan1.471.vert +9324 /Japan1.472.vert +9325 /Japan1.473.vert +9326 /Japan1.474.vert +9327 /Japan1.475.vert +9328 /Japan1.476.vert +9329 /Japan1.477.vert +9330 /Japan1.478.vert +9331 /Japan1.479.vert +9332 /Japan1.480.vert +9333 /Japan1.481.vert +9334 /Japan1.482.vert +9335 /Japan1.483.vert +9336 /Japan1.484.vert +9337 /Japan1.485.vert +9338 /Japan1.486.vert +9339 /Japan1.487.vert +9340 /Japan1.488.vert +9341 /Japan1.489.vert +9342 /Japan1.490.vert +9343 /Japan1.491.vert +9344 /Japan1.492.vert +9345 /Japan1.493.vert +9346 /Japan1.494.vert +9347 /Japan1.495.vert +9348 /Japan1.496.vert +9349 /Japan1.497.vert +9350 /Japan1.498.vert +9351 /Japan1.499.vert +9352 /Japan1.500.vert +9353 /Japan1.501.vert +9354 20ac +9355 2126 +9358 fb00 +9359..9360 fb03 +9361 0101 +9362 012b +9363 016b +9364 0113 +9365 014d +9366 0100 +9367 012a +9368 016a +9369 0112 +9370 014c +9371..9374 215b +9375..9376 2153 +9377 2070 +9378..9383 2074 +9384..9393 2080 +9394 01cd +9395 011a +9397 1ebc +9398 01cf +9400 0128 +9401 01d1 +9403 01d3 +9404 016e +9405 0168 +9406 01ce +9407 011b +9409 1ebd +9410 01d0 +9412 0129 +9413 01d2 +9415 01d4 +9416 016f +9417 0169 +9418 0251 +9419 1f71 +9420 1f70 +9421 01fd +9423 0254 +9426 0259 +9429 025a +9432 025b +9433 1f73 +9434 1f72 +9435 f6be +9436 014b +9437 0275 +9438 028c +9441 0292 +9442 0283 +9443 02d0 +9444 /uni0020.italic +9445 /uni0021.italic +9446 /uni0022.italic +9447 /uni0023.italic +9448 /uni0024.italic +9449 /uni0025.italic +9450 /uni0026.italic +9451 /uni0027.italic +9452 /uni0028.italic +9453 /uni0029.italic +9454 /uni002A.italic +9455 /uni002B.italic +9456 /uni002C.italic +9457 /uni002D.italic +9458 /uni002E.italic +9459 /uni002F.italic +9460 /uni0030.italic +9461 /uni0031.italic +9462 /uni0032.italic +9463 /uni0033.italic +9464 /uni0034.italic +9465 /uni0035.italic +9466 /uni0036.italic +9467 /uni0037.italic +9468 /uni0038.italic +9469 /uni0039.italic +9470 /uni003A.italic +9471 /uni003B.italic +9472 /uni003C.italic +9473 /uni003D.italic +9474 /uni003E.italic +9475 /uni003F.italic +9476 /uni0040.italic +9477 /uni0041.italic +9478 /uni0042.italic +9479 /uni0043.italic +9480 /uni0044.italic +9481 /uni0045.italic +9482 /uni0046.italic +9483 /uni0047.italic +9484 /uni0048.italic +9485 /uni0049.italic +9486 /uni004A.italic +9487 /uni004B.italic +9488 /uni004C.italic +9489 /uni004D.italic +9490 /uni004E.italic +9491 /uni004F.italic +9492 /uni0050.italic +9493 /uni0051.italic +9494 /uni0052.italic +9495 /uni0053.italic +9496 /uni0054.italic +9497 /uni0055.italic +9498 /uni0056.italic +9499 /uni0057.italic +9500 /uni0058.italic +9501 /uni0059.italic +9502 /uni005A.italic +9503 /uni005B.italic +9504 /uni00A5.italic +9505 /uni005D.italic +9506 /uni005E.italic +9507 /uni005F.italic +9508 /uni0060.italic +9509 /uni0061.italic +9510 /uni0062.italic +9511 /uni0063.italic +9512 /uni0064.italic +9513 /uni0065.italic +9514 /uni0066.italic +9515 /uni0067.italic +9516 /uni0068.italic +9517 /uni0069.italic +9518 /uni006A.italic +9519 /uni006B.italic +9520 /uni006C.italic +9521 /uni006D.italic +9522 /uni006E.italic +9523 /uni006F.italic +9524 /uni0070.italic +9525 /uni0071.italic +9526 /uni0072.italic +9527 /uni0073.italic +9528 /uni0074.italic +9529 /uni0075.italic +9530 /uni0076.italic +9531 /uni0077.italic +9532 /uni0078.italic +9533 /uni0079.italic +9534 /uni007A.italic +9535 /uni007B.italic +9536 /uni007C.italic +9537 /uni007D.italic +9540 /uni005C.italic +9544 /uni00A1.italic +9545 /uni00A2.italic +9546 /uni00A3.italic +9549 /uni00A7.italic +9550 /uni00A4.italic +9551 /uni201C.italic +9552 /uni00AB.italic +9553 /uni2039.italic +9554 /uni203A.italic +9555 /uniFB01.italic +9556 /uniFB02.italic +9558 /uni2020.italic +9559 /uni2021.italic +9560 /uni00B7.italic +9561 /uni00B6.italic +9562 /uni2022.italic +9563 /uni201A.italic +9564 /uni201E.italic +9565 /uni201D.italic +9566 /uni00BB.italic +9567 /uni2026.italic +9568 /uni2030.italic +9569 /uni00BF.italic +9570 /uni02CA.italic +9571 /uni02C6.italic +9572 /uni00AF.italic +9573 /uni02D8.italic +9574 /uni02D9.italic +9575 /uni00A8.italic +9576 /uni02DA.italic +9577 /uni00B8.italic +9578 /uni02DD.italic +9579 /uni02DB.italic +9580 /uni02C7.italic +9581 /uni2014.italic +9582 /uni00C6.italic +9583 /uni00AA.italic +9584 /uni0141.italic +9585 /uni00D8.italic +9586 /uni0152.italic +9587 /uni00BA.italic +9588 /uni00E6.italic +9589 /uni0131.italic +9590 /uni0142.italic +9591 /uni00F8.italic +9592 /uni0153.italic +9593 /uni00DF.italic +9595 /uni00A9.italic +9596 /uni00AC.italic +9597 /uni00AE.italic +9598 /uni00B0.italic +9599 /uni00B1.italic +9600 /uni00B2.italic +9601 /uni00B3.italic +9602 /uni00B5.italic +9603 /uni00B9.italic +9604 /uni00BC.italic +9605 /uni00BD.italic +9606 /uni00BE.italic +9607 /uni00C0.italic +9608 /uni00C1.italic +9609 /uni00C2.italic +9610 /uni00C3.italic +9611 /uni00C4.italic +9612 /uni00C5.italic +9613 /uni00C7.italic +9614 /uni00C8.italic +9615 /uni00C9.italic +9616 /uni00CA.italic +9617 /uni00CB.italic +9618 /uni00CC.italic +9619 /uni00CD.italic +9620 /uni00CE.italic +9621 /uni00CF.italic +9622 /uni00D0.italic +9623 /uni00D1.italic +9624 /uni00D2.italic +9625 /uni00D3.italic +9626 /uni00D4.italic +9627 /uni00D5.italic +9628 /uni00D6.italic +9629 /uni00D7.italic +9630 /uni00D9.italic +9631 /uni00DA.italic +9632 /uni00DB.italic +9633 /uni00DC.italic +9634 /uni00DD.italic +9635 /uni00DE.italic +9636 /uni00DF.italic +9637 /uni00E0.italic +9638 /uni00E1.italic +9639 /uni00E2.italic +9640 /uni00E3.italic +9641 /uni00E4.italic +9642 /uni00E7.italic +9643 /uni00E8.italic +9644 /uni00E9.italic +9645 /uni00EA.italic +9646 /uni00EB.italic +9647 /uni00EC.italic +9648 /uni00ED.italic +9649 /uni00EE.italic +9650 /uni00EF.italic +9651 /uni00F0.italic +9652 /uni00F1.italic +9653 /uni00F2.italic +9654 /uni00F3.italic +9655 /uni00F4.italic +9656 /uni00F5.italic +9657 /uni00F6.italic +9658 /uni00F7.italic +9659 /uni00F9.italic +9660 /uni00FA.italic +9661 /uni00FB.italic +9662 /uni00FC.italic +9663 /uni00FD.italic +9664 /uni00FE.italic +9665 /uni00FF.italic +9666 /uni0160.italic +9667 /uni0178.italic +9668 /uni017D.italic +9670 /uni0160.italic +9671 /uni2122.italic +9672 /uni017E.italic +9673 /uni00D8.italic +9674 /uni20AC.italic +9675 /uni2126.italic +9676 /uni2032.italic +9677 /uni2033.italic +9678 /uniFB00.italic +9679 /uniFB03.italic +9680 /uniFB04.italic +9681 /uni0101.italic +9682 /uni012B.italic +9683 /uni016B.italic +9684 /uni0113.italic +9685 /uni014D.italic +9686 /uni0100.italic +9687 /uni012A.italic +9688 /uni016A.italic +9689 /uni0112.italic +9690 /uni014C.italic +9691 /uni2158.italic +9692 /uni2159.italic +9693 /uni215A.italic +9694 /uni215B.italic +9695 /uni2153.italic +9696 /uni2154.italic +9697 /uni2070.italic +9698 /uni2074.italic +9699 /uni2075.italic +9700 /uni2076.italic +9701 /uni2077.italic +9702 /uni2078.italic +9703 /uni2079.italic +9704 /uni2080.italic +9705 /uni2081.italic +9706 /uni2082.italic +9707 /uni2083.italic +9708 /uni2084.italic +9709 /uni2085.italic +9710 /uni2086.italic +9711 /uni2087.italic +9712 /uni2088.italic +9713 /uni2089.italic +9714 /uni01CD.italic +9715 /uni011A.italic +9717 /uni1EBC.italic +9718 /uni01CF.italic +9721 /uni01D1.italic +9723 /uni01D3.italic +9724 /uni016E.italic +9725 /uni0168.italic +9726 /uni01CE.italic +9727 /uni011B.italic +9729 /uni1EBD.italic +9730 /uni01D0.italic +9733 /uni01D2.italic +9735 /uni01D4.italic +9736 /uni016F.italic +9737 /uni0169.italic +9785..9789 2156 +10126..10135 3220 +10244..10247 325c +10248..10262 32b1 +10313..10338 24d0 +10339..10364 24b6 +10413..10459 32d0 +10461..10470 3280 +10471 3290 +10472..10477 328a +10479 329f +10486..10487 32a0 +10488 329b +10489 329a +10490 32a3 +10491 32a2 +10492 3297 +10494 329c +10495 3295 +10502 25cc +10503 24ff +10514 277f +10515..10524 24eb +11035 20de +11851 33da +11855 2100 +11856 33c2 +11859 2105 +11861 3371 +11864 338d +11865 339b +11869..11870 33d7 +11874..11875 3301 +11876 3304 +11877 3306 +11879 3308 +11881 3307 +11882 330a +11884 3309 +11886 330b +11888 330c +11889..11894 330e +11896 3317 +11898 3319 +11900..11903 331a +11904..11906 331f +11907 3324 +11909 3325 +11912..11913 3328 +11915 332d +11918..11920 332e +11921 3332 +11924..11925 3334 +11926 333c +11930 3337 +11932 3338 +11933 333a +11934 333d +11935 3341 +11936..11938 333e +11939..11942 3343 +11943 3348 +11944..11945 334b +11946..11947 334f +11950 3352 +11951 3354 +11954 3353 +11955..11956 3355 +11958 /Japan1.11874.vert +11959 /Japan1.11875.vert +11960 /Japan1.11876.vert +11961 /Japan1.11877.vert +11963 /Japan1.11879.vert +11965 /Japan1.11881.vert +11966 /Japan1.11882.vert +11968 /Japan1.11884.vert +11970 /Japan1.11886.vert +11972 /Japan1.11888.vert +11973 /Japan1.11889.vert +11974 /Japan1.11890.vert +11975 /Japan1.11891.vert +11976 /Japan1.11892.vert +11977 /Japan1.11893.vert +11978 /Japan1.11894.vert +11980 /Japan1.11896.vert +11982 /Japan1.11898.vert +11984 /Japan1.11900.vert +11985 /Japan1.11901.vert +11986 /Japan1.11902.vert +11987 /Japan1.11903.vert +11988 /Japan1.11904.vert +11989 /Japan1.11905.vert +11990 /Japan1.11906.vert +11991 /Japan1.11907.vert +11993 /Japan1.11909.vert +11996 /Japan1.11912.vert +11997 /Japan1.11913.vert +11999 /Japan1.11915.vert +12002 /Japan1.11918.vert +12003 /Japan1.11919.vert +12004 /Japan1.11920.vert +12005 /Japan1.11921.vert +12008 /Japan1.11924.vert +12009 /Japan1.11925.vert +12010 /Japan1.11926.vert +12014 /Japan1.11930.vert +12016 /Japan1.11932.vert +12017 /Japan1.11933.vert +12018 /Japan1.11934.vert +12019 /Japan1.11935.vert +12020 /Japan1.11936.vert +12021 /Japan1.11937.vert +12022 /Japan1.11938.vert +12023 /Japan1.11939.vert +12024 /Japan1.11940.vert +12025 /Japan1.11941.vert +12026 /Japan1.11942.vert +12027 /Japan1.11943.vert +12028 /Japan1.11944.vert +12029 /Japan1.11945.vert +12030 /Japan1.11946.vert +12031 /Japan1.11947.vert +12034 /Japan1.11950.vert +12035 /Japan1.11951.vert +12038 /Japan1.11954.vert +12039 /Japan1.11955.vert +12040 /Japan1.11956.vert +12089 2135 +12090 03d0 +12091 220a +12092 210f +12094 03d5 +12095 03db +12096 03d1 +12098..12099 2668 +12100 266c +12106 303b +12107 /Japan1.12106.vert +12108..12110 3033 +12111 203c +12112 2049 +12116 244a +12118 2213 +12120 2243 +12121..12122 2272 +12129..12130 3018 +12131..12132 ff5f +12139 /Japan1.12129.vert +12140 /Japan1.12130.vert +12141 /Japan1.12131.vert +12142 /Japan1.12132.vert +12143 239b +12144..12145 239d +12146 23a0 +12147 /Japan1.12144.vert +12148 /Japan1.12143.vert +12149 /Japan1.12146.vert +12150 /Japan1.12145.vert +12151 23a1 +12152..12153 23a3 +12154 23a6 +12155 /Japan1.12152.vert +12156 /Japan1.12151.vert +12157 /Japan1.12154.vert +12158 /Japan1.12153.vert +12167 239c +12168 /Japan1.12167.vert +12176 2702 +12178 /Japan1.12176.vert +12179 303d +12181 309f +12184 2205 +12185 22a0 +12186 2296 +12187 2298 +12188 2295 +12189 2297 +12190 229e +12192 26a0 +12194 25c0 +12195 25b6 +12200 21d0 +12201 2194 +12202..12203 2198 +12204..12205 2196 +12206 21cc +12207 21cb +12214 /Japan1.12215.vert +12215 2195 +12218 3030 +12219 2307 +12228 2740 +12229 273f +12237 25ab +12239 25aa +12241 271a +12254 25e6 +12259 2756 +12639..12640 fe45 +12870 /Japan1.9354.vert +12871 /Japan1.9355.vert +12872 /Japan1.9356.vert +12873 /Japan1.9357.vert +12874 /Japan1.9358.vert +12875 /Japan1.9359.vert +12876 /Japan1.9360.vert +12877 /Japan1.9361.vert +12878 /Japan1.9362.vert +12879 /Japan1.9363.vert +12880 /Japan1.9364.vert +12881 /Japan1.9365.vert +12882 /Japan1.9366.vert +12883 /Japan1.9367.vert +12884 /Japan1.9368.vert +12885 /Japan1.9369.vert +12886 /Japan1.9370.vert +12887 /Japan1.9371.vert +12888 /Japan1.9372.vert +12889 /Japan1.9373.vert +12890 /Japan1.9374.vert +12891 /Japan1.9375.vert +12892 /Japan1.9376.vert +12893 /Japan1.9377.vert +12894 /Japan1.9378.vert +12895 /Japan1.9379.vert +12896 /Japan1.9380.vert +12897 /Japan1.9381.vert +12898 /Japan1.9382.vert +12899 /Japan1.9383.vert +12900 /Japan1.9384.vert +12901 /Japan1.9385.vert +12902 /Japan1.9386.vert +12903 /Japan1.9387.vert +12904 /Japan1.9388.vert +12905 /Japan1.9389.vert +12906 /Japan1.9390.vert +12907 /Japan1.9391.vert +12908 /Japan1.9392.vert +12909 /Japan1.9393.vert +12910 /Japan1.9394.vert +12911 /Japan1.9395.vert +12912 /Japan1.9396.vert +12913 /Japan1.9397.vert +12914 /Japan1.9398.vert +12915 /Japan1.9399.vert +12916 /Japan1.9400.vert +12917 /Japan1.9401.vert +12918 /Japan1.9402.vert +12919 /Japan1.9403.vert +12920 /Japan1.9404.vert +12921 /Japan1.9405.vert +12922 /Japan1.9406.vert +12923 /Japan1.9407.vert +12924 /Japan1.9408.vert +12925 /Japan1.9409.vert +12926 /Japan1.9410.vert +12927 /Japan1.9411.vert +12928 /Japan1.9412.vert +12929 /Japan1.9413.vert +12930 /Japan1.9414.vert +12931 /Japan1.9415.vert +12932 /Japan1.9416.vert +12933 /Japan1.9417.vert +12934 /Japan1.9418.vert +12935 /Japan1.9419.vert +12936 /Japan1.9420.vert +12937 /Japan1.9421.vert +12938 /Japan1.9422.vert +12939 /Japan1.9423.vert +12940 /Japan1.9424.vert +12941 /Japan1.9425.vert +12942 /Japan1.9426.vert +12943 /Japan1.9427.vert +12944 /Japan1.9428.vert +12945 /Japan1.9429.vert +12946 /Japan1.9430.vert +12947 /Japan1.9431.vert +12948 /Japan1.9432.vert +12949 /Japan1.9433.vert +12950 /Japan1.9434.vert +12951 /Japan1.9435.vert +12952 /Japan1.9436.vert +12953 /Japan1.9437.vert +12954 /Japan1.9438.vert +12955 /Japan1.9439.vert +12956 /Japan1.9440.vert +12957 /Japan1.9441.vert +12958 /Japan1.9442.vert +12959 /Japan1.9443.vert +12960 /Japan1.9444.vert +12961 /Japan1.9445.vert +12962 /Japan1.9446.vert +12963 /Japan1.9447.vert +12964 /Japan1.9448.vert +12965 /Japan1.9449.vert +12966 /Japan1.9450.vert +12967 /Japan1.9451.vert +12968 /Japan1.9452.vert +12969 /Japan1.9453.vert +12970 /Japan1.9454.vert +12971 /Japan1.9455.vert +12972 /Japan1.9456.vert +12973 /Japan1.9457.vert +12974 /Japan1.9458.vert +12975 /Japan1.9459.vert +12976 /Japan1.9460.vert +12977 /Japan1.9461.vert +12978 /Japan1.9462.vert +12979 /Japan1.9463.vert +12980 /Japan1.9464.vert +12981 /Japan1.9465.vert +12982 /Japan1.9466.vert +12983 /Japan1.9467.vert +12984 /Japan1.9468.vert +12985 /Japan1.9469.vert +12986 /Japan1.9470.vert +12987 /Japan1.9471.vert +12988 /Japan1.9472.vert +12989 /Japan1.9473.vert +12990 /Japan1.9474.vert +12991 /Japan1.9475.vert +12992 /Japan1.9476.vert +12993 /Japan1.9477.vert +12994 /Japan1.9478.vert +12995 /Japan1.9479.vert +12996 /Japan1.9480.vert +12997 /Japan1.9481.vert +12998 /Japan1.9482.vert +12999 /Japan1.9483.vert +13000 /Japan1.9484.vert +13001 /Japan1.9485.vert +13002 /Japan1.9486.vert +13003 /Japan1.9487.vert +13004 /Japan1.9488.vert +13005 /Japan1.9489.vert +13006 /Japan1.9490.vert +13007 /Japan1.9491.vert +13008 /Japan1.9492.vert +13009 /Japan1.9493.vert +13010 /Japan1.9494.vert +13011 /Japan1.9495.vert +13012 /Japan1.9496.vert +13013 /Japan1.9497.vert +13014 /Japan1.9498.vert +13015 /Japan1.9499.vert +13016 /Japan1.9500.vert +13017 /Japan1.9501.vert +13018 /Japan1.9502.vert +13019 /Japan1.9503.vert +13020 /Japan1.9504.vert +13021 /Japan1.9505.vert +13022 /Japan1.9506.vert +13023 /Japan1.9507.vert +13024 /Japan1.9508.vert +13025 /Japan1.9509.vert +13026 /Japan1.9510.vert +13027 /Japan1.9511.vert +13028 /Japan1.9512.vert +13029 /Japan1.9513.vert +13030 /Japan1.9514.vert +13031 /Japan1.9515.vert +13032 /Japan1.9516.vert +13033 /Japan1.9517.vert +13034 /Japan1.9518.vert +13035 /Japan1.9519.vert +13036 /Japan1.9520.vert +13037 /Japan1.9521.vert +13038 /Japan1.9522.vert +13039 /Japan1.9523.vert +13040 /Japan1.9524.vert +13041 /Japan1.9525.vert +13042 /Japan1.9526.vert +13043 /Japan1.9527.vert +13044 /Japan1.9528.vert +13045 /Japan1.9529.vert +13046 /Japan1.9530.vert +13047 /Japan1.9531.vert +13048 /Japan1.9532.vert +13049 /Japan1.9533.vert +13050 /Japan1.9534.vert +13051 /Japan1.9535.vert +13052 /Japan1.9536.vert +13053 /Japan1.9537.vert +13054 /Japan1.9538.vert +13055 /Japan1.9539.vert +13056 /Japan1.9540.vert +13057 /Japan1.9541.vert +13058 /Japan1.9542.vert +13059 /Japan1.9543.vert +13060 /Japan1.9544.vert +13061 /Japan1.9545.vert +13062 /Japan1.9546.vert +13063 /Japan1.9547.vert +13064 /Japan1.9548.vert +13065 /Japan1.9549.vert +13066 /Japan1.9550.vert +13067 /Japan1.9551.vert +13068 /Japan1.9552.vert +13069 /Japan1.9553.vert +13070 /Japan1.9554.vert +13071 /Japan1.9555.vert +13072 /Japan1.9556.vert +13073 /Japan1.9557.vert +13074 /Japan1.9558.vert +13075 /Japan1.9559.vert +13076 /Japan1.9560.vert +13077 /Japan1.9561.vert +13078 /Japan1.9562.vert +13079 /Japan1.9563.vert +13080 /Japan1.9564.vert +13081 /Japan1.9565.vert +13082 /Japan1.9566.vert +13083 /Japan1.9567.vert +13084 /Japan1.9568.vert +13085 /Japan1.9569.vert +13086 /Japan1.9570.vert +13087 /Japan1.9571.vert +13088 /Japan1.9572.vert +13089 /Japan1.9573.vert +13090 /Japan1.9574.vert +13091 /Japan1.9575.vert +13092 /Japan1.9576.vert +13093 /Japan1.9577.vert +13094 /Japan1.9578.vert +13095 /Japan1.9579.vert +13096 /Japan1.9580.vert +13097 /Japan1.9581.vert +13098 /Japan1.9582.vert +13099 /Japan1.9583.vert +13100 /Japan1.9584.vert +13101 /Japan1.9585.vert +13102 /Japan1.9586.vert +13103 /Japan1.9587.vert +13104 /Japan1.9588.vert +13105 /Japan1.9589.vert +13106 /Japan1.9590.vert +13107 /Japan1.9591.vert +13108 /Japan1.9592.vert +13109 /Japan1.9593.vert +13110 /Japan1.9594.vert +13111 /Japan1.9595.vert +13112 /Japan1.9596.vert +13113 /Japan1.9597.vert +13114 /Japan1.9598.vert +13115 /Japan1.9599.vert +13116 /Japan1.9600.vert +13117 /Japan1.9601.vert +13118 /Japan1.9602.vert +13119 /Japan1.9603.vert +13120 /Japan1.9604.vert +13121 /Japan1.9605.vert +13122 /Japan1.9606.vert +13123 /Japan1.9607.vert +13124 /Japan1.9608.vert +13125 /Japan1.9609.vert +13126 /Japan1.9610.vert +13127 /Japan1.9611.vert +13128 /Japan1.9612.vert +13129 /Japan1.9613.vert +13130 /Japan1.9614.vert +13131 /Japan1.9615.vert +13132 /Japan1.9616.vert +13133 /Japan1.9617.vert +13134 /Japan1.9618.vert +13135 /Japan1.9619.vert +13136 /Japan1.9620.vert +13137 /Japan1.9621.vert +13138 /Japan1.9622.vert +13139 /Japan1.9623.vert +13140 /Japan1.9624.vert +13141 /Japan1.9625.vert +13142 /Japan1.9626.vert +13143 /Japan1.9627.vert +13144 /Japan1.9628.vert +13145 /Japan1.9629.vert +13146 /Japan1.9630.vert +13147 /Japan1.9631.vert +13148 /Japan1.9632.vert +13149 /Japan1.9633.vert +13150 /Japan1.9634.vert +13151 /Japan1.9635.vert +13152 /Japan1.9636.vert +13153 /Japan1.9637.vert +13154 /Japan1.9638.vert +13155 /Japan1.9639.vert +13156 /Japan1.9640.vert +13157 /Japan1.9641.vert +13158 /Japan1.9642.vert +13159 /Japan1.9643.vert +13160 /Japan1.9644.vert +13161 /Japan1.9645.vert +13162 /Japan1.9646.vert +13163 /Japan1.9647.vert +13164 /Japan1.9648.vert +13165 /Japan1.9649.vert +13166 /Japan1.9650.vert +13167 /Japan1.9651.vert +13168 /Japan1.9652.vert +13169 /Japan1.9653.vert +13170 /Japan1.9654.vert +13171 /Japan1.9655.vert +13172 /Japan1.9656.vert +13173 /Japan1.9657.vert +13174 /Japan1.9658.vert +13175 /Japan1.9659.vert +13176 /Japan1.9660.vert +13177 /Japan1.9661.vert +13178 /Japan1.9662.vert +13179 /Japan1.9663.vert +13180 /Japan1.9664.vert +13181 /Japan1.9665.vert +13182 /Japan1.9666.vert +13183 /Japan1.9667.vert +13184 /Japan1.9668.vert +13185 /Japan1.9669.vert +13186 /Japan1.9670.vert +13187 /Japan1.9671.vert +13188 /Japan1.9672.vert +13189 /Japan1.9673.vert +13190 /Japan1.9674.vert +13191 /Japan1.9675.vert +13192 /Japan1.9676.vert +13193 /Japan1.9677.vert +13194 /Japan1.9678.vert +13195 /Japan1.9679.vert +13196 /Japan1.9680.vert +13197 /Japan1.9681.vert +13198 /Japan1.9682.vert +13199 /Japan1.9683.vert +13200 /Japan1.9684.vert +13201 /Japan1.9685.vert +13202 /Japan1.9686.vert +13203 /Japan1.9687.vert +13204 /Japan1.9688.vert +13205 /Japan1.9689.vert +13206 /Japan1.9690.vert +13207 /Japan1.9691.vert +13208 /Japan1.9692.vert +13209 /Japan1.9693.vert +13210 /Japan1.9694.vert +13211 /Japan1.9695.vert +13212 /Japan1.9696.vert +13213 /Japan1.9697.vert +13214 /Japan1.9698.vert +13215 /Japan1.9699.vert +13216 /Japan1.9700.vert +13217 /Japan1.9701.vert +13218 /Japan1.9702.vert +13219 /Japan1.9703.vert +13220 /Japan1.9704.vert +13221 /Japan1.9705.vert +13222 /Japan1.9706.vert +13223 /Japan1.9707.vert +13224 /Japan1.9708.vert +13225 /Japan1.9709.vert +13226 /Japan1.9710.vert +13227 /Japan1.9711.vert +13228 /Japan1.9712.vert +13229 /Japan1.9713.vert +13230 /Japan1.9714.vert +13231 /Japan1.9715.vert +13232 /Japan1.9716.vert +13233 /Japan1.9717.vert +13234 /Japan1.9718.vert +13235 /Japan1.9719.vert +13236 /Japan1.9720.vert +13237 /Japan1.9721.vert +13238 /Japan1.9722.vert +13239 /Japan1.9723.vert +13240 /Japan1.9724.vert +13241 /Japan1.9725.vert +13242 /Japan1.9726.vert +13243 /Japan1.9727.vert +13244 /Japan1.9728.vert +13245 /Japan1.9729.vert +13246 /Japan1.9730.vert +13247 /Japan1.9731.vert +13248 /Japan1.9732.vert +13249 /Japan1.9733.vert +13250 /Japan1.9734.vert +13251 /Japan1.9735.vert +13252 /Japan1.9736.vert +13253 /Japan1.9737.vert +13254 /Japan1.9738.vert +13255 /Japan1.9739.vert +13256 /Japan1.9740.vert +13257 /Japan1.9741.vert +13258 /Japan1.9742.vert +13259 /Japan1.9743.vert +13260 /Japan1.9744.vert +13261 /Japan1.9745.vert +13262 /Japan1.9746.vert +13263 /Japan1.9747.vert +13264 /Japan1.9748.vert +13265 /Japan1.9749.vert +13266 /Japan1.9750.vert +13267 /Japan1.9751.vert +13268 /Japan1.9752.vert +13269 /Japan1.9753.vert +13270 /Japan1.9754.vert +13271 /Japan1.9755.vert +13272 /Japan1.9756.vert +13273 /Japan1.9757.vert +13274 /Japan1.9758.vert +13275 /Japan1.9759.vert +13276 /Japan1.9760.vert +13277 /Japan1.9761.vert +13278 /Japan1.9762.vert +13279 /Japan1.9763.vert +13280 /Japan1.9764.vert +13281 /Japan1.9765.vert +13282 /Japan1.9766.vert +13283 /Japan1.9767.vert +13284 /Japan1.9768.vert +13285 /Japan1.9769.vert +13286 /Japan1.9770.vert +13287 /Japan1.9771.vert +13288 /Japan1.9772.vert +13289 /Japan1.9773.vert +13290 /Japan1.9774.vert +13291 /Japan1.9775.vert +13292 /Japan1.9776.vert +13293 /Japan1.9777.vert +13294 /Japan1.9778.vert +13320 fa67 +13321 fa62 +13322 7de3 +13323 9ec3 +13324 6eab +13325 fa52 +13326 fa3d +13327 fa45 +13328 fa3e +13329 69ea +13330 6e34 +13331 fa60 +13332 fa47 +13333 fa38 +13334 fa42 +13335 fa4e +13336 865b +13337 fa69 +13338 fa34 +13339 fa63 +13340 63ed +13341 64ca +13342 784f +13343 fa54 +13344 f970 +13345 fa4d +13346 fa61 +13347 fa48 +13348 fa4c +13349..13350 fa5b +13351 fa51 +13352 fa43 +13353 fa5a +13354 6d89 +13355 72c0 +13357 2f945 +13358 fa56 +13359 fa50 +13360 fa31 +13361 fa3b +13362 5de2 +13363 fa3f +13364 fa65 +13365 537d +13366 fa37 +13367 fa5f +13368 5fb5 +13369 fa40 +13371 fa53 +13372 9b2d +13373 fa55 +13374 fa68 +13375 fa44 +13376 fa59 +13377 665a +13378 fa35 +13379 fa4b +13380 fa64 +13381 fa41 +13382 fa30 +13383 5002 +13384 fa39 +13385 fa33 +13386 6b65 +13387 fa3a +13388 6bcf +13389 fa32 +13390 623e +13391 fa4f +13392 f91d +13393 /uniF9DC.dup2 +13394 f936 +13395 6dda +13396 f9d0 +13397 66c6 +13398 6b77 +13399 fa57 +13400 934a +13402 9304 +13523 2090e +13644 8c9f +13645 2ed7 +13646 26951 +13652 92b3 +13653 95b1 +13656 2f8fc +13670 2f995 +13679 2f8ea +13681 676e +13682 2ec6 +13684 2f822 +13698 3402 +13701 65e3 +13706 20bb7 +13717 29d4b +13719 2f833 +13720 5f3a +13729 2ea9 +13731 4ff1 +13739 f909 +13747 2ebc +13750 2f8ac +13751 6743 +13755 20a64 +13756 8a01 +13757 6236 +13760 5433 +13761 5a1b +13765 6285 +13768 2f903 +13775 543f +13785 6b72 +13790 7522 +13791 4b38 +13794 5dff +13801 2f90b +13802 73ba +13803 20b9f +13807 2f828 +13809 2f921 +13815 2f83f +13832 2f873 +13833..13834 2e8c +13835 5c19 +13839 2000b +13840 5b82 +13841 2f852 +13847 2edd +13848 98e0 +13849 2967f +13850 378d +13852 38fa +13854 2f947 +13856 4ebb +13857 201a2 +13865 351f +13867 2f8b2 +13870 8980 +13875 7a05 +13880 8aaa +13882 7d55 +13884 6f98 +13892 63f7 +13893 /uni7626.dup2 +13898 27fb7 +13904 23cfe +13910 3427 +13913 812b +13916 2f91a +13922 2eae +13928 2f89a +13932 2f90f +13952 5721 +13953 2123d +13954 2f81a +13956 fa03 +13964 541e +13965 3b88 +13966 5167 +13971 f95f +13981 4e37 +13995 24d14 +13996 5f65 +13997 59ec +13998 2f862 +14000 5e99 +14047 3468 +14056 52d0 +14066 /uni6801.dup2 +14068 2f9d0 +14069 2f9df +14075 2567f +14078 2eb7 +14083 8eb6 +14084 f91f +14088 f983 +14094 7c7b +14095 f9a2 +14097 f99a +14099 8002 +14100 266b0 +14105 20628 +14108 2008a +14109 2f82c +14110 353e +14115 5455 +14117 5939 +14120 5b76 +14121 2f86d +14122 5c14 +14123 37e2 +14124 5ce6 +14126 4e48 +14129 2f8b6 +14134 26999 +14135 631b +14138 6663 +14140 2f8db +14143 69f6 +14144 6986 +14148 6bcc +14150 6e17 +14153 6caa +14157 4e2c +14160 74ef +14161 7575 +14162 75ec +14163 764e +14164 3fb1 +14165 776a +14166 77a9 +14173 7b53 +14176 4264 +14180 2f96c +14183 7e48 +14189 2eb3 +14194 8141 +14195 4453 +14197 8279 +14198 fa5e +14199 fa5d +14201 5179 +14202 835a +14206 4525 +14208 85f4 +14209 200b0 +14214 867d +14216 342e +14217 88c6 +14224 47e6 +14233 8fc8 +14253 28987 +14256 28e17 +14259 9839 +14266 9a08 +14271 9bdf +14282 242ee +14288 5389 +14290 /uniFA11.dup2 +14291 2f8e1 +14293 23cbe +14294 20611 +14296..14297 4e04 +14298 4e1f +14299 4e2b +14300..14301 4e2f +14302..14303 4e40 +14304 4e44 +14305 4e5a +14306 4e7f +14307 4e8d +14308 4e96 +14309 4eb9 +14310 4ed0 +14311 4ee0 +14312 4efd +14313 4eff +14314 4f0b +14315 4f15 +14316 4f60 +14317 4f3b +14318 4f49 +14319 4f54 +14320 4f7a +14321..14322 4f7d +14323 4f97 +14324 4fbe +14325 4fcf +14326 4ffd +14327..14328 5000 +14329 5010 +14330 501b +14331 5027 +14332 502e +14333 5057 +14334 5066 +14335 506a +14336 503b +14337 508f +14338 5096 +14339 509c +14340 50cc +14341 50e6 +14342 50e9 +14343 50ef +14344 5108 +14345 510b +14346 5110 +14347 511b +14348 511e +14349 515f +14350 51a1 +14351 51bc +14352 51de +14353 51ee +14354 51f4 +14355..14356 5201 +14357 5213 +14358 5249 +14359 5261 +14360 5266 +14361 5293 +14362 52c8 +14363 52f0 +14364..14365 530a +14366 533e +14367 534c +14368 534b +14369 5361 +14370 536c +14371 53ab +14372 53da +14373 53e6 +14374 53f5 +14375 5427 +14376 544d +14377 5466 +14378 546b +14379 5474 +14380 548d +14381 5496 +14382 54a1 +14383 54ad +14384 54b9 +14385 54bf +14386 54c6 +14387 54cd +14388 550e +14389 552b +14390 5535 +14391 554a +14392..14393 5560 +14394 5588 +14395 558e +14396 5608 +14397..14398 560e +14399 5637 +14400 563f +14401 5649 +14402 564b +14403 564f +14404 5666 +14405 5669 +14406 566f +14407..14408 5671 +14409 5695 +14410 569a +14411..14412 56ac +14413 56b1 +14414 56c9 +14415 56dd +14416 56e4 +14417 570a +14418 5715 +14419 5723 +14420 572f +14421..14422 5733 +14423 574c +14424 5770 +14425 578c +14426 579c +14427 57b8 +14428 57e6 +14429 57ed +14430..14431 57f5 +14432 57ff +14433 5809 +14434 5820 +14435 5832 +14436 587c +14437 5880 +14438 58a9 +14439 58ce +14440 58d0 +14441 58d4 +14442 58da +14443 58e9 +14444 590c +14445 5924 +14446 592f +14447 5961 +14448 596d +14449 59ca +14450 59d2 +14451 59dd +14452..14453 59e3 +14454 5a04 +14455 5a0c +14456 5a23 +14457 5a47 +14458 5a55 +14459 5a63 +14460 5a6d +14461 5a7e +14462 5a9e +14463 5aa7 +14464 5aac +14465 5ab3 +14466 5ae0 +14467 5b00 +14468 5b19 +14469 5b25 +14470 5b2d +14471 5b41 +14472 5b7c +14473..14474 5b7e +14475 5b8a +14476 5c23 +14477 5c2b +14478 5c30 +14479 5c63 +14480 5c69 +14481 5c7c +14482 5ccb +14483 5cd2 +14484 5cf4 +14485 5d24 +14486 5d26 +14487 5d43 +14488 5d46 +14489 5d4a +14490 5d92 +14491 5d94 +14492 5d99 +14493 5da0 +14494 5dd8 +14495 5de0 +14496 5df8 +14497 5e00 +14498 5e12 +14499..14500 5e14 +14501 5e18 +14502 5e2e +14503 5e58 +14504..14505 5e6b +14506 5ea8 +14507 5eaa +14508..14509 5ebe +14510 5ecb +14511 5ed2 +14512 5f07 +14513 5f0e +14514..14515 5f1c +14516 5f22 +14517 5f28 +14518 5f36 +14519 5f3b +14520 5f40 +14521 5f50 +14522 5f58 +14523 5f64 +14524 5f89 +14525 5f9c +14526 5fa7 +14527 5fa4 +14528 5faf +14529 5fb8 +14530 5fc4 +14531 5fc9 +14532 5fe1 +14533 5fe9 +14534 5fed +14535 5ffc +14536 6017 +14537 601a +14538 6033 +14539 6061 +14540 607f +14541 609e +14542 60a4 +14543 60b0 +14544 60cb +14545 60db +14546 60f8 +14547..14549 6112 +14550 611c +14551 617c +14552 618d +14553 619f +14554 61a8 +14555 61c2 +14556 61df +14557 6215 +14558 6229 +14559 6243 +14560 6246 +14561 624c +14562 6251 +14563 6256 +14564 62c4 +14565 62fc +14566 630a +14567 630d +14568 6318 +14569 6339 +14570..14571 6342 +14572 6365 +14573 6374 +14574 637d +14575 6384 +14576 6387 +14577 6390 +14578 639e +14579 63d1 +14580 63dc +14581 6409 +14582 6410 +14583 6422 +14584 6454 +14585 645b +14586 646d +14587 647b +14588..14589 64be +14590 64e5 +14591 64f7 +14592 64fb +14593 6504 +14594 6516 +14595 6519 +14596 6547 +14597 6567 +14598 6581 +14599 6585 +14600 65c2 +14601 65f0 +14602 65f2 +14603 662c +14604 664c +14605..14606 665b +14607 6661 +14608 666b +14609 6677 +14610 66a4 +14611 66c8 +14612 66ec +14613 6705 +14614 6713 +14615 6733 +14616 6748 +14617 674c +14618 6776 +14619 677b +14620 67b0 +14621 67b2 +14622 67f9 +14623 67d7 +14624 67d9 +14625 67f0 +14626 682c +14627..14628 6830 +14629 685b +14630 6872 +14631 6875 +14632 687a +14633 6884 +14634 68a5 +14635 68b2 +14636 68d0 +14637 68d6 +14638 68e8 +14639 68ed +14640..14641 68f0 +14642 68fc +14643 6911 +14644 6913 +14645 6935 +14646 693b +14647 6957 +14648 6963 +14649 6972 +14650..14651 697f +14652 69a6 +14653 69ad +14654 69b7 +14655..14656 69d6 +14657 6a01 +14658 6a0f +14659 6a15 +14660 6a28 +14661 6a34 +14662 6a3e +14663 6a45 +14664..14665 6a50 +14666 6a56 +14667 6a5b +14668 6a83 +14669 6a89 +14670 6a91 +14671..14673 6a9d +14674 6adc +14675 6ae7 +14676 6aec +14677 6b1e +14678 6b24 +14679 6b35 +14680 6b46 +14681 6b56 +14682 6b60 +14683 6b82 +14684 6bbe +14685 6be1 +14686 6bf1 +14687 6c10 +14688 6c33 +14689 6c35 +14690 2ea2 +14691 6c59 +14692 6c76 +14693 6c7b +14694 6c85 +14695 6c95 +14696 6c9c +14697 6cd0 +14698 6cd4 +14699 6cd6 +14700 6ce0 +14701..14702 6ceb +14703 6cee +14704 6d0a +14705 6d0e +14706 6d11 +14707 6d2e +14708 6d57 +14709 6d5e +14710 6d65 +14711 6d82 +14712 6dbf +14713 6dc4 +14714 6dca +14715 6dd6 +14716 6de9 +14717 6e22 +14718 6e51 +14719 6ec7 +14720 6eca +14721 6ece +14722 6efd +14723 6f1a +14724 6f2a +14725 6f2f +14726 6f33 +14727 6f5a +14728 6f5e +14729 6f62 +14730 6f7d +14731 6f8b +14732 6f8d +14733 6f92 +14734 6f94 +14735 6f9a +14736..14737 6fa7 +14738 6fb6 +14739 6fda +14740 6fde +14741 6ff9 +14742 7039 +14743 703c +14744 704a +14745 7054 +14746..14747 705d +14748 7064 +14749 706c +14750 707e +14751 7081 +14752 7095 +14753 70b7 +14754..14755 70d3 +14756 70d8 +14757 70dc +14758 7107 +14759 7120 +14760 7131 +14761 714a +14762 7152 +14763 7160 +14764 7179 +14765 7192 +14766 71b3 +14767 71cb +14768 71d3 +14769 71d6 +14770 7200 +14771 721d +14772 722b +14773 7238 +14774 7241 +14775 7253 +14776..14777 7255 +14778 725c +14779 728d +14780 72ad +14781 72b4 +14782 72c7 +14783 72fb +14784..14785 7304 +14786 7328 +14787 7331 +14788 7343 +14789 736c +14790 737c +14791 7383 +14792..14793 7385 +14794 7395 +14795..14797 739e +14798 73a6 +14799 73ab +14800 73b5 +14801 73b7 +14802 73bc +14803 73cf +14804 73d9 +14805 73e9 +14806 73f4 +14807 73fd +14808 7404 +14809 740a +14810..14811 741a +14812 7424 +14813 7428 +14814 742c +14815..14817 742f +14818 7439 +14819 7444 +14820 7447 +14821 744b +14822 744d +14823 7451 +14824 7457 +14825 7466 +14826 746b +14827 7471 +14828 7480 +14829..14831 7485 +14832 7490 +14833 7498 +14834 749c +14835 74a0 +14836 74a3 +14837 74a8 +14838 74ab +14839 74b5 +14840 74bf +14841 74c8 +14842 74da +14843 74de +14844 754e +14845 7579 +14846 7581 +14847 7590 +14848..14849 7592 +14850 75b4 +14851 75e4 +14852 75f9 +14853 7600 +14854 760a +14855..14856 7615 +14857 7619 +14858 761e +14859 762d +14860 7635 +14861 7643 +14862 764b +14863 7665 +14864 766d +14865 766f +14866 7671 +14867 7674 +14868..14869 76a4 +14870 76c5 +14871 76cc +14872 76ec +14873 76fc +14874 7734 +14875 7736 +14876 775c +14877..14878 775f +14879 7772 +14880 777d +14881 7795 +14882 77aa +14883 77e6 +14884 77f0 +14885 77f4 +14886 7806 +14887 7822 +14888..14889 782d +14890 7830 +14891 7835 +14892 7868 +14893 789e +14894 78c8 +14895 78cc +14896 78ce +14897 78e4 +14898..14899 78e0 +14900 78f2 +14901 78f7 +14902 78fb +14903 7931 +14904 7934 +14905 793b +14906 793d +14907 7945 +14908..14909 795b +14910 798b +14911 7996 +14912 7998 +14913 79b8 +14914 79bb +14915 79ca +14916 79da +14917 7a03 +14918 7a09 +14919 7a11 +14920 7a1e +14921 7a2d +14922 7a39 +14923 7a45 +14924 7a4c +14925 7a5d +14926 7a60 +14927 7a6d +14928 7a78 +14929 7aa0 +14930 7aa3 +14931 7ab3 +14932..14933 7abb +14934 7ac6 +14935 7b07 +14936 7b14 +14937 7b27 +14938 7b31 +14939 7b47 +14940 7b4e +14941 7b60 +14942 7b69 +14943 7b6d +14944 7b72 +14945 7b91 +14946 7baf +14947 7bd7 +14948 7bd9 +14949 7c0b +14950 7c0f +14951 7c20 +14952 7c26 +14953 7c31 +14954 7c36 +14955 7c51 +14956 7c59 +14957 7c67 +14958 7c6e +14959 7c70 +14960 7cbc +14961 7cbf +14962..14963 7cc8 +14964 7cd7 +14965 7cd9 +14966 7cdd +14967 7ceb +14968..14970 7d07 +14971 7d13 +14972 7d1d +14973 7d23 +14974 7d41 +14975 7d53 +14976 7d59 +14977 7d5d +14978 7d7a +14979 7d86 +14980..14981 7d8b +14982 7dcc +14983 7deb +14984 7df1 +14985 7df9 +14986 7e08 +14987 7e11 +14988 7e15 +14989 7e20 +14990 7e47 +14991 7e62 +14992 7e6e +14993 7e73 +14994 7e8d +14995 7e91 +14996 7e98 +14997 7f44 +14998 7f4f +14999..15000 7f52 +15001 7f61 +15002 7f91 +15003 7fbf +15004 7fce +15005 7fdf +15006 7fe5 +15007 7fec +15008..15009 7fee +15010 7ffa +15011 800e +15012 8011 +15013 8014 +15014 8024 +15015 8026 +15016 803a +15017 803c +15018 8060 +15019 8071 +15020 8075 +15021 809e +15022 80a6 +15023 80ab +15024..15025 80d7 +15026 8116 +15027 8118 +15028 813a +15029 814a +15030 814c +15031 8181 +15032 8184 +15033 81b4 +15034 81cf +15035 81f9 +15036 8203 +15037 8221 +15038 8232 +15039 8234 +15040 8246 +15041 824b +15042 824f +15043 828e +15044 82ae +15045 82b7 +15046 82be +15047 82c6 +15048 82fe +15049 8343 +15050 8351 +15051 8355 +15052 8386 +15053 838d +15054 8392 +15055 8398 +15056 83a9 +15057..15058 83bf +15059 83ea +15060 840f +15061 8411 +15062 844a +15063 8476 +15064 84a8 +15065 84af +15066 84c0 +15067 84c2 +15068 84f0 +15069 84fd +15070 850c +15071 8534 +15072 855e +15073 858f +15074 85b7 +15075 85ce +15076 85ad +15077 8612 +15078 8629 +15079 8652 +15080 8663 +15081 866c +15082 866f +15083 867a +15084 868d +15085 8691 +15086 8698 +15087..15088 86a7 +15089 86fa +15090 86fd +15091 870b +15092 8713 +15093 8719 +15094 871e +15095 8728 +15096 873e +15097 8771 +15098 8788 +15099 8799 +15100..15101 87ac +15102 87b5 +15103 87d6 +15104 87eb +15105 87ed +15106 8801 +15107 8803 +15108 8806 +15109 880b +15110 8814 +15111 881c +15112 8856 +15113 885f +15114 8864 +15115 8898 +15116 88aa +15117..15118 88bd +15119 88ca +15120 88d2 +15121 88db +15122..15123 88f0 +15124 8906 +15125..15127 8918 +15128 8927 +15129 8930 +15130 893e +15131 897b +15132 89d4 +15133 89d6 +15134 89e5 +15135 89f1 +15136 8a07 +15137 8a0f +15138 8a15 +15139 8a22 +15140 8a4e +15141 8a7f +15142 8af4 +15143 8b1f +15144 8b37 +15145..15146 8b43 +15147 8b54 +15148 8b9c +15149 8b9e +15150 8c47 +15151 8c54 +15152 8c73 +15153 8ca4 +15154 8cd9 +15155 8ce1 +15156 8cf8 +15157 8cfe +15158 8d1b +15159 8d69 +15160 8d6c +15161 8d84 +15162 8d8d +15163 8d95 +15164 8da6 +15165 8dc6 +15166 8dce +15167 8de4 +15168 8dec +15169 8e20 +15170 8e4b +15171 8e6c +15172 8e70 +15173 8e7a +15174 8e92 +15175 8eae +15176 8eb3 +15177 8ed1 +15178 8ed4 +15179 8ef9 +15180 8f17 +15181 8f36 +15182 8fa6 +15183..15184 8fb5 +15185 8fc6 +15186 8fe0 +15187 8fe4 +15188 8ff6 +15189 9002 +15190 902c +15191 9044 +15192 9088 +15193 9095 +15194 9099 +15195 909b +15196 90a2 +15197 90b4 +15198 90d7 +15199 90dd +15200 90f4 +15201 9117 +15202 911c +15203 9131 +15204 913a +15205 913d +15206 9148 +15207 915b +15208 9161 +15209 9164 +15210 918e +15211 919e +15212 91a8 +15213..15214 91ad +15215 91b2 +15216 91bc +15217 91f0 +15218 91f7 +15219 91fb +15220 9207 +15221 9228 +15222 9233 +15223 9238 +15224 9243 +15225 9247 +15226 924f +15227 9260 +15228 92c2 +15229..15230 92cb +15231 92df +15232 930d +15233 9315 +15234 931f +15235 9327 +15236 9347 +15237 9352 +15238 9365 +15239 936a +15240 936d +15241 939b +15242 93ba +15243 93a9 +15244 93c1 +15245 93ca +15246 93e2 +15247 93fa +15248 93fd +15249 940f +15250 9434 +15251 943f +15252 9455 +15253 946b +15254 9472 +15255 9578 +15256 95a6 +15257 95a9 +15258 95ab +15259 95b4 +15260 95bd +15261 95da +15262 961d +15263 9641 +15264 9658 +15265 9684 +15266 96a4 +15267 96a9 +15268 96d2 +15269 2f9f4 +15270 96de +15271 96e9 +15272 96f1 +15273 9702 +15274 9709 +15275 975a +15276 9763 +15277 976e +15278 9773 +15279 979a +15280 97a2 +15281..15282 97b5 +15283 97d9 +15284 97de +15285 97f4 +15286 980a +15287 980e +15288 981e +15289 9823 +15290 982b +15291 983e +15292..15293 9852 +15294 9859 +15295 986c +15296 98b8 +15297 98ba +15298 98bf +15299 98c8 +15300 98e5 +15301..15302 9932 +15303 9940 +15304 994d +15305 995c +15306 995f +15307 99b1 +15308..15309 99b9 +15310 99c9 +15311 9a02 +15312 9a16 +15313 9a24 +15314 9a27 +15315..15316 9a2d +15317 9a36 +15318 9a38 +15319 9a4a +15320 9a56 +15321..15322 9ab5 +15323 9af9 +15324 9b03 +15325 9b20 +15326..15327 9b33 +15328 9b73 +15329 9b79 +15330 9ba7 +15331 9bc1 +15332 9bc7 +15333 9bd7 +15334 9be7 +15335 9beb +15336 9bf7 +15337 9bfa +15338 9bfd +15339 9c0b +15340 9c27 +15341 9c2a +15342 9c36 +15343 9c41 +15344 9c53 +15345 9c63 +15346 9c70 +15347 9c77 +15348 9d02 +15349 9d42 +15350 9d47 +15351 9d63 +15352 9d69 +15353 9d7c +15354 9d7e +15355 9d8d +15356 9db1 +15357 9dc3 +15358 9dc7 +15359 9dd6 +15360 9ddf +15361 9deb +15362 9df4 +15363 9e15 +15364 9e1d +15365 9ea4 +15366 9ea8 +15367 9eac +15368 9ee7 +15369 9eee +15370 9f10 +15371 9f12 +15372 9f17 +15373 9f19 +15374 9f2f +15375 9f37 +15376 9f39 +15377 9f41 +15378 9f45 +15379 9f57 +15380 9f68 +15381 9f71 +15382 9f75 +15383 9f90 +15384 9f94 +15385 9fa2 +15387 3405 +15388 2f804 +15389 5620 +15390 /uni5ECB.dup2 +15391 2e95 +15393 2363a +15395 /uni6FF9.dup2 +15396 6ee6 +15397 /uni71B3.dup2 +15398 fa49 +15403 fa66 +15405 5db2 +15407 4fd3 +15408 50d9 +15409 50f0 +15410 51c3 +15411 5676 +15412 6a54 +15413 6d01 +15414 6dd0 +15415 6e42 +15416 6ed9 +15417 73e4 +15418 7421 +15419 756c +15420 7851 +15421 87f5 +15422 233fe +15423 73a8 +15424 3af3 +15425 34db +15426 440c +15427 3e8a +15430 4be8 +15432 3eda +15433 3b22 +15435 457a +15436 4093 +15438 4665 +15439 4103 +15440 4293 +15441 46ae +15442 3488 +15443 22609 +15444..15446 f860 +15447 f87a +15448 f87f +15472..15473 2284 +15474..15475 228a +15476 2209 +15478..15479 2305 +15489..15490 2225 +15505 2262 +15507 2245 +15508 2248 +15509..15510 2276 +15515 2127 +15725..15726 22da +15727 2155 +15728 2318 +15729..15730 1e3e +15731..15732 01f8 +15733 01d6 +15734 01d8 +15735 01da +15736 01dc +15737 0104 +15738 02d8 +15739 013d +15740 015a +15741 015e +15742 0164 +15743 0179 +15744 017b +15745 0105 +15746 02db +15747 013e +15748 015b +15749 02c7 +15750 015f +15751 0165 +15752 017a +15753 02dd +15754 017c +15755 0154 +15756 0102 +15757 0139 +15758 0106 +15759 010c +15760 0118 +15761 010e +15762 0143 +15763 0147 +15764 0150 +15765 0158 +15766 0170 +15767 0162 +15768 0155 +15769 0103 +15770 013a +15771 0107 +15772 010d +15773 0119 +15774 010f +15775 0111 +15776 0144 +15777 0148 +15778 0151 +15779 0159 +15780 0171 +15781 0163 +15782 02d9 +15783 0108 +15784 011c +15785 0124 +15786 0134 +15787 015c +15788 016c +15789 0109 +15790 011d +15791 0125 +15792 0135 +15793 015d +15794 016d +15795 0271 +15796 028b +15797 027e +15798 026c +15799 026e +15800 0279 +15801 0288 +15802 0256 +15803 0273 +15804 027d +15805 0282 +15806 0290 +15807 027b +15808 026d +15809 025f +15810 0272 +15811 029d +15812 028e +15813 0261 +15814 0270 +15815 0281 +15816 0127 +15817 0295 +15818 0294 +15819 0266 +15820 0298 +15821 01c2 +15822 0253 +15823 0257 +15824 0284 +15825 0260 +15826 0193 +15827 0268 +15828 0289 +15829 0258 +15830 025c +15831 025e +15832 0250 +15833 026f +15834 028a +15835 0264 +15836 0252 +15837 028d +15838 0265 +15839 02a2 +15840 02a1 +15841 0255 +15842 0291 +15843 027a +15844 0267 +15845 0361 +15846 02c8 +15847 02cc +15848 02d1 +15849 203f +15850 030f +15851..15855 02e5 +15858 0325 +15859 032c +15860 0339 +15861 031c +15862..15863 031f +15864 033d +15865 0329 +15866 032f +15867 02de +15868 0324 +15869 0330 +15870 033c +15871 0334 +15872..15873 031d +15874..15875 0318 +15876 032a +15877..15878 033a +15879 031a +15883..15884 0262 +15885 026a +15886 0274 +15887 0276 +15888 0278 +15889 0280 +15890 028f +15891 0299 +15892 029c +15893 029f +15894 02b0 +15895 02b2 +15896 02b7 +15897 02c1 +15898..15899 02e0 +15906 /uni229E.dup2 +16194 303c +16195 30ff +16197..16198 3016 +16199 266e +16200 266b +16201..16202 2934 +16203 29bf +16205 30a0 +16207..16208 29fa +16222 03c2 +16223..16232 24f5 +16233..16234 2616 +16235 25b1 +16236..16245 31f0 +16247..16252 31fa +16253..16267 23be +16270 2713 +16272 2423 +16273 23ce +16274..16277 25d0 +16278..16279 2047 +16281 2051 +16282 2042 +16283..16298 3190 +16312..16313 23b0 +16314..16325 2672 +16326..16327 3099 +16328 20dd +16329 /Japan1.16197.vert +16330 /Japan1.16198.vert +16331 /Japan1.16205.vert +16333 /Japan1.16236.vert +16334 /Japan1.16237.vert +16335 /Japan1.16238.vert +16336 /Japan1.16239.vert +16337 /Japan1.16240.vert +16338 /Japan1.16241.vert +16339 /Japan1.16242.vert +16340 /Japan1.16243.vert +16341 /Japan1.16244.vert +16342 /Japan1.16245.vert +16344 /Japan1.16247.vert +16345 /Japan1.16248.vert +16346 /Japan1.16249.vert +16347 /Japan1.16250.vert +16348 /Japan1.16251.vert +16349 /Japan1.16252.vert +16350 /Japan1.16312.vert +16351 /Japan1.16313.vert +16779 4f48 +16780 4f5f +16781 4f6a +16782 4f6c +16783 500e +16784 5018 +16785 5041 +16786 50f2 +16787 50d0 +16788 5106 +16789 5103 +16790 5135 +16791 5155 +16792 5157 +16793 34b5 +16794 51ca +16795 51e2 +16796 5257 +16797 52cc +16798 52d6 +16799 52fb +16800 531c +16801 5363 +16802 539d +16803 5412 +16804 547f +16805 5488 +16806 5550 +16807 5581 +16808 55ad +16809 55ce +16810 563b +16811 569e +16812 56a9 +16813 56b3 +16814 5777 +16815 577c +16816 2131b +16817 57cf +16818 57e4 +16819 5864 +16820 5889 +16821 2146e +16822 58d2 +16823 58e0 +16824 8641 +16825 598b +16826 5992 +16827 59c3 +16828 5a13 +16829 5a67 +16830 5a77 +16831 5a84 +16832 5ac4 +16833 218bd +16834 5b7d +16835 5b93 +16836 5c12 +16837 fa3c +16838 216b4 +16839 5c7a +16840 5c8f +16841 5c9f +16842 5ca3 +16843 5caa +16844 5cd0 +16845 21e34 +16846 5d0d +16847 5d47 +16848 5d81 +16849 5da4 +16850 5da7 +16851 5dcb +16852 5e5e +16853 5ef9 +16854 5f00 +16855 5f02 +16856 5f23 +16857 5f3d +16858 5f54 +16859 5f7d +16860 600d +16861 6014 +16862 6018 +16863 6035 +16864 6047 +16865 609d +16866 60d4 +16867 60dd +16868 612b +16869 61bc +16870 61b9 +16871 6222 +16872 625a +16873 626f +16874 62d6 +16875 637c +16876 63e5 +16877 6479 +16878 64c4 +16879 64d0 +16880 6529 +16881 659d +16882 663a +16883 6622 +16884 662b +16885 6630 +16886 6633 +16887 6648 +16888 231c4 +16889 /uni6677.dup2 +16890 6678 +16891 668d +16892 66bb +16893 66db +16894 66e8 +16895 6747 +16896 6781 +16897 6793 +16898 6798 +16899 679b +16900 67fc +16901 681d +16902 68a3 +16903 690a +16904 6949 +16905 235c4 +16906 6942 +16907 6964 +16908 69a5 +16909 69cf +16910 3bb6 +16911 3bc3 +16912 69e9 +16913 69f5 +16914 2373f +16915 6a3b +16916 23763 +16917 6a94 +16918 6aa5 +16919 3c0f +16920 6b1b +16921 6b2c +16922 6b67 +16923 6ba9 +16924 6bad +16925 6bd7 +16926 6bff +16927 6c05 +16928 6c74 +16929 6c98 +16930 6cfb +16931 6cc6 +16932 6d31 +16933 6d39 +16934 6d3f +16935 6d58 +16936 6d94 +16937 6daa +16938 6ddb +16939 6ddd +16940 6e44 +16941 6e5e +16942 6eb1 +16943 6ec1 +16944 6f10 +16945 6f59 +16946 6f61 +16947 6f7e +16948 6f8c +16949 6fa0 +16950 6fbc +16951 6fc7 +16952 6fca +16953 6ff0 +16954 704e +16955 7075 +16956 70a4 +16957 70e4 +16958 712b +16959 711e +16960 712e +16961 7151 +16962 7168 +16963 7185 +16964 7187 +16965 71ba +16966 71c4 +16967 7215 +16968 3e3f +16969 729b +16970 247f1 +16971 7327 +16972 7350 +16973 7366 +16974 73a2 +16975 742b +16976 7446 +16977 /uni7462.dup2 +16978 746d +16979 74a6 +16980 74a9 +16981 74c9 +16982 74ff +16983 7517 +16984 3f72 +16985 75ce +16986 7602 +16987 7608 +16988 7664 +16989 7681 +16990 769d +16991 76aa +16992 76b6 +16993 76ce +16994 76d4 +16995 76e6 +16996 76f1 +16997 770a +16998 7719 +16999..17000 774d +17001 777a +17002 7780 +17003 7794 +17004 77e0 +17005 2548e +17006 7843 +17007 786e +17008 78b0 +17009 2550e +17010 78ad +17011 7900 +17012 791c +17013 792e +17014 /uni7934.dup2 +17015 7946 +17016 7979 +17017 79c8 +17018 25771 +17019 79d4 +17020 79de +17021 79eb +17022 79ed +17023 7a85 +17024 259c4 +17025 7ace +17026 7afd +17027 7b12 +17028 7b2d +17029 7b3b +17030 7b6f +17031 7c01 +17032 7c33 +17033 25da1 +17034 7c6d +17035 7c79 +17036 7c8f +17037 7c94 +17038 7ca0 +17039 7cd5 +17040 7d31 +17041 /uni7D5C.dup2 +17042 7d83 +17043 7da6 +17044 7dc2 +17045 7e28 +17046 7f97 +17047 7fdb +17048 8035 +17049 8037 +17050 80ca +17051 80e0 +17052 80f3 +17053 8160 +17054..17055 8167 +17056 816d +17057 81bb +17058 81ca +17059 81d7 +17060 445b +17061 8260 +17062 8274 +17063 26aff +17064 82a1 +17065..17066 82a3 +17067 82a9 +17068 82bf +17069 82d5 +17070 82fd +17071 8300 +17072 8322 +17073 832d +17074 833a +17075 8347 +17076 837d +17077 83a7 +17078 83cf +17079 83d1 +17080 83e1 +17081 8401 +17082 8406 +17083 845f +17084 8470 +17085 8473 +17086 8485 +17087 849e +17088 84ba +17089 26e40 +17090 8532 +17091 851e +17092 852f +17093 8564 +17094 857a +17095 858c +17096 85a2 +17097 85cb +17098 85ed +17099 85ff +17100..17101 8604 +17102 8610 +17103 270f4 +17104 8618 +17105 8638 +17106 8657 +17107 8662 +17108 459d +17109 8675 +17110 86b8 +17111 86fc +17112 8787 +17113 45ea +17114 880a +17115 8810 +17116 88ce +17117 27684 +17118 8932 +17119 8939 +17120 8940 +17121 8994 +17122 89f6 +17123 8a47 +17124 8a5d +17125 8a61 +17126 8a75 +17127 8ad0 +17128 8b46 +17129 8b59 +17130 8b69 +17131 8b9d +17132 8c49 +17133 8c68 +17134 8daf +17135 8dd1 +17136 8dd7 +17137 8e23 +17138 8e3d +17139 8e7b +17140 28277 +17141 4844 +17142 8efa +17143 8f1e +17144 8f2d +17145 8f54 +17146 283cd +17147 8fe8 +17148 8fee +17149 9008 +17150 902d +17151 9097 +17152 90b3 +17153 90be +17154..17155 90c4 +17156 90c7 +17157 90ef +17158 9114 +17159 9116 +17160..17161 9122 +17162 912f +17163 9134 +17164 9183 +17165 91f1 +17166 9349 +17167 9364 +17168 /uni9365.dup2 +17169 93a3 +17170 93df +17171 9404 +17172 9433 +17173 944a +17174 9463 +17175 9471 +17176 958e +17177 959f +17178 95ac +17179 95b6 +17180 95cb +17181 95d0 +17182 95d3 +17183 49b0 +17184 95de +17185 96a5 +17186 96ef +17187 974e +17188 9795 +17189 97ae +17190 97ba +17191 97c1 +17192 97c9 +17193 97db +17194 9856 +17195 98e7 +17196 9958 +17197 9a03 +17198 9ac1 +17199 9ac3 +17200 9ace +17201 9ad6 +17202 9b02 +17203 9b08 +17204 4c17 +17205 /uni9B2D.dup2 +17206 9b5e +17207 9b66 +17208 9b84 +17209 9b8a +17210 9b9e +17211 9bce +17212 9be5 +17213 9bf8 +17214 9c23 +17215..17216 9c4f +17217 9c65 +17218..17219 9d1d +17220 9d43 +17221 9d52 +17222 9d8a +17223 9d96 +17224 9dc0 +17225 9dac +17226 9dbc +17227 2a190 +17228 9de7 +17229 9e07 +17230 9e9e +17231 9eaf +17232 9f97 +17233 20089 +17234 4e02 +17235 4e0f +17236 4e12 +17237 4e29 +17238 4e2e +17239 4e47 +17240 200a2 +17241 4e51 +17242 3406 +17243 200a4 +17244 4e69 +17245 4e9d +17246 342c +17247 4ebc +17248 4ec3 +17249 4ec8 +17250 4eeb +17251 4eda +17252 4ef1 +17253 4ef5 +17254 4f16 +17255 4f64 +17256 4f37 +17257 4f3e +17258 4f58 +17259 20213 +17260..17261 4f77 +17262 4f82 +17263 4f85 +17264 4fe6 +17265 4fb2 +17266 4fc5 +17267 4fcb +17268 4fd2 +17269 346a +17270 4ff2 +17271 5013 +17272 501c +17273 504e +17274 5053 +17275 5063 +17276 50a3 +17277 5088 +17278..17279 5092 +17280 5095 +17281 50aa +17282 2032b +17283 50b1 +17284..17285 50ba +17286 50c4 +17287 50c7 +17288 50f3 +17289 20381 +17290 50ce +17291 20371 +17292 50d4 +17293 50e1 +17294 3492 +17295 203f9 +17296 5117 +17297 2044a +17298 5160 +17299 20509 +17300 5173 +17301 5183 +17302 518b +17303 34bc +17304 5198 +17305 51a3 +17306 51ad +17307 34c7 +17308 205d6 +17309 51f3 +17310 5212 +17311 5216 +17312 2074f +17313 5255 +17314 525c +17315 526c +17316 5277 +17317 5284 +17318 5282 +17319 20807 +17320 5298 +17321 2083a +17322 52a4 +17323..17324 52ba +17325 52ca +17326 52d1 +17327 208b9 +17328 52f7 +17329 5335 +17330 5342 +17331 2097c +17332 2099d +17333 5367 +17334 537a +17335 53a4 +17336 53b4 +17337 20ad3 +17338 53b7 +17339 53c0 +17340 20b1d +17341..17342 355d +17343 53d5 +17344 3563 +17345 53f4 +17346 5424 +17347 5428 +17348 356e +17349 5443 +17350 5462 +17351 546c +17352 5495 +17353 54a0 +17354 54a6 +17355 54ae +17356 54b7 +17357 54ba +17358 54c3 +17359 20d45 +17360 54ec +17361 54ef +17362 54f1 +17363 54f3 +17364..17365 5500 +17366 5509 +17367 553c +17368 5541 +17369 35a6 +17370 5547 +17371 35a8 +17372 5564 +17373 20de1 +17374 557d +17375 5582 +17376 5591 +17377 35c5 +17378 55d2 +17379 20e95 +17380 20e6d +17381 55bf +17382 55c9 +17383 55cc +17384 55d1 +17385 55dd +17386 35da +17387 55e2 +17388 20e64 +17389 55e9 +17390 5628 +17391 20f5f +17392 5607 +17393 5610 +17394 5630 +17395 35f4 +17396 563d +17397 5640 +17398 5647 +17399 565e +17400 5660 +17401 566d +17402 3605 +17403 5688 +17404 568c +17405 569d +17406 56a8 +17407 56b2 +17408 56c5 +17409 56cd +17410 56df +17411 56e8 +17412..17413 56f6 +17414 21201 +17415 21255 +17416 5729 +17417 2127b +17418..17419 5745 +17420 574d +17421 21274 +17422 5768 +17423 576f +17424..17426 5773 +17427 577b +17428 212e4 +17429 212d7 +17430 579a +17431..17432 579d +17433 57a8 +17434 57d7 +17435 212fd +17436 57cc +17437 21336 +17438 21344 +17439 57de +17440 57f0 +17441 364a +17442 57f8 +17443 57fb +17444 57fd +17445 5804 +17446 581e +17447 5827 +17448 5839 +17449 213c4 +17450 5849 +17451 584c +17452 5867 +17453..17454 588a +17455 588d +17456..17457 588f +17458 5894 +17459 589d +17460 58aa +17461 58b1 +17462 2146d +17463 58c3 +17464 58cd +17465 58e2 +17466..17467 58f3 +17468..17469 5905 +17470 590d +17471 5914 +17472 215d7 +17473 3691 +17474 593d +17475 3699 +17476 5946 +17477 3696 +17478 26c29 +17479 595f +17480 21647 +17481..17482 5975 +17483 597c +17484 599f +17485 59ae +17486 59bc +17487 59c8 +17488 59cd +17489 59de +17490 59e7 +17491 59ee +17492 21706 +17493 21742 +17494 36cf +17495 5a0d +17496 5a17 +17497 5a27 +17498 5a2d +17499 5a65 +17500 5a7a +17501 5a8b +17502 5a9c +17503..17504 5a9f +17505 5aa2 +17506 5ab1 +17507 5ab5 +17508 5aba +17509 5abf +17510 5ada +17511 5adc +17512 5ae5 +17513 5af0 +17514 5aee +17515 5af5 +17516 5b08 +17517 5b17 +17518 5b34 +17519 5b4c +17520 5b52 +17521 5b68 +17522 5b6f +17523 5b81 +17524 5b84 +17525 219c3 +17526 5b96 +17527 5bac +17528..17529 3761 +17530 5bce +17531 5bd6 +17532 376c +17533 376b +17534 5bf1 +17535 5bfd +17536 3775 +17537 5c03 +17538 5c29 +17539 21c56 +17540 5c5f +17541..17542 5c67 +17543 5c70 +17544 21d2d +17545 21d45 +17546 21d78 +17547 21d62 +17548 5c88 +17549 5c8a +17550 37c1 +17551 21da1 +17552 21d9c +17553 5ca0 +17554 5ca2 +17555 5ca7 +17556 21d92 +17557 5cad +17558 5cb5 +17559 21db7 +17560 5cc9 +17561 21de0 +17562 21e33 +17563 5d06 +17564 5d10 +17565 5d2b +17566 5d1d +17567 5d20 +17568 5d31 +17569 5d39 +17570 37e8 +17571 5d61 +17572 5d6a +17573 37f4 +17574 5d70 +17575 21f1e +17576 37fd +17577 5d88 +17578 3800 +17579 5d97 +17580 5db0 +17581 5db4 +17582 21f76 +17583 5dd1 +17584 5dd7 +17585 21ffa +17586 5de4 +17587 5de9 +17588 382f +17589 3836 +17590 3840 +17591 5e1f +17592 5e3e +17593 5e49 +17594 385c +17595 5e56 +17596 3861 +17597..17598 5e6d +17599 2217b +17600 5ea5 +17601 5eac +17602 5eb9 +17603 5ec6 +17604 5ed9 +17605 2231e +17606 5efd +17607 5f08 +17608 223ad +17609 5f1e +17610 5f47 +17611 5f63 +17612 5f72 +17613 5f7e +17614 5f8f +17615 5fa2 +17616 5fc7 +17617 5fcb +17618..17620 5fd2 +17621 5fe2 +17622..17623 5fee +17624 5ff3 +17625 3917 +17626 6022 +17627 6024 +17628 391a +17629 604c +17630 6095 +17631 60a8 +17632 226f3 +17633 60b1 +17634 60be +17635 60c8 +17636 60d9 +17637 60ee +17638 60f5 +17639 6110 +17640 6119 +17641 611e +17642 613a +17643 396f +17644 6141 +17645 6146 +17646 6160 +17647 2285b +17648..17649 6192 +17650 6197 +17651 61a5 +17652 61ad +17653 228ab +17654 61d5 +17655 61dd +17656 61f5 +17657 2298f +17658 6223 +17659 6252 +17660 6261 +17661 6264 +17662 627b +17663 626d +17664 6273 +17665 6299 +17666 62d5 +17667 22ab8 +17668 62fd +17669 6303 +17670 6310 +17671..17672 22b4f +17673 6332 +17674 6335 +17675..17676 633b +17677 6341 +17678 6344 +17679 634e +17680 22b46 +17681 6359 +17682 22c1d +17683 22ba6 +17684 636c +17685 6399 +17686 22c24 +17687 6394 +17688 63bd +17689..17690 63d4 +17691 63e0 +17692..17693 63eb +17694 63f2 +17695 641e +17696 6425 +17697 6429 +17698 642f +17699 645a +17700 645d +17701 6473 +17702 647d +17703 6487 +17704 6491 +17705 649f +17706..17707 64cb +17708 64d5 +17709 64d7 +17710 22de1 +17711 64e4 +17712 64ff +17713 3a6e +17714 650f +17715 6514 +17716 3a73 +17717 651e +17718 6532 +17719 6544 +17720 6554 +17721 656b +17722 657a +17723 6584 +17724 658a +17725 65b2 +17726 65b5 +17727 65b8 +17728 65bf +17729 65c9 +17730 65d4 +17731 3ad6 +17732 65f9 +17733 65fc +17734 6604 +17735 6608 +17736 6621 +17737 662a +17738 6645 +17739 6651 +17740 664e +17741 3aea +17742 231c3 +17743 231f5 +17744 231b6 +17745 666a +17746..17747 666c +17748 667b +17749 6680 +17750 6690 +17751 6692 +17752 3b0e +17753 66ad +17754 66b1 +17755 66b5 +17756 3b1a +17757 3b1c +17758 3ad7 +17759 6701 +17760 6712 +17761 23372 +17762 6719 +17763 233d3 +17764 233d2 +17765 674d +17766 6754 +17767 675d +17768 233d0 +17769 233e4 +17770 233d5 +17771 6774 +17772 233da +17773 6792 +17774 233df +17775 8363 +17776 6810 +17777 67c3 +17778 67c8 +17779 67d2 +17780 67db +17781 67f7 +17782 2344a +17783 23451 +17784 2344b +17785 6818 +17786 681f +17787 682d +17788 23465 +17789 6833 +17790 683b +17791 683e +17792 6845 +17793 6849 +17794 684c +17795 6855 +17796 6857 +17797 3b77 +17798 686b +17799 686e +17800 687c +17801 6882 +17802 6890 +17803 6896 +17804 3b6d +17805..17807 6898 +17808 689c +17809..17810 68aa +17811 68b4 +17812 68bb +17813 68fb +17814 234e4 +17815 2355a +17816 68c3 +17817 68c5 +17818 68cc +17819 68d9 +17820..17821 68e4 +17822 68ec +17823 68f7 +17824 6903 +17825 6907 +17826 3b87 +17827 23594 +17828 3b8d +17829 6946 +17830 6969 +17831 696c +17832 697a +17833 6992 +17834 3ba4 +17835 6996 +17836 69b0 +17837 69ba +17838 69bc +17839 69c0 +17840 69d1 +17841 23639 +17842 23647 +17843 23638 +17844 69e3 +17845..17846 69ee +17847 69f3 +17848 3bcd +17849 69f4 +17850 69fe +17851 6a11 +17852 6a1a +17853 6a1d +17854 2371c +17855..17856 6a32 +17857 6a3f +17858 6a49 +17859 6a7a +17860 6a4e +17861 6a52 +17862 6a64 +17863 2370c +17864 6a8b +17865 3bf0 +17866 6aa1 +17867 23764 +17868 6aab +17869 6abd +17870 6ac6 +17871 6ad4 +17872 6ad0 +17873 6add +17874 237ff +17875 237e7 +17876..17878 6af1 +17879 6afd +17880 23824 +17881 6b0b +17882..17884 6b0f +17885 2383d +17886 6b17 +17887 3c26 +17888 6b2f +17889 6b4a +17890 6b58 +17891 6b6c +17892 6b75 +17893 6b7a +17894 6b81 +17895 6b9b +17896 6bae +17897 23a98 +17898 6bbd +17899..17901 6bc7 +17902 6bda +17903..17904 6be6 +17905 6bee +17906 6c02 +17907 6c0a +17908 6c0e +17909 6c36 +17910 23c7f +17911 6c4d +17912 6c5b +17913 6c6d +17914 6c84 +17915 6c89 +17916 3cc3 +17917 6c94 +17918 6c97 +17919 6cad +17920 6cc2 +17921 3cd2 +17922 6cdc +17923 6ce9 +17924 6ced +17925 23d00 +17926 6d00 +17927 6d24 +17928..17929 6d26 +17930 6c67 +17931 6d2f +17932 6d3c +17933 6d5b +17934 6d60 +17935 6d70 +17936..17937 6d80 +17938 6d8a +17939 6d8d +17940 6d91 +17941 6d98 +17942 23d40 +17943 23dfa +17944 23df9 +17945 23dd3 +17946 6dab +17947 6dae +17948 6db4 +17949 6dc2 +17950 6d34 +17951 6dc8 +17952 6dce +17953 6ddf +17954 6df6 +17955 6e36 +17956 6e1e +17957 3d11 +17958 6e32 +17959..17960 6e48 +17961..17962 6e4b +17963 6e4f +17964..17965 6e53 +17966 6e57 +17967 6e63 +17968 3d1e +17969 6e93 +17970 6ea7 +17971 6eb4 +17972 6ec3 +17973 6f35 +17974 6eeb +17975 6ef9 +17976 6efb +17977 6f0a +17978 6f0c +17979 6f18 +17980 6f25 +17981 6f36 +17982 6f3c +17983 23f7e +17984 6f52 +17985 6f57 +17986 6f60 +17987 6f68 +17988 6f90 +17989 6f96 +17990 6fbe +17991 6f9f +17992 6fa5 +17993 6faf +17994 3d64 +17995..17996 6fc8 +17997 6fe9 +17998 24096 +17999 6ffc +18000 7000 +18001 700a +18002 7023 +18003 24103 +18004 703a +18005 7043 +18006 7047 +18007 704b +18008 3d9a +18009 7065 +18010 7069 +18011 706e +18012 7076 +18013 7086 +18014 7097 +18015 241c6 +18016 709f +18017 70b1 +18018 241fe +18019 70ec +18020 70ca +18021 70d1 +18022 7103 +18023 7106 +18024 7108 +18025 710c +18026 3dc0 +18027 712f +18028 7150 +18029 7153 +18030 715e +18031 3dd4 +18032 7196 +18033 7180 +18034 719b +18035 71a0 +18036 71a2 +18037..18038 71ae +18039 243bc +18040 71d9 +18041 71dc +18042 7207 +18043 3e05 +18044 7234 +18045 7239 +18046 7242 +18047 7257 +18048 7263 +18049 24629 +18050..18051 726e +18052 7278 +18053 727f +18054 728e +18055 246a5 +18056 72ae +18057 72b0 +18058 72c1 +18059 3e60 +18060 72cc +18061 3e66 +18062 3e68 +18063 72f3 +18064 72fa +18065 7307 +18066 7312 +18067..18068 7318 +18069 3e83 +18070 7339 +18071 732c +18072 7333 +18073 733d +18074 7352 +18075 3e94 +18076 736b +18077 24896 +18078..18079 736e +18080 7371 +18081 7381 +18082 738a +18083 7394 +18084 7398 +18085 739c +18086 73a5 +18087 73b9 +18088 73bf +18089 73c5 +18090 73cb +18091 73e1 +18092 73e7 +18093 73f9 +18094 7413 +18095 73fa +18096 7401 +18097 7453 +18098 7440 +18099 7443 +18100 7452 +18101 745d +18102 7481 +18103 7488 +18104 24a4d +18105 7492 +18106 7497 +18107 7499 +18108 74a1 +18109 74a5 +18110 74aa +18111 74b9 +18112 74bb +18113 74ba +18114 74d6 +18115 74d8 +18116 74eb +18117 24b56 +18118 74fa +18119 24b6f +18120 7520 +18121 7524 +18122 752a +18123 3f57 +18124 24c16 +18125..18126 753d +18127 7540 +18128 7548 +18129 7550 +18130 7552 +18131 7572 +18132 7571 +18133 757a +18134..18135 757d +18136 758c +18137 3f75 +18138 75a2 +18139 3f77 +18140 75b0 +18141 75b7 +18142..18143 75bf +18144 75c6 +18145 75cf +18146 75d3 +18147 75dd +18148..18149 75df +18150 75e7 +18151 75ee +18152 75f1 +18153 7603 +18154 7618 +18155 7607 +18156 760f +18157 3fae +18158 24e0e +18159 7613 +18160..18161 761b +18162 24e37 +18163 7625 +18164 7628 +18165 763c +18166 7633 +18167 24e6a +18168 3fc9 +18169 7641 +18170 24e8b +18171 7649 +18172 7655 +18173 3fd7 +18174 766e +18175 7695 +18176 76a1 +18177 76a0 +18178..18179 76a7 +18180 76af +18181 2504a +18182 76c9 +18183 25055 +18184 76e8 +18185 25122 +18186 7717 +18187 771a +18188 772d +18189 7735 +18190 251a9 +18191 4039 +18192 251e5 +18193 251cd +18194 7758 +18195 2521e +18196 777c +18197 2524c +18198 4058 +18199 779a +18200 779f +18201 77a2 +18202 77a4 +18203..18204 77de +18205 77e4 +18206 77ea +18207 77ec +18208 77fb +18209 2542e +18210 7805 +18211 7809 +18212 780d +18213 7819 +18214 782c +18215 7847 +18216 786a +18217 254d9 +18218 788a +18219 7894 +18220 78a4 +18221 789d +18222 789f +18223 78bb +18224 78d5 +18225 78e6 +18226..18227 78f9 +18228 78fe +18229 255a7 +18230 7910 +18231 791b +18232 7925 +18233 794a +18234 7958 +18235 4105 +18236 7967 +18237 7972 +18238 7995 +18239 79a1 +18240 79a9 +18241 79b4 +18242 79c2 +18243 79c7 +18244..18245 79cc +18246 79d6 +18247 4148 +18248 257a9 +18249 257b4 +18250 414f +18251 7a0a +18252 7a15 +18253 7a1b +18254 4163 +18255 7a38 +18256 7a47 +18257 7a56 +18258 7a59 +18259 7a5c +18260 7a5f +18261 7a67 +18262 7a6a +18263 7a75 +18264 7a82 +18265 7a8a +18266 7a90 +18267 7aac +18268 259d4 +18269 41b4 +18270 7ab9 +18271 7abe +18272 41bf +18273 7acc +18274 7ae8 +18275 7af4 +18276 25ae4 +18277 25ae3 +18278 25af1 +18279 7b3d +18280 7b2a +18281..18282 7b2e +18283 41e6 +18284 41f3 +18285 7b7f +18286 7b41 +18287 41ee +18288 7b55 +18289 7b79 +18290 7b64 +18291 7b66 +18292 7b73 +18293 25bb2 +18294 4207 +18295 7b90 +18296 7b9b +18297 420e +18298 7bb5 +18299 7bbc +18300 7bc5 +18301 7bca +18302 25c4b +18303 25c64 +18304 7bd4 +18305 7bd6 +18306 7bda +18307 7bea +18308 7bf0 +18309 7c03 +18310 7c0e +18311 7c45 +18312 7c4a +18313 7c57 +18314 7c5e +18315 7c61 +18316 7c69 +18317 7c6f +18318 25e2e +18319 25e56 +18320 25e65 +18321 7ca6 +18322 25e62 +18323..18324 7cb6 +18325 25ed8 +18326 7cc4 +18327 25ec2 +18328 7ccd +18329 25ee8 +18330 25f23 +18331 7ce6 +18332 25f5c +18333 7cf5 +18334 7d03 +18335 42c6 +18336 7d12 +18337 7d1e +18338 25fe0 +18339 25fd4 +18340..18341 7d3d +18342 7d40 +18343 7d47 +18344 2600c +18345 25ffb +18346 42d6 +18347 7d5a +18348 7d6a +18349 7d70 +18350 42dd +18351 7d7f +18352 26017 +18353 7d88 +18354 7d97 +18355 26060 +18356 7d9d +18357 7da7 +18358 7daa +18359 7db6 +18360 7dc0 +18361 7dd7 +18362 7dd9 +18363 7de6 +18364 4302 +18365 260ed +18366 fa58 +18367 7e10 +18368 7e17 +18369 7e1d +18370 7e27 +18371 7e2c +18372 7e45 +18373 7e75 +18374 7e7e +18375..18376 7e86 +18377 432b +18378 7e9a +18379 4343 +18380 7f3c +18381 7f3b +18382 7f3e +18383 7f43 +18384 34c1 +18385 26270 +18386 26286 +18387..18388 7f63 +18389 7f6d +18390..18391 7f7d +18392 7f90 +18393 517b +18394 23d0e +18395 7f96 +18396 7f9c +18397 7fad +18398 26402 +18399 7fc3 +18400 7fcf +18401 7fe3 +18402 7ff2 +18403 800a +18404 8008 +18405 8016 +18406 802c +18407 8030 +18408 8043 +18409 8066 +18410 807b +18411 8099 +18412 809c +18413 80a4 +18414 80a7 +18415 80b8 +18416 2667e +18417 80c5 +18418 80d5 +18419 80e6 +18420 810d +18421 80f5 +18422 80fb +18423 43ee +18424 8135 +18425 811e +18426 43f0 +18427 8124 +18428 8127 +18429 812c +18430 2671d +18431 813d +18432 4408 +18433 8169 +18434 4417 +18435 441c +18436 8185 +18437 4422 +18438 8198 +18439 81b2 +18440 81c1 +18441 81c3 +18442 81d6 +18443 81db +18444 268dd +18445 81e4 +18446 268ea +18447 81ec +18448 81fd +18449 81ff +18450 2696f +18451 8204 +18452 269dd +18453 8219 +18454 8222 +18455 26a1e +18456 823c +18457 8249 +18458 8245 +18459 26a58 +18460 4476 +18461 447a +18462 8257 +18463 26a8c +18464 825c +18465 8263 +18466 26ab7 +18467 4491 +18468 827d +18469 827f +18470 8283 +18471 828a +18472 8293 +18473..18474 82a7 +18475 82b2 +18476 82b4 +18477 82ba +18478 82bc +18479 82e2 +18480 82e8 +18481 82f7 +18482..18483 8307 +18484 830c +18485 8354 +18486 831b +18487 831d +18488 8330 +18489 833c +18490 8344 +18491 8357 +18492 44be +18493 44d4 +18494 44b3 +18495..18496 8394 +18497 839b +18498 839d +18499 83c9 +18500 83d0 +18501 83d4 +18502 83dd +18503 83e5 +18504 83f9 +18505 8415 +18506 26c73 +18507 8417 +18508 8439 +18509 844f +18510..18511 8451 +18512..18513 8459 +18514 845c +18515 26cdd +18516 8465 +18517 8478 +18518 847c +18519 8481 +18520 450d +18521 8497 +18522 84a6 +18523 84be +18524 4508 +18525..18526 84ce +18527 84d3 +18528 26e65 +18529 84e7 +18530 84ea +18531 84ef +18532 84f1 +18533 84fa +18534 851b +18535..18536 8524 +18537 852b +18538 854f +18539 856f +18540 4543 +18541 8551 +18542..18543 8561 +18544 26f94 +18545 857b +18546 857d +18547 857f +18548 8581 +18549 8586 +18550 8593 +18551 859d +18552 859f +18553 26ff8 +18554..18555 26ff6 +18556 85bc +18557 85c7 +18558 85ca +18559..18560 85d8 +18561 85df +18562 85e1 +18563 85e6 +18564 85f6 +18565 8600 +18566 8611 +18567 861e +18568 8621 +18569 8624 +18570 8627 +18571 2710d +18572 8639 +18573 863c +18574 27139 +18575 8640 +18576 8653 +18577 8656 +18578 8677 +18579 8687 +18580 8689 +18581..18582 869c +18583 86b1 +18584 86b3 +18585 86c1 +18586 86c3 +18587 86d1 +18588 86d5 +18589 86d7 +18590 86e3 +18591 86e6 +18592 45b8 +18593 8705 +18594 8707 +18595 870e +18596 8710 +18597 871f +18598 8721 +18599 8723 +18600 8731 +18601 873a +18602 8740 +18603 8743 +18604 8751 +18605 8758 +18606..18607 8764 +18608 8772 +18609 877c +18610 273db +18611 273da +18612 87a7 +18613 8789 +18614 878b +18615 8793 +18616 87a0 +18617 273fe +18618 45e5 +18619 87be +18620 27410 +18621 87c1 +18622 87ce +18623 87df +18624 27449 +18625 87e3 +18626..18627 87e5 +18628 87ea +18629 8813 +18630 8828 +18631 882e +18632 8832 +18633 883c +18634 460f +18635 884a +18636 8858 +18637 27615 +18638 27614 +18639 8869 +18640 27631 +18641 886f +18642 88a0 +18643 88bc +18644 88c0 +18645 27693 +18646 88d1 +18647 88d3 +18648 4641 +18649 8901 +18650 2770e +18651 8937 +18652 27723 +18653 8942 +18654 8945 +18655 8949 +18656 27752 +18657 8962 +18658 8989 +18659 8990 +18660 899f +18661 89b0 +18662 89b7 +18663 89d8 +18664 89eb +18665 46a1 +18666 89f3 +18667 89fd +18668 89ff +18669 46af +18670 8a11 +18671 8a14 +18672 27985 +18673 8a21 +18674 8a35 +18675 8a3e +18676 8a45 +18677 8a4d +18678 8a58 +18679 8aae +18680 8a90 +18681 8ab7 +18682 8ad7 +18683 8afc +18684 27a84 +18685 8b0a +18686 8b05 +18687 8b0d +18688 8b1c +18689 8b2d +18690 470c +18691 8b51 +18692 8b5e +18693 8b76 +18694 8b81 +18695 8b8b +18696..18697 8b94 +18698 8c39 +18699 27bb3 +18700 8c3d +18701 27bbe +18702 27bc7 +18703 8c45 +18704 8c4f +18705 8c57 +18706 8c69 +18707 8c6d +18708 27cb8 +18709 8c93 +18710 8c92 +18711 8c99 +18712 4764 +18713 8c9b +18714 8cd6 +18715 8cd5 +18716 27da0 +18717 8cf1 +18718 27e10 +18719 8d09 +18720 8d0e +18721 8dc8 +18722 8dd9 +18723 8e0c +18724 47fd +18725 8dfd +18726 8e06 +18727 2808a +18728 8e14 +18729 8e16 +18730..18731 8e21 +18732 8e27 +18733 280bb +18734 4816 +18735 8e36 +18736 8e39 +18737 8e54 +18738 8e62 +18739 8e6d +18740 8e6f +18741 8e98 +18742 8e9e +18743 8eb5 +18744 8ebb +18745 28282 +18746 484e +18747 282f3 +18748 8f00 +18749 8f08 +18750 8f2b +18751 8f40 +18752 8f4a +18753 8f58 +18754 2840c +18755 8fa4 +18756 8fb4 +18757 28455 +18758 8fc1 +18759 /uni8FC6.dup2 +18760 /uniFA24.dup2 +18761 8fca +18762 8fcd +18763 8fd3 +18764 8fd5 +18765 8ff1 +18766 8ff5 +18767 8ffb +18768 900c +18769 9037 +18770 2856b +18771 9043 +18772 905d +18773..18774 285c8 +18775 9085 +18776 908c +18777 9090 +18778 90a1 +18779 48b5 +18780 90b0 +18781 90b6 +18782 90c3 +18783 90c8 +18784 286d7 +18785 90dc +18786 90df +18787 286fa +18788 90f6 +18789 90f2 +18790 9100 +18791 90eb +18792..18793 90fe +18794 9104 +18795 9106 +18796 9118 +18797 911e +18798 9137 +18799 9139 +18800..18801 9146 +18802 9157 +18803 9159 +18804 9174 +18805 9179 +18806 9185 +18807 91b3 +18808 91b6 +18809..18810 91c3 +18811 28949 +18812 28946 +18813 91ec +18814 9201 +18815..18816 9216 +18817 2896b +18818 9242 +18819 924a +18820 9256 +18821 9261 +18822 9265 +18823 9268 +18824 28988 +18825..18826 927c +18827 927f +18828 9289 +18829 928d +18830 9297 +18831 9299 +18832 929f +18833 92ab +18834..18835 289ba +18836 92b2 +18837..18838 92bf +18839 92c6 +18840 92ce +18841 92e5 +18842 9311 +18843 28a1e +18844 28a29 +18845 92f7 +18846 9329 +18847 28a71 +18848 28a43 +18849 9351 +18850 935a +18851 936b +18852 9371 +18853 9373 +18854 93a1 +18855 28a99 +18856 28acd +18857 9388 +18858 938b +18859 938f +18860 939e +18861 93f5 +18862 28ae4 +18863 28add +18864 93f1 +18865 93c7 +18866 93dc +18867 93e7 +18868 9409 +18869..18870 9416 +18871 93fb +18872 9432 +18873 943b +18874 28bc1 +18875 28bef +18876 946d +18877 946f +18878 9579 +18879 9586 +18880..18881 958c +18882 28d10 +18883 28d71 +18884 95c8 +18885 28dfb +18886 28e1f +18887 962c +18888..18889 9633 +18890 28e36 +18891 963c +18892 9661 +18893 28e89 +18894 9682 +18895 28eeb +18896 969a +18897 28f32 +18898 49e7 +18899 96b3 +18900 96ba +18901 96bd +18902 49fa +18903 28ff8 +18904 96d8 +18905 96da +18906 96dd +18907 4a04 +18908 9714 +18909 9723 +18910 4a29 +18911 9736 +18912 9741 +18913 9747 +18914 9757 +18915 975b +18916 976a +18917 292a0 +18918 292b1 +18919 9796 +18920 979e +18921..18922 97b1 +18923 97be +18924 97cc +18925 97d1 +18926 97d4 +18927 97d8 +18928 97e1 +18929 97f1 +18930 9804 +18931 980d +18932 9814 +18933 9816 +18934 4abc +18935 29490 +18936..18937 9832 +18938 9825 +18939 9847 +18940 9866 +18941 98ab +18942 98ad +18943 98b0 +18944 295cf +18945 98b7 +18946..18947 98bb +18948 98c2 +18949 98c7 +18950 98cb +18951 98e1 +18952 98e3 +18953 98ea +18954..18955 98f0 +18956 98f3 +18957 9908 +18958 4b3b +18959 296f0 +18960..18961 9916 +18962 29719 +18963..18965 991a +18966 29750 +18967 9931 +18968..18970 993a +18971 9941 +18972 9946 +18973 994e +18974 9960 +18975 99a3 +18976 99a6 +18977 99bd +18978 99bf +18979 99c3 +18980 99d4 +18981 99d9 +18982 99de +18983 298c6 +18984 99f0 +18985 99f9 +18986 99fc +18987 9a0a +18988 9a11 +18989 9a1a +18990 9a20 +18991 9a31 +18992 9a44 +18993 9a4c +18994 9a58 +18995 4bc2 +18996 9aaf +18997 4bca +18998 9ab7 +18999 4bd2 +19000 9ab9 +19001 29a72 +19002 9ac6 +19003 9ad0 +19004 9ad2 +19005 9ad5 +19006 9ae0 +19007 9ae5 +19008 9ae9 +19009 9b0c +19010 9b10 +19011 9b12 +19012 9b16 +19013 9b1c +19014 9b2b +19015 9b3d +19016 4c20 +19017 9b4b +19018 9b63 +19019 9b65 +19020..19021 9b6b +19022..19023 9b76 +19024 9ba6 +19025 9bac +19026 29ddb +19027 9bb2 +19028 9bb8 +19029 9bbe +19030 9bf3 +19031 9bd8 +19032 9bdd +19033 9bea +19034 9bef +19035 9bee +19036 29e15 +19037 29e8a +19038 29e49 +19039 9c16 +19040..19042 9c18 +19043 9c1d +19044 9c22 +19045 9c29 +19046 29ec4 +19047 9c31 +19048 9c37 +19049 9c45 +19050 9c5c +19051 29ee9 +19052..19053 9c49 +19054 29edb +19055 9c54 +19056 9c58 +19057 9c5b +19058 9c5d +19059 9c5f +19060..19062 9c69 +19063..19064 9c6d +19065 9c72 +19066 9c75 +19067 9c7a +19068 9ce6 +19069 9cf2 +19070 9d0b +19071 29fce +19072 9d11 +19073..19074 9d17 +19075 2a02f +19076 4cc4 +19077 2a01a +19078 9d32 +19079 4cd1 +19080 9d4a +19081 9d5f +19082 9d62 +19083 2a0f9 +19084 2a082 +19085 9d73 +19086..19087 9d76 +19088 9d84 +19089 9d99 +19090 9da1 +19091 9dbf +19092 9db5 +19093 9db9 +19094 9dbd +19095 9dc9 +19096 9dda +19097 9de0 +19098 9de3 +19099 4d07 +19100 9e0a +19101 9e02 +19102 9e0d +19103 9e1c +19104 9e7b +19105 22218 +19106 9e80 +19107 9e85 +19108 9e9b +19109 2a38c +19110 9ebd +19111 2a437 +19112 9edf +19113 9eff +19114 9f02 +19115 4d77 +19116 9f03 +19117 9f3a +19118 9f3d +19119 9f46 +19120 9f53 +19121 9f55 +19122 9f58 +19123 2a5f1 +19124 9f5d +19125 2a602 +19126 9f69 +19127 9f6d +19128 9f70 +19129 2a6b2 +19130 2eac +19131 3614 +19132 38ad +19133 3dcc +19134 3fdc +19135 45be +19136 4610 +19137 4b7e +19138 4c38 +19139 4ce1 +19140 4e0c +19141..19142 4e23 +19143 4e79 +19144 4ef3 +19145 4f0c +19146 4f19 +19147 4f2b +19148 4f2e +19149 4f31 +19150 4f84 +19151 4f9e +19152 4fb7 +19153 5004 +19154 500c +19155 504c +19156 505f +19157 5062 +19158 5077 +19159 508e +19160 509e +19161 50a2 +19162 50c3 +19163 50e8 +19164 50f1 +19165 50fe +19166 5107 +19167..19169 510c +19170 5133 +19171 5138 +19172 5174 +19173 5184 +19174 51b8 +19175 51ba +19176 51c8 +19177 51cf +19178 51d1 +19179..19180 51d3 +19181 51d8 +19182 51df +19183 5205 +19184 5226 +19185 5228 +19186 522b +19187..19188 5231 +19189 5235 +19190 523c +19191 525a +19192 5260 +19193 526e +19194..19195 5278 +19196 528a +19197 528c +19198 52e1 +19199 52e9 +19200 52f1 +19201 5303 +19202 5311 +19203 531f +19204 532d +19205 5332 +19206 533d +19207 5365 +19208 536d +19209 5379 +19210 537e +19211 5394 +19212 5399 +19213 53aa +19214 53af +19215 53ba +19216 53c1 +19217..19218 53c4 +19219 53e0 +19220 5413 +19221 542a +19222 5431 +19223..19224 5434 +19225 544c +19226 54a7 +19227 54aa +19228 54b1 +19229 54bb +19230 54ce +19231 54ea +19232 54fc +19233 5505 +19234 5508 +19235 5515 +19236 5527 +19237 552a +19238 5536 +19239 5551 +19240 5566 +19241 558f +19242 5592 +19243 5594 +19244 55a4 +19245 55b2 +19246 55c3 +19247 55c6 +19248 55d3 +19249 55db +19250 55ec +19251 55ee +19252 55f1 +19253 55f6 +19254 55f8 +19255 5605 +19256 560d +19257..19258 5611 +19259 562c +19260 5635 +19261 5639 +19262 564d +19263 5654 +19264 5685 +19265 569f +19266 56a6 +19267 56b7 +19268 56cc +19269 56cf +19270 56d9 +19271 56e1 +19272 56eb +19273 56ed +19274 56f1 +19275 5707 +19276 570c +19277..19278 571a +19279 571d +19280 572c +19281 572e +19282..19283 573d +19284 575f +19285 576b +19286 576d +19287 577a +19288 5783 +19289 5797 +19290 57ae +19291 57d5 +19292 57e7 +19293 580d +19294 5826 +19295 584d +19296 584f +19297 585f +19298 586d +19299 587f +19300 5881 +19301 5898 +19302 58bc +19303 591f +19304 5923 +19305 5959 +19306 5979 +19307 5997 +19308 59af +19309 59b3 +19310 59df +19311 59f1 +19312 59f8 +19313 5ab2 +19314 5ab8 +19315 5aea +19316 5af6 +19317 5b1b +19318 5b1d +19319 5b21 +19320 5b38 +19321 5bb7 +19322 5bd7 +19323 5be0 +19324 5c1f +19325 5c2a +19326 5c2c +19327 5c36 +19328 5c59 +19329 5c5c +19330 5c6d +19331 5cdd +19332 5d01 +19333 5d34 +19334 5d3d +19335 5d59 +19336 5d7e +19337 5d83 +19338 5dc7 +19339 5df9 +19340 5e28 +19341 5e32 +19342 5e35 +19343 5e5b +19344 5e68 +19345 5e6a +19346 5e77 +19347 5e80 +19348 5e8b +19349 5eb3 +19350 5ebd +19351 5ed1 +19352..19353 5ed4 +19354 5f4d +19355 5fac +19356 5fea +19357 6007 +19358 6049 +19359 6054 +19360 6067 +19361 60bb +19362 60c4 +19363 60fd +19364 610a +19365 6116 +19366 612a +19367 6136 +19368 615e +19369 6164 +19370 617b +19371 617d +19372 617f +19373 619d +19374 61b8 +19375 61dc +19376 61e2 +19377 61e5 +19378 61e8 +19379 6204 +19380 6207 +19381 6231 +19382 6239 +19383 623d +19384 627a +19385 6290 +19386 62a8 +19387 62da +19388 62f4 +19389 6316 +19390 632a +19391 6336 +19392 6346 +19393 634b +19394 6353 +19395 6371 +19396 6375 +19397 637f +19398 6382 +19399 638a +19400..19401 63ae +19402 63ea +19403..19404 63f8 +19405 6412 +19406 6418 +19407 6420 +19408 6424 +19409 642a +19410 6435 +19411 643d +19412 643f +19413 6452 +19414 645f +19415 6474 +19416 6490 +19417..19418 6498 +19419 64ac +19420 64b3 +19421 64ed +19422 64f0 +19423 651b +19424 651f +19425 652e +19426 6549 +19427 6560 +19428 6592 +19429 6595 +19430 65b4 +19431 65be +19432 65c8 +19433 65ce +19434 65d0 +19435 65df +19436 667e +19437..19438 668b +19439 66b3 +19440 66c0 +19441 66cf +19442 6725 +19443 6735 +19444 6755 +19445 6780 +19446 678f +19447 6791 +19448 67a4 +19449 67b1 +19450 67b5 +19451 67be +19452 6828 +19453 6886 +19454 68eb +19455 68f5 +19456 6917 +19457 6933 +19458 6938 +19459 695b +19460 6965 +19461 69a8 +19462 69ab +19463 69af +19464 69e5 +19465 69f1 +19466 6a4a +19467 6a55 +19468 6a67 +19469 6a71 +19470 6aaf +19471..19472 6ac8 +19473 6b03 +19474 6b3b +19475 6b3f +19476..19477 6b7d +19478 6bb0 +19479 6bf7 +19480 6bf9 +19481 6c04 +19482 6c09 +19483 6c0d +19484 6c2c +19485 6c4a +19486 6c52 +19487 6c54 +19488 6c79 +19489 6cac +19490 6cb4 +19491 6cd2 +19492 6d61 +19493 6d7c +19494 6db9 +19495 6df0 +19496 6e45 +19497 6e73 +19498 6e7b +19499 6e7d +19500 6e89 +19501 6ebc +19502..19503 6eda +19504 6f26 +19505 6f29 +19506 6f30 +19507 6f87 +19508 6f9d +19509 6fae +19510 6fb7 +19511 700d +19512 7020 +19513 7049 +19514 7098 +19515 70b0 +19516..19517 70d5 +19518 7145 +19519 71b2 +19520 71f4 +19521 7217 +19522 721f +19523 7243 +19524..19525 724f +19526 725a +19527 7260 +19528 7268 +19529 7277 +19530 7284 +19531 72c9 +19532 72e5 +19533 72f4 +19534 7302 +19535 730b +19536 731e +19537 7322 +19538..19539 733a +19540 734d +19541 7358 +19542 7367 +19543 7472 +19544 74af +19545 74df +19546 74e4 +19547 74f4 +19548 74fb +19549 7516 +19550 7521 +19551 753f +19552 755e +19553 7599 +19554 75a4 +19555 75c1 +19556 75c4 +19557 75cc +19558 75d7 +19559 75dc +19560 75e1 +19561 75ef +19562 7604 +19563 760c +19564 761d +19565 7632 +19566 7638 +19567 7645 +19568 764a +19569 765f +19570 76ad +19571 76bd +19572 76d9 +19573 76eb +19574 76f0 +19575 76f9 +19576 7700 +19577 770e +19578 7722 +19579 7728 +19580 772f +19581 7739 +19582 773e +19583 7745 +19584 774a +19585 774f +19586 775e +19587 7764 +19588 7767 +19589 776c +19590 7784 +19591..19592 778c +19593 7796 +19594 77a7 +19595 77af +19596 77b7 +19597 77be +19598 77c9 +19599 77d1 +19600 77d9 +19601 77f1 +19602 7837 +19603 785c +19604 787e +19605 7898 +19606 78a1 +19607 78b1 +19608 78b3 +19609 78c9 +19610 78d3 +19611 790c +19612 791f +19613..19614 7927 +19615 793f +19616 7942 +19617 7954 +19618 796b +19619 797c +19620 79ab +19621 79c4 +19622 79ea +19623 7a02 +19624 7a0c +19625 7a30 +19626 7a3a +19627 7a44 +19628 7a80 +19629 7a86 +19630 7a94 +19631 7ab5 +19632 7abd +19633 7afe +19634 7b2b +19635 7b77 +19636 7ba0 +19637 7bac +19638 7bb0 +19639 7be8 +19640 7bf2 +19641 7bf8 +19642 7bfc +19643 7bfe +19644 7c09 +19645 7c28 +19646 7c2f +19647 7c42 +19648..19649 7c52 +19650..19652 7c5b +19653 7c72 +19654 7c7d +19655 7c87 +19656 7c9e +19657 7cba +19658 7cc7 +19659 7cd3 +19660 7cda +19661 7d3c +19662 7d4d +19663 7d82 +19664 7d85 +19665 7d8d +19666 7d91 +19667 7d9e +19668 7db3 +19669 7db9 +19670 7dd0 +19671 7de5 +19672..19673 7df5 +19674 7e2f +19675 7e36 +19676 7e44 +19677 7e6f +19678 7e78 +19679 7e81 +19680 7f3d +19681 7f5b +19682 7f5d +19683 7f65 +19684 7f71 +19685..19686 7f7f +19687 7f8b +19688 7fa2 +19689..19691 7ffd +19692 8007 +19693 800d +19694 801e +19695 8039 +19696 8088 +19697 808e +19698 80cf +19699 80d4 +19700 80ed +19701 80f0 +19702 80f7 +19703 80fa +19704 80fe +19705 8103 +19706 8117 +19707 8130 +19708 8157 +19709 816f +19710 8173 +19711 818b +19712 8190 +19713 819b +19714 819e +19715 81cb +19716 81d5 +19717..19718 81dd +19719 81e1 +19720 81ef +19721 81f6 +19722 8200 +19723 820b +19724..19725 8213 +19726 821a +19727 823a +19728 8244 +19729 826d +19730 8284 +19731 8289 +19732 8291 +19733 82aa +19734 82b0 +19735 82d0 +19736 82ea +19737 82ef +19738 82f6 +19739 8356 +19740 8378 +19741 83f8 +19742 83fc +19743 8458 +19744 8493 +19745 84b1 +19746 84bd +19747 84fb +19748 8546 +19749 8556 +19750 855d +19751 8585 +19752 8598 +19753 8642 +19754 8646 +19755 86c0 +19756 8714 +19757 8722 +19758 872e +19759 8739 +19760 875d +19761 877b +19762 878c +19763 878e +19764..19765 8797 +19766 879e +19767 87a3 +19768 87ae +19769 87bf +19770 87c9 +19771 87da +19772 8818 +19773 881b +19774 882d +19775 883a +19776 8845 +19777 884b +19778 884e +19779 8855 +19780 885a +19781 886e +19782..19784 889a +19785 88cd +19786 88e0 +19787 88ef +19788..19789 890e +19790 8926 +19791 8935 +19792 895a +19793 895c +19794 896b +19795 8970 +19796 897c +19797 89a5 +19798 89b5 +19799 89bc +19800 89d5 +19801 8a49 +19802 8a57 +19803 8a67 +19804 8a7e +19805 8a86 +19806 8a96 +19807 8ab6 +19808 8ac9 +19809 8ad1 +19810 8add +19811 8aec +19812 8af5 +19813 8b06 +19814 8b0f +19815 8b11 +19816 8b45 +19817 8b52 +19818 8b6d +19819 8b78 +19820 8b7c +19821 8b7e +19822 8b85 +19823 8b9f +19824 8c4b +19825 8c53 +19826 8c7b +19827 8cba +19828 8cc5 +19829 8cc9 +19830 8cd2 +19831 8cec +19832 8cf5 +19833 8cf7 +19834 8d01 +19835 8d03 +19836 8d17 +19837 8d1c +19838 8d6e +19839 8d91 +19840 8d9f +19841 8dab +19842 8db2 +19843 8dd5 +19844 8de7 +19845..19846 8df1 +19847 8df4 +19848 8e01 +19849 8e0b +19850 8e26 +19851 8e31 +19852..19853 8e40 +19854 8e4d +19855 8e4f +19856 8e5c +19857 8e61 +19858 8e69 +19859 8e71 +19860 8e75 +19861 8e77 +19862 8e89 +19863 8e90 +19864 8e95 +19865 8e9a +19866 8ea7 +19867 8ea9 +19868 8ead +19869 8ee8 +19870 8ef0 +19871 8f07 +19872 8f18 +19873 8f25 +19874 8f27 +19875 8f2c +19876 8f35 +19877 8f3a +19878 8f43 +19879 8f47 +19880 8f51 +19881 8f55 +19882..19884 8fa0 +19885 8fa5 +19886 9004 +19887 901b +19888 902f +19889 904c +19890 905b +19891 9070 +19892 9074 +19893 9079 +19894 908b +19895 9098 +19896 90a0 +19897 90b2 +19898 90bd +19899 90c9 +19900 90f0 +19901 9105 +19902 9125 +19903 915a +19904 9167 +19905 917a +19906 918a +19907 9191 +19908 9195 +19909 91b0 +19910 91bb +19911 91bd +19912 91c2 +19913 91c5 +19914 9200 +19915 9209 +19916 9223 +19917 9276 +19918 928e +19919 92af +19920..19921 92bb +19922 92c1 +19923 92c3 +19924 92c5 +19925 92c8 +19926 9314 +19927 9333 +19928 9336 +19929 9358 +19930 937f +19931 9382 +19932 938a +19933 93bb +19934 93cc +19935 93e6 +19936 93f9 +19937 9402 +19938..19939 940d +19940 942e +19941 944c +19942 9588 +19943 95a1 +19944 95bf +19945 95c6 +19946 95c9 +19947..19948 95d1 +19949 95e0 +19950 95e4 +19951 95e6 +19952 9624 +19953 9631 +19954 9638 +19955 963d +19956 9654 +19957 9674 +19958 967b +19959 967f +19960 9681 +19961 9683 +19962 9689 +19963 9696 +19964 96ae +19965 9703 +19966 971b +19967..19968 9721 +19969 9728 +19970 9731 +19971 9767 +19972 9776 +19973 977d +19974 977f +19975 9799 +19976 979f +19977 97ac +19978 97b9 +19979 97cd +19980 97e0 +19981 97ef +19982 9807 +19983 9826 +19984 982e +19985..19986 9862 +19987 98b4 +19988 98c5 +19989 9902 +19990 9911 +19991 9915 +19992 9935 +19993 9948 +19994 9954 +19995 995e +19996 99e1 +19997 9a0c +19998 9a10 +19999 9a23 +20000 9a41 +20001 9a51 +20002..20003 9abd +20004 9b01 +20005 9b09 +20006 9b0b +20007..20008 9b0d +20009 9b19 +20010 9b35 +20011 9b48 +20012 9b55 +20013 9b68 +20014 9b80 +20015 9b86 +20016 9b90 +20017 9b9d +20018 9bb0 +20019 9bbf +20020 9bc8 +20021 9bff +20022 9c02 +20023 9c1c +20024 9c35 +20025 9c44 +20026 9c56 +20027 9c61 +20028 9c68 +20029 9d30 +20030 9d3d +20031 9d6a +20032 9d7b +20033 9de5 +20034 9de9 +20035 9df3 +20036 9e7a +20037..20039 9e82 +20040 9eb0 +20041 9ee4 +20042 9ef0 +20043 9ef2 +20044 9f09 +20045 9f0f +20046 9f14 +20047 9f1b +20048 9f22 +20049 9f26 +20050..20051 9f2a +20052 9f34 +20053 9f5a +20054 9f6f +20055 9f9e +20056 9fa5 +20057 200f5 +20058 24e04 +20059 24ff2 +20060 27d73 +20061 2f815 +20062 2f846 +20063 2f899 +20064 2f8a6 +20065 2f8e5 +20066 2f9de +20067 35de +20072 2a2b2 +20075 20158 +20080 205b1 +20083 206ec +20090 20d58 +20112 259cc +20122 39a4 +20123 39b8 +20124 22e42 +20127 3a5c +20130 22feb +20133 279b4 +20135 3ac4 +20136 3acb +20142 3a85 +20151 3bf3 +20152 6af8 +20158 3d31 +20168 2404b +20170 3e40 +20171 38a1 +20206 26c9e +20219 471f +20220 27c3c +20225 481e +20297 9b1d +20298 9b2c +20299 /uni5002.dup2 +20300 /uni51DE.dup2 +20301 /uni5307.dup2 +20302 /uni5BEC.dup2 +20303 f928 +20304 /uni661E.dup2 +20305 /uniF929.dup2 +20306 /uni704A.dup2 +20307 /uniFA15.dup2 +20308 /uni5561.dup2 +20309 6c3a +20310 /uni7A60.dup2 +20311 2634c +20312 /uni8803.dup2 +20313 /uni95AB.dup2 +20314 /uni9755.dup2 +20315 29e3d +20316 2a61a +20317..20318 0384 +20322 0110 +20323 0126 +20324 0132 +20325 013f +20326 014a +20327 0166 +20328 0133 +20329 0138 +20330 0140 +20331 0149 +20332 0167 +20333 010a +20334 0116 +20335 011e +20336 0122 +20337 0120 +20338 0130 +20339 012e +20340 0136 +20342 013b +20343 0145 +20344 0156 +20345 0172 +20346 01d7 +20347 01db +20348 01d9 +20349 01d5 +20350 0174 +20351 0176 +20352 010b +20353 0117 +20354 01f5 +20355 011f +20356 0121 +20357 012f +20358 0137 +20360 013c +20361 0146 +20362 0157 +20363 0173 +20364 0175 +20365 0177 +20366 212e +20367 2206 +20368 220f +20369..20370 2264 +20371 25ca +20427 0386 +20428..20430 0388 +20431 03aa +20432 038c +20433 038e +20434 03ab +20435 038f +20436..20439 03ac +20440 03ca +20441 0390 +20442..20443 03cc +20444 03cb +20445 03b0 +20446 03ce +20447..20457 0402 +20458..20459 040e +20460..20470 0452 +20471..20472 045e +21075 4e35 +21076 4e5c +21077 4e63 +21078 4e68 +21079..21080 4e74 +21081 4e97 +21082 4eaf +21083 4edb +21084 4ee2 +21085 4ee8 +21086 4eef +21087 4efe +21088 4f02 +21089 4f08 +21090 4f12 +21091 4f17 +21092 4f33 +21093 4f35 +21094 4f40 +21095 4f42 +21096..21097 4f4b +21098 4f52 +21099 4f63 +21100 4f6e +21101 4f71 +21102 4f79 +21103 4f81 +21104 4f89 +21105 4f8c +21106 4f8e +21107 4f90 +21108 4f93 +21109 4f99 +21110 4f9f +21111 4fb9 +21112..21114 4fbb +21115..21116 4fc0 +21117 4fc6 +21118 4fc8 +21119 4fcc +21120 4fdc +21121 4fe2 +21122 4ff0 +21123 4ffc +21124 5007 +21125 500a +21126 5017 +21127 501d +21128 5030 +21129..21130 5032 +21131 5035 +21132 5045 +21133 504a +21134..21135 5051 +21136 5059 +21137 5060 +21138 5067 +21139 506d +21140 5071 +21141 5081 +21142..21143 5083 +21144 5086 +21145 508a +21146 5090 +21147 509b +21148..21150 509f +21151..21152 50af +21153 50b9 +21154 50bd +21155 50c0 +21156 50d3 +21157..21158 50dc +21159 50df +21160 50e2 +21161 50e4 +21162 50f6 +21163 50fa +21165 5119 +21166..21167 511c +21168 5123 +21169..21170 5127 +21171..21172 512c +21173 512f +21174 5131 +21175 5134 +21176 5139 +21177 5142 +21178 514f +21179 5153 +21180 5158 +21181 5166 +21182 517e +21183 518e +21184 51bf +21185 51c2 +21186 51d2 +21187 51d5 +21188 51e5 +21189 51f2 +21190 51f7 +21191 5218 +21192 5222 +21193 5245 +21194 5258 +21195 525f +21196 5280 +21197 5285 +21198..21200 5295 +21201 529a +21202 52a5 +21203 52a7 +21204 52b0 +21205..21207 52b6 +21208 52bd +21209 52c4 +21210 52c6 +21211 52cf +21212 52d4 +21213 52dc +21214 52e5 +21215 52e8 +21216 52ea +21217 52ec +21218 52f4 +21219 52f6 +21220 530c +21221 5313 +21222 5318 +21223 531b +21224 531e +21225 5325 +21226..21228 5327 +21229..21230 532b +21231 5330 +21232 533c +21233 5359 +21234 535b +21236 5383 +21237..21238 5387 +21239 538e +21240 53a1 +21241 53b5 +21242 53b8 +21243 53bd +21244 53cf +21245..21246 53d2 +21247 53de +21249 53e7 +21250 5402 +21251 541a +21252 5421 +21253 542f +21254 5444 +21255 5447 +21256 544f +21257 545e +21258 5464 +21259 5467 +21260 5469 +21261..21262 546d +21263 5481 +21264 5483 +21265 5485 +21266 5489 +21267 5491 +21268 549f +21269 54ca +21270 54e0 +21271 54f6 +21272 54fe +21273..21274 550c +21275 5532 +21276 553b +21277 553d +21278 5549 +21279 554d +21280 5558 +21281..21282 555a +21283 557f +21284 5593 +21285 5597 +21286 55a3 +21287 55c1 +21288 55cb +21289..21290 55d7 +21291 55de +21292 55ff +21294 560a +21295 5619 +21296 5633 +21297 563c +21298 5641 +21299..21300 5643 +21301 5646 +21302..21304 5661 +21305 5675 +21306 5684 +21307 568b +21308 56a7 +21309 56ab +21310 56be +21311 56cb +21312 56d0 +21313 56dc +21314..21316 56e5 +21317..21318 5701 +21319 5711 +21320 5720 +21321 5722 +21322..21323 5724 +21324 572a +21325 573f +21326 5752 +21327 5762 +21328 5767 +21329 576e +21330 5771 +21331 5779 +21332 577e +21333 5781 +21334 5794 +21335 5799 +21336 579f +21337 57a1 +21338 5795 +21339 57a7 +21340 57a9 +21341 57bd +21342 57dd +21343 57e9 +21344 57fe +21345 5803 +21346 5808 +21347 57e1 +21348 580c +21349 581b +21350 581f +21351 582d +21352 583f +21353 5850 +21354 5855 +21355 5868 +21356 5878 +21357..21358 5887 +21359 588c +21360 5896 +21361..21363 58a0 +21364 58a6 +21365 58c4 +21366 58c2 +21367 58c8 +21368 58d6 +21369 58dd +21370 58e1 +21372..21373 5912 +21374 591d +21375 5921 +21376 5928 +21377 5930 +21378 5933 +21379..21380 5935 +21381 593f +21382 5943 +21383 5952 +21384 595e +21385 596b +21386 596f +21387 5972 +21388 597b +21389 598c +21390 598e +21391 5995 +21392 59a7 +21393 59ad +21394 59b0 +21395 59b7 +21396 59c1 +21397 59c4 +21398 59ef +21399 59f2 +21400 59f4 +21401 59f7 +21402 5a00 +21403 5a0e +21404 5a12 +21405 5a1e +21406 5a24 +21407 5a28 +21408 5a2a +21409 5a30 +21410..21411 5a44 +21412 5a48 +21413 5a4c +21414 5a50 +21415 5a5e +21416 5a7b +21417 5a90 +21418 5a93 +21419 5a96 +21420 5a99 +21421 5abb +21422 5ac6 +21423 5ac8 +21424 5acf +21425 5afd +21426 5b01 +21427 5b4b +21428 5b5e +21429 5b6e +21430 5b86 +21431 5b8e +21432..21433 5b90 +21434 5b94 +21435..21436 5ba8 +21437 5bad +21438 5baf +21439..21440 5bb1 +21441 5bba +21442 5bbc +21443 5bc1 +21444 5bcd +21445 5bcf +21446..21447 5bd9 +21448 5bef +21449 5bf4 +21450 5c0c +21451 5c17 +21452 5c26 +21453 5c2e +21454 5c32 +21455 5c35 +21456 5c5a +21457..21458 5c74 +21459 5c7b +21460 5c7d +21461 5c87 +21462 5c92 +21463 5c9d +21464 5cb2 +21465 5cb4 +21466 5cd7 +21467 5cee +21468..21469 5cf1 +21470 5d12 +21471 5d23 +21472 5d3f +21473 5d48 +21474 5d55 +21475 5d51 +21476..21477 5d5f +21478 5d62 +21479 5d64 +21480..21481 5d79 +21482 5d7f +21483 5d8a +21484 5d93 +21485 5d95 +21486 5d9b +21487 5d9f +21488 5dab +21489 5dc3 +21490 5dce +21491 5dd9 +21492 5e07 +21493 5e0d +21494 5e20 +21495 5e4b +21496..21497 5e50 +21498 5e5c +21499 5e70 +21500 5e8e +21501 5ea2 +21502 5ea4 +21503 5eb1 +21504 5ecc +21505 5ece +21506 5edc +21507 5ede +21508 5ee5 +21509 5eeb +21510 5f06 +21511 5f19 +21512 5f24 +21513..21514 5f2b +21515 5f2e +21516 5f30 +21517 5f3f +21518 5f44 +21519 5f5b +21520 5f60 +21521 5f6f +21522..21523 5f74 +21524 5f78 +21525 5f7a +21526 5f8d +21527 5f96 +21528 5f9d +21529 5fab +21530..21531 5fb0 +21532 5fc8 +21533..21534 5fd0 +21535 5fe8 +21536 5fec +21537 5ff2 +21538 5ff6 +21539 5ffa +21540 600a +21541 6013 +21542 601f +21543 602d +21544 6040 +21545 6048 +21546 6051 +21547..21548 6056 +21549 6071 +21550 607e +21551 6082 +21552 6086 +21553 6088 +21554 608e +21555 6091 +21556 6093 +21557 6098 +21559 60a2 +21560 60a5 +21561 60b7 +21562 60c2 +21563..21564 60c9 +21565..21566 60ce +21567 60e2 +21568 60e5 +21569 60fc +21570 6102 +21571 6107 +21572 610c +21573 6117 +21574 6122 +21575 6131 +21576 6135 +21577 6139 +21578 6145 +21579 6149 +21580 616c +21581 6172 +21582 6178 +21583..21584 6180 +21585..21586 6183 +21587 618b +21588 619c +21589 61a0 +21590 61aa +21591..21592 61c0 +21593..21594 61ce +21595 61de +21596 61e1 +21597 61e7 +21598 61e9 +21599..21600 61ec +21601 61ef +21602 6201 +21603 6203 +21604 621c +21605 6220 +21606 6227 +21607 622b +21608 6242 +21609 6244 +21610 6250 +21611 6254 +21612 625c +21613 627d +21614..21616 628d +21617 62b3 +21618..21619 62b6 +21620 62ba +21621..21622 62be +21623 62ce +21624 62ea +21625 62f2 +21626 6304 +21627 630b +21628 6313 +21629 6329 +21630 632d +21631 634a +21632 6352 +21633 6354 +21634 6358 +21635 635b +21636 6366 +21637 636d +21638 6378 +21639 6395 +21640 639a +21641 63a4 +21642 63a6 +21643 63ad +21644 63c1 +21645 63c5 +21646 63c8 +21647 63ce +21648 63d3 +21649 63f3 +21650 640a +21651 6430 +21652 644b +21653 644f +21654 6453 +21655 645c +21656 6461 +21657 6463 +21658 6485 +21659 648f +21660 649b +21661 64a1 +21662 64a3 +21663 64a6 +21664 64a8 +21665 64bd +21666 64c9 +21667 64d1 +21668..21669 64e9 +21670 64f5 +21671 6501 +21672..21674 6508 +21675 6513 +21676 6526 +21677 6531 +21678 653a +21679..21680 653c +21681 6543 +21682 6550 +21683 6552 +21684 655f +21685 657d +21686 6598 +21687 65a0 +21688 65a3 +21689 65a6 +21690 65ae +21691 65b3 +21692 65d6 +21693 65d8 +21695..21696 65f4 +21697..21698 65fe +21699 660d +21700..21701 6611 +21702 6616 +21703 661d +21704 6623 +21705 6626 +21706 6629 +21707 6639 +21708 6637 +21709 6640 +21710 6646 +21711 664a +21712 6658 +21713 6660 +21714 6675 +21715 667f +21716 6679 +21717 667c +21718..21720 669a +21721 669f +21723..21724 66c2 +21725 66cc +21726 66ce +21727 66d4 +21728 66df +21729 66eb +21730 66ee +21731 6707 +21732 671c +21733 6720 +21734 6722 +21735 673e +21736 6745 +21737 676c +21738 6784 +21739 678e +21740 6796 +21741 6799 +21742..21743 67bc +21744 67c2 +21745 67c5 +21746 67c9 +21747 67dc +21748 67e1 +21749 67e6 +21750 67f2 +21751 67f6 +21752 6814 +21753 6819 +21754 6827 +21755 682f +21756 683f +21757 684a +21758 6858 +21759..21761 686f +21762 6879 +21763 687b +21764 6888 +21765 68a1 +21766 68a9 +21767 68ae +21768 68d1 +21769 68d3 +21770..21771 68dc +21772 68ea +21773 68f6 +21774 68fd +21775 6906 +21776 6909 +21777 6910 +21778 6916 +21779 6931 +21780 6945 +21781 694e +21782 6966 +21783..21784 6970 +21785 697b +21786 698d +21787 69a1 +21788 69b8 +21789 69c5 +21790 69c8 +21792 6a00 +21793 6a03 +21794 6a20 +21795 6a24 +21796 6a37 +21798 6a6a +21799 6a81 +21800..21801 6a86 +21802 6a9b +21803..21804 6ab0 +21805 6ab4 +21806..21807 6abe +21808 6acc +21809..21810 6ad5 +21811 6af0 +21812 6afc +21813 6b02 +21814..21815 6b06 +21816 6b09 +21817 6b28 +21818 6b2b +21819 6b36 +21820 6b4d +21821 6b52 +21822 6b5d +21823 6b6b +21824 6b6e +21825 6b70 +21826 6b85 +21827 6b97 +21828..21829 6b9f +21830..21831 6ba2 +21832 6ba8 +21833 6bac +21834..21835 6bb8 +21836..21837 6bc3 +21838 6be3 +21839 6c12 +21840 6c19 +21841 6c1f +21842..21844 6c26 +21845 6c2e +21846 6c3b +21847 6c4b +21848 6c4f +21849 6c6b +21850 6c78 +21851 6c87 +21852 6c9f +21853 6cb0 +21854 6cb2 +21855 6ccd +21856 6ccf +21857 6cd1 +21858 6ce7 +21859 6cf2 +21860 6cf4 +21861 6d07 +21862 6d0f +21863 6d13 +21864 6d1a +21865 6d28 +21866 6d5f +21867 6d67 +21868 6d92 +21869 6d97 +21870 6db7 +21871 6dbd +21872 6de0 +21873 6de2 +21874 6de5 +21875 6def +21876 6df4 +21877 6e00 +21878 6e04 +21879 6e3b +21880 6e52 +21881 6e5d +21882 6e62 +21883 6e68 +21884 6e8d +21885 6e99 +21886 6ea0 +21887..21888 6ead +21889 6eb3 +21890 6ebb +21891 6ec0 +21892 6ec8 +21893 6ecd +21894 6ecf +21895..21896 6eed +21897 6f04 +21898 6f08 +21899 6f0d +21900 6f16 +21901 6f1b +21902 6f3b +21903 6f2d +21904 6f4f +21905 6f53 +21906 6f5d +21907 6f6c +21908 6f83 +21909 6f93 +21910 6fa6 +21911 6fb0 +21912 6fc5 +21913 6fe8 +21914 6ffd +21915 7017 +21916 702f +21917 7034 +21918 7037 +21919 7044 +21920 7048 +21921 7055 +21922 7094 +21923 7096 +21924 709b +21925 70b4 +21926 70fa +21927 7105 +21928 710b +21929 712d +21930 7138 +21931 7141 +21932 714b +21934 7157 +21935 715a +21936 718c +21937 719a +21938 71b0 +21939..21940 71bf +21941 71cc +21942 71da +21943 71f8 +21944..21945 7208 +21946 7213 +21947 721a +21948 7224 +21949 722f +21950 7245 +21951 724e +21952 725e +21953 726b +21954 7271 +21955..21956 727b +21957 7289 +21958 7293 +21959 72a8 +21960..21961 72d5 +21962 72d8 +21963 72df +21964 72fe +21965 730d +21966 7313 +21967 7332 +21968 7335 +21969 7356 +21970..21973 735d +21974 7369 +21975 7379 +21976 7380 +21977 738e +21978 7390 +21979 7393 +21980 7397 +21981 73aa +21982 73ad +21983 73c6 +21984 73cc +21985 73d3 +21986 73dd +21987 73e6 +21988 73f7 +21989 73fb +21990..21991 73ff +21992 7411 +21993 742d +21994..21995 7467 +21996 746e +21997 748f +21998 7491 +21999 749a +22000 74ae +22001..22002 74b1 +22003 74cc +22004 74d0 +22005 74d3 +22007 74db +22008 74e8 +22009 74ea +22011 74fc +22012 7506 +22013 7512 +22014 7527 +22015 7529 +22016 7536 +22017 7539 +22018 7543 +22019 7547 +22020 7557 +22021 755f +22022 7561 +22023..22024 757b +22025 7585 +22026 7595 +22027 759c +22028 75ba +22029 7612 +22030 7623 +22031 7629 +22032..22033 7639 +22034 7640 +22035 7644 +22036 7659 +22037 7685 +22038..22039 768c +22040 769f +22041..22042 76a2 +22043 76c1 +22044 76cb +22046 76e0 +22047 76f6 +22048 7706 +22049 7712 +22050..22051 7714 +22052 771c +22053 772e +22054 773d +22055 7742 +22056 7752 +22057..22058 7756 +22059 7770 +22060..22061 7773 +22064 77ae +22065 77b1 +22066 77b5 +22067 77c3 +22068 77d2 +22069 77d5 +22070 77f8 +22071 780e +22072 7811 +22073 781d +22074 7823 +22075 7844 +22076 7848 +22077 784c +22078 7852 +22079 785e +22080..22081 7860 +22082 7863 +22083 788f +22084 78a8 +22085 78ac +22086 78b2 +22087 78bd +22088 78bf +22089 78c7 +22090 78d2 +22091 78d6 +22092 78db +22093 78df +22094 78ea +22095 78f3 +22096 78f6 +22097 78ff +22098 7906 +22099 791a +22100 791e +22101 7920 +22102 7929 +22103 792d +22104 7935 +22105 7944 +22106 794b +22107 794f +22108 7951 +22109 7969 +22110 797b +22111 797e +22112 798c +22113 7991 +22114 7993 +22115 799c +22116 79a8 +22117 79af +22118 79cf +22119 79dd +22120 79e0 +22121 79e2 +22122 79e5 +22123 79f1 +22124 79f8 +22125 79fc +22126 7a07 +22127 7a21 +22128 7a27 +22129 7a2b +22130 7a2f +22131..22132 7a34 +22133 7a48 +22134 7a55 +22135 7a65 +22136 7a7e +22137 7a8b +22138 7a91 +22139 7a9e +22140 7ac9 +22141 7adb +22142 7ae9 +22143 7aec +22144 7af1 +22145 7afb +22146 7b1f +22147 7b23 +22148 7b29 +22149 7b30 +22150 7b34 +22151..22152 7b3f +22153 7b6a +22154 7b84 +22155 7b89 +22156 7b8e +22157 7b96 +22158 7ba5 +22159 7bb2 +22160 7bb6 +22161..22162 7bba +22163 7bbd +22164 7bc2 +22165 7bc8 +22166 7bdb +22167..22168 7bf4 +22169..22170 7bf9 +22171 7c02 +22172 7c04 +22173 7c06 +22174 7c0c +22175 7c19 +22176 7c1b +22177 7c25 +22178 7c2c +22179 7c34 +22180..22181 7c39 +22182 7c46 +22183 7c55 +22184 7c5a +22185 7c63 +22187 7c7c +22188 7c86 +22189 7cb0 +22190 7cbb +22191 7ccf +22192 7cd4 +22193 7ce9 +22194 7d0f +22195 7d11 +22196 7d16 +22197 7d26 +22198 7d2a +22199 7d2d +22200 7d51 +22201 7d57 +22202 7d65 +22203 7d67 +22204 7d78 +22205 7d7b +22206 7d81 +22207 7d96 +22208..22211 7dc3 +22212..22213 7dcd +22214 7e00 +22215 7de2 +22216 7dea +22217 7ded +22218 7dfa +22219 7e1c +22220 7e2d +22221 7e33 +22222 7e3f +22223 7e4e +22224 7e50 +22225 7e58 +22226 7e5f +22227 7e65 +22228 7e95 +22229..22230 7e9d +22231 7f3f +22232 7f5c +22233 7f66 +22235 7f8d +22236 7f8f +22237 7fa6 +22238 7faa +22239 7fb4 +22240 7fbc +22241 7fc0 +22242 7fc8 +22243 7fe8 +22244 800f +22245 8013 +22246 801d +22247..22248 801f +22249 802e +22250 8034 +22251 803e +22252 8040 +22253 8044 +22254 8064 +22255 806d +22256 8081 +22257 80b9 +22258 80c8 +22259 80cd +22260 80d2 +22261 80ee +22262 80f2 +22263 80f6 +22264 80f9 +22265 810b +22266 811c +22267 8120 +22268 813c +22269 8145 +22270 8147 +22271 8152 +22272 8161 +22273 8177 +22274 8186 +22275 818e +22276 8196 +22277 81a2 +22278 81ae +22279 81c5 +22280 81ce +22281 81eb +22282..22284 81f0 +22285 81f5 +22286 81f8 +22288 820f +22289 821d +22290 8228 +22291 8243 +22292 824e +22293 8251 +22294 8256 +22295 8267 +22296 827b +22297..22298 8280 +22299 8287 +22300 8294 +22301 8296 +22302 8298 +22303..22304 829a +22305 82a0 +22306 82da +22307 82e0 +22308 82e4 +22309 82ed +22310..22311 830a +22312..22313 831e +22314 8321 +22315 832c +22316 832e +22317 8333 +22318 8337 +22319 833d +22320 8342 +22321..22322 834d +22323 8370 +22324 8380 +22325 8382 +22326 8384 +22327 8399 +22328 839c +22329 83a6 +22330 83ac +22331 83be +22332 8353 +22333 83e8 +22334 8419 +22335 83ad +22336 842f +22337 8445 +22338 8447 +22339 844d +22340 8456 +22342 8460 +22343 8464 +22344 8467 +22345 846a +22346 8474 +22347 847d +22348 8492 +22349 8495 +22350..22351 84a9 +22352..22353 84c7 +22354 84cc +22355 84f2 +22356 84f7 +22357..22358 8502 +22359 8507 +22360 850e +22361 8510 +22362 851c +22363 8522 +22364 8527 +22365 852a +22366 8533 +22367 8536 +22368 853f +22369 8550 +22370 8552 +22371 855c +22373..22374 855f +22375 8579 +22376 8589 +22377 858b +22378 85a0 +22379 85a5 +22380 85a7 +22381 85b4 +22382 85b6 +22383 85b8 +22384..22386 85bd +22387 85c2 +22388 85da +22389 85e0 +22390 85e8 +22391 85f3 +22392 85fc +22393..22394 860d +22395 8619 +22396 861b +22397 8636 +22398 863a +22399 863d +22400..22401 8658 +22402 865d +22403..22404 8660 +22405 8664 +22406 8669 +22407 8676 +22408 8696 +22409 869a +22410 86a1 +22411 86a6 +22412 86ad +22413..22414 86b4 +22415 86b7 +22416 86b9 +22417 86bf +22418 86c5 +22419 86d2 +22420 86da +22421 86dc +22422 86e0 +22423 86e5 +22424 86e7 +22425 8688 +22426 8704 +22427 870f +22428 872f +22429 8732 +22430..22431 873c +22432 8745 +22433 874d +22434 8761 +22435 876f +22436..22439 8783 +22440 8790 +22441 8795 +22443 87b1 +22444 87c8 +22445 87ca +22446 87d5 +22447 87d9 +22448 87dc +22449 87e2 +22450 87e4 +22451 87f1 +22452 87f3 +22453 87f8 +22454 87fa +22455 87ff +22456 8809 +22457 8819 +22458 8812 +22459 881a +22460 881e +22461 8830 +22462 8835 +22463 8841 +22464 8843 +22465..22466 8848 +22468 8851 +22469 885c +22470 8860 +22471 8871 +22472 8879 +22473 887b +22474 8880 +22475 889f +22476 88a8 +22477 88ba +22478..22479 88cb +22480 88de +22481 88e7 +22482 88f7 +22483 890d +22484..22485 8915 +22486 8920 +22487 8928 +22488 8931 +22489 893a +22490 8946 +22491 894f +22492 8952 +22493 8957 +22494 895b +22495 8961 +22496 8963 +22497 896e +22498 8973 +22499 8975 +22500 897a +22501 897d +22502 898d +22503 8995 +22504..22505 899b +22506 89a0 +22507 89b4 +22508 89b6 +22509 89d7 +22510 89e9 +22511 89ed +22512 89f9 +22513..22514 8a04 +22515 8a1e +22516 8a20 +22517 8a24 +22518 8a26 +22519..22520 8a2b +22521 8a2f +22522 8a3d +22523 8a40 +22524 8a43 +22525 8a53 +22526 8a56 +22527 8a5c +22528 8a65 +22529..22530 8a76 +22531..22532 8a7a +22533 8a80 +22534 8a83 +22535 8a8b +22536 8a8f +22537 8a92 +22538 8a97 +22539 8a99 +22540 8a9f +22541 8aa9 +22542 8aaf +22543 8ab3 +22544 8abb +22545 8ac3 +22546 8ac6 +22547 8ac8 +22548 8aca +22549..22551 8ad3 +22552 8af0 +22553 8aff +22554 8b0b +22555 8b1e +22556 8b30 +22557 8b3c +22558 8b42 +22559 8b48 +22560 8b4d +22561 8b63 +22562 8b79 +22563 8b84 +22564 8b8d +22565 8b8f +22566 8c38 +22567 8c3e +22568 8c51 +22569 8c58 +22570 8c5b +22571 8c5d +22572 8c59 +22573..22574 8c63 +22575 8c66 +22576..22577 8c75 +22578 8c7e +22579..22580 8c86 +22581 8c8b +22582 8c90 +22584 8c9c +22585 8cb9 +22586 8cc6 +22587 8ccb +22588 8ccf +22589 8cdd +22590 8ce8 +22591 8cef +22592 8cf2 +22593 8cff +22594 8d65 +22595 8d7f +22596 8d82 +22597 8d88 +22598 8d90 +22599 8d9e +22600 8da0 +22601 8dac +22602 8db5 +22603 8db7 +22604 8db9 +22605 8dbb +22606 8dc0 +22607 8dc5 +22608 8dc7 +22609 8dca +22610 8dd4 +22611 8de5 +22612 8df0 +22613 8dbc +22614..22615 8e04 +22616 8e11 +22617 8e33 +22618..22619 8e37 +22620 8e4e +22621 8e5b +22622..22623 8e5d +22624 8e79 +22625..22626 8e82 +22627 8e9b +22628 8e9d +22629 8ea2 +22630 8eba +22631 8ec1 +22632..22633 8ec3 +22634 8ec7 +22635 8edc +22636 8eee +22637 8ef1 +22638 8ef7 +22639 8eed +22640 8f02 +22641..22642 8f0f +22643 8f16 +22644..22645 8f20 +22646 8f23 +22647 8f28 +22648 8f2e +22649 8f34 +22650 8f37 +22651 8f41 +22652 8f4f +22653..22654 8f52 +22655..22656 8f5d +22657 8f65 +22658 8f9d +22659 8fb8 +22660 8fbe +22661 8fc0 +22662 8fcb +22663 8fd0 +22664 8fd2 +22665 8fe3 +22666 8ffe +22667 9018 +22668..22670 9028 +22671..22672 9033 +22673 903f +22674 9062 +22675 9066 +22676 906c +22677 908e +22678 90a5 +22679 90cc +22680 90d5 +22681..22682 90d8 +22683 90e5 +22684 90d2 +22685 9108 +22686 910d +22687 9110 +22688 911a +22689 9120 +22690 9129 +22691 912e +22692 9136 +22693 913c +22694 9143 +22695 914f +22696 9153 +22697 916d +22698 917b +22699 9181 +22700 9186 +22701..22702 9193 +22703 9198 +22704 91a1 +22705 91a6 +22706 91bf +22707..22708 91d3 +22709 91d9 +22710..22711 91e9 +22712 91ef +22713 91f9 +22714 91fd +22715..22716 9204 +22717 920c +22718..22719 9212 +22720 9218 +22721..22722 921c +22723..22725 9224 +22726..22728 922e +22729..22730 9235 +22731 923e +22732 9246 +22733 924d +22734 9258 +22735..22736 925c +22737 9269 +22738..22740 926e +22741 9275 +22742 9279 +22743 927b +22744 928a +22745 9292 +22746 92a0 +22747..22748 92a4 +22749 92a8 +22750 92b6 +22751 92b8 +22752 92ba +22753 92bd +22754 92c7 +22755 92cd +22756 92d8 +22757..22758 92dc +22759 92e1 +22760 92e3 +22761 92e8 +22762 92ec +22763 92ee +22764 92f0 +22765 9300 +22766 9308 +22767 931c +22768 9324 +22769 932a +22770 9334 +22771 9337 +22772 9350 +22773 9355 +22774 935e +22775 9367 +22776 9369 +22777 936f +22778 9374 +22779 9376 +22780 937a +22781 937d +22782..22783 9380 +22784 938d +22785 9392 +22786 9395 +22787 9398 +22789 93a6 +22790 93a8 +22791 93ab +22792..22794 93b4 +22795..22796 93c4 +22797 93c9 +22798 93cb +22799 93cd +22800 93d3 +22801 93d9 +22802 93f7 +22803 9401 +22804 9408 +22805 9415 +22806 941f +22807 942f +22808 943d +22809 9443 +22810 9459 +22811 945c +22812 945f +22813 9461 +22814 9468 +22815 946e +22816 9484 +22817 9483 +22818 957e +22819 9584 +22820..22821 959d +22822 95ba +22823 95d9 +22824 95dd +22825 95df +22826 961e +22827 9622 +22828..22829 9625 +22830 9637 +22831..22832 9639 +22833 9652 +22834..22835 9656 +22836 966e +22837 967c +22838 967e +22839 9691 +22840 969f +22841 96a6 +22842 96ca +22844 96df +22845 96fa +22846 9705 +22847 971a +22848 971d +22850 974a +22851 9758 +22852..22853 9777 +22854 977b +22855 9780 +22856 9789 +22857 9797 +22858 97b8 +22859 97bc +22860 97bf +22861..22862 97c4 +22863 97c7 +22864 97ca +22865 97ce +22866 97d0 +22867 97d7 +22868 97dd +22869 97e4 +22870..22871 97f7 +22872 97fa +22873 9819 +22874 981c +22875 9820 +22876 982f +22877 9835 +22878 9844 +22879 984a +22880 9851 +22881 986a +22882 98ae +22883 98cc +22884 98e6 +22885 98f6 +22886 9907 +22887 991f +22888 9922 +22889 9926 +22890 992b +22891 9934 +22892 9939 +22893 9947 +22894 9959 +22895 995b +22896 999b +22897 999d +22898 999f +22899 99b0 +22900 99b2 +22901 99b5 +22902 99d3 +22903 99da +22904 99dc +22905 99e7 +22906..22908 99ea +22909..22910 99f4 +22911..22912 99fd +22913 9a04 +22914 9a0b +22915 9a1e +22916 9a22 +22917 9a33 +22918 9a35 +22919 9a47 +22921 9a4b +22922 9a54 +22923 9a5d +22924 9aaa +22925 9aac +22926 9aae +22927 9ab2 +22928 9ab4 +22929 9abb +22930 9abf +22931 9ac8 +22932 9ad7 +22933 9adb +22934 9ae4 +22935 9ae7 +22936 9aec +22937..22938 9af2 +22939 9af5 +22940 9afa +22941 9afd +22942..22943 9aff +22944..22945 9b04 +22946 9b1b +22947 9b26 +22949 9b37 +22950..22951 9b39 +22952 9b4c +22953..22954 9b56 +22955 9b5b +22956 9b61 +22957 9b6a +22958..22959 9b6d +22960 9b78 +22961 9b7f +22962 9b85 +22963 9b87 +22964 9b89 +22965 9b8b +22966 9b8d +22967 9b94 +22968 9b9a +22969 9ba9 +22970 9bb7 +22971 9bbc +22972 9bd0 +22973 9bf9 +22974 9c0f +22975 9c11 +22976 9c1e +22977 9c26 +22978 9c28 +22979 9c3d +22980 9c43 +22981 9c4e +22982 9c5e +22983 9c7b +22984 9cf7 +22985 9cf9 +22986 9d1c +22987 9d2f +22988..22989 9d33 +22990 9d3a +22991 9d3c +22992 9d45 +22993..22994 9d53 +22995 9d65 +22996 9d83 +22997 9d86 +22998 9d8e +22999..23000 9d92 +23001 9d95 +23002..23003 9d97 +23004 9daa +23005 9dae +23007 9dca +23008..23009 9dd4 +23010 9dde +23011 9dee +23012 9df0 +23013 9dfe +23014 9e0e +23015..23017 9e10 +23018 9e16 +23019 9e87 +23020..23021 9e8e +23022 9e96 +23023 9e98 +23024 9eae +23025 9eb3 +23026 9ec6 +23027 9ec8 +23028 9ecb +23029 9ed5 +23030..23031 9eec +23032 9ef1 +23033 9ef5 +23034 9ef8 +23035 9f11 +23036 9f16 +23037 9f1a +23038 9f1f +23039..23040 9f31 +23041 9f3c +23042 9f3f +23043..23044 9f43 +23045 9f47 +23046 9f56 +23047 9f5e +23048 9f6e +23049 9f73 +23050 9f7a +23051 9f7d +23052 9f8f +23053..23054 9f91 +23055 9f96 +23056 9fa1 +23057 9fa3 diff --git a/fonts/cid/fontforge/Adobe-Japan2-0.cidmap b/fonts/cid/fontforge/Adobe-Japan2-0.cidmap new file mode 100644 index 000000000..6bac1eebb --- /dev/null +++ b/fonts/cid/fontforge/Adobe-Japan2-0.cidmap @@ -0,0 +1,4223 @@ +6067 6067 +0 /.notdef +1 02d8 +2 02c7 +3 00b8 +4 02d9 +5 02dd +6 00af +7 02db +8 02da +9 007e +10..11 0384 +12 00a1 +13 00a6 +14 00bf +15 00ba +16 00aa +17 00a9 +18 00ae +19 2122 +20 00a4 +21 2116 +22 0386 +23..25 0388 +26 03aa +27 038c +28 038e +29 03ab +30 038f +31..34 03ac +35 03ca +36 0390 +37 03cc +38 03c2 +39 03cd +40 03cb +41 03b0 +42 03ce +43..53 0402 +54..55 040e +56..66 0452 +67..68 045e +69 00c6 +70 0110 +71 0126 +72 0132 +73 0141 +74 013f +75 014a +76 00d8 +77 0152 +78 0166 +79 00de +80 00e6 +81 0111 +82 00f0 +83 0127 +84 0131 +85 0133 +86 0138 +87 0142 +88 0140 +89 0149 +90 014b +91 00f8 +92 0153 +93 00df +94 0167 +95 00fe +96 00c1 +97 00c0 +98 00c4 +99 00c2 +100 0102 +101 01cd +102 0100 +103 0104 +104 00c5 +105 00c3 +106 0106 +107 0108 +108 010c +109 00c7 +110 010a +111 010e +112 00c9 +113 00c8 +114 00cb +115 00ca +116 011a +117 0116 +118 0112 +119 0118 +120 011c +121 011e +122 0122 +123 0120 +124 0124 +125 00cd +126 00cc +127 00cf +128 00ce +129 01cf +130 0130 +131 012a +132 012e +133 0128 +134 0134 +135 0136 +136 0139 +137 013d +138 013b +139 0143 +140 0147 +141 0145 +142 00d1 +143 00d3 +144 00d2 +145 00d6 +146 00d4 +147 01d1 +148 0150 +149 014c +150 00d5 +151 0154 +152 0158 +153 0156 +154 015a +155 015c +156 0160 +157 015e +158 0164 +159 0162 +160 00da +161 00d9 +162 00dc +163 00db +164 016c +165 01d3 +166 0170 +167 016a +168 0172 +169 016e +170 0168 +171 01d7 +172 01db +173 01d9 +174 01d5 +175 0174 +176 00dd +177 0178 +178 0176 +179 0179 +180 017d +181 017b +182 00e1 +183 00e0 +184 00e4 +185 00e2 +186 0103 +187 01ce +188 0101 +189 0105 +190 00e5 +191 00e3 +192 0107 +193 0109 +194 010d +195 00e7 +196 010b +197 010f +198 00e9 +199 00e8 +200 00eb +201 00ea +202 011b +203 0117 +204 0113 +205 0119 +206 01f5 +207 011d +208 011f +209 0121 +210 0125 +211 00ed +212 00ec +213 00ef +214 00ee +215 01d0 +216 012b +217 012f +218 0129 +219 0135 +220 0137 +221 013a +222 013e +223 013c +224 0144 +225 0148 +226 0146 +227 00f1 +228 00f3 +229 00f2 +230 00f6 +231 00f4 +232 01d2 +233 0151 +234 014d +235 00f5 +236 0155 +237 0159 +238 0157 +239 015b +240 015d +241 0161 +242 015f +243 0165 +244 0163 +245 00fa +246 00f9 +247 00fc +248 00fb +249 016d +250 01d4 +251 0171 +252 016b +253 0173 +254 016f +255 0169 +256 01d8 +257 01dc +258 01da +259 01d6 +260 0175 +261 00fd +262 00ff +263 0177 +264 017a +265 017e +266 017c +267 4e02 +268..269 4e04 +270 4e0c +271 4e12 +272 4e1f +273..274 4e23 +275 4e28 +276 4e2b +277..279 4e2e +280 4e35 +281..282 4e40 +283 4e44 +284 4e47 +285 4e51 +286 4e5a +287 4e5c +288 4e63 +289..290 4e68 +291..292 4e74 +293 4e79 +294 4e7f +295 4e8d +296..297 4e96 +298 4e9d +299 4eaf +300 4eb9 +301 4ec3 +302 4ed0 +303..304 4eda +305..307 4ee0 +308 4ee8 +309 4eef +310 4ef1 +311 4ef3 +312 4ef5 +313..316 4efd +317..318 4f02 +319 4f08 +320..321 4f0b +322 4f12 +323..325 4f15 +326 4f19 +327 4f2e +328 4f31 +329 4f60 +330 4f33 +331 4f35 +332 4f37 +333 4f39 +334 4f3b +335 4f3e +336 4f40 +337 4f42 +338..339 4f48 +340..341 4f4b +342 4f52 +343 4f54 +344 4f56 +345 4f58 +346 4f5f +347 4f63 +348 4f6a +349 4f6c +350 4f6e +351 4f71 +352..355 4f77 +356..357 4f7d +358..359 4f81 +360..361 4f84 +362..363 4f89 +364 4f8c +365 4f8e +366 4f90 +367..369 4f92 +370 4f97 +371..372 4f99 +373..374 4f9e +375 4fb2 +376 4fb7 +377 4fb9 +378..381 4fbb +382..383 4fc0 +384..385 4fc5 +386..387 4fc8 +388..390 4fcb +391 4fcf +392 4fd2 +393 4fdc +394 4fe0 +395 4fe2 +396 4ff0 +397 4ff2 +398..399 4ffc +400..402 4fff +403 5004 +404 5007 +405 500a +406 500c +407 500e +408 5010 +409 5013 +410..411 5017 +412..415 501b +416 5022 +417 5027 +418 502e +419 5030 +420..421 5032 +422 5035 +423..425 5040 +426..427 5045 +428 504a +429 504c +430 504e +431..433 5051 +434 5057 +435 5059 +436..437 505f +438..439 5062 +440..441 5066 +442 506a +443 506d +444..445 5070 +446 503b +447 5081 +448..449 5083 +450 5086 +451 508a +452..454 508e +455..457 5092 +458 5096 +459..460 509b +461..465 509e +466 50aa +467..468 50af +469..470 50b9 +471 50bd +472 50c0 +473..474 50c3 +475 50c7 +476 50cc +477 50ce +478 50d0 +479..480 50d3 +481 50d8 +482..483 50dc +484 50df +485 50e2 +486 50e4 +487 50e6 +488..489 50e8 +490 50ef +491 50f1 +492 50f6 +493 50fa +494 50fe +495 5103 +496..498 5106 +499..502 510b +503 50f2 +504 5110 +505 5117 +506 5119 +507..510 511b +511 5123 +512..513 5127 +514..515 512c +516 512f +517 5131 +518..520 5133 +521..522 5138 +523 5142 +524 514a +525 514f +526 5153 +527 5155 +528..529 5157 +530 515f +531 5164 +532 5166 +533 517e +534..535 5183 +536 518b +537 518e +538 5198 +539 519d +540 51a1 +541 51a3 +542 51ad +543 51b8 +544 51ba +545 51bc +546..547 51be +548 51c2 +549 51c8 +550 51cf +551..553 51d1 +554 51d5 +555 51d8 +556 51de +557 51e2 +558 51e5 +559 51ee +560..562 51f2 +563 51f7 +564..565 5201 +566 5205 +567..568 5212 +569..570 5215 +571 5218 +572 5222 +573 5228 +574..575 5231 +576 5235 +577 523c +578 5245 +579 5249 +580 5255 +581..582 5257 +583 525a +584 525c +585..587 525f +588 5266 +589 526e +590..592 5277 +593 5280 +594 5282 +595 5285 +596 528a +597 528c +598 5293 +599..602 5295 +603 529a +604 529c +605..608 52a4 +609..610 52af +611..613 52b6 +614..615 52ba +616 52bd +617 52c0 +618 52c4 +619 52c6 +620 52c8 +621 52cc +622 52cf +623 52d1 +624 52d4 +625 52d6 +626..627 52db +628 52e1 +629 52e5 +630..632 52e8 +633 52ec +634..635 52f0 +636 52f4 +637..638 52f6 +639 5300 +640 5303 +641..643 530a +644 5311 +645 5313 +646 5318 +647..648 531b +649..650 531e +651 5325 +652..654 5327 +655..657 532b +658 5330 +659 5332 +660 5335 +661..663 533c +664 5342 +665 534c +666 534b +667 5359 +668 535b +669 5361 +670 5363 +671 5365 +672..673 536c +674 5372 +675 5379 +676 537e +677 5383 +678..679 5387 +680 538e +681..682 5393 +683 5399 +684 539d +685 53a1 +686 53a4 +687..688 53aa +689 53af +690 53b2 +691..692 53b4 +693..694 53b7 +695 53ba +696 53bd +697 53c0 +698 53c5 +699 53cf +700..701 53d2 +702 53d5 +703 53da +704..705 53dd +706 53e0 +707..708 53e6 +709 53f5 +710 5402 +711 5413 +712 541a +713 5421 +714..715 5427 +716 542a +717 542f +718 5431 +719..720 5434 +721..722 5443 +723 5447 +724 544d +725 544f +726 545e +727 5462 +728 5464 +729..730 5466 +731 5469 +732 546b +733..734 546d +735 5474 +736 547f +737 5481 +738 5483 +739 5485 +740..741 5488 +742 548d +743 5491 +744..745 5495 +746 549c +747 549f +748 54a1 +749..750 54a6 +751..752 54a9 +753..754 54ad +755 54b1 +756 54b7 +757..759 54b9 +760 54bf +761 54c6 +762 54ca +763..764 54cd +765 54e0 +766 54ea +767 54ec +768 54ef +769 54f6 +770 54fc +771..774 54fe +775 5505 +776..777 5508 +778..780 550c +781 5515 +782..783 552a +784 5532 +785..786 5535 +787..789 553b +790 5541 +791 5547 +792..793 5549 +794 554d +795..796 5550 +797 5558 +798..799 555a +800 555e +801..802 5560 +803 5564 +804 5566 +805 557f +806..807 5581 +808 5586 +809 5588 +810..811 558e +812..815 5591 +816 5597 +817..818 55a3 +819 55ad +820 55b2 +821 55bf +822 55c1 +823 55c3 +824 55c6 +825 55c9 +826..827 55cb +828 55ce +829..831 55d1 +832..833 55d7 +834 55db +835 55de +836 55e2 +837 55e9 +838 55f6 +839 55ff +840 5605 +841 5608 +842 560a +843..848 560d +849 5619 +850 562c +851 5630 +852 5633 +853 5635 +854 5637 +855 5639 +856..858 563b +859..861 563f +862..863 5643 +864 5646 +865 5649 +866 564b +867 564d +868 564f +869 5654 +870 565e +871..874 5660 +875 5666 +876 5669 +877 566d +878 566f +879..880 5671 +881 5675 +882..883 5684 +884 5688 +885..886 568b +887 5695 +888..889 5699 +890..892 569d +893..896 56a6 +897..899 56ab +900 56b1 +901 56b3 +902 56b7 +903 56be +904 56c5 +905..907 56c9 +908..909 56cf +910..911 56cc +912 56d9 +913..914 56dc +915 56df +916 56e1 +917..921 56e4 +922 56f1 +923 56eb +924 56ed +925..926 56f6 +927..928 5701 +929 5707 +930 570a +931 570c +932 5711 +933 5715 +934..935 571a +936 571d +937 5720 +938..941 5722 +942..943 5729 +944 572c +945..946 572e +947..948 5733 +949..951 573d +952..953 5745 +954..955 574c +956 5752 +957 5762 +958 5765 +959..960 5767 +961 576b +962..966 576d +967..969 5773 +970 5777 +971..974 5779 +975 577e +976 5781 +977 5783 +978 578c +979 5794 +980 5797 +981..982 5799 +983..986 579c +987 57a1 +988 5795 +989..991 57a7 +992 57ac +993 57b8 +994 57bd +995..996 57c7 +997 57cc +998 57cf +999 57d5 +1000..1001 57dd +1002 57e4 +1003..1004 57e6 +1005 57e9 +1006 57ed +1007 57f0 +1008..1009 57f5 +1010 57f8 +1011..1013 57fd +1014..1015 5803 +1016..1017 5808 +1018 57e1 +1019..1020 580c +1021 581b +1022..1024 581e +1025..1026 5826 +1027 582d +1028 5832 +1029 5839 +1030 583f +1031 5849 +1032..1033 584c +1034..1035 584f +1036 5855 +1037 585f +1038 5861 +1039 5864 +1040..1041 5867 +1042 5878 +1043 587c +1044..1046 587f +1047..1050 5887 +1051..1052 588c +1053..1054 588f +1055 5894 +1056 5896 +1057 589d +1058..1060 58a0 +1061 58a6 +1062 58a9 +1063..1064 58b1 +1065 58c4 +1066 58bc +1067 58c2 +1068 58c8 +1069..1070 58cd +1071 58d0 +1072 58d2 +1073 58d4 +1074 58d6 +1075 58da +1076 58dd +1077..1078 58e1 +1079 58e9 +1080 58f3 +1081..1082 5905 +1083..1084 590b +1085..1087 5912 +1088 8641 +1089 591d +1090 5921 +1091..1092 5923 +1093 5928 +1094..1095 592f +1096 5933 +1097..1098 5935 +1099 593f +1100 5943 +1101 5946 +1102..1103 5952 +1104 5959 +1105 595b +1106..1108 595d +1109 5961 +1110 5963 +1111 596b +1112 596d +1113 596f +1114 5972 +1115..1116 5975 +1117 5979 +1118..1119 597b +1120..1121 598b +1122 598e +1123 5992 +1124 5995 +1125 5997 +1126 599f +1127 59a4 +1128 59a7 +1129..1132 59ad +1133 59b3 +1134 59b7 +1135 59ba +1136 59bc +1137 59c1 +1138..1139 59c3 +1140 59c8 +1141 59ca +1142 59cd +1143 59d2 +1144..1146 59dd +1147..1148 59e3 +1149 59e7 +1150..1151 59ee +1152..1153 59f1 +1154 59f4 +1155 59f7 +1156 5a00 +1157 5a04 +1158..1160 5a0c +1161..1162 5a12 +1163 5a1e +1164..1165 5a23 +1166..1167 5a27 +1168 5a2a +1169 5a2d +1170 5a30 +1171..1172 5a44 +1173..1174 5a47 +1175 5a4c +1176 5a50 +1177 5a55 +1178 5a5e +1179 5a63 +1180 5a65 +1181 5a67 +1182 5a6d +1183 5a77 +1184..1185 5a7a +1186 5a7e +1187 5a8b +1188 5a90 +1189 5a93 +1190 5a96 +1191 5a99 +1192 5a9c +1193..1195 5a9e +1196 5aa2 +1197 5aa7 +1198 5aac +1199..1201 5ab1 +1202 5ab5 +1203 5ab8 +1204..1205 5aba +1206 5abf +1207 5ac4 +1208 5ac6 +1209 5ac8 +1210 5acf +1211 5ada +1212 5adc +1213 5ae0 +1214 5ae5 +1215 5aea +1216 5aee +1217..1218 5af5 +1219 5afd +1220..1221 5b00 +1222 5b08 +1223 5b17 +1224 5b34 +1225 5b19 +1226 5b1b +1227 5b1d +1228 5b21 +1229 5b25 +1230 5b2d +1231 5b38 +1232 5b41 +1233..1234 5b4b +1235 5b52 +1236 5b56 +1237 5b5e +1238 5b68 +1239..1240 5b6e +1241..1244 5b7c +1245 5b81 +1246 5b84 +1247 5b86 +1248 5b8a +1249 5b8e +1250..1251 5b90 +1252..1253 5b93 +1254 5b96 +1255..1256 5ba8 +1257..1258 5bac +1259 5baf +1260..1261 5bb1 +1262 5bb7 +1263 5bba +1264 5bbc +1265..1266 5bc0 +1267 5bcd +1268 5bcf +1269..1273 5bd6 +1274 5be0 +1275 5bef +1276 5bf1 +1277 5bf4 +1278 5bfd +1279 5c0c +1280 5c17 +1281..1282 5c1e +1283 5c23 +1284 5c26 +1285 5c29 +1286..1287 5c2b +1288 5c2e +1289 5c30 +1290 5c32 +1291..1292 5c35 +1293..1294 5c59 +1295 5c5c +1296..1297 5c62 +1298..1300 5c67 +1301 5c6d +1302 5c70 +1303..1304 5c74 +1305..1308 5c7a +1309..1310 5c87 +1311 5c8a +1312 5c8f +1313 5c92 +1314 5c9d +1315..1316 5c9f +1317..1318 5ca2 +1319 5ca6 +1320 5caa +1321 5cb2 +1322..1323 5cb4 +1324 5cba +1325 5cc9 +1326 5ccb +1327 5cd2 +1328 5cdd +1329 5cd7 +1330 5cee +1331..1332 5cf1 +1333 5cf4 +1334 5d01 +1335 5d06 +1336 5d0d +1337 5d12 +1338 5d2b +1339..1340 5d23 +1341..1342 5d26 +1343 5d31 +1344 5d34 +1345 5d39 +1346 5d3d +1347 5d3f +1348..1349 5d42 +1350 5d46 +1351 5d48 +1352 5d55 +1353 5d51 +1354 5d59 +1355 5d4a +1356..1359 5d5f +1360 5d64 +1361 5d6a +1362 5d6d +1363 5d70 +1364..1365 5d79 +1366..1367 5d7e +1368 5d81 +1369 5d83 +1370 5d88 +1371 5d8a +1372..1375 5d92 +1376 5d99 +1377 5d9b +1378..1379 5d9f +1380 5da7 +1381 5dab +1382 5db0 +1383 5db4 +1384..1385 5db8 +1386 5dc3 +1387 5dc7 +1388 5dcb +1389 5dd0 +1390 5dce +1391..1392 5dd8 +1393 5de0 +1394 5de4 +1395 5de9 +1396..1397 5df8 +1398 5e00 +1399 5e07 +1400 5e0d +1401 5e12 +1402..1403 5e14 +1404 5e18 +1405..1406 5e1f +1407 5e2e +1408 5e28 +1409 5e32 +1410 5e35 +1411 5e3e +1412 5e4b +1413 5e50 +1414 5e49 +1415 5e51 +1416 5e56 +1417 5e58 +1418..1419 5e5b +1420 5e5e +1421 5e68 +1422..1426 5e6a +1427 5e70 +1428 5e80 +1429 5e8b +1430 5e8e +1431 5ea2 +1432..1433 5ea4 +1434 5ea8 +1435 5eaa +1436 5eac +1437 5eb1 +1438 5eb3 +1439..1441 5ebd +1442 5ec6 +1443 5ecc +1444 5ecb +1445 5ece +1446..1447 5ed1 +1448..1449 5ed4 +1450 5edc +1451 5ede +1452 5ee5 +1453 5eeb +1454 5f02 +1455..1457 5f06 +1458 5f0e +1459 5f19 +1460..1461 5f1c +1462..1465 5f21 +1466 5f28 +1467..1468 5f2b +1469 5f2e +1470 5f30 +1471 5f34 +1472 5f36 +1473 5f3b +1474 5f3d +1475..1476 5f3f +1477..1478 5f44 +1479 5f47 +1480 5f4d +1481 5f50 +1482 5f54 +1483 5f58 +1484 5f5b +1485 5f60 +1486..1487 5f63 +1488 5f67 +1489 5f6f +1490 5f72 +1491..1492 5f74 +1493 5f78 +1494 5f7a +1495..1496 5f7d +1497 5f89 +1498 5f8d +1499 5f8f +1500 5f96 +1501..1502 5f9c +1503 5fa2 +1504 5fa7 +1505 5fab +1506 5fa4 +1507 5fac +1508..1510 5faf +1511 5fb8 +1512 5fc4 +1513..1515 5fc7 +1516 5fcb +1517..1521 5fd0 +1522 5fde +1523..1524 5fe1 +1525..1527 5fe8 +1528..1531 5fec +1532..1533 5ff2 +1534 5ff6 +1535 5ffa +1536 5ffc +1537 6007 +1538 600a +1539 600d +1540..1541 6013 +1542..1543 6017 +1544 601a +1545 601f +1546 6024 +1547 602d +1548 6033 +1549 6035 +1550 6040 +1551..1553 6047 +1554 604c +1555 6051 +1556 6054 +1557..1558 6056 +1559 605d +1560 6061 +1561 6067 +1562 6071 +1563..1564 607e +1565 6082 +1566 6086 +1567 6088 +1568 608a +1569 608e +1570 6091 +1571 6093 +1572 6095 +1573 6098 +1574..1575 609d +1576 60a2 +1577..1578 60a4 +1579 60a8 +1580..1581 60b0 +1582 60b7 +1583 60bb +1584 60be +1585 60c2 +1586 60c4 +1587..1590 60c8 +1591..1592 60ce +1593..1594 60d4 +1595 60d9 +1596 60db +1597..1598 60dd +1599 60e2 +1600 60e5 +1601 60f2 +1602 60f5 +1603 60f8 +1604..1605 60fc +1606 6102 +1607 6107 +1608 610a +1609 610c +1610..1614 6110 +1615..1616 6116 +1617 6119 +1618 611c +1619 611e +1620 6122 +1621..1622 612a +1623..1624 6130 +1625..1627 6135 +1628 6139 +1629 6141 +1630..1631 6145 +1632 6149 +1633 615e +1634 6160 +1635 616c +1636 6172 +1637 6178 +1638..1639 617b +1640..1642 617f +1643..1644 6183 +1645 618b +1646 618d +1647..1648 6192 +1649..1650 6197 +1651..1652 619c +1653..1654 619f +1655 61a5 +1656 61a8 +1657 61aa +1658 61ad +1659..1660 61b8 +1661 61bc +1662..1664 61c0 +1665..1666 61ce +1667 61d5 +1668..1671 61dc +1672..1673 61e1 +1674 61e7 +1675 61e9 +1676 61e5 +1677..1678 61ec +1679 61ef +1680 6201 +1681..1682 6203 +1683 6207 +1684 6213 +1685 6215 +1686 621c +1687 6220 +1688..1689 6222 +1690 6227 +1691 6229 +1692 622b +1693 6239 +1694 623d +1695..1697 6242 +1698 6246 +1699 624c +1700..1702 6250 +1703 6254 +1704 6256 +1705 625a +1706 625c +1707 6264 +1708 626d +1709 626f +1710 6273 +1711 627a +1712 627d +1713..1716 628d +1717 62a6 +1718 62a8 +1719 62b3 +1720..1721 62b6 +1722 62ba +1723..1724 62be +1725 62c4 +1726 62ce +1727..1728 62d5 +1729 62da +1730 62ea +1731 62f2 +1732 62f4 +1733..1734 62fc +1735..1736 6303 +1737..1738 630a +1739 630d +1740 6310 +1741 6313 +1742 6316 +1743 6318 +1744..1745 6329 +1746 632d +1747..1748 6335 +1749 6339 +1750 633c +1751..1754 6341 +1755 6346 +1756..1757 634a +1758 634e +1759..1761 6352 +1762 6358 +1763 635b +1764..1765 6365 +1766..1767 636c +1768 6371 +1769..1770 6374 +1771 6378 +1772..1773 637c +1774 637f +1775 6382 +1776 6384 +1777 6387 +1778 638a +1779 6390 +1780..1781 6394 +1782..1783 6399 +1784 639e +1785 63a4 +1786 63a6 +1787..1789 63ad +1790 63bd +1791 63c1 +1792 63c5 +1793 63c8 +1794 63ce +1795 63d1 +1796..1798 63d3 +1799 63dc +1800 63e0 +1801 63e5 +1802 63ea +1803 63ec +1804..1805 63f2 +1806 63f5 +1807..1808 63f8 +1809..1810 6409 +1811 6410 +1812 6412 +1813 6414 +1814 6418 +1815 641e +1816 6420 +1817 6422 +1818..1819 6424 +1820..1821 6429 +1822..1823 642f +1824 6435 +1825 643d +1826 643f +1827 644b +1828 644f +1829..1832 6451 +1833..1836 645a +1837..1839 645f +1840 6463 +1841 646d +1842..1843 6473 +1844 647b +1845 647d +1846 6485 +1847 6487 +1848..1850 648f +1851..1852 6498 +1853 649b +1854 649d +1855 649f +1856 64a1 +1857 64a3 +1858 64a6 +1859 64a8 +1860 64ac +1861 64b3 +1862..1864 64bd +1865 64c4 +1866..1869 64c9 +1870 64ce +1871..1872 64d0 +1873 64d5 +1874 64d7 +1875..1876 64e4 +1877..1878 64e9 +1879 64ed +1880 64f0 +1881 64f5 +1882 64f7 +1883 64fb +1884 64ff +1885 6501 +1886 6504 +1887..1889 6508 +1890 650f +1891..1892 6513 +1893 6516 +1894 6519 +1895 651b +1896..1897 651e +1898 6522 +1899 6526 +1900 6529 +1901 652e +1902 6531 +1903 653a +1904..1905 653c +1906 6543 +1907 6547 +1908 6549 +1909 6550 +1910 6552 +1911 6554 +1912..1913 655f +1914 6567 +1915 656b +1916 657a +1917 657d +1918 6581 +1919 6585 +1920 658a +1921 6592 +1922 6595 +1923 6598 +1924 659d +1925 65a0 +1926 65a3 +1927 65a6 +1928 65ae +1929..1931 65b2 +1932 65bf +1933 65c2 +1934..1935 65c8 +1936 65ce +1937 65d0 +1938 65d4 +1939 65d6 +1940 65d8 +1941 65df +1942 65f0 +1943 65f2 +1944..1945 65f4 +1946 65f9 +1947..1949 65fe +1950 6604 +1951..1952 6608 +1953 660d +1954..1955 6611 +1956..1957 6615 +1958..1959 661d +1960..1963 6621 +1964 6626 +1965..1968 6629 +1969 662e +1970..1971 6630 +1972 6633 +1973 6639 +1974 6637 +1975 6640 +1976..1977 6645 +1978 664a +1979 664c +1980 6651 +1981 664e +1982..1984 6657 +1985..1986 665b +1987..1988 6660 +1989 66fb +1990..1992 666a +1993 667e +1994 6673 +1995 6675 +1996 667f +1997..1999 6677 +2000 667b +2001 6680 +2002 667c +2003..2005 668b +2006 6690 +2007 6692 +2008..2011 6699 +2012..2013 669f +2014 66a4 +2015 66ad +2016..2017 66b1 +2018 66b5 +2019 66bb +2020..2021 66bf +2022..2023 66c2 +2024 66c8 +2025 66cc +2026..2027 66ce +2028 66d4 +2029 66db +2030 66df +2031 66e8 +2032..2033 66eb +2034 66ee +2035 66fa +2036 6705 +2037 6707 +2038 670e +2039 6713 +2040 6719 +2041 671c +2042 6720 +2043 6722 +2044 6733 +2045 673e +2046 6745 +2047..2048 6747 +2049 674c +2050..2051 6754 +2052 675d +2053 6766 +2054 676c +2055 676e +2056 6774 +2057 6776 +2058 677b +2059 6781 +2060 6784 +2061..2062 678e +2063 6791 +2064 6793 +2065 6796 +2066..2067 6798 +2068 679b +2069..2071 67b0 +2072 67b5 +2073..2075 67bb +2076 67f9 +2077 67c0 +2078..2079 67c2 +2080 67c5 +2081..2082 67c8 +2083 67d2 +2084 67d7 +2085 67d9 +2086 67dc +2087 67e1 +2088 67e6 +2089 67f0 +2090 67f2 +2091..2092 67f6 +2093 6852 +2094 6814 +2095 6819 +2096 681d +2097 681f +2098 6828 +2099 6827 +2100..2101 682c +2102..2104 682f +2105 6833 +2106 683b +2107 683f +2108..2109 6844 +2110 684a +2111 684c +2112 6855 +2113..2114 6857 +2115 685b +2116 686b +2117..2121 686e +2122 6875 +2123..2126 6879 +2127 6882 +2128 6884 +2129 6886 +2130 6888 +2131 6896 +2132 6898 +2133 689a +2134 689c +2135 68a1 +2136 68a3 +2137 68a5 +2138..2139 68a9 +2140 68ae +2141 68b2 +2142 68bb +2143 68c5 +2144 68c8 +2145 68cc +2146..2148 68cf +2149 68d3 +2150 68d6 +2151 68d9 +2152..2153 68dc +2154 68e5 +2155 68e8 +2156..2159 68ea +2160..2161 68f0 +2162..2163 68f5 +2164..2166 68fb +2167 6906 +2168..2169 6909 +2170..2171 6910 +2172 6913 +2173..2174 6916 +2175 6931 +2176 6933 +2177 6935 +2178 6938 +2179 693b +2180 6942 +2181 6945 +2182 6949 +2183 694e +2184 6957 +2185 695b +2186..2189 6963 +2190..2191 6968 +2192 696c +2193..2195 6970 +2196..2197 697a +2198..2199 697f +2200 698d +2201 6992 +2202 6996 +2203 6998 +2204 69a1 +2205..2206 69a5 +2207 69a8 +2208 69ab +2209 69ad +2210 69af +2211..2212 69b7 +2213 69ba +2214 69bc +2215 69c5 +2216 69c8 +2217 69d1 +2218..2219 69d6 +2220 69e2 +2221 69e5 +2222..2223 69ee +2224 69f1 +2225 69f3 +2226 69f5 +2227 69fe +2228..2229 6a00 +2230 6a03 +2231 6a0f +2232 6a11 +2233 6a15 +2234 6a1a +2235 6a1d +2236 6a20 +2237 6a24 +2238 6a28 +2239 6a30 +2240 6a32 +2241 6a34 +2242 6a37 +2243 6a3b +2244..2245 6a3e +2246..2247 6a45 +2248..2249 6a49 +2250 6a4e +2251..2253 6a50 +2254..2255 6a55 +2256 6a5b +2257 6a64 +2258 6a67 +2259 6a6a +2260 6a71 +2261 6a73 +2262 6a7e +2263 6a81 +2264 6a83 +2265..2266 6a86 +2267 6a89 +2268 6a8b +2269 6a91 +2270 6a9b +2271..2273 6a9d +2274 6aa5 +2275 6aab +2276..2278 6aaf +2279 6ab4 +2280..2282 6abd +2283 6ac6 +2284 6ac9 +2285 6ac8 +2286 6acc +2287 6ad0 +2288..2290 6ad4 +2291..2292 6adc +2293 6ae4 +2294 6ae7 +2295 6aec +2296..2298 6af0 +2299..2300 6afc +2301..2302 6b02 +2303..2304 6b06 +2305 6b09 +2306..2308 6b0f +2309 6b17 +2310 6b1b +2311 6b1e +2312 6b24 +2313 6b28 +2314..2315 6b2b +2316 6b2f +2317..2318 6b35 +2319 6b3b +2320 6b3f +2321 6b46 +2322 6b4a +2323 6b4d +2324 6b52 +2325 6b56 +2326 6b58 +2327 6b5d +2328 6b60 +2329 6b67 +2330 6b6b +2331 6b6e +2332 6b70 +2333 6b75 +2334..2335 6b7d +2336 6b82 +2337 6b85 +2338 6b97 +2339 6b9b +2340..2341 6b9f +2342..2343 6ba2 +2344..2345 6ba8 +2346..2348 6bac +2349 6bb0 +2350..2351 6bb8 +2352..2353 6bbd +2354..2355 6bc3 +2356 6bc9 +2357 6bcc +2358 6bd6 +2359 6bda +2360 6be1 +2361 6be3 +2362..2363 6be6 +2364 6bee +2365 6bf1 +2366 6bf7 +2367 6bf9 +2368 6bff +2369 6c02 +2370..2371 6c04 +2372 6c09 +2373..2374 6c0d +2375 6c10 +2376 6c12 +2377 6c19 +2378 6c1f +2379..2381 6c26 +2382 6c2c +2383 6c2e +2384 6c33 +2385..2386 6c35 +2387..2388 6c3a +2389 6c3f +2390..2391 6c4a +2392 6c4d +2393 6c4f +2394 6c52 +2395 6c54 +2396 6c59 +2397..2398 6c5b +2399 6c6b +2400 6c6d +2401 6c6f +2402 6c74 +2403 6c76 +2404..2405 6c78 +2406 6c7b +2407..2409 6c85 +2410 6c89 +2411..2412 6c94 +2413..2414 6c97 +2415 6c9c +2416 6c9f +2417 6cb0 +2418 6cb2 +2419 6cb4 +2420 6cc2 +2421 6cc6 +2422 6ccd +2423..2426 6ccf +2427 6cd4 +2428 6cd6 +2429 6cda +2430 6cdc +2431 6ce0 +2432 6ce7 +2433 6ce9 +2434..2435 6ceb +2436 6cee +2437 6cf2 +2438 6cf4 +2439 6d04 +2440 6d07 +2441 6d0a +2442..2443 6d0e +2444 6d11 +2445 6d13 +2446 6d1a +2447..2449 6d26 +2450 6c67 +2451..2452 6d2e +2453 6d31 +2454 6d39 +2455 6d3c +2456 6d3f +2457 6d57 +2458..2459 6d5e +2460 6d61 +2461 6d65 +2462 6d67 +2463..2464 6d6f +2465 6d7c +2466 6d82 +2467 6d87 +2468..2469 6d91 +2470 6d94 +2471..2473 6d96 +2474 6daa +2475 6dac +2476 6db4 +2477 6db7 +2478 6db9 +2479 6dbd +2480 6dbf +2481 6dc4 +2482 6dc8 +2483 6dca +2484..2485 6dce +2486 6dd6 +2487 6ddb +2488 6ddd +2489..2490 6ddf +2491 6de2 +2492 6de5 +2493 6de9 +2494..2495 6def +2496 6df4 +2497 6df6 +2498 6dfc +2499 6e00 +2500 6e04 +2501 6e1e +2502 6e22 +2503 6e27 +2504 6e32 +2505 6e36 +2506 6e39 +2507..2508 6e3b +2509..2510 6e44 +2511..2512 6e48 +2513 6e4b +2514 6e4f +2515..2518 6e51 +2519 6e57 +2520..2522 6e5c +2523..2524 6e62 +2525 6e68 +2526 6e73 +2527 6e7b +2528 6e7d +2529 6e8d +2530 6e93 +2531 6e99 +2532 6ea0 +2533 6ea7 +2534..2535 6ead +2536 6eb1 +2537 6eb3 +2538 6ebb +2539..2541 6ebf +2542 6ec3 +2543..2544 6ec7 +2545 6eca +2546..2548 6ecd +2549 6eeb +2550..2551 6eed +2552 6ef9 +2553 6efb +2554 6efd +2555 6f04 +2556 6f08 +2557 6f0a +2558..2559 6f0c +2560 6f16 +2561 6f18 +2562..2563 6f1a +2564 6f26 +2565..2566 6f29 +2567..2568 6f2f +2569 6f33 +2570 6f36 +2571..2572 6f3b +2573 6f2d +2574 6f4f +2575..2577 6f51 +2578 6f57 +2579..2580 6f59 +2581..2582 6f5d +2583..2584 6f61 +2585 6f68 +2586 6f6c +2587..2588 6f7d +2589 6f83 +2590..2591 6f87 +2592..2594 6f8b +2595 6f90 +2596..2598 6f92 +2599 6f96 +2600 6f9a +2601..2602 6f9f +2603..2606 6fa5 +2607..2609 6fae +2610..2611 6fb5 +2612 6fbc +2613 6fc5 +2614..2615 6fc7 +2616 6fca +2617 6fda +2618 6fde +2619..2620 6fe8 +2621 6ff0 +2622 6ff5 +2623 6ff9 +2624..2625 6ffc +2626 7000 +2627..2629 7005 +2630 700d +2631 7017 +2632 7020 +2633 7023 +2634 702f +2635 7034 +2636 7037 +2637 7039 +2638 703c +2639..2640 7043 +2641..2644 7048 +2645..2646 7054 +2647..2648 705d +2649 704e +2650..2651 7064 +2652 706c +2653 706e +2654..2655 7075 +2656 707e +2657 7081 +2658..2659 7085 +2660..2664 7094 +2665 709b +2666 70a4 +2667 70ab +2668..2669 70b0 +2670 70b4 +2671 70b7 +2672 70ca +2673 70d1 +2674..2677 70d3 +2678 70d8 +2679 70dc +2680 70e4 +2681 70fa +2682..2686 7103 +2687..2688 710b +2689 710f +2690 711e +2691 7120 +2692 712b +2693 712d +2694..2696 712f +2697 7138 +2698 7141 +2699..2701 7145 +2702..2703 714a +2704 7150 +2705 7152 +2706 7157 +2707 715a +2708 715c +2709 715e +2710 7160 +2711 7168 +2712 7179 +2713 7180 +2714 7185 +2715 7187 +2716 718c +2717 7192 +2718..2719 719a +2720 71a0 +2721 71a2 +2722..2723 71af +2724..2725 71b2 +2726 71ba +2727..2729 71bf +2730 71c4 +2731..2732 71cb +2733 71d3 +2734 71d6 +2735..2736 71d9 +2737 71dc +2738 71f8 +2739 71fe +2740 7200 +2741..2743 7207 +2744 7213 +2745 7217 +2746 721a +2747 721d +2748 721f +2749 7224 +2750 722b +2751 722f +2752 7234 +2753..2754 7238 +2755..2757 7241 +2758 7245 +2759..2761 724e +2762 7253 +2763..2764 7255 +2765 725a +2766 725c +2767 725e +2768 7260 +2769 7263 +2770 7268 +2771 726b +2772..2773 726e +2774 7271 +2775..2776 7277 +2777..2778 727b +2779 727f +2780 7284 +2781 7289 +2782..2783 728d +2784 7293 +2785 729b +2786 72a8 +2787..2788 72ad +2789 72b1 +2790 72b4 +2791 72be +2792 72c1 +2793 72c7 +2794 72c9 +2795 72cc +2796..2797 72d5 +2798 72d8 +2799 72df +2800 72e5 +2801..2802 72f3 +2803..2804 72fa +2805 72fe +2806 7302 +2807..2808 7304 +2809 7307 +2810 730b +2811 730d +2812..2813 7312 +2814..2815 7318 +2816 731e +2817 7322 +2818 7324 +2819..2820 7327 +2821 732c +2822..2823 7331 +2824 7335 +2825..2826 733a +2827 733d +2828 7343 +2829 734d +2830 7350 +2831 7352 +2832 7356 +2833 7358 +2834..2837 735d +2838..2839 7366 +2840 7369 +2841..2842 736b +2843..2844 736e +2845 7371 +2846 7377 +2847 7379 +2848 737c +2849..2850 7380 +2851 7383 +2852..2853 7385 +2854 738e +2855 7390 +2856 7393 +2857 7395 +2858..2859 7397 +2860 739c +2861..2863 739e +2864 73a2 +2865..2866 73a5 +2867..2868 73aa +2869 73ad +2870 73b5 +2871 73b7 +2872 73b9 +2873..2874 73bc +2875 73bf +2876..2877 73c5 +2878 73c9 +2879..2880 73cb +2881 73cf +2882..2883 73d2 +2884 73d6 +2885 73d9 +2886 73dd +2887 73e1 +2888 73e3 +2889..2890 73e6 +2891 73e9 +2892..2893 73f4 +2894 73f7 +2895..2897 73f9 +2898 73fd +2899..2901 73ff +2902 7404 +2903 7407 +2904 740a +2905 7411 +2906..2907 741a +2908 7424 +2909 7426 +2910..2919 7428 +2920 7439 +2921 7440 +2922..2923 7443 +2924..2925 7446 +2926 744b +2927 744d +2928..2929 7451 +2930 7457 +2931 745d +2932 7462 +2933..2935 7466 +2936 746b +2937..2938 746d +2939..2940 7471 +2941..2942 7480 +2943..2945 7485 +2946 7489 +2947..2950 748f +2951..2953 7498 +2954 749c +2955..2957 749f +2958 74a3 +2959 74a6 +2960..2963 74a8 +2964..2965 74ae +2966..2967 74b1 +2968 74b5 +2969 74b9 +2970 74bb +2971 74bf +2972..2973 74c8 +2974 74cc +2975 74d0 +2976 74d3 +2977 74d8 +2978..2979 74da +2980..2981 74de +2982 74e4 +2983 74e8 +2984..2985 74ea +2986 74ef +2987 74f4 +2988..2990 74fa +2991 74ff +2992 7506 +2993 7512 +2994..2995 7516 +2996..2997 7520 +2998 7524 +2999 7527 +3000..3001 7529 +3002 752f +3003 7536 +3004 7539 +3005..3008 753d +3009 7543 +3010..3011 7547 +3012 754e +3013 7550 +3014 7552 +3015 7557 +3016..3017 755e +3018 7561 +3019 756f +3020 7571 +3021..3026 7579 +3027 7581 +3028 7585 +3029 7590 +3030..3031 7592 +3032 7595 +3033 7599 +3034 759c +3035 75a2 +3036 75a4 +3037 75b4 +3038 75ba +3039..3041 75bf +3042 75c4 +3043 75c6 +3044 75cc +3045..3046 75ce +3047 75d7 +3048 75dc +3049..3051 75df +3052 75e4 +3053 75e7 +3054 75ec +3055..3056 75ee +3057 75f1 +3058 75f9 +3059 7600 +3060..3062 7602 +3063..3064 7607 +3065 760a +3066 760c +3067 760f +3068..3069 7612 +3070..3071 7615 +3072 7619 +3073..3076 761b +3077 7623 +3078..3079 7625 +3080 7629 +3081 762d +3082..3083 7632 +3084 7635 +3085..3087 7638 +3088 763c +3089 764a +3090..3091 7640 +3092..3094 7643 +3095 7649 +3096 764b +3097 7655 +3098 7659 +3099 765f +3100..3101 7664 +3102..3104 766d +3105 7671 +3106 7674 +3107 7681 +3108 7685 +3109..3110 768c +3111 7695 +3112..3114 769b +3115..3116 769f +3117..3123 76a2 +3124 76aa +3125 76ad +3126 76bd +3127 76c1 +3128 76c5 +3129 76c9 +3130..3131 76cb +3132 76ce +3133 76d4 +3134 76d9 +3135 76e0 +3136 76e6 +3137 76e8 +3138 76ec +3139..3140 76f0 +3141 76f6 +3142 76f9 +3143 76fc +3144 7700 +3145 7706 +3146 770a +3147 770e +3148 7712 +3149..3150 7714 +3151 7717 +3152..3153 7719 +3154 771c +3155 7722 +3156 7728 +3157..3159 772d +3160..3162 7734 +3163 7739 +3164..3165 773d +3166 7742 +3167..3168 7745 +3169 774a +3170..3172 774d +3173 7752 +3174..3175 7756 +3176 775c +3177..3179 775e +3180 7762 +3181 7764 +3182 7767 +3183 776a +3184 776c +3185 7770 +3186..3188 7772 +3189 777a +3190 777d +3191 7780 +3192 7784 +3193..3194 778c +3195..3197 7794 +3198 779a +3199 779f +3200 77a2 +3201 77a7 +3202 77aa +3203..3204 77ae +3205 77b1 +3206 77b5 +3207 77be +3208 77c3 +3209 77c9 +3210..3211 77d1 +3212 77d5 +3213 77d9 +3214..3216 77de +3217 77e4 +3218 77e6 +3219 77ea +3220 77ec +3221..3222 77f0 +3223 77f4 +3224 77f8 +3225 77fb +3226..3227 7805 +3228 7809 +3229..3230 780d +3231 7811 +3232 781d +3233..3235 7821 +3236..3237 782d +3238 7830 +3239 7835 +3240 7837 +3241..3242 7843 +3243..3244 7847 +3245 784c +3246 784e +3247 7852 +3248 785c +3249 785e +3250..3251 7860 +3252..3253 7863 +3254 7868 +3255 786a +3256 786e +3257 787a +3258 787e +3259 788a +3260 788f +3261 7894 +3262 7898 +3263 78a1 +3264..3266 789d +3267 78a4 +3268 78a8 +3269..3270 78ac +3271..3274 78b0 +3275 78bb +3276 78bd +3277 78bf +3278..3280 78c7 +3281 78cc +3282 78ce +3283..3284 78d2 +3285..3286 78d5 +3287 78e4 +3288 78db +3289..3291 78df +3292 78e6 +3293 78ea +3294..3295 78f2 +3296 7900 +3297..3298 78f6 +3299..3300 78fa +3301 78ff +3302 7906 +3303 790c +3304 7910 +3305 791a +3306 791c +3307..3309 791e +3310 7925 +3311 7927 +3312 7929 +3313 792d +3314 7931 +3315..3316 7934 +3317 793b +3318 793d +3319 793f +3320..3322 7944 +3323..3324 794a +3325 794f +3326 7951 +3327 7954 +3328 7958 +3329..3330 795b +3331 7967 +3332 7969 +3333 796b +3334 7972 +3335 7979 +3336..3337 797b +3338 797e +3339..3340 798b +3341 7991 +3342..3345 7993 +3346 7998 +3347..3348 799b +3349 79a1 +3350..3351 79a8 +3352 79ab +3353 79af +3354 79b1 +3355 79b4 +3356 79b8 +3357 79bb +3358 79c2 +3359 79c4 +3360..3361 79c7 +3362 79ca +3363 79cf +3364 79d4 +3365 79d6 +3366 79da +3367..3368 79dd +3369 79e0 +3370 79e2 +3371 79e5 +3372..3373 79ea +3374 79ed +3375 79f1 +3376 79f8 +3377 79fc +3378..3379 7a02 +3380 7a07 +3381..3382 7a09 +3383 7a0c +3384 7a11 +3385 7a15 +3386 7a1b +3387 7a1e +3388 7a21 +3389 7a27 +3390 7a2b +3391 7a2d +3392..3393 7a2f +3394..3395 7a34 +3396..3398 7a38 +3399..3400 7a44 +3401..3402 7a47 +3403 7a4c +3404..3405 7a55 +3406 7a59 +3407..3408 7a5c +3409..3410 7a5f +3411 7a65 +3412 7a67 +3413 7a6a +3414 7a6d +3415 7a75 +3416 7a78 +3417 7a7e +3418 7a80 +3419 7a82 +3420..3421 7a85 +3422..3423 7a8a +3424..3425 7a90 +3426 7a94 +3427 7a9e +3428 7aa0 +3429 7aa3 +3430 7aac +3431 7ab3 +3432 7ab5 +3433 7ab9 +3434..3435 7abb +3436 7ac6 +3437 7ac9 +3438 7acc +3439 7ace +3440 7ad1 +3441 7adb +3442..3443 7ae8 +3444..3445 7aeb +3446 7af1 +3447 7af4 +3448 7afb +3449..3450 7afd +3451 7b07 +3452 7b14 +3453 7b1f +3454 7b23 +3455 7b27 +3456..3458 7b29 +3459..3463 7b2d +3464 7b34 +3465 7b3d +3466..3468 7b3f +3469 7b47 +3470 7b4e +3471 7b55 +3472 7b60 +3473 7b64 +3474 7b66 +3475..3476 7b69 +3477 7b6d +3478 7b6f +3479..3480 7b72 +3481 7b77 +3482 7b84 +3483 7b89 +3484 7b8e +3485..3486 7b90 +3487 7b96 +3488 7b9b +3489 7b9e +3490 7ba0 +3491 7ba5 +3492 7bac +3493..3494 7baf +3495 7bb2 +3496..3497 7bb5 +3498..3501 7bba +3502 7bc2 +3503 7bc5 +3504 7bc8 +3505 7bca +3506 7bd4 +3507..3508 7bd6 +3509..3511 7bd9 +3512 7be8 +3513 7bea +3514 7bf2 +3515..3516 7bf4 +3517..3519 7bf8 +3520 7bfc +3521 7bfe +3522..3525 7c01 +3526 7c06 +3527 7c09 +3528..3529 7c0b +3530..3531 7c0e +3532 7c19 +3533 7c1b +3534 7c20 +3535..3536 7c25 +3537 7c28 +3538 7c2c +3539 7c31 +3540..3541 7c33 +3542 7c36 +3543..3544 7c39 +3545 7c46 +3546 7c4a +3547 7c55 +3548..3550 7c51 +3551..3556 7c59 +3557 7c61 +3558 7c63 +3559 7c67 +3560 7c69 +3561..3562 7c6d +3563 7c70 +3564 7c72 +3565 7c79 +3566..3567 7c7c +3568..3569 7c86 +3570 7c8f +3571 7c94 +3572 7c9e +3573 7ca0 +3574 7ca6 +3575 7cb0 +3576..3577 7cb6 +3578..3580 7cba +3581 7cbf +3582 7cc4 +3583..3585 7cc7 +3586 7ccd +3587 7ccf +3588..3590 7cd3 +3591 7cd7 +3592..3593 7cd9 +3594 7cdd +3595 7ce6 +3596 7ce9 +3597 7ceb +3598 7cf5 +3599 7d03 +3600..3602 7d07 +3603 7d0f +3604..3606 7d11 +3607 7d16 +3608..3609 7d1d +3610 7d23 +3611 7d26 +3612 7d2a +3613 7d2d +3614 7d31 +3615..3617 7d3c +3618..3619 7d40 +3620..3621 7d47 +3622 7d4d +3623 7d51 +3624 7d53 +3625 7d57 +3626..3627 7d59 +3628..3629 7d5c +3630 7d65 +3631 7d67 +3632 7d6a +3633 7d70 +3634 7d78 +3635..3636 7d7a +3637 7d7f +3638..3640 7d81 +3641..3642 7d85 +3643 7d88 +3644..3646 7d8b +3647 7d91 +3648..3649 7d96 +3650..3651 7d9d +3652..3653 7da6 +3654 7daa +3655 7db3 +3656..3657 7db6 +3658 7db9 +3659..3663 7dc2 +3664..3666 7dcc +3667 7dd7 +3668 7dd9 +3669 7e00 +3670 7de2 +3671..3672 7de5 +3673..3674 7dea +3675 7ded +3676 7df1 +3677..3678 7df5 +3679..3680 7df9 +3681 7e08 +3682..3683 7e10 +3684 7e15 +3685 7e17 +3686..3687 7e1c +3688 7e20 +3689..3690 7e27 +3691..3692 7e2c +3693 7e2f +3694 7e33 +3695 7e36 +3696 7e3f +3697..3698 7e44 +3699 7e47 +3700 7e4e +3701 7e50 +3702 7e52 +3703 7e58 +3704 7e5f +3705..3706 7e61 +3707 7e65 +3708 7e6b +3709..3710 7e6e +3711 7e73 +3712 7e78 +3713 7e7e +3714 7e81 +3715..3716 7e86 +3717 7e8a +3718 7e8d +3719 7e91 +3720 7e95 +3721 7e98 +3722 7e9a +3723..3724 7e9d +3725 7f3c +3726 7f3b +3727..3729 7f3d +3730..3731 7f43 +3732 7f47 +3733 7f4f +3734..3735 7f52 +3736..3738 7f5b +3739 7f61 +3740..3743 7f63 +3744 7f6d +3745 7f71 +3746..3749 7f7d +3750 7f8b +3751 7f8d +3752..3754 7f8f +3755..3756 7f96 +3757 7f9c +3758..3759 7fa1 +3760 7fa6 +3761 7faa +3762 7fad +3763 7fb4 +3764 7fbc +3765..3766 7fbf +3767 7fc3 +3768 7fc8 +3769..3770 7fce +3771 7fdb +3772 7fdf +3773 7fe3 +3774 7fe5 +3775 7fe8 +3776 7fec +3777..3778 7fee +3779 7ff2 +3780 7ffa +3781..3783 7ffd +3784..3785 8007 +3786 800a +3787..3789 800d +3790 8011 +3791..3792 8013 +3793 8016 +3794..3797 801d +3798 8024 +3799 8026 +3800 802c +3801 802e +3802 8030 +3803..3804 8034 +3805 8037 +3806..3807 8039 +3808 803c +3809 803e +3810 8040 +3811 8044 +3812 8060 +3813 8064 +3814 8066 +3815 806d +3816 8071 +3817 8075 +3818 8081 +3819 8088 +3820 808e +3821 809c +3822 809e +3823..3824 80a6 +3825 80ab +3826..3827 80b8 +3828 80c8 +3829 80cd +3830 80cf +3831 80d2 +3832..3833 80d4 +3834..3835 80d7 +3836 80e0 +3837..3838 80ed +3839 80f0 +3840..3841 80f2 +3842 80f6 +3843..3844 80f9 +3845 80fe +3846 8103 +3847 810b +3848..3850 8116 +3851 811c +3852 811e +3853 8120 +3854 8124 +3855 8127 +3856 812c +3857 8130 +3858 8135 +3859 813a +3860 813c +3861 8145 +3862 8147 +3863 814a +3864 814c +3865 8152 +3866 8157 +3867..3868 8160 +3869..3871 8167 +3872 816d +3873 816f +3874 8177 +3875 8181 +3876 8190 +3877..3879 8184 +3880 818b +3881 818e +3882 8196 +3883 8198 +3884 819b +3885 819e +3886 81a2 +3887 81ae +3888 81b2 +3889 81b4 +3890 81bb +3891 81cb +3892 81c3 +3893 81c5 +3894 81ca +3895..3896 81ce +3897 81d5 +3898 81d7 +3899 81db +3900..3901 81dd +3902 81e1 +3903 81e4 +3904..3905 81eb +3906..3908 81f0 +3909..3910 81f5 +3911..3912 81f8 +3913 81fd +3914..3915 81ff +3916 8203 +3917 820f +3918..3919 8213 +3920..3921 8219 +3922 821d +3923..3924 8221 +3925 8228 +3926 8232 +3927 8234 +3928 823a +3929..3932 8243 +3933 824b +3934..3935 824e +3936 8251 +3937 8256 +3938 825c +3939 8260 +3940 8263 +3941 8267 +3942 826d +3943 8274 +3944 827b +3945 827d +3946..3948 827f +3949..3950 8283 +3951 8287 +3952..3953 8289 +3954 828e +3955 8291 +3956 8294 +3957 8296 +3958 8298 +3959..3960 829a +3961..3962 82a0 +3963..3964 82a3 +3965..3968 82a7 +3969 82ae +3970 82b0 +3971 82b2 +3972 82b4 +3973 82b7 +3974 82ba +3975 82bc +3976..3977 82be +3978 82c6 +3979 82d0 +3980 82d5 +3981 82da +3982 82e0 +3983 82e2 +3984 82e4 +3985 82e8 +3986 82ea +3987 82ed +3988 82ef +3989..3990 82f6 +3991..3992 82fd +3993..3994 8300 +3995..3996 8307 +3997..3998 830a +3999 8354 +4000 831b +4001..4003 831d +4004..4005 8321 +4006..4008 832c +4009 8330 +4010 8333 +4011 8337 +4012 833a +4013..4014 833c +4015..4017 8342 +4018 8347 +4019..4020 834d +4021 8351 +4022..4024 8355 +4025 8370 +4026 8378 +4027 837d +4028..4029 837f +4030 8382 +4031 8384 +4032 8386 +4033 838d +4034 8392 +4035..4036 8394 +4037..4038 8398 +4039..4041 839b +4042..4043 83a6 +4044 83a9 +4045 83ac +4046..4048 83be +4049 83c7 +4050 83c9 +4051..4053 83cf +4054 83d4 +4055 83dd +4056 8353 +4057 83e8 +4058 83ea +4059 83f6 +4060..4061 83f8 +4062 83fc +4063 8401 +4064 8406 +4065 840a +4066 840f +4067 8411 +4068 8415 +4069 8419 +4070 83ad +4071 842f +4072 8439 +4073 8445 +4074..4075 8447 +4076 844a +4077 844d +4078 844f +4079..4080 8451 +4081 8456 +4082..4084 8458 +4085 845c +4086 8460 +4087..4088 8464 +4089 8467 +4090 846a +4091 8470 +4092..4093 8473 +4094 8476 +4095 8478 +4096..4097 847c +4098 8481 +4099 8485 +4100..4101 8492 +4102 8495 +4103 849e +4104 84a6 +4105..4107 84a8 +4108 84af +4109 84b1 +4110 84b4 +4111 84ba +4112..4113 84bd +4114 84c0 +4115 84c2 +4116..4117 84c7 +4118 84cc +4119 84cf +4120 84d3 +4121 84dc +4122 84e7 +4123 84ea +4124..4127 84ef +4128 84f7 +4129 8532 +4130..4131 84fa +4132 84fd +4133..4134 8502 +4135 8507 +4136 850c +4137 850e +4138 8510 +4139 851c +4140 851e +4141..4144 8522 +4145 8527 +4146..4147 852a +4148 852f +4149..4150 8533 +4151 8536 +4152 853f +4153 8546 +4154..4158 854f +4159 8556 +4160 8559 +4161..4167 855c +4168 8564 +4169 856b +4170 856f +4171..4173 8579 +4174 857d +4175 857f +4176 8581 +4177..4178 8585 +4179 8589 +4180..4181 858b +4182 858f +4183 8593 +4184 8598 +4185 859d +4186..4187 859f +4188 85a2 +4189 85a5 +4190 85a7 +4191 85b4 +4192..4194 85b6 +4195..4198 85bc +4199 85c2 +4200 85c7 +4201..4202 85ca +4203 85ce +4204 85ad +4205 85d8 +4206 85da +4207..4208 85df +4209 85e6 +4210 85e8 +4211 85ed +4212 85f3 +4213 85f6 +4214 85fc +4215..4216 85ff +4217..4218 8604 +4219..4220 860d +4221..4223 8610 +4224..4225 8618 +4226 861b +4227 861e +4228 8621 +4229 8627 +4230 8629 +4231 8636 +4232 8638 +4233 863a +4234..4235 863c +4236 8640 +4237 8642 +4238 8646 +4239..4240 8652 +4241..4244 8656 +4245 865d +4246..4250 8660 +4251 8669 +4252 866c +4253 866f +4254..4256 8675 +4257 867a +4258 868d +4259 8691 +4260 8696 +4261 8698 +4262 869a +4263 869c +4264 86a1 +4265..4267 86a6 +4268 86ad +4269 86b1 +4270..4272 86b3 +4273..4275 86b7 +4276..4278 86bf +4279 86c3 +4280 86c5 +4281..4282 86d1 +4283 86d5 +4284 86d7 +4285 86da +4286 86dc +4287 86e0 +4288 86e3 +4289 86e5 +4290 86e7 +4291 8688 +4292 86fa +4293..4294 86fc +4295..4296 8704 +4297 8707 +4298 870b +4299..4301 870e +4302..4303 8713 +4304 8719 +4305..4306 871e +4307 8721 +4308 8723 +4309 8728 +4310..4311 872e +4312..4313 8731 +4314..4315 8739 +4316..4318 873c +4319 8740 +4320 8743 +4321 8745 +4322 874d +4323 8758 +4324 875d +4325 8761 +4326..4327 8764 +4328 876f +4329..4330 8771 +4331 877b +4332..4338 8783 +4339..4340 878b +4341 8790 +4342 8793 +4343 8795 +4344..4346 8797 +4347 879e +4348 87a0 +4349 87a3 +4350 87a7 +4351..4353 87ac +4354 87b1 +4355 87b5 +4356..4357 87be +4358 87c1 +4359..4361 87c8 +4362 87ce +4363..4364 87d5 +4365..4366 87d9 +4367 87dc +4368 87df +4369..4371 87e2 +4372..4373 87ea +4374 87ed +4375 87f1 +4376 87f3 +4377 87f8 +4378 87fa +4379 87ff +4380 8801 +4381 8803 +4382 8806 +4383..4385 8809 +4386 8810 +4387 8819 +4388..4390 8812 +4391 8818 +4392..4394 881a +4395..4396 881e +4397 8828 +4398..4399 882d +4400 8830 +4401 8832 +4402 8835 +4403 883a +4404 883c +4405 8841 +4406 8843 +4407 8845 +4408..4411 8848 +4412 884e +4413 8851 +4414..4415 8855 +4416 8858 +4417 885a +4418 885c +4419..4420 885f +4421 8864 +4422 8869 +4423 8871 +4424 8879 +4425 887b +4426 8880 +4427 8898 +4428..4430 889a +4431..4432 889f +4433 88a8 +4434 88aa +4435 88ba +4436..4437 88bd +4438 88c0 +4439..4443 88ca +4444..4446 88d1 +4447 88db +4448 88de +4449 88e7 +4450..4452 88ef +4453 88f5 +4454 88f7 +4455 8901 +4456 8906 +4457..4459 890d +4460..4461 8915 +4462..4464 8918 +4465 891c +4466 8920 +4467..4469 8926 +4470..4472 8930 +4473 8935 +4474..4475 8939 +4476 893e +4477 8940 +4478 8942 +4479..4480 8945 +4481 8949 +4482 894f +4483 8952 +4484 8957 +4485..4487 895a +4488..4490 8961 +4491 896b +4492 896e +4493 8970 +4494 8973 +4495 8975 +4496..4499 897a +4500 8989 +4501 898d +4502 8990 +4503..4504 8994 +4505..4506 899b +4507..4508 899f +4509 89a5 +4510 89b0 +4511..4514 89b4 +4515 89bc +4516..4520 89d4 +4521 89e5 +4522 89e9 +4523 89eb +4524 89ed +4525 89f1 +4526 89f3 +4527 89f6 +4528 89f9 +4529 89fd +4530 89ff +4531..4532 8a04 +4533 8a07 +4534 8a0f +4535..4536 8a11 +4537..4538 8a14 +4539 8a1e +4540 8a20 +4541 8a22 +4542 8a24 +4543 8a26 +4544..4545 8a2b +4546 8a2f +4547 8a35 +4548 8a37 +4549..4550 8a3d +4551 8a40 +4552 8a43 +4553 8a45 +4554 8a47 +4555 8a49 +4556..4557 8a4d +4558 8a53 +4559..4561 8a56 +4562..4563 8a5c +4564 8a61 +4565 8a65 +4566 8a67 +4567..4569 8a75 +4570..4572 8a79 +4573..4575 8a7e +4576 8a83 +4577 8a86 +4578 8a8b +4579..4580 8a8f +4581 8a92 +4582..4583 8a96 +4584 8a99 +4585 8a9f +4586 8aa7 +4587 8aa9 +4588..4589 8aae +4590 8ab3 +4591..4592 8ab6 +4593 8abb +4594 8abe +4595 8ac3 +4596 8ac6 +4597..4599 8ac8 +4600 8ad1 +4601..4603 8ad3 +4604 8ad7 +4605 8add +4606 8adf +4607 8aec +4608 8af0 +4609..4611 8af4 +4612 8afc +4613 8aff +4614..4615 8b05 +4616 8b0b +4617 8b11 +4618 8b1c +4619..4620 8b1e +4621 8b0a +4622 8b2d +4623 8b30 +4624 8b37 +4625 8b3c +4626..4630 8b42 +4631 8b48 +4632..4634 8b52 +4635 8b59 +4636 8b4d +4637 8b5e +4638 8b63 +4639 8b6d +4640 8b76 +4641..4642 8b78 +4643 8b7c +4644 8b7e +4645 8b81 +4646..4647 8b84 +4648 8b8b +4649 8b8d +4650 8b8f +4651..4652 8b94 +4653 8b9c +4654..4655 8b9e +4656..4657 8c38 +4658..4659 8c3d +4660 8c45 +4661 8c47 +4662 8c49 +4663 8c4b +4664 8c4f +4665 8c51 +4666..4667 8c53 +4668..4669 8c57 +4670 8c5b +4671 8c5d +4672 8c59 +4673..4674 8c63 +4675 8c66 +4676..4677 8c68 +4678 8c6d +4679 8c73 +4680..4681 8c75 +4682 8c7b +4683 8c7e +4684..4685 8c86 +4686 8c8b +4687 8c90 +4688..4689 8c92 +4690 8c99 +4691..4692 8c9b +4693 8ca4 +4694..4695 8cb9 +4696..4697 8cc5 +4698 8cc9 +4699 8ccb +4700 8ccf +4701 8cd6 +4702 8cd5 +4703 8cd9 +4704 8cdd +4705 8ce1 +4706 8ce8 +4707 8cec +4708..4709 8cef +4710 8cf2 +4711 8cf5 +4712..4713 8cf7 +4714..4715 8cfe +4716 8d01 +4717 8d03 +4718 8d09 +4719 8d12 +4720 8d17 +4721 8d1b +4722 8d65 +4723 8d69 +4724 8d6c +4725 8d6e +4726 8d7f +4727 8d82 +4728 8d84 +4729 8d88 +4730 8d8d +4731..4732 8d90 +4733 8d95 +4734..4736 8d9e +4737 8da6 +4738..4739 8dab +4740 8daf +4741 8db2 +4742 8db5 +4743 8db7 +4744 8db9 +4745 8dbb +4746 8dc0 +4747..4750 8dc5 +4751 8dca +4752 8dce +4753 8dd1 +4754..4755 8dd4 +4756 8dd7 +4757 8dd9 +4758..4759 8de4 +4760 8de7 +4761 8dec +4762 8df0 +4763 8dbc +4764..4765 8df1 +4766 8df4 +4767 8dfd +4768 8e01 +4769..4771 8e04 +4772 8e0b +4773 8e11 +4774 8e14 +4775 8e16 +4776..4779 8e20 +4780..4781 8e26 +4782 8e31 +4783 8e33 +4784..4787 8e36 +4788 8e3d +4789..4790 8e40 +4791 8e4b +4792..4794 8e4d +4795 8e54 +4796..4799 8e5b +4800..4801 8e61 +4802 8e69 +4803..4804 8e6c +4805..4807 8e6f +4808..4810 8e79 +4811..4812 8e82 +4813 8e89 +4814 8e90 +4815 8e92 +4816 8e95 +4817..4818 8e9a +4819..4820 8e9d +4821 8ea2 +4822 8ea7 +4823 8ea9 +4824..4825 8ead +4826 8eb3 +4827 8eb5 +4828..4829 8eba +4830..4831 8ec0 +4832..4833 8ec3 +4834 8ec7 +4835 8ecf +4836 8ed1 +4837 8ed4 +4838 8edc +4839 8ee8 +4840 8eee +4841..4842 8ef0 +4843 8ef7 +4844..4845 8ef9 +4846 8eed +4847 8f00 +4848 8f02 +4849..4850 8f07 +4851..4852 8f0f +4853..4855 8f16 +4856 8f1e +4857..4858 8f20 +4859 8f23 +4860 8f25 +4861..4862 8f27 +4863..4865 8f2c +4866..4869 8f34 +4870 8f3a +4871..4872 8f40 +4873 8f43 +4874 8f47 +4875 8f4f +4876..4880 8f51 +4881 8f58 +4882..4883 8f5d +4884 8f65 +4885 8f9d +4886..4887 8fa0 +4888..4890 8fa4 +4891..4892 8fb5 +4893 8fb8 +4894 8fbe +4895..4896 8fc0 +4897 8fc6 +4898..4899 8fca +4900 8fcd +4901 8fd0 +4902..4903 8fd2 +4904 8fd5 +4905 8fe0 +4906..4907 8fe3 +4908 8fe8 +4909 8fee +4910 8ff1 +4911..4912 8ff5 +4913 8ffb +4914 8ffe +4915 9002 +4916 9004 +4917 9008 +4918 900c +4919 9018 +4920 901b +4921..4922 9028 +4923 902f +4924 902a +4925..4926 902c +4927..4928 9033 +4929 9037 +4930 903f +4931..4932 9043 +4933 904c +4934 905b +4935 905d +4936 9062 +4937..4938 9066 +4939 906c +4940 9070 +4941 9074 +4942 9079 +4943 9085 +4944 9088 +4945..4946 908b +4947 908e +4948 9090 +4949 9095 +4950..4952 9097 +4953 909b +4954..4956 90a0 +4957 90a5 +4958 90b0 +4959..4961 90b2 +4962 90b6 +4963 90bd +4964 90cc +4965 90be +4966..4968 90c3 +4969..4970 90c7 +4971 90d5 +4972..4974 90d7 +4975..4976 90dc +4977 90df +4978 90e5 +4979 90d2 +4980 90f6 +4981 90eb +4982..4983 90ef +4984 90f4 +4985..4987 90fe +4988..4990 9104 +4991 9108 +4992 910d +4993 9110 +4994 9114 +4995..4997 9116 +4998 911a +4999 911c +5000 911e +5001 9120 +5002 9125 +5003..5004 9122 +5005 9127 +5006 9129 +5007..5008 912e +5009 9131 +5010 9134 +5011..5012 9136 +5013..5014 9139 +5015..5016 913c +5017 9143 +5018..5019 9147 +5020 914f +5021 9153 +5022 9157 +5023..5025 9159 +5026 9161 +5027 9164 +5028 9167 +5029 916d +5030 9174 +5031..5033 9179 +5034 9181 +5035 9183 +5036..5037 9185 +5038 918a +5039 918e +5040 9191 +5041..5043 9193 +5044 9198 +5045 919e +5046 91a1 +5047 91a6 +5048 91a8 +5049..5051 91ac +5052..5055 91b0 +5056 91b6 +5057..5059 91bb +5060 91bf +5061..5062 91c2 +5063 91c5 +5064..5065 91d3 +5066 91d7 +5067..5068 91d9 +5069 91de +5070..5071 91e4 +5072..5073 91e9 +5074..5079 91ec +5080 91f7 +5081 91f9 +5082 91fb +5083 91fd +5084..5085 9200 +5086..5089 9204 +5090..5091 9209 +5092 920c +5093 9210 +5094..5095 9212 +5096 9216 +5097 9218 +5098..5099 921c +5100..5103 9223 +5104 9228 +5105..5107 922e +5108 9233 +5109..5110 9235 +5111..5113 9238 +5114 923c +5115 923e +5116 9240 +5117..5118 9242 +5119..5120 9246 +5121 924a +5122..5124 924d +5125 9251 +5126..5127 9258 +5128..5129 925c +5130..5131 9260 +5132 9265 +5133..5135 9267 +5136..5138 926e +5139..5143 9275 +5144..5146 927b +5147 927f +5148..5150 9288 +5151..5152 928d +5153 9292 +5154 9297 +5155 9299 +5156..5157 929f +5158..5159 92a4 +5160..5161 92a7 +5162 92ab +5163 92af +5164 92b2 +5165 92b6 +5166 92b8 +5167..5170 92ba +5171..5175 92bf +5176..5179 92c5 +5180..5183 92cb +5184 92d0 +5185 92d3 +5186 92d5 +5187..5189 92d7 +5190..5191 92dc +5192..5194 92df +5195 92e3 +5196 92e5 +5197..5198 92e7 +5199 92ec +5200 92ee +5201 92f0 +5202 92f9 +5203 92fb +5204..5205 92ff +5206 9302 +5207 9308 +5208 930d +5209 9311 +5210..5211 9314 +5212..5215 931c +5216 9321 +5217..5218 9324 +5219 9327 +5220..5221 9329 +5222..5223 9333 +5224..5225 9336 +5226..5228 9347 +5229..5231 9350 +5232 9355 +5233..5234 9357 +5235 935a +5236 935e +5237..5238 9364 +5239 9367 +5240..5241 9369 +5242 936d +5243..5245 936f +5246..5247 9373 +5248 9376 +5249 937a +5250 937d +5251..5254 937f +5255 9388 +5256..5257 938a +5258 938d +5259 938f +5260 9392 +5261 9395 +5262 9398 +5263 939b +5264 939e +5265 93a1 +5266..5267 93a3 +5268 93a6 +5269 93a8 +5270 93ab +5271..5273 93b4 +5274 93ba +5275 93a9 +5276 93c1 +5277..5280 93c4 +5281..5285 93c9 +5286 93d3 +5287 93d9 +5288 93dc +5289..5290 93de +5291 93e2 +5292..5293 93e6 +5294 93f9 +5295..5296 93f7 +5297..5298 93fa +5299 93fd +5300..5301 9401 +5302 9404 +5303..5304 9408 +5305..5307 940d +5308..5310 9415 +5311 941f +5312..5313 942e +5314..5317 9431 +5318 943b +5319 943f +5320 943d +5321 9443 +5322 9445 +5323 9448 +5324 944a +5325 944c +5326 9455 +5327 9459 +5328 945c +5329 945f +5330 9461 +5331 9463 +5332 9468 +5333 946b +5334..5336 946d +5337..5338 9471 +5339 9484 +5340 9483 +5341..5342 9578 +5343 957e +5344 9584 +5345 9588 +5346..5348 958c +5349..5351 959d +5352 95a1 +5353 95a6 +5354 95a9 +5355..5356 95ab +5357 95b4 +5358 95b6 +5359 95ba +5360 95bd +5361 95bf +5362 95c6 +5363..5364 95c8 +5365 95cb +5366..5369 95d0 +5370..5371 95d9 +5372..5375 95dd +5376 95e4 +5377 95e6 +5378..5379 961d +5380 9622 +5381..5383 9624 +5384 962c +5385 9631 +5386 9633 +5387..5390 9637 +5391..5392 963c +5393 9641 +5394 9652 +5395 9654 +5396..5398 9656 +5399 9661 +5400 966e +5401 9674 +5402..5403 967b +5404..5405 967e +5406..5409 9681 +5410 9689 +5411 9691 +5412 9696 +5413 969a +5414 969d +5415 969f +5416..5418 96a4 +5419 96a9 +5420..5421 96ae +5422 96b3 +5423 96ba +5424 96ca +5425 96d2 +5426 5db2 +5427 96d8 +5428 96da +5429..5431 96dd +5432 96e9 +5433 96ef +5434 96f1 +5435 96fa +5436..5437 9702 +5438 9705 +5439 9709 +5440..5441 971a +5442 971d +5443..5445 9721 +5446 9728 +5447 9731 +5448 9733 +5449 9741 +5450 9743 +5451 974a +5452..5453 974e +5454 9755 +5455..5456 9757 +5457..5458 975a +5459 9763 +5460 9767 +5461 976a +5462 976e +5463 9773 +5464..5466 9776 +5467 977b +5468 977d +5469..5470 977f +5471 9789 +5472..5474 9795 +5475..5476 9799 +5477..5478 979e +5479 97a2 +5480 97ac +5481 97ae +5482..5483 97b1 +5484..5485 97b5 +5486..5488 97b8 +5489 97bc +5490..5491 97be +5492 97c1 +5493..5494 97c4 +5495 97c7 +5496..5497 97c9 +5498..5500 97cc +5501..5502 97d0 +5503 97d4 +5504..5506 97d7 +5507..5508 97dd +5509 97e0 +5510 97db +5511 97e1 +5512 97e4 +5513 97ef +5514 97f1 +5515 97f4 +5516..5517 97f7 +5518 97fa +5519 9807 +5520 980a +5521 9819 +5522..5523 980d +5524 9814 +5525 9816 +5526 981c +5527 981e +5528 9820 +5529 9823 +5530 9826 +5531 982b +5532..5534 982e +5535..5536 9832 +5537 9835 +5538 9825 +5539 983e +5540 9844 +5541 9847 +5542 984a +5543..5545 9851 +5546..5547 9856 +5548..5549 9859 +5550..5551 9862 +5552..5553 9865 +5554 986a +5555 986c +5556 98ab +5557..5558 98ad +5559 98b0 +5560 98b4 +5561..5562 98b7 +5563..5564 98ba +5565 98bf +5566 98c2 +5567 98c5 +5568 98c8 +5569 98cc +5570 98e1 +5571 98e3 +5572..5574 98e5 +5575 98ea +5576 98f3 +5577 98f6 +5578 9902 +5579..5580 9907 +5581 9911 +5582..5584 9915 +5585..5587 991a +5588 991f +5589 9922 +5590..5591 9926 +5592 992b +5593..5597 9931 +5598..5601 9939 +5602..5603 9940 +5604..5606 9946 +5607..5608 994d +5609 9954 +5610..5611 9958 +5612..5613 995b +5614..5616 995e +5617 999b +5618 999d +5619 999f +5620 99a6 +5621..5623 99b0 +5624 99b5 +5625..5626 99b9 +5627 99bd +5628 99bf +5629 99c3 +5630 99c9 +5631..5632 99d3 +5633..5634 99d9 +5635 99dc +5636 99de +5637 99e7 +5638..5640 99ea +5641 99f0 +5642..5643 99f4 +5644 99f9 +5645..5646 99fd +5647..5649 9a02 +5650..5651 9a0b +5652..5653 9a10 +5654 9a16 +5655 9a1e +5656 9a20 +5657..5659 9a22 +5660 9a27 +5661..5662 9a2d +5663 9a33 +5664..5665 9a35 +5666 9a38 +5667 9a47 +5668 9a41 +5669 9a44 +5670..5672 9a4a +5673 9a4e +5674 9a51 +5675 9a54 +5676 9a56 +5677 9a5d +5678 9aaa +5679 9aac +5680..5681 9aae +5682 9ab2 +5683..5685 9ab4 +5686 9ab9 +5687 9abb +5688..5689 9abe +5690 9ac1 +5691 9ac3 +5692 9ac6 +5693 9ac8 +5694 9ace +5695 9ad0 +5696 9ad2 +5697..5699 9ad5 +5700..5701 9adb +5702 9ae0 +5703..5704 9ae4 +5705 9ae7 +5706 9ae9 +5707 9aec +5708..5709 9af2 +5710 9af5 +5711..5712 9af9 +5713 9afd +5714..5720 9aff +5721..5722 9b08 +5723..5726 9b0b +5727 9b10 +5728 9b12 +5729 9b16 +5730 9b19 +5731..5732 9b1b +5733 9b20 +5734 9b26 +5735 9b2b +5736 9b2d +5737..5739 9b33 +5740 9b37 +5741..5742 9b39 +5743 9b3d +5744 9b48 +5745..5746 9b4b +5747..5749 9b55 +5750 9b5b +5751 9b5e +5752 9b61 +5753 9b63 +5754..5755 9b65 +5756 9b68 +5757..5761 9b6a +5762 9b73 +5763 9b75 +5764..5766 9b77 +5767..5768 9b7f +5769..5772 9b84 +5773..5775 9b89 +5776 9b8d +5777..5778 9b8f +5779 9b94 +5780 9b9a +5781..5782 9b9d +5783..5784 9ba6 +5785 9ba9 +5786 9bac +5787..5789 9bb0 +5790..5791 9bb7 +5792..5793 9bbb +5794..5795 9bbe +5796 9bc1 +5797..5798 9bc7 +5799 9bce +5800 9bd0 +5801..5802 9bd7 +5803 9bdd +5804 9bdf +5805 9be5 +5806 9be7 +5807..5808 9bea +5809 9bef +5810 9bf3 +5811..5814 9bf7 +5815 9bfd +5816..5817 9bff +5818 9c02 +5819 9c0b +5820 9c0f +5821 9c11 +5822 9c16 +5823..5825 9c18 +5826 9c1c +5827 9c1e +5828..5829 9c22 +5830..5834 9c26 +5835 9c31 +5836..5838 9c35 +5839 9c3d +5840 9c41 +5841..5843 9c43 +5844..5845 9c49 +5846..5848 9c4e +5849..5850 9c53 +5851 9c56 +5852 9c58 +5853 9c5b +5854..5856 9c5d +5857 9c63 +5858..5859 9c69 +5860 9c5c +5861 9c6b +5862 9c68 +5863 9c6e +5864 9c70 +5865 9c72 +5866 9c75 +5867 9c77 +5868 9c7b +5869 9ce6 +5870 9cf2 +5871 9cf7 +5872 9cf9 +5873 9d0b +5874 9d02 +5875 9d11 +5876..5877 9d17 +5878..5880 9d1c +5881..5882 9d2f +5883..5885 9d32 +5886 9d3a +5887 9d3c +5888 9d45 +5889 9d3d +5890..5891 9d42 +5892 9d47 +5893 9d4a +5894..5895 9d53 +5896 9d5f +5897 9d63 +5898 9d62 +5899 9d65 +5900..5902 9d69 +5903 9d70 +5904..5905 9d76 +5906..5907 9d7b +5908 9d7e +5909..5910 9d83 +5911 9d86 +5912 9d8a +5913..5914 9d8d +5915..5916 9d92 +5917..5920 9d95 +5921 9da1 +5922 9daa +5923 9dac +5924 9dae +5925 9db1 +5926 9db5 +5927 9db9 +5928 9dbc +5929 9dbf +5930 9dc3 +5931 9dc7 +5932..5933 9dc9 +5934..5937 9dd4 +5938 9dda +5939..5941 9dde +5942 9de5 +5943 9de7 +5944 9de9 +5945 9deb +5946 9dee +5947 9df0 +5948..5949 9df3 +5950 9dfe +5951 9e0a +5952 9e02 +5953 9e07 +5954 9e0e +5955..5957 9e10 +5958..5959 9e15 +5960 9e19 +5961..5962 9e1c +5963..5965 9e7a +5966 9e80 +5967..5970 9e82 +5971 9e87 +5972..5973 9e8e +5974 9e96 +5975 9e98 +5976 9e9b +5977 9e9e +5978 9ea4 +5979 9ea8 +5980 9eac +5981..5983 9eae +5984..5986 9eb3 +5987 9ec6 +5988 9ec8 +5989 9ecb +5990 9ed5 +5991 9edf +5992 9ee4 +5993 9ee7 +5994..5996 9eec +5997..5999 9ef0 +6000 9ef5 +6001 9ef8 +6002 9eff +6003..6004 9f02 +6005 9f09 +6006..6009 9f0f +6010 9f14 +6011..6012 9f16 +6013..6015 9f19 +6016 9f1f +6017 9f22 +6018 9f26 +6019..6020 9f2a +6021 9f2f +6022..6023 9f31 +6024 9f34 +6025 9f37 +6026..6027 9f39 +6028..6029 9f3c +6030 9f3f +6031 9f41 +6032..6036 9f43 +6037 9f53 +6038..6041 9f55 +6042 9f5a +6043..6044 9f5d +6045..6046 9f68 +6047..6051 9f6d +6052 9f73 +6053 9f75 +6054 9f7a +6055 9f7d +6056..6059 9f8f +6060 9f94 +6061..6062 9f96 +6063 9f9e +6064..6066 9fa1 +6067 9fa5 diff --git a/fonts/cid/fontforge/Adobe-Korea1-2.cidmap b/fonts/cid/fontforge/Adobe-Korea1-2.cidmap new file mode 100644 index 000000000..1588b2961 --- /dev/null +++ b/fonts/cid/fontforge/Adobe-Korea1-2.cidmap @@ -0,0 +1,8543 @@ +18351 18351 +0 /.notdef +1..95 0020 +96 20a9 +97 2010 +98 00a9 +101 3164 +102..103 3001 +104 30fb +105 2025 +106 22ef +107 00a8 +108 3003 +109..110 2013 +111 2016 +112 ff3c +113 ff5e +114..115 2018 +116..117 201c +118..119 3014 +120..129 3008 +130 00b1 +131 00d7 +132 00f7 +133 2260 +134..135 2264 +136 221e +137 2234 +138 00b0 +139..140 2032 +141 2103 +142 212b +143..144 ffe0 +145 ffe5 +146 2642 +147 2640 +148 2220 +149 22a5 +150 2312 +151 2202 +152 2207 +153 2261 +154 2252 +155 00a7 +156 203b +157 2606 +158 2605 +159 25cb +160 25cf +161 25ce +162 25c7 +163 25c6 +164 25a1 +165 25a0 +166 25b3 +167 25b2 +168 25bd +169 25bc +170 2192 +171..172 2190 +173..174 2193 +175 3013 +176 00ab +177 00bb +178 221a +179 223d +180 221d +181 2235 +182..183 222b +184 2208 +185 220b +186..187 2286 +188..189 2282 +190 222a +191 2229 +192..193 2227 +194 ffe2 +195 21d2 +196 21d4 +197 2200 +198 2203 +199 00b4 +200 02dc +201 02c7 +202 02d8 +203 02dd +204 02da +205 02d9 +206 00b8 +207 02db +208 00a1 +209 00bf +210 2236 +211 222e +212 2211 +213 220f +214 00a4 +215 2109 +216 2030 +217 25c1 +218 25c0 +219 25b7 +220 25b6 +221 2664 +222..223 2660 +224 2665 +225 2667 +226 2663 +227 25c9 +228 25c8 +229 25a3 +230..231 25d0 +232 2592 +233..234 25a4 +235 25a8 +236 25a7 +237 25a6 +238 25a9 +239 2668 +240 260f +241 260e +242 261c +243 261e +244 00b6 +245..246 2020 +247 2195 +248 2197 +249 2199 +250 2196 +251 2198 +252 266d +253..254 2669 +255 266c +256 327f +257 321c +258 2116 +259 33c7 +260 2122 +261 33c2 +262 33d8 +263 2121 +264..322 ff01 +323 ffe6 +324..356 ff3d +357 ffe3 +358..408 3131 +409..450 3165 +451..460 2170 +461..470 2160 +471..487 0391 +488..494 03a3 +495..511 03b1 +512..518 03c3 +519 2500 +520 2502 +521 250c +522 2510 +523 2518 +524 2514 +525 251c +526 252c +527 2524 +528 2534 +529 253c +530 2501 +531 2503 +532 250f +533 2513 +534 251b +535 2517 +536 2523 +537 2533 +538 252b +539 253b +540 254b +541 2520 +542 252f +543 2528 +544 2537 +545 253f +546 251d +547 2530 +548 2525 +549 2538 +550 2542 +551 2512 +552 2511 +553 251a +554 2519 +555 2516 +556 2515 +557 250e +558 250d +559..560 251e +561..562 2521 +563..564 2526 +565..566 2529 +567..568 252d +569..570 2531 +571..572 2535 +573..574 2539 +575..576 253d +577..578 2540 +579..586 2543 +587..589 3395 +590 2113 +591 3398 +592 33c4 +593..596 33a3 +597..606 3399 +607 33ca +608..610 338d +611 33cf +612..613 3388 +614 33c8 +615..616 33a7 +617..626 33b0 +627..631 3380 +632..637 33ba +638..642 3390 +643 2126 +644..645 33c0 +646..648 338a +649 33d6 +650 33c5 +651..653 33ad +654 33db +655..658 33a9 +659 33dd +660 33d0 +661 33d3 +662 33c3 +663 33c9 +664 33dc +665 33c6 +666 00c6 +667 00d0 +668 00aa +669 0126 +670 0132 +671 013f +672 0141 +673 00d8 +674 0152 +675 00ba +676 00de +677 0166 +678 014a +679..706 3260 +707..732 24d0 +733..747 2460 +748 00bd +749..750 2153 +751 00bc +752 00be +753..756 215b +757 00e6 +758 0111 +759 00f0 +760 0127 +761 0131 +762 0133 +763 0138 +764 0140 +765 0142 +766 00f8 +767 0153 +768 00df +769 00fe +770 0167 +771 014b +772 0149 +773..800 3200 +801..826 249c +827..841 2474 +842 00b9 +843..844 00b2 +845 2074 +846 207f +847..850 2081 +851..933 3041 +934..1019 30a1 +1020..1025 0410 +1026 0401 +1027..1058 0416 +1059 0451 +1060..1085 0436 +1086..1087 ac00 +1088 ac04 +1089..1092 ac07 +1093..1100 ac10 +1101..1105 ac19 +1106 ac20 +1107 ac24 +1108..1109 ac2c +1110..1112 ac2f +1113..1114 ac38 +1115 ac3c +1116 ac40 +1117 ac4b +1118 ac4d +1119 ac54 +1120 ac58 +1121 ac5c +1122..1123 ac70 +1124 ac74 +1125..1126 ac77 +1127 ac7a +1128..1129 ac80 +1130..1133 ac83 +1134..1137 ac89 +1138 ac90 +1139 ac94 +1140..1141 ac9c +1142..1144 ac9f +1145..1147 aca8 +1148 acac +1149..1150 acaf +1151..1152 acb8 +1153..1155 acbb +1156 acc1 +1157 acc4 +1158 acc8 +1159 accc +1160 acd5 +1161 acd7 +1162..1163 ace0 +1164 ace4 +1165..1166 ace7 +1167 acea +1168 acec +1169..1171 acef +1172 acf3 +1173..1174 acf5 +1175..1176 acfc +1177 ad00 +1178 ad04 +1179 ad06 +1180..1181 ad0c +1182 ad0f +1183 ad11 +1184 ad18 +1185 ad1c +1186 ad20 +1187 ad29 +1188..1189 ad2c +1190..1191 ad34 +1192 ad38 +1193 ad3c +1194..1195 ad44 +1196 ad47 +1197 ad49 +1198 ad50 +1199 ad54 +1200 ad58 +1201 ad61 +1202 ad63 +1203..1204 ad6c +1205 ad70 +1206..1209 ad73 +1210..1212 ad7b +1213 ad7f +1214..1215 ad81 +1216..1217 ad88 +1218 ad8c +1219 ad90 +1220..1221 ad9c +1222 ada4 +1223 adb7 +1224..1225 adc0 +1226 adc4 +1227 adc8 +1228..1229 add0 +1230 add3 +1231 addc +1232 ade0 +1233 ade4 +1234..1235 adf8 +1236 adfc +1237..1239 adff +1240..1241 ae08 +1242 ae0b +1243 ae0d +1244 ae14 +1245..1246 ae30 +1247 ae34 +1248..1249 ae37 +1250 ae3a +1251..1252 ae40 +1253 ae43 +1254..1255 ae45 +1256 ae4a +1257..1259 ae4c +1260 ae50 +1261 ae54 +1262 ae56 +1263..1264 ae5c +1265..1267 ae5f +1268 ae65 +1269..1270 ae68 +1271 ae6c +1272 ae70 +1273..1274 ae78 +1275..1277 ae7b +1278..1279 ae84 +1280 ae8c +1281..1283 aebc +1284 aec0 +1285 aec4 +1286..1287 aecc +1288..1290 aecf +1291..1292 aed8 +1293 aedc +1294 aee8 +1295 aeeb +1296 aeed +1297 aef4 +1298 aef8 +1299 aefc +1300..1301 af07 +1302 af0d +1303 af10 +1304..1305 af2c +1306 af30 +1307 af32 +1308 af34 +1309..1310 af3c +1311 af3f +1312..1314 af41 +1315..1316 af48 +1317 af50 +1318..1319 af5c +1320..1321 af64 +1322 af79 +1323 af80 +1324 af84 +1325 af88 +1326..1327 af90 +1328 af95 +1329 af9c +1330..1331 afb8 +1332 afbc +1333 afc0 +1334..1336 afc7 +1337 afcb +1338..1339 afcd +1340 afd4 +1341 afdc +1342..1343 afe8 +1344..1345 aff0 +1346 aff4 +1347 aff8 +1348..1349 b000 +1350 b004 +1351 b00c +1352 b010 +1353 b014 +1354..1355 b01c +1356 b028 +1357..1358 b044 +1359 b048 +1360 b04a +1361 b04c +1362 b04e +1363..1365 b053 +1366 b057 +1367 b059 +1368 b05d +1369..1370 b07c +1371 b080 +1372 b084 +1373..1374 b08c +1375 b08f +1376 b091 +1377..1379 b098 +1380 b09c +1381..1384 b09f +1385..1386 b0a8 +1387..1391 b0ab +1392 b0b1 +1393..1395 b0b3 +1396 b0b8 +1397 b0bc +1398..1399 b0c4 +1400..1402 b0c7 +1403..1404 b0d0 +1405 b0d4 +1406 b0d8 +1407 b0e0 +1408 b0e5 +1409..1410 b108 +1411..1412 b10b +1413 b110 +1414..1415 b112 +1416..1417 b118 +1418..1420 b11b +1421..1423 b123 +1424 b128 +1425 b12c +1426..1427 b134 +1428..1430 b137 +1431..1432 b140 +1433 b144 +1434 b148 +1435..1436 b150 +1437..1438 b154 +1439 b158 +1440 b15c +1441 b160 +1442..1443 b178 +1444 b17c +1445 b180 +1446 b182 +1447..1448 b188 +1449 b18b +1450 b18d +1451..1453 b192 +1454 b198 +1455 b19c +1456 b1a8 +1457 b1cc +1458 b1d0 +1459 b1d4 +1460..1461 b1dc +1462 b1df +1463..1464 b1e8 +1465 b1ec +1466 b1f0 +1467 b1f9 +1468 b1fb +1469 b1fd +1470..1471 b204 +1472 b208 +1473..1474 b20b +1475..1476 b214 +1477 b217 +1478 b219 +1479 b220 +1480 b234 +1481 b23c +1482 b258 +1483 b25c +1484 b260 +1485..1486 b268 +1487..1488 b274 +1489 b27c +1490..1491 b284 +1492 b289 +1493..1494 b290 +1495 b294 +1496..1498 b298 +1499..1500 b2a0 +1501 b2a3 +1502..1503 b2a5 +1504 b2aa +1505 b2ac +1506 b2b0 +1507 b2b4 +1508..1509 b2c8 +1510 b2cc +1511 b2d0 +1512 b2d2 +1513..1514 b2d8 +1515 b2db +1516 b2dd +1517 b2e2 +1518..1520 b2e4 +1521 b2e8 +1522..1526 b2eb +1527..1529 b2f3 +1530..1534 b2f7 +1535..1537 b2ff +1538 b304 +1539 b308 +1540..1541 b310 +1542..1544 b313 +1545 b31c +1546..1548 b354 +1549 b358 +1550..1551 b35b +1552..1553 b35e +1554..1555 b364 +1556 b367 +1557 b369 +1558 b36b +1559 b36e +1560..1561 b370 +1562 b374 +1563 b378 +1564..1565 b380 +1566..1568 b383 +1569 b38c +1570 b390 +1571 b394 +1572..1573 b3a0 +1574 b3a8 +1575 b3ac +1576..1577 b3c4 +1578 b3c8 +1579..1580 b3cb +1581 b3ce +1582 b3d0 +1583..1584 b3d4 +1585 b3d7 +1586 b3d9 +1587 b3db +1588 b3dd +1589 b3e0 +1590 b3e4 +1591 b3e8 +1592 b3fc +1593 b410 +1594 b418 +1595 b41c +1596 b420 +1597..1598 b428 +1599 b42b +1600 b434 +1601..1602 b450 +1603 b454 +1604 b458 +1605..1606 b460 +1607 b463 +1608 b465 +1609 b46c +1610 b480 +1611 b488 +1612 b49d +1613 b4a4 +1614 b4a8 +1615 b4ac +1616 b4b5 +1617 b4b7 +1618 b4b9 +1619 b4c0 +1620 b4c4 +1621 b4c8 +1622 b4d0 +1623 b4d5 +1624..1625 b4dc +1626 b4e0 +1627..1628 b4e3 +1629 b4e6 +1630..1631 b4ec +1632 b4ef +1633 b4f1 +1634 b4f8 +1635..1636 b514 +1637 b518 +1638..1639 b51b +1640..1641 b524 +1642..1645 b527 +1646..1647 b530 +1648 b534 +1649 b538 +1650..1651 b540 +1652..1654 b543 +1655..1657 b54b +1658 b550 +1659 b554 +1660..1661 b55c +1662..1664 b55f +1665..1666 b5a0 +1667 b5a4 +1668 b5a8 +1669..1670 b5aa +1671..1672 b5b0 +1673..1675 b5b3 +1676..1678 b5bb +1679 b5c0 +1680 b5c4 +1681..1682 b5cc +1683..1685 b5cf +1686 b5d8 +1687 b5ec +1688..1689 b610 +1690 b614 +1691 b618 +1692 b625 +1693 b62c +1694 b634 +1695 b648 +1696 b664 +1697 b668 +1698..1699 b69c +1700 b6a0 +1701 b6a4 +1702..1703 b6ab +1704 b6b1 +1705 b6d4 +1706 b6f0 +1707 b6f4 +1708 b6f8 +1709..1710 b700 +1711 b705 +1712..1713 b728 +1714 b72c +1715..1716 b72f +1717..1718 b738 +1719 b73b +1720 b744 +1721 b748 +1722 b74c +1723..1724 b754 +1725 b760 +1726 b764 +1727 b768 +1728..1729 b770 +1730 b773 +1731 b775 +1732..1733 b77c +1734 b780 +1735 b784 +1736..1737 b78c +1738..1741 b78f +1742..1745 b796 +1746 b79c +1747 b7a0 +1748..1749 b7a8 +1750..1752 b7ab +1753..1754 b7b4 +1755 b7b8 +1756 b7c7 +1757 b7c9 +1758..1759 b7ec +1760 b7f0 +1761 b7f4 +1762..1763 b7fc +1764..1766 b7ff +1767..1769 b807 +1770 b80c +1771 b810 +1772..1773 b818 +1774 b81b +1775 b81d +1776..1777 b824 +1778 b828 +1779 b82c +1780..1781 b834 +1782..1784 b837 +1785 b840 +1786 b844 +1787 b851 +1788 b853 +1789..1790 b85c +1791 b860 +1792 b864 +1793..1794 b86c +1795 b86f +1796 b871 +1797 b878 +1798 b87c +1799 b88d +1800 b8a8 +1801 b8b0 +1802 b8b4 +1803 b8b8 +1804..1805 b8c0 +1806 b8c3 +1807 b8c5 +1808 b8cc +1809 b8d0 +1810 b8d4 +1811 b8dd +1812 b8df +1813 b8e1 +1814..1815 b8e8 +1816 b8ec +1817 b8f0 +1818..1819 b8f8 +1820 b8fb +1821 b8fd +1822 b904 +1823 b918 +1824 b920 +1825..1826 b93c +1827 b940 +1828 b944 +1829 b94c +1830 b94f +1831 b951 +1832..1833 b958 +1834 b95c +1835 b960 +1836..1837 b968 +1838 b96b +1839 b96d +1840..1841 b974 +1842 b978 +1843 b97c +1844..1845 b984 +1846 b987 +1847..1848 b989 +1849..1850 b98d +1851..1852 b9ac +1853 b9b0 +1854 b9b4 +1855..1856 b9bc +1857 b9bf +1858 b9c1 +1859..1860 b9c8 +1861 b9cc +1862..1866 b9ce +1867..1868 b9d8 +1869 b9db +1870..1871 b9dd +1872 b9e1 +1873..1875 b9e3 +1876 b9e8 +1877 b9ec +1878..1879 b9f4 +1880..1883 b9f7 +1884..1885 ba00 +1886 ba08 +1887 ba15 +1888..1889 ba38 +1890 ba3c +1891 ba40 +1892 ba42 +1893..1894 ba48 +1895 ba4b +1896..1897 ba4d +1898..1900 ba53 +1901 ba58 +1902 ba5c +1903..1904 ba64 +1905..1907 ba67 +1908..1909 ba70 +1910 ba74 +1911 ba78 +1912..1914 ba83 +1915 ba87 +1916 ba8c +1917..1918 baa8 +1919..1920 baab +1921 bab0 +1922 bab2 +1923..1924 bab8 +1925 babb +1926 babd +1927 bac4 +1928 bac8 +1929..1930 bad8 +1931 bafc +1932 bb00 +1933 bb04 +1934 bb0d +1935 bb0f +1936 bb11 +1937 bb18 +1938 bb1c +1939 bb20 +1940 bb29 +1941 bb2b +1942..1944 bb34 +1945 bb38 +1946..1949 bb3b +1950..1951 bb44 +1952 bb47 +1953 bb49 +1954 bb4d +1955..1956 bb4f +1957 bb54 +1958 bb58 +1959 bb61 +1960 bb63 +1961 bb6c +1962 bb88 +1963 bb8c +1964 bb90 +1965 bba4 +1966 bba8 +1967 bbac +1968 bbb4 +1969 bbb7 +1970 bbc0 +1971 bbc4 +1972 bbc8 +1973 bbd0 +1974 bbd3 +1975..1976 bbf8 +1977 bbfc +1978..1979 bbff +1980 bc02 +1981..1982 bc08 +1983..1985 bc0b +1986 bc0f +1987 bc11 +1988..1992 bc14 +1993..1997 bc1b +1998..1999 bc24 +2000 bc27 +2001 bc29 +2002 bc2d +2003..2004 bc30 +2005 bc34 +2006 bc38 +2007..2008 bc40 +2009..2011 bc43 +2012 bc49 +2013..2014 bc4c +2015 bc50 +2016 bc5d +2017..2018 bc84 +2019 bc88 +2020..2021 bc8b +2022 bc8e +2023..2024 bc94 +2025 bc97 +2026..2027 bc99 +2028..2029 bca0 +2030 bca4 +2031..2032 bca7 +2033..2034 bcb0 +2035..2037 bcb3 +2038..2039 bcbc +2040 bcc0 +2041 bcc4 +2042 bccd +2043..2045 bccf +2046 bcd5 +2047 bcd8 +2048 bcdc +2049..2051 bcf4 +2052 bcf8 +2053 bcfc +2054..2055 bd04 +2056 bd07 +2057 bd09 +2058 bd10 +2059 bd14 +2060 bd24 +2061 bd2c +2062 bd40 +2063..2064 bd48 +2065 bd4c +2066 bd50 +2067..2068 bd58 +2069 bd64 +2070 bd68 +2071..2072 bd80 +2073 bd84 +2074..2077 bd87 +2078..2079 bd90 +2080 bd93 +2081 bd95 +2082..2083 bd99 +2084 bd9c +2085 bda4 +2086 bdb0 +2087 bdb8 +2088..2089 bdd4 +2090 bdd8 +2091 bddc +2092 bde9 +2093 bdf0 +2094 bdf4 +2095 bdf8 +2096 be00 +2097 be03 +2098 be05 +2099..2100 be0c +2101 be10 +2102 be14 +2103..2104 be1c +2105 be1f +2106..2107 be44 +2108 be48 +2109 be4c +2110 be4e +2111..2112 be54 +2113 be57 +2114..2116 be59 +2117..2118 be60 +2119 be64 +2120 be68 +2121 be6a +2122..2123 be70 +2124..2126 be73 +2127..2129 be7b +2130 be80 +2131 be84 +2132..2133 be8c +2134..2136 be8f +2137..2138 be98 +2139 bea8 +2140..2141 bed0 +2142 bed4 +2143..2144 bed7 +2145 bee0 +2146..2148 bee3 +2149 beec +2150 bf01 +2151..2152 bf08 +2153..2154 bf18 +2155..2157 bf1b +2158..2159 bf40 +2160 bf44 +2161 bf48 +2162..2163 bf50 +2164 bf55 +2165 bf94 +2166 bfb0 +2167 bfc5 +2168..2169 bfcc +2170 bfd0 +2171 bfd4 +2172 bfdc +2173 bfdf +2174 bfe1 +2175 c03c +2176 c051 +2177 c058 +2178 c05c +2179 c060 +2180..2181 c068 +2182..2183 c090 +2184 c094 +2185 c098 +2186..2187 c0a0 +2188 c0a3 +2189 c0a5 +2190..2191 c0ac +2192..2193 c0af +2194..2197 c0b3 +2198..2199 c0bc +2200..2202 c0bf +2203 c0c5 +2204..2205 c0c8 +2206 c0cc +2207 c0d0 +2208..2209 c0d8 +2210..2212 c0db +2213..2214 c0e4 +2215 c0e8 +2216 c0ec +2217..2218 c0f4 +2219 c0f7 +2220 c0f9 +2221 c100 +2222 c104 +2223 c108 +2224 c110 +2225 c115 +2226..2230 c11c +2231..2232 c123 +2233..2234 c126 +2235..2236 c12c +2237..2239 c12f +2240 c136 +2241..2242 c138 +2243 c13c +2244 c140 +2245..2246 c148 +2247..2249 c14b +2250..2251 c154 +2252 c158 +2253 c15c +2254..2255 c164 +2256..2258 c167 +2259 c170 +2260 c174 +2261 c178 +2262 c185 +2263..2265 c18c +2266 c190 +2267 c194 +2268 c196 +2269..2270 c19c +2271 c19f +2272 c1a1 +2273 c1a5 +2274..2275 c1a8 +2276 c1ac +2277 c1b0 +2278 c1bd +2279 c1c4 +2280 c1c8 +2281 c1cc +2282 c1d4 +2283..2284 c1d7 +2285 c1e0 +2286 c1e4 +2287 c1e8 +2288..2289 c1f0 +2290 c1f3 +2291..2292 c1fc +2293 c200 +2294 c204 +2295..2296 c20c +2297 c20f +2298 c211 +2299..2300 c218 +2301 c21c +2302..2303 c21f +2304..2305 c228 +2306 c22b +2307 c22d +2308 c22f +2309..2310 c231 +2311 c234 +2312 c248 +2313..2314 c250 +2315 c254 +2316 c258 +2317 c260 +2318 c265 +2319..2320 c26c +2321 c270 +2322 c274 +2323..2324 c27c +2325 c27f +2326 c281 +2327..2328 c288 +2329 c290 +2330 c298 +2331 c29b +2332 c29d +2333..2334 c2a4 +2335 c2a8 +2336..2337 c2ac +2338..2339 c2b4 +2340 c2b7 +2341 c2b9 +2342..2343 c2dc +2344 c2e0 +2345..2346 c2e3 +2347..2349 c2eb +2350 c2ef +2351 c2f1 +2352 c2f6 +2353..2354 c2f8 +2355..2356 c2fb +2357 c300 +2358..2359 c308 +2360..2361 c30c +2362..2364 c313 +2365 c318 +2366 c31c +2367..2368 c324 +2369..2370 c328 +2371 c345 +2372..2373 c368 +2374 c36c +2375 c370 +2376 c372 +2377..2378 c378 +2379..2380 c37c +2381 c384 +2382 c388 +2383 c38c +2384 c3c0 +2385..2386 c3d8 +2387 c3dc +2388..2389 c3df +2390 c3e2 +2391..2392 c3e8 +2393 c3ed +2394..2395 c3f4 +2396 c3f8 +2397 c408 +2398 c410 +2399 c424 +2400 c42c +2401 c430 +2402 c434 +2403..2404 c43c +2405 c448 +2406..2407 c464 +2408 c468 +2409 c46c +2410..2411 c474 +2412 c479 +2413 c480 +2414 c494 +2415 c49c +2416 c4b8 +2417 c4bc +2418 c4e9 +2419..2420 c4f0 +2421 c4f4 +2422 c4f8 +2423 c4fa +2424..2426 c4ff +2427 c50c +2428 c510 +2429 c514 +2430 c51c +2431..2432 c528 +2433 c52c +2434 c530 +2435..2436 c538 +2437 c53b +2438 c53d +2439..2440 c544 +2441..2443 c548 +2444..2446 c54c +2447..2449 c553 +2450..2452 c557 +2453..2454 c55d +2455..2456 c560 +2457 c564 +2458 c568 +2459..2460 c570 +2461..2463 c573 +2464..2465 c57c +2466 c580 +2467 c584 +2468 c587 +2469..2470 c58c +2471 c58f +2472 c591 +2473 c595 +2474..2475 c597 +2476 c59c +2477 c5a0 +2478 c5a9 +2479..2480 c5b4 +2481..2482 c5b8 +2483..2486 c5bb +2487..2493 c5c4 +2494 c5cc +2495 c5ce +2496..2497 c5d0 +2498 c5d4 +2499 c5d8 +2500..2501 c5e0 +2502 c5e3 +2503 c5e5 +2504..2506 c5ec +2507 c5f0 +2508 c5f4 +2509..2510 c5f6 +2511..2516 c5fc +2517..2520 c605 +2521 c60c +2522 c610 +2523..2524 c618 +2525..2526 c61b +2527..2528 c624 +2529 c628 +2530..2532 c62c +2533 c630 +2534..2536 c633 +2537 c637 +2538 c639 +2539 c63b +2540..2541 c640 +2542 c644 +2543 c648 +2544..2545 c650 +2546..2548 c653 +2549..2550 c65c +2551 c660 +2552 c66c +2553 c66f +2554 c671 +2555..2556 c678 +2557 c67c +2558 c680 +2559..2560 c688 +2561 c68b +2562 c68d +2563..2564 c694 +2565 c698 +2566 c69c +2567..2568 c6a4 +2569 c6a7 +2570 c6a9 +2571..2572 c6b0 +2573 c6b4 +2574..2576 c6b8 +2577..2578 c6c0 +2579 c6c3 +2580 c6c5 +2581..2582 c6cc +2583 c6d0 +2584 c6d4 +2585..2586 c6dc +2587..2588 c6e0 +2589..2590 c6e8 +2591 c6ec +2592 c6f0 +2593..2594 c6f8 +2595 c6fd +2596..2597 c704 +2598 c708 +2599 c70c +2600..2601 c714 +2602 c717 +2603 c719 +2604..2605 c720 +2606 c724 +2607 c728 +2608..2609 c730 +2610 c733 +2611 c735 +2612 c737 +2613..2614 c73c +2615 c740 +2616 c744 +2617 c74a +2618..2619 c74c +2620 c74f +2621..2628 c751 +2629 c75c +2630 c760 +2631 c768 +2632 c76b +2633..2634 c774 +2635 c778 +2636..2638 c77c +2639..2641 c783 +2642..2645 c787 +2646 c78e +2647..2648 c790 +2649 c794 +2650..2652 c796 +2653 c79a +2654..2655 c7a0 +2656..2659 c7a3 +2660..2661 c7ac +2662 c7b0 +2663 c7b4 +2664..2665 c7bc +2666..2668 c7bf +2669..2670 c7c8 +2671 c7cc +2672 c7ce +2673 c7d0 +2674 c7d8 +2675 c7dd +2676 c7e4 +2677 c7e8 +2678 c7ec +2679..2680 c800 +2681 c804 +2682 c808 +2683 c80a +2684..2685 c810 +2686 c813 +2687..2688 c815 +2689..2690 c81c +2691 c820 +2692 c824 +2693..2694 c82c +2695 c82f +2696 c831 +2697 c838 +2698 c83c +2699 c840 +2700..2701 c848 +2702..2703 c84c +2704 c854 +2705..2706 c870 +2707 c874 +2708 c878 +2709 c87a +2710..2711 c880 +2712 c883 +2713..2715 c885 +2716..2718 c88b +2719 c894 +2720 c89d +2721 c89f +2722 c8a1 +2723 c8a8 +2724..2725 c8bc +2726 c8c4 +2727 c8c8 +2728 c8cc +2729..2730 c8d4 +2731 c8d7 +2732 c8d9 +2733..2734 c8e0 +2735 c8e4 +2736 c8f5 +2737..2738 c8fc +2739 c900 +2740..2742 c904 +2743..2744 c90c +2745 c90f +2746 c911 +2747 c918 +2748 c92c +2749 c934 +2750..2751 c950 +2752 c954 +2753 c958 +2754..2755 c960 +2756 c963 +2757 c96c +2758 c970 +2759 c974 +2760 c97c +2761..2762 c988 +2763 c98c +2764 c990 +2765..2766 c998 +2767 c99b +2768 c99d +2769..2770 c9c0 +2771 c9c4 +2772..2773 c9c7 +2774 c9ca +2775..2776 c9d0 +2777 c9d3 +2778..2779 c9d5 +2780..2781 c9d9 +2782..2783 c9dc +2784 c9e0 +2785 c9e2 +2786 c9e4 +2787 c9e7 +2788..2789 c9ec +2790..2792 c9ef +2793..2794 c9f8 +2795 c9fc +2796 ca00 +2797..2798 ca08 +2799..2801 ca0b +2802 ca14 +2803 ca18 +2804 ca29 +2805..2806 ca4c +2807 ca50 +2808 ca54 +2809..2810 ca5c +2811..2813 ca5f +2814 ca68 +2815 ca7d +2816 ca84 +2817 ca98 +2818..2819 cabc +2820 cac0 +2821 cac4 +2822..2823 cacc +2824 cacf +2825 cad1 +2826 cad3 +2827..2828 cad8 +2829 cae0 +2830 caec +2831 caf4 +2832 cb08 +2833 cb10 +2834 cb14 +2835 cb18 +2836..2837 cb20 +2838 cb41 +2839..2840 cb48 +2841 cb4c +2842 cb50 +2843..2844 cb58 +2845 cb5d +2846 cb64 +2847..2848 cb78 +2849 cb9c +2850 cbb8 +2851 cbd4 +2852 cbe4 +2853 cbe7 +2854 cbe9 +2855..2856 cc0c +2857 cc10 +2858 cc14 +2859..2860 cc1c +2861..2862 cc21 +2863..2865 cc27 +2866 cc2c +2867 cc2e +2868 cc30 +2869..2870 cc38 +2871..2874 cc3b +2875..2876 cc44 +2877 cc48 +2878 cc4c +2879..2880 cc54 +2881..2883 cc57 +2884 cc60 +2885 cc64 +2886 cc66 +2887 cc68 +2888 cc70 +2889 cc75 +2890..2891 cc98 +2892 cc9c +2893 cca0 +2894..2895 cca8 +2896..2898 ccab +2899..2900 ccb4 +2901 ccb8 +2902 ccbc +2903..2904 ccc4 +2905 ccc7 +2906 ccc9 +2907 ccd0 +2908 ccd4 +2909 cce4 +2910 ccec +2911 ccf0 +2912 cd01 +2913..2914 cd08 +2915 cd0c +2916 cd10 +2917..2918 cd18 +2919 cd1b +2920 cd1d +2921 cd24 +2922 cd28 +2923 cd2c +2924 cd39 +2925 cd5c +2926 cd60 +2927 cd64 +2928..2929 cd6c +2930 cd6f +2931 cd71 +2932 cd78 +2933 cd88 +2934..2935 cd94 +2936 cd98 +2937 cd9c +2938..2939 cda4 +2940 cda7 +2941 cda9 +2942 cdb0 +2943 cdc4 +2944 cdcc +2945 cdd0 +2946 cde8 +2947 cdec +2948 cdf0 +2949..2950 cdf8 +2951 cdfb +2952 cdfd +2953 ce04 +2954 ce08 +2955 ce0c +2956 ce14 +2957 ce19 +2958..2959 ce20 +2960 ce24 +2961 ce28 +2962..2963 ce30 +2964 ce33 +2965 ce35 +2966..2967 ce58 +2968 ce5c +2969..2971 ce5f +2972..2973 ce68 +2974 ce6b +2975 ce6d +2976..2977 ce74 +2978 ce78 +2979 ce7c +2980..2981 ce84 +2982 ce87 +2983 ce89 +2984..2985 ce90 +2986 ce94 +2987 ce98 +2988..2989 cea0 +2990..2992 cea3 +2993..2994 ceac +2995 cec1 +2996..2997 cee4 +2998 cee8 +2999..3000 ceeb +3001..3002 cef4 +3003..3005 cef7 +3006..3007 cf00 +3008 cf04 +3009 cf08 +3010..3011 cf10 +3012 cf13 +3013 cf15 +3014 cf1c +3015 cf20 +3016 cf24 +3017..3018 cf2c +3019..3021 cf2f +3022 cf38 +3023..3024 cf54 +3025 cf58 +3026 cf5c +3027..3028 cf64 +3029 cf67 +3030 cf69 +3031..3032 cf70 +3033 cf74 +3034 cf78 +3035 cf80 +3036 cf85 +3037 cf8c +3038 cfa1 +3039 cfa8 +3040 cfb0 +3041 cfc4 +3042..3043 cfe0 +3044 cfe4 +3045 cfe8 +3046..3047 cff0 +3048 cff3 +3049 cff5 +3050 cffc +3051 d000 +3052 d004 +3053 d011 +3054 d018 +3055 d02d +3056..3057 d034 +3058 d038 +3059 d03c +3060..3061 d044 +3062 d047 +3063 d049 +3064 d050 +3065 d054 +3066 d058 +3067 d060 +3068..3069 d06c +3070 d070 +3071 d074 +3072..3073 d07c +3074 d081 +3075..3076 d0a4 +3077 d0a8 +3078 d0ac +3079..3080 d0b4 +3081 d0b7 +3082 d0b9 +3083..3084 d0c0 +3085 d0c4 +3086..3087 d0c8 +3088..3089 d0d0 +3090..3092 d0d3 +3093..3094 d0dc +3095 d0e0 +3096 d0e4 +3097..3098 d0ec +3099..3101 d0ef +3102 d0f8 +3103 d10d +3104..3105 d130 +3106 d134 +3107 d138 +3108 d13a +3109..3110 d140 +3111..3113 d143 +3114..3115 d14c +3116 d150 +3117 d154 +3118..3119 d15c +3120 d15f +3121 d161 +3122 d168 +3123 d16c +3124 d17c +3125 d184 +3126 d188 +3127..3128 d1a0 +3129 d1a4 +3130 d1a8 +3131..3132 d1b0 +3133 d1b3 +3134 d1b5 +3135 d1ba +3136 d1bc +3137 d1c0 +3138 d1d8 +3139 d1f4 +3140 d1f8 +3141 d207 +3142 d209 +3143 d210 +3144..3145 d22c +3146 d230 +3147 d234 +3148..3149 d23c +3150 d23f +3151 d241 +3152 d248 +3153 d25c +3154 d264 +3155..3156 d280 +3157 d284 +3158 d288 +3159..3160 d290 +3161 d295 +3162 d29c +3163 d2a0 +3164 d2a4 +3165 d2ac +3166 d2b1 +3167..3168 d2b8 +3169 d2bc +3170..3171 d2bf +3172 d2c2 +3173..3174 d2c8 +3175 d2cb +3176 d2d4 +3177 d2d8 +3178 d2dc +3179..3180 d2e4 +3181..3182 d2f0 +3183 d2f4 +3184 d2f8 +3185..3186 d300 +3187 d303 +3188 d305 +3189..3191 d30c +3192 d310 +3193 d314 +3194 d316 +3195..3196 d31c +3197..3199 d31f +3200 d325 +3201..3202 d328 +3203 d32c +3204 d330 +3205..3206 d338 +3207..3209 d33b +3210..3211 d344 +3212..3213 d37c +3214 d380 +3215 d384 +3216..3217 d38c +3218..3220 d38f +3221..3222 d398 +3223 d39c +3224 d3a0 +3225..3226 d3a8 +3227 d3ab +3228 d3ad +3229 d3b4 +3230 d3b8 +3231 d3bc +3232..3233 d3c4 +3234..3235 d3c8 +3236 d3d0 +3237 d3d8 +3238 d3e1 +3239 d3e3 +3240..3241 d3ec +3242 d3f0 +3243 d3f4 +3244..3245 d3fc +3246 d3ff +3247 d401 +3248 d408 +3249 d41d +3250 d440 +3251 d444 +3252 d45c +3253 d460 +3254 d464 +3255 d46d +3256 d46f +3257..3258 d478 +3259 d47c +3260..3261 d47f +3262 d482 +3263..3264 d488 +3265 d48b +3266 d48d +3267 d494 +3268 d4a9 +3269 d4cc +3270 d4d0 +3271 d4d4 +3272 d4dc +3273 d4df +3274 d4e8 +3275 d4ec +3276 d4f0 +3277 d4f8 +3278 d4fb +3279 d4fd +3280 d504 +3281 d508 +3282 d50c +3283..3284 d514 +3285 d517 +3286..3287 d53c +3288 d540 +3289 d544 +3290..3291 d54c +3292 d54f +3293 d551 +3294..3295 d558 +3296 d55c +3297 d560 +3298 d565 +3299..3300 d568 +3301 d56b +3302 d56d +3303..3304 d574 +3305 d578 +3306 d57c +3307..3308 d584 +3309..3311 d587 +3312 d590 +3313 d5a5 +3314..3315 d5c8 +3316 d5cc +3317 d5d0 +3318 d5d2 +3319..3320 d5d8 +3321 d5db +3322 d5dd +3323..3324 d5e4 +3325 d5e8 +3326 d5ec +3327..3328 d5f4 +3329 d5f7 +3330 d5f9 +3331..3332 d600 +3333 d604 +3334 d608 +3335..3336 d610 +3337..3339 d613 +3340 d61c +3341 d620 +3342 d624 +3343 d62d +3344..3345 d638 +3346 d63c +3347 d640 +3348 d645 +3349..3350 d648 +3351 d64b +3352 d64d +3353 d651 +3354..3355 d654 +3356 d658 +3357 d65c +3358 d667 +3359 d669 +3360..3361 d670 +3362 d674 +3363 d683 +3364 d685 +3365..3366 d68c +3367 d690 +3368 d694 +3369 d69d +3370 d69f +3371 d6a1 +3372 d6a8 +3373 d6ac +3374 d6b0 +3375 d6b9 +3376 d6bb +3377..3378 d6c4 +3379 d6c8 +3380 d6cc +3381 d6d1 +3382 d6d4 +3383 d6d7 +3384 d6d9 +3385 d6e0 +3386 d6e4 +3387 d6e8 +3388 d6f0 +3389 d6f5 +3390..3391 d6fc +3392 d700 +3393 d704 +3394 d711 +3395..3396 d718 +3397 d71c +3398 d720 +3399..3400 d728 +3401 d72b +3402 d72d +3403..3404 d734 +3405 d738 +3406 d73c +3407 d744 +3408 d747 +3409 d749 +3410..3411 d750 +3412 d754 +3413..3416 d756 +3417..3418 d760 +3419 d763 +3420 d765 +3421 d769 +3422 d76c +3423 d770 +3424 d774 +3425..3426 d77c +3427 d781 +3428..3429 d788 +3430 d78c +3431 d790 +3432..3433 d798 +3434 d79b +3435 d79d +3436 4f3d +3437 4f73 +3438 5047 +3439 50f9 +3440 52a0 +3441 53ef +3442 5475 +3443 54e5 +3444 5609 +3445 5ac1 +3446 5bb6 +3447 6687 +3448..3449 67b6 +3450 67ef +3451 6b4c +3452 73c2 +3453 75c2 +3454 7a3c +3455 82db +3456 8304 +3457 8857 +3458 8888 +3459 8a36 +3460 8cc8 +3461 8dcf +3462 8efb +3463 8fe6 +3464 99d5 +3465 523b +3466 5374 +3467 5404 +3468 606a +3469 6164 +3470 6bbc +3471 73cf +3472 811a +3473 89ba +3474 89d2 +3475 95a3 +3476 4f83 +3477 520a +3478 58be +3479 5978 +3480 59e6 +3481 5e72 +3482 5e79 +3483 61c7 +3484 63c0 +3485 6746 +3486 67ec +3487 687f +3488 6f97 +3489 764e +3490 770b +3491 78f5 +3492 7a08 +3493 7aff +3494 7c21 +3495 809d +3496 826e +3497 8271 +3498 8aeb +3499 9593 +3500 4e6b +3501 559d +3502 66f7 +3503 6e34 +3504 78a3 +3505 7aed +3506 845b +3507 8910 +3508 874e +3509 97a8 +3510 52d8 +3511 574e +3512 582a +3513 5d4c +3514 611f +3515 61be +3516 6221 +3517 6562 +3518 67d1 +3519 6a44 +3520 6e1b +3521 7518 +3522 75b3 +3523 76e3 +3524 77b0 +3525 7d3a +3526 90af +3527..3528 9451 +3529 9f95 +3530 5323 +3531 5cac +3532 7532 +3533 80db +3534 9240 +3535 9598 +3536 525b +3537 5808 +3538 59dc +3539 5ca1 +3540 5d17 +3541 5eb7 +3542 5f3a +3543 5f4a +3544 6177 +3545 6c5f +3546 757a +3547 7586 +3548 7ce0 +3549 7d73 +3550 7db1 +3551 7f8c +3552 8154 +3553 8221 +3554 8591 +3555 8941 +3556 8b1b +3557 92fc +3558 964d +3559 9c47 +3560 4ecb +3561 4ef7 +3562 500b +3563 51f1 +3564 584f +3565 6137 +3566 613e +3567 6168 +3568 6539 +3569 69ea +3570 6f11 +3571 75a5 +3572 7686 +3573 76d6 +3574 7b87 +3575 82a5 +3576 84cb +3577 93a7 +3578 958b +3579 5580 +3580 5ba2 +3581 5751 +3582 7cb3 +3583 7fb9 +3584 91b5 +3585 5028 +3586 53bb +3587 5c45 +3588 5de8 +3589 62d2 +3590 636e +3591 64da +3592 64e7 +3593 6e20 +3594 70ac +3595 795b +3596 8ddd +3597 8e1e +3598 907d +3599 9245 +3600 92f8 +3601 4e7e +3602 4ef6 +3603 5065 +3604 5dfe +3605 5efa +3606 6106 +3607 6957 +3608 8171 +3609 8654 +3610 8e47 +3611 9375 +3612 9a2b +3613 4e5e +3614 5091 +3615 6770 +3616 6840 +3617 5109 +3618 528d +3619 5292 +3620 6aa2 +3621 77bc +3622 9210 +3623 9ed4 +3624 52ab +3625 602f +3626 8ff2 +3627 5048 +3628 61a9 +3629 63ed +3630 64ca +3631 683c +3632 6a84 +3633 6fc0 +3634 8188 +3635 89a1 +3636 9694 +3637 5805 +3638 727d +3639 72ac +3640 7504 +3641 7d79 +3642 7e6d +3643 80a9 +3644 898b +3645 8b74 +3646 9063 +3647 9d51 +3648 6289 +3649 6c7a +3650 6f54 +3651 7d50 +3652 7f3a +3653 8a23 +3654 517c +3655 614a +3656 7b9d +3657 8b19 +3658 9257 +3659 938c +3660 4eac +3661 4fd3 +3662 501e +3663 50be +3664 5106 +3665 52c1 +3666 52cd +3667 537f +3668 5770 +3669 5883 +3670 5e9a +3671 5f91 +3672 6176 +3673 61ac +3674 64ce +3675 656c +3676 666f +3677 66bb +3678 66f4 +3679 6897 +3680 6d87 +3681 7085 +3682 70f1 +3683 749f +3684 74a5 +3685 74ca +3686 75d9 +3687 786c +3688 78ec +3689 7adf +3690 7af6 +3691 7d45 +3692 7d93 +3693 8015 +3694 803f +3695 811b +3696 8396 +3697 8b66 +3698 8f15 +3699 9015 +3700 93e1 +3701 9803 +3702 9838 +3703 9a5a +3704 9be8 +3705 4fc2 +3706 5553 +3707 583a +3708 5951 +3709 5b63 +3710 5c46 +3711 60b8 +3712 6212 +3713 6842 +3714 68b0 +3715 68e8 +3716 6eaa +3717 754c +3718 7678 +3719 78ce +3720 7a3d +3721 7cfb +3722 7e6b +3723 7e7c +3724 8a08 +3725 8aa1 +3726 8c3f +3727 968e +3728 9dc4 +3729 53e4 +3730 53e9 +3731 544a +3732 5471 +3733 56fa +3734 59d1 +3735 5b64 +3736 5c3b +3737 5eab +3738 62f7 +3739 6537 +3740 6545 +3741 6572 +3742 66a0 +3743 67af +3744 69c1 +3745 6cbd +3746 75fc +3747 7690 +3748 777e +3749 7a3f +3750 7f94 +3751 8003 +3752 80a1 +3753 818f +3754 82e6 +3755 82fd +3756 83f0 +3757 85c1 +3758 8831 +3759 88b4 +3760 8aa5 +3761 8f9c +3762 932e +3763 96c7 +3764 9867 +3765 9ad8 +3766 9f13 +3767 54ed +3768 659b +3769 66f2 +3770 688f +3771 7a40 +3772 8c37 +3773 9d60 +3774 56f0 +3775 5764 +3776 5d11 +3777 6606 +3778 68b1 +3779 68cd +3780 6efe +3781 7428 +3782 889e +3783 9be4 +3784 6c68 +3785 9aa8 +3786 4f9b +3787 516c +3788 5171 +3789 529f +3790 5b54 +3791 5de5 +3792 6050 +3793 606d +3794 62f1 +3795 63a7 +3796 653b +3797 73d9 +3798 7a7a +3799 86a3 +3800 8ca2 +3801 978f +3802 4e32 +3803 5be1 +3804 6208 +3805 679c +3806 74dc +3807 79d1 +3808 83d3 +3809 8a87 +3810 8ab2 +3811 8de8 +3812 904e +3813 934b +3814 9846 +3815 5ed3 +3816 69e8 +3817 85ff +3818 90ed +3819 51a0 +3820 5b98 +3821 5bec +3822 6163 +3823 68fa +3824 6b3e +3825 704c +3826 742f +3827 74d8 +3828 7ba1 +3829 7f50 +3830 83c5 +3831 89c0 +3832 8cab +3833 95dc +3834 9928 +3835 522e +3836 605d +3837 62ec +3838 9002 +3839 4f8a +3840 5149 +3841 5321 +3842 58d9 +3843 5ee3 +3844 66e0 +3845 6d38 +3846 709a +3847 72c2 +3848 73d6 +3849 7b50 +3850 80f1 +3851 945b +3852 5366 +3853 639b +3854 7f6b +3855 4e56 +3856 5080 +3857 584a +3858 58de +3859 602a +3860 6127 +3861 62d0 +3862 69d0 +3863 9b41 +3864 5b8f +3865 7d18 +3866 80b1 +3867 8f5f +3868 4ea4 +3869 50d1 +3870 54ac +3871 55ac +3872 5b0c +3873 5da0 +3874 5de7 +3875 652a +3876 654e +3877 6821 +3878 6a4b +3879 72e1 +3880 768e +3881 77ef +3882 7d5e +3883 7ff9 +3884 81a0 +3885 854e +3886 86df +3887 8f03 +3888 8f4e +3889 90ca +3890 9903 +3891 9a55 +3892 9bab +3893 4e18 +3894 4e45 +3895 4e5d +3896 4ec7 +3897 4ff1 +3898 5177 +3899 52fe +3900 5340 +3901 53e3 +3902 53e5 +3903 548e +3904 5614 +3905 5775 +3906 57a2 +3907 5bc7 +3908 5d87 +3909 5ed0 +3910 61fc +3911 62d8 +3912 6551 +3913 67b8 +3914 67e9 +3915 69cb +3916 6b50 +3917 6bc6 +3918 6bec +3919 6c42 +3920 6e9d +3921 7078 +3922 72d7 +3923 7396 +3924 7403 +3925 77bf +3926 77e9 +3927 7a76 +3928 7d7f +3929 8009 +3930 81fc +3931 8205 +3932 820a +3933 82df +3934 8862 +3935 8b33 +3936 8cfc +3937 8ec0 +3938 9011 +3939 90b1 +3940 9264 +3941 92b6 +3942 99d2 +3943 9a45 +3944 9ce9 +3945 9dd7 +3946 9f9c +3947 570b +3948 5c40 +3949 83ca +3950 97a0 +3951 97ab +3952 9eb4 +3953 541b +3954 7a98 +3955 7fa4 +3956 88d9 +3957 8ecd +3958 90e1 +3959 5800 +3960 5c48 +3961 6398 +3962 7a9f +3963 5bae +3964 5f13 +3965 7a79 +3966 7aae +3967 828e +3968 8eac +3969 5026 +3970 5238 +3971 52f8 +3972 5377 +3973 5708 +3974 62f3 +3975 6372 +3976 6b0a +3977 6dc3 +3978 7737 +3979 53a5 +3980 7357 +3981 8568 +3982 8e76 +3983 95d5 +3984 673a +3985 6ac3 +3986 6f70 +3987 8a6d +3988 8ecc +3989 994b +3990 6677 +3991 6b78 +3992 8cb4 +3993 9b3c +3994 53eb +3995 572d +3996 594e +3997 63c6 +3998 69fb +3999 73ea +4000 7845 +4001 7aba +4002 7ac5 +4003 7cfe +4004 8475 +4005 898f +4006 8d73 +4007 9035 +4008 95a8 +4009 52fb +4010 5747 +4011 7547 +4012 7b60 +4013 83cc +4014 921e +4015 6a58 +4016 514b +4017 524b +4018 5287 +4019 621f +4020 68d8 +4021 6975 +4022 9699 +4023 50c5 +4024 52a4 +4025 52e4 +4026 61c3 +4027 65a4 +4028 6839 +4029 69ff +4030 747e +4031 7b4b +4032 82b9 +4033 83eb +4034 89b2 +4035 8b39 +4036 8fd1 +4037 9949 +4038 4eca +4039 5997 +4040 64d2 +4041 6611 +4042 6a8e +4043 7434 +4044 7981 +4045 79bd +4046 82a9 +4047..4048 887e +4049 895f +4050 9326 +4051 4f0b +4052 53ca +4053 6025 +4054 6271 +4055 6c72 +4056 7d1a +4057 7d66 +4058 4e98 +4059 5162 +4060 77dc +4061 80af +4062 4f01 +4063 4f0e +4064 5176 +4065 5180 +4066 55dc +4067 5668 +4068 573b +4069 57fa +4070 57fc +4071 5914 +4072 5947 +4073 5993 +4074 5bc4 +4075 5c90 +4076 5d0e +4077 5df1 +4078 5e7e +4079 5fcc +4080 6280 +4081 65d7 +4082 65e3 +4083..4084 671e +4085 675e +4086 68cb +4087 68c4 +4088 6a5f +4089 6b3a +4090 6c23 +4091 6c7d +4092 6c82 +4093 6dc7 +4094 7398 +4095 7426 +4096 742a +4097 7482 +4098 74a3 +4099 7578 +4100 757f +4101 7881 +4102 78ef +4103 7941 +4104..4105 7947 +4106 797a +4107 7b95 +4108 7d00 +4109 7dba +4110 7f88 +4111 8006 +4112 802d +4113 808c +4114 8a18 +4115 8b4f +4116 8c48 +4117 8d77 +4118 9321 +4119 9324 +4120 98e2 +4121 9951 +4122..4123 9a0e +4124 9a65 +4125 9e92 +4126 7dca +4127 4f76 +4128 5409 +4129 62ee +4130 6854 +4131 91d1 +4132 55ab +4133 513a +4134 5a1c +4135 61e6 +4136 62cf +4137 62ff +4138 90a3 +4139 8afe +4140 6696 +4141 7156 +4142 96e3 +4143 634f +4144 637a +4145 5357 +4146 678f +4147 6960 +4148 6e73 +4149 7537 +4150 7d0d +4151 8872 +4152 56ca +4153 5a18 +4154 4e43 +4155 5167 +4156 5948 +4157 67f0 +4158 8010 +4159 5973 +4160 5e74 +4161 649a +4162 79ca +4163 5ff5 +4164 606c +4165 62c8 +4166 637b +4167 5be7 +4168 5bd7 +4169 52aa +4170 5974 +4171 5f29 +4172 6012 +4173 7459 +4174 99d1 +4175 6fc3 +4176 81bf +4177 8fb2 +4178 60f1 +4179 8166 +4180 5c3f +4181 5ae9 +4182 8a25 +4183 677b +4184 7d10 +4185 80fd +4186 5c3c +4187 6ce5 +4188 533f +4189 6eba +4190 591a +4191 8336 +4192 4e39 +4193 4eb6 +4194 4f46 +4195 55ae +4196 5718 +4197 58c7 +4198 5f56 +4199 65b7 +4200 65e6 +4201 6a80 +4202 6bb5 +4203 6e4d +4204 77ed +4205 7aef +4206 7c1e +4207 7dde +4208 86cb +4209 8892 +4210 9132 +4211 935b +4212 64bb +4213 6fbe +4214 737a +4215 75b8 +4216 9054 +4217 5556 +4218 574d +4219 61ba +4220 64d4 +4221 66c7 +4222 6de1 +4223 6e5b +4224 6f6d +4225 6fb9 +4226 75f0 +4227 8043 +4228 81bd +4229 8541 +4230 8983 +4231 8ac7 +4232 8b5a +4233 931f +4234 6c93 +4235 7553 +4236 7b54 +4237 8e0f +4238 905d +4239 5510 +4240 5802 +4241 5858 +4242 5e62 +4243 6207 +4244 649e +4245 68e0 +4246 7576 +4247 7cd6 +4248 87b3 +4249 9ee8 +4250 4ee3 +4251 5788 +4252 576e +4253 5927 +4254 5c0d +4255 5cb1 +4256 5e36 +4257 5f85 +4258 6234 +4259 64e1 +4260 73b3 +4261 81fa +4262 888b +4263 8cb8 +4264 968a +4265 9edb +4266 5b85 +4267 5fb7 +4268 60b3 +4269 5012 +4270 5200 +4271 5230 +4272 5716 +4273 5835 +4274 5857 +4275 5c0e +4276 5c60 +4277 5cf6 +4278 5d8b +4279 5ea6 +4280 5f92 +4281 60bc +4282 6311 +4283 6389 +4284 6417 +4285 6843 +4286 68f9 +4287 6ac2 +4288 6dd8 +4289 6e21 +4290 6ed4 +4291 6fe4 +4292 71fe +4293 76dc +4294 7779 +4295 79b1 +4296 7a3b +4297 8404 +4298 89a9 +4299 8ced +4300 8df3 +4301 8e48 +4302 9003 +4303 9014 +4304 9053 +4305 90fd +4306 934d +4307 9676 +4308 97dc +4309 6bd2 +4310 7006 +4311 7258 +4312 72a2 +4313 7368 +4314 7763 +4315 79bf +4316 7be4 +4317 7e9b +4318 8b80 +4319 58a9 +4320 60c7 +4321 6566 +4322 65fd +4323 66be +4324 6c8c +4325 711e +4326 71c9 +4327 8c5a +4328 9813 +4329 4e6d +4330 7a81 +4331 4edd +4332 51ac +4333 51cd +4334 52d5 +4335 540c +4336 61a7 +4337 6771 +4338 6850 +4339 68df +4340 6d1e +4341 6f7c +4342 75bc +4343 77b3 +4344 7ae5 +4345 80f4 +4346 8463 +4347 9285 +4348 515c +4349 6597 +4350 675c +4351 6793 +4352 75d8 +4353 7ac7 +4354 8373 +4355 8c46 +4356 9017 +4357 982d +4358 5c6f +4359 81c0 +4360 829a +4361 9041 +4362 906f +4363 920d +4364 5f97 +4365 5d9d +4366 6a59 +4367 71c8 +4368 767b +4369 7b49 +4370 85e4 +4371 8b04 +4372 9127 +4373 9a30 +4374 5587 +4375 61f6 +4376 7669 +4377 7f85 +4378 863f +4379 87ba +4380 88f8 +4381 908f +4382 6d1b +4383 70d9 +4384 73de +4385 7d61 +4386 843d +4387 916a +4388 99f1 +4389 4e82 +4390 5375 +4391 6b04 +4392 6b12 +4393 703e +4394 721b +4395 862d +4396 9e1e +4397 524c +4398 8fa3 +4399 5d50 +4400 64e5 +4401 652c +4402 6b16 +4403 6feb +4404 7c43 +4405 7e9c +4406 85cd +4407 8964 +4408 89bd +4409 62c9 +4410 81d8 +4411 881f +4412 5eca +4413 6717 +4414 6d6a +4415 72fc +4416 7405 +4417 746f +4418 8782 +4419 90de +4420 4f86 +4421 5d0d +4422 5fa0 +4423 840a +4424 51b7 +4425 63a0 +4426 7565 +4427 4eae +4428 5006 +4429 5169 +4430 51c9 +4431 6881 +4432 6a11 +4433 7cae +4434 7cb1 +4435 7ce7 +4436 826f +4437 8ad2 +4438 8f1b +4439 91cf +4440 4fb6 +4441 5137 +4442 52f5 +4443 5442 +4444 5eec +4445 616e +4446 623e +4447 65c5 +4448 6ada +4449 6ffe +4450 792a +4451 85dc +4452 8823 +4453 95ad +4454 9a62 +4455 9a6a +4456 9e97 +4457 9ece +4458 529b +4459 66c6 +4460 6b77 +4461 701d +4462 792b +4463 8f62 +4464 9742 +4465 6190 +4466 6200 +4467 6523 +4468 6f23 +4469 7149 +4470 7489 +4471 7df4 +4472 806f +4473 84ee +4474 8f26 +4475 9023 +4476 934a +4477 51bd +4478 5217 +4479 52a3 +4480 6d0c +4481 70c8 +4482 88c2 +4483 5ec9 +4484 6582 +4485 6bae +4486 6fc2 +4487 7c3e +4488 7375 +4489 4ee4 +4490 4f36 +4491 56f9 +4492 5cba +4493 5dba +4494 601c +4495 73b2 +4496 7b2d +4497 7f9a +4498 7fce +4499 8046 +4500 901e +4501 9234 +4502 96f6 +4503 9748 +4504 9818 +4505 9f61 +4506 4f8b +4507 6fa7 +4508 79ae +4509 91b4 +4510 96b7 +4511 52de +4512 6488 +4513 64c4 +4514 6ad3 +4515 6f5e +4516 7018 +4517 7210 +4518 76e7 +4519 8001 +4520 8606 +4521 865c +4522 8def +4523 8f05 +4524 9732 +4525 9b6f +4526 9dfa +4527 9e75 +4528 788c +4529 797f +4530 7da0 +4531 83c9 +4532 9304 +4533 9e7f +4534 9e93 +4535 8ad6 +4536 58df +4537 5f04 +4538 6727 +4539 7027 +4540 74cf +4541 7c60 +4542 807e +4543 5121 +4544 7028 +4545 7262 +4546 78ca +4547 8cc2 +4548 8cda +4549 8cf4 +4550 96f7 +4551 4e86 +4552 50da +4553 5bee +4554 5ed6 +4555 6599 +4556 71ce +4557 7642 +4558 77ad +4559 804a +4560 84fc +4561 907c +4562 9b27 +4563 9f8d +4564 58d8 +4565 5a41 +4566 5c62 +4567 6a13 +4568 6dda +4569 6f0f +4570 763b +4571 7d2f +4572 7e37 +4573 851e +4574 8938 +4575 93e4 +4576 964b +4577 5289 +4578 65d2 +4579 67f3 +4580 69b4 +4581 6d41 +4582 6e9c +4583 700f +4584 7409 +4585 7460 +4586 7559 +4587 7624 +4588 786b +4589 8b2c +4590 985e +4591 516d +4592 622e +4593 9678 +4594 4f96 +4595 502b +4596 5d19 +4597 6dea +4598 7db8 +4599 8f2a +4600 5f8b +4601 6144 +4602 6817 +4603 9686 +4604 52d2 +4605 808b +4606 51dc +4607 51cc +4608 695e +4609 7a1c +4610 7dbe +4611 83f1 +4612 9675 +4613 4fda +4614 5229 +4615 5398 +4616 540f +4617 550e +4618 5c65 +4619 60a7 +4620 674e +4621 68a8 +4622 6d6c +4623 7281 +4624 72f8 +4625 7406 +4626 7483 +4627 75e2 +4628 7c6c +4629 7f79 +4630 7fb8 +4631 8389 +4632 88cf +4633 88e1 +4634 91cc +4635 91d0 +4636 96e2 +4637 9bc9 +4638 541d +4639 6f7e +4640 71d0 +4641 7498 +4642 85fa +4643 8eaa +4644 96a3 +4645 9c57 +4646 9e9f +4647 6797 +4648 6dcb +4649 7433 +4650 81e8 +4651 9716 +4652 782c +4653 7acb +4654 7b20 +4655 7c92 +4656 6469 +4657 746a +4658 75f2 +4659 78bc +4660 78e8 +4661 99ac +4662 9b54 +4663 9ebb +4664 5bde +4665 5e55 +4666 6f20 +4667 819c +4668 83ab +4669 9088 +4670 4e07 +4671 534d +4672 5a29 +4673 5dd2 +4674 5f4e +4675 6162 +4676 633d +4677 6669 +4678 66fc +4679 6eff +4680 6f2b +4681 7063 +4682 779e +4683 842c +4684 8513 +4685 883b +4686 8f13 +4687 9945 +4688 9c3b +4689 551c +4690 62b9 +4691 672b +4692 6cab +4693 8309 +4694 896a +4695 977a +4696 4ea1 +4697 5984 +4698..4699 5fd8 +4700 671b +4701 7db2 +4702 7f54 +4703 8292 +4704 832b +4705 83bd +4706 8f1e +4707 9099 +4708 57cb +4709 59b9 +4710 5a92 +4711 5bd0 +4712 6627 +4713 679a +4714 6885 +4715 6bcf +4716 7164 +4717 7f75 +4718 8cb7 +4719 8ce3 +4720 9081 +4721 9b45 +4722 8108 +4723 8c8a +4724 964c +4725 9a40 +4726 9ea5 +4727 5b5f +4728 6c13 +4729 731b +4730 76f2 +4731 76df +4732 840c +4733 51aa +4734 8993 +4735 514d +4736 5195 +4737 52c9 +4738 68c9 +4739 6c94 +4740 7704 +4741 7720 +4742 7dbf +4743 7dec +4744 9762 +4745 9eb5 +4746 6ec5 +4747 8511 +4748 51a5 +4749 540d +4750 547d +4751 660e +4752 669d +4753 6927 +4754 6e9f +4755 76bf +4756 7791 +4757 8317 +4758 84c2 +4759 879f +4760 9169 +4761 9298 +4762 9cf4 +4763 8882 +4764 4fae +4765 5192 +4766 52df +4767 59c6 +4768 5e3d +4769 6155 +4770..4771 6478 +4772 66ae +4773 67d0 +4774 6a21 +4775 6bcd +4776 6bdb +4777 725f +4778 7261 +4779 7441 +4780 7738 +4781 77db +4782 8017 +4783 82bc +4784 8305 +4785 8b00 +4786 8b28 +4787 8c8c +4788 6728 +4789 6c90 +4790 7267 +4791 76ee +4792 7766 +4793 7a46 +4794 9da9 +4795 6b7f +4796 6c92 +4797 5922 +4798 6726 +4799 8499 +4800 536f +4801 5893 +4802 5999 +4803 5edf +4804 63cf +4805 6634 +4806 6773 +4807 6e3a +4808 732b +4809 7ad7 +4810 82d7 +4811 9328 +4812 52d9 +4813 5deb +4814 61ae +4815 61cb +4816 620a +4817 62c7 +4818 64ab +4819 65e0 +4820 6959 +4821 6b66 +4822 6bcb +4823 7121 +4824 73f7 +4825 755d +4826 7e46 +4827 821e +4828 8302 +4829 856a +4830 8aa3 +4831 8cbf +4832 9727 +4833 9d61 +4834 58a8 +4835 9ed8 +4836 5011 +4837 520e +4838 543b +4839 554f +4840 6587 +4841 6c76 +4842..4843 7d0a +4844 805e +4845 868a +4846 9580 +4847 96ef +4848 52ff +4849 6c95 +4850 7269 +4851 5473 +4852 5a9a +4853 5c3e +4854 5d4b +4855 5f4c +4856 5fae +4857 672a +4858 68b6 +4859 6963 +4860 6e3c +4861 6e44 +4862 7709 +4863 7c73 +4864 7f8e +4865 8587 +4866 8b0e +4867 8ff7 +4868 9761 +4869 9ef4 +4870 5cb7 +4871 60b6 +4872 610d +4873 61ab +4874 654f +4875..4876 65fb +4877 6c11 +4878 6cef +4879 739f +4880 73c9 +4881 7de1 +4882 9594 +4883 5bc6 +4884 871c +4885 8b10 +4886 525d +4887 535a +4888 62cd +4889 640f +4890 64b2 +4891 6734 +4892 6a38 +4893 6cca +4894 73c0 +4895 749e +4896 7b94 +4897 7c95 +4898 7e1b +4899 818a +4900 8236 +4901 8584 +4902 8feb +4903 96f9 +4904 99c1 +4905 4f34 +4906 534a +4907 53cd +4908 53db +4909 62cc +4910 642c +4911 6500 +4912 6591 +4913 69c3 +4914 6cee +4915 6f58 +4916 73ed +4917 7554 +4918 7622 +4919 76e4 +4920 76fc +4921 78d0 +4922 78fb +4923 792c +4924 7d46 +4925 822c +4926 87e0 +4927 8fd4 +4928 9812 +4929 98ef +4930 52c3 +4931 62d4 +4932 64a5 +4933 6e24 +4934 6f51 +4935 767c +4936 8dcb +4937 91b1 +4938 9262 +4939 9aee +4940 9b43 +4941 5023 +4942 508d +4943 574a +4944 59a8 +4945 5c28 +4946 5e47 +4947 5f77 +4948 623f +4949 653e +4950 65b9 +4951 65c1 +4952 6609 +4953 678b +4954 699c +4955 6ec2 +4956 78c5 +4957 7d21 +4958 80aa +4959 8180 +4960 822b +4961 82b3 +4962 84a1 +4963 868c +4964 8a2a +4965 8b17 +4966 90a6 +4967 9632 +4968 9f90 +4969 500d +4970 4ff3 +4971 57f9 +4972 5f98 +4973 62dc +4974 6392 +4975 676f +4976 6e43 +4977 7119 +4978 76c3 +4979 80cc +4980 80da +4981..4982 88f4 +4983 8919 +4984 8ce0 +4985 8f29 +4986 914d +4987 966a +4988 4f2f +4989 4f70 +4990 5e1b +4991 67cf +4992 6822 +4993..4994 767d +4995 9b44 +4996 5e61 +4997 6a0a +4998 7169 +4999 71d4 +5000 756a +5001 7e41 +5002 8543 +5003 85e9 +5004 98dc +5005 4f10 +5006 7b4f +5007 7f70 +5008 95a5 +5009 51e1 +5010 5e06 +5011 68b5 +5012 6c3e +5013 6c4e +5014 6cdb +5015 72af +5016 7bc4 +5017 8303 +5018 6cd5 +5019 743a +5020 50fb +5021 5288 +5022 58c1 +5023 64d8 +5024 6a97 +5025 74a7 +5026 7656 +5027 78a7 +5028 8617 +5029 95e2 +5030 9739 +5031 535e +5032 5f01 +5033 8b8a +5034 8fa8 +5035 8faf +5036 908a +5037 5225 +5038 77a5 +5039 9c49 +5040 9f08 +5041 4e19 +5042 5002 +5043 5175 +5044 5c5b +5045 5e77 +5046 661e +5047 663a +5048 67c4 +5049 68c5 +5050 70b3 +5051 7501 +5052 75c5 +5053 79c9 +5054 7add +5055 8f27 +5056 9920 +5057 9a08 +5058 4fdd +5059 5821 +5060 5831 +5061 5bf6 +5062 666e +5063 6b65 +5064 6d11 +5065 6e7a +5066 6f7d +5067 73e4 +5068 752b +5069 83e9 +5070 88dc +5071 8913 +5072 8b5c +5073 8f14 +5074 4f0f +5075 50d5 +5076 5310 +5077 535c +5078 5b93 +5079 5fa9 +5080 670d +5081 798f +5082 8179 +5083 832f +5084 8514 +5085 8907 +5086 8986 +5087 8f39 +5088 8f3b +5089 99a5 +5090 9c12 +5091 672c +5092 4e76 +5093 4ff8 +5094 5949 +5095 5c01 +5096..5097 5cef +5098 6367 +5099 68d2 +5100 70fd +5101 71a2 +5102 742b +5103 7e2b +5104 84ec +5105 8702 +5106 9022 +5107 92d2 +5108 9cf3 +5109 4e0d +5110 4ed8 +5111 4fef +5112 5085 +5113 5256 +5114 526f +5115 5426 +5116 5490 +5117 57e0 +5118 592b +5119 5a66 +5120 5b5a +5121 5b75 +5122 5bcc +5123 5e9c +5124 6276 +5125 6577 +5126 65a7 +5127 6d6e +5128 6ea5 +5129 7236 +5130 7b26 +5131 7c3f +5132 7f36 +5133..5134 8150 +5135 819a +5136 8240 +5137 8299 +5138 83a9 +5139 8a03 +5140 8ca0 +5141 8ce6 +5142 8cfb +5143 8d74 +5144 8dba +5145 90e8 +5146 91dc +5147 961c +5148 9644 +5149 99d9 +5150 9ce7 +5151 5317 +5152 5206 +5153 5429 +5154 5674 +5155 58b3 +5156 5954 +5157 596e +5158 5fff +5159 61a4 +5160 626e +5161 6610 +5162 6c7e +5163 711a +5164 76c6 +5165 7c89 +5166 7cde +5167 7d1b +5168 82ac +5169 8cc1 +5170 96f0 +5171 4f5b +5172 5f17 +5173 5f7f +5174 62c2 +5175 5d29 +5176 670b +5177 68da +5178 787c +5179 7e43 +5180 9d6c +5181 4e15 +5182 5099 +5183 5315 +5184 532a +5185 5351 +5186 5983 +5187 5a62 +5188 5e87 +5189 60b2 +5190 618a +5191 6249 +5192 6279 +5193 6590 +5194 6787 +5195 69a7 +5196 6bd4 +5197..5199 6bd6 +5200 6cb8 +5201 7435 +5202 75fa +5203 7812 +5204 7891 +5205 79d5 +5206 79d8 +5207 7c83 +5208 7dcb +5209 7fe1 +5210 80a5 +5211 813e +5212 81c2 +5213 83f2 +5214 871a +5215 88e8 +5216 8ab9 +5217 8b6c +5218 8cbb +5219 9119 +5220 975e +5221 98db +5222 9f3b +5223 56ac +5224 5b2a +5225 5f6c +5226 658c +5227 6ab3 +5228 6baf +5229 6d5c +5230 6ff1 +5231 7015 +5232 725d +5233 73ad +5234 8ca7 +5235 8cd3 +5236 983b +5237 6191 +5238 6c37 +5239 8058 +5240 9a01 +5241 4e4d +5242 4e8b +5243 4e9b +5244 4ed5 +5245 4f3a +5246 4f3c +5247 4f7f +5248 4fdf +5249 50ff +5250 53f2 +5251 53f8 +5252 5506 +5253 55e3 +5254 56db +5255 58eb +5256 5962 +5257 5a11 +5258 5beb +5259 5bfa +5260 5c04 +5261 5df3 +5262 5e2b +5263 5f99 +5264 601d +5265 6368 +5266 659c +5267 65af +5268 67f6 +5269 67fb +5270 68ad +5271 6b7b +5272 6c99 +5273 6cd7 +5274 6e23 +5275 7009 +5276 7345 +5277 7802 +5278 793e +5279 7940 +5280 7960 +5281 79c1 +5282 7be9 +5283 7d17 +5284 7d72 +5285 8086 +5286 820d +5287 838e +5288 84d1 +5289 86c7 +5290 88df +5291 8a50 +5292 8a5e +5293 8b1d +5294 8cdc +5295 8d66 +5296 8fad +5297 90aa +5298 98fc +5299 99df +5300 9e9d +5301 524a +5302 6714 +5303 5098 +5304 522a +5305 5c71 +5306 6563 +5307 6c55 +5308 73ca +5309 7523 +5310 759d +5311 7b97 +5312 849c +5313 9178 +5314 9730 +5315 4e77 +5316 6492 +5317 6bba +5318 715e +5319 85a9 +5320 4e09 +5321 6749 +5322 68ee +5323 6e17 +5324 829f +5325 8518 +5326 886b +5327 63f7 +5328 6f81 +5329 9212 +5330 98af +5331 4e0a +5332 50b7 +5333 50cf +5334 511f +5335 5546 +5336 55aa +5337 5617 +5338 5b40 +5339 5c19 +5340 5ce0 +5341 5e38 +5342 5e8a +5343 5ea0 +5344 5ec2 +5345 60f3 +5346 6851 +5347 6a61 +5348 6e58 +5349 723d +5350 7240 +5351 72c0 +5352 76f8 +5353 7965 +5354 7bb1 +5355 7fd4 +5356 88f3 +5357 89f4 +5358 8a73 +5359 8c61 +5360 8cde +5361 971c +5362 585e +5363 74bd +5364 8cfd +5365 55c7 +5366 7a61 +5367 7d22 +5368 8272 +5369 7272 +5370 751f +5371 7525 +5372 7b19 +5373 5885 +5374 58fb +5375 5dbc +5376 5e8f +5377 5eb6 +5378 5f90 +5379 6055 +5380 6292 +5381 637f +5382 654d +5383 6691 +5384 66d9 +5385 66f8 +5386 6816 +5387 68f2 +5388 7280 +5389 745e +5390 7b6e +5391 7d6e +5392 7dd6 +5393 7f72 +5394 80e5 +5395 8212 +5396 85af +5397 897f +5398 8a93 +5399 901d +5400 92e4 +5401 9ecd +5402 9f20 +5403 5915 +5404 596d +5405 5e2d +5406 60dc +5407 6614 +5408 6673 +5409 6790 +5410 6c50 +5411 6dc5 +5412 6f5f +5413 77f3 +5414 78a9 +5415 84c6 +5416 91cb +5417 932b +5418 4ed9 +5419 50ca +5420 5148 +5421 5584 +5422 5b0b +5423 5ba3 +5424 6247 +5425 657e +5426 65cb +5427 6e32 +5428 717d +5429 7401 +5430 7444 +5431 7487 +5432 74bf +5433 766c +5434 79aa +5435 7dda +5436 7e55 +5437 7fa8 +5438 817a +5439 81b3 +5440 8239 +5441 861a +5442 87ec +5443 8a75 +5444 8de3 +5445 9078 +5446 9291 +5447 9425 +5448 994d +5449 9bae +5450 5368 +5451 5c51 +5452 6954 +5453 6cc4 +5454 6d29 +5455 6e2b +5456 820c +5457 859b +5458 893b +5459 8a2d +5460 8aaa +5461 96ea +5462 9f67 +5463 5261 +5464 66b9 +5465 6bb2 +5466 7e96 +5467 87fe +5468 8d0d +5469 9583 +5470 965d +5471 651d +5472 6d89 +5473 71ee +5474 57ce +5475 59d3 +5476 5bac +5477 6027 +5478 60fa +5479 6210 +5480 661f +5481 665f +5482 7329 +5483 73f9 +5484 76db +5485 7701 +5486 7b6c +5487 8056 +5488 8072 +5489 8165 +5490 8aa0 +5491 9192 +5492 4e16 +5493 52e2 +5494 6b72 +5495 6d17 +5496 7a05 +5497 7b39 +5498 7d30 +5499 8cb0 +5500 53ec +5501 562f +5502 5851 +5503 5bb5 +5504 5c0f +5505 5c11 +5506 5de2 +5507 6240 +5508 6383 +5509 6414 +5510 662d +5511 68b3 +5512 6cbc +5513 6d88 +5514 6eaf +5515 701f +5516 70a4 +5517 71d2 +5518 7526 +5519 758f +5520 758e +5521 7619 +5522 7b11 +5523 7be0 +5524 7c2b +5525 7d20 +5526 7d39 +5527 852c +5528 856d +5529 8607 +5530 8a34 +5531 900d +5532 9061 +5533 90b5 +5534 92b7 +5535 97f6 +5536 9a37 +5537 4fd7 +5538 5c6c +5539 675f +5540 6d91 +5541 7c9f +5542 7e8c +5543 8b16 +5544 8d16 +5545 901f +5546 5b6b +5547 5dfd +5548 640d +5549 84c0 +5550 905c +5551 98e1 +5552 7387 +5553 5b8b +5554 609a +5555 677e +5556 6dde +5557 8a1f +5558 8aa6 +5559 9001 +5560 980c +5561 5237 +5562 7051 +5563 788e +5564 9396 +5565 8870 +5566 91d7 +5567 4fee +5568 53d7 +5569 55fd +5570 56da +5571 5782 +5572 58fd +5573 5ac2 +5574 5b88 +5575 5cab +5576 5cc0 +5577 5e25 +5578 6101 +5579 620d +5580 624b +5581 6388 +5582 641c +5583 6536 +5584 6578 +5585 6a39 +5586 6b8a +5587 6c34 +5588 6d19 +5589 6f31 +5590 71e7 +5591 72e9 +5592 7378 +5593 7407 +5594 74b2 +5595 7626 +5596 7761 +5597 79c0 +5598 7a57 +5599 7aea +5600 7cb9 +5601 7d8f +5602 7dac +5603 7e61 +5604 7f9e +5605 8129 +5606 8331 +5607 8490 +5608 84da +5609 85ea +5610 8896 +5611 8ab0 +5612 8b90 +5613 8f38 +5614 9042 +5615 9083 +5616 916c +5617 9296 +5618 92b9 +5619 968b +5620..5621 96a7 +5622 96d6 +5623 9700 +5624 9808 +5625 9996 +5626 9ad3 +5627 9b1a +5628 53d4 +5629 587e +5630 5919 +5631 5b70 +5632 5bbf +5633 6dd1 +5634 6f5a +5635 719f +5636 7421 +5637 74b9 +5638 8085 +5639 83fd +5640 5de1 +5641 5f87 +5642 5faa +5643 6042 +5644 65ec +5645 6812 +5646 696f +5647 6a53 +5648 6b89 +5649 6d35 +5650 6df3 +5651 73e3 +5652 76fe +5653 77ac +5654 7b4d +5655 7d14 +5656 8123 +5657 821c +5658 8340 +5659 84f4 +5660 8563 +5661 8a62 +5662 8ac4 +5663 9187 +5664 931e +5665 9806 +5666 99b4 +5667 620c +5668 8853 +5669 8ff0 +5670 9265 +5671 5d07 +5672 5d27 +5673 5d69 +5674 745f +5675 819d +5676 8768 +5677 6fd5 +5678 62fe +5679 7fd2 +5680 8936 +5681 8972 +5682 4e1e +5683 4e58 +5684 50e7 +5685 52dd +5686 5347 +5687 627f +5688 6607 +5689 7e69 +5690 8805 +5691 965e +5692 4f8d +5693 5319 +5694 5636 +5695 59cb +5696 5aa4 +5697 5c38 +5698 5c4e +5699 5c4d +5700 5e02 +5701 5f11 +5702 6043 +5703 65bd +5704 662f +5705 6642 +5706 67be +5707 67f4 +5708 731c +5709 77e2 +5710 793a +5711 7fc5 +5712 8494 +5713 84cd +5714 8996 +5715 8a66 +5716 8a69 +5717 8ae1 +5718 8c55 +5719 8c7a +5720 57f4 +5721 5bd4 +5722 5f0f +5723 606f +5724 62ed +5725 690d +5726 6b96 +5727 6e5c +5728 7184 +5729 7bd2 +5730 8755 +5731 8b58 +5732 8efe +5733 98df +5734 98fe +5735 4f38 +5736 4f81 +5737 4fe1 +5738 547b +5739 5a20 +5740 5bb8 +5741 613c +5742 65b0 +5743 6668 +5744 71fc +5745 7533 +5746 795e +5747 7d33 +5748 814e +5749 81e3 +5750 8398 +5751 85aa +5752 85ce +5753 8703 +5754 8a0a +5755 8eab +5756 8f9b +5757 8fc5 +5758 5931 +5759 5ba4 +5760 5be6 +5761 6089 +5762 5be9 +5763 5c0b +5764 5fc3 +5765 6c81 +5766 6df1 +5767 700b +5768 751a +5769 82af +5770 8af6 +5771 4ec0 +5772 5341 +5773 96d9 +5774 6c0f +5775 4e9e +5776 4fc4 +5777 5152 +5778 555e +5779 5a25 +5780 5ce8 +5781 6211 +5782 7259 +5783 82bd +5784 83aa +5785 86fe +5786 8859 +5787 8a1d +5788 963f +5789 96c5 +5790 9913 +5791 9d09 +5792 9d5d +5793 580a +5794 5cb3 +5795 5dbd +5796 5e44 +5797 60e1 +5798 6115 +5799 63e1 +5800 6a02 +5801 6e25 +5802 9102 +5803 9354 +5804 984e +5805 9c10 +5806 9f77 +5807 5b89 +5808 5cb8 +5809 6309 +5810 664f +5811 6848 +5812 773c +5813 96c1 +5814 978d +5815 9854 +5816 9b9f +5817 65a1 +5818 8b01 +5819 8ecb +5820 95bc +5821 5535 +5822 5ca9 +5823 5dd6 +5824 5eb5 +5825 6697 +5826 764c +5827 83f4 +5828 95c7 +5829 58d3 +5830 62bc +5831 72ce +5832 9d28 +5833 4ef0 +5834 592e +5835 600f +5836 663b +5837 6b83 +5838 79e7 +5839 9d26 +5840 5393 +5841 54c0 +5842 57c3 +5843 5d16 +5844 611b +5845 66d6 +5846 6daf +5847 788d +5848 827e +5849 9698 +5850 9744 +5851 5384 +5852 627c +5853 6396 +5854 6db2 +5855 7e0a +5856 814b +5857 984d +5858 6afb +5859 7f4c +5860 9daf +5861 9e1a +5862 4e5f +5863 503b +5864 51b6 +5865 591c +5866 60f9 +5867 63f6 +5868 6930 +5869 723a +5870 8036 +5871 91ce +5872 5f31 +5873 7d04 +5874 82e5 +5875 846f +5876 84bb +5877 85e5 +5878 8e8d +5879 4f6f +5880 58e4 +5881 5b43 +5882 6059 +5883 63da +5884 6518 +5885 656d +5886 6698 +5887 694a +5888 6a23 +5889 6d0b +5890 7001 +5891 716c +5892 75d2 +5893 760d +5894 79b3 +5895 7a70 +5896 7f8a +5897 8944 +5898 8b93 +5899 91c0 +5900 967d +5901 990a +5902 5704 +5903 5fa1 +5904 65bc +5905 6f01 +5906 7600 +5907 79a6 +5908 8a9e +5909 99ad +5910 9b5a +5911 9f6c +5912 5104 +5913 61b6 +5914 6291 +5915 6a8d +5916 81c6 +5917 5043 +5918 5830 +5919 5f66 +5920 7109 +5921 8a00 +5922 8afa +5923 5b7c +5924 8616 +5925 4ffa +5926 513c +5927 56b4 +5928 5944 +5929 63a9 +5930 6df9 +5931 5daa +5932 696d +5933 5186 +5934 4e88 +5935 4f59 +5936 5982 +5937 6b5f +5938 6c5d +5939 74b5 +5940 7916 +5941 8207 +5942 8245 +5943 8339 +5944 8f3f +5945 8f5d +5946 9918 +5947 4ea6 +5948 57df +5949 5f79 +5950 6613 +5951 75ab +5952 7e79 +5953 8b6f +5954 9006 +5955 9a5b +5956 56a5 +5957 5827 +5958 59f8 +5959 5a1f +5960 5bb4 +5961 5ef6 +5962 6350 +5963 633b +5964 693d +5965 6c87 +5966 6cbf +5967 6d8e +5968 6d93 +5969 6df5 +5970 6f14 +5971 70df +5972 7136 +5973 7159 +5974 71c3 +5975 71d5 +5976 784f +5977 786f +5978 7b75 +5979 7de3 +5980 7e2f +5981 884d +5982 8edf +5983 925b +5984 9cf6 +5985 6085 +5986 6d85 +5987 71b1 +5988 95b1 +5989 53ad +5990 67d3 +5991 708e +5992 7130 +5993 7430 +5994 8276 +5995 82d2 +5996 95bb +5997 9ae5 +5998 9e7d +5999 66c4 +6000 71c1 +6001 8449 +6002 584b +6003 5db8 +6004 5f71 +6005 6620 +6006 668e +6007 6979 +6008 69ae +6009 6c38 +6010 6cf3 +6011 6e36 +6012 6f41 +6013 6fda +6014 701b +6015 702f +6016 7150 +6017 71df +6018 7370 +6019 745b +6020 74d4 +6021 76c8 +6022 7a4e +6023 7e93 +6024 82f1 +6025 8a60 +6026 8fce +6027 9348 +6028 9719 +6029 4e42 +6030 502a +6031 5208 +6032 53e1 +6033 66f3 +6034 6c6d +6035 6fca +6036 730a +6037 777f +6038 7a62 +6039 82ae +6040 85dd +6041 8602 +6042 88d4 +6043 8a63 +6044 8b7d +6045 8c6b +6046 92b3 +6047 9713 +6048 9810 +6049 4e94 +6050 4f0d +6051 4fc9 +6052 50b2 +6053 5348 +6054 543e +6055 5433 +6056 55da +6057 5862 +6058 58ba +6059 5967 +6060 5a1b +6061 5be4 +6062 609f +6063 61ca +6064 6556 +6065 65ff +6066 6664 +6067 68a7 +6068 6c5a +6069 6fb3 +6070 70cf +6071 71ac +6072 7352 +6073 7b7d +6074 8708 +6075 8aa4 +6076 9c32 +6077 9f07 +6078 5c4b +6079 6c83 +6080 7344 +6081 7389 +6082 923a +6083 6eab +6084 7465 +6085 761f +6086 7a69 +6087 7e15 +6088 860a +6089 5140 +6090 58c5 +6091 64c1 +6092 74ee +6093 7515 +6094 7670 +6095 7fc1 +6096 9095 +6097 96cd +6098 9954 +6099 6e26 +6100 74e6 +6101..6102 7aa9 +6103 81e5 +6104 86d9 +6105 8778 +6106 8a1b +6107 5a49 +6108 5b8c +6109 5b9b +6110 68a1 +6111 6900 +6112 6d63 +6113 73a9 +6114 7413 +6115 742c +6116 7897 +6117 7de9 +6118 7feb +6119 8118 +6120 8155 +6121 839e +6122 8c4c +6123 962e +6124 9811 +6125 66f0 +6126 5f80 +6127 65fa +6128 6789 +6129 6c6a +6130 738b +6131 502d +6132 5a03 +6133 6b6a +6134 77ee +6135 5916 +6136 5d6c +6137 5dcd +6138 7325 +6139 754f +6140 50e5 +6141 51f9 +6142 582f +6143 592d +6144 5996 +6145 59da +6146 5be5 +6147 5da2 +6148 62d7 +6149 6416 +6150 6493 +6151 64fe +6152 66dc +6153 6a48 +6154 71ff +6155 7464 +6156 7a88 +6157 7aaf +6158 7e47 +6159 7e5e +6160 8000 +6161 8170 +6162 87ef +6163 8981 +6164 8b20 +6165 9059 +6166 9080 +6167 9952 +6168 617e +6169 6b32 +6170 6d74 +6171 7e1f +6172 8925 +6173 8fb1 +6174 4fd1 +6175 50ad +6176 5197 +6177 52c7 +6178 57c7 +6179 5889 +6180 5bb9 +6181 5eb8 +6182 6142 +6183 6995 +6184 6d8c +6185 6e67 +6186 6eb6 +6187 7194 +6188 7462 +6189 7528 +6190 752c +6191 8073 +6192 8338 +6193 84c9 +6194 8e0a +6195 9394 +6196 93de +6197 4e8e +6198 4f51 +6199 5076 +6200 512a +6201 53c8 +6202 53cb +6203 53f3 +6204 5b87 +6205 5bd3 +6206 5c24 +6207 611a +6208 6182 +6209 65f4 +6210 725b +6211 7397 +6212 7440 +6213 76c2 +6214 7950 +6215 7991 +6216 79b9 +6217 7d06 +6218 7fbd +6219 828b +6220 85d5 +6221 865e +6222 8fc2 +6223 9047 +6224 90f5 +6225 91ea +6226 9685 +6227..6228 96e8 +6229 52d6 +6230 5f67 +6231 65ed +6232 6631 +6233 682f +6234 715c +6235 7a36 +6236 90c1 +6237 980a +6238 4e91 +6239 6a52 +6240 6b9e +6241 6f90 +6242 7189 +6243 8018 +6244 82b8 +6245 8553 +6246 904b +6247 9695 +6248 96f2 +6249 97fb +6250 851a +6251 9b31 +6252 4e90 +6253 718a +6254 96c4 +6255 5143 +6256 539f +6257 54e1 +6258 5713 +6259 5712 +6260 57a3 +6261 5a9b +6262 5ac4 +6263 5bc3 +6264 6028 +6265 613f +6266 63f4 +6267 6c85 +6268 6d39 +6269 6e72 +6270 6e90 +6271 7230 +6272 733f +6273 7457 +6274 82d1 +6275 8881 +6276 8f45 +6277 9060 +6278 9662 +6279 9858 +6280 9d1b +6281 6708 +6282 8d8a +6283 925e +6284 4f4d +6285 5049 +6286 50de +6287 5371 +6288 570d +6289 59d4 +6290 5a01 +6291 5c09 +6292 6170 +6293 6690 +6294 6e2d +6295 7232 +6296 744b +6297 7def +6298 80c3 +6299 840e +6300 8466 +6301 853f +6302 875f +6303 885b +6304 8918 +6305 8b02 +6306 9055 +6307 97cb +6308 9b4f +6309 4e73 +6310 4f91 +6311 5112 +6312 516a +6313 552f +6314 55a9 +6315 5b7a +6316 5ba5 +6317..6318 5e7c +6319 5ebe +6320 60a0 +6321 60df +6322..6323 6108 +6324 63c4 +6325 6538 +6326 6709 +6327 67d4 +6328 67da +6329..6330 6961 +6331 6cb9 +6332 6d27 +6333 6e38 +6334 6fe1 +6335..6336 7336 +6337 745c +6338 7531 +6339 7652 +6340 7dad +6341 81fe +6342 8438 +6343 88d5 +6344 8a98 +6345 8adb +6346 8aed +6347 8e30 +6348 8e42 +6349 904a +6350 903e +6351 907a +6352 9149 +6353 91c9 +6354 936e +6355 5809 +6356 6bd3 +6357 8089 +6358 80b2 +6359 5141 +6360 596b +6361 5c39 +6362 6f64 +6363 73a7 +6364 80e4 +6365 8d07 +6366 9217 +6367 958f +6368 807f +6369 620e +6370 701c +6371 7d68 +6372 878d +6373 57a0 +6374 6069 +6375 6147 +6376 6bb7 +6377 8abe +6378 9280 +6379 96b1 +6380 4e59 +6381 541f +6382 6deb +6383 852d +6384 9670 +6385 97f3 +6386 98ee +6387 63d6 +6388 6ce3 +6389 9091 +6390 51dd +6391 61c9 +6392 81ba +6393 9df9 +6394 4f9d +6395 501a +6396 5100 +6397 5b9c +6398 610f +6399 61ff +6400 64ec +6401 6905 +6402 6bc5 +6403 7591 +6404 77e3 +6405 7fa9 +6406 8264 +6407 858f +6408 87fb +6409 8863 +6410 8abc +6411 8b70 +6412 91ab +6413 4e8c +6414 4ee5 +6415 4f0a +6416 5937 +6417 59e8 +6418 5df2 +6419 5f1b +6420 5f5b +6421 6021 +6422 723e +6423 73e5 +6424 7570 +6425 75cd +6426 79fb +6427 800c +6428 8033 +6429 8084 +6430 82e1 +6431 8351 +6432 8cbd +6433 8cb3 +6434 9087 +6435 98f4 +6436 990c +6437 7037 +6438 76ca +6439 7fca +6440 7fcc +6441 7ffc +6442 8b1a +6443 4eba +6444 4ec1 +6445 5203 +6446 5370 +6447 54bd +6448 56e0 +6449 59fb +6450 5bc5 +6451 5f15 +6452 5fcd +6453 6e6e +6454 7d6a +6455 8335 +6456 8693 +6457 8a8d +6458 976d +6459 9777 +6460 4e00 +6461 4f5a +6462 4f7e +6463 58f9 +6464 65e5 +6465 6ea2 +6466 9038 +6467 93b0 +6468 99b9 +6469 4efb +6470 58ec +6471 598a +6472 59d9 +6473 6041 +6474 7a14 +6475 834f +6476 8cc3 +6477 5165 +6478 5344 +6479 4ecd +6480 5269 +6481 5b55 +6482 82bf +6483 4ed4 +6484 523a +6485 54a8 +6486 59c9 +6487 59ff +6488 5b50 +6489 5b57 +6490 5b5c +6491 6063 +6492 6148 +6493 6ecb +6494 7099 +6495 716e +6496 7386 +6497 74f7 +6498 75b5 +6499 78c1 +6500 7d2b +6501 8005 +6502 81ea +6503 8328 +6504 8517 +6505 85c9 +6506 8aee +6507 8cc7 +6508 96cc +6509 4f5c +6510 52fa +6511 56bc +6512 65ab +6513 6628 +6514 707c +6515 70b8 +6516 7235 +6517 7dbd +6518 828d +6519 914c +6520 96c0 +6521 9d72 +6522 5b71 +6523 68e7 +6524 6b98 +6525 6f7a +6526 76de +6527 5c91 +6528 66ab +6529 6f5b +6530 7bb4 +6531 7c2a +6532 8836 +6533 96dc +6534 4e08 +6535 4ed7 +6536 5320 +6537 5834 +6538 58bb +6539 58ef +6540 596c +6541 5c07 +6542 5e33 +6543 5e84 +6544 5f35 +6545 638c +6546 66b2 +6547 6756 +6548 6a1f +6549 6aa3 +6550 6b0c +6551 6f3f +6552 7246 +6553 7350 +6554 748b +6555 7ae0 +6556 7ca7 +6557 8178 +6558 81df +6559 81e7 +6560 838a +6561 846c +6562 8523 +6563 8594 +6564 85cf +6565 88dd +6566 8d13 +6567 91ac +6568 9577 +6569 969c +6570 518d +6571 54c9 +6572 5728 +6573 5bb0 +6574 624d +6575 6750 +6576 683d +6577 6893 +6578 6e3d +6579 6ed3 +6580 707d +6581 7e21 +6582 88c1 +6583 8ca1 +6584 8f09 +6585 9f4b +6586 9f4e +6587 722d +6588 7b8f +6589 8acd +6590 931a +6591 4f47 +6592 4f4e +6593 5132 +6594 5480 +6595 59d0 +6596 5e95 +6597 62b5 +6598 6775 +6599 696e +6600 6a17 +6601 6cae +6602 6e1a +6603 72d9 +6604 732a +6605 75bd +6606 7bb8 +6607 7d35 +6608 82e7 +6609 83f9 +6610 8457 +6611 85f7 +6612 8a5b +6613 8caf +6614 8e87 +6615 9019 +6616 90b8 +6617 96ce +6618 9f5f +6619 52e3 +6620 540a +6621 5ae1 +6622 5bc2 +6623 6458 +6624 6575 +6625 6ef4 +6626 72c4 +6627 7684 +6628 7a4d +6629 7b1b +6630 7c4d +6631 7e3e +6632 7fdf +6633 837b +6634 8b2b +6635 8cca +6636 8d64 +6637 8de1 +6638 8e5f +6639 8fea +6640 8ff9 +6641 9069 +6642 93d1 +6643 4f43 +6644 4f7a +6645 50b3 +6646 5168 +6647 5178 +6648 524d +6649 526a +6650 5861 +6651 587c +6652 5960 +6653 5c08 +6654 5c55 +6655 5edb +6656 609b +6657 6230 +6658 6813 +6659 6bbf +6660 6c08 +6661 6fb1 +6662 714e +6663 7420 +6664 7530 +6665 7538 +6666 7551 +6667 7672 +6668 7b4c +6669 7b8b +6670 7bad +6671 7bc6 +6672 7e8f +6673 8a6e +6674 8f3e +6675 8f49 +6676 923f +6677 9293 +6678 9322 +6679 942b +6680 96fb +6681 985a +6682 986b +6683 991e +6684 5207 +6685 622a +6686 6298 +6687 6d59 +6688 7664 +6689 7aca +6690 7bc0 +6691 7d76 +6692 5360 +6693 5cbe +6694 5e97 +6695 6f38 +6696 70b9 +6697 7c98 +6698 9711 +6699 9b8e +6700 9ede +6701 63a5 +6702 647a +6703 8776 +6704 4e01 +6705 4e95 +6706 4ead +6707 505c +6708 5075 +6709 5448 +6710 59c3 +6711 5b9a +6712 5e40 +6713 5ead +6714 5ef7 +6715 5f81 +6716 60c5 +6717 633a +6718 653f +6719 6574 +6720 65cc +6721 6676 +6722 6678 +6723 67fe +6724 6968 +6725 6a89 +6726 6b63 +6727 6c40 +6728 6dc0 +6729 6de8 +6730 6e1f +6731 6e5e +6732 701e +6733 70a1 +6734 738e +6735 73fd +6736 753a +6737 775b +6738 7887 +6739 798e +6740 7a0b +6741 7a7d +6742 7cbe +6743 7d8e +6744 8247 +6745 8a02 +6746 8aea +6747 8c9e +6748 912d +6749 914a +6750 91d8 +6751 9266 +6752 92cc +6753 9320 +6754 9706 +6755 9756 +6756 975c +6757 9802 +6758 9f0e +6759 5236 +6760 5291 +6761 557c +6762 5824 +6763 5e1d +6764 5f1f +6765 608c +6766 63d0 +6767 68af +6768 6fdf +6769 796d +6770 7b2c +6771 81cd +6772 85ba +6773 88fd +6774 8af8 +6775 8e44 +6776 918d +6777 9664 +6778 969b +6779 973d +6780 984c +6781 9f4a +6782 4fce +6783 5146 +6784 51cb +6785 52a9 +6786 5632 +6787 5f14 +6788 5f6b +6789 63aa +6790 64cd +6791 65e9 +6792 6641 +6793 66fa +6794 66f9 +6795 671d +6796 689d +6797 68d7 +6798 69fd +6799 6f15 +6800 6f6e +6801 7167 +6802 71e5 +6803 722a +6804 74aa +6805 773a +6806 7956 +6807 795a +6808 79df +6809 7a20 +6810 7a95 +6811 7c97 +6812 7cdf +6813 7d44 +6814 7e70 +6815 8087 +6816 85fb +6817 86a4 +6818 8a54 +6819 8abf +6820 8d99 +6821 8e81 +6822 9020 +6823 906d +6824 91e3 +6825 963b +6826 96d5 +6827 9ce5 +6828 65cf +6829 7c07 +6830 8db3 +6831 93c3 +6832 5b58 +6833 5c0a +6834 5352 +6835 62d9 +6836 731d +6837 5027 +6838 5b97 +6839 5f9e +6840 60b0 +6841 616b +6842 68d5 +6843 6dd9 +6844 742e +6845 7a2e +6846 7d42 +6847 7d9c +6848 7e31 +6849 816b +6850 8e2a +6851 8e35 +6852 937e +6853 9418 +6854 4f50 +6855 5750 +6856 5de6 +6857 5ea7 +6858 632b +6859 7f6a +6860 4e3b +6861 4f4f +6862 4f8f +6863 505a +6864 59dd +6865 80c4 +6866 546a +6867 5468 +6868 55fe +6869 594f +6870 5b99 +6871 5dde +6872 5eda +6873 665d +6874 6731 +6875 67f1 +6876 682a +6877 6ce8 +6878 6d32 +6879 6e4a +6880 6f8d +6881 70b7 +6882 73e0 +6883 7587 +6884 7c4c +6885 7d02 +6886 7d2c +6887 7da2 +6888 821f +6889 86db +6890 8a3b +6891 8a85 +6892 8d70 +6893 8e8a +6894 8f33 +6895 9031 +6896 914e +6897 9152 +6898 9444 +6899 99d0 +6900 7af9 +6901 7ca5 +6902 4fca +6903 5101 +6904 51c6 +6905 57c8 +6906 5bef +6907 5cfb +6908 6659 +6909 6a3d +6910 6d5a +6911 6e96 +6912 6fec +6913 710c +6914 756f +6915 7ae3 +6916 8822 +6917 9021 +6918 9075 +6919 96cb +6920 99ff +6921 8301 +6922 4e2d +6923 4ef2 +6924 8846 +6925 91cd +6926 537d +6927 6adb +6928 696b +6929 6c41 +6930 847a +6931 589e +6932 618e +6933 66fe +6934 62ef +6935 70dd +6936 7511 +6937 75c7 +6938 7e52 +6939 84b8 +6940 8b49 +6941 8d08 +6942 4e4b +6943 53ea +6944 54ab +6945 5730 +6946 5740 +6947 5fd7 +6948 6301 +6949 6307 +6950 646f +6951 652f +6952 65e8 +6953 667a +6954 679d +6955 67b3 +6956 6b62 +6957 6c60 +6958 6c9a +6959 6f2c +6960 77e5 +6961 7825 +6962 7949 +6963 7957 +6964 7d19 +6965 80a2 +6966 8102 +6967 81f3 +6968 829d +6969 82b7 +6970 8718 +6971 8a8c +6972 8d04 +6973 8dbe +6974 9072 +6975 76f4 +6976 7a19 +6977 7a37 +6978 7e54 +6979 8077 +6980 5507 +6981 55d4 +6982 5875 +6983 632f +6984 6422 +6985 6649 +6986 664b +6987 686d +6988 699b +6989 6b84 +6990 6d25 +6991 6eb1 +6992 73cd +6993 7468 +6994 74a1 +6995 755b +6996 75b9 +6997 76e1 +6998 771e +6999 778b +7000 79e6 +7001 7e09 +7002 7e1d +7003 81fb +7004 852f +7005 8897 +7006 8a3a +7007 8cd1 +7008 8eeb +7009 8fb0 +7010 9032 +7011 93ad +7012 9663 +7013 9673 +7014 9707 +7015 4f84 +7016 53f1 +7017 59ea +7018 5ac9 +7019 5e19 +7020 684e +7021 74c6 +7022 75be +7023 79e9 +7024 7a92 +7025 81a3 +7026 86ed +7027 8cea +7028 8dcc +7029 8fed +7030 659f +7031 6715 +7032 57f7 +7033 6f57 +7034 7ddd +7035 8f2f +7036 93f6 +7037 96c6 +7038 5fb5 +7039 61f2 +7040 6f84 +7041 4e14 +7042 4f98 +7043 501f +7044 53c9 +7045 55df +7046 5d6f +7047 5dee +7048 6b21 +7049 6b64 +7050 78cb +7051 7b9a +7052 8e49 +7053 8eca +7054 906e +7055 6349 +7056 643e +7057 7740 +7058 7a84 +7059 932f +7060 947f +7061 9f6a +7062 64b0 +7063 6faf +7064 71e6 +7065 74a8 +7066 74da +7067 7ac4 +7068 7c12 +7069 7e82 +7070 7cb2 +7071 7e98 +7072 8b9a +7073 8d0a +7074 947d +7075 9910 +7076 994c +7077 5239 +7078 5bdf +7079 64e6 +7080 672d +7081 7d2e +7082 50ed +7083 53c3 +7084 5879 +7085..7086 6158 +7087 61fa +7088 65ac +7089 7ad9 +7090 8b92 +7091 8b96 +7092 5009 +7093 5021 +7094 5275 +7095 5531 +7096 5a3c +7097 5ee0 +7098 5f70 +7099 6134 +7100 655e +7101 660c +7102 6636 +7103 66a2 +7104 69cd +7105 6ec4 +7106 6f32 +7107 7316 +7108 7621 +7109 7a93 +7110 8139 +7111 8259 +7112 83d6 +7113 84bc +7114 50b5 +7115 57f0 +7116 5bc0 +7117 5be8 +7118 5f69 +7119 63a1 +7120 7826 +7121 7db5 +7122 83dc +7123 8521 +7124 91c7 +7125 91f5 +7126 518a +7127 67f5 +7128 7b56 +7129 8cac +7130 51c4 +7131 59bb +7132 60bd +7133 8655 +7134 501c +7135 5254 +7136 5c3a +7137 617d +7138 621a +7139 62d3 +7140 64f2 +7141 65a5 +7142 6ecc +7143 7620 +7144 810a +7145 8e60 +7146 965f +7147 96bb +7148 4edf +7149 5343 +7150 5598 +7151 5929 +7152 5ddd +7153 64c5 +7154 6cc9 +7155 6dfa +7156 7394 +7157 7a7f +7158 821b +7159 85a6 +7160 8ce4 +7161 8e10 +7162 9077 +7163 91e7 +7164 95e1 +7165 9621 +7166 97c6 +7167 51f8 +7168 54f2 +7169 5586 +7170 5fb9 +7171 64a4 +7172 6f88 +7173 7db4 +7174 8f1f +7175 8f4d +7176 9435 +7177 50c9 +7178 5c16 +7179 6cbe +7180 6dfb +7181 751b +7182 77bb +7183 7c3d +7184 7c64 +7185 8a79 +7186 8ac2 +7187 581e +7188 59be +7189 5e16 +7190 6377 +7191 7252 +7192 758a +7193 776b +7194 8adc +7195 8cbc +7196 8f12 +7197 5ef3 +7198 6674 +7199 6df8 +7200 807d +7201 83c1 +7202 8acb +7203 9751 +7204 9bd6 +7205 5243 +7206 66ff +7207 6d95 +7208 6eef +7209 7de0 +7210 8ae6 +7211 902e +7212 905e +7213 9ad4 +7214 521d +7215 527f +7216 54e8 +7217 6194 +7218 6284 +7219 62db +7220 68a2 +7221 6912 +7222 695a +7223 6a35 +7224 7092 +7225 7126 +7226 785d +7227 7901 +7228 790e +7229 79d2 +7230 7a0d +7231 8096 +7232 8278 +7233 82d5 +7234 8349 +7235 8549 +7236 8c82 +7237 8d85 +7238 9162 +7239 918b +7240 91ae +7241 4fc3 +7242 56d1 +7243 71ed +7244 77d7 +7245 8700 +7246 89f8 +7247 5bf8 +7248 5fd6 +7249 6751 +7250 90a8 +7251 53e2 +7252 585a +7253 5bf5 +7254 60a4 +7255 6181 +7256 6460 +7257 7e3d +7258 8070 +7259 8525 +7260 9283 +7261 64ae +7262 50ac +7263 5d14 +7264 6700 +7265 589c +7266 62bd +7267 63a8 +7268 690e +7269 6978 +7270 6a1e +7271 6e6b +7272 76ba +7273 79cb +7274 82bb +7275 8429 +7276 8acf +7277 8da8 +7278 8ffd +7279 9112 +7280 914b +7281 919c +7282 9310 +7283 9318 +7284 939a +7285 96db +7286 9a36 +7287 9c0d +7288 4e11 +7289 755c +7290 795d +7291 7afa +7292 7b51 +7293 7bc9 +7294 7e2e +7295 84c4 +7296 8e59 +7297 8e74 +7298 8ef8 +7299 9010 +7300 6625 +7301 693f +7302 7443 +7303 51fa +7304 672e +7305 9edc +7306 5145 +7307 5fe0 +7308 6c96 +7309 87f2 +7310 885d +7311 8877 +7312 60b4 +7313 81b5 +7314 8403 +7315 8d05 +7316 53d6 +7317 5439 +7318 5634 +7319 5a36 +7320 5c31 +7321 708a +7322 7fe0 +7323 805a +7324 8106 +7325 81ed +7326 8da3 +7327 9189 +7328 9a5f +7329 9df2 +7330 5074 +7331 4ec4 +7332 53a0 +7333 60fb +7334 6e2c +7335 5c64 +7336 4f88 +7337 5024 +7338 55e4 +7339 5cd9 +7340 5e5f +7341 6065 +7342 6894 +7343 6cbb +7344 6dc4 +7345 71be +7346 75d4 +7347 75f4 +7348 7661 +7349 7a1a +7350 7a49 +7351 7dc7 +7352 7dfb +7353 7f6e +7354 81f4 +7355 86a9 +7356 8f1c +7357 96c9 +7358 99b3 +7359 9f52 +7360 5247 +7361 52c5 +7362 98ed +7363 89aa +7364 4e03 +7365 67d2 +7366 6f06 +7367 4fb5 +7368 5be2 +7369 6795 +7370 6c88 +7371 6d78 +7372 741b +7373 7827 +7374 91dd +7375 937c +7376 87c4 +7377 79e4 +7378 7a31 +7379 5feb +7380 4ed6 +7381 54a4 +7382 553e +7383 58ae +7384 59a5 +7385 60f0 +7386 6253 +7387 62d6 +7388 6736 +7389 6955 +7390 8235 +7391 9640 +7392 99b1 +7393 99dd +7394 502c +7395 5353 +7396 5544 +7397 577c +7398 6258 +7399 64e2 +7400 666b +7401 67dd +7402 6fc1 +7403 6fef +7404 7422 +7405 7438 +7406 8a17 +7407 9438 +7408 5451 +7409 5606 +7410 5766 +7411 5f48 +7412 619a +7413 6b4e +7414 7058 +7415 70ad +7416 7dbb +7417 8a95 +7418 596a +7419 812b +7420 63a2 +7421 7708 +7422 803d +7423 8caa +7424 5854 +7425 642d +7426 69bb +7427 5b95 +7428 5e11 +7429 6e6f +7430 8569 +7431 514c +7432 53f0 +7433 592a +7434 6020 +7435 614b +7436 6b86 +7437 6c70 +7438 6cf0 +7439 7b1e +7440 80ce +7441 82d4 +7442 8dc6 +7443 90b0 +7444 98b1 +7445 64c7 +7446 6fa4 +7447 6491 +7448 6504 +7449 514e +7450 5410 +7451 571f +7452 8a0e +7453 615f +7454 6876 +7455 75db +7456 7b52 +7457 7d71 +7458 901a +7459 5806 +7460 69cc +7461 817f +7462 892a +7463 9000 +7464 9839 +7465 5078 +7466 5957 +7467 59ac +7468 6295 +7469 900f +7470 9b2a +7471 615d +7472 7279 +7473 95d6 +7474 5761 +7475 5a46 +7476 5df4 +7477 628a +7478 64ad +7479 64fa +7480 6777 +7481 6ce2 +7482 6d3e +7483 722c +7484 7436 +7485 7834 +7486 7f77 +7487 82ad +7488 8ddb +7489 9817 +7490 5224 +7491 5742 +7492 677f +7493 7248 +7494 74e3 +7495 8ca9 +7496 8fa6 +7497 9211 +7498 962a +7499 516b +7500 53ed +7501 634c +7502 4f69 +7503 5504 +7504 6096 +7505 6557 +7506 6c9b +7507 6d7f +7508 724c +7509 72fd +7510 7a17 +7511 8987 +7512 8c9d +7513 5f6d +7514 6f8e +7515 70f9 +7516 81a8 +7517 610e +7518 4fbf +7519 504f +7520 6241 +7521 7247 +7522 7bc7 +7523 7de8 +7524 7fe9 +7525 904d +7526 97ad +7527 9a19 +7528 8cb6 +7529 576a +7530 5e73 +7531 67b0 +7532 840d +7533 8a55 +7534 5420 +7535 5b16 +7536 5e63 +7537 5ee2 +7538 5f0a +7539 6583 +7540 80ba +7541 853d +7542 9589 +7543 965b +7544 4f48 +7545 5305 +7546 530d +7547 530f +7548 5486 +7549 54fa +7550 5703 +7551 5e03 +7552 6016 +7553 629b +7554 62b1 +7555 6355 +7556 6ce1 +7557 6d66 +7558 75b1 +7559 7832 +7560 80de +7561 812f +7562 82de +7563 8461 +7564 84b2 +7565 888d +7566 8912 +7567 900b +7568 92ea +7569 98fd +7570 9b91 +7571 5e45 +7572 66b4 +7573 66dd +7574 7011 +7575 7206 +7576 4ff5 +7577 527d +7578 5f6a +7579 6153 +7580 6753 +7581 6a19 +7582 6f02 +7583 74e2 +7584 7968 +7585 8868 +7586 8c79 +7587 98c7 +7588 98c4 +7589 9a43 +7590 54c1 +7591 7a1f +7592 6953 +7593 8af7 +7594 8c4a +7595 98a8 +7596 99ae +7597 5f7c +7598 62ab +7599 75b2 +7600 76ae +7601 88ab +7602 907f +7603 9642 +7604 5339 +7605 5f3c +7606 5fc5 +7607 6ccc +7608 73cc +7609 7562 +7610 758b +7611 7b46 +7612 82fe +7613 999d +7614 4e4f +7615 903c +7616 4e0b +7617 4f55 +7618 53a6 +7619 590f +7620 5ec8 +7621 6630 +7622 6cb3 +7623 7455 +7624 8377 +7625 8766 +7626 8cc0 +7627 9050 +7628 971e +7629 9c15 +7630 58d1 +7631 5b78 +7632 8650 +7633 8b14 +7634 9db4 +7635 5bd2 +7636 6068 +7637 608d +7638 65f1 +7639 6c57 +7640 6f22 +7641 6fa3 +7642 701a +7643 7f55 +7644 7ff0 +7645..7646 9591 +7647 9650 +7648 97d3 +7649 5272 +7650 8f44 +7651 51fd +7652 542b +7653 54b8 +7654 5563 +7655 558a +7656 6abb +7657 6db5 +7658 7dd8 +7659 8266 +7660 929c +7661 9677 +7662 9e79 +7663 5408 +7664 54c8 +7665 76d2 +7666 86e4 +7667 95a4 +7668 95d4 +7669 965c +7670 4ea2 +7671 4f09 +7672 59ee +7673 5ae6 +7674 5df7 +7675 6052 +7676 6297 +7677 676d +7678 6841 +7679 6c86 +7680 6e2f +7681 7f38 +7682 809b +7683 822a +7684 9805 +7685 4ea5 +7686 5055 +7687 54b3 +7688 5793 +7689 595a +7690 5b69 +7691 5bb3 +7692 61c8 +7693 6977 +7694 6d77 +7695 7023 +7696 87f9 +7697 89e3 +7698 8a72 +7699 8ae7 +7700 9082 +7701 99ed +7702 9ab8 +7703 52be +7704 6838 +7705 5016 +7706 5e78 +7707 674f +7708 8347 +7709 884c +7710 4eab +7711 5411 +7712 56ae +7713 73e6 +7714 9115 +7715 97ff +7716 9909 +7717 9957 +7718 9999 +7719 5653 +7720 589f +7721 865b +7722 8a31 +7723 61b2 +7724 6af6 +7725 737b +7726 8ed2 +7727 6b47 +7728 96aa +7729 9a57 +7730 5955 +7731 7200 +7732 8d6b +7733 9769 +7734 4fd4 +7735 5cf4 +7736 5f26 +7737 61f8 +7738 665b +7739 6ceb +7740 70ab +7741 7384 +7742 73b9 +7743 73fe +7744 7729 +7745 774d +7746 7d43 +7747 7d62 +7748 7e23 +7749 8237 +7750 8852 +7751 8ce2 +7752 9249 +7753 986f +7754 5b51 +7755 7a74 +7756 8840 +7757 9801 +7758 5acc +7759 4fe0 +7760 5354 +7761 593e +7762 5cfd +7763 633e +7764 6d79 +7765 72f9 +7766 8105 +7767 8107 +7768 83a2 +7769 92cf +7770 9830 +7771 4ea8 +7772 5144 +7773 5211 +7774 578b +7775 5f62 +7776 6cc2 +7777 6ece +7778 7005 +7779 7050 +7780 70af +7781 7192 +7782 73e9 +7783 7469 +7784 834a +7785 87a2 +7786 8861 +7787 9008 +7788 90a2 +7789 93a3 +7790 99a8 +7791 516e +7792 5f57 +7793 60e0 +7794 6167 +7795 66b3 +7796 8559 +7797 8e4a +7798 91af +7799 978b +7800 4e4e +7801 4e92 +7802 547c +7803 58d5 +7804 58fa +7805 597d +7806 5cb5 +7807 5f27 +7808 6236 +7809 6248 +7810 660a +7811 6667 +7812 6beb +7813 6d69 +7814 6dcf +7815 6e56 +7816 6ef8 +7817 6f94 +7818 6fe0 +7819 6fe9 +7820 705d +7821 72d0 +7822 7425 +7823 745a +7824 74e0 +7825 7693 +7826 795c +7827 7cca +7828 7e1e +7829 80e1 +7830 82a6 +7831 846b +7832 84bf +7833 864e +7834 865f +7835 8774 +7836 8b77 +7837 8c6a +7838 93ac +7839 9800 +7840 9865 +7841 60d1 +7842 6216 +7843 9177 +7844 5a5a +7845 660f +7846 6df7 +7847 6e3e +7848 743f +7849 9b42 +7850 5ffd +7851 60da +7852 7b0f +7853 54c4 +7854 5f18 +7855 6c5e +7856 6cd3 +7857 6d2a +7858 70d8 +7859 7d05 +7860 8679 +7861 8a0c +7862 9d3b +7863 5316 +7864 548c +7865 5b05 +7866 6a3a +7867 706b +7868 7575 +7869 798d +7870 79be +7871 82b1 +7872 83ef +7873 8a71 +7874 8b41 +7875 8ca8 +7876 9774 +7877 64f4 +7878 652b +7879..7880 78ba +7881 7a6b +7882 4e38 +7883 559a +7884 5950 +7885 5ba6 +7886 5e7b +7887 60a3 +7888 63db +7889 6b61 +7890 6665 +7891 6853 +7892 6e19 +7893 7165 +7894 74b0 +7895 7d08 +7896 9084 +7897 9a69 +7898 9c25 +7899 6d3b +7900 6ed1 +7901 733e +7902 8c41 +7903 95ca +7904 51f0 +7905 5e4c +7906 5fa8 +7907 604d +7908 60f6 +7909 6130 +7910 614c +7911..7912 6643 +7913 69a5 +7914 6cc1 +7915 6e5f +7916 6ec9 +7917 6f62 +7918 714c +7919 749c +7920 7687 +7921 7bc1 +7922 7c27 +7923 8352 +7924 8757 +7925 9051 +7926 968d +7927 9ec3 +7928 532f +7929 56de +7930 5efb +7931 5f8a +7932 6062 +7933 6094 +7934 61f7 +7935 6666 +7936 6703 +7937 6a9c +7938 6dee +7939 6fae +7940 7070 +7941 736a +7942 7e6a +7943 81be +7944 8334 +7945 86d4 +7946 8aa8 +7947 8cc4 +7948 5283 +7949 7372 +7950 5b96 +7951 6a6b +7952 9404 +7953 54ee +7954 5686 +7955 5b5d +7956 6548 +7957 6585 +7958 66c9 +7959 689f +7960 6d8d +7961 6dc6 +7962 723b +7963 80b4 +7964 9175 +7965 9a4d +7966 4faf +7967 5019 +7968 539a +7969 540e +7970 543c +7971 5589 +7972 55c5 +7973 5e3f +7974 5f8c +7975 673d +7976 7166 +7977 73dd +7978 9005 +7979 52db +7980 52f3 +7981 5864 +7982 58ce +7983 7104 +7984 718f +7985 71fb +7986 85b0 +7987 8a13 +7988 6688 +7989 85a8 +7990 55a7 +7991 6684 +7992 714a +7993 8431 +7994 5349 +7995 5599 +7996 6bc1 +7997 5f59 +7998 5fbd +7999 63ee +8000 6689 +8001 7147 +8002 8af1 +8003 8f1d +8004 9ebe +8005 4f11 +8006 643a +8007 70cb +8008 7566 +8009 8667 +8010 6064 +8011 8b4e +8012 9df8 +8013 5147 +8014 51f6 +8015 5308 +8016 6d36 +8017 80f8 +8018 9ed1 +8019 6615 +8020 6b23 +8021 7098 +8022 75d5 +8023 5403 +8024 5c79 +8025 7d07 +8026 8a16 +8027 6b20 +8028 6b3d +8029 6b46 +8030 5438 +8031 6070 +8032 6d3d +8033 7fd5 +8034 8208 +8035 50d6 +8036 51de +8037 559c +8038 566b +8039 56cd +8040 59ec +8041 5b09 +8042 5e0c +8043 6199 +8044 6198 +8045 6231 +8046 665e +8047 66e6 +8048 7199 +8049..8050 71b9 +8051 72a7 +8052 79a7 +8053 7a00 +8054 7fb2 +8055 8a70 +8056 /Korea1.102.vert +8057 /Korea1.103.vert +8058 /Korea1.105.vert +8059 /Korea1.109.vert +8060 /Korea1.110.vert +8061 /Korea1.111.vert +8062 /Korea1.113.vert +8063 /Korea1.118.vert +8064 /Korea1.119.vert +8065 /Korea1.120.vert +8066 /Korea1.121.vert +8067 /Korea1.122.vert +8068 /Korea1.123.vert +8069 /Korea1.124.vert +8070 /Korea1.125.vert +8071 /Korea1.126.vert +8072 /Korea1.127.vert +8073 /Korea1.128.vert +8074 /Korea1.129.vert +8075 /Korea1.175.vert +8076 /Korea1.264.vert +8077 /Korea1.271.vert +8078 /Korea1.272.vert +8079 /Korea1.275.vert +8080 /Korea1.277.vert +8081 /Korea1.289.vert +8082 /Korea1.290.vert +8083 /Korea1.291.vert +8084 /Korea1.292.vert +8085 /Korea1.293.vert +8086 /Korea1.294.vert +8087 /Korea1.322.vert +8088 /Korea1.324.vert +8089 /Korea1.326.vert +8090 /Korea1.354.vert +8091 /Korea1.355.vert +8092 /Korea1.356.vert +8093 /Korea1.357.vert +8094 /uni0020.hw +8095 /uni0021.hw +8096 /uni0022.hw +8097 /uni0023.hw +8098 /uni0024.hw +8099 /uni0025.hw +8100 /uni0026.hw +8101 /uni0027.hw +8102 /uni0028.hw +8103 /uni0029.hw +8104 /uni002A.hw +8105 /uni002B.hw +8106 /uni002C.hw +8107 /uni002D.hw +8108 /uni002E.hw +8109 /uni002F.hw +8110 /uni0030.hw +8111 /uni0031.hw +8112 /uni0032.hw +8113 /uni0033.hw +8114 /uni0034.hw +8115 /uni0035.hw +8116 /uni0036.hw +8117 /uni0037.hw +8118 /uni0038.hw +8119 /uni0039.hw +8120 /uni003A.hw +8121 /uni003B.hw +8122 /uni003C.hw +8123 /uni003D.hw +8124 /uni003E.hw +8125 /uni003F.hw +8126 /uni0040.hw +8127 /uni0041.hw +8128 /uni0042.hw +8129 /uni0043.hw +8130 /uni0044.hw +8131 /uni0045.hw +8132 /uni0046.hw +8133 /uni0047.hw +8134 /uni0048.hw +8135 /uni0049.hw +8136 /uni004A.hw +8137 /uni004B.hw +8138 /uni004C.hw +8139 /uni004D.hw +8140 /uni004E.hw +8141 /uni004F.hw +8142 /uni0050.hw +8143 /uni0051.hw +8144 /uni0052.hw +8145 /uni0053.hw +8146 /uni0054.hw +8147 /uni0055.hw +8148 /uni0056.hw +8149 /uni0057.hw +8150 /uni0058.hw +8151 /uni0059.hw +8152 /uni005A.hw +8153 /uni005B.hw +8154 /uni20A9.hw +8155 /uni005D.hw +8156 /uni005E.hw +8157 /uni005F.hw +8158 /uni0060.hw +8159 /uni0061.hw +8160 /uni0062.hw +8161 /uni0063.hw +8162 /uni0064.hw +8163 /uni0065.hw +8164 /uni0066.hw +8165 /uni0067.hw +8166 /uni0068.hw +8167 /uni0069.hw +8168 /uni006A.hw +8169 /uni006B.hw +8170 /uni006C.hw +8171 /uni006D.hw +8172 /uni006E.hw +8173 /uni006F.hw +8174 /uni0070.hw +8175 /uni0071.hw +8176 /uni0072.hw +8177 /uni0073.hw +8178 /uni0074.hw +8179 /uni0075.hw +8180 /uni0076.hw +8181 /uni0077.hw +8182 /uni0078.hw +8183 /uni0079.hw +8184 /uni007A.hw +8185 /uni007B.hw +8186 /uni007C.hw +8187 /uni007D.hw +8188 /uni007E.hw +8189 /uni007F.hw +8190 /uni005C.hw +8219..8222 3016 +8237 201f +8238 201b +8239..8240 207a +8248 207c +8250..8251 207d +8275 02bc +8320 22ee +8321 2237 +8342..8351 278a +8388..8413 24b6 +8475..8476 227a +8477..8478 22ce +8479..8480 2280 +8481..8484 2270 +8486 228a +8488 228b +8489..8490 2276 +8491 2279 +8492..8493 22da +8499 2245 +8500 2243 +8501 2248 +8503 22a4 +8582 2034 +8594 266f +8599 2042 +8604 273d +8607 2022 +8612..8613 2039 +8630 271a +8631 2716 +8633 25ef +8637 2756 +8639 25cc +8664 262f +8671 3020 +8673..8682 2776 +8700 3012 +8701 3036 +8715 2206 +8717 221f +8719..8720 2225 +8722 2253 +8723 2251 +8724..8725 2266 +8726 2213 +8727..8729 2295 +8731 2314 +8734 2262 +8736 25b1 +8738 2222 +8739 2250 +8742 22a3 +8745..8746 226e +8747 2285 +8748 2284 +8749 2209 +8750 220c +8751..8752 22bb +8753 225a +8754 2306 +8761 329e +8763 203c +8775 25e6 +8779 25bf +8780 25b5 +8781 25b9 +8782 25c3 +8787 25ca +8788 3231 +8789 3239 +8790 33cb +8791..8795 246f +8814 21d0 +8815 21cf +8816 21cd +8854 21d1 +8855 21d3 +8864 21b2 +8865 21b1 +8867 21b4 +8868 21b0 +8869 21b3 +8884 21bc +8885 21c0 +8896..8897 21c4 +9042..9046 2483 +9080 3294 +9096 32a5 +9190 21e0 +9191 21e2 +9192 21e1 +9193 21e3 +9198 21e6 +9199 21e8 +9200 21e7 +9201 21e9 +9222 261d +9223 261f +9300 3290 +9301..9306 328a +9322..9323 301e +9324 2036 +9326 2035 +9330 30fc +9333..9334 ac02 +9335..9336 ac05 +9337..9341 ac0b +9342 ac18 +9343..9344 ac1e +9345..9347 ac21 +9348..9354 ac25 +9355 ac2e +9356..9361 ac32 +9362..9363 ac3a +9364..9366 ac3d +9367..9376 ac41 +9377 ac4c +9378..9383 ac4e +9384..9386 ac55 +9387..9389 ac59 +9390..9408 ac5d +9409..9410 ac72 +9411..9412 ac75 +9413 ac79 +9414..9418 ac7b +9419 ac82 +9420..9421 ac87 +9422..9424 ac8d +9425..9427 ac91 +9428..9434 ac95 +9435 ac9e +9436..9441 aca2 +9442 acab +9443..9444 acad +9445..9451 acb1 +9452 acba +9453..9455 acbe +9456..9457 acc2 +9458..9460 acc5 +9461..9463 acc9 +9464..9471 accd +9472 acd6 +9473..9480 acd8 +9481..9482 ace2 +9483..9484 ace5 +9485 ace9 +9486 aceb +9487..9488 aced +9489 acf2 +9490 acf4 +9491..9495 acf7 +9496..9497 acfe +9498..9500 ad01 +9501 ad05 +9502..9506 ad07 +9507 ad0e +9508 ad10 +9509..9514 ad12 +9515..9517 ad19 +9518..9520 ad1d +9521..9528 ad21 +9529..9530 ad2a +9531..9536 ad2e +9537..9538 ad36 +9539..9541 ad39 +9542..9548 ad3d +9549 ad46 +9550 ad48 +9551..9556 ad4a +9557..9559 ad51 +9560..9562 ad55 +9563..9570 ad59 +9571 ad62 +9572..9579 ad64 +9580..9581 ad6e +9582..9583 ad71 +9584..9587 ad77 +9588 ad7e +9589 ad80 +9590..9594 ad83 +9595..9596 ad8a +9597..9599 ad8d +9600..9610 ad91 +9611..9616 ad9e +9617..9634 ada5 +9635..9642 adb8 +9643..9644 adc2 +9645..9647 adc5 +9648..9654 adc9 +9655 add2 +9656..9663 add4 +9664..9666 addd +9667..9669 ade1 +9670..9688 ade5 +9689..9690 adfa +9691..9692 adfd +9693..9698 ae02 +9699 ae0a +9700 ae0c +9701..9706 ae0e +9707..9733 ae15 +9734..9735 ae32 +9736..9737 ae35 +9738 ae39 +9739..9743 ae3b +9744 ae42 +9745 ae44 +9746..9748 ae47 +9749 ae4b +9750 ae4f +9751..9753 ae51 +9754 ae55 +9755..9759 ae57 +9760 ae5e +9761..9763 ae62 +9764..9765 ae66 +9766..9767 ae6a +9768..9770 ae6d +9771..9777 ae71 +9778 ae7a +9779..9784 ae7e +9785..9790 ae86 +9791..9837 ae8d +9838 aebf +9839..9841 aec1 +9842..9848 aec5 +9849 aece +9850..9855 aed2 +9856..9857 aeda +9858..9868 aedd +9869..9870 aee9 +9871 aeec +9872..9877 aeee +9878..9880 aef5 +9881..9883 aef9 +9884..9893 aefd +9894..9897 af09 +9898..9899 af0e +9900..9926 af11 +9927..9928 af2e +9929 af31 +9930 af33 +9931..9937 af35 +9938 af3e +9939 af40 +9940..9943 af44 +9944..9949 af4a +9950..9960 af51 +9961..9966 af5e +9967..9985 af66 +9986..9991 af7a +9992..9994 af81 +9995..9997 af85 +9998..10004 af89 +10005..10007 af92 +10008..10013 af96 +10014..10040 af9d +10041..10042 afba +10043..10045 afbd +10046..10051 afc1 +10052 afca +10053 afcc +10054..10058 afcf +10059..10065 afd5 +10066..10076 afdd +10077..10082 afea +10083..10084 aff2 +10085..10087 aff5 +10088..10094 aff9 +10095..10096 b002 +10097..10103 b005 +10104..10106 b00d +10107..10109 b011 +10110..10116 b015 +10117..10126 b01e +10127..10153 b029 +10154..10155 b046 +10156 b049 +10157 b04b +10158 b04d +10159..10162 b04f +10163 b056 +10164 b058 +10165..10167 b05a +10168..10197 b05e +10198..10199 b07e +10200..10202 b081 +10203..10209 b085 +10210 b08e +10211 b090 +10212..10217 b092 +10218 b09b +10219..10220 b09d +10221..10225 b0a3 +10226 b0aa +10227 b0b0 +10228 b0b2 +10229..10230 b0b6 +10231..10233 b0b9 +10234..10240 b0bd +10241 b0c6 +10242..10247 b0ca +10248..10249 b0d2 +10250..10252 b0d5 +10253..10259 b0d9 +10260..10263 b0e1 +10264..10297 b0e6 +10298 b10a +10299..10301 b10d +10302 b111 +10303..10306 b114 +10307 b11a +10308..10312 b11e +10313..10314 b126 +10315..10317 b129 +10318..10324 b12d +10325 b136 +10326..10331 b13a +10332..10333 b142 +10334..10336 b145 +10337..10343 b149 +10344..10345 b152 +10346..10347 b156 +10348..10350 b159 +10351..10353 b15d +10354..10376 b161 +10377..10378 b17a +10379..10381 b17d +10382 b181 +10383..10387 b183 +10388 b18a +10389 b18c +10390..10393 b18e +10394..10396 b195 +10397..10399 b199 +10400..10410 b19d +10411..10445 b1a9 +10446..10448 b1cd +10449..10451 b1d1 +10452..10458 b1d5 +10459 b1de +10460..10467 b1e0 +10468..10469 b1ea +10470..10472 b1ed +10473..10480 b1f1 +10481 b1fa +10482 b1fc +10483..10488 b1fe +10489..10490 b206 +10491..10492 b209 +10493..10499 b20d +10500 b216 +10501 b218 +10502..10507 b21a +10508..10526 b221 +10527..10533 b235 +10534..10560 b23d +10561..10563 b259 +10564..10566 b25d +10567..10573 b261 +10574..10583 b26a +10584..10589 b276 +10590..10596 b27d +10597..10599 b286 +10600..10605 b28a +10606..10607 b292 +10608..10610 b295 +10611..10615 b29b +10616 b2a2 +10617 b2a4 +10618..10620 b2a7 +10621 b2ab +10622..10624 b2ad +10625..10627 b2b1 +10628..10646 b2b5 +10647..10648 b2ca +10649..10651 b2cd +10652 b2d1 +10653..10657 b2d3 +10658 b2da +10659 b2dc +10660..10663 b2de +10664 b2e3 +10665 b2e7 +10666..10667 b2e9 +10668..10670 b2f0 +10671 b2f6 +10672..10674 b2fc +10675..10676 b302 +10677..10679 b305 +10680..10686 b309 +10687 b312 +10688..10693 b316 +10694..10748 b31d +10749 b357 +10750..10751 b359 +10752 b35d +10753..10756 b360 +10757 b366 +10758 b368 +10759 b36a +10760..10761 b36c +10762 b36f +10763..10764 b372 +10765..10767 b375 +10768..10774 b379 +10775 b382 +10776..10781 b386 +10782..10784 b38d +10785..10787 b391 +10788..10798 b395 +10799..10804 b3a2 +10805..10807 b3a9 +10808..10830 b3ad +10831..10832 b3c6 +10833..10834 b3c9 +10835 b3cd +10836 b3cf +10837..10839 b3d1 +10840 b3d6 +10841 b3d8 +10842 b3da +10843 b3dc +10844..10845 b3de +10846..10848 b3e1 +10849..10851 b3e5 +10852..10870 b3e9 +10871..10889 b3fd +10890..10896 b411 +10897..10899 b419 +10900..10902 b41d +10903..10909 b421 +10910 b42a +10911..10918 b42c +10919..10945 b435 +10946..10947 b452 +10948..10950 b455 +10951..10957 b459 +10958 b462 +10959 b464 +10960..10965 b466 +10966..10984 b46d +10985..10991 b481 +10992..11011 b489 +11012..11017 b49e +11018..11020 b4a5 +11021..11023 b4a9 +11024..11031 b4ad +11032 b4b6 +11033 b4b8 +11034..11039 b4ba +11040..11042 b4c1 +11043..11045 b4c5 +11046..11052 b4c9 +11053..11056 b4d1 +11057..11062 b4d6 +11063..11064 b4de +11065..11066 b4e1 +11067 b4e5 +11068..11072 b4e7 +11073 b4ee +11074 b4f0 +11075..11080 b4f2 +11081..11107 b4f9 +11108..11109 b516 +11110..11111 b519 +11112..11118 b51d +11119 b526 +11120..11124 b52b +11125..11126 b532 +11127..11129 b535 +11130..11136 b539 +11137 b542 +11138..11142 b546 +11143..11144 b54e +11145..11147 b551 +11148..11154 b555 +11155 b55e +11156..11217 b562 +11218..11219 b5a2 +11220..11222 b5a5 +11223 b5a9 +11224..11227 b5ac +11228 b5b2 +11229..11233 b5b6 +11234..11235 b5be +11236..11238 b5c1 +11239..11245 b5c5 +11246 b5ce +11247..11252 b5d2 +11253..11271 b5d9 +11272..11306 b5ed +11307..11308 b612 +11309..11311 b615 +11312..11323 b619 +11324..11329 b626 +11330..11336 b62d +11337..11355 b635 +11356..11382 b649 +11383..11385 b665 +11386..11436 b669 +11437..11438 b69e +11439..11441 b6a1 +11442..11447 b6a5 +11448..11451 b6ad +11452..11485 b6b2 +11486..11512 b6d5 +11513..11515 b6f1 +11516..11518 b6f5 +11519..11525 b6f9 +11526..11528 b702 +11529..11562 b706 +11563..11564 b72a +11565..11566 b72d +11567..11573 b731 +11574 b73a +11575..11582 b73c +11583..11585 b745 +11586..11588 b749 +11589..11595 b74d +11596..11605 b756 +11606..11608 b761 +11609..11611 b765 +11612..11618 b769 +11619 b772 +11620 b774 +11621..11626 b776 +11627..11628 b77e +11629..11631 b781 +11632..11638 b785 +11639 b78e +11640..11642 b793 +11643..11644 b79a +11645..11647 b79d +11648..11654 b7a1 +11655 b7aa +11656..11661 b7ae +11662..11663 b7b6 +11664..11677 b7b9 +11678 b7c8 +11679..11712 b7ca +11713..11714 b7ee +11715..11717 b7f1 +11718..11724 b7f5 +11725 b7fe +11726..11730 b802 +11731..11732 b80a +11733..11735 b80d +11736..11742 b811 +11743 b81a +11744 b81c +11745..11750 b81e +11751..11752 b826 +11753..11755 b829 +11756..11762 b82d +11763 b836 +11764..11769 b83a +11770..11772 b841 +11773..11784 b845 +11785 b852 +11786..11793 b854 +11794..11795 b85e +11796..11798 b861 +11799..11805 b865 +11806 b86e +11807 b870 +11808..11813 b872 +11814..11816 b879 +11817..11832 b87d +11833..11858 b88e +11859..11865 b8a9 +11866..11868 b8b1 +11869..11871 b8b5 +11872..11878 b8b9 +11879 b8c2 +11880 b8c4 +11881..11886 b8c6 +11887..11889 b8cd +11890..11892 b8d1 +11893..11900 b8d5 +11901 b8de +11902 b8e0 +11903..11908 b8e2 +11909..11910 b8ea +11911..11913 b8ed +11914..11920 b8f1 +11921 b8fa +11922 b8fc +11923..11928 b8fe +11929..11947 b905 +11948..11954 b919 +11955..11981 b921 +11982..11983 b93e +11984..11986 b941 +11987..11993 b945 +11994..11995 b94d +11996 b950 +11997..12002 b952 +12003..12004 b95a +12005..12007 b95d +12008..12014 b961 +12015 b96a +12016 b96c +12017..12022 b96e +12023..12024 b976 +12025..12027 b979 +12028..12034 b97d +12035 b986 +12036 b988 +12037..12038 b98b +12039..12067 b98f +12068..12069 b9ae +12070..12072 b9b1 +12073..12079 b9b5 +12080 b9be +12081 b9c0 +12082..12087 b9c2 +12088..12089 b9ca +12090 b9cd +12091..12095 b9d3 +12096 b9da +12097 b9dc +12098..12099 b9df +12100 b9e2 +12101..12102 b9e6 +12103..12105 b9e9 +12106..12112 b9ed +12113 b9f6 +12114..12118 b9fb +12119..12124 ba02 +12125..12136 ba09 +12137..12170 ba16 +12171..12172 ba3a +12173..12175 ba3d +12176 ba41 +12177..12181 ba43 +12182 ba4a +12183 ba4c +12184..12187 ba4f +12188..12189 ba56 +12190..12192 ba59 +12193..12199 ba5d +12200 ba66 +12201..12206 ba6a +12207..12208 ba72 +12209..12211 ba75 +12212..12221 ba79 +12222 ba86 +12223..12226 ba88 +12227..12253 ba8d +12254 baaa +12255..12257 baad +12258 bab1 +12259..12263 bab3 +12264 baba +12265 babc +12266..12271 babe +12272..12274 bac5 +12275..12289 bac9 +12290..12323 bada +12324..12326 bafd +12327..12329 bb01 +12330..12337 bb05 +12338 bb0e +12339 bb10 +12340..12345 bb12 +12346..12348 bb19 +12349..12351 bb1d +12352..12359 bb21 +12360 bb2a +12361..12368 bb2c +12369 bb37 +12370..12371 bb39 +12372..12376 bb3f +12377 bb46 +12378 bb48 +12379..12381 bb4a +12382 bb4e +12383..12385 bb51 +12386..12388 bb55 +12389..12396 bb59 +12397 bb62 +12398..12405 bb64 +12406..12432 bb6d +12433..12435 bb89 +12436..12438 bb8d +12439..12457 bb91 +12458..12460 bba5 +12461..12463 bba9 +12464..12470 bbad +12471..12472 bbb5 +12473..12480 bbb8 +12481..12483 bbc1 +12484..12486 bbc5 +12487..12493 bbc9 +12494..12495 bbd1 +12496..12531 bbd4 +12532..12533 bbfa +12534..12535 bbfd +12536 bc01 +12537..12541 bc03 +12542 bc0a +12543 bc0e +12544 bc10 +12545..12546 bc12 +12547..12548 bc19 +12549..12552 bc20 +12553 bc26 +12554 bc28 +12555..12557 bc2a +12558..12559 bc2e +12560..12561 bc32 +12562..12564 bc35 +12565..12571 bc39 +12572 bc42 +12573..12575 bc46 +12576..12577 bc4a +12578..12579 bc4e +12580..12591 bc51 +12592..12629 bc5e +12630..12631 bc86 +12632..12633 bc89 +12634 bc8d +12635..12639 bc8f +12640 bc96 +12641 bc98 +12642..12646 bc9b +12647..12648 bca2 +12649..12650 bca5 +12651..12657 bca9 +12658 bcb2 +12659..12664 bcb6 +12665..12666 bcbe +12667..12669 bcc1 +12670..12677 bcc5 +12678 bcce +12679..12681 bcd2 +12682..12683 bcd6 +12684..12686 bcd9 +12687..12709 bcdd +12710 bcf7 +12711..12713 bcf9 +12714..12720 bcfd +12721 bd06 +12722 bd08 +12723..12728 bd0a +12729..12731 bd11 +12732..12746 bd15 +12747..12753 bd25 +12754..12772 bd2d +12773..12779 bd41 +12780..12781 bd4a +12782..12784 bd4d +12785..12791 bd51 +12792..12801 bd5a +12802..12804 bd65 +12805..12827 bd69 +12828..12829 bd82 +12830..12831 bd85 +12832..12836 bd8b +12837 bd92 +12838 bd94 +12839..12841 bd96 +12842 bd9b +12843..12849 bd9d +12850..12860 bda5 +12861..12867 bdb1 +12868..12894 bdb9 +12895..12896 bdd6 +12897..12899 bdd9 +12900..12911 bddd +12912..12917 bdea +12918..12920 bdf1 +12921..12923 bdf5 +12924..12930 bdf9 +12931..12932 be01 +12933 be04 +12934..12939 be06 +12940..12941 be0e +12942..12944 be11 +12945..12951 be15 +12952 be1e +12953..12988 be20 +12989..12990 be46 +12991..12993 be49 +12994 be4d +12995..12999 be4f +13000 be56 +13001 be58 +13002..13005 be5c +13006..13007 be62 +13008..13010 be65 +13011 be69 +13012..13016 be6b +13017 be72 +13018..13022 be76 +13023..13024 be7e +13025..13027 be81 +13028..13034 be85 +13035 be8e +13036..13041 be92 +13042..13055 be9a +13056..13094 bea9 +13095..13096 bed2 +13097..13098 bed5 +13099..13105 bed9 +13106..13107 bee1 +13108..13113 bee6 +13114..13133 beed +13134..13139 bf02 +13140..13153 bf0a +13154 bf1a +13155..13188 bf1e +13189..13190 bf42 +13191..13193 bf45 +13194..13200 bf49 +13201..13203 bf52 +13204..13265 bf56 +13266..13292 bf95 +13293..13312 bfb1 +13313..13318 bfc6 +13319..13320 bfce +13321..13323 bfd1 +13324..13330 bfd5 +13331..13332 bfdd +13333 bfe0 +13334..13423 bfe2 +13424..13443 c03d +13444..13449 c052 +13450..13452 c059 +13453..13455 c05d +13456..13462 c061 +13463..13500 c06a +13501..13502 c092 +13503..13505 c095 +13506..13512 c099 +13513 c0a2 +13514 c0a4 +13515..13520 c0a6 +13521 c0ae +13522..13523 c0b1 +13524..13528 c0b7 +13529 c0be +13530..13532 c0c2 +13533..13534 c0c6 +13535..13536 c0ca +13537..13539 c0cd +13540..13546 c0d1 +13547 c0da +13548..13553 c0de +13554..13555 c0e6 +13556..13558 c0e9 +13559..13565 c0ed +13566 c0f6 +13567 c0f8 +13568..13573 c0fa +13574..13576 c101 +13577..13579 c105 +13580..13586 c109 +13587..13590 c111 +13591..13596 c116 +13597..13598 c121 +13599 c125 +13600..13603 c128 +13604 c12e +13605..13608 c132 +13609 c137 +13610..13611 c13a +13612..13614 c13d +13615..13621 c141 +13622 c14a +13623..13628 c14e +13629..13630 c156 +13631..13633 c159 +13634..13640 c15d +13641 c166 +13642..13647 c16a +13648..13650 c171 +13651..13653 c175 +13654..13665 c179 +13666..13671 c186 +13672 c18f +13673..13675 c191 +13676 c195 +13677..13681 c197 +13682 c19e +13683 c1a0 +13684..13686 c1a2 +13687..13688 c1a6 +13689..13690 c1aa +13691..13693 c1ad +13694..13705 c1b1 +13706..13711 c1be +13712..13714 c1c5 +13715..13717 c1c9 +13718..13724 c1cd +13725..13726 c1d5 +13727..13733 c1d9 +13734..13736 c1e1 +13737..13739 c1e5 +13740..13746 c1e9 +13747 c1f2 +13748..13755 c1f4 +13756..13757 c1fe +13758..13760 c201 +13761..13767 c205 +13768 c20e +13769 c210 +13770..13775 c212 +13776..13777 c21a +13778..13779 c21d +13780..13786 c221 +13787 c22a +13788 c22c +13789 c22e +13790 c230 +13791 c233 +13792..13810 c235 +13811..13817 c249 +13818..13819 c252 +13820..13822 c255 +13823..13829 c259 +13830..13833 c261 +13834..13839 c266 +13840..13841 c26e +13842..13844 c271 +13845..13851 c275 +13852 c27e +13853 c280 +13854..13859 c282 +13860..13865 c28a +13866..13872 c291 +13873..13874 c299 +13875 c29c +13876..13881 c29e +13882..13883 c2a6 +13884..13886 c2a9 +13887..13892 c2ae +13893 c2b6 +13894 c2b8 +13895..13928 c2ba +13929..13930 c2de +13931..13932 c2e1 +13933..13938 c2e5 +13939 c2ee +13940 c2f0 +13941..13944 c2f2 +13945 c2f7 +13946 c2fa +13947..13949 c2fd +13950..13956 c301 +13957..13958 c30a +13959..13963 c30e +13964..13965 c316 +13966..13968 c319 +13969..13975 c31d +13976..13977 c326 +13978..14004 c32a +14005..14038 c346 +14039..14040 c36a +14041..14043 c36d +14044 c371 +14045..14049 c373 +14050..14051 c37a +14052..14057 c37e +14058..14060 c385 +14061..14063 c389 +14064..14114 c38d +14115..14137 c3c1 +14138..14139 c3da +14140..14141 c3dd +14142 c3e1 +14143..14147 c3e3 +14148..14150 c3ea +14151..14156 c3ee +14157..14158 c3f6 +14159..14173 c3f9 +14174..14180 c409 +14181..14199 c411 +14200..14206 c425 +14207..14209 c42d +14210..14212 c431 +14213..14219 c435 +14220..14229 c43e +14230..14256 c449 +14257..14258 c466 +14259..14261 c469 +14262..14268 c46d +14269..14271 c476 +14272..14277 c47a +14278..14296 c481 +14297..14303 c495 +14304..14330 c49d +14331..14333 c4b9 +14334..14377 c4bd +14378..14383 c4ea +14384..14385 c4f2 +14386..14388 c4f5 +14389 c4f9 +14390..14393 c4fb +14394..14403 c502 +14404..14406 c50d +14407..14409 c511 +14410..14416 c515 +14417..14427 c51d +14428..14429 c52a +14430..14432 c52d +14433..14439 c531 +14440 c53a +14441 c53c +14442..14447 c53e +14448..14449 c546 +14450 c54b +14451..14454 c54f +14455 c556 +14456..14458 c55a +14459 c55f +14460..14461 c562 +14462..14464 c565 +14465..14471 c569 +14472 c572 +14473..14478 c576 +14479..14480 c57e +14481..14483 c581 +14484..14485 c585 +14486..14489 c588 +14490 c58e +14491 c590 +14492..14494 c592 +14495 c596 +14496..14498 c599 +14499..14501 c59d +14502..14509 c5a1 +14510..14519 c5aa +14520..14521 c5b6 +14522 c5ba +14523..14527 c5bf +14528 c5cb +14529 c5cd +14530 c5cf +14531..14532 c5d2 +14533..14535 c5d5 +14536..14542 c5d9 +14543 c5e2 +14544 c5e4 +14545..14550 c5e6 +14551 c5ef +14552..14554 c5f1 +14555 c5f5 +14556..14559 c5f8 +14560..14562 c602 +14563..14565 c609 +14566..14568 c60d +14569..14575 c611 +14576 c61a +14577..14583 c61d +14584..14585 c626 +14586..14588 c629 +14589 c62f +14590..14591 c631 +14592 c636 +14593 c638 +14594 c63a +14595..14598 c63c +14599..14600 c642 +14601..14603 c645 +14604..14610 c649 +14611 c652 +14612..14617 c656 +14618..14619 c65e +14620..14630 c661 +14631..14632 c66d +14633 c670 +14634..14639 c672 +14640..14641 c67a +14642..14644 c67d +14645..14651 c681 +14652 c68a +14653 c68c +14654..14659 c68e +14660..14661 c696 +14662..14664 c699 +14665..14671 c69d +14672 c6a6 +14673 c6a8 +14674..14679 c6aa +14680..14681 c6b2 +14682..14684 c6b5 +14685..14689 c6bb +14690 c6c2 +14691 c6c4 +14692..14697 c6c6 +14698..14699 c6ce +14700..14702 c6d1 +14703..14709 c6d5 +14710..14711 c6de +14712..14717 c6e2 +14718..14719 c6ea +14720..14722 c6ed +14723..14729 c6f1 +14730..14732 c6fa +14733..14738 c6fe +14739..14740 c706 +14741..14743 c709 +14744..14750 c70d +14751 c716 +14752 c718 +14753..14758 c71a +14759..14760 c722 +14761..14763 c725 +14764..14770 c729 +14771 c732 +14772 c734 +14773 c736 +14774..14777 c738 +14778..14779 c73e +14780..14782 c741 +14783..14787 c745 +14788 c74b +14789 c74e +14790 c750 +14791..14793 c759 +14794..14796 c75d +14797..14803 c761 +14804..14805 c769 +14806..14813 c76c +14814..14815 c776 +14816..14818 c779 +14819..14822 c77f +14823 c786 +14824..14826 c78b +14827 c78f +14828..14829 c792 +14830 c795 +14831 c799 +14832..14836 c79b +14837 c7a2 +14838..14842 c7a7 +14843..14844 c7ae +14845..14847 c7b1 +14848..14854 c7b5 +14855 c7be +14856..14861 c7c2 +14862..14863 c7ca +14864 c7cd +14865 c7cf +14866..14872 c7d1 +14873..14876 c7d9 +14877..14882 c7de +14883..14885 c7e5 +14886..14888 c7e9 +14889..14907 c7ed +14908..14909 c802 +14910..14912 c805 +14913 c809 +14914..14918 c80b +14919 c812 +14920 c814 +14921..14925 c817 +14926..14927 c81e +14928..14930 c821 +14931..14937 c825 +14938 c82e +14939 c830 +14940..14945 c832 +14946..14948 c839 +14949..14951 c83d +14952..14958 c841 +14959..14960 c84a +14961..14966 c84e +14967..14993 c855 +14994..14995 c872 +14996..14998 c875 +14999 c879 +15000..15004 c87b +15005 c882 +15006 c884 +15007..15009 c888 +15010..15015 c88e +15016..15023 c895 +15024 c89e +15025 c8a0 +15026..15031 c8a2 +15032..15050 c8a9 +15051..15056 c8be +15057..15059 c8c5 +15060..15062 c8c9 +15063..15069 c8cd +15070 c8d6 +15071 c8d8 +15072..15077 c8da +15078..15079 c8e2 +15080..15095 c8e5 +15096..15101 c8f6 +15102..15103 c8fe +15104..15106 c901 +15107..15111 c907 +15112 c90e +15113 c910 +15114..15119 c912 +15120..15138 c919 +15139..15145 c92d +15146..15172 c935 +15173..15174 c952 +15175..15177 c955 +15178..15184 c959 +15185 c962 +15186..15193 c964 +15194..15196 c96d +15197..15199 c971 +15200..15206 c975 +15207..15217 c97d +15218..15219 c98a +15220..15222 c98d +15223..15229 c991 +15230 c99a +15231 c99c +15232..15265 c99e +15266..15267 c9c2 +15268..15269 c9c5 +15270 c9c9 +15271..15275 c9cb +15276 c9d2 +15277 c9d4 +15278..15279 c9d7 +15280 c9db +15281..15282 c9de +15283 c9e1 +15284 c9e3 +15285..15286 c9e5 +15287..15290 c9e8 +15291 c9ee +15292..15297 c9f2 +15298..15299 c9fa +15300..15302 c9fd +15303..15309 ca01 +15310 ca0a +15311..15316 ca0e +15317..15319 ca15 +15320..15335 ca19 +15336..15369 ca2a +15370..15371 ca4e +15372..15374 ca51 +15375..15381 ca55 +15382 ca5e +15383..15388 ca62 +15389..15408 ca69 +15409..15414 ca7e +15415..15433 ca85 +15434..15468 ca99 +15469..15470 cabe +15471..15473 cac1 +15474..15480 cac5 +15481 cace +15482 cad0 +15483 cad2 +15484..15487 cad4 +15488..15493 cada +15494..15504 cae1 +15505..15511 caed +15512..15530 caf5 +15531..15537 cb09 +15538..15540 cb11 +15541..15543 cb15 +15544..15550 cb19 +15551..15581 cb22 +15582..15587 cb42 +15588..15589 cb4a +15590..15592 cb4d +15593..15599 cb51 +15600..15602 cb5a +15603..15608 cb5e +15609..15627 cb65 +15628..15661 cb7a +15662..15688 cb9d +15689..15715 cbb9 +15716..15730 cbd5 +15731..15732 cbe5 +15733 cbe8 +15734..15767 cbea +15768..15769 cc0e +15770..15772 cc11 +15773..15779 cc15 +15780..15782 cc1e +15783..15786 cc23 +15787..15788 cc2a +15789 cc2d +15790 cc2f +15791..15797 cc31 +15798 cc3a +15799..15803 cc3f +15804..15805 cc46 +15806..15808 cc49 +15809..15815 cc4d +15816 cc56 +15817..15822 cc5a +15823..15825 cc61 +15826 cc65 +15827 cc67 +15828..15834 cc69 +15835..15838 cc71 +15839..15872 cc76 +15873..15874 cc9a +15875..15877 cc9d +15878..15884 cca1 +15885 ccaa +15886..15891 ccae +15892..15893 ccb6 +15894..15896 ccb9 +15897..15903 ccbd +15904 ccc6 +15905 ccc8 +15906..15911 ccca +15912..15914 ccd1 +15915..15929 ccd5 +15930..15936 cce5 +15937..15939 cced +15940..15955 ccf1 +15956..15961 cd02 +15962..15963 cd0a +15964..15966 cd0d +15967..15973 cd11 +15974 cd1a +15975 cd1c +15976..15981 cd1e +15982..15984 cd25 +15985..15987 cd29 +15988..15999 cd2d +16000..16033 cd3a +16034..16036 cd5d +16037..16039 cd61 +16040..16046 cd65 +16047 cd6e +16048 cd70 +16049..16054 cd72 +16055..16069 cd79 +16070..16080 cd89 +16081..16082 cd96 +16083..16085 cd99 +16086..16092 cd9d +16093 cda6 +16094 cda8 +16095..16100 cdaa +16101..16119 cdb1 +16120..16126 cdc5 +16127..16129 cdcd +16130..16152 cdd1 +16153..16155 cde9 +16156..16158 cded +16159..16165 cdf1 +16166 cdfa +16167 cdfc +16168..16173 cdfe +16174..16176 ce05 +16177..16179 ce09 +16180..16186 ce0d +16187..16190 ce15 +16191..16196 ce1a +16197..16198 ce22 +16199..16201 ce25 +16202..16208 ce29 +16209 ce32 +16210 ce34 +16211..16244 ce36 +16245..16246 ce5a +16247..16248 ce5d +16249..16254 ce62 +16255 ce6a +16256 ce6c +16257..16262 ce6e +16263..16264 ce76 +16265..16267 ce79 +16268..16274 ce7d +16275 ce86 +16276 ce88 +16277..16282 ce8a +16283..16284 ce92 +16285..16287 ce95 +16288..16294 ce99 +16295 cea2 +16296..16301 cea6 +16302..16320 ceae +16321..16354 cec2 +16355..16356 cee6 +16357..16358 cee9 +16359..16365 ceed +16366 cef6 +16367..16372 cefa +16373..16374 cf02 +16375..16377 cf05 +16378..16384 cf09 +16385 cf12 +16386 cf14 +16387..16392 cf16 +16393..16395 cf1d +16396..16398 cf21 +16399..16405 cf25 +16406 cf2e +16407..16412 cf32 +16413..16439 cf39 +16440..16441 cf56 +16442..16444 cf59 +16445..16451 cf5d +16452 cf66 +16453 cf68 +16454..16459 cf6a +16460..16461 cf72 +16462..16464 cf75 +16465..16471 cf79 +16472..16475 cf81 +16476..16481 cf86 +16482..16501 cf8d +16502..16507 cfa2 +16508..16514 cfa9 +16515..16533 cfb1 +16534..16560 cfc5 +16561..16562 cfe2 +16563..16565 cfe5 +16566..16572 cfe9 +16573 cff2 +16574 cff4 +16575..16580 cff6 +16581..16583 cffd +16584..16586 d001 +16587..16598 d005 +16599..16604 d012 +16605..16624 d019 +16625..16630 d02e +16631..16632 d036 +16633..16635 d039 +16636..16642 d03d +16643 d046 +16644 d048 +16645..16650 d04a +16651..16653 d051 +16654..16656 d055 +16657..16663 d059 +16664..16674 d061 +16675..16676 d06e +16677..16679 d071 +16680..16686 d075 +16687..16689 d07e +16690..16723 d082 +16724..16725 d0a6 +16726..16728 d0a9 +16729..16735 d0ad +16736 d0b6 +16737 d0b8 +16738..16743 d0ba +16744..16745 d0c2 +16746..16748 d0c5 +16749..16754 d0ca +16755 d0d2 +16756..16761 d0d6 +16762..16763 d0de +16764..16766 d0e1 +16767..16773 d0e5 +16774 d0ee +16775..16780 d0f2 +16781..16800 d0f9 +16801..16834 d10e +16835..16836 d132 +16837..16839 d135 +16840 d139 +16841..16845 d13b +16846 d142 +16847..16852 d146 +16853..16854 d14e +16855..16857 d151 +16858..16864 d155 +16865 d15e +16866 d160 +16867..16872 d162 +16873..16875 d169 +16876..16890 d16d +16891..16897 d17d +16898..16900 d185 +16901..16923 d189 +16924..16925 d1a2 +16926..16928 d1a5 +16929..16935 d1a9 +16936 d1b2 +16937 d1b4 +16938..16941 d1b6 +16942 d1bb +16943..16945 d1bd +16946..16968 d1c1 +16969..16995 d1d9 +16996..16998 d1f5 +16999..17012 d1f9 +17013 d208 +17014..17019 d20a +17020..17046 d211 +17047..17048 d22e +17049..17051 d231 +17052..17058 d235 +17059 d23e +17060 d240 +17061..17066 d242 +17067..17085 d249 +17086..17092 d25d +17093..17119 d265 +17120..17121 d282 +17122..17124 d285 +17125..17131 d289 +17132..17134 d292 +17135..17140 d296 +17141..17143 d29d +17144..17146 d2a1 +17147..17153 d2a5 +17154..17157 d2ad +17158..17163 d2b2 +17164..17165 d2ba +17166..17167 d2bd +17168 d2c1 +17169..17173 d2c3 +17174 d2ca +17175..17182 d2cc +17183..17185 d2d5 +17186..17188 d2d9 +17189..17195 d2dd +17196..17205 d2e6 +17206..17207 d2f2 +17208..17210 d2f5 +17211..17217 d2f9 +17218 d302 +17219 d304 +17220..17225 d306 +17226 d30f +17227..17229 d311 +17230 d315 +17231..17235 d317 +17236 d31e +17237..17239 d322 +17240..17241 d326 +17242..17243 d32a +17244..17246 d32d +17247..17253 d331 +17254 d33a +17255..17260 d33e +17261..17314 d346 +17315..17316 d37e +17317..17319 d381 +17320..17326 d385 +17327 d38e +17328..17333 d392 +17334..17335 d39a +17336..17338 d39d +17339..17345 d3a1 +17346 d3aa +17347 d3ac +17348..17353 d3ae +17354..17356 d3b5 +17357..17359 d3b9 +17360..17366 d3bd +17367..17368 d3c6 +17369..17374 d3ca +17375..17381 d3d1 +17382..17389 d3d9 +17390 d3e2 +17391..17398 d3e4 +17399..17400 d3ee +17401..17403 d3f1 +17404..17410 d3f5 +17411 d3fe +17412 d400 +17413..17418 d402 +17419..17438 d409 +17439..17472 d41e +17473..17475 d441 +17476..17498 d445 +17499..17501 d45d +17502..17504 d461 +17505..17512 d465 +17513 d46e +17514..17521 d470 +17522..17523 d47a +17524..17525 d47d +17526 d481 +17527..17531 d483 +17532 d48a +17533 d48c +17534..17539 d48e +17540..17559 d495 +17560..17593 d4aa +17594..17596 d4cd +17597..17599 d4d1 +17600..17606 d4d5 +17607..17608 d4dd +17609..17616 d4e0 +17617..17619 d4e9 +17620..17622 d4ed +17623..17629 d4f1 +17630..17631 d4f9 +17632 d4fc +17633..17638 d4fe +17639..17641 d505 +17642..17644 d509 +17645..17651 d50d +17652 d516 +17653..17688 d518 +17689..17690 d53e +17691..17693 d541 +17694..17700 d545 +17701 d54e +17702 d550 +17703..17708 d552 +17709..17710 d55a +17711..17713 d55d +17714..17717 d561 +17718..17719 d566 +17720 d56a +17721 d56c +17722..17727 d56e +17728..17729 d576 +17730..17732 d579 +17733..17739 d57d +17740 d586 +17741..17746 d58a +17747..17766 d591 +17767..17800 d5a6 +17801..17802 d5ca +17803..17805 d5cd +17806 d5d1 +17807..17811 d5d3 +17812 d5da +17813 d5dc +17814..17819 d5de +17820..17821 d5e6 +17822..17824 d5e9 +17825..17831 d5ed +17832 d5f6 +17833 d5f8 +17834..17839 d5fa +17840..17841 d602 +17842..17844 d605 +17845..17851 d609 +17852 d612 +17853..17858 d616 +17859..17861 d61d +17862..17864 d621 +17865..17872 d625 +17873..17882 d62e +17883..17884 d63a +17885..17887 d63d +17888..17891 d641 +17892..17893 d646 +17894 d64a +17895 d64c +17896..17898 d64e +17899..17900 d652 +17901..17902 d656 +17903..17905 d659 +17906..17915 d65d +17916 d668 +17917..17922 d66a +17923..17924 d672 +17925..17938 d675 +17939 d684 +17940..17945 d686 +17946..17947 d68e +17948..17950 d691 +17951..17958 d695 +17959 d69e +17960 d6a0 +17961..17966 d6a2 +17967..17969 d6a9 +17970..17972 d6ad +17973..17980 d6b1 +17981 d6ba +17982..17989 d6bc +17990..17991 d6c6 +17992..17994 d6c9 +17995..17998 d6cd +17999..18000 d6d2 +18001..18002 d6d5 +18003 d6d8 +18004..18009 d6da +18010..18012 d6e1 +18013..18015 d6e5 +18016..18022 d6e9 +18023..18026 d6f1 +18027..18032 d6f6 +18033..18034 d6fe +18035..18037 d701 +18038..18049 d705 +18050..18055 d712 +18056..18057 d71a +18058..18060 d71d +18061..18067 d721 +18068 d72a +18069 d72c +18070..18075 d72e +18076..18077 d736 +18078..18080 d739 +18081..18087 d73d +18088..18089 d745 +18090 d748 +18091..18096 d74a +18097..18098 d752 +18099 d755 +18100..18105 d75a +18106 d762 +18107 d764 +18108..18110 d766 +18111..18112 d76a +18113..18115 d76d +18116..18118 d771 +18119..18125 d775 +18126..18128 d77e +18129..18134 d782 +18135..18136 d78a +18137..18139 d78d +18140..18146 d791 +18147 d79a +18148 d79c +18149..18154 d79e +18155 /Korea1.1.vert +18156 /Korea1.2.vert +18157 /Korea1.3.vert +18158 /Korea1.4.vert +18159 /Korea1.5.vert +18160 /Korea1.6.vert +18161 /Korea1.7.vert +18162 /Korea1.8.vert +18163 /Korea1.9.vert +18164 /Korea1.10.vert +18165 /Korea1.11.vert +18166 /Korea1.12.vert +18167 /Korea1.13.vert +18168 /Korea1.14.vert +18169 /Korea1.15.vert +18170 /Korea1.16.vert +18171 /Korea1.17.vert +18172 /Korea1.18.vert +18173 /Korea1.19.vert +18174 /Korea1.20.vert +18175 /Korea1.21.vert +18176 /Korea1.22.vert +18177 /Korea1.23.vert +18178 /Korea1.24.vert +18179 /Korea1.25.vert +18180 /Korea1.26.vert +18181 /Korea1.27.vert +18182 /Korea1.28.vert +18183 /Korea1.29.vert +18184 /Korea1.30.vert +18185 /Korea1.31.vert +18186 /Korea1.32.vert +18187 /Korea1.33.vert +18188 /Korea1.34.vert +18189 /Korea1.35.vert +18190 /Korea1.36.vert +18191 /Korea1.37.vert +18192 /Korea1.38.vert +18193 /Korea1.39.vert +18194 /Korea1.40.vert +18195 /Korea1.41.vert +18196 /Korea1.42.vert +18197 /Korea1.43.vert +18198 /Korea1.44.vert +18199 /Korea1.45.vert +18200 /Korea1.46.vert +18201 /Korea1.47.vert +18202 /Korea1.48.vert +18203 /Korea1.49.vert +18204 /Korea1.50.vert +18205 /Korea1.51.vert +18206 /Korea1.52.vert +18207 /Korea1.53.vert +18208 /Korea1.54.vert +18209 /Korea1.55.vert +18210 /Korea1.56.vert +18211 /Korea1.57.vert +18212 /Korea1.58.vert +18213 /Korea1.59.vert +18214 /Korea1.60.vert +18215 /Korea1.61.vert +18216 /Korea1.62.vert +18217 /Korea1.63.vert +18218 /Korea1.64.vert +18219 /Korea1.65.vert +18220 /Korea1.66.vert +18221 /Korea1.67.vert +18222 /Korea1.68.vert +18223 /Korea1.69.vert +18224 /Korea1.70.vert +18225 /Korea1.71.vert +18226 /Korea1.72.vert +18227 /Korea1.73.vert +18228 /Korea1.74.vert +18229 /Korea1.75.vert +18230 /Korea1.76.vert +18231 /Korea1.77.vert +18232 /Korea1.78.vert +18233 /Korea1.79.vert +18234 /Korea1.80.vert +18235 /Korea1.81.vert +18236 /Korea1.82.vert +18237 /Korea1.83.vert +18238 /Korea1.84.vert +18239 /Korea1.85.vert +18240 /Korea1.86.vert +18241 /Korea1.87.vert +18242 /Korea1.88.vert +18243 /Korea1.89.vert +18244 /Korea1.90.vert +18245 /Korea1.91.vert +18246 /Korea1.92.vert +18247 /Korea1.93.vert +18248 /Korea1.94.vert +18249 /Korea1.95.vert +18250 /Korea1.96.vert +18251 /Korea1.97.vert +18252 /Korea1.98.vert +18253 /Korea1.99.vert +18254 /Korea1.100.vert +18255 /Korea1.8094.vert +18256 /Korea1.8095.vert +18257 /Korea1.8096.vert +18258 /Korea1.8097.vert +18259 /Korea1.8098.vert +18260 /Korea1.8099.vert +18261 /Korea1.8100.vert +18262 /Korea1.8101.vert +18263 /Korea1.8102.vert +18264 /Korea1.8103.vert +18265 /Korea1.8104.vert +18266 /Korea1.8105.vert +18267 /Korea1.8106.vert +18268 /Korea1.8107.vert +18269 /Korea1.8108.vert +18270 /Korea1.8109.vert +18271 /Korea1.8110.vert +18272 /Korea1.8111.vert +18273 /Korea1.8112.vert +18274 /Korea1.8113.vert +18275 /Korea1.8114.vert +18276 /Korea1.8115.vert +18277 /Korea1.8116.vert +18278 /Korea1.8117.vert +18279 /Korea1.8118.vert +18280 /Korea1.8119.vert +18281 /Korea1.8120.vert +18282 /Korea1.8121.vert +18283 /Korea1.8122.vert +18284 /Korea1.8123.vert +18285 /Korea1.8124.vert +18286 /Korea1.8125.vert +18287 /Korea1.8126.vert +18288 /Korea1.8127.vert +18289 /Korea1.8128.vert +18290 /Korea1.8129.vert +18291 /Korea1.8130.vert +18292 /Korea1.8131.vert +18293 /Korea1.8132.vert +18294 /Korea1.8133.vert +18295 /Korea1.8134.vert +18296 /Korea1.8135.vert +18297 /Korea1.8136.vert +18298 /Korea1.8137.vert +18299 /Korea1.8138.vert +18300 /Korea1.8139.vert +18301 /Korea1.8140.vert +18302 /Korea1.8141.vert +18303 /Korea1.8142.vert +18304 /Korea1.8143.vert +18305 /Korea1.8144.vert +18306 /Korea1.8145.vert +18307 /Korea1.8146.vert +18308 /Korea1.8147.vert +18309 /Korea1.8148.vert +18310 /Korea1.8149.vert +18311 /Korea1.8150.vert +18312 /Korea1.8151.vert +18313 /Korea1.8152.vert +18314 /Korea1.8153.vert +18315 /Korea1.8154.vert +18316 /Korea1.8155.vert +18317 /Korea1.8156.vert +18318 /Korea1.8157.vert +18319 /Korea1.8158.vert +18320 /Korea1.8159.vert +18321 /Korea1.8160.vert +18322 /Korea1.8161.vert +18323 /Korea1.8162.vert +18324 /Korea1.8163.vert +18325 /Korea1.8164.vert +18326 /Korea1.8165.vert +18327 /Korea1.8166.vert +18328 /Korea1.8167.vert +18329 /Korea1.8168.vert +18330 /Korea1.8169.vert +18331 /Korea1.8170.vert +18332 /Korea1.8171.vert +18333 /Korea1.8172.vert +18334 /Korea1.8173.vert +18335 /Korea1.8174.vert +18336 /Korea1.8175.vert +18337 /Korea1.8176.vert +18338 /Korea1.8177.vert +18339 /Korea1.8178.vert +18340 /Korea1.8179.vert +18341 /Korea1.8180.vert +18342 /Korea1.8181.vert +18343 /Korea1.8182.vert +18344 /Korea1.8183.vert +18345 /Korea1.8184.vert +18346 /Korea1.8185.vert +18347 /Korea1.8186.vert +18348 /Korea1.8187.vert +18349 /Korea1.8188.vert +18350 /Korea1.8189.vert +18351 /Korea1.8190.vert diff --git a/fonts/enc/dvips/context/cmin.enc b/fonts/enc/dvips/context/cmin.enc new file mode 100644 index 000000000..dc2b063a6 --- /dev/null +++ b/fonts/enc/dvips/context/cmin.enc @@ -0,0 +1,258 @@ +/enccmin[ +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/space +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/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 +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/dvips/context/cmit.enc b/fonts/enc/dvips/context/cmit.enc new file mode 100644 index 000000000..40fd82f77 --- /dev/null +++ b/fonts/enc/dvips/context/cmit.enc @@ -0,0 +1,258 @@ +/enccmit[ +/Gamma +/Delta +/Theta +/Lambda +/Xi +/Pi +/Sigma +/Upsilon +/Phi +/Psi +/Omega +/ff +/fi +/fl +/ffi +/ffl +/dotlessi +/dotlessj +/grave +/acute +/caron +/breve +/macron +/ring +/cedilla +/germandbls +/ae +/oe +/oslash +/AE +/OE +/Oslash +/suppress +/exclam +/quotedblright +/numbersign +/sterling +/percent +/ampersand +/quoteright +/parenleft +/parenright +/asterisk +/plus +/comma +/hyphen +/period +/slash +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/colon +/semicolon +/exclamdown +/equal +/questiondown +/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 +/quotedblleft +/bracketright +/circumflex +/dotaccent +/quoteleft +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/n +/o +/p +/q +/r +/s +/t +/u +/v +/w +/x +/y +/z +/endash +/emdash +/hungarumlaut +/tilde +/dieresis +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/dvips/context/cmitt.enc b/fonts/enc/dvips/context/cmitt.enc new file mode 100644 index 000000000..971187c32 --- /dev/null +++ b/fonts/enc/dvips/context/cmitt.enc @@ -0,0 +1,258 @@ +/enccmitt[ +/Gamma +/Delta +/Theta +/Lambda +/Xi +/Pi +/Sigma +/Upsilon +/Phi +/Psi +/Omega +/arrowup +/arrowdown +/quotesingle +/exclamdown +/questiondown +/dotlessi +/dotlessj +/grave +/acute +/caron +/breve +/macron +/ring +/cedilla +/germandbls +/ae +/oe +/oslash +/AE +/OE +/Oslash +/visiblespace +/exclam +/quotedbl +/numbersign +/sterling +/percent +/ampersand +/quoteright +/parenleft +/parenright +/asterisk +/plus +/comma +/hyphen +/period +/slash +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/colon +/semicolon +/less +/equal +/greater +/question +/at +/A +/B +/C +/D +/E +/F +/G +/H +/I +/J +/K +/L +/M +/N +/O +/P +/Q +/R +/S +/T +/U +/V +/W +/X +/Y +/Z +/bracketleft +/backslash +/bracketright +/asciicircum +/underscore +/quoteleft +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/n +/o +/p +/q +/r +/s +/t +/u +/v +/w +/x +/y +/z +/braceleft +/bar +/braceright +/asciitilde +/dieresis +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/dvips/context/cmrm.enc b/fonts/enc/dvips/context/cmrm.enc new file mode 100644 index 000000000..3a1ab23dd --- /dev/null +++ b/fonts/enc/dvips/context/cmrm.enc @@ -0,0 +1,258 @@ +/enccmrm[ +/Gamma +/Delta +/Theta +/Lambda +/Xi +/Pi +/Sigma +/Upsilon +/Phi +/Psi +/Omega +/ff +/fi +/fl +/ffi +/ffl +/dotlessi +/dotlessj +/grave +/acute +/caron +/breve +/macron +/ring +/cedilla +/germandbls +/ae +/oe +/oslash +/AE +/OE +/Oslash +/suppress +/exclam +/quotedblright +/numbersign +/dollar +/percent +/ampersand +/quoteright +/parenleft +/parenright +/asterisk +/plus +/comma +/hyphen +/period +/slash +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/colon +/semicolon +/exclamdown +/equal +/questiondown +/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 +/quotedblleft +/bracketright +/circumflex +/dotaccent +/quoteleft +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/n +/o +/p +/q +/r +/s +/t +/u +/v +/w +/x +/y +/z +/endash +/emdash +/hungarumlaut +/tilde +/dieresis +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/dvips/context/cmsc.enc b/fonts/enc/dvips/context/cmsc.enc new file mode 100644 index 000000000..b8ab09121 --- /dev/null +++ b/fonts/enc/dvips/context/cmsc.enc @@ -0,0 +1,258 @@ +/enccmsc[ +/Gamma +/Delta +/Theta +/Lambda +/Xi +/Pi +/Sigma +/Upsilon +/Phi +/Psi +/Omega +/arrowup +/arrowdown +/quotesingle +/exclamdown +/questiondown +/dotlessi +/dotlessj +/grave +/acute +/caron +/breve +/macron +/ring +/cedilla +/germandbls +/ae +/oe +/oslash +/AE +/OE +/Oslash +/suppress +/exclam +/quotedblright +/numbersign +/dollar +/percent +/ampersand +/quoteright +/parenleft +/parenright +/asterisk +/plus +/comma +/hyphen +/period +/slash +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/colon +/semicolon +/less +/equal +/greater +/question +/at +/A +/B +/C +/D +/E +/F +/G +/H +/I +/J +/K +/L +/M +/N +/O +/P +/Q +/R +/S +/T +/U +/V +/W +/X +/Y +/Z +/bracketleft +/quotedblleft +/bracketright +/circumflex +/dotaccent +/quoteleft +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/n +/o +/p +/q +/r +/s +/t +/u +/v +/w +/x +/y +/z +/endash +/emdash +/hungarumlaut +/tilde +/dieresis +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/dvips/context/cmtt.enc b/fonts/enc/dvips/context/cmtt.enc new file mode 100644 index 000000000..3c3a9f74b --- /dev/null +++ b/fonts/enc/dvips/context/cmtt.enc @@ -0,0 +1,258 @@ +/enccmtt[ +/Gamma +/Delta +/Theta +/Lambda +/Xi +/Pi +/Sigma +/Upsilon +/Phi +/Psi +/Omega +/arrowup +/arrowdown +/quotesingle +/exclamdown +/questiondown +/dotlessi +/dotlessj +/grave +/acute +/caron +/breve +/macron +/ring +/cedilla +/germandbls +/ae +/oe +/oslash +/AE +/OE +/Oslash +/visiblespace +/exclam +/quotedbl +/numbersign +/dollar +/percent +/ampersand +/quoteright +/parenleft +/parenright +/asterisk +/plus +/comma +/hyphen +/period +/slash +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/colon +/semicolon +/less +/equal +/greater +/question +/at +/A +/B +/C +/D +/E +/F +/G +/H +/I +/J +/K +/L +/M +/N +/O +/P +/Q +/R +/S +/T +/U +/V +/W +/X +/Y +/Z +/bracketleft +/backslash +/bracketright +/asciicircum +/underscore +/quoteleft +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/n +/o +/p +/q +/r +/s +/t +/u +/v +/w +/x +/y +/z +/braceleft +/bar +/braceright +/asciitilde +/dieresis +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/dvips/context/ec-2004.enc b/fonts/enc/dvips/context/ec-2004.enc new file mode 100644 index 000000000..f092a34a2 --- /dev/null +++ b/fonts/enc/dvips/context/ec-2004.enc @@ -0,0 +1,82 @@ +% +% This is the EC encoding. +% +% These are the ligs and kerns in addition to those found in the +% AFM file. (The only ligs in the Times-Roman.afm file are the +% fi and fl ligatures.) +% +% LIGKERN space l =: lslash ; space L =: Lslash ; +% LIGKERN question quoteleft =: questiondown ; exclam quoteleft =: exclamdown ; +% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ; +% LIGKERN quoteleft quoteleft =: quotedblleft ; +% LIGKERN quoteright quoteright =: quotedblright ; +% +% We blow away kerns to and from spaces (TeX doesn't have a +% space) and also remove any kerns from the numbers (although +% the only kern pair that mentions a number in Times-Roman.afm +% is one one.) +% +% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ; +% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ; +% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ; +% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ; +% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ; +% LIGKERN nine {} * ; * {} nine ; +% LIGKERN comma comma =: quotedblbase ; less less =: guillemotleft ; +% LIGKERN greater greater =: guillemotright ; +% +/ECEncoding [ % now 256 chars follow +% 0x00 + /grave /acute /circumflex /tilde /dieresis /hungarumlaut /ring /caron + /breve /macron /dotaccent /cedilla + /ogonek /quotesinglbase /guilsinglleft /guilsinglright +% 0x10 + /quotedblleft /quotedblright /quotedblbase /guillemotleft + /guillemotright /endash /emdash /cwm + /zeroinferior /dotlessi /dotlessj /ff /fi /fl /ffi /ffl +% 0x20 + /visualspace /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /hyphen +% 0x80 + /Abreve /Aogonek /Cacute /Ccaron /Dcaron /Ecaron /Eogonek /Gbreve + /Lacute /Lcaron /Lslash /Nacute /Ncaron /Ng /Ohungarumlaut /Racute +% 0x90 + /Rcaron /Sacute /Scaron /Scedilla + /Tcaron /Tcedilla /Uhungarumlaut /Uring + /Ydieresis /Zacute /Zcaron /Zdotaccent /IJ /Idotaccent /dbar /section +% 0xA0 + /abreve /aogonek /cacute /ccaron /dcaron /ecaron /eogonek /gbreve + /lacute /lcaron /lslash /nacute /ncaron /ng /ohungarumlaut /racute +% 0xB0 + /rcaron /sacute /scaron /scedilla + /tquoteright /tcedilla /uhungarumlaut /uring + /ldot /zacute /zcaron /zdotaccent /ij /exclamdown /questiondown /sterling +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /Germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /germandbls +] def diff --git a/fonts/enc/dvips/context/q-8r.enc b/fonts/enc/dvips/context/q-8r.enc new file mode 100644 index 000000000..be8b32613 --- /dev/null +++ b/fonts/enc/dvips/context/q-8r.enc @@ -0,0 +1,264 @@ +% This file could belong to the TeX Gyre collection of fonts, +% but is only needed and thus distributed with ConTeXt macro package. +% +% It provides 8r encoding compatible with TeX Gyre fonts and is used to enable +% substituting Adobe fonts by TeX Gyre in pxfonts & txfonts. +% +/encq8r [ +/.notdef +/dotaccent +/fi +/fl +/fraction +/hungarumlaut +/Lslash +/lslash +/ogonek +/ring +/.notdef +/breve +/minus +/.notdef +/Zcaron +/zcaron +/caron +/dotlessi +/dotlessj +/ff +/ffi +/ffl +/notequal +/infinity +/lessequal +/greaterequal +/partialdiff +/summation +/product +/pi +/grave +/quotesingle +/space +/exclam +/quotedbl +/numbersign +/dollar +/percent +/ampersand +/quoteright +/parenleft +/parenright +/asterisk +/plus +/comma +/hyphen +/period +/slash +/zero +/one +/two +/three +/four +/five +/six +/seven +/eight +/nine +/colon +/semicolon +/less +/equal +/greater +/question +/at +/A +/B +/C +/D +/E +/F +/G +/H +/I +/J +/K +/L +/M +/N +/O +/P +/Q +/R +/S +/T +/U +/V +/W +/X +/Y +/Z +/bracketleft +/backslash +/bracketright +/asciicircum +/underscore +/quoteleft +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/n +/o +/p +/q +/r +/s +/t +/u +/v +/w +/x +/y +/z +/braceleft +/bar +/braceright +/asciitilde +/.notdef +/Euro +/integral +/quotesinglbase +/florin +/quotedblbase +/ellipsis +/dagger +/daggerdbl +/circumflex +/perthousand +/Scaron +/guilsinglleft +/OE +/Omega +/radical +/approxequal +/.notdef +/.notdef +/.notdef +/quotedblleft +/quotedblright +/bullet +/endash +/emdash +/tilde +/trademark +/scaron +/guilsinglright +/oe +/Delta +/lozenge +/Ydieresis +/.notdef +/exclamdown +/cent +/sterling +/currency +/yen +/brokenbar +/section +/dieresis +/copyright +/ordfeminine +/guillemotleft +/logicalnot +/hyphen +/registered +/macron +/degree +/plusminus +/two.superior +/three.superior +/acute +/mu +/paragraph +/periodcentered +/cedilla +/one.superior +/ordmasculine +/guillemotright +/onequarter +/onehalf +/threequarters +/questiondown +/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 +] def diff --git a/fonts/enc/dvips/context/teff-trinite.enc b/fonts/enc/dvips/context/teff-trinite.enc new file mode 100644 index 000000000..ea0e2651e --- /dev/null +++ b/fonts/enc/dvips/context/teff-trinite.enc @@ -0,0 +1,260 @@ +% Encoding file, generated by textools.rb from TriniteNo2RomCon-Regular.afm + +/tefftriniteencoding [ + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /breve + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /caron + /dotlessi + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /fraction + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /space + /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 + /.notdef + /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 + /bar + /braceright + /.notdef + /.notdef + /Euro + /.notdef + /.notdef + /florin + /quotedblbase + /ellipsis + /dagger + /daggerdbl + /circumflex + /perthousand + /.notdef + /guilsinglleft + /OE + /.notdef + /.notdef + /.notdef + /.notdef + /quoteleft + /quoteright + /quotedblleft + /quotedblright + /bullet + /endash + /emdash + /tilde + /.notdef + /.notdef + /guilsinglright + /oe + /.notdef + /.notdef + /Ydieresis + /.notdef + /exclamdown + /cent + /sterling + /.notdef + /.notdef + /.notdef + /section + /dieresis + /copyright + /.notdef + /guillemotleft + /.notdef + /.notdef + /.notdef + /macron + /degree + /.notdef + /.notdef + /.notdef + /acute + /.notdef + /paragraph + /multiply + /cedilla + /.notdef + /.notdef + /guillemotright + /.notdef + /.notdef + /.notdef + /questiondown + /Agrave + /Aacute + /Acircumflex + /Atilde + /Adieresis + /Aring + /AE + /Ccedilla + /Egrave + /Eacute + /Ecircumflex + /Edieresis + /Igrave + /Iacute + /Icircumflex + /Idieresis + /.notdef + /Ntilde + /Ograve + /Oacute + /Ocircumflex + /Otilde + /Odieresis + /.notdef + /Oslash + /Ugrave + /Uacute + /Ucircumflex + /Udieresis + /.notdef + /.notdef + /germandbls + /agrave + /aacute + /acircumflex + /atilde + /adieresis + /aring + /ae + /ccedilla + /egrave + /eacute + /ecircumflex + /edieresis + /igrave + /iacute + /icircumflex + /idieresis + /.notdef + /ntilde + /ograve + /oacute + /ocircumflex + /otilde + /odieresis + /.notdef + /oslash + /ugrave + /uacute + /ucircumflex + /udieresis + /.notdef + /.notdef + /ydieresis +] def diff --git a/fonts/enc/dvips/jmn/hans.enc b/fonts/enc/dvips/jmn/hans.enc new file mode 100644 index 000000000..9c7b78a86 --- /dev/null +++ b/fonts/enc/dvips/jmn/hans.enc @@ -0,0 +1,258 @@ +/enchans[ +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/space +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/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 +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/a +/b +/c +/d +/e +/f +/g +/h +/i +/j +/k +/l +/m +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/AA +/AAA +/BB +/BBB +/CC +/CCC +/DD +/DDD +/EE +/EEE +/FF +/FFF +/GG +/GGG +/HH +/HHH +/II +/III +/JJ +/JJJ +/KK +/KKK +/LL +/LLL +/MM +/MMM +/NN +/NNN +/OO +/OOO +/PP +/PPP +/QQ +/QQQ +/RR +/RRR +/SS +/SSS +/TT +/TTT +/UU +/UUU +/VV +/VVV +/WW +/WWW +/XX +/XXX +/YY +/YYY +/ZZ +/ZZZ +/aa +/aaa +/bb +/bbb +/cc +/ccc +/dd +/ddd +/ee +/eee +/ff +/fff +/gg +/ggg +/hh +/hhh +/ii +/iii +/jj +/jjj +/kk +/kkk +/ll +/lll +/A.alt +/B.alt +/C.alt +/D.alt +/E.alt +/F.alt +/G.alt +/H.alt +/I.alt +/J.alt +/K.alt +/L.alt +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +/.notdef +] def diff --git a/fonts/enc/pdftex/context/koeieletters-ex.enc b/fonts/enc/pdftex/context/koeieletters-ex.enc new file mode 100644 index 000000000..ae27d11de --- /dev/null +++ b/fonts/enc/pdftex/context/koeieletters-ex.enc @@ -0,0 +1,259 @@ +/koeielettersEnc-ex [ + /parenleft.big % 0x00 + /parenright.big + /bracketleft.big + /bracketright.big + /.notdef + /.notdef + /.notdef + /.notdef + /braceleft.big + /braceright.big + /.notdef + /.notdef + /bar.big + /bar.bigg + /slash.big + /backslash.big % 0x10 + /parenleft.bigg + /parenright.bigg + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x20 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /slash.bigg + /backslash.bigg + /parenleft.top % 0x30 + /parenright.top + /bracketleft.top + /bracketright.top + /bracketleft.bot + /bracketright.bot + /bracketleft.ex + /bracketright.ex + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /parenleft.bot % 0x40 + /parenright.bot + /parenleft.ex + /parenright.ex + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /summation.alt % 0x50 + /.notdef + /integral.alt + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /summation.big + /.notdef + /integral.big + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x60 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /bracketleft.bigg + /bracketright.bigg + /.notdef + /.notdef + /.notdef + /.notdef + /braceleft.bigg + /braceright.bigg + /radical.big % 0x70 + /radical.bigg + /radical.Bigg + /radical.BIGG + /radical.bot + /radical.mid + /radical.top + /.notdef + /.notdef + /.notdef + /radical.extender + /radical.end + /bar.begin + /.notdef + /.notdef + /.notdef + /.notdef % 0x80 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x90 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xa0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xb0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xc0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xd0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xe0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xf0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef +] def + diff --git a/fonts/enc/pdftex/context/koeieletters-mi.enc b/fonts/enc/pdftex/context/koeieletters-mi.enc new file mode 100644 index 000000000..60a91b83f --- /dev/null +++ b/fonts/enc/pdftex/context/koeieletters-mi.enc @@ -0,0 +1,271 @@ +/koeielettersEnc-mi [ + /.notdef % 0x00 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x10 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x20 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /zero.alt % 0x30 + /one.alt + /two.alt + /three.alt + /four.alt + /five.alt + /six.alt + /seven.alt + /eight.alt + /nine.alt + /period + /comma + /less + /slash + /greater + /.notdef + /.notdef % 0x40 + /A + /B + /C + /D + /E + /F + /G + /H + /I + /J + /K + /L + /M + /N + /O + /P % 0x50 + /Q + /R + /S + /T + /U + /V + /W + /X + /Y + /Z + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x60 + /a + /b + /c + /d + /e + /f + /g + /h + /i + /j + /k + /l + /m + /n + /o + /p % 0x70 + /q + /r + /s + /t + /u + /v + /w + /x + /y + /z + /dotlessi + /dotlessj + /.notdef + /.notdef + /.notdef + /.notdef % 0x80 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x90 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xa0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xb0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xc0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xd0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xe0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xf0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef +] def + + + + + + + + + + + + + diff --git a/fonts/enc/pdftex/context/koeieletters-sy.enc b/fonts/enc/pdftex/context/koeieletters-sy.enc new file mode 100644 index 000000000..ef9e95467 --- /dev/null +++ b/fonts/enc/pdftex/context/koeieletters-sy.enc @@ -0,0 +1,271 @@ +/koeielettersEnc-sy [ + /minus % 0x00 + /periodcentered + /multiply + /asteriskmath + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x10 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /similar + /equivalence + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /arrowleft % 0x20 + /arrowright + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /minute % 0x30 + /infinity + /.notdef + /.notdef + /.notdef + /.notdef + /slash + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x40 + /A + /B + /C + /D + /E + /F + /G + /H + /I + /J + /K + /L + /M + /N + /O + /P % 0x50 + /Q + /R + /S + /T + /U + /V + /W + /X + /Y + /Z + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x60 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /braceleft + /braceright + /.notdef + /.notdef + /bar + /.notdef + /.notdef + /.notdef + /backslash + /.notdef + /radical.alt % 0x70 + /.notdef + /.notdef + /integral + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /minus.alt % 0x80 + /arrowleft.lft % this was start of braces + /arrowleft.rt + /arrowright.lft + /arrowright.rt + /arrow.mid + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x90 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xa0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xb0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xc0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xd0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xe0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xf0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef +] def + + + + + + + + + + + + + diff --git a/fonts/enc/pdftex/context/koeieletters.enc b/fonts/enc/pdftex/context/koeieletters.enc new file mode 100644 index 000000000..e6b0405ea --- /dev/null +++ b/fonts/enc/pdftex/context/koeieletters.enc @@ -0,0 +1,271 @@ +/koeielettersEnc [ + /.notdef % 0x00 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /dotlessi % 0x10 + /dotlessj + /grave + /acute + /caron + /breve + /hungarumlaut + /macron + /ringaccent + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /space % 0x20 + /exclam + /quotedbl + /.notdef + /.notdef + /.notdef + /.notdef + /quotesingle + /parenleft + /parenright + /asterisk + /plus + /comma + /hyphen + /period + /slash + /zero % 0x30 + /one + /two + /three + /four + /five + /six + /seven + /eight + /nine + /colon + /semicolon + /less + /equal + /greater + /question + /at % 0x40 + /A + /B + /C + /D + /E + /F + /G + /H + /I + /J + /K + /L + /M + /N + /O + /P % 0x50 + /Q + /R + /S + /T + /U + /V + /W + /X + /Y + /Z + /bracketleft + /backslash + /bracketright + /asciicircum + /underscore + /grave % 0x60 + /a + /b + /c + /d + /e + /f + /g + /h + /i + /j + /k + /l + /m + /n + /o + /p % 0x70 + /q + /r + /s + /t + /u + /v + /w + /x + /y + /z + /braceleft + /bar + /braceright + /asciitilde + /quotedblright + /quoteright % 0x80 + /quoteleft + /breve + /quotedblleft + /quotesinglbase + /quotedblbase + /second + /radical + /circumflex + /tilde + /dotlessi + /dotlessj + /plus.alt + /minus.alt + /zero.alt + /one.alt + /two.alt % 0x90 + /three.alt + /four.alt + /five.alt + /six.alt + /seven.alt + /eight.alt + /nine.alt + /endash + /emdash + /dotaccent + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xa0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /dieresis + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xb0 + /.notdef + /.notdef + /.notdef + /acute + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xc0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xd0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /multiply + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xe0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xf0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef +] def + + + + + + + + + + + + + diff --git a/fonts/enc/pdftex/context/koeielogos.enc b/fonts/enc/pdftex/context/koeielogos.enc new file mode 100644 index 000000000..0b813a91b --- /dev/null +++ b/fonts/enc/pdftex/context/koeielogos.enc @@ -0,0 +1,258 @@ +/koeielogosEnc [ + /P_r_a_g_m_a_A_d_e % 0x00 + /p_r_a_g_m_a_a_d_e + /c_o_n_t_e_x_t + /contextlogo + /contextlogo.shadow + /contextlogo.contour + /contextlogo.skeleton + /contextlogo.dots + /M_P + /mplogo + /T_e_X + /texlogo + /boo + /cow + /examplelogo + /foxetlogo + /m_e_t_a_f_u_n % 0x10 + /metafunlogo + /texlogo.alt + /wikilogo + /PragmaADElogo + /pragmaadelogo + /E_x_a_m_p_l_e + /F_o_X_e_t + /T_E_X + /W_i_k_i + /cowtextlogo + /C_o_w_t_e_x_t + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef +] def diff --git a/fonts/fea/context/greek-babel.fea b/fonts/fea/context/greek-babel.fea new file mode 100644 index 000000000..68f5cd145 --- /dev/null +++ b/fonts/fea/context/greek-babel.fea @@ -0,0 +1,294 @@ +# This file has been written by Arthur Reutenauer. +# An Opentype feature to replace the Babel input scheme + +lookup GreekBabelLookupMultiple { + lookupflag 1 ; + sub quotedbl quotesingle i by uni1FD3 ; + sub quotedbl quotesingle u by uni1FE3 ; + sub quotedbl grave i by uni1FD2 ; + sub quotedbl grave u by uni1FE2 ; + sub quotedbl asciitilde i by uni1FD7 ; + sub quotedbl asciitilde u by uni1FE7 ; + sub quotedbl i by uni03CA ; + sub quotedbl u by uni03CB ; + sub equal a by uni1FB1 ; + sub equal i by uni1FD1 ; + sub equal u by uni1FE1 ; + sub equal quotesingle a by uniEB00 ; + sub equal quotesingle i by uniEB39 ; + sub equal u quotesingle by uniEB7A ; + sub greater a by uni1F00 ; + sub greater A by uni1F08 ; + sub greater e by uni1F10 ; + sub greater E by uni1F18 ; + sub greater h by uni1F20 ; + sub greater H by uni1F28 ; + sub greater i by uni1F30 ; + sub greater I by uni1F38 ; + sub greater o by uni1F40 ; + sub greater O by uni1F48 ; + sub greater u by uni1F50 ; + sub greater w by uni1F60 ; + sub greater W by uni1F68 ; + sub greater grave a by uni1F02 ; + sub greater grave A by uni1F0A ; + sub greater grave e by uni1F12 ; + sub greater grave E by uni1F1A ; + sub greater grave h by uni1F22 ; + sub greater grave H by uni1F2A ; + sub greater grave i by uni1F32 ; + sub greater grave I by uni1F3A ; + sub greater grave o by uni1F42 ; + sub greater grave O by uni1F4A ; + sub greater grave u by uni1F52 ; + sub greater grave w by uni1F62 ; + sub greater grave W by uni1F6A ; + sub greater quotesingle a by uni1F04 ; + sub greater quotesingle A by uni1F0C ; + sub greater quotesingle e by uni1F14 ; + sub greater quotesingle E by uni1F1C ; + sub greater quotesingle h by uni1F24 ; + sub greater quotesingle H by uni1F2C ; + sub greater quotesingle i by uni1F34 ; + sub greater quotesingle I by uni1F3C ; + sub greater quotesingle o by uni1F44 ; + sub greater quotesingle O by uni1F4C ; + sub greater quotesingle u by uni1F54 ; + sub greater quotesingle U by uni1F5C ; + sub greater quotesingle w by uni1F64 ; + sub greater quotesingle W by uni1F6C ; + sub greater asciitilde a by uni1F06 ; + sub greater asciitilde A by uni1F0E ; + sub greater asciitilde e by uni1F16 ; + sub greater asciitilde E by uni1F1E ; + sub greater asciitilde h by uni1F26 ; + sub greater asciitilde H by uni1F2E ; + sub greater asciitilde i by uni1F36 ; + sub greater asciitilde I by uni1F3E ; + sub greater asciitilde o by uni1F46 ; + sub greater asciitilde O by uni1F4E ; + sub greater asciitilde u by uni1F56 ; + sub greater asciitilde U by uni1F5E ; + sub greater asciitilde w by uni1F66 ; + sub greater asciitilde W by uni1F6E ; + sub less a by uni1F01 ; + sub less A by uni1F09 ; + sub less e by uni1F11 ; + sub less E by uni1F19 ; + sub less h by uni1F21 ; + sub less H by uni1F29 ; + sub less i by uni1F31 ; + sub less I by uni1F39 ; + sub less o by uni1F41 ; + sub less O by uni1F49 ; + sub less u by uni1F51 ; + sub less U by uni1F59 ; + sub less w by uni1F61 ; + sub less W by uni1F69 ; + sub less grave a by uni1F03 ; + sub less grave A by uni1F0B ; + sub less grave e by uni1F13 ; + sub less grave E by uni1F1B ; + sub less grave h by uni1F23 ; + sub less grave H by uni1F2B ; + sub less grave i by uni1F33 ; + sub less grave I by uni1F3B ; + sub less grave o by uni1F43 ; + sub less grave O by uni1F4B ; + sub less grave u by uni1F53 ; + sub less grave U by uni1F5B ; + sub less grave w by uni1F63 ; + sub less grave W by uni1F6B ; + sub less quotesingle a by uni1F05 ; + sub less quotesingle A by uni1F0D ; + sub less quotesingle e by uni1F15 ; + sub less quotesingle E by uni1F1D ; + sub less quotesingle h by uni1F25 ; + sub less quotesingle H by uni1F2D ; + sub less quotesingle i by uni1F35 ; + sub less quotesingle I by uni1F3D ; + sub less quotesingle o by uni1F45 ; + sub less quotesingle O by uni1F4D ; + sub less quotesingle u by uni1F55 ; + sub less quotesingle U by uni1F5D ; + sub less quotesingle w by uni1F65 ; + sub less quotesingle W by uni1F6D ; + sub less asciitilde a by uni1F07 ; + sub less asciitilde A by uni1F0F ; + sub less asciitilde e by uni1F17 ; + sub less asciitilde E by uni1F1F ; + sub less asciitilde h by uni1F27 ; + sub less asciitilde H by uni1F2F ; + sub less asciitilde i by uni1F37 ; + sub less asciitilde I by uni1F3F ; + sub less asciitilde o by uni1F47 ; + sub less asciitilde O by uni1F4F ; + sub less asciitilde u by uni1F57 ; + sub less asciitilde U by uni1F5F ; + sub less asciitilde w by uni1F67 ; + sub less asciitilde W by uni1F6F ; + sub grave a by uni1F70 ; + sub quotesingle a by uni1F71 ; + sub grave e by uni1F72 ; + sub quotesingle e by uni1F73 ; + sub grave h by uni1F74 ; + sub quotesingle h by uni1F75 ; + sub grave i by uni1F76 ; + sub quotesingle i by uni1F77 ; + sub grave o by uni1F78 ; + sub quotesingle o by uni1F79 ; + sub grave u by uni1F7A ; + sub quotesingle u by uni1F7B ; + sub grave w by uni1F7C ; + sub quotesingle w by uni1F7D ; + sub grave A by uni1FBA ; + sub quotesingle A by uni1FBB ; + sub grave E by uni1FC8 ; + sub quotesingle E by uni1FC9 ; + sub grave H by uni1FCA ; + sub quotesingle H by uni1FCB ; + sub grave I by uni1FDA ; + sub quotesingle I by uni1FDB ; + sub grave U by uni1FEA ; + sub quotesingle U by uni1FEB ; + sub grave W by uni1FFA ; + sub quotesingle W by uni1FFB ; + sub greater a bar by uni1F80 ; + sub greater A bar by uni1F88 ; + sub greater h bar by uni1F90 ; + sub greater H bar by uni1F98 ; + sub greater w bar by uni1FA0 ; + sub greater W bar by uni1FA8 ; + sub greater grave a bar by uni1F82 ; + sub greater grave A bar by uni1F8A ; + sub greater grave h bar by uni1F92 ; + sub greater grave H bar by uni1F9A ; + sub greater grave w bar by uni1FA2 ; + sub greater grave W bar by uni1FAA ; + sub greater quotesingle a bar by uni1F84 ; + sub greater quotesingle A bar by uni1F8C ; + sub greater quotesingle h bar by uni1F94 ; + sub greater quotesingle H bar by uni1F9C ; + sub greater quotesingle w bar by uni1FA4 ; + sub greater quotesingle W bar by uni1FAC ; + sub greater asciitilde a bar by uni1F86 ; + sub greater asciitilde A bar by uni1F8E ; + sub greater asciitilde h bar by uni1F96 ; + sub greater asciitilde H bar by uni1F9E ; + sub greater asciitilde w bar by uni1FA6 ; + sub greater asciitilde W bar by uni1FAE ; + sub less a bar by uni1F81 ; + sub less A bar by uni1F89 ; + sub less h bar by uni1F91 ; + sub less H bar by uni1F99 ; + sub less w bar by uni1FA1 ; + sub less W bar by uni1FA9 ; + sub less grave a bar by uni1F83 ; + sub less grave A bar by uni1F8B ; + sub less grave h bar by uni1F93 ; + sub less grave H bar by uni1F9B ; + sub less grave w bar by uni1FA3 ; + sub less grave W bar by uni1FAB ; + sub less quotesingle a bar by uni1F85 ; + sub less quotesingle A bar by uni1F8D ; + sub less quotesingle h bar by uni1F95 ; + sub less quotesingle H bar by uni1F9D ; + sub less quotesingle w bar by uni1FA5 ; + sub less quotesingle W bar by uni1FAD ; + sub less asciitilde a bar by uni1F87 ; + sub less asciitilde A bar by uni1F8F ; + sub less asciitilde h bar by uni1F97 ; + sub less asciitilde H bar by uni1F9F ; + sub less asciitilde w bar by uni1FA7 ; + sub less asciitilde W bar by uni1FAF ; + sub grave a bar by uni1FB2 ; + sub a bar by uni1FB3 ; + sub quotesingle a bar by uni1FB4 ; + sub h bar by uni1FC3 ; + sub grave h bar by uni1FC2 ; + sub quotesingle h bar by uni1FC4 ; + sub grave w bar by uni1FF2 ; + sub w bar by uni1FF3 ; + sub quotesingle w bar by uni1FF4 ; + sub asciitilde a by uni1FB6 ; + sub asciitilde a bar by uni1FB7 ; + sub asciitilde h by uni1FC6 ; + sub asciitilde h bar by uni1FC7 ; + sub asciitilde i by uni1FD6 ; + sub asciitilde u by uni1FE6 ; + sub asciitilde w by uni1FF6 ; + sub asciitilde w bar by uni1FF7 ; + sub greater r by uni1FE4 ; + sub less r by uni1FE5 ; + sub less R by uni1FEC ; +} GreekBabelLookupMultiple ; + +lookup GreekBabelLookupSimple { + lookupflag 0 ; + sub a by alpha ; + sub b by beta ; + sub g by gamma ; + sub d by delta ; + sub e by epsilon ; + sub z by zeta ; + sub h by eta ; + sub j by theta ; + sub i by iota ; + sub k by kappa ; + sub l by lambda ; + sub m by mu ; + sub n by nu ; + sub x by xi ; + sub o by omicron ; + sub p by pi ; + sub r by rho ; + sub c by uni03F2 ; + sub s by uni03F2 ; + sub t by tau ; + sub u by upsilon ; + sub f by phi ; + sub q by chi ; + sub y by psi ; + sub w by omega ; + sub A by Alpha ; + sub B by Beta ; + sub G by Gamma ; + sub D by Delta ; + sub E by Epsilon ; + sub Z by Zeta ; + sub H by Eta ; + sub J by Theta ; + sub I by Iota ; + sub K by Kappa ; + sub L by Lambda ; + sub M by Mu ; + sub N by Nu ; + sub X by Xi ; + sub O by Omicron ; + sub P by Pi ; + sub R by Rho ; + sub C by Uni03C2 ; + sub S by uni03F9 ; + sub T by Tau ; + sub U by Upsilon ; + sub F by Phi ; + sub Q by Chi ; + sub Y by Psi ; + sub W by Omega ; + sub semicolon by anoteleia ; + sub exclam by dotbelowcomb ; +} GreekBabelLookupSimple ; + +feature grbl { + + script DFLT ; + language dflt ; + lookup GreekBabelLookupMultiple ; + lookup GreekBabelLookupSimple ; + + script latn; + language dflt ; + lookup GreekBabelLookupMultiple ; + lookup GreekBabelLookupSimple ; +} grbl ; + diff --git a/fonts/fea/context/test-features.fea b/fonts/fea/context/test-features.fea new file mode 100644 index 000000000..ffc3c588d --- /dev/null +++ b/fonts/fea/context/test-features.fea @@ -0,0 +1,20 @@ +lookup TestLookupENGLISH { + lookupflag 0 ; + sub l a n g u a g e by e n g l i s h ; +} TestLookupENGLISH ; + +lookup TestLookupDUTCH { + lookupflag 0 ; + sub l a n g u a g e by d u t c h ; +} TestLookupDUTCH ; + +feature test { + + script latn ; + language ENG exclude_dflt ; + lookup TestLookupENGLISH ; + language NLD exclude_dflt ; + lookup TestLookupDUTCH ; + +} test ; + diff --git a/fonts/fea/context/texhistoric.fea b/fonts/fea/context/texhistoric.fea new file mode 100644 index 000000000..453ea0188 --- /dev/null +++ b/fonts/fea/context/texhistoric.fea @@ -0,0 +1,42 @@ +# The first MkIV OpenType Handler used internal methods, but +# after we implemented other things it made more sense to +# do the following. (HH) + +lookup TeXPseudoLigaturesLookup { + lookupflag 1 ; + sub hyphen hyphen hypen by emdash ; + sub hyphen hyphen by endash ; + sub hyphen endash by emdash ; + sub endash hyphen by emdash ; + sub quoteleft quoteleft by quotedblleft ; + sub quoteright quoteright by quotedblright ; + sub grave grave by quotedblleft ; + sub quotesingle quotesingle by quotedblright ; + sub comma comma by quotedblbase ; +} TeXPseudoLigaturesLookup ; + +lookup TeXQuoteReplacementLookup { + lookupflag 1 ; + sub quotedbl by quotedblright ; + sub quotesingle by quoteright ; + sub grave by quoteleft ; +} TeXQuoteReplacementLookup ; + +feature tlig { + script DFLT ; + language dflt ; + lookup TeXPseudoLigaturesLookup ; + script latn; + language dflt ; + lookup TeXPseudoLigaturesLookup ; +} tlig ; + +feature trep { + script DFLT ; + language dflt ; + lookup TeXQuoteReplacementLookup ; + script latn; + language dflt ; + lookup TeXQuoteReplacementLookup ; +} trep ; + diff --git a/fonts/fea/context/verbose-digits.fea b/fonts/fea/context/verbose-digits.fea new file mode 100644 index 000000000..866734853 --- /dev/null +++ b/fonts/fea/context/verbose-digits.fea @@ -0,0 +1,36 @@ +lookup NumericLookupDFLT { + lookupflag 0 ; + sub zero by z e r o ; + sub one by o n e ; + sub two by t w o ; + sub three by t h r e e ; + sub four by f o u r ; + sub five by f i v e ; + sub six by s i x ; + sub seven by s e v e n ; + sub eight by e i g h t ; + sub nine by n i n e ; +} NumericLookupDFLT ; + +feature verb { + + script DFLT ; + language dflt ; + lookup NumericLookupDFLT ; + + script latn; + language dflt ; + lookup NumericLookupDFLT ; + language AZE exclude_dflt ; + lookup NumericLookupDFLT ; + language CRT exclude_dflt ; + lookup NumericLookupDFLT ; + language MOL exclude_dflt ; + lookup NumericLookupDFLT ; + language ROM exclude_dflt ; + lookup NumericLookupDFLT ; + language TRK exclude_dflt ; + lookup NumericLookupDFLT ; + +} verb ; + diff --git a/fonts/map/dvips/context/contnav.map b/fonts/map/dvips/context/contnav.map new file mode 100644 index 000000000..942798c57 --- /dev/null +++ b/fonts/map/dvips/context/contnav.map @@ -0,0 +1 @@ +contnav ContextNavigation /fonts/map/luatex/context/demo-file.lum + + We recommend that you use a lowercase filename, just to prevent + lookup errors. Font filenames are already such a mess. + + A test file, dedicated to Dohyun Kim is: + + \usemodule[fnt-20] + + \starttext + + \definefontfeature + [otftracker-kozminprovi-regular] + [mode=node,vrt2=yes,script=latn] + + \setvariables + [otftracker] + [font=kozminprovi-regular, + sample=\char"3002] + + \stoptext + + In the resulting pdf file you will then find: + + begincmap + /CIDSystemInfo + << /Registry (TeX) + /Ordering (FNUMTE-KozMinProVI-Regular) + /Supplement 0 + >> def + /CMapName /TeX-Identity-FNUMTE-KozMinProVI-Regular def + /CMapType 2 def + 1 begincodespacerange + <0000> + endcodespacerange + 0 beginbfrange + endbfrange + 2 beginbfchar + <027B> <3002> + <1ED0> <3002> + endbfchar + endcmap + + Of course this assumes that the font used is the same as we + have on our machines. + +]]-- + +return { + version = 1.00, + fontname = "kozminprovi-regular.otf", + tounicode = { + ["Japan1.7888"] = 0x3002, + }, +} diff --git a/fonts/map/pdftex/context/8r-base.map b/fonts/map/pdftex/context/8r-base.map new file mode 100644 index 000000000..e1611cfe8 --- /dev/null +++ b/fonts/map/pdftex/context/8r-base.map @@ -0,0 +1,135 @@ +% courier / urw + +ucrb8r NimbusMonL-Bold <8r.enc Unicode characters +; +; Based on tex-text.map used in XeTeX, but with less ligatures (olny the most important ones) +; This part of ConTeXt distribution, but may be used for any purpose + +LHSName "tlig" +RHSName "UNICODE" + +pass(Unicode) + +; ligatures from Knuth's original CMR fonts +U+002D U+002D <> U+2013 ; -- -> en dash +U+002D U+002D U+002D <> U+2014 ; --- -> em dash + +U+0027 <> U+2019 ; ' -> right single quote + diff --git a/fonts/misc/xetex/fontmapping/tlig.tec b/fonts/misc/xetex/fontmapping/tlig.tec new file mode 100644 index 000000000..ab2268c20 Binary files /dev/null and b/fonts/misc/xetex/fontmapping/tlig.tec differ diff --git a/fonts/pfm/hoekwater/context/contnav.pfm b/fonts/pfm/hoekwater/context/contnav.pfm new file mode 100644 index 000000000..2e6e2eebb Binary files /dev/null and b/fonts/pfm/hoekwater/context/contnav.pfm differ diff --git a/fonts/pfm/hoekwater/context/koeieletters.pfm b/fonts/pfm/hoekwater/context/koeieletters.pfm new file mode 100644 index 000000000..8c890917a Binary files /dev/null and b/fonts/pfm/hoekwater/context/koeieletters.pfm differ diff --git a/fonts/pfm/jmn/hans/hans-sh.pfm b/fonts/pfm/jmn/hans/hans-sh.pfm new file mode 100644 index 000000000..806167740 Binary files /dev/null and b/fonts/pfm/jmn/hans/hans-sh.pfm differ diff --git a/fonts/pfm/jmn/hans/hans.pfm b/fonts/pfm/jmn/hans/hans.pfm new file mode 100644 index 000000000..89f74d81e Binary files /dev/null and b/fonts/pfm/jmn/hans/hans.pfm differ diff --git a/fonts/tfm/hoekwater/context/contnav.tfm b/fonts/tfm/hoekwater/context/contnav.tfm new file mode 100644 index 000000000..c272e9d49 Binary files /dev/null and b/fonts/tfm/hoekwater/context/contnav.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeielett-contour.tfm b/fonts/tfm/hoekwater/koeieletters/koeielett-contour.tfm new file mode 100644 index 000000000..52cb2595f Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeielett-contour.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeielett.tfm b/fonts/tfm/hoekwater/koeieletters/koeielett.tfm new file mode 100644 index 000000000..52cb2595f Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeielett.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeieletter-ex.tfm b/fonts/tfm/hoekwater/koeieletters/koeieletter-ex.tfm new file mode 100644 index 000000000..a567060b0 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeieletter-ex.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeieletter-mi.tfm b/fonts/tfm/hoekwater/koeieletters/koeieletter-mi.tfm new file mode 100644 index 000000000..0779ff06e Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeieletter-mi.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeieletter-sy.tfm b/fonts/tfm/hoekwater/koeieletters/koeieletter-sy.tfm new file mode 100644 index 000000000..74b8add89 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeieletter-sy.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeieletter-syx.tfm b/fonts/tfm/hoekwater/koeieletters/koeieletter-syx.tfm new file mode 100644 index 000000000..04b1c2768 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeieletter-syx.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeieletters-contour.tfm b/fonts/tfm/hoekwater/koeieletters/koeieletters-contour.tfm new file mode 100644 index 000000000..b4959f413 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeieletters-contour.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeieletters.tfm b/fonts/tfm/hoekwater/koeieletters/koeieletters.tfm new file mode 100644 index 000000000..f05925c35 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeieletters.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeielettx.tfm b/fonts/tfm/hoekwater/koeieletters/koeielettx.tfm new file mode 100644 index 000000000..eec544858 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeielettx.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeielogos-contour.tfm b/fonts/tfm/hoekwater/koeieletters/koeielogos-contour.tfm new file mode 100644 index 000000000..56e99ff04 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeielogos-contour.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeielogos.tfm b/fonts/tfm/hoekwater/koeieletters/koeielogos.tfm new file mode 100644 index 000000000..56e99ff04 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeielogos.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeien-ex.tfm b/fonts/tfm/hoekwater/koeieletters/koeien-ex.tfm new file mode 100644 index 000000000..0b3f5c9f1 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeien-ex.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeien-mi.tfm b/fonts/tfm/hoekwater/koeieletters/koeien-mi.tfm new file mode 100644 index 000000000..eafcd1156 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeien-mi.tfm differ diff --git a/fonts/tfm/hoekwater/koeieletters/koeien-sy.tfm b/fonts/tfm/hoekwater/koeieletters/koeien-sy.tfm new file mode 100644 index 000000000..80aa0ab68 Binary files /dev/null and b/fonts/tfm/hoekwater/koeieletters/koeien-sy.tfm differ diff --git a/fonts/tfm/jmn/hans/hans-sh.tfm b/fonts/tfm/jmn/hans/hans-sh.tfm new file mode 100644 index 000000000..09c3a8974 Binary files /dev/null and b/fonts/tfm/jmn/hans/hans-sh.tfm differ diff --git a/fonts/tfm/jmn/hans/hans.tfm b/fonts/tfm/jmn/hans/hans.tfm new file mode 100644 index 000000000..26002455c Binary files /dev/null and b/fonts/tfm/jmn/hans/hans.tfm differ diff --git a/fonts/tfm/public/marvosym/fmvr8x.tfm b/fonts/tfm/public/marvosym/fmvr8x.tfm new file mode 100644 index 000000000..ce8172f1c Binary files /dev/null and b/fonts/tfm/public/marvosym/fmvr8x.tfm differ diff --git a/fonts/truetype/hoekwater/lm/lmtypewriter10-regular.ttf b/fonts/truetype/hoekwater/lm/lmtypewriter10-regular.ttf new file mode 100644 index 000000000..4034627eb Binary files /dev/null and b/fonts/truetype/hoekwater/lm/lmtypewriter10-regular.ttf differ diff --git a/fonts/type1/hoekwater/context/contnav.pfb b/fonts/type1/hoekwater/context/contnav.pfb new file mode 100644 index 000000000..ab81c4f69 Binary files /dev/null and b/fonts/type1/hoekwater/context/contnav.pfb differ diff --git a/fonts/type1/hoekwater/koeieletters/koeieletters-contour.pfb b/fonts/type1/hoekwater/koeieletters/koeieletters-contour.pfb new file mode 100644 index 000000000..a6250e338 Binary files /dev/null and b/fonts/type1/hoekwater/koeieletters/koeieletters-contour.pfb differ diff --git a/fonts/type1/hoekwater/koeieletters/koeieletters.pfb b/fonts/type1/hoekwater/koeieletters/koeieletters.pfb new file mode 100644 index 000000000..25fef49f1 Binary files /dev/null and b/fonts/type1/hoekwater/koeieletters/koeieletters.pfb differ diff --git a/fonts/type1/hoekwater/koeieletters/koeielogos-contour.pfb b/fonts/type1/hoekwater/koeieletters/koeielogos-contour.pfb new file mode 100644 index 000000000..5f94d4683 Binary files /dev/null and b/fonts/type1/hoekwater/koeieletters/koeielogos-contour.pfb differ diff --git a/fonts/type1/hoekwater/koeieletters/koeielogos.pfb b/fonts/type1/hoekwater/koeieletters/koeielogos.pfb new file mode 100644 index 000000000..e7e000f32 Binary files /dev/null and b/fonts/type1/hoekwater/koeieletters/koeielogos.pfb differ diff --git a/fonts/type1/jmn/hans/hans-sh.pfb b/fonts/type1/jmn/hans/hans-sh.pfb new file mode 100644 index 000000000..9c633d6d1 Binary files /dev/null and b/fonts/type1/jmn/hans/hans-sh.pfb differ diff --git a/fonts/type1/jmn/hans/hans.pfb b/fonts/type1/jmn/hans/hans.pfb new file mode 100644 index 000000000..f516e4618 Binary files /dev/null and b/fonts/type1/jmn/hans/hans.pfb differ diff --git a/fonts/vf/hoekwater/koeieletters/koeielett-contour.vf b/fonts/vf/hoekwater/koeieletters/koeielett-contour.vf new file mode 100644 index 000000000..88365aee7 Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeielett-contour.vf differ diff --git a/fonts/vf/hoekwater/koeieletters/koeielett.vf b/fonts/vf/hoekwater/koeieletters/koeielett.vf new file mode 100644 index 000000000..1c657d50e Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeielett.vf differ diff --git a/fonts/vf/hoekwater/koeieletters/koeieletter-ex.vf b/fonts/vf/hoekwater/koeieletters/koeieletter-ex.vf new file mode 100644 index 000000000..5933a23d7 Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeieletter-ex.vf differ diff --git a/fonts/vf/hoekwater/koeieletters/koeieletter-mi.vf b/fonts/vf/hoekwater/koeieletters/koeieletter-mi.vf new file mode 100644 index 000000000..2ba294d2f Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeieletter-mi.vf differ diff --git a/fonts/vf/hoekwater/koeieletters/koeieletter-sy.vf b/fonts/vf/hoekwater/koeieletters/koeieletter-sy.vf new file mode 100644 index 000000000..b5c3ef1cc Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeieletter-sy.vf differ diff --git a/fonts/vf/hoekwater/koeieletters/koeieletter-syx.vf b/fonts/vf/hoekwater/koeieletters/koeieletter-syx.vf new file mode 100644 index 000000000..15e8428e2 Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeieletter-syx.vf differ diff --git a/fonts/vf/hoekwater/koeieletters/koeielettx.vf b/fonts/vf/hoekwater/koeieletters/koeielettx.vf new file mode 100644 index 000000000..fe36a339a Binary files /dev/null and b/fonts/vf/hoekwater/koeieletters/koeielettx.vf differ diff --git a/metapost/context/base/metafun.mp b/metapost/context/base/metafun.mp new file mode 100644 index 000000000..00011c8be --- /dev/null +++ b/metapost/context/base/metafun.mp @@ -0,0 +1,75 @@ +%D \module +%D [ file=metafun.mp, +%D version=2000.07.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=format generation file, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%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 generating many graphics at runtime, it can save run +%D time to use a format file. We could have named this file +%D \type {context}, but this is error prone, because it forces +%D to use the progname \type {mpost} or \type {context} +%D explicitly, depending on the needs. When using the format, +%D a mismatch in the memory specification of \type {mpost} or +%D \type {context} (the \TEX\ one) could lead to lost strings +%D (and as a result in buggy boundingbox and special +%D handling). By using the name \type {metatex} we make sure +%D that we use (unless overloaded) the settings of \type +%D {mpost}. + +%D First we input John Hobby's metapost plain file. However, +%D because we want to prevent dependency problems and in the +%D end even may use a patched version, we prefer to use a +%D copy, + +if unknown ahangle : + input mp-base.mp ; % input plain.mp ; +else : + let dump = relax ; +fi ; + +input mp-tool.mp ; +input mp-spec.mp ; % will be skipped in mkiv, some day +input mp-core.mp ; +input mp-page.mp ; +input mp-text.mp ; +input mp-txts.mp ; +input mp-shap.mp ; +input mp-butt.mp ; +input mp-char.mp ; +input mp-step.mp ; +input mp-grph.mp ; +input mp-figs.mp ; + +input mp-mlib.mp ; + +if known context_mlib : input mp-chem.mp ; fi ; % only when mkiv + +% mp-form.mp ; +input mp-grid.mp ; +input mp-func.mp ; + +string metafunversion ; + +metafunversion = "metafun" & " " & + decimal year & "-" & + decimal month & "-" & + decimal day & " " & + if ((time div 60) < 10) : "0" & fi + decimal (time div 60) & ":" & + if ((time-(time div 60)*60) < 10) : "0" & fi + decimal (time-(time div 60)*60) ; + +let normalend = end ; + +def end = + ; message "" ; message metafunversion ; message "" ; normalend ; +enddef ; + +dump ; endinput . diff --git a/metapost/context/base/mp-back.mp b/metapost/context/base/mp-back.mp new file mode 100644 index 000000000..f49474cf7 --- /dev/null +++ b/metapost/context/base/mp-back.mp @@ -0,0 +1,206 @@ +%D \module +%D [ file=mp-back.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%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 licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_back : endinput ; fi ; + +boolean context_back ; context_back := true ; + +def some_hash ( expr hash_width , + hash_height , + hash_linewidth , + hash_linecolor , + hash_angle , + hash_gap ) = + + stripe_gap := hash_gap ; + stripe_angle := hash_angle ; + drawoptions (withpen pencircle scaled hash_linewidth + withcolor hash_linecolor) ; + path p ; p := unitsquare xscaled hash_width yscaled hash_height ; + stripe_path_a () (draw) p ; % next we move it all to quadrant 1 + currentpicture := currentpicture shifted urcorner currentpicture ; + +enddef ; + +def some_double_back (expr back_type , + back_width , + back_height , + back_delta , + back_linewidth , + back_linecolor , + back_fillcolor , + back_topcolor , + back_bottomcolor , + back_leftcolor , + back_rightcolor ) = + + numeric ww ; ww := back_width ; + numeric hh ; hh := back_height ; + numeric dd ; dd := back_delta ; + + color back_nillcolor ; back_nillcolor := back_topcolor ; + + path p ; p := fullsquare xscaled ww yscaled hh ; + path q ; q := fullsquare xscaled (ww-2dd) yscaled (hh-2dd) ; + path r ; r := llcorner p -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p -- cycle ; + path s ; s := r xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path t ; t := llcorner p -- + lrcorner p -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) -- + llcorner p -- cycle ; + path u ; u := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path v ; v := llcorner p shifted ( 3dd,0) -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) .. + llcorner p shifted (0, 3dd) .. controls llcorner p .. cycle ; % {down} .. cycle ; + path w ; w := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path a ; a := llcorner p -- ulcorner p -- + ulcorner q -- llcorner q -- cycle ; + path b ; b := llcorner p -- lrcorner p -- + lrcorner q -- llcorner q -- cycle ; + path c ; c := lrcorner p -- urcorner p -- + urcorner q -- lrcorner q -- cycle ; + path d ; d := ulcorner p -- urcorner p -- + urcorner q -- ulcorner q -- cycle ; + path e ; e := llcorner p -- lrcorner p -- + urcorner p -- urcorner q -- + lrcorner q -- llcorner q -- cycle ; + path f ; f := llcorner p -- ulcorner p -- + urcorner p -- urcorner q -- + ulcorner q -- llcorner q -- cycle ; + + linecap := butt ; pickup pencircle scaled back_linewidth ; + + if back_type=1 : + + fill p withcolor back_fillcolor ; + fill a withcolor back_leftcolor ; + fill b withcolor back_bottomcolor ; + fill c withcolor back_rightcolor ; + fill d withcolor back_topcolor ; + draw a withcolor back_linecolor ; + draw d withcolor back_linecolor ; + draw b withcolor back_linecolor ; + draw c withcolor back_linecolor ; + + elseif back_type=2 : + + fill p withcolor back_fillcolor ; + fill e withcolor back_bottomcolor ; + fill f withcolor back_topcolor ; + draw e withcolor back_linecolor ; + draw f withcolor back_linecolor ; + + elseif back_type=3 : + + fill v withcolor back_nillcolor ; + fill w withcolor back_fillcolor ; + draw v withcolor back_linecolor ; + draw w withcolor back_linecolor ; + + elseif back_type=4 : + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=5 : + + t := t rotatedaround(center t,180) ; + u := u rotatedaround(center u,180) ; + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=6 : + + r := r rotatedaround(center r,180) ; + s := s rotatedaround(center s,180) ; + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + + elseif back_type=7 : + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + +fi ; + +enddef ; + +endinput ; + +beginfig (1) ; + +some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, .7white, .6white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +endfig ; + +end . diff --git a/metapost/context/base/mp-base.mp b/metapost/context/base/mp-base.mp new file mode 100644 index 000000000..d0b3991c8 --- /dev/null +++ b/metapost/context/base/mp-base.mp @@ -0,0 +1,558 @@ +% This is (currently) a copy of the plain.mp file. We use a copy +% because (1) we want to make sure that there are no unresolved +% dependencies, and (2) we may patch this file eventually. + +% This file gives the macros for plain MetaPost +% It contains all the features of plain METAFONT except those specific to +% font-making. (See The METAFONTbook by D.E. Knuth). +% There are also a number of macros for labeling figures, etc. +string base_name, base_version; base_name="plain"; base_version="0.63"; + +message "Preloading the plain mem file, version "&base_version; + +delimiters (); % this makes parentheses behave like parentheses +def upto = step 1 until enddef; % syntactic sugar +def downto = step -1 until enddef; +def exitunless expr c = exitif not c enddef; +let relax = \; % ignore the word `relax', as in TeX +let \\ = \; % double relaxation is like single +def ]] = ] ] enddef; % right brackets should be loners +def -- = {curl 1}..{curl 1} enddef; +def --- = .. tension infinity .. enddef; +def ... = .. tension atleast 1 .. enddef; + +def gobble primary g = enddef; +primarydef g gobbled gg = enddef; +def hide(text t) = exitif numeric begingroup t;endgroup; enddef; +def ??? = hide(interim showstopping:=1; showdependencies) enddef; +def stop expr s = message s; gobble readstring enddef; + +warningcheck:=1; +tracinglostchars:=1; + +def interact = % sets up to make "show" commands stop + hide(showstopping:=1; tracingonline:=1) enddef; + +def loggingall = % puts tracing info into the log + tracingcommands:=3; tracingtitles:=1; tracingequations:=1; + tracingcapsules:=1; tracingspecs:=2; tracingchoices:=1; tracinglostchars:=1; + tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1; + enddef; + +def tracingall = % turns on every form of tracing + tracingonline:=1; showstopping:=1; loggingall enddef; + +def tracingnone = % turns off every form of tracing + tracingcommands:=0; tracingtitles:=0; tracingequations:=0; + tracingcapsules:=0; tracingspecs:=0; tracingchoices:=0; tracinglostchars:=0; + tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0; + enddef; + + + +%% dash patterns + +vardef dashpattern(text t) = + save on, off, w; + let on=_on_; + let off=_off_; + w = 0; + nullpicture t +enddef; + +tertiarydef p _on_ d = + begingroup save pic; + picture pic; pic=p; + addto pic doublepath (w,w)..(w+d,w); + w := w+d; + pic shifted (0,d) + endgroup +enddef; + +tertiarydef p _off_ d = + begingroup w:=w+d; + p shifted (0,d) + endgroup +enddef; + + + +%% basic constants and mathematical macros + +% numeric constants +newinternal eps,epsilon,infinity,_; +eps := .00049; % this is a pretty small positive number +epsilon := 1/256/256; % but this is the smallest +infinity := 4095.99998; % and this is the largest +_ := -1; % internal constant to make macros unreadable but shorter + +newinternal mitered, rounded, beveled, butt, squared; +mitered:=0; rounded:=1; beveled:=2; % linejoin types +butt:=0; rounded:=1; squared:=2; % linecap types + + +% pair constants +pair right,left,up,down,origin; +origin=(0,0); up=-down=(0,1); right=-left=(1,0); + +% path constants +path quartercircle,halfcircle,fullcircle,unitsquare; +fullcircle = makepath pencircle; +halfcircle = subpath (0,4) of fullcircle; +quartercircle = subpath (0,2) of fullcircle; +unitsquare=(0,0)--(1,0)--(1,1)--(0,1)--cycle; + +% transform constants +transform identity; +for z=origin,right,up: z transformed identity = z; endfor + +% color constants +color black, white, red, green, blue, background; +black = (0,0,0); +white = (1,1,1); +red = (1,0,0); +green = (0,1,0); +blue = (0,0,1); +background = white; % The user can reset this + +% picture constants +picture blankpicture,evenly,withdots; +blankpicture=nullpicture; % `display blankpicture...' +evenly=dashpattern(on 3 off 3); % `dashed evenly' +withdots=dashpattern(off 2.5 on 0 off 2.5); % `dashed withdots' + +% string constants +string ditto, EOF; +ditto = char 34; % ASCII double-quote mark +EOF = char 0; % end-of-file for readfrom and write..to + +% pen constants +pen pensquare,penrazor,penspeck; +pensquare = makepen(unitsquare shifted -(.5,.5)); +penrazor = makepen((-.5,0)--(.5,0)--cycle); +penspeck=pensquare scaled eps; + +% nullary operators +vardef whatever = save ?; ? enddef; + +% unary operators +let abs = length; + +vardef round primary u = + if numeric u: floor(u+.5) + elseif pair u: (round xpart u, round ypart u) + else: u fi enddef; + +vardef ceiling primary x = -floor(-x) enddef; + +vardef byte primary s = + if string s: ASCII fi s enddef; + +vardef dir primary d = right rotated d enddef; + +vardef unitvector primary z = z/abs z enddef; + +vardef inverse primary T = + transform T_; T_ transformed T = identity; T_ enddef; + +vardef counterclockwise primary c = + if turningnumber c <= 0: reverse fi c enddef; + +vardef tensepath expr r = + for k=0 upto length r - 1: point k of r --- endfor + if cycle r: cycle else: point infinity of r fi enddef; + +vardef center primary p = .5[llcorner p, urcorner p] enddef; + + + +% binary operators + +primarydef x mod y = (x-y*floor(x/y)) enddef; +primarydef x div y = floor(x/y) enddef; +primarydef w dotprod z = (xpart w * xpart z + ypart w * ypart z) enddef; + +primarydef x**y = if y=2: x*x else: takepower y of x fi enddef; +def takepower expr y of x = + if x>0: mexp(y*mlog x) + elseif (x=0) and (y>0): 0 + else: 1 + if y=floor y: + if y>=0: for n=1 upto y: *x endfor + else: for n=_ downto y: /x endfor + fi + else: hide(errmessage "Undefined power: " & decimal x&"**"&decimal y) + fi fi enddef; + +vardef direction expr t of p = + postcontrol t of p - precontrol t of p enddef; + +vardef directionpoint expr z of p = + a_:=directiontime z of p; + if a_<0: errmessage("The direction doesn't occur"); fi + point a_ of p enddef; + +secondarydef p intersectionpoint q = + begingroup save x_,y_; (x_,y_)=p intersectiontimes q; + if x_<0: errmessage("The paths don't intersect"); origin + else: .5[point x_ of p, point y_ of q] fi endgroup +enddef; + +tertiarydef p softjoin q = + begingroup c_:=fullcircle scaled 2join_radius shifted point 0 of q; + a_:=ypart(c_ intersectiontimes p); b_:=ypart(c_ intersectiontimes q); + if a_<0:point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi + ... if b_<0:{direction infinity of q}point infinity of q + else: subpath(b_,infinity) of q fi endgroup enddef; +newinternal join_radius,a_,b_; path c_; + + +path cuttings; % what got cut off + +tertiarydef a cutbefore b = % tries to cut as little as possible + begingroup save t; + (t, whatever) = a intersectiontimes b; + if t<0: + cuttings:=point 0 of a; + a + else: cuttings:= subpath (0,t) of a; + subpath (t,length a) of a + fi + endgroup +enddef; + +tertiarydef a cutafter b = + reverse (reverse a cutbefore b) + hide(cuttings:=reverse cuttings) +enddef; + + + +% special operators +vardef incr suffix $ = $:=$+1; $ enddef; +vardef decr suffix $ = $:=$-1; $ enddef; + +def reflectedabout(expr w,z) = % reflects about the line w..z + transformed + begingroup transform T_; + w transformed T_ = w; z transformed T_ = z; + xxpart T_ = -yypart T_; xypart T_ = yxpart T_; % T_ is a reflection + T_ endgroup enddef; + +def rotatedaround(expr z, d) = % rotates d degrees around z + shifted -z rotated d shifted z enddef; +let rotatedabout = rotatedaround; % for roundabout people + +vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings + save u_; setu_ u; for uu = t: if uuu_: u_:=uu; fi endfor + u_ enddef; + +def setu_ primary u = + if pair u: pair u_ elseif string u: string u_ fi; + u_=u enddef; + +def flex(text t) = % t is a list of pairs + hide(n_:=0; for z=t: z_[incr n_]:=z; endfor + dz_:=z_[n_]-z_1) + z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef; +newinternal n_; pair z_[],dz_; + +def superellipse(expr r,t,l,b,s)= + r{up}...(s[xpart t,xpart r],s[ypart r,ypart t]){t-r}... + t{left}...(s[xpart t,xpart l],s[ypart l,ypart t]){l-t}... + l{down}...(s[xpart b,xpart l],s[ypart l,ypart b]){b-l}... + b{right}...(s[xpart b,xpart r],s[ypart r,ypart b]){r-b}...cycle enddef; + +vardef interpath(expr a,p,q) = + for t=0 upto length p-1: a[point t of p, point t of q] + ..controls a[postcontrol t of p, postcontrol t of q] + and a[precontrol t+1 of p, precontrol t+1 of q] .. endfor + if cycle p: cycle + else: a[point infinity of p, point infinity of q] fi enddef; + +vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false + tx_:=true_x; fx_:=false_x; + forever: x_:=.5[tx_,fx_]; exitif abs(tx_-fx_)<=tolerance; + if @#(x_): tx_ else: fx_ fi :=x_; endfor + x_ enddef; % now x_ is near where @# changes from true to false +newinternal tolerance, tx_,fx_,x_; tolerance:=.01; + +vardef buildcycle(text ll) = + save ta_, tb_, k_, i_, pp_; path pp_[]; + k_=0; + for q=ll: pp_[incr k_]=q; endfor + i_=k_; + for i=1 upto k_: + (ta_[i], length pp_[i_]-tb_[i_]) = + pp_[i] intersectiontimes reverse pp_[i_]; + if ta_[i]<0: + errmessage("Paths "& decimal i &" and "& decimal i_ &" don't intersect"); + fi + i_ := i; + endfor + for i=1 upto k_: subpath (ta_[i],tb_[i]) of pp_[i] .. endfor + cycle +enddef; + + + +%% units of measure + +mm=2.83464; pt=0.99626; dd=1.06601; bp:=1; +cm=28.34645; pc=11.95517; cc=12.79213; in:=72; + +vardef magstep primary m = mexp(46.67432m) enddef; + + + +%% macros for drawing and filling + +def drawoptions(text t) = + def _op_ = t enddef +enddef; + +linejoin:=rounded; % parameters that effect drawing +linecap:=rounded; +miterlimit:=10; + +drawoptions(); + +pen currentpen; +picture currentpicture; + +def fill expr c = addto currentpicture contour c _op_ enddef; +def draw expr p = + addto currentpicture + if picture p: + also p + else: + doublepath p withpen currentpen + fi + _op_ +enddef; +def filldraw expr c = + addto currentpicture contour c withpen currentpen + _op_ enddef; +def drawdot expr z = + addto currentpicture contour makepath currentpen shifted z + _op_ enddef; + +def unfill expr c = fill c withcolor background enddef; +def undraw expr p = draw p withcolor background enddef; +def unfilldraw expr c = filldraw c withcolor background enddef; +def undrawdot expr z = drawdot z withcolor background enddef; +def erase text t = + def _e_ = withcolor background hide(def _e_=enddef;) enddef; + t _e_ +enddef; +def _e_= enddef; + +def cutdraw text t = + begingroup interim linecap:=butt; draw t _e_; endgroup enddef; + +vardef image(text t) = + save currentpicture; + picture currentpicture; + currentpicture := nullpicture; + t; + currentpicture +enddef; + +def pickup secondary q = + if numeric q: numeric_pickup_ else: pen_pickup_ fi q enddef; +def numeric_pickup_ primary q = + if unknown pen_[q]: errmessage "Unknown pen"; clearpen + else: currentpen:=pen_[q]; + pen_lft:=pen_lft_[q]; + pen_rt:=pen_rt_[q]; + pen_top:=pen_top_[q]; + pen_bot:=pen_bot_[q]; + currentpen_path:=pen_path_[q] fi; enddef; +def pen_pickup_ primary q = + currentpen:=q; + pen_lft:=xpart penoffset down of currentpen; + pen_rt:=xpart penoffset up of currentpen; + pen_top:=ypart penoffset left of currentpen; + pen_bot:=ypart penoffset right of currentpen; + path currentpen_path; enddef; +newinternal pen_lft,pen_rt,pen_top,pen_bot,pen_count_; + +vardef savepen = pen_[incr pen_count_]=currentpen; + pen_lft_[pen_count_]=pen_lft; + pen_rt_[pen_count_]=pen_rt; + pen_top_[pen_count_]=pen_top; + pen_bot_[pen_count_]=pen_bot; + pen_path_[pen_count_]=currentpen_path; + pen_count_ enddef; + +def clearpen = currentpen:=nullpen; + pen_lft:=pen_rt:=pen_top:=pen_bot:=0; + path currentpen_path; + enddef; +def clear_pen_memory = + pen_count_:=0; + numeric pen_lft_[],pen_rt_[],pen_top_[],pen_bot_[]; + pen currentpen,pen_[]; + path currentpen_path, pen_path_[]; + enddef; + +vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef; +vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef; +vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef; +vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef; + +vardef penpos@#(expr b,d) = + (x@#r-x@#l,y@#r-y@#l)=(b,0) rotated d; + x@#=.5(x@#l+x@#r); y@#=.5(y@#l+y@#r) enddef; + +def penstroke text t = + forsuffixes e = l,r: path_.e:=t; endfor + fill path_.l -- reverse path_.r -- cycle enddef; +path path_.l,path_.r; + + + +%% High level drawing commands + +newinternal ahlength, ahangle; +ahlength := 4; % default arrowhead length 4bp +ahangle := 45; % default head angle 45 degrees + +vardef arrowhead expr p = + save q,e; path q; pair e; + e = point length p of p; + q = gobble(p shifted -e cutafter makepath(pencircle scaled 2ahlength)) + cuttings; + (q rotated .5ahangle & reverse q rotated -.5ahangle -- cycle) shifted e +enddef; + +path _apth; +def drawarrow expr p = _apth:=p; _finarr enddef; +def drawdblarrow expr p = _apth:=p; _findarr enddef; + +def _finarr text t = + draw _apth t; + filldraw arrowhead _apth t +enddef; + +def _findarr text t = + draw _apth t; + fill arrowhead _apth withpen currentpen t; + fill arrowhead reverse _apth withpen currentpen t +enddef; + + + +%% macros for labels + +newinternal bboxmargin; bboxmargin:=2bp; + +vardef bbox primary p = + llcorner p-(bboxmargin,bboxmargin) -- lrcorner p+(bboxmargin,-bboxmargin) + -- urcorner p+(bboxmargin,bboxmargin) -- ulcorner p+(-bboxmargin,bboxmargin) + -- cycle +enddef; + +string defaultfont; +newinternal defaultscale, labeloffset; +defaultfont = "cmr10"; +defaultscale := 1; +labeloffset := 3bp; + +vardef thelabel@#(expr s,z) = % Position s near z + save p; picture p; + if picture s: p=s + else: p = s infont defaultfont scaled defaultscale + fi; + p shifted (z + labeloffset*laboff@# - + (labxf@#*lrcorner p + labyf@#*ulcorner p + + (1-labxf@#-labyf@#)*llcorner p + ) + ) +enddef; + +def label = draw thelabel enddef; +newinternal dotlabeldiam; dotlabeldiam:=3bp; +vardef dotlabel@#(expr s,z) text t_ = + label@#(s,z) t_; + label@#(s,z); + interim linecap:=rounded; + draw z withpen pencircle scaled dotlabeldiam t_; +enddef; +def makelabel = dotlabel enddef; + +pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot; +pair laboff.ulft, laboff.llft, laboff.urt, laboff.lrt; +laboff =(0,0); labxf =.5; labyf =.5; +laboff.lft=(-1,0); labxf.lft=1; labyf.lft=.5; +laboff.rt =(1,0); labxf.rt =0; labyf.rt =.5; +laboff.bot=(0,-1); labxf.bot=.5; labyf.bot=1; +laboff.top=(0,1); labxf.top=.5; labyf.top=0; +laboff.ulft=(-.7,.7);labxf.ulft=1; labyf.ulft=0; +laboff.urt=(.7,.7); labxf.urt=0; labyf.urt=0; +laboff.llft=-(.7,.7);labxf.llft=1; labyf.llft=1; +laboff.lrt=(.7,-.7); labxf.lrt=0; labyf.lrt=1; + +vardef labels@#(text t) = + forsuffixes $=t: + label@#(str$,z$); endfor + enddef; +vardef dotlabels@#(text t) = + forsuffixes $=t: + dotlabel@#(str$,z$); endfor + enddef; +vardef penlabels@#(text t) = + forsuffixes $$=l,,r: forsuffixes $=t: + makelabel@#(str$.$$,z$.$$); endfor endfor + enddef; + + +def range expr x = numtok[x] enddef; +def numtok suffix x=x enddef; +tertiarydef m thru n = + m for x=m+1 step 1 until n: , numtok[x] endfor enddef; + + + +%% Overall adminstration + +string extra_beginfig, extra_endfig; +extra_beginfig = extra_endfig = "" ; + +def beginfig(expr c) = + begingroup + charcode:=c; + clearxy; clearit; clearpen; + pickup defaultpen; + drawoptions(); + scantokens extra_beginfig; +enddef; + +def endfig = + ; % added by HH + scantokens extra_endfig; + shipit ; + endgroup +enddef; + + +%% last-minute items + +vardef z@#=(x@#,y@#) enddef; + +def clearxy = save x,y enddef; +def clearit = currentpicture:=nullpicture enddef; +def shipit = shipout currentpicture enddef; + +let bye = end; outer end,bye; + +clear_pen_memory; % initialize the `savepen' mechanism +clearit; + +newinternal defaultpen; +pickup pencircle scaled .5bp; % set default line width +defaultpen := savepen; diff --git a/metapost/context/base/mp-butt.mp b/metapost/context/base/mp-butt.mp new file mode 100644 index 000000000..cf580211e --- /dev/null +++ b/metapost/context/base/mp-butt.mp @@ -0,0 +1,75 @@ +%D \module +%D [ file=mp-butt.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=buttons, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={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. + +if unknown context_tool : input mp-tool ; fi ; +if known context_butt : endinput ; fi ; + +boolean context_butt ; context_butt := true ; + +def some_button (expr button_type , + button_size , + button_linecolor , + button_fillcolor ) = + + numeric button_linewidth ; button_linewidth := button_size/10 ; + + drawoptions (withpen pencircle scaled button_linewidth + withcolor button_linecolor) ; + + path p ; p := unitsquare scaled button_size ; + numeric d ; d := button_size ; + numeric l ; l := button_linewidth ; + + fill p withcolor button_fillcolor ; draw p ; + + if button_type=101 : + draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ; + elseif button_type=102 : + draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ; + elseif button_type=103 : + for i=2l step 2l until d-2l : + draw (2l,i)--(2l ,i) ; + draw (4l,i)--(d-2l,i) ; + endfor ; + elseif button_type=104 : + for i=2l step 2l until d-2l : + draw (2l ,i)--(d/2-l,i) ; + draw (d/2+l,i)--(d-2l ,i) ; + endfor ; + elseif button_type=105 : + fill fullcircle scaled (.2d) shifted (.5d,.7d) ; + fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ; + clip currentpicture to p ; + draw p ; + elseif button_type=106 : + draw (2l,2l)--(d-2l,d-2l) ; + draw (d-2l,2l)--(2l,d-2l) ; + elseif button_type=107 : + p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ; + fill p ; draw p ; + draw (.5d,2l) ; + elseif button_type=108 : + draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ; + elseif button_type=109 : + draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ; + elseif button_type=110 : + button_linewidth := button_linewidth/2 ; + draw p enlarged (-2l,-l) ; + for i=2l step l until d-2l : + draw (3l,i)--(d-3l,i) ; + endfor ; + fi ; + +enddef ; + +endinput ; diff --git a/metapost/context/base/mp-char.mp b/metapost/context/base/mp-char.mp new file mode 100644 index 000000000..786c1f904 --- /dev/null +++ b/metapost/context/base/mp-char.mp @@ -0,0 +1,999 @@ +% to be cleaned up, namespace needed ! ! ! ! ! + +%D \module +%D [ file=mp-char.mp, +%D version=1998.10.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=charts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={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. + +if unknown context_tool : input mp-tool ; fi ; +if unknown context_shap : input mp-shap ; fi ; +if known context_char : endinput ; fi ; + +boolean context_char ; context_char := true ; + +% kan naar elders + +current_position := 0 ; + +def save_text_position (expr p) = % beware: clip shift needed + current_position := current_position + 1 ; + savedata + "\MPposition{" & decimal current_position & "}{" + & decimal xpart p & "}{" + & decimal ypart p & "}%" ; +enddef ; + +%D settings + +grid_width := 60pt ; grid_height := 40pt ; +shape_width := 45pt ; shape_height := 30pt ; + +chart_offset := 2pt ; + +color chart_background_color ; chart_background_color := white ; + +%D test mode + +boolean show_mid_points ; show_mid_points := false ; +boolean show_con_points ; show_con_points := false ; +boolean show_all_points ; show_all_points := false ; + +%D shapes + +color shape_line_color, shape_fill_color ; + +shape_line_width := 2pt ; +shape_line_color := .5white ; +shape_fill_color := .9white ; + +shape_node := 0 ; +shape_action := 24 ; +shape_procedure := 5 ; +shape_product := 12 ; +shape_decision := 14 ; +shape_archive := 19 ; +shape_loop := 35 ; +shape_wait := 6 ; +shape_subprocedure := 20 ; shape_sub_procedure := 20 ; +shape_singledocument := 32 ; shape_single_document := 32 ; +shape_multidocument := 33 ; shape_multi_document := 33 ; +shape_right := 66 ; +shape_left := 67 ; +shape_up := 68 ; +shape_down := 69 ; + +% vardef some_shape_path (expr type) == imported from mp-shap + +def show_shapes (expr n) = + + begin_chart(n,8,10) ; + show_con_points := true ; + for i=0 upto 7 : + for j=0 upto 9 : + new_shape(i+1,j+1,i*10+j); + endfor ; + endfor ; + end_chart ; + +enddef ; + +%D connections + +def new_chart = + + color connection_line_color ; + + connection_line_width := shape_line_width ; + connection_line_color := .8white ; + connection_smooth_size := 5pt ; + connection_arrow_size := 4pt ; + connection_dash_size := 3pt ; + + max_x := 6 ; + max_y := 4 ; + + numeric xypoint ; xypoint := 0 ; + + pair xypoints [] ; + + boolean xyfree [][] ; + path xypath [][] ; + numeric xysx [][] ; + numeric xysy [][] ; + color xyfill [][] ; + color xydraw [][] ; + numeric xyline [][] ; + boolean xypeep [][] ; + + numeric cpath ; cpath := 0 ; + path cpaths [] ; + numeric cline [] ; + color ccolor [] ; + boolean carrow [] ; + boolean cdash [] ; + boolean ccross [] ; + + boolean smooth ; smooth := true ; + boolean peepshape ; peepshape := false ; + boolean arrowtip ; arrowtip := true ; + boolean dashline ; dashline := false ; + boolean forcevalid ; forcevalid := false ; + boolean touchshape ; touchshape := false ; + boolean showcrossing ; showcrossing := false ; + + picture dash_pattern ; + + boolean reverse_y ; reverse_y := true ; + +enddef ; + +new_chart ; + +def y_pos (expr y) = + if reverse_y : max_y + 1 - y else : y fi +enddef ; + +def initialize_grid (expr maxx, maxy) = + begingroup ; + save i, j ; + max_x := maxx ; + max_y := maxy ; + dsp_x := 0 ; + dsp_y := 0 ; + for x=1 upto max_x : + for y=1 upto max_y : + xyfree [x][y] := true ; + xyfill [x][y] := shape_fill_color ; + xydraw [x][y] := shape_line_color ; + xyline [x][y] := shape_line_width ; + endfor ; + endfor ; + endgroup ; +enddef ; + +def scaled_to_grid = + xscaled grid_width yscaled grid_height +enddef ; + +def xy_offset (expr x, y) = + (x+.5,y+.5) +enddef ; + +def draw_shape (expr x, yy, p, sx, sy) = + begingroup ; + save y ; + y := y_pos(yy) ; + xypath [x][y] := (p xscaled sx yscaled sy) shifted xy_offset(x,y) ; + xyfree [x][y] := false ; + xysx [x][y] := sx ; + xysy [x][y] := sy ; + xyfill [x][y] := shape_fill_color ; + xydraw [x][y] := shape_line_color ; + xyline [x][y] := shape_line_width ; + xypeep [x][y] := peepshape ; + endgroup ; +enddef ; + +vardef i_point (expr x, y, p, t) = + begingroup ; + save q, ok ; + pair q ; + boolean ok ; + q := xypath[x][y] intersection_point ((p) shifted xy_offset(x,y)) ; + ok := true ; +% if xpart q < -.5 : ok := false ; q := (-.45,ypart q) fi ; +% if xpart q > .5 : ok := false ; q := ( .45,ypart q) fi ; +% if ypart q < -.5 : ok := false ; q := (xpart q,-.45) fi ; +% if ypart q > .5 : ok := false ; q := (xpart q, .45) fi ; + if not ok : + message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ; + fi ; + q + endgroup +enddef ; + +vardef trimmed (expr x, y, z, t) = + if touchshape and t : xyline[x][y]/z else : epsilon fi +enddef ; + +zfactor := 1/3 ; + +vardef xy_bottom (expr x, y, z, t) = + i_point (x, y, ((0,0)--(0,-2)) shifted (zfactor*z*xysx[x][y],0), "bottom") + shifted(0,-trimmed(x,y,grid_height,t)) +enddef ; + +vardef xy_top (expr x, y, z, t) = + i_point (x, y, ((0,0)--(0,2)) shifted (zfactor*z*xysx[x][y],0), "top") + shifted(0,trimmed(x,y,grid_height,t)) +enddef ; + +vardef xy_left (expr x, y, z, t) = + i_point (x, y, ((0,0)--(-2,0)) shifted (0,zfactor*z*xysy[x][y]), "left") + shifted(-trimmed(x,y,grid_width,t),0) +enddef ; + +vardef xy_right (expr x, y, z, t) = + i_point (x, y, ((0,0)--(2,0)) shifted (0,zfactor*z*xysy[x][y]), "right") + shifted(trimmed(x,y,grid_width,t),0) +enddef ; + +def flush_shapes = + for x=1 upto max_x : + for y=1 upto max_y : + flush_shape (x, y) ; + endfor ; + endfor ; +enddef ; + +def draw_connection_point (expr x, y, z) = + pickup pencircle scaled if (z=0): 2 fi xyline[x][y] ; + drawdot xy_bottom(x,y,z,false) scaled_to_grid withcolor (1,0,0) ; + drawdot xy_top (x,y,z,false) scaled_to_grid withcolor (0,1,0) ; + drawdot xy_left (x,y,z,false) scaled_to_grid withcolor (0,0,1) ; + drawdot xy_right (x,y,z,false) scaled_to_grid withcolor (1,1,0) ; +enddef ; + +def flush_shape (expr x, yy) = + begingroup ; + save y ; + y := y_pos(yy) ; + if not xyfree[x][y] : + pickup pencircle scaled xyline[x][y] ; + if xypeep[x][y] : + fill (xypath[x][y] peepholed (unitsquare shifted (x,y))) + scaled_to_grid withpen pencircle scaled 0 + withcolor chart_background_color ; + else : + fill xypath[x][y] scaled_to_grid withcolor xyfill[x][y] ; + fi ; + draw xypath[x][y] scaled_to_grid withcolor xydraw[x][y] ; + if show_con_points or show_all_points : + draw_connection_point (x, y, 0) ; + fi ; + if show_all_points : + for i=-1 upto 1 : + draw_connection_point (x, y, i) ; + endfor ; + fi ; + fi ; + endgroup ; +enddef ; + +vardef points_initialized (expr xfrom, yfrom, xto, yto, n) = + if not xyfree[xfrom][yfrom] and not xyfree[xto][yto] : + xypoint := n ; true + else : + xypoint := 0 ; false + fi +enddef ; + +def collapse_points = % this is now an mp-tool macro + % remove redundant points + n := 1 ; + for i=2 upto xypoint: + if not (xypoints[i]=xypoints[n]) : + n := n + 1 ; + xypoints[n] := xypoints[i] + fi ; + endfor ; + xypoint := n ; + % make straight lines + if xypoints[2]=xypoints[xypoint-1] : + xypoints[3] := xypoints[xypoint] ; + xypoint := 3 ; + fi ; +enddef ; + +vardef smooth_connection (expr a,b) = + sx := connection_smooth_size/grid_width ; + sy := connection_smooth_size/grid_height ; + if ypart a = ypart b : + a shifted (if xpart a >= xpart b : - fi sx,0) +% a shifted (sx*xpart unitvector(b-a),0) + else : + a shifted (0,if ypart a >= ypart b : - fi sy) +% a shifted (0,sy*ypart unitvector(b-a)) + fi +enddef ; + +vardef trim_points = + begingroup + save p, a, b, d, i ; path p ; pair d ; + p := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; + if touchshape : + a := shape_line_width/grid_width ; + b := shape_line_width/grid_height ; + else : + a := epsilon ; + b := epsilon ; + fi ; + d := direction infinity of p ; + xypoints[xypoint] := xypoints[xypoint] shifted + if xpart d < 0 : (+a,0) ; + elseif xpart d > 0 : (-a,0) ; + elseif ypart d < 0 : (0,+b) ; + elseif ypart d > 0 : (0,-b) ; + else : origin ; + fi ; + d := direction 0 of p ; + xypoints[1] := xypoints[1] shifted + if xpart d < 0 : (-a,0) ; + elseif xpart d > 0 : (+a,0) ; + elseif ypart d < 0 : (0,-b) ; + elseif ypart d > 0 : (0,+b) ; + else : origin ; + fi ; + endgroup +enddef ; + +vardef trim_points = enddef ; + +vardef connection_path = + if reverse_connection : reverse fi (xypoints[1]-- + for i=2 upto xypoint-1 : + if smooth : + smooth_connection(xypoints[i],xypoints[i-1]) .. + controls xypoints[i] and xypoints[i] .. + smooth_connection(xypoints[i],xypoints[i+1]) -- + else : + xypoints[i]-- + fi + endfor + xypoints[xypoint]) +enddef ; + +% vardef connection_path = +% sx := connection_smooth_size/grid_width ; +% sy := connection_smooth_size/grid_height ; +% if reverse_connection : reverse fi +% (for i=1 upto xypoint-1 : xypoints[i] -- endfor xypoints[xypoint]) +% if smooth : cornered max(sx,sy) fi +% enddef ; +% +% primarydef p cornered c = +% if cycle p : +% ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) -- +% for i=1 upto length(p) : +% (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) -- +% (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) .. +% controls point i of p .. +% endfor cycle) +% else : +% ((point 0 of p) -- +% for i=1 upto length(p)-1 : +% (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) -- +% (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) .. +% controls point i of p .. +% endfor +% (point length(p) of p)) +% fi +% enddef ; + +def draw_connection = + if xypoint>0 : + collapse_points ; + trim_points ; + cpath := cpath + 1 ; + cpaths[cpath] := connection_path scaled_to_grid ; + cline[cpath] := connection_line_width ; + ccolor[cpath] := connection_line_color ; + carrow[cpath] := arrowtip ; + cdash[cpath] := dashline ; + ccross[cpath] := showcrossing ; + else : + message("no connection defined") ; + fi ; + reverse_connection := false ; +enddef ; + +def flush_connections = + pair ip ; + boolean crossing ; + ahlength := connection_arrow_size ; + dash_pattern := dashpattern(on connection_dash_size off connection_dash_size ) ; + for i=1 upto cpath : + if ccross[i] : + crossing := false ; + for j=1 upto i : + %if not ((point infinity of cpaths[i] = point infinity of cpaths[j]) or + % (point 0 of cpaths[i] = point 0 of cpaths[j])) : + if not (point infinity of cpaths[i] = point infinity of cpaths[j]) : + ip := cpaths[i] intersection_point cpaths[j] ; + if intersection_found : crossing := true fi ; + fi ; + endfor ; + if crossing : + pickup pencircle scaled 2cline[i] ; + %draw cpaths[i] withcolor chart_background_color ; + path cp ; cp := cpaths[i] ; + cp := cp cutbefore point .05 length cp of cp ; + cp := cp cutafter point .95 length cp of cp ; + draw cp withcolor chart_background_color ; + fi ; + fi ; + pickup pencircle scaled cline[i] ; + if carrow[i] : + if cdash[i] : + drawarrow cpaths[i] withcolor ccolor[i] dashed dash_pattern ; + else : + drawarrow cpaths[i] withcolor ccolor[i] ; + fi ; + else : + if cdash[i] : + draw cpaths[i] withcolor ccolor[i] dashed dash_pattern ; + else : + draw cpaths[i] withcolor ccolor[i] ; + fi ; + fi ; + draw_midpoint (i) ; + endfor ; +enddef ; + +def draw_midpoint (expr n) = + begingroup + save p ; + pair p ; + p := point .5*length(cpaths[n]) of cpaths[n]; + pickup pencircle scaled 2cline[n] ; + save_text_position (p) ; + if show_mid_points : + drawdot p withcolor .7white ; + fi ; + endgroup ; +enddef ; + +boolean reverse_connection ; reverse_connection := false ; + +vardef up_on_grid (expr n) = + (xpart xypoints[n],(ypart xypoints[n]+1) div 1) +enddef ; + +vardef down_on_grid (expr n) = + (xpart xypoints[n],(ypart xypoints[n]) div 1) +enddef ; + +vardef left_on_grid (expr n) = + ((xpart xypoints[n]) div 1, ypart xypoints[n]) +enddef ; + +vardef right_on_grid (expr n) = + ((xpart xypoints[n]+1) div 1, ypart xypoints[n]) +enddef ; + +vardef x_on_grid (expr n, xfrom, xto, zfrom) = + if (xfrom=xto) and not (zfrom=0) : + if (zfrom=1) : right_on_grid(2) else : left_on_grid(2) fi + elseif xpart xypoints[1] < xpart xypoints[6] : + right_on_grid(n) + else : + left_on_grid(n) + fi +enddef ; + +vardef y_on_grid (expr n, yfrom, yto, zfrom) = + if (yfrom=yto) and not (zfrom=0) : + if (zfrom=1) : up_on_grid(2) else : down_on_grid(2) fi + elseif ypart xypoints[1] < ypart xypoints[6] : + up_on_grid(n) + else : + down_on_grid(n) + fi +enddef ; + +vardef xy_on_grid (expr n, m) = + (xpart xypoints[n], ypart xypoints[m]) +enddef ; + +vardef down_to_grid (expr a,b) = + (xpart xypoints[a], + ypart xypoints[if ypart xypoints[a]ypart xypoints[b]:a else:b fi]) +enddef ; + +vardef left_to_grid (expr a,b) = + (xpart xypoints[if xpart xypoints[a]xpart xypoints[b]:a else:b fi], + ypart xypoints[a]) +enddef ; + +% vardef boundingboxfraction(expr p, f) = +% ((boundingbox p) enlarged (-f*bbwidth(p),-f*bbheight(p))) +% enddef ; + +vardef valid_connection (expr xfrom, yfrom, xto, yto) = + begingroup ; + save ok, vc, pp ; + boolean ok ; + % check for slanted lines + ok := true ; + for i=1 upto xypoint-1 : + if not ((xpart xypoints[i]=xpart xypoints[i+1]) or + (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ; + fi ; + endfor ; + if not ok : + %message("slanted"); + false + elseif forcevalid : + %message("force"); + true + elseif (xfrom=xto) and (yfrom=yto) : + %message("self"); + false + else : + % check for crossing shapes + pair vc ; + path pp ; + + pair xyfirst, xylast ; + xyfirst := xypoints[1] ; + xylast := xypoints[xypoint] ; + trim_points ; + pp := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; + xypoints[1] := xyfirst ; + xypoints[xypoint] := xylast ; + + for i=1 upto max_x : + for j=1 upto max_y : % was bug: xfrom,yto + if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) : + if not xyfree[i][j] : + vc := pp intersection_point xypath[i][j] ; + if intersection_found : ok := false fi ; + fi ; + fi ; + endfor ; + endfor ; + %if not ok: message("crossing") ; fi ; + ok + fi + endgroup +enddef ; + +def connect_top_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := up_on_grid(1) ; + xypoints[5] := down_on_grid(6) ; + xypoints[3] := up_to_grid(2,5) ; + xypoints[4] := up_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + %%%% begin experiment + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + xypoints[4] := xypoints[4] shifted (dsp_x,0) ; + if dsp_y>0 : + xypoints[2] := xypoints[2] shifted (0,dsp_y) ; + xypoints[3] := xypoints[3] shifted (0,dsp_y) ; + elseif dsp_y<0 : + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + xypoints[5] := xypoints[5] shifted (0,dsp_y) ; + fi + %%%% end experiment + draw_connection ; + fi ; +enddef ; + +def connect_left_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_right(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[5] := right_on_grid(6) ; + xypoints[3] := left_to_grid(2,5) ; + xypoints[4] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_top(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[4] := up_on_grid(5) ; + xypoints[3] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[4] := down_on_grid(5) ; + xypoints[3] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_top(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[4] := up_on_grid(5) ; + xypoints[3] := right_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[4] := down_on_grid(5) ; + xypoints[3] := right_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + %%%% begin experiment + xypoints[2] := xypoints[2] shifted (dsp_x,0) ; + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + if dsp_y>0 : + xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; + xypoints[4] := xypoints[4] shifted (0,-dsp_y) ; + elseif dsp_y<0 : + xypoints[3] := xypoints[3] shifted (0,dsp_y) ; + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + fi + %%%% end experiment + draw_connection ; + fi ; +enddef ; + +def connect_left_left (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_left(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[5] := left_on_grid(6) ; + xypoints[3] := left_to_grid(2,5) ; + xypoints[4] := left_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_right(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[5] := right_on_grid(6) ; + xypoints[3] := right_to_grid(2,5) ; + xypoints[4] := right_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_top_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_top(xto,yto,zto,true) ; + xypoints[2] := up_on_grid(1) ; + xypoints[5] := up_on_grid(6) ; + xypoints[3] := up_to_grid(2,5) ; + xypoints[4] := up_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_bottom_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_bottom(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := down_on_grid(1) ; + xypoints[5] := down_on_grid(6) ; + xypoints[3] := down_to_grid(2,5) ; + xypoints[4] := down_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + %%%% begin experiment + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + xypoints[4] := xypoints[4] shifted (dsp_x,0) ; + if dsp_y<0 : + xypoints[2] := xypoints[2] shifted (0,-dsp_y) ; + xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; + elseif dsp_y>0 : + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + xypoints[5] := xypoints[5] shifted (0,dsp_y) ; + fi + %%%% end experiment + draw_connection ; + fi ; +enddef ; + +def connect_bottom_top (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_top_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_right_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_right (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_top_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_bottom_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_top_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_right_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_bottom_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_right_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def draw_test_shape (expr x, y) = + draw_shape(x,y,fullcircle, .7, .7) ; +enddef ; + +def draw_test_shapes = + for i=1 upto max_x : + for j=1 upto max_y : + draw_test_shape(i,j) ; + endfor ; + endfor ; +enddef; + +def draw_test_area = + pickup pencircle scaled .5shape_line_width ; + draw (unitsquare xscaled max_x yscaled max_y shifted (1,1)) + scaled_to_grid withcolor blue ; +enddef ; + +def show_connection (expr n, m) = + + begin_chart(100+n,6,6) ; + + draw_test_area ; + + smooth := true ; + arrowtip := true ; + dashline := true ; + + draw_test_shape(2,2) ; draw_test_shape(4,5) ; + draw_test_shape(3,3) ; draw_test_shape(5,1) ; + draw_test_shape(2,5) ; draw_test_shape(1,3) ; + draw_test_shape(6,2) ; draw_test_shape(4,6) ; + + if (m=1) : + connect_top_bottom (2,2,0) (4,5,0) ; + connect_top_bottom (3,3,0) (5,1,0) ; + connect_top_bottom (2,5,0) (1,3,0) ; + connect_top_bottom (6,2,0) (4,6,0) ; + elseif (m=2) : + connect_top_top (2,2,0) (4,5,0) ; + connect_top_top (3,3,0) (5,1,0) ; + connect_top_top (2,5,0) (1,3,0) ; + connect_top_top (6,2,0) (4,6,0) ; + elseif (m=3) : + connect_bottom_bottom (2,2,0) (4,5,0) ; + connect_bottom_bottom (3,3,0) (5,1,0) ; + connect_bottom_bottom (2,5,0) (1,3,0) ; + connect_bottom_bottom (6,2,0) (4,6,0) ; + elseif (m=4) : + connect_left_right (2,2,0) (4,5,0) ; + connect_left_right (3,3,0) (5,1,0) ; + connect_left_right (2,5,0) (1,3,0) ; + connect_left_right (6,2,0) (4,6,0) ; + elseif (m=5) : + connect_left_left (2,2,0) (4,5,0) ; + connect_left_left (3,3,0) (5,1,0) ; + connect_left_left (2,5,0) (1,3,0) ; + connect_left_left (6,2,0) (4,6,0) ; + elseif (m=6) : + connect_right_right (2,2,0) (4,5,0) ; + connect_right_right (3,3,0) (5,1,0) ; + connect_right_right (2,5,0) (1,3,0) ; + connect_right_right (6,2,0) (4,6,0) ; + elseif (m=7) : + connect_left_top (2,2,0) (4,5,0) ; + connect_left_top (3,3,0) (5,1,0) ; + connect_left_top (2,5,0) (1,3,0) ; + connect_left_top (6,2,0) (4,6,0) ; + elseif (m=8) : + connect_left_bottom (2,2,0) (4,5,0) ; + connect_left_bottom (3,3,0) (5,1,0) ; + connect_left_bottom (2,5,0) (1,3,0) ; + connect_left_bottom (6,2,0) (4,6,0) ; + elseif (m=9) : + connect_right_top (2,2,0) (4,5,0) ; + connect_right_top (3,3,0) (5,1,0) ; + connect_right_top (2,5,0) (1,3,0) ; + connect_right_top (6,2,0) (4,6,0) ; + else : + connect_right_bottom (2,2,0) (4,5,0) ; + connect_right_bottom (3,3,0) (5,1,0) ; + connect_right_bottom (2,5,0) (1,3,0) ; + connect_right_bottom (6,2,0) (4,6,0) ; + fi ; + + end_chart ; + +enddef ; + +def show_connections = + for f=1 upto 10 : + show_connection(f,f) ; + endfor ; +enddef ; + +%D charts + +def clip_chart (expr minx, miny, maxx, maxy) = + cmin_x := minx ; + cmax_x := maxx ; + cmin_y := miny ; + cmax_y := maxy ; +enddef ; + +def begin_chart (expr n, maxx, maxy) = + new_chart ; + chart_figure := n ; + chart_scale := 1 ; + if chart_figure>0: beginfig(chart_figure) ; fi ; + startsavingdata ; + initialize_grid (maxx, maxy) ; + bboxmargin := 0 ; + cmin_x := 1 ; + cmax_x := maxx ; + cmin_y := 1 ; + cmax_y := maxy ; +enddef ; + +def end_chart = + flush_shapes ; + flush_connections ; + cmin_x := cmin_x ; + cmax_x := cmin_x+cmax_x ; + cmin_y := cmin_y-1 ; + cmax_y := cmin_y+cmax_y ; + if reverse_y : + cmin_y := y_pos(cmin_y) ; + cmax_y := y_pos(cmax_y) ; + fi ; + path p ; + p := (((cmin_x,cmin_y)--(cmax_x,cmin_y)-- + (cmax_x,cmax_y)--(cmin_x,cmax_y)--cycle)) + scaled_to_grid ; + %draw p withcolor red ; + p := p enlarged chart_offset ; + clip currentpicture to p ; + setbounds currentpicture to p ; + savedata + "\MPclippath{" & + decimal xpart llcorner p & "}{" & + decimal ypart llcorner p & "}{" & + decimal xpart urcorner p & "}{" & + decimal ypart urcorner p & "}%" ; + savedata + "\MPareapath{" & + decimal (xpart llcorner p + 2chart_offset) & "}{" & + decimal (ypart llcorner p + 2chart_offset) & "}{" & + decimal (xpart urcorner p - 2chart_offset) & "}{" & + decimal (ypart urcorner p - 2chart_offset) & "}%" ; + currentpicture := currentpicture scaled chart_scale ; + stopsavingdata ; + if chart_figure>0: endfig ; fi ; +enddef ; + +def new_shape (expr x, y, n) = + if known n : + if (x>0) and (x<=max_x) and (y>0) and (y<=max_y) : + sx := shape_width/grid_width ; + sy := shape_height/grid_height ; + draw_shape(x,y,some_shape_path(n), sx, sy) ; + else : + message ("shape outside grid ignored") ; + fi ; + else + message ("shape not known" ) ; + fi ; +enddef ; + +def begin_sub_chart = + begingroup ; + save shape_line_width , connection_line_width ; + save shape_line_color, shape_fill_color, connection_line_color ; + color shape_line_color, shape_fill_color, connection_line_color ; + save smooth, arrowtip, dashline, peepshape ; + boolean smooth, arrowtip, dashline, peepshape ; +enddef ; + +def end_sub_chart = + endgroup ; +enddef ; + +%D done + +endinput ; + +%D testing + +show_shapes(100) ; + +end + +%D more testing + +show_connections ; + +begin_chart (1,4,5) ; + %clip_chart(1,1,1,2) ; + new_shape (1,1,31) ; + new_shape (1,2,3) ; + new_shape (4,4,5) ; + connect_top_left (1,1,0) (4,4,0) ; + connect_bottom_top (1,2,0) (4,4,0) ; + connect_left_right (1,2,0) (1,1,0) ; +end_chart ; + +end diff --git a/metapost/context/base/mp-chem.mp b/metapost/context/base/mp-chem.mp new file mode 100644 index 000000000..c70dafd85 --- /dev/null +++ b/metapost/context/base/mp-chem.mp @@ -0,0 +1,761 @@ +%D \module +%D [ file=mp-chem.mp, +%D version=2009.05.13, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=chemicals, +%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 licen-en.pdf for +%C details. + +%D This module in incomplete and experimental. + +% either consistent setting or not + +if known chem_reset : endinput ; fi ; + +numeric + chem_width, chem_radical_min, chem_radical_max, chem_text_max, chem_circle_radius, + chem_rotation, chem_adjacent, chem_stack, chem_substituent, chem_direction, chem_setting_scale, + chem_setting_offset, chem_text_offset, chem_picture_offset, chem_center_offset, chem_substituent_offset, + chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ; + +boolean + chem_setting_axis, + chem_setting_fixedwidth, chem_setting_fixedheight, + chem_doing_pb, chem_text_trace ; + +path + chem_setting_bbox ; + +pair + chem_shift, + chem_adjacent_p, chem_substituent_p, chem_direction_p, chem_move_p ; + +numeric + chem_width[], chem_angle[], chem_start[], chem_initialrot[], chem_initialmov[] ; + +pair + chem_stack_d[], + chem_b_zero[], chem_n_zero[], + chem_r_max[], chem_r_min[], + chem_r_zero[], chem_mr_zero[], chem_pr_zero[], chem_crz_zero[], + chem_rt_zero[], chem_rtt_zero[], chem_rbt_zero[], + chem_mid_zero[] ; + +path + chem_b_path[], chem_bx_path[], chem_eb_path[], chem_sr_path[], chem_br_path[], + chem_sb_path[], chem_msb_path[], chem_psb_path[], + chem_s_path[], chem_ss_path[], chem_mss_path[], chem_pss_path[], + chem_e_path[], chem_sd_path[], chem_bb_path[], chem_oe_path[], + chem_bd_path[], chem_bw_path[], + chem_ddt_path[], chem_ddb_path[], chem_ldt_path[], chem_ldb_path[], chem_rdt_path[], chem_rdb_path[], + chem_dbl_path[], chem_dbr_path[], + chem_ad_path[], chem_au_path[], + chem_r_path[], chem_rl_path[], chem_rr_path[], + chem_rb_path[], chem_prb_path[], chem_mrb_path[], + chem_srl_path[], chem_srr_path[], + chem_msr_path[], chem_psr_path[], + chem_mr_path[], chem_pr_path[], + chem_c_path[], chem_cc_path[], + chem_midt_path[], chem_midb_path[], chem_midst_path[], chem_midsb_path[] ; + +chem_setting_scale := 1 ; +chem_base_width := 40pt ; +chem_text_offset := 3pt ; +chem_center_offset := 6pt ; +chem_picture_offset := 10pt ; +chem_substituent_offset := 10pt ; +chem_radical_min := 1.25 ; +chem_radical_max := 1.50 ; +chem_text_min := 0.75 ; +chem_text_max := 1.75 ; +chem_circle_radius := 0.80 ; +chem_circle_radius := 1.10 ; +chem_rotation := 1 ; +chem_adjacent := 0 ; +chem_substituent := 0 ; +chem_direction := 0 ; +chem_stack_n := 0 ; +chem_doing_pb := false ; +chem_shift := origin ; +chem_dot_factor := 4 ; +chem_text_trace := false ; +chem_bd_n := 4 ; +chem_bw_n := 4 ; +chem_bd_angle := 4 ; +chem_bb_angle := 4 ; + +vardef chem_start_structure(expr n, l, r, t, b, scale, axis, fixedwidth, fixedheight, offset) = + chem_setting_axis := axis ; + chem_setting_l := l * scale ; + chem_setting_r := r * scale ; + chem_setting_t := t * scale ; + chem_setting_b := b * scale ; + chem_setting_fixedwidth := fixedwidth ; + chem_setting_fixedheight := fixedheight ; + chem_setting_offset := offset ; + if scale <> chem_setting_scale : + chem_setting_scale := scale ; + chem_init_all ; + fi ; + chem_rotation := 1 ; + chem_adjacent := 0 ; + chem_substituent := 0 ; + chem_direction := 0 ; + chem_stack_n := 0 ; + chem_doing_pb := false ; + chem_shift := origin ; +enddef ; + +def chem_stop_structure = + currentpicture := currentpicture shifted - chem_shift ; + % axis here + if chem_setting_fixedwidth : + chem_setting_l := - xpart llcorner currentpicture ; + chem_setting_r := xpart urcorner currentpicture ; + fi ; + if chem_setting_fixedheight : + chem_setting_t := ypart urcorner currentpicture ; + chem_setting_b := - ypart llcorner currentpicture ; + fi ; + chem_setting_bbox := + (-chem_setting_l,-chem_setting_b) -- ( chem_setting_r,-chem_setting_b) -- + ( chem_setting_r, chem_setting_t) -- (-chem_setting_l, chem_setting_t) -- cycle ; + % maybe put it behind the picture + if chem_setting_axis : + save stp ; stp := chem_base_width/ 2 * chem_setting_scale ; + save siz ; siz := chem_base_width/10 * chem_setting_scale ; + draw (-chem_setting_l,0) -- (chem_setting_r,0) withcolor blue ; + draw (0,-chem_setting_b) -- (0,chem_setting_t) withcolor blue ; + for i = 0 step stp until chem_setting_r : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ; + for i = 0 step -stp until -chem_setting_l : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ; + for i = 0 step stp until chem_setting_t : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ; + for i = 0 step -stp until -chem_setting_b : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ; + draw chem_setting_bbox withcolor blue ; + fi ; + setbounds currentpicture to chem_setting_bbox ; +enddef ; + +def chem_start_component = +enddef ; +def chem_stop_component = +enddef ; + +def chem_pb = +% draw boundingbox currentpicture withpen pencircle scaled 1mm withcolor blue ; +% draw origin withpen pencircle scaled 2mm withcolor blue ; + chem_doing_pb := true ; +enddef ; +def chem_pe = +% draw boundingbox currentpicture withpen pencircle scaled .5mm withcolor red ; +% draw origin withpen pencircle scaled 1mm withcolor red ; + currentpicture := currentpicture shifted - chem_shift ; +% draw origin withpen pencircle scaled .5mm withcolor green ; + chem_shift := origin ; + chem_doing_pb := false ; +enddef ; + +vardef chem_do (expr p) = + if chem_doing_pb : + chem_doing_pb := false ; +% save pp ; pair pp ; pp := point 1 of ((origin -- p) enlonged chem_picture_offset) ; +% currentpicture := currentpicture shifted - pp ; +% chem_shift := chem_shift - center pp ; + currentpicture := currentpicture shifted - p ; + chem_shift := chem_shift - p ; + origin % nullpicture + else : + p + fi +enddef ; + +vardef chem_b (expr n, f, t, r, c) = + chem_draw (n, chem_b_path[n], f, t, r, c) ; +enddef ; +vardef chem_sb (expr n, f, t, r, c) = + chem_draw (n, chem_sb_path[n], f, t, r, c) ; +enddef ; +vardef chem_s (expr n, f, t, r, c) = + chem_draw (n, chem_s_path[n], f, t, r, c) ; +enddef ; +vardef chem_ss (expr n, f, t, r, c) = + chem_draw (n, chem_ss_path[n], f, t, r, c) ; +enddef ; +vardef chem_mid (expr n, r, c) = + chem_draw_fixed (n, chem_midt_path[n], r, c) ; + chem_draw_fixed (n, chem_midb_path[n], r, c) ; +enddef ; +vardef chem_mids (expr n, r, c) = + chem_draw_fixed (n, chem_midst_path[n], r, c) ; + chem_draw_fixed (n, chem_midsb_path[n], r, c) ; +enddef ; +vardef chem_mss (expr n, f, t, r, c) = + chem_draw (n, chem_mss_path[n], f, t, r, c) ; +enddef ; +vardef chem_pss (expr n, f, t, r, c) = + chem_draw (n, chem_pss_path[n], f, t, r, c) ; +enddef ; +vardef chem_msb (expr n, f, t, r, c) = + chem_draw (n, chem_msb_path[n], f, t, r, c) ; +enddef ; +vardef chem_psb (expr n, f, t, r, c) = + chem_draw (n, chem_psb_path[n], f, t, r, c) ; +enddef ; +vardef chem_eb (expr n, f, t, r, c) = + chem_draw (n, chem_eb_path[n], f, t, r, c) ; +enddef ; +vardef chem_db (expr n, f, t, r, c) = + if n = 1 : + chem_draw (n, chem_msb_path [n], f, t, r, c) ; + chem_draw (n, chem_psb_path [n], f, t, r, c) ; + else : + chem_draw (n, chem_dbl_path [n], f, t, r, c) ; + chem_draw (n, chem_dbr_path [n], f, t, r, c) ; + fi ; +enddef ; +vardef chem_er (expr n, f, t, r, c) = + chem_draw (n, chem_rl_path[n], f, t, r, c) ; + chem_draw (n, chem_rr_path[n], f, t, r, c) ; +enddef ; +vardef chem_dr (expr n, f, t, r, c) = + chem_draw (n, chem_srl_path[n], f, t, r, c) ; + chem_draw (n, chem_srr_path[n], f, t, r, c) ; +enddef ; +vardef chem_ad (expr n, f, t, r, c) = + chem_draw_arrow(n, chem_ad_path[n], f, t, r, c) ; +enddef ; +vardef chem_au (expr n, f, t, r, c) = + chem_draw_arrow(n, chem_au_path[n], f, t, r, c) +enddef ; +vardef chem_r (expr n, f, t, r, c) = + if n < 0 : + chem_draw_vertical (n, chem_r_path[n], f, t, r, c) ; + else : + chem_draw (n, chem_r_path[n], f, t, r, c) ; + fi ; +enddef ; +vardef chem_rd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_r_path[n], f, t, r, c) +enddef ; +vardef chem_mrd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_mr_path[n], f, t, r, c) +enddef ; +vardef chem_prd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_pr_path[n], f, t, r, c) +enddef ; +vardef chem_br (expr n, f, t, r, c) = + chem_fill (n, chem_br_path[n], f, t, r, c ) +enddef ; +vardef chem_rb (expr n, f, t, r, c) = + chem_fill (n, chem_rb_path[n], f, t, r, c) +enddef ; +vardef chem_mrb (expr n, f, t, r, c) = + chem_fill (n, chem_mrb_path[n], f, t, r, c) +enddef ; +vardef chem_prb (expr n, f, t, r, c) = + chem_fill (n, chem_prb_path[n], f, t, r, c) +enddef ; +vardef chem_mr (expr n, f, t, r, c) = + if n < 0 : + chem_draw_vertical(n, chem_mr_path[n], f, t, r, c) + else : + chem_draw (n, chem_mr_path[n], f, t, r, c) + fi +enddef ; +vardef chem_pr (expr n, f, t, r, c) = + if n < 0 : + chem_draw_vertical(n, chem_pr_path[n], f, t, r, c) + else : + chem_draw (n, chem_pr_path[n], f, t, r, c) + fi +enddef ; +vardef chem_sr (expr n, f, t, r, c) = + chem_draw (n, chem_sr_path[n], f, t, r, c) +enddef ; +vardef chem_msr (expr n, f, t, r, c) = + chem_draw (n, chem_msr_path[n], f, t, r, c) +enddef ; +vardef chem_psr (expr n, f, t, r, c) = + chem_draw (n, chem_psr_path[n], f, t, r, c) +enddef ; +vardef chem_c (expr n, f, t, r, c) = + chem_draw (n, chem_c_path[n], f, t, r, c) +enddef ; +vardef chem_cc (expr n, f, t, r, c) = + chem_draw (n, chem_cc_path[n], f, f, r, c) +enddef ; +vardef chem_cd (expr n, f, t, r, c) = + chem_dashed_connected (n, chem_c_path[n], f, t, r, c) +enddef ; +vardef chem_ccd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_cc_path[n], f, f, r, c) +enddef ; +vardef chem_rn (expr n, i, t) = + chem_rt (n,i,t) ; +enddef ; +vardef chem_rtn (expr n, i, t) = + chem_rtt(n,i,t) ; +enddef ; +vardef chem_rbn (expr n, i, t) = + chem_rbt(n,i,t) ; +enddef ; +vardef chem_tb (expr n, f, t, r, c) = % one + chem_draw (n, chem_msb_path[n], f, t, r, c) ; + chem_draw (n, chem_sb_path [n], f, t, r, c) ; + chem_draw (n, chem_psb_path[n], f, t, r, c) ; +enddef ; +vardef chem_ep (expr n, f, t, r, c) = % one + chem_draw (n, chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_es (expr n, f, t, r, c) = % one + chem_draw_dot (n, center chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_ed (expr n, f, t, r, c) = % one + chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ; + chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_et (expr n, f, t, r, c) = % one + chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ; + chem_draw_dot (n, center chem_e_path[n], f, t, r, c) ; + chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_sd (expr n, f, t, r, c) = % one + chem_draw (n, chem_ddt_path[n], f, t, r, c) ; + chem_draw (n, chem_ddb_path[n], f, t, r, c) ; +enddef ; +vardef chem_rdd (expr n, f, t, r, c) = % one + chem_draw (n, chem_ldt_path[n], f, t, r, c) ; + chem_draw (n, chem_ldb_path[n], f, t, r, c) ; + chem_draw (n, chem_psb_path[n], f, t, r, c) ; +enddef ; +vardef chem_ldd (expr n, f, t, r, c) = % one + chem_draw (n, chem_msb_path[n], f, t, r, c) ; + chem_draw (n, chem_rdt_path[n], f, t, r, c) ; + chem_draw (n, chem_rdb_path[n], f, t, r, c) ; +enddef ; +vardef chem_hb (expr n, f, t, r, c) = % one + chem_draw_dot (n, point 0 of chem_sb_path[n], f, t, r, c) ; + chem_draw_dot (n, center chem_sb_path[n], f, t, r, c) ; + chem_draw_dot (n, point 1 of chem_sb_path[n], f, t, r, c) ; +enddef ; +vardef chem_bb (expr n, f, t, r, c) = % one + if n < 0 : + chem_fill (n, chem_bb_path[n], 1, 1, r, c) ; + chem_b (n, f, t, r, c) ; + else : + chem_fill (n, chem_bb_path[n], f, t, r, c) ; + fi ; +enddef ; +vardef chem_oe (expr n, f, t, r, c) = % one + chem_draw (n, chem_oe_path[n], f, t, r, c) ; +enddef ; +vardef chem_bd (expr n, f, t, r, c) = % one + for i=0 upto 5 : + chem_draw (n, subpath (2i,2i+1) of chem_bd_path[n], f, t, r, c) ; + endfor ; +enddef ; +vardef chem_bw (expr n, f, t, r, c) = % one + chem_draw (n, chem_bw_path[n], f, t, r, c) ; +enddef ; + +vardef chem_z_zero@#(text t) = + chem_text@#(t, chem_do(origin)) ; +enddef ; +vardef chem_cz_zero@#(text t) = + chem_text@#(t, chem_do(origin)) ; +enddef ; +vardef chem_z@#(expr n, p) (text t) = + if p = 0 : + chem_text@#(t, chem_do(origin)) ; + else : + chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_cz@#(expr n, p) (text t) = + if n = 1 : + chem_c_text(t, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ; + else : + chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_midz@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_mid_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_rz@#(expr n, p) (text t) = + if n < 0 : + % quite special + chem_text@#(t, chem_do(chem_r_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; + else : + chem_text@#(t, chem_do(chem_r_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_crz@#(expr n, p) (text tx) = + chem_text(tx, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_mrz@#(expr n, p) (text t) = + if n < 0 : + % quite special + chem_text@#(t, chem_do(chem_mr_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; + else : + chem_text@#(t, chem_do(chem_mr_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_prz@#(expr n, p) (text t) = + if n < 0 : + % quite special + chem_text@#(t, chem_do(chem_pr_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; + else : + chem_text@#(t, chem_do(chem_pr_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_rt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_rtt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_rbt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_zt@#(expr n, p) (text t) = + if n = 1 : + chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; + else : + chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_zn@#(expr n, p) (text t) = + if n = 1 : + chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; + else : + chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_zbt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_zbn@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_ztt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_ztn@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; +enddef ; + +vardef chem_symbol(expr t) = + draw textext(t) ; +enddef ; + +vardef chem_text@#(expr txt, z) = % adapted copy of thelabel@ + save p ; picture p ; + p := textext(txt) ; + p := p + if (labtype@# >= 10) : shifted (0,ypart center p) fi + shifted (z + chem_text_offset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) ; + if chem_text_trace : + draw z withpen pencircle scaled 2pt withcolor red ; + draw boundingbox p withpen pencircle scaled 1pt withcolor red ; + fi ; + draw p +enddef ; + +vardef chem_c_text(expr txt, z) = % adapted copy of thelabel@ + save p ; picture p ; p := textext(txt) ; + save b ; path b ; b := (boundingbox p) shifted z ; + save a ; pair a ; a := (origin--z) intersection_point b ; + if intersection_found : + draw p shifted (z enlonged arclength(a -- center b)) ; + else : + draw p shifted z ; + fi +% draw b withcolor green ; +% draw a withcolor red ; +enddef ; + +vardef chem_ang (expr n, d) = + ((-1 * (d-1) * chem_angle[n]) + (-chem_rotation+1) * 90 + chem_start[n]) % no ; +enddef ; +vardef chem_rot (expr n, d) = + chem_rotation := d ; +enddef ; +vardef chem_adj (expr n, d) = + chem_adjacent := d ; +enddef ; +vardef chem_sub (expr n, d) = + chem_substituent := d ; +enddef ; +vardef chem_dir (expr n, d) = + if n = 1 : + chem_direction_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+1))) ; + currentpicture := currentpicture shifted chem_direction_p ; + chem_shift := chem_shift + chem_direction_p ; + fi ; +enddef ; +vardef chem_mov (expr n, d) = + if d = 0 : + currentpicture := currentpicture shifted - chem_shift ; + chem_shift := origin ; + else : + chem_move_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+chem_initialmov[n]))) ; + currentpicture := currentpicture shifted chem_move_p ; + chem_shift := chem_shift + chem_move_p ; + fi ; +enddef ; +vardef chem_off (expr n, d) = + if (d = 1) or (d = 2) or (d = 8) : % positive + currentpicture := currentpicture shifted (-chem_setting_offset,0) ; + chem_shift := chem_shift + (-chem_setting_offset,0) + elseif (d = 4) or (d = 5) or (d = 6) : % negative + currentpicture := currentpicture shifted ( chem_setting_offset,0) ; + chem_shift := chem_shift + ( chem_setting_offset,0) + fi ; +enddef ; + +vardef chem_set(expr n, m) = + if chem_adjacent > 0 : + chem_adjacent_d := xpart chem_b_zero[n] + xpart chem_b_zero[m] ; + if chem_adjacent = 1 : chem_adjacent_p := (-chem_adjacent_d, 0) ; + elseif chem_adjacent = 2 : chem_adjacent_p := (0, -chem_adjacent_d) ; + elseif chem_adjacent = 3 : chem_adjacent_p := ( chem_adjacent_d, 0) ; + elseif chem_adjacent = 4 : chem_adjacent_p := (0, chem_adjacent_d) ; + else : chem_adjacent_p := origin ; + fi ; + currentpicture := currentpicture shifted chem_adjacent_p ; + chem_shift := chem_shift + chem_adjacent_p ; + chem_adjacent := 0 ; + fi ; + if chem_substituent > 0 : + if m = 1 : + chem_substituent_d := xpart chem_crz_zero[n] + chem_substituent_offset ; + else : + chem_substituent_d := xpart chem_crz_zero[n] + xpart chem_b_zero[m] ; + fi ; + if chem_substituent = 1 : chem_substituent_p := (-chem_substituent_d, 0) ; % - ? + elseif chem_substituent = 2 : chem_substituent_p := (0, chem_substituent_d) ; + elseif chem_substituent = 3 : chem_substituent_p := ( chem_substituent_d, 0) ; + elseif chem_substituent = 4 : chem_substituent_p := (0, -chem_substituent_d) ; + else : chem_substituent_p := origin ; + fi ; + currentpicture := currentpicture shifted chem_substituent_p ; + chem_shift := chem_shift + chem_substituent_p ; + chem_substituent := 0 ; + fi ; + chem_rotation := chem_initialrot[m] ; +enddef ; + +vardef chem_draw (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor ; + endfor ; +enddef ; +vardef chem_fill (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + fill (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled 0 withcolor linecolor ; + endfor ; +enddef ; + +vardef chem_dashed_normal (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor dashed evenly ; + endfor ; +enddef ; +vardef chem_dashed_connected (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + draw for i:=from_point upto to_point: + (path_fragment rotated chem_ang(n,i)) if i < to_point : -- fi + endfor withpen pencircle scaled linewidth withcolor linecolor dashed evenly ; +enddef ; +vardef chem_draw_dot (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled (chem_dot_factor*linewidth) withcolor linecolor ; + endfor ; +enddef ; +vardef chem_draw_fixed (expr n, path_fragment, linewidth, linecolor) = + draw (path_fragment rotated chem_ang(n,1)) withpen pencircle scaled linewidth withcolor linecolor ; +enddef ; +vardef chem_draw_arrow (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + drawarrow (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor ; + endfor ; +enddef ; +vardef chem_draw_vertical (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + % quite special + for i:=from_point upto to_point: + draw (path_fragment shifted (chem_b_zero[n] rotated chem_ang(n,i))) withpen pencircle scaled linewidth withcolor linecolor ; + endfor ; +enddef ; + +picture chem_stack_p[] ; +pair chem_stack_shift[] ; + +vardef chem_save = + chem_stack_n := chem_stack_n + 1 ; + chem_stack_p[chem_stack_n] := currentpicture ; + chem_stack_shift[chem_stack_n] := chem_shift ; + chem_shift := origin ; +% chem_adjacent := 0 ; +% chem_substituent := 0 ; +% chem_rotation := 1 ; + currentpicture := nullpicture ; +enddef ; +vardef chem_restore = + if chem_stack_n > 0 : + currentpicture := currentpicture shifted - chem_shift ; + addto chem_stack_p[chem_stack_n] also currentpicture ; + currentpicture := chem_stack_p[chem_stack_n] ; + chem_stack_p[chem_stack_n] := nullpicture ; + chem_shift := chem_stack_shift[chem_stack_n] ; + chem_stack_n := chem_stack_n - 1 ; + fi ; +enddef ; + +def chem_init_some(expr n, ratio, start, initialrot, initialmov) = + chem_width [n] := ratio * chem_base_width * chem_setting_scale ; + chem_angle [n] := 360/abs(n) ; + chem_start [n] := start ; + chem_initialrot[n] := initialrot ; + chem_initialmov[n] := initialmov ; + chem_b_zero [n] := (chem_width[n],0) rotated (chem_angle[n]/2) ; + chem_n_zero [n] := (chem_text_min*chem_width[n],0) rotated (chem_angle[n]/2) ; + chem_r_max [n] := chem_radical_max*chem_b_zero[n] ; + chem_r_path [n] := chem_b_zero[n] -- chem_r_max[n] ; + chem_mr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; + chem_pr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; + chem_r_zero [n] := point 1 of chem_r_path [n] ; + chem_mr_zero [n] := point 1 of chem_mr_path[n] ; + chem_pr_zero [n] := point 1 of chem_pr_path[n] ; + chem_crz_zero [n] := point 1 of (chem_r_path[n] enlonged chem_center_offset) ; + chem_au_path [n] := subpath (0.2,0.8) of (chem_r_max[n] -- (chem_r_max[n] rotated chem_angle[n])) ; + chem_ad_path [n] := reverse(chem_au_path[n]) ; + chem_rt_zero [n] := (((chem_radical_max+chem_radical_min)/2)*chem_width[n],0) rotated (chem_angle[n]/2) ; + chem_rtt_zero [n] := chem_rt_zero[n] rotated + 10 ; + chem_rbt_zero [n] := chem_rt_zero[n] rotated - 10 ; + chem_b_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; + chem_bx_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; % ? + chem_sb_path [n] := subpath (0.25,0.75) of chem_b_path[n] ; + chem_s_path [n] := point 0 of chem_b_path[n] -- point 0 of (chem_b_path[n] rotated (2chem_angle[n])) ; + chem_ss_path [n] := subpath (0.25,0.75) of (chem_s_path[n]) ; + chem_pss_path [n] := subpath (0.00,0.75) of (chem_s_path[n]) ; + chem_mss_path [n] := subpath (0.25,1.00) of (chem_s_path[n]) ; + chem_mid_zero [n] := origin shifted (-.25chem_width[n],0) ; + chem_midst_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated ( chem_angle[n] + chem_angle[n]/2) ; + chem_midsb_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated (-chem_angle[n] - chem_angle[n]/2) ; + chem_midt_path [n] := subpath (0.25,1.00) of chem_midst_path [n] ; + chem_midb_path [n] := subpath (0.25,1.00) of chem_midsb_path [n] ; + chem_msb_path [n] := subpath (0.00,0.75) of chem_b_path[n] ; + chem_psb_path [n] := subpath (0.25,1.00) of chem_b_path[n] ; + chem_dbl_path [n] := chem_sb_path[n] shifted - (0.05[origin,center chem_sb_path[n]]) ; % parallel + chem_dbr_path [n] := chem_sb_path[n] shifted + (0.05[origin,center chem_sb_path[n]]) ; + chem_eb_path [n] := chem_sb_path[n] shifted - (0.25[origin,center chem_sb_path[n]]) ; + chem_sr_path [n] := chem_radical_min*chem_b_zero[n] -- chem_r_max[n] ; + chem_rl_path [n] := chem_r_path[n] paralleled (chem_base_width/20) ; + chem_rr_path [n] := chem_r_path[n] paralleled -(chem_base_width/20) ; + chem_srl_path [n] := chem_sr_path[n] paralleled (chem_base_width/20) ; + chem_srr_path [n] := chem_sr_path[n] paralleled -(chem_base_width/20) ; + chem_br_path [n] := point 1 of chem_sb_path[n] -- + point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], -4) -- + point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], 4) -- cycle ; + chem_rb_path [n] := chem_b_zero[n] -- chem_r_max[n] rotated -2 -- chem_r_max[n] -- chem_r_max[n] rotated 2 -- cycle ; + chem_mrb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; + chem_prb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; + chem_msr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; + chem_psr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; + % not yet ok: +% chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (1.25*chem_circle_radius*chem_width[n])); +% chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (1.25*chem_circle_radius*chem_width[n])); + chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (chem_width[n])); + chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (chem_width[n])); +enddef ; + +def chem_init_three = chem_init_some(3,30/52 ,-60,1,2) ; enddef ; % 60 +def chem_init_four = chem_init_some(4,30/42.5, 0,1,0) ; enddef ; % 45 +def chem_init_five = chem_init_some(5,30/35 , 0,1,0) ; enddef ; % 36 +def chem_init_six = chem_init_some(6, 1 , 0,1,0) ; enddef ; % 30 +def chem_init_eight = chem_init_some(8,30/22.5, 0,1,0) ; enddef ; % 22.5 + +% bb R -R R Z -RZ +RZ + +def chem_init_some_front(expr n, ratio, start, initialrot, initialmov) = + chem_init_some(n, ratio, start, initialrot, initialmov) ; + chem_bb_path [n] := chem_b_path[n] rotated -chem_angle[n] -- chem_b_path[n] -- chem_b_path[n] rotated chem_angle[n] -- + (reverse(chem_b_path[n] shortened (chem_base_width/20))) paralleled (chem_base_width/20) -- + cycle ; + chem_r_max [n] := chem_radical_max*chem_b_zero[n] ; + chem_mr_path [n] := origin -- origin shifted (0,-.25chem_base_width) ; + chem_pr_path [n] := origin -- origin shifted (0, .25*chem_base_width) ; + chem_r_path [n] := point 1 of chem_mr_path[n] -- point 1 of chem_pr_path[n] ; + chem_mr_zero [n] := point 1 of chem_mr_path[n] ; + chem_pr_zero [n] := point 1 of chem_pr_path[n] ; +enddef ; + +def chem_init_five_front = chem_init_some_front(-5,30/35,0,2,0) ; enddef ; % 36 +def chem_init_six_front = chem_init_some_front(-6, 1 ,0,2,0) ; enddef ; % 30 + +vardef chem_init_one = + chem_width [1] := .75 * chem_base_width * chem_setting_scale ; + chem_angle [1] := 360/8 ; + chem_start [1] := 0 ; + chem_initialrot[1] := 1 ; + chem_initialmov[1] := 1 ; + chem_b_zero [1] := (1.75*chem_width[1],0) ; + chem_r_min [1] := chem_radical_min*chem_b_zero[1] ; + chem_r_max [1] := chem_radical_max*chem_b_zero[1] ; + chem_r_path [1] := (.5*chem_width[1],0) -- (1.25*chem_width[1],0) ; + chem_r_zero [1] := point 1 of chem_r_path [1] ; + chem_b_path [1] := chem_r_path[1] rotated + (chem_angle[1]) ; % used for move here + chem_b_zero [1] := chem_r_zero[1] ; + chem_crz_zero [1] := chem_r_zero[1] enlonged chem_center_offset ; + chem_e_path [1] := (.5*chem_width[1],-.25*chem_width[1]) -- (.5*chem_width[1],.25*chem_width[1]) ; + chem_sb_path [1] := chem_r_path [1] ; + chem_msb_path [1] := chem_r_path [1] shifted (0,-.1chem_width[1]) ; + chem_psb_path [1] := chem_r_path [1] shifted (0, .1chem_width[1]) ; + chem_ddt_path [1] := subpath(0,.4) of chem_r_path [1] ; + chem_ddb_path [1] := subpath(.6,1) of chem_r_path [1] ; + chem_ldt_path [1] := chem_ddt_path [1] shifted (0,-.1chem_width[1]) ; % parallel + chem_ldb_path [1] := chem_ddb_path [1] shifted (0,-.1chem_width[1]) ; + chem_rdt_path [1] := chem_ddt_path [1] shifted (0, .1chem_width[1]) ; + chem_rdb_path [1] := chem_ddb_path [1] shifted (0, .1chem_width[1]) ; + save pr ; pair pr[] ; + pr0 := point 0 of chem_r_path[1] ; + pr1 := point 1 of chem_r_path[1] ; + chem_bb_path [1] := pr0 -- (pr1 rotatedaround(pr0,-chem_bb_angle)) -- (pr1 rotatedaround(pr0,chem_bb_angle)) -- cycle ; + chem_oe_path [1] := ((-20,0)--(10,0){up}..(20,10)..(30,0)..(40,-10)..(50.0,0)..(60,10)..(70,0)..(80,-10)..{up}(90,0)--(120,0)) + xsized (.75*chem_width[1]) shifted pr0 ; + chem_rt_zero [1] := point .5 of chem_r_path[1] ; + chem_rtt_zero [1] := chem_rt_zero[1] rotated + (chem_angle[1]/2) ; + chem_rbt_zero [1] := chem_rt_zero[1] rotated - (chem_angle[1]/2) ; + % added by Alan Braslau (adapted to use shared variables): + save p ; pair p[] ; + p0 := pr1 rotatedaround(pr0, -chem_bd_angle) ; + p1 := pr1 rotatedaround(pr0, +chem_bd_angle) ; + p2 := p0 shifted - pr1 ; + p3 := p1 shifted - pr1 ; + chem_bd_path [1] := + p0 -- p1 for i=chem_bd_n downto 0 : + -- p2 shifted (i/chem_bd_n)[pr1,pr0] + -- p3 shifted (i/chem_bd_n)[pr1,pr0] + endfor ; + chem_bw_path [1] := + for i=0 upto chem_bw_n - 1 : + ((i) /chem_bw_n)[pr0,pr1] .. ((i+.25)/chem_bw_n)[pr0,pr1] shifted p2 .. + ((i+.50)/chem_bw_n)[pr0,pr1] .. ((i+.75)/chem_bw_n)[pr0,pr1] shifted -p2 .. + endfor pr1 ; +enddef ; + +def chem_init_all = + chem_init_one ; + chem_init_three ; + chem_init_four ; + chem_init_five ; + chem_init_six ; + chem_init_eight ; + chem_init_five_front ; + chem_init_six_front ; +enddef ; + +chem_init_all ; diff --git a/metapost/context/base/mp-core.mp b/metapost/context/base/mp-core.mp new file mode 100644 index 000000000..7c5d5a1c1 --- /dev/null +++ b/metapost/context/base/mp-core.mp @@ -0,0 +1,1418 @@ + +if unknown context_tool : input mp-tool ; fi ; +if known context_core : endinput ; fi ; + +boolean context_core ; context_core := true ; + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; + llxy := (x,y-d) ; + lrxy := (x+w,y-d) ; + urxy := (x+w,y+h) ; + ulxy := (x,y+h) ; + wxy := w ; + hxy := h ; + dxy := d ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; + nxy := n ; + freeze_box(pos) ; +enddef ; + +def freeze_box (expr pos) = + lxy[pos] := lxy ; + llxy[pos] := llxy ; + lrxy[pos] := lrxy ; + urxy[pos] := urxy ; + ulxy[pos] := ulxy ; + wxy[pos] := wxy ; + hxy[pos] := hxy ; + dxy[pos] := dxy ; + rxy[pos] := rxy ; + pxy[pos] := pxy ; + cxy[pos] := cxy ; + nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; + +enddef ; + +def initialize_area (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + + do_initialize_area (fpos, tpos) ; + +enddef ; + +def do_initialize_area (expr fpos, tpos) = + lxy := lxy[fpos] ; + llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; + lrxy := lrxy[tpos] ; + urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; + ulxy := ulxy[fpos] ; + wxy := xpart lrxy - xpart llxy ; + hxy := hxy[fpos] ; + dxy := dxy[tpos] ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; +enddef ; + +def set_par_line_height (expr ph, pd) = + par_strut_height := + if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ; + par_strut_depth := + if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ; + par_line_height := + par_strut_height + par_strut_depth ; +enddef ; + +def initialize_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + mn,mx,my,mw,mh,md, + pn,px,py,pw,ph,pd, + rw,rl,rr,rh,ra,ri) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; + numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (ph, pd) ; + + do_initialize_area (fpos, tpos) ; + do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; + +enddef ; + +def initialize_area_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + wn,wx,wy,ww,wh,wd) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (wh, wd) ; + + numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ; + numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ; + + do_initialize_area (ffpos, ttpos) ; + + numeric mpos ; mpos := 6 ; freeze_box(mpos) ; + + do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; + +enddef ; + +def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = + + pair lref, rref, pref, lhref, rhref ; + + % clip the page area to the left and right skips + + llxy[mpos] := llxy[mpos] shifted (+rl,0) ; + lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; + urxy[mpos] := urxy[mpos] shifted (-rr,0) ; + ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; + + % fixate the leftskip, rightskip and hanging indentation + + lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; + rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; + + pref := lxy[ppos] ; + + if nxy[tpos] > nxy[fpos] : + if nxy[fpos] = nxy[mpos] : + % first of multiple pages + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := down ; + elseif nxy[tpos] = nxy[mpos] : + % last of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + boxgriddirection := up ; + else : + % middle of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := up ; + fi ; + else : + % just one page + boxgriddirection := up ; + fi ; + + path txy, bxy, pxy, mxy ; + + txy := originpath ; % top + bxy := originpath ; % bottom + pxy := originpath ; % composed + + boolean lefthang, righthang, somehang ; + + % we only hang on the first of a multiple page background + + if nxy[mpos] > nxy[fpos] : + lefthang := righthang := somehang := false ; + else : + lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; + fi ; + + if lefthang : + mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; + elseif righthang : + mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; + else : + mxy := originpath ; + fi ; + + if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : + + % We have a one-liner. Watch how er use the bottom pos for + % determining the height. + + llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; + ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; + + else : + + % We have a multi-liner. For convenience we now correct the + % begin and end points for indentation. + + if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : + llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; + else : + llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; + fi ; + + if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : + lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; + else : + lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; + fi ; + + fi ; + + somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and + (ypart llxy[tpos]0 : + left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; + right_skip := rw - left_skip - ww ; + else : + left_skip := rl ; + right_skip := rr ; + fi ; + + path multipar, multipars[] ; + numeric multiref, multirefs[] ; + numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end + + numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; + + vardef snapped_multi_pos (expr p) = + if snap_multi_par_tops : + if abs(ypart p - ypart ulcorner multipar) < par_line_height : + (xpart p,ypart ulcorner multipar) + else : + p + fi + else : + p + fi + enddef ; + + % def set_multipar (expr i) = + % ((TextAreas[i] leftenlarged -left_skip) rightenlarged -right_skip) + % enddef ; + + vardef set_multipar (expr i) = + ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip + if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) + enddef ; + + vardef top_multi_par(expr p) = + (round(estimated_par_lines(bbheight(p)*par_line_height))=round(bbheight(p))) + enddef ; + + vardef multi_par_tsc(expr p) = + if top_multi_par(p) : TopSkipCorrection else : 0 fi + enddef ; + + vardef estimated_par_lines (expr h) = + round(h/par_line_height) + enddef ; + + vardef estimated_multi_par_height (expr n, t) = + if round(par_line_height)=0 : + 0 + else : + save ok, h ; boolean ok ; + numeric h ; h := 0 ; + ok := false ; + if (nxy[fpos]=RealPageNumber-1) : + for i := 1 upto NOfSavedTextAreas : + if (InsideSavedTextArea(i,par_start_pos)) : + ok := true ; + h := h + estimated_par_lines(ypart ulxy[fpos] - + ypart llcorner SavedTextAreas[i]) ; + elseif ok : + h := h + estimated_par_lines(bbheight(SavedTextAreas[i])) ; + fi ; + endfor ; + fi ; + if ok : + for i := 1 upto n-1 : + h := h + estimated_par_lines(bbheight(TextAreas[i])) ; + endfor ; + else : + % already: ok := false ; + for i := 1 upto n-1 : + if (InsideTextArea(i,par_start_pos)) : + ok := true ; + h := h + estimated_par_lines(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; + elseif ok : + h := h + estimated_par_lines(bbheight(TextAreas[i])) ; + fi ; + endfor ; + fi ; + h + fi + enddef ; + + vardef left_top_hang (expr same_area) = + + par_hang_after := ra + estimated_par_lines(py-fy) ; + + if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart snapped_multi_pos(ulxy[fpos])); + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llxy[tpos])) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) -- + (xpart _ul_ + par_hang_indent, ypart _pa_) -- + (xpart ulcorner multipar, ypart _pa_) + else : + (xpart ulcorner multipar, ypart lrxy[fpos]) + fi + enddef ; + + vardef right_top_hang (expr same_area) = + + par_hang_after := ra + estimated_par_lines(py-fy) ; + + if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart snapped_multi_pos(urxy[fpos])) ; + pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart snapped_multi_pos(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart urcorner multipar, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart snapped_multi_pos(urxy[fpos])) + else : + (xpart urcorner multipar, ypart snapped_multi_pos(urxy[fpos])) + fi + enddef ; + + vardef x_left_top_hang (expr i, t) = + par_hang_after := min(0,ra + estimated_multi_par_height(i,t)) ; + if (par_hang_indent>0) and (par_hang_after<0) : + pair _ul_ ; _ul_ := ulcorner multipar ; + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if t : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])); + fi ; + if abs(ypart _pa_-ypart llxy[tpos])0) and (par_hang_after>0) and obey_multi_par_hang : + _ll_ := (xpart ulcorner multipar, ypart snapped_multi_pos(ulxy[fpos])) ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + _pa_ -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + (xpart _pa_ + par_hang_indent,ypart _sa_) + else : + (xpart llcorner multipar, ypart _sa_) + fi + enddef ; + + vardef right_bottom_hang (expr same_area) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if same_area : snapped_multi_pos(ulxy[tpos]) else : lrcorner multipar fi ; + if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang : + _lr_ := (xpart urcorner multipar, ypart snapped_multi_pos(urxy[fpos])) ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart snapped_multi_pos(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + _pa_ + else : + (xpart lrcorner multipar, ypart _sa_) + fi + enddef ; + + vardef x_left_bottom_hang (expr i, t) = + pair _ll_, _sa_, _pa_ ; + _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; + if (par_hang_indent>0) and (ra>0) : + par_hang_after := max(0,ra - estimated_multi_par_height(i,t)) ; + _ll_ := ulcorner multipar ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + fi + _pa_ + else : + (xpart llcorner multipar, ypart _sa_) + fi + enddef ; + + vardef x_right_bottom_hang (expr i, t) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if t : snapped_multi_pos(ulxy[tpos]) else : llcorner multipar fi ; + if (par_hang_indent<0) and (ra>0) : + par_hang_after := max(0,ra - estimated_multi_par_height(i, t)) ; + _lr_ := urcorner multipar ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + _pa_ + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + -- (xpart _pa_ + par_hang_indent,ypart _pa_) + -- (xpart _pa_ + par_hang_indent,ypart _sa_) + fi + else : + (xpart lrcorner multipar, ypart _sa_) + fi + enddef ; + + def test_multipar = + multipar := boundingbox multipar ; + enddef ; + + % first loop + + ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; + + if enable_multi_par_fallback and + (nxy[fpos]=RealPageNumber) and + (nxy[tpos]=RealPageNumber) and not + (InsideSomeTextArea(lxy[fpos]) and + InsideSomeTextArea(rxy[tpos])) : + + % fallback + + % multipar := + % llxy[fpos] -- + % lrxy[tpos] -- + % urxy[tpos] -- + % ulxy[fpos] -- cycle ; + % + % save_multipar (1,1,multipar) ; + + % we need to take the boundingbox because there can be + % more lines and we want a proper rectange + + multipar := + ulxy[fpos] -- + urxy[tpos] -- + lrxy[fpos] -- + llxy[tpos] -- cycle ; + + save_multipar (1,1,boundingbox(multipar)) ; + + else : + + % normal + + for i=1 upto NOfTextAreas : + + TopSkipCorrection := 0 ; + + multipar := set_multipar(i) ; + + % watch how we compensate for negative indentation + + if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) : + + % first one in chain + + ii := i ; + + if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + + % in same area + + nn := i ; + + if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : + + TopSkipCorrection := TopSkip - StrutHeight ; + + if round(ypart ulxy[fpos] + TopSkipCorrection) = + round(ypart ulcorner TextAreas[i]) : + ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; + urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; + else : + TopSkipCorrection := 0 ; + fi ; + + fi ; + + if ypart llxy[fpos] = ypart llxy[tpos] : + + multipar := + llxy[fpos] -- + lrxy[tpos] -- + %urxy[tpos] -- + snapped_multi_pos(urxy[tpos]) -- + %ulxy[fpos] -- + snapped_multi_pos(ulxy[fpos]) -- + cycle ; + + save_multipar (i,1,multipar) ; + + elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and + (xpart llxy[tpos] < xpart llxy[fpos]) : + + % two loners + + multipar := if obey_multi_par_hang : + + right_bottom_hang(true) -- + right_top_hang(true) -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + + else : + + llxy[fpos] -- + (xpart urcorner multipar, ypart llxy[fpos]) -- + (xpart urcorner multipar, ypart ulxy[fpos]) -- + snapped_multi_pos(ulxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + multipar := set_multipar(i) ; + + multipar := if obey_multi_par_hang : + + left_bottom_hang(true) -- + llxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + left_top_hang(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + (xpart llcorner multipar, ypart ulxy[tpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + else : + + multipar := if obey_multi_par_hang : + + left_bottom_hang(true) -- + llxy[tpos] -- + %ulxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + right_bottom_hang(true) -- + right_top_hang(true) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + left_top_hang(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + %ulxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + (xpart lrcorner multipar, ypart ulxy[tpos]) -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + else : + + multipar := if obey_multi_par_hang : + + left_bottom_hang(false) -- + right_bottom_hang(false) -- + right_top_hang(false) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + left_top_hang(false) -- + + else : + + llcorner multipar -- + lrcorner multipar -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + + % last one in chain + + nn := i ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + x_left_top_hang(i,true) -- + x_right_top_hang(i,true) -- + x_right_bottom_hang(i,true) -- + snapped_multi_pos(ulxy[tpos]) -- + llxy[tpos] -- + x_left_bottom_hang(i,true) -- + cycle ; + + else : + + multipar := + ulcorner multipar -- + urcorner multipar -- + (xpart lrcorner multipar, ypart urxy[tpos]) -- + snapped_multi_pos(ulxy[tpos]) -- + llxy[tpos] -- + (xpart llcorner multipar, ypart llxy[tpos]) -- + cycle ; + + fi ; + + save_multipar (i,3,multipar) ; + + elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) and (NOfTextColumns>1)) : + + save_multipar (i,2,multipar) ; + + else : + % handled later + fi ; + + endfor ; + + % second loop + + if force_multi_par_chain or (ii > 1) : + + for i=ii+1 upto nn-1 : + + % rest of chain / todo : hang + +% hm, the second+ column in column sets now gets lost in a NOfTextColumns + + if (not check_multi_par_chain) or + ((nxy[fpos]RealPageNumber)) + : + + multipar := set_multipar(i) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + x_left_top_hang(i,false) -- + x_right_top_hang(i,false) -- + x_right_bottom_hang(i,false) -- + x_left_bottom_hang(i,false) -- + cycle ; + + fi ; + + save_multipar(i,2,multipar) ; + + fi ; + + endfor ; + + fi ; + + % end of normal/fallback + +fi ; + + if span_multi_column_pars : + endgroup ; + fi ; + + % potential safeguard: + + % for i=1 upto nofmultipars : + % if length p <= 4 : + % multipars[i] := boundingbox(multipars[i]) ; + % fi ; + % end ; + + % quick hack for gb: + + one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; + +enddef ; + +color boxgridcolor ; boxgridcolor := .8red ; +color boxlinecolor ; boxlinecolor := .8blue ; +color boxfillcolor ; boxfillcolor := .8white ; +numeric boxgridtype ; boxgridtype := 0 ; +numeric boxlinetype ; boxlinetype := 1 ; +numeric boxfilltype ; boxfilltype := 1 ; +numeric boxdashtype ; boxdashtype := 0 ; +pair boxgriddirection ; boxgriddirection := up ; +numeric boxgridwidth ; boxgridwidth := 1pt ; +numeric boxlinewidth ; boxlinewidth := 1pt ; +numeric boxlineradius ; boxlineradius := 0pt ; +numeric boxfilloffset ; boxfilloffset := 0pt ; +numeric boxgriddistance ; boxgriddistance := .5cm ; +numeric boxgridshift ; boxgridshift := 0pt ; + +def draw_box = + draw pxy withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; + draw lxy -- rxy withcolor boxlinecolor withpen pencircle scaled boxgridwidth ; +enddef ; + +def draw_par = % 1 2 3 11 12 + do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ; + for i = pxy, txy, bxy : + if boxgridtype = 1 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; + elseif boxgridtype = 2 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,false) withcolor boxgridcolor ; + elseif boxgridtype = 3 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight) withcolor boxgridcolor ; + elseif boxgridtype = 4 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight/2) withcolor boxgridcolor ; + elseif boxgridtype = 11 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype = 12 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def do_show_par (expr p, r, c) = + if length(p) > 2 : for i=0 upto length(p) : + draw fullcircle scaled r shifted point i of p + withpen pencircle scaled .5pt withcolor c ; + endfor ; fi ; + draw p withpen pencircle scaled .5pt withcolor c ; +enddef ; + +def show_par = + if length(mxy) > 2 : + draw mxy dashed evenly + withpen pencircle scaled .5pt withcolor .5white ; + fi ; + do_show_par(txy, 4pt, .5green) ; + do_show_par(bxy, 6pt, .5blue ) ; + do_show_par(pxy, 8pt, .5red ) ; + draw pref withpen pencircle scaled 2pt ; +enddef ; + +def sort_multi_pars = + if nofmultipars>1 : + begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ; + for i := 1 upto nofmultipars : + if multilocs[i] = 3 : + _p_ := multipars[nofmultipars] ; + multipars[nofmultipars] := multipars[i] ; + multipars[i] := _p_ ; + _n_ := multirefs[nofmultipars] ; + multirefs[nofmultipars] := multirefs[i] ; + multirefs[i] := _n_ ; + _n_ := multilocs[nofmultipars] ; + multilocs[nofmultipars] := multilocs[i] ; + multilocs[i] := _n_ ; + fi ; + endfor ; + endgroup ; + fi ; +enddef ; + + +def collapse_multi_pars = + if nofmultipars>1 : + begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ; + _nofmultipars_ := 1 ; + sort_multi_pars ; % block not in order: 1, 3, 2.... + for i:=1 upto nofmultipars-1 : + if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and + (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : +multilocs[_nofmultipars_] := multilocs[i+1] ; +multirefs[_nofmultipars_] := multirefs[i+1] ; + multipars[_nofmultipars_] := + ulcorner multipars[_nofmultipars_] -- + urcorner multipars[_nofmultipars_] -- + lrcorner multipars[i+1] -- + llcorner multipars[i+1] -- cycle ; + else : + _nofmultipars_ := _nofmultipars_ + 1 ; + multipars[_nofmultipars_] := multipars[i+1] ; + multilocs[_nofmultipars_] := multilocs[i+1] ; + multirefs[_nofmultipars_] := multirefs[i+1] ; + fi ; + endfor ; + nofmultipars := _nofmultipars_ ; + endgroup ; + fi ; +enddef ; + +% def draw_multi_pars = +% for i=1 upto nofmultipars : +% do_draw_par(multipars[i]) ; +% if boxgridtype= 1 : +% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 2 : +% draw baseline_grid (multipars[i],up,false) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 3 : +% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; +% draw baseline_grid (multipars[i],up,true ) +% shifted (0,ExHeight) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 4 : +% draw baseline_grid (multipars[i],up,true ) +% shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; +% elseif boxgridtype=11 : +% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; +% elseif boxgridtype=12 : +% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; +% fi ; +% endfor ; +% enddef ; + +def draw_multi_pars = + for i=1 upto nofmultipars : + do_draw_par(multipars[i]) ; + if boxgridtype= 1 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; + elseif boxgridtype= 2 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; % withcolor boxgridcolor ; + elseif boxgridtype= 3 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; % withcolor boxgridcolor ; + elseif boxgridtype= 4 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; + elseif boxgridtype=11 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype=12 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def show_multi_pars = + for i=1 upto nofmultipars : + do_show_par(multipars[i], 6pt, .5blue) ; + endfor ; +enddef ; + +vardef do_draw_par (expr p) = + if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : + save pp ; path pp ; + if (boxlineradius>0) and (boxlinetype=2) : + pp := p cornered boxlineradius ; + else : + pp := p ; + fi ; + if boxfilltype>0 : + if boxfilloffset>0 : + % temporary hack + begingroup ; interim linejoin := mitered ; + filldraw pp withcolor boxfillcolor withpen pencircle scaled (2*boxfilloffset) ; + endgroup ; + else : + fill pp withcolor boxfillcolor ; + fi ; + fi ; + if boxlinetype>0 : + draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; + fi ; + fi ; +enddef ; + +vardef baseline_grid (expr pxy, pdir, at_baseline) = + if (par_line_height>0) and (bbheight(pxy)>1) and (bbwidth(pxy)>1) and (boxgridwidth>0) : + save i, grid, bb ; picture grid ; pair start ; path bb ; + def _do_ (expr start) = + % 1 = normal, 2 = with background (i.e. no shine-through) + if boxdashtype = 2 : + draw start -- start shifted (bbwidth(pxy),0) + withpen pencircle scaled boxgridwidth + withcolor boxfillcolor ; + fi ; + draw start -- start shifted (bbwidth(pxy),0) + if boxdashtype > 0 : dashed evenly fi + withpen pencircle scaled boxgridwidth + withcolor boxgridcolor ; + enddef ; + grid := image + ( %fails with inlinespace + % + if pdir=up : + for i = if at_baseline : par_strut_depth else : 0 fi + step par_line_height + until max(bbheight(pxy),par_line_height) : + _do_ (llcorner pxy shifted (0,+i)) ; + endfor ; + else : + for i = if at_baseline : par_strut_height else : 0 fi + step par_line_height + until bbheight(pxy) : + _do_ (ulcorner pxy shifted (0,-i)) ; + endfor ; + fi ; + ) ; + clip grid to pxy ; + bb := boundingbox grid ; + grid := grid shifted (0,boxgridshift) ; + setbounds grid to bb ; + grid + else : + nullpicture + fi +enddef ; + +vardef graphic_grid (expr pxy, dx, dy, x, y) = + if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : + save grid ; picture grid ; + grid := image + ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy : + draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) + withpen pencircle scaled boxgridwidth ; + endfor ; + for i = ypart llcorner pxy step dy until ypart ulcorner pxy : + draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) + withpen pencircle scaled boxgridwidth ; + endfor ) shifted (x,y) ; + clip grid to pxy ; + grid + else : + nullpicture + fi +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; + +let draw_area = draw_box ; +let anchor_area = anchor_box ; +let anchor_par = anchor_box ; + + +numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; +pair sync_xy[][] ; color sync_c[][] ; + +def ResetSyncTasks = + path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; + NOfSyncPaths := CurrentSyncClass := 0 ; + if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; + if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; + if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; + if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; + if (SyncLeftOffset = 0) and (SyncWidth = 0) : + SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; + fi ; +enddef ; + +ResetSyncTasks ; + +vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = + save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; + o shifted (leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,bottomoffset) -- + o shifted (leftoffset,bottomoffset) -- cycle +enddef ; + +def SetSyncColor(expr n, i, c) = + sync_c[n][i] := c ; +enddef ; + +def SetSyncThreshold(expr n, i, th) = + sync_th[n][i] := th ; +enddef ; + +vardef TheSyncColor(expr n, i) = + if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi +enddef ; + +vardef TheSyncThreshold(expr n, i) = + if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi +enddef ; + +vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = + ResetSyncTasks ; + if known sync_n[n] : + CurrentSyncClass := n ; + save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; + for i=1 upto sync_n[n] : + if RealPageNumber > sync_p[n][i] : + l := i ; + elseif RealPageNumber = sync_p[n][i] : + NOfSyncPaths := NOfSyncPaths + 1 ; + if not ok : + if i>1 : + if sync_t[n][i-1] = sync_t[n][i] : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i-1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + ok := true ; + fi ; + endfor ; + if (NOfSyncPaths = 0) and (l > 0) : + NOfSyncPaths := 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := l ; + fi ; + if NOfSyncPaths > 0 : + for i = 1 upto NOfSyncPaths-1 : + SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; + endfor ; + if unknown SyncThresholdMethod : + numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; + fi ; + if extendtop : + if SyncThresholdMethod = 1 : + if NOfSyncPaths>1 : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; + if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : + SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; + fi ; + fi ; + else : + for i = 1 upto NOfSyncPaths : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; + if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : + SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; + fi ; + endfor ; + fi ; + fi ; + if prestartnext : + if NOfSyncPaths>1 : + if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; + if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : + SyncPaths[NOfSyncPaths+1] := + (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + lrcorner SyncPaths[NOfSyncPaths] -- + llcorner SyncPaths[NOfSyncPaths] -- cycle ; + SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + fi ; + fi ; + fi ; + else : + if NOfSyncPaths>1 : + d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; + if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : + NOfSyncPaths := NOfSyncPaths - 1 ; + SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; + fi ; + fi ; + fi ; + if (NOfSyncPaths>1) and collapse : + save j ; numeric j ; j := 1 ; + for i = 2 upto NOfSyncPaths : + if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : + SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; + SyncTasks[j] := SyncTasks[i] ; + else : + j := j + 1 ; + SyncPaths[j] := SyncPaths[i] ; + SyncTasks[j] := SyncTasks[i] ; + fi ; + endfor ; + NOfSyncPaths := j ; + fi ; + fi ; + fi ; +enddef ; + +def SyncTask(expr n) = + if known SyncTasks[n] : SyncTasks[n] else : 0 fi +enddef ; + +def FlushSyncTasks = + for i = 1 upto NOfSyncPaths : + ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; + endfor ; +enddef ; + +def ProcessSyncTask(expr p, c) = + fill p withcolor c ; +enddef ; + +endinput ; + +end + +% for Jelle Huisman +% +% \setupcolors[state=start] +% \dontcomplain +% \definecolumnset[example][n=3,distance=5mm] +% \startMPextensions +% multi_column_first_page_hack := true ; +% \stopMPextensions +% \startuseMPgraphic{mpos:par:trick} +% for i=1 upto nofmultipars-1 : draw (rightboundary multipars[i]) shifted (2.5mm, 0) ; endfor ; +% \stopuseMPgraphic +% \definetextbackground[test][mp=mpos:par:trick,method=mpos:par:columnset] +% \starttext +% \definecolumnsetspan[chapter][n=3] +% \startcolumnset[example] +% \startcolumnsetspan[chapter] +% \chapter{Chapter One} +% \stopcolumnsetspan +% \starttextbackground[test] \dorecurse {3}{\input knuth } \stoptextbackground +% \stopcolumnset +% \startcolumnset[example] +% \startcolumnsetspan[chapter] +% \chapter{Chapter One} +% \stopcolumnsetspan +% \starttextbackground[test] \dorecurse {10}{\input knuth } \stoptextbackground +% \stopcolumnset +% \stoptext +% +% fast variant: +% +% \startuseMPgraphic{whatever} +% for i=1 upto NOfTextColumns-1 : +% draw (rightboundary TextColumns[i]) shifted (2.5mm,0) shifted -\MPxy\textanchor ; +% endfor ; +% setbounds currentpicture to OverlayBox ; +% \stopuseMPgraphic +% \defineoverlay[whatever][\useMPgraphic{whatever}] +% \setupbackgrounds[text][background=whatever] diff --git a/metapost/context/base/mp-figs.mp b/metapost/context/base/mp-figs.mp new file mode 100644 index 000000000..da5fa0d16 --- /dev/null +++ b/metapost/context/base/mp-figs.mp @@ -0,0 +1,50 @@ +%D \module +%D [ file=mp-tool.mp, +%D version=2003.01.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=figures, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={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. + +if unknown context_tool : input mp-tool ; fi ; +if known context_figs : endinput ; fi ; + +boolean context_figs ; context_figs := true ; + +% todo: check defined + +def registerfigure(expr name,width,height) = + begingroup ; + save s ; string s ; s := cleanstring(name) ; + scantokens( s & "_width := " & decimal(width)) ; + scantokens( s & "_height := " & decimal(height)) ; + endgroup ; +enddef ; + +vardef figuresize(expr name) = + save s ; string s ; s := cleanstring(name) ; + save p ; pair p ; + scantokens( "p := " & "(" & s & "_width" & "," & s & "_height" & ")" ) ; + p +enddef ; + +vardef figurewidth(expr name) = + xpart figuresize(name) +enddef ; + +vardef figureheight(expr name) = + ypart figuresize(name) +enddef ; + +def figuredimensions = figuresize enddef ; % for old times sake + +def naturalfigure(expr name) = + externalfigure name xyscaled(figuresize(name)) +enddef ; + +endinput diff --git a/metapost/context/base/mp-fobg.mp b/metapost/context/base/mp-fobg.mp new file mode 100644 index 000000000..712efe751 --- /dev/null +++ b/metapost/context/base/mp-fobg.mp @@ -0,0 +1,88 @@ +%D \module +%D [ file=mp-fobg.mp, +%D version=2004.03.12, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=Formatting 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 licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_fobg : endinput ; fi ; + +boolean context_fobg ; context_fobg := true ; + +FoNone := 0 ; FoHidden := 1 ; FoDotted := 2 ; FoDashed := 3 ; FoSolid := 4 ; +FoDouble := 5 ; FoGroove := 6 ; FoRidge := 7 ; FoInset := 8 ; FoOutset := 9 ; +FoAll := 0 ; FoTop := 1 ; FoBottom := 2 ; FoLeft := 3 ; FoRight := 4 ; +FoMedium := .5pt ; FoThin := FoMedium/2 ; FoThick := FoMedium*2 ; + +color FoBackgroundColor, FoNoColor, FoLineColor[] ; FoNoColor := (-1,-1,-1) ; +numeric FoLineWidth[], FoLineStyle[] ; +boolean FoFrame, FoBackground, FoSplit ; + +FoFrame := FoBackground := FoSplit := false ; +FoBackgroundColor := white ; +FoDashFactor := .5 ; +FoDotFactor := .375 ; + +for i = FoAll upto FoRight : + FoLineColor[i] := black ; + FoLineWidth[i] := .5pt ; + FoLineStyle[i] := FoNone ; +endfor ; + +def DrawFoFrame(expr n, p) = + drawoptions(withcolor FoLineColor[n] withpen pencircle scaled FoLineWidth[n]) ; + if FoLineStyle[n] = FoNone : + % nothing + elseif FoLineStyle[n] = FoHidden : + % nothing + elseif FoLineStyle[n] = FoDotted : + draw p dashed (withdots scaled (FoDotFactor*FoLineWidth[n])) ; + elseif FoLineStyle[n] = FoDashed : + draw p dashed (evenly scaled (FoDashFactor*FoLineWidth[n])) ; + elseif FoLineStyle[n] = FoSolid : + draw p ; + elseif FoLineStyle[n] = FoDouble : + draw p enlarged FoLineWidth[n] ; draw p enlarged -FoLineWidth[n] ; + elseif FoLineStyle[n] = FoGroove : + draw p ; + draw p withpen pencircle scaled .5FoLineWidth[n] withcolor (inverted FoLineColor[n] softened .5) ; + elseif FoLineStyle[n] = FoRidge : + draw p withcolor (inverted FoLineColor[n] softened .5) ; + draw p withpen pencircle scaled .5FoLineWidth[n] ; + elseif FoLineStyle[n] = FoInset : + draw p ; draw p inset 2.5FoLineWidth[n] ; + elseif FoLineStyle[n] = FoOutset : + draw p ; draw p outset 2.5FoLineWidth[n] ; + fi ; +enddef ; + +primarydef p outset d = + ((lrcorner p -- urcorner p -- ulcorner p -- llcorner p -- cycle) + shifted (d*(-1,1)) cutbefore topboundary p) cutafter leftboundary p +enddef ; + +primarydef p inset d = + ((ulcorner p -- llcorner p -- lrcorner p -- urcorner p -- cycle) + shifted (d*(1,-1)) cutbefore bottomboundary p) cutafter rightboundary p +enddef ; + +vardef equalpaths(expr p, q) = + if length(p) = length(q) : + save ok ; boolean ok ; ok := true ; + for i = 0 upto length(p)-1 : + ok := ok and (round(point i of p) = round(point i of q)) ; + endfor ; + ok + else : + false + fi +enddef ; + +endinput ; diff --git a/metapost/context/base/mp-form.mp b/metapost/context/base/mp-form.mp new file mode 100644 index 000000000..a65ab6d73 --- /dev/null +++ b/metapost/context/base/mp-form.mp @@ -0,0 +1,403 @@ +% Hans Hagen / October 2000 +% +% This file is mostly a copy from the file format.mp, that +% comes with MetaPost and is written by John Hobby. This file +% is meant to be compatible, but has a few more features, +% controlled by the variables: +% +% fmt_initialize when false, initialization is skipped +% fmt_precision the default accuracy (default=3) +% fmt_separator the pattern separator (default=%) +% fmt_zerocheck activate extra sci notation zero check +% +% instead of a picture, one can format a number in a for TeX +% acceptable input string + +boolean mant_font ; mant_font := true ; % signals graph not to load form + +if known fmt_loaded : expandafter endinput fi ; + boolean fmt_loaded ; fmt_loaded := true ; + +if unknown fmt_precision : + numeric fmt_precision ; fmt_precision := 3 ; +fi ; + +if unknown fmt_initialize : + boolean fmt_initialize ; fmt_initialize := true ; +fi ; + +if unknown fmt_separator : + string fmt_separator ; fmt_separator := "%" ; +fi ; + +if unknown fmt_zerocheck : + boolean fmt_zerocheck ; fmt_zerocheck := false ; +fi ; + +boolean fmt_metapost ; fmt_metapost := true ; % == use old method + +% As said, all clever code is from John, the more stupid +% extensions are mine. The following string variables are +% responsible for the TeX formatting. + +% TeX specs when using TeX instead of pseudo TeX. + +string sFebraise_ ; sFebraise_ := "{" ; +string sFeeraise_ ; sFeeraise_ := "}" ; +string sFebmath_ ; sFebmath_ := "$" ; +string sFeemath_ ; sFeemath_ := "$" ; + +string sFmneg_ ; sFmneg_ := "-" ; +string sFemarker_ ; sFemarker_ := "{\times}10^" ; +string sFeneg_ ; sFeneg_ := "-" ; +string sFe_plus ; sFe_plus := "" ; % "+" + +def sFe_base = Fline_up_("1", sFemarker_) enddef ; + +% Macros for generating typeset pictures of computed numbers +% +% format(f,x) typeset generalized number x using format string f +% Mformat(f,x) like format, but x is in Mlog form (see marith.mp) +% init_numbers(s,m,x,sn,e) choose typeset style given sample sign, mantissa,... +% roundd(x,d) round numeric x to d places right of decimal point +% Fe_base what precedes the exponent for typeset powers of 10 +% Fe_plus plus sign if any for typesetting positive exponents +% Ten_to[] powers of ten for indices 0,1,2,3,4 +% +% New are: +% +% formatstr(f,x) TeX string representing x using format f +% Mformatstr(f,x) like Mformatstr, but x is in Mlog form + +% Other than the above-documented user interface, all +% externally visible names start with F and end with _. + +% Allow big numbers in token lists + +begingroup interim warningcheck := 0 ; + +%%% Load auxiliary macros. + +input string +input marith + +%%% Choosing the Layout %%% + +picture Fmneg_, Femarker_, Feneg_, Fe_base, Fe_plus ; +string Fmfont_, Fefont_ ; +numeric Fmscale_, Fescale_, Feraise_ ; + +% Argument +% +% s is a leading minus sign +% m is a 1-digit mantissa +% x is whatever follows the mantissa +% sn is a leading minus for the exponent, and +% e is a 1-digit exponent. +% +% Numbers in scientific notation are constructed by placing +% these pieces side-by-side; decimal numbers use only m +% and/or s. To get exponents with leading plus signs, assign +% to Fe_plus after calling init_numbers. To do something +% special with a unit mantissa followed by x, assign to +% Fe_base after calling init_numbers. + +vardef init_numbers(expr s, m, x, sn, e) = + Fmneg_ := s ; + for p within m : + Fmfont_ := fontpart p ; + Fmscale_ := xxpart p ; + exitif true ; + endfor + Femarker_ := x ; + Feneg_ := sn ; + for p within e : + Fefont_ := fontpart p ; + Fescale_ := xxpart p ; + Feraise_ := ypart llcorner p ; + exitif true ; + endfor + if fmt_metapost : + Fe_base := Fline_up_("1" infont Fmfont_ scaled Fmscale_, Femarker_) ; + % else : + % sFe_base := Fline_up_("1", sFemarker_) ; + fi ; + Fe_plus := nullpicture ; +enddef ; + +%%% Low-Level Typesetting %%% + +vardef Fmant_(expr x) = %%% adapted by HH %%% + if fmt_metapost : + (decimal abs x infont Fmfont_ scaled Fmscale_) + else : + (decimal abs x) + fi +enddef ; + +vardef Fexp_(expr x) = %%% adapted by HH %%% + if fmt_metapost : + (decimal x infont Fefont_ scaled Fescale_ shifted (0,Feraise_)) + else : + (decimal x) + fi +enddef ; + +vardef Fline_up_(text t_) = %%% adapted by HH %%% + if fmt_metapost : + save p_, c_ ; + picture p_ ; p_ = nullpicture ; + pair c_ ; c_ = (0,0) ; + for q_ = t_ : + addto p_ also q_ if string q_ : infont defaultfont scaled defaultscale fi + shifted c_ ; + c_ := (xpart lrcorner p_, 0) ; + endfor + p_ + else : + "" for q_ = t_ : & q_ endfor + fi +enddef ; + +vardef Fdec_o_(expr x) = %%% adapted by HH %%% + if x<0 : + Fline_up_(if fmt_metapost : Fmneg_ else : sFmneg_ fi, Fmant_(x)) + else : + Fmant_(x) + fi +enddef ; + +vardef Fsci_o_(expr x, e) = %%% adapted by HH %%% + if fmt_metapost : + Fline_up_ + (if x < 0 : Fmneg_,fi + if abs x = 1 : Fe_base else : Fmant_(x), Femarker_ fi, + if e < 0 : Feneg_ else : Fe_plus fi, + Fexp_(abs e)) + else : + Fline_up_ + (if x < 0 : sFmneg_, fi + if abs x = 1 : sFe_base else : Fmant_(x), sFemarker_ fi, + sFebraise_, + if e < 0 : sFeneg_ else : sFe_plus fi, + Fexp_(abs e), + sFeeraise_) + fi +enddef ; + +% Assume prologues=1 implies troff mode. TeX users who want +% prologues on should use some other positive value. The mpx +% file mechanism requires separate input files here. +% +% if fmt_initialize : %%% adapted by HH +% if prologues = 1 : input troffnum else : input texnum fi +% fi ; +% +% wrong assumption, so we need: + +if fmt_initialize : + input texnum ; +fi ; + +%%% Scaling and Rounding %%% + +% Find a pair p where x = xpart p*10**ypart p and either p = +% (0,0) or xpart p is between 1000 and 9999.99999. This is +% the `exponent form' of x. + +vardef Feform_(expr x) = + interim warningcheck := 0 ; + if string x : + Meform(Mlog_str x) + else : + save b, e ; + b = x ; e = 0 ; + if abs b >= 10000 : + (b/10, 1) + elseif b = 0 : + origin + else : + forever : + exitif abs b >= 1000 ; + b := b*10 ; e := e-1 ; + endfor + (b, e) + fi + fi +enddef ; + +% The marith.mp macros include a similar macro Meform that +% converts from `Mlog form' to exponent form. In case +% rounding has made the xpart of an exponent form number too +% large, fix it. + +vardef Feadj_(expr x, y) = + if abs x >= 10000 : (x/10, y+1) else : (x,y) fi +enddef ; + +% Round x to d places right of the decimal point. When d<0, +% round to the nearest multiple of 10 to the -d. + +vardef roundd(expr x, d) = + if abs d > 4 : + if d > 0 : x else : 0 fi + elseif d > 0 : + save i ; i = floor x ; + i + round(Ten_to[d]*(x-i))/Ten_to[d] + else : + round(x/Ten_to[-d])*Ten_to[-d] + fi +enddef ; + +Ten_to0 = 1 ; +Ten_to1 = 10 ; +Ten_to2 = 100 ; +Ten_to3 = 1000 ; +Ten_to4 = 10000 ; + +% Round an exponent form number p to k significant figures. + +primarydef p Fprec_ k = + Feadj_(roundd(xpart p,k-4), ypart p) +enddef ; + +% Round an exponent form number p to k digits right of the +% decimal point. + +primarydef p Fdigs_ k = + Feadj_(roundd(xpart p,k+ypart p), ypart p) +enddef ; + +%%% High-Level Routines %%% + +% The following operators convert z from exponent form and +% produce typeset output: Formsci_ generates scientific +% notation; Formdec_ generates decimal notation; and +% Formgen_ generates whatever is likely to be most compact. + +vardef Formsci_(expr z) = %%% adapted by HH %%% + if fmt_zerocheck and (z = origin) : + Fsci_o_(0,0) + else : + Fsci_o_(xpart z/1000, ypart z + 3) + fi +enddef ; + +vardef Formdec_(expr z) = + if ypart z > 0 : + Formsci_(z) + else : + Fdec_o_ + (xpart z if ypart z >= -4 : + /Ten_to[-ypart z] + else : + for i = ypart z upto -5 : /(10) endfor /10000 + fi) + fi +enddef ; + +vardef Formgen_(expr q) = + clearxy ; (x,y) = q ; + if x = 0 : Formdec_ + elseif y >= -6 : Formdec_ + else : Formsci_ + fi (q) +enddef ; + +def Fset_item_(expr s) = %%% adapted by HH %%% + if s <> "" : + if fmt_metapost : + s infont defaultfont scaled defaultscale, + else : + s, + fi + fi +enddef ; + +% For each format letter, the table below tells how to +% round and typeset a quantity z in exponent form. +% +% e scientific, p significant figures +% p decimal, p digits right of the point +% g decimal or scientific, p sig. figs. +% G decimal or scientific, p digits + +string fmt_[] ; + +fmt_[ASCII "e"] = "Formsci_(z Fprec_ p)" ; +fmt_[ASCII "f"] = "Formdec_(z Fdigs_ p)" ; +fmt_[ASCII "g"] = "Formgen_(z Fprec_ p)" ; +fmt_[ASCII "G"] = "Formgen_(z Fdigs_ p)" ; + +% The format and Mformat macros take a format string f and +% generate typeset output for a numeric quantity x. String f +% should contain a `%' followed by an optional number and one +% of the format letters defined above. The number should be +% an integer giving the precision (default 3). + +vardef isfmtseparator primary c = %%% added by HH %%% + ((c <> fmt_separator) and (c <> "%")) +enddef ; + +def initialize_form_numbers = + initialize_numbers ; % in context: do_initialize_numbers ; +enddef ; + +vardef dofmt_@#(expr f, x) = %%% adapted by HH %%% + initialize_form_numbers ; + if f = "" : + if fmt_metapost : nullpicture else : "" fi + else : + interim warningcheck := 0 ; + save k, l, s, p, z ; + pair z ; z = @#(x) ; + % the next adaption is okay + % k = 1 + cspan(f, fmt_separator <> ) ; + % but best is to support both % and fmt_separator + k = 1 + cspan(f, isfmtseparator) ; + % + l-k = cspan(substring(k,infinity) of f, isdigit) ; + p = if l > k : + scantokens substring(k,l) of f + else : + fmt_precision + fi ; + string s ; s = fmt_[ASCII substring (l,l+1) of f] ; + if unknown s : + if k <= length f : + errmessage("No valid format letter found in "&f) ; + fi + s = if fmt_metapost : "nullpicture" else : "" fi ; + fi + Fline_up_ + (Fset_item_(substring (0,k-1) of f) + if not fmt_metapost : sFebmath_, fi + scantokens s, + if not fmt_metapost : sFeemath_, fi + Fset_item_(substring (l+1,infinity) of f) + if fmt_metapost : nullpicture else : "" fi) + fi + hide (fmt_metapost := true) +enddef ; + +%%% so far %%% + +vardef format (expr f, x) = + fmt_metapost := true ; dofmt_.Feform_(f,x) +enddef ; + +vardef Mformat(expr f, x) = + fmt_metapost := true ; dofmt_.Meform (f,x) +enddef ; + +vardef formatstr (expr f, x) = + fmt_metapost := false ; dofmt_.Feform_(f,x) +enddef ; + +vardef Mformatstr(expr f, x) = + fmt_metapost := false ; dofmt_.Meform (f,x) +enddef ; + +% Restore warningcheck to previous value. + +endgroup ; diff --git a/metapost/context/base/mp-func.mp b/metapost/context/base/mp-func.mp new file mode 100644 index 000000000..d8646ef3b --- /dev/null +++ b/metapost/context/base/mp-func.mp @@ -0,0 +1,59 @@ +%D \module +%D [ file=mp-func.mp, +%D version=2001.12.29, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=function 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 licen-en.pdf for +%C details. + +%D Under construction. + +if unknown context_tool : input mp-tool ; fi ; +if known context_func : endinput ; fi ; + +boolean context_func ; context_func := true ; + +string pathconnectors[] ; + +pathconnectors[0] := "," ; +pathconnectors[1] := "--" ; +pathconnectors[2] := ".." ; +pathconnectors[3] := "..." ; + +vardef function (expr f) (expr u, t, b, e, s) = save x ; numeric x ; + for xx := b step s until e : + hide (x := xx ;) if xx>b : scantokens(pathconnectors[f]) fi + (scantokens(u),scantokens(t)) + endfor +enddef ; + +def punkedfunction = function (1) enddef ; +def curvedfunction = function (2) enddef ; +def tightfunction = function (3) enddef ; + +vardef constructedpath (expr f) (text t) = + save ok ; boolean ok ; ok := false ; + for i=t : + if ok : scantokens(pathconnectors[f]) else : ok := true ; fi i + endfor +enddef ; + +def punkedpath = constructedpath (1) enddef ; +def curvedpath = constructedpath (2) enddef ; +def tightpath = constructedpath (3) enddef ; + +vardef constructedpairs (expr f) (text p) = + save i ; i := -1 ; + forever : exitif unknown p[incr(i)] ; + if i>0 : scantokens(pathconnectors[f]) fi p[i] + endfor +enddef ; + +def punkedpairs = constructedpairs (1) enddef ; +def curvedpairs = constructedpairs (2) enddef ; +def tightpairs = constructedpairs (3) enddef ; diff --git a/metapost/context/base/mp-grid.mp b/metapost/context/base/mp-grid.mp new file mode 100644 index 000000000..f6e843489 --- /dev/null +++ b/metapost/context/base/mp-grid.mp @@ -0,0 +1,145 @@ +%D \module +%D [ file=mp-grid.mp, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=grid 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 licen-en.pdf for +%C details. + +%D Under construction. + +if unknown context_tool : input mp-tool ; fi ; +if known context_grid : endinput ; fi ; + +boolean context_grid ; context_grid := true ; + +string fmt_separator ; fmt_separator := "@" ; +numeric fmt_precision ; fmt_precision := 3 ; +boolean fmt_initialize ; fmt_initialize := false ; +boolean fmt_zerocheck ; fmt_zerocheck := true ; + +if unknown fmt_loaded : input mp-form ; fi ; + +boolean fmt_pictures ; fmt_pictures := true ; + +def do_format = if fmt_pictures : format else : formatstr fi enddef ; +def do_mformat = if fmt_pictures : Mformat else : Mformatstr fi enddef ; + +numeric grid_eps ; grid_eps = eps ; + +def hlingrid (expr Min, Max, Step, Length, Width) text t = + image ( for i=Min step Step until Max+grid_eps : + draw (origin--(Width,0)) shifted (0,i*(Length/Max)) t ; + endfor ; ) ; +enddef ; + +def vlingrid (expr Min, Max, Step, Length, Height) text t = + image ( for i=Min step Step until Max+grid_eps : + draw (origin--(0,Height)) shifted (i*(Length/Max),0) t ; + endfor ; ) ; +enddef ; + +def hloggrid (expr Min, Max, Step, Length, Width) text t = + image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw (origin--(Width,0)) shifted (0,Length*log(i)) t ; + endfor ; ) ; +enddef ; + +def vloggrid (expr Min, Max, Step, Length, Height) text t = + image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw (origin--(0,Height)) shifted (Length*log(i),0) t ; + endfor ; ) ; +enddef ; + +vardef hlintext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=Min step Step until Max+grid_eps : + draw textext@#(do_format(Format,i)) shifted (0,i*(Length/Max)) t ; + endfor ; ) +enddef ; + +vardef vlintext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=Min step Step until Max+grid_eps : + draw textext@#(do_format(Format,i)) shifted (i*(Length/Max),0) t ; + endfor ; ) +enddef ; + +vardef hlogtext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw textext@#(do_format(Format,i)) shifted (0,Length*log(i)) t ; + endfor ; ) +enddef ; + +vardef vlogtext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw textext@#(do_format(Format,i)) shifted (Length*log(i),0) t ; + endfor ; ) +enddef ; + +vardef hlinlabel@#(expr Min, Max, Step, Length) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw thelabel@#(decimal i,(0,i*(Length/Max))) t ; + endfor ; ) +enddef ; + +vardef vlinlabel@#(expr Min, Max, Step, Length) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw thelabel@#(decimal i,(i*(Length/Max),0)) t ; + endfor ; ) +enddef ; + +boolean numbers_initialized ; numbers_initialized := false ; + +def do_initialize_numbers = + if not numbers_initialized : + init_numbers ( textext.raw("$-$") , + textext.raw("$1$") , + textext.raw("${\times}10$") , + textext.raw("${}^-$") , + textext.raw("${}^2$") ) ; + numbers_initialized := true ; + fi ; +enddef ; + +def initialize_numbers = + numbers_initialized := false ; do_initialize_numbers ; +enddef ; + +vardef linlog(expr xy) = ( xpart xy, log(ypart xy)) enddef ; +vardef loglin(expr xy) = (log(xpart xy), ypart xy) enddef ; +vardef loglog(expr xy) = (log(xpart xy), log(ypart xy)) enddef ; +vardef linlin(expr xy) = ( (xpart xy), (ypart xy)) enddef ; + +vardef loglinpath primary p = processpath (p) (loglin) enddef ; +vardef linlogpath primary p = processpath (p) (linlog) enddef ; +vardef loglogpath primary p = processpath (p) (loglog) enddef ; +vardef linlinpath primary p = processpath (p) (linlin) enddef ; + +def processpath (expr p) (text pp) = + if path p : + for i=0 upto length(p)-1 : + (pp(point i of p)) .. controls + (pp(postcontrol i of p)) and + (pp(precontrol (i+1) of p)) .. + endfor + if cycle p : + cycle + else : + (pp(point length(p) of p)) + fi + elseif pair p : + (pp(p)) + else : + p + fi +enddef ; diff --git a/metapost/context/base/mp-grph.mp b/metapost/context/base/mp-grph.mp new file mode 100644 index 000000000..243b45318 --- /dev/null +++ b/metapost/context/base/mp-grph.mp @@ -0,0 +1,296 @@ +%D \module +%D [ file=mp-grph.mp, +%D version=2000.12.14, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=graphic text 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 licen-en.pdf for +%C details. + +%D Under construction. + +if unknown context_tool : input mp-tool ; fi ; +if known context_grph : endinput ; fi ; + +boolean context_grph ; context_grph := true ; + +string CRLF ; CRLF := char 10 & char 13 ; + +picture _currentpicture_ ; + +def beginfig (expr c) = + begingroup + charcode := c ; + resetfig ; + scantokens extra_beginfig ; +enddef ; + +def resetfig = + clearxy ; + clearit ; + clearpen ; + pickup defaultpen ; + interim linecap := linecap ; + interim linejoin := linejoin ; + interim miterlimit := miterlimit ; + save _background_ ; color _background_ ; _background_ := background ; + save background ; color background ; background := _background_ ; + drawoptions () ; +enddef ; + +def protectgraphicmacros = + save showtext ; + save beginfig ; let beginfig = begingraphictextfig ; + save endfig ; let endfig = endgraphictextfig ; + save end ; let end = relax ; + interim prologues := prologues ; + resetfig ; % resets currentpicture +enddef ; + +numeric currentgraphictext ; currentgraphictext := 0 ; +string graphictextformat ; graphictextformat := "plain" ; +string graphictextstring ; graphictextstring := "" ; +string graphictextfile ; graphictextfile := "dummy.mpo" ; + +def data_mpo_file = job_name & "-mpgraph.mpo" enddef ; +def data_mpy_file = job_name & "-mpgraph.mpy" enddef ; + +def savegraphictext (expr str) = + if (graphictextstring<>"") : + write graphictextstring to data_mpo_file ; + graphictextstring := "" ; + fi ; + write str to data_mpo_file ; + let erasegraphictextfile = relax ; +enddef ; + +def erasegraphictextfile = + write EOF to data_mpo_file ; + let erasegraphictextfile = relax ; +enddef ; + +extra_beginfig := extra_beginfig & " erasegraphictextfile ;" ; + +def begingraphictextfig (expr n) = + foundpicture := n ; scratchpicture := nullpicture ; +enddef ; + +def endgraphictextfig = + if foundpicture = currentgraphictext : + expandafter endinput + else : + scratchpicture := nullpicture ; + fi ; +enddef ; + +def loadfigure primary filename = + doloadfigure (filename) +enddef ; + +def doloadfigure (expr filename) text figureattributes = + begingroup ; + save figurenumber, figurepicture, number, fixedplace ; + numeric figurenumber ; figurenumber := 0 ; + boolean figureshift ; figureshift := true ; + picture figurepicture ; figurepicture := currentpicture ; + def number primary n = hide(figurenumber := n) enddef ; + def fixedplace = hide(figureshift := false) enddef ; + protectgraphicmacros ; + % defaults + interim linecap := rounded ; + interim linejoin := rounded ; + interim miterlimit := 10 ; + % + currentpicture := nullpicture ; + draw fullcircle figureattributes ; % expand number + currentpicture := nullpicture ; + def beginfig (expr n) = + currentpicture := nullpicture ; + if (figurenumber=n) or (figurenumber=0) : + let endfig = endinput ; + fi ; + enddef ; + let endfig = relax ; + readfile(filename) ; + if figureshift : + currentpicture := currentpicture shifted -llcorner currentpicture ; + fi ; + addto figurepicture also currentpicture figureattributes ; + currentpicture := figurepicture ; + endgroup ; +enddef ; + +def graphictext primary t = + dographictext(t) +enddef ; + +def dographictext (expr t) = + begingroup ; + save figurepicture ; picture figurepicture ; + figurepicture := currentpicture ; currentpicture := nullpicture ; + if graphictextformat<>"" : + graphictextstring := + "% format=" & graphictextformat & CRLF & graphictextstring ; + graphictextformat := "" ; + fi ; + currentgraphictext := currentgraphictext + 1 ; + savegraphictext ("\startTEXpage[scale=10000]" & t & "\stopTEXpage") ; + dofinishgraphictext +enddef ; + +def redographictext primary t = + regraphictext(t) +enddef ; + +def regraphictext (expr t) = + begingroup ; + save figurepicture ; picture figurepicture ; + figurepicture := currentpicture ; currentpicture := nullpicture ; + save currentgraphictext ; numeric currentgraphictext ; + currentgraphictext := t ; + dofinishgraphictext +enddef ; + +%D Believe it or not, but it took me half a day to uncover +%D the following neccessity: +%D +%D \starttypen +%D save withfillcolor, withdrawcolor ; +%D \stoptypen +%D +%D When we have more than one graphictext, these will be +%D defined after the first graphic. For some obscure reason, +%D this means that in the next graphic they will be called, but +%D afterwards the data and boolean are not set. Don't ask me +%D why. + +def dofinishgraphictext text x_op_x = + protectgraphicmacros ; % resets currentpicture + interim linecap := butt ; % normally rounded + interim linejoin := mitered ; % normally rounded + interim miterlimit := 10 ; % todo + let normalwithshade = withshade ; + save foundpicture, scratchpicture, str ; + save fill, draw, withshade, reversefill, outlinefill ; + save withfillcolor, withdrawcolor ; % quite important + numeric foundpicture ; picture scratchpicture ; string str ; + def draw expr p = + % the first, naive implementation was: + % addto scratchpicture doublepath p withpen currentpen ; + % but it is better to turn lines into fills + addto scratchpicture contour boundingbox + image (addto currentpicture doublepath p withpen currentpen) ; + enddef ; + def fill expr p = + addto scratchpicture contour p withpen currentpen ; + enddef ; + def f_op_f = enddef ; boolean f_color ; f_color := false ; + def d_op_d = enddef ; boolean d_color ; d_color := false ; + def s_op_s = enddef ; boolean s_color ; s_color := false ; + boolean reverse_fill ; reverse_fill := false ; + boolean outline_fill ; outline_fill := false ; + def reversefill = + hide(reverse_fill := true ) + enddef ; + def outlinefill = + hide(outline_fill := true ) + enddef ; + def withshade primary c = + hide(def s_op_s = normalwithshade c enddef ; s_color := true ) + enddef ; + def withfillcolor primary c = + hide(def f_op_f = withcolor c enddef ; f_color := true ) + enddef ; + def withdrawcolor primary c = + hide(def d_op_d = withcolor c enddef ; d_color := true ) + enddef ; + scratchpicture := nullpicture ; + addto scratchpicture doublepath origin x_op_x ; % pre-roll + for i within scratchpicture : % Below here is a dirty tricky test! + if (urcorner dashpart i) = origin : outline_fill := false ; fi ; + endfor ; + scratchpicture := nullpicture ; + readfile(data_mpy_file) ; + scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ; + if not d_color and not f_color : d_color := true ; fi + if s_color : d_color := false ; f_color := false ; fi ; + currentpicture := figurepicture ; + if d_color and not reverse_fill : + for i within scratchpicture : + if f_color and outline_fill : + addto currentpicture doublepath pathpart i _op_ x_op_x f_op_f + dashed nullpicture ; + fi ; + if filled i : + addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; + fi ; + endfor ; + fi ; + if f_color : + for i within scratchpicture : + if filled i : + addto currentpicture contour pathpart i _op_ x_op_x f_op_f + withpen pencircle scaled 0 ; + fi ; + endfor ; + fi ; + if d_color and reverse_fill : + for i within scratchpicture : + if filled i : + addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; + fi ; + endfor ; + fi ; + if s_color : + for i within scratchpicture : + if filled i : + addto currentpicture contour pathpart i _op_ x_op_x s_op_s ; + fi ; + endfor ; + else : + for i within scratchpicture : + if stroked i : + addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; + fi ; + endfor ; + fi ; + endgroup ; +enddef ; + +def resetgraphictextdirective = + graphictextstring := "" ; +enddef ; + +def graphictextdirective text t = + graphictextstring := graphictextstring & t & CRLF ; +enddef ; + +endinput + +% example + +input mp-grph ; + + graphictextformat := "context" ; +% graphictextformat := "plain" ; +% graphictextformat := "latex" ; graphictextdirective "\documentclass[]{article}" ; + +beginfig (1) ; + graphictext + "\vbox{\hsize10cm \input tufte }" + scaled 8 + withdrawcolor blue + withfillcolor red + withpen pencircle scaled 2pt ; +endfig ; + +beginfig(1) ; + loadfigure "gracht.mp" rotated 20 ; + loadfigure "koe.mp" number 1 scaled 2 ; +endfig ; + +end diff --git a/metapost/context/base/mp-mlib.mp b/metapost/context/base/mp-mlib.mp new file mode 100644 index 000000000..bf2372ca3 --- /dev/null +++ b/metapost/context/base/mp-mlib.mp @@ -0,0 +1,282 @@ +%D \module +%D [ file=mp-mlib.mp, +%D version=2008.03.21, +%D title=\CONTEXT\ \METAPOST\ graphics, +%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 licen-en.pdf for +%C details. + +if unknown mplib : endinput ; fi ; +if known context_mlib : endinput ; fi ; + +boolean context_mlib ; context_mlib := true ; + +numeric _tt_w_[], _tt_h_[], _tt_d_[] ; +numeric _tt_n_ ; _tt_n_ := 0 ; +picture _tt_p_ ; _tt_p_ := nullpicture ; +boolean _trial_run_ ; _trial_run_ := false ; + +def resettextexts = + _tt_n_ := 0 ; + _tt_p_ := nullpicture ; +enddef ; + +extra_endfig := ";addto currentpicture also _tt_p_; " & extra_endfig; % was draw _tt_p_ +extra_beginfig := extra_beginfig & "resettextexts;"; + +vardef rawtextext(expr str) = + if str = "" : + nullpicture + elseif _trial_run_ : + image ( + _tt_n_ := _tt_n_ + 1 ; + _tt_p_ := image ( + addto currentpicture also _tt_p_ ; + addto currentpicture doublepath unitsquare withprescript "tf" withpostscript decimal _tt_n_ & ":" & str ; + ) ; + addto currentpicture doublepath unitsquare withpen pencircle scaled 0 ; + ) + else : + image ( + _tt_n_ := _tt_n_ + 1 ; + addto currentpicture doublepath unitsquare + xscaled _tt_w_[_tt_n_] + yscaled (_tt_h_[_tt_n_] + _tt_d_[_tt_n_]) + withprescript "ts" + withpostscript decimal _tt_n_ & ":" & str ; + ) shifted (0,-_tt_d_[_tt_n_]) + fi +enddef ; + +% not ok yet + +pair laboff.d, laboff.dlft, laboff.drt ; % new positional suffixes +pair laboff.origin, laboff.raw ; % graph mess + +laboff.d := laboff ; labxf.d := labxf ; labyf.d := labyf ; +laboff.dlft := laboff.lft ; labxf.dlft := labxf.lft ; labyf.dlft := labyf.lft ; +laboff.drt := laboff.rt ; labxf.drt := labxf.rt ; labyf.drt := labyf.rt ; + +labtype := 0 ; labtype.lft := 1 ; labtype.rt := 2 ; +labtype.bot := 3 ; labtype.top := 4 ; labtype.ulft := 5 ; +labtype.urt := 6 ; labtype.llft := 7 ; labtype.lrt := 8 ; +labtype.d := 10 ; labtype.dlft := 11 ; labtype.drt := 12 ; +labtype.origin := 0 ; labtype.raw := 0 ; + +% laboff.origin = (infinity,infinity) ; labxf.origin := 0 ; labyf.origin := 0 ; +% laboff.raw = (infinity,infinity) ; labxf.raw := 0 ; labyf.raw := 0 ; + +% todo: thelabel.origin("xxxx",origin) (overflows) + +laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ; +laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ; + +pair laboff.l ; laboff.l = laboff.lft ; +pair laboff.r ; laboff.r = laboff.rt ; +pair laboff.b ; laboff.b = laboff.bot ; +pair laboff.t ; laboff.t = laboff.top ; +pair laboff.l_t ; laboff.l_t = laboff.ulft ; +pair laboff.r_t ; laboff.r_t = laboff.urt ; +pair laboff.l_b ; laboff.l_b = laboff.llft ; +pair laboff.r_b ; laboff.r_b = laboff.lrt ; +pair laboff.t_l ; laboff.t_l = laboff.ulft ; +pair laboff.t_r ; laboff.t_r = laboff.urt ; +pair laboff.b_l ; laboff.b_l = laboff.llft ; +pair laboff.b_r ; laboff.b_r = laboff.lrt ; + +labxf.l ; labxf.l = labxf.lft ; +labxf.r ; labxf.r = labxf.rt ; +labxf.b ; labxf.b = labxf.bot ; +labxf.t ; labxf.t = labxf.top ; +labxf.l_t ; labxf.l_t = labxf.ulft ; +labxf.r_t ; labxf.r_t = labxf.urt ; +labxf.l_b ; labxf.l_b = labxf.llft ; +labxf.r_b ; labxf.r_b = labxf.lrt ; +labxf.t_l ; labxf.t_l = labxf.ulft ; +labxf.t_r ; labxf.t_r = labxf.urt ; +labxf.b_l ; labxf.b_l = labxf.llft ; +labxf.b_r ; labxf.b_r = labxf.lrt ; + +labyf.l ; labyf.l = labyf.lft ; +labyf.r ; labyf.r = labyf.rt ; +labyf.b ; labyf.b = labyf.bot ; +labyf.t ; labyf.t = labyf.top ; +labyf.l_t ; labyf.l_t = labyf.ulft ; +labyf.r_t ; labyf.r_t = labyf.urt ; +labyf.l_b ; labyf.l_b = labyf.llft ; +labyf.r_b ; labyf.r_b = labyf.lrt ; +labyf.t_l ; labyf.t_l = labyf.ulft ; +labyf.t_r ; labyf.t_r = labyf.urt ; +labyf.b_l ; labyf.b_l = labyf.llft ; +labyf.b_r ; labyf.b_r = labyf.lrt ; + +labtype.l ; labtype.l = labtype.lft ; +labtype.r ; labtype.r = labtype.rt ; +labtype.b ; labtype.b = labtype.bot ; +labtype.t ; labtype.t = labtype.top ; +labtype.l_t ; labtype.l_t = labtype.ulft ; +labtype.r_t ; labtype.r_t = labtype.urt ; +labtype.l_b ; labtype.l_b = labtype.llft ; +labtype.r_b ; labtype.r_b = labtype.lrt ; +labtype.t_l ; labtype.t_l = labtype.ulft ; +labtype.t_r ; labtype.t_r = labtype.urt ; +labtype.b_l ; labtype.b_l = labtype.llft ; +labtype.b_r ; labtype.b_r = labtype.lrt ; + +vardef thetextext@#(expr p,z) = % adapted copy of thelabel@ + if string p : + thetextext@#(rawtextext(p),z) + else : + p + if (labtype@# >= 10) : shifted (0,ypart center p) fi + shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) + fi +enddef ; + +vardef textext@#(expr txt) = + interim labeloffset := textextoffset ; + if string txt : + thetextext@#(rawtextext(txt),origin) + else : + thetextext@#(txt,origin) + fi +enddef ; + +% \starttext +% \startMPpage +% numeric value ; value = 123 ; +% label.lft(decimal value,origin) ; +% draw "oeps" infont defaultfont ; +% \stopMPpage +% \stoptext + +vardef thelabel@#(expr s, z) = + save p ; picture p ; + if picture s : + p = s ; + else : + p = textext("\definedfont[" & defaultfont & "]" & s) scaled defaultscale ; + fi ; + p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) +enddef; + +let normalinfont = infont ; + +primarydef str infont name = % very naughty ! + if name = "" : + textext(str) + else : + textext("\definedfont[" & name & "]" & str) + fi +enddef ; + +def circular_shade (expr p, n, ca, cb) = + begingroup ; + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + fill p withcircularshade(ab,ab,0,r,ca,cb) ; + if trace_shades : + drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; +def linear_shade (expr p, n, ca, cb) = + begingroup ; + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + fill p withlinearshade(a,b,ca,cb) ; + if trace_shades : + drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; +def withcircularshade (expr a, b, ra, rb, ca, cb) = + withprescript + "cs" + withpostscript + "0 1 " & decimal shadefactor & " " & + colordecimals ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + colordecimals cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb +enddef ; +def withlinearshade (expr a, b, ca, cb) = + withprescript + "ls" + withpostscript + "0 1 " & decimal shadefactor & " " & + colordecimals ca & " " & ddecimal (a shifted shadeoffset) & " " & + colordecimals cb & " " & ddecimal (b shifted shadeoffset) +enddef ; +string _defined_cs_pre_[], _defined_cs_post_[] ; numeric _defined_cs_ ; _defined_cs_:= 0 ; +vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = + _defined_cs_ := _defined_cs_ + 1 ; + _defined_cs_pre_ [_defined_cs_] := "cs" ; + _defined_cs_post_[_defined_cs_] := "0 1 " & decimal shadefactor & " " & + colordecimals ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + colordecimals cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ; + _defined_cs_ +enddef ; +vardef define_linear_shade (expr a, b, ca, cb) = + _defined_cs_ := _defined_cs_ + 1 ; + _defined_cs_pre_ [_defined_cs_] := "ls" ; + _defined_cs_post_[_defined_cs_] := "0 1 " & decimal shadefactor & " " & + colordecimals ca & " " & ddecimal (a shifted shadeoffset) & " " & + colordecimals cb & " " & ddecimal (b shifted shadeoffset) ; + _defined_cs_ +enddef ; +primarydef p withshade sc = + p withprescript _defined_cs_pre_[sc] withpostscript _defined_cs_post_[sc] +enddef ; +def shadecolor(expr sc) = % obsolete + 1 withprescript _defined_cs_pre_[sc] withpostscript _defined_cs_post_[sc] +enddef ; + +def graphictext primary t = + if _trial_run_ : + let dographictextindeed = nographictext ; + else : + let dographictextindeed = dographictext ; + fi + dographictextindeed(t) +enddef ; +def dographictext (expr t) = + begingroup ; + save figurepicture ; picture figurepicture ; + figurepicture := currentpicture ; currentpicture := nullpicture ; + currentgraphictext := currentgraphictext + 1 ; + dofinishgraphictext +enddef ; +def nographictext (expr t) text rest = + draw unitsquare withprescript "gt" withpostscript t ; +enddef ; +def savegraphictext (expr str) = +enddef ; +def erasegraphictextfile = +enddef ; + +def externalfigure primary filename = + doexternalfigure (filename) +enddef ; +def doexternalfigure (expr filename) text transformation = + draw unitsquare transformation withprescript "fg" withpostscript filename ; +enddef ; + +def register (expr label, width, height, offset) = + draw unitsquare xscaled width yscaled height shifted offset withprescript "ps" withpostscript label ; +enddef ; + +extra_beginfig := extra_beginfig & "currentgraphictext := 0 ; " ; +extra_endfig := extra_endfig & "finishsavingdata ; " ; +extra_endfig := extra_endfig & "resettextexts ; " ; + +boolean cmykcolors ; cmykcolors := true ; +boolean spotcolors ; spotcolors := true ; + +vardef verbatim(expr str) = + ditto & "\detokenize{" & str & "}" & ditto +enddef ; diff --git a/metapost/context/base/mp-page.mp b/metapost/context/base/mp-page.mp new file mode 100644 index 000000000..60bfb1417 --- /dev/null +++ b/metapost/context/base/mp-page.mp @@ -0,0 +1,474 @@ +%D \module +%D [ file=mp-page.mp, +%D version=1999.03.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=page enhancements, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%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 preliminary and subjected to +%D changes. + +if unknown context_tool : input mp-tool ; fi ; +if known context_page : endinput ; fi ; + +boolean context_page ; context_page := true ; + +if unknown PageStateAvailable : + boolean PageStateAvailable ; PageStateAvailable := false ; +fi ; + +if unknown OnRightPage : + boolean OnRightPage ; OnRightPage := true ; +fi ; + +if unknown OnOddPage : + boolean OnOddPage ; OnOddPage := true ; +fi ; + +if unknown InPageBody : + boolean InPageBody ; InPageBody := false ; +fi ; + +def SaveTextAreas = + path SavedTextAreas [] ; + path SavedTextColumns[] ; + numeric NOfSavedTextAreas ; + numeric NOfSavedTextColumns ; + for i=1 upto NOfTextAreas : + SavedTextAreas[i] := TextAreas[i] ; + endfor ; + for i=1 upto NOfTextColumns : + SavedTextColumns[i] := TextColumns[i] ; + endfor ; + NOfSavedTextAreas := NOfTextAreas ; + NOfSavedTextColumns := NOfTextColumns ; +enddef ; + +def ResetTextAreas = + path TextAreas[], TextColumns[] ; + numeric NOfTextAreas ; NOfTextAreas := 0 ; + numeric NOfTextColumns ; NOfTextColumns := 0 ; + numeric nofmultipars ; nofmultipars := 0 ; + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetTextAreas ; SaveTextAreas ; ; + +def RegisterTextArea (expr x, y, w, h, d) = + begingroup ; save p ; path p ; + p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; + if NOfTextAreas>0 : + % if needed, concatenate areas + if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and + (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) : + p := ulcorner TextAreas[NOfTextAreas] -- + urcorner TextAreas[NOfTextAreas] -- + lrcorner p -- + llcorner p -- + cycle ; + else : + NOfTextAreas := NOfTextAreas + 1 ; + fi ; + else : + NOfTextAreas := NOfTextAreas + 1 ; + fi ; + TextAreas[NOfTextAreas] := p ; + if NOfTextColumns>0 : + if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and + (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) : + p := ulcorner TextColumns[NOfTextColumns] -- + urcorner TextColumns[NOfTextColumns] -- + lrcorner p -- + llcorner p -- + cycle ; + else : + NOfTextColumns := NOfTextColumns + 1 ; + fi ; + else : + NOfTextColumns := NOfTextColumns + 1 ; + fi ; + TextColumns[NOfTextColumns] := p ; + endgroup ; +enddef ; + +%D We store a local area in slot zero. + +def RegisterLocalTextArea (expr x, y, w, h, d) = + TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; +enddef ; + +def ResetLocalTextArea = + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetLocalTextArea ; + +vardef InsideTextArea (expr _i_, _xy_) = + ( (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and + (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and + (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and + (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) ) +enddef ; + +vardef InsideSavedTextArea (expr _i_, _xy_) = + ( (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and + (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and + (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and + (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) ) +enddef ; + +vardef InsideSomeTextArea(expr _xy_) = + save ok ; boolean ok ; ok := false ; + for i := 1 upto NOfTextAreas : + if InsideTextArea(i,_xy_) : ok := true ; fi ; + exitif ok ; + endfor ; + ok +enddef ; + +vardef InsideSomeSavedTextArea(expr _xy_) = + save ok ; boolean ok ; ok := false ; + for i := 1 upto NOfSavedTextAreas : + if InsideSavedTextArea(i,_xy_) : ok := true ; fi ; + exitif ok ; + endfor ; + ok +enddef ; + +vardef TextAreaX (expr x) = + numeric _TextAreaX_ ; _TextAreaX_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) : + _TextAreaX_ := xpart llcorner TextAreas[i] ; + fi ; + endfor ; + _TextAreaX_ +enddef ; + +vardef TextAreaY (expr y) = + numeric _TextAreaY_ ; _TextAreaY_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and + (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) : + _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ; + fi ; + endfor ; + _TextAreaY_ +enddef ; + +vardef TextAreaXY (expr x, y) = + pair _TextAreaXY_ ; _TextAreaXY_ := origin ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) and + (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaXY_ := llconer TextAreas[i] ; + fi ; + endfor ; + _TextAreaXY_ +enddef ; + +vardef TextAreaW (expr x) = + numeric _TextAreaW_ ; _TextAreaW_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) : + _TextAreaW_ := bbwidth(TextAreas[i]) ; + fi ; + endfor ; + _TextAreaW_ +enddef ; + +vardef TextAreaH (expr y) = + numeric _TextAreaH_ ; _TextAreaH_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaH_ := bbheight(TextAreas[i]) ; + fi ; + endfor ; + _TextAreaH_ +enddef ; + +vardef TextAreaWH (expr x, y) = + pair _TextAreaWH_ ; _TextAreaWH_ := origin ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) and + (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ; + fi ; + endfor ; + _TextAreaWH_ +enddef ; + +PageNumber := 0 ; +PaperHeight := 845.04684pt ; +PaperWidth := 597.50787pt ; +PrintPaperHeight := 845.04684pt ; +PrintPaperWidth := 597.50787pt ; +TopSpace := 71.12546pt ; +BottomSpace := 0.0pt ; +BackSpace := 71.13275pt ; +CutSpace := 0.0pt ; +MakeupHeight := 711.3191pt ; +MakeupWidth := 426.78743pt ; +TopHeight := 0.0pt ; +TopDistance := 0.0pt ; +HeaderHeight := 56.90294pt ; +HeaderDistance := 0.0pt ; +TextHeight := 597.51323pt ; +FooterDistance := 0.0pt ; +FooterHeight := 56.90294pt ; +BottomDistance := 0.0pt ; +BottomHeight := 0.0pt ; +LeftEdgeWidth := 0.0pt ; +LeftEdgeDistance := 0.0pt ; +LeftMarginWidth := 75.58197pt ; +LeftMarginDistance := 11.99829pt ; +TextWidth := 426.78743pt ; +RightMarginDistance := 11.99829pt ; +RightMarginWidth := 75.58197pt ; +RightEdgeDistance := 0.0pt ; +RightEdgeWidth := 0.0pt ; + +PageOffset := 0.0pt ; +PageDepth := 0.0pt ; + +LayoutColumns := 0 ; +LayoutColumnDistance:= 0.0pt ; +LayoutColumnWidth := 0.0pt ; + +LeftEdge := -4 ; Top := -40 ; +LeftEdgeSeparator := -3 ; TopSeparator := -30 ; +LeftMargin := -2 ; Header := -20 ; +LeftMarginSeparator := -1 ; HeaderSeparator := -10 ; +Text := 0 ; Text := 0 ; +RightMarginSeparator := +1 ; FooterSeparator := +10 ; +RightMargin := +2 ; Footer := +20 ; +RightEdgeSeparator := +3 ; BottomSeparator := +30 ; +RightEdge := +4 ; Bottom := +40 ; + +Margin := LeftMargin ; % obsolete +Edge := LeftEdge ; % obsolete +InnerMargin := RightMargin ; % obsolete +InnerEdge := RightEdge ; % obsolete +OuterMargin := LeftMargin ; % obsolete +OuterEdge := LeftEdge ; % obsolete + +InnerMarginWidth := 0pt ; +OuterMarginWidth := 0pt ; +InnerMarginDistance := 0pt ; +OuterMarginDistance := 0pt ; + +InnerEdgeWidth := 0pt ; +OuterEdgeWidth := 0pt ; +InnerEdgeDistance := 0pt ; +OuterEdgeDistance := 0pt ; + +path Area [][] ; pair Location [][] ; path Field [][] ; path Page ; +numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ; +numeric VerPos ; numeric Vstep [] ; numeric Vsize [] ; + +for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Area[HorPos][VerPos] := origin--cycle ; + Area[VerPos][HorPos] := Area[HorPos][VerPos] ; + Location[HorPos][VerPos] := origin ; + Location[VerPos][HorPos] := Location[HorPos][VerPos] ; + Field[HorPos][VerPos] := origin--cycle ; + Field[VerPos][HorPos] := Field[HorPos][VerPos] ; + endfor ; +endfor ; + +% def LoadPageState = +% scantokens "input mp-state.tmp" ; +% enddef ; + +def SwapPageState = + if not OnRightPage : + BackSpace := PaperWidth-MakeupWidth-BackSpace ; + CutSpace := PaperWidth-MakeupWidth-CutSpace ; + i := LeftMarginWidth ; + LeftMarginWidth := RightMarginWidth ; + RightMarginWidth := i ; + i := LeftMarginDistance ; + LeftMarginDistance := RightMarginDistance ; + RightMarginDistance := i ; + i := LeftEdgeWidth ; + LeftEdgeWidth := RightEdgeWidth ; + RightEdgeWidth := i ; + i := LeftEdgeDistance ; + LeftEdgeDistance := RightEdgeDistance ; + RightEdgeDistance := i ; + +% these are now available as ..Width and ..Distance + + Margin := LeftMargin ; + Edge := LeftEdge ; + InnerMargin := RightMargin ; + InnerEdge := RightEdge ; + OuterMargin := LeftMargin ; + OuterEdge := LeftEdge ; + else : + Margin := RightMargin ; + Edge := RightEdge ; + InnerMargin := LeftMargin ; + InnerEdge := LeftEdge ; + OuterMargin := RightMargin ; + OuterEdge := RightEdge ; + fi ; +enddef ; + +def SetPageAreas = + + numeric Vsize[], Hsize[], Vstep[], Hstep[] ; + + Vsize[Top] = TopHeight ; + Vsize[TopSeparator] = TopDistance ; + Vsize[Header] = HeaderHeight ; + Vsize[HeaderSeparator] = HeaderDistance ; + Vsize[Text] = TextHeight ; + Vsize[FooterSeparator] = FooterDistance ; + Vsize[Footer] = FooterHeight ; + Vsize[BottomSeparator] = BottomDistance ; + Vsize[Bottom] = BottomHeight ; + + Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; + Vstep[TopSeparator] = PaperHeight-TopSpace ; + Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; + Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; + Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; + Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; + Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; + Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; + Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; + + Hsize[LeftEdge] = LeftEdgeWidth ; + Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; + Hsize[LeftMargin] = LeftMarginWidth ; + Hsize[LeftMarginSeparator] = LeftMarginDistance ; + Hsize[Text] = MakeupWidth ; + Hsize[RightMarginSeparator] = RightMarginDistance ; + Hsize[RightMargin] = RightMarginWidth ; + Hsize[RightEdgeSeparator] = RightEdgeDistance ; + Hsize[RightEdge] = RightEdgeWidth ; + + Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; + Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; + Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; + Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; + Hstep[Text] = BackSpace ; + Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; + Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; + Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; + Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; + + for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; + Area[VerPos][HorPos] := Area[HorPos][VerPos] ; + Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; + Location[VerPos][HorPos] := Location[HorPos][VerPos] ; + Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ; + Field[VerPos][HorPos] := Field[HorPos][VerPos] ; + endfor ; + endfor ; + + Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; + +enddef ; + +def BoundPageAreas = + + % pickup pencircle scaled 0pt ; + + bboxmargin := 0 ; setbounds currentpicture to Page ; + +enddef ; + +def StartPage = + + if PageStateAvailable : + LoadPageState ; + SwapPageState ; + fi ; + + SetPageAreas ; + BoundPageAreas ; + +enddef ; + +def StopPage = + + BoundPageAreas ; + +enddef ; + +def OverlayBox = + (unitsquare xyscaled (OverlayWidth,OverlayHeight)) +enddef ; + +% handy + +def innerenlarged = + hide(LoadPageState) + if OnRightPage : leftenlarged else : rightenlarged fi +enddef ; + +def outerenlarged = + hide(LoadPageState) + if OnRightPage : rightenlarged else : leftenlarged fi +enddef ; + +% obsolete + +def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ; +def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ; +def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ; +def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ; + +def Enlarged (expr p, d) = + (llEnlarged (p,d) -- + lrEnlarged (p,d) -- + urEnlarged (p,d) -- + ulEnlarged (p,d) -- cycle) +enddef ; + +% New: + +def position_anchor_bar(expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self, + distance, linewidth, linecolor) = + StartPage ; + path p ; p := + if p_b_self=p_e_self : + (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) -- + (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ; + elseif RealPageNumber=p_b_self : + (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) -- + (llcorner Field[Text][Text]) ; + elseif RealPageNumber=p_e_self : + (ulcorner Field[Text][Text]) -- + (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ; + else : + (ulcorner Field[Text][Text]) -- + (llcorner Field[Text][Text]) ; + fi ; + p := p shifted (-llcorner Field[Text][Text]-(distance,0)) ; + interim linecap := butt ; + draw p + withpen pencircle scaled linewidth + withcolor linecolor ; + StopPage ; +enddef ; + +endinput ; diff --git a/metapost/context/base/mp-shap.mp b/metapost/context/base/mp-shap.mp new file mode 100644 index 000000000..0f5fe431d --- /dev/null +++ b/metapost/context/base/mp-shap.mp @@ -0,0 +1,307 @@ +%D \module +%D [ file=mp-shap.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=shapes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={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. + +if unknown context_tool : input mp-tool ; fi ; +if known context_shap : endinput ; fi ; + +boolean context_shap ; context_shap := true ; + +vardef some_shape_path (expr type) = + + begingroup ; + + save border, xradius, yradius, + normal, mirror, rotate, + lc, rc, tc, bc, ll, lr, ur, ul, + llx, lrx, urx, ulx, lly, lry, ury, uly ; + + path border ; + + xradius := .15 ; xxradius := .10 ; + yradius := .15 ; yyradius := .10 ; + + pair ll ; ll := llcorner (unitsquare shifted (-.5,-.5)) ; + pair lr ; lr := lrcorner (unitsquare shifted (-.5,-.5)) ; + pair ur ; ur := urcorner (unitsquare shifted (-.5,-.5)) ; + pair ul ; ul := ulcorner (unitsquare shifted (-.5,-.5)) ; + + pair llx ; llx := ll shifted (xradius,0) ; + pair lly ; lly := ll shifted (0,yradius) ; + + pair lrx ; lrx := lr shifted (-xradius,0) ; + pair lry ; lry := lr shifted (0,yradius) ; + + pair urx ; urx := ur shifted (-xradius,0) ; + pair ury ; ury := ur shifted (0,-yradius) ; + + pair ulx ; ulx := ul shifted (xradius,0) ; + pair uly ; uly := ul shifted (0,-yradius) ; + + pair llxx ; llxx := ll shifted (xxradius,0) ; + pair llyy ; llyy := ll shifted (0,yyradius) ; + + pair lrxx ; lrxx := lr shifted (-xxradius,0) ; + pair lryy ; lryy := lr shifted (0,yyradius) ; + + pair urxx ; urxx := ur shifted (-xxradius,0) ; + pair uryy ; uryy := ur shifted (0,-yyradius) ; + + pair ulxx ; ulxx := ul shifted (xxradius,0) ; + pair ulyy ; ulyy := ul shifted (0,-yyradius) ; + + pair lc ; lc := ll shifted (0,.5) ; + pair rc ; rc := lr shifted (0,.5) ; + pair tc ; tc := ul shifted (.5,0) ; + pair bc ; bc := ll shifted (.5,0) ; + + def mirror (expr p) = + p rotatedaround(origin,180) + enddef ; + + def normal (expr p ) = + p + enddef ; + + def rotate (expr p) = + p rotated 45 + enddef ; + + if type= 0 : + border := normal (origin--cycle) ; + + elseif type= 5 : + border := normal (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ; + elseif type= 6 : + border := normal (ll--lrx{right}...rc...{left}urx--ul--cycle) ; + elseif type= 7 : + border := mirror (ll--lrx{right}...rc...{left}urx--ul--cycle) ; + elseif type= 8 : + border := normal (lr--ury{up}...tc...{down}uly--ll--cycle) ; + elseif type= 9 : + border := mirror (lr--ury{up}...tc...{down}uly--ll--cycle) ; + elseif type=10 : + border := normal (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ; + elseif type=11 : + border := normal (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ; + elseif type=12 : + border := normal (ll--lrx--ur--ulx--cycle) ; + elseif type=13 : + border := normal (llx--lr--urx--ul--cycle) ; + elseif type=14 : + border := normal (lly--bc--lry--ury--tc--uly--cycle) ; + elseif type=15 : + border := normal (llx--lrx--rc--urx--ulx--lc--cycle) ; + elseif type=16 : + border := normal (ll--lrx--rc--urx--ul--cycle) ; + elseif type=17 : + border := mirror (ll--lrx--rc--urx--ul--cycle) ; + elseif type=18 : + border := normal (lr--ury--tc--uly--ll--cycle) ; + elseif type=19 : + border := mirror (lr--ury--tc--uly--ll--cycle) ; + elseif type=20 : + border := normal (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll-- + lr--ur--urxx--lrxx--cycle) ; + elseif type=21 : + border := normal (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul-- + ll--lr--lryy--llyy--cycle) ; + elseif type=22 : + border := normal (ll--lrx--lry--ur--ulx--uly--cycle) ; + elseif type=23 : + border := normal (llx--lr--ury--urx--ul--lly--cycle) ; + elseif type=24 : + border := normal (ll--lr--ur--ul--cycle) ; + elseif type=25 : + border := normal (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ; + elseif type=26 : + border := normal (ll--lrx--lry--ur--ul--cycle) ; + elseif type=27 : + border := mirror (ll--lr--ury--urx--ul--cycle) ; + elseif type=28 : + border := normal (ll--lr--ury--urx--ul--cycle) ; + elseif type=29 : + border := mirror (ll--lrx--lry--ur--ul--cycle) ; + elseif type=30 : + border := rotate (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & + bc--tc & tc{left}..{down}lc & lc--rc & + rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; + elseif type=31 : + border := normal (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & + bc--tc & tc{left}..{down}lc & lc--rc & + rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; + elseif type=32 : + border := normal (ll{right}...{right}lry--ur--ul--ll--cycle) ; + elseif type=33 : + border := normal (ll{right}...{right}lry--ur--ul--ll--cycle + --ul--ulx--ulx shifted(0,yyradius) + --ur shifted(yyradius,yyradius) + --lry shifted(yyradius,yyradius) + --lry shifted(0,yyradius) + --ur--ul--cycle ) ; + elseif type=34 : + border := normal (uly..tc..ury & + ury..tc shifted (0,-2yradius)..uly & + uly--lly & + lly..bc..lry & + lry--ury & + ury..tc shifted (0,-2yradius)..uly & cycle ) ; + elseif type=35 : + border := normal (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ; + elseif type=36 : + border := normal (ul--tc{right}..rc{down}..{left}bc--ll & + ll..(xpart llx, ypart lc)..ul & cycle) ; + elseif type=37 : + border := mirror (ul--tc{right}..rc{down}..{left}bc--ll & + ll..(xpart llx, ypart lc)..ul & cycle) ; + elseif type=38 : + border := normal (ll--lc{up}..tc{right}..{down}rc--lr & + lr..(xpart bc, ypart lly)..ll & cycle) ; + elseif type=39 : + border := mirror (ll--lc{up}..tc{right}..{down}rc--lr & + lr..(xpart bc, ypart lly)..ll & cycle) ; + elseif type=40 : + border := normal (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ; + elseif type=41 : + border := normal (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ; + elseif type=42 : + border := normal (ll--lr--origin shifted (+epsilon,0)-- + ur--ul--origin shifted (-epsilon,0)--cycle) ; + elseif type=43 : + border := normal (ll--ul--origin shifted (0,+epsilon)-- + ur--lr--origin shifted (0,-epsilon)--cycle) ; + elseif type=45 : + border := normal (bc--rc--tc--lc--cycle) ; + elseif type=46 : + border := normal (ll--ul--rc--cycle) ; + elseif type=47 : + border := mirror (ll--ul--rc--cycle) ; + elseif type=48 : + border := mirror (ul--ur--bc--cycle) ; + elseif type=49 : + border := normal (ul--ur--bc--cycle) ; + + elseif type=56 : + border := normal (ll--lry--ury--ul--cycle) ; + elseif type=57 : + border := mirror (ll--lry--ury--ul--cycle) ; + elseif type=58 : + border := normal (ll--ulx--urx--lr--cycle) ; + elseif type=59 : + border := mirror (ll--ulx--urx--lr--cycle) ; + + elseif type=61 : + border := normal (fullcircle scaled (1.5*yradius) xscaled (grid_height/grid_width)) ; + elseif type=62 : + border := normal (fullcircle scaled (2.0*yradius) xscaled (grid_height/grid_width)) ; + + elseif type=66 : + border := normal (rc--origin shifted ( epsilon,0) --cycle & + rc--origin --cycle ) ; + elseif type=67 : + border := normal (lc--origin shifted (-epsilon,0) --cycle & + lc--origin --cycle ) ; + elseif type=68 : + border := normal (tc--origin shifted (0, epsilon) --cycle & + tc--origin --cycle ) ; + elseif type=69 : + border := normal (bc--origin shifted (0,-epsilon) --cycle & + bc--origin --cycle ) ; + + elseif type=75 : + border := mirror (lly--lry--ury--uly--cycle) ; + elseif type=76 : + border := mirror (ll--lr--ur--uly--cycle) ; + elseif type=77 : + border := mirror (ll--lr--ury--ul--cycle) ; + elseif type=78 : + border := mirror (lly--lr--ur--ul--cycle) ; + elseif type=79 : + border := mirror (ll--lry--ur--ul--cycle) ; + + else : + border := normal (origin--cycle) ; + %border := normal (ll--lr--ur--ul--cycle) ; + fi ; + + border + + endgroup + +enddef; + +def some_shape ( expr shape_type , + shape_width , + shape_height , + shape_linewidth , + shape_linecolor , + shape_fillcolor ) = + + path p ; p := + some_shape_path (shape_type) + xscaled shape_width + yscaled shape_height ; + + pickup pencircle scaled shape_linewidth ; + + fill p withcolor shape_fillcolor ; + draw p withcolor shape_linecolor ; + +enddef ; + +vardef drawshape (expr t, p, lw, lc, fc) = + save pp ; + if t>1 : % normal shape + path pp ; + pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + fill pp withcolor fc ; + draw pp withpen pencircle scaled lw withcolor lc ; + elseif t=1 : % background only + path pp ; + pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + fill pp withcolor fc ; + else : % dimensions only + picture pp ; pp := nullpicture ; + setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + draw pp ; + fi ; +enddef ; + +vardef drawline (expr t, p, lw, lc) = + if (t>0) and (length(p)>1) : + saveoptions ; + drawoptions(withpen pencircle scaled lw withcolor lc) ; + draw p ; + if t = 1 : + draw arrowheadonpath(p,1) ; + elseif t = 2 : + draw arrowheadonpath(reverse p,1) ; + elseif t = 3 : + for $ = p,reverse p : draw arrowheadonpath($,1) ; endfor ; + elseif t = 11 : + draw arrowheadonpath(p,1/2) ; + elseif t = 12 : + draw arrowheadonpath(reverse p,1/2) ; + elseif t = 13 : + for $=p,reverse p : draw arrowheadonpath($,1) ; endfor ; + for $=p,reverse p : draw arrowheadonpath($,3/4) ; endfor ; + elseif t = 21 : + for $=1/5,1/2,4/5 : draw arrowheadonpath(p,$) ; endfor ; + elseif t = 22 : + for $=1/5,1/2,4/5 : draw arrowheadonpath(reverse p,$) ; endfor ; + elseif t = 23 : + for $=p,reverse p : draw arrowheadonpath($,1/4) ; endfor ; + fi ; + fi ; +enddef ; + +endinput ; diff --git a/metapost/context/base/mp-spec.mp b/metapost/context/base/mp-spec.mp new file mode 100644 index 000000000..9125b4b8b --- /dev/null +++ b/metapost/context/base/mp-spec.mp @@ -0,0 +1,776 @@ +%D \module +%D [ file=mp-spec.mp, +%D version=1999.6.26, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=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 licen-en.pdf for +%C details. + +% Spot colors are not handled by mptopdf ! + +% let graycolor = numeric ; +% let greycolor = numeric ; +% let withanycolor = withcolor ; + +% rgbcolor red ; red := (1,0,0) ; +% rgbcolor green ; green := (0,1,0) ; +% rgbcolor blue ; blue := (0,0,1) ; +% cmykcolor cyan ; cyan := (1,0,0,0) ; +% cmykcolor magenta ; magenta := (0,1,0,0) ; +% cmykcolor yellow ; yellow := (0,0,1,0) ; +% graycolor black ; black := 0 ; % (0) ; +% graycolor white ; white := 1 ; % (1) ; + +% primarydef p withcolor c = +% p withanycolor (c) +% enddef ; + +% fill fullcircle scaled 10cm withcolor cyan ; +% fill fullcircle scaled 7cm withcolor red ; +% fill fullcircle scaled 4cm withcolor white ; + +% (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 + +%D This module is rather preliminary and subjected to +%D changes. Here we closely cooperates with the \METAPOST\ +%D to \PDF\ converter module built in \CONTEXT\ and provides +%D for instance shading. More information can be found in +%D type {supp-mpe.tex}. + +if unknown context_tool : input mp-tool ; fi ; +if known context_spec : endinput ; fi ; + +boolean context_spec ; context_spec := true ; + +numeric _special_counter_ ; _special_counter_ := 0 ; +numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved +numeric _special_signal_ ; _special_signal_ := 123 ; + +numeric _special_div_ ; _special_div_ := 1000 ; + +%D When set to \type {true}, shading will be supported. Some +%D day I will also write an additional directive. + +boolean _inline_specials_ ; _inline_specials_ := false ; + +%D Because we want to output only those specials that are +%D actually used in a figure, we need a bit complicated +%D bookkeeping and collection of specials. At the cost of some +%D obscurity, we now have rather efficient resources. + +string _global_specials_ ; _global_specials_ := "" ; +string _local_specials_ ; _local_specials_ := "" ; + +% vardef add_special_signal = % write the version number +% if (length _global_specials_>0) or (length _local_specials_ >0) : +% special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; +% fi ; +% enddef ; +% +% After some reported problems at the \CONTEXT\ mailing list, +% Taco's came up with: + +% TH: \quotation {Ok, got it. There is a bug in mp-spec.mp (inside metafun). +% Because of a wrapping number, it fails to recognize the fact that there +% are embedded specials at all.} The corrected definition is: + +vardef add_special_signal = % write the version number + if (length _global_specials_ <> 0) or (length _local_specials_ <> 0) : + special ("%%MetaPostSpecials: 2.0 " & decimal _special_signal_ & " " & decimal _special_div_) ; + fi ; +enddef ; + +% \quotation {It now tests for \quote {not equal to zero} instead of +% \quote {larger than zero}: because of all the included files, the +% string \type {_local_specials_} becomes longer than the maximum number +% \quote {length} can return, so it returns -32768 instead, and that is +% of course less than zero.} + +vardef add_extra_specials = + scantokens _global_specials_ ; + scantokens _local_specials_ ; +enddef ; + +vardef reset_extra_specials = + % only local ones + _local_specials_ := "" ; +enddef ; + +boolean insidefigure ; insidefigure := false ; + +% todo: alleen als special gebruikt flush + +extra_beginfig := + " insidefigure := true ; " & + " reset_extra_specials ; " & + extra_beginfig & + " ; " ; + +extra_endfig := + " ; " & + " add_special_signal ; " & + extra_endfig & + " add_extra_specials ; " & + " reset_extra_specials ; " & + " insidefigure := false ; " ; + +def set_extra_special (expr s) = + if insidefigure : + _local_specials_ := _local_specials_ & s ; + else : + _global_specials_ := _global_specials_ & s ; + fi +enddef ; + +def flush_special (expr typ, siz, dat) = + _special_counter_ := _special_counter_ + 1 ; + if _inline_specials_ : + set_extra_special + ( "special " + & "(" & ditto + & dat & " " + & decimal _special_counter_ & " " + & decimal typ & " " + & decimal siz + & " special" + & ditto & ");" ) ; + else : + set_extra_special + ( "special " + & "(" & ditto + & "%%MetaPostSpecial: " + & decimal siz & " " + & dat & " " + & decimal _special_counter_ & " " + & decimal typ + & ditto & ");" ) ; + fi ; +enddef ; + +%D The next hack is needed in case you use a version of +%D \METAPOST\ that does not provide you the means to configure +%D the buffer size. Patrick Gundlach suggested to use arrays +%D in this case. + +boolean bufferhack ; bufferhack := false ; % true ; + +if bufferhack : + + string _global_specials_[] ; numeric _nof_global_specials_ ; + string _local_specials_[] ; numeric _nof_local_specials_ ; + + _nof_global_specials_ := _nof_local_specials_ := 0 ; + + vardef add_special_signal = % write the version number + if (_nof_global_specials_>0) or (_nof_local_specials_>0) : + special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; + fi ; + enddef ; + + vardef add_extra_specials = + for i=1 upto _nof_global_specials_ : + scantokens _global_specials_[i] ; + endfor; + for i=1 upto _nof_local_specials_ : + scantokens _local_specials_[i] ; + endfor; + enddef ; + + vardef reset_extra_specials = + string _local_specials_[] ; _nof_local_specials_ := 0 ; + enddef ; + + def set_extra_special (expr s) = + if insidefigure : + _local_specials_[incr(_nof_local_specials_)] := s ; + else : + _global_specials_[incr(_nof_global_specials_)] := s ; + fi + enddef ; + +fi ; + +%D So far for this hack. + +%D Shade allocation. + +newinternal shadefactor ; shadefactor := 1 ; + +pair shadeoffset ; shadeoffset := origin ; + +% vardef define_linear_shade (expr a, b, ca, cb) = +% flush_special(30, 15, "0 1 " & decimal shadefactor & " " & +% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & +% dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; +% _special_counter_ +% enddef ; + +% vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = +% flush_special(31, 17, "0 1 " & decimal shadefactor & " " & +% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & +% dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; +% _special_counter_ +% enddef ; + +% these tests are not yet robust for new gray/cmyk features; +% +% - we need to get rid of cmykcolor() and + +vardef _is_cmyk_(expr c) = + (redpart c = _special_signal_/_special_div_) and (greenpart c = 1/_special_div_) +enddef ; +vardef _is_spot_(expr c) = + (redpart c = _special_signal_/_special_div_) and (greenpart c = 2/_special_div_) +enddef ; +vardef _is_gray_(expr c) = + (redpart c = greenpart c) and (greenpart c = bluepart c) +enddef ; + +numeric mp_shade_version ; mp_shade_version := 2 ; % more colors, needs new backend + +vardef define_linear_shade (expr a, b, ca, cb) = + save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; + save gray_a, gray_b ; boolean gray_a, gray_b ; + cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; + cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; + if (mp_shade_version > 1) and cmyk_a and cmyk_b : + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and cmyk_a and gray_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and gray_a and cmyk_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : + flush_special(34, 17, "0 1 " & decimal shadefactor & " " & + spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + else : + flush_special(30, 15, "0 1 " & decimal shadefactor & " " & + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; + fi ; + _special_counter_ +enddef ; + +vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = + save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; + save gray_a, gray_b ; boolean gray_a, gray_b ; + cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; + cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; + if (mp_shade_version > 1) and cmyk_a and cmyk_b : + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and cmyk_a and gray_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and gray_a and cmyk_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : + flush_special(35, 19, "0 1 " & decimal shadefactor & " " & + spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + else : + flush_special(31, 17, "0 1 " & decimal shadefactor & " " & + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + fi ; + _special_counter_ +enddef ; + +%D A few predefined shading macros. + +boolean trace_shades ; trace_shades := false ; + +% if (n=1) : a := llcorner p ; b := urcorner p ; +% elseif (n=2) : a := llcorner p ; b := ulcorner p ; +% elseif (n=3) : a := lrcorner p ; b := ulcorner p ; +% else : a := llcorner p ; b := lrcorner p ; +% fi ; + +def set_linear_vector (suffix a,b)(expr p,n) = + if (n=1) : a := llcorner p ; + b := urcorner p ; + elseif (n=2) : a := lrcorner p ; + b := ulcorner p ; + elseif (n=3) : a := urcorner p ; + b := llcorner p ; + elseif (n=4) : a := ulcorner p ; + b := lrcorner p ; + elseif (n=5) : a := .5[ulcorner p,llcorner p] ; + b := .5[urcorner p,lrcorner p] ; + elseif (n=6) : a := .5[llcorner p,lrcorner p] ; + b := .5[ulcorner p,urcorner p] ; + elseif (n=7) : a := .5[lrcorner p,urcorner p] ; + b := .5[llcorner p,ulcorner p] ; + elseif (n=8) : a := .5[urcorner p,ulcorner p] ; + b := .5[lrcorner p,llcorner p] ; + else : a := .5[ulcorner p,llcorner p] ; + b := .5[urcorner p,lrcorner p] ; + fi ; +enddef ; + +def set_circular_vector (suffix ab, r)(expr p,n) = + if (n=1) : ab := llcorner p ; + elseif (n=2) : ab := lrcorner p ; + elseif (n=3) : ab := urcorner p ; + elseif (n=4) : ab := ulcorner p ; + else : ab := center p ; r := .5r ; + fi ; +enddef ; + +def linear_shade (expr p, n, ca, cb) = + begingroup ; + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + fill p withshade define_linear_shade (a,b,ca,cb) ; + if trace_shades : + drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +def circular_shade (expr p, n, ca, cb) = + begingroup ; + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ + (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ; + if trace_shades : + drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +vardef predefined_linear_shade (expr p, n, ca, cb) = + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + set_shade_vector(a,b)(p,n) ; + define_linear_shade (a,b,ca,cb) +enddef ; + +vardef predefined_circular_shade (expr p, n, ca, cb) = + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ + (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + define_circular_shade(ab,ab,0,r,ca,cb) +enddef ; + +%D Since a \type {fill p withshade s} syntax looks better +%D than some macro, we implement a new primary. + +primarydef p withshade sc = % == p withcolor shadecolor(sh) + hide (_color_counter_ := _color_counter_ + 1) + p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) +enddef ; + +vardef shadecolor(expr sc) = + hide (_color_counter_ := _color_counter_ + 1) + (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) +enddef ; + +%D Figure inclusion. + +%numeric cef ; cef := 0 ; + +def externalfigure primary filename = + doexternalfigure (filename) +enddef ; + +def doexternalfigure (expr filename) text transformation = + begingroup ; save p, t ; picture p ; transform t ; + p := nullpicture ; t := identity transformation ; + flush_special(10, 9, + dddecimal (xxpart t, yxpart t, xypart t) & " " & + dddecimal (yypart t, xpart t, ypart t) & " " & filename) ; + addto p contour unitsquare scaled 0 ; + setbounds p to unitsquare transformed t ; + _color_counter_ := _color_counter_ + 1 ; + draw p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; + endgroup ; +enddef ; + +%D Experimental: + +%numeric currenthyperlink ; currenthyperlink := 0 ; + +def hyperlink primary t = dohyperlink(t) enddef ; +def hyperpath primary t = dohyperpath(t) enddef ; + +def dohyperlink (expr destination) text transformation = + begingroup ; save somepath ; path somepath ; + somepath := fullsquare transformation ; + dohyperpath(destination) somepath ; + endgroup ; +enddef ; + +def dohyperpath (expr destination) expr somepath = + begingroup ; + flush_special(20, 7, + ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " & + ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ; + _color_counter_ := _color_counter_ + 1 ; + fill boundingbox unitsquare scaled 0 withcolor + (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; + endgroup ; +enddef ; + +% \setupinteraction[state=start] +% \setupcolors [state=start] +% +% Hello There! \blank +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 4cm withcolor red ; +% hyperpath "nextpage" boundingbox currentpicture ; +% draw origin withcolor blue ; +% \stopMPcode +% +% \blank Does it work or not? +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 4cm withcolor red ; +% hyperpath "nextpage" fullcircle scaled 4cm ; +% draw origin withcolor blue ; +% draw fullcircle scaled 4cm shifted (1cm,1cm); +% \stopMPcode +% +% \blank Does it work or not? \page Hello There! \blank +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ; +% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ; +% draw fullcircle scaled 1cm ; +% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ; +% draw origin withcolor blue ; +% \stopMPcode +% +% \blank Does it work or not? + +_cmyk_counter_ := 0 ; + +extra_endfig := " ; resetcmykcolors ; " & extra_endfig ; + +def resetcmykcolors = + numeric cmykcolorhash[][][][] ; +enddef ; + +resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true + +string cmykcolorpattern[] ; % needed for transparancies + +vardef cmyk(expr c,m,y,k) = + if cmykcolors : + save ok ; boolean ok ; + if unknown cmykcolorhash[c][m][y][k] : + ok := false ; % not yet defined + elseif cmykcolorhash[c][m][y][k] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : +% save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; + save s ; string s ; s := ddddecimal (c,m,y,k) ; + _cmyk_counter_ := _cmyk_counter_ + 1 ; + cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; + cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; + flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; + _local_specials_ := _local_specials_ & + " cmykcolorhash[" & decimal c & "][" & decimal m & + "][" & decimal y & "][" & decimal k & "] := -1 ; " ; + fi ; + (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) + else : + (1-c-k,1-m-k,1-y-k) + fi +enddef ; + +% newcolor truecyan, truemagenta, trueyellow ; +% +% truecyan = (1,0,0,0) ; +% truemagenta = (0,1,0,0) ; +% trueyellow = (0,0,1,0) ; + +%D Spot colors + +_spotcolor_counter_ := 0 ; +_spotcolor_number_ := 0 ; + +extra_endfig := " ; resetspotcolors ; " & extra_endfig ; + +def resetspotcolors = + numeric spotcolorhash[][] ; +enddef ; + +resetspotcolors ; boolean spotcolors ; spotcolors := false ; % true + +string spotcolorpattern[] ; % needed for transparancies + +vardef spotcolor(expr p, s) = + multitonecolor(p, 1, "", decimal s) +enddef ; + +vardef multitonecolor(expr n, f, d, p) = % name fractions names factors + if spotcolors : + save ok, pc_tag ; boolean ok ; string pc_tag ; + pc_tag := "_pct_" & n ; + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + pp := getunstringed(pc_tag) ; + pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi & "_" & p ; % check for d empty + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + ps := getunstringed(pc_tag) ; + if unknown spotcolorhash[pp][ps] : + ok := false ; % not yet defined + elseif spotcolorhash[pp][ps] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + save ss ; string ss ; ss := n & " " & decimal f & " " & if d = "" : n else : d fi & " " & p ; + _spotcolor_counter_ := _spotcolor_counter_ + 1 ; + spotcolorpattern[_spotcolor_counter_/_special_div_] := ss ; + spotcolorhash[pp][ps] := _spotcolor_counter_ ; + flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ; + _local_specials_ := _local_specials_ & + "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ; + fi ; + (_special_signal_/_special_div_,2/_special_div_,spotcolorhash[pp][ps]/_special_div_) + else : + .5white + fi +enddef ; + +%D Transparency + +normaltransparent := 1 ; multiplytransparent := 2 ; +screentransparent := 3 ; overlaytransparent := 4 ; +softlighttransparent := 5 ; hardlighttransparent := 6 ; +colordodgetransparent := 7 ; colorburntransparent := 8 ; +darkentransparent := 9 ; lightentransparent := 10 ; +differencetransparent := 11 ; exclusiontransparent := 12 ; + +% nottransparent := 0 ; +% compatibletransparent := 99 ; + +% fill fullcircle scaled 10cm withcolor transparant(8,.3,red) ; + +vardef transparent(expr n, t, c) = + save s, ss, nn, cc, is_cmyk, is_spot, ok ; + string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot, ok ; + % transparancy type + if string n : + if expandafter known scantokens(n&"transparent") : + nn := scantokens(n&"transparent") ; + else : + nn := 0 ; + fi + else : % nn := min(n,13) + nn := if n<13 : n else : nn := 0 fi ; + fi ; + % we need to expand the color (can be cmyk(..) or predefined) + cc := c ; % expand color + % check for cmyk special + is_cmyk := (redpart cc = _special_signal_/_special_div_) + and (greenpart cc = 1/_special_div_) ; + is_spot := (redpart cc = _special_signal_/_special_div_) + and (greenpart cc = 2/_special_div_) ; + % build special string, fetch cmyk components + s := decimal nn & " " & decimal t & " " & + if is_cmyk : cmykcolorpattern[bluepart cc] + elseif is_spot : spotcolorpattern[bluepart cc] + else : dddecimal cc fi ; + % check if this one is already used + ss := cleanstring("tr_" & s) ; + % we now have rather unique names, i.e. a color spec of .234 becomes + % tr..._234.... and metapost gives a number overflow (parse error) + % for variables like tr_12345678 which may result from many decimal + % positions (imo mp bug) + ss := asciistring(ss) ; + % efficiency hack + if expandafter unknown scantokens(ss) : + ok := false ; % not yet defined + elseif scantokens(ss) < 0 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + if is_spot : + flush_special(5, 8, s) ; + elseif is_cmyk : + flush_special(4, 8, s) ; + else : + flush_special(3, 7, s) ; + fi ; + scantokens(ss) := _special_counter_ ; + _local_specials_ := _local_specials_ & + "scantokens(" & ditto & ss & ditto & ") := -1 ;" ; + fi ; + % go ahead + if is_spot : + (_special_signal_/_special_div_,5/_special_div_,scantokens(ss)/_special_div_) + elseif is_cmyk : + (_special_signal_/_special_div_,4/_special_div_,scantokens(ss)/_special_div_) + else : + (_special_signal_/_special_div_,3/_special_div_,scantokens(ss)/_special_div_) + fi +enddef ; + +%D This function returns true of false, dependent on transparency. + +vardef is_transparent(text t) = + begingroup ; save transparent ; save _c_, _b_ ; + vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ; + boolean _b_ ; _b_ := false ; + color _c_ ; _c_ := t ; _b_ + endgroup +enddef ; + +%D This function returns the not transparent color. + +vardef not_transparent(text t) = + begingroup ; save transparent ; + vardef transparent(expr nn, tt, cc) = cc enddef ; + t endgroup +enddef ; + +%D Basic position tracking: + +def register (expr label, width, height, offset) = + begingroup ; + flush_special(50, 7, + ddecimal offset & " " & + decimal width & " " & + decimal height & " " & label) ; + endgroup ; +enddef ; + +%D We cannot scale cmyk colors directly since this spoils +%D the trigger signal (such colors are no real colors). + +vardef scaledcmyk(expr c,m,y,k,sf) = + cmyk(sf*c,sf*m,sf*y,sf*k) +enddef ; + +vardef scaledcmykasrgb(expr c,m,y,k,sf) = + (sf*(1-c-k,1-m-k,1-y-k)) +enddef ; + +vardef scaledrgbascmyk(expr c,m,y,k,sf) = + scaledcmyk(1-c,1-m,1-y,0,sf) +enddef ; + +vardef scaledrgb(expr r,g,b,sf) = + (sf*(r,g,b)) +enddef ; + +vardef scaledgray(expr s,sf) = + (sf*(s,s,s)) +enddef ; + +% spotcolor is already scaled + +endinput ; + +% just an exercise (due to a question by Chof on the context mailing list); scaling of +% 'special' colors is not possible and the next solution is incomplete (spot colors, +% transparency, etc); watch the the tricky chained macro construction + +% vardef normalgray(expr s ) = (s,s,s) enddef ; +% vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ; +% vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ; cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) else : (1-c-k,1-m-k,1-y-k) fi enddef ; + +% vardef gray(expr s) = normalgray(s ) enddef ; +% vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ; +% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; + +% numeric _scaled_color_t_ ; +% color _scaled_color_c_ ; + +% def withscaledcolor = +% hide ( +% _scaled_color_t_ := 0 ; % direct +% def gray(expr s) = +% hide ( +% _gray_s_ := s ; +% _scaled_color_t_ := 1; % gray +% ) +% 0 +% enddef ; +% def rgb (expr r,g,b) = +% hide ( +% _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ; +% _scaled_color_t_ := 2 ; % rgb +% ) +% 0 +% enddef ; +% def cmyk (expr c,m,y,k) = +% hide ( +% _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ; _cmyk_k_ := k ; +% _scaled_color_t_ := 3 ; % cmyk +% ) +% 0 +% enddef ; ) +% dowithscaledcolor +% enddef ; + +% def dowithscaledcolor expr t = +% hide ( +% if color t : _scaled_color_c_ := t fi ; +% vardef gray(expr s) = normalgray(s) enddef ; +% vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ; +% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; +% ) +% enddef ; + +% def by expr s = +% if _scaled_color_t_ = 0 : +% withcolor s*_scaled_color_c_ +% elseif _scaled_color_t_ = 1 : +% withcolor gray(s*_gray_s_) +% elseif _scaled_color_t_ = 2 : +% withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_) +% elseif _scaled_color_t_ = 3 : +% withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_, s*_cmyk_k_) +% fi +% enddef ; + +% fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ; +% fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ; +% fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ; +% fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ; diff --git a/metapost/context/base/mp-step.mp b/metapost/context/base/mp-step.mp new file mode 100644 index 000000000..d602f7014 --- /dev/null +++ b/metapost/context/base/mp-step.mp @@ -0,0 +1,320 @@ +%D \module +%D [ file=mp-step.mp, +%D version=2001.05.22, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=steps, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={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. + +if unknown context_tool : input mp-tool ; fi ; +if known context_step : endinput ; fi ; + +boolean context_step ; context_step := true ; + +%D In the associated \TEX\ module \type {m-steps}, we describe +%D three methods. The first method uses a different kind of +%D code than the other two. The method we decided to use, +%D is based on positional information (paths) provided by +%D \CONTEXT. + +def initialize_step_variables = + save line_method, line_h_offset, line_v_offset ; + numeric line_method ; line_method := 1 ; + numeric line_h_offset ; line_h_offset := 3pt ; + numeric line_v_offset ; line_v_offset := 3pt ; +enddef ; + +def begin_step_chart = + initialize_step_variables ; + save steps, texts, t, b, tb, nofcells ; + picture cells[][], texts[][][], lines[][][] ; + numeric t, b ; t := 1 ; b := 2 ; + numeric nofcells ; nofcells := 0 ; +enddef ; + +def analyze_step_chart = + numeric n[], l[][], r[][] ; pair p[] ; + n[t] := n[b] := 0 ; numeric tb ; + for i=1 upto nofcells : for nn = t, b : + if bbwidth(cells[nn][i])>0 : n[nn] := n[nn] + 1 ; fi ; + l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ; + endfor ; endfor ; + % count left and right points + for i=1 upto nofcells-1 : for j=i upto nofcells-1 : for nn = t, b : + if bbwidth(texts[nn][i][j])>0 : + l[nn][i] := l[nn][i] + 1 ; + r[nn][j+1] := r[nn][j+1] + 1 ; + fi ; + endfor ; endfor ; endfor ; + % calculate left and right points + vardef do (expr nn, mm, ii, ss) = + if (l[nn][ii] + r[nn][ii]) > 1 : ss else : .5 fi + [ ulcorner cells[mm][ii], urcorner cells[mm][ii] ] + enddef ; + % combined rows + tb := if n[t]>0 : t else : b fi ; +enddef ; + +vardef get_step_chart_top_line (expr i, j) = + if bbwidth(cells[tb][i])>0 : + if bbwidth(texts[t][i][j])>0 : + if bbwidth(cells[tb][j+1])>0 : + p[1] := top do(t, tb, i, .6) ; + p[3] := top do(t, tb, j+1, .4) ; + p[2] := .5[p[1],p[3]] ; + if line_method = 1 : + p[2] := p[2] shifted (0, ypart + (llcorner texts[t][i][j] - ulcorner cells[tb][j+1])) ; + elseif line_method = 2 : + p[2] := center texts[t][i][j] ; + else : + % nothing + fi ; + p[1] := p[1] shifted (0,+line_v_offset) ; + p[2] := p[2] shifted (0,-line_v_offset) ; + p[3] := p[3] shifted (0,+line_v_offset) ; + (p[1] {up} ... p[2] ... {down} p[3]) + else : + origin + fi + else : + origin + fi + else : + origin + fi +enddef ; + +vardef get_step_chart_bot_line (expr i, j) = + if bbwidth(cells[b][i])>0 : + if bbwidth(texts[b][i][j])>0 : + if bbwidth(cells[b][j+1])>0 : + p[1] := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ; + p[3] := (bot do(b, b, j+1, .4)) shifted (0,-bbheight(cells[b][j+1])) ; + p[2] := .5[p[1],p[3]] ; + if line_method = 1 : + p[2] := p[2] shifted (0, -ypart + (llcorner cells[b][j+1] - ulcorner texts[b][i][j])) ; + elseif line_method = 2 : + p[2] := center texts[b][i][j] ; + fi ; + p[1] := p[1] shifted (0,-line_v_offset) ; + p[2] := p[2] shifted (0,+line_v_offset) ; + p[3] := p[3] shifted (0,-line_v_offset) ; + (p[1] {down} ... p[2] ... {up} p[3]) + else : + origin + fi + else : + origin + fi + else : + origin + fi +enddef ; + +def end_step_chart = + for i=1 upto nofcells : for nn = t, b : + if bbwidth(cells[nn][i]) >0 : draw cells[nn][i] ; fi ; + endfor ; endfor ; + for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b : + if known lines[nn][i][j] : + if bbwidth(lines[nn][i][j])>0 : draw lines[nn][i][j] ; fi ; + fi ; + endfor ; endfor ; endfor ; + for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b : + if bbwidth(texts[nn][i][j])>0 : draw texts[nn][i][j] ; fi ; + endfor ; endfor ; endfor ; +enddef ; + +%D Step tables. + +def begin_step_table = + initialize_step_variables ; + picture cells[], texts[], lines[] ; + numeric nofcells ; nofcells := 0 ; +enddef ; + +def end_step_table = + for i=1 upto nofcells : if known cells[i] : if bbwidth(cells[i])>0 : + draw cells[i] ; + fi ; fi ; endfor ; + for i=1 upto nofcells : if known lines[i] : if bbwidth(lines[i])>0 : + draw lines[i] ; + fi ; fi ; endfor ; + for i=1 upto nofcells : if known texts[i] : if bbwidth(texts[i])>0 : + draw texts[i] ; + fi ; fi ; endfor ; +enddef ; + +vardef get_step_table_line (expr i) = + pair prev, self, next ; + if known texts[i] : + self := lft .5[llcorner texts[i], ulcorner texts[i] ] ; + prev := rt if known texts[i-1] : .3 else : .5 fi [lrcorner cells[i] , urcorner cells[i] ] ; + next := rt if known texts[i+1] : .7 else : .5 fi [lrcorner cells[i+1], urcorner cells[i+1]] ; + self := self shifted (-line_h_offset,0) ; + prev := prev shifted (+line_h_offset,0) ; + next := next shifted (+line_h_offset,0) ; + prev {right} ... self ... {left} next + else : + origin + fi +enddef ; + +endinput + +%D The older method let \METAPOST\ do the typesetting. The +%D macros needed for that are included here for educational +%D purposes. +%D +%D \starttypen +%D def initialize_step_variables = +%D save line_color, line_width, arrow_alternative, +%D text_fill_color, text_line_color, text_line_width, text_offset, +%D cell_fill_color, cell_line_color, cell_line_width, cell_offset, +%D line_h_offset, line_v_offset ; +%D color line_color ; line_color := .4white ; +%D numeric line_width ; line_width := 1.5pt ; +%D color text_fill_color ; text_fill_color := white ; +%D color text_line_color ; text_line_color := red ; +%D numeric text_line_width ; text_line_width := 1pt ; +%D numeric text_offset ; text_offset := 2pt ; +%D color cell_fill_color ; cell_fill_color := white ; +%D color cell_line_color ; cell_line_color := blue ; +%D numeric cell_line_width ; cell_line_width := 1pt ; +%D numeric cell_offset ; cell_offset := 2pt ; +%D numeric line_alternative ; line_alternative := 1 ; +%D numeric line_h_offset ; line_h_offset := 3pt ; +%D numeric line_v_offset ; line_v_offset := 3pt ; +%D enddef ; +%D +%D def begin_step_chart = +%D begingroup ; +%D initialize_step_variables ; +%D save steps, texts, t, b ; +%D picture cells[][] ; numeric nofcells ; nofcells := 0 ; +%D picture texts[][][] ; numeric noftexts ; noftexts := 0 ; +%D numeric t, b ; t := 1 ; b := 2 ; +%D enddef ; +%D \stoptypen +%D +%D We use a couple of macros to store the content. In the +%D second (third) alternative we will directly fill the +%D cells. +%D +%D \starttypen +%D def set_step_chart_cells (expr one, two) = +%D nofcells := nofcells + 1 ; noftexts := 0 ; +%D cells[t][nofcells] := textext.rt(one) ; +%D cells[b][nofcells] := textext.rt(two) ; +%D enddef ; +%D +%D def set_step_chart_texts (expr one, two) = +%D noftexts := noftexts + 1 ; +%D texts[t][nofcells][noftexts] := textext.rt(one) ; +%D texts[b][nofcells][noftexts] := textext.rt(two) ; +%D enddef ; +%D \stoptypen +%D +%D If you compare the building macro with the later +%D alternative, you will notice that here we explicitly +%D have to calculate the distances and positions. +%D +%D \starttypen +%D def end_step_chart = +%D numeric dx ; dx := 0 ; path p ; +%D numeric n[] ; n[t] := n[b] := 0 ; +%D numeric stepsvdistance[] ; +%D vardef bbwidth (expr p) = (xpart (lrcorner p - llcorner p)) enddef ; +%D vardef bbheight (expr p) = (ypart (urcorner p - lrcorner p)) enddef ; +%D stepsvdistance[t] := stepsvdistance[b] := 0 ; +%D for i=1 upto nofcells : +%D % find largest bbox +%D p := boundingbox steps +%D [if bbwidth(cells[t][i])>bbwidth(cells[b][i]): t else: b fi][i] ; +%D % assign largest bbox +%D for nn = t, b : +%D if bbwidth(cells[nn][i])>0 : +%D setbounds cells[nn][i] to p enlarged cell_offset ; +%D n[nn] := n[nn] + 1 ; +%D fi ; +%D endfor ; +%D % determine height +%D if n[t]>0 : +%D stepsvdistance[t] := bbheight(cells[t][1]) + intertextdistance ; +%D fi ; +%D % add to row +%D for nn = t, b : +%D cells[nn][i] := cells[nn][i] shifted (dx,stepsvdistance[nn]) ; +%D if bbwidth(cells[nn][i])>0 : +%D dowithpath (boundingbox cells[nn][i], +%D cell_line_width, cell_line_color, cell_background_color) ; +%D fi ; +%D endfor ; +%D % calculate position +%D dx := dx + interstepdistance + bbwidth(cells[b][i]) ; +%D endfor ; +%D boolean stacked ; stacked := false ; +%D numeric l[][], r[][], l[][], r[][] ; +%D pair pa, pb, pc ; path p[] ; +%D for i=1 upto nofcells : +%D l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ; +%D endfor ; +%D % count left and right points +%D for i=1 upto nofcells : for j=1 upto nofcells : for nn = t, b : +%D if known texts[nn][i][j] : if bbwidth(texts[nn][i][j])>0 : +%D l[nn][i] := l[nn][i] + 1 ; +%D r[nn][j+i] := r[nn][j+i] + 1 ; +%D stacked := (stacked or (j>1)) ; +%D setbounds texts[nn][i][j] to boundingbox texts[nn][i][j] enlarged cell_offset ; +%D fi fi ; +%D endfor ; endfor ; endfor ; +%D % calculate left and right points +%D vardef do (expr nn, mm, ii, ss) = +%D if (l[nn][ii] > 0) and (r[nn][ii] > 0) : ss else : .5 fi +%D [ ulcorner cells[mm][ii],urcorner cells[mm][ii] ] +%D enddef ; +%D % draw arrow from left to right point +%D def dodo (expr nn, ii, jj, dd) = +%D drawarrow p[nn] +%D withpen pencircle scaled arrow_line_width +%D withcolor arrow_line_color ; +%D transform tr ; tr := identity +%D shifted point .5 along p[nn] +%D shifted -center texts[nn][ii][jj] +%D if not stacked : shifted (0,dd) fi ; +%D dowithpath ((boundingbox texts[nn][ii][jj]) transformed tr, +%D text_line_width, text_line_color, text_fill_color) ; +%D enddef ; +%D % draw top and bottom text boxes +%D for i=1 upto nofcells : for j=1 upto nofcells : +%D pickup pencircle scaled arrow_line_width ; +%D if known texts[t][i][j] : if bbwidth(texts[t][i][j]) > 0 : +%D pa := top do(t, if n[t]>0 : t else : b fi, i, .6) ; +%D pb := top do(t, if n[t]>0 : t else : b fi, j+i, .4) ; +%D pc := .5[pa,pb] shifted (0,+step_arrow_depth) ; +%D p[t] := pa {up} .. if not stacked : pc .. fi {down} pb ; +%D dodo(t, i, j, +intertextdistance) ; +%D fi fi ; +%D if known texts[b][i][j] : if bbwidth(texts[b][i][j]) > 0 : +%D pa := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ; +%D pb := (bot do(b, b, j+i, .4)) shifted (0,-bbheight(cells[b][j+i])) ; +%D pc := .5[pa,pb] shifted (0,-step_arrow_depth) ; +%D p[b] := pa {down} .. if not stacked : pc .. fi {up} pb ; +%D dodo(b, i, j, -intertextdistance) ; +%D fi fi ; +%D endfor ; endfor ; +%D endgroup ; +%D enddef ; +%D \stoptypen +%D +%D If you compare both methods, you will notice that the +%D first method is the cleanest, but not the most efficient +%D (since it needs \TEX\ runs within \METAPOST\ runs within +%D \TEX\ runs). diff --git a/metapost/context/base/mp-symb.mp b/metapost/context/base/mp-symb.mp new file mode 100644 index 000000000..a84c84e82 --- /dev/null +++ b/metapost/context/base/mp-symb.mp @@ -0,0 +1,351 @@ +%D \module +%D [ file=mp-symb.mp, +%D version=very old, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=navigation symbol 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 Instead of these symbols, you can use the \type {contnav} +%D font by Taco Hoekwater that is derived form this file. + +u := 3; +h := 5u; +wt := 5u; +wb := .25wt; +o := .1u; +pw := .5u; + +drawoptions (withpen pencircle scaled pw); + +path lefttriangle, righttriangle, sublefttriangle, subrighttriangle; + +pair s ; s = (2wb,0) ; + +x1t = x2t = 0; +x3t = wt; +y3t = .5h; +z1t-z2t = (z3t-z2t) rotated 60; + +z4t = (z2t--z3t) intersectionpoint ((z1t--z2t) shifted s) ; +z5t = (z3t--z1t) intersectionpoint ((z1t--z2t) shifted s) ; + +righttriangle = z1t--z2t--z3t--cycle; +lefttriangle = righttriangle rotatedaround((0,.5h), 180) shifted (wt,0); + +subrighttriangle = z4t--((z2t--z3t--z1t) shifted s)--z5t ; +sublefttriangle = subrighttriangle rotatedaround((0,.5h), 180) shifted (wt,0); + +path sidebar; + +x1b = x4b = 0; +x2b = x3b = wb; +y1b = y2b = y1t; +y3b = y4b = y2t; + +sidebar = z1b--z2b--z3b--z4b--cycle; + +path midbar, onebar, twobar; + +hh = abs(y1t-y2t); + +%midbar := unitsquare scaled 2hh/3; +midbar := unitsquare scaled hh; +onebar := unitsquare xscaled (hh/3) yscaled hh; +twobar := onebar; + +def prepareglyph = + drawoptions (withpen pencircle scaled .5u); +enddef; + +def finishglyph = + set_outer_boundingbox currentpicture; + bboxmargin := o; + setbounds currentpicture to bbox currentpicture; +% draw boundingbox currentpicture withcolor red withpen pencircle scaled 1; +enddef; + +beginfig (1); + prepareglyph; + fill lefttriangle; + draw lefttriangle; % draw gets the bbox right, filldraw doesn't + finishglyph; +endfig; + +beginfig (2); + prepareglyph; + fill righttriangle; + draw righttriangle; + finishglyph; +endfig; + +beginfig (3); + prepareglyph; + fill sidebar; + draw sidebar; + fill lefttriangle shifted (.5s); + draw lefttriangle shifted (.5s); + finishglyph; +endfig; + +beginfig (4); + prepareglyph; + fill righttriangle; + draw righttriangle; + fill sidebar shifted (wt,0); + draw sidebar shifted (wt,0); + finishglyph; +endfig; + +beginfig (5); + prepareglyph; + fill lefttriangle; + draw lefttriangle; + fill lefttriangle shifted s; + draw lefttriangle shifted s; + finishglyph; +endfig; + +beginfig (6); + prepareglyph; + fill righttriangle; + draw righttriangle; + fill righttriangle shifted s; + draw righttriangle shifted s; + finishglyph; +endfig; + +beginfig (7); + prepareglyph; + fill midbar; + draw midbar; + finishglyph; +endfig; + +beginfig (8); + prepareglyph; + fill onebar; + draw onebar; + finishglyph; +endfig; + +beginfig (9); + prepareglyph; + fill twobar; + draw twobar; + fill twobar shifted (pw+hh/2,0); + draw twobar shifted (pw+hh/2,0); + finishglyph; +endfig; + +beginfig(101); + prepareglyph; + draw lefttriangle; + finishglyph; +endfig; + +beginfig(102); + prepareglyph; + draw righttriangle; + finishglyph; +endfig; + +beginfig(103); + prepareglyph; + draw sidebar; + draw lefttriangle shifted (.5s); + finishglyph; +endfig; + +beginfig(104); + prepareglyph; + draw righttriangle; + draw sidebar shifted (wt,0); + finishglyph; +endfig; + +beginfig(105); + prepareglyph; + draw lefttriangle; + draw lefttriangle shifted s; + finishglyph; +endfig; + +beginfig(106); + prepareglyph; + draw righttriangle; + draw righttriangle shifted s; + finishglyph; +endfig; + +beginfig(107); + prepareglyph; + draw midbar; + finishglyph; +endfig; + +beginfig(108); + prepareglyph; + draw onebar; + finishglyph; +endfig; + +beginfig(109); + prepareglyph; + draw twobar; + draw twobar shifted (pw+hh/2,0); + finishglyph; +endfig; + +beginfig(201); + prepareglyph; + draw lefttriangle; + finishglyph; +endfig; + +beginfig(202); + prepareglyph; + draw righttriangle; + finishglyph; +endfig; + +beginfig(203); + prepareglyph; + draw sidebar; + draw lefttriangle shifted (.5s); + finishglyph; +endfig; + +beginfig(204); + prepareglyph; + draw righttriangle; + draw sidebar shifted (wt,0); + finishglyph; +endfig; + +beginfig(205); + prepareglyph; + draw sublefttriangle shifted s; + draw lefttriangle shifted s; + finishglyph; +endfig; + +beginfig(206); + prepareglyph; + draw subrighttriangle; + draw righttriangle; + finishglyph; +endfig; + +beginfig(207); + prepareglyph; + draw midbar; + finishglyph; +endfig; + +beginfig(208); + prepareglyph; + draw onebar; + finishglyph; +endfig; + +beginfig(209); + prepareglyph; + draw twobar; + draw twobar shifted (pw+hh/2,0); + finishglyph; +endfig; + + +beginfig(999); + +picture collection [] ; + +prepareglyph ; +draw lefttriangle ; +finishglyph ; +collection[201] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw righttriangle ; +finishglyph ; +collection[202] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw sidebar ; +draw lefttriangle shifted (.5s) ; +finishglyph ; +collection[203] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw righttriangle ; +draw sidebar shifted (wt,0) ; +finishglyph ; +collection[204] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw sublefttriangle shifted s ; +draw lefttriangle shifted s ; +finishglyph ; +collection[205] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw subrighttriangle ; +draw righttriangle ; +finishglyph ; +collection[206] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw midbar ; +finishglyph ; +collection[207] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw onebar ; +finishglyph ; +collection[208] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw twobar ; +draw twobar shifted (pw+hh/2,0) ; +finishglyph ; +collection[209] := currentpicture ; +currentpicture := nullpicture ; + +for i=201 upto 209 : + collection[i] := collection[i] shifted - center collection[i] ; +endfor ; + +addto currentpicture also collection[205] shifted ( 0, 0) + withcolor (.3,.4,.5) ; +addto currentpicture also collection[202] shifted ( 0,1.5h) + withcolor (.5,.6,.7) ; +addto currentpicture also collection[201] shifted (1.5h, 0) + withcolor (.6,.7,.8) ; +addto currentpicture also collection[206] shifted (1.5h,1.5h) + withcolor (.4,.5,.6) ; + +collection[210] := currentpicture ; +currentpicture := nullpicture ; + +bboxmargin := .25u; + +fill bbox collection[210] withcolor .95(1,1,0); +addto currentpicture also collection[210] ; + +endfig ; + +end diff --git a/metapost/context/base/mp-text.mp b/metapost/context/base/mp-text.mp new file mode 100644 index 000000000..60e16c09b --- /dev/null +++ b/metapost/context/base/mp-text.mp @@ -0,0 +1,269 @@ +%D \module +%D [ file=mp-text.mp, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=text 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 licen-en.pdf for +%C details. + +%D Under construction. + +if unknown context_tool : input mp-tool ; fi ; +if known context_text : endinput ; fi ; + +boolean context_text ; context_text := true ; + +if unknown noftexpictures : + numeric noftexpictures ; noftexpictures := 0 ; +fi ; + +if unknown texpictures[1] : + picture texpictures[] ; +fi ; + +numeric textextoffset ; textextoffset := 0 ; + +% vardef textext@#(expr txt) = +% interim labeloffset := textextoffset ; +% noftexpictures := noftexpictures + 1 ; +% if string txt : +% write "% figure " & decimal charcode & " : " & +% "texpictures[" & decimal noftexpictures & "] := btex " & +% txt & " etex ;" to jobname & ".mpt" ; +% if unknown texpictures[noftexpictures] : +% thelabel@#("unknown",origin) +% else : +% thelabel@#(texpictures[noftexpictures],origin) +% fi +% else : +% thelabel@#(txt,origin) +% fi +% enddef ; + +boolean hobbiestextext ; hobbiestextext := false ; +% string textextstring ; textextstring := "" ; + +% def resettextextdirective = +% textextstring := "" ; +% enddef ; + +% def textextdirective text t = +% textextstring := textextstring & t ; +% enddef ; + +vardef textext@#(expr txt) = + save _s_ ; string _s_ ; + interim labeloffset := textextoffset ; + noftexpictures := noftexpictures + 1 ; + if string txt : + if hobbiestextext : % the tex.mp method as fallback (see tex.mp) + write _s_ & "btex " & txt & " etex" to "mptextmp.mp" ; + write EOF to "mptextmp.mp" ; + scantokens "input mptextmp" + else : + write "% figure " & decimal charcode & " : " & + "texpictures[" & decimal noftexpictures & "] := btex " & + txt & " etex ;" to jobname & ".mpt" ; + if unknown texpictures[noftexpictures] : + thelabel@#("unknown",origin) + else : + thelabel@#(texpictures[noftexpictures],origin) + fi + fi + else : + thelabel@#(txt,origin) + fi +enddef ; + +string laboff_ ; laboff_ := "" ; +string laboff_c ; laboff_c := "" ; +string laboff_l ; laboff_l := ".lft" ; +string laboff_r ; laboff_r := ".rt" ; +string laboff_b ; laboff_b := ".bot" ; +string laboff_t ; laboff_t := ".top" ; + +string laboff_lt ; laboff_lt := ".ulft" ; +string laboff_rt ; laboff_rt := ".urt" ; % bugged, conflict with r +string laboff_lb ; laboff_lb := ".llft" ; +string laboff_rb ; laboff_rb := ".lrt" ; +string laboff_tl ; laboff_tl := ".ulft" ; +string laboff_tr ; laboff_tr := ".urt" ; +string laboff_bl ; laboff_bl := ".llft" ; +string laboff_br ; laboff_br := ".lrt" ; + +vardef textextstr(expr s, a) = + save ss ; string ss ; + ss := "laboff_" & a ; + ss := scantokens ss ; + ss := "textext" & ss & "(" & ditto & s & ditto & ")" ; + scantokens ss +enddef ; + +pair laboff.origin ; laboff.origin = (0,0) ; % (infinity,infinity) ; +pair laboff.raw ; laboff.raw = (0,0) ; % (infinity,infinity) ; + +laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ; +laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ; + +vardef thelabel@#(expr s, z) = + save p ; picture p ; + p = s if not picture s : infont defaultfont scaled defaultscale fi ; +% wrong, see myway textext +% if laboff@#<>laboff.origin : + (p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))) +% else : +% (p shifted z) +% fi +enddef; + +def build_parshape (expr p, offset_or_path, dx, dy, + baselineskip, strutheight, strutdepth, topskip) = + + if unknown trace_parshape : + boolean trace_parshape ; trace_parshape := false ; + fi ; + + begingroup ; + + save q, l, r, line, tt, bb, + n, hsize, vsize, vvsize, voffset, hoffset, width, indent, + ll, lll, rr, rrr, cp, cq, t, b ; + + path q, l, r, line, tt, bb ; + numeric n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ; + pair ll, lll, rr, rrr, cp, cq, t, b ; + + n := 0 ; cp := center p ; + + if path offset_or_path : + q := offset_or_path ; cq := center q ; + voffset := dy ; + hoffset := dx ; + else : + q := p ; cq := center q ; + hoffset := offset_or_path + dx ; + voffset := offset_or_path + dy ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + q := p shifted - cp ; + + startsavingdata ; + + savedata "\global\parvoffset " & decimal voffset&"bp " ; + savedata "\global\parhoffset " & decimal hoffset&"bp " ; + savedata "\global\parwidth " & decimal hsize&"bp " ; + savedata "\global\parheight " & decimal vsize&"bp " ; + + if not path offset_or_path : + q := q xscaled ((hsize-2hoffset)/hsize) + yscaled ((vsize-2voffset)/vsize) ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + t := (ulcorner q -- urcorner q) intersection_point q ; + b := (llcorner q -- lrcorner q) intersection_point q ; + + if xpart directionpoint t of q < 0 : + q := reverse q ; + fi ; + + l := q cutbefore t ; + l := l if xpart point 0 of q < 0 : & q fi cutafter b ; + + r := q cutbefore b ; + r := r if xpart point 0 of q > 0 : & q fi cutafter t ; + +% tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ; +% bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ; +% +% l := l cutbefore (l intersection_point tt) ; +% l := l cutafter (l intersection_point bb) ; +% r := r cutbefore (r intersection_point bb) ; +% r := r cutafter (r intersection_point tt) ; + + if trace_parshape : + drawarrow p withpen pencircle scaled 2pt withcolor red ; + drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ; + drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ; + fi ; + + vardef found_point (expr lin, pat, sig) = + pair a, b ; + a := pat intersection_point (lin shifted (0,strutheight)) ; + if intersection_found : + a := a shifted (0,-strutheight) ; + else : + a := pat intersection_point lin ; + fi ; + b := pat intersection_point (lin shifted (0,-strutdepth)) ; + if intersection_found : + if sig : + if xpart b > xpart a : a := b shifted (0,strutdepth) fi ; + else : + if xpart b < xpart a : a := b shifted (0,strutdepth) fi ; + fi ; + fi ; + a + enddef ; + + if (strutheight+strutdepth " & if numeric s : decimal s else : s fi) +% enddef ; +% vardef mpversionlt(expr s) = +% scantokens (mpversion & " < " & if numeric s : decimal s else : s fi) +% enddef ; +% vardef mpversioneq(expr s) = +% scantokens (mpversion & " = " & if numeric s : decimal s else : s fi) +% enddef ; + +%D More interesting: +%D +%D \starttyping +%D fill fullcircle scaled 4cm withcolor if mpversiongt("0.6") : red else : green fi ; +%D fill fullcircle scaled 2cm withcolor if mpversionlt(0.6) : blue else : white fi ; +%D fill fullcircle scaled 1cm withcolor if mpversioncmp(0.6,">=") : yellow else : black fi ; +%D \stoptyping + +vardef mpversioncmp(expr s, c) = + scantokens (mpversion & c & if numeric s : decimal s else : s fi) +enddef ; + +vardef mpversionlt (expr s) = mpversioncmp(s, "<") enddef ; +vardef mpversioneq (expr s) = mpversioncmp(s, "=") enddef ; +vardef mpversiongt (expr s) = mpversioncmp(s, ">") enddef ; + +%D We always want \EPS\ conforming output, so we say: + +prologues := 1 ; +warningcheck := 0 ; +mpprocset := 1 ; + +%D Namespace handling: + +% let exclamationmark = ! ; +% let questionmark = ? ; +% +% def unprotect = +% let ! = relax ; +% let ? = relax ; +% enddef ; +% +% def protect = +% let ! = exclamationmark ; +% let ? = questionmark ; +% enddef ; +% +% unprotect ; +% +% mp!some!module = 10 ; show mp!some!module ; show somemodule ; +% +% protect ; + +%D A semicolor to be used in specials: ? ? ? + +string semicolor ; semicolor := char 59 ; + +%D By including this module, \METAPOST\ automatically writes a +%D high resolution boundingbox to the \POSTSCRIPT\ file. This +%D hack is due to John Hobby himself. + +% When somehow the first one gets no HiRes, then make sure +% that the format matches the mem sizes in the config file. + +% eerste " " er uit + +string space ; space = char 32 ; + +vardef ddecimal primary p = + decimal xpart p & " " & decimal ypart p +enddef ; + +% is now built in + +% extra_endfig := extra_endfig +% & "special " +% & "(" +% & ditto +% & "%%HiResBoundingBox: " +% & ditto +% & "&ddecimal llcorner currentpicture" +% & "&space" +% & "&ddecimal urcorner currentpicture" +% & ");"; + +%D Crap (experimental, not used): + +def forcemultipass = + % extra_endfig := extra_endfig & "special(" & ditto & "%%MetaPostOption: multipass" & ditto & ");" ; +enddef ; + +%D Colors: + +nocolormodel := 1 ; +greycolormodel := 3 ; +rgbcolormodel := 5 ; +cmykcolormodel := 7 ; + +let grayscale = numeric ; + +% def colorlike(expr c) text v = % colorlike(a) b, c, d ; +% forsuffixes i=v : % save i ; +% if cmykcolor c : +% cmykcolor i ; +% elseif rgbcolor c : +% rgbcolor i ; +% else : +% grayscale i ; +% fi ; +% endfor ; +% enddef ; + +vardef colorlike(text c) text v = % colorlike(a) b, c, d ; + save _p_ ; picture _p_ ; + forsuffixes i=v : + _p_ := image(draw origin withcolor c ;) ; % intercept pre and postscripts + if (colormodel _p_ = cmykcolormodel) : + cmykcolor i ; + elseif (colormodel _p_ = rgbcolormodel) : + rgbcolor i ; + else : + grayscale i ; + fi ; + endfor ; +enddef ; + +% if (unknown colormodel) : +% def colormodel = +% rgbcolormodel +% enddef ; +% fi ; + +%D Also handy (when we flush colors): + +vardef dddecimal primary c = + decimal redpart c & " " & decimal greenpart c & " " & decimal bluepart c +enddef ; + +vardef ddddecimal primary c = + decimal cyanpart c & " " & decimal magentapart c & " " & decimal yellowpart c & " " & decimal blackpart c +enddef ; + +vardef colordecimals primary c = + if cmykcolor c : + decimal cyanpart c & ":" & decimal magentapart c & ":" & decimal yellowpart c & ":" & decimal blackpart c + elseif rgbcolor c : + decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c + else : + decimal c + fi +enddef ; + +%D We have standardized data file names: + +def job_name = + jobname +enddef ; + +def data_mpd_file = + job_name & "-mp.mpd" +enddef ; + +%D Because \METAPOST\ has a hard coded limit of 4~datafiles, +%D we need some trickery when we have multiple files. + +if unknown collapse_data : + boolean collapse_data ; collapse_data := false ; +fi ; + +boolean savingdata ; savingdata := false ; +boolean savingdatadone ; savingdatadone := false ; + +def savedata expr txt = + if collapse_data : + write txt to data_mpd_file ; + else : + write if savingdata : txt else : + "\MPdata{" & decimal charcode & "}{" & txt & "}" + fi + & "%" to data_mpd_file ; + fi ; +enddef ; + +def startsavingdata = + savingdata := true ; + savingdatadone := true ; + if collapse_data : + write + "\MPdata{" & decimal charcode & "}{%" + to + data_mpd_file ; + fi ; +enddef ; + +def stopsavingdata = + if collapse_data : + write "}%" to data_mpd_file ; + fi ; + savingdata := false ; +enddef ; + +def finishsavingdata = + if savingdatadone : + write EOF to data_mpd_file ; + savingdatadone := false ; + fi ; +enddef ; + +%D Instead of a keystroke eating save and allocation +%D sequence, you can use the \citeer {new} alternatives to +%D save and allocate in one command. + +def newcolor text v = forsuffixes i=v : save i ; color i ; endfor ; enddef ; +def newnumeric text v = forsuffixes i=v : save i ; numeric i ; endfor ; enddef ; +def newboolean text v = forsuffixes i=v : save i ; boolean i ; endfor ; enddef ; +def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ; +def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ; +def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ; +def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ; + +%D Sometimes we don't want parts of the graphics add to the +%D bounding box. One way of doing this is to save the bounding +%D box, draw the graphics that may not count, and restore the +%D bounding box. +%D +%D \starttypen +%D push_boundingbox currentpicture; +%D pop_boundingbox currentpicture; +%D \stoptypen +%D +%D The bounding box can be called with: +%D +%D \starttypen +%D boundingbox currentpicture +%D inner_boundingbox currentpicture +%D outer_boundingbox currentpicture +%D \stoptypen +%D +%D Especially the latter one can be of use when we include +%D the graphic in a document that is clipped to the bounding +%D box. In such occasions one can use: +%D +%D \starttypen +%D set_outer_boundingbox currentpicture; +%D \stoptypen +%D +%D Its counterpart is: +%D +%D \starttypen +%D set_inner_boundingbox p +%D \stoptypen + +path pushed_boundingbox; + +def push_boundingbox text p = + pushed_boundingbox := boundingbox p; +enddef; + +def pop_boundingbox text p = + setbounds p to pushed_boundingbox; +enddef; + +vardef boundingbox primary p = + if (path p) or (picture p) : + llcorner p -- lrcorner p -- urcorner p -- ulcorner p + else : + origin + fi -- cycle +enddef; + +vardef inner_boundingbox primary p = + top rt llcorner p -- + top lft lrcorner p -- + bot lft urcorner p -- + bot rt ulcorner p -- cycle +enddef; + +vardef outer_boundingbox primary p = + bot lft llcorner p -- + bot rt lrcorner p -- + top rt urcorner p -- + top lft ulcorner p -- cycle +enddef; + +def innerboundingbox = inner_boundingbox enddef ; +def outerboundingbox = outer_boundingbox enddef ; + +vardef set_inner_boundingbox text q = + setbounds q to inner_boundingbox q; +enddef; + +vardef set_outer_boundingbox text q = + setbounds q to outer_boundingbox q; +enddef; + +%D Some missing functions can be implemented rather +%D straightforward: + +numeric Pi ; Pi := 3.1415926 ; + +vardef sqr primary x = (x*x) enddef ; +vardef log primary x = (if x=0: 0 else: mlog(x)/mlog(10) fi) enddef ; +vardef ln primary x = (if x=0: 0 else: mlog(x)/256 fi) enddef ; +vardef exp primary x = ((mexp 256)**x) enddef ; +vardef inv primary x = (if x=0: 0 else: x**-1 fi) enddef ; + +vardef pow (expr x,p) = (x**p) enddef ; + +vardef asin primary x = (x+(x**3)/6+3(x**5)/40) enddef ; +vardef acos primary x = (asin(-x)) enddef ; +vardef atan primary x = (x-(x**3)/3+(x**5)/5-(x**7)/7) enddef ; +vardef tand primary x = (sind(x)/cosd(x)) enddef ; + +%D Here are Taco Hoekwater's alternatives (but +%D vardef'd and primaried). + +pi := 3.1415926 ; radian := 180/pi ; % 2pi*radian = 360 ; + +vardef tand primary x = (sind(x)/cosd(x)) enddef ; +vardef cotd primary x = (cosd(x)/sind(x)) enddef ; + +vardef sin primary x = (sind(x*radian)) enddef ; +vardef cos primary x = (cosd(x*radian)) enddef ; +vardef tan primary x = (sin(x)/cos(x)) enddef ; +vardef cot primary x = (cos(x)/sin(x)) enddef ; + +vardef asin primary x = angle((1+-+x,x)) enddef ; +vardef acos primary x = angle((x,1+-+x)) enddef ; + +vardef invsin primary x = ((asin(x))/radian) enddef ; +vardef invcos primary x = ((acos(x))/radian) enddef ; + +vardef acosh primary x = ln(x+(x+-+1)) enddef ; +vardef asinh primary x = ln(x+(x++1)) enddef ; + +vardef sinh primary x = save xx ; xx = exp x ; (xx-1/xx)/2 enddef ; +vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ; + +%D We provide two macros for drawing stripes across a shape. +%D The first method (with the n suffix) uses another method, +%D slower in calculation, but more efficient when drawn. The +%D first macro divides the sides into n equal parts. The +%D first argument specifies the way the lines are drawn, while +%D the second argument identifier the way the shape is to be +%D drawn. +%D +%D \starttypen +%D stripe_path_n +%D (dashed evenly withcolor blue) +%D (filldraw) +%D fullcircle xscaled 100 yscaled 40 shifted (50,50) withpen pencircle scaled 4; +%D \stoptypen +%D +%D The a (or angle) alternative supports arbitrary angles and +%D is therefore more versatile. +%D +%D \starttypen +%D stripe_path_a +%D (withpen pencircle scaled 2 withcolor red) +%D (draw) +%D fullcircle xscaled 100 yscaled 40 withcolor blue; +%D \stoptypen +%D +%D The first alternative obeys: + +stripe_n := 10; +stripe_slot := 3; + +%D When no pen dimensions are passed, the slot determines +%D the spacing. +%D +%D The angle alternative is influenced by: + +stripe_gap := 5; +stripe_angle := 45; + +def stripe_path_n (text s_spec) (text s_draw) expr s_path = + do_stripe_path_n (s_spec) (s_draw) (s_path) +enddef; + +def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = + begingroup + save curpic, newpic, bb, pp, ww; + picture curpic, newpic; + path bb, pp; + pp := s_path; + curpic := currentpicture; + currentpicture := nullpicture; + s_draw pp s_text; + bb := boundingbox currentpicture; + newpic := currentpicture; + currentpicture := nullpicture; + ww := min(ypart urcorner newpic - ypart llcorner newpic, + xpart urcorner newpic - xpart llcorner newpic); + ww := ww/(stripe_slot*stripe_n); + for i=1/stripe_n step 1/stripe_n until 1: + draw point (1+i) of bb -- point (3-i) of bb + withpen pencircle scaled ww s_spec ; + endfor; + for i=0 step 1/stripe_n until 1: + draw point (3+i) of bb -- point (1-i) of bb + withpen pencircle scaled ww s_spec; + endfor; + clip currentpicture to pp; + addto newpic also currentpicture; + currentpicture := curpic; + addto currentpicture also newpic; + endgroup +enddef; + +def stripe_path_a (text s_spec) (text s_draw) expr s_path = + do_stripe_path_a (s_spec) (s_draw) (s_path) +enddef; + +def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = + begingroup + save curpic, newpic, pp; picture curpic, newpic; path pp ; + pp := s_path ; + curpic := currentpicture; + currentpicture := nullpicture; + s_draw pp s_text ; + def do_stripe_rotation (expr p) = + (currentpicture rotatedaround(center p,stripe_angle)) + enddef ; + s_max := max + (xpart llcorner do_stripe_rotation(currentpicture), + xpart urcorner do_stripe_rotation(currentpicture), + ypart llcorner do_stripe_rotation(currentpicture), + ypart urcorner do_stripe_rotation(currentpicture)); + newpic := currentpicture; + currentpicture := nullpicture; + for i=-s_max-.5stripe_gap step stripe_gap until s_max: + draw (-s_max,i)--(s_max,i) s_spec; + endfor; + currentpicture := do_stripe_rotation(newpic); + clip currentpicture to pp ; + addto newpic also currentpicture; + currentpicture := curpic; + addto currentpicture also newpic; + endgroup +enddef; + +%D A few normalizing macros: +%D +%D \starttypen +%D xscale_currentpicture ( width ) +%D yscale_currentpicture ( height ) +%D xyscale_currentpicture ( width, height ) +%D scale_currentpicture ( width, height ) +%D \stoptypen + +% def xscale_currentpicture(expr the_width) = +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_width/natural_width) ; +% enddef; +% +% def yscale_currentpicture(expr the_height ) = +% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_height/natural_height) ; +% enddef; +% +% def xyscale_currentpicture(expr the_width, the_height) = +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; +% currentpicture := currentpicture +% xscaled (the_width/natural_width) +% yscaled (the_height/natural_height) ; +% enddef; +% +% def scale_currentpicture(expr the_width, the_height) = +% xscale_currentpicture(the_width) ; +% yscale_currentpicture(the_height) ; +% enddef; + +% nog eens uitbreiden zodat path en pic worden afgehandeld. + +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_width/natural_width) ; + +% TODO TODO TODO TODO, not yet ok + +primarydef p xsized w = + (p if (bbwidth (p)>0) and (w>0) : scaled (w/bbwidth (p)) fi) +enddef ; + +primarydef p ysized h = + (p if (bbheight(p)>0) and (h>0) : scaled (h/bbheight(p)) fi) +enddef ; + +primarydef p xysized s = + begingroup ; + save wh, w, h ; pair wh ; numeric w, h ; + wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; + (p if (w>0) and (h>0) : + if xpart wh > 0 : xscaled (xpart wh/w) fi + if ypart wh > 0 : yscaled (ypart wh/h) fi + fi) + endgroup +enddef ; + +primarydef p sized wh = + (p xysized wh) +enddef ; + +def xscale_currentpicture(expr w) = + currentpicture := currentpicture xsized w ; +enddef; + +def yscale_currentpicture(expr h) = + currentpicture := currentpicture ysized h ; +enddef; + +def xyscale_currentpicture(expr w, h) = + currentpicture := currentpicture xysized (w,h) ; +enddef; + +def scale_currentpicture(expr w, h) = + currentpicture := currentpicture xsized w ; + currentpicture := currentpicture ysized h ; +enddef; + +%D A full circle is centered at the origin, while a unitsquare +%D is located in the first quadrant. Now guess what kind of +%D path fullsquare and unitcircle do return. + +path fullsquare, unitcircle ; + +fullsquare := unitsquare shifted - center unitsquare ; +unitcircle := fullcircle shifted urcorner fullcircle ; + +%D Some more paths: + +path urcircle, ulcircle, llcircle, lrcircle ; + +urcircle := origin--(+.5,0)&(+.5,0){up} ..(0,+.5)&(0,+.5)--cycle ; +ulcircle := origin--(0,+.5)&(0,+.5){left} ..(-.5,0)&(-.5,0)--cycle ; +llcircle := origin--(-.5,0)&(-.5,0){down} ..(0,-.5)&(0,-.5)--cycle ; +lrcircle := origin--(0,-.5)&(0,-.5){right}..(+.5,0)&(+.5,0)--cycle ; + +path tcircle, bcircle, lcircle, rcircle ; + +tcircle = origin--(+.5,0)&(+.5,0){up} ..(0,+.5)..{down} (-.5,0)--cycle ; +bcircle = origin--(-.5,0)&(-.5,0){down} ..(0,-.5)..{up} (+.5,0)--cycle ; +lcircle = origin--(0,+.5)&(0,+.5){left} ..(-.5,0)..{right}(0,-.5)--cycle ; +rcircle = origin--(0,-.5)&(0,-.5){right}..(+.5,0)..{left} (0,+.5)--cycle ; + +path urtriangle, ultriangle, lltriangle, lrtriangle ; + +urtriangle := origin--(+.5,0)--(0,+.5)--cycle ; +ultriangle := origin--(0,+.5)--(-.5,0)--cycle ; +lltriangle := origin--(-.5,0)--(0,-.5)--cycle ; +lrtriangle := origin--(0,-.5)--(+.5,0)--cycle ; + +path unitdiamond, fulldiamond ; + +unitdiamond := (.5,0)--(1,.5)--(.5,1)--(0,.5)--cycle ; +fulldiamond := unitdiamond shifted - center unitdiamond ; + +%D More robust: + +% let normalscaled = scaled ; +% let normalxscaled = xscaled ; +% let normalyscaled = yscaled ; +% +% def scaled expr s = normalscaled (s) enddef ; +% def xscaled expr s = normalxscaled (s) enddef ; +% def yscaled expr s = normalyscaled (s) enddef ; + +%D Shorter + +primarydef p xyscaled q = + begingroup ; save qq ; pair qq ; qq = paired(q) ; + ( p + if xpart qq<>0 : xscaled (xpart qq) fi + if ypart qq<>0 : yscaled (ypart qq) fi ) + endgroup +enddef ; + +%D Experimenteel, zie folder-3.tex. + +def set_grid(expr w, h, nx, ny) = + boolean grid[][] ; boolean grid_full ; + grid_w := w ; + grid_h := h ; + grid_nx := nx ; + grid_ny := ny ; + grid_x := round(w/grid_nx) ; % +.5) ; + grid_y := round(h/grid_ny) ; % +.5) ; + grid_left := (1+grid_x)*(1+grid_y) ; + grid_full := false ; + for i=0 upto grid_x: + for j=0 upto grid_y: + grid[i][j] := false ; + endfor ; + endfor ; +enddef ; + +vardef new_on_grid(expr _dx_, _dy_) = + dx := _dx_ ; + dy := _dy_ ; + ddx := min(round(dx/grid_nx),grid_x) ; % +.5),grid_x) ; + ddy := min(round(dy/grid_ny),grid_y) ; % +.5),grid_y) ; + if not grid_full and not grid[ddx][ddy]: + grid[ddx][ddy] := true ; + grid_left := grid_left-1 ; + grid_full := (grid_left=0) ; + true + else: + false + fi +enddef ; + +%D usage: \type{innerpath peepholed outerpath}. +%D +%D beginfig(1); +%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; +%D fill (fullsquare scaled 200) withcolor red ; +%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; +%D fill p peepholed bbox p ; +%D endfig; + +secondarydef p peepholed q = + begingroup ; + save start ; pair start ; start := point 0 of p ; + if xpart start >= xpart center p : + if ypart start >= ypart center p : + urcorner q -- ulcorner q -- llcorner q -- lrcorner q -- + reverse p -- lrcorner q -- cycle + else : + lrcorner q -- urcorner q -- ulcorner q -- llcorner q -- + reverse p -- llcorner q -- cycle + fi + else : + if ypart start > ypart center p : + ulcorner q -- llcorner q -- lrcorner q -- urcorner q -- + reverse p -- urcorner q -- cycle + else : + llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- + reverse p -- ulcorner q -- cycle + fi + fi + endgroup +enddef ; + +boolean intersection_found ; + +secondarydef p intersection_point q = + begingroup + save x_, y_ ; + (x_,y_) = p intersectiontimes q ; + if x_<0 : + intersection_found := false ; + center p % origin + else : + intersection_found := true ; + .5[point x_ of p, point y_ of q] + fi + endgroup +enddef ; + +%D New, undocumented, experimental: + +vardef tensecircle (expr width, height, offset) = + ((-width/2,-height/2) ... (0,-height/2-offset) ... + (+width/2,-height/2) ... (+width/2+offset,0) ... + (+width/2,+height/2) ... (0,+height/2+offset) ... + (-width/2,+height/2) ... (-width/2-offset,0) ... cycle) +enddef ; + +%vardef tensecircle (expr width, height, offset) = +% ((-width/2,-height/2)..(0,-height/2-offset)..(+width/2,-height/2) & +% (+width/2,-height/2)..(+width/2+offset,0)..(+width/2,+height/2) & +% (+width/2,+height/2)..(0,+height/2+offset)..(-width/2,+height/2) & +% (-width/2,+height/2)..(-width/2-offset,0)..(-width/2,-height/2)..cycle) +%enddef ; + +vardef roundedsquare (expr width, height, offset) = + ((offset,0)--(width-offset,0){right} .. + (width,offset)--(width,height-offset){up} .. + (width-offset,height)--(offset,height){left} .. + (0,height-offset)--(0,offset){down} .. cycle) +enddef ; + +%D Some colors. + +color cyan ; cyan = (0,1,1) ; +color magenta ; magenta = (1,0,1) ; +color yellow ; yellow = (1,1,0) ; + +def colortype(expr c) = + if cmykcolor c : cmykcolor elseif rgbcolor c : rgbcolor else : grayscale fi +enddef ; +vardef whitecolor(expr c) = + if cmykcolor c : (0,0,0,0) elseif rgbcolor c : (1,1,1) else : 1 fi +enddef ; +vardef blackcolor(expr c) = + if cmykcolor c : (0,0,0,1) elseif rgbcolor c : (0,0,0) else : 0 fi +enddef ; + +%D Well, this is the dangerous and naive version: + +def drawfill text t = + fill t ; + draw t ; +enddef; + +%D This two step approach saves the path first, since it can +%D be a function. Attributes must not be randomized. + +def drawfill expr c = + path _c_ ; _c_ := c ; + do_drawfill +enddef ; + +def do_drawfill text t = + draw _c_ t ; + fill _c_ t ; +enddef; + +def undrawfill expr c = + drawfill c withcolor background +enddef ; + +%D Moved from mp-char.mp + +vardef paired (expr d) = + if pair d : d else : (d,d) fi +enddef ; + +vardef tripled (expr d) = + if color d : d else : (d,d,d) fi +enddef ; + +primarydef p enlarged d = + (p llmoved d -- p lrmoved d -- p urmoved d -- p ulmoved d -- cycle) +enddef; + +primarydef p llenlarged d = + (p llmoved d -- lrcorner p -- urcorner p -- ulcorner p -- cycle) +enddef ; + +primarydef p lrenlarged d = + (llcorner p -- p lrmoved d -- urcorner p -- ulcorner p -- cycle) +enddef ; + +primarydef p urenlarged d = + (llcorner p -- lrcorner p -- p urmoved d -- ulcorner p -- cycle) +enddef ; + +primarydef p ulenlarged d = + (llcorner p -- lrcorner p -- urcorner p -- p ulmoved d -- cycle) +enddef ; + +primarydef p llmoved d = + ((llcorner p) shifted (-xpart paired(d),-ypart paired(d))) +enddef ; + +primarydef p lrmoved d = + ((lrcorner p) shifted (+xpart paired(d),-ypart paired(d))) +enddef ; + +primarydef p urmoved d = + ((urcorner p) shifted (+xpart paired(d),+ypart paired(d))) +enddef ; + +primarydef p ulmoved d = + ((ulcorner p) shifted (-xpart paired(d),+ypart paired(d))) +enddef ; + +primarydef p leftenlarged d = + ((llcorner p) shifted (-d,0) -- lrcorner p -- + urcorner p -- (ulcorner p) shifted (-d,0) -- cycle) +enddef ; + +primarydef p rightenlarged d = + (llcorner p -- (lrcorner p) shifted (d,0) -- + (urcorner p) shifted (d,0) -- ulcorner p -- cycle) +enddef ; + +primarydef p topenlarged d = + (llcorner p -- lrcorner p -- + (urcorner p) shifted (0,d) -- (ulcorner p) shifted (0,d) -- cycle) +enddef ; + +primarydef p bottomenlarged d = + (llcorner p shifted (0,-d) -- lrcorner p shifted (0,-d) -- + urcorner p -- ulcorner p -- cycle) +enddef ; + +%D Handy for testing/debugging: + +primarydef p crossed d = + if pair p : + (p shifted (-d, 0) -- p -- + p shifted ( 0,-d) -- p -- + p shifted (+d, 0) -- p -- + p shifted ( 0,+d) -- p -- cycle) + else : + (center p shifted (-d, 0) -- llcorner p -- + center p shifted ( 0,-d) -- lrcorner p -- + center p shifted (+d, 0) -- urcorner p -- + center p shifted ( 0,+d) -- ulcorner p -- cycle) + fi +enddef ; + +%D Also handy (math ladders): + +vardef laddered expr p = + point 0 of p + for i=1 upto length(p) : + -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) + endfor +enddef ; + +%D Saves typing: + +% vardef bottomboundary primary p = (llcorner p -- lrcorner p) enddef ; +% vardef rightboundary primary p = (lrcorner p -- urcorner p) enddef ; +% vardef topboundary primary p = (urcorner p -- ulcorner p) enddef ; +% vardef leftboundary primary p = (ulcorner p -- llcorner p) enddef ; + +vardef bottomboundary primary p = + if pair p : p else : (llcorner p -- lrcorner p) fi +enddef ; + +vardef rightboundary primary p = + if pair p : p else : (lrcorner p -- urcorner p) fi +enddef ; + +vardef topboundary primary p = + if pair p : p else : (urcorner p -- ulcorner p) fi +enddef ; + +vardef leftboundary primary p = + if pair p : p else : (ulcorner p -- llcorner p) fi +enddef ; + +%D Nice too: + +primarydef p superellipsed s = + superellipse + (.5[lrcorner p,urcorner p], + .5[urcorner p,ulcorner p], + .5[ulcorner p,llcorner p], + .5[llcorner p,lrcorner p], + s) +enddef ; + +primarydef p squeezed s = + ((llcorner p .. .5[llcorner p,lrcorner p] shifted ( 0, ypart paired(s)) .. lrcorner p) & + (lrcorner p .. .5[lrcorner p,urcorner p] shifted (-xpart paired(s), 0) .. urcorner p) & + (urcorner p .. .5[urcorner p,ulcorner p] shifted ( 0,-ypart paired(s)) .. ulcorner p) & + (ulcorner p .. .5[ulcorner p,llcorner p] shifted ( xpart paired(s), 0) .. llcorner p) & cycle) +enddef ; + +primarydef p randomshifted s = + begingroup ; save ss ; pair ss ; ss := paired(s) ; + p shifted (-.5xpart ss + uniformdeviate xpart ss, + -.5ypart ss + uniformdeviate ypart ss) + endgroup +enddef ; + +%primarydef p randomized s = +% for i=0 upto length(p)-1 : +% ((point i of p) randomshifted s) .. controls +% ((postcontrol i of p) randomshifted s) and +% ((precontrol (i+1) of p) randomshifted s) .. +% endfor cycle +%enddef ; + +primarydef p randomized s = + (if path p : + for i=0 upto length(p)-1 : + ((point i of p) randomshifted s) .. controls + ((postcontrol i of p) randomshifted s) and + ((precontrol (i+1) of p) randomshifted s) .. + endfor + if cycle p : + cycle + else : + ((point length(p) of p) randomshifted s) + fi + elseif pair p : + p randomshifted s + elseif cmykcolor p : + if color s : + (uniformdeviate cyanpart s * cyanpart p, + uniformdeviate magentapart s * magentapart p, + uniformdeviate yellowpart s * yellowpart p, + uniformdeviate blackpart s * blackpart p) + elseif pair s : + ((xpart s + uniformdeviate (ypart s - xpart s)) * p) + else : + (uniformdeviate s * p) + fi + elseif rgbcolor p : + if color s : + (uniformdeviate redpart s * redpart p, + uniformdeviate greenpart s * greenpart p, + uniformdeviate bluepart s * bluepart p) + elseif pair s : + ((xpart s + uniformdeviate (ypart s - xpart s)) * p) + else : + (uniformdeviate s * p) + fi + elseif color p : + if color s : + (uniformdeviate graypart s * graypart p) + elseif pair s : + ((xpart s + uniformdeviate (ypart s - xpart s)) * p) + else : + (uniformdeviate s * p) + fi + else : + p + uniformdeviate s + fi) +enddef ; + +%D Not perfect (alternative for interpath) + +vardef interpolated(expr s, p, q) = + save m ; m := max(length(p),length(q)) ; + (if path p : + for i=0 upto m-1 : + s[point (i /m) along p, + point (i /m) along q] .. controls + s[postcontrol (i /m) along p, + postcontrol (i /m) along q] and + s[precontrol ((i+1)/m) along p, + precontrol ((i+1)/m) along q] .. + endfor + if cycle p : + cycle + else : + s[point infinity of p, + point infinity of q] + fi + else : + a[p,q] + fi) +enddef ; + +%D Interesting too: + +% primarydef p parallel s = +% begingroup ; save q, b ; path q ; numeric b ; +% b := xpart (lrcorner p - llcorner p) ; +% q := p if b>0 : scaled ((b+2s)/b) fi ; +% (q shifted (center p-center q)) +% endgroup +% enddef ; + +%primarydef p parallel s = +% begingroup ; save q, w,h ; path q ; numeric w, h ; +% w := bbwidth(p) ; h := bbheight(p) ; +% q := p if (w>0) and (h>0) : +% xyscaled ((w+2*xpart paired(s))/w,(h+2*ypart paired(s))/h) fi ; +% (q shifted (center p-center q)) +% endgroup +%enddef ; + +primarydef p paralleled d = + p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p) +enddef ; + +vardef punked primary p = + (point 0 of p for i=1 upto length(p)-1 : -- point i of p endfor + if cycle p : -- cycle else : -- point length(p) of p fi) +enddef ; + +vardef curved primary p = + (point 0 of p for i=1 upto length(p)-1 : .. point i of p endfor + if cycle p : .. cycle else : .. point length(p) of p fi) +enddef ; + +primarydef p blownup s = + begingroup + save _p_ ; path _p_ ; _p_ := p xysized + (bbwidth (p)+2(xpart paired(s)), + bbheight(p)+2(ypart paired(s))) ; + (_p_ shifted (center p - center _p_)) + endgroup +enddef ; + +%D Rather fundamental. + +% not yet ok + +def leftrightpath(expr p, l) = % used in s-pre-19 + save q, r, t, b ; path q, r ; pair t, b ; + t := (ulcorner p -- urcorner p) intersection_point p ; + b := (llcorner p -- lrcorner p) intersection_point p ; + r := if xpart directionpoint t of p < 0 : reverse p else : p fi ; % r is needed, else problems when reverse is fed + q := r cutbefore if l: t else: b fi ; + q := q if xpart point 0 of r > 0 : & + r fi cutafter if l: b else: t fi ; + q +enddef ; + +vardef leftpath expr p = leftrightpath(p,true ) enddef ; +vardef rightpath expr p = leftrightpath(p,false) enddef ; + +%D Drawoptions + +def saveoptions = + save _op_ ; def _op_ = enddef ; +enddef ; + +%D Tracing. + +let normaldraw = draw ; +let normalfill = fill ; + +% bugged in mplib so ... + +def normalfill expr c = addto currentpicture contour c _op_ enddef ; +def normaldraw expr p = addto currentpicture if picture p: also p else: doublepath p withpen currentpen fi _op_ enddef ; + + +def drawlineoptions (text t) = def _lin_opt_ = t enddef ; enddef ; +def drawpointoptions (text t) = def _pnt_opt_ = t enddef ; enddef ; +def drawcontroloptions(text t) = def _ctr_opt_ = t enddef ; enddef ; +def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ; +def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ; +def drawboundoptions (text t) = def _bnd_opt_ = t enddef ; enddef ; +def drawpathoptions (text t) = def _pth_opt_ = t enddef ; enddef ; + +def resetdrawoptions = + drawlineoptions (withpen pencircle scaled 1pt withcolor .5white) ; + drawpointoptions (withpen pencircle scaled 4pt withcolor black) ; + drawcontroloptions(withpen pencircle scaled 2.5pt withcolor black) ; + drawlabeloptions () ; + draworiginoptions (withpen pencircle scaled 1pt withcolor .5white) ; + drawboundoptions (dashed evenly _ori_opt_) ; + drawpathoptions (withpen pencircle scaled 5pt withcolor .8white) ; +enddef ; + +resetdrawoptions ; + +%D Path. + +def drawpath expr p = + normaldraw p _pth_opt_ +enddef ; + +%D Arrow. + +vardef drawarrowpath expr p = + save autoarrows ; boolean autoarrows ; autoarrows := true ; + drawarrow p _pth_opt_ +enddef ; + +%def drawarrowpath expr p = +% begingroup ; +% save autoarrows ; boolean autoarrows ; autoarrows := true ; +% save arrowpath ; path arrowpath ; arrowpath := p ; +% _drawarrowpath_ +%enddef ; +% +%def _drawarrowpath_ text t = +% drawarrow arrowpath _pth_opt_ t ; +% endgroup ; +%enddef ; + +def midarrowhead expr p = + arrowhead p cutafter + (point length(p cutafter point .5 along p)+ahlength on p) +enddef ; + +vardef arrowheadonpath (expr p, s) = + save autoarrows ; boolean autoarrows ; autoarrows := true ; + set_ahlength(scaled ahfactor) ; % added + arrowhead p if s<1 : cutafter (point (s*arclength(p)+.5ahlength) on p) fi +enddef ; + +%D Points. + +def drawpoint expr c = + if string c : + string _c_ ; _c_ := "(" & c & ")" ; + dotlabel.urt(_c_, scantokens _c_) ; + drawdot scantokens _c_ + else : + dotlabel.urt("(" & decimal xpart c & "," & decimal ypart c & ")", c) ; + drawdot c + fi _pnt_opt_ +enddef ; + +%D PathPoints. + +def drawpoints expr c = path _c_ ; _c_ := c ; do_drawpoints enddef ; +def drawcontrolpoints expr c = path _c_ ; _c_ := c ; do_drawcontrolpoints enddef ; +def drawcontrollines expr c = path _c_ ; _c_ := c ; do_drawcontrollines enddef ; +def drawpointlabels expr c = path _c_ ; _c_ := c ; do_drawpointlabels enddef ; + +def do_drawpoints text t = + for _i_=0 upto length(_c_) : + normaldraw point _i_ of _c_ _pnt_opt_ t ; + endfor ; +enddef; + +def do_drawcontrolpoints text t = + for _i_=0 upto length(_c_) : + normaldraw precontrol _i_ of _c_ _ctr_opt_ t ; + normaldraw postcontrol _i_ of _c_ _ctr_opt_ t ; + endfor ; +enddef; + +def do_drawcontrollines text t = + for _i_=0 upto length(_c_) : + normaldraw point _i_ of _c_ -- precontrol _i_ of _c_ _lin_opt_ t ; + normaldraw point _i_ of _c_ -- postcontrol _i_ of _c_ _lin_opt_ t ; + endfor ; +enddef; + +boolean swappointlabels ; swappointlabels := false ; + +def do_drawpointlabels text t = + for _i_=0 upto length(_c_) : + pair _u_ ; _u_ := unitvector(direction _i_ of _c_) + rotated if swappointlabels : - fi 90 ; + pair _p_ ; _p_ := (point _i_ of _c_) ; + _u_ := 12 * defaultscale * _u_ ; + normaldraw thelabel ( decimal _i_, + _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ; + endfor ; +enddef; + +%D Bounding box. + +def drawboundingbox expr p = + normaldraw boundingbox p _bnd_opt_ +enddef ; + +%D Origin. + +numeric originlength ; originlength := .5cm ; + +def draworigin text t = + normaldraw (origin shifted (0, originlength) -- + origin shifted (0,-originlength)) _ori_opt_ t ; + normaldraw (origin shifted ( originlength,0) -- + origin shifted (-originlength,0)) _ori_opt_ t ; +enddef; + +%D Axis. + +numeric tickstep ; tickstep := 5mm ; +numeric ticklength ; ticklength := 2mm ; + +def drawxticks expr c = path _c_ ; _c_ := c ; do_drawxticks enddef ; +def drawyticks expr c = path _c_ ; _c_ := c ; do_drawyticks enddef ; +def drawticks expr c = path _c_ ; _c_ := c ; do_drawticks enddef ; + +% Adding eps prevents disappearance due to rounding errors. + +def do_drawxticks text t = + for i=0 step -tickstep until xpart llcorner _c_ - eps : + if (i<=xpart lrcorner _c_) : + normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ; + fi ; + endfor ; + for i=0 step tickstep until xpart lrcorner _c_ + eps : + if (i>=xpart llcorner _c_) : + normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ; + fi ; + endfor ; + normaldraw (llcorner _c_ -- ulcorner _c_) + shifted (-xpart llcorner _c_,0) _ori_opt_ t ; +enddef ; + +def do_drawyticks text t = + for i=0 step -tickstep until ypart llcorner _c_ - eps : + if (i<=ypart ulcorner _c_) : + normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ; + fi ; + endfor ; + for i=0 step tickstep until ypart ulcorner _c_ + eps : + if (i>=ypart llcorner _c_) : + normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ; + fi ; + endfor ; + normaldraw (llcorner _c_ -- lrcorner _c_) + shifted (0,-ypart llcorner _c_) _ori_opt_ t ; +enddef ; + +def do_drawticks text t = + drawxticks _c_ t ; + drawyticks _c_ t ; +enddef ; + +%D All of it except axis. + +def drawwholepath expr p = + draworigin ; + drawpath p ; + drawcontrollines p ; + drawcontrolpoints p ; + drawpoints p ; + drawboundingbox p ; + drawpointlabels p ; +enddef ; + +%D Tracing. + +def visualizeddraw expr c = + if picture c : normaldraw c else : path _c_ ; _c_ := c ; do_visualizeddraw fi +enddef ; + +def visualizedfill expr c = + if picture c : normalfill c else : path _c_ ; _c_ := c ; do_visualizedfill fi +enddef ; + +def do_visualizeddraw text t = + draworigin ; + drawpath _c_ t ; + drawcontrollines _c_ ; + drawcontrolpoints _c_ ; + drawpoints _c_ ; + drawboundingbox _c_ ; + drawpointlabels _c_ ; +enddef ; + +def do_visualizedfill text t = + if cycle _c_ : normalfill _c_ t fi ; + draworigin ; + drawcontrollines _c_ ; + drawcontrolpoints _c_ ; + drawpoints _c_ ; + drawboundingbox _c_ ; + drawpointlabels _c_ ; +enddef ; + +def visualizepaths = + let fill = visualizedfill ; + let draw = visualizeddraw ; +enddef ; + +def naturalizepaths = + let fill = normalfill ; + let draw = normaldraw ; +enddef ; + +extra_endfig := extra_endfig & " naturalizepaths ; " ; + +%D Also handy: + +extra_beginfig := extra_beginfig & " truecorners := 0 ; " ; % restores +extra_beginfig := extra_beginfig & " miterlimit := 10 ; " ; % restores +extra_beginfig := extra_beginfig & " linejoin := rounded ; " ; % restores +extra_beginfig := extra_beginfig & " linecap := rounded ; " ; % restores + +%D Normally, arrowheads don't scale well. So we provide a +%D hack. + +boolean autoarrows ; autoarrows := false ; +numeric ahfactor ; ahfactor := 2.5 ; + +def set_ahlength (text t) = +% ahlength := (ahfactor*pen_size(_op_ t)) ; % _op_ added +% problem: _op_ can contain color so a no-go, we could apply the transform +% but i need to figure out the best way (fakepicture and take components). + ahlength := (ahfactor*pen_size(t)) ; +enddef ; + +vardef pen_size (text t) = + save p ; picture p ; p := nullpicture ; + addto p doublepath (top origin -- bot origin) t ; + (ypart urcorner p - ypart lrcorner p) +enddef ; + +%D The next two macros are adapted versions of plain +%D \METAPOST\ definitions. + +def _finarr text t = + if autoarrows : set_ahlength (t) fi ; + draw _apth t ; + filldraw arrowhead _apth t ; +enddef; + +def _findarr text t = + if autoarrows : set_ahlength (t) fi ; + draw _apth t ; + fill arrowhead _apth withpen currentpen t ; + fill arrowhead reverse _apth withpen currentpen t ; +enddef ; + +%D Handy too ...... + +vardef pointarrow (expr pat, loc, len, off) = + save l, r, s, t ; path l, r ; numeric s ; pair t ; + t := if pair loc : loc else : point loc along pat fi ; + s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ; + r := pat cutbefore t ; + r := (r cutafter point (arctime s of r) of r) ; + s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ; + l := reverse (pat cutafter t) ; + l := (reverse (l cutafter point (arctime s of l) of l)) ; + (l..r) +enddef ; + +def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ; +def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ; +def centerarrow (expr pat,tim,len) = pointarrow(pat,tim,len, 0) enddef ; + +%D The \type {along} and \type {on} operators can be used +%D as follows: +%D +%D \starttypen +%D drawdot point .5 along somepath ; +%D drawdot point 3cm on somepath ; +%D \stoptypen +%D +%D The number denotes a percentage (fraction). + +primarydef pct along pat = % also negative + (arctime (pct * (arclength pat)) of pat) of pat +enddef ; + +% primarydef len on pat = +% (arctime len of pat) of pat +% enddef ; + +primarydef len on pat = + (arctime if len>0 : len else : (arclength(pat)+len) fi of pat) of pat +enddef ; + +% this cuts of a piece from both ends + +% tertiarydef pat cutends len = +% begingroup ; save tap ; path tap ; +% tap := pat cutbefore (point len on pat) ; +% (tap cutafter (point -len on tap)) +% endgroup +% enddef ; + +tertiarydef pat cutends len = + begingroup ; save tap ; path tap ; + tap := pat cutbefore (point (xpart paired(len)) on pat) ; + (tap cutafter (point -(ypart paired(len)) on tap)) + endgroup +enddef ; + +%D To be documented. + +path freesquare ; + +freesquare := ((-1,0)--(-1,-1)--(0,-1)--(+1,-1)-- + (+1,0)--(+1,+1)--(0,+1)--(-1,+1)--cycle) scaled .5 ; + +numeric freelabeloffset ; freelabeloffset := 3pt ; +numeric freedotlabelsize ; freedotlabelsize := 3pt ; + +vardef thefreelabel (expr str, loc, ori) = + save s, p, q, l ; picture s ; path p, q ; pair l ; + interim labeloffset := freelabeloffset ; + s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ; + setbounds s to boundingbox s enlarged freelabeloffset ; + p := fullcircle scaled (2*length(loc-ori)) shifted ori ; + q := freesquare xyscaled (urcorner s - llcorner s) ; +% l := point (xpart (p intersectiontimes (ori--loc))) of q ; + l := point xpart (p intersectiontimes + (ori--((1+eps)*arclength(ori--loc)*unitvector(loc-ori)))) of q ; + setbounds s to boundingbox s enlarged -freelabeloffset ; % new + %draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ; + (s shifted -l) +enddef ; + +% better? + +vardef thefreelabel (expr str, loc, ori) = + save s, p, q, l ; picture s ; path p, q ; pair l ; + interim labeloffset := freelabeloffset ; + s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ; + setbounds s to boundingbox s enlarged freelabeloffset ; + p := fullcircle scaled (2*length(loc-ori)) shifted ori ; + q := freesquare xyscaled (urcorner s - llcorner s) ; + l := point xpart (p intersectiontimes (ori--loc shifted (loc-ori))) of q ; + setbounds s to boundingbox s enlarged -freelabeloffset ; % new + %draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ; + (s shifted -l) +enddef ; + +vardef freelabel (expr str, loc, ori) = + draw thefreelabel(str,loc,ori) ; +enddef ; + +vardef freedotlabel (expr str, loc, ori) = + interim linecap:=rounded ; + draw loc withpen pencircle scaled freedotlabelsize ; + draw thefreelabel(str,loc,ori) ; +enddef ; + +%D \starttypen +%D drawarrow anglebetween(line_a,line_b,somelabel) ; +%D \stoptypen + +% angleoffset ; angleoffset := 0pt ; +numeric anglelength ; anglelength := 20pt ; +numeric anglemethod ; anglemethod := 1 ; + +% vardef anglebetween (expr a, b, str) = % path path string +% save pointa, pointb, common, middle, offset ; +% pair pointa, pointb, common, middle, offset ; +% save curve ; path curve ; +% save where ; numeric where ; +% if round point 0 of a = round point 0 of b : +% common := point 0 of a ; +% else : +% common := a intersectionpoint b ; +% fi ; +% pointa := point anglelength on a ; +% pointb := point anglelength on b ; +% where := turningnumber (common--pointa--pointb--cycle) ; +% middle := ((common--pointa) rotatedaround (pointa,-where*90)) +% intersectionpoint +% ((common--pointb) rotatedaround (pointb, where*90)) ; +% if anglemethod = 0 : +% curve := pointa{unitvector(middle-pointa)}.. pointb; +% middle := point .5 along curve ; +% curve := common ; +% elseif anglemethod = 1 : +% curve := pointa{unitvector(middle-pointa)}.. pointb; +% middle := point .5 along curve ; +% elseif anglemethod = 2 : +% middle := common rotatedaround(.5[pointa,pointb],180) ; +% curve := pointa--middle--pointb ; +% elseif anglemethod = 3 : +% curve := pointa--middle--pointb ; +% elseif anglemethod = 4 : +% curve := pointa..controls middle..pointb ; +% middle := point .5 along curve ; +% fi ; +% draw thefreelabel(str, middle, common) withcolor black ; +% curve +% enddef ; + +vardef anglebetween (expr a, b, str) = % path path string + save pointa, pointb, common, middle, offset ; + pair pointa, pointb, common, middle, offset ; + save curve ; path curve ; + save where ; numeric where ; + if round point 0 of a = round point 0 of b : + common := point 0 of a ; + else : + common := a intersectionpoint b ; + fi ; + pointa := point anglelength on a ; + pointb := point anglelength on b ; + where := turningnumber (common--pointa--pointb--cycle) ; + middle := (reverse(common--pointa) rotatedaround (pointa,-where*90)) + intersection_point + (reverse(common--pointb) rotatedaround (pointb, where*90)) ; + if not intersection_found : + middle := point .5 along + ((reverse(common--pointa) rotatedaround (pointa,-where*90)) -- + ( (common--pointb) rotatedaround (pointb, where*90))) ; + fi ; + if anglemethod = 0 : + curve := pointa{unitvector(middle-pointa)}.. pointb; + middle := point .5 along curve ; + curve := common ; + elseif anglemethod = 1 : + curve := pointa{unitvector(middle-pointa)}.. pointb; + middle := point .5 along curve ; + elseif anglemethod = 2 : + middle := common rotatedaround(.5[pointa,pointb],180) ; + curve := pointa--middle--pointb ; + elseif anglemethod = 3 : + curve := pointa--middle--pointb ; + elseif anglemethod = 4 : + curve := pointa..controls middle..pointb ; + middle := point .5 along curve ; + fi ; + draw thefreelabel(str, middle, common) ; % withcolor black ; + curve +enddef ; + +% Stack + +picture currentpicturestack[] ; +numeric currentpicturedepth ; currentpicturedepth := 0 ; + +def pushcurrentpicture = + currentpicturedepth := currentpicturedepth + 1 ; + currentpicturestack[currentpicturedepth] := currentpicture ; + currentpicture := nullpicture ; +enddef ; + +def popcurrentpicture text t = % optional text + if currentpicturedepth > 0 : + addto currentpicturestack[currentpicturedepth] also currentpicture t ; + currentpicture := currentpicturestack[currentpicturedepth] ; + currentpicturedepth := currentpicturedepth - 1 ; + fi ; +enddef ; + +%D colorcircle(size, red, green, blue) ; + +% vardef colorcircle (expr size, red, green, blue) = +% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; +% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; +% +% radius := 5cm ; pickup pencircle scaled (radius/25) ; +% +% r := g := b := fullcircle scaled radius shifted (0,radius/4) ; +% +% r := r rotatedaround (origin, 15) ; +% g := g rotatedaround (origin,135) ; +% b := b rotatedaround (origin,255) ; +% +% r := r rotatedaround(center r,-90) ; +% g := g rotatedaround(center g, 90) ; +% +% gg := buildcycle(buildcycle(reverse r,b),g) ; +% cc := buildcycle(buildcycle(b,reverse g),r) ; +% +% rr := gg rotatedaround(origin,120) ; +% bb := gg rotatedaround(origin,240) ; +% +% yy := cc rotatedaround(origin,120) ; +% mm := cc rotatedaround(origin,240) ; +% +% pushcurrentpicture ; +% +% fill fullcircle scaled radius withcolor white ; +% +% fill rr withcolor red ; fill cc withcolor white-red ; +% fill gg withcolor green ; fill mm withcolor white-green ; +% fill bb withcolor blue ; fill yy withcolor white-blue ; +% +% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; +% +% currentpicture := currentpicture xsized size ; +% +% popcurrentpicture ; +% enddef ; + +% vardef colorcircle (expr size, red, green, blue) = +% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; +% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; +% +% radius := 5cm ; pickup pencircle scaled (radius/25) ; +% +% transform t ; t := identity rotatedaround(origin,120) ; +% +% r := fullcircle scaled radius +% shifted (0,radius/4) rotatedaround(origin,15) ; +% +% g := r transformed t ; b := g transformed t ; +% +% r := r rotatedaround(center r,-90) ; +% g := g rotatedaround(center g, 90) ; +% +% gg := buildcycle(buildcycle(reverse r,b),g) ; +% cc := buildcycle(buildcycle(b,reverse g),r) ; +% +% rr := gg transformed t ; bb := rr transformed t ; +% yy := cc transformed t ; mm := yy transformed t ; +% +% pushcurrentpicture ; +% +% fill fullcircle scaled radius withcolor white ; +% +% fill rr withcolor red ; fill cc withcolor white-red ; +% fill gg withcolor green ; fill mm withcolor white-green ; +% fill bb withcolor blue ; fill yy withcolor white-blue ; +% +% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; +% +% currentpicture := currentpicture xsized size ; +% +% popcurrentpicture ; +% enddef ; + +vardef colorcircle (expr size, red, green, blue) = + save r, g, b, c, m, y, w ; save radius ; + path r, g, b, c, m, y, w ; numeric radius ; + + radius := 5cm ; pickup pencircle scaled (radius/25) ; + + transform t ; t := identity rotatedaround(origin,120) ; + + r := fullcircle rotated 90 scaled radius + shifted (0,radius/4) rotatedaround(origin,135) ; + + b := r transformed t ; g := b transformed t ; + + c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ; + y := c transformed t ; m := y transformed t ; + + w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ; + + pushcurrentpicture ; + + fill r withcolor red ; + fill g withcolor green ; + fill b withcolor blue ; + fill c withcolor white-red ; + fill m withcolor white-green ; + fill y withcolor white-blue ; + fill w withcolor white ; + + for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ; + + currentpicture := currentpicture xsized size ; + + popcurrentpicture ; +enddef ; + +% penpoint (i,2) of somepath -> inner / outer point + +vardef penpoint expr pnt of p = + save n, d ; numeric n, d ; + (n,d) = if pair pnt : pnt else : (pnt,1) fi ; + (point n of p shifted ((penoffset direction n of p of currentpen) scaled d)) +enddef ; + +% nice: currentpicture := inverted currentpicture ; + +primarydef p uncolored c = + if color p : + c - p + else : + image + (for i within p : + addto currentpicture + if stroked i or filled i : + if filled i : contour else : doublepath fi pathpart i + dashed dashpart i withpen penpart i + else : + also i + fi + withcolor c-(redpart i, greenpart i, bluepart i) ; + endfor ; ) + fi +enddef ; + +vardef inverted primary p = + (p uncolored white) +enddef ; + +% primarydef p softened c = +% if color p : +% tripled(c) * p +% else : +% image +% (save cc ; color cc ; cc := tripled(c) ; +% for i within p : +% addto currentpicture +% if stroked i or filled i : +% if filled i : contour else : doublepath fi pathpart i +% dashed dashpart i withpen penpart i +% else : +% also i +% fi +% withcolor (redpart cc * redpart i, +% greenpart cc * greenpart i, +% bluepart cc * bluepart i) ; +% endfor ;) +% fi +% enddef ; + +primarydef p softened c = + begingroup + save cc ; color cc ; cc := tripled(c) ; + if color p : + (redpart cc * redpart p, + greenpart cc * greenpart p, + bluepart cc * bluepart p) + else : + image + (for i within p : + addto currentpicture + if stroked i or filled i : + if filled i : contour else : doublepath fi pathpart i + dashed dashpart i withpen penpart i + else : + also i + fi + withcolor (redpart cc * redpart i, + greenpart cc * greenpart i, + bluepart cc * bluepart i) ; + endfor ;) + fi + endgroup +enddef ; + +vardef grayed primary p = + if color p : + tripled(.30redpart p+.59greenpart p+.11bluepart p) + else : + image + (for i within p : + addto currentpicture + if stroked i or filled i : + if filled i : contour else : doublepath fi pathpart i + dashed dashpart i withpen penpart i + else : + also i + fi + withcolor tripled(.30redpart i+.59greenpart i+.11bluepart i) ; + endfor ; ) + fi +enddef ; + +% yes or no: "text" infont "cmr12" at 24pt ; + +% let normalinfont = infont ; +% +% numeric lastfontsize ; lastfontsize = fontsize defaultfont ; +% +% def infont primary name = % no vardef, no expr +% hide(lastfontsize := fontsize name) % no ; +% normalinfont name +% enddef ; +% +% def scaledat expr size = +% scaled (size/lastfontsize) +% enddef ; +% +% let at = scaledat ; + +% like decimal + +def condition primary b = if b : "true" else : "false" fi enddef ; + +% undocumented + +primarydef p stretched s = + begingroup + save pp ; path pp ; pp := p xyscaled s ; + (pp shifted ((point 0 of p) - (point 0 of pp))) + endgroup +enddef ; + +% primarydef p enlonged len = +% begingroup +% save al ; al := arclength(p) ; +% if al > 0 : +% if pair p : +% point 1 of ((origin -- p) stretched ((al+len)/al)) +% else : +% p stretched ((al+len)/al) +% fi +% else : +% p +% fi +% endgroup +% enddef ; + +primarydef p enlonged len = + begingroup + if pair p : + save q ; path q ; q := origin -- p ; + save al ; al := arclength(q) ; + if al > 0 : + point 1 of (q stretched ((al+len)/al)) + else : + p + fi + else : + save al ; al := arclength(p) ; + if al > 0 : + p stretched ((al+len)/al) + else : + p + fi + fi + endgroup +enddef ; + +% path p ; p := (0,0) -- (10cm,5cm) ; +% drawarrow p withcolor red ; +% drawarrow p shortened 1cm withcolor green ; + +primarydef p shortened d = + reverse ( ( reverse (p enlonged -d) ) enlonged -d ) +enddef ; + +% yes or no, untested -) + +def xshifted expr dx = shifted(dx,0) enddef ; +def yshifted expr dy = shifted(0,dy) enddef ; + +% also handy + +% right: str = readfrom ("abc" & ".def" ) ; +% wrong: str = readfrom "abc" & ".def" ; + +% Every 62th read fails so we need to try again! + +% def readfile (expr name) = +% if (readfrom (name) <> EOF) : +% scantokens("input " & name & ";") ; +% elseif (readfrom (name) <> EOF) : +% scantokens("input " & name & ";") ; +% fi ; +% closefrom (name) ; +% enddef ; +% +% this sometimes fails on the elseif, so : +% + +def readfile (expr name) = + begingroup ; save ok ; boolean ok ; + if (readfrom (name) <> EOF) : + ok := false ; + elseif (readfrom (name) <> EOF) : + ok := false ; + else : + ok := true ; + fi ; + if not ok : + scantokens("input " & name & " ") ; + fi ; + closefrom (name) ; + endgroup ; +enddef ; + +% permits redefinition of end in macro + +inner end ; + +% real fun + +let normalwithcolor = withcolor ; + +def remapcolors = + def withcolor primary c = normalwithcolor remappedcolor(c) enddef ; +enddef ; + +def normalcolors = + let withcolor = normalwithcolor ; +enddef ; + +def resetcolormap = + color color_map[][][] ; + normalcolors ; +enddef ; + +resetcolormap ; + +% color_map_resolution := 1000 ; +% +% def r_color primary c = round(color_map_resolution*redpart c) enddef ; +% def g_color primary c = round(color_map_resolution*greenpart c) enddef ; +% def b_color primary c = round(color_map_resolution*bluepart c) enddef ; + +def r_color primary c = redpart c enddef ; +def g_color primary c = greenpart c enddef ; +def b_color primary c = bluepart c enddef ; + +def remapcolor(expr old, new) = + color_map[r_color old][g_color old][b_color old] := new ; +enddef ; + +def remappedcolor(expr c) = + if known color_map[r_color c][g_color c][b_color c] : + color_map[r_color c][g_color c][b_color c] + else : + c + fi +enddef ; + +% def refill suffix c = do_repath (1) (c) enddef ; +% def redraw suffix c = do_repath (2) (c) enddef ; +% def recolor suffix c = do_repath (0) (c) enddef ; +% +% color refillbackground ; refillbackground := (1,1,1) ; +% +% def do_repath (expr mode) (suffix c) text t = % can it be stroked and filled at the same time ? +% begingroup ; +% if mode=0 : save withcolor ; remapcolors ; fi ; +% save _c_, _cc_, _f_, _b_ ; picture _c_, _cc_ ; color _f_ ; path _b_ ; +% _c_ := c ; _b_ := boundingbox c ; c := nullpicture ; +% for i within _c_ : +% _f_ := (redpart i, greenpart i, bluepart i) ; +% if bounded i : +% setbounds c to pathpart i ; +% elseif clipped i : +% clip c to pathpart i ; +% elseif stroked i : +% addto c doublepath pathpart i +% dashed dashpart i withpen penpart i +% withcolor _f_ % (redpart i, greenpart i, bluepart i) +% if mode=2 : t fi ; +% elseif filled i : +% addto c contour pathpart i +% withcolor _f_ +% if (mode=1) and (_f_<>refillbackground) : t fi ; +% else : +% addto c also i ; +% fi ; +% endfor ; +% setbounds c to _b_ ; +% endgroup ; +% enddef ; + +% Thanks to Jens-Uwe Morawski for pointing out that we need +% to treat bounded and clipped components as local pictures. + +def recolor suffix p = p := repathed (0,p) enddef ; +def refill suffix p = p := repathed (1,p) enddef ; +def redraw suffix p = p := repathed (2,p) enddef ; +def retext suffix p = p := repathed (3,p) enddef ; +def untext suffix p = p := repathed (4,p) enddef ; + +% primarydef p recolored t = repathed(0,p) t enddef ; +% primarydef p refilled t = repathed(1,p) t enddef ; +% primarydef p redrawn t = repathed(2,p) t enddef ; +% primarydef p retexted t = repathed(3,p) t enddef ; +% primarydef p untexted t = repathed(4,p) t enddef ; + +color refillbackground ; refillbackground := (1,1,1) ; + +% vardef repathed (expr mode, p) text t = +% begingroup ; +% if mode=0 : save withcolor ; remapcolors ; fi ; +% save _p_, _pp_, _f_, _b_, _t_ ; +% picture _p_, _pp_ ; color _f_ ; path _b_ ; transform _t_ ; +% _b_ := boundingbox p ; _p_ := nullpicture ; +% for i within p : +% _f_ := (redpart i, greenpart i, bluepart i) ; +% if bounded i : +% _pp_ := repathed(mode,i) t ; +% setbounds _pp_ to pathpart i ; +% addto _p_ also _pp_ ; +% elseif clipped i : +% _pp_ := repathed(mode,i) t ; +% clip _pp_ to pathpart i ; +% addto _p_ also _pp_ ; +% elseif stroked i : +% addto _p_ doublepath pathpart i +% dashed dashpart i withpen penpart i +% withcolor _f_ % (redpart i, greenpart i, bluepart i) +% if mode=2 : t fi ; +% elseif filled i : +% addto _p_ contour pathpart i +% withcolor _f_ +% if (mode=1) and (_f_<>refillbackground) : t fi ; +% elseif textual i : % textpart i <> "" : +% if mode <> 4 : +% % transform _t_ ; +% % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ; +% % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ; +% % addto _p_ also +% % textpart i infont fontpart i % todo : other font +% % transformed _t_ +% % withpen penpart i +% % withcolor _f_ +% % if mode=3 : t fi ; +% addto _p_ also i if mode=3 : t fi ; +% fi ; +% else : +% addto _p_ also i ; +% fi ; +% endfor ; +% setbounds _p_ to _b_ ; +% _p_ +% endgroup +% enddef ; + +def restroke suffix p = p := repathed (21,p) enddef ; % keep attributes +def reprocess suffix p = p := repathed (22,p) enddef ; % no attributes + +% also 11 and 12 + +vardef repathed (expr mode, p) text t = + begingroup ; + if mode=0 : save withcolor ; remapcolors ; fi ; + save _p_, _pp_, _ppp_, _f_, _b_, _t_ ; + picture _p_, _pp_, _ppp_ ; color _f_ ; path _b_ ; transform _t_ ; + _b_ := boundingbox p ; _p_ := nullpicture ; + for i within p : + _f_ := (redpart i, greenpart i, bluepart i) ; + if bounded i : + _pp_ := repathed(mode,i) t ; + setbounds _pp_ to pathpart i ; + addto _p_ also _pp_ ; + elseif clipped i : + _pp_ := repathed(mode,i) t ; + clip _pp_ to pathpart i ; + addto _p_ also _pp_ ; + elseif stroked i : + if mode=21 : + _ppp_ := i ; % indirectness is needed + addto _p_ also image(scantokens(t & " pathpart _ppp_") + dashed dashpart i withpen penpart i + withcolor _f_ ; ) ; + elseif mode=22 : + _ppp_ := i ; % indirectness is needed + addto _p_ also image(scantokens(t & " pathpart _ppp_")) ; + else : + addto _p_ doublepath pathpart i + dashed dashpart i withpen penpart i + withcolor _f_ % (redpart i, greenpart i, bluepart i) + if mode=2 : t fi ; + fi ; + elseif filled i : + if mode=11 : + _ppp_ := i ; % indirectness is needed + addto _p_ also image(scantokens(t & " pathpart _ppp_") + withcolor _f_ ; ) ; + elseif mode=12 : + _ppp_ := i ; % indirectness is needed + addto _p_ also image(scantokens(t & " pathpart _ppp_")) ; + else : + addto _p_ contour pathpart i + withcolor _f_ + if (mode=1) and (_f_<>refillbackground) : t fi ; + fi ; + elseif textual i : % textpart i <> "" : + if mode <> 4 : + % transform _t_ ; + % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ; + % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ; + % addto _p_ also + % textpart i infont fontpart i % todo : other font + % transformed _t_ + % withpen penpart i + % withcolor _f_ + % if mode=3 : t fi ; + addto _p_ also i if mode=3 : t fi ; + fi ; + else : + addto _p_ also i ; + fi ; + endfor ; + setbounds _p_ to _b_ ; + _p_ + endgroup +enddef ; + +% After a question of Denis on how to erase a z variable, Jacko +% suggested to assign whatever to x and y. So a clearz +% variable can be defined as: +% +% vardef clearz@# = +% x@# := whatever ; +% y@# := whatever ; +% enddef ; +% +% but Jacko suggested a redefinition of clearxy: +% +% def clearxy text s = +% clearxy_index_:=0; +% for $:=s: +% clearxy_index_:=clearxy_index_+1; endfor; +% if clearxy_index_=0: +% save x,y; +% else: +% forsuffixes $:=s: x$:=whatever; y$:=whatever; endfor; +% fi +% enddef; +% +% which i decided to simplify to: + +def clearxy text s = + if false for $ := s : or true endfor : + forsuffixes $ := s : x$ := whatever ; y$ := whatever ; endfor ; + else : + save x, y ; + fi +enddef ; + +% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ; + +% show x0 ; z0 = (10,10) ; +% show x0 ; x0 := whatever ; y0 := whatever ; +% show x0 ; z0 = (20,20) ; +% show x0 ; clearxy 0 ; +% show x0 ; z0 = (30,30) ; + +primarydef p smoothed d = + (p llmoved (-xpart paired(d),0) -- p lrmoved (-xpart paired(d),0) {right} .. + p lrmoved (0,-ypart paired(d)) -- p urmoved (0,-ypart paired(d)) {up} .. + p urmoved (-xpart paired(d),0) -- p ulmoved (-xpart paired(d),0) {left} .. + p ulmoved (0,-ypart paired(d)) -- p llmoved (0,-ypart paired(d)) {down} .. cycle) +enddef ; + +primarydef p cornered c = + ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) -- + for i=1 upto length(p) : + (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) -- + (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) .. + controls point i of p .. + endfor cycle) +enddef ; + +% cmyk color support + +vardef cmyk(expr c,m,y,k) = + (1-c-k,1-m-k,1-y-k) +enddef ; + +% handy + +vardef bbwidth (expr p) = + (if known p : + if path p or picture p : + xpart (lrcorner p - llcorner p) + else : 0 fi else : 0 + fi ) +enddef ; + +vardef bbheight (expr p) = + (if known p : if path p or picture p : + ypart (urcorner p - lrcorner p) + else : 0 fi else : 0 + fi) +enddef ; + +color nocolor ; numeric noline ; % both unknown signals + +def dowithpath (expr p, lw, lc, bc) = + if known p : + if known bc : + fill p withcolor bc ; + fi ; + if known lw and known lc : + draw p withpen pencircle scaled lw withcolor lc ; + elseif known lw : + draw p withpen pencircle scaled lw ; + elseif known lc : + draw p withcolor lc ; + fi ; + fi ; +enddef ; + +% result from metafont discussion list (denisr/boguslawj) + +def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ; +def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ; + +% not perfect, but useful since it removes redundant points. + +% vardef dostraightened(expr sign, p) = +% if length(p)>2 : % was 1, but straight lines are ok +% save pp ; path pp ; +% pp := point 0 of p ; +% for i=1 upto length(p)-1 : +% if round(point i of p) <> round(point length(pp) of pp) : +% pp := pp -- point i of p ; +% fi ; +% endfor ; +% save n, ok ; numeric n ; boolean ok ; +% n := length(pp) ; ok := false ; +% if n>2 : +% for i=0 upto n : % evt hier ook round +% if unitvector(round(point i of pp - +% point if i=0 : n else : i-1 fi of pp)) <> +% sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp - +% point i of pp)) : +% if ok : -- else : ok := true ; fi point i of pp +% fi +% endfor +% if ok and (cycle p) : -- cycle fi +% else : +% pp +% fi +% else : +% p +% fi +% enddef ; + +% vardef simplified expr p = +% (reverse dostraightened(+1,dostraightened(+1,reverse p))) +% enddef ; + +% vardef unspiked expr p = +% (reverse dostraightened(-1,dostraightened(-1,reverse p))) +% enddef ; + +% simplified : remove same points as well as redundant points +% unspiked : remove same points as well as areas with zero distance + +vardef dostraightened(expr sign, p) = + save _p_, _q_ ; path _p_, _q_ ; + _p_ := p ; + forever : + _q_ := dodostraightened(sign, _p_) ; + exitif length(_p_) = length(_q_) ; + _p_ := _q_ ; + endfor ; + _q_ +enddef ; + +vardef dodostraightened(expr sign, p) = + if length(p)>2 : % was 1, but straight lines are ok + save pp ; path pp ; + pp := point 0 of p ; + for i=1 upto length(p)-1 : + if round(point i of p) <> round(point length(pp) of pp) : + pp := pp -- point i of p ; + fi ; + endfor ; + save n, ok ; numeric n ; boolean ok ; + n := length(pp) ; ok := false ; + if n>2 : + for i=0 upto n : % evt hier ook round + if unitvector(round(point i of pp - + point if i=0 : n else : i-1 fi of pp)) <> + sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp - + point i of pp)) : + if ok : -- else : ok := true ; fi point i of pp + fi + endfor + if ok and (cycle p) : -- cycle fi + else : + pp + fi + else : + p + fi +enddef ; + +% vardef simplified expr p = +% dostraightened(+1,p) +% enddef ; + +% vardef unspiked expr p = +% dostraightened(-1,p) +% enddef ; + +vardef simplified expr p = + (reverse dostraightened(+1,dostraightened(+1,reverse p))) +enddef ; + +vardef unspiked expr p = + (reverse dostraightened(-1,dostraightened(-1,reverse p))) +enddef ; + +% path p ; +% p := (2cm,1cm) -- (2cm,1cm) -- (2cm,1cm) -- (3cm,1cm) -- +% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) -- +% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) -- +% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ; +% +% p := unitcircle scaled 4cm ; +% +% drawpath p ; drawpoints p ; drawpointlabels p ; +% p := p shifted (4cm,0) ; p := straightened p ; +% drawpath p ; drawpoints p ; drawpointlabels p ; +% p := p shifted (4cm,0) ; p := straightened p ; +% drawpath p ; drawpoints p ; drawpointlabels p ; + +% new + +path originpath ; originpath := origin -- cycle ; + +vardef unitvector primary z = + if abs z = abs origin : z else : z/abs z fi +enddef; + +% also new + +vardef anchored@#(expr p, z) = + p shifted (z + (labxf@#*lrcorner p + labyf@#*ulcorner p + + (1-labxf@#-labyf@#)*llcorner p)) +enddef ; + +% epsed(1.2345) + +vardef epsed (expr e) = + e if e>0 : + eps elseif e<0 : - eps fi +enddef ; + +% handy + +def withgray primary g = + withcolor (g,g,g) +enddef ; + +% for metafun + +if unknown darkred : color darkred ; darkred := .625(1,0,0) fi ; +if unknown darkyellow : color darkyellow ; darkyellow := .625(1,1,0) fi ; +if unknown darkgray : color darkgray ; darkgray := .625(1,1,1) fi ; +if unknown lightgray : color lightgray ; lightgray := .875(1,1,1) fi ; + +% an improved plain mp macro + +vardef center primary p = + if pair p : p else : .5[llcorner p, urcorner p] fi +enddef; + +% new, yet undocumented + +vardef rangepath (expr p, d, a) = + (if length p>0 : + (d*unitvector(direction 0 of p) rotated a) + shifted point 0 of p + -- p -- + (d*unitvector(direction length(p) of p) rotated a) + shifted point length(p) of p + else : + p + fi) +enddef ; + +% under construction + +vardef straightpath(expr a, b, method) = + if (method<1) or (method>6) : + (a--b) + elseif method = 1 : + (a -- + if xpart a > xpart b : + if ypart a > ypart b : + (xpart b,ypart a) -- + elseif ypart a < ypart b : + (xpart a,ypart b) -- + fi + elseif xpart a < xpart b : + if ypart a > ypart b : + (xpart a,ypart b) -- + elseif ypart a < ypart b : + (xpart b,ypart a) -- + fi + fi + b) + elseif method = 3 : + (a -- + if xpart a > xpart b : + (xpart b,ypart a) -- + elseif xpart a < xpart b : + (xpart a,ypart b) -- + fi + b) + elseif method = 5 : + (a -- + if ypart a > ypart b : + (xpart b,ypart a) -- + elseif ypart a < ypart b : + (xpart a,ypart b) -- + fi + b) + else : + (reverse straightpath(b,a,method-1)) + fi +enddef ; + +% handy for myself + +def addbackground text t = + begingroup ; save p, b ; picture p ; path b ; + b := boundingbox currentpicture ; + p := currentpicture ; currentpicture := nullpicture ; + fill b t ; setbounds currentpicture to b ; addto currentpicture also p ; + endgroup ; +enddef ; + +% makes a (line) into an infinite one (handy for calculating +% intersection points + +vardef infinite expr p = + (-infinity*unitvector(direction 0 of p) + shifted point 0 of p + -- p -- + +infinity*unitvector(direction length(p) of p) + shifted point length(p) of p) +enddef ; + +% obscure macros: create var from string and replace - and : +% (needed for process color id's) + +string _clean_ascii_[] ; + +def register_dirty_chars(expr str) = + for i = 0 upto length(str)-1 : + _clean_ascii_[ASCII substring(i,i+1) of str] := "_" ; + endfor ; +enddef ; + +register_dirty_chars("+-*/:;., ") ; + +vardef cleanstring (expr s) = + save ss ; string ss, si ; ss = "" ; save i ; + for i=0 upto length(s) : + si := substring(i,i+1) of s ; + ss := ss & if known _clean_ascii_[ASCII si] : _clean_ascii_[ASCII si] else : si fi ; + endfor ; + ss +enddef ; + +vardef asciistring (expr s) = + save ss ; string ss, si ; ss = "" ; save i ; + for i=0 upto length(s) : + si := substring(i,i+1) of s ; + if (ASCII si >= ASCII "0") and (ASCII si <= ASCII "9") : + ss := ss & char(scantokens(si) + ASCII "A") ; + else : + ss := ss & si ; + fi ; + endfor ; + ss +enddef ; + +vardef setunstringed (expr s, v) = + scantokens(cleanstring(s)) := v ; +enddef ; + +vardef setunstringed (expr s, v) = + scantokens(cleanstring(s)) := v ; +enddef ; + +vardef getunstringed (expr s) = + scantokens(cleanstring(s)) +enddef ; + +vardef unstringed (expr s) = + expandafter known scantokens(cleanstring(s)) +enddef ; + +% new + +vardef colorpart(expr i) = + (redpart i, greenpart i,bluepart i) +enddef ; + +% for david arnold: + +% showgrid(-5,10,1cm,-10,10,1cm); + +def showgrid (expr MinX, MaxX, DeltaX, MinY, MaxY, DeltaY)= + begingroup + save defaultfont, defaultscale, size ; + string defaultfont ; defaultfont := "cmtt10"; % i.e. infofont + numeric defaultscale ; defaultscale := 8pt / fontsize defaultfont; + numeric size ; size := 2pt ; + for x=MinX upto MaxX : + for y=MinY upto MaxY : + draw (x*DeltaX, y*DeltaY) + withpen pencircle scaled + if (x mod 5 = 0) and (y mod 5 = 0) : + 1.5size withcolor .50white + else : + size withcolor .75white + fi ; + endfor ; + endfor ; + for x=MinX upto MaxX: + label.bot(decimal x, (x*DeltaX,-size)); + endfor ; + for y=MinY upto MaxY: + label.lft(decimal y, (-size,y*DeltaY)) ; + endfor ; + endgroup +enddef; + +% new, handy for: +% +% \startuseMPgraphic{map}{n} +% \includeMPgraphic{map:germany} ; +% c_phantom (\MPvar{n}<1) ( +% fill map_germany withcolor \MPcolor{lightgray} ; +% draw map_germany withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% \includeMPgraphic{map:austria} ; +% c_phantom (\MPvar{n}<2) ( +% fill map_austria withcolor \MPcolor{lightgray} ; +% draw map_austria withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% c_phantom (\MPvar{n}<3) ( +% \includeMPgraphic{map:swiss} ; +% fill map_swiss withcolor \MPcolor{lightgray} ; +% draw map_swiss withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% c_phantom (\MPvar{n}<4) ( +% \includeMPgraphic{map:luxembourg} ; +% fill map_luxembourg withcolor \MPcolor{lightgray} ; +% draw map_luxembourg withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% \stopuseMPgraphic +% +% \useMPgraphic{map}{n=3} + +vardef phantom (text t) = + picture _p_ ; _p_ := image(t) ; addto _p_ also currentpicture ; + setbounds currentpicture to boundingbox _p_ ; +enddef ; + +vardef c_phantom (expr b) (text t) = + if b : + picture _p_ ; _p_ := image(t) ; addto _p_ also currentpicture ; + setbounds currentpicture to boundingbox _p_ ; + else : + t ; + fi ; +enddef ; + +% mark paths (for external progs to split) + +% def somepath(expr p) +% p +% enddef ; + +%D Handy: + +def break = + exitif true fi ; +enddef ; + +%D New too: + +primarydef p xstretched w = + (p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi) +enddef ; + +primarydef p ystretched h = + (p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi) +enddef ; + +primarydef p snapped s = + hide ( if path p : + forever : + exitif (bbheight(p) <= s) and (bbwidth(p) <= s) ; + p := p scaled (1/2) ; + endfor ; + elseif numeric p : + forever : + exitif p <= s ; + p := p scaled (1/2) ; + endfor ; + fi ; ) + p +enddef ; + +% done + +endinput ; diff --git a/metapost/context/base/mp-txts.mp b/metapost/context/base/mp-txts.mp new file mode 100644 index 000000000..f208c7149 --- /dev/null +++ b/metapost/context/base/mp-txts.mp @@ -0,0 +1,67 @@ +%D \module +%D [ file=mp-txts.mp, +%D version=2006.06.08, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=more text 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 licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_txts : endinput ; fi ; + +boolean context_txts ; context_txts := true ; + +%D The real code: + +string txtfile ; txtfile := "" ; +string txtfont ; txtfont := defaultfont ; +string txtpref ; txtpref := "00001::::" ; +numeric txtnext ; txtnext := 0 ; +numeric txtdepth ; txtdepth := 0 ; + +vardef nexttxt = + txtnext := txtnext + 1 ; + txtnext +enddef ; + +picture savedtxts[] ; +numeric depthtxts[] ; + +vardef zerofilled(expr fd) = + if fd<10: "0000" else : + if fd<100: "000" else : + if fd<1000: "00" else : + if fd<10000: "0" else : + fi fi fi fi & decimal fd +enddef; + +vardef savetxt(expr n,w,h,d) text t = + depthtxts[n] := d ; + savedtxts[n] := ((txtpref & zerofilled(n)) infont txtfont) xysized(w,h+d) t +enddef ; + +vardef sometxt(expr n) = + if known savedtxts[n] : + txtdepth := depthtxts[n] ; savedtxts[n] + else : + txtdepth := 0 ; nullpicture + fi +enddef ; + +def loadtxts = + if txtfile <> "" : + readfile(txtfile) ; + fi ; +enddef ; + +def StartTexts = + loadtxts ; +enddef ; + +def StopTexts = +enddef ; diff --git a/metapost/context/font/punkfont.mp b/metapost/context/font/punkfont.mp new file mode 100644 index 000000000..e57499859 --- /dev/null +++ b/metapost/context/font/punkfont.mp @@ -0,0 +1,863 @@ +% Remark: +% +% This file is a merge of the original punk files by Donald Knuth, who +% added this comment: +% +% Font inspired by Gerard and Marjan Unger's lectures, +% Feb 1985 +% +% The regular punk files are part of TeXLive and in metafont format. All +% errors introduced are ours. We also changed the encoding to unicode. In +% due time we might add a few more more characters. We still need to +% improve some of the metrics which involves a bit of trial and error. The +% font just covers basic latin shapes but in ConTeXt MkIV we add virtual +% composed shapes. There is a module m-punk.tex that implements this. This +% derivate is also used in mk.tex (mk.pdf) which is one of our tests for +% LuaTeX. We published an article on it in the MAPS (NTG magazine). +% +% 2008, Taco Hoekwater & Hans Hagen + +if unknown punk_font_loaded : + + if unknown scale_factor : + scale_factor := 1 ; + fi ; + + boolean punk_font_loaded ; + + punk_font_loaded := true ; + warningcheck := 0 ; + designsize := 10pt#; + font_identifier := "Punk Nova" ; % dedicated to Don Knuth and Hermann Zapf + + ht# := 7pt# ; % height of characters + u# := 1/4pt# ; % unit width + % s# := 1.2pt# ; % extra sidebar + % s# := 0.1pt# ; % extra sidebar, needed because we use the bbox currently + s# := 0 ; % extra sidebar, ok +% s# := 1.2pt# ; % extra sidebar + px# := .6pt# ; % horizontal thickness of pen + py# := .5pt# ; % vertical thickness of pen + dot# := 1.3pt# ; % diameter of dots + dev# := .3pt# ; % standard deviation of punk points + + % dot# := .8pt# ; % diameter of dots + % px# := .3pt# ; % horizontal thickness of pen + % py# := .2pt# ; % vertical thickness of pen + + % seed := sqrt2 ; + % randomseed := seed ; + proofing := 0 ; + pt := .1pt ; + mag := scale_factor * 10 ; + bp_per_pixel := bpppix_ * mag ; + + define_pixels(u,dev) ; + define_blacker_pixels(px,py,dot) ; + define_whole_pixels(s) ; + xoffset := s ; + + pickup pencircle xscaled px yscaled py ; + punk_pen := savepen ; + pickup pencircle scaled dot ; + path dot_pen_path ; + dot_pen_path := tensepath makepath currentpen ; + +% px# := .8pt# ; % horizontal thickness of pen +% define_pixels(u,dev) ; +% define_blacker_pixels(px,py,dot) ; +% pickup pencircle xscaled 1.25px yscaled 1.25py ; +% punk_pen := savepen ; +% pickup pencircle scaled 1.25dot ; +% path dot_pen_path ; +% dot_pen_path := tensepath makepath currentpen ; + + defaultcolormodel := 1 ; + + def beginpunkchar(expr c,n,h,v) = % code $c$; width is $n$ units + hdev := h * dev ; % modify horizontal amounts of deviation + vdev := v * dev ; % modify vertical amounts of deviation + beginchar(c,n*u#,ht#,0) ; + italcorr 0 ; + % italcorr ht#*slant; + pickup punk_pen + enddef ; + +% extra_endchar := extra_endchar & "w := w+2s ; charwd := charwd+2s# ;" ; +% extra_endchar := extra_endchar & "setbounds currentpicture to (0,-d)--(w*1.2,-d)--(w*1.2,h)--(0,h)--cycle;" ; + +% extra_endchar := extra_endchar & "w := w+2s ; " ; +% extra_endchar := extra_endchar & "w := 1.2w ; " ; +% extra_endchar := extra_endchar & "charwd := 1.2charwd ; " ; +% extra_endchar := extra_endchar & "setbounds currentpicture to (0,-d)--(w,-d)--(w,h)--(0,h)--cycle;" ; + +% todo: + +% extra_endchar := extra_endchar & +% "currentpicture := currentpicture shifted (0,1pt#) ; setbounds currentpicture to " & +% "llcorner currentpicture shifted ( 0,-1pt#) -- lrcorner currentpicture shifted ( 1pt#,-1pt#) -- " & +% "urcorner currentpicture shifted ( 1pt#, 1pt#) -- ulcorner currentpicture shifted ( 0, 1pt#) -- cycle ; " ; + + def ^ = + transformed currenttransform + enddef ; + + def makebox(text rule) = + for y=0, h : % horizontals + rule((-s,y)^,(w-s,y)^) ; + endfor + for x=-s, 0, w-2s, w-s : % verticals + rule((x,0)^,(x,h)^) ; + endfor + enddef ; + + rulepen := pensquare ; + + vardef pp expr z = + z + (hdev * normaldeviate, vdev * normaldeviate) + enddef; + + def pd expr z = % {\bf drawdot} + addto currentpicture contour dot_pen_path shifted z.t_ withpen penspeck + enddef; + + def initialize_punk_upper = + ht# := 7pt# ; dev# := .3pt# ; + enddef ; + def initialize_punk_lower = + sht# := ht#; sdev := dev; + ht# := .6ht# ; dev := .7dev ; + enddef ; + def revert_punk_lower = + ht# := sht#; dev := sdev; + enddef ; + +fi ; + + +initialize_punk_upper ; + +beginpunkchar("A",13,1,2); +z1=pp(1.5u,0); z2=(.5w,1.1h); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % left and right diagonals +z4=pp .3[z1,z2]; z5=pp .3[z3,z2]; pd z4; pd z5; draw z4--z5; % crossbar +endchar; + +beginpunkchar("B",12,1,1); +z1=pp(2u,0); z2=pp(2u,.6h); z3=pp(2u,h); pd z1; pd z3; draw z1--z3; % stem +z1.5=pp(w-u,.5y2); z2.5=pp(w-u,.5[y2,y3]); draw z2--z2.5--z3; % upper lobe +draw flex(z2,z1.5,z1); % lower lobe +endchar; + +beginpunkchar("C",13,1,2); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=(.6w,0); z5=(w-2u,.2h); +pd z1; pd z5; draw z1..z2..z3..z4..z5; % arc +endchar; + +beginpunkchar("D",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6h); +pd z1; pd z2; draw flex(z1,z3,z2); % lobe +draw z1--z2; % stem +endchar; + +beginpunkchar("E",12,.5,1); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2.5u,h); z4=pp(w-2u,0); +pd z3; pd z4; draw z4--z1--z2--z3; % stem and arms +z5=pp(2u,.6h); z6=pp(w-3u,.6h); pd z5; pd z6; draw z5--z6; % crossbar +endchar; + +beginpunkchar("F",12,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,h); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +z5=pp(2u,.6h); z6=pp(w-3u,.6h); z4=pp .5[z5,z6]-(0,.1h); +pd z5; pd z6; draw flex (z5,z4,z6); % crossbar +endchar; + +beginpunkchar("G",13,.5,.5); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=pp(.6w,0); z5=(w-2u,0); +pd z1; draw z1..z2..z3..z4---z5; % arc +z6=pp(.5[u,x5],.4h); pd z6; pd z5; draw z6--(pp(x5,y6))--z5; % spur +endchar; + +beginpunkchar("H",14,1,.5); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +z5=pp(2u,.6h); z6=pp(w-2u,.6h); +pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems +pd z5; draw z5--z6; % crossbar +endchar; + +beginpunkchar("I",5,1,2); +z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); +pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem +endchar; + +beginpunkchar("J",9,1,2); +z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); +pd z1; pd z3; draw z1--z2--z3; % arc +endchar; + +beginpunkchar("K",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(2u,1/3h); z4=pp(w-1.5u,h); +pd z1; pd z2; draw z1--z2; % stem +pd z3; pd z4; draw z3--z4; % upper diagonal +z6=pp(w-u,0); z5=1/3[z3,z4]; +pd z6; draw flex(z5,.8[z1,2/3[z5,z6] ],z6);% lower diagonal +endchar; + +beginpunkchar("L",11,1,2); +z1=pp(2u,h); z2=pp(2u,0); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +endchar; + +beginpunkchar("M",17,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(.5w,0); z4=pp(w-2u,h); z5=pp(w-2u,0); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % stems and diagonals +endchar; + +beginpunkchar("N",13,.75,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +pd z1; pd z4; draw z1--z2--z3--z4; % stems and diagonals +endchar; + +beginpunkchar("O",12,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{left}..z2..z3..z4..z1; % bowl +endchar; + +beginpunkchar("P",13,1,2); +z1=pp(2u,0); z2=pp(2u,1.1h); z3=pp(2u,.5h); z4=pp(w,.6[y3,y2]); +pd z1; pd z3; draw z1--z2--z4--z3; % stem and bowl +endchar; + +beginpunkchar("Q",14,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl +z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h); +pd z5; pd z6; draw z5--z7--z6; % tail +endchar; + +beginpunkchar("R",16,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0); +pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal +endchar; + +beginpunkchar("S",11,.3,1); +z1=pp(w-2u,.9h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.6[z6,z2]; +z5=pp(w-u,.35h); z6=pp(.5w,u); z7=pp(u,.2h); +pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % stroke +endchar; + +beginpunkchar("T",13,.75,2); +z1=pp(u,h); z2=pp(w-u,h); z3=pp(.5w,0); +pd z1; pd z2; pd z3; draw z1--z2; % arms +draw .5[z1,z2]--z3; % stem +endchar; + +beginpunkchar("U",13,.3,2); +z1=pp(2u,h); z2=pp(2u,.2h); z3=pp(.5w,0); z4=pp(w-2u,.2h); z5=pp(w-2u,h); +pd z1; pd z5; draw z1---z2...z3{z4-z2}...z4---z5; % stroke +endchar; + +beginpunkchar("V",13,1,2); +z1=pp(1.5u,h); z2=pp(.5w,0); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar("W",18,1,2); +z1=pp(1.5u,h); z2=pp(.5[x1,x3],0); z3=pp(.5w,.8h); z4=pp(.5[x3,x5],0); +z5=pp(w-1.5u,h); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % diagonals +endchar; + +beginpunkchar("X",13,1,1); +z1=pp(1.5u,h); z2=pp(w-1.5u,0); z3=pp(1.5u,0); z4=pp(w-2.5u,h); +pd z1; pd z2; draw z1--z2; % main diagonal +pd z3; pd z4; draw z3--z4; % cross diagonal +endchar; + +beginpunkchar("Y",13,1,2); +z1=pp(1.5u,h); z2=pp(w-1.5u,h); z3=pp(.5w,.5h); z4=pp(.5w,0); +pd z1; pd z2; pd z4; draw z1--z3--z4; % stem and left diagonal +draw z2--z3; % right diagonal +endchar; + +beginpunkchar("Z",11,1,2); +z1=pp(1.5u,h); z2=pp(w-2.5u,h); z3=pp(1.5u,0); z4=pp(w-1.5u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % diagonals +endchar; + +beginpunkchar(198,16,1,2); % \AE +z1=pp(1.5u,0); z2=pp(.6w,h); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % left diagonal and upper arm +z4=pp .3[z1,z2]; z5=pp(.6w,0); z6=pp(w-2u,.3h); +pd z4; pd z6; draw z4--z6; % crossbar +z7=pp(w-u,0); pd z2; pd z7; draw z2--z5--z7; % stem and lower arm +endchar; + +beginpunkchar(338,18,1,2); % \OE +z1=pp(.5w,h); z2=pp(u,.4h); z3=pp(.5w,0); +pd z1; draw z1..z2..{right}z3; % bowl +z4=pp(w-1.5u,h); z5=pp(w-2u,.4h); z6=pp(w-u,0); +pd z4; pd z6; draw z4--z1--z3--z6; % arms and stem +pd z5; draw z5--.4[z3,z1]; % crossbar +endchar; + +beginpunkchar(216,14,1,1); % \O +z1=pp(.5w,h); z2=pp(u,.5h); z3=pp(.5w,0); z4=pp(w-u,.5h); +z5=pp(w-2u,1.1h); z6=pp(2u,-.1h); +pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % bowl and diagonal +endchar; + +beginpunkchar(915,11,1,2); % $\Gamma$ +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +endchar; + +beginpunkchar(916,15,1,2); % $\Delta$ +z1=pp(u,0); z2=pp(.5w,h); z3=pp(w-u,0); +pd z1; draw z1--z2..tension 5..z3..tension 5..z1; % triangle +endchar; + +beginpunkchar(920,15,.5,2); % $\Theta$ +z1=pp(.5w,h); z2=pp(u,.6h); z3=pp(.5w,0); z4=pp(w-u,.6h); +pd z1; draw z1..tension.8..z2..z3..z4..tension.8..z1; % bowl +z5=pp(x2+2u,.4h); z6=pp(x4-2u,.4h); pd z5; pd z6; draw z5--z6; % bar +endchar; + +beginpunkchar(923,12,1,2); % $\Lambda$ +z1=pp(u,0); z2=pp(.5w,h); z3=pp(w-u,0); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(926,12,1,1); % $\Xi$ +z1=pp(u,h); z2=pp(w-u,h); pd z1; pd z2; draw z1--z2; % upper arm +z3=pp(2u,.55h); z4=pp(w-2u,.55h); pd z3; pd z4; draw z3--z4; % bar +z5=pp(u,0); z6=pp(w-u,0); pd z5; pd z6; draw z5--z6; % lower arm +endchar; + +beginpunkchar(928,13,1,.5); % $\Pi$ +z1=pp(1.5u,0); z2=pp(1.5u,h); z3=pp(w-1.5u,h); z4=pp(w-1.5u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % stems and bar +endchar; + +beginpunkchar(931,13,1,1); % $\Sigma$ +z1=pp(w-u,h); z2=pp(u,h); z3=pp(.5w-u,.5h); z4=pp(u,0); z5=pp(w-u,0); +pd z1; pd z5; draw z1--z2{.5[z4,z5]-z2}..z3--z4--z5; % arms and diagonals +endchar; + +beginpunkchar(933,15,1,.5); % $\Upsilon$ +z1=pp(u,.8h); z2=pp(.3w,h); z3=pp(.5w,.5h); z4=pp(.5w,0); +pd z1; pd z4; draw z1..z2..tension2..z3---z4; % left arc and stem +z5=pp(w-u,.8h); z6=pp(.7w,h); +pd z5; draw z5..z6..tension2..{z4-z3}z3; % right arc +endchar; + +beginpunkchar(934,13,1,2); % $\Phi$ +z1=pp(.5w,h); z2=pp(.5w,0); pd z1; pd z2; draw z1--z2; % stem +z3=pp(.5w,2/3h); z4=pp(u,.5h); z5=pp(.5w,1/4h); z6=pp(w-u,.5h); +pd z3; draw z3..z4..z5..z6..z3; % bowl +endchar; + +beginpunkchar(936,14,1,1); % $\Psi$ +z1=pp(.5w,h); z2=pp(.5w,0); pd z1; pd z2; draw z1--z2; % stem +z3=pp(u,.8h); z4=pp(.5w,.2h); z5=pp(w-u,.8h); +pd z3; pd z5; draw z3{.4[z1,z2]-z3}..z4{right}..{z5-.4[z1,z2]}z5; % stroke +endchar; + +beginpunkchar(937,13,1,2); % $\Omega$ +z1=pp(u,0); z2=pp(1/3w,0); z3=pp(u,2/3h); z4=pp(.5w,h); +z5=pp(w-u,2/3h); z6=pp(2/3w,0); z7=pp(w-u,0); +pd z1; pd z7; draw z1--z2{up}..z3..z4..z5..{down}z6--z7; % bowl and arms +endchar; + +beginpunkchar(".",5,1,2); +pd pp(.5w,0); % dot +endchar; + +beginpunkchar(",",5,.5,.5); +z1=pp(.5w,0); z2=pp(w-u,-.1h); z3=pp(.5w,-.3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(":",5,1,.5); +pd pp(.5w,0); pd pp(.5w,.4h); % dots +endchar; + +beginpunkchar(";",5,.5,.5); +z1=pp(.5w,0); z2=pp(w-u,-.1h); z3=pp(.5w,-.3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +pd pp(.5w,.4h); % dot +endchar; + +beginpunkchar("!",5,.5,.5); +pd pp(.5w,0); % dot +z1=pp(.5w,1.05h); z2=pp(.5w,.3h); pd z1; pd z2; draw z1--z2; % stem +endchar; + +beginpunkchar(161,5,.5,.5); % spanish inverted ! +pd pp(.5w,.9h); % dot +z1=pp(.5w,-.1h); z2=pp(.5w,.6h); pd z1; pd z2; draw z1--z2; % stem +endchar; + +beginpunkchar("?",9,1,.5); +z1=pp(1.5u,.8h); z2=pp(.5w,h); z3=pp(w-u,.8h); z4=pp(.5w,.3h); +pd z1; pd z4; draw z1..z2..z3..{down}z4; % arc and stem +pd pp(.5w,0); % dot +endchar; + +beginpunkchar(191,9,1,.5); % spanish inverted ? +z1=pp(1.5u,.1h); z2=pp(.5w,-.1h); z3=pp(w-u,.1h); z4=pp(.5w,.6h); +pd z1; pd z4; draw z1..z2..z3..{up}z4; % arc and stem +pd pp(.5w,.9h); % dot +endchar; + +beginpunkchar("&",14,.5,.5); +z1=pp(w-2u,h); z2=pp(u,h); z3=pp(3u,0); z5=pp(w-u,.6h); z6=pp(w-2u,0); +pd z1; pd z5; draw z1--z2--z3--z5; % arms and stem +draw z1--.5[z2,z3]; pd z6; draw z6--.6[z3,z5]; % diagonals +endchar; + +beginpunkchar("$",12,.5,.5); +z1=pp(w-1.5u,.7h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.5[z3,z5]; +z5=pp(w-u,.3h); z6=pp(.5w,0); z7=pp(u,.3h); +pd z1; pd z7; draw z1..z2..z3..z4..z5..z6..z7; % stroke +z8=z2+(0,.1h); pd z8; draw z8--z6; % stem +endchar; + +beginpunkchar("%",18,.5,.5); +z1=pp(3.5u,1.1h); z2=pp(u,.8h); z3=pp(3.5u,.5h); z4=pp(6u,.8h); +z5=pp(w-3.5u,.5h); z6=pp(w-6u,.2h); z7=pp(w-3.5u,-.1h); z8=pp(w-u,.2h); +pd z1; draw z1..z2..z3..z4..z1; % upper bowl +pd z5; draw z5..z6..z7..z8..z5; % lower bowl +z9=pp(w-3u,1.1h); z0=pp(3u,-.1h); pd z0; draw z9--z0; % diagonal +draw z1{z5-z1}..z9; % link +endchar; + +beginpunkchar("@",18,1,.5); +z1=pp(2u,0); z2=pp(1/3w,.7h); z3=pp(w-6u,0); +z4=pp(w,.3h); z5=pp(1/3w,h); z6=pp(u,.5h); z7=.7[z2,z3]; +pd z1; pd z7; draw z1--z2--z3{right}..z4..z5..z6..z7; % diagonals and stroke +endchar; + +beginpunkchar("-",7,.5,.5); +z1=pp(u,.4h); z2=pp(w-u,.5h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar(8211,9,.5,.5); % -- +z1=pp(0,.5h); z2=pp(w,.4h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar(8212,18,.5,.5); % --- +z1=pp(0,.5h); z2=pp(w,.4h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar("+",9,.5,1); +z1=pp(0,.5h); z2=pp(w,.5h); pd z1; pd z2; draw z1--z2; % bar +z3=pp(.5w,.1h); z4=pp(.5w,.9h); pd z3; pd z4; draw z3--z4; % stem +endchar; + +beginpunkchar("*",13,.5,1); +z0=pp(.5w,1.1h); z1=pp(u,.9h); z2=pp(2u,.3h); z3=pp(w-u,.3h); z4=pp(w-u,.9h); +pd z0; draw z0--z2..1/3[.5[z2,z4],z0]..z4--z1--z3--z0; % star +endchar; + +beginpunkchar(39,5,.5,1.5); % ' apostrofe HH/TH (to be checked) +z1=pp(w/2,h); z2=pp(w/2+u,.85h); z3=pp(w/2,2/3h); +pd z1; pd z3; draw z1..z2..z3; % stroke +endchar; + +beginpunkchar(34,9,1,1.5); % " HH/TH (to be checked) +z1=pp(1.5u,h); z2=pp(1.5u,.6h); z3=pp(w-1.5u,h); z4=pp(w-1.5u,.6h); +pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw z3--z4; +endchar; + +beginpunkchar(8216,5,.3,.5); % ` +z1=pp(w-1.5u,h); z2=pp(u,.85h); z3=pp(w-u,2/3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(8217,5,.3,.5); % ' +z1=pp(1.5u,h); z2=pp(w-u,.85h); z3=pp(u,2/3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(8220,9,.3,.5); % `` quotedblleft +z1=pp(.5w+.5u,h); z2=pp(w-u,.6h); z3=pp(u,.95h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(8221,9,.3,.5); % '' quotedblright +z1=pp(.5w-.5u,h); z2=pp(u,.6h); z3=pp(w-u,.95h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar("(",7,.5,.5); +z1=pp(w-u,h); z2=pp(u,.5h); z3=pp(w-u,0); +pd z1; pd z3; draw z1..z2..z3; % stroke +endchar; + +beginpunkchar(")",7,.5,.5); +z1=pp(u,h); z2=pp(w-u,.5h); z3=pp(u,0); pd z1; pd z3; draw z1..z2..z3; % stroke +endchar; + +beginpunkchar("[",8,.5,.5); +z1=pp(w-u,h); z2=pp(.5w,h); z3=pp(.5w,0); z4=pp(w-u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % bars and stem +endchar; + +beginpunkchar("]",8,.5,.5); +z1=pp(u,h); z2=pp(.5w,h); z3=pp(.5w,0); z4=pp(u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % bars and stem +endchar; + +beginpunkchar("<",9,.5,.5); +z1=pp(w-u,.9h); z2=pp(u,.5h); z3=pp(w-u,.1h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(">",9,.5,.5); +z1=pp(u,.9h); z2=pp(w-u,.5h); z3=pp(u,.1h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar("{",10,.5,.5); % HH/TH +z1=pp(w-2u,h); z3=pp(2u,.5h); z5=pp(w-2u,0); +z2=pp(w-4u,.6h); z4=(w-4u,.4h); +pd z1; pd z3; pd z5; draw z1{left}..z2--z3 & z3--z4..{right}z5; +endchar; + +beginpunkchar("}",10,.5,.5); % HH/TH +z1=pp(2u,h); z3=pp(w-2u,.5h); z5=pp(2u,0); +z2=pp(4u,.6h); z4=(4u,.4h); +pd z1; pd z3; pd z5; draw z1{right}..z2--z3 & z3--z4..{left}z5; +endchar; + +beginpunkchar("=",9,.5,.5); +z5=pp(u,2/3h); z6=pp(w-u,2/3h); pd z5; pd z6; draw z5--z6; % upper bar +z7=pp(u,1/3h); z8=pp(w-u,1/3h); pd z7; pd z8; draw z7--z8; % lower bar +endchar; + +beginpunkchar("#",15,.5,.5); +z1=pp(.5w,h); z2=pp(3u,0); z3=pp(w-3u,h); z4=pp(.5w,0); +pd z2; pd z3; draw z3--z1--z2; draw z3--z4--z2; % diagonals (linked) +z5=pp(u,2/3h); z6=pp(w-u,2/3h); pd z5; pd z6; draw z5--z6; % upper bar +z7=pp(u,1/3h); z8=pp(w-u,1/3h); pd z7; pd z8; draw z7--z8; % lower bar +endchar; + +beginpunkchar("/",9,1,1); +z1=pp(1.5u,-.05h); z2=pp(w-1.5u,1.05h); pd z1; pd z2; draw z1--z2; % diagonal +endchar; + +beginpunkchar("\",9,1,1); % HH/TH +z1=pp(1.5u,1.05h); z2=pp(w-1.5u,-.05h); pd z1; pd z2; draw z1--z2; % reverse diagonal +endchar; + + +beginpunkchar("0",9,.5,1); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl +endchar; + +beginpunkchar("1",9,.3,1); +z1=pp(2u,.7h); z2=pp(.6w,h); z3=pp(.6w,0); +pd z1; pd z3; draw z1--z2--z3; % serif and stem +endchar; + +beginpunkchar("2",9,1,1); +z1=pp(2u,.7h); z2=pp(.5w,h); z3=pp(w-u,.6h); z4=pp(u,0); z5=pp(w-2u,0); +pd z1; pd z5; draw z1..z2..z3..z4--z5; % stroke +endchar; + +beginpunkchar("3",9,.5,.5); +z1=pp(2u,.7h); z2=pp(.5w,h); z3=pp(w-u,.5[y2,y4]); +z4=pp(.5w-u,.55h); z5=pp(w-u,.5[y4,y6]); z6=pp(.5w,0); z7=pp(1.5u,.2h); +pd z1; pd z7; draw z1..z2..z3..z4&z4..z5..z6..z7; % arcs +endchar; + +beginpunkchar("4",9,1,1); +z1=pp(w-u,.3h); z2=pp(u,.3h); z3=pp(2/3w,h); z4=pp(2/3w,0); +pd z1; pd z4; draw z1--z2--z3--z4; % stem and diagonals +endchar; + +beginpunkchar("5",9,.5,.5); +z1=pp(w-2u,h); z2=pp(2u,h); z3=pp(u,.7h); z4=pp(w-u,.5[y3,y5]); +z5=pp(.5w,0); z6=pp(u,.2h); +pd z1; pd z6; draw z1--z2--z3..z4..z5..z6; % stroke +endchar; + +beginpunkchar("6",9,1,1); +z1=pp(2/3w,h); z2=pp(u,.3h); z3=pp(.5w,0); z4=pp(w-u,.3h); z5=pp(.6w,.6h); +z6=pp z2; pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % stroke +endchar; + +beginpunkchar("7",9,.5,1); +z1=pp(2u,h); z2=pp(w-.5u,h); z3=pp(.4w,0); +pd z1; pd z3; draw z1--z2&z2..z3{down}; % stroke +endchar; + +beginpunkchar("8",9,.5,.5); +z1=pp(.5w,h); z2=pp(u,.5[y1,y3]); z3=pp(.5w,.6h); z4=pp(w-u,.5[y3,y5]); +z5=pp(.5w,0); z6=pp(u,.5[y5,y3]); z7=pp(w-u,.5[y1,y3]); +pd z1; draw z1{curl 8}..z2..z3..z4..z5..z6..z3..z7..z1; % stroke +endchar; + +beginpunkchar("9",9,1,1); +z1=pp(1/3w,0); z2=pp(w-u,.7h); z3=pp(.5w,h); z4=pp(u,.7h); z5=pp(.5w,.4h); +pd z1; pd z5; draw z1..z2..z3..z4..z5; % stroke +endchar; + +beginpunkchar(96,9,1,1); % \`{} grave +z1=pp(2.5u,h); z2=pp(.6w,.8h); pd z1; pd z2; draw z1--z2; % diagonal +endchar; + +beginpunkchar(180,9,1,1); % \'{} acute +z1=pp(w-2.5u,h); z2=pp(.4w,.8h); pd z1; pd z2; draw z1--z2; % diagonal +endchar; + +beginpunkchar(710,13,1,1); % \^{} circumflex +z1=pp(2.5u,.8h); z2=pp(.5w,h); z3=(w-2.5u,.8h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(711,13,1,1); % \v{} caron +z1=pp(2.5u,.9h); z2=pp(.5w,.7h); z3=pp(w-2.5u,.9h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(728,11,1,1); % \u{} breve +z1=pp(2u,h); z2=pp(.5w,.75h); z3=pp(w-2u,h); +pd z1; pd z3; draw flex(z1,z2,z3); % stroke +endchar; + +beginpunkchar(175,12,1,1); % \={} macron +z1=pp(u,.8h); z2=pp(w-u,.8h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar(729,5,1,1); % \.{} +pd pp(.5w,.9h); % dot +endchar; + +beginpunkchar(168,13,1,1); % \"{} diaeresis +pd pp(1/5w,.9h); pd pp(4/5w,.9h); % dots +endchar; + +beginpunkchar(732,13,1,1); % \~{} tilde +z1=pp(u,.75h); z2=pp(w-u,.9h); pd z1; pd z2; draw z1{up}..{up}z2; % stroke +endchar; + +beginpunkchar(733,13,1,1); % \H{} hungarumlaut +z1=pp(4u,h); z2=pp(2.5u,.7h); z3=pp(w-2u,h); z4=pp(w-3.5u,.7h); +pd z1; pd z3; draw z1--z2--z4--z3; % diagonals (linked) +endchar; + +beginpunkchar(730,13,0,0); % Scandinavian loop, for \AA\ and \aa (ring) +z0=(.5w,.66h); % point $z^2$ of lowercase A +z1=(.5w,.9h); draw z0{z0-(1.5u,0)}..z1..{(w-1.5u,0)-z0}z0; % loop +endchar; + +beginpunkchar(184,13,.5,.5); % Cedilla, for \c c +z1=(.6w,0); z2=pp(.6w,-.1h); z3=pp(2.5u,-.1h); +pd z3; draw z1--z2--z3; % stroke +endchar; + +initialize_punk_lower ; + +beginpunkchar(305,5,1,2); % dotless I +z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); +pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem +endchar; + +beginpunkchar(567,9,1,2); % dotless J +z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); +pd z1; pd z3; draw z1--z2--z3; % arc +endchar; + +beginpunkchar(223,18,.3,1); % German SS +z1=pp(.5w-u,.9h); z2=pp(1/3w,h); z3=pp(u,.7h); z4=.6[z6,z2]; +z5=pp(.5w,.35h); z6=pp(1/3w,u); z7=pp(u,.2h); +pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % left stroke +for i=1 upto 7: z[i+10]=pp(z[i] shifted (.5w-u,0)); endfor +pd z11; pd z17; draw z11--z12...z13..z14..z15...z16--z17; % right stroke +endchar; + +beginpunkchar("a",13,1,2); +z1=pp(1.5u,0); z2=(.5w,1.1h); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % left and right diagonals +z4=pp .3[z1,z2]; z5=pp .3[z3,z2]; pd z4; pd z5; draw z4--z5; % crossbar +endchar; + +beginpunkchar("b",12,1,1); +z1=pp(2u,0); z2=pp(2u,.6h); z3=pp(2u,h); pd z1; pd z3; draw z1--z3; % stem +z1.5=pp(w-u,.5y2); z2.5=pp(w-u,.5[y2,y3]); draw z2--z2.5--z3; % upper lobe +draw flex(z2,z1.5,z1); % lower lobe +endchar; + +beginpunkchar("c",13,1,2); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=(.6w,0); z5=(w-2u,.2h); +pd z1; pd z5; draw z1..z2..z3..z4..z5; % arc +endchar; + +beginpunkchar("d",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6h); +pd z1; pd z2; draw flex(z1,z3,z2); % lobe +draw z1--z2; % stem +endchar; + +beginpunkchar("e",12,.5,1); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2.5u,h); z4=pp(w-2u,0); +pd z3; pd z4; draw z4--z1--z2--z3; % stem and arms +z5=pp(2u,.6h); z6=pp(w-3u,.6h); pd z5; pd z6; draw z5--z6; % crossbar +endchar; + +beginpunkchar("f",12,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,h); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +z5=pp(2u,.6h); z6=pp(w-3u,.6h); z4=pp .5[z5,z6]-(0,.1h); +pd z5; pd z6; draw flex (z5,z4,z6); % crossbar +endchar; + +beginpunkchar("g",13,.5,.5); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=pp(.6w,0); z5=(w-2u,0); +pd z1; draw z1..z2..z3..z4---z5; % arc +z6=pp(.5[u,x5],.4h); pd z6; pd z5; draw z6--(pp(x5,y6))--z5; % spur +endchar; + +beginpunkchar("h",14,1,.5); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +z5=pp(2u,.6h); z6=pp(w-2u,.6h); +pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems +pd z5; draw z5--z6; % crossbar +endchar; + +beginpunkchar("i",5,1,2); +z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); +pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem +endchar; + +beginpunkchar("j",9,1,2); +z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); +pd z1; pd z3; draw z1--z2--z3; % arc +endchar; + +beginpunkchar("k",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(2u,1/3h); z4=pp(w-1.5u,h); +pd z1; pd z2; draw z1--z2; % stem +pd z3; pd z4; draw z3--z4; % upper diagonal +z6=pp(w-u,0); z5=1/3[z3,z4]; +pd z6; draw flex(z5,.8[z1,2/3[z5,z6] ],z6);% lower diagonal +endchar; + +beginpunkchar("l",11,1,2); +z1=pp(2u,h); z2=pp(2u,0); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +endchar; + +beginpunkchar("m",17,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(.5w,0); z4=pp(w-2u,h); z5=pp(w-2u,0); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % stems and diagonals +endchar; + +beginpunkchar("n",13,.75,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +pd z1; pd z4; draw z1--z2--z3--z4; % stems and diagonals +endchar; + +beginpunkchar("o",12,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{left}..z2..z3..z4..z1; % bowl +endchar; + +beginpunkchar("p",13,1,2); +z1=pp(2u,0); z2=pp(2u,1.1h); z3=pp(2u,.5h); z4=pp(w,.6[y3,y2]); +pd z1; pd z3; draw z1--z2--z4--z3; % stem and bowl +endchar; + +beginpunkchar("q",14,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl +z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h); +pd z5; pd z6; draw z5--z7--z6; % tail +endchar; + +beginpunkchar("r",16,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0); +pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal +endchar; + +beginpunkchar("s",11,.3,1); +z1=pp(w-2u,.9h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.6[z6,z2]; +z5=pp(w-u,.35h); z6=pp(.5w,u); z7=pp(u,.2h); +pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % stroke +endchar; + +beginpunkchar("t",13,.75,2); +z1=pp(u,h); z2=pp(w-u,h); z3=pp(.5w,0); +pd z1; pd z2; pd z3; draw z1--z2; % arms +draw .5[z1,z2]--z3; % stem +endchar; + +beginpunkchar("u",13,.3,2); +z1=pp(2u,h); z2=pp(2u,.2h); z3=pp(.5w,0); z4=pp(w-2u,.2h); z5=pp(w-2u,h); +pd z1; pd z5; draw z1---z2...z3{z4-z2}...z4---z5; % stroke +endchar; + +beginpunkchar("v",13,1,2); +z1=pp(1.5u,h); z2=pp(.5w,0); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar("w",18,1,2); +z1=pp(1.5u,h); z2=pp(.5[x1,x3],0); z3=pp(.5w,.8h); z4=pp(.5[x3,x5],0); +z5=pp(w-1.5u,h); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % diagonals +endchar; + +beginpunkchar("x",13,1,1); +z1=pp(1.5u,h); z2=pp(w-1.5u,0); z3=pp(1.5u,0); z4=pp(w-2.5u,h); +pd z1; pd z2; draw z1--z2; % main diagonal +pd z3; pd z4; draw z3--z4; % cross diagonal +endchar; + +beginpunkchar("y",13,1,2); +z1=pp(1.5u,h); z2=pp(w-1.5u,h); z3=pp(.5w,.5h); z4=pp(.5w,0); +pd z1; pd z2; pd z4; draw z1--z3--z4; % stem and left diagonal +draw z2--z3; % right diagonal +endchar; + +beginpunkchar("z",11,1,2); +z1=pp(1.5u,h); z2=pp(w-2.5u,h); z3=pp(1.5u,0); z4=pp(w-1.5u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % diagonals +endchar; + +beginpunkchar(230,16,1,2); % \ae +z1=pp(1.5u,0); z2=pp(.6w,h); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % left diagonal and upper arm +z4=pp .3[z1,z2]; z5=pp(.6w,0); z6=pp(w-2u,.3h); +pd z4; pd z6; draw z4--z6; % crossbar +z7=pp(w-u,0); pd z2; pd z7; draw z2--z5--z7; % stem and lower arm +endchar; + +beginpunkchar(339,18,1,2); % \oe +z1=pp(.5w,h); z2=pp(u,.4h); z3=pp(.5w,0); +pd z1; draw z1..z2..{right}z3; % bowl +z4=pp(w-1.5u,h); z5=pp(w-2u,.4h); z6=pp(w-u,0); +pd z4; pd z6; draw z4--z1--z3--z6; % arms and stem +pd z5; draw z5--.4[z3,z1]; % crossbar +endchar; + +beginpunkchar(248,14,1,1); % \o +z1=pp(.5w,h); z2=pp(u,.5h); z3=pp(.5w,0); z4=pp(w-u,.5h); +z5=pp(w-2u,1.1h); z6=pp(2u,-.1h); +pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % bowl and diagonal +endchar; + +revert_punk_lower; + +beginpunkchar("_",12,.5,.5); % _ +z1=pp(0,-.2h); z2=pp(w,-.2h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar("^",12,1,.5); % +z1=pp(.5w,h); z2=pp(1.5u,.6h); z3=pp(w-1.5u,.6h); +pd z2; pd z3; draw z2--z1--z3; +endchar; diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua new file mode 100644 index 000000000..1d87322c1 --- /dev/null +++ b/scripts/context/lua/luatools.lua @@ -0,0 +1,8185 @@ +#!/usr/bin/env texlua + +if not modules then modules = { } end modules ['luatools'] = { + version = 1.001, + comment = "companion to context.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +-- one can make a stub: +-- +-- #!/bin/sh +-- env LUATEXDIR=/....../texmf/scripts/context/lua texlua luatools.lua "$@" + +-- Although this script is part of the ConTeXt distribution it is +-- relatively indepent of ConTeXt. The same is true for some of +-- the luat files. We may may make them even less dependent in +-- the future. As long as Luatex is under development the +-- interfaces and names of functions may change. + +-- For the sake of independence we optionally can merge the library +-- code here. It's too much code, but that does not harm. Much of the +-- library code is used elsewhere. We don't want dependencies on +-- Lua library paths simply because these scripts are located in the +-- texmf tree and not in some Lua path. Normally this merge is not +-- needed when texmfstart is used, or when the proper stub is used or +-- when (windows) suffix binding is active. + +texlua = true + +-- begin library merge + + + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 +local unpack = unpack or table.unpack + +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 + +-- rougly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack) + +function table.sub(t,i,j) + return { unpack(t,i,j) } +end + +function table.replace(a,b) + for k,v in next, b do + a[k] = v + end +end + +-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice) + +function table.is_empty(t) -- 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 +--~ 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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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')) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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") + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + +-- 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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-tra'] = { + version = 1.001, + comment = "companion to trac-tra.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + +debugger = debugger or { } + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in next, counters do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ print("") +--~ debugger.showstats(print,3) + +setters = setters or { } +setters.data = setters.data or { } + +--~ local function set(t,what,value) +--~ local data, done = t.data, t.done +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end + +local function set(t,what,value) + local data, done = t.data, t.done + if type(what) == "string" then + what = aux.settings_to_hash(what) -- inefficient but ok + end + for w, v in next, what do + if v == "" then + v = value + else + v = toboolean(v) + end + for d, f in next, data do + if done[d] then + -- prevent recursion due to wildcards + elseif find(d,w) then + done[d] = true + for i=1,#f do + f[i](v) + end + end + end + end +end + +local function reset(t) + for d, f in next, t.data do + for i=1,#f do + f[i](false) + end + end +end + +local function enable(t,what) + set(t,what,true) +end + +local function disable(t,what) + local data = t.data + if not what or what == "" then + t.done = { } + reset(t) + else + set(t,what,false) + end +end + +function setters.register(t,what,...) + local data = t.data + what = lower(what) + local w = data[what] + if not w then + w = { } + data[what] = w + end + for _, fnc in next, { ... } do + local typ = type(fnc) + if typ == "function" then + w[#w+1] = fnc + elseif typ == "string" then + w[#w+1] = function(value) set(t,fnc,value,nesting) end + end + end +end + +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(tostring(what))) + t.enable, t.done = e, { } +end + +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(tostring(what))) + t.disable, t.done = e, { } +end + +function setters.reset(t) + t.done = { } + reset(t) +end + +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) + local user, system = { }, { } + for l=1,#list do + local what = list[l] + if find(what,"^%*") then + system[#system+1] = what + else + user[#user+1] = what + end + end + return user, system +end + +function setters.show(t) + commands.writestatus("","") + local list = setters.list(t) + for k=1,#list do + commands.writestatus(t.name,list[k]) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singular tracker + +-- we could make this into a module + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") +experiments = setters.new("experiments") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) +local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +local e = experiments.enable +local d = experiments.disable + +function experiments.enable(...) + commands.writestatus("experiments","enabling: %s",concat({...}," ")) + e(...) +end + +function experiments.disable(...) + commands.writestatus("experiments","disabling: %s",concat({...}," ")) + d(...) +end + +-- a useful example + +directives.register("system.nostatistics", function(v) + statistics.enable = not v +end) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-inf'] = { + version = 1.001, + comment = "companion to trac-inf.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 statusinfo, n, registered = { }, 0, { } + +statistics = statistics or { } + +statistics.enable = true +statistics.threshold = 0.05 + +-- timing functions + +local clock = os.gettimeofday or os.clock + +local notimer + +function statistics.hastimer(instance) + return instance and instance.starttime +end + +function statistics.resettiming(instance) + if not instance then + notimer = { timing = 0, loadtime = 0 } + else + instance.timing, instance.loadtime = 0, 0 + end +end + +function statistics.starttiming(instance) + if not instance then + notimer = { } + instance = notimer + end + local it = instance.timing + if not it then + it = 0 + end + if it == 0 then + instance.starttime = clock() + if not instance.loadtime then + instance.loadtime = 0 + end + else +--~ logs.report("system","nested timing (%s)",tostring(instance)) + end + instance.timing = it + 1 +end + +function statistics.stoptiming(instance, report) + if not instance then + instance = notimer + end + if instance then + local it = instance.timing + if it > 1 then + instance.timing = it - 1 + else + local starttime = instance.starttime + if starttime then + local stoptime = clock() + local loadtime = stoptime - starttime + instance.stoptime = stoptime + instance.loadtime = instance.loadtime + loadtime + if report then + statistics.report("load time %0.3f",loadtime) + end + instance.timing = 0 + return loadtime + end + end + end + return 0 +end + +function statistics.elapsedtime(instance) + if not instance then + instance = notimer + end + return format("%0.3f",(instance and instance.loadtime) or 0) +end + +function statistics.elapsedindeed(instance) + if not instance then + instance = notimer + end + local t = (instance and instance.loadtime) or 0 + return t > statistics.threshold +end + +function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds + if statistics.elapsedindeed(instance) then + return format("%s seconds %s", statistics.elapsedtime(instance),rest or "") + end +end + +-- general function + +function statistics.register(tag,fnc) + if statistics.enable and type(fnc) == "function" then + local rt = registered[tag] or (#statusinfo + 1) + statusinfo[rt] = { tag, fnc } + registered[tag] = rt + if #tag > n then n = #tag end + end +end + +function statistics.show(reporter) + if statistics.enable then + if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end + -- this code will move + local register = statistics.register + register("luatex banner", function() + return string.lower(status.banner) + end) + register("control sequences", function() + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) + end) + register("callbacks", function() + local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 + return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total) + end) + register("current memory usage", statistics.memused) + register("runtime",statistics.runtime) +-- -- + for i=1,#statusinfo do + local s = statusinfo[i] + local r = s[2]() + if r then + reporter(s[1],r,n) + end + end + texio.write_nl("") -- final newline + statistics.enable = false + end +end + +function statistics.show_job_stat(tag,data,n) + texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data)) +end + +function statistics.memused() -- no math.round yet -) + local round = math.round or math.floor + return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) +end + +if statistics.runtime then + -- already loaded and set +elseif luatex and luatex.starttime then + statistics.starttime = luatex.starttime + statistics.loadtime = 0 + statistics.timing = 0 +else + statistics.starttiming(statistics) +end + +function statistics.runtime() + statistics.stoptiming(statistics) + return statistics.formatruntime(statistics.elapsedtime(statistics)) +end + +function statistics.formatruntime(runtime) + return format("%s seconds", statistics.elapsedtime(statistics)) +end + +function statistics.timed(action,report) + local timer = { } + report = report or logs.simple + statistics.starttiming(timer) + action() + statistics.stoptiming(timer) + report("total runtime: %s",statistics.elapsedtime(timer)) +end + +-- where, not really the best spot for this: + +commands = commands or { } + +local timer + +function commands.resettimer() + statistics.resettiming(timer) + statistics.starttiming(timer) +end + +function commands.elapsedtime() + statistics.stoptiming(timer) + tex.sprint(statistics.elapsedtime(timer)) +end + +commands.resettimer() + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-log'] = { + version = 1.001, + comment = "companion to trac-log.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is old code that needs an overhaul + +--~ io.stdout:setvbuf("no") +--~ io.stderr:setvbuf("no") + +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch +local texcount = tex and tex.count + +if texlua then + write_nl = print + write = io.write +end + +--[[ldx-- +

This is a prelude to a more extensive logging module. For the sake +of parsing log files, in addition to the standard logging we will +provide an structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

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

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

+--ldx]]-- + +logs.moreinfo = [[ +more information about ConTeXt and the tools that come with it can be found at: + +maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context +webpage : http://www.pragma-ade.nl / http://tex.aanhet.net +wiki : http://contextgarden.net +]] + +logs.levels = { + ['error'] = 1, + ['warning'] = 2, + ['info'] = 3, + ['debug'] = 4, +} + +logs.functions = { + 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct', + 'start_run', 'stop_run', + 'start_page_number', 'stop_page_number', + 'report_output_pages', 'report_output_log', + 'report_tex_stat', 'report_job_stat', + 'show_open', 'show_close', 'show_load', +} + +logs.tracers = { +} + +logs.level = 0 +logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex")) + +function logs.set_level(level) + logs.level = logs.levels[level] or level +end + +function logs.set_method(method) + for _, v in next, logs.functions do + logs[v] = logs[method][v] or function() end + end +end + +-- tex logging + +function logs.tex.report(category,fmt,...) -- new + if fmt then + write_nl(category .. " | " .. format(fmt,...)) + else + write_nl(category .. " |") + end +end + +function logs.tex.line(fmt,...) -- new + if fmt then + write_nl(format(fmt,...)) + else + write_nl("") + end +end + +--~ function logs.tex.start_page_number() +--~ local real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +--~ if real > 0 then +--~ if user > 0 then +--~ if sub > 0 then +--~ write(format("[%s.%s.%s",real,user,sub)) +--~ else +--~ write(format("[%s.%s",real,user)) +--~ end +--~ else +--~ write(format("[%s",real)) +--~ end +--~ else +--~ write("[-") +--~ end +--~ end + +--~ function logs.tex.stop_page_number() +--~ write("]") +--~ end + +local real, user, sub + +function logs.tex.start_page_number() + real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +end + +function logs.tex.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + logs.report("pages", "flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + logs.report("pages", "flushing realpage %s, userpage %s",real,user) + end + else + logs.report("pages", "flushing realpage %s",real) + end + else + logs.report("pages", "flushing page") + end + io.flush() +end + +logs.tex.report_job_stat = statistics.show_job_stat + +-- xml logging + +function logs.xml.report(category,fmt,...) -- new + if fmt then + write_nl(format("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + end +end + +function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end +function logs.xml.stop () if logs.level > 0 then tw("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",level+1,name)) +end + +-- + +local name, banner = 'report', 'context' + +local function report(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + +local function simple(fmt,...) + if fmt then + write_nl(format("%s | %s",name,format(fmt,...))) + else + write_nl(format("%s |",name)) + end +end + +function logs.setprogram(_name_,_banner_,_verbose_) + name, banner = _name_, _banner_ + if _verbose_ then + trackers.enable("resolvers.locating") + end + logs.set_method("tex") + logs.report = report -- also used in libraries + logs.simple = simple -- only used in scripts ! + if utils then + utils.report = simple + end + logs.verbose = _verbose_ +end + +function logs.setverbose(what) + if what then + trackers.enable("resolvers.locating") + else + trackers.disable("resolvers.locating") + end + logs.verbose = what or false +end + +function logs.extendbanner(_banner_,_verbose_) + banner = banner .. " | ".. _banner_ + if _verbose_ ~= nil then + logs.setverbose(what) + end +end + +logs.verbose = false +logs.report = logs.tex.report +logs.simple = logs.tex.report + +function logs.reportlines(str) -- todo: + for line in gmatch(str,"(.-)[\n\r]") do + logs.report(line) + end +end + +function logs.reportline() -- for scripts too + logs.report() +end + +logs.simpleline = logs.reportline + +function logs.reportbanner() -- for scripts too + logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() + logs.reportline() + logs.reportlines(message) + local moreinfo = logs.moreinfo or "" + if moreinfo ~= "" and option ~= "nomoreinfo" then + logs.reportline() + logs.reportlines(moreinfo) + end +end + +logs.set_level('error') +logs.set_method('tex') + +function logs.system(whereto,process,jobname,category,...) + for i=1,10 do + local f = io.open(whereto,"a") + if f then + f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...))) + f:close() + break + else + sleep(0.1) + end + end +end + +--~ local syslogname = "oeps.xxx" +--~ +--~ for i=1,10 do +--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123") +--~ end + +function logs.fatal(where,...) + logs.report(where,"fatal error: %s, aborting now",format(...)) + os.exit() +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 } + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 { } + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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' + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure +-- end library merge + +-- We initialize some characteristics of this program. We need to +-- do this before we load the libraries, else own.name will not be +-- properly set (handy for selfcleaning the file). It's an ugly +-- looking piece of code. + +own = { } + +own.libs = { -- todo: check which ones are really needed + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-io.lua', + 'l-number.lua', + 'l-set.lua', + 'l-os.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-boolean.lua', + 'l-unicode.lua', + 'l-math.lua', + 'l-utils.lua', + 'l-aux.lua', + 'trac-tra.lua', + 'luat-env.lua', + 'trac-inf.lua', + 'trac-log.lua', + 'data-res.lua', + 'data-tmp.lua', +-- 'data-pre.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-tex.lua', +-- 'data-bin.lua', +-- 'data-zip.lua', +-- 'data-crl.lua', +-- 'data-lua.lua', + 'data-kps.lua', -- so that we can replace kpsewhich + 'data-aux.lua', -- updater + 'data-lst.lua', -- lister +} + +-- We need this hack till luatex is fixed. + +if arg and arg[0] == 'luatex' 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 + +-- End of hack. + +own.name = (environment and environment.ownname) or arg[0] or 'luatools.lua' +own.path = string.match(own.name,"^(.+)[\\/].-$") or "." +own.list = { '.' } + +if own.path ~= '.' then + table.insert(own.list,own.path) +end + +table.insert(own.list,own.path.."/../../../tex/context/base") +table.insert(own.list,own.path.."/mtx") +table.insert(own.list,own.path.."/../sources") + +function locate_libs() + for _, lib in pairs(own.libs) do + for _, pth in pairs(own.list) do + local filename = string.gsub(pth .. "/" .. lib,"\\","/") + local codeblob = loadfile(filename) + if codeblob then + codeblob() + own.list = { pth } -- speed up te search + break + end + end + end +end + +if not resolvers then + locate_libs() +end + +if not resolvers then + print("") + print("Luatools is unable to start up due to lack of libraries. You may") + print("try to run 'lua luatools.lua --selfmerge' in the path where this") + print("script is located (normally under ..../scripts/context/lua) which") + print("will make luatools library independent.") + os.exit() +end + +logs.setprogram('LuaTools',"TDS Management Tool 1.32",environment.arguments["verbose"] or false) + +local instance = resolvers.reset() + +resolvers.defaultlibs = { -- not all are needed (this will become: context.lus (lua spec) + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-boolean.lua', + 'l-number.lua', + 'l-unicode.lua', + 'l-os.lua', + 'l-io.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-utils.lua', + 'l-dimen.lua', + 'trac-inf.lua', + 'trac-tra.lua', + 'trac-log.lua', + 'luat-env.lua', -- here ? + 'data-res.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-tmp.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-pre.lua', + 'data-tex.lua', + 'data-bin.lua', +-- 'data-zip.lua', +-- 'data-clr.lua', + 'data-lua.lua', + 'data-ctx.lua', + 'luat-fio.lua', + 'luat-cnf.lua', +} + +instance.engine = environment.arguments["engine"] or 'luatex' +instance.progname = environment.arguments["progname"] or 'context' +instance.luaname = environment.arguments["luafile"] or "" -- environment.ownname or "" +instance.lualibs = environment.arguments["lualibs"] or table.concat(resolvers.defaultlibs,",") +instance.allresults = environment.arguments["all"] or false +instance.pattern = environment.arguments["pattern"] or nil +instance.sortdata = environment.arguments["sort"] or false +instance.kpseonly = not environment.arguments["all"] or false +instance.my_format = environment.arguments["format"] or instance.format + +if type(instance.pattern) == 'boolean' then + logs.simple("invalid pattern specification") + instance.pattern = nil +end + +if environment.arguments["trace"] then resolvers.settrace(environment.arguments["trace"]) end + +local trackspec = environment.argument("trackers") or environment.argument("track") + +if trackspec then + trackers.enable(trackspec) +end + +runners = runners or { } +messages = messages or { } + +messages.no_ini_file = [[ +There is no lua initialization file found. This file can be forced by the +"--progname" directive, or specified with "--luaname", or it is derived +automatically from the formatname (aka jobname). It may be that you have +to regenerate the file database using "luatools --generate". +]] + +messages.help = [[ +--generate generate file database +--variables show configuration variables +--expansions show expanded variables +--configurations show configuration order +--expand-braces expand complex variable +--expand-path expand variable (resolve paths) +--expand-var expand variable (resolve references) +--show-path show path expansion of ... +--var-value report value of variable +--find-file report file location +--find-path report path of file +--make or --ini make luatex format +--run or --fmt= run luatex format +--luafile=str lua inifile (default is .lua) +--lualibs=list libraries to assemble (optional when --compile) +--compile assemble and compile lua inifile +--verbose give a bit more info +--all show all found files +--sort sort cached data +--engine=str target engine +--progname=str format or backend +--pattern=str filter variables +--trackers=list enable given trackers +]] + +function runners.make_format(texname) + local instance = resolvers.instance + if texname and texname ~= "" then + if resolvers.usecache then + local path = file.join(caches.setpath("formats")) -- maybe platform + if path and lfs then + lfs.chdir(path) + end + end + local barename = texname:gsub("%.%a+$","") + if barename == texname then + texname = texname .. ".tex" + end + local fullname = resolvers.find_files(texname)[1] or "" + if fullname == "" then + logs.simple("no tex file with name: %s",texname) + else + local luaname, lucname, luapath, lualibs = "", "", "", { } + -- the following is optional, since context.lua can also + -- handle this collect and compile business + if environment.arguments["compile"] then + if luaname == "" then luaname = barename end + logs.simple("creating initialization file: %s",luaname) + luapath = file.dirname(luaname) + if luapath == "" then + luapath = file.dirname(texname) + end + if luapath == "" then + luapath = file.dirname(resolvers.find_files(texname)[1] or "") + end + lualibs = string.split(instance.lualibs,",") + luaname = file.basename(barename .. ".lua") + lucname = file.basename(barename .. ".luc") + -- todo: when this fails, we can just copy the merged libraries from + -- luatools since they are normally the same, at least for context + if lualibs[1] then + local firstlib = file.join(luapath,lualibs[1]) + if not lfs.isfile(firstlib) then + local foundname = resolvers.find_files(lualibs[1])[1] + if foundname then + logs.simple("located library path: %s",luapath) + luapath = file.dirname(foundname) + end + end + end + logs.simple("using library path: %s",luapath) + logs.simple("using lua libraries: %s",table.join(lualibs," ")) + utils.merger.selfcreate(lualibs,luapath,luaname) + local strip = resolvers.boolean_variable("LUACSTRIP", true) + if utils.lua.compile(luaname,lucname,false,strip) and io.exists(lucname) then + luaname = lucname + logs.simple("using compiled initialization file: %s",lucname) + else + logs.simple("using uncompiled initialization file: %s",luaname) + end + else + local what = { instance.luaname, instance.progname, barename } + for k=1,#what do + local v = string.gsub(what[k]..".lua","%.lua%.lua$",".lua") + if v and (v ~= "") then + luaname = resolvers.find_files(v)[1] or "" + if luaname ~= "" then + break + end + end + end + end + if environment.arguments["noluc"] then + luaname = luaname:gsub("%.luc$",".lua") -- make this an option + end + if luaname == "" then + if logs.verbose then + logs.simplelines(messages.no_ini_file) + logs.simple("texname : %s",texname) + logs.simple("luaname : %s",instance.luaname) + logs.simple("progname: %s",instance.progname) + logs.simple("barename: %s",barename) + end + else + logs.simple("using lua initialization file: %s",luaname) + local mp = dir.glob(file.removesuffix(file.basename(luaname)).."-*.mem") + if mp and #mp > 0 then + for i=1,#mp do + local name = mp[i] + logs.simple("removing related mplib format %s", file.basename(name)) + os.remove(name) + end + end + local flags = { + "--ini", + "--lua=" .. string.quote(luaname) + } + local bs = (os.platform == "unix" and "\\\\") or "\\" -- todo: make a function + local command = "luatex ".. table.concat(flags," ") .. " " .. string.quote(fullname) .. " " .. bs .. "dump" + logs.simple("running command: %s\n",command) + os.spawn(command) + -- todo: do a dummy run that generates the related metafun and mfplain formats + end + end + else + logs.simple("no tex file given") + end +end + +function runners.run_format(name,data,more) + -- hm, rather old code here; we can now use the file.whatever functions + if name and (name ~= "") then + local barename = name:gsub("%.%a+$","") + local fmtname = "" + 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) + barename = fmtname:gsub("%.%a+$","") + if fmtname == "" then + logs.simple("no format with name: %s",name) + else + local luaname = barename .. ".luc" + local f = io.open(luaname) + if not f then + luaname = barename .. ".lua" + f = io.open(luaname) + end + if f then + f:close() + local command = "luatex --fmt=" .. string.quote(barename) .. " --lua=" .. string.quote(luaname) .. " " .. string.quote(data) .. " " .. (more ~= "" and string.quote(more) or "") + logs.simple("running command: %s",command) + os.spawn(command) + else + logs.simple("using format name: %s",fmtname) + logs.simple("no luc/lua with name: %s",barename) + end + end + end +end + +local ok = true + +-- private option --noluc for testing errors in the stub + +if environment.arguments["find-file"] then + resolvers.load() + instance.format = environment.arguments["format"] or instance.format + if instance.pattern then + instance.allresults = true + resolvers.for_files(resolvers.find_files, { instance.pattern }, instance.my_format) + else + resolvers.for_files(resolvers.find_files, environment.files, instance.my_format) + end +elseif environment.arguments["find-path"] then + resolvers.load() + local path = resolvers.find_file(environment.files[1], instance.my_format) + if logs.verbose then + logs.simple(file.dirname(path)) + else + print(file.dirname(path)) + end +elseif environment.arguments["run"] then + resolvers.load("nofiles") -- ! no need for loading databases + logs.setverbose(true) + runners.run_format(environment.files[1] or "",environment.files[2] or "",environment.files[3] or "") +elseif environment.arguments["fmt"] then + resolvers.load("nofiles") -- ! no need for loading databases + logs.setverbose(true) + runners.run_format(environment.arguments["fmt"], environment.files[1] or "",environment.files[2] or "") +elseif environment.arguments["expand-braces"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_braces, environment.files) +elseif environment.arguments["expand-path"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_path, environment.files) +elseif environment.arguments["expand-var"] or environment.arguments["expand-variable"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_var, environment.files) +elseif environment.arguments["show-path"] or environment.arguments["path-value"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.show_path, environment.files) +elseif environment.arguments["var-value"] or environment.arguments["show-value"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.var_value, environment.files) +elseif environment.arguments["format-path"] then + resolvers.load() + logs.simple(caches.setpath("format")) +elseif instance.pattern then -- brrr + resolvers.load() + instance.format = environment.arguments["format"] or instance.format + instance.allresults = true + resolvers.for_files(resolvers.find_files, { instance.pattern }, instance.my_format) +elseif environment.arguments["generate"] then + instance.renewcache = true + logs.setverbose(true) + resolvers.load() +elseif environment.arguments["make"] or environment.arguments["ini"] or environment.arguments["compile"] then + resolvers.load() + logs.setverbose(true) + runners.make_format(environment.files[1] or "") +elseif environment.arguments["selfmerge"] then + utils.merger.selfmerge(own.name,own.libs,own.list) +elseif environment.arguments["selfclean"] then + utils.merger.selfclean(own.name) +elseif environment.arguments["selfupdate"] then + resolvers.load() + logs.setverbose(true) + resolvers.update_script(own.name,"luatools") +elseif environment.arguments["variables"] or environment.arguments["show-variables"] then + resolvers.load("nofiles") + resolvers.listers.variables() +elseif environment.arguments["expansions"] or environment.arguments["show-expansions"] then + resolvers.load("nofiles") + resolvers.listers.expansions() +elseif environment.arguments["configurations"] or environment.arguments["show-configurations"] then + resolvers.load("nofiles") + resolvers.listers.configurations() +elseif environment.arguments["help"] or (environment.files[1]=='help') or (#environment.files==0) then + logs.help(messages.help) +else + resolvers.load() + resolvers.for_files(resolvers.find_files, environment.files, instance.my_format) +end + +if logs.verbose then + logs.simpleline() + logs.simple("runtime: %0.3f seconds",os.runtime()) +end + +if os.platform == "unix" then + io.write("\n") +end diff --git a/scripts/context/lua/luatools.rme b/scripts/context/lua/luatools.rme new file mode 100644 index 000000000..901e9a9a3 --- /dev/null +++ b/scripts/context/lua/luatools.rme @@ -0,0 +1,3 @@ +On MSWindows the luatools.lua script is called +with luatools.exe. On Unix you can either rename +luatools.lua to luatools, or use a symlink. diff --git a/scripts/context/lua/mtx-babel.lua b/scripts/context/lua/mtx-babel.lua new file mode 100644 index 000000000..01e2ba4b2 --- /dev/null +++ b/scripts/context/lua/mtx-babel.lua @@ -0,0 +1,430 @@ +if not modules then modules = { } end modules ['mtx-babel'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- data tables by Thomas A. Schmitz + +scripts = scripts or { } +scripts.babel = scripts.babel or { } + +do + + local converters = { } + + -- greek + + local replace_01 = { -- <' * | + a = "ᾅ", + h = "ᾕ", + w = "ᾥ", + } + + local replace_02 = { -- >' * | + a = "ᾄ", + h = "ᾔ", + w = "ᾤ", + } + + local replace_03 = { -- <` * | + a = "ᾃ", + h = "ᾓ", + w = "ᾣ", + } + + local replace_04 = { -- >` * | + a = "ᾂ", + h = "ᾒ", + w = "ᾢ", + } + + local replace_05 = { -- <~ * | + a = "ᾇ", + h = "ᾗ", + w = "ᾧ", + } + + local replace_06 = { -- >~ * | + a = "ᾆ", + h = "ᾖ", + w = "ᾦ" + } + + local replace_07 = { -- "' * + i = "ΐ", + u = "ΰ", + } + + local replace_08 = { -- "` * + i = "ῒ", + u = "ῢ", + } + + local replace_09 = { -- "~ * + i = "ῗ", + u = "ῧ", + } + + local replace_10 = { -- <' * + a = "ἅ", + e = "ἕ", + h = "ἥ", + i = "ἵ", + o = "ὅ", + u = "ὕ", + w = "ὥ", + A = "Ἅ", + E = "Ἕ", + H = "Ἥ", + I = "Ἵ", + O = "Ὅ", + U = "Ὕ", + W = "Ὥ", + } + + local replace_11 = { -- >' * + a = "ἄ", + e = "ἔ", + h = "ἤ", + i = "ἴ", + o = "ὄ", + u = "ὔ", + w = "ὤ", + A = "Ἄ", + E = "Ἔ", + H = "Ἤ", + I = "Ἴ", + O = "Ὄ", + U = "῎Υ", + W = "Ὤ", + } + + local replace_12 = { -- <` * + a = "ἃ", + e = "ἓ", + h = "ἣ", + i = "ἳ", + o = "ὃ", + u = "ὓ", + w = "ὣ", + A = "Ἃ", + E = "Ἒ", + H = "Ἣ", + I = "Ἳ", + O = "Ὃ", + U = "Ὓ", + W = "Ὣ", + } + + local replace_13 = { -- >` * + a = "ἂ", + e = "ἒ", + h = "ἢ", + i = "ἲ", + o = "ὂ", + u = "ὒ", + w = "ὢ", + A = "Ἂ", + E = "Ἒ", + H = "Ἢ", + I = "Ἲ", + O = "Ὂ", + U = "῍Υ", + W = "Ὢ", + } + + local replace_14 = { -- <~ * + a = "ἇ", + h = "ἧ", + i = "ἷ", + u = "ὗ", + w = "ὧ", + A = "Ἇ", + H = "Ἧ", + I = "Ἷ", + U = "Ὗ", + W = "Ὧ", + } + + local replace_15 = { -- >~ * + a = "ἆ", + h = "ἦ", + i = "ἶ", + u = "ὖ", + w = "ὦ", + A = "Ἆ", + H = "Ἦ", + I = "Ἶ", + U = "῏Υ", + W = "Ὦ", + } + + local replace_16 = { -- ' * | + a = "ᾴ", + h = "ῄ", + w = "ῴ", + } + + local replace_17 = { -- ` * | + a = "ᾲ", + h = "ῂ", + w = "ῲ", + } + + local replace_18 = { -- ~ * | + a = "ᾷ", + h = "ῇ", + w = "ῷ" + } + + local replace_19 = { -- ' * + a = "ά", + e = "έ", + h = "ή", + i = "ί", + o = "ό", + u = "ύ", + w = "ώ", + ["'"] = "’", + } + + local replace_20 = { -- ` * + a = "ὰ", + e = "ὲ", + h = "ὴ", + i = "ὶ", + o = "ὸ", + u = "ὺ", + w = "ὼ", + } + + local replace_21 = { -- ~ * + a = "ᾶ", + h = "ῆ", + i = "ῖ", + u = "ῦ", + w = "ῶ", + } + + local replace_22 = { -- < * + a = "ἁ", + e = "ἑ", + h = "ἡ", + i = "ἱ", + o = "ὁ", + u = "ὑ", + w = "ὡ", + r = "ῥ", + A = "Ἁ", + E = "Ἑ", + H = "Ἡ", + I = "Ἱ", + O = "Ὁ", + U = "Ὑ", + W = "Ὡ", + R = "Ῥ", + } + + local replace_23 = { -- > * + a = "ἀ", + e = "ἐ", + h = "ἠ", + i = "ἰ", + o = "ὀ", + u = "ὐ", + w = "ὠ", + A = "Ἀ", + E = "Ἐ", + H = "Ἠ", + I = "Ἰ", + O = "Ὀ", + U = "᾿Υ", + W = "Ὠ", + } + + local replace_24 = { -- * | + a = "ᾳ", + h = "ῃ", + w = "ῳ", + } + + local replace_25 = { -- " * + i = "ϊ", + u = "ϋ", + } + + local replace_26 = { -- * + a = "α", + b = "β", + g = "γ", + d = "δ", + e = "ε", + z = "ζ", + h = "η", + j = "θ", + i = "ι", + k = "κ", + l = "λ", + m = "μ", + n = "ν", + x = "ξ", + o = "ο", + p = "π", + r = "ρ", + s = "σ", + c = "ς", + t = "τ", + u = "υ", + f = "φ", + q = "χ", + y = "ψ", + w = "ω", + A = "Α", + B = "Β", + G = "Γ", + D = "Δ", + E = "Ε", + Z = "Ζ", + H = "Η", + J = "Θ", + I = "Ι", + K = "Κ", + L = "Λ", + M = "Μ", + N = "Ν", + X = "Ξ", + O = "Ο", + P = "Π", + R = "Ρ", + S = "Σ", + T = "Τ", + U = "Υ", + F = "Φ", + Q = "Χ", + Y = "Ψ", + W = "Ω", + [";"] = "·", + ["?"] = ";", + } + + local P, R, S, V, Cs = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Cs + + local skips_01 = P("\\") * R("az", "AZ")^1 + local skips_02 = P("[") * (1- S("[]"))^1 * P("]") + + local greek_01 = (P("<'") * Cs(1) * P('|')) / replace_01 + local greek_02 = (P(">'") * Cs(1) * P('|')) / replace_02 + local greek_03 = (P("<`") * Cs(1) * P('|')) / replace_03 + local greek_04 = (P(">`") * Cs(1) * P('|')) / replace_04 + local greek_05 = (P("<~") * Cs(1) * P('|')) / replace_05 + local greek_06 = (P(">~") * Cs(1) * P('|')) / replace_06 + local greek_07 = (P('"\'') * Cs(1) ) / replace_07 + local greek_08 = (P('"`') * Cs(1) ) / replace_08 + local greek_09 = (P('"~') * Cs(1) ) / replace_09 + local greek_10 = (P("<'") * Cs(1) ) / replace_10 + local greek_11 = (P(">'") * Cs(1) ) / replace_11 + local greek_12 = (P("<`") * Cs(1) ) / replace_12 + local greek_13 = (P(">`") * Cs(1) ) / replace_13 + local greek_14 = (P("<~") * Cs(1) ) / replace_14 + local greek_15 = (P(">~") * Cs(1) ) / replace_15 + local greek_16 = (P("'") * Cs(1) * P('|')) / replace_16 + local greek_17 = (P("`") * Cs(1) * P('|')) / replace_17 + local greek_18 = (P("~") * Cs(1) * P('|')) / replace_18 + local greek_19 = (P("'") * Cs(1) ) / replace_19 + local greek_20 = (P("`") * Cs(1) ) / replace_20 + local greek_21 = (P("~") * Cs(1) ) / replace_21 + local greek_22 = (P("<") * Cs(1) ) / replace_22 + local greek_23 = (P(">") * Cs(1) ) / replace_23 + local greek_24 = (Cs(1) * P('|') ) / replace_24 + local greek_25 = (P('"') * Cs(1) ) / replace_25 + local greek_26 = (Cs(1) ) / replace_26 + + local skips = + skips_01 + skips_02 + + local greek = + greek_01 + greek_02 + greek_03 + greek_04 + greek_05 + + greek_06 + greek_07 + greek_08 + greek_09 + greek_10 + + greek_11 + greek_12 + greek_13 + greek_14 + greek_15 + + greek_16 + greek_17 + greek_18 + greek_19 + greek_20 + + greek_21 + greek_22 + greek_23 + greek_24 + greek_25 + + greek_26 + + local spacing = S(" \n\r\t") + local startgreek = P("\\startgreek") + local stopgreek = P("\\stopgreek") + local localgreek = P("\\localgreek") + local lbrace = P("{") + local rbrace = P("}") + + local documentparser = Cs((skips + greek + 1)^0) + + local contextgrammar = Cs ( P { "scan", + ["scan"] = (V("global") + V("local") + skips + 1)^0, + ["global"] = startgreek * ((skips + greek + 1)-stopgreek )^0 , + ["local"] = localgreek * V("grouped"), + ["grouped"] = spacing^0 * lbrace * (V("grouped") + skips + (greek - rbrace))^0 * rbrace, + } ) + + converters['greek'] = { + document = documentparser, + context = contextgrammar, + } + + -- lpeg.print(parser): 254 lines + + function scripts.babel.convert(filename) + if filename and filename ~= empty then + local data = io.loaddata(filename) or "" + if data ~= "" then + local language = environment.argument("language") or "" + if language ~= "" then + local converter = converters[language] + if converter then + local structure = environment.argument("structure") or "document" + converter = converter[structure] + if converter then + logs.simple("converting '%s' using language '%s' with structure '%s'", filename, language, structure) + data = converter:match(data) + local newfilename = filename .. ".utf" + io.savedata(newfilename, data) + logs.simple("converted data saved in '%s'", newfilename) + else + logs.simple("unknown structure '%s' language '%s'", structure, language) + end + else + logs.simple("no converter for language '%s'", language) + end + else + logs.simple("provide language") + end + else + logs.simple("no data in '%s'",filename) + end + end + end + + --~ print(contextgrammar:match [[ + --~ oeps abg \localgreek{a} + --~ \startgreek abg \stopgreek \oeps + --~ oeps abg \localgreek{a{b}\oeps g} + --~ ]]) + +end + +logs.extendbanner("Babel Input To UTF Conversion 1.20",true) + +messages.help = [[ +--language=string conversion language (e.g. greek) +--structure=string obey given structure (e.g. 'document', default: 'context') +--convert convert babel codes into utf +]] + +if environment.argument("convert") then + scripts.babel.convert(environment.files[1] or "") +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-cache.lua b/scripts/context/lua/mtx-cache.lua new file mode 100644 index 000000000..c2a0db00d --- /dev/null +++ b/scripts/context/lua/mtx-cache.lua @@ -0,0 +1,96 @@ +if not modules then modules = { } end modules ['mtx-cache'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.cache = scripts.cache or { } + +function scripts.cache.collect_one(...) + local path = caches.setpath(...) + local tmas = dir.glob(path .. "/*.tma") + local tmcs = dir.glob(path .. "/*.tmc") + return path, tmas, tmcs +end + +function scripts.cache.collect_two(...) + local path = caches.setpath(...) + local rest = dir.glob(path .. "/**/*") + return path, rest +end + +local suffixes = { "afm", "tfm", "def", "enc", "otf", "mp", "data" } + +function scripts.cache.process_one(action) + for i=1,#suffixes do + action("fonts", suffixes[i]) + end +end + +function scripts.cache.process_two(action) + action("curl") +end + +-- todo: recursive delete of paths + +function scripts.cache.remove(list,keep) + local n, keepsuffixes = 0, table.tohash(keep or { }) + for i=1,#list do + local filename = list[i] + if string.find(filename,"luatex%-cache") then -- safeguard + if not keepsuffixes[file.extname(filename) or ""] then + os.remove(filename) + n = n + 1 + end + end + end + return n +end + +function scripts.cache.delete(all,keep) + scripts.cache.process_one(function(...) + local path, rest = scripts.cache.collect_one(...) + local n = scripts.cache.remove(rest,keep) + logs.report("cache path",string.format("%4i files out of %4i deleted on %s",n,#rest,path)) + end) + scripts.cache.process_two(function(...) + local path, rest = scripts.cache.collect_two(...) + local n = scripts.cache.remove(rest,keep) + logs.report("cache path",string.format("%4i files out of %4i deleted on %s",n,#rest,path)) + end) +end + +function scripts.cache.list(all) + scripts.cache.process_one(function(...) + local path, tmas, tmcs = scripts.cache.collect_one(...) + logs.report("cache path",string.format("%4i (tma:%4i, tmc:%4i) %s",#tmas+#tmcs,#tmas,#tmcs,path)) + logs.report("cache path",string.format("%4i (tma:%4i, tmc:%4i) %s",#tmas+#tmcs,#tmas,#tmcs,path)) + end) + scripts.cache.process_two(function(...) + local path, rest = scripts.cache.collect_two("curl") + logs.report("cache path",string.format("%4i %s",#rest,path)) + end) +end + +logs.extendbanner("ConTeXt & MetaTeX Cache Management 0.10") + +messages.help = [[ +--purge remove not used files +--erase completely remove cache +--list show cache + +--all all (not yet implemented) +]] + +if environment.argument("purge") then + scripts.cache.delete(environment.argument("all"),{"tmc"}) +elseif environment.argument("erase") then + scripts.cache.delete(environment.argument("all")) +elseif environment.argument("list") then + scripts.cache.list(environment.argument("all")) +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-chars.lua b/scripts/context/lua/mtx-chars.lua new file mode 100644 index 000000000..6acacfbd2 --- /dev/null +++ b/scripts/context/lua/mtx-chars.lua @@ -0,0 +1,322 @@ +if not modules then modules = { } end modules ['mtx-chars'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, concat, utfchar, upper = string.format, table.concat, unicode.utf8.char, string.upper + +scripts = scripts or { } +scripts.chars = scripts.chars or { } + +--~ local banner = [[ +--~ -- filename : char-mth.lua +--~ -- comment : companion to char-mth.tex (in ConTeXt) +--~ -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL +--~ -- license : see context related readme files +--~ -- comment : generated from data file downloaded from STIX website +--~ +--~ if not versions then versions = { } end versions['char-mth'] = 1.001 +--~ if not characters then characters = { } end +--~ ]] +--~ +--~ function scripts.chars.stixtomkiv(inname,outname) +--~ if inname == "" then +--~ logs.report("aquiring math data","invalid datafilename") +--~ end +--~ local f = io.open(inname) +--~ if not f then +--~ logs.report("aquiring math data","invalid datafile") +--~ else +--~ logs.report("aquiring math data","processing " .. inname) +--~ if not outname or outname == "" then +--~ outname = "char-mth.lua" +--~ end +--~ local classes = { +--~ N = "normal", +--~ A = "alphabetic", +--~ D = "diacritic", +--~ P = "punctuation", +--~ B = "binary", +--~ R = "relation", +--~ L = "large", +--~ O = "opening", +--~ C = "closing", +--~ F = "fence" +--~ } +--~ local valid, done = false, { } +--~ local g = io.open(outname,'w') +--~ g:write(banner) +--~ g:write(format("\ncharacters.math = {\n")) +--~ for l in f:lines() do +--~ if not valid then +--~ valid = l:find("AMS/TeX name") +--~ end +--~ if valid then +--~ local unicode = l:sub(2,6) +--~ if unicode:sub(1,1) ~= " " and unicode ~= "" and not done[unicode] then +--~ local mathclass, adobename, texname = l:sub(57,57) or "", l:sub(13,36) or "", l:sub(84,109) or "" +--~ texname, adobename = texname:gsub("[\\ ]",""), adobename:gsub("[\\ ]","") +--~ local t = { } +--~ if mathclass ~= "" then t[#t+1] = format("mathclass='%s'", classes[mathclass] or "unknown") end +--~ if adobename ~= "" then t[#t+1] = format("adobename='%s'", adobename ) end +--~ if texname ~= "" then t[#t+1] = format("texname='%s'" , texname ) end +--~ if #t > 0 then +--~ g:write(format("\t[0x%s] = { %s },\n",unicode, concat(t,", "))) +--~ end +--~ done[unicode] = true +--~ end +--~ end +--~ end +--~ if not valid then +--~ g:write("\t-- The data file is corrupt, invalid or maybe the format has changed.\n") +--~ logs.report("aquiring math data","problems with data table") +--~ else +--~ logs.report("aquiring math data","table saved in " .. outname) +--~ end +--~ g:write("}\n") +--~ g:close() +--~ f:close() +--~ end +--~ end + +function scripts.chars.stixtomkiv(inname,outname) + logs.report("we no longer use this options but use our own tables instead") +end + +local banner_pdf_1 = [[ +% 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 +% +]] + +local banner_pdf_2 = [[ +% +\endinput +]] + +function scripts.chars.makepdfr() + local chartable = resolvers.find_file("char-def.lua") or "" + if chartable ~= "" then + dofile(chartable) + if characters and characters.data then + local f = io.open("pdfr-def.tex", 'w') + if f then + f:write(banner_pdf_1) + local cd = characters.data + local sd = table.sortedkeys(cd) + for i=1,#sd do + local char = cd[sd[i]] + if char.adobename then + f:write(format("\\pdfglyphtounicode{%s}{%04X}%%\n",char.adobename,char.unicodeslot)) + end + end + f:write(banner_pdf_2) + f:close() + end + end + end +end + +local banner_utf_module = [[ +%% filename : %s +%% comment : generated by mtxrun --script chars --xtx +%% author : Hans Hagen, PRAGMA-ADE, Hasselt NL +%% copyright: PRAGMA ADE / ConTeXt Development Team +%% license : see context related readme files +]] + +local banner_utf_mappings = [[ + +% lc/uc/catcode mappings + +]] + +local banner_utf_patch = [[ + +% patch needed for turkish + +\setXTXcharcodes "201C "201C "201C +\setXTXcharcodes "201D "201D "201D +]] + +local banner_utf_names = [[ + +% named characters mapped onto utf (\\char is needed for accents) + +]] + +local banner_utf_classes = [[ + +% some character classes for xetex; seems to be rather hard coded, these numbers +% and also a mix of several classes; here we do linebreaks + +]] + +local banner_utf_finish = [[ + +\endinput +]] + +local xtxclasses = { + id = 1, + ex = 3, + is = 3, + cm = 256, + op = 2, + ns = 3, + cl = 3, +} + +function scripts.chars.makeencoutf() + local chartable = resolvers.find_file("char-def.lua") or "" + if chartable ~= "" then + dofile(chartable) + local function open(name,banner) + local f = io.open(name,'w') + if f then + logs.simple("writing '%s'",name) + f:write(format(banner_utf_module,name)) + f:write(banner) + f:write() + return f + end + end + local function close(f) + f:write(banner_utf_finish) + f:close() + end + local data = characters and characters.data + if data then + local list = table.sortedkeys(characters.data) + local f = open("xetx-utf.tex",banner_utf_mappings) + if f then + for i=1,#list do + local code = list[i] + if code <= 0xFFFF then + local chr = data[code] + local cc = chr.category + if cc == 'll' or cc == 'lu' or cc == 'lt' then + if not chr.lccode then chr.lccode = code end + if not chr.uccode then chr.uccode = code end + f:write(format('\\setXTXcharcodes "%05X "%05X "%05X %% %s\n',code,chr.lccode,chr.uccode,chr.description)) + end + end + end + f:write("\n") + for i=1,#list do + local code = list[i] + local chr = data[code] + if chr and chr.range then + local cc = chr.category + if cc == 'lo' then + f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharcodes\\recurselevel\\recurselevel\\recurselevel}\n',code,chr.range)) + end + end + end + f:write(banner_utf_patch) + close(f) + end + local f = open("xetx-chr.tex",banner_utf_names) + if f then + local length = 0 + for i=1,#list do + local code = list[i] + if code > 0x5B and code <= 0xFFFF then + local chr = data[code] + if chr and #(chr.contextname or "") > length then + length = #chr.contextname + end + end + end + for i=1,#list do + local code = list[i] + if code > 0x5B and code <= 0xFFFF then + local chr = data[code] + if chr and chr.contextname then + local ch = utfchar(code) + f:write(format("\\def\\%s{\\char\"%05X } %% %s: %s\n", chr.contextname:rpadd(length," "), code, chr.description, ch)) + end + end + end + close(f) + end + local f = open("xetx-cls.tex",banner_utf_classes) + if f then + for k, v in next, xtxclasses do + f:write(format("\\defineXTXcharinjectionclass[lb:%s]\n",k)) + end + f:write("\n") + local i_first, i_last, i_clb = nil, nil, nil + local function flush() + if i_first then + if i_first == i_last then + f:write(format('\\dosetXTXcharacterclass{"%05X}{lb:%s}\n',i_first,i_clb)) + else + f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharacterclass\\fastrecursecounter{lb:%s}}\n',i_first,i_last,i_clb)) + end + end + i_first, i_last, i_clb = nil, nil, nil + end + for i=1,#list do + local code = list[i] + local code_next = list[i+1] + local chr = data[code] + local chr_next = data[code_next] + local clb = chr and chr.linebreak + local lbc = xtxclasses[clb] + if not lbc then + flush() + elseif clb == i_clb then + if i_first then + i_last = code + else + i_first, i_last, i_clb = code, code, clb + end + else + flush() + i_first, i_last, i_clb = code, code, clb + end + end + flush() + f:write("\n") + for i=1,#list do + local code = list[i] + local chr = data[code] + if chr and chr.range then + local lbc = chr.linebreak + if xtxclasses[lbc] then + f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharacterclass\\fastrecursecounter{lb:%s}}\n',code,chr.range,lbc)) + end + end + end + close(f) + end + end + end +end + +logs.extendbanner("MkII Character Table Generators 0.10") + +messages.help = [[ +--stix convert stix table to math table +--xtx generate xetx-*.tex (used by xetex) +--pdf generate pdfr-def.tex (used by pdftex) +]] + +if environment.argument("stix") then + local inname = environment.files[1] or "" + local outname = environment.files[2] or "" + scripts.chars.stixtomkiv(inname,outname) +elseif environment.argument("xtx") then + scripts.chars.makeencoutf() +elseif environment.argument("pdf") then + scripts.chars.makepdfr() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-check.lua b/scripts/context/lua/mtx-check.lua new file mode 100644 index 000000000..4266ddf0d --- /dev/null +++ b/scripts/context/lua/mtx-check.lua @@ -0,0 +1,143 @@ +if not modules then modules = { } end modules ['mtx-check'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.checker = scripts.checker or { } + +local validator = { } + +do + + validator.n = 1 + validator.errors = { } + validator.trace = false + validator.direct = false + + validator.printer = print + validator.tracer = print + + local message = function(position, kind) + local ve = validator.errors + ve[#ve+1] = { kind, position, validator.n } + if validator.direct then + validator.printer(string.format("%s error at position %s (line %s)", kind, position, validator.n)) + end + end + local progress = function(position, data, kind) + if validator.trace then + validator.tracer(string.format("%s at position %s: %s", kind, position, data or "")) + end + end + + local P, R, S, V, C, CP, CC = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cp, lpeg.Cc + + local i_m, d_m = P("$"), P("$$") + local l_s, r_s = P("["), P("]") + local l_g, r_g = P("{"), P("}") + + local okay = lpeg.P("{[}") + lpeg.P("{]}") + + local esc = P("\\") + local cr = P("\r") + local lf = P("\n") + local crlf = P("\r\n") + local space = S(" \t\f\v") + local newline = crlf + cr + lf + + local line = newline / function() validator.n = validator.n + 1 end + + -- local grammar = P { "tokens", + -- ["tokens"] = (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + V("errors") + 1)^0, + -- ["whatever"] = line + esc * 1 + C(P("%") * (1-line)^0), + -- ["grouped"] = CP() * C(l_g * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_g - r_g))^0 * r_g) * CC("group") / progress, + -- ["setup"] = CP() * C(l_s * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_s - r_s))^0 * r_s) * CC("setup") / progress, + -- ["display"] = CP() * C(d_m * (V("whatever") + V("grouped") + (1 - d_m))^0 * d_m) * CC("display") / progress, + -- ["inline"] = CP() * C(i_m * (V("whatever") + V("grouped") + (1 - i_m))^0 * i_m) * CC("inline") / progress, + -- ["errors"] = (V("gerror") + V("serror") + V("derror") + V("ierror")) * true, + -- ["gerror"] = CP() * (l_g + r_g) * CC("grouping") / message, + -- ["serror"] = CP() * (l_s + r_g) * CC("setup error") / message, + -- ["derror"] = CP() * d_m * CC("display math error") / message, + -- ["ierror"] = CP() * i_m * CC("inline math error") / message, + -- } + + local startluacode = P("\\startluacode") + local stopluacode = P("\\stopluacode") + + local somecode = startluacode * (1-stopluacode)^1 * stopluacode + + local grammar = P { "tokens", + ["tokens"] = (V("ignore") + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + V("errors") + 1)^0, + ["whatever"] = line + esc * 1 + C(P("%") * (1-line)^0), + ["grouped"] = l_g * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_g - r_g))^0 * r_g, + ["setup"] = l_s * (okay + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_s - r_s))^0 * r_s, + ["display"] = d_m * (V("whatever") + V("grouped") + (1 - d_m))^0 * d_m, + ["inline"] = i_m * (V("whatever") + V("grouped") + (1 - i_m))^0 * i_m, + ["errors"] = (V("gerror")+ V("serror") + V("derror") + V("ierror")), + ["gerror"] = CP() * (l_g + r_g) * CC("grouping") / message, + ["serror"] = CP() * (l_s + r_g) * CC("setup error") / message, + ["derror"] = CP() * d_m * CC("display math error") / message, + ["ierror"] = CP() * i_m * CC("inline math error") / message, + ["ignore"] = somecode, + } + + function validator.check(str) + validator.n = 1 + validator.errors = { } + grammar:match(str) + end + +end + +--~ str = [[ +--~ a{oeps {oe\{\}ps} } +--~ test { oeps \} \[\] oeps \setupxxx[oeps=bla]} +--~ test $$ \hbox{$ oeps \} \[\] oeps $} $$ +--~ {$x\$xx$ $ +--~ ]] +--~ str = string.rep(str,10) + +function scripts.checker.check(filename) + local str = io.loaddata(filename) + if str then + validator.check(str) + local errors = validator.errors + if #errors > 0 then + for k=1,#errors do + local v = errors[k] + local kind, position, line = v[1], v[2], v[3] + local data = str:sub(position-30,position+30) + data = data:gsub("(.)", { + ["\n"] = " ", + ["\r"] = " ", + ["\t"] = " ", + }) + data = data:gsub("^ *","") + print(string.format("% 5i %s %s", line,string.rpadd(kind,10," "),data)) + end + else + print("no error") + end + else + print("no file") + end +end + +logs.extendbanner("Basic ConTeXt Syntax Checking 0.10",true) + +messages.help = [[ +--convert check tex file for errors +]] + +if environment.argument("check") then + scripts.checker.check(environment.files[1]) +elseif environment.argument("help") then + logs.help(messages.help) +elseif environment.files[1] then + scripts.checker.check(environment.files[1]) +end + diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua new file mode 100644 index 000000000..79e74e407 --- /dev/null +++ b/scripts/context/lua/mtx-context.lua @@ -0,0 +1,1554 @@ +if not modules then modules = { } end modules ['mtx-context'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.context = scripts.context or { } + +-- a demo cld file: +-- +-- context.starttext() +-- context.chapter("Hello There") +-- context.readfile("tufte","","not found") +-- context.stoptext() + +-- l-file / todo + +function file.needsupdate(oldfile,newfile) + return true +end +function file.syncmtimes(oldfile,newfile) +end + +-- l-io + +function io.copydata(fromfile,tofile) + io.savedata(tofile,io.loaddata(fromfile) or "") +end + +-- ctx + +ctxrunner = { } + +do + + function ctxrunner.filtered(str,method) + str = tostring(str) + if method == 'name' then str = file.removesuffix(file.basename(str)) + elseif method == 'path' then str = file.dirname(str) + elseif method == 'suffix' then str = file.extname(str) + elseif method == 'nosuffix' then str = file.removesuffix(str) + elseif method == 'nopath' then str = file.basename(str) + elseif method == 'base' then str = file.basename(str) + -- elseif method == 'full' then + -- elseif method == 'complete' then + -- elseif method == 'expand' then -- str = file.expand_path(str) + end + return str:gsub("\\","/") + end + + function ctxrunner.substitute(e,str) + local attributes = e.at + if str and attributes then + if attributes['method'] then + str = ctxrunner.filtered(str,attributes['method']) + end + if str == "" and attributes['default'] then + str = attributes['default'] + end + end + return str + end + + function ctxrunner.reflag(flags) + local t = { } + for _, flag in next, flags do + local key, value = flag:match("^(.-)=(.+)$") + if key and value then + t[key] = value + else + t[flag] = true + end + end + return t + end + + function ctxrunner.substitute(str) + return str + end + + function ctxrunner.justtext(str) + str = xml.unescaped(tostring(str)) + str = xml.cleansed(str) + str = str:gsub("\\+",'/') + str = str:gsub("%s+",' ') + return str + end + + function ctxrunner.new() + return { + ctxname = "", + jobname = "", + xmldata = nil, + suffix = "prep", + locations = { '..', '../..' }, + variables = { }, + messages = { }, + environments = { }, + modules = { }, + filters = { }, + flags = { }, + modes = { }, + prepfiles = { }, + paths = { }, + } + end + + function ctxrunner.savelog(ctxdata,ctlname) + local function yn(b) + if b then return 'yes' else return 'no' end + end + if not ctlname or ctlname == "" or ctlname == ctxdata.jobname then + if ctxdata.jobname then + ctlname = file.replacesuffix(ctxdata.jobname,'ctl') + elseif ctxdata.ctxname then + ctlname = file.replacesuffix(ctxdata.ctxname,'ctl') + else + logs.simple("invalid ctl name: %s",ctlname or "?") + return + end + end + local prepfiles = ctxdata.prepfiles + if prepfiles and next(prepfiles) then + logs.simple("saving logdata in: %s",ctlname) + f = io.open(ctlname,'w') + if f then + f:write("\n\n") + f:write(string.format("\n",yn(ctxdata.runlocal))) + local sorted = table.sortedkeys(prepfiles) + for i=1,#sorted do + local name = sorted[i] + f:write(string.format("\t%s\n",yn(prepfiles[name]),name)) + end + f:write("\n") + f:close() + end + else + logs.simple("nothing prepared, no ctl file saved") + os.remove(ctlname) + end + end + + function ctxrunner.register_path(ctxdata,path) + -- test if exists + ctxdata.paths[ctxdata.paths+1] = path + end + + function ctxrunner.trace(ctxdata) + print(table.serialize(ctxdata.messages)) + print(table.serialize(ctxdata.flags)) + print(table.serialize(ctxdata.environments)) + print(table.serialize(ctxdata.modules)) + print(table.serialize(ctxdata.filters)) + print(table.serialize(ctxdata.modes)) + print(xml.tostring(ctxdata.xmldata)) + end + + function ctxrunner.manipulate(ctxdata,ctxname,defaultname) + + if not ctxdata.jobname or ctxdata.jobname == "" then + return + end + + ctxdata.ctxname = ctxname or file.removesuffix(ctxdata.jobname) or "" + + if ctxdata.ctxname == "" then + return + end + + ctxdata.jobname = file.addsuffix(ctxdata.jobname,'tex') + ctxdata.ctxname = file.addsuffix(ctxdata.ctxname,'ctx') + + logs.simple("jobname: %s",ctxdata.jobname) + logs.simple("ctxname: %s",ctxdata.ctxname) + + -- mtxrun should resolve kpse: and file: + + local usedname = ctxdata.ctxname + local found = lfs.isfile(usedname) + + if not found then + for _, path in next, ctxdata.locations do + local fullname = file.join(path,ctxdata.ctxname) + if lfs.isfile(fullname) then + usedname, found = fullname, true + break + end + end + end + + usedname = resolvers.find_file(ctxdata.ctxname,"tex") + found = usedname ~= "" + + if not found and defaultname and defaultname ~= "" and lfs.isfile(defaultname) then + usedname, found = defaultname, true + end + + if not found then + return + end + + ctxdata.xmldata = xml.load(usedname) + + if not ctxdata.xmldata then + return + else + -- test for valid, can be text file + end + + xml.include(ctxdata.xmldata,'ctx:include','name', table.append({'.', file.dirname(ctxdata.ctxname)},ctxdata.locations)) + + ctxdata.variables['job'] = ctxdata.jobname + + ctxdata.flags = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:flags/ctx:flag",true) + ctxdata.environments = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:environment",true) + ctxdata.modules = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:module",true) + ctxdata.filters = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:filter",true) + ctxdata.modes = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:mode",true) + ctxdata.messages = xml.collect_texts(ctxdata.xmldata,"ctx:message",true) + + ctxdata.flags = ctxrunner.reflag(ctxdata.flags) + + local messages = ctxdata.messages + for i=1,#messages do + logs.simple("ctx comment: %s", xml.tostring(messages[i])) + end + + for r, d, k in xml.elements(ctxdata.xmldata,"ctx:value[@name='job']") do + d[k] = ctxdata.variables['job'] or "" + end + + local commands = { } + for e in xml.collected(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:processors/ctx:processor") do + commands[e.at and e.at['name'] or "unknown"] = e + end + + local suffix = xml.filter(ctxdata.xmldata,"/ctx:job/ctx:preprocess/attribute('suffix')") or ctxdata.suffix + local runlocal = xml.filter(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:processors/attribute('local')") + + runlocal = toboolean(runlocal) + + for files in xml.collected(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:files") do + for pattern in xml.collected(files,"ctx:file") do + + preprocessor = pattern.at['processor'] or "" + + if preprocessor ~= "" then + + ctxdata.variables['old'] = ctxdata.jobname + for r, d, k in xml.elements(ctxdata.xmldata,"ctx:value") do + local ek = d[k] + local ekat = ek.at['name'] + if ekat == 'old' then + d[k] = ctxrunner.substitute(ctxdata.variables[ekat] or "") + end + end + + pattern = ctxrunner.justtext(xml.tostring(pattern)) + + local oldfiles = dir.glob(pattern) + + local pluspath = false + if #oldfiles == 0 then + -- message: no files match pattern + local paths = ctxdata.paths + for i=1,#paths do + local p = paths[i] + local oldfiles = dir.glob(path.join(p,pattern)) + if #oldfiles > 0 then + pluspath = true + break + end + end + end + if #oldfiles == 0 then + -- message: no old files + else + for i=1,#oldfiles do + local oldfile = oldfiles[i] + local newfile = oldfile .. "." .. suffix -- addsuffix will add one only + if ctxdata.runlocal then + newfile = file.basename(newfile) + end + if oldfile ~= newfile and file.needsupdate(oldfile,newfile) then + -- message: oldfile needs preprocessing + -- os.remove(newfile) + local splitted = preprocessor:split(',') + for i=1,#splitted do + local pp = splitted[i] + local command = commands[pp] + if command then + command = xml.copy(command) + local suf = (command.at and command.at['suffix']) or ctxdata.suffix + if suf then + newfile = oldfile .. "." .. suf + end + if ctxdata.runlocal then + newfile = file.basename(newfile) + end + for r, d, k in xml.elements(command,"ctx:old") do + d[k] = ctxrunner.substitute(oldfile) + end + for r, d, k in xml.elements(command,"ctx:new") do + d[k] = ctxrunner.substitute(newfile) + end + ctxdata.variables['old'] = oldfile + ctxdata.variables['new'] = newfile + for r, d, k in xml.elements(command,"ctx:value") do + local ek = d[k] + local ekat = ek.at and ek.at['name'] + if ekat then + d[k] = ctxrunner.substitute(ctxdata.variables[ekat] or "") + end + end + -- potential optimization: when mtxrun run internal + command = xml.content(command) + command = ctxrunner.justtext(command) + logs.simple("command: %s",command) + local result = os.spawn(command) or 0 + -- somehow we get the wrong return value + if result > 0 then + logs.simple("error, return code: %s",result) + end + if ctxdata.runlocal then + oldfile = file.basename(oldfile) + end + end + end + if lfs.isfile(newfile) then + file.syncmtimes(oldfile,newfile) + ctxdata.prepfiles[oldfile] = true + else + logs.simple("error, check target location of new file: %s", newfile) + ctxdata.prepfiles[oldfile] = false + end + else + logs.simple("old file needs no preprocessing") + ctxdata.prepfiles[oldfile] = lfs.isfile(newfile) + end + end + end + end + end + end + + ctxrunner.savelog(ctxdata) + + end + + function ctxrunner.preppedfile(ctxdata,filename) + if ctxdata.prepfiles[file.basename(filename)] then + return filename .. ".prep" + else + return filename + end + end + +end + +-- rest + +scripts.context.multipass = { +-- suffixes = { ".tuo", ".tuc" }, + suffixes = { ".tuc" }, + nofruns = 8, +} + +function scripts.context.multipass.hashfiles(jobname) + local hash = { } + local suffixes = scripts.context.multipass.suffixes + for i=1,#suffixes do + local suffix = suffixes[i] + local full = jobname .. suffix + hash[full] = md5.hex(io.loaddata(full) or "unknown") + end + return hash +end + +function scripts.context.multipass.changed(oldhash, newhash) + for k,v in next, oldhash do + if v ~= newhash[k] then + return true + end + end + return false +end + +scripts.context.backends = { + pdftex = 'pdftex', + luatex = 'pdftex', + pdf = 'pdftex', + dvi = 'dvipdfmx', + dvips = 'dvips' +} + +function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,currentrun,finalrun) + -- take jobname from ctx + jobname = file.removesuffix(jobname) + local f = io.open(jobname..".top","w") + if f then + local function someflag(flag) + return (ctxdata and ctxdata.flags[flag]) or environment.argument(flag) + end + local function setvalue(flag,format,hash,default) + local a = someflag(flag) or default + if a and a ~= "" then + if hash then + if hash[a] then + f:write(format:format(a),"\n") + end + else + f:write(format:format(a),"\n") + end + end + end + local function setvalues(flag,format,plural) + if type(flag) == "table" then + for k, v in next, flag do + f:write(format:format(v),"\n") + end + else + local a = someflag(flag) or (plural and someflag(flag.."s")) + if a and a ~= "" then + for v in a:gmatch("%s*([^,]+)") do + f:write(format:format(v),"\n") + end + end + end + end + local function setfixed(flag,format,...) + if someflag(flag) then + f:write(format:format(...),"\n") + end + end + local function setalways(format,...) + f:write(format:format(...),"\n") + end + -- + setalways("%% runtime options files (command line driven)") + -- + setalways("\\unprotect") + -- + setalways("%% special commands, mostly for the ctx development team") + -- + if environment.argument("dumpdelta") then + setalways("\\tracersdumpdelta") + elseif environment.argument("dumphash") then + setalways("\\tracersdumphash") + end + setalways("%% feedback and basic job control") + if type(environment.argument("track")) == "string" then + setvalue ("track" , "\\enabletrackers[%s]") + end + if type(environment.argument("trackers")) == "string" then + setvalue ("trackers" , "\\enabletrackers[%s]") + end + if type(environment.argument("directives")) == "string" then + setvalue ("directives", "\\enabledirectives[%s]") + end + setfixed ("timing" , "\\usemodule[timing]") + setfixed ("batchmode" , "\\batchmode") + setfixed ("batch" , "\\batchmode") + setfixed ("nonstopmode" , "\\nonstopmode") + setfixed ("nonstop" , "\\nonstopmode") + setfixed ("tracefiles" , "\\tracefilestrue") + setfixed ("nostats" , "\\nomkivstatistics") + setfixed ("paranoid" , "\\def\\maxreadlevel{1}") + -- + setalways("%% handy for special styles") + -- + setalways("\\startluacode") + setalways("document = document or { }") + setalways(table.serialize(environment.arguments, "document.arguments")) + setalways(table.serialize(environment.files, "document.files")) + setalways("\\stopluacode") + -- + setalways("%% process info") + -- + -- setvalue ("inputfile" , "\\setupsystem[inputfile=%s]") + setalways( "\\setupsystem[inputfile=%s]",environment.argument("input") or environment.files[1] or "\\jobname") + setvalue ("result" , "\\setupsystem[file=%s]") + setalways( "\\setupsystem[\\c!n=%s,\\c!m=%s]", kindofrun or 0, currentrun or 0) + -- setalways( "\\setupsystem[\\c!type=%s]",os.type) -- windows or unix + setvalues("path" , "\\usepath[%s]") + setvalue ("setuppath" , "\\setupsystem[\\c!directory={%s}]") + setvalue ("randomseed" , "\\setupsystem[\\c!random=%s]") + setvalue ("arguments" , "\\setupenv[%s]") + setalways("%% modes") + setvalues("modefile" , "\\readlocfile{%s}{}{}") + setvalues("mode" , "\\enablemode[%s]", true) + if ctxdata then + setvalues(ctxdata.modes, "\\enablemode[%s]") + end + -- + setalways("%% options (not that important)") + -- + setalways("\\startsetups *runtime:options") + setvalue ('output' , "\\setupoutput[%s]", scripts.context.backends, 'pdftex') + setfixed ("color" , "\\setupcolors[\\c!state=\\v!start]") + setvalue ("separation" , "\\setupcolors[\\c!split=%s]") + setfixed ("noarrange" , "\\setuparranging[\\v!disable]") + if environment.argument('arrange') and not finalrun then + setalways( "\\setuparranging[\\v!disable]") + end + setalways("\\stopsetups") + -- + setalways("%% styles and modules") + -- + setalways("\\startsetups *runtime:modules") + setvalues("filter" , "\\useXMLfilter[%s]", true) + setvalues("usemodule" , "\\usemodule[%s]", true) + setvalues("environment" , "\\environment %s ", true) + if ctxdata then + setvalues(ctxdata.modules, "\\usemodule[%s]") + setvalues(ctxdata.environments, "\\environment %s ") + end + setalways("\\stopsetups") + -- + setalways("%% done") + -- + setalways("\\protect \\endinput") + f:close() + end +end + +function scripts.context.multipass.copyluafile(jobname) +-- io.savedata(jobname..".tuc",io.loaddata(jobname..".tua") or "") + local tuaname, tucname = jobname..".tua", jobname..".tuc" + if lfs.isfile(tuaname) then + os.remove(tucname) + os.rename(tuaname,tucname) + end +end + +-- obsolete: +-- +-- function scripts.context.multipass.copytuifile(jobname) +-- local tuiname, tuoname = jobname .. ".tui", jobname .. ".tuo" +-- if lfs.isfile(tuiname) then +-- local f, g = io.open(tuiname), io.open(tuoname,'w') +-- if f and g then +-- g:write("% traditional utility file, only commands written by mtxrun/context\n%\n") +-- for line in f:lines() do +-- if line:find("^c ") then +-- g:write((line:gsub("^c ","")),"%\n") +-- end +-- end +-- g:write("\\endinput\n") +-- f:close() +-- g:close() +-- end +-- else +-- -- os.remove(tuoname) +-- end +-- end + +scripts.context.cldsuffixes = table.tohash { + "cld", +} + +scripts.context.xmlsuffixes = table.tohash { + "xml", +} + +scripts.context.luasuffixes = table.tohash { + "lua", +} + +scripts.context.beforesuffixes = { + "tuo", "tuc" +} +scripts.context.aftersuffixes = { + "pdf", "tuo", "tuc", "log" +} + +scripts.context.interfaces = { + en = "cont-en", + uk = "cont-uk", + de = "cont-de", + fr = "cont-fr", + nl = "cont-nl", + cz = "cont-cz", + it = "cont-it", + ro = "cont-ro", + pe = "cont-pe", +} + +scripts.context.defaultformats = { + "cont-en", + "cont-nl", + "mptopdf", +-- "metatex", + "metafun", +-- "plain" +} + +local function analyze(filename) + local f = io.open(file.addsuffix(filename,"tex")) + if f then + local t = { } + local line = f:read("*line") or "" + local preamble = line:match("[\254\255]*%%%s+(.+)$") -- there can be an utf bomb in front + if preamble then + for key, value in preamble:gmatch("(%S+)=(%S+)") do + t[key] = value + end + t.type = "tex" + elseif line:find("^&1', file.replacesuffix(name,"pdf"))) +--~ end +--~ function scripts.context.closepdf(name) +--~ os.spawn(string.format('pdfclose --file "%s" 2>&1', file.replacesuffix(name,"pdf"))) +--~ end + +local pdfview -- delayed loading + +function scripts.context.openpdf(name) + pdfview = pdfview or dofile(resolvers.find_file("l-pdfview.lua","tex")) + logs.simple("pdfview methods: %s, current method: %s, MTX_PDFVIEW_METHOD=%s",pdfview.methods(),pdfview.method,os.getenv(pdfview.METHOD) or "") + pdfview.open(file.replacesuffix(name,"pdf")) +end + +function scripts.context.closepdf(name) + pdfview = pdfview or dofile(resolvers.find_file("l-pdfview.lua","tex")) + pdfview.close(file.replacesuffix(name,"pdf")) +end + +function scripts.context.run(ctxdata,filename) + -- filename overloads environment.files + local files = (filename and { filename }) or environment.files + if ctxdata then + -- todo: interface + for k,v in next, ctxdata.flags do + environment.setargument(k,v) + end + end + if #files > 0 then + -- + local interface = environment.argument("interface") + -- todo: environment.argument("interface","en") + interface = (type(interface) == "string" and interface) or "en" + -- + local formatname = scripts.context.interfaces[interface] or "cont-en" + local formatfile, scriptfile = resolvers.locate_format(formatname) + -- this catches the command line + if not formatfile or not scriptfile then + logs.simple("warning: no format found, forcing remake (commandline driven)") + scripts.context.generate() + scripts.context.make(formatname) + formatfile, scriptfile = resolvers.locate_format(formatname) + end + -- + if formatfile and scriptfile then + for i=1,#files do + local filename = files[i] + local basename, pathname = file.basename(filename), file.dirname(filename) + local jobname = file.removesuffix(basename) + if pathname == "" then + filename = "./" .. filename + end + -- look at the first line + local a = analyze(filename) + if a and (a.engine == 'pdftex' or a.engine == 'xetex' or environment.argument("pdftex") or environment.argument("xetex")) then + if false then + -- we need to write a top etc too and run mp etc so it's not worth the + -- trouble, so it will take a while before the next is finished + -- + -- require "mtx-texutil.lua" + else + local texexec = resolvers.find_file("texexec.rb") or "" + if texexec ~= "" then + os.setenv("RUBYOPT","") + local command = string.format("ruby %s %s",texexec,environment.reconstruct_commandline(environment.arguments_after)) + os.exec(command) + end + end + else + if a and a.interface and a.interface ~= interface then + formatname = scripts.context.interfaces[a.interface] or formatname + formatfile, scriptfile = resolvers.locate_format(formatname) + end + -- this catches the command line + if not formatfile or not scriptfile then + logs.simple("warning: no format found, forcing remake (source driven)") + scripts.context.generate() + scripts.context.make(formatname) + formatfile, scriptfile = resolvers.locate_format(formatname) + end + if formatfile and scriptfile then + -- we default to mkiv xml ! + -- the --prep argument might become automatic (and noprep) + local suffix = file.extname(filename) or "?" + if scripts.context.xmlsuffixes[suffix] or environment.argument("forcexml") then + if environment.argument("mkii") then + filename = makestub("\\processXMLfilegrouped{%s}",filename) + else + filename = makestub("\\xmlprocess{\\xmldocument}{%s}{}",filename) + end + elseif scripts.context.cldsuffixes[suffix] or environment.argument("forcecld") then + filename = makestub("\\ctxlua{context.runfile('%s')}",filename) + elseif scripts.context.luasuffixes[suffix] or environment.argument("forcelua") then + filename = makestub("\\ctxlua{dofile('%s')}",filename) + elseif environment.argument("prep") then + -- we need to keep the original jobname + filename = makestub("\\readfile{%s}{}{}",filename,ctxrunner.preppedfile(ctxdata,filename)) + end + -- + -- todo: also other stubs + -- + local suffix, resultname = environment.argument("suffix"), environment.argument("result") + if type(suffix) == "string" then + resultname = file.removesuffix(jobname) .. suffix + end + local oldbase, newbase = "", "" + if type(resultname) == "string" then + oldbase = file.removesuffix(jobname) + newbase = file.removesuffix(resultname) + if oldbase ~= newbase then + for _, suffix in next, scripts.context.beforesuffixes do + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) + local tmpname = "keep-"..oldname + os.remove(tmpname) + os.rename(oldname,tmpname) + os.remove(oldname) + os.rename(newname,oldname) + end + else + resultname = nil + end + else + resultname = nil + end + -- + if environment.argument("autopdf") then + scripts.context.closepdf(filename) + if resultname then + scripts.context.closepdf(resultname) + end + end + -- + local okay = statistics.check_fmt_status(formatfile) + if okay ~= true then + logs.simple("warning: %s, forcing remake",tostring(okay)) + scripts.context.generate() + scripts.context.make(formatname) + end + -- + local flags = { } + if environment.argument("batchmode") or environment.argument("batch") then + flags[#flags+1] = "--interaction=batchmode" + end + if environment.argument("synctex") then + logs.simple("warning: syntex is enabled") -- can add upto 5% runtime + flags[#flags+1] = "--synctex=1" + end + flags[#flags+1] = "--fmt=" .. string.quote(formatfile) + flags[#flags+1] = "--lua=" .. string.quote(scriptfile) + flags[#flags+1] = "--backend=pdf" + local command = string.format("luatex %s %s", table.concat(flags," "), string.quote(filename)) + local oldhash, newhash = scripts.context.multipass.hashfiles(jobname), { } + local once = environment.argument("once") + local maxnofruns = (once and 1) or scripts.context.multipass.nofruns + local arrange = environment.argument("arrange") + for i=1,maxnofruns do + -- 1:first run, 2:successive run, 3:once, 4:last of maxruns + local kindofrun = (once and 3) or (i==1 and 1) or (i==maxnofruns and 4) or 2 + scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,false) -- kindofrun, currentrun, final + logs.simple("run %s: %s",i,command) + local returncode, errorstring = os.spawn(command) + --~ if returncode == 3 then + --~ scripts.context.generate() + --~ scripts.context.make(formatname) + --~ returncode, errorstring = os.spawn(command) + --~ if returncode == 3 then + --~ logs.simple("ks: return code 3, message: %s",errorstring or "?") + --~ os.exit(1) + --~ end + --~ end + if not returncode then + logs.simple("fatal error: no return code, message: %s",errorstring or "?") + os.exit(1) + break + elseif returncode > 0 then + logs.simple("fatal error: return code: %s",returncode or "?") + os.exit(returncode) + break + else + scripts.context.multipass.copyluafile(jobname) + -- scripts.context.multipass.copytuifile(jobname) + newhash = scripts.context.multipass.hashfiles(jobname) + if scripts.context.multipass.changed(oldhash,newhash) then + oldhash = newhash + else + break + end + end + end + -- + if arrange then + local kindofrun = 3 + scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,true) -- kindofrun, currentrun, final + logs.simple("arrange run: %s",command) + local returncode, errorstring = os.spawn(command) + if not returncode then + logs.simple("fatal error: no return code, message: %s",errorstring or "?") + os.exit(1) + elseif returncode > 0 then + logs.simple("fatal error: return code: %s",returncode or "?") + os.exit(returncode) + end + end + -- + if environment.argument("purge") then + scripts.context.purge_job(jobname) + elseif environment.argument("purgeall") then + scripts.context.purge_job(jobname,true) + end + -- + os.remove(jobname..".top") + -- + if resultname then + for _, suffix in next, scripts.context.aftersuffixes do + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) + local tmpname = "keep-"..oldname + os.remove(newname) + os.rename(oldname,newname) + os.rename(tmpname,oldname) + end + logs.simple("result renamed to: %s",newbase) + end + -- + if environment.argument("purge") then + scripts.context.purge_job(resultname) + elseif environment.argument("purgeall") then + scripts.context.purge_job(resultname,true) + end + -- + if environment.argument("autopdf") then + scripts.context.openpdf(resultname or filename) + end + -- + if environment.argument("timing") then + logs.line() + logs.simple("you can process (timing) statistics with:",jobname) + logs.line() + logs.simple("context --extra=timing '%s'",jobname) + logs.simple("mtxrun --script timing --xhtml [--launch --remove] '%s'",jobname) + logs.line() + end + else + if formatname then + logs.simple("error, no format found with name: %s, skipping",formatname) + else + logs.simple("error, no format found (provide formatname or interface)") + end + break + end + end + end + else + if formatname then + logs.simple("error, no format found with name: %s, aborting",formatname) + else + logs.simple("error, no format found (provide formatname or interface)") + end + end + end +end + +function scripts.context.pipe() + -- context --pipe + -- context --pipe --purge --dummyfile=whatever.tmp + local interface = environment.argument("interface") + interface = (type(interface) == "string" and interface) or "en" + local formatname = scripts.context.interfaces[interface] or "cont-en" + local formatfile, scriptfile = resolvers.locate_format(formatname) + if not formatfile or not scriptfile then + logs.simple("warning: no format found, forcing remake (commandline driven)") + scripts.context.generate() + scripts.context.make(formatname) + formatfile, scriptfile = resolvers.locate_format(formatname) + end + if formatfile and scriptfile then + local okay = statistics.check_fmt_status(formatfile) + if okay ~= true then + logs.simple("warning: %s, forcing remake",tostring(okay)) + scripts.context.generate() + scripts.context.make(formatname) + end + local flags = { + "--interaction=scrollmode", + "--fmt=" .. string.quote(formatfile), + "--lua=" .. string.quote(scriptfile), + "--backend=pdf", + } + local filename = environment.argument("dummyfile") or "" + if filename == "" then + filename = "\\relax" + logs.simple("entering scrollmode, end job with \\end") + else + filename = file.addsuffix(filename,"tmp") + io.savedata(filename,"\\relax") + scripts.context.multipass.makeoptionfile(filename,{ flags = flags },3,1,false) -- kindofrun, currentrun, final + logs.simple("entering scrollmode using '%s' with optionfile, end job with \\end",filename) + end + local command = string.format("luatex %s %s", table.concat(flags," "), string.quote(filename)) + os.spawn(command) + if environment.argument("purge") then + scripts.context.purge_job(filename) + elseif environment.argument("purgeall") then + scripts.context.purge_job(filename,true) + os.remove(filename) + end + else + if formatname then + logs.simple("error, no format found with name: %s, aborting",formatname) + else + logs.simple("error, no format found (provide formatname or interface)") + end + end +end + +function scripts.context.make(name) + local runners = { + "luatools --make --compile ", + (environment.argument("pdftex") and "mtxrun texexec.rb --make --pdftex ") or false, + (environment.argument("xetex") and "mtxrun texexec.rb --make --xetex " ) or false, + } + local list = (name and { name }) or (environment.files[1] and environment.files) or scripts.context.defaultformats + for i=1,#list do + local name = list[i] + name = scripts.context.interfaces[name] or name + for i=1,#runners do + local runner = runners[i] + if runner then + local command = runner .. name + logs.simple("running command: %s",command) + os.spawn(command) + end + end + end +end + +function scripts.context.generate() + -- hack, should also be a shared function + local command = "luatools --generate " + logs.simple("running command: %s",command) + os.spawn(command) +end + +function scripts.context.ctx() + local ctxdata = ctxrunner.new() + ctxdata.jobname = environment.files[1] + ctxrunner.manipulate(ctxdata,environment.argument("ctx")) + scripts.context.run(ctxdata) +end + +function scripts.context.autoctx() + local ctxdata = nil + local files = (filename and { filename }) or environment.files + local firstfile = #files > 0 and files[1] + if firstfile and file.extname(firstfile) == "xml" then + local f = io.open(firstfile) + if f then + local chunk = f:read(512) or "" + f:close() + local ctxname = string.match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>") + if ctxname then + ctxdata = ctxrunner.new() + ctxdata.jobname = firstfile + ctxrunner.manipulate(ctxdata,ctxname) + end + end + end + scripts.context.run(ctxdata) +end + +-- todo: quite after first image + +local template = [[ + \starttext + \startMPpage %% %s + input "%s" ; + \stopMPpage + \stoptext +]] + +local loaded = false + +function scripts.context.metapost() + local filename = environment.files[1] or "" + if not loaded then + dofile(resolvers.find_file("mlib-run.lua")) + loaded = true + commands = commands or { } + commands.writestatus = logs.report + end + local formatname = environment.argument("format") or "metafun" + if formatname == "" or type(format) == "boolean" then + formatname = "metafun" + end + if environment.argument("pdf") then + local basename = file.removesuffix(filename) + local resultname = environment.argument("result") or basename + local jobname = "mtx-context-metapost" + local tempname = file.addsuffix(jobname,"tex") + io.savedata(tempname,string.format(template,"metafun",filename)) + environment.files[1] = tempname + environment.setargument("result",resultname) + environment.setargument("once",true) + scripts.context.run() + scripts.context.purge_job(jobname,true) + scripts.context.purge_job(resultname,true) + elseif environment.argument("svg") then + metapost.directrun(formatname,filename,"svg") + else + metapost.directrun(formatname,filename,"mps") + end +end + +function scripts.context.version() + local name = resolvers.find_file("context.tex") + if name ~= "" then + logs.simple("main context file: %s",name) + local data = io.loaddata(name) + if data then + local version = data:match("\\edef\\contextversion{(.-)}") + if version then + logs.simple("current version: %s",version) + else + logs.simple("context version: unknown, no timestamp found") + end + else + logs.simple("context version: unknown, load error") + end + else + logs.simple("main context file: unknown, 'context.tex' not found") + end +end + +local generic_files = { + "texexec.tex", "texexec.tui", "texexec.tuo", + "texexec.tuc", "texexec.tua", + "texexec.ps", "texexec.pdf", "texexec.dvi", + "cont-opt.tex", "cont-opt.bak" +} + +local obsolete_results = { + "dvi", +} + +local temporary_runfiles = { + "tui", "tua", "tup", "ted", "tes", "top", + "log", "tmp", "run", "bck", "rlg", + "mpt", "mpx", "mpd", "mpo", "mpb", "ctl", + "synctex.gz", "pgf" +} + +local persistent_runfiles = { + "tuo", "tub", "top", "tuc" +} + +local function purge_file(dfile,cfile) + if cfile and lfs.isfile(cfile) then + if os.remove(dfile) then + return file.basename(dfile) + end + elseif dfile then + if os.remove(dfile) then + return file.basename(dfile) + end + end +end + +function scripts.context.purge_job(jobname,all) + if jobname and jobname ~= "" then + jobname = file.basename(jobname) + local filebase = file.removesuffix(jobname) + local deleted = { } + for i=1,#obsolete_results do + deleted[#deleted+1] = purge_file(filebase.."."..obsolete_results[i],filebase..".pdf") + end + for i=1,#temporary_runfiles do + deleted[#deleted+1] = purge_file(filebase.."."..temporary_runfiles[i]) + end + if all then + for i=1,#persistent_runfiles do + deleted[#deleted+1] = purge_file(filebase.."."..persistent_runfiles[i]) + end + end + if #deleted > 0 then + logs.simple("purged files: %s", table.join(deleted,", ")) + end + end +end + +function scripts.context.purge(all) + local all = all or environment.argument("all") + local pattern = environment.argument("pattern") or "*.*" + local files = dir.glob(pattern) + local obsolete = table.tohash(obsolete_results) + local temporary = table.tohash(temporary_runfiles) + local persistent = table.tohash(persistent_runfiles) + local generic = table.tohash(generic_files) + local deleted = { } + for i=1,#files do + local name = files[i] + local suffix = file.extname(name) + local basename = file.basename(name) + if obsolete[suffix] or temporary[suffix] or persistent[suffix] or generic[basename] then + deleted[#deleted+1] = purge_file(name) + end + end + if #deleted > 0 then + logs.simple("purged files: %s", table.join(deleted,", ")) + end +end + +--~ purge_for_files("test",true) +--~ purge_all_files() + +local function touch(name,pattern) + local name = resolvers.find_file(name) + local olddata = io.loaddata(name) + if olddata then + local oldversion, newversion = "", os.date("%Y.%m.%d %H:%M") + local newdata, ok = olddata:gsub(pattern,function(pre,mid,post) + oldversion = mid + return pre .. newversion .. post + end) + if ok > 0 then + local backup = file.replacesuffix(name,"tmp") + os.remove(backup) + os.rename(name,backup) + io.savedata(name,newdata) + return true, oldversion, newversion, name + else + return false + end + end +end + +function scripts.context.touch() + if environment.argument("expert") then + local done, oldversion, newversion, foundname = touch("context.tex", "(\\edef\\contextversion{)(.-)(})") + if done then + logs.simple("old version : %s", oldversion) + logs.simple("new version : %s", newversion) + logs.simple("touched file: %s", foundname) + local ok, _, _, foundname = touch("cont-new.tex", "(\\newcontextversion{)(.-)(})") + if ok then + logs.simple("touched file: %s", foundname) + end + local ok, _, _, foundname = touch("cont-xp.tex", "(\\edef\\contextversion{)(.-)(})") + if ok then + logs.simple("touched file: %s", foundname) + end + end + end +end + +-- extras + +function scripts.context.extras(pattern) + local found = resolvers.find_file("context.tex") + if found == "" then + logs.simple("unknown extra: %s", extra) + else + pattern = file.join(dir.expand_name(file.dirname(found)),string.format("mtx-context-%s.tex",pattern or "*")) + local list = dir.glob(pattern) + if not extra or extra == "" then + logs.extendbanner("extras") + else + logs.extendbanner(extra) + end + for i=1,#list do + local v = list[i] + local data = io.loaddata(v) or "" + data = string.match(data,"begin help(.-)end help") + if data then + local h = { string.format("extra: %s (%s)",string.gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1"),v) } + for s in string.gmatch(data,"%% *(.-)[\n\r]") do + h[#h+1] = s + end + h[#h+1] = "" + logs.help(table.concat(h,"\n"),"nomoreinfo") + end + end + end +end + +function scripts.context.extra() + local extra = environment.argument("extra") + if type(extra) == "string" then + if environment.argument("help") then + scripts.context.extras(extra) + else + local fullextra = extra + if not string.find(fullextra,"mtx%-context%-") then + fullextra = "mtx-context-" .. extra + end + local foundextra = resolvers.find_file(fullextra) + if foundextra == "" then + scripts.context.extras() + return + else + logs.simple("processing extra: %s", foundextra) + end + environment.setargument("purgeall",true) + local result = environment.setargument("result") or "" + if result == "" then + environment.setargument("result","context-extra") + end + scripts.context.run(nil,foundextra) + end + else + scripts.context.extras() + end +end + +-- todo: we need to do a dummy run + +function scripts.context.trackers() + environment.files = { resolvers.find_file("m-trackers.tex") } + scripts.context.multipass.nofruns = 1 + scripts.context.run() + -- maybe filter from log +end + +function scripts.context.directives() + environment.files = { resolvers.find_file("m-directives.tex") } + scripts.context.multipass.nofruns = 1 + scripts.context.run() + -- maybe filter from log +end + +function scripts.context.timed(action) + statistics.timed(action) +end + +local zipname = "cont-tmf.zip" +local mainzip = "http://www.pragma-ade.com/context/latest/" .. zipname +local validtrees = { "texmf-local", "texmf-context" } + +function zip.loaddata(zipfile,filename) -- should be in zip lib + local f = zipfile:open(filename) + if f then + local data = f:read("*a") + f:close() + return data + end + return nil +end + +function scripts.context.update() + local force = environment.argument("force") + local socket = require("socket") + local http = require("socket.http") + local basepath = resolvers.find_file("context.tex") or "" + if basepath == "" then + logs.simple("quiting, no 'context.tex' found") + return + end + local basetree = basepath.match(basepath,"^(.-)tex/context/base/context.tex$") or "" + if basetree == "" then + logs.simple("quiting, no proper tds structure (%s)",basepath) + return + end + local function is_okay(basetree) + for _, tree in next, validtrees do + local pattern = string.gsub(tree,"%-","%%-") + if basetree:find(pattern) then + return tree + end + end + return false + end + local okay = is_okay(basetree) + if not okay then + logs.simple("quiting, tree '%s' is protected",okay) + return + else + logs.simple("updating tree '%s'",okay) + end + if not lfs.chdir(basetree) then + logs.simple("quiting, unable to change to '%s'",okay) + return + end + logs.simple("fetching '%s'",mainzip) + local latest = http.request(mainzip) + if not latest then + logs.simple("context tree '%s' can be updated, use --force",okay) + return + end + io.savedata("cont-tmf.zip",latest) + if false then + -- variant 1 + os.execute("mtxrun --script unzip cont-tmf.zip") + else + -- variant 2 + local zipfile = zip.open(zipname) + if not zipfile then + logs.simple("quiting, unable to open '%s'",zipname) + return + end + local newfile = zip.loaddata(zipfile,"tex/context/base/context.tex") + if not newfile then + logs.simple("quiting, unable to open '%s'","context.tex") + return + end + local oldfile = io.loaddata(resolvers.find_file("context.tex")) or "" + local function versiontonumber(what,str) + local version = str:match("\\edef\\contextversion{(.-)}") or "" + local year, month, day, hour, minute = str:match("\\edef\\contextversion{(%d+)%.(%d+)%.(%d+) *(%d+)%:(%d+)}") + if year and minute then + local time = os.time { year=year,month=month,day=day,hour=hour,minute=minute} + logs.simple("%s version: %s (%s)",what,version,time) + return time + else + logs.simple("%s version: %s (unknown)",what,version) + return nil + end + end + local oldversion = versiontonumber("old",oldfile) + local newversion = versiontonumber("new",newfile) + if not oldversion or not newversion then + logs.simple("quiting, version cannot be determined") + return + elseif oldversion == newversion then + logs.simple("quiting, your current version is up-to-date") + return + elseif oldversion > newversion then + logs.simple("quiting, your current version is newer") + return + end + for k in zipfile:files() do + local filename = k.filename + if filename:find("/$") then + lfs.mkdir(filename) + else + local data = zip.loaddata(zipfile,filename) + if data then + if force then + io.savedata(filename,data) + end + logs.simple(filename) + end + end + end + for _, scriptname in next, { "luatools.lua", "mtxrun.lua" } do + local oldscript = resolvers.find_file(scriptname) or "" + if oldscript ~= "" and is_okay(oldscript) then + local newscript = "./scripts/context/lua/" .. scriptname + local data = io.loaddata(newscript) or "" + if data ~= "" then + logs.simple("replacing script '%s' by '%s'",oldscript,newscript) + if force then + io.savedata(oldscript,data) + end + end + else + logs.simple("keeping script '%s'",oldscript) + end + end + if force then + os.execute("context --generate") + os.execute("context --make") + end + end + if force then + logs.simple("context tree '%s' has been updated",okay) + else + logs.simple("context tree '%s' can been updated (use --force)",okay) + end +end + +logs.extendbanner("ConTeXt Process Management 0.51",true) + +messages.help = [[ +--run process (one or more) files (default action) +--make create context formats + +--ctx=name use ctx file (process management specification) +--interface use specified user interface (default: en) + +--autopdf close pdf file in viewer and start pdf viewer afterwards +--purge(all) purge files either or not after a run (--pattern=...) + +--usemodule=list load the given module or style, normally part o fthe distribution +--environment=list load the given environment file first (document styles) +--mode=list enable given the modes (conditional processing in styles) +--path=list also consult the given paths when files are looked for +--arguments=list set variables that can be consulted during a run (key/value pairs) +--randomseed=number set the randomseed +--result=name rename the resulting output to the given name +--trackers=list show/set tracker variables +--directives=list show/set directive variables + +--forcexml force xml stub (optional flag: --mkii) +--forcecld force cld (context lua document) stub + +--arrange run extra imposition pass, given that the style sets up imposition +--noarrange ignore imposition specifications in the style + +--once only run once (no multipass data file is produced) +--batchmode run without stopping and don't show messages on the console +--nonstopmode run without stopping + +--generate generate file database etc. (as luatools does) +--paranoid don't descend to .. and ../.. +--version report installed context version + +--expert expert options +]] + +-- filter=list is kind of obsolete +-- color is obsolete for mkiv, always on +-- separation is obsolete for mkiv, no longer available +-- output is currently obsolete for mkiv +-- setuppath=list must check +-- modefile=name must check +-- input=name load the given inputfile (must check) + +messages.expert = [[ +expert options: + +--touch update context version number (remake needed afterwards, also provide --expert) +--nostats omit runtime statistics at the end of the run +--update update context from website (not to be confused with contextgarden) +--profile profile job (use: mtxrun --script profile --analyse) +--timing generate timing and statistics overview +--tracefiles show some extra info when locating files (at the tex end) + +--extra=name process extra (mtx-context- in distribution) +--extras show extras +]] + +messages.private = [[ +private options: + +--dumphash dump hash table afterwards +--dumpdelta dump hash table afterwards (only new entries) +]] + +messages.special = [[ +special options: + +--pdftex process file with texexec using pdftex +--xetex process file with texexec using xetex + +--pipe don't check for file and enter scroll mode (--dummyfile=whatever.tmp) +]] + +if environment.argument("once") then + scripts.context.multipass.nofruns = 1 +elseif environment.argument("runs") then + scripts.context.multipass.nofruns = tonumber(environment.argument("runs")) or nil +end + +if environment.argument("profile") then + os.setenv("MTX_PROFILE_RUN","YES") +end + +if environment.argument("run") then +-- scripts.context.timed(scripts.context.run) + scripts.context.timed(scripts.context.autoctx) +elseif environment.argument("make") or environment.argument("generate") then + scripts.context.timed(function() + if environment.argument("generate") then + scripts.context.generate() + end + if environment.argument("make") then + scripts.context.make() + end + end) +elseif environment.argument("ctx") then + scripts.context.timed(scripts.context.ctx) +elseif environment.argument("mp") or environment.argument("metapost") then + scripts.context.timed(scripts.context.metapost) +elseif environment.argument("version") then + scripts.context.version() +elseif environment.argument("touch") then + scripts.context.touch() +elseif environment.argument("update") then + scripts.context.update() +elseif environment.argument("expert") then + logs.help(table.join({ messages.expert, messages.private, messages.special },"\n")) +elseif environment.argument("extras") then + scripts.context.extras() +elseif environment.argument("extra") then + scripts.context.extra() +elseif environment.argument("help") then + if environment.files[1] == "extras" then + scripts.context.extras() + else + logs.help(messages.help) + end +elseif environment.argument("trackers") and type(environment.argument("trackers")) == "boolean" then + scripts.context.trackers() +elseif environment.argument("directives") and type(environment.argument("directives")) == "boolean" then + scripts.context.directives() +elseif environment.argument("track") and type(environment.argument("track")) == "boolean" then -- for old times sake, will go + scripts.context.trackers() +elseif environment.files[1] then +-- scripts.context.timed(scripts.context.run) + scripts.context.timed(scripts.context.autoctx) +elseif environment.argument("pipe") then + scripts.context.timed(scripts.context.pipe) +elseif environment.argument("purge") then + -- only when no filename given, supports --pattern + scripts.context.purge() +elseif environment.argument("purgeall") then + -- only when no filename given, supports --pattern + scripts.context.purge(true) +else + logs.help(messages.help) +end + +if environment.argument("profile") then + os.setenv("MTX_PROFILE_RUN","NO") +end diff --git a/scripts/context/lua/mtx-convert.lua b/scripts/context/lua/mtx-convert.lua new file mode 100644 index 000000000..62198a621 --- /dev/null +++ b/scripts/context/lua/mtx-convert.lua @@ -0,0 +1,139 @@ +if not modules then modules = { } end modules ['mtx-convert'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: eps and svg + +graphics = graphics or { } +graphics.converters = graphics.converters or { } + +local gsprogram = (os.type == "windows" and "gswin32c") or "gs" +local gstemplate = "%s -q -sDEVICE=pdfwrite -dEPSCrop -dNOPAUSE -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit" + +function graphics.converters.eps(oldname,newname) + return gstemplate:format(gsprogram,newname,oldname) +end + +local improgram = "convert" +local imtemplate = { + low = "%s -quality 0 -compress zip %s pdf:%s", + medium = "%s -quality 75 -compress zip %s pdf:%s", + high = "%s -quality 100 -compress zip %s pdf:%s", +} + +function graphics.converters.jpg(oldname,newname) + local ea = environment.arguments + local quality = (ea.high and 'high') or (ea.medium and 'medium') or (ea.low and 'low') or 'high' + return imtemplate[quality]:format(improgram,oldname,newname) +end + +graphics.converters.gif = graphics.converters.jpg +graphics.converters.tif = graphics.converters.jpg +graphics.converters.tiff = graphics.converters.jpg +graphics.converters.png = graphics.converters.jpg + +local function convert(kind,oldname,newname) + if graphics.converters[kind] then -- extra test + local tmpname = file.replacesuffix(newname,"tmp") + local command = graphics.converters[kind](oldname,tmpname) + logs.simple("command: %s",command) + io.flush() + os.spawn(command) + os.remove(newname) + os.rename(tmpname,newname) + if lfs.attributes(newname,"size") == 0 then + os.remove(newname) + end + end +end + +function graphics.converters.convertpath(inputpath,outputpath) + inputpath = inputpath or "." + outputpath = outputpath or "." + for name in lfs.dir(inputpath) do + local suffix = file.extname(name) + if name:find("%.$") then + -- skip . and .. + elseif graphics.converters[suffix] then + local oldname = file.join(inputpath,name) + local newname = file.join(outputpath,file.replacesuffix(name,"pdf")) + local et = lfs.attributes(oldname,"modification") + local pt = lfs.attributes(newname,"modification") + if not pt or et > pt then + dir.mkdirs(outputpath) + convert(suffix,oldname,newname) + end + elseif lfs.isdir(inputpath .. "/".. name) then + graphics.converters.convertpath(inputpath .. "/".. name,outputpath .. "/".. name) + end + end +end + +function graphics.converters.convertfile(oldname) + local suffix = file.extname(oldname) + if graphics.converters[suffix] then + local newname = file.replacesuffix(name,"pdf") + if oldname == newname then + -- todo: downsample, crop etc + elseif environment.argument("force") then + convert(suffix,oldname,newname) + else + local et = lfs.attributes(oldname,"modification") + local pt = lfs.attributes(newname,"modification") + if not pt or et > pt then + convert(suffix,oldname,newname) + end + end + end +end + +scripts = scripts or { } +scripts.convert = scripts.convert or { } + +scripts.convert.delay = 5 * 60 -- 5 minutes + +function scripts.convert.convertall() + local watch = environment.arguments.watch or false + local delay = environment.arguments.delay or scripts.convert.delay + local input = environment.arguments.inputpath or "." + local output = environment.arguments.outputpath or "." + while true do + graphics.converters.convertpath(input, output) + if watch then + os.sleep(delay) + else + break + end + end +end + +function scripts.convert.convertgiven() + local files = environment.files + for i=1,#files do + graphics.converters.convertfile(files[i]) + end +end + + +logs.extendbanner("ConTeXT Graphic Conversion Helpers 0.10",true) + +messages.help = [[ +--convertall convert all graphics on path +--inputpath=string original graphics path +--outputpath=string converted graphics path +--watch watch folders +--force force conversion (even if older) +--delay time between sweeps +]] + +if environment.argument("convertall") then + scripts.convert.convertall() +elseif environment.files[1] then + scripts.convert.convertgiven() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua new file mode 100644 index 000000000..74012ae38 --- /dev/null +++ b/scripts/context/lua/mtx-fonts.lua @@ -0,0 +1,345 @@ +if not modules then modules = { } end modules ['mtx-fonts'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not fontloader then fontloader = fontforge end + +dofile(resolvers.find_file("font-otp.lua","tex")) +dofile(resolvers.find_file("font-syn.lua","tex")) +dofile(resolvers.find_file("font-mis.lua","tex")) + +scripts = scripts or { } +scripts.fonts = scripts.fonts or { } + +function fonts.names.simple() + local simpleversion = 1.001 + local simplelist = { "ttf", "otf", "ttc", "dfont" } + local name = "luatex-fonts-names.lua" + fonts.names.filters.list = simplelist + fonts.names.version = simpleversion -- this number is the same as in font-dum.lua + logs.report("fontnames","generating font database for 'luatex-fonts' version %s",fonts.names.version) + fonts.names.identify(true) + local data = fonts.names.data + if data then + local simplemappings = { } + local simplified = { + mappings = simplemappings, + version = simpleversion, + } + local specifications = data.specifications + for i=1,#simplelist do + local format = simplelist[i] + for tag, index in next, data.mappings[format] do + local s = specifications[index] + simplemappings[tag] = { s.rawname, s.filename, s.subfont } + end + end + logs.report("fontnames","saving names in '%s'",name) + io.savedata(name,table.serialize(simplified,true)) + local data = io.loaddata(resolvers.find_file("font-dum.lua","tex")) + local dummy = string.match(data,"fonts%.names%.version%s*=%s*([%d%.]+)") + if tonumber(dummy) ~= simpleversion then + logs.report("fontnames","warning: version number %s in 'font-dum' does not match database version number %s",dummy or "?",simpleversion) + end + elseif lfs.isfile(name) then + os.remove(name) + end +end + +function scripts.fonts.reload() + if environment.argument("simple") then + fonts.names.simple() + else + fonts.names.load(true) + end +end + +local function subfont(sf) + if sf then + return string.format("index: % 2s", sf) + else + return "" + end +end + +local function fontweight(fw) + if fw then + return string.format("conflict: %s", fw) + else + return "" + end +end + +local function showfeatures(tag,specification) + logs.simple("mapping : %s",tag) + logs.simple("fontname: %s",specification.fontname) + logs.simple("fullname: %s",specification.fullname) + logs.simple("filename: %s",specification.filename) + logs.simple("family : %s",specification.familyname or "") + logs.simple("weight : %s",specification.weight or "") + logs.simple("style : %s",specification.style or "") + logs.simple("width : %s",specification.width or "") + logs.simple("variant : %s",specification.variant or "") + logs.simple("subfont : %s",subfont(specification.subfont)) + logs.simple("fweight : %s",fontweight(specification.fontweight)) + -- maybe more + local features = fonts.get_features(specification.filename,specification.format) + if features then + for what, v in table.sortedhash(features) do + local data = features[what] + if data and next(data) then + logs.simple() + logs.simple("%s features:",what) + logs.simple() + logs.simple("feature script languages") + logs.simple() + for f,ff in table.sortedhash(data) do + local done = false + for s, ss in table.sortedhash(ff) do + if s == "*" then s = "all" end + if ss ["*"] then ss["*"] = nil ss.all = true end + if done then + f = "" + else + done = true + end + logs.simple("% -8s % -8s % -8s",f,s,table.concat(table.sortedkeys(ss), " ")) + end + end + end + end + else + logs.simple() + logs.simple("no features") + logs.simple() + end + logs.reportline() +end + +local function reloadbase(reload) + if reload then + logs.simple("fontnames, reloading font database") + names.load(true) + logs.simple("fontnames, done\n\n") + end +end + +local function list_specifications(t,info) + if t then + local s = table.sortedkeys(t) + if info then + for k=1,#s do + local v = s[k] + showfeatures(v,t[v]) + end + else + for k=1,#s do + local v = s[k] + local entry = t[v] + s[k] = { + entry.familyname or "", + entry.weight or "", + entry.style or "", + entry.width or "", + entry.variant or "", + entry.fontname, + entry.filename, + subfont(entry.subfont), + fontweight(entry.fontweight), + } + e[k] = entry + end + table.formatcolumns(s) + for k=1,#s do + local v = s[k] + texio.write_nl(v) + end + end + end +end + +local function list_matches(t,info) + if t then + local s, w = table.sortedkeys(t), { 0, 0, 0 } + if info then + for k=1,#s do + local v = s[k] + showfeatures(v,t[v]) + end + else + for k=1,#s do + local v = s[k] + local entry = t[v] + s[k] = { + v, + entry.fontname, + entry.filename, + subfont(entry.subfont) + } + end + table.formatcolumns(s) + for k=1,#s do + texio.write_nl(s[k]) + end + end + end +end + +function scripts.fonts.list() + + local all = environment.argument("all") + local info = environment.argument("info") + local reload = environment.argument("reload") + local pattern = environment.argument("pattern") + local filter = environment.argument("filter") + local given = environment.files[1] + + reloadbase(reload) + + if environment.argument("name") then + if pattern then + --~ mtxrun --script font --list --name --pattern=*somename* + list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info) + elseif filter then + logs.report("fontnames","not supported: --list --name --filter",name) + elseif given then + --~ mtxrun --script font --list --name somename + list_matches(fonts.names.list(given,reload,all),info) + else + logs.report("fontnames","not supported: --list --name ",name) + end + elseif environment.argument("spec") then + if pattern then + --~ mtxrun --script font --list --spec --pattern=*somename* + logs.report("fontnames","not supported: --list --spec --pattern",name) + elseif filter then + --~ mtxrun --script font --list --spec --filter="fontname=somename" + list_specifications(fonts.names.getlookups(filter),info) + elseif given then + --~ mtxrun --script font --list --spec somename + list_specifications(fonts.names.collectspec(given,reload,all),info) + else + logs.report("fontnames","not supported: --list --spec ",name) + end + elseif environment.argument("file") then + if pattern then + --~ mtxrun --script font --list --file --pattern=*somename* + list_specifications(fonts.names.collectfiles(string.topattern(pattern,true),reload,all),info) + elseif filter then + logs.report("fontnames","not supported: --list --spec",name) + elseif given then + --~ mtxrun --script font --list --file somename + list_specifications(fonts.names.collectfiles(given,reload,all),info) + else + logs.report("fontnames","not supported: --list --file ",name) + end + elseif pattern then + --~ mtxrun --script font --list --pattern=*somename* + list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info) + elseif given then + --~ mtxrun --script font --list somename + list_matches(fonts.names.list(given,reload,all),info) + else + logs.report("fontnames","not supported: --list ",name) + end + +end + +function scripts.fonts.save() + local name = environment.files[1] or "" + local sub = environment.files[2] or "" + local function save(savename,fontblob) + if fontblob then + savename = savename:lower() .. ".lua" + logs.simple("fontsave, saving data in %s",savename) + table.tofile(savename,fontloader.to_table(fontblob),"return") + fontloader.close(fontblob) + end + end + if name and name ~= "" then + local filename = resolvers.find_file(name) -- maybe also search for opentype + if filename and filename ~= "" then + local suffix = file.extname(filename) + if suffix == 'ttf' or suffix == 'otf' or suffix == 'ttc' or suffix == "dfont" then + local fontinfo = fontloader.info(filename) + if fontinfo then + logs.simple("font: %s located as %s",name,filename) + if fontinfo[1] then + for k=1,#fontinfo do + local v = fontinfo[k] + save(v.fontname,fontloader.open(filename,v.fullname)) + end + else + save(fontinfo.fullname,fontloader.open(filename)) + end + else + logs.simple("font: %s cannot be read",filename) + end + else + logs.simple("font: %s not saved",filename) + end + else + logs.simple("font: %s not found",name) + end + else + logs.simple("font: no name given") + end +end + +logs.extendbanner("ConTeXt Font Database Management 0.21",true) + +messages.help = [[ +--save save open type font in raw table + +--reload generate new font database +--reload --simple generate 'luatex-fonts-names.lua' (not for context!) + +--list --name list installed fonts, filter by name [--pattern] +--list --spec list installed fonts, filter by spec [--filter] +--list --file list installed fonts, filter by file [--pattern] + +--pattern=str filter files using pattern +--filter=list key-value pairs +--all show all found instances +--info give more details +--track=list enable trackers + +examples of searches: + +mtxrun --script font --list somename (== --pattern=*somename*) + +mtxrun --script font --list --name somename +mtxrun --script font --list --name --pattern=*somename* + +mtxrun --script font --list --spec somename +mtxrun --script font --list --spec somename-bold-italic +mtxrun --script font --list --spec --pattern=*somename* +mtxrun --script font --list --spec --filter="fontname=somename" +mtxrun --script font --list --spec --filter="familyname=somename,weight=bold,style=italic,width=condensed" + +mtxrun --script font --list --file somename +mtxrun --script font --list --file --pattern=*somename* +]] + +local track = environment.argument("track") + +if track then trackers.enable(track) end + +if environment.argument("names") then + environment.setargument("reload",true) + environment.setargument("simple",true) +end + +if environment.argument("list") then + scripts.fonts.list() +elseif environment.argument("reload") then + scripts.fonts.reload() +elseif environment.argument("save") then + scripts.fonts.save() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-grep.lua b/scripts/context/lua/mtx-grep.lua new file mode 100644 index 000000000..9604bc9f8 --- /dev/null +++ b/scripts/context/lua/mtx-grep.lua @@ -0,0 +1,114 @@ +if not modules then modules = { } end modules ['mtx-babel'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.grep = scripts.grep or { } + +logs.extendbanner("Simple Grepper 0.10",true) + +local find, format = string.find, string.format + +local cr = lpeg.P("\r") +local lf = lpeg.P("\n") +local crlf = cr * lf +local newline = crlf + cr + lf +local content = lpeg.C((1-newline)^0) * newline + +local write_nl = texio.write_nl + +function scripts.grep.find(pattern, files, offset) + if pattern and pattern ~= "" then + statistics.starttiming(scripts.grep) + local nofmatches, noffiles, nofmatchedfiles = 0, 0, 0 + local n, m, name, check = 0, 0, "", nil + local count, nocomment = environment.argument("count"), environment.argument("nocomment") + if nocomment then + if count then + check = function(line) + n = n + 1 + if find(line,"^[%%#]") then + -- skip + elseif find(line,pattern) then + m = m + 1 + end + end + else + check = function(line) + n = n + 1 + if find(line,"^[%%#]") then + -- skip + elseif find(line,pattern) then + m = m + 1 + write_nl(format("%s %6i: %s",name,n,line)) + io.flush() + end + end + end + else + if count then + check = function(line) + n = n + 1 + if find(line,pattern) then + m = m + 1 + end + end + else + check = function(line) + n = n + 1 + if find(line,pattern) then + m = m + 1 + write_nl(format("%s %6i: %s",name,n,line)) + io.flush() + end + end + end + end + local capture = (content/check)^0 + for i=offset or 1, #files do + local globbed = dir.glob(files[i]) + for i=1,#globbed do + local nam = globbed[i] + name = nam + local data = io.loaddata(name) + if data then + n, m, noffiles = 0, 0, noffiles + 1 + capture:match(data) + if count and m > 0 then + nofmatches = nofmatches + m + nofmatchedfiles = nofmatchedfiles + 1 + write_nl(format("%s: %s",name,m)) + io.flush() + end + end + end + end + statistics.stoptiming(scripts.grep) + if count and nofmatches > 0 then + write_nl(format("\nfiles: %s, matches: %s, matched files: %s, runtime: %0.3f seconds",noffiles,nofmatches,nofmatchedfiles,statistics.elapsedtime(scripts.grep))) + end + end +end + +messages.help = [[ +--pattern search for pattern (optional) +--count count matches only +--nocomment skip lines that start with %% or # + +patterns are lua patterns and need to be escaped accordingly +]] + +local pattern = environment.argument("pattern") +local files = environment.files and #environment.files > 0 and environment.files + +if pattern and files then + scripts.grep.find(pattern, files) +elseif files then + scripts.grep.find(files[1], files, 2) +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-interface.lua b/scripts/context/lua/mtx-interface.lua new file mode 100644 index 000000000..730a030d9 --- /dev/null +++ b/scripts/context/lua/mtx-interface.lua @@ -0,0 +1,274 @@ +if not modules then modules = { } end modules ['mtx-cache'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +scripts = scripts or { } +scripts.interface = scripts.interface or { } + +local flushers = { } +local userinterfaces = { 'en','cs','de','it','nl','ro','fr','pe' } +local messageinterfaces = { 'en','cs','de','it','nl','ro','fr','pe','no' } + +function flushers.scite(interface,collection) + local result, i = {}, 0 + result[#result+1] = format("keywordclass.macros.context.%s=",interface) + for i=1,#collection do + local command = collection[i] + if i==0 then + result[#result+1] = "\\\n" + i = 5 + else + i = i - 1 + end + result[#result+1] = format("%s ",command) + end + io.savedata(format("cont-%s-scite.properties",interface), table.concat(result),"\n") + io.savedata(format("cont-%s-scite.lua",interface), table.serialize(collection,true)) +end + +function flushers.jedit(interface,collection) + local result = {} + result[#result+1] = "" + result[#result+1] = "\n" + result[#result+1] = "" + result[#result+1] = "\t" + result[#result+1] = "\t\t" + for i=1,#collection do + local command = collection[i] + result[#result+1] = format("\t\t\t%s",command) + end + result[#result+1] = "\t\t" + result[#result+1] = "\t" + result[#result+1] = "" + io.savedata(format("context-jedit-%s.xml",interface), table.concat(result),"\n") +end + +function flushers.bbedit(interface,collection) + local result = {} + result[#result+1] = "" + result[#result+1] = "BBLMKeywordList" + result[#result+1] = "" + for i=1,#collection do + local command = collection[i] + result[#result+1] = format("\t\\%s",command) + end + result[#result+1] = "" + io.savedata(format("context-bbedit-%s.xml",interface), table.concat(result),"\n") +end + +function flushers.raw(interface,collection) + for i=1,#collection do + local command = collection[i] + logs.simple(command) + end +end + +function scripts.interface.editor(editor) + local interfaces= environment.files + if #interfaces == 0 then + interfaces= userinterfaces + end + local xmlfile = resolvers.find_file("cont-en.xml") or "" + if xmlfile == "" then + logs.simple("unable to locate cont-en.xml") + end + for i=1,#interfaces do + local interface = interfaces[i] + local keyfile = resolvers.find_file(format("keys-%s.xml",interface)) or "" + if keyfile == "" then + logs.simple("unable to locate keys-*.xml") + else + local collection = { } + local mappings = { } + local x = xml.load(keyfile) + for e, d, k in xml.elements(x,"cd:command") do + local at = d[k].at + local name, value = at.name, at.value + if name and value then + mappings[name] = value + end + end + local x = xml.load(xmlfile) + for e, d, k in xml.elements(x,"cd:command") do + local at = d[k].at + local name, type = at.name, at["type"] + if name and name ~= "" then + local remapped = mappings[name] or name + if type == "environment" then + collection[#collection+1] = "start" .. remapped + collection[#collection+1] = "stop" .. remapped + else + collection[#collection+1] = remapped + end + end + end + if #collection > 0 then + table.sort(collection) + flushers[editor](interface,collection) + end + end + end +end + +function scripts.interface.check() + local xmlfile = resolvers.find_file("cont-en.xml") or "" + if xmlfile ~= "" then + local f = io.open("cont-en-check.tex","w") + if f then + f:write("\\starttext\n") + local x = xml.load(xmlfile) + for e, d, k in xml.elements(x,"cd:command") do + local dk = d[k] + local at = dk.at + if at then + local name = xml.filter(dk,"cd:sequence/cd:string/attribute(value)") + if name and name ~= "" then + if at.type == "environment" then + name = "start" .. name + end + f:write(format("\\doifundefined{%s}{\\writestatus{check}{command '%s' is undefined}}\n",name,name)) + end + end + end + f:write("\\stoptext\n") + f:close() + end + end +end + +function scripts.interface.context() + local filename = resolvers.find_file(environment.files[1] or "mult-def.lua") or "" + if filename ~= "" then + local interface = dofile(filename) + if interface and next(interface) then + local variables, constants, commands, elements = interface.variables, interface.constants, interface.commands, interface.elements + local filename = resolvers.find_file("cont-en.xml") or "" + local xmldata = filename ~= "" and (io.loaddata(filename) or "") + local function flush(texresult,xmlresult,language,what,tag) + local t = interface[what] + texresult[#texresult+1] = format("%% definitions for interface %s for language %s\n%%",what,language) + xmlresult[#xmlresult+1] = format("\t\n",what,language) + xmlresult[#xmlresult+1] = format("\t",what) + local sorted = table.sortedkeys(t) + for i=1,#sorted do + local key = sorted[i] + local v = t[key] + local value = v[language] or v["en"] + if not value then + logs.simple(format("warning, no value for key '%s' for language '%s'",key,language)) + else + local value = t[key][language] or t[key].en + texresult[#texresult+1] = format("\\setinterface%s{%s}{%s}",tag,key,value) + xmlresult[#xmlresult+1] = format("\t\t",tag,key,value) + end + end + xmlresult[#xmlresult+1] = format("\t\n",tag) + end + local function replace(str, element, attribute, category, othercategory, language) + return str:gsub(format("(<%s[^>]-%s=)([\"\'])([^\"\']-)([\"\'])",element,attribute), function(a,b,c) + local cc = category[c] + if not cc and othercategory then + cc = othercategory[c] + end + if cc then + ccl = cc[language] + if ccl then + return a .. b .. ccl .. b + end + end + return a .. b .. c .. b + end) + end + for language, _ in next, commands.setuplayout do + local texresult, xmlresult = { }, { } + texresult[#texresult+1] = format("%% this file is auto-generated, don't edit this file\n%%") + xmlresult[#xmlresult+1] = format("\n",tag) + xmlresult[#xmlresult+1] = format("\n",language) + flush(texresult,xmlresult,language,"variables","variable") + flush(texresult,xmlresult,language,"constants","constant") + flush(texresult,xmlresult,language,"elements", "element") + flush(texresult,xmlresult,language,"commands", "command") + texresult[#texresult+1] = format("%%\n\\endinput") + xmlresult[#xmlresult+1] = format("") + local texfilename = format("mult-%s.tex",language) + local xmlfilename = format("keys-%s.xml",language) + io.savedata(texfilename,table.concat(texresult,"\n")) + logs.simple(format("saving interface definitions '%s'",texfilename)) + io.savedata(xmlfilename,table.concat(xmlresult,"\n")) + logs.simple(format("saving interface translations '%s'",xmlfilename)) + if language ~= "en" and xmldata ~= "" then + local newdata = xmldata:gsub("( 0 then + local fn = files[1] + if #files == 1 and fn:find("%.mp$") then + latex = scripts.mptopdf.aux.find_latex(fn) or latex + end + if scripts.mptopdf.aux.make_mps(fn,latex,rawmp,metafun) then + files = dir.glob(file.nameonly(fn) .. ".*") -- reset + else + logs.simple("error while processing mp file '%s'", fn) + exit(1) + end + local report = { } + for i=1,#files do + local fn = files[i] + local success, name = scripts.mptopdf.aux.do_convert(fn) + if success > 0 then + report[#report+1] = { fn, name } + end + end + if #report > 0 then + logs.simple("number of converted files: %i", #report) + logs.simple("") + for i=1,#report do + local r = report[i] + logs.simple("%s => %s", r[1], r[2]) + end + else + logs.simple("no files are converted") + end + else + logs.simple("no files match %s", table.concat(environment.files,' ')) + end +end + +logs.extendbanner("MetaPost to PDF Converter 0.51",true) + +messages.help = [[ +--rawmp raw metapost run +--metafun use metafun instead of plain +--latex force --tex=latex +]] + +if environment.files[1] then + scripts.mptopdf.convertall() +else + if not environment.arguments.help then + logs.simple("provide MP output file (or pattern)") + logs.simple("") + end + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-mtxworks.lua b/scripts/context/lua/mtx-mtxworks.lua new file mode 100644 index 000000000..1239ae4c5 --- /dev/null +++ b/scripts/context/lua/mtx-mtxworks.lua @@ -0,0 +1,14 @@ +if not modules then modules = { } end modules ['mtx-mtxworks'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is a shortcut to "mtxrun --script texworks --start" + +environment.setargument("start",true) + +require "mtx-texworks" + diff --git a/scripts/context/lua/mtx-package.lua b/scripts/context/lua/mtx-package.lua new file mode 100644 index 000000000..b36fc0ed8 --- /dev/null +++ b/scripts/context/lua/mtx-package.lua @@ -0,0 +1,68 @@ +if not modules then modules = { } end modules ['mtx-package'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, gsub, gmatch = string.format, string.gsub, string.gmatch + +scripts = scripts or { } +messages = messages or { } +scripts.package = scripts.package or { } + +function scripts.package.merge_luatex_files(name,strip) + local oldname = resolvers.find_file(name) or "" + oldname = file.replacesuffix(oldname,"lua") + if oldname == "" then + logs.simple("missing '%s'",name) + else + local newname = file.removesuffix(oldname) .. "-merged.lua" + local data = io.loaddata(oldname) or "" + if data == "" then + logs.simple("missing '%s'",newname) + else + logs.simple("loading '%s'",oldname) + local collected = { } + collected[#collected+1] = format("-- merged file : %s\n",newname) + collected[#collected+1] = format("-- parent file : %s\n",oldname) + collected[#collected+1] = format("-- merge date : %s\n",os.date()) + -- loadmodule can have extra arguments + for lib in gmatch(data,"loadmodule *%([\'\"](.-)[\'\"]") do + if file.basename(lib) ~= file.basename(newname) then + local fullname = resolvers.find_file(lib) or "" + if fullname == "" then + logs.simple("missing '%s'",lib) + else + logs.simple("fetching '%s'",fullname) + local data = io.loaddata(fullname) + if strip then + data = gsub(data,"%-%-%[%[ldx%-%-.-%-%-%ldx%]%]%-%-[\n\r]*","") + data = gsub(data,"%-%-%~[^\n\r]*[\n\r]*","\n") + data = gsub(data,"%s+%-%-[^\n\r]*[\n\r]*","\n") + data = gsub(data,"[\n\r]+","\n") + end + collected[#collected+1] = "\ndo -- begin closure to overcome local limits and interference\n\n" + collected[#collected+1] = data + collected[#collected+1] = "\nend -- closure\n" + end + end + end + logs.simple("saving '%s'",newname) + io.savedata(newname,table.concat(collected)) + end + end +end + +logs.extendbanner("Distribution Related Goodies 0.10",true) + +messages.help = [[ +--merge merge 'loadmodule' into merge file +]] + +if environment.argument("merge") then + scripts.package.merge_luatex_files(environment.files[1] or "") +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-patterns.lua b/scripts/context/lua/mtx-patterns.lua new file mode 100644 index 000000000..293016991 --- /dev/null +++ b/scripts/context/lua/mtx-patterns.lua @@ -0,0 +1,366 @@ +if not modules then modules = { } end modules ['mtx-patterns'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +scripts = scripts or { } +scripts.patterns = scripts.patterns or { } + +scripts.patterns.list = { + { "??", "hyph-ar.tex", "arabic" }, + { "bg", "hyph-bg.tex", "bulgarian" }, + { "ca", "hyph-ca.tex", "catalan" }, + { "??", "hyph-cop.tex", "coptic" }, + { "cs", "hyph-cs.tex", "czech" }, + { "cy", "hyph-cy.tex", "welsh" }, + { "da", "hyph-da.tex", "danish" }, + { "deo", "hyph-de-1901.tex", "german, old spelling" }, + { "de", "hyph-de-1996.tex", "german, new spelling" }, +--~ { "??", "hyph-el-monoton.tex", "" }, +--~ { "??", "hyph-el-polyton.tex", "" }, + { "agr", "hyph-grc", "ancient greek" }, +--~ { "???", "hyph-x-ibycus", "ancient greek in ibycus encoding" }, +--~ { "gr", "", "" }, + { "eo", "hyph-eo.tex", "esperanto" }, + { "gb", "hyph-en-gb.tex", "british english" }, + { "us", "hyph-en-us.tex", "american english" }, + { "es", "hyph-es.tex", "spanish" }, + { "et", "hyph-et.tex", "estonian" }, + { "eu", "hyph-eu.tex", "basque" }, -- ba is Bashkir! + { "fa", "hyph-fa.tex", "farsi" }, + { "fi", "hyph-fi.tex", "finnish" }, + { "fr", "hyph-fr.tex", "french" }, +-- { "??", "hyph-ga.tex", "" }, +-- { "??", "hyph-gl.tex", "" }, +-- { "??", "hyph-grc.tex", "" }, + { "hr", "hyph-hr.tex", "croatian" }, + { "??", "hyph-hsb.tex", "upper sorbian" }, + { "hu", "hyph-hu.tex", "hungarian" }, + { "??", "hyph-ia.tex", "interlingua" }, + { "??", "hyph-id.tex", "indonesian" }, + { "is", "hyph-is.tex", "icelandic" }, + { "it", "hyph-it.tex", "italian" }, + { "la", "hyph-la.tex", "latin" }, + { "lt", "hyph-lt.tex", "lithuanian" }, + { "mn", "hyph-mn-cyrl.tex", "mongolian, cyrillic script" }, + { "nb", "hyph-nb.tex", "norwegian bokmål" }, + { "nl", "hyph-nl.tex", "dutch" }, + { "nn", "hyph-nn.tex", "norwegian nynorsk" }, + { "pl", "hyph-pl.tex", "polish" }, + { "pt", "hyph-pt.tex", "portuguese" }, + { "ro", "hyph-ro.tex", "romanian" }, + { "ru", "hyph-ru.tex", "russian" }, + { "sk", "hyph-sk.tex", "slovak" }, + { "sl", "hyph-sl.tex", "slovenian" }, + { "sr", "hyph-sr-cyrl.tex", "serbian" }, + { "sv", "hyph-sv.tex", "swedish" }, + { "tr", "hyph-tr.tex", "turkish" }, + { "tk", "hyph-tk.tex", "turkman" }, + { "uk", "hyph-uk.tex", "ukrainian" }, + { "zh", "hyph-zh-latn.tex", "zh-latn, chinese Pinyin" }, +} + + +-- stripped down from lpeg example: + +local utf = unicode.utf8 + +local cont = lpeg.R("\128\191") -- continuation byte + +local utf8 = lpeg.R("\0\127") + + lpeg.R("\194\223") * cont + + lpeg.R("\224\239") * cont * cont + + lpeg.R("\240\244") * cont * cont * cont + +local validutf = (utf8^0/function() return true end) * (lpeg.P(-1)/function() return false end) + +function utf.check(str) + return lpeg.match(validutf,str) +end + +local permitted_commands = table.tohash { + "message", + "endinput" +} + +local permitted_characters = table.tohash { + 0x0009, -- tab + 0x0027, -- apostrofe + 0x002D, -- hyphen + 0x200C, -- +} + +function scripts.patterns.load(path,name,mnemonic,fullcheck) + local fullname = file.join(path,name) + local data = io.loaddata(fullname) or "" + local byte, char = utf.byte, utf.char + if data ~= "" then + data = data:gsub("([\n\r])\\input ([^ \n\r]+)", function(previous,subname) + local subname = file.addsuffix(subname,"tex") + local subfull = file.join(file.dirname(fullname),subname) + local subdata = io.loaddata(subfull) or "" + if subdata == "" then + if mnemonic then + logs.simple("no subfile %s for language %s",subname,mnemonic) + else + logs.simple("no subfile %s",name) + end + end + return previous .. subdata + end) + local comment = data:match("^(.-)[\n\r]\\patterns") or "" + local n, okay = 0, true + local cd = characters.data + for line in data:gmatch("[^ \n\r]+") do + local ok = utf.check(line) + n = n + 1 + if not ok then + okay = false + line = line:gsub("%%","%%%%") + if fullcheck then + if mnemonic then + logs.simple("invalid utf in language %s, file %s, line %s: %s",mnemonic,name,n,line) + else + logs.simple("invalid utf in file %s, line %s: %s",name,n,line) + end + else + if mnemonic then + logs.simple("file %s for %s contains invalid utf",name,mnemonic) + else + logs.simple("file %s contains invalid utf",name) + end + break + end + end + end + local c, h = { }, { } + for line in data:gmatch("[^\n\r]+") do + local txt, cmt = line:match("^(.-)%%(.*)$") + if not txt then + txt, cmt = line, "" + end + for s in txt:gmatch("\\([a-zA-Z]+)") do + h[s] = (h[s] or 0) + 1 + end + for s in cmt:gmatch("\\([a-zA-Z]+)") do + c[s] = (c[s] or 0) + 1 + end + end + h.patterns = nil + h.hyphenation = nil + for k, v in next, h do + if not permitted_commands[k] then okay = false end + if mnemonic then + logs.simple("command \\%s found in language %s, file %s, n=%s",k,mnemonic,name,v) + else + logs.simple("command \\%s found in file %s, n=%s",k,name,v) + end + end + if not environment.argument("fast") then + for k, v in next, c do + if mnemonic then + logs.simple("command \\%s found in comment of language %s, file %s, n=%s",k,mnemonic,name,v) + else + logs.simple("command \\%s found in comment of file %s, n=%s",k,name,v) + end + end + end + data = data:gsub("%%.-[\n\r]","") + data = data:gsub(" *[\n\r]+","\n") + local patterns = data:match("\\patterns[%s]*{[%s]*(.-)[%s]*}") or "" + local hyphenations = data:match("\\hyphenation[%s]*{[%s]*(.-)[%s]*}") or "" + patterns = patterns:gsub(" +","\n") + hyphenations = hyphenations:gsub(" +","\n") + local p, h = { }, { } + local pats, hyps = { } , { } + local pused, hused = { } , { } + local period = byte(".") + for line in patterns:gmatch("[^ \n\r]+") do + local ok = true + for b in line:utfvalues() do + if b == period then + -- ok + else + local ct = cd[b].category + if ct == "lu" or ct == "ll" then + pused[char(b)] = true + elseif ct == "nd" then + -- ok + else + p[b] = (p[b] or 0) + 1 + ok = false + end + end + end + if ok then + pats[#pats+1] = line + end + end + local hyphen = byte("-") + for line in hyphenations:gmatch("[^ \n\r]+") do + local ok = true + for b in line:utfvalues() do + if b == hyphen then + -- ok + else + local ct = cd[b].category + if ct == "lu" or ct == "ll" then + hused[char(b)] = true + else + h[b] = (h[b] or 0) + 1 + ok = false + end + end + end + if ok then + hyps[#hyps+1] = line + end + end + local stripped = { } + for k, v in next, p do + if mnemonic then + logs.simple("invalid character %s (0x%04X) in patterns of language %s, file %s, n=%s",char(k),k,mnemonic,name,v) + else + logs.simple("invalid character %s (0x%04X) in patterns of file %s, n=%s",char(k),k,name,v) + end + if not permitted_characters[k] then + okay = false + else + stripped[k] = true + end + end + for k, v in next, h do + if mnemonic then + logs.simple("invalid character %s (0x%04X) in exceptions of language %s, file %s, n=%s",char(k),k,mnemonic,name,v) + else + logs.simple("invalid character %s (0x%04X) in exceptions of file %s, n=%s",char(k),k,name,v) + end + if not permitted_characters[k] then + okay = false + else + stripped[k] = true + end + end + local stripset = "" + for k, v in next, stripped do + logs.simple("entries that contain character %s will be omitted",char(k)) + stripset = stripset .. "%" .. char(k) + end + return okay, pats, hyps, comment, stripset, pused, hused + else + if mnemonic then + logs.simple("no file %s for language %s",fullname,mnemonic) + else + logs.simple("no file %s",fullname) + end + return false, { }, { }, "", "", { }, { } + end +end + +function scripts.patterns.save(destination,mnemonic,patterns,hyphenations,comment,stripped,pused,hused) + local nofpatterns = #patterns + local nofhyphenations = #hyphenations + local pu = table.concat(table.sortedkeys(pused), " ") + local hu = table.concat(table.sortedkeys(hused), " ") + logs.simple("language %s has %s patterns and %s exceptions",mnemonic,nofpatterns,nofhyphenations) + if mnemonic ~= "??" then + local rmefile = file.join(destination,"lang-"..mnemonic..".rme") + local patfile = file.join(destination,"lang-"..mnemonic..".pat") + local hypfile = file.join(destination,"lang-"..mnemonic..".hyp") + local topline = "% generated by mtxrun --script pattern --convert" + local banner = "% for comment and copyright, see " .. rmefile + logs.simple("saving language data for %s",mnemonic) + if not comment or comment == "" then comment = "% no comment" end + if not type(destination) == "string" then destination = "." end + os.remove(rmefile) + os.remove(patfile) + os.remove(hypfile) + io.savedata(rmefile,format("%s\n\n%s",topline,comment)) + io.savedata(patfile,format("%s\n\n%s\n\n%% used: %s\n\n\\patterns{\n%s}",topline,banner,pu,table.concat(patterns,"\n"))) + io.savedata(hypfile,format("%s\n\n%s\n\n%% used: %s\n\n\\hyphenation{\n%s}",topline,banner,hu,table.concat(hyphenations,"\n"))) + end +end + +function scripts.patterns.prepare() + dofile(resolvers.find_file("char-def.lua")) +end + +function scripts.patterns.check() + local path = environment.argument("path") or "." + local found = false + local files = environment.files + if #files > 0 then + for i=1,#files do + local name = files[i] + logs.simple("checking language file %s", name) + local okay = scripts.patterns.load(path,name,nil,not environment.argument("fast")) + if #environment.files > 1 then + logs.simple("") + end + end + else + for k, v in next, scripts.patterns.list do + local mnemonic, name = v[1], v[2] + logs.simple("checking language %s, file %s", mnemonic, name) + local okay = scripts.patterns.load(path,name,mnemonic,not environment.argument("fast")) + if not okay then + logs.simple("there are errors that need to be fixed") + end + logs.simple("") + end + end +end + +function scripts.patterns.convert() + local path = environment.argument("path") or "." + if path == "" then + logs.simple("provide sourcepath using --path ") + else + local destination = environment.argument("destination") or "." + if path == destination then + logs.simple("source path and destination path should differ (use --path and/or --destination)") + else + for k, v in next, scripts.patterns.list do + local mnemonic, name = v[1], v[2] + logs.simple("converting language %s, file %s", mnemonic, name) + local okay, patterns, hyphenations, comment, stripped, pused, hused = scripts.patterns.load(path,name,false) + if okay then + scripts.patterns.save(destination,mnemonic,patterns,hyphenations,comment,stripped,pused,hused) + else + logs.simple("convertion aborted due to error(s)") + end + logs.simple("") + end + end + end +end + +logs.extendbanner("ConTeXt Pattern File Management 0.20",true) + +messages.help = [[ +--convert generate context language files (mnemonic driven, if not given then all) +--check check pattern file (or those used by context when no file given) + +--fast only report filenames, no lines +]] + +if environment.argument("check") then + scripts.patterns.prepare() + scripts.patterns.check() +elseif environment.argument("convert") then + scripts.patterns.prepare() + scripts.patterns.convert() +else + logs.help(messages.help) +end + +-- mtxrun --script pattern --check hyph-*.tex +-- mtxrun --script pattern --check --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns +-- mtxrun --script pattern --check --fast --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns +-- mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns --destination=e:/tmp/patterns +-- mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/branches/luatex/hyph-utf8/tex/generic/hyph-utf8/patterns/tex --destination=e:/tmp/patterns diff --git a/scripts/context/lua/mtx-profile.lua b/scripts/context/lua/mtx-profile.lua new file mode 100644 index 000000000..11d48d039 --- /dev/null +++ b/scripts/context/lua/mtx-profile.lua @@ -0,0 +1,170 @@ +if not modules then modules = { } end modules ['mtx-profile'] = { + version = 1.000, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: also line number +-- todo: sort runtime as option + +local match, format, find = string.match, string.format, string.find + +scripts = scripts or { } +scripts.profiler = scripts.profiler or { } + +local timethreshold = 0 +local callthreshold = 2500 +local countthreshold = 2500 + +local functiontemplate = "%12s %03.4f %9i %s" +local calltemplate = "%9i %s" +local totaltemplate = "%i internal calls, %i function calls taking %3.4f seconds" +local thresholdtemplate = "thresholds: %i internal calls, %i function calls, %i seconds" + +function scripts.profiler.analyse(filename) + local f = io.open(filename) + if f then + local times, counts, calls = { }, { }, { } + local totalruntime, totalcount, totalcalls = 0, 0, 0 + while true do + local line = f:read() + if line then + local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)") + if not filename then + -- next + elseif filename == "=[C]" then + if not functionname:find("^%(") then + calls[functionname] = (calls[functionname] or 0) + 1 + end + else + local filename = filename:match("^@(.*)$") + if filename then + local fi = times[filename] + if not fi then fi = { } times[filename] = fi end + fi[functionname] = (fi[functionname] or 0) + tonumber(localtime) + counts[functionname] = (counts[functionname] or 0) + 1 + end + end + else + break + end + end + f:close() + print("") + local loaded = { } + local sortedtable.sortedkeys(times) + for i=1,#sorted do + local filename = sorted[i] + local functions = times[filename] + local sorted = table.sortedkeys(functions) + for i=1,#sorted do + local functionname = sorted[i] + local totaltime = functions[functionname] + local count = counts[functionname] + totalcount = totalcount + count + if totaltime > timethreshold or count > countthreshold then + totalruntime = totalruntime + totaltime + local functionfile, somenumber = functionname:match("^@(.+):(.-)$") + if functionfile then + local number = tonumber(somenumber) + if number then + if not loaded[functionfile] then + loaded[functionfile] = string.splitlines(io.loaddata(functionfile) or "") + end + functionname = loaded[functionfile][number] or functionname + functionname = functionname:gsub("^%s*","") + functionname = functionname:gsub("%s*%-%-.*$","") + functionname = number .. ": " .. functionname + end + end + filename = file.basename(filename) + print(functiontemplate:format(filename,totaltime,count,functionname)) + end + end + end + print("") + local sorted = table.sortedkeys(calls) + for i=1,#sorted do + local call = sorted[i] + local n = calls[call] + totalcalls = totalcalls + n + if n > callthreshold then + print(calltemplate:format(n,call)) + end + end + print("") + print(totaltemplate:format(totalcalls,totalcount,totalruntime)) + print("") + print(thresholdtemplate:format(callthreshold,countthreshold,timethreshold)) + end +end + +function scripts.profiler.x_analyse(filename) + local f = io.open(filename) + local calls = { } + local lines = 0 + if f then + while true do + local line = f:read() + if line then + lines = lines + 1 + local c = match(line,"\\([a-zA-Z%!%?@]+) *%->") + if c then + local cc = calls[c] + if not cc then + calls[c] = 1 + else + calls[c] = cc + 1 + end + end + else + break + end + end + f:close() + local noc = 0 +local criterium = 100 + for name, n in next, calls do + if n > criterium then + if find(name,"^@@[a-z][a-z]") then + -- parameter + elseif find(name,"^[cvserft]%!") then + -- variables and constants + elseif find(name,"^%?%?[a-z][a-z]$") then + -- prefix + elseif find(name,"^%!%!") then + -- reserved + elseif find(name,"^@.+@$") then + -- weird + else + noc = noc + n + print(format("%6i: %s",n,name)) + end + end + end + print("") + print(format("number of lines: %s",lines)) + print(format("number of calls: %s",noc)) + print(format("criterium calls: %s",criterium)) + end +end + +--~ scripts.profiler.analyse("t:/manuals/mk/mk-fonts-profile.lua") +--~ scripts.profiler.analyse("t:/manuals/mk/mk-introduction-profile.lua") + +logs.extendbanner("ConTeXt MkIV LuaTeX Profiler 1.00",true) + +messages.help = [[ +--analyse analyse lua calls +--trace analyse tex calls +]] + +if environment.argument("analyse") then + scripts.profiler.analyse(environment.files[1] or "luatex-profile.log") +elseif environment.argument("trace") then + scripts.profiler.analyse(environment.files[1] or "temp.log") +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-scite.lua b/scripts/context/lua/mtx-scite.lua new file mode 100644 index 000000000..d5f0a5344 --- /dev/null +++ b/scripts/context/lua/mtx-scite.lua @@ -0,0 +1,166 @@ +if not modules then modules = { } end modules ['mtx-scite'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: append to global properties else order of loading problem +-- linux problem ... files are under root protection so we need --install + +scripts = scripts or { } +scripts.scite = scripts.scite or { } + +local scitesignals = { "scite-context.rme", "context.properties" } +local screenfont = "lmtypewriter10-regular.ttf" + +function scripts.scite.start(indeed) + local usedsignal, datapath, fullname, workname, userpath, fontpath + if os.type == "windows" then + workname = "scite.exe" + userpath = os.getenv("USERPROFILE") or "" + fontpath = os.getenv("SYSTEMROOT") + fontpath = (fontpath and file.join(fontpath,"fonts")) or "" + else + workname = "scite" + userpath = os.getenv("HOME") or "" + fontpath = "" + end + local binpaths = file.split_path(os.getenv("PATH")) or file.split_path(os.getenv("path")) + for i=1,#scitesignals do + local scitesignal = scitesignals[i] + local scitepath = resolvers.find_file(scitesignal,"other text files") or "" + if scitepath ~= "" then + scitepath = file.dirname(scitepath) -- data + if scitepath == "" then + scitepath = resolvers.clean_path(lfs.currentdir()) + else + usedsignal, datapath = scitesignal, scitepath + break + end + end + end + if not datapath or datapath == "" then + logs.simple("invalid datapath, maybe you need to regenerate the file database") + return false + end + if not binpaths or #binpaths == 0 then + logs.simple("invalid binpath") + return false + end + for i=1,#binpaths do + local p = file.join(binpaths[i],workname) + if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub + fullname = p + break + end + end + if not fullname then + logs.simple("unable to locate %s",workname) + return false + end + local properties = dir.glob(file.join(datapath,"*.properties")) + local luafiles = dir.glob(file.join(datapath,"*.lua")) + local extrafont = resolvers.find_file(screenfont,"truetype font") or "" + local pragmafound = dir.glob(file.join(datapath,"pragma.properties")) + if userpath == "" then + logs.simple("unable to figure out userpath") + return false + end + local verbose = environment.argument("verbose") + local tobecopied, logdata = { }, { } + local function check_state(fullname,newpath) + local basename = file.basename(fullname) + local destination = file.join(newpath,basename) + local pa, da = lfs.attributes(fullname), lfs.attributes(destination) + if not da then + logdata[#logdata+1] = { "new : %s", basename } + tobecopied[#tobecopied+1] = { fullname, destination } + elseif pa.modification > da.modification then + logdata[#logdata+1] = { "outdated : %s", basename } + tobecopied[#tobecopied+1] = { fullname, destination } + else + logdata[#logdata+1] = { "up to date : %s", basename } + end + end + for i=1,#properties do + check_state(properties[i],userpath) + end + for i=1,#luafiles do + check_state(luafiles[i],userpath) + end + if fontpath ~= "" then + check_state(extrafont,fontpath) + end + local userpropfile = "SciTEUser.properties" + if os.name ~= "windows" then + userpropfile = "." .. userpropfile + end + local fullpropfile = file.join(userpath,userpropfile) + local userpropdata = io.loaddata(fullpropfile) or "" + local propfiledone = false + if pragmafound then + if userpropdata == "" then + logdata[#logdata+1] = { "error : no user properties found on '%s'", fullpropfile } + elseif string.find(userpropdata,"import *pragma") then + logdata[#logdata+1] = { "up to date : 'import pragma' in '%s'", userpropfile } + else + logdata[#logdata+1] = { "yet unset : 'import pragma' in '%s'", userpropfile } + userproperties = userpropdata .. "\n\nimport pragma\n\n" + propfiledone = true + end + else + if string.find(userpropdata,"import *context") then + logdata[#logdata+1] = { "up to date : 'import context' in '%s'", userpropfile } + else + logdata[#logdata+1] = { "yet unset : 'import context' in '%s'", userpropfile } + userproperties = userpropdata .. "\n\nimport context\n\n" + propfiledone = true + end + end + if not indeed or verbose then + logs.simple("used signal: %s", usedsignal) + logs.simple("data path : %s", datapath) + logs.simple("full name : %s", fullname) + logs.simple("user path : %s", userpath) + logs.simple("extra font : %s", extrafont) + end + if #logdata > 0 then + logs.simple("") + for k=1,#logdata do + local v = logdata[k] + logs.simple(v[1],v[2]) + end + end + if indeed then + if #tobecopied > 0 then + logs.simple("warning : copying updated files") + for i=1,#tobecopied do + local what = tobecopied[i] + logs.simple("copying : '%s' => '%s'",what[1],what[2]) + file.copy(what[1],what[2]) + end + end + if propfiledone then + logs.simple("saving : '%s'",userpropfile) + io.savedata(fullpropfile,userpropdata) + end + os.launch(fullname) + end +end + +logs.extendbanner("Scite Startup Script 1.00",true) + +messages.help = [[ +--start [--verbose] start scite +--test report what will happen +]] + +if environment.argument("start") then + scripts.scite.start(true) +elseif environment.argument("test") then + scripts.scite.start() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-server-ctx-fonttest.lua b/scripts/context/lua/mtx-server-ctx-fonttest.lua new file mode 100644 index 000000000..b2a993bf8 --- /dev/null +++ b/scripts/context/lua/mtx-server-ctx-fonttest.lua @@ -0,0 +1,733 @@ +if not modules then modules = { } end modules ['mtx-server-ctx-fonttest'] = { + version = 1.001, + comment = "Font Feature Tester", + author = "Hans Hagen", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--~ dofile(resolvers.find_file("l-aux.lua","tex")) +dofile(resolvers.find_file("trac-lmx.lua","tex")) +dofile(resolvers.find_file("font-ott.lua","tex")) +dofile(resolvers.find_file("font-syn.lua","tex")) +dofile(resolvers.find_file("font-mis.lua","tex")) +dofile(resolvers.find_file("font-otp.lua","tex")) + +local format, gsub, concat, match, find = string.format, string.gsub, table.concat, string.match, string.find + +local sample_line = "This is a sample line!" +local tempname = "mtx-server-ctx-fonttest-temp" +local temppath = caches.setpath("temp","mtx-server-ctx-fonttest") +local basename = "mtx-server-ctx-fonttest-data.lua" +local basepath = temppath + +local remove_suffixes = { "tex", "pdf", "log" } +local what_options = { "trace", "basemode" } + +for i=1,#remove_suffixes do + os.remove(file.join(temppath,file.addsuffix(tempname,remove_suffixes[i]))) +end + +local process_templates = { } + +process_templates.default = [[ +\starttext + \setcharactermirroring[1] + \definefontfeature[sample][analyse=yes,%s] + \definedfont[name:%s*sample] + \startTEXpage[offset=3pt] + \detokenize{%s} + \stopTEXpage +\stoptext +]] + +process_templates.cache = [[ +\starttext + \definedfont[name:%s] + \startTEXpage[offset=3pt] + cached: \detokenize{%s} + \stopTEXpage +\stoptext +]] + +process_templates.trace = [[ +\usemodule[fnt-20] + +\definefontfeature[sample][%s] + +\setupcolors[state=start] + +\setcharactermirroring[1] + +\setvariables + [otftracker] + [title=Test Run, + font=name:%s, + direction=0, + features=sample, + sample={‍\detokenize{%s}}] +]] + +local javascripts = [[ +function selected_radio(name) { + var form = document.forms["main-form"] ; + var script = form.elements[name] ; + if (script) { + var n = script.length ; + if (n) { + for (var i=0; i + safe name     + family name     + style-variant-weight-width     + font name     + weight     + filename +]] + +local template_d = [[ + + %s     + %s     + %s-%s-%s-%s     + %s     + %s     + %s +]] + +local function select_font() + local t = fonts.names.list(".*",false,true) + if t then + local listoffonts = { } + listoffonts[#listoffonts+1] = "" + listoffonts[#listoffonts+1] = template_h + for k, v in table.sortedhash(t) do + local kind = v.format + if kind == "otf" or kind == "ttf" or kind == "ttc" then + local fontname = v.fontname + listoffonts[#listoffonts+1] = format(template_d, fontname, fontname, + v.familyname or "", + t.variant or "normal", + t.weight or "normal", + t.width or "normal", + t.style or "normal", + v.rawname or fontname, + v.fontweight or "", + v.filename or "" + ) + end + end + listoffonts[#listoffonts+1] = "
" + return concat(listoffonts,"\n") + end + return "no fonts" +end + +local edit_template = [[ + +

name:    title:  +

scripts: %s +

languages: %s +

features: %s +

options: %s +]] + +local result_template = [[ +

+ +

results: + tex file + pdf file +

+]] + +scripts.webserver.registerpath(temppath) + +local function get_specification(name) + return fonts.names.resolvedspecification(name or "") +end + +local function edit_font(currentfont,detail,tempname) + logs.simple("entering edit mode for '%s'",currentfont) + local specification = get_specification(currentfont) + if specification then + local htmldata = showfeatures(specification.filename) + if htmldata then + local features, languages, scripts, options = { }, { }, { }, { } + local sorted = table.sortedkeys(htmldata.scripts) + for k=1,#sorted do + local v = sorted[k] + local s = fonts.otf.tables.scripts[v] or v + if detail and v == detail.script then + scripts[#scripts+1] = format(" %s",s,v,v,v,v) + else + scripts[#scripts+1] = format(" %s",s,v,v,v,v) + end + end + local sorted = table.sortedkeys(htmldata.languages) + for k=1,#sorted do + local v = sorted[k] + local l = fonts.otf.tables.languages[v] or v + if detail and v == detail.language then + languages[#languages+1] = format(" %s",l,v,v,v,v) + else + languages[#languages+1] = format(" %s",l,v,v,v,v) + end + end + local sorted = table.sortedkeys(htmldata.features) + for k=1,#sorted do + local v = sorted[k] + local f = fonts.otf.tables.features[v] or v + if detail and detail["f-"..v] then + features[#features+1] = format(" %s",f,v,v,v,v) + else + features[#features+1] = format(" %s",f,v,v,v,v) + end + end + for k=1,#what_options do + local v = what_options[k] + if detail and detail["o-"..v] then + options[#options+1] = format(" %s",v,v,v) + else + options[#options+1] = format(" %s",v,v,v) + end + end + local e = format(edit_template, + (detail and detail.sampletext) or sample_line,(detail and detail.name) or "no name",(detail and detail.title) or "", + concat(scripts," "),concat(languages," "),concat(features," "),concat(options," ")) + if tempname then + local pdffile, texfile = file.addsuffix(tempname,"pdf"), file.addsuffix(tempname,"tex") + local r = format(result_template,pdffile,texfile,pdffile) + return e .. r, htmldata.javascript or "" + else + return e, htmldata.javascript or "" + end + else + return "error, nothing set up yet" + end + else + return "error, no info about font" + end +end + +local function process_font(currentfont,detail) -- maybe just fontname + local features = { + "mode=node", + format("language=%s",detail.language or "dflt"), + format("script=%s",detail.script or "dflt"), + } + for k,v in next, detail do + local f = match(k,"^f%-(.*)$") + if f then + features[#features+1] = format("%s=yes",f) + end + end + local variant = process_templates.default + if detail["o-trace"] then + variant = process_templates.trace + end + local sample = string.strip(detail.sampletext or "") + if sample == "" then sample = sample_line end + logs.simple("sample text: %s",sample) + io.savedata(file.join(temppath,file.addsuffix(tempname,"tex")),format(variant,concat(features,","),currentfont,sample)) + os.execute(format("mtxrun --path=%s --script context --once --batchmode %s",temppath,tempname)) + return edit_font(currentfont,detail,tempname) +end + +local tex_template = [[ +

+%s
+
+]] + +local function show_source(currentfont,detail) + if tempname and tempname ~= "" then + return format(tex_template,io.loaddata(file.join(temppath,file.addsuffix(tempname,"tex"))) or "no source yet") + else + return "no source file" + end +end + +local function show_log(currentfont,detail) + if tempname and tempname ~= "" then + local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,'log'))) or "no log file yet" + data = gsub(data,"[%s%%]*begin of optionfile.-end of optionfile[%s%%]*","\n") + return format(tex_template,data) + else + return "no log file" + end +end + +local function show_font(currentfont,detail) + local specification = get_specification(currentfont) + local features = fonts.get_features(specification.filename) + local result = { } + result[#result+1] = format("

names

",what) + result[#result+1] = "" + result[#result+1] = format("",currentfont) + result[#result+1] = format("",specification.fontname or "-") + result[#result+1] = format("",specification.fontfile or "-") + result[#result+1] = format("",specification.familyname or "-") + result[#result+1] = format("",specification.fontweight or "-") + result[#result+1] = format("",specification.format or "-") + result[#result+1] = format("",specification.fullname or "-") + result[#result+1] = format("",specification.subfamily or "-") + result[#result+1] = format("",specification.rawname or "-") + result[#result+1] = format("",specification.designsize or "-") + result[#result+1] = format("",specification.minsize or "-") + result[#result+1] = format("",specification.maxsize or "-") + result[#result+1] = format("",specification.style ~= "" and specification.style or "normal") + result[#result+1] = format("",specification.variant ~= "" and specification.variant or "normal") + result[#result+1] = format("",specification.weight ~= "" and specification.weight or "normal") + result[#result+1] = format("",specification.width ~= "" and specification.width or "normal") + result[#result+1] = "
fontname: %s
fullname: %s
filename: %s
familyname: %s
fontweight: %s
format: %s
fullname: %s
subfamily: %s
rawname: %s
designsize: %s
minimumsize:%s
maximumsize:%s
style: %s
variant: %s
weight: %s
width: %s
" + if features then + for what, v in table.sortedhash(features) do + local data = features[what] + if data and next(data) then + result[#result+1] = format("

%s features

",what) + result[#result+1] = "" + result[#result+1] = "" + for f,ff in table.sortedhash(data) do + local done = false + for s, ss in table.sortedhash(ff) do + if s == "*" then s = "all" end + if ss ["*"] then ss["*"] = nil ss.all = true end + if done then + f = "" + else + done = true + end + local title = fonts.otf.tables.features[f] or "" + result[#result+1] = format("",title,f,s,concat(table.sortedkeys(ss)," ")) + end + end + result[#result+1] = "
featuretag script languages 
%s  %s  %s  %s  
" + end + end + else + result[#result+1] = "

This font has no features." + end + return concat(result,"\n") +end + + +local info_template = [[ +

+version   : %s
+comment   : %s
+author    : %s
+copyright : %s
+
+maillist  : ntg-context at ntg.nl
+webpage   : www.pragma-ade.nl
+wiki      : contextgarden.net
+
+]] + +local function info_about() + local m = modules ['mtx-server-ctx-fonttest'] + return format(info_template,m.version,m.comment,m.author,m.copyright) +end + +local save_template = [[ + the current setup has been saved: +

+ + + + + + + + + +
name  %s
title  %s
font  %s
script  %s
language  %s
features  %s
options  %s
sampletext %s
+]] + +local function loadbase() + local datafile = file.join(basepath,basename) + local storage = io.loaddata(datafile) or "" + if storage == "" then + storage = { } + else + logs.simple("loading '%s'",datafile) + storage = loadstring(storage) + storage = (storage and storage()) or { } + end + return storage +end + +local function loadstored(detail,currentfont,name) + local storage = loadbase() + storage = storage and storage[name] + if storage then + currentfont = storage.font + detail.script = storage.script or detail.script + detail.language = storage.language or detail.language + detail.title = storage.title or detail.title + detail.sampletext = storage.text or detail.sampletext + detail.name = name or "no name" + for k,v in next, storage.features do + detail["f-"..k] = v + end + for k,v in next, storage.options do + detail["o-"..k] = v + end + end + detail.loadname = nil + return detail, currentfont +end + +local function savebase(storage,name) + local datafile = file.join(basepath,basename) + logs.simple("saving '%s' in '%s'",name or "data",datafile) + io.savedata(datafile,table.serialize(storage,true)) +end + +local function deletestored(detail,currentfont,name) + local storage = loadbase() + if storage and name and storage[name] then + logs.simple("deleting '%s' from base",name) + storage[name] = nil + savebase(storage) + end + detail.deletename = nil + return detail, "" +end + +local function save_font(currentfont,detail) + local specification = get_specification(currentfont) + local name, title, script, language, features, options, text = currentfont, "", "dflt", "dflt", { }, { }, "" + if detail then + local htmldata = showfeatures(specification.filename) + script = detail.script or script + language = detail.language or language + text = string.strip(detail.sampletext or text) + name = string.strip(detail.name or name) + title = string.strip(detail.title or title) + for k,v in next, htmldata.features do + if detail["f-"..k] then features[k] = true end + end + for k=1,#what_options do + local v = what_options[k] + if detail["o-"..v] then options[k] = true end + end + end + if name == "" then + name = "no name" + end + local storage = loadbase() + storage[name] = { + font = currentfont, title = title, script = script, language = language, features = features, options = options, text = text, + } + savebase(storage,name) + return format(save_template,name,title,currentfont,script,language,concat(table.sortedkeys(features)," "),concat(table.sortedkeys(options)," "),text) +end + +local function load_font(currentfont) + local datafile = file.join(basepath,basename) + local storage = loadbase(datafile) + local result = {} + result[#result+1] = format("del name font fontname script language features title sampletext ") + for k,v in table.sortedhash(storage) do + local fontname, fontfile = get_specification(v.font) + result[#result+1] = format("x %s %s %s %s %s %s %s %s ", + k,k,k,v.font,fontname,v.script,v.language,concat(table.sortedkeys(v.features)," "),v.title or "no title",v.text or "") + end + if #result == 1 then + return "nothing saved yet" + else + return format("%s
",concat(result,"\n")) + end +end + +local function reset_font(currentfont) + return edit_font(currentfont) +end + +local extras_template = [[ + remake font database (take some time)

+]] + +local function do_extras(detail,currentfont,extra) + return extras_template +end + +local extras = { } + +local function do_extra(detail,currentfont,extra) + local e = extras[extra] + if e then e(detail,currentfont,extra) end + return do_extras(detail,currentfont,extra) +end + +function extras.reload() + local command = "mtxrun --script font --reload" + logs.simple("run command: %s",command) + os.execute(command) + return do_extras() +end + + +local status_template = [[ + +]] + +local variables = { + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['title'] = 'ConTeXt Font Tester', + ['formaction'] = "mtx-server-ctx-fonttest.lua", +} + +function doit(configuration,filename,hashed) + + local start = os.clock() + + local detail = url.query(hashed.query or "") + + local currentfont = detail.currentfont + local action = detail.action + local selection = detail.selection + + local loadname = detail.loadname + local deletename = detail.deletename + local extra = detail.extra + + if loadname and loadname ~= "" then + detail, currentfont = loadstored(detail,currentfont,loadname) + action = "process" + elseif deletename and deletename ~= "" then + detail, currentfont = deletestored(detail,currentfont,deletename) + action = "load" + elseif selection and selection ~= "" then + currentfont = selection + elseif extra and extra ~= "" then + do_extra(detail,currentfont,extra) + action = "extras" + end + + local fontname, fontfile = get_specification(currentfont) + + if fontfile then + variables.title = format('ConTeXt Font Tester: %s (%s)',fontname,fontfile) + else + variables.title = 'ConTeXt Font Tester' + end + + -- lua table and adapt + + local buttons = { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras'} + local menu = { } + + for i=1,#buttons do + local button = buttons[i] + menu[#menu+1] = format("",button,button) + end + + variables.menu = concat(menu," ") + variables.status = format(status_template,currentfont or "") + variables.maintext = "" + variables.javascriptdata = "" + variables.javascripts = "" + variables.javascriptinit = "" + + logs.simple("action: %s",action or "no action") + + local result + + if action == "select" then + variables.maintext = select_font() + elseif action == "info" then + variables.maintext = info_about() + elseif action == "extras" then + variables.maintext = do_extras() + elseif currentfont and currentfont ~= "" then + if action == "save" then + variables.maintext = save_font(currentfont,detail) + elseif action == "load" then + variables.maintext = load_font(currentfont,detail) + elseif action == "source" then + variables.maintext = show_source(currentfont,detail) + elseif action == "log" then + variables.maintext = show_log(currentfont,detail) + elseif action == "features" then + variables.maintext = show_font(currentfont,detail) + else + local e, s + if action == "process" then + e, s = process_font(currentfont,detail) + elseif action == "reset" then + e, s = reset_font(currentfont) + elseif action == "edit" then + e, s = edit_font(currentfont,detail) + else + e, s = process_font(currentfont,detail) + end + variables.maintext = e + variables.javascriptdata = s + variables.javascripts = javascripts + variables.javascriptinit = "check_form()" + end + else + variables.maintext = select_font() + end + + result = { content = lmx.convert('context-fonttest.lmx',false,variables) } + + logs.simple("time spent on page: %0.03f seconds",os.clock()-start) + + return result + +end + +return doit, true + +--~ make_lmx_page("test") diff --git a/scripts/context/lua/mtx-server-ctx-help.lua b/scripts/context/lua/mtx-server-ctx-help.lua new file mode 100644 index 000000000..2f072f977 --- /dev/null +++ b/scripts/context/lua/mtx-server-ctx-help.lua @@ -0,0 +1,665 @@ +if not modules then modules = { } end modules ['mtx-server-ctx-help'] = { + version = 1.001, + comment = "Basic Definition Browser", + author = "Hans Hagen", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo in lua interface: noargument, oneargument, twoarguments, threearguments + +--~ dofile(resolvers.find_file("l-aux.lua","tex")) +--~ dofile(resolvers.find_file("l-url.lua","tex")) +dofile(resolvers.find_file("trac-lmx.lua","tex")) + +-- problem ... serialize parent stack + +local format = string.format +local concat = table.concat + +-- -- -- make this a module: cont-xx.lua + +document = document or { } +document.setups = document.setups or { } + +document.setups.div = { + pe = "
%s
" +} + +document.setups.span = { + pe = "%s" +} + +document.setups.translations = document.setups.translations or { + + nl = { + ["title"] = "setup", + ["formula"] = "formule", + ["number"] = "getal", + ["list"] = "lijst", + ["dimension"] = "maat", + ["mark"] = "markering", + ["reference"] = "verwijzing", + ["command"] = "commando", + ["file"] = "file", + ["name"] = "naam", + ["identifier"] = "naam", + ["text"] = "tekst", + ["section"] = "sectie", + ["singular"] = "naam enkelvoud", + ["plural"] = "naam meervoud", + ["matrix"] = "n*m", + ["see"] = "zie", + ["inherits"] = "erft van", + ["optional"] = "optioneel", + ["displaymath"] = "formule", + ["index"] = "ingang", + ["math"] = "formule", + ["nothing"] = "leeg", + ["file"] = "file", + ["position"] = "positie", + ["reference"] = "verwijzing", + ["csname"] = "naam", + ["destination"] = "bestemming", + ["triplet"] = "triplet", + ["word"] = "woord", + ["content"] = "tekst", + }, + + en = { + ["title"] = "setup", + ["formula"] = "formula", + ["number"] = "number", + ["list"] = "list", + ["dimension"] = "dimension", + ["mark"] = "mark", + ["reference"] = "reference", + ["command"] = "command", + ["file"] = "file", + ["name"] = "name", + ["identifier"] = "identifier", + ["text"] = "text", + ["section"] = "section", + ["singular"] = "singular name", + ["plural"] = "plural name", + ["matrix"] = "n*m", + ["see"] = "see", + ["inherits"] = "inherits from", + ["optional"] = "optional", + ["displaymath"] = "formula", + ["index"] = "entry", + ["math"] = "formula", + ["nothing"] = "empty", + ["file"] = "file", + ["position"] = "position", + ["reference"] = "reference", + ["csname"] = "name", + ["destination"] = "destination", + ["triplet"] = "triplet", + ["word"] = "word", + ["content"] = "text", + + ["noargument"] = "\\cs", + ["oneargument"] = "\\cs#1{..}", + ["twoarguments"] = "\\cs#1#2{..}{..}", + ["threearguments"] = "\\cs#1#2#3{..}{..}{..}", + + }, + + de = { + ["title"] = "Setup", + ["formula"] = "Formel", + ["number"] = "Nummer", + ["list"] = "Liste", + ["dimension"] = "Dimension", + ["mark"] = "Beschriftung", + ["reference"] = "Referenz", + ["command"] = "Befehl", + ["file"] = "Datei", + ["name"] = "Name", + ["identifier"] = "Name", + ["text"] = "Text", + ["section"] = "Abschnitt", + ["singular"] = "singular", + ["plural"] = "plural", + ["matrix"] = "n*m", + ["see"] = "siehe", + ["inherits"] = "inherits from", + ["optional"] = "optioneel", + ["displaymath"] = "formula", + ["index"] = "entry", + ["math"] = "formula", + ["nothing"] = "empty", + ["file"] = "file", + ["position"] = "position", + ["reference"] = "reference", + ["csname"] = "name", + ["destination"] = "destination", + ["triplet"] = "triplet", + ["word"] = "word", + ["content"] = "text", + }, + + cz = { + ["title"] = "setup", + ["formula"] = "rovnice", + ["number"] = "cislo", + ["list"] = "seznam", + ["dimension"] = "dimenze", + ["mark"] = "znacka", + ["reference"] = "reference", + ["command"] = "prikaz", + ["file"] = "soubor", + ["name"] = "jmeno", + ["identifier"] = "jmeno", + ["text"] = "text", + ["section"] = "sekce", + ["singular"] = "jmeno v singularu", + ["plural"] = "jmeno v pluralu", + ["matrix"] = "n*m", + ["see"] = "viz", + ["inherits"] = "inherits from", + ["optional"] = "optioneel", + ["displaymath"] = "formula", + ["index"] = "entry", + ["math"] = "formula", + ["nothing"] = "empty", + ["file"] = "file", + ["position"] = "position", + ["reference"] = "reference", + ["csname"] = "name", + ["destination"] = "destination", + ["triplet"] = "triplet", + ["word"] = "word", + ["content"] = "text", + }, + + it = { + ["title"] = "setup", + ["formula"] = "formula", + ["number"] = "number", + ["list"] = "list", + ["dimension"] = "dimension", + ["mark"] = "mark", + ["reference"] = "reference", + ["command"] = "command", + ["file"] = "file", + ["name"] = "name", + ["identifier"] = "name", + ["text"] = "text", + ["section"] = "section", + ["singular"] = "singular name", + ["plural"] = "plural name", + ["matrix"] = "n*m", + ["see"] = "see", + ["inherits"] = "inherits from", + ["optional"] = "optioneel", + ["displaymath"] = "formula", + ["index"] = "entry", + ["math"] = "formula", + ["nothing"] = "empty", + ["file"] = "file", + ["position"] = "position", + ["reference"] = "reference", + ["csname"] = "name", + ["destination"] = "destination", + ["triplet"] = "triplet", + ["word"] = "word", + ["content"] = "text", + }, + + ro = { + ["title"] = "setari", + ["formula"] = "formula", + ["number"] = "numar", + ["list"] = "lista", + ["dimension"] = "dimensiune", + ["mark"] = "marcaj", + ["reference"] = "referinta", + ["command"] = "comanda", + ["file"] = "fisier", + ["name"] = "nume", + ["identifier"] = "nume", + ["text"] = "text", + ["section"] = "sectiune", + ["singular"] = "nume singular", + ["plural"] = "nume pluram", + ["matrix"] = "n*m", + ["see"] = "vezi", + ["inherits"] = "inherits from", + ["optional"] = "optioneel", + ["displaymath"] = "formula", + ["index"] = "entry", + ["math"] = "formula", + ["nothing"] = "empty", + ["file"] = "file", + ["position"] = "position", + ["reference"] = "reference", + ["csname"] = "name", + ["destination"] = "destination", + ["triplet"] = "triplet", + ["word"] = "word", + ["content"] = "text", + }, + + fr = { + ["title"] = "réglage", + ["formula"] = "formule", + ["number"] = "numéro", + ["list"] = "liste", + ["dimension"] = "dimension", + ["mark"] = "marquage", + ["reference"] = "reference", + ["command"] = "commande", + ["file"] = "fichier", + ["name"] = "nom", + ["identifier"] = "identificateur", + ["text"] = "texte", + ["section"] = "section", + ["singular"] = "nom singulier", + ["plural"] = "nom pluriel", + ["matrix"] = "n*m", + ["see"] = "vois", + ["inherits"] = "herite de", + ["optional"] = "optionel", + ["displaymath"] = "formule", + ["index"] = "entrée", + ["math"] = "formule", + ["nothing"] = "vide", + ["file"] = "fichier", + ["position"] = "position", + ["reference"] = "réference", + ["csname"] = "nom", + ["destination"] = "destination", + ["triplet"] = "triplet", + ["word"] = "mot", + ["content"] = "texte", + } + +} + +document.setups.formats = { + open_command = { [[\%s]], [[context.%s (]] }, + close_command = { [[]], [[ )]] }, + connector = { [[]], [[, ]] }, + href_in_list = { [[%s]], [[%s]] }, + href_as_command = { [[\%s]], [[context.%s]] }, + interface = [[%s]], + source = [[%s]], + modes = { [[lua mode]], [[tex mode]] }, + optional_single = { "[optional string %s]", "{optional string %s}" }, + optional_list = { "[optional list %s]", "{optional table %s}" } , + mandate_single = { "[mandate string %s]", "{mandate string %s}" }, + mandate_list = { "[mandate list %s]", "{mandate list %s}" }, + parameter = [[%s%s%s]], + parameters = [[%s
]], + listing = [[
%s]],
+    special         = [[%s]],
+    default         = [[%s]],
+}
+
+local function translate(tag,int,noformat)
+    local t = document.setups.translations
+    local te = t["en"]
+    local ti = t[int] or te
+    if noformat then
+        return ti[tag] or te[tag] or tag
+    else
+        return format(document.setups.formats.special,ti[tag] or te[tag] or tag)
+    end
+end
+
+local function translated(e,int)
+    local attributes = e.at
+    local s = attributes.type or "?"
+    local tag = s:match("^cd:(.*)$")
+    if attributes.default == "yes" then
+        return format(document.setups.formats.default,tag or "?")
+    elseif tag then
+        return translate(tag,int)
+    else
+        return s
+    end
+end
+
+document.setups.loaded = document.setups.loaded or { }
+
+document.setups.current = { }
+document.setups.showsources = true
+document.setups.mode = 1
+
+function document.setups.load(filename)
+    filename = resolvers.find_file(filename) or ""
+    if filename ~= "" then
+        local current = document.setups.loaded[filename]
+        if not current then
+            local loaded = xml.load(filename)
+            if loaded then
+                -- xml.inject(document.setups.root,"/",loaded)
+                current = {
+                    file = filename,
+                    root = loaded,
+                    names = { },
+                    used = { },
+                }
+                document.setups.loaded[filename] = current
+            end
+        end
+        document.setups.current = current or { }
+    end
+end
+
+function document.setups.name(ek)
+    local at = ek.at
+    local name = at.name
+    if at.type == 'environment' then
+        name = "start" .. name
+    end
+    if at.variant then
+        name = name .. ":" .. at.variant
+    end
+    if at.generated == "yes" then
+        name = name .. "*"
+    end
+    return name:lower()
+end
+
+function document.setups.csname(ek,int)
+    local cs = ""
+    local at = ek.at or { }
+    if at.type == 'environment' then
+        cs = translate("start",int,true) .. cs
+    end
+    for e in xml.collected(ek,'cd:sequence/(cd:string|variable)') do
+        if e.tg == "string" then
+            cs = cs .. e.at.value
+        else
+            cs = cs .. e.at.value -- to be translated
+        end
+    end
+    return cs
+end
+
+function document.setups.names()
+    local current = document.setups.current
+    local names = current.names
+    if not names or #names == 0 then
+        names = { }
+        local name = document.setups.name
+        local csname = document.setups.csname
+        for e in xml.collected(current.root,'cd:command') do
+            names[#names+1] = { e.at.name, csname(e,int) }
+        end
+        table.sort(names, function(a,b) return a[2]:lower() < b[2]:lower() end)
+        current.names = names
+    end
+    return names
+end
+
+function document.setups.show(name)
+    local current = document.setups.current
+    if current.root then
+        local name = name:gsub("[<>]","")
+        local setup = xml.first(current.root,"cd:command[@name='" .. name .. "']")
+        current.used[#current.used+1] = setup
+        xml.sprint(setup)
+    end
+end
+
+function document.setups.showused()
+    local current = document.setups.current
+    if current.root and next(current.used) then
+        local sorted = table.sortedkeys(current.used)
+        for i=1,#sorted do
+            xml.sprint(current.used[sorted[i]])
+        end
+    end
+end
+function document.setups.showall()
+    local current = document.setups.current
+    if current.root then
+        local list = { }
+        for e in xml.collected(current.root,"cd:command") do
+            list[document.setups.name(e)] = e
+        end
+        local sorted = table.sortedkeys(list)
+        for i=1,#sorted do
+            xml.sprint(list[sorted[i]])
+        end
+    end
+end
+function document.setups.resolve(name)
+    local current = document.setups.current
+    if current.root then
+        local e = xml.filter(current.root,format("cd:define[@name='%s']/text()",name))
+        if e then
+            xml.sprint(e)
+        end
+    end
+end
+
+function document.setups.collect(name,int,lastmode)
+    local current = document.setups.current
+    local formats = document.setups.formats
+    local command = xml.filter(current.root,format("cd:command[@name='%s']/first()",name))
+    if command then
+        local attributes = command.at or { }
+        local data = {
+            command = command,
+            category = attributes.category or "",
+        }
+        if document.setups.showsources then
+            data.source = (attributes.file and formats.source:format(attributes.file,lastmode,attributes.file)) or ""
+        else
+            data.source = attributes.file or ""
+        end
+        local n, sequence, tags = 0, { }, { }
+        sequence[#sequence+1] = formats.open_command[lastmode]:format(document.setups.csname(command,int))
+        local arguments, tag = { }, ""
+        for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
+            n = n + 1
+            local attributes = d[k].at
+            if #sequence > 1 then
+                local c = formats.connector[lastmode]
+                if c ~= "" then
+                    sequence[#sequence+1] = c
+                end
+            end
+            if attributes.optional == 'yes' then
+                if attributes.list == 'yes' then
+                    tag = formats.optional_list[lastmode]:format(n)
+                else
+                    tag = formats.optional_single[lastmode]:format(n)
+                end
+            else
+                if attributes.list == 'yes' then
+                    tag = formats.mandate_list[lastmode]:format(n)
+                else
+                    tag = formats.mandate_single[lastmode]:format(n)
+                end
+            end
+            sequence[#sequence+1] = tag
+            tags[#tags+1] = tag
+        end
+        sequence[#sequence+1] = formats.close_command[lastmode]
+        data.sequence = concat(sequence, " ")
+        local parameters, n = { }, 0
+        for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
+            n = n + 1
+            if d[k].tg == "keywords" then
+                local left = tags[n]
+                local right = { }
+                for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do
+                    local tag = d[k].tg
+                    if tag == "resolve" then
+                        local name = d[k].at.name or ""
+                        if name ~= "" then
+                            local resolved = xml.filter(current.root,format("cd:define[@name='%s']",name))
+                            for r, d, k in xml.elements(resolved,"cd:constant") do
+                                right[#right+1] = translated(d[k],int)
+                            end
+                        end
+                    else
+                        right[#right+1] = translated(d[k],int)
+                    end
+                end
+                parameters[#parameters+1] = formats.parameter:format(left,"",concat(right, ", "))
+            else
+                local what = tags[n]
+                for r, d, k in xml.elements(d[k],"(cd:parameter|cd:inherit)") do
+                    local tag = d[k].tg
+                    local left, right = d[k].at.name or "?", { }
+                    if tag == "inherit" then
+                        local name = d[k].at.name or "?"
+                        local goto = document.setups.formats.href_as_command[lastmode]:format(name,lastmode,name)
+                        if #parameters > 0 and not parameters[#parameters]:find("
") then + parameters[#parameters+1] = formats.parameter:format("
","","") + end + parameters[#parameters+1] = formats.parameter:format(what,formats.special:format(translate("inherits",int)),goto) + else + for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do + local tag = d[k].tg + if tag == "resolve" then + local name = d[k].at.name or "" + if name ~= "" then + local resolved = xml.filter(current.root,format("cd:define[@name='%s']",name)) + for r, d, k in xml.elements(resolved,"cd:constant") do + right[#right+1] = translated(d[k],int) + end + end + else + right[#right+1] = translated(d[k],int) + end + end + parameters[#parameters+1] = formats.parameter:format(what,left,concat(right, ", ")) + end + what = "" + end + end + parameters[#parameters+1] = formats.parameter:format("
","","") + end + data.parameters = parameters or { } + data.mode = formats.modes[lastmode or 1] + return data + else + return nil + end +end + +-- -- -- + +tex = tex or { } + +-- -- -- + +local interfaces = { + czech = 'cz', + dutch = 'nl', + english = 'en', + french = 'fr', + german = 'de', + italian = 'it', + persian = 'pe', + romanian = 'ro', +} + +local lastinterface, lastcommand, lastsource, lastmode = "en", "", "", 1 + +local variables = { + ['color-background-main-left'] = '#3F3F3F', + ['color-background-main-right'] = '#5F5F5F', + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['title'] = 'ConTeXt Help Information', +} + +--~ function lmx.loadedfile(filename) +--~ return io.loaddata(resolvers.find_file(filename)) -- return resolvers.texdatablob(filename) +--~ end + +local function doit(configuration,filename,hashed) + + local formats = document.setups.formats + + local start = os.clock() + + local detail = url.query(hashed.query or "") + + lastinterface = detail.interface or lastinterface + lastcommand = detail.command or lastcommand + lastsource = detail.source or lastsource + lastmode = tonumber(detail.mode or lastmode) or 1 + + if lastinterface then + logs.simple("checking interface: %s",lastinterface) + document.setups.load(format("cont-%s.xml",lastinterface)) + end + + local div = document.setups.div[lastinterface] + local span = document.setups.span[lastinterface] + + local result = { content = "error" } + + local names, refs, ints = document.setups.names(lastinterface), { }, { } + for k=1,#names do + local v = names[k] + refs[k] = formats.href_in_list[lastmode]:format(v[1],lastmode,v[2]) + end + if lastmode ~= 2 then + local sorted = table.sortedkeys(interfaces) + for k=1,#sorted do + local v = sorted[k] + ints[k] = formats.interface:format(interfaces[v],lastmode,v) + end + end + + local n = concat(refs,"
") + local i = concat(ints,"

") + + if div then + variables.names = div:format(n) + variables.interfaces = div:format(i) + else + variables.names = n + variables.interfaces = i + end + + -- first we need to add information about mkii/mkiv + + variables.maintitle = "no definition" + variables.maintext = "" + variables.extra = "" + + if document.setups.showsources and lastsource and lastsource ~= "" then + -- todo: mkii, mkiv, tex (can be different) + local data = io.loaddata(resolvers.find_file(lastsource)) + variables.maintitle = lastsource + variables.maintext = formats.listing:format(data) + lastsource = "" + elseif lastcommand and lastcommand ~= "" then + local data = document.setups.collect(lastcommand,lastinterface,lastmode) + if data then + local what, extra = { "environment", "category", "source", "mode" }, { } + for k=1,#what do + local v = what[k] + if data[v] and data[v] ~= "" then + lmx.set(v, data[v]) + extra[#extra+1] = v .. ": " .. data[v] + end + end + variables.maintitle = data.sequence + variables.maintext = formats.parameters:format(concat(data.parameters)) + variables.extra = concat(extra,"   ") + else + variables.maintext = "select command" + end + end + + local content = lmx.convert('context-help.lmx',false,variables) + + logs.simple("time spent on page: %0.03f seconds",os.clock()-start) + + return { content = content } +end + +return doit, true diff --git a/scripts/context/lua/mtx-server-ctx-startup.lua b/scripts/context/lua/mtx-server-ctx-startup.lua new file mode 100644 index 000000000..59536c36c --- /dev/null +++ b/scripts/context/lua/mtx-server-ctx-startup.lua @@ -0,0 +1,39 @@ +if not modules then modules = { } end modules ['mtx-server-ctx-startup'] = { + version = 1.001, + comment = "Overview Of Goodies", + author = "Hans Hagen", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +dofile(resolvers.find_file("trac-lmx.lua","tex")) + +function doit(configuration,filename,hashed) + + local list = { } + local root = file.dirname(resolvers.find_file("mtx-server.lua") or ".") + if root == "" then root = "." end + local pattern = root .. "/mtx-server-ctx-*.lua" + local files = dir.glob(pattern) + for i=1,#files do + local filename = file.basename(files[i]) + local name = string.match(filename,"mtx%-server%-ctx%-(.-)%.lua$") + if name and name ~= "startup" then + list[#list+1] = string.format("%s

",filename,name,name) + end + end + + local variables = { + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['title'] = "Overview Of Goodies", + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['maintext'] = table.concat(list,"\n"), + } + + return { content = lmx.convert('context-base.lmx',false,variables) } + +end + +return doit, true diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua new file mode 100644 index 000000000..dc0befcaa --- /dev/null +++ b/scripts/context/lua/mtx-server.lua @@ -0,0 +1,361 @@ +if not modules then modules = { } end modules ['mtx-server'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen & Taco Hoekwater", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.webserver = scripts.webserver or { } + +dofile(resolvers.find_file("l-url.lua","tex")) +dofile(resolvers.find_file("luat-soc.lua","tex")) + +local socket = socket or require("socket") -- redundant in future version +local format = string.format + +-- The following two lists are taken from webrick (ruby) and +-- extended with a few extra suffixes. + +local mimetypes = { + ai = 'application/postscript', + asc = 'text/plain', + avi = 'video/x-msvideo', + bin = 'application/octet-stream', + bmp = 'image/bmp', + bz2 = 'application/x-bzip2', + cer = 'application/pkix-cert', + class = 'application/octet-stream', + crl = 'application/pkix-crl', + crt = 'application/x-x509-ca-cert', + css = 'text/css', + dms = 'application/octet-stream', + doc = 'application/msword', + dvi = 'application/x-dvi', + eps = 'application/postscript', + etx = 'text/x-setext', + exe = 'application/octet-stream', + gif = 'image/gif', + gz = 'application/x-tar', + hqx = 'application/mac-binhex40', + htm = 'text/html', + html = 'text/html', + jpe = 'image/jpeg', + jpeg = 'image/jpeg', + jpg = 'image/jpeg', + lha = 'application/octet-stream', + lzh = 'application/octet-stream', + mov = 'video/quicktime', + mpe = 'video/mpeg', + mpeg = 'video/mpeg', + mpg = 'video/mpeg', + pbm = 'image/x-portable-bitmap', + pdf = 'application/pdf', + pgm = 'image/x-portable-graymap', + png = 'image/png', + pnm = 'image/x-portable-anymap', + ppm = 'image/x-portable-pixmap', + ppt = 'application/vnd.ms-powerpoint', + ps = 'application/postscript', + qt = 'video/quicktime', + ras = 'image/x-cmu-raster', + rb = 'text/plain', + rd = 'text/plain', + rgb = 'image/x-rgb', + rtf = 'application/rtf', + sgm = 'text/sgml', + sgml = 'text/sgml', + snd = 'audio/basic', + tar = 'application/x-tar', + tgz = 'application/x-tar', + tif = 'image/tiff', + tiff = 'image/tiff', + txt = 'text/plain', + xbm = 'image/x-xbitmap', + xls = 'application/vnd.ms-excel', + xml = 'text/xml', + xpm = 'image/x-xpixmap', + xwd = 'image/x-xwindowdump', + zip = 'application/zip', +} + +local messages = { + [100] = 'Continue', + [101] = 'Switching Protocols', + [200] = 'OK', + [201] = 'Created', + [202] = 'Accepted', + [203] = 'Non-Authoritative Information', + [204] = 'No Content', + [205] = 'Reset Content', + [206] = 'Partial Content', + [300] = 'Multiple Choices', + [301] = 'Moved Permanently', + [302] = 'Found', + [303] = 'See Other', + [304] = 'Not Modified', + [305] = 'Use Proxy', + [307] = 'Temporary Redirect', + [400] = 'Bad Request', + [401] = 'Unauthorized', + [402] = 'Payment Required', + [403] = 'Forbidden', + [404] = 'Not Found', + [405] = 'Method Not Allowed', + [406] = 'Not Acceptable', + [407] = 'Proxy Authentication Required', + [408] = 'Request Timeout', + [409] = 'Conflict', + [410] = 'Gone', + [411] = 'Length Required', + [412] = 'Precondition Failed', + [413] = 'Request Entity Too Large', + [414] = 'Request-URI Too Large', + [415] = 'Unsupported Media Type', + [416] = 'Request Range Not Satisfiable', + [417] = 'Expectation Failed', + [500] = 'Internal Server Error', + [501] = 'Not Implemented', + [502] = 'Bad Gateway', + [503] = 'Service Unavailable', + [504] = 'Gateway Timeout', + [505] = 'HTTP Version Not Supported', +} + +local handlers = { } + +local function errormessage(client,configuration,n) + local data = format("%s %s

%s %s

",n,messages[n],n,messages[n]) + logs.simple("handling error %s: %s",n,messages[n]) + handlers.generic(client,configuration,data,nil,true) +end + +local validpaths, registered = { }, { } + +function scripts.webserver.registerpath(name) + if not registered[name] then + local cleanname = string.gsub(name,"%.%.","deleted-parent") + logs.simple("registering path '%s'",cleanname) + validpaths[#validpaths+1] = cleanname + registered[name] = true + end +end + +function handlers.generic(client,configuration,data,suffix,iscontent) + if not iscontent then + local name = data + logs.simple("requested file '%s'",name) + local fullname = file.join(configuration.root,name) + data = io.loaddata(fullname) or "" + if data == "" then + for n=1,#validpaths do + local fullname = file.join(validpaths[n],name) + data = io.loaddata(fullname) or "" + if data ~= "" then + logs.simple("sending generic file '%s'",fullname) + break + end + end + else + logs.simple("sending generic file '%s'",fullname) + end + end + if data and data ~= "" then + client:send("HTTP/1.1 200 OK\r\n") + client:send("Connection: close\r\n") + client:send(format("Content-Length: %s\r\n",#data)) + client:send(format("Content-Type: %s\r\n",(suffix and mimetypes[suffix]) or "text/html")) + client:send("\r\n") + client:send(data) + client:send("\r\n") + else + errormessage(client,configuration,404) + end +end + +--~ return os.date() + +--~ return { content = "crap" } + +--~ return function(configuration,filename) +--~ return { content = filename } +--~ end + +local loaded = { } + +function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) -- filename will disappear, and become hashed.filename + local filename = file.join(configuration.scripts,filename) + if not file.is_qualified_path(filename) then + filename = file.join(configuration.root,filename) + end + -- todo: split url in components, see l-url; rather trivial + local result, keep = loaded[filename], false + if result then + logs.simple("reusing script: %s",filename) + else + logs.simple("locating script: %s",filename) + if lfs.isfile(filename) then + logs.simple("loading script: %s",filename) + result = loadfile(filename) + logs.simple("return type: %s",type(result)) + if result and type(result) == "function" then + -- result() should return a table { [type=,] [length=,] content= }, function or string + result, keep = result() + if keep then + logs.simple("saving script: %s",type(result)) + loaded[filename] = result + end + end + else + errormessage(client,configuration,404) + end + end + if result then + if type(result) == "function" then + result = result(configuration,filename,hashed) -- second argument will become query + end + if result and type(result) == "string" then + result = { content = result } + end + if result and type(result) == "table" then + if result.content then + local suffix = result.type or "text/html" + local action = handlers[suffix] or handlers.generic + action(client,configuration,result.content,suffix,true) -- content + elseif result.filename then + local suffix = file.extname(result.filename) or "text/html" + local action = handlers[suffix] or handlers.generic + action(client,configuration,result.filename,suffix,false) -- filename + else + errormessage(client,configuration,404) + end + else + errormessage(client,configuration,500) + end + else + errormessage(client,configuration,404) + end +end + +handlers.luc = handlers.lua +handlers.html = handlers.htm + +local indices = { "index.htm", "index.html" } +local portnumber = 31415 -- pi suits tex + +function scripts.webserver.run(configuration) + -- check configuration + configuration.port = tonumber(configuration.port or os.getenv("MTX_SERVER_PORT") or portnumber) or portnumber + if not configuration.root or not lfs.isdir(configuration.root) then + configuration.root = os.getenv("MTX_SERVER_ROOT") or "." + end + -- locate root and index file in tex tree + if not lfs.isdir(configuration.root) then + for i=1,#indices do + local name = indices[i] + local root = resolvers.resolve("path:" .. name) or "" + if root ~= "" then + configuration.root = root + configuration.index = configuration.index or name + break + end + end + end + configuration.root = dir.expand_name(configuration.root) + if not configuration.index then + for i=1,#indices do + local name = indices[i] + if lfs.isfile(file.join(configuration.root,name)) then + configuration.index = name -- we will prepend the rootpath later + break + end + end + configuration.index = configuration.index or "unknown" + end + if not configuration.scripts or configuration.scripts == "" then + configuration.scripts = dir.expand_name(file.join(configuration.root or ".",configuration.scripts or ".")) + end + -- so far for checks + logs.simple("running at port: %s",configuration.port) + logs.simple("document root: %s",configuration.root or resolvers.ownpath) + logs.simple("main index file: %s",configuration.index) + logs.simple("scripts subpath: %s",configuration.scripts) + logs.simple("context services: http://localhost:%s/mtx-server-ctx-startup.lua",configuration.port) + local server = assert(socket.bind("*", configuration.port)) +--~ local reading = { server } + while true do -- no multiple clients + local start = os.clock() +--~ local input = socket.select(reading) +--~ local client = input:accept() + local client = server:accept() + client:settimeout(configuration.timeout or 60) + local request, e = client:receive() + if e then + errormessage(client,configuration,404) + else + local from = client:getpeername() + logs.simple("request from: %s",tostring(from)) + local fullurl = request:match("GET (.+) HTTP/.*$") -- todo: more clever + fullurl = socket.url.unescape(fullurl) + local hashed = url.hashed(fullurl) + local query = url.query(hashed.query) + local filename = hashed.path + if filename then + filename = socket.url.unescape(filename) + logs.simple("requested action: %s",filename) + if filename:find("%.%.") then + filename = nil -- invalid path + end + if filename == nil or filename == "" or filename == "/" then + filename = configuration.index + logs.simple("invalid filename, forcing: %s",filename) + end + local suffix = file.extname(filename) + local action = handlers[suffix] or handlers.generic + if action then + logs.simple("performing action: %s",filename) + action(client,configuration,filename,suffix,false,hashed) -- filename and no content + else + errormessage(client,configuration,404) + end + else + errormessage(client,configuration,404) + end + end + client:close() + logs.simple("time spent with client: %0.03f seconds",os.clock()-start) + end +end + +logs.extendbanner("Simple Webserver For Helpers 0.10") + +messages.help = [[ +--start start server +--port port to listen to +--root server root +--scripts scripts sub path +--index index file +--auto start on own path +]] + +if environment.argument("auto") then + local path = resolvers.find_file("mtx-server.lua") or "." + scripts.webserver.run { + port = environment.argument("port"), + root = environment.argument("root") or file.dirname(path) or ".", + scripts = environment.argument("scripts") or file.dirname(path) or ".", + } +elseif environment.argument("start") then + scripts.webserver.run { + port = environment.argument("port"), + root = environment.argument("root") or ".", -- "e:/websites/www.pragma-ade.com", + index = environment.argument("index"), + scripts = environment.argument("scripts"), + } +else + logs.help(messages.help) +end + + +-- mtxrun --script server --start => http://localhost:8080/mtx-server-ctx-help.lua diff --git a/scripts/context/lua/mtx-texworks.lua b/scripts/context/lua/mtx-texworks.lua new file mode 100644 index 000000000..73ab846cd --- /dev/null +++ b/scripts/context/lua/mtx-texworks.lua @@ -0,0 +1,99 @@ +if not modules then modules = { } end modules ['mtx-texworks'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.texworks = scripts.texworks or { } + +local texworkspaths = { + "completion", + "configuration", + "dictionaries", + "translations", + "scripts", + "templates", + "TUG" +} + +local texworkssignal = "texworks-context.rme" +local texworkininame = "texworks.ini" + +function scripts.texworks.start(indeed) + local workname = (os.type == "windows" and "texworks.exe") or "texworks" + local fullname = nil + local binpaths = file.split_path(os.getenv("PATH")) or file.split_path(os.getenv("path")) + local usedsignal = texworkssignal + local datapath = resolvers.find_file(usedsignal,"other text files") or "" + if datapath ~= "" then + datapath = file.dirname(datapath) -- data + if datapath == "" then + datapath = resolvers.clean_path(lfs.currentdir()) + end + else + usedsignal = texworkininame + datapath = resolvers.find_file(usedsignal,"other text files") or "" + if datapath == "" then + usedsignal = string.lower(usedsignal) + datapath = resolvers.find_file(usedsignal,"other text files") or "" + end + if datapath ~= "" and lfs.isfile(datapath) then + datapath = file.dirname(datapath) -- TUG + datapath = file.dirname(datapath) -- data + if datapath == "" then + datapath = resolvers.clean_path(lfs.currentdir()) + end + end + end + if datapath == "" then + logs.simple("invalid datapath, maybe you need to regenerate the file database") + return false + end + if not binpaths or #binpaths == 0 then + logs.simple("invalid binpath") + return false + end + for i=1,#binpaths do + local p = file.join(binpaths[i],workname) + if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub + fullname = p + break + end + end + if not fullname then + logs.simple("unable to locate %s",workname) + return false + end + for i=1,#texworkspaths do + dir.makedirs(file.join(datapath,texworkspaths[i])) + end + os.setenv("TW_INIPATH",datapath) + os.setenv("TW_LIBPATH",datapath) + if not indeed or environment.argument("verbose") then + logs.simple("used signal: %s", usedsignal) + logs.simple("data path : %s", datapath) + logs.simple("full name : %s", fullname) + logs.simple("set paths : TW_INIPATH TW_LIBPATH") + end + if indeed then + os.launch(fullname) + end +end + +logs.extendbanner("TeXworks Startup Script 1.00",true) + +messages.help = [[ +--start [--verbose] start texworks +--test report what will happen +]] + +if environment.argument("start") then + scripts.texworks.start(true) +elseif environment.argument("test") then + scripts.texworks.start() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-timing.lua b/scripts/context/lua/mtx-timing.lua new file mode 100644 index 000000000..40e33cdae --- /dev/null +++ b/scripts/context/lua/mtx-timing.lua @@ -0,0 +1,193 @@ +if not modules then modules = { } end modules ['mtx-timing'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, gsub, concat = string.format, string.gsub, table.concat + +dofile(resolvers.find_file("trac-tim.lua","tex")) +dofile(resolvers.find_file("trac-lmx.lua","tex")) + +local meta = [[ + beginfig(%s) ; + begingroup ; + save p, q, b, h, w ; + path p, q, b ; numeric h, w ; + linecap := butt ; + h := 100 ; + w := 800pt ; + p := %s ; + q := %s ; + p := p shifted -llcorner p ; + q := q shifted -llcorner q ; + q := q xstretched w ; + p := p xstretched w ; + b := boundingbox (llcorner p -- llcorner p shifted (w,h)) ; + draw b withcolor white withpen pencircle scaled 4pt ; + draw p withcolor red withpen pencircle scaled 4pt ; + draw q withcolor blue withpen pencircle scaled 2pt ; + endgroup ; + endfig ; +]] + +local html_graphic = [[ +

%s (red) %s (blue)

+ + + + + +
%s +   min: %s
+   max: %s
+   pages: %s
+   average: %s
+
+
+]] + +local html_menu = [[ + %s +]] + +local directrun = true + +local what = { "parameters", "nodes" } + +function plugins.progress.make_svg(filename,other) + local metadata, menudata, c = { }, { }, 0 + metadata[#metadata+1] = 'outputformat := "svg" ;' + for i=1,#what do + local kind, mdk = what[i], { } + menudata[kind] = mdk + for n, name in next, plugins.progress[kind](filename) do + local first = plugins.progress.path(filename,name) + local second = plugins.progress.path(filename,other) + c = c + 1 + metadata[#metadata+1] = format(meta,c,first,second) + mdk[#mdk+1] = { name, c } + end + end + metadata[#metadata+1] = "end ." + metadata = concat(metadata,"\n\n") + if directrun then + dofile(resolvers.find_file("mlib-run.lua","tex")) + commands = commands or { } + commands.writestatus = logs.report + local result = metapost.directrun("metafun","timing data","svg",true,metadata) + return menudata, result + else + local mpname = file.replacesuffix(filename,"mp") + io.savedata(mpname,metadata) + os.execute(format("mpost --progname=context --mem=metafun.mem %s",mpname)) + os.remove(mpname) + os.remove(file.removesuffix(filename).."-mpgraph.mpo") -- brr + os.remove(file.removesuffix(filename)..".log") -- brr + return menudata + end +end + +function plugins.progress.makehtml(filename,other,menudata,metadata) + local graphics = { } + local result = { graphics = graphics } + for i=1,#what do + local kind, menu = what[i], { } + local md = menudata[kind] + result[kind] = menu + for k=1,#md do + local v = md[k] + local name, number = v[1], v[2] + local min = plugins.progress.bot(filename,name) + local max = plugins.progress.top(filename,name) + local pages = plugins.progress.pages(filename) + local average = math.round(max/pages) + if directrun then + local data = metadata[number] + menu[#menu+1] = format(html_menu,name,name) + graphics[#graphics+1] = format(html_graphic,name,name,other,data,min,max,pages,average) + else + local mpname = file.replacesuffix(filename,number) + local data = io.loaddata(mpname) or "" + -- data = gsub(data,"[\n\r]*","") + data = gsub(data,"<%?xml.->","") + menu[#menu+1] = format(html_menu,name,name) + graphics[#graphics+1] = format(html_graphic,name,name,other,data,min,max,pages,average) + os.remove(mpname) + end + end + end + return result +end + +function plugins.progress.valid_file(name) + return name and name ~= "" and lfs.isfile(name .. "-luatex-progress.lut") +end + +function plugins.progress.make_lmx_page(name,launch,remove) + + local filename = name .. "-luatex-progress" + local other = "elapsed_time" + local template = 'context-timing.lmx' + + plugins.progress.convert(filename) + + local menudata, metadata = plugins.progress.make_svg(filename,other) + local htmldata = plugins.progress.makehtml(filename,other,menudata,metadata) + + lmx.htmfile = function(name) return name .. "-timing.xhtml" end + lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end + + local variables = { + ['title-default'] = 'ConTeXt Timing Information', + ['title'] = format('ConTeXt Timing Information: %s',file.basename(name)), + ['parametersmenu'] = concat(htmldata.parameters, "  "), + ['nodesmenu'] = concat(htmldata.nodes, "  "), + ['graphics'] = concat(htmldata.graphics, "\n\n"), + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + } + + if launch then + local htmfile = lmx.show(template,variables) + if remove then + os.sleep(1) -- give time to launch + os.remove(htmfile) + end + else + lmx.make(template,variables) + end + +end + +scripts = scripts or { } +scripts.timings = scripts.timings or { } + +function scripts.timings.xhtml(filename) + if filename == "" then + logs.simple("provide filename") + elseif not plugins.progress.valid_file(filename) then + logs.simple("first run context again with the --timing option") + else + local basename = file.removesuffix(filename) + local launch = environment.argument("launch") + local remove = environment.argument("remove") + plugins.progress.make_lmx_page(basename,launch,remove) + end +end + +logs.extendbanner("ConTeXt Timing Tools 0.10",true) + +messages.help = [[ +--xhtml make xhtml file +--launch launch after conversion +--remove remove after launching +]] + +if environment.argument("xhtml") then + scripts.timings.xhtml(environment.files[1] or "") +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-tools.lua b/scripts/context/lua/mtx-tools.lua new file mode 100644 index 000000000..bf4add168 --- /dev/null +++ b/scripts/context/lua/mtx-tools.lua @@ -0,0 +1,176 @@ +if not modules then modules = { } end modules ['mtx-tools'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local find, format, sub, rep, gsub, lower = string.find, string.format, string.sub, string.rep, string.gsub, string.lower + +scripts = scripts or { } +scripts.tools = scripts.tools or { } + +local bomb_1, bomb_2 = "^\254\255", "^\239\187\191" + +function scripts.tools.disarmutfbomb() + local force, done = environment.argument("force"), false + local files = environment.files + for i=1,#files do + local name = files[i] + if lfs.isfile(name) then + local data = io.loaddata(name) + if not data then + -- just skip + elseif find(data,bomb_1) then + logs.simple("file '%s' has a 2 character utf bomb",name) + if force then + io.savedata(name,(gsub(data,bomb_1,""))) + end + done = true + elseif find(data,bomb_2) then + logs.simple("file '%s' has a 3 character utf bomb",name) + if force then + io.savedata(name,(gsub(data,bomb_2,""))) + end + done = true + else + -- logs.simple("file '%s' has no utf bomb",name) + end + end + end + if done and not force then + logs.simple("use --force to do a real disarming") + end +end + +function scripts.tools.downcase() + local pattern = environment.argument('pattern') or "*" + local recurse = environment.argument('recurse') + local force = environment.argument('force') + local n = 0 + if recurse and not find(pattern,"^%*%*%/") then + pattern = "**/*" .. pattern + end + dir.glob(pattern,function(name) + local basename = file.basename(name) + if lower(basename) ~= basename then + n = n + 1 + if force then + os.rename(name,lower(name)) + end + end + end) + if n > 0 then + if force then + logs.simple("%s files renamed",n) + else + logs.simple("use --force to do a real rename (%s files involved)",n) + end + else + logs.simple("nothing to do") + end +end + + +function scripts.tools.dirtoxml() + + local join, removesuffix, extname, date = file.join, file.removesuffix, file.extname, os.date + + local xmlns = "http://www.pragma-ade.com/rlg/xmldir.rng" + local timestamp = "%Y-%m-%d %H:%M" + + local pattern = environment.argument('pattern') or ".*" + local url = environment.argument('url') or "no-url" + local root = environment.argument('root') or "." + local outputfile = environment.argument('output') + + local recurse = environment.argument('recurse') + local stripname = environment.argument('stripname') + local longname = environment.argument('longname') + + local function flush(list,result,n,path) + n, result = n or 1, result or { } + local d = rep(" ",n) + for name, attr in table.sortedhash(list) do + local mode = attr.mode + if mode == "file" then + result[#result+1] = format("%s",d,(longname and path and join(path,name)) or name) + result[#result+1] = format("%s %s",d,removesuffix(name)) + result[#result+1] = format("%s %s",d,extname(name)) + result[#result+1] = format("%s %s",d,attr.size) + result[#result+1] = format("%s %s",d,sub(attr.permissions,7,9)) + result[#result+1] = format("%s %s",d,date(timestamp,attr.modification)) + result[#result+1] = format("%s",d) + elseif mode == "directory" then + result[#result+1] = format("%s",d,name) + flush(attr.list,result,n+1,(path and join(path,name)) or name) + result[#result+1] = format("%s",d) + end + end + end + + if not pattern or pattern == "" then + logs.report('provide --pattern=') + return + end + + if stripname then + pattern = file.dirname(pattern) + end + + local luapattern = string.topattern(pattern,true) + + lfs.chdir(root) + + local list = dir.collect_pattern(root,luapattern,recurse) + + if list[outputfile] then + list[outputfile] = nil + end + + local result = { "" } + result[#result+1] = format("",url,root,pattern,luapattern,xmlns,date(timestamp)) + flush(list,result) + result[#result+1] = "" + + result = table.concat(result,"\n") + + if not outputfile or outputfile == "" then + texio.write_nl(result) + else + io.savedata(outputfile,result) + end + +end + +logs.extendbanner("Some File Related Goodies 1.01",true) + +messages.help = [[ +--disarmutfbomb remove utf bomb if present + --force remove indeed + +--dirtoxml glob directory into xml + --pattern glob pattern (default: *) + --url url attribute (no processing) + --root the root of the globbed path (default: .) + --output output filename (console by default) + --recurse recurse into subdirecories + --stripname take pathpart of given pattern + --longname set name attributes to full path name + +--downcase + --pattern glob pattern (default: *) + --recurse recurse into subdirecories + --force downcase indeed +]] + +if environment.argument("disarmutfbomb") then + scripts.tools.disarmutfbomb() +elseif environment.argument("dirtoxml") then + scripts.tools.dirtoxml() +elseif environment.argument("downcase") then + scripts.tools.downcase() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtx-unzip.lua b/scripts/context/lua/mtx-unzip.lua new file mode 100644 index 000000000..f990f4210 --- /dev/null +++ b/scripts/context/lua/mtx-unzip.lua @@ -0,0 +1,101 @@ +-- maybe --pattern + +logs.extendbanner("Simple Unzipper 0.10") + +messages.help = [[ +--list list files in archive +--junk flatten unzipped directory structure +--extract extract files +]] + +scripts = scripts or { } +scripts.unzipper = scripts.unzipper or { } + +function scripts.unzipper.help() + logs.help(messages.help) +end + +function scripts.unzipper.opened() + local filename = environment.files[1] + if filename and filename ~= "" then + filename = file.addsuffix(filename,'zip') + local zipfile = zip.open(filename) + if zipfile then + return zipfile + end + end + logs.report("unzip", "no zip file: " .. filename) + return false +end + +function scripts.unzipper.list() + local zipfile = scripts.unzipper.opened() + if zipfile then + local n = 0 + for k in zipfile:files() do + if #k.filename > n then n = #k.filename end + end + local files, paths, compressed, uncompressed = 0, 0, 0, 0 + for k in zipfile:files() do + if k.filename:find("/$") then + paths = paths + 1 + print(string.format("%s", k.filename:rpadd(n," "))) + else + files = files + 1 + local cs, us = k.compressed_size, k.uncompressed_size + if cs > compressed then + compressed = cs + end + if us > uncompressed then + uncompressed = us + end + print(string.format("%s % 9i % 9i", k.filename:rpadd(n," "),cs,us)) + end + end + print(string.format("\n%s % 9i % 9i", (files .. " files, " .. paths .. " directories"):rpadd(n," "),compressed,uncompressed)) + end +end + +function zip.loaddata(zipfile,filename) + local f = zipfile:open(filename) + if f then + local data = f:read("*a") + f:close() + return data + end + return nil +end + +function scripts.unzipper.extract() + local zipfile = scripts.unzipper.opened() + if zipfile then + local junk = environment.arguments["j"] or environment.arguments["junk"] + for k in zipfile:files() do + local filename = k.filename + if filename:find("/$") then + if not junk then + lfs.mkdir(filename) + end + else + local data = zip.loaddata(zipfile,filename) + if data then + if junk then + filename = file.basename(filename) + end + io.savedata(filename,data) + print(filename) + end + end + end + end +end + +if environment.arguments["h"] or environment.arguments["help"] then + scripts.unzipper.help() +elseif environment.arguments["l"] or environment.arguments["list"] then + scripts.unzipper.list(zipfile) +elseif environment.files[1] then -- implicit --extract + scripts.unzipper.extract(zipfile) +else + scripts.unzipper.help() +end diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua new file mode 100644 index 000000000..b56083d38 --- /dev/null +++ b/scripts/context/lua/mtx-update.lua @@ -0,0 +1,580 @@ +if not modules then modules = { } end modules ['mtx-update'] = { + version = 1.002, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This script is dedicated to Mojca Miklavec, who is the driving force behind +-- moving minimal generation from our internal machines to the context garden. +-- Together with Arthur Reutenauer she made sure that it worked well on all +-- platforms that matter. + +local format, concat, gmatch = string.format, table.concat, string.gmatch + +scripts = scripts or { } +scripts.update = scripts.update or { } + +minimals = minimals or { } +minimals.config = minimals.config or { } + +-- this is needed under windows +-- else rsync fails to set the right chmod flags to files + +os.setenv("CYGWIN","nontsec") + +scripts.update.texformats = { + "cont-en", + "cont-nl", + "cont-cz", + "cont-de", + "cont-fa", + "cont-it", + "cont-ro", + "cont-uk", + "cont-pe", + "cont-xp", + "mptopdf", + "plain" +} + +scripts.update.mpformats = { + "metafun", + "mpost", +} + +-- experimental is not functional at the moment + +scripts.update.repositories = { + "current", + "experimental" +} + +-- more options than just these two are available (no idea why this is here) + +scripts.update.versions = { + "current", + "latest" +} + +-- list of basic folders that are needed to make a functional distribution + +scripts.update.base = { + { "base/tex/", "texmf" }, + { "base/metapost/", "texmf" }, + { "fonts/common/", "texmf" }, + { "fonts/other/", "texmf" }, -- not *really* needed, but helpful + { "context//", "texmf-context" }, + { "context/img/", "texmf-context" }, + { "misc/setuptex/", "." }, + { "misc/web2c", "texmf" }, + { "bin/common//", "texmf-" }, + { "bin/context//", "texmf-" }, + { "bin/metapost//", "texmf-" }, + { "bin/man/", "texmf-" }, +} + +-- binaries and font-related files +-- for pdftex we don't need OpenType fonts, for LuaTeX/XeTeX we don't need TFM files + +scripts.update.engines = { + ["luatex"] = { + { "fonts/new/", "texmf" }, + { "bin/luatex//", "texmf-" }, + }, + ["xetex"] = { + { "base/xetex/", "texmf" }, + { "fonts/new/", "texmf" }, + { "bin/luatex//", "texmf-" }, -- tools + { "bin/xetex//", "texmf-" }, + }, + ["pdftex"] = { + { "fonts/old/", "texmf" }, + { "bin/luatex//", "texmf-" }, -- tools + { "bin/pdftex//", "texmf-" }, + }, + ["all"] = { + { "fonts/new/", "texmf" }, + { "fonts/old/", "texmf" }, + { "base/xetex/", "texmf" }, + { "bin/luatex//", "texmf-" }, + { "bin/xetex//", "texmf-" }, + { "bin/pdftex//", "texmf-" }, + }, +} + +scripts.update.goodies = { + ["scite"] = { + { "bin//scite/", "texmf-" }, + }, + ["texworks"] = { + { "bin//texworks/", "texmf-" }, + }, +} + +scripts.update.platforms = { + ["mswin"] = "mswin", + ["windows"] = "mswin", + ["win32"] = "mswin", + ["win"] = "mswin", + ["linux"] = "linux", + ["freebsd"] = "freebsd", + ["freebsd-amd64"] = "freebsd-amd64", + ["kfreebsd"] = "kfreebsd-i386", + ["kfreebsd-i386"] = "kfreebsd-i386", + ["kfreebsd-amd64"] = "kfreebsd-amd64", + ["linux-32"] = "linux", + ["linux-64"] = "linux-64", + ["linux32"] = "linux", + ["linux64"] = "linux-64", + ["linux-ppc"] = "linux-ppc", + ["ppc"] = "linux-ppc", + ["osx"] = "osx-intel", + ["macosx"] = "osx-intel", + ["osx-intel"] = "osx-intel", + ["osx-ppc"] = "osx-ppc", + ["osx-powerpc"] = "osx-ppc", + ["osx-64"] = "osx-64", + ["osxintel"] = "osx-intel", + ["osxppc"] = "osx-ppc", + ["osxpowerpc"] = "osx-ppc", + ["solaris-intel"] = "solaris-intel", + ["solaris-sparc"] = "solaris-sparc", + ["solaris"] = "solaris-sparc", +} + +-- the list is filled up later (when we know what modules to download) + +scripts.update.modules = { +} + +function scripts.update.run(str) + -- important, otherwise formats fly to a weird place + -- (texlua sets luatex as the engine, we need to reset that or to fix texexec :) + os.setenv("engine",nil) + if environment.argument("force") then + logs.report("run", str) + os.execute(str) + else + logs.report("dry run", str) + end +end + +function scripts.update.fullpath(path) + if file.is_rootbased_path(path) then + return path + else + return lfs.currentdir() .. "/" .. path + end +end + +function scripts.update.synchronize() + + logs.report("update","start") + + local texroot = scripts.update.fullpath(states.get("paths.root")) + local engines = states.get('engines') or { } + local platforms = states.get('platforms') or { } + local repositories = states.get('repositories') -- minimals + local bin = states.get("rsync.program") -- rsync + local url = states.get("rsync.server") -- contextgarden.net + local version = states.get("context.version") -- current (or beta) + local extras = states.get("extras") -- extras (like modules) + local goodies = states.get("goodies") -- goodies (like editors) + local force = environment.argument("force") + + bin = string.gsub(bin,"\\","/") + + if not url:find("::$") then url = url .. "::" end + local ok = lfs.attributes(texroot,"mode") == "directory" + if not ok and force then + dir.mkdirs(texroot) + ok = lfs.attributes(texroot,"mode") == "directory" + end + + if force then + dir.mkdirs(format("%s/%s", texroot, "texmf-cache")) + dir.mkdirs(format("%s/%s", texroot, "texmf-local")) + dir.mkdirs(format("%s/%s", texroot, "texmf-project")) + end + + if ok or not force then + + local fetched, individual, osplatform = { }, { }, os.platform + + -- takes a collection as argument and returns a list of folders + + local function collection_to_list_of_folders(collection, platform) + local archives = {} + for i=1,#collection do + local archive = collection[i][1] + archive = archive:gsub("", platform) + archive = archive:gsub("", version) + archives[#archives+1] = archive + end + return archives + end + + -- takes a list of folders as argument and returns a string for rsync + -- sample input: + -- {'bin/common', 'bin/context'} + -- output: + -- 'minimals/current/bin/common minimals/current/bin/context' + + local function list_of_folders_to_rsync_string(list_of_folders) + local repository = 'current' + local prefix = format("%s/%s/", states.get('rsync.module'), repository) -- minimals/current/ + + return prefix .. concat(list_of_folders, format(" %s", prefix)) + end + + -- example of usage: print(list_of_folders_to_rsync_string(collection_to_list_of_folders(scripts.update.base, os.platform))) + + -- rename function and add some more functionality: + -- * recursive/non-recursive (default: non-recursive) + -- * filter folders or regular files only (default: no filter) + -- * grep for size of included files (with --stats switch) + + local function get_list_of_files_from_rsync(list_of_folders) + -- temporary file to store the output of rsync (could be a more random name; watch for overwrites) + local temp_file = "rsync.tmp.txt" + -- a set of folders + local folders = {} + local command = format("%s %s'%s' > %s", bin, url, list_of_folders_to_rsync_string(list_of_folders), temp_file) + os.execute(command) + -- read output of rsync + local data = io.loaddata(temp_file) or "" + -- for every line extract the filename + for chmod, s in data:gmatch("([d%-][rwx%-]+).-(%S+)[\n\r]") do + -- skip "current" folder + if s ~= '.' and chmod:len() == 10 then + folders[#folders+1] = s + end + end + -- delete the file to which we have put output of rsync + os.remove(temp_file) + return folders + end + + -- rsync://contextgarden.net/minimals/current/modules/ + + if extras and type(extras) == "table" then + -- fetch the list of available modules from rsync server + local available_modules = get_list_of_files_from_rsync({"modules/"}) + -- hash of requested modules + -- local h = table.tohash(extras:split(",")) + for i=1,#available_modules do + local s = available_modules[i] + -- if extras == "all" or h[s] then + if extras.all or extras[s] then + scripts.update.modules[#scripts.update.modules+1] = { format("modules/%s/",s), "texmf-context" } + end + end + -- TODO: check if every module from the list has been added and issue warning otherwise + -- one idea to do it: remove every value from h once added and then check if anything is left in h + end + + local function add_collection(collection,platform) + if collection and platform then + platform = scripts.update.platforms[platform] + if platform then + for i=1,#collection do + local c = collection[i] + local archive = c[1]:gsub("", platform) + local destination = format("%s/%s", texroot, c[2]:gsub("", platform)) + destination = destination:gsub("\\","/") + archive = archive:gsub("",version) + if osplatform == "windows" or osplatform == "mswin" then + destination = destination:gsub("([a-zA-Z]):/", "/cygdrive/%1/") + end + individual[#individual+1] = { archive, destination } + end + end + end + end + + for platform, _ in next, platforms do + add_collection(scripts.update.base,platform) + end + for platform, _ in next, platforms do + add_collection(scripts.update.modules,platform) + end + for engine, _ in next, engines do + for platform, _ in next, platforms do + add_collection(scripts.update.engines[engine],platform) + end + end + + if goodies and type(goodies) == "table" then + for goodie, _ in next, goodies do + for platform, _ in next, platforms do + add_collection(scripts.update.goodies[goodie],platform) + end + end + end + + local combined = { } + local update_repositories = scripts.update.repositories + for i=1,#update_repositories do + local repository = update_repositories[i] + if repositories[repository] then + for _, v in next, individual do + local archive, destination = v[1], v[2] + local cd = combined[destination] + if not cd then + cd = { } + combined[destination] = cd + end + cd[#cd+1] = format("%s/%s/%s",states.get('rsync.module'),repository,archive) + end + end + end + if logs.verbose then + for k, v in next, combined do + logs.report("update", k) + for i=1,#v do + logs.report("update", " <= " .. v[i]) + end + end + end + for destination, archive in next, combined do + local archives, command = concat(archive," "), "" + -- local normalflags, deleteflags = states.get("rsync.flags.normal"), states.get("rsync.flags.delete") + -- if environment.argument("keep") or destination:find("%.$") then + -- command = format("%s %s %s'%s' '%s'", bin, normalflags, url, archives, destination) + -- else + -- command = format("%s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, url, archives, destination) + -- end + local normalflags, deleteflags = states.get("rsync.flags.normal"), "" + local dryrunflags = "" + if not environment.argument("force") then + dryrunflags = "--dry-run" + end + if (destination:find("texmf$") or destination:find("texmf%-context$")) and (not environment.argument("keep")) then + deleteflags = states.get("rsync.flags.delete") + end + command = format("%s %s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, dryrunflags, url, archives, destination) + --logs.report("mtx update", format("running command: %s",command)) + if not fetched[command] then + scripts.update.run(command,true) + fetched[command] = command + end + end + + local function update_script(script, platform) + local bin = bin:gsub("\\","/") + local texroot = texroot:gsub("\\","/") + platform = scripts.update.platforms[platform] + if platform then + local command + if platform == 'mswin' then + bin = bin:gsub("([a-zA-Z]):/", "/cygdrive/%1/") + texroot = texroot:gsub("([a-zA-Z]):/", "/cygdrive/%1/") + command = string.format("%s -t %s/texmf-context/scripts/context/lua/%s.lua %s/texmf-mswin/bin/", bin, texroot, script, texroot) + else + command = string.format("%s -tgo --chmod=a+x %s/texmf-context/scripts/context/lua/%s.lua %s/texmf-%s/bin/%s", bin, texroot, script, texroot, platform, script) + end + logs.report("mtx update", format("updating %s for %s: %s", script, platform, command)) + scripts.update.run(command) + end + end + + for platform, _ in next, platforms do + update_script('luatools',platform) + update_script('mtxrun',platform) + end + + else + logs.report("mtx update", format("no valid texroot: %s",texroot)) + end + if not force then + logs.report("update", "use --force to really update files") + end + + resolvers.load_tree(texroot) -- else we operate in the wrong tree + + -- update filename database for pdftex/xetex + scripts.update.run("mktexlsr") + -- update filename database for luatex + scripts.update.run("luatools --generate") + + logs.report("update","done") +end + +function table.fromhash(t) + local h = { } + for k, v in next, t do -- not indexed + if v then h[#h+1] = k end + end + return h +end + +-- make the ConTeXt formats +function scripts.update.make() + + logs.report("make","start") + + local force = environment.argument("force") + local texroot = scripts.update.fullpath(states.get("paths.root")) + local engines = states.get('engines') + local goodies = states.get('goodies') + local platforms = states.get('platforms') + local formats = states.get('formats') + + resolvers.load_tree(texroot) + + scripts.update.run("mktexlsr") + scripts.update.run("luatools --generate") + + local askedformats = formats + local texformats = table.tohash(scripts.update.texformats) + local mpformats = table.tohash(scripts.update.mpformats) + for k,v in next, texformats do + if not askedformats[k] then + texformats[k] = nil + end + end + for k,v in next, mpformats do + if not askedformats[k] then + mpformats[k] = nil + end + end + local formatlist = concat(table.fromhash(texformats), " ") + if formatlist ~= "" then + for engine in next, engines do + if engine == "luatex" then + scripts.update.run(format("context --make")) -- maybe also formatlist + else + -- todo: just handle make here or in mtxrun --script context --make + scripts.update.run(format("texexec --make --all --fast --%s %s",engine,formatlist)) + end + end + end + local formatlist = concat(table.fromhash(mpformats), " ") + if formatlist ~= "" then + scripts.update.run(format("texexec --make --all --fast %s",formatlist)) + end + if not force then + logs.report("make", "use --force to really make formats") + end + scripts.update.run("mktexlsr") + scripts.update.run("luatools --generate") + logs.report("make","done") +end + +logs.extendbanner("ConTeXt Minimals Updater 0.21",true) + +messages.help = [[ +--platform=string platform (windows, linux, linux-64, osx-intel, osx-ppc, linux-ppc) +--server=string repository url (rsync://contextgarden.net) +--module=string repository url (minimals) +--repository=string specify version (current, experimental) +--context=string specify version (current, latest, yyyy.mm.dd) +--rsync=string rsync binary (rsync) +--texroot=string installation directory (not guessed for the moment) +--engine=string tex engine (luatex, pdftex, xetex) +--extras=string extra modules (can be list or 'all') +--goodies=string extra binaries (like scite and texworks) +--force instead of a dryrun, do the real thing +--update update minimal tree +--make also make formats and generate file databases +--keep don't delete unused or obsolete files +--state update tree using saved state +]] + +scripts.savestate = true + +if scripts.savestate then + + states.load("status-of-update.lua") + + -- tag, value, default, persistent + + statistics.starttiming(states) + + states.set("info.version",0.1) -- ok + states.set("info.count",(states.get("info.count") or 0) + 1,1,false) -- ok + states.set("info.comment","this file contains the settings of the last 'mtxrun --script update ' run",false) -- ok + states.set("info.date",os.date("!%Y-%m-%d %H:%M:%S")) -- ok + + states.set("rsync.program", environment.argument("rsync"), "rsync", true) -- ok + states.set("rsync.server", environment.argument("server"), "contextgarden.net::", true) -- ok + states.set("rsync.module", environment.argument("module"), "minimals", true) -- ok + states.set("rsync.flags.normal", environment.argument("flags"), "-rpztlv", true) -- ok + states.set("rsync.flags.delete", nil, "--delete", true) -- ok + + states.set("paths.root", environment.argument("texroot"), "tex", true) -- ok + + states.set("context.version", environment.argument("context"), "current", true) -- ok + + local valid = table.tohash(scripts.update.repositories) + for r in gmatch(environment.argument("repository") or "current","([^, ]+)") do + if valid[r] then states.set("repositories." .. r, true) end + end + local valid = scripts.update.engines + for r in gmatch(environment.argument("engine") or "all","([^, ]+)") do + if r == "all" then + for k, v in next, valid do + if k ~= "all" then + states.set("engines." .. k, true) + end + end + elseif valid[r] then + states.set("engines." .. r, true) + end + end + local valid = scripts.update.platforms + for r in gmatch(environment.argument("platform") or os.platform,"([^, ]+)") do + if valid[r] then states.set("platforms." .. r, true) end + end + + local valid = table.tohash(scripts.update.texformats) + for r in gmatch(environment.argument("formats") or "","([^, ]+)") do + if valid[r] then states.set("formats." .. r, true) end + end + local valid = table.tohash(scripts.update.mpformats) + for r in gmatch(environment.argument("formats") or "","([^, ]+)") do + if valid[r] then states.set("formats." .. r, true) end + end + + states.set("formats.cont-en", true) + states.set("formats.cont-nl", true) + states.set("formats.metafun", true) + + for r in gmatch(environment.argument("extras") or "","([^, ]+)") do + states.set("extras." .. r, true) + end + for r in gmatch(environment.argument("goodies") or "","([^, ]+)") do + states.set("goodies." .. r, true) + end + + logs.report("state","loaded") + +end + +if environment.argument("state") then + environment.setargument("update",true) + environment.setargument("force",true) + environment.setargument("make",true) +end + +if environment.argument("update") then + scripts.update.synchronize() + if environment.argument("make") then + scripts.update.make() + end +elseif environment.argument("make") then + scripts.update.make() +else + logs.help(messages.help) +end + +if scripts.savestate then + statistics.stoptiming(states) + states.set("info.runtime",tonumber(statistics.elapsedtime(states))) + if environment.argument("force") then + states.save() + logs.report("state","saved") + end +end diff --git a/scripts/context/lua/mtx-watch.lua b/scripts/context/lua/mtx-watch.lua new file mode 100644 index 000000000..10f01cf86 --- /dev/null +++ b/scripts/context/lua/mtx-watch.lua @@ -0,0 +1,382 @@ +if not modules then modules = { } end modules ['mtx-watch'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.watch = scripts.watch or { } + +local format, concat, difftime, time = string.format, table.concat, os.difftime, os.time +local next, type = next, type + +-- the machine/instance matches the server app we use + +local machine = socket.dns.gethostname() or "unknown-machine" +local instance = string.match(machine,"(%d+)$") or "0" + +function scripts.watch.save_exa_modes(joblog,ctmname) + local values = joblog and joblog.values + if values then + local t= { } + t[#t+1] = "\n" + t[#t+1] = "" + for k, v in next, joblog.values do + t[#t+1] = format("\t%s", k, tostring(v)) + end + t[#t+1] = "" + io.savedata(ctmname,concat(t,"\n")) + else + os.remove(ctmname) + end +end + +local function toset(t) + if type(t) == "table" then + return concat(t,",") + else + return t + end +end + +local function noset(t) + if type(t) == "table" then + return t[1] + else + return t + end +end + +local lfsdir, lfsattributes = lfs.dir, lfs.attributes + +local function glob(files,path) + for name in lfsdir(path) do + if name:find("^%.") then + -- skip . and .. + else + name = path .. "/" .. name + local a = lfsattributes(name) + if not a then + -- weird + elseif a.mode == "directory" then + if name:find("graphics$") or name:find("figures$") or name:find("resources$") then + -- skip these too + else + glob(files,name) + end + elseif name:find(".%luj$") then + files[name] = a.change or a.ctime or a.modification or a.mtime + end + end + end +end + +local clock = os.gettimeofday or os.time -- we cannot trust os.clock on linux + +function scripts.watch.watch() + local delay = tonumber(environment.argument("delay") or 5) or 5 + if delay == 0 then + delay = .25 + end + local logpath = environment.argument("logpath") or "" + local pipe = environment.argument("pipe") or false + local watcher = "mtxwatch.run" + local paths = environment.files + if #paths > 0 then + if environment.argument("automachine") then + logpath = string.gsub(logpath,"/machine/","/"..machine.."/") + for i=1,#paths do + paths[i] = string.gsub(paths[i],"/machine/","/"..machine.."/") + end + end + for i=1,#paths do + logs.report("watch", "watching path ".. paths[i]) + end + local function process() + local done = false + for i=1,#paths do + local path = paths[i] + lfs.chdir(path) + local files = { } + glob(files,path) + table.sort(files) -- what gets sorted here, todo: by time + for name, time in next, files do + --~ local ok, joblog = xpcall(function() return dofile(name) end, function() end ) + local ok, joblog = pcall(dofile,name) + if ok and joblog then + if joblog.status == "processing" then + logs.report("watch",format("aborted job, %s added to queue",name)) + joblog.status = "queued" + io.savedata(name, table.serialize(joblog,true)) + elseif joblog.status == "queued" then + local command = joblog.command + if command then + local replacements = { + inputpath = toset((joblog.paths and joblog.paths.input ) or "."), + outputpath = noset((joblog.paths and joblog.paths.output) or "."), + filename = joblog.filename or "", + } + -- todo: revision path etc + command = command:gsub("%%(.-)%%", replacements) + if command ~= "" then + joblog.status = "processing" + joblog.runtime = clock() + io.savedata(name, table.serialize(joblog,true)) + logs.report("watch",format("running: %s", command)) + local newpath = file.dirname(name) + io.flush() + local result = "" + local ctmname = file.basename(replacements.filename) + if ctmname == "" then ctmname = name end -- use self as fallback + ctmname = file.replacesuffix(ctmname,"ctm") + if newpath ~= "" and newpath ~= "." then + local oldpath = lfs.currentdir() + lfs.chdir(newpath) + scripts.watch.save_exa_modes(joblog,ctmname) + if pipe then result = os.resultof(command) else result = os.spawn(command) end + lfs.chdir(oldpath) + else + scripts.watch.save_exa_modes(joblog,ctmname) + if pipe then result = os.resultof(command) else result = os.spawn(command) end + end + logs.report("watch",format("return value: %s", result)) + done = true + local path, base = replacements.outputpath, file.basename(replacements.filename) + joblog.runtime = clock() - joblog.runtime + if base ~= "" then + joblog.result = file.replacesuffix(file.join(path,base),"pdf") + joblog.size = lfs.attributes(joblog.result,"size") + end + joblog.status = "finished" + else + joblog.status = "invalid command" + end + else + joblog.status = "no command" + end + -- pcall, when error sleep + again + -- todo: just one log file and append + io.savedata(name, table.serialize(joblog,true)) + if logpath and logpath ~= "" then + local name = file.join(logpath,os.uuid() .. ".lua") + io.savedata(name, table.serialize(joblog,true)) + logs.report("watch", "saving joblog in " .. name) + end + end + end + end + end + end + local n, start = 0, time() +--~ local function wait() +--~ io.flush() +--~ if not done then +--~ n = n + 1 +--~ if n >= 10 then +--~ logs.report("watch", format("run time: %i seconds, memory usage: %0.3g MB", difftime(time(),start), (status.luastate_bytes/1024)/1000)) +--~ n = 0 +--~ end +--~ os.sleep(delay) +--~ end +--~ end + local wtime = 0 + local function wait() + io.flush() + if not done then + n = n + 1 + if n >= 10 then + logs.report("watch", format("run time: %i seconds, memory usage: %0.3g MB", difftime(time(),start), (status.luastate_bytes/1024)/1000)) + n = 0 + end + local ttime = 0 + while ttime <= delay do + local wt = lfs.attributes(watcher,"mtime") + if wt and wt ~= wtime then + -- fast signal that there is a request + wtime = wt + break + end + ttime = ttime + 0.2 + os.sleep(0.2) + end + end + end + local cleanupdelay, cleanup = environment.argument("cleanup"), false + if cleanupdelay then + local lasttime = time() + cleanup = function() + local currenttime = time() + local delta = difftime(currenttime,lasttime) + if delta > cleanupdelay then + lasttime = currenttime + for i=1,#paths do + local path = paths[i] + if string.find(path,"%.") then + -- safeguard, we want a fully qualified path + else + local files = dir.glob(file.join(path,"*")) + for i=1,#files do + local name = files[i] + local filetime = lfs.attributes(name,"modification") + local delta = difftime(currenttime,filetime) + if delta > cleanupdelay then + -- logs.report("watch",format("cleaning up '%s'",name)) + os.remove(name) + end + end + end + end + end + end + else + cleanup = function() + -- nothing + end + end + while true do + if false then +--~ if true then + process() + cleanup() + wait() + else + pcall(process) + pcall(cleanup) + pcall(wait) + end + end + else + logs.report("watch", "no paths to watch") + end +end + +function scripts.watch.collect_logs(path) -- clean 'm up too + path = path or environment.argument("logpath") or "" + path = (path == "" and ".") or path + local files = dir.globfiles(path,false,"^%d+%.lua$") + local collection = { } + local valid = table.tohash({"filename","result","runtime","size","status"}) + for i=1,#files do + local name = files[i] + local t = dofile(name) + if t and type(t) == "table" and t.status then + for k, v in next, t do + if not valid[k] then + t[k] = nil + end + end + collection[name:gsub("[^%d]","")] = t + end + end + return collection +end + +function scripts.watch.save_logs(collection,path) -- play safe + if collection and next(collection) then + path = path or environment.argument("logpath") or "" + path = (path == "" and ".") or path + local filename = format("%s/collected-%s.lua",path,tostring(time())) + io.savedata(filename,table.serialize(collection,true)) + local check = dofile(filename) + for k,v in next, check do + if not collection[k] then + logs.error("watch", "error in saving file") + os.remove(filename) + return false + end + end + for k,v in next, check do + os.remove(format("%s.lua",k)) + end + return true + else + return false + end +end + +function scripts.watch.collect_collections(path) -- removes duplicates + path = path or environment.argument("logpath") or "" + path = (path == "" and ".") or path + local files = dir.globfiles(path,false,"^collected%-%d+%.lua$") + local collection = { } + for i=1,#files do + local name = files[i] + local t = dofile(name) + if t and type(t) == "table" then + for k, v in next, t do + collection[k] = v + end + end + end + return collection +end + +function scripts.watch.show_logs(path) -- removes duplicates + local collection = scripts.watch.collect_collections(path) or { } + local max = 0 + for k,v in next, collection do + v = v.filename or "?" + if #v > max then max = #v end + end + -- print(max) + local sorted = table.sortedkeys(collection) + for k=1,#sorted do + local v = sorted[k] + local c = collection[v] + local f, s, r, n = c.filename or "?", c.status or "?", c.runtime or 0, c.size or 0 + logs.report("watch", format("%s %s %3i %8i %s",string.padd(f,max," "),string.padd(s,10," "),r,n,v)) + end +end + +function scripts.watch.cleanup_stale_files() -- removes duplicates + local path = environment.files[1] + local delay = tonumber(environment.argument("cleanup")) + local force = environment.argument("force") + if not path or path == "." then + logs.report("watch","provide qualified path") + elseif not delay then + logs.report("watch","missing --cleanup=delay") + else + logs.report("watch","dryrun, use --force for real cleanup") + local files = dir.glob(file.join(path,"*")) + local rtime = time() + for i=1,#files do + local name = files[i] + local mtime = lfs.attributes(name,"modification") + local delta = difftime(rtime,mtime) + if delta > delay then + logs.report("watch",format("cleaning up '%s'",name)) + if force then + os.remove(name) + end + end + end + end +end + +logs.extendbanner("ConTeXt Request Watchdog 1.00",true) + +messages.help = [[ +--logpath optional path for log files +--watch watch given path [--delay] +--pipe use pipe instead of execute +--delay delay between sweeps +--automachine replace /machine/ in path // +--collect condense log files +--cleanup=delay remove files in given path [--force] +--showlog show log data +]] + +if environment.argument("watch") then + scripts.watch.watch() +elseif environment.argument("collect") then + scripts.watch.save_logs(scripts.watch.collect_logs()) +elseif environment.argument("cleanup") then + scripts.watch.save_logs(scripts.watch.cleanup_stale_files()) +elseif environment.argument("showlog") then + scripts.watch.show_logs() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua new file mode 100644 index 000000000..b99327692 --- /dev/null +++ b/scripts/context/lua/mtxrun.lua @@ -0,0 +1,12639 @@ +#!/usr/bin/env texlua + +if not modules then modules = { } end modules ['mtxrun'] = { + version = 1.001, + comment = "runner, lua replacement for texmfstart.rb", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + + +-- one can make a stub: +-- +-- #!/bin/sh +-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@" + +-- filename : mtxrun.lua +-- comment : companion to context.tex +-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL +-- copyright: PRAGMA ADE / ConTeXt Development Team +-- license : see context related readme files + +-- This script is based on texmfstart.rb but does not use kpsewhich to +-- locate files. Although kpse is a library it never came to opening up +-- its interface to other programs (esp scripting languages) and so we +-- do it ourselves. The lua variant evolved out of an experimental ruby +-- one. Interesting is that using a scripting language instead of c does +-- not have a speed penalty. Actually the lua variant is more efficient, +-- especially when multiple calls to kpsewhich are involved. The lua +-- library also gives way more control. + +-- to be done / considered +-- +-- support for --exec or make it default +-- support for jar files (or maybe not, never used, too messy) +-- support for $RUBYINPUTS cum suis (if still needed) +-- remember for subruns: _CTX_K_V_#{original}_ +-- remember for subruns: _CTX_K_S_#{original}_ +-- remember for subruns: TEXMFSTART.#{original} [tex.rb texmfstart.rb] + +texlua = true + +-- begin library merge + + + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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')) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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") + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-tra'] = { + version = 1.001, + comment = "companion to trac-tra.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + +debugger = debugger or { } + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in next, counters do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ print("") +--~ debugger.showstats(print,3) + +setters = setters or { } +setters.data = setters.data or { } + +--~ local function set(t,what,value) +--~ local data, done = t.data, t.done +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end + +local function set(t,what,value) + local data, done = t.data, t.done + if type(what) == "string" then + what = aux.settings_to_hash(what) -- inefficient but ok + end + for w, v in next, what do + if v == "" then + v = value + else + v = toboolean(v) + end + for d, f in next, data do + if done[d] then + -- prevent recursion due to wildcards + elseif find(d,w) then + done[d] = true + for i=1,#f do + f[i](v) + end + end + end + end +end + +local function reset(t) + for d, f in next, t.data do + for i=1,#f do + f[i](false) + end + end +end + +local function enable(t,what) + set(t,what,true) +end + +local function disable(t,what) + local data = t.data + if not what or what == "" then + t.done = { } + reset(t) + else + set(t,what,false) + end +end + +function setters.register(t,what,...) + local data = t.data + what = lower(what) + local w = data[what] + if not w then + w = { } + data[what] = w + end + for _, fnc in next, { ... } do + local typ = type(fnc) + if typ == "function" then + w[#w+1] = fnc + elseif typ == "string" then + w[#w+1] = function(value) set(t,fnc,value,nesting) end + end + end +end + +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(tostring(what))) + t.enable, t.done = e, { } +end + +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(tostring(what))) + t.disable, t.done = e, { } +end + +function setters.reset(t) + t.done = { } + reset(t) +end + +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) + local user, system = { }, { } + for l=1,#list do + local what = list[l] + if find(what,"^%*") then + system[#system+1] = what + else + user[#user+1] = what + end + end + return user, system +end + +function setters.show(t) + commands.writestatus("","") + local list = setters.list(t) + for k=1,#list do + commands.writestatus(t.name,list[k]) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singular tracker + +-- we could make this into a module + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") +experiments = setters.new("experiments") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) +local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +local e = experiments.enable +local d = experiments.disable + +function experiments.enable(...) + commands.writestatus("experiments","enabling: %s",concat({...}," ")) + e(...) +end + +function experiments.disable(...) + commands.writestatus("experiments","disabling: %s",concat({...}," ")) + d(...) +end + +-- a useful example + +directives.register("system.nostatistics", function(v) + statistics.enable = not v +end) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-inf'] = { + version = 1.001, + comment = "companion to trac-inf.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 statusinfo, n, registered = { }, 0, { } + +statistics = statistics or { } + +statistics.enable = true +statistics.threshold = 0.05 + +-- timing functions + +local clock = os.gettimeofday or os.clock + +local notimer + +function statistics.hastimer(instance) + return instance and instance.starttime +end + +function statistics.resettiming(instance) + if not instance then + notimer = { timing = 0, loadtime = 0 } + else + instance.timing, instance.loadtime = 0, 0 + end +end + +function statistics.starttiming(instance) + if not instance then + notimer = { } + instance = notimer + end + local it = instance.timing + if not it then + it = 0 + end + if it == 0 then + instance.starttime = clock() + if not instance.loadtime then + instance.loadtime = 0 + end + else +--~ logs.report("system","nested timing (%s)",tostring(instance)) + end + instance.timing = it + 1 +end + +function statistics.stoptiming(instance, report) + if not instance then + instance = notimer + end + if instance then + local it = instance.timing + if it > 1 then + instance.timing = it - 1 + else + local starttime = instance.starttime + if starttime then + local stoptime = clock() + local loadtime = stoptime - starttime + instance.stoptime = stoptime + instance.loadtime = instance.loadtime + loadtime + if report then + statistics.report("load time %0.3f",loadtime) + end + instance.timing = 0 + return loadtime + end + end + end + return 0 +end + +function statistics.elapsedtime(instance) + if not instance then + instance = notimer + end + return format("%0.3f",(instance and instance.loadtime) or 0) +end + +function statistics.elapsedindeed(instance) + if not instance then + instance = notimer + end + local t = (instance and instance.loadtime) or 0 + return t > statistics.threshold +end + +function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds + if statistics.elapsedindeed(instance) then + return format("%s seconds %s", statistics.elapsedtime(instance),rest or "") + end +end + +-- general function + +function statistics.register(tag,fnc) + if statistics.enable and type(fnc) == "function" then + local rt = registered[tag] or (#statusinfo + 1) + statusinfo[rt] = { tag, fnc } + registered[tag] = rt + if #tag > n then n = #tag end + end +end + +function statistics.show(reporter) + if statistics.enable then + if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end + -- this code will move + local register = statistics.register + register("luatex banner", function() + return string.lower(status.banner) + end) + register("control sequences", function() + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) + end) + register("callbacks", function() + local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 + return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total) + end) + register("current memory usage", statistics.memused) + register("runtime",statistics.runtime) +-- -- + for i=1,#statusinfo do + local s = statusinfo[i] + local r = s[2]() + if r then + reporter(s[1],r,n) + end + end + texio.write_nl("") -- final newline + statistics.enable = false + end +end + +function statistics.show_job_stat(tag,data,n) + texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data)) +end + +function statistics.memused() -- no math.round yet -) + local round = math.round or math.floor + return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) +end + +if statistics.runtime then + -- already loaded and set +elseif luatex and luatex.starttime then + statistics.starttime = luatex.starttime + statistics.loadtime = 0 + statistics.timing = 0 +else + statistics.starttiming(statistics) +end + +function statistics.runtime() + statistics.stoptiming(statistics) + return statistics.formatruntime(statistics.elapsedtime(statistics)) +end + +function statistics.formatruntime(runtime) + return format("%s seconds", statistics.elapsedtime(statistics)) +end + +function statistics.timed(action,report) + local timer = { } + report = report or logs.simple + statistics.starttiming(timer) + action() + statistics.stoptiming(timer) + report("total runtime: %s",statistics.elapsedtime(timer)) +end + +-- where, not really the best spot for this: + +commands = commands or { } + +local timer + +function commands.resettimer() + statistics.resettiming(timer) + statistics.starttiming(timer) +end + +function commands.elapsedtime() + statistics.stoptiming(timer) + tex.sprint(statistics.elapsedtime(timer)) +end + +commands.resettimer() + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-log'] = { + version = 1.001, + comment = "companion to trac-log.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is old code that needs an overhaul + +--~ io.stdout:setvbuf("no") +--~ io.stderr:setvbuf("no") + +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch +local texcount = tex and tex.count + +if texlua then + write_nl = print + write = io.write +end + +--[[ldx-- +

This is a prelude to a more extensive logging module. For the sake +of parsing log files, in addition to the standard logging we will +provide an structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

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

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

+--ldx]]-- + +logs.moreinfo = [[ +more information about ConTeXt and the tools that come with it can be found at: + +maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context +webpage : http://www.pragma-ade.nl / http://tex.aanhet.net +wiki : http://contextgarden.net +]] + +logs.levels = { + ['error'] = 1, + ['warning'] = 2, + ['info'] = 3, + ['debug'] = 4, +} + +logs.functions = { + 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct', + 'start_run', 'stop_run', + 'start_page_number', 'stop_page_number', + 'report_output_pages', 'report_output_log', + 'report_tex_stat', 'report_job_stat', + 'show_open', 'show_close', 'show_load', +} + +logs.tracers = { +} + +logs.level = 0 +logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex")) + +function logs.set_level(level) + logs.level = logs.levels[level] or level +end + +function logs.set_method(method) + for _, v in next, logs.functions do + logs[v] = logs[method][v] or function() end + end +end + +-- tex logging + +function logs.tex.report(category,fmt,...) -- new + if fmt then + write_nl(category .. " | " .. format(fmt,...)) + else + write_nl(category .. " |") + end +end + +function logs.tex.line(fmt,...) -- new + if fmt then + write_nl(format(fmt,...)) + else + write_nl("") + end +end + +--~ function logs.tex.start_page_number() +--~ local real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +--~ if real > 0 then +--~ if user > 0 then +--~ if sub > 0 then +--~ write(format("[%s.%s.%s",real,user,sub)) +--~ else +--~ write(format("[%s.%s",real,user)) +--~ end +--~ else +--~ write(format("[%s",real)) +--~ end +--~ else +--~ write("[-") +--~ end +--~ end + +--~ function logs.tex.stop_page_number() +--~ write("]") +--~ end + +local real, user, sub + +function logs.tex.start_page_number() + real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +end + +function logs.tex.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + logs.report("pages", "flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + logs.report("pages", "flushing realpage %s, userpage %s",real,user) + end + else + logs.report("pages", "flushing realpage %s",real) + end + else + logs.report("pages", "flushing page") + end + io.flush() +end + +logs.tex.report_job_stat = statistics.show_job_stat + +-- xml logging + +function logs.xml.report(category,fmt,...) -- new + if fmt then + write_nl(format("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + end +end + +function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end +function logs.xml.stop () if logs.level > 0 then tw("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",level+1,name)) +end + +-- + +local name, banner = 'report', 'context' + +local function report(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + +local function simple(fmt,...) + if fmt then + write_nl(format("%s | %s",name,format(fmt,...))) + else + write_nl(format("%s |",name)) + end +end + +function logs.setprogram(_name_,_banner_,_verbose_) + name, banner = _name_, _banner_ + if _verbose_ then + trackers.enable("resolvers.locating") + end + logs.set_method("tex") + logs.report = report -- also used in libraries + logs.simple = simple -- only used in scripts ! + if utils then + utils.report = simple + end + logs.verbose = _verbose_ +end + +function logs.setverbose(what) + if what then + trackers.enable("resolvers.locating") + else + trackers.disable("resolvers.locating") + end + logs.verbose = what or false +end + +function logs.extendbanner(_banner_,_verbose_) + banner = banner .. " | ".. _banner_ + if _verbose_ ~= nil then + logs.setverbose(what) + end +end + +logs.verbose = false +logs.report = logs.tex.report +logs.simple = logs.tex.report + +function logs.reportlines(str) -- todo: + for line in gmatch(str,"(.-)[\n\r]") do + logs.report(line) + end +end + +function logs.reportline() -- for scripts too + logs.report() +end + +logs.simpleline = logs.reportline + +function logs.reportbanner() -- for scripts too + logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() + logs.reportline() + logs.reportlines(message) + local moreinfo = logs.moreinfo or "" + if moreinfo ~= "" and option ~= "nomoreinfo" then + logs.reportline() + logs.reportlines(moreinfo) + end +end + +logs.set_level('error') +logs.set_method('tex') + +function logs.system(whereto,process,jobname,category,...) + for i=1,10 do + local f = io.open(whereto,"a") + if f then + f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...))) + f:close() + break + else + sleep(0.1) + end + end +end + +--~ local syslogname = "oeps.xxx" +--~ +--~ for i=1,10 do +--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123") +--~ end + +function logs.fatal(where,...) + logs.report(where,"fatal error: %s, aborting now",format(...)) + os.exit() +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 } + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 { } + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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') + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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' + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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")) + + +end -- of closure +-- end library merge + +own = { } -- not local + +own.libs = { -- todo: check which ones are really needed + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-io.lua', + 'l-number.lua', + 'l-set.lua', + 'l-os.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-boolean.lua', + 'l-math.lua', +-- 'l-unicode.lua', +-- 'l-tex.lua', + 'l-utils.lua', + 'l-aux.lua', +-- 'l-xml.lua', + 'trac-tra.lua', + 'lxml-tab.lua', + 'lxml-lpt.lua', +-- 'lxml-ent.lua', + 'lxml-mis.lua', + 'lxml-aux.lua', + 'lxml-xml.lua', + 'luat-env.lua', + 'trac-inf.lua', + 'trac-log.lua', + 'data-res.lua', + 'data-tmp.lua', + 'data-pre.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-tex.lua', +-- 'data-bin.lua', + 'data-zip.lua', + 'data-crl.lua', + 'data-lua.lua', + 'data-kps.lua', -- so that we can replace kpsewhich + 'data-aux.lua', -- updater + 'data-tmf.lua', -- tree files + -- needed ? + 'luat-sta.lua', -- states +} + +-- We need this hack till luatex is fixed. +-- +-- for k,v in pairs(arg) do print(k,v) end + +if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then + arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil +end + +-- End of hack. + +own.name = (environment and environment.ownname) or arg[0] or 'luatools.lua' + + +own.path = string.match(own.name,"^(.+)[\\/].-$") or "." +own.list = { '.' } +if own.path ~= '.' then + table.insert(own.list,own.path) +end +table.insert(own.list,own.path.."/../../../tex/context/base") +table.insert(own.list,own.path.."/mtx") +table.insert(own.list,own.path.."/../sources") + +local function locate_libs() + for _, lib in pairs(own.libs) do + for _, pth in pairs(own.list) do + local filename = string.gsub(pth .. "/" .. lib,"\\","/") + local codeblob = loadfile(filename) + if codeblob then + codeblob() + own.list = { pth } -- speed up te search + break + end + end + end +end + +if not resolvers then + locate_libs() +end + +if not resolvers then + print("") + print("Mtxrun is unable to start up due to lack of libraries. You may") + print("try to run 'lua mtxrun.lua --selfmerge' in the path where this") + print("script is located (normally under ..../scripts/context/lua) which") + print("will make this script library independent.") + os.exit() +end + +logs.setprogram('MTXrun',"TDS Runner Tool 1.24",environment.arguments["verbose"] or false) + +local instance = resolvers.reset() + +local trackspec = environment.argument("trackers") or environment.argument("track") + +if trackspec then + trackers.enable(trackspec) +end + +runners = runners or { } -- global +messages = messages or { } + +messages.help = [[ +--script run an mtx script (lua prefered method) (--noquotes), no script gives list +--execute run a script or program (texmfstart method) (--noquotes) +--resolve resolve prefixed arguments +--ctxlua run internally (using preloaded libs) +--internal run script using built in libraries (same as --ctxlua) +--locate locate given filename + +--autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' +--tree=pathtotree use given texmf tree (default file: 'setuptex.tmf') +--environment=name use given (tmf) environment file +--path=runpath go to given path before execution +--ifchanged=filename only execute when given file has changed (md checksum) +--iftouched=old,new only execute when given file has changed (time stamp) + +--make create stubs for (context related) scripts +--remove remove stubs (context related) scripts +--stubpath=binpath paths where stubs wil be written +--windows create windows (mswin) stubs +--unix create unix (linux) stubs + +--verbose give a bit more info +--trackers=list enable given trackers +--engine=str target engine +--progname=str format or backend + +--edit launch editor with found file +--launch (--all) launch files like manuals, assumes os support + +--timedrun run a script an time its run +--autogenerate regenerate databases if needed (handy when used to run context in an editor) + +--usekpse use kpse as fallback (when no mkiv and cache installed, often slower) +--forcekpse force using kpse (handy when no mkiv and cache installed but less functionality) + +--prefixes show supported prefixes +]] + +runners.applications = { + ["lua"] = "luatex --luaonly", + ["luc"] = "luatex --luaonly", + ["pl"] = "perl", + ["py"] = "python", + ["rb"] = "ruby", +} + +runners.suffixes = { + 'rb', 'lua', 'py', 'pl' +} + +runners.registered = { + texexec = { 'texexec.rb', false }, -- context mkii runner (only tool not to be luafied) + texutil = { 'texutil.rb', true }, -- old perl based index sorter for mkii (old versions need it) + texfont = { 'texfont.pl', true }, -- perl script that makes mkii font metric files + texfind = { 'texfind.pl', false }, -- perltk based tex searching tool, mostly used at pragma + texshow = { 'texshow.pl', false }, -- perltk based context help system, will be luafied + -- texwork = { 'texwork.pl', false }, -- perltk based editing environment, only used at pragma + makempy = { 'makempy.pl', true }, + mptopdf = { 'mptopdf.pl', true }, + pstopdf = { 'pstopdf.rb', true }, -- converts ps (and some more) images, does some cleaning (replaced) +-- examplex = { 'examplex.rb', false }, + concheck = { 'concheck.rb', false }, + runtools = { 'runtools.rb', true }, + textools = { 'textools.rb', true }, + tmftools = { 'tmftools.rb', true }, + ctxtools = { 'ctxtools.rb', true }, + rlxtools = { 'rlxtools.rb', true }, + pdftools = { 'pdftools.rb', true }, + mpstools = { 'mpstools.rb', true }, +-- exatools = { 'exatools.rb', true }, + xmltools = { 'xmltools.rb', true }, +-- luatools = { 'luatools.lua', true }, + mtxtools = { 'mtxtools.rb', true }, + pdftrimwhite = { 'pdftrimwhite.pl', false } +} + +runners.launchers = { + windows = { }, + unix = { } +} + +-- like runners.libpath("framework"): looks on script's subpath + +function runners.libpath(...) + package.prepend_libpath(file.dirname(environment.ownscript),...) + package.prepend_libpath(file.dirname(environment.ownname) ,...) +end + +function runners.prepare() + local checkname = environment.argument("ifchanged") + if checkname and checkname ~= "" then + local oldchecksum = file.loadchecksum(checkname) + local newchecksum = file.checksum(checkname) + if oldchecksum == newchecksum then + logs.simple("file '%s' is unchanged",checkname) + return "skip" + else + logs.simple("file '%s' is changed, processing started",checkname) + end + file.savechecksum(checkname) + end + local oldname, newname = string.split(environment.argument("iftouched") or "", ",") + if oldname and newname and oldname ~= "" and newname ~= "" then + if not file.needs_updating(oldname,newname) then + logs.simple("file '%s' and '%s' have same age",oldname,newname) + return "skip" + else + logs.simple("file '%s' is older than '%s'",oldname,newname) + end + end + local tree = environment.argument('tree') or "" + if environment.argument('autotree') then + tree = os.getenv('TEXMFSTART_TREE') or os.getenv('TEXMFSTARTTREE') or tree + end + if tree and tree ~= "" then + resolvers.load_tree(tree) + end + local env = environment.argument('environment') or "" + if env and env ~= "" then + for _,e in pairs(string.split(env)) do + -- maybe force suffix when not given + resolvers.load_tree(e) + end + end + local runpath = environment.argument("path") + if runpath and not lfs.chdir(runpath) then + logs.simple("unable to change to path '%s'",runpath) + return "error" + end + return "run" +end + +function runners.execute_script(fullname,internal,nosplit) + local noquote = environment.argument("noquotes") + if fullname and fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + instance.progname = environment.argument("progname") or instance.progname + instance.format = environment.argument("format") or instance.format + local path, name, suffix, result = file.dirname(fullname), file.basename(fullname), file.extname(fullname), "" + if path ~= "" then + result = fullname + elseif name then + name = name:gsub("^int[%a]*:",function() + internal = true + return "" + end ) + name = name:gsub("^script:","") + if suffix == "" and runners.registered[name] and runners.registered[name][1] then + name = runners.registered[name][1] + suffix = file.extname(name) + end + if suffix == "" then + -- loop over known suffixes + for _,s in pairs(runners.suffixes) do + result = resolvers.find_file(name .. "." .. s, 'texmfscripts') + if result ~= "" then + break + end + end + elseif runners.applications[suffix] then + result = resolvers.find_file(name, 'texmfscripts') + else + -- maybe look on path + result = resolvers.find_file(name, 'other text files') + end + end + if result and result ~= "" then + if not no_split then + local before, after = environment.split_arguments(fullname) -- already done + environment.arguments_before, environment.arguments_after = before, after + end + if internal then + arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end + environment.ownscript = result + dofile(result) + else + local binary = runners.applications[file.extname(result)] + if binary and binary ~= "" then + result = binary .. " " .. result + end + local command = result .. " " .. environment.reconstruct_commandline(environment.arguments_after,noquote) + if logs.verbose then + logs.simpleline() + logs.simple("executing: %s",command) + logs.simpleline() + logs.simpleline() + io.flush() + end + -- no os.exec because otherwise we get the wrong return value + local code = os.execute(command) -- maybe spawn + if code == 0 then + return true + else + if binary then + binary = file.addsuffix(binary,os.binsuffix) + for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do + if lfs.isfile(file.join(p,binary)) then + return false + end + end + logs.simpleline() + logs.simple("This script needs '%s' which seems not to be installed.",binary) + logs.simpleline() + end + return false + end + end + end + end + end + return false +end + +function runners.execute_program(fullname) + local noquote = environment.argument("noquotes") + if fullname and fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + local before, after = environment.split_arguments(fullname) + environment.initialize_arguments(after) + fullname = fullname:gsub("^bin:","") + local command = fullname .. " " .. (environment.reconstruct_commandline(after or "",noquote) or "") + logs.simpleline() + logs.simple("executing: %s",command) + logs.simpleline() + logs.simpleline() + io.flush() + local code = os.exec(command) -- (fullname,unpack(after)) does not work / maybe spawn + return code == 0 + end + end + return false +end + +-- the --usekpse flag will fallback on kpse (hm, we can better update mtx-stubs) + +local windows_stub = '@echo off\013\010setlocal\013\010set ownpath=%%~dp0%%\013\010texlua "%%ownpath%%mtxrun.lua" --usekpse --execute %s %%*\013\010endlocal\013\010' +local unix_stub = '#!/bin/sh\010mtxrun --usekpse --execute %s \"$@\"\010' + +function runners.handle_stubs(create) + local stubpath = environment.argument('stubpath') or '.' -- 'auto' no longer subpathssupported + local windows = environment.argument('windows') or environment.argument('mswin') or false + local unix = environment.argument('unix') or environment.argument('linux') or false + if not windows and not unix then + if os.platform == "unix" then + unix = true + else + windows = true + end + end + for _,v in pairs(runners.registered) do + local name, doit = v[1], v[2] + if doit then + local base = string.gsub(file.basename(name), "%.(.-)$", "") + if create then + if windows then + io.savedata(file.join(stubpath,base..".bat"),string.format(windows_stub,name)) + logs.simple("windows stub for '%s' created",base) + end + if unix then + io.savedata(file.join(stubpath,base),string.format(unix_stub,name)) + logs.simple("unix stub for '%s' created",base) + end + else + if windows and (os.remove(file.join(stubpath,base..'.bat')) or os.remove(file.join(stubpath,base..'.cmd'))) then + logs.simple("windows stub for '%s' removed", base) + end + if unix and (os.remove(file.join(stubpath,base)) or os.remove(file.join(stubpath,base..'.sh'))) then + logs.simple("unix stub for '%s' removed",base) + end + end + end + end +end + +function runners.resolve_string(filename) + if filename and filename ~= "" then + runners.report_location(resolvers.resolve(filename)) + end +end + +function runners.locate_file(filename) + -- differs from texmfstart where locate appends .com .exe .bat ... todo + if filename and filename ~= "" then + runners.report_location(resolvers.find_given_file(filename)) + end +end + +function runners.locate_platform() + runners.report_location(os.platform) +end + +function runners.report_location(result) + if logs.verbose then + logs.simpleline() + if result and result ~= "" then + logs.simple(result) + else + logs.simple("not found") + end + else + io.write(result) + end +end + +function runners.edit_script(filename) -- we assume that vim is present on most systems + local editor = os.getenv("MTXRUN_EDITOR") or os.getenv("TEXMFSTART_EDITOR") or os.getenv("EDITOR") or 'vim' + local rest = resolvers.resolve(filename) + if rest ~= "" then + local command = editor .. " " .. rest + if logs.verbose then + logs.simpleline() + logs.simple("starting editor: %s",command) + logs.simple_line() + logs.simple_line() + end + os.launch(command) + end +end + +function runners.save_script_session(filename, list) + local t = { } + for i=1,#list do + local key = list[i] + t[key] = environment.arguments[key] + end + io.savedata(filename,table.serialize(t,true)) +end + +function runners.load_script_session(filename) + if lfs.isfile(filename) then + local t = io.loaddata(filename) + if t then + t = loadstring(t) + if t then t = t() end + for key, value in pairs(t) do + environment.arguments[key] = value + end + end + end +end + +function resolvers.launch(str) + -- maybe we also need to test on mtxrun.launcher.suffix environment + -- variable or on windows consult the assoc and ftype vars and such + local launchers = runners.launchers[os.platform] if launchers then + local suffix = file.extname(str) if suffix then + local runner = launchers[suffix] if runner then + str = runner .. " " .. str + end + end + end + os.launch(str) +end + +function runners.launch_file(filename) + instance.allresults = true + logs.setverbose(true) + local pattern = environment.arguments["pattern"] + if not pattern or pattern == "" then + pattern = filename + end + if not pattern or pattern == "" then + logs.simple("provide name or --pattern=") + else + local t = resolvers.find_files(pattern) + if not t or #t == 0 then + t = resolvers.find_files("*/" .. pattern) + end + if not t or #t == 0 then + t = resolvers.find_files("*/" .. pattern .. "*") + end + if t and #t > 0 then + if environment.arguments["all"] then + for _, v in pairs(t) do + logs.simple("launching %s", v) + resolvers.launch(v) + end + else + logs.simple("launching %s", t[1]) + resolvers.launch(t[1]) + end + else + logs.simple("no match for %s", pattern) + end + end +end + +function runners.find_mtx_script(filename) + local function found(name) + local path = file.dirname(name) + if path and path ~= "" then + return false + else + local fullname = own and own.path and file.join(own.path,name) + return io.exists(fullname) and fullname + end + end + filename = file.addsuffix(filename,"lua") + local basename = file.removesuffix(file.basename(filename)) + local suffix = file.extname(filename) + -- qualified path, raw name + local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename + if fullname and fullname ~= "" then + return fullname + end + -- current path, raw name + fullname = "./" .. filename + fullname = io.exists(fullname) and fullname + if fullname and fullname ~= "" then + return fullname + end + -- mtx- prefix checking + local mtxprefix = (filename:find("^mtx%-") and "") or "mtx-" + -- context namespace, mtx- + fullname = mtxprefix .. filename + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx-s + fullname = mtxprefix .. basename .. "s" .. "." .. suffix + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx- + fullname = mtxprefix .. basename:gsub("s$","") .. "." .. suffix + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, just + fullname = resolvers.find_file(filename) + return fullname +end + +function runners.execute_ctx_script(filename) + local arguments = environment.arguments_after + local fullname = runners.find_mtx_script(filename) or "" + if file.extname(fullname) == "cld" then + -- handy in editors where we force --autopdf + logs.simple("running cld script: %s",filename) + table.insert(arguments,1,fullname) + table.insert(arguments,"--autopdf") + fullname = runners.find_mtx_script("context") or "" + end + -- retry after generate but only if --autogenerate + if fullname == "" and environment.argument("autogenerate") then -- might become the default + instance.renewcache = true + logs.setverbose(true) + resolvers.load() + -- + fullname = runners.find_mtx_script(filename) or "" + end + -- that should do it + if fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + -- load and save ... kind of undocumented + arg = { } for _,v in pairs(arguments) do arg[#arg+1] = resolvers.resolve(v) end + environment.initialize_arguments(arg) + local loadname = environment.arguments['load'] + if loadname then + if type(loadname) ~= "string" then loadname = file.basename(fullname) end + loadname = file.replacesuffix(loadname,"cfg") + runners.load_script_session(loadname) + end + filename = environment.files[1] + if logs.verbose then + logs.simple("using script: %s\n",fullname) + end + environment.ownscript = fullname + dofile(fullname) + local savename = environment.arguments['save'] + if savename then + local save_list = runners.save_list + if save_list and next(save_list) then + if type(savename) ~= "string" then savename = file.basename(fullname) end + savename = file.replacesuffix(savename,"cfg") + runners.save_script_session(savename,save_list) + end + end + return true + end + else + -- logs.setverbose(true) + if filename == "" or filename == "help" then + local context = resolvers.find_file("mtx-context.lua") + logs.setverbose(true) + if context ~= "" then + local result = dir.glob((string.gsub(context,"mtx%-context","mtx-*"))) -- () needed + local valid = { } + table.sort(result) + for i=1,#result do + local scriptname = result[i] + local scriptbase = string.match(scriptname,".*mtx%-([^%-]-)%.lua") + if scriptbase then + local data = io.loaddata(scriptname) + local banner, version = string.match(data,"[\n\r]logs%.extendbanner%s*%(%s*[\"\']([^\n\r]+)%s*(%d+%.%d+)") + if banner then + valid[#valid+1] = { scriptbase, version, banner } + end + end + end + if #valid > 0 then + logs.reportbanner() + logs.reportline() + logs.simple("no script name given, known scripts:") + logs.simple() + for k=1,#valid do + local v = valid[k] + logs.simple("%-12s %4s %s",v[1],v[2],v[3]) + end + end + else + logs.simple("no script name given") + end + else + filename = file.addsuffix(filename,"lua") + if file.is_qualified_path(filename) then + logs.simple("unknown script '%s'",filename) + else + logs.simple("unknown script '%s' or 'mtx-%s'",filename,filename) + end + end + return false + end +end + +function runners.prefixes() + logs.reportbanner() + logs.reportline() + logs.simple(table.concat(resolvers.allprefixes(true)," ")) +end + +function runners.timedrun(filename) -- just for me + if filename and filename ~= "" then + runners.timed(function() os.execute(filename) end) + end +end + +function runners.timed(action) + statistics.timed(action) +end + +-- this is a bit dirty ... first we store the first filename and next we +-- split the arguments so that we only see the ones meant for this script +-- ... later we will use the second half + +local filename = environment.files[1] or "" +local ok = true + +local before, after = environment.split_arguments(filename) +environment.arguments_before, environment.arguments_after = before, after +environment.initialize_arguments(before) + +instance.engine = environment.argument("engine") or 'luatex' +instance.progname = environment.argument("progname") or 'context' +instance.lsrmode = environment.argument("lsr") or false + +-- maybe the unset has to go to this level + +local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] + +if environment.argument("usekpse") or environment.argument("forcekpse") or is_mkii_stub then + + os.setenv("engine","") + os.setenv("progname","") + + local remapper = { + otf = "opentype fonts", + ttf = "truetype fonts", + ttc = "truetype fonts", + pfb = "type1 fonts", + other = "other text files", + } + + local function kpse_initialized() + texconfig.kpse_init = true + local t = os.clock() + local k = kpse.original.new("luatex",instance.progname) + local dummy = k:find_file("mtxrun.lua") -- so that we're initialized + logs.simple("kpse fallback with progname '%s' initialized in %s seconds",instance.progname,os.clock()-t) + kpse_initialized = function() return k end + return k + end + + local find_file = resolvers.find_file + local show_path = resolvers.show_path + + if environment.argument("forcekpse") then + + function resolvers.find_file(name,kind) + return (kpse_initialized():find_file(resolvers.clean_path(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" + end + function resolvers.show_path(name) + return (kpse_initialized():show_path(name)) or "" + end + + elseif environment.argument("usekpse") or is_mkii_stub then + + resolvers.load() + + function resolvers.find_file(name,kind) + local found = find_file(name,kind) or "" + if found ~= "" then + return found + else + return (kpse_initialized():find_file(resolvers.clean_path(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" + end + end + function resolvers.show_path(name) + local found = show_path(name) or "" + if found ~= "" then + return found + else + return (kpse_initialized():show_path(name)) or "" + end + end + + end + +else + + resolvers.load() + +end + +if environment.argument("selfmerge") then + -- embed used libraries + utils.merger.selfmerge(own.name,own.libs,own.list) +elseif environment.argument("selfclean") then + -- remove embedded libraries + utils.merger.selfclean(own.name) +elseif environment.argument("selfupdate") then + logs.setverbose(true) + resolvers.update_script(own.name,"mtxrun") +elseif environment.argument("ctxlua") or environment.argument("internal") then + -- run a script by loading it (using libs) + ok = runners.execute_script(filename,true) +elseif environment.argument("script") or environment.argument("scripts") then + -- run a script by loading it (using libs), pass args + if is_mkii_stub then + -- execute mkii script + ok = runners.execute_script(filename,false,true) + else + ok = runners.execute_ctx_script(filename) + end +elseif environment.argument("execute") then + -- execute script + ok = runners.execute_script(filename) +elseif environment.argument("direct") then + -- equals bin: + ok = runners.execute_program(filename) +elseif environment.argument("edit") then + -- edit file + runners.edit_script(filename) +elseif environment.argument("launch") then + runners.launch_file(filename) +elseif environment.argument("make") then + -- make stubs + runners.handle_stubs(true) +elseif environment.argument("remove") then + -- remove stub + runners.handle_stubs(false) +elseif environment.argument("resolve") then + -- resolve string + runners.resolve_string(filename) +elseif environment.argument("locate") then + -- locate file + runners.locate_file(filename) +elseif environment.argument("platform")then + -- locate platform + runners.locate_platform() +elseif environment.argument("prefixes") then + runners.prefixes() +elseif environment.argument("timedrun") then + -- locate platform + runners.timedrun(filename) +elseif environment.argument("help") or filename=='help' or filename == "" then + logs.help(messages.help) + -- execute script +elseif filename:find("^bin:") then + ok = runners.execute_program(filename) +elseif is_mkii_stub then + -- execute mkii script + ok = runners.execute_script(filename,false,true) +else + ok = runners.execute_ctx_script(filename) + if not ok then + ok = runners.execute_script(filename) + end +end + +if os.platform == "unix" then + io.write("\n") +end + +if ok == false then ok = 1 elseif ok == true then ok = 0 end + +os.exit(ok) diff --git a/scripts/context/lua/mtxrun.rme b/scripts/context/lua/mtxrun.rme new file mode 100644 index 000000000..9850e389d --- /dev/null +++ b/scripts/context/lua/mtxrun.rme @@ -0,0 +1,18 @@ +On MSWindows the mtxrun.lua script is called with +mtxrun.exe. On Unix you can either rename mtxrun.lua +to mtxrun, or use a symlink. + +You can create additional stubs, like + +copy mtxrun.exe luatools.exe +copy mtxrun.exe texexec.exe +copy mtxrun.exe context.exe +copy mtxrun.exe mtx-server.exe + +The mtxrun.exe program is rather dump and only +intercepts mtxrun, luatools and texmfstart (for +old times sake) and passes the buck to mtxrun.lua +which happens to know enough of mkii to deal +with kpse based lookups and therefore acts like +texmfstart but when used with mkiv it behaves +more clever and looks for more. diff --git a/scripts/context/lua/x-ldx.lua b/scripts/context/lua/x-ldx.lua new file mode 100644 index 000000000..e0f21d68c --- /dev/null +++ b/scripts/context/lua/x-ldx.lua @@ -0,0 +1,322 @@ +--[[ldx-- +Lua Documentation Module + +This file is part of the documentation suite and +itself serves as an example of using in combination +with . + +I will rewrite this using lpeg once I have the time to study that nice new +subsystem. On the other hand, we cannot expect proper +ad for educational purposed the syntax migh be wrong. +--ldx]]-- + +banner = "version 1.0.1 - 2007+ - PRAGMA ADE / CONTEXT" + +--[[ +This script needs a few libraries. Instead of merging the code here +we can use + + +mtxrun --internal x-ldx.lua + + +That way, the libraries included in the runner will be used. +]]-- + +-- libraries l-string.lua l-table.lua l-io.lua l-file.lua + +-- begin library merge +-- end library merge + +--[[ +Just a demo comment line. We will handle such multiline comments but +only when they start and end at the beginning of a line. More rich +comments are tagged differently. +]]-- + +--[[ldx-- +First we define a proper namespace for this module. The l stands for +, the d for documentation and the x for +. +--ldx]]-- + +if not ldx then ldx = { } end + +--[[ldx-- +We load the lua file into a table. The entries in this table themselves are +tables and have keys like code and comment. +--ldx]]-- + +function ldx.load(filename) + local data = file.readdata(filename) + local expr = "%s*%-%-%[%[ldx%-*%s*(.-)%s*%-%-ldx%]%]%-*%s*" + local i, j, t = 0, 0, { } + while true do + local comment, ni + ni, j, comment = data:find(expr, j) + if not ni then break end + t[#t+1] = { code = data:sub(i, ni-1) } + t[#t+1] = { comment = comment } + i = j + 1 + end + local str = data:sub(i, #data) + str = str:gsub("^%s*(.-)%s*$", "%1") + if #str > 0 then + t[#t+1] = { code = str } + end + return t +end + +--[[ldx-- +We will tag keywords so that we can higlight them using a special font +or color. Users can extend this list when needed. +--ldx]]-- + +ldx.keywords = { } + +--[[ldx-- +Here come the reserved words: +--ldx]]-- + +ldx.keywords.reserved = { + ["and"] = 1, + ["break"] = 1, + ["do"] = 1, + ["else"] = 1, + ["elseif"] = 1, + ["end"] = 1, + ["false"] = 1, + ["for"] = 1, + ["function"] = 1, + ["if"] = 1, + ["in"] = 1, + ["local"] = 1, + ["nil"] = 1, + ["not"] = 1, + ["or"] = 1, + ["repeat"] = 1, + ["return"] = 1, + ["then"] = 1, + ["true"] = 1, + ["until"] = 1, + ["while"] = 1 +} + +--[[ldx-- +We need to escape a few tokens. We keep the hash local to the +definition but set it up only once, hence the do +construction. +--ldx]]-- + +do + local e = { [">"] = ">", ["<"] = "<", ["&"] = "&" } + function ldx.escape(str) + return (str:gsub("([><&])",e)) + end +end + +--[[ldx-- +Enhancing the code is a bit tricky due to the fact that we have to +deal with strings and escaped quotes within these strings. Before we +mess around with the code, we hide the strings, and after that we +insert them again. Single and double quoted strings are tagged so +that we can use a different font to highlight them. +--ldx]]-- + +ldx.make_index = true + +function ldx.enhance(data) -- i need to use lpeg and then we can properly autoindent -) + local e = ldx.escape + for k=1,#data do + local v = data[k] + if v.code then + local dqs, sqs, com, cmt, cod = { }, { }, { }, { }, e(v.code) + cod = cod:gsub('\\"', "##d##") + cod = cod:gsub("\\'", "##s##") + cod = cod:gsub("%-%-%[%[.-%]%]%-%-", function(s) + cmt[#cmt+1] = s + return ">>l>" + end) + cod = cod:gsub("%-%-([^\n]*)", function(s) + com[#com+1] = s + return ">>c>" + end) + cod = cod:gsub("(%b\"\")", function(s) + dqs[#dqs+1] = s:sub(2,-2) or "" + return ">>d>" + end) + cod = cod:gsub("(%b\'\')", function(s) + sqs[#sqs+1] = s:sub(2,-2) or "" + return ">>s>" + end) + cod = cod:gsub("(%a+)",function(key) + local class = ldx.keywords.reserved[key] + if class then + return "" .. key .. "" + else + return key + end + end) + cod = cod:gsub(">>s>", function(s) + return "" .. sqs[tonumber(s)] .. "" + end) + cod = cod:gsub(">>d>", function(s) + return "" .. dqs[tonumber(s)] .. "" + end) + cod = cod:gsub(">>c>", function(s) + return "" .. com[tonumber(s)] .. "" + end) + cod = cod:gsub(">>l>", function(s) + return cmt[tonumber(s)] + end) + cod = cod:gsub("##d##", "\\\"") + cod = cod:gsub("##s##", "\\\'") + if ldx.make_index then + local lines = cod:split("\n") + local f = "(function)%s+([%w%.]+)%s*%(" + for k=1,#lines do + local v = lines[k] + -- functies + v = v:gsub(f,function(key, str) + return "" .. str .. "(" + end) + -- variables + v = v:gsub("^([%w][%w%,%s]-)(=[^=])",function(str, rest) + local t = string.split(str, ",%s*") + for k=1,#t do + t[k] = "" .. t[k] .. "" + end + return table.join(t,", ") .. rest + end) + -- so far + lines[k] = v + end + v.code = table.concat(lines,"\n") + else + v.code = cod + end + end + end +end + +--[[ldx-- +We're now ready to save the file in format. This boils +down to wrapping the code and comment as well as the whole document. We tag +lines in the code as such so that we don't need messy CDATA constructs +and by calculating the indentation we also avoid space troubles. It also makes +it possible to change the indentation afterwards. +--ldx]]-- + +function ldx.as_xml(data) -- ldx: not needed + local t, cmode = { }, false + t[#t+1] = "\n" + t[#t+1] = "\n\n" + for k=1,#data do + local v = data[k] + if v.code and not v.code:is_empty() then + t[#t+1] = "\n\n" + local split = v.code:split("\n") + for k=1,#split do -- make this faster + local v = split[k] + local a, b = v:find("^(%s+)") + if v then v = v:gsub("[\n\r ]+$","") end + if a and b then + v = v:sub(b+1,#v) + if cmode then + t[#t+1] = "" .. v .. "\n" + else + t[#t+1] = "" .. v .. "\n" + end + elseif v:is_empty() then + if cmode then + t[#t+1] = "\n" + else + t[#t+1] = "\n" + end + elseif v:find("^%-%-%[%[") then + t[#t+1] = "" .. v .. "\n" + cmode= true + elseif v:find("^%]%]%-%-") then + t[#t+1] = "" .. v .. "\n" + cmode= false + elseif cmode then + t[#t+1] = "" .. v .. "\n" + else + t[#t+1] = "" .. v .. "\n" + end + end + t[#t+1] = "\n" + elseif v.comment then + t[#t+1] = "\n\n" .. v.comment .. "\n\n" + else + -- cannot happen + end + end + t[#t+1] = "\n\n" + return table.concat(t,"") +end + +--[[ldx-- +Saving the result is a trivial effort. +--ldx]]-- + +function ldx.save(filename,data) + file.savedata(filename,ldx.as_xml(data)) +end + +--[[ldx-- +The next function wraps it all in one call: +--ldx]]-- + +function ldx.convert(luaname,ldxname) + if not file.isreadable(luaname) then + luaname = luaname .. ".lua" + end + if file.isreadable(luaname) then + if not ldxname then + ldxname = file.replacesuffix(luaname,"ldx") + end + local data = ldx.load(luaname) + if data then + ldx.enhance(data) + if ldxname ~= luaname then + ldx.save(ldxname,data) + end + end + end +end + +--[[ldx-- +This module can be used directly: + + +mtxrun --internal x-ldx somefile.lua + + +will produce an ldx file that can be processed with +by running: + + +texexec --use=x-ldx --forcexml somefile.ldx + + +You can do this in one step by saying: + + +texmfstart texexec --ctx=x-ldx somefile.lua + + +This will trigger into loading the mentioned + file. That file describes the conversion as well +as the module to be used. + +The main conversion call is: +--ldx]]-- + +-- todo: assume usage of "mtxrun --script x-ldx", maybe make it mtx-ldx + +if arg and arg[1] then + ldx.convert(arg[1],arg[2]) +end + +--~ exit(1) diff --git a/scripts/context/perl/makempy.pl b/scripts/context/perl/makempy.pl new file mode 100644 index 000000000..7cba2e1a6 --- /dev/null +++ b/scripts/context/perl/makempy.pl @@ -0,0 +1,361 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' + if 0; + +#D \module +#D [ file=makempy.pl, +#D version=2000.12.14, +#D title=\METAFUN, +#D subtitle=\METAPOST\ Text 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 licen-en.pdf for +#C details. + +# Tobias Burnus provided the code needed to proper testing +# of binaries on UNIX as well as did some usefull suggestions +# to improve the functionality. + +# This script uses GhostScript and PStoEdit as well as +# pdfTeX, and if requested TeXEdit and ConTeXt. + +# todo: we can nowadays do without the intermediate step, because GS +# can now handle PDF quite good + +use Getopt::Long ; +use Config ; +use strict ; + +$Getopt::Long::passthrough = 1 ; # no error message +$Getopt::Long::autoabbrev = 1 ; # partial switch accepted + +my $help = 0 ; +my $silent = 0 ; +my $force = 0 ; +my $noclean = 0 ; + +my $amethod = my $pmethod = my $gmethod = 0 ; + +my $format = "plain" ; # can be "context" for plain users too + +&GetOptions + ( "help" => \$help , + "silent" => \$silent , + "force" => \$force , + "pdftops" => \$pmethod , + "xpdf" => \$pmethod , + "gs" => \$gmethod , + "ghostscript" => \$gmethod , + "noclean" => \$noclean ) ; + +my $mpochecksum = 0 ; + +my %tex ; my %start ; my %stop ; + +$tex{plain} = "pdftex" ; +$tex{latex} = "pdflatex" ; +$tex{context} = "texexec --batch --once --interface=en --pdf" ; + +$start{plain} = '' ; +$stop{plain} = '\end' ; + +$start{latex} = '\begin{document}' ; +$stop{latex} = '\end{document}' ; + +$start{context} = '\starttext' ; +$stop{context} = '\stoptext' ; + +my $ghostscript = "" ; +my $pstoedit = "" ; +my $pdftops = "" ; +my $acroread = "" ; + +my $wereondos = ($Config{'osname'} =~ /dos|mswin/io) ; + +# Unix only: assume that "gs" in the path. We could also +# use $ghostscipt = system "which gs" but this would require +# that which is installedd on the system. + +sub checkenv + { my ($var, $env) = @_ ; + if ($var) + { return $var } + elsif ($ENV{$env}) + { return $ENV{$env} } + else + { return $var } } + +$ghostscript = checkenv ($ghostscript, "GS_PROG" ) ; +$ghostscript = checkenv ($ghostscript, "GS" ) ; +$pstoedit = checkenv ($pstoedit , "PSTOEDIT") ; +$pdftops = checkenv ($pdftops , "PDFTOPS" ) ; +$acroread = checkenv ($acroread , "ACROREAD") ; + +sub setenv + { my ($var, $unix, $win) = @_ ; + if ($var) + { return $var } + elsif ($wereondos) + { return $win } + else + { return $unix } } + +$ghostscript = setenv($ghostscript, "gs" , "gswin32c") ; +$pstoedit = setenv($pstoedit , "pstoedit", "pstoedit") ; +$pdftops = setenv($pdftops , "pdftops" , "pdftops" ) ; +$acroread = setenv($acroread , "acroread", "" ) ; + +# Force a method if unknown. + +unless ($pmethod||$amethod||$gmethod) + { if ($wereondos) { $pmethod = 1 } else { $amethod = 1 } } + +# Set the error redirection used under Unix: +# stderr -> stdout + +my $logredirection = '>>' ; + +# This unfortunally doesn't work with the ksh and simple sh +# +# if (!$wereondos) +# { $logredirection = '2>&1 >>' ; # Bash +# $logredirection = '>>&' ; # tcsh, Bash +# default $logredirection. } + +# Some TeX Code Snippets. + +my $macros = ' + +% auxiliary macros + +\input supp-mis.tex + +\def\startTEXpage[scale=#1]% + {\output{} + \batchmode + \pdfoutput=1 + \pdfcompresslevel=9 + \hoffset=-1in + \voffset=\hoffset + \scratchcounter=#1 + \divide\scratchcounter1000 + \edef\TEXscale{\the\scratchcounter\space} + \forgetall + \setbox0=\vbox\bgroup} + +\def\stopTEXpage + {\egroup + \dimen0=\ht0 \advance\dimen0 \dp0 + \setbox2=\vbox to 10\dimen0 + {\pdfliteral{\TEXscale 0 0 \TEXscale 0 0 cm} + \copy0 + \pdfliteral{1 0 0 1 0 0 cm} + \vfill} + \wd2=10\wd0 + \pdfpageheight=\ht2 + \pdfpagewidth=\wd2 + \ScaledPointsToBigPoints{\number\pdfpageheight}\pdfcropheight + \ScaledPointsToBigPoints{\number\pdfpagewidth }\pdfcropwidth + \expanded{\pdfpageattr{/CropBox [0 0 \pdfcropwidth \space \pdfcropheight]}} + \shipout\hbox{\box2}} + +% end of auxiliary macros' ; + +sub report + { return if $silent ; + my $str = shift ; + if ($str =~ /(.*?)\s+([\:\/])\s+(.*)/o) + { if ($1 eq "") { $str = " " } else { $str = $2 } + print sprintf("%22s $str %s\n",$1,$3) } } + +sub error + { report("processing aborted : " . shift) ; + exit } + +sub process + { report("generating : " . shift) } + +sub banner + { return if $silent ; + print "\n" ; + report ("MakeMPY 1.1 - MetaFun / PRAGMA ADE 2000-2004") ; + print "\n" } + +my $metfile = "" ; # main metapost file +my $mpofile = "" ; # metapost text specifiation file (provided) +my $mpyfile = "" ; # metapost text picture file (generated) +my $texfile = "" ; # temporary tex file +my $pdffile = "" ; # temporary pdf file +my $tmpfile = "" ; # temporary metapost file +my $posfile = "" ; # temporary postscript file +my $logfile = "" ; # temporary log file +my $errfile = "" ; # final log file (with suffix log) + +sub show_help_info + { banner ; + report ("--help : this message" ) ; + report ("--noclean : don't remove temporary files" ) ; + report ("--force : force processing (ignore checksum)" ) ; + report ("--silent : don't show messages" ) ; + print "\n" ; + report ("--pdftops : use pdftops (xpdf) pdf->ps") ; + report ("--ghostscript : use ghostscript (gs) for pdf->ps") ; + print "\n" ; + report ("input file : metapost file with graphics") ; + report ("programs needed : texexec and english context") ; + report (" : pdftops from the xpdf suite, or") ; # page size buggy + report (" : pdf2ps and ghostscript, and") ; + report (" : pstoedit and ghostscript") ; + report ("output file : metapost file with pictures") ; + exit } + +sub check_input_file + { my $file = $ARGV[0] ; + if ((!defined($file))||($file eq "")) + { banner ; error("no filename given") } + else + { $file =~ s/\.mp.*$//o ; + $metfile = "$file.mp" ; + $mpofile = "$file.mpo" ; + $mpyfile = "$file.mpy" ; + $logfile = "$file.log" ; + $texfile = "mpy-$file.tex" ; + $pdffile = "mpy-$file.pdf" ; + $posfile = "mpy-$file.pos" ; + $tmpfile = "mpy-$file.tmp" ; + $errfile = "mpy-$file.log" ; + if (! -f $metfile) + { banner ; error("$metfile is empty") } + elsif (-s $mpofile < 32) + { unlink $mpofile ; # may exist with zero length + unlink $mpyfile ; # get rid of left overs + exit } + else + { banner ; report("processing file : $mpofile") } } } + +sub verify_check_sum # checksum calculation from perl documentation + { return unless (open (MPO,"$mpofile")) ; + $mpochecksum = do { local $/ ; unpack("%32C*",) % 65535 } ; + close (MPO) ; + return unless open (MPY,"$mpyfile") ; + my $str = ; chomp $str ; + close (MPY) ; + if ($str =~ /^\%\s*mpochecksum\s*\:\s*(\d+)/o) + { if ($mpochecksum eq $1) + { report("mpo checksum : $mpochecksum / unchanged") ; + exit unless $force } + else + { report("mpo checksum : $mpochecksum / changed") } } } + +sub cleanup_files + { my @files = ; + foreach (@files) { unless (/\.log/o) { unlink $_ } } } + +sub construct_tex_file + { my $n = 0 ; + unless (open (MPO, "<$mpofile")) + { error("unable to open $mpofile") } + unless (open (TEX, ">$texfile")) + { error("unable to open $texfile") } + my $textext = "" ; + while () + { s/\s*$//mois ; + if (/\%\s*format=(\w+)/) + { $format = $1 } + else # if (!/^\%/) + { if (/startTEXpage/o) + { ++$n ; + $textext .= "$start{$format}\n" ; + $start{$format} = "" } + $textext .= "$_\n" } } + unless (defined($tex{$format})) { $format = "plain" } + if ($format eq "context") { $macros = "" } + # print TEX "$start{$format}\n$macros\n$textext\n$stop{$format}\n" ; + print TEX "$start{$format}\n\n" if $start{$format} ; + print TEX "$macros\n" if $macros ; + print TEX "$textext\n" if $textext ; + print TEX "$stop{$format}\n" if $stop{$format} ; + close (MPO) ; + close (TEX) ; + report("tex format : $format") ; + report("requested texts : $n") } + +sub construct_mpy_file + { unless (open (TMP, "<$tmpfile")) + { error("unable to open $tmpfile file") } + unless (open (MPY, ">$mpyfile")) + { error("unable to open $mpyfile file") } + print MPY "% mpochecksum : $mpochecksum\n" ; + my $copying = my $n = 0 ; + while () # a simple sub is faster + { if (s/beginfig/begingraphictextfig/o) + { print MPY $_ ; $copying = 1 ; ++$n } + elsif (s/endfig/endgraphictextfig/o) + { print MPY $_ ; $copying = 0 } + elsif ($copying) + { print MPY $_ } } + close (TMP) ; + close (MPY) ; + report("processed texts : $n") ; + report("produced file : $mpyfile") } + +sub run + { my ($resultfile, $program,$arguments) = @_ ; + my $result = system("$program $arguments $logredirection $logfile") ; + unless (-f $resultfile) { error("invalid `$program' run") } } + +sub make_pdf_pages + { process ("pdf file") ; + run ($pdffile, "$tex{$format}", "$texfile") } + +sub make_mp_figures + { process ("postscript file") ; + if ($pmethod) { run($posfile, "$pdftops", + "-paper match $pdffile $posfile") } + if ($gmethod) { run($posfile, "$ghostscript", + "-q -sOutputFile=$posfile -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pswrite $pdffile") } + if ($amethod) { run($posfile, "$acroread", + "-toPostScript -pairs $pdffile $posfile") } } + +sub make_mp_pictures_ps + { process ("metapost file") ; + run ($tmpfile, "$pstoedit", "-ssp -dt -f mpost $posfile $tmpfile") } + +sub make_mp_pictures_pdf + { process ("metapost file") ; + run ($tmpfile, "$pstoedit", "-ssp -dt -f mpost $pdffile $tmpfile") } + +if ($help) { show_help_info } + +check_input_file ; +verify_check_sum ; +cleanup_files ; +construct_tex_file ; +make_pdf_pages ; +if (1) + { make_mp_pictures_pdf ; } +else + { make_mp_figures ; + make_mp_pictures_ps ; } +construct_mpy_file ; # less save : rename $tmpfile, $mpyfile ; +unless ($noclean) { cleanup_files } + +# a simple test file (needs context) +# +# % output=pdftex +# +# \starttext +# +# \startMPpage +# graphictext +# "\bf MAKE" +# scaled 8 +# zscaled (1,2) +# withdrawcolor \MPcolor{blue} +# withfillcolor \MPcolor{gray} +# withpen pencircle scaled 5pt ; +# \stopMPpage +# +# \stoptext diff --git a/scripts/context/perl/mptopdf.pl b/scripts/context/perl/mptopdf.pl new file mode 100644 index 000000000..41d1ae1f7 --- /dev/null +++ b/scripts/context/perl/mptopdf.pl @@ -0,0 +1,160 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' + if 0; + +# MikTeX users can set environment variable TEXSYSTEM to "miktex". + +#D \module +#D [ file=mptopdf.pl, +#D version=2000.05.29, +#D title=converting MP to PDF, +#D subtitle=\MPTOPDF, +#D author=Hans Hagen, +#D date=\currentdate, +#D url=www.pragma-ade.nl, +#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 licen-en.pdf for +#C details. + +# use File::Copy ; # not in every perl + +use Config ; +use Getopt::Long ; +use strict ; +use File::Basename ; + +$Getopt::Long::passthrough = 1 ; # no error message +$Getopt::Long::autoabbrev = 1 ; # partial switch accepted + +my $Help = my $Latex = my $RawMP = my $MetaFun = 0 ; +my $PassOn = '' ; + +&GetOptions + ( "help" => \$Help , + "rawmp" => \$RawMP, + "metafun" => \$MetaFun, + "passon" => \$PassOn, + "latex" => \$Latex ) ; + +my $program = "MPtoPDF 1.3.3" ; +my $pattern = "@ARGV" ; # was $ARGV[0] +my $miktex = 0 ; +my $done = 0 ; +my $report = '' ; +my $mplatexswitch = " --tex=latex " ; + +my $dosish = ($Config{'osname'} =~/^(ms)?dos|^os\/2|^mswin/i) ; +my $escapeshell = (($ENV{'SHELL'}) && ($ENV{'SHELL'} =~ m/sh/i )); + +if ($ENV{"TEXSYSTEM"}) { + $miktex = ($ENV{"TEXSYSTEM"} =~ /miktex/io) ; +} + +my @files ; +my $command = my $mpbin = '' ; + +# agressive copy, works for open files like in gs + +sub CopyFile { + my ($From,$To) = @_ ; + return unless open(INP,"<$From") ; + return unless open(OUT,">$To") ; + binmode INP ; + binmode OUT ; + while () { + print OUT $_ ; + } + close (INP) ; + close (OUT) ; +} + +if (($pattern eq '')||($Help)) { + print "\n$program : provide MP output file (or pattern)\n" ; + exit ; +} elsif ($pattern =~ /\.mp$/io) { + shift @ARGV ; my $rest = join(" ", @ARGV) ; + if (open(INP,$pattern)) { + while () { + if (/(documentstyle|documentclass|begin\{document\})/io) { + $Latex = 1 ; last ; + } + } + close (INP) ; + } + if ($RawMP) { + if ($Latex) { + $rest .= " $mplatexswitch" ; + } + if ($MetaFun) { + $mpbin = "mpost --progname=mpost --mem=metafun" ; + } else { + $mpbin = "mpost --mem=mpost" ; + } + } else { + if ($Latex) { + $rest .= " $mplatexswitch" ; + $mpbin = "mpost --mem=mpost" ; + } else { + $mpbin = "texexec --mptex $PassOn " ; + } + } + my $runner = "$mpbin $rest $pattern" ; + print "\n$program : running '$runner'\n" ; + my $error = system ($runner) ; + if ($error) { + print "\n$program : error while processing mp file\n" ; + exit 1 ; + } else { + $pattern =~ s/\.mp$//io ; + @files = glob "$pattern.*" ; + } +} elsif (-e $pattern) { + @files = ($pattern) ; +} elsif ($pattern =~ /.\../o) { + @files = glob "$pattern" ; +} else { + $pattern .= '.*' ; + @files = glob "$pattern" ; +} + +foreach my $file (@files) { + $_ = $file ; + if (s/\.(\d+|mps)$// && -e $file) { + if ($miktex) { + $command = "pdftex -undump=mptopdf" ; + } else { + $command = "pdftex -fmt=mptopdf -progname=context" ; + } + if ($dosish) { + $command = "$command \\relax $file" ; + } else { + $command = "$command \\\\relax $file" ; + } + my $error = system($command) ; + if ($error) { + print "\n$program : error while processing tex file\n" ; + exit 1 ; + } + my $pdfsrc = basename($_).".pdf"; + rename ($pdfsrc, "$_-$1.pdf") ; + if (-e $pdfsrc) { + CopyFile ($pdfsrc, "$_-$1.pdf") ; + } + if ($done) { + $report .= " +" ; + } + $report .= " $_-$1.pdf" ; + ++$done ; + } +} + +if ($report eq '') { + $report = '*' ; +} + +if ($done) { + print "\n$program : $pattern is converted to$report\n" ; +} else { + print "\n$program : no filename matches $pattern\n" ; +} diff --git a/scripts/context/perl/path_tre.pm b/scripts/context/perl/path_tre.pm new file mode 100644 index 000000000..546afcd27 --- /dev/null +++ b/scripts/context/perl/path_tre.pm @@ -0,0 +1,36 @@ +#D \module +#D [ file=path\_tre.pm, +#D version=1999.05.05, +#D title=Path modules, +#D subtitle=selecting a path, +#D author=Hans Hagen, +#D date=\currentdate, +#D copyright={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 Not yet documented, source will be cleaned up. + +package Tk::path_tre ; + +use Tk; +require Tk::DirTree ; + +use base qw(Tk::DirTree); +use strict; + +Construct Tk::Widget 'PathTree'; + +sub ClassInit + { my ($class,$mw) = @_ ; + return $class -> SUPER::ClassInit ($mw) } + +sub dirnames + { my ( $w, $dir ) = @_ ; + unless ($dir=~/\//) { $dir .= '/' } + my @names = $w->Callback("-dircmd", $dir, $w->cget("-showhidden")); + return( @names ) } + +__END__ diff --git a/scripts/context/perl/pdftrimwhite.pl b/scripts/context/perl/pdftrimwhite.pl new file mode 100644 index 000000000..6ac4f70c5 --- /dev/null +++ b/scripts/context/perl/pdftrimwhite.pl @@ -0,0 +1,525 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' + if 0; + +#D \module +#D [ file=pdftrimwhite.pl, +#D version=2000.07.13, +#D title=PDF postprocessing, +#D subtitle=cropping whitespace from pdf files, +#D author=Hans Hagen, +#D date=\currentdate, +#D copyright=PRAGMA ADE] + +#C This module is part of the \CONTEXT\ macro||package and is +#C therefore copyrighted by \PRAGMA. See readme.pdf for +#C details. + +#D This script can be used to crop margins that contain +#D useless information from a \PDF\ image. It does so by: +#D +#D \startitemize[packed,n] +#D \som cropping the image into an alternative file +#D \som determining the boundingbox of the alternative +#D \som cropping the image into a resulting file +#D \stoppacked +#D +#D In the process, some checks are carried out. Step~1 is +#D taken care of by \PDFTEX, step~2 by \GHOSTSCRIPT, using a +#D file generated by \PDFTOPS, and \PDFTEX\ is responsible +#D for step~3. +#D +#D \startuseMPgraphic{original} +#D numeric n ; n = 1cm ; +#D path p ; p := fullsquare xyscaled (8n,12n) ; +#D path q ; q := fullsquare xyscaled (2n,3n) shifted (n,n) ; +#D path r ; r := ((0,0)--(3n,0)) shifted (0, 5.5n) ; +#D path s ; s := ((0,0)--(3n,0)) shifted (0,-5.5n) ; +#D path t ; t := (-2n,-4n) ; +#D path u ; u := p enlarged -.75n ; +#D path v ; v := p enlarged (-1.75n,-2n) shifted (n,1.25n) ; +#D path w ; w := q enlarged .25n ; +#D fill p withcolor .7white ; +#D fill q withcolor .7green ; +#D draw r withpen pencircle scaled .25n withcolor .7green ; +#D draw s withpen pencircle scaled .25n withcolor .7green ; +#D draw t withpen pencircle scaled .50n withcolor .7green ; +#D draw u withpen pencircle scaled .10n withcolor white ; +#D draw v withpen pencircle scaled .10n withcolor .7red ; +#D draw w withpen pencircle scaled .10n ; +#D verbatimtex \tttf \setupframed[frame=off,align=left] etex ; +#D label (btex \framed{crap} etex, center r) ; +#D label (btex \framed{crap} etex, center s) ; +#D label (btex \framed{crap} etex, center t) ; +#D label (btex \framed{graphic} etex, center q) ; +#D label.urt(btex \framed{page} etex, llcorner p) ; +#D label.urt(btex \framed{crop} etex, llcorner u) ; +#D label.lft(btex \framed{leftcrop\\ +#D rightcrop\\ +#D topcrop\\ +#D bottomcrop} etex, .5[ulcorner v,llcorner v]) ; +#D label.bot(btex \framed{offset} etex, .5[llcorner w,lrcorner w]) ; +#D \stopuseMPgraphic +#D +#D \placefigure +#D [here][fig:pdftrimwhite] +#D {Crops and offsets.} +#D {\useMPgraphic{original}} +#D +#D The \TEX\ part has two alternatives, one using \CONTEXT, and +#D another using plain \TEX. The \CONTEXT\ method is slower but +#D can be extended more easily. +#D +#D The script is executed as follows: +#D +#D \starttyping +#D pdftrimwhite [] [] +#D \stoptyping +#D +#D The next call crops \type {test.pdf} to its natural +#D boundingbox. +#D +#D \starttyping +#D pdftrimwhite test +#D \stoptyping +#D +#D If the file has some crap at the bottom, you can say: +#D +#D \starttyping +#D pdftrimwhite test --bottomcrop=2cm +#D \stoptyping +#D +#D This clips 2cm from the bottom. You can clip on all sides +#D individually, in combination or at once, like in: +#D +#D \starttyping +#D pdftrimwhite test --bottomcrop=2cm --crop=1cm +#D \stoptyping +#D +#D The final result is a tightly cropped image. In order to get +#D a 5mm margin around this image, you can say: +#D +#D \starttyping +#D pdftrimwhite test --bottomcrop=2cm --offset=5mm +#D \stoptyping +#D +#D By default, the script intercepts logging messages and +#D writes them to a logfile with the same name as the +#D resulting image and the prefix \type {log}. If no name is +#D given, the name \type {pdftrimwhite} is used for all resulting +#D files. +#D +#D By default, \CONTEXT\ is used. When installed properly, you +#D can also use plain \TEX, by adding a switch \type +#D {--plain}. Partial switched are accepted, so the next call +#D is valid: +#D +#D \starttyping +#D pdftrimwhite test result --bot=2cm --off=5mm --plain +#D \stoptyping +#D +#D The current implementation uses an intermediate \POSTSCRIPT\ +#D file. This may change as \GHOSTSCRIPT\ gets more clever with +#D \PDF\ files. +#D +#D In \in {figure} [fig:pdftrimwhite] the green rectangle is the +#D picture we want to keep. Around this picture, we want a +#D margin, represented by the black rectangle, and specified by +#D \type {--offset}. The white rectangle is the cropbox +#D defined by \type {--crop}. That way we get rid of header +#D and footerlines. The red rectangle results from an +#D additional \type {--leftcrop} and \type {-bottomcrop} and +#D takes care of some content, as represented by the green +#D dot. +#D +#D The \type {--verbose} switch can be used to disable the +#D interception of log messages. + +#D We load a few \PERL\ modules \unknown\ + +use Config ; +use Getopt::Long ; + +use strict ; + +#D \unknown\ and initialize them. + +Getopt::Long::Configure + ("auto_abbrev", + "ignore_case", + "pass_through") ; + +#D Before fetching the switches, we initialize the +#D variables. + +my $Crop = "0cm" ; + +my $LeftCrop = "0cm" ; +my $RightCrop = "0cm" ; +my $TopCrop = "0cm" ; +my $BottomCrop = "0cm" ; + +my $Offset = "0cm" ; + +my $GSbin = "" ; +my $Verbose = 0 ; +my $Help = 0 ; +my $UsePlain = 0 ; + +my $Page = 1 ; + +#D On \MSWINDOWS\ and \UNIX\ the following defaults, combined +#D with the check later, should work out okay. + +my $pdfps = "pdftops" ; +my $gs = "gs" ; + +my $thisisunix = $Config{'osname'} !~ /dos|mswin/i ; + +#D When no resulting file is given, we use \type {pdftrimwhite} +#D as name (checked later). + +my $figurefile = "" ; +my $resultfile = "" ; +my $tempfile = "" ; + +my $programname = "pdftrimwhite" ; + +#D Messages are temporarily saved and written to a log file +#D afterwards. + +my $results = "" ; +my $pipe = "" ; +my $result = "" ; + +#D Unfortunately we need this information, first since +#D \PDFTOPS\ does not honor the cropbox, and second because +#D the vertical coordinated are swapped. + +my $pwidth = 597 ; +my $pheight = 847 ; +my $hoffset = 0 ; +my $voffset = 0 ; + +#D A few more variables. + +my $width = my $height = my $llx = my $lly = my $urx = my $ury = 0 ; + +#D Here are the switches we accept. The \type {--gsbin} switch +#D is a bonus one, and the \type {--help} switch comes +#D naturally. + +&GetOptions + ( "leftcrop=s" => \$LeftCrop , + "rightcrop=s" => \$RightCrop , + "topcrop=s" => \$TopCrop , + "bottomcrop=s" => \$BottomCrop, + "crop=s" => \$Crop , + "offset=s" => \$Offset , + "verbose" => \$Verbose , + "gsbin=s" => \$GSbin , + "plain" => \$UsePlain , + "page=i" => \$Page , + "help" => \$Help ) ; + +#D If asked for, or if no file is given, we provide some +#D help information. + +sub PrintHelp + { print "This is PdfTrimWhite\n\n" . + "usage:\n\n" . + "pdftrimwhite [switches] filename result\n\n" . + "switches:\n\n" . + "--crop=\n" . + "--offset=\n" . + "--leftcrop=\n" . + "--rightcrop=\n" . + "--topcrop=\n" . + "--bottomcrop=\n" . + "--gsbin=\n" . + "--page=\n" . + "--plain\n" . + "--verbose\n" } + +#D The preparations: + +sub GetItRight + { if ($Help) + { PrintHelp() ; exit } + $figurefile = $ARGV[0] ; $figurefile =~ s/\.pdf$//oi ; + $resultfile = $ARGV[1] ; $resultfile =~ s/\.pdf$//oi ; + $tempfile = "pdftrimwhite-$resultfile" ; + if ($figurefile eq '') + { PrintHelp() ; exit } + unless ($thisisunix) + { $gs = "gswin32c" } + if ($GSbin ne '') + { $gs = $GSbin } + unless (-e "$figurefile.pdf") + { print "Something is terribly wrong: no file found\n" ; + exit } + if (($resultfile eq '')||($resultfile=~/(^\-|\.)/io)) + { $resultfile = $programname } + $pipe = "2>&1" ; + if ($thisisunix) + { $pipe = "2>&1" } } + +#D Something common. + +sub SavePageData + { return "% saving page data +\\immediate\\openout\\scratchwrite=$figurefile.tmp +\\immediate\\write\\scratchwrite + {\\HOffsetBP\\space\\VOffsetBP\\space + \\FigureWidthBP\\space\\FigureHeightBP} +\\immediate\\closeout\\scratchwrite\n" } + +sub MakePageConTeXt + { return "% the real work +\\definepapersize + [Crap] + [width=\\FigureWidth, + height=\\FigureHeight] +\\setuppapersize + [Crap][Crap] +\\setuplayout + [topspace=0cm,backspace=0pt, + height=middle,width=middle, + header=0pt,footer=0pt] +\\starttext + \\startstandardmakeup + \\clip + [voffset=\\VOffset, + hoffset=\\HOffset, + width=\\FigureWidth, + height=\\FigureHeight] + {\\externalfigure[$figurefile.pdf][page=$Page]\\hss} + \\stopstandardmakeup +\\stoptext\n" } + +sub MakePagePlainTeX + { return "% the real work +\\output{} +\\hoffset=-1in +\\voffset=\\hoffset +\\pdfpageheight=\\FigureHeight +\\pdfpagewidth=\\FigureWidth +\\vbox to \\pdfpageheight + {\\offinterlineskip + \\vskip-\\VOffset + \\hbox to \\pdfpagewidth{\\hskip-\\HOffset\\box0\\hss} + \\vss} +\\end\n" } + +sub CalculateClip + { return "% some calculations +\\dimen0=\\figurewidth +\\dimen2=\\figureheight +\\dimen4=$Crop +\\dimen6=$Crop +\\advance\\dimen4 by $LeftCrop +\\advance\\dimen6 by $TopCrop +\\advance\\dimen0 by -\\dimen4 +\\advance\\dimen0 by -$Crop +\\advance\\dimen0 by -$RightCrop +\\advance\\dimen2 by -\\dimen6 +\\advance\\dimen2 by -$Crop +\\advance\\dimen2 by -$BottomCrop +\\edef\\FigureWidth {\\the\\dimen0} +\\edef\\FigureHeight{\\the\\dimen2} +\\edef\\HOffset {\\the\\dimen4} +\\edef\\VOffset {\\the\\dimen6} +\\ScaledPointsToWholeBigPoints{\\number\\dimen0}\\FigureWidthBP +\\ScaledPointsToWholeBigPoints{\\number\\dimen2}\\FigureHeightBP +\\ScaledPointsToWholeBigPoints{\\number\\dimen4}\\HOffsetBP +\\ScaledPointsToWholeBigPoints{\\number\\dimen6}\\VOffsetBP\n" } + +sub RecalculateClip + { return "% some calculations +\\dimen0=${width}bp +\\dimen2=${height}bp +\\dimen4=${hoffset}bp +\\dimen6=${pheight}bp +\\advance\\dimen0 by $Offset +\\advance\\dimen0 by $Offset +\\advance\\dimen2 by $Offset +\\advance\\dimen2 by $Offset +\\advance\\dimen4 by ${llx}bp +\\advance\\dimen4 by -$Offset +\\advance\\dimen6 by -${lly}bp +\\advance\\dimen6 by $Offset +\\advance\\dimen6 by -\\dimen2 +\\advance\\dimen6 by $TopCrop +\\edef\\FigureWidth {\\the\\dimen0} +\\edef\\FigureHeight{\\the\\dimen2} +\\edef\\HOffset {\\the\\dimen4} +\\edef\\VOffset {\\the\\dimen6}\n" } + +#D The previous scripts could be more sparse, but for the +#D moment we prefer readability. Both scripts save some +#D information in temporary file. We choose between them with +#D the following sub routine. + +#D The first pass: + +sub PrepareConTeXt + { return "% interface=en +\\setupoutput[pdftex] +\\getfiguredimensions[$figurefile.pdf][page=$Page]\n" } + +sub PreparePlainTeX + { return "% plain tex alternative, needs recent supp-mis +\\input supp-mis +\\pdfoutput=1 +\\newdimen\\figurewidth +\\newdimen\\figureheight +\\setbox0=\\hbox + {\\immediate\\pdfximage page $Page {$figurefile.pdf}\\pdfrefximage\\pdflastximage} +\\figurewidth=\\wd0 +\\figureheight=\\ht0\n" } + +sub PrepareFirstPass + { open (TEX, ">$tempfile.tex") ; + if ($UsePlain) + { print TEX + PreparePlainTeX . + CalculateClip . + SavePageData . + MakePagePlainTeX } + else + { print TEX + PrepareConTeXt . + CalculateClip . + SavePageData . + MakePageConTeXt } + close TEX } + +#D The second pass looks much like the first one, but this +#D time we don't save information, use the natural +#D boundingbox, and provide the offset. + +sub SetupConTeXt + { return "% interface=en +\\setupoutput[pdftex]\n" } + +sub SetupPlainTeX + { return "% plain tex alternative +\\pdfoutput=1 +\\setbox0=\\hbox + {\\immediate\\pdfximage page $Page {$figurefile.pdf}\\pdfrefximage\\pdflastximage}\n" } + +sub PrepareSecondPass + { open (TEX, ">$tempfile.tex") ; + if ($UsePlain) + { print TEX + SetupPlainTeX . + RecalculateClip . + MakePagePlainTeX } + else + { print TEX + SetupConTeXt . + RecalculateClip . + MakePageConTeXt } + close TEX } + +#D The information we save in the first pass, is loaded here. + +sub FetchPaperSize + { open (TMP,"$figurefile.tmp") ; + while () + { chomp ; + if (/^(\d+) (\d+) (\d+) (\d+) *$/oi) + { $hoffset = $1 ; + $voffset = $2 ; + $pwidth = $3 ; + $pheight = $4 ; + last } } + close (TMP) } + +#D Here we try to find the natural boundingbox. We need to +#D pick up the page dimensions here. + +sub RunTeX + { if ($UsePlain) + { $result = `pdftex -prog=pdftex -fmt=plain -int=batchmode $tempfile` } + else + { $result = `texexec --batch --once --purge $tempfile` } + print $result if $Verbose ; $results .= "$result\n" } + +sub FindBoundingBox + { $result = `$gs -sDEVICE=bbox -dNOPAUSE -dBATCH $tempfile.pdf $pipe` ; + print $result if $Verbose ; $results .= "$result\n" } + +sub IdentifyCropBox + { RunTeX() ; + FetchPaperSize () ; + FindBoundingBox() } + +#D Just to be sure, we check if there is some image data, so +#D that we can retry if something went wrong. Unfortunately we cannot +#D safely check on a high res boundingbox. + +my $digits = '([\-\d\.]+)' ; + +sub ValidatedCropBox + { if ($result =~ /BoundingBox:\s*$digits\s+$digits\s+$digits\s+$digits\s*/mois) + { $llx = $1 ; $lly = $2 ; $urx = $3 ; $ury = $4 } + else + { print "Something is terribly wrong: no boundingbox:\n$result\n" ; exit } + $width = abs($urx - $llx) ; + $height = abs($ury - $lly) ; + if ($width&&$height) + { return 1 } + else + { unless ($width) + { print "Something seems wrong: no width\n" ; + $LeftCrop = "0cm" ; $RightCrop = "0cm" ; $Crop = "0cm" } + unless ($height) + { print "Something seems wrong: no height\n" ; + $TopCrop = "0cm" ; $BottomCrop = "0cm" ; $Crop = "0cm" } + return 0 } } + +#D This is the main cropping routine. + +sub FixCropBox + { RunTeX() } + +#D For error tracing we save the log information in a file. + +sub RenameResult + { unlink "$resultfile.pdf" ; + rename "$tempfile.pdf", "$resultfile.pdf" } + +sub SaveLogInfo + { open (LOG, ">$resultfile.log") ; + print LOG $results ; + close (LOG) } + +#D We remove all temporary files. + +sub CleanUp + { unless ($Verbose) + { unlink "$tempfile.tex" ; + unlink "$tempfile.tuo" ; + unlink "$tempfile.tui" ; + unlink "$figurefile.tmp" } } + +#D Here it all comes together. + +GetItRight() ; + +PrepareFirstPass() ; + +IdentifyCropBox () ; + +unless (ValidatedCropBox()) + { PrepareFirstPass() ; + IdentifyCropBox () } + +if (ValidatedCropBox()) + { PrepareSecondPass() ; + FixCropBox() } + +RenameResult() ; +SaveLogInfo() ; + +CleanUp () ; diff --git a/scripts/context/perl/texfind.pl b/scripts/context/perl/texfind.pl new file mode 100644 index 000000000..53a560c79 --- /dev/null +++ b/scripts/context/perl/texfind.pl @@ -0,0 +1,270 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' + if 0; + +#D \module +#D [ file=texfind.pl, +#D version=1998.05.10, +#D title=\TEXFIND, +#D subtitle=searching 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 licen-en.pdf for +#C details. + +# test with "doif(un|)defined" + +use strict ; +use Getopt::Long ; +use File::Find ; +use Cwd ; +use Tk ; +use Tk::widgets ; +use Tk::ROText ; + +use FindBin ; +use lib $FindBin::Bin ; +use path_tre ; + +my $FileSuffix = 'tex' ; +my $SearchString = '' ; +my $Recurse = 0 ; +my $NumberOfHits = 0 ; +my $QuitSearch = 0 ; +my $Location = '' ; +my $currentpath = '.' ; + +my @FileList ; + +my ($dw, $mw, $log, $sea, $fil, $num, $but, $dir, $loc) ; + +$mw = MainWindow -> new () ; +$dw = MainWindow -> new () ; + +$mw -> protocol( 'WM_DELETE_WINDOW' => sub { exit } ) ; +$dw -> protocol( 'WM_DELETE_WINDOW' => sub { exit } ) ; + +$log = $mw -> Scrolled ( 'ROText' , + -scrollbars => 'se' , + -font => 'courier' , + -wrap => 'none' , + -width => 65 , + -height => 22 ) + -> pack ( -side => 'bottom' , + -padx => 2 , + -pady => 2 , + -expand => 1 , + -fill => 'both' ) ; + +$sea = $mw -> Entry ( -textvariable => \$SearchString , + -font => 'courier' , + -width => 20 ) + -> pack ( -side => 'left' , + -padx => 2 , + -pady => 2 ) ; + +$fil = $mw -> Entry ( -textvariable => \$FileSuffix , + -font => 'courier' , + -width => 5 ) + -> pack ( -side => 'left' , + -padx => 2 , + -pady => 2 ) ; + +$but = $mw -> Checkbutton ( -variable => \$Recurse , + -text => 'recurse' ) + -> pack ( -side => 'left' ) ; + +$num = $mw -> Entry ( -textvariable => \$NumberOfHits , + -font => 'courier' , + -justify => 'right' , + -width => 5 ) + -> pack ( -side => 'right' , + -padx => 2 , + -pady => 2 ) ; + +$loc = $mw -> Entry ( -textvariable => \$Location , + -font => 'courier' , + -width => 8 ) + -> pack ( -side => 'right' , + -padx => 2 , + -pady => 2 ) ; + +sub BuildDir + { if (Exists($dir)) { $dir -> destroy } ; + $dir = $dw -> Scrolled ( 'PathTree' , + -scrollbars => 'se' ) + -> pack ( -expand => 1 , + -fill => 'both' , + -padx => 2 , + -pady => 2 ) ; + $dir -> configure ( -font => 'courier' , + -height => 24 , + -width => 65 , + -selectbackground => 'blue3' , + -browsecmd => \&ChangePath ) ; + $dir -> bind ('' , \&ShowFile ) ; + $dir -> bind ('' , \&ShowFile ) } + +BuildDir ; + +sub ShowFile { $mw -> raise ; $sea -> focusForce } +sub ShowPath { $dw -> raise ; $dir -> focusForce } + +$log -> tagConfigure ( 'found', -foreground => 'green3' ) ; +$log -> tagConfigure ( 'title', -foreground => 'blue3' ) ; + +$sea -> bind ('' , \&LocateStrings ) ; +$fil -> bind ('' , \&LocateStrings ) ; +$loc -> bind ('' , \&ChangeLocation ) ; +$log -> bind ('' , \&ShowPath ) ; + +$sea -> bind ('' , \&QuitSearch ) ; +$fil -> bind ('' , \&QuitSearch ) ; +$loc -> bind ('' , \&QuitSearch ) ; + +$sea -> bind ('' , \&QuitSearch ) ; +$fil -> bind ('' , \&QuitSearch ) ; +$loc -> bind ('' , \&QuitSearch ) ; +$log -> bind ('' , \&QuitSearch ) ; + +$sea -> bind ('' , \&LocateStrings ) ; +$fil -> bind ('' , \&LocateStrings ) ; +$loc -> bind ('' , \&ChangeLocation ) ; +$log -> bind ('' , \&ShowPath ) ; + +sub ChangePath + { my $currentpath = shift ; +chdir($currentpath) ; + $QuitSearch = 1 ; + $log -> delete ('1.0', 'end') ; + $log -> insert ('end', "$currentpath\n\n", 'title') } + +sub ChangeLocation + { $QuitSearch = 1 ; + $log -> delete ('1.0', 'end') ; + $Location =~ s/^\s*//o ; + $Location =~ s/\s*$//o ; + $Location =~ s/(\\|\/\/)/\//go ; + unless (-d $Location) + { unless ($Location =~ /\//) { $Location .= '/' } } + if (-d $Location) + { $log -> insert ('end', "changed to location '$Location'\n\n", 'title') ; + $currentpath = $Location ; + chdir ($currentpath) ; + $dir -> destroy ; + BuildDir ; + $dw -> raise ; + $dw -> focusForce } + else + { $log -> insert ('end', "unknown location '$Location'\n\n", 'title') ; + $Location = '' } } + +sub QuitSearch + { $QuitSearch = 1 } + +sub SearchFile + { my ($FileName, $SearchString) = @_ ; + my $Ok = 0 ; my $len ; + open (TEX, $FileName) ; + my $LineNumber = 0 ; + while () + { ++$LineNumber ; + if ($QuitSearch) + { if ($Ok) { $log -> see ('end') } + last } + if (/$SearchString/i) + { ++$NumberOfHits ; $num -> update ; + unless ($Ok) + { $Ok = 1 ; + $log -> insert ('end', "$FileName\n\n",'title') } + $log -> insert ('end', sprintf("%5i : ",$LineNumber), 'title') ; + s/^\s*//o ; +# + $len = 0 ; + while (/(.*?)($SearchString)/gi) + { $len += length($1) + length($2) ; + $log -> insert ('end', "$1") ; + $log -> insert ('end', "$2", 'found' ) } + $_ = substr($_,$len) ; + $log -> insert ('end', "$_") ; +# + $log -> update ; + $log -> see ('end') } } + if ($Ok) { $log -> insert ('end', "\n") } + close (TEX) } + +sub DoLocateFiles + { @FileList = () ; + $NumberOfHits = 0 ; + if ($FileSuffix ne "") + { $log -> delete ('1.0', 'end') ; + if ($Recurse) + { $log -> insert ('end', "recursively identifying files\n", 'title') ; + $log -> see ('end') ; + find (\&wanted, $currentpath) ; + sub wanted + { if ($QuitSearch) { last ; return } + if (/.*\.$FileSuffix/i) + { ++$NumberOfHits ; $num -> update ; + push @FileList, $File::Find::name } } } + else + { $log -> insert ('end', "identifying files\n", 'title') ; + $log -> see ('end') ; + opendir(DIR, $currentpath) ; my @TEMPLIST = readdir(DIR) ; closedir(DIR) ; + foreach my $FileName (@TEMPLIST) + { if ($FileName =~ /.*\.$FileSuffix/i) + { ++$NumberOfHits ; $num -> update ; + if ($QuitSearch) + { last } + push @FileList, $FileName } } } + @FileList = sort @FileList } } + +sub DoLocateStrings + { $log -> delete ('1.0', 'end') ; + $log -> update ; + $log -> see ('end') ; + $NumberOfHits = 0 ; + if ($SearchString ne "") + { foreach my $FileName (@FileList) + { if ($QuitSearch) + { $log -> insert ('end', "search aborted\n", 'title') ; + $log -> see ('end') ; + last } + SearchFile($FileName,$SearchString) } } + unless ($QuitSearch) + { $log -> insert ('end', "done\n", 'title') ; + $log -> see ('end') } } + +sub LocateStrings + { $QuitSearch = 0 ; + DoLocateFiles() ; + DoLocateStrings() } + +$log -> insert ('end', + + "data fields\n\n" , '' , + + + "string :", 'title', " regular expression to search for\n" , '' , + "suffix :", 'title', " type of file to search in\n" , '' , + "recurse :", 'title', " enable searching subpaths\n" , '' , + "location :", 'title', " drive of root path\n" , '' , + "counter :", 'title', " file/hit counter\n\n" , '' , + + "key bindings\n\n" , '' , + + "double 1 :", 'title', " directory window <-> search window\n" , '' , + "enter :", 'title', " start searching\n" , '' , + "escape :", 'title', " quit searching\n\n" , '' , + + "current path\n\n" , '' , + + cwd(), 'title', "\n\n" , 'title' ) ; + +$log -> update ; + +ShowPath ; + +MainLoop() ; diff --git a/scripts/context/perl/texfont.pl b/scripts/context/perl/texfont.pl new file mode 100644 index 000000000..5b3c1f1d7 --- /dev/null +++ b/scripts/context/perl/texfont.pl @@ -0,0 +1,1373 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' + if 0; + +# This is an example of a crappy unstructured file but once +# I know what should happen exactly, I will clean it up. + +# once it works all right, afmpl will be default + +# todo : ttf (partially doen already) + +# added: $pattern in order to avoid fuzzy shelle expansion of +# filenames (not consistent over perl and shells); i hate that +# kind of out of control features. + +#D \module +#D [ file=texfont.pl, +#D version=2004.02.06, % 2000.12.14 +#D title=Font Handling, +#D subtitle=installing and generating, +#D author=Hans Hagen ++, +#D date=\currentdate, +#D copyright={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 For usage information, see \type {mfonts.pdf}. + +#D Todo : copy afm/pfb from main to local files to ensure metrics +#D Todo : Wybo's help system +#D Todo : list of encodings [texnansi, ec, textext] + +#D Thanks to George N. White III for solving a couple of bugs. +#D Thanks to Adam T. Lindsay for adding Open Type support (and more). + +use strict ; + +my $savedoptions = join (" ",@ARGV) ; + +use Config ; +use FindBin ; +use File::Copy ; +use Getopt::Long ; +use Data::Dumper; + +$Getopt::Long::passthrough = 1 ; # no error message +$Getopt::Long::autoabbrev = 1 ; # partial switch accepted + +# Unless a user has specified an installation path, we take +# the dedicated font path or the local path. + +## $dosish = ($Config{'osname'} =~ /dos|mswin/i) ; +my $dosish = ($Config{'osname'} =~ /^(ms)?dos|^os\/2|^(ms|cyg)win/i) ; + +my $IsWin32 = ($^O =~ /MSWin32/i); +my $SpacyPath = 0 ; + +# great, the win32api is not present in all perls + +BEGIN { + $IsWin32 = ($^O =~ /MSWin32/i) ; + $SpacyPath = 0 ; + if ($IsWin32) { + my $str = `kpsewhich -expand-path=\$TEXMF` ; + $SpacyPath = ($str =~ / /) ; + if ($SpacyPath) { + require Win32::API; import Win32::API; + } + } +} + +# great, glob changed to bsd glob in an incompatible way ... sigh, we now +# have to catch a failed glob returning the pattern +# +# to stupid either: +# +# sub validglob { +# my @globbed = glob(shift) ; +# if ((@globbed) && (! -e $globbed[0])) { +# return () ; +# } else { +# return @globbed ; +# } +# } +# +# so now we have: + +sub validglob { + my @globbed = glob(shift) ; + my @globout = () ; + foreach my $file (@globbed) { + push (@globout,$file) if (-e $file) ; + } + return @globout ; +} + +sub GetShortPathName { + my ($filename) = @_ ; + return $filename unless (($IsWin32)&&($SpacyPath)) ; + my $GetShortPathName = new Win32::API('kernel32', 'GetShortPathName', 'PPN', 'N') ; + if(not defined $GetShortPathName) { + die "Can't import API GetShortPathName: $!\n" ; + } + my $buffer = " " x 260; + my $len = $GetShortPathName->Call($filename, $buffer, 260) ; + return substr($buffer, 0, $len) ; +} + +my $installpath = "" ; + +if (defined($ENV{TEXMFLOCAL})) { + $installpath = "TEXMFLOCAL" ; +} + +if (defined($ENV{TEXMFFONTS})) { + $installpath = "TEXMFFONTS" ; +} + +if ($installpath eq "") { + $installpath = "TEXMFLOCAL" ; # redundant +} + +my $encoding = "texnansi" ; +my $vendor = "" ; +my $collection = "" ; +my $fontroot = "" ; #/usr/people/gwhite/texmf-fonts" ; +my $help = 0 ; +my $makepath = 0 ; +my $show = 0 ; +my $install = 0 ; +my $sourcepath = "." ; +my $passon = "" ; +my $extend = "" ; +my $narrow = "" ; +my $slant = "" ; +my $spaced = "" ; +my $caps = "" ; +my $noligs = 0 ; +my $nofligs = 0 ; +my $test = 0 ; +my $virtual = 0 ; +my $novirtual = 0 ; +my $listing = 0 ; +my $remove = 0 ; +my $expert = 0 ; +my $trace = 0 ; +my $afmpl = 0 ; +my $trees = 'TEXMFFONTS,TEXMFLOCAL,TEXMFEXTRA,TEXMFMAIN,TEXMFDIST' ; +my $pattern = '' ; +my $uselmencodings = 0 ; + +my $fontsuffix = "" ; +my $namesuffix = "" ; + +my $batch = "" ; + +my $weight = "" ; +my $width = "" ; + +my $preproc = 0 ; # atl: formerly OpenType switch +my $variant = "" ; # atl: encoding variant +my $extension = "pfb" ; # atl: default font extension +my $lcdf = "" ; # atl: trigger for lcdf otftotfm + +my @cleanup = () ; # atl: build list of generated files to delete + +# todo: parse name for style, take face from command line +# +# @Faces = ("Serif","Sans","Mono") ; +# @Styles = ("Slanted","Spaced", "Italic","Bold","BoldSlanted","BoldItalic") ; +# +# for $fac (@Faces) { for $sty (@Styles) { $FacSty{"$fac$sty"} = "" } } + +&GetOptions + ( "help" => \$help, + "makepath" => \$makepath, + "noligs" => \$noligs, + "nofligs" => \$nofligs, + "show" => \$show, + "install" => \$install, + "encoding=s" => \$encoding, + "variant=s" => \$variant, # atl: used as a suffix to $encfile only + "vendor=s" => \$vendor, + "collection=s" => \$collection, + "fontroot=s" => \$fontroot, + "sourcepath=s" => \$sourcepath, + "passon=s" => \$passon, + "slant=s" => \$slant, + "spaced=s" => \$spaced, + "extend=s" => \$extend, + "narrow=s" => \$narrow, + "listing" => \$listing, + "remove" => \$remove, + "test" => \$test, + "virtual" => \$virtual, + "novirtual" => \$novirtual, + "caps=s" => \$caps, + "batch" => \$batch, + "weight=s" => \$weight, + "width=s" => \$width, + "expert" => \$expert, + "afmpl" => \$afmpl, + "afm2pl" => \$afmpl, + "lm" => \$uselmencodings, + "rootlist=s" => \$trees, + "pattern=s" => \$pattern, + "trace" => \$trace, # --verbose conflicts with --ve + "preproc" => \$preproc, # atl: trigger conversion to pfb + "lcdf" => \$lcdf ) ; # atl: trigger use of lcdf fonttoools + +# for/from Fabrice: + +my $own_path = "$FindBin::Bin/" ; + +$FindBin::RealScript =~ m/([^\.]*)(\.pl|\.bat|\.exe|)/io ; + +my $own_name = $1 ; +my $own_type = $2 ; +my $own_stub = "" ; + +if ($own_type =~ /pl/oi) { + $own_stub = "perl " +} + +if ($caps) { $afmpl = 0 } # for the moment + +# so we can use both combined + +if ($lcdf) { + $novirtual = 1 ; +} + +if (!$novirtual) { + $virtual = 1 ; +} + +# A couple of routines. + +sub report { + my $str = shift ; + $str =~ s/ / /goi ; + if ($str =~ /(.*?)\s+([\:\/])\s+(.*)/o) { + if ($1 eq "") { + $str = " " ; + } else { + $str = $2 ; + } + print sprintf("%22s $str %s\n",$1,$3) ; + } +} + +sub error { + report("processing aborted : " . shift) ; + print "\n" ; + report "--help : show some more info" ; + exit ; +} + +# The banner. + +print "\n" ; +report ("TeXFont 2.2.1 - ConTeXt / PRAGMA ADE 2000-2004") ; +print "\n" ; + +# Handy for scripts: one can provide a preferred path, if it +# does not exist, the current path is taken. + +if (!(-d $sourcepath)&&($sourcepath ne 'auto')) { $sourcepath = "." } + +# Let's make multiple masters if requested. + +sub create_mm_font + { my ($name,$weight,$width) = @_ ; my $flag = my $args = my $tags = "" ; + my $ok ; + if ($name ne "") + { report ("mm source file : $name") } + else + { error ("missing mm source file") } + if ($weight ne "") + { report ("weight : $weight") ; + $flag .= " --weight=$weight " ; + $tags .= "-weight-$weight" } + if ($width ne "") + { report ("width : $width") ; + $flag .= " --width=$width " ; + $tags .= "-width-$width" } + error ("no specification given") if ($tags eq "") ; + error ("no amfm file found") unless (-f "$sourcepath/$name.amfm") ; + error ("no pfb file found") unless (-f "$sourcepath/$name.pfb") ; + $args = "$flag --precision=5 --kern-precision=0 --output=$sourcepath/$name$tags.afm" ; + my $command = "mmafm $args $sourcepath/$name.amfm" ; + print "$command\n" if $trace ; + $ok = `$command` ; chomp $ok ; + if ($ok ne "") { report ("warning $ok") } + $args = "$flag --precision=5 --output=$sourcepath/$name$tags.pfb" ; + $command = "mmpfb $args $sourcepath/$name.pfb" ; + print "$command\n" if $trace ; + $ok = `$command` ; chomp $ok ; + if ($ok ne "") { report ("warning $ok") } + report ("mm result file : $name$tags") } + +if (($weight ne "")||($width ne "")) + { create_mm_font($ARGV[0],$weight,$width) ; + exit } + +# go on + +if (($listing||$remove)&&($sourcepath eq ".")) + { $sourcepath = "auto" } + +if ($fontroot eq "") + { if ($dosish) + { $fontroot = `kpsewhich -expand-path=\$$installpath` } + else + { $fontroot = `kpsewhich -expand-path=\\\$$installpath` } + chomp $fontroot } + + +if ($fontroot =~ /\s+/) # needed for windows, spaces in name + { $fontroot = &GetShortPathName($fontroot) } # but ugly when not needed + +if ($test) + { $vendor = $collection = "test" ; + $install = 1 } + +if (($spaced ne "") && ($spaced !~ /\d/)) { $spaced = "50" } +if (($slant ne "") && ($slant !~ /\d/)) { $slant = "0.167" } +if (($extend ne "") && ($extend !~ /\d/)) { $extend = "1.200" } +if (($narrow ne "") && ($narrow !~ /\d/)) { $narrow = "0.800" } +if (($caps ne "") && ($caps !~ /\d/)) { $caps = "0.800" } + +$encoding = lc $encoding ; +$vendor = lc $vendor ; +$collection = lc $collection ; + +if ($encoding =~ /default/oi) { $encoding = "texnansi" } + +my $lcfontroot = lc $fontroot ; + +# Auto search paths + +my @trees = split(/\,/,$trees) ; + +# Test for help asked. + +if ($help) + { report "--fontroot=path : texmf destination font root (default: $lcfontroot)" ; + report "--rootlist=paths : texmf source roots (default: $trees)" ; + report "--sourcepath=path : when installing, copy from this path (default: $sourcepath)" ; + report "--sourcepath=auto : locate and use vendor/collection" ; + print "\n" ; + report "--vendor=name : vendor name/directory" ; + report "--collection=name : font collection" ; + report "--encoding=name : encoding vector (default: $encoding)" ; + report "--variant=name : encoding variant (.enc file or otftotfm features)" ; + print "\n" ; + report "--spaced=s : space glyphs in font by promille of em (0 - 1000)" ; + report "--slant=s : slant glyphs in font by factor (0.0 - 1.5)" ; + report "--extend=s : extend glyphs in font by factor (0.0 - 1.5)" ; + report "--caps=s : capitalize lowercase chars by factor (0.5 - 1.0)" ; + report "--noligs --nofligs : remove ligatures" ; + print "\n" ; + report "--install : copy files from source to font tree" ; + report "--listing : list files on auto sourcepath" ; + report "--remove : remove files on auto sourcepath" ; + report "--makepath : when needed, create the paths" ; + print "\n" ; + report "--test : use test paths for vendor/collection" ; + report "--show : run tex on texfont.tex" ; + print "\n" ; + report "--batch : process given batch file" ; + print "\n" ; + report "--weight : multiple master weight" ; + report "--width : multiple master width" ; + print "\n" ; + report "--expert : also handle expert fonts" ; + print "\n" ; + report "--afmpl : use afm2pl instead of afm2tfm" ; + report "--preproc : pre-process ttf/otf, converting them to pfb" ; + report "--lcdf : use lcdf fonttools to create virtual encoding" ; + exit } + +if (($batch)||(($ARGV[0]) && ($ARGV[0] =~ /.+\.dat$/io))) + { my $batchfile = $ARGV[0] ; + unless (-f $batchfile) + { if ($batchfile !~ /\.dat$/io) { $batchfile .= ".dat" } } + unless (-f $batchfile) + { report ("trying to locate : $batchfile") ; + $batchfile = `kpsewhich -format="other text files" -progname=context $batchfile` ; + chomp $batchfile } + error ("unknown batch file $batchfile") unless -e $batchfile ; + report ("processing batch file : $batchfile") ; + my $select = (($vendor ne "")||($collection ne "")) ; + my $selecting = 0 ; + if (open(BAT, $batchfile)) + { while () + { chomp ; + s/(.+)\#.*/$1/o ; + next if (/^\s*$/io) ; + if ($select) + { if ($selecting) + { if (/^\s*[\#\%]/io) { if (!/\-\-/o) { last } else { next } } } + elsif ((/^\s*[\#\%]/io)&&(/$vendor/i)&&(/$collection/i)) + { $selecting = 1 ; next } + else + { next } } + else + { next if (/^\s*[\#\%]/io) ; + next unless (/\-\-/oi) } + s/\s+/ /gio ; + s/(--en.*\=)\?/$1$encoding/io ; + report ("batch line : $_") ; + # system ("perl $0 --fontroot=$fontroot $_") } + my $own_quote = ( $own_path =~ m/^[^\"].* / ? "\"" : "" ); + my $switches = '' ; + $switches .= "--afmpl " if $afmpl ; + system ("$own_stub$own_quote$own_path$own_name$own_type$own_quote $switches --fontroot=$fontroot $_") } + close (BAT) } + exit } + +error ("unknown vendor $vendor") unless $vendor ; +error ("unknown collection $collection") unless $collection ; +error ("unknown tex root $lcfontroot") unless -d $fontroot ; + +my $varlabel = $variant ; + +if ($lcdf) + { $varlabel =~ s/,/-/goi ; + $varlabel =~ tr/a-z/A-Z/ } + +if ($varlabel ne "") + { $varlabel = "-$varlabel" } + +my $identifier = "$encoding$varlabel-$vendor-$collection" ; + +my $outlinepath = $sourcepath ; my $path = "" ; + +my $shape = "" ; + +if ($noligs||$nofligs) + { report ("ligatures : removed") ; + $fontsuffix .= "-unligatured" ; + $namesuffix .= "-NoLigs" } + +if ($caps ne "") + { if ($caps <0.5) { $caps = 0.5 } + elsif ($caps >1.0) { $caps = 1.0 } + $shape .= " -c $caps " ; + report ("caps factor : $caps") ; + $fontsuffix .= "-capitalized-" . int(1000*$caps) ; + $namesuffix .= "-Caps" } + +if ($extend ne "") + { if ($extend<0.0) { $extend = 0.0 } + elsif ($extend>1.5) { $extend = 1.5 } + report ("extend factor : $extend") ; + if ($lcdf) + { $shape .= " -E $extend " } + else + { $shape .= " -e $extend " } + $fontsuffix .= "-extended-" . int(1000*$extend) ; + $namesuffix .= "-Extended" } + +if ($narrow ne "") # goodie + { $extend = $narrow ; + if ($extend<0.0) { $extend = 0.0 } + elsif ($extend>1.5) { $extend = 1.5 } + report ("narrow factor : $extend") ; + if ($lcdf) + { $shape .= " -E $extend " } + else + { $shape .= " -e $extend " } + $fontsuffix .= "-narrowed-" . int(1000*$extend) ; + $namesuffix .= "-Narrowed" } + +if ($slant ne "") + { if ($slant <0.0) { $slant = 0.0 } + elsif ($slant >1.5) { $slant = 1.5 } + report ("slant factor : $slant") ; + if ($lcdf) + { $shape .= " -S $slant " } + else + { $shape .= " -s $slant " } + $fontsuffix .= "-slanted-" . int(1000*$slant) ; + $namesuffix .= "-Slanted" } + +if ($spaced ne "") + { if ($spaced < 0) { $spaced = 0 } + elsif ($spaced >1000) { $spaced = 1000 } + report ("space factor : $spaced") ; + if ($lcdf) + { $shape .= " -L $spaced " } + else + { $shape .= " -m $spaced " } + $fontsuffix .= "-spaced-" . $spaced ; + $namesuffix .= "-Spaced" } + +if ($sourcepath eq "auto") # todo uppercase root + { foreach my $root (@trees) + { if ($dosish) + { $path = `kpsewhich -expand-path=\$$root` } + else + { $path = `kpsewhich -expand-path=\\\$$root` } + chomp $path ; + $path = $ENV{$root} if (($path eq '') && defined($ENV{$root})) ; + report ("checking root : $root") ; + if ($preproc) + { $sourcepath = "$path/fonts/truetype/$vendor/$collection" } + else + { $sourcepath = "$path/fonts/afm/$vendor/$collection" } + unless (-d $sourcepath) + { my $ven = $vendor ; $ven =~ s/(........).*/$1/ ; + my $col = $collection ; $col =~ s/(........).*/$1/ ; + $sourcepath = "$path/fonts/afm/$ven/$col" ; + if (-d $sourcepath) + { $vendor = $ven ; $collection = $col } } + $outlinepath = "$path/fonts/type1/$vendor/$collection" ; + if (-d $sourcepath) + { # $install = 0 ; # no copy needed + $makepath = 1 ; # make on local if needed + my @files = validglob("$sourcepath/*.afm") ; + if ($preproc) + { @files = validglob("$sourcepath/*.otf") ; + report("locating : otf files") } + unless (@files) + { @files = validglob("$sourcepath/*.ttf") ; + report("locating : ttf files") } + if (@files) + { if ($listing) + { report ("fontpath : $sourcepath" ) ; + print "\n" ; + foreach my $file (@files) + { if (open(AFM,$file)) + { my $name = "unknown name" ; + while () + { chomp ; + if (/^fontname\s+(.*?)$/oi) + { $name = $1 ; last } } + close (AFM) ; + if ($preproc) + { $file =~ s/.*\/(.*)\..tf/$1/io } + else + { $file =~ s/.*\/(.*)\.afm/$1/io } + report ("$file : $name") } } + exit } + elsif ($remove) + { error ("no removal from : $root") if ($root eq 'TEXMFMAIN') ; + foreach my $file (@files) + { if ($preproc) + { $file =~ s/.*\/(.*)\..tf/$1/io } + else + { $file =~ s/.*\/(.*)\.afm/$1/io } + foreach my $sub ("tfm","vf") + { foreach my $typ ("","-raw") + { my $nam = "$path/fonts/$sub/$vendor/$collection/$encoding$varlabel$typ-$file.$sub" ; + if (-s $nam) + { report ("removing : $encoding$varlabel$typ-$file.$sub") ; + unlink $nam } } } } + my $nam = "$encoding$varlabel-$vendor-$collection.tex" ; + if (-e $nam) + { report ("removing : $nam") ; + unlink "$nam" } + my $mapfile = "$encoding$varlabel-$vendor-$collection" ; + foreach my $map ("pdftex","dvips", "dvipdfm") + { my $maproot = "$fontroot/fonts/map/$map/context/"; + if (-e "$maproot$mapfile.map") + { report ("renaming : $mapfile.map -> $mapfile.bak") ; + unlink "$maproot$mapfile.bak" ; + rename "$maproot$mapfile.map", "$maproot$mapfile.bak" } } + exit } + else + { last } } } } + error ("unknown subpath ../fonts/afm/$vendor/$collection") unless -d $sourcepath } + +error ("unknown source path $sourcepath") unless -d $sourcepath ; +error ("unknown option $ARGV[0]") if (($ARGV[0]||'') =~ /\-\-/) ; + +my $afmpath = "$fontroot/fonts/afm/$vendor/$collection" ; +my $tfmpath = "$fontroot/fonts/tfm/$vendor/$collection" ; +my $vfpath = "$fontroot/fonts/vf/$vendor/$collection" ; +my $pfbpath = "$fontroot/fonts/type1/$vendor/$collection" ; +my $ttfpath = "$fontroot/fonts/truetype/$vendor/$collection" ; +my $otfpath = "$fontroot/fonts/opentype/$vendor/$collection" ; +my $encpath = "$fontroot/fonts/enc/dvips/context" ; + +sub mappath + { my $str = shift ; + return "$fontroot/fonts/map/$str/context" } + +# are not on local path ! ! ! ! + +foreach my $path ($afmpath, $pfbpath) + { my @gzipped = <$path/*.gz> ; + foreach my $file (@gzipped) + { print "file = $file\n"; + system ("gzip -d $file") } } + +# For gerben, we only generate a new database when an lsr file is present but for +# myself we force this when texmf-fonts is used (else I get compatibility problems). + +if (($fontroot =~ /texmf\-fonts/o) || (-e "$fontroot/ls-R") || (-e "$fontroot/ls-r") || (-e "$fontroot/LS-R")) { + system ("mktexlsr $fontroot") ; +} + +sub do_make_path + { my $str = shift ; + if ($str =~ /^(.*)\/.*?$/) + { do_make_path($1); } + mkdir $str, 0755 unless -d $str } + +sub make_path + { my $str = shift ; + do_make_path("$fontroot/fonts/$str/$vendor/$collection") } + +if ($makepath&&$install) + { make_path ("afm") ; make_path ("type1") } + +do_make_path(mappath("pdftex")) ; +do_make_path(mappath("dvips")) ; +do_make_path(mappath("dvipdfm")) ; +do_make_path($encpath) ; + +# now fonts/map and fonts/enc + +make_path ("vf") ; +make_path ("tfm") ; + +if ($install) + { error ("unknown afm path $afmpath") unless -d $afmpath ; + error ("unknown pfb path $pfbpath") unless -d $pfbpath } + +error ("unknown tfm path $tfmpath") unless -d $tfmpath ; +error ("unknown vf path $vfpath" ) unless -d $vfpath ; +error ("unknown map path " . mappath("pdftex")) unless -d mappath("pdftex"); +error ("unknown map path " . mappath("dvips")) unless -d mappath("dvips"); +error ("unknown map path " . mappath("dvipdfm")) unless -d mappath("dvipdfm"); + +my $mapfile = "$identifier.map" ; +my $bakfile = "$identifier.bak" ; +my $texfile = "$identifier.tex" ; + + report "encoding vector : $encoding" ; +if ($variant) { report "encoding variant : $variant" } + report "vendor name : $vendor" ; + report " source path : $sourcepath" ; + report "font collection : $collection" ; + report "texmf font root : $lcfontroot" ; + report " map file name : $mapfile" ; + +if ($install) { report "source path : $sourcepath" } + +my $fntlist = "" ; + +my $runpath = $sourcepath ; + +my @files ; + +sub UnLink + { foreach my $f (@_) + { if (unlink $f) + { report "deleted : $f" if $trace } } } + +sub globafmfiles + { my ($runpath, $pattern) = @_ ; + my @files = validglob("$runpath/$pattern.afm") ; + report("locating afm files : using pattern $runpath/$pattern.afm"); + if ($preproc && !$lcdf) + { @files = validglob("$runpath/$pattern.*tf") ; + report("locating otf files : using pattern $runpath/$pattern.*tf"); + unless (@files) + { @files = validglob("$sourcepath/$pattern.ttf") ; + report("locating ttf files : using pattern $sourcepath/$pattern.ttf") } + } + if (@files) # also elsewhere + { report("locating afm files : using pattern $pattern") } + else + { @files = validglob("$runpath/$pattern.ttf") ; + if (@files) + { report("locating afm files : using ttf files") ; + $extension = "ttf" ; + foreach my $file (@files) + { $file =~ s/\.ttf$//io ; + report ("generating afm file : $file.afm") ; + my $command = "ttf2afm \"$file.ttf\" -o \"$file.afm\"" ; + system($command) ; + print "$command\n" if $trace ; + push(@cleanup, "$file.afm") } + @files = validglob("$runpath/$pattern.afm") } + else # try doing the pre-processing earlier + { report("locating afm files : using otf files") ; + $extension = "otf" ; + @files = validglob("$runpath/$pattern.otf") ; + foreach my $file (@files) + { $file =~ s/\.otf$//io ; + if (!$lcdf) + { report ("generating afm file : $file.afm") ; + preprocess_font("$file.otf", "$file.bdf") ; + push(@cleanup,"$file.afm") } + if ($preproc) + { my $command = "cfftot1 --output=$file.pfb $file.otf" ; + print "$command\n" if $trace ; + report("converting : $file.otf to $file.pfb") ; + system($command) ; + push(@cleanup, "$file.pfb") ; + } + } + if ($lcdf) + { @files = validglob("$runpath/$pattern.otf") } + else + { @files = validglob("$runpath/$pattern.afm") } + } + } + return @files } + +if ($pattern eq '') { if ($ARGV[0]) { $pattern = $ARGV[0] } } + +if ($pattern ne '') + { report ("processing files : all in pattern $pattern") ; + @files = globafmfiles($runpath,$pattern) } +elsif ("$extend$narrow$slant$spaced$caps" ne "") + { error ("transformation needs file spec") } +else + { $pattern = "*" ; + report ("processing files : all on afm path") ; + @files = globafmfiles($runpath,$pattern) } + +sub copy_files + { my ($suffix,$sourcepath,$topath) = @_ ; + my @files = validglob("$sourcepath/$pattern.$suffix") ; + return if ($topath eq $sourcepath) ; + report ("copying files : $suffix") ; + foreach my $file (@files) + { my $ok = $file =~ /(.*)\/(.+?)\.(.*)/ ; + my ($path,$name,$suffix) = ($1,$2,$3) ; + UnLink "$topath/$name.$suffix" ; + report ("copying : $name.$suffix") ; + copy ($file,"$topath/$name.$suffix") } } + +if ($install) + { copy_files("afm",$sourcepath,$afmpath) ; +# copy_files("tfm",$sourcepath,$tfmpath) ; # raw supplied names + copy_files("pfb",$outlinepath,$pfbpath) ; + if ($extension eq "ttf") + { make_path("truetype") ; + copy_files("ttf",$sourcepath,$ttfpath) } + if ($extension eq "otf") + { make_path("truetype") ; + copy_files("otf",$sourcepath,$ttfpath) } } + +error ("no afm files found") unless @files ; + +sub open_mapfile + { my $type = shift; + my $mappath = mappath($type); + my $mapdata = ""; + my $mapptr = undef; + my $fullmapfile = $mapfile; + $fullmapfile = "$type-$fullmapfile" unless $type eq "pdftex"; + if ($install) + { copy ("$mappath/$mapfile","$mappath/$bakfile") ; } + if (open ($mapptr,"<$mappath/$mapfile")) + { report ("extending map file : $mappath/$mapfile") ; + while (<$mapptr>) { unless (/^\%/o) { $mapdata .= $_ } } + close ($mapptr) } + else + { report ("no map file at : $mappath/$mapfile") } + #~ unless (open ($mapptr,">$fullmapfile") ) +do_make_path($mappath) ; + unless (open ($mapptr,">$mappath/$fullmapfile") ) + { report "warning : can't open $fullmapfile" } + else + { if ($type eq "pdftex") + { print $mapptr "% This file is generated by the TeXFont Perl script.\n"; + print $mapptr "%\n" ; + print $mapptr "% You need to add the following line to your file:\n" ; + print $mapptr "%\n" ; + print $mapptr "% \\pdfmapfile{+$mapfile}\n" ; + print $mapptr "%\n" ; + print $mapptr "% In ConTeXt you can best use:\n" ; + print $mapptr "%\n" ; + print $mapptr "% \\loadmapfile\[$mapfile\]\n\n" } } + return ($mapptr,$mapdata) ; } + +sub finish_mapfile + { my ($type, $mapptr, $mapdata ) = @_; + my $fullmapfile = $mapfile; + $fullmapfile = "$type-$fullmapfile" unless $type eq "pdftex"; + if (defined $mapptr) + { report ("updating map file : $mapfile (for $type)") ; + while ($mapdata =~ s/\n\n+/\n/mois) {} ; + $mapdata =~ s/^\s*//gmois ; + print $mapptr $mapdata ; + close ($mapptr) ; + if ($install) + { copy ("$fullmapfile", mappath($type) . "/$mapfile") ; } } } + + +my ($PDFTEXMAP,$pdftexmapdata) = open_mapfile("pdftex"); +my ($DVIPSMAP,$dvipsmapdata) = open_mapfile("dvips"); +my ($DVIPDFMMAP,$dvipdfmmapdata) = open_mapfile("dvipdfm"); + +my $tex = 0 ; +my $texdata = "" ; + +if (open (TEX,"<$texfile")) + { while () { unless (/stoptext/o) { $texdata .= $_ } } + close (TEX) } + +$tex = open (TEX,">$texfile") ; + +unless ($tex) { report "warning : can't open $texfile" } + +if ($tex) + { if ($texdata eq "") + { print TEX "% interface=en\n" ; + print TEX "\n" ; + print TEX "\\usemodule[fnt-01]\n" ; + print TEX "\n" ; + print TEX "\\loadmapfile[$mapfile]\n" ; + print TEX "\n" ; + print TEX "\\starttext\n\n" } + else + { print TEX "$texdata" ; + print TEX "\n\%appended section\n\n\\page\n\n" } } + +sub removeligatures + { my $filename = shift ; my $skip = 0 ; + copy ("$filename.vpl","$filename.tmp") ; + if ((open(TMP,"<$filename.tmp"))&&(open(VPL,">$filename.vpl"))) + { report "removing ligatures : $filename" ; + while () + { chomp ; + if ($skip) + { if (/^\s*\)\s*$/o) { $skip = 0 ; print VPL "$_\n" } } + elsif (/\(LIGTABLE/o) + { $skip = 1 ; print VPL "$_\n" } + else + { print VPL "$_\n" } } + close(TMP) ; close(VPL) } + UnLink ("$filename.tmp") } + +my $raw = my $use = my $maplist = my $texlist = my $report = "" ; + +$use = "$encoding$varlabel-" ; $raw = $use . "raw-" ; + +my $encfil = "" ; + +if ($encoding ne "") # evt -progname=context + { $encfil = `kpsewhich -progname=pdftex $encoding$varlabel.enc` ; + chomp $encfil ; if ($encfil eq "") { $encfil = "$encoding$varlabel.enc" } } + +sub build_pdftex_mapline + { my ($option, $usename, $fontname, $rawname, $cleanfont, $encoding, $varlabel, $strange) = @_; + my $cleanname = $fontname; + $cleanname =~ s/\_//gio ; + $option =~ s/^\s+(.*)/$1/o ; + $option =~ s/(.*)\s+$/$1/o ; + $option =~ s/ / /g ; + if ($option ne "") + { $option = "\"$option\" 4" } + else + { $option = "4" } + # adding cleanfont is kind of dangerous + my $thename = ""; + my $str = ""; + my $theencoding = "" ; + if ($strange ne "") + { $thename = $cleanname ; $theencoding = "" ; } + elsif ($lcdf) + { $thename = $usename ; $theencoding = " $encoding$varlabel-$cleanname.enc" } + elsif ($afmpl) + { $thename = $usename ; $theencoding = " $encoding$varlabel.enc" } + elsif ($virtual) + { $thename = $rawname ; $theencoding = " $encoding$varlabel.enc" } + else + { $thename = $usename ; $theencoding = " $encoding$varlabel.enc" } +if ($uselmencodings) { + $theencoding =~ s/^(ec)\.enc/lm\-$1.enc/ ; +} + # quit rest if no type 1 file + my $pfb_sourcepath = $sourcepath ; + $pfb_sourcepath =~ s@/afm/@/type1/@ ; + unless ((-e "$pfbpath/$fontname.$extension")|| + (-e "$pfb_sourcepath/$fontname.$extension")|| + (-e "$sourcepath/$fontname.$extension")|| + (-e "$ttfpath/$fontname.$extension")) + { if ($tex) { $report .= "missing file: \\type \{$fontname.pfb\}\n" } + report ("missing pfb file : $fontname.pfb") } + # now add entry to map + if ($strange eq "") { + if ($extension eq "otf") { + if ($lcdf) { + my $mapline = "" ; + if (open(ALTMAP,"texfont.map")) { + while () { + chomp ; + # atl: we assume this b/c we always force otftotfm --no-type1 + if (/<<(.*)\.otf$/oi) { + $mapline = $_ ; last ; + } + } + close(ALTMAP) ; + } else { + report("no mapfile from otftotfm : texfont.map") ; + } + if ($preproc) { + $mapline =~ s/<\[/) + { if (/^\/([^ ]+)\s*\[/) + { $encname = $1; + last; } } + close ENC; } } + if ($strange ne "") + { $thename = $cleanname ; + $optionencoding = "\"$option\"" if length($option)>1; } + elsif ($lcdf) + { $thename = $usename ; + $optionencoding = "\"$option $encname ReEncodeFont\" <$encoding$varlabel-$cleanname.enc" } + elsif ($afmpl) + { $thename = $usename ; + $optionencoding = "\"$option $encname ReEncodeFont\" <$encoding$varlabel.enc" } + elsif ($virtual) + { $thename = $rawname ; + $optionencoding = "\"$option $encname ReEncodeFont\" <$encoding$varlabel.enc" } + else + { $thename = $usename ; + $optionencoding = "\"$option $encname ReEncodeFont\" <$encoding$varlabel.enc" } +if ($uselmencodings) { + $theencoding =~ s/^(ec)\.enc/lm\-$1.enc/ ; +} + # quit rest if no type 1 file + my $pfb_sourcepath = $sourcepath ; + $pfb_sourcepath =~ s@/afm/@/type1/@ ; + unless ((-e "$pfbpath/$fontname.$extension")|| + (-e "$pfb_sourcepath/$fontname.$extension")|| + (-e "$sourcepath/$fontname.$extension")|| + (-e "$ttfpath/$fontname.$extension")) + { if ($tex) { $report .= "missing file: \\type \{$fontname.pfb\}\n" } + report ("missing pfb file : $fontname.pfb") } + # now add entry to map + if ($strange eq "") { + if ($extension eq "otf") { + if ($lcdf) { + my $mapline = "" ; + if (open(ALTMAP,"texfont.map")) { + while () { + chomp ; + # atl: we assume this b/c we always force otftotfm --no-type1 + if (/<<(.*)\.otf$/oi) { + $mapline = $_ ; last ; + } + } + close(ALTMAP) ; + } else { + report("no mapfile from otftotfm : texfont.map") ; + } + if ($preproc) { + $mapline =~ s/<\[/ $strange -> tfm") } + elsif ($strange ne "") + { report ("font identifier : $cleanfont$namesuffix -> $strange -> skipping") } + elsif ($afmpl) + { report ("font identifier : $cleanfont$namesuffix -> text -> tfm") } + elsif ($virtual) + { report ("font identifier : $cleanfont$namesuffix -> text -> tfm + vf") } + else + { report ("font identifier : $cleanfont$namesuffix -> text -> tfm") } + # don't handle strange fonts + if ($strange eq "") + { # atl: support for lcdf otftotfm + if ($lcdf && $extension eq "otf") + { # no vf, bypass afm, use otftotfm to get encoding and tfm + my $varstr = my $encout = my $tfmout = "" ; + report "processing files : otf -> tfm + enc" ; + if ($encoding ne "") + { $encfil = `kpsewhich -progname=pdftex $encoding.enc` ; + chomp $encfil ; if ($encfil eq "") { $encfil = "$encoding.enc" } + $encstr = " -e $encfil " } + if ($variant ne "") + { ( $varstr = $variant ) =~ s/,/ -f /goi ; + $varstr = " -f $varstr" } + $encout = "$encpath/$use$cleanfont.enc" ; + if (-e $encout) + { report ("renaming : $encout -> $use$cleanfont.bak") ; + UnLink "$encpath/$use$cleanfont.bak" ; + rename $encout, "$encpath/$use$cleanfont.bak" } + UnLink "texfont.map" ; + $tfmout = "$use$cleanfont$fontsuffix" ; + my $otfcommand = "otftotfm -a $varstr $encstr $passon $shape --name=\"$tfmout\" --encoding-dir=\"$encpath/\" --tfm-dir=\"$tfmpath/\" --vf-dir=\"$vfpath/\" --no-type1 --map-file=./texfont.map \"$file\"" ; + print "$otfcommand\n" if $trace ; + system("$otfcommand") ; + $encfil = $encout } + else + { # generate tfm and vpl, $file is on afm path + my $font = '' ; + if ($afmpl) + { report " generating pl : $cleanname$fontsuffix (from $cleanname)" ; + $encstr = " -p $encfil" ; + if ($uselmencodings) { + $encstr =~ s/(ec)\.enc$/lm\-$1\.enc/ ; + } + my $command = "afm2pl -f afm2tfm $shape $passon $encstr $file $cleanname$fontsuffix.vpl" ; + print "$command\n" if $trace ; + my $ok = `$command` ; + if (open (TMP,"$cleanname$fontsuffix.map")) + { $font = ; + close(TMP) ; + UnLink "$cleanname$fontsuffix.map" } } + else + { report "generating raw tfm/vpl : $raw$cleanname$fontsuffix (from $cleanname)" ; + my $command = "afm2tfm $file $shape $passon $encstr $vfstr $raw$cleanname$fontsuffix" ; + print "$command\n" if $trace ; + $font = `$command` } + # generate vf file if needed + chomp $font ; + if ($font =~ /.*?([\d\.]+)\s*ExtendFont/io) { $extend = $1 } + if ($font =~ /.*?([\d\.]+)\s*SlantFont/io) { $slant = $1 } + if ($extend ne "") { $option .= " $extend ExtendFont " } + if ($slant ne "") { $option .= " $slant SlantFont " } + if ($afmpl) + { if ($noligs||$nofligs) { removeligatures("$cleanname$fontsuffix") } + report "generating new tfm : $use$cleanname$fontsuffix" ; + my $command = "pltotf $cleanname$fontsuffix.vpl $use$cleanname$fontsuffix.tfm" ; + print "$command\n" if $trace ; + my $ok = `$command` } + elsif ($virtual) + { if ($noligs||$nofligs) { removeligatures("$use$cleanname$fontsuffix") } + report "generating new vf : $use$cleanname$fontsuffix (from $use$cleanname)" ; + my $command = "vptovf $use$cleanname$fontsuffix.vpl $use$cleanname$fontsuffix.vf $use$cleanname$fontsuffix.tfm" ; + print "$command\n" if $trace ; + my $ok = `$command` } + else + { if ($noligs||$nofligs) { removeligatures("$raw$cleanname$fontsuffix") } + report "generating new tfm : $use$cleanname$fontsuffix (from $raw$cleanname)" ; + my $command = "pltotf $raw$cleanname$fontsuffix.vpl $use$cleanname$fontsuffix.tfm" ; + print "$command\n" if $trace ; + my $ok = `$command` } } } + elsif (-e "$sourcepath/$cleanname.tfm" ) + { report "using existing tfm : $cleanname.tfm" } + elsif (($strange eq "expert")&&($expert)) + { report "creating tfm file : $cleanname.tfm" ; + my $command = "afm2tfm $file $cleanname.tfm" ; + print "$command\n" if $trace ; + my $font = `$command` } + else + { report "use supplied tfm : $cleanname" } + # report results + if (!$lcdf) + { ($rawfont,$cleanfont,$restfont) = split(/\s/,$font) } + $cleanfont =~ s/\_/\-/goi ; + $cleanfont =~ s/\-+$//goi ; + # copy files + my $usename = "$use$cleanname$fontsuffix" ; + my $rawname = "$raw$cleanname$fontsuffix" ; + + if ($lcdf eq "") + { if ($strange ne "") + { UnLink ("$vfpath/$cleanname.vf", "$tfmpath/$cleanname.tfm") ; + copy ("$cleanname.tfm","$tfmpath/$cleanname.tfm") ; + copy ("$usename.tfm","$tfmpath/$usename.tfm") ; + # or when available, use vendor one : + copy ("$sourcepath/$cleanname.tfm","$tfmpath/$cleanname.tfm") } + elsif ($virtual) + { UnLink ("$vfpath/$rawname.vf", "$vfpath/$usename.vf") ; + UnLink ("$tfmpath/$rawname.tfm", "$tfmpath/$usename.tfm") ; + copy ("$usename.vf" ,"$vfpath/$usename.vf") ; + copy ("$rawname.tfm","$tfmpath/$rawname.tfm") ; + copy ("$usename.tfm","$tfmpath/$usename.tfm") } + elsif ($afmpl) + { UnLink ("$vfpath/$rawname.vf", "$vfpath/$usename.vf", "$vfpath/$cleanname.vf") ; + UnLink ("$tfmpath/$rawname.tfm", "$tfmpath/$usename.tfm", "$tfmpath/$cleanname.tfm") ; + copy ("$usename.tfm","$tfmpath/$usename.tfm") } + else + { UnLink ("$vfpath/$usename.vf", "$tfmpath/$usename.tfm") ; + # slow but prevents conflicting vf's + my $rubish = `kpsewhich $usename.vf` ; chomp $rubish ; + if ($rubish ne "") { UnLink $rubish } + # + copy ("$usename.tfm","$tfmpath/$usename.tfm") } } + # cleanup + foreach my $suf ("tfm", "vf", "vpl") + { UnLink ("$rawname.$suf", "$usename.$suf") ; + UnLink ("$cleanname.$suf", "$fontname.$suf") ; + UnLink ("$cleanname$fontsuffix.$suf", "$fontname$fontsuffix.$suf") } + # add line to map files + my $str = my $thename = ""; + ($str, $thename) = build_pdftex_mapline($option, $usename, $fontname, $rawname, $cleanfont, $encoding, $varlabel, $strange); + # check for redundant entries + if (defined $PDFTEXMAP) { + $pdftexmapdata =~ s/^$thename\s.*?$//gmis ; + if ($afmpl) { + if ($pdftexmapdata =~ s/^$rawname\s.*?$//gmis) { + report ("removing raw file : $rawname") ; + } + } + $maplist .= $str ; + $pdftexmapdata .= $str ; + } + ($str, $thename) = build_dvips_mapline($option, $usename, $fontname, $rawname, $cleanfont, $encoding, $varlabel, $strange); + # check for redundant entries + if (defined $DVIPSMAP) { + $dvipsmapdata =~ s/^$thename\s.*?$//gmis ; + if ($afmpl) { + if ($dvipsmapdata =~ s/^$rawname\s.*?$//gmis) { + report ("removing raw file : $rawname") ; + } + } + $dvipsmapdata .= $str ; + } + ($str, $thename) = build_dvipdfm_mapline($option, $usename, $fontname, $rawname, $cleanfont, $encoding, $varlabel, $strange); + # check for redundant entries + if (defined $DVIPDFMMAP) { + $dvipdfmmapdata =~ s/^$thename\s.*?$//gmis ; + if ($afmpl) { + if ($dvipdfmmapdata =~ s/^$rawname\s.*?$//gmis) { + report ("removing raw file : $rawname") ; + } + } + $dvipdfmmapdata .= $str ; + } + + # write lines to tex file + if (($strange eq "expert")&&($expert)) { + $fntlist .= "\\definefontsynonym[$cleanfont$namesuffix][$cleanname] \% expert\n" ; + } elsif ($strange ne "") { + $fntlist .= "\%definefontsynonym[$cleanfont$namesuffix][$cleanname]\n" ; + } else { + $fntlist .= "\\definefontsynonym[$cleanfont$namesuffix][$usename][encoding=$encoding]\n" ; + } + next unless $tex ; + if (($strange eq "expert")&&($expert)) { + $texlist .= "\\ShowFont[$cleanfont$namesuffix][$cleanname]\n" ; + } elsif ($strange ne "") { + $texlist .= "\%ShowFont[$cleanfont$namesuffix][$cleanname]\n" ; + } else { + $texlist .= "\\ShowFont[$cleanfont$namesuffix][$usename][$encoding]\n" + } +} + +finish_mapfile("pdftex", $PDFTEXMAP, $pdftexmapdata); +finish_mapfile("dvipdfm", $DVIPDFMMAP, $dvipdfmmapdata); +finish_mapfile("dvips", $DVIPSMAP, $dvipsmapdata); + +if ($tex) + { my $mappath = mappath("pdftex"); + $mappath =~ s/\\/\//go ; + $savedoptions =~ s/^\s+//gmois ; $savedoptions =~ s/\s+$//gmois ; + $fntlist =~ s/^\s+//gmois ; $fntlist =~ s/\s+$//gmois ; + $maplist =~ s/^\s+//gmois ; $maplist =~ s/\s+$//gmois ; + print TEX "$texlist" ; + print TEX "\n" ; + print TEX "\\setupheadertexts[\\tttf example definitions]\n" ; + print TEX "\n" ; + print TEX "\\starttyping\n" ; + print TEX "texfont $savedoptions\n" ; + print TEX "\\stoptyping\n" ; + print TEX "\n" ; + print TEX "\\starttyping\n" ; + print TEX "$mappath/$mapfile\n" ; + print TEX "\\stoptyping\n" ; + print TEX "\n" ; + print TEX "\\starttyping\n" ; + print TEX "$fntlist\n" ; + print TEX "\\stoptyping\n" ; + print TEX "\n" ; + print TEX "\\page\n" ; + print TEX "\n" ; + print TEX "\\setupheadertexts[\\tttf $mapfile]\n" ; + print TEX "\n" ; + print TEX "\\starttyping\n" ; + print TEX "$maplist\n" ; + print TEX "\\stoptyping\n" ; + print TEX "\n" ; + print TEX "\\stoptext\n" } + +if ($tex) { close (TEX) } + +# atl: global cleanup with generated files (afm & ttf don't mix) + +UnLink(@cleanup) ; + +print "\n" ; report ("generating : ls-r databases") ; + +# Refresh database. + +print "\n" ; system ("mktexlsr $fontroot") ; print "\n" ; + +# Process the test file. + +if ($show) { system ("texexec --once --silent $texfile") } + +@files = validglob("$identifier.* *-$identifier.map") ; + +foreach my $file (@files) + { unless ($file =~ /(tex|pdf|log|mp|tmp)$/io) { UnLink ($file) } } + +exit ; diff --git a/scripts/context/ruby/base/ctx.rb b/scripts/context/ruby/base/ctx.rb new file mode 100644 index 000000000..13b4045af --- /dev/null +++ b/scripts/context/ruby/base/ctx.rb @@ -0,0 +1,462 @@ +# module : base/ctx +# copyright : PRAGMA Advanced Document Engineering +# version : 2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# todo: write systemcall for mpost to file so that it can be run +# faster + +# report ? + +require 'base/system' +require 'base/file' +require 'base/switch' # has needsupdate, bad place + +require 'rexml/document' + +class CtxRunner + + attr_reader :environments, :modules, :filters, :flags, :modes + + @@suffix = 'prep' + + def initialize(jobname=nil,logger=nil) + if @logger = logger then + def report(str='') + @logger.report(str) + end + else + def report(str='') + puts(str) + end + end + @jobname = jobname + @ctxname = nil + @xmldata = nil + @prepfiles = Hash.new + @environments = Array.new + @modules = Array.new + @filters = Array.new + @flags = Array.new + @modes = Array.new + @local = false + @paths = Array.new + end + + def register_path(str) + @paths << str + end + + def manipulate(ctxname=nil,defaultname=nil) + + if ctxname then + @ctxname = ctxname + @jobname = File.suffixed(@ctxname,'tex') unless @jobname + else + @ctxname = File.suffixed(@jobname,'ctx') if @jobname + end + + if not @ctxname then + report('no ctx file specified') + return + end + + if @ctxname !~ /\.[a-z]+$/ then + @ctxname += ".ctx" + end + + # name can be kpse:res-make.ctx + if not FileTest.file?(@ctxname) then + fullname, done = '', false + if @ctxname =~ /^kpse:/ then + begin + if fullname = Kpse.found(@ctxname.sub(/^kpse:/,'')) then + @ctxname, done = fullname, true + end + rescue + # should not happen + end + else + ['..','../..'].each do |path| + begin + fullname = File.join(path,@ctxname) + if FileTest.file?(fullname) then + @ctxname, done = fullname, true + end + rescue + # probably strange join + end + break if done + end + if ! done then + fullname = Kpse.found(@ctxname) + if FileTest.file?(fullname) then + @ctxname, done = fullname, true + end + end + end + if ! done && defaultname && FileTest.file?(defaultname) then + report("using default ctxfile #{defaultname}") + @ctxname, done = defaultname, true + end + if not done then + report('no ctx file found') + return false + end + end + + if FileTest.file?(@ctxname) then + @xmldata = IO.read(@ctxname) + else + report('no ctx file found') + return false + end + + unless @xmldata =~ /^.*<\?xml.*?\?>/moi then + report("ctx file #{@ctxname} is no xml file, skipping") + return + else + report("loading ctx file #{@ctxname}") + end + + if @xmldata then + # out if a sudden rexml started to be picky about namespaces + @xmldata.gsub!(//,"") + end + + begin + @xmldata = REXML::Document.new(@xmldata) + rescue + report('provide valid ctx file (xml error)') + return + else + include(@xmldata,'ctx:include','name') + end + + begin + variables = Hash.new + if @jobname then + variables['job'] = @jobname + end + root = @xmldata.root + REXML::XPath.each(root,"/ctx:job//ctx:flags/ctx:flag") do |flg| + @flags << justtext(flg) + end + REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:environment") do |sty| + @environments << justtext(sty) + end + REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:module") do |mod| + @modules << justtext(mod) + end + REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:filter") do |fil| + @filters << justtext(fil) + end + REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:mode") do |fil| + @modes << justtext(fil) + end + begin + REXML::XPath.each(root,"//ctx:block") do |blk| + if @jobname && blk.attributes['pattern'] then + root.delete(blk) unless @jobname =~ /#{blk.attributes['pattern']}/ + else + root.delete(blk) + end + end + rescue + end + REXML::XPath.each(root,"//ctx:value[@name='job']") do |val| + substititute(val,variables['job']) + end + REXML::XPath.each(root,"/ctx:job//ctx:message") do |mes| + report("preprocessing: #{justtext(mes)}") + end + REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:environment") do |sty| + @environments << justtext(sty) + end + REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:module") do |mod| + @modules << justtext(mod) + end + REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:filter") do |fil| + @filters << justtext(fil) + end + REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:mode") do |fil| + @modes << justtext(fil) + end + REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:flags/ctx:flag") do |flg| + @flags << justtext(flg) + end + commands = Hash.new + REXML::XPath.each(root,"/ctx:job//ctx:preprocess/ctx:processors/ctx:processor") do |pre| + begin + commands[pre.attributes['name']] = pre + rescue + end + end + suffix = @@suffix + begin + suffix = REXML::XPath.match(root,"/ctx:job//ctx:preprocess/@suffix").to_s + rescue + suffix = @@suffix + else + if suffix && suffix.empty? then suffix = @@suffix end + end + if (REXML::XPath.first(root,"/ctx:job//ctx:preprocess/ctx:processors/@local").to_s =~ /(yes|true)/io rescue false) then + @local = true + else + @local = false + end + REXML::XPath.each(root,"/ctx:job//ctx:preprocess/ctx:files") do |files| + REXML::XPath.each(files,"ctx:file") do |pattern| + suffix = @@suffix + begin + suffix = REXML::XPath.match(root,"/ctx:job//ctx:preprocess/@suffix").to_s + rescue + suffix = @@suffix + else + if suffix && suffix.empty? then suffix = @@suffix end + end + preprocessor = pattern.attributes['processor'] + if preprocessor and not preprocessor.empty? then + begin + variables['old'] = @jobname + variables['new'] = "" + REXML::XPath.each(pattern,"ctx:value") do |value| + if name = value.attributes['name'] then + substititute(value,variables[name.to_s]) + end + end + rescue + report('unable to resolve file pattern') + return + end + pattern = justtext(pattern) + oldfiles = Dir.glob(pattern) + pluspath = false + if oldfiles.length == 0 then + report("no files match #{pattern}") + if @paths.length > 0 then + @paths.each do |p| + oldfiles = Dir.glob("#{p}/#{pattern}") + if oldfiles.length > 0 then + pluspath = true + break + end + end + if oldfiles.length == 0 then + report("no files match #{pattern} on path") + end + end + end + oldfiles.each do |oldfile| + newfile = "#{oldfile}.#{suffix}" + newfile = File.basename(newfile) if @local # or pluspath + if File.expand_path(oldfile) != File.expand_path(newfile) && File.needsupdate(oldfile,newfile) then + report("#{oldfile} needs preprocessing") + begin + File.delete(newfile) + rescue + # hope for the best + end + # there can be a sequence of processors + preprocessor.split(',').each do |pp| + if command = commands[pp] then + # a lie: no + command = REXML::Document.new(command.to_s) # don't infect original + # command = command.deep_clone() # don't infect original + command = command.elements["ctx:processor"] + if suf = command.attributes['suffix'] then + newfile = "#{oldfile}.#{suf}" + end + begin + newfile = File.basename(newfile) if @local + rescue + end + REXML::XPath.each(command,"ctx:old") do |value| replace(value,oldfile) end + REXML::XPath.each(command,"ctx:new") do |value| replace(value,newfile) end + report("preprocessing #{oldfile} into #{newfile} using #{pp}") + variables['old'] = oldfile + variables['new'] = newfile + REXML::XPath.each(command,"ctx:value") do |value| + if name = value.attributes['name'] then + substititute(value,variables[name.to_s]) + end + end + command = justtext(command) + report(command) + unless ok = System.run(command) then + report("error in preprocessing file #{oldfile}") + end + begin + oldfile = File.basename(oldfile) if @local + rescue + end + end + end + if FileTest.file?(newfile) then + File.syncmtimes(oldfile,newfile) + else + report("check target location of #{newfile}") + end + else + report("#{oldfile} needs no preprocessing (same file)") + end + @prepfiles[oldfile] = FileTest.file?(newfile) + end + end + end + end + rescue + report("fatal error in preprocessing #{@ctxname}: #{$!}") + end + end + + def savelog(ctlname=nil) + unless ctlname then + if @jobname then + ctlname = File.suffixed(@jobname,'ctl') + elsif @ctxname then + ctlname = File.suffixed(@ctxname,'ctl') + else + return + end + end + if @prepfiles.length > 0 then + if log = File.open(ctlname,'w') then + log << "\n\n" + if @local then + log << "\n" + else + log << "\n" + end + @prepfiles.keys.sort.each do |prep| + # log << "\t#{File.basename(prep)}\n" + log << "\t#{prep}\n" + end + log << "\n" + log.close + end + else + begin + File.delete(ctlname) + rescue + end + end + end + + private + + def include(xmldata,element='ctx:include',attribute='name') + loop do + begin + more = false + REXML::XPath.each(xmldata.root,element) do |e| + begin + name = e.attributes.get_attribute(attribute).to_s + name = e.text.to_s if name.empty? + name.strip! if name + done = false + if name and not name.empty? then + ['.',File.dirname(@ctxname),'..','../..'].each do |path| + begin + fullname = if path == '.' then name else File.join(path,name) end + if FileTest.file?(fullname) then + if f = File.open(fullname,'r') and i = REXML::Document.new(f) then + report("including ctx file #{name}") + REXML::XPath.each(i.root,"*") do |ii| + xmldata.root.insert_before(e,ii) + more = true + end + end + done = true + end + rescue + end + break if done + end + end + report("no valid ctx inclusion file #{name}") unless done + rescue Exception + # skip this file + ensure + xmldata.root.delete(e) + end + end + break unless more + rescue Exception + break # forget about inclusion + end + end + end + + private + + def yes_or_no(b) + if b then 'yes' else 'no' end + end + + private # copied from rlxtools.rb + + def justtext(str) + str = str.to_s + str.gsub!(/<[^>]*?>/o, '') + str.gsub!(/\s+/o, ' ') + str.gsub!(/</o, '<') + str.gsub!(/>/o, '>') + str.gsub!(/&/o, '&') + str.gsub!(/"/o, '"') + str.gsub!(/[\/\\]+/o, '/') + return str.strip + end + + def substititute(value,str) + if str then + begin + if value.attributes.key?('method') then + str = filtered(str.to_s,value.attributes['method'].to_s) + end + if str.empty? && value.attributes.key?('default') then + str = value.attributes['default'].to_s + end + value.insert_after(value,REXML::Text.new(str.to_s)) + rescue Exception + end + end + end + + def replace(value,str) + if str then + begin + value.insert_after(value,REXML::Text.new(str.to_s)) + rescue Exception + end + end + end + + def filtered(str,method) + str = str.to_s # to be sure + case method + when 'name' then # no path, no suffix + case str + when /^.*[\\\/](.+?)\..*?$/o then $1 + when /^.*[\\\/](.+?)$/o then $1 + when /^(.*)\..*?$/o then $1 + else str + end + when 'path' then if str =~ /^(.+)([\\\/])(.*?)$/o then $1 else '' end + when 'suffix' then if str =~ /^.*\.(.*?)$/o then $1 else '' end + when 'nosuffix' then if str =~ /^(.*)\..*?$/o then $1 else str end + when 'nopath' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end + when 'base' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end + when 'full' then str + when 'complete' then str + when 'expand' then File.expand_path(str).gsub(/\\/,"/") + else str + end + end + +end diff --git a/scripts/context/ruby/base/exa.rb b/scripts/context/ruby/base/exa.rb new file mode 100644 index 000000000..7ba990cf9 --- /dev/null +++ b/scripts/context/ruby/base/exa.rb @@ -0,0 +1,407 @@ +# \setuplayout[width=3cm] +# +# tex.setup.setuplayout.width.[integer|real|dimension|string|key] +# tex.[mp]var.whatever.width.[integer|real|dimension|string|key] + +require 'fileutils' +# require 'ftools' +require 'digest/md5' + +# this can become a lua thing + +# no .*? but 0-9a-z\:\. because other too slow (and greedy) + +class Hash + + def subset(pattern) + h = Hash.new + r = /^#{pattern.gsub('.','\.')}/ + self.keys.each do |k| + h[k] = self[k].dup if k =~ r + end + return h + end + +end + +module ExaEncrypt + + def ExaEncrypt.encrypt_base(logger, oldfilename, newfilename) + if FileTest.file?(oldfilename) then + logger.report("checking #{oldfilename}") if logger + if data = IO.read(oldfilename) then + done = false + # cfg file: + # + # banner : exa configuration file + # user : domain, name = password, projectlist + # + if data =~ /^\s*banner\s*\:\s*exa\s*configuration\s*file/ then + data.gsub!(/^(\s*user\s*\:\s*.+?\s*\,\s*.+?\s*\=\s*)(.+?)(\s*\,\s*.+\s*)$/) do + pre, password, post = $1, $2, $3 + unless password =~ /MD5:/i then + done = true + password = "MD5:" + Digest::MD5.hexdigest(password).upcase + end + "#{pre}#{password}#{post}" + end + else + data.gsub!(/]*?)>(.*?)<\/exa:password>/moi) do + attributes, password = $1, $2 + unless password =~ /^([0-9A-F][0-9A-F])+$/ then + done = true + password = Digest::MD5.hexdigest(password).upcase + attributes = " encryption='md5'#{attributes}" + end + "#{password}" + end + end + begin + File.open(newfilename,'w') do |f| + f.puts(data) + end + rescue + logger.report("#{newfilename} cannot be written") if logger + else + logger.report("#{oldfilename} encrypted into #{newfilename}") if done and logger + end + end + end + end + +end + +module ExaModes + + @@modefile = 'examodes.tex' + + @@request = /(.*?<\/exa:request>)/mo + @@redone = /]*?texified=([\'\"])yes\1.*?>/mo + @@reload = /<(exa:variable)([^>]+?label\=)([\"\'])([0-9A-Za-z\-\.\:]+?)(\3[^\/]*?)>(.*?)<(\/exa:variable)>/mo + @@recalc = /<(exa:variable)([^>]+?label\=)([\"\'])([0-9A-Za-z\-\.\:]+?)([\.\:]calcmath)(\3[^\/]*?)>(.*?)<(\/exa:variable)>/mo + @@rename = /<(exa:variable)([^>]+?label\=)([\"\'])([0-9A-Za-z\-\.\:]+?)(\3[^\/]*?)>(.*?)<(\/exa:variable)>/mo + @@refile = /<(exa:filename|exa:filelist)>(.*?)<(\/\1)>/mo + + def ExaModes.cleanup_request(logger,filename='request.exa',modefile=@@modefile) + begin File.delete(filename+'.raw') ; rescue ; end + begin File.delete(modefile) ; rescue ; end + if FileTest.file?(filename) then + data, done = nil, false + begin + data = IO.read(filename) + rescue + data = nil + end + if data =~ @@request and data !~ @@redone then + data.gsub!(@@rename) do + done = true + '<' + $1 + $2 + $3 + $4 + $5 + '>' + + texifiedstr($4,$6) + + '<' + $7 + '>' + end + data.gsub!(@@refile) do + done = true + '<' + $1 + '>' + + cleanpath($2) + + '<' + $3 + '>' + end + data.gsub!(@@recalc) do + done = true + '<' + $1 + $2 + $3 + $4 + ":raw" + $6 + '>' + $7 + '<' + $8 + '>' + + '<' + $1 + $2 + $3 + $4 + $6 + '>' + + calculatortexmath($7,false) + + '<' + $8 + '>' + end + if done then + data.gsub!(@@request) do + $1 + " texified='yes'" + $2 + end + begin File.copy(filename, filename+'.raw') ; rescue ; end + begin + logger.report("rewriting #{filename}") if logger + File.open(filename,'w') do |f| + f.puts(data) + end + rescue + logger.report("#{filename} cannot be rewritten") if logger + end + end + else + logger.report("#{filename} is already ok") if logger + end + @variables = Hash.new + data.scan(@@reload) do + @variables[$4] = $5 + end + vars = @variables.subset('data.tex.var') + mpvars = @variables.subset('data.tex.mpvar') + modes = @variables.subset('data.tex.mode') + setups = @variables.subset('data.tex.setup') + if not (modes.empty? and setups.empty? and vars.empty? and mpvars.empty?) then + begin + File.open(modefile,'w') do |mod| + logger.report("saving modes and setups in #{modefile}") if logger + if not modes.empty? then + for key in modes.keys do + k = key.dup + k.gsub!(/\./,'-') + mod.puts("\\enablemode[#{k}-#{modes[key]}]\n") + if modes[key] =~ /(on|yes|start)/o then # ! ! ! ! ! + mod.puts("\\enablemode[#{k}]\n") + end + end + mod.puts("\n\\readfile{cont-mod}{}{}\n") + end + if not setups.empty? then + for key in setups.keys + if key =~ /^(.+?)\.(.+?)\.(.+?)$/o then + command, key, type, value = $1, $2, $3, setups[key] + value = cleanedup(key,type,value) + mod.puts("\\#{$1}[#{key}=#{value}]\n") + elsif key =~ /^(.+?)\.(.+?)$/o then + command, type, value = $1, $2, setups[key] + mod.puts("\\#{$1}[#{value}]\n") + end + end + end + savevaroptions(vars, 'setvariables', mod) + savevaroptions(mpvars,'setMPvariables',mod) + end + rescue + logger.report("#{modefile} cannot be saved") if logger + end + else + logger.report("#{modefile} is not created") if logger + end + end + end + + private + + def ExaModes.autoparenthesis(str) + if str =~ /[\+\-]/o then '[1]' + str + '[1]' else str end + end + + def ExaModes.cleanedup(key,type,value) + if type == 'dimension' then + unless value =~ /(cm|mm|in|bp|sp|pt|dd|em|ex)/o + value + 'pt' + else + value + end + elsif type == 'calcmath' then + '{' + calculatortexmath(value,true) + '}' + elsif type =~ /^filename|filelist$/ or key =~ /^filename|filelist$/ then + cleanpath(value) + else + value + end + end + + def ExaModes.cleanpath(str) + (str ||'').gsub(/\\/o,'/') + end + + def ExaModes.texifiedstr(key,val) + case key + when 'filename' then + cleanpath(val) + when 'filelist' then + cleanpath(val) + else + val + end + end + + def ExaModes.savevaroptions(vars,setvariables,mod) + if not vars.empty? then + for key in vars.keys do + # var.whatever.width.dimension.value + if key =~ /^(.+?)\.(.+?)\.(.+?)$/o then + tag, key, type, value = $1, $2, $3, vars[key] + value = cleanedup(key,type,value) + mod.puts("\\#{setvariables}[#{tag}][#{key}=#{value}]\n") + elsif key =~ /^(.+?)\.(.+?)$/o then + tag, key, value = $1, $2, vars[key] + mod.puts("\\#{setvariables}[#{tag}][#{key}=#{value}]\n") + end + end + end + end + + def ExaModes.calculatortexmath(str,tx=true) + if tx then + bdisp, edisp = "\\displaymath\{", "\}" + binln, einln = "\\inlinemath\{" , "\}" + egraf = "\\endgraf" + else + bdisp, edisp = "", "" + binln, einln = "" , "" + egraf = "

" + end + str.gsub!(/\n\s*\n+/moi, "\\ENDGRAF ") + str.gsub!(/(\[\[)\s*(.*?)\s*(\]\])/mos) do + $1 + docalculatortexmath($2) + $3 + end + str.gsub!(/(\\ENDGRAF)+\s*(\[\[)\s*(.*?)\s*(\]\])/moi) do + $1 + bdisp + $3 + edisp + end + str.gsub!(/(\[\[)\s*(.*?)\s*(\]\])/o) do + binln + $2 + einln + end + str.gsub!(/\\ENDGRAF/mos, egraf) + str + end + + def ExaModes.docalculatortexmath(str) + str.gsub!(/\n/o) { ' ' } + str.gsub!(/\s+/o) { ' ' } + str.gsub!(/>/o) { '>' } + str.gsub!(/</o) { '<' } + str.gsub!(/&.*?;/o) { } + level = 0 + str.gsub!(/([\(\)])/o) do |chr| + if chr == '(' then + level = level + 1 + chr = '[' + level.to_s + ']' + elsif chr == ')' then + chr = '[' + level.to_s + ']' + level = level - 1 + end + chr + end + # ...E... + loop do + break unless str.gsub!(/([\d\.]+)E([\-\+]{0,1}[\d\.]+)/o) do + "\{\\SCINOT\{#{$1}\}\{#{$2}\}\}" + end + end + # ^-.. + loop do + break unless str.gsub!(/\^([\-\+]*\d+)/o) do + "\^\{#{$1}\}" + end + end + # ^(...) + loop do + break unless str.gsub!(/\^(\[\d+\])(.*?)\1/o) do + "\^\{#{$2}\}" + end + end + # 1/x^2 + loop do + break unless str.gsub!(/([\d\w\.]+)\/([\d\w\.]+)\^([\d\w\.]+)/o) do + "@\{#{$1}\}\{#{$2}\^\{#{$3}\}\}" + end + end + # int(a,b,c) + loop do + break unless str.gsub!(/(int|sum|prod)(\[\d+\])(.*?),(.*?),(.*?)\2/o) do + "\\#{$1.upcase}\^\{#{$4}\}\_\{#{$5}\}\{#{autoparenthesis($3)}\}" + end + end + # int(a,b) + loop do + break unless str.gsub!(/(int|sum|prod)(\[\d+\])(.*?),(.*?)\2/o) do + "\\#{$1.upcase}\_\{#{$4}\}\{#{autoparenthesis($3)}\}" + end + end + # int(a) + loop do + break unless str.gsub!(/(int|sum|prod)(\[\d+\])(.*?)\2/o) do + "\\#{$1.upcase}\{#{autoparenthesis($3)}\}" + end + end + # sin(x) => {\sin(x)} + loop do + break unless str.gsub!(/(median|min|max|round|sqrt|sin|cos|tan|sinh|cosh|tanh|ln|log)\s*(\[\d+\])(.*?)\2/o) do + "\{\\#{$1.upcase}\{#{$2}#{$3}#{$2}\}\}" + end + end + # mean + str.gsub!(/(mean)(\[\d+\])(.*?)\2/o) do + "\{\\OVERLINE\{#{$3}\}\}" + end + # sin x => {\sin(x)} + # ... + # (1+x)/(1+x) => \frac{1+x}{1+x} + loop do + break unless str.gsub!(/(\[\d+\])(.*?)\1\/(\[\d+\])(.*?)\3/o) do + "@\{#{$2}\}\{#{$4}\}" + end + end + # (1+x)/x => \frac{1+x}{x} + loop do + break unless str.gsub!(/(\[\d+\])(.*?)\1\/([a-zA-Z0-9]+)/o) do + "@\{#{$2}\}\{#{$3}\}" + end + end + # 1/(1+x) => \frac{1}{1+x} + loop do + break unless str.gsub!(/([a-zA-Z0-9]+)\/(\[\d+\])(.*?)\2/o) do + "@\{#{$1}\}\{#{$3}\}" + end + end + # 1/x => \frac{1}{x} + loop do + break unless str.gsub!(/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)/o) do + "@\{#{$1}\}\{#{$2}\}" + end + end + # + str.gsub!(/\@/o) do + "\\FRAC " + end + str.gsub!(/\*/o) do + " " + end + str.gsub!(/\<\=/o) do + "\\LE " + end + str.gsub!(/\>\=/o) do + "\\GE " + end + str.gsub!(/\=/o) do + "\\EQ " + end + str.gsub!(/\/) do + "\\GT " + end + str.gsub!(/(D)(\[\d+\])(.*?)\2/o) do + "\{\\FRAC\{\\MBOX{d}\}\{\\MBOX{d}x\}\{#{$2}#{$3}#{$2}\}\}" + end + str.gsub!(/(exp)(\[\d+\])(.*?)\2/o) do + "\{e^\{#{$3}\}\}" + end + str.gsub!(/(abs)(\[\d+\])(.*?)\2/o) do + "\{\\left\|#{$3}\\right\|\}" + end + str.gsub!(/D([x|y])/o) do + "\\FRAC\{\{\\rm d\}#{$1}\}\{\{\\rm d\}x\}" + end + str.gsub!(/D([f|g])(\[\d+\])(.*?)\2/o) do + "\{\\rm #{$1}\}'#{$2}#{$3}#{$2}" + end + str.gsub!(/([f|g])(\[\d+\])(.*?)\2/o) do + "\{\\rm #{$1}\}#{$2}#{$3}#{$2}" + end + str.gsub!(/(pi|inf)/io) do + "\\#{$1} " + end + loop do + break unless str.gsub!(/(\[\d+?\])(.*?)\1/o) do + "\\left(#{$2}\\right)" + end + end + str.gsub!(/\\([A-Z]+?)([\s\{\^\_\\])/io) do + "\\#{$1.downcase}#{$2}" + end + str + end + +end + +# ExaModes.cleanup_request() diff --git a/scripts/context/ruby/base/file.rb b/scripts/context/ruby/base/file.rb new file mode 100644 index 000000000..1aeac5fd6 --- /dev/null +++ b/scripts/context/ruby/base/file.rb @@ -0,0 +1,150 @@ +# module : base/file +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +require 'fileutils' +# require 'ftools' + +class File + + def File.suffixed(name,sufa,sufb=nil) + if sufb then + if sufa.empty? then + unsuffixed(name) + ".#{sufb}" + else + unsuffixed(name) + "-#{sufa}.#{sufb}" + end + else + unsuffixed(name) + ".#{sufa}" + end + end + + def File.unsuffixed(name) + name.sub(/\.[^\.]*?$/o, '') + end + + def File.suffix(name,default='') + if name =~ /\.([^\.]*?)$/o then + $1 + else + default + end + end + + def File.splitname(name,suffix='') + if name =~ /^(.*)\.([^\.]*?)$/o then + [$1, $2] + else + [name, suffix] + end + end + +end + +class File + + def File.silentopen(name,method='r') + begin + f = File.open(name,method) + rescue + return nil + else + return f + end + end + + def File.silentread(name) + begin + data = IO.read(name) + rescue + return nil + else + return data + end + end + + def File.atleast?(name,n=0) + begin + size = FileTest.size(name) + rescue + return false + else + return size > n + end + end + + def File.appended(name,str='') + if FileTest.file?(name) then + begin + if f = File.open(name,'a') then + f << str + f.close + return true + end + rescue + end + end + return false + end + + def File.written(name,str='') + begin + if f = File.open(name,'w') then + f << str + f.close + return true + end + rescue + end + return false + end + + def File.silentdelete(filename) + File.delete(filename) rescue false + end + + def File.silentcopy(oldname,newname) + return if File.expand_path(oldname) == File.expand_path(newname) + FileUtils.makedirs(File.dirname(newname)) rescue false + File.copy(oldname,newname) rescue false + end + + def File.silentrename(oldname,newname) + # in case of troubles, we just copy the file; we + # maybe working over multiple file systems or + # apps may have mildly locked files (like gs does) + return if File.expand_path(oldname) == File.expand_path(newname) + File.delete(newname) rescue false + begin + File.rename(oldname,newname) + rescue + FileUtils.makedirs(File.dirname(newname)) rescue false + File.copy(oldname,newname) rescue false + end + end + +end + +class File + + # handles "c:\tmp\test.tex" as well as "/${TEMP}/test.tex") + + def File.unixfied(filename) + begin + str = filename.gsub(/\$\{*([a-z0-9\_]+)\}*/oi) do + if ENV.key?($1) then ENV[$1] else $1 end + end + str.gsub(/[\/\\]+/o, '/') + rescue + filename + end + end + +end + diff --git a/scripts/context/ruby/base/kpse.rb b/scripts/context/ruby/base/kpse.rb new file mode 100644 index 000000000..0f9868784 --- /dev/null +++ b/scripts/context/ruby/base/kpse.rb @@ -0,0 +1,389 @@ +# module : base/kpse +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# rename this one to environment +# +# todo: web2c vs miktex module and include in kpse + +require 'rbconfig' +require 'fileutils' + +# beware $engine is lowercase in kpse +# +# miktex has mem|fmt|base paths + +class String + + def split_path + if self =~ /\;/o || self =~ /^[a-z]\:/io then + self.split(";") + else + self.split(":") + end + end + + def sane_path + self.gsub(/\\/,'/') + end + +end + +class Array + + def join_path + self.join(File::PATH_SEPARATOR) + end + + def non_empty + self.delete_if do |i| + (i == nil || i.empty?) rescue false + end + end + +end + +module Kpse + + @@located = Hash.new + @@paths = Hash.new + @@scripts = Hash.new + @@formats = ['tex','texmfscripts','other text files'] + @@progname = 'context' + @@ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'') + @@problems = false + @@tracing = false + @@distribution = 'web2c' + @@crossover = true + @@mswindows = Config::CONFIG['host_os'] =~ /mswin/ + + # @@distribution = 'miktex' if ENV['PATH'] =~ /miktex[\\\/]bin/o + + # if ENV['PATH'] =~ /(.*?)miktex[\\\/]bin/i then + # @@distribution = 'miktex' unless $1 =~ /(texmf\-mswin[\/\\]bin|bin[\/\\]win32)/i + # end + + if @@mswindows && (ENV['PATH'] =~ /(.*?)miktex[\\\/]bin/i) then + @@distribution = 'miktex' unless $1 =~ /(texmf\-mswin[\/\\]bin|bin[\/\\]win32)/i + end + + @@re_true = /yes|on|true|1/i + + if (ENV['KPSEFAST'] =~ @@re_true) || (ENV['CTXMINIMAL'] =~ @@re_true) then + @@usekpserunner = true + require 'base/kpsefast' + require 'base/kpserunner' + else + @@usekpserunner = false + end + + if @@crossover then + ENV.keys.each do |k| + case k + when /\_CTX\_KPSE\_V\_(.*?)\_/io then @@located[$1] = ENV[k].dup + when /\_CTX\_KPSE\_P\_(.*?)\_/io then @@paths [$1] = ENV[k].dup.split(';') + when /\_CTX\_KPSE\_S\_(.*?)\_/io then @@scripts[$1] = ENV[k].dup + end + end + end + + def Kpse.distribution + @@distribution + end + + def Kpse.miktex? + @@distribution == 'miktex' + end + + def Kpse.web2c? + @@distribution == 'web2c' + end + + def Kpse.inspect + @@located.keys.sort.each do |k| puts("located : #{k} -> #{@@located[k]}\n") end + @@paths .keys.sort.each do |k| puts("paths : #{k} -> #{@@paths [k]}\n") end + @@scripts.keys.sort.each do |k| puts("scripts : #{k} -> #{@@scripts[k]}\n") end + end + + def Kpse.used_path(varname) + begin + if @@mswindows then + path = run("--expand-path=\$#{varname}") rescue '' + else + path = run("--expand-path='$#{varname}'") rescue '' + end + rescue + path = '' + end + return path.sane_path + end + + def Kpse.found(filename, progname=nil, format=nil) + begin + tag = Kpse.key(filename) # all + if @@located.key?(tag) then + return @@located[tag].sane_path + elsif FileTest.file?(filename) then + setvariable(tag,filename) + return filename + elsif FileTest.file?(File.join(@@ownpath,filename)) then + setvariable(tag,File.join(@@ownpath,filename)) + return @@located[tag].sane_path + else + [progname,@@progname].flatten.compact.uniq.each do |prg| + [format,@@formats].flatten.compact.uniq.each do |fmt| + begin + tag = Kpse.key(filename,prg,fmt) + if @@located.key?(tag) then + return @@located[tag].sane_path + elsif p = Kpse.kpsewhich(filename,prg,fmt) then + setvariable(tag,p.chomp) + return @@located[tag].sane_path + end + rescue + end + end + end + setvariable(tag,filename) + return filename.sane_path + end + rescue + filename.sane_path + end + end + + def Kpse.kpsewhich(filename,progname,format) + p = if progname && ! progname.empty? then "-progname=#{progname}" else '' end + f = if format && ! format.empty? then "-format=\"#{format}\"" else '' end + Kpse.run("#{p} #{f} #{filename}") + end + + def Kpse.which + Kpse.kpsewhich + end + + def Kpse.run(arguments) + puts arguments if @@tracing + begin + if @@problems then + results = '' + elsif @@usekpserunner then + results = KpseRunner.kpsewhich(arguments).chomp + else + results = `kpsewhich #{arguments}`.chomp + end + rescue + puts "unable to run kpsewhich" if @@tracing + @@problems, results = true, '' + end + puts results if @@tracing + return results + end + + + def Kpse.formatpaths + # maybe we should check for writeability + unless @@paths.key?('formatpaths') then + begin + setpath('formatpaths',run("--show-path=fmt").sane_path.split_path) + rescue + setpath('formatpaths',[]) + end + end + return @@paths['formatpaths'] + end + + def Kpse.key(filename='',progname='all',format='all') + [progname,format,filename].join('-') + end + + def Kpse.formatpath(engine='pdftex',enginepath=true) + + # because engine support in distributions is not always + # as we expect, we need to check for it; + + # todo: miktex + + if miktex? then + return '.' + else + unless @@paths.key?(engine) then + # savedengine = ENV['engine'] + if ENV['TEXFORMATS'] && ! ENV['TEXFORMATS'].empty? then + # make sure that we have a lowercase entry + ENV['TEXFORMATS'] = ENV['TEXFORMATS'].sub(/\$engine/io,"\$engine") + # well, we will append anyway, so we could also strip it + # ENV['TEXFORMATS'] = ENV['TEXFORMATS'].sub(/\$engine/io,"") + end + # use modern method + if enginepath then + formatpath = run("--engine=#{engine} --show-path=fmt") + else + # ENV['engine'] = engine if engine + formatpath = run("--show-path=fmt") + end + # use ancient method + if formatpath.empty? then + if enginepath then + if @@mswindows then + formatpath = run("--engine=#{engine} --expand-path=\$TEXFORMATS") + else + formatpath = run("--engine=#{engine} --expand-path=\\\$TEXFORMATS") + end + end + # either no enginepath or failed run + if formatpath.empty? then + if @@mswindows then + formatpath = run("--expand-path=\$TEXFORMATS") + else + formatpath = run("--expand-path=\\\$TEXFORMATS") + end + end + end + # locate writable path + if ! formatpath.empty? then + formatpaths, done = formatpath.split_path, false + formatpaths.collect! do |fp| + fp.gsub!(/\\/o,'/') + fp.gsub!(/\/\/$/o,'/') + # remove funny patterns + fp.sub!(/^!!/o,'') + fp.sub!(/\/+$/o,'') + fp.sub!(/(unsetengine|unset)/o,if enginepath then engine else '' end) + fp + end + formatpaths.delete_if do |fp| + fp.empty? || fp == '.' + end + # the engine path may not yet be present, find first writable + formatpaths.each do |fp| + # strip (possible engine) and test for writeability + fpp = fp.sub(/#{engine}\/*$/o,'') + if FileTest.directory?(fpp) && FileTest.writable?(fpp) then + # use this path + formatpath, done = fp.dup, true + break + end + end + unless done then + formatpaths.each do |fp| + fpp = fp.sub(/#{engine}\/*$/o,'') + FileUtils.makedirs(fpp) rescue false # maybe we don't have an path yet + if FileTest.directory?(fpp) && FileTest.writable?(fpp) then + # use this path + formatpath, done = fp.dup, true + break + end + end + end + unless done then + formatpath = '.' + end + end + # needed ! + FileUtils.makedirs(formatpath) rescue false + # fall back to current path + formatpath = '.' if formatpath.empty? || ! FileTest.writable?(formatpath) + # append engine but prevent duplicates + formatpath = File.join(formatpath.sub(/\/*#{engine}\/*$/,''), engine) if enginepath + FileUtils.makedirs(formatpath) rescue false + setpath(engine,formatpath) + # ENV['engine'] = savedengine + end + return @@paths[engine].first + end + end + + def Kpse.update + system('initexmf -u') if Kpse.miktex? + system('mktexlsr') + end + + # engine support is either broken of not implemented in some + # distributions, so we need to take care of it ourselves (without + # delays due to kpse calls); there can be many paths in the string + # + # in a year or so, i will drop this check + + def Kpse.fixtexmfvars(engine=nil) + ENV['ENGINE'] = engine if engine + texformats = if ENV['TEXFORMATS'] then ENV['TEXFORMATS'].dup else '' end + if texformats.empty? then + if engine then + if @@mswindows then + texformats = `kpsewhich --engine=#{engine} --expand-var=\$TEXFORMATS`.chomp + else + texformats = `kpsewhich --engine=#{engine} --expand-var=\\\$TEXFORMATS`.chomp + end + else + if @@mswindows then + texformats = `kpsewhich --expand-var=\$TEXFORMATS`.chomp + else + texformats = `kpsewhich --expand-var=\\\$TEXFORMATS`.chomp + end + end + end + if engine then + texformats.sub!(/unsetengine/,engine) + else + texformats.sub!(/unsetengine/,"\$engine") + end + if engine && (texformats =~ /web2c[\/\\].*#{engine}/o) then + # ok, engine is seen + return false + elsif texformats =~ /web2c[\/\\].*\$engine/io then + # shouldn't happen + return false + else + ENV['TEXFORMATS'] = texformats.gsub(/(web2c\/\{)(,\})/o) do + "#{$1}\$engine#{$2}" + end + if texformats !~ /web2c[\/\\].*\$engine/io then + ENV['TEXFORMATS'] = texformats.gsub(/web2c\/*/, "web2c/{\$engine,}") + end + return true + end + end + + def Kpse.runscript(name,filename=[],options=[]) + setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name) + cmd = "#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}" + system(cmd) + end + + def Kpse.pipescript(name,filename=[],options=[]) + setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name) + cmd = "#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}" + `#{cmd}` + end + + def Kpse.searchmethod + if @@usekpserunner then 'kpsefast' else 'kpsewhich' end + end + + private + + def Kpse.setvariable(key,value) + @@located[key] = value + ENV["_CTX_K_V_#{key}_"] = @@located[key] if @@crossover + end + + def Kpse.setscript(key,value) + @@scripts[key] = value + ENV["_CTX_K_S_#{key}_"] = @@scripts[key] if @@crossover + end + + def Kpse.setpath(key,value) + @@paths[key] = [value].flatten.uniq.collect do |p| + p.sub(/^!!/,'').sub(/\/*$/,'') + end + ENV["_CTX_K_P_#{key}_"] = @@paths[key].join(';') if @@crossover + end + +end diff --git a/scripts/context/ruby/base/kpse/drb.rb b/scripts/context/ruby/base/kpse/drb.rb new file mode 100644 index 000000000..db1ce0eec --- /dev/null +++ b/scripts/context/ruby/base/kpse/drb.rb @@ -0,0 +1,57 @@ +require 'drb' +require 'base/kpse/trees' + +class KpseServer + + attr_accessor :port + + def initialize(port=7000) + @port = port + end + + def start + puts "starting drb service at port #{@port}" + DRb.start_service("druby://localhost:#{@port}", KpseTrees.new) + trap(:INT) do + DRb.stop_service + end + DRb.thread.join + end + + def stop + # todo + end + +end + +class KpseClient + + attr_accessor :port + + def initialize(port=7000) + @port = port + @kpse = nil + end + + def start + # only needed when callbacks are used / slow, due to Socket::getaddrinfo + # DRb.start_service + end + + def object + @kpse = DRbObject.new(nil,"druby://localhost:#{@port}") + end + +end + + +# SERVER_URI="druby://localhost:8787" +# +# # Start a local DRbServer to handle callbacks. +# # +# # Not necessary for this small example, but will be required +# # as soon as we pass a non-marshallable object as an argument +# # to a dRuby call. +# DRb.start_service +# +# timeserver = DRbObject.new_with_uri(SERVER_URI) diff --git a/scripts/context/ruby/base/kpse/soap.rb b/scripts/context/ruby/base/kpse/soap.rb new file mode 100644 index 000000000..c9ed75c44 --- /dev/null +++ b/scripts/context/ruby/base/kpse/soap.rb @@ -0,0 +1,79 @@ +require 'soap/rpc/standaloneServer' +require 'soap/rpc/driver' + +require 'base/kpse/trees' + +class KpseService < SOAP::RPC::StandaloneServer + + def on_init + kpse = KpseTrees.new + add_method(kpse, 'choose', 'files', 'environment') + add_method(kpse, 'load', 'files', 'environment') + add_method(kpse, 'expand_variables', 'tree') + add_method(kpse, 'expand_braces', 'tree', 'str') + add_method(kpse, 'expand_path', 'tree', 'str') + add_method(kpse, 'expand_var', 'tree', 'str') + add_method(kpse, 'show_path', 'tree', 'str') + add_method(kpse, 'var_value', 'tree', 'str') + add_method(kpse, 'find_file', 'tree', 'filename') + add_method(kpse, 'find_files', 'tree', 'filename', 'first') + end + +end + +class KpseServer + + @@url = 'http://kpse.thismachine.org/KpseService' + + attr_accessor :port + + def initialize(port=7000) + @port = port + @server = nil + end + + def start + puts "starting soap service at port #{@port}" + @server = KpseService.new('KpseServer', @@url, '0.0.0.0', @port.to_i) + trap(:INT) do + @server.shutdown + end + status = @server.start + end + + def stop + @server.shutdown rescue false + end + +end + +class KpseClient + + @@url = 'http://kpse.thismachine.org/KpseService' + + attr_accessor :port + + def initialize(port=7000) + @port = port + @kpse = nil + end + + def start + @kpse = SOAP::RPC::Driver.new("http://localhost:#{port}/", @@url) + @kpse.add_method('choose','files', 'environment') + @kpse.add_method('load','files', 'environment') + @kpse.add_method('expand_variables', 'tree') + @kpse.add_method('expand_braces', 'tree', 'str') + @kpse.add_method('expand_path', 'tree', 'str') + @kpse.add_method('expand_var', 'tree', 'str') + @kpse.add_method('show_path', 'tree', 'str') + @kpse.add_method('var_value', 'tree', 'str') + @kpse.add_method('find_file', 'tree', 'filename') + @kpse.add_method('find_files', 'tree', 'filename', 'first') + end + + def object + @kpse + end + +end diff --git a/scripts/context/ruby/base/kpse/trees.rb b/scripts/context/ruby/base/kpse/trees.rb new file mode 100644 index 000000000..9c872eb18 --- /dev/null +++ b/scripts/context/ruby/base/kpse/trees.rb @@ -0,0 +1,84 @@ +require 'monitor' +require 'base/kpsefast' + +class KpseTrees < Monitor + + def initialize + @trees = Hash.new + end + + def pattern(filenames) + filenames.join('|').gsub(/\\+/o,'/').downcase + end + + def choose(filenames,environment) + current = pattern(filenames) + load(filenames,environment) unless @trees[current] + puts "enabling tree #{current}" + current + end + + def fetch(filenames,environment) # will send whole object ! + current = pattern(filenames) + load(filenames,environment) unless @trees[current] + puts "fetching tree #{current}" + @trees[current] + end + + def load(filenames,environment) + current = pattern(filenames) + puts "loading tree #{current}" + @trees[current] = KpseFast.new + @trees[current].push_environment(environment) + @trees[current].load_cnf(filenames) + @trees[current].expand_variables + @trees[current].load_lsr + end + + def set(tree,key,value) + case key + when 'progname' then @trees[tree].progname = value + when 'engine' then @trees[tree].engine = value + when 'format' then @trees[tree].format = value + end + end + def get(tree,key) + case key + when 'progname' then @trees[tree].progname + when 'engine' then @trees[tree].engine + when 'format' then @trees[tree].format + end + end + + def load_cnf(tree) + @trees[tree].load_cnf + end + def load_lsr(tree) + @trees[tree].load_lsr + end + def expand_variables(tree) + @trees[tree].expand_variables + end + def expand_braces(tree,str) + @trees[tree].expand_braces(str) + end + def expand_path(tree,str) + @trees[tree].expand_path(str) + end + def expand_var(tree,str) + @trees[tree].expand_var(str) + end + def show_path(tree,str) + @trees[tree].show_path(str) + end + def var_value(tree,str) + @trees[tree].var_value(str) + end + def find_file(tree,filename) + @trees[tree].find_file(filename) + end + def find_files(tree,filename,first) + @trees[tree].find_files(filename,first) + end + +end diff --git a/scripts/context/ruby/base/kpsedirect.rb b/scripts/context/ruby/base/kpsedirect.rb new file mode 100644 index 000000000..6fa8c8601 --- /dev/null +++ b/scripts/context/ruby/base/kpsedirect.rb @@ -0,0 +1,34 @@ +class KpseDirect + + attr_accessor :progname, :format, :engine + + def initialize + @progname, @format, @engine = '', '', '' + end + + def expand_path(str) + clean_name(`kpsewhich -expand-path=#{str}`.chomp) + end + + def expand_var(str) + clean_name(`kpsewhich -expand-var=#{str}`.chomp) + end + + def find_file(str) + clean_name(`kpsewhich #{_progname_} #{_format_} #{str}`.chomp) + end + + def _progname_ + if @progname.empty? then '' else "-progname=#{@progname}" end + end + def _format_ + if @format.empty? then '' else "-format=\"#{@format}\"" end + end + + private + + def clean_name(str) + str.gsub(/\\/,'/') + end + +end diff --git a/scripts/context/ruby/base/kpsefast.rb b/scripts/context/ruby/base/kpsefast.rb new file mode 100644 index 000000000..8a9f89593 --- /dev/null +++ b/scripts/context/ruby/base/kpsefast.rb @@ -0,0 +1,934 @@ +# module : base/kpsefast +# copyright : PRAGMA Advanced Document Engineering +# version : 2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# todo: multiple cnf files +# +# todo: cleanup, string or table store (as in lua variant) + +class String + + def split_path + if self =~ /\;/o || self =~ /^[a-z]\:/io then + self.split(";") + else + self.split(":") + end + end + +end + +class Array + + def join_path + self.join(File::PATH_SEPARATOR) + end + +end + +class File + + def File.locate_file(path,name) + begin + files = Dir.entries(path) + if files.include?(name) then + fullname = File.join(path,name) + return fullname if FileTest.file?(fullname) + end + files.each do |p| + fullname = File.join(path,p) + if p != '.' and p != '..' and FileTest.directory?(fullname) and result = locate_file(fullname,name) then + return result + end + end + rescue + # bad path + end + return nil + end + + def File.glob_file(pattern) + return Dir.glob(pattern).first + end + +end + +module KpseUtil + + # to be adapted, see loading cnf file + + @@texmftrees = ['texmf-local','texmf.local','../..','texmf'] # '../..' is for gwtex + @@texmfcnf = 'texmf.cnf' + + def KpseUtil::identify + # we mainly need to identify the local tex stuff and wse assume that + # the texmfcnf variable is set; otherwise we need to expand the + # TEXMF variable and that takes time since it may involve more + ownpath = File.expand_path($0) + if ownpath.gsub!(/texmf.*?$/o, '') then + ENV['SELFAUTOPARENT'] = ownpath + else + ENV['SELFAUTOPARENT'] = '.' # fall back + # may be too tricky: + # + # (ENV['PATH'] ||'').split_path.each do |p| + # if p.gsub!(/texmf.*?$/o, '') then + # ENV['SELFAUTOPARENT'] = p + # break + # end + # end + end + filenames = Array.new + if ENV['TEXMFCNF'] && ! ENV['TEXMFCNF'].empty? then + ENV['TEXMFCNF'].to_s.split_path.each do |path| + filenames << File.join(path,@@texmfcnf) + end + elsif ENV['SELFAUTOPARENT'] == '.' then + filenames << File.join('.',@@texmfcnf) + else + @@texmftrees.each do |tree| + filenames << File.join(ENV['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf) + end + end + loop do + busy = false + filenames.collect! do |f| + f.gsub(/\$([a-zA-Z0-9\_\-]+)/o) do + if (! ENV[$1]) || (ENV[$1] == $1) then + "$#{$1}" + else + busy = true + ENV[$1] + end + end + end + break unless busy + end + filenames.delete_if do |f| + ! FileTest.file?(f) + end + return filenames + end + + def KpseUtil::environment + Hash.new.merge(ENV) + end + +end + +class KpseFast + + # formats are an incredible inconsistent mess + + @@suffixes = Hash.new + @@formats = Hash.new + @@suffixmap = Hash.new + + @@texmfcnf = 'texmf.cnf' + + @@suffixes['gf'] = ['.gf'] # todo + @@suffixes['pk'] = ['.pk'] # todo + @@suffixes['tfm'] = ['.tfm'] + @@suffixes['afm'] = ['.afm'] + @@suffixes['base'] = ['.base'] + @@suffixes['bib'] = ['.bib'] + @@suffixes['bst'] = ['.bst'] + @@suffixes['cnf'] = ['.cnf'] + @@suffixes['ls-R'] = ['ls-R', 'ls-r'] + @@suffixes['fmt'] = ['.fmt', '.efmt', '.efm', '.ofmt', '.ofm', '.oft', '.eofmt', '.eoft', '.eof', '.pfmt', '.pfm', '.epfmt', '.epf', '.xpfmt', '.xpf', '.afmt', '.afm'] + @@suffixes['map'] = ['.map'] + @@suffixes['mem'] = ['.mem'] + @@suffixes['mf'] = ['.mf'] + @@suffixes['mfpool'] = ['.pool'] + @@suffixes['mft'] = ['.mft'] + @@suffixes['mp'] = ['.mp'] + @@suffixes['mppool'] = ['.pool'] + @@suffixes['ocp'] = ['.ocp'] + @@suffixes['ofm'] = ['.ofm', '.tfm'] + @@suffixes['opl'] = ['.opl'] + @@suffixes['otp'] = ['.otp'] + @@suffixes['ovf'] = ['.ovf'] + @@suffixes['ovp'] = ['.ovp'] + @@suffixes['graphic/figure'] = ['.eps', '.epsi'] + @@suffixes['tex'] = ['.tex'] + @@suffixes['texpool'] = ['.pool'] + @@suffixes['PostScript header'] = ['.pro'] + @@suffixes['type1 fonts'] = ['.pfa', '.pfb'] + @@suffixes['vf'] = ['.vf'] + @@suffixes['ist'] = ['.ist'] + @@suffixes['truetype fonts'] = ['.ttf', '.ttc'] + @@suffixes['web'] = ['.web', '.ch'] + @@suffixes['cweb'] = ['.w', '.web', '.ch'] + @@suffixes['enc files'] = ['.enc'] + @@suffixes['cmap files'] = ['.cmap'] + @@suffixes['subfont definition files'] = ['.sfd'] + @@suffixes['lig files'] = ['.lig'] + @@suffixes['bitmap font'] = [] + @@suffixes['MetaPost support'] = [] + @@suffixes['TeX system documentation'] = [] + @@suffixes['TeX system sources'] = [] + @@suffixes['Troff fonts'] = [] + @@suffixes['dvips config'] = [] + @@suffixes['type42 fonts'] = [] + @@suffixes['web2c files'] = [] + @@suffixes['other text files'] = [] + @@suffixes['other binary files'] = [] + @@suffixes['misc fonts'] = [] + @@suffixes['opentype fonts'] = [] + @@suffixes['pdftex config'] = [] + @@suffixes['texmfscripts'] = [] + + # replacements + + @@suffixes['fmt'] = ['.fmt'] + @@suffixes['type1 fonts'] = ['.pfa', '.pfb', '.pfm'] + @@suffixes['tex'] = ['.tex', '.xml'] + @@suffixes['texmfscripts'] = ['rb','lua','py','pl'] + + @@suffixes.keys.each do |k| @@suffixes[k].each do |s| @@suffixmap[s] = k end end + + # TTF2TFMINPUTS + # MISCFONTS + # TEXCONFIG + # DVIPDFMINPUTS + # OTFFONTS + + @@formats['gf'] = '' + @@formats['pk'] = '' + @@formats['tfm'] = 'TFMFONTS' + @@formats['afm'] = 'AFMFONTS' + @@formats['base'] = 'MFBASES' + @@formats['bib'] = '' + @@formats['bst'] = '' + @@formats['cnf'] = '' + @@formats['ls-R'] = '' + @@formats['fmt'] = 'TEXFORMATS' + @@formats['map'] = 'TEXFONTMAPS' + @@formats['mem'] = 'MPMEMS' + @@formats['mf'] = 'MFINPUTS' + @@formats['mfpool'] = 'MFPOOL' + @@formats['mft'] = '' + @@formats['mp'] = 'MPINPUTS' + @@formats['mppool'] = 'MPPOOL' + @@formats['ocp'] = 'OCPINPUTS' + @@formats['ofm'] = 'OFMFONTS' + @@formats['opl'] = 'OPLFONTS' + @@formats['otp'] = 'OTPINPUTS' + @@formats['ovf'] = 'OVFFONTS' + @@formats['ovp'] = 'OVPFONTS' + @@formats['graphic/figure'] = '' + @@formats['tex'] = 'TEXINPUTS' + @@formats['texpool'] = 'TEXPOOL' + @@formats['PostScript header'] = 'TEXPSHEADERS' + @@formats['type1 fonts'] = 'T1FONTS' + @@formats['vf'] = 'VFFONTS' + @@formats['ist'] = '' + @@formats['truetype fonts'] = 'TTFONTS' + @@formats['web'] = '' + @@formats['cweb'] = '' + @@formats['enc files'] = 'ENCFONTS' + @@formats['cmap files'] = 'CMAPFONTS' + @@formats['subfont definition files'] = 'SFDFONTS' + @@formats['lig files'] = 'LIGFONTS' + @@formats['bitmap font'] = '' + @@formats['MetaPost support'] = '' + @@formats['TeX system documentation'] = '' + @@formats['TeX system sources'] = '' + @@formats['Troff fonts'] = '' + @@formats['dvips config'] = '' + @@formats['type42 fonts'] = 'T42FONTS' + @@formats['web2c files'] = 'WEB2C' + @@formats['other text files'] = '' + @@formats['other binary files'] = '' + @@formats['misc fonts'] = '' + @@formats['opentype fonts'] = 'OPENTYPEFONTS' + @@formats['pdftex config'] = 'PDFTEXCONFIG' + @@formats['texmfscripts'] = 'TEXMFSCRIPTS' + + attr_accessor :progname, :engine, :format, :rootpath, :treepath, + :verbose, :remember, :scandisk, :diskcache, :renewcache + + @@cacheversion = '1' + + def initialize + @rootpath = '' + @treepath = '' + @progname = 'kpsewhich' + @engine = 'pdftex' + @variables = Hash.new + @expansions = Hash.new + @files = Hash.new + @found = Hash.new + @kpsevars = Hash.new + @lsrfiles = Array.new + @cnffiles = Array.new + @verbose = true + @remember = true + @scandisk = true + @diskcache = true + @renewcache = false + @isolate = false + + @diskcache = false + @cachepath = nil + @cachefile = 'tmftools.log' + + @environment = ENV + end + + def set(key,value) + case key + when 'progname' then @progname = value + when 'engine' then @engine = value + when 'format' then @format = value + end + end + + def push_environment(env) + @environment = env + end + + # {$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c} + # + # $SELFAUTOLOC : /usr/tex/bin/platform + # $SELFAUTODIR : /usr/tex/bin + # $SELFAUTOPARENT : /usr/tex + # + # since we live in scriptpath we need a slightly different method + + def load_cnf(filenames=nil) + unless filenames then + ownpath = File.expand_path($0) + if ownpath.gsub!(/texmf.*?$/o, '') then + @environment['SELFAUTOPARENT'] = ownpath + else + @environment['SELFAUTOPARENT'] = '.' + end + unless @treepath.empty? then + unless @rootpath.empty? then + @treepath = @treepath.split(',').collect do |p| File.join(@rootpath,p) end.join(',') + end + @environment['TEXMF'] = @treepath + # only the first one + @environment['TEXMFCNF'] = File.join(@treepath.split(',').first,'texmf/web2c') + end + unless @rootpath.empty? then + @environment['TEXMFCNF'] = File.join(@rootpath,'texmf/web2c') + @environment['SELFAUTOPARENT'] = @rootpath + @isolate = true + end + filenames = Array.new + if @environment['TEXMFCNF'] and not @environment['TEXMFCNF'].empty? then + @environment['TEXMFCNF'].to_s.split_path.each do |path| + filenames << File.join(path,@@texmfcnf) + end + elsif @environment['SELFAUTOPARENT'] == '.' then + filenames << File.join('.',@@texmfcnf) + else + ['texmf-local','texmf'].each do |tree| + filenames << File.join(@environment['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf) + end + end + end + # /texmf/web2c/texmf.cnf + filenames = _expanded_path_(filenames) + @rootpath = filenames.first + 3.times do + @rootpath = File.dirname(@rootpath) + end + filenames.collect! do |f| + f.gsub("\\", '/') + end + filenames.each do |fname| + if FileTest.file?(fname) and f = File.open(fname) then + @cnffiles << fname + while line = f.gets do + loop do + # concatenate lines ending with \ + break unless line.sub!(/\\\s*$/o) do + f.gets || '' + end + end + case line + when /^[\%\#]/o then + # comment + when /^\s*(.*?)\s*\=\s*(.*?)\s*$/o then + key, value = $1, $2 + unless @variables.key?(key) then + value.sub!(/\%.*$/,'') + value.sub!(/\~/, "$HOME") + @variables[key] = value + end + @kpsevars[key] = true + end + end + f.close + end + end + end + + def load_lsr + @lsrfiles = [] + simplified_list(expansion('TEXMF')).each do |p| + ['ls-R','ls-r'].each do |f| + filename = File.join(p,f) + if FileTest.file?(filename) then + @lsrfiles << [filename,File.size(filename)] + break + end + end + end + @files = Hash.new + if @diskcache then + ['HOME','TEMP','TMP','TMPDIR'].each do |key| + if @environment[key] then + if FileTest.directory?(@environment[key]) then + @cachepath = @environment[key] + @cachefile = [@rootpath.gsub(/[^A-Z0-9]/io, '-').gsub(/\-+/,'-'),File.basename(@cachefile)].join('-') + break + end + end + end + if @cachepath and not @renewcache and FileTest.file?(File.join(@cachepath,@cachefile)) then + begin + if f = File.open(File.join(@cachepath,@cachefile)) then + cacheversion = Marshal.load(f) + if cacheversion == @@cacheversion then + lsrfiles = Marshal.load(f) + if lsrfiles == @lsrfiles then + @files = Marshal.load(f) + end + end + f.close + end + rescue + @files = Hash.new + end + end + end + return if @files.size > 0 + @lsrfiles.each do |filedata| + filename, filesize = filedata + filepath = File.dirname(filename) + begin + path = '.' + data = IO.readlines(filename) + if data[0].chomp =~ /% ls\-R \-\- filename database for kpathsea\; do not change this line\./io then + data.each do |line| + case line + when /^[a-zA-Z0-9]/o then + line.chomp! + if @files[line] then + @files[line] << path + else + @files[line] = [path] + end + when /^\.\/(.*?)\:$/o then + path = File.join(filepath,$1) + end + end + end + rescue + # sorry + end + end + if @diskcache and @cachepath and f = File.open(File.join(@cachepath,@cachefile),'wb') then + f << Marshal.dump(@@cacheversion) + f << Marshal.dump(@lsrfiles) + f << Marshal.dump(@files) + f.close + end + end + + def expand_variables + @expansions = Hash.new + if @isolate then + @variables['TEXMFCNF'] = @environment['TEXMFCNF'].dup + @variables['SELFAUTOPARENT'] = @environment['SELFAUTOPARENT'].dup + else + @environment.keys.each do |e| + if e =~ /^([a-zA-Z]+)\_(.*)\s*$/o then + @expansions["#{$1}.#{$2}"] = (@environment[e] ||'').dup + else + @expansions[e] = (@environment[e] ||'').dup + end + end + end + @variables.keys.each do |k| + @expansions[k] = @variables[k].dup unless @expansions[k] + end + loop do + busy = false + @expansions.keys.each do |k| + @expansions[k].gsub!(/\$([a-zA-Z0-9\_\-]*)/o) do + busy = true + @expansions[$1] || '' + end + @expansions[k].gsub!(/\$\{([a-zA-Z0-9\_\-]*)\}/o) do + busy = true + @expansions[$1] || '' + end + end + break unless busy + end + @expansions.keys.each do |k| + @expansions[k] = @expansions[k].gsub("\\", '/') + end + end + + def variable(name='') + (name and not name.empty? and @variables[name.sub('$','')]) or '' + end + + def expansion(name='') + (name and not name.empty? and @expansions[name.sub('$','')]) or '' + end + + def variable?(name='') + name and not name.empty? and @variables.key?(name.sub('$','')) + end + + def expansion?(name='') + name and not name.empty? and @expansions.key?(name.sub('$','')) + end + + def simplified_list(str) + lst = str.gsub(/^\{/o,'').gsub(/\}$/o,'').split(",") + lst.collect do |l| + l.sub(/^[\!]*/,'').sub(/[\/\\]*$/o,'') + end + end + + def original_variable(variable) + if variable?("#{@progname}.#{variable}") then + variable("#{@progname}.#{variable}") + elsif variable?(variable) then + variable(variable) + else + '' + end + end + + def expanded_variable(variable) + if expansion?("#{variable}.#{@progname}") then + expansion("#{variable}.#{@progname}") + elsif expansion?(variable) then + expansion(variable) + else + '' + end + end + + def original_path(filename='') + _expanded_path_(original_variable(var_of_format_or_suffix(filename)).split(";")) + end + + def expanded_path(filename='') + _expanded_path_(expanded_variable(var_of_format_or_suffix(filename)).split(";")) + end + + def _expanded_path_(pathlist) + i, n = 0, 0 + pathlist.collect! do |mainpath| + mainpath.gsub(/([\{\}])/o) do + if $1 == "{" then + i += 1 ; n = i if i > n ; "<#{i}>" + else + i -= 1 ; "" + end + end + end + n.times do |i| + loop do + more = false + newlist = [] + pathlist.each do |path| + unless path.sub!(/^(.*?)<(#{n-i})>(.*?)<\/\2>(.*?)$/) do + pre, mid, post = $1, $3, $4 + mid.gsub!(/\,$/,',.') + mid.split(',').each do |m| + more = true + if m == '.' then + newlist << "#{pre}#{post}" + else + newlist << "#{pre}#{m}#{post}" + end + end + end then + newlist << path + end + end + if more then + pathlist = [newlist].flatten # copy -) + else + break + end + end + end + pathlist = pathlist.uniq.collect do |path| + p = path + # p.gsub(/^\/+/o) do '' end + # p.gsub!(/(.)\/\/(.)/o) do "#{$1}/#{$2}" end + # p.gsub!(/\/\/+$/o) do '//' end + p.gsub!(/\/\/+/o) do '//' end + p + end + pathlist + end + + # todo: ignore case + + def var_of_format(str) + @@formats[str] || '' + end + + def var_of_suffix(str) # includes . + if @@suffixmap.key?(str) then @@formats[@@suffixmap[str]] else '' end + end + + def var_of_format_or_suffix(str) + if @@formats.key?(str) then + @@formats[str] + elsif @@suffixmap.key?(File.extname(str)) then # extname includes . + @@formats[@@suffixmap[File.extname(str)]] # extname includes . + else + '' + end + end + +end + +class KpseFast + + # test things + + def list_variables(kpseonly=true) + @variables.keys.sort.each do |k| + if kpseonly then + puts("#{k} = #{@variables[k]}") if @kpsevars[k] + else + puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@variables[k]}") + end + end + end + + def list_expansions(kpseonly=true) + @expansions.keys.sort.each do |k| + if kpseonly then + puts("#{k} = #{@expansions[k]}") if @kpsevars[k] + else + puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@expansions[k]}") + end + end + end + + def list_lsr + puts("files = #{@files.size}") + end + + def set_test_patterns + @variables["KPSE_TEST_PATTERN_A"] = "foo/{1,2}/bar//" + @variables["KPSE_TEST_PATTERN_B"] = "!!x{A,B{1,2}}y" + @variables["KPSE_TEST_PATTERN_C"] = "x{A,B//{1,2}}y" + @variables["KPSE_TEST_PATTERN_D"] = "x{A,B//{1,2,}}//y" + end + + def show_test_patterns + ['A','B','D'].each do |i| + puts "" + puts @variables ["KPSE_TEST_PATTERN_#{i}"] + puts "" + puts expand_path("KPSE_TEST_PATTERN_#{i}").split_path + puts "" + end + end + +end + +class KpseFast + + # kpse stuff + + def expand_braces(str) # output variable and brace expansion of STRING. + _expanded_path_(original_variable(str).split_path).join_path + end + + def expand_path(str) # output complete path expansion of STRING. + _expanded_path_(expanded_variable(str).split_path).join_path + end + + def expand_var(str) # output variable expansion of STRING. + expanded_variable(str) + end + + def show_path(str) # output search path for file type NAME + expanded_path(str).join_path + end + + def var_value(str) # output the value of variable $STRING. + original_variable(str) + end + +end + +class KpseFast + + def _is_cnf_?(filename) + filename == File.basename((@cnffiles.first rescue @@texmfcnf) || @@texmfcnf) + end + + def find_file(filename) + if _is_cnf_?(filename) then + @cnffiles.first rescue '' + else + [find_files(filename,true)].flatten.first || '' + end + end + + def find_files(filename,first=false) + if _is_cnf_?(filename) then + result = @cnffiles.dup + else + if @remember then + # stamp = "#{filename}--#{@format}--#{@engine}--#{@progname}" + stamp = "#{filename}--#{@engine}--#{@progname}" + return @found[stamp] if @found.key?(stamp) + end + pathlist = expanded_path(filename) + result = [] + filelist = if @files.key?(filename) then @files[filename].uniq else nil end + done = false + if pathlist.size == 0 then + if FileTest.file?(filename) then + done = true + result << '.' + end + else + pathlist.each do |path| + doscan = if path =~ /^\!\!/o then false else true end + recurse = if path =~ /\/\/$/o then true else false end + pathname = path.dup + pathname.gsub!(/^\!+/o, '') + done = false + if not done and filelist then + # checking for exact match + if filelist.include?(pathname) then + result << pathname + done = true + end + if not done and recurse then + # checking for fuzzy // + pathname.gsub!(/\/+$/o, '/.*') + # pathname.gsub!(/\/\//o,'/[\/]*/') + pathname.gsub!(/\/\//o,'/.*?/') + re = /^#{pathname}/ + filelist.each do |f| + if re =~ f then + result << f # duplicates will be filtered later + done = true + end + break if done + end + end + end + if not done and doscan then + # checking for path itself + pname = pathname.sub(/\.\*$/,'') + if not pname =~ /\*/o and FileTest.file?(File.join(pname,filename)) then + result << pname + done = true + end + end + break if done and first + end + end + if not done and @scandisk then + pathlist.each do |path| + pathname = path.dup + unless pathname.gsub!(/^\!+/o, '') then # !! prevents scan + recurse = pathname.gsub!(/\/+$/o, '') + complex = pathname.gsub!(/\/\//o,'/*/') + if recurse then + if complex then + if ok = File.glob_file("#{pathname}/**/#{filename}") then + result << File.dirname(ok) + done = true + end + elsif ok = File.locate_file(pathname,filename) then + result << File.dirname(ok) + done = true + end + elsif complex then + if ok = File.glob_file("#{pathname}/#{filename}") then + result << File.dirname(ok) + done = true + end + elsif FileTest.file?(File.join(pathname,filename)) then + result << pathname + done = true + end + break if done and first + end + end + end + result = result.uniq.collect do |pathname| + File.join(pathname,filename) + end + @found[stamp] = result if @remember + end + return result # redundant + end + +end + +class KpseFast + + class FileData + attr_accessor :tag, :name, :size, :date + def initialize(tag=0,name=nil,size=nil,date=nil) + @tag, @name, @size, @date = tag, name, size, date + end + def FileData.sizes(a) + a.collect do |aa| + aa.size + end + end + def report + case @tag + when 1 then "deleted | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}" + when 2 then "present | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}" + when 3 then "obsolete | #{' '*8} | #{' '*16} | #{@name}" + end + end + end + + def analyze_files(filter='',strict=false,sort='',delete=false) + puts("command line = #{ARGV.join(' ')}") + puts("number of files = #{@files.size}") + puts("filter pattern = #{filter}") + puts("loaded cnf files = #{@cnffiles.join(' ')}") + puts('') + if filter.gsub!(/^not:/,'') then + def the_same(filter,filename) + not filter or filter.empty? or /#{filter}/ !~ filename + end + else + def the_same(filter,filename) + not filter or filter.empty? or /#{filter}/ =~ filename + end + end + @files.keys.each do |name| + if @files[name].size > 1 then + data = Array.new + @files[name].each do |path| + filename = File.join(path,name) + # if not filter or filter.empty? or /#{filter}/ =~ filename then + if the_same(filter,filename) then + if FileTest.file?(filename) then + if delete then + data << FileData.new(1,filename,File.size(filename),File.mtime(filename)) + begin + File.delete(filename) if delete + rescue + end + else + data << FileData.new(2,filename,File.size(filename),File.mtime(filename)) + end + else + # data << FileData.new(3,filename) + end + end + end + if data.length > 1 then + if strict then + # if data.collect do |d| d.size end.uniq! then + # data.sort! do |a,b| b.size <=> a.size end + # data.each do |d| puts d.report end + # puts '' + # end + data.sort! do |a,b| + if a.size and b.size then + b.size <=> a.size + else + 0 + end + end + bunch = Array.new + done = false + data.each do |d| + if bunch.size == 0 then + bunch << d + elsif bunch[0].size == d.size then + bunch << d + else + if bunch.size > 1 then + bunch.each do |b| + puts b.report + end + done = true + end + bunch = [d] + end + end + puts '' if done + else + case sort + when 'size' then data.sort! do |a,b| a.size <=> b.size end + when 'revsize' then data.sort! do |a,b| b.size <=> a.size end + when 'date' then data.sort! do |a,b| a.date <=> b.date end + when 'revdate' then data.sort! do |a,b| b.date <=> a.date end + end + data.each do |d| puts d.report end + puts '' + end + end + end + end + end + +end + +# if false then + + # k = KpseFast.new # (root) + # k.set_test_patterns + # k.load_cnf + # k.expand_variables + # k.load_lsr + + # k.show_test_patterns + + # puts k.list_variables + # puts k.list_expansions + # k.list_lsr + # puts k.expansion("$TEXMF") + # puts k.expanded_path("TEXINPUTS","context") + + # k.progname, k.engine, k.format = 'context', 'pdftex', 'tfm' + # k.scandisk = false # == must_exist + # k.expand_variables + + # 10.times do |i| puts k.find_file('texnansi-lmr10.tfm') end + + # puts "expand braces $TEXMF" + # puts k.expand_braces("$TEXMF") + # puts "expand path $TEXMF" + # puts k.expand_path("$TEXMF") + # puts "expand var $TEXMF" + # puts k.expand_var("$TEXMF") + # puts "expand path $TEXMF" + # puts k.show_path('tfm') + # puts "expand value $TEXINPUTS" + # puts k.var_value("$TEXINPUTS") + # puts "expand value $TEXINPUTS.context" + # puts k.var_value("$TEXINPUTS.context") + + # exit + +# end diff --git a/scripts/context/ruby/base/kpseremote.rb b/scripts/context/ruby/base/kpseremote.rb new file mode 100644 index 000000000..9a73b88b0 --- /dev/null +++ b/scripts/context/ruby/base/kpseremote.rb @@ -0,0 +1,116 @@ +require 'base/kpsefast' + +case ENV['KPSEMETHOD'] + when /soap/o then require 'base/kpse/soap' + when /drb/o then require 'base/kpse/drb' + else require 'base/kpse/drb' +end + +class KpseRemote + + @@port = ENV['KPSEPORT'] || 7000 + @@method = ENV['KPSEMETHOD'] || 'drb' + + def KpseRemote::available? + @@method && @@port + end + + def KpseRemote::start_server(port=nil) + kpse = KpseServer.new(port || @@port) + kpse.start + end + + def KpseRemote::start_client(port=nil) # keeps object in server + kpseclient = KpseClient.new(port || @@port) + kpseclient.start + kpse = kpseclient.object + tree = kpse.choose(KpseUtil::identify, KpseUtil::environment) + [kpse, tree] + end + + def KpseRemote::fetch(port=nil) # no need for defining methods but slower, send whole object + kpseclient = KpseClient.new(port || @@port) + kpseclient.start + kpseclient.object.fetch(KpseUtil::identify, KpseUtil::environment) rescue nil + end + + def initialize(port=nil) + if KpseRemote::available? then + begin + @kpse, @tree = KpseRemote::start_client(port) + rescue + @kpse, @tree = nil, nil + end + else + @kpse, @tree = nil, nil + end + end + + def progname=(value) + @kpse.set(@tree,'progname',value) + end + def format=(value) + @kpse.set(@tree,'format',value) + end + def engine=(value) + @kpse.set(@tree,'engine',value) + end + + def progname + @kpse.get(@tree,'progname') + end + def format + @kpse.get(@tree,'format') + end + def engine + @kpse.get(@tree,'engine') + end + + def load + @kpse.load(KpseUtil::identify, KpseUtil::environment) + end + def okay? + @kpse && @tree + end + def set(key,value) + @kpse.set(@tree,key,value) + end + def load_cnf + @kpse.load_cnf(@tree) + end + def load_lsr + @kpse.load_lsr(@tree) + end + def expand_variables + @kpse.expand_variables(@tree) + end + def expand_braces(str) + clean_name(@kpse.expand_braces(@tree,str)) + end + def expand_path(str) + clean_name(@kpse.expand_path(@tree,str)) + end + def expand_var(str) + clean_name(@kpse.expand_var(@tree,str)) + end + def show_path(str) + clean_name(@kpse.show_path(@tree,str)) + end + def var_value(str) + clean_name(@kpse.var_value(@tree,str)) + end + def find_file(filename) + clean_name(@kpse.find_file(@tree,filename)) + end + def find_files(filename,first=false) + # dodo: each filename + @kpse.find_files(@tree,filename,first) + end + + private + + def clean_name(str) + str.gsub(/\\/,'/') + end + +end diff --git a/scripts/context/ruby/base/kpserunner.rb b/scripts/context/ruby/base/kpserunner.rb new file mode 100644 index 000000000..cfc2ad4fb --- /dev/null +++ b/scripts/context/ruby/base/kpserunner.rb @@ -0,0 +1,87 @@ +require 'base/kpsefast' + +module KpseRunner + + @@kpse = nil + + def KpseRunner.kpsewhich(arg='') + options, arguments = split_args(arg) + unless @@kpse then + if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then + require 'base/kpseremote' + @@kpse = KpseRemote.new + else + @@kpse = nil + end + if @@kpse && @@kpse.okay? then + @@kpse.progname = options['progname'] || '' + @@kpse.engine = options['engine'] || '' + @@kpse.format = options['format'] || '' + else + require 'base/kpsefast' + @@kpse = KpseFast.new + @@kpse.load_cnf + @@kpse.progname = options['progname'] || '' + @@kpse.engine = options['engine'] || '' + @@kpse.format = options['format'] || '' + @@kpse.expand_variables + @@kpse.load_lsr + end + else + @@kpse.progname = options['progname'] || '' + @@kpse.engine = options['engine'] || '' + @@kpse.format = options['format'] || '' + @@kpse.expand_variables + end + if option = options['expand-braces'] and not option.empty? then + @@kpse.expand_braces(option) + elsif option = options['expand-path'] and not option.empty? then + @@kpse.expand_path(option) + elsif option = options['expand-var'] and not option.empty? then + @@kpse.expand_var(option) + elsif option = options['show-path'] and not option.empty? then + @@kpse.show_path(option) + elsif option = options['var-value'] and not option.empty? then + @@kpse.expand_var(option) + elsif arguments.size > 0 then + files = Array.new + arguments.each do |option| + if file = @@kpse.find_file(option) and not file.empty? then + files << file + end + end + files.join("\n") + else + '' + end + end + + def KpseRunner.kpsereset + @@kpse = nil + end + + private + + def KpseRunner.split_args(arg) + vars, args = Hash.new, Array.new + arg.gsub!(/([\"\'])(.*?)\1/o) do + $2.gsub(' ','') + end + arg = arg.split(/\s+/o) + arg.collect! do |a| + a.gsub('',' ') + end + arg.each do |a| + if a =~ /^(.*?)\=(.*?)$/o then + k, v = $1, $2 + vars[k.sub(/^\-+/,'')] = v + else + args << a + end + end + # puts vars.inspect + # puts args.inspect + return vars, args + end + +end diff --git a/scripts/context/ruby/base/logger.rb b/scripts/context/ruby/base/logger.rb new file mode 100644 index 000000000..2526cdb0e --- /dev/null +++ b/scripts/context/ruby/base/logger.rb @@ -0,0 +1,104 @@ +# module : base/logger +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +require 'thread' + +# The next calls are valid: + +# @log.report('a','b','c', 'd') +# @log.report('a','b',"c #{d}") +# @log.report("a b c #{d}") + +# Keep in mind that "whatever #{something}" is two times faster than +# 'whatever ' + something or ['whatever',something].join and that +# when verbosity is not needed the following is much faster too: + +# @log.report('a','b','c', 'd') if @log.verbose? +# @log.report('a','b',"c #{d}") if @log.verbose? +# @log.report("a b c #{d}") if @log.verbose? + +# The last three cases are equally fast when verbosity is turned off. + +# Under consideration: verbose per instance + +class Logger + + @@length = 0 + @@verbose = false + + def initialize(tag=nil,length=0,verbose=false) + @tag = tag || '' + @@verbose = @@verbose || verbose + @@length = @tag.length if @tag.length > @@length + @@length = length if length > @@length + end + + def report(*str) + begin + case str.length + when 0 + print("\n") + return true + when 1 + message = str.first + else + message = [str].flatten.collect{|s| s.to_s}.join(' ').chomp + end + if @tag.empty? then + print("#{message}\n") + else + # try to avoid too many adjustments + @tag = @tag.ljust(@@length) unless @tag.length == @@length + print("#{@tag} | #{message}\n") + end + rescue + end + return true + end + + def reportlines(*str) + unless @tag.empty? then + @tag = @tag.ljust(@@length) unless @tag.length == @@length + end + report([str].flatten.collect{|s| s.gsub(/\n/,"\n#{@tag} | ")}.join(' ')) + end + + def debug(*str) + report(str) if @@verbose + end + + def error(*str) + if ! $! || $!.to_s.empty? then + report(str) + else + report(str,$!) + end + end + + def verbose + @@verbose = true + end + + def silent + @@verbose = false + end + + def verbose? + @@verbose + end + + # attr_reader :tag + + # alias fatal error + # alias info debug + # alias warn debug + # alias debug? :verbose? + +end diff --git a/scripts/context/ruby/base/merge.rb b/scripts/context/ruby/base/merge.rb new file mode 100644 index 000000000..a66b97e91 --- /dev/null +++ b/scripts/context/ruby/base/merge.rb @@ -0,0 +1,139 @@ +# module : base/merge +# copyright : PRAGMA Advanced Document Engineering +# version : 2006 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# --selfmerg ewill create stand alone script (--selfcleanup does the opposite) + +# this module will package all the used modules in the file itself +# so that we can relocate the file at wish, usage: +# +# merge: +# +# unless SelfMerge::ok? && SelfMerge::merge then +# puts("merging should happen on the path were the base inserts reside") +# end +# +# cleanup: +# +# unless SelfMerge::cleanup then +# puts("merging should happen on the path were the base inserts reside") +# end + +module SelfMerge + + @@kpsemergestart = "\# kpse_merge_start" + @@kpsemergestop = "\# kpse_merge_stop" + @@kpsemergefile = "\# kpse_merge_file: " + @@kpsemergedone = "\# kpse_merge_done: " + + @@filename = File.basename($0) + @@ownpath = File.expand_path(File.dirname($0)) + @@modroot = '(base|graphics|rslb|www)' # needed in regex in order not to mess up SelfMerge + @@modules = $".collect do |file| File.expand_path(file) end + + @@modules.delete_if do |file| + file !~ /^#{@@ownpath}\/#{@@modroot}.*$/i + end + + def SelfMerge::ok? + begin + @@modules.each do |file| + return false unless FileTest.file?(file) + end + rescue + return false + else + return true + end + end + + def SelfMerge::merge + begin + if SelfMerge::ok? && rbfile = IO.read(@@filename) then + begin + inserts = "#{@@kpsemergestart}\n\n" + @@modules.each do |file| + inserts << "#{@@kpsemergefile}'#{file}'\n\n" + inserts << IO.read(file).gsub(/^#.*?\n$/,'') + inserts << "\n\n" + end + inserts << "#{@@kpsemergestop}\n\n" + # no gsub! else we end up in SelfMerge + rbfile.sub!(/#{@@kpsemergestart}\s*#{@@kpsemergestop}/moi) do + inserts + end + rbfile.gsub!(/^(.*)(require [\"\'].*?#{@@modroot}.*)$/) do + pre, post = $1, $2 + if pre =~ /#{@@kpsemergedone}/ then + "#{pre}#{post}" + else + "#{pre}#{@@kpsemergedone}#{post}" + end + end + rescue + return false + else + begin + File.open(@@filename,'w') do |f| + f << rbfile + end + rescue + return false + end + end + end + rescue + return false + else + return true + end + end + + def SelfMerge::cleanup + begin + if rbfile = IO.read(@@filename) then + begin + rbfile.sub!(/#{@@kpsemergestart}(.*)#{@@kpsemergestop}\s*/moi) do + "#{@@kpsemergestart}\n\n#{@@kpsemergestop}\n\n" + end + rbfile.gsub!(/^(.*#{@@kpsemergedone}.*)$/) do + str = $1 + if str =~ /require [\"\']/ then + str.gsub(/#{@@kpsemergedone}/, '') + else + str + end + end + rescue + return false + else + begin + File.open(@@filename,'w') do |f| + f << rbfile + end + rescue + return false + end + end + end + rescue + return false + else + return true + end + end + + def SelfMerge::replace + if SelfMerge::ok? then + SelfMerge::cleanup + SelfMerge::merge + end + end + +end diff --git a/scripts/context/ruby/base/mp.rb b/scripts/context/ruby/base/mp.rb new file mode 100644 index 000000000..d168bde1d --- /dev/null +++ b/scripts/context/ruby/base/mp.rb @@ -0,0 +1,167 @@ +# module : base/mp +# copyright : PRAGMA Advanced Document Engineering +# version : 2005-2006 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +module MPTools + + @@definitions, @@start, @@stop, @@before, @@after = Hash.new, Hash.new, Hash.new, Hash.new, Hash.new + + + @@definitions['plain'] = <0 \\vrule width1sp height\\dimen1 depth\\dimen2 + \\else \\vrule width1sp height1sp depth0sp\\relax + \\fi\\egroup + \\ht0=0pt \\dp0=0pt \\box0 \\egroup} +EOT + + @@start ['plain'] = "" + @@before['plain'] = "\\mpxshipout" + @@after ['plain'] = "\\stopmpxshipout" + @@stop ['plain'] = "\\end{document}" + + @@definitions['context'] = <0 + \\vrule width 1sp height \\dimen1 depth \\dimen2 + \\else + \\vrule width 1sp height 1sp depth 0sp \\relax + \\fi + \\egroup + \\ht0=0pt + \\dp0=0pt + \\loadallfontmapfiles + \\box0 + \\egroup} + +\\fi + +\\ifx\\starttext\\undefined + + \\let\\starttext\\relax + \\def\\stoptext{\\end{document}} + +\\fi +EOT + + @@start ['context'] = "\\starttext" + @@before['context'] = "\\startMPXpage" + @@after ['context'] = "\\stopMPXpage" + @@stop ['context'] = "\\stoptext" + + # todo: \usemodule[m-mpx ] and test fo defined + + def MPTools::mptotex(from,to=nil,method='plain') + begin + if from && data = IO.read(from) then + f = if to then File.open(to,'w') else $stdout end + f.puts("% file: #{from}") + f.puts("") + f.puts(@@definitions[method]) + unless @@start[method].empty? then + f.puts("") + f.puts(@@start[method]) + end + data.gsub!(/([^\\])%.*?$/mo) do + $1 + end + data.scan(/(verbatim|b)tex\s*(.*?)\s*etex/mo) do + tag, text = $1, $2 + f.puts("") + if tag == 'b' then + f.puts(@@before[method]) + f.puts("#{text}%") + f.puts(@@after [method]) + else + f.puts("#{text}") + end + f.puts("") + end + f.puts("") + f.puts(@@stop[method]) + f.close + else + return false + end + rescue + File.delete(to) rescue false + return false + else + return true + end + end + + @@splitMPlines = false + + def MPTools::splitmplines(str) + if @@splitMPlines then + btex, verbatimtex, strings, result = Array.new, Array.new, Array.new, str.dup + # protect texts + result.gsub!(/btex\s*(.*?)\s*etex/) do + btex << $1 + "btex(#{btex.length-1})" + end + result.gsub!(/verbatimtex\s*(.*?)\s*etex/) do + verbatimtex << $1 + "verbatimtex(#{verbatimtex.length-1})" + end + result.gsub!(/\"(.*?)\"/) do + strings << $1 + "\"#{strings.length-1}\"" + end + result.gsub!(/\;/) do + ";\n" + end + result.gsub!(/(.{80,})(\-\-\-|\-\-|\.\.\.|\.\.)/) do + "#{$1}#{$2}\n" + end + result.gsub!(/\n[\s\n]+/moi) do + "\n" + end + result.gsub!(/btex\((\d+)\)/) do + "btex #{btex[$1.to_i]} etex" + end + result.gsub!(/verbatimtex\((\d+)\)/) do + "verbatimtex #{verbatimtex[$1.to_i]} etex" + end + result.gsub!(/\"(\d+)\"/) do + "\"#{strings[$1.to_i]}\"" + end + # return result # let's catch xetex bug + return result.gsub(/\^\^(M|J)/o, "\n") + else + # return str # let's catch xetex bug + return str.gsub(/\^\^(M|J)/o, "\n") + end + end + +end diff --git a/scripts/context/ruby/base/pdf.rb b/scripts/context/ruby/base/pdf.rb new file mode 100644 index 000000000..5aec06fc5 --- /dev/null +++ b/scripts/context/ruby/base/pdf.rb @@ -0,0 +1,75 @@ +module PDFview + + @files = Hash.new + @opencalls = Hash.new + @closecalls = Hash.new + @allcalls = Hash.new + + @method = 'default' # 'xpdf' + + @opencalls['default'] = "pdfopen --file" # "pdfopen --back --file" + @opencalls['xpdf'] = "xpdfopen" + + @closecalls['default'] = "pdfclose --file" + @closecalls['xpdf'] = nil + + @allcalls['default'] = "pdfclose --all" + @allcalls['xpdf'] = nil + + def PDFview.setmethod(method) + @method = method + end + + def PDFview.open(*list) + begin + [*list].flatten.each do |file| + filename = fullname(file) + if FileTest.file?(filename) then + if @opencalls[@method] then + result = `#{@opencalls[@method]} #{filename} 2>&1` + @files[filename] = true + end + end + end + rescue + end + end + + def PDFview.close(*list) + [*list].flatten.each do |file| + filename = fullname(file) + begin + if @files.key?(filename) then + if @closecalls[@method] then + result = `#{@closecalls[@method]} #{filename} 2>&1` + end + else + closeall + return + end + rescue + end + @files.delete(filename) + end + end + + def PDFview.closeall + begin + if @allcalls[@method] then + result = `#{@allcalls[@method]} 2>&1` + end + rescue + end + @files.clear + end + + def PDFview.fullname(name) + name + if name =~ /\.pdf$/ then '' else '.pdf' end + end + +end + +# PDFview.open("t:/document/show-exa.pdf") +# PDFview.open("t:/document/show-gra.pdf") +# PDFview.close("t:/document/show-exa.pdf") +# PDFview.close("t:/document/show-gra.pdf") diff --git a/scripts/context/ruby/base/state.rb b/scripts/context/ruby/base/state.rb new file mode 100644 index 000000000..76ef50b25 --- /dev/null +++ b/scripts/context/ruby/base/state.rb @@ -0,0 +1,75 @@ +require 'digest/md5' + +# todo: register omissions per file + +class FileState + + def initialize + @states = Hash.new + @omiter = Hash.new + end + + def reset + @states.clear + @omiter.clear + end + + def register(filename,omit=nil) + unless @states.key?(filename) then + @states[filename] = Array.new + @omiter[filename] = omit + end + @states[filename] << checksum(filename,@omiter[filename]) + end + + def update(filename=nil) + [filename,@states.keys].flatten.compact.uniq.each do |fn| + register(fn) + end + end + + def inspect(filename=nil) + result = '' + [filename,@states.keys].flatten.compact.uniq.sort.each do |fn| + if @states.key?(fn) then + result += "#{fn}: #{@states[fn].inspect}\n" + end + end + result + end + + def changed?(filename) + if @states.key?(filename) then + n = @states[filename].length + if n>1 then + changed = @states[filename][n-1] != @states[filename][n-2] + else + changed = true + end + else + changed = true + end + return changed + end + + def checksum(filename,omit=nil) + sum = '' + begin + if FileTest.file?(filename) && (data = IO.read(filename)) then + data.gsub!(/\n.*?(#{[omit].flatten.join('|')}).*?\n/) do "\n" end if omit + sum = Digest::MD5.hexdigest(data).upcase + end + rescue + sum = '' + end + return sum + end + + def stable? + @states.keys.each do |s| + return false if changed?(s) + end + return true + end + +end diff --git a/scripts/context/ruby/base/switch.rb b/scripts/context/ruby/base/switch.rb new file mode 100644 index 000000000..19eced424 --- /dev/null +++ b/scripts/context/ruby/base/switch.rb @@ -0,0 +1,635 @@ +# module : base/switch +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# we cannot use getoptlong because we want to be more +# tolerant; also we want to be case insensitive (2002). + +# we could make each option a class itself, but this is +# simpler; also we can put more in the array + +# beware: regexps/o in methods are optimized globally + +require "rbconfig" + +$mswindows = Config::CONFIG['host_os'] =~ /mswin/ +$separator = File::PATH_SEPARATOR + +class String + + def has_suffix?(suffix) + self =~ /\.#{suffix}$/i + end + +end + +# may move to another module + +class File + + @@update_eps = 1 + + def File.needsupdate(oldname,newname) + begin + oldtime = File.stat(oldname).mtime.to_i + newtime = File.stat(newname).mtime.to_i + if newtime >= oldtime then + return false + elsif oldtime-newtime < @@update_eps then + return false + else + return true + end + rescue + return true + end + end + + def File.syncmtimes(oldname,newname) + return + begin + if $mswindows then + # does not work (yet) / gives future timestamp + # t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here + # File.utime(0,t,oldname,newname) + else + t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here + File.utime(0,t,oldname,newname) + end + rescue + end + end + + def File.timestamp(name) + begin + "#{File.stat(name).mtime}" + rescue + return 'unknown' + end + end + +end + +# main thing + +module CommandBase + + # this module can be used as a mixin in a command handler + + $stdout.sync = true + + def initialize(commandline,logger,banner) + @commandline, @logger, @banner = commandline, logger, banner + @forcenewline, @versiondone, @error = false, false, false + version if @commandline.option('version') + end + + def reportlines(*str) + @logger.reportlines(str) + end + + # only works in 1.8 + # + # def report(*str) + # @logger.report(str) + # end + # + # def version # just a bit of playing with defs + # report(@banner.join(' - ')) + # def report(*str) + # @logger.report + # @logger.report(str) + # def report(*str) + # @logger.report(str) + # end + # end + # def version + # end + # end + + def report(*str) + initlogger ; @logger.report(str) + end + + def seterror + @error = true + end + + def error? + return @error + end + + def exit + if @error then Kernel.exit(1) else Kernel.exit(0) end + end + + def execute(str=nil) + send(str || action || 'main') + exit + end + + def debug(*str) + initlogger ; @logger.debug(str) + end + + def error(*str) + initlogger ; @logger.error(str) + end + + def initlogger + if @forcenewline then + @logger.report + @forcenewline = false + end + end + + def logger + @logger + end + + def version # just a bit of playing with defs + unless @versiondone then + report(@banner.join(' - ')) + @forcenewline = true + @versiondone = true + end + end + + def help + version # is nilled when already given + @commandline.helpkeys.each do |k| + if @commandline.help?(k) then + kstr = ('--'+k).ljust(@commandline.helplength+2) + message = @commandline.helptext(k) + message = '' if message == CommandLine::NOHELP + message = message.split(/\s*\n\s*/) + loop do + report("#{kstr} #{message.shift}") + kstr = ' '*kstr.length + break if message.length == 0 + end + end + end + end + + def option(key) + @commandline.option(key) + end + def oneof(*key) + @commandline.oneof(*key) + end + + def globfiles(pattern='*',suffix=nil) + @commandline.setarguments([pattern].flatten) + if files = findfiles(suffix) then + @commandline.setarguments(files) + else + @commandline.setarguments + end + end + + private + + def findfiles(suffix=nil) + + if @commandline.arguments.length>1 then + return @commandline.arguments + else + pattern = @commandline.argument('first') + pattern = '*' if pattern.empty? + if suffix && ! pattern.match(/\..+$/o) then + suffix = '.' + suffix + pattern += suffix unless pattern =~ /#{suffix}$/ + end + # not {} safe + pattern = '**/' + pattern if @commandline.option('recurse') + files = Dir[pattern] + if files && files.length>0 then + return files + else + pattern = @commandline.argument('first') + if FileTest.file?(pattern) then + return [pattern] + else + report("no files match pattern #{pattern}") + return nil + end + end + end + + end + + def globbed(pattern,recurse=false) + + files = Array.new + pattern.split(' ').each do |p| + if recurse then + if p =~ /^(.*)(\/.*?)$/i then + p = $1 + '/**' + $2 + else + p = '**/' + p + end + p.gsub!(/[\\\/]+/, '/') + end + files.push(Dir.glob(p)) + end + files.flatten.sort do |a,b| + pathcompare(a,b) + end + end + + def pathcompare(a,b) + + aa, bb = a.split('/'), b.split('/') + if aa.length == bb.length then + aa.each_index do |i| + if aa[i]bb[i] then + return +1 + end + end + return 0 + else + return aa.length <=> bb.length + end + + end + +end + +class CommandLine + + VALUE, FLAG = 1, 2 + NOHELP = 'no arguments' + + def initialize(prefix='-') + + @registered = Array.new + @options = Hash.new + @unchecked = Hash.new + @arguments = Array.new + @original = ARGV.join(' ') + @helptext = Hash.new + @mandated = Hash.new + @provided = Hash.new + @prefix = prefix + @actions = Array.new + + # The quotes in --switch="some value" get lost in ARGV, so we need to do some trickery here. + + @original = '' + ARGV.each do |a| + aa = a.strip.gsub(/^([#{@prefix}]+\w+\=)([^\"].*?\s+.*[^\"])$/) do + $1 + "\"" + $2 + "\"" + end + @original += if @original.empty? then '' else ' ' end + aa + end + + end + + def setarguments(args=[]) + @arguments = if args then args else [] end + end + + def register(option,shortcut,kind,default=false,action=false,helptext='') + if kind == FLAG then + @options[option] = default + elsif not default then + @options[option] = '' + else + @options[option] = default + end + @registered.push([option,shortcut,kind]) + @mandated[option] = false + # @provided[option] = false + @helptext[option] = helptext + @actions.push(option) if action + end + + def registerflag(option,default=false,helptext='') + if default.class == String then + register(option,'',FLAG,false,false,default) + else + register(option,'',FLAG,false,false,helptext) + end + end + + def registervalue(option,default='',helptext='') + register(option,'',VALUE,default,false,helptext) + end + + def registeraction(option,helptext='') + register(option,'',FLAG,false,true,helptext) + end + + def registermandate(*option) + [*option].each do |o| + [o].each do |oo| + @mandated[oo] = true + end + end + end + + def actions + a = @actions.delete_if do |t| + ! option(t) + end + if a && a.length>0 then + return a + else + return nil + end + end + + def action + @actions.each do |t| + return t if option(t) + end + return nil + end + + def forgotten + @mandated.keys.sort - @provided.keys.sort + end + + def registerhelp(option,text='') + @helptext['unknown'] = if text.empty? then option else text end + end + + def helpkeys(option='.*') + @helptext.keys.sort.grep(/#{option}/) + end + + def helptext(option) + @helptext.fetch(option,'') + end + + def help?(option) + @helptext[option] && ! @helptext[option].empty? + end + + def helplength + n = 0 + @helptext.keys.each do |h| + n = h.length if h.length>n + end + return n + end + + def expand + + # todo : '' or false, depending on type + # @options.clear + # @arguments.clear + + dirtyvalue(@original).split(' ').each do |arg| + case arg + when /^[#{@prefix}][#{@prefix}](.+?)\=(.*?)$/ then locatedouble($1,$2) + when /^[#{@prefix}][#{@prefix}](.+?)$/ then locatedouble($1,false) + when /^[#{@prefix}](.)\=(.)$/ then locatesingle($1,$2) + when /^[#{@prefix}](.+?)$/ then locateseries($1,false) + when /^[\+\-]+/o then # do nothing + else + arguments.push(arg) + end + end + + @options or @unchecked or @arguments + + end + + def extend (str) + @original = @original + ' ' + str + end + + def replace (str) + @original = str + end + + def show + # print "-- options --\n" + @options.keys.sort.each do |key| + print "option: #{key} -> #{@options[key]}\n" + end + # print "-- arguments --\n" + @arguments.each_index do |key| + print "argument: #{key} -> #{@arguments[key]}\n" + end + end + + def option(str,default=nil) + if @options.key?(str) then + @options[str] + elsif default then + default + else + @options[str] + end + end + + def checkedoption(str,default='') + if @options.key?(str) then + if @options[str].empty? then default else @options[str] end + else + default + end + end + + def foundoption(str,default='') + str = str.split(',') if str.class == String + str.each do |s| + return str if @options.key?(str) + end + return default + end + + def oneof(*key) + [*key].flatten.compact.each do |k| + return true if @options.key?(k) && @options[k] + end + return false + end + + def setoption(str,value) + @options[str] = value + end + + def getoption(str,value='') # value ? + @options[str] + end + + def argument(n=0) + if n.class == String then + case n + when 'first' then argument(0) + when 'second' then argument(1) + when 'third' then argument(2) + else + argument(0) + end + elsif @arguments[n] then + @arguments[n] + else + '' + end + end + + # a few local methods, cannot be defined nested (yet) + + private + + def dirtyvalue(value) + if value then + value.gsub(/([\"\'])(.*?)\1/) do + $2.gsub(/\s+/o, "\xFF") + end + else + '' + end + end + + def cleanvalue(value) + if value then + # value.sub(/^([\"\'])(.*?)\1$/) { $2.gsub(/\xFF/o, ' ') } + value.gsub(/\xFF/o, ' ') + else + '' + end + end + + def locatedouble(key, value) + + foundkey, foundkind = nil, nil + + @registered.each do |option, shortcut, kind| + if option == key then + foundkey, foundkind = option, kind + break + end + end + unless foundkey then + @registered.each do |option, shortcut, kind| + n = 0 + begin + re = /^#{key}/i + rescue + key = key.inspect.sub(/^\"(.*)\"$/) do $1 end + re = /^#{key}/i + ensure + if option =~ re then + case n + when 0 + foundkey, foundkind, n = option, kind, 1 + when 1 + # ambiguous matches, like --fix => --fixme --fixyou + foundkey, foundkind = nil, nil + break + end + end + end + end + end + if foundkey then + @provided[foundkey] = true + if foundkind == VALUE then + @options[foundkey] = cleanvalue(value) + else + @options[foundkey] = true + end + else + if value.class == FalseClass then + @unchecked[key] = true + else + @unchecked[key] = cleanvalue(value) + end + end + + end + + def locatesingle(key, value) + + @registered.each do |option, shortcut, kind| + if shortcut == key then + @provided[option] = true + @options[option] = if kind == VALUE then '' else cleanvalue(value) end + break + end + end + + end + + def locateseries(series, value) + + series.each do |key| + locatesingle(key,cleanvalue(value)) + end + + end + + public + + attr_reader :arguments, :options, :original, :unchecked + +end + +# options = CommandLine.new +# +# options.register("filename", "f", CommandLine::VALUE) +# options.register("request" , "r", CommandLine::VALUE) +# options.register("verbose" , "v", CommandLine::FLAG) +# +# options.expand +# options.extend(str) +# options.show +# +# c = CommandLine.new +# +# c.registervalue('aaaa') +# c.registervalue('test') +# c.registervalue('zzzz') +# +# c.registerhelp('aaaa','some aaaa to enter') +# c.registerhelp('test','some text to enter') +# c.registerhelp('zzzz','some zzzz to enter') +# +# c.registermandate('test') +# +# c.expand +# +# class CommandLine +# +# def showhelp (banner,*str) +# if helpkeys(*str).length>0 +# print banner +# helpkeys(*str).each do |h| +# print helptext(h) + "\n" +# end +# true +# else +# false +# end +# end +# +# def showmandate(banner) +# if forgotten.length>0 +# print banner +# forgotten.each do |f| +# print helptext(f) + "\n" +# end +# true +# else +# false +# end +# end +# +# end +# +# c.showhelp("you can provide:\n\n") +# c.showmandate("you also need to provide:\n\n") diff --git a/scripts/context/ruby/base/system.rb b/scripts/context/ruby/base/system.rb new file mode 100644 index 000000000..c3fb08645 --- /dev/null +++ b/scripts/context/ruby/base/system.rb @@ -0,0 +1,121 @@ +# module : base/system +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +require "rbconfig" + +module System + + @@mswindows = Config::CONFIG['host_os'] =~ /mswin/ + @@binpaths = ENV['PATH'].split(File::PATH_SEPARATOR) + @@binsuffixes = if $mswindows then ['.exe','.com','.bat'] else ['','.sh','.csh'] end + @@located = Hash.new + @@binnames = Hash.new + + if @@mswindows then + @@binnames['ghostscript'] = ['gswin32c.exe','gs.cmd','gs.bat'] + @@binnames['imagemagick'] = ['imagemagick.exe','convert.exe'] + @@binnames['inkscape'] = ['inkscape.exe'] + else + @@binnames['ghostscript'] = ['gs'] + @@binnames['imagemagick'] = ['convert'] + @@binnames['inkscape'] = ['inkscape'] + end + + + def System.null + if @@mswindows then 'nul' else '/dev/null' end + end + + def System.unix? + not @@mswindows + end + def System.mswin? + @@mswindows + end + + def System.binnames(str) + if @@binnames.key?(str) then + @@binnames[str] + else + [str] + end + end + + def System.prependengine(str) + if str =~ /^\S+\.(pl|rb|lua|py)/io then + case $1 + when 'pl' then return "perl #{str}" + when 'rb' then return "ruby #{str}" + when 'lua' then return "lua #{str}" + when 'py' then return "python #{str}" + end + end + return str + end + + def System.locatedprogram(program) + if @@located.key?(program) then + return @@located[program] + else + System.binnames(program).each do |binname| + if binname =~ /\..*$/io then + @@binpaths.each do |path| + if FileTest.file?(str = File.join(path,binname)) then + return @@located[program] = System.prependengine(str) + end + end + end + binname.gsub!(/\..*$/io, '') + @@binpaths.each do |path| + @@binsuffixes.each do |suffix| + if FileTest.file?(str = File.join(path,"#{binname}#{suffix}")) then + return @@located[program] = System.prependengine(str) + end + end + end + end + end + return @@located[program] = "texmfstart #{program}" + end + + def System.command(program,arguments='') + if program =~ /^(.*?) (.*)$/ then + program = System.locatedprogram($1) + ' ' + $2 + else + program = System.locatedprogram(program) + end + program = program + ' ' + arguments if ! arguments.empty? + program.gsub!(/\s+/io, ' ') + #program.gsub!(/(\/\.\/)+/io, '/') + program.gsub!(/\\/io, '/') + return program + end + + def System.run(program,arguments='',pipe=false,collect=false) + if pipe then + if collect then + `#{System.command(program,arguments)} 2>&1` + else + `#{System.command(program,arguments)}` + end + else + system(System.command(program,arguments)) + end + end + + def System.pipe(program,arguments='',collect=false) + System.run(program,arguments,true) + end + + def System.safepath(path) + if path.match(/ /o) then "\"#{path}\"" else path end + end + +end diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb new file mode 100644 index 000000000..84025693b --- /dev/null +++ b/scripts/context/ruby/base/tex.rb @@ -0,0 +1,2299 @@ +# module : base/tex +# copyright : PRAGMA Advanced Document Engineering +# version : 2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# todo: +# +# - write systemcall for mpost to file so that it can be run faster +# - use -8bit and -progname +# + +# report ? + +require 'fileutils' + +require 'base/variables' +require 'base/kpse' +require 'base/system' +require 'base/state' +require 'base/pdf' +require 'base/file' +require 'base/ctx' +require 'base/mp' + +class String + + def standard? + begin + self == 'standard' + rescue + false + end + end + +end + +# class String + # def utf_bom? + # self.match(/^\357\273\277/o).length>0 rescue false + # end +# end + +class Array + + def standard? + begin + self.include?('standard') + rescue + false + end + end + + def join_path + self.join(File::PATH_SEPARATOR) + end + +end + +class TEX + + # The make-part of this class was made on a rainy day while listening + # to "10.000 clowns on a rainy day" by Jan Akkerman. Unfortunately the + # make method is not as swinging as this live cd. + + include Variables + + @@texengines = Hash.new + @@mpsengines = Hash.new + @@backends = Hash.new + @@mappaths = Hash.new + @@runoptions = Hash.new + @@tcxflag = Hash.new + @@draftoptions = Hash.new + @@synctexcoptions = Hash.new + @@texformats = Hash.new + @@mpsformats = Hash.new + @@prognames = Hash.new + @@texmakestr = Hash.new + @@texprocstr = Hash.new + @@mpsmakestr = Hash.new + @@mpsprocstr = Hash.new + @@texmethods = Hash.new + @@mpsmethods = Hash.new + @@pdftex = 'pdftex' # new default, pdfetex is gone + @@luafiles = "luafiles.tmp" + @@luatarget = "lua/context" + + @@platformslash = if System.unix? then "\\\\" else "\\" end + + ['tex','etex','pdftex','pdfetex','standard'] .each do |e| @@texengines[e] = 'pdftex' end + ['aleph','omega'] .each do |e| @@texengines[e] = 'aleph' end + ['xetex'] .each do |e| @@texengines[e] = 'xetex' end + ['petex'] .each do |e| @@texengines[e] = 'petex' end + ['luatex'] .each do |e| @@texengines[e] = 'luatex' end + + ['metapost','mpost', 'standard'] .each do |e| @@mpsengines[e] = 'mpost' end + + ['pdfetex','pdftex','pdf','pdftex','standard'] .each do |b| @@backends[b] = 'pdftex' end + ['dvipdfmx','dvipdfm','dpx','dpm'] .each do |b| @@backends[b] = 'dvipdfmx' end + ['xetex','xtx'] .each do |b| @@backends[b] = 'xetex' end + ['petex'] .each do |b| @@backends[b] = 'dvipdfmx' end + ['aleph'] .each do |b| @@backends[b] = 'dvipdfmx' end + ['dvips','ps','dvi'] .each do |b| @@backends[b] = 'dvips' end + ['dvipsone'] .each do |b| @@backends[b] = 'dvipsone' end + ['acrobat','adobe','distiller'] .each do |b| @@backends[b] = 'acrobat' end + ['xdv','xdv2pdf'] .each do |b| @@backends[b] = 'xdv2pdf' end + + ['tex','standard'] .each do |b| @@mappaths[b] = 'dvips' end + ['pdftex','pdfetex'] .each do |b| @@mappaths[b] = 'pdftex' end + ['aleph','omega','xetex','petex'] .each do |b| @@mappaths[b] = 'dvipdfmx' end + ['dvipdfm', 'dvipdfmx', 'xdvipdfmx'] .each do |b| @@mappaths[b] = 'dvipdfmx' end + ['xdv','xdv2pdf'] .each do |b| @@mappaths[b] = 'dvips' end + + # todo norwegian (no) + + ['plain'] .each do |f| @@texformats[f] = 'plain' end + ['cont-en','en','english','context','standard'].each do |f| @@texformats[f] = 'cont-en' end + ['cont-nl','nl','dutch'] .each do |f| @@texformats[f] = 'cont-nl' end + ['cont-de','de','german'] .each do |f| @@texformats[f] = 'cont-de' end + ['cont-it','it','italian'] .each do |f| @@texformats[f] = 'cont-it' end + ['cont-fr','fr','french'] .each do |f| @@texformats[f] = 'cont-fr' end + ['cont-cs','cs','cont-cz','cz','czech'] .each do |f| @@texformats[f] = 'cont-cs' end + ['cont-ro','ro','romanian'] .each do |f| @@texformats[f] = 'cont-ro' end + ['cont-gb','gb','cont-uk','uk','british'] .each do |f| @@texformats[f] = 'cont-gb' end + ['cont-pe','pe','persian'] .each do |f| @@texformats[f] = 'cont-pe' end + ['cont-xp','xp','experimental'] .each do |f| @@texformats[f] = 'cont-xp' end + ['mptopdf'] .each do |f| @@texformats[f] = 'mptopdf' end + + ['latex'] .each do |f| @@texformats[f] = 'latex.ltx' end + + ['plain','mpost'] .each do |f| @@mpsformats[f] = 'mpost' end + ['metafun','context','standard'] .each do |f| @@mpsformats[f] = 'metafun' end + + ['pdftex','pdfetex','aleph','omega','petex', + 'xetex','luatex'] .each do |p| @@prognames[p] = 'context' end + ['mpost'] .each do |p| @@prognames[p] = 'metafun' end + ['latex','pdflatex'] .each do |p| @@prognames[p] = 'latex' end + + ['plain','default','standard','mptopdf'] .each do |f| @@texmethods[f] = 'plain' end + ['cont-en','cont-nl','cont-de','cont-it', + 'cont-fr','cont-cs','cont-ro','cont-gb', + 'cont-pe','cont-xp'] .each do |f| @@texmethods[f] = 'context' end + ['latex','pdflatex'] .each do |f| @@texmethods[f] = 'latex' end + + ['plain','default','standard'] .each do |f| @@mpsmethods[f] = 'plain' end + ['metafun'] .each do |f| @@mpsmethods[f] = 'metafun' end + + @@texmakestr['plain'] = @@platformslash + "dump" + @@mpsmakestr['plain'] = @@platformslash + "dump" + + ['cont-en','cont-nl','cont-de','cont-it', + 'cont-fr','cont-cs','cont-ro','cont-gb', + 'cont-pe','cont-xp'] .each do |f| @@texprocstr[f] = @@platformslash + "emergencyend" end + + @@runoptions['aleph'] = ['--8bit'] + @@runoptions['luatex'] = ['--file-line-error'] + @@runoptions['mpost'] = ['--8bit'] + @@runoptions['pdfetex'] = ['--8bit'] # obsolete + @@runoptions['pdftex'] = ['--8bit'] # pdftex is now pdfetex + # @@runoptions['petex'] = [] + @@runoptions['xetex'] = ['--8bit','-output-driver="xdvipdfmx -E -d 4 -V 5"'] + @@draftoptions['pdftex'] = ['--draftmode'] + @@synctexcoptions['pdftex'] = ['--synctex=1'] + @@synctexcoptions['luatex'] = ['--synctex=1'] + @@synctexcoptions['xetex'] = ['--synctex=1'] + + @@tcxflag['aleph'] = true + @@tcxflag['luatex'] = false + @@tcxflag['mpost'] = false + @@tcxflag['pdfetex'] = true + @@tcxflag['pdftex'] = true + @@tcxflag['petex'] = false + @@tcxflag['xetex'] = false + + @@mainbooleanvars = [ + 'batchmode', 'nonstopmode', 'fast', 'final', + 'paranoid', 'notparanoid', 'nobanner', 'once', 'allpatterns', 'draft', + 'nompmode', 'nomprun', 'automprun', 'combine', + 'nomapfiles', 'local', + 'arrange', 'noarrange', + 'forcexml', 'foxet', + 'alpha', 'beta', 'luatex', + 'mpyforce', 'forcempy', + 'forcetexutil', 'texutil', + 'globalfile', 'autopath', + 'purge', 'purgeall', 'keep', 'autopdf', 'xpdf', 'simplerun', 'verbose', + 'nooptionfile', 'nobackend', 'noctx', 'utfbom', + 'mkii','mkiv', + 'synctex', + ] + @@mainstringvars = [ + 'modefile', 'result', 'suffix', 'response', 'path', + 'filters', 'usemodules', 'environments', 'separation', 'setuppath', + 'arguments', 'input', 'output', 'randomseed', 'modes', 'mode', 'filename', + 'ctxfile', 'printformat', 'paperformat', 'paperoffset', + 'timeout', 'passon' + ] + @@mainstandardvars = [ + 'mainlanguage', 'bodyfont', 'language' + ] + @@mainknownvars = [ + 'engine', 'distribution', 'texformats', 'mpsformats', 'progname', 'interface', + 'runs', 'backend' + ] + + @@extrabooleanvars = [] + @@extrastringvars = [] + + def booleanvars + [@@mainbooleanvars,@@extrabooleanvars].flatten.uniq + end + def stringvars + [@@mainstringvars,@@extrastringvars].flatten.uniq + end + def standardvars + [@@mainstandardvars].flatten.uniq + end + def knownvars + [@@mainknownvars].flatten.uniq + end + def allbooleanvars + [@@mainbooleanvars,@@extrabooleanvars].flatten.uniq + end + def allstringvars + [@@mainstringvars,@@extrastringvars,@@mainstandardvars,@@mainknownvars].flatten.uniq + end + + def setextrastringvars(vars) + # @@extrastringvars << vars -- problems in 1.9 + @@extrastringvars = [@@extrastringvars,vars].flatten + end + def setextrabooleanvars(vars) + # @@extrabooleanvars << vars -- problems in 1.9 + @@extrabooleanvars = [@@extrabooleanvars,vars].flatten + end + + # def jobvariables(names=nil) + # if [names ||[]].flatten.size == 0 then + # names = [allbooleanvars,allstringvars].flatten + # end + # data = Hash.new + # names.each do |name| + # if allbooleanvars.include?(name) then + # data[name] = if getvariable(name) then "yes" else "no" end + # else + # data[name] = getvariable(name) + # end + # end + # data + # end + + # def setjobvariables(names=nil) + # assignments = Array.new + # jobvariables(names).each do |k,v| + # assignments << "#{k}=\{#{v}\}" + # end + # "\setvariables[exe][#{assignments.join(", ")}]" + # end + + @@temprunfile = 'texexec' + @@temptexfile = 'texexec.tex' + + def initialize(logger=nil) + if @logger = logger then + def report(str='') + @logger.report(str) + end + else + def report(str='') + puts(str) + end + end + @cleanups = Array.new + @variables = Hash.new + @startuptime = Time.now + # options + booleanvars.each do |k| + setvariable(k,false) + end + stringvars.each do |k| + setvariable(k,'') + end + standardvars.each do |k| + setvariable(k,'standard') + end + setvariable('distribution', Kpse.distribution) + setvariable('texformats', defaulttexformats) + setvariable('mpsformats', defaultmpsformats) + setvariable('progname', 'standard') # or '' + setvariable('interface', 'standard') + setvariable('engine', 'standard') # replaced by tex/mpsengine + setvariable('backend', 'pdftex') + setvariable('runs', '8') + setvariable('randomseed', rand(1440).to_s) # we want the same seed for one run + # files + setvariable('files', []) + # defaults + setvariable('texengine', 'standard') + setvariable('mpsengine', 'standard') + setvariable('backend', 'standard') + setvariable('error', '') + end + + def error? + not getvariable('error').empty? + end + + def runtime + Time.now - @startuptime + end + + def reportruntime + report("runtime: #{runtime}") + end + + def runcommand(something) + command = [something].flatten.join(' ') + report("running: #{command}") if getvariable('verbose') + system(command) + end + + def inspect(name=nil) + if ! name || name.empty? then + name = [booleanvars,stringvars,standardvars,knownvars] + end + str = '' # allocate + [name].flatten.each do |n| + if str = getvariable(n) then + str = str.join(" ") if str.class == Array + unless (str.class == String) && str.empty? then + report("option '#{n}' is set to '#{str}'") + end + end + end + end + + def tempfilename(suffix='') + @@temprunfile + if suffix.empty? then '' else ".#{suffix}" end + end + + def cleanup + @cleanups.each do |name| + begin + File.delete(name) if FileTest.file?(name) + rescue + report("unable to delete #{name}") + end + end + end + + def cleanuptemprunfiles + begin + Dir.glob("#{@@temprunfile}*").each do |name| + if File.file?(name) && (File.splitname(name)[1] !~ /(pdf|dvi)/o) then + File.delete(name) rescue false + end + end + rescue + end + ['mpgraph.mp'].each do |file| + (File.delete(file) if (FileTest.size?(file) rescue 10) < 10) rescue false + end + end + + def backends() @@backends.keys.sort end + + def texengines() @@texengines.keys.sort end + def mpsengines() @@mpsengines.keys.sort end + def texformats() @@texformats.keys.sort end + def mpsformats() @@mpsformats.keys.sort end + + def defaulttexformats() ['en','nl','mptopdf'] end + def defaultmpsformats() ['metafun'] end + + def texmakeextras(format) @@texmakestr[format] || '' end + def mpsmakeextras(format) @@mpsmakestr[format] || '' end + def texprocextras(format) @@texprocstr[format] || '' end + def mpsprocextras(format) @@mpsprocstr[format] || '' end + + def texmethod(format) @@texmethods[str] || @@texmethods['standard'] end + def mpsmethod(format) @@mpsmethods[str] || @@mpsmethods['standard'] end + + def runoptions(engine) + options = if getvariable('draft') then @@draftoptions[engine] else [] end + options = if getvariable('synctex') then @@synctexcoptions[engine] else [] end + begin + if str = getvariable('passon') then + options = [options,str.split(' ')].flatten + end + rescue + end + if @@runoptions.key?(engine) then + [options,@@runoptions[engine]].flatten.join(' ') + else + options.join(' ') + end + end + + # private + + def cleanuplater(name) + begin + @cleanups.push(File.expand_path(name)) + rescue + @cleanups.push(name) + end + end + + def openedfile(name) + begin + f = File.open(name,'w') + rescue + report("file '#{File.expand_path(name)}' cannot be opened for writing") + return nil + else + cleanuplater(name) if f + return f + end + end + + def prefixed(format,engine) + # format + case engine + when /etex|pdftex|pdfetex|aleph|xetex|luatex/io then + "*#{format}" + else + format + end + end + + def quoted(str) + if str =~ /^[^\"].* / then "\"#{str}\"" else str end + end + + def getarrayvariable(str='') + str = getvariable(str) + if str.class == String then str.split(',') else str.flatten end + end + + def validtexformat(str) validsomething(str,@@texformats,'tex') end + def validmpsformat(str) validsomething(str,@@mpsformats,'mp' ) end + def validtexengine(str) validsomething(str,@@texengines,'pdftex') end + def validmpsengine(str) validsomething(str,@@mpsengines,'mpost' ) end + + def validtexmethod(str) [validsomething(str,@@texmethods)].flatten.first end + def validmpsmethod(str) [validsomething(str,@@mpsmethods)].flatten.first end + + def validsomething(str,something,type=nil) + if str then + list = [str].flatten.collect do |s| + if something[s] then + something[s] + elsif type && s =~ /\.#{type}$/ then + s + else + nil + end + end .compact.uniq + if list.length>0 then + if str.class == String then list.first else list end + else + false + end + else + false + end + end + + def validbackend(str) + if str && @@backends.key?(str) then + @@backends[str] + else + @@backends['standard'] + end + end + + def validprogname(str) + if str then + [str].flatten.each do |s| + s = s.sub(/\.\S*/,"") + return @@prognames[s] if @@prognames.key?(s) + end + return str[0].sub(/\.\S*/,"") + else + return nil + end + end + + # we no longer support the & syntax + + def formatflag(engine=nil,format=nil) + case getvariable('distribution') + when 'standard' then prefix = "--fmt" + when /web2c/io then prefix = web2cformatflag(engine) + when /miktex/io then prefix = "--undump" + else return "" + end + if format then + "#{prefix}=#{format.sub(/\.\S+$/,"")}" + else + prefix + end + end + + def web2cformatflag(engine=nil) + # funny that we've standardized on the fmt suffix (at the cost of + # upward compatibility problems) but stuck to the bas/mem/fmt flags + if engine then + case validmpsengine(engine) + when /mpost/ then "-mem" + when /mfont/ then "-bas" + else "-fmt" + end + else + "-fmt" + end + end + + def prognameflag(progname=nil) + case getvariable('distribution') + when 'standard' then prefix = "-progname" + when /web2c/io then prefix = "-progname" + when /miktex/io then prefix = "-alias" + else return "" + end + if progname and not progname.empty? then + "#{prefix}=#{progname}" + else + prefix + end + end + + def iniflag() # should go to kpse and kpse should become texenv + if Kpse.miktex? then + "-initialize" + else + "--ini" + end + end + def tcxflag(engine) + if @@tcxflag[engine] then + file = "natural.tcx" + if Kpse.miktex? then + "-tcx=#{file}" + else + "-translate-file=#{file}" + end + else + "" + end + end + + def filestate(file) + File.mtime(file).strftime("%d/%m/%Y %H:%M:%S") + end + + # will go to context/process context/listing etc + + def contextversion # ook elders gebruiken + filename = Kpse.found('context.tex') + version = 'unknown' + begin + if FileTest.file?(filename) && IO.read(filename).match(/\\contextversion\{(\d+\.\d+\.\d+.*?)\}/) then + version = $1 + end + rescue + end + return version + end + + def cleanupluafiles + File.delete(@@luafiles) rescue false + end + + def compileluafiles + begin + Dir.glob("lua/context/*.luc").each do |luc| + File.delete(luc) rescue false + end + rescue + end + if data = (IO.readlines(@@luafiles) rescue nil) then + report("compiling lua files (using #{File.expand_path(@@luafiles)})") + begin + FileUtils.makedirs(@@luatarget) rescue false + data.each do |line| + luafile = line.chomp + lucfile = File.basename(luafile).gsub(/\..*?$/,'') + ".luc" + if runcommand(["luac","-s","-o",quoted(File.join(Dir.getwd,@@luatarget,lucfile)),quoted(luafile)]) then + report("#{File.basename(luafile)} converted to #{File.basename(lucfile)}") + else + report("#{File.basename(luafile)} not converted to #{File.basename(lucfile)}") + end + end + rescue + report("fatal error in compilation") + end + else + report("no lua compilations needed") + end + File.delete(@@luafiles) rescue false + end + + # we need engine methods + + def makeformats + + checktestversion + + report("using search method '#{Kpse.searchmethod}'") + if getvariable('fast') then + report('using existing database') + else + report('updating file database') + Kpse.update # obsolete here + if getvariable('luatex') then + begin + runcommand(["luatools","--generate","--verbose"]) + rescue + report("run 'luatools --generate' manualy") + exit + end + end + end + # goody + if getvariable('texformats') == 'standard' then + setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty? + end + # prepare + texformats = validtexformat(getarrayvariable('texformats')) + mpsformats = validmpsformat(getarrayvariable('mpsformats')) + texengine = validtexengine(getvariable('texengine')) + mpsengine = validmpsengine(getvariable('mpsengine')) + # save current path + savedpath = Dir.getwd + # generate tex formats + unless texformats || mpsformats then + report('provide valid format (name.tex, name.mp, ...) or format id (metafun, en, nl, ...)') + setvariable('error','no format specified') + end + if texformats && texengine then + report("using tex engine #{texengine}") + texformatpath = if getvariable('local') then '.' else Kpse.formatpath(texengine,true) end + # can be empty, to do + report("using tex format path #{texformatpath}") + Dir.chdir(texformatpath) rescue false + if FileTest.writable?(texformatpath) then + # from now on we no longer support this; we load + # all patterns and if someone wants another + # interface language ... cook up a fmt or usr file + # + # if texformats.length > 0 then + # makeuserfile + # makeresponsefile + # end + if texengine == 'luatex' then + cleanupluafiles + texformats.each do |texformat| + report("generating tex format #{texformat}") + flags = ['--ini','--compile'] + flags << '--verbose' if getvariable('verbose') + flags << '--mkii' if getvariable('mkii') + run_luatools("#{flags.join(" ")} #{texformat}") + end + compileluafiles + else + texformats.each do |texformat| + report("generating tex format #{texformat}") + progname = validprogname([getvariable('progname'),texformat,texengine]) + runcommand([quoted(texengine),prognameflag(progname),iniflag,tcxflag(texengine),prefixed(texformat,texengine),texmakeextras(texformat)]) + end + end + else + report("unable to make format due to lack of permissions") + texformatpath = '' + setvariable('error','no permissions to write') + end + if not mpsformats then + # we want metafun to be in sync + setvariable('mpsformats',defaultmpsformats) + mpsformats = validmpsformat(getarrayvariable('mpsformats')) + end + else + texformatpath = '' + end + # generate mps formats + if mpsformats && mpsengine then + report("using mp engine #{mpsengine}") + mpsformatpath = if getvariable('local') then '.' else Kpse.formatpath(mpsengine,false) end + report("using mps format path #{mpsformatpath}") + Dir.chdir(mpsformatpath) rescue false + if FileTest.writable?(mpsformatpath) then + mpsformats.each do |mpsformat| + report("generating mps format #{mpsformat}") + progname = validprogname([getvariable('progname'),mpsformat,mpsengine]) + # if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,tcxflag(mpsengine),runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then + if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then + setvariable('error','no format made') + end + end + else + report("unable to make format due to lack of permissions") + mpsformatpath = '' + setvariable('error','file permission problem') + end + else + mpsformatpath = '' + end + # check for problems + report("") + report("tex engine path: #{texformatpath}") unless texformatpath.empty? + report("mps engine path: #{mpsformatpath}") unless mpsformatpath.empty? + report("") + [['fmt','tex'],['mem','mps']].each do |f| + [[texformatpath,'global'],[mpsformatpath,'global'],[savedpath,'current']].each do |p| + begin + Dir.chdir(p[0]) + rescue + else + Dir.glob("*.#{f[0]}").each do |file| + report("#{f[1]}: #{filestate(file)} > #{File.expand_path(file)} (#{File.size(file)})") + end + end + end + end + begin + lucdir = File.join(texformatpath,@@luatarget) + Dir.chdir(lucdir) + rescue + else + Dir.glob("*.luc").each do |file| + report("luc: #{filestate(file)} > #{File.expand_path(file)} (#{File.size(file)})") + end + end + # to be sure, go back to current path + begin + Dir.chdir(savedpath) + rescue + end + # finalize + cleanup + report("") + reportruntime + end + + def checkcontext + + # todo : report texmf.cnf en problems + + # basics + report("current distribution: #{Kpse.distribution}") + report("context source date: #{contextversion}") + formatpaths = Kpse.formatpaths + globpattern = "**/{#{formatpaths.join(',')}}/*/*.{fmt,efmt,ofmt,xfmt,mem}" + report("format path: #{formatpaths.join(' ')}") + # utilities + report('start of analysis') + results = Array.new + # ['texexec','texutil','ctxtools'].each do |program| + ['texexec'].each do |program| + result = `texmfstart #{program} --help` + result.sub!(/.*?(#{program}[^\n]+)\n.*/mi) do $1 end + results.push("#{result}") + end + # formats + cleanuptemprunfiles + if formats = Dir.glob(globpattern) then + formats.sort.each do |name| + cleanuptemprunfiles + if f = open(tempfilename('tex'),'w') then + # kind of aleph-run-out-of-par safe + f << "\\starttext\n" + f << " \\relax test \\relax\n" + f << "\\stoptext\n" + f << "\\endinput\n" + f.close + if FileTest.file?(tempfilename('tex')) then + format = File.basename(name) + engine = if name =~ /(pdftex|pdfetex|aleph|xetex|luatex)[\/\\]#{format}/ then $1 else '' end + if engine.empty? then + engineflag = "" + else + engineflag = "--engine=#{$1}" + end + case format + when /cont\-([a-z]+)/ then + interface = $1.sub(/cont\-/,'') + results.push('') + results.push("testing interface #{interface}") + flags = ['--noctx','--process','--batch','--once',"--interface=#{interface}",engineflag] + # result = Kpse.pipescript('texexec',tempfilename,flags) + result = runtexexec([tempfilename], flags, 1) + if FileTest.file?("#{@@temprunfile}.log") then + logdata = IO.read("#{@@temprunfile}.log") + if logdata =~ /^\s*This is (.*?)[\s\,]+(.*?)$/moi then + if validtexengine($1.downcase) then + results.push("#{$1} #{$2.gsub(/\(format.*$/,'')}".strip) + end + end + if logdata =~ /^\s*(ConTeXt)\s+(.*int:\s+[a-z]+.*?)\s*$/moi then + results.push("#{$1} #{$2}".gsub(/\s+/,' ').strip) + end + else + results.push("format #{format} does not work") + end + when /metafun/ then + # todo + when /mptopdf/ then + # todo + end + else + results.push("error in creating #{tempfilename('tex')}") + end + end + cleanuptemprunfiles + end + end + report('end of analysis') + report + results.each do |line| + report(line) + end + cleanuptemprunfiles + + end + + private + + def makeuserfile # not used in luatex (yet) + language = getvariable('language') + mainlanguage = getvariable('mainlanguage') + bodyfont = getvariable('bodyfont') + if f = openedfile("cont-fmt.tex") then + f << "\\unprotect\n" + case language + when 'all' then + f << "\\preloadallpatterns\n" + when '' then + f << "% no language presets\n" + when 'standard' + f << "% using defaults\n" + else + languages = language.split(',') + languages.each do |l| + f << "\\installlanguage[\\s!#{l}][\\c!state=\\v!start]\n" + end + mainlanguage = languages.first + end + unless mainlanguage == 'standard' then + f << "\\setupcurrentlanguage[\\s!#{mainlanguage}]\n"; + end + unless bodyfont == 'standard' then + # ~ will become obsolete when lmr is used + f << "\\definetypescriptsynonym[cmr][#{bodyfont}]" + # ~ is already obsolete for some years now + f << "\\definefilesynonym[font-cmr][font-#{bodyfont}]\n" + end + f << "\\protect\n" + f << "\\endinput\n" + f.close + end + end + + def makeresponsefile + interface = getvariable('interface') + if f = openedfile("mult-def.tex") then + case interface + when 'standard' then + f << "% using default response interface" + else + f << "\\def\\currentresponses\{#{interface}\}\n" + end + f << "\\endinput\n" + f.close + end + end + + private # will become baee/context + + @@preamblekeys = [ + ['tex','texengine'], + ['engine','texengine'], + ['program','texengine'], + ['translate','tcxfilter'], + ['tcx','tcxfilter'], + ['output','backend'], + ['mode','mode'], + ['ctx','ctxfile'], + ['version','contextversion'], + ['format','texformats'], + ['interface','texformats'], + ] + + @@re_utf_bom = /^\357\273\277/o + + def scantexpreamble(filename) + begin + if FileTest.file?(filename) and tex = File.open(filename,'rb') then + bomdone = false + while str = tex.gets and str.chomp! do + unless bomdone then + if str.sub!(@@re_utf_bom, '') + report("utf mode forced (bom found)") + setvariable('utfbom',true) + end + bomdone = true + end + if str =~ /^\%\s*(.*)/o then + # we only accept lines with key=value pairs + vars, ok = Hash.new, true + $1.split(/\s+/o).each do |s| + k, v = s.split('=') + if k && v then + vars[k] = v + else + ok = false + break + end + end + if ok then + # we have a valid line + + @@preamblekeys.each do |v| + setvariable(v[1],vars[v[0]]) if vars.key?(v[0]) && vars[v[0]] + end + +if getvariable('given.backend') == "standard" or getvariable('given.backend') == "" then + setvariable('backend',@@backends[getvariable('texengine')] || 'standard') +end + break + end + else + break + end + end + tex.close + end + rescue + # well, let's not worry too much + end + end + + def scantexcontent(filename) + if FileTest.file?(filename) and tex = File.open(filename,'rb') then + while str = tex.gets do + case str.chomp + when /^\%/o then + # next + # when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then + when /\\(starttekst|stoptekst|startonderdeel|startoverzicht)/o then + setvariable('texformats','nl') ; break + when /\\(stelle|verwende|umgebung|benutze)/o then + setvariable('texformats','de') ; break + when /\\(stel|gebruik|omgeving)/o then + setvariable('texformats','nl') ; break + when /\\(use|setup|environment)/o then + setvariable('texformats','en') ; break + when /\\(usa|imposta|ambiente)/o then + setvariable('texformats','it') ; break + when /(height|width|style)=/o then + setvariable('texformats','en') ; break + when /(hoehe|breite|schrift)=/o then + setvariable('texformats','de') ; break + when /(hoogte|breedte|letter)=/o then + setvariable('texformats','nl') ; break + when /(altezza|ampiezza|stile)=/o then + setvariable('texformats','it') ; break + when /externfiguur/o then + setvariable('texformats','nl') ; break + when /externalfigure/o then + setvariable('texformats','en') ; break + when /externeabbildung/o then + setvariable('texformats','de') ; break + when /figuraesterna/o then + setvariable('texformats','it') ; break + end + end + tex.close + end + + end + + private # will become base/context + + def pushresult(filename,resultname) + fname = File.unsuffixed(filename) + rname = File.unsuffixed(resultname) + if ! rname.empty? && (rname != fname) then + report("outputfile #{rname}") + ['tuo','tuc','log','dvi','pdf'].each do |s| + File.silentrename(File.suffixed(fname,s),File.suffixed('texexec',s)) + end + ['tuo','tuc'].each do |s| + File.silentrename(File.suffixed(rname,s),File.suffixed(fname,s)) if FileTest.file?(File.suffixed(rname,s)) + end + end + end + + def popresult(filename,resultname) + fname = File.unsuffixed(filename) + rname = File.unsuffixed(resultname) + if ! rname.empty? && (rname != fname) then + report("renaming #{fname} to #{rname}") + ['tuo','tuc','log','dvi','pdf'].each do |s| + File.silentrename(File.suffixed(fname,s),File.suffixed(rname,s)) + end + report("restoring #{fname}") + unless $fname == 'texexec' then + ['tuo','tuc','log','dvi','pdf'].each do |s| + File.silentrename(File.suffixed('texexec',s),File.suffixed(fname,s)) + end + end + end + end + + def makestubfile(rawname,rawbase,forcexml=false) + if tmp = openedfile(File.suffixed(rawbase,'run')) then + tmp << "\\starttext\n" + if forcexml then + # tmp << checkxmlfile(rawname) + if getvariable('mkiv') then + tmp << "\\xmlprocess{\\xmldocument}{#{rawname}}{}\n" + else + tmp << "\\processXMLfilegrouped{#{rawname}}\n" + end + else + tmp << "\\processfile{#{rawname}}\n" + end + tmp << "\\stoptext\n" + tmp.close + return "run" + else + return File.splitname(rawname)[1] + end + end + + # def checkxmlfile(rawname) + # tmp = '' + # if FileTest.file?(rawname) && (xml = File.open(rawname)) then + # xml.each do |line| + # case line + # when /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then + # category, key, value, rest = $1, $2, $3, $4 + # case category + # when 'job' then + # case key + # when 'control' then + # setvariable(value,if rest.empty? then true else rest end) + # when 'mode', 'modes' then + # tmp << "\\enablemode[#{value}]\n" + # when 'stylefile', 'environment' then + # tmp << "\\environment #{value}\n" + # when 'module' then + # tmp << "\\usemodule[#{value}]\n" + # when 'interface' then + # contextinterface = value + # when 'ctxfile' then + # setvariable('ctxfile', value) + # report("using source driven ctxfile #{value}") + # end + # end + # when /<[a-z]+/io then # beware of order, first pi test + # break + # end + # end + # xml.close + # end + # return tmp + # end + + def extendvariable(name,value) + set = getvariable(name).split(',') + set << value + str = set.uniq.join(',') + setvariable(name,str) + end + + def checkxmlfile(rawname) + if FileTest.file?(rawname) && (xml = File.open(rawname,'rb')) then + xml.each do |line| + case line + when /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then + category, key, value, rest = $1, $2, $3, $4 + case category + when 'job' then + case key + when 'control' then + setvariable(value,if rest.empty? then true else rest end) + when /^(mode)(s|)$/ then + extendvariable('modes',value) + when /^(stylefile|environment)(s|)$/ then + extendvariable('environments',value) + when /^(use|)(module)(s|)$/ then + extendvariable('usemodules',value) + when /^(filter)(s|)$/ then + extendvariable('filters',value) + when 'interface' then + contextinterface = value + when 'ctxfile' then + setvariable('ctxfile', value) + report("using source driven ctxfile #{value}") + end + end + when /<[a-z]+/io then # beware of order, first pi test + break + end + end + xml.close + end + end + +end + +class TEX + + def timedrun(delay, &block) + delay = delay.to_i rescue 0 + if delay > 0 then + begin + report("job started with timeout '#{delay}'") + timeout(delay) do + yield block + end + rescue TimeoutError + report("job aborted due to timeout '#{delay}'") + setvariable('error','timeout') + rescue + report("job aborted due to error") + setvariable('error','fatal error') + else + report("job finished within timeout '#{delay}'") + end + else + yield block + end + end + + def processtex # much to do: mp, xml, runs etc + setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty? + getarrayvariable('files').each do |filename| + setvariable('filename',filename) + report("processing document '#{filename}'") + timedrun(getvariable('timeout')) do + processfile + end + end + reportruntime + end + + def processmptex + getarrayvariable('files').each do |filename| + setvariable('filename',filename) + report("processing graphic '#{filename}'") + runtexmp(filename) + end + reportruntime + end + + private + + def load_map_files(filename) # tui basename + # c \usedmapfile{=}{lm-texnansi} + begin + str = "" + IO.read(filename).scan(/^c\s+\\usedmapfile\{(.*?)\}\{(.*?)\}\s*$/o) do + str << "\\loadmapfile[#{$2}.map]\n" + end + rescue + return "" + else + return str + end + end + + public + + # def run_luatools(args) + # dirty trick: we know that the lua path is relative to the ruby path; of course this + # will not work well when stubs are used + # [(ENV["_CTX_K_S_texexec_"] or ENV["_CTX_K_S_THREAD_"] or ENV["TEXMFSTART.THREAD"]), File.dirname($0)].each do |path| + # if path then + # script = "#{path}/../lua/luatools.lua" + # if FileTest.file?(script) then + # return runcommand("luatex --luaonly #{script} #{args}") + # end + # end + # end + # return runcommand("texmfstart luatools #{args}") + # end + + def run_luatools(args) + return runcommand("luatools #{args}") + end + + def processmpgraphic + getarrayvariable('files').each do |filename| + setvariable('filename',filename) + report("processing graphic '#{filename}'") + runtexmp(filename,'',false) # no purge + mapspecs = load_map_files(File.suffixed(filename,'temp','tui')) + unless getvariable('keep') then + # not enough: purge_mpx_files(filename) + Dir.glob(File.suffixed(filename,'temp*','*')).each do |fname| + File.delete(fname) unless File.basename(filename) == File.basename(fname) + end + end + begin + data = IO.read(File.suffixed(filename,'log')) + basename = filename.sub(/\.mp$/, '') + if data =~ /output files* written\:\s*(.*)$/moi then + files, number, range, list = $1.split(/\s+/), 0, false, [] + files.each do |fname| + if fname =~ /^.*\.(\d+)$/ then + if range then + (number+1 .. $1.to_i).each do |i| + list << i + end + range = false + else + number = $1.to_i + list << number + end + elsif fname =~ /\.\./ then + range = true + else + range = false + next + end + end + begin + if getvariable('combine') then + fullname = "#{basename}.#{number}" + File.open("texexec.tex",'w') do |f| + f << "\\setupoutput[pdftex]\n" + f << "\\setupcolors[state=start]\n" + f << mapspecs + f << "\\starttext\n" + list.each do |number| + f << "\\startTEXpage\n" + f << "\\convertMPtoPDF{#{fullname}}{1}{1}" + f << "\\stopTEXpage\n" + end + f << "\\stoptext\n" + end + report("converting graphic '#{fullname}'") + runtex("texexec.tex") + pdffile = File.suffixed(basename,'pdf') + File.silentrename("texexec.pdf",pdffile) + report ("#{basename}.* converted to #{pdffile}") + else + list.each do |number| + begin + fullname = "#{basename}.#{number}" + File.open("texexec.tex",'w') do |f| + f << "\\setupoutput[pdftex]\n" + f << "\\setupcolors[state=start]\n" + f << mapspecs + f << "\\starttext\n" + f << "\\startTEXpage\n" + f << "\\convertMPtoPDF{#{fullname}}{1}{1}" + f << "\\stopTEXpage\n" + f << "\\stoptext\n" + end + report("converting graphic '#{fullname}'") + runtex("texexec.tex") + if files.length>1 then + pdffile = File.suffixed(basename,number.to_s,'pdf') + else + pdffile = File.suffixed(basename,'pdf') + end + File.silentrename("texexec.pdf",pdffile) + report ("#{fullname} converted to #{pdffile}") + end + end + end + rescue + report ("error when converting #{fullname} (#{$!})") + end + end + rescue + report("error in converting #{filename}") + end + end + reportruntime + end + + def processmpstatic + if filename = getvariable('filename') then + filename += ".mp" unless filename =~ /\..+?$/ + if FileTest.file?(filename) then + begin + data = IO.read(filename) + File.open("texexec.tex",'w') do |f| + f << "\\setupoutput[pdftex]\n" + f << "\\setupcolors[state=start]\n" + data.sub!(/^%mpenvironment\:\s*(.*?)$/moi) do + f << $1 + "\n" + end + f << "\\starttext\n" + f << "\\startMPpage\n" + f << data.gsub(/end\.*\s*$/m, '') # a bit of a hack + f << "\\stopMPpage\n" + f << "\\stoptext\n" + end + report("converting static '#{filename}'") + runtex("texexec.tex") + pdffile = File.suffixed(filename,'pdf') + File.silentrename("texexec.pdf",pdffile) + report ("#{filename} converted to #{pdffile}") + rescue + report("error in converting #{filename} (#{$!}") + end + end + end + reportruntime + end + + def processmpxtex + getarrayvariable('files').each do |filename| + setvariable('filename',filename) + report("processing text of graphic '#{filename}'") + processmpx(filename,false,true,true) + end + reportruntime + end + + def deleteoptionfile(rawname) + ['top','top.keep'].each do |suffix| + begin + File.delete(File.suffixed(rawname,suffix)) + rescue + end + end + end + + def makeoptionfile(rawname, jobname, jobsuffix, finalrun, fastdisabled, kindofrun, currentrun=1) + begin + # jobsuffix = orisuffix + if topname = File.suffixed(rawname,'top') and opt = File.open(topname,'w') then + report("writing option file #{topname}") + # local handies + opt << "\% #{topname}\n" + opt << "\\unprotect\n" + # + # feedback and basic control + # + if getvariable('batchmode') then + opt << "\\batchmode\n" + end + if getvariable('nonstopmode') then + opt << "\\nonstopmode\n" + end + if getvariable('paranoid') then + opt << "\\def\\maxreadlevel{1}\n" + end + if getvariable('nomapfiles') then + opt << "\\disablemapfiles\n" + end + if getvariable('nompmode') || getvariable('nomprun') || getvariable('automprun') then + opt << "\\runMPgraphicsfalse\n" + end + if getvariable('utfbom') then + opt << "\\enableregime[utf]" + end + progname = validprogname(['metafun']) # [getvariable('progname'),mpsformat,mpsengine] + opt << "\\def\\MPOSTformatswitch\{#{prognameflag(progname)} #{formatflag('mpost')}=\}\n" + # + # process info + # + opt << "\\setupsystem[\\c!n=#{kindofrun},\\c!m=#{currentrun}]\n" + if (str = File.unixfied(getvariable('modefile'))) && ! str.empty? then + opt << "\\readlocfile{#{str}}{}{}\n" + end + if (str = File.unixfied(getvariable('result'))) && ! str.empty? then + opt << "\\setupsystem[file=#{str}]\n" + elsif (str = getvariable('suffix')) && ! str.empty? then + opt << "\\setupsystem[file=#{jobname}.#{str}]\n" + end + opt << "\\setupsystem[\\c!method=2]\n" # 1=oldtexexec 2=newtexexec (obsolete) + opt << "\\setupsystem[\\c!type=#{Tool.ruby_platform()}]\n" + if (str = File.unixfied(getvariable('path'))) && ! str.empty? then + opt << "\\usepath[#{str}]\n" unless str.empty? + end + if (str = getvariable('mainlanguage').downcase) && ! str.empty? && ! str.standard? then + opt << "\\setuplanguage[#{str}]\n" + end + if (str = getvariable('arguments')) && ! str.empty? then + opt << "\\setupenv[#{str}]\n" + end + if (str = getvariable('setuppath')) && ! str.empty? then + opt << "\\setupsystem[\\c!directory=\{#{str}\}]\n" + end + if (str = getvariable('randomseed')) && ! str.empty? then + report("using randomseed #{str}") + opt << "\\setupsystem[\\c!random=#{str}]\n" + end + if (str = getvariable('input')) && ! str.empty? then + opt << "\\setupsystem[inputfile=#{str}]\n" + else + opt << "\\setupsystem[inputfile=#{rawname}]\n" + end + # + # modes + # + # we handle both "--mode" and "--modes", else "--mode" is mapped onto "--modefile" + if (str = getvariable('modes')) && ! str.empty? then + opt << "\\enablemode[#{str}]\n" + end + if (str = getvariable('mode')) && ! str.empty? then + opt << "\\enablemode[#{str}]\n" + end + # + # options + # + opt << "\\startsetups *runtime:options\n" + if str = validbackend(getvariable('backend')) then + opt << "\\setupoutput[#{str}]\n" + elsif str = validbackend(getvariable('output')) then + opt << "\\setupoutput[#{str}]\n" + end + if getvariable('color') then + opt << "\\setupcolors[\\c!state=\\v!start]\n" + end + if (str = getvariable('separation')) && ! str.empty? then + opt << "\\setupcolors[\\c!split=#{str}]\n" + end + if (str = getvariable('paperformat')) && ! str.empty? && ! str.standard? then + if str =~ /^([a-z]+\d+)([a-z]+\d+)$/io then # A5A4 A4A3 A2A1 ... + opt << "\\setuppapersize[#{$1.upcase}][#{$2.upcase}]\n" + else # ...*... + pf = str.upcase.split(/[x\*]/o) + pf << pf[0] if pf.size == 1 + opt << "\\setuppapersize[#{pf[0]}][#{pf[1]}]\n" + end + end + if (str = getvariable('background')) && ! str.empty? then + opt << "\\defineoverlay[whatever][{\\externalfigure[#{str}][\\c!factor=\\v!max]}]\n" + opt << "\\setupbackgrounds[\\v!page][\\c!background=whatever]\n" + end + if getvariable('centerpage') then + opt << "\\setuplayout[\\c!location=\\v!middle,\\c!marking=\\v!on]\n" + end + if getvariable('noarrange') then + opt << "\\setuparranging[\\v!disable]\n" + elsif getvariable('arrange') then + arrangement = Array.new + if finalrun then + arrangement << "\\v!doublesided" unless getvariable('noduplex') + case getvariable('printformat') + when '' then arrangement << "\\v!normal" + when /.*up/oi then arrangement << ["2UP","\\v!rotated"] + when /.*down/oi then arrangement << ["2DOWN","\\v!rotated"] + when /.*side/oi then arrangement << ["2SIDE","\\v!rotated"] + end + else + arrangement << "\\v!disable" + end + opt << "\\setuparranging[#{arrangement.flatten.join(',')}]\n" if arrangement.size > 0 + end + if (str = getvariable('pages')) && ! str.empty? then + if str.downcase == 'odd' then + opt << "\\chardef\\whichpagetoshipout=1\n" + elsif str.downcase == 'even' then + opt << "\\chardef\\whichpagetoshipout=2\n" + else + pagelist = Array.new + str.split(/\,/).each do |page| + pagerange = page.split(/\D+/o) + if pagerange.size > 1 then + pagerange.first.to_i.upto(pagerange.last.to_i) do |p| + pagelist << p.to_s + end + else + pagelist << page + end + end + opt << "\\def\\pagestoshipout\{#{pagelist.join(',')}\}\n"; + end + end + opt << "\\stopsetups\n" + # + # styles and modules + # + opt << "\\startsetups *runtime:modules\n" + begin getvariable('filters' ).split(',').uniq.each do |f| opt << "\\useXMLfilter[#{f}]\n" end ; rescue ; end + begin getvariable('usemodules' ).split(',').uniq.each do |m| opt << "\\usemodule [#{m}]\n" end ; rescue ; end + begin getvariable('environments').split(',').uniq.each do |e| opt << "\\environment #{e} \n" end ; rescue ; end + opt << "\\stopsetups\n" + # + opt << "\\protect \\endinput\n" + # + opt.close + else + report("unable to write option file #{topname}") + end + rescue + report("fatal error in writing option file #{topname} (#{$!})") + end + end + + def takeprecautions + ENV['MPXCOMAND'] = '0' # else loop + if getvariable('paranoid') then + ENV['SHELL_ESCAPE'] = ENV['SHELL_ESCAPE'] || 'f' + ENV['OPENOUT_ANY'] = ENV['OPENOUT_ANY'] || 'p' + ENV['OPENIN_ANY'] = ENV['OPENIN_ANY'] || 'p' + elsif getvariable('notparanoid') then + ENV['SHELL_ESCAPE'] = ENV['SHELL_ESCAPE'] || 't' + ENV['OPENOUT_ANY'] = ENV['OPENOUT_ANY'] || 'a' + ENV['OPENIN_ANY'] = ENV['OPENIN_ANY'] || 'a' + end + if ENV['OPENIN_ANY'] && (ENV['OPENIN_ANY'] == 'p') then # first test redundant + setvariable('paranoid', true) + end + if ENV.key?('SHELL_ESCAPE') && (ENV['SHELL_ESCAPE'] == 'f') then + setvariable('automprun',true) + end + done = false + ['TXRESOURCES','MPRESOURCES','MFRESOURCES'].each do |res| + [getvariable('runpath'),getvariable('path')].each do |pat| + unless pat.empty? then + if ENV.key?(res) then + # ENV[res] = if ENV[res].empty? then pat else pat + ":" + ENV[res] end +if ENV[res].empty? then + ENV[res] = pat +elsif ENV[res] == pat || ENV[res] =~ /^#{pat}\:/ || ENV[res] =~ /\:#{pat}\:/ then + # skip +else + ENV[res] = pat + ":" + ENV[res] +end + else + ENV[res] = pat + end + report("setting #{res} to #{ENV[res]}") unless done + end + end + done = true + end + end + + def checktestversion + # + # one can set TEXMFALPHA and TEXMFBETA for test versions + # but keep in mind that the format as well as the test files + # then need the --alpha or --beta flag + # + done, tree = false, '' + ['alpha', 'beta'].each do |what| + if getvariable(what) then + if ENV["TEXMF#{what.upcase}"] then + done, tree = true, ENV["TEXMF#{what.upcase}"] + elsif ENV["TEXMFLOCAL"] then + done, tree = true, File.join(File.dirname(ENV['TEXMFLOCAL']), "texmf-#{what}") + end + end + break if done + end + if done then + tree = tree.strip + ENV['TEXMFPROJECT'] = tree + report("using test tree '#{tree}'") + ['MP', 'MF', 'TX'].each do |ctx| + ENV['CTXDEV#{ctx}PATH'] = '' + end + unless (FileTest.file?(File.join(tree,'ls-r')) || FileTest.file?(File.join(tree,'ls-R'))) then + report("no ls-r/ls-R file for tree '#{tree}' (run: mktexlsr #{tree})") + end + end + # puts `kpsewhich --expand-path=$TEXMF` + # exit + end + + def runtex(filename) + checktestversion + texengine = validtexengine(getvariable('texengine')) + texformat = validtexformat(getarrayvariable('texformats').first) + report("tex engine: #{texengine}") + report("tex format: #{texformat}") + if texengine && texformat then + fixbackendvars(@@mappaths[texengine]) + if texengine == "luatex" then + # currently we use luatools to start luatex but some day we should + # find a clever way to directly call luatex (problem is that we need + # to feed the explicit location of the format and lua initialization + # file) + run_luatools("--fmt=#{texformat} #{filename}") + else + progname = validprogname([getvariable('progname'),texformat,texengine]) + runcommand([quoted(texengine),prognameflag(progname),formatflag(texengine,texformat),tcxflag(texengine),runoptions(texengine),filename,texprocextras(texformat)]) + end + # true + else + false + end + end + + def runmp(mpname,mpx=false) + checktestversion + mpsengine = validmpsengine(getvariable('mpsengine')) + mpsformat = validmpsformat(getarrayvariable('mpsformats').first) + if mpsengine && mpsformat then + ENV["MPXCOMMAND"] = "0" unless mpx + progname = validprogname([getvariable('progname'),mpsformat,mpsengine]) + mpname.gsub!(/\.mp$/,"") # temp bug in mp + # runcommand([quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),tcxflag(mpsengine),runoptions(mpsengine),mpname,mpsprocextras(mpsformat)]) + runcommand([quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),runoptions(mpsengine),mpname,mpsprocextras(mpsformat)]) + true + else + false + end + end + + def runtexmp(filename,filetype='',purge=true) + checktestversion + mpname = File.suffixed(filename,filetype,'mp') + if File.atleast?(mpname,10) then + # first run needed + File.silentdelete(File.suffixed(mpname,'mpt')) + doruntexmp(mpname,nil,true,purge) + mpgraphics = checkmpgraphics(mpname) + mplabels = checkmplabels(mpname) + if mpgraphics || mplabels then + # second run needed + doruntexmp(mpname,mplabels,true,purge) + else + # no labels + end + end + end + + def runtexmpjob(filename,filetype='') + checktestversion + mpname = File.suffixed(filename,filetype,'mp') + if File.atleast?(mpname,25) && (data = File.silentread(mpname)) then + textranslation = if data =~ /^\%\s+translate.*?\=([\w\d\-]+)/io then $1 else '' end + mpjobname = if data =~ /collected graphics of job \"(.+?)\"/io then $1 else '' end + if ! mpjobname.empty? and File.unsuffixed(filename) =~ /#{mpjobname}/ then # don't optimize + options = Array.new + options.push("--mptex") + options.push("--nomp") + options.push("--mpyforce") if getvariable('forcempy') || getvariable('mpyforce') + options.push("--translate=#{textranslation}") unless textranslation.empty? + options.push("--batch") if getvariable('batchmode') + options.push("--nonstop") if getvariable('nonstopmode') + options.push("--output=ps") # options.push("--dvi") + options.push("--nobackend") + return runtexexec(mpname,options,2) + end + end + return false + end + + def runtexutil(filename=[], options=['--ref','--ij','--high'], old=false) + [filename].flatten.each do |fname| + if old then + Kpse.runscript('texutil',fname,options) + else + begin + logger = Logger.new('TeXUtil') + if tu = TeXUtil::Converter.new(logger) and tu.loaded(fname) then + ok = tu.processed && tu.saved && tu.finalized + end + rescue + Kpse.runscript('texutil',fname,options) + end + end + end + end + + def runluacheck(jobname) + if false then + # test-pos.tex / 6 meg tua file: 18.6 runtime + old, new = File.suffixed(jobname,'tua'), File.suffixed(jobname,'tuc') + if FileTest.file?(old) then + report("converting #{old} into #{new}") + system("luac -s -o #{new} #{old}") + end + else + # test-pos.tex / 6 meg tua file: 17.5 runtime + old, new = File.suffixed(jobname,'tua'), File.suffixed(jobname,'tuc') + if FileTest.file?(old) then + report("renaming #{old} into #{new}") + File.rename(old,new) rescue false + end + end + end + + # 1=tex 2=mptex 3=mpxtex 4=mpgraphic 5=mpstatic + + def runtexexec(filename=[], options=[], mode=nil) + begin + if mode and job = TEX.new(@logger) then + options.each do |option| + case option + when /^\-*(.*?)\=(.*)$/o then + job.setvariable($1,$2) + when /^\-*(.*?)$/o then + job.setvariable($1,true) + end + end + job.setvariable("files",filename) + case mode + when 1 then job.processtex + when 2 then job.processmptex + when 3 then job.processmpxtex + when 4 then job.processmpgraphic + when 5 then job.processmpstatic + end + job.inspect && Kpse.inspect if getvariable('verbose') + return true + else + Kpse.runscript('texexec',filename,options) + end + rescue + Kpse.runscript('texexec',filename,options) + end + end + + def fixbackendvars(backend) + if backend then + ENV['backend'] = backend ; + ENV['progname'] = backend unless validtexengine(backend) + ENV['TEXFONTMAPS'] = ['.',"\$TEXMF/fonts/{data,map}/{#{backend},pdftex,dvips,}//",'./fonts//'].join_path + report("fixing backend map path for #{backend}: #{ENV['TEXFONTMAPS']}") if getvariable('verbose') + else + report("unable to fix backend map path") if getvariable('verbose') + end + end + + def runbackend(rawname) + unless getvariable('nobackend') then + case validbackend(getvariable('backend')) + when 'dvipdfmx' then + fixbackendvars('dvipdfm') + runcommand("dvipdfmx -d 4 -V 5 #{File.unsuffixed(rawname)}") + when 'xetex' then + # xetex now runs its own backend + xdvfile = File.suffixed(rawname,'xdv') + if FileTest.file?(xdvfile) then + fixbackendvars('dvipdfm') + runcommand("xdvipdfmx -q -d 4 -V 5 -E #{xdvfile}") + end + when 'xdv2pdf' then + xdvfile = File.suffixed(rawname,'xdv') + if FileTest.file?(xdvfile) then + fixbackendvars('xdv2pdf') + runcommand("xdv2pdf #{xdvfile}") + end + when 'dvips' then + fixbackendvars('dvips') + mapfiles = '' + begin + if tuifile = File.suffixed(rawname,'tui') and FileTest.file?(tuifile) then + IO.read(tuifile).scan(/^c \\usedmapfile\{.\}\{(.*?)\}\s*$/o) do + mapfiles += "-u +#{$1} " ; + end + end + rescue + mapfiles = '' + end + runcommand("dvips #{mapfiles} #{File.unsuffixed(rawname)}") + when 'pdftex' then + # no need for postprocessing + else + report("no postprocessing needed") + end + end + end + + def processfile + + takeprecautions + report("using search method '#{Kpse.searchmethod}'") if getvariable('verbose') + + rawname = getvariable('filename') + jobname = getvariable('filename') + + if getvariable('autopath') then + jobname = File.basename(jobname) + inppath = File.dirname(jobname) + else + inppath = '' + end + + jobname, jobsuffix = File.splitname(jobname,'tex') + + jobname = File.unixfied(jobname) + inppath = File.unixfied(inppath) + + orisuffix = jobsuffix # still needed ? + + if jobsuffix =~ /^(htm|html|xhtml|xml|fo|fox|rlg|exa)$/io then + setvariable('forcexml',true) + end + + dummyfile = false + + # fuzzy code snippet: (we kunnen kpse: prefix gebruiken) + + unless FileTest.file?(File.suffixed(jobname,jobsuffix)) then + if FileTest.file?(rawname + '.tex') then + jobname = rawname.dup + jobsuffix = 'tex' + end + end + + # we can have funny names, like 2005.10.10 (given without suffix) + + rawname = jobname + '.' + jobsuffix + rawpath = File.dirname(rawname) + rawbase = File.basename(rawname) + + unless FileTest.file?(rawname) then + inppath.split(',').each do |ip| + break if dummyfile = FileTest.file?(File.join(ip,rawname)) + end + end + + forcexml = getvariable('forcexml') + + if dummyfile || forcexml then # after ctx? + jobsuffix = makestubfile(rawname,rawbase,forcexml) + checkxmlfile(rawname) + end + + # preprocess files + + unless getvariable('noctx') then + ctx = CtxRunner.new(rawname,@logger) + if pth = getvariable('path') then + pth.split(',').each do |p| + ctx.register_path(p) + end + end + if getvariable('ctxfile').empty? then + if rawname == rawbase then + ctx.manipulate(File.suffixed(rawname,'ctx'),'jobname.ctx') + else + ctx.manipulate(File.suffixed(rawname,'ctx'),File.join(rawpath,'jobname.ctx')) + end + else + ctx.manipulate(File.suffixed(getvariable('ctxfile'),'ctx')) + end + ctx.savelog(File.suffixed(rawbase,'ctl')) + + envs = ctx.environments + mods = ctx.modules + flags = ctx.flags + mdes = ctx.modes + + flags.each do |f| + f.sub!(/^\-+/,'') + if f =~ /^(.*?)=(.*)$/ then + setvariable($1,$2) + else + setvariable(f,true) + end + end + + report("using flags #{flags.join(' ')}") if flags.size > 0 + + # merge environment and module specs + + envs << getvariable('environments') unless getvariable('environments').empty? + mods << getvariable('usemodules') unless getvariable('usemodules') .empty? + mdes << getvariable('modes') unless getvariable('modes') .empty? + + envs = envs.uniq.join(',') + mods = mods.uniq.join(',') + mdes = mdes.uniq.join(',') + + report("using search method '#{Kpse.searchmethod}'") if getvariable('verbose') + + report("using environments #{envs}") if envs.length > 0 + report("using modules #{mods}") if mods.length > 0 + report("using modes #{mdes}") if mdes.length > 0 + + setvariable('environments', envs) + setvariable('usemodules', mods) + setvariable('modes', mdes) + end + + # end of preprocessing and merging + + setvariable('nomprun',true) if orisuffix == 'mpx' # else cylic run + PDFview.setmethod('xpdf') if getvariable('xpdf') + PDFview.closeall if getvariable('autopdf') + + runonce = getvariable('once') + finalrun = getvariable('final') || (getvariable('arrange') && ! getvariable('noarrange')) + suffix = getvariable('suffix') + result = getvariable('result') + globalfile = getvariable('globalfile') + forcexml = getvariable('forcexml') # can be set in ctx file + +if dummyfile || forcexml then # after ctx? + jobsuffix = makestubfile(rawname,rawbase,forcexml) + checkxmlfile(rawname) +end + + result = File.unixfied(result) + + if globalfile || FileTest.file?(rawname) then + + if not dummyfile and not globalfile and not forcexml then + scantexpreamble(rawname) + scantexcontent(rawname) if getvariable('texformats').standard? + end + result = File.suffixed(rawname,suffix) unless suffix.empty? + + pushresult(rawbase,result) + + method = validtexmethod(validtexformat(getvariable('texformats'))) + + report("tex processing method: #{method}") + + case method + + when 'context' then + if getvariable('simplerun') || runonce then + makeoptionfile(rawbase,jobname,orisuffix,true,true,3,1) unless getvariable('nooptionfile') + ok = runtex(if dummyfile || forcexml then rawbase else rawname end) + if ok then + ok = runtexutil(rawbase) if getvariable('texutil') || getvariable('forcetexutil') + runluacheck(rawbase) + runbackend(rawbase) + popresult(rawbase,result) + end + if getvariable('keep') then + ['top','log','run'].each do |suffix| + File.silentrename(File.suffixed(rawbase,suffix),File.suffixed(rawbase,suffix+'.keep')) + end + end + else +# goto tmp/jobname when present + mprundone, ok, stoprunning = false, true, false + texruns, nofruns = 0, getvariable('runs').to_i + state = FileState.new + ['tub','tuo','tuc'].each do |s| + state.register(File.suffixed(rawbase,s)) + end + if getvariable('automprun') then # check this + ['mprun','mpgraph'].each do |s| + state.register(File.suffixed(rawbase,s,'mp'),'randomseed') + end + end + while ! stoprunning && (texruns < nofruns) && ok do + texruns += 1 + report("TeX run #{texruns}") + unless getvariable('nooptionfile') then + if texruns == nofruns then + makeoptionfile(rawbase,jobname,orisuffix,false,false,4,texruns) # last + elsif texruns == 1 then + makeoptionfile(rawbase,jobname,orisuffix,false,false,1,texruns) # first + else + makeoptionfile(rawbase,jobname,orisuffix,false,false,2,texruns) # unknown + end + end +# goto . + + ok = runtex(File.suffixed(if dummyfile || forcexml then rawbase else rawname end,jobsuffix)) + +if getvariable('texengine') == "xetex" then + ok = true +end + +############################ + +# goto tmp/jobname when present + if ok && (nofruns > 1) then + unless getvariable('nompmode') then + mprundone = runtexmpjob(rawbase, "mpgraph") + mprundone = runtexmpjob(rawbase, "mprun") + end + ok = runtexutil(rawbase) + runluacheck(rawbase) + state.update + stoprunning = state.stable? + end + end + if not ok then + setvariable('error','error in tex file') + end + if (nofruns == 1) && getvariable('texutil') then + ok = runtexutil(rawbase) + runluacheck(rawbase) + end + if ok && finalrun && (nofruns > 1) then + makeoptionfile(rawbase,jobname,orisuffix,true,finalrun,4,texruns) unless getvariable('nooptionfile') + report("final TeX run #{texruns}") +# goto . + ok = runtex(File.suffixed(if dummyfile || forcexml then rawbase else rawname end,jobsuffix)) +# goto tmp/jobname when present + end + if getvariable('keep') then + ['top','log','run'].each do |suffix| + File.silentrename(File.suffixed(rawbase,suffix),File.suffixed(rawbase,suffix+'.keep')) + end + else + File.silentrename(File.suffixed(rawbase,'top'),File.suffixed(rawbase,'tmp')) + end + # ['tmp','top','log'].each do |s| # previous tuo file / runtime option file / log file + # File.silentdelete(File.suffixed(rawbase,s)) + # end + if ok then +# goto . + runbackend(rawbase) + popresult(rawbase,result) +# goto tmp/jobname when present +# skip next + end + if true then # autopurge + begin + File.open(File.suffixed(rawbase, 'tuo'),'rb') do |f| + ok = 0 + f.each do |line| + case ok + when 1 then + # next line is empty + ok = 2 + when 2 then + if line =~ /^\%\s+\>\s+(.*?)\s+(\d+)/moi then + filename, n = $1, $2 + done = File.delete(filename) rescue false + if done && getvariable('verbose') then + report("deleting #{filename} (#{n} times used)") + end + else + break + end + else + if line =~ /^\%\s+temporary files\:\s+(\d+)/moi then + if $1.to_i == 0 then + break + else + ok = 1 + end + end + end + end + end + rescue + # report("fatal error #{$!}") + end + end + end + + Kpse.runscript('ctxtools',rawbase,'--purge') if getvariable('purge') + Kpse.runscript('ctxtools',rawbase,'--purge --all') if getvariable('purgeall') + + # runcommand('mtxrun','--script','ctxtools',rawbase,'--purge') if getvariable('purge') + # runcommand('mtxrun','--script','ctxtools',rawbase,'--purge --all') if getvariable('purgeall') + + when 'latex' then + + ok = runtex(rawname) + + else + + ok = runtex(rawname) + + end + + if (dummyfile or forcexml) and FileTest.file?(rawbase) then + begin + File.delete(File.suffixed(rawbase,'run')) + rescue + report("unable to delete stub file") + end + end + + if ok and getvariable('autopdf') then + PDFview.open(File.suffixed(if result.empty? then rawbase else result end,'pdf')) + end + + else + report("nothing to process") + end + + end + + # The labels are collected in the mergebe hash. Here we merge the relevant labels + # into beginfig/endfig. We could as well do this in metafun itself. Maybe some + # day ... (it may cost a bit of string space but that is cheap nowadays). + + def doruntexmp(mpname,mergebe=nil,context=true,purge=true) + texfound = false + mpname = File.suffixed(mpname,'mp') + mpcopy = File.suffixed(mpname,'mp.copy') + mpkeep = File.suffixed(mpname,'mp.keep') + setvariable('mp.file',mpname) + setvariable('mp.line','') + setvariable('mp.error','') + if mpdata = File.silentread(mpname) then + # mpdata.gsub!(/^\%.*\n/o,'') + File.silentrename(mpname,mpcopy) + texfound = mergebe || (mpdata =~ /btex .*? etex/mo) + if mp = openedfile(mpname) then + if mergebe then + mpdata.gsub!(/beginfig\s*\((\d+)\)\s*\;(.+?)endfig\s*\;/mo) do + n, str = $1, $2 + if str =~ /^(.*?)(verbatimtex.*?etex)\s*\;(.*)$/mo then + "beginfig(#{n})\;\n#{$1}#{$2}\;\n#{mergebe[n]}\n#{$3}\;endfig\;\n" + else + "beginfig(#{n})\;\n#{mergebe[n]}\n#{str}\;endfig\;\n" + end + end + unless mpdata =~ /beginfig\s*\(\s*0\s*\)/o then + mp << mergebe['0'] if mergebe.key?('0') + end + end + # mp << MPTools::splitmplines(mpdata) + mp << mpdata + mp << "\n" + # mp << "end" + # mp << "\n" + mp.close + end + processmpx(mpname,true,true,purge) if texfound + if getvariable('batchmode') then + options = ' --interaction=batch' + elsif getvariable('nonstopmode') then + options = ' --interaction=nonstop' + else + options = '' + end + # todo plain|mpost|metafun + begin + ok = runmp(mpname) + rescue + end + if f = File.silentopen(File.suffixed(mpname,'log')) then + while str = f.gets do + if str =~ /^l\.(\d+)\s(.*?)\n/o then + setvariable('mp.line',$1) + setvariable('mp.error',$2) + break + end + end + f.close + end + File.silentrename(mpname, mpkeep) + File.silentrename(mpcopy, mpname) + end + end + + # todo: use internal mptotext function and/or turn all btex/etex into textexts + + def processmpx(mpname,force=false,context=true,purge=true) + unless force then + mpname = File.suffixed(mpname,'mp') + if File.atleast?(mpname,10) && (data = File.silentread(mpname)) then + if data =~ /(btex|etex|verbatimtex|textext)/o then + force = true + end + end + end + if force then + begin + mptex = File.suffixed(mpname,'temp','tex') + mpdvi = File.suffixed(mpname,'temp','dvi') + mplog = File.suffixed(mpname,'temp','log') + mpmpx = File.suffixed(mpname,'mpx') + File.silentdelete(mptex) + if true then + report("using internal mptotex converter") + ok = MPTools::mptotex(mpname,mptex,'context') + else + command = "mpto #{mpname} > #{mptex}" + report(command) if getvariable('verbose') + ok = system(command) + end + # not "ok && ..." because of potential problem with return code and redirect (>) + if FileTest.file?(mptex) && File.appended(mptex, "\\end\n") then + # to be replaced by runtexexec([filenames],options,1) + if localjob = TEX.new(@logger) then + localjob.setvariable('files',mptex) + localjob.setvariable('backend','dvips') + localjob.setvariable('engine',getvariable('engine')) unless getvariable('engine').empty? + localjob.setvariable('once',true) + localjob.setvariable('nobackend',true) + if context then + localjob.setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty? + elsif getvariable('interface').empty? then + localjob.setvariable('texformats',['plain']) + else + localjob.setvariable('texformats',[getvariable('interface')]) + end + localjob.processtex + ok = true # todo + else + ok = false + end + # so far + command = "dvitomp #{mpdvi} #{mpmpx}" + report(command) if getvariable('verbose') + ok = ok && FileTest.file?(mpdvi) && system(command) + purge_mpx_files(mpname) if purge + end + rescue + # error in processing mpx file + end + end + end + + def purge_mpx_files(mpname) + unless getvariable('keep') then + ['tex', 'log', 'tui', 'tuo', 'tuc', 'top'].each do |suffix| + File.silentdelete(File.suffixed(mpname,'temp',suffix)) + end + end + end + + def checkmpgraphics(mpname) + # in practice the checksums will differ because of multiple instances + # ok, we could save the mpy/mpo files by number, but not now + mpoptions = '' + if getvariable('makempy') then + mpoptions += " --makempy " + end + mponame = File.suffixed(mpname,'mpo') + mpyname = File.suffixed(mpname,'mpy') + pdfname = File.suffixed(mpname,'pdf') + tmpname = File.suffixed(mpname,'tmp') + if getvariable('mpyforce') || getvariable('forcempy') then + mpoptions += " --force " + else + return false unless File.atleast?(mponame,32) + mpochecksum = FileState.new.checksum(mponame) + return false if mpochecksum.empty? + # where does the checksum get into the file? + # maybe let texexec do it? + # solution: add one if not present or update when different + begin + mpydata = IO.read(mpyname) + if mpydata then + if mpydata =~ /^\%\s*mpochecksum\s*\:\s*([A-Z0-9]+)$/mo then + checksum = $1 + if mpochecksum == checksum then + return false + end + end + end + rescue + # no file + end + end + # return Kpse.runscript('makempy',mpname) + # only pdftex + flags = ['--noctx','--process','--batch','--once'] + result = runtexexec([mponame], flags, 1) + runcommand(["pstoedit","-ssp -dt -f mpost", pdfname,tmpname]) + tmpdata = IO.read(tmpname) + if tmpdata then + if mpy = openedfile(mpyname) then + mpy << "% mpochecksum: #{mpochecksum}\n" + tmpdata.scan(/beginfig(.*?)endfig/mo) do |s| + mpy << "begingraphictextfig#{s}endgraphictextfig\n" + end + mpy.close() + end + end + File.silentdelete(tmpname) + File.silentdelete(pdfname) + return true + end + + def checkmplabels(mpname) + mpname = File.suffixed(mpname,'mpt') + if File.atleast?(mpname,10) && (mp = File.silentopen(mpname)) then + labels = Hash.new + while str = mp.gets do + t = if str =~ /^%\s*setup\s*:\s*(.*)$/o then $1 else '' end + if str =~ /^%\s*figure\s*(\d+)\s*:\s*(.*)$/o then + labels[$1] = labels[$1] || '' + unless t.empty? then + labels[$1] += "#{t}\n" + t = '' + end + labels[$1] += "#{$2}\n" + end + end + mp.close + if labels.size>0 then + return labels + else + return nil + end + end + return nil + end + +end diff --git a/scripts/context/ruby/base/texutil.rb b/scripts/context/ruby/base/texutil.rb new file mode 100644 index 000000000..868e3ca16 --- /dev/null +++ b/scripts/context/ruby/base/texutil.rb @@ -0,0 +1,1097 @@ +require "base/file" +require "base/logger" + +class String + + # real dirty, but inspect does a pretty good escaping but + # unfortunately puts quotes around the string so we need + # to strip these + + # def escaped + # self.inspect[1,self.inspect.size-2] + # end + + def escaped + str = self.inspect ; str[1,str.size-2] + end + + def splitdata + if self =~ /^\s*(.*?)\s*\{(.*)\}\s*$/o then + first, second = $1, $2 + if first.empty? then + [second.split(/\} \{/o)].flatten + else + [first.split(/\s+/o)] + [second.split(/\} \{/o)] + end + else + [] + end + end + +end + +class Logger + def banner(str) + report(str) + return "%\n% #{str}\n%\n" + end +end + +class TeXUtil + + class Plugin + + # we need to reset module data for each run; persistent data is + # possible, just don't reinitialize the data structures that need + # to be persistent; we reset afterwards becausethen we know what + # plugins are defined + + def initialize(logger) + @plugins = Array.new + @logger = logger + end + + def report(str) + @logger.report("fatal error in plugin (#{str}): #{$!}") + puts("\n") + $@.each do |line| + puts(" #{line}") + end + puts("\n") + end + + def reset(name) + if @plugins.include?(name) then + begin + eval("#{name}").reset(@logger) + rescue Exception + report("resetting") + end + else + @logger.report("no plugin #{name}") + end + end + + def resets + @plugins.each do |p| + reset(p) + end + end + + def register(name, file=nil) # maybe also priority + if file then + begin + require("#{file.downcase.sub(/\.rb$/,'')}.rb") + rescue Exception + @logger.report("no plugin file #{file} for #{name}") + else + @plugins.push(name) + end + else + @plugins.push(name) + end + return self + end + + def reader(name, data=[]) + if @plugins.include?(name) then + begin + eval("#{name}").reader(@logger,data.flatten) + rescue Exception + report("reading") + end + else + @logger.report("no plugin #{name}") + end + end + + def readers(data=[]) + @plugins.each do |p| + reader(p,data.flatten) + end + end + + def writers(handle) + @plugins.each do |p| + begin + eval("#{p}").writer(@logger,handle) + rescue Exception + report("writing") + end + end + end + + def processors + @plugins.each do |p| + begin + eval("#{p}").processor(@logger) + rescue Exception + report("processing") + end + end + end + + def finalizers + @plugins.each do |p| + begin + eval("#{p}").finalizer(@logger) + rescue Exception + report("finalizing") + end + end + end + + end + + class Sorter + + @@downcase = true + + def initialize(max=12) + @rep, @map, @exp, @div = Hash.new, Hash.new, Hash.new, Hash.new + @max = max + @rexa, @rexb = nil, nil + end + + def replacer(from,to='') # and expand + @max = [@max,to.length+1].max if to + @rep[from.escaped] = to || '' + end + + # sorter.reducer('ch', 'c') + # sorter.reducer('ij', 'y') + + def reducer(from,to='') + @max = [@max,to.length+1].max if to + @map[from] = to || '' + end + + # sorter.expander('aeligature', 'ae') + # sorter.expander('ijligature', 'y') + + def expander(from,to=nil) + to = converted(to) # not from !!! + @max = [@max,to.length+1].max if to + @exp[from] = to || from || '' + end + + def division(from,to=nil) + from, to = converted(from), converted(to) + @max = [@max,to.length+1].max if to + @div[from] = to || from || '' + end + + # shortcut("\\ab\\cd\\e\\f", 'iacute') + # shortcut("\\\'\\i", 'iacute') + # shortcut("\\\'i", 'iacute') + # shortcut("\\\"e", 'ediaeresis') + # shortcut("\\\'o", 'oacute') + + def hextoutf(str) + str.gsub(/^(0x[A-F\d]+)$/) do + [$1.hex()].pack("U") + end + end + + def shortcut(from,to) + from = hextoutf(from) + replacer(from,to) + expander(to) + end + + def prepare + if @rep.size > 0 then + @rexa = /(#{@rep.keys.join('|')})/ # o + else + @rexa = nil + end + if @map.size > 0 then + # watch out, order of match matters + if @@downcase then + @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/i # o + else + @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/ # o + end + else + if @@downcase then + @rexb = /(\\[a-zA-Z]+|.)\s*/io + else + @rexb = /(\\[a-zA-Z]+|.)\s*/o + end + end + if false then + @exp.keys.each do |e| + @exp[e].downcase! + end + end + end + + def replace(str) + if @rexa then + str.gsub(@rexa) do + @rep[$1.escaped] + end + else + str + end + end + + def normalize(str) + # replace(str).gsub(/ +/,' ') + replace(str).gsub(/\s\s+/," \\space") + end + + def tokenize(str) + if str then + str.gsub(/\\strchr\{(.*?)\}/o) do "\\#{$1}" end + else + "" + end + end + + def remap(str) + s = str.dup + if true then # numbers are treated special + s.gsub!(/(\d+)/o) do + $1.rjust(10,'a') # rest is b .. k + end + end + if @rexa then + s.gsub!(@rexa) do + @rep[$1.escaped] + end + end + if @rexb then + s.gsub!(@rexb) do + token = $1.sub(/\\/o, '') + if @@downcase then + token.downcase! + end + if @exp.key?(token) then + @exp[token].ljust(@max,' ') + elsif @map.key?(token) then + @map[token].ljust(@max,' ') + else + '' + end + end + end + s + end + + def preset(shortcuts=[],expansions=[],reductions=[],divisions=[],language='') + 'a'.upto('z') do |c| expander(c) ; division(c) end + 'A'.upto('Z') do |c| expander(c) ; division(c) end + expander('1','b') ; expander('2','c') ; expander('3','e') ; expander('4','f') + expander('5','g') ; expander('6','h') ; expander('7','i') ; expander('8','i') + expander('9','j') ; expander('0','a') ; expander('-','-') ; + shortcuts.each do |s| shortcut(s[1],s[2]) if s[0] == '' || s[0] == language end + expansions.each do |e| expander(e[1],e[2]) if e[0] == '' || e[0] == language end + reductions.each do |r| reducer(r[1],r[2]) if r[0] == '' || r[0] == language end + divisions.each do |d| division(d[1],d[2]) if d[0] == '' || d[0] == language end + end + + def simplify(str) + s = str.dup + # ^^ + # s.gsub!(/\^\^([a-f0-9][a-f0-9])/o, $1.hex.chr) + # \- || + s.gsub!(/(\\\-|\|\|)/o) do '-' end + # {} + s.gsub!(/\{\}/o) do '' end + # <*..> (internal xml entity) + s.gsub!(/<\*(.*?)>/o) do $1 end + # entities + s.gsub!(/\\getXMLentity\s*\{(.*?)\}/o) do $1 end + # elements + s.gsub!(/\<.*?>/o) do '' end + # what to do with xml and utf-8 + # \"e etc + # unknown \cs + s.gsub!(/\\[a-zA-Z][a-zA-Z]+\s*\{(.*?)\}/o) do $1 end + return s + end + + def getdivision(str) + @div[str] || str + end + + def division?(str) + @div.key?(str) + end + + private + + def converted(str) + if str then + # puts str + str.gsub(/([\+\-]*\d+)/o) do + n = $1.to_i + if n > 0 then + 'z'*n + elsif n < 0 then + '-'*(-n) # '-' precedes 'a' + else + '' + end + end + else + nil + end + end + + end + + class Plugin + + module MyFiles + + @@files, @@temps = Hash.new, Hash.new + + def MyFiles::reset(logger) + @@files, @@temps = Hash.new, Hash.new + end + + def MyFiles::reader(logger,data) + case data[0] + when 'b', 'e' then + @@files[data[1]] = (@@files[data[1]] ||0) + 1 + when 't' then # temporary file + @@temps[data[1]] = (@@temps[data[1]] ||0) + 1 + end + end + + def MyFiles::writer(logger,handle) + handle << logger.banner("loaded files: #{@@files.size}") + @@files.keys.sort.each do |k| + handle << "% > #{k} #{@@files[k]/2}\n" + end + handle << logger.banner("temporary files: #{@@temps.size}") + @@temps.keys.sort.each do |k| + handle << "% > #{k} #{@@temps[k]}\n" + end + end + + def MyFiles::processor(logger) + @@files.keys.sort.each do |k| + unless (@@files[k] % 2) == 0 then + logger.report("check loading of file '#{k}', begin/end problem") + end + end + @@temps.keys.sort.each do |k| + # logger.report("temporary file '#{k}' can be deleted") + end + end + + def MyFiles::finalizer(logger) + end + + end + + end + + class Plugin + + module MyCommands + + @@commands = [] + + def MyCommands::reset(logger) + @@commands = [] + end + + def MyCommands::reader(logger,data) + @@commands.push(data.shift+data.collect do |d| "\{#{d}\}" end.join) + end + + def MyCommands::writer(logger,handle) + handle << logger.banner("commands: #{@@commands.size}") + @@commands.each do |c| + handle << "#{c}%\n" + end + end + + def MyCommands::processor(logger) + end + + def MyCommands::finalizer(logger) + end + + end + + end + + class Plugin + + module MyExtras + + @@programs = [] + + def MyExtras::reset(logger) + @@programs = [] + end + + def MyExtras::reader(logger,data) + case data[0] + when 'p' then + @@programs.push(data[1]) if data[0] + end + end + + def MyExtras::writer(logger,handle) + handle << logger.banner("programs: #{@@programs.size}") + @@programs.each_with_index do |cmd, p| + handle << "% #{p+1} (#{cmd})\n" + end + end + + def MyExtras::processor(logger) + @@programs.each do |p| + # cmd = @@programs[p.to_i] + # logger.report("running #{cmd}") + # system(cmd) + end + end + + def MyExtras::finalizer(logger) + unless (ENV["CTX.TEXUTIL.EXTRAS"] =~ /^(no|off|false|0)$/io) || (ENV["CTX_TEXUTIL_EXTRAS"] =~ /^(no|off|false|0)$/io) then + @@programs.each do |cmd| + logger.report("running #{cmd}") + system(cmd) + end + end + end + + end + + end + + class Plugin + + module MySynonyms + + class Synonym + + @@debug = false + + def initialize(t, c, k, d) + @type, @command, @key, @sortkey, @data = t, c, k, c, d + end + + attr_reader :type, :command, :key, :data + attr_reader :sortkey + attr_writer :sortkey + + # def build(sorter) + # if @key then + # @sortkey = sorter.normalize(sorter.tokenize(@sortkey)) + # @sortkey = sorter.remap(sorter.simplify(@key.downcase)) # ?? + # if @sortkey.empty? then + # @sortkey = sorter.remap(@command.downcase) + # end + # else + # @key = "" + # @sortkey = "" + # end + # end + + def build(sorter) + if @sortkey and not @sortkey.empty? then + @sortkey = sorter.normalize(sorter.tokenize(@sortkey)) + @sortkey = sorter.remap(sorter.simplify(@sortkey.downcase)) # ?? + end + if not @sortkey or @sortkey.empty? then + @sortkey = sorter.normalize(sorter.tokenize(@key)) + @sortkey = sorter.remap(sorter.simplify(@sortkey.downcase)) # ?? + end + if not @sortkey or @sortkey.empty? then + @sortkey = @key.dup + end + end + + def <=> (other) + @sortkey <=> other.sortkey + end + + def Synonym.flush(list,handle) + if @@debug then + list.each do |entry| + handle << "% [#{entry.sortkey}]\n" + end + end + list.each do |entry| + handle << "\\synonymentry{#{entry.type}}{#{entry.command}}{#{entry.key}}{#{entry.data}}%\n" + end + end + + end + + @@synonyms = Hash.new + @@sorter = Hash.new + @@languages = Hash.new + + def MySynonyms::reset(logger) + @@synonyms = Hash.new + @@sorter = Hash.new + @@languages = Hash.new + end + + def MySynonyms::reader(logger,data) + case data[0] + when 'e' then + @@synonyms[data[1]] = Array.new unless @@synonyms.key?(data[1]) + @@synonyms[data[1]].push(Synonym.new(data[1],data[2],data[3],data[4])) + when 'l' then + @@languages[data[1]] = data[2] || '' + end + end + + def MySynonyms::writer(logger,handle) + if @@synonyms.size > 0 then + @@synonyms.keys.sort.each do |s| + handle << logger.banner("synonyms: #{s} #{@@synonyms[s].size}") + Synonym.flush(@@synonyms[s],handle) + end + end + end + + def MySynonyms::processor(logger) + @@synonyms.keys.each do |s| + @@sorter[s] = Sorter.new + @@sorter[s].preset( + eval("MyKeys").shortcuts, + eval("MyKeys").expansions, + eval("MyKeys").reductions, + eval("MyKeys").divisions, + @@languages[s] || '') + @@sorter[s].prepare + @@synonyms[s].each_index do |i| + @@synonyms[s][i].build(@@sorter[s]) + end + @@synonyms[s] = @@synonyms[s].sort + end + end + + def MySynonyms::finalizer(logger) + end + + end + + end + + class Plugin + + module MyRegisters + + class Register + + @@specialsymbol = "\000" + @@specialbanner = "" # \\relax" + + @@debug = false + + @@howto = /^(.*?)\:\:(.*)$/o + @@split = ' && ' + + def initialize(state, t, l, k, e, s, p, r) + @state, @type, @location, @key, @entry, @seetoo, @page, @realpage = state, t, l, k, e, s, p, r + if @key =~ @@howto then @pagehowto, @key = $1, $2 else @pagehowto = '' end + if @entry =~ @@howto then @texthowto, @entry = $1, $2 else @texthowto = '' end + @key = @entry.dup if @key.empty? + @sortkey = @key.dup + @nofentries, @nofpages = 0, 0 + @normalizeentry = false + end + + attr_reader :state, :type, :location, :key, :entry, :seetoo, :page, :realpage, :texthowto, :pagehowto + attr_reader :sortkey + attr_writer :sortkey + + def build(sorter) + # @entry, @key = sorter.normalize(@entry), sorter.normalize(sorter.tokenize(@key)) + @entry = sorter.normalize(sorter.tokenize(@entry)) if @normalizeentry + @key = sorter.normalize(sorter.tokenize(@key)) + if false then + @entry, @key = [@entry, @key].collect do |target| + # +a+b+c &a&b&c a+b+c a&b&c + case target[0,1] + when '&' then target = target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end + when '+' then target = target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end + else target = target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end + end + # {a}{b}{c} + # if target =~ /^\{(.*)\}$/o then + # $1.split(/\} \{/o).join(@@split) # space between } { is mandate + # else + target + # end + end + else + # @entry, @key = cleanupsplit(@entry), cleanupsplit(@key) + @entry, @key = cleanupsplit(@entry), xcleanupsplit(@key) + end + @sortkey = sorter.simplify(@key) + # special = @sortkey =~ /^([^a-zA-Z\\])/o + special = @sortkey =~ /^([\`\~\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\}\[\]\:\;\"\'\|\<\,\>\.\?\/\d])/o + @sortkey = @sortkey.split(@@split).collect do |c| sorter.remap(c) end.join(@@split) + if special then + @sortkey = "#{@@specialsymbol}#{@sortkey}" + end + if @realpage == 0 then + @realpage = 999999 + end + @sortkey = [ + @sortkey.downcase, + @sortkey, + @entry, + @texthowto.ljust(10,' '), + # @state, # no, messes up things + (@realpage.to_s || '').rjust(6,' ').gsub(/0/,' '), + # (@realpage ||'').rjust(6,' '), + @pagehowto + ].join(@@split) + end + + def cleanupsplit(target) + # +a+b+c &a&b&c a+b+c a&b&c + case target[0,1] + when '&' then target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end + when '+' then target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end + else target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end + end + end + + def xcleanupsplit(target) # +a+b+c &a&b&c a+b+c a&b&c + t = Array.new + case target[0,1] + when '&' then + t = target.sub(/^./o,'').split(/([^\\])\&/o) + when '+' then + t = target.sub(/^./o,'').split(/([^\\])\+/o) + else + # t = target.split(/([^\\])[\&\+]/o) + # t = target.split(/[\&\+]/o) + t = target.split(/(?!\\)[\&\+]/o) # lookahead + end + if not t[1] then t[1] = " " end # we need some entry else we get subentries first + if not t[2] then t[2] = " " end # we need some entry else we get subentries first + if not t[3] then t[3] = " " end # we need some entry else we get subentries first + return t.join(@@split) + end + def <=> (other) + @sortkey <=> other.sortkey + end + + # more module like + + @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', '', '' + @@collapse = false + + def Register.flushsavedline(handle) + if @@collapse && ! @@savedfrom.empty? then + if ! @@savedto.empty? then + handle << "\\registerfrom#{@@savedfrom}%" + handle << "\\registerto#{@@savedto}%" + else + handle << "\\registerpage#{@@savedfrom}%" + end + end + @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', '' + end + + def Register.flush(list,handle,sorter) + # a bit messy, quite old mechanism, maybe some day ... + # alphaclass can go, now flushed per class + if list.size > 0 then + @nofentries, @nofpages = 0, 0 + current, previous, howto = Array.new, Array.new, Array.new + lastpage, lastrealpage = '', '' + alphaclass, alpha = '', '' + @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', '' + if @@debug then + list.each do |entry| + handle << "% [#{entry.sortkey.gsub(/#{@@split}/o,'] [')}]\n" + end + end + list.each do |entry| +# puts(entry.sortkey.gsub(/\s+/,"")) + if entry.sortkey =~ /^(\S+)/o then + if sorter.division?($1) then + testalpha = sorter.getdivision($1) + else + testalpha = entry.sortkey[0,1].downcase + end + else + testalpha = entry.sortkey[0,1].downcase + end + if (testalpha != alpha.downcase) || (alphaclass != entry.class) then + alpha = testalpha + alphaclass = entry.class + if alpha != ' ' then + flushsavedline(handle) + if alpha =~ /^[a-zA-Z]$/o then + character = alpha.dup + elsif alpha == @@specialsymbol then + character = @@specialbanner + elsif alpha.length > 1 then + # character = "\\getvalue\{#{alpha}\}" + character = "\\#{alpha}" + else + character = "\\unknown" + end + handle << "\\registerentry{#{entry.type}}{#{character}}%\n" + end + end + current = [entry.entry.split(@@split),'','','',''].flatten + howto = current.collect do |e| + e + '::' + entry.texthowto + end + if howto[0] == previous[0] then + current[0] = '' + else + previous[0] = howto[0].dup + previous[1] = '' + previous[2] = '' + previous[3] = '' + end + if howto[1] == previous[1] then + current[1] = '' + else + previous[1] = howto[1].dup + previous[2] = '' + previous[3] = '' + end + if howto[2] == previous[2] then + current[2] = '' + else + previous[2] = howto[2].dup + previous[3] = '' + end + if howto[3] == previous[3] then + current[3] = '' + else + previous[3] = howto[3].dup + end + copied = false + unless current[0].empty? then + Register.flushsavedline(handle) + handle << "\\registerentrya{#{entry.type}}{#{current[0]}}%\n" + copied = true + end + unless current[1].empty? then + Register.flushsavedline(handle) + handle << "\\registerentryb{#{entry.type}}{#{current[1]}}%\n" + copied = true + end + unless current[2].empty? then + Register.flushsavedline(handle) + handle << "\\registerentryc{#{entry.type}}{#{current[2]}}%\n" + copied = true + end + unless current[3].empty? then + Register.flushsavedline(handle) + handle << "\\registerentryd{#{entry.type}}{#{current[3]}}%\n" + copied = true + end + @nofentries += 1 if copied + # if entry.realpage.to_i == 0 then + if entry.realpage.to_i == 999999 then + Register.flushsavedline(handle) + handle << "\\registersee{#{entry.type}}{#{entry.pagehowto},#{entry.texthowto}}{#{entry.seetoo}}{#{entry.page}}%\n" ; + lastpage, lastrealpage = entry.page, entry.realpage + copied = false # no page ! + elsif @@savedhowto != entry.pagehowto and ! entry.pagehowto.empty? then + @@savedhowto = entry.pagehowto + end + # beware, we keep multiple page entries per realpage because of possible prefix usage + if copied || ! ((lastpage == entry.page) && (lastrealpage == entry.realpage)) then + nextentry = "{#{entry.type}}{#{previous[0]}}{#{previous[1]}}{#{previous[2]}}{#{previous[3]}}{#{entry.pagehowto},#{entry.texthowto}}" + savedline = "{#{entry.type}}{#{@@savedhowto},#{entry.texthowto}}{#{entry.location}}{#{entry.page}}{#{entry.realpage}}" + if entry.state == 1 then # from + Register.flushsavedline(handle) + handle << "\\registerfrom#{savedline}%\n" + elsif entry.state == 3 then # to + Register.flushsavedline(handle) + handle << "\\registerto#{savedline}%\n" + @@savedhowto = '' # test + elsif @@collapse then + if savedentry != nextentry then + savedFrom = savedline + else + savedTo, savedentry = savedline, nextentry + end + else + handle << "\\registerpage#{savedline}%\n" + @@savedhowto = '' # test + end + @nofpages += 1 + lastpage, lastrealpage = entry.page, entry.realpage + end + end + Register.flushsavedline(handle) + end + end + + end + + @@registers = Hash.new + @@sorter = Hash.new + @@languages = Hash.new + + def MyRegisters::reset(logger) + @@registers = Hash.new + @@sorter = Hash.new + @@languages = Hash.new + end + + def MyRegisters::reader(logger,data) + case data[0] + when 'f' then + @@registers[data[1]] = Array.new unless @@registers.key?(data[1]) + @@registers[data[1]].push(Register.new(1,data[1],data[2],data[3],data[4],nil,data[5],data[6])) + when 'e' then + @@registers[data[1]] = Array.new unless @@registers.key?(data[1]) + @@registers[data[1]].push(Register.new(2,data[1],data[2],data[3],data[4],nil,data[5],data[6])) + when 't' then + @@registers[data[1]] = Array.new unless @@registers.key?(data[1]) + @@registers[data[1]].push(Register.new(3,data[1],data[2],data[3],data[4],nil,data[5],data[6])) + when 's' then + @@registers[data[1]] = Array.new unless @@registers.key?(data[1]) + # was this but wrong sort order (4,data[1],data[2],data[3],data[4],data[5],data[6],nil)) + @@registers[data[1]].push(Register.new(4,data[1],data[2],data[3],data[4],data[5],data[6],0)) + when 'l' then + @@languages[data[1]] = data[2] || '' + end + end + + def MyRegisters::writer(logger,handle) + if @@registers.size > 0 then + @@registers.keys.sort.each do |s| + handle << logger.banner("registers: #{s} #{@@registers[s].size}") + Register.flush(@@registers[s],handle,@@sorter[s]) + # report("register #{@@registers[s].class}: #{@@registers[s].@nofentries} entries and #{@@registers[s].@nofpages} pages") + end + end + end + + def MyRegisters::processor(logger) + @@registers.keys.each do |s| + @@sorter[s] = Sorter.new + @@sorter[s].preset( + eval("MyKeys").shortcuts, + eval("MyKeys").expansions, + eval("MyKeys").reductions, + eval("MyKeys").divisions, + @@languages[s] || '') + @@sorter[s].prepare + @@registers[s].each_index do |i| + @@registers[s][i].build(@@sorter[s]) + end + # @@registers[s].uniq! + @@registers[s] = @@registers[s].sort + end + end + + def MyRegisters::finalizer(logger) + end + + end + + end + + class Plugin + + module MyPlugins + + @@plugins = nil + + def MyPlugins::reset(logger) + @@plugins = nil + end + + def MyPlugins::reader(logger,data) + @@plugins = Plugin.new(logger) unless @@plugins + case data[0] + when 'r' then + logger.report("registering plugin #{data[1]}") + @@plugins.register(data[1],data[2]) + when 'd' then + begin + @@plugins.reader(data[1],data[2,data.length-1]) + rescue + @@plugins.reader(data[1],['error']) + end + end + end + + def MyPlugins::writer(logger,handle) + @@plugins.writers(handle) if @@plugins + end + + def MyPlugins::processor(logger) + @@plugins.processors if @@plugins + end + + def MyPlugins::finalizer(logger) + @@plugins.finalizers if @@plugins + end + + end + + end + + class Plugin + + module MyKeys + + @@shortcuts = Array.new + @@expansions = Array.new + @@reductions = Array.new + @@divisions = Array.new + + def MyKeys::shortcuts + @@shortcuts + end + def MyKeys::expansions + @@expansions + end + def MyKeys::reductions + @@reductions + end + def MyKeys::divisions + @@divisions + end + + def MyKeys::reset(logger) + @@shortcuts = Array.new + @@expansions = Array.new + @@reductions = Array.new + end + + def MyKeys::reader(logger,data) + key = data.shift + # grp = data.shift # language code, todo + case key + when 's' then @@shortcuts.push(data) + when 'e' then @@expansions.push(data) + when 'r' then @@reductions.push(data) + when 'd' then @@divisions.push(data) + end + end + + def MyKeys::writer(logger,handle) + end + + def MyKeys::processor(logger) + logger.report("shortcuts : #{@@shortcuts.size}") # logger.report(@@shortcuts.inspect) + logger.report("expansions: #{@@expansions.size}") # logger.report(@@expansions.inspect) + logger.report("reductions: #{@@reductions.size}") # logger.report(@@reductions.inspect) + logger.report("divisions : #{@@divisions.size}") # logger.report(@@divisions.inspect) + end + + def MyKeys::finalizer(logger) + end + + end + + end + + class Converter + + def initialize(logger=nil) + if @logger = logger then + def report(str) + @logger.report(str) + end + def banner(str) + @logger.banner(str) + end + else + @logger = self + def report(str) + puts(str) + end + def banner(str) + puts(str) + end + end + @filename = 'texutil' + @fatalerror = false + @plugins = Plugin.new(@logger) + ['MyFiles', 'MyCommands', 'MySynonyms', 'MyRegisters', 'MyExtras', 'MyPlugins', 'MyKeys'].each do |p| + @plugins.register(p) + end + end + + def loaded(filename) + begin + tuifile = File.suffixed(filename,'tui') + if FileTest.file?(tuifile) then + report("parsing file #{tuifile}") + if f = File.open(tuifile,'rb') then + f.each do |line| + case line.chomp + when /^f (.*)$/o then @plugins.reader('MyFiles', $1.splitdata) + when /^c (.*)$/o then @plugins.reader('MyCommands', [$1]) + when /^e (.*)$/o then @plugins.reader('MyExtras', $1.splitdata) + when /^s (.*)$/o then @plugins.reader('MySynonyms', $1.splitdata) + when /^r (.*)$/o then @plugins.reader('MyRegisters',$1.splitdata) + when /^p (.*)$/o then @plugins.reader('MyPlugins', $1.splitdata) + when /^x (.*)$/o then @plugins.reader('MyKeys', $1.splitdata) + when /^r (.*)$/o then # nothing, not handled here + else + # report("unknown entry #{line[0,1]} in line #{line.chomp}") + end + end + f.close + end + else + report("unable to locate #{tuifile}") + end + rescue + report("fatal error in parsing #{tuifile}") + @filename = 'texutil' + else + @filename = filename + end + end + + def processed + @plugins.processors + return true # for the moment + end + + def saved(filename=@filename) + if @fatalerror then + report("fatal error, no tuo file saved") + return false + else + begin + if f = File.open(File.suffixed(filename,'tuo'),'w') then + @plugins.writers(f) + f << "\\endinput\n" + f.close + end + rescue + report("fatal error when saving file (#{$!})") + return false + else + report("tuo file saved") + return true + end + end + end + + def finalized + @plugins.finalizers + @plugins.resets + return true # for the moment + end + + def reset + @plugins.resets + end + + end + +end diff --git a/scripts/context/ruby/base/tool.rb b/scripts/context/ruby/base/tool.rb new file mode 100644 index 000000000..abf0d5ed0 --- /dev/null +++ b/scripts/context/ruby/base/tool.rb @@ -0,0 +1,291 @@ +# module : base/tool +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +require 'timeout' +require 'socket' +require 'rbconfig' + +module Tool + + $constructedtempdir = '' + + def Tool.constructtempdir(create,mainpath='',fallback='') + begin + mainpath += '/' unless mainpath.empty? + timeout(5) do + begin + t = Time.now + u = t.usec.to_s % [1..2] [0..3] + pth = t.strftime("#{mainpath}%Y%m%d-%H%M%S-#{u}-#{Process.pid}") + # + # problems with 1.9 + # + # if pth == $constructedtempdir + # # sleep(0.01) + # retry + # end + pth == $constructedtempdir + # + Dir.mkdir(pth) if create + $constructedtempdir = pth + return pth + rescue + # sleep(0.01) + retry + end + end + rescue TimeoutError + # ok + rescue + # ok + end + unless fallback.empty? + begin + pth = "#{mainpath}#{fallback}" + mkdir(pth) if create + $constructedtempdir = path + return pth + rescue + return '.' + end + else + return '.' + end + + end + + def Tool.findtempdir(*vars) + constructtempdir(false,*vars) + end + + def Tool.maketempdir(*vars) + constructtempdir(true,*vars) + end + + # print maketempdir + "\n" + # print maketempdir + "\n" + # print maketempdir + "\n" + # print maketempdir + "\n" + # print maketempdir + "\n" + + + def Tool.ruby_platform + case RUBY_PLATFORM + when /(mswin|bccwin|mingw|cygwin)/i then 'mswin' + when /(linux)/i then 'linux' + when /(netbsd|unix)/i then 'unix' + when /(darwin|rhapsody|nextstep)/i then 'macosx' + else 'unix' + end + end + + $defaultlineseparator = $/ # $RS in require 'English' + + def Tool.file_platform(filename) + + begin + if f = open(filename,'rb') then + str = f.read(4000) + str.gsub!(/(.*?)\%\!PS/mo, "%!PS") # don't look into preamble crap + f.close + nn = str.count("\n") + nr = str.count("\r") + if nn>nr then + return 2 + elsif nn0 then + return buffer.slice(0..length-1) + else + # when the path or file does not exist, nothing is returned + # so we try to handle the path separately from the basename + basename = File.basename(filename) + pathname = File.dirname(filename) + length = filemethod.call(pathname,buffer,260) + if length>0 then + return buffer.slice(0..length-1) + '/' + basename + else + return filename + end + end + else + # no danger + return filename + end + end + + def Tool.shortpathname(filename) + dowith_pathname(filename,GetShortPathName) + end + + def Tool.longpathname(filename) + dowith_pathname(filename,GetLongPathName) + end + + else + + def Tool.shortpathname(filename) + filename + end + + def Tool.longpathname(filename) + filename + end + + end + + # print shortpathname("C:/Program Files/ABBYY FineReader 6.0/matrix.str")+ "!\n" + # print shortpathname("C:/Program Files/ABBYY FineReader 6.0/matrix.strx")+ "!\n" + + def Tool.checksuffix(old) + + return old unless FileTest.file?(old) + + new = old + + unless new =~ /\./io # no suffix + f = open(filename,'rb') + if str = f.gets + case str + when /^\%\!PS/io + # logging.report(filename, 'analyzed as EPS') + new = new + '.eps' + when /^\%PDF/io + # logging.report(filename, 'analyzed as PDF') + new = new + '.pdf' + else + # logging.report(filename, 'fallback as TIF') + new = new + '.tif' + end + end + f.close + end + + new.sub!(/\.jpeg$/io) do + '.jpg' + end + new.sub!(/\.tiff$/io) do + '.tif' + end + new.sub!(/\.ai$/io) do + '.eps' + end + new.sub!(/\.ai([a-z0-9]*)$/io) do + '-' + $1 + '.eps' + end + new + + end + + def Tool.cleanfilename(old,logging=nil) + + return old if not FileTest.file?(old) + + new = checksuffix(simplefilename(old)) + unless new == old + begin # bugged, should only be name, not path + File.rename(old,new) + logging.report("renaming fuzzy name #{old} to #{new}") unless logging + return old + rescue + logging.report("unable to rename fuzzy name #{old} to #{new}") unless logging + end + end + return new + + end + + def Tool.servername + host = Socket::gethostname + begin + Socket::gethostbyname(host)[0] + rescue + host + end + end + + # print file_platform(ARGV[0]) + +end diff --git a/scripts/context/ruby/base/variables.rb b/scripts/context/ruby/base/variables.rb new file mode 100644 index 000000000..403b57716 --- /dev/null +++ b/scripts/context/ruby/base/variables.rb @@ -0,0 +1,132 @@ +# module : base/variables +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# ['base/tool','tool'].each do |r| begin require r ; rescue Exception ; else break ; end ; end + +require 'base/tool' + +class Hash + + def nothing?(id) + ! self[id] || self[id].empty? + end + + def subset(pattern) + h = Hash.new + p = pattern.gsub(/([\.\:\-])/) do "\\#{$1}" end + r = /^#{p}/ + self.keys.each do |k| + h[k] = self[k].dup if k =~ r + end + return h + end + +end + +class ExtendedHash < Hash + + @@re_var_a = /\%(.*?)\%/ + @@re_var_b = /\$\((.*?)\)/ + + def set(key,value='',resolve=true) + if value then + self[key] = if resolve then resolved(value.to_s) else value.to_s end + else + self[key] = '' + end + end + + def replace(key,value='') + self[key] = value if self?(key) + end + + def get(key,default='') + if self.key?(key) then self[key] else default end + end + + def true?(key) + self[key] =~ /^(yes|on|true|enable|enabled|y|start)$/io rescue false + end + + def resolved(str) + begin + str.to_s.gsub(@@re_var_a) do + self[$1] || '' + end.gsub(@@re_var_b) do + self[$1] || '' + end + rescue + str.to_s rescue '' + end + end + + def check(key,default='') + if self.key?(key) then + if self[key].empty? then self[key] = (default || '') end + else + self[key] = (default || '') + end + end + + def checked(key,default='') + if self.key?(key) then + if self[key].empty? then default else self[key] end + else + default + end + end + + def empty?(key) + self[key].empty? + end + + # def downcase(key) + # self[key].downcase! + # end + +end + +# the next one is obsolete so we need to replace things + +module Variables + + def setvariable(key,value='') + @variables[key] = value + end + + def replacevariable(key,value='') + @variables[key] = value if @variables.key?(key) + end + + def getvariable(key,default='') + if @variables.key?(key) then @variables[key] else default end + end + + def truevariable(key) + @variables[key] =~ /^(yes|on|true)$/io rescue false + end + + def checkedvariable(str,default='') + if @variables.key?(key) then + if @variables[key].empty? then default else @variables[key] end + else + default + end + end + + def report(*str) + @logger.report(*str) + end + + def debug(*str) + @logger.debug(str) + end + +end diff --git a/scripts/context/ruby/concheck.rb b/scripts/context/ruby/concheck.rb new file mode 100644 index 000000000..3db3e5148 --- /dev/null +++ b/scripts/context/ruby/concheck.rb @@ -0,0 +1,471 @@ +# Program : concheck (tex & context syntax checker) +# Copyright : PRAGMA ADE / Hasselt NL / www.pragma-ade.com +# Author : Hans Hagen +# Version : 1.1 / 2003.08.18 + +# remarks: +# +# - the error messages are formatted like tex's messages so that scite can see them +# - begin and end tags are only tested on a per line basis because we assume clean sources +# - maybe i'll add begin{something} ... end{something} checking + +# # example validation file +# +# begin interface en +# +# 1 text +# 4 Question +# 0 endinput +# 0 setupsomething +# 0 chapter +# +# end interface en + +# nicer + +# class Interface + + # def initialize (language = 'unknown') + # @valid = Array.new + # @language = language + # end + + # def register (left, right) + # @valid.push([left,right]) + # end + +# end + +# $interfaces = Hash.new + +# $interfaces['en'] = Interface.new('english') +# $interfaces['nl'] = Interface.new('dutch') + +# $interfaces['en'].add('\\\\start','\\\\stop') +# $interfaces['en'].add('\\\\begin','\\\\end') +# $interfaces['en'].add('\\\\Start','\\\\Stop') +# $interfaces['en'].add('\\\\Begin','\\\\End') + +# $interfaces['nl'].add('\\\\start','\\\\stop') +# $interfaces['nl'].add('\\\\beginvan','\\\\eindvan') +# $interfaces['nl'].add('\\\\Start','\\\\Stop') +# $interfaces['nl'].add('\\\\BeginVan','\\\\Eindvan') + +# rest todo + +$valid = Hash.new + +$valid['en'] = Array.new +$valid['nl'] = Array.new + +#$valid['en'].push(['','']) +$valid['en'].push(['\\\\start','\\\\stop']) +$valid['en'].push(['\\\\begin','\\\\end']) +$valid['en'].push(['\\\\Start','\\\\Stop']) +$valid['en'].push(['\\\\Begin','\\\\End']) + +#$valid['nl'].push(['','']) +$valid['nl'].push(['\\\\start','\\\\stop']) +$valid['nl'].push(['\\\\beginvan','\\\\eindvan']) +$valid['nl'].push(['\\\\Start','\\\\Stop']) +$valid['nl'].push(['\\\\BeginVan','\\\\Eindvan']) + +$valid_tex = "\\\\end\(input|insert|csname|linechar|graf|buffer|strut\)" +$valid_mp = "(enddef||end||endinput)" + +$start_verbatim = Hash.new +$stop_verbatim = Hash.new + +$start_verbatim['en'] = '\\\\starttyping' +$start_verbatim['nl'] = '\\\\starttypen' + +$stop_verbatim['en'] = '\\\\stoptyping' +$stop_verbatim['nl'] = '\\\\stoptypen' + +def message(str, filename=nil, line=nil, column=nil) + if filename then + if line then + if column then + puts("error in file #{filename} at line #{line} in column #{column}: #{str}\n") + else + puts("error in file #{filename} at line #{line}: #{str}\n") + end + else + puts("file #{filename}: #{str}\n") + end + else + puts(str+"\n") + end +end + +def load_file (filename='') + begin + data = IO.readlines(filename) + data.collect! do |d| + if d =~ /^\s*%/o then + '' + elsif d =~ /(.*?[^\\])%.*$/o then + $1 + else + d + end + end + rescue + message("provide proper filename") + return nil + end + # print data.to_s + "\n" + return data +end + +def guess_interface(data) + if data.first =~ /^%.*interface\=(.*)\s*/ then + return $1 + else + data.each do |line| + case line + when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then return 'nl' + when /\\(stelle|verwende|umgebung|benutze)/o then return 'de' + when /\\(stel|gebruik|omgeving)/ then return 'nl' + when /\\(use|setup|environment)/ then return 'en' + when /\\(usa|imposta|ambiente)/ then return 'it' + when /(height|width|style)=/ then return 'en' + when /(hoehe|breite|schrift)=/ then return 'de' + when /(hoogte|breedte|letter)=/ then return 'nl' + when /(altezza|ampiezza|stile)=/ then return 'it' + when /externfiguur/ then return 'nl' + when /externalfigure/ then return 'en' + when /externeabbildung/ then return 'de' + when /figuraesterna/ then return 'it' + end + end + return 'en' + end +end + +def cleanup_data(data, interface='en') + verbatim = 0 + re_start = /^\s*#{$start_verbatim[interface]}/ + re_stop = /^\s*#{$stop_verbatim[interface]}/ + data.collect! do |d| + if d =~ re_start then + verbatim += 1 + if verbatim>1 then + '' + else + d + end + elsif d =~ re_stop then + verbatim -= 1 + if verbatim>0 then + '' + else + d + end + elsif verbatim > 0 then + '' + else + d + end + end + return data +end + +def load_valid(data, interface=nil) + if data && (data.first =~ /^%.*valid\=(.*)\s*/) + filename = $1 + filename = '../' + filename unless test(?f,filename) + filename = '../' + filename unless test(?f,filename) + if test(?f,filename) then + interface = guess_interface(data) unless interface + if $valid.has_key?(interface) then + interface = $valid[interface] + else + interface = $valid['en'] + end + begin + message("loading validation file",filename) + validkeys = Hash.new + line = 1 + IO.readlines(filename).each do |l| + if l =~ /\s+[\#\%]/io then + # ignore line + elsif l =~ /^\s*(begin|end)\s+interface\s+([a-z][a-z])/o then + # not yet supported + elsif l =~ /^\s*(\d+)\s+([a-zA-Z]*)$/o then + type, key = $1.to_i, $2.strip + if interface[type] then + validkeys[interface[type].first+key] = true + validkeys[interface[type].last+key] = true + else + error_message(filename,line,nil,'wrong definition') + end + end + line += 1 + end + if validkeys then + message("#{validkeys.length} validation keys loaded",filename) + end + return validkeys + rescue + message("invalid validation file",filename) + end + else + message("unknown validation file", filename) + end + else + message("no extra validation file specified") + end + return nil +end + +def some_chr_error(data, filename, left, right) + levels = Array.new + for line in 0..data.length-1 do + str = data[line] + # str = data[line].gsub(/\\[\#{left}\#{right}]/,'') + column = 0 + while column0 then + levels.each do |l| + column = l.pop + line = l.pop + message("missing #{right} for #{left}",filename,line+1,column+1) + end + return true + else + return false + end +end + +def some_wrd_error(data, filename, start, stop, ignore) + levels = Array.new + len = 0 + re_start = /[^\%]*(#{start})([a-zA-Z]*)/ + re_stop = /[^\%]*(#{stop})([a-zA-Z]*)/ + re_ignore = /#{ignore}.*/ + str_start = start.gsub(/\\+/,'\\') + str_stop = stop.gsub(/\\+/,'\\') + line = 0 + while line0 then + # todo: more on one line + dataline.each do |dataword| + case dataword + when re_ignore then + # just go on + when re_start then + levels.push([line,$2]) + # print ' '*levels.length + '>' + $2 + "\n" + when re_stop then + # print ' '*levels.length + '<' + $2 + "\n" + if levels && levels.last && (levels.last[1] == $2) then + levels.pop + elsif levels && levels.last then + message("#{str_stop}#{levels.last[1]} expected instead of #{str_stop}#{$2}",filename,line+1) + return true + else + message("missing #{str_start}#{$2} for #{str_stop}#{$2}",filename,line+1) + return true + end + else + # just go on + end + end + end + line += 1 + end + if levels && levels.length>0 then + levels.each do |l| + text = l.pop + line = l.pop + message("missing #{str_stop}#{text} for #{str_start}#{text}",filename,line+1) + end + return true + else + return false + end +end + +def some_sym_error (data, filename, symbol, template=false) + saved = Array.new + inside = false + level = 0 + for line in 0..data.length-1 do + str = data[line] + column = 0 + while column 0 + when "\%" then + break + when "\\" then + column += 1 + when symbol then + if level == 0 then + inside = ! inside + saved = [line,column] + else + # we're in some kind of template or so + end + else + # go on + end + column += 1 + end + end + if inside && saved && level == 0 then + column = saved.pop + line = saved.pop + message("missing #{symbol} for #{symbol}",filename,line+1) + return true + else + return false + end +end + +def some_key_error(data, filename, valid) + return if (! valid) || (valid.length == 0) + error = false + # data.foreach do |line| ... end + for line in 0..data.length-1 do + data[line].scan(/\\([a-zA-Z]+)/io) do + unless valid.has_key?($1) then + message("unknown command \\#{$1}",filename,line+1) + error = true + end + end + end + return error +end + +# todo : language dependent + +def check_file_tex (filename) + error = false + if data = load_file(filename) then + message("checking tex file", filename) + interface = guess_interface(data) + valid = load_valid(data,interface) + data = cleanup_data(data,interface) + # data.each do |d| print d end + $valid[interface].each do |v| + if some_wrd_error(data, filename, v[0], v[1] ,$valid_tex) then + error = true + break + end + end + # return false if some_wrd_error(data, filename, '\\\\start' , '\\\\stop' , $valid_tex) + # return false if some_wrd_error(data, filename, '\\\\Start' , '\\\\Stop' , $valid_tex) + # return false if some_wrd_error(data, filename, '\\\\beginvan', '\\\\eindvan', $valid_tex) + # return false if some_wrd_error(data, filename, '\\\\begin' , '\\\\end|\\\\eind', $valid_tex) + error = true if some_sym_error(data, filename, '$', false) + error = true if some_sym_error(data, filename, '|', true) + error = true if some_chr_error(data, filename, '{', '}') + error = true if some_chr_error(data, filename, '[', ']') + error = true if some_chr_error(data, filename, '(', ')') + error = true if some_key_error(data, filename, valid) + message("no errors in tex code", filename) unless error + return error + else + return false + end +end + +def check_file_mp (filename) + error = false + if data = load_file(filename) then + message("checking metapost file", filename) + interface = guess_interface(data) + valid = load_valid(data,interface) + $valid[interface].each do |v| + if some_wrd_error(data, filename, v[0], v[1] ,$valid_tex) then + error = true + break + end + end + # return false if some_wrd_error(data, filename, '', 'begin', 'end', $valid_mp) + error = true if some_chr_error(data, filename, '{', '}') + error = true if some_chr_error(data, filename, '[', ']') + error = true if some_chr_error(data, filename, '(', ')') + error = true if some_key_error(data, filename, valid) + message("no errors in metapost code", filename) unless error + return error + else + return false + end +end + +def check_file_text(filename='') + if data = load_file(filename) then + for line in 0..data.length-1 do + # case data[line] + # when /\s([\:\;\,\.\?\!])/ then + # message("space before #{$1}",filename,line+1) + # when /\D([\:\;\,\.\?\!])\S/ then + # message("no space after #{$1}",filename,line+1) + # end + if data[line] =~ /\s([\:\;\,\.\?\!])/ then + message("space before #{$1}",filename,line+1) + else + data[line].gsub!(/\[.*?\]/o, '') + data[line].gsub!(/\(.*?\)/o, '') + data[line].gsub!(/\[.*?$/o, '') + data[line].gsub!(/^.*?\]/o, '') + if data[line] =~ /\D([\:\;\,\.\?\!])\S/ then + message("no space after #{$1}",filename,line+1) + end + end + end + end +end + +def check_file(filename='') + case filename + when '' then + message("provide filename") + return false + when /\.(tex|mk.+)$/i then + return check_file_tex(filename) # && check_file_text(filename) + when /\.mp$/i then + return check_file_mp(filename) + else + message("only tex and metapost files are checked") + return false + end +end + +if ARGV.size > 0 then + someerror = false + ARGV.each do |filename| + somerror = true if check_file(filename) + end + exit (if someerror then 1 else 0 end) +else + exit 1 +end + diff --git a/scripts/context/ruby/ctxtools.rb b/scripts/context/ruby/ctxtools.rb new file mode 100644 index 000000000..c1cbc7d20 --- /dev/null +++ b/scripts/context/ruby/ctxtools.rb @@ -0,0 +1,2785 @@ +#!/usr/bin/env ruby +#encoding: ASCII-8BIT + +# program : ctxtools +# copyright : PRAGMA Advanced Document Engineering +# version : 2004-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# This script will harbor some handy manipulations on context +# related files. + +# todo: move scite here +# +# todo: move kpse call to kpse class/module, faster and better + +# Taco Hoekwater on patterns and lig building (see 'agr'): +# +# Any direct use of a ligature (as accessed by \char or through active +# characters) is wrong and will create faulty hyphenation. Normally, +# when TeX sees "office", it has six tokens, and it knows from the +# patterns that it can hyphenate between the "ff". It will build an +# internal list of four nodes, like this: +# +# [char, o , ffi ] +# [lig , ffi, c ,[f,f,i]] +# [char, c , e ] +# [char, e , NULL] +# +# as you can see from the ffi line, it has remembered the original +# characters. While hyphenating, it temporarily changes back to +# that, then re-instates the ligature afterwards. +# +# If you feed it the ligature directly, like so: +# +# [char, o , ffi ] +# [char, ffi , c ] +# [char, c , e ] +# [char, e , NULL] +# +# it cannot do that (it tries to hyphenate as if the "ffi" was a +# character), and the result is wrong hyphenation. + +banner = ['CtxTools', 'version 1.3.5', '2004/2008', 'PRAGMA ADE'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' +require 'base/system' +require 'base/kpse' +require 'base/file' + +require 'rexml/document' +require 'net/http' +require 'fileutils' +# require 'ftools' +require 'kconv' + +exit if defined?(REQUIRE2LIB) + +class String + + def i_translate(element, attribute, category) + self.gsub!(/(<#{element}.*?#{attribute}=)([\"\'])(.*?)\2/) do + if category.key?($3) then + # puts "#{element} #{$3} -> #{category[$3]}\n" if element == 'cd:inherit' + # puts "#{element} #{$3} => #{category[$3]}\n" if element == 'cd:command' + "#{$1}#{$2}#{category[$3]}#{$2}" + else + # puts "#{element} #{$3} -> ?\n" if element == 'cd:inherit' + # puts "#{element} #{$3} => ?\n" if element == 'cd:command' + "#{$1}#{$2}#{$3}#{$2}" # unchanged + end + end + end + + def i_load(element, category) + self.scan(/<#{element}.*?name=([\"\'])(.*?)\1.*?value=\1(.*?)\1/) do + category[$2] = $3 + end + end + + def nosuffix(suffix) + self.sub(/\.#{suffix}/,'') # no /o + end + +end + +class Commands + + include CommandBase + + public + + def touchcontextfile + dowithcontextfile(1) + end + + def contextversion + dowithcontextfile(2) + end + + private + + def dowithcontextfile(action) + maincontextfile = 'context.tex' + unless FileTest.file?(maincontextfile) then + begin + maincontextfile = Kpse.found(maincontextfile,'context') + rescue + maincontextfile = '' + end + end + unless maincontextfile.empty? then + nextcontextfile = maincontextfile.sub(/context\.tex$/,"cont-new.tex") + case action + when 1 then + touchfile(maincontextfile) + touchfile(nextcontextfile,@@newcontextversion) + when 2 then + reportversion(maincontextfile) + reportversion(nextcontextfile,@@newcontextversion) + end + end + + end + + @@contextversion = "\\\\contextversion" + @@newcontextversion = "\\\\newcontextversion" + + def touchfile(filename,command=@@contextversion) + + if FileTest.file?(filename) then + if data = IO.read(filename) then + timestamp = Time.now.strftime('%Y.%m.%d %H:%M') + prevstamp = '' + begin + data.gsub!(/#{command}\{(\d+\.\d+\.\d+.*?)\}/) do + prevstamp = $1 + "#{command.sub(/(\\)+/,"\\")}{#{timestamp}}" + end + rescue + else + begin + File.delete(filename+'.old') + rescue + end + begin + File.copy(filename,filename+'.old') + rescue + end + begin + if f = File.open(filename,'w') then + f.puts(data) + f.close + end + rescue + end + end + if prevstamp.empty? then + report("#{filename} is not updated, no timestamp found") + else + report("#{filename} is updated from #{prevstamp} to #{timestamp}") + end + end + else + report("#{filename} is not found") + end + + end + + def reportversion(filename,command=@@contextversion) + + version = 'unknown' + begin + if FileTest.file?(filename) && IO.read(filename).match(/#{command}\{(\d+\.\d+\.\d+.*?)\}/) then + version = $1 + end + rescue + end + if @commandline.option("pipe") then + print version + else + report("context version: #{version} (#{filename})") + end + + end + +end + +class Commands + + include CommandBase + + public + + def jeditinterface + editinterface('jedit') + end + + def bbeditinterface + editinterface('bbedit') + end + + def sciteinterface + editinterface('scite') + end + + def rawinterface + editinterface('raw') + end + + private + + def editinterface(type='raw') + + return unless FileTest.file?("cont-en.xml") + + interfaces = @commandline.arguments + + if interfaces.empty? then + interfaces = ['en','cs','de','it','nl','ro','fr'] + end + + interfaces.each do |interface| + begin + collection = Hash.new + mappings = Hash.new + if f = open("keys-#{interface}.xml") then + while str = f.gets do + if str =~ /\/o then + mappings[$1] = $2 + end + end + f.close + if f = open("cont-en.xml") then + while str = f.gets do + if str =~ /\/o then + collection["start#{mappings[$1]}"] = '' + collection["stop#{mappings[$1]}"] = '' + elsif str =~ /\/o then + collection["#{mappings[$1]}"] = '' + end + end + f.close + case type + when 'jedit' then + if f = open("context-jedit-#{interface}.xml", 'w') then + f.puts("\n\n") + f.puts("\n\n") + f.puts("\n") + f.puts(" \n") + f.puts(" \n") + collection.keys.sort.each do |name| + f.puts(" \\#{name}\n") unless name.empty? + end + f.puts(" \n") + f.puts(" \n") + f.puts("\n") + f.close + end + when 'bbedit' then + if f = open("context-bbedit-#{interface}.xml", 'w') then + f.puts("\n\n") + f.puts("BBLMKeywordList\n") + f.puts("\n") + collection.keys.sort.each do |name| + f.puts(" \\#{name}\n") unless name.empty? + end + f.puts("\n") + f.close + end + when 'scite' then + if f = open("cont-#{interface}-scite.properties", 'w') then + i = 0 + f.write("keywordclass.macros.context.#{interface}=") + collection.keys.sort.each do |name| + unless name.empty? then + if i==0 then + f.write("\\\n ") + i = 5 + else + i = i - 1 + end + f.write("#{name} ") + end + end + f.write("\n") + f.close + end + else # raw + collection.keys.sort.each do |name| + puts("\\#{name}\n") unless name.empty? + end + end + end + end + end + end + + end + +end + +# class Commands +# +# include CommandBase +# +# public +# +# def translateinterface +# +# # since we know what kind of file we're dealing with, +# # we do it quick and dirty instead of using rexml or +# # xslt +# +# interfaces = @commandline.arguments +# +# if interfaces.empty? then +# interfaces = ['cs','de','it','nl','ro','fr'] +# else +# interfaces.delete('en') +# end +# +# interfaces.flatten.each do |interface| +# +# variables, constants, strings, list, data = Hash.new, Hash.new, Hash.new, '', '' +# +# keyfile, intfile, outfile = "keys-#{interface}.xml", "cont-en.xml", "cont-#{interface}.xml" +# +# report("generating #{keyfile}") +# +# begin +# one = "texexec --make --all #{interface}" +# two = "texexec --batch --silent --interface=#{interface} x-set-01" +# if @commandline.option("force") then +# system(one) +# system(two) +# elsif not system(two) then +# system(one) +# system(two) +# end +# rescue +# end +# +# unless File.file?(keyfile) then +# report("no #{keyfile} generated") +# next +# end +# +# report("loading #{keyfile}") +# +# begin +# list = IO.read(keyfile) +# rescue +# list = empty +# end +# +# if list.empty? then +# report("error in loading #{keyfile}") +# next +# end +# +# list.i_load('cd:variable', variables) +# list.i_load('cd:constant', constants) +# list.i_load('cd:command' , strings) +# # list.i_load('cd:element' , strings) +# +# report("loading #{intfile}") +# +# begin +# data = IO.read(intfile) +# rescue +# data = empty +# end +# +# if data.empty? then +# report("error in loading #{intfile}") +# next +# end +# +# report("translating interface en to #{interface}") +# +# data.i_translate('cd:string' , 'value', strings) +# data.i_translate('cd:variable' , 'value', variables) +# data.i_translate('cd:parameter', 'name' , constants) +# data.i_translate('cd:constant' , 'type' , variables) +# data.i_translate('cd:variable' , 'type' , variables) +# data.i_translate('cd:inherit' , 'name' , strings) +# # data.i_translate('cd:command' , 'name' , strings) +# +# data.gsub!(/(\]*?language=")en(")/) do +# $1 + interface + $2 +# end +# +# report("saving #{outfile}") +# +# begin +# if f = File.open(outfile, 'w') then +# f.write(data) +# f.close +# end +# rescue +# end +# +# end +# +# end +# +# end + +class Commands + + include CommandBase + + public + + # faster is to glob the whole dir and regexp over that list + + def purgefiles + + pattern = @commandline.arguments + purgeall = @commandline.option("all") + recurse = @commandline.option("recurse") + + $dontaskprefixes.push(Dir.glob("mpx-*")) + + if purgeall then + $dontaskprefixes.push(Dir.glob("*.tex.prep")) + $dontaskprefixes.push(Dir.glob("*.xml.prep")) + end + + $dontaskprefixes.flatten! + $dontaskprefixes.sort! + + if purgeall then + $forsuresuffixes.push($texnonesuffixes) + $texnonesuffixes = [] + $forsuresuffixes.flatten! + end + + if ! pattern || pattern.empty? then + globbed = if recurse then "**/*.*" else "*.*" end + files = Dir.glob(globbed) + report("purging#{if purgeall then ' all' end} temporary files : #{globbed}") + else + report("purging#{if purgeall then ' all' end} temporary files : #{pattern.join(' ')}") + pattern.each do |pat| + nosuf = File.unsuffixed(pat) + globbed = if recurse then "**/#{nosuf}-*.*" else "#{nosuf}-*.*" end + report("checking files that match '#{globbed}'") + files = Dir.glob(globbed) + globbed = if recurse then "**/#{nosuf}.*" else "#{nosuf}.*" end + report("checking files that match '#{globbed}'") + files.push(Dir.glob(globbed)) + end + end + files.flatten! + files.sort! + + $dontaskprefixes.each do |file| + removecontextfile(file) + end + $dontasksuffixes.each do |suffix| + files.each do |file| + removecontextfile(file) if file =~ /#{suffix}$/i + end + end + $forsuresuffixes.each do |suffix| + files.each do |file| + removecontextfile(file) if file =~ /\.#{suffix}$/i + end + end + files.each do |file| + if file =~ /(.*?)\.\d+$/o then + basename = $1 + if file =~ /mp(graph|run)/o || FileTest.file?("#{basename}.mp") then + removecontextfile($file) + end + end + end + $dummyfiles.each do |file| + (File.delete(file) if (FileTest.size?(file) rescue 10) < 10) rescue false + end + $texnonesuffixes.each do |suffix| + files.each do |file| + if file =~ /(.*)\.#{suffix}$/i then + if FileTest.file?("#{$1}.tex") || FileTest.file?("#{$1}.xml") || FileTest.file?("#{$1}.fo") then + keepcontextfile(file) + else + strippedname = $1.gsub(/\-[a-z]$/io, '') + if FileTest.file?("#{strippedname}.tex") || FileTest.file?("#{strippedname}.xml") then + keepcontextfile("#{file} (potential result file)") + else + removecontextfile(file) + end + end + end + end + end + + files = Dir.glob("*.*") + $dontasksuffixes.each do |suffix| + files.each do |file| + removecontextfile(file) if file =~ /^#{suffix}$/i + end + end + + if $removedfiles || $keptfiles || $persistentfiles then + report("removed files : #{$removedfiles}") + report("kept files : #{$keptfiles}") + report("persistent files : #{$persistentfiles}") + report("reclaimed bytes : #{$reclaimedbytes}") + end + + end + + private + + $removedfiles = 0 + $keptfiles = 0 + $persistentfiles = 0 + $reclaimedbytes = 0 + + $dontaskprefixes = [ + # "tex-form.tex", "tex-edit.tex", "tex-temp.tex", + "texexec.tex", "texexec.tui", "texexec.tuo", + "texexec.tuc", "texexec.tua", + "texexec.ps", "texexec.pdf", "texexec.dvi", + "cont-opt.tex", "cont-opt.bak" + ] + $dontasksuffixes = [ + "mp(graph|run)\\.mp", "mp(graph|run)\\.mpd", "mp(graph|run)\\.mpo", "mp(graph|run)\\.mpy", + "mp(graph|run)\\.\\d+", "mp(graph|run)\\.mp.keep", + "xlscript\\.xsl" + ] + $forsuresuffixes = [ + "tui", "tua", "tup", "ted", "tes", "top", + "log", "tmp", "run", "bck", "rlg", + "mpt", "mpx", "mpd", "mpo", "mpb", + "ctl", + "pgf", "synctex.gz", + "tmp.md5", "tmp.out" + ] + $texonlysuffixes = [ + "dvi", "ps", "pdf" + ] + $texnonesuffixes = [ + "tuo", "tub", "top", "tuc" + ] + $dummyfiles = [ + "mpgraph" + ] + + def removecontextfile (filename) + if filename && FileTest.file?(filename) then + begin + filesize = FileTest.size(filename) + File.delete(filename) + rescue + report("problematic : #{filename}") + else + if FileTest.file?(filename) then + $persistentfiles += 1 + report("persistent : #{filename}") + else + $removedfiles += 1 + $reclaimedbytes += filesize + report("removed : #{filename}") + end + end + end + end + + def keepcontextfile (filename) + if filename && FileTest.file?(filename) then + $keptfiles += 1 + report("not removed : #{filename}") + end + end + +end + +#D Documentation can be woven into a source file. The next +#D routine generates a new, \TEX\ ready file with the +#D documentation and source fragments properly tagged. The +#D documentation is included as comment: +#D +#D \starttypen +#D %D ...... some kind of documentation +#D %M ...... macros needed for documenation +#D %S B begin skipping +#D %S E end skipping +#D \stoptypen +#D +#D The most important tag is \type {%D}. Both \TEX\ and \METAPOST\ +#D files use \type{%} as a comment chacacter, while \PERL, \RUBY\ +#D and alike use \type{#}. Therefore \type{#D} is also handled. +#D +#D The generated file gets the suffix \type{ted} and is +#D structured as: +#D +#D \starttypen +#D \startmodule[type=suffix] +#D \startdocumentation +#D \stopdocumentation +#D \startdefinition +#D \stopdefinition +#D \stopmodule +#D \stoptypen +#D +#D Macro definitions specific to the documentation are not +#D surrounded by start||stop commands. The suffix specifaction +#D can be overruled at runtime, but defaults to the file +#D extension. This specification can be used for language +#D depended verbatim typesetting. + +class Commands + + include CommandBase + + public + + def documentation + files = @commandline.arguments + processtype = @commandline.option("type") + files.each do |fullname| + if fullname =~ /(.*)\.(.+?)$/o then + filename, filesuffix = $1, $2 + else + filename, filesuffix = fullname, 'tex' + end + filesuffix = 'tex' if filesuffix.empty? + fullname, resultname = "#{filename}.#{filesuffix}", "#{filename}.ted" + if ! FileTest.file?(fullname) + report("empty input file #{fullname}") + elsif ! tex = File.open(fullname) + report("invalid input file #{fullname}") + elsif ! ted = File.open(resultname,'w') then + report("unable to openresult file #{resultname}") + else + report("input file : #{fullname}") + report("output file : #{resultname}") + nofdocuments, nofdefinitions, nofskips = 0, 0, 0 + skiplevel, indocument, indefinition, skippingbang = 0, false, false, false + if processtype.empty? then + filetype = filesuffix.downcase.sub(/^mk.+$/,'tex') # make sure that mkii and mkiv files are handled + else + filetype = processtype.downcase + end + report("filetype : #{filetype}") + # we need to signal to texexec what interface to use + firstline = tex.gets + if firstline =~ /^\%.*interface\=/ then + ted.puts(firstline) + else + tex.rewind # seek(0) + end + ted.puts("\\startmodule[type=#{filetype}]\n") + while str = tex.gets do + if skippingbang then + skippingbang = false + else + str.chomp! + str.sub!(/\s*$/o, '') + case str + when /^[%\#]D($| )/io then + if skiplevel == 0 then + someline = if str.length < 3 then "" else str[3,str.length-1] end + if indocument then + ted.puts("#{someline}\n") + else + if indefinition then + ted.puts("\\stopdefinition\n") + indefinition = false + end + unless indocument then + ted.puts("\n\\startdocumentation\n") + end + ted.puts("#{someline}\n") + indocument = true + nofdocuments += 1 + end + end + when /^[%\#]M($| )/io then + if skiplevel == 0 then + someline = if str.length < 3 then "" else str[3,str.length-1] end + ted.puts("#{someline}\n") + end + when /^[%\%]S B/io then + skiplevel += 1 + nofskips += 1 + when /^[%\%]S E/io then + skiplevel -= 1 + when /^[%\#]/io then + #nothing + when /^eval \'\(exit \$\?0\)\' \&\& eval \'exec perl/o then + skippingbang = true + else + if skiplevel == 0 then + inlocaldocument = indocument + inlocaldocument = false # else first line skipped when not empty + someline = str + if indocument then + ted.puts("\\stopdocumentation\n") + indocument = false + end + if indefinition then + if someline.empty? then + ted.puts("\\stopdefinition\n") + indefinition = false + else + ted.puts("#{someline}\n") + end + elsif ! someline.empty? then + ted.puts("\n\\startdefinition\n") + indefinition = true + if inlocaldocument then + # nothing + else + nofdefinitions += 1 + ted.puts("#{someline}\n") + end + end + end + end + end + end + if indocument then + ted.puts("\\stopdocumentation\n") + end + if indefinition then + ted.puts("\\stopdefinition\n") + end + ted.puts("\\stopmodule\n") + ted.close + + if nofdocuments == 0 && nofdefinitions == 0 then + begin + File.delete(resultname) + rescue + end + end + report("documentation sections : #{nofdocuments}") + report("definition sections : #{nofdefinitions}") + report("skipped sections : #{nofskips}") + end + end + end + +end + +#D This feature was needed when \PDFTEX\ could not yet access page object +#D numbers (versions prior to 1.11). + +class Commands + + include CommandBase + + public + + def filterpages # temp feature / no reporting + filename = @commandline.argument('first') + filename.sub!(/\.([a-z]+?)$/io,'') + pdffile = "#{filename}.pdf" + tuofile = "#{filename}.tuo" + if FileTest.file?(pdffile) then + begin + prevline, n = '', 0 + if (pdf = File.open(pdffile)) && (tuo = File.open(tuofile,'a')) then + report('filtering page object numbers') + pdf.binmode + while line = pdf.gets do + line.chomp + # typical pdftex search + if (line =~ /\/Type \/Page/o) && (prevline =~ /^(\d+)\s+0\s+obj/o) then + p = $1 + n += 1 + tuo.puts("\\objectreference{PDFP}{#{n}}{#{p}}{#{n}}\n") + else + prevline = line + end + end + end + pdf.close + tuo.close + report("number of pages : #{n}") + rescue + report("fatal error in filtering pages") + end + end + end + +end + +# This script is used to generate hyphenation pattern files +# that suit ConTeXt. One reason for independent files is that +# over the years too many uncommunicated changes took place +# as well that inconsistency in content, naming, and location +# in the texmf tree takes more time than I'm willing to spend +# on it. Pattern files are normally shipped for LaTeX (and +# partially plain). A side effect of independent files is that +# we can make them encoding independent. +# +# Maybe I'll make this hyptools.tex + +class String + + def markbraces + level = 0 + self.gsub(/([\{\}])/o) do |chr| + if chr == '{' then + level = level + 1 + chr = "((+#{level}))" + elsif chr == '}' then + chr = "((-#{level}))" + level = level - 1 + end + chr + end + end + + def unmarkbraces + self.gsub(/\(\(\+\d+?\)\)/o) do + "{" + end .gsub(/\(\(\-\d+?\)\)/o) do + "}" + end + end + + def getargument(pattern) + if self =~ /(#{pattern})\s*\(\(\+(\d+)\)\)(.*?)\(\(\-\2\)\)/m then # no /o + return $3 + else + return "" + end + end + + def withargument(pattern, &block) + if self.markbraces =~ /^(.*)(#{pattern}\s*)\(\(\+(\d+)\)\)(.*?)\(\(\-\3\)\)(.*)$/m then # no /o + "#{$1.unmarkbraces}#{$2}{#{yield($4.unmarkbraces)}}#{$5.unmarkbraces}" + else + self + end + end + + def filterargument(pattern, &block) + if self.markbraces =~ /^(.*)(#{pattern}\s*)\(\(\+(\d+)\)\)(.*?)\(\(\-\3\)\)(.*)$/m then # no /o + yield($4.unmarkbraces) + else + self + end + end + +end + +class Language + + include CommandBase + + def initialize(commandline=nil, language='en', filenames=nil, encoding='ec') + @commandline= commandline + @language = language + @filenames = filenames + @remapping = Array.new + @demapping = Array.new + @cloning = Array.new + @unicode = Hash.new + @encoding = encoding + @data = '' + @read = '' + preload_accents() + preload_unicode() if @commandline.option('utf8') + case @encoding.downcase + when 't1', 'ec', 'cork' then preload_vector('ec', 'enco-ec.tex') + when 'y', 'texnansi' then preload_vector('texnansi', 'enco-ans.tex') + when 'agr', 'agreek' then preload_vector('agr', 'enco-agr.tex') + when 't2a' then preload_vector('t2a', 'enco-cyr.tex') + when 'cyr' then preload_vector() # somehow loading t2a does not work out well + end + end + + def report(str) + if @commandline then + @commandline.report(str) + else + puts("#{str}\n") + end + end + + def remap(from, to) + @remapping.push([from,to]) + end + def demap(from, to) + @demapping.push([from,to]) + end + def clone(from, to) + @cloning.push([from,to]) + end + + def load(filenames=@filenames) + found = false + begin + if filenames then + @filenames.each do |fileset| + [fileset].flatten.each do |filename| + begin + if fname = located(filename) then + data = IO.read(fname) + @data += data.gsub(/\%.*$/, '').gsub(/\\message\{.*?\}/, '') + data.gsub!(/(\\patterns|\\hyphenation)\s*\{.*/mo) do '' end + @read += "\n% preamble of file #{fname}\n\n#{data}\n" + @data.gsub!(/^[\s\n]+$/moi, '') + report("file #{fname} is loaded") + found = true + break # next fileset + end + rescue + report("file #{filename} is not readable") + end + end + end + end + rescue + end + return found + end + + def valid? + ! @data.empty? + end + + def convert + if @data then + n = 0 + if true then + report("") + ["\\patterns","\\hyphenation"].each do |what| + @data = @data.withargument(what) do |content| + report("converting #{what}") + report("") + @demapping.each_index do |i| + content.gsub!(@demapping[i][0], @demapping[i][1]) + end + content.gsub!(/\\delete\{.*?\}/o) do '' end + content.gsub!(/\\keep\{(.*?)\}/o) do $1 end + done = false + @remapping.each_index do |i| + from, to, m = @remapping[i][0], @remapping[i][1], 0 + content.gsub!(from) do + done = true + m += 1 + "[#{i}]" + end + report("#{m.to_s.rjust(5)} entries remapped to #{to}") unless m == 0 + n += m + end + content.gsub!(/\[(\d+)\]/o) do + @remapping[$1.to_i][1] + end + report(" nothing remapped") unless done + @cloning.each_index do |i| + c = 0 + f, s = @cloning[i][0], @cloning[i][1] + str = "#{f}|#{s}" + str.gsub!(/([\[\]])/) do "\\" + "#{$1}" end + reg = /(#{str})/ + content.gsub!(/(\S*(#{str})\S*)/) do + a, b = $1, $1 + a.gsub!(reg, f) + b.gsub!(reg, s) + c = c + 1 + "#{a} #{b}" + end + report("#{c.to_s.rjust(5)} times #{f} cloned to #{s}") + n += c + end + report("") + content.to_s + end + end + else + @remapping.each do |k| + from, to, m = k[0], k[1], 0 + @data.gsub!(from) do + m += 1 + to + end + report("#{m.to_s.rjust(5)} entries remapped to #{to}") unless m == 0 + n += m + end + end + report("#{n} changes in patterns and exceptions") + if @commandline.option('utf8') then + n = 0 + @data.gsub!(/\[(.*?)\]/o) do + n += 1 + @unicode[$1] || $1 + end + report("#{n} unicode utf8 entries") + end + return true + else + return false + end + end + + def comment(str) + str.gsub!(/^\n/o, '') + str.chomp! + if @commandline.option('xml') then + "\n\n" + else + "% #{str.strip}\n\n" + end + end + + def content(tag, str) + lst = str.split(/\s+/) + lst.collect! do |l| + l.strip + end + if lst.length>0 then + lst = "\n#{lst.join("\n")}\n" + else + lst = "" + end + if @commandline.option('xml') then + lst.gsub!(/\[(.*?)\]/o) do + "&#{$1};" + end + "<#{tag}>#{lst}\n\n" + else + "\\#{tag} \{#{lst}\}\n\n" + end + end + + def banner + if @commandline.option('xml') then + "\n\n" + end + end + + def triggerunicode + return + if @commandline.option('utf8') then + "% xetex needs utf8 encoded patterns and for patterns\n" + + "% coded as such we need to enable this regime when\n" + + "% not in xetex; this code will be moved into context\n" + + "% as soon as we've spread the generic patterns\n" + + "\n" + + "\\ifx\\XeTeXversion\\undefined \\else\n" + + " \\ifx\\enableregime\\undefined \\else\n" + + " \\enableregime[utf]\n" + + " \\fi\n" + + "\\fi\n" + + "\n" + end + end + + def save + xml = @commandline.option("xml") + + patname = "lang-#{@language}.pat" + hypname = "lang-#{@language}.hyp" + rmename = "lang-#{@language}.rme" + logname = "lang-#{@language}.log" + + desname = "lang-all.xml" + + @data.gsub!(/\\[nc]\{(.+?)\}/) do $1 end + @data.gsub!(/\{\}/) do '' end + @data.gsub!(/\n+/mo) do "\n" end + @read.gsub!(/\n+/mo) do "\n" end + + description = '' + commentfile = rmename.dup + + begin + desfile = Kpse.found(desname,'context') + if f = File.new(desfile) then + if doc = REXML::Document.new(f) then + if e = REXML::XPath.first(doc.root,"/descriptions/description[@language='#{@language}']") then + description = e.to_s + end + end + end + rescue + description = '' + else + unless description.empty? then + commentfile = desname.dup + str = "\n" + str.gsub!(/^/io, "% ") unless @commandline.option('xml') + description = comment("begin description data") + description << str + "\n" + description << comment("end description data") + report("description found for language #{@language}") + end + end + + begin + if description.empty? || @commandline.option('log') then + if f = File.open(logname,'w') then + report("saving #{@remapping.length} remap patterns in #{logname}") + @remapping.each do |m| + f.puts("#{m[0].inspect} => #{m[1]}\n") + end + f.close + end + else + File.delete(logname) if FileTest.file?(logname) + end + rescue + end + + begin + if description.empty? || @commandline.option('log') then + if f = File.open(rmename,'w') then + data = @read.dup + data.gsub!(/(\s*\n\s*)+/mo, "\n") + f << comment("comment copied from public hyphenation files}") + f << comment("source of data: #{@filenames.join(' ')}") + f << comment("begin original comment") + f << "#{data}\n" + f << comment("end original comment") + f.close + report("comment saved in file #{rmename}") + else + report("file #{rmename} is not writable") + end + else + File.delete(rmename) if FileTest.file?(rmename) + end + rescue + end + + begin + if f = File.open(patname,'w') then + data = '' + @data.filterargument('\\patterns') do |content| + report("merging patterns") + data += content.strip + end + data.gsub!(/(\s*\n\s*)+/mo, "\n") + + f << banner + f << comment("context pattern file, see #{commentfile} for original comment") + f << comment("source of data: #{@filenames.join(' ')}") + f << description + f << comment("begin pattern data") + f << triggerunicode + f << content('patterns', data) + f << comment("end pattern data") + f.close + report("patterns saved in file #{patname}") + else + report("file #{patname} is not writable") + end + rescue + report("problems with file #{patname}") + end + + begin + if f = File.open(hypname,'w') then + data = '' + @data.filterargument('\\hyphenation') do |content| + report("merging exceptions") + data += content.strip + end + data.gsub!(/(\s*\n\s*)+/mo, "\n") + f << banner + f << comment("context hyphenation file, see #{commentfile} for original comment") + f << comment("source of data: #{@filenames.join(' ')}") + f << description + f << comment("begin hyphenation data") + f << triggerunicode + f << content('hyphenation', data) + f << comment("end hyphenation data") + f.close + report("exceptions saved in file #{hypname}") + else + report("file #{hypname} is not writable") + end + rescue + report("problems with file #{hypname}") + end + end + + def process + load + if valid? then + convert + save + else + report("aborted due to missing files") + end + end + + def Language::generate(commandline, language='', filenames='', encoding='ec') + if ! language.empty? && ! filenames.empty? then + commandline.report("processing language #{language}") + commandline.report("") + language = Language.new(commandline,language,filenames,encoding) + if language.load then + language.convert + language.save + commandline.report("") + end + end + end + + private + + def located(filename) + begin + ["context","plain","latex"].each do |name| # fallbacks needed for czech patterns + fname = Kpse.found(filename, name) + if FileTest.file?(fname) then + report("using file #{fname}") + return fname + end + end + report("file #{filename} is not present") + return nil + rescue + report("file #{filename} cannot be located using kpsewhich") + return nil + end + end + + def preload_accents + + begin + if filename = located("enco-acc.tex") then + if data = IO.read(filename) then + report("preloading accent conversions") + data.scan(/\\defineaccent\s*\\*(.+?)\s*\{*(.+?)\}*\s*\{\\(.+?)\}/o) do + one, two, three = $1, $2, $3 + one.gsub!(/[\`\~\!\^\*\_\-\+\=\:\;\"\'\,\.\?]/o) do + "\\#{one}" + end + remap(/\\#{one} #{two}/, "[#{three}]") + remap(/\\#{one}#{two}/, "[#{three}]") unless one =~ /[a-zA-Z]/o + remap(/\\#{one}\{#{two}\}/, "[#{three}]") + end + end + end + rescue + end + + end + + def preload_unicode + + # \definecharacter Agrave {\uchar0{192}} + + begin + if filename = located("enco-uc.tex") then + if data = IO.read(filename) then + report("preloading unicode conversions") + data.scan(/\\definecharacter\s*(.+?)\s*\{\\uchar\{*(\d+)\}*\s*\{(\d+)\}/o) do + one, two, three = $1, $2.to_i, $3.to_i + @unicode[one] = [(two*256 + three)].pack("U") + end + end + end + rescue + report("error in loading unicode mapping (#{$!})") + end + + end + + def preload_vector(encoding='', filename='') + + # funny polish + + case @language + when 'pl' then + remap(/\/a/, "[aogonek]") ; remap(/\/A/, "[Aogonek]") + remap(/\/c/, "[cacute]") ; remap(/\/C/, "[Cacute]") + remap(/\/e/, "[eogonek]") ; remap(/\/E/, "[Eogonek]") + remap(/\/l/, "[lstroke]") ; remap(/\/L/, "[Lstroke]") + remap(/\/n/, "[nacute]") ; remap(/\/N/, "[Nacute]") + remap(/\/o/, "[oacute]") ; remap(/\/O/, "[Oacute]") + remap(/\/s/, "[sacute]") ; remap(/\/S/, "[Sacute]") + remap(/\/x/, "[zacute]") ; remap(/\/X/, "[Zacute]") + remap(/\/z/, "[zdotaccent]") ; remap(/\/Z/, "[Zdotaccent]") + when 'sl' then + remap(/\"c/,"[ccaron]") ; remap(/\"C/,"[Ccaron]") + remap(/\"s/,"[scaron]") ; remap(/\"S/,"[Scaron]") + remap(/\"z/,"[zcaron]") ; remap(/\"Z/,"[Zcaron]") + when 'da' then + remap(/X/, "[aeligature]") + remap(/Y/, "[ostroke]") + remap(/Z/, "[aring]") + when 'hu' then + # nothing + when 'ca' then + demap(/\\c\{/, "\\delete{") + when 'de', 'deo' then + demap(/\\c\{/, "\\delete{") + demap(/\\n\{/, "\\keep{") + remap(/\\3/, "[ssharp]") + remap(/\\9/, "[ssharp]") + remap(/\"a/, "[adiaeresis]") + remap(/\"o/, "[odiaeresis]") + remap(/\"u/, "[udiaeresis]") + when 'fr' then + demap(/\\n\{/, "\\delete{") + remap(/\\ae/, "[aeligature]") + remap(/\\oe/, "[oeligature]") + when 'la' then + # \lccode`'=`' somewhere else, todo + demap(/\\c\{/, "\\delete{") + remap(/\\a\s*/, "[aeligature]") + remap(/\\o\s*/, "[oeligature]") + when 'agr' then + # bug fix + remap("a2|", "[greekalphaiotasub]") + remap("h2|", "[greeketaiotasub]") + remap("w2|", "[greekomegaiotasub]") + remap(">2r1<2r", "[2ῤ1ῥ]") + remap(">a2n1wdu'", "[ἀ2ν1ωδύ]") + remap(">e3s2ou'", "[ἐ3σ2ού]") + # main conversion + remap(/\<\'a\|/, "[greekalphaiotasubdasiatonos]") + # remap(/\<\'a\|/, "[greekdasiatonos][greekAlpha][greekiota]") + remap(/\>\'a\|/, "[greekalphaiotasubpsilitonos]") + remap(/\<\`a\|/, "[greekalphaiotasubdasiavaria]") + remap(/\>\`a\|/, "[greekalphaiotasubpsilivaria]") + remap(/\<\~a\|/, "[greekalphaiotasubdasiaperispomeni]") + remap(/\>\~a\|/, "[greekalphaiotasubpsiliperispomeni]") + remap(/\'a\|/, "[greekalphaiotasubtonos]") + remap(/\`a\|/, "[greekalphaiotasubvaria]") + remap(/\~a\|/, "[greekalphaiotasubperispomeni]") + remap(/\a\|/, "[greekalphaiotasubpsili]") + remap(/a\|/, "[greekalphaiotasub]") + remap(/\<\'h\|/, "[greeketaiotasubdasiatonos]") + remap(/\>\'h\|/, "[greeketaiotasubpsilitonos]") + remap(/\<\`h\|/, "[greeketaiotasubdasiavaria]") + remap(/\>\`h\|/, "[greeketaiotasubpsilivaria]") + remap(/\<\~h\|/, "[greeketaiotasubdasiaperispomeni]") + remap(/\>\~h\|/, "[greeketaiotasubpsiliperispomeni]") + remap(/\'h\|/, "[greeketaiotasubtonos]") + remap(/\`h\|/, "[greeketaiotasubvaria]") + remap(/\~h\|/, "[greeketaiotasubperispomeni]") + remap(/\h\|/, "[greeketaiotasubpsili]") + remap(/h\|/, "[greeketaiotasub]") + remap(/\<'w\|/, "[greekomegaiotasubdasiatonos]") + remap(/\>'w\|/, "[greekomegaiotasubpsilitonos]") + remap(/\<`w\|/, "[greekomegaiotasubdasiavaria]") + remap(/\>`w\|/, "[greekomegaiotasubpsilivaria]") + remap(/\<~w\|/, "[greekomegaiotasubdasiaperispomeni]") + remap(/\>~w\|/, "[greekomegaiotasubpsiliperispomeni]") + remap(/\w\|/, "[greekomegaiotasubpsili]") + remap(/\'w\|/, "[greekomegaiotasubtonos]") + remap(/\`w\|/, "[greekomegaiotasubvaria]") + remap(/\~w\|/, "[greekomegaiotasubperispomeni]") + remap(/w\|/, "[greekomegaiotasub]") + remap(/\<\'i/, "[greekiotadasiatonos]") + remap(/\>\'i/, "[greekiotapsilitonos]") + remap(/\<\`i/, "[greekiotadasiavaria]") + remap(/\>\`i/, "[greekiotapsilivaria]") + remap(/\<\~i/, "[greekiotadasiaperispomeni]") + remap(/\>\~i/, "[greekiotapsiliperispomeni]") + remap(/\"\'i/, "[greekiotadialytikatonos]") + remap(/\"\`i/, "[greekiotadialytikavaria]") + remap(/\"\~i/, "[greekiotadialytikaperispomeni]") + remap(/\i/, "[greekiotapsili]") + remap(/\'i/, "[greekiotaoxia]") + remap(/\`i/, "[greekiotavaria]") + remap(/\~i/, "[greekiotaperispomeni]") + remap(/\"i/, "[greekiotadialytika]") + remap(/\>\~e/, "[greekepsilonpsiliperispomeni]") + remap(/\<\~e/, "[greekepsilondasiaperispomeni]") + remap(/\<\'e/, "[greekepsilondasiatonos]") + remap(/\>\'e/, "[greekepsilonpsilitonos]") + remap(/\<\`e/, "[greekepsilondasiavaria]") + remap(/\>\`e/, "[greekepsilonpsilivaria]") + remap(/\e/, "[greekepsilonpsili]") + remap(/\'e/, "[greekepsilonoxia]") + remap(/\`e/, "[greekepsilonvaria]") + remap(/\~e/, "[greekepsilonperispomeni]") + remap(/\<\'a/, "[greekalphadasiatonos]") + remap(/\>\'a/, "[greekalphapsilitonos]") + remap(/\<\`a/, "[greekalphadasiavaria]") + remap(/\>\`a/, "[greekalphapsilivaria]") + remap(/\<\~a/, "[greekalphadasiaperispomeni]") + remap(/\>\~a/, "[greekalphapsiliperispomeni]") + remap(/\a/, "[greekalphapsili]") + remap(/\'a/, "[greekalphaoxia]") + remap(/\`a/, "[greekalphavaria]") + remap(/\~a/, "[greekalphaperispomeni]") + remap(/\<\'h/, "[greeketadasiatonos]") + remap(/\>\'h/, "[greeketapsilitonos]") + remap(/\<\`h/, "[greeketadasiavaria]") + remap(/\>\`h/, "[greeketapsilivaria]") + remap(/\<\~h/, "[greeketadasiaperispomeni]") + remap(/\>\~h/, "[greeketapsiliperispomeni]") + remap(/\h/, "[greeketapsili]") + remap(/\'h/, "[greeketaoxia]") + remap(/\`h/, "[greeketavaria]") + remap(/\~h/, "[greeketaperispomeni]") + remap(/\<\~o/, "[greekomicrondasiaperispomeni]") + remap(/\>\~o/, "[greekomicronpsiliperispomeni]") + remap(/\<\'o/, "[greekomicrondasiatonos]") + remap(/\>\'o/, "[greekomicronpsilitonos]") + remap(/\<\`o/, "[greekomicrondasiavaria]") + remap(/\>\`o/, "[greekomicronpsilivaria]") + remap(/\o/, "[greekomicronpsili]") + remap(/\'o/, "[greekomicronoxia]") + remap(/\`o/, "[greekomicronvaria]") + remap(/\~o/, "[greekomicronperispomeni]") + remap(/\<\'u/, "[greekupsilondasiatonos]") + remap(/\>\'u/, "[greekupsilonpsilitonos]") + remap(/\<\`u/, "[greekupsilondasiavaria]") + remap(/\>\`u/, "[greekupsilonpsilivaria]") + remap(/\<\~u/, "[greekupsilondasiaperispomeni]") + remap(/\>\~u/, "[greekupsilonpsiliperispomeni]") + remap(/\"\'u/, "[greekupsilondialytikatonos]") + remap(/\"\`u/, "[greekupsilondialytikavaria]") + remap(/\"\~u/, "[greekupsilondialytikaperispomeni]") + remap(/\u/, "[greekupsilonpsili]") + remap(/\'u/, "[greekupsilonoxia]") + remap(/\`u/, "[greekupsilonvaria]") + remap(/\~u/, "[greekupsilonperispomeni]") + remap(/\"u/, "[greekupsilondiaeresis]") + remap(/\<\'w/, "[greekomegadasiatonos]") + remap(/\>\'w/, "[greekomegapsilitonos]") + remap(/\<\`w/, "[greekomegadasiavaria]") + remap(/\>\`w/, "[greekomegapsilivaria]") + remap(/\<\~w/, "[greekomegadasiaperispomeni]") + remap(/\>\~w/, "[greekomegapsiliperispomeni]") + remap(/\w/, "[greekomegapsili]") + remap(/\'w/, "[greekomegaoxia]") + remap(/\`w/, "[greekomegavaria]") + remap(/\~w/, "[greekomegaperispomeni]") + remap(/\r/, "[greekrhopsili]") + remap(/\<\~/, "[greekdasiaperispomeni]") + remap(/\>\~/, "[greekpsiliperispomeni]") + remap(/\<\'/, "[greekdasiatonos]") + remap(/\>\'/, "[greekpsilitonos]") + remap(/\<\`/, "[greekdasiavaria]") + remap(/\>\`/, "[greekpsilivaria]") + remap(/\"\'/, "[greekdialytikatonos]") + remap(/\"\`/, "[greekdialytikavaria]") + remap(/\"\~/, "[greekdialytikaperispomeni]") + remap(/\/, "[greekpsili]") + remap(/\d.{0,2}''/, "") + remap(/\'/, "[greekoxia]") + remap(/\`/, "[greekvaria]") + remap(/\~/, "[perispomeni]") + remap(/\"/, "[greekdialytika]") + # unknown + # remap(/\|/, "[greekIotadialytika]") + # next + remap(/A/, "[greekAlpha]") + remap(/B/, "[greekBeta]") + remap(/D/, "[greekDelta]") + remap(/E/, "[greekEpsilon]") + remap(/F/, "[greekPhi]") + remap(/G/, "[greekGamma]") + remap(/H/, "[greekEta]") + remap(/I/, "[greekIota]") + remap(/J/, "[greekTheta]") + remap(/K/, "[greekKappa]") + remap(/L/, "[greekLambda]") + remap(/M/, "[greekMu]") + remap(/N/, "[greekNu]") + remap(/O/, "[greekOmicron]") + remap(/P/, "[greekPi]") + remap(/Q/, "[greekChi]") + remap(/R/, "[greekRho]") + remap(/S/, "[greekSigma]") + remap(/T/, "[greekTau]") + remap(/U/, "[greekUpsilon]") + remap(/W/, "[greekOmega]") + remap(/X/, "[greekXi]") + remap(/Y/, "[greekPsi]") + remap(/Z/, "[greekZeta]") + remap(/a/, "[greekalpha]") + remap(/b/, "[greekbeta]") + remap(/c/, "[greekfinalsigma]") + remap(/d/, "[greekdelta]") + remap(/e/, "[greekepsilon]") + remap(/f/, "[greekphi]") + remap(/g/, "[greekgamma]") + remap(/h/, "[greeketa]") + remap(/i/, "[greekiota]") + remap(/j/, "[greektheta]") + remap(/k/, "[greekkappa]") + remap(/l/, "[greeklambda]") + remap(/m/, "[greekmu]") + remap(/n/, "[greeknu]") + remap(/o/, "[greekomicron]") + remap(/p/, "[greekpi]") + remap(/q/, "[greekchi]") + remap(/r/, "[greekrho]") + remap(/s/, "[greeksigma]") + remap(/t/, "[greektau]") + remap(/u/, "[greekupsilon]") + remap(/w/, "[greekomega]") + remap(/x/, "[greekxi]") + remap(/y/, "[greekpsi]") + remap(/z/, "[greekzeta]") + clone("[greekalphatonos]", "[greekalphaoxia]") + clone("[greekepsilontonos]", "[greekepsilonoxia]") + clone("[greeketatonos]", "[greeketaoxia]") + clone("[greekiotatonos]", "[greekiotaoxia]") + clone("[greekomicrontonos]", "[greekomicronoxia]") + clone("[greekupsilontonos]", "[greekupsilonoxia]") + clone("[greekomegatonos]", "[greekomegaoxia]") + when 'ru' then + remap(/\xC1/, "[cyrillica]") + remap(/\xC2/, "[cyrillicb]") + remap(/\xD7/, "[cyrillicv]") + remap(/\xC7/, "[cyrillicg]") + remap(/\xC4/, "[cyrillicd]") + remap(/\xC5/, "[cyrillice]") + remap(/\xD6/, "[cyrilliczh]") + remap(/\xDA/, "[cyrillicz]") + remap(/\xC9/, "[cyrillici]") + remap(/\xCA/, "[cyrillicishrt]") + remap(/\xCB/, "[cyrillick]") + remap(/\xCC/, "[cyrillicl]") + remap(/\xCD/, "[cyrillicm]") + remap(/\xCE/, "[cyrillicn]") + remap(/\xCF/, "[cyrillico]") + remap(/\xD0/, "[cyrillicp]") + remap(/\xD2/, "[cyrillicr]") + remap(/\xD3/, "[cyrillics]") + remap(/\xD4/, "[cyrillict]") + remap(/\xD5/, "[cyrillicu]") + remap(/\xC6/, "[cyrillicf]") + remap(/\xC8/, "[cyrillich]") + remap(/\xC3/, "[cyrillicc]") + remap(/\xDE/, "[cyrillicch]") + remap(/\xDB/, "[cyrillicsh]") + remap(/\xDD/, "[cyrillicshch]") + remap(/\xDF/, "[cyrillichrdsn]") + remap(/\xD9/, "[cyrillicery]") + remap(/\xD8/, "[cyrillicsftsn]") + remap(/\xDC/, "[cyrillicerev]") + remap(/\xC0/, "[cyrillicyu]") + remap(/\xD1/, "[cyrillicya]") + remap(/\xA3/, "[cyrillicyo]") + when 'tr' then + remap(/\^\^11/, "[dotlessi]") + else + end + + if ! encoding.empty? then + begin + filename = Kpse.found(filename, 'context') + if data = IO.readlines(filename.chomp) then + report("preloading #{encoding} character mappings") + accept = false + data.each do |line| + case line.chomp + when /\\start(en|)coding\s*\[(.*?)\]/io then + enc = $2 + if accept = (enc == encoding) then + report("accepting vector #{enc}") + else + report("skipping vector #{enc}") + end + when /\\stop(en|)coding/io then + accept = false + when accept && /\\definecharacter\s*([a-zA-Z]+)\s*(\d+)\s*/o then + name, number = $1, $2 + remap(/\^\^#{sprintf("%02x",number)}/, "[#{name}]") + if number.to_i > 127 then + remap(/#{sprintf("\\%03o",number)}/, "[#{name}]") + end + end + end + end + rescue + end + end + end + +end + +class Commands + + include CommandBase + + public + + @@languagedata = Hash.new + + def patternfiles + language = @commandline.argument('first') + if (language == 'all') || language.empty? then + languages = @@languagedata.keys.sort + elsif @@languagedata.key?(language) then + languages = [language] + else + languages = [] + end + languages.each do |language| + encoding = @@languagedata[language][0] || '' + files = @@languagedata[language][1] || [] + Language::generate(self,language,files,encoding) + end + end + + private + + # todo: filter the fallback list from context + + # The first entry in the array is the encoding which will be used + # when interpreting the raw patterns. The second entry is a list of + # filesets (string|aray), each first match of a set is taken. + + @@languagedata['ba' ] = [ 'ec' , ['bahyph.tex'] ] + @@languagedata['ca' ] = [ 'ec' , ['cahyph.tex'] ] + @@languagedata['cy' ] = [ 'ec' , ['cyhyph.tex'] ] + @@languagedata['cs' ] = [ 'ec' , ['czhyphen.tex','czhyphen.ex'] ] + @@languagedata['de' ] = [ 'ec' , ['dehyphn.tex'] ] + @@languagedata['deo'] = [ 'ec' , ['dehypht.tex'] ] + @@languagedata['da' ] = [ 'ec' , ['dkspecial.tex','dkcommon.tex'] ] + # elhyph.tex + @@languagedata['es' ] = [ 'ec' , ['eshyph.tex'] ] + @@languagedata['et' ] = [ 'ec' , ['ethyph.tex'] ] + @@languagedata['fi' ] = [ 'ec' , ['fihyph.tex'] ] + @@languagedata['fr' ] = [ 'ec' , ['frhyph.tex'] ] + # ghyphen.readme ghyph31.readme grphyph + @@languagedata['hr' ] = [ 'ec' , ['hrhyph.tex'] ] + @@languagedata['hu' ] = [ 'ec' , ['huhyphn.tex'] ] + @@languagedata['us' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ] + @@languagedata['us' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ] + # inhyph.tex + @@languagedata['is' ] = [ 'ec' , ['ishyph.tex'] ] + @@languagedata['it' ] = [ 'ec' , ['ithyph.tex'] ] + @@languagedata['la' ] = [ 'ec' , ['lahyph.tex'] ] + # mnhyph + @@languagedata['nl' ] = [ 'ec' , ['nehyph96.tex'] ] + # @@languagedata['no' ] = [ 'ec' , ['nohyphbx.tex'],['nohyphb.tex'],['nohyph2.tex'],['nohyph1.tex'],['nohyph.tex'] ] + @@languagedata['no' ] = [ 'ec' , [['asxsx.tex','nohyphbx.tex'],['nohyphb.tex'],['nohyph2.tex'],['nohyph1.tex'],['nohyph.tex']] ] + @@languagedata['agr'] = [ 'agr' , [['grahyph4.tex'], ['oldgrhyph.tex']] ] # new, todo + @@languagedata['pl' ] = [ 'ec' , ['plhyph.tex'] ] + @@languagedata['pt' ] = [ 'ec' , ['pthyph.tex'] ] + @@languagedata['ro' ] = [ 'ec' , ['rohyph.tex'] ] + @@languagedata['sl' ] = [ 'ec' , [['slhyph.tex'], ['sihyph.tex']] ] + @@languagedata['sk' ] = [ 'ec' , ['skhyphen.tex','skhyphen.ex'] ] + # sorhyph.tex / upper sorbian + # srhyphc.tex / cyrillic + @@languagedata['sv' ] = [ 'ec' , ['svhyph.tex'] ] + @@languagedata['tr' ] = [ 'ec' , ['tkhyph.tex'] ] + @@languagedata['gb' ] = [ 'default' , [['ukhyphen.tex'],['ukhyph.tex']] ] + # @@languagedata['ru' ] = [ 't2a' , ['ruhyphal.tex'] ] # t2a does not work + @@languagedata['ru' ] = [ 'cyr' , ['ruhyphal.tex'] ] +end + +class Commands + + include CommandBase + + def dpxmapfiles + + force = @commandline.option("force") + + texmfroot = @commandline.argument('first') + texmfroot = '.' if texmfroot.empty? + if @commandline.option('maproot') != "" then + maproot = @commandline.option('maproot') + else + maproot = "#{texmfroot.gsub(/\\/,'/')}/fonts/map/pdftex/context" + end + if File.directory?(maproot) then + files = Dir.glob("#{maproot}/*.map") + if files.size > 0 then + files.each do |pdffile| + next if File.basename(pdffile) == 'pdftex.map' + pdffile = File.expand_path(pdffile) + dpxfile = File.expand_path(pdffile.sub(/(dvips|pdftex)/i,'dvipdfm')) + unless pdffile == dpxfile then + begin + if data = File.read(pdffile) then + report("< #{File.basename(pdffile)} - pdf(e)tex") + n = 0 + data = data.collect do |line| + if line =~ /^[\%\#]+/mo then + '' + else + encoding = if line =~ /([a-z0-9\-]+)\.enc/io then $1 else '' end + fontfile = if line =~ /([a-z0-9\-]+)\.(pfb|ttf)/io then $1 else nil end + metrics = if line =~ /^([a-z0-9\-]+)[\s\<]+/io then $1 else nil end + slant = if line =~ /\"([\d\.]+)\s+SlantFont\"/io then "-s #{$1}" else '' end + if metrics && encoding && fontfile then + n += 1 + "#{metrics} #{encoding} #{fontfile} #{slant}" + else + '' + end + end + end + data.delete_if do |line| + line.gsub(/\s+/,'').empty? + end + data.collect! do |line| + # remove line with "name name" lines + line.gsub(/^(\S+)\s+\1\s*$/) do + $1 + end + end + begin + if force then + if n > 0 then + File.makedirs(File.dirname(dpxfile)) + if f = File.open(dpxfile,'w') then + report("> #{File.basename(dpxfile)} - dvipdfm(x) - #{n}") + f.puts(data) + f.close + else + report("? #{File.basename(dpxfile)} - dvipdfm(x)") + end + else + report("- #{File.basename(dpxfile)} - dvipdfm(x) - no entries") + # begin File.delete(dpxname) ; rescue ; end + if f = File.open(dpxfile,'w') then + f.puts("% no map entries") + f.close + end + end + else + report(". #{File.basename(dpxfile)} - dvipdfm(x) - #{n}") + end + rescue + report("error in saving dvipdfm file") + end + else + report("error in loading pdftex file") + end + rescue + report("error in processing pdftex file") + end + end + end + if force then + begin + report("regenerating database for #{texmfroot}") + system("mktexlsr #{texmfroot}") + rescue + end + end + else + report("no mapfiles found in #{maproot}") + end + else + report("provide proper texmfroot") + end + + end + +end + +class Array + + def add_shebang(filename,program) + unless self[0] =~ /^\#/ then + self.insert(0,"\#!/usr/bin/env #{program}") + end + unless self[2] =~ /^\#.*?copyright\=/ then + self.insert(1,"\#") + self.insert(2,"\# copyright=pragma-ade readme=readme.pdf licence=cc-gpl") + self.insert(3,"") unless self[3].chomp.strip.empty? + self[2].gsub!(/ +/, ' ') + return true + else + return false + end + end + + def add_directive(filename,program) + unless self[0] =~ /^\%/ then + self.insert(0,"\% content=#{program}") + end + unless self[2] =~ /^\%.*?copyright\=/ then + self.insert(1,"\%") + if File.expand_path(filename) =~ /[\\\/](doc|manuals)[\\\/]/ then + self.insert(2,"\% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa") + else + self.insert(2,"\% copyright=pragma-ade readme=readme.pdf licence=cc-gpl") + end + self.insert(3,"") unless self[3].chomp.strip.empty? + self[0].gsub!(/ +/, ' ') + return true + else + return false + end + end + + def add_comment(filename) + if self[0] =~ /<\?xml.*?\?>/ && self[2] !~ /^<\!\-\-.*?copyright\=.*?\-\->/ then + self.insert(1,"") + if File.expand_path(filename) =~ /[\\\/](doc|manuals)[\\\/]/ then + self.insert(2,"") + else + self.insert(2,"") + end + self.insert(3,"") unless self[3].chomp.strip.empty? + return true + else + return false + end + end + +end + +class Commands + + include CommandBase + + def brandfiles + + force = @commandline.option("force") + files = @commandline.arguments # Dir.glob("**/*.*") + done = false + + files.each do |filename| + if FileTest.file?(filename) then + ok = false + begin + data = IO.readlines(filename) + case filename + when /\.rb$/ then + ok = data.add_shebang(filename,'ruby') + when /\.pl$/ then + ok = data.add_shebang(filename,'perl') + when /\.py$/ then + ok = data.add_shebang(filename,'python') + when /\.lua$/ then + ok = data.add_shebang(filename,'lua') + when /\.tex$/ then + ok = data.add_directive(filename,'tex') + when /\.mp$/ then + ok = data.add_directive(filename,'metapost') + when /\.mf$/ then + ok = data.add_directive(filename,'metafont') + when /\.(xml|xsl|fo|fx|rlx|rng|exa)$/ then + ok = data.add_comment(filename) + end + rescue + report("fatal error in processing #{filename}") # maybe this catches the mac problem taco reported + else + if ok then + report() + report(filename) + report() + for i in 0..4 do + report(' ' + data[i].chomp) + end + if force && f = File.open(filename,'w') then + f.puts data + f.close + end + done = true + end + end + else + report("no file named #{filename}") + end + end + report() if done + end + +end + +class Commands + + include CommandBase + + # usage : ctxtools --listentities entities.xml + # document: + + def flushentities(handle,entities,doctype=nil) # 'stylesheet' + if doctype then + tab = "\t" + handle << "\n\n" + handle << "\n\n" + handle << "\n" + end + if doctype then + handle << "]>\n" + end + end + + def listentities + + filenames = ['enco-uc.tex','contextnames.txt'] + outputname = @commandline.argument('first') + doctype = @commandline.option('doctype') + entities = Hash.new + + filenames.each do |filename| + filename = Kpse.found(filename, 'context') + if filename and not filename.empty? and FileTest.file?(filename) then + report("loading #{filename.gsub(/\\/,'/')}") unless outputname.empty? + IO.readlines(filename).each do |line| + case line + when /^[\#\%]/io then + # skip comment line + when /\\definecharacter\s+([a-z]+)\s+\{\\uchar\{*(\d+)\}*\{(\d+)\}\}/io then + name, code = $1, sprintf("%04X",$2.to_i*256 + $3.to_i) + entities[name] = code.rjust(4,'0') unless entities.key?(name) + when /^([A-F0-9]+)\;([a-z][a-z]+)\;(.*?)\;(.*?)\s*$/io then + code, name, adobe, comment = $1, $2, $3, $4 + entities[name] = code.rjust(4,'0') unless entities.key?(name) + end + end + end + end + if outputname and not outputname.empty? then + if f = File.open(outputname,'w') then + report("saving #{entities.size} entities in #{outputname}") + flushentities(f,entities,doctype) + f.close + else + flushentities($stdout,entities,doctype) + end + else + flushentities($stdout,entities,doctype) + end + end + +end + +class Commands + + include CommandBase + + def platformize + + pattern = if @commandline.arguments.empty? then "*.{rb,pl,py}" else @commandline.arguments end + recurse = @commandline.option("recurse") + force = @commandline.option("force") + pattern = "#{if recurse then '**/' else '' end}#{pattern}" + Dir.glob(pattern).each do |file| + if File.file?(file) then + size = File.size(file) + data = IO.readlines(file) + if force then + if f = File.open(file,'w') + data.each do |line| + f.puts(line.chomp) + end + f.close + end + if File.size(file) == size then # not robust + report("file '#{file}' is unchanged") + else + report("file '#{file}' is platformized") + end + else + report("file '#{file}' is a candidate") + end + end + end + end + +end + +class TexDeps + + @@cs_tex = %q/ + above abovedisplayshortskip abovedisplayskip + abovewithdelims accent adjdemerits advance afterassignment + aftergroup atop atopwithdelims + badness baselineskip batchmode begingroup + belowdisplayshortskip belowdisplayskip binoppenalty botmark + box boxmaxdepth brokenpenalty + catcode char chardef cleaders closein closeout clubpenalty + copy count countdef cr crcr csname + day deadcycles def defaulthyphenchar defaultskewchar + delcode delimiter delimiterfactor delimeters + delimitershortfall delimeters dimen dimendef discretionary + displayindent displaylimits displaystyle + displaywidowpenalty displaywidth divide + doublehyphendemerits dp dump + edef else emergencystretch end endcsname endgroup endinput + endlinechar eqno errhelp errmessage errorcontextlines + errorstopmode escapechar everycr everydisplay everyhbox + everyjob everymath everypar everyvbox exhyphenpenalty + expandafter + fam fi finalhyphendemerits firstmark floatingpenalty font + fontdimen fontname futurelet + gdef global group globaldefs + halign hangafter hangindent hbadness hbox hfil horizontal + hfill horizontal hfilneg hfuzz hoffset holdinginserts hrule + hsize hskip hss horizontal ht hyphenation hyphenchar + hyphenpenalty hyphen + if ifcase ifcat ifdim ifeof iffalse ifhbox ifhmode ifinner + ifmmode ifnum ifodd iftrue ifvbox ifvmode ifvoid ifx + ignorespaces immediate indent input inputlineno input + insert insertpenalties interlinepenalty + jobname + kern + language lastbox lastkern lastpenalty lastskip lccode + leaders left lefthyphenmin leftskip leqno let limits + linepenalty line lineskip lineskiplimit long looseness + lower lowercase + mag mark mathaccent mathbin mathchar mathchardef mathchoice + mathclose mathcode mathinner mathop mathopen mathord + mathpunct mathrel mathsurround maxdeadcycles maxdepth + meaning medmuskip message mkern month moveleft moveright + mskip multiply muskip muskipdef + newlinechar noalign noboundary noexpand noindent nolimits + nonscript scriptscript nonstopmode nulldelimiterspace + nullfont number + omit openin openout or outer output outputpenalty over + overfullrule overline overwithdelims + pagedepth pagefilllstretch pagefillstretch pagefilstretch + pagegoal pageshrink pagestretch pagetotal par parfillskip + parindent parshape parskip patterns pausing penalty + postdisplaypenalty predisplaypenalty predisplaysize + pretolerance prevdepth prevgraf + radical raise read relax relpenalty right righthyphenmin + rightskip romannumeral + scriptfont scriptscriptfont scriptscriptstyle scriptspace + scriptstyle scrollmode setbox setlanguage sfcode shipout + show showbox showboxbreadth showboxdepth showlists showthe + skewchar skip skipdef spacefactor spaceskip span special + splitbotmark splitfirstmark splitmaxdepth splittopskip + string + tabskip textfont textstyle the thickmuskip thinmuskip time + toks toksdef tolerance topmark topskip tracingcommands + tracinglostchars tracingmacros tracingonline tracingoutput + tracingpages tracingparagraphs tracingrestores tracingstats + uccode uchyph underline unhbox unhcopy unkern unpenalty + unskip unvbox unvcopy uppercase + vadjust valign vbadness vbox vcenter vfil vfill vfilneg + vfuzz voffset vrule vsize vskip vsplit vss vtop + wd widowpenalty write + xdef xleaders xspaceskip + year + /.split + + @@cs_etex = %q/ + beginL beginR botmarks + clubpenalties currentgrouplevel currentgrouptype + currentifbranch currentiflevel currentiftype + detokenize dimexpr displaywidowpenalties + endL endR eTeXrevision eTeXversion everyeof + firstmarks fontchardp fontcharht fontcharic fontcharwd + glueexpr glueshrink glueshrinkorder gluestretch + gluestretchorder gluetomu + ifcsname ifdefined iffontchar interactionmode + interactionmode interlinepenalties + lastlinefit lastnodetype + marks topmarks middle muexpr mutoglue + numexpr + pagediscards parshapedimen parshapeindent parshapelength + predisplaydirection + savinghyphcodes savingvdiscards scantokens showgroups + showifs showtokens splitdiscards splitfirstmarks + TeXXeTstate tracingassigns tracinggroups tracingifs + tracingnesting tracingscantokens + unexpanded unless + widowpenalties + /.split + + @@cs_pdftex = %q/ + pdfadjustspacing pdfannot pdfavoidoverfull + pdfcatalog pdfcompresslevel + pdfdecimaldigits pdfdest pdfdestmargin + pdfendlink pdfendthread + pdffontattr pdffontexpand pdffontname pdffontobjnum pdffontsize + pdfhorigin + pdfimageresolution pdfincludechars pdfinfo + pdflastannot pdflastdemerits pdflastobj + pdflastvbreakpenalty pdflastxform pdflastximage + pdflastximagepages pdflastxpos pdflastypos + pdflinesnapx pdflinesnapy pdflinkmargin pdfliteral + pdfmapfile pdfmaxpenalty pdfminpenalty pdfmovechars + pdfnames + pdfobj pdfoptionpdfminorversion pdfoutline pdfoutput + pdfpageattr pdfpageheight pdfpageresources pdfpagesattr + pdfpagewidth pdfpkresolution pdfprotrudechars + pdfrefobj pdfrefxform pdfrefximage + pdfsavepos pdfsnaprefpoint pdfsnapx pdfsnapy pdfstartlink + pdfstartthread + pdftexrevision pdftexversion pdfthread pdfthreadmargin + pdfuniqueresname + pdfvorigin + pdfxform pdfximage + /.split + + @@cs_omega = %q/ + odelimiter omathaccent omathchar oradical omathchardef omathcode odelcode + leftghost rightghost + charwd charht chardp charit + localleftbox localrightbox + localinterlinepenalty localbrokenpenalty + pagedir bodydir pardir textdir mathdir + boxdir nextfakemath + pagewidth pageheight pagerightoffset pagebottomoffset + nullocp nullocplist ocp externalocp ocplist pushocplist popocplist clearocplists ocptracelevel + addbeforeocplist addafterocplist removebeforeocplist removeafterocplist + OmegaVersion + InputTranslation OutputTranslation DefaultInputTranslation DefaultOutputTranslation + noInputTranslation noOutputTranslation + InputMode OutputMode DefaultInputMode DefaultOutputMode + noInputMode noOutputMode noDefaultInputMode noDefaultOutputMode + /.split + + @@cs_metatex = %q/ + /.split + + @@cs_xetex = %q/ + /.split + + @@cs_skip = %q/ + v\! c\! s\! e\! m\! f\! + \!tf \!tt \!tq \!ta \?\? + csname endcsname relax + \!\!string[a-f] \!\!dimen[a-k] \!\!count[a-f] \!\!toks[a-e] \!\!box[a-e] + \!\!width[a-c] \!\!height[a-c] \!\!depth[a-c] + \!\!done[a-f] if\!\!done[a-f] if\:\!\!done[a-f] + scratch globalscratch + ascii[a-d] globalascii + @@expanded @@globalexpanded @EA @EAEA @EAEAEA + bgroup egroup par next nextnext docommand dodocommand dododocommand + \!\!width \!\!height \!\!depth \!\!plus \!\!minus \!\!to + /.split + + @@cs_skip = %q/ + [vcsemf]\! \?\? + \!t[ftqa] + csname endcsname relax + \!\!string[a-f] \!\!dimen[a-k] \!\!count[a-f] \!\!toks[a-e] \!\!box[a-e] + \!\!width[a-c] \!\!height[a-c] \!\!depth[a-c] + \!\!done[a-f] if\!\!done[a-f] if\:\!\!done[a-f] + scratch globalscratch + ascii[a-d] globalascii + @@expanded @@globalexpanded @(EA)+ + [be]group par next nextnext (do)+command + \!\!(width|height|depth|plus|minus|to) + /.split + + # let's ignore \dimendef etc + + @@primitives_def = %q/ + def edef xdef gdef let + newcount newdimen newskip newbox newtoks newmarks newif newinsert newmuskip + chardef mathchardef dimendef countdef toksdef + newconditional definecomplexorsimple definecomplexorsimpleempty + newcounter newpersistentmark + installinsertion installspecial\s*\\[* installoutput\s*\\[* + /.split + + @@types = [['invalid','*'],['okay','='],['forward','>'],['backward','<'],['unknown','?']] + + @@skips = /^(#{@@cs_skip.join('|')})/o + + def initialize(logger=nil,compact=false) + @defined = Hash.new + @definitive = Hash.new + @used_before = Hash.new + @used_after = Hash.new + @dependencies = Hash.new + @fineorder = Hash.new + @forward = Hash.new + @backward = Hash.new + @disorder = Hash.new + @disordercs = Hash.new + @type = Hash.new + @filename = 'context.tex' + @files = Array.new # keep load order ! + @order = Hash.new + @logger = logger + @filefilter = nil + @namefilter = nil + @compact = compact + # + @@cs_tex.each do |cs| @defined[cs] = ['-tex--------'] end + @@cs_etex.each do |cs| @defined[cs] = ['-etex-------'] end + @@cs_pdftex.each do |cs| @defined[cs] = ['-pdftex-----'] end + @@cs_omega.each do |cs| @defined[cs] = ['-omega------'] end + @@cs_xetex.each do |cs| @defined[cs] = ['-xetex------'] end + @@cs_metatex.each do |cs| @defined[cs] = ['-metatex----'] end + end + + def report(str) + @logger.report(str) rescue false + end + + def setfilter(data) + data.split(/\s*\,\s*/).each do |d| + if d =~ /\.tex$/ then + @filefilter = Array.new unless @filefilter + @filefilter << d + else + @namefilter = Array.new unless @namefilter + @namefilter << d + end + end + end + + def load(filename='context.tex') + begin + @filename = filename + n = 0 + File.open(filename) do |f| + f.each do |line| + if line =~ /^(\\input\s+|\\load[a-z]+\{)([a-z\-\.]+)(\}*)/ then + ante, name, post = $1, $2, $3 + @files.push(name) + @order[name] = n += 1 + end + end + end + rescue + @files = Array.new + @order = Hash.new + end + end + + def save(filename='context.tex') + unless @filefilter || @namefilter then + begin + data = IO.readlines(filename).each do |line| + line.gsub!(/^(\\input\s+|\\load[a-z]+\{)([a-z\-\.]+)(\}*)\s*$/) do + ante, name, post = $1, $2, $3 + fin = (@fineorder[name] || [])-[name] + dep = (@dependencies[name] || [])-[name] + dis = (@disorder[name] || [])-[name] + fin = if fin.size > 0 then " B[#{fin.join(' ')}]" else "" end + dep = if dep.size > 0 then " A[#{dep.join(' ')}]" else "" end + dis = if dis.size > 0 then " D[#{dis.join(' ')}]" else "" end + "#{ante}#{name}#{post} %#{fin}#{dep}#{dis}\n" + end + end + rescue + report("error: #{$!}") + else + begin + newname = filename.sub(/\..*$/,'.log') + report("") + report("writing to #{newname}") + report("") + File.open(newname,'w') do |f| + f << data + end + rescue + report("error: #{$!}") + end + end + end + end + + def analyze + report('') + report("loading files") + report('') + n = 0 +# try tex and mkiv + @files.each do |filename| + if File.file?(filename) and f = File.open(filename) then + defs, uses, l = 0, 0, 0 + n += 1 + report("#{n.to_s.rjust(5,' ')} #{filename}") + f.each do |line| + l += 1 + line.chomp! + + + line.sub!(/\%.*$/, '') + line.gsub!(/\\(unexpanded|unprotected|global|protected|long)\s*(\\)/, "\\") + # the superseded, overloaded, forwarded, and predefined macros + # are at the outer level anyway, so there we may ignore leading + # spaces (could be inside an \if); other definitions are only + # accepted when they start at the beginning of a line + case line + when /^\\ifx\s*\\[a-zA-Z\@\!\?]+\s*\\undefined\s*(\\else)*(.*?)$/ then + if $2 =~ /^\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})/o then + pushdef(filename,l,$2,5) # kind of auto-predefined + end + when /^\s*\\superseded\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o + name, rest = $2, $3 + pushdef(filename,l,name,1) + moreuse(filename,l,rest) + when /^\s*\\overloaded\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o + name, rest = $2, $3 + pushdef(filename,l,name,2) + moreuse(filename,l,rest) + when /^\s*\\forwarded\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o + name, rest = $2, $3 + pushdef(filename,l,name,3) + moreuse(filename,l,rest) + when /^\s*\\predefined\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o + name, rest = $2, $3 + pushdef(filename,l,name,4) + moreuse(filename,l,rest) + when /^\\(#{@@primitives_def.join('|')})[\=\s]*\\([a-zA-Z\@\?\!]{3,})(.*)$/o + name, rest = $2, $3 # \=* catches the \let \a = \b + pushdef(filename,l,name,0) + moreuse(filename,l,rest) + when /\\newevery\s*\\([a-zA-Z\@\?\!]+)\s*\\([a-zA-Z\@\?\!]+)/ then + a, b = $1, $2 + pushdef(filename,l,a,0) + pushdef(filename,l,b,0) + else + moreuse(filename,l,line) + end + end + f.close + end + end + @used_after.each do |cs,files| + (@defined[cs] || []).each do |name| + @dependencies[name] = Array.new unless @dependencies[name] + files.each do |file| + @dependencies[name] << file unless @dependencies[name].include?(file) + end + end + end + @used_before.each do |cs,files| + (@defined[cs] || []).each do |name| + @disorder[name] = Array.new unless @disorder[name] + @disordercs[name] = Array.new unless @disordercs[name] + @fineorder[name] = Array.new unless @fineorder[name] + files.each do |file| + unless @disorder[name].include?(file) || name == file then + unless @defined[cs].include?(file) then + if @order[name] > @order[file] then + @disorder[name] << file + @disordercs[name] << "#{file}:#{cs}" + end + end + end + @fineorder[name] << file unless @fineorder[name].include?(file) || name == file + end + end + end + end + + def moreuse(filename,l,line) + line.scan(/\\if([a-zA-Z@\?\!]{3,})/) do |name, rest| # rest, else array + pushuse(filename,l,"if#{name}") unless name =~ /^(true|false)$/ + end + line.scan(/\\([a-zA-Z@\?\!]{3,})/) do |name, rest| # rest, else array + if name =~ /(true|false)$/ then + pushuse(filename,l,"if#{name}") unless name =~ /^(if|set)$/ + else + pushuse(filename,l,name) + end + end + end + + def feedback + begin + # get max length + l = 0 + list = @defined.keys.sort + list.each do |cs| + l = cs.length if cs.length > l + end + if ! @compact then + n = 0 + report('') + report("defined: #{@defined.size}") + report('') + @defined.keys.sort.each do |cs| + next if @namefilter && ! @namefilter.include?(cs) + next if @filefilter && ! @defined[cs].include?(cs) + if @defined[cs].size > 1 then + dlist = @defined[cs].collect do |d| + if d == @definitive[cs] then d else "[#{d}]" end + end + else + dlist = @defined[cs] + end + report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{dlist.join(' ')}") + end + end + if true then + n = 0 + report('') + report("used before defined: #{@used_before.size}") + report('') + @used_before.keys.sort.each do |cs| + next if @namefilter && ! @namefilter.include?(cs) + next if @filefilter && (@used_before[cs] & @filefilter).size == 0 + used = @used_before[cs] - (@defined[cs] || []) + defined = (@defined[cs] || []).join(' ') + defined = "[ ? ]" if defined.empty? + if used.size > 0 then + report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined} -> #{used.join(' ')}") + else + report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined}") + end + end + report(' none') if n == 0 + end + if ! @compact then + n = 0 + report('') + report("used after defined: #{@used_after.size}") + report('') + @used_after.keys.sort.each do |cs| + next if @namefilter && ! @namefilter.include?(cs) + next if @filefilter && (@used_after[cs] & @filefilter).size == 0 + used = @used_after[cs] - (@defined[cs] || []) + defined = (@defined[cs] || []).join(' ') + if used.size > 0 then + report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined} <- #{used.join(' ')}") + else + report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined}") + end + end + report(' none') if n == 0 + end + if ! @compact then + unless @filefilter || @namefilter then + [false,true].each do |mode| + n = 0 + report("") + report("file dependecies #{if mode then '(critical)' end}") + [@dependencies].each do |dependencies| + report("") + dependencies.keys.sort.each do |f| + if dependencies[f].size > 0 then + dependencies[f].delete(f) + end + if mode then + dep = dependencies[f].delete_if do |d| + f[0..3] == d[0..3] # same xxxx- prefix + end + else + dep = dependencies[f] + end + if dep.size > 0 then + name = f.nosuffix('tex').ljust(8,' ') + list = dep.sort.collect do |k| k.nosuffix('tex') end + report("#{(n += 1).to_s.rjust(5,' ')} #{name} !! #{list.join(' ')}") + end + end + end + report(' none') if n == 0 + end + end + end + if true then + unless @filefilter || @namefilter then + [false,true].each do |mode| + [@disorder,@disordercs].each do |disorder| + n = 0 + report("") + report("file disorder #{if mode then '(critical)' end}") + report("") + disorder.keys.sort.each do |f| + if disorder[f].size > 0 then + disorder[f].delete(f) + end + if mode then + dis = disorder[f].delete_if do |d| + f[0..3] == d[0..3] # same xxxx- prefix + end + else + dis = disorder[f] + end + if dis.size > 0 then + name = f.nosuffix('tex').ljust(8,' ') + list = dis.sort.collect do |k| k.nosuffix('tex') end + report("#{(n += 1).to_s.rjust(3,' ')} #{name} ?? #{list.join(' ')}") + end + end + end + report(' none') if n == 0 + end + end + end + rescue + puts("fatal error: #{$!} #{$@.join("\n")}") + end + end + + private + + def csdefined?(cs,filename) + @defined[cs] && @defined[cs].include?(filename) + end + def csbefore?(cs,filename) + @used_before[cs] && @used_before[cs].include?(filename) + end + def csafter?(cs,filename) + @used_after[cs] && @used_after[cs].include?(filename) + end + + def csignored?(cs) + cs.to_s =~ @@skips + end + + def pushdef(filename,n,cs,type) + if csignored?(cs) then + # nothing + elsif @defined[cs] then + case type + when 5 then + # if test, no definition done + else + @definitive[cs] = filename + unless @filefilter || @namefilter then + report("#{cs} is redefined") unless csdefined?(cs,filename) || @compact + end + end + @defined[cs] << filename unless @defined[cs].include?(filename) + else + @defined[cs] = Array.new + @defined[cs] << filename + @definitive[cs] = filename + @type[cs] = type + end + end + + def pushuse(filename,n,cs) + if csignored?(cs) then + # nothing + elsif @defined[cs] then + @used_after[cs] = Array.new unless @used_after[cs] + @used_after[cs] << filename unless csafter?(cs,filename) + else + @used_before[cs] = Array.new unless @used_before[cs] + @used_before[cs] << filename unless csbefore?(cs,filename) + end + end + +end + +class Commands + + include CommandBase + + def dependencies + + filename = if @commandline.arguments.empty? then 'context.tex' else @commandline.arguments.first end + compact = @commandline.option('compact') + + ['context',''].each do |progname| + unless FileTest.file?(filename) then + name = Kpse.found(filename, progname) + if FileTest.file?(name) then + filename = name + break + end + end + end + + if FileTest.file?(filename) && deps = TexDeps.new(logger,compact) then + deps.setfilter(@commandline.option('filter')) + deps.load + deps.analyze + deps.feedback + deps.save if @commandline.option('save') + else + report("unknown file #{filename}") + end + + end + +end + +class Commands + + @@re_utf_bom = /^\357\273\277/o # just utf-8 + + def disarmutfbom + + if @commandline.arguments.empty? then + report("provide filename") + else + @commandline.arguments.each do |filename| + report("checking '#{filename}'") + if FileTest.file?(filename) then + begin + data = IO.read(filename) + if data.sub!(@@re_utf_bom,'') then + if @commandline.option('force') then + if f = File.open(filename,'wb') then + f << data + f.close + report("bom found and removed") + else + report("bom found and removed, but saving file fails") + end + else + report("bom found, use '--force' to remove it") + end + else + report("no bom found") + end + rescue + report("bom found, but removing it fails") + end + else + report("provide valid filename") + end + end + end + end + +end + +class Commands + + include CommandBase + + def updatecontext + + def fetchfile(site, name, target=nil) + begin + proxy = @commandline.option('proxy') + if proxy && ! proxy.empty? then + address, port = proxy.split(":") + if address && port then + http = Net::HTTP::Proxy(address, port).new(site) + else + http = Net::HTTP::Proxy(proxy, 80).new(site) + end + else + http = Net::HTTP.new(site) + end + resp, data = http.get(name.gsub(/^\/*/, '/')) + rescue + return false + else + begin + if data then + name = File.basename(name) + File.open(target || name, 'wb') do |f| + f << data + end + else + return false + end + rescue + return false + else + return true + end + end + end + + def locatedlocaltree + tree = Kpse.used_path('TEXMFLOCAL') + unless tree && FileTest.directory?(tree) then + tree = Kpse.used_path('TEXMF') + end + return tree + end + + def extractarchive(archive) + unless FileTest.file?(archive) then + report("fatal error, '#{archive}' has not been downloaded") + return false + end + # unless system("unzip -uo #{archive}") then + unless system("unzip -o #{archive}") then + report("fatal error, make sure that you have 'unzip' in your path") + return false + end + stubs = "scripts/context/stubs/unix/*" + if System.unix? and not system("chmod +x #{stubs}") then + report("change x-permissions of '#{stubs}' manually") + end + return true + end + + def remakeformats + system("mktexlsr") + system("luatools --selfupdate") + system("mtxrun --selfupdate") + system("luatools --generate") + system("texmfstart texexec --make --all --fast --pdftex") + system("texmfstart texexec --make --all --fast --luatex") + system("texmfstart texexec --make --all --fast --xetex") + return true + end + + if localtree = locatedlocaltree then + report("updating #{localtree}") + begin + Dir.chdir(localtree) + rescue + report("unable to change to #{localtree}") + else + archive = 'cont-tmf.zip' + report("fetching #{archive}") + unless fetchfile("www.pragma-ade.com","/context/latest/#{archive}") then + report("unable to fetch #{archive}") + return + end + report("extracting #{archive}") + unless extractarchive(archive) then + report("unable to extract #{archive}") + return + end + report("remaking formats") + unless remakeformats then + report("unable to remak formats") + end + end + else + report("unable to locate local tree") + end + + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('touchcontextfile' , 'update context version') +commandline.registeraction('contextversion' , 'report context version') +commandline.registeraction('jeditinterface' , 'generate jedit syntax files [--pipe]') +commandline.registeraction('bbeditinterface' , 'generate bbedit syntax files [--pipe]') +commandline.registeraction('sciteinterface' , 'generate scite syntax files [--pipe]') +commandline.registeraction('rawinterface' , 'generate raw syntax files [--pipe]') +# commandline.registeraction('translateinterface', 'generate interface files (xml) [nl de ..]') +commandline.registeraction('purgefiles' , 'remove temporary files [--all --recurse] [basename]') +commandline.registeraction('documentation' , 'generate documentation [--type=] [filename]') +commandline.registeraction('filterpages' ) # no help, hidden temporary feature +commandline.registeraction('patternfiles' , 'generate pattern files [--all --xml --utf8] [languagecode]') +commandline.registeraction('dpxmapfiles' , 'convert pdftex mapfiles to dvipdfmx [--force] [texmfroot]') +commandline.registeraction('listentities' , 'create doctype entity definition from enco-uc.tex') +commandline.registeraction('brandfiles' , 'add context copyright notice [--force]') +commandline.registeraction('platformize' , 'replace line-endings [--recurse --force] [pattern]') +commandline.registeraction('dependencies' , 'analyze depedencies within context [--save --compact --filter=[macros|filenames]] [filename]') +commandline.registeraction('updatecontext' , 'download latest version and remake formats [--proxy]') +commandline.registeraction('disarmutfbom' , 'remove utf bom [--force]') + +commandline.registervalue('type','') +commandline.registervalue('filter','') +commandline.registervalue('maproot','') +commandline.registervalue('proxy','') + +commandline.registerflag('recurse') +commandline.registerflag('force') +commandline.registerflag('compact') +commandline.registerflag('pipe') +commandline.registerflag('save') +commandline.registerflag('all') +commandline.registerflag('xml') +commandline.registerflag('log') +commandline.registerflag('utf8') +commandline.registerflag('doctype') + +# general + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/ruby/fcd_start.rb b/scripts/context/ruby/fcd_start.rb new file mode 100644 index 000000000..b1fa42a2a --- /dev/null +++ b/scripts/context/ruby/fcd_start.rb @@ -0,0 +1,472 @@ +# Hans Hagen / PRAGMA ADE / 2005 / www.pragma-ade.com +# +# Fast Change Dir +# +# This is a kind of variant of the good old ncd +# program. This script uses the same indirect cmd +# trick as Erwin Waterlander's wcd program. +# +# === windows: fcd.cmd === +# +# @echo off +# ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9 +# if exist "%HOME%/fcd_stage.cmd" call %HOME%/fcd_stage.cmd +# +# === linux: fcd (fcd.sh) === +# +# !/usr/bin/env sh +# ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9 +# if test -f "$HOME/fcd_stage.sh" ; then +# . $HOME/fcd_stage.sh ; +# fi; +# +# === +# +# On linux, one should source the file: ". fcd args" in order +# to make the chdir persistent. +# +# You can create a stub with: +# +# ruby fcd_start.rb --stub --verbose +# +# usage: +# +# fcd --make t:\ +# fcd --add f:\project +# fcd [--find] whatever +# fcd [--find] whatever c (c being a list entry) +# fcd [--find] whatever . (last choice with this pattern) +# fcd --list + +# todo: HOMEDRIVE\HOMEPATH + +require 'rbconfig' + +class FastCD + + @@rootpath = nil + + ['HOME','TEMP','TMP','TMPDIR'].each do |key| + if ENV[key] then + if FileTest.directory?(ENV[key]) then + @@rootpath = ENV[key] + break + end + end + end + + exit unless @@rootpath + + @@mswindows = Config::CONFIG['host_os'] =~ /mswin/ + @@maxlength = 26 + + require 'Win32API' if @@mswindows + + if @@mswindows then + @@stubcode = [ + '@echo off', + '', + 'if not exist "%HOME%" goto temp', + '', + ':home', + '', + 'ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9', + '', + 'if exist "%HOME%\fcd_stage.cmd" call %HOME%\fcd_stage.cmd', + 'goto end', + '', + ':temp', + '', + 'ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9', + '', + 'if exist "%TEMP%\fcd_stage.cmd" call %TEMP%\fcd_stage.cmd', + 'goto end', + '', + ':end' + ].join("\n") + else + @@stubcode = [ + '#!/usr/bin/env sh', + '', + 'ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9', + '', + 'if test -f "$HOME/fcd_stage.sh" ; then', + ' . $HOME/fcd_stage.sh ;', + 'fi;' + ].join("\n") + end + + @@selfpath = File.dirname($0) + @@datafile = File.join(@@rootpath,'fcd_state.dat') + @@histfile = File.join(@@rootpath,'fcd_state.his') + @@cdirfile = File.join(@@rootpath,if @@mswindows then 'fcd_stage.cmd' else 'fcd_stage.sh' end) + @@stubfile = File.join(@@selfpath,if @@mswindows then 'fcd.cmd' else 'fcd' end) + + def initialize(verbose=false) + @list = Array.new + @hist = Hash.new + @result = Array.new + @pattern = '' + @result = '' + @verbose = verbose + if f = File.open(@@cdirfile,'w') then + f << "#{if @@mswindows then 'rem' else '#' end} no dir to change to" + f.close + else + report("unable to create stub #{@@cdirfile}") + end + end + + def filename(name) + File.join(@@root,name) + end + + def report(str,verbose=@verbose) + puts(">> #{str}") if verbose + end + + def flush(str,verbose=@verbose) + print(str) if verbose + end + + def clear + if FileTest.file?(@@histfile) + begin + File.delete(@@histfile) + rescue + report("error in deleting history file '#{@histfile}'") + else + report("history file '#{@histfile}' is deleted") + end + else + report("no history file '#{@histfile}'") + end + end + + def scan(dir='.') + begin + [dir].flatten.sort.uniq.each do |dir| + begin + Dir.chdir(dir) + report("scanning '#{dir}'") + # flush(">> ") + Dir.glob("**/*").each do |d| + if FileTest.directory?(d) then + @list << File.expand_path(d) + # flush(".") + end + end + # flush("\n") + @list = @list.sort.uniq + report("#{@list.size} entries found") + rescue + report("unknown directory '#{dir}'") + end + end + rescue + report("invalid dir specification ") + end + end + + def save + begin + if f = File.open(@@datafile,'w') then + @list.each do |l| + f.puts(l) + end + f.close + report("#{@list.size} status bytes saved in #{@@datafile}") + else + report("unable to save status in #{@@datafile}") + end + rescue + report("error in saving status in #{@@datafile}") + end + end + + def remember + if @hist[@pattern] == @result then + # no need to save result + else + begin + if f = File.open(@@histfile,'w') then + @hist[@pattern] = @result + @hist.keys.each do |k| + f.puts("#{k} #{@hist[k]}") + end + f.close + report("#{@hist.size} history entries saved in #{@@histfile}") + else + report("unable to save history in #{@@histfile}") + end + rescue + report("error in saving history in #{@@histfile}") + end + end + end + + def load + begin + @list = IO.read(@@datafile).split("\n") + report("#{@list.length} status bytes loaded from #{@@datafile}") + rescue + report("error in loading status from #{@@datafile}") + end + begin + IO.readlines(@@histfile).each do |line| + if line =~ /^(.*?)\s+(.*)$/i then + @hist[$1] = $2 + end + end + report("#{@hist.length} history entries loaded from #{@@histfile}") + rescue + report("error in loading history from #{@@histfile}") + end + end + + def show + begin + puts("directories:") + puts("\n") + if @list.length > 0 then + @list.each do |l| + puts(l) + end + else + puts("no entries") + end + puts("\n") + puts("history:") + puts("\n") + if @hist.length > 0 then + @hist.keys.sort.each do |h| + puts("#{h} >> #{@hist[h]}") + end + else + puts("no entries") + end + rescue + end + end + + def find(pattern=nil) + begin + if pattern = [pattern].flatten.first then + if pattern.length > 0 and @pattern = pattern then + @result = @list.grep(/\/#{@pattern}$/i) + if @result.length == 0 then + @result = @list.grep(/\/#{@pattern}[^\/]*$/i) + end + end + else + puts(Dir.pwd.gsub(/\\/o, '/')) + end + rescue + puts("some error") + end + end + + def chdir(dir) + begin + if dir then + if f = File.open(@@cdirfile,'w') then + if @@mswindows then + f.puts("cd /d #{dir.gsub('/','\\')}") + else + f.puts("cd #{dir.gsub("\\",'/')}") + end + f.close + end + @result = dir + report("changing to #{dir}",true) + else + report("not changing dir") + end + rescue + end + end + + def choose(args=[]) + offset = 97 + unless @pattern.empty? then + begin + case @result.size + when 0 then + report("dir '#{@pattern}' not found",true) + when 1 then + chdir(@result[0]) + else + list = @result.dup + begin + if answer = args[1] then # assignment & test + if answer == '.' and @hist.key?(@pattern) then + if FileTest.directory?(@hist[@pattern]) then + print("last choice ") + chdir(@hist[@pattern]) + return + end + else + index = answer[0] - offset + if dir = list[index] then + chdir(dir) + return + end + end + end + rescue + puts("some error") + end + loop do + print("\n") + list.each_index do |i| +begin + if i < @@maxlength then + # puts("#{(i+?a).chr} #{list[i]}") + puts("#{(i+offset).chr} #{list[i]}") + else + puts("\n there are #{list.length-@@maxlength} entries more") + break + end +rescue + puts("some error") +end + end + print("\n>> ") + if answer = wait then + if answer >= offset and answer <= offset+25 then + index = answer - offset + if dir = list[index] then + print("#{answer.chr} ") + chdir(dir) + elsif @hist.key?(@pattern) and FileTest.directory?(@hist[@pattern]) then + print("last choice ") + chdir(@hist[@pattern]) + else + print("quit\n") + end + break + elsif list.length >= @@maxlength then + @@maxlength.times do |i| list.shift end + print("next set") + print("\n") + elsif @hist.key?(@pattern) and FileTest.directory?(@hist[@pattern]) then + print("last choice ") + chdir(@hist[@pattern]) + break + else + print("quit\n") + break + end + end + end + end + rescue + report($!) + end + end + end + + def wait + begin + $stdout.flush + return getc + rescue + return nil + end + end + + def getc + begin + if @@mswindows then + ch = Win32API.new('crtdll','_getch',[],'L').call + else + system('stty raw -echo') + ch = $stdin.getc + system('stty -raw echo') + end + rescue + ch = nil + end + return ch + end + + def check + unless FileTest.file?(@@stubfile) then + report("creating stub #{@@stubfile}") + begin + if f = File.open(@@stubfile,'w') then + f.puts(@@stubcode) + f.close + end + rescue + report("unable to create stub #{@@stubfile}") + else + unless @mswindows then + begin + File.chmod(0755,@@stubfile) + rescue + report("unable to change protections on #{@@stubfile}") + end + end + end + else + report("stub #{@@stubfile} already present") + end + end + +end + +$stdout.sync = true + +verbose, action, args = false, :find, Array.new + +usage = "fcd [--add|clear|find|list|make|show|stub] [--verbose] [pattern]" +version = "1.0.2" + +def quit(message) + puts(message) + exit +end + +ARGV.each do |a| + case a + when '-a', '--add' then action = :add + when '-c', '--clear' then action = :clear + when '-f', '--find' then action = :find + when '-l', '--list' then action = :show + when '-m', '--make' then action = :make + when '-s', '--show' then action = :show + when '--stub' then action = :stub + when '-v', '--verbose' then verbose = true + when '--version' then quit("version: #{version}") + when '-h', '--help' then quit("usage: #{usage}") + when /^\-\-.*/ then quit("error: unknown switch #{a}, try --help") + else args << a + end +end + +fcd = FastCD.new(verbose) +fcd.report("Fast Change Dir / version #{version}") + +case action + when :make then + fcd.clear + fcd.scan(args) + fcd.save + when :clear then + fcd.clear + when :add then + fcd.load + fcd.scan(args) + fcd.save + when :show then + fcd.load + fcd.show + when :find then + fcd.load + fcd.find(args) + fcd.choose(args) + fcd.remember + when :stub + fcd.check +end diff --git a/scripts/context/ruby/graphics/gs.rb b/scripts/context/ruby/graphics/gs.rb new file mode 100644 index 000000000..6143c8812 --- /dev/null +++ b/scripts/context/ruby/graphics/gs.rb @@ -0,0 +1,684 @@ +# module : graphics/gs +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# ['base/variables','../variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end +# ['base/system', '../system', 'system' ].each do |r| begin require r ; rescue Exception ; else break ; end ; end + +require 'base/variables' +require 'base/system' +require 'fileutils' +# Require 'ftools' + +class GhostScript + + include Variables + + @@pdftrimwhite = 'pdftrimwhite.pl' + + @@pstopdfoptions = [ + 'AntiAliasColorImages', + 'AntiAliasGrayImages', + 'AntiAliasMonoImages', + 'ASCII85EncodePages', + 'AutoFilterColorImages', + 'AutoFilterGrayImages', + 'AutoPositionEPSFiles', + 'AutoRotatePages', + 'Binding', + 'ColorConversionStrategy', + 'ColorImageDepth', + 'ColorImageDownsampleThreshold', + 'ColorImageDownsampleType', + 'ColorImageFilter', + 'ColorImageResolution', + 'CompatibilityLevel', + 'CompressPages', + #'ConvertCMYKImagesToRGB', # buggy + #'ConvertImagesToIndexed', # buggy + 'CreateJobTicket', + 'DetectBlends', + 'DoThumbnails', + 'DownsampleColorImages', + 'DownsampleGrayImages', + 'DownsampleMonoImages', + 'EmbedAllFonts', + 'EncodeColorImages', + 'EncodeGrayImages', + 'EncodeMonoImages', + 'EndPage', + 'FirstPage', + 'GrayImageDepth', + 'GrayImageDownsampleThreshold', + 'GrayImageDownsampleType', + 'GrayImageFilter', + 'GrayImageResolution', + 'MaxSubsetPct', + 'MonoImageDepth', + 'MonoImageDownsampleThreshold', + 'MonoImageDownsampleType', + 'MonoImageFilter', + 'MonoImageResolution', + 'Optimize', + 'ParseDCSComments', + 'ParseDCSCommentsForDocInfo', + 'PreserveCopyPage', + 'PreserveEPSInfo', + 'PreserveHalftoneInfo', + 'PreserveOPIComments', + 'PreserveOverprintSettings', + 'SubsetFonts', + 'UseFlateCompression' + ] + + @@methods = Hash.new + + @@methods['raw'] = '1' + @@methods['bound'] = '2' + @@methods['bounded'] = '2' + @@methods['crop'] = '3' + @@methods['cropped'] = '3' + @@methods['down'] = '4' + @@methods['downsample'] = '4' + @@methods['downsampled'] = '4' + @@methods['simplify'] = '5' + @@methods['simplified'] = '5' + + @@tempfile = 'gstemp' + @@pstempfile = @@tempfile + '.ps' + @@pdftempfile = @@tempfile + '.pdf' + + @@bboxspec = '\s*([\-\d\.]+)' + '\s+([\-\d\.]+)'*3 + + def initialize(logger=nil) + + unless logger then + puts('gs class needs a logger') + exit + end + + @variables = Hash.new + @psoptions = Hash.new + @logger = logger + + setvariable('profile', 'gsprofile.ini') + setvariable('pipe', true) + setvariable('method', 2) + setvariable('force', false) + setvariable('colormodel', 'cmyk') + setvariable('inputfile', '') + setvariable('outputfile', '') + + @@pstopdfoptions.each do |key| + @psoptions[key] = '' + end + + reset + + end + + def reset + @llx = @lly = @ulx = @uly = 0 + @oldbbox = [@llx,@lly,@urx,@ury] + @width = @height = @xoffset = @yoffset = @offset = 0 + @rs = Tool.default_line_separator + end + + def supported?(filename) + psfile?(filename) || pdffile?(filename) + end + + def psfile?(filename) + filename =~ /\.(eps|epsf|ps|ai\d*)$/io + end + + def pdffile?(filename) + filename =~ /\.(pdf)$/io + end + + def setpsoption(key,value) + @psoptions[key] = value unless value.empty? + end + + def setdimensions (llx,lly,urx,ury) + @oldbbox = [llx,lly,urx,ury] + @llx, @lly = llx.to_f-@offset, lly.to_f-@offset + @urx, @ury = urx.to_f+@offset, ury.to_f+@offset + @width, @height = @urx - @llx, @ury - @lly + @xoffset, @yoffset = 0 - @llx, 0 - @lly + end + + def setoffset (offset=0) + @offset = offset.to_f + setdimensions(@llx,@lly,@urx,@ury) if dimensions? + end + + def resetdimensions + setdimensions(0,0,0,0) + end + + def dimensions? + (@width>0) && (@height>0) + end + + def convert + + inpfile = getvariable('inputfile') + + if inpfile.empty? then + report('no inputfile specified') + return false + end + + unless FileTest.file?(inpfile) then + report("unknown input file #{inpfile}") + return false + end + + outfile = getvariable('outputfile') + + if outfile.empty? then + outfile = inpfile + outfile = outfile.sub(/^.*[\\\/]/,'') + end + + outfile = outfile.sub(/\.(pdf|eps|ps|ai)/i, "") + resultfile = outfile + '.pdf' + setvariable('outputfile', resultfile) + + # flags + + saveprofile(getvariable('profile')) + + begin + gsmethod = method(getvariable('method')).to_i + report("conversion method #{gsmethod}") + rescue + gsmethod = 1 + report("fallback conversion method #{gsmethod}") + end + + debug('piping data') if getvariable('pipe') + + ok = false + begin + case gsmethod + when 0, 1 then ok = convertasis(inpfile,resultfile) + when 2 then ok = convertbounded(inpfile,resultfile) + when 3 then ok = convertcropped(inpfile,resultfile) + when 4 then ok = downsample(inpfile,resultfile,'screen') + when 5 then ok = downsample(inpfile,resultfile,'prepress') + else report("invalid conversion method #{gsmethod}") + end + rescue + report("job aborted due to some error: #{$!}") + begin + File.delete(resultfile) if FileTest.file?(resultfile) + rescue + report("unable to delete faulty #{resultfile}") + end + ok = false + ensure + deleteprofile(getvariable('profile')) + File.delete(@@pstempfile) if FileTest.file?(@@pstempfile) + File.delete(@@pdftempfile) if FileTest.file?(@@pdftempfile) + end + return ok + end + + # private + + def method (str) + if @@methods.key?(str) then + @@methods[str] + else + str + end + end + + def pdfmethod? (str) + case method(str).to_i + when 1, 3, 4, 5 then return true + end + return false + end + + def pdfprefix (str) + case method(str).to_i + when 1 then return 'raw-' + when 4 then return 'lowres-' + when 5 then return 'normal-' + end + return '' + end + + def psmethod? (str) + ! pdfmethod?(str) + end + + def insertprofile (flags) + for key in flags.keys do + replacevariable("flag.#{key}", flags[key]) + end + end + + def deleteprofile (filename) + begin + File.delete(filename) if FileTest.file?(filename) + rescue + end + end + + def saveprofile (filename) + return if filename.empty? || ! (ini = open(filename,"w")) + @@pstopdfoptions.each do |k| + str = @psoptions[k] + # beware, booleans are translated, but so are yes/no which is dangerous + if str.class == String then + if ! str.empty? && (str != 'empty') then + str.sub!(/(.+)\-/io, '') + str = "/" + str unless str =~ /^(true|false|none|[\d\.\-\+]+)$/ + ini.puts("-d#{k}=#{str}\n") + end + end + end + ini.close + debug("gs profile #{filename} saved") + end + + def gsstream # private + if getvariable('pipe') then '-' else @@pstempfile end + end + + def gscolorswitch + case getvariable('colormodel') + when 'cmyk' then '-dProcessColorModel=/DeviceCMYK -dColorConversionStrategy=/CMYK ' + when 'rgb' then '-dProcessColorModel=/DeviceRGB -dColorConversionStrategy=/RGB ' + when 'gray' then '-dProcessColorModel=/DeviceGRAY -dColorConversionStrategy=/GRAY ' + else + '' + end + end + + def gsdefaults + defaults = '' + begin + defaults << '-dAutoRotatePages=/None ' if @psoptions['AutoRotatePages'].empty? + rescue + defaults << '-dAutoRotatePages=/None ' + end + return defaults + end + + def convertasis (inpfile, outfile) + + report("converting #{inpfile} as-is") + + @rs = Tool.line_separator(inpfile) + debug("platform mac") if @rs == "\r" + + arguments = '' + arguments << "\@gsprofile.ini " + arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH " + arguments << "#{gsdefaults} " + arguments << "#{gscolorswitch} " + arguments << "-sOutputFile=#{outfile} #{inpfile} -c quit " + + debug("ghostscript: #{arguments}") + unless ok = System.run('ghostscript',arguments) then + begin + report("removing file #{outfile}") + File.delete(outfile) if FileTest.file?(outfile) + rescue + debug("file #{outfile} may be invalid") + end + end + return ok + + end + + def convertbounded(inpfile, outfile) + report("converting #{inpfile} bounded") + do_convertbounded(inpfile, outfile) + end + + def do_convertbounded(inpfile, outfile) + + begin + return false if FileTest.file?(outfile) && (! File.delete(outfile)) + rescue + return false + end + + arguments = '' + arguments << "\@gsprofile.ini " + arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH -dSAFER " + arguments << "#{gscolorswitch} " + arguments << "#{gsdefaults} " + arguments << "-sOutputFile=#{outfile} #{gsstream} -c quit " + + debug("ghostscript: #{arguments}") + debug('opening input file') + + @rs = Tool.line_separator(inpfile) + debug("platform mac") if @rs == "\r" + + if FileTest.file?(outfile) and not File.writable?(outfile) then + report("output file cannot be written") + return false + elsif not tmp = open(inpfile, 'rb') then + report("input file cannot be opened") + return false + end + + debug('opening pipe/file') + + if getvariable('pipe') then + + return false unless eps = IO.popen(System.command('ghostscript',arguments),'wb') + debug('piping data') + unless pipebounded(tmp,eps) then + debug('something went wrong in the pipe') + File.delete(outfile) if FileTest.file?(outfile) + end + debug('closing pipe') + eps.close_write + + else + + return false unless eps = File.open(@@pstempfile, 'wb') + + debug('copying data') + + if pipebounded(tmp,eps) then + eps.close + debug('processing temp file') + begin + ok = System.run('ghostscript',arguments) + rescue + ok = false + # debug("fatal error: #{$!}") + ensure + end + else + eps.close + ok = false + end + + unless ok then + begin + report('no output file due to error') + File.delete(outfile) if FileTest.file?(outfile) + rescue + # debug("fatal error: #{$!}") + debug('file',outfile,'may be invalid') + end + end + + debug('deleting temp file') + begin + File.delete(@@pstempfile) if FileTest.file?(@@pstempfile) + rescue + end + + end + + tmp.close + return FileTest.file?(outfile) + + end + + # hm, strange, no execute here, todo ! ! ! + + def getdimensions (inpfile) + + # -dEPSFitPage and -dEPSCrop behave weird (don't work) + + arguments = "-sDEVICE=bbox -dSAFER -dNOPAUSE -dBATCH #{inpfile} " + + debug("ghostscript: #{arguments}") + + begin + bbox = System.run('ghostscript',arguments,true,true) + rescue + bbox = '' + end + + resetdimensions + + debug('bbox spec', bbox) + + if bbox =~ /(Exact|HiRes)BoundingBox:#{@@bboxspec}/moi then + debug("high res bbox #{$2} #{$3} #{$4} #{$5}") + setdimensions($2,$3,$4,$5) + elsif bbox =~ /BoundingBox:#{@@bboxspec}/moi + debug("low res bbox #{$1} #{$2} #{$3} #{$4}") + setdimensions($1,$2,$3,$4) + end + + return dimensions? + + end + + # def convertcropped (inpfile, outfile) + # report("converting #{inpfile} cropped") + # do_convertbounded(inpfile, @@pdftempfile) + # return unless FileTest.file?(@@pdftempfile) + # arguments = " --offset=#{@offset} #{@@pdftempfile} #{outfile}" + # report("calling #{@@pdftrimwhite}") + # unless ok = System.run(@@pdftrimwhite,arguments) then + # report('cropping failed') + # begin + # File.delete(outfile) + # rescue + # end + # begin + # File.move(@@pdftempfile,outfile) + # rescue + # File.copy(@@pdftempfile,outfile) + # File.delete(@@pdftempfile) + # end + # end + # return ok + # end + + def convertcropped (inpfile, outfile) + report("converting #{inpfile} cropped") + if File.expand_path(inpfile) == File.expand_path(outfile) then + report("output filename must be different") + elsif inpfile =~ /\.pdf$/io then + System.run("pdftops -eps #{inpfile} #{@@pstempfile}") + if getdimensions(@@pstempfile) then + report("tight boundingbox found") + end + do_convertbounded(@@pstempfile, outfile) + File.delete(@@pstempfile) if FileTest.file?(@@pstempfile) + else + if getdimensions(inpfile) then + report("tight boundingbox found") + end + do_convertbounded(inpfile, outfile) + end + resetdimensions + return true + end + + + def pipebounded (eps, out) + + epsbbox, skip, buffer = false, false, '' + + while str = eps.gets(rs=@rs) do + if str =~ /^%!PS/oi then + debug("looks like a valid ps file") + break + elsif str =~ /%PDF\-\d+\.\d+/oi then + debug("looks like a pdf file, so let\'s quit") + return false + end + end + + # why no BeginData check + + eps.rewind + +if dimensions? then + + debug('using found boundingbox') + +else + + debug('locating boundingbox') + while str = eps.gets(rs=@rs) do + case str + when /^%%Page:/io then + break + when /^%%(Crop|HiResBounding|ExactBounding)Box:#{@@bboxspec}/moi then + debug('high res boundingbox found') + setdimensions($2,$3,$4,$5) + break + when /^%%BoundingBox:#{@@bboxspec}/moi then + debug('low res boundingbox found') + setdimensions($1,$2,$3,$4) + end + end + debug('no boundingbox found') if @width == 0 + +end + + eps.rewind + + while str = eps.gets(rs=@rs) do + if str.sub!(/^(.*)%!PS/moi, "%!PS") then + debug("removing pre banner data") + out.puts(str) + break + end + end + + while str = eps.gets(rs=@rs) do + if skip then + skip = false if str =~ /^%+(EndData|EndPhotoshop|BeginProlog).*$/o + out.puts(str) if $1 == "BeginProlog" + elsif str =~ /^%(BeginPhotoshop)\:\s*\d+.*$/o then + skip = true + elsif str =~ /^%%/mos then + if ! epsbbox && str =~ /^%%(Page:|EndProlog)/io then + out.puts(str) if $1 == "EndProlog" + debug('faking papersize') + # out.puts("<< /PageSize [#{@width} #{@height}] >> setpagedevice\n") + if ! dimensions? then + out.puts("<< /PageSize [1 1] >> setpagedevice\n") + else + out.puts("<< /PageSize [#{@width} #{@height}] >> setpagedevice\n") + end + out.puts("gsave #{@xoffset} #{@yoffset} translate\n") + epsbbox = true + elsif str =~ /^%%BeginBinary\:\s*\d+\s*$/o then + debug('copying binary data') + out.puts(str) + while str = eps.gets(rs=@rs) + if str =~ /^%%EndBinary\s*$/o then + out.puts(str) + else + out.write(str) + end + end + elsif str =~ /^%AI9\_PrivateDataBegin/o then + debug('ignore private ai crap') + break + elsif str =~ /^%%EOF/o then + debug('ignore post eof crap') + break + # elsif str =~ /^%%PageTrailer/o then + # debug('ignoring post page trailer crap') + # break + elsif str =~ /^%%Trailer/o then + debug('ignoring post trailer crap') + break + elsif str =~ /^%%Creator.*Illustrator.*$/io then + debug('getting rid of problematic creator spec') + str = "% Creator: Adobe Illustrator ..." + out.puts(str) + elsif str =~ /^%%AI.*(PaperRect|Margin)/io then + debug('removing AI paper crap') + elsif str =~ /^%%AI.*Version.*$/io then + debug('removing dangerous version info') + elsif str =~ /^(%+AI.*Thumbnail.*)$/o then + debug('skipping AI thumbnail') + skip = true + else + out.puts(str) + end + else + out.puts(str) + end + end + + debug('done, sending EOF') + + out.puts "grestore\n%%EOF\n" + + # ok = $? == 0 + # report('process aborted, broken pipe, fatal error') unless ok + # return ok + +resetdimensions + + return true + + end + + def downsample (inpfile, outfile, method='screen') + + # gs <= 8.50 + + report("downsampling #{inpfile}") + + doit = true + unless getvariable('force') then + begin + if f = File.open(inpfile) then + f.binmode + while doit && (data = f.gets) do + if data =~ /\/ArtBox\s*\[\s*[\d\.]+\s+[\d\.]+\s+[\d\.]+\s+[\d\.]+\s*\]/io then + doit = false + end + end + f.close + end + rescue + end + end + + if doit then + arguments = '' + arguments << "-dPDFSETTINGS=/#{method} -dEmbedAllFonts=true " + arguments << "#{gscolorswitch} " + arguments << "#{gsdefaults} " + arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH -dSAFER " + arguments << "-sOutputFile=#{outfile} #{inpfile} -c quit " + unless ok = System.run('ghostscript',arguments) then + begin + File.delete(outfile) if FileTest.file?(outfile) + report("removing file #{outfile}") + rescue + debug("file #{outfile} may be invalid") + end + end + return ok + else + report("crop problem, straight copying #{inpfile}") + File.copy(inpfile,outfile) + return false + end + + end + +end diff --git a/scripts/context/ruby/graphics/inkscape.rb b/scripts/context/ruby/graphics/inkscape.rb new file mode 100644 index 000000000..8d3b26468 --- /dev/null +++ b/scripts/context/ruby/graphics/inkscape.rb @@ -0,0 +1,112 @@ +# module : graphics/inkscape +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# ['base/variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end +# ['graphics/gs','gs'].each do |r| begin require r ; rescue Exception ; else break ; end ; end + +require 'base/variables' +require 'base/system' +require 'graphics/gs' + +class InkScape + + include Variables + + def initialize(logger=nil) + + unless logger then + puts('inkscape class needs a logger') + exit + end + + @variables = Hash.new + @logger = logger + + reset + + end + + def reset + # nothing yet + end + + def supported?(filename) + filename =~ /.*\.(svg|svgz)/io + end + + def convert(logfile=System.null) + + directpdf = false + + logfile = logfile.gsub(/\/+$/,"") + + inpfilename = getvariable('inputfile').dup + outfilename = getvariable('outputfile').dup + outfilename = inpfilename.dup if outfilename.empty? + outfilename.gsub!(/(\.[^\.]*?)$/, ".pdf") + tmpfilename = outfilename.gsub(/(\.[^\.]*?)$/, ".ps") + + if inpfilename.empty? || outfilename.empty? then + report("no filenames given") + return false + end + if inpfilename == outfilename then + report("filenames must differ (#{inpfilename} #{outfilename})") + return false + end + unless FileTest.file?(inpfilename) then + report("unknown file #{inpfilename}") + return false + end + + # we need to redirect the error info else we get a pop up console + + if directpdf then + report("converting #{inpfilename} to #{outfilename}") + resultpipe = "--without-gui --export-pdf=\"#{outfilename}\" 2>#{logfile}" + else + report("converting #{inpfilename} to #{tmpfilename}") + resultpipe = "--without-gui --print=\">#{tmpfilename}\" 2>#{logfile}" + end + + arguments = [resultpipe,inpfilename].join(' ').gsub(/\s+/,' ') + + ok = true + begin + debug("inkscape: #{arguments}") + # should work + # ok = System.run('inkscape',arguments) # does not work here + # but 0.40 only works with this: + command = "inkscape #{arguments}" + report(command) + ok = system(command) + # and 0.41 fails with everything + # and 0.45 is better + rescue + report("aborted due to error") + return false + else + return false unless ok + end + + if not directpdf then + ghostscript = GhostScript.new(@logger) + ghostscript.setvariable('inputfile',tmpfilename) + ghostscript.setvariable('outputfile',outfilename) + report("converting #{tmpfilename} to #{outfilename}") + ghostscript.convert + begin + File.delete(tmpfilename) + rescue + end + end + end + +end diff --git a/scripts/context/ruby/graphics/magick.rb b/scripts/context/ruby/graphics/magick.rb new file mode 100644 index 000000000..f59087bdf --- /dev/null +++ b/scripts/context/ruby/graphics/magick.rb @@ -0,0 +1,161 @@ +# module : graphics/inkscape +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# ['base/variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end + +require 'base/variables' + +class ImageMagick + + include Variables + + def initialize(logger=nil) + + unless logger then + puts('magick class needs a logger') + exit + end + + @variables = Hash.new + @logger = logger + + reset + + end + + def reset + ['compression','depth','colorspace','quality'].each do |key| + setvariable(key) + end + end + + def supported?(filename) # ? pdf + filename =~ /.*\.(png|gif|tif|tiff|jpg|jpeg|eps|ai\d*)/io + end + + def convert(suffix='pdf') + + inpfilename = getvariable('inputfile').dup + outfilename = getvariable('outputfile').dup + outfilename = inpfilename.dup if outfilename.empty? + outfilename.gsub!(/(\.[^\.]*?)$/, ".#{suffix}") + + if inpfilename.empty? || outfilename.empty? then + report("no filenames given") + return false + end + if inpfilename == outfilename then + report("filenames must differ (#{inpfilename} #{outfilename})") + return false + end + unless FileTest.file?(inpfilename) then + report("unknown file #{inpfilename}") + return false + end + + if inpfilename =~ /\.tif+$/io then + tmpfilename = 'temp.png' + arguments = "#{inpfilename} #{tmpfilename}" + begin + debug("imagemagick: #{arguments}") + ok = System.run('imagemagick',arguments) + rescue + report("aborted due to error") + return false + else + return false unless ok + end + inpfilename = tmpfilename + end + + compression = depth = colorspace = quality = '' + + if getvariable('compression') =~ /(zip|jpeg)/o then + compression = " -compress #{$1}" + end + if getvariable('depth') =~ /(8|16)/o then + depth = "-depth #{$1}" + end + if getvariable('colorspace') =~ /(gray|rgb|cmyk)/o then + colorspace = "-colorspace #{$1}" + end + case getvariable('quality') + when 'low' then quality = '-quality 0' + when 'medium' then quality = '-quality 75' + when 'high' then quality = '-quality 100' + end + + report("converting #{inpfilename} to #{outfilename}") + + arguments = [compression,depth,colorspace,quality,inpfilename,outfilename].join(' ').gsub(/\s+/,' ') + + begin + debug("imagemagick: #{arguments}") + ok = System.run('imagemagick',arguments) + rescue + report("aborted due to error") + return false + else + return ok + end + + end + + def autoconvert + + inpfilename = getvariable('inputfile') + outfilename = getvariable('outputfile') + + if inpfilename.empty? || ! FileTest.file?(inpfilename) then + report("missing file #{inpfilename}") + return + end + + outfilename = inpfilename.dup if outfilename.empty? + tmpfilename = 'temp.jpg' + + reset + + megabyte = 1024*1024 + + ok = false + + if FileTest.size(inpfilename)>2*megabyte + setvariable('compression','zip') + ok = convert + else + setvariable('compression','jpeg') + if FileTest.size(inpfilename)>10*megabyte then + setvariable('quality',85) + elsif FileTest.size(inpfilename)>5*megabyte then + setvariable('quality',90) + else + setvariable('quality',95) + end + report("auto quality #{getvariable('quality')}") + setvariable('outputfile', tmpfilename) + ok = convert('jpg') + setvariable('inputfile', tmpfilename) + setvariable('outputfile', outfilename) + ok = convert + begin + File.delete(tmpfilename) + rescue + report("#{tmpfilename} cannot be deleted") + end + end + + reset + + return ok + + end + +end diff --git a/scripts/context/ruby/imgtopdf.rb b/scripts/context/ruby/imgtopdf.rb new file mode 100644 index 000000000..98a36c17f --- /dev/null +++ b/scripts/context/ruby/imgtopdf.rb @@ -0,0 +1,86 @@ +#!/usr/bin/env ruby + +# program : newimgtopdf +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2006 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +unless defined? ownpath + ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'') + $: << ownpath +end + +require 'base/switch' +require 'base/logger' + +require 'graphics/magick' + +banner = ['ImgToPdf', 'version 1.1.2', '2002-2006', 'PRAGMA ADE/POD'] + +class Commands + + include CommandBase + + # nowadays we would force a directive, but + # for old times sake we handle default usage + + def main + filename = @commandline.argument('first') + + if filename.empty? then + help + else + convert + end + end + + # actions + + def convert + + magick = Magick.new(session) + + ['compression','depth','colorspace','quality','inputpath','outputpath'].each do |v| + magick.setvariable(v,@commandline.option(v)) + end + + @commandline.arguments.each do |fullname| + magick.setvariable('inputfile',fullname) + magick.setvariable('outputfile',fullname.gsub(/(\..*?$)/io, '.pdf')) + if @commandline.option('auto') then + magick.autoconvert + else + magick.convert + end + end + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registerflag('auto') + +commandline.registervalue('compression') +commandline.registervalue('depth') +commandline.registervalue('colorspace') +commandline.registervalue('quality') + +commandline.registervalue('inputpath') +commandline.registervalue('outputpath') + + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registeraction('convert', 'convert image into pdf') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'main') diff --git a/scripts/context/ruby/mpstools.rb b/scripts/context/ruby/mpstools.rb new file mode 100644 index 000000000..534bfb95b --- /dev/null +++ b/scripts/context/ruby/mpstools.rb @@ -0,0 +1,7 @@ +# todo +# +# this script will replace mptopdf and makempy + +puts("This program is yet unfinished, for the moment it just calls 'mptopdf'.\n\n") + +system("texmfstart mptopdf #{ARGV.join(' ')}") diff --git a/scripts/context/ruby/mtxtools.rb b/scripts/context/ruby/mtxtools.rb new file mode 100644 index 000000000..41d0f7085 --- /dev/null +++ b/scripts/context/ruby/mtxtools.rb @@ -0,0 +1,475 @@ +#!/usr/bin/env ruby + +# program : mtxtools +# copyright : PRAGMA Advanced Document Engineering +# version : 2004-2005 +# author : Hans Hagen +# +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# This script hosts MetaTeX related features. + +banner = ['MtxTools', 'version 1.0.0', '2006', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' +require 'base/system' +require 'base/kpse' + +class Reporter + def report(str) + puts(str) + end +end + +module ConTeXt + + def ConTeXt::banner(filename,companionname,compact=false) + "-- filename : #{File.basename(filename)}\n" + + "-- comment : companion to #{File.basename(companionname)} (in ConTeXt)\n" + + "-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL\n" + + "-- copyright: PRAGMA ADE / ConTeXt Development Team\n" + + "-- license : see context related readme files\n" + + if compact then "\n-- remark : compact version\n" else "" end + end + +end + +class UnicodeTables + + @@version = "1.001" + + @@shape_a = /^((GREEK|LATIN|HEBREW)\s*(SMALL|CAPITAL|)\s*LETTER\s*[A-Z]+)$/ + @@shape_b = /^((GREEK|LATIN|HEBREW)\s*(SMALL|CAPITAL|)\s*LETTER\s*[A-Z]+)\s*(.+)$/ + + @@shape_a = /^(.*\s*LETTER\s*[A-Z]+)$/ + @@shape_b = /^(.*\s*LETTER\s*[A-Z]+)\s+WITH\s+(.+)$/ + + attr_accessor :context, :comment + + def initialize(logger=Reporter.new) + @data = Array.new + @logger = logger + @error = false + @context = true + @comment = true + @shapes = Hash.new + end + + def load_unicode_data(filename='unicodedata.txt') + # beware, the unicodedata table is bugged, sometimes ending + @logger.report("reading base data from #{filename}") if @logger + begin + IO.readlines(filename).each do |line| + if line =~ /^[0-9A-F]{4,4}/ then + d = line.chomp.sub(/\;$/, '').split(';') + if d then + while d.size < 15 do d << '' end + n = d[0].hex + @data[n] = d + if d[1] =~ @@shape_a then + @shapes[$1] = d[0] + end + end + end + end + rescue + @error = true + @logger.report("error while reading base data from #{filename}") if @logger + end + end + + def load_context_data(filename='contextnames.txt') + @logger.report("reading data from #{filename}") if @logger + begin + IO.readlines(filename).each do |line| + if line =~ /^[0-9A-F]{4,4}/ then + d = line.chomp.split(';') + if d then + n = d[0].hex + if @data[n] then + @data[d[0].hex] << d[1] # adobename == 15 + @data[d[0].hex] << d[2] # contextname == 16 + else + @logger.report("missing information about #{d} in #{filename}") if @logger + end + end + end + end + rescue + @error = true + @logger.report("error while reading context data from #{filename}") if @logger + end + end + + def save_metatex_data(filename='char-def.lua',compact=false) + if not @error then + begin + File.open(filename,'w') do |f| + @logger.report("saving data in #{filename}") if @logger + f << ConTeXt::banner(filename,'char-def.tex',compact) + f << "\n" + f << "\nif not versions then versions = { } end versions['#{filename.gsub(/\..*?$/,'')}'] = #{@@version}\n" + f << "\n" + f << "if not characters then characters = { } end\n" + f << "if not characters.data then characters.data = { } end\n" + f << "\n" + f << "characters.data = {\n" if compact + @data.each do |d| + if d then + r = metatex_data(d) + if compact then + f << "\t" << "[0x#{d[0]}]".rjust(8,' ') << " = { #{r.join(", ").gsub(/\t/,'')} }, \n" + else + f << "characters.define { -- #{d[0].hex}" << "\n" + f << r.join(",\n") << "\n" + f << "}" << "\n" + end + end + end + f << "}\n" if compact + end + rescue + @logger.report("error while saving data in #{filename}") if @logger + else + @logger.report("#{@data.size} (#{sprintf('%X',@data.size)}) entries saved in #{filename}") if @logger + end + else + @logger.report("not saving data in #{filename} due to previous error") if @logger + end + end + + def metatex_data(d) + r = Array.new + r << "\tunicodeslot=0x#{d[0]}" + if d[2] && ! d[2].empty? then + r << "\tcategory='#{d[2].downcase}'" + end + if @context then + if d[15] && ! d[15].empty? then + r << "\tadobename='#{d[15]}'" + end + if d[16] && ! d[16].empty? then + r << "\tcontextname='#{d[16]}'" + end + end + if @comment then + if d[1] == "" then + r << "\tdescription='#{d[10]}'" unless d[10].empty? + else + r << "\tdescription='#{d[1]}'" unless d[1].empty? + end + end + if d[1] =~ @@shape_b then + r << "\tshcode=0x#{@shapes[$1]}" if @shapes[$1] + end + if d[12] && ! d[12].empty? then + r << "\tuccode=0x#{d[12]}" + elsif d[14] && ! d[14].empty? then + r << "\tuccode=0x#{d[14]}" + end + if d[13] && ! d[13].empty? then + r << "\tlccode=0x#{d[13]}" + end + if d[5] && ! d[5].empty? then + special, specials = '', Array.new + c = d[5].split(/\s+/).collect do |cc| + if cc =~ /^\<(.*)\>$/io then + special = $1.downcase + else + specials << "0x#{cc}" + end + end + if specials.size > 0 then + special = 'char' if special.empty? + r << "\tspecials={'#{special}',#{specials.join(',')}}" + end + end + return r + end + + def save_xetex_data(filename='enco-utf.tex') + if not @error then + begin + minnumber, maxnumber, n = 0x001F, 0xFFFF, 0 + File.open(filename,'w') do |f| + @logger.report("saving data in #{filename}") if @logger + f << "% filename : #{filename}\n" + f << "% comment : poor man's alternative for a proper enco file\n" + f << "% this file is generated by mtxtools and can be\n" + f << "% used in xetex and luatex mkii mode\n" + f << "% author : Hans Hagen, PRAGMA-ADE, Hasselt NL\n" + f << "% copyright: PRAGMA ADE / ConTeXt Development Team\n" + f << "% license : see context related readme files\n" + f << "\n" + f << "\\ifx\\setcclcucx\\undefined\n" + f << "\n" + f << " \\def\\setcclcucx #1 #2 #3 %\n" + f << " {\\global\\catcode\"#1=11 \n" + f << " \\global\\lccode \"#1=\"#2 \n" + f << " \\global\\uccode \"#1=\"#3 }\n" + f << "\n" + f << "\\fi\n" + f << "\n" + @data.each do |d| + if d then + number, type = d[0], d[2].downcase + if number.hex >= minnumber && number.hex <= maxnumber && type =~ /^l(l|u|t)$/o then + if d[13] && ! d[13].empty? then + lc = d[13] + else + lc = number + end + if d[12] && ! d[12].empty? then + uc = d[12] + elsif d[14] && ! d[14].empty? then + uc = d[14] + else + uc = number + end + if @comment then + f << "\\setcclcuc #{number} #{lc} #{uc} % #{d[1]}\n" + else + f << "\\setcclcuc #{number} #{lc} #{uc} \n" + end + n += 1 + end + end + end + f << "\n" + f << "\\endinput\n" + end + rescue + @logger.report("error while saving data in #{filename}") if @logger + else + @logger.report("#{n} entries saved in #{filename}") if @logger + end + else + @logger.report("not saving data in #{filename} due to previous error") if @logger + end + end + +end + +class RegimeTables + + @@version = "1.001" + + def initialize(logger=Reporter.new) + @logger = logger + reset + end + + def reset + @code, @regime, @filename, @loaded = Array.new(256), '', '', false + (32..127).each do |i| + @code[i] = [sprintf('%04X',i), i.chr] + end + end + + def load(filename) + begin + reset + if filename =~ /regi\-(ini|run|uni|utf|syn)/ then + report("skipping #{filename}") + else + report("loading file #{filename}") + @regime, unicodeset = File.basename(filename).sub(/\..*?$/,''), false + IO.readlines(filename).each do |line| + case line + when /^\#/ then + # skip + when /^(0x[0-9A-F]+)\s+(0x[0-9A-F]+)\s+\#\s+(.*)$/ then + @code[$1.hex], unicodeset = [$2, $3], true + when /^(0x[0-9A-F]+)\s+(0x[0-9A-F]+)\s+/ then + @code[$1.hex], unicodeset = [$2, ''], true + end + end + reset if not unicodeset + end + rescue + report("problem in loading file #{filename}") + reset + else + if ! @regime.empty? then + @loaded = true + else + reset + end + end + end + + def save(filename,compact=false) + begin + if @loaded && ! @regime.empty? then + if File.expand_path(filename) == File.expand_path(@filename) then + report("saving in #{filename} is blocked") + else + report("saving file #{filename}") + File.open(filename,'w') do |f| + f << ConTeXt::banner(filename,'regi-ini.tex',compact) + f << "\n" + f << "\nif not versions then versions = { } end versions['#{filename.gsub(/\..*?$/,'')}'] = #{@@version}\n" + f << "\n" + f << "if not regimes then regimes = { } end\n" + f << "if not regimes.data then regimes.data = { } end\n" + f << "\n" + if compact then + f << "regimes.data[\"#{@regime}\"] = { [0] = \n\t" + i = 17 + @code.each_index do |c| + if (i-=1) == 0 then + i = 16 + f << "\n\t" + end + if @code[c] then + f << @code[c][0].rjust(6,' ') + else + f << "0x0000".rjust(6,' ') + end + f << ', ' if c<@code.length-1 + end + f << "\n}\n" + else + @code.each_index do |c| + if @code[c] then + f << someregimeslot(@regime,c,@code[c][0],@code[c][1]) + else + f << someregimeslot(@regime,c,'','') + end + end + end + end + end + end + rescue + report("problem in saving file #{filename} #{$!}") + end + end + + def report(str) + @logger.report(str) + end + + private + + def someregimeslot(regime,slot,unicodeslot,comment) + "regimes.define { #{if comment.empty? then '' else '-- ' end} #{comment}\n" + + "\tregime='#{regime}',\n" + + "\tslot='#{sprintf('0x%02X',slot)}',\n" + + "\tunicodeslot='#{if unicodeslot.empty? then '0x0000' else unicodeslot end}'\n" + + "}\n" + end + + public + + def RegimeTables::convert(filenames,compact=false) + filenames.each do |filename| + txtfile = File.expand_path(filename) + luafile = File.join(File.dirname(txtfile),'regi-'+File.basename(txtfile.sub(/\..*?$/, '.lua'))) + unless txtfile == luafile then + regime = RegimeTables.new + regime.load(txtfile) + regime.save(luafile,compact) + end + end + end + +end + +class Commands + + include CommandBase + + def unicodetable + unicode = UnicodeTables.new(logger) + unicode.load_unicode_data + unicode.load_context_data + unicode.save_metatex_data('char-def.lua',@commandline.option('compact')) + end + + def xetextable + unicode = UnicodeTables.new(logger) + unicode.load_unicode_data + unicode.load_context_data + # unicode.comment = false + unicode.save_xetex_data + end + + def regimetable + if @commandline.arguments.length > 0 then + RegimeTables::convert(@commandline.arguments, @commandline.option('compact')) + else + RegimeTables::convert(Dir.glob("cp*.txt") , @commandline.option('compact')) + RegimeTables::convert(Dir.glob("8859*.txt") , @commandline.option('compact')) + end + end + + def pdftextable + # instead of directly saving the data, we use luatex (kind of test) + pdfrdef = 'pdfr-def.tex' + tmpfile = 'mtxtools.tmp' + File.delete(pdfrdef) rescue false + if f = File.open(tmpfile,'w') then + f << "\\starttext\n" + f << "\\ctxlua{characters.pdftex.make_pdf_to_unicodetable('#{pdfrdef}')}\n" + f << "\\stoptext\n" + f.close() + system("texmfstart texexec --luatex --once --purge mtxtools.tmp") + report("vecor saved in #{pdfrdef}") + end + File.delete(tmpfile) rescue false + end + + def xmlmapfile + # instead of directly saving the data, we use luatex (kind of test) + tmpfile = 'mtxtools.tmp' + xmlsuffix = 'frx' + @commandline.arguments.each do |mapname| + if f = File.open(tmpfile,'w') then + xmlname = mapname.gsub(/\.map$/,".#{xmlsuffix}") + File.delete(xmlname) rescue false + f << "\\starttext\n" + f << "\\ctxlua{\n" + f << " mapname = input.find_file(texmf.instance,'#{mapname}') or ''\n" + f << " xmlname = '#{xmlname}'\n" + f << " if mapname and not mapname:is_empty() then\n" + f << " ctx.fonts.map.convert_file(mapname,xmlname)\n" + f << " end\n" + f << "}\n" + f << "\\stoptext\n" + f.close() + system("texmfstart texexec --luatex --once --purge mtxtools.tmp") + if FileTest.file?(xmlname) then + report("map file #{mapname} converted to #{xmlname}") + else + report("no valid map file #{mapname}") + end + end + end + File.delete(tmpfile) rescue false + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('unicodetable', 'create unicode table for metatex/luatex') +commandline.registeraction('regimetable' , 'create regime table(s) for metatex/luatex [--compact]') +commandline.registeraction('xetextable' , 'create unicode table for xetex') +commandline.registeraction('pdftextable' , 'create unicode table for xetex') +commandline.registeraction('xmlmapfile' , 'convert traditional mapfile to xml font resourse') + +# general + +commandline.registeraction('help') +commandline.registeraction('version') +commandline.registerflag('compact') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/ruby/pdftools.rb b/scripts/context/ruby/pdftools.rb new file mode 100644 index 000000000..8ad74ec4f --- /dev/null +++ b/scripts/context/ruby/pdftools.rb @@ -0,0 +1,861 @@ +#!/usr/bin/env ruby + +# program : pdftools +# copyright : PRAGMA Advanced Document Engineering +# version : 2003-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# This script will harbor some handy manipulations on tex +# related files. + +banner = ['PDFTools', 'version 1.2.1', '2003/2005', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' + +require 'fileutils' +# require 'ftools' + +class File + + def File.deletefiles(*filenames) + filenames.flatten.each do |filename| + begin + delete(filename) if FileTest.file?(filename) + rescue + end + end + end + + def File.needsupdate(oldname,newname) + begin + return File.stat(oldname).mtime != File.stat(newname).mtime + rescue + return true + end + end + + def File.syncmtimes(oldname,newname) + begin + t = Time.now # i'm not sure if the time is frozen, so we do it here + File.utime(0,t,oldname,newname) + rescue + end + end + + def File.replacesuffix(oldname,subpath='') + newname = File.expand_path(oldname.sub(/\.\w+?$/,'.pdf')) + File.join(File.dirname(newname),subpath,File.basename(newname)) + end + +end + +class ImageMagick + + def initialize + + begin + version = `convert -version` + rescue + @binary = nil + ensure + if (version) && (! version.empty?) && (version =~ /ImageMagick/mo) && (version =~ /version/mio) then + @binary = 'convert' + else + @binary = 'imagemagick' + end + end + + end + + def process(arguments) + begin + @binary && system("#{@binary} #{arguments}") + rescue + false + end + end + +end + +class TexExec + + def initialize + @binary = 'texmfstart texexec.pl --pdf --batch --silent --purge' + end + + def process(arguments,once=true) + begin + if once then + @binary && system("#{@binary} --once #{arguments}") + else + @binary && system("#{@binary} #{arguments}") + end + rescue + false + end + end + +end + +class PdfImages + + def initialize + @binary = "pdfimages" + end + + def process(arguments) + begin + @binary && system("#{@binary} #{arguments}") + rescue + false + end + end + +end + +class ConvertImage + + def initialize(command=nil) + @command = command + end + + def convertimage(filename) + + return if filename =~ /\.(pdf)$/io + + retain = @command.option('retain') + subpath = @command.option('subpath') + + if filename =~ /\s/ then + @command.report("skipping strange filename '#{filename}'") + else + newname = File.replacesuffix(filename,subpath) + # newname.gsub!(s/[^a-zA-Z0-9\_-\.]/o, '-') + begin + File.makedirs(File.dirname(newname)) + rescue + end + if ! retain || File.needsupdate(filename,newname) then + imagemagick = ImageMagick.new + if imagemagick then + ok = imagemagick.process("-compress zip -quality 99 #{filename} #{newname}") + File.syncmtimes(oldname,newname) if retain + end + end + end + end + +end + +class DownsampleImage + + def initialize(command=nil) + @command = command + end + + def convertimage(filename) + + return if filename =~ /\.(pdf)$/io + + retain = @command.option('retain') + subpath = @command.option('subpath') + + if @command.option('lowres') then + method = '4' + elsif @command.option('medres') || @command.option('normal') then + method = '5' + else + method = '4' + end + + if filename =~ /\s/ then + @command.report("skipping strange filename '#{filename}'") + else + newname = File.replacesuffix(filename,subpath) + begin + File.makedirs(File.dirname(newname)) + rescue + end + if ! retain || File.needsupdate(filename,newname) then + ok = system("texmfstart pstopdf.rb --method=#{method} #{filename} #{newname}") + File.syncmtimes(oldname,newname) if retain + end + end + end + +end + +class ColorImage + + def initialize(command=nil,tmpname='pdftools') + @command = command + @tmpname = tmpname + @colorname = nil + @colorspec = nil + @colorspace = nil + end + + def registercolor(spec='.5',name='c') + name = name || 'c' + spec = spec.split(',') + case spec.length + when 4 + @colorname, @colorspec, @colorspace = name, spec.join('/'), 'cmyk' + when 3 + @colorname, @colorspec, @colorspace = name, spec.join('/'), 'rgb' + when 1 + @colorname, @colorspec, @colorspace = name, spec.join('/'), 'gray' + else + @colorname, @colorspec, @colorspace = nil, nil, nil + end + end + + def convertimage(filename) + + invert = @command.option('invert') + retain = @command.option('retain') + subpath = @command.option('subpath') + + subpath += '/' unless subpath.empty? + + if @colorname && ! @colorname.empty? && @colorspec && ! @colorspec.empty? then + basename = filename.sub(/\.\w+?$/,'') + oldname = filename + ppmname = @tmpname + '-000.ppm' + jpgname = @tmpname + '-000.jpg' + newname = File.expand_path(oldname) + newname = File.dirname(newname) + '/' + subpath + @colorname + '-' + File.basename(newname) + newname.sub!(/\.\w+?$/, '.pdf') + begin + File.makedirs(File.dirname(newname)) + rescue + end + if ! retain || File.needsupdate(filename,newname) then + pdfimages = PdfImages.new + imagemagick = ImageMagick.new + if pdfimages && imagemagick then + File.deletefiles(ppmname,jpgname,newname) + if filename =~ /\.(pdf)$/io then + ok = pdfimages.process("-j -f 1 -l 1 #{filename} #{@tmpname}") + if ok then + if FileTest.file?(ppmname) then + inpname = ppmname + elsif FileTest.file?(jpgname) then + inpname = jpgname + else + ok = false + end + if ok then + switch = if ! invert then '-negate' else '' end + # make sure that we keep the format + tmpname = File.basename(inpname) + tmpname = tmpname.sub(/(.*)\..*?$/,@tmpname) # somehow sub! fails here + ok = imagemagick.process("-colorspace gray #{switch} #{inpname} #{tmpname}") + if ! ok || ! FileTest.file?(tmpname) then + # problems + else + ok = imagemagick.process("-colorspace #{switch} #{@colorspace} -colorize #{@colorspec} -compress zip #{tmpname} #{newname}") + if ! ok || ! FileTest.file?(newname) then + # unable to colorize image + else + # conversion done + end + end + end + end + else + # make sure that we keep the format + tmpname = File.basename(basename) + tmpname = tmpname.sub(/(.*)\..*?$/,@tmpname) # somehow sub! fails here + ok = imagemagick.process("-colorspace gray #{oldname} #{tmpname}") + if ! ok || ! FileTest.file?(tmpname) then + # unable to convert color to gray + else + ok = imagemagick.process("-colorspace #{@colorspace} -colorize #{@colorspec} -compress zip #{tmpname} #{newname}") + if ! ok || ! FileTest.file?(newname) then + # unable to colorize image + else + # conversion done + end + end + end + File.deletefiles(ppmname,jpgname,tmpname) + File.syncmtimes(filename,newname) if retain + end + end + end + end + +end + +class SpotColorImage + + def initialize(command=nil, tmpname='pdftools') + @command = command + @tmpname = tmpname + @colorname = nil + @colorspec = nil + @colorspace = nil + @colorfile = nil + end + + def registercolor(spec='.5',name='unknown') + name = name || 'unknown' + if spec =~ /^[\d\.\,]+$/ then + spec = spec.split(',') + case spec.length + when 4 + @colorname, @colorspec, @colorspace = name, ["c=#{spec[0]}","m=#{spec[1]}","y=#{spec[2]}","k=#{spec[3]}"].join(','), 'cmyk' + when 3 + @colorname, @colorspec, @colorspace = name, ["r=#{spec[0]}","g=#{spec[1]}","b=#{spec[2]}"].join(','), 'rgb' + when 1 + @colorname, @colorspec, @colorspace = name, ["s=#{spec[0]}"].join(','), 'gray' + else + @colorname, @colorspec, @colorspace = nil, nil, nil + end + else + @colorname, @colorfile = name, spec + end + end + + def convertgrayimage(filename) + + invert = @command.option('invert') + retain = @command.option('retain') + subpath = @command.option('subpath') + + subpath += '/' unless subpath.empty? + + if @colorname && ! @colorname.empty? && ((@colorspec && ! @colorspec.empty?) || (@colorfile && ! @colorfile.empty?)) then + basename = filename.sub(/\.\w+?$/,'') + oldname = filename # png jpg pdf + newname = File.expand_path(oldname) + ppmname = @tmpname + '-000.ppm' + jpgname = @tmpname + '-000.jpg' + outname = @tmpname + '-000.pdf' + texname = @tmpname + '-temp.tex' + pdfname = @tmpname + '-temp.pdf' + newname = File.dirname(newname) + '/' + subpath + @colorname + '-' + File.basename(newname) + newname.sub!(/\.\w+?$/, '.pdf') + begin + File.makedirs(File.dirname(newname)) + rescue + end + if ! retain || File.needsupdate(filename,newname) then + pdfimages = PdfImages.new + imagemagick = ImageMagick.new + texexec = TexExec.new + if pdfimages && imagemagick && texexec then + if filename =~ /\.(jpg|png|pdf)$/io then + @command.report("processing #{basename}") + File.deletefiles(ppmname,jpgname,newname) + switch = if ! invert then '-negate' else '' end + if filename =~ /\.(pdf)$/io then + ok = pdfimages.process("-j -f 1 -l 1 #{oldname} #{@tmpname}") + if ok then + if FileTest.file?(ppmname) then + inpname = ppmname + elsif FileTest.file?(jpgname) then + inpname = jpgname + else + ok = false + end + if ok then + ok = imagemagick.process("-colorspace gray #{switch} -compress zip #{inpname} #{outname}") + end + end + else + ok = imagemagick.process("-colorspace gray #{switch} -compress zip #{oldname} #{outname}") + end + if ok then + ok = false unless FileTest.file?(outname) + end + if ok then + if f = File.open(texname, 'w') then + f.puts(conversionfile(filename,outname,newname)) + f.close + ok = texexec.process(texname) + else + ok = false + end + @command.report("error in processing #{newname}") unless ok + if FileTest.file?(pdfname) then + if f = File.open(pdfname,'r') then + f.binmode + begin + if g = File.open(newname,'w') then + g.binmode + data = f.read + # pdftex (direct) & imagemagick (indirect) + if data =~ /(\d+)\s+0\s+obj\s+\[\/Separation\s+\/#{@colorname}/mos then + @command.report("replacing separation color") + object = $1 + data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/moi) do + $1 + "/ColorSpace #{object} 0 R".ljust($2.length) + end + elsif data =~ /(\d+)\s+0\s+obj\s+\[\/Indexed\s*\[/mos then + @command.report("replacing indexed color") + # todo: more precise check on color + object = $1 + data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/moi) do + $1 + "/ColorSpace #{object} 0 R".ljust($2.length) + end + elsif data =~ /(\d+)\s+0\s+obj\s+\[\/Separation/mos then + @command.report("replacing separation color") + object = $1 + data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/moi) do + $1 + "/ColorSpace #{object} 0 R".ljust($2.length) + end + end + g.write(data) + g.close + end + rescue + @command.report("error in converting #{newname}") + else + @command.report("#{newname} is converted") + end + f.close + end + else + @command.report("error in writing #{newname}") + end + else + @command.report("error in producing #{newname}") + end + File.deletefiles(ppmname,jpgname,outname) + # File.deletefiles(texname,pdfname) + File.syncmtimes(filename,newname) if retain + end + else + @command.report("error in locating binaries") + end + else + @command.report("#{newname} is not changed") + end + end + end + + private + + # % example colorfile: + # + # \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-100] [darkblue] [p=1] + # % \definecolor [darkyellow-100] [darkyellow] [p=1] + # + # \definecolorcombination [pdftoolscolor] [darkblue=.12,darkyellow=.28] [c=.1,m=.1,y=.3,k=.1] + + def conversionfile(originalname,filename,finalname) + tex = "\\setupcolors[state=start]\n" + if @colorfile then + tex += "\\readfile{#{@colorfile}}{}{}\n" + tex += "\\starttext\n" + # tex += "\\predefineindexcolor[pdftoolscolor]\n" + tex += "\\startTEXpage\n" + tex += "\\pdfimage{#{filename}}\n" + tex += "\\stopTEXpage\n" + tex += "\\stoptext\n" + else + tex += "\\definecolor[#{@colorname}][#{@colorspec}]\n" + tex += "\\definecolor[pdftoolscolor][#{@colorname}][p=1]\n" + tex += "\\starttext\n" + tex += "\\startTEXpage\n" + tex += "\\hbox{\\color[pdftoolscolor]{\\pdfimage{#{filename}}}}\n" + tex += "\\stopTEXpage\n" + tex += "\\stoptext\n" + end + tex += "\n" + tex += "% old: #{originalname}\n" + tex += "% new: #{finalname}\n" + return tex + end + +end + +module XML + + def XML::version + "" + end + + def XML::start(element, attributes='') + if attributes.empty? then + "<#{element}>" + else + "<#{element} #{attributes}>" + end + end + + def XML::end(element) + "" + end + + def XML::empty(element, attributes='') + if attributes && attributes.empty? then + "<#{element}/>" + else + "<#{element} #{attributes}/>" + end + end + + def XML::element(element, attributes='', content='') + if content && ! content.empty? then + XML::start(element,attributes) + content + XML::end(element) + else + XML::empty(element,attributes) + end + end + + def XML::box(tag, rect, type=1) + case type + when 1 + if rect && ! rect.empty? then + rect = rect.split(' ') + XML::element("#{tag}box", '', + XML::element("llx", '', rect[0]) + + XML::element("lly", '', rect[1]) + + XML::element("ulx", '', rect[2]) + + XML::element("uly", '', rect[3]) ) + else + XML::empty("#{tag}box") + end + when 2 + if rect && ! rect.empty? then + rect = rect.split(' ') + XML::element("box", "type='#{tag}'", + XML::element("llx", '', rect[0]) + + XML::element("lly", '', rect[1]) + + XML::element("ulx", '', rect[2]) + + XML::element("uly", '', rect[3]) ) + else + XML::empty("box", "type='#{tag}'") + end + when 3 + if rect && ! rect.empty? then + rect = rect.split(' ') + XML::element("box", "type='#{tag}' llx='#{rect[0]}' lly='#{rect[1]}' ulx='#{rect[2]}' uly='#{rect[3]}'") + else + XML::empty("box", "type='#{tag}'") + end + else + '' + end + end + + def XML::crlf + "\n" + end + + def XML::skip(n=1) + ' '*n + end + +end + +class Commands + + include CommandBase + + # alias savedhelp :help + + # def help + # savedhelp + # report("under construction (still separate tools)") + # end + + # filename.pdf --spotimage --colorname=darkblue --colorspec=1,0.38,0,0.64 + + def spotimage + + if ! @commandline.argument('first').empty? && files = findfiles() then + colorname = @commandline.option('colorname') + colorspec = @commandline.option('colorspec') + if colorname && ! colorname.empty? && colorspec && ! colorspec.empty? then + files.each do |filename| + s = SpotColorImage.new(self) + s.registercolor(colorspec,colorname) + s.convertgrayimage(filename) + end + else + report("provide --colorname=somename --colorspec=c,m,y,k") + end + else + report("provide filename (png, jpg, pdf)") + end + + end + + def colorimage + + if ! @commandline.argument('first').empty? && files = findfiles() then + colorname = @commandline.option('colorname') + colorspec = @commandline.option('colorspec') + if colorspec && ! colorspec.empty? then + files.each do |filename| + s = ColorImage.new(self) + s.registercolor(colorspec,colorname) # name optional + s.convertimage(filename) + end + else + report("provide --colorspec=c,m,y,k") + end + else + report("provide filename") + end + + end + + def convertimage + + if ! @commandline.argument('first').empty? && files = findfiles() then + files.each do |filename| + s = ConvertImage.new(self) + s.convertimage(filename) + end + else + report("provide filename") + end + + end + + def downsampleimage + + if ! @commandline.argument('first').empty? && files = findfiles() then + files.each do |filename| + s = DownsampleImage.new(self) + s.convertimage(filename) + end + else + report("provide filename") + end + + end + + def info + + if files = findfiles() then + + print(XML.version + XML.crlf) + print(XML.start('pdfinfo', "xmlns='http://www.pragma-ade.com/schemas/pdfinfo.rng'") + XML.crlf) + + files.each do |filename| + + if filename =~ /\.pdf$/io then + + begin + data = `pdfinfo -box #{filename}`.chomp.split("\n") + rescue + data = nil + end + + if data then + + pairs = Hash.new + + data.each do |d| + if (d =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/moi) then + key, val = $1, $2 + pairs[key.downcase.sub(/ /,'')] = val + end + end + + print(XML.skip(1) + XML.start('pdffile', "filename='#{filename}'") + XML.crlf) + + print(XML.skip(2) + XML.element('path', '', File.expand_path(filename)) + XML.crlf) + + if pairs.key?('error') then + + print(XML.skip(2) + XML.element('comment', '', pairs['error']) + XML.crlf) + + else + + print(XML.skip(2) + XML.element('version', '', pairs['pdfversion']) + XML.crlf) + print(XML.skip(2) + XML.element('pages', '', pairs['pages' ]) + XML.crlf) + print(XML.skip(2) + XML.element('title', '', pairs['title' ]) + XML.crlf) + print(XML.skip(2) + XML.element('subject', '', pairs['subject' ]) + XML.crlf) + print(XML.skip(2) + XML.element('author', '', pairs['author' ]) + XML.crlf) + print(XML.skip(2) + XML.element('producer', '', pairs['producer' ]) + XML.crlf) + + if pairs.key?('creationdate') then + pairs['creationdate'].sub!(/(\d\d)\/(\d\d)\/(\d\d)/) do + '20' + $3 + '-' + $1 + '-' +$2 + end + pairs['creationdate'].sub!(/(\d\d)\/(\d\d)\/(\d\d\d\d)/) do + $3 + '-' + $1 + '-' + $2 + end + print(XML.skip(2) + XML.element('creationdate', '', pairs['creationdate']) + XML.crlf) + end + + if pairs.key?('moddate') then + if pairs['moddate'] =~ /(\d\d\d\d)(\d\d)(\d\d)/ then + pairs['moddate'] = "#{$1}-#{$2}-#{$3}" + end + print(XML.skip(2) + XML.element('modificationdate', '', pairs['moddate']) + XML.crlf) + end + + print(XML.skip(2) + XML.element('tagged', '', pairs['tagged' ]) + XML.crlf) + print(XML.skip(2) + XML.element('encrypted', '', pairs['encrypted']) + XML.crlf) + print(XML.skip(2) + XML.element('optimized', '', pairs['optimized']) + XML.crlf) + + if pairs.key?('PageSize') then + print(XML.skip(2) + XML.element('width', '', pairs['pagesize'].sub(/\s*(.*?)\s+(.*?)\s+.*/, $1)) + XML.crlf) + print(XML.skip(2) + XML.element('height', '', pairs['pagesize'].sub(/\s*(.*?)\s+(.*?)\s+.*/, $2)) + XML.crlf) + end + + if pairs.key?('FileSize') then + print(XML.skip(2) + XML.element('size', '', pairs['filesize'].sub(/\s*(.*?)\s+.*/, $1)) + XML.crlf) + end + + print(XML.skip(2) + XML.box('media', pairs['mediabox']) + XML.crlf) + print(XML.skip(2) + XML.box('crop' , pairs['cropbox' ]) + XML.crlf) + print(XML.skip(2) + XML.box('bleed', pairs['bleedbox']) + XML.crlf) + print(XML.skip(2) + XML.box('trim' , pairs['trimBox' ]) + XML.crlf) + print(XML.skip(2) + XML.box('art' , pairs['artbox' ]) + XML.crlf) + + end + + print(XML.skip(1) + XML.end('pdffile') + XML.crlf) + + end + + end + + end + + print(XML.end('pdfinfo') + XML.crlf) + + end + + end + + # name type emb sub uni object ID + # ------------------------------------ ------------ --- --- --- --------- + # EOPLBP+TimesNewRomanPSMT TrueType yes yes no 167 0 + # Times-Roman TrueType no no no 95 0 + # EPBAAB+Helvetica Type 1C yes yes yes 108 0 + # EPBMLE+Helvetica-Oblique Type 1C yes yes yes 111 0 + # Helvetica TrueType no no no 112 0 + + def checkembedded + $stderr = $stdout + $stdout.flush + if @commandline.option('pattern') then + # **/*.pdf + filenames, n = globfiles(@commandline.option('pattern'),'pdf'), 0 + else + filenames, n = findfiles('pdf'), 0 + end + filenames.sort.each do |file| + report("= checking #{File.expand_path(file)}") + result = `pdffonts #{file}`.chomp + lines = result.split(/\n/) + if result =~ /emb\s+sub\s+uni/io then + lines.each do |line| + report("! #{line}") if line =~ /no\s+(no|yes)\s+(no|yes)/io + end + else + lines.each do |line| + report("? #{line}") + end + end + report("") + end + end + + def countpages + if @commandline.option('pattern') then + filenames, n = globfiles(@commandline.option('pattern'),'pdf'), 0 + else + filenames, n = findfiles('pdf'), 0 + end + threshold = @commandline.option('threshold').to_i rescue 0 + filenames.each do |filename| + if `pdfinfo #{filename}`.chomp =~ /^pages\s*\:\s*(\d+)/moi then + p = $1 + m = p.to_i rescue 0 + if threshold == 0 or m > threshold then + report("#{p.rjust(4)} pages found in #{filename}") + n += m + end + end + end + report("") + report("#{n.to_s.rjust(4)} pages in total") + end + + def analyzefile + # needs an update + filenames = @commandline.arguments + filenames.each do |filename| + if filename && FileTest.file?(filename) && filename =~ /\.pdf/io then + filesize = FileTest.size(filename) + report("analyzing file : #{filename}") + report("file size : #{filesize}") + if pdf = File.open(filename) then + pdf.binmode + nofobject, nofxform, nofannot, noflink, nofwidget, nofnamed, nofscript, nofcross = 0, 0, 0, 0, 0, 0, 0, 0 + while data = pdf.gets do + data.scan(/\d+\s+\d+\s+obj/o) do nofobject += 1 end + data.scan(/\/Type\s*\/XObject/o) do nofxform += 1 end + data.scan(/\/Type\s*\/Annot/o) do nofannot += 1 end + data.scan(/\/GoToR\s*\/F/o) do nofcross += 1 end + data.scan(/\/Subtype\s*\/Link/o) do noflink += 1 end + data.scan(/\/Subtype\s*\/Widget/o) do nofwidget += 1 end + data.scan(/\/S\s*\/Named/o) do nofnamed += 1 end + data.scan(/\/S\s*\/JavaScript/o) do nofscript += 1 end + end + pdf.close + report("objects : #{nofobject}") + report("xforms : #{nofxform}") + report("annotations : #{nofannot}") + report("links : #{noflink} (#{nofnamed} named / #{nofscript} scripts / #{nofcross} files)") + report("widgets : #{nofwidget}") + end + end + end + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('spotimage' , 'filename --colorspec= --colorname= [--retain --invert --subpath=]') +commandline.registeraction('colorimage', 'filename --colorspec= [--retain --invert --colorname= ]') +commandline.registeraction('convertimage', 'filename [--retain --subpath]') +commandline.registeraction('downsampleimage', 'filename [--retain --subpath --lowres --normal]') +commandline.registeraction('info', 'filename') +commandline.registeraction('countpages', '[--pattern --threshold]') +commandline.registeraction('checkembedded', '[--pattern]') + +commandline.registeraction('analyzefile' , 'filename') + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registervalue('colorname') +commandline.registervalue('colorspec') +commandline.registervalue('subpath') +commandline.registervalue('pattern') +commandline.registervalue('threshold',0) + +commandline.registerflag('lowres') +commandline.registerflag('medres') +commandline.registerflag('normal') +commandline.registerflag('invert') +commandline.registerflag('retain') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/ruby/pstopdf.rb b/scripts/context/ruby/pstopdf.rb new file mode 100644 index 000000000..73e628df2 --- /dev/null +++ b/scripts/context/ruby/pstopdf.rb @@ -0,0 +1,533 @@ +#!/usr/bin/env ruby + +# program : pstopdf +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +banner = ['PsToPdf', 'version 2.0.1', '2002-2006', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +# todo: paden/prefix in magick and inkscape +# todo: clean up method handling (pass strings, no numbers) +# --method=crop|bounded|raw|... +# --resolution=low|normal|medium|high|printer|print|screen|ebook|default +# + downward compatible flag handling + +require 'base/switch' +require 'base/tool' +require 'base/logger' + +require 'graphics/gs' +require 'graphics/magick' +require 'graphics/inkscape' + +require 'rexml/document' + +exit if defined?(REQUIRE2LIB) + +class Commands + + include CommandBase + + # nowadays we would force a directive, but + # for old times sake we handle default usage + + def main + filename = @commandline.argument('first') + pattern = @commandline.option('pattern') + if filename.empty? && ! pattern.empty? then + pattern = "**/#{pattern}" if @commandline.option('recurse') + globfiles(pattern) + end + filename = @commandline.argument('first') + if filename.empty? then + help + elsif filename =~ /\.exa$/ then + request + else + convert + end + end + + # actions + + def convert + + ghostscript = GhostScript.new(logger) + magick = ImageMagick.new(logger) + inkscape = InkScape.new(logger) + + outpath = @commandline.option('outputpath') + unless outpath.empty? then + begin + File.expand_path(outpath) + outpath = File.makedirs(outpath) unless FileTest.directory?(outpath) + rescue + # sorry + end + end + + @commandline.arguments.each do |filename| + + filename = Tool.cleanfilename(filename,@commandline) # brrrr + inppath = @commandline.option('inputpath') + if inppath.empty? then + inppath = '.' + fullname = filename # avoid duplicate './' + else + fullname = File.join(inppath,filename) + end + if FileTest.file?(fullname) then + handle_whatever(ghostscript,inkscape,magick,filename) + else + report("file #{fullname} does not exist") + end + + end + + end + + def request + + # + # + # pstopdf + # E:/tmp/demo.ps + # + # + # false + # -1 + # + # + + ghostscript = GhostScript.new(logger) + magick = ImageMagick.new(logger) + inkscape = InkScape.new(logger) + + dataname = @commandline.argument('first') || '' + filename = @commandline.argument('second') || '' + + if dataname.empty? || ! FileTest.file?(dataname) then + report('provide valid exa file') + return + else + begin + request = REXML::Document.new(File.new(dataname)) + rescue + report('provide valid exa file (xml error)') + return + end + end + if filename.empty? then + begin + if filename = REXML::XPath.first(request.root,"exa:request/exa:application/exa:filename/text()") then + filename = filename.to_s + else + report('no filename found in exa file') + return + end + rescue + filename = '' + end + end + if filename.empty? then + report('provide valid filename') + return + elsif ! FileTest.file?(filename) then + report("invalid filename #{filename}") + return + end + + [ghostscript,inkscape,magick].each do |i| + i.setvariable('inputfile',filename) + end + + # set ghostscript variables + REXML::XPath.each(request.root,"/exa:request/exa:data/exa:variable") do |v| + begin + if (key = v.attributes['label']) and (value = v.text.to_s) then + case key + when /gs[\:\.](var[\:\.])*(offset)/io then ghostscript.setoffset(value) + when /gs[\:\.](var[\:\.])*(method)/io then ghostscript.setvariable('method',value) + when /gs[\:\.](var[\:\.])*(.*)/io then ghostscript.setpsoption($2,value) + end + end + rescue + end + end + + # no inkscape and magick variables (yet) + + handle_whatever(ghostscript,inkscape,magick,filename) + + end + + def watch + + ghostscript = GhostScript.new(logger) + magick = ImageMagick.new(logger) + inkscape = InkScape.new(logger) + + pathname = commandline.option('watch') + + unless pathname and not pathname.empty? then + report('empty watchpath is not supported') + exit + end + + if pathname == '.' then + report("watchpath #{pathname} is not supported") + exit + end + + if FileTest.directory?(pathname) then + if Dir.chdir(pathname) then + report("watching path #{pathname}") + else + report("unable to change to path #{pathname}") + exit + end + else + report("invalid path #{pathname}") + exit + end + + waiting = false + + loop do + + if waiting then + report("waiting #{getvariable('delay')}") + waiting = false + sleep(getvariable('delay').to_i) + end + + files = Dir.glob("**/*.*") + + if files and files.length > 0 then + + files.each do |fullname| + + next unless fullname + + if FileTest.directory?(fullname) then + debug('skipping path', fullname) + next + end + + unless magick.supported(fullname) then + debug('not supported', fullname) + next + end + + if (! FileTest.file?(fullname)) || (FileTest.size(fullname) < 100) then + debug("skipping small crap file #{fullname}") + next + end + + debug("handling file #{fullname}") + + begin + next unless File.rename(fullname,fullname) # access trick + rescue + next # being written + end + + fullname = Tool.cleanfilename(fullname,@commandline) + + fullname.gsub!(/\\/io, '/') + + filename = File.basename(fullname) + filepath = File.dirname(fullname) + + next if filename =~ /gstemp.*/io + + if filepath !~ /(result|done|raw|crop|bound|bitmap)/io then + begin + File.makedirs(filepath+'/raw') + File.makedirs(filepath+'/bound') + File.makedirs(filepath+'/crop') + File.makedirs(filepath+'/bitmap') + debug("creating prefered input paths on #{filepath}") + rescue + debug("creating input paths on #{filepath} failed") + end + end + + if filepath =~ /^(.*\/|)(done|result)$/io then + debug("skipping file #{fullname}") + else + report("start processing file #{fullname}") + if filepath =~ /^(.*\/*)(raw|crop|bound)$/io then + donepath = $1 + 'done' + resultpath = $1 + 'result' + case $2 + when 'raw' then method = 1 + when 'bound' then method = 2 + when 'crop' then method = 3 + else method = 2 + end + report("forcing method #{method}") + else + method = 2 + donepath = filepath + '/done' + resultpath = filepath + '/result' + report("default method #{method}") + end + + begin + File.makedirs(donepath) + File.makedirs(resultpath) + rescue + report('result path creation fails') + end + + if FileTest.directory?(donepath) && FileTest.directory?(resultpath) then + + resultname = resultpath + '/' + filename.sub(/\.[^\.]*$/,'') + '.pdf' + + @commandline.setoption('inputpath', filepath) + @commandline.setoption('outputpath', resultpath) + @commandline.setoption('method', method) + + if ghostscript.psfile?(fullname) then + handle_ghostscript(ghostscript,filename) + else + handle_magick(magick,filename) + end + + sleep(1) # calm down + + if FileTest.file?(fullname) then + begin + File.copy(fullname,donepath + '/' + filename) + File.delete(fullname) + rescue + report('cleanup fails') + end + end + + end + + end + + end + + end + + waiting = true + end + + end + + private + + def handle_whatever(ghostscript,inkscape,magick,filename) + if ghostscript.psfile?(filename) then + # report("processing ps file #{filename}") + ghostscript.setvariable('pipe',false) if @commandline.option('nopipe') + # ghostscript.setvariable('pipe',not @commandline.option('nopipe')) + ghostscript.setvariable('colormodel',@commandline.option('colormodel')) + ghostscript.setvariable('offset',@commandline.option('offset')) + handle_ghostscript(ghostscript,filename) + elsif ghostscript.pdffile?(filename) && ghostscript.pdfmethod?(@commandline.option('method')) then + # report("processing pdf file #{filename}") + handle_ghostscript(ghostscript,filename) + elsif inkscape.supported?(filename) then + # report("processing non ps/pdf file #{filename}") + handle_inkscape(inkscape,filename) + elsif magick.supported?(filename) then + # report("processing non ps/pdf file #{filename}") + handle_magick(magick,filename) + else + report("option not supported for #{filename}") + end + end + + def handle_magick(magick,filename) + + report("converting non-ps file #{filename} into pdf") + + inppath = @commandline.option('inputpath') + outpath = @commandline.option('outputpath') + + inppath = inppath + '/' if not inppath.empty? + outpath = outpath + '/' if not outpath.empty? + + prefix = @commandline.option('prefix') + suffix = @commandline.option('suffix') + + inpfilename = "#{inppath}#{filename}" + outfilename = "#{outpath}#{prefix}#{filename.sub(/\.([^\.]*?)$/, '')}#{suffix}.pdf" + + magick.setvariable('inputfile' , inpfilename) + magick.setvariable('outputfile', outfilename) + + magick.autoconvert + + end + + def handle_inkscape(inkscape,filename) + + report("converting svg(z) file #{filename} into pdf") + + inppath = @commandline.option('inputpath') + outpath = @commandline.option('outputpath') + + inppath = inppath + '/' if not inppath.empty? + outpath = outpath + '/' if not outpath.empty? + + prefix = @commandline.option('prefix') + suffix = @commandline.option('suffix') + + inpfilename = "#{inppath}#{filename}" + outfilename = "#{outpath}#{prefix}#{filename.sub(/\.([^\.]*?)$/, '')}#{suffix}.pdf" + + inkscape.setvariable('inputfile' , inpfilename) + inkscape.setvariable('outputfile', outfilename) + + if @commandline.option('verbose') || @commandline.option('debug') then + logname = filename.gsub(/\.[^\.]*?$/, '.log') + report("log info saved in #{logname}") + inkscape.convert(logname) # logname ook doorgeven + else + inkscape.convert + end + + end + + def handle_ghostscript(ghostscript,filename) + + ghostscript.reset + + method = ghostscript.method(@commandline.option('method')) + force = ghostscript.method(@commandline.option('force')) + + ghostscript.setvariable('method', method) + ghostscript.setvariable('force', force) + + # report("conversion method #{method}") + + inppath = @commandline.option('inputpath') + outpath = @commandline.option('outputpath') + + inppath = inppath + '/' if not inppath.empty? + outpath = outpath + '/' if not outpath.empty? + + prefix = @commandline.option('prefix') + suffix = @commandline.option('suffix') + + ok = false + + if ghostscript.pdfmethod?(method) then + + report("converting pdf file #{filename} into pdf") + + if prefix.empty? && suffix.empty? && inppath.empty? && outpath.empty? then + prefix = ghostscript.pdfprefix(method) + end + + if ghostscript.pdffile?(filename) then + + filename = filename.sub(/\.pdf$/, '') + + inpfilename = "#{inppath}#{filename}.pdf" + outfilename = "#{outpath}#{prefix}#{filename}#{suffix}.pdf" + + ghostscript.setvariable('inputfile' ,inpfilename) + ghostscript.setvariable('outputfile',outfilename) + + if FileTest.file?(inpfilename) then + ok = ghostscript.convert + else + report("no file found #{filename}") + end + + else + report("no pdf file #{filename}") + end + + elsif ghostscript.psfile?(filename) then + + if filename =~ /(.*)\.([^\.]*?)$/io then + filename, filesuffix = $1, $2 + else + filesuffix = 'eps' + end + + report("converting #{filesuffix} (ps) into pdf") + + inpfilename = "#{inppath}#{filename}.#{filesuffix}" + outfilename = "#{outpath}#{prefix}#{filename}#{suffix}.pdf" + + ghostscript.setvariable('inputfile' , inpfilename) + ghostscript.setvariable('outputfile', outfilename) + + if FileTest.file?(inpfilename) then + ok = ghostscript.convert + if ! ok && FileTest.file?(outfilename) then + begin + File.delete(outfilename) + rescue + end + end + else + report("no file with name #{filename} found") + end + + else + report('file must be of type eps/ps/ai/pdf') + end + + return ok + + end + +end + +# ook pdf -> pdf onder optie 0, andere kleurruimte + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registerflag('debug') +commandline.registerflag('verbose') +commandline.registerflag('nopipe') + +commandline.registervalue('method',2) +commandline.registervalue('offset',0) + +commandline.registervalue('prefix') +commandline.registervalue('suffix') + +commandline.registervalue('inputpath') +commandline.registervalue('outputpath') + +commandline.registerflag('watch') +commandline.registerflag('force') +commandline.registerflag('recurse') + +commandline.registervalue('delay',2) + +commandline.registervalue('colormodel','cmyk') +commandline.registervalue('pattern','') + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registeraction('convert', 'convert ps into pdf') +commandline.registeraction('request', 'handles exa request file') +commandline.registeraction('watch', 'watch folders for conversions (untested)') + +commandline.expand + +logger.verbose if (commandline.option('verbose') || commandline.option('debug')) + +Commands.new(commandline,logger,banner).send(commandline.action || 'main') diff --git a/scripts/context/ruby/rlxtools.rb b/scripts/context/ruby/rlxtools.rb new file mode 100644 index 000000000..6a5c5ca20 --- /dev/null +++ b/scripts/context/ruby/rlxtools.rb @@ -0,0 +1,368 @@ +#!/usr/bin/env ruby + +# program : rlxtools +# copyright : PRAGMA Advanced Document Engineering +# version : 2004-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +banner = ['RlxTools', 'version 1.0.1', '2004/2005', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' +require 'base/system' +require 'base/kpse' + +require 'fileutils' +# require 'ftools' +require 'rexml/document' + +class Commands + + include CommandBase + + # + # + # + # + # texmfstart + # --verbose + # --iftouched=/,/ + # pstopdf + # --method=5 + # --inputpath= + # --outputpath=/ + # + # + # + # + # + # + # + # + # figure + # found + # cow.pdf + # pdf + # . + # lowres + # lowres/ + # 276.03125pt + # 200.75pt + # + # + + def manipulate + + procname = @commandline.argument('first') || '' + filename = @commandline.argument('second') || '' + + procname = Kpse.found(procname) + + if procname.empty? || ! FileTest.file?(procname) then + report('provide valid manipulator file') + elsif filename.empty? || ! FileTest.file?(filename) then + report('provide valid resource log file') + else + begin + data = REXML::Document.new(File.new(filename)) + rescue + report('provide valid resource log file (xml error)') + return + end + begin + proc = REXML::Document.new(File.new(procname)) + rescue + report('provide valid manipulator file (xml error)') + return + end + report("manipulator file: #{procname}") + report("resourcelog file: #{filename}") + begin + nofrecords, nofdone = 0, 0 + REXML::XPath.each(data.root,"/rl:library/rl:usage") do |usage| + nofrecords += 1 + variables = Hash.new + usage.elements.each do |e| + variables[e.name] = e.text.to_s + end + report("processing record #{nofrecords} (#{variables['file'] || 'noname'}: #{variables.size} entries)") + if conversion = variables['conversion'] then + report("testing for conversion #{conversion}") + if suffix = variables['suffix'] then + suffix.downcase! + if ! suffix.empty? && variables['file'] && variables['file'] !~ /\.([a-z]+)$/i then + variables['file'] += ".#{suffix}" + end + if file = variables['file'] then + report("conversion #{conversion} for suffix #{suffix} for file #{file}") + else + report("conversion #{conversion} for suffix #{suffix}") + end + pattern = "@name='#{conversion}' and @suffix='#{suffix}'" + if steps = REXML::XPath.first(proc.root,"/rl:manipulators/rl:manipulator[#{pattern}]") then + localsteps = steps.deep_clone + ['rl:old','rl:new'].each do |tag| + REXML::XPath.each(localsteps,tag) do |extras| + REXML::XPath.each(extras,"rl:value") do |value| + if name = value.attributes['name'] then + substitute(value,variables[name.to_s] || '') + end + end + end + end + old = REXML::XPath.first(localsteps,"rl:old") + new = REXML::XPath.first(localsteps,"rl:new") + if old && new then + old, new = justtext(old.to_s), justtext(new.to_s) + variables['old'], variables['new'] = old, new + begin + [old,new].each do |d| + File.makedirs(File.dirname(d)) + end + rescue + report("error during path creation") + end + report("old file #{old}") + report("new file #{new}") + level = if File.needsupdate(old,new) then 2 else 0 end + else + level = 1 + end + if level>0 then + REXML::XPath.each(localsteps,"rl:step") do |command| + REXML::XPath.each(command,"rl:old") do |value| + replace(value,old) + end + REXML::XPath.each(command,"rl:new") do |value| + replace(value,new) + end + REXML::XPath.each(command,"rl:value") do |value| + if name = value.attributes['name'] then + substitute(value,variables[name.to_s]) + end + end + str = justtext(command.to_s) + # str.gsub!(/(\.\/)+/io, '') + report("command #{str}") + System.run(str) unless @commandline.option('test') + report("synchronizing #{old} and #{new}") + File.syncmtimes(old,new) if level > 1 + nofdone += 1 + end + else + report("no need for a manipulation") + end + else + report("no manipulator found") + end + else + report("no suffix specified") + end + else + report("no conversion needed") + end + end + if nofdone > 0 then + jobname = filename.gsub(/\.(.*?)$/,'') # not 'tuo' here + tuoname = jobname + '.tuo' + if FileTest.file?(tuoname) && (f = File.open(tuoname,'a')) then + f.puts("%\n% number of rlx manipulations: #{nofdone}\n") + f.close + end + end + rescue + report("error in manipulating files: #{$!}") + end + begin + logname = "#{filename}.log" + File.delete(logname) if FileTest.file?(logname) + File.copy(filename,logname) + rescue + end + end + + end + + private + + def justtext(str) + str = str.to_s + str.gsub!(/<[^>]*?>/o, '') + str.gsub!(/\s+/o, ' ') + str.gsub!(/</o, '<') + str.gsub!(/>/o, '>') + str.gsub!(/&/o, '&') + str.gsub!(/"/o, '"') + str.gsub!(/[\/\\]+/o, '/') + return str.strip + end + + def substitute(value,str='') + if str then + begin + if value.attributes.key?('method') then + str = filtered(str.to_s,value.attributes['method'].to_s) + end + if str.empty? && value.attributes.key?('default') then + str = value.attributes['default'].to_s + end + value.insert_after(value,REXML::Text.new(str.to_s)) + rescue Exception + end + end + end + + def replace(value,str) + if str then + begin + value.insert_after(value,REXML::Text.new(str.to_s)) + rescue Exception + end + end + end + + def filtered(str,method) + + str = str.to_s # to be sure + case method + when 'name' then # no path, no suffix + case str + when /^.*[\\\/](.+?)\..*?$/o then $1 + when /^.*[\\\/](.+?)$/o then $1 + when /^(.*)\..*?$/o then $1 + else str + end + when 'path' then if str =~ /^(.+)([\\\/])(.*?)$/o then $1 else '' end + when 'suffix' then if str =~ /^.*\.(.*?)$/o then $1 else '' end + when 'nosuffix' then if str =~ /^(.*)\..*?$/o then $1 else str end + when 'nopath' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end + else str + end + end + +end + +class Commands + + include CommandBase + + @@xmlbanner = "" + + def identify(resultfile='rlxtools.rli') + if @commandline.option('collect') then + begin + File.open(resultfile,'w') do |f| + f << "#{@@xmlbanner}\n" + f << "\n" + @commandline.arguments.each do |filename| + if state = do_identify(filename) then + report("#{filename} is identified") + f << state + else + report("unable to identify #{filename}") + end + end + f << "\n" + report("result saved in #{resultfile}") + end + rescue + report("error in writing result") + end + else + @commandline.arguments.each do |filename| + if state = do_identify(filename) then + begin + File.open(filename+'.rli','w') do |f| + f << "#{@@xmlbanner}\n" + f << state + end + rescue + report("error in identifying #{filename}") + else + report("#{filename} is identified") + end + else + report("unable to identify #{filename}") + end + end + end + end + + private + + def do_identify(filename,centimeters=false) + begin + str = nil + if FileTest.file?(filename) then + # todo: use pdfinto for pdf files, identify is bugged + if centimeters then + result = `identify -units PixelsPerCentimeter -format \"x=%x,y=%y,w=%w,h=%h,b=%b\" #{filename}`.chomp.split(',') + else + result = `identify -units PixelsPerInch -format \"x=%x,y=%y,w=%w,h=%h,b=%b\" #{filename}`.chomp.split(',') + end + tags = Hash.new + result.each do |r| + if rr = r.split("=") then + tags[rr[0]] = rr[1] + end + end + size = (tags['b']||0).to_i + width = unified(tags['w']||0,tags['x']||'1') + height = unified(tags['h']||0,tags['y']||'1') + if size > 0 then + str = '' + str << "\n" + str << " #{size}\n" + str << " #{File.dirname(filename).sub(/\\/o,'/')}\n" + str << " #{width}\n" + str << " #{height}\n" + str << "\n" + end + else + str = nil + end + rescue + str = nil + end + return str + end + + def unified(dim,res) + case res + when /([\d\.]+)\s*PixelsPerInch/io then + sprintf("%.4fin",dim.to_f/$1.to_f) + when /([\d\.]+)\s*PixelsPerCentimeter/io then + sprintf("%.4fcm",dim.to_f/$1.to_f) + when /([\d\.]+)\s*PixelsPerMillimeter/io then + sprintf("%.4fmm",dim.to_f/$1.to_f) + when /([\d\.]+)\s*PixelsPerPoint/io then + sprintf("%.4fbp",dim.to_f/$1.to_f) + else + sprintf("%.4fbp",dim.to_f) + end + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('manipulate', '[--test] manipulatorfile resourselog') +commandline.registeraction('identify' , '[--collect] filename') + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registerflag('test') +commandline.registerflag('collect') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/ruby/rscortool.rb b/scripts/context/ruby/rscortool.rb new file mode 100644 index 000000000..c656fed85 --- /dev/null +++ b/scripts/context/ruby/rscortool.rb @@ -0,0 +1,63 @@ +# program : rscortool +# copyright : PRAGMA Publishing On Demand +# version : 1.00 - 2002 +# author : Hans Hagen +# +# project : eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-pod.com / www.pragma-ade.com + +require 'rexml/document.rb' + +class Array + + def downcase + self.collect { |l| l.to_s.downcase } + end + +end + +class SortedXML + + def initialize (filename) + return nil if not filename or filename.empty? or not test(?e,filename) + @data = REXML::Document.new(File.new(filename), + {:ignore_whitespace_nodes => :all, + :compress_whitespace => :all}) + end + + def save (filename) + # filename += '.xml' unless filename.match(/\..*?$/) + filename += '.xml' unless filename =~ /\..*?$/ + if not filename.empty? and f = open(filename,'w') + @data.write(f,0) + f.close + end + end + + def sort + keys = REXML::XPath.match(@data.root,"/contacts/contact/@label") + return unless keys + keys = keys.downcase + records = @data.elements.to_a("/contacts/contact") + @data.elements.delete_all("/contacts/contact") + keys = keys.collect do |l| # prepare numbers + l.gsub(/(\d+)/) do |d| sprintf('%05d', d) end + end + keys.sort.each do |s| + @data.root.add_element(records[keys.index(s)]) + end + end + +end + +def sortfile (filename) + c = SortedXML.new(filename) + c.sort + c.save('test.xml') +end + +exit if ARGV[0] == nil or ARGV[0].empty? + +sortfile(ARGV[0]) diff --git a/scripts/context/ruby/rsfiltool.rb b/scripts/context/ruby/rsfiltool.rb new file mode 100644 index 000000000..6d7c7aba0 --- /dev/null +++ b/scripts/context/ruby/rsfiltool.rb @@ -0,0 +1,341 @@ +# program : rsfiltool +# copyright : PRAGMA Publishing On Demand +# version : 1.01 - 2002 +# author : Hans Hagen +# +# project : eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-pod.com / www.pragma-ade.com + +unless defined? ownpath + ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'') + $: << ownpath +end + +# --name=a,b,c.xml wordt names [a.xml, b.xml, c.xml] +# --path=x/y/z/a,b,c.xml wordt [x/y/z/a.xml, x/y/z/b.xml, x/y/z/c.xml] + +# todo : split session stuff from xmpl/base into an xmpl/session module and "include xmpl/session" into base and here and ... + +require 'fileutils' +# require 'ftools' +require 'xmpl/base' +require 'xmpl/switch' +require 'xmpl/request' + +session = Example.new('rsfiltool', '1.01', 'PRAGMA POD') + +filterprefix = 'rsfil-' + +commandline = CommandLine.new + +commandline.registerflag('submit') +commandline.registerflag('fetch') +commandline.registerflag('report') +#commandline.registerflag('split') +commandline.registerflag('stamp') +commandline.registerflag('silent') +commandline.registerflag('request') +commandline.registerflag('nobackup') + +commandline.registervalue('filter') + +commandline.registervalue('root') +commandline.registervalue('path') +commandline.registervalue('name') + +commandline.expand + +session.set('log.silent',true) if commandline.option('silent') + +session.inherit(commandline) + +session.identify + +# session.exit unless session.loadenvironment + +def prepare (session) + + # Normally the system provides the file, but a user can provide the rest; in + # order to prevent problems with keying in names, we force lowercase names. + + session.set('option.file',session.get('argument.first')) if session.get('option.file').empty? + + root = session.get('option.root').downcase + path = session.get('option.path').downcase + name = session.get('option.name').downcase + file = session.get('option.file').downcase + + session.error('provide file') if file.empty? + session.error('provide root') if root.empty? + + filter = session.get('option.filter').downcase + trash = session.get('option.trash').downcase + + trash = '' unless FileTest.directory?(trash) + + if not filter.empty? then + begin + require filter + rescue Exception + begin + require filterprefix + filter + rescue Exception + session.error('invalid filter') + end + end + begin + if RSFIL::valid?(file) then + split = RSFIL::split(file,name) + path = if split[0].downcase then split[0] else '' end + file = if split[1].downcase then split[1] else '' end + name = if split[2].downcase then split[2] else '' end + session.report('split result',split.inspect) + session.error('unable to split off path') if path.empty? + session.error('unable to split off file') if file.empty? + session.error('unable to split off name') if name.empty? + session.set('option.path',path) if path + session.set('option.file',file) if file + session.set('option.name',name) if name + else + session.error('invalid filename', file) + unless trash.empty? then + File.copy(file,trash + '/' + file) + end + end + rescue + session.error('unable to split',file,'with filter',filter) + end + end + + session.error('provide path') if path.empty? + + session.error('invalid root') unless test(?d,root) + + exit if session.error? + + session.set('fb.filename',file) + + path.gsub!(/\\/o, '/') + path.gsub!(/\s/o, '') + + path = root + '/' + path + + # multiple paths + + if path =~ /^(.*)\/(.*?)$/o then + prepath = $1 + postpath = $2 + paths = postpath.split(/\,/) + paths.collect! do |p| + prepath + '/' + p + end + else + paths = Array.new + paths.push(path) + end + + paths.collect! do |p| + p.gsub(/[^a-zA-Z0-9\s\-\_\/\.\:]/o, '-') + end + + file.gsub!(/\\/o, '/') + file.gsub!(/[^a-zA-Z0-9\s\-\_\/\.\:]/o, '-') + +# if session.get('option.split') +# if file =~ /(.*)\.(.*?)$/o +# path = path + '/' + $1 +# else +# session.error('nothing to split in filename') +# end +# end + + paths.each do |p| + begin + session.report('creating path', p) + File.makedirs(p) + rescue + session.error('unable to create path', p) + end + end + + name.gsub!(/\s+/,'') + + # can be a,b,c.exa.saved => a.exa.saved,b.exa.saved,c.exa.saved + + if name =~ /(.*?)\.(.*)$/ + name = $1 + suffix = $2 + names = name.split(/\,/) + names.collect! do |n| + n + '.' + suffix + end + name = names.join(',') + else + names = name.split(/\,/) + end + + session.set('fb.path',path) + session.set('fb.paths',paths) + session.set('fb.name',name) + session.set('fb.names',names) + +end + +def thefullname(path,file,name='') + + filename = file.gsub(/.*?\//, '') + + if name.empty? + path + '/' + filename + else + unless name =~ /\..+$/o # unless name.match(/\..+$/o) + if filename =~ /(\..+)$/o # if file.match(/(\..+)$/o) + name = name + $1 + end + end + path + '/' + name + end + +end + +def submitfile (session) + + filename = session.get('fb.filename') + paths = session.get('fb.paths') + names = session.get('fb.names') + + paths.each do |path| + session.report('submitting path',path) + names.each do |name| + session.report('submitting file',filename,'to',name) + submit(session,path,filename,name) + end + end + +end + +def submitlist (session) + + requestname = session.get('fb.filename') + paths = session.get('fb.paths') + + if test(?e,requestname) + session.report('loading request file', requestname) + if request = ExaRequest.new(requestname) + filelist = request.files + if filelist && (filelist.size > 0) + filelist.each do |filename| + paths.each do |path| + session.report('submitting file from list', filename) + submit(session,path,filename,request.naturalname(filename)) + end + end + else + session.warning('no filelist in', requestname) + end + else + session.warning('unable to load', requestname) + end + else + session.warning('no file', requestname) + end + +end + +def submit (session, path, filename, newname) + + fullname = thefullname(path,newname) + + unless test(?e,filename) + session.warning('no file to submit', filename) + return + end + + begin + File.copy(fullname,fullname+'.old') if ! session.get('nobackup') && test(?e,fullname) + if test(?e,filename) + File.copy(filename,fullname) + session.report('submit', filename, 'in', fullname) + if session.get('option.stamp') + f = open(fullname+'.tim','w') + f.puts(Time.now.gmtime.strftime("%a %b %d %H:%M:%S %Y")) + f.close + end + else + session.error('unable to locate', filename) + end + rescue + session.error('unable to move', filename, 'to', fullname) + end + +end + +def fetch (session) + + filename = session.get('fb.filename') + paths = session.get('fb.paths') + name = session.get('fb.name') + + begin + File.copy(filename,filename+'.old') if ! session.get('nobackup') && test(?e,filename) + paths.each do |path| + # fullname = thefullname(path,request.naturalname(filename)) + # fullname = thefullname(path,filename) + fullname = thefullname(path,name) + if test(?e,fullname) + File.copy(fullname,filename) + session.report('fetch', filename, 'from', fullname) + return + else + session.report('file',fullname, 'is not present') + end + end + rescue + session.error('unable to fetch file from path') + end + session.error('no file',filename, 'fetched') unless test(?e,filename) + +end + +def report (session) + + filename = session.get('fb.filename') + paths = session.get('fb.paths') + + paths.each do |path| + fullname = thefullname(path,request.naturalname(filename)) + if test(?e,fullname) + begin + session.report('file', fullname) + session.report('size', test(?s,fullname)) + if test(?e,fullname+'.tim') + str = IO.readlines(fullname+'.tim') + # str = IO.read(fullname+'.tim') + session.report('time', str) + end + rescue + session.error('unable to report about', fullname) + end + end + end + +end + +if session.get('option.submit') + prepare(session) + if session.get('option.request') + submitlist(session) + else + submitfile(session) + end +elsif session.get('option.fetch') + prepare(session) + fetch(session) +elsif session.get('option.report') + prepare(session) + report(session) +else + session.report('provide action') +end diff --git a/scripts/context/ruby/rslibtool.rb b/scripts/context/ruby/rslibtool.rb new file mode 100644 index 000000000..7ae5efb64 --- /dev/null +++ b/scripts/context/ruby/rslibtool.rb @@ -0,0 +1,114 @@ +# program : rslibtool +# copyright : PRAGMA Publishing On Demand +# version : 1.00 - 2002 +# author : Hans Hagen +# +# project : eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-pod.com / www.pragma-ade.com + +# --add --base=filename --path=directory pattern +# --remove --base=filename --path=directory label +# --sort --base=filename --path=directory +# --purge --base=filename --path=directory +# --dummy --base=filename +# --namespace + +# rewrite + +unless defined? ownpath + ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'') + $: << ownpath +end + +require 'rslb/base' +require 'xmpl/base' +require 'xmpl/switch' + +session = Example.new('rslbtool', '1.0', 'PRAGMA POD') + +session.identify + +commandline = CommandLine.new + +commandline.registerflag('add') +commandline.registerflag('remove') +commandline.registerflag('delete') +commandline.registerflag('sort') +commandline.registerflag('purge') +commandline.registerflag('dummy') +commandline.registerflag('process') +commandline.registerflag('namespace') + +commandline.registervalue('prefix') +commandline.registervalue('base') +commandline.registervalue('path') +commandline.registervalue('result') +commandline.registervalue('texexec') +commandline.registervalue('zipalso') + +commandline.expand + +session.inherit(commandline) + +base = session.get('option.base') +path = session.get('option.path') + +base = 'rslbtool.xml' if base.empty? + +# when path is given, assume that arg list is list of +# suffixes, else assume it is a list of globbed filespec + +if path.empty? + base += '.xml' unless base =~ /\..+$/ + list = commandline.arguments +else + Dir.chdir(File.dirname(path)) + list = Dir.glob("*.{#{commandline.arguments.join(',')}}") +end + +begin + reslib = Resource.new(base,session.get('option.namespace')) + reslib.load(base) +rescue + session.error('problems with loading base') + exit +end + +unless session.get('option.texexec').empty? + reslib.set_texexec(session.get('option.texexec')) +end + +if session.get('option.add') + + session.report('adding records', list) + reslib.add_figures(list,session.get('option.prefix')) + +elsif session.get('option.remove') or session.get('option.delete') + + session.report('removing records') + reslib.delete_figures(list) + +elsif session.get('option.sort') + + session.report('sorting records') + reslib.sort_figures() + +elsif session.get('option.purge') + + session.report('purging records') + reslib.purge_figures() + +elsif session.get('option.dummy') + + session.report('creating dummy records') + reslib.create_dummies(session.get('option.process'),session.get('option.result'),session.get('option.zipalso')) + +else + + session.warning('provide action') + +end + +reslib.save(base) diff --git a/scripts/context/ruby/runtools.rb b/scripts/context/ruby/runtools.rb new file mode 100644 index 000000000..5565748e2 --- /dev/null +++ b/scripts/context/ruby/runtools.rb @@ -0,0 +1,506 @@ +require 'timeout' +require 'fileutils' +# require 'ftools' +require 'rbconfig' + +class File + + # we don't want a/b//c + # + # puts File.join('a','b','c') + # puts File.join('/a','b','c') + # puts File.join('a:','b','c') + # puts File.join('a/','/b/','c') + # puts File.join('/a','/b/','c') + # puts File.join('//a/','/b/','c') + + def File.join(*list) + path, prefix = [*list].flatten.join(File::SEPARATOR), '' + path.sub!(/^([\/]+)/) do + prefix = $1 + '' + end + path.gsub!(/([\\\/]+)/) do + File::SEPARATOR + end + prefix + path + end + +end + + +class Job + + $ownfile, $ownpath = '', '' + + def Job::set_own_path(file) + $ownfile, $ownpath = File.basename(file), File.expand_path(File.dirname(file)) + $: << $ownpath + end + + def Job::ownfile + $ownfile + end + + def Job::ownpath + $ownpath + end + +end + +class Job + + def initialize + @startuppath = Dir.getwd + @log = Array.new + @testmode = false + @ownpath = $ownpath + @paths = Array.new + end + + def exit(showlog=false) + Dir.chdir(@startuppath) + show_log if showlog + Kernel::exit + end + + def platform + case Config::CONFIG['host_os'] + when /mswin/ then :windows + else :unix + end + end + + def path(*components) + File.join([*components].flatten) + end + + def found(name) + FileTest.file?(path(name)) || FileTest.directory?(path(name)) + end + + def binary(name) + if platform == :windows then + name.sub(/\.[^\/]+$/o,'') + '.exe' + else + name + end + end + + def suffixed(name,suffix) + if name =~ /\.[^\/]+$/o then + name + else + name + '.' + suffix + end + end + + def expanded(*name) + File.expand_path(File.join(*name)) + end + + def argument(n,default=nil) + ARGV[n] || default + end + + def variable(name,default='') + ENV[name] || default + end + + def change_dir(*dir) + dir, old = expanded(path(*dir)), expanded(Dir.getwd) + unless old == dir then + begin + Dir.chdir(dir) + rescue + error("unable to change to path #{dir}") + else + if old == dir then + error("error in changing to path #{dir}") + else + message("changed to path #{dir}") + end + end + end + # return File.expand_path(Dir.getwd) + end + + def delete_dir(*dir) + begin + dir = path(*dir) + pattern = "#{dir}/**/*" + puts("analyzing dir #{pattern}") + files = Dir.glob(pattern).sort.reverse + files.each do |f| + begin + # FileTest.file?(f) fails on .whatever files + File.delete(f) + rescue + # probably directory + else + puts("deleting file #{f}") + end + end + files.each do |f| + begin + Dir.rmdir(f) + rescue + # strange + else + message("deleting path #{f}") + end + end + begin + Dir.rmdir(dir) + rescue + # strange + else + message("deleting parent #{dir}") + end + Dir.glob(pattern).sort.each do |f| + warning("unable to delete #{f}") + end + rescue + warning("unable to delete path #{File.expand_path(dir)} (#{$!})") + else + message("path #{File.expand_path(dir)} removed") + end + end + + + def create_dir(*dir) + begin + dir = path(*dir) + unless FileTest.directory?(dir) then + File.makedirs(dir) + else + return + end + rescue + error("unable to create path #{File.expand_path(dir)}") + else + message("path #{File.expand_path(dir)} created") + end + end + + def show_dir(delay=0) + _puts_("\n") + print Dir.getwd + ' ' + begin + timeout(delay) do + loop do + print '.' + sleep(1) + end + end + rescue TimeoutError + # ok + end + _puts_("\n\n") + end + + def copy_file(from,to='.',exclude=[]) + to, ex = path(to), [exclude].flatten + Dir.glob(path(from)).each do |file| + tofile = to.sub(/[\.\*]$/o) do File.basename(file) end + _do_copy_(file,tofile) unless ex.include?(File.extname(file)) + end + end + + def clone_file(from,to) + if from and to then + to = File.join(File.basename(from),to) if File.basename(to).empty? + _do_copy_(from,to) + end + end + + def copy_dir(from,to,pattern='*',exclude=[]) # recursive + pattern = '*' if ! pattern or pattern.empty? + if from and to and File.expand_path(from) != File.expand_path(to) then + ex = [exclude].flatten + Dir.glob("#{from}/**/#{pattern}").each do |file| + unless ex.include?(File.extname(file)) then + _do_copy_(file,File.join(to,file.sub(/^#{from}/, ''))) + end + end + end + end + + def copy_path(from,to,pattern='*',exclude=[]) # non-recursive + pattern = '*' if ! pattern or pattern.empty? + if from and to and File.expand_path(from) != File.expand_path(to) then + ex = [exclude].flatten + Dir.glob("#{from}/#{pattern}").each do |file| + unless ex.include?(File.extname(file)) then + _do_copy_(file,File.join(to,file.sub(/^#{from}/, ''))) + end + end + end + end + + def _do_copy_(file,tofile) + if FileTest.file?(file) and File.expand_path(file) != File.expand_path(tofile) then + begin + create_dir(File.dirname(tofile)) + File.copy(file,tofile) + rescue + error("unable to copy #{file} to #{tofile}") + else + message("file #{file} copied to #{tofile}") + end + else + puts("file #{file} is not copied") + end + end + + def rename_file(from,to) + from, to = path(from), path(to) + begin + File.move(from,to) + rescue + error("unable to rename #{from} to #{to}") + else + message("#{from} renamed to #{to}") + end + end + + def delete_file(pattern) + Dir.glob(path(pattern)).each do |file| + _do_delete_(file) + end + end + + def delete_files(*files) + [*files].flatten.each do |file| + _do_delete_(file) + end + end + + def _do_delete_(file) + if FileTest.file?(file) then + begin + File.delete(file) + rescue + error("unable to delete file #{file}") + else + message("file #{file} deleted") + end + else + message("no file #{File.expand_path(file)}") + end + end + + def show_log(filename=nil) + if filename then + begin + if f = File.open(filename,'w') then + @log.each do |line| + f.puts(line) + end + f.close + end + message("log data written to #{filename}") + rescue + error("unable to write log to #{filename}") + end + else + @log.each do |line| + _puts_(line) + end + end + end + + def _puts_(str) + begin + STDOUT.puts( str) + rescue + STDERR.puts("error while writing '#{str}' to terminal") + end + end + + def puts(message) + @log << message + _puts_(message) + end + + def error(message) + puts("! #{message}") + exit + end + + def warning(message) + puts("- #{message}") + end + + def message(message) + puts("+ #{message}") + end + + def export_variable(variable,value) + value = path(value) if value.class == Array + ENV[variable] = value + message("environment variable #{variable} set to #{value}") + return value + end + + def execute_command(*command) + begin + command = [*command].flatten.join(' ') + message("running '#{command}'") + _puts_("\n") + ok = system(command) + _puts_("\n") + if true then # ok then + message("finished '#{command}'") + else + error("error in running #{command}") + end + rescue + error("unable to run #{command}") + end + end + + def pipe_command(*command) + begin + command = [*command].flatten.join(' ') + message("running '#{command}'") + result = `#{command}` + _puts_("\n") + _puts_(result) + _puts_("\n") + rescue + error("unable to run #{command}") + end + end + + def execute_script(script) + script = suffixed(script,'rb') + script = path(script_path,File.basename(script)) unless found(script) + if found(script) then + begin + message("loading script #{script}") + load(script) + rescue + error("error in loading script #{script} (#{$!})") + else + message("script #{script} finished") + end + else + warning("no script #{script}") + end + end + + def execute_binary(*command) + command = [*command].flatten.join(' ').split(' ') + command[0] = binary(command[0]) + execute_command(command) + end + + def extend_path(pth) + export_variable('PATH',"#{path(pth)}#{File::PATH_SEPARATOR}#{ENV['PATH']}") + end + + def startup_path + @startuppath + end + + def current_path + Dir.getwd + end + + def script_path + @ownpath + end + + def push_path(newpath) + newpath = File.expand_path(newpath) + @paths.push(newpath) + change_dir(newpath) + end + + def pop_path + change_dir(if @paths.length > 0 then @paths.pop else @startuppath end) + end + + # runner = Runner.new + # runner.texmfstart('texexec','--help') + + def texmfstart(name,args,verbose=false) + command = ['texmfstart',"#{'--verbose' if verbose}",name,args].flatten.join(' ') + system(command) + end + +end + +class Job + + # copied from texmfstart and patched (message/error), different name + + def use_tree(tree) + unless tree.empty? then + begin + setuptex = File.join(tree,'setuptex.tmf') + if FileTest.file?(setuptex) then + message("tex tree : #{setuptex}") + ENV['TEXPATH'] = tree.sub(/\/+$/,'') # + '/' + ENV['TMP'] = ENV['TMP'] || ENV['TEMP'] || ENV['TMPDIR'] || ENV['HOME'] + case RUBY_PLATFORM + when /(mswin|bccwin|mingw|cygwin)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-mswin' + when /(linux)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-linux' + when /(darwin|rhapsody|nextstep)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-macosx' + # when /(netbsd|unix)/i then # todo + else # todo + end + ENV['TEXMFOS'] = "#{ENV['TEXPATH']}/#{ENV['TEXOS']}" + message("preset : TEXPATH => #{ENV['TEXPATH']}") + message("preset : TEXOS => #{ENV['TEXOS']}") + message("preset : TEXMFOS => #{ENV['TEXMFOS']}") + message("preset : TMP => #{ENV['TMP']}") + IO.readlines(File.join(tree,'setuptex.tmf')).each do |line| + case line + when /^[\#\%]/ then + # comment + when /^(.*?)\s+\=\s+(.*)\s*$/ then + k, v = $1, $2 + ENV[k] = v.gsub(/\%(.*?)\%/) do + ENV[$1] || '' + end + message("user set : #{k} => #{ENV[k]}") + end + end + else + warning("no setup file '#{setuptex}', tree not initialized") # no error + end + rescue + warning("error in setup: #{$!}") + end + end + end + +end + +Job::set_own_path($0) + +if Job::ownfile == 'runtools.rb' then + + begin + script = ARGV.shift + if script then + script += '.rb' if File.extname(script).empty? + fullname = File.expand_path(script) + fullname = File.join(Job::ownpath,script) unless FileTest.file?(fullname) + if FileTest.file?(fullname) then + puts("loading script #{fullname}") + Job::set_own_path(fullname) + load(fullname) + else + puts("unknown script #{fullname}") + end + else + puts("provide script name") + end + rescue + puts("fatal error: #{$!}") + end + +end diff --git a/scripts/context/ruby/texexec.rb b/scripts/context/ruby/texexec.rb new file mode 100644 index 000000000..747d76b68 --- /dev/null +++ b/scripts/context/ruby/texexec.rb @@ -0,0 +1,792 @@ +#!/usr/bin/env ruby +#encoding: ASCII-8BIT + +banner = ['TeXExec', 'version 6.2.1', '1997-2009', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'fileutils' +# require 'ftools' # needed ? + +require 'base/switch' +require 'base/logger' +require 'base/variables' +require 'base/system' + +require 'base/state' # needed ? +require 'base/file' # needed ? + +require 'base/tex' +require 'base/texutil' +require 'base/kpse' + +class Commands + + include CommandBase + + def make + if job = TEX.new(logger) then + prepare(job) + # bonus, overloads language switch ! + job.setvariable('language','all') if @commandline.option('all') + if @commandline.arguments.length > 0 then + if @commandline.arguments.first == 'all' then + job.setvariable('texformats',job.defaulttexformats) + job.setvariable('mpsformats',job.defaultmpsformats) + else + job.setvariable('texformats',@commandline.arguments) + job.setvariable('mpsformats',@commandline.arguments) + end + end + job.makeformats + job.inspect && Kpse.inspect if @commandline.option('verbose') + seterror if job.error? + end + end + + def check + if job = TEX.new(logger) then + job.checkcontext + job.inspect && Kpse.inspect if @commandline.option('verbose') + end + end + + def main + if @commandline.arguments.length>0 then + process + else + help + end + end + + def process + if job = TEX.new(logger) then + job.setvariable('files',@commandline.arguments) + prepare(job) + job.processtex + job.inspect && Kpse.inspect if @commandline.option('verbose') + seterror if job.error? + end + end + + def mptex + if job = TEX.new(logger) then + job.setvariable('files',@commandline.arguments) + prepare(job) + job.processmptex + job.inspect && Kpse.inspect if @commandline.option('verbose') + seterror if job.error? + end + end + + def mpxtex + if job = TEX.new(logger) then + job.setvariable('files',@commandline.arguments) + prepare(job) + job.processmpxtex + job.inspect && Kpse.inspect if @commandline.option('verbose') + seterror if job.error? + end + end + + def mpgraphic + if job = TEX.new(logger) then + job.setvariable('files',@commandline.arguments) + prepare(job) + job.processmpgraphic + job.inspect && Kpse.inspect if @commandline.option('verbose') + seterror if job.error? + end + end + + def mpstatic + if job = TEX.new(logger) then + job.setvariable('filename',@commandline.arguments.first) + prepare(job) + job.processmpstatic + job.inspect && Kpse.inspect if @commandline.option('verbose') + seterror if job.error? + end + end + + # hard coded goodies # to be redone as s-ctx-.. with vars passed as such + + def listing + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + if files.length > 0 then + if f = File.open(job.tempfilename('tex'),'w') then + backspace = @commandline.checkedoption('backspace', '1.5cm') + topspace = @commandline.checkedoption('topspace', '1.5cm') + pretty = @commandline.option('pretty') + f << "% interface=english\n" + f << "\\setupbodyfont[11pt,tt]\n" + f << "\\setuplayout\n" + f << " [topspace=#{topspace},backspace=#{backspace},\n" + f << " header=0cm,footer=1.5cm,\n" + f << " width=middle,height=middle]\n" + f << "\\setuptyping[lines=yes]\n" + f << "\\setuptyping[option=color]\n" if pretty + f << "\\starttext\n"; + files.each do |filename| + report("list file: #{filename}") + cleanname = cleantexfilename(filename).downcase + f << "\\page\n" + f << "\\setupfootertexts[\\tttf #{cleanname}][\\tttf \\pagenumber]\n" + f << "\\typefile{#{filename}}\n" + end + f << "\\stoptext\n" + f.close + job.setvariable('interface','english') + job.setvariable('simplerun',true) + # job.setvariable('nooptionfile',true) + job.setvariable('files',[job.tempfilename]) + job.processtex + else + report('no files to list') + end + else + report('no files to list') + end + job.cleanuptemprunfiles + end + end + + def figures + # we replaced "texutil --figures ..." + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + fast = @commandline.option('fast') + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + if fast or (files.length > 0) then + if f = File.open(job.tempfilename('tex'),'w') then + files.delete("texexec.pdf") + # Kpse.runscript('rlxtools', ['--identify','--collect'], files.join(' ')) unless fast + system("texmfstart rlxtools --identify --collect #{files.join(' ')}") + figures = @commandline.checkedoption('method', 'a').downcase + paperoffset = @commandline.checkedoption('paperoffset', '0pt') + backspace = @commandline.checkedoption('backspace', '1.5cm') + topspace = @commandline.checkedoption('topspace', '1.5cm') + boxtype = @commandline.checkedoption('boxtype','') + f << "% format=english\n"; + f << "\\usemodule[res-20]\n" + f << "\\setuplayout\n"; + f << " [topspace=#{topspace},backspace=#{backspace},\n" + f << " header=1.5cm,footer=0pt,\n"; + f << " width=middle,height=middle]\n"; + if @commandline.option('fullscreen') then + f << "\\setupinteraction\n"; + f << " [state=start]\n"; + f << "\\setupinteractionscreen\n"; + f << " [option=max]\n"; + end + boxtype += "box" unless boxtype.empty? || (boxtype =~ /box$/io) + f << "\\starttext\n"; + f << "\\showexternalfigures[alternative=#{figures},offset=#{paperoffset},size=#{boxtype}]\n"; + f << "\\stoptext\n"; + f.close + job.setvariable('interface','english') + job.setvariable('simplerun',true) + job.setvariable('files',[job.tempfilename]) + job.processtex + # File.silentdelete('rlxtools.rli') unless job.getvariable('keep') + else + report('no figures to show') + end + else + report('no figures to show') + end + job.cleanuptemprunfiles + end + end + + def modules + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + msuffixes = ['tex','mkii','mkiv','mp','pl','pm','rb'] + if files.length > 0 then + files.each do |fname| + fnames = Array.new + if FileTest.file?(fname) then + fnames << fname + else + msuffixes.each do |fsuffix| + fnames << File.suffixed(fname,fsuffix) + end + end + fnames.each do |ffname| + if msuffixes.include?(File.splitname(ffname)[1]) && FileTest.file?(ffname) then + if mod = File.open(job.tempfilename('tex'),'w') then + if File.suffix(ffname) =~ /^(mkii|mkiv)$/o then + markfile = $1 + else + markfile = nil + end + # Kpse.runscript('ctxtools',['--document'],ffname) + system("texmfstart ctxtools --document #{ffname}") + if ted = File.silentopen(File.suffixed(ffname,'ted')) then + firstline = ted.gets + if firstline =~ /interface=/o then + mod << firstline + else + mod << "% interface=en\n" + end + ted.close + else + mod << "% interface=en\n" + end + mod << "\\usemodule[mod-01]\n" + mod << "\\def\\ModuleNumber{1}\n" + mod << "\\starttext\n" + # todo: global file too + mod << "\\readlocfile{#{File.suffixed(ffname,'ted')}}{}{}\n" + mod << "\\stoptext\n" + mod.close + job.setvariable('interface','english') # redundant + # job.setvariable('simplerun',true) + # job.setvariable('nooptionfile',true) + job.setvariable('files',[job.tempfilename]) + result = File.unsuffixed(File.basename(ffname)) + if markfile then + result = result+'-'+markfile + end + job.setvariable('result',result) + job.processtex + # ["dvi", "pdf","ps"].each do |s| + # File.silentrename(job.tempfilename(s),File.suffixed(ffname,s)); + # end + end + end + end + end + else + report('no modules to process') + end + job.cleanuptemprunfiles + end + end + + def pdfsplit + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + filename = File.expand_path(@commandline.arguments.first) + if FileTest.file?(filename) then + basename = filename.sub(/\..*?$/,'') + tempfile = File.suffixed(job.tempfilename,'tex') + if basename != filename then + info = `pdfinfo #{filename}` + if info =~ /Pages:\s*(\d+)/ then + nofpages = $1.to_i + result = @commandline.checkedoption('result','texexec') + nofpages.times do |i| + if f = File.open(tempfile,"w") then + n = i + 1 + report("extracting page #{n}") + f << "\\starttext\\startTEXpage\n" + f << "\\externalfigure[#{filename}][object=no,page=#{n}]\n" + f << "\\stopTEXpage\\stoptext\n" + f.close + job.setvariable('result',"#{result}-#{n}") + job.setvariable('interface','english') # redundant + job.setvariable('simplerun',true) + job.setvariable('purge',true) + job.setvariable('files',[tempfile]) + job.processtex + end + end + end + end + end + job.cleanuptemprunfiles + end + end + + def arrangeoutput + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + if files.length > 0 then + if f = File.open(job.tempfilename('tex'),'w') then + emptypages = @commandline.checkedoption('addempty', '') + paperoffset = @commandline.checkedoption('paperoffset', '0cm') + textwidth = @commandline.checkedoption('textwidth', '0cm') + backspace = @commandline.checkedoption('backspace', '0cm') + topspace = @commandline.checkedoption('topspace', '0cm') + f << "\\definepapersize\n" + f << " [offset=#{paperoffset}]\n" + f << "\\setuplayout\n" + f << " [backspace=#{backspace},\n" + f << " topspace=#{topspace},\n" + f << " marking=on,\n" if @commandline.option('marking') + f << " width=middle,\n" + f << " height=middle,\n" + f << " location=middle,\n" + f << " header=0pt,\n" + f << " footer=0pt]\n" + unless @commandline.option('noduplex') then + f << "\\setuppagenumbering\n" + f << " [alternative=doublesided]\n" + end + f << "\\starttext\n" + files.each do |filename| + report("arranging file #{filename}") + f << "\\insertpages\n" + f << " [#{filename}]\n" + f << " [#{emptypages}]\n" unless emptypages.empty? + f << " [width=#{textwidth}]\n" + end + f << "\\stoptext\n" + f.close + job.setvariable('interface','english') + job.setvariable('simplerun',true) + job.setvariable('arrange',true) + # job.setvariable('nooptionfile',true) + job.setvariable('files',[job.tempfilename]) + job.processtex + else + report('no files to arrange') + end + else + report('no files to arrange') + end + job.cleanuptemprunfiles + end + end + + def selectoutput + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + if files.length > 0 then + if f = File.open(job.tempfilename('tex'),'w') then + selection = @commandline.checkedoption('selection', '') + paperoffset = @commandline.checkedoption('paperoffset', '0cm') + textwidth = @commandline.checkedoption('textwidth', '0cm') + backspace = @commandline.checkedoption('backspace', '0cm') + topspace = @commandline.checkedoption('topspace', '0cm') + paperformat = @commandline.checkedoption('paperformat', 'A4*A4').split(/[\*x]/o) + from, to = paperformat[0] || 'A4', paperformat[1] || paperformat[0] || 'A4' + if from == 'fit' or to == 'fit' then + f << "\\getfiguredimensions[#{files.first}]\n" + if from == 'fit' then + f << "\\expanded{\\definepapersize[from-fit][width=\\figurewidth,height=\\figureheight]}\n" + from = 'from-fit' + end + if to == 'fit' then + f << "\\expanded{\\definepapersize[to-fit][width=\\figurewidth,height=\\figureheight]}\n" + to = 'to-fit' + end + end + job.setvariable('paperformat','') # else overloaded later on + f << "\\setuppapersize[#{from}][#{to}]\n" + f << "\\definepapersize\n"; + f << " [offset=#{paperoffset}]\n"; + f << "\\setuplayout\n"; + f << " [backspace=#{backspace},\n"; + f << " topspace=#{topspace},\n"; + f << " marking=on,\n" if @commandline.option('marking') + f << " width=middle,\n"; + f << " height=middle,\n"; + f << " location=middle,\n"; + f << " header=0pt,\n"; + f << " footer=0pt]\n"; + f << "\\setupexternalfigures\n"; + f << " [directory=]\n"; + f << "\\starttext\n"; + unless selection.empty? then + f << "\\filterpages\n" + f << " [#{files.first}][#{selection}][width=#{textwidth}]\n" + end + f << "\\stoptext\n" + f.close + job.setvariable('interface','english') + job.setvariable('simplerun',true) + # job.setvariable('nooptionfile',true) + job.setvariable('files',[job.tempfilename]) + job.processtex + else + report('no files to selectt') + end + else + report('no files to select') + end + job.cleanuptemprunfiles + end + end + + def copyoutput + copyortrim(false,'copy') + end + + def trimoutput + copyortrim(true,'trim') + end + + def copyortrim(trim=false,what='unknown') + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + if files.length > 0 then + if f = File.open(job.tempfilename('tex'),'w') then + scale = @commandline.checkedoption('scale') + begin + scale = (scale.to_f * 1000.0).to_i if scale.to_i < 10 + rescue + scale = 1000 + end + scale = scale.to_i + paperoffset = @commandline.checkedoption('paperoffset', '0cm') + f << "\\starttext\n" + files.each do |filename| + result = @commandline.checkedoption('result','texexec') + begin + if (filename !~ /^texexec/io) && (filename !~ /^#{result}/) then + report("copying file: #{filename}") + f << "\\getfiguredimensions\n" + f << " [#{filename}]\n" + f << " [scale=#{scale},\n" + f << " page=1,\n" + f << " size=trimbox\n" if trim + f << "]\n" + f << "\\definepapersize\n" + f << " [copy]\n" + f << " [width=\\figurewidth,\n" + f << " height=\\figureheight]\n" + f << "\\setuppapersize\n" + f << " [copy][copy]\n" + f << "\\setuplayout\n" + f << " [page]\n" + f << "\\setupexternalfigures\n" + f << " [directory=]\n" + f << "\\copypages\n" + f << " [#{filename}]\n" + f << " [scale=#{scale},\n" + f << " marking=on,\n" if @commandline.option('markings') + f << " size=trimbox,\n" if trim + f << " offset=#{paperoffset}]\n" + end + rescue + report("wrong specification") + end + end + f << "\\stoptext\n" + f.close + job.setvariable('interface','english') + job.setvariable('simplerun',true) + # job.setvariable('nooptionfile',true) + job.setvariable('files',[job.tempfilename]) + job.processtex + else + report("no files to #{what}") + end + else + report("no files to #{what}") + end + job.cleanuptemprunfiles + end + end + + # todo: make this styles + + def combineoutput + if job = TEX.new(logger) then + prepare(job) + job.cleanuptemprunfiles + files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end + if files.length > 0 then + if f = File.open(job.tempfilename('tex'),'w') then + paperoffset = @commandline.checkedoption('paperoffset', '0cm') + combination = @commandline.checkedoption('combination','2*2').split(/[\*x]/o) + paperformat = @commandline.checkedoption('paperformat', 'A4*A4').split(/[\*x]/o) + bannerheight = @commandline.checkedoption('bannerheight', '') + nx, ny = combination[0] || '2', combination[1] || combination[0] || '2' + from, to = paperformat[0] || 'A4', paperformat[1] || paperformat[0] || 'A4' + f << "\\setuppapersize[#{from}][#{to}]\n" + f << "\\setuplayout\n" + f << " [topspace=#{paperoffset},backspace=#{paperoffset},\n" + f << " header=0pt,footer=0pt,\n" + f << " width=middle,height=middle]\n" + if bannerheight.empty? then + f << "\\setuplayout[footer=1cm]\n" + else + f << "\\definelayer[page][width=\\paperwidth,height=\\paperheight]\n" + f << "\\setupbackgrounds[page][background=page]\n" + end + if @commandline.option('nobanner') then + f << "\\setuplayout[footer=0cm]\n" + f << "\\setupbackgrounds[page][background=]\n" + end + f << "\\setupexternalfigures\n" + f << " [directory=]\n" + f << "\\starttext\n" + files.each do |filename| + result = @commandline.checkedoption('result','texexec') + if (filename !~ /^texexec/io) && (filename !~ /^#{result}/) then + report("combination file: #{filename}") + cleanname = cleantexfilename(filename).downcase + bannerstring = "\\tttf #{cleanname}\\quad\\quad\\currentdate\\quad\\quad\\pagenumber" + if bannerheight.empty? then + f << "\\setupfootertexts\n" + f << " [#{bannerstring}]\n" + else + # for the moment we lack a better hook + f << "\\setuptexttexts\n" + f << " [{\\setlayerframed[page][preset=middlebottom][frame=off,height=#{bannerheight}]{#{bannerstring}}}]\n" + end + f << "\\combinepages[#{filename}][nx=#{nx},ny=#{ny}]\n" + f << "\\page\n" + end + end + f << "\\stoptext\n" + f.close + job.setvariable('interface','english') + job.setvariable('simplerun',true) + # job.setvariable('nooptionfile',true) + job.setvariable('files',[job.tempfilename]) + job.processtex + else + report('no files to list') + end + else + report('no files to list') + end + job.cleanuptemprunfiles + end + end + + private + + def prepare(job) + + job.booleanvars.each do |k| + job.setvariable(k,@commandline.option(k)) + end + job.stringvars.each do |k| + job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty? + end + job.standardvars.each do |k| + job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty? + end + job.knownvars.each do |k| + job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty? + end + +job.setvariable('given.backend',job.getvariable('backend')) + + if (str = @commandline.option('engine')) && ! str.standard? && ! str.empty? then + job.setvariable('texengine',str) + elsif @commandline.oneof('luatex') then + job.setvariable('texengine','luatex') + elsif @commandline.oneof('pdfetex','pdftex','pdf') then + job.setvariable('texengine','pdftex') + elsif @commandline.oneof('xetex','xtx') then + job.setvariable('texengine','xetex') + elsif @commandline.oneof('aleph') then + job.setvariable('texengine','aleph') + elsif @commandline.oneof('petex') then + job.setvariable('texengine','petex') + else + job.setvariable('texengine','standard') + end + + if (str = @commandline.option('backend')) && ! str.standard? && ! str.empty? then + job.setvariable('backend',str) + elsif @commandline.oneof('pdfetex','pdftex','pdf','luatex') then + job.setvariable('backend','pdftex') + elsif @commandline.oneof('dvipdfmx','dvipdfm','dpx','dpm') then + job.setvariable('backend','dvipdfmx') + elsif @commandline.oneof('xetex','xtx') then + job.setvariable('backend','xetex') + elsif @commandline.oneof('aleph') then + job.setvariable('backend','dvipdfmx') + elsif @commandline.oneof('petex') then + job.setvariable('backend','dvipdfmx') + elsif @commandline.oneof('dvips','ps') then + job.setvariable('backend','dvips') + elsif @commandline.oneof('xdv') then + job.setvariable('backend','xdv') + else + case job.getvariable('texengine') + when 'pdfetex' then job.setvariable('backend','pdftex') + when 'pdftex' then job.setvariable('backend','pdftex') + when 'luatex' then job.setvariable('backend','pdftex') + when 'xetex' then job.setvariable('backend','xetex') + when 'petex' then job.setvariable('backend','dvipdfmx') + when 'aleph' then job.setvariable('backend','dvipdfmx') + else + job.setvariable('backend','standard') + end + end + + if (str = @commandline.option('engine')) && ! str.standard? && ! str.empty? then + job.setvariable('mpsengine',@commandline.option('engine')) + else + job.setvariable('mpsengine','standard') + end + + end + + def cleantexfilename(filename) + filename.gsub(/([\$\_\#])/) do "\\$1" end.gsub(/([\~])/) do "\\string$1" end + end + +end + +# we will make this pluggable, i.e. load plugins from base/tex that +# extend the class and may even add switches +# +# commandline.load_plugins('base/tex') +# +# maybe it's too slow so for a while keep the --pdf* in here + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('make', 'make formats') +commandline.registeraction('check', 'check versions') +commandline.registeraction('process', 'process file') +commandline.registeraction('mptex', 'process mp file') +commandline.registeraction('mpxtex', 'process mpx file') +commandline.registeraction('mpgraphic', 'process mp file to stand-alone graphics') +commandline.registeraction('mpstatic', 'process mp/ctx file to stand-alone graphics') + +commandline.registeraction('listing', 'list of file content') +commandline.registeraction('figures', 'generate overview of figures') +commandline.registeraction('modules', 'generate module documentation') +commandline.registeraction('pdfarrange', 'impose pages (booklets)') +commandline.registeraction('pdfselect', 'select pages from file(s)') +commandline.registeraction('pdfcopy', 'copy pages from file(s)') +commandline.registeraction('pdftrim', 'trim pages from file(s)') +commandline.registeraction('pdfcombine', 'combine multiple pages') +commandline.registeraction('pdfsplit', 'split file in pages') + +# compatibility switch + +class Commands + + include CommandBase + + alias pdfarrange :arrangeoutput + alias pdfselect :selectoutput + alias pdfcopy :copyoutput + alias pdftrim :trimoutput + alias pdfcombine :combineoutput + +end + +# so far for compatibility, will move to tex + +@@extrastringvars = [ + 'pages', 'background', 'backspace', 'topspace', 'boxtype', 'tempdir','bannerheight', + 'printformat', 'method', 'scale', 'selection', + 'combination', 'textwidth', 'addempty', 'logfile', + 'startline', 'endline', 'startcolumn', 'endcolumn', 'scale' +] + +@@extrabooleanvars = [ + 'centerpage', 'noduplex', 'color', 'pretty', + 'fullscreen', 'screensaver', 'markings' +] + +if job = TEX.new(logger) then + + job.setextrastringvars(@@extrastringvars) + job.setextrabooleanvars(@@extrabooleanvars) + + job.booleanvars.each do |k| + commandline.registerflag(k) + end + job.stringvars.each do |k| + commandline.registervalue(k,'') + end + job.standardvars.each do |k| + commandline.registervalue(k,'standard') + end + job.knownvars.each do |k| + commandline.registervalue(k,'') + end + +end + +class Commands + + alias saved_help help + + def wrap_help(title, vars) + report("") + report(title) + report("") + r, n = '', 0 + vars.sort.each do |s| + if n == 5 then + report(r) + r, n = '', 1 + else + n += 1 + end + r << ' ' + s + end + report(r) unless r.empty? + end + + def help + saved_help + if @commandline.option('all') then + if job = TEX.new(logger) then + wrap_help("boolean switches:", job.allbooleanvars) + wrap_help("string switches:", job.allstringvars) + end + else + report('') + report('--help --all shows all switches') + end + end + +end + +# todo: register flags -> first one true + +commandline.registerflag('pdf') +commandline.registerflag('pdftex') +commandline.registerflag('pdfetex') +commandline.registerflag('luatex') + +commandline.registerflag('dvipdfmx') +commandline.registerflag('dvipdfm') +commandline.registerflag('dpx') +commandline.registerflag('dpm') + +commandline.registerflag('dvips') +commandline.registerflag('ps') + +commandline.registerflag('xetex') +commandline.registerflag('xtx') +commandline.registerflag('xdv') + +commandline.registerflag('aleph') + +commandline.registerflag('petex') + +commandline.registerflag('all') +commandline.registerflag('fast') +commandline.registerflag('sort') + +# generic + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registerflag('verbose') + +commandline.expand + +Commands.new(commandline,logger,banner).execute(commandline.action || 'main') # or just execute() diff --git a/scripts/context/ruby/texmfstart.rb b/scripts/context/ruby/texmfstart.rb new file mode 100644 index 000000000..97087c3ae --- /dev/null +++ b/scripts/context/ruby/texmfstart.rb @@ -0,0 +1,1277 @@ +#!/usr/bin/env ruby +#encoding: ASCII-8BIT + +# We have removed the fast, server and client variants and no longer +# provide the distributed 'serve trees' option. After all, we're now +# using luatex. + +# program : texmfstart +# copyright : PRAGMA Advanced Document Engineering +# version : 1.9.0 - 2003/2006 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# info : j.hagen@xs4all.nl +# www : www.pragma-pod.com / www.pragma-ade.com + +# no special requirements, i.e. no exa modules/classes used + +# texmfstart [switches] filename [optional arguments] +# +# ruby2exe texmfstart --help -> avoids stub test +# +# Of couse I can make this into a nice class, which i'll undoubtely will +# do when I feel the need. In that case it will be part of a bigger game. + +# --locate => provides location +# --exec => exec instead of system +# --iftouched=a,b => only if timestamp a<>b +# --ifchanged=a,b => only if checksum changed +# +# file: path: bin: + +# texmfstart --exec bin:scite *.tex + +# we don't depend on other libs + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require "rbconfig" +require "fileutils" + +require "digest/md5" + +# kpse_merge_start + +class File + def File::makedirs(*x) + FileUtils.makedirs(x) + end +end + +class String + + def split_path + if self =~ /\;/o || self =~ /^[a-z]\:/io then + self.split(";") + else + self.split(":") + end + end + +end + +class Array + + def join_path + self.join(File::PATH_SEPARATOR) + end + +end + +class File + + def File.locate_file(path,name) + begin + files = Dir.entries(path) + if files.include?(name) then + fullname = File.join(path,name) + return fullname if FileTest.file?(fullname) + end + files.each do |p| + fullname = File.join(path,p) + if p != '.' and p != '..' and FileTest.directory?(fullname) and result = locate_file(fullname,name) then + return result + end + end + rescue + # bad path + end + return nil + end + + def File.glob_file(pattern) + return Dir.glob(pattern).first + end + +end + +# kpse_merge_file: 't:/ruby/base/kpsedirect.rb' + +class KpseDirect + + attr_accessor :progname, :format, :engine + + def initialize + @progname, @format, @engine = '', '', '' + end + + def expand_path(str) + clean_name(`kpsewhich -expand-path=#{str}`.chomp) + end + + def expand_var(str) + clean_name(`kpsewhich -expand-var=#{str}`.chomp) + end + + def find_file(str) + clean_name(`kpsewhich #{_progname_} #{_format_} #{str}`.chomp) + end + + def _progname_ + if @progname.empty? then '' else "-progname=#{@progname}" end + end + def _format_ + if @format.empty? then '' else "-format=\"#{@format}\"" end + end + + private + + def clean_name(str) + str.gsub(/\\/,'/') + end + +end + +# kpse_merge_stop + +$mswindows = Config::CONFIG['host_os'] =~ /mswin/ +$separator = File::PATH_SEPARATOR +$version = "2.1.0" +$ownpath = File.dirname($0) + +if $mswindows then + require "win32ole" + require "Win32API" +end + +# exit if defined?(REQUIRE2LIB) + +$stdout.sync = true +$stderr.sync = true + +$applications = Hash.new +$suffixinputs = Hash.new +$predefined = Hash.new +$runners = Hash.new + +$suffixinputs['pl'] = 'PERLINPUTS' +$suffixinputs['rb'] = 'RUBYINPUTS' +$suffixinputs['py'] = 'PYTHONINPUTS' +$suffixinputs['lua'] = 'LUAINPUTS' +$suffixinputs['jar'] = 'JAVAINPUTS' +$suffixinputs['pdf'] = 'PDFINPUTS' + +$predefined['texexec'] = 'texexec.rb' +$predefined['texutil'] = 'texutil.rb' +$predefined['texfont'] = 'texfont.pl' +$predefined['texshow'] = 'texshow.pl' + +$predefined['makempy'] = 'makempy.pl' +$predefined['mptopdf'] = 'mptopdf.pl' +$predefined['pstopdf'] = 'pstopdf.rb' + +$predefined['examplex'] = 'examplex.rb' +$predefined['concheck'] = 'concheck.rb' + +$predefined['runtools'] = 'runtools.rb' +$predefined['textools'] = 'textools.rb' +$predefined['tmftools'] = 'tmftools.rb' +$predefined['ctxtools'] = 'ctxtools.rb' +$predefined['rlxtools'] = 'rlxtools.rb' +$predefined['pdftools'] = 'pdftools.rb' +$predefined['mpstools'] = 'mpstools.rb' +# $predefined['exatools'] = 'exatools.rb' +$predefined['xmltools'] = 'xmltools.rb' +# $predefined['luatools'] = 'luatools.lua' +# $predefined['mtxtools'] = 'mtxtools.rb' + +$predefined['newpstopdf'] = 'pstopdf.rb' +$predefined['newtexexec'] = 'texexec.rb' +$predefined['pdftrimwhite'] = 'pdftrimwhite.pl' + +$makelist = [ + # context + 'texexec', + 'texutil', + 'texfont', + # mp/ps + 'pstopdf', + 'mptopdf', + 'makempy', + # misc + 'ctxtools', + 'pdftools', + 'xmltools', + 'textools', + 'mpstools', + 'tmftools', + 'exatools', + 'runtools', + 'rlxtools', + 'pdftrimwhite', + 'texfind', + 'texshow' + # + # no 'luatools', + # no 'mtxtools', + # no, 'texmfstart' +] + +$scriptlist = 'rb|pl|py|lua|jar' +$documentlist = 'pdf|ps|eps|htm|html' + +$editor = ENV['TEXMFSTART_EDITOR'] || ENV['EDITOR'] || ENV['editor'] || 'scite' + +$crossover = true # to other tex tools, else only local +$kpse = nil + +def set_applications(page=1) + + $applications['unknown'] = '' + $applications['ruby'] = $applications['rb'] = 'ruby' + $applications['lua'] = $applications['lua'] = 'lua' + $applications['perl'] = $applications['pl'] = 'perl' + $applications['python'] = $applications['py'] = 'python' + $applications['java'] = $applications['jar'] = 'java' + + if $mswindows then + $applications['pdf'] = ['',"pdfopen --page #{page} --file",'acroread'] + $applications['html'] = ['','netscape','mozilla','opera','iexplore'] + $applications['ps'] = ['','gview32','gv','gswin32','gs'] + else + $applications['pdf'] = ["pdfopen --page #{page} --file",'acroread'] + $applications['html'] = ['netscape','mozilla','opera'] + $applications['ps'] = ['gview','gv','gs'] + end + + $applications['htm'] = $applications['html'] + $applications['eps'] = $applications['ps'] + + $runners['lua'] = "texlua" + +end + +set_applications() + +def check_kpse + if $kpse then + # already done + else + $kpse = KpseDirect.new + end +end + +if $mswindows then + + GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', ['P','P','N'], 'N') + GetLongPathName = Win32API.new('kernel32', 'GetLongPathName', ['P','P','N'], 'N') + + def dowith_pathname (filename,filemethod) + filename = filename.gsub(/\\/o,'/') # no gsub! because filename can be frozen + case filename + when /\;/o then + # could be a path spec + return filename + when /\s+/o then + # danger lurking + buffer = ' ' * 260 + length = filemethod.call(filename,buffer,buffer.size) + if length>0 then + return buffer.slice(0..length-1) + else + # when the path or file does not exist, nothing is returned + # so we try to handle the path separately from the basename + basename = File.basename(filename) + pathname = File.dirname(filename) + length = filemethod.call(pathname,buffer,260) + if length>0 then + return buffer.slice(0..length-1) + '/' + basename + else + return filename + end + end + else + # no danger + return filename + end + end + + def longpathname (filename) + dowith_pathname(filename,GetLongPathName) + end + + def shortpathname (filename) + dowith_pathname(filename,GetShortPathName) + end + +else + + def longpathname (filename) + filename + end + + def shortpathname (filename) + filename + end + +end + +class File + + @@update_eps = 1 + + def File.needsupdate(oldname,newname) + begin + oldtime = File.stat(oldname).mtime.to_i + newtime = File.stat(newname).mtime.to_i + if newtime >= oldtime then + return false + elsif oldtime-newtime < @@update_eps then + return false + else + return true + end + rescue + return true + end + end + + def File.syncmtimes(oldname,newname) + return + begin + if $mswindows then + # does not work (yet) / gives future timestamp + # t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here + # File.utime(0,t,oldname,newname) + else + t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here + File.utime(0,t,oldname,newname) + end + rescue + end + end + + def File.timestamp(name) + begin + "#{File.stat(name).mtime}" + rescue + return 'unknown' + end + end + +end + +def hashed (arr=[]) + arg = if arr.class == String then arr.split(' ') else arr.dup end + hsh = Hash.new + if arg.length > 0 + hsh['arguments'] = '' + done = false + arg.each do |s| + if done then + if s =~ /\s/ then + kvl = s.split('=') + if kvl[1] and kvl[1] !~ /^[\"\']/ then + hsh['arguments'] += ' ' + kvl[0] + "=" + '"' + kvl[1] + '"' + elsif s =~ /\s/ then + hsh['arguments'] += ' "' + s + '"' + else + hsh['arguments'] += ' ' + s + end + else + hsh['arguments'] += ' ' + s + end + else + kvl = s.split('=') + if kvl[0].sub!(/^\-+/,'') then + hsh[kvl[0]] = if kvl.length > 1 then kvl[1] else true end + else + hsh['file'] = s + done = true + end + end + end + end + return hsh +end + + +def launch(filename) + if $browser && $mswindows then + filename = filename.gsub(/\.[\/\\]/) do + Dir.getwd + '/' + end + report("launching #{filename}") + ie = WIN32OLE.new("InternetExplorer.Application") + ie.visible = true + ie.navigate(filename) + return true + else + return false + end +end + +# env|environment +# rel|relative +# loc|locate|kpse|path|file + +def quoted(str) + if str =~ /^\"/ then + return str + elsif str =~ / / then + return "\"#{str}\"" + else + return str + end +end + +def expanded(arg) # no "other text files", too restricted + arg.gsub(/(env|environment)\:([a-zA-Z\-\_\.0-9]+)/o) do + method, original, resolved = $1, $2, '' + if resolved = ENV[original] then + report("environment variable #{original} expands to #{resolved}") unless $report + quoted(resolved) + else + report("environment variable #{original} cannot be resolved") unless $report + quoted(original) + end + end . gsub(/(rel|relative)\:([a-zA-Z\-\_\.0-9]+)/o) do + method, original, resolved = $1, $2, '' + ['.','..','../..'].each do |r| + if FileTest.file?(File.join(r,original)) then + resolved = File.join(r,original) + break + end + end + if resolved.empty? then + quoted(original) + else + quoted(resolved) + end + end . gsub(/(kpse|loc|locate|file|path)\:([a-zA-Z\-\_\.0-9]+)/o) do + method, original, resolved = $1, $2, '' + if $program && ! $program.empty? then + # pstrings = ["-progname=#{$program}"] + pstrings = [$program] + else + # pstrings = ['','-progname=context'] + pstrings = ['','context'] + end + # auto suffix with texinputs as fall back + if ENV["_CTX_K_V_#{original}_"] then + resolved = ENV["_CTX_K_V_#{original}_"] + report("environment provides #{original} as #{resolved}") unless $report + quoted(resolved) + else + check_kpse + pstrings.each do |pstr| + if resolved.empty? then + # command = "kpsewhich #{pstr} #{original}" + # report("running #{command}") + report("locating '#{original}' in program space '#{pstr}'") + begin + # resolved = `#{command}`.chomp + $kpse.progname = pstr + $kpse.format = '' + resolved = $kpse.find_file(original).gsub(/\\/,'/') + rescue + resolved = '' + end + end + # elsewhere in the tree + if resolved.empty? then + # command = "kpsewhich #{pstr} -format=\"other text files\" #{original}" + # report("running #{command}") + report("locating '#{original}' in program space '#{pstr}' using format 'other text files'") + begin + # resolved = `#{command}`.chomp + $kpse.progname = pstr + $kpse.format = 'other text files' + resolved = $kpse.find_file(original).gsub(/\\/,'/') + rescue + resolved = '' + end + end + end + if resolved.empty? then + original = File.dirname(original) if method =~ /path/ + report("#{original} is not resolved") unless $report + ENV["_CTX_K_V_#{original}_"] = original if $crossover + quoted(original) + else + resolved = File.dirname(resolved) if method =~ /path/ + report("#{original} is resolved to #{resolved}") unless $report + ENV["_CTX_K_V_#{original}_"] = resolved if $crossover + quoted(resolved) + end + end + end +end + +def changeddir?(path) + if path.empty? then + return true + else + oldpath = File.expand_path(path) + begin + Dir.chdir(path) if not path.empty? + rescue + report("unable to change to directory: #{path}") + else + report("changed to directory: #{path}") + end + newpath = File.expand_path(Dir.getwd) + return oldpath == newpath + end +end + +def runcommand(command) + if $locate then + command = command.split(' ').collect do |c| + if c =~ /\//o then + begin + cc = File.expand_path(c) + c = cc if FileTest.file?(cc) + rescue + end + end + c + end . join(' ') + print command # to stdout and no newline + elsif $execute then + report("using 'exec' instead of 'system' call: #{command}") + exec(command) if changeddir?($path) + else + report("using 'system' call: #{command}") + system(command) if changeddir?($path) + end +end + +def join_command(args) + args[0] = $runners[args[0]] || args[0] + [args].join(' ') +end + +def runoneof(application,fullname,browserpermitted) + if browserpermitted && launch(fullname) then + return true + else + fullname = quoted(fullname) # added because MM ran into problems + report("starting #{$filename}") unless $report + output("\n") if $report && $verbose + applications = $applications[application.downcase] + if ! applications then + output("problems with determining application type") + return true + elsif applications.class == Array then + if $report then + output(join_command([fullname,expanded($arguments)])) + return true + else + applications.each do |a| + return true if runcommand(join_command([a,fullname,expanded($arguments)])) + end + end + elsif applications.empty? then + if $report then + output(join_command([fullname,expanded($arguments)])) + return true + else + return runcommand(join_command([fullname,expanded($arguments)])) + end + else + if $report then + output(join_command([applications,fullname,expanded($arguments)])) + return true + else + return runcommand(join_command([applications,fullname,expanded($arguments)])) + end + end + return false + end +end + +def report(str) + $stdout.puts(str) if $verbose +end + +def output(str) + $stdout.puts(str) +end + +def usage + print "version : #{$version} - 2003/2006 - www.pragma-ade.com\n" + print("\n") + print("usage : texmfstart [switches] filename [optional arguments]\n") + print("\n") + print("switches : --verbose --report --browser --direct --execute --locate --iftouched --ifchanged\n") + print(" --program --file --page --arguments --batch --edit --report --clear\n") + print(" --make --lmake --wmake --path --stubpath --indirect --before --after\n") + print(" --tree --autotree --environment --showenv\n") + print("\n") + print("example : texmfstart pstopdf.rb cow.eps\n") + print(" texmfstart --locate examplex.rb\n") + print(" texmfstart --execute examplex.rb\n") + print(" texmfstart --browser examplap.pdf\n") + print(" texmfstart showcase.pdf\n") + print(" texmfstart --page=2 --file=showcase.pdf\n") + print(" texmfstart --program=yourtex yourscript.rb arg-1 arg-2\n") + print(" texmfstart --direct xsltproc kpse:somefile.xsl somefile.xml\n") + print(" texmfstart --direct ruby rel:wn-cleanup-1.rb oldfile.xml newfile.xml\n") + print(" texmfstart bin:xsltproc env:somepreset path:somefile.xsl somefile.xml\n") + print(" texmfstart --iftouched=normal,lowres downsample.rb normal lowres\n") + print(" texmfstart --ifchanged=somefile.dat --direct processit somefile.dat\n") + print(" texmfstart bin:scite kpse:texmf.cnf\n") + print(" texmfstart --exec bin:scite *.tex\n") + print(" texmfstart --edit texmf.cnf\n") + print(" texmfstart --edit kpse:texmf.cnf\n") + print(" texmfstart --serve\n") + print("\n") + print(" texmfstart --stubpath=/usr/local/bin [--make --remove] --verbose all\n") + print(" texmfstart --stubpath=auto [--make --remove] all\n") + print("\n") + check_kpse +end + +# somehow registration does not work out (at least not under windows) +# the . is also not accepted by unix as seperator + +def tag(name) + if $crossover then "_CTX_K_S_#{name}_" else "TEXMFSTART.#{name}" end +end + +def registered?(filename) + return ENV[tag(filename)] != nil +end + +def registered(filename) + return ENV[tag(filename)] || 'unknown' +end + +def register(filename,fullname) + if fullname && ! fullname.empty? then # && FileTest.file?(fullname) + ENV[tag(filename)] = fullname + report("registering '#{filename}' as '#{fullname}'") + return true + else + return false + end +end + +def find(filename,program) + begin + filename = filename.sub(/script:/o, '') # so we have bin: and script: and nothing + if $predefined.key?(filename) then + report("expanding '#{filename}' to '#{$predefined[filename]}'") + filename = $predefined[filename] + end + if registered?(filename) then + report("already located '#{filename}'") + return registered(filename) + end + # create suffix list + if filename =~ /^(.*)\.(.+)$/ then + filename = $1 + suffixlist = [$2] + else + suffixlist = [$scriptlist.split('|'),$documentlist.split('|')].flatten + end + # first we honor a given path + if filename =~ /[\\\/]/ then + report("trying to honor '#{filename}'") + suffixlist.each do |suffix| + fullname = filename+'.'+suffix + if FileTest.file?(fullname) && register(filename,fullname) + return shortpathname(fullname) + end + end + end + filename.sub!(/^.*[\\\/]/, '') + # next we look at the current path and the callerpath + pathlist = [ ] + progpath = $applications[suffixlist[0]] + threadok = registered("THREAD") !~ /unknown/ + pathlist << ['.','current'] + pathlist << [$ownpath,'caller'] if $ownpath != '.' + pathlist << ["#{$ownpath}/../#{progpath}",'caller'] if progpath + pathlist << [registered("THREAD"),'thread'] if threadok + pathlist << ["#{registered("THREAD")}/../#{progpath}",'thread'] if progpath && threadok + pathlist.each do |p| + if p && ! p.empty? && ! (p[0] == 'unknown') then + suffixlist.each do |suffix| + fname = "#{filename}.#{suffix}" + fullname = File.expand_path(File.join(p[0],fname)) + report("locating '#{fname}' in #{p[1]} path '#{p[0]}'") + if FileTest.file?(fullname) && register(filename,fullname) then + report("'#{fname}' located in #{p[1]} path") + return shortpathname(fullname) + end + end + end + end + # now we consult environment settings + fullname = nil + check_kpse + $kpse.progname = program + suffixlist.each do |suffix| + begin + break unless $suffixinputs[suffix] + environment = ENV[$suffixinputs[suffix]] || ENV[$suffixinputs[suffix]+".#{$program}"] + if ! environment || environment.empty? then + begin + # environment = `kpsewhich -expand-path=\$#{$suffixinputs[suffix]}`.chomp + environment = $kpse.expand_path("\$#{$suffixinputs[suffix]}") + rescue + environment = nil + else + if environment && ! environment.empty? then + report("using kpsewhich variable #{$suffixinputs[suffix]}") + end + end + elsif environment && ! environment.empty? then + report("using environment variable #{$suffixinputs[suffix]}") + end + if environment && ! environment.empty? then + environment.split($separator).each do |e| + e.strip! + e = '.' if e == '\.' # somehow . gets escaped + e += '/' unless e =~ /[\\\/]$/ + fullname = e + filename + '.' + suffix + report("testing '#{fullname}'") + if FileTest.file?(fullname) then + break + else + fullname = nil + end + end + end + rescue + report("environment string '#{$suffixinputs[suffix]}' cannot be used to locate '#{filename}'") + fullname = nil + else + return shortpathname(fullname) if register(filename,fullname) + end + end + return shortpathname(fullname) if register(filename,fullname) + # then we fall back on kpsewhich + suffixlist.each do |suffix| + # TDS script scripts location as per 2004 + if suffix =~ /(#{$scriptlist})/ then + begin + report("using 'kpsewhich' to locate '#{filename}' in suffix space '#{suffix}' (1)") + # fullname = `kpsewhich -progname=#{program} -format=texmfscripts #{filename}.#{suffix}`.chomp + $kpse.format = 'texmfscripts' + fullname = $kpse.find_file("#{filename}.#{suffix}").gsub(/\\/,'/') + rescue + report("kpsewhich cannot locate '#{filename}' in suffix space '#{suffix}' (1)") + fullname = nil + else + return shortpathname(fullname) if register(filename,fullname) + end + end + # old TDS location: .../texmf/context/... + begin + report("using 'kpsewhich' to locate '#{filename}' in suffix space '#{suffix}' (2)") + # fullname = `kpsewhich -progname=#{program} -format="other text files" #{filename}.#{suffix}`.chomp + $kpse.format = 'other text files' + fullname = $kpse.find_file("#{filename}.#{suffix}").gsub(/\\/,'/') + rescue + report("kpsewhich cannot locate '#{filename}' in suffix space '#{suffix}' (2)") + fullname = nil + else + return shortpathname(fullname) if register(filename,fullname) + end + end + return shortpathname(fullname) if register(filename,fullname) + # let's take a look at the path + paths = ENV['PATH'].split($separator) + suffixlist.each do |s| + paths.each do |p| + suffixedname = "#{filename}.#{s}" + report("checking #{p} for #{filename}") + if FileTest.file?(File.join(p,suffixedname)) then + fullname = File.join(p,suffixedname) + return shortpathname(fullname) if register(filename,fullname) + end + end + end + # bad luck, we need to search the tree ourselves + if (suffixlist.length == 1) && (suffixlist.first =~ /(#{$documentlist})/) then + report("aggressively locating '#{filename}' in document trees") + begin + # texroot = `kpsewhich -expand-var=$SELFAUTOPARENT`.chomp + texroot = $kpse.expand_var("$SELFAUTOPARENT") + rescue + texroot = '' + else + texroot.sub!(/[\\\/][^\\\/]*?$/, '') + end + if not texroot.empty? then + sffxlst = suffixlist.join(',') + begin + report("locating '#{filename}' in document tree '#{texroot}/doc*'") + if (result = Dir.glob("#{texroot}/doc*/**/#{filename}.{#{sffxlst}}")) && result && result[0] && FileTest.file?(result[0]) then + fullname = result[0] + end + rescue + report("locating '#{filename}.#{suffixlist.join('|')}' in tree '#{texroot}' aborted") + end + end + return shortpathname(fullname) if register(filename,fullname) + end + report("aggressively locating '#{filename}' in tex trees") + begin + # textrees = `kpsewhich -expand-var=$TEXMF`.chomp + textrees = $kpse.expand_var("$TEXMF") + rescue + textrees = '' + end + if not textrees.empty? then + textrees.gsub!(/[\{\}\!]/, '') + textrees = textrees.split(',') + if (suffixlist.length == 1) && (suffixlist.first =~ /(#{$documentlist})/) then + speedup = ['doc**','**'] + else + speedup = ['**'] + end + sffxlst = suffixlist.join(',') + speedup.each do |speed| + textrees.each do |tt| + tt.gsub!(/[\\\/]$/, '') + if FileTest.directory?(tt) then + begin + report("locating '#{filename}' in tree '#{tt}/#{speed}/#{filename}.{#{sffxlst}}'") + if (result = Dir.glob("#{tt}/#{speed}/#{filename}.{#{sffxlst}}")) && result && result[0] && FileTest.file?(result[0]) then + fullname = result[0] + break + end + rescue + report("locating '#{filename}' in tree '#{tt}' aborted") + next + end + end + end + break if fullname && ! fullname.empty? + end + end + if register(filename,fullname) then + return shortpathname(fullname) + else + return '' + end + rescue + error, trace = $!, $@.join("\n") + report("fatal error: #{error}\n#{trace}") + # report("fatal error") + end +end + +def run(fullname) + if ! fullname || fullname.empty? then + output("the file '#{$filename}' is not found") + elsif FileTest.file?(fullname) then + begin + case fullname + when /\.(#{$scriptlist})$/i then + return runoneof($1,fullname,false) + when /\.(#{$documentlist})$/i then + return runoneof($1,fullname,true) + else + return runoneof('unknown',fullname,false) + end + rescue + report("starting '#{$filename}' in program space '#{$program}' fails (#{$!})") + end + else + report("the file '#{$filename}' in program space '#{$program}' is not accessible") + end + return false +end + +def direct(fullname) + begin + return runcommand([fullname.sub(/^(bin|binary)\:/, ''),expanded($arguments)].join(' ')) + rescue + return false + end +end + +def edit(filename) + begin + return runcommand([$editor,expanded(filename),expanded($arguments)].join(' ')) + rescue + return false + end +end + +def make(filename,windows=false,linux=false,remove=false) + basename = File.basename(filename).gsub(/\.[^.]+?$/, '') + if $stubpath == 'auto' then + basename = File.dirname($0) + '/' + basename + else + basename = $stubpath + '/' + basename unless $stubpath.empty? + end + if filename == 'texmfstart' then + program = 'ruby' + command = 'kpsewhich --format=texmfscripts --progname=context texmfstart.rb' + filename = `#{command}`.chomp.gsub(/\\/, '/') + if filename.empty? then + report("failure: #{command}") + return + elsif not remove then + if windows then + ['bat','cmd','exe'].each do |suffix| + if FileTest.file?("#{basename}.#{suffix}") then + report("windows stub '#{basename}.#{suffix}' skipped (already present)") + return + end + end + elsif linux && FileTest.file?(basename) then + report("unix stub '#{basename}' skipped (already present)") + return + end + end + else + program = nil + if filename =~ /[\\\/]/ && filename =~ /\.(#{$scriptlist})$/ then + program = $applications[$1] + end + filename = "\"#{filename}\"" if filename =~ /\s/ + program = 'texmfstart' if $indirect || ! program || program.empty? + end + begin + callname = $predefined[filename.sub(/\.*?$/,'')] || filename + if remove then + if windows && (File.delete(basename+'.bat') rescue false) then + report("windows stub '#{basename}.bat' removed (calls #{callname})") + elsif linux && (File.delete(basename) rescue false) then + report("unix stub '#{basename}' removed (calls #{callname})") + end + else + if windows && f = open(basename+'.bat','w') then + f.binmode + f.write("@echo off\015\012") + f.write("#{program} #{callname} %*\015\012") + f.close + report("windows stub '#{basename}.bat' made (calls #{callname})") + elsif linux && f = open(basename,'w') then + f.binmode + f.write("#!/bin/sh\012") + f.write("#{program} #{callname} \"$@\"\012") + f.close + report("unix stub '#{basename}' made (calls #{callname})") + end + end + rescue + report("failed to make stub '#{basename}' #{$!}") + return false + else + return true + end +end + +def process(&block) + if $iftouched then + files = $directives['iftouched'].split(',') + oldname, newname = files[0], files[1] + if oldname && newname && File.needsupdate(oldname,newname) then + report("file #{oldname}: #{File.timestamp(oldname)}") + report("file #{newname}: #{File.timestamp(newname)}") + report("file is touched, processing started") + yield + File.syncmtimes(oldname,newname) + else + report("file #{oldname} is untouched") + end + elsif $ifchanged then + filename = $directives['ifchanged'] + checkname = filename + ".md5" + oldchecksum, newchecksum = "old", "new" + begin + newchecksum = Digest::MD5.hexdigest(IO.read(filename)).upcase + rescue + newchecksum = "new" + else + begin + oldchecksum = IO.read(checkname).chomp + rescue + oldchecksum = "old" + end + end + if $verbose then + report("old checksum #{filename}: #{oldchecksum}") + report("new checksum #{filename}: #{newchecksum}") + end + if oldchecksum != newchecksum then + report("file is changed, processing started") + begin + File.open(checkname,'w') do |f| + f << newchecksum + end + rescue + end + yield + else + report("file #{filename} is unchanged") + end + else + yield + end +end + +def checkenvironment(tree) + report('') + ENV['TMP'] = ENV['TMP'] || ENV['TEMP'] || ENV['TMPDIR'] || ENV['HOME'] + case RUBY_PLATFORM + when /(mswin|bccwin|mingw|cygwin)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-mswin' + when /(linux)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-linux' + when /(darwin|rhapsody|nextstep)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-macosx' + # when /(netbsd|unix)/i then # todo + else # todo + end + ENV['TEXOS'] = "#{ENV['TEXOS'].sub(/^[\\\/]*/, '').sub(/[\\\/]*$/, '')}" + ENV['TEXPATH'] = tree.sub(/\/+$/,'') # + '/' + ENV['TEXMFOS'] = "#{ENV['TEXPATH']}/#{ENV['TEXOS']}" + report('') + report("preset : TEXPATH => #{ENV['TEXPATH']}") + report("preset : TEXOS => #{ENV['TEXOS']}") + report("preset : TEXMFOS => #{ENV['TEXMFOS']}") + report("preset : TMP => #{ENV['TMP']}") + report('') +end + +def loadfile(filename) + begin + IO.readlines(filename).each do |line| + case line.chomp + when /^[\#\%]/ then + # comment + when /^(.*?)\s*(\>|\=|\<)\s*(.*)\s*$/ then + # = assign | > prepend | < append + key, how, value = $1, $2, $3 + begin + # $SAFE = 0 + value.gsub!(/\%(.*?)\%/) do + ENV[$1] || '' + end + # value.gsub!(/\;/,$separator) if key =~ /PATH/i then + case how + when '=', '<<' then ENV[key] = value + when '?', '??' then ENV[key] = ENV[key] || value + when '<', '+=' then ENV[key] = (ENV[key] || '') + $separator + value + when '>', '=+' then ENV[key] = value + $separator + (ENV[key] ||'') + end + rescue + report("user set failed : #{key} (#{$!})") + else + report("user set : #{key} => #{ENV[key]}") + end + end + end + rescue + report("error in reading file '#{filename}'") + end +end + +def loadtree(tree) + begin + unless tree.empty? then + if File.directory?(tree) then + setuptex = File.join(tree,'setuptex.tmf') + else + setuptex = tree.dup + end + if FileTest.file?(setuptex) then + report("tex tree definition: #{setuptex}") + checkenvironment(File.dirname(setuptex)) + loadfile(setuptex) + else + report("no setup file '#{setuptex}'") + end + end + rescue + # maybe tree is empty or boolean (no arg given) + end +end + +def loadenvironment(environment) + begin + unless environment.empty? then + filename = if $path.empty? then environment else File.expand_path(File.join($path,environment)) end + if FileTest.file?(filename) then + report("environment : #{environment}") + loadfile(filename) + else + report("no environment file '#{environment}'") + end + end + rescue + report("problem while loading '#{environment}'") + end +end + +def show_environment + if $showenv then + keys = ENV.keys.sort + size = 0 + keys.each do |k| + size = k.size if k.size > size + end + report('') + keys.each do |k| + report("#{k.rjust(size)} => #{ENV[k]}") + end + report('') + end +end + +def execute(arguments) # br global + + arguments = arguments.split(/\s+/) if arguments.class == String + $directives = hashed(arguments) + + $help = $directives['help'] || false + $batch = $directives['batch'] || false + $filename = $directives['file'] || '' + $program = $directives['program'] || 'context' + $direct = $directives['direct'] || false + $edit = $directives['edit'] || false + $page = $directives['page'] || 1 + $browser = $directives['browser'] || false + $report = $directives['report'] || false + $verbose = $directives['verbose'] || false + $arguments = $directives['arguments'] || '' + $execute = $directives['execute'] || $directives['exec'] || false + $locate = $directives['locate'] || false + + $autotree = if $directives['autotree'] then (ENV['TEXMFSTART_TREE'] || ENV['TEXMFSTARTTREE'] || '') else '' end + + $path = $directives['path'] || '' + $tree = $directives['tree'] || $autotree || '' + $environment = $directives['environment'] || '' + + $make = $directives['make'] || false + $remove = $directives['remove'] || $directives['delete'] || false + $unix = $directives['unix'] || false + $windows = $directives['windows'] || $directives['mswin'] || false + $stubpath = $directives['stubpath'] || '' + $indirect = $directives['indirect'] || false + + $before = $directives['before'] || '' + $after = $directives['after'] || '' + + $iftouched = $directives['iftouched'] || false + $ifchanged = $directives['ifchanged'] || false + + $openoffice = $directives['oo'] || false + + $crossover = false if $directives['clear'] + + $showenv = $directives['showenv'] || false + $verbose = true if $showenv + + $serve = $directives['serve'] || false + + $verbose = true if (ENV['_CTX_VERBOSE_'] =~ /(y|yes|t|true|on)/io) && ! $locate && ! $report + + set_applications($page) + + # private: + + $selfmerge = $directives['selfmerge'] || false + $selfcleanup = $directives['selfclean'] || $directives['selfcleanup'] || false + + ENV['_CTX_VERBOSE_'] = 'yes' if $verbose + + if $openoffice then + if ENV['OOPATH'] then + if FileTest.directory?(ENV['OOPATH']) then + report("using open office python") + if $mswindows then + $applications['python'] = $applications['py'] = "\"#{File.join(ENV['OOPATH'],'program','python.bat')}\"" + else + $applications['python'] = $applications['py'] = File.join(ENV['OOPATH'],'python') + end + report("python path #{$applications['python']}") + else + report("environment variable 'OOPATH' does not exist") + end + else + report("environment variable 'OOPATH' is not set") + end + end + + if $selfmerge then + output("ruby libraries are cleaned up") if SelfMerge::cleanup + output("ruby libraries are merged") if SelfMerge::merge + return true + elsif $selfcleanup then + output("ruby libraries are cleaned up") if SelfMerge::cleanup + return true + elsif $help || ! $filename || $filename.empty? then + usage + loadtree($tree) + loadenvironment($environment) + show_environment() + return true + elsif $batch && $filename && ! $filename.empty? then + # todo, take commands from file and avoid multiple starts and checks + return false + else + report("texmfstart version #{$version}") + loadtree($tree) + loadenvironment($environment) + show_environment() + if $make || $remove then + if $filename == 'all' then + makelist = $makelist + else + makelist = [$filename] + end + makelist.each do |filename| + if $windows then + make(filename,true,false,$remove) + elsif $unix then + make(filename,false,true,$remove) + else + make(filename,$mswindows,!$mswindows,$remove) + end + end + return true # guess + elsif $browser && $filename =~ /^http\:\/\// then + return launch($filename) + else + begin + process do + if $direct || $filename =~ /^bin\:/ then + return direct($filename) + elsif $edit && ! $editor.empty? then + return edit($filename) + else # script: or no prefix + command = find(shortpathname($filename),$program) + if command then + register("THREAD",File.dirname(File.expand_path(command))) + return run(command) + else + report('unable to locate program') + return false + end + end + end + rescue + report('fatal error in starting process') + return false + end + end + end + +end + +if execute(ARGV) then + report("\nexecution was successful") if $verbose + exit(0) +else + report("\nexecution failed") if $verbose + exit(1) +end diff --git a/scripts/context/ruby/texsync.rb b/scripts/context/ruby/texsync.rb new file mode 100644 index 000000000..004610399 --- /dev/null +++ b/scripts/context/ruby/texsync.rb @@ -0,0 +1,206 @@ +#!/usr/bin/env ruby + +# program : texsync +# copyright : PRAGMA Advanced Document Engineering +# version : 2003-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# For the moment this script only handles the 'minimal' context +# distribution. In due time I will add a few more options, like +# synchronization of the iso image. + +# taco's sync: rsync -au -v rsync://www.pragma-ade.com/all ./htdocs + +banner = ['TeXSync', 'version 1.1.1', '2002/2004', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' +# require 'base/tool' + +require 'rbconfig' + +class Commands + + include CommandBase + + @@formats = ['en','nl','de','cz','it','ro', 'fr'] + @@always = ['metafun','mptopdf','en','nl'] + @@rsync = 'rsync -r -z -c --progress --stats "--exclude=*.fmt" "--exclude=*.efmt" "--exclude=*.mem"' + + @@kpsewhich = Hash.new + + @@kpsewhich['minimal'] = 'SELFAUTOPARENT' + @@kpsewhich['context'] = 'TEXMFLOCAL' + @@kpsewhich['documentation'] = 'TEXMFLOCAL' + @@kpsewhich['unknown'] = 'SELFAUTOPARENT' + + def update + + report + + return unless destination = getdestination + + texpaths = gettexpaths + address = option('address') + user = option('user') + tree = option('tree') + force = option('force') + + ok = true + begin + report("synchronizing '#{tree}' from '#{address}' to '#{destination}'") + report + if texpaths then + texpaths.each do |path| + report("synchronizing path '#{path}' of '#{tree}' from '#{address}' to '#{destination}'") + command = "#{rsync} #{user}@#{address}::#{tree}/#{path} #{destination}/{path}" + ok = ok && system(command) if force + end + else + command = "#{@@rsync} #{user}@#{address}::#{tree} #{destination}" + ok = system(command) if force + end + rescue + report("error in running rsync") + ok = false + ensure + if force then + if ok then + if option('make') then + report("generating tex and metapost formats") + report + @@formats.delete_if do |f| + begin + `kpsewhich cont-#{f}`.chomp.empty? + rescue + end + end + str = [@@formats,@@always].flatten.uniq.join(' ') + begin + system("texexec --make --alone #{str}") + rescue + report("unable to generate formats '#{str}'") + else + report + end + else + report("regenerate the formats files if needed") + end + else + report("error in synchronizing '#{tree}'") + end + else + report("provide --force to execute '#{command}'") unless force + end + end + + end + + def list + + report + + address = option('address') + user = option('user') + result = nil + + begin + report("fetching list of trees from '#{address}'") + command = "#{@@rsync} #{user}@#{address}::" + if option('force') then + result = `#{command}`.chomp + else + report("provide --force to execute '#{command}'") + end + rescue + result = nil + else + if result then + report("available trees:") + report + reportlines(result) + end + ensure + report("unable to fetch list") unless result + end + + end + + private + + def gettexpaths + if option('full') then + texpaths = ['texmf','texmf-local','texmf-fonts','texmf-mswin','texmf-linux','texmf-macos'] + elsif option('terse') then + texpaths = ['texmf','texmf-local','texmf-fonts'] + case Config::CONFIG['host_os'] # or: Tool.ruby_platform + when /mswin/ then texpaths.push('texmf-mswin') + when /linux/ then texpaths.push('texmf-linux') + when /darwin/ then texpaths.push('texmf-macosx') + end + else + texpaths = nil + end + texpaths + end + + def getdestination + if (destination = option('destination')) && ! destination.empty? then + begin + if @@kpsewhich.key?(destination) then + destination = @@kpsewhich[option('tree')] || @@kpsewhich['unknown'] + destination = `kpsewhich --expand-var=$#{destination}`.chomp + elsif ! FileTest.directory?(destination) then + destination = nil + end + rescue + report("unable to determine destination tex root") + else + if ! destination || destination.empty? then + report("no destination is specified") + elsif not FileTest.directory?(destination) then + report("invalid destination '#{destination}'") + elsif not FileTest.writable?(destination) then + report("destination '#{destination}' is not writable") + else + report("using destination '#{destination}'") + return destination + end + end + else + report("unknown destination") + end + return nil + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('update', 'update installed tree') +commandline.registeraction('list', 'list available trees') + +commandline.registerflag('terse', 'download as less as possible (esp binaries)') +commandline.registerflag('full', 'download everything (all binaries)') +commandline.registerflag('force', 'confirm action') +commandline.registerflag('make', 'remake formats') + +commandline.registervalue('address', 'www.pragma-ade.com', 'adress of repository (www.pragma-ade)') +commandline.registervalue('user', 'guest', 'user account (guest)') +commandline.registervalue('tree', 'tex', 'tree to synchronize (tex)') +commandline.registervalue('destination', nil, 'destination of tree (kpsewhich)') + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/ruby/textools.rb b/scripts/context/ruby/textools.rb new file mode 100644 index 000000000..a5858c5ca --- /dev/null +++ b/scripts/context/ruby/textools.rb @@ -0,0 +1,1033 @@ +#!/usr/bin/env ruby + +# program : textools +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# This script will harbor some handy manipulations on tex +# related files. + +banner = ['TeXTools', 'version 1.3.1', '2002/2006', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' + +require 'fileutils' +# require 'ftools' + +# Remark +# +# The fixtexmftrees feature does not realy belong in textools, but +# since it looks like no measures will be taken to make texlive (and +# tetex) downward compatible with respect to fonts installed by +# users, we provide this fixer. This option also moves script files +# to their new location (only for context) in the TDS. Beware: when +# locating scripts, the --format switch in kpsewhich should now use +# 'texmfscripts' instead of 'other text files' (texmfstart is already +# aware of this). Files will only be moved when --force is given. Let +# me know if more fixes need to be made. + +class Commands + + include CommandBase + + def tpmmake + if filename = @commandline.argument('first') then + filename = File.join('tpm',filename) unless filename =~ /^tpm[\/\\]/ + filename += '.tpm' unless filename =~ /\.tpm$/ + if FileTest.file?(filename) then + data = IO.read(filename) rescue '' + data, fn, n = calculate_tpm(data,"TPM:RunFiles") + data, fm, m = calculate_tpm(data,"TPM:DocFiles") + data = replace_tpm(data,"TPM:Size",n+m) + report("total size #{n+m}") + begin + File.open(filename, 'w') do |f| + f << data + end + rescue + report("unable to save '#{filename}'") + else + report("file '#{filename}' is updated") + filename = File.basename(filename).sub(/\..*$/,'') + zipname = sprintf("%s-%04i.%02i.%02i%s",filename,Time.now.year,Time.now.month,Time.now.day,'.zip') + File.delete(zipname) rescue true + report("zipping file '#{zipname}'") + system("zip -r -9 -q #{zipname} #{[fn,fm].flatten.join(' ')}") + end + else + report("no file '#{filename}'") + end + end + end + + def calculate_tpm(data, tag='') + size, ok = 0, Array.new + data.gsub!(/<#{tag}.*>(.*?)<\/#{tag}>/m) do + content = $1 + files = content.split(/\s+/) + files.each do |file| + unless file =~ /^\s*$/ then + if FileTest.file?(file) then + report("found file #{file}") + size += FileTest.size(file) rescue 0 + ok << file + else + report("missing file #{file}") + end + end + end + "<#{tag} size=\"#{size}\">#{content}" + end + [data, ok, size] + end + + def replace_tpm(data, tag='', txt='') + data.gsub(/(<#{tag}.*>)(.*?)(<\/#{tag}>)/m) do + $1 + txt.to_s + $3 + end + end + +end + +class Commands + + include CommandBase + + def hidemapnames + report('hiding FontNames in map files') + xidemapnames(true) + end + + def videmapnames + report('unhiding FontNames in map files') + xidemapnames(false) + end + + def removemapnames + + report('removing FontNames from map files') + + if files = findfiles('map') then + report + files.sort.each do |fn| + gn = fn # + '.nonames' + hn = fn + '.original' + begin + if FileTest.file?(fn) && ! FileTest.file?(hn) then + if File.rename(fn,hn) then + if (fh = File.open(hn,'r')) && (gh = File.open(gn,'w')) then + report("processing #{fn}") + while str = fh.gets do + str.sub!(/^([^\%]+?)(\s+)([^\"\<\s]*?)(\s)/) do + $1 + $2 + " "*$3.length + $4 + end + gh.puts(str) + end + fh.close + gh.close + else + report("no permissions to handle #{fn}") + end + else + report("unable to rename #{fn} to #{hn}") + end + else + report("not processing #{fn} due to presence of #{hn}") + end + rescue + report("error in handling #{fn}") + end + end + end + + end + + def restoremapnames + + report('restoring FontNames in map files') + + if files = findfiles('map') then + report + files.sort.each do |fn| + hn = fn + '.original' + begin + if FileTest.file?(hn) then + File.delete(fn) if FileTest.file?(fn) + report("#{fn} restored") if File.rename(hn,fn) + else + report("no original found for #{fn}") + end + rescue + report("error in restoring #{fn}") + end + end + end + + end + + def findfile + + report('locating file in texmf tree') + + # ! not in tree + # ? fuzzy + # . in tree + # > in tree and used + + if filename = @commandline.argument('first') then + if filename && ! filename.empty? then + report + used = kpsefile(filename) || pathfile(filename) + if paths = texmfroots then + found, prefered = false, false + paths.each do |p| + if files = texmffiles(p,filename) then + found = true + files.each do |f| + # unreadable: report("#{if f == used then '>' else '.' end} #{f}") + if f == used then + prefered = true + report("> #{f}") + else + report(". #{f}") + end + end + end + end + if prefered then + report("! #{used}") unless found + else + report("> #{used}") + end + elsif used then + report("? #{used}") + else + report('no file found') + end + else + report('no file specified') + end + else + report('no file specified') + end + + end + + def unzipfiles + + report('g-unzipping files') + + if files = findfiles('gz') then + report + files.each do |f| + begin + system("gunzip -d #{f}") + rescue + report("unable to unzip file #{f}") + else + report("file #{f} is unzipped") + end + end + end + + end + + def fixafmfiles + + report('fixing afm files') + + if files = findfiles('afm') then + report + ok = false + files.each do |filename| + if filename =~ /\.afm$/io then + if f = File.open(filename) then + result = '' + done = false + while str = f.gets do + str.chomp! + str.strip! + if str.empty? then + # skip + elsif (str.length > 200) && (str =~ /^(comment|notice)\s(.*)\s*$/io) then + done = true + tag, words, len = $1, $2.split(' '), 0 + result += tag + while words.size > 0 do + str = words.shift + len += str.length + 1 + result += ' ' + str + if len > (70 - tag.length) then + result += "\n" + result += tag if words.size > 0 + len = 0 + end + end + result += "\n" if len>0 + else + result += str + "\n" + end + end + f.close + if done then + ok = true + begin + if File.rename(filename,filename+'.original') then + if FileTest.file?(filename) then + report("something to fix in #{filename} but error in renaming (3)") + elsif f = File.open(filename,'w') then + f.puts(result) + f.close + report('file', filename, 'has been fixed') + else + report("something to fix in #{filename} but error in opening (4)") + File.rename(filename+'.original',filename) # gamble + end + else + report("something to fix in #{filename} but error in renaming (2)") + end + rescue + report("something to fix in #{filename} but error in renaming (1)") + end + else + report("nothing to fix in #{filename}") + end + else + report("error in opening #{filename}") + end + end + end + report('no files match the pattern') unless ok + end + + end + + def mactodos + + report('fixing mac newlines') + + if files = findfiles('tex') then + report + files.each do |filename| + begin + report("converting file #{filename}") + tmpfilename = filename + '.tmp' + if f = File.open(filename) then + if g = File.open(tmpfilename, 'w') + while str = f.gets do + g.puts(str.gsub(/\r/,"\n")) + end + if f.close && g.close && FileTest.file?(tmpfilename) then + File.delete(filename) + File.rename(tmpfilename,filename) + end + else + report("unable to open temporary file #{tmpfilename}") + end + else + report("unable to open #{filename}") + end + rescue + report("problems with fixing #{filename}") + end + end + end + + end + + def fixtexmftrees + + if paths = @commandline.argument('first') then + paths = [paths] if ! paths.empty? + end + paths = texmfroots if paths.empty? + + if paths then + + moved = 0 + force = @commandline.option('force') + + report + report("checking TDS 2003 => TDS 2004 : map files") + # report + + # move [map,enc] files from /texmf/[dvips,pdftex,dvipdfmx] -> /texmf/fonts/[*] + + ['map','enc'].each do |suffix| + paths.each do |path| + ['dvips','pdftex','dvipdfmx'].each do |program| + report + report("checking #{suffix} files for #{program} on #{path}") + report + moved += movefiles("#{path}/#{program}","#{path}/fonts/#{suffix}/#{program}",suffix) do + # nothing + end + end + end + end + + report + report("checking TDS 2003 => TDS 2004 : scripts") + # report + + # move [rb,pl,py] files from /texmf/someplace -> /texmf/scripts/someplace + + ['rb','pl','py'].each do |suffix| + paths.each do |path| + ['context'].each do |program| + report + report("checking #{suffix} files for #{program} on #{path}") + report + moved += movefiles("#{path}/#{program}","#{path}/scripts/#{program}",suffix) do |f| + f.gsub!(/\/(perl|ruby|python)tk\//o) do + "/#{$1}/" + end + end + end + end + end + + begin + if moved>0 then + report + if force then + system('mktexlsr') + report + report("#{moved} files moved") + else + report("#{moved} files will be moved") + end + else + report('no files need to be moved') + end + rescue + report('you need to run mktexlsr') + end + + end + + end + + def replacefile + + report('replace file') + + if newname = @commandline.argument('first') then + if newname && ! newname.empty? then + report + report("replacing #{newname}") + report + oldname = kpsefile(File.basename(newname)) + force = @commandline.option('force') + if oldname && ! oldname.empty? then + oldname = File.expand_path(oldname) + newname = File.expand_path(newname) + report("old: #{oldname}") + report("new: #{newname}") + report + if newname == oldname then + report('unable to replace itself') + elsif force then + begin + File.copy(newname,oldname) + rescue + report('error in replacing the old file') + end + else + report('the old file will be replaced (use --force)') + end + else + report('nothing to replace') + end + else + report('no file specified') + end + else + report('no file specified') + end + + end + + private # general + + def texmfroots + begin + paths = `kpsewhich -expand-path=\$TEXMF`.chomp + rescue + else + return paths.split(/#{File::PATH_SEPARATOR}/) if paths && ! paths.empty? + end + return nil + end + + def texmffiles(root, filename) + begin + files = Dir.glob("#{root}/**/#{filename}") + rescue + else + return files if files && files.length>0 + end + return nil + end + + def pathfile(filename) + used = nil + begin + if ! filename || filename.empty? then + return nil + else + ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| + if FileTest.file?(File.join(path,filename)) then + used = File.join(path,filename) + break + end + end + end + rescue + used = nil + else + used = nil if used && used.empty? + end + return used + end + + def kpsefile(filename) + used = nil + begin + if ! filename || filename.empty? then + return nil + else + used = `kpsewhich #{filename}`.chomp + end + if used && used.empty? then + used = `kpsewhich -progname=context #{filename}`.chomp + end + if used && used.empty? then + used = `kpsewhich -format=texmfscripts #{filename}`.chomp + end + if used && used.empty? then + used = `kpsewhich -progname=context -format=texmfscripts #{filename}`.chomp + end + if used && used.empty? then + used = `kpsewhich -format="other text files" #{filename}`.chomp + end + if used && used.empty? then + used = `kpsewhich -progname=context -format="other text files" #{filename}`.chomp + end + rescue + used = nil + else + used = nil if used && used.empty? + end + return used + end + + def downcasefilenames + + report('downcase filenames') + + force = @commandline.option('force') + + # if @commandline.option('recurse') then + # files = Dir.glob('**/*') + # else + # files = Dir.glob('*') + # end + # if files && files.length>0 then + + if files = findfiles() then + files.each do |oldname| + if FileTest.file?(oldname) then + newname = oldname.downcase + if oldname != newname then + if force then + begin + File.rename(oldname,newname) + rescue + report("#{oldname} == #{oldname}\n") + else + report("#{oldname} => #{newname}\n") + end + else + report("(#{oldname} => #{newname})\n") + end + end + end + end + end + end + + def stripformfeeds + + report('strip formfeeds') + + force = @commandline.option('force') + + if files = findfiles() then + files.each do |filename| + if FileTest.file?(filename) then + begin + data = IO.readlines(filename).join('') + rescue + else + if data.gsub!(/\n*\f\n*/io,"\n\n") then + if force then + if f = open(filename,'w') then + report("#{filename} is stripped\n") + f.puts(data) + f.close + else + report("#{filename} cannot be stripped\n") + end + else + report("#{filename} will be stripped\n") + end + end + end + end + end + end + end + + public + + def showfont + + file = @commandline.argument('first') + + if file.empty? then + report('provide filename') + else + file.sub!(/\.afm$/,'') + begin + report("analyzing afm file #{file}.afm") + file = `kpsewhich #{file}.afm`.chomp + rescue + report('unable to run kpsewhich') + return + end + + names = Array.new + + if FileTest.file?(file) then + File.new(file).each do |line| + if line.match(/^C\s*([\-\d]+)\s*\;.*?\s*N\s*(.+?)\s*\;/o) then + names.push($2) + end + end + ranges = names.size + report("number of glyphs: #{ranges}") + ranges = ranges/256 + 1 + report("number of subsets: #{ranges}") + file = File.basename(file).sub(/\.afm$/,'') + tex = File.open("textools.tex",'w') + map = File.open("textools.map",'w') + tex.puts("\\starttext\n") + tex.puts("\\loadmapfile[textools.map]\n") + for i in 1..ranges do + rfile = "#{file}-range-#{i}" + report("generating enc file #{rfile}.enc") + flushencoding("#{rfile}", (i-1)*256, i*256-1, names) + # catch console output + report("generating tfm file #{rfile}.tfm") + mapline = `afm2tfm #{file}.afm -T #{rfile}.enc #{rfile}.tfm` + # more robust replacement + mapline = "#{rfile} <#{rfile}.enc <#{file}.pfb" + # final entry in map file + mapline = "#{mapline} <#{file}.pfb" + map.puts("#{mapline}\n") + tex.puts("\\showfont[#{rfile}][unknown]\n") + end + tex.puts("\\stoptext\n") + report("generating map file textools.map") + report("generating tex file textools.tex") + map.close + tex.close + else + report("invalid file #{file}") + end + end + + end + + @@knownchars = Hash.new + + @@knownchars['ae'] = 'aeligature' ; @@knownchars['oe'] = 'oeligature' + @@knownchars['AE'] = 'AEligature' ; @@knownchars['OE'] = 'OEligature' + + @@knownchars['acute' ] = 'textacute' + @@knownchars['breve' ] = 'textbreve' + @@knownchars['caron' ] = 'textcaron' + @@knownchars['cedilla' ] = 'textcedilla' + @@knownchars['circumflex' ] = 'textcircumflex' + @@knownchars['diaeresis' ] = 'textdiaeresis' + @@knownchars['dotaccent' ] = 'textdotaccent' + @@knownchars['grave' ] = 'textgrave' + @@knownchars['hungarumlaut'] = 'texthungarumlaut' + @@knownchars['macron' ] = 'textmacron' + @@knownchars['ogonek' ] = 'textogonek' + @@knownchars['ring' ] = 'textring' + @@knownchars['tilde' ] = 'texttilde' + + @@knownchars['cent' ] = 'textcent' + @@knownchars['currency'] = 'textcurrency' + @@knownchars['euro' ] = 'texteuro' + @@knownchars['florin' ] = 'textflorin' + @@knownchars['sterling'] = 'textsterling' + @@knownchars['yen' ] = 'textyen' + + @@knownchars['brokenbar'] = 'textbrokenbar' + @@knownchars['bullet' ] = 'textbullet' + @@knownchars['dag' ] = 'textdag' + @@knownchars['ddag' ] = 'textddag' + @@knownchars['degree' ] = 'textdegree' + @@knownchars['div' ] = 'textdiv' + @@knownchars['ellipsis' ] = 'textellipsis' + @@knownchars['fraction' ] = 'textfraction' + @@knownchars['lognot' ] = 'textlognot' + @@knownchars['minus' ] = 'textminus' + @@knownchars['mu' ] = 'textmu' + @@knownchars['multiply' ] = 'textmultiply' + @@knownchars['pm' ] = 'textpm' + + def encmake + afmfile = @commandline.argument('first') + encoding = @commandline.argument('second') || 'dummy' + if afmfile && FileTest.file?(afmfile) then + chars = Array.new + IO.readlines(afmfile).each do |line| + if line =~ /C\s+(\d+).*?N\s+([a-zA-Z\-\.]+?)\s*;/ then + chars[$1.to_i] = $2 + end + end + if f = File.open(encoding+'.enc','w') then + f << "% Encoding file, generated by textools.rb from #{afmfile}\n" + f << "\n" + f << "/#{encoding.gsub(/[^a-zA-Z]/,'')}encoding [\n" + 256.times do |i| + f << " /#{chars[i] || '.notdef'} % #{i}\n" + end + f << "] def\n" + f.close + end + if f = File.open('enco-'+encoding+'.tex','w') then + f << "% ConTeXt file, generated by textools.rb from #{afmfile}\n" + f << "\n" + f << "\\startencoding[#{encoding}]\n\n" + 256.times do |i| + if str = chars[i] then + tmp = str.gsub(/dieresis/,'diaeresis') + if chr = @@knownchars[tmp] then + f << " \\definecharacter #{chr} #{i}\n" + elsif tmp.length > 5 then + f << " \\definecharacter #{tmp} #{i}\n" + end + end + end + f << "\n\\stopencoding\n" + f << "\n\\endinput\n" + f.close + end + end + end + + private + + def flushencoding (file, from, to, names) + n = 0 + out = File.open("#{file}.enc",'w') + out.puts("/#{file.gsub(/\-/,'')} [\n") + for i in from..to do + if names[i] then + n += 1 + out.puts("/#{names[i]}\n") + else + out.puts("/.notdef\n") + end + end + out.puts("] def\n") + out.close + return n + end + + private # specific + + def movefiles(from_path,to_path,suffix,&block) + obsolete = 'obsolete' + force = @commandline.option('force') + moved = 0 + if files = texmffiles(from_path, "*.#{suffix}") then + files.each do |filename| + newfilename = filename.sub(/^#{from_path}/, to_path) + yield(newfilename) if block + if FileTest.file?(newfilename) then + begin + File.rename(filename,filename+'.obsolete') if force + rescue + report("#{filename} cannot be made obsolete") if force + else + if force then + report("#{filename} is made obsolete") + else + report("#{filename} will become obsolete") + end + end + else + begin + File.makedirs(File.dirname(newfilename)) if force + rescue + end + begin + File.copy(filename,newfilename) if force + rescue + report("#{filename} cannot be copied to #{newfilename}") + else + begin + File.delete(filename) if force + rescue + report("#{filename} cannot be deleted") if force + else + if force then + report("#{filename} is moved to #{newfilename}") + moved += 1 + else + report("#{filename} will be moved to #{newfilename}") + end + end + end + end + end + else + report('no matches found') + end + return moved + end + + def xidemapnames(hide) + + filter = /^([^\%]+?)(\s+)([^\"\<\s]*?)(\s)/ + banner = '% textools:nn ' + + if files = findfiles('map') then + report + files.sort.each do |fn| + if fn.has_suffix?('map') then + begin + lines = IO.read(fn) + report("processing #{fn}") + if f = File.open(fn,'w') then + skip = false + if hide then + lines.each do |str| + if skip then + skip = false + elsif str =~ /#{banner}/ then + skip = true + elsif str =~ filter then + f.puts(banner+str) + str.sub!(filter) do + $1 + $2 + " "*$3.length + $4 + end + end + f.puts(str) + end + else + lines.each do |str| + if skip then + skip = false + elsif str.sub!(/#{banner}/, '') then + f.puts(str) + skip = true + else + f.puts(str) + end + end + end + f.close + end + rescue + report("error in handling #{fn}") + end + end + end + end + + end + + public + + def updatetree + + nocheck = @commandline.option('nocheck') + merge = @commandline.option('merge') + delete = @commandline.option('delete') + force = @commandline.option('force') + root = @commandline.argument('first').gsub(/\\/,'/') + path = @commandline.argument('second').gsub(/\\/,'/') + + if FileTest.directory?(root) then + report("scanning #{root}") + rootfiles = Dir.glob("#{root}/**/*") + else + report("provide source root") + return + end + if rootfiles.size > 0 then + report("#{rootfiles.size} files") + else + report("no files") + return + end + rootfiles.collect! do |rf| + rf.gsub(/\\/o, '/').sub(/#{root}\//o, '') + end + rootfiles = rootfiles.delete_if do |rf| + FileTest.directory?(File.join(root,rf)) + end + + if FileTest.directory?(path) then + report("scanning #{path}") + pathfiles = Dir.glob("#{path}/**/*") + else + report("provide destination root") + return + end + if pathfiles.size > 0 then + report("#{pathfiles.size} files") + else + report("no files") + return + end + pathfiles.collect! do |pf| + pf.gsub(/\\/o, '/').sub(/#{path}\//o, '') + end + pathfiles = pathfiles.delete_if do |pf| + FileTest.directory?(File.join(path,pf)) + end + + root = File.expand_path(root) + path = File.expand_path(path) + + donepaths = Hash.new + copiedfiles = Hash.new + + # update existing files, assume similar paths + + report("") + pathfiles.each do |f| # destination + p = File.join(path,f) + if rootfiles.include?(f) then + r = File.join(root,f) + if p != r then + if nocheck or File.mtime(p) < File.mtime(r) then + copiedfiles[File.expand_path(p)] = true + report("updating '#{r}' to '#{p}'") + begin + begin File.makedirs(File.dirname(p)) if force ; rescue ; end + File.copy(r,p) if force + rescue + report("updating failed") + end + else + report("not updating '#{r}'") + end + end + end + end + + # merging non existing files + + report("") + rootfiles.each do |f| + donepaths[File.dirname(f)] = true + r = File.join(root,f) + if not pathfiles.include?(f) then + p = File.join(path,f) + if p != r then + if merge then + copiedfiles[File.expand_path(p)] = true + report("merging '#{r}' to '#{p}'") + begin + begin File.makedirs(File.dirname(p)) if force ; rescue ; end + File.copy(r,p) if force + rescue + report("merging failed") + end + else + report("not merging '#{r}'") + end + end + end + end + + # deleting obsolete files + + report("") + donepaths.keys.sort.each do |d| + pathfiles = Dir.glob("#{path}/#{d}/**/*") + pathfiles.each do |p| +# puts(File.dirname(p)) +# if donepaths[File.dirname(p)] then + r = File.join(root,d,File.basename(p)) + if FileTest.file?(p) and not FileTest.file?(r) and not copiedfiles.key?(File.expand_path(p)) then + if delete then + report("deleting '#{p}'") + begin + File.delete(p) if force + rescue + report("deleting failed") + end + else + report("not deleting '#{p}'") + end + end + end +# end + end + + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('removemapnames' , '[pattern] [--recurse]') +commandline.registeraction('restoremapnames' , '[pattern] [--recurse]') +commandline.registeraction('hidemapnames' , '[pattern] [--recurse]') +commandline.registeraction('videmapnames' , '[pattern] [--recurse]') +commandline.registeraction('findfile' , 'filename [--recurse]') +commandline.registeraction('unzipfiles' , '[pattern] [--recurse]') +commandline.registeraction('fixafmfiles' , '[pattern] [--recurse]') +commandline.registeraction('mactodos' , '[pattern] [--recurse]') +commandline.registeraction('fixtexmftrees' , '[texmfroot] [--force]') +commandline.registeraction('replacefile' , 'filename [--force]') +commandline.registeraction('updatetree' , 'fromroot toroot [--force --nocheck --merge --delete]') +commandline.registeraction('downcasefilenames', '[--recurse] [--force]') # not yet documented +commandline.registeraction('stripformfeeds' , '[--recurse] [--force]') # not yet documented +commandline.registeraction('showfont' , 'filename') +commandline.registeraction('encmake' , 'afmfile encodingname') + +commandline.registeraction('tpmmake' , 'tpm file (run in texmf root)') + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registerflag('recurse') +commandline.registerflag('force') +commandline.registerflag('merge') +commandline.registerflag('delete') +commandline.registerflag('nocheck') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/ruby/texutil.rb b/scripts/context/ruby/texutil.rb new file mode 100644 index 000000000..ee0fc1e5e --- /dev/null +++ b/scripts/context/ruby/texutil.rb @@ -0,0 +1,93 @@ +banner = ['TeXUtil ', 'version 9.1.0', '1997-2005', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' +require 'base/file' +require 'base/texutil' + +class Commands + + include CommandBase + + def references + filename = @commandline.argument('first') + if not filename.empty? and FileTest.file?(File.suffixed(filename,'tuo')) then + if tu = TeXUtil::Converter.new(logger) and tu.loaded(filename) then + tu.saved if tu.processed + end + end + end + + def main + if @commandline.arguments.length>0 then + references + else + help + end + end + + def purgefiles + system("texmfstart ctxtools --purge #{@commandline.arguments.join(' ')}") + end + + def purgeallfiles + system("texmfstart ctxtools --purge --all #{@commandline.arguments.join(' ')}") + end + + def documentation + system("texmfstart ctxtools --document #{@commandline.arguments.join(' ')}") + end + + def analyzefile + system("texmfstart pdftools --analyze #{@commandline.arguments.join(' ')}") + end + + def filterpages # obsolete + system("texmfstart ctxtools --purge #{@commandline.arguments.join(' ')}") + end + + def figures + report("this code is not yet converted from perl to ruby") + end + + def logfile + report("this code is not yet converted from perl to ruby") + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +# main feature + +commandline.registeraction('references', 'convert tui file into tuo file') + +# todo features + +commandline.registeraction('figures', 'generate figure dimensions file') +commandline.registeraction('logfile', 'filter essential log messages') + +# backward compatibility features + +commandline.registeraction('purgefiles', 'remove most temporary files') +commandline.registeraction('purgeallfiles', 'remove all temporary files') +commandline.registeraction('documentation', 'generate documentation file from source') +commandline.registeraction('analyzefile', 'analyze pdf file') + +# old feature, not needed any longer due to extension of pdftex + +commandline.registeraction('filterpages') + +# generic features + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registerflag('verbose') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'main') diff --git a/scripts/context/ruby/tmftools.rb b/scripts/context/ruby/tmftools.rb new file mode 100644 index 000000000..626ef1f4a --- /dev/null +++ b/scripts/context/ruby/tmftools.rb @@ -0,0 +1,165 @@ +#!/usr/bin/env ruby + +# program : tmftools +# copyright : PRAGMA Advanced Document Engineering +# version : 2005 +# author : Hans Hagen +# +# project : ConTeXt +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# The script based alternative is not slower than the kpse one. +# Loading is a bit faster when the log file is used. + +# todo: create database + +# tmftools [some of the kpsewhich switches] + +# tmftools --analyze +# tmftools --analyze > kpsewhat.log +# tmftools --analyze --strict > kpsewhat.log +# tmftools --analyze --delete --force "texmf-local/fonts/.*/somename" +# tmftools --serve + +# the real thing + +banner = ['TMFTools', 'version 1.1.0 (experimental, no help yet)', '2005/2006', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' + +class Commands + + include CommandBase + + def init_kpse + # require 'base/kpseremote' + # if KpseRemote::available? then + if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then + require 'base/kpseremote' + k = KpseRemote.new + else + k = nil + end + if k && k.okay? then + k.progname = @commandline.option('progname') + k.engine = @commandline.option('engine') + k.format = @commandline.option('format') + else + require 'base/kpsefast' + k = KpseFast.new + k.rootpath = @commandline.option('rootpath') + k.treepath = @commandline.option('treepath') + k.progname = @commandline.option('progname') + k.engine = @commandline.option('engine') + k.format = @commandline.option('format') + k.diskcache = @commandline.option('diskcache') + k.renewcache = @commandline.option('renewcache') + k.load_cnf + k.expand_variables + k.load_lsr + end + return k + end + + def serve + if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then + require 'base/kpseremote' + begin + KpseRemote::start_server + rescue + end + end + end + + def reload + begin + init_kpse.load + rescue + end + end + + def main + if option = @commandline.option('expand-braces') and not option.empty? then + puts init_kpse.expand_braces(option) + elsif option = @commandline.option('expand-path') and not option.empty? then + puts init_kpse.expand_path(option) + elsif option = @commandline.option('expand-var') and not option.empty? then + if option == '*' then + init_kpse.list_expansions() + else + puts init_kpse.expand_var(option) + end + elsif option = @commandline.option('show-path') and not option.empty? then + puts init_kpse.show_path(option) + elsif option = @commandline.option('var-value') and not option.empty? then + if option == '*' then + init_kpse.list_variables() + else + puts init_kpse.expand_var(option) + end + elsif @commandline.arguments.size > 0 then + kpse = init_kpse + @commandline.arguments.each do |option| + puts kpse.find_file(option) + end + else + help + end + end + + def analyze + pattern = @commandline.argument('first') + strict = @commandline.option('strict') + sort = @commandline.option('sort') + delete = @commandline.option('delete') and @commandline.option('force') + init_kpse.analyze_files(pattern, strict, sort, delete) + end + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +# kpsewhich compatible options + +commandline.registervalue('expand-braces','') +commandline.registervalue('expand-path','') +commandline.registervalue('expand-var','') +commandline.registervalue('show-path','') +commandline.registervalue('var-value','') + +commandline.registervalue('engine','') +commandline.registervalue('progname','') +commandline.registervalue('format','') + +# additional goodies + +commandline.registervalue('rootpath','') +commandline.registervalue('treepath','') +commandline.registervalue('sort','') + +commandline.registerflag('diskcache') +commandline.registerflag('renewcache') +commandline.registerflag('strict') +commandline.registerflag('delete') +commandline.registerflag('force') + +commandline.registeraction('analyze', "[--strict --sort --rootpath --treepath]\n[--delete [--force]] [pattern]") + +# general purpose options + +commandline.registerflag('verbose') +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registeraction('reload', 'reload file database') +commandline.registeraction('serve', 'act as kpse server') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'main') diff --git a/scripts/context/ruby/xmltools.rb b/scripts/context/ruby/xmltools.rb new file mode 100644 index 000000000..c28df200d --- /dev/null +++ b/scripts/context/ruby/xmltools.rb @@ -0,0 +1,656 @@ +#!/usr/bin/env ruby + +# program : xmltools +# copyright : PRAGMA Advanced Document Engineering +# version : 2002-2005 +# author : Hans Hagen +# +# project : ConTeXt / eXaMpLe +# concept : Hans Hagen +# info : j.hagen@xs4all.nl +# www : www.pragma-ade.com + +# todo : use kpse lib + +# This script will harbor some handy manipulations on tex +# related files. + +banner = ['XMLTools', 'version 1.2.2', '2002/2007', 'PRAGMA ADE/POD'] + +$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! + +require 'base/switch' +require 'base/logger' + +class String + + def astring(n=10) + gsub(/(\d+)/o) do $1.to_s.rjust(n) end.gsub(/ /o, '0') + end + + def xstring + if self =~ /\'/o then + "\"#{self.gsub(/\"/, '"')}\"" + else + "\'#{self}\'" + end + end + +end + +class Array + + def asort(n=10) + sort {|x,y| x.astring(n) <=> y.astring(n)} + end + +end + +class Commands + + include CommandBase + + def dir + + @xmlns = "xmlns='http://www.pragma-ade.com/rlg/xmldir.rng'" + + pattern = @commandline.option('pattern') + recurse = @commandline.option('recurse') + stripname = @commandline.option('stripname') + longname = @commandline.option('longname') + url = @commandline.option('url') + outputfile = @commandline.option('output') + root = @commandline.option('root') + + def generate(output,files,url,root,longname) + + class << output + def xputs(str,n=0) + puts("#{' '*n}#{str}") + end + end + + dirname = '' + output.xputs("\n\n") + if ! root || root.empty? then + rootatt = @xmlns + else + rootatt = " #{@xmlns} root='#{root}'" + end + rootatt += " timestamp='#{Time.now}'" + if url.empty? then + output.xputs("\n") + else + output.xputs("\n") + end + files.each do |f| + bn, dn = File.basename(f), File.dirname(f) + if dirname != dn then + output.xputs("\n", 2) if dirname != '' + output.xputs("\n", 2) + dirname = dn + end + if longname && dn != '.' then + output.xputs("\n", 4) + else + output.xputs("\n", 4) + end + output.xputs("#{bn.sub(/\..*$/,'')}\n", 6) + if File.stat(f).file? then + bt = bn.sub(/^.*\./,'') + if bt != bn then + output.xputs("#{bt}\n", 6) + end + output.xputs("#{File.stat(f).size}\n", 6) + permissions = '' + permissions << 'r' if File.readable?(f) + permissions << 'w' if File.writable?(f) + permissions << 'x' if File.executable?(f) + output.xputs("#{permissions}\n", 6) unless permissions.empty? + end + output.xputs("#{File.stat(f).mtime.strftime("%Y-%m-%d %H:%M")}\n", 6) + output.xputs("\n", 4) + end + output.xputs("\n", 2) if dirname != '' + output.xputs("\n") + + end + + if pattern.empty? then + report('provide --pattern=') + return + end + + unless outputfile.empty? then + begin + output = File.open(outputfile,'w') + rescue + report("unable to open #{outputfile}") + return + end + else + report('provide --output') + return + end + + if stripname && pattern.class == String && ! pattern.empty? then + pattern = File.dirname(pattern) + end + + pattern = '*' if pattern.empty? + + unless root.empty? then + unless FileTest.directory?(root) then + report("unknown root #{root}") + return + end + begin + Dir.chdir(root) + rescue + report("unable to change to root #{root}") + return + end + end + + generate(output, globbed(pattern, recurse), url, root, longname) + + output.close if output + + end + + alias ls :dir + + def mmlpages + + file = @commandline.argument('first') + eps = @commandline.option('eps') + jpg = @commandline.option('jpg') + png = @commandline.option('png') + style = @commandline.option('style') + modes = @commandline.option('modes') + + file = file.sub(/\.xml/io, '') + long = "#{file}-mmlpages" + if FileTest.file?(file+'.xml') then + style = "--arg=\"style=#{style}\"" unless style.empty? + modes = "--mode=#{modes}" unless modes.empty? + if system("texmfstart texexec --batch --pdf --once --result=#{long} --use=mmlpag #{style} #{modes} #{file}.xml") then + if eps then + if f = open("#{file}-mmlpages.txt") then + while line = f.gets do + data = Hash.new + if fields = line.split then + fields.each do |fld| + key, value = fld.split('=') + data[key] = value if key && value + end + if data.key?('p') then + page = data['p'] + name = "#{long}-#{page.to_i-1}" + if eps then + report("generating eps file #{name}") + if system("pdftops -eps -f #{page} -l #{page} #{long}.pdf #{name}.eps") then + if data.key?('d') then + if epsfile = IO.read("#{name}.eps") then + epsfile.sub!(/^(\%\%BoundingBox:.*?$)/i) do + newline = $1 + "\n%%Baseline: #{data['d']}\n" + if data.key?('w') && data.key?('h') then + newline += "%%PositionWidth: #{data['w']}\n" + newline += "%%PositionHeight: #{data['h']}\n" + newline += "%%PositionDepth: #{data['d']}" + end + newline + end + if g = File.open("#{name}.eps",'wb') then + g.write(epsfile) + g.close + end + end + end + else + report("error in generating eps from #{name}") + end + end + end + end + end + f.close + else + report("missing data log file #{file}") + end + end + if png then + report("generating png file for #{long}") + system("imagemagick #{long}.pdf #{long}-%d.png") + end + if jpg then + report("generating jpg files for #{long}") + system("imagemagick #{long}.pdf #{long}-%d.jpg") + end + else + report("error in processing file #{file}") + end + system("texmfstart ctxtools --purge") + else + report("error in processing file #{file}") + end + + end + + def analyze + + file = @commandline.argument('first') + result = @commandline.option('output') + utf = @commandline.option('utf') + process = @commandline.option('process') + + if FileTest.file?(file) then + if data = IO.read(file) then + if data =~ /\s\/\!\?]+)([^>]*?)>/o) do + element, attributelist = $1, $2 + if elements.key?(element) then + elements[element] += 1 + else + elements[element] = 1 + end + attributelist.scan(/\s*([^\=]+)\=([\"\'])(.*?)(\2)/) do + key, value = $1, $3 + attributes[element] = Hash.new unless attributes.key?(element) + attributes[element][key] = Hash.new unless attributes[element].key?(key) + if attributes[element][key].key?(value) then + attributes[element][key][value] += 1 + else + attributes[element][key][value] = 1 + end + end + end + data.scan(/\&([^\;]+)\;/o) do + entity = $1 + if entities.key?(entity) then + entities[entity] += 1 + else + entities[entity] = 1 + end + end + if utf then + data.scan(/(\w)/u) do + chars[$1] = (chars[$1] || 0) + 1 + end + if chars.size > 0 then + begin + # todo : use kpse lib + filename, ownpath, foundpath = 'contextnames.txt', File.dirname($0), '' + begin + foundpath = File.dirname(`kpsewhich -progname=context -format=\"other text files\" #{filename}`.chomp) + rescue + foundpath = '.' + else + foundpath = '.' if foundpath.empty? + end + [foundpath,ownpath,File.join(ownpath,'../../../context/data')].each do |path| + fullname = File.join(path,filename) + if FileTest.file?(fullname) then + report("loading '#{fullname}'") + # rough scan, we assume no valid lines after comments + IO.read(fullname).scan(/^([0-9A-F][0-9A-F][0-9A-F][0-9A-F])\s*\;\s*(.*?)\s*\;\s*(.*?)\s*\;\s*(.*?)\s*$/) do + names[$1.hex.to_i.to_s] = [$2,$3,$4] + end + break + end + end + rescue + end + end + end + result = file.gsub(/\..*?$/, '') + '.xlg' if result.empty? + if f = File.open(result,'w') then + report("saving report in #{result}") + f.puts "\n" + f.puts "\n" + if entities.length>0 then + total = 0 + entities.each do |k,v| + total += v + end + f.puts " \n" + entities.keys.asort.each do |entity| + f.puts " \n" + end + f.puts " \n" + end + if utf && (chars.size > 0) then + total = 0 + chars.each do |k,v| + total += v + end + f.puts " \n" + chars.each do |k,v| + if k.length > 1 then + begin + u = k.unpack('U') + unicodes[u] = (unicodes[u] || 0) + v + rescue + report("invalid utf codes") + end + end + end + unicodes.keys.sort.each do |u| + ustr = u.to_s + if names[ustr] then + f.puts " \n" + else + f.puts " \n" + end + end + f.puts " \n" + end + if elements.length>0 then + f.puts " \n" + elements.keys.sort.each do |element| + if attributes.key?(element) then + f.puts " \n" + if attributes.key?(element) then + attributes[element].keys.asort.each do |attribute| + f.puts " \n" + if attribute =~ /id$/o then + nn = 0 + attributes[element][attribute].keys.asort.each do |value| + nn += attributes[element][attribute][value].to_i + end + f.puts " \n" + else + attributes[element][attribute].keys.asort.each do |value| + f.puts " \n" + end + end + f.puts " \n" + end + end + f.puts " \n" + else + f.puts " \n" + end + end + f.puts " \n" + end + f.puts "\n" + f.close + if process then + system("texmfstart texexec --purge --pdf --use=xml-analyze #{result}") + end + else + report("unable to open file '#{result}'") + end + else + report("invalid xml file '#{file}'") + end + else + report("unable to load file '#{file}'") + end + else + report("unknown file '#{file}'") + end + end + + def filter + + require "rexml/document" + + element = @commandline.option('element') + files = @commandline.arguments + result = "xmltools.xlg" + + if element.empty? then + report("provide element using --element") + elsif files.length == 0 then + report("provide filename(s)") + else + begin + File.open(result,'w') do |f| + f << "\n\n" + f << "\n\n" + total = 0 + files.sort.each do |file| + begin + report("loading: #{file}") + data = REXML::Document.new(IO.read(file)) + rescue + report("error: invalid xml") + else + found = 0 + report("filtering: #{element}") + REXML::XPath.each(data,"//#{element}") do |table| + str = table.to_s + if str.length > 0 then + total += 1 + found += 1 + report("found: #{total} / #{found} / #{str.length} bytes") + f << "\n\n" unless found > 1 + f << "" + f << "#{str.gsub(/^\s*/m,'').gsub(/\s*$/m,'')}" + f << "\n\n" + end + end + f << "\n\n" if found > 0 + end + end + f << "\n" + end + report("result: #{result}") + rescue + report("error in opening #{result}") + end + end + + end + + def enhance + oldname = @commandline.argument('first') + newname = @commandline.argument('second') + verbose = @commandline.option('verbose') + # todo: options, maybe a config file + if ! newname || newname.empty? then + newname = oldname + ".prep" + end + if FileTest.file?(oldname) then + report("") if verbose + data = IO.read(oldname) + elements = Array.new + preamble = "" + done = false + data.sub!(/^(.*?)\s*(<[a-z])/moi) do + preamble = $1 + $2 + end + # hide elements + data.gsub!(/<([^>]*?)>/moi) do + elements << $1 + "<#{elements.length}>" + end + # abc[-/]def + data.gsub!(/([a-z]{3,})([\/\-\(\)]+)([a-z]{3,})/moi) do + done = true + report("compound: #{$1}#{$2}#{$3}") if verbose + "#{$1}#{$3}" + end + # (abcd + # data.gsub!(/(\()([a-z]{4,})/moi) do + # done = true + # report("compound: #{$1}#{$2}") if verbose + # "#{$2}" + # end + # abcd) + # data.gsub!(/(\()([a-z]{4,})/moi) do + # done = true + # report("compound: #{$1}#{$2}") if verbose + # "#{$2}" + # end + # roll back elements + data.gsub!(/<(\d+)>/moi) do + "<#{elements.shift}>" + end + File.open(newname,'wb') do |f| + f << preamble + f << "\n" + f << data + end + if verbose then + if done then + report("") + report(oldname," converted to ",newname) + else + report(oldname," copied to ",newname) + end + end + end + end + + def cleanup # todo, share loading/saving with previous + + file = @commandline.argument('first') + force = @commandline.option('force') + verbose = @commandline.option('verbose') + + if FileTest.file?(file) then + if data = IO.read(file) then + if data =~ /" + + data.gsub!(/\<(\/*\w+)\s*(\/*)>/o) do + "<#{$1}#{$2}>" + end + + # remove funny ampersands + # + # data = " B&W " + + data.gsub!(/\&([^\<\>\&]*?)\;/mo) do + "" + end + data.gsub!(/\&/o) do + doxmlreport("&",verbose) + end + data.gsub!(/\/o) do + doxmlreport("&#{$1};",verbose) + end + + # remove funny < > + # + # data = " < 5% " + + data.gsub!(/<([^>].*?)>/o) do + tag = $1 + case tag + when /^\//o then + "<#{tag}>" # funny tag but ok + when /\/$/o then + "<#{tag}>" # funny tag but ok + when /",verbose) + else + "<#{tag}>" + end + end + + # remove funny < > + # + # data = " > 5% " + + data.gsub!(/<([^>].*?)>([^\>\<]*?)>/o) do + doxmlreport("<#{$1}>#{$2}>",verbose) + end + + return data + end + + # puts doxmlcleanup("") + # puts doxmlcleanup(" B&W ") + # puts doxmlcleanup(" < 5% ") + # puts doxmlcleanup(" > 5% ") + +end + +logger = Logger.new(banner.shift) +commandline = CommandLine.new + +commandline.registeraction('dir', 'generate directory listing') +commandline.registeraction('mmlpages','generate graphic from mathml') +commandline.registeraction('analyze', 'report entities and elements [--utf --process]') +commandline.registeraction('cleanup', 'cleanup xml file [--force]') +commandline.registeraction('enhance', 'enhance xml file (partial)') +commandline.registeraction('filter', 'filter elements from xml file [element=]') + +# commandline.registeraction('dir', 'filename --pattern= --output= [--recurse --stripname --longname --url --root]') +# commandline.registeraction('mmlpages','filename [--eps --jpg --png --style= --mode=]') + +commandline.registeraction('ls') + +commandline.registeraction('help') +commandline.registeraction('version') + +commandline.registerflag('stripname') +commandline.registerflag('longname') +commandline.registerflag('recurse') +commandline.registerflag('verbose') + +commandline.registervalue('pattern') +commandline.registervalue('element') +commandline.registervalue('url') +commandline.registervalue('output') +commandline.registervalue('root') + +commandline.registerflag('eps') +commandline.registerflag('png') +commandline.registerflag('jpg') +commandline.registerflag('utf') +commandline.registerflag('process') +commandline.registervalue('style') +commandline.registervalue('modes') + +commandline.expand + +Commands.new(commandline,logger,banner).send(commandline.action || 'help') diff --git a/scripts/context/stubs/mswin/context.exe b/scripts/context/stubs/mswin/context.exe new file mode 100644 index 000000000..2d45f2749 Binary files /dev/null and b/scripts/context/stubs/mswin/context.exe differ diff --git a/scripts/context/stubs/mswin/luatools.exe b/scripts/context/stubs/mswin/luatools.exe new file mode 100644 index 000000000..2d45f2749 Binary files /dev/null and b/scripts/context/stubs/mswin/luatools.exe differ diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua new file mode 100644 index 000000000..1d87322c1 --- /dev/null +++ b/scripts/context/stubs/mswin/luatools.lua @@ -0,0 +1,8185 @@ +#!/usr/bin/env texlua + +if not modules then modules = { } end modules ['luatools'] = { + version = 1.001, + comment = "companion to context.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +-- one can make a stub: +-- +-- #!/bin/sh +-- env LUATEXDIR=/....../texmf/scripts/context/lua texlua luatools.lua "$@" + +-- Although this script is part of the ConTeXt distribution it is +-- relatively indepent of ConTeXt. The same is true for some of +-- the luat files. We may may make them even less dependent in +-- the future. As long as Luatex is under development the +-- interfaces and names of functions may change. + +-- For the sake of independence we optionally can merge the library +-- code here. It's too much code, but that does not harm. Much of the +-- library code is used elsewhere. We don't want dependencies on +-- Lua library paths simply because these scripts are located in the +-- texmf tree and not in some Lua path. Normally this merge is not +-- needed when texmfstart is used, or when the proper stub is used or +-- when (windows) suffix binding is active. + +texlua = true + +-- begin library merge + + + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 +local unpack = unpack or table.unpack + +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 + +-- rougly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack) + +function table.sub(t,i,j) + return { unpack(t,i,j) } +end + +function table.replace(a,b) + for k,v in next, b do + a[k] = v + end +end + +-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice) + +function table.is_empty(t) -- 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 +--~ 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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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')) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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") + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + +-- 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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-tra'] = { + version = 1.001, + comment = "companion to trac-tra.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + +debugger = debugger or { } + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in next, counters do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ print("") +--~ debugger.showstats(print,3) + +setters = setters or { } +setters.data = setters.data or { } + +--~ local function set(t,what,value) +--~ local data, done = t.data, t.done +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end + +local function set(t,what,value) + local data, done = t.data, t.done + if type(what) == "string" then + what = aux.settings_to_hash(what) -- inefficient but ok + end + for w, v in next, what do + if v == "" then + v = value + else + v = toboolean(v) + end + for d, f in next, data do + if done[d] then + -- prevent recursion due to wildcards + elseif find(d,w) then + done[d] = true + for i=1,#f do + f[i](v) + end + end + end + end +end + +local function reset(t) + for d, f in next, t.data do + for i=1,#f do + f[i](false) + end + end +end + +local function enable(t,what) + set(t,what,true) +end + +local function disable(t,what) + local data = t.data + if not what or what == "" then + t.done = { } + reset(t) + else + set(t,what,false) + end +end + +function setters.register(t,what,...) + local data = t.data + what = lower(what) + local w = data[what] + if not w then + w = { } + data[what] = w + end + for _, fnc in next, { ... } do + local typ = type(fnc) + if typ == "function" then + w[#w+1] = fnc + elseif typ == "string" then + w[#w+1] = function(value) set(t,fnc,value,nesting) end + end + end +end + +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(tostring(what))) + t.enable, t.done = e, { } +end + +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(tostring(what))) + t.disable, t.done = e, { } +end + +function setters.reset(t) + t.done = { } + reset(t) +end + +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) + local user, system = { }, { } + for l=1,#list do + local what = list[l] + if find(what,"^%*") then + system[#system+1] = what + else + user[#user+1] = what + end + end + return user, system +end + +function setters.show(t) + commands.writestatus("","") + local list = setters.list(t) + for k=1,#list do + commands.writestatus(t.name,list[k]) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singular tracker + +-- we could make this into a module + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") +experiments = setters.new("experiments") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) +local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +local e = experiments.enable +local d = experiments.disable + +function experiments.enable(...) + commands.writestatus("experiments","enabling: %s",concat({...}," ")) + e(...) +end + +function experiments.disable(...) + commands.writestatus("experiments","disabling: %s",concat({...}," ")) + d(...) +end + +-- a useful example + +directives.register("system.nostatistics", function(v) + statistics.enable = not v +end) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-inf'] = { + version = 1.001, + comment = "companion to trac-inf.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 statusinfo, n, registered = { }, 0, { } + +statistics = statistics or { } + +statistics.enable = true +statistics.threshold = 0.05 + +-- timing functions + +local clock = os.gettimeofday or os.clock + +local notimer + +function statistics.hastimer(instance) + return instance and instance.starttime +end + +function statistics.resettiming(instance) + if not instance then + notimer = { timing = 0, loadtime = 0 } + else + instance.timing, instance.loadtime = 0, 0 + end +end + +function statistics.starttiming(instance) + if not instance then + notimer = { } + instance = notimer + end + local it = instance.timing + if not it then + it = 0 + end + if it == 0 then + instance.starttime = clock() + if not instance.loadtime then + instance.loadtime = 0 + end + else +--~ logs.report("system","nested timing (%s)",tostring(instance)) + end + instance.timing = it + 1 +end + +function statistics.stoptiming(instance, report) + if not instance then + instance = notimer + end + if instance then + local it = instance.timing + if it > 1 then + instance.timing = it - 1 + else + local starttime = instance.starttime + if starttime then + local stoptime = clock() + local loadtime = stoptime - starttime + instance.stoptime = stoptime + instance.loadtime = instance.loadtime + loadtime + if report then + statistics.report("load time %0.3f",loadtime) + end + instance.timing = 0 + return loadtime + end + end + end + return 0 +end + +function statistics.elapsedtime(instance) + if not instance then + instance = notimer + end + return format("%0.3f",(instance and instance.loadtime) or 0) +end + +function statistics.elapsedindeed(instance) + if not instance then + instance = notimer + end + local t = (instance and instance.loadtime) or 0 + return t > statistics.threshold +end + +function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds + if statistics.elapsedindeed(instance) then + return format("%s seconds %s", statistics.elapsedtime(instance),rest or "") + end +end + +-- general function + +function statistics.register(tag,fnc) + if statistics.enable and type(fnc) == "function" then + local rt = registered[tag] or (#statusinfo + 1) + statusinfo[rt] = { tag, fnc } + registered[tag] = rt + if #tag > n then n = #tag end + end +end + +function statistics.show(reporter) + if statistics.enable then + if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end + -- this code will move + local register = statistics.register + register("luatex banner", function() + return string.lower(status.banner) + end) + register("control sequences", function() + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) + end) + register("callbacks", function() + local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 + return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total) + end) + register("current memory usage", statistics.memused) + register("runtime",statistics.runtime) +-- -- + for i=1,#statusinfo do + local s = statusinfo[i] + local r = s[2]() + if r then + reporter(s[1],r,n) + end + end + texio.write_nl("") -- final newline + statistics.enable = false + end +end + +function statistics.show_job_stat(tag,data,n) + texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data)) +end + +function statistics.memused() -- no math.round yet -) + local round = math.round or math.floor + return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) +end + +if statistics.runtime then + -- already loaded and set +elseif luatex and luatex.starttime then + statistics.starttime = luatex.starttime + statistics.loadtime = 0 + statistics.timing = 0 +else + statistics.starttiming(statistics) +end + +function statistics.runtime() + statistics.stoptiming(statistics) + return statistics.formatruntime(statistics.elapsedtime(statistics)) +end + +function statistics.formatruntime(runtime) + return format("%s seconds", statistics.elapsedtime(statistics)) +end + +function statistics.timed(action,report) + local timer = { } + report = report or logs.simple + statistics.starttiming(timer) + action() + statistics.stoptiming(timer) + report("total runtime: %s",statistics.elapsedtime(timer)) +end + +-- where, not really the best spot for this: + +commands = commands or { } + +local timer + +function commands.resettimer() + statistics.resettiming(timer) + statistics.starttiming(timer) +end + +function commands.elapsedtime() + statistics.stoptiming(timer) + tex.sprint(statistics.elapsedtime(timer)) +end + +commands.resettimer() + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-log'] = { + version = 1.001, + comment = "companion to trac-log.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is old code that needs an overhaul + +--~ io.stdout:setvbuf("no") +--~ io.stderr:setvbuf("no") + +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch +local texcount = tex and tex.count + +if texlua then + write_nl = print + write = io.write +end + +--[[ldx-- +

This is a prelude to a more extensive logging module. For the sake +of parsing log files, in addition to the standard logging we will +provide an structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

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

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

+--ldx]]-- + +logs.moreinfo = [[ +more information about ConTeXt and the tools that come with it can be found at: + +maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context +webpage : http://www.pragma-ade.nl / http://tex.aanhet.net +wiki : http://contextgarden.net +]] + +logs.levels = { + ['error'] = 1, + ['warning'] = 2, + ['info'] = 3, + ['debug'] = 4, +} + +logs.functions = { + 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct', + 'start_run', 'stop_run', + 'start_page_number', 'stop_page_number', + 'report_output_pages', 'report_output_log', + 'report_tex_stat', 'report_job_stat', + 'show_open', 'show_close', 'show_load', +} + +logs.tracers = { +} + +logs.level = 0 +logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex")) + +function logs.set_level(level) + logs.level = logs.levels[level] or level +end + +function logs.set_method(method) + for _, v in next, logs.functions do + logs[v] = logs[method][v] or function() end + end +end + +-- tex logging + +function logs.tex.report(category,fmt,...) -- new + if fmt then + write_nl(category .. " | " .. format(fmt,...)) + else + write_nl(category .. " |") + end +end + +function logs.tex.line(fmt,...) -- new + if fmt then + write_nl(format(fmt,...)) + else + write_nl("") + end +end + +--~ function logs.tex.start_page_number() +--~ local real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +--~ if real > 0 then +--~ if user > 0 then +--~ if sub > 0 then +--~ write(format("[%s.%s.%s",real,user,sub)) +--~ else +--~ write(format("[%s.%s",real,user)) +--~ end +--~ else +--~ write(format("[%s",real)) +--~ end +--~ else +--~ write("[-") +--~ end +--~ end + +--~ function logs.tex.stop_page_number() +--~ write("]") +--~ end + +local real, user, sub + +function logs.tex.start_page_number() + real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +end + +function logs.tex.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + logs.report("pages", "flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + logs.report("pages", "flushing realpage %s, userpage %s",real,user) + end + else + logs.report("pages", "flushing realpage %s",real) + end + else + logs.report("pages", "flushing page") + end + io.flush() +end + +logs.tex.report_job_stat = statistics.show_job_stat + +-- xml logging + +function logs.xml.report(category,fmt,...) -- new + if fmt then + write_nl(format("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + end +end + +function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end +function logs.xml.stop () if logs.level > 0 then tw("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",level+1,name)) +end + +-- + +local name, banner = 'report', 'context' + +local function report(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + +local function simple(fmt,...) + if fmt then + write_nl(format("%s | %s",name,format(fmt,...))) + else + write_nl(format("%s |",name)) + end +end + +function logs.setprogram(_name_,_banner_,_verbose_) + name, banner = _name_, _banner_ + if _verbose_ then + trackers.enable("resolvers.locating") + end + logs.set_method("tex") + logs.report = report -- also used in libraries + logs.simple = simple -- only used in scripts ! + if utils then + utils.report = simple + end + logs.verbose = _verbose_ +end + +function logs.setverbose(what) + if what then + trackers.enable("resolvers.locating") + else + trackers.disable("resolvers.locating") + end + logs.verbose = what or false +end + +function logs.extendbanner(_banner_,_verbose_) + banner = banner .. " | ".. _banner_ + if _verbose_ ~= nil then + logs.setverbose(what) + end +end + +logs.verbose = false +logs.report = logs.tex.report +logs.simple = logs.tex.report + +function logs.reportlines(str) -- todo: + for line in gmatch(str,"(.-)[\n\r]") do + logs.report(line) + end +end + +function logs.reportline() -- for scripts too + logs.report() +end + +logs.simpleline = logs.reportline + +function logs.reportbanner() -- for scripts too + logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() + logs.reportline() + logs.reportlines(message) + local moreinfo = logs.moreinfo or "" + if moreinfo ~= "" and option ~= "nomoreinfo" then + logs.reportline() + logs.reportlines(moreinfo) + end +end + +logs.set_level('error') +logs.set_method('tex') + +function logs.system(whereto,process,jobname,category,...) + for i=1,10 do + local f = io.open(whereto,"a") + if f then + f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...))) + f:close() + break + else + sleep(0.1) + end + end +end + +--~ local syslogname = "oeps.xxx" +--~ +--~ for i=1,10 do +--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123") +--~ end + +function logs.fatal(where,...) + logs.report(where,"fatal error: %s, aborting now",format(...)) + os.exit() +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 } + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 { } + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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' + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure +-- end library merge + +-- We initialize some characteristics of this program. We need to +-- do this before we load the libraries, else own.name will not be +-- properly set (handy for selfcleaning the file). It's an ugly +-- looking piece of code. + +own = { } + +own.libs = { -- todo: check which ones are really needed + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-io.lua', + 'l-number.lua', + 'l-set.lua', + 'l-os.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-boolean.lua', + 'l-unicode.lua', + 'l-math.lua', + 'l-utils.lua', + 'l-aux.lua', + 'trac-tra.lua', + 'luat-env.lua', + 'trac-inf.lua', + 'trac-log.lua', + 'data-res.lua', + 'data-tmp.lua', +-- 'data-pre.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-tex.lua', +-- 'data-bin.lua', +-- 'data-zip.lua', +-- 'data-crl.lua', +-- 'data-lua.lua', + 'data-kps.lua', -- so that we can replace kpsewhich + 'data-aux.lua', -- updater + 'data-lst.lua', -- lister +} + +-- We need this hack till luatex is fixed. + +if arg and arg[0] == 'luatex' 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 + +-- End of hack. + +own.name = (environment and environment.ownname) or arg[0] or 'luatools.lua' +own.path = string.match(own.name,"^(.+)[\\/].-$") or "." +own.list = { '.' } + +if own.path ~= '.' then + table.insert(own.list,own.path) +end + +table.insert(own.list,own.path.."/../../../tex/context/base") +table.insert(own.list,own.path.."/mtx") +table.insert(own.list,own.path.."/../sources") + +function locate_libs() + for _, lib in pairs(own.libs) do + for _, pth in pairs(own.list) do + local filename = string.gsub(pth .. "/" .. lib,"\\","/") + local codeblob = loadfile(filename) + if codeblob then + codeblob() + own.list = { pth } -- speed up te search + break + end + end + end +end + +if not resolvers then + locate_libs() +end + +if not resolvers then + print("") + print("Luatools is unable to start up due to lack of libraries. You may") + print("try to run 'lua luatools.lua --selfmerge' in the path where this") + print("script is located (normally under ..../scripts/context/lua) which") + print("will make luatools library independent.") + os.exit() +end + +logs.setprogram('LuaTools',"TDS Management Tool 1.32",environment.arguments["verbose"] or false) + +local instance = resolvers.reset() + +resolvers.defaultlibs = { -- not all are needed (this will become: context.lus (lua spec) + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-boolean.lua', + 'l-number.lua', + 'l-unicode.lua', + 'l-os.lua', + 'l-io.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-utils.lua', + 'l-dimen.lua', + 'trac-inf.lua', + 'trac-tra.lua', + 'trac-log.lua', + 'luat-env.lua', -- here ? + 'data-res.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-tmp.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-pre.lua', + 'data-tex.lua', + 'data-bin.lua', +-- 'data-zip.lua', +-- 'data-clr.lua', + 'data-lua.lua', + 'data-ctx.lua', + 'luat-fio.lua', + 'luat-cnf.lua', +} + +instance.engine = environment.arguments["engine"] or 'luatex' +instance.progname = environment.arguments["progname"] or 'context' +instance.luaname = environment.arguments["luafile"] or "" -- environment.ownname or "" +instance.lualibs = environment.arguments["lualibs"] or table.concat(resolvers.defaultlibs,",") +instance.allresults = environment.arguments["all"] or false +instance.pattern = environment.arguments["pattern"] or nil +instance.sortdata = environment.arguments["sort"] or false +instance.kpseonly = not environment.arguments["all"] or false +instance.my_format = environment.arguments["format"] or instance.format + +if type(instance.pattern) == 'boolean' then + logs.simple("invalid pattern specification") + instance.pattern = nil +end + +if environment.arguments["trace"] then resolvers.settrace(environment.arguments["trace"]) end + +local trackspec = environment.argument("trackers") or environment.argument("track") + +if trackspec then + trackers.enable(trackspec) +end + +runners = runners or { } +messages = messages or { } + +messages.no_ini_file = [[ +There is no lua initialization file found. This file can be forced by the +"--progname" directive, or specified with "--luaname", or it is derived +automatically from the formatname (aka jobname). It may be that you have +to regenerate the file database using "luatools --generate". +]] + +messages.help = [[ +--generate generate file database +--variables show configuration variables +--expansions show expanded variables +--configurations show configuration order +--expand-braces expand complex variable +--expand-path expand variable (resolve paths) +--expand-var expand variable (resolve references) +--show-path show path expansion of ... +--var-value report value of variable +--find-file report file location +--find-path report path of file +--make or --ini make luatex format +--run or --fmt= run luatex format +--luafile=str lua inifile (default is .lua) +--lualibs=list libraries to assemble (optional when --compile) +--compile assemble and compile lua inifile +--verbose give a bit more info +--all show all found files +--sort sort cached data +--engine=str target engine +--progname=str format or backend +--pattern=str filter variables +--trackers=list enable given trackers +]] + +function runners.make_format(texname) + local instance = resolvers.instance + if texname and texname ~= "" then + if resolvers.usecache then + local path = file.join(caches.setpath("formats")) -- maybe platform + if path and lfs then + lfs.chdir(path) + end + end + local barename = texname:gsub("%.%a+$","") + if barename == texname then + texname = texname .. ".tex" + end + local fullname = resolvers.find_files(texname)[1] or "" + if fullname == "" then + logs.simple("no tex file with name: %s",texname) + else + local luaname, lucname, luapath, lualibs = "", "", "", { } + -- the following is optional, since context.lua can also + -- handle this collect and compile business + if environment.arguments["compile"] then + if luaname == "" then luaname = barename end + logs.simple("creating initialization file: %s",luaname) + luapath = file.dirname(luaname) + if luapath == "" then + luapath = file.dirname(texname) + end + if luapath == "" then + luapath = file.dirname(resolvers.find_files(texname)[1] or "") + end + lualibs = string.split(instance.lualibs,",") + luaname = file.basename(barename .. ".lua") + lucname = file.basename(barename .. ".luc") + -- todo: when this fails, we can just copy the merged libraries from + -- luatools since they are normally the same, at least for context + if lualibs[1] then + local firstlib = file.join(luapath,lualibs[1]) + if not lfs.isfile(firstlib) then + local foundname = resolvers.find_files(lualibs[1])[1] + if foundname then + logs.simple("located library path: %s",luapath) + luapath = file.dirname(foundname) + end + end + end + logs.simple("using library path: %s",luapath) + logs.simple("using lua libraries: %s",table.join(lualibs," ")) + utils.merger.selfcreate(lualibs,luapath,luaname) + local strip = resolvers.boolean_variable("LUACSTRIP", true) + if utils.lua.compile(luaname,lucname,false,strip) and io.exists(lucname) then + luaname = lucname + logs.simple("using compiled initialization file: %s",lucname) + else + logs.simple("using uncompiled initialization file: %s",luaname) + end + else + local what = { instance.luaname, instance.progname, barename } + for k=1,#what do + local v = string.gsub(what[k]..".lua","%.lua%.lua$",".lua") + if v and (v ~= "") then + luaname = resolvers.find_files(v)[1] or "" + if luaname ~= "" then + break + end + end + end + end + if environment.arguments["noluc"] then + luaname = luaname:gsub("%.luc$",".lua") -- make this an option + end + if luaname == "" then + if logs.verbose then + logs.simplelines(messages.no_ini_file) + logs.simple("texname : %s",texname) + logs.simple("luaname : %s",instance.luaname) + logs.simple("progname: %s",instance.progname) + logs.simple("barename: %s",barename) + end + else + logs.simple("using lua initialization file: %s",luaname) + local mp = dir.glob(file.removesuffix(file.basename(luaname)).."-*.mem") + if mp and #mp > 0 then + for i=1,#mp do + local name = mp[i] + logs.simple("removing related mplib format %s", file.basename(name)) + os.remove(name) + end + end + local flags = { + "--ini", + "--lua=" .. string.quote(luaname) + } + local bs = (os.platform == "unix" and "\\\\") or "\\" -- todo: make a function + local command = "luatex ".. table.concat(flags," ") .. " " .. string.quote(fullname) .. " " .. bs .. "dump" + logs.simple("running command: %s\n",command) + os.spawn(command) + -- todo: do a dummy run that generates the related metafun and mfplain formats + end + end + else + logs.simple("no tex file given") + end +end + +function runners.run_format(name,data,more) + -- hm, rather old code here; we can now use the file.whatever functions + if name and (name ~= "") then + local barename = name:gsub("%.%a+$","") + local fmtname = "" + 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) + barename = fmtname:gsub("%.%a+$","") + if fmtname == "" then + logs.simple("no format with name: %s",name) + else + local luaname = barename .. ".luc" + local f = io.open(luaname) + if not f then + luaname = barename .. ".lua" + f = io.open(luaname) + end + if f then + f:close() + local command = "luatex --fmt=" .. string.quote(barename) .. " --lua=" .. string.quote(luaname) .. " " .. string.quote(data) .. " " .. (more ~= "" and string.quote(more) or "") + logs.simple("running command: %s",command) + os.spawn(command) + else + logs.simple("using format name: %s",fmtname) + logs.simple("no luc/lua with name: %s",barename) + end + end + end +end + +local ok = true + +-- private option --noluc for testing errors in the stub + +if environment.arguments["find-file"] then + resolvers.load() + instance.format = environment.arguments["format"] or instance.format + if instance.pattern then + instance.allresults = true + resolvers.for_files(resolvers.find_files, { instance.pattern }, instance.my_format) + else + resolvers.for_files(resolvers.find_files, environment.files, instance.my_format) + end +elseif environment.arguments["find-path"] then + resolvers.load() + local path = resolvers.find_file(environment.files[1], instance.my_format) + if logs.verbose then + logs.simple(file.dirname(path)) + else + print(file.dirname(path)) + end +elseif environment.arguments["run"] then + resolvers.load("nofiles") -- ! no need for loading databases + logs.setverbose(true) + runners.run_format(environment.files[1] or "",environment.files[2] or "",environment.files[3] or "") +elseif environment.arguments["fmt"] then + resolvers.load("nofiles") -- ! no need for loading databases + logs.setverbose(true) + runners.run_format(environment.arguments["fmt"], environment.files[1] or "",environment.files[2] or "") +elseif environment.arguments["expand-braces"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_braces, environment.files) +elseif environment.arguments["expand-path"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_path, environment.files) +elseif environment.arguments["expand-var"] or environment.arguments["expand-variable"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_var, environment.files) +elseif environment.arguments["show-path"] or environment.arguments["path-value"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.show_path, environment.files) +elseif environment.arguments["var-value"] or environment.arguments["show-value"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.var_value, environment.files) +elseif environment.arguments["format-path"] then + resolvers.load() + logs.simple(caches.setpath("format")) +elseif instance.pattern then -- brrr + resolvers.load() + instance.format = environment.arguments["format"] or instance.format + instance.allresults = true + resolvers.for_files(resolvers.find_files, { instance.pattern }, instance.my_format) +elseif environment.arguments["generate"] then + instance.renewcache = true + logs.setverbose(true) + resolvers.load() +elseif environment.arguments["make"] or environment.arguments["ini"] or environment.arguments["compile"] then + resolvers.load() + logs.setverbose(true) + runners.make_format(environment.files[1] or "") +elseif environment.arguments["selfmerge"] then + utils.merger.selfmerge(own.name,own.libs,own.list) +elseif environment.arguments["selfclean"] then + utils.merger.selfclean(own.name) +elseif environment.arguments["selfupdate"] then + resolvers.load() + logs.setverbose(true) + resolvers.update_script(own.name,"luatools") +elseif environment.arguments["variables"] or environment.arguments["show-variables"] then + resolvers.load("nofiles") + resolvers.listers.variables() +elseif environment.arguments["expansions"] or environment.arguments["show-expansions"] then + resolvers.load("nofiles") + resolvers.listers.expansions() +elseif environment.arguments["configurations"] or environment.arguments["show-configurations"] then + resolvers.load("nofiles") + resolvers.listers.configurations() +elseif environment.arguments["help"] or (environment.files[1]=='help') or (#environment.files==0) then + logs.help(messages.help) +else + resolvers.load() + resolvers.for_files(resolvers.find_files, environment.files, instance.my_format) +end + +if logs.verbose then + logs.simpleline() + logs.simple("runtime: %0.3f seconds",os.runtime()) +end + +if os.platform == "unix" then + io.write("\n") +end diff --git a/scripts/context/stubs/mswin/metatex.exe b/scripts/context/stubs/mswin/metatex.exe new file mode 100644 index 000000000..2d45f2749 Binary files /dev/null and b/scripts/context/stubs/mswin/metatex.exe differ diff --git a/scripts/context/stubs/mswin/mtxrun.dll b/scripts/context/stubs/mswin/mtxrun.dll new file mode 100644 index 000000000..23e476cac Binary files /dev/null and b/scripts/context/stubs/mswin/mtxrun.dll differ diff --git a/scripts/context/stubs/mswin/mtxrun.exe b/scripts/context/stubs/mswin/mtxrun.exe new file mode 100644 index 000000000..745eaf224 Binary files /dev/null and b/scripts/context/stubs/mswin/mtxrun.exe differ diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua new file mode 100644 index 000000000..b99327692 --- /dev/null +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -0,0 +1,12639 @@ +#!/usr/bin/env texlua + +if not modules then modules = { } end modules ['mtxrun'] = { + version = 1.001, + comment = "runner, lua replacement for texmfstart.rb", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + + +-- one can make a stub: +-- +-- #!/bin/sh +-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@" + +-- filename : mtxrun.lua +-- comment : companion to context.tex +-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL +-- copyright: PRAGMA ADE / ConTeXt Development Team +-- license : see context related readme files + +-- This script is based on texmfstart.rb but does not use kpsewhich to +-- locate files. Although kpse is a library it never came to opening up +-- its interface to other programs (esp scripting languages) and so we +-- do it ourselves. The lua variant evolved out of an experimental ruby +-- one. Interesting is that using a scripting language instead of c does +-- not have a speed penalty. Actually the lua variant is more efficient, +-- especially when multiple calls to kpsewhich are involved. The lua +-- library also gives way more control. + +-- to be done / considered +-- +-- support for --exec or make it default +-- support for jar files (or maybe not, never used, too messy) +-- support for $RUBYINPUTS cum suis (if still needed) +-- remember for subruns: _CTX_K_V_#{original}_ +-- remember for subruns: _CTX_K_S_#{original}_ +-- remember for subruns: TEXMFSTART.#{original} [tex.rb texmfstart.rb] + +texlua = true + +-- begin library merge + + + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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')) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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") + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-tra'] = { + version = 1.001, + comment = "companion to trac-tra.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + +debugger = debugger or { } + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in next, counters do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ print("") +--~ debugger.showstats(print,3) + +setters = setters or { } +setters.data = setters.data or { } + +--~ local function set(t,what,value) +--~ local data, done = t.data, t.done +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end + +local function set(t,what,value) + local data, done = t.data, t.done + if type(what) == "string" then + what = aux.settings_to_hash(what) -- inefficient but ok + end + for w, v in next, what do + if v == "" then + v = value + else + v = toboolean(v) + end + for d, f in next, data do + if done[d] then + -- prevent recursion due to wildcards + elseif find(d,w) then + done[d] = true + for i=1,#f do + f[i](v) + end + end + end + end +end + +local function reset(t) + for d, f in next, t.data do + for i=1,#f do + f[i](false) + end + end +end + +local function enable(t,what) + set(t,what,true) +end + +local function disable(t,what) + local data = t.data + if not what or what == "" then + t.done = { } + reset(t) + else + set(t,what,false) + end +end + +function setters.register(t,what,...) + local data = t.data + what = lower(what) + local w = data[what] + if not w then + w = { } + data[what] = w + end + for _, fnc in next, { ... } do + local typ = type(fnc) + if typ == "function" then + w[#w+1] = fnc + elseif typ == "string" then + w[#w+1] = function(value) set(t,fnc,value,nesting) end + end + end +end + +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(tostring(what))) + t.enable, t.done = e, { } +end + +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(tostring(what))) + t.disable, t.done = e, { } +end + +function setters.reset(t) + t.done = { } + reset(t) +end + +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) + local user, system = { }, { } + for l=1,#list do + local what = list[l] + if find(what,"^%*") then + system[#system+1] = what + else + user[#user+1] = what + end + end + return user, system +end + +function setters.show(t) + commands.writestatus("","") + local list = setters.list(t) + for k=1,#list do + commands.writestatus(t.name,list[k]) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singular tracker + +-- we could make this into a module + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") +experiments = setters.new("experiments") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) +local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +local e = experiments.enable +local d = experiments.disable + +function experiments.enable(...) + commands.writestatus("experiments","enabling: %s",concat({...}," ")) + e(...) +end + +function experiments.disable(...) + commands.writestatus("experiments","disabling: %s",concat({...}," ")) + d(...) +end + +-- a useful example + +directives.register("system.nostatistics", function(v) + statistics.enable = not v +end) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-inf'] = { + version = 1.001, + comment = "companion to trac-inf.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 statusinfo, n, registered = { }, 0, { } + +statistics = statistics or { } + +statistics.enable = true +statistics.threshold = 0.05 + +-- timing functions + +local clock = os.gettimeofday or os.clock + +local notimer + +function statistics.hastimer(instance) + return instance and instance.starttime +end + +function statistics.resettiming(instance) + if not instance then + notimer = { timing = 0, loadtime = 0 } + else + instance.timing, instance.loadtime = 0, 0 + end +end + +function statistics.starttiming(instance) + if not instance then + notimer = { } + instance = notimer + end + local it = instance.timing + if not it then + it = 0 + end + if it == 0 then + instance.starttime = clock() + if not instance.loadtime then + instance.loadtime = 0 + end + else +--~ logs.report("system","nested timing (%s)",tostring(instance)) + end + instance.timing = it + 1 +end + +function statistics.stoptiming(instance, report) + if not instance then + instance = notimer + end + if instance then + local it = instance.timing + if it > 1 then + instance.timing = it - 1 + else + local starttime = instance.starttime + if starttime then + local stoptime = clock() + local loadtime = stoptime - starttime + instance.stoptime = stoptime + instance.loadtime = instance.loadtime + loadtime + if report then + statistics.report("load time %0.3f",loadtime) + end + instance.timing = 0 + return loadtime + end + end + end + return 0 +end + +function statistics.elapsedtime(instance) + if not instance then + instance = notimer + end + return format("%0.3f",(instance and instance.loadtime) or 0) +end + +function statistics.elapsedindeed(instance) + if not instance then + instance = notimer + end + local t = (instance and instance.loadtime) or 0 + return t > statistics.threshold +end + +function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds + if statistics.elapsedindeed(instance) then + return format("%s seconds %s", statistics.elapsedtime(instance),rest or "") + end +end + +-- general function + +function statistics.register(tag,fnc) + if statistics.enable and type(fnc) == "function" then + local rt = registered[tag] or (#statusinfo + 1) + statusinfo[rt] = { tag, fnc } + registered[tag] = rt + if #tag > n then n = #tag end + end +end + +function statistics.show(reporter) + if statistics.enable then + if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end + -- this code will move + local register = statistics.register + register("luatex banner", function() + return string.lower(status.banner) + end) + register("control sequences", function() + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) + end) + register("callbacks", function() + local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 + return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total) + end) + register("current memory usage", statistics.memused) + register("runtime",statistics.runtime) +-- -- + for i=1,#statusinfo do + local s = statusinfo[i] + local r = s[2]() + if r then + reporter(s[1],r,n) + end + end + texio.write_nl("") -- final newline + statistics.enable = false + end +end + +function statistics.show_job_stat(tag,data,n) + texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data)) +end + +function statistics.memused() -- no math.round yet -) + local round = math.round or math.floor + return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) +end + +if statistics.runtime then + -- already loaded and set +elseif luatex and luatex.starttime then + statistics.starttime = luatex.starttime + statistics.loadtime = 0 + statistics.timing = 0 +else + statistics.starttiming(statistics) +end + +function statistics.runtime() + statistics.stoptiming(statistics) + return statistics.formatruntime(statistics.elapsedtime(statistics)) +end + +function statistics.formatruntime(runtime) + return format("%s seconds", statistics.elapsedtime(statistics)) +end + +function statistics.timed(action,report) + local timer = { } + report = report or logs.simple + statistics.starttiming(timer) + action() + statistics.stoptiming(timer) + report("total runtime: %s",statistics.elapsedtime(timer)) +end + +-- where, not really the best spot for this: + +commands = commands or { } + +local timer + +function commands.resettimer() + statistics.resettiming(timer) + statistics.starttiming(timer) +end + +function commands.elapsedtime() + statistics.stoptiming(timer) + tex.sprint(statistics.elapsedtime(timer)) +end + +commands.resettimer() + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-log'] = { + version = 1.001, + comment = "companion to trac-log.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is old code that needs an overhaul + +--~ io.stdout:setvbuf("no") +--~ io.stderr:setvbuf("no") + +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch +local texcount = tex and tex.count + +if texlua then + write_nl = print + write = io.write +end + +--[[ldx-- +

This is a prelude to a more extensive logging module. For the sake +of parsing log files, in addition to the standard logging we will +provide an structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

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

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

+--ldx]]-- + +logs.moreinfo = [[ +more information about ConTeXt and the tools that come with it can be found at: + +maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context +webpage : http://www.pragma-ade.nl / http://tex.aanhet.net +wiki : http://contextgarden.net +]] + +logs.levels = { + ['error'] = 1, + ['warning'] = 2, + ['info'] = 3, + ['debug'] = 4, +} + +logs.functions = { + 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct', + 'start_run', 'stop_run', + 'start_page_number', 'stop_page_number', + 'report_output_pages', 'report_output_log', + 'report_tex_stat', 'report_job_stat', + 'show_open', 'show_close', 'show_load', +} + +logs.tracers = { +} + +logs.level = 0 +logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex")) + +function logs.set_level(level) + logs.level = logs.levels[level] or level +end + +function logs.set_method(method) + for _, v in next, logs.functions do + logs[v] = logs[method][v] or function() end + end +end + +-- tex logging + +function logs.tex.report(category,fmt,...) -- new + if fmt then + write_nl(category .. " | " .. format(fmt,...)) + else + write_nl(category .. " |") + end +end + +function logs.tex.line(fmt,...) -- new + if fmt then + write_nl(format(fmt,...)) + else + write_nl("") + end +end + +--~ function logs.tex.start_page_number() +--~ local real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +--~ if real > 0 then +--~ if user > 0 then +--~ if sub > 0 then +--~ write(format("[%s.%s.%s",real,user,sub)) +--~ else +--~ write(format("[%s.%s",real,user)) +--~ end +--~ else +--~ write(format("[%s",real)) +--~ end +--~ else +--~ write("[-") +--~ end +--~ end + +--~ function logs.tex.stop_page_number() +--~ write("]") +--~ end + +local real, user, sub + +function logs.tex.start_page_number() + real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +end + +function logs.tex.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + logs.report("pages", "flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + logs.report("pages", "flushing realpage %s, userpage %s",real,user) + end + else + logs.report("pages", "flushing realpage %s",real) + end + else + logs.report("pages", "flushing page") + end + io.flush() +end + +logs.tex.report_job_stat = statistics.show_job_stat + +-- xml logging + +function logs.xml.report(category,fmt,...) -- new + if fmt then + write_nl(format("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + end +end + +function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end +function logs.xml.stop () if logs.level > 0 then tw("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",level+1,name)) +end + +-- + +local name, banner = 'report', 'context' + +local function report(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + +local function simple(fmt,...) + if fmt then + write_nl(format("%s | %s",name,format(fmt,...))) + else + write_nl(format("%s |",name)) + end +end + +function logs.setprogram(_name_,_banner_,_verbose_) + name, banner = _name_, _banner_ + if _verbose_ then + trackers.enable("resolvers.locating") + end + logs.set_method("tex") + logs.report = report -- also used in libraries + logs.simple = simple -- only used in scripts ! + if utils then + utils.report = simple + end + logs.verbose = _verbose_ +end + +function logs.setverbose(what) + if what then + trackers.enable("resolvers.locating") + else + trackers.disable("resolvers.locating") + end + logs.verbose = what or false +end + +function logs.extendbanner(_banner_,_verbose_) + banner = banner .. " | ".. _banner_ + if _verbose_ ~= nil then + logs.setverbose(what) + end +end + +logs.verbose = false +logs.report = logs.tex.report +logs.simple = logs.tex.report + +function logs.reportlines(str) -- todo: + for line in gmatch(str,"(.-)[\n\r]") do + logs.report(line) + end +end + +function logs.reportline() -- for scripts too + logs.report() +end + +logs.simpleline = logs.reportline + +function logs.reportbanner() -- for scripts too + logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() + logs.reportline() + logs.reportlines(message) + local moreinfo = logs.moreinfo or "" + if moreinfo ~= "" and option ~= "nomoreinfo" then + logs.reportline() + logs.reportlines(moreinfo) + end +end + +logs.set_level('error') +logs.set_method('tex') + +function logs.system(whereto,process,jobname,category,...) + for i=1,10 do + local f = io.open(whereto,"a") + if f then + f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...))) + f:close() + break + else + sleep(0.1) + end + end +end + +--~ local syslogname = "oeps.xxx" +--~ +--~ for i=1,10 do +--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123") +--~ end + +function logs.fatal(where,...) + logs.report(where,"fatal error: %s, aborting now",format(...)) + os.exit() +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 } + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 { } + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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') + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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' + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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")) + + +end -- of closure +-- end library merge + +own = { } -- not local + +own.libs = { -- todo: check which ones are really needed + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-io.lua', + 'l-number.lua', + 'l-set.lua', + 'l-os.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-boolean.lua', + 'l-math.lua', +-- 'l-unicode.lua', +-- 'l-tex.lua', + 'l-utils.lua', + 'l-aux.lua', +-- 'l-xml.lua', + 'trac-tra.lua', + 'lxml-tab.lua', + 'lxml-lpt.lua', +-- 'lxml-ent.lua', + 'lxml-mis.lua', + 'lxml-aux.lua', + 'lxml-xml.lua', + 'luat-env.lua', + 'trac-inf.lua', + 'trac-log.lua', + 'data-res.lua', + 'data-tmp.lua', + 'data-pre.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-tex.lua', +-- 'data-bin.lua', + 'data-zip.lua', + 'data-crl.lua', + 'data-lua.lua', + 'data-kps.lua', -- so that we can replace kpsewhich + 'data-aux.lua', -- updater + 'data-tmf.lua', -- tree files + -- needed ? + 'luat-sta.lua', -- states +} + +-- We need this hack till luatex is fixed. +-- +-- for k,v in pairs(arg) do print(k,v) end + +if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then + arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil +end + +-- End of hack. + +own.name = (environment and environment.ownname) or arg[0] or 'luatools.lua' + + +own.path = string.match(own.name,"^(.+)[\\/].-$") or "." +own.list = { '.' } +if own.path ~= '.' then + table.insert(own.list,own.path) +end +table.insert(own.list,own.path.."/../../../tex/context/base") +table.insert(own.list,own.path.."/mtx") +table.insert(own.list,own.path.."/../sources") + +local function locate_libs() + for _, lib in pairs(own.libs) do + for _, pth in pairs(own.list) do + local filename = string.gsub(pth .. "/" .. lib,"\\","/") + local codeblob = loadfile(filename) + if codeblob then + codeblob() + own.list = { pth } -- speed up te search + break + end + end + end +end + +if not resolvers then + locate_libs() +end + +if not resolvers then + print("") + print("Mtxrun is unable to start up due to lack of libraries. You may") + print("try to run 'lua mtxrun.lua --selfmerge' in the path where this") + print("script is located (normally under ..../scripts/context/lua) which") + print("will make this script library independent.") + os.exit() +end + +logs.setprogram('MTXrun',"TDS Runner Tool 1.24",environment.arguments["verbose"] or false) + +local instance = resolvers.reset() + +local trackspec = environment.argument("trackers") or environment.argument("track") + +if trackspec then + trackers.enable(trackspec) +end + +runners = runners or { } -- global +messages = messages or { } + +messages.help = [[ +--script run an mtx script (lua prefered method) (--noquotes), no script gives list +--execute run a script or program (texmfstart method) (--noquotes) +--resolve resolve prefixed arguments +--ctxlua run internally (using preloaded libs) +--internal run script using built in libraries (same as --ctxlua) +--locate locate given filename + +--autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' +--tree=pathtotree use given texmf tree (default file: 'setuptex.tmf') +--environment=name use given (tmf) environment file +--path=runpath go to given path before execution +--ifchanged=filename only execute when given file has changed (md checksum) +--iftouched=old,new only execute when given file has changed (time stamp) + +--make create stubs for (context related) scripts +--remove remove stubs (context related) scripts +--stubpath=binpath paths where stubs wil be written +--windows create windows (mswin) stubs +--unix create unix (linux) stubs + +--verbose give a bit more info +--trackers=list enable given trackers +--engine=str target engine +--progname=str format or backend + +--edit launch editor with found file +--launch (--all) launch files like manuals, assumes os support + +--timedrun run a script an time its run +--autogenerate regenerate databases if needed (handy when used to run context in an editor) + +--usekpse use kpse as fallback (when no mkiv and cache installed, often slower) +--forcekpse force using kpse (handy when no mkiv and cache installed but less functionality) + +--prefixes show supported prefixes +]] + +runners.applications = { + ["lua"] = "luatex --luaonly", + ["luc"] = "luatex --luaonly", + ["pl"] = "perl", + ["py"] = "python", + ["rb"] = "ruby", +} + +runners.suffixes = { + 'rb', 'lua', 'py', 'pl' +} + +runners.registered = { + texexec = { 'texexec.rb', false }, -- context mkii runner (only tool not to be luafied) + texutil = { 'texutil.rb', true }, -- old perl based index sorter for mkii (old versions need it) + texfont = { 'texfont.pl', true }, -- perl script that makes mkii font metric files + texfind = { 'texfind.pl', false }, -- perltk based tex searching tool, mostly used at pragma + texshow = { 'texshow.pl', false }, -- perltk based context help system, will be luafied + -- texwork = { 'texwork.pl', false }, -- perltk based editing environment, only used at pragma + makempy = { 'makempy.pl', true }, + mptopdf = { 'mptopdf.pl', true }, + pstopdf = { 'pstopdf.rb', true }, -- converts ps (and some more) images, does some cleaning (replaced) +-- examplex = { 'examplex.rb', false }, + concheck = { 'concheck.rb', false }, + runtools = { 'runtools.rb', true }, + textools = { 'textools.rb', true }, + tmftools = { 'tmftools.rb', true }, + ctxtools = { 'ctxtools.rb', true }, + rlxtools = { 'rlxtools.rb', true }, + pdftools = { 'pdftools.rb', true }, + mpstools = { 'mpstools.rb', true }, +-- exatools = { 'exatools.rb', true }, + xmltools = { 'xmltools.rb', true }, +-- luatools = { 'luatools.lua', true }, + mtxtools = { 'mtxtools.rb', true }, + pdftrimwhite = { 'pdftrimwhite.pl', false } +} + +runners.launchers = { + windows = { }, + unix = { } +} + +-- like runners.libpath("framework"): looks on script's subpath + +function runners.libpath(...) + package.prepend_libpath(file.dirname(environment.ownscript),...) + package.prepend_libpath(file.dirname(environment.ownname) ,...) +end + +function runners.prepare() + local checkname = environment.argument("ifchanged") + if checkname and checkname ~= "" then + local oldchecksum = file.loadchecksum(checkname) + local newchecksum = file.checksum(checkname) + if oldchecksum == newchecksum then + logs.simple("file '%s' is unchanged",checkname) + return "skip" + else + logs.simple("file '%s' is changed, processing started",checkname) + end + file.savechecksum(checkname) + end + local oldname, newname = string.split(environment.argument("iftouched") or "", ",") + if oldname and newname and oldname ~= "" and newname ~= "" then + if not file.needs_updating(oldname,newname) then + logs.simple("file '%s' and '%s' have same age",oldname,newname) + return "skip" + else + logs.simple("file '%s' is older than '%s'",oldname,newname) + end + end + local tree = environment.argument('tree') or "" + if environment.argument('autotree') then + tree = os.getenv('TEXMFSTART_TREE') or os.getenv('TEXMFSTARTTREE') or tree + end + if tree and tree ~= "" then + resolvers.load_tree(tree) + end + local env = environment.argument('environment') or "" + if env and env ~= "" then + for _,e in pairs(string.split(env)) do + -- maybe force suffix when not given + resolvers.load_tree(e) + end + end + local runpath = environment.argument("path") + if runpath and not lfs.chdir(runpath) then + logs.simple("unable to change to path '%s'",runpath) + return "error" + end + return "run" +end + +function runners.execute_script(fullname,internal,nosplit) + local noquote = environment.argument("noquotes") + if fullname and fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + instance.progname = environment.argument("progname") or instance.progname + instance.format = environment.argument("format") or instance.format + local path, name, suffix, result = file.dirname(fullname), file.basename(fullname), file.extname(fullname), "" + if path ~= "" then + result = fullname + elseif name then + name = name:gsub("^int[%a]*:",function() + internal = true + return "" + end ) + name = name:gsub("^script:","") + if suffix == "" and runners.registered[name] and runners.registered[name][1] then + name = runners.registered[name][1] + suffix = file.extname(name) + end + if suffix == "" then + -- loop over known suffixes + for _,s in pairs(runners.suffixes) do + result = resolvers.find_file(name .. "." .. s, 'texmfscripts') + if result ~= "" then + break + end + end + elseif runners.applications[suffix] then + result = resolvers.find_file(name, 'texmfscripts') + else + -- maybe look on path + result = resolvers.find_file(name, 'other text files') + end + end + if result and result ~= "" then + if not no_split then + local before, after = environment.split_arguments(fullname) -- already done + environment.arguments_before, environment.arguments_after = before, after + end + if internal then + arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end + environment.ownscript = result + dofile(result) + else + local binary = runners.applications[file.extname(result)] + if binary and binary ~= "" then + result = binary .. " " .. result + end + local command = result .. " " .. environment.reconstruct_commandline(environment.arguments_after,noquote) + if logs.verbose then + logs.simpleline() + logs.simple("executing: %s",command) + logs.simpleline() + logs.simpleline() + io.flush() + end + -- no os.exec because otherwise we get the wrong return value + local code = os.execute(command) -- maybe spawn + if code == 0 then + return true + else + if binary then + binary = file.addsuffix(binary,os.binsuffix) + for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do + if lfs.isfile(file.join(p,binary)) then + return false + end + end + logs.simpleline() + logs.simple("This script needs '%s' which seems not to be installed.",binary) + logs.simpleline() + end + return false + end + end + end + end + end + return false +end + +function runners.execute_program(fullname) + local noquote = environment.argument("noquotes") + if fullname and fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + local before, after = environment.split_arguments(fullname) + environment.initialize_arguments(after) + fullname = fullname:gsub("^bin:","") + local command = fullname .. " " .. (environment.reconstruct_commandline(after or "",noquote) or "") + logs.simpleline() + logs.simple("executing: %s",command) + logs.simpleline() + logs.simpleline() + io.flush() + local code = os.exec(command) -- (fullname,unpack(after)) does not work / maybe spawn + return code == 0 + end + end + return false +end + +-- the --usekpse flag will fallback on kpse (hm, we can better update mtx-stubs) + +local windows_stub = '@echo off\013\010setlocal\013\010set ownpath=%%~dp0%%\013\010texlua "%%ownpath%%mtxrun.lua" --usekpse --execute %s %%*\013\010endlocal\013\010' +local unix_stub = '#!/bin/sh\010mtxrun --usekpse --execute %s \"$@\"\010' + +function runners.handle_stubs(create) + local stubpath = environment.argument('stubpath') or '.' -- 'auto' no longer subpathssupported + local windows = environment.argument('windows') or environment.argument('mswin') or false + local unix = environment.argument('unix') or environment.argument('linux') or false + if not windows and not unix then + if os.platform == "unix" then + unix = true + else + windows = true + end + end + for _,v in pairs(runners.registered) do + local name, doit = v[1], v[2] + if doit then + local base = string.gsub(file.basename(name), "%.(.-)$", "") + if create then + if windows then + io.savedata(file.join(stubpath,base..".bat"),string.format(windows_stub,name)) + logs.simple("windows stub for '%s' created",base) + end + if unix then + io.savedata(file.join(stubpath,base),string.format(unix_stub,name)) + logs.simple("unix stub for '%s' created",base) + end + else + if windows and (os.remove(file.join(stubpath,base..'.bat')) or os.remove(file.join(stubpath,base..'.cmd'))) then + logs.simple("windows stub for '%s' removed", base) + end + if unix and (os.remove(file.join(stubpath,base)) or os.remove(file.join(stubpath,base..'.sh'))) then + logs.simple("unix stub for '%s' removed",base) + end + end + end + end +end + +function runners.resolve_string(filename) + if filename and filename ~= "" then + runners.report_location(resolvers.resolve(filename)) + end +end + +function runners.locate_file(filename) + -- differs from texmfstart where locate appends .com .exe .bat ... todo + if filename and filename ~= "" then + runners.report_location(resolvers.find_given_file(filename)) + end +end + +function runners.locate_platform() + runners.report_location(os.platform) +end + +function runners.report_location(result) + if logs.verbose then + logs.simpleline() + if result and result ~= "" then + logs.simple(result) + else + logs.simple("not found") + end + else + io.write(result) + end +end + +function runners.edit_script(filename) -- we assume that vim is present on most systems + local editor = os.getenv("MTXRUN_EDITOR") or os.getenv("TEXMFSTART_EDITOR") or os.getenv("EDITOR") or 'vim' + local rest = resolvers.resolve(filename) + if rest ~= "" then + local command = editor .. " " .. rest + if logs.verbose then + logs.simpleline() + logs.simple("starting editor: %s",command) + logs.simple_line() + logs.simple_line() + end + os.launch(command) + end +end + +function runners.save_script_session(filename, list) + local t = { } + for i=1,#list do + local key = list[i] + t[key] = environment.arguments[key] + end + io.savedata(filename,table.serialize(t,true)) +end + +function runners.load_script_session(filename) + if lfs.isfile(filename) then + local t = io.loaddata(filename) + if t then + t = loadstring(t) + if t then t = t() end + for key, value in pairs(t) do + environment.arguments[key] = value + end + end + end +end + +function resolvers.launch(str) + -- maybe we also need to test on mtxrun.launcher.suffix environment + -- variable or on windows consult the assoc and ftype vars and such + local launchers = runners.launchers[os.platform] if launchers then + local suffix = file.extname(str) if suffix then + local runner = launchers[suffix] if runner then + str = runner .. " " .. str + end + end + end + os.launch(str) +end + +function runners.launch_file(filename) + instance.allresults = true + logs.setverbose(true) + local pattern = environment.arguments["pattern"] + if not pattern or pattern == "" then + pattern = filename + end + if not pattern or pattern == "" then + logs.simple("provide name or --pattern=") + else + local t = resolvers.find_files(pattern) + if not t or #t == 0 then + t = resolvers.find_files("*/" .. pattern) + end + if not t or #t == 0 then + t = resolvers.find_files("*/" .. pattern .. "*") + end + if t and #t > 0 then + if environment.arguments["all"] then + for _, v in pairs(t) do + logs.simple("launching %s", v) + resolvers.launch(v) + end + else + logs.simple("launching %s", t[1]) + resolvers.launch(t[1]) + end + else + logs.simple("no match for %s", pattern) + end + end +end + +function runners.find_mtx_script(filename) + local function found(name) + local path = file.dirname(name) + if path and path ~= "" then + return false + else + local fullname = own and own.path and file.join(own.path,name) + return io.exists(fullname) and fullname + end + end + filename = file.addsuffix(filename,"lua") + local basename = file.removesuffix(file.basename(filename)) + local suffix = file.extname(filename) + -- qualified path, raw name + local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename + if fullname and fullname ~= "" then + return fullname + end + -- current path, raw name + fullname = "./" .. filename + fullname = io.exists(fullname) and fullname + if fullname and fullname ~= "" then + return fullname + end + -- mtx- prefix checking + local mtxprefix = (filename:find("^mtx%-") and "") or "mtx-" + -- context namespace, mtx- + fullname = mtxprefix .. filename + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx-s + fullname = mtxprefix .. basename .. "s" .. "." .. suffix + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx- + fullname = mtxprefix .. basename:gsub("s$","") .. "." .. suffix + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, just + fullname = resolvers.find_file(filename) + return fullname +end + +function runners.execute_ctx_script(filename) + local arguments = environment.arguments_after + local fullname = runners.find_mtx_script(filename) or "" + if file.extname(fullname) == "cld" then + -- handy in editors where we force --autopdf + logs.simple("running cld script: %s",filename) + table.insert(arguments,1,fullname) + table.insert(arguments,"--autopdf") + fullname = runners.find_mtx_script("context") or "" + end + -- retry after generate but only if --autogenerate + if fullname == "" and environment.argument("autogenerate") then -- might become the default + instance.renewcache = true + logs.setverbose(true) + resolvers.load() + -- + fullname = runners.find_mtx_script(filename) or "" + end + -- that should do it + if fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + -- load and save ... kind of undocumented + arg = { } for _,v in pairs(arguments) do arg[#arg+1] = resolvers.resolve(v) end + environment.initialize_arguments(arg) + local loadname = environment.arguments['load'] + if loadname then + if type(loadname) ~= "string" then loadname = file.basename(fullname) end + loadname = file.replacesuffix(loadname,"cfg") + runners.load_script_session(loadname) + end + filename = environment.files[1] + if logs.verbose then + logs.simple("using script: %s\n",fullname) + end + environment.ownscript = fullname + dofile(fullname) + local savename = environment.arguments['save'] + if savename then + local save_list = runners.save_list + if save_list and next(save_list) then + if type(savename) ~= "string" then savename = file.basename(fullname) end + savename = file.replacesuffix(savename,"cfg") + runners.save_script_session(savename,save_list) + end + end + return true + end + else + -- logs.setverbose(true) + if filename == "" or filename == "help" then + local context = resolvers.find_file("mtx-context.lua") + logs.setverbose(true) + if context ~= "" then + local result = dir.glob((string.gsub(context,"mtx%-context","mtx-*"))) -- () needed + local valid = { } + table.sort(result) + for i=1,#result do + local scriptname = result[i] + local scriptbase = string.match(scriptname,".*mtx%-([^%-]-)%.lua") + if scriptbase then + local data = io.loaddata(scriptname) + local banner, version = string.match(data,"[\n\r]logs%.extendbanner%s*%(%s*[\"\']([^\n\r]+)%s*(%d+%.%d+)") + if banner then + valid[#valid+1] = { scriptbase, version, banner } + end + end + end + if #valid > 0 then + logs.reportbanner() + logs.reportline() + logs.simple("no script name given, known scripts:") + logs.simple() + for k=1,#valid do + local v = valid[k] + logs.simple("%-12s %4s %s",v[1],v[2],v[3]) + end + end + else + logs.simple("no script name given") + end + else + filename = file.addsuffix(filename,"lua") + if file.is_qualified_path(filename) then + logs.simple("unknown script '%s'",filename) + else + logs.simple("unknown script '%s' or 'mtx-%s'",filename,filename) + end + end + return false + end +end + +function runners.prefixes() + logs.reportbanner() + logs.reportline() + logs.simple(table.concat(resolvers.allprefixes(true)," ")) +end + +function runners.timedrun(filename) -- just for me + if filename and filename ~= "" then + runners.timed(function() os.execute(filename) end) + end +end + +function runners.timed(action) + statistics.timed(action) +end + +-- this is a bit dirty ... first we store the first filename and next we +-- split the arguments so that we only see the ones meant for this script +-- ... later we will use the second half + +local filename = environment.files[1] or "" +local ok = true + +local before, after = environment.split_arguments(filename) +environment.arguments_before, environment.arguments_after = before, after +environment.initialize_arguments(before) + +instance.engine = environment.argument("engine") or 'luatex' +instance.progname = environment.argument("progname") or 'context' +instance.lsrmode = environment.argument("lsr") or false + +-- maybe the unset has to go to this level + +local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] + +if environment.argument("usekpse") or environment.argument("forcekpse") or is_mkii_stub then + + os.setenv("engine","") + os.setenv("progname","") + + local remapper = { + otf = "opentype fonts", + ttf = "truetype fonts", + ttc = "truetype fonts", + pfb = "type1 fonts", + other = "other text files", + } + + local function kpse_initialized() + texconfig.kpse_init = true + local t = os.clock() + local k = kpse.original.new("luatex",instance.progname) + local dummy = k:find_file("mtxrun.lua") -- so that we're initialized + logs.simple("kpse fallback with progname '%s' initialized in %s seconds",instance.progname,os.clock()-t) + kpse_initialized = function() return k end + return k + end + + local find_file = resolvers.find_file + local show_path = resolvers.show_path + + if environment.argument("forcekpse") then + + function resolvers.find_file(name,kind) + return (kpse_initialized():find_file(resolvers.clean_path(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" + end + function resolvers.show_path(name) + return (kpse_initialized():show_path(name)) or "" + end + + elseif environment.argument("usekpse") or is_mkii_stub then + + resolvers.load() + + function resolvers.find_file(name,kind) + local found = find_file(name,kind) or "" + if found ~= "" then + return found + else + return (kpse_initialized():find_file(resolvers.clean_path(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" + end + end + function resolvers.show_path(name) + local found = show_path(name) or "" + if found ~= "" then + return found + else + return (kpse_initialized():show_path(name)) or "" + end + end + + end + +else + + resolvers.load() + +end + +if environment.argument("selfmerge") then + -- embed used libraries + utils.merger.selfmerge(own.name,own.libs,own.list) +elseif environment.argument("selfclean") then + -- remove embedded libraries + utils.merger.selfclean(own.name) +elseif environment.argument("selfupdate") then + logs.setverbose(true) + resolvers.update_script(own.name,"mtxrun") +elseif environment.argument("ctxlua") or environment.argument("internal") then + -- run a script by loading it (using libs) + ok = runners.execute_script(filename,true) +elseif environment.argument("script") or environment.argument("scripts") then + -- run a script by loading it (using libs), pass args + if is_mkii_stub then + -- execute mkii script + ok = runners.execute_script(filename,false,true) + else + ok = runners.execute_ctx_script(filename) + end +elseif environment.argument("execute") then + -- execute script + ok = runners.execute_script(filename) +elseif environment.argument("direct") then + -- equals bin: + ok = runners.execute_program(filename) +elseif environment.argument("edit") then + -- edit file + runners.edit_script(filename) +elseif environment.argument("launch") then + runners.launch_file(filename) +elseif environment.argument("make") then + -- make stubs + runners.handle_stubs(true) +elseif environment.argument("remove") then + -- remove stub + runners.handle_stubs(false) +elseif environment.argument("resolve") then + -- resolve string + runners.resolve_string(filename) +elseif environment.argument("locate") then + -- locate file + runners.locate_file(filename) +elseif environment.argument("platform")then + -- locate platform + runners.locate_platform() +elseif environment.argument("prefixes") then + runners.prefixes() +elseif environment.argument("timedrun") then + -- locate platform + runners.timedrun(filename) +elseif environment.argument("help") or filename=='help' or filename == "" then + logs.help(messages.help) + -- execute script +elseif filename:find("^bin:") then + ok = runners.execute_program(filename) +elseif is_mkii_stub then + -- execute mkii script + ok = runners.execute_script(filename,false,true) +else + ok = runners.execute_ctx_script(filename) + if not ok then + ok = runners.execute_script(filename) + end +end + +if os.platform == "unix" then + io.write("\n") +end + +if ok == false then ok = 1 elseif ok == true then ok = 0 end + +os.exit(ok) diff --git a/scripts/context/stubs/mswin/texexec.exe b/scripts/context/stubs/mswin/texexec.exe new file mode 100644 index 000000000..2d45f2749 Binary files /dev/null and b/scripts/context/stubs/mswin/texexec.exe differ diff --git a/scripts/context/stubs/mswin/texmfstart.exe b/scripts/context/stubs/mswin/texmfstart.exe new file mode 100644 index 000000000..2d45f2749 Binary files /dev/null and b/scripts/context/stubs/mswin/texmfstart.exe differ diff --git a/scripts/context/stubs/source/mtxrun_dll.c b/scripts/context/stubs/source/mtxrun_dll.c new file mode 100644 index 000000000..5b7cd31a0 --- /dev/null +++ b/scripts/context/stubs/source/mtxrun_dll.c @@ -0,0 +1,221 @@ +/************************************************************************ + + Copyright: + + Public Domain + Originally written in 2010 by Tomasz M. Trzeciak and Hans Hagen + + This program is derived from the 'runscript' program originally + written in 2009 by T.M. Trzeciak. It has been adapted for use in + ConTeXt MkIV. + + Comment: + + In ConTeXt MkIV we have two core scripts: luatools.lua and + mtxrun.lua where the second one is used to launch other scripts. + Normally a user will use a call like: + + mtxrun --script font --reload + + Here mtxrun is a lua script. In order to avoid the usage of a cmd + file on windows this runner will start texlua directly. If the + shared library luatex.dll is available, texlua will be started in + the same process avoiding thus any additional overhead. Otherwise + it will be spawned in a new proces. + + We also don't want to use other runners, like those that use kpse + to locate the script as this is exactly what mtxrun itself is doing + already. Therefore the runscript program is adapted to a more direct + approach suitable for mtxrun. + + Compilation: + + with gcc (size optimized): + + gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c + gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun + + with tcc (extra small size): + + tcc -shared -o mtxrun.dll mtxrun_dll.c + tcc -o mtxrun.exe mtxrun_exe.c mtxrun.def + +************************************************************************/ + +#include +#include +#include + +//#define STATIC +#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) +#define MAX_CMD 32768 +#define DIE(...) { \ + fprintf( stderr, "mtxrun: " ); \ + fprintf( stderr, __VA_ARGS__ ); \ + return 1; \ +} + +char texlua_name[] = "texlua"; // just a bare name, luatex strips the rest anyway +static char cmdline[MAX_CMD]; +static char dirpath[MAX_PATH]; +static char progname[MAX_PATH]; +static char scriptpath[MAX_PATH]; +static char luatexpath[MAX_PATH]; +HMODULE dllluatex = NULL; +typedef int ( *mainlikeproc )( int, char ** ); + +#ifdef STATIC +int main( int argc, char *argv[] ) +#else +__declspec(dllexport) int dllrunscript( int argc, char *argv[] ) +#endif +{ + char *s, *luatexfname, *argstr, **lua_argv; + int k, quoted, lua_argc; + int passprogname = 0; + + // directory of this module/executable + + HMODULE module_handle = GetModuleHandle( "mtxrun.dll" ); + // if ( module_handle == NULL ) exe path will be used, which is OK too + k = (int) GetModuleFileName( module_handle, dirpath, MAX_PATH ); + if ( !k || ( k == MAX_PATH ) ) + DIE( "unable to determine a valid module name\n" ); + s = strrchr(dirpath, '\\'); + if ( s == NULL ) DIE( "no directory part in module path: %s\n", dirpath ); + *(++s) = '\0'; //remove file name, leave trailing backslash + + // program name + + k = strlen(argv[0]); + while ( k && (argv[0][k-1] != '/') && (argv[0][k-1] != '\\') ) k--; + strcpy(progname, &argv[0][k]); + s = progname; + if ( s = strrchr(s, '.') ) *s = '\0'; // remove file extension part + + // script path + + strcpy( scriptpath, dirpath ); + k = strlen(progname); + if ( k < 6 ) k = 6; // in case the program name is shorter than "mtxrun" + if ( strlen(dirpath) + k + 4 >= MAX_PATH ) + DIE( "path too long: %s%s\n", dirpath, progname ); + if ( ( strcmpi(progname,"mtxrun") == 0 ) || ( strcmpi(progname,"luatools") == 0 ) ) { + strcat( scriptpath, progname ); + strcat( scriptpath, ".lua" ); + } else { + strcat( scriptpath, "mtxrun.lua" ); + if ( strcmpi(progname,"texmfstart") != 0 ) passprogname = 1; + } + if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES ) + DIE( "file not found: %s\n", scriptpath ); + + // find texlua.exe + + if ( !SearchPath( + getenv( "PATH" ), // path to search (optional) + "texlua.exe", // file name to search + NULL, // file extension to add (optional) + MAX_PATH, // output buffer size + luatexpath, // output buffer pointer + &luatexfname ) // pointer to a file part in the output buffer (optional) + ) DIE( "unable to locate texlua.exe on the search path" ); + + // link directly with luatex.dll if available in texlua's dir + + strcpy( luatexfname, "luatex.dll" ); + if ( dllluatex = LoadLibrary(luatexpath) ) + { + mainlikeproc dllluatexmain = (mainlikeproc) GetProcAddress( dllluatex, "dllluatexmain" ); + if ( dllluatexmain == NULL ) + DIE( "unable to locate dllluatexmain procedure in luatex.dll" ); + + // set up argument list for texlua script + + lua_argv = (char **)malloc( (argc + 4) * sizeof(char *) ); + if ( lua_argv == NULL ) DIE( "out of memory\n" ); + lua_argv[lua_argc=0] = texlua_name; + lua_argv[++lua_argc] = scriptpath; // script to execute + if (passprogname) { + lua_argv[++lua_argc] = "--script"; + lua_argv[++lua_argc] = progname; + } + for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k]; + lua_argv[++lua_argc] = NULL; + + // call texlua interpreter + // dllluatexmain never returns, but we pretend that it does + + k = dllluatexmain( lua_argc, lua_argv ); + if (lua_argv) free( lua_argv ); + return k; + } + + // we are still here, so no luatex.dll; spawn texlua.exe instead + + strcpy( luatexfname, "texlua.exe" ); + strcpy( cmdline, "\"" ); + strcat( cmdline, luatexpath ); + strcat( cmdline, "\" \"" ); + strcat( cmdline, scriptpath ); + strcat( cmdline, "\"" ); + if (passprogname) { + strcat( cmdline, " --script " ); + strcat( cmdline, progname ); + } + + argstr = GetCommandLine(); // get the command line of this process + if ( argstr == NULL ) DIE( "unable to retrieve the command line string\n" ); + + // skip over argv[0] in the argument string + // (it can contain embedded double quotes if launched from cmd.exe!) + + for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ ) + if (*argstr == '"') quoted = !quoted; + + // pass through all the arguments + + if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD ) + DIE( "command line string too long:\n%s%s\n", cmdline, argstr ); + strcat( cmdline, argstr ); + + // create child process + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW; + //si.dwFlags = STARTF_USESHOWWINDOW; + //si.wShowWindow = SW_HIDE ; // can be used to hide console window (requires STARTF_USESHOWWINDOW flag) + si.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); + si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE ); + si.hStdError = GetStdHandle( STD_ERROR_HANDLE ); + ZeroMemory( &pi, sizeof(pi) ); + + if( !CreateProcess( + NULL, // module name (uses command line if NULL) + cmdline, // command line + NULL, // process security atrributes + NULL, // thread security atrributes + TRUE, // handle inheritance + 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS + NULL, // pointer to environment block (uses parent if NULL) + NULL, // starting directory (uses parent if NULL) + &si, // STARTUPINFO structure + &pi ) // PROCESS_INFORMATION structure + ) DIE( "command execution failed: %s\n", cmdline ); + + DWORD ret = 0; + CloseHandle( pi.hThread ); // thread handle is not needed + if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) { + if ( !GetExitCodeProcess( pi.hProcess, &ret) ) + DIE( "unable to retrieve process exit code: %s\n", cmdline ); + } else DIE( "failed to wait for process termination: %s\n", cmdline ); + CloseHandle( pi.hProcess ); + + // propagate exit code from the child process + + return ret; + +} diff --git a/scripts/context/stubs/source/mtxrun_exe.c b/scripts/context/stubs/source/mtxrun_exe.c new file mode 100644 index 000000000..0c27c272e --- /dev/null +++ b/scripts/context/stubs/source/mtxrun_exe.c @@ -0,0 +1,8 @@ +// This is the .exe part of the mtxrun program, see mtxrun_dll.c +// for more details. + +#include + +__declspec(dllimport) int dllrunscript( int argc, char *argv[] ); + +int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); } diff --git a/scripts/context/stubs/source/readme.txt b/scripts/context/stubs/source/readme.txt new file mode 100644 index 000000000..354d85b09 --- /dev/null +++ b/scripts/context/stubs/source/readme.txt @@ -0,0 +1,36 @@ +Copyright: + +The originally 'runscript' program was written by in 2009 by +T.M.Trzeciak and is public domain. This derived mtxrun program +is an adapted version by Hans Hagen. + +Comment: + +In ConTeXt MkIV we have two core scripts: luatools.lua and +mtxrun.lua where the second one is used to launch other scripts. +Normally a user will use a call like: + +mtxrun --script font --reload + +Here mtxrun is a lua script. In order to avoid the usage of a cmd +file on windows this runner will start texlua directly. In TeXlive +a runner is added for each cmd file but we don't want that overhead +(and extra files). By using an exe we can call these scripts in +batch files without the need for using call. + +We also don't want to use other runners, like those that use kpse +to locate the script as this is exactly what mtxrun itself is doing +already. Therefore the runscript program is adapted to a more direct +approach suitable for mtxrun. + +Compilation: + +with gcc (size optimized): + +gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c +gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun + +with tcc (ver. 0.9.24), extra small size + +tcc -shared -o runscript.dll runscript_dll.c +tcc -o runscript.exe runscript_exe.c runscript.def diff --git a/scripts/context/stubs/unix/context b/scripts/context/stubs/unix/context new file mode 100644 index 000000000..fa62ba8d1 --- /dev/null +++ b/scripts/context/stubs/unix/context @@ -0,0 +1,2 @@ +#!/bin/sh +mtxrun --script context "$@" diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools new file mode 100644 index 000000000..1d87322c1 --- /dev/null +++ b/scripts/context/stubs/unix/luatools @@ -0,0 +1,8185 @@ +#!/usr/bin/env texlua + +if not modules then modules = { } end modules ['luatools'] = { + version = 1.001, + comment = "companion to context.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +-- one can make a stub: +-- +-- #!/bin/sh +-- env LUATEXDIR=/....../texmf/scripts/context/lua texlua luatools.lua "$@" + +-- Although this script is part of the ConTeXt distribution it is +-- relatively indepent of ConTeXt. The same is true for some of +-- the luat files. We may may make them even less dependent in +-- the future. As long as Luatex is under development the +-- interfaces and names of functions may change. + +-- For the sake of independence we optionally can merge the library +-- code here. It's too much code, but that does not harm. Much of the +-- library code is used elsewhere. We don't want dependencies on +-- Lua library paths simply because these scripts are located in the +-- texmf tree and not in some Lua path. Normally this merge is not +-- needed when texmfstart is used, or when the proper stub is used or +-- when (windows) suffix binding is active. + +texlua = true + +-- begin library merge + + + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 +local unpack = unpack or table.unpack + +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 + +-- rougly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack) + +function table.sub(t,i,j) + return { unpack(t,i,j) } +end + +function table.replace(a,b) + for k,v in next, b do + a[k] = v + end +end + +-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice) + +function table.is_empty(t) -- 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 +--~ 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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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')) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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") + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + +-- 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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-tra'] = { + version = 1.001, + comment = "companion to trac-tra.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + +debugger = debugger or { } + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in next, counters do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ print("") +--~ debugger.showstats(print,3) + +setters = setters or { } +setters.data = setters.data or { } + +--~ local function set(t,what,value) +--~ local data, done = t.data, t.done +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end + +local function set(t,what,value) + local data, done = t.data, t.done + if type(what) == "string" then + what = aux.settings_to_hash(what) -- inefficient but ok + end + for w, v in next, what do + if v == "" then + v = value + else + v = toboolean(v) + end + for d, f in next, data do + if done[d] then + -- prevent recursion due to wildcards + elseif find(d,w) then + done[d] = true + for i=1,#f do + f[i](v) + end + end + end + end +end + +local function reset(t) + for d, f in next, t.data do + for i=1,#f do + f[i](false) + end + end +end + +local function enable(t,what) + set(t,what,true) +end + +local function disable(t,what) + local data = t.data + if not what or what == "" then + t.done = { } + reset(t) + else + set(t,what,false) + end +end + +function setters.register(t,what,...) + local data = t.data + what = lower(what) + local w = data[what] + if not w then + w = { } + data[what] = w + end + for _, fnc in next, { ... } do + local typ = type(fnc) + if typ == "function" then + w[#w+1] = fnc + elseif typ == "string" then + w[#w+1] = function(value) set(t,fnc,value,nesting) end + end + end +end + +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(tostring(what))) + t.enable, t.done = e, { } +end + +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(tostring(what))) + t.disable, t.done = e, { } +end + +function setters.reset(t) + t.done = { } + reset(t) +end + +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) + local user, system = { }, { } + for l=1,#list do + local what = list[l] + if find(what,"^%*") then + system[#system+1] = what + else + user[#user+1] = what + end + end + return user, system +end + +function setters.show(t) + commands.writestatus("","") + local list = setters.list(t) + for k=1,#list do + commands.writestatus(t.name,list[k]) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singular tracker + +-- we could make this into a module + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") +experiments = setters.new("experiments") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) +local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +local e = experiments.enable +local d = experiments.disable + +function experiments.enable(...) + commands.writestatus("experiments","enabling: %s",concat({...}," ")) + e(...) +end + +function experiments.disable(...) + commands.writestatus("experiments","disabling: %s",concat({...}," ")) + d(...) +end + +-- a useful example + +directives.register("system.nostatistics", function(v) + statistics.enable = not v +end) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-inf'] = { + version = 1.001, + comment = "companion to trac-inf.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 statusinfo, n, registered = { }, 0, { } + +statistics = statistics or { } + +statistics.enable = true +statistics.threshold = 0.05 + +-- timing functions + +local clock = os.gettimeofday or os.clock + +local notimer + +function statistics.hastimer(instance) + return instance and instance.starttime +end + +function statistics.resettiming(instance) + if not instance then + notimer = { timing = 0, loadtime = 0 } + else + instance.timing, instance.loadtime = 0, 0 + end +end + +function statistics.starttiming(instance) + if not instance then + notimer = { } + instance = notimer + end + local it = instance.timing + if not it then + it = 0 + end + if it == 0 then + instance.starttime = clock() + if not instance.loadtime then + instance.loadtime = 0 + end + else +--~ logs.report("system","nested timing (%s)",tostring(instance)) + end + instance.timing = it + 1 +end + +function statistics.stoptiming(instance, report) + if not instance then + instance = notimer + end + if instance then + local it = instance.timing + if it > 1 then + instance.timing = it - 1 + else + local starttime = instance.starttime + if starttime then + local stoptime = clock() + local loadtime = stoptime - starttime + instance.stoptime = stoptime + instance.loadtime = instance.loadtime + loadtime + if report then + statistics.report("load time %0.3f",loadtime) + end + instance.timing = 0 + return loadtime + end + end + end + return 0 +end + +function statistics.elapsedtime(instance) + if not instance then + instance = notimer + end + return format("%0.3f",(instance and instance.loadtime) or 0) +end + +function statistics.elapsedindeed(instance) + if not instance then + instance = notimer + end + local t = (instance and instance.loadtime) or 0 + return t > statistics.threshold +end + +function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds + if statistics.elapsedindeed(instance) then + return format("%s seconds %s", statistics.elapsedtime(instance),rest or "") + end +end + +-- general function + +function statistics.register(tag,fnc) + if statistics.enable and type(fnc) == "function" then + local rt = registered[tag] or (#statusinfo + 1) + statusinfo[rt] = { tag, fnc } + registered[tag] = rt + if #tag > n then n = #tag end + end +end + +function statistics.show(reporter) + if statistics.enable then + if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end + -- this code will move + local register = statistics.register + register("luatex banner", function() + return string.lower(status.banner) + end) + register("control sequences", function() + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) + end) + register("callbacks", function() + local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 + return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total) + end) + register("current memory usage", statistics.memused) + register("runtime",statistics.runtime) +-- -- + for i=1,#statusinfo do + local s = statusinfo[i] + local r = s[2]() + if r then + reporter(s[1],r,n) + end + end + texio.write_nl("") -- final newline + statistics.enable = false + end +end + +function statistics.show_job_stat(tag,data,n) + texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data)) +end + +function statistics.memused() -- no math.round yet -) + local round = math.round or math.floor + return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) +end + +if statistics.runtime then + -- already loaded and set +elseif luatex and luatex.starttime then + statistics.starttime = luatex.starttime + statistics.loadtime = 0 + statistics.timing = 0 +else + statistics.starttiming(statistics) +end + +function statistics.runtime() + statistics.stoptiming(statistics) + return statistics.formatruntime(statistics.elapsedtime(statistics)) +end + +function statistics.formatruntime(runtime) + return format("%s seconds", statistics.elapsedtime(statistics)) +end + +function statistics.timed(action,report) + local timer = { } + report = report or logs.simple + statistics.starttiming(timer) + action() + statistics.stoptiming(timer) + report("total runtime: %s",statistics.elapsedtime(timer)) +end + +-- where, not really the best spot for this: + +commands = commands or { } + +local timer + +function commands.resettimer() + statistics.resettiming(timer) + statistics.starttiming(timer) +end + +function commands.elapsedtime() + statistics.stoptiming(timer) + tex.sprint(statistics.elapsedtime(timer)) +end + +commands.resettimer() + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-log'] = { + version = 1.001, + comment = "companion to trac-log.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is old code that needs an overhaul + +--~ io.stdout:setvbuf("no") +--~ io.stderr:setvbuf("no") + +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch +local texcount = tex and tex.count + +if texlua then + write_nl = print + write = io.write +end + +--[[ldx-- +

This is a prelude to a more extensive logging module. For the sake +of parsing log files, in addition to the standard logging we will +provide an structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

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

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

+--ldx]]-- + +logs.moreinfo = [[ +more information about ConTeXt and the tools that come with it can be found at: + +maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context +webpage : http://www.pragma-ade.nl / http://tex.aanhet.net +wiki : http://contextgarden.net +]] + +logs.levels = { + ['error'] = 1, + ['warning'] = 2, + ['info'] = 3, + ['debug'] = 4, +} + +logs.functions = { + 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct', + 'start_run', 'stop_run', + 'start_page_number', 'stop_page_number', + 'report_output_pages', 'report_output_log', + 'report_tex_stat', 'report_job_stat', + 'show_open', 'show_close', 'show_load', +} + +logs.tracers = { +} + +logs.level = 0 +logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex")) + +function logs.set_level(level) + logs.level = logs.levels[level] or level +end + +function logs.set_method(method) + for _, v in next, logs.functions do + logs[v] = logs[method][v] or function() end + end +end + +-- tex logging + +function logs.tex.report(category,fmt,...) -- new + if fmt then + write_nl(category .. " | " .. format(fmt,...)) + else + write_nl(category .. " |") + end +end + +function logs.tex.line(fmt,...) -- new + if fmt then + write_nl(format(fmt,...)) + else + write_nl("") + end +end + +--~ function logs.tex.start_page_number() +--~ local real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +--~ if real > 0 then +--~ if user > 0 then +--~ if sub > 0 then +--~ write(format("[%s.%s.%s",real,user,sub)) +--~ else +--~ write(format("[%s.%s",real,user)) +--~ end +--~ else +--~ write(format("[%s",real)) +--~ end +--~ else +--~ write("[-") +--~ end +--~ end + +--~ function logs.tex.stop_page_number() +--~ write("]") +--~ end + +local real, user, sub + +function logs.tex.start_page_number() + real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +end + +function logs.tex.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + logs.report("pages", "flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + logs.report("pages", "flushing realpage %s, userpage %s",real,user) + end + else + logs.report("pages", "flushing realpage %s",real) + end + else + logs.report("pages", "flushing page") + end + io.flush() +end + +logs.tex.report_job_stat = statistics.show_job_stat + +-- xml logging + +function logs.xml.report(category,fmt,...) -- new + if fmt then + write_nl(format("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + end +end + +function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end +function logs.xml.stop () if logs.level > 0 then tw("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",level+1,name)) +end + +-- + +local name, banner = 'report', 'context' + +local function report(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + +local function simple(fmt,...) + if fmt then + write_nl(format("%s | %s",name,format(fmt,...))) + else + write_nl(format("%s |",name)) + end +end + +function logs.setprogram(_name_,_banner_,_verbose_) + name, banner = _name_, _banner_ + if _verbose_ then + trackers.enable("resolvers.locating") + end + logs.set_method("tex") + logs.report = report -- also used in libraries + logs.simple = simple -- only used in scripts ! + if utils then + utils.report = simple + end + logs.verbose = _verbose_ +end + +function logs.setverbose(what) + if what then + trackers.enable("resolvers.locating") + else + trackers.disable("resolvers.locating") + end + logs.verbose = what or false +end + +function logs.extendbanner(_banner_,_verbose_) + banner = banner .. " | ".. _banner_ + if _verbose_ ~= nil then + logs.setverbose(what) + end +end + +logs.verbose = false +logs.report = logs.tex.report +logs.simple = logs.tex.report + +function logs.reportlines(str) -- todo: + for line in gmatch(str,"(.-)[\n\r]") do + logs.report(line) + end +end + +function logs.reportline() -- for scripts too + logs.report() +end + +logs.simpleline = logs.reportline + +function logs.reportbanner() -- for scripts too + logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() + logs.reportline() + logs.reportlines(message) + local moreinfo = logs.moreinfo or "" + if moreinfo ~= "" and option ~= "nomoreinfo" then + logs.reportline() + logs.reportlines(moreinfo) + end +end + +logs.set_level('error') +logs.set_method('tex') + +function logs.system(whereto,process,jobname,category,...) + for i=1,10 do + local f = io.open(whereto,"a") + if f then + f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...))) + f:close() + break + else + sleep(0.1) + end + end +end + +--~ local syslogname = "oeps.xxx" +--~ +--~ for i=1,10 do +--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123") +--~ end + +function logs.fatal(where,...) + logs.report(where,"fatal error: %s, aborting now",format(...)) + os.exit() +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 } + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 { } + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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' + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure +-- end library merge + +-- We initialize some characteristics of this program. We need to +-- do this before we load the libraries, else own.name will not be +-- properly set (handy for selfcleaning the file). It's an ugly +-- looking piece of code. + +own = { } + +own.libs = { -- todo: check which ones are really needed + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-io.lua', + 'l-number.lua', + 'l-set.lua', + 'l-os.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-boolean.lua', + 'l-unicode.lua', + 'l-math.lua', + 'l-utils.lua', + 'l-aux.lua', + 'trac-tra.lua', + 'luat-env.lua', + 'trac-inf.lua', + 'trac-log.lua', + 'data-res.lua', + 'data-tmp.lua', +-- 'data-pre.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-tex.lua', +-- 'data-bin.lua', +-- 'data-zip.lua', +-- 'data-crl.lua', +-- 'data-lua.lua', + 'data-kps.lua', -- so that we can replace kpsewhich + 'data-aux.lua', -- updater + 'data-lst.lua', -- lister +} + +-- We need this hack till luatex is fixed. + +if arg and arg[0] == 'luatex' 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 + +-- End of hack. + +own.name = (environment and environment.ownname) or arg[0] or 'luatools.lua' +own.path = string.match(own.name,"^(.+)[\\/].-$") or "." +own.list = { '.' } + +if own.path ~= '.' then + table.insert(own.list,own.path) +end + +table.insert(own.list,own.path.."/../../../tex/context/base") +table.insert(own.list,own.path.."/mtx") +table.insert(own.list,own.path.."/../sources") + +function locate_libs() + for _, lib in pairs(own.libs) do + for _, pth in pairs(own.list) do + local filename = string.gsub(pth .. "/" .. lib,"\\","/") + local codeblob = loadfile(filename) + if codeblob then + codeblob() + own.list = { pth } -- speed up te search + break + end + end + end +end + +if not resolvers then + locate_libs() +end + +if not resolvers then + print("") + print("Luatools is unable to start up due to lack of libraries. You may") + print("try to run 'lua luatools.lua --selfmerge' in the path where this") + print("script is located (normally under ..../scripts/context/lua) which") + print("will make luatools library independent.") + os.exit() +end + +logs.setprogram('LuaTools',"TDS Management Tool 1.32",environment.arguments["verbose"] or false) + +local instance = resolvers.reset() + +resolvers.defaultlibs = { -- not all are needed (this will become: context.lus (lua spec) + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-boolean.lua', + 'l-number.lua', + 'l-unicode.lua', + 'l-os.lua', + 'l-io.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-utils.lua', + 'l-dimen.lua', + 'trac-inf.lua', + 'trac-tra.lua', + 'trac-log.lua', + 'luat-env.lua', -- here ? + 'data-res.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-tmp.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-pre.lua', + 'data-tex.lua', + 'data-bin.lua', +-- 'data-zip.lua', +-- 'data-clr.lua', + 'data-lua.lua', + 'data-ctx.lua', + 'luat-fio.lua', + 'luat-cnf.lua', +} + +instance.engine = environment.arguments["engine"] or 'luatex' +instance.progname = environment.arguments["progname"] or 'context' +instance.luaname = environment.arguments["luafile"] or "" -- environment.ownname or "" +instance.lualibs = environment.arguments["lualibs"] or table.concat(resolvers.defaultlibs,",") +instance.allresults = environment.arguments["all"] or false +instance.pattern = environment.arguments["pattern"] or nil +instance.sortdata = environment.arguments["sort"] or false +instance.kpseonly = not environment.arguments["all"] or false +instance.my_format = environment.arguments["format"] or instance.format + +if type(instance.pattern) == 'boolean' then + logs.simple("invalid pattern specification") + instance.pattern = nil +end + +if environment.arguments["trace"] then resolvers.settrace(environment.arguments["trace"]) end + +local trackspec = environment.argument("trackers") or environment.argument("track") + +if trackspec then + trackers.enable(trackspec) +end + +runners = runners or { } +messages = messages or { } + +messages.no_ini_file = [[ +There is no lua initialization file found. This file can be forced by the +"--progname" directive, or specified with "--luaname", or it is derived +automatically from the formatname (aka jobname). It may be that you have +to regenerate the file database using "luatools --generate". +]] + +messages.help = [[ +--generate generate file database +--variables show configuration variables +--expansions show expanded variables +--configurations show configuration order +--expand-braces expand complex variable +--expand-path expand variable (resolve paths) +--expand-var expand variable (resolve references) +--show-path show path expansion of ... +--var-value report value of variable +--find-file report file location +--find-path report path of file +--make or --ini make luatex format +--run or --fmt= run luatex format +--luafile=str lua inifile (default is .lua) +--lualibs=list libraries to assemble (optional when --compile) +--compile assemble and compile lua inifile +--verbose give a bit more info +--all show all found files +--sort sort cached data +--engine=str target engine +--progname=str format or backend +--pattern=str filter variables +--trackers=list enable given trackers +]] + +function runners.make_format(texname) + local instance = resolvers.instance + if texname and texname ~= "" then + if resolvers.usecache then + local path = file.join(caches.setpath("formats")) -- maybe platform + if path and lfs then + lfs.chdir(path) + end + end + local barename = texname:gsub("%.%a+$","") + if barename == texname then + texname = texname .. ".tex" + end + local fullname = resolvers.find_files(texname)[1] or "" + if fullname == "" then + logs.simple("no tex file with name: %s",texname) + else + local luaname, lucname, luapath, lualibs = "", "", "", { } + -- the following is optional, since context.lua can also + -- handle this collect and compile business + if environment.arguments["compile"] then + if luaname == "" then luaname = barename end + logs.simple("creating initialization file: %s",luaname) + luapath = file.dirname(luaname) + if luapath == "" then + luapath = file.dirname(texname) + end + if luapath == "" then + luapath = file.dirname(resolvers.find_files(texname)[1] or "") + end + lualibs = string.split(instance.lualibs,",") + luaname = file.basename(barename .. ".lua") + lucname = file.basename(barename .. ".luc") + -- todo: when this fails, we can just copy the merged libraries from + -- luatools since they are normally the same, at least for context + if lualibs[1] then + local firstlib = file.join(luapath,lualibs[1]) + if not lfs.isfile(firstlib) then + local foundname = resolvers.find_files(lualibs[1])[1] + if foundname then + logs.simple("located library path: %s",luapath) + luapath = file.dirname(foundname) + end + end + end + logs.simple("using library path: %s",luapath) + logs.simple("using lua libraries: %s",table.join(lualibs," ")) + utils.merger.selfcreate(lualibs,luapath,luaname) + local strip = resolvers.boolean_variable("LUACSTRIP", true) + if utils.lua.compile(luaname,lucname,false,strip) and io.exists(lucname) then + luaname = lucname + logs.simple("using compiled initialization file: %s",lucname) + else + logs.simple("using uncompiled initialization file: %s",luaname) + end + else + local what = { instance.luaname, instance.progname, barename } + for k=1,#what do + local v = string.gsub(what[k]..".lua","%.lua%.lua$",".lua") + if v and (v ~= "") then + luaname = resolvers.find_files(v)[1] or "" + if luaname ~= "" then + break + end + end + end + end + if environment.arguments["noluc"] then + luaname = luaname:gsub("%.luc$",".lua") -- make this an option + end + if luaname == "" then + if logs.verbose then + logs.simplelines(messages.no_ini_file) + logs.simple("texname : %s",texname) + logs.simple("luaname : %s",instance.luaname) + logs.simple("progname: %s",instance.progname) + logs.simple("barename: %s",barename) + end + else + logs.simple("using lua initialization file: %s",luaname) + local mp = dir.glob(file.removesuffix(file.basename(luaname)).."-*.mem") + if mp and #mp > 0 then + for i=1,#mp do + local name = mp[i] + logs.simple("removing related mplib format %s", file.basename(name)) + os.remove(name) + end + end + local flags = { + "--ini", + "--lua=" .. string.quote(luaname) + } + local bs = (os.platform == "unix" and "\\\\") or "\\" -- todo: make a function + local command = "luatex ".. table.concat(flags," ") .. " " .. string.quote(fullname) .. " " .. bs .. "dump" + logs.simple("running command: %s\n",command) + os.spawn(command) + -- todo: do a dummy run that generates the related metafun and mfplain formats + end + end + else + logs.simple("no tex file given") + end +end + +function runners.run_format(name,data,more) + -- hm, rather old code here; we can now use the file.whatever functions + if name and (name ~= "") then + local barename = name:gsub("%.%a+$","") + local fmtname = "" + 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) + barename = fmtname:gsub("%.%a+$","") + if fmtname == "" then + logs.simple("no format with name: %s",name) + else + local luaname = barename .. ".luc" + local f = io.open(luaname) + if not f then + luaname = barename .. ".lua" + f = io.open(luaname) + end + if f then + f:close() + local command = "luatex --fmt=" .. string.quote(barename) .. " --lua=" .. string.quote(luaname) .. " " .. string.quote(data) .. " " .. (more ~= "" and string.quote(more) or "") + logs.simple("running command: %s",command) + os.spawn(command) + else + logs.simple("using format name: %s",fmtname) + logs.simple("no luc/lua with name: %s",barename) + end + end + end +end + +local ok = true + +-- private option --noluc for testing errors in the stub + +if environment.arguments["find-file"] then + resolvers.load() + instance.format = environment.arguments["format"] or instance.format + if instance.pattern then + instance.allresults = true + resolvers.for_files(resolvers.find_files, { instance.pattern }, instance.my_format) + else + resolvers.for_files(resolvers.find_files, environment.files, instance.my_format) + end +elseif environment.arguments["find-path"] then + resolvers.load() + local path = resolvers.find_file(environment.files[1], instance.my_format) + if logs.verbose then + logs.simple(file.dirname(path)) + else + print(file.dirname(path)) + end +elseif environment.arguments["run"] then + resolvers.load("nofiles") -- ! no need for loading databases + logs.setverbose(true) + runners.run_format(environment.files[1] or "",environment.files[2] or "",environment.files[3] or "") +elseif environment.arguments["fmt"] then + resolvers.load("nofiles") -- ! no need for loading databases + logs.setverbose(true) + runners.run_format(environment.arguments["fmt"], environment.files[1] or "",environment.files[2] or "") +elseif environment.arguments["expand-braces"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_braces, environment.files) +elseif environment.arguments["expand-path"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_path, environment.files) +elseif environment.arguments["expand-var"] or environment.arguments["expand-variable"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.expand_var, environment.files) +elseif environment.arguments["show-path"] or environment.arguments["path-value"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.show_path, environment.files) +elseif environment.arguments["var-value"] or environment.arguments["show-value"] then + resolvers.load("nofiles") + resolvers.for_files(resolvers.var_value, environment.files) +elseif environment.arguments["format-path"] then + resolvers.load() + logs.simple(caches.setpath("format")) +elseif instance.pattern then -- brrr + resolvers.load() + instance.format = environment.arguments["format"] or instance.format + instance.allresults = true + resolvers.for_files(resolvers.find_files, { instance.pattern }, instance.my_format) +elseif environment.arguments["generate"] then + instance.renewcache = true + logs.setverbose(true) + resolvers.load() +elseif environment.arguments["make"] or environment.arguments["ini"] or environment.arguments["compile"] then + resolvers.load() + logs.setverbose(true) + runners.make_format(environment.files[1] or "") +elseif environment.arguments["selfmerge"] then + utils.merger.selfmerge(own.name,own.libs,own.list) +elseif environment.arguments["selfclean"] then + utils.merger.selfclean(own.name) +elseif environment.arguments["selfupdate"] then + resolvers.load() + logs.setverbose(true) + resolvers.update_script(own.name,"luatools") +elseif environment.arguments["variables"] or environment.arguments["show-variables"] then + resolvers.load("nofiles") + resolvers.listers.variables() +elseif environment.arguments["expansions"] or environment.arguments["show-expansions"] then + resolvers.load("nofiles") + resolvers.listers.expansions() +elseif environment.arguments["configurations"] or environment.arguments["show-configurations"] then + resolvers.load("nofiles") + resolvers.listers.configurations() +elseif environment.arguments["help"] or (environment.files[1]=='help') or (#environment.files==0) then + logs.help(messages.help) +else + resolvers.load() + resolvers.for_files(resolvers.find_files, environment.files, instance.my_format) +end + +if logs.verbose then + logs.simpleline() + logs.simple("runtime: %0.3f seconds",os.runtime()) +end + +if os.platform == "unix" then + io.write("\n") +end diff --git a/scripts/context/stubs/unix/metatex b/scripts/context/stubs/unix/metatex new file mode 100644 index 000000000..f0c6b65d4 --- /dev/null +++ b/scripts/context/stubs/unix/metatex @@ -0,0 +1,2 @@ +#!/bin/sh +mtxrun --script metatex "$@" diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun new file mode 100644 index 000000000..b99327692 --- /dev/null +++ b/scripts/context/stubs/unix/mtxrun @@ -0,0 +1,12639 @@ +#!/usr/bin/env texlua + +if not modules then modules = { } end modules ['mtxrun'] = { + version = 1.001, + comment = "runner, lua replacement for texmfstart.rb", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + + +-- one can make a stub: +-- +-- #!/bin/sh +-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@" + +-- filename : mtxrun.lua +-- comment : companion to context.tex +-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL +-- copyright: PRAGMA ADE / ConTeXt Development Team +-- license : see context related readme files + +-- This script is based on texmfstart.rb but does not use kpsewhich to +-- locate files. Although kpse is a library it never came to opening up +-- its interface to other programs (esp scripting languages) and so we +-- do it ourselves. The lua variant evolved out of an experimental ruby +-- one. Interesting is that using a scripting language instead of c does +-- not have a speed penalty. Actually the lua variant is more efficient, +-- especially when multiple calls to kpsewhich are involved. The lua +-- library also gives way more control. + +-- to be done / considered +-- +-- support for --exec or make it default +-- support for jar files (or maybe not, never used, too messy) +-- support for $RUBYINPUTS cum suis (if still needed) +-- remember for subruns: _CTX_K_V_#{original}_ +-- remember for subruns: _CTX_K_S_#{original}_ +-- remember for subruns: TEXMFSTART.#{original} [tex.rb texmfstart.rb] + +texlua = true + +-- begin library merge + + + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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')) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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") + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-tra'] = { + version = 1.001, + comment = "companion to trac-tra.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + +debugger = debugger or { } + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in next, counters do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ print("") +--~ debugger.showstats(print,3) + +setters = setters or { } +setters.data = setters.data or { } + +--~ local function set(t,what,value) +--~ local data, done = t.data, t.done +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end + +local function set(t,what,value) + local data, done = t.data, t.done + if type(what) == "string" then + what = aux.settings_to_hash(what) -- inefficient but ok + end + for w, v in next, what do + if v == "" then + v = value + else + v = toboolean(v) + end + for d, f in next, data do + if done[d] then + -- prevent recursion due to wildcards + elseif find(d,w) then + done[d] = true + for i=1,#f do + f[i](v) + end + end + end + end +end + +local function reset(t) + for d, f in next, t.data do + for i=1,#f do + f[i](false) + end + end +end + +local function enable(t,what) + set(t,what,true) +end + +local function disable(t,what) + local data = t.data + if not what or what == "" then + t.done = { } + reset(t) + else + set(t,what,false) + end +end + +function setters.register(t,what,...) + local data = t.data + what = lower(what) + local w = data[what] + if not w then + w = { } + data[what] = w + end + for _, fnc in next, { ... } do + local typ = type(fnc) + if typ == "function" then + w[#w+1] = fnc + elseif typ == "string" then + w[#w+1] = function(value) set(t,fnc,value,nesting) end + end + end +end + +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(tostring(what))) + t.enable, t.done = e, { } +end + +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(tostring(what))) + t.disable, t.done = e, { } +end + +function setters.reset(t) + t.done = { } + reset(t) +end + +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) + local user, system = { }, { } + for l=1,#list do + local what = list[l] + if find(what,"^%*") then + system[#system+1] = what + else + user[#user+1] = what + end + end + return user, system +end + +function setters.show(t) + commands.writestatus("","") + local list = setters.list(t) + for k=1,#list do + commands.writestatus(t.name,list[k]) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singular tracker + +-- we could make this into a module + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") +experiments = setters.new("experiments") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) +local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +local e = experiments.enable +local d = experiments.disable + +function experiments.enable(...) + commands.writestatus("experiments","enabling: %s",concat({...}," ")) + e(...) +end + +function experiments.disable(...) + commands.writestatus("experiments","disabling: %s",concat({...}," ")) + d(...) +end + +-- a useful example + +directives.register("system.nostatistics", function(v) + statistics.enable = not v +end) + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-inf'] = { + version = 1.001, + comment = "companion to trac-inf.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 statusinfo, n, registered = { }, 0, { } + +statistics = statistics or { } + +statistics.enable = true +statistics.threshold = 0.05 + +-- timing functions + +local clock = os.gettimeofday or os.clock + +local notimer + +function statistics.hastimer(instance) + return instance and instance.starttime +end + +function statistics.resettiming(instance) + if not instance then + notimer = { timing = 0, loadtime = 0 } + else + instance.timing, instance.loadtime = 0, 0 + end +end + +function statistics.starttiming(instance) + if not instance then + notimer = { } + instance = notimer + end + local it = instance.timing + if not it then + it = 0 + end + if it == 0 then + instance.starttime = clock() + if not instance.loadtime then + instance.loadtime = 0 + end + else +--~ logs.report("system","nested timing (%s)",tostring(instance)) + end + instance.timing = it + 1 +end + +function statistics.stoptiming(instance, report) + if not instance then + instance = notimer + end + if instance then + local it = instance.timing + if it > 1 then + instance.timing = it - 1 + else + local starttime = instance.starttime + if starttime then + local stoptime = clock() + local loadtime = stoptime - starttime + instance.stoptime = stoptime + instance.loadtime = instance.loadtime + loadtime + if report then + statistics.report("load time %0.3f",loadtime) + end + instance.timing = 0 + return loadtime + end + end + end + return 0 +end + +function statistics.elapsedtime(instance) + if not instance then + instance = notimer + end + return format("%0.3f",(instance and instance.loadtime) or 0) +end + +function statistics.elapsedindeed(instance) + if not instance then + instance = notimer + end + local t = (instance and instance.loadtime) or 0 + return t > statistics.threshold +end + +function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds + if statistics.elapsedindeed(instance) then + return format("%s seconds %s", statistics.elapsedtime(instance),rest or "") + end +end + +-- general function + +function statistics.register(tag,fnc) + if statistics.enable and type(fnc) == "function" then + local rt = registered[tag] or (#statusinfo + 1) + statusinfo[rt] = { tag, fnc } + registered[tag] = rt + if #tag > n then n = #tag end + end +end + +function statistics.show(reporter) + if statistics.enable then + if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end + -- this code will move + local register = statistics.register + register("luatex banner", function() + return string.lower(status.banner) + end) + register("control sequences", function() + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) + end) + register("callbacks", function() + local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 + return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total) + end) + register("current memory usage", statistics.memused) + register("runtime",statistics.runtime) +-- -- + for i=1,#statusinfo do + local s = statusinfo[i] + local r = s[2]() + if r then + reporter(s[1],r,n) + end + end + texio.write_nl("") -- final newline + statistics.enable = false + end +end + +function statistics.show_job_stat(tag,data,n) + texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data)) +end + +function statistics.memused() -- no math.round yet -) + local round = math.round or math.floor + return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) +end + +if statistics.runtime then + -- already loaded and set +elseif luatex and luatex.starttime then + statistics.starttime = luatex.starttime + statistics.loadtime = 0 + statistics.timing = 0 +else + statistics.starttiming(statistics) +end + +function statistics.runtime() + statistics.stoptiming(statistics) + return statistics.formatruntime(statistics.elapsedtime(statistics)) +end + +function statistics.formatruntime(runtime) + return format("%s seconds", statistics.elapsedtime(statistics)) +end + +function statistics.timed(action,report) + local timer = { } + report = report or logs.simple + statistics.starttiming(timer) + action() + statistics.stoptiming(timer) + report("total runtime: %s",statistics.elapsedtime(timer)) +end + +-- where, not really the best spot for this: + +commands = commands or { } + +local timer + +function commands.resettimer() + statistics.resettiming(timer) + statistics.starttiming(timer) +end + +function commands.elapsedtime() + statistics.stoptiming(timer) + tex.sprint(statistics.elapsedtime(timer)) +end + +commands.resettimer() + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['trac-log'] = { + version = 1.001, + comment = "companion to trac-log.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is old code that needs an overhaul + +--~ io.stdout:setvbuf("no") +--~ io.stderr:setvbuf("no") + +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch +local texcount = tex and tex.count + +if texlua then + write_nl = print + write = io.write +end + +--[[ldx-- +

This is a prelude to a more extensive logging module. For the sake +of parsing log files, in addition to the standard logging we will +provide an structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

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

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

+--ldx]]-- + +logs.moreinfo = [[ +more information about ConTeXt and the tools that come with it can be found at: + +maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context +webpage : http://www.pragma-ade.nl / http://tex.aanhet.net +wiki : http://contextgarden.net +]] + +logs.levels = { + ['error'] = 1, + ['warning'] = 2, + ['info'] = 3, + ['debug'] = 4, +} + +logs.functions = { + 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct', + 'start_run', 'stop_run', + 'start_page_number', 'stop_page_number', + 'report_output_pages', 'report_output_log', + 'report_tex_stat', 'report_job_stat', + 'show_open', 'show_close', 'show_load', +} + +logs.tracers = { +} + +logs.level = 0 +logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex")) + +function logs.set_level(level) + logs.level = logs.levels[level] or level +end + +function logs.set_method(method) + for _, v in next, logs.functions do + logs[v] = logs[method][v] or function() end + end +end + +-- tex logging + +function logs.tex.report(category,fmt,...) -- new + if fmt then + write_nl(category .. " | " .. format(fmt,...)) + else + write_nl(category .. " |") + end +end + +function logs.tex.line(fmt,...) -- new + if fmt then + write_nl(format(fmt,...)) + else + write_nl("") + end +end + +--~ function logs.tex.start_page_number() +--~ local real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +--~ if real > 0 then +--~ if user > 0 then +--~ if sub > 0 then +--~ write(format("[%s.%s.%s",real,user,sub)) +--~ else +--~ write(format("[%s.%s",real,user)) +--~ end +--~ else +--~ write(format("[%s",real)) +--~ end +--~ else +--~ write("[-") +--~ end +--~ end + +--~ function logs.tex.stop_page_number() +--~ write("]") +--~ end + +local real, user, sub + +function logs.tex.start_page_number() + real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno +end + +function logs.tex.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + logs.report("pages", "flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + logs.report("pages", "flushing realpage %s, userpage %s",real,user) + end + else + logs.report("pages", "flushing realpage %s",real) + end + else + logs.report("pages", "flushing page") + end + io.flush() +end + +logs.tex.report_job_stat = statistics.show_job_stat + +-- xml logging + +function logs.xml.report(category,fmt,...) -- new + if fmt then + write_nl(format("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + end +end + +function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end +function logs.xml.stop () if logs.level > 0 then tw("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",level+1,name)) +end + +-- + +local name, banner = 'report', 'context' + +local function report(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + +local function simple(fmt,...) + if fmt then + write_nl(format("%s | %s",name,format(fmt,...))) + else + write_nl(format("%s |",name)) + end +end + +function logs.setprogram(_name_,_banner_,_verbose_) + name, banner = _name_, _banner_ + if _verbose_ then + trackers.enable("resolvers.locating") + end + logs.set_method("tex") + logs.report = report -- also used in libraries + logs.simple = simple -- only used in scripts ! + if utils then + utils.report = simple + end + logs.verbose = _verbose_ +end + +function logs.setverbose(what) + if what then + trackers.enable("resolvers.locating") + else + trackers.disable("resolvers.locating") + end + logs.verbose = what or false +end + +function logs.extendbanner(_banner_,_verbose_) + banner = banner .. " | ".. _banner_ + if _verbose_ ~= nil then + logs.setverbose(what) + end +end + +logs.verbose = false +logs.report = logs.tex.report +logs.simple = logs.tex.report + +function logs.reportlines(str) -- todo: + for line in gmatch(str,"(.-)[\n\r]") do + logs.report(line) + end +end + +function logs.reportline() -- for scripts too + logs.report() +end + +logs.simpleline = logs.reportline + +function logs.reportbanner() -- for scripts too + logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() + logs.reportline() + logs.reportlines(message) + local moreinfo = logs.moreinfo or "" + if moreinfo ~= "" and option ~= "nomoreinfo" then + logs.reportline() + logs.reportlines(moreinfo) + end +end + +logs.set_level('error') +logs.set_method('tex') + +function logs.system(whereto,process,jobname,category,...) + for i=1,10 do + local f = io.open(whereto,"a") + if f then + f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...))) + f:close() + break + else + sleep(0.1) + end + end +end + +--~ local syslogname = "oeps.xxx" +--~ +--~ for i=1,10 do +--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123") +--~ end + +function logs.fatal(where,...) + logs.report(where,"fatal error: %s, aborting now",format(...)) + os.exit() +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 } + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 { } + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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') + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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' + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +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")) + + +end -- of closure +-- end library merge + +own = { } -- not local + +own.libs = { -- todo: check which ones are really needed + 'l-string.lua', + 'l-lpeg.lua', + 'l-table.lua', + 'l-io.lua', + 'l-number.lua', + 'l-set.lua', + 'l-os.lua', + 'l-file.lua', + 'l-md5.lua', + 'l-url.lua', + 'l-dir.lua', + 'l-boolean.lua', + 'l-math.lua', +-- 'l-unicode.lua', +-- 'l-tex.lua', + 'l-utils.lua', + 'l-aux.lua', +-- 'l-xml.lua', + 'trac-tra.lua', + 'lxml-tab.lua', + 'lxml-lpt.lua', +-- 'lxml-ent.lua', + 'lxml-mis.lua', + 'lxml-aux.lua', + 'lxml-xml.lua', + 'luat-env.lua', + 'trac-inf.lua', + 'trac-log.lua', + 'data-res.lua', + 'data-tmp.lua', + 'data-pre.lua', + 'data-inp.lua', + 'data-out.lua', + 'data-con.lua', + 'data-use.lua', +-- 'data-tex.lua', +-- 'data-bin.lua', + 'data-zip.lua', + 'data-crl.lua', + 'data-lua.lua', + 'data-kps.lua', -- so that we can replace kpsewhich + 'data-aux.lua', -- updater + 'data-tmf.lua', -- tree files + -- needed ? + 'luat-sta.lua', -- states +} + +-- We need this hack till luatex is fixed. +-- +-- for k,v in pairs(arg) do print(k,v) end + +if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then + arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil +end + +-- End of hack. + +own.name = (environment and environment.ownname) or arg[0] or 'luatools.lua' + + +own.path = string.match(own.name,"^(.+)[\\/].-$") or "." +own.list = { '.' } +if own.path ~= '.' then + table.insert(own.list,own.path) +end +table.insert(own.list,own.path.."/../../../tex/context/base") +table.insert(own.list,own.path.."/mtx") +table.insert(own.list,own.path.."/../sources") + +local function locate_libs() + for _, lib in pairs(own.libs) do + for _, pth in pairs(own.list) do + local filename = string.gsub(pth .. "/" .. lib,"\\","/") + local codeblob = loadfile(filename) + if codeblob then + codeblob() + own.list = { pth } -- speed up te search + break + end + end + end +end + +if not resolvers then + locate_libs() +end + +if not resolvers then + print("") + print("Mtxrun is unable to start up due to lack of libraries. You may") + print("try to run 'lua mtxrun.lua --selfmerge' in the path where this") + print("script is located (normally under ..../scripts/context/lua) which") + print("will make this script library independent.") + os.exit() +end + +logs.setprogram('MTXrun',"TDS Runner Tool 1.24",environment.arguments["verbose"] or false) + +local instance = resolvers.reset() + +local trackspec = environment.argument("trackers") or environment.argument("track") + +if trackspec then + trackers.enable(trackspec) +end + +runners = runners or { } -- global +messages = messages or { } + +messages.help = [[ +--script run an mtx script (lua prefered method) (--noquotes), no script gives list +--execute run a script or program (texmfstart method) (--noquotes) +--resolve resolve prefixed arguments +--ctxlua run internally (using preloaded libs) +--internal run script using built in libraries (same as --ctxlua) +--locate locate given filename + +--autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' +--tree=pathtotree use given texmf tree (default file: 'setuptex.tmf') +--environment=name use given (tmf) environment file +--path=runpath go to given path before execution +--ifchanged=filename only execute when given file has changed (md checksum) +--iftouched=old,new only execute when given file has changed (time stamp) + +--make create stubs for (context related) scripts +--remove remove stubs (context related) scripts +--stubpath=binpath paths where stubs wil be written +--windows create windows (mswin) stubs +--unix create unix (linux) stubs + +--verbose give a bit more info +--trackers=list enable given trackers +--engine=str target engine +--progname=str format or backend + +--edit launch editor with found file +--launch (--all) launch files like manuals, assumes os support + +--timedrun run a script an time its run +--autogenerate regenerate databases if needed (handy when used to run context in an editor) + +--usekpse use kpse as fallback (when no mkiv and cache installed, often slower) +--forcekpse force using kpse (handy when no mkiv and cache installed but less functionality) + +--prefixes show supported prefixes +]] + +runners.applications = { + ["lua"] = "luatex --luaonly", + ["luc"] = "luatex --luaonly", + ["pl"] = "perl", + ["py"] = "python", + ["rb"] = "ruby", +} + +runners.suffixes = { + 'rb', 'lua', 'py', 'pl' +} + +runners.registered = { + texexec = { 'texexec.rb', false }, -- context mkii runner (only tool not to be luafied) + texutil = { 'texutil.rb', true }, -- old perl based index sorter for mkii (old versions need it) + texfont = { 'texfont.pl', true }, -- perl script that makes mkii font metric files + texfind = { 'texfind.pl', false }, -- perltk based tex searching tool, mostly used at pragma + texshow = { 'texshow.pl', false }, -- perltk based context help system, will be luafied + -- texwork = { 'texwork.pl', false }, -- perltk based editing environment, only used at pragma + makempy = { 'makempy.pl', true }, + mptopdf = { 'mptopdf.pl', true }, + pstopdf = { 'pstopdf.rb', true }, -- converts ps (and some more) images, does some cleaning (replaced) +-- examplex = { 'examplex.rb', false }, + concheck = { 'concheck.rb', false }, + runtools = { 'runtools.rb', true }, + textools = { 'textools.rb', true }, + tmftools = { 'tmftools.rb', true }, + ctxtools = { 'ctxtools.rb', true }, + rlxtools = { 'rlxtools.rb', true }, + pdftools = { 'pdftools.rb', true }, + mpstools = { 'mpstools.rb', true }, +-- exatools = { 'exatools.rb', true }, + xmltools = { 'xmltools.rb', true }, +-- luatools = { 'luatools.lua', true }, + mtxtools = { 'mtxtools.rb', true }, + pdftrimwhite = { 'pdftrimwhite.pl', false } +} + +runners.launchers = { + windows = { }, + unix = { } +} + +-- like runners.libpath("framework"): looks on script's subpath + +function runners.libpath(...) + package.prepend_libpath(file.dirname(environment.ownscript),...) + package.prepend_libpath(file.dirname(environment.ownname) ,...) +end + +function runners.prepare() + local checkname = environment.argument("ifchanged") + if checkname and checkname ~= "" then + local oldchecksum = file.loadchecksum(checkname) + local newchecksum = file.checksum(checkname) + if oldchecksum == newchecksum then + logs.simple("file '%s' is unchanged",checkname) + return "skip" + else + logs.simple("file '%s' is changed, processing started",checkname) + end + file.savechecksum(checkname) + end + local oldname, newname = string.split(environment.argument("iftouched") or "", ",") + if oldname and newname and oldname ~= "" and newname ~= "" then + if not file.needs_updating(oldname,newname) then + logs.simple("file '%s' and '%s' have same age",oldname,newname) + return "skip" + else + logs.simple("file '%s' is older than '%s'",oldname,newname) + end + end + local tree = environment.argument('tree') or "" + if environment.argument('autotree') then + tree = os.getenv('TEXMFSTART_TREE') or os.getenv('TEXMFSTARTTREE') or tree + end + if tree and tree ~= "" then + resolvers.load_tree(tree) + end + local env = environment.argument('environment') or "" + if env and env ~= "" then + for _,e in pairs(string.split(env)) do + -- maybe force suffix when not given + resolvers.load_tree(e) + end + end + local runpath = environment.argument("path") + if runpath and not lfs.chdir(runpath) then + logs.simple("unable to change to path '%s'",runpath) + return "error" + end + return "run" +end + +function runners.execute_script(fullname,internal,nosplit) + local noquote = environment.argument("noquotes") + if fullname and fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + instance.progname = environment.argument("progname") or instance.progname + instance.format = environment.argument("format") or instance.format + local path, name, suffix, result = file.dirname(fullname), file.basename(fullname), file.extname(fullname), "" + if path ~= "" then + result = fullname + elseif name then + name = name:gsub("^int[%a]*:",function() + internal = true + return "" + end ) + name = name:gsub("^script:","") + if suffix == "" and runners.registered[name] and runners.registered[name][1] then + name = runners.registered[name][1] + suffix = file.extname(name) + end + if suffix == "" then + -- loop over known suffixes + for _,s in pairs(runners.suffixes) do + result = resolvers.find_file(name .. "." .. s, 'texmfscripts') + if result ~= "" then + break + end + end + elseif runners.applications[suffix] then + result = resolvers.find_file(name, 'texmfscripts') + else + -- maybe look on path + result = resolvers.find_file(name, 'other text files') + end + end + if result and result ~= "" then + if not no_split then + local before, after = environment.split_arguments(fullname) -- already done + environment.arguments_before, environment.arguments_after = before, after + end + if internal then + arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end + environment.ownscript = result + dofile(result) + else + local binary = runners.applications[file.extname(result)] + if binary and binary ~= "" then + result = binary .. " " .. result + end + local command = result .. " " .. environment.reconstruct_commandline(environment.arguments_after,noquote) + if logs.verbose then + logs.simpleline() + logs.simple("executing: %s",command) + logs.simpleline() + logs.simpleline() + io.flush() + end + -- no os.exec because otherwise we get the wrong return value + local code = os.execute(command) -- maybe spawn + if code == 0 then + return true + else + if binary then + binary = file.addsuffix(binary,os.binsuffix) + for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do + if lfs.isfile(file.join(p,binary)) then + return false + end + end + logs.simpleline() + logs.simple("This script needs '%s' which seems not to be installed.",binary) + logs.simpleline() + end + return false + end + end + end + end + end + return false +end + +function runners.execute_program(fullname) + local noquote = environment.argument("noquotes") + if fullname and fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + local before, after = environment.split_arguments(fullname) + environment.initialize_arguments(after) + fullname = fullname:gsub("^bin:","") + local command = fullname .. " " .. (environment.reconstruct_commandline(after or "",noquote) or "") + logs.simpleline() + logs.simple("executing: %s",command) + logs.simpleline() + logs.simpleline() + io.flush() + local code = os.exec(command) -- (fullname,unpack(after)) does not work / maybe spawn + return code == 0 + end + end + return false +end + +-- the --usekpse flag will fallback on kpse (hm, we can better update mtx-stubs) + +local windows_stub = '@echo off\013\010setlocal\013\010set ownpath=%%~dp0%%\013\010texlua "%%ownpath%%mtxrun.lua" --usekpse --execute %s %%*\013\010endlocal\013\010' +local unix_stub = '#!/bin/sh\010mtxrun --usekpse --execute %s \"$@\"\010' + +function runners.handle_stubs(create) + local stubpath = environment.argument('stubpath') or '.' -- 'auto' no longer subpathssupported + local windows = environment.argument('windows') or environment.argument('mswin') or false + local unix = environment.argument('unix') or environment.argument('linux') or false + if not windows and not unix then + if os.platform == "unix" then + unix = true + else + windows = true + end + end + for _,v in pairs(runners.registered) do + local name, doit = v[1], v[2] + if doit then + local base = string.gsub(file.basename(name), "%.(.-)$", "") + if create then + if windows then + io.savedata(file.join(stubpath,base..".bat"),string.format(windows_stub,name)) + logs.simple("windows stub for '%s' created",base) + end + if unix then + io.savedata(file.join(stubpath,base),string.format(unix_stub,name)) + logs.simple("unix stub for '%s' created",base) + end + else + if windows and (os.remove(file.join(stubpath,base..'.bat')) or os.remove(file.join(stubpath,base..'.cmd'))) then + logs.simple("windows stub for '%s' removed", base) + end + if unix and (os.remove(file.join(stubpath,base)) or os.remove(file.join(stubpath,base..'.sh'))) then + logs.simple("unix stub for '%s' removed",base) + end + end + end + end +end + +function runners.resolve_string(filename) + if filename and filename ~= "" then + runners.report_location(resolvers.resolve(filename)) + end +end + +function runners.locate_file(filename) + -- differs from texmfstart where locate appends .com .exe .bat ... todo + if filename and filename ~= "" then + runners.report_location(resolvers.find_given_file(filename)) + end +end + +function runners.locate_platform() + runners.report_location(os.platform) +end + +function runners.report_location(result) + if logs.verbose then + logs.simpleline() + if result and result ~= "" then + logs.simple(result) + else + logs.simple("not found") + end + else + io.write(result) + end +end + +function runners.edit_script(filename) -- we assume that vim is present on most systems + local editor = os.getenv("MTXRUN_EDITOR") or os.getenv("TEXMFSTART_EDITOR") or os.getenv("EDITOR") or 'vim' + local rest = resolvers.resolve(filename) + if rest ~= "" then + local command = editor .. " " .. rest + if logs.verbose then + logs.simpleline() + logs.simple("starting editor: %s",command) + logs.simple_line() + logs.simple_line() + end + os.launch(command) + end +end + +function runners.save_script_session(filename, list) + local t = { } + for i=1,#list do + local key = list[i] + t[key] = environment.arguments[key] + end + io.savedata(filename,table.serialize(t,true)) +end + +function runners.load_script_session(filename) + if lfs.isfile(filename) then + local t = io.loaddata(filename) + if t then + t = loadstring(t) + if t then t = t() end + for key, value in pairs(t) do + environment.arguments[key] = value + end + end + end +end + +function resolvers.launch(str) + -- maybe we also need to test on mtxrun.launcher.suffix environment + -- variable or on windows consult the assoc and ftype vars and such + local launchers = runners.launchers[os.platform] if launchers then + local suffix = file.extname(str) if suffix then + local runner = launchers[suffix] if runner then + str = runner .. " " .. str + end + end + end + os.launch(str) +end + +function runners.launch_file(filename) + instance.allresults = true + logs.setverbose(true) + local pattern = environment.arguments["pattern"] + if not pattern or pattern == "" then + pattern = filename + end + if not pattern or pattern == "" then + logs.simple("provide name or --pattern=") + else + local t = resolvers.find_files(pattern) + if not t or #t == 0 then + t = resolvers.find_files("*/" .. pattern) + end + if not t or #t == 0 then + t = resolvers.find_files("*/" .. pattern .. "*") + end + if t and #t > 0 then + if environment.arguments["all"] then + for _, v in pairs(t) do + logs.simple("launching %s", v) + resolvers.launch(v) + end + else + logs.simple("launching %s", t[1]) + resolvers.launch(t[1]) + end + else + logs.simple("no match for %s", pattern) + end + end +end + +function runners.find_mtx_script(filename) + local function found(name) + local path = file.dirname(name) + if path and path ~= "" then + return false + else + local fullname = own and own.path and file.join(own.path,name) + return io.exists(fullname) and fullname + end + end + filename = file.addsuffix(filename,"lua") + local basename = file.removesuffix(file.basename(filename)) + local suffix = file.extname(filename) + -- qualified path, raw name + local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename + if fullname and fullname ~= "" then + return fullname + end + -- current path, raw name + fullname = "./" .. filename + fullname = io.exists(fullname) and fullname + if fullname and fullname ~= "" then + return fullname + end + -- mtx- prefix checking + local mtxprefix = (filename:find("^mtx%-") and "") or "mtx-" + -- context namespace, mtx- + fullname = mtxprefix .. filename + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx-s + fullname = mtxprefix .. basename .. "s" .. "." .. suffix + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx- + fullname = mtxprefix .. basename:gsub("s$","") .. "." .. suffix + fullname = found(fullname) or resolvers.find_file(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, just + fullname = resolvers.find_file(filename) + return fullname +end + +function runners.execute_ctx_script(filename) + local arguments = environment.arguments_after + local fullname = runners.find_mtx_script(filename) or "" + if file.extname(fullname) == "cld" then + -- handy in editors where we force --autopdf + logs.simple("running cld script: %s",filename) + table.insert(arguments,1,fullname) + table.insert(arguments,"--autopdf") + fullname = runners.find_mtx_script("context") or "" + end + -- retry after generate but only if --autogenerate + if fullname == "" and environment.argument("autogenerate") then -- might become the default + instance.renewcache = true + logs.setverbose(true) + resolvers.load() + -- + fullname = runners.find_mtx_script(filename) or "" + end + -- that should do it + if fullname ~= "" then + local state = runners.prepare() + if state == 'error' then + return false + elseif state == 'skip' then + return true + elseif state == "run" then + -- load and save ... kind of undocumented + arg = { } for _,v in pairs(arguments) do arg[#arg+1] = resolvers.resolve(v) end + environment.initialize_arguments(arg) + local loadname = environment.arguments['load'] + if loadname then + if type(loadname) ~= "string" then loadname = file.basename(fullname) end + loadname = file.replacesuffix(loadname,"cfg") + runners.load_script_session(loadname) + end + filename = environment.files[1] + if logs.verbose then + logs.simple("using script: %s\n",fullname) + end + environment.ownscript = fullname + dofile(fullname) + local savename = environment.arguments['save'] + if savename then + local save_list = runners.save_list + if save_list and next(save_list) then + if type(savename) ~= "string" then savename = file.basename(fullname) end + savename = file.replacesuffix(savename,"cfg") + runners.save_script_session(savename,save_list) + end + end + return true + end + else + -- logs.setverbose(true) + if filename == "" or filename == "help" then + local context = resolvers.find_file("mtx-context.lua") + logs.setverbose(true) + if context ~= "" then + local result = dir.glob((string.gsub(context,"mtx%-context","mtx-*"))) -- () needed + local valid = { } + table.sort(result) + for i=1,#result do + local scriptname = result[i] + local scriptbase = string.match(scriptname,".*mtx%-([^%-]-)%.lua") + if scriptbase then + local data = io.loaddata(scriptname) + local banner, version = string.match(data,"[\n\r]logs%.extendbanner%s*%(%s*[\"\']([^\n\r]+)%s*(%d+%.%d+)") + if banner then + valid[#valid+1] = { scriptbase, version, banner } + end + end + end + if #valid > 0 then + logs.reportbanner() + logs.reportline() + logs.simple("no script name given, known scripts:") + logs.simple() + for k=1,#valid do + local v = valid[k] + logs.simple("%-12s %4s %s",v[1],v[2],v[3]) + end + end + else + logs.simple("no script name given") + end + else + filename = file.addsuffix(filename,"lua") + if file.is_qualified_path(filename) then + logs.simple("unknown script '%s'",filename) + else + logs.simple("unknown script '%s' or 'mtx-%s'",filename,filename) + end + end + return false + end +end + +function runners.prefixes() + logs.reportbanner() + logs.reportline() + logs.simple(table.concat(resolvers.allprefixes(true)," ")) +end + +function runners.timedrun(filename) -- just for me + if filename and filename ~= "" then + runners.timed(function() os.execute(filename) end) + end +end + +function runners.timed(action) + statistics.timed(action) +end + +-- this is a bit dirty ... first we store the first filename and next we +-- split the arguments so that we only see the ones meant for this script +-- ... later we will use the second half + +local filename = environment.files[1] or "" +local ok = true + +local before, after = environment.split_arguments(filename) +environment.arguments_before, environment.arguments_after = before, after +environment.initialize_arguments(before) + +instance.engine = environment.argument("engine") or 'luatex' +instance.progname = environment.argument("progname") or 'context' +instance.lsrmode = environment.argument("lsr") or false + +-- maybe the unset has to go to this level + +local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] + +if environment.argument("usekpse") or environment.argument("forcekpse") or is_mkii_stub then + + os.setenv("engine","") + os.setenv("progname","") + + local remapper = { + otf = "opentype fonts", + ttf = "truetype fonts", + ttc = "truetype fonts", + pfb = "type1 fonts", + other = "other text files", + } + + local function kpse_initialized() + texconfig.kpse_init = true + local t = os.clock() + local k = kpse.original.new("luatex",instance.progname) + local dummy = k:find_file("mtxrun.lua") -- so that we're initialized + logs.simple("kpse fallback with progname '%s' initialized in %s seconds",instance.progname,os.clock()-t) + kpse_initialized = function() return k end + return k + end + + local find_file = resolvers.find_file + local show_path = resolvers.show_path + + if environment.argument("forcekpse") then + + function resolvers.find_file(name,kind) + return (kpse_initialized():find_file(resolvers.clean_path(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" + end + function resolvers.show_path(name) + return (kpse_initialized():show_path(name)) or "" + end + + elseif environment.argument("usekpse") or is_mkii_stub then + + resolvers.load() + + function resolvers.find_file(name,kind) + local found = find_file(name,kind) or "" + if found ~= "" then + return found + else + return (kpse_initialized():find_file(resolvers.clean_path(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" + end + end + function resolvers.show_path(name) + local found = show_path(name) or "" + if found ~= "" then + return found + else + return (kpse_initialized():show_path(name)) or "" + end + end + + end + +else + + resolvers.load() + +end + +if environment.argument("selfmerge") then + -- embed used libraries + utils.merger.selfmerge(own.name,own.libs,own.list) +elseif environment.argument("selfclean") then + -- remove embedded libraries + utils.merger.selfclean(own.name) +elseif environment.argument("selfupdate") then + logs.setverbose(true) + resolvers.update_script(own.name,"mtxrun") +elseif environment.argument("ctxlua") or environment.argument("internal") then + -- run a script by loading it (using libs) + ok = runners.execute_script(filename,true) +elseif environment.argument("script") or environment.argument("scripts") then + -- run a script by loading it (using libs), pass args + if is_mkii_stub then + -- execute mkii script + ok = runners.execute_script(filename,false,true) + else + ok = runners.execute_ctx_script(filename) + end +elseif environment.argument("execute") then + -- execute script + ok = runners.execute_script(filename) +elseif environment.argument("direct") then + -- equals bin: + ok = runners.execute_program(filename) +elseif environment.argument("edit") then + -- edit file + runners.edit_script(filename) +elseif environment.argument("launch") then + runners.launch_file(filename) +elseif environment.argument("make") then + -- make stubs + runners.handle_stubs(true) +elseif environment.argument("remove") then + -- remove stub + runners.handle_stubs(false) +elseif environment.argument("resolve") then + -- resolve string + runners.resolve_string(filename) +elseif environment.argument("locate") then + -- locate file + runners.locate_file(filename) +elseif environment.argument("platform")then + -- locate platform + runners.locate_platform() +elseif environment.argument("prefixes") then + runners.prefixes() +elseif environment.argument("timedrun") then + -- locate platform + runners.timedrun(filename) +elseif environment.argument("help") or filename=='help' or filename == "" then + logs.help(messages.help) + -- execute script +elseif filename:find("^bin:") then + ok = runners.execute_program(filename) +elseif is_mkii_stub then + -- execute mkii script + ok = runners.execute_script(filename,false,true) +else + ok = runners.execute_ctx_script(filename) + if not ok then + ok = runners.execute_script(filename) + end +end + +if os.platform == "unix" then + io.write("\n") +end + +if ok == false then ok = 1 elseif ok == true then ok = 0 end + +os.exit(ok) diff --git a/scripts/context/stubs/unix/texexec b/scripts/context/stubs/unix/texexec new file mode 100644 index 000000000..cd5900ff8 --- /dev/null +++ b/scripts/context/stubs/unix/texexec @@ -0,0 +1,2 @@ +#!/bin/sh +mtxrun --usekpse --execute texexec "$@" diff --git a/scripts/context/stubs/unix/texmfstart b/scripts/context/stubs/unix/texmfstart new file mode 100644 index 000000000..1799b3579 --- /dev/null +++ b/scripts/context/stubs/unix/texmfstart @@ -0,0 +1,2 @@ +#!/bin/sh +mtxrun --usekpse "$@" 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 +% \|{