From 40e5e0f114c759b17af50cde80677a9612d4d41b Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Tue, 2 Jun 2009 09:30:00 +0200 Subject: beta 2009.06.02 09:30 --- metapost/context/base/mp-grph.mp | 2 +- metapost/context/base/mp-mlib.mp | 29 +- metapost/context/base/mp-text.mp | 8 +- metapost/context/base/mp-tool.mp | 6 + scripts/context/lua/mtx-server.lua | 1 + tex/context/base/anch-bar.tex | 194 + tex/context/base/anch-pgr.tex | 1687 +++++++ tex/context/base/anch-pos.lua | 107 + tex/context/base/anch-pos.mkii | 873 ++++ tex/context/base/anch-pos.mkiv | 828 ++++ tex/context/base/anch-snc.tex | 179 + tex/context/base/attr-ini.mkiv | 153 + tex/context/base/attr-ini.tex | 153 - tex/context/base/back-ini.mkiv | 896 ++++ tex/context/base/back-ini.tex | 896 ---- tex/context/base/back-pdf.mkiv | 3226 +++++++++++++ tex/context/base/back-pdf.tex | 3226 ------------- tex/context/base/buff-ini.lua | 472 ++ tex/context/base/buff-ini.mkii | 348 ++ tex/context/base/buff-ini.mkiv | 314 ++ tex/context/base/buff-ver.mkii | 1334 ++++++ tex/context/base/buff-ver.mkiv | 1049 ++++ tex/context/base/char-act.mkiv | 125 + tex/context/base/char-enc.mkiv | 18 + tex/context/base/char-enc.tex | 18 - tex/context/base/char-ini.mkiv | 74 + tex/context/base/char-ini.tex | 74 - tex/context/base/char-utf.mkiv | 47 + tex/context/base/char-utf.tex | 47 - tex/context/base/chem-str-test.tex | 560 --- tex/context/base/colo-ini.mkiv | 316 +- tex/context/base/cont-log.tex | 56 +- tex/context/base/cont-new.tex | 2 +- tex/context/base/context.mkii | 81 +- tex/context/base/context.mkiv | 150 +- tex/context/base/context.tex | 2 +- tex/context/base/core-bar.tex | 194 - tex/context/base/core-blk.tex | 548 --- tex/context/base/core-box.tex | 954 ---- tex/context/base/core-buf.lua | 499 -- tex/context/base/core-buf.mkii | 348 -- tex/context/base/core-buf.mkiv | 314 -- tex/context/base/core-dat.tex | 248 - tex/context/base/core-des.tex | 921 ---- tex/context/base/core-fig.tex | 559 --- tex/context/base/core-fld.mkii | 1080 ----- tex/context/base/core-fld.mkiv | 1079 ----- tex/context/base/core-hlp.tex | 169 - tex/context/base/core-inc.lua | 854 ---- tex/context/base/core-inc.mkii | 1265 ----- tex/context/base/core-inc.mkiv | 417 -- tex/context/base/core-int.mkii | 2217 --------- tex/context/base/core-int.mkiv | 2036 -------- tex/context/base/core-itm.tex | 1344 ------ tex/context/base/core-lst.tex | 1150 ----- tex/context/base/core-mar.tex | 318 -- tex/context/base/core-mat.tex | 2923 ------------ tex/context/base/core-nav.mkii | 379 -- tex/context/base/core-nav.mkiv | 425 -- tex/context/base/core-not.tex | 1440 ------ tex/context/base/core-num.tex | 151 - tex/context/base/core-obj.lua | 54 - tex/context/base/core-obj.mkii | 371 -- tex/context/base/core-obj.mkiv | 234 - tex/context/base/core-pgr.tex | 1687 ------- tex/context/base/core-pos.lua | 107 - tex/context/base/core-pos.mkii | 873 ---- tex/context/base/core-pos.mkiv | 828 ---- tex/context/base/core-ref.tex | 3038 ------------ tex/context/base/core-reg.tex | 1242 ----- tex/context/base/core-rul.lua | 42 - tex/context/base/core-rul.mkii | 3637 -------------- tex/context/base/core-rul.mkiv | 3675 -------------- tex/context/base/core-sec.tex | 2572 ---------- tex/context/base/core-snc.tex | 179 - tex/context/base/core-spa.mkiv | 2 +- tex/context/base/core-swd.tex | 125 - tex/context/base/core-syn.tex | 438 -- tex/context/base/core-trf.tex | 577 --- tex/context/base/core-ver.mkii | 1334 ------ tex/context/base/core-ver.mkiv | 1179 ----- tex/context/base/core-vis.tex | 748 --- tex/context/base/font-otn.lua | 2 +- tex/context/base/grph-fig.mkii | 559 +++ tex/context/base/grph-fig.mkiv | 559 +++ tex/context/base/grph-inc.lua | 854 ++++ tex/context/base/grph-inc.mkii | 1215 +++++ tex/context/base/grph-inc.mkiv | 417 ++ tex/context/base/grph-trf.mkii | 577 +++ tex/context/base/grph-trf.mkiv | 577 +++ tex/context/base/luat-bas.mkiv | 64 + tex/context/base/luat-bas.tex | 64 - tex/context/base/luat-cod.mkiv | 161 + tex/context/base/luat-cod.tex | 161 - tex/context/base/luat-ini.mkiv | 218 + tex/context/base/luat-ini.tex | 218 - tex/context/base/luat-lib.mkiv | 65 + tex/context/base/luat-lib.tex | 65 - tex/context/base/m-datastrc.tex | 228 + tex/context/base/meta-fig.mkiv | 4 +- tex/context/base/meta-ini.mkiv | 137 +- tex/context/base/mlib-ctx.mkiv | 81 + tex/context/base/mlib-ctx.tex | 81 - tex/context/base/mlib-pdf.lua | 3 +- tex/context/base/mlib-pdf.mkiv | 93 + tex/context/base/mlib-pdf.tex | 92 - tex/context/base/mlib-pps.lua | 216 +- tex/context/base/mlib-pps.mkiv | 61 + tex/context/base/mlib-pps.tex | 61 - tex/context/base/mlib-run.lua | 43 +- tex/context/base/mult-sys.tex | 2 + tex/context/base/node-fin.mkiv | 78 + tex/context/base/node-fin.tex | 78 - tex/context/base/node-ini.mkiv | 106 + tex/context/base/node-ini.tex | 106 - tex/context/base/node-par.mkiv | 60 + tex/context/base/node-par.tex | 60 - tex/context/base/pack-box.mkii | 954 ++++ tex/context/base/pack-box.mkiv | 954 ++++ tex/context/base/pack-lyr.mkii | 753 +++ tex/context/base/pack-lyr.mkiv | 753 +++ tex/context/base/pack-obj.lua | 54 + tex/context/base/pack-obj.mkii | 371 ++ tex/context/base/pack-obj.mkiv | 234 + tex/context/base/pack-rul.lua | 42 + tex/context/base/pack-rul.mkii | 3637 ++++++++++++++ tex/context/base/pack-rul.mkiv | 3675 ++++++++++++++ tex/context/base/page-flt.tex | 2159 --------- tex/context/base/page-lyr.tex | 753 --- tex/context/base/page-num.tex | 534 --- tex/context/base/pret-lua.lua | 259 + tex/context/base/pret-mp.lua | 235 + tex/context/base/pret-tex.lua | 85 + tex/context/base/s-abr-01.tex | 7 +- tex/context/base/scrn-fld.mkii | 1080 +++++ tex/context/base/scrn-fld.mkiv | 1079 +++++ tex/context/base/scrn-hlp.mkii | 171 + tex/context/base/scrn-hlp.mkiv | 171 + tex/context/base/scrn-int.mkii | 2217 +++++++++ tex/context/base/scrn-int.mkiv | 2036 ++++++++ tex/context/base/scrn-nav.mkii | 379 ++ tex/context/base/scrn-nav.mkiv | 425 ++ tex/context/base/scrp-ini.mkiv | 91 + tex/context/base/scrp-ini.tex | 91 - tex/context/base/strc-bkm.mkiv | 92 + tex/context/base/strc-bkm.tex | 90 - tex/context/base/strc-blk.mkii | 548 +++ tex/context/base/strc-blk.mkiv | 110 + tex/context/base/strc-blk.tex | 110 - tex/context/base/strc-def.mkiv | 302 ++ tex/context/base/strc-def.tex | 302 -- tex/context/base/strc-des.mkii | 921 ++++ tex/context/base/strc-des.mkiv | 994 ++++ tex/context/base/strc-des.tex | 1018 ---- tex/context/base/strc-doc.lua | 4 +- tex/context/base/strc-doc.mkiv | 166 + tex/context/base/strc-doc.tex | 166 - tex/context/base/strc-flt.mkii | 2143 +++++++++ tex/context/base/strc-flt.mkiv | 2173 +++++++++ tex/context/base/strc-flt.tex | 2173 --------- tex/context/base/strc-ini.mkiv | 88 + tex/context/base/strc-ini.tex | 88 - tex/context/base/strc-itm.mkii | 1328 ++++++ tex/context/base/strc-itm.mkiv | 1195 +++++ tex/context/base/strc-itm.tex | 1195 ----- tex/context/base/strc-lst.mkii | 1150 +++++ tex/context/base/strc-lst.mkiv | 944 ++++ tex/context/base/strc-lst.tex | 944 ---- tex/context/base/strc-mar.mkii | 318 ++ tex/context/base/strc-mar.mkiv | 493 ++ tex/context/base/strc-mar.tex | 493 -- tex/context/base/strc-mat.mkii | 2923 ++++++++++++ tex/context/base/strc-mat.mkiv | 933 ++++ tex/context/base/strc-mat.tex | 933 ---- tex/context/base/strc-not.lua | 5 +- tex/context/base/strc-not.mkii | 1440 ++++++ tex/context/base/strc-not.mkiv | 1154 +++++ tex/context/base/strc-not.tex | 1154 ----- tex/context/base/strc-num.mkii | 151 + tex/context/base/strc-num.mkiv | 450 ++ tex/context/base/strc-num.tex | 440 -- tex/context/base/strc-pag.mkii | 534 +++ tex/context/base/strc-pag.mkiv | 506 ++ tex/context/base/strc-pag.tex | 506 -- tex/context/base/strc-prc.mkiv | 84 + tex/context/base/strc-prc.tex | 84 - tex/context/base/strc-ref.mkii | 3038 ++++++++++++ tex/context/base/strc-ref.mkiv | 1905 ++++++++ tex/context/base/strc-ref.tex | 1905 -------- tex/context/base/strc-reg.mkii | 1242 +++++ tex/context/base/strc-reg.mkiv | 907 ++++ tex/context/base/strc-reg.tex | 907 ---- tex/context/base/strc-ren.mkiv | 467 ++ tex/context/base/strc-ren.tex | 467 -- tex/context/base/strc-sbe.mkiv | 137 + tex/context/base/strc-sbe.tex | 137 - tex/context/base/strc-sec.mkii | 2572 ++++++++++ tex/context/base/strc-sec.mkiv | 667 +++ tex/context/base/strc-sec.tex | 667 --- tex/context/base/strc-swd.mkii | 127 + tex/context/base/strc-syn.mkii | 438 ++ tex/context/base/strc-syn.mkiv | 392 ++ tex/context/base/strc-syn.tex | 392 -- tex/context/base/strc-xml.mkiv | 87 + tex/context/base/strc-xml.tex | 87 - tex/context/base/syst-aux.mkiv | 6866 +++++++++++++++++++++++++++ tex/context/base/syst-aux.tex | 6841 -------------------------- tex/context/base/syst-lua.mkiv | 37 + tex/context/base/syst-lua.tex | 37 - tex/context/base/task-ini.mkiv | 22 + tex/context/base/task-ini.tex | 22 - tex/context/base/toks-ini.mkiv | 78 + tex/context/base/toks-ini.tex | 78 - tex/context/base/trac-deb.mkiv | 43 + tex/context/base/trac-deb.tex | 43 - tex/context/base/trac-lmx.mkiv | 16 + tex/context/base/trac-lmx.tex | 16 - tex/context/base/trac-vis.mkii | 748 +++ tex/context/base/trac-vis.mkiv | 748 +++ tex/context/base/typo-brk.mkiv | 77 + tex/context/base/typo-brk.tex | 77 - tex/context/base/typo-cap.mkiv | 204 + tex/context/base/typo-cap.tex | 214 - tex/context/base/typo-ini.mkii | 40 + tex/context/base/typo-ini.mkiv | 40 + tex/context/base/typo-ini.tex | 40 - tex/context/base/typo-krn.mkiv | 59 + tex/context/base/typo-krn.tex | 59 - tex/context/base/typo-mir.mkiv | 144 + tex/context/base/typo-mir.tex | 144 - tex/context/base/typo-spa.mkiv | 69 + tex/context/base/typo-spa.tex | 69 - tex/context/base/verb-lua.lua | 216 - tex/context/base/verb-mp.lua | 238 - tex/context/base/verb-tex.lua | 126 - tex/context/test/chem-str-test.tex | 560 +++ tex/generic/context/luatex-fonts-merged.lua | 4 +- 237 files changed, 80995 insertions(+), 77256 deletions(-) create mode 100644 tex/context/base/anch-bar.tex create mode 100644 tex/context/base/anch-pgr.tex 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.tex create mode 100644 tex/context/base/attr-ini.mkiv delete mode 100644 tex/context/base/attr-ini.tex create mode 100644 tex/context/base/back-ini.mkiv delete mode 100644 tex/context/base/back-ini.tex create mode 100644 tex/context/base/back-pdf.mkiv delete mode 100644 tex/context/base/back-pdf.tex 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/char-act.mkiv create mode 100644 tex/context/base/char-enc.mkiv delete mode 100644 tex/context/base/char-enc.tex create mode 100644 tex/context/base/char-ini.mkiv delete mode 100644 tex/context/base/char-ini.tex create mode 100644 tex/context/base/char-utf.mkiv delete mode 100644 tex/context/base/char-utf.tex delete mode 100644 tex/context/base/chem-str-test.tex delete mode 100644 tex/context/base/core-bar.tex delete mode 100644 tex/context/base/core-blk.tex delete mode 100644 tex/context/base/core-box.tex delete mode 100644 tex/context/base/core-buf.lua delete mode 100644 tex/context/base/core-buf.mkii delete mode 100644 tex/context/base/core-buf.mkiv delete mode 100644 tex/context/base/core-dat.tex delete mode 100644 tex/context/base/core-des.tex delete mode 100644 tex/context/base/core-fig.tex delete mode 100644 tex/context/base/core-fld.mkii delete mode 100644 tex/context/base/core-fld.mkiv delete mode 100644 tex/context/base/core-hlp.tex delete mode 100644 tex/context/base/core-inc.lua delete mode 100644 tex/context/base/core-inc.mkii delete mode 100644 tex/context/base/core-inc.mkiv delete mode 100644 tex/context/base/core-int.mkii delete mode 100644 tex/context/base/core-int.mkiv delete mode 100644 tex/context/base/core-itm.tex delete mode 100644 tex/context/base/core-lst.tex delete mode 100644 tex/context/base/core-mar.tex delete mode 100644 tex/context/base/core-mat.tex delete mode 100644 tex/context/base/core-nav.mkii delete mode 100644 tex/context/base/core-nav.mkiv delete mode 100644 tex/context/base/core-not.tex delete mode 100644 tex/context/base/core-num.tex delete mode 100644 tex/context/base/core-obj.lua delete mode 100644 tex/context/base/core-obj.mkii delete mode 100644 tex/context/base/core-obj.mkiv delete mode 100644 tex/context/base/core-pgr.tex delete mode 100644 tex/context/base/core-pos.lua delete mode 100644 tex/context/base/core-pos.mkii delete mode 100644 tex/context/base/core-pos.mkiv delete mode 100644 tex/context/base/core-ref.tex delete mode 100644 tex/context/base/core-reg.tex delete mode 100644 tex/context/base/core-rul.lua delete mode 100644 tex/context/base/core-rul.mkii delete mode 100644 tex/context/base/core-rul.mkiv delete mode 100644 tex/context/base/core-sec.tex delete mode 100644 tex/context/base/core-snc.tex delete mode 100644 tex/context/base/core-swd.tex delete mode 100644 tex/context/base/core-syn.tex delete mode 100644 tex/context/base/core-trf.tex delete mode 100644 tex/context/base/core-ver.mkii delete mode 100644 tex/context/base/core-ver.mkiv delete mode 100644 tex/context/base/core-vis.tex 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-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-trf.mkii create mode 100644 tex/context/base/grph-trf.mkiv create mode 100644 tex/context/base/luat-bas.mkiv delete mode 100644 tex/context/base/luat-bas.tex create mode 100644 tex/context/base/luat-cod.mkiv delete mode 100644 tex/context/base/luat-cod.tex create mode 100644 tex/context/base/luat-ini.mkiv delete mode 100644 tex/context/base/luat-ini.tex create mode 100644 tex/context/base/luat-lib.mkiv delete mode 100644 tex/context/base/luat-lib.tex create mode 100644 tex/context/base/m-datastrc.tex create mode 100644 tex/context/base/mlib-ctx.mkiv delete mode 100644 tex/context/base/mlib-ctx.tex create mode 100644 tex/context/base/mlib-pdf.mkiv delete mode 100644 tex/context/base/mlib-pdf.tex create mode 100644 tex/context/base/mlib-pps.mkiv delete mode 100644 tex/context/base/mlib-pps.tex create mode 100644 tex/context/base/node-fin.mkiv delete mode 100644 tex/context/base/node-fin.tex create mode 100644 tex/context/base/node-ini.mkiv delete mode 100644 tex/context/base/node-ini.tex create mode 100644 tex/context/base/node-par.mkiv delete mode 100644 tex/context/base/node-par.tex 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 delete mode 100644 tex/context/base/page-flt.tex delete mode 100644 tex/context/base/page-lyr.tex delete mode 100644 tex/context/base/page-num.tex 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/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.mkii create mode 100644 tex/context/base/scrn-int.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-ini.mkiv delete mode 100644 tex/context/base/scrp-ini.tex create mode 100644 tex/context/base/strc-bkm.mkiv delete mode 100644 tex/context/base/strc-bkm.tex create mode 100644 tex/context/base/strc-blk.mkii create mode 100644 tex/context/base/strc-blk.mkiv delete mode 100644 tex/context/base/strc-blk.tex create mode 100644 tex/context/base/strc-def.mkiv delete mode 100644 tex/context/base/strc-def.tex create mode 100644 tex/context/base/strc-des.mkii create mode 100644 tex/context/base/strc-des.mkiv delete mode 100644 tex/context/base/strc-des.tex create mode 100644 tex/context/base/strc-doc.mkiv delete mode 100644 tex/context/base/strc-doc.tex create mode 100644 tex/context/base/strc-flt.mkii create mode 100644 tex/context/base/strc-flt.mkiv delete mode 100644 tex/context/base/strc-flt.tex create mode 100644 tex/context/base/strc-ini.mkiv delete mode 100644 tex/context/base/strc-ini.tex create mode 100644 tex/context/base/strc-itm.mkii create mode 100644 tex/context/base/strc-itm.mkiv delete mode 100644 tex/context/base/strc-itm.tex create mode 100644 tex/context/base/strc-lst.mkii create mode 100644 tex/context/base/strc-lst.mkiv delete mode 100644 tex/context/base/strc-lst.tex create mode 100644 tex/context/base/strc-mar.mkii create mode 100644 tex/context/base/strc-mar.mkiv delete mode 100644 tex/context/base/strc-mar.tex create mode 100644 tex/context/base/strc-mat.mkii create mode 100644 tex/context/base/strc-mat.mkiv delete mode 100644 tex/context/base/strc-mat.tex create mode 100644 tex/context/base/strc-not.mkii create mode 100644 tex/context/base/strc-not.mkiv delete mode 100644 tex/context/base/strc-not.tex create mode 100644 tex/context/base/strc-num.mkii create mode 100644 tex/context/base/strc-num.mkiv delete mode 100644 tex/context/base/strc-num.tex create mode 100644 tex/context/base/strc-pag.mkii create mode 100644 tex/context/base/strc-pag.mkiv delete mode 100644 tex/context/base/strc-pag.tex create mode 100644 tex/context/base/strc-prc.mkiv delete mode 100644 tex/context/base/strc-prc.tex create mode 100644 tex/context/base/strc-ref.mkii create mode 100644 tex/context/base/strc-ref.mkiv delete mode 100644 tex/context/base/strc-ref.tex create mode 100644 tex/context/base/strc-reg.mkii create mode 100644 tex/context/base/strc-reg.mkiv delete mode 100644 tex/context/base/strc-reg.tex create mode 100644 tex/context/base/strc-ren.mkiv delete mode 100644 tex/context/base/strc-ren.tex create mode 100644 tex/context/base/strc-sbe.mkiv delete mode 100644 tex/context/base/strc-sbe.tex create mode 100644 tex/context/base/strc-sec.mkii create mode 100644 tex/context/base/strc-sec.mkiv delete mode 100644 tex/context/base/strc-sec.tex create mode 100644 tex/context/base/strc-swd.mkii create mode 100644 tex/context/base/strc-syn.mkii create mode 100644 tex/context/base/strc-syn.mkiv delete mode 100644 tex/context/base/strc-syn.tex create mode 100644 tex/context/base/strc-xml.mkiv delete mode 100644 tex/context/base/strc-xml.tex create mode 100644 tex/context/base/syst-aux.mkiv delete mode 100644 tex/context/base/syst-aux.tex create mode 100644 tex/context/base/syst-lua.mkiv delete mode 100644 tex/context/base/syst-lua.tex create mode 100644 tex/context/base/task-ini.mkiv delete mode 100644 tex/context/base/task-ini.tex create mode 100644 tex/context/base/toks-ini.mkiv delete mode 100644 tex/context/base/toks-ini.tex create mode 100644 tex/context/base/trac-deb.mkiv delete mode 100644 tex/context/base/trac-deb.tex create mode 100644 tex/context/base/trac-lmx.mkiv delete mode 100644 tex/context/base/trac-lmx.tex create mode 100644 tex/context/base/trac-vis.mkii create mode 100644 tex/context/base/trac-vis.mkiv create mode 100644 tex/context/base/typo-brk.mkiv delete mode 100644 tex/context/base/typo-brk.tex create mode 100644 tex/context/base/typo-cap.mkiv delete mode 100644 tex/context/base/typo-cap.tex create mode 100644 tex/context/base/typo-ini.mkii create mode 100644 tex/context/base/typo-ini.mkiv delete mode 100644 tex/context/base/typo-ini.tex create mode 100644 tex/context/base/typo-krn.mkiv delete mode 100644 tex/context/base/typo-krn.tex create mode 100644 tex/context/base/typo-mir.mkiv delete mode 100644 tex/context/base/typo-mir.tex create mode 100644 tex/context/base/typo-spa.mkiv delete mode 100644 tex/context/base/typo-spa.tex delete mode 100644 tex/context/base/verb-lua.lua delete mode 100644 tex/context/base/verb-mp.lua delete mode 100644 tex/context/base/verb-tex.lua create mode 100644 tex/context/test/chem-str-test.tex diff --git a/metapost/context/base/mp-grph.mp b/metapost/context/base/mp-grph.mp index 1ff2a9ec2..243b45318 100644 --- a/metapost/context/base/mp-grph.mp +++ b/metapost/context/base/mp-grph.mp @@ -94,7 +94,7 @@ enddef ; def doloadfigure (expr filename) text figureattributes = begingroup ; save figurenumber, figurepicture, number, fixedplace ; - numeric figurenumber ; figurenumber := 0 ; + numeric figurenumber ; figurenumber := 0 ; boolean figureshift ; figureshift := true ; picture figurepicture ; figurepicture := currentpicture ; def number primary n = hide(figurenumber := n) enddef ; diff --git a/metapost/context/base/mp-mlib.mp b/metapost/context/base/mp-mlib.mp index 893222473..aeacb3e9c 100644 --- a/metapost/context/base/mp-mlib.mp +++ b/metapost/context/base/mp-mlib.mp @@ -36,10 +36,10 @@ vardef rawtextext(expr str) = image ( _tt_n_ := _tt_n_ + 1 ; _tt_p_ := image ( - draw _tt_p_ ; + addto currentpicture also _tt_p_ ; addto currentpicture doublepath unitsquare withprescript "tf" withpostscript decimal _tt_n_ & ":" & str ; ) ; - draw unitsquare withpen pencircle scaled 0 ; + addto currentpicture doublepath unitsquare withpen pencircle scaled 0 ; ) else : image ( @@ -68,8 +68,13 @@ 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 ; +% 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 ; @@ -131,7 +136,7 @@ vardef thetextext@#(expr p,z) = % adapted copy of thelabel@ 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; +enddef ; vardef textext@#(expr txt) = interim labeloffset := textextoffset ; @@ -161,7 +166,11 @@ vardef thelabel@#(expr s, z) = enddef; primarydef str infont name = % very naughty ! - textext("\definedfont[" & name & "]" & str) + if name = "" : + textext(str) + else : + textext("\definedfont[" & name & "]" & str) + fi enddef ; def circular_shade (expr p, n, ca, cb) = @@ -252,9 +261,17 @@ 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-text.mp b/metapost/context/base/mp-text.mp index 292b79b4f..a76458144 100644 --- a/metapost/context/base/mp-text.mp +++ b/metapost/context/base/mp-text.mp @@ -104,8 +104,8 @@ vardef textextstr(expr s, a) = scantokens ss enddef ; -pair laboff.origin ; laboff.origin = (infinity,infinity) ; -pair laboff.raw ; laboff.raw = (infinity,infinity) ; +pair laboff.origin ; laboff.origin = (0,0) ; % (infinity,infinity) ; +pair laboff.raw ; laboff.raw = (0,0) ; % (infinity,infinity) ; vardef thelabel@#(expr s, z) = save p ; picture p ; @@ -259,3 +259,7 @@ def build_parshape (expr p, offset_or_path, dx, dy, endgroup ; enddef ; + +vardef verbatim(expr str) = + ditto & "\detokenize{" & str & "}" & ditto +enddef ; diff --git a/metapost/context/base/mp-tool.mp b/metapost/context/base/mp-tool.mp index 817f237b0..3ba5923ea 100644 --- a/metapost/context/base/mp-tool.mp +++ b/metapost/context/base/mp-tool.mp @@ -1054,6 +1054,12 @@ enddef ; 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 ; diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua index 74f0ed924..615506ac0 100644 --- a/scripts/context/lua/mtx-server.lua +++ b/scripts/context/lua/mtx-server.lua @@ -279,6 +279,7 @@ function scripts.webserver.run(configuration) 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)) while true do -- no multiple clients local start = os.clock() diff --git a/tex/context/base/anch-bar.tex b/tex/context/base/anch-bar.tex new file mode 100644 index 000000000..d08573c0f --- /dev/null +++ b/tex/context/base/anch-bar.tex @@ -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-pgr.tex b/tex/context/base/anch-pgr.tex new file mode 100644 index 000000000..5d8ec6bf5 --- /dev/null +++ b/tex/context/base/anch-pgr.tex @@ -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} +\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 + \global\positioningtrue + \global\positioningpartrue + \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 + \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-pos.lua b/tex/context/base/anch-pos.lua new file mode 100644 index 000000000..82b0657a1 --- /dev/null +++ b/tex/context/base/anch-pos.lua @@ -0,0 +1,107 @@ +if not modules then modules = { } end modules ['anch-pos'] = { + version = 1.001, + comment = "companion to anch-pos.tex", + 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 texprint, concat, format = tex.print, table.concat, string.format + +jobpositions = jobpositions or { } +jobpositions.collected = jobpositions.collected or { } +jobpositions.tobesaved = jobpositions.tobesaved or { } + +-- these are global since they are used often at the tex end + +ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -- global + +local function initializer() + ptbs, pcol = jobpositions.tobesaved, jobpositions.collected +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((jpi and jpi[1]) or '0' ) end +function jobpositions.MPx(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[2]) or '0pt') end +function jobpositions.MPy(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[3]) or '0pt') end +function jobpositions.MPw(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[4]) or '0pt') end +function jobpositions.MPh(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[5]) or '0pt') end +function jobpositions.MPd(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[6]) or '0pt') end + +-- the following are only for MP so there we can leave out the pt + +function jobpositions.MPxy(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(format('(%s,%s)',jpi[2],jpi[3])) + else + texprint('(0,0)') + end +end +function jobpositions.MPll(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(format('(%s,%s-%s)',jpi[2],jpi[3],jpi[6])) + else + texprint('(0,0)') + end +end +function jobpositions.MPlr(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(format('(%s+%s,%s-%s)',jpi[2],jpi[4],jpi[3],jpi[6])) + else + texprint('(0,0)') + end +end +function jobpositions.MPur(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(format('(%s+%s,%s+%s)',jpi[2],jpi[4],jpi[3],jpi[5])) + else + texprint('(0,0)') + end +end +function jobpositions.MPul(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(format('(%s,%s+%s)',jpi[2],jpi[3],jpi[5])) + else + texprint('(0,0)') + end +end +function jobpositions.MPpos(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(concat(jpi,',',1,6)) + else + texprint('0,0,0,0,0,0') + end +end +function jobpositions.MPplus(id,n,default) + local jpi = pcol[id] or ptbs[id] + texprint((jpi and jpi[6+n]) or default) +end +function jobpositions.MPrest(id,default) + local jpi = pcol[id] or ptbs[id] + texprint((jpi and jpi[7] and concat(jpi,",",7,#jpi)) 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..eaf9886b4 --- /dev/null +++ b/tex/context/base/anch-pos.mkii @@ -0,0 +1,873 @@ +%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\registerparoptions + {\ifpositioningpar \ifpositioning \iftrialtypesetting \else + \ifinpagebody \else \ifmmode \else \ifinformula \else + \ifprocessingverbatim + \iflinepar \doregisterparoptions \fi + \else + \doregisterparoptions + \fi + \fi \fi \fi + \fi \fi \fi} + +\chardef\parposstrut=1 % 0 => no strut data, so fall backs used + +\newif\iftracepositions + +% \def\doregisterparoptions +% {\global\advance\parposcounter\plusone +% \begingroup +% \leftskip 1\leftskip +% \rightskip1\rightskip +% \setpositiondataplus +% {p:\number\parposcounter}% identifier +% {\the\zeropoint}% +% {\the\strutht}% +% {\the\strutdp}% +% {\the\hsize ,% 1 +% \the\leftskip ,% 2 +% \the\rightskip ,% 3 +% \the\hangindent,% 4 +% \the\hangafter ,% 5 (num) +% \the\parindent }% 6 +% %\normalhbox{\registerparsymbol}% +% \registerparsymbol +% \endgroup} + +\def\doregisterparoptions + {\global\advance\parposcounter\plusone + \setpositiondataplus + {p:\number\parposcounter}% identifier + {\the\zeropoint}% + {\the\strutht}% + {\the\strutdp}% + {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}% + %\normalhbox{\registerparsymbol}% + \iftracepositions\registerparsymbol\fi} + +\def\traceposstring#1#2#3% + {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi} + +\def\registerparsymbol + {\iftracepositions + \smashedhbox to \zeropoint + {\hss + \startcolor[blue]% + \llap{\infofont\number\parposcounter}% + \scratchdimen\onepoint + \vrule + \!!width 4\scratchdimen + \!!height2\scratchdimen + \!!depth 2\scratchdimen + \stopcolor + \hss}% + \fi} + +% \appendtoks \registerparoptions \to \everypar + +%D Eperimental code, don't use this yet: (must be sped up anyway) + +\def\@@noden{node:n:} +\def\@@nodeo{node:o:} +\def\@@nodep{node:p:} + +\def\doifelsenodelocation#1% + {\ifcsname\@@noden#1\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\nextnodelocation#1% + {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi} + +\def\newnodelocation#1% + {\ifcsname\@@noden#1\endcsname + \setcounter{\@@noden#1}\zerocount + \letgvalue {\@@nodeo#1}\!!zerocount + \fi} + +\def\tagnodelocation#1% + {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi} + +\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}} +\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}} +\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}} + +\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}} +\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}} +\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}} + +\def\getnodelocationn#1{\countervalue{\@@noden#1}} +\def\getnodelocationo#1{\getvalue {\@@nodeo#1}} + +\chardef\nodelocationmode\plusone + +\def\analyzenodelocation#1% + {\ifcsname\@@noden#1\endcsname + \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount + \fi} + +\def\doanalyzenodelocation#1#2#3% class n default + {\begingroup + \donefalse + \ifcase\nodelocationmode + % do nothing + \else + \edef\nodelocationselfn{#2}% + \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}% + \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}% + \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}% + \scratchcounter\plusone + \doloop + {\ifnum\recurselevel=\nodelocationselfn\relax + \donetrue + \else + \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}% + \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}% + \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}% + \ifcase\nodelocationmode + \or + % ok for single column + \ifcase\nodelocationotherp\relax + \exitloop + \else\ifnum\nodelocationotherp<\nodelocationselfp\relax + \donetrue \advance\scratchcounter\plusone + \else\ifnum\nodelocationotherp>\nodelocationselfp\relax + % skip + \else\ifdim\nodelocationothery>\nodelocationselfy\relax + \donetrue \advance\scratchcounter\plusone + \else\ifdim\nodelocationothery<\nodelocationselfy\relax + % skip + \else\ifdim\nodelocationotherx<\nodelocationselfx\relax + \donetrue \advance\scratchcounter\plusone + \fi\fi\fi\fi\fi\fi + \or + % acceptable for double column + \ifcase\nodelocationotherp\relax + \exitloop + \else\ifnum\nodelocationotherp<\nodelocationselfp\relax + \donetrue \advance\scratchcounter\plusone + \else\ifnum\nodelocationotherp>\nodelocationselfp\relax + % skip + \else\ifnum\recurselevel>\nodelocationselfn\relax + \donetrue \exitloop + \else + \donetrue \advance\scratchcounter\plusone + \fi\fi\fi\fi + \else + \exitloop + \fi + \fi}% + \fi + \ifdone \else + \scratchcounter#3\relax + \fi + \setxvalue{\@@nodeo#1}{\the\scratchcounter}% + \endgroup} + +\unexpanded\def\shownodelocation#1% + {\ifcsname\@@noden#1\endcsname + \analyzenodelocation{#1}% + (#1,% + n:\getnodelocationn{#1},% + p:\getnodelocationp{#1},% + x:\getnodelocationx{#1},% + y:\getnodelocationy{#1},% + o:\getnodelocationo{#1})% + \fi} + +%D \macros +%D {doifoverlappingelse} +%D +%D A first application of positional information, is to +%D determine if two boxes do overlap: +%D +%D \starttyping +%D \doifoverlappingelse{point a}{point b} +%D {action when overlapping} +%D {action when not overlapping} +%D \stoptyping + +\def\overlappingmargin{-2\scaledpoint} + +\def\doifoverlappingelse#1#2% + {\begingroup + \donefalse + \edef\!!stringa{#1}\edef\!!stringb{#2}% + \ifnum\MPp\!!stringa=\MPp\!!stringb\relax + \!!dimena\MPx\!!stringa + \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax + \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax + \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax + \!!dimene\MPx\!!stringb + \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax + \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax + \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax + \ifdim\overlappingmargin=\zeropoint\else + \advance\!!dimena-\overlappingmargin + \advance\!!dimenb+\overlappingmargin + \advance\!!dimenc-\overlappingmargin + \advance\!!dimend+\overlappingmargin + \advance\!!dimene-\overlappingmargin + \advance\!!dimenf+\overlappingmargin + \advance\!!dimeng-\overlappingmargin + \advance\!!dimenh+\overlappingmargin + \fi + % more often eh fb eg fg + \def\checkone##1##2% + {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else + \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else + \donetrue + \fi\fi + \fi\fi}% + \def\checktwo##1##2% + {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else + \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else + \donetrue + \fi\fi + \fi\fi}% + \checkone\!!dimene\!!dimeng \ifdone \else + \checkone\!!dimene\!!dimenh \ifdone \else + \checkone\!!dimenf\!!dimeng \ifdone \else + \checkone\!!dimenf\!!dimenh \ifdone \else + \checktwo\!!dimena\!!dimenc \ifdone \else + \checktwo\!!dimena\!!dimend \ifdone \else + \checktwo\!!dimenb\!!dimene \ifdone \else + \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi + \fi + \ifdone + \endgroup\expandafter\firstoftwoarguments + \else + \endgroup\expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifpositionsonsamepageelse, +%D doifpositionsonthispageelse} +%D +%D Instead of letting the user handle fuzzy expansion, we +%D provide a simple test on positione being on the same page. +%D +%D \starttyping +%D \doifpositionsonsamepageelse{point a}{point b} +%D {action when on same page} +%D {action when not on same page} +%D \doifpositionsonthispageelse{point a}{point b} +%D {action when on this page} +%D {action when not on this page} +%D \stoptyping + +\def\dodoifpositionsonsamepageelse#1#2#3#4% + {\bgroup + \scratchcounter#1\donefalse + \def\docommand##1% + {\ifcase\scratchcounter + \scratchcounter\MPp{##1}\donetrue + \else + \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi + \fi}% + \rawprocesscommalist[#2]\docommand + \ifdone\egroup#3\else\egroup#4\fi} + +\def\doifpositionsonsamepageelse + {\dodoifpositionsonsamepageelse{0}} + +\def\doifpositionsonthispageelse#1#2#3% + {\dodoifpositionsonsamepageelse\realfolio} + +%D Plugins: + +\let\MPv \MPplus +\let\MPvv\MPrest + +\let\MPanchor\MPpos + +\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy +\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw + +\protect \endinput diff --git a/tex/context/base/anch-pos.mkiv b/tex/context/base/anch-pos.mkiv new file mode 100644 index 000000000..a3c7b06cf --- /dev/null +++ b/tex/context/base/anch-pos.mkiv @@ -0,0 +1,828 @@ +%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. + +% TO BE MERGED + +\def\dolazysaveposition #1#2#3#4{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4"}}}} +\def\dolazysavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}} +\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\dosetposition#1% +% {\pdfsavepos +% \dolazysaveposition +% {#1}% +% {\noexpand\realfolio}% +% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}% +% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}}% +% +% \def\dosetpositionwhd#1#2#3#4% +% {\pdfsavepos +% \dolazysavepositionwhd +% {#1}% +% {\noexpand\realfolio}% +% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}% +% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}% +% {#2}{#3}{#4}} +% +% \def\dosetpositionplus#1#2#3#4#5% +% {\pdfsavepos +% \dolazysavepositionplus +% {#1}% +% {\noexpand\realfolio}% +% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}% +% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}% +% {#2}{#3}{#4}{#5}} + +\def\lastsavedpositionx {\the\dimexpr\pdflastxpos\scaledpoint\relax} +\def\lastsavedpositiony {\the\dimexpr\pdflastypos\scaledpoint\relax} +\let\savecurrentposition\pdfsavepos + +\def\dosetposition#1% + {\savecurrentposition + \normalexpanded{\ctxlatelua{ptbs['#1']={% + \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony"}}}} + +\def\dosetpositionwhd#1#2#3#4% + {\savecurrentposition + \normalexpanded{\ctxlatelua{ptbs['#1']={% + \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4"}}}} + +\def\dosetpositionplus#1#2#3#4#5% + {\savecurrentposition + \normalexpanded{\ctxlatelua{ptbs['#1']={% + \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4","#5"}}}} + +\let\dosetpositionpapersize\gobbletwoarguments + +\newbox\positionbox +\newif \ifpositioning + +\def\POSprefix{POS::} + +\let\setpospx \gobblefourarguments % suppress errors with mkii tuo file +\let\setpospxywhd \gobblesevenarguments % suppress errors with mkii tuo file +\let\setpospxyplus\gobbleeightarguments % suppress errors with mkii tuo file + +%D This is real tricky! The page anchor is applied to the +%D page box and therefore flushed first. So, when present, it +%D is applied to all positions except itself. + +\chardef\positionanchormode=0 % don't relocate page origin +\chardef\positionanchormode=1 % relocate page origin once + +%D The core set macros. + +\let\pospxy \gobblefourarguments +\let\pospxywhd \gobblesevenarguments +\let\pospxyplus\gobbleeightarguments + +%D Sometimes we want to trick the position handler a bit: + +\def\replacepospxywhd#1#2#3#4#5#6#7{\ctxlua{jobpositions.replace('#1',\number#2,"\the\dimexpr#3\relax","\the\dimexpr#4\relax","\the\dimexpr#5\relax","\the\dimexpr#6\relax","\the\dimexpr#7\relax")}} + +%D For postprocessing purposes, we save the number of +%D positions. + +\newcount\currentpositions % current number of positions +\newcounter\totalnofpositions % total from previous run + +\appendtoks + \expanded{\savecurrentvalue\noexpand\totalnofpositions{\the\currentpositions}}% +\to \everybye + +%D The next switch can be used to communicate a special +%D situation. Positioning and associated actions can be +%D executed any time. However, in for instance backgrounds +%D they can be collected in a layer, for instance the text +%D layer (especially the hidden text layer). In the case of +%D floats, we run into problems, since the page information is +%D not applicable when the content floats indeed. In such +%D situations one can treat positions and graphics local. + +\newif\iflocalpositioning + +%D Watch out: sometimes a pagebreak occurs inside a float +%D placement, so there we need to disable local mode. + +\appendtoks + \localpositioningtrue +\to \everyinsidefloat + +\appendtoks + \localpositioningfalse +\to \everypagebody + +\def\checkpositions + {\startnointerference + \protectlabels + \doutilities{positions}\jobname\empty\relax\relax + \global\let\checkpositions\relax + \stopnointerference} + +%D Since the positional values are to be fully expandable, we +%D need to preload them as soon as possible, which is why we +%D load the data when we start a text. + +\appendtoks \checkpositions \to \everystarttext + +%D \macros +%D {MPp, MPx, MPy, MPw, MPh, MPd, +%D MPxy, MPll, MPlr, MPur, MPul, MPpos} +%D +%D Access to the positional information is provided by macros +%D with short names that are clearly meant for \METAPOST. + +\def\MPp #1{\ctxlua{jobpositions.MPp("#1")}} +\def\MPx #1{\ctxlua{jobpositions.MPx("#1")}} +\def\MPy #1{\ctxlua{jobpositions.MPy("#1")}} +\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 + +% we can check for used entries, and if not, then not add one + +\def\registerparoptions + {\ifpositioningpar \ifpositioning \iftrialtypesetting \else + \ifinpagebody \else \ifmmode \else \ifinformula \else + \ifprocessingverbatim + \iflinepar \doregisterparoptions \fi + \else + \doregisterparoptions + \fi + \fi \fi \fi + \fi \fi \fi} + +\chardef\parposstrut=1 % 0 => no strut data, so fall backs used + +\newif\iftracepositions + +% \def\doregisterparoptions +% {\global\advance\parposcounter\plusone +% \begingroup +% \leftskip 1\leftskip +% \rightskip1\rightskip +% \setpositiondataplus +% {p:\number\parposcounter}% identifier +% {\the\zeropoint}% +% {\the\strutht}% +% {\the\strutdp}% +% {\the\hsize ,% 1 +% \the\leftskip ,% 2 +% \the\rightskip ,% 3 +% \the\hangindent,% 4 +% \the\hangafter ,% 5 (num) +% \the\parindent }% 6 +% %\normalhbox{\registerparsymbol}% +% \registerparsymbol +% \endgroup} + +\def\doregisterparoptions + {\global\advance\parposcounter\plusone + \setpositiondataplus + {p:\number\parposcounter}% identifier + {\the\zeropoint}% + {\the\strutht}% + {\the\strutdp}% + {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}% + %\normalhbox{\registerparsymbol}% + \iftracepositions\registerparsymbol\fi} + +\def\traceposstring#1#2#3% + {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi} + +\def\registerparsymbol + {\iftracepositions + \smashedhbox to \zeropoint + {\hss + \startcolor[blue]% + \llap{\infofont\number\parposcounter}% + \scratchdimen\onepoint + \vrule + \!!width 4\scratchdimen + \!!height2\scratchdimen + \!!depth 2\scratchdimen + \stopcolor + \hss}% + \fi} + +% \appendtoks \registerparoptions \to \everypar + +%D Eperimental code, don't use this yet: (must be sped up anyway) + +\def\@@noden{node:n:} +\def\@@nodeo{node:o:} +\def\@@nodep{node:p:} + +\def\doifelsenodelocation#1% + {\ifcsname\@@noden#1\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\nextnodelocation#1% + {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi} + +\def\newnodelocation#1% + {\ifcsname\@@noden#1\endcsname + \setcounter{\@@noden#1}\zerocount + \letgvalue {\@@nodeo#1}\!!zerocount + \fi} + +\def\tagnodelocation#1% + {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi} + +\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}} +\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}} +\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}} + +\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}} +\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}} +\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}} + +\def\getnodelocationn#1{\countervalue{\@@noden#1}} +\def\getnodelocationo#1{\getvalue {\@@nodeo#1}} + +\chardef\nodelocationmode\plusone + +\def\analyzenodelocation#1% + {\ifcsname\@@noden#1\endcsname + \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount + \fi} + +\def\doanalyzenodelocation#1#2#3% class n default + {\begingroup + \donefalse + \ifcase\nodelocationmode + % do nothing + \else + \edef\nodelocationselfn{#2}% + \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}% + \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}% + \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}% + \scratchcounter\plusone + \doloop + {\ifnum\recurselevel=\nodelocationselfn\relax + \donetrue + \else + \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}% + \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}% + \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}% + \ifcase\nodelocationmode + \or + % ok for single column + \ifcase\nodelocationotherp\relax + \exitloop + \else\ifnum\nodelocationotherp<\nodelocationselfp\relax + \donetrue \advance\scratchcounter\plusone + \else\ifnum\nodelocationotherp>\nodelocationselfp\relax + % skip + \else\ifdim\nodelocationothery>\nodelocationselfy\relax + \donetrue \advance\scratchcounter\plusone + \else\ifdim\nodelocationothery<\nodelocationselfy\relax + % skip + \else\ifdim\nodelocationotherx<\nodelocationselfx\relax + \donetrue \advance\scratchcounter\plusone + \fi\fi\fi\fi\fi\fi + \or + % acceptable for double column + \ifcase\nodelocationotherp\relax + \exitloop + \else\ifnum\nodelocationotherp<\nodelocationselfp\relax + \donetrue \advance\scratchcounter\plusone + \else\ifnum\nodelocationotherp>\nodelocationselfp\relax + % skip + \else\ifnum\recurselevel>\nodelocationselfn\relax + \donetrue \exitloop + \else + \donetrue \advance\scratchcounter\plusone + \fi\fi\fi\fi + \else + \exitloop + \fi + \fi}% + \fi + \ifdone \else + \scratchcounter#3\relax + \fi + \setxvalue{\@@nodeo#1}{\the\scratchcounter}% + \endgroup} + +\unexpanded\def\shownodelocation#1% + {\ifcsname\@@noden#1\endcsname + \analyzenodelocation{#1}% + (#1,% + n:\getnodelocationn{#1},% + p:\getnodelocationp{#1},% + x:\getnodelocationx{#1},% + y:\getnodelocationy{#1},% + o:\getnodelocationo{#1})% + \fi} + +%D \macros +%D {doifoverlappingelse} +%D +%D A first application of positional information, is to +%D determine if two boxes do overlap: +%D +%D \starttyping +%D \doifoverlappingelse{point a}{point b} +%D {action when overlapping} +%D {action when not overlapping} +%D \stoptyping + +\def\overlappingmargin{-2\scaledpoint} + +\def\doifoverlappingelse#1#2% + {\begingroup + \donefalse + \edef\!!stringa{#1}\edef\!!stringb{#2}% + \ifnum\MPp\!!stringa=\MPp\!!stringb\relax + \!!dimena\MPx\!!stringa + \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax + \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax + \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax + \!!dimene\MPx\!!stringb + \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax + \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax + \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax + \ifdim\overlappingmargin=\zeropoint\else + \advance\!!dimena-\overlappingmargin + \advance\!!dimenb+\overlappingmargin + \advance\!!dimenc-\overlappingmargin + \advance\!!dimend+\overlappingmargin + \advance\!!dimene-\overlappingmargin + \advance\!!dimenf+\overlappingmargin + \advance\!!dimeng-\overlappingmargin + \advance\!!dimenh+\overlappingmargin + \fi + % more often eh fb eg fg + \def\checkone##1##2% + {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else + \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else + \donetrue + \fi\fi + \fi\fi}% + \def\checktwo##1##2% + {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else + \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else + \donetrue + \fi\fi + \fi\fi}% + \checkone\!!dimene\!!dimeng \ifdone \else + \checkone\!!dimene\!!dimenh \ifdone \else + \checkone\!!dimenf\!!dimeng \ifdone \else + \checkone\!!dimenf\!!dimenh \ifdone \else + \checktwo\!!dimena\!!dimenc \ifdone \else + \checktwo\!!dimena\!!dimend \ifdone \else + \checktwo\!!dimenb\!!dimene \ifdone \else + \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi + \fi + \ifdone + \endgroup\expandafter\firstoftwoarguments + \else + \endgroup\expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifpositionsonsamepageelse, +%D doifpositionsonthispageelse} +%D +%D Instead of letting the user handle fuzzy expansion, we +%D provide a simple test on positione being on the same page. +%D +%D \starttyping +%D \doifpositionsonsamepageelse{point a}{point b} +%D {action when on same page} +%D {action when not on same page} +%D \doifpositionsonthispageelse{point a}{point b} +%D {action when on this page} +%D {action when not on this page} +%D \stoptyping + +\def\dodoifpositionsonsamepageelse#1#2#3#4% + {\bgroup + \scratchcounter#1\donefalse + \def\docommand##1% + {\ifcase\scratchcounter + \scratchcounter\MPp{##1}\donetrue + \else + \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi + \fi}% + \rawprocesscommalist[#2]\docommand + \ifdone\egroup#3\else\egroup#4\fi} + +\def\doifpositionsonsamepageelse + {\dodoifpositionsonsamepageelse{0}} + +\def\doifpositionsonthispageelse#1#2#3% + {\dodoifpositionsonsamepageelse\realfolio} + +%D Plugins: + +\let\MPv \MPplus +\let\MPvv\MPrest + +\let\MPanchor\MPpos + +\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy +\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw + +\protect \endinput diff --git a/tex/context/base/anch-snc.tex b/tex/context/base/anch-snc.tex new file mode 100644 index 000000000..ed090eaf9 --- /dev/null +++ b/tex/context/base/anch-snc.tex @@ -0,0 +1,179 @@ +%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 + +\setupcolors[state=start] + +\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.mkiv b/tex/context/base/attr-ini.mkiv new file mode 100644 index 000000000..3997d546b --- /dev/null +++ b/tex/context/base/attr-ini.mkiv @@ -0,0 +1,153 @@ +%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} + +\definesystemattribute[state] +\definesystemattribute[skip] +\definesystemattribute[penalty] +\definesystemattribute[colormodel][global] % no reset +\definesystemattribute[color] +\definesystemattribute[transparency] +\definesystemattribute[overprint] +\definesystemattribute[negative] +\definesystemattribute[effect] +\definesystemattribute[viewerlayer] + +% \definesystemattribute[ignore] +% +% \edef\startignorecontent{\dosetattribute{ignore}\plusone} +% \edef\stopignorecontent {\doresetattribute{ignore}} + +% 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\setcolormodel#1% + {\currentcolormodel\ctxlua{tex.print(colors.setmodel('colormodel','#1'))}% + \dosetattribute{colormodel}{\the\currentcolormodel}} + +\setcolormodel{all} + +\appendtoks + \setcolormodel{all}% redundant? +\to \everyjob + +\def\registerrgbcolor #1#2#3#4{\ctxlua{colors.register('color','#1','rgb' ,#2,#3,#4)}} +\def\registercmykcolor#1#2#3#4#5{\ctxlua{colors.register('color','#1','cmyk',#2,#3,#4,#5)}} +\def\registergraycolor #1#2{\ctxlua{colors.register('color','#1','gray',#2)}} + +% transparency + +\def\registertransparency#1#2#3% + {\setevalue{(ts:#1)}{\dosetattribute{transparency}{\ctxlua{tex.print(transparencies.register(#2,#3))}}}} + +\def\sometransparencyswitch#1{\csname(ts:#1)\endcsname} + +\def\sometransparencyswitch + {\ctxlua{transparencies.enabled=true}% + \gdef\sometransparencyswitch##1{\csname(ts:##1)\endcsname}% + \sometransparencyswitch} + +% \registertransparency {one} {1} {.5} +% \registertransparency {two} {1} {.6} + +% overprint + +\def\registeroverprint#1#2% + {\setevalue{(os:#1)}{\dosetattribute{overprint}{\ctxlua{tex.print(overprints.register('#2'))}}}} + +\def\dotriggeroverprint + {\initializePDFoverprint % temp here, to be tested in la code (states.collect) + \ctxlua{overprints.enabled=true}% + \gdef\dotriggeroverprint##1{\csname(os:##1)\endcsname}% + \dotriggeroverprint} + +\registeroverprint{knockout} {knockout} +\registeroverprint{overprint}{overprint} + +% negative + +\def\registernegative#1#2% + {\setevalue{(ns:#1)}{\dosetattribute{negative}{\ctxlua{tex.print(negatives.register('#2'))}}}} + +\def\dotriggernegative + {\initializePDFnegative % temp here, to be tested in la code (states.collect) + \ctxlua{negatives.enabled=true}% + \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)}% + {\dosetattribute{effect}{\ctxlua{tex.print(effects.register('#1',#2,\number\dimexpr#3\relax))}}}} + +\def\dotriggereffect + {\ctxlua{effects.enabled=true}% + \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 + +% \def\registerviewerlayer#1#2% global ! +% {\setxvalue{(vl:#1)}{\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}} +% +% \setevalue{(vl:)}{\doresetattribute{viewerlayer}} +% +% needs to work over stopitemize grouping etc + +\def\registerviewerlayer#1#2% global ! + {\setxvalue{(vl:#1)}{\global\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}} + +\setevalue{(vl:)}{\global\doresetattribute{viewerlayer}} + +% + +\def\dotriggerviewerlayer + {\ctxlua{viewerlayers.enabled=true}% + \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/attr-ini.tex b/tex/context/base/attr-ini.tex deleted file mode 100644 index 3997d546b..000000000 --- a/tex/context/base/attr-ini.tex +++ /dev/null @@ -1,153 +0,0 @@ -%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} - -\definesystemattribute[state] -\definesystemattribute[skip] -\definesystemattribute[penalty] -\definesystemattribute[colormodel][global] % no reset -\definesystemattribute[color] -\definesystemattribute[transparency] -\definesystemattribute[overprint] -\definesystemattribute[negative] -\definesystemattribute[effect] -\definesystemattribute[viewerlayer] - -% \definesystemattribute[ignore] -% -% \edef\startignorecontent{\dosetattribute{ignore}\plusone} -% \edef\stopignorecontent {\doresetattribute{ignore}} - -% 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\setcolormodel#1% - {\currentcolormodel\ctxlua{tex.print(colors.setmodel('colormodel','#1'))}% - \dosetattribute{colormodel}{\the\currentcolormodel}} - -\setcolormodel{all} - -\appendtoks - \setcolormodel{all}% redundant? -\to \everyjob - -\def\registerrgbcolor #1#2#3#4{\ctxlua{colors.register('color','#1','rgb' ,#2,#3,#4)}} -\def\registercmykcolor#1#2#3#4#5{\ctxlua{colors.register('color','#1','cmyk',#2,#3,#4,#5)}} -\def\registergraycolor #1#2{\ctxlua{colors.register('color','#1','gray',#2)}} - -% transparency - -\def\registertransparency#1#2#3% - {\setevalue{(ts:#1)}{\dosetattribute{transparency}{\ctxlua{tex.print(transparencies.register(#2,#3))}}}} - -\def\sometransparencyswitch#1{\csname(ts:#1)\endcsname} - -\def\sometransparencyswitch - {\ctxlua{transparencies.enabled=true}% - \gdef\sometransparencyswitch##1{\csname(ts:##1)\endcsname}% - \sometransparencyswitch} - -% \registertransparency {one} {1} {.5} -% \registertransparency {two} {1} {.6} - -% overprint - -\def\registeroverprint#1#2% - {\setevalue{(os:#1)}{\dosetattribute{overprint}{\ctxlua{tex.print(overprints.register('#2'))}}}} - -\def\dotriggeroverprint - {\initializePDFoverprint % temp here, to be tested in la code (states.collect) - \ctxlua{overprints.enabled=true}% - \gdef\dotriggeroverprint##1{\csname(os:##1)\endcsname}% - \dotriggeroverprint} - -\registeroverprint{knockout} {knockout} -\registeroverprint{overprint}{overprint} - -% negative - -\def\registernegative#1#2% - {\setevalue{(ns:#1)}{\dosetattribute{negative}{\ctxlua{tex.print(negatives.register('#2'))}}}} - -\def\dotriggernegative - {\initializePDFnegative % temp here, to be tested in la code (states.collect) - \ctxlua{negatives.enabled=true}% - \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)}% - {\dosetattribute{effect}{\ctxlua{tex.print(effects.register('#1',#2,\number\dimexpr#3\relax))}}}} - -\def\dotriggereffect - {\ctxlua{effects.enabled=true}% - \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 - -% \def\registerviewerlayer#1#2% global ! -% {\setxvalue{(vl:#1)}{\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}} -% -% \setevalue{(vl:)}{\doresetattribute{viewerlayer}} -% -% needs to work over stopitemize grouping etc - -\def\registerviewerlayer#1#2% global ! - {\setxvalue{(vl:#1)}{\global\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}} - -\setevalue{(vl:)}{\global\doresetattribute{viewerlayer}} - -% - -\def\dotriggerviewerlayer - {\ctxlua{viewerlayers.enabled=true}% - \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.mkiv b/tex/context/base/back-ini.mkiv new file mode 100644 index 000000000..a60b6a329 --- /dev/null +++ b/tex/context/base/back-ini.mkiv @@ -0,0 +1,896 @@ +%D \module +%D [ file=back-ini, +%D version=2009.04.15, +%D title=\CONTEXT\ Backend Macros, +%D subtitle=Initialization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Backend Macros / Initialization} + +\registerctxluafile{back-ini}{1.001} + +%D We currently have a curious mix between tex and lua backend +%D handling but eventually most will move to lua. + +\unprotect + +%D Right from the start \CONTEXT\ had a backend system based on +%D runtime pluggable code. As most backend issues involved specials +%D and since postprocessors had not that much in common, we ended up +%D with a system where we could switch backend as well as output code +%D for multiple backends at the same time. +%D +%D Because \LUATEX\ has the backend built in, and since some backend +%D issues have been moved to the frontend I decided to provide new +%D backend code for \MKIV, starting with what was actually used. +%D +%D At this moment \DVI\ is no longer used for advanced document +%D output and we therefore dropped support for this format. Future +%D versions might support more backends again, but this has a low +%D priority. +%D +%D The big question is: what is to be considered a backend issue and +%D what not. For the moment we treat image inclusion, object reuse, +%D position tracking and color as frontend issues, if only because we +%D deal with them via \LUA\ code and as such we don't depend too much +%D on macro calls that need to inject code for the backend. +%D +%D Not everything here makes sense and the content of this file will +%D definitely change. + +%D We use a couple of (global) variables because it saves us the +%D trouble of dealing with arguments. + +\letempty \@@DriverFieldName +\letempty \@@DriverFieldWidth +\letempty \@@DriverFieldHeight +\letempty \@@DriverFieldDefault +\letempty \@@DriverFieldNumber +\letempty \@@DriverFieldNumber +\letempty \@@DriverFieldStyle +\letempty \@@DriverFieldColor +\letempty \@@DriverFieldBackgroundColor +\letempty \@@DriverFieldFrameColor +\letempty \@@DriverFieldLayer +\letempty \@@DriverFieldOption +\letempty \@@DriverFieldAlign +\letempty \@@DriverFieldClickIn +\letempty \@@DriverFieldClickOut +\letempty \@@DriverFieldRegionIn +\letempty \@@DriverFieldRegionOut +\letempty \@@DriverFieldAfterKey +\letempty \@@DriverFieldFormat +\letempty \@@DriverFieldValidate +\letempty \@@DriverFieldCalculate +\letempty \@@DriverFieldFocusIn +\letempty \@@DriverFieldFocusOut + +\letempty \@@DriverCommentLayer +\letempty \@@DriverAttachmentLayer + +\letempty \@@DriverImageBox +\letempty \@@DriverImageOptions +\letempty \@@DriverImageWidth +\letempty \@@DriverImageHeight +\letempty \@@DriverImageFile +\letempty \@@DriverImageLabel +\letempty \@@DriverImageType +\letempty \@@DriverImageMethod +\letempty \@@DriverImagePage + +\newif\ifcollectreferenceactions + +%D \macros +%D {dostartgraymode,dostopgraymode, +%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,dostopcolormode} +%D +%D Switching to and from color can be done in two ways: +%D +%D \startitemize[packed,n] +%D \item insert driver specific commands +%D \item pass instructions to the output device +%D \stopitemize +%D +%D The first approach is more general and lays the +%D responsibility at the driver side. Probably due to the fact +%D that \TEX\ does not directly support color, we have been +%D confronted for the last few years with changing special +%D definitions. The need for support depends on how a macro +%D package handles colored text that crosses the page boundary. +%D Again, there are two approaches. +%D +%D \startitemize[packed,n] +%D \item let \TEX\ do the job +%D \item let the driver handle things +%D \stopitemize +%D +%D The first approach is as driver independant as possible and +%D can easily be accomplished by using \TEX's mark mechanism. +%D In \CONTEXT\ we follow this approach. More and more, drivers +%D are starting to support color, including stacking them. +%D +%D Colors as well as grayscales can be represented in scales +%D from~0 to~1. When drivers use values in the range 0..255, +%D this value has to be adapted in the translation process. +%D Technically it's possible to get a grayscale from combining +%D colors. In the \cap{RGB} color system, a color with Red, +%D Green and Blue components of 0.80 show the same gray as a +%D Gray Scale specified 0.80. The \cap{CMYK} color system +%D supports a Black component apart from Cyan, Magenta and +%D Yellow. +%D +%D Depending on the target format, color support differs from +%D gray support. PostScript for example offers different +%D operators for setting gray and color. This is because +%D printing something using three colors is someting else than +%D printing with just black. +%D +%D In \CONTEXT\ we have implemented a color subsystem that +%D supports the use of well defined colors that, when printed +%D in black and white, still can be distinguished. This +%D approach enables us to serve both printed and electronic +%D versions, using colored text and illustrations. More on the +%D fundamentals of this topic can be found in the \cap{MAPS} of +%D the Dutch User Group, 14 (95.1). +%D +%D To satisfy all those needs, we define four specials which +%D supply enough information for drivers to act upon. We +%D could have used more general commands with the keywords +%D 'rgb' and 'gray', but because these specials are used often, +%D we prefer the more direct and shorter alternative. +%D +%D We start with the installation of color and grayscale +%D specials. The values are in the range 0..1 (e.g. 0.25). +%D +%D \starttyping +%D \dostartgraymode {gray} ... \dostopgraymode +%D \dostartrgbcolormode {red} {green} {blue} ... \dostopcolormode +%D \dostartcmykcolormode {cyan} {magenta} {yellow} {black} ... \dostopcolormode +%D \dostartgraycolormode {gray} ... \dostopcolormode +%D \stoptyping +%D +%D Because we can expect conflicts between drivers, we +%D implement them as category \type{or}. In previous versions +%D of \DVIPSONE\ the use of their color||specials did not +%D interfere with the PostScript ones, but recent versions do. + +\let \dostartgraymode \gobbleoneargument +\let \dostopgraymode \donothing +\let \dostartrgbcolormode \gobblethreearguments +\let \dostartcmykcolormode \gobblefourarguments +\let \dostartgraycolormode \gobbleoneargument +\let \dostopcolormode \donothing +\let \dostartspotcolormode \gobbletwoarguments +\let \doregisterrgbspotcolor \gobblesevenarguments +\let \doregistercmykspotcolor \gobbleeightarguments +\let \doregistergrayspotcolor \gobblefourarguments +\let \doregisterrgbindexcolor \gobblesevenarguments +\let \doregistercmykindexcolor \gobbleeightarguments +\let \doregistergrayindexcolor \gobblefourarguments +\let \doregisterspotcolorname \gobbletwoarguments +\let \dostartnonecolormode \donothing +\let \doregisternonecolor \donothing + +%D \macros +%D {doinsertsoundtrack} +%D +%D Sounds are (for the moment) just files with +%D associated options. +%D +%D \starttyping +%D \doinsertsoundtrack {file} {label} {options} +%D \stoptyping + +\let \doinsertsoundtrack \gobblethreearguments + +%D \macros +%D {dostartrotation,dostoprotation, +%D dostartscaling,dostopscaling, +%D dostartmirroring,dostopmirroring, +%D dostartnegative,dostopnegative} +%D dostartoverprint,dostopoverprint} +%D +%D We support a couple of transformations and renderings: +%D +%D \starttyping +%D \dostartrotation {angle} ... \dostoprotation +%D \dostartscaling {x} {y} ... \dostopscaling +%D \dostartmirroring {x} {y} ... \dostopmirroring +%D \stoptyping + +\let \dostartrotation \gobbleoneargument +\let \dostoprotation \donothing +\let \dostartscaling \gobbletwoarguments +\let \dostopscaling \donothing +\let \dostartmirroring \donothing +\let \dostopmirroring \donothing + +\let \dostartnegative \donothing +\let \dostopnegative \donothing +\let \dostartoverprint \donothing +\let \dostopoverprint \donothing + +%D The following two specials are used in for instance \type +%D {\vadjust}'d margin material inside colored paragraphs. + +\let \dostartgraphicgroup \donothing +\let \dostopgraphicgroup \donothing + +%D \macros +%D {doselectfirstpaperbin, +%D doselectsecondpaperbin} +%D +%D Here are some very printer||specific ones. No further +%D comment. + +\let \doselectfirstpaperbin \donothing +\let \doselectsecondpaperbin \donothing + +%D \macros +%D {doovalbox} +%D +%D When we look at the implementation, this is a complicated +%D one. There are seven arguments. +%D +%D \starttyping +%D \doovalbox {w} {h} {d} {linewidth} {radius} {stroke} {fill} {variant} +%D \stoptyping +%D +%D This command has to return a \type{\vbox} which can be used +%D to lay over another one (with text). The radius is in +%D degrees, the stroke and fill are~\type{1} (true) of~\type{0} +%D (false). + +\let \doovalbox \gobbleeightarguments + +%D \macros +%D {dostartclipping,dostopclipping} +%D +%D Clipping is implemented in such a way that an arbitrary code +%D can be fed. +%D +%D \starttyping +%D \dostartclipping {pathname} {width} {height} +%D \dostopclipping +%D \stoptyping + +\let \dostartclipping \gobblethreearguments +\let \dostopclipping \donothing + +%D \macros +%D {dosetupidentity} +%D +%D We can declare some characteristics of the document with +%D +%D \starttyping +%D \dosetupidentity {title} {subject} {author} {creator} {date} {keys} +%D \stoptyping +%D +%D All data is in string format. + +\let \dosetupidentity \gobblesixarguments + +%D \macros +%D {dosetuppaper} +%D +%D This special can be used to tell the driver what page size +%D to use. The special takes three arguments. +%D +%D \starttyping +%D \dosetuppaper {type} {width} {height} +%D \stoptyping +%D +%D The type is one of the common identifiers, like A4, A5 or +%D B2. + +\let \dosetuppaper \gobblethreearguments + +%D \macros +%D {dosetupprinter} +%D +%D Some drivers enable the user to specify the paper type +%D used and/or page dimensions to be taken into account. +%D +%D \starttyping +%D \dosetupprinter {type} {hoffset} {voffset} {width} {height} +%D \stoptyping +%D +%D The first argument is one of \type{letter}, \type{legal}, +%D \type{A4}, \type{A5} etc. The dimensions are in +%D basepoints. + +\let \dosetupprinter \gobblefourarguments + +%D \macros +%D {dosetupopenaction, dosetupclosaction, +%D dosetupopenpageaction, dosetupclospageaction, +%D dosetupinteraction, +%D dosetupscreen, +%D dosetupviewmode} +%D +%D Here come some obscure interactive commands. Probably the +%D specs will change with the development of the macros that +%D use them. +%D +%D The first ones can be used to set up the interaction. +%D +%D \starttyping +%D \dosetupinteraction +%D \stoptyping +%D +%D Normally this command does nothing but giving a message +%D that some scheme is supported. +%D +%D \starttyping +%D \dosetupstartaction +%D \dosetupstopaction +%D \stoptyping +%D +%D These two setup the actions to be executed when the document +%D is opened and closed. +%D +%D The next commands sets up the page and screen. They are +%D kind of related. +%D +%D \starttyping +%D \dosetuppage {hoffset} {voffset} {width} {height} {options} +%D \dosetupscreen {hoffset} {voffset} {width} {height} {options} +%D \stoptyping +%D +%D The first four arguments are in points. Option~1 results in a +%D full screen launch. +%D +%D \starttyping +%D \dosetuppageview {keyword} +%D \stoptyping +%D +%D For the moment we only support \type{fit}. + +\let \dosetupinteraction \donothing +\let \dosetupopenaction \donothing +\let \dosetupscreen \gobblefourarguments +\let \dosetuppageview \gobbleoneargument +\let \dosetupcloseaction \donothing +\let \dosetupopenpageaction \donothing +\let \dosetupclosepageaction \donothing +\let \dosetuprenderingopenpageaction \donothing +\let \dosetuprenderingclosepageaction \donothing +\let \dosetupcropbox \gobblefourarguments +\let \dosetuptrimbox \gobblefourarguments +\let \dosetupartbox \gobblefourarguments +\let \dosetupbleedbox \gobblefourarguments + +%D \macros +%D {dostarthide, +%D dostophide} +%D +%D Not every part of the screen is suitable for paper. Menus +%D for instance have no meaning on an non||interactive medium. +%D These elements are hidden by means of: +%D +%D \starttyping +%D \dostarthide .. \dostophide +%D \stoptyping + +\let \dostarthide \donothing +\let \dostophide \donothing + +%D \macros +%D {dostartgotolocation, dostopgotolocation, +%D dostartgotorealpage, dostopgotorealpage} +%D +%D When we want to support hypertext buttons, again we have +%D to deal with two concepts. +%D +%D \startitemize[packed,n] +%D \item let \TEX\ highlight the text +%D \item let the driver show us where to click +%D \stopitemize +%D +%D The first approach is the most secure one. It gives us +%D complete control over the visual appearance of hyper +%D buttons. The second alternative lets the driver guess what +%D part of the text needs highlighting. As long as we deal with +%D not too complicated textual buttons, this is no problem. +%D It's even a bit more efficient when we take long mid +%D paragraph active regions into account. When we let \TEX\ +%D handle active sentences {\em for instance marked like this +%D one}, we have to take care of line- and pagebreaks ourselve. +%D However, it's no trivial matter to let a driver find out +%D where things begin and end. Because most hyperlinks can be +%D found in tables of contents and registers, the saving in +%D terms of bytes can be neglected and the first approach is a +%D clear winner. +%D +%D The most convenient way of cross||referencing is using named +%D destinations. A more simple scheme is using page numbers as +%D destinations. Because the latter alternative can often be +%D implemented more efficient, and because we cannot be sure +%D what scheme a driver supports, we always have to supply a +%D pagenumber, even when we use named destinations. +%D +%D To enable a driver to find out what to make active, we have +%D to provide begin and endpoints, so like with color, we use +%D pairs of specials. The first scheme can be satisfied with +%D proper dimensions of the areas to be made active. +%D +%D The interactive real work is done by the following four +%D specials. The reason for providing the first one with both +%D a label and a number, is a result of the quite poor +%D implementation of \type{pdfmarks} in version 1.0 of +%D Acrobat. Because only pagenumbers were supported as +%D destination, we had to provide both labels (\DVIWINDO) and +%D pagenumbers (\PDF). Some drivers use start stop pairs. +%D +%D \starttyping +%D \dostartgotolocation {w} {h} {url} {file} {label} {page} +%D \dostartgotorealpage {w} {h} {url} {file} {page} +%D \stoptyping +%D +%D Their counterparts are: +%D +%D \starttyping +%D \dostopgotolocation +%D \dostopgotorealpage +%D \stoptyping +%D +%D The internal alternative is used for system||generated +%D links, the external one for user||generated links. The +%D Uniform Resource Locator can be used to let the reader +%D surf the net. + +\let \dostartgotolocation \gobblesixarguments +\let \dostopgotolocation \donothing +\let \dostartgotorealpage \gobblefourarguments +\let \dostopgotorealpage \donothing + +%D One may wonder why jumps to page and location are not +%D combined. By splitting them, we enable macro||packages to +%D force the prefered alternative, while on the other hand +%D drivers can pick up the alternative desired most. + +%D \macros +%D {dostartgotoJS, doflushJSpreamble} +%D +%D Rather special is the option to include and execute +%D JavaScript code. This is a typical \PDF\ option. +%D +%D \starttyping +%D \dostartgotoJS {w} {h} {script} +%D \stoptyping +%D +%D This not so standard \TEX\ feature should be used with +%D care. Preamble scripts are flushed by +%D +%D \doflushJSpreamble {script} + +\let \dostartgotoJS \gobblethreearguments +\let \dostopgotoJS \donothing +\let \doflushJSpreamble \gobbleoneargument + +%D \macros +%D {dostartthisislocation, dostopthisislocation, +%D dostartthisisrealpage, dostopthisisrealpage} +%D +%D Before we can goto some location or page, we have to tell +%D the system where it can be found. Because some drivers +%D follow the \SGML\ approach of begin||end tags, we have to +%D support pairs. A possible extension to this scheme is +%D supplying coordinates for viewing the text. +%D +%D The opposite commands of \type{\dogotosomething} have only +%D one argument: +%D +%D \starttyping +%D \dostartthisislocation {label} +%D \dostartthisisrealpage {page} +%D \stoptyping +%D +%D These commands are accompanied by: +%D +%D \starttyping +%D \dostopthisislocation +%D \dostopthisisrealpage +%D \stoptyping +%D +%D As with all interactive commands's they are installed as +%D \type{and} category specials. + +\let \dostartthisislocation \gobbleoneargument +\let \dostopthisislocation \donothing +\let \dostartthisisrealpage \gobbleoneargument +\let \dostopthisisrealpage \donothing + +%D In \CONTEXT\ we don't use the \type{\stopsomething} +%D macros because we let \TEX\ take care of typographic +%D issues. + +%D \macros +%D {doresetgotowhereever} +%D +%D These and others need: + +\let \doresetgotowhereever \donothing + +%D \macros +%D {dostartexecutecommand, dostopexecutecommand} +%D +%D The actual behavior of the next pair of commands depends +%D much on the viewing engine. Therefore one cannot depend +%D too much on their support. +%D +%D \starttyping +%D \dostartexecutecommand {w} {h} {command} {options} +%D \stoptyping +%D +%D At least the next commands are supported (more examples +%D can be found in \type {spec-fdf.tex}: +%D +%D \startlinecorrection\setupalign[middle]\leavevmode +%D \starttable[|l|l|] +%D \HL +%D \NC \bf command \NC \bf action \NC\SR +%D \HL +%D \NC first \NC go to the first page \NC\FR +%D \NC previous \NC go to the previous page \NC\MR +%D \NC next \NC go to the next page \NC\MR +%D \NC last \NC go to the last page \NC\MR +%D \NC backward \NC go back to the link list \NC\MR +%D \NC forward \NC go forward in the link list \NC\MR +%D \NC print \NC enter print mode \NC\MR +%D \NC exit \NC exit viewer \NC\MR +%D \NC close \NC close document \NC\MR +%D \NC enter \NC enter viewer \NC\MR +%D \NC help \NC show help on the viewer \NC\LR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D Options are to be passed as a comma separated list of +%D assignments. + +\let \dostartexecutecommand \gobblefourarguments +\let \dostopexecutecommand \donothing + +%D \macros +%D {dostartobject, +%D dostopobject, +%D doresetobjects, +%D doinsertobject} +%D +%D Reuse of object can reduce the output filesize +%D considerably. Reusable objects are implemented with: +%D +%D \starttyping +%D \dostartobject{class}{name}{width}{height}{depth} +%D some typeset material +%D \dostopobject +%D \stoptyping +%D +%D \starttyping +%D \doinsertobject{class}{name} +%D \stoptyping +%D +%D The savings can be huge in interactive texts. The next macro needs +%D to be called after a graphic is inserted (in order to clean up +%D global references). +%D +%D \starttyping +%D \doresetobjects +%D \stoptyping + +\let \dostartobject \gobblefourarguments +\let \dostopobject \donothing +\let \doinsertobject \gobbletwoarguments +\let \doresetobjects \donothing + +%D \macros +%D {doregisterfigure, doregisterfigurecolor} +%D +%D Images can be objects as well and it's up to the driver to +%D handle this. Alternative images are also up to the driver, +%D and the next macro tells the driver that the previous image +%D is somehow followed by another and that both have to be +%D handled together. This is a rather fuzzy model, but for the +%D moment it suits its purpose: low res screen versions combined +%D with high res printable ones. + +\let \doregisterfigure \gobbletwoarguments +\let \doregisterfigurecolor \gobbleoneargument + +% %D \macros +% %D {dogetobjectreference} +% %D +% %D For very special purposes, one can ask for the internal +% %D reference to the object. Beware! +% +% \let \dogetobjectreference \gobblethreearguments +% +% %D The first argument is the name, the second a macro that +% %D gets the associated value. + +%D \macros +%D {dostartrunprogram, dostoprunprogram, +%D dostartgotoprofile, dostopgotoprofile, +%D dobeginofprofile, +%D doendofprofile} +%D +%D These specials are still experimental. They are not yet +%D supported by the programs the way they should be. +%D +%D {\em --- still undocumented ---} + +\let \dostartrunprogram \gobblefourarguments +\let \dostoprunprogram \donothing +\let \dostartgotoprofile \gobblethreearguments +\let \dostopgotoprofile \donothing +\let \dobeginofprofile \gobblefourarguments +\let \doendofprofile \donothing + +%D \macros +%D {doinsertbookmark} +%D +%D Bookmarks, that is viewer generated tables of contents, are +%D a strange phenomena, mainly because \TEX\ can provide +%D whatever kind of table in much better quality. + +\let \doinsertbookmark \gobblefourarguments + +%D This special is called as: +%D +%D \starttyping +%D \doinstallbookmark {level} {nofsubentries} {text} {page} {open} +%D \stoptyping +%D +%D This definition is very \PDF\ oriented, so for more +%D information we kindly refer to the \PDF\ manuals. + +%D \macros +%D {dosetpagetransition} +%D +%D In presentations, fancy page transitions can, at least for a +%D short moment, let the audience focus at the screen. Like the +%D previous one, this special is very \PDF. +%D +%D \starttyping +%D \dosetpagetransition{dissolve}{0} +%D \stoptyping +%D +%D Transitions have symbolic names, like dissolve, box, split, +%D blinds, wipe and glitter. The second argument determines +%D the wait time (unless zero). + +\let \dosetpagetransition \gobbletwoarguments + +%D \macros +%D {dopresettextfield,dopresetlinefield, +%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, +%D dopresetbuttonfield,dopresetcheckfield, +%D dopresetradiofield,dopresetradiorecord} +%D +%D The special drivers are programmed independant from their +%D calling macros are thereby use the standard \TEX\ way of +%D passing parameters. Unfortunately fields often have more +%D than nine characteristics, so we pack some arguments in one. +%D +%D \starttyping +%D \dopresettextfield / \dopresetlinefield +%D {name} {width} {height} {default} {length} +%D {style,color} {options} {alignment} {actions} +%D +%D \dopresetchoicefield / \dopresetpopupfield / \dopresetcombofield +%D {name} {width} {height} {default} +%D {style,color} {options} {values} {actions} +%D +%D \dopresetpushfield +%D {name} {width} {height} {default} +%D {options} {values} {actions} +%D +%D \dopresetcheckfield +%D {name} {width} {height} {default} +%D {options} {values} {actions} +%D +%D \dopresetradiofield +%D {name} {width} {height} {default} +%D {options} {parent} {values} {actions} +%D +%D \dopresetradiorecord +%D {name} {top} {options} {kids} {actions} +%D \stoptyping + +\let \dopresetlinefield \gobbleninearguments +\let \dopresettextfield \gobbleninearguments +\let \dopresetchoicefield \gobbleeightarguments +\let \dopresetpopupfield \gobbleeightarguments +\let \dopresetcombofield \gobbleeightarguments +\let \dopresetpushfield \gobblesevenarguments +\let \dopresetcheckfield \gobblesevenarguments +\let \dopresetradiofield \gobbleeightarguments +\let \dopresetradiorecord \gobblefourarguments + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} +%D +%D Field sets, used in resetting and submitting, are handled +%D by: + +\let \dodefinefieldset \gobbletwoarguments +\let \dogetfieldset \gobbleoneargument +\let \doiffieldset \gobbletwoarguments + +%D \macros +%D {dosetfieldstatus} +%D +%D For practical reasons we set some field characteristics +%D using: +%D +%D \starttyping +%D \dosetfieldstatus {mode} {parent} {kids} {root} +%D \stoptyping + +\let \dosetfieldstatus \gobblefourarguments + +%D with: + +\def\fieldlonermode {0} % no \chardef here +\def\fieldparentmode{1} % no \chardef here +\def\fieldchildmode {2} % no \chardef here +\def\fieldcopymode {3} % no \chardef here + +%D \macros +%D {doregistercalculationset} +%D +%D We can define a calculation order list with: +%D +%D \starttyping +%D \doregistercalculationset {set identifier} +%D \stoptyping + +\let \doregistercalculationset \gobbleoneargument + +%D \macros +%D {doinsertcomment, doflushcomments} +%D +%D Not so much out of need, but to be complete, we also +%D implement text annotations, so called comment: +%D +%D \starttyping +%D \doinsertcomment +%D {title} {width} {height} {color} {open} {symbol} {collect} {data} +%D \stoptyping +%D +%D When enables, comments can be collected and flushed: +%D +%D \starttyping +%D \doflushcomments +%D \stoptyping + +\let \doinsertcomment \gobbleeightarguments +\let \doflushcomments \donothing + +%D \macros +%D {dostarttransparency,dostoptransparency} +%D +%D \starttyping +%D \dostarttransparency{fraction}{type} +%D \dostoptransparency +%D \stoptyping +%D +%D Although in \CONTEXT\ transparency is closely integrated +%D in the color drivers, in the end it is an independent +%D feature. + +\let \dostarttransparency \gobbletwoarguments +\let \dostoptransparency \donothing + +%D \macros +%D {doattachfile} +%D +%D \starttyping +%D \doattachfile{title}{width}{height}{depth}{color}{symbol}{filename}{source} +%D \stoptyping + +\let \doattachfile \gobbleeightarguments + +%D Experimental (properties): + +\let \dostartviewerlayer \gobbleoneargument +\let \dostopviewerlayer \donothing +\let \dodefineviewerlayer \gobblefivearguments +\let \domakeviewerlayerlist \gobbleoneargument + +\let \doinsertrenderingwindow \gobblefourarguments +\let \doinsertrendering \gobblefourarguments +\let \doinsertrenderingobject \gobblefourarguments +\let \doinsertrenderingobject \gobblefourarguments + +\let \dostartfonteffect \gobblethreearguments +\let \dostopfonteffect \donothing + +%D From now on, mapfile loading is also a special; we assume the +%D more or less standard dvips syntax. + +\let \doresetmapfilelist \donothing +\let \doloadmapfile \gobbletwoarguments % + - = | filename +\let \doloadmapline \gobbletwoarguments % + - = | fileline + +%D \macros +%D {ifusepagedestinations} +%D +%D In \PDF\ version 1.0 only page references were supported, +%D while in \DVIWINDO\ 1.N only named references were accepted. +%D Therefore \CONTEXT\ supports both methods of referencing. In +%D \PDF\ version 1.1 named destinations arrived. Lack of +%D continuous support of version 1.1 viewers for \MSDOS\ +%D therefore sometimes forces us to prefer page references. As +%D a bonus, they are faster too and have no limitations. How +%D fortunate we were having both mechanisms available when the +%D version 3.0 (\PDF\ version 1.2) viewers proved to be too +%D bugged to support named destinations. + +\newif\ifusepagedestinations + +%D \macros +%D {ifhighlighthyperlinks} +%D +%D The next switch can be used to make user hyperlinks are +%D not highlighted when clicked on. + +\newif\ifhighlighthyperlinks + +%D \macros +%D {ifgotonewwindow} +%D +%D To make the {\em goto previous jump} feature more +%D convenient when using more than one file, it makes sense +%D to force the viewer to open a new window for each file +%D opened. + +\newif\ifgotonewwindow + +%D \macros +%D {jobsuffix} +%D +%D By default, \TEX\ produces \DVI\ files which can be +%D converted to other filetypes. Sometimes it is handy to +%D know what the target file will be. In other driver +%D modules we wil set \type {\jobsuffix} to \type {pdf}. + +% this will become a mode + +\def\jobsuffix{pdf} + +\ifdefined\resetsystemmode \else + \let\setsystemmode \gobbleoneargument + \let\resetsystemmode\gobbleoneargument +\fi + +\def\setjobsuffix#1% + {\resetsystemmode\jobsuffix + \edef\jobsuffix{#1}% + \setsystemmode\jobsuffix} + +%D \macros +%D {everyresetspecials} +%D +%D Now what will this one do? We'll see in a few lines. + +\newtoks\everyresetspecials + +\appendtoksonce + \ifdefined\setjobsuffix\setjobsuffix{pdf}\fi +\to \everyresetspecials + +\def\defineoutput{\dodoubleargument\dodefineoutput} + +\def\usespecials [#1]{} +\def\dodefineoutput[#1][#2]{} +\def\setupoutput [#1]{} + +\protect \endinput diff --git a/tex/context/base/back-ini.tex b/tex/context/base/back-ini.tex deleted file mode 100644 index a60b6a329..000000000 --- a/tex/context/base/back-ini.tex +++ /dev/null @@ -1,896 +0,0 @@ -%D \module -%D [ file=back-ini, -%D version=2009.04.15, -%D title=\CONTEXT\ Backend Macros, -%D subtitle=Initialization, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Backend Macros / Initialization} - -\registerctxluafile{back-ini}{1.001} - -%D We currently have a curious mix between tex and lua backend -%D handling but eventually most will move to lua. - -\unprotect - -%D Right from the start \CONTEXT\ had a backend system based on -%D runtime pluggable code. As most backend issues involved specials -%D and since postprocessors had not that much in common, we ended up -%D with a system where we could switch backend as well as output code -%D for multiple backends at the same time. -%D -%D Because \LUATEX\ has the backend built in, and since some backend -%D issues have been moved to the frontend I decided to provide new -%D backend code for \MKIV, starting with what was actually used. -%D -%D At this moment \DVI\ is no longer used for advanced document -%D output and we therefore dropped support for this format. Future -%D versions might support more backends again, but this has a low -%D priority. -%D -%D The big question is: what is to be considered a backend issue and -%D what not. For the moment we treat image inclusion, object reuse, -%D position tracking and color as frontend issues, if only because we -%D deal with them via \LUA\ code and as such we don't depend too much -%D on macro calls that need to inject code for the backend. -%D -%D Not everything here makes sense and the content of this file will -%D definitely change. - -%D We use a couple of (global) variables because it saves us the -%D trouble of dealing with arguments. - -\letempty \@@DriverFieldName -\letempty \@@DriverFieldWidth -\letempty \@@DriverFieldHeight -\letempty \@@DriverFieldDefault -\letempty \@@DriverFieldNumber -\letempty \@@DriverFieldNumber -\letempty \@@DriverFieldStyle -\letempty \@@DriverFieldColor -\letempty \@@DriverFieldBackgroundColor -\letempty \@@DriverFieldFrameColor -\letempty \@@DriverFieldLayer -\letempty \@@DriverFieldOption -\letempty \@@DriverFieldAlign -\letempty \@@DriverFieldClickIn -\letempty \@@DriverFieldClickOut -\letempty \@@DriverFieldRegionIn -\letempty \@@DriverFieldRegionOut -\letempty \@@DriverFieldAfterKey -\letempty \@@DriverFieldFormat -\letempty \@@DriverFieldValidate -\letempty \@@DriverFieldCalculate -\letempty \@@DriverFieldFocusIn -\letempty \@@DriverFieldFocusOut - -\letempty \@@DriverCommentLayer -\letempty \@@DriverAttachmentLayer - -\letempty \@@DriverImageBox -\letempty \@@DriverImageOptions -\letempty \@@DriverImageWidth -\letempty \@@DriverImageHeight -\letempty \@@DriverImageFile -\letempty \@@DriverImageLabel -\letempty \@@DriverImageType -\letempty \@@DriverImageMethod -\letempty \@@DriverImagePage - -\newif\ifcollectreferenceactions - -%D \macros -%D {dostartgraymode,dostopgraymode, -%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,dostopcolormode} -%D -%D Switching to and from color can be done in two ways: -%D -%D \startitemize[packed,n] -%D \item insert driver specific commands -%D \item pass instructions to the output device -%D \stopitemize -%D -%D The first approach is more general and lays the -%D responsibility at the driver side. Probably due to the fact -%D that \TEX\ does not directly support color, we have been -%D confronted for the last few years with changing special -%D definitions. The need for support depends on how a macro -%D package handles colored text that crosses the page boundary. -%D Again, there are two approaches. -%D -%D \startitemize[packed,n] -%D \item let \TEX\ do the job -%D \item let the driver handle things -%D \stopitemize -%D -%D The first approach is as driver independant as possible and -%D can easily be accomplished by using \TEX's mark mechanism. -%D In \CONTEXT\ we follow this approach. More and more, drivers -%D are starting to support color, including stacking them. -%D -%D Colors as well as grayscales can be represented in scales -%D from~0 to~1. When drivers use values in the range 0..255, -%D this value has to be adapted in the translation process. -%D Technically it's possible to get a grayscale from combining -%D colors. In the \cap{RGB} color system, a color with Red, -%D Green and Blue components of 0.80 show the same gray as a -%D Gray Scale specified 0.80. The \cap{CMYK} color system -%D supports a Black component apart from Cyan, Magenta and -%D Yellow. -%D -%D Depending on the target format, color support differs from -%D gray support. PostScript for example offers different -%D operators for setting gray and color. This is because -%D printing something using three colors is someting else than -%D printing with just black. -%D -%D In \CONTEXT\ we have implemented a color subsystem that -%D supports the use of well defined colors that, when printed -%D in black and white, still can be distinguished. This -%D approach enables us to serve both printed and electronic -%D versions, using colored text and illustrations. More on the -%D fundamentals of this topic can be found in the \cap{MAPS} of -%D the Dutch User Group, 14 (95.1). -%D -%D To satisfy all those needs, we define four specials which -%D supply enough information for drivers to act upon. We -%D could have used more general commands with the keywords -%D 'rgb' and 'gray', but because these specials are used often, -%D we prefer the more direct and shorter alternative. -%D -%D We start with the installation of color and grayscale -%D specials. The values are in the range 0..1 (e.g. 0.25). -%D -%D \starttyping -%D \dostartgraymode {gray} ... \dostopgraymode -%D \dostartrgbcolormode {red} {green} {blue} ... \dostopcolormode -%D \dostartcmykcolormode {cyan} {magenta} {yellow} {black} ... \dostopcolormode -%D \dostartgraycolormode {gray} ... \dostopcolormode -%D \stoptyping -%D -%D Because we can expect conflicts between drivers, we -%D implement them as category \type{or}. In previous versions -%D of \DVIPSONE\ the use of their color||specials did not -%D interfere with the PostScript ones, but recent versions do. - -\let \dostartgraymode \gobbleoneargument -\let \dostopgraymode \donothing -\let \dostartrgbcolormode \gobblethreearguments -\let \dostartcmykcolormode \gobblefourarguments -\let \dostartgraycolormode \gobbleoneargument -\let \dostopcolormode \donothing -\let \dostartspotcolormode \gobbletwoarguments -\let \doregisterrgbspotcolor \gobblesevenarguments -\let \doregistercmykspotcolor \gobbleeightarguments -\let \doregistergrayspotcolor \gobblefourarguments -\let \doregisterrgbindexcolor \gobblesevenarguments -\let \doregistercmykindexcolor \gobbleeightarguments -\let \doregistergrayindexcolor \gobblefourarguments -\let \doregisterspotcolorname \gobbletwoarguments -\let \dostartnonecolormode \donothing -\let \doregisternonecolor \donothing - -%D \macros -%D {doinsertsoundtrack} -%D -%D Sounds are (for the moment) just files with -%D associated options. -%D -%D \starttyping -%D \doinsertsoundtrack {file} {label} {options} -%D \stoptyping - -\let \doinsertsoundtrack \gobblethreearguments - -%D \macros -%D {dostartrotation,dostoprotation, -%D dostartscaling,dostopscaling, -%D dostartmirroring,dostopmirroring, -%D dostartnegative,dostopnegative} -%D dostartoverprint,dostopoverprint} -%D -%D We support a couple of transformations and renderings: -%D -%D \starttyping -%D \dostartrotation {angle} ... \dostoprotation -%D \dostartscaling {x} {y} ... \dostopscaling -%D \dostartmirroring {x} {y} ... \dostopmirroring -%D \stoptyping - -\let \dostartrotation \gobbleoneargument -\let \dostoprotation \donothing -\let \dostartscaling \gobbletwoarguments -\let \dostopscaling \donothing -\let \dostartmirroring \donothing -\let \dostopmirroring \donothing - -\let \dostartnegative \donothing -\let \dostopnegative \donothing -\let \dostartoverprint \donothing -\let \dostopoverprint \donothing - -%D The following two specials are used in for instance \type -%D {\vadjust}'d margin material inside colored paragraphs. - -\let \dostartgraphicgroup \donothing -\let \dostopgraphicgroup \donothing - -%D \macros -%D {doselectfirstpaperbin, -%D doselectsecondpaperbin} -%D -%D Here are some very printer||specific ones. No further -%D comment. - -\let \doselectfirstpaperbin \donothing -\let \doselectsecondpaperbin \donothing - -%D \macros -%D {doovalbox} -%D -%D When we look at the implementation, this is a complicated -%D one. There are seven arguments. -%D -%D \starttyping -%D \doovalbox {w} {h} {d} {linewidth} {radius} {stroke} {fill} {variant} -%D \stoptyping -%D -%D This command has to return a \type{\vbox} which can be used -%D to lay over another one (with text). The radius is in -%D degrees, the stroke and fill are~\type{1} (true) of~\type{0} -%D (false). - -\let \doovalbox \gobbleeightarguments - -%D \macros -%D {dostartclipping,dostopclipping} -%D -%D Clipping is implemented in such a way that an arbitrary code -%D can be fed. -%D -%D \starttyping -%D \dostartclipping {pathname} {width} {height} -%D \dostopclipping -%D \stoptyping - -\let \dostartclipping \gobblethreearguments -\let \dostopclipping \donothing - -%D \macros -%D {dosetupidentity} -%D -%D We can declare some characteristics of the document with -%D -%D \starttyping -%D \dosetupidentity {title} {subject} {author} {creator} {date} {keys} -%D \stoptyping -%D -%D All data is in string format. - -\let \dosetupidentity \gobblesixarguments - -%D \macros -%D {dosetuppaper} -%D -%D This special can be used to tell the driver what page size -%D to use. The special takes three arguments. -%D -%D \starttyping -%D \dosetuppaper {type} {width} {height} -%D \stoptyping -%D -%D The type is one of the common identifiers, like A4, A5 or -%D B2. - -\let \dosetuppaper \gobblethreearguments - -%D \macros -%D {dosetupprinter} -%D -%D Some drivers enable the user to specify the paper type -%D used and/or page dimensions to be taken into account. -%D -%D \starttyping -%D \dosetupprinter {type} {hoffset} {voffset} {width} {height} -%D \stoptyping -%D -%D The first argument is one of \type{letter}, \type{legal}, -%D \type{A4}, \type{A5} etc. The dimensions are in -%D basepoints. - -\let \dosetupprinter \gobblefourarguments - -%D \macros -%D {dosetupopenaction, dosetupclosaction, -%D dosetupopenpageaction, dosetupclospageaction, -%D dosetupinteraction, -%D dosetupscreen, -%D dosetupviewmode} -%D -%D Here come some obscure interactive commands. Probably the -%D specs will change with the development of the macros that -%D use them. -%D -%D The first ones can be used to set up the interaction. -%D -%D \starttyping -%D \dosetupinteraction -%D \stoptyping -%D -%D Normally this command does nothing but giving a message -%D that some scheme is supported. -%D -%D \starttyping -%D \dosetupstartaction -%D \dosetupstopaction -%D \stoptyping -%D -%D These two setup the actions to be executed when the document -%D is opened and closed. -%D -%D The next commands sets up the page and screen. They are -%D kind of related. -%D -%D \starttyping -%D \dosetuppage {hoffset} {voffset} {width} {height} {options} -%D \dosetupscreen {hoffset} {voffset} {width} {height} {options} -%D \stoptyping -%D -%D The first four arguments are in points. Option~1 results in a -%D full screen launch. -%D -%D \starttyping -%D \dosetuppageview {keyword} -%D \stoptyping -%D -%D For the moment we only support \type{fit}. - -\let \dosetupinteraction \donothing -\let \dosetupopenaction \donothing -\let \dosetupscreen \gobblefourarguments -\let \dosetuppageview \gobbleoneargument -\let \dosetupcloseaction \donothing -\let \dosetupopenpageaction \donothing -\let \dosetupclosepageaction \donothing -\let \dosetuprenderingopenpageaction \donothing -\let \dosetuprenderingclosepageaction \donothing -\let \dosetupcropbox \gobblefourarguments -\let \dosetuptrimbox \gobblefourarguments -\let \dosetupartbox \gobblefourarguments -\let \dosetupbleedbox \gobblefourarguments - -%D \macros -%D {dostarthide, -%D dostophide} -%D -%D Not every part of the screen is suitable for paper. Menus -%D for instance have no meaning on an non||interactive medium. -%D These elements are hidden by means of: -%D -%D \starttyping -%D \dostarthide .. \dostophide -%D \stoptyping - -\let \dostarthide \donothing -\let \dostophide \donothing - -%D \macros -%D {dostartgotolocation, dostopgotolocation, -%D dostartgotorealpage, dostopgotorealpage} -%D -%D When we want to support hypertext buttons, again we have -%D to deal with two concepts. -%D -%D \startitemize[packed,n] -%D \item let \TEX\ highlight the text -%D \item let the driver show us where to click -%D \stopitemize -%D -%D The first approach is the most secure one. It gives us -%D complete control over the visual appearance of hyper -%D buttons. The second alternative lets the driver guess what -%D part of the text needs highlighting. As long as we deal with -%D not too complicated textual buttons, this is no problem. -%D It's even a bit more efficient when we take long mid -%D paragraph active regions into account. When we let \TEX\ -%D handle active sentences {\em for instance marked like this -%D one}, we have to take care of line- and pagebreaks ourselve. -%D However, it's no trivial matter to let a driver find out -%D where things begin and end. Because most hyperlinks can be -%D found in tables of contents and registers, the saving in -%D terms of bytes can be neglected and the first approach is a -%D clear winner. -%D -%D The most convenient way of cross||referencing is using named -%D destinations. A more simple scheme is using page numbers as -%D destinations. Because the latter alternative can often be -%D implemented more efficient, and because we cannot be sure -%D what scheme a driver supports, we always have to supply a -%D pagenumber, even when we use named destinations. -%D -%D To enable a driver to find out what to make active, we have -%D to provide begin and endpoints, so like with color, we use -%D pairs of specials. The first scheme can be satisfied with -%D proper dimensions of the areas to be made active. -%D -%D The interactive real work is done by the following four -%D specials. The reason for providing the first one with both -%D a label and a number, is a result of the quite poor -%D implementation of \type{pdfmarks} in version 1.0 of -%D Acrobat. Because only pagenumbers were supported as -%D destination, we had to provide both labels (\DVIWINDO) and -%D pagenumbers (\PDF). Some drivers use start stop pairs. -%D -%D \starttyping -%D \dostartgotolocation {w} {h} {url} {file} {label} {page} -%D \dostartgotorealpage {w} {h} {url} {file} {page} -%D \stoptyping -%D -%D Their counterparts are: -%D -%D \starttyping -%D \dostopgotolocation -%D \dostopgotorealpage -%D \stoptyping -%D -%D The internal alternative is used for system||generated -%D links, the external one for user||generated links. The -%D Uniform Resource Locator can be used to let the reader -%D surf the net. - -\let \dostartgotolocation \gobblesixarguments -\let \dostopgotolocation \donothing -\let \dostartgotorealpage \gobblefourarguments -\let \dostopgotorealpage \donothing - -%D One may wonder why jumps to page and location are not -%D combined. By splitting them, we enable macro||packages to -%D force the prefered alternative, while on the other hand -%D drivers can pick up the alternative desired most. - -%D \macros -%D {dostartgotoJS, doflushJSpreamble} -%D -%D Rather special is the option to include and execute -%D JavaScript code. This is a typical \PDF\ option. -%D -%D \starttyping -%D \dostartgotoJS {w} {h} {script} -%D \stoptyping -%D -%D This not so standard \TEX\ feature should be used with -%D care. Preamble scripts are flushed by -%D -%D \doflushJSpreamble {script} - -\let \dostartgotoJS \gobblethreearguments -\let \dostopgotoJS \donothing -\let \doflushJSpreamble \gobbleoneargument - -%D \macros -%D {dostartthisislocation, dostopthisislocation, -%D dostartthisisrealpage, dostopthisisrealpage} -%D -%D Before we can goto some location or page, we have to tell -%D the system where it can be found. Because some drivers -%D follow the \SGML\ approach of begin||end tags, we have to -%D support pairs. A possible extension to this scheme is -%D supplying coordinates for viewing the text. -%D -%D The opposite commands of \type{\dogotosomething} have only -%D one argument: -%D -%D \starttyping -%D \dostartthisislocation {label} -%D \dostartthisisrealpage {page} -%D \stoptyping -%D -%D These commands are accompanied by: -%D -%D \starttyping -%D \dostopthisislocation -%D \dostopthisisrealpage -%D \stoptyping -%D -%D As with all interactive commands's they are installed as -%D \type{and} category specials. - -\let \dostartthisislocation \gobbleoneargument -\let \dostopthisislocation \donothing -\let \dostartthisisrealpage \gobbleoneargument -\let \dostopthisisrealpage \donothing - -%D In \CONTEXT\ we don't use the \type{\stopsomething} -%D macros because we let \TEX\ take care of typographic -%D issues. - -%D \macros -%D {doresetgotowhereever} -%D -%D These and others need: - -\let \doresetgotowhereever \donothing - -%D \macros -%D {dostartexecutecommand, dostopexecutecommand} -%D -%D The actual behavior of the next pair of commands depends -%D much on the viewing engine. Therefore one cannot depend -%D too much on their support. -%D -%D \starttyping -%D \dostartexecutecommand {w} {h} {command} {options} -%D \stoptyping -%D -%D At least the next commands are supported (more examples -%D can be found in \type {spec-fdf.tex}: -%D -%D \startlinecorrection\setupalign[middle]\leavevmode -%D \starttable[|l|l|] -%D \HL -%D \NC \bf command \NC \bf action \NC\SR -%D \HL -%D \NC first \NC go to the first page \NC\FR -%D \NC previous \NC go to the previous page \NC\MR -%D \NC next \NC go to the next page \NC\MR -%D \NC last \NC go to the last page \NC\MR -%D \NC backward \NC go back to the link list \NC\MR -%D \NC forward \NC go forward in the link list \NC\MR -%D \NC print \NC enter print mode \NC\MR -%D \NC exit \NC exit viewer \NC\MR -%D \NC close \NC close document \NC\MR -%D \NC enter \NC enter viewer \NC\MR -%D \NC help \NC show help on the viewer \NC\LR -%D \HL -%D \stoptable -%D \stoplinecorrection -%D -%D Options are to be passed as a comma separated list of -%D assignments. - -\let \dostartexecutecommand \gobblefourarguments -\let \dostopexecutecommand \donothing - -%D \macros -%D {dostartobject, -%D dostopobject, -%D doresetobjects, -%D doinsertobject} -%D -%D Reuse of object can reduce the output filesize -%D considerably. Reusable objects are implemented with: -%D -%D \starttyping -%D \dostartobject{class}{name}{width}{height}{depth} -%D some typeset material -%D \dostopobject -%D \stoptyping -%D -%D \starttyping -%D \doinsertobject{class}{name} -%D \stoptyping -%D -%D The savings can be huge in interactive texts. The next macro needs -%D to be called after a graphic is inserted (in order to clean up -%D global references). -%D -%D \starttyping -%D \doresetobjects -%D \stoptyping - -\let \dostartobject \gobblefourarguments -\let \dostopobject \donothing -\let \doinsertobject \gobbletwoarguments -\let \doresetobjects \donothing - -%D \macros -%D {doregisterfigure, doregisterfigurecolor} -%D -%D Images can be objects as well and it's up to the driver to -%D handle this. Alternative images are also up to the driver, -%D and the next macro tells the driver that the previous image -%D is somehow followed by another and that both have to be -%D handled together. This is a rather fuzzy model, but for the -%D moment it suits its purpose: low res screen versions combined -%D with high res printable ones. - -\let \doregisterfigure \gobbletwoarguments -\let \doregisterfigurecolor \gobbleoneargument - -% %D \macros -% %D {dogetobjectreference} -% %D -% %D For very special purposes, one can ask for the internal -% %D reference to the object. Beware! -% -% \let \dogetobjectreference \gobblethreearguments -% -% %D The first argument is the name, the second a macro that -% %D gets the associated value. - -%D \macros -%D {dostartrunprogram, dostoprunprogram, -%D dostartgotoprofile, dostopgotoprofile, -%D dobeginofprofile, -%D doendofprofile} -%D -%D These specials are still experimental. They are not yet -%D supported by the programs the way they should be. -%D -%D {\em --- still undocumented ---} - -\let \dostartrunprogram \gobblefourarguments -\let \dostoprunprogram \donothing -\let \dostartgotoprofile \gobblethreearguments -\let \dostopgotoprofile \donothing -\let \dobeginofprofile \gobblefourarguments -\let \doendofprofile \donothing - -%D \macros -%D {doinsertbookmark} -%D -%D Bookmarks, that is viewer generated tables of contents, are -%D a strange phenomena, mainly because \TEX\ can provide -%D whatever kind of table in much better quality. - -\let \doinsertbookmark \gobblefourarguments - -%D This special is called as: -%D -%D \starttyping -%D \doinstallbookmark {level} {nofsubentries} {text} {page} {open} -%D \stoptyping -%D -%D This definition is very \PDF\ oriented, so for more -%D information we kindly refer to the \PDF\ manuals. - -%D \macros -%D {dosetpagetransition} -%D -%D In presentations, fancy page transitions can, at least for a -%D short moment, let the audience focus at the screen. Like the -%D previous one, this special is very \PDF. -%D -%D \starttyping -%D \dosetpagetransition{dissolve}{0} -%D \stoptyping -%D -%D Transitions have symbolic names, like dissolve, box, split, -%D blinds, wipe and glitter. The second argument determines -%D the wait time (unless zero). - -\let \dosetpagetransition \gobbletwoarguments - -%D \macros -%D {dopresettextfield,dopresetlinefield, -%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, -%D dopresetbuttonfield,dopresetcheckfield, -%D dopresetradiofield,dopresetradiorecord} -%D -%D The special drivers are programmed independant from their -%D calling macros are thereby use the standard \TEX\ way of -%D passing parameters. Unfortunately fields often have more -%D than nine characteristics, so we pack some arguments in one. -%D -%D \starttyping -%D \dopresettextfield / \dopresetlinefield -%D {name} {width} {height} {default} {length} -%D {style,color} {options} {alignment} {actions} -%D -%D \dopresetchoicefield / \dopresetpopupfield / \dopresetcombofield -%D {name} {width} {height} {default} -%D {style,color} {options} {values} {actions} -%D -%D \dopresetpushfield -%D {name} {width} {height} {default} -%D {options} {values} {actions} -%D -%D \dopresetcheckfield -%D {name} {width} {height} {default} -%D {options} {values} {actions} -%D -%D \dopresetradiofield -%D {name} {width} {height} {default} -%D {options} {parent} {values} {actions} -%D -%D \dopresetradiorecord -%D {name} {top} {options} {kids} {actions} -%D \stoptyping - -\let \dopresetlinefield \gobbleninearguments -\let \dopresettextfield \gobbleninearguments -\let \dopresetchoicefield \gobbleeightarguments -\let \dopresetpopupfield \gobbleeightarguments -\let \dopresetcombofield \gobbleeightarguments -\let \dopresetpushfield \gobblesevenarguments -\let \dopresetcheckfield \gobblesevenarguments -\let \dopresetradiofield \gobbleeightarguments -\let \dopresetradiorecord \gobblefourarguments - -%D \macros -%D {dodefinefieldset,dogetfieldset,doiffieldset} -%D -%D Field sets, used in resetting and submitting, are handled -%D by: - -\let \dodefinefieldset \gobbletwoarguments -\let \dogetfieldset \gobbleoneargument -\let \doiffieldset \gobbletwoarguments - -%D \macros -%D {dosetfieldstatus} -%D -%D For practical reasons we set some field characteristics -%D using: -%D -%D \starttyping -%D \dosetfieldstatus {mode} {parent} {kids} {root} -%D \stoptyping - -\let \dosetfieldstatus \gobblefourarguments - -%D with: - -\def\fieldlonermode {0} % no \chardef here -\def\fieldparentmode{1} % no \chardef here -\def\fieldchildmode {2} % no \chardef here -\def\fieldcopymode {3} % no \chardef here - -%D \macros -%D {doregistercalculationset} -%D -%D We can define a calculation order list with: -%D -%D \starttyping -%D \doregistercalculationset {set identifier} -%D \stoptyping - -\let \doregistercalculationset \gobbleoneargument - -%D \macros -%D {doinsertcomment, doflushcomments} -%D -%D Not so much out of need, but to be complete, we also -%D implement text annotations, so called comment: -%D -%D \starttyping -%D \doinsertcomment -%D {title} {width} {height} {color} {open} {symbol} {collect} {data} -%D \stoptyping -%D -%D When enables, comments can be collected and flushed: -%D -%D \starttyping -%D \doflushcomments -%D \stoptyping - -\let \doinsertcomment \gobbleeightarguments -\let \doflushcomments \donothing - -%D \macros -%D {dostarttransparency,dostoptransparency} -%D -%D \starttyping -%D \dostarttransparency{fraction}{type} -%D \dostoptransparency -%D \stoptyping -%D -%D Although in \CONTEXT\ transparency is closely integrated -%D in the color drivers, in the end it is an independent -%D feature. - -\let \dostarttransparency \gobbletwoarguments -\let \dostoptransparency \donothing - -%D \macros -%D {doattachfile} -%D -%D \starttyping -%D \doattachfile{title}{width}{height}{depth}{color}{symbol}{filename}{source} -%D \stoptyping - -\let \doattachfile \gobbleeightarguments - -%D Experimental (properties): - -\let \dostartviewerlayer \gobbleoneargument -\let \dostopviewerlayer \donothing -\let \dodefineviewerlayer \gobblefivearguments -\let \domakeviewerlayerlist \gobbleoneargument - -\let \doinsertrenderingwindow \gobblefourarguments -\let \doinsertrendering \gobblefourarguments -\let \doinsertrenderingobject \gobblefourarguments -\let \doinsertrenderingobject \gobblefourarguments - -\let \dostartfonteffect \gobblethreearguments -\let \dostopfonteffect \donothing - -%D From now on, mapfile loading is also a special; we assume the -%D more or less standard dvips syntax. - -\let \doresetmapfilelist \donothing -\let \doloadmapfile \gobbletwoarguments % + - = | filename -\let \doloadmapline \gobbletwoarguments % + - = | fileline - -%D \macros -%D {ifusepagedestinations} -%D -%D In \PDF\ version 1.0 only page references were supported, -%D while in \DVIWINDO\ 1.N only named references were accepted. -%D Therefore \CONTEXT\ supports both methods of referencing. In -%D \PDF\ version 1.1 named destinations arrived. Lack of -%D continuous support of version 1.1 viewers for \MSDOS\ -%D therefore sometimes forces us to prefer page references. As -%D a bonus, they are faster too and have no limitations. How -%D fortunate we were having both mechanisms available when the -%D version 3.0 (\PDF\ version 1.2) viewers proved to be too -%D bugged to support named destinations. - -\newif\ifusepagedestinations - -%D \macros -%D {ifhighlighthyperlinks} -%D -%D The next switch can be used to make user hyperlinks are -%D not highlighted when clicked on. - -\newif\ifhighlighthyperlinks - -%D \macros -%D {ifgotonewwindow} -%D -%D To make the {\em goto previous jump} feature more -%D convenient when using more than one file, it makes sense -%D to force the viewer to open a new window for each file -%D opened. - -\newif\ifgotonewwindow - -%D \macros -%D {jobsuffix} -%D -%D By default, \TEX\ produces \DVI\ files which can be -%D converted to other filetypes. Sometimes it is handy to -%D know what the target file will be. In other driver -%D modules we wil set \type {\jobsuffix} to \type {pdf}. - -% this will become a mode - -\def\jobsuffix{pdf} - -\ifdefined\resetsystemmode \else - \let\setsystemmode \gobbleoneargument - \let\resetsystemmode\gobbleoneargument -\fi - -\def\setjobsuffix#1% - {\resetsystemmode\jobsuffix - \edef\jobsuffix{#1}% - \setsystemmode\jobsuffix} - -%D \macros -%D {everyresetspecials} -%D -%D Now what will this one do? We'll see in a few lines. - -\newtoks\everyresetspecials - -\appendtoksonce - \ifdefined\setjobsuffix\setjobsuffix{pdf}\fi -\to \everyresetspecials - -\def\defineoutput{\dodoubleargument\dodefineoutput} - -\def\usespecials [#1]{} -\def\dodefineoutput[#1][#2]{} -\def\setupoutput [#1]{} - -\protect \endinput diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv new file mode 100644 index 000000000..b7de1051f --- /dev/null +++ b/tex/context/base/back-pdf.mkiv @@ -0,0 +1,3226 @@ +%D \module +%D [ file=back-pdf, +%D version=2009.04.15, +%D title=\CONTEXT\ Backend Macros, +%D subtitle=\PDF, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Backend Macros / PDF} + +\registerctxluafile{back-pdf}{1.001} + +\unprotect + +%D When dealing with resources, we share the resource dictionaries +%D between all xforms. This is inefficent in the sense that when no +%D resources are used, redundant entries take space, but on the other +%D hand we save redundant dictionaries so it's a nice compromise. Maybe +%D that in \LUATEX\ I will reimplement most of the code here anyway. + +%D Initialization of fields is tricky. If a field has no +%D value, it is kind of not there. If ResetForm is used, the +%D default is assigned, but pushbuttons are spoiled. Adding a +%D \type {/MK} dictionary helps, but gives ugly down +%D appearances (displaced with background). What a mess. +%D Also, in order to get at least something, the \type {/AS} +%D key should be provided. + +%D A couple of variables: + +\newtoks \everybackendshipout +\newtoks \everylastbackendshipout + +\let\lastPDFaction\empty + +\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi +\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi +\ifdefined\everygoto \else \newtoks\everygoto \fi +\ifdefined\everysetfield \else \newtoks\everysetfield \fi + +%D A few helpers: + +\let\PDFcode \pdfliteral +\def\PDFcontentcode{\pdfliteral} +\def\PDFdirectcode {\pdfliteral direct} + +%D \macros +%D {PDFobjref} +%D +%D Just a shortcut. + +% Watch out, \def\PDFobjref#1{\purenumber#1 0 R} also works, but not when +% #1 == \the\whatever + +\def\PDFobjref#1{\purenumber{#1} 0 R} + +%D \macros +%D {PDFswapdir} + +\let\PDFswapdir\empty \def\PDFswapdir{\ifcase\inlinedirection\or\or-\fi} + +% the pdf spec changed cq. viewers started behaving differently / 5+ + +\chardef\overcomePDFpage\plusone % page numbers/ beware: optimizers remove this one +\chardef\overcomePDFpage\plustwo % page:number +\chardef\overcomePDFpage\plusthree % pdftex page ref feature + +%D \macros +%D {setPDFdestination} +%D +%D \PDF\ destinations should obey the specifications laid down +%D in the \PDF\ reference manual. The next macro strips illegal +%D characters from the destination name. + +\def\setPDFdestination #1{\xdef\PDFdestination{\ctxlua{pdf.cleandestination("\luaescapestring{#1}")}}} +\def\hexifiedPDFstring #1{\ctxlua{pdf.hexify("\luaescapestring{#1}")}} +\def\sanitizePDFencoding#1\to#2{\xdef#2{\ctxlua{pdf.hexify("\luaescapestring{#1}")}}} + +%D + +\def\appendtopdfpageresources #1{\normalexpanded{\global\pdfpageresources{#1\the\pdfpageresources}}} +\def\appendtopdfpageattributes #1{\normalexpanded{\global\pdfpageattr {#1\the\pdfpageattr }}} +\def\appendtopdfpagesattributes#1{\normalexpanded{\global\pdfpagesattr {#1\the\pdfpagesattr }}} +\def\appendtopdfcatalog {\pdfcatalog} +\def\appendtopdfinfo {\pdfinfo} + +\def\resetpdfpageattributes{\global\pdfpageattr\emptytoks} +\def\resetpdfpageresources {\global\pdfpageresources\emptytoks} + +%D Due to the fact that \PDFTEX\ has a different concept of +%D page attributes, we need: + +\appendtoksonce + \resetpdfpageattributes + \resetpdfpageresources +\to \everyaftershipout + +%D \macros +%D {insertpdfaction, +%D insertpdfannotation, +%D insertpdfannotationobject, +%D createpdfdictionaryobject, +%D createpdfarrayobject, +%D defaultobjectreference, +%D doPDFgetobjectreference} +%D +%D This module deals with \PDF\ support, including fill||in +%D forms. Before we present the largely unreadable bunch of +%D macros, we introduce the here||not||defined low level +%D interface macros. These must be provided by the special +%D drivers \type{pdf} (\ACROBAT) and \type{tpd} (\PDFTEX). +%D +%D \starttyping +%D \insertpdfaction #1#2#3 width height action +%D \insertpdfannotation #1#2#3 width height data +%D \createpdfannotationobject #1#2#3#4#5 class name width height data +%D \createpdfdictionaryobject #1#2#3 class name data +%D \createpdfarrayobject #1#2#3 class name data +%D +%D \defaultobjectreference #1#2 class name +%D \doPDFgetobjectreference #1#2#3 class name \PDFobjectreference +%D \doPDFgetobjectpagereference #1#2#3 class name \PDFobjectreference +%D \stoptyping +%D +%D The keywords reflect their use. For the moment we stick to +%D keywords, because that way at we get an indication of what +%D we're doing. + +\def\createpdfdictionaryobject#1#2#3% + {\flushatshipout + {\immediate\pdfobj{<< #3 >>}% + \dosetobjectreference{#1}{#2}{\the\pdflastobj}}} + +\def\createpdfarrayobject#1#2#3% + {\flushatshipout + {\immediate\pdfobj{[ #3 ]}% + \dosetobjectreference{#1}{#2}{\the\pdflastobj}}} + +\def\createpdfannotationobject#1#2#3#4#5% + {\insertpdfannotation{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{\the\pdflastannot}} + +\def\createpdfactionobject#1#2#3#4#5% + {\insertpdfaction{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{\the\pdflastannot}} + +%D \macros +%D {insertpdfaction,insertpdfannotation,ifsharePDFactions} +%D +%D Next we handle annotations. All link annotations are +%D implemented using the action dictionary. This enables us to +%D use multiple actions. The second macro is for instance +%D used for movie inclusion. + +\newif\ifsharePDFactions \sharePDFactionstrue + +\def\insertpdfaction#1#2#3% + {\xdef\lastPDFcontent{#3}% + \ifcollectreferenceactions + \global\let\lastPDFaction\lastPDFcontent + \else + \ifsharePDFactions + \ifcase\similarreference\relax + \xdef\lastPDFaction{<<\lastPDFcontent>>}% + \or + \immediate\pdfobj{<<\lastPDFcontent>>}% + \xdef\lastPDFaction{\PDFobjref\pdflastobj}% + \else + % leave \lastPDFaction untouched + \fi + \else + \xdef\lastPDFaction{<<\lastPDFcontent>>}% + \fi + \pdfannot + width #1 height #2 depth \zeropoint + {/Subtype /Link + /Border [0 0 0] + \ifhighlighthyperlinks \else /H /N \fi + /A \lastPDFaction}% + \fi} + +\def\insertpdfannotation#1#2#3% + {\pdfannot width #1 height #2 depth \zeropoint{#3}} + +%D \macros +%D {doPDFbookmark} +%D +%D Well, isn't the next one ugly? Thanks to the \PDF\ +%D standard. + +\def\doPDFbookmark#1#2#3#4#5% to be renamed + {\doPDFgetpagereference{#4}\PDFobjectreference + \pdfoutline + user {<>}% + \ifcase#2 \else count \ifcase#5-\fi#2 \fi + {#3}} + +%D For special (\METAPOST) effects, we need to build +%D resource dictionaries. Here is the framework. + +\let\docuPDFextgstates \empty +\let\docuPDFcolorspaces\empty +\let\docuPDFshades \empty + +\def\checkPDFextgstates + {\ifx\docuPDFextgstates\empty \else + \ifnum\realpageno=\lastpage\relax + \createpdfdictionaryobject{FDF}{docuextgstates}{\docuPDFextgstates}% + \fi + \doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference + \appendtopdfpageresources{/ExtGState \PDFobjectreference}% + \fi} + +\def\checkPDFcolorspaces + {\ifx\docuPDFcolorspaces\empty \else + \ifnum\realpageno=\lastpage\relax + \createpdfdictionaryobject{FDF}{colorspaces}{\docuPDFcolorspaces}% + \fi + \doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference + \appendtopdfpageresources{/ColorSpace \PDFobjectreference}% + \fi} + +\def\checkPDFshades + {\ifx\docuPDFshades\empty \else + \ifnum\realpageno=\lastpage\relax + \createpdfdictionaryobject{FDF}{docushades}{\docuPDFshades}% + \fi + \doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference + \appendtopdfpageresources{/Shading \PDFobjectreference}% + \fi} + +\def\appendtoPDFdocumentextgstates #1{\xdef\docuPDFextgstates {\docuPDFextgstates \space#1}} +\def\appendtoPDFdocumentcolorspaces#1{\xdef\docuPDFcolorspaces{\docuPDFcolorspaces\space#1}} +\def\appendtoPDFdocumentshades #1{\xdef\docuPDFshades {\docuPDFshades \space#1}} + +%D Page actions: + +\let\lastpdfopenaction \empty +\let\lastpdfcloseaction\empty + +\def\dosetupopenaction {\appendtopdfcatalog{/OpenAction <<\lastPDFaction>>}} +\def\dosetupcloseaction{\appendtopdfcatalog{/CloseAction <<\lastPDFaction>>}} + +\def\dosetupopenpageaction {\glet\lastpdfopenaction \lastPDFaction} +\def\dosetupclosepageaction{\glet\lastpdfcloseaction\lastPDFaction} + +\def\checkPDFpageactions + {\iflocation % important since direct + \donefalse + \ifx\lastpdfopenaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi + \ifx\lastpdfcloseaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi + \ifdone + \appendtopdfpageattributes + {/AA <<\if!!donea/O <<\lastpdfopenaction >> \fi + \if!!doneb/C <<\lastpdfcloseaction>> \fi>>}% + \fi + \glet\lastpdfopenaction \empty + \glet\lastpdfcloseaction\empty + \fi} + +%D \macros +%D {ifPDFstrokecolor} +%D +%D We can reduce the filesize a bit by setting the next switch +%D to false. The amount of reduction depends on the use of +%D color, but don't expect more than a few percent. Zip +%D compression is already rather efficient in itself. + +\newif\ifPDFstrokecolor \PDFstrokecolortrue + +%D When submitting forms, we need to communicate the format. + +\chardef\submitoutputformat=0 % 0=unknown 1=HTML 2=FDF 3=XML + +\def\setsubmitoutputformat#1% + {\doifinsetelse{#1}{FDF,fdf} + {\chardef\submitoutputformat2} + {\doifinsetelse{#1}{XML,xml} + {\chardef\submitoutputformat3} + {\chardef\submitoutputformat1}}% + \relax} + +%D Handy to have this available asap: + +\ifdefined\everyPDFxform \newtoks\everyPDFxform \fi +\ifdefined\everyPDFximage \newtoks\everyPDFximage \fi + +% once we can be sure that the latest versions of pdftex are +% available we can use: +% +% \pdfobj reserveobjnum \edef\one{\the\pdflastobj} +% \pdfobj reserveobjnum \edef\two{\the\pdflastobj} +% +% \pdfobj useobjnum \one {x} +% \pdfobj useobjnum \two {x} +% +% we then can rewrite part of spec-fdf because the other drivers +% already support symbolic references + +%D \macros +%D {jobsuffix} +%D +%D Being one of the first typographical systems able to support +%D advances \PDF\ support, \TEX\ is also one of the first +%D systems to produce high quality \PDF\ code directly. Thanks +%D to Han The Thanh c.s. the \TEX\ community can leap forward +%D once again. +%D +%D One important characteristic of \PDFTEX\ is that is can +%D produce standard \DVI\ code as well as \PDF\ code. This +%D enables us to use one format file to support both output +%D formats. + +%D All modules in this group use specials to tell drivers what +%D non||\TEX\ actions to take. Because from the \TEX\ point of +%D view, there is no difference between \DVI\ and \PDF, we +%D therefore only have to bend the \DVI\ driver support into +%D \PDF\ support. Technically spoken, specials no longer serve +%D a purpose, except from ending up as comment in the \PDF\ +%D file. +%D +%D Before we continue we need to make sure if indeed those +%D \PDFTEX\ primitives are permitted. If no primitives are +%D available, we just stop reading any further. + +\pdfoutput = 1 +\pdfhorigin = 1 true in +\pdfvorigin = 1 true in +\pdfimageresolution = 300 +\pdfpkresolution = 600 +\pdfdecimaldigits = 10 +\pdfinclusionerrorlevel = 0 +\pdfminorversion = 5 +%pdfuniqueresname = 1 + +\def\PDFversion{1.\number\pdfminorversion} + +%D For some internal testing we need to know the output +%D suffix. + +\setjobsuffix{pdf} + +%D \macros +%D {dosetuppaper} +%D +%D If we don't set the paper size, \PDFTEX\ will certainly do +%D it in a way we don't want, therefore we need: + +\def\dosetuppaper#1#2#3% + {\global\pdfpagewidth #2\relax + \global\pdfpageheight#3\relax} + +%D \macros +%D {doloadmapfile,doloadmapline,doresetmapfilelist} + +\def\doresetmapfilelist + {\global\let\doresetmapfilelist\relax + \pdfmapfile{original-empty.map}} + +\def\doloadmapfile #1#2{\pdfmapfile{#1#2}} +\def\doloadmapline #1#2{\pdfmapline{#1#2}} + +%D nasty but needed + +\appendtoksonce \loadallfontmapfiles \to \everyPDFximage +\appendtoksonce \loadallfontmapfiles \to \everyPDFxform + +%D left overs: + + \let\currentmovie\s!unknown + + \def\doPDFinsertmov + {\bgroup + \xdef\currentmovie{\@@DriverImageLabel}% + \PointsToBigPoints\@@DriverImageWidth \width + \PointsToBigPoints\@@DriverImageHeight\height + \let\pdf@@options\empty + \let\pdf@@actions\empty + \donefalse + \expanded{\processallactionsinset[\@@DriverImageOptions]} + [\v!controls=>\donetrue, + \v!repeat=>\edef\pdf@@actions{\pdf@@actions /Mode /Repeat }, + \v!preview=>\edef\pdf@@options{\pdf@@options /Poster true }]% + \edef\pdf@@actions{\pdf@@actions /ShowControls \ifdone true\else false\fi}% + \insertpdfannotation\@@DriverImageWidth\@@DriverImageHeight + {/Subtype /Movie + /Border [0 0 0] + /T (movie \currentmovie) + /Movie << /F (\@@DriverImageFile) /Aspect [\width\space\height] \pdf@@options >> + /A << \pdf@@actions >>}% + \egroup} + +%D \macros +%D {doinsertsoundtrack} +%D +%D We use numbers instead of labels to keep track of sounds. + +\let\currentsound\s!unknown + +\def\doinsertsoundtrack#1#2#3% + {\bgroup + \xdef\currentsound{#2}% + \let\pdf@@actions\empty + \@EA\processallactionsinset\@EA + [#3] + [\v!repeat=>\edef\pdf@@actions{\pdf@@actions /Mode /Repeat }]% + \collectdriverresource + %\flushatshipout % since it can be buried in a chained box + {\insertpdfannotation{0pt}{0pt} + {/Subtype /Movie + /Border [0 0 0] + /T (sound \currentsound) + /Movie <>% + \ifx\pdf@@actions\empty\else/A << \pdf@@actions >>\fi}}% + \egroup} + +%D \macros +%D {doPDFattachfile} + +\def\doPDFfilestreamobject#1#2#3#4% + {} + +\def\doPDFfilestreamidentifier#1% + {0} + +\def\doPDFgetfilestreamreference#1#2% + {0 0 R} + +\def\doattachfile#1#2#3#4#5#6#7#8% + {\bgroup % title width height color symbol file + \edefconvertedargument\PDFfile{#8}% + % beware: the symbol may (indirectly) use the file + % reference when typesetting the object number; + \presetPDFsymbolappearance{#5}{#6}{#2}{#3}{#4}% sets width/height + \startPDFsymbolappearance + \doPDFembedfile\PDFfile{#7}{#8}% + \doPDFgetembeddedfilereference\PDFfile\PDFobjectreference + \setFDFlayer\@@DriverAttachmentLayer + \insertpdfannotation{\width}{\totalheight} + {/Subtype /FileAttachment + /FS \PDFobjectreference\space + /Contents (#1) + \PDFsymbol + \FDFlayer + \PDFattributes}% + \stopPDFsymbolappearance + \egroup} + +% semi-public + +\def\doPDFembedfile#1#2#3% symbolic name | filename | user name + {\edefconvertedargument\PDFfile{#1}% + \doifnotflagged{a:\PDFfile}% + {\doPDFfilestreamobject{PDFEF}{\PDFfile}{#2}{#3}% + \doglobal\setflag{a:\PDFfile}}} + +\def\doPDFgetembeddedfilereference#1#2% + {\edefconvertedargument\PDFfile{#1}% + \doPDFgetobjectreference{PDFEF}\PDFfile#2} + +\def\doPDFgetembeddedfilestreamreference#1#2% + {\edefconvertedargument\PDFfile{#1}% + \doPDFgetfilestreamreference\PDFfile#2} % == \doPDFgetobjectreference{PDFFS}\PDFfile#2 + +% requested by Jens-Uwe Morawski: permits usage of pdftosrc +% in viewers that don't support attachments: +% +% \definesymbol +% [ObjectNumber] +% % [object number {\PDFattachmentnumber[xx]}] % named +% [object number \PDFattachmentnumber] % current +% +% \useattachment[test][xx][test.tex] +% \setupattachments[symbol=ObjectNumber] +% \attachment[test] + +\def\PDFattachmentnumber + {\dosingleargument\doPDFattachmentnumber} + +\def\doPDFattachmentnumber[#1]% + {\iffirstargument + \doPDFfilestreamidentifier{#1}% + \else + \doPDFfilestreamidentifier\PDFfile + \fi} + +%D \macros +%D {...} +%D +%D Rather preliminary. We have to wait till the complete specs +%D show up. As usual, we cannot really check it (Acrobat 6.0 +%D has a bug that inhibits us to make a test file). Half a day +%D of testing made clear that trying to control the plugin fails +%D in most cases (we need plugin specs -). We also miss a feature +%D to let acrobat wait with proceeding (action processing) till +%D the media clip is ready. + +% aiff audio/aiff +% au audio/basic +% avi video/avi +% mid audio/midi +% mov video/quicktime +% mp3 audio/x-mp3 (mpeg) +% mp4 audio/mp4 +% mp4 video/mp4 +% mpeg video/mpeg +% smil application/smil +% swf application/x-shockwave-flash + +% beware, this is preliminary code, should be improved + +\def\PDFrenderingspecs#1{\executeifdefined{PDFMR:#1}\empty} + +\def\PDFexecutestartrendering {/Rendition /OP 0 \PDFrenderingspecs\argumentA} +\def\PDFexecutestoprendering {/Rendition /OP 1 \PDFrenderingspecs\argumentA} +\def\PDFexecutepauserendering {/Rendition /OP 2 \PDFrenderingspecs\argumentA} +\def\PDFexecuteresumerendering {/Rendition /OP 3 \PDFrenderingspecs\argumentA} + +% todo : sub files +% +% \doPDFembedfile{pier-39.png}{pier-39.png}{pier-39.png}% +% \doPDFgetembeddedfilestreamreference{pier-39.png}\xPDFobjectreference +% \edef\xxxx{/RF [(pier-39.png) \xPDFobjectreference]}% + +% todo: alternative renderings +% +% object_1 -> <> >> +% object_2 -> <> >> +% rendering -> <> + +\def\doinsertrendering#1#2#3#4% tag mime file options + {\ifundefined{PDFMR:#1}% + \doifinstringelse{://}{#3}\donetrue\donefalse % evt url as keyword + \createpdfdictionaryobject{PDFMF}{#1} + {/Type /Rendition + /S /MR + % does not work: /SP << /Type /MediaScreenParam /BE << /B [1 0 0] /O 0.5 >> >> + /C << /Type /MediaClip + /S /MCD + /N (#1) + /Alt [() (file not found)] % language id + message + /D << /Type /Filespec + /F (#3) + \ifdone/FS /URL\fi >> + /CT (#2) >>}% + % common code + \doifobjectreferencefoundelse{PDFMS}{#1} + {\doPDFgetobjectreference{PDFMS}{#1}\PDFobjectreferenceB} + {\doPDFgetobjectreference{PDFMU}{#1}\PDFobjectreferenceB}% + \doPDFgetobjectreference{PDFMF}{#1}\PDFobjectreferenceA + \setxvalue{PDFMR:#1}% needed /AA actions in /Screen + {/R \PDFobjectreferenceA + /AN \PDFobjectreferenceB}% + \doifobjectreferencefoundelse{PDFMS}{#1}\donothing + {\dodoinsertrenderingwindow{PDFMU}{#1}\zeropoint\zeropoint{#4}}% + \fi} + +\def\doinsertrenderingobject#1#2#3#4% tag class objectname options + {\ifundefined{PDFMR:#1}% + \doPDFgetobjectreference{#2}{#3}\PDFobjectreference + \createpdfdictionaryobject{PDFMF}{#1} + {/Type /Rendition + /S /MR + /C << /Type /MediaClip + /S /MCD + /N (#1) + /D \PDFobjectreference>>}% + % common code + \doifobjectreferencefoundelse{PDFMS}{#1} + {\doPDFgetobjectreference{PDFMS}{#1}\PDFobjectreferenceB} + {\doPDFgetobjectreference{PDFMU}{#1}\PDFobjectreferenceB}% + \doPDFgetobjectreference{PDFMF}{#1}\PDFobjectreferenceA + \setxvalue{PDFMR:#1}% needed /AA actions in /Screen + {/R \PDFobjectreferenceA + /AN \PDFobjectreferenceB}% + \doifobjectreferencefoundelse{PDFMS}{#1}\donothing + {\dodoinsertrenderingwindow{PDFMU}{#1}\zeropoint\zeropoint{#4}}% + \fi} + +\def\doinsertrenderingwindow + {\dodoinsertrenderingwindow{PDFMS}} + +\def\dodoinsertrenderingwindow#1#2#3#4#5% + {\vbox to #4 \bgroup + \checkPDFscreenactions{#2}{#5}% + \doPDFgetobjectpagereference{PDFMF}{#2}\PDFobjectreferenceA + \doPDFgetobjectreference {PDFMF}{#2}\PDFobjectreferenceB + \vss + \hbox to #3 \bgroup + \createpdfannotationobject{#1}{#2}{#3}{#4} + {/Subtype /Screen + /P \PDFobjectreferenceA + /A \PDFobjectreferenceB + \PDFattributes + /Border [0 0 0]}% + \hss + \egroup + \egroup} + +\global\let\PDFrenderingopenpageaction \empty +\global\let\PDFrenderingclosepageaction\empty + +\def\checkPDFscreenactions#1#2% + {\let\PDFattributes\empty + \iflocation % important since direct -) + % the action can either (already) be set by the window handler + % or (normally when no window [i.e a zero dimensions one] is present) by keyword + \doifinset\v!auto{#2} + {% brrr, here instead of in navigation module, must move and become special + % now two sided dependency + \let\checkrendering\gobbleoneargument + \ifx\PDFrenderingopenpageaction \empty + \handlereferenceactions{\v!StartRendering{#1}}\dosetuprenderingopenpageaction + \fi + \ifx\PDFrenderingclosepageaction\empty + \handlereferenceactions{\v!StopRendering {#1}}\dosetuprenderingclosepageaction + \fi + }% + \donefalse + \ifx\PDFrenderingopenpageaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi + \ifx\PDFrenderingclosepageaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi + \ifdone + \edef\PDFattributes + {/AA <<\if!!donea/PO <<\PDFrenderingopenpageaction >> \fi + \if!!doneb/PC <<\PDFrenderingclosepageaction>> \fi>>}% + \fi + \global\let\PDFrenderingopenpageaction \empty + \global\let\PDFrenderingclosepageaction\empty + \fi} + +\def\dosetuprenderingopenpageaction {\global\let\PDFrenderingopenpageaction \lastPDFaction} +\def\dosetuprenderingclosepageaction{\global\let\PDFrenderingclosepageaction\lastPDFaction} + +%D For the moment we don't test for alternatives that +%D themselves have alternatives, especially cylcic +%D dependencies. + +% \def\pdfimmediateximage{\immediate\pdfximage} +% +% \def\checkpdfimageattributes +% {\ifx\PDFfigurereference\empty +% \global\let\pdfimageattributes\empty +% \else +% \immediate\pdfobj +% {[ << /Image \PDFobjref\PDFfigurereference +% /DefaultForPrinting true >> ]}% +% \xdef\pdfimageattributes +% {attr {/Alternates \PDFobjref\pdflastobj}}% +% \fi} +% +% \global\let\PDFimagecolorreference\empty +% +% \def\checkpdfimagecolorspecs +% {\ifx\pdflastximagecolordepth \undefined +% \global\let\pdfimagecolorspecs\empty +% \else\ifx\PDFimagecolorreference\empty +% \global\let\pdfimagecolorspecs\empty +% \else +% \xdef\pdfimagecolorspecs{colorspace \PDFimagecolorreference\space}% +% \fi\fi +% \global\let\PDFimagecolorreference\empty} + +%D \macros +%D {doregisterfigure} +%D +%D Here is the fuzzy, very special dependant figure +%D registration special. We need to refer to the innermost +%D object (ximage). + + \def\doregisterfigure#1#2% + {\doifundefined{IM::#1::#2} + {\setxvalue{IM::#1::#2}{\the\pdflastximage}}% + \xdef\PDFfigurereference{\getvalue{IM::#1::#2}}} + +%D \macros +%D {doovalbox} +%D +%D Drawing frames with round corners is inherited from the +%D main module. +%D +%D For drawing ovals we use quite raw \PDF\ code. The next +%D implementation does not differ that much from the one +%D implemented in the \POSTSCRIPT\ driver. + +\def\doPDFovalcalc#1#2#3% + {\PointsToBigPoints{\dimexpr#1+#2\relax}#3} + +\def\doovalbox#1#2#3#4#5#6#7#8% todo: \scratchdimen/\scatchbox + {\forcecolorhack + \bgroup + \dimen0=#4\divide\dimen0 \plustwo + \doPDFovalcalc{0pt}{+\dimen0}\xmin + \doPDFovalcalc{#1}{-\dimen0}\xmax + \doPDFovalcalc{#2}{-\dimen0}\ymax + \doPDFovalcalc{-#3}{+\dimen0}\ymin + \advance\dimen0 by #5% + \doPDFovalcalc{0pt}{+\dimen0}\xxmin + \doPDFovalcalc{#1}{-\dimen0}\xxmax + \doPDFovalcalc{#2}{-\dimen0}\yymax + \doPDFovalcalc{-#3}{+\dimen0}\yymin + \doPDFovalcalc{#4}{\zeropoint}\stroke + \doPDFovalcalc{#5}{\zeropoint}\radius + \edef\dostroke{#6}% + \edef\dofill{#7}% + \edef\mode{\number#8 \space}% + % no \ifcase, else \relax in pdfcode + \setbox\scratchbox\hbox + {\ifnum\dostroke\dofill>\zerocount + \ifPDFstrokecolor\else\ifnum\dostroke=\plusone + \writestatus\m!colors{pdf stroke color will fail}\wait + \fi\fi + \PDFcode + {q + \stroke\space w + \ifcase\mode + \xxmin\space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or % 1 + \xxmin\space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \ymax \space l + \xmin \space \ymax \space l + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or % 2 + \xxmin\space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \ymax \space l + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or % 3 + \xmin \space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \ymin \space l + h + \or % 4 + \xmin \space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xmin \space \ymax \space l + \xmin \space \ymin\space l + h + \or % 5 + \xmin \space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xmin \space \ymax \space l + \xmin \space \ymin \space l + h + \or % 6 + \xmin \space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \ymax \space l + \xmin \space \ymax \space l + \xmin \space \ymin \space l + h + \or + \xxmin\space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \ymax \space l + \xmin \space \ymax \space l + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or + \xmin \space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \ymax \space l + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \ymin \space l + h + \or % 9 top open + \xmin \space \ymax \space m + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \ymax \space l + \or % 10 right open + \xmax \space \ymax \space m + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + \xmax\space \ymin \space l + \or % 11 bottom open + \xmax \space \ymin \space m + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax \space \ymax\space y + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \ymin \space l + \or % 12 left open + \xmin \space \ymax \space m + \xxmax\space \ymax \space l + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax \space \yymin\space l + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xmin \space \ymin \space l + \or % 13 + \xmin \space \ymax \space m + \xxmax\space \ymax \space l + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax\space \ymin \space l + \or % 14 + \xmax \space \ymax \space m + \xmax \space \yymin\space l + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xmin \space \ymin \space l + \or % 15 + \xmax \space \ymin \space m + \xxmin\space \ymin \space l + \xmin \space \ymin \space \xmin \space \yymin\space y + \xmin \space \ymax \space l + \or % 16 + \xmin \space \ymin \space m + \xmin \space \yymax\space l + \xmin \space \ymax \space \xxmin\space \ymax \space y + \xmax \space \ymax \space l + \or % 17 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \or % 18 + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \or % 19 + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \or % 20 + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 21 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 22 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \or % 23 + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \or % 24 + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 25 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 26 + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 27 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \or % 28 + \fi + \ifnum\mode>8 + S + \else + \ifnum\dostroke=\plusone S \fi + \ifnum\dofill =\plusone f \fi + \fi + Q}% + \fi}% + \wd\scratchbox#1\ht\scratchbox#2\dp\scratchbox#3\box\scratchbox + \egroup} + +%D \macros +%D {dostartgraymode,dostopgraymode, +%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode, +%D dostopcolormode, +%D dostartrotation,dostoprotation, +%D dostartscaling,dostopscaling, +%D dostartmirroring,dostopmirroring, +%D dostartnegative,dostopnegative, +%D dostartoverprint,dostopoverprint} + +\def\dostartrotation#1% grouped + {\setcalculatedcos\cos{#1}% + \setcalculatedsin\sin{#1}% + \forcecolorhack + \PDFcode{q \cos\space\sin\space\negated\sin\space\cos\space0 0 cm}} + +\def\dostoprotation + {\PDFcode{Q}} + +\def\@@PDFzeroscale{.0001} + +\def\dostartscaling#1#2% the test is needed because acrobat is bugged! + {\forcecolorhack + \PDFcode{q \ifdim#1\points=\zeropoint\@@PDFzeroscale\else#1\fi\space 0 0 + \ifdim#2\points=\zeropoint\@@PDFzeroscale\else#2\fi\space 0 0 cm}} + +\def\dostopscaling + {\PDFcode{Q}} + +\def\dostartmirroring{\PDFcode{-1 0 0 1 0 0 cm}} +\def\dostopmirroring {\PDFcode{-1 0 0 1 0 0 cm}} + +\def\dostartnegative {\ifdefined\initializePDFnegative \initializePDFnegative \PDFcode{/GSnegative gs}\fi} +\def\dostopnegative {\ifdefined\initializePDFnegative \initializePDFnegative \PDFcode{/GSpositive gs}\fi} +\def\dostartoverprint{\ifdefined\initializePDFoverprint\initializePDFoverprint\PDFcode{/GSoverprint gs}\fi} +\def\dostopoverprint {\ifdefined\initializePDFoverprint\initializePDFoverprint\PDFcode{/GSknockout gs}\fi} % wrong + +%D \macros +%D {doPDFstartgraymode,doPDFstopgraymode, +%D doPDFstartrgbcolormode,doPDFstartcmykcolormode,doPDFstartgraycolormode, +%D doPDFstopcolormode} +%D +%D In \PDF\ there are two color states, one for strokes and one +%D for fills. This means that we have to set the color in a +%D rather redundant looking way. Unfortunately this makes the +%D \PDF\ file much larger than needed. We can save few bytes +%D by not setting the stroke color. Due to zip compression we +%D only save a few percent. + +\def\dostartgraymode #1{\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} +\def\dostopgraymode {\PDFcode{0 g\ifPDFstrokecolor\space 0 G\fi}} +\def\dostartrgbcolormode #1#2#3{\PDFcode{#1 #2 #3 rg\ifPDFstrokecolor\space#1 #2 #3 RG\fi}} +\def\dostartcmykcolormode#1#2#3#4{\PDFcode{#1 #2 #3 #4 k\ifPDFstrokecolor\space#1 #2 #3 #4 K\fi}} +\def\dostartgraycolormode #1{\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} +\def\dostopcolormode {\PDFcode{0 g\ifPDFstrokecolor\space0 G\fi}} + +\def\dostartspotcolormode#1#2% redefining spotcolors is not possible anyway + {\ifundefined{pdf:scs:#2}% + \bgroup + \getcommacommandsize[#2]% + \ifcase\commalistsize\or + \setxvalue{pdf:scs:#2}{#2 SCN #2 scn}% \setxvalue{pdf:scs:#2}{#2 SC #2 sc}% + \else + \let\PDFspotcolorspecs\empty + \def\dospotcolorcommand##1{\edef\PDFspotcolorspecs{\PDFspotcolorspecs##1\space}}% + \processcommacommand[#2]\dospotcolorcommand + \setxvalue{pdf:scs:#2}{\PDFspotcolorspecs SCN \PDFspotcolorspecs scn}% + \fi + \egroup + \fi + \PDFcode{/#1 cs /#1 CS \PDFgetspotcolorspec{#2}}} + +\def\PDFgetspotcolorspec#1% + {\executeifdefined{pdf:scs:#1}\empty} % better no default than one with too less args + +\def\dostartnonecolormode + {\PDFcode{/None CS 1 SC /None cs 1 sc}} + +%D We need to register the spot colors and their fallbacks. + +% we cannot use /DeviceN since GS <=7.21 breaks on it +% and Jaws does not handle it at all {[/DeviceN [/All|/None] +% /Device#2 \PDFobjref\pdflastobj]} so we use separation +% colors that work and print ok + +\def\doPDFregistersomespotcolor#1#2#3#4% implemented in the driver + {\writestatus\m!systems{missing spot color definition}\wait} + +\def\doregisternonecolor % internal command + {\doregistergrayspotcolor{None}{1}% + \globallet\doregisternonecolor\relax} + +\def\dodoPDFregisterrgbspotcolor#1#2#3#4#5#6#7% name noffractions names p's r g b + {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{RGB}{0.0 1.0 0.0 1.0 0.0 1.0}% + {\ifcase#2\or dup #5 mul exch dup #6 mul exch #7 mul\else#5 #6 #7\fi}} + +\def\dodoPDFregistercmykspotcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k + {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{CMYK}{0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0}% + {\ifcase#2\or dup #5 mul exch dup #6 mul exch dup #7 mul exch #8 mul\else #5 #6 #7 #8\fi}} + +\def\dodoPDFregistergrayspotcolor#1#2#3#4#5% name noffractions names p's s + {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}% + {\ifcase#2\or #5 mul\else #5\fi}} + +\def\doregisterrgbspotcolor#1#2#3#4#5#6#7% name noffractions names p's r g b + {\ifRGBsupported + \dodoPDFregisterrgbspotcolor{#1}{#2}{#3}{#4}{#5}{#6}{#7}% + \else + \edef\@@cl@@r{#5}\edef\@@cl@@g{#6}\edef\@@cl@@b{#7}% + \ifCMYKsupported + \convertRGBtoCMYK\@@cl@@r\@@cl@@g\@@cl@@b + \dodoPDFregistercmykspotcolor{#1}{#2}{#3}{#4}\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \else + \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b + \dodoPDFregistergrayspotcolor{#1}{#2}{#3}{#4}\@@cl@@s + \fi + \fi} + +\def\doregistercmykspotcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k + {\ifCMYKsupported + \dodoPDFregistercmykspotcolor{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% + \else + \edef\@@cl@@c{#5}\edef\@@cl@@m{#6}\edef\@@cl@@y{#7}\edef\@@cl@@k{#8}% + \ifRGBsupported + \convertCMYKtoRGB\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \dodoPDFregisterrgbspotcolor{#1}{#2}{#3}{#4}\@@cl@@r\@@cl@@g\@@cl@@b + \else + \convertCMYKtoGRAY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \dodoPDFregistergrayspotcolor{#1}{#2}{#3}{#4}\@@cl@@s + \fi + \fi} + +\def\doregistergrayspotcolor{\dodoPDFregistergrayspotcolor} + +%D New and very experimental. + +\def\doregistercmykindexcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k + {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{CMYK}{0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0}% + {dup #5 mul exch dup #6 mul exch dup #7 mul exch #8 mul}} + +\def\doregisterrgbindexcolor#1#2#3#4#5#6#7% name noffractions names p's r g b + {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{RGB}{0.0 1.0 0.0 1.0 0.0 1.0}% + {dup #5 mul exch dup #6 mul exch #7 mul}} + +\def\doregistergrayindexcolor#1#2#3#4#5% name noffractions names p's s + {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}% + {pop}} + +\let\checkpredefinedcolor\predefineindexcolor % we need an index in order to negate bitmaps + +\def\doregisterfigurecolor#1% always an index color + {\dogetobjectreference{PDFIX}{\internalspotcolorname{#1}}\PDFimagecolorreference} + +\def\doregisterspotcolorname#1#2% no need for escape in luatex + {\bgroup + \let\ascii\empty + \def\docommand##1% + {\edef\ascii{\ascii + \ifx\nexthandledtoken\space + \letterhash20% + \else\ifx\nexthandledtoken\blankspace + \letterhash20% + \else + ##1% + \fi\fi}}% + \expanded{\handletokens#2}\with\docommand + \letgvalue{@@pdf@@scn@@#1}\ascii + \egroup} + +\def\doPDFregistersomespotcolor#1#2#3#4#5#6#7% name fractions names p's space domain function + {\bgroup + \let\spotpops\empty + \ifcase#2\or + %def\PDFspotcolornames{/Separation /#1}% + \edef\PDFspotcolornames{/Separation /\executeifdefined{@@pdf@@scn@@#1}{#1}}% + \def\PDFspotcolordomain{0.0 1.0}% + \else + \dorecurse{#2}{\edef\spotpops{\spotpops pop }}% + \let\PDFspotcolornames \empty + \let\PDFspotcolordomain\empty + \def\dospotcolorcommand##1% + {\edef\PDFspotcolornames {\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}% + \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}% + \processcommacommand[#3]\dospotcolorcommand + \edef\PDFspotcolornames{/DeviceN [\PDFspotcolornames]}% + \fi + \immediate \pdfobj stream attr + {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}% + \immediate \pdfobj + {[\PDFspotcolornames\space /Device#5 \PDFobjref\pdflastobj]}% + \dosetobjectreference{PDFCS}{#1}{\the\pdflastobj}% + \appendtoPDFdocumentcolorspaces{/#1 \PDFobjref\pdflastobj}% + \egroup} + +%D New and very experimental. + +\def\doPDFregistersomeindexcolor#1#2#3#4#5#6#7% name fractions names p's space domain function + {\bgroup + \let\spotpops\empty + \dorecurse{#2}{\edef\spotpops{\spotpops exch pop\space}}% + \let\PDFspotcolornames \empty + \let\PDFspotcolordomain\empty + \def\docommand##1% + {%\edef\PDFspotcolornames {\PDFspotcolornames/##1\space}% + \edef\PDFspotcolornames{\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}% + \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}% + \processcommacommand[#3,None]\docommand + \let\PDFcolorindexvector\empty + \def\docommand##1% + {\scratchdimen##1\points + \scratchdimen\recurselevel\scratchdimen + \scratchcounter\scratchdimen + \divide\scratchcounter \maxcard + \edef\PDFcolorindexvector{\PDFcolorindexvector\uchexnumbers\scratchcounter}}% + %\dostepwiserecurse\zerocount{255}\plusone + \dostepwiserecurse{255}\zerocount\minusone % we need to negate + {\rawprocesscommacommand[#4,1]\docommand + \xdef\PDFcolorindexvector{\PDFcolorindexvector\space}}% + \immediate \pdfobj stream attr + {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}% + \immediate \pdfobj + {[/Indexed + [/DeviceN [\PDFspotcolornames] /Device#5 \the\pdflastobj\space0 R] % + 255 <\PDFcolorindexvector>]}% + \dosetobjectreference{PDFIX}{#1}{\the\pdflastobj}% + \appendtoPDFdocumentcolorspaces{/#1_INDEXED \the\pdflastobj\space0 R}% + \egroup} + +%D \macros +%D {dostarttransparency,dostoptransparency} +%D +%D For transparency, we need to implement a couple of +%D auxiliary macros. If needed, we will generalize them later. + +\def\@@PDT{@PDT@} + +\ifx\PDFcurrenttransparency\undefined + \newcount\PDFcurrenttransparency \PDFcurrenttransparency=0 % -1 +\fi + +\def\assignPDFtransparency#1#2% + {\edef\PDFtransparencyidentifier{/Tr#1}% + \edef\PDFtransparencyreference{\PDFobjref{#2}}} + +\def\presetPDFtransparency#1#2% + {\initializePDFtransparency + \executeifdefined{\@@PDT#1:#2}{\dopresetPDFtransparency{#1}{#2}}} + +\def\dopresetPDFtransparency#1#2% + {\global\advance\PDFcurrenttransparency \plusone + \immediate\pdfobj{\PDFtransparancydictionary{#1}{#2}{}}% + \edef\PDFtransparencyidentifier{/Tr\the\PDFcurrenttransparency}% + \edef\PDFtransparencyreference {\PDFobjref\pdflastobj}% + \setxvalue{\@@PDT#1:#2}% + {\noexpand\assignPDFtransparency{\the\PDFcurrenttransparency}{\the\pdflastobj}}% + \appendtoPDFdocumentextgstates + {\PDFtransparencyidentifier\space + \PDFtransparencyreference\space}} + +\def\initializePDFtransparency + {\immediate\pdfobj{\PDFtransparancydictionary{1}{1}{/AIS false}}% + \xdef\PDFtransparencyresetidentifier{/Tr0}% + \xdef\PDFtransparencyresetreference{\PDFobjref\pdflastobj}% + \setxvalue{\@@PDT0:0}% + {\noexpand\assignPDFtransparency{0}{\the\pdflastobj}}% + \appendtoPDFdocumentextgstates + {\PDFtransparencyresetidentifier\space + \PDFtransparencyresetreference\space}% + \global\let\initializePDFtransparency\relax} + +%D Transparency support: + +\def\PDFtransparancydictionary#1#2#3% type fraction extras + {<>} + +\def\dodoPDFstarttransparency#1#2% + {\presetPDFtransparency{#1}{#2}% + \PDFcode{\PDFtransparencyidentifier\space gs }} + +\def\dodoPDFstoptransparency + {\PDFcode{/Tr0 gs }} + +\def\dostarttransparency + {\global\let\dostarttransparency\dodoPDFstarttransparency + \global\let\dostoptransparency \dodoPDFstoptransparency + \initializetransparency + \dostarttransparency} + +% This is tricky: because a text stream is handled before +% the page body is built, we can run into stops that will +% match an outer start; however, the stop is needed in case +% of a text color: [text color text] [other color text] on a +% first page combined with color splitting will go wrong if +% we stick to the relaxing method. + +% \def\dostoptransparency +% {\initializetransparency +% \dodoPDFstoptransparency} + +%D These use: + +\let\initializetransparency\relax + +\let\PDFtransparencyresetreference \empty +\let\PDFtransparencyresetidentifier\empty + +\let\PDFtransparencyreference \empty +\let\PDFtransparencyidentifier\empty + +%D New trickery: + +\def\dostartgraphicgroup{\PDFcode{q}} +\def\dostopgraphicgroup {\PDFcode{Q}} + +%D \macros +%D {dostartclipping,dostopclipping} +%D +%D Clipping in \PDFTEX\ is rather trivial. We can even hook +%D in \METAPOST\ without problems. + +\def\dostartclipping#1#2#3% + {\PointsToBigPoints{#2}\width + \PointsToBigPoints{#3}\height + \grabMPclippath{#1}{1}\width\height + {0 0 m \width\space 0 l \width \height l 0 \height l}% + \pdfliteral % PDFcode ? + {q 0 w \MPclippath\space W n}} + +\def\dostopclipping + {\pdfliteral{Q n}} % PDFcode + +%D \macros +%D {dosetupinteraction} +%D +%D Nothing special is needed to enable \PDF\ commands and +%D interaction. We stick with a message. + +\def\dosetupinteraction + {\showmessage\m!interactions{21}{pdftex}} + +%D \macros +%D {doresetgotowhereever, +%D dostartthisisrealpage,dostartthisislocation, +%D dostartgotorealpage,dostartgotolocation,dostartgotoJS} +%D +%D The interactions macros are the core of this module. We +%D support both page destinations and named ones. We don't +%D need the \type{\stop}||alternatives. We also don't need +%D to set the special that sets the real page number. + +%D In the goto specials we took care of secondary references. +%D Here we define the macros used. + +\def\doresetgotowhereever + {\global\let\secondaryPDFreferences\empty} + +\doresetgotowhereever % just to be sure + +% we can (in etex) share more by testing on this + +\def\savesecondaryPDFreference#1% + {\@EA\xdef\csname PDF-SR:\the\nofsecondaryreferences\endcsname{#1}} + +\def\savesecondaryPDFreference % #1 == \action + {\global\@EA\let\csname PDF-SR:\the\nofsecondaryreferences\endcsname} + +% test should happen in core-ref + +\def\getsecondaryPDFreferences + {\ifcase\nofsecondaryreferences\else + \ifcsname PDF-SR:\the\nofsecondaryreferences\endcsname + \xdef\secondaryPDFreferences{/Next <<\csname PDF-SR:\the\nofsecondaryreferences\endcsname\space\secondaryPDFreferences>>}% + \fi + \global\advance\nofsecondaryreferences \minusone + \expandafter\getsecondaryPDFreferences + \fi} + +%D \macros +%D {dostartthisislocation} +%D +%D Next we define the macros that deal with hyperreferencing, +%D graphic inclusion and general document features. These are +%D the olderst ones. I won't comment much because one needs +%D knowledge of \PDF\ itself, and explaning \PDF\ is beyond +%D this documentation. + +\def\dostartthisislocation#1% + {\bgroup + \setPDFdestination{#1}% + \ifx\PDFdestination\empty \else + \pdfdest name {\PDFdestination}\PDFpageviewkey + \fi + \egroup} + +\def\locationfilesuffix{pdf} + +\def\dostartgotolocation#1#2#3#4#5#6% + {\bgroup + \doifelsenothing{#3} + {\setPDFdestination{#5}% + \doifelsenothing\PDFdestination + {\let\action\empty} + {\doifelsenothing{#4} + {\let\PDFfile\empty} + {\expanded{\beforesplitstring#4}\at.\to\PDFfile + \doifparentfileelse\PDFfile % {#4} + {\let\PDFfile\empty} + %{\setreferencefilename#4.\locationfilesuffix\to\PDFfile + {\@EA\setreferencefilename\PDFfile.\locationfilesuffix\to\PDFfile + \edef\PDFfile + {R /F (\PDFfile)\ifgotonewwindow\space/NewWindow true \fi}}}% + \edef\action% + {/S /GoTo\PDFfile\space /D (\PDFdestination)}}} + {\doifelsenothing{#4} + {\let\PDFfile\empty + \let\PDFdestination\empty} + {\setreferencefilename/#4\to\PDFfile + \setPDFdestination{#5}% + \doifsomething\PDFdestination + {\edef\PDFdestination{\letterhash\PDFdestination}}}% + \edef\action{/S /URI /URI (#3\PDFfile\PDFdestination)}}% + \ifx\action\empty\else + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \fi + \egroup} + +\def\PDFgotonewwindow{\ifgotonewwindow\space/NewWindow true \fi} + +% optimization in tpd driver +% +% \edef\PDFdestination{(page:\the\scratchcounter)}% +% +% ==> +% +% \advance\scratchcounter 1 +% \edef\PDFdestination{[\pdfpageref \PDFobjref\scratchcounter\PDFpageviewwrd]}% +% +% \doPDFgetpagedestination#1#2% pagenumber macro % % fuzzy hack + +\def\dostartgotorealpage#1#2#3#4#5% watch the R append trick + {\bgroup + \doifelsenothing{#3}% #1 = url + {\scratchcounter0#5\relax + \ifnum\scratchcounter>0 + \doifelsenothing{#4} + {\let\PDFfile\empty} + {\expanded{\beforesplitstring#4}\at.\to\PDFfile + \doifparentfileelse\PDFfile % {#4} + {\let\PDFfile\empty} + %{\setreferencefilename#4.\locationfilesuffix\to\PDFfile + {\@EA\setreferencefilename\PDFfile.\locationfilesuffix\to\PDFfile + \edef\PDFfile{R /F (\PDFfile)\PDFgotonewwindow}}}% + \ifx\PDFfile\empty + \ifcase\overcomePDFpage + \or % pdf starts numbering at zero + \advance\scratchcounter \minusone + \edef\PDFdestination{[\the\scratchcounter\space\PDFpageviewwrd]}% + \or % pdf starts numbering at zero + \advance\scratchcounter \minusone + \edef\PDFdestination{(page:\the\scratchcounter)}% + \or % pdftex starts numbering at one + \edef\PDFdestination{[\pdfpageref\scratchcounter\space0 R \PDFpageviewwrd]}% + \fi + \else % across files it's a page number / pdf starts numbering at zero + \advance\scratchcounter \minusone + \edef\PDFdestination{[\the\scratchcounter\space\PDFpageviewwrd]}% + \fi + \edef\action{/S /GoTo\PDFfile\space /D \PDFdestination}% + \else + \let\action\empty + \fi} + {\doifelsenothing{#4} + {\let\PDFfile\empty} + {\setreferencefilename/#4\to\PDFfile}% + \edef\action{/S /URI /URI (#3\PDFfile)}}% + \ifx\action\empty\else + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \fi + \egroup} + +\let\lastfakedPDFpage\!!zerocount + +\def\fakePDFpagedestination % as in pdf, we start numbering at zero + {\iflocation \ifarrangingpages \ifnum\overcomePDFpage=\plustwo \else + \ifnum\lastfakedPDFpage<\realpageno + \bgroup + \xdef\lastfakedPDFpage{\realfolio}% + \advance\realpageno \minusone % is \expanded needed ? + \normalexpanded{\noexpand\pdfdest name {page:\realfolio}\PDFpageviewkey}% + \egroup + \fi + \fi \fi \fi} + +\def\dostartgotoJS#1#2#3% + {\bgroup + \doPSsanitizeJScode#3\to\sanitizedJScode + \edef\action{/S /JavaScript /JS (\sanitizedJScode)}% + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \egroup} + +%D When going to a location, we obey the time and space saving +%D boolean \type{\ifusepagedestination}. Named destinations are +%D stripped and made robust. This all happens in the macros +%D called for. + +%D \macros +%D {doflushJSpreamble} +%D +%D It does not make sense to duplicate common \JAVASCRIPT\ +%D functions, and therefore they can be predefined and must be +%D output separately. Currently this special is not shared +%D with the \ACROBAT\ one, simply because \DISTILLER\ does not +%D yet support something \type{\pdfnames}. + +% \oneJSpreamblefalse % buggy in acrobat + +\def\doflushJSpreamble#1% + {\bgroup + \let\compositeJScode\empty + \def\docommand##1% + {\edef\sanitizedJScode{\getJSpreamble{##1}}% + \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode + \immediate\pdfobj {<< /S /JavaScript /JS (\sanitizedJScode) >>}% + \edef\compositeJScode + {\compositeJScode\space (##1) \PDFobjref\pdflastobj}}% + \processcommalist[#1]\docommand + \immediate\pdfobj{<< /Names [ \compositeJScode ] >>}% + \pdfnames{/JavaScript \PDFobjref\pdflastobj}% + \egroup} + +%D \macros +%D {dostarthide,dostophide} +%D +%D Hiding parts of the document for printing is not yet +%D supported by \PDF\ and therefore \PDFTEX. + +\let\dostarthide\donothing +\let\dostophide \donothing + +%D \macros +%D {doPDFsetupscreen,doPDFsetupidentity} +%D +%D Opposite to \DVI\ drivers, \PDF\ ones must know which what +%D page dimensions they are dealing. We also use the +%D opportunity to launch full screen (1) or show bookmarks (2). +%D +%D Setting of the screen boundingbox involves some +%D calculations. Here we also take care of (non) full screen +%D startup. The dimensions are rounded. Because \PDFTEX\ and +%D \ACROBAT\ handle setting the page dimensions in a +%D different way, we do not share this special. + +\def\dosetupscreen{\doPDFsetupscreen\pdfpageheight} + +\let\currentPDFpagemode \empty % document catalog +\let\currentPDFviewerprefs\empty % document catalog + +\let\currentPDFcropbox \empty % page attributes +\let\currentPDFbleedbox \empty % page attributes +\let\currentPDFartbox \empty % page attributes +\let\currentPDFtrimbox \empty % page attributes + +\def\doPDFsetupscreen#1#2#3#4#5#6% watch the extra argument + {\bgroup + \xdef\currentPDFpagemode + {\ifnum#6=4 + /PageLayout /TwoColumnRight + \else + /PageMode \ifcase#6 + /UseNone\or/FullScreen\or/UseOutlines\else/UseNone\fi + \fi}% + \xdef\currentPDFviewerprefs % space after #6 needed, else \relax + {\ifcase#6 \or\or\else /ViewerPreferences << /FitWindow true >>\fi}% + \egroup} + +\def\addPDFdocumentinfo + {\appendtopdfcatalog{\currentPDFpagemode\currentPDFviewerprefs}% + \appendtopdfcatalog{/Version \ifdim\PDFversion00\points>100\points 1.\fi\PDFversion}% + \appendtopdfinfo{/Trapped /False}% + \appendtopdfinfo{/ConTeXt.Version (\contextversion)}% + \appendtopdfinfo{/ConTeXt.Time (\number\normalyear.\twodigits\normalmonth.\twodigits\normalday\space \twodigits\currenthour:\twodigits\currentminute)}% + \appendtopdfinfo{/ConTeXt.Jobname (\jobname)}% + \appendtopdfinfo{/ConTeXt.Url (www.pragma-ade.com)}% + \glet\addPDFdocumentinfo\relax} + +\def\PDFversion{1.5} + +\appendtoksonce + \def\PDFversion{1.5}% +\to \everyresetspecials + +\def\doPDFsetupwhateverbox#1#2#3#4#5#6% watch the extra arguments + {\bgroup + \!!widtha \dimexpr#5+#3\relax + \!!heightb\dimexpr#2-#4\relax + \!!heighta\dimexpr\!!heightb-#6\relax + % sometimes whole values give better results + % \PointsToWholeBigPoints{#3}\left + % \PointsToWholeBigPoints\!!heighta\bottom + % \PointsToWholeBigPoints\!!widtha \width + % \PointsToWholeBigPoints\!!heightb\height + % but since pdf/x does not round when checking if + % the boxes fit inside the media box ... + \PointsToBigPoints{#3}\left + \PointsToBigPoints\!!heighta\bottom + \PointsToBigPoints\!!widtha \width + \PointsToBigPoints\!!heightb\height + \xdef#1{[\left\space\bottom\space\width\space\height]}% + \egroup} + +\gdef\currentPDFtrimbox{\currentPDFcropbox} % default, needed for pdf/x + +\def\dosetupartbox {\doPDFsetupwhateverbox\currentPDFartbox \pdfpageheight} +\def\dosetupcropbox {\doPDFsetupwhateverbox\currentPDFcropbox \pdfpageheight} +\def\dosetupbleedbox{\doPDFsetupwhateverbox\currentPDFbleedbox\pdfpageheight} +\def\dosetuptrimbox {\doPDFsetupwhateverbox\currentPDFtrimbox \pdfpageheight} + +\def\flushPDFpageboxes + {\edef\currentPDFtrimbox{\currentPDFtrimbox}% + \ifx\currentPDFartbox \empty\else\appendtopdfpageattributes{/ArtBox \currentPDFartbox }\fi + \ifx\currentPDFcropbox \empty\else\appendtopdfpageattributes{/CropBox \currentPDFcropbox }\fi + \ifx\currentPDFbleedbox\empty\else\appendtopdfpageattributes{/BleedBox \currentPDFbleedbox}\fi + \ifx\currentPDFtrimbox \empty\else\appendtopdfpageattributes{/TrimBox \currentPDFtrimbox }\fi} + +%D \macros +%D {dostartexecutecommand} +%D +%D \PDF\ viewers enable us to navigate using menus and shortcut +%D keys. These navigational tools can also be accessed by using +%D annotations. The next special takes care of inserting them. +%D +%D At the cost of much auxiliary placeholders, we can pretty +%D fast convert the command asked for. This is how the \PDF\ +%D code looks like. + +\def\PDFmoviecode#1#2#3% + {/Movie + /T (\ifcase#1movie \else sound \fi\ifx\argumentA\empty#2\else\argumentA\fi) + /Operation /\ifcase#3Play\or Stop\or Pause\or Resume\fi\space} + +\def\PDFexecutestartmovie {\PDFmoviecode0\currentmovie0} +\def\PDFexecutestopmovie {\PDFmoviecode0\currentmovie1} +\def\PDFexecutepausemovie {\PDFmoviecode0\currentmovie2} +\def\PDFexecuteresumemovie {\PDFmoviecode0\currentmovie3} + +\def\PDFexecutestartsound {\PDFmoviecode1\currentsound0} +\def\PDFexecutestopsound {\PDFmoviecode1\currentsound1} +\def\PDFexecutepausesound {\PDFmoviecode1\currentsound2} +\def\PDFexecuteresumesound {\PDFmoviecode1\currentsound3} + +\def\PDFformcode#1% + {\doiffieldset{#1}{/Field [\dogetfieldset{#1}]}} + +% bit 3 = html +% bit 6 = xml +% bit 4 = get + +\ifx\PDFsubmitfiller\undefined \let\PDFsubmitfiller\empty \fi + +\chardef\PDFformmethod=1 % 0=GET 1=POST + +\def\PDFformflag#1#2{\ifcase\PDFformmethod#1\else#2\fi} + +\def\PDFexecuteimportform {/Named /N /AcroForm:ImportFDF} +\def\PDFexecuteexportform {/Named /N /AcroForm:ExportFDF} +\def\PDFexecuteresetform {/ResetForm \PDFformcode\argumentA} +\def\PDFexecutesubmitform {/SubmitForm \PDFformcode\argumentB + /Flags \ifcase\submitoutputformat\space + \PDFformflag{12} {4} % 0=unknown + \or \PDFformflag{12} {4} % 1=HTML + \or \PDFformflag {8} {0} % 2=FDF + \or \PDFformflag{40}{32} % 3=XML + \else \PDFformflag{12} {4} % ?=unknown + \fi + /F (\argumentA)\PDFsubmitfiller} + +% urifill permits url substitution + +\def\PDFexecutehide {/Hide /T (\argumentA) /H true} +\def\PDFexecuteshow {/Hide /T (\argumentA) /H false} + +\def\PDFexecutefirst {/Named /N /FirstPage} +\def\PDFexecuteprevious {/Named /N /PrevPage} +\def\PDFexecutenext {/Named /N /NextPage} +\def\PDFexecutelast {/Named /N /LastPage} +\def\PDFexecutebackward {/Named /N /GoBack} +\def\PDFexecuteforward {/Named /N /GoForward} +\def\PDFexecuteprint {/Named /N /Print} +\def\PDFexecuteexit {/Named /N /Quit} +\def\PDFexecuteclose {/Named /N /Close} +\def\PDFexecutesave {/Named /N /Save} +\def\PDFexecutesavenamed {/Named /N /SaveAs} +\def\PDFexecuteopennamed {/Named /N /Open} +\def\PDFexecutehelp {/Named /N /HelpUserGuide} +\def\PDFexecutetoggle {/Named /N /FullScreen} +\def\PDFexecutesearch {/Named /N /Find} +\def\PDFexecutesearchagain {/Named /N /FindAgain} +\def\PDFexecutegotopage {/Named /N /GoToPage} +\def\PDFexecutequery {/Named /N /AcroSrch:Query} +\def\PDFexecutequeryagain {/Named /N /AcroSrch:NextHit} +\def\PDFexecutefitwidth {/Named /N /FitWidth} +\def\PDFexecutefitheight {/Named /N /FitHeight} + +\let\PDFobjectclass\empty +\let\PDFobjectname \empty + +\def\dostartexecutecommand#1#2#3#4% + {\doifdefined{PDFexecute#3} + {\bgroup + \edef\argument{#4}% + \ifx\argument\empty + \let\argumentA\empty + \let\argumentB\empty + \else + \@EA\dogetcommalistelement\@EA1\@EA\from#4\to\argumentA + \@EA\dogetcommalistelement\@EA2\@EA\from#4\to\argumentB + \fi + \edef\action% + {/S \getvalue{PDFexecute#3}}% + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences +% \ifx\PDFobjectclass\empty +% \let\next\insertpdfaction +% \else +% \edef\next{\createpdfactionobject{\PDFobjectclass}{\PDFobjectname}}% +% \globalletempty\PDFobjectclass +% \globalletempty\PDFobjectname +% \fi +% \next + \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \egroup}} + +%D \macros +%D {dosetupidentity} +%D +%D Documents can be tagged with an application accessible title +%D and subtitle, the authorname, a date, the creator, keywords +%D etc. For the moment \PDFTEX\ only supports the first three +%D of these. + +\def\dosetupidentity#1#2#3#4#5#6% + {\normalexpanded{\noexpand\appendtopdfinfo + {/Title <\hexifiedPDFstring{#1}> + /Subject <\hexifiedPDFstring{#2}> + /Author <\hexifiedPDFstring{#3}> + /Creator <\hexifiedPDFstring{#4}> + /ModDate (#4) + /ID (\jobname.#5) % needed for pdf/x + /Keywords <\hexifiedPDFstring{#6}>}}} + +%D \macros +%D {dostartrunprogam} +%D +%D We can run a program form within a document, although this +%D feature is rather weak, due to path problems and buggy +%D argument passing. + +\def\dostartrunprogram#1#2#3#4% new: #3 => #3#4 + {\bgroup + %\edef\string{#3}% + %\@EA\beforesplitstring\string\at{ }\to\program + %\@EA\aftersplitstring \string\at{ }\to\parameters + %\edef\action% + % {/S /Launch /F (\program) /P (\parameters) /D (.)}% + \edef\action + {/S /Launch /F (#3) /P (#4) /D (.)}% + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \egroup} + +%D \macros +%D {dostartgotoprofile, dostopgotoprofile, +%D dobeginofprofile, doendofprofile} +%D +%D \CONTEXT\ user profiles and version control fall back on +%D \PDF\ article threads. Unfortunately one cannot influence +%D the view yet in an (for me) acceptable way. + +\def\dostartgotoprofile#1#2#3% to be done: file + {\bgroup + \setPDFdestination{#3}% + \doifsomething\PDFdestination + {\edef\action + {/S /Thread /D (\PDFdestination)}% + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi}% + \egroup} + +%D Some day, I'll reimplement threading in a useful way. +%D Currently the viewers handle threads rather diffuse. + +\def\dobeginofprofile#1#2#3#4% + {\setPDFdestination{#1}% + \doifsomething\PDFdestination + {\pdfthread + width #2 height #3 + attr {/Title (\PDFdestination)} % can be omitted + name {\PDFdestination}}} + +\def\doendofprofile + {} + +%D \macros +%D {doinsertbookmark} +%D +%D In \PDF\ bookmarks are the building blocks of a viewer +%D provided sort of table of contents. \TEX\ has to provide +%D the entry as well as the number of child entries. Strings +%D need to be sanatized as good as possible to suit the default +%D encoding. In \CONTEXT\ users can overrule this string by +%D supplying an alternative one. Look at the macro called for +%D to see how funny these bookmarks are defined. + +\def\doinsertbookmark#1#2#3#4#5% level sublevels text page open=1 + {\bgroup + \doPDFgetpagereference{#4}\PDFobjectreference + \pdfoutline + user {<>}% + \ifcase#2 \else count \ifcase#5-\fi#2 \fi +% {<\hexifiedPDFstring{#3}>}% goes wrong + {<#3>}% + \egroup} + +%D \macros +%D {dostartobject,dostopobject,doinsertobject} +%D +%D Due to \PDF's object oriented character, we can include and +%D reuse objects. These can be compared with \TEX's boxes. The +%D \TEX\ counterpart is defined in the module \type{spec-dvi}. +%D We don't use the dimensions here. +%D +%D The next solution is not that beautiful. Because objects are +%D containers for whatever kind of content, graphics can be +%D part of this content, and a graphic object can be part of +%D the more general type. In practice this means that an ximage +%D would be embedded in an xform, which in itself is not that +%D big a problem, apart from a few bytes overhead. However, for +%D reasons unknown to me alternative images must be pure +%D ximages |<|indeed, somehow one cannot use a vector graphic +%D as alternative|>| that are not embedded into forms, so this +%D is why the object handler treats them different. This +%D implies knowledge of the calling routines, especially the +%D \type{FIG} trigger, that signals that we just embedded an +%D image. Alternatively I could have introduced a dual object +%D system, but the overhead in duplicate specials is currently +%D not what we want. I'd rather implement a more mature +%D object support system from scratch. + +\let\currentPDFresources\empty +\let\PDFimageattributes \empty +\let\PDFfigurereference \empty +\let\PDFimagereference \empty + +\def\dostartobject#1#2#3#4#5% + {\bgroup + \setbox\nextbox\vbox\bgroup + \def\dodostopobject + {\egroup + \ifx\PDFimagereference\empty + % We also flush page resources, since shared + % resources end up there; otherwise transparencies + % won't work in xforms; some day I will optimize + % this. + \the\everyPDFxform + \finalizeobjectbox\nextbox + \immediate\pdfxform + resources {\currentPDFresources\the\pdfpageresources}% + \nextbox + \global\let\currentPDFresources\empty + \dosetobjectreference{#1}{#2}{\the\pdflastxform}% + \else + \dosetobjectreference{#1}{#2}{-\PDFimagereference}% + \global\let\PDFimagereference\empty + \fi}} + +\def\dostopobject + {\dodostopobject + \egroup} + +\def\doresetobjects + {\global\let\PDFimagereference\empty} + +\def\doinsertobject#1#2% + {\bgroup + \doifobjectreferencefoundelse{#1}{#2} + {\dogetobjectreference{#1}{#2}\PDFobjectreference + \ifnum\PDFobjectreference<0 + \@EA\@EA\@EA\pdfrefximage\@EA\gobbleoneargument\PDFobjectreference + \else + \pdfrefxform\PDFobjectreference + \fi}% + {}% + \egroup} + +\appendtoksonce + \collectPDFresources + \global\let\currentPDFresources\collectedPDFresources +\to \everyPDFxform + +%D \macros +%D {dosetpagetransition} +%D +%D Page transitions only make sence in presentations. They are +%D passed as raw \PDF\ code to the page object. Take a look +%D at the implementation to get an impression of the rubish +%D passed on. +%D +%D This array holds a reasonable selection of transitions +%D (watch out: \type{replace} is not in this list). Most of +%D the transitions look awful anyway. By the way, \CONTEXT\ is +%D able to select transitions randomly. + +\def\pagetransitions + {{split,in,vertical},{split,in,horizontal}, + {split,out,vertical},{split,out,horizontal}, + {blinds,horizontal},{blinds,vertical}, + {box,in},{box,out}, + {wipe,east},{wipe,west},{wipe,north},{wipe,south}, + dissolve, + {glitter,east},{glitter,south}, + {fly,in,east},{fly,in,west},{fly,in,north},{fly,in,south}, + {fly,out,east},{fly,out,west},{fly,out,north},{fly,out,south}, + {push,east},{push,west},{push,north},{push,south}, + {cover,east},{cover,west},{cover,north},{cover,south}, + {uncover,east},{uncover,west},{uncover,north},{uncover,south}, + fade} + +%D Again, we use macros as placeholders for \PDF\ key||value +%D pairs. + +\def\PDFpagesplit {/S /Split } +\def\PDFpageblinds {/S /Blinds } +\def\PDFpagebox {/S /Box } +\def\PDFpagewipe {/S /Wipe } +\def\PDFpagedissolve {/S /Dissolve } +\def\PDFpageglitter {/S /Glitter } +\def\PDFpagereplace {/S /R } + +\def\PDFpagefly {/S /Fly } % 1.5 +\def\PDFpagepush {/S /Push } % 1.5 +\def\PDFpagecover {/S /Cover } % 1.5 +\def\PDFpageuncover {/S /Uncover } % 1.5 +\def\PDFpagefade {/S /Fade } % 1.5 + +\def\PDFpagehorizontal {/Dm /H } +\def\PDFpagevertical {/Dm /V } +\def\PDFpagein {/M /I } +\def\PDFpageout {/M /O } +\def\PDFpageeast {/Di 0 } +\def\PDFpagenorth {/Di 90 } +\def\PDFpagewest {/Di 180 } +\def\PDFpagesouth {/Di 270 } + +\def\dodoPDFsetpagetransition#1% + {\doifdefined{PDFpage#1} + {\edef\PDFpagetransitions{\PDFpagetransitions\getvalue{PDFpage#1}}}} + +\def\dosetpagetransition#1#2% + {\let\PDFpagetransitions\empty + \processcommalist[#1]\dodoPDFsetpagetransition + \appendtopdfpageattributes + %{\ifnum#2>0 /Dur #2 \fi + {\ifnum0<0#2 /Dur #2 \fi + \ifx\PDFpagetransitions\empty\else/Trans <<\PDFpagetransitions>>\fi}} + +%D The expansion is needed because else the \type{\pdfpageattr} +%D token list flushes an unexpanded \type{\csname}. The +%D \type{\global} is needed because the assignment can take +%D place deeply buried (for instance in the \type{\shipout} +%D box. + +%D \macros +%D {doinsertcomment, doflushcomments} +%D +%D Text annotation, or comments, are provided too: + +%D \macros +%D {dopresetlinefield,dopresettextfield, +%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, +%D dopresetpushfield,dopresetcheckfield, +%D dopresetradiofield,dopresetradiorecord} +%D +%D \PDF\ offers extensive field support. The next bunch of +%D definitions map the specials. + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} +%D +%D Field sets, needed for reset and submit handling, are +%D taken care of by: + +%D The next section of this module is dedicated to form +%D support. These macros are complicated by the fact that +%D cloning is possible. + +%D \macros +%D {FDFflag...,FDFplus...} +%D +%D The \type{/FT} key determines the type of field: text, +%D button or choice. The latter two come in several disguises, +%D which are set by flipping bits in the \type{/Ff}. Other bits +%D are used to set states. Personally I hate this bitty way of +%D doing things. The next six bit determine the field sub type: + +\def\FDFflagMultiLine {4096} % 13 +\def\FDFflagNoToggleToOff {16384} % 15 +\def\FDFflagRadio {32768} % 16 +\def\FDFflagPushButton {65536} % 17 +\def\FDFflagPopUp {131072} % 18 +\def\FDFflagEdit {262144} % 19 + +% bugged anyway, so we need to drop it: + +\def\FDFflagRadiosInUnison {33554432} % 26 + +%D A few more (pdf 1.4) flags, what the spell check one: for +%D obscure reasons for Adobe downward compatibility means +%D enabling features that harm old applications like testing. + +\def\FDFflagDoNotSpellCheck {4194304} % 23 +\def\FDFflagDoNotScroll {8388608} % 24 + +%D The next bits (watch how strange the bits are organized) +%D take care of the states: + +\def\FDFflagReadOnly {1} % 1 +\def\FDFflagRequired {2} % 2 +\def\FDFflagNoExport {4} % 3 +\def\FDFflagPassword {8192} % 14 +\def\FDFflagSort {524288} % 20 +\def\FDFflagFileSelect {1048576} % 21 + +%D There is a second, again bitset oriented, \type{/F} flag: + +\def\FDFplusInvisible {1} % 1 +\def\FDFplusHidden {2} % 2 +\def\FDFplusPrintable {4} % 3 + +%def\FDFplusNoView {32} % 6 +%def\FDFplusToggleNoView {256} % 9 + +\def\FDFplusAutoView {256} % {288} % 6+9 + +%D \macros +%D {setFDFswitches} +%D +%D The non||type bits are mapped onto user||interface +%D swithes, to be used later on: + +\def\@@FDFflag{FDFflag} +\def\@@FDFplus{FDFplus} + +\letvalue {\@@FDFflag\v!readonly}=\FDFflagReadOnly +\letvalue {\@@FDFflag\v!required}=\FDFflagRequired +\letvalue {\@@FDFflag\v!protected}=\FDFflagPassword +\letvalue {\@@FDFflag\v!sorted}=\FDFflagSort +\letvalue {\@@FDFflag\v!unavailable}=\FDFflagNoExport +\letvalue {\@@FDFflag\v!nocheck}=\FDFflagDoNotSpellCheck +\letvalue {\@@FDFflag\v!fixed}=\FDFflagDoNotScroll +\letvalue {\@@FDFflag\v!file}=\FDFflagFileSelect + +\letvalue {\@@FDFplus\v!hidden}=\FDFplusHidden +\letvalue {\@@FDFplus\v!printable}=\FDFplusPrintable + +\letvalue {\@@FDFplus\v!auto}=\FDFplusAutoView + +%D A set of switches is collected into the flags we mentioned +%D before by the next macro (we don't handle negations yet, +%D but do take care of redundancy): + +\def\FDFflag{0} +\def\FDFplus{0} + +\def\setFDFswitches[#1]% + {\bgroup + \!!counta\zerocount + \!!countb\zerocount + \def\docommand##1% + {\doifsomething{##1} + {\advance\!!counta 0\getvalue{\@@FDFflag##1}% + \setvalue{\@@FDFflag##1}{0}% + \advance\!!countb 0\getvalue{\@@FDFplus##1}% + \setvalue{\@@FDFplus##1}{0}}}% + \processcommacommand[#1]\docommand + \xdef\FDFflag{\the\!!counta}% + \xdef\FDFplus{\the\!!countb}% + \egroup} + +%D \macros +%D {setFDFvalues} +%D +%D Menu items are passed as an array of \type{(string)}'s and +%D the content of this array is build with: + +\let\FDFvalues \empty +\let\FDFfirstvalues \empty +\let\FDFsecondvalues\empty +\let\FDFkidlist \empty +\let\FDFdefaultindex\!!zerocount +\let\FDFdefaultvalue\empty + +% Why do we need to tweak this mechanism each time acrobat updates ... +% it would make sense to have version specific sections in pdf files +% since my guess is that it never will be done right since each year +% new programmers have new ideas about what is supposed to happen with +% kids. So .. best is not to trust this feature esp not for radio +% widgets. (new flags, different interpretation of AS etc etc) + +\def\setFDFvalues[#1][#2]% #1 = list (item=>value) #2 = default + {\let\FDFvalues \empty + %when radio opt works ok + %\let\FDFfirstvalues \empty + %\let\FDFsecondvalues\empty + \let\FDFkidlist \empty + %\let\FDFdefaultindex\!!zerocount + %\let\FDFdefaultvalue\empty + %\scratchcounter\zerocount + \def\dodocommand##1=>##2=>##3\end + {\addtocommalist{##1}\FDFkidlist + %\edef\FDFfirstvalues{\FDFfirstvalues(##1)}% + %\doif{##1}{#2}{\edef\FDFdefaultindex{\the\scratchcounter}}% + %\advance\scratchcounter\plusone + \doifelsenothing{##2} + {\doif{##1}{#2}{\edef\FDFdefaultvalue{##1}}% + %\edef\FDFsecondvalues{\FDFsecondvalues(##1)}% + \edef\FDFvalues{\FDFvalues [(##1)(##1)] }} + {\doif{##1}{#2}{\edef\FDFdefaultvalue{##2}}% + %\edef\FDFsecondvalues{\FDFsecondvalues(##2)}% + \edef\FDFvalues{\FDFvalues [(##2)(##1)] }}}% ! ##1 is shown + \def\docommand##1% + {\dodocommand##1=>=>\end}% + \expanded{\processcommalist[#1]}\docommand} + +%D This macro accepts comma separated \type{visual=>result} +%D pairs. + +%D \macros +%D {setFDFalignment} +%D +%D Text and line fields can be entered and showed in three +%D alternative alingments, indicated by a digit: + +\def\FDFalign{0} + +\def\setFDFalignment[#1]% + {\processaction + [#1] + [ \v!left=>\edef\FDFalign{2}, % raggedleft + \v!middle=>\edef\FDFalign{1}, % raggedcenter + \v!right=>\edef\FDFalign{0}]} % raggedright + +%D \macros +%D {setFDFattributes} +%D +%D The weak part of (at least version 2.1 \PDF) is that only +%D default fonts are handled well. Another restriction is that +%D the encoding vector must be the standard \PDF\ document one. +%D Although the \PDF\ reference explictly states that one could +%D use the normal text operators, leading is not yet handled. +%D +%D For the moment the current \CONTEXT\ font is mapped onto +%D one best suitable default font. The color attribute is +%D less problematic and is directly derived from the \CONTEXT\ +%D color. + +\def\FDFattributes{/Helv 12 Tf 0 g 14.4 TL} + +\def\FDFrm {TiRo} \def\FDFss {Helv} \def\FDFtt {Cour} +\def\FDFrmtf{TiRo} \def\FDFsstf{Helv} \def\FDFtttf{Cour} +\def\FDFrmbf{TiBo} \def\FDFssbf{HeBo} \def\FDFttbf{CoBo} +\def\FDFrmit{TiIt} \def\FDFssit{HeOb} \def\FDFttit{CoOb} +\def\FDFrmsl{TiIt} \def\FDFsssl{HeOb} \def\FDFttsl{CoOb} +\def\FDFrmbi{TiBI} \def\FDFssbi{HeBO} \def\FDFttbi{CoBO} +\def\FDFrmbs{TiBI} \def\FDFssbs{HeBO} \def\FDFttbs{CoBO} + +\let\FDFusedfonts=\FDFsstf + +\def\setFDFattributes[#1,#2,#3,#4]% style, color, backgroundcolor, framecolor + {\bgroup % nog interlinie: n TL + \setbox\scratchbox\hbox + \bgroup + \doconvertfont{#1}{}% + \PointsToBigPoints\bodyfontsize\size % x/xx, so better the actual size + \doifdefinedelse{FDF\fontstyle\fontalternative} + {\xdef\FDFattributes{\getvalue{FDF\fontstyle\fontalternative}}} + {\doifdefinedelse{FDF\fontstyle} + {\xdef\FDFattributes{\getvalue{FDF\fontstyle}}} + {\xdef\FDFattributes{\FDFrm}}}% + \doglobal\addtocommalist\FDFattributes\FDFusedfonts + \xdef\FDFattributes% move up with "x.y Ts" + {/\FDFattributes\space\size\space Tf\space\PDFcolor{#2}}% + \doifelsenothing{#3} + {\global\let\FDFsurroundings\empty} + {\xdef\FDFsurroundings{/BG \FDFcolor{#3}}}% + \doifsomething{#4} + {\xdef\FDFsurroundings{\FDFsurroundings\space /BC \FDFcolor{#4}}}% + \ifx\FDFsurroundings\empty \else + \xdef\FDFsurroundings{/MK << \FDFsurroundings\space>>}% + \fi + \egroup + \egroup} + +%D \macros +%D {setFDFactions} +%D +%D Depending on the type of the field, one can assign +%D \JAVASCRIPT\ code to a mouse event or keystroke. The next +%D preparation macro shows what events are handled. + +\let\FDFactions\empty + +\def\setFDFactions[#1,#2,#3,#4,#5,#6,#7,#8,% + {\global\let\FDFactions\empty + \setFDFaction D#1% mousedown + \setFDFaction U#2% mouseup + \setFDFaction E#3% enterregion + \setFDFaction X#4% exitregion + \setFDFaction K#5% afterkeystroke + \setFDFaction F#6% formatresult + \setFDFaction V#7% validateresult + \setFDFaction C#8% calculatewhatever + \setFDFactionsmore} + +\def\setFDFactionsmore#1,#2]% + {\setFDFaction{Fo}#1% focusin + \setFDFaction{Bl}#2% focusout % was I (now pdf ref manual explicitly talks about lowercase l) + \ifx\FDFactions\empty\else + \xdef\FDFactions{/AA << \FDFactions >>}% since 1.3 no longer inherited + \fi} + +% todo, when new var scheme is implemented +% +% \setFDFaction{PO}\@@DriverFieldPageOpen +% \setFDFaction{PC}\@@DriverFieldPageClose +% \setFDFaction{PV}\@@DriverFieldPageVisible +% \setFDFaction{PI}\@@DriverFieldPageInVisible + +%D The event handler becomes something: +%D +%D \starttyping +%D /AA << /D << /S ... >> ... /C << /S ... >> +%D /A << /S /JavaScript /JS (...) >> +%D \stoptyping + +\def\setFDFaction#1#2% + {\bgroup + \def\docommand{\xdef\FDFactions{\FDFactions /#1 << \lastPDFaction >> }}% + \@EA\handlereferenceactions\@EA{#2}\docommand % one level expansion + \egroup} + +%D \macros +%D {testFDFactions} +%D +%D This rather confusion prone series of script can be tested +%D with: +%D +%D \starttyping +%D \testFDFactions +%D \stoptyping +%D +%D which simply redefined the previous macro to one that prints +%D a message to the console. + +\def\testFDFactions + {\def\setFDFaction##1##2% + {\doPSsanitizeJScode console.show();console.println("executing:##1"); \to\sanitizedJScode + \edef\FDFactions{\FDFactions /##1 << /S /JavaScript /JS (\sanitizedJScode) >> }}} + +%D \macros +%D {doregistercalculationset} +%D +%D There is at most one calculation order list, which defines +%D the order in which fields are calculated. The calculation +%D order is defined using: + +\let\PDFcalculationset\empty + +\def\doregistercalculationset#1% + {\def\PDFcalculationset{#1}} + +%D \macros +%D {registerFDFobject,everylastshipout} +%D +%D Officially one needs to embed some general datastructures +%D that tell the viewer what fields are present in the file, as +%D well as what resources they use. The next mechanism does that +%D job automatically when one registers the field. + +\def\flushFDFnames + {\ifx\FDFcollection\empty\else + \defineFDFfonts + \createpdfarrayobject{FDF}{local:fields}{\FDFcollection}% + \doPDFgetobjectreference{FDF}{local:fields}\PDFobjectreference + % The /NeedAppearances is pretty important because + % otherwise Acrobat 5 blows up on cloned radio widgets + \createpdfdictionaryobject{FDF}{local:acroform} + {/Fields \PDFobjectreference\space + /NeedAppearances true + \doiffieldset\PDFcalculationset{/CO [\dogetfieldset\PDFcalculationset]} + /DR << /Font << \FDFfonts >> >> + /DA (/Helv 10 Tf 0 g)}% + \doPDFgetobjectreference{FDF}{local:acroform}\PDFobjectreference + \appendtopdfcatalog + {/AcroForm \PDFobjectreference}% + \global\let\FDFcollection\empty + \global\let\flushFDFnames\relax + \fi} + +\let\FDFcollection\empty + +\def\registerFDFobject#1% + {\ifx\flushFDFnames\relax + \writestatus{FDF}{second run needed for field list (#1)}% + \fi + \doPDFgetobjectreference{FDF}{#1}\PDFobjectreference + \xdef\FDFcollection{\FDFcollection\space\PDFobjectreference}} + +\appendtoksonce \flushFDFnames \to \everylastshipout % test \everybye / was \prependtoksonce + +%D \macros +%D {defineFDFfonts} +%D +%D Another datastruture concerns the fonts used. We only +%D define the fonts we use. + +\def\defineFDFfonts + {\let\FDFfonts\empty + \processcommacommand[\FDFusedfonts]\defineFDFfont} + +\def\defineFDFfont#1% + {\createpdfdictionaryobject{FDF}{local:#1} + {/Type /Font + /Subtype /Type1 + /Name /#1 + /BaseFont /\getvalue{FDFname#1}}% + \doPDFgetobjectreference{FDF}{local:#1}\PDFobjectreference + \edef\FDFfonts{\FDFfonts \space/#1 \PDFobjectreference}} + +%D Another list of constants: + +\def\FDFnameTiRo {Times-Roman} +\def\FDFnameTiBo {Times-Bold} +\def\FDFnameTiIt {Times-Italic} +\def\FDFnameTiBI {Times-BoldItalic} +\def\FDFnameHelv {Helvetica} +\def\FDFnameHeBo {Helvetica-Bold} +\def\FDFnameHeOb {Helvetica-Oblique} +\def\FDFnameHeBO {Helvetica-BoldOblique} +\def\FDFnameCour {Courier} +\def\FDFnameCoBo {Courier-Bold} +\def\FDFnameCoOb {Courier-Oblique} +\def\FDFnameCoBO {Courier-BoldOblique} + +%D \macros +%D {currentFDFmode,currentFDFparent,currentFDFkids,currenrFDFroot} +%D +%D There are three more quasi global interfacing variables +%D that need to be set. + +\let\currentFDFmode \fieldlonermode +\let\currentFDFkids \empty +\let\currentFDFparent\empty +\let\currentFDFroot \empty + +%D \macros +%D {dosetfieldstatus} +%D +%D And here comes the special that deals with them. + +\def\dosetfieldstatus#1#2#3#4% + {\chardef\currentFDFmode #1% + \edef\currentFDFparent {#2}% + \edef\currentFDFkids {#3}% + \edef\currentFDFroot {#4}} + +%D We already dealt with the encoding vector. Conversion from +%D \TEX\ \ASCII\ encoding to the other one, is accomplished by +%D the next few macros. Wach out: we don't group here. + +\appendtoksonce + \simplifycommands +\to \everysetfield + +%D \macros +%D {doPDFinsertcomment} +%D +%D An example its use is the next special, one that deals with +%D text annotations. + +\newcounter\nofFDFcomments + +\newif\ifPDFpopupcomments \PDFpopupcommentstrue + +\def\doflushcomments + {\box\PDFsymbolbox} + +\long\def\doinsertcomment#1#2#3#4#5#6#7#8% % \@@DriverCommentLayer set otherwise + {\bgroup % title width height color open symbol collect data + \presetPDFsymbolappearance{#4}{#6}{#2}{#3}\!!zeropoint% sets width/height + \doifelsenothing{#1} + {\let\PDFidentifier\empty} + {\sanitizePDFencoding#1\to\PDFcommenttitle + \def\PDFidentifier{/T <\PDFcommenttitle>}}% + \sanitizePDFencoding#8\to\PDFdata + \setFDFlayer\@@DriverCommentLayer + \startPDFsymbolappearance + \ifPDFpopupcomments + \doglobal\increment\nofFDFcomments + \doifobjectreferencefoundelse{FDF}{c:\nofFDFcomments} + {\doPDFgetobjectreference{FDF}{c:\nofFDFcomments}\PDFobjectreference + \donetrue} + \donefalse + \ifdone + \setbox\scratchbox\hbox + {\createpdfannotationobject{FDF}{c::\nofFDFcomments}{#2}{#3}% text window, size does not work + {/Subtype /Popup + /Parent \PDFobjectreference}}% + \ifcase#7\relax + \vbox to \height{\forgetall\vskip#3\box\scratchbox\vss}% + \else % incredible trial and error hack + % it's quite a mess, the annot width cannot be set, well, it can + % but the appearance and text sizes get mixed up +% \setbox\scratchbox\vbox to \height{\forgetall\vskip#3\box\scratchbox\vss}% +% \global\setbox\PDFsymbolbox\vbox +% {\hsize#2% +% \forgetall +% \vsmash{\box\PDFsymbolbox} +% \box\scratchbox}% + % this may change when acrobat gets less bugged + \setbox\scratchbox\vbox to #3{\forgetall\vss\box\scratchbox}% + \wd\scratchbox#2% + \global\setbox\PDFsymbolbox\vbox + {\startoverlay{\box\PDFsymbolbox}{\box\scratchbox}\stopoverlay}% + \fi + \fi + % generic + \doifobjectreferencefoundelse{FDF}{c::\nofFDFcomments} + {\doPDFgetobjectreference{FDF}{c::\nofFDFcomments}\PDFobjectreference + \donetrue} + \donefalse + \createpdfannotationobject{FDF}{c:\nofFDFcomments}{\width}{\height} + {/Subtype /Text + \ifcase#5 \else/Open true\fi + % pdftex (efficient) + % \ifdone /Popup \PDFobjref\pdflastannot\fi + % generic (less efficient) + \ifdone /Popup \PDFobjectreference\fi + /Contents <\PDFdata> + \PDFidentifier + \FDFlayer + \PDFsymbol + \PDFattributes}% + \else + \insertpdfannotation{#2}{#3} + {/Subtype /Text + \ifcase#5 \else/Open true\fi + /Contents <\PDFdata> + \FDFlayer + \PDFsymbol + \PDFidentifier + \PDFattributes}% + \fi + \stopPDFsymbolappearance + \egroup} + +% symbols with a reasonable default of 18/24 pt + +\newbox\PDFsymbolbox + +\def\PDFsymbolNew {/Insert} +\def\PDFsymbolBalloon {/Comment} +\def\PDFsymbolAddition {/NewParagraph} +\def\PDFsymbolHelp {/Help} +\def\PDFsymbolParagraph {/Paragraph} +\def\PDFsymbolKey {/Key } + +\def\PDFsymbolGraph {/Graph} +\def\PDFsymbolPaperclip {/Paperclip} +\def\PDFsymbolAttachment{/Attachment} +\def\PDFsymbolTag {/Tag} + +\def\startPDFsymbolappearance + {\setbox\scratchbox\vbox to \totalheight \bgroup \vfill} + +\def\stopPDFsymbolappearance + {\egroup + \setbox\scratchbox\hbox{\lower\depth\box\scratchbox}% + \wd\scratchbox\width + \ht\scratchbox\height + \dp\scratchbox\depth + \box\scratchbox} + +\def\presetPDFsymbolappearance#1#2#3#4#5% symbol color width height depth + {\doifelsenothing{#1} + {\let\PDFattributes\empty} + {\def\PDFattributes{/C \FDFcolor{#1}}}% + \scratchdimen#3\edef\width {\the\scratchdimen}% + \scratchdimen#4\edef\height{\the\scratchdimen}% + \scratchdimen#5\edef\depth {\the\scratchdimen}% + \advance\scratchdimen\height\edef\totalheight{\the\scratchdimen}% + \doifelsenothing{#2} + {\let\PDFsymbol\empty} + {\ifundefined{PDFsymbol#2}% + \getfromcommacommand[#2][1]\let\PDFsymbolnormalsymbol\commalistelement + \getfromcommacommand[#2][2]\let\PDFsymboldownsymbol \commalistelement + \doifsymboldefinedelse\PDFsymbolnormalsymbol + {\doifsymboldefinedelse\PDFsymboldownsymbol + {\dopresetPDFsymbolappearance + \PDFsymbolnormalsymbol\PDFsymboldownsymbol} + {\dopresetPDFsymbolappearance + \PDFsymbolnormalsymbol\PDFsymbolnormalsymbol}} + {\doifsymboldefinedelse\PDFsymboldownsymbol + {\dopresetPDFsymbolappearance + \PDFsymboldownsymbol\PDFsymboldownsymbol} + {\let\PDFsymbol\empty}}% + \else + \def\PDFsymbol{/Name \getvalue{PDFsymbol#2} }% + \fi}} + +\def\dopresetPDFsymbolappearance#1#2% + {\dopresetfieldsymbol{#1}% + \dopresetfieldsymbol{#2}% + \setbox\scratchbox\hbox{\symbol[#1]}% + \edef\width {\the\wd\scratchbox}% + \edef\height{\the\ht\scratchbox}% + \edef\depth {\the\dp\scratchbox}% + \scratchdimen\height \advance\scratchdimen\depth + \edef\totalheight{\the\scratchdimen}% + \doPDFgetobjectreference{SYM}{#1}\FDFsymbolNappearance + \doPDFgetobjectreference{SYM}{#2}\FDFsymbolDappearance + \edef\PDFsymbol + {/AP <>}} + +%D Hooked into \CONTEXT, this special supports +%D +%D \starttyping +%D \startcomment +%D hello beautiful\\world +%D \stopcomment +%D +%D \startcomment[hello] +%D de \'e\'erste keer +%D the f\'irst time +%D \stopcommen +%D +%D \startcommentaar[hallo][color=green,width=4cm,height=3cm] +%D first +%D +%D second +%D \stopcommentaar +%D \stoptyping +%D +%D So, special characters, forced linebreaks using \type{\\} +%D and \type{\par} are handled in the appropriate way. + +%D \macros +%D {dosetuppageview} +%D +%D Because this command will seldom be called, we can permit +%D slow action processing. We need three settings, one for +%D direct \PDF\ inclusion, the other as \PDFTEX\ keyword, an +%D a last one for form. All determine in what way the +%D screen is adapted when going to a destination. Watch the +%D space. + +\def\PDFpageviewkey{fit} +\def\PDFpageviewwrd{/Fit} +\def\PDFpageview {/View [\PDFpageviewwrd] } +\def\PDFpagexyzspec{0 0 0} % hack, pdftex does handle this +\let\PDFpagexyzspec\empty % hack, pdftex does not accept spec + +\def\dosetuppageview#1% watch the v-h swapping here + {\processaction + [#1] + [ \v!fit=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit}, + \v!width=>\def\PDFpageviewkey {fith}\def\PDFpageviewwrd{/FitH}, + \v!height=>\def\PDFpageviewkey {fitv}\def\PDFpageviewwrd{/FitV}, + \v!minwidth=>\def\PDFpageviewkey{fitbh}\def\PDFpageviewwrd{/FitBH}, + \v!minheight=>\def\PDFpageviewkey{fitbv}\def\PDFpageviewwrd{/FitBV}, + \v!standard=>\def\PDFpageviewkey{xyz \PDFpagexyzspec}\def\PDFpageviewwrd{/XYZ \PDFpagexyzspec}, + \s!unknown=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit}]% + \edef\PDFpageview{/View [\PDFpageviewwrd]}} + +%D \macros +%D {setFDFkids} +%D +%D Clones as well as radiofields (which themselves can have +%D cloned components) need a list of kids. The next macro +%D builds one. + +\def\setFDFkids[#1][#2]% tag commalist + {\let\FDFkids\empty + \def\docommand##1% + {\doPDFgetobjectreference{FDF}{#1##1}\PDFobjectreference + \edef\FDFkids{\FDFkids\PDFobjectreference\space}}% + \@EA\processcommalist\@EA[#2]\docommand + \ifx\FDFkids\empty\else\edef\FDFkids{/Kids [\FDFkids]}\fi} + +%D \macros +%D {dopresetlinefield,dopresettextfield, +%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, +%D dopresetpushfield,dopresetcheckfield, +%D dopresetfield,dopresetradiorecord} +%D +%D I would say: read the \PDF\ reference manual first and see +%D what happens here next. Lucky us that they have so much in +%D common. + +\def\dopresetlinefield#1#2#3#4#5#6#7#8#9% + {\bgroup + \setFDFlayer\@@DriverFieldLayer + \setFDFswitches[#7]% + \setFDFattributes[#6]% + \setFDFalignment[#8]% + \setFDFactions[#9]% + \edef\FDFtext{\hexifiedPDFstring{#4}}% + \ifcase\currentFDFmode + \createpdfannotationobject{FDF}{#1}{#2}{#3} + {/Subtype /Widget /T (#1) /FT /Tx + /MaxLen \ifcase0#5 1000 \else#5 \fi + %/DV (#4) /V (#4) % value added + /DV <\FDFtext> /V <\FDFtext> + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + /Q \FDFalign\space + \FDFactions}% + \registerFDFobject{#1}% + \or + \setFDFkids[kids:][\currentFDFkids]% + \createpdfdictionaryobject{FDF}{#1} + {/T (#1) /FT /Tx + /MaxLen \ifcase0#5 1000 \else#5 \fi + \FDFkids\space + %/DV (#4) /V (#4) % value added + /DV <\FDFtext> /V <\FDFtext> + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + /Q \FDFalign\space + \FDFactions}% + \registerFDFobject{#1}% + \or + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + /Q \FDFalign\space + \FDFactions}% + \or + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference + /F \FDFplus + \FDFactions}% + \fi + \egroup} + +\def\dopresettextfield#1#2#3#4#5#6#7#8#9% + {\dopresetlinefield{#1}{#2}{#3}{#4}{#5}{#6}{MultiLine,#7}{#8}{#9}} + +\def\dopresetchoicefield#1#2#3#4#5#6#7#8% + {\bgroup + \setFDFlayer\@@DriverFieldLayer + \setFDFswitches[#6]% + \setFDFattributes[#5]% + \setFDFvalues[#7][#4]% + \setFDFactions[#8]% + \ifcase\currentFDFmode + \createpdfannotationobject{FDF}{#1}{#2}{#3} + {/Subtype /Widget + /T (#1) /FT /Ch + /DV (#4) /V (#4) + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + /Opt [\FDFvalues] + \FDFactions}% + \registerFDFobject{#1}% + \or + \setFDFkids[kids:][\currentFDFkids]% + \createpdfdictionaryobject{FDF}{#1} + {/T (#1) /FT /Ch + \FDFkids\space + /DV (#4) /V (#4) + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + /Opt [\FDFvalues] + \FDFactions}% + \registerFDFobject{#1}% + \or + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + \FDFactions}% + \or + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference + /F \FDFplus + \FDFactions}% + \fi + \egroup} + +\def\dopresetpopupfield#1#2#3#4#5#6#7#8% + {\dopresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,#6}{#7}{#8}} + +\def\dopresetcombofield#1#2#3#4#5#6#7#8% + {\dopresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,Edit,#6}{#7}{#8}} + +\newif\ifFDFvalues + +\def\doFDFpresetpushcheckfield#1#2#3#4#5#6#7#8% in acro<5 (\FDFdefault) + {\bgroup % in acro>5 /\FDFdefault + \setFDFlayer\@@DriverFieldLayer + \ifcase#8\relax\FDFvaluesfalse\else\FDFvaluestrue\fi + \setFDFswitches[#5]% + \setFDFactions[#7]% + \doifelse{#4}{1} + {\def\FDFdefault{On}} + {\def\FDFdefault{Off}}% + \ifcase\currentFDFmode + \doFDFappearance{On}{#6}{#8}% + \createpdfannotationobject{FDF}{#1}{#2}{#3} + {/Subtype /Widget /T (#1) /FT /Btn + \ifFDFvalues + /DV /\FDFdefault\space + /V /\FDFdefault\space + /AS /\FDFdefault\space + \fi + \FDFlayer + /Ff \FDFflag\space + /F \FDFplus\space + \FDFlayer\space + \FDFappearance\space +% /IF << /SW /N >> % strange, only works for stupid buttons + \FDFactions}% + \registerFDFobject{#1}% + \or % no appearance and layer ? + \setFDFkids[kids:][\currentFDFkids]% + \createpdfdictionaryobject{FDF}{#1} + {/T (#1) /FT /Btn + \FDFkids\space + \ifFDFvalues + /DV /\FDFdefault\space + /V /\FDFdefault\space + /AS /\FDFdefault\space + \fi + /Ff \FDFflag\space + /F \FDFplus\space + \FDFactions}% + \registerFDFobject{#1}% + \or + \doFDFappearance{On}{#6}{#8}% + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference\space + \ifFDFvalues + /DV /\FDFdefault\space + /V /\FDFdefault\space + /AS /\FDFdefault\space + \fi + /Ff \FDFflag\space + /F \FDFplus\space + \FDFlayer\space + \FDFappearance\space + \FDFactions}% + \or + \doFDFappearance{On}{#6}{#8}% + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference\space + /F \FDFplus\space + \ifFDFvalues + /DV /\FDFdefault\space + /V /\FDFdefault\space + /AS /\FDFdefault\space + \fi + \FDFlayer\space + \FDFappearance + \FDFactions}% + \fi + \egroup} + +\def\dopresetpushfield#1#2#3#4#5#6#7% + {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{PushButton,#5}{#6}{#7}{0}} + +\def\dopresetcheckfield#1#2#3#4#5#6#7% + {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{1}} + +\def\dopresetradiofield#1#2#3#4#5#6#7#8% + {\bgroup + \setFDFlayer\@@DriverFieldLayer + \FDFvaluestrue + \setFDFswitches[#5]% + \setFDFactions[#8]% + \doifelsenothing{#4} + {\def\FDFdefault{Off}} + {\def\FDFdefault{#4}}% + \@EA\aftersplitstring\FDFdefault\at=>\to\FDFdefaultvalue + \ifx\FDFdefaultvalue\empty\else\let\FDFdefault\FDFdefaultvalue\fi + \ifcase\currentFDFmode + \doFDFappearance{#1}{#7}{1}% + \doPDFgetobjectreference{FDF}{#6}\PDFobjectreference + \createpdfannotationobject{FDF}{#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference\space + /F \FDFplus\space + /AS /\FDFdefault\space + \FDFlayer\space + \FDFappearance\space + \FDFactions}% + \registerFDFobject{#1}% + \or + \setFDFkids[kids:][\currentFDFkids]% + \doPDFgetobjectreference{FDF}{#6}\PDFobjectreference + \createpdfdictionaryobject{FDF}{#1} + {/Parent \PDFobjectreference\space + \FDFkids\space + /F \FDFplus\space + \FDFactions}% + \registerFDFobject{#1}% + \or + %\doFDFappearance{#1}{#7}{1}% + \doFDFappearance{\currentFDFparent}{#7}{1}% + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue % nb + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference\space + /AS /\FDFdefault\space + /F \FDFplus\space + \FDFlayer\space + \FDFappearance\space + \FDFactions}% + \or + %\doFDFappearance{#1}{#7}{1}% + \doFDFappearance{\currentFDFparent}{#7}{1}% + \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference + %\global\objectreferencingtrue + \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference\space + /AS /\FDFdefault\space + /F \FDFplus\space + \FDFlayer\space + \FDFappearance\space + \FDFactions}% + \fi + \egroup} + +% Beware, RadiosInUnison is really needed in the pre 1.5/6 time this +% was the default but out of a sudden it's no longer the case. Also +% the NoToggleToOff interferes with kids of kids and both it will +% break older documents, i.e. so much for pdf as standard. With +% features like widgets we can probably best wait till adobe tools +% themselves support it because that's probably the moment that +% functionality gets frozen/becomes definitive. Actually, acrobat +% flattens the kids tree, so that's yet another situation. The +% interesting thing is that it worked ok in acrobat 2/3 but got bugged +% in later versions. [The rationale is in html compatibility, which +% seems to be more important than compatibility of documents, which in +% turn renders acrobat useless for forms.] Anyway, synchronization is +% broken or not depending on the combination pdfversion/acrobatversion. + +\def\dopresetradiorecord#1#2#3#4#5% + {\bgroup + % < pdf 1.5 (1.5 was broken) + % \setFDFswitches[Radio,NoToggleToOff,RadiosInUnison,#3]% + % > pdf 1.5 + \setFDFswitches[Radio,RadiosInUnison,#3]% + % older, else fatal error + % \setFDFkids[#4][]% + % newer + \setFDFvalues[#4][#2]% inits kidlist + \expanded{\setFDFkids[][\FDFkidlist]}% + % + \setFDFactions[#5]% + \createpdfdictionaryobject{FDF}{#1} + {%/Subtype /Widget + /FT /Btn /T (#1) /Rect [0 0 0 0] + % used to be this + % /V (#2) + % then this + % /DV (#2) + % since this bomded in 5 + % /V (#2) + % and now finally this works + /H /N + % /opt is buggy in 5.05, only works once, sigh + %\ifx\FDFfirstvalues\FDFsecondvalues + /V /#2 + %\else + % /V /\FDFdefaultindex\space + % /Opt [\FDFsecondvalues] + %\fi + /Ff \FDFflag\space + /F \FDFplus\space + \FDFkids\space + \FDFactions}% + \egroup} + +%D At the cost of some more references, we can save bytes, +%D by sharing appearance dictionaries. This code needs more +%D documentation. Surprise: + +\def\dodoFDFappearance#1#2% + {\ifx#2\empty\else + \dogetcommacommandelement1\from#2\to\commalistelement + \ifx\commalistelement\empty\else + \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference + \edef\N{\ifFDFvalues\N /#1 \fi\PDFobjectreference\space}% + \fi + \dogetcommacommandelement2\from#2\to\commalistelement + \ifx\commalistelement\empty\else + \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference + \edef\R{\ifFDFvalues\R /#1 \fi\PDFobjectreference\space}% + \fi + \dogetcommacommandelement3\from#2\to\commalistelement + \ifx\commalistelement\empty\else + \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference + \edef\D{\ifFDFvalues\D /#1 \fi\PDFobjectreference\space}% + \def\FDFappearance{/H /P }% + \fi + \fi} + +\def\redoFDFappearance#1% + {\ifx#1\empty\else + \dogetcommacommandelement3\from#1\to\commalistelement + \ifx\commalistelement\empty\else + \def\FDFappearance{/H /P }% + \fi + \fi} + +\def\doFDFappearance#1#2#3% + {\ifcase#3\relax % push only field + \edef\yes{#2}% + \let\no\empty + \else % on / off field + \dogetcommacommandelement1\from#2,\to\yes + \dogetcommacommandelement2\from#2,\to\no + \fi + \def\FDFappearance{/H /N}% + \doifobjectfoundelse{FDF}{ap:#1:\yes:\no} + {\redoFDFappearance\yes + \redoFDFappearance\no} + {\presetobject{FDF}{ap:#1:\yes:\no}% funny hack + \let\N\empty\let\R\empty\let\D\empty + \dodoFDFappearance{#1}\yes + \dodoFDFappearance{Off}\no + \createpdfdictionaryobject{FDF}{ap:#1:\yes:\no} + {\ifx\N\empty\else/N \ifFDFvalues<<\N>>\else\N\fi\fi + \ifx\R\empty\else/R \ifFDFvalues<<\R>>\else\R\fi\fi + \ifx\D\empty\else/D \ifFDFvalues<<\D>>\else\D\fi\fi}}% + \doPDFgetobjectreference{FDF}{ap:#1:\yes:\no}\PDFobjectreference + \edef\FDFappearance{\FDFappearance /AP \PDFobjectreference}} + +\def\doFDFdefault#1#2% + {\doifelse{#2}{1}{\def\FDFdefault{On}}{\def\FDFdefault{Off}}} + +%D Layer support: + +\def\setFDFlayer#1% todo : \ifx\PDFobjectreference\noPDFobjectreference ipv found + {\letempty\FDFlayer + \doifsomething{#1}% + {\checkproperty[#1]% == \dodocheckproperty\@@DriverFieldLayer + \doifobjectreferencefoundelse{PDLN}{#1} + {\doPDFgetobjectreference{PDLN}{#1}\!!stringa % we need to avoid a clash with other macros + \edef\FDFlayer{/OC \!!stringa}}% + \donothing}} + +%D The three appearances {\em normal}, \type{roll over} and +%D \type{push down} are passed as comma separated triplets, +%D that is, the second argument can look like: +%D +%D \starttyping +%D {yes,ok,fine},{no,rubish,awful} +%D \stoptyping + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} +%D +%D Field sets, the ones we use in submitting and resetting +%D fields, are implemented using the next low level specials: +%D +%D \starttyping +%D \doFDFdefinefieldset{TAG}{name,name,...} +%D \doFDFgetfieldset{TAG} +%D \doiffieldset{TAG}{sequence} +%D \stoptyping + +\def\dodefinefieldset#1#2% tag commalist + {\let\FDFfieldset\empty + \def\docommand##1% + {\doPDFgetobjectreference{FDF}{##1}\PDFobjectreference + \edef\FDFfieldset{\FDFfieldset\PDFobjectreference\space}}% + \processcommacommand[#2]\docommand % nb: command + \setevalue{FDF:set:#1}{\FDFfieldset}} + +\def\dogetfieldset#1% + {\getvalue{FDF:set:#1}} + +\def\doiffieldset#1#2% + {\ifundefined{FDF:set:#1}\else#2\fi} + +%D \macros +%D {defaultobjectreference,doPDFgetobjectreference} +%D +%D Because in \PDFTEX\ we have to construct the object +%D references \type{N 0 R}, we can default to the non existing +%D zero object number. + +\def\defaultobjectreference#1#2% + {0} + +\def\doPDFgetobjectreference#1#2#3% + {\dogetobjectreference{#1}{#2}#3% + \edef#3{\ifx#3\empty null\else\PDFobjref{#3}\fi}} + +\def\doPDFgetobjectnumber#1#2#3% + {\dogetobjectreference{#1}{#2}#3% + \edef#3{\ifx#3\empty 0\else#3\fi}} + +\def\doPDFgetobjectpage#1#2#3% + {\dogetobjectreferencepage{#1}{#2}#3% + \ifx#3\empty\def#3{1}\fi} + +\def\doPDFgetobjectpagereference#1#2#3% + {\dogetobjectreferencepage{#1}{#2}#3% + \ifx#3\empty + \doPDFgetpagereference\realfolio#3% + \else + \doPDFgetpagereference#3#3% we assume that #3 gets expanded + \fi} + +\def\doPDFgetpagereference#1#2% number macro + {\edef#2{\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi}} + +\def\thePDFpagereference#1#2% number macro + {\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi} + +%D \macros +%D {initializePDFnegative,initializePDFoverprint} +%D +%D Here follow some rather obscure macros. They will only +%D come into action when one wants negated output. + +\def\initializePDFnegative + {\immediate\pdfobj stream attr {/FunctionType 4 /Range [0 1] /Domain [0 1]} {{1 exch sub}}% + \immediate\pdfobj{<>}% + \appendtoPDFdocumentextgstates{/GSnegative \PDFobjref\pdflastobj}% + \immediate\pdfobj{<>}% + \appendtoPDFdocumentextgstates{/GSpositive \PDFobjref\pdflastobj}% + \global\let\initializePDFnegative\relax} + +\def\initializePDFoverprint + {\immediate\pdfobj{<>}% /op defaults to /OP + \appendtoPDFdocumentextgstates{/GSknockout \PDFobjref\pdflastobj}% + \immediate\pdfobj{<>}% /op defaults to /OP + \edef\PDFobjectreferenceB{\the\pdflastobj}% + \appendtoPDFdocumentextgstates{/GSoverprint \PDFobjref\pdflastobj}% + \global\let\initializePDFoverprint\relax} + +%D File embedding. Storing the stream identifier is needed +%D to get access to the number. When typeset, the user can +%D feed this number to \type {pdftosrc} and filter the +%D file from the \PDF\ file. + +\let\PDFlaststreamobject \s!unknown +%def\PDFlaststreamreference{0 0 R} + +\def\doPDFfilestreamobject#1#2#3#4% + {\immediate\pdfobj stream file{#4}% + \edef\PDFlaststreamobject{\the\pdflastobj}% + \dosetobjectreference{PDFFS}{#2}{\PDFlaststreamobject}% + \createpdfdictionaryobject{#1}{#2}{/Type /Filespec /F (#3) /EF <>}} + +\def\doPDFgetfilestreamreference#1#2% + {\doPDFgetobjectreference{PDFFS}{#1}#2} + +\def\doPDFfilestreamidentifier#1% + {\doifsomething{#1} + {\doPDFgetfilestreamreference{#1}\PDFobjectreference + \@EA\beforesplitstring\PDFobjectreference\at{ }\to\PDFlaststreamobject + \PDFlaststreamobject}} + +% MP ? + + \def\setMPPDFobject#1#2% resources boxnumber + {\the\everyPDFxform + \finalizeobjectbox{#2}% + \immediate\pdfxform resources{#1}#2% + \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}} + + \let\getMPPDFobject\relax + + \def\doinsertMPfile#1% + {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}} + +%D Even newer trickery: + +% resource -> prop -> mc's -> OCG|OCMD (nested) +% ocg: +% /Intent/Design +% ocmd +% /P /AllOn +% kan zelf ocmd bevatten + +\let\PDFtextlayers\empty +\let\PDFpagelayers\empty +\let\PDFhidelayers\empty +\let\PDFvidelayers\empty + +\def\dostartlayer#1{\PDFcode{/OC /#1 BDC}} +\def\dostoplayer {\PDFcode {EMC}} + +\def\dodefineviewerlayer#1#2#3#4#5% tag title visible type printable + {\createpdfdictionaryobject{PDLN}{#1} + {/Type /OCG + \ifcase#4 \or + /Intent /Design % disable layer hiding by user + \fi + \ifnum#5=\zerocount + /Usage << /Print << /PrintState /OFF >> >> % printable or not + \fi + /Name (#2)}% + \doPDFgetobjectreference{PDLN}{#1}\PDFobjectreference + \xdef\PDFtextlayers{\PDFtextlayers\space\PDFobjectreference}% + \doifelse{#3}\v!start + {\xdef\PDFvidelayers{\PDFvidelayers\space\PDFobjectreference}}% + {\xdef\PDFhidelayers{\PDFhidelayers\space\PDFobjectreference}}% + \createpdfdictionaryobject{PDLD}{#1} + {/Type /OCMD + /OCGs [\PDFobjectreference]}% + \doPDFgetobjectreference{PDLD}{#1}\PDFobjectreference + \xdef\PDFpagelayers{\PDFpagelayers\space /#1 \PDFobjectreference}} + +\def\flushPDFtextlayers + {\ifx\PDFtextlayers\empty \else + \driverreferenced \createpdfarrayobject{PDF}{textlayers}{\PDFtextlayers}% + \doPDFgetobjectreference{PDF}{textlayers}\!!stringa + \ifx\PDFvidelayers\empty + \def\!!stringb{[null]}% + \else + \driverreferenced \createpdfarrayobject{PDF}{videlayers}{\PDFvidelayers}% + \doPDFgetobjectreference{PDF}{videlayers}\!!stringb + \fi + \ifx\PDFhidelayers\empty + \def\!!stringc{[null]}% + \else + \driverreferenced \createpdfarrayobject{PDF}{hidelayers}{\PDFhidelayers}% + \doPDFgetobjectreference{PDF}{hidelayers}\!!stringc + \fi + \appendtopdfcatalog + {/OCProperties + << % display in menu + /D << /Order \!!stringa + /ON \!!stringb + /OFF \!!stringc >> + % used properties + /OCGs \!!stringa >>}% + \globallet\flushPDFtextlayers\relax + \fi} + +\def\flushPDFpagelayers + {\ifx\PDFpagelayers\empty \else + \appendtopdfpageresources{/Properties <<\PDFpagelayers>>}% + \fi} + +\def\PDFlayeractionlist{null} + +\def\PDFexecutehidelayer {/SetOCGState /State [/OFF \PDFlayeractionlist]} +\def\PDFexecutevidelayer {/SetOCGState /State [/ON \PDFlayeractionlist]} +\def\PDFexecutetogglelayer {/SetOCGState /State [/Toggle \PDFlayeractionlist]} + +\def\domakeviewerlayerlist#1% + {\bgroup + \globallet\PDFlayeractionlist\empty + \def\docommand##1% + {\doPDFgetobjectreference{PDLN}{##1}\PDFobjectreference + \xdef\PDFlayeractionlist{\PDFlayeractionlist\space\PDFobjectreference}}% + \processcommalist[#1]\docommand + \egroup} + +%D Something rather pdf dependent: + +% #1 => 1=fill 2=stroke 3=strokedfill 4=invisible +% #2 => linewidth +% #3 => spacing (beware, one needs to set the hsize as well) + +\def\dostartfonteffect#1#2#3% + {\ifdim#2>\zeropoint + \PointsToBigPoints{#2}\ascii + \PDFcode{\ascii\space w}% + \fi + \ifdim#3\points=\onepoint\else + \scratchdimen#3\points + \PDFcode{\withoutpt{\the\scratchdimen}\space Tc}% + \fi + \PDFcode{\purenumber#1 Tr}} + +\def\dostopfonteffect + {\PDFcode{1 w 0 Tc 0 Tr}} + +%D Handy for the \METAPOST\ to \PDF\ converter: + +\appendtoksonce + \collectPDFresources + \global\let\currentPDFresources\collectedPDFresources +\to \everyPDFxform + +\let\collectedPDFresources\empty + +\def\collectPDFresources % suboptimal + {\doifobjectreferencefoundelse{FDF}{docushades} % redundant, we have an reserved object now + {\doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference + \xdef\collectedPDFresources{\collectedPDFresources/Shading \PDFobjectreference}}\donothing + \doifobjectreferencefoundelse{FDF}{docuextgstates} + {\doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference + \xdef\collectedPDFresources{\collectedPDFresources/ExtGState \PDFobjectreference}}\donothing + \doifobjectreferencefoundelse{FDF}{colorspaces} + {\doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference + \xdef\collectedPDFresources{\collectedPDFresources/ColorSpace \PDFobjectreference}}\donothing + \global\let\collectPDFresources\relax} + +\appendtoks + \flushPDFpagelayers + \flushJSpreamble + \flushJSpreamble + \checkPDFextgstates + \checkPDFcolorspaces + \checkPDFshades + \checkPDFpageactions + \fakePDFpagedestination + \flushPDFpageboxes + \addPDFdocumentinfo +\to \everybackendshipout + +\appendtoks + \flushPDFtextlayers + \finalflushJSpreamble +\to \everylastbackendshipout + +%D Temporary hack: + +\def\TransparencyHack % png: /CS /DeviceRGB /I true + {\appendtoksonce + \appendtopdfpageattributes{/Group << /S /Transparency /I true /K true>>}% + \to \everyPDFxform + \appendtoksonce + \appendtopdfpageattributes{/Group << /S /Transparency /I true /K true>>}% + \to \everyshipout} + +\protect \endinput diff --git a/tex/context/base/back-pdf.tex b/tex/context/base/back-pdf.tex deleted file mode 100644 index b7de1051f..000000000 --- a/tex/context/base/back-pdf.tex +++ /dev/null @@ -1,3226 +0,0 @@ -%D \module -%D [ file=back-pdf, -%D version=2009.04.15, -%D title=\CONTEXT\ Backend Macros, -%D subtitle=\PDF, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Backend Macros / PDF} - -\registerctxluafile{back-pdf}{1.001} - -\unprotect - -%D When dealing with resources, we share the resource dictionaries -%D between all xforms. This is inefficent in the sense that when no -%D resources are used, redundant entries take space, but on the other -%D hand we save redundant dictionaries so it's a nice compromise. Maybe -%D that in \LUATEX\ I will reimplement most of the code here anyway. - -%D Initialization of fields is tricky. If a field has no -%D value, it is kind of not there. If ResetForm is used, the -%D default is assigned, but pushbuttons are spoiled. Adding a -%D \type {/MK} dictionary helps, but gives ugly down -%D appearances (displaced with background). What a mess. -%D Also, in order to get at least something, the \type {/AS} -%D key should be provided. - -%D A couple of variables: - -\newtoks \everybackendshipout -\newtoks \everylastbackendshipout - -\let\lastPDFaction\empty - -\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi -\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi -\ifdefined\everygoto \else \newtoks\everygoto \fi -\ifdefined\everysetfield \else \newtoks\everysetfield \fi - -%D A few helpers: - -\let\PDFcode \pdfliteral -\def\PDFcontentcode{\pdfliteral} -\def\PDFdirectcode {\pdfliteral direct} - -%D \macros -%D {PDFobjref} -%D -%D Just a shortcut. - -% Watch out, \def\PDFobjref#1{\purenumber#1 0 R} also works, but not when -% #1 == \the\whatever - -\def\PDFobjref#1{\purenumber{#1} 0 R} - -%D \macros -%D {PDFswapdir} - -\let\PDFswapdir\empty \def\PDFswapdir{\ifcase\inlinedirection\or\or-\fi} - -% the pdf spec changed cq. viewers started behaving differently / 5+ - -\chardef\overcomePDFpage\plusone % page numbers/ beware: optimizers remove this one -\chardef\overcomePDFpage\plustwo % page:number -\chardef\overcomePDFpage\plusthree % pdftex page ref feature - -%D \macros -%D {setPDFdestination} -%D -%D \PDF\ destinations should obey the specifications laid down -%D in the \PDF\ reference manual. The next macro strips illegal -%D characters from the destination name. - -\def\setPDFdestination #1{\xdef\PDFdestination{\ctxlua{pdf.cleandestination("\luaescapestring{#1}")}}} -\def\hexifiedPDFstring #1{\ctxlua{pdf.hexify("\luaescapestring{#1}")}} -\def\sanitizePDFencoding#1\to#2{\xdef#2{\ctxlua{pdf.hexify("\luaescapestring{#1}")}}} - -%D - -\def\appendtopdfpageresources #1{\normalexpanded{\global\pdfpageresources{#1\the\pdfpageresources}}} -\def\appendtopdfpageattributes #1{\normalexpanded{\global\pdfpageattr {#1\the\pdfpageattr }}} -\def\appendtopdfpagesattributes#1{\normalexpanded{\global\pdfpagesattr {#1\the\pdfpagesattr }}} -\def\appendtopdfcatalog {\pdfcatalog} -\def\appendtopdfinfo {\pdfinfo} - -\def\resetpdfpageattributes{\global\pdfpageattr\emptytoks} -\def\resetpdfpageresources {\global\pdfpageresources\emptytoks} - -%D Due to the fact that \PDFTEX\ has a different concept of -%D page attributes, we need: - -\appendtoksonce - \resetpdfpageattributes - \resetpdfpageresources -\to \everyaftershipout - -%D \macros -%D {insertpdfaction, -%D insertpdfannotation, -%D insertpdfannotationobject, -%D createpdfdictionaryobject, -%D createpdfarrayobject, -%D defaultobjectreference, -%D doPDFgetobjectreference} -%D -%D This module deals with \PDF\ support, including fill||in -%D forms. Before we present the largely unreadable bunch of -%D macros, we introduce the here||not||defined low level -%D interface macros. These must be provided by the special -%D drivers \type{pdf} (\ACROBAT) and \type{tpd} (\PDFTEX). -%D -%D \starttyping -%D \insertpdfaction #1#2#3 width height action -%D \insertpdfannotation #1#2#3 width height data -%D \createpdfannotationobject #1#2#3#4#5 class name width height data -%D \createpdfdictionaryobject #1#2#3 class name data -%D \createpdfarrayobject #1#2#3 class name data -%D -%D \defaultobjectreference #1#2 class name -%D \doPDFgetobjectreference #1#2#3 class name \PDFobjectreference -%D \doPDFgetobjectpagereference #1#2#3 class name \PDFobjectreference -%D \stoptyping -%D -%D The keywords reflect their use. For the moment we stick to -%D keywords, because that way at we get an indication of what -%D we're doing. - -\def\createpdfdictionaryobject#1#2#3% - {\flushatshipout - {\immediate\pdfobj{<< #3 >>}% - \dosetobjectreference{#1}{#2}{\the\pdflastobj}}} - -\def\createpdfarrayobject#1#2#3% - {\flushatshipout - {\immediate\pdfobj{[ #3 ]}% - \dosetobjectreference{#1}{#2}{\the\pdflastobj}}} - -\def\createpdfannotationobject#1#2#3#4#5% - {\insertpdfannotation{#3}{#4}{#5}% - \dosetobjectreference{#1}{#2}{\the\pdflastannot}} - -\def\createpdfactionobject#1#2#3#4#5% - {\insertpdfaction{#3}{#4}{#5}% - \dosetobjectreference{#1}{#2}{\the\pdflastannot}} - -%D \macros -%D {insertpdfaction,insertpdfannotation,ifsharePDFactions} -%D -%D Next we handle annotations. All link annotations are -%D implemented using the action dictionary. This enables us to -%D use multiple actions. The second macro is for instance -%D used for movie inclusion. - -\newif\ifsharePDFactions \sharePDFactionstrue - -\def\insertpdfaction#1#2#3% - {\xdef\lastPDFcontent{#3}% - \ifcollectreferenceactions - \global\let\lastPDFaction\lastPDFcontent - \else - \ifsharePDFactions - \ifcase\similarreference\relax - \xdef\lastPDFaction{<<\lastPDFcontent>>}% - \or - \immediate\pdfobj{<<\lastPDFcontent>>}% - \xdef\lastPDFaction{\PDFobjref\pdflastobj}% - \else - % leave \lastPDFaction untouched - \fi - \else - \xdef\lastPDFaction{<<\lastPDFcontent>>}% - \fi - \pdfannot - width #1 height #2 depth \zeropoint - {/Subtype /Link - /Border [0 0 0] - \ifhighlighthyperlinks \else /H /N \fi - /A \lastPDFaction}% - \fi} - -\def\insertpdfannotation#1#2#3% - {\pdfannot width #1 height #2 depth \zeropoint{#3}} - -%D \macros -%D {doPDFbookmark} -%D -%D Well, isn't the next one ugly? Thanks to the \PDF\ -%D standard. - -\def\doPDFbookmark#1#2#3#4#5% to be renamed - {\doPDFgetpagereference{#4}\PDFobjectreference - \pdfoutline - user {<>}% - \ifcase#2 \else count \ifcase#5-\fi#2 \fi - {#3}} - -%D For special (\METAPOST) effects, we need to build -%D resource dictionaries. Here is the framework. - -\let\docuPDFextgstates \empty -\let\docuPDFcolorspaces\empty -\let\docuPDFshades \empty - -\def\checkPDFextgstates - {\ifx\docuPDFextgstates\empty \else - \ifnum\realpageno=\lastpage\relax - \createpdfdictionaryobject{FDF}{docuextgstates}{\docuPDFextgstates}% - \fi - \doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference - \appendtopdfpageresources{/ExtGState \PDFobjectreference}% - \fi} - -\def\checkPDFcolorspaces - {\ifx\docuPDFcolorspaces\empty \else - \ifnum\realpageno=\lastpage\relax - \createpdfdictionaryobject{FDF}{colorspaces}{\docuPDFcolorspaces}% - \fi - \doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference - \appendtopdfpageresources{/ColorSpace \PDFobjectreference}% - \fi} - -\def\checkPDFshades - {\ifx\docuPDFshades\empty \else - \ifnum\realpageno=\lastpage\relax - \createpdfdictionaryobject{FDF}{docushades}{\docuPDFshades}% - \fi - \doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference - \appendtopdfpageresources{/Shading \PDFobjectreference}% - \fi} - -\def\appendtoPDFdocumentextgstates #1{\xdef\docuPDFextgstates {\docuPDFextgstates \space#1}} -\def\appendtoPDFdocumentcolorspaces#1{\xdef\docuPDFcolorspaces{\docuPDFcolorspaces\space#1}} -\def\appendtoPDFdocumentshades #1{\xdef\docuPDFshades {\docuPDFshades \space#1}} - -%D Page actions: - -\let\lastpdfopenaction \empty -\let\lastpdfcloseaction\empty - -\def\dosetupopenaction {\appendtopdfcatalog{/OpenAction <<\lastPDFaction>>}} -\def\dosetupcloseaction{\appendtopdfcatalog{/CloseAction <<\lastPDFaction>>}} - -\def\dosetupopenpageaction {\glet\lastpdfopenaction \lastPDFaction} -\def\dosetupclosepageaction{\glet\lastpdfcloseaction\lastPDFaction} - -\def\checkPDFpageactions - {\iflocation % important since direct - \donefalse - \ifx\lastpdfopenaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi - \ifx\lastpdfcloseaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi - \ifdone - \appendtopdfpageattributes - {/AA <<\if!!donea/O <<\lastpdfopenaction >> \fi - \if!!doneb/C <<\lastpdfcloseaction>> \fi>>}% - \fi - \glet\lastpdfopenaction \empty - \glet\lastpdfcloseaction\empty - \fi} - -%D \macros -%D {ifPDFstrokecolor} -%D -%D We can reduce the filesize a bit by setting the next switch -%D to false. The amount of reduction depends on the use of -%D color, but don't expect more than a few percent. Zip -%D compression is already rather efficient in itself. - -\newif\ifPDFstrokecolor \PDFstrokecolortrue - -%D When submitting forms, we need to communicate the format. - -\chardef\submitoutputformat=0 % 0=unknown 1=HTML 2=FDF 3=XML - -\def\setsubmitoutputformat#1% - {\doifinsetelse{#1}{FDF,fdf} - {\chardef\submitoutputformat2} - {\doifinsetelse{#1}{XML,xml} - {\chardef\submitoutputformat3} - {\chardef\submitoutputformat1}}% - \relax} - -%D Handy to have this available asap: - -\ifdefined\everyPDFxform \newtoks\everyPDFxform \fi -\ifdefined\everyPDFximage \newtoks\everyPDFximage \fi - -% once we can be sure that the latest versions of pdftex are -% available we can use: -% -% \pdfobj reserveobjnum \edef\one{\the\pdflastobj} -% \pdfobj reserveobjnum \edef\two{\the\pdflastobj} -% -% \pdfobj useobjnum \one {x} -% \pdfobj useobjnum \two {x} -% -% we then can rewrite part of spec-fdf because the other drivers -% already support symbolic references - -%D \macros -%D {jobsuffix} -%D -%D Being one of the first typographical systems able to support -%D advances \PDF\ support, \TEX\ is also one of the first -%D systems to produce high quality \PDF\ code directly. Thanks -%D to Han The Thanh c.s. the \TEX\ community can leap forward -%D once again. -%D -%D One important characteristic of \PDFTEX\ is that is can -%D produce standard \DVI\ code as well as \PDF\ code. This -%D enables us to use one format file to support both output -%D formats. - -%D All modules in this group use specials to tell drivers what -%D non||\TEX\ actions to take. Because from the \TEX\ point of -%D view, there is no difference between \DVI\ and \PDF, we -%D therefore only have to bend the \DVI\ driver support into -%D \PDF\ support. Technically spoken, specials no longer serve -%D a purpose, except from ending up as comment in the \PDF\ -%D file. -%D -%D Before we continue we need to make sure if indeed those -%D \PDFTEX\ primitives are permitted. If no primitives are -%D available, we just stop reading any further. - -\pdfoutput = 1 -\pdfhorigin = 1 true in -\pdfvorigin = 1 true in -\pdfimageresolution = 300 -\pdfpkresolution = 600 -\pdfdecimaldigits = 10 -\pdfinclusionerrorlevel = 0 -\pdfminorversion = 5 -%pdfuniqueresname = 1 - -\def\PDFversion{1.\number\pdfminorversion} - -%D For some internal testing we need to know the output -%D suffix. - -\setjobsuffix{pdf} - -%D \macros -%D {dosetuppaper} -%D -%D If we don't set the paper size, \PDFTEX\ will certainly do -%D it in a way we don't want, therefore we need: - -\def\dosetuppaper#1#2#3% - {\global\pdfpagewidth #2\relax - \global\pdfpageheight#3\relax} - -%D \macros -%D {doloadmapfile,doloadmapline,doresetmapfilelist} - -\def\doresetmapfilelist - {\global\let\doresetmapfilelist\relax - \pdfmapfile{original-empty.map}} - -\def\doloadmapfile #1#2{\pdfmapfile{#1#2}} -\def\doloadmapline #1#2{\pdfmapline{#1#2}} - -%D nasty but needed - -\appendtoksonce \loadallfontmapfiles \to \everyPDFximage -\appendtoksonce \loadallfontmapfiles \to \everyPDFxform - -%D left overs: - - \let\currentmovie\s!unknown - - \def\doPDFinsertmov - {\bgroup - \xdef\currentmovie{\@@DriverImageLabel}% - \PointsToBigPoints\@@DriverImageWidth \width - \PointsToBigPoints\@@DriverImageHeight\height - \let\pdf@@options\empty - \let\pdf@@actions\empty - \donefalse - \expanded{\processallactionsinset[\@@DriverImageOptions]} - [\v!controls=>\donetrue, - \v!repeat=>\edef\pdf@@actions{\pdf@@actions /Mode /Repeat }, - \v!preview=>\edef\pdf@@options{\pdf@@options /Poster true }]% - \edef\pdf@@actions{\pdf@@actions /ShowControls \ifdone true\else false\fi}% - \insertpdfannotation\@@DriverImageWidth\@@DriverImageHeight - {/Subtype /Movie - /Border [0 0 0] - /T (movie \currentmovie) - /Movie << /F (\@@DriverImageFile) /Aspect [\width\space\height] \pdf@@options >> - /A << \pdf@@actions >>}% - \egroup} - -%D \macros -%D {doinsertsoundtrack} -%D -%D We use numbers instead of labels to keep track of sounds. - -\let\currentsound\s!unknown - -\def\doinsertsoundtrack#1#2#3% - {\bgroup - \xdef\currentsound{#2}% - \let\pdf@@actions\empty - \@EA\processallactionsinset\@EA - [#3] - [\v!repeat=>\edef\pdf@@actions{\pdf@@actions /Mode /Repeat }]% - \collectdriverresource - %\flushatshipout % since it can be buried in a chained box - {\insertpdfannotation{0pt}{0pt} - {/Subtype /Movie - /Border [0 0 0] - /T (sound \currentsound) - /Movie <>% - \ifx\pdf@@actions\empty\else/A << \pdf@@actions >>\fi}}% - \egroup} - -%D \macros -%D {doPDFattachfile} - -\def\doPDFfilestreamobject#1#2#3#4% - {} - -\def\doPDFfilestreamidentifier#1% - {0} - -\def\doPDFgetfilestreamreference#1#2% - {0 0 R} - -\def\doattachfile#1#2#3#4#5#6#7#8% - {\bgroup % title width height color symbol file - \edefconvertedargument\PDFfile{#8}% - % beware: the symbol may (indirectly) use the file - % reference when typesetting the object number; - \presetPDFsymbolappearance{#5}{#6}{#2}{#3}{#4}% sets width/height - \startPDFsymbolappearance - \doPDFembedfile\PDFfile{#7}{#8}% - \doPDFgetembeddedfilereference\PDFfile\PDFobjectreference - \setFDFlayer\@@DriverAttachmentLayer - \insertpdfannotation{\width}{\totalheight} - {/Subtype /FileAttachment - /FS \PDFobjectreference\space - /Contents (#1) - \PDFsymbol - \FDFlayer - \PDFattributes}% - \stopPDFsymbolappearance - \egroup} - -% semi-public - -\def\doPDFembedfile#1#2#3% symbolic name | filename | user name - {\edefconvertedargument\PDFfile{#1}% - \doifnotflagged{a:\PDFfile}% - {\doPDFfilestreamobject{PDFEF}{\PDFfile}{#2}{#3}% - \doglobal\setflag{a:\PDFfile}}} - -\def\doPDFgetembeddedfilereference#1#2% - {\edefconvertedargument\PDFfile{#1}% - \doPDFgetobjectreference{PDFEF}\PDFfile#2} - -\def\doPDFgetembeddedfilestreamreference#1#2% - {\edefconvertedargument\PDFfile{#1}% - \doPDFgetfilestreamreference\PDFfile#2} % == \doPDFgetobjectreference{PDFFS}\PDFfile#2 - -% requested by Jens-Uwe Morawski: permits usage of pdftosrc -% in viewers that don't support attachments: -% -% \definesymbol -% [ObjectNumber] -% % [object number {\PDFattachmentnumber[xx]}] % named -% [object number \PDFattachmentnumber] % current -% -% \useattachment[test][xx][test.tex] -% \setupattachments[symbol=ObjectNumber] -% \attachment[test] - -\def\PDFattachmentnumber - {\dosingleargument\doPDFattachmentnumber} - -\def\doPDFattachmentnumber[#1]% - {\iffirstargument - \doPDFfilestreamidentifier{#1}% - \else - \doPDFfilestreamidentifier\PDFfile - \fi} - -%D \macros -%D {...} -%D -%D Rather preliminary. We have to wait till the complete specs -%D show up. As usual, we cannot really check it (Acrobat 6.0 -%D has a bug that inhibits us to make a test file). Half a day -%D of testing made clear that trying to control the plugin fails -%D in most cases (we need plugin specs -). We also miss a feature -%D to let acrobat wait with proceeding (action processing) till -%D the media clip is ready. - -% aiff audio/aiff -% au audio/basic -% avi video/avi -% mid audio/midi -% mov video/quicktime -% mp3 audio/x-mp3 (mpeg) -% mp4 audio/mp4 -% mp4 video/mp4 -% mpeg video/mpeg -% smil application/smil -% swf application/x-shockwave-flash - -% beware, this is preliminary code, should be improved - -\def\PDFrenderingspecs#1{\executeifdefined{PDFMR:#1}\empty} - -\def\PDFexecutestartrendering {/Rendition /OP 0 \PDFrenderingspecs\argumentA} -\def\PDFexecutestoprendering {/Rendition /OP 1 \PDFrenderingspecs\argumentA} -\def\PDFexecutepauserendering {/Rendition /OP 2 \PDFrenderingspecs\argumentA} -\def\PDFexecuteresumerendering {/Rendition /OP 3 \PDFrenderingspecs\argumentA} - -% todo : sub files -% -% \doPDFembedfile{pier-39.png}{pier-39.png}{pier-39.png}% -% \doPDFgetembeddedfilestreamreference{pier-39.png}\xPDFobjectreference -% \edef\xxxx{/RF [(pier-39.png) \xPDFobjectreference]}% - -% todo: alternative renderings -% -% object_1 -> <> >> -% object_2 -> <> >> -% rendering -> <> - -\def\doinsertrendering#1#2#3#4% tag mime file options - {\ifundefined{PDFMR:#1}% - \doifinstringelse{://}{#3}\donetrue\donefalse % evt url as keyword - \createpdfdictionaryobject{PDFMF}{#1} - {/Type /Rendition - /S /MR - % does not work: /SP << /Type /MediaScreenParam /BE << /B [1 0 0] /O 0.5 >> >> - /C << /Type /MediaClip - /S /MCD - /N (#1) - /Alt [() (file not found)] % language id + message - /D << /Type /Filespec - /F (#3) - \ifdone/FS /URL\fi >> - /CT (#2) >>}% - % common code - \doifobjectreferencefoundelse{PDFMS}{#1} - {\doPDFgetobjectreference{PDFMS}{#1}\PDFobjectreferenceB} - {\doPDFgetobjectreference{PDFMU}{#1}\PDFobjectreferenceB}% - \doPDFgetobjectreference{PDFMF}{#1}\PDFobjectreferenceA - \setxvalue{PDFMR:#1}% needed /AA actions in /Screen - {/R \PDFobjectreferenceA - /AN \PDFobjectreferenceB}% - \doifobjectreferencefoundelse{PDFMS}{#1}\donothing - {\dodoinsertrenderingwindow{PDFMU}{#1}\zeropoint\zeropoint{#4}}% - \fi} - -\def\doinsertrenderingobject#1#2#3#4% tag class objectname options - {\ifundefined{PDFMR:#1}% - \doPDFgetobjectreference{#2}{#3}\PDFobjectreference - \createpdfdictionaryobject{PDFMF}{#1} - {/Type /Rendition - /S /MR - /C << /Type /MediaClip - /S /MCD - /N (#1) - /D \PDFobjectreference>>}% - % common code - \doifobjectreferencefoundelse{PDFMS}{#1} - {\doPDFgetobjectreference{PDFMS}{#1}\PDFobjectreferenceB} - {\doPDFgetobjectreference{PDFMU}{#1}\PDFobjectreferenceB}% - \doPDFgetobjectreference{PDFMF}{#1}\PDFobjectreferenceA - \setxvalue{PDFMR:#1}% needed /AA actions in /Screen - {/R \PDFobjectreferenceA - /AN \PDFobjectreferenceB}% - \doifobjectreferencefoundelse{PDFMS}{#1}\donothing - {\dodoinsertrenderingwindow{PDFMU}{#1}\zeropoint\zeropoint{#4}}% - \fi} - -\def\doinsertrenderingwindow - {\dodoinsertrenderingwindow{PDFMS}} - -\def\dodoinsertrenderingwindow#1#2#3#4#5% - {\vbox to #4 \bgroup - \checkPDFscreenactions{#2}{#5}% - \doPDFgetobjectpagereference{PDFMF}{#2}\PDFobjectreferenceA - \doPDFgetobjectreference {PDFMF}{#2}\PDFobjectreferenceB - \vss - \hbox to #3 \bgroup - \createpdfannotationobject{#1}{#2}{#3}{#4} - {/Subtype /Screen - /P \PDFobjectreferenceA - /A \PDFobjectreferenceB - \PDFattributes - /Border [0 0 0]}% - \hss - \egroup - \egroup} - -\global\let\PDFrenderingopenpageaction \empty -\global\let\PDFrenderingclosepageaction\empty - -\def\checkPDFscreenactions#1#2% - {\let\PDFattributes\empty - \iflocation % important since direct -) - % the action can either (already) be set by the window handler - % or (normally when no window [i.e a zero dimensions one] is present) by keyword - \doifinset\v!auto{#2} - {% brrr, here instead of in navigation module, must move and become special - % now two sided dependency - \let\checkrendering\gobbleoneargument - \ifx\PDFrenderingopenpageaction \empty - \handlereferenceactions{\v!StartRendering{#1}}\dosetuprenderingopenpageaction - \fi - \ifx\PDFrenderingclosepageaction\empty - \handlereferenceactions{\v!StopRendering {#1}}\dosetuprenderingclosepageaction - \fi - }% - \donefalse - \ifx\PDFrenderingopenpageaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi - \ifx\PDFrenderingclosepageaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi - \ifdone - \edef\PDFattributes - {/AA <<\if!!donea/PO <<\PDFrenderingopenpageaction >> \fi - \if!!doneb/PC <<\PDFrenderingclosepageaction>> \fi>>}% - \fi - \global\let\PDFrenderingopenpageaction \empty - \global\let\PDFrenderingclosepageaction\empty - \fi} - -\def\dosetuprenderingopenpageaction {\global\let\PDFrenderingopenpageaction \lastPDFaction} -\def\dosetuprenderingclosepageaction{\global\let\PDFrenderingclosepageaction\lastPDFaction} - -%D For the moment we don't test for alternatives that -%D themselves have alternatives, especially cylcic -%D dependencies. - -% \def\pdfimmediateximage{\immediate\pdfximage} -% -% \def\checkpdfimageattributes -% {\ifx\PDFfigurereference\empty -% \global\let\pdfimageattributes\empty -% \else -% \immediate\pdfobj -% {[ << /Image \PDFobjref\PDFfigurereference -% /DefaultForPrinting true >> ]}% -% \xdef\pdfimageattributes -% {attr {/Alternates \PDFobjref\pdflastobj}}% -% \fi} -% -% \global\let\PDFimagecolorreference\empty -% -% \def\checkpdfimagecolorspecs -% {\ifx\pdflastximagecolordepth \undefined -% \global\let\pdfimagecolorspecs\empty -% \else\ifx\PDFimagecolorreference\empty -% \global\let\pdfimagecolorspecs\empty -% \else -% \xdef\pdfimagecolorspecs{colorspace \PDFimagecolorreference\space}% -% \fi\fi -% \global\let\PDFimagecolorreference\empty} - -%D \macros -%D {doregisterfigure} -%D -%D Here is the fuzzy, very special dependant figure -%D registration special. We need to refer to the innermost -%D object (ximage). - - \def\doregisterfigure#1#2% - {\doifundefined{IM::#1::#2} - {\setxvalue{IM::#1::#2}{\the\pdflastximage}}% - \xdef\PDFfigurereference{\getvalue{IM::#1::#2}}} - -%D \macros -%D {doovalbox} -%D -%D Drawing frames with round corners is inherited from the -%D main module. -%D -%D For drawing ovals we use quite raw \PDF\ code. The next -%D implementation does not differ that much from the one -%D implemented in the \POSTSCRIPT\ driver. - -\def\doPDFovalcalc#1#2#3% - {\PointsToBigPoints{\dimexpr#1+#2\relax}#3} - -\def\doovalbox#1#2#3#4#5#6#7#8% todo: \scratchdimen/\scatchbox - {\forcecolorhack - \bgroup - \dimen0=#4\divide\dimen0 \plustwo - \doPDFovalcalc{0pt}{+\dimen0}\xmin - \doPDFovalcalc{#1}{-\dimen0}\xmax - \doPDFovalcalc{#2}{-\dimen0}\ymax - \doPDFovalcalc{-#3}{+\dimen0}\ymin - \advance\dimen0 by #5% - \doPDFovalcalc{0pt}{+\dimen0}\xxmin - \doPDFovalcalc{#1}{-\dimen0}\xxmax - \doPDFovalcalc{#2}{-\dimen0}\yymax - \doPDFovalcalc{-#3}{+\dimen0}\yymin - \doPDFovalcalc{#4}{\zeropoint}\stroke - \doPDFovalcalc{#5}{\zeropoint}\radius - \edef\dostroke{#6}% - \edef\dofill{#7}% - \edef\mode{\number#8 \space}% - % no \ifcase, else \relax in pdfcode - \setbox\scratchbox\hbox - {\ifnum\dostroke\dofill>\zerocount - \ifPDFstrokecolor\else\ifnum\dostroke=\plusone - \writestatus\m!colors{pdf stroke color will fail}\wait - \fi\fi - \PDFcode - {q - \stroke\space w - \ifcase\mode - \xxmin\space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or % 1 - \xxmin\space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \ymax \space l - \xmin \space \ymax \space l - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or % 2 - \xxmin\space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \ymax \space l - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or % 3 - \xmin \space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \ymin \space l - h - \or % 4 - \xmin \space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xmin \space \ymax \space l - \xmin \space \ymin\space l - h - \or % 5 - \xmin \space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xmin \space \ymax \space l - \xmin \space \ymin \space l - h - \or % 6 - \xmin \space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \ymax \space l - \xmin \space \ymax \space l - \xmin \space \ymin \space l - h - \or - \xxmin\space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \ymax \space l - \xmin \space \ymax \space l - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or - \xmin \space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \ymax \space l - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \ymin \space l - h - \or % 9 top open - \xmin \space \ymax \space m - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \ymax \space l - \or % 10 right open - \xmax \space \ymax \space m - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - \xmax\space \ymin \space l - \or % 11 bottom open - \xmax \space \ymin \space m - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax \space \ymax\space y - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \ymin \space l - \or % 12 left open - \xmin \space \ymax \space m - \xxmax\space \ymax \space l - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax \space \yymin\space l - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xmin \space \ymin \space l - \or % 13 - \xmin \space \ymax \space m - \xxmax\space \ymax \space l - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax\space \ymin \space l - \or % 14 - \xmax \space \ymax \space m - \xmax \space \yymin\space l - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xmin \space \ymin \space l - \or % 15 - \xmax \space \ymin \space m - \xxmin\space \ymin \space l - \xmin \space \ymin \space \xmin \space \yymin\space y - \xmin \space \ymax \space l - \or % 16 - \xmin \space \ymin \space m - \xmin \space \yymax\space l - \xmin \space \ymax \space \xxmin\space \ymax \space y - \xmax \space \ymax \space l - \or % 17 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \or % 18 - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \or % 19 - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \or % 20 - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 21 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 22 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \or % 23 - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \or % 24 - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 25 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 26 - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 27 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \or % 28 - \fi - \ifnum\mode>8 - S - \else - \ifnum\dostroke=\plusone S \fi - \ifnum\dofill =\plusone f \fi - \fi - Q}% - \fi}% - \wd\scratchbox#1\ht\scratchbox#2\dp\scratchbox#3\box\scratchbox - \egroup} - -%D \macros -%D {dostartgraymode,dostopgraymode, -%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode, -%D dostopcolormode, -%D dostartrotation,dostoprotation, -%D dostartscaling,dostopscaling, -%D dostartmirroring,dostopmirroring, -%D dostartnegative,dostopnegative, -%D dostartoverprint,dostopoverprint} - -\def\dostartrotation#1% grouped - {\setcalculatedcos\cos{#1}% - \setcalculatedsin\sin{#1}% - \forcecolorhack - \PDFcode{q \cos\space\sin\space\negated\sin\space\cos\space0 0 cm}} - -\def\dostoprotation - {\PDFcode{Q}} - -\def\@@PDFzeroscale{.0001} - -\def\dostartscaling#1#2% the test is needed because acrobat is bugged! - {\forcecolorhack - \PDFcode{q \ifdim#1\points=\zeropoint\@@PDFzeroscale\else#1\fi\space 0 0 - \ifdim#2\points=\zeropoint\@@PDFzeroscale\else#2\fi\space 0 0 cm}} - -\def\dostopscaling - {\PDFcode{Q}} - -\def\dostartmirroring{\PDFcode{-1 0 0 1 0 0 cm}} -\def\dostopmirroring {\PDFcode{-1 0 0 1 0 0 cm}} - -\def\dostartnegative {\ifdefined\initializePDFnegative \initializePDFnegative \PDFcode{/GSnegative gs}\fi} -\def\dostopnegative {\ifdefined\initializePDFnegative \initializePDFnegative \PDFcode{/GSpositive gs}\fi} -\def\dostartoverprint{\ifdefined\initializePDFoverprint\initializePDFoverprint\PDFcode{/GSoverprint gs}\fi} -\def\dostopoverprint {\ifdefined\initializePDFoverprint\initializePDFoverprint\PDFcode{/GSknockout gs}\fi} % wrong - -%D \macros -%D {doPDFstartgraymode,doPDFstopgraymode, -%D doPDFstartrgbcolormode,doPDFstartcmykcolormode,doPDFstartgraycolormode, -%D doPDFstopcolormode} -%D -%D In \PDF\ there are two color states, one for strokes and one -%D for fills. This means that we have to set the color in a -%D rather redundant looking way. Unfortunately this makes the -%D \PDF\ file much larger than needed. We can save few bytes -%D by not setting the stroke color. Due to zip compression we -%D only save a few percent. - -\def\dostartgraymode #1{\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} -\def\dostopgraymode {\PDFcode{0 g\ifPDFstrokecolor\space 0 G\fi}} -\def\dostartrgbcolormode #1#2#3{\PDFcode{#1 #2 #3 rg\ifPDFstrokecolor\space#1 #2 #3 RG\fi}} -\def\dostartcmykcolormode#1#2#3#4{\PDFcode{#1 #2 #3 #4 k\ifPDFstrokecolor\space#1 #2 #3 #4 K\fi}} -\def\dostartgraycolormode #1{\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} -\def\dostopcolormode {\PDFcode{0 g\ifPDFstrokecolor\space0 G\fi}} - -\def\dostartspotcolormode#1#2% redefining spotcolors is not possible anyway - {\ifundefined{pdf:scs:#2}% - \bgroup - \getcommacommandsize[#2]% - \ifcase\commalistsize\or - \setxvalue{pdf:scs:#2}{#2 SCN #2 scn}% \setxvalue{pdf:scs:#2}{#2 SC #2 sc}% - \else - \let\PDFspotcolorspecs\empty - \def\dospotcolorcommand##1{\edef\PDFspotcolorspecs{\PDFspotcolorspecs##1\space}}% - \processcommacommand[#2]\dospotcolorcommand - \setxvalue{pdf:scs:#2}{\PDFspotcolorspecs SCN \PDFspotcolorspecs scn}% - \fi - \egroup - \fi - \PDFcode{/#1 cs /#1 CS \PDFgetspotcolorspec{#2}}} - -\def\PDFgetspotcolorspec#1% - {\executeifdefined{pdf:scs:#1}\empty} % better no default than one with too less args - -\def\dostartnonecolormode - {\PDFcode{/None CS 1 SC /None cs 1 sc}} - -%D We need to register the spot colors and their fallbacks. - -% we cannot use /DeviceN since GS <=7.21 breaks on it -% and Jaws does not handle it at all {[/DeviceN [/All|/None] -% /Device#2 \PDFobjref\pdflastobj]} so we use separation -% colors that work and print ok - -\def\doPDFregistersomespotcolor#1#2#3#4% implemented in the driver - {\writestatus\m!systems{missing spot color definition}\wait} - -\def\doregisternonecolor % internal command - {\doregistergrayspotcolor{None}{1}% - \globallet\doregisternonecolor\relax} - -\def\dodoPDFregisterrgbspotcolor#1#2#3#4#5#6#7% name noffractions names p's r g b - {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{RGB}{0.0 1.0 0.0 1.0 0.0 1.0}% - {\ifcase#2\or dup #5 mul exch dup #6 mul exch #7 mul\else#5 #6 #7\fi}} - -\def\dodoPDFregistercmykspotcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k - {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{CMYK}{0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0}% - {\ifcase#2\or dup #5 mul exch dup #6 mul exch dup #7 mul exch #8 mul\else #5 #6 #7 #8\fi}} - -\def\dodoPDFregistergrayspotcolor#1#2#3#4#5% name noffractions names p's s - {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}% - {\ifcase#2\or #5 mul\else #5\fi}} - -\def\doregisterrgbspotcolor#1#2#3#4#5#6#7% name noffractions names p's r g b - {\ifRGBsupported - \dodoPDFregisterrgbspotcolor{#1}{#2}{#3}{#4}{#5}{#6}{#7}% - \else - \edef\@@cl@@r{#5}\edef\@@cl@@g{#6}\edef\@@cl@@b{#7}% - \ifCMYKsupported - \convertRGBtoCMYK\@@cl@@r\@@cl@@g\@@cl@@b - \dodoPDFregistercmykspotcolor{#1}{#2}{#3}{#4}\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k - \else - \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b - \dodoPDFregistergrayspotcolor{#1}{#2}{#3}{#4}\@@cl@@s - \fi - \fi} - -\def\doregistercmykspotcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k - {\ifCMYKsupported - \dodoPDFregistercmykspotcolor{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% - \else - \edef\@@cl@@c{#5}\edef\@@cl@@m{#6}\edef\@@cl@@y{#7}\edef\@@cl@@k{#8}% - \ifRGBsupported - \convertCMYKtoRGB\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k - \dodoPDFregisterrgbspotcolor{#1}{#2}{#3}{#4}\@@cl@@r\@@cl@@g\@@cl@@b - \else - \convertCMYKtoGRAY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k - \dodoPDFregistergrayspotcolor{#1}{#2}{#3}{#4}\@@cl@@s - \fi - \fi} - -\def\doregistergrayspotcolor{\dodoPDFregistergrayspotcolor} - -%D New and very experimental. - -\def\doregistercmykindexcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k - {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{CMYK}{0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0}% - {dup #5 mul exch dup #6 mul exch dup #7 mul exch #8 mul}} - -\def\doregisterrgbindexcolor#1#2#3#4#5#6#7% name noffractions names p's r g b - {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{RGB}{0.0 1.0 0.0 1.0 0.0 1.0}% - {dup #5 mul exch dup #6 mul exch #7 mul}} - -\def\doregistergrayindexcolor#1#2#3#4#5% name noffractions names p's s - {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}% - {pop}} - -\let\checkpredefinedcolor\predefineindexcolor % we need an index in order to negate bitmaps - -\def\doregisterfigurecolor#1% always an index color - {\dogetobjectreference{PDFIX}{\internalspotcolorname{#1}}\PDFimagecolorreference} - -\def\doregisterspotcolorname#1#2% no need for escape in luatex - {\bgroup - \let\ascii\empty - \def\docommand##1% - {\edef\ascii{\ascii - \ifx\nexthandledtoken\space - \letterhash20% - \else\ifx\nexthandledtoken\blankspace - \letterhash20% - \else - ##1% - \fi\fi}}% - \expanded{\handletokens#2}\with\docommand - \letgvalue{@@pdf@@scn@@#1}\ascii - \egroup} - -\def\doPDFregistersomespotcolor#1#2#3#4#5#6#7% name fractions names p's space domain function - {\bgroup - \let\spotpops\empty - \ifcase#2\or - %def\PDFspotcolornames{/Separation /#1}% - \edef\PDFspotcolornames{/Separation /\executeifdefined{@@pdf@@scn@@#1}{#1}}% - \def\PDFspotcolordomain{0.0 1.0}% - \else - \dorecurse{#2}{\edef\spotpops{\spotpops pop }}% - \let\PDFspotcolornames \empty - \let\PDFspotcolordomain\empty - \def\dospotcolorcommand##1% - {\edef\PDFspotcolornames {\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}% - \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}% - \processcommacommand[#3]\dospotcolorcommand - \edef\PDFspotcolornames{/DeviceN [\PDFspotcolornames]}% - \fi - \immediate \pdfobj stream attr - {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}% - \immediate \pdfobj - {[\PDFspotcolornames\space /Device#5 \PDFobjref\pdflastobj]}% - \dosetobjectreference{PDFCS}{#1}{\the\pdflastobj}% - \appendtoPDFdocumentcolorspaces{/#1 \PDFobjref\pdflastobj}% - \egroup} - -%D New and very experimental. - -\def\doPDFregistersomeindexcolor#1#2#3#4#5#6#7% name fractions names p's space domain function - {\bgroup - \let\spotpops\empty - \dorecurse{#2}{\edef\spotpops{\spotpops exch pop\space}}% - \let\PDFspotcolornames \empty - \let\PDFspotcolordomain\empty - \def\docommand##1% - {%\edef\PDFspotcolornames {\PDFspotcolornames/##1\space}% - \edef\PDFspotcolornames{\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}% - \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}% - \processcommacommand[#3,None]\docommand - \let\PDFcolorindexvector\empty - \def\docommand##1% - {\scratchdimen##1\points - \scratchdimen\recurselevel\scratchdimen - \scratchcounter\scratchdimen - \divide\scratchcounter \maxcard - \edef\PDFcolorindexvector{\PDFcolorindexvector\uchexnumbers\scratchcounter}}% - %\dostepwiserecurse\zerocount{255}\plusone - \dostepwiserecurse{255}\zerocount\minusone % we need to negate - {\rawprocesscommacommand[#4,1]\docommand - \xdef\PDFcolorindexvector{\PDFcolorindexvector\space}}% - \immediate \pdfobj stream attr - {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}% - \immediate \pdfobj - {[/Indexed - [/DeviceN [\PDFspotcolornames] /Device#5 \the\pdflastobj\space0 R] % - 255 <\PDFcolorindexvector>]}% - \dosetobjectreference{PDFIX}{#1}{\the\pdflastobj}% - \appendtoPDFdocumentcolorspaces{/#1_INDEXED \the\pdflastobj\space0 R}% - \egroup} - -%D \macros -%D {dostarttransparency,dostoptransparency} -%D -%D For transparency, we need to implement a couple of -%D auxiliary macros. If needed, we will generalize them later. - -\def\@@PDT{@PDT@} - -\ifx\PDFcurrenttransparency\undefined - \newcount\PDFcurrenttransparency \PDFcurrenttransparency=0 % -1 -\fi - -\def\assignPDFtransparency#1#2% - {\edef\PDFtransparencyidentifier{/Tr#1}% - \edef\PDFtransparencyreference{\PDFobjref{#2}}} - -\def\presetPDFtransparency#1#2% - {\initializePDFtransparency - \executeifdefined{\@@PDT#1:#2}{\dopresetPDFtransparency{#1}{#2}}} - -\def\dopresetPDFtransparency#1#2% - {\global\advance\PDFcurrenttransparency \plusone - \immediate\pdfobj{\PDFtransparancydictionary{#1}{#2}{}}% - \edef\PDFtransparencyidentifier{/Tr\the\PDFcurrenttransparency}% - \edef\PDFtransparencyreference {\PDFobjref\pdflastobj}% - \setxvalue{\@@PDT#1:#2}% - {\noexpand\assignPDFtransparency{\the\PDFcurrenttransparency}{\the\pdflastobj}}% - \appendtoPDFdocumentextgstates - {\PDFtransparencyidentifier\space - \PDFtransparencyreference\space}} - -\def\initializePDFtransparency - {\immediate\pdfobj{\PDFtransparancydictionary{1}{1}{/AIS false}}% - \xdef\PDFtransparencyresetidentifier{/Tr0}% - \xdef\PDFtransparencyresetreference{\PDFobjref\pdflastobj}% - \setxvalue{\@@PDT0:0}% - {\noexpand\assignPDFtransparency{0}{\the\pdflastobj}}% - \appendtoPDFdocumentextgstates - {\PDFtransparencyresetidentifier\space - \PDFtransparencyresetreference\space}% - \global\let\initializePDFtransparency\relax} - -%D Transparency support: - -\def\PDFtransparancydictionary#1#2#3% type fraction extras - {<>} - -\def\dodoPDFstarttransparency#1#2% - {\presetPDFtransparency{#1}{#2}% - \PDFcode{\PDFtransparencyidentifier\space gs }} - -\def\dodoPDFstoptransparency - {\PDFcode{/Tr0 gs }} - -\def\dostarttransparency - {\global\let\dostarttransparency\dodoPDFstarttransparency - \global\let\dostoptransparency \dodoPDFstoptransparency - \initializetransparency - \dostarttransparency} - -% This is tricky: because a text stream is handled before -% the page body is built, we can run into stops that will -% match an outer start; however, the stop is needed in case -% of a text color: [text color text] [other color text] on a -% first page combined with color splitting will go wrong if -% we stick to the relaxing method. - -% \def\dostoptransparency -% {\initializetransparency -% \dodoPDFstoptransparency} - -%D These use: - -\let\initializetransparency\relax - -\let\PDFtransparencyresetreference \empty -\let\PDFtransparencyresetidentifier\empty - -\let\PDFtransparencyreference \empty -\let\PDFtransparencyidentifier\empty - -%D New trickery: - -\def\dostartgraphicgroup{\PDFcode{q}} -\def\dostopgraphicgroup {\PDFcode{Q}} - -%D \macros -%D {dostartclipping,dostopclipping} -%D -%D Clipping in \PDFTEX\ is rather trivial. We can even hook -%D in \METAPOST\ without problems. - -\def\dostartclipping#1#2#3% - {\PointsToBigPoints{#2}\width - \PointsToBigPoints{#3}\height - \grabMPclippath{#1}{1}\width\height - {0 0 m \width\space 0 l \width \height l 0 \height l}% - \pdfliteral % PDFcode ? - {q 0 w \MPclippath\space W n}} - -\def\dostopclipping - {\pdfliteral{Q n}} % PDFcode - -%D \macros -%D {dosetupinteraction} -%D -%D Nothing special is needed to enable \PDF\ commands and -%D interaction. We stick with a message. - -\def\dosetupinteraction - {\showmessage\m!interactions{21}{pdftex}} - -%D \macros -%D {doresetgotowhereever, -%D dostartthisisrealpage,dostartthisislocation, -%D dostartgotorealpage,dostartgotolocation,dostartgotoJS} -%D -%D The interactions macros are the core of this module. We -%D support both page destinations and named ones. We don't -%D need the \type{\stop}||alternatives. We also don't need -%D to set the special that sets the real page number. - -%D In the goto specials we took care of secondary references. -%D Here we define the macros used. - -\def\doresetgotowhereever - {\global\let\secondaryPDFreferences\empty} - -\doresetgotowhereever % just to be sure - -% we can (in etex) share more by testing on this - -\def\savesecondaryPDFreference#1% - {\@EA\xdef\csname PDF-SR:\the\nofsecondaryreferences\endcsname{#1}} - -\def\savesecondaryPDFreference % #1 == \action - {\global\@EA\let\csname PDF-SR:\the\nofsecondaryreferences\endcsname} - -% test should happen in core-ref - -\def\getsecondaryPDFreferences - {\ifcase\nofsecondaryreferences\else - \ifcsname PDF-SR:\the\nofsecondaryreferences\endcsname - \xdef\secondaryPDFreferences{/Next <<\csname PDF-SR:\the\nofsecondaryreferences\endcsname\space\secondaryPDFreferences>>}% - \fi - \global\advance\nofsecondaryreferences \minusone - \expandafter\getsecondaryPDFreferences - \fi} - -%D \macros -%D {dostartthisislocation} -%D -%D Next we define the macros that deal with hyperreferencing, -%D graphic inclusion and general document features. These are -%D the olderst ones. I won't comment much because one needs -%D knowledge of \PDF\ itself, and explaning \PDF\ is beyond -%D this documentation. - -\def\dostartthisislocation#1% - {\bgroup - \setPDFdestination{#1}% - \ifx\PDFdestination\empty \else - \pdfdest name {\PDFdestination}\PDFpageviewkey - \fi - \egroup} - -\def\locationfilesuffix{pdf} - -\def\dostartgotolocation#1#2#3#4#5#6% - {\bgroup - \doifelsenothing{#3} - {\setPDFdestination{#5}% - \doifelsenothing\PDFdestination - {\let\action\empty} - {\doifelsenothing{#4} - {\let\PDFfile\empty} - {\expanded{\beforesplitstring#4}\at.\to\PDFfile - \doifparentfileelse\PDFfile % {#4} - {\let\PDFfile\empty} - %{\setreferencefilename#4.\locationfilesuffix\to\PDFfile - {\@EA\setreferencefilename\PDFfile.\locationfilesuffix\to\PDFfile - \edef\PDFfile - {R /F (\PDFfile)\ifgotonewwindow\space/NewWindow true \fi}}}% - \edef\action% - {/S /GoTo\PDFfile\space /D (\PDFdestination)}}} - {\doifelsenothing{#4} - {\let\PDFfile\empty - \let\PDFdestination\empty} - {\setreferencefilename/#4\to\PDFfile - \setPDFdestination{#5}% - \doifsomething\PDFdestination - {\edef\PDFdestination{\letterhash\PDFdestination}}}% - \edef\action{/S /URI /URI (#3\PDFfile\PDFdestination)}}% - \ifx\action\empty\else - \ifsecondaryreference - \savesecondaryPDFreference\action - \else - \getsecondaryPDFreferences - \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% - \fi - \fi - \egroup} - -\def\PDFgotonewwindow{\ifgotonewwindow\space/NewWindow true \fi} - -% optimization in tpd driver -% -% \edef\PDFdestination{(page:\the\scratchcounter)}% -% -% ==> -% -% \advance\scratchcounter 1 -% \edef\PDFdestination{[\pdfpageref \PDFobjref\scratchcounter\PDFpageviewwrd]}% -% -% \doPDFgetpagedestination#1#2% pagenumber macro % % fuzzy hack - -\def\dostartgotorealpage#1#2#3#4#5% watch the R append trick - {\bgroup - \doifelsenothing{#3}% #1 = url - {\scratchcounter0#5\relax - \ifnum\scratchcounter>0 - \doifelsenothing{#4} - {\let\PDFfile\empty} - {\expanded{\beforesplitstring#4}\at.\to\PDFfile - \doifparentfileelse\PDFfile % {#4} - {\let\PDFfile\empty} - %{\setreferencefilename#4.\locationfilesuffix\to\PDFfile - {\@EA\setreferencefilename\PDFfile.\locationfilesuffix\to\PDFfile - \edef\PDFfile{R /F (\PDFfile)\PDFgotonewwindow}}}% - \ifx\PDFfile\empty - \ifcase\overcomePDFpage - \or % pdf starts numbering at zero - \advance\scratchcounter \minusone - \edef\PDFdestination{[\the\scratchcounter\space\PDFpageviewwrd]}% - \or % pdf starts numbering at zero - \advance\scratchcounter \minusone - \edef\PDFdestination{(page:\the\scratchcounter)}% - \or % pdftex starts numbering at one - \edef\PDFdestination{[\pdfpageref\scratchcounter\space0 R \PDFpageviewwrd]}% - \fi - \else % across files it's a page number / pdf starts numbering at zero - \advance\scratchcounter \minusone - \edef\PDFdestination{[\the\scratchcounter\space\PDFpageviewwrd]}% - \fi - \edef\action{/S /GoTo\PDFfile\space /D \PDFdestination}% - \else - \let\action\empty - \fi} - {\doifelsenothing{#4} - {\let\PDFfile\empty} - {\setreferencefilename/#4\to\PDFfile}% - \edef\action{/S /URI /URI (#3\PDFfile)}}% - \ifx\action\empty\else - \ifsecondaryreference - \savesecondaryPDFreference\action - \else - \getsecondaryPDFreferences - \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% - \fi - \fi - \egroup} - -\let\lastfakedPDFpage\!!zerocount - -\def\fakePDFpagedestination % as in pdf, we start numbering at zero - {\iflocation \ifarrangingpages \ifnum\overcomePDFpage=\plustwo \else - \ifnum\lastfakedPDFpage<\realpageno - \bgroup - \xdef\lastfakedPDFpage{\realfolio}% - \advance\realpageno \minusone % is \expanded needed ? - \normalexpanded{\noexpand\pdfdest name {page:\realfolio}\PDFpageviewkey}% - \egroup - \fi - \fi \fi \fi} - -\def\dostartgotoJS#1#2#3% - {\bgroup - \doPSsanitizeJScode#3\to\sanitizedJScode - \edef\action{/S /JavaScript /JS (\sanitizedJScode)}% - \ifsecondaryreference - \savesecondaryPDFreference\action - \else - \getsecondaryPDFreferences - \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% - \fi - \egroup} - -%D When going to a location, we obey the time and space saving -%D boolean \type{\ifusepagedestination}. Named destinations are -%D stripped and made robust. This all happens in the macros -%D called for. - -%D \macros -%D {doflushJSpreamble} -%D -%D It does not make sense to duplicate common \JAVASCRIPT\ -%D functions, and therefore they can be predefined and must be -%D output separately. Currently this special is not shared -%D with the \ACROBAT\ one, simply because \DISTILLER\ does not -%D yet support something \type{\pdfnames}. - -% \oneJSpreamblefalse % buggy in acrobat - -\def\doflushJSpreamble#1% - {\bgroup - \let\compositeJScode\empty - \def\docommand##1% - {\edef\sanitizedJScode{\getJSpreamble{##1}}% - \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode - \immediate\pdfobj {<< /S /JavaScript /JS (\sanitizedJScode) >>}% - \edef\compositeJScode - {\compositeJScode\space (##1) \PDFobjref\pdflastobj}}% - \processcommalist[#1]\docommand - \immediate\pdfobj{<< /Names [ \compositeJScode ] >>}% - \pdfnames{/JavaScript \PDFobjref\pdflastobj}% - \egroup} - -%D \macros -%D {dostarthide,dostophide} -%D -%D Hiding parts of the document for printing is not yet -%D supported by \PDF\ and therefore \PDFTEX. - -\let\dostarthide\donothing -\let\dostophide \donothing - -%D \macros -%D {doPDFsetupscreen,doPDFsetupidentity} -%D -%D Opposite to \DVI\ drivers, \PDF\ ones must know which what -%D page dimensions they are dealing. We also use the -%D opportunity to launch full screen (1) or show bookmarks (2). -%D -%D Setting of the screen boundingbox involves some -%D calculations. Here we also take care of (non) full screen -%D startup. The dimensions are rounded. Because \PDFTEX\ and -%D \ACROBAT\ handle setting the page dimensions in a -%D different way, we do not share this special. - -\def\dosetupscreen{\doPDFsetupscreen\pdfpageheight} - -\let\currentPDFpagemode \empty % document catalog -\let\currentPDFviewerprefs\empty % document catalog - -\let\currentPDFcropbox \empty % page attributes -\let\currentPDFbleedbox \empty % page attributes -\let\currentPDFartbox \empty % page attributes -\let\currentPDFtrimbox \empty % page attributes - -\def\doPDFsetupscreen#1#2#3#4#5#6% watch the extra argument - {\bgroup - \xdef\currentPDFpagemode - {\ifnum#6=4 - /PageLayout /TwoColumnRight - \else - /PageMode \ifcase#6 - /UseNone\or/FullScreen\or/UseOutlines\else/UseNone\fi - \fi}% - \xdef\currentPDFviewerprefs % space after #6 needed, else \relax - {\ifcase#6 \or\or\else /ViewerPreferences << /FitWindow true >>\fi}% - \egroup} - -\def\addPDFdocumentinfo - {\appendtopdfcatalog{\currentPDFpagemode\currentPDFviewerprefs}% - \appendtopdfcatalog{/Version \ifdim\PDFversion00\points>100\points 1.\fi\PDFversion}% - \appendtopdfinfo{/Trapped /False}% - \appendtopdfinfo{/ConTeXt.Version (\contextversion)}% - \appendtopdfinfo{/ConTeXt.Time (\number\normalyear.\twodigits\normalmonth.\twodigits\normalday\space \twodigits\currenthour:\twodigits\currentminute)}% - \appendtopdfinfo{/ConTeXt.Jobname (\jobname)}% - \appendtopdfinfo{/ConTeXt.Url (www.pragma-ade.com)}% - \glet\addPDFdocumentinfo\relax} - -\def\PDFversion{1.5} - -\appendtoksonce - \def\PDFversion{1.5}% -\to \everyresetspecials - -\def\doPDFsetupwhateverbox#1#2#3#4#5#6% watch the extra arguments - {\bgroup - \!!widtha \dimexpr#5+#3\relax - \!!heightb\dimexpr#2-#4\relax - \!!heighta\dimexpr\!!heightb-#6\relax - % sometimes whole values give better results - % \PointsToWholeBigPoints{#3}\left - % \PointsToWholeBigPoints\!!heighta\bottom - % \PointsToWholeBigPoints\!!widtha \width - % \PointsToWholeBigPoints\!!heightb\height - % but since pdf/x does not round when checking if - % the boxes fit inside the media box ... - \PointsToBigPoints{#3}\left - \PointsToBigPoints\!!heighta\bottom - \PointsToBigPoints\!!widtha \width - \PointsToBigPoints\!!heightb\height - \xdef#1{[\left\space\bottom\space\width\space\height]}% - \egroup} - -\gdef\currentPDFtrimbox{\currentPDFcropbox} % default, needed for pdf/x - -\def\dosetupartbox {\doPDFsetupwhateverbox\currentPDFartbox \pdfpageheight} -\def\dosetupcropbox {\doPDFsetupwhateverbox\currentPDFcropbox \pdfpageheight} -\def\dosetupbleedbox{\doPDFsetupwhateverbox\currentPDFbleedbox\pdfpageheight} -\def\dosetuptrimbox {\doPDFsetupwhateverbox\currentPDFtrimbox \pdfpageheight} - -\def\flushPDFpageboxes - {\edef\currentPDFtrimbox{\currentPDFtrimbox}% - \ifx\currentPDFartbox \empty\else\appendtopdfpageattributes{/ArtBox \currentPDFartbox }\fi - \ifx\currentPDFcropbox \empty\else\appendtopdfpageattributes{/CropBox \currentPDFcropbox }\fi - \ifx\currentPDFbleedbox\empty\else\appendtopdfpageattributes{/BleedBox \currentPDFbleedbox}\fi - \ifx\currentPDFtrimbox \empty\else\appendtopdfpageattributes{/TrimBox \currentPDFtrimbox }\fi} - -%D \macros -%D {dostartexecutecommand} -%D -%D \PDF\ viewers enable us to navigate using menus and shortcut -%D keys. These navigational tools can also be accessed by using -%D annotations. The next special takes care of inserting them. -%D -%D At the cost of much auxiliary placeholders, we can pretty -%D fast convert the command asked for. This is how the \PDF\ -%D code looks like. - -\def\PDFmoviecode#1#2#3% - {/Movie - /T (\ifcase#1movie \else sound \fi\ifx\argumentA\empty#2\else\argumentA\fi) - /Operation /\ifcase#3Play\or Stop\or Pause\or Resume\fi\space} - -\def\PDFexecutestartmovie {\PDFmoviecode0\currentmovie0} -\def\PDFexecutestopmovie {\PDFmoviecode0\currentmovie1} -\def\PDFexecutepausemovie {\PDFmoviecode0\currentmovie2} -\def\PDFexecuteresumemovie {\PDFmoviecode0\currentmovie3} - -\def\PDFexecutestartsound {\PDFmoviecode1\currentsound0} -\def\PDFexecutestopsound {\PDFmoviecode1\currentsound1} -\def\PDFexecutepausesound {\PDFmoviecode1\currentsound2} -\def\PDFexecuteresumesound {\PDFmoviecode1\currentsound3} - -\def\PDFformcode#1% - {\doiffieldset{#1}{/Field [\dogetfieldset{#1}]}} - -% bit 3 = html -% bit 6 = xml -% bit 4 = get - -\ifx\PDFsubmitfiller\undefined \let\PDFsubmitfiller\empty \fi - -\chardef\PDFformmethod=1 % 0=GET 1=POST - -\def\PDFformflag#1#2{\ifcase\PDFformmethod#1\else#2\fi} - -\def\PDFexecuteimportform {/Named /N /AcroForm:ImportFDF} -\def\PDFexecuteexportform {/Named /N /AcroForm:ExportFDF} -\def\PDFexecuteresetform {/ResetForm \PDFformcode\argumentA} -\def\PDFexecutesubmitform {/SubmitForm \PDFformcode\argumentB - /Flags \ifcase\submitoutputformat\space - \PDFformflag{12} {4} % 0=unknown - \or \PDFformflag{12} {4} % 1=HTML - \or \PDFformflag {8} {0} % 2=FDF - \or \PDFformflag{40}{32} % 3=XML - \else \PDFformflag{12} {4} % ?=unknown - \fi - /F (\argumentA)\PDFsubmitfiller} - -% urifill permits url substitution - -\def\PDFexecutehide {/Hide /T (\argumentA) /H true} -\def\PDFexecuteshow {/Hide /T (\argumentA) /H false} - -\def\PDFexecutefirst {/Named /N /FirstPage} -\def\PDFexecuteprevious {/Named /N /PrevPage} -\def\PDFexecutenext {/Named /N /NextPage} -\def\PDFexecutelast {/Named /N /LastPage} -\def\PDFexecutebackward {/Named /N /GoBack} -\def\PDFexecuteforward {/Named /N /GoForward} -\def\PDFexecuteprint {/Named /N /Print} -\def\PDFexecuteexit {/Named /N /Quit} -\def\PDFexecuteclose {/Named /N /Close} -\def\PDFexecutesave {/Named /N /Save} -\def\PDFexecutesavenamed {/Named /N /SaveAs} -\def\PDFexecuteopennamed {/Named /N /Open} -\def\PDFexecutehelp {/Named /N /HelpUserGuide} -\def\PDFexecutetoggle {/Named /N /FullScreen} -\def\PDFexecutesearch {/Named /N /Find} -\def\PDFexecutesearchagain {/Named /N /FindAgain} -\def\PDFexecutegotopage {/Named /N /GoToPage} -\def\PDFexecutequery {/Named /N /AcroSrch:Query} -\def\PDFexecutequeryagain {/Named /N /AcroSrch:NextHit} -\def\PDFexecutefitwidth {/Named /N /FitWidth} -\def\PDFexecutefitheight {/Named /N /FitHeight} - -\let\PDFobjectclass\empty -\let\PDFobjectname \empty - -\def\dostartexecutecommand#1#2#3#4% - {\doifdefined{PDFexecute#3} - {\bgroup - \edef\argument{#4}% - \ifx\argument\empty - \let\argumentA\empty - \let\argumentB\empty - \else - \@EA\dogetcommalistelement\@EA1\@EA\from#4\to\argumentA - \@EA\dogetcommalistelement\@EA2\@EA\from#4\to\argumentB - \fi - \edef\action% - {/S \getvalue{PDFexecute#3}}% - \ifsecondaryreference - \savesecondaryPDFreference\action - \else - \getsecondaryPDFreferences -% \ifx\PDFobjectclass\empty -% \let\next\insertpdfaction -% \else -% \edef\next{\createpdfactionobject{\PDFobjectclass}{\PDFobjectname}}% -% \globalletempty\PDFobjectclass -% \globalletempty\PDFobjectname -% \fi -% \next - \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% - \fi - \egroup}} - -%D \macros -%D {dosetupidentity} -%D -%D Documents can be tagged with an application accessible title -%D and subtitle, the authorname, a date, the creator, keywords -%D etc. For the moment \PDFTEX\ only supports the first three -%D of these. - -\def\dosetupidentity#1#2#3#4#5#6% - {\normalexpanded{\noexpand\appendtopdfinfo - {/Title <\hexifiedPDFstring{#1}> - /Subject <\hexifiedPDFstring{#2}> - /Author <\hexifiedPDFstring{#3}> - /Creator <\hexifiedPDFstring{#4}> - /ModDate (#4) - /ID (\jobname.#5) % needed for pdf/x - /Keywords <\hexifiedPDFstring{#6}>}}} - -%D \macros -%D {dostartrunprogam} -%D -%D We can run a program form within a document, although this -%D feature is rather weak, due to path problems and buggy -%D argument passing. - -\def\dostartrunprogram#1#2#3#4% new: #3 => #3#4 - {\bgroup - %\edef\string{#3}% - %\@EA\beforesplitstring\string\at{ }\to\program - %\@EA\aftersplitstring \string\at{ }\to\parameters - %\edef\action% - % {/S /Launch /F (\program) /P (\parameters) /D (.)}% - \edef\action - {/S /Launch /F (#3) /P (#4) /D (.)}% - \ifsecondaryreference - \savesecondaryPDFreference\action - \else - \getsecondaryPDFreferences - \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% - \fi - \egroup} - -%D \macros -%D {dostartgotoprofile, dostopgotoprofile, -%D dobeginofprofile, doendofprofile} -%D -%D \CONTEXT\ user profiles and version control fall back on -%D \PDF\ article threads. Unfortunately one cannot influence -%D the view yet in an (for me) acceptable way. - -\def\dostartgotoprofile#1#2#3% to be done: file - {\bgroup - \setPDFdestination{#3}% - \doifsomething\PDFdestination - {\edef\action - {/S /Thread /D (\PDFdestination)}% - \ifsecondaryreference - \savesecondaryPDFreference\action - \else - \getsecondaryPDFreferences - \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% - \fi}% - \egroup} - -%D Some day, I'll reimplement threading in a useful way. -%D Currently the viewers handle threads rather diffuse. - -\def\dobeginofprofile#1#2#3#4% - {\setPDFdestination{#1}% - \doifsomething\PDFdestination - {\pdfthread - width #2 height #3 - attr {/Title (\PDFdestination)} % can be omitted - name {\PDFdestination}}} - -\def\doendofprofile - {} - -%D \macros -%D {doinsertbookmark} -%D -%D In \PDF\ bookmarks are the building blocks of a viewer -%D provided sort of table of contents. \TEX\ has to provide -%D the entry as well as the number of child entries. Strings -%D need to be sanatized as good as possible to suit the default -%D encoding. In \CONTEXT\ users can overrule this string by -%D supplying an alternative one. Look at the macro called for -%D to see how funny these bookmarks are defined. - -\def\doinsertbookmark#1#2#3#4#5% level sublevels text page open=1 - {\bgroup - \doPDFgetpagereference{#4}\PDFobjectreference - \pdfoutline - user {<>}% - \ifcase#2 \else count \ifcase#5-\fi#2 \fi -% {<\hexifiedPDFstring{#3}>}% goes wrong - {<#3>}% - \egroup} - -%D \macros -%D {dostartobject,dostopobject,doinsertobject} -%D -%D Due to \PDF's object oriented character, we can include and -%D reuse objects. These can be compared with \TEX's boxes. The -%D \TEX\ counterpart is defined in the module \type{spec-dvi}. -%D We don't use the dimensions here. -%D -%D The next solution is not that beautiful. Because objects are -%D containers for whatever kind of content, graphics can be -%D part of this content, and a graphic object can be part of -%D the more general type. In practice this means that an ximage -%D would be embedded in an xform, which in itself is not that -%D big a problem, apart from a few bytes overhead. However, for -%D reasons unknown to me alternative images must be pure -%D ximages |<|indeed, somehow one cannot use a vector graphic -%D as alternative|>| that are not embedded into forms, so this -%D is why the object handler treats them different. This -%D implies knowledge of the calling routines, especially the -%D \type{FIG} trigger, that signals that we just embedded an -%D image. Alternatively I could have introduced a dual object -%D system, but the overhead in duplicate specials is currently -%D not what we want. I'd rather implement a more mature -%D object support system from scratch. - -\let\currentPDFresources\empty -\let\PDFimageattributes \empty -\let\PDFfigurereference \empty -\let\PDFimagereference \empty - -\def\dostartobject#1#2#3#4#5% - {\bgroup - \setbox\nextbox\vbox\bgroup - \def\dodostopobject - {\egroup - \ifx\PDFimagereference\empty - % We also flush page resources, since shared - % resources end up there; otherwise transparencies - % won't work in xforms; some day I will optimize - % this. - \the\everyPDFxform - \finalizeobjectbox\nextbox - \immediate\pdfxform - resources {\currentPDFresources\the\pdfpageresources}% - \nextbox - \global\let\currentPDFresources\empty - \dosetobjectreference{#1}{#2}{\the\pdflastxform}% - \else - \dosetobjectreference{#1}{#2}{-\PDFimagereference}% - \global\let\PDFimagereference\empty - \fi}} - -\def\dostopobject - {\dodostopobject - \egroup} - -\def\doresetobjects - {\global\let\PDFimagereference\empty} - -\def\doinsertobject#1#2% - {\bgroup - \doifobjectreferencefoundelse{#1}{#2} - {\dogetobjectreference{#1}{#2}\PDFobjectreference - \ifnum\PDFobjectreference<0 - \@EA\@EA\@EA\pdfrefximage\@EA\gobbleoneargument\PDFobjectreference - \else - \pdfrefxform\PDFobjectreference - \fi}% - {}% - \egroup} - -\appendtoksonce - \collectPDFresources - \global\let\currentPDFresources\collectedPDFresources -\to \everyPDFxform - -%D \macros -%D {dosetpagetransition} -%D -%D Page transitions only make sence in presentations. They are -%D passed as raw \PDF\ code to the page object. Take a look -%D at the implementation to get an impression of the rubish -%D passed on. -%D -%D This array holds a reasonable selection of transitions -%D (watch out: \type{replace} is not in this list). Most of -%D the transitions look awful anyway. By the way, \CONTEXT\ is -%D able to select transitions randomly. - -\def\pagetransitions - {{split,in,vertical},{split,in,horizontal}, - {split,out,vertical},{split,out,horizontal}, - {blinds,horizontal},{blinds,vertical}, - {box,in},{box,out}, - {wipe,east},{wipe,west},{wipe,north},{wipe,south}, - dissolve, - {glitter,east},{glitter,south}, - {fly,in,east},{fly,in,west},{fly,in,north},{fly,in,south}, - {fly,out,east},{fly,out,west},{fly,out,north},{fly,out,south}, - {push,east},{push,west},{push,north},{push,south}, - {cover,east},{cover,west},{cover,north},{cover,south}, - {uncover,east},{uncover,west},{uncover,north},{uncover,south}, - fade} - -%D Again, we use macros as placeholders for \PDF\ key||value -%D pairs. - -\def\PDFpagesplit {/S /Split } -\def\PDFpageblinds {/S /Blinds } -\def\PDFpagebox {/S /Box } -\def\PDFpagewipe {/S /Wipe } -\def\PDFpagedissolve {/S /Dissolve } -\def\PDFpageglitter {/S /Glitter } -\def\PDFpagereplace {/S /R } - -\def\PDFpagefly {/S /Fly } % 1.5 -\def\PDFpagepush {/S /Push } % 1.5 -\def\PDFpagecover {/S /Cover } % 1.5 -\def\PDFpageuncover {/S /Uncover } % 1.5 -\def\PDFpagefade {/S /Fade } % 1.5 - -\def\PDFpagehorizontal {/Dm /H } -\def\PDFpagevertical {/Dm /V } -\def\PDFpagein {/M /I } -\def\PDFpageout {/M /O } -\def\PDFpageeast {/Di 0 } -\def\PDFpagenorth {/Di 90 } -\def\PDFpagewest {/Di 180 } -\def\PDFpagesouth {/Di 270 } - -\def\dodoPDFsetpagetransition#1% - {\doifdefined{PDFpage#1} - {\edef\PDFpagetransitions{\PDFpagetransitions\getvalue{PDFpage#1}}}} - -\def\dosetpagetransition#1#2% - {\let\PDFpagetransitions\empty - \processcommalist[#1]\dodoPDFsetpagetransition - \appendtopdfpageattributes - %{\ifnum#2>0 /Dur #2 \fi - {\ifnum0<0#2 /Dur #2 \fi - \ifx\PDFpagetransitions\empty\else/Trans <<\PDFpagetransitions>>\fi}} - -%D The expansion is needed because else the \type{\pdfpageattr} -%D token list flushes an unexpanded \type{\csname}. The -%D \type{\global} is needed because the assignment can take -%D place deeply buried (for instance in the \type{\shipout} -%D box. - -%D \macros -%D {doinsertcomment, doflushcomments} -%D -%D Text annotation, or comments, are provided too: - -%D \macros -%D {dopresetlinefield,dopresettextfield, -%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, -%D dopresetpushfield,dopresetcheckfield, -%D dopresetradiofield,dopresetradiorecord} -%D -%D \PDF\ offers extensive field support. The next bunch of -%D definitions map the specials. - -%D \macros -%D {dodefinefieldset,dogetfieldset,doiffieldset} -%D -%D Field sets, needed for reset and submit handling, are -%D taken care of by: - -%D The next section of this module is dedicated to form -%D support. These macros are complicated by the fact that -%D cloning is possible. - -%D \macros -%D {FDFflag...,FDFplus...} -%D -%D The \type{/FT} key determines the type of field: text, -%D button or choice. The latter two come in several disguises, -%D which are set by flipping bits in the \type{/Ff}. Other bits -%D are used to set states. Personally I hate this bitty way of -%D doing things. The next six bit determine the field sub type: - -\def\FDFflagMultiLine {4096} % 13 -\def\FDFflagNoToggleToOff {16384} % 15 -\def\FDFflagRadio {32768} % 16 -\def\FDFflagPushButton {65536} % 17 -\def\FDFflagPopUp {131072} % 18 -\def\FDFflagEdit {262144} % 19 - -% bugged anyway, so we need to drop it: - -\def\FDFflagRadiosInUnison {33554432} % 26 - -%D A few more (pdf 1.4) flags, what the spell check one: for -%D obscure reasons for Adobe downward compatibility means -%D enabling features that harm old applications like testing. - -\def\FDFflagDoNotSpellCheck {4194304} % 23 -\def\FDFflagDoNotScroll {8388608} % 24 - -%D The next bits (watch how strange the bits are organized) -%D take care of the states: - -\def\FDFflagReadOnly {1} % 1 -\def\FDFflagRequired {2} % 2 -\def\FDFflagNoExport {4} % 3 -\def\FDFflagPassword {8192} % 14 -\def\FDFflagSort {524288} % 20 -\def\FDFflagFileSelect {1048576} % 21 - -%D There is a second, again bitset oriented, \type{/F} flag: - -\def\FDFplusInvisible {1} % 1 -\def\FDFplusHidden {2} % 2 -\def\FDFplusPrintable {4} % 3 - -%def\FDFplusNoView {32} % 6 -%def\FDFplusToggleNoView {256} % 9 - -\def\FDFplusAutoView {256} % {288} % 6+9 - -%D \macros -%D {setFDFswitches} -%D -%D The non||type bits are mapped onto user||interface -%D swithes, to be used later on: - -\def\@@FDFflag{FDFflag} -\def\@@FDFplus{FDFplus} - -\letvalue {\@@FDFflag\v!readonly}=\FDFflagReadOnly -\letvalue {\@@FDFflag\v!required}=\FDFflagRequired -\letvalue {\@@FDFflag\v!protected}=\FDFflagPassword -\letvalue {\@@FDFflag\v!sorted}=\FDFflagSort -\letvalue {\@@FDFflag\v!unavailable}=\FDFflagNoExport -\letvalue {\@@FDFflag\v!nocheck}=\FDFflagDoNotSpellCheck -\letvalue {\@@FDFflag\v!fixed}=\FDFflagDoNotScroll -\letvalue {\@@FDFflag\v!file}=\FDFflagFileSelect - -\letvalue {\@@FDFplus\v!hidden}=\FDFplusHidden -\letvalue {\@@FDFplus\v!printable}=\FDFplusPrintable - -\letvalue {\@@FDFplus\v!auto}=\FDFplusAutoView - -%D A set of switches is collected into the flags we mentioned -%D before by the next macro (we don't handle negations yet, -%D but do take care of redundancy): - -\def\FDFflag{0} -\def\FDFplus{0} - -\def\setFDFswitches[#1]% - {\bgroup - \!!counta\zerocount - \!!countb\zerocount - \def\docommand##1% - {\doifsomething{##1} - {\advance\!!counta 0\getvalue{\@@FDFflag##1}% - \setvalue{\@@FDFflag##1}{0}% - \advance\!!countb 0\getvalue{\@@FDFplus##1}% - \setvalue{\@@FDFplus##1}{0}}}% - \processcommacommand[#1]\docommand - \xdef\FDFflag{\the\!!counta}% - \xdef\FDFplus{\the\!!countb}% - \egroup} - -%D \macros -%D {setFDFvalues} -%D -%D Menu items are passed as an array of \type{(string)}'s and -%D the content of this array is build with: - -\let\FDFvalues \empty -\let\FDFfirstvalues \empty -\let\FDFsecondvalues\empty -\let\FDFkidlist \empty -\let\FDFdefaultindex\!!zerocount -\let\FDFdefaultvalue\empty - -% Why do we need to tweak this mechanism each time acrobat updates ... -% it would make sense to have version specific sections in pdf files -% since my guess is that it never will be done right since each year -% new programmers have new ideas about what is supposed to happen with -% kids. So .. best is not to trust this feature esp not for radio -% widgets. (new flags, different interpretation of AS etc etc) - -\def\setFDFvalues[#1][#2]% #1 = list (item=>value) #2 = default - {\let\FDFvalues \empty - %when radio opt works ok - %\let\FDFfirstvalues \empty - %\let\FDFsecondvalues\empty - \let\FDFkidlist \empty - %\let\FDFdefaultindex\!!zerocount - %\let\FDFdefaultvalue\empty - %\scratchcounter\zerocount - \def\dodocommand##1=>##2=>##3\end - {\addtocommalist{##1}\FDFkidlist - %\edef\FDFfirstvalues{\FDFfirstvalues(##1)}% - %\doif{##1}{#2}{\edef\FDFdefaultindex{\the\scratchcounter}}% - %\advance\scratchcounter\plusone - \doifelsenothing{##2} - {\doif{##1}{#2}{\edef\FDFdefaultvalue{##1}}% - %\edef\FDFsecondvalues{\FDFsecondvalues(##1)}% - \edef\FDFvalues{\FDFvalues [(##1)(##1)] }} - {\doif{##1}{#2}{\edef\FDFdefaultvalue{##2}}% - %\edef\FDFsecondvalues{\FDFsecondvalues(##2)}% - \edef\FDFvalues{\FDFvalues [(##2)(##1)] }}}% ! ##1 is shown - \def\docommand##1% - {\dodocommand##1=>=>\end}% - \expanded{\processcommalist[#1]}\docommand} - -%D This macro accepts comma separated \type{visual=>result} -%D pairs. - -%D \macros -%D {setFDFalignment} -%D -%D Text and line fields can be entered and showed in three -%D alternative alingments, indicated by a digit: - -\def\FDFalign{0} - -\def\setFDFalignment[#1]% - {\processaction - [#1] - [ \v!left=>\edef\FDFalign{2}, % raggedleft - \v!middle=>\edef\FDFalign{1}, % raggedcenter - \v!right=>\edef\FDFalign{0}]} % raggedright - -%D \macros -%D {setFDFattributes} -%D -%D The weak part of (at least version 2.1 \PDF) is that only -%D default fonts are handled well. Another restriction is that -%D the encoding vector must be the standard \PDF\ document one. -%D Although the \PDF\ reference explictly states that one could -%D use the normal text operators, leading is not yet handled. -%D -%D For the moment the current \CONTEXT\ font is mapped onto -%D one best suitable default font. The color attribute is -%D less problematic and is directly derived from the \CONTEXT\ -%D color. - -\def\FDFattributes{/Helv 12 Tf 0 g 14.4 TL} - -\def\FDFrm {TiRo} \def\FDFss {Helv} \def\FDFtt {Cour} -\def\FDFrmtf{TiRo} \def\FDFsstf{Helv} \def\FDFtttf{Cour} -\def\FDFrmbf{TiBo} \def\FDFssbf{HeBo} \def\FDFttbf{CoBo} -\def\FDFrmit{TiIt} \def\FDFssit{HeOb} \def\FDFttit{CoOb} -\def\FDFrmsl{TiIt} \def\FDFsssl{HeOb} \def\FDFttsl{CoOb} -\def\FDFrmbi{TiBI} \def\FDFssbi{HeBO} \def\FDFttbi{CoBO} -\def\FDFrmbs{TiBI} \def\FDFssbs{HeBO} \def\FDFttbs{CoBO} - -\let\FDFusedfonts=\FDFsstf - -\def\setFDFattributes[#1,#2,#3,#4]% style, color, backgroundcolor, framecolor - {\bgroup % nog interlinie: n TL - \setbox\scratchbox\hbox - \bgroup - \doconvertfont{#1}{}% - \PointsToBigPoints\bodyfontsize\size % x/xx, so better the actual size - \doifdefinedelse{FDF\fontstyle\fontalternative} - {\xdef\FDFattributes{\getvalue{FDF\fontstyle\fontalternative}}} - {\doifdefinedelse{FDF\fontstyle} - {\xdef\FDFattributes{\getvalue{FDF\fontstyle}}} - {\xdef\FDFattributes{\FDFrm}}}% - \doglobal\addtocommalist\FDFattributes\FDFusedfonts - \xdef\FDFattributes% move up with "x.y Ts" - {/\FDFattributes\space\size\space Tf\space\PDFcolor{#2}}% - \doifelsenothing{#3} - {\global\let\FDFsurroundings\empty} - {\xdef\FDFsurroundings{/BG \FDFcolor{#3}}}% - \doifsomething{#4} - {\xdef\FDFsurroundings{\FDFsurroundings\space /BC \FDFcolor{#4}}}% - \ifx\FDFsurroundings\empty \else - \xdef\FDFsurroundings{/MK << \FDFsurroundings\space>>}% - \fi - \egroup - \egroup} - -%D \macros -%D {setFDFactions} -%D -%D Depending on the type of the field, one can assign -%D \JAVASCRIPT\ code to a mouse event or keystroke. The next -%D preparation macro shows what events are handled. - -\let\FDFactions\empty - -\def\setFDFactions[#1,#2,#3,#4,#5,#6,#7,#8,% - {\global\let\FDFactions\empty - \setFDFaction D#1% mousedown - \setFDFaction U#2% mouseup - \setFDFaction E#3% enterregion - \setFDFaction X#4% exitregion - \setFDFaction K#5% afterkeystroke - \setFDFaction F#6% formatresult - \setFDFaction V#7% validateresult - \setFDFaction C#8% calculatewhatever - \setFDFactionsmore} - -\def\setFDFactionsmore#1,#2]% - {\setFDFaction{Fo}#1% focusin - \setFDFaction{Bl}#2% focusout % was I (now pdf ref manual explicitly talks about lowercase l) - \ifx\FDFactions\empty\else - \xdef\FDFactions{/AA << \FDFactions >>}% since 1.3 no longer inherited - \fi} - -% todo, when new var scheme is implemented -% -% \setFDFaction{PO}\@@DriverFieldPageOpen -% \setFDFaction{PC}\@@DriverFieldPageClose -% \setFDFaction{PV}\@@DriverFieldPageVisible -% \setFDFaction{PI}\@@DriverFieldPageInVisible - -%D The event handler becomes something: -%D -%D \starttyping -%D /AA << /D << /S ... >> ... /C << /S ... >> -%D /A << /S /JavaScript /JS (...) >> -%D \stoptyping - -\def\setFDFaction#1#2% - {\bgroup - \def\docommand{\xdef\FDFactions{\FDFactions /#1 << \lastPDFaction >> }}% - \@EA\handlereferenceactions\@EA{#2}\docommand % one level expansion - \egroup} - -%D \macros -%D {testFDFactions} -%D -%D This rather confusion prone series of script can be tested -%D with: -%D -%D \starttyping -%D \testFDFactions -%D \stoptyping -%D -%D which simply redefined the previous macro to one that prints -%D a message to the console. - -\def\testFDFactions - {\def\setFDFaction##1##2% - {\doPSsanitizeJScode console.show();console.println("executing:##1"); \to\sanitizedJScode - \edef\FDFactions{\FDFactions /##1 << /S /JavaScript /JS (\sanitizedJScode) >> }}} - -%D \macros -%D {doregistercalculationset} -%D -%D There is at most one calculation order list, which defines -%D the order in which fields are calculated. The calculation -%D order is defined using: - -\let\PDFcalculationset\empty - -\def\doregistercalculationset#1% - {\def\PDFcalculationset{#1}} - -%D \macros -%D {registerFDFobject,everylastshipout} -%D -%D Officially one needs to embed some general datastructures -%D that tell the viewer what fields are present in the file, as -%D well as what resources they use. The next mechanism does that -%D job automatically when one registers the field. - -\def\flushFDFnames - {\ifx\FDFcollection\empty\else - \defineFDFfonts - \createpdfarrayobject{FDF}{local:fields}{\FDFcollection}% - \doPDFgetobjectreference{FDF}{local:fields}\PDFobjectreference - % The /NeedAppearances is pretty important because - % otherwise Acrobat 5 blows up on cloned radio widgets - \createpdfdictionaryobject{FDF}{local:acroform} - {/Fields \PDFobjectreference\space - /NeedAppearances true - \doiffieldset\PDFcalculationset{/CO [\dogetfieldset\PDFcalculationset]} - /DR << /Font << \FDFfonts >> >> - /DA (/Helv 10 Tf 0 g)}% - \doPDFgetobjectreference{FDF}{local:acroform}\PDFobjectreference - \appendtopdfcatalog - {/AcroForm \PDFobjectreference}% - \global\let\FDFcollection\empty - \global\let\flushFDFnames\relax - \fi} - -\let\FDFcollection\empty - -\def\registerFDFobject#1% - {\ifx\flushFDFnames\relax - \writestatus{FDF}{second run needed for field list (#1)}% - \fi - \doPDFgetobjectreference{FDF}{#1}\PDFobjectreference - \xdef\FDFcollection{\FDFcollection\space\PDFobjectreference}} - -\appendtoksonce \flushFDFnames \to \everylastshipout % test \everybye / was \prependtoksonce - -%D \macros -%D {defineFDFfonts} -%D -%D Another datastruture concerns the fonts used. We only -%D define the fonts we use. - -\def\defineFDFfonts - {\let\FDFfonts\empty - \processcommacommand[\FDFusedfonts]\defineFDFfont} - -\def\defineFDFfont#1% - {\createpdfdictionaryobject{FDF}{local:#1} - {/Type /Font - /Subtype /Type1 - /Name /#1 - /BaseFont /\getvalue{FDFname#1}}% - \doPDFgetobjectreference{FDF}{local:#1}\PDFobjectreference - \edef\FDFfonts{\FDFfonts \space/#1 \PDFobjectreference}} - -%D Another list of constants: - -\def\FDFnameTiRo {Times-Roman} -\def\FDFnameTiBo {Times-Bold} -\def\FDFnameTiIt {Times-Italic} -\def\FDFnameTiBI {Times-BoldItalic} -\def\FDFnameHelv {Helvetica} -\def\FDFnameHeBo {Helvetica-Bold} -\def\FDFnameHeOb {Helvetica-Oblique} -\def\FDFnameHeBO {Helvetica-BoldOblique} -\def\FDFnameCour {Courier} -\def\FDFnameCoBo {Courier-Bold} -\def\FDFnameCoOb {Courier-Oblique} -\def\FDFnameCoBO {Courier-BoldOblique} - -%D \macros -%D {currentFDFmode,currentFDFparent,currentFDFkids,currenrFDFroot} -%D -%D There are three more quasi global interfacing variables -%D that need to be set. - -\let\currentFDFmode \fieldlonermode -\let\currentFDFkids \empty -\let\currentFDFparent\empty -\let\currentFDFroot \empty - -%D \macros -%D {dosetfieldstatus} -%D -%D And here comes the special that deals with them. - -\def\dosetfieldstatus#1#2#3#4% - {\chardef\currentFDFmode #1% - \edef\currentFDFparent {#2}% - \edef\currentFDFkids {#3}% - \edef\currentFDFroot {#4}} - -%D We already dealt with the encoding vector. Conversion from -%D \TEX\ \ASCII\ encoding to the other one, is accomplished by -%D the next few macros. Wach out: we don't group here. - -\appendtoksonce - \simplifycommands -\to \everysetfield - -%D \macros -%D {doPDFinsertcomment} -%D -%D An example its use is the next special, one that deals with -%D text annotations. - -\newcounter\nofFDFcomments - -\newif\ifPDFpopupcomments \PDFpopupcommentstrue - -\def\doflushcomments - {\box\PDFsymbolbox} - -\long\def\doinsertcomment#1#2#3#4#5#6#7#8% % \@@DriverCommentLayer set otherwise - {\bgroup % title width height color open symbol collect data - \presetPDFsymbolappearance{#4}{#6}{#2}{#3}\!!zeropoint% sets width/height - \doifelsenothing{#1} - {\let\PDFidentifier\empty} - {\sanitizePDFencoding#1\to\PDFcommenttitle - \def\PDFidentifier{/T <\PDFcommenttitle>}}% - \sanitizePDFencoding#8\to\PDFdata - \setFDFlayer\@@DriverCommentLayer - \startPDFsymbolappearance - \ifPDFpopupcomments - \doglobal\increment\nofFDFcomments - \doifobjectreferencefoundelse{FDF}{c:\nofFDFcomments} - {\doPDFgetobjectreference{FDF}{c:\nofFDFcomments}\PDFobjectreference - \donetrue} - \donefalse - \ifdone - \setbox\scratchbox\hbox - {\createpdfannotationobject{FDF}{c::\nofFDFcomments}{#2}{#3}% text window, size does not work - {/Subtype /Popup - /Parent \PDFobjectreference}}% - \ifcase#7\relax - \vbox to \height{\forgetall\vskip#3\box\scratchbox\vss}% - \else % incredible trial and error hack - % it's quite a mess, the annot width cannot be set, well, it can - % but the appearance and text sizes get mixed up -% \setbox\scratchbox\vbox to \height{\forgetall\vskip#3\box\scratchbox\vss}% -% \global\setbox\PDFsymbolbox\vbox -% {\hsize#2% -% \forgetall -% \vsmash{\box\PDFsymbolbox} -% \box\scratchbox}% - % this may change when acrobat gets less bugged - \setbox\scratchbox\vbox to #3{\forgetall\vss\box\scratchbox}% - \wd\scratchbox#2% - \global\setbox\PDFsymbolbox\vbox - {\startoverlay{\box\PDFsymbolbox}{\box\scratchbox}\stopoverlay}% - \fi - \fi - % generic - \doifobjectreferencefoundelse{FDF}{c::\nofFDFcomments} - {\doPDFgetobjectreference{FDF}{c::\nofFDFcomments}\PDFobjectreference - \donetrue} - \donefalse - \createpdfannotationobject{FDF}{c:\nofFDFcomments}{\width}{\height} - {/Subtype /Text - \ifcase#5 \else/Open true\fi - % pdftex (efficient) - % \ifdone /Popup \PDFobjref\pdflastannot\fi - % generic (less efficient) - \ifdone /Popup \PDFobjectreference\fi - /Contents <\PDFdata> - \PDFidentifier - \FDFlayer - \PDFsymbol - \PDFattributes}% - \else - \insertpdfannotation{#2}{#3} - {/Subtype /Text - \ifcase#5 \else/Open true\fi - /Contents <\PDFdata> - \FDFlayer - \PDFsymbol - \PDFidentifier - \PDFattributes}% - \fi - \stopPDFsymbolappearance - \egroup} - -% symbols with a reasonable default of 18/24 pt - -\newbox\PDFsymbolbox - -\def\PDFsymbolNew {/Insert} -\def\PDFsymbolBalloon {/Comment} -\def\PDFsymbolAddition {/NewParagraph} -\def\PDFsymbolHelp {/Help} -\def\PDFsymbolParagraph {/Paragraph} -\def\PDFsymbolKey {/Key } - -\def\PDFsymbolGraph {/Graph} -\def\PDFsymbolPaperclip {/Paperclip} -\def\PDFsymbolAttachment{/Attachment} -\def\PDFsymbolTag {/Tag} - -\def\startPDFsymbolappearance - {\setbox\scratchbox\vbox to \totalheight \bgroup \vfill} - -\def\stopPDFsymbolappearance - {\egroup - \setbox\scratchbox\hbox{\lower\depth\box\scratchbox}% - \wd\scratchbox\width - \ht\scratchbox\height - \dp\scratchbox\depth - \box\scratchbox} - -\def\presetPDFsymbolappearance#1#2#3#4#5% symbol color width height depth - {\doifelsenothing{#1} - {\let\PDFattributes\empty} - {\def\PDFattributes{/C \FDFcolor{#1}}}% - \scratchdimen#3\edef\width {\the\scratchdimen}% - \scratchdimen#4\edef\height{\the\scratchdimen}% - \scratchdimen#5\edef\depth {\the\scratchdimen}% - \advance\scratchdimen\height\edef\totalheight{\the\scratchdimen}% - \doifelsenothing{#2} - {\let\PDFsymbol\empty} - {\ifundefined{PDFsymbol#2}% - \getfromcommacommand[#2][1]\let\PDFsymbolnormalsymbol\commalistelement - \getfromcommacommand[#2][2]\let\PDFsymboldownsymbol \commalistelement - \doifsymboldefinedelse\PDFsymbolnormalsymbol - {\doifsymboldefinedelse\PDFsymboldownsymbol - {\dopresetPDFsymbolappearance - \PDFsymbolnormalsymbol\PDFsymboldownsymbol} - {\dopresetPDFsymbolappearance - \PDFsymbolnormalsymbol\PDFsymbolnormalsymbol}} - {\doifsymboldefinedelse\PDFsymboldownsymbol - {\dopresetPDFsymbolappearance - \PDFsymboldownsymbol\PDFsymboldownsymbol} - {\let\PDFsymbol\empty}}% - \else - \def\PDFsymbol{/Name \getvalue{PDFsymbol#2} }% - \fi}} - -\def\dopresetPDFsymbolappearance#1#2% - {\dopresetfieldsymbol{#1}% - \dopresetfieldsymbol{#2}% - \setbox\scratchbox\hbox{\symbol[#1]}% - \edef\width {\the\wd\scratchbox}% - \edef\height{\the\ht\scratchbox}% - \edef\depth {\the\dp\scratchbox}% - \scratchdimen\height \advance\scratchdimen\depth - \edef\totalheight{\the\scratchdimen}% - \doPDFgetobjectreference{SYM}{#1}\FDFsymbolNappearance - \doPDFgetobjectreference{SYM}{#2}\FDFsymbolDappearance - \edef\PDFsymbol - {/AP <>}} - -%D Hooked into \CONTEXT, this special supports -%D -%D \starttyping -%D \startcomment -%D hello beautiful\\world -%D \stopcomment -%D -%D \startcomment[hello] -%D de \'e\'erste keer -%D the f\'irst time -%D \stopcommen -%D -%D \startcommentaar[hallo][color=green,width=4cm,height=3cm] -%D first -%D -%D second -%D \stopcommentaar -%D \stoptyping -%D -%D So, special characters, forced linebreaks using \type{\\} -%D and \type{\par} are handled in the appropriate way. - -%D \macros -%D {dosetuppageview} -%D -%D Because this command will seldom be called, we can permit -%D slow action processing. We need three settings, one for -%D direct \PDF\ inclusion, the other as \PDFTEX\ keyword, an -%D a last one for form. All determine in what way the -%D screen is adapted when going to a destination. Watch the -%D space. - -\def\PDFpageviewkey{fit} -\def\PDFpageviewwrd{/Fit} -\def\PDFpageview {/View [\PDFpageviewwrd] } -\def\PDFpagexyzspec{0 0 0} % hack, pdftex does handle this -\let\PDFpagexyzspec\empty % hack, pdftex does not accept spec - -\def\dosetuppageview#1% watch the v-h swapping here - {\processaction - [#1] - [ \v!fit=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit}, - \v!width=>\def\PDFpageviewkey {fith}\def\PDFpageviewwrd{/FitH}, - \v!height=>\def\PDFpageviewkey {fitv}\def\PDFpageviewwrd{/FitV}, - \v!minwidth=>\def\PDFpageviewkey{fitbh}\def\PDFpageviewwrd{/FitBH}, - \v!minheight=>\def\PDFpageviewkey{fitbv}\def\PDFpageviewwrd{/FitBV}, - \v!standard=>\def\PDFpageviewkey{xyz \PDFpagexyzspec}\def\PDFpageviewwrd{/XYZ \PDFpagexyzspec}, - \s!unknown=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit}]% - \edef\PDFpageview{/View [\PDFpageviewwrd]}} - -%D \macros -%D {setFDFkids} -%D -%D Clones as well as radiofields (which themselves can have -%D cloned components) need a list of kids. The next macro -%D builds one. - -\def\setFDFkids[#1][#2]% tag commalist - {\let\FDFkids\empty - \def\docommand##1% - {\doPDFgetobjectreference{FDF}{#1##1}\PDFobjectreference - \edef\FDFkids{\FDFkids\PDFobjectreference\space}}% - \@EA\processcommalist\@EA[#2]\docommand - \ifx\FDFkids\empty\else\edef\FDFkids{/Kids [\FDFkids]}\fi} - -%D \macros -%D {dopresetlinefield,dopresettextfield, -%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, -%D dopresetpushfield,dopresetcheckfield, -%D dopresetfield,dopresetradiorecord} -%D -%D I would say: read the \PDF\ reference manual first and see -%D what happens here next. Lucky us that they have so much in -%D common. - -\def\dopresetlinefield#1#2#3#4#5#6#7#8#9% - {\bgroup - \setFDFlayer\@@DriverFieldLayer - \setFDFswitches[#7]% - \setFDFattributes[#6]% - \setFDFalignment[#8]% - \setFDFactions[#9]% - \edef\FDFtext{\hexifiedPDFstring{#4}}% - \ifcase\currentFDFmode - \createpdfannotationobject{FDF}{#1}{#2}{#3} - {/Subtype /Widget /T (#1) /FT /Tx - /MaxLen \ifcase0#5 1000 \else#5 \fi - %/DV (#4) /V (#4) % value added - /DV <\FDFtext> /V <\FDFtext> - /Ff \FDFflag\space - /F \FDFplus\space - /DA (\FDFattributes) - \FDFlayer\space - \FDFsurroundings\space - /Q \FDFalign\space - \FDFactions}% - \registerFDFobject{#1}% - \or - \setFDFkids[kids:][\currentFDFkids]% - \createpdfdictionaryobject{FDF}{#1} - {/T (#1) /FT /Tx - /MaxLen \ifcase0#5 1000 \else#5 \fi - \FDFkids\space - %/DV (#4) /V (#4) % value added - /DV <\FDFtext> /V <\FDFtext> - /Ff \FDFflag\space - /F \FDFplus\space - /DA (\FDFattributes) - \FDFlayer\space - \FDFsurroundings\space - /Q \FDFalign\space - \FDFactions}% - \registerFDFobject{#1}% - \or - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference - /Ff \FDFflag\space - /F \FDFplus\space - /DA (\FDFattributes) - \FDFlayer\space - \FDFsurroundings\space - /Q \FDFalign\space - \FDFactions}% - \or - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference - /F \FDFplus - \FDFactions}% - \fi - \egroup} - -\def\dopresettextfield#1#2#3#4#5#6#7#8#9% - {\dopresetlinefield{#1}{#2}{#3}{#4}{#5}{#6}{MultiLine,#7}{#8}{#9}} - -\def\dopresetchoicefield#1#2#3#4#5#6#7#8% - {\bgroup - \setFDFlayer\@@DriverFieldLayer - \setFDFswitches[#6]% - \setFDFattributes[#5]% - \setFDFvalues[#7][#4]% - \setFDFactions[#8]% - \ifcase\currentFDFmode - \createpdfannotationobject{FDF}{#1}{#2}{#3} - {/Subtype /Widget - /T (#1) /FT /Ch - /DV (#4) /V (#4) - /Ff \FDFflag\space - /F \FDFplus\space - /DA (\FDFattributes) - \FDFlayer\space - \FDFsurroundings\space - /Opt [\FDFvalues] - \FDFactions}% - \registerFDFobject{#1}% - \or - \setFDFkids[kids:][\currentFDFkids]% - \createpdfdictionaryobject{FDF}{#1} - {/T (#1) /FT /Ch - \FDFkids\space - /DV (#4) /V (#4) - /Ff \FDFflag\space - /F \FDFplus\space - /DA (\FDFattributes) - \FDFlayer\space - \FDFsurroundings\space - /Opt [\FDFvalues] - \FDFactions}% - \registerFDFobject{#1}% - \or - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference - /Ff \FDFflag\space - /F \FDFplus\space - /DA (\FDFattributes) - \FDFlayer\space - \FDFsurroundings\space - \FDFactions}% - \or - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference - /F \FDFplus - \FDFactions}% - \fi - \egroup} - -\def\dopresetpopupfield#1#2#3#4#5#6#7#8% - {\dopresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,#6}{#7}{#8}} - -\def\dopresetcombofield#1#2#3#4#5#6#7#8% - {\dopresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,Edit,#6}{#7}{#8}} - -\newif\ifFDFvalues - -\def\doFDFpresetpushcheckfield#1#2#3#4#5#6#7#8% in acro<5 (\FDFdefault) - {\bgroup % in acro>5 /\FDFdefault - \setFDFlayer\@@DriverFieldLayer - \ifcase#8\relax\FDFvaluesfalse\else\FDFvaluestrue\fi - \setFDFswitches[#5]% - \setFDFactions[#7]% - \doifelse{#4}{1} - {\def\FDFdefault{On}} - {\def\FDFdefault{Off}}% - \ifcase\currentFDFmode - \doFDFappearance{On}{#6}{#8}% - \createpdfannotationobject{FDF}{#1}{#2}{#3} - {/Subtype /Widget /T (#1) /FT /Btn - \ifFDFvalues - /DV /\FDFdefault\space - /V /\FDFdefault\space - /AS /\FDFdefault\space - \fi - \FDFlayer - /Ff \FDFflag\space - /F \FDFplus\space - \FDFlayer\space - \FDFappearance\space -% /IF << /SW /N >> % strange, only works for stupid buttons - \FDFactions}% - \registerFDFobject{#1}% - \or % no appearance and layer ? - \setFDFkids[kids:][\currentFDFkids]% - \createpdfdictionaryobject{FDF}{#1} - {/T (#1) /FT /Btn - \FDFkids\space - \ifFDFvalues - /DV /\FDFdefault\space - /V /\FDFdefault\space - /AS /\FDFdefault\space - \fi - /Ff \FDFflag\space - /F \FDFplus\space - \FDFactions}% - \registerFDFobject{#1}% - \or - \doFDFappearance{On}{#6}{#8}% - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference\space - \ifFDFvalues - /DV /\FDFdefault\space - /V /\FDFdefault\space - /AS /\FDFdefault\space - \fi - /Ff \FDFflag\space - /F \FDFplus\space - \FDFlayer\space - \FDFappearance\space - \FDFactions}% - \or - \doFDFappearance{On}{#6}{#8}% - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference\space - /F \FDFplus\space - \ifFDFvalues - /DV /\FDFdefault\space - /V /\FDFdefault\space - /AS /\FDFdefault\space - \fi - \FDFlayer\space - \FDFappearance - \FDFactions}% - \fi - \egroup} - -\def\dopresetpushfield#1#2#3#4#5#6#7% - {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{PushButton,#5}{#6}{#7}{0}} - -\def\dopresetcheckfield#1#2#3#4#5#6#7% - {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{1}} - -\def\dopresetradiofield#1#2#3#4#5#6#7#8% - {\bgroup - \setFDFlayer\@@DriverFieldLayer - \FDFvaluestrue - \setFDFswitches[#5]% - \setFDFactions[#8]% - \doifelsenothing{#4} - {\def\FDFdefault{Off}} - {\def\FDFdefault{#4}}% - \@EA\aftersplitstring\FDFdefault\at=>\to\FDFdefaultvalue - \ifx\FDFdefaultvalue\empty\else\let\FDFdefault\FDFdefaultvalue\fi - \ifcase\currentFDFmode - \doFDFappearance{#1}{#7}{1}% - \doPDFgetobjectreference{FDF}{#6}\PDFobjectreference - \createpdfannotationobject{FDF}{#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference\space - /F \FDFplus\space - /AS /\FDFdefault\space - \FDFlayer\space - \FDFappearance\space - \FDFactions}% - \registerFDFobject{#1}% - \or - \setFDFkids[kids:][\currentFDFkids]% - \doPDFgetobjectreference{FDF}{#6}\PDFobjectreference - \createpdfdictionaryobject{FDF}{#1} - {/Parent \PDFobjectreference\space - \FDFkids\space - /F \FDFplus\space - \FDFactions}% - \registerFDFobject{#1}% - \or - %\doFDFappearance{#1}{#7}{1}% - \doFDFappearance{\currentFDFparent}{#7}{1}% - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue % nb - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference\space - /AS /\FDFdefault\space - /F \FDFplus\space - \FDFlayer\space - \FDFappearance\space - \FDFactions}% - \or - %\doFDFappearance{#1}{#7}{1}% - \doFDFappearance{\currentFDFparent}{#7}{1}% - \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference - %\global\objectreferencingtrue - \createpdfannotationobject{FDF}{kids:#1}{#2}{#3} - {/Subtype /Widget - /Parent \PDFobjectreference\space - /AS /\FDFdefault\space - /F \FDFplus\space - \FDFlayer\space - \FDFappearance\space - \FDFactions}% - \fi - \egroup} - -% Beware, RadiosInUnison is really needed in the pre 1.5/6 time this -% was the default but out of a sudden it's no longer the case. Also -% the NoToggleToOff interferes with kids of kids and both it will -% break older documents, i.e. so much for pdf as standard. With -% features like widgets we can probably best wait till adobe tools -% themselves support it because that's probably the moment that -% functionality gets frozen/becomes definitive. Actually, acrobat -% flattens the kids tree, so that's yet another situation. The -% interesting thing is that it worked ok in acrobat 2/3 but got bugged -% in later versions. [The rationale is in html compatibility, which -% seems to be more important than compatibility of documents, which in -% turn renders acrobat useless for forms.] Anyway, synchronization is -% broken or not depending on the combination pdfversion/acrobatversion. - -\def\dopresetradiorecord#1#2#3#4#5% - {\bgroup - % < pdf 1.5 (1.5 was broken) - % \setFDFswitches[Radio,NoToggleToOff,RadiosInUnison,#3]% - % > pdf 1.5 - \setFDFswitches[Radio,RadiosInUnison,#3]% - % older, else fatal error - % \setFDFkids[#4][]% - % newer - \setFDFvalues[#4][#2]% inits kidlist - \expanded{\setFDFkids[][\FDFkidlist]}% - % - \setFDFactions[#5]% - \createpdfdictionaryobject{FDF}{#1} - {%/Subtype /Widget - /FT /Btn /T (#1) /Rect [0 0 0 0] - % used to be this - % /V (#2) - % then this - % /DV (#2) - % since this bomded in 5 - % /V (#2) - % and now finally this works - /H /N - % /opt is buggy in 5.05, only works once, sigh - %\ifx\FDFfirstvalues\FDFsecondvalues - /V /#2 - %\else - % /V /\FDFdefaultindex\space - % /Opt [\FDFsecondvalues] - %\fi - /Ff \FDFflag\space - /F \FDFplus\space - \FDFkids\space - \FDFactions}% - \egroup} - -%D At the cost of some more references, we can save bytes, -%D by sharing appearance dictionaries. This code needs more -%D documentation. Surprise: - -\def\dodoFDFappearance#1#2% - {\ifx#2\empty\else - \dogetcommacommandelement1\from#2\to\commalistelement - \ifx\commalistelement\empty\else - \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference - \edef\N{\ifFDFvalues\N /#1 \fi\PDFobjectreference\space}% - \fi - \dogetcommacommandelement2\from#2\to\commalistelement - \ifx\commalistelement\empty\else - \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference - \edef\R{\ifFDFvalues\R /#1 \fi\PDFobjectreference\space}% - \fi - \dogetcommacommandelement3\from#2\to\commalistelement - \ifx\commalistelement\empty\else - \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference - \edef\D{\ifFDFvalues\D /#1 \fi\PDFobjectreference\space}% - \def\FDFappearance{/H /P }% - \fi - \fi} - -\def\redoFDFappearance#1% - {\ifx#1\empty\else - \dogetcommacommandelement3\from#1\to\commalistelement - \ifx\commalistelement\empty\else - \def\FDFappearance{/H /P }% - \fi - \fi} - -\def\doFDFappearance#1#2#3% - {\ifcase#3\relax % push only field - \edef\yes{#2}% - \let\no\empty - \else % on / off field - \dogetcommacommandelement1\from#2,\to\yes - \dogetcommacommandelement2\from#2,\to\no - \fi - \def\FDFappearance{/H /N}% - \doifobjectfoundelse{FDF}{ap:#1:\yes:\no} - {\redoFDFappearance\yes - \redoFDFappearance\no} - {\presetobject{FDF}{ap:#1:\yes:\no}% funny hack - \let\N\empty\let\R\empty\let\D\empty - \dodoFDFappearance{#1}\yes - \dodoFDFappearance{Off}\no - \createpdfdictionaryobject{FDF}{ap:#1:\yes:\no} - {\ifx\N\empty\else/N \ifFDFvalues<<\N>>\else\N\fi\fi - \ifx\R\empty\else/R \ifFDFvalues<<\R>>\else\R\fi\fi - \ifx\D\empty\else/D \ifFDFvalues<<\D>>\else\D\fi\fi}}% - \doPDFgetobjectreference{FDF}{ap:#1:\yes:\no}\PDFobjectreference - \edef\FDFappearance{\FDFappearance /AP \PDFobjectreference}} - -\def\doFDFdefault#1#2% - {\doifelse{#2}{1}{\def\FDFdefault{On}}{\def\FDFdefault{Off}}} - -%D Layer support: - -\def\setFDFlayer#1% todo : \ifx\PDFobjectreference\noPDFobjectreference ipv found - {\letempty\FDFlayer - \doifsomething{#1}% - {\checkproperty[#1]% == \dodocheckproperty\@@DriverFieldLayer - \doifobjectreferencefoundelse{PDLN}{#1} - {\doPDFgetobjectreference{PDLN}{#1}\!!stringa % we need to avoid a clash with other macros - \edef\FDFlayer{/OC \!!stringa}}% - \donothing}} - -%D The three appearances {\em normal}, \type{roll over} and -%D \type{push down} are passed as comma separated triplets, -%D that is, the second argument can look like: -%D -%D \starttyping -%D {yes,ok,fine},{no,rubish,awful} -%D \stoptyping - -%D \macros -%D {dodefinefieldset,dogetfieldset,doiffieldset} -%D -%D Field sets, the ones we use in submitting and resetting -%D fields, are implemented using the next low level specials: -%D -%D \starttyping -%D \doFDFdefinefieldset{TAG}{name,name,...} -%D \doFDFgetfieldset{TAG} -%D \doiffieldset{TAG}{sequence} -%D \stoptyping - -\def\dodefinefieldset#1#2% tag commalist - {\let\FDFfieldset\empty - \def\docommand##1% - {\doPDFgetobjectreference{FDF}{##1}\PDFobjectreference - \edef\FDFfieldset{\FDFfieldset\PDFobjectreference\space}}% - \processcommacommand[#2]\docommand % nb: command - \setevalue{FDF:set:#1}{\FDFfieldset}} - -\def\dogetfieldset#1% - {\getvalue{FDF:set:#1}} - -\def\doiffieldset#1#2% - {\ifundefined{FDF:set:#1}\else#2\fi} - -%D \macros -%D {defaultobjectreference,doPDFgetobjectreference} -%D -%D Because in \PDFTEX\ we have to construct the object -%D references \type{N 0 R}, we can default to the non existing -%D zero object number. - -\def\defaultobjectreference#1#2% - {0} - -\def\doPDFgetobjectreference#1#2#3% - {\dogetobjectreference{#1}{#2}#3% - \edef#3{\ifx#3\empty null\else\PDFobjref{#3}\fi}} - -\def\doPDFgetobjectnumber#1#2#3% - {\dogetobjectreference{#1}{#2}#3% - \edef#3{\ifx#3\empty 0\else#3\fi}} - -\def\doPDFgetobjectpage#1#2#3% - {\dogetobjectreferencepage{#1}{#2}#3% - \ifx#3\empty\def#3{1}\fi} - -\def\doPDFgetobjectpagereference#1#2#3% - {\dogetobjectreferencepage{#1}{#2}#3% - \ifx#3\empty - \doPDFgetpagereference\realfolio#3% - \else - \doPDFgetpagereference#3#3% we assume that #3 gets expanded - \fi} - -\def\doPDFgetpagereference#1#2% number macro - {\edef#2{\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi}} - -\def\thePDFpagereference#1#2% number macro - {\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi} - -%D \macros -%D {initializePDFnegative,initializePDFoverprint} -%D -%D Here follow some rather obscure macros. They will only -%D come into action when one wants negated output. - -\def\initializePDFnegative - {\immediate\pdfobj stream attr {/FunctionType 4 /Range [0 1] /Domain [0 1]} {{1 exch sub}}% - \immediate\pdfobj{<>}% - \appendtoPDFdocumentextgstates{/GSnegative \PDFobjref\pdflastobj}% - \immediate\pdfobj{<>}% - \appendtoPDFdocumentextgstates{/GSpositive \PDFobjref\pdflastobj}% - \global\let\initializePDFnegative\relax} - -\def\initializePDFoverprint - {\immediate\pdfobj{<>}% /op defaults to /OP - \appendtoPDFdocumentextgstates{/GSknockout \PDFobjref\pdflastobj}% - \immediate\pdfobj{<>}% /op defaults to /OP - \edef\PDFobjectreferenceB{\the\pdflastobj}% - \appendtoPDFdocumentextgstates{/GSoverprint \PDFobjref\pdflastobj}% - \global\let\initializePDFoverprint\relax} - -%D File embedding. Storing the stream identifier is needed -%D to get access to the number. When typeset, the user can -%D feed this number to \type {pdftosrc} and filter the -%D file from the \PDF\ file. - -\let\PDFlaststreamobject \s!unknown -%def\PDFlaststreamreference{0 0 R} - -\def\doPDFfilestreamobject#1#2#3#4% - {\immediate\pdfobj stream file{#4}% - \edef\PDFlaststreamobject{\the\pdflastobj}% - \dosetobjectreference{PDFFS}{#2}{\PDFlaststreamobject}% - \createpdfdictionaryobject{#1}{#2}{/Type /Filespec /F (#3) /EF <>}} - -\def\doPDFgetfilestreamreference#1#2% - {\doPDFgetobjectreference{PDFFS}{#1}#2} - -\def\doPDFfilestreamidentifier#1% - {\doifsomething{#1} - {\doPDFgetfilestreamreference{#1}\PDFobjectreference - \@EA\beforesplitstring\PDFobjectreference\at{ }\to\PDFlaststreamobject - \PDFlaststreamobject}} - -% MP ? - - \def\setMPPDFobject#1#2% resources boxnumber - {\the\everyPDFxform - \finalizeobjectbox{#2}% - \immediate\pdfxform resources{#1}#2% - \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}} - - \let\getMPPDFobject\relax - - \def\doinsertMPfile#1% - {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}} - -%D Even newer trickery: - -% resource -> prop -> mc's -> OCG|OCMD (nested) -% ocg: -% /Intent/Design -% ocmd -% /P /AllOn -% kan zelf ocmd bevatten - -\let\PDFtextlayers\empty -\let\PDFpagelayers\empty -\let\PDFhidelayers\empty -\let\PDFvidelayers\empty - -\def\dostartlayer#1{\PDFcode{/OC /#1 BDC}} -\def\dostoplayer {\PDFcode {EMC}} - -\def\dodefineviewerlayer#1#2#3#4#5% tag title visible type printable - {\createpdfdictionaryobject{PDLN}{#1} - {/Type /OCG - \ifcase#4 \or - /Intent /Design % disable layer hiding by user - \fi - \ifnum#5=\zerocount - /Usage << /Print << /PrintState /OFF >> >> % printable or not - \fi - /Name (#2)}% - \doPDFgetobjectreference{PDLN}{#1}\PDFobjectreference - \xdef\PDFtextlayers{\PDFtextlayers\space\PDFobjectreference}% - \doifelse{#3}\v!start - {\xdef\PDFvidelayers{\PDFvidelayers\space\PDFobjectreference}}% - {\xdef\PDFhidelayers{\PDFhidelayers\space\PDFobjectreference}}% - \createpdfdictionaryobject{PDLD}{#1} - {/Type /OCMD - /OCGs [\PDFobjectreference]}% - \doPDFgetobjectreference{PDLD}{#1}\PDFobjectreference - \xdef\PDFpagelayers{\PDFpagelayers\space /#1 \PDFobjectreference}} - -\def\flushPDFtextlayers - {\ifx\PDFtextlayers\empty \else - \driverreferenced \createpdfarrayobject{PDF}{textlayers}{\PDFtextlayers}% - \doPDFgetobjectreference{PDF}{textlayers}\!!stringa - \ifx\PDFvidelayers\empty - \def\!!stringb{[null]}% - \else - \driverreferenced \createpdfarrayobject{PDF}{videlayers}{\PDFvidelayers}% - \doPDFgetobjectreference{PDF}{videlayers}\!!stringb - \fi - \ifx\PDFhidelayers\empty - \def\!!stringc{[null]}% - \else - \driverreferenced \createpdfarrayobject{PDF}{hidelayers}{\PDFhidelayers}% - \doPDFgetobjectreference{PDF}{hidelayers}\!!stringc - \fi - \appendtopdfcatalog - {/OCProperties - << % display in menu - /D << /Order \!!stringa - /ON \!!stringb - /OFF \!!stringc >> - % used properties - /OCGs \!!stringa >>}% - \globallet\flushPDFtextlayers\relax - \fi} - -\def\flushPDFpagelayers - {\ifx\PDFpagelayers\empty \else - \appendtopdfpageresources{/Properties <<\PDFpagelayers>>}% - \fi} - -\def\PDFlayeractionlist{null} - -\def\PDFexecutehidelayer {/SetOCGState /State [/OFF \PDFlayeractionlist]} -\def\PDFexecutevidelayer {/SetOCGState /State [/ON \PDFlayeractionlist]} -\def\PDFexecutetogglelayer {/SetOCGState /State [/Toggle \PDFlayeractionlist]} - -\def\domakeviewerlayerlist#1% - {\bgroup - \globallet\PDFlayeractionlist\empty - \def\docommand##1% - {\doPDFgetobjectreference{PDLN}{##1}\PDFobjectreference - \xdef\PDFlayeractionlist{\PDFlayeractionlist\space\PDFobjectreference}}% - \processcommalist[#1]\docommand - \egroup} - -%D Something rather pdf dependent: - -% #1 => 1=fill 2=stroke 3=strokedfill 4=invisible -% #2 => linewidth -% #3 => spacing (beware, one needs to set the hsize as well) - -\def\dostartfonteffect#1#2#3% - {\ifdim#2>\zeropoint - \PointsToBigPoints{#2}\ascii - \PDFcode{\ascii\space w}% - \fi - \ifdim#3\points=\onepoint\else - \scratchdimen#3\points - \PDFcode{\withoutpt{\the\scratchdimen}\space Tc}% - \fi - \PDFcode{\purenumber#1 Tr}} - -\def\dostopfonteffect - {\PDFcode{1 w 0 Tc 0 Tr}} - -%D Handy for the \METAPOST\ to \PDF\ converter: - -\appendtoksonce - \collectPDFresources - \global\let\currentPDFresources\collectedPDFresources -\to \everyPDFxform - -\let\collectedPDFresources\empty - -\def\collectPDFresources % suboptimal - {\doifobjectreferencefoundelse{FDF}{docushades} % redundant, we have an reserved object now - {\doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference - \xdef\collectedPDFresources{\collectedPDFresources/Shading \PDFobjectreference}}\donothing - \doifobjectreferencefoundelse{FDF}{docuextgstates} - {\doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference - \xdef\collectedPDFresources{\collectedPDFresources/ExtGState \PDFobjectreference}}\donothing - \doifobjectreferencefoundelse{FDF}{colorspaces} - {\doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference - \xdef\collectedPDFresources{\collectedPDFresources/ColorSpace \PDFobjectreference}}\donothing - \global\let\collectPDFresources\relax} - -\appendtoks - \flushPDFpagelayers - \flushJSpreamble - \flushJSpreamble - \checkPDFextgstates - \checkPDFcolorspaces - \checkPDFshades - \checkPDFpageactions - \fakePDFpagedestination - \flushPDFpageboxes - \addPDFdocumentinfo -\to \everybackendshipout - -\appendtoks - \flushPDFtextlayers - \finalflushJSpreamble -\to \everylastbackendshipout - -%D Temporary hack: - -\def\TransparencyHack % png: /CS /DeviceRGB /I true - {\appendtoksonce - \appendtopdfpageattributes{/Group << /S /Transparency /I true /K true>>}% - \to \everyPDFxform - \appendtoksonce - \appendtopdfpageattributes{/Group << /S /Transparency /I true /K true>>}% - \to \everyshipout} - -\protect \endinput diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua new file mode 100644 index 000000000..6f098a271 --- /dev/null +++ b/tex/context/base/buff-ini.lua @@ -0,0 +1,472 @@ +if not modules then modules = { } end modules ['buff-ini'] = { + version = 1.001, + comment = "companion to core-buf.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- ctx lua reference model / hooks and such +-- to be optimized + +-- redefine buffers.get + +buffers = { } +buffers.data = { } +buffers.hooks = { } +buffers.flags = { } +buffers.commands = { } +buffers.visualizers = { } + +-- if needed we can make 'm local + +local utf = unicode.utf8 + +local concat, texsprint, texprint, texwrite = table.concat, tex.sprint, tex.print, tex.write +local utfbyte, utffind, utfgsub = utf.byte, utf.find, utf.gsub +local type, next = type, next +local byte, sub, find, char, gsub, rep, lower = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local ctxcatcodes = tex.ctxcatcodes + +local data, commands, flags, hooks, visualizers = buffers.data, buffers.commands, buffers.flags, buffers.hooks, buffers.visualizers + +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 = bufferdata:sub(1,#bufferdata-1) + else + dn = dn .. "\n" .. bufferdata:sub(1,#bufferdata-1) + end + dn = dn:gsub("[\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 + +commands.no_break = "\\doverbatimnobreak" +commands.do_break = "\\doverbatimgoodbreak" +commands.begin_of_line_command = "\\doverbatimbeginofline" +commands.end_of_line_command = "\\doverbatimendofline" +commands.empty_line_command = "\\doverbatimemptyline" + +function buffers.verbatimbreak(n,m) + if flags.optimize_verbatim then + if n == 2 or n == m then + texsprint(commands.no_break) + else + texsprint(commands.do_break) + end + end +end + +function buffers.strip(lines) + local first, last = 1, #lines + for i=first,last do + if #lines[i] == 0 then + first = first + 1 + else + break + end + end + for i=last,first,-1 do + if #lines[i] == 0 then + last = last - 1 + else + break + end + end + return first, last, last - first + 1 +end + +function buffers.type(name) + local lines = data[name] + local action = buffers.typeline + if lines then + if type(lines) == "string" then + lines = lines:splitlines() + end + local line, n = 0, 0 + local first, last, m = buffers.strip(lines) + for i=first,last do + n, line = action(lines[i], n, m, line) + end + end +end + +function buffers.loaddata(filename) -- this one might go away + -- this will be cleaned up when we have split supp-fil completely + -- instead of half-half + local ok, str, n = resolvers.loaders.tex(filename) + if not str then + ok, str, n = resolvers.loaders.tex(file.addsuffix(filename,'tex')) + end + return str or "" +end + +function buffers.typefile(name) -- still somewhat messy, since name can be be suffixless + local str = buffers.loaddata(name) + if str and str~= "" then + local lines = str:splitlines() + local line, n, action = 0, 0, buffers.typeline + local first, last, m = buffers.strip(lines) + for i=first,last do + n, line = action(lines[i], n, m, line) + end + end +end + +function buffers.typeline(str,n,m,line) + n = n + 1 + buffers.verbatimbreak(n,m) + if str:find("%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 + +function buffers.save(name) + if not name or name == "" then + name = tex.jobname + end + local b, f = data[name], tex.jobname .. "-" .. name .. ".tmp" + b = (b and type(b) == "table" and table.join(b,"\n")) or b or "" + io.savedata(f,b) +end + +local printer = (lpeg.linebyline/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 + printer:match(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 shoul always store a buffer as table so + -- that we can pass if directly + local t = { } + if type(names) == "table" then + for i=1,#names do + local c = content(names[i],separator) + if c ~= "" then + t[#t+1] = c + end + end + else + for name in names:gmatch("[^,%s]+") do + local c = content(name,separator) + if c ~= "" then + t[#t+1] = c + end + end + end + return concat(t,separator or "\r") -- "\n" is safer due to comments and such +end + +function buffers.feedback(names,separator) + texsprint(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 _,v in ipairs(b) do + if v == "" then + texsprint(ctxcatcodes,"[crlf]\\par ") -- space ? + else + texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte)),"\\par") + end + end + else + texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte))) + end + end +end + +-- maybe just line(n,str) empty(n,str) + +visualizers.default = visualizers.default or { } +visualizers.tex = visualizers.tex or { } +visualizers.mp = visualizers.mp or { } + +visualizers.escapetoken = nil +visualizers.tablength = 7 + +visualizers.enabletab = true -- false +visualizers.enableescape = false +visualizers.obeyspace = true + +local default = visualizers.default + +function visualizers.reset() +--~ visualizers.enabletab = false +--~ visualizers.enableescape = false +--~ buffers.currentvisualizer = 'default' +end + +buffers.currentvisualizer = 'default' -- could become a local + +function buffers.setvisualizer(str) + buffers.currentvisualizer = lower(str) + local v = visualizers[buffers.currentvisualizer] + if not v then + buffers.currentvisualizer = 'default' + elseif v.reset then + v.reset() + end +end + +function buffers.doifelsevisualizer(str) + cs.testcase((str ~= "") and (visualizers[lower(str)] ~= nil)) +end + +-- calling routines, don't change + +function hooks.flush_line(str,nesting) + str = gsub(str," *[\n\r]+ *"," ") ; -- semi colon needed + (visualizers[buffers.currentvisualizer].flush_line or default.flush_line)(str,nesting) +end + +function hooks.begin_of_line(n) + (visualizers[buffers.currentvisualizer].begin_of_line or default.begin_of_line)(n) +end + +function hooks.end_of_line() + (visualizers[buffers.currentvisualizer].end_of_line or default.end_of_line)() +end + +function hooks.empty_line() + (visualizers[buffers.currentvisualizer].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 (visualizers[buffers.currentvisualizer].line or default.line)(str) +end + +-- defaults + +function default.begin_of_line(n) + texsprint(ctxcatcodes, commands.begin_of_line_command,"{",n,"}") +end + +function default.end_of_line() + texsprint(ctxcatcodes,commands.end_of_line_command) +end + +function default.empty_line() + texsprint(ctxcatcodes,commands.empty_line_command) +end + +function default.line(str) + return str +end + +function default.flush_line(str) + str = str:gsub(" *[\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 + +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 = str:gsub(" *[\n\r]+ *"," ") + local result, c, nested, i = "", "", 0, 1 + 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 c:find("%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)) .. " " .. string.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 diff --git a/tex/context/base/buff-ini.mkii b/tex/context/base/buff-ini.mkii new file mode 100644 index 000000000..0f0655ea1 --- /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]}% + \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}% + \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}% + \getparameters[\??bu#1][#2]% + \fi} + +\def\definebuffer + {\dodoubleempty\dodefinebuffer} + +\def\getbuffer + {\dodoubleempty\dogetbuffer} + +\def\dogetbuffer[#1][#2]% + {\ifsecondargument + \dodogetbuffer[#1][#2]% + \else + \dodogetbuffer[][#1]% + \fi} + +\def\dogetbufferasis{\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing}% + +\def\dodogetbuffer[#1][#2]% + {\getvalue{\??bu#1\c!before}% + \dobuffer{16}{#2}\dogetbufferasis + \getvalue{\??bu#1\c!after}} + +\def\typebuffer + {\dodoubleempty\dotypebuffer} + +\def\dogetfilebuffer{\typefile{\TEXbufferfile{\currentbuffer}}} + +\def\dotypebuffer[#1][#2]% + {\iffirstargument + \dobuffer{17}{#1}\dogetfilebuffer + \else + \dobuffer{17}{#2}\dogetfilebuffer + \fi} + +\def\dobuffer#1#2#3% + {\doifelsenothing{#2} + {\dodobuffer#3\jobname} + {\processcommalist[#2]{\dodobuffer#3}}} + +\def\dodobuffer#1#2% command name + {\pushmacro\currentbuffer + \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}% + \beginrestorecatcodes + #1% + \endrestorecatcodes + \popmacro\currentbuffer} + +\def\processTEXbuffer{\getbuffer} % handy + +% seldom used, only in a few projects that demanded more speed + +\def\dostartmemorybuffer + {\dosingleempty\dostartmemorybuffer} + +\long\def\dostartmemorybuffer[#1]#2\stopbuffer + {\setbuffer[#1]#2\endbuffer} + +\let\dostartfilebuffer\startbuffer + +\def\usememorybuffers{\let\startbuffer\dostartmemorybuffer} +\def\usefilebuffers {\let\startbuffer\dostartfilebuffer} + +% this features is soldom used (complex examns where we need to fetch +% special parts of a text +% +% this is not yet supported in mkiv (relatively easy to do but there +% we don't have the par tags but need to grab 'm + +\def\skippedbufferparagraphs{0} + +\let\startbufferparagraph\relax +\let\stopbufferparagraph \par % \relax + +\newcount\currentbufferparagraph + +\def\getbufferparagraphs + {\dodoubleempty\dogetbufferparagraphs} + +\def\dosetbufferoffset#1% + {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}} + {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}} + {\currentbufferparagraph \zerocount}% + \relax} + +\def\dogetbufferparagraphs[#1][#2]% + {\iffirstargument + \ifsecondargument + \dosetbufferoffset{#1}% + \doifelse{#2}\v!all + {\def\startbufferparagraph{\normalbufferparagraph{#1}}} + {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}% + \def\stopbufferparagraph{\dostopbufferparagraph{#1}}% + \def\next{\getparagraphedbuffer[#1]}% + \else + \dosetbufferoffset\empty + \def\startbufferparagraph{\filterbufferparagraph{}{#1}}% + \def\stopbufferparagraph{\dostopbufferparagraph{}}% + \def\next{\getparagraphedbuffer[]}% + \fi + \else + \dosetbufferoffset\empty + \def\startbufferparagraph{\normalbufferparagraph{}}% + \def\stopbufferparagraph{\dostopbufferparagraph{}}% + \def\next{\getparagraphedbuffer[]}% + \fi + \next} + +\def\dogetparagraphbuffer{\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing} + +\def\getparagraphedbuffer[#1]% + {\dobuffer{16}{#1}\dogetparagraphbuffer} + +\def\dostopbufferparagraph#1% + {\getvalue{\??bu#1\c!after}\par} + +\def\dostartbufferparagraph#1% + {\par\getvalue{\??bu#1\c!before}} + +\def\normalbufferparagraph + {\advance\currentbufferparagraph \plusone + \ifnum\currentbufferparagraph>\zerocount + \expandafter\dostartbufferparagraph + \else + \expandafter\gobbleoneargument + \fi} + +\def\filterbufferparagraph#1#2% + {\advance\currentbufferparagraph \plusone + \ifcase\currentbufferparagraph + \@EA\gobblebufferparagraph + \else + \doifinsetelse{\the\currentbufferparagraph}{#2} + {\@EA\dostartbufferparagraph} + {\@EA\fakebufferparagraph}% + \fi + {#1}} + +\long\def\gobblebufferparagraph#1#2\stopbufferparagraph + {} + +\def\fakebufferparagraph#1% + {\bgroup + \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}% + \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}} + +% definitions + +\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes] + +\setupbuffer + [\c!paragraph=\v!no, + \c!before=, + \c!after=] + +\protect \endinput diff --git a/tex/context/base/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv new file mode 100644 index 000000000..c9c1ae052 --- /dev/null +++ b/tex/context/base/buff-ini.mkiv @@ -0,0 +1,314 @@ +%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} + +\ifdefined\doinitializeverbatim \else% temp hack + \ifdefined\mkinitializeverbatim + \let\doinitializeverbatim\mkinitializeverbatim + \else + \def\doinitializeverbatim{\tttf} + \fi +\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} + +\def\setupbuffer + {\dodoubleempty\dosetupbuffer} + +\def\dosetupbuffer[#1][#2]% + {\ifsecondargument + \getparameters[\??bu#1][#2]% + \else + \getparameters[\??bu][#1]% + \fi} + +\def\dodefinebuffer[#1][#2]% + {\iffirstargument % else problems + \doglobal\increment\nofdefinedbuffers + \letvalue{\??bu#1\c!number }\nofdefinedbuffers + \letvalue{\??bu#1\c!paragraph}\v!no + \setevalue{\e!start#1}{\noexpand\dostartbuffer[#1][def-\nofdefinedbuffers][\e!start#1][\e!stop#1]}% + \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}% + \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}% + \getparameters[\??bu#1][#2]% + \fi} + +\def\definebuffer + {\dodoubleempty\dodefinebuffer} + +\def\getbuffer + {\dodoubleempty\dogetbuffer} + +\def\dogetbuffer[#1][#2]% + {\ifsecondargument + \dodogetbuffer[#1][#2]% + \else + \dodogetbuffer[][#1]% + \fi} + +\def\dogetbufferasis{\ctxlua{buffers.get("\currentbuffer")}} + +\def\dodogetbuffer[#1][#2]% + {\getvalue{\??bu#1\c!before}% + \dobuffer{16}{#2}\dogetbufferasis + \getvalue{\??bu#1\c!after}} + +\def\typebuffer + {\dodoubleempty\dotypebuffer} + +\def\doprocessbufferverbatim + {\doinitializeverbatim + \ctxlua{buffers.type("\currentbuffer")}} + +\def\doprocessbufferlinesverbatim#1#2#3% + {#2% + % todo, set up numbers + \doinitializeverbatim + \ctxlua{buffers.type("\currentbuffer")} + #3} + +\def\doifelsebuffer#1% + {\ctxlua{buffers.doifelsebuffer("#1")}} + +\def\dodotypebuffer#1#2#3% see dodotypefile + {\doifelsebuffer{#3} + {\dosometyping{#1}{#2}{#3}\doprocessbufferverbatim\doprocessbufferlinesverbatim} + {\reporttypingerror{#3}}} + +\def\dotypefilebuffer{\dodotypebuffer{\v!file}{}{\currentbuffer}}% + +\def\dotypebuffer[#1][#2]% + {\iffirstargument + \dobuffer{17}{#1}\dotypefilebuffer + \else + \dobuffer{17}{#2}\dotypefilebuffer + \fi} + +\def\dobuffer#1#2#3% + {\doifelsenothing{#2} + {\dodobuffer#3\jobname} + {\processcommalist[#2]{\dodobuffer#3}}} + +\def\dodobuffer#1#2% command name + {\pushmacro\currentbuffer + \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}% + #1% + \popmacro\currentbuffer} + +\def\processTEXbuffer{\getbuffer} % handy + +% extras: + +\def\inspectbuffer + {\dosingleempty\doinspectbuffer} + +\def\doinspectbuffer[#1]% + {\setcurrentbuffer{#1}% + \ctxlua{buffers.inspect("\currentbuffer")}} + +% seldom used, only in a few projects that demanded more speed + +\let\usememorybuffers\relax +\let\usefilebuffers \relax + +% this features is soldom used (complex examns where we need to fetch +% special parts of a text +% +% this is not yet supported in mkiv (relatively easy to do but there +% we don't have the par tags but need to grab 'm + +\def\skippedbufferparagraphs{0} + +\let\startbufferparagraph\relax +\let\stopbufferparagraph \par % \relax + +\newcount\currentbufferparagraph + +\def\getbufferparagraphs + {\dodoubleempty\dogetbufferparagraphs} + +\def\dosetbufferoffset#1% + {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}} + {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}} + {\currentbufferparagraph \zerocount}% + \relax} + +\def\dogetbufferparagraphs[#1][#2]% + {\iffirstargument + \ifsecondargument + \dosetbufferoffset{#1}% + \doifelse{#2}\v!all + {\def\startbufferparagraph{\normalbufferparagraph{#1}}} + {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}% + \def\stopbufferparagraph{\dostopbufferparagraph{#1}}% + \def\next{\getparagraphedbuffer[#1]}% + \else + \dosetbufferoffset\empty + \def\startbufferparagraph{\filterbufferparagraph{}{#1}}% + \def\stopbufferparagraph{\dostopbufferparagraph{}}% + \def\next{\getparagraphedbuffer[]}% + \fi + \else + \dosetbufferoffset\empty + \def\startbufferparagraph{\normalbufferparagraph{}}% + \def\stopbufferparagraph{\dostopbufferparagraph{}}% + \def\next{\getparagraphedbuffer[]}% + \fi + \next} + +\def\dotypeparagraphbuffer{\ctxlua{buffers.get("\currentbuffer")}} + +\def\getparagraphedbuffer[#1]% + {\dobuffer{16}{#1}\dotypeparagraphbuffer} + +\def\dostopbufferparagraph#1% + {\getvalue{\??bu#1\c!after}\par} + +\def\dostartbufferparagraph#1% + {\par\getvalue{\??bu#1\c!before}} + +\def\normalbufferparagraph + {\advance\currentbufferparagraph \plusone + \ifnum\currentbufferparagraph>\zerocount + \expandafter\dostartbufferparagraph + \else + \expandafter\gobbleoneargument + \fi} + +\def\filterbufferparagraph#1#2% + {\advance\currentbufferparagraph \plusone + \ifcase\currentbufferparagraph + \@EA\gobblebufferparagraph + \else + \doifinsetelse{\the\currentbufferparagraph}{#2} + {\@EA\dostartbufferparagraph} + {\@EA\fakebufferparagraph}% + \fi + {#1}} + +\long\def\gobblebufferparagraph#1#2\stopbufferparagraph + {} + +\def\fakebufferparagraph#1% + {\bgroup + \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}% + \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}} + +% definitions + +\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes] + +\setupbuffer + [\c!paragraph=\v!no, + \c!before=, + \c!after=] + +% only mkiv: + +\def\savebuffer{\dosingleempty\dosavebuffer} +\def\dosavebuffer[#1]{\ctxlua{buffers.save("#1")}} + +\protect \endinput diff --git a/tex/context/base/buff-ver.mkii b/tex/context/base/buff-ver.mkii new file mode 100644 index 000000000..c9ad8cbc9 --- /dev/null +++ b/tex/context/base/buff-ver.mkii @@ -0,0 +1,1334 @@ +%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.tex\to\filename + \readsysfile\filename\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 + {% \language\minusone % extra bonus, the \null should do the job too + \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip + \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}% + \spaceskip.5em\relax} + +\unexpanded\def\typ + {\bgroup + \let\@@tylines\v!hyphenated + \futurelet\next\dodotype} + +%D \macros +%D {tex,arg,mat,dis} +%D +%D Sometimes, for instance when we pass verbatim text as an +%D argument, the fixed \CATCODES\ interfere with our wishes. An +%D experimental implementation of character by character +%D processing of verbatim text did overcome this limitation, +%D but we've decided not to use that slow and sometimes +%D troublesome solution. Instead we stick to some 'old' +%D \CONTEXT\ macros for typesetting typical \TEX\ characters. +%D +%D The next implementation is more clear but less versatile, +%D so we treated it for a beter one. +%D +%D \starttyping +%D \def\dospecialtype#1#2% +%D {\bgroup +%D \initializetype +%D \catcode`\{=\@@begingroup +%D \catcode`\}=\@@endgroup +%D \def\dospecialtype% +%D {\def\dospecialtype{#2\egroup}% +%D \bgroup +%D \aftergroup\dospecialtype +%D #1}% +%D \afterassignment\dospecialtype +%D \let\next=} +%D +%D \unexpanded\def\tex{\dospecialtype\texescape\relax} +%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument} +%D \unexpanded\def\mat{\dospecialtype\$\$} +%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}} +%D \stoptyping + +\def\setgroupedtype + {\let\currenttypingclass\??ty + \initializetype + \verbatimcolor + %\setcatcodetable \typcatcodesa + \catcode`\{=\@@begingroup + \catcode`\}=\@@endgroup} + +\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}} +\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}} +\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}} +\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}} + +%D \macros +%D {starttyping} +%D +%D Display verbatim is realized far more easy, which is mostly +%D due to the fact that we use \type{\stop...} as delimiter. +%D The implementation inherits some features, for instance the +%D support of linenumbering, which can best be studied in the +%D documented support module. + +\let\currenttyping \empty +\let\currenttypingclass\??ty % saveguard + +% \def\typingparameter#1% +% {\executeifdefined +% {\currenttypingclass\currenttyping#1}% +% {\executeifdefined{\currenttypingclass#1}\empty}} + +\def\typingparameter#1% + {\ifcsname\currenttypingclass\currenttyping#1\endcsname + \csname\currenttypingclass\currenttyping#1\endcsname + \else\ifcsname\currenttypingclass#1\endcsname + \csname\currenttypingclass#1\endcsname + \fi\fi} + +\def\settypingparameter#1#2% + {\setvalue{\currenttypingclass\currenttyping#1}{#2}} + +\def\setxtypingparameter#1#2% + {\setxvalue{\currenttypingclass\currenttyping#1}{#2}} + +% \def\initializetyping +% {%\donefalse +% \switchtobodyfont[\typingparameter\c!bodyfont]% +% \donefalse +% \scratchskip\typingparameter\c!oddmargin\relax +% \ifzeropt\scratchskip\else\donetrue\fi +% \scratchskip\typingparameter\c!evenmargin\relax +% \ifzeropt\scratchskip\else\donetrue\fi +% \ifdone +% \def\doopenupverbatimline +% {\getpagestatus +% \ifrightpage +% \hskip\typingparameter\c!oddmargin\relax +% \else +% \hskip\typingparameter\c!evenmargin\relax +% \fi}% +% \else +% \doadaptleftskip{\typingparameter\c!margin}% +% \fi +% \doifdefinedelse{\??bo\typingparameter\c!blank} +% {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}} +% {\edef\!!stringa{\typingparameter\c!blank}}% +% \processaction +% [\!!stringa] +% [ \v!standard=>\scratchskip\ctxparskip, +% \v!small=>\scratchskip\blankokleinmaat, +% \v!medium=>\scratchskip\blankomiddelmaat, +% \v!big=>\scratchskip\blankogrootmaat, +% \v!halfline=>\scratchskip.5\baselineskip, +% \v!line=>\scratchskip\baselineskip, +% \v!none=>\scratchskip\zeropoint, +% \s!unknown=>\scratchskip\commalistelement]% +% \ifgridsnapping +% \ifdim\scratchskip=.5\baselineskip\relax +% \edef\verbatimbaselineskip{\the\scratchskip}% new +% \else +% \edef\verbatimbaselineskip{\the\baselineskip}% +% \fi +% \else +% \edef\verbatimbaselineskip{\the\scratchskip}% +% \fi +% \setupcommonverbatim} + +\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip} +\setvalue{\??tp:\c!blank:\v!small }{\blankokleinmaat} +\setvalue{\??tp:\c!blank:\v!medium }{\blankomiddelmaat} +\setvalue{\??tp:\c!blank:\v!big }{\blankogrootmaat} +\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip} +\setvalue{\??tp:\c!blank:\v!line }{\baselineskip} +\setvalue{\??tp:\c!blank:\v!none }{\zeropoint} + +\def\initializetyping + {%\donefalse + \switchtobodyfont[\typingparameter\c!bodyfont]% + \donefalse + \scratchskip\typingparameter\c!oddmargin\relax + \ifzeropt\scratchskip\else\donetrue\fi + \scratchskip\typingparameter\c!evenmargin\relax + \ifzeropt\scratchskip\else\donetrue\fi + \ifdone + \def\doopenupverbatimline + {\getpagestatus + \ifrightpage + \hskip\typingparameter\c!oddmargin\relax + \else + \hskip\typingparameter\c!evenmargin\relax + \fi}% + \else + \doadaptleftskip{\typingparameter\c!margin}% + \fi + \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}% + \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax + \ifgridsnapping + \ifdim\scratchskip=.5\baselineskip\relax + \edef\verbatimbaselineskip{\the\scratchskip}% new + \else + \edef\verbatimbaselineskip{\the\baselineskip}% + \fi + \else + \edef\verbatimbaselineskip{\the\scratchskip}% + \fi + \setupcommonverbatim} + +%D The basic display verbatim commands are defined in an +%D indirect way. As we will see, they are a specific case of a +%D more general mechanism. + +% we need this hack because otherwise verbatim skips +% the first line (everything after the initial command) + +\def\dostarttyping#1% tricky non standard lookahead + {\bgroup + \let\currenttypingclass\??tp + \edef\currenttyping{#1}% + \obeylines + \futurelet\nexttoken\dodostarttyping} + +\def\dodostarttyping + {\ifx\nexttoken[% + \expandafter\dododostarttyping + \else + \expandafter\nododostarttyping + \fi} + +\def\nododostarttyping + {\dododostarttyping[]} + +\def\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..5998260f2 --- /dev/null +++ b/tex/context/base/buff-ver.mkiv @@ -0,0 +1,1049 @@ +%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 + +% 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}} + +\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}% + \endgroup} + +\def\setupprettytype + {\processingverbatimtrue % will move + \ctxlua{buffers.visualizers.reset()}} + +\def\setverbatimspaceskip + {\setbox\scratchbox\hbox{x}% + \spaceskip\wd\scratchbox + \xspaceskip\spaceskip} + +\let\obeycharacters\relax + +\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 +% {}% todo + % + \ignorehyphens % default + \getvalue{\??tp:\c!lines:\typingparameter\c!lines}% + \getvalue{\??tp:\c!empty:\typingparameter\c!empty}% + \getvalue{\??tp:\c!option:\ifcsname\??tp:\c!option:\typingparameter\c!option\endcsname\typingparameter\c!option\else\s!unknown\fi}% + \doifnumberelse{\typingparameter\c!tab} + {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}% + \donothing + %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}% + % more generic, but beware of the \redoconvertfont (else no typing in titles and such) + \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}% + \setupverbatimcolor} + +\newtoks \everyinitializeverbatim + +\def\doinitializeverbatim + {\ctxlua{buffers.visualizers.reset()}% + \def\obs{\obeyedspace}% + \ctxlua{buffers.doifelsevisualizer("\prettyidentifier")} + {\ctxlua{buffers.setvisualizer("\prettyidentifier")}% + \localcolortrue % tricky, maybe not here + \def\bop{\bgroup\beginofpretty}% + \def\eop{\endofpretty\egroup}% + \def\sop{\endofpretty\egroup\bgroup\beginofpretty}}% + {\let\bop\donothing + \let\eop\donothing + \let\sop\donothing}% + \verbatimfont + \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. + +\def\setupcommandsintype % can also be \string\ + {\ctxlua{ + buffers.visualizers.enableescape = true + buffers.visualizers.escapetoken = \!!bs\typingparameter\c!escape\!!es + }% + \setevalue{\typingparameter\c!escape}{\typingparameter\c!escape}} + +\def\setupslantedtype + {\slantedtypepermittedtrue} + +\ifx\setupprettytype \undefined \let\setupprettytype \relax \fi +\ifx\setupslantedtype \undefined \let\setupslantedtype \relax \fi +\ifx\setupgroupedtype \undefined \let\setupgroupedtype \relax \fi +\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi + +%D The verbatim commands have a rather long and turbulent +%D history. Most users of \CONTEXT\ probably will never use +%D some of the features, but I've kept in mind that when one is +%D writing a users manual, about everything can and undoubtly +%D will be subject to a verbatim treatment. +%D +%D Verbatim command are very sensitive to argument processing, +%D which is a direct result of the \CATCODES\ being fixed at +%D reading time. With our growing understanding of \TEX, +%D especially of the mechanism that can be used for looking +%D ahead and manipulating \CATCODES, the verbatim support +%D became more and more advanced and natural. +%D +%D Typesetting inline verbatim can be accomplished by +%D \type{\type}, which in this sentence was typeset by saying +%D just \type{\type{\type}}, which in turn was typeset by +%D \unknown. Using the normal grouping characters \type{{}} is +%D the most natural way of using this command. +%D +%D A second, more or less redundant, alternative is delimiting +%D the argument with an own character. This method was +%D implemented in the context of a publication in the \MAPS, +%D where this way of delimiting is recognized by \LATEX\ users. +%D +%D The third, more original alternative, is the one using +%D \type{<<} and \type{>>} as delimiters. This alternative can +%D be used in situations where slanted typeseting is needed. + +% todo: we can use \letter... here: + +\def\lesscharacter {<} +\def\morecharacter {>} + +\chardef\texescape = `\\ +\chardef\leftargument = `\{ +\chardef\rightargument = `\} + +%D \macros +%D {type} +%D +%D We define \type{\type} as a protected command. This command +%D has several invocations: grouped, wirt boundary characters, +%D and with font switches. + +% \starttyping +% normal: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \par +% normal: \par \type{xx<..xx.. >..>xx} \par \type{<....>} \par \type{<....>} +% \setuptype[option=slanted] +% slanted: \par \type{xx<<..sl..<> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<>..>> \par +% slanted: \par \type{xx<<..sl.. xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<....>> \par +% \setuptype[option=none] +% none: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \par +% \stoptyping + +%D When writing the manual to \CONTEXT\ and documenting this +%D source we needed to typeset \type{<<} and \type{>>}. Because +%D we wanted to do this in the natural way, we've adapted the +%D original definition a bit. This implementation went through +%D several live cycles. The final implementation looks a bit +%D further and treats the lone \type{<<} and \type{>>} a bit +%D different. The \type {\null} prevents ligatures, which +%D unfortunately turn up in Lucida fonts. + +%D The following lines show what happens when we set +%D \type {option=commands}. +%D +%D \startbuffer +%D \starttyping +%D test//test test/BTEX \footnote{test test test}/ETEX test +%D test//test test/BTEX \footnote{test test test}/ETEX test +%D test test test/BTEX \bf(nota bene)/ETEX test +%D test test test /BTEX \bf(nota bene)/ETEX test +%D \stoptyping +%D \stopbuffer +%D +%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup +%D +%D this was keyed in as: +%D +%D \typebuffer + +\unexpanded\def\type{\dotype\empty} + +\def\dotype#1% was \dotype + {\bgroup + \begstrut % new, enables leading space in \type { abc } at par start / begstrut else no hyphenation + \let\currenttypingclass\??ty + \edef\currenttyping{#1}% + \catcode`\<=\@@other + \catcode`\>=\@@other + \futurelet\next\dodotype} + +\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} + +\def\dodotypeA + {\initializetype % probably too much + \verbatimcolor + \setcatcodetable \typcatcodesa + \dodotypeAA} + +\def\dodotypeAA#1% + {\doinitializeverbatim + \def\obs{\obeyedspace}% + \ctxlua{buffers.hooks.flush_line(\!!bs\detokenize{#1}\!!es)}% + \egroup} + +\def\dodotypeB#1% + {\initializetype + \verbatimcolor + \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 + \setcatcodetable \typcatcodesb + \dodotypeCC} + +\def\dodotypeCC#1% + {\doinitializeverbatim + \ifx\obeycharacters\setupprettytype % temp hack, we need a proper signal + \ctxlua{buffers.hooks.flush_line([\!!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 + \setcatcodetable \typcatcodesa + \def\dodotypeDD##1#1{\dodotypeAA{##1}}% + \dodotypeDD} + +\def\dodotypeDD#1% + {\doinitializeverbatim + \ctxlua{buffers.hooks.flush_line(\!!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 + \verbatimfont % needed for \tex + %\setverbatimspaceskip + %\let\obeytabs \ignoretabs % probably not needed + %\let\obeylines\ignorelines % probably not needed + %\let\obeypages\ignorepages % probably not needed + %\setupcopyverbatim % not needed + } + +%D \macros +%D {setuptype} +%D +%D Some characteristics of \type{\type} can be set up by: + +\def\setuptype + {\dodoubleempty\dosetuptype} + +\def\dosetuptype[#1][#2]% + {\ifsecondargument + \getparameters[\??ty#1][#2]% + \else + \getparameters[\??ty][#1]% + \fi} + +%D \macros +%D {typ,obeyhyphens,obeybreakpoints} +%D +%D Although it's not clear from the macros, one character +%D trait of this macros, which are build on top of the support +%D module, is that they don't hyphenate. We therefore offer +%D the alternative \type{\typ}. The current implementation +%D works all right, but a decent hyphenation support of +%D \type{\tt} text will be implemented soon. + +\def\obeyhyphens + {\def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip + \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}% + \spaceskip.25em\relax} % hm a bit of stretch ! + +\def\obeybreakpoints + {\ignorehyphens + \veryraggedright} + +\def\ignorehyphens + {% \language\minusone % extra bonus, the \null should do the job too + \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip + \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}% + \spaceskip.5em\relax} + +\unexpanded\def\typ + {\bgroup + \let\@@tylines\v!hyphenated + \futurelet\next\dodotype} + +%D \macros +%D {tex,arg,mat,dis} +%D +%D Sometimes, for instance when we pass verbatim text as an +%D argument, the fixed \CATCODES\ interfere with our wishes. An +%D experimental implementation of character by character +%D processing of verbatim text did overcome this limitation, +%D but we've decided not to use that slow and sometimes +%D troublesome solution. Instead we stick to some 'old' +%D \CONTEXT\ macros for typesetting typical \TEX\ characters. +%D +%D The next implementation is more clear but less versatile, +%D so we treated it for a beter one. +%D +%D \starttyping +%D \def\dospecialtype#1#2% +%D {\bgroup +%D \initializetype +%D \catcode`\{=\@@begingroup +%D \catcode`\}=\@@endgroup +%D \def\dospecialtype% +%D {\def\dospecialtype{#2\egroup}% +%D \bgroup +%D \aftergroup\dospecialtype +%D #1}% +%D \afterassignment\dospecialtype +%D \let\next=} +%D +%D \unexpanded\def\tex{\dospecialtype\texescape\relax} +%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument} +%D \unexpanded\def\mat{\dospecialtype\$\$} +%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}} +%D \stoptyping + +\def\setgroupedtype + {\let\currenttypingclass\??ty + \initializetype + \verbatimcolor + %\setcatcodetable \typcatcodesa + \catcode`\{=\@@begingroup + \catcode`\}=\@@endgroup} + +\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}} +\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}} +\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}} +\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}} + +%D \macros +%D {starttyping} +%D +%D Display verbatim is realized far more easy, which is mostly +%D due to the fact that we use \type{\stop...} as delimiter. +%D The implementation inherits some features, for instance the +%D support of linenumbering, which can best be studied in the +%D documented support module. + +\let\currenttyping \empty +\let\currenttypingclass\??ty % saveguard + +\def\typingparameter#1% + {\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 }{\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. + +\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 + \ctxlua{buffers.typefile("\readfilename")}} + +\def\dotypefilelinesverbatim#1#2% + {#1% + \doinitializeverbatim + \ctxlua{buffers.typefile("\readfilename")}% + #2} + +\def\dotypeblockverbatim#1#2% + {\dowithbuffer{_typing_}{#1}{#2} + {} + {\doinitializeverbatim + \beginofverbatimlines + \ctxlua{buffers.type("_typing_")}% + \endofverbatimlines + \getvalue{\strippedcsname#2}}} + +\def\dododostarttyping[#1]% + {\typingparameter\c!before + \startpacked % includes \bgroup + \dosetuptypelinenumbering{#1}% + \initializetyping + \startverbatimcolor + \expanded{\dotypeblockverbatim{\s!start\currenttyping}{\s!stop\currenttyping}}} + +\def\dostoptyping#1% hm, currenttyping + {\stopverbatimcolor + \stoppacked % includes \egroup + \typingparameter\c!after + \egroup + \dochecknextindentation{\??tp#1}% + \dorechecknextindentation} + +%D Line numbering for files is combined with filtering, while +%D display verbatim has the ability to continue. +%D +%D \starttyping +%D \typefile[numbering=file,start=10,stop=12]{test.tex} +%D +%D \definetyping[code][numbering=line] +%D +%D \starttext +%D \startcode +%D ... +%D ... +%D \stopcode +%D +%D \startcode[continue] +%D ... +%D ... +%D \stopcode +%D +%D \startcode[start=10] +%D ... +%D \stopcode +%D \stoptyping + +%D \macros +%D {setuptyping} +%D +%D The setup of typing accepts two arguments. The optional +%D first one identifies the user defined ones. If only one +%D argument is given, the values apply to both the standard +%D command \type{\starttyping} and \type{\typefile}. + +\def\dosetuptyping[#1][#2]% + {\ifsecondargument + \getparameters[\??tp#1][#2]% + \else + \getparameters[\??tp][#1]% + \fi} + +\def\setuptyping + {\dodoubleempty\dosetuptyping} + +%D \macros +%D {definetype} +%D +%D Specific inline verbatim commands can be defined with the +%D following command. + +\def\definetype + {\dodoubleempty\dodefinetype} + +\def\dodefinetype[#1][#2]% + {\unexpanded\setvalue{#1}{\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 + {\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 \macros +%D {EveryPar, EveryLine, iflinepar} +%D +%D One of the features of these commands is the support of +%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}. +%D In the documentation of the verbatim support module we give +%D some examples of line- and paragraph numbering using these +%D macros. + +%D \macros +%D {typefile} +%D +%D Typesetting files verbatim (for the moment) only supports +%D colorization of \TEX\ sources as valid option. The other +%D setup values are inherited from display verbatim. +%D The implementation of \type{\typefile} is straightforward: + +% new feature (not yet 100\% ok) +% +% \setuptyping[file][numbering=file] +% +% \typefile[start=2,nlines=3]{zapf} +% \typefile[start=continue,nlines=13]{zapf} +% \typefile{zapf} +% +% \setuptyping[file][numbering=line] +% +% \typefile[start=4,step=3]{zapf} +% \typefile{zapf} + +\def\typefile + {\dodoubleempty\dotypefile} + +\def\dotypefile[#1][#2]#3% + {\ifsecondargument + \dodotypefile[#1][#2]{#3}% + \else\iffirstargument + \doifassignmentelse{#1} + {\dodotypefile[\v!file][#1]{#3}} + {\dodotypefile[#1][]{#3}}% + \else + \dodotypefile[\v!file][]{#3}% + \fi\fi} + +\def\dosetuptypelinenumbering#1% fuzzy + {\doifundefined{\currenttypingclass\currenttyping\c!start} + {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}% + \setuptyping[\currenttyping][#1]% + \doifelse{\typingparameter\c!numbering}\v!file + {% kind of special: filters lines ! + \setuplinenumbering[\c!method=\v!file]% + \donetrue} + {\doifelse{\typingparameter\c!numbering}\v!line + {% \setuplinenumbering defaults start/step to 1/1, so we need + \doifinsetelse\v!continue{#1,\typingparameter\c!start} + {\scratchcounter0\typingparameter\c!n + \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}% + {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}% + \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}% + \setuplinenumbering + [\c!method=\v!type, + \c!start=\typingparameter\c!start, + \c!stop=\typingparameter\c!stop, + \c!step=\typingparameter\c!step]% + \donetrue} + {\donefalse}}% + \ifdone + \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi + \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi + \def\beginofverbatimlines{\startlinenumbering}% + \def\endofverbatimlines {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}% + \fi} + +\def\reporttypingerror#1% temp hack + {\blank + \dontleavehmode\hbox\bgroup + \expanded{\defconvertedargument\noexpand\ascii{#1}}% + \tttf[\makemessage\m!verbatims1\ascii]% + \showmessage\m!verbatims1\ascii + \egroup + \blank} + +\def\dosometyping#1#2#3#4#5% + {\bgroup + \let\currenttypingclass\??tp + \edef\currenttyping{#1}% + \typingparameter\c!before + \startpacked % includes \bgroup + \dosetuptypelinenumbering{#2}% + \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal} + {\setuptyping[#1][\c!option=\v!none]}% + \doif{\typingparameter\c!option}\v!color + {\expandafter\aftersplitstring#3\at.\to\prettyidentifier + \settypingparameter\c!option{\prettyidentifier}}% + \initializetyping + \startverbatimcolor + \doifundefinedelse{\currenttypingclass#3\v!global\c!start} + {\scratchcounter\zerocount} + {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}% + \advance\scratchcounter\plusone + \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}% + \doifelsenothing{\typingparameter\c!start} + {#4} + {\doif{\typingparameter\c!start}\v!continue + {\setevalue{\currenttypingclass#1\c!start}% + {\getvalue{\currenttypingclass#3\v!global\c!start}}}% + \doifelsenothing{\typingparameter\c!stop} + {\doifelsenothing{\typingparameter\c!nlines} + {#4} + {\setxvalue{\currenttypingclass#3\v!global\c!start}% + {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}% + #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}% + {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}% + \stopverbatimcolor + \stoppacked + \typingparameter\c!after + \egroup} + +\def\doifelsetypingfile#1% sets \readfilename (we will make this proper mkiv i.e. less messy) + {\doiflocfileelse{#1} + {\firstoftwoarguments} + {\doifinputfileelse{#1} + {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments} % messy, looks wrong too + {\secondoftwoarguments}}} + +\def\dodotypefile[#1][#2]#3% + {\doifelsetypingfile{#3} + {\dosometyping{#1}{#2}{#3}\dotypefileverbatim\dotypefilelinesverbatim} + {\reporttypingerror{#3}}} + +%D \macros +%D {filename} +%D +%D Typesetting filenames in monospaced fonts is possible with +%D +%D \starttyping +%D \filename{here/there/filename.suffix} +%D \stoptyping +%D +%D The definition is not that spectacular. + +\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}} + +%D 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] + +%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 +\let\doopenupverbatimline\empty + +\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/char-act.mkiv b/tex/context/base/char-act.mkiv new file mode 100644 index 000000000..34358784a --- /dev/null +++ b/tex/context/base/char-act.mkiv @@ -0,0 +1,125 @@ +%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} + +\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-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-enc.tex b/tex/context/base/char-enc.tex deleted file mode 100644 index 9fe9a363b..000000000 --- a/tex/context/base/char-enc.tex +++ /dev/null @@ -1,18 +0,0 @@ -%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.mkiv b/tex/context/base/char-ini.mkiv new file mode 100644 index 000000000..b79e44857 --- /dev/null +++ b/tex/context/base/char-ini.mkiv @@ -0,0 +1,74 @@ +%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 + +\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=11 \global\lccode #1=#2 \global\uccode #1=#3 } +\def\setcclcucself#1{\global\catcode#1=11 \global\lccode #1=#1 \global\uccode #1=#1 } + +\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, + } + ) +} + +\protect \endinput diff --git a/tex/context/base/char-ini.tex b/tex/context/base/char-ini.tex deleted file mode 100644 index b79e44857..000000000 --- a/tex/context/base/char-ini.tex +++ /dev/null @@ -1,74 +0,0 @@ -%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 - -\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=11 \global\lccode #1=#2 \global\uccode #1=#3 } -\def\setcclcucself#1{\global\catcode#1=11 \global\lccode #1=#1 \global\uccode #1=#1 } - -\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, - } - ) -} - -\protect \endinput diff --git a/tex/context/base/char-utf.mkiv b/tex/context/base/char-utf.mkiv new file mode 100644 index 000000000..d21cd842c --- /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 + +\def\definecomposedutf#1 #2 #3 % + {\ctxlua{characters.filters.utf.add_grapheme("#1","#2","#3")}} + +\protect diff --git a/tex/context/base/char-utf.tex b/tex/context/base/char-utf.tex deleted file mode 100644 index d21cd842c..000000000 --- a/tex/context/base/char-utf.tex +++ /dev/null @@ -1,47 +0,0 @@ -%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 - -\def\definecomposedutf#1 #2 #3 % - {\ctxlua{characters.filters.utf.add_grapheme("#1","#2","#3")}} - -\protect diff --git a/tex/context/base/chem-str-test.tex b/tex/context/base/chem-str-test.tex deleted file mode 100644 index fd6a8227a..000000000 --- a/tex/context/base/chem-str-test.tex +++ /dev/null @@ -1,560 +0,0 @@ -% Beware, integrated ppchtex support is incomplete and under -% construction so when you depend on the full functionality -% you need to use the module! -% -% For testing new functionality: -% -% \startMPextensions -% input "mp-chem.mp" ; -% \stopMPextensions -% \startluacode -% dofile(resolvers.find_file("chem-str.lua","tex")) -% \stopluacode -% \setbox\scratchbox\hbox{\startMPcode\stopMPcode} - -\enabletrackers[chemistry.structure] - -\starttext - -\defineprocessor[ch:r][color=red] -\defineprocessor[ch:g][color=green] -\defineprocessor[ch:b][color=blue] - -\setupchemical[frame=on,offset=3pt] - -\startbuffer[test-set] - - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV1,B] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV2,B] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV3,B] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV4,B] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV5,B] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV6,B] \stopchemical \quad - - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,AU] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,AD] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,EB] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,DB] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,ER] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,DR] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,BR] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,SB] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,-SB] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,+SB] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,C] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CC] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CD] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CCD] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,SR] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,-SR] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,+SR] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,RD] \stopchemical \quad - - \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,Z] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RZ] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,+R,+RZ] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,-R,-RZ] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,RB,RZ] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,+RB,+RZ][a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,-RB,-RZ][a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RT] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RTT] [a,b,c,d,e,f] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RBT] [a,b,c,d,e,f] \stopchemical \quad - - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RN] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RTN] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RBN] \stopchemical \quad - - \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RN] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT1,B,R,RN] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT2,B,R,RN] \stopchemical \quad - \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT3,B,R,RN] \stopchemical \quad - -\stopbuffer - -\dontcomplain - -% \startTEXpage - -\setupchemicalframed[frame=on] - -% \startTEXpage -% \noindent \startchemical \chemical[THREE, B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT1,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT2,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT3,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT4,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical - -% \noindent \startchemical \chemical[THREE, B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical - -% \noindent \startchemical \chemical[THREE, B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical -% \stopTEXpage - -% \startTEXpage -% \noindent \startchemical \chemical[SIX,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical - -% \noindent \startchemical \chemical[SIX,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical - -% \noindent \startchemical \chemical[SIX,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[SIX,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \stopTEXpage - -% \startTEXpage -% \noindent \startchemical \chemical[FIVE,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical - -% \noindent \startchemical \chemical[FIVE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical - -% \noindent \startchemical \chemical[FIVE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[FIVE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \stopTEXpage - -% \startTEXpage -% \noindent \startchemical \chemical[FOUR,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical - -% \noindent \startchemical \chemical[FOUR,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical - -% \noindent \startchemical \chemical[FOUR,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[FOUR,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \stopTEXpage - -% \startTEXpage -% \noindent \startchemical \chemical[THREE,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical - -% \noindent \startchemical \chemical[THREE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical - -% \noindent \startchemical \chemical[THREE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \noindent \startchemical \chemical[THREE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical -% \stopTEXpage - -% \startTEXpage -% \noindent \startchemical \chemical[EIGHT,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical - -% \noindent \startchemical \chemical[EIGHT,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical - -% \noindent \startchemical \chemical[EIGHT,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical -% \noindent \startchemical \chemical[EIGHT,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical -% \stopTEXpage - -% \enabletrackers[chemistry.molecules] - -% \startchemicalformula -% \chemical{S} -% \chemical{+} -% \chemical{O_2} -% \chemical{GIVES} -% \chemical{\+{4}{S}} -% \chemical{\+{4}{S}\-{2}{O_2}} -% \chemical{\-{2}{O_2}} -% \stopchemicalformula - -% \startformula -% \chemical{S} -% \chemical{+} -% \chemical{O_2} -% \chemical{GIVES} -% \chemical{\+{4}{S}} -% \chemical{\+{4}{S}\-{2}{O_2}} -% \chemical{\-{2}{O_2}} -% \stopformula - - -\startTEXpage[offset=2cm] - -\startchemical[width=fit,size=small,scale=small,frame=on] - \chemical[SIX,B] -\stopchemical - -% \startchemical[width=fit,size=small,scale=small,frame=on] -% \chemical[ONE,SB258] -% \stopchemical - -% \startchemical[width=fit,size=small,scale=small,frame=on] -% \chemical[ONE,ROT3,SB258] -% \stopchemical - -% \startchemical[width=fit,size=small,scale=small,frame=on] -% \chemical[FIVE,ROT3,SB34,+SB2,-SB5,Z345,DR35,SR4,CRZ35,SUB1,ONE,SB258,Z0,Z28][C,N,C,O,O,CH,COOC_2H_5,COOC_2H_5] -% \stopchemical - -% \startchemical[scale=small,width=8000,height=8000,frame=on] -% \chemical[SIX,SB2356,DB14,Z2346,SR36,RZ36] [C,N,C,C,H,H_2] -% \chemical[PB:Z1,ONE,Z0,DIR8,Z0,SB24,DB7,Z27,PE][C,C,CH_3,O] -% \chemical[PB:Z5,ONE,Z0,DIR6,Z0,SB24,DB7,Z47,PE][C,C,H_3C,O] -% \chemical[SR24,RZ24] [CH_3,H_3C] -% \stopchemical - -% \startchemical[scale=small,width=6000,height=6000,frame=on] -% \chemical[SIX,SB2356,DB14,Z,SR36,RZ36,SR1245,RZ24][C,C,N,C,C,C,H,H_2,CH_3,H_3C] -% \chemical[PB:RZ1,ONE,Z0,SB2,DB7,Z27,PE][C,CH_3,O] -% \chemical[PB:RZ5,ONE,Z0,SB4,DB7,Z47,PE][C,H_3C,O] -% \stopchemical - -% \startchemical[width=fit,size=small,scale=small,frame=on] -% \chemical -% [SIX,B,C,ADJ1,FIVE,ROT3,SB34,+SB2,-SB5,Z345,DR35,SR4,CRZ35,SUB1,ONE,OFF1,SB258,Z0,Z28] -% [C,N,C,O,O,CH,COOC_2H_5,COOC_2H_5] -% \stopchemical - -% \startchemical[width=fit,height=fit,frame=on,scale=small] -% \chemical -% [ONE,SB15,DB7,Z057,3OFF1,MOV1,Z0,3OFF1,MOV1, -% Z017,SB1357,MOV3,Z0,MOV3,SB1357,Z013,3OFF5, -% MOV5,Z0,3OFF5,SB5,Z5] -% [C,H_2N,NH,(CH_2)_3,C,COOH,H,\SL{NH},C,COOH,H, -% (CH_2)_2,HOOC] -% \stopchemical - -% \startchemical[width=fit,height=fit,frame=on,scale=small] -% \chemical -% [ONE,SB15,DB7,Z057,3OFF1,MOV1,Z0,3OFF1,MOV1,Z017,SB1357,MOV3,Z0,MOV3,SB1357,Z013,3OFF5,MOV5,Z0,3OFF5,SB5,Z5] -% [C,H_2N,NH,(CH_2)_3,C,COOH,H,\SL{NH},C,COOH,H,(CH_2)_2,HOOC] -% \stopchemical - -% \startchemical -% \chemical[ONE,Z0,DB,Z][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8] -% \stopchemical - -% \startchemical -% \chemical[ONE,Z0,SB,Z][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8] -% \stopchemical - -% \startchemical -% \chemical[ONE,Z0,DB,CZ][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8] -% \stopchemical - -% \startchemical -% [width=fit,top=2000,bottom=2000, -% scale=small,size=small]% -% \chemical -% [ONE, -% SAVE, -% Z0,SB731,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1, -% RESTORE, -% SAVE, -% SUB4,ONE,Z0,SB3,SB1,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1, -% RESTORE, -% SUB2,ONE,Z0,SB7,SB1,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1] -% [\SR{HC},O,C,O,C_{19}H_{39}, -% \SR{H_{2}C},O,C,O,C_{17}H_{29}, -% \SR{H_{2}C},O,C,O,C_{21}H_{41}] -% \stopchemical - -% \chemical[width=fit,height=fit,frame=on,scale=small] -% [ONE,Z0,MOV7,SB1357,Z017,3OFF5,MOV5,Z0,3OFF5,MOV5,SB15,DB7,Z057,MOV0,MOV3,SB1357,Z013,MOV5,3OFF5,Z0,6OFF5,SB5,Z5] -% [\SL{NH},C,COOH,H,(CH_2)_3,C,H_2H,NH,C,COOH,H,(CH_2)_2,HOOC] -% \stopchemical - -% \chemical[width=fit,height=fit,frame=on,scale=small] -% [ONE,Z0,MOV7,SB1357,Z017,3OFF5,MOV5,Z0,3OFF5,MOV5,SB15,DB7,Z057,MOV0,MOV3,SB1357,Z013,MOV5,3OFF5,Z0,6OFF5,SB5,Z5] -% [\SL{NH},C,COOH,H,(CH_2)_3,C,H_2H,NH,C,COOH,H,(CH_2)_2,HOOC] -% \stopchemical - -% \startchemical[width=fit,top=1500,bottom=3500] -% \chemical[ONE,Z0,DB1,SB3,SB7,Z7,MOV1,Z0,SB3,SB7,Z3,Z7,MOV0,SUB2,SIX,B,R6,C][C,H,C,H,H] -% \chemical[ONE,Z0,DB1,SB3,SB7,Z7,MOV1,Z0,SB3,SB7,Z3,Z7,MOV0,SUB2,SIX,B,R6,C][C,H,C,H,H] -% \bottext{styreen} -% \stopchemical - -% \startchemical -% \chemical[SPACE,PLUS,SPACE] -% \stopchemical -% \startchemical[right=600] -% \chemical[ONE,CZ0][3CH_{3}OH] -% \stopchemical -% \startchemical -% \chemical[SPACE,GIVES,SPACE,SPACE][H^+/H_2O] -% \stopchemical -% \startchemical -% \chemical -% [ONE, -% SAVE, -% Z0,SB7,SB3,SB1,Z1, -% RESTORE, -% SAVE, -% SUB4,ONE,Z0,SB3,SB1,Z1, -% RESTORE, -% SUB2,ONE,Z0,SB7,SB1,Z1] -% [\SR{HC},OH, -% \SR{H_{2}C},OH, -% \SR{H_{2}C},OH] -% \stopchemical -% \startchemical -% \chemical[SPACE,PLUS,SPACE] -% \stopchemical - -% \startchemical -% \chemical -% [ONE, -% SAVE, -% Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1, -% RESTORE, -% SAVE, -% SUB4,ONE,Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1, -% RESTORE, -% SUB2,ONE,Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1] -% [C,O,C_{19}H_{39},O,CH_{3}, -% C,O,C_{17}H_{29},O,CH_{3}, -% C,O,C_{21}H_{41},O,CH_{3}] -% \stopchemical - -% \startchemical[height=4500,bottom=2500] -% \bottext{$\beta$-D-Fructopyranose} -% \chemical[SIX,FRONT,BB,B1236,+SB4,-SB5,Z5,+R12346,+RZ12346,-R12346,-RZ12346][Z_0,+R_1,+R_2,+R_3,+R_4,+R_6,-R_1,-R_2,-R_3,-R_4,-R_6] -% \stopchemical - -% \startchemical[height=4500,bottom=2500] -% \chemical[SIX,FRONT,BB,B] -% \stopchemical - -% \startchemical -% [width=fit,height=fit,frame=on] -% \chemical -% [SIX,DB135,SB246,Z,SR6,RZ6][C,C,N,\SR{HC},N,C,NH_2] -% \chemical -% [SIX,MOV1,DB1,SB23,SS6,Z1..3,SR3,RZ3][N,\SL{CH},N,H] -% \stopchemical - -% \startchemical \chemical[SIX,B,R,RZ1=a] \stopchemical -% \startchemical \chemical[SIX,B,R,RZ1..3=a] \stopchemical -% \startchemical \chemical[SIX,B,R,RZ135=a] \stopchemical -% \startchemical \chemical[SIX,B,R,RZ] [a] \stopchemical -% \startchemical \chemical[SIX,B,R,RZ] [a,b] \stopchemical -% \startchemical \chemical[SIX,B,R,RZ=a] \stopchemical - -% \definechemical[molecule] -% {\chemical -% [ONE,Z0,SB1357, -% SAVE,SUB2,SIX,B,R6,C,RESTORE, -% MOV1,Z0,SB137,MOV1,Z0,SB37,MOV1] -% [C,C,C]} - -% \startchemical[width=fit,height=fit] -% \chemical[molecule,molecule,molecule] -% \stopchemical - -% \definechemical[molecule] -% {\chemical -% [ONE,Z0,SB1357, -% SAVE,SUB2,SIX,B,R6,C,RESTORE, -% MOV1,Z0,SB137,MOV1,Z0,SB37,MOV1]} - -% \startchemical[width=fit,height=fit] -% \chemical[molecule,molecule,molecule][A,B,C,D,E,F,G,H,I] -% \stopchemical - -\stopTEXpage - -% \noindent \startchemical -% \chemical[SIX,B1..3] -% \stopchemical - -% \noindent \startchemical[width=fit,height=fit] % auto5 ipb off5 -% \chemical[SIX,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] -% \stopchemical -% \noindent \startchemical[width=fit,height=fit] % auto5 ipb off5 -% \chemical[SIX,ROT1,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] -% \stopchemical -% \startchemical[width=fit,height=fit] % auto5 ipb off5 -% \chemical[SIX,ROT2,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] -% \stopchemical -% \startchemical[width=fit,height=fit] % auto5 ipb off5 -% \chemical[SIX,ROT3,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] -% \stopchemical -% \startchemical[width=fit,height=fit] % auto5 ipb off5 -% \chemical[SIX,ROT4,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] -% \stopchemical - -% \startchemical[width=fit,height=fit,axis=on] % auto5 ipb off5 -% \chemical[SIX,B,C,R6,PB:RZ6,ONE,CZ0,OE1,SB5,MOV5,CZ0,OFF5,OE5,PE][CH,CH_2] -% \stopchemical - -% \dontleavehmode \startchemical \chemical[SIX,B,R,RZ][1,2,3,4,5,6,] \stopchemical - -% \start -% \setupchemicalframed[frame=off] -% \dontleavehmode \startchemical[scale=medium,style=slanted,color=red,rulecolor=green,left=2000,right=4000,top=2000,bottom=2000,axis=on] \chemical[SIX,B,R,RZ][1,2,3,4,5,6,] \stopchemical - -% \dontleavehmode -% \startchemical[width=fit,height=fit] -% \chemical[SIX,B][1,2,3,4,5,6] -% \start -% \setupchemical[rulecolor=red] -% \chemical[SIX,R][1,2,3,4,5,6] -% \stop -% \chemical[SIX,RZ][1,2,3,4,5,6] -% \stopchemical -% \stop - -% \stopTEXpage - -% \stoptext - -% \startTEXpage - -% \dontleavehmode \startchemical \chemical[ONE,SB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,DB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,TB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,EP,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,ES,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,ED,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,ET,Z0][0] \stopchemical \quad - - -% \dontleavehmode \startchemical \chemical[ONE,SD,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,LDD,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,RDD,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,HB,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,BB,Z0][0] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,OE,Z0][0] \stopchemical \quad - - -% \dontleavehmode \startchemical \chemical[ONE,SB,Z] [1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,CZ][1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,ZT][a,b,c,d,e,f,g,h] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,ZN][1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,ZBT][1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,ZBN][1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,ZTT][1,2,3,4,5,6,7,8] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,ZTN][1,2,3,4,5,6,7,8] \stopchemical \quad - -% \dontleavehmode \startchemical \chemical[ONE,SB,MOV1,SB] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[ONE,SB,MOV1,SB,MOV3,SB] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,MOV1,B] \stopchemical \quad - - -% \dontleavehmode \startchemical \chemical[ONE,SB,Z0,Z][0,1,2,3,4,5,6] \stopchemical \quad -% \stopTEXpage - - -% \dorecurse{1000}{\dontleavehmode \startchemical \chemical[SIX,B,R,RZ][a,b,c,d,e,f] \stopchemical \quad} - -% \dontleavehmode \startchemical \chemical[SIX,B,R,RT] [a,b,c,d,e,f] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,R,RTT] [a,b,c,d,e,f] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,R,RBT] [a,b,c,d,e,f] \stopchemical \quad - -% \dontleavehmode \startchemical \chemical[SIX,B,R,+R,-R] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B1..4] \stopchemical \quad - -% \dontleavehmode \startchemical \chemical[SIX,B,ZN] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,ZT][A,B,C,D,E,F] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,R,AU] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,R,AD] \stopchemical \quad - -% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,SIX,B] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,FIVE,ROT1,B] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,FOUR,B] \stopchemical \quad -% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,THREE,B] \stopchemical \quad - -% \definechemical[sixring] -% {\chemical[SIX,B,R]} - -% \startchemical[frame=on,width=6000] -% \chemical[sixring,RZ][A,B,C,D,E,F] -% \stopchemical - -% \definechemical[test] -% {\chemical[SIX,SB,Z][A,B,C,D,E,F]} - -% \startchemical -% \chemical[SIX,SB,Z,ADJ1,test,ADJ1,SIX,SB,Z][a,b,c,d,e,f,g,h,j,k,l,m,P,Q,R,S,T,U,W] -% \chemical[ADJ1,SIX,SB,Z][1,2,3,4,5,6] -% \stopchemical - -% \definechemical[test]{\chemical[SIX,SB,Z]} - -% \startchemical -% \chemical[SIX,SB,Z,ADJ1,test,ADJ1,SIX,SB,Z][a,b,c,d,e,f,g,h,j,k,l,m,P,Q,R,S,T,U,W] -% \chemical[ADJ1,SIX,SB,Z][1,2,3,4,5,6] -% \stopchemical - -% \startchemical -% \chemical[ADJ1,SIX,SB,Z][a_1,a_2,a_3,a_4,a_5,\ominus] -% \stopchemical - -% \startchemical -% \chemical[SIX,SB,Z,SAVE,ADJ1,SIX,SB,Z,ADJ1,SIX,SB,Z,RESTORE,ADJ3,SIX,SB,Z][1,2,3,4,5,6,a,b,c,d,e,f,A,B,C,D,E,F,!,!,!,!,!,!] -% \stopchemical - -% $$ -% \startchemical -% \chemical[OPENCOMPLEX] -% \stopchemical -% \startchemical -% \chemical[SIX,SB,Z][1,2,3,4,5,6] -% \stopchemical -% \startchemical -% \chemical[SPACE,GIVES,SPACE][a,b] -% \stopchemical -% \startchemical -% \chemical[SIX,SB,Z][1,2,3,4,5,6] -% \stopchemical -% \startchemical -% \chemical[CLOSECOMPLEX] -% \stopchemical -% $$ - -% \stoptext - -% \page - -% \def\ChemicalKind{SIX} \getbuffer[test-set] -% \def\ChemicalKind{FIVE} \getbuffer[test-set] -% \def\ChemicalKind{FOUR} \getbuffer[test-set] -% \def\ChemicalKind{THREE} \getbuffer[test-set] - -% \startchemical -% \chemical[SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f] -% \chemical[MOV1,SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f] -% \chemical[MOV3,SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f] -% \stopchemical - -\stoptext diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv index cf7f2446a..b2b2b896c 100644 --- a/tex/context/base/colo-ini.mkiv +++ b/tex/context/base/colo-ini.mkiv @@ -119,125 +119,62 @@ \def\definespotcolor {\dotripleargument\dodefinespotcolor} \def\definemultitonecolor{\doquadrupleempty\dodefinemultitonecolor} -% check: registerusedspotcolors -% check: registerusedcolorchannels - %D \macros -%D {doifcolorelse, doifcolor} +%D {startcolor,stopcolor, +%D faststartcolor,faststopcolor, +%D localstartcolor,localstopcolor, +%D localstartraster,localstopraster, +%D startraster,stopraster,raster, +%D color,graycolor} %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 The local and global and raster commands are here just +%D for compatibility with \MKII. %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 \showsetup{startcolor} %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 {color,graycolor} %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 This leaves the simple color command: %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 \showsetup{color} +%D \showsetup{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 + \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{\setcolormodel{gray}\getvalue{#1}}{}} +\unexpanded\def\colored [#1]{\groupedcommand{\definecolor[@colored@][#1]\doactivatecolor{@colored@}}{}} + \def\predefinecolor [#1]{\flushatshipout{\hbox{\color[#1]{}}}} + \def\predefineindexcolor[#1]{\flushatshipout{\hbox{\color[#1]{}}}} + \def\startcolorpage {\startcolor[\ifx\maintextcolor\empty\defaulttextcolor\else\maintextcolor\fi]} + \def\stopcolorpage {\stopcolor} + \def\startraster [#1]{\dosetrastercolor{#1}} + \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} -%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 +\let\localstartcolor \startcolor +\let\localstopcolor \stopcolor +\let\globalstartcolor\startcolor +\let\globalstopcolor \stopcolor +\let\localstartraster\startraster +\let\localstopraster \stopraster +\let\grey \graycolor %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 +%D {startcurrentcolor,stopcurrentcolor} -% check: \currentcolorname -% check: \outercolorname +\def\startcurrentcolor{\startcolor[\outercolorname]} +\def\stopcurrentcolor {\stopcolor} %D \macros %D {setupcolor} @@ -325,10 +262,6 @@ \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 @@ -394,53 +327,6 @@ \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]. @@ -525,10 +411,6 @@ {\doifdefined{\??pa#2} {\expanded{\dodefinepalet[#1][\csname\??pa\??pa#2\endcsname]}}}} -\ifx\dodefinepaletcolor\undefined - \let\dodefinepaletcolor\gobblethreearguments -\fi - \let\paletsize\!!zerocount \def\getpaletsize[#1]% @@ -947,7 +829,8 @@ \letvalue{(ts:-}\empty \def\doactivatecolor#1% : in currentpalet, maybe not, ugly - {\ifcsname(cs:\currentpalet#1)\endcsname + {\def\currentcolorname{#1}% + \ifcsname(cs:\currentpalet#1)\endcsname \csname(cs:\currentpalet#1)\endcsname \csname(ts:\currentpalet#1)\endcsname \else\ifcsname(cs:#1)\endcsname @@ -970,7 +853,8 @@ \fi} \def\deactivatecolor - {\doresetattribute\s!color + {\let\currentcolorname\s!black + \doresetattribute\s!color \doresetattribute\s!transparency} \def\dodefinecolorcommand#1#2% @@ -1014,6 +898,13 @@ \fi \dosetattribute\s!color{\ctxlua{tex.sprint(ctx.definesimplegray("_raster_",\@@rastervalue))}}} +%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 @@ -1032,33 +923,45 @@ \@EAEAEA\gobbleoneargument \fi\fi} -% currentcolor, then we can push pop in register - - \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{\setcolormodel{gray}\getvalue{#1}}{}} -\unexpanded\def\colored [#1]{\groupedcommand{\definecolor[@colored@][#1]\doactivatecolor{@colored@}}{}} - \def\predefinecolor [#1]{\flushatshipout{\hbox{\color[#1]{}}}} - \def\predefineindexcolor[#1]{\flushatshipout{\hbox{\color[#1]{}}}} - \def\startcolorpage {\startcolor[\ifx\maintextcolor\empty\defaulttextcolor\else\maintextcolor\fi]} - \def\stopcolorpage {\stopcolor} - \def\localstartraster [#1]{\dosetrastercolor{#1}} - \def\localstopraster {} - \def\startraster [#1]{\dosetrastercolor{#1}} - \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} - -% more efficient: +%D \macros +%D {colored} +%D +%D A bit like \type {\definedfont}: \unexpanded\def\colored[#1]% {\ctxlua{ctx.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 + +\let\maintextcolor \empty +\def\defaulttextcolor {black} +\def\@@themaintextcolor{themaintextcolor} + \def\startregistercolor[#1]% {\doifelsenothing{#1} {\let\stopregistercolor\relax} @@ -1080,25 +983,9 @@ \fi \fi} -% \def\pushpostponedpagecolor -% {\edef\savedtopofpagecolor{\topofpagecolor}% -% \doifsomething\savedtopofpagecolor\restorecolormode} -% -% \def\poppostponedpagecolor -% {\doifsomething\savedtopofpagecolor\doactivatecolor\savedtopofpagecolor} -% -% no \topofpagecolor - \let\pushpostponedpagecolor\relax \let\poppostponedpagecolor \relax -% \def\pushcolor -% {\edef\popcolor -% {\dosetattribute\s!color {\dogetattribute\s!color }% -% \dosetattribute\s!transparency{\dogetattribute\s!transparency}}% -% \let\popsplitcolor\popcolor -% \deactivatecolor} - \appendtoks\deactivatecolor\to\everybeforeoutput % maybe we don't need push pop now \def\startregistercolor[#1]% @@ -1109,12 +996,6 @@ \dosetattribute\s!transparency{\dogetattribute\s!transparency}}% \doactivatecolor{#1}}} -\let\grey \graycolor -\let\localstartcolor \startcolor -\let\localstopcolor \stopcolor -\let\globalstartcolor\startcolor -\let\globalstopcolor \stopcolor - \def\registermaintextcolor{\ctxlua{colors.main = \thecolorattribute\maintextcolor}} \def\starttextcolor[#1]% @@ -1162,10 +1043,31 @@ \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 \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(ctx.mpcolor(\number\currentcolormodel,\number\doinheritca{#1},\number\doinheritta{#1}))}} -\def\currentcolorname{\s!black} % todo -\def\outercolorname {\s!black} % todo +\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} @@ -1216,7 +1118,9 @@ % % \def\forcecolorhack{\vrule\!!width\zeropoint\!!height\zeropoint\!!depth\zeropoint} -\def\forcecolorhack{\leaders\hrule\hskip\zeropoint} +% \normal added else fails in metafun manual (leaders do a hard scan) + +\unexpanded\def\forcecolorhack{\leaders\hrule\normalhskip\zeropoint} % \setupcolors[state=start] % diff --git a/tex/context/base/cont-log.tex b/tex/context/base/cont-log.tex index 8419394c4..27f3b1134 100644 --- a/tex/context/base/cont-log.tex +++ b/tex/context/base/cont-log.tex @@ -43,12 +43,12 @@ \def\Mkern#1% {{\setbox\scratchbox\hbox{M}\kern#1\wd\scratchbox}} -\def\TeX +\unexpanded\def\TeX {T% \Mkern{-.1667}\lower.5ex\hbox{E}% \Mkern{-.125}X} -\def\ConTeXt +\unexpanded\def\ConTeXt {C% \CMRkern-.0333emo% \CMRkern-.0333emn% @@ -56,10 +56,10 @@ \CMRkern-.0667em\TeX% \CMRkern-.0333emt} -\def\PPCHTeX +\unexpanded\def\PPCHTeX {ppch\TeX} -\def\PRAGMA +\unexpanded\def\PRAGMA {Pragma ADE} %\def\LaTeX @@ -67,7 +67,7 @@ % \kern-.30em\raise.3ex\hbox{\txx A}% % \kern-.18em\TeX} -\def\LaTeX % requested by erik frambach +\unexpanded\def\LaTeX % requested by erik frambach {{\setbox\scratchbox\hbox{L}% \scratchdimen\ht\scratchbox \setbox\scratchbox\hbox{\txx A}% @@ -75,14 +75,14 @@ \raise\scratchdimen\hbox{\lower\ht\scratchbox\copy\scratchbox}% \kern-.2\wd\scratchbox\TeX}} -\def\TaBlE +\unexpanded\def\TaBlE {T% \kern-.27em\lower.5ex\hbox{A}% \kern-.18emB% \kern-.1em\lower.5ex\hbox{L}% \kern-.075emE} -\def\PiCTeX +\unexpanded\def\PiCTeX {P% \kern-.12em\lower.5ex\hbox{I}% \kern-.075em C% @@ -91,20 +91,20 @@ \def\AMSswitch#1% {$\fam2\ifdim\bodyfontsize>1.1em\scriptstyle\fi#1$} -\def\AmSTeX +\unexpanded\def\AmSTeX {\AMSswitch A% \kern-.1667em\lower.5ex\hbox{\AMSswitch M}% \kern-.125em\AMSswitch S% -\TeX} -\def\LamSTeX +\unexpanded\def\LamSTeX {L% \kern-.4em\raise.3ex\hbox{\AMSswitch A}% \kern-.25em\lower.4ex\hbox{\AMSswitch M}% \kern-.1em{\AMSswitch S}% -\TeX} -\def\AmSLaTeX +\unexpanded\def\AmSLaTeX {\AMSswitch A% \kern-.1667em\lower.5ex\hbox{\AMSswitch M}% \kern-.125em\AMSswitch S% @@ -118,7 +118,7 @@ %D %D I changed this into one that adapts itself: -\def\Context +\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}}} @@ -198,18 +198,18 @@ %D write all user defined commands, like abbreviations, in %D uppercase.) -\def\METAFONT {\MetaFont} -\def\METAPOST {\MetaPost} -\def\PPCHTEX {\PPCHTeX} -\def\CONTEXT {\ConTeXt} -\def\METAFUN {\MetaFun} +\unexpanded\def\METAFONT {\MetaFont} +\unexpanded\def\METAPOST {\MetaPost} +\unexpanded\def\PPCHTEX {\PPCHTeX} +\unexpanded\def\CONTEXT {\ConTeXt} +\unexpanded\def\METAFUN {\MetaFun} -\def\TEX {\TeX} -\def\LATEX {\LaTeX} -\def\PICTEX {\PiCTeX} -\def\TABLE {\TaBlE} -\def\AMSTEX {\AmSTeX} -\def\LAMSTEX {\LamSTeX} +\unexpanded\def\TEX {\TeX} +\unexpanded\def\LATEX {\LaTeX} +\unexpanded\def\PICTEX {\PiCTeX} +\unexpanded\def\TABLE {\TaBlE} +\unexpanded\def\AMSTEX {\AmSTeX} +\unexpanded\def\LAMSTEX {\LamSTeX} %D And this is how they show up: \TeX, \MetaFont, \MetaPost, %D \PiCTeX, \TaBlE, \ConTeXt, \PPCHTeX, \AmSTeX, \LaTeX, @@ -224,12 +224,12 @@ %D Some placeholders: -\def\eTeX {\mathematics{\varepsilon}-\TeX} -\def\pdfTeX {pdf\TeX} -\def\pdfeTeX {pdfe-\TeX} -\def\luaTeX {lua\TeX} -\def\metaTeX {meta\TeX} -\unexpanded\def\XeTeX {X\lower.5ex\hbox{\kern-.15em\mirror{E}}\kern-.1667em\TeX} +\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) diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index b8e2a6f95..5886a1f27 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2009.05.28 11:23} +\newcontextversion{2009.06.02 09:30} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 1a2fa4abb..9b8cb8a99 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -85,11 +85,6 @@ \loadcorefile{supp-ali.tex} \loadcorefile{supp-num.tex} -%D The next module deals with language specific typographic -%D extensions. - -\loadcorefile{typo-ini.tex} - %D Verbatim typesetting is implemented in a separate class of %D modules. The pretty typesetting modules are loaded at run %D time. @@ -173,6 +168,8 @@ \loadcorefile{lang-ara.tex} \loadcorefile{lang-cyr.tex} +\loadmarkfile{typo-ini} + %D All kind of symbols are handled in: \loadcorefile{symb-ini.tex} @@ -187,25 +184,27 @@ \loadmarkfile{core-spa} \loadcorefile{core-grd.tex} -\loadcorefile{core-mar.tex} -\loadmarkfile{core-pos} +\loadmarkfile{strc-mar} +\loadmarkfile{anch-pos} \loadcorefile{core-mak.tex} -\loadcorefile{core-dat.tex} -\loadmarkfile{core-ver} -\loadmarkfile{core-rul} -\loadcorefile{core-vis.tex} -\loadcorefile{core-num.tex} + +\loadmarkfile{buff-ver} +\loadmarkfile{buff-ini} + +\loadmarkfile{pack-rul} +\loadmarkfile{trac-vis} +\loadmarkfile{strc-num} \loadcorefile{tabl-pln.tex} \loadcorefile{tabl-tab.tex} \loadcorefile{tabl-tsp.tex} -\loadmarkfile{core-nav} -\loadcorefile{core-ref.tex} -\loadmarkfile{core-obj} -\loadcorefile{core-lst.tex} -\loadcorefile{core-itm.tex} -\loadcorefile{core-des.tex} -\loadcorefile{core-mat.tex} % should come after math-pln etc -\loadcorefile{core-syn.tex} +\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} @@ -216,13 +215,13 @@ \loadmkiifile{page-log.tex} \loadmarkfile{page-txt} \loadcorefile{page-sid.tex} -\loadcorefile{page-flt.tex} +\loadmarkfile{strc-flt} \loadcorefile{page-mis.tex} \loadcorefile{page-mul.tex} \loadcorefile{page-set.tex} -\loadcorefile{page-lyr.tex} +\loadmarkfile{pack-lyr} \loadcorefile{page-mak.tex} -\loadcorefile{page-num.tex} +\loadmarkfile{strc-pag} \loadmarkfile{page-lin} \loadcorefile{page-par.tex} \loadcorefile{page-mar.tex} @@ -231,13 +230,13 @@ % so far -\loadcorefile{core-sec.tex} -\loadcorefile{core-swd.tex} -\loadmarkfile{core-buf} -\loadcorefile{core-blk.tex} +\loadmarkfile{strc-sec} +\loadmarkfile{strc-swd} +\loadmarkfile{strc-blk} + \loadcorefile{page-imp.tex} \loadcorefile{tabl-tbl.tex} -\loadmarkfile{core-int} +\loadmarkfile{scrn-int} \loadmarkfile{tabl-ntb} \loadcorefile{tabl-nte.tex} \loadcorefile{tabl-ltb.tex} @@ -251,12 +250,12 @@ %D How about fill||in fields and related stuff? \loadmarkfile{java-ini} -\loadmarkfile{core-fld} -\loadcorefile{core-hlp.tex} +\loadmarkfile{scrn-fld} +\loadmarkfile{scrn-hlp} %D Registers can depend on fields, so we load that now. -\loadcorefile{core-reg.tex} +\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 @@ -300,12 +299,11 @@ \loadcorefile{page-plg.tex} \loadcorefile{page-str.tex} -%D Hm. - -\loadcorefile{core-pgr.tex} -\loadcorefile{core-bar.tex} -\loadcorefile{core-snc.tex} +%D Anchoring graphics: +\loadcorefile{anch-pgr.tex} +\loadcorefile{anch-bar.tex} +\loadcorefile{anch-snc.tex} %D Math. @@ -317,17 +315,18 @@ %D Now we're ready for more core modules. \loadmarkfile{core-fnt} -\loadcorefile{core-not.tex} +\loadmarkfile{strc-not} \loadcorefile{core-lnt.tex} \loadmarkfile{core-mis} -\loadcorefile{core-trf.tex} -\loadmarkfile{core-inc} -\loadcorefile{core-fig.tex} +\loadmarkfile{grph-trf} +\loadmarkfile{grph-inc} +\loadmarkfile{grph-fig} + \loadcorefile{core-par.tex} -\loadcorefile{core-box.tex} +\loadmarkfile{pack-box} \loadcorefile{page-app.tex} \loadmarkfile{meta-fig} diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index b3542fb21..163ab803a 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -22,9 +22,9 @@ \loadcorefile{norm-ctx.tex} \loadcorefile{syst-pln.tex} -\loadmkivfile{luat-cod.tex} -\loadmkivfile{luat-bas.tex} -\loadmkivfile{luat-lib.tex} +\loadmarkfile{luat-cod} +\loadmarkfile{luat-bas} +\loadmarkfile{luat-lib} \loadmarkfile{catc-ini} \loadcorefile{catc-act.tex} @@ -34,8 +34,8 @@ \newif\ifCONTEXT \CONTEXTtrue % will disappear -\loadcorefile{syst-aux.tex} -\loadcorefile{syst-lua.tex} +\loadmarkfile{syst-aux} +\loadmarkfile{syst-lua} \loadmarkfile{syst-con} \loadmarkfile{syst-fnt} @@ -45,8 +45,9 @@ \loadmarkfile{supp-fil} \loadmarkfile{supp-dir} -\loadmkivfile{char-ini.tex} -\loadmkivfile{char-utf.tex} +\loadmarkfile{char-ini} +\loadmarkfile{char-utf} +\loadmarkfile{char-act} \loadmarkfile{mult-ini} \loadcorefile{mult-fst.tex} @@ -54,25 +55,25 @@ \loadcorefile{mult-def.tex} \loadmarkfile{mult-chk} -\loadmkivfile{luat-ini.tex} +\loadmarkfile{luat-ini} -\loadmkivfile{toks-ini.tex} +\loadmarkfile{toks-ini} -\loadmkivfile{node-ini.tex} -\loadmkivfile{node-fin.tex} -\loadmkivfile{node-par.tex} +\loadmarkfile{node-ini} +\loadmarkfile{node-fin} +\loadmarkfile{node-par} \loadcorefile{core-var.tex} -\loadcorefile{back-ini.tex} -\loadcorefile{back-pdf.tex} +\loadmarkfile{back-ini} +\loadmarkfile{back-pdf} -\loadmkivfile{attr-ini.tex} +\loadmarkfile{attr-ini} \loadmarkfile{core-env} -\loadmkivfile{trac-lmx.tex} -\loadmkivfile{trac-deb.tex} +\loadmarkfile{trac-lmx} +\loadmarkfile{trac-deb} \loadcorefile{supp-box.tex} @@ -84,9 +85,7 @@ \loadcorefile{supp-ali.tex} \loadcorefile{supp-num.tex} -\loadcorefile{typo-ini.tex} - -\loadcorefile{verb-ini.tex} +\loadmarkfile{typo-ini} \loadcorefile{core-ins.tex} \loadcorefile{core-fil.tex} @@ -110,14 +109,11 @@ \loadmarkfile{core-two} \loadcorefile{core-stg.tex} -% \loadcorefile{spec-ini.tex} -% \loadcorefile{spec-mis.tex} -% \loadcorefile{spec-def.tex} -% \loadcorefile{spec-var.tex} - \loadmarkfile{colo-ini} \loadmarkfile{colo-ext} +\loadmarkfile{trac-vis} + \loadcorefile{lang-mis.tex} \loadmarkfile{lang-url} @@ -141,41 +137,39 @@ \loadmarkfile{sort-ini} -\loadmarkfile{core-rul} +\loadmarkfile{pack-rul} \loadcorefile{lxml-ini} -\loadcorefile{strc-ini} -\loadcorefile{strc-doc} -\loadcorefile{strc-mar} -\loadcorefile{strc-prc} -\loadcorefile{strc-sbe} -\loadcorefile{strc-lst} -\loadcorefile{strc-sec} -\loadcorefile{strc-num} -\loadcorefile{strc-ren} -\loadcorefile{strc-xml} -\loadcorefile{strc-pag} % hm, depends on core-num -\loadcorefile{strc-def} % might happen later -\loadcorefile{strc-ref} -\loadcorefile{strc-reg} +\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} \loadcorefile{bibl-bib} \loadmarkfile{core-spa} \loadcorefile{core-grd.tex} -\loadmarkfile{core-pos} +\loadmarkfile{anch-pos} \loadcorefile{core-mak.tex} -\loadmarkfile{core-ver} -\loadcorefile{core-vis.tex} -\loadmarkfile{core-nav} -\loadmarkfile{core-obj} +\loadmarkfile{scrn-nav} +\loadmarkfile{pack-obj} -\loadcorefile{strc-itm.tex} -\loadcorefile{strc-des.tex} -\loadcorefile{strc-syn.tex} +\loadmarkfile{strc-itm} +\loadmarkfile{strc-des} +\loadmarkfile{strc-syn} \loadmarkfile{core-sys} @@ -187,12 +181,12 @@ \loadmarkfile{page-txt} \loadcorefile{page-sid.tex} -\loadcorefile{strc-flt.tex} +\loadmarkfile{strc-flt} \loadcorefile{page-mis.tex} \loadcorefile{page-mul.tex} \loadcorefile{page-set.tex} -\loadcorefile{page-lyr.tex} +\loadmarkfile{pack-lyr} \loadcorefile{page-mak.tex} \loadmarkfile{page-lin} @@ -201,14 +195,15 @@ \loadmarkfile{core-job} % why so late? -\loadmarkfile{core-buf} +\loadmarkfile{buff-ini} +\loadmarkfile{buff-ver} -\loadcorefile{strc-blk.tex} +\loadmarkfile{strc-blk} \loadcorefile{page-imp.tex} -\loadmarkfile{core-int} -\loadcorefile{strc-bkm.tex} % bookmarks +\loadmarkfile{scrn-int} +\loadmarkfile{strc-bkm} % bookmarks \loadcorefile{tabl-pln.tex} \loadcorefile{thrd-tab.tex} @@ -220,34 +215,35 @@ \loadcorefile{tabl-tsp.tex} \loadmarkfile{java-ini} -\loadmarkfile{core-fld} -\loadcorefile{core-hlp.tex} -\loadcorefile{char-enc.tex} +\loadmarkfile{scrn-fld} +\loadmarkfile{scrn-hlp} + +\loadmarkfile{char-enc} \loadmarkfile{font-ini} \loadmarkfile{font-unk} \loadmarkfile{font-tra} \loadmarkfile{font-uni} \loadmarkfile{font-col} -\loadcorefile{typo-spa.tex} -\loadcorefile{typo-krn.tex} -\loadcorefile{typo-mir.tex} -\loadcorefile{typo-brk.tex} -\loadcorefile{typo-cap.tex} +\loadmarkfile{typo-spa} +\loadmarkfile{typo-krn} +\loadmarkfile{typo-mir} +\loadmarkfile{typo-brk} +\loadmarkfile{typo-cap} \loadmarkfile{type-ini} \loadcorefile{type-def.tex} -\loadcorefile{scrp-ini.tex} +\loadmarkfile{scrp-ini} \loadmarkfile{prop-ini} \loadmarkfile{prop-lay} \loadmarkfile{prop-mis} -\loadmkivfile{mlib-ctx.tex} -\loadmkivfile{mlib-pdf.tex} -\loadmkivfile{mlib-pps.tex} +\loadmarkfile{mlib-ctx} +\loadmarkfile{mlib-pdf} +\loadmarkfile{mlib-pps} \loadmarkfile{meta-ini} \loadmarkfile{meta-tex} @@ -260,9 +256,9 @@ \loadcorefile{page-plg.tex} \loadcorefile{page-str.tex} -\loadcorefile{core-pgr.tex} -\loadcorefile{core-bar.tex} -\loadcorefile{core-snc.tex} +\loadcorefile{anch-pgr.tex} +\loadcorefile{anch-bar.tex} +\loadcorefile{anch-snc.tex} \loadmarkfile{math-pln} \loadmarkfile{math-ini} @@ -277,24 +273,24 @@ \loadmarkfile{math-inl} \loadmarkfile{math-dis} -\loadcorefile{strc-mat.tex} +\loadmarkfile{strc-mat} \loadmarkfile{chem-ini} \loadmarkfile{chem-str} \loadmarkfile{core-fnt} -\loadcorefile{strc-not.tex} +\loadmarkfile{strc-not} \loadcorefile{core-lnt.tex} \loadmarkfile{core-mis} -\loadcorefile{core-trf.tex} -\loadmarkfile{core-inc} -\loadcorefile{core-fig.tex} +\loadmarkfile{grph-trf} +\loadmarkfile{grph-inc} +\loadmarkfile{grph-fig} -\loadcorefile{core-box.tex} +\loadmarkfile{pack-box} \loadcorefile{page-app.tex} \loadmarkfile{meta-fig} @@ -311,7 +307,7 @@ \loadcorefile{cont-log.tex} -\loadcorefile{task-ini.tex} +\loadmarkfile{task-ini} \loadmarkfile{core-ctx} @@ -345,6 +341,4 @@ }% \to \everydump -\setsystemmode{experimental} % test with *experimental - \protect \errorstopmode \dump \endinput diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 08ffc3a60..fa9866a71 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2009.05.28 11:23} +\edef\contextversion{2009.06.02 09:30} %D For those who want to use this: diff --git a/tex/context/base/core-bar.tex b/tex/context/base/core-bar.tex deleted file mode 100644 index 5b28afb9d..000000000 --- a/tex/context/base/core-bar.tex +++ /dev/null @@ -1,194 +0,0 @@ -%D \module -%D [ file=core-bar, -%D version=2003.03.16, -%D title=\CONTEXT\ Core 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 Core 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/core-blk.tex b/tex/context/base/core-blk.tex deleted file mode 100644 index b224bf18e..000000000 --- a/tex/context/base/core-blk.tex +++ /dev/null @@ -1,548 +0,0 @@ -%D \module -%D [ file=core-blk, % split off core-buf.tex -%D version=2000.01.05, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Blockmoves, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% investigate etex's \readline and \scantokens - -\writestatus{loading}{ConTeXt Core 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/core-box.tex b/tex/context/base/core-box.tex deleted file mode 100644 index 97811e78f..000000000 --- a/tex/context/base/core-box.tex +++ /dev/null @@ -1,954 +0,0 @@ -%D \module -%D [ file=core-box, -%D version=2002.04.12, -%D title=\CONTEXT\ Core 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 Core 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} - -\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 - -\def\offset {\dodoubleempty\dooffsetbox [\hbox]} % yes or no -\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} - -\def\ltabbed{\dotabbed\relax\hss} -\def\rtabbed{\dotabbed\hss \relax} -\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 - -\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]} - -\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/core-buf.lua b/tex/context/base/core-buf.lua deleted file mode 100644 index 389ebde35..000000000 --- a/tex/context/base/core-buf.lua +++ /dev/null @@ -1,499 +0,0 @@ -if not modules then modules = { } end modules ['core-buf'] = { - version = 1.001, - comment = "companion to core-buf.tex", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- ctx lua reference model / hooks and such --- to be optimized - --- redefine buffers.get - -utf = unicode.utf8 - -buffers = { } -buffers.data = { } -buffers.hooks = { } -buffers.flags = { } -buffers.commands = { } -buffers.visualizers = { } - --- if needed we can make 'm local - -local utf = unicode.utf8 - -local concat, texsprint, texprint, texwrite = table.concat, tex.sprint, tex.print, tex.write -local utfbyte, utffind, utfgsub = utf.byte, utf.find, utf.gsub -local byte, sub, find, char, gsub, rep, lower = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower -local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues - -local vrbcatcodes = tex.vrbcatcodes -local ctxcatcodes = tex.ctxcatcodes - -local data, commands, flags, hooks, visualizers = buffers.data, buffers.commands, buffers.flags, buffers.hooks, buffers.visualizers - -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 = bufferdata:sub(1,#bufferdata-1) - else - dn = dn .. "\n" .. bufferdata:sub(1,#bufferdata-1) - end - dn = dn:gsub("[\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 - -commands.no_break = "\\doverbatimnobreak" -commands.do_break = "\\doverbatimgoodbreak" -commands.begin_of_line_command = "\\doverbatimbeginofline" -commands.end_of_line_command = "\\doverbatimendofline" -commands.empty_line_command = "\\doverbatimemptyline" - -function buffers.verbatimbreak(n,m) - if flags.optimize_verbatim then - if n == 2 or n == m then - texsprint(commands.no_break) - else - texsprint(commands.do_break) - end - end -end - -function buffers.strip(lines) - local first, last = 1, #lines - for i=first,last do - if #lines[i] == 0 then - first = first + 1 - else - break - end - end - for i=last,first,-1 do - if #lines[i] == 0 then - last = last - 1 - else - break - end - end - return first, last, last - first + 1 -end - -function buffers.type(name) - local lines = data[name] - local action = buffers.typeline - if lines then - if type(lines) == "string" then - lines = lines:splitlines() - end - local line, n = 0, 0 - local first, last, m = buffers.strip(lines) - for i=first,last do - n, line = action(lines[i], n, m, line) - end - end -end - -function buffers.loaddata(filename) -- this one might go away - -- this will be cleaned up when we have split supp-fil completely - -- instead of half-half - local ok, str, n = resolvers.loaders.tex(filename) - if not str then - ok, str, n = resolvers.loaders.tex(file.addsuffix(filename,'tex')) - end - return str or "" -end - -function buffers.typefile(name) -- still somewhat messy, since name can be be suffixless - local str = buffers.loaddata(name) - if str and str~= "" then - local lines = str:splitlines() - local line, n, action = 0, 0, buffers.typeline - local first, last, m = buffers.strip(lines) - for i=first,last do - n, line = action(lines[i], n, m, line) - end - end -end - -function buffers.typeline(str,n,m,line) - n = n + 1 - buffers.verbatimbreak(n,m) - if str:find("%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 - -function buffers.save(name) - if not name or name == "" then - name = tex.jobname - end - local b, f = data[name], tex.jobname .. "-" .. name .. ".tmp" - b = (b and type(b) == "table" and table.join(b,"\n")) or b or "" - io.savedata(f,b) -end - -local printer = (lpeg.linebyline/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 - printer:match(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 - local t = { } - if type(names) == "table" then - for i=1,#names do - local c = content(names[i],separator) - if c ~= "" then - t[#t+1] = c - end - end - else - for name in names:gmatch("[^,]+") do - local c = content(name,separator) - if c ~= "" then - t[#t+1] = c - end - end - end - return concat(t,separator or "\n") -- "\n" is safer due to comments and such -end - -local function tobyte(c) - return " [" .. byte(c) .. "] " -end - -function buffers.inspect(name) - local b = data[name] - if b then - if type(b) == "table" then - for _,v in ipairs(b) do - if v == "" then - texsprint(ctxcatcodes,"[crlf]\\par ") -- space ? - else - texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte)),"\\par") - end - end - else - texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte))) - end - end -end - --- maybe just line(n,str) empty(n,str) - -visualizers.default = { } -visualizers.tex = { } -visualizers.mp = { } - -visualizers.escapetoken = nil -visualizers.tablength = 7 - -visualizers.enabletab = true -- false -visualizers.enableescape = false -visualizers.obeyspace = true - -function visualizers.reset() ---~ visualizers.enabletab = false ---~ visualizers.enableescape = false ---~ buffers.currentvisualizer = 'default' -end - -buffers.currentvisualizer = 'default' - -function buffers.setvisualizer(str) - buffers.currentvisualizer = lower(str) - if not visualizers[buffers.currentvisualizer] then - buffers.currentvisualizer = 'default' - end -end - -function buffers.doifelsevisualizer(str) - cs.testcase((str ~= "") and (visualizers[lower(str)] ~= nil)) -end - --- calling routines, don't change - -function hooks.flush_line(str,nesting) - str = str:gsub(" *[\n\r]+ *"," ") - local flush_line = visualizers[buffers.currentvisualizer].flush_line - if flush_line then - flush_line(str,nesting) - else - visualizers.default.flush_line(str,nesting) - end -end - -function hooks.begin_of_line(n) - local begin_of_line = visualizers[buffers.currentvisualizer].begin_of_line - if begin_of_line then - begin_of_line(n) - else - visualizers.default.begin_of_line(n) - end -end - -function hooks.end_of_line() - local end_of_line = visualizers[buffers.currentvisualizer].end_of_line - if end_of_line then - end_of_line() - else - visualizers.default.end_of_line(str) - end -end - -function hooks.empty_line() - local empty_line = visualizers[buffers.currentvisualizer].empty_line - if empty_line then - empty_line() - else - visualizers.default.empty_line() - end -end - -function hooks.line(str) - local line = visualizers[buffers.currentvisualizer].line - if visualizers.enabletab then - str = string.tabtospace(str,visualizers.tablength) - else - str = gsub(str,"\t"," ") - end - if line then - return line(str) - else - return visualizers.default.line(str) - end -end - --- defaults - -function visualizers.default.flush_line(str) - texsprint(ctxcatcodes,buffers.escaped(str)) -end - -function visualizers.default.begin_of_line(n) - texsprint(ctxcatcodes, commands.begin_of_line_command,"{",n,"}") -end - -function visualizers.default.end_of_line() - texsprint(ctxcatcodes,commands.end_of_line_command) -end - -function visualizers.default.empty_line() - texsprint(ctxcatcodes,commands.empty_line_command) -end - -function visualizers.default.line(str) - return str -end - --- special one - -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 = str:gsub(" *[\n\r]+ *"," ") - local result, c, nested, i = "", "", 0, 1 - 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 c:find("%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)) .. " " .. string.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, result) - if n then - if state ~= n then - if state > 0 then - result[#result+1] = "\\sop[" .. buffers.currentcolors[n] .. "]" - else - result[#result+1] = "\\bop[" .. buffers.currentcolors[n] .. "]" - end - return n - end - elseif state > 0 then - result[#result+1] = "\\eop " - return 0 - end - return state -end - -function buffers.finish_state(state, result) - if state > 0 then - result[#result+1] = "\\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 - -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 - -function buffers.escaped_chr(ch) - if ch == " " then - return "\\obs " - else - return "\\char" .. utfbyte(ch) .. " " - end -end - -function visualizers.default.flush_line(str) - str = str:gsub(" *[\n\r]+ *"," ") - if visualizers.obeyspace then - for c in utfcharacters(str) do - if c == " " then - texsprint(ctxcatcodes,"\\obs ") - else - texsprint(vrbcatcodes,c) - end - end - else - texsprint(vrbcatcodes,str) - end -end diff --git a/tex/context/base/core-buf.mkii b/tex/context/base/core-buf.mkii deleted file mode 100644 index 9937fae01..000000000 --- a/tex/context/base/core-buf.mkii +++ /dev/null @@ -1,348 +0,0 @@ -%D \module -%D [ file=core-buf, % blocks are moved to core-blk -%D version=2000.01.05, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Buffers, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Buffers} - -\unprotect - -% 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]}% - \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}% - \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}% - \getparameters[\??bu#1][#2]% - \fi} - -\def\definebuffer - {\dodoubleempty\dodefinebuffer} - -\def\getbuffer - {\dodoubleempty\dogetbuffer} - -\def\dogetbuffer[#1][#2]% - {\ifsecondargument - \dodogetbuffer[#1][#2]% - \else - \dodogetbuffer[][#1]% - \fi} - -\def\dogetbufferasis{\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing}% - -\def\dodogetbuffer[#1][#2]% - {\getvalue{\??bu#1\c!before}% - \dobuffer{16}{#2}\dogetbufferasis - \getvalue{\??bu#1\c!after}} - -\def\typebuffer - {\dodoubleempty\dotypebuffer} - -\def\dogetfilebuffer{\typefile{\TEXbufferfile{\currentbuffer}}} - -\def\dotypebuffer[#1][#2]% - {\iffirstargument - \dobuffer{17}{#1}\dogetfilebuffer - \else - \dobuffer{17}{#2}\dogetfilebuffer - \fi} - -\def\dobuffer#1#2#3% - {\doifelsenothing{#2} - {\dodobuffer#3\jobname} - {\processcommalist[#2]{\dodobuffer#3}}} - -\def\dodobuffer#1#2% command name - {\pushmacro\currentbuffer - \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}% - \beginrestorecatcodes - #1% - \endrestorecatcodes - \popmacro\currentbuffer} - -\def\processTEXbuffer{\getbuffer} % handy - -% seldom used, only in a few projects that demanded more speed - -\def\dostartmemorybuffer - {\dosingleempty\dostartmemorybuffer} - -\long\def\dostartmemorybuffer[#1]#2\stopbuffer - {\setbuffer[#1]#2\endbuffer} - -\let\dostartfilebuffer\startbuffer - -\def\usememorybuffers{\let\startbuffer\dostartmemorybuffer} -\def\usefilebuffers {\let\startbuffer\dostartfilebuffer} - -% this features is soldom used (complex examns where we need to fetch -% special parts of a text -% -% this is not yet supported in mkiv (relatively easy to do but there -% we don't have the par tags but need to grab 'm - -\def\skippedbufferparagraphs{0} - -\let\startbufferparagraph\relax -\let\stopbufferparagraph \par % \relax - -\newcount\currentbufferparagraph - -\def\getbufferparagraphs - {\dodoubleempty\dogetbufferparagraphs} - -\def\dosetbufferoffset#1% - {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}} - {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}} - {\currentbufferparagraph \zerocount}% - \relax} - -\def\dogetbufferparagraphs[#1][#2]% - {\iffirstargument - \ifsecondargument - \dosetbufferoffset{#1}% - \doifelse{#2}\v!all - {\def\startbufferparagraph{\normalbufferparagraph{#1}}} - {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}% - \def\stopbufferparagraph{\dostopbufferparagraph{#1}}% - \def\next{\getparagraphedbuffer[#1]}% - \else - \dosetbufferoffset\empty - \def\startbufferparagraph{\filterbufferparagraph{}{#1}}% - \def\stopbufferparagraph{\dostopbufferparagraph{}}% - \def\next{\getparagraphedbuffer[]}% - \fi - \else - \dosetbufferoffset\empty - \def\startbufferparagraph{\normalbufferparagraph{}}% - \def\stopbufferparagraph{\dostopbufferparagraph{}}% - \def\next{\getparagraphedbuffer[]}% - \fi - \next} - -\def\dogetparagraphbuffer{\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing} - -\def\getparagraphedbuffer[#1]% - {\dobuffer{16}{#1}\dogetparagraphbuffer} - -\def\dostopbufferparagraph#1% - {\getvalue{\??bu#1\c!after}\par} - -\def\dostartbufferparagraph#1% - {\par\getvalue{\??bu#1\c!before}} - -\def\normalbufferparagraph - {\advance\currentbufferparagraph \plusone - \ifnum\currentbufferparagraph>\zerocount - \expandafter\dostartbufferparagraph - \else - \expandafter\gobbleoneargument - \fi} - -\def\filterbufferparagraph#1#2% - {\advance\currentbufferparagraph \plusone - \ifcase\currentbufferparagraph - \@EA\gobblebufferparagraph - \else - \doifinsetelse{\the\currentbufferparagraph}{#2} - {\@EA\dostartbufferparagraph} - {\@EA\fakebufferparagraph}% - \fi - {#1}} - -\long\def\gobblebufferparagraph#1#2\stopbufferparagraph - {} - -\def\fakebufferparagraph#1% - {\bgroup - \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}% - \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}} - -% definitions - -\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes] - -\setupbuffer - [\c!paragraph=\v!no, - \c!before=, - \c!after=] - -\protect \endinput diff --git a/tex/context/base/core-buf.mkiv b/tex/context/base/core-buf.mkiv deleted file mode 100644 index 8b69616b9..000000000 --- a/tex/context/base/core-buf.mkiv +++ /dev/null @@ -1,314 +0,0 @@ -%D \module -%D [ file=core-buf, % blocks are moved to core-blk -%D version=2000.01.05, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Buffers, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Buffers} - -\registerctxluafile{core-buf}{1.001} - -\ifdefined\doinitializeverbatim \else% temp hack - \ifdefined\mkinitializeverbatim - \let\doinitializeverbatim\mkinitializeverbatim - \else - \def\doinitializeverbatim{\tttf} - \fi -\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} - -\def\setupbuffer - {\dodoubleempty\dosetupbuffer} - -\def\dosetupbuffer[#1][#2]% - {\ifsecondargument - \getparameters[\??bu#1][#2]% - \else - \getparameters[\??bu][#1]% - \fi} - -\def\dodefinebuffer[#1][#2]% - {\iffirstargument % else problems - \doglobal\increment\nofdefinedbuffers - \letvalue{\??bu#1\c!number }\nofdefinedbuffers - \letvalue{\??bu#1\c!paragraph}\v!no - \setevalue{\e!start#1}{\noexpand\dostartbuffer[#1][def-\nofdefinedbuffers][\e!start#1][\e!stop#1]}% - \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}% - \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}% - \getparameters[\??bu#1][#2]% - \fi} - -\def\definebuffer - {\dodoubleempty\dodefinebuffer} - -\def\getbuffer - {\dodoubleempty\dogetbuffer} - -\def\dogetbuffer[#1][#2]% - {\ifsecondargument - \dodogetbuffer[#1][#2]% - \else - \dodogetbuffer[][#1]% - \fi} - -\def\dogetbufferasis{\ctxlua{buffers.get("\currentbuffer")}} - -\def\dodogetbuffer[#1][#2]% - {\getvalue{\??bu#1\c!before}% - \dobuffer{16}{#2}\dogetbufferasis - \getvalue{\??bu#1\c!after}} - -\def\typebuffer - {\dodoubleempty\dotypebuffer} - -\def\doprocessbufferverbatim - {\doinitializeverbatim - \ctxlua{buffers.type("\currentbuffer")}} - -\def\doprocessbufferlinesverbatim#1#2#3% - {#2% - % todo, set up numbers - \doinitializeverbatim - \ctxlua{buffers.type("\currentbuffer")} - #3} - -\def\doifelsebuffer#1% - {\ctxlua{buffers.doifelsebuffer("#1")}} - -\def\dodotypebuffer#1#2#3% see dodotypefile - {\doifelsebuffer{#3} - {\dosometyping{#1}{#2}{#3}\doprocessbufferverbatim\doprocessbufferlinesverbatim} - {\reporttypingerror{#3}}} - -\def\dotypefilebuffer{\dodotypebuffer{\v!file}{}{\currentbuffer}}% - -\def\dotypebuffer[#1][#2]% - {\iffirstargument - \dobuffer{17}{#1}\dotypefilebuffer - \else - \dobuffer{17}{#2}\dotypefilebuffer - \fi} - -\def\dobuffer#1#2#3% - {\doifelsenothing{#2} - {\dodobuffer#3\jobname} - {\processcommalist[#2]{\dodobuffer#3}}} - -\def\dodobuffer#1#2% command name - {\pushmacro\currentbuffer - \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}% - #1% - \popmacro\currentbuffer} - -\def\processTEXbuffer{\getbuffer} % handy - -% extras: - -\def\inspectbuffer - {\dosingleempty\doinspectbuffer} - -\def\doinspectbuffer[#1]% - {\setcurrentbuffer{#1}% - \ctxlua{buffers.inspect("\currentbuffer")}} - -% seldom used, only in a few projects that demanded more speed - -\let\usememorybuffers\relax -\let\usefilebuffers \relax - -% this features is soldom used (complex examns where we need to fetch -% special parts of a text -% -% this is not yet supported in mkiv (relatively easy to do but there -% we don't have the par tags but need to grab 'm - -\def\skippedbufferparagraphs{0} - -\let\startbufferparagraph\relax -\let\stopbufferparagraph \par % \relax - -\newcount\currentbufferparagraph - -\def\getbufferparagraphs - {\dodoubleempty\dogetbufferparagraphs} - -\def\dosetbufferoffset#1% - {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}} - {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}} - {\currentbufferparagraph \zerocount}% - \relax} - -\def\dogetbufferparagraphs[#1][#2]% - {\iffirstargument - \ifsecondargument - \dosetbufferoffset{#1}% - \doifelse{#2}\v!all - {\def\startbufferparagraph{\normalbufferparagraph{#1}}} - {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}% - \def\stopbufferparagraph{\dostopbufferparagraph{#1}}% - \def\next{\getparagraphedbuffer[#1]}% - \else - \dosetbufferoffset\empty - \def\startbufferparagraph{\filterbufferparagraph{}{#1}}% - \def\stopbufferparagraph{\dostopbufferparagraph{}}% - \def\next{\getparagraphedbuffer[]}% - \fi - \else - \dosetbufferoffset\empty - \def\startbufferparagraph{\normalbufferparagraph{}}% - \def\stopbufferparagraph{\dostopbufferparagraph{}}% - \def\next{\getparagraphedbuffer[]}% - \fi - \next} - -\def\dotypeparagraphbuffer{\ctxlua{buffers.get("\currentbuffer")}} - -\def\getparagraphedbuffer[#1]% - {\dobuffer{16}{#1}\dotypeparagraphbuffer} - -\def\dostopbufferparagraph#1% - {\getvalue{\??bu#1\c!after}\par} - -\def\dostartbufferparagraph#1% - {\par\getvalue{\??bu#1\c!before}} - -\def\normalbufferparagraph - {\advance\currentbufferparagraph \plusone - \ifnum\currentbufferparagraph>\zerocount - \expandafter\dostartbufferparagraph - \else - \expandafter\gobbleoneargument - \fi} - -\def\filterbufferparagraph#1#2% - {\advance\currentbufferparagraph \plusone - \ifcase\currentbufferparagraph - \@EA\gobblebufferparagraph - \else - \doifinsetelse{\the\currentbufferparagraph}{#2} - {\@EA\dostartbufferparagraph} - {\@EA\fakebufferparagraph}% - \fi - {#1}} - -\long\def\gobblebufferparagraph#1#2\stopbufferparagraph - {} - -\def\fakebufferparagraph#1% - {\bgroup - \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}% - \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}} - -% definitions - -\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes] - -\setupbuffer - [\c!paragraph=\v!no, - \c!before=, - \c!after=] - -% only mkiv: - -\def\savebuffer{\dosingleempty\dosavebuffer} -\def\dosavebuffer[#1]{\ctxlua{buffers.save("#1")}} - -\protect \endinput diff --git a/tex/context/base/core-dat.tex b/tex/context/base/core-dat.tex deleted file mode 100644 index 44a82e1f3..000000000 --- a/tex/context/base/core-dat.tex +++ /dev/null @@ -1,248 +0,0 @@ -%D \module -%D [ file=core-dat, % was core-02a, -%D version=1999.08.10, % 1997.03.31, -%D title=\CONTEXT\ Core Macros, -%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. - -% THIS WILL DISAPPEAR, I.E. BE MOVED TO A MODULE - -\writestatus{loading}{ConTeXt Core Macros / Database Support} - -% messages moved - -% messages moved - -% messages moved - -% TOM : - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -\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 mechaism, the current implementation is -%D prefered out of speed reasons. - -\protect \endinput diff --git a/tex/context/base/core-des.tex b/tex/context/base/core-des.tex deleted file mode 100644 index dc7136c40..000000000 --- a/tex/context/base/core-des.tex +++ /dev/null @@ -1,921 +0,0 @@ -%D \module -%D [ file=core-des, -%D version=1997.03.31, -%D title=\CONTEXT\ Core 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 Core Macros / Descriptions} - -%D In order to be more flexible with theorems Aditya Mahajan added -%D support for titles and endsymbols. At the same time we some more -%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/core-fig.tex b/tex/context/base/core-fig.tex deleted file mode 100644 index 63aa1d193..000000000 --- a/tex/context/base/core-fig.tex +++ /dev/null @@ -1,559 +0,0 @@ -%D \module -%D [ file=core-fig, -%D version=2006.08.26, % overhaul of 1997.03.31 -%D title=\CONTEXT\ Core Macros, -%D subtitle=Figure Inclusion, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Figure 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/core-fld.mkii b/tex/context/base/core-fld.mkii deleted file mode 100644 index 2b177c916..000000000 --- a/tex/context/base/core-fld.mkii +++ /dev/null @@ -1,1080 +0,0 @@ -%D \module -%D [ file=core-fld, -%D version=1997.05.18, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Fields, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% \appendtocommalist versus \addtocommalist -% -% * as default trigger in radiofields ? -% -% beware: weblink plugin truncates on length, while save as doesn't; -% more precise: (1) first time right string is sent, (2) -% internal string truncated, (3) second time truncated -% string is sent. - -\writestatus{loading}{ConTeXt Core Macros / Fields} - -% messages - -\definemessageconstant{fields} - -\unprotect - -%D First we hook fields into the (viewer based) layering mechanism -%D (implemented as properties). - -\ifx\currentlayerproperty\undefined\else \let\currentlayerproperty\empty\fi - -\appendtoks - \doif\@@iafieldlayer\v!auto - {\def\@@iafieldlayer{\currentlayerproperty}}% -\to \everysetupinteraction - -\setupinteraction - [\c!fieldlayer=\v!auto] % auto by default - -%D Internal command, linked to \type{\definesymbol}. - -\def\dogetfieldsymbol#1% - {\getobject{SYM}{#1}} - -\def\dopresetfieldsymbol#1% - {\checkobjectreferences - \doifobjectfoundelse{SYM}{#1} - {} - {\settightobject{SYM}{#1}\hbox{\symbol[#1]}% - \flushatshipout - {\setbox0\hbox{\hskip-\maxdimen\getobject{SYM}{#1}}% - \smashbox0\box0}}} - -\def\presetfieldsymbols[#1]% slow - {\def\dopresetfieldsymbols##1% - {\processcommalist[##1]\dopresetfieldsymbol}% - \@EA\processcommalist\@EA[#1]\dopresetfieldsymbols} - -\def\definedefaultsymbols - {\definesymbol[defaultyes][$\times$]% - \definesymbol[defaultno][$\cdot$]} - -\def\resetfieldsymbol[#1]% for experimental usage only - {\resetobject{SYM}{#1}} - -%D The interface to the specials. DEFAULT NOG ANDERS - -\def\preparefieldvariables % evt \def's at the outer level (test) or \edef's here for fast testing - {\let\@@DriverFieldNumber \@@fdn - \let\@@DriverFieldStyle \@@fdstyle - \let\@@DriverFieldColor \@@fdcolor - \let\@@DriverFieldBackgroundColor\@@fdfieldbackgroundcolor - \let\@@DriverFieldFrameColor \@@fdfieldframecolor - \let\@@DriverFieldLayer \@@fdfieldlayer - \let\@@DriverFieldOption \@@fdoption - \let\@@DriverFieldAlign \@@fdalign - \let\@@DriverFieldClickIn \@@fdclickin - \let\@@DriverFieldClickOut \@@fdclickout - \let\@@DriverFieldRegionIn \@@fdregionin - \let\@@DriverFieldRegionOut \@@fdregionout - \let\@@DriverFieldAfterKey \@@fdafterkey - \let\@@DriverFieldFormat \@@fdformat - \let\@@DriverFieldValidate \@@fdvalidate - \let\@@DriverFieldCalculate \@@fdcalculate - \let\@@DriverFieldFocusIn \@@fdfocusin - \let\@@DriverFieldFocusOut \@@fdfocusout} - -% todo : remove arguments, consider DriverField a namespace - -\def\presetlinefield - {\preparefieldvariables - \dopresetlinefield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldNumber} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldAlign} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presettextfield - {\preparefieldvariables - \dopresettextfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldNumber} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldAlign} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetchoicefield - {\preparefieldvariables - \dopresetchoicefield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetpopupfield - {\preparefieldvariables - \dopresetpopupfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetcombofield - {\preparefieldvariables - \dopresetcombofield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetcheckfield - {\preparefieldvariables - \presetfieldsymbols[\@@DriverFieldValues]% - \dopresetcheckfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetpushfield - {\preparefieldvariables - %\edef\@@DriverFieldValues{{\@@DriverFieldValues}}% makes sure {a,b,c} is passed - \presetfieldsymbols[\@@DriverFieldValues]% - \dopresetpushfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetradiofield - {\preparefieldvariables - \presetfieldsymbols[\@@DriverFieldValues]% - \dopresetradiofield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldRoot} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetradiorecord - {\preparefieldvariables - \dopresetradiorecord - {\@@DriverFieldName} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldKids} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\setfieldmodes#1#2#3% - {\xdef\@@DriverFieldMode{#1}% % 0 1 2 3 - \xdef\@@DriverFieldFree{#2}% % 0 1 - \xdef\@@DriverFieldAuto{#3}} % 0 1 - -\newevery\everysetfield\relax - -\def\doiffieldelse#1{\doifdefinedelse{fielddata#1}} - -\def\setfield#1#2#3#4#5#6#7#8#9% - {\bgroup - \doglobal\increment\numberoffields - \iftracefields - \doglobal\addtocommalist{#1}\collectedfields - \fi - \the\everysetfield - \setxvalue{fielddata#1}% kortere tag #7 needs expansion etc - {\noexpand\dosetfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}% - \egroup} - -\def\dosetfield#1#2#3#4#5#6#7#8#9% - {\xdef\@@DriverFieldName {#1}% - \xdef\@@DriverFieldType {#2}% - \xdef\@@DriverFieldRoot {#3}% - \xdef\@@DriverFieldParent {#4}% - \xdef\@@DriverFieldKids {#5}% - \xdef\@@DriverFieldGroup {#6}% - \setfieldmodes #7% - \bgroup - \def\par{\string\n\string\n}% - \xdef\@@DriverFieldValues {#8}% - \xdef\@@DriverFieldDefault{#9}% - \egroup} - -\def\changefield#1% - {\setfield{#1}\@@DriverFieldType\@@DriverFieldRoot\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldGroup - {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}\@@DriverFieldValues\@@DriverFieldDefault} - -\def\getfield#1% name - {\doifundefinedelse{fielddata#1} - {\dosetfield{#1}\empty\empty\empty\empty\empty{\empty00}\empty\empty} - {\getvalue{fielddata#1}}} - -\newif\iftracefields \tracefieldsfalse - -\let\tracefields\tracefieldstrue - -\def\doshowfields[#1]% todo: tabulate van maken en runtime - {\bgroup - \switchtobodyfont[8pt,tt]% - \doifsomething{#1}{\def\collectedfields{#1}}% - \ifx\collectedfields\empty - \par specify [fieldlist] or say \type{\tracefieldstrue} first\par - \else - \def\normalizedfieldmode##1##2##3% - {\ifcase0##2 \else\sl\fi - \ifcase0##1 loner\or parent\or clone\or copy\fi}% - \def\dosetfield##1##2##3##4##5##6##7##8##9% - {##1&##2&##3&##4&##5&##6&\normalizedfieldmode##7&##8&##9\cr}% - \halign - {&##\strut\hss\quad\cr - \noalign{\hrule}% - NAME &TYPE &ROOT & - PARENT&KIDS &GROUP & - MODE &VALUES&DEFAULT\cr - \noalign{\hrule}% - \@EA\globalprocesscommalist\@EA[\collectedfields]\getfield - \noalign{\hrule}}% - \fi - \egroup} - -\def\showfields - {\dosingleempty\doshowfields} - -\def\dologfields[#1]% - {\bgroup - \immediate\openout\scratchwrite=fields.log - \doifsomething{#1}{\def\collectedfields{#1}}% - \ifx\colledtedfields\empty - \immediate\write\scratchwrite{use \tracefieldstrue}% - \else - \def\normalizedfieldmode##1##2##3% - {\edef\@@DriverFieldMode - {\ifcase##1 loner \or parent \or clone \or copy \fi - \ifcase##2 \else(done)\fi}}% - \def\dosetfield##1##2##3##4##5##6##7##8##9% - {\normalizedfieldmode##7% - \immediate\write\scratchwrite - {N=##1 / T=##2 / R=##3 / P=##4 / K=##5 / G=##6 / - M=\@@DriverFieldMode\space/ V=##8 / D=##9}}% - \processcommacommand[\collectedfields]\getfield - \fi - \immediate\closeout\scratchwrite - \egroup} - -\def\logfields - {\dosingleempty\doLogFields} - -%D \starttyping -%D \definefield [name] [type] [group] [values] [default] -%D -%D \definefield [WWWW] [text] [textsetup] [default text] -%D \definefield [XXXX] [push] [pushsetup] [yes,no] [yes] -%D \definefield [XXXX] [check] [checksetup] [yes,no] [yes] -%D \definefield [YYYY] [combo] [combosetup] [a,b,c,d] [b] -%D \definefield [ZZZZ] [radio] [radiosetup] [W,X,Y,Z] [Y] -%D -%D \definesubfield [W] [subsetup] [p,q] -%D \definesubfield [X,Y] [subsetup] [p,r] -%D \definesubfield [Z] [subsetup] [y,z] -%D -%D evt \definemainfield ... wanneer geplaatst voor subs gegeven -%D -%D \clonefield [XXXX] [XX,YY] [mysetup] [on,off] -%D \clonefield [Z] [AA,BB] [somesetup] [true,false] -%D \clonefield [Z] [CC,DD] [anothersetup] -%D -%D \copyfield [XXXX] [PP,QQ,RR] -%D -%D \field[XXXX] -%D \fitfield[XXXX] -%D \stoptyping - -\newif\ifdefinemainfield \definemainfieldfalse - -%D We need to keep track of cloned (related) fields and so by -%D maintaining lists of field clones. -%D -%D The first alternative used a two pass data list and was -%D implemented as follows: -%D -%D \starttyping -%D \def\getmainfieldkids#1% -%D {\let\@@DriverFieldKids\empty -%D \ifdefinemainfield -%D \definetwopasslist{fld:#1}% defined by system -%D \doloop -%D {\gettwopassdata{fld:#1}% -%D \iftwopassdatafound -%D %\addtocommalist\twopassdata\@@DriverFieldKids -%D \appendtocommalist\twopassdata\@@DriverFieldKids -%D \else -%D \exitloop -%D \fi}% -%D \fi} -%D \stoptyping -%D -%D However, the next alternative is much faster when we have -%D a field with thousands of clones, something not that -%D imaginary. -%D -%D \starttyping -%D \def\getmainfieldkids#1% -%D {\let\@@DriverFieldKids\empty -%D \ifdefinemainfield -%D \definetwopasslist{fld:#1}% runtime defined by system -%D \getnamedtwopassdatalist{fld:#1}\@@DriverFieldKids -%D \fi} -%D \stoptyping -%D -%D The data is written by file using: -%D -%D \starttyping -%D \newcounter\nofmainfieldkids -%D -%D \def\setmainfieldkid#1#2% -%D {\doglobal\increment\nofmainfieldkids -%D \savetwopassdata{fld:#1}{\nofmainfieldkids}{#2}} -%D \stoptyping -%D -%D The trade of of this mechanism is that for each cloned or -%D copied field, the uitlity file is to be read in order to -%D fetch the data. -%D -%D The next, much faster alternative uses a dedicated % -%D reference mechanism. - -\def\setmainfieldkid#1#2% - {\immediatewriteutilitycommand{\fieldreference{#1}{#2}}} - -\def\checkfieldreferences - {\startnointerference - \protectlabels - \doutilities{fieldreferences}\jobname\empty\relax\relax - \global\let\checkfieldreferences\relax - \stopnointerference} - -\def\setfieldreferences - {\def\fieldreference##1##2% - {\ifundefined{\r!widget##1}% - \setxvalue{\r!widget##1}{##2}% - \else - \edef\!!stringa{\getvalue{\r!widget##1}}% - \setxvalue{\r!widget##1}{\!!stringa,##2}% - \fi}} - -\def\resetfieldreferences - {\let\fieldreference\gobbletwoarguments} - -\def\getmainfieldkids#1% - {\checkfieldreferences - \ifdefinemainfield - \doifundefinedelse{\r!widget#1}% - {\let\@@DriverFieldKids\empty} - {\@EA\let\@EA\@@DriverFieldKids\csname\r!widget#1\endcsname}% - \else - \let\@@DriverFieldKids\empty - \fi} - -\resetfieldreferences - -%D Of course it costs a few more tokens to implement, but it's -%D worth the memory: running for instance the 2000 page -%D english examns publishing on demand document went down from -%D 1350 seconds to less than 950 on a 650 Mhz pentium. - -\def\definefield - {\definemainfieldfalse\doquintupleempty\dodefinefield} - -\def\definemainfield - {\definemainfieldtrue \doquintupleempty\dodefinefield} - -\let\collectedfields\empty -\newcounter\numberoffields -\newcounter\totalnumberoffields - -\def\savenumberoffields - {\ifcase\numberoffields\relax\else - \savecurrentvalue\totalnumberoffields\numberoffields - \fi} - -\appendtoks \savenumberoffields \to \everybye % \everylastshipout - -% \def\presetfieldreferences -% {\ifnum\totalnumberoffields>0 -% \definereference[AtOpenInitializeForm][\v!ResetForm]% -% \fi} -% -% \definereference[AtOpenInitializeForm][\v!geen] -% -% \appendtoks \presetfieldreferences \to \everycheckreferences - -\def\dodefinefield[#1][#2][#3][#4][#5]% - {\ifsecondargument - \edef\currentfieldname{#1}% just in case we're inside a loop - \doifundefinedelse{define#2field} - {\writestatus\m!fields{unknown field type #2}} - {\doifundefined{fielddata\currentfieldname} - {\getmainfieldkids\currentfieldname - \ifdefinemainfield - \ifx\@@DriverFieldKids\empty - \let\@@DriverFieldMode\fieldlonermode - \else - \let\@@DriverFieldMode\fieldparentmode - \fi - \def\@@DriverFieldAuto{1}% - \else - \let\@@DriverFieldMode\fieldlonermode - \def\@@DriverFieldAuto{0}% - \fi - \def\@@DriverFieldFree{0}% - \getvalue{define#2field}{\currentfieldname}{#2}{#3}{#4}{#5}}}% - \else - \writestatus\m!fields{pass fieldname and fieldtype}% - \fi} - -\def\definelinefield#1#2#3#4#5% - {\setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{#4}} - -\let\definetextfield=\definelinefield - -\def\definechoicefield#1#2#3#4#5% - {\doifelsenothing{#4} - {\def\@@DriverFieldValues{yes,no}} - {\def\@@DriverFieldValues{#4}}% - \doifelsenothing{#5} - {\dogetcommacommandelement2\from\@@DriverFieldValues \to\@@DriverFieldDefault - \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} - {\def\@@DriverFieldDefault{#5}}% - \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} - -\let\definepopupfield=\definechoicefield -\let\definecombofield=\definechoicefield - -%\def\definecheckfield#1#2#3#4#5% -% {\doifelsenothing{#4} -% {\definedefaultsymbols -% \def\@@DriverFieldValues{defaultyes}} -% {\def\@@DriverFieldValues{#4}}% -% \doifelsenothing{#5} -% {\dogetcommacommandelement2\from\@@DriverFieldValues\to\@@DriverFieldDefault -% \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} -% {\def\@@DriverFieldDefault{#5}}% -% \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} - -%D Since these fields have an on/off state only, we pass 1/0 -%D to the driver as default values. - -\def\definecheckfield#1#2#3#4#5% - {\doifelsenothing{#4} - {\definedefaultsymbols - \def\@@DriverFieldValues{defaultyes}} - {\def\@@DriverFieldValues{#4}}% - \doifelsenothing{#5} - {\def\@@DriverFieldDefault{2}} - {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldDefault - \doifinstringelse{#5}{\@@DriverFieldDefault} - {\def\@@DriverFieldDefault{1}} - {\def\@@DriverFieldDefault{0}}}% - \setfield - {#1}{#2}{}{}{\@@DriverFieldKids}{#3}% - {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}% - {\@@DriverFieldValues}{\@@DriverFieldDefault}} - -\let\definepushfield=\definecheckfield - -\def\defineradiofield#1#2#3#4#5% - {\iffourthargument - \doifelsenothing{#5} - {\dogetcommacommandelement1\from#4\to\SavedFieldDefault - \dogetcommacommandelement1\from\SavedFieldDefault\to\SavedFieldDefault} - {\def\SavedFieldDefault{#5}}% -% when opt works -% \@EA\beforesplitstring\SavedFieldDefault\at=>\to\SavedFieldDefault - \ifx\@@DriverFieldKids\empty - \setfield{#1}{#2}{}{}{#4}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% - \else - \setfield{#1}{#2}{}{}{#4,\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% - \fi -% - \def\docommand##1% - {\doifelse{##1}\SavedFieldDefault - {\def\@@DriverFieldDefault{##1}}% - {\let\@@DriverFieldDefault\empty}% - \setfield{##1}{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% -% when opt works -% \def\docommand##1% -% {\@EA\beforesplitstring##1\at=>\to\FieldValue -% \doifelse\FieldValue\SavedFieldDefault -% {\let\@@DriverFieldDefault\FieldValue}% -% {\let\@@DriverFieldDefault\empty}% -% \setfield\FieldValue{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% - \processcommalist[#4]\docommand - \else - \writestatus\m!fields{pass values too}% - \fi} - -\def\definesubfield - {\dotripleempty\dodefinesubfield} - -\def\dodefinesubfield[#1][#2][#3]% for the moment only radio ones - {\ifsecondargument - \def\docommand##1% - {\getfield{##1}% - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field ##1}% to do - \else - \doifsomething{#2} - {\edef\@@DriverFieldGroup{#2}}% - \doifelsenothing{#3} - {\definedefaultsymbols - \def\@@DriverFieldValues{defaultyes}} - {\def\@@DriverFieldValues{#3}}% - \changefield{##1}% - \fi}% - \processcommalist[#1]\docommand - \else - \writestatus\m!fields{pass fieldname, setupgroup, values and default}% - \fi} - -\def\doclonefield[#1][#2][#3][#4]% parent children setupgroup values - {\ifsecondargument - \getfield{#1}% -\iftrialtypesetting\else - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field #1}% - \else - \let\@@DriverFieldMode\fieldparentmode - %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% - \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% - \processcommalist[#2]\docommand - \changefield{#1}% - \let\@@DriverFieldAutoParent\@@DriverFieldAuto - \def\@@DriverFieldParent{#1}% - \let\@@DriverFieldKids\empty - \let\@@DriverFieldRoot\empty - \let\@@DriverFieldMode\fieldchildmode - \def\@@DriverFieldFree{0}% - \def\@@DriverFieldAuto{0}% - \doifsomething{#3}{\edef\@@DriverFieldGroup{#3}}% - \doifsomething{#4}{\edef\@@DriverFieldValues{#4}}% - \def\docommand##1% - {\ifcase\@@DriverFieldAutoParent\else - \setmainfieldkid{\@@DriverFieldParent}{##1}% - \fi - \changefield{##1}}% - \processcommalist[#2]\docommand - \fi -\fi - \else - \writestatus\m!fields{pass parent field and clones}% - \fi} - -\def\clonefield - {\doquadrupleempty\doclonefield} - -\def\docopyfield[#1][#2]% parent children - {\ifsecondargument - \getfield{#1}% -\iftrialtypesetting\else - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field #1}% - \else - \let\@@DriverFieldMode\fieldparentmode - %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% - \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% - \processcommalist[#2]\docommand - \changefield{#1}% - \let\@@DriverFieldAutoParent\@@DriverFieldAuto - \def\@@DriverFieldParent{#1}% - \let\@@DriverFieldKids\empty - \let\@@DriverFieldRoot\empty - \let\@@DriverFieldMode\fieldcopymode - \def\@@DriverFieldFree{0}% - \def\@@DriverFieldAuto{0}% - \def\docommand##1% - {\ifcase\@@DriverFieldAutoParent\else - \setmainfieldkid{\@@DriverFieldParent}{##1}% - \fi - \changefield{##1}}% - \processcommalist[#2]\docommand - \fi -\fi - \else - \writestatus\m!fields{pass parent field and copies}% - \fi} - -\def\copyfield{\dodoubleempty\docopyfield} - -\unexpanded\def\field {\dotripleempty\dofield[\dohandlefield]} -\unexpanded\def\fitfield{\dotripleempty\dofield[\dohandlefitfield]} - -\def\dofield[#1][#2][#3]% - {\iffirstargument - \bgroup - \getfield{#2}% - \ifsecondargument - \def\@@DriverFieldLabel{#3}% - \else - \let\@@DriverFieldLabel\@@DriverFieldName - \fi - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field #2}% - \else\ifcase\@@DriverFieldFree\relax - \doifdefinedelse{\strippedcsname\setupfield\@@DriverFieldGroup} - {\let\dosetupfield=#1\getvalue{\strippedcsname\setupfield\@@DriverFieldGroup}} - {#1[\@@DriverFieldName][\v!label,\v!frame,\v!horizontal][][][]}% -\iftrialtypesetting\else - \def\@@DriverFieldFree{1}% - \changefield{#2}% -\fi - \else\ifcase\@@DriverFieldAuto\relax - % \writestatus\m!fields{field #2 already typeset}% - \else - % \writestatus\m!fields{field #2 automatically copied}% - \nextsystemfield - \copyfield[\@@DriverFieldName][\currentsystemfield]% - \dotripleempty\dofield[#1][\currentsystemfield][#3]% get the if's right - \fi\fi\fi - \egroup - \fi} - -\def\typesetfield - {\useJSscripts[fld]% - \ifx\@@DriverFieldRoot\empty \else - \let\@@SavedFieldName\@@DriverFieldName - \getfield\@@DriverFieldRoot - \ifcase\@@DriverFieldFree\relax - \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot - \dopresetrecord -\iftrialtypesetting\else - \def\@@DriverFieldFree{1}% - \changefield\@@DriverFieldName -\fi - \fi - \getfield\@@SavedFieldName - \fi - \ifx\@@DriverFieldKids\empty - \donefalse - \else - \donetrue - \fi - \ifdone - \let\@@DriverFieldParent\@@DriverFieldName - %\addtocommalist\@@DriverFieldParent\@@DriverFieldKids - \appendtocommalist\@@DriverFieldParent\@@DriverFieldKids - \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot - \dopresetfield - \let\@@DriverFieldMode\fieldchildmode - \fi - \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot - \dopresetfield} - -\def\dopresetfield - {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType field}\fi\fi} - -\def\dopresetrecord - {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType record}\fi\fi} - -\def\dodefinethefieldset[#1][#2]% - {\dodefinefieldset{#1}{#2}} - -\def\definefieldset% - {\dodoubleargument\dodefinethefieldset} - -\def\normaldodosetupfield[#1][#2][#3][#4][#5]% - {\doifdefinedelse{\strippedcsname\setupfield#1} - {\pushmacro\dosetupfield - \def\dosetupfield[##1][##2][##3][##4][##5]% - {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][##2,#2][##3,#3][##4,#4][##5,#5]}}% - \getvalue{\strippedcsname\setupfield#1}% - \popmacro\dosetupfield} - {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}}} - -\let\dodosetupfield\normaldodosetupfield - -\def\donosetupfield[#1][#2][#3][#4][#5]% - {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}} - -\def\dosetupfield[#1][#2][#3][#4][#5]% - {\iffifthargument - \def\docommand##1{\dodosetupfield[##1][#2][#3][#4][#5]}% - \processcommalist[#1]\docommand - \else\ifthirdargument - \def\docommand##1{\dodosetupfield[##1][#2][][][#3]}% - \processcommalist[#1]\docommand - \else\ifsecondargument - \doifelse{#2}\v!reset - {\def\docommand##1{\donosetupfield[#1][][][][]}} - {\def\docommand##1{\dodosetupfield[##1][][][][#2]}}% - \processcommalist[#1]\docommand - \else\iffirstargument - \def\docommand##1{\dodosetupfield[##1][][][][]}% - \processcommalist[#1]\docommand - \else - \writestatus\m!fields{provide either 1, 2, 3 or 5 arguments}% - \fi\fi\fi\fi} - -\def\setupfield - {\doquintupleempty\dosetupfield} - -\def\dosetupfields[#1][#2][#3][#4]% - {\ifsecondargument - \def\dodosetupfield[##1][##2][##3][##4][##5]% - {\doifdefinedelse{\strippedcsname\setupfield##1} - {\def\dosetupfield[####1][####2][####3][####4][####5]% - {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,####2,##2][#2,####3,##3][#3,####4,##4][#4,####5,##5]}}% - \getvalue{\strippedcsname\setupfield##1}} - {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,##2][#2,##3][#3,##4][#4,##5]}}}% - \else\iffirstargument - \doifelse{#1}\v!reset - {\resetfields} - {\setupfields[][][][#1]}% checken - \else - \writestatus\m!fields{provide either 1 or 4 arguments}% - \fi\fi} - -\def\setupfields - {\doquadrupleempty\dosetupfields} - -\def\resetfields - {\let\dodosetupfield\normaldodosetupfield} - -% \setupfields[\v!reset] - -% opties: veld, label, kader, vertikaal/horizontaal - -\newif\ifShowFieldLabel -\newif\ifShowFieldFrame -\newif\ifVerticalField -\newif\ifHorizontalField - -% way to slow/complicated, we need some simple alternative -% as well - -\def\dohandlefield[#1][#2][#3][#4][#5]% - {\presetlocalframed[\??fd]% - \processallactionsinset - [#2] - [ \v!reset=>\ShowFieldLabelfalse\ShowFieldFramefalse - \HorizontalFieldfalse\VerticalFieldfalse, - \v!label=>\ShowFieldLabeltrue, - \v!frame=>\ShowFieldFrametrue, - \v!horizontal=>\HorizontalFieldtrue, - \v!vertical=>\VerticalFieldtrue]% - \ifVerticalField - \getparameters[\??fd] - [\c!distance=\!!zeropoint,\c!inbetween=\vskip\@@localoffset, - \c!align=\v!right,\c!width=20em]% - \else\ifHorizontalField - \getparameters[\??fd] - [\c!distance=\@@localoffset,\c!inbetween=,\c!align=\c!left, - \c!height=10ex]% - \else - \getparameters[\??fd] - [\c!distance=\!!zeropoint,\c!inbetween=,\c!align=\c!left]% - \fi\fi - \getparameters[\??fd] - [\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=,#3]% - \reshapeframeboxfalse % else ugly spacing - \ifShowFieldFrame - \localframed[\??fd][\c!strut=\v!no,\c!align=]\bgroup - \else - \vbox\bgroup - \fi - \dontcomplain - \ifShowFieldLabel - \setbox0\hbox - {\reshapeframeboxtrue % else wrong dimensions - \framed - [\c!style=,\c!color=,\c!align=\c!right,#4] - {\@@DriverFieldLabel}}% - \fi - \setbox2\hbox - {\reshapeframeboxtrue % else wrong dimensions - \ifVerticalField - \setupframed[\c!height=6ex,\c!width=\hsize]% - \else\ifHorizontalField - \setupframed[\c!height=\vsize,\c!width=20em]% - \else - \setupframed[\c!height=2cm,\c!width=2cm]% - \fi\fi - \framed - [\c!align=\v!right,\c!strut=\v!no,#5] - {\getparameters - [\??fd] - [\c!color=,\c!style=,\c!align=\v!right,\c!option=, - \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, - \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, - \c!focusin=,\c!focusout=, - \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, - \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5]% - \scratchdimen\framedwidth \edef\@@DriverFieldWidth {\the\scratchdimen}% - \scratchdimen\framedheight\edef\@@DriverFieldHeight{\the\scratchdimen}% - \vfill - \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}} - \vss}}% - \ifShowFieldLabel - \ifVerticalField - \vbox - {\copy0 - \@@fdinbetween - \copy2}% - \else - \hbox - {\vbox \ifdim\ht2>\ht0 to \ht2 \fi - {\@@fdbefore - \copy0 - \@@fdafter}% - \hskip\@@fddistance - \vbox \ifdim\ht0>\ht2 to \ht0 \fi - {\@@fdbefore - \box2 - \@@fdafter}}% - \fi - \else - \box2 - \fi - \egroup} - -\chardef\fitfieldmode\plusone % 3 = best - -\def\dohandlefitfield[#1][#2][#3][#4][#5]% alleen check - {\presetlocalframed[\??fd]% - \localframed - [\??fd] - [\c!n=1024, % beware: weblink plug in truncates - \c!strut=\v!no,\c!color=,\c!style=,\c!option=, - \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, - \c!focusin=,\c!focusout=, - \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, - \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, - \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5,\c!align=] - {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldValue - \ifx\@@DriverFieldValue\empty - \let\@@DriverFieldValue\@@DriverFieldDefault - \fi - \dopresetfieldsymbol\@@DriverFieldValue - \setbox\scratchbox\hbox{\dogetfieldsymbol\@@DriverFieldValue}% - \scratchdimen\wd\scratchbox \edef\@@DriverFieldWidth {\the\scratchdimen}% - \scratchdimen\ht\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% - \ifcase\fitfieldmode - \typesetfield - \or % 1 = ignore depth (original, assumed no depth, actually a bug) - \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% - \or % 2 = add depth to height, but no depth in result - \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% - \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% - \or % 3 = add depth to height, and apply depth to result - \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% - \hbox to \wd\scratchbox{\lower\dp\scratchbox\hbox{\typesetfield}\hfill}% - \fi}} - -%D Common stuff - -\newcounter\nofsystemfields - -\def\nextsystemfield - {\doglobal\increment\nofsystemfields - \def\currentsystemfield{sys::\nofsystemfields}} - -%D An example: - -\def\fillinfield - {\dosingleempty\dofillinfield} - -\def\dofillinfield[#1]#2% - {\dontleavehmode - \hbox - {\forgetall - \setupfields[\v!reset]% - \nextsystemfield - \useJSscripts[ans]% - \doifelsenothing{#1} - {\def\therightanswer{#2}} - {\def\therightanswer{#1}}% - \setbox0\hbox{#2}% - \setbox2\hbox{\therightanswer}% - \dimen0=\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi - \advance\dimen0 .2em - \definefield - [\currentsystemfield][line][systemfield]% - \setupfield - [systemfield] - [\c!n=1024, % beware: weblink plugin truncates - \c!location=\v!low,\c!strut=\v!yes,\c!fieldoffset=0pt, - \c!height=1.2\openlineheight,\c!width=\dimen0,\c!offset=\v!overlay, - \c!style=,\c!align=\v!middle,\c!frame=\v!off, - \c!color=red,\c!fieldbackgroundcolor=\s!white,\c!fieldframecolor=blue, - \c!validate=JS(Check_Answer{\currentsystemfield,\therightanswer})]% - \switchtobodyfont - [\c!small]% - \hbox to \wd0 - {\copy0\hskip-\wd0\hss\field[\currentsystemfield]\hss}}} - -%D and another one: - -\def\tooltip - {\dosingleempty\dotooltip} - -\def\dotooltip[#1]#2#3% - {\bgroup - \setupfields[\v!reset]% - \useJSscripts[fld]% - \setbox0\hbox - {\dontcomplain - \nextsystemfield - \setbox0\hbox{#2}% - \definesymbol - [\currentsystemfield:txt] - [{\inframed[\c!frame=\v!off,\c!background=\v!screen]{#3}}]% - \setbox2\hbox{\symbol[\currentsystemfield:txt]}% - \definefield - [\currentsystemfield:txt][check] - [dummy][\currentsystemfield:txt][\currentsystemfield:txt]% - \setupfield - [dummy] - [\c!frame=\v!off, - \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), - \c!option=\v!hidden]% - \hbox to \zeropoint - {\dimen0\wd2\advance\dimen0 -\wd0 - \doifelse{#1}\v!left - {\hskip-\dimen0} - {\doif{#1}\v!middle - {\hskip-.5\dimen0}}% - \lower\openlineheight\hbox to \zeropoint - {\fitfield[\currentsystemfield:txt]}}% - \dimen0=\ifdim\wd0=\zeropoint 3em\else\wd0\fi - \definesymbol - [\currentsystemfield:but] - [{\framed[\c!height=2ex,\c!width=\dimen0,\c!frame=\v!off]{}}]% - \definefield - [\currentsystemfield:but][push] - [dummy][\currentsystemfield:but][\currentsystemfield:but]% - \setupfield - [dummy] - [\c!frame=\v!off, - \c!option=, - \c!regionin=JS(Vide_Field{\currentsystemfield:txt}), - \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), - \c!fieldlayer=\@@iafieldlayer]% - \lower2ex\hbox to \zeropoint - {\fitfield[\currentsystemfield:but]}% - #2}% - \ht0\strutht\dp0\strutdp\box0 - \egroup} - -%D And one more: - -\def\definefieldstack - {\dotripleargument\dodefinefieldstack} - -\def\dodefinefieldstack[#1][#2][#3]% name, symbols, settings - {\doifundefined{fieldstack:#1} - {\setgvalue{fieldstack:#1}{\dodofieldstack[#1][#2][#3]}}} - -\def\dodofieldstack[#1][#2][#3]% start=n, 0 == leeg - {\bgroup - \getparameters[\??fd][\c!start=1,#3]% - \setupfields[\v!reset]% - \definesymbol[\v!empty][]% - \useJSscripts[fld][FieldStack]% - \newcounter\stackedfieldnumber - \def\dododofieldstack##1% - {\increment\stackedfieldnumber - \ifnum\stackedfieldnumber=\@@fdstart\relax - \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][##1]% - \else - \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][\v!empty]% - \fi}% - \processcommalist[#2]\dododofieldstack - \setupfield[#1][\v!reset]% added - \setupfield[#1][\c!option=\v!readonly,#3]% #3 swapped - \newcounter\stackedfieldnumber - \def\dododofieldstack##1% - {\doglobal\increment\stackedfieldnumber - \fitfield[#1:\stackedfieldnumber]\egroup\bgroup}% - \startoverlay - \bgroup - \globalprocesscommalist[#2]\dododofieldstack - \egroup - \stopoverlay - \egroup} - -\def\dofieldstack[#1][#2][#3]% - {\ifsecondargument - \dodefinefieldstack[#1][#2][#3]\fieldstack[#1]% - \else - \getvalue{fieldstack:#1}\setgvalue{fieldstack:#1}{[#1]}% - \fi} - -\def\fieldstack - {\dotripleempty\dofieldstack} - -%D When submitting a form, we need to tell the driver module -%D that we want \FDF\ or \HTML. - -\def\setupforms - {\dodoubleargument\getparameters[\??fr]} - -\def\checksubmitform#1% - {\setsubmitoutputformat\@@frmethod} - -\setexecutecommandcheck {submitform} \checksubmitform - -\setupforms - [\c!method=HTML] - -\protect \endinput diff --git a/tex/context/base/core-fld.mkiv b/tex/context/base/core-fld.mkiv deleted file mode 100644 index 96ecf6b54..000000000 --- a/tex/context/base/core-fld.mkiv +++ /dev/null @@ -1,1079 +0,0 @@ -%D \module -%D [ file=core-fld, -%D version=1997.05.18, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Fields, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% \appendtocommalist versus \addtocommalist -% -% * as default trigger in radiofields ? -% -% beware: weblink plugin truncates on length, while save as doesn't; -% more precise: (1) first time right string is sent, (2) -% internal string truncated, (3) second time truncated -% string is sent. - -\writestatus{loading}{ConTeXt Core Macros / Fields} - -% messages - -\definemessageconstant{fields} - -\unprotect - -%D First we hook fields into the (viewer based) layering mechanism -%D (implemented as properties). - -\ifx\currentlayerproperty\undefined\else \let\currentlayerproperty\empty\fi - -\appendtoks - \doif\@@iafieldlayer\v!auto - {\def\@@iafieldlayer{\currentlayerproperty}}% -\to \everysetupinteraction - -\setupinteraction - [\c!fieldlayer=\v!auto] % auto by default - -%D Internal command, linked to \type{\definesymbol}. - -\def\dogetfieldsymbol#1% - {\getobject{SYM}{#1}} - -\def\dopresetfieldsymbol#1% - {\doifobjectfoundelse{SYM}{#1} - {} - {\settightobject{SYM}{#1}\hbox{\symbol[#1]}% - \flushatshipout - {\setbox0\hbox{\hskip-\maxdimen\getobject{SYM}{#1}}% - \smashbox0\box0}}} - -\def\presetfieldsymbols[#1]% slow - {\def\dopresetfieldsymbols##1% - {\processcommalist[##1]\dopresetfieldsymbol}% - \@EA\processcommalist\@EA[#1]\dopresetfieldsymbols} - -\def\definedefaultsymbols - {\definesymbol[defaultyes][$\times$]% - \definesymbol[defaultno][$\cdot$]} - -\def\resetfieldsymbol[#1]% for experimental usage only - {\resetobject{SYM}{#1}} - -%D The interface to the specials. DEFAULT NOG ANDERS - -\def\preparefieldvariables % evt \def's at the outer level (test) or \edef's here for fast testing - {\let\@@DriverFieldNumber \@@fdn - \let\@@DriverFieldStyle \@@fdstyle - \let\@@DriverFieldColor \@@fdcolor - \let\@@DriverFieldBackgroundColor\@@fdfieldbackgroundcolor - \let\@@DriverFieldFrameColor \@@fdfieldframecolor - \let\@@DriverFieldLayer \@@fdfieldlayer - \let\@@DriverFieldOption \@@fdoption - \let\@@DriverFieldAlign \@@fdalign - \let\@@DriverFieldClickIn \@@fdclickin - \let\@@DriverFieldClickOut \@@fdclickout - \let\@@DriverFieldRegionIn \@@fdregionin - \let\@@DriverFieldRegionOut \@@fdregionout - \let\@@DriverFieldAfterKey \@@fdafterkey - \let\@@DriverFieldFormat \@@fdformat - \let\@@DriverFieldValidate \@@fdvalidate - \let\@@DriverFieldCalculate \@@fdcalculate - \let\@@DriverFieldFocusIn \@@fdfocusin - \let\@@DriverFieldFocusOut \@@fdfocusout} - -% todo : remove arguments, consider DriverField a namespace - -\def\presetlinefield - {\preparefieldvariables - \dopresetlinefield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldNumber} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldAlign} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presettextfield - {\preparefieldvariables - \dopresettextfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldNumber} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldAlign} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetchoicefield - {\preparefieldvariables - \dopresetchoicefield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetpopupfield - {\preparefieldvariables - \dopresetpopupfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetcombofield - {\preparefieldvariables - \dopresetcombofield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetcheckfield - {\preparefieldvariables - \presetfieldsymbols[\@@DriverFieldValues]% - \dopresetcheckfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetpushfield - {\preparefieldvariables - %\edef\@@DriverFieldValues{{\@@DriverFieldValues}}% makes sure {a,b,c} is passed - \presetfieldsymbols[\@@DriverFieldValues]% - \dopresetpushfield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetradiofield - {\preparefieldvariables - \presetfieldsymbols[\@@DriverFieldValues]% - \dopresetradiofield - {\@@DriverFieldName} - {\@@DriverFieldWidth} - {\@@DriverFieldHeight} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldRoot} - {\@@DriverFieldValues} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\presetradiorecord - {\preparefieldvariables - \dopresetradiorecord - {\@@DriverFieldName} - {\@@DriverFieldDefault} - {\@@DriverFieldOption} - {\@@DriverFieldKids} - {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% - \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% - \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} - -\def\setfieldmodes#1#2#3% - {\xdef\@@DriverFieldMode{#1}% % 0 1 2 3 - \xdef\@@DriverFieldFree{#2}% % 0 1 - \xdef\@@DriverFieldAuto{#3}} % 0 1 - -\newevery\everysetfield\relax - -\def\doiffieldelse#1{\doifdefinedelse{fielddata#1}} - -\def\setfield#1#2#3#4#5#6#7#8#9% - {\bgroup - \doglobal\increment\numberoffields - \iftracefields - \doglobal\addtocommalist{#1}\collectedfields - \fi - \the\everysetfield - \setxvalue{fielddata#1}% kortere tag #7 needs expansion etc - {\noexpand\dosetfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}% - \egroup} - -\def\dosetfield#1#2#3#4#5#6#7#8#9% - {\xdef\@@DriverFieldName {#1}% - \xdef\@@DriverFieldType {#2}% - \xdef\@@DriverFieldRoot {#3}% - \xdef\@@DriverFieldParent {#4}% - \xdef\@@DriverFieldKids {#5}% - \xdef\@@DriverFieldGroup {#6}% - \setfieldmodes #7% - \bgroup - \def\par{\string\n\string\n}% - \xdef\@@DriverFieldValues {#8}% - \xdef\@@DriverFieldDefault{#9}% - \egroup} - -\def\changefield#1% - {\setfield{#1}\@@DriverFieldType\@@DriverFieldRoot\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldGroup - {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}\@@DriverFieldValues\@@DriverFieldDefault} - -\def\getfield#1% name - {\doifundefinedelse{fielddata#1} - {\dosetfield{#1}\empty\empty\empty\empty\empty{\empty00}\empty\empty} - {\getvalue{fielddata#1}}} - -\newif\iftracefields \tracefieldsfalse - -\let\tracefields\tracefieldstrue - -\def\doshowfields[#1]% todo: tabulate van maken en runtime - {\bgroup - \switchtobodyfont[8pt,tt]% - \doifsomething{#1}{\def\collectedfields{#1}}% - \ifx\collectedfields\empty - \par specify [fieldlist] or say \type{\tracefieldstrue} first\par - \else - \def\normalizedfieldmode##1##2##3% - {\ifcase0##2 \else\sl\fi - \ifcase0##1 loner\or parent\or clone\or copy\fi}% - \def\dosetfield##1##2##3##4##5##6##7##8##9% - {##1&##2&##3&##4&##5&##6&\normalizedfieldmode##7&##8&##9\cr}% - \halign - {&##\strut\hss\quad\cr - \noalign{\hrule}% - NAME &TYPE &ROOT & - PARENT&KIDS &GROUP & - MODE &VALUES&DEFAULT\cr - \noalign{\hrule}% - \@EA\globalprocesscommalist\@EA[\collectedfields]\getfield - \noalign{\hrule}}% - \fi - \egroup} - -\def\showfields - {\dosingleempty\doshowfields} - -\def\dologfields[#1]% - {\bgroup - \immediate\openout\scratchwrite=fields.log - \doifsomething{#1}{\def\collectedfields{#1}}% - \ifx\colledtedfields\empty - \immediate\write\scratchwrite{use \tracefieldstrue}% - \else - \def\normalizedfieldmode##1##2##3% - {\edef\@@DriverFieldMode - {\ifcase##1 loner \or parent \or clone \or copy \fi - \ifcase##2 \else(done)\fi}}% - \def\dosetfield##1##2##3##4##5##6##7##8##9% - {\normalizedfieldmode##7% - \immediate\write\scratchwrite - {N=##1 / T=##2 / R=##3 / P=##4 / K=##5 / G=##6 / - M=\@@DriverFieldMode\space/ V=##8 / D=##9}}% - \processcommacommand[\collectedfields]\getfield - \fi - \immediate\closeout\scratchwrite - \egroup} - -\def\logfields - {\dosingleempty\doLogFields} - -%D \starttyping -%D \definefield [name] [type] [group] [values] [default] -%D -%D \definefield [WWWW] [text] [textsetup] [default text] -%D \definefield [XXXX] [push] [pushsetup] [yes,no] [yes] -%D \definefield [XXXX] [check] [checksetup] [yes,no] [yes] -%D \definefield [YYYY] [combo] [combosetup] [a,b,c,d] [b] -%D \definefield [ZZZZ] [radio] [radiosetup] [W,X,Y,Z] [Y] -%D -%D \definesubfield [W] [subsetup] [p,q] -%D \definesubfield [X,Y] [subsetup] [p,r] -%D \definesubfield [Z] [subsetup] [y,z] -%D -%D evt \definemainfield ... wanneer geplaatst voor subs gegeven -%D -%D \clonefield [XXXX] [XX,YY] [mysetup] [on,off] -%D \clonefield [Z] [AA,BB] [somesetup] [true,false] -%D \clonefield [Z] [CC,DD] [anothersetup] -%D -%D \copyfield [XXXX] [PP,QQ,RR] -%D -%D \field[XXXX] -%D \fitfield[XXXX] -%D \stoptyping - -\newif\ifdefinemainfield \definemainfieldfalse - -%D We need to keep track of cloned (related) fields and so by -%D maintaining lists of field clones. -%D -%D The first alternative used a two pass data list and was -%D implemented as follows: -%D -%D \starttyping -%D \def\getmainfieldkids#1% -%D {\let\@@DriverFieldKids\empty -%D \ifdefinemainfield -%D \definetwopasslist{fld:#1}% defined by system -%D \doloop -%D {\gettwopassdata{fld:#1}% -%D \iftwopassdatafound -%D %\addtocommalist\twopassdata\@@DriverFieldKids -%D \appendtocommalist\twopassdata\@@DriverFieldKids -%D \else -%D \exitloop -%D \fi}% -%D \fi} -%D \stoptyping -%D -%D However, the next alternative is much faster when we have -%D a field with thousands of clones, something not that -%D imaginary. -%D -%D \starttyping -%D \def\getmainfieldkids#1% -%D {\let\@@DriverFieldKids\empty -%D \ifdefinemainfield -%D \definetwopasslist{fld:#1}% runtime defined by system -%D \getnamedtwopassdatalist{fld:#1}\@@DriverFieldKids -%D \fi} -%D \stoptyping -%D -%D The data is written by file using: -%D -%D \starttyping -%D \newcounter\nofmainfieldkids -%D -%D \def\setmainfieldkid#1#2% -%D {\doglobal\increment\nofmainfieldkids -%D \savetwopassdata{fld:#1}{\nofmainfieldkids}{#2}} -%D \stoptyping -%D -%D The trade of of this mechanism is that for each cloned or -%D copied field, the uitlity file is to be read in order to -%D fetch the data. -%D -%D The next, much faster alternative uses a dedicated % -%D reference mechanism. - -\def\setmainfieldkid#1#2% - {\immediatewriteutilitycommand{\fieldreference{#1}{#2}}} - -\def\checkfieldreferences - {\startnointerference - \protectlabels - \doutilities{fieldreferences}\jobname\empty\relax\relax - \global\let\checkfieldreferences\relax - \stopnointerference} - -\def\setfieldreferences - {\def\fieldreference##1##2% - {\ifundefined{\r!widget##1}% - \setxvalue{\r!widget##1}{##2}% - \else - \edef\!!stringa{\getvalue{\r!widget##1}}% - \setxvalue{\r!widget##1}{\!!stringa,##2}% - \fi}} - -\def\resetfieldreferences - {\let\fieldreference\gobbletwoarguments} - -\def\getmainfieldkids#1% - {\checkfieldreferences - \ifdefinemainfield - \doifundefinedelse{\r!widget#1}% - {\let\@@DriverFieldKids\empty} - {\@EA\let\@EA\@@DriverFieldKids\csname\r!widget#1\endcsname}% - \else - \let\@@DriverFieldKids\empty - \fi} - -\resetfieldreferences - -%D Of course it costs a few more tokens to implement, but it's -%D worth the memory: running for instance the 2000 page -%D english examns publishing on demand document went down from -%D 1350 seconds to less than 950 on a 650 Mhz pentium. - -\def\definefield - {\definemainfieldfalse\doquintupleempty\dodefinefield} - -\def\definemainfield - {\definemainfieldtrue \doquintupleempty\dodefinefield} - -\let\collectedfields\empty -\newcounter\numberoffields -\newcounter\totalnumberoffields - -\def\savenumberoffields - {\ifcase\numberoffields\relax\else - \savecurrentvalue\totalnumberoffields\numberoffields - \fi} - -\appendtoks \savenumberoffields \to \everybye % \everylastshipout - -% \def\presetfieldreferences -% {\ifnum\totalnumberoffields>0 -% \definereference[AtOpenInitializeForm][\v!ResetForm]% -% \fi} -% -% \definereference[AtOpenInitializeForm][\v!geen] -% -% \appendtoks \presetfieldreferences \to \everycheckreferences - -\def\dodefinefield[#1][#2][#3][#4][#5]% - {\ifsecondargument - \edef\currentfieldname{#1}% just in case we're inside a loop - \doifundefinedelse{define#2field} - {\writestatus\m!fields{unknown field type #2}} - {\doifundefined{fielddata\currentfieldname} - {\getmainfieldkids\currentfieldname - \ifdefinemainfield - \ifx\@@DriverFieldKids\empty - \let\@@DriverFieldMode\fieldlonermode - \else - \let\@@DriverFieldMode\fieldparentmode - \fi - \def\@@DriverFieldAuto{1}% - \else - \let\@@DriverFieldMode\fieldlonermode - \def\@@DriverFieldAuto{0}% - \fi - \def\@@DriverFieldFree{0}% - \getvalue{define#2field}{\currentfieldname}{#2}{#3}{#4}{#5}}}% - \else - \writestatus\m!fields{pass fieldname and fieldtype}% - \fi} - -\def\definelinefield#1#2#3#4#5% - {\setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{#4}} - -\let\definetextfield=\definelinefield - -\def\definechoicefield#1#2#3#4#5% - {\doifelsenothing{#4} - {\def\@@DriverFieldValues{yes,no}} - {\def\@@DriverFieldValues{#4}}% - \doifelsenothing{#5} - {\dogetcommacommandelement2\from\@@DriverFieldValues \to\@@DriverFieldDefault - \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} - {\def\@@DriverFieldDefault{#5}}% - \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} - -\let\definepopupfield=\definechoicefield -\let\definecombofield=\definechoicefield - -%\def\definecheckfield#1#2#3#4#5% -% {\doifelsenothing{#4} -% {\definedefaultsymbols -% \def\@@DriverFieldValues{defaultyes}} -% {\def\@@DriverFieldValues{#4}}% -% \doifelsenothing{#5} -% {\dogetcommacommandelement2\from\@@DriverFieldValues\to\@@DriverFieldDefault -% \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} -% {\def\@@DriverFieldDefault{#5}}% -% \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} - -%D Since these fields have an on/off state only, we pass 1/0 -%D to the driver as default values. - -\def\definecheckfield#1#2#3#4#5% - {\doifelsenothing{#4} - {\definedefaultsymbols - \def\@@DriverFieldValues{defaultyes}} - {\def\@@DriverFieldValues{#4}}% - \doifelsenothing{#5} - {\def\@@DriverFieldDefault{2}} - {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldDefault - \doifinstringelse{#5}{\@@DriverFieldDefault} - {\def\@@DriverFieldDefault{1}} - {\def\@@DriverFieldDefault{0}}}% - \setfield - {#1}{#2}{}{}{\@@DriverFieldKids}{#3}% - {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}% - {\@@DriverFieldValues}{\@@DriverFieldDefault}} - -\let\definepushfield=\definecheckfield - -\def\defineradiofield#1#2#3#4#5% - {\iffourthargument - \doifelsenothing{#5} - {\dogetcommacommandelement1\from#4\to\SavedFieldDefault - \dogetcommacommandelement1\from\SavedFieldDefault\to\SavedFieldDefault} - {\def\SavedFieldDefault{#5}}% -% when opt works -% \@EA\beforesplitstring\SavedFieldDefault\at=>\to\SavedFieldDefault - \ifx\@@DriverFieldKids\empty - \setfield{#1}{#2}{}{}{#4}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% - \else - \setfield{#1}{#2}{}{}{#4,\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% - \fi -% - \def\docommand##1% - {\doifelse{##1}\SavedFieldDefault - {\def\@@DriverFieldDefault{##1}}% - {\let\@@DriverFieldDefault\empty}% - \setfield{##1}{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% -% when opt works -% \def\docommand##1% -% {\@EA\beforesplitstring##1\at=>\to\FieldValue -% \doifelse\FieldValue\SavedFieldDefault -% {\let\@@DriverFieldDefault\FieldValue}% -% {\let\@@DriverFieldDefault\empty}% -% \setfield\FieldValue{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% - \processcommalist[#4]\docommand - \else - \writestatus\m!fields{pass values too}% - \fi} - -\def\definesubfield - {\dotripleempty\dodefinesubfield} - -\def\dodefinesubfield[#1][#2][#3]% for the moment only radio ones - {\ifsecondargument - \def\docommand##1% - {\getfield{##1}% - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field ##1}% to do - \else - \doifsomething{#2} - {\edef\@@DriverFieldGroup{#2}}% - \doifelsenothing{#3} - {\definedefaultsymbols - \def\@@DriverFieldValues{defaultyes}} - {\def\@@DriverFieldValues{#3}}% - \changefield{##1}% - \fi}% - \processcommalist[#1]\docommand - \else - \writestatus\m!fields{pass fieldname, setupgroup, values and default}% - \fi} - -\def\doclonefield[#1][#2][#3][#4]% parent children setupgroup values - {\ifsecondargument - \getfield{#1}% -\iftrialtypesetting\else - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field #1}% - \else - \let\@@DriverFieldMode\fieldparentmode - %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% - \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% - \processcommalist[#2]\docommand - \changefield{#1}% - \let\@@DriverFieldAutoParent\@@DriverFieldAuto - \def\@@DriverFieldParent{#1}% - \let\@@DriverFieldKids\empty - \let\@@DriverFieldRoot\empty - \let\@@DriverFieldMode\fieldchildmode - \def\@@DriverFieldFree{0}% - \def\@@DriverFieldAuto{0}% - \doifsomething{#3}{\edef\@@DriverFieldGroup{#3}}% - \doifsomething{#4}{\edef\@@DriverFieldValues{#4}}% - \def\docommand##1% - {\ifcase\@@DriverFieldAutoParent\else - \setmainfieldkid{\@@DriverFieldParent}{##1}% - \fi - \changefield{##1}}% - \processcommalist[#2]\docommand - \fi -\fi - \else - \writestatus\m!fields{pass parent field and clones}% - \fi} - -\def\clonefield - {\doquadrupleempty\doclonefield} - -\def\docopyfield[#1][#2]% parent children - {\ifsecondargument - \getfield{#1}% -\iftrialtypesetting\else - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field #1}% - \else - \let\@@DriverFieldMode\fieldparentmode - %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% - \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% - \processcommalist[#2]\docommand - \changefield{#1}% - \let\@@DriverFieldAutoParent\@@DriverFieldAuto - \def\@@DriverFieldParent{#1}% - \let\@@DriverFieldKids\empty - \let\@@DriverFieldRoot\empty - \let\@@DriverFieldMode\fieldcopymode - \def\@@DriverFieldFree{0}% - \def\@@DriverFieldAuto{0}% - \def\docommand##1% - {\ifcase\@@DriverFieldAutoParent\else - \setmainfieldkid{\@@DriverFieldParent}{##1}% - \fi - \changefield{##1}}% - \processcommalist[#2]\docommand - \fi -\fi - \else - \writestatus\m!fields{pass parent field and copies}% - \fi} - -\def\copyfield{\dodoubleempty\docopyfield} - -\unexpanded\def\field {\dotripleempty\dofield[\dohandlefield]} -\unexpanded\def\fitfield{\dotripleempty\dofield[\dohandlefitfield]} - -\def\dofield[#1][#2][#3]% - {\iffirstargument - \bgroup - \getfield{#2}% - \ifsecondargument - \def\@@DriverFieldLabel{#3}% - \else - \let\@@DriverFieldLabel\@@DriverFieldName - \fi - \ifx\@@DriverFieldType\empty - \writestatus\m!fields{unknown field #2}% - \else\ifcase\@@DriverFieldFree\relax - \doifdefinedelse{\strippedcsname\setupfield\@@DriverFieldGroup} - {\let\dosetupfield=#1\getvalue{\strippedcsname\setupfield\@@DriverFieldGroup}} - {#1[\@@DriverFieldName][\v!label,\v!frame,\v!horizontal][][][]}% -\iftrialtypesetting\else - \def\@@DriverFieldFree{1}% - \changefield{#2}% -\fi - \else\ifcase\@@DriverFieldAuto\relax - % \writestatus\m!fields{field #2 already typeset}% - \else - % \writestatus\m!fields{field #2 automatically copied}% - \nextsystemfield - \copyfield[\@@DriverFieldName][\currentsystemfield]% - \dotripleempty\dofield[#1][\currentsystemfield][#3]% get the if's right - \fi\fi\fi - \egroup - \fi} - -\def\typesetfield - {\useJSscripts[fld]% - \ifx\@@DriverFieldRoot\empty \else - \let\@@SavedFieldName\@@DriverFieldName - \getfield\@@DriverFieldRoot - \ifcase\@@DriverFieldFree\relax - \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot - \dopresetrecord -\iftrialtypesetting\else - \def\@@DriverFieldFree{1}% - \changefield\@@DriverFieldName -\fi - \fi - \getfield\@@SavedFieldName - \fi - \ifx\@@DriverFieldKids\empty - \donefalse - \else - \donetrue - \fi - \ifdone - \let\@@DriverFieldParent\@@DriverFieldName - %\addtocommalist\@@DriverFieldParent\@@DriverFieldKids - \appendtocommalist\@@DriverFieldParent\@@DriverFieldKids - \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot - \dopresetfield - \let\@@DriverFieldMode\fieldchildmode - \fi - \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot - \dopresetfield} - -\def\dopresetfield - {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType field}\fi\fi} - -\def\dopresetrecord - {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType record}\fi\fi} - -\def\dodefinethefieldset[#1][#2]% - {\dodefinefieldset{#1}{#2}} - -\def\definefieldset% - {\dodoubleargument\dodefinethefieldset} - -\def\normaldodosetupfield[#1][#2][#3][#4][#5]% - {\doifdefinedelse{\strippedcsname\setupfield#1} - {\pushmacro\dosetupfield - \def\dosetupfield[##1][##2][##3][##4][##5]% - {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][##2,#2][##3,#3][##4,#4][##5,#5]}}% - \getvalue{\strippedcsname\setupfield#1}% - \popmacro\dosetupfield} - {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}}} - -\let\dodosetupfield\normaldodosetupfield - -\def\donosetupfield[#1][#2][#3][#4][#5]% - {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}} - -\def\dosetupfield[#1][#2][#3][#4][#5]% - {\iffifthargument - \def\docommand##1{\dodosetupfield[##1][#2][#3][#4][#5]}% - \processcommalist[#1]\docommand - \else\ifthirdargument - \def\docommand##1{\dodosetupfield[##1][#2][][][#3]}% - \processcommalist[#1]\docommand - \else\ifsecondargument - \doifelse{#2}\v!reset - {\def\docommand##1{\donosetupfield[#1][][][][]}} - {\def\docommand##1{\dodosetupfield[##1][][][][#2]}}% - \processcommalist[#1]\docommand - \else\iffirstargument - \def\docommand##1{\dodosetupfield[##1][][][][]}% - \processcommalist[#1]\docommand - \else - \writestatus\m!fields{provide either 1, 2, 3 or 5 arguments}% - \fi\fi\fi\fi} - -\def\setupfield - {\doquintupleempty\dosetupfield} - -\def\dosetupfields[#1][#2][#3][#4]% - {\ifsecondargument - \def\dodosetupfield[##1][##2][##3][##4][##5]% - {\doifdefinedelse{\strippedcsname\setupfield##1} - {\def\dosetupfield[####1][####2][####3][####4][####5]% - {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,####2,##2][#2,####3,##3][#3,####4,##4][#4,####5,##5]}}% - \getvalue{\strippedcsname\setupfield##1}} - {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,##2][#2,##3][#3,##4][#4,##5]}}}% - \else\iffirstargument - \doifelse{#1}\v!reset - {\resetfields} - {\setupfields[][][][#1]}% checken - \else - \writestatus\m!fields{provide either 1 or 4 arguments}% - \fi\fi} - -\def\setupfields - {\doquadrupleempty\dosetupfields} - -\def\resetfields - {\let\dodosetupfield\normaldodosetupfield} - -% \setupfields[\v!reset] - -% opties: veld, label, kader, vertikaal/horizontaal - -\newif\ifShowFieldLabel -\newif\ifShowFieldFrame -\newif\ifVerticalField -\newif\ifHorizontalField - -% way to slow/complicated, we need some simple alternative -% as well - -\def\dohandlefield[#1][#2][#3][#4][#5]% - {\presetlocalframed[\??fd]% - \processallactionsinset - [#2] - [ \v!reset=>\ShowFieldLabelfalse\ShowFieldFramefalse - \HorizontalFieldfalse\VerticalFieldfalse, - \v!label=>\ShowFieldLabeltrue, - \v!frame=>\ShowFieldFrametrue, - \v!horizontal=>\HorizontalFieldtrue, - \v!vertical=>\VerticalFieldtrue]% - \ifVerticalField - \getparameters[\??fd] - [\c!distance=\!!zeropoint,\c!inbetween=\vskip\@@localoffset, - \c!align=\v!right,\c!width=20em]% - \else\ifHorizontalField - \getparameters[\??fd] - [\c!distance=\@@localoffset,\c!inbetween=,\c!align=\c!left, - \c!height=10ex]% - \else - \getparameters[\??fd] - [\c!distance=\!!zeropoint,\c!inbetween=,\c!align=\c!left]% - \fi\fi - \getparameters[\??fd] - [\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=,#3]% - \reshapeframeboxfalse % else ugly spacing - \ifShowFieldFrame - \localframed[\??fd][\c!strut=\v!no,\c!align=]\bgroup - \else - \vbox\bgroup - \fi - \dontcomplain - \ifShowFieldLabel - \setbox0\hbox - {\reshapeframeboxtrue % else wrong dimensions - \framed - [\c!style=,\c!color=,\c!align=\c!right,#4] - {\@@DriverFieldLabel}}% - \fi - \setbox2\hbox - {\reshapeframeboxtrue % else wrong dimensions - \ifVerticalField - \setupframed[\c!height=6ex,\c!width=\hsize]% - \else\ifHorizontalField - \setupframed[\c!height=\vsize,\c!width=20em]% - \else - \setupframed[\c!height=2cm,\c!width=2cm]% - \fi\fi - \framed - [\c!align=\v!right,\c!strut=\v!no,#5] - {\getparameters - [\??fd] - [\c!color=,\c!style=,\c!align=\v!right,\c!option=, - \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, - \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, - \c!focusin=,\c!focusout=, - \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, - \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5]% - \scratchdimen\framedwidth \edef\@@DriverFieldWidth {\the\scratchdimen}% - \scratchdimen\framedheight\edef\@@DriverFieldHeight{\the\scratchdimen}% - \vfill - \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}} - \vss}}% - \ifShowFieldLabel - \ifVerticalField - \vbox - {\copy0 - \@@fdinbetween - \copy2}% - \else - \hbox - {\vbox \ifdim\ht2>\ht0 to \ht2 \fi - {\@@fdbefore - \copy0 - \@@fdafter}% - \hskip\@@fddistance - \vbox \ifdim\ht0>\ht2 to \ht0 \fi - {\@@fdbefore - \box2 - \@@fdafter}}% - \fi - \else - \box2 - \fi - \egroup} - -\chardef\fitfieldmode\plusone % 3 = best - -\def\dohandlefitfield[#1][#2][#3][#4][#5]% alleen check - {\presetlocalframed[\??fd]% - \localframed - [\??fd] - [\c!n=1024, % beware: weblink plug in truncates - \c!strut=\v!no,\c!color=,\c!style=,\c!option=, - \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, - \c!focusin=,\c!focusout=, - \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, - \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, - \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5,\c!align=] - {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldValue - \ifx\@@DriverFieldValue\empty - \let\@@DriverFieldValue\@@DriverFieldDefault - \fi - \dopresetfieldsymbol\@@DriverFieldValue - \setbox\scratchbox\hbox{\dogetfieldsymbol\@@DriverFieldValue}% - \scratchdimen\wd\scratchbox \edef\@@DriverFieldWidth {\the\scratchdimen}% - \scratchdimen\ht\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% - \ifcase\fitfieldmode - \typesetfield - \or % 1 = ignore depth (original, assumed no depth, actually a bug) - \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% - \or % 2 = add depth to height, but no depth in result - \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% - \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% - \or % 3 = add depth to height, and apply depth to result - \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% - \hbox to \wd\scratchbox{\lower\dp\scratchbox\hbox{\typesetfield}\hfill}% - \fi}} - -%D Common stuff - -\newcounter\nofsystemfields - -\def\nextsystemfield - {\doglobal\increment\nofsystemfields - \def\currentsystemfield{sys::\nofsystemfields}} - -%D An example: - -\def\fillinfield - {\dosingleempty\dofillinfield} - -\def\dofillinfield[#1]#2% - {\dontleavehmode - \hbox - {\forgetall - \setupfields[\v!reset]% - \nextsystemfield - \useJSscripts[ans]% - \doifelsenothing{#1} - {\def\therightanswer{#2}} - {\def\therightanswer{#1}}% - \setbox0\hbox{#2}% - \setbox2\hbox{\therightanswer}% - \dimen0=\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi - \advance\dimen0 .2em - \definefield - [\currentsystemfield][line][systemfield]% - \setupfield - [systemfield] - [\c!n=1024, % beware: weblink plugin truncates - \c!location=\v!low,\c!strut=\v!yes,\c!fieldoffset=0pt, - \c!height=1.2\openlineheight,\c!width=\dimen0,\c!offset=\v!overlay, - \c!style=,\c!align=\v!middle,\c!frame=\v!off, - \c!color=red,\c!fieldbackgroundcolor=\s!white,\c!fieldframecolor=blue, - \c!validate=JS(Check_Answer{\currentsystemfield,\therightanswer})]% - \switchtobodyfont - [\c!small]% - \hbox to \wd0 - {\copy0\hskip-\wd0\hss\field[\currentsystemfield]\hss}}} - -%D and another one: - -\def\tooltip - {\dosingleempty\dotooltip} - -\def\dotooltip[#1]#2#3% - {\bgroup - \setupfields[\v!reset]% - \useJSscripts[fld]% - \setbox0\hbox - {\dontcomplain - \nextsystemfield - \setbox0\hbox{#2}% - \definesymbol - [\currentsystemfield:txt] - [{\inframed[\c!frame=\v!off,\c!background=\v!screen]{#3}}]% - \setbox2\hbox{\symbol[\currentsystemfield:txt]}% - \definefield - [\currentsystemfield:txt][check] - [dummy][\currentsystemfield:txt][\currentsystemfield:txt]% - \setupfield - [dummy] - [\c!frame=\v!off, - \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), - \c!option=\v!hidden]% - \hbox to \zeropoint - {\dimen0\wd2\advance\dimen0 -\wd0 - \doifelse{#1}\v!left - {\hskip-\dimen0} - {\doif{#1}\v!middle - {\hskip-.5\dimen0}}% - \lower\openlineheight\hbox to \zeropoint - {\fitfield[\currentsystemfield:txt]}}% - \dimen0=\ifdim\wd0=\zeropoint 3em\else\wd0\fi - \definesymbol - [\currentsystemfield:but] - [{\framed[\c!height=2ex,\c!width=\dimen0,\c!frame=\v!off]{}}]% - \definefield - [\currentsystemfield:but][push] - [dummy][\currentsystemfield:but][\currentsystemfield:but]% - \setupfield - [dummy] - [\c!frame=\v!off, - \c!option=, - \c!regionin=JS(Vide_Field{\currentsystemfield:txt}), - \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), - \c!fieldlayer=\@@iafieldlayer]% - \lower2ex\hbox to \zeropoint - {\fitfield[\currentsystemfield:but]}% - #2}% - \ht0\strutht\dp0\strutdp\box0 - \egroup} - -%D And one more: - -\def\definefieldstack - {\dotripleargument\dodefinefieldstack} - -\def\dodefinefieldstack[#1][#2][#3]% name, symbols, settings - {\doifundefined{fieldstack:#1} - {\setgvalue{fieldstack:#1}{\dodofieldstack[#1][#2][#3]}}} - -\def\dodofieldstack[#1][#2][#3]% start=n, 0 == leeg - {\bgroup - \getparameters[\??fd][\c!start=1,#3]% - \setupfields[\v!reset]% - \definesymbol[\v!empty][]% - \useJSscripts[fld][FieldStack]% - \newcounter\stackedfieldnumber - \def\dododofieldstack##1% - {\increment\stackedfieldnumber - \ifnum\stackedfieldnumber=\@@fdstart\relax - \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][##1]% - \else - \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][\v!empty]% - \fi}% - \processcommalist[#2]\dododofieldstack - \setupfield[#1][\v!reset]% added - \setupfield[#1][\c!option=\v!readonly,#3]% #3 swapped - \newcounter\stackedfieldnumber - \def\dododofieldstack##1% - {\doglobal\increment\stackedfieldnumber - \fitfield[#1:\stackedfieldnumber]\egroup\bgroup}% - \startoverlay - \bgroup - \globalprocesscommalist[#2]\dododofieldstack - \egroup - \stopoverlay - \egroup} - -\def\dofieldstack[#1][#2][#3]% - {\ifsecondargument - \dodefinefieldstack[#1][#2][#3]\fieldstack[#1]% - \else - \getvalue{fieldstack:#1}\setgvalue{fieldstack:#1}{[#1]}% - \fi} - -\def\fieldstack - {\dotripleempty\dofieldstack} - -%D When submitting a form, we need to tell the driver module -%D that we want \FDF\ or \HTML. - -\def\setupforms - {\dodoubleargument\getparameters[\??fr]} - -\def\checksubmitform#1% - {\setsubmitoutputformat\@@frmethod} - -\setexecutecommandcheck {submitform} \checksubmitform - -\setupforms - [\c!method=HTML] - -\protect \endinput diff --git a/tex/context/base/core-hlp.tex b/tex/context/base/core-hlp.tex deleted file mode 100644 index 46b469b68..000000000 --- a/tex/context/base/core-hlp.tex +++ /dev/null @@ -1,169 +0,0 @@ -%D \module -%D [ file=core-hlp, -%D version=1998.10.10, -%D title=\CONTEXT\ Core 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 - -%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/core-inc.lua b/tex/context/base/core-inc.lua deleted file mode 100644 index 35370058d..000000000 --- a/tex/context/base/core-inc.lua +++ /dev/null @@ -1,854 +0,0 @@ -if not modules then modules = { } end modules ['core-inc'] = { - version = 1.001, - comment = "companion to core-inc.tex", - 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 - ---[[ -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 texsprint, format, lower = tex.sprint, string.format, string.lower - -local ctxcatcodes = tex.ctxcatcodes - -local trace_figures = false trackers.register("figures.locating",function(v) trace_figures = 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 = size:gsub("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.boxid 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", "mov", "buffer", "tex" -} - -figures.formats = { - ["pdf"] = { }, - ["mps"] = { patterns = { "%d+" } }, - ["jpg"] = { list = { "jpg", "jpeg" } }, - ["png"] = { } , - ["jbig"] = { list = { "jbig", "jbig2", "jb2" } }, - ["svg"] = { list = { "svg", "svgz" } }, - ["eps"] = { list = { "eps", "ai" } }, - ["mov"] = { list = { "mov", "avi" } }, - ["buffer"] = { list = { "tmp", "buffer", "buf" } }, - ["tex"] = { }, -} - -function figures.setlookups() - figures.suffixes, figures.patterns = { }, { } - for _, format in pairs(figures.order) do - local data = figures.formats[format] - local fs, fp = figures.suffixes, figures.patterns - if data.list then - for _, s in ipairs(data.list) do - fs[s] = format -- hash - end - else - fs[format] = format - end - if data.patterns then - for _, s in ipairs(data.patterns) do - fp[#fp+1] = { s, format } -- array - end - end - end -end - -figures.setlookups() - -local function register(tag,target,what) - local data = figures.formats[target] - if data then - local d = data[tag] - if d and not table.contains(d,what) then - d[#d+1] = what - else - data[tag] = { what } - end - else - figures.formats[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 pathlist:gmatch("([^, ]+)") do - if not table.contains(t,s) then - t[#t+1] = s - end - end - end - figures.paths, last_pathlist = t, pathlist - if trace_figures then - logs.report("figures","locations: %s",last_locationset) - logs.report("figures","path list: %s",table.concat(figures.paths)) - end -end - --- check conversions and handle it here - ---~ local keys = img.keys() - ---~ function figures.hash(data) ---~ local i = data.status.private ---~ local t = { } ---~ for _, v in ipairs(keys) do ---~ local iv = i[v] ---~ if iv then ---~ t[#t+1] = v .. '=' .. iv ---~ end ---~ end ---~ return table.concat(t,"+") ---~ end - -function figures.hash(data) - return tostring(data.status.private) -- the --- 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) - statistics.starttiming(figures) - 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] == "yes" - request["repeat"] = iv[request["repeat"]] == "yes" - request.preview = iv[request.preview] == "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[#callstack+1] = figuredata - return figuredata - end - function figures.pop() - figuredata = callstack[#callstack] - callstack[#callstack] = nil - statistics.stoptiming(figures) - end - -- maybe move texsprint to tex - function figures.get(category,tag,default) - local value = figuredata[category][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 function register(askedname,specification) - if specification then - local format = specification.format - if format then - local converter = figures.converters[format] - if converter then - local oldname = specification.fullname - local newformat = "pdf" -- todo, other target than pdf - local newpath = file.dirname(oldname) - local newbase = file.replacesuffix(file.basename(oldname),newformat) - local fc = specification.cache or figures.cachepaths.path - if fc and fc ~= "" and fc ~= "." then - newpath = fc - end - local subpath = specification.subpath or figures.cachepaths.subpath - if subpath and subpath ~= "" and subpath ~= "." then - newpath = newpath .. "/" .. subpath - end - local prefix = specification.prefix or figures.cachepaths.prefix - if prefix and prefix ~= "" then - newbase = prefix .. newbase - end - local newname = file.join(newpath,newbase) - dir.makedirs(newpath) - local oldtime = lfs.attributes(oldname,'modification') or 0 - local newtime = lfs.attributes(newname,'modification') or 0 - if oldtime > newtime then - converter(oldname,newname) - end - if io.exists(newname) then - specification.foundname = oldname - specification.fullname = newname - specification.prefix = prefix - specification.subpath = subpath - specification.converted = true - format = newformat - elseif io.exists(oldname) then - specification.fullname = newname - specification.converted = false - end - end - end - local found = figures.suffixes[format] -- validtypes[format] - if not found then - specification.found = false - if trace_figures then - logs.report("figures","format not supported: %s",format) - end - else - specification.found = true - if trace_figures then - if validtypes[format] then - logs.report("figures","format natively supported by backend: %s",format) - else - logs.report("figures","format supported by output file format: %s",format) - end - end - end - else - specification = { } - end - specification.foundname = specification.foundname or specification.fullname - figures.found[askedname] = specification - return specification -end - -local function locate(request) -- name, format, cache - local askedname = resolvers.clean_path(request.name) - if figures.found[askedname] then - return figures.found[askedname] - end - local askedpath= file.dirname(askedname) - local askedbase = file.basename(askedname) - local askedformat = (request.format ~= "" and request.format ~= "unknown" and request.format) or file.extname(askedname) or "" - local askedcache = request.cache - if askedformat ~= "" then - askedformat = lower(askedformat) - local format = figures.suffixes[askedformat] - if not format then - for _, pattern in ipairs(figures.patterns) do - if askedformat:find(pattern[1]) then - format = pattern[2] - break - end - end - end - if format then - local foundname = figures.exists(askedname,askedformat) - if foundname then - return register(askedname, { - askedname = askedname, - fullname = askedname, - format = format, - cache = askedcache, - foundname = foundname, - }) - end - end - if askedpath ~= "" then - -- path and type given, todo: strip pieces of path - if figures.exists(askedname,askedformat) then - return register(askedname, { - askedname = askedname, - fullname = askedname, - format = askedformat, - cache = askedcache, - }) - end - else - -- type given - for _, path in ipairs(figures.paths) do - local check = path .. "/" .. askedname - if figures.exists(check,askedformat) then - return register(check, { - askedname = askedname, - fullname = check, - format = askedformat, - cache = askedcache, - }) - 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, - }) - end - end - end - elseif askedpath ~= "" then - for _, format in ipairs(figures.order) do - local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do - local check = file.addsuffix(askedname,suffix) - if figures.exists(check,format) then - return register(askedname, { - askedname = askedname, - fullname = check, - format = format, - cache = askedcache, - }) - end - end - end - else - if figures.prefer_quality then - for _, format in ipairs(figures.order) do - local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do - local name = file.replacesuffix(askedbase,suffix) - for _, path in ipairs(figures.paths) do - local check = path .. "/" .. name - if figures.exists(check,format) then - return register(askedname, { - askedname = askedname, - fullname = check, - format = format, - cache = askedcache, - }) - end - end - end - end - else -- 'location' - for _, path in ipairs(figures.paths) do - for _, format in ipairs(figures.order) do - local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do - local check = path .. "/" .. file.replacesuffix(askedbase,suffix) - if figures.exists(check,format) then - return register(askedname, { - askedname = askedname, - fullname = check, - format = format, - cache = askedcache, - }) - end - end - end - end - end - if figures.defaultsearch then - for _, format in ipairs(figures.order) do - local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do - local check = resolvers.find_file(file.replacesuffix(askedname,suffix)) - if check and check ~= "" then - return register(askedname, { - askedname = askedname, - fullname = check, - format = format, - cache = askedcache, - }) - end - end - end - end - end - return register(askedname) -end - --- -- -- plugins -- -- -- - -figures.existers = figures.existers or { } -figures.checkers = figures.checkers or { } -figures.includers = figures.includers or { } -figures.converters = figures.converters or { } -figures.identifiers = figures.identifiers or { } - -figures.identifiers.list = { - figures.identifiers.default -} - -function figures.identifiers.default(data) - local dr, du, ds = data.request, data.used, data.status - local l = locate(dr) - local foundname = l.foundname - local fullname = l.fullname or foundname - if fullname then - du.format = l.format or false - du.fullname = fullname -- can be cached - ds.fullname = foundname -- original - ds.format = l.format - ds.status = (l.found and 10) or 0 - end - return data -end - -function figures.identify(data) - data = data or figures.current() - for _, identifier in ipairs(figures.identifiers.list) do - data = identifier(data) - if data.status.status > 0 then - break - end - end - return data -end -function figures.exists(askedname,format) - return (figures.existers[format] or figures.existers.generic)(askedname) -end -function figures.check(data) - data = data or figures.current() - local dr, du, ds = data.request, data.used, data.status - return (figures.checkers[ds.format] or figures.checkers.generic)(data) -end -function figures.include(data) - data = data or figures.current() - local dr, du, ds = data.request, data.used, data.status - return (figures.includers[ds.format] or figures.includers.generic)(data) -end -function figures.scale(data) -- will become lua code - texsprint(ctxcatcodes,"\\doscalefigure") - return data -end -function figures.done(data) - figures.n = figures.n + 1 - data = data or figures.current() - local dr, du, ds = data.request, data.used, data.status - ds.width = tex.wd[figures.boxnumber] - ds.height = tex.ht[figures.boxnumber] - ds.xscale = ds.width/(du.width or 1) - ds.yscale = ds.height/(du.height or 1) - return data -end - -function figures.dummy(data) -- fails ---~ data = data or figures.current() ---~ local dr, du, ds = data.request, data.used, data.status ---~ local r = node.new("rule") ---~ r.width = du.width or figures.defaultwidth ---~ r.height = du.height or figures.defaultheight ---~ r.depth = du.depth or figures.defaultdepth ---~ tex.box[figures.boxnumber] = node.write(r) - texsprint(ctxcatcodes,"\\emptyfoundexternalfigure") -end - --- -- -- generic -- -- -- - -function figures.existers.generic(askedname) ---~ local result = io.exists(askedname) ---~ result = (result==true and askedname) or result ---~ local result = resolvers.find_file(askedname) or "" - local result = resolvers.findbinfile(askedname) or "" - if result == "" then result = false end - if trace_figures then - if result then - logs.report("figures","found: %s -> %s",askedname,result) - else - logs.report("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 = du.fullname or "unknown generic", du.page or dr.page, dr.size or "crop" - local hash = name .. "->" .. page .. "->" .. size - local figure = figures.loaded[hash] - if figure == nil then - figure = img.new { filename = name, page = page, pagebox = dr.size } - figure = (figure and img.scan(figure)) or false - figures.loaded[hash] = figure - end - if figure then - du.width = figure.width - du.height = figure.height - du.pages = figure.pages - ds.private = figure - 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.page = dr.page or '1' - figure = img.copy(figure) - figure = (figure and img.clone(figure,data.request)) or false - end - figures.used[hash] = figure - end - if figure then - local n = figures.boxnumber - tex.box[n] = img.node(figure) -- img.write(figure) - tex.wd[n], tex.ht[n], tex.dp[n] = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) - ds.objectnumber = figure.objnum - texsprint(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 - dr.width = (dr.width or figures.defaultwidth):todimen() - dr.height = (dr.height or figures.defaultheight):todimen() - du.width = dr.width - du.height = dr.height - du.foundname = du.fullname - local code = backends.codeinjections { - width = du.width or dr.width, - height = du.height or dr.height, - factor = number.dimenfactors.bp, - ["repeat"] = dr["repeat"], - controls = dr.controls, - preview = dr.preview, - label = dr.label, - foundname = du.foundname, - } - texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}%s\\stopfoundexternalfigure",du.width,du.height,code)) - return data -end - -figures.includers.mov = figures.includers.nongeneric - --- -- -- mps -- -- -- - -function figures.checkers.mps(data) - return figures.checkers.nongeneric(data,format("\\docheckfiguremps{%s}",data.used.fullname)) -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 - --- -- -- eps -- -- -- - -function figures.converters.eps(oldname,newname) - -- hack, we need a lua based converter script, or better, we should use - -- rlx as alternative - local outputpath = file.dirname(newname) - local outputbase = file.basename(newname) - local command = format("mtxrun bin:pstopdf --outputpath=%s %s",outputpath,oldname) - os.spawn(command) -end - -figures.converters.svg = figures.converters.eps - --- -- -- lowres -- -- -- - ---~ function figures.converters.pdf(oldname,newname) ---~ local outputpath = file.dirname(newname) ---~ local outputbase = file.basename(newname) ---~ local command = format("mtxrun bin:pstopdf --method=4 --outputpath=%s %s",outputpath,oldname) ---~ os.spawn(command) ---~ end - -figures.bases = { } -figures.bases.list = { } -- index => { basename, fullname, xmlroot } -figures.bases.used = { } -- [basename] => { basename, fullname, xmlroot } -- pointer to list -figures.bases.found = { } -figures.bases.enabled = false - -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 - end - end -end - -function bases.find(basename,askedlabel) - 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 - for _, path in ipairs(figures.paths) do - local xmlfile = path .. "/" .. basename - if io.exists(xmlfile) then - base[2] = xmlfile - base[3] = xml.load(xmlfile) - break - end - end - end - t = false - if base[2] and base[3] then -- rlx:library - for e, d, k in xml.elements(base[3],"/(*:library|figurelibrary)/*:figure/*:label") do - page = page + 1 - if xml.content(d[k]) == askedlabel then - t = { - base = file.replacesuffix(base[2],"pdf"), - format = "pdf", - name = xml.filters.text(e,"*:file"), - page = page, - } - bases.found[askedlabel] = t - return t - end - end - end - end - return t -end - --- we can access sequential or by name - -function bases.locate(askedlabel) - for _, entry in ipairs(bases.list) do - 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/core-inc.mkii b/tex/context/base/core-inc.mkii deleted file mode 100644 index ce97a0d1b..000000000 --- a/tex/context/base/core-inc.mkii +++ /dev/null @@ -1,1265 +0,0 @@ -%D \module -%D [ file=core-inc, % moved from core-fig -%D version=2006.08.26, % overhaul of 1997.03.31 -%D title=\CONTEXT\ Core Macros, -%D subtitle=Figure Inclusion, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Figure Inclusion} - -% 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 - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -%D Due to the mere fact that \DVI|/|\PDF\ drivers differ in their -%D needs for figure dimensions, we have to provide the width, -%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 - -%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! - {\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]}}% - \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]% - \ifcase\figurewidth - \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}} - -% \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 -% \let\figurepathlist\wantedfigurepath -% \let\wantedfigurepath\empty -% \settrue\figurefileisqualified -% \fi -% \else % fully qualified -% \splitfigurefilename -% \let\figurepathlist\wantedfigurepath -% \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}} - -% 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} - -\protect \endinput diff --git a/tex/context/base/core-inc.mkiv b/tex/context/base/core-inc.mkiv deleted file mode 100644 index 06c8dc306..000000000 --- a/tex/context/base/core-inc.mkiv +++ /dev/null @@ -1,417 +0,0 @@ -%D \module -%D [ file=core-inc, % moved from core-fig -%D version=2006.08.26, % overhaul of 1997.03.31 -%D title=\CONTEXT\ Core Macros, -%D subtitle=Figure Inclusion, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Figure Inclusion} - -%D todo: -%D -%D - color conversion -%D - color separation -%D - alternative images -%D - a few more obscure things - -\registerctxluafile{core-inc}{1.001} - -\unprotect - -%D The following registers are used (if only to be downward compatible). - -\newbox \foundexternalfigure -\newif \iftraceexternalfigures -\newif \ifskipexternalfigures -\newtoks \everyexternalfigureresets -\newtoks \everyexternalfigurechecks -\newtoks \externalfigurepostprocessors -\chardef \splitexternalfigure \zerocount % 0 nosplit 1 split/yes 2 split/no - -\let\traceexternalfigures \traceexternalfigurestrue - -\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 - -\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","\@@exdirectory")}} - -%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.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}% - % 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} - -\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\doscalefigure - {\global\setbox\foundexternalfigure\vbox{\doscalebox\??ef{\dowithfigure{\box\foundexternalfigure}}}} - -\newconditional\testexternalfigureonly - -\def\calculateexternalfigure[#1][#2][#3][#4][#5][#6]% \cmd label filename parent_id preset current - {\dontcomplain - \restorecatcodes - \forgetall - \resetfigurevariables - \dosetefparameters{#4}{#5}{#6}% - \checkfigurevariables - \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", - ["repeat"]="\@@efrepeat", - width="\@@efwidth", % can be crap - height="\@@efheight", % can be crap - } }% - \ctxlua{figures.identify()}% - \ifconditional\testexternalfigureonly - \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 - {\ifcase\figurestatus - \resetsystemmode\v!figure % todo, also: \v!resource - \else - \setsystemmode \v!figure % todo, also: \v!resource - \fi} - -\def\startfoundexternalfigure#1#2% - {\global\setbox\foundexternalfigure\vbox to #2\bgroup\vss\hbox to #1\bgroup} - -\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\ifnum\splitexternalfigure=\plustwo\else - \the\externalfigurepostprocessors - \box\foundexternalfigure - \fi\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\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}} - -\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethreearguments\fi -\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethreearguments\fi - -\let\feedbackexternalfigure\relax % \gobblefourarguments -\let\dowithfigure \relax - -% \let\lastfigureobjectname\empty - -\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]% - {\startnointerference - \testexternalfigureonly - \externalfigure[#1][#2,\c!display=,\c!object=\v!no]% - \stopnointerference} - -\let\getfiguredimensionsonly\getfiguredimensions - -\def\doiffigureelse#1% - {\getfiguredimensions[#1]% - \ifcase\figurewidth % 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 diff --git a/tex/context/base/core-int.mkii b/tex/context/base/core-int.mkii deleted file mode 100644 index 1ca9d23d1..000000000 --- a/tex/context/base/core-int.mkii +++ /dev/null @@ -1,2217 +0,0 @@ -%D \module -%D [ file=core-int, -%D version=1995.01.01, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Interaction, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% evt interactionbaren runtime laden (scheelt 8K) - -%D Still to be done properly. - -\writestatus{loading}{ConTeXt Core Macros / Interaction} - -\unprotect - -% \expand vs \expanded - -% linked registers implementeren als een koppeling == mooier - -\presetlocalframed[\??lk] - -\newcounter\numberoflinks - -\def\stelkoppelingenin% - {\dodoubleargument\getparameters[\??lk]} - -\def\definieerkoppeling[#1]% % local loading ! - {\doifundefined{\s!link:#1:\s!list} - {\expanded{\definetwopasslist{\s!link:#1}}% - \expanded{\doloadtwopassdata{\s!link:#1}}% - \getfirsttwopassdata{\s!link:#1}% - \letgvalue{\s!link:#1:f}\twopassdata - \getlasttwopassdata{\s!link:#1}% - \letgvalue{\s!link:#1:l}\twopassdata - \letgvalue{\s!link:#1:s}\noftwopassitems - \gettwopassdata{\s!link:#1}% - \letgvalue{\s!link:#1:c}\twopassdata - \letgvalue{\s!link:#1:n}\twopassdata}} - -\def\koppeling[#1]#2% - {\bgroup - \definieerkoppeling[#1]% - \doglobal\increment\numberoflinks - \gettwopassdata{\s!link:#1}% - \edef\numberoflinks{0\getvalue{\s!link:#1:s}}% - \edef\firstlink {0\getvalue{\s!link:#1:f}}% - \edef\lastlink {0\getvalue{\s!link:#1:l}}% - \edef\currentlink {0\getvalue{\s!link:#1:n}}% - \edef\prevlink {0\getvalue{\s!link:#1:c}}% - \iftwopassdatafound - \edef\nextlink{0\twopassdata}% - \letgvalue{\s!link:#1:n}\nextlink - \letgvalue{\s!link:#1:c}\currentlink - \else - \edef\nextlink{0\getvalue{\s!link:#1:l}}% - \fi - \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% - \ifnum\noflinks<\plustwo - \locationfalse - \fi - \iflocation - \hbox - {\setinteractionparameter\c!width\!!zeropoint - \dogotosomepage\??lk\gotobegincharacter\firstlink\hss - \ifnum\noflinks>\plustwo - \hskip\@@lkdistance - \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss - \fi - \hskip\@@lkdistance - #2\relax - \hskip\@@lkdistance - \ifnum\noflinks>\plustwo - \dogotosomepage\??lk\goforwardcharacter\nextlink\hss - \hskip\@@lkdistance - \fi - \dogotosomepage\??lk\gotoendcharacter\lastlink}% - \else - \hbox{#2}% - \fi - \egroup} - -\def\definieerkoppeling[#1]% % local loading ! - {\doifundefined{\s!link:#1:\s!list} - {\expanded{\definetwopasslist{\s!link:#1}}% \expanded{\doloadtwopassdata{\s!link:#1}}% - \getfirsttwopassdata{\s!link:#1}% - \let\firstlink\twopassdata - \getlasttwopassdata{\s!link:#1}% - \let\lastlink\twopassdata - \let\noflinks\noftwopassitems - \gettwopassdata{\s!link:#1}% - \let\currentlink\twopassdata - \let\nextlink\twopassdata - \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}}} - -\def\koppeling[#1]#2% - {\bgroup - \definieerkoppeling[#1]% - \doglobal\increment\numberoflinks - \gettwopassdata{\s!link:#1}% - \def\next[##1:##2:##3:##4:##5]% - {\edef\firstlink {0##1}% - \edef\lastlink {0##2}% - \edef\noflinks {0##3}% - \edef\prevlink {0##4}% - \edef\currentlink{0##5}}% - \expanded{\next[\getvalue{\s!link:#1:}]}% - \edef\nextlink{0\iftwopassdatafound\twopassdata\else\lastlink\fi}% - \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}% - \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% - \ifnum\noflinks<\plustwo - \locationfalse - \fi - \iflocation - \hbox - {\setinteractionparameter\c!width\!!zeropoint - #2\relax - \hskip\@@lkdistance - \dogotosomepage\??lk\gotobegincharacter\firstlink\hss - \ifnum\noflinks>\plustwo - \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss - \fi - \ifnum\noflinks>\plustwo - \dogotosomepage\??lk\goforwardcharacter\nextlink\hss - \hskip\@@lkdistance - \fi - \dogotosomepage\??lk\gotoendcharacter\lastlink}% - \else - \hbox{#2}% - \fi - \egroup} - -\let\setupinteractionscreens\empty - -\def\docalculateinteractionscreen - {\doifelse\@@scwidth\v!fit - {\!!widtha\leftcombitotal - \ifdim\backspace>\!!widtha\ifdim\backspace>\zeropoint\relax - \advance\backspace -\!!widtha - \fi\fi - \advance\!!widtha\rightcombitotal - \advance\!!widtha 2\dimexpr\@@scbackspace+\@@schoroffset\relax} - {\doifelse\@@scwidth\v!max - {\!!widtha\printpaperwidth} - {\!!widtha\@@scwidth}}% - \doifelse\@@scheight\v!fit - {\!!heighta\dimexpr\topheight+\topdistance\relax - \ifdim\topspace>\!!heighta\ifdim\topspace>\zeropoint\relax - \advance\topspace -\!!heighta - \fi\fi - \advance\!!heighta \dimexpr\makeupheight+\bottomdistance+\bottomheight\relax - \advance\!!heighta 2\dimexpr\@@sctopspace+\@@scveroffset\relax} - {\doifelse\@@scheight\v!max - {\!!heighta\printpaperheight} - {\!!heighta\@@scheight}}% - \doif\@@scdelay\v!none{\let\@@scdelay\zerocountervalue}} - -% The macro is not to be changed; only the \@@ia-variables -% may be set! ConTeXt is the producer but we no longer -% mention the pragma site, since we don't want to be bothered -% with remarks about third party documents and/or associated -% with documents produced outside our control. - -\def\doprepareidentity % beware, we need to construct - {\let\!!stringa\@@iakeyword % an unexpanded space separated - \let\@@iakeyword\empty % list of keywords from a comma - \def\doprepareidentity##1% % separated one - {\ifx\@@iakeyword\empty - \appended\def\@@iakeyword{##1}% - \else - \appended\def\@@iakeyword{ ##1}% - \fi}% - \@EA\processcommalist\@EA[\!!stringa]\doprepareidentity - \global\let\doprepareidentity\relax} - -%D The Creator field is changed per 12/04/2006 due to user presure. This -%D means that I need to put my own status info someplace else. - -\def\initializeidentity - {\doprepareidentity - \dosetupidentity % no \expanded{..} will be done in special (else no pdfdoc) - {\@@iatitle}{\@@iasubtitle}{\@@iaauthor}% - {ConTeXt - \contextversion}% - {\@@iadate}{\@@iakeyword}% - \global\let\initializeidentity\relax} - -\appendtoks \initializeidentity \to \everyshipout - -\def\initializepaper - {\bgroup - \ifx\@@ppleft \empty - \ifx\@@ppright\empty - \ifx\@@pptop \empty - \ifx\@@ppbottom \empty - \ifx\@@pcstate\v!start - \locationfalse\fi\else - \locationfalse\fi\else - \locationfalse\fi\else - \locationfalse\fi\else - \locationfalse\fi - \iflocation % without screen settings - \egroup - \dosetuppaper\papersize\paperwidth\paperheight - \else - \egroup - \dosetuppaper\printpapersize\printpaperwidth\printpaperheight - \fi} - -\appendtoks \initializepaper \to \everyshipout - -\def\doinitializepaper - {\bgroup - \docalculateinteractionscreen - \ifdim\!!widtha>\paperwidth\ifdim\!!widtha>\zeropoint - \paperwidth\!!widtha - \fi\fi - \ifdim\!!heighta>\paperheight\ifdim\!!heighta>\zeropoint - \paperheight\!!heighta - \fi\fi - \dosetuppaper - {\printpapersize} - {\the\paperwidth} - {\the\paperheight}% - \egroup} - -\let\@@pcscreendata\empty - -\def\dosetupinteractionscreens % met a, b en \number - {\doifnot\@@pcstate\v!start\dodosetupinteractionscreens} - -\setvalue{\??sc\c!option\v!max }{1} % tzt share with driver -\setvalue{\??sc\c!option\v!bookmark }{2} % tzt share with driver -\setvalue{\??sc\c!option\v!fit }{3} % tzt share with driver -\setvalue{\??sc\c!option\v!doublesided}{4} % tzt share with driver - -\def\dodosetupinteractionscreens % met a, b en \number - {\bgroup - \docalculateinteractionscreen - \!!counte=0\getvalue{\??sc\c!option\@@scoption}\relax - % niet waterdicht - \doifnot{\the\!!widtha\the\!!heighta}\@@pcscreendata - {\xdef\@@pcscreendata{\the\!!widtha\the\!!heighta}% - \showmessage\m!interactions1{\withoutpt\the\!!widtha,\withoutpt\the\!!heighta}}% - % needs to be split: dimensions for each page - % and mode per document and only once ! - \dosetupscreen \backoffset\topoffset\!!widtha\!!heighta{\the\!!counte}% - \dosetupcropbox\backoffset\topoffset\!!widtha\!!heighta - \egroup} - -\def\dosetupinteractionscreen[#1]% - {\getparameters[\??sc][#1]% - \ifproductionrun - \let\initializepaper\doinitializepaper - \let\setupinteractionscreens\dosetupinteractionscreens - \fi} - -\appendtoks \setupinteractionscreens \to \everyfirstshipout % needed to get option=max etc working -\appendtoks \setupinteractionscreens \to \everyshipout % needed for page/screen dimensions - -\def\setupinteractionscreen - {\dosingleempty\dosetupinteractionscreen} - -%D Due to requests I finally decided to support bookmarks, a -%D driver dependant way of showing tables of content. The most -%D simple way of support is hooking bookmark generation into -%D the existing list mechanisms. That way users can generate -%D bookmarks automatically, although its entirely valid to add -%D bookmarks by defining alternative ones. These will be added -%D at the appropriate place in the list. - -% \hoofdstuk{het eerste hoofdstuk} -% -% \bookmark {de eerste bookmark} % optional overruled hoofdstuk -% -% .... text .... -% -% \placebookmarks [hoofdstuk,paragraaf,subparagraaf,subsubparagraaf,mylist] -% [open list] -% -% \bookmark[mylist]{whatever} - -\def\@@bookmark {bm::} -\def\@@booklevel{bl::} -\def\@@bookcount{bc::} - -\definelist[\@@bookmark] - -\newtoks\postponedbookmarks - -\def\flushpostponedbookmark - {\the\postponedbookmarks - \global\postponedbookmarks\emptytoks} - -\def\simplebookmark#1% - {\doglobal\prependtoks - \writetolist[\@@bookmark]{}{#1}% - \to\postponedbookmarks} - -\def\complexbookmark[#1]#2% - {\doglobal\appendtoks\writetolist[#1]{}{#2}\to\postponedbookmarks} - -\definecomplexorsimple\bookmark - -\newif\iftracebookmarks \tracebookmarksfalse - -\let\tracebookmarks\tracebookmarkstrue - -\def\placebookmarks - {\dodoubleempty\doplacebookmarks} - -\def\doplacebookmarks[#1][#2]% - {\iflocation - \iffirstargument - \bgroup - \ifsecondargument - \doifelse{#2}\v!all - {\edef\openbookmarklist{#1}} - {\edef\openbookmarklist{#2}}% - \else - \let\openbookmarklist\empty - \fi - \global\let\bookmarklevellist\empty - \def\bookmarklevelcount{0}% - \doprocessbookmarks[#1]\dogetbookmarkelement - \dolistelement{}{}{}{}{}{}% needed to finish the first pass - \doprocessbookmarks[#1]\doputbookmarkelement - \flushbookmark - \egroup - \else - \expanded{\placebookmarks\@EA[\getvalue{\??ih\v!content\c!list}]}% - \fi - \fi} - -\def\doprocessbookmarks[#1]#2% - {\let\dolistelement#2\relax - \scratchcounter\zerocount - \def\docommand##1% - {\advance\scratchcounter \plusone - \getlistlevel[##1]\listlevel{\the\scratchcounter}% - \setxvalue{\@@bookcount\the\scratchcounter}{1}% - \setxvalue{\@@booklevel##1}{\listlevel}}% - \processcommalist[#1]\docommand - \setxvalue{\@@bookcount0}{1}% - \global\chardef\currentbookmarklevel\zerocount - \global\chardef\previousbookmarklevel\zerocount - \doutilities{listentries,#1,\@@bookmark}\jobname{#1}\relax\relax} - -\def\dodogetbookmarkelement#1#2#3#4#5#6% - {\doifelsenothing{#1} - {\global\chardef\currentbookmarklevel\zerocount} - {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% - \ifnum\currentbookmarklevel>\previousbookmarklevel - \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% - \else\ifnum\currentbookmarklevel<\previousbookmarklevel - \bgroup - \!!counta\previousbookmarklevel - \doloop - {\let\bookmarktag\empty - \!!countb\!!counta - \advance\!!countb \minusone - \dorecurse\!!countb - {\edef\bookmarktag - {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% - \edef\bookmarklevelcount - {\getvalue{\@@bookcount\the\!!counta}}% - \xdef\bookmarklevellist - {\bookmarklevellist/\bookmarktag:\bookmarklevelcount/}% - \advance\!!counta \minusone - \ifnum\!!counta=\currentbookmarklevel - \exitloop - \fi}% - \egroup - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax - \else - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax - \fi\fi - \global\utilitydonetrue - \global\chardef\previousbookmarklevel\currentbookmarklevel} - -\def\getbookmarklevelcount - {\@EA\def\@EA\docommand\@EA[\@EA##\@EA1\@EA/\bookmarktag:##2/##3]% - {\def\bookmarklevelcount{##2}}% - \@EA\@EA\@EA\docommand\@EA\@EA\@EA[\@EA\bookmarklevellist\@EA/\bookmarktag:0/]} - -\def\dodoputbookmarkelement#1#2#3#4#5#6% - {\doifelsenothing{#1} - {\global\chardef\currentbookmarklevel\zerocount} - {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% - \ifnum\currentbookmarklevel>\previousbookmarklevel - \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% - \else\ifnum\currentbookmarklevel<\previousbookmarklevel - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax - \else - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax - \fi\fi - \let\bookmarktag\empty - \!!countb\currentbookmarklevel - \dorecurse\!!countb - {\edef\bookmarktag - {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% - \getbookmarklevelcount - \iftracebookmarks - \bgroup - \par - \bookmarktag\quad - \dorecurse\currentbookmarklevel{\quad}\unskip#1\quad - (\bookmarklevelcount)\quad - \egroup - \fi - \global\chardef\previousbookmarklevel\currentbookmarklevel - \global\utilitydonetrue - \insertsomebookmark{#1}{\the\currentbookmarklevel}{\bookmarklevelcount}{#4}{#6}} - -\def\dogetbookmarkelement#1#2#3#4#5#6% - {\doifnot{#1}\@@bookmark - {\dodogetbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} - -\def\doputbookmarkelement#1#2#3#4#5#6% - {\doifelse{#1}\@@bookmark - {\localbookmark{#4}} - {\flushbookmark - \dodoputbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} - -\let\flushbookmark\relax -\let\localbookmark\gobbleoneargument - -\def\insertsomebookmark#1#2#3#4#5% - {\gdef\flushbookmark - {\doinsertsomebookmark{#1}{#2}{#3}{#4}{#5}{g}}% - \gdef\localbookmark##1% - {\doinsertsomebookmark{#1}{#2}{#3}{##1}{#5}{l}}} - -\def\doinsertsomebookmark#1#2#3#4#5#6% - {\global\utilitydonetrue - \global\let\localbookmark\gobbleoneargument - \global\let\flushbookmark\relax - \doifinstringelse{#1}\openbookmarklist - {\chardef\openbookmark\plusone} - {\chardef\openbookmark\zerocount}% - \iftracebookmarks(#6: #4)\quad(\the\openbookmark)\par\fi - \doinsertbookmark{#2}{#3}{#4}{#5}{\openbookmark}} - -% \startinteractionmenu[rechts] -% \but [eerste] eerste \\ -% \txt hello world \\ -% \but [tweede] tweede \\ -% \nop \\ -% \but [tweede] tweede \\ -% \rul whow \\ -% \but [tweede] tweede \\ -% \raw hello world \\ -% \but [tweede] tweede \\ -% \com \vfill \\ -% \but [derde] derde \\ -% \stopinteractionmenu - -\newif\iflocationmenupermitted - -\def\testinteractionmenu#1% - {\iflocation - \doifelse\@@iamenu\v!on - {\doifelsevalue{\??am#1\c!state}\v!start - {\global\locationmenupermittedtrue} - {\global\locationmenupermittedfalse}} - {\global\locationmenupermittedfalse}% - \else - \global\locationmenupermittedfalse - \fi} - -\def\dodisableinteractionmenu[#1][#2][#3]% - {\def\dododisableinteractionmenu##1% - {\doifelse{#3}{} - {\letvalue{\??am##1\c!obstruction}\empty} - {\edef\interactieblokkade{\getvalue{\??am##1\c!obstruction}} - \def\docommand####1{#1{####1}{\interactieblokkade}}% #1 = \remove or \add - \processcommalist[#3]\docommand - \setevalue{\??am##1\c!obstruction}{\interactieblokkade}}}% - \processcommalist[#2]\dododisableinteractionmenu} - -\def\disableinteractionmenu - {\dotripleempty\dodisableinteractionmenu[\addtocommalist]} - -\def\enableinteractionmenu - {\dotripleempty\dodisableinteractionmenu[\removefromcommalist]} - -% ja : kader/achtergrond met tekst -% leeg : kader/achtergrond maar geen tekst -% nee : alleen ruimte reserveren -% geen : helemaal weglaten - -\newif\iflocationdummy -\newif\ifskippedmenuitem - -\newif\iflocationempty -\newif\iflocationclick - -% ja : kader/achtergrond met tekst -% leeg : kader/achtergrond maar geen tekst -% nee : alleen ruimte reserveren -% geen : helemaal weglaten -% -% \setupinteractionmenu[right][samepage=yes, unknownreference=yes] -% \setupinteractionmenu[right][samepage=empty,unknownreference=empty] -% \setupinteractionmenu[right][samepage=no, unknownreference=no] -% \setupinteractionmenu[right][samepage=none, unknownreference=none] -% -% \startinteractionmenu[right] -% \but [firstpage] first \\ -% \but [lastpage] last \\ -% \but [somepage] crap \\ -% \stopinteractionmenu - -\def\dosetlocationboxcontent#1[#2]#3[#4]% - {\global\skippedmenuitemfalse - \setbox\locationbox\hbox - {\resetgoto % anders cyclische aanroep ! - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}}% - \iflocationclick - \hbox{\gotolocation{#4}{\box\locationbox}}% - \else - \hbox{\box\locationbox}% - \fi} - -\let\dosetlocationboxyes\dosetlocationboxcontent - -\def\dosetlocationboxempty#1[% - {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,} - -\def\dosetlocationboxno#1[% - {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,\c!frame=,\c!background=,} - -\def\dosetlocationboxnone#1[#2]#3[#4]% - {\global\skippedmenuitemtrue} - -\def\setlocationboxyes#1[#2]#3[#4]% - {\locationclicktrue - \setbox\locationbox\hbox - {\resetgoto % anders cyclische aanroep ! - \global\skippedmenuitemfalse - \gotolocation - {#4}% % needed - {\ifrealreferencepage - \ifcase\csname\??am\??am\csname#1\c!samepage\endcsname\endcsname\relax - \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \global\skippedmenuitemtrue - \fi - \else - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \fi}}% - \ifskippedmenuitem\else\box\locationbox\fi} - -\def\setlocationboxnop#1[#2]#3[#4]% - {\locationclickfalse - \setbox\locationbox\hbox - {\resetgoto % anders cyclische aanroep ! - \global\skippedmenuitemfalse - \ifcase\csname\??am\??am\csname#1\c!unknownreference\endcsname\endcsname\relax - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \global\skippedmenuitemtrue - \fi}% - \ifskippedmenuitem\else\box\locationbox\fi} - -\def\setlocationboxraw#1[#2]#3[#4]% - {\localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}} - -\def\setlocationbox#1[#2]#3[#4]% - {\bgroup % really needed ! - \edef\permittedreferences{\csname#1\c!obstruction\endcsname}% - \doifreferencepermittedelse{#4}% - {\setlocationboxyes{#1}[#2]{#3}[#4]}% - {\setlocationboxnop{#1}[#2]{#3}[#4]}% - \egroup} - -\def\setlocationnop#1[#2]#3% - {\localframed[#1][#2]{#3}} - -\def\executeamboxcommands#1#2#3#4#5% - {%\processaction - % [\getvalue{\??am#1\c!dummy}] - % [ \v!yes=>\chardef\handleunknownmenuitem=0\relax, - % \v!empty=>\chardef\handleunknownmenuitem=1\relax, - % \v!no=>\chardef\handleunknownmenuitem=2\relax]% - \getvalue{\??am#1#3}\relax - \setamboxcommands{#1}{#4}% - \ignorespaces#2\unskip - \getvalue{\??am#1#5}} - -\newcounter\currentamposition - -\newtoks\everysetmenucommands - -\def\setamboxcommands#1#2% - {\def\currentmenu{#1}% % kan nog eerder - \def\currentsubmenu{#2}% % ? ? - \doglobal\newcounter\currentamposition - \the\everysetmenucommands} - -\def\menu@@amboxcommand#1\\% - {\dontleavehmode - \bgroup - \ignorespaces#1\unskip\relax - \ifskippedmenuitem \else - \getvalue{\??am\currentmenu\currentsubmenu}% - \fi - \egroup - \ignorespaces} - -\appendtoks - \let\@@amboxcommand\menu@@amboxcommand -\to \everysetmenucommands - -\def\menu@raw[#1]#2\\% - {\@@amboxcommand\gotobox{\ignorespaces#2\unskip}[#1]\\}% - -\def\menu@but[#1]#2\\% - {\@@amboxcommand\do@@amposition\currentmenu{#1}{\setlocationbox{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}\\}% - -\def\menu@got[#1]#2\\% pas op! offset - {\@@amboxcommand\setlocationbox{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]\\}% - -\def\menu@nop#1\\% - {\@@amboxcommand\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]\\}% - -\def\menu@txt#1\\% - {\@@amboxcommand\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}\\}% - -\def\menu@rul#1\\% ook \do@@amposition ! - {\@@amboxcommand\localframed[\??am\currentmenu][]{\ignorespaces#1\unskip}\\}% - -\def\menu@com#1\\% - {\ignorespaces#1\unskip\ignorespaces}% - -\appendtoks - \let\raw\menu@raw - \let\but\menu@but - \let\got\menu@got - \let\nop\menu@nop - \let\txt\menu@txt - \let\rul\menu@rul - \let\com\menu@com -\to \everysetmenucommands - -\ifx\do@@amposition\undefined - \let\do@@amposition\gobbletwoarguments % hook for positional thingies -\fi - -\let\currentmenu\empty - -% beware : never change the concept of pbgoffset - -\def\menuparameter#1{\csname\??am\currentmenu#1\endcsname} - -\def\@@amhbox#1#2#3#4% - {\def\currentmenu{#3}% - \testinteractionmenu{#3}% - \iflocationmenupermitted - \bgroup - \showcomposition - \scratchdimen\dimexpr - \makeupwidth - +\pagebackgroundhoffset - +\pagebackgroundhoffset - -\menuparameter\c!leftoffset - -\menuparameter\c!rightoffset - \relax - \setbox\scratchbox\hbox to \scratchdimen - {\forgetall\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}% - \setbox\scratchbox\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}% - \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet) - \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax - \box\scratchbox - \egroup - \else - #1\relax - \fi} - -\def\@@amvbox#1#2#3#4% don't change skipping, this one works! - {\def\currentmenu{#3}% - \testinteractionmenu{#3}% - \iflocationmenupermitted - \bgroup - \showcomposition - \scratchdimen\dimexpr - \textheight - +\pagebackgroundvoffset - +\pagebackgroundvoffset - +\pagebackgrounddepth - -\menuparameter\c!topoffset - -\menuparameter\c!bottomoffset - \relax - \setbox\scratchbox\vbox to \scratchdimen - {\forgetall % Voor't geval de afstand - %\setupblank[\v!standard]% % (tijdelijk) is aangepast. - \restorestandardblank - \hsize#2\relax - \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}% - \setbox\scratchbox\vbox{\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}}% - \setbox\scratchbox\vbox - {\ht\scratchbox\zeropoint - \vskip\dimexpr-\pagebackgroundvoffset+\menuparameter\c!topoffset\relax - \box\scratchbox - \vskip\pagebackgroundvoffset}% overbodig - \ht\scratchbox\textheight - \wd\scratchbox#2\relax - \box\scratchbox - \egroup - \else - #1\relax - \fi} - -\ifx\do@@ammenuposition\undefined - \let\do@@ammenuposition\gobbleoneargument % hook for positional thingies -\fi - -\setvalue{\??am\s!do\v!right }{\@@amvbox{\dodummypageskip\v!right }\rightedgewidth} -\setvalue{\??am\s!do\v!left }{\@@amvbox{\dodummypageskip\v!left }\leftedgewidth } -\setvalue{\??am\s!do\v!top }{\@@amhbox{\dodummypageskip\v!top }\topheight } -\setvalue{\??am\s!do\v!bottom}{\@@amhbox{\dodummypageskip\v!bottom}\bottomheight } - -\def\dointeractionmenu#1#2% - {\getvalue{\??am\s!do\getvalue{\??am#1\c!location}}{#1}{#2}} - -\unexpanded\def\interactionmenu[#1]% - {\getvalue{\??am\c!menu#1}} - -\def\horizontalinteractionmenu#1#2#3#4% - {\ifdim#2>\zeropoint % new - \scratchdimen\zeropoint - \setbox\scratchbox\hbox - {\def\docommand##1% - {\doifnotvalue{\??am##1\c!state}\v!none - {\hskip\scratchdimen - \setbox2\hbox to #2 - {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% - \doifelsevalue{\??am##1\c!distance}\v!overlay - {\scratchdimen\zeropoint - \wd2\zeropoint}% - {\scratchdimen\getvalue{\??am##1\c!distance}}% - \box2}}% - \startinteraction - \processcommacommand[\getvalue{\??am#1}]\docommand - \stopinteraction}% - \wd\scratchbox#2\relax - \box\scratchbox - \fi} - -\def\verticalinteractionmenu#1#2#3#4% - {\ifdim#2>\zeropoint % new - \scratchdimen\zeropoint - \setbox\scratchbox\vbox - {\def\docommand##1% - {\doifnotvalue{\??am##1\c!state}\v!none - {\vskip\scratchdimen - \setbox2\vbox to #2 - {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% - \doifelsevalue{\??am##1\c!distance}\v!overlay - {\scratchdimen\zeropoint - \offinterlineskip - \dp2\zeropoint - \ht2\zeropoint}% - {\scratchdimen\getvalue{\??am##1\c!distance}}% - \box2}}% - \startinteraction - \processcommacommand[\getvalue{\??am#1}]\docommand - \stopinteraction}% - \ht\scratchbox#2\relax - \dp\scratchbox\zeropoint - \box\scratchbox - \fi} - -\letvalue{\??am\v!left }\empty -\letvalue{\??am\v!right}\empty -\letvalue{\??am\v!top }\empty -\letvalue{\??am\v!bottom }\empty - -% todo : \defineinteractionmenuclass - -\def\interactionmenus[#1]% - {\iflocation - \getvalue{\??am\??am\c!menu#1}% - \else - \dodummypageskip{#1}% - \fi} - -\setvalue{\??am\??am\c!menu\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth \c!left \c!right} -\setvalue{\??am\??am\c!menu\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth\c!left \c!right} -\setvalue{\??am\??am\c!menu\v!top }{\verticalinteractionmenu \v!top \topheight \c!before\c!after} -\setvalue{\??am\??am\c!menu\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight \c!before\c!after} - -% this can be implemented with the following command (which -% is new, undocumented, experimental, untested, etc etc) - -\def\defineinteractionmenuclass - {\dodoubleargument\dodefineinteractionmenuclass} - -\def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri - {\doifelse{#2}\v!vertical - {\setvalue{\??am\??am\c!menu#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}\c!before\c!after}} - {\setvalue{\??am\??am\c!menu#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}\c!left\c!right }}} - -% \setupinteraction[menu=on,state=start] -% -% \defineinteractionmenuclass[test] [vertical] -% \defineinteractionmenuclass[another][horizontal] -% -% \defineinteractionmenu[test] [left][state=start,width=4cm] -% \defineinteractionmenu[another][top] [state=start,height=1cm] -% -% \startinteractionmenu[test] -% \but [firstpage] test-a \\ -% \but [nextpage] test-b \\ -% \stopinteractionmenu -% -% \startinteractionmenu[another] -% \but [firstpage] test-a \\ -% \but [nextpage] test-b \\ -% \stopinteractionmenu -% -% \setupheadertexts[{\interactionmenu[another]}] -% -% \starttext -% -% test \interactionmenu[test] \page -% test \interactionmenu[test] \page -% -% \stoptext - -%D This can save complicated menu macros when one want to -%D keep control over parts of a menu (i.e.\ turn them on and -%D off). We could have achieved something similar with modes. - -\def\local@@ambox#1#2#3#4% don't change skipping, this one works! - {\bgroup - \testinteractionmenu{#3}% - \iflocationmenupermitted - \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after - \else - #1\relax - \fi - \egroup} - -\def\includemenu[#1]% - {\doifvalue{\??am#1\c!state}\v!local - {\bgroup - \letvalue{\??am#1\c!state}\v!start - \let\@@amvbox\local@@ambox - \let\@@amhbox\local@@ambox - \getvalue{\??am\c!menu#1}% - \egroup}} - -%D We also need an explicit position control some day. I'll -%D do that when I need it. [The stacking order.] - -\newif\ifextendedmenu - -% [name] [location] -% [name] [location] [pars] - -\def\defineinteractionmenu - {\dotripleempty\dodefineinteractionmenu} - -\def\dodefineinteractionmenu[#1][#2][#3]% - {% main settings - \letvalue{\??am\c!menu#1}\empty - \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}% - \presetlocalframed[\??am#1]% - % register location - \expanded{\addtocommalist{#1}\@EA\noexpand\csname\??am#2\endcsname}% - % inherit settings - \doifnot{#1}{#2} - {\copyparameters[\??am#1][\??am#2] - [\c!left,\c!middle,\c!right,\c!before,\c!after,\c!inbetween,% - \c!width,\c!height,\c!distance,\c!offset,% - \c!frame,\c!framecolor,\c!rulethickness,% - \c!background,\c!backgroundcolor,\c!backgroundscreen,% - \c!style,\c!color,\c!contrastcolor,\c!samepage,\c!unknownreference,% - \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]}% - % additional settings - \getparameters[\??am#1][\c!location=#2,\c!obstruction=,#3]} - -\def\setupinteractionmenu - {\dodoubleargument\dosetupinteractionmenu} - -\def\dosetupinteractionmenu[#1][#2]% - {\def\docommand##1{\getparameters[\??am##1][#2]}% - \processcommalist[#1]\docommand} - -\expandafter\chardef\csname\??am\??am\v!yes \endcsname\zerocount -\expandafter\chardef\csname\??am\??am\v!empty\endcsname\plusone -\expandafter\chardef\csname\??am\??am\v!no \endcsname\plustwo -\expandafter\chardef\csname\??am\??am\v!none \endcsname\plusthree -\expandafter\chardef\csname\??am\??am \endcsname\plusone % default - -\processbetween{\v!interactionmenu}\dostartinteractionmenu - -\def\dostartinteractionmenu#1% - {\dodostartinteractionmenu#1\dodostopinteractionmenu} - -\def\dodostartinteractionmenu[#1]#2\dodostopinteractionmenu - {\setvalue{\??am\c!menu#1}{\extendedmenutrue\dointeractionmenu{#1}{#2}}} - -\def\resetinteractionmenu[#1]% - {\letvalue{\??am\c!menu#1}\empty} - -\def\dodomenulistelement#1#2#3#4#5#6#7% - {\setbox0=\hbox - {\let\gotolocation\gobbleoneargument % hack to catch last [] - %\locationclickfalse % ipv ^ - \docheckrealreferencepage{#7}% - \setlocationboxyes - {\??am#1}% % needed ! - []% no settings - {\limitatetext{#5}{\getvalue{\??li#2\c!maxwidth}}{\unknown}}% % needed ! - []}% normally the destination, catch by gobble - \@@amboxcommand\do@@amposition{#1}{#7}% beware, we pass the pagenumber - {\ignorespaces\linklisttoelement{#3}{#6}{#7}{\box0}\unskip}\\} - -% \scherm moet worden als \page - -\def\screen - {\dosingleempty\doscreen} - -\def\doscreen[#1]% - {\iflocation\page[#1]\fi} - -\unexpanded\def\menubutton - {\dodoubleempty\domenubutton} - -\def\domenubutton[#1]% - {\iffirstargument - \ifsecondargument - \@EAEAEA\domenubuttonB - \else - \doifassignmentelse{#1} - {\@EAEAEA\domenubuttonC} - {\@EAEAEA\domenubuttonD}% - \fi - \else - \@EA\domenubuttonA - \fi[#1]} - -\def\domenubuttonA[#1][#2]#3[#4]% normal button, no parameters - {\bgroup - %\locationdummytrue - \setlocationbox\??bt[]{#3}[#4]% - \egroup} - -\def\domenubuttonB[#1][#2]#3[#4]% menu button, with parameters - {\bgroup - %\locationdummytrue - \setlocationbox{\??am#1}[#2]{#3}[#4]% - \egroup} - -\def\domenubuttonC[#1][#2]#3[#4]% normal button, with parameters - {\bgroup - %\locationdummytrue - \setlocationbox\??bt[#1]{#3}[#4]% - \egroup} - -\def\domenubuttonD[#1][#2]#3[#4]% menu button, no parameters - {\bgroup - %\locationdummytrue - \setlocationbox{\??am#1}[]{#3}[#4]% - \egroup} - -\def\menubox - {\dodoubleempty\domenubox} - -\def\domenubox[#1][#2]#3% - {\bgroup - \let\setlocationbox\setlocationboxraw - \domenubutton[#1][#2]#3[]% - \egroup} - -% Hier volgen de synchronisatiemacro's: - -\def\syncprefix{sync} - -%def\syncmarker{syncmark} -%\definemarking[\syncmarker] -%\setupmarking[\syncmarker][\c!expansie=\v!ja] - -\newmark\syncmarker - -\newcounter\synccounter - -\newif\ifsynchronisation - -\def\startsynchronization% - {\iflocation\ifsynchronisation - \doglobal\increment\synccounter - \fi\fi} - -\def\stopsynchronization% - {\iflocation\ifsynchronisation - %\thisisdestination{\syncprefix:\synccounter}% - \pagereference[\syncprefix:\synccounter]% - \ifvmode - \@EA\setmark\@EA\syncmarker\@EA{\synccounter} % \marking[\syncmarker]{\synccounter}% - \else - \showmessage\m!interactions4\synccounter - \fi - \fi\fi} - -\def\synchronize% - {\startsynchronization - \stopsynchronization} - -\def\dosetupsynchronization[#1]% - {\getparameters[\??sy][#1]% - \doifelse\@@systate\v!start - \synchronisationtrue - \synchronisationfalse} - -\def\setupsynchronization - {\dosingleargument\dosetupsynchronization} - -\def\definesynchronization - {\dosingleargument\dodefinesynchronization} - -\def\setupsynchronizationbar - {\dodoubleargument\getparameters[\??ba]} - -\presetlocalframed[\??ba] - -\setvalue{synchronisatie\v!page}[#1]% - {\bgroup - %\setupinteraction[\c!width=\!!zeropoint]% - \setinteractionparameter\c!width\!!zeropoint - \setbox0\hbox - {\localframed[\??ba][]{\dolocationattributes\??ba\c!style\c!color{\strut\@@batext}}}% - \dontcomplain - \def\atthebottom - {\leaders\hrule\!!depth1ex\!!height-.5ex\hfil}% - \def\atthetop##1##2##3% - {\dimen0=\wd0 - \divide\dimen0 3 - \multiply\dimen0 ##2\relax - \dimen2=.25em % brrr - \advance\dimen0 -##3\dimen2 - %\gotodestination - % {}{#1}{\syncprefix:##1}{} - % {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}}% - \gotobox - {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}% - [#1::\syncprefix:##1]}% - \hbox - {\def\check##1##2% - {\edef##2{0##1\syncmarker}% - \ifnum0##2=0 \def##2{1}\fi}% - \check\gettopmark\top - \check\getfirstmark\first - \check\getbotmark\bot - \setbox2\hbox to \wd0 - {\ifnum\top=\first\relax - \ifnum\first=\bot\relax - \atthetop\first30\relax - \else - \atthetop\first21\hss\atthetop\bot11\relax - \fi - \else - \ifnum\first=\bot\relax - \atthetop\top11\hss\atthetop\first21\relax - \else - \atthetop\top11\hss\atthetop\first11\hss\atthetop\bot11\relax - \fi - \fi}% - \wd2=\zeropoint\box2 - \box0\relax}% - \egroup} - -\setvalue{synchronisatie\v!local}[#1]% - {\bgroup - %\setupinteraction[\c!width=\!!zeropoint]% - \setinteractionparameter\c!width\!!zeropoint - \def\blackrule{\hbox{\vrule\!!height.5em\!!width.5em}}% - %\gotodestination - % {}{##1}{\syncprefix:#1}{0} - % {\color[\locationcolor\@@bacolor]{\blackrule}}% - \gotobox % - {\color[\locationcolor\@@bacolor]{\blackrule}}% - [#1::\syncprefix:\synccounter]% - \egroup} - -\def\synchronizationbar[#1][#2]% - {\iflocation\ifsynchronisation - \bgroup - \setupsynchronizationbar - [\c!text=\getvalue{doc:des:#1},#2]% - \getvalue{synchronisatie\@@baalternative}[#1]% - \egroup - \fi\fi} - -% A nice application of glue. All this code will be rewritten and -% generalized. - -\newbox\interactionbarbox - -\newif\ifbarsymbol - -\def\dogotosomepage#1#2#3% nog checken ! - {\checkreferences % nodig ?? - \hbox - {\iflocation - \ifnum#3=\realpageno - #2% - \else - \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% - \fi - \else - #2% - \fi}} - -\def\dogotosomecontrastpage#1#2#3% nog checken, may replace previous - {\checkreferences % nodig ?? - \hbox - {\iflocation - \ifnum#3=\realpageno - \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!contrastcolor}{#2}}% - \else - \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% - \fi - \else - #2% - \fi}} - -\presetlocalframed[\??ib] - -\def\interactionbara % we need better control over contrastcolor - {\iflocation % maybe just use gotopage and set colors - \bgroup - \setinteractionparameter\c!width\zeropoint - \setupblackrules[\c!height=\v!max,\c!depth=\v!max]% - \!!widthb\dimexpr\@@ibwidth-2.75\emwidth\relax - \!!widtha\dimexpr\!!widthb/\lastpage\relax - \bgroup - \advance\realpageno\minusone - \ifvoid\interactionbarbox - \bgroup - \processaction - [\@@ibstep] - [ \v!small=>\scratchdimen.25\emwidth, - \v!medium=>\scratchdimen.5\emwidth, - \v!big=>\scratchdimen\emwidth, - \s!unknown=>\scratchdimen\!!widtha]% - \ifdim\!!widtha<\scratchdimen\relax - \!!counta\numexpr\scratchdimen/\!!widtha\relax - \else - \!!counta\@@ibstep\relax - \fi - \!!widtha\!!counta\!!widtha - \setbox\scratchbox\hbox{\blackrule[\c!width=\!!widtha,\c!color=middlegray]}% color here, else no mkiv - \global\setbox\interactionbarbox\hbox to \!!widthb - {\hss - \dostepwiserecurse\plusone\lastpage\!!counta - {\gotorealpage\empty\empty\recurselevel{\copy\scratchbox}}% - \hss}% - \global\wd\interactionbarbox\zeropoint - \egroup - \fi - \egroup - \noindent - \strut - \hbox to \@@ibwidth - {\dontcomplain - \setupblackrules[\c!width=\emwidth]% - \dogotosomecontrastpage\??ib\blackrule\firstpage - \hss - \copy\interactionbarbox - \hbox to \!!widthb - {\ifdim\!!widtha<\emwidth - \!!widtha\emwidth - \fi - \setupblackrules[\c!width=\!!widtha]% - \ifnum\realpageno>\plusone - \!!counta\numexpr\realpageno-\plustwo\relax - \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow - \dogotosomepage\??ib\blackrule\prevpage - \fi - \dogotosomecontrastpage\??ib{\blackrule[\c!width=.5em]}\realpageno - \ifnum\realpageno<\lastpage\relax - \dogotosomepage\??ib\blackrule\nextpage - \!!counta\numexpr\lastpage-\realpageno-\plusone\relax - \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow - \fi}% - \hss - \dogotosomecontrastpage\??ib\blackrule\lastpage}% - \egroup - \fi} - -\def\interactionbarb - {\ifnum\lastpage>\firstpage\relax - \interactionbuttons[\v!firstpage,\v!previouspage,\v!nextpage,\v!lastpage]% - \fi} - -\def\interactionbarc - {\iflocation - \ifnum\lastpage>\plusone - \hbox to \@@ibwidth - {\setupblackrules[\c!height=\@@ibheight,\c!depth=\@@ibdepth]% - \scratchdimen\dimexpr(\@@ibwidth-4\emwidth)/\numexpr\lastpage+\minusone\relax\relax - \!!widtha\numexpr\realpageno+\minusone\relax\scratchdimen - \!!widthb\numexpr\lastpage-\realpageno\relax\scratchdimen - \startcolor[\locationcolor\@@ibcolor]% - \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\firstpage - \hss - \dogotosomepage\empty{\blackrule[\c!width=\!!widtha]}\prevpage - \color[\@@ibcontrastcolor]{\blackrule[\c!width=\emwidth]}% - \dogotosomepage\empty{\blackrule[\c!width=\!!widthb]}\nextpage - \hss - \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\lastpage - \stopcolor}% - \fi - \fi} - -\def\interactionbard - {\iflocation\ifshowingsubpage - \ifnum\nofsubpages>\plusone - \hbox \bgroup - \setinteractionparameter\c!width\!!zeropoint - \ifbarsymbol - \setupsymbolset[\@@iasymbolset]% - \def\dogotox##1% - {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi]}}% - \else - \def\dogotox##1% - {\hbox{\vrule\!!height\@@ibheight\!!depth \@@ibdepth\!!width \@@ibwidth}}% - \fi - \dostepwiserecurse\plusone\nofsubpages\plusone - {\bgroup - \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax - \ifnum\scratchcounter<\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter - \else\ifnum\scratchcounter=\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter - \else - \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter - \fi\fi - \egroup - \hskip\@@ibdistance}% - \unskip % not needed - \egroup - \fi - \fi\fi} - -\def\interactionbare% KAN WORDEN GECOMBINEERD MET D - {\iflocation\ifshowingsubpage - \ifnum\nofsubpages>\plusone - \bgroup - \!!widthb\dimexpr\nofsubpages\dimexpr\@@ibdistance\relax-\@@ibdistance\relax % (n-1) - \!!widtha\dimexpr(\@@ibwidth-\!!widthb)/\nofsubpages\relax - \ifdim\!!widtha<\@@ibdistance\relax - \interactionbarf - \else - \setinteractionparameter\c!width\!!zeropoint - \noindent - \hbox to \@@ibwidth - \bgroup - \ifbarsymbol - \setupsymbolset[\@@iasymbolset]% - \def\dogotox##1% - {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi}}% - \else - \def\dogotox##1% - {\hbox{\vrule\!!height\@@ibheight\!!depth\@@ibdepth\!!width\!!widtha}}% - \fi - \dostepwiserecurse\plusone\nofsubpages\plusone - {\bgroup - \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax - \ifnum\scratchcounter<\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter - \else\ifnum\scratchcounter=\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter - \else - \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter - \fi\fi - \egroup - \hss}% - \unskip - \egroup - \fi - \egroup - \fi - \fi\fi} - -\def\interactionbarf % !! KAN WORDEN GECOMBINEERD MET D !! - {\iflocation\ifshowingsubpage - \ifnum\nofsubpages>\plusone - \setinteractionparameter\c!width\!!zeropoint - \noindent - \hbox to \@@ibwidth - \bgroup - \!!countb\zerocount - \loop % todo: \doloop - \advance\!!countb \plusone - %\!!countc\nofsubpages \divide\!!countc \!!countb \advance\!!countc \plusone - \!!countc\numexpr(\nofsubpages/\!!countb)+\plusone\relax % rounding - \!!widthb\@@ibdistance - \multiply\!!widthb \!!countc - \advance\!!widthb -\@@ibdistance - \!!widtha\@@ibwidth - \advance\!!widtha -\!!widthb - \divide\!!widtha \!!countc - \ifdim\!!widtha<\@@ibdistance\relax - \repeat - \ifnum\!!countc>\plusone - % this is not that well tested - \advance\!!countc \minustwo - \!!widtha-\@@ibdistance - \!!widtha\!!countc\!!widtha - \advance\!!widtha \@@ibwidth - \advance\!!countc \plusone - \divide\!!widtha \!!countc - \fi - \ifbarsymbol - \setupsymbolset[\@@iasymbolset]% - \def\dogotox##1% - {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!somewhere\or\v!somewhere\or\v!next\fi}}% - \else - \def\dogotox##1% - {\hbox - {\!!heighta\@@ibheight - \!!deptha\@@ibdepth - \ifcase##1\relax - \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha - \or - \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha - \or - \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha - \or - \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha - \or - \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha - \fi}}% - \fi - \!!countc\numexpr\realpageno-\plustwo\relax - \!!countd\numexpr\realpageno+\plustwo\relax - \ifnum\!!countc<\plusone \!!countc\plusone \fi - \!!countf\zerocount - \dostepwiserecurse\firstsubpage\lastsubpage\plusone - {\!!doneafalse - \advance\!!countf \plusone - \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi - \ifnum\recurselevel=\lastsubpage\relax \!!doneatrue \fi - \if!!donea - \ifnum\recurselevel<\realpageno - \dogotosomecontrastpage\??ib{\dogotox0}\recurselevel - \else\ifnum\recurselevel>\realpageno - \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel - \else - \dogotosomecontrastpage\??ib{\dogotox4}\recurselevel - \fi\fi - \hss - \!!countf\zerocount - \else\ifnum\!!countf=\!!countb - \ifnum\recurselevel<\realpageno - \dogotosomecontrastpage\??ib{\dogotox1}\recurselevel - \else\ifnum\recurselevel>\realpageno - \dogotosomecontrastpage\??ib{\dogotox3}\recurselevel - \else - \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel - \fi\fi - \hss - \!!countf\zerocount - \fi\fi}% - \unskip - \egroup - \fi - \fi\fi} - -\def\interactionbarg - {\ifnum\lastsubpage>\firstsubpage\relax - \interactionbuttons[\v!firstsubpage,\v!previoussubpage,\v!nextsubpage,\v!lastsubpage]% - \fi} - -\def\checkinteractionbar#1#2#3% - {\ifdim\@@ibwidth=\zeropoint\def\@@ibwidth{#1}\fi - \doifnothing\@@ibheight{\def\@@ibheight{#2}}% - \doifnothing\@@ibdepth{\def\@@ibdepth{#3}}} - -\def\complexinteractionbar[#1]% - {\doifelse{#1}\v!reset - {\global\setbox\interactionbarbox\emptybox}% - {\bgroup - \iflocation - \checksubpages % goes wrong / loads \numberofpages too - \getparameters[\??ib][#1]% - \doif\@@ibstate\v!start - {\startinteraction - \processaction % breedte defaults ! - [\@@ibalternative] - [ c=>\checkinteractionbar{10em}\v!max \v!max, - d=>\checkinteractionbar{.5em}{.5em} \!!zeropoint, - e=>\checkinteractionbar{10em}{.5em} \!!zeropoint, - f=>\checkinteractionbar{10em}{.5em} \!!zeropoint, - \s!default=>\checkinteractionbar{10em}\v!broad\!!zeropoint, - \s!unknown=>\checkinteractionbar{10em}\v!broad\!!zeropoint]% - \doifelse\@@ibsymbol\v!yes - \barsymboltrue\barsymbolfalse - \getvalue{interactionbar\@@ibalternative}% - \stopinteraction}% - \fi - \egroup}} - -\definecomplexorsimpleempty\interactionbar - -\def\setupinteractionbar - {\dodoubleargument\getparameters[\??ib]} - -% Er wordt vooralsnog uitgegaan van een symmetrische -% start-stop situatie. - -\def\c!profiel!! {profiel:} % brrr -\def\c!versie!! {versie:} - -\def\dodefineprofile[#1][#2]% - {\iflocation - \def\dododefineprofile##1% - {\def\dodododefineprofile####1% - {\doifdefinedelse{\c!profiel!!####1}% - {\edef\!!stringa{\getvalue{\c!profiel!!####1}}% - \setevalue{\c!profiel!!####1}{\!!stringa,##1}}% - {\setevalue{\c!profiel!!####1}{##1}}}% - \processcommalist[#2]\dodododefineprofile}% - \processcommalist[#1]\dododefineprofile - \fi} - -\def\defineprofile% - {\dodoubleargument\dodefineprofile} - -% Als met \getpar wordt gewerkt, dan moet \next worden toegepast. - -% TZT initialisatie! - -\def\profilepage{} - -\let\dosetprofilepage\relax -\let\dogetprofilepage\relax - -\def\processprofile#1[#2]% - {\iflocation - \par % needed for pdftex - \bgroup - \dosetprofilepage - \dogetprofilepage - \def\processoneprofile##1##2% - {\ExpandBothAfter\doifinsetelse{##2}{\processedprofiles}% - {\doifsomething{##1}{(##1)}}% - {\addtocommalist{##2}\processedprofiles - ##1\relax - \ifcase#1\relax - \dobeginofprofile{##2}\paperwidth\paperheight\profilepage - \else - \doendofprofile - \fi}}% - \let\processedprofiles\empty - \def\doprocessprofile##1% - {\doifelse{\@@pfoption}{\v!test}% - {\goodbreak\blank\nobreak\tt[\space - \ifcase#1\v!start\else\v!stop\fi profiel\space ##1:\space - \doifdefinedelse{\c!profiel!!##1}% - {\def\dodoprocessprofile####1% - {\processoneprofile - {\goto{####1}[\c!profiel!!####1]}% - {####1}% - \space}% - \processcommacommand - [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}% - {- }% - ]\nobreak\blank}% - {\doifdefined{\c!profiel!!##1}% - {\def\dodoprocessprofile####1% - {\processoneprofile{}{####1}}% - \processcommacommand - [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}}}% - \processcommalist[#2]\doprocessprofile - \egroup - \par % needed for pdftex - \fi} - -\def\startprofile[#1]% - {\iflocation - \bgroup - \addtocommalist{#1}\actualprofile - \def\stopprofile% - {\processprofile1[#1]% - \egroup}% - \def\next{\processprofile0[#1]}% % \DoAfterFi \processprofile0[#1]% - \else % ^^^^^^^^^^ will be obsolete - \let\next\relax % since ugly and never used - \fi - \next} - -\let\stopprofile\relax - -\def\dofollowprofile#1[#2]% - {\iflocation - \hbox - {\dohandlegoto - {\dolocationattributes\??ia\c!style\c!color{#1\presetgoto}}% - {\dostartgotoprofile\buttonwidth\buttonheight{#2}}% - {\dostopgotoprofile}}% - \else - {#1}% - \fi} - -\def\followprofile#1[#2]% - {\iflocation - \doif\@@pfoption\v!test{\pagereference[\c!profiel!!#2]}% - \dofollowprofile{#1}[#2]% - \fi} - -\def\setupprofiles% - {\dodoubleargument\getparameters[\??pf]} - -% Als er nog geen tekst op de pagina staat, dan heeft het -% profiel betrekking op het bovenstaande, dus soms een vorige -% pagina! Vreemd, omdat PDF paginagewijs werkt. Gelukkig -% biedt /page een oplossing. Echter: expansie van een -% \special kan niet worden uitgesteld, zodat alleen een -% two-pass een oplossing vormt. Het onderstaande kan komen -% te vervallen als Acrobat dit ondervangt. Het scheelt een -% pass en een lijst. -% -% Er kunnen eventueel twee lijsten worden gebruikt. Een voor -% het begin (start) en een voor het eind (stop). Nu staat -% alles in een lijst. - -\definetwopasslist\s!profile - -\newcounter\currentprofile - -\def\dosetprofilepage% - {\doglobal\increment\currentprofile - \lazysavetwopassdata{\s!profile}{\currentprofile}{\noexpand\realfolio}} - -\def\dogetprofilepage% - {\gettwopassdata{\s!profile}% - \let\profilepage=\twopassdata} - -% is this stuff used at all - -\newcounter\versionlevel -\newcounter\versionorder - -\newif\ifrecentversion - -\let\oldatcharacter=@ - -\def\minimumversion{0} -\def\actualversion{0} - -\def\dosetupversions[#1]% - {\getparameters[\??ve][#1] - \stripcharacter.\from\@@venumber\to\minimumversion} - -\def\setupversions - {\dosingleargument\dosetupversions} - -\definetwopasslist\s!versionbegin -\definetwopasslist\s!versionend - -\let\actualprofile\empty - -\def\doresetpageversion - {\lazysavetwopassdata{\s!versionend}{\versionorder}{\noexpand\realfolio}} - -\def\dosetpageversion#1% - {\recentversiontrue - \doglobal\increment\versionorder\relax - \lazysavetwopassdata{\s!versionbegin}{\versionorder}{\noexpand\realfolio}% - \let\resetpageversion\doresetpageversion} - -\def\recentcontributions{} - -\def\checkrecentcontributions% - {\gettwopassdata{\s!versionbegin}% - \iftwopassdatafound - \!!counta\twopassdata\relax - \gettwopassdata{\s!versionend}% - \iftwopassdatafound - \!!countb\twopassdata\relax - \doglobal\increment\versionorder\relax - \savetwopassdata{\s!versionbegin}{\versionorder}{\the\!!counta}% - \savetwopassdata{\s!versionend }{\versionorder}{\the\!!countb}% - \dostepwiserecurse\!!counta\!!countb\plusone - {\@EA\doglobal\@EA\addtocommalist\@EA{\recurselevel}{\recentcontributions}}% - \let\next\checkrecentcontributions - \else - \let\next\relax - \fi - \else - \let\next\relax - \fi - \next} - -\def\docheckpageversion - {\ExpandBothAfter\doifinsetelse{\realfolio}{\recentcontributions} - {\pageselectedtrue}% - {\pageselectedfalse}} - -\let\setpageversion \gobbleoneargument -\let\resetpageversion \relax -\let\checkpageversion \relax - -\def\complexstartversion[#1]% - {\bgroup - \doifelsenothing\actualprofile - {\startprofile[#1]}% - {\startprofile[#1,\actualprofile]}% - \def\docomplexstartversie##1% - {\stripcharacter.\from##1\to\actualversion - \ifnum\versionlevel>\zerocount\relax - \ifnum\actualversion=\zerocount - \setpageversion\actualversion % unknown version - \else - \ifnum\actualversion<\minimumversion\relax - \relax % old version - \else - \setpageversion\actualversion % new version - \fi - \fi - \fi}% - \doglobal\increment\versionlevel\relax - \doifelsenothing{#1} - {\docomplexstartversie{0}}% - {\processcommalist[#1]\docomplexstartversie}} - -\definecomplexorsimpleempty\startversion - -\def\stopversion - {\stopprofile - \doglobal\decrement\versionlevel - \ifnum\versionlevel<\zerocount - \showmessage\m!versions1\empty - \else - \resetpageversion - \egroup - \fi} - -\def\markversion - {\showmessage\m!versions2\empty - \let\setpageversion\dosetpageversion - \let\resetpageversion\relax - \let\checkpageversion\relax} - -\def\selectversion - {\checkrecentcontributions - \showmessage\m!versions3\recentcontributions - \let\setpageversio\gobbleoneargument - \let\resetpageversion\relax - \let\checkpageversion\docheckpageversion} - -\def\dodefineversion[#1][#2]% - {\setvalue{\c!versie!!#1}{#2}% - \defineprofile[#1][#2]} - -\def\defineversion - {\dodoubleargument\dodefineversion} - -\def\followversion - {\followprofile} - -\def\followprofileversion#1[#2][#3]% - {\def\docommand##1% - {\defineprofile[#2#3][##1]}% - \processcommacommand[\getvalue{\c!versie!!#3}]\docommand - \followprofile#1[#2#3]} - -\newcounter\currentpagetransition - -\newif\ifrandomtransitions - -\def\setuppagetransitions% - {\dosingleempty\dosetuppagetransitions} - -\def\dosetuppagetransitions[#1]% - {\doifelsenothing{#1} - {\doifnot\@@scdelay\v!none - {\let\setpagetransition\setsomepagedelay}} - {\doifelse{#1}\v!start - {\doifnot\@@scdelay\v!none - {\let\setpagetransition\setsomepagedelay}} - {\doglobal\newcounter\currentpagetransition - \doifinsetelse{#1}{\v!reset,\v!stop} - {\let\setpagetransition\relax} - {\let\setpagetransition\setsomepagetransition - \doifinsetelse\v!random{#1} - {\randomtransitionstrue}{\randomtransitionsfalse}% - \edef\userpagetransitions{#1}% - \@EA\removefromcommalist\@EA{\v!random}\userpagetransitions - \ifx\userpagetransitions\empty - \let\userpagetransitions\pagetransitions - \fi}}}} - -\def\setsomepagedelay - {\expanded{\dosetpagetransition{0}{\@@scdelay}}} - -\def\setsomepagetransition - {\iflocation - \ifrandomtransitions - \expanded{\getcommalistsize[\userpagetransitions]}% - \getrandomnumber\currentpagetransition1\commalistsize - \else - \doglobal\increment\currentpagetransition - \fi - \expanded{\getfromcommalist[\userpagetransitions][\currentpagetransition]}% - \doifnumberelse\commalistelement - {\expanded{\getfromcommalist[\pagetransitions][\commalistelement]}} - {}% - \ifx\commalistelement\empty - \doglobal\newcounter\currentpagetransition - \setsomepagetransition - \else - \doifelse\@@scdelay\v!none - {\expanded{\dosetpagetransition{\commalistelement}{0}}} - {\expanded{\dosetpagetransition{\commalistelement}{\@@scdelay}}}% - \fi - \fi} - -\prependtoks \setpagetransition \to \everyshipout - -% temporary here - -%D \startbuffer -%D \dorecurse{10} -%D {\horizontalpositionbar -%D \pos\recurselevel \min1 \max10 -%D \token\framed{\recurselevel}% -%D \\} -%D -%D \hbox to 15em -%D {\hss -%D \dorecurse{10} -%D {\verticalpositionbar\pos\recurselevel\min1\max10\token\blackrule\\ -%D \hss}} -%D \stopbuffer - -\def\horizontalpositionbar\pos#1\min#2\max#3\token#4\\% - {\hbox to \hsize - {\hskip\zeropoint\!!plus #1\!!fill - \hskip\zeropoint\!!plus-#2\!!fill - #4\relax - \hskip\zeropoint\!!plus #3\!!fill - \hskip\zeropoint\!!plus-#1\!!fill}} - -\def\verticalpositionbar\pos#1\min#2\max#3\token#4\\% - {\vbox to \vsize - {\vskip\zeropoint\!!plus #1\!!fill - \vskip\zeropoint\!!plus-#2\!!fill - \hbox{#4}\relax - \vskip\zeropoint\!!plus #3\!!fill - \vskip\zeropoint\!!plus-#1\!!fill}} - -\def\horizontalgrowingbar\pos#1\min#2\max#3\height#4\depth#5\\% - {\hbox to \hsize - {\scratchcounter#1% - \advance\scratchcounter -#2% - \advance\scratchcounter \plusone - \leaders\vrule\hskip\zeropoint\!!plus \scratchcounter\!!fill - \vrule\!!width\zeropoint\!!height#4\!!depth#5% - \hskip\zeropoint\!!plus #3\!!fill - \hskip\zeropoint\!!plus-#1\!!fill}} - -\def\verticalgrowingbar\pos#1\min#2\max#3\width#4\\% - {\vbox to \vsize - {\scratchcounter#1% - \advance\scratchcounter -#2% - \advance\scratchcounter \plusone - \leaders\hrule\vskip\zeropoint\!!plus\scratchcounter\!!fill - \hrule\!!width#4\!!height\zeropoint\!!depth\zeropoint - \vskip\zeropoint\!!plus #3\!!fill - \vskip\zeropoint\!!plus-#1\!!fill}} - -\newbox\commentbox - -\def\doflushcommentanchors - {\let\next\relax % new - \processaction - [\@@cclocation] - [% \v!text=>\let\next\relax, % new - \v!inmargin=>\let\next\inmargin, % brr not the same as inleft|rightmargin - \v!leftedge=>\let\next\inleftedge, - \v!rightedge=>\let\next\inrightedge, - \v!leftmargin=>\let\next\inleftmargin, - \v!rightmargin=>\let\next\inrightmargin]% - \next{\hbox{\raise\strutht\box\commentbox}}} - -\def\flushcommentanchors % in everypar so indirect - {\ifvoid\commentbox\else \doflushcommentanchors \fi} - -\def\setupcomment - {\dodoubleargument\getparameters[\??cc]} - -\setvalue{\e!start\v!comment}% the dummy triple gobbles trailing spaces - {\dotripleempty\dostartcommentaar} - -\def\comment - {\dodoubleempty\docomment} - -\def\dodocomment#1% - {\!!widtha\@@ccwidth - \!!heighta\@@ccheight - \doifelse\@@ccoption\v!max - {\let\@@ccopen \!!plusone}{\let\@@ccopen \!!zerocount}% - \doifelse\@@ccoption\v!buffer - {\let\@@cccollect\!!plusone}{\let\@@cccollect\!!zerocount}% - \preparecommentvariables - \doinsertcomment - \@@cctitle\!!widtha\!!heighta - \@@cccolor\@@ccopen\@@ccsymbol - \@@cccollect{#1}} - -\def\preparecommentvariables % more will move here as with fields - {\let\@@DriverCommentLayer\@@cctextlayer} - -\def\dopreparecommentaar#1#2% - {\doifassignmentelse{#1} - {\getparameters[\??cc][#1]} - {\getparameters[\??cc][\c!title=#1,#2]}% - \obeylines - \doif\@@ccspace\v!yes\obeyspaces} - -\def\dostartcommentaar[#1][#2][#3]% - {\bgroup - \doifelse\@@ccstate\v!start - {\dopreparecommentaar{#1}{#2}% - \long\def\docommand##1% - {\global\setbox\commentbox\frozenhbox - {\hbox to \zeropoint - {\struttedbox{\tbox{\dodocomment{##1}}}\hss}% - \hskip\ifvoid\commentbox\@@ccmargin\else\@@ccdistance\fi - \box\commentbox}% - \egroup}}% - {\long\def\docommand##1% - {\egroup}}% - \grabuntil{\e!stop\v!comment}\docommand} - -\letvalue{\e!stop\v!comment}\relax % handy for \expanded{...} - -\def\docomment[#1][#2]#3% - {\doif\@@ccstate\v!start - {\hbox to \zeropoint - {\dopreparecommentaar{#1}{#2}% - \hskip-\@@ccmargin - \struttedbox{\tbox{\dodocomment{#3}}\hss}}}% - \ignorespaces} - -% \startcomment -% hello beautiful\\world -% \stopcomment -% -% \startcomment[hello] -% hello << \'e\'erste >> -% beautiful -% world -% \stopcomment -% -% \startcomment[hello][color=green,width=4cm,height=3cm] -% hello \leftguillemot\ \'e\'erste \rightguillemot\ -% beautiful -% world -% \stopcommentaar -% -% \startcomment[hello][color=green,width=4cm,height=3cm] -% hello \leftguillemot\ \'e\'erste \rightguillemot\ test -% -% beautiful -% -% world -% \stopcomment -% -% \startcomment[symbol=Balloon] -% Do we want this kind of rubish? And, why isn't this and -% some more features related to text annotations so poorly -% (actually not) documented? Anyhow, by providing this -% functionality we demonstrate that \pdfTeX\ can do it. By -% the way, it's funny that when in Acrobat we scale up the -% text, the symbols scale down. -% \stopcomment - -% \definesymbol [comment-normal][{\externalfigure[cow.pdf]}] -% \definesymbol [comment-down] [{\externalfigure[cow.pdf]}] -% -% \def\CowSymbol#1#2% -% {\scale -% [\c!height=#1] -% {\startMPcode -% loadfigure "koe.mp" number 1 ; -% refill currentpicture withcolor #2 ; -% \stopMPcode}} -% -% \definesymbol [comment-normal] -% [\CowSymbol{4ex}{red}] -% -% \definesymbol [comment-down] -% [\CowSymbol{4ex}{green}] -% -% \setupcomment -% [\c!symbol={comment-normal,comment-down}, -% \c!option=\v!buffer] -% -% \setupfootertexts[\placecomments] - -\def\placecomments - {\doflushcomments} - -% \setupinteraction[state=start] -% -% \useattachment[test.tex] -% \useattachment[whatever][test.tex] -% \useattachment[whatever][newname][test.tex] -% \useattachment[whatever][title][newname][test.tex] -% -% % \setupattachments[\c!symbol={symbol-normal,symbol-down}] -% -% \starttext \attachment[whatever] \stoptext - -\definesystemvariable{at} - -\def\useattachment - {\doquadrupleempty\douseattachment} - -\def\douseattachment[#1][#2][#3][#4]% tag title newname filename - {\iffourthargument - \setgvalue{\??at:#1}{{#2}{#3}{#4}}% tooltip kind of case - \else\ifthirdargument - \setgvalue{\??at:#1}{{#2}{#2}{#3}}% full path case - \else\ifsecondargument - \setgvalue{\??at:#1}{{#2}{#2}{#2}}% obvious case - \else - \setgvalue{\??at:#1}{{#1}{#1}{#1}}% worst case - \fi\fi\fi} - -\let\attachmenttitle\empty -\let\attachmentname \empty -\let\attachmentfile \empty - -\def\getattachmentdata[#1]% - {\edef\attachmenttitle{\filterfromvalue{\??at:#1}31}% description - \edef\attachmentname {\filterfromvalue{\??at:#1}32}% new name - \edef\attachmentfile {\filterfromvalue{\??at:#1}33}% original - \expandafter\splitstring\attachmentname\at.\to\!!stringa\and\!!stringb - \ifx\!!stringb\empty % no suffix, so we need to inherit it - \expandafter\splitstring\attachmentfile\at.\to\!!stringc\and\!!stringd - \edef\attachmentname{\attachmentname.\!!stringd}% - \fi} - -\def\attachment - {\dodoubleempty\doattachment} - -\def\doattachment[#1][#2]% currently title equals newname - {\iflocation - \ifsecondargument - \doifundefined{\??at:#2} - {\showmessage\m!interactions6{#2}% - \useattachment[#2]}% - \doif\@@atstate\v!start - {\bgroup - \getattachmentdata[#2]% - \doiffileelse\attachmentfile - {\setupattachments[#1]% - \presetattachmentvariables -\struttedbox{\tbox{% - \doattachfile - \attachmenttitle - {1em}\strutheight\strutdepth\@@atcolor\@@atsymbol - \attachmentname - \attachmentfile}% -}}% - {\showmessage\m!interactions5\attachmentfile}% - \egroup}% - \else\iffirstargument - \attachment[][#1]% - \fi\fi - \fi} - -\def\presetattachmentvariables - {\let\@@DriverAttachmentLayer\@@attextlayer} - -\def\setupattachments - {\dodoubleempty\getparameters[\??at]} - -\setupattachments - [\c!state=\v!start, - \c!color=\@@iacolor, - \c!textlayer=, - \c!symbol=] - -% jammer, tussen/midden had erin gemoeten; \c!commando toevoegen - -\def\registermenucommand#1% - {{\textonly\noindent#1\space}} % no math switching - -\def\doregistermenubuttons[#1][#2]% [menu id] [register] - {\bgroup - \ifsecondargument - \setupinteractionmenu - [#1][\c!unknownreference=\v!yes,\c!samepage=\v!yes]% - \def\docommand##1% - {\registermenucommand{\menubutton[#1]{##1}[#2:##1]}}% - \else - \def\docommand##1% - {\registermenucommand - {\button - [\c!unknownreference=\v!yes,\c!samepage=\v!yes] - {##1}[#1:##1]}}% - \fi - \handletokens abcdefghijklmnopqrstuvwxyz\with\docommand % moet anders - \egroup} - -\def\registermenubuttons - {\dodoubleempty\doregistermenubuttons} - -\stelkoppelingenin - [\c!distance=.25em, - \c!width=\v!fit, - \c!location=\v!low, - \c!color=\@@iacolor, - \c!frame=\v!off, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=] - -\defineinteractionmenu - [\v!right] - [\v!right] - [\c!before=, - \c!after=\vfil, - \c!inbetween=\blank, - \c!distance=\bodyfontsize, % 12pt - \c!left=\hss, - \c!right=\hss, - \c!width=\rightedgewidth, - \c!height=\v!broad] - -\defineinteractionmenu - [\v!left] - [\v!left] - [\c!before=, - \c!after=\vfil, - \c!inbetween=\blank, - \c!distance=\bodyfontsize, % 12pt - \c!left=\hss, - \c!right=\hss, - \c!width=\leftedgewidth, - \c!height=\v!broad] - -\defineinteractionmenu - [\v!bottom] - [\v!bottom] - [\c!before=\vss, - \c!after=\vss, - \c!middle=\hfil, - \c!distance=\bodyfontsize, % 12pt - \c!width=\v!fit, - \c!height=\v!broad] - -\defineinteractionmenu - [\v!top] - [\v!top] - [\c!before=\vss, - \c!after=\vss, - \c!middle=\hfil, - \c!distance=\bodyfontsize, % 12pt - \c!width=\v!fit, - \c!height=\v!broad] - -\setupinteractionmenu - [\v!left,\v!right,\v!top,\v!bottom] - [\c!offset=.25em, - \c!position=\v!no, - \c!frame=\v!on, - \c!background=, - \c!backgroundcolor=, - \c!backgroundscreen=\@@rsscreen, - \c!style=\@@iastyle, - \c!color=\@@iacolor, - \c!contrastcolor=\@@iacontrastcolor, - \c!state=\v!start, - \c!samepage=\v!yes, - \c!unknownreference=\v!empty, - \c!topoffset=\!!zeropoint, - \c!bottomoffset=\!!zeropoint, - \c!leftoffset=\!!zeropoint, - \c!rightoffset=\!!zeropoint] - -\def\placeleftedgetextblock % Is \hss/\hsize really needed here? - {\hbox to \leftedgewidth % (check outer level and settings) - {\hsize\leftedgewidth\hss\interactionmenus[\v!left]}} - -\def\placerightedgetextblock % Is \hss/\hsize really needed here? - {\hbox to \rightedgewidth % (check outer level and settings) - {\hsize\rightedgewidth\interactionmenus[\v!right]\hss}} - -\def\placetoptextblock - {\vbox to \topheight - {\vsize\topheight - \csname\??tk\v!top\c!before\endcsname - \interactionmenus[\v!top]% - \csname\??tk\v!top\c!after\endcsname - \kern\zeropoint}} - -\def\placebottomtextblock - {\vbox to \bottomheight - {\vsize\bottomheight - \csname\??tk\v!bottom\c!before\endcsname - \interactionmenus[\v!bottom]% - \csname\??tk\v!bottom\c!after\endcsname - \kern\zeropoint}} - -\ifx\leftedgetextcontent\undefined \else - - \appendtoks \placeleftedgetextblock \hskip-\leftedgewidth \to \leftedgetextcontent - \appendtoks \placerightedgetextblock \hskip-\rightedgewidth \to \rightedgetextcontent - \appendtoks \placetoptextblock \vskip-\topheight \to \toptextcontent - \appendtoks \placebottomtextblock \vskip-\bottomheight \to \bottomtextcontent - -\fi - -\setupinteractionscreen - [\c!width=\printpaperwidth, - \c!height=\printpaperheight, - \c!horoffset=\!!zeropoint, - \c!veroffset=\!!zeropoint, - \c!backspace=\backspace, - \c!topspace=\topspace, - \c!option=\v!min, - \c!delay=\v!none] - -\setupbuttons - [\c!state=\v!start, - \c!width=\v!fit, - \c!height=\v!broad, - \c!offset=0.25em, - \c!frame=\v!on, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!style=\@@iastyle, - \c!color=\@@iacolor, - \c!contrastcolor=\@@iacontrastcolor, - \c!samepage=\v!yes, - \c!unknownreference=\v!yes] - -\setupinteractionbar - [\c!state=\v!start, - \c!alternative=a, - \c!symbol=\v!no, - \c!width=\rightedgewidth, - \c!height=, % these are taken care - \c!depth=, % of at calling time - \c!distance=.5em, % beter relateren aan breedte - \c!step=1, - \c!color=\@@iacolor, - \c!contrastcolor=\@@iacontrastcolor, - \c!frame=\v!on, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!samepage=\v!yes, - \c!unknownreference=\v!yes] - -\setupsynchronizationbar - [\c!alternative=\v!page, - \c!width=\rightedgewidth, - \c!style=\@@iastyle, - \c!color=\@@iacolor, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=] - -\setupsynchronization - [\c!state=\v!stop] - -\setupprofiles - [\c!option=] - -\setuppagetransitions - [\v!reset] - -\setupcomment - [\c!state=\v!start, - \c!margin=2.5em, - \c!distance=1em, - \c!width=.3\textwidth, - \c!height=.2\textheight, - \c!color=\@@iacolor, - \c!title=, - \c!space=\v!no, - \c!symbol=\v!normal, - \c!location=\v!inmargin, - \c!option=, - \c!textlayer=] - -\setupversions % beware, @ is made active here, - [\c!number=1, % therefore we set this one at the end - \c!style=\ss, - \c!color=] - -\protect \endinput diff --git a/tex/context/base/core-int.mkiv b/tex/context/base/core-int.mkiv deleted file mode 100644 index d02881801..000000000 --- a/tex/context/base/core-int.mkiv +++ /dev/null @@ -1,2036 +0,0 @@ -%D \module -%D [ file=core-int, -%D version=1995.01.01, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Interaction, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% evt interactionbaren runtime laden (scheelt 8K) - -%D Still to be done properly. - -\writestatus{loading}{ConTeXt Core Macros / Interaction} - -\unprotect - -% \expand vs \expanded - -% linked registers implementeren als een koppeling == mooier - -\presetlocalframed[\??lk] - -\newcounter\numberoflinks - -\def\stelkoppelingenin% - {\dodoubleargument\getparameters[\??lk]} - -\def\definieerkoppeling[#1]% % local loading ! - {\doifundefined{\s!link:#1:\s!list} - {\expanded{\definetwopasslist{\s!link:#1}}% - \expanded{\doloadtwopassdata{\s!link:#1}}% - \getfirsttwopassdata{\s!link:#1}% - \letgvalue{\s!link:#1:f}\twopassdata - \getlasttwopassdata{\s!link:#1}% - \letgvalue{\s!link:#1:l}\twopassdata - \letgvalue{\s!link:#1:s}\noftwopassitems - \gettwopassdata{\s!link:#1}% - \letgvalue{\s!link:#1:c}\twopassdata - \letgvalue{\s!link:#1:n}\twopassdata}} - -\def\koppeling[#1]#2% - {\bgroup - \definieerkoppeling[#1]% - \doglobal\increment\numberoflinks - \gettwopassdata{\s!link:#1}% - \edef\numberoflinks{0\getvalue{\s!link:#1:s}}% - \edef\firstlink {0\getvalue{\s!link:#1:f}}% - \edef\lastlink {0\getvalue{\s!link:#1:l}}% - \edef\currentlink {0\getvalue{\s!link:#1:n}}% - \edef\prevlink {0\getvalue{\s!link:#1:c}}% - \iftwopassdatafound - \edef\nextlink{0\twopassdata}% - \letgvalue{\s!link:#1:n}\nextlink - \letgvalue{\s!link:#1:c}\currentlink - \else - \edef\nextlink{0\getvalue{\s!link:#1:l}}% - \fi - \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% - \ifnum\noflinks<\plustwo - \locationfalse - \fi - \iflocation - \hbox - {\setinteractionparameter\c!width\!!zeropoint - \dogotosomepage\??lk\gotobegincharacter\firstlink\hss - \ifnum\noflinks>\plustwo - \hskip\@@lkdistance - \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss - \fi - \hskip\@@lkdistance - #2\relax - \hskip\@@lkdistance - \ifnum\noflinks>\plustwo - \dogotosomepage\??lk\goforwardcharacter\nextlink\hss - \hskip\@@lkdistance - \fi - \dogotosomepage\??lk\gotoendcharacter\lastlink}% - \else - \hbox{#2}% - \fi - \egroup} - -\def\definieerkoppeling[#1]% % local loading ! - {\doifundefined{\s!link:#1:\s!list} - {\expanded{\definetwopasslist{\s!link:#1}}% \expanded{\doloadtwopassdata{\s!link:#1}}% - \getfirsttwopassdata{\s!link:#1}% - \let\firstlink\twopassdata - \getlasttwopassdata{\s!link:#1}% - \let\lastlink\twopassdata - \let\noflinks\noftwopassitems - \gettwopassdata{\s!link:#1}% - \let\currentlink\twopassdata - \let\nextlink\twopassdata - \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}}} - -\def\koppeling[#1]#2% - {\bgroup - \definieerkoppeling[#1]% - \doglobal\increment\numberoflinks - \gettwopassdata{\s!link:#1}% - \def\next[##1:##2:##3:##4:##5]% - {\edef\firstlink {0##1}% - \edef\lastlink {0##2}% - \edef\noflinks {0##3}% - \edef\prevlink {0##4}% - \edef\currentlink{0##5}}% - \expanded{\next[\getvalue{\s!link:#1:}]}% - \edef\nextlink{0\iftwopassdatafound\twopassdata\else\lastlink\fi}% - \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}% - \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% - \ifnum\noflinks<\plustwo - \locationfalse - \fi - \iflocation - \hbox - {\setinteractionparameter\c!width\!!zeropoint - #2\relax - \hskip\@@lkdistance - \dogotosomepage\??lk\gotobegincharacter\firstlink\hss - \ifnum\noflinks>\plustwo - \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss - \fi - \ifnum\noflinks>\plustwo - \dogotosomepage\??lk\goforwardcharacter\nextlink\hss - \hskip\@@lkdistance - \fi - \dogotosomepage\??lk\gotoendcharacter\lastlink}% - \else - \hbox{#2}% - \fi - \egroup} - -\let\setupinteractionscreens\empty - -\def\docalculateinteractionscreen - {\doifelse\@@scwidth\v!fit - {\!!widtha\leftcombitotal - \ifdim\backspace>\!!widtha\ifdim\backspace>\zeropoint\relax - \advance\backspace -\!!widtha - \fi\fi - \advance\!!widtha\rightcombitotal - \advance\!!widtha 2\dimexpr\@@scbackspace+\@@schoroffset\relax} - {\doifelse\@@scwidth\v!max - {\!!widtha\printpaperwidth} - {\!!widtha\@@scwidth}}% - \doifelse\@@scheight\v!fit - {\!!heighta\dimexpr\topheight+\topdistance\relax - \ifdim\topspace>\!!heighta\ifdim\topspace>\zeropoint\relax - \advance\topspace -\!!heighta - \fi\fi - \advance\!!heighta \dimexpr\makeupheight+\bottomdistance+\bottomheight\relax - \advance\!!heighta 2\dimexpr\@@sctopspace+\@@scveroffset\relax} - {\doifelse\@@scheight\v!max - {\!!heighta\printpaperheight} - {\!!heighta\@@scheight}}% - \doif\@@scdelay\v!none{\let\@@scdelay\zerocountervalue}} - -% The macro is not to be changed; only the \@@ia-variables -% may be set! ConTeXt is the producer but we no longer -% mention the pragma site, since we don't want to be bothered -% with remarks about third party documents and/or associated -% with documents produced outside our control. - -\def\doprepareidentity % beware, we need to construct - {\let\!!stringa\@@iakeyword % an unexpanded space separated - \let\@@iakeyword\empty % list of keywords from a comma - \def\doprepareidentity##1% % separated one - {\ifx\@@iakeyword\empty - \appended\def\@@iakeyword{##1}% - \else - \appended\def\@@iakeyword{ ##1}% - \fi}% - \@EA\processcommalist\@EA[\!!stringa]\doprepareidentity - \global\let\doprepareidentity\relax} - -%D The Creator field is changed per 12/04/2006 due to user presure. This -%D means that I need to put my own status info someplace else. - -\def\initializeidentity - {\doprepareidentity - \dosetupidentity % no \expanded{..} will be done in special (else no pdfdoc) - {\@@iatitle}{\@@iasubtitle}{\@@iaauthor}% - {ConTeXt - \contextversion}% - {\@@iadate}{\@@iakeyword}% - \global\let\initializeidentity\relax} - -\appendtoks \initializeidentity \to \everyshipout - -\def\initializepaper - {\bgroup - \ifx\@@ppleft \empty - \ifx\@@ppright\empty - \ifx\@@pptop \empty - \ifx\@@ppbottom \empty - \ifx\@@pcstate\v!start - \locationfalse\fi\else - \locationfalse\fi\else - \locationfalse\fi\else - \locationfalse\fi\else - \locationfalse\fi - \iflocation % without screen settings - \egroup - \dosetuppaper\papersize\paperwidth\paperheight - \else - \egroup - \dosetuppaper\printpapersize\printpaperwidth\printpaperheight - \fi} - -\appendtoks \initializepaper \to \everyshipout - -\def\doinitializepaper - {\bgroup - \docalculateinteractionscreen - \ifdim\!!widtha>\paperwidth\ifdim\!!widtha>\zeropoint - \paperwidth\!!widtha - \fi\fi - \ifdim\!!heighta>\paperheight\ifdim\!!heighta>\zeropoint - \paperheight\!!heighta - \fi\fi - \dosetuppaper - {\printpapersize} - {\the\paperwidth} - {\the\paperheight}% - \egroup} - -\let\@@pcscreendata\empty - -\def\dosetupinteractionscreens % met a, b en \number - {\doifnot\@@pcstate\v!start\dodosetupinteractionscreens} - -\setvalue{\??sc\c!option\v!max }{1} % tzt share with driver -\setvalue{\??sc\c!option\v!bookmark }{2} % tzt share with driver -\setvalue{\??sc\c!option\v!fit }{3} % tzt share with driver -\setvalue{\??sc\c!option\v!doublesided}{4} % tzt share with driver - -\def\dodosetupinteractionscreens % met a, b en \number - {\bgroup - \docalculateinteractionscreen - \!!counte=0\getvalue{\??sc\c!option\@@scoption}\relax - % niet waterdicht - \doifnot{\the\!!widtha\the\!!heighta}\@@pcscreendata - {\xdef\@@pcscreendata{\the\!!widtha\the\!!heighta}% - \showmessage\m!interactions1{\withoutpt\the\!!widtha,\withoutpt\the\!!heighta}}% - % needs to be split: dimensions for each page - % and mode per document and only once ! - \dosetupscreen \backoffset\topoffset\!!widtha\!!heighta{\the\!!counte}% - \dosetupcropbox\backoffset\topoffset\!!widtha\!!heighta - \egroup} - -\def\dosetupinteractionscreen[#1]% - {\getparameters[\??sc][#1]% - \ifproductionrun - \let\initializepaper\doinitializepaper - \let\setupinteractionscreens\dosetupinteractionscreens - \fi} - -\appendtoks \setupinteractionscreens \to \everyfirstshipout % needed to get option=max etc working -\appendtoks \setupinteractionscreens \to \everyshipout % needed for page/screen dimensions - -\def\setupinteractionscreen - {\dosingleempty\dosetupinteractionscreen} - -% \startinteractionmenu[rechts] -% \but [eerste] eerste \\ -% \txt hello world \\ -% \but [tweede] tweede \\ -% \nop \\ -% \but [tweede] tweede \\ -% \rul whow \\ -% \but [tweede] tweede \\ -% \raw hello world \\ -% \but [tweede] tweede \\ -% \com \vfill \\ -% \but [derde] derde \\ -% \stopinteractionmenu - -\newif\iflocationmenupermitted - -\def\testinteractionmenu#1% - {\iflocation - \doifelse\@@iamenu\v!on - {\doifelsevalue{\??am#1\c!state}\v!start - {\global\locationmenupermittedtrue} - {\global\locationmenupermittedfalse}} - {\global\locationmenupermittedfalse}% - \else - \global\locationmenupermittedfalse - \fi} - -\def\dodisableinteractionmenu[#1][#2][#3]% - {\def\dododisableinteractionmenu##1% - {\doifelse{#3}{} - {\letvalue{\??am##1\c!obstruction}\empty} - {\edef\interactieblokkade{\getvalue{\??am##1\c!obstruction}} - \def\docommand####1{#1{####1}{\interactieblokkade}}% #1 = \remove or \add - \processcommalist[#3]\docommand - \setevalue{\??am##1\c!obstruction}{\interactieblokkade}}}% - \processcommalist[#2]\dododisableinteractionmenu} - -\def\disableinteractionmenu - {\dotripleempty\dodisableinteractionmenu[\addtocommalist]} - -\def\enableinteractionmenu - {\dotripleempty\dodisableinteractionmenu[\removefromcommalist]} - -% ja : kader/achtergrond met tekst -% leeg : kader/achtergrond maar geen tekst -% nee : alleen ruimte reserveren -% geen : helemaal weglaten - -\newif\iflocationdummy -\newif\ifskippedmenuitem - -\newif\iflocationempty -\newif\iflocationclick - -% ja : kader/achtergrond met tekst -% leeg : kader/achtergrond maar geen tekst -% nee : alleen ruimte reserveren -% geen : helemaal weglaten -% -% \setupinteractionmenu[right][samepage=yes, unknownreference=yes] -% \setupinteractionmenu[right][samepage=empty,unknownreference=empty] -% \setupinteractionmenu[right][samepage=no, unknownreference=no] -% \setupinteractionmenu[right][samepage=none, unknownreference=none] -% -% \startinteractionmenu[right] -% \but [firstpage] first \\ -% \but [lastpage] last \\ -% \but [somepage] crap \\ -% \stopinteractionmenu - -\def\dosetlocationboxcontent#1[#2]#3[#4]% - {\global\skippedmenuitemfalse - \setbox\locationbox\hbox - {\resetgoto % anders cyclische aanroep ! - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}}% - \iflocationclick - \hbox{\gotolocation{#4}{\box\locationbox}}% - \else - \hbox{\box\locationbox}% - \fi} - -\let\dosetlocationboxyes\dosetlocationboxcontent - -\def\dosetlocationboxempty#1[% - {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,} - -\def\dosetlocationboxno#1[% - {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,\c!frame=,\c!background=,} - -\def\dosetlocationboxnone#1[#2]#3[#4]% - {\global\skippedmenuitemtrue} - -\def\setlocationboxyes#1[#2]#3[#4]% - {\locationclicktrue - \setbox\locationbox\hbox - {\resetgoto % anders cyclische aanroep ! - \global\skippedmenuitemfalse - \gotolocation - {#4}% % needed - {\ifrealreferencepage - \ifcase\csname\??am\??am\csname#1\c!samepage\endcsname\endcsname\relax - \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \global\skippedmenuitemtrue - \fi - \else - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \fi}}% - \ifskippedmenuitem\else\box\locationbox\fi} - -\def\setlocationboxnop#1[#2]#3[#4]% - {\locationclickfalse - \setbox\locationbox\hbox - {\resetgoto % anders cyclische aanroep ! - \global\skippedmenuitemfalse - \ifcase\csname\??am\??am\csname#1\c!unknownreference\endcsname\endcsname\relax - \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% - \or - \global\skippedmenuitemtrue - \fi}% - \ifskippedmenuitem\else\box\locationbox\fi} - -\def\setlocationboxraw#1[#2]#3[#4]% - {\localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}} - -\def\setlocationbox#1[#2]#3[#4]% - {\bgroup % really needed ! - \edef\permittedreferences{\csname#1\c!obstruction\endcsname}% - \doifreferencepermittedelse{#4}% - {\setlocationboxyes{#1}[#2]{#3}[#4]}% - {\setlocationboxnop{#1}[#2]{#3}[#4]}% - \egroup} - -\def\setlocationnop#1[#2]#3% - {\localframed[#1][#2]{#3}} - -\def\executeamboxcommands#1#2#3#4#5% - {%\processaction - % [\getvalue{\??am#1\c!dummy}] - % [ \v!yes=>\chardef\handleunknownmenuitem=0\relax, - % \v!empty=>\chardef\handleunknownmenuitem=1\relax, - % \v!no=>\chardef\handleunknownmenuitem=2\relax]% - \getvalue{\??am#1#3}\relax - \setamboxcommands{#1}{#4}% - \ignorespaces#2\unskip - \getvalue{\??am#1#5}} - -\newcounter\currentamposition - -\newtoks\everysetmenucommands - -\def\setamboxcommands#1#2% - {\def\currentmenu{#1}% % kan nog eerder - \def\currentsubmenu{#2}% % ? ? - \doglobal\newcounter\currentamposition - \the\everysetmenucommands} - -\def\menu@@amboxcommand#1\\% - {\dontleavehmode - \bgroup - \ignorespaces#1\unskip\relax - \ifskippedmenuitem \else - \getvalue{\??am\currentmenu\currentsubmenu}% - \fi - \egroup - \ignorespaces} - -\appendtoks - \let\@@amboxcommand\menu@@amboxcommand -\to \everysetmenucommands - -\def\menu@raw[#1]#2\\% - {\@@amboxcommand\gotobox{\ignorespaces#2\unskip}[#1]\\}% - -\def\menu@but[#1]#2\\% - {\@@amboxcommand\do@@amposition\currentmenu{#1}{\setlocationbox{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}\\}% - -\def\menu@got[#1]#2\\% pas op! offset - {\@@amboxcommand\setlocationbox{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]\\}% - -\def\menu@nop#1\\% - {\@@amboxcommand\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]\\}% - -\def\menu@txt#1\\% - {\@@amboxcommand\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}\\}% - -\def\menu@rul#1\\% ook \do@@amposition ! - {\@@amboxcommand\localframed[\??am\currentmenu][]{\ignorespaces#1\unskip}\\}% - -\def\menu@com#1\\% - {\ignorespaces#1\unskip\ignorespaces}% - -\appendtoks - \let\raw\menu@raw - \let\but\menu@but - \let\got\menu@got - \let\nop\menu@nop - \let\txt\menu@txt - \let\rul\menu@rul - \let\com\menu@com -\to \everysetmenucommands - -\ifx\do@@amposition\undefined - \let\do@@amposition\gobbletwoarguments % hook for positional thingies -\fi - -\let\currentmenu\empty - -% beware : never change the concept of pbgoffset - -\def\menuparameter#1{\csname\??am\currentmenu#1\endcsname} - -\def\@@amhbox#1#2#3#4% - {\def\currentmenu{#3}% - \testinteractionmenu{#3}% - \iflocationmenupermitted - \bgroup - \showcomposition - \scratchdimen\dimexpr - \makeupwidth - +\pagebackgroundhoffset - +\pagebackgroundhoffset - -\menuparameter\c!leftoffset - -\menuparameter\c!rightoffset - \relax - \setbox\scratchbox\hbox to \scratchdimen - {\forgetall\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}% - \setbox\scratchbox\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}% - \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet) - \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax - \box\scratchbox - \egroup - \else - #1\relax - \fi} - -\def\@@amvbox#1#2#3#4% don't change skipping, this one works! - {\def\currentmenu{#3}% - \testinteractionmenu{#3}% - \iflocationmenupermitted - \bgroup - \showcomposition - \scratchdimen\dimexpr - \textheight - +\pagebackgroundvoffset - +\pagebackgroundvoffset - +\pagebackgrounddepth - -\menuparameter\c!topoffset - -\menuparameter\c!bottomoffset - \relax - \setbox\scratchbox\vbox to \scratchdimen - {\forgetall % Voor't geval de afstand - %\setupblank[\v!standard]% % (tijdelijk) is aangepast. - \restorestandardblank - \hsize#2\relax - \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}% - \setbox\scratchbox\vbox{\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}}% - \setbox\scratchbox\vbox - {\ht\scratchbox\zeropoint - \vskip\dimexpr-\pagebackgroundvoffset+\menuparameter\c!topoffset\relax - \box\scratchbox - \vskip\pagebackgroundvoffset}% overbodig - \ht\scratchbox\textheight - \wd\scratchbox#2\relax - \box\scratchbox - \egroup - \else - #1\relax - \fi} - -\ifx\do@@ammenuposition\undefined - \let\do@@ammenuposition\gobbleoneargument % hook for positional thingies -\fi - -\setvalue{\??am\s!do\v!right }{\@@amvbox{\dodummypageskip\v!right }\rightedgewidth} -\setvalue{\??am\s!do\v!left }{\@@amvbox{\dodummypageskip\v!left }\leftedgewidth } -\setvalue{\??am\s!do\v!top }{\@@amhbox{\dodummypageskip\v!top }\topheight } -\setvalue{\??am\s!do\v!bottom}{\@@amhbox{\dodummypageskip\v!bottom}\bottomheight } - -\def\dointeractionmenu#1#2% - {\getvalue{\??am\s!do\getvalue{\??am#1\c!location}}{#1}{#2}} - -\unexpanded\def\interactionmenu[#1]% - {\getvalue{\??am\c!menu#1}} - -\def\horizontalinteractionmenu#1#2#3#4% - {\ifdim#2>\zeropoint % new - \scratchdimen\zeropoint - \setbox\scratchbox\hbox - {\def\docommand##1% - {\doifnotvalue{\??am##1\c!state}\v!none - {\hskip\scratchdimen - \setbox2\hbox to #2 - {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% - \doifelsevalue{\??am##1\c!distance}\v!overlay - {\scratchdimen\zeropoint - \wd2\zeropoint}% - {\scratchdimen\getvalue{\??am##1\c!distance}}% - \box2}}% - \startinteraction - \processcommacommand[\getvalue{\??am#1}]\docommand - \stopinteraction}% - \wd\scratchbox#2\relax - \box\scratchbox - \fi} - -\def\verticalinteractionmenu#1#2#3#4% - {\ifdim#2>\zeropoint % new - \scratchdimen\zeropoint - \setbox\scratchbox\vbox - {\def\docommand##1% - {\doifnotvalue{\??am##1\c!state}\v!none - {\vskip\scratchdimen - \setbox2\vbox to #2 - {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% - \doifelsevalue{\??am##1\c!distance}\v!overlay - {\scratchdimen\zeropoint - \offinterlineskip - \dp2\zeropoint - \ht2\zeropoint}% - {\scratchdimen\getvalue{\??am##1\c!distance}}% - \box2}}% - \startinteraction - \processcommacommand[\getvalue{\??am#1}]\docommand - \stopinteraction}% - \ht\scratchbox#2\relax - \dp\scratchbox\zeropoint - \box\scratchbox - \fi} - -\letvalue{\??am\v!left }\empty -\letvalue{\??am\v!right}\empty -\letvalue{\??am\v!top }\empty -\letvalue{\??am\v!bottom }\empty - -% todo : \defineinteractionmenuclass - -\def\interactionmenus[#1]% - {\iflocation - \getvalue{\??am\??am\c!menu#1}% - \else - \dodummypageskip{#1}% - \fi} - -\setvalue{\??am\??am\c!menu\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth \c!left \c!right} -\setvalue{\??am\??am\c!menu\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth\c!left \c!right} -\setvalue{\??am\??am\c!menu\v!top }{\verticalinteractionmenu \v!top \topheight \c!before\c!after} -\setvalue{\??am\??am\c!menu\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight \c!before\c!after} - -% this can be implemented with the following command (which -% is new, undocumented, experimental, untested, etc etc) - -\def\defineinteractionmenuclass - {\dodoubleargument\dodefineinteractionmenuclass} - -\def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri - {\doifelse{#2}\v!vertical - {\setvalue{\??am\??am\c!menu#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}\c!before\c!after}} - {\setvalue{\??am\??am\c!menu#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}\c!left\c!right }}} - -% \setupinteraction[menu=on,state=start] -% -% \defineinteractionmenuclass[test] [vertical] -% \defineinteractionmenuclass[another][horizontal] -% -% \defineinteractionmenu[test] [left][state=start,width=4cm] -% \defineinteractionmenu[another][top] [state=start,height=1cm] -% -% \startinteractionmenu[test] -% \but [firstpage] test-a \\ -% \but [nextpage] test-b \\ -% \stopinteractionmenu -% -% \startinteractionmenu[another] -% \but [firstpage] test-a \\ -% \but [nextpage] test-b \\ -% \stopinteractionmenu -% -% \setupheadertexts[{\interactionmenu[another]}] -% -% \starttext -% -% test \interactionmenu[test] \page -% test \interactionmenu[test] \page -% -% \stoptext - -%D This can save complicated menu macros when one want to -%D keep control over parts of a menu (i.e.\ turn them on and -%D off). We could have achieved something similar with modes. - -\def\local@@ambox#1#2#3#4% don't change skipping, this one works! - {\bgroup - \testinteractionmenu{#3}% - \iflocationmenupermitted - \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after - \else - #1\relax - \fi - \egroup} - -\def\includemenu[#1]% - {\doifvalue{\??am#1\c!state}\v!local - {\bgroup - \letvalue{\??am#1\c!state}\v!start - \let\@@amvbox\local@@ambox - \let\@@amhbox\local@@ambox - \getvalue{\??am\c!menu#1}% - \egroup}} - -%D We also need an explicit position control some day. I'll -%D do that when I need it. [The stacking order.] - -\newif\ifextendedmenu - -% [name] [location] -% [name] [location] [pars] - -\def\defineinteractionmenu - {\dotripleempty\dodefineinteractionmenu} - -\def\dodefineinteractionmenu[#1][#2][#3]% - {% main settings - \letvalue{\??am\c!menu#1}\empty - \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}% - \presetlocalframed[\??am#1]% - % register location - \expanded{\addtocommalist{#1}\@EA\noexpand\csname\??am#2\endcsname}% - % inherit settings - \doifnot{#1}{#2} - {\copyparameters[\??am#1][\??am#2] - [\c!left,\c!middle,\c!right,\c!before,\c!after,\c!inbetween,% - \c!width,\c!height,\c!distance,\c!offset,% - \c!frame,\c!framecolor,\c!rulethickness,% - \c!background,\c!backgroundcolor,\c!backgroundscreen,% - \c!style,\c!color,\c!contrastcolor,\c!samepage,\c!unknownreference,% - \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]}% - % additional settings - \getparameters[\??am#1][\c!location=#2,\c!obstruction=,#3]} - -\def\setupinteractionmenu - {\dodoubleargument\dosetupinteractionmenu} - -\def\dosetupinteractionmenu[#1][#2]% - {\def\docommand##1{\getparameters[\??am##1][#2]}% - \processcommalist[#1]\docommand} - -\expandafter\chardef\csname\??am\??am\v!yes \endcsname\zerocount -\expandafter\chardef\csname\??am\??am\v!empty\endcsname\plusone -\expandafter\chardef\csname\??am\??am\v!no \endcsname\plustwo -\expandafter\chardef\csname\??am\??am\v!none \endcsname\plusthree -\expandafter\chardef\csname\??am\??am \endcsname\plusone % default - -\processbetween{\v!interactionmenu}\dostartinteractionmenu - -\def\dostartinteractionmenu#1% - {\dodostartinteractionmenu#1\dodostopinteractionmenu} - -\def\dodostartinteractionmenu[#1]#2\dodostopinteractionmenu - {\setvalue{\??am\c!menu#1}{\extendedmenutrue\dointeractionmenu{#1}{#2}}} - -\def\resetinteractionmenu[#1]% - {\letvalue{\??am\c!menu#1}\empty} - -\def\dodomenulistelement#1#2#3#4#5#6#7% - {\setbox0=\hbox - {\let\gotolocation\gobbleoneargument % hack to catch last [] - %\locationclickfalse % ipv ^ - \docheckrealreferencepage{#7}% - \setlocationboxyes - {\??am#1}% % needed ! - []% no settings - {\limitatetext{#5}{\getvalue{\??li#2\c!maxwidth}}{\unknown}}% % needed ! - []}% normally the destination, catch by gobble - \@@amboxcommand\do@@amposition{#1}{#7}% beware, we pass the pagenumber - {\ignorespaces\linklisttoelement{#3}{#6}{#7}{\box0}\unskip}\\} - -% \scherm moet worden als \page - -\def\screen - {\dosingleempty\doscreen} - -\def\doscreen[#1]% - {\iflocation\page[#1]\fi} - -\unexpanded\def\menubutton - {\dodoubleempty\domenubutton} - -\def\domenubutton[#1]% - {\iffirstargument - \ifsecondargument - \@EAEAEA\domenubuttonB - \else - \doifassignmentelse{#1} - {\@EAEAEA\domenubuttonC} - {\@EAEAEA\domenubuttonD}% - \fi - \else - \@EA\domenubuttonA - \fi[#1]} - -\def\domenubuttonA[#1][#2]#3[#4]% normal button, no parameters - {\bgroup - %\locationdummytrue - \setlocationbox\??bt[]{#3}[#4]% - \egroup} - -\def\domenubuttonB[#1][#2]#3[#4]% menu button, with parameters - {\bgroup - %\locationdummytrue - \setlocationbox{\??am#1}[#2]{#3}[#4]% - \egroup} - -\def\domenubuttonC[#1][#2]#3[#4]% normal button, with parameters - {\bgroup - %\locationdummytrue - \setlocationbox\??bt[#1]{#3}[#4]% - \egroup} - -\def\domenubuttonD[#1][#2]#3[#4]% menu button, no parameters - {\bgroup - %\locationdummytrue - \setlocationbox{\??am#1}[]{#3}[#4]% - \egroup} - -\def\menubox - {\dodoubleempty\domenubox} - -\def\domenubox[#1][#2]#3% - {\bgroup - \let\setlocationbox\setlocationboxraw - \domenubutton[#1][#2]#3[]% - \egroup} - -% Hier volgen de synchronisatiemacro's: - -\def\syncprefix{sync} - -%def\syncmarker{syncmark} -%\definemarking[\syncmarker] -%\setupmarking[\syncmarker][\c!expansie=\v!ja] - -\newmark\syncmarker - -\newcounter\synccounter - -\newif\ifsynchronisation - -\def\startsynchronization% - {\iflocation\ifsynchronisation - \doglobal\increment\synccounter - \fi\fi} - -\def\stopsynchronization% - {\iflocation\ifsynchronisation - %\thisisdestination{\syncprefix:\synccounter}% - \pagereference[\syncprefix:\synccounter]% - \ifvmode - \@EA\setmark\@EA\syncmarker\@EA{\synccounter} % \marking[\syncmarker]{\synccounter}% - \else - \showmessage\m!interactions4\synccounter - \fi - \fi\fi} - -\def\synchronize% - {\startsynchronization - \stopsynchronization} - -\def\dosetupsynchronization[#1]% - {\getparameters[\??sy][#1]% - \doifelse\@@systate\v!start - \synchronisationtrue - \synchronisationfalse} - -\def\setupsynchronization - {\dosingleargument\dosetupsynchronization} - -\def\definesynchronization - {\dosingleargument\dodefinesynchronization} - -\def\setupsynchronizationbar - {\dodoubleargument\getparameters[\??ba]} - -\presetlocalframed[\??ba] - -\setvalue{synchronisatie\v!page}[#1]% - {\bgroup - %\setupinteraction[\c!width=\!!zeropoint]% - \setinteractionparameter\c!width\!!zeropoint - \setbox0\hbox - {\localframed[\??ba][]{\dolocationattributes\??ba\c!style\c!color{\strut\@@batext}}}% - \dontcomplain - \def\atthebottom - {\leaders\hrule\!!depth1ex\!!height-.5ex\hfil}% - \def\atthetop##1##2##3% - {\dimen0=\wd0 - \divide\dimen0 3 - \multiply\dimen0 ##2\relax - \dimen2=.25em % brrr - \advance\dimen0 -##3\dimen2 - %\gotodestination - % {}{#1}{\syncprefix:##1}{} - % {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}}% - \gotobox - {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}% - [#1::\syncprefix:##1]}% - \hbox - {\def\check##1##2% - {\edef##2{0##1\syncmarker}% - \ifnum0##2=0 \def##2{1}\fi}% - \check\gettopmark\top - \check\getfirstmark\first - \check\getbotmark\bot - \setbox2\hbox to \wd0 - {\ifnum\top=\first\relax - \ifnum\first=\bot\relax - \atthetop\first30\relax - \else - \atthetop\first21\hss\atthetop\bot11\relax - \fi - \else - \ifnum\first=\bot\relax - \atthetop\top11\hss\atthetop\first21\relax - \else - \atthetop\top11\hss\atthetop\first11\hss\atthetop\bot11\relax - \fi - \fi}% - \wd2=\zeropoint\box2 - \box0\relax}% - \egroup} - -\setvalue{synchronisatie\v!local}[#1]% - {\bgroup - %\setupinteraction[\c!width=\!!zeropoint]% - \setinteractionparameter\c!width\!!zeropoint - \def\blackrule{\hbox{\vrule\!!height.5em\!!width.5em}}% - %\gotodestination - % {}{##1}{\syncprefix:#1}{0} - % {\color[\locationcolor\@@bacolor]{\blackrule}}% - \gotobox % - {\color[\locationcolor\@@bacolor]{\blackrule}}% - [#1::\syncprefix:\synccounter]% - \egroup} - -\def\synchronizationbar[#1][#2]% - {\iflocation\ifsynchronisation - \bgroup - \setupsynchronizationbar - [\c!text=\getvalue{doc:des:#1},#2]% - \getvalue{synchronisatie\@@baalternative}[#1]% - \egroup - \fi\fi} - -% A nice application of glue. All this code will be rewritten and -% generalized. - -\newbox\interactionbarbox - -\newif\ifbarsymbol - -\def\dogotosomepage#1#2#3% nog checken ! - {\hbox - {\iflocation - \ifnum#3=\realpageno - #2% - \else - \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% - \fi - \else - #2% - \fi}} - -\def\dogotosomecontrastpage#1#2#3% nog checken, may replace previous - {\checkreferences % nodig ?? - \hbox - {\iflocation - \ifnum#3=\realpageno - \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!contrastcolor}{#2}}% - \else - \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% - \fi - \else - #2% - \fi}} - -\presetlocalframed[\??ib] - -\def\interactionbara % we need better control over contrastcolor - {\iflocation % maybe just use gotopage and set colors - \bgroup - \setinteractionparameter\c!width\zeropoint - \setupblackrules[\c!height=\v!max,\c!depth=\v!max]% - \!!widthb\dimexpr\@@ibwidth-2.75\emwidth\relax - \!!widtha\dimexpr\!!widthb/\lastpage\relax - \bgroup - \advance\realpageno\minusone - \ifvoid\interactionbarbox - \bgroup - \processaction - [\@@ibstep] - [ \v!small=>\scratchdimen.25\emwidth, - \v!medium=>\scratchdimen.5\emwidth, - \v!big=>\scratchdimen\emwidth, - \s!unknown=>\scratchdimen\!!widtha]% - \ifdim\!!widtha<\scratchdimen\relax - \!!counta\numexpr\scratchdimen/\!!widtha\relax - \else - \!!counta\@@ibstep\relax - \fi - \!!widtha\!!counta\!!widtha - \setbox\scratchbox\hbox{\blackrule[\c!width=\!!widtha,\c!color=middlegray]}% color here, else no mkiv - \global\setbox\interactionbarbox\hbox to \!!widthb - {\hss - \dostepwiserecurse\plusone\lastpage\!!counta - {\gotorealpage\empty\empty\recurselevel{\copy\scratchbox}}% - \hss}% - \global\wd\interactionbarbox\zeropoint - \egroup - \fi - \egroup - \noindent - \strut - \hbox to \@@ibwidth - {\dontcomplain - \setupblackrules[\c!width=\emwidth]% - \dogotosomecontrastpage\??ib\blackrule\firstpage - \hss - \copy\interactionbarbox - \hbox to \!!widthb - {\ifdim\!!widtha<\emwidth - \!!widtha\emwidth - \fi - \setupblackrules[\c!width=\!!widtha]% - \ifnum\realpageno>\plusone - \!!counta\numexpr\realpageno-\plustwo\relax - \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow - \dogotosomepage\??ib\blackrule\prevpage - \fi - \dogotosomecontrastpage\??ib{\blackrule[\c!width=.5em]}\realpageno - \ifnum\realpageno<\lastpage\relax - \dogotosomepage\??ib\blackrule\nextpage - \!!counta\numexpr\lastpage-\realpageno-\plusone\relax - \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow - \fi}% - \hss - \dogotosomecontrastpage\??ib\blackrule\lastpage}% - \egroup - \fi} - -\def\interactionbarb - {\ifnum\lastpage>\firstpage\relax - \interactionbuttons[\v!firstpage,\v!previouspage,\v!nextpage,\v!lastpage]% - \fi} - -\def\interactionbarc - {\iflocation - \ifnum\lastpage>\plusone - \hbox to \@@ibwidth - {\setupblackrules[\c!height=\@@ibheight,\c!depth=\@@ibdepth]% - \scratchdimen\dimexpr(\@@ibwidth-4\emwidth)/\numexpr\lastpage+\minusone\relax\relax - \!!widtha\numexpr\realpageno+\minusone\relax\scratchdimen - \!!widthb\numexpr\lastpage-\realpageno\relax\scratchdimen - \startcolor[\locationcolor\@@ibcolor]% - \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\firstpage - \hss - \dogotosomepage\empty{\blackrule[\c!width=\!!widtha]}\prevpage - \color[\@@ibcontrastcolor]{\blackrule[\c!width=\emwidth]}% - \dogotosomepage\empty{\blackrule[\c!width=\!!widthb]}\nextpage - \hss - \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\lastpage - \stopcolor}% - \fi - \fi} - -\def\interactionbard - {\iflocation\ifshowingsubpage - \ifnum\nofsubpages>\plusone - \hbox \bgroup - \setinteractionparameter\c!width\!!zeropoint - \ifbarsymbol - \setupsymbolset[\@@iasymbolset]% - \def\dogotox##1% - {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi]}}% - \else - \def\dogotox##1% - {\hbox{\vrule\!!height\@@ibheight\!!depth \@@ibdepth\!!width \@@ibwidth}}% - \fi - \dostepwiserecurse\plusone\nofsubpages\plusone - {\bgroup - \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax - \ifnum\scratchcounter<\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter - \else\ifnum\scratchcounter=\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter - \else - \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter - \fi\fi - \egroup - \hskip\@@ibdistance}% - \unskip % not needed - \egroup - \fi - \fi\fi} - -\def\interactionbare% KAN WORDEN GECOMBINEERD MET D - {\iflocation\ifshowingsubpage - \ifnum\nofsubpages>\plusone - \bgroup - \!!widthb\dimexpr\nofsubpages\dimexpr\@@ibdistance\relax-\@@ibdistance\relax % (n-1) - \!!widtha\dimexpr(\@@ibwidth-\!!widthb)/\nofsubpages\relax - \ifdim\!!widtha<\@@ibdistance\relax - \interactionbarf - \else - \setinteractionparameter\c!width\!!zeropoint - \noindent - \hbox to \@@ibwidth - \bgroup - \ifbarsymbol - \setupsymbolset[\@@iasymbolset]% - \def\dogotox##1% - {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi}}% - \else - \def\dogotox##1% - {\hbox{\vrule\!!height\@@ibheight\!!depth\@@ibdepth\!!width\!!widtha}}% - \fi - \dostepwiserecurse\plusone\nofsubpages\plusone - {\bgroup - \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax - \ifnum\scratchcounter<\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter - \else\ifnum\scratchcounter=\realpageno\relax - \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter - \else - \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter - \fi\fi - \egroup - \hss}% - \unskip - \egroup - \fi - \egroup - \fi - \fi\fi} - -\def\interactionbarf % !! KAN WORDEN GECOMBINEERD MET D !! - {\iflocation\ifshowingsubpage - \ifnum\nofsubpages>\plusone - \setinteractionparameter\c!width\!!zeropoint - \noindent - \hbox to \@@ibwidth - \bgroup - \!!countb\zerocount - \loop % todo: \doloop - \advance\!!countb \plusone - %\!!countc\nofsubpages \divide\!!countc \!!countb \advance\!!countc \plusone - \!!countc\numexpr(\nofsubpages/\!!countb)+\plusone\relax % rounding - \!!widthb\@@ibdistance - \multiply\!!widthb \!!countc - \advance\!!widthb -\@@ibdistance - \!!widtha\@@ibwidth - \advance\!!widtha -\!!widthb - \divide\!!widtha \!!countc - \ifdim\!!widtha<\@@ibdistance\relax - \repeat - \ifnum\!!countc>\plusone - % this is not that well tested - \advance\!!countc \minustwo - \!!widtha-\@@ibdistance - \!!widtha\!!countc\!!widtha - \advance\!!widtha \@@ibwidth - \advance\!!countc \plusone - \divide\!!widtha \!!countc - \fi - \ifbarsymbol - \setupsymbolset[\@@iasymbolset]% - \def\dogotox##1% - {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!somewhere\or\v!somewhere\or\v!next\fi}}% - \else - \def\dogotox##1% - {\hbox - {\!!heighta\@@ibheight - \!!deptha\@@ibdepth - \ifcase##1\relax - \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha - \or - \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha - \or - \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha - \or - \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha - \or - \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha - \fi}}% - \fi - \!!countc\numexpr\realpageno-\plustwo\relax - \!!countd\numexpr\realpageno+\plustwo\relax - \ifnum\!!countc<\plusone \!!countc\plusone \fi - \!!countf\zerocount - \dostepwiserecurse\firstsubpage\lastsubpage\plusone - {\!!doneafalse - \advance\!!countf \plusone - \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi - \ifnum\recurselevel=\lastsubpage\relax \!!doneatrue \fi - \if!!donea - \ifnum\recurselevel<\realpageno - \dogotosomecontrastpage\??ib{\dogotox0}\recurselevel - \else\ifnum\recurselevel>\realpageno - \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel - \else - \dogotosomecontrastpage\??ib{\dogotox4}\recurselevel - \fi\fi - \hss - \!!countf\zerocount - \else\ifnum\!!countf=\!!countb - \ifnum\recurselevel<\realpageno - \dogotosomecontrastpage\??ib{\dogotox1}\recurselevel - \else\ifnum\recurselevel>\realpageno - \dogotosomecontrastpage\??ib{\dogotox3}\recurselevel - \else - \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel - \fi\fi - \hss - \!!countf\zerocount - \fi\fi}% - \unskip - \egroup - \fi - \fi\fi} - -\def\interactionbarg - {\ifnum\lastsubpage>\firstsubpage\relax - \interactionbuttons[\v!firstsubpage,\v!previoussubpage,\v!nextsubpage,\v!lastsubpage]% - \fi} - -\def\checkinteractionbar#1#2#3% - {\ifdim\@@ibwidth=\zeropoint\def\@@ibwidth{#1}\fi - \doifnothing\@@ibheight{\def\@@ibheight{#2}}% - \doifnothing\@@ibdepth{\def\@@ibdepth{#3}}} - -\def\complexinteractionbar[#1]% - {\doifelse{#1}\v!reset - {\global\setbox\interactionbarbox\emptybox}% - {\bgroup - \iflocation - \checksubpages % goes wrong / loads \numberofpages too - \getparameters[\??ib][#1]% - \doif\@@ibstate\v!start - {\startinteraction - \processaction % breedte defaults ! - [\@@ibalternative] - [ c=>\checkinteractionbar{10em}\v!max \v!max, - d=>\checkinteractionbar{.5em}{.5em} \!!zeropoint, - e=>\checkinteractionbar{10em}{.5em} \!!zeropoint, - f=>\checkinteractionbar{10em}{.5em} \!!zeropoint, - \s!default=>\checkinteractionbar{10em}\v!broad\!!zeropoint, - \s!unknown=>\checkinteractionbar{10em}\v!broad\!!zeropoint]% - \doifelse\@@ibsymbol\v!yes - \barsymboltrue\barsymbolfalse - \getvalue{interactionbar\@@ibalternative}% - \stopinteraction}% - \fi - \egroup}} - -\definecomplexorsimpleempty\interactionbar - -\def\setupinteractionbar - {\dodoubleargument\getparameters[\??ib]} - -% Er wordt vooralsnog uitgegaan van een symmetrische -% start-stop situatie. - -\def\c!profiel!! {profiel:} % brrr -\def\c!versie!! {versie:} - -\def\dodefineprofile[#1][#2]% - {\iflocation - \def\dododefineprofile##1% - {\def\dodododefineprofile####1% - {\doifdefinedelse{\c!profiel!!####1}% - {\edef\!!stringa{\getvalue{\c!profiel!!####1}}% - \setevalue{\c!profiel!!####1}{\!!stringa,##1}}% - {\setevalue{\c!profiel!!####1}{##1}}}% - \processcommalist[#2]\dodododefineprofile}% - \processcommalist[#1]\dododefineprofile - \fi} - -\def\defineprofile% - {\dodoubleargument\dodefineprofile} - -% Als met \getpar wordt gewerkt, dan moet \next worden toegepast. - -% TZT initialisatie! - -\def\profilepage{} - -\let\dosetprofilepage\relax -\let\dogetprofilepage\relax - -\def\processprofile#1[#2]% - {\iflocation - \par % needed for pdftex - \bgroup - \dosetprofilepage - \dogetprofilepage - \def\processoneprofile##1##2% - {\ExpandBothAfter\doifinsetelse{##2}{\processedprofiles}% - {\doifsomething{##1}{(##1)}}% - {\addtocommalist{##2}\processedprofiles - ##1\relax - \ifcase#1\relax - \dobeginofprofile{##2}\paperwidth\paperheight\profilepage - \else - \doendofprofile - \fi}}% - \let\processedprofiles\empty - \def\doprocessprofile##1% - {\doifelse{\@@pfoption}{\v!test}% - {\goodbreak\blank\nobreak\tt[\space - \ifcase#1\v!start\else\v!stop\fi profiel\space ##1:\space - \doifdefinedelse{\c!profiel!!##1}% - {\def\dodoprocessprofile####1% - {\processoneprofile - {\goto{####1}[\c!profiel!!####1]}% - {####1}% - \space}% - \processcommacommand - [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}% - {- }% - ]\nobreak\blank}% - {\doifdefined{\c!profiel!!##1}% - {\def\dodoprocessprofile####1% - {\processoneprofile{}{####1}}% - \processcommacommand - [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}}}% - \processcommalist[#2]\doprocessprofile - \egroup - \par % needed for pdftex - \fi} - -\def\startprofile[#1]% - {\iflocation - \bgroup - \addtocommalist{#1}\actualprofile - \def\stopprofile% - {\processprofile1[#1]% - \egroup}% - \def\next{\processprofile0[#1]}% % \DoAfterFi \processprofile0[#1]% - \else % ^^^^^^^^^^ will be obsolete - \let\next\relax % since ugly and never used - \fi - \next} - -\let\stopprofile\relax - -\def\dofollowprofile#1[#2]% - {\iflocation - \hbox - {\dohandlegoto - {\dolocationattributes\??ia\c!style\c!color{#1\presetgoto}}% - {\dostartgotoprofile\buttonwidth\buttonheight{#2}}% - {\dostopgotoprofile}}% - \else - {#1}% - \fi} - -\def\followprofile#1[#2]% - {\iflocation - \doif\@@pfoption\v!test{\pagereference[\c!profiel!!#2]}% - \dofollowprofile{#1}[#2]% - \fi} - -\def\setupprofiles% - {\dodoubleargument\getparameters[\??pf]} - -% Als er nog geen tekst op de pagina staat, dan heeft het -% profiel betrekking op het bovenstaande, dus soms een vorige -% pagina! Vreemd, omdat PDF paginagewijs werkt. Gelukkig -% biedt /page een oplossing. Echter: expansie van een -% \special kan niet worden uitgesteld, zodat alleen een -% two-pass een oplossing vormt. Het onderstaande kan komen -% te vervallen als Acrobat dit ondervangt. Het scheelt een -% pass en een lijst. -% -% Er kunnen eventueel twee lijsten worden gebruikt. Een voor -% het begin (start) en een voor het eind (stop). Nu staat -% alles in een lijst. - -\definetwopasslist\s!profile - -\newcounter\currentprofile - -\def\dosetprofilepage% - {\doglobal\increment\currentprofile - \lazysavetwopassdata{\s!profile}{\currentprofile}{\noexpand\realfolio}} - -\def\dogetprofilepage% - {\gettwopassdata{\s!profile}% - \let\profilepage=\twopassdata} - -% is this stuff used at all - -\newcounter\versionlevel -\newcounter\versionorder - -\newif\ifrecentversion - -\let\oldatcharacter=@ - -\def\minimumversion{0} -\def\actualversion{0} - -\def\dosetupversions[#1]% - {\getparameters[\??ve][#1] - \stripcharacter.\from\@@venumber\to\minimumversion} - -\def\setupversions - {\dosingleargument\dosetupversions} - -\definetwopasslist\s!versionbegin -\definetwopasslist\s!versionend - -\let\actualprofile\empty - -\def\doresetpageversion - {\lazysavetwopassdata{\s!versionend}{\versionorder}{\noexpand\realfolio}} - -\def\dosetpageversion#1% - {\recentversiontrue - \doglobal\increment\versionorder\relax - \lazysavetwopassdata{\s!versionbegin}{\versionorder}{\noexpand\realfolio}% - \let\resetpageversion\doresetpageversion} - -\def\recentcontributions{} - -\def\checkrecentcontributions% - {\gettwopassdata{\s!versionbegin}% - \iftwopassdatafound - \!!counta\twopassdata\relax - \gettwopassdata{\s!versionend}% - \iftwopassdatafound - \!!countb\twopassdata\relax - \doglobal\increment\versionorder\relax - \savetwopassdata{\s!versionbegin}{\versionorder}{\the\!!counta}% - \savetwopassdata{\s!versionend }{\versionorder}{\the\!!countb}% - \dostepwiserecurse\!!counta\!!countb\plusone - {\@EA\doglobal\@EA\addtocommalist\@EA{\recurselevel}{\recentcontributions}}% - \let\next\checkrecentcontributions - \else - \let\next\relax - \fi - \else - \let\next\relax - \fi - \next} - -\def\docheckpageversion - {\ExpandBothAfter\doifinsetelse{\realfolio}{\recentcontributions} - {\pageselectedtrue}% - {\pageselectedfalse}} - -\let\setpageversion \gobbleoneargument -\let\resetpageversion \relax -\let\checkpageversion \relax - -\def\complexstartversion[#1]% - {\bgroup - \doifelsenothing\actualprofile - {\startprofile[#1]}% - {\startprofile[#1,\actualprofile]}% - \def\docomplexstartversie##1% - {\stripcharacter.\from##1\to\actualversion - \ifnum\versionlevel>\zerocount\relax - \ifnum\actualversion=\zerocount - \setpageversion\actualversion % unknown version - \else - \ifnum\actualversion<\minimumversion\relax - \relax % old version - \else - \setpageversion\actualversion % new version - \fi - \fi - \fi}% - \doglobal\increment\versionlevel\relax - \doifelsenothing{#1} - {\docomplexstartversie{0}}% - {\processcommalist[#1]\docomplexstartversie}} - -\definecomplexorsimpleempty\startversion - -\def\stopversion - {\stopprofile - \doglobal\decrement\versionlevel - \ifnum\versionlevel<\zerocount - \showmessage\m!versions1\empty - \else - \resetpageversion - \egroup - \fi} - -\def\markversion - {\showmessage\m!versions2\empty - \let\setpageversion\dosetpageversion - \let\resetpageversion\relax - \let\checkpageversion\relax} - -\def\selectversion - {\checkrecentcontributions - \showmessage\m!versions3\recentcontributions - \let\setpageversio\gobbleoneargument - \let\resetpageversion\relax - \let\checkpageversion\docheckpageversion} - -\def\dodefineversion[#1][#2]% - {\setvalue{\c!versie!!#1}{#2}% - \defineprofile[#1][#2]} - -\def\defineversion - {\dodoubleargument\dodefineversion} - -\def\followversion - {\followprofile} - -\def\followprofileversion#1[#2][#3]% - {\def\docommand##1% - {\defineprofile[#2#3][##1]}% - \processcommacommand[\getvalue{\c!versie!!#3}]\docommand - \followprofile#1[#2#3]} - -\newcounter\currentpagetransition - -\newif\ifrandomtransitions - -\def\setuppagetransitions% - {\dosingleempty\dosetuppagetransitions} - -\def\dosetuppagetransitions[#1]% - {\doifelsenothing{#1} - {\doifnot\@@scdelay\v!none - {\let\setpagetransition\setsomepagedelay}} - {\doifelse{#1}\v!start - {\doifnot\@@scdelay\v!none - {\let\setpagetransition\setsomepagedelay}} - {\doglobal\newcounter\currentpagetransition - \doifinsetelse{#1}{\v!reset,\v!stop} - {\let\setpagetransition\relax} - {\let\setpagetransition\setsomepagetransition - \doifinsetelse\v!random{#1} - {\randomtransitionstrue}{\randomtransitionsfalse}% - \edef\userpagetransitions{#1}% - \@EA\removefromcommalist\@EA{\v!random}\userpagetransitions - \ifx\userpagetransitions\empty - \let\userpagetransitions\pagetransitions - \fi}}}} - -\def\setsomepagedelay - {\expanded{\dosetpagetransition{0}{\@@scdelay}}} - -\def\setsomepagetransition - {\iflocation - \ifrandomtransitions - \expanded{\getcommalistsize[\userpagetransitions]}% - \getrandomnumber\currentpagetransition1\commalistsize - \else - \doglobal\increment\currentpagetransition - \fi - \expanded{\getfromcommalist[\userpagetransitions][\currentpagetransition]}% - \doifnumberelse\commalistelement - {\expanded{\getfromcommalist[\pagetransitions][\commalistelement]}} - {}% - \ifx\commalistelement\empty - \doglobal\newcounter\currentpagetransition - \setsomepagetransition - \else - \doifelse\@@scdelay\v!none - {\expanded{\dosetpagetransition{\commalistelement}{0}}} - {\expanded{\dosetpagetransition{\commalistelement}{\@@scdelay}}}% - \fi - \fi} - -\prependtoks \setpagetransition \to \everyshipout - -% temporary here - -%D \startbuffer -%D \dorecurse{10} -%D {\horizontalpositionbar -%D \pos\recurselevel \min1 \max10 -%D \token\framed{\recurselevel}% -%D \\} -%D -%D \hbox to 15em -%D {\hss -%D \dorecurse{10} -%D {\verticalpositionbar\pos\recurselevel\min1\max10\token\blackrule\\ -%D \hss}} -%D \stopbuffer - -\def\horizontalpositionbar\pos#1\min#2\max#3\token#4\\% - {\hbox to \hsize - {\hskip\zeropoint\!!plus #1\!!fill - \hskip\zeropoint\!!plus-#2\!!fill - #4\relax - \hskip\zeropoint\!!plus #3\!!fill - \hskip\zeropoint\!!plus-#1\!!fill}} - -\def\verticalpositionbar\pos#1\min#2\max#3\token#4\\% - {\vbox to \vsize - {\vskip\zeropoint\!!plus #1\!!fill - \vskip\zeropoint\!!plus-#2\!!fill - \hbox{#4}\relax - \vskip\zeropoint\!!plus #3\!!fill - \vskip\zeropoint\!!plus-#1\!!fill}} - -\def\horizontalgrowingbar\pos#1\min#2\max#3\height#4\depth#5\\% - {\hbox to \hsize - {\scratchcounter#1% - \advance\scratchcounter -#2% - \advance\scratchcounter \plusone - \leaders\vrule\hskip\zeropoint\!!plus \scratchcounter\!!fill - \vrule\!!width\zeropoint\!!height#4\!!depth#5% - \hskip\zeropoint\!!plus #3\!!fill - \hskip\zeropoint\!!plus-#1\!!fill}} - -\def\verticalgrowingbar\pos#1\min#2\max#3\width#4\\% - {\vbox to \vsize - {\scratchcounter#1% - \advance\scratchcounter -#2% - \advance\scratchcounter \plusone - \leaders\hrule\vskip\zeropoint\!!plus\scratchcounter\!!fill - \hrule\!!width#4\!!height\zeropoint\!!depth\zeropoint - \vskip\zeropoint\!!plus #3\!!fill - \vskip\zeropoint\!!plus-#1\!!fill}} - -\newbox\commentbox - -\def\doflushcommentanchors - {\let\next\relax % new - \processaction - [\@@cclocation] - [% \v!text=>\let\next\relax, % new - \v!inmargin=>\let\next\inmargin, % brr not the same as inleft|rightmargin - \v!leftedge=>\let\next\inleftedge, - \v!rightedge=>\let\next\inrightedge, - \v!leftmargin=>\let\next\inleftmargin, - \v!rightmargin=>\let\next\inrightmargin]% - \next{\hbox{\raise\strutht\box\commentbox}}} - -\def\flushcommentanchors % in everypar so indirect - {\ifvoid\commentbox\else \doflushcommentanchors \fi} - -\def\setupcomment - {\dodoubleargument\getparameters[\??cc]} - -\setvalue{\e!start\v!comment}% the dummy triple gobbles trailing spaces - {\dotripleempty\dostartcommentaar} - -\def\comment - {\dodoubleempty\docomment} - -\def\dodocomment#1% - {\!!widtha\@@ccwidth - \!!heighta\@@ccheight - \doifelse\@@ccoption\v!max - {\let\@@ccopen \!!plusone}{\let\@@ccopen \!!zerocount}% - \doifelse\@@ccoption\v!buffer - {\let\@@cccollect\!!plusone}{\let\@@cccollect\!!zerocount}% - \preparecommentvariables - \doinsertcomment - \@@cctitle\!!widtha\!!heighta - \@@cccolor\@@ccopen\@@ccsymbol - \@@cccollect{#1}} - -\def\preparecommentvariables % more will move here as with fields - {\let\@@DriverCommentLayer\@@cctextlayer} - -\def\dopreparecommentaar#1#2% - {\doifassignmentelse{#1} - {\getparameters[\??cc][#1]} - {\getparameters[\??cc][\c!title=#1,#2]}% - \obeylines - \doif\@@ccspace\v!yes\obeyspaces} - -\def\dostartcommentaar[#1][#2][#3]% - {\bgroup - \doifelse\@@ccstate\v!start - {\dopreparecommentaar{#1}{#2}% - \long\def\docommand##1% - {\global\setbox\commentbox\frozenhbox - {\hbox to \zeropoint - {\struttedbox{\tbox{\dodocomment{##1}}}\hss}% - \hskip\ifvoid\commentbox\@@ccmargin\else\@@ccdistance\fi - \box\commentbox}% - \egroup}}% - {\long\def\docommand##1% - {\egroup}}% - \grabuntil{\e!stop\v!comment}\docommand} - -\letvalue{\e!stop\v!comment}\relax % handy for \expanded{...} - -\def\docomment[#1][#2]#3% - {\doif\@@ccstate\v!start - {\hbox to \zeropoint - {\dopreparecommentaar{#1}{#2}% - \hskip-\@@ccmargin - \struttedbox{\tbox{\dodocomment{#3}}\hss}}}% - \ignorespaces} - -% \startcomment -% hello beautiful\\world -% \stopcomment -% -% \startcomment[hello] -% hello << \'e\'erste >> -% beautiful -% world -% \stopcomment -% -% \startcomment[hello][color=green,width=4cm,height=3cm] -% hello \leftguillemot\ \'e\'erste \rightguillemot\ -% beautiful -% world -% \stopcommentaar -% -% \startcomment[hello][color=green,width=4cm,height=3cm] -% hello \leftguillemot\ \'e\'erste \rightguillemot\ test -% -% beautiful -% -% world -% \stopcomment -% -% \startcomment[symbol=Balloon] -% Do we want this kind of rubish? And, why isn't this and -% some more features related to text annotations so poorly -% (actually not) documented? Anyhow, by providing this -% functionality we demonstrate that \pdfTeX\ can do it. By -% the way, it's funny that when in Acrobat we scale up the -% text, the symbols scale down. -% \stopcomment - -% \definesymbol [comment-normal][{\externalfigure[cow.pdf]}] -% \definesymbol [comment-down] [{\externalfigure[cow.pdf]}] -% -% \def\CowSymbol#1#2% -% {\scale -% [\c!height=#1] -% {\startMPcode -% loadfigure "koe.mp" number 1 ; -% refill currentpicture withcolor #2 ; -% \stopMPcode}} -% -% \definesymbol [comment-normal] -% [\CowSymbol{4ex}{red}] -% -% \definesymbol [comment-down] -% [\CowSymbol{4ex}{green}] -% -% \setupcomment -% [\c!symbol={comment-normal,comment-down}, -% \c!option=\v!buffer] -% -% \setupfootertexts[\placecomments] - -\def\placecomments - {\doflushcomments} - -% \setupinteraction[state=start] -% -% \useattachment[test.tex] -% \useattachment[whatever][test.tex] -% \useattachment[whatever][newname][test.tex] -% \useattachment[whatever][title][newname][test.tex] -% -% % \setupattachments[\c!symbol={symbol-normal,symbol-down}] -% -% \starttext \attachment[whatever] \stoptext - -\definesystemvariable{at} - -\def\useattachment - {\doquadrupleempty\douseattachment} - -\def\douseattachment[#1][#2][#3][#4]% tag title newname filename - {\iffourthargument - \setgvalue{\??at:#1}{{#2}{#3}{#4}}% tooltip kind of case - \else\ifthirdargument - \setgvalue{\??at:#1}{{#2}{#2}{#3}}% full path case - \else\ifsecondargument - \setgvalue{\??at:#1}{{#2}{#2}{#2}}% obvious case - \else - \setgvalue{\??at:#1}{{#1}{#1}{#1}}% worst case - \fi\fi\fi} - -\let\attachmenttitle\empty -\let\attachmentname \empty -\let\attachmentfile \empty - -\def\getattachmentdata[#1]% - {\edef\attachmenttitle{\filterfromvalue{\??at:#1}31}% description - \edef\attachmentname {\filterfromvalue{\??at:#1}32}% new name - \edef\attachmentfile {\filterfromvalue{\??at:#1}33}% original - \expandafter\splitstring\attachmentname\at.\to\!!stringa\and\!!stringb - \ifx\!!stringb\empty % no suffix, so we need to inherit it - \expandafter\splitstring\attachmentfile\at.\to\!!stringc\and\!!stringd - \edef\attachmentname{\attachmentname.\!!stringd}% - \fi} - -\def\attachment - {\dodoubleempty\doattachment} - -\def\doattachment[#1][#2]% currently title equals newname - {\iflocation - \ifsecondargument - \doifundefined{\??at:#2} - {\showmessage\m!interactions6{#2}% - \useattachment[#2]}% - \doif\@@atstate\v!start - {\bgroup - \getattachmentdata[#2]% - \doiffileelse\attachmentfile - {\setupattachments[#1]% - \presetattachmentvariables -\struttedbox{\tbox{% - \doattachfile - \attachmenttitle - {1em}\strutheight\strutdepth\@@atcolor\@@atsymbol - \attachmentname - \attachmentfile}% -}}% - {\showmessage\m!interactions5\attachmentfile}% - \egroup}% - \else\iffirstargument - \attachment[][#1]% - \fi\fi - \fi} - -\def\presetattachmentvariables - {\let\@@DriverAttachmentLayer\@@attextlayer} - -\def\setupattachments - {\dodoubleempty\getparameters[\??at]} - -\setupattachments - [\c!state=\v!start, - \c!color=\@@iacolor, - \c!textlayer=, - \c!symbol=] - -% jammer, tussen/midden had erin gemoeten; \c!commando toevoegen - -\def\registermenucommand#1% - {{\textonly\noindent#1\space}} % no math switching - -\def\doregistermenubuttons[#1][#2]% [menu id] [register] - {\bgroup - \ifsecondargument - \setupinteractionmenu - [#1][\c!unknownreference=\v!yes,\c!samepage=\v!yes]% - \def\docommand##1% - {\registermenucommand{\menubutton[#1]{##1}[#2:##1]}}% - \else - \def\docommand##1% - {\registermenucommand - {\button - [\c!unknownreference=\v!yes,\c!samepage=\v!yes] - {##1}[#1:##1]}}% - \fi - \handletokens abcdefghijklmnopqrstuvwxyz\with\docommand % moet anders - \egroup} - -\def\registermenubuttons - {\dodoubleempty\doregistermenubuttons} - -\stelkoppelingenin - [\c!distance=.25em, - \c!width=\v!fit, - \c!location=\v!low, - \c!color=\@@iacolor, - \c!frame=\v!off, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=] - -\defineinteractionmenu - [\v!right] - [\v!right] - [\c!before=, - \c!after=\vfil, - \c!inbetween=\blank, - \c!distance=\bodyfontsize, % 12pt - \c!left=\hss, - \c!right=\hss, - \c!width=\rightedgewidth, - \c!height=\v!broad] - -\defineinteractionmenu - [\v!left] - [\v!left] - [\c!before=, - \c!after=\vfil, - \c!inbetween=\blank, - \c!distance=\bodyfontsize, % 12pt - \c!left=\hss, - \c!right=\hss, - \c!width=\leftedgewidth, - \c!height=\v!broad] - -\defineinteractionmenu - [\v!bottom] - [\v!bottom] - [\c!before=\vss, - \c!after=\vss, - \c!middle=\hfil, - \c!distance=\bodyfontsize, % 12pt - \c!width=\v!fit, - \c!height=\v!broad] - -\defineinteractionmenu - [\v!top] - [\v!top] - [\c!before=\vss, - \c!after=\vss, - \c!middle=\hfil, - \c!distance=\bodyfontsize, % 12pt - \c!width=\v!fit, - \c!height=\v!broad] - -\setupinteractionmenu - [\v!left,\v!right,\v!top,\v!bottom] - [\c!offset=.25em, - \c!position=\v!no, - \c!frame=\v!on, - \c!background=, - \c!backgroundcolor=, - \c!backgroundscreen=\@@rsscreen, - \c!style=\@@iastyle, - \c!color=\@@iacolor, - \c!contrastcolor=\@@iacontrastcolor, - \c!state=\v!start, - \c!samepage=\v!yes, - \c!unknownreference=\v!empty, - \c!topoffset=\!!zeropoint, - \c!bottomoffset=\!!zeropoint, - \c!leftoffset=\!!zeropoint, - \c!rightoffset=\!!zeropoint] - -\def\placeleftedgetextblock % Is \hss/\hsize really needed here? - {\hbox to \leftedgewidth % (check outer level and settings) - {\hsize\leftedgewidth\hss\interactionmenus[\v!left]}} - -\def\placerightedgetextblock % Is \hss/\hsize really needed here? - {\hbox to \rightedgewidth % (check outer level and settings) - {\hsize\rightedgewidth\interactionmenus[\v!right]\hss}} - -\def\placetoptextblock - {\vbox to \topheight - {\vsize\topheight - \csname\??tk\v!top\c!before\endcsname - \interactionmenus[\v!top]% - \csname\??tk\v!top\c!after\endcsname - \kern\zeropoint}} - -\def\placebottomtextblock - {\vbox to \bottomheight - {\vsize\bottomheight - \csname\??tk\v!bottom\c!before\endcsname - \interactionmenus[\v!bottom]% - \csname\??tk\v!bottom\c!after\endcsname - \kern\zeropoint}} - -\ifx\leftedgetextcontent\undefined \else - - \appendtoks \placeleftedgetextblock \hskip-\leftedgewidth \to \leftedgetextcontent - \appendtoks \placerightedgetextblock \hskip-\rightedgewidth \to \rightedgetextcontent - \appendtoks \placetoptextblock \vskip-\topheight \to \toptextcontent - \appendtoks \placebottomtextblock \vskip-\bottomheight \to \bottomtextcontent - -\fi - -\setupinteractionscreen - [\c!width=\printpaperwidth, - \c!height=\printpaperheight, - \c!horoffset=\!!zeropoint, - \c!veroffset=\!!zeropoint, - \c!backspace=\backspace, - \c!topspace=\topspace, - \c!option=\v!min, - \c!delay=\v!none] - -\setupbuttons - [\c!state=\v!start, - \c!width=\v!fit, - \c!height=\v!broad, - \c!offset=0.25em, - \c!frame=\v!on, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!style=\@@iastyle, - \c!color=\@@iacolor, - \c!contrastcolor=\@@iacontrastcolor, - \c!samepage=\v!yes, - \c!unknownreference=\v!yes] - -\setupinteractionbar - [\c!state=\v!start, - \c!alternative=a, - \c!symbol=\v!no, - \c!width=\rightedgewidth, - \c!height=, % these are taken care - \c!depth=, % of at calling time - \c!distance=.5em, % beter relateren aan breedte - \c!step=1, - \c!color=\@@iacolor, - \c!contrastcolor=\@@iacontrastcolor, - \c!frame=\v!on, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!samepage=\v!yes, - \c!unknownreference=\v!yes] - -\setupsynchronizationbar - [\c!alternative=\v!page, - \c!width=\rightedgewidth, - \c!style=\@@iastyle, - \c!color=\@@iacolor, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=] - -\setupsynchronization - [\c!state=\v!stop] - -\setupprofiles - [\c!option=] - -\setuppagetransitions - [\v!reset] - -\setupcomment - [\c!state=\v!start, - \c!margin=2.5em, - \c!distance=1em, - \c!width=.3\textwidth, - \c!height=.2\textheight, - \c!color=\@@iacolor, - \c!title=, - \c!space=\v!no, - \c!symbol=\v!normal, - \c!location=\v!inmargin, - \c!option=, - \c!textlayer=] - -\setupversions % beware, @ is made active here, - [\c!number=1, % therefore we set this one at the end - \c!style=\ss, - \c!color=] - -\protect \endinput diff --git a/tex/context/base/core-itm.tex b/tex/context/base/core-itm.tex deleted file mode 100644 index 406f9d1e4..000000000 --- a/tex/context/base/core-itm.tex +++ /dev/null @@ -1,1344 +0,0 @@ -%D \module -%D [ file=core-itm, % updated -%D version=1997.03.31, -%D title=\CONTEXT\ Core 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 Core Macros / Itemgroups} - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -\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} - -% 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}{0}% - \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/core-lst.tex b/tex/context/base/core-lst.tex deleted file mode 100644 index 84648f6c9..000000000 --- a/tex/context/base/core-lst.tex +++ /dev/null @@ -1,1150 +0,0 @@ -%D \module -%D [ file=core-lst, -%D version=1997.03.31, -%D title=\CONTEXT\ Core 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 Core 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/core-mar.tex b/tex/context/base/core-mar.tex deleted file mode 100644 index 8096793ad..000000000 --- a/tex/context/base/core-mar.tex +++ /dev/null @@ -1,318 +0,0 @@ -%D \module -%D [ file=core-mar, -%D version=1997.03.31, -%D title=\CONTEXT\ Core 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 Core 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/core-mat.tex b/tex/context/base/core-mat.tex deleted file mode 100644 index 21f4e60b8..000000000 --- a/tex/context/base/core-mat.tex +++ /dev/null @@ -1,2923 +0,0 @@ -%D \module -%D [ file=core-mat, -%D version=2006.03.27, % 1998.12.07 -%D title=\CONTEXT\ Core 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 Core 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 - \prevdepth-\maxdimen % texbook pagina 79-80 - % otherwise problems at the top of a page, don't remove: - \verticalstrut - \vskip-\struttotal - \vskip-\baselineskip - \fi - \fi - $$\setdisplaydimensions - \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/core-nav.mkii b/tex/context/base/core-nav.mkii deleted file mode 100644 index f4594ab3b..000000000 --- a/tex/context/base/core-nav.mkii +++ /dev/null @@ -1,379 +0,0 @@ -%D \module -%D [ file=core-nav, -%D version=1998.01.15, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Navigation, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Navigation} - -\unprotect - -%D Support for interactive document is very present in -%D \CONTEXT\ and interwoven in many modules. This means that in -%D this module, where we deal with some common navigational -%D features, there will be quite some forward references. -%D -%D When I started implementing hypertext support, the macros -%D were mostly dealing with things related to locations, that -%D is click in this location and goto that one. The -%D functionality of many macro depends on the output medium: -%D paper or screen. The next boolean holds the state: - -\newif\iflocation \def\ifinteractief{\iflocation} % upw comp - -%D We also allocate a scratchbox: - -\newbox\locationbox - -%D There is no interaction at all unless enabled by saying: -%D -%D \starttyping -%D \setupinteraction[state=start] -%D \stoptyping -%D -%D The other settings are: -%D -%D \showsetup{setupinteraction} -%D -%D In the special driver modules we introduced a switch that -%D forces page destinations (instead of named ones). We set -%D this switch here. - -\def\setinteractionparameter#1#2% use with case, no checking done - {\setvalue{\??ia#1}{#2}} % pass #2, can be \blabla - -\def\resetinteractionparameter#1% use with case, no checking done - {\letvalue{\??ia#1}\empty} - -% \def\interactionparameter#1% -% {\csname\??ia#1\endcsname} - -\newtoks\everysetupinteraction - -\def\setupinteraction - {\dosingleargument\dodosetupinteraction} - -\def\dodosetupinteraction[#1]% % \dosetupinteraction == special - {\getparameters[\??ia][#1]% - \the\everysetupinteraction} - -% todo, move partial append to where the action happens - -\appendtoks - \doifelse\@@iastate\v!start - {\iflocation\else - \showmessage\m!interactions2{\ifusepagedestinations\space(PAGE)\fi}% - \global\locationtrue - \fi} - {\iflocation - \showmessage\m!interactions3{\ifusepagedestinations\space(PAGE)\fi}% - \global\locationfalse - \fi}% - \iflocation - \setsystemmode \v!interaction - \else - \resetsystemmode\v!interaction - \fi - \dosetuppageview\@@iafocus - \doifsomething\@@iacalculate - {\doregistercalculationset\@@iacalculate}% - \doifelse\@@iastrut\v!yes - \locationstruttrue - \locationstrutfalse - \doifelse\@@iaclick\v!yes - \highlighthyperlinkstrue - \highlighthyperlinksfalse - \doifelse\@@iasplit\v!yes - \locationsplittrue - \locationsplitfalse - \doifelse\@@iadisplay\v!new - \gotonewwindowtrue - \gotonewwindowfalse - \doifelse\@@iapage\v!yes - {\global\usepagedestinationstrue} - {\global\usepagedestinationsfalse}% -\to \everysetupinteraction - -%D We have to make sure of some settings: - -\def\dolocationstartup - {\iflocation - \dosetupinteraction - \handlereferenceactions\@@iaopenaction \dosetupopenaction - \handlereferenceactions\@@iacloseaction\dosetupcloseaction - \setupinteractionscreens - \global\let\dolocationstartup\relax - \fi} - -\appendtoks \dolocationstartup \to \everyshipout - -\def\dolocationpagecheck % brr pdf dependent - {\iflocation - \handlereferenceactions\@@iaopenpageaction \dosetupopenpageaction - \handlereferenceactions\@@iaclosepageaction\dosetupclosepageaction - \fi} - -\appendtoks \dolocationpagecheck \to \everyshipout - -%D The next few macros are really horrible. For proper -%D navigation a in||line hypertext fragment must have -%D comfortable properties, so we must force some minimal -%D dimensions. On the other hand button, and here I mean those -%D pieces of text with fancy outlines and/or backgrounds, often -%D have fixed, preset dimensions. -%D -%D To make things even worse, if we choose to let the optimal -%D dimensions depend on the height and depth of a strut, a not -%D too uncommon practice in \TEX, we have to deal with the fact -%D that such a strut, set inside a box, is unknown too the -%D outside world. -%D -%D The solution lays in passing the strut characteristics in -%D a proper way, in our case by applying \type{\presetgoto}: -%D -%D \starttyping -%D {some piece of text \presetgoto} -%D \stoptyping -%D -%D This macro stores the current strut values. - -\newif\iflocationstrut -\newif\iflocationsplit - -\def\resetgoto - {\globallet\@@ia@@hoogte\!!zeropoint - \globallet\@@ia@@diepte\!!zeropoint} - -\resetgoto - -\def\presetgoto - {\iflocationstrut - \setstrut - %\xdef\@@ia@@hoogte{\the\strutht}% - %\xdef\@@ia@@diepte{\the\strutdp}% - \globallet\@@ia@@hoogte\strutheight - \globallet\@@ia@@diepte\strutdepth - \else - \globallet\@@ia@@hoogte\@@iaheight - \globallet\@@ia@@diepte\@@iadepth - \fi} - -%D In the macros that deal with making areas into hyperlinks, -%D we use: - -\newbox\driverresources - -\def\collectdriverresource#1% - {\global\setbox\driverresources\hbox{\box\driverresources#1}} - -\def\flushdriverresources - {\ifvoid\driverresources\else\box\driverresources\fi} - -\def\dohandlegoto#1#2#3% - {\ifsecondaryreference - \bgroup\setbox0\hbox{#2#3}\egroup - \else - \hbox - {\setbox0\hbox{#1}% - \ifdim\wd0<\@@iawidth\relax - \buttonwidth\@@iawidth\relax - \else - \buttonwidth\wd0 - \fi - \ifdim\ht0<\@@ia@@hoogte\relax - \buttonheight\@@ia@@hoogte\relax - \else - \buttonheight\ht0 - \fi - \ifdim\dp0<\@@ia@@diepte\relax - \dimen0=\@@ia@@diepte\relax % = ! - \else - \dimen0\dp0 - \fi - \advance\buttonheight \dimen0 - \setbox2\hbox - {\lower\dimen0\hbox - {\dontcomplain - \dimen0=.5\wd0 % direct skipping is faster of course - \advance\dimen0 -.5\buttonwidth % buts this is nicer - \hskip\dimen0#2#3}}% when visualizing things - \naturalhbox % needed for omega / moved from plus-omg - {\ifreversegoto - \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0 - \else - \smashbox2\box2\box0 - \fi - \flushdriverresources}% - \resetgoto}% - \fi} - -%D The secondary references are processed but not typeset. The -%D special driver must collect the data needed. - -%D The width of the active area depends on the dimensions -%D preset, the actual dimens and/or the height and depth of the -%D strut. -%D -%D Normally the hyper active area is laid on top of the text. -%D This enables stacking hyperlinks on top of each other. When, -%D for some reason the opposite is prefered, one can use the -%D next boolean to signal this wish. - -\newif\ifreversegoto \reversegotofalse - -%D As long as there a natural feeling of what can be considered -%D hyper active or not, we have to tell users where they can -%D possibly click. We've already seen a few macros that deal -%D with this visualization, something we definitely do not let -%D up to the viewer. One way of telling is using a distinctive -%D typeface, another way is using color. -%D -%D There are two colors involved: one for normal hyperlinks, -%D and one for those that point to the currentpage, the -%D contrast color. - -\definecolor [interactioncolor] [r=0, g=.6, b=0] -\definecolor [interactioncontrastcolor] [r=.8, g=0, b=0] - -\definecolor [interactiekleur] [interactioncolor] -\definecolor [interactiecontrastkleur] [interactioncontrastcolor] - -%D The next few macros are responsible for highlighting hyper -%D links. The first one, \type{\showlocation}, is used in those -%D situations where the typeface is handled by the calling -%D macro. - -\def\interactioncolor % todo \??ia as argument - {\iflocation - \ifrealreferencepage - \@@iacontrastcolor - \else - \@@iacolor - \fi - \fi} - -%D CHECK WHERE USED / CONSISTENCY - -\def\showlocation#1% - {\iflocation\color[\@@iacolor]{#1\presetgoto}\else#1\fi} - -%D When local color settings are to be used, we can use the -%D next macro, where \type{#1} is a tag like \type{\??tg} and -%D \type{#2} some text. - -\def\showcoloredlocation#1#2% - {\iflocation - \color[\getvalue{#1\c!color}]{#2\presetgoto}% - \else - #2% - \fi} - -%D When we're dealing with pure page references, contrast -%D colors are used when we are already at the page mentioned. - -\def\showcontrastlocation#1#2#3% the \@EA is needed - {\iflocation - \ifnum#2=\realpageno\relax - \doifelsevaluenothing{#1\c!color} - {#3\presetgoto} - {\color[\getvalue{#1\c!contrastcolor}]{#3\presetgoto}}% - \else - \color[\getvalue{#1\c!color}]{#3\presetgoto}% - \fi - \else - #3% - \fi} - -%D The next simple macro can be used in color specifications, -%D like \type{\color[\locationcolor{green}]}. - -\def\locationcolor#1% - {\iflocation#1\fi} - -%D More tokens are spend when we want both typeface and color -%D highlighting. - -\def\dolocationattributes#1#2#3#4% - {\bgroup - \let\fontattribute\empty - \let\colorattribute\empty - \doifdefined{#1#2}{\def\fontattribute{\getvalue{#1#2}}}% - \iflocation - \doifdefined{#1#3}{\def\colorattribute{\getvalue{#1#3}}}% - \fi - \startcolor[\colorattribute]% - \@EA\doconvertfont\@EA{\fontattribute}{#4}% no \edef, but \@EA here - \stopcolor - \egroup} - -\def\navigating - {\dolocationattributes\??ia\c!style\c!color} - -%D Although not decently supported in current viewers, a -%D provisory hiding mechanims is implemented. Areas marked as -%D such, are visible on screen, but invisible on paper. Don't -%D trust this mechanism yet! - -\def\dostartinteraction - {\bgroup - \let\stopinteraction\egroup - \dowithnextbox{\dostarthide\flushnextbox\dostophide\egroup}\hbox} - -\let\startinteraction = \relax -\let\stopinteraction = \relax - -% in the future: -% -% eerst boolean invoeren bij menu, achtergrond, balk, button -% enz; verder startinteractie een argument meegeven {#1} -> -% \getvalue{#1\c!print}=={\v!ja} enz. Consequent menubutton -% gebruiken! - -\def\@@iatimestamp - {\the\normalyear - \ifnum\normalmonth<10 0\fi\the\normalmonth - \ifnum\normalday <10 0\fi\the\normalday} - -% happens in core-fld -% -% \definereference [AtOpenInitializeForm] [\v!geen] - -\setupinteraction % start fit page and reset form - [\c!state=\v!stop, - \c!page=\v!no, - \c!click=\v!yes, - \c!display=, - %\c!openaction={\v!firstpage,AtOpenInitializeForm}, - %\c!openaction={\v!firstpage,\v!ResetForm}, - %\c!openaction=\v!ResetForm, % too buggy in reader 4.05 - \c!openaction=, - \c!closeaction=, - \c!openpageaction=, - \c!closepageaction=, - \c!display=\v!normal, - \c!focus=\v!fit, - \c!menu=\v!off, - \c!style=\v!bold, - \c!calculate=, - \c!strut=\v!yes, - \c!split=\v!yes, - \c!color=interactioncolor, - \c!contrastcolor=interactioncontrastcolor, - \c!symbolset=, - \c!width=1em, - \c!height=\!!zeropoint, - \c!depth=\!!zeropoint, - \c!title=\jobname, % needed for fdf/x - \c!subtitle=, - \c!author=, - \c!keyword=, - \c!date=\@@iatimestamp] - -\protect \endinput diff --git a/tex/context/base/core-nav.mkiv b/tex/context/base/core-nav.mkiv deleted file mode 100644 index e079f5f08..000000000 --- a/tex/context/base/core-nav.mkiv +++ /dev/null @@ -1,425 +0,0 @@ -%D \module -%D [ file=core-nav, -%D version=1998.01.15, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Navigation, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Navigation} - -\unprotect - -%D Support for interactive document is very present in -%D \CONTEXT\ and interwoven in many modules. This means that in -%D this module, where we deal with some common navigational -%D features, there will be quite some forward references. -%D -%D When I started implementing hypertext support, the macros -%D were mostly dealing with things related to locations, that -%D is click in this location and goto that one. The -%D functionality of many macro depends on the output medium: -%D paper or screen. The next boolean holds the state: - -\newif\iflocation \def\ifinteractief{\iflocation} % upw comp - -%D We also allocate a scratchbox: - -\newbox\locationbox - -%D There is no interaction at all unless enabled by saying: -%D -%D \starttyping -%D \setupinteraction[state=start] -%D \stoptyping -%D -%D The other settings are: -%D -%D \showsetup{setupinteraction} -%D -%D In the special driver modules we introduced a switch that -%D forces page destinations (instead of named ones). We set -%D this switch here. - -\def\setinteractionparameter#1#2% use with case, no checking done - {\setvalue{\??ia#1}{#2}} % pass #2, can be \blabla - -\def\resetinteractionparameter#1% use with case, no checking done - {\letvalue{\??ia#1}\empty} - -% \def\interactionparameter#1% -% {\csname\??ia#1\endcsname} - -\newtoks\everysetupinteraction - -\def\setupinteraction - {\dosingleargument\dodosetupinteraction} - -\def\dodosetupinteraction[#1]% % \dosetupinteraction == special - {\getparameters[\??ia][#1]% - \the\everysetupinteraction} - -% todo, move partial append to where the action happens - -\appendtoks - \doifelse\@@iastate\v!start - {\iflocation\else - \showmessage\m!interactions2{\ifusepagedestinations\space(PAGE)\fi}% - \global\locationtrue - \fi} - {\iflocation - \showmessage\m!interactions3{\ifusepagedestinations\space(PAGE)\fi}% - \global\locationfalse - \fi}% - \iflocation - \setsystemmode \v!interaction - \else - \resetsystemmode\v!interaction - \fi - \dosetuppageview\@@iafocus - \doifsomething\@@iacalculate - {\doregistercalculationset\@@iacalculate}% - \doifelse\@@iastrut\v!yes - \locationstruttrue - \locationstrutfalse - \doifelse\@@iaclick\v!yes - \highlighthyperlinkstrue - \highlighthyperlinksfalse - \doifelse\@@iasplit\v!yes - \locationsplittrue - \locationsplitfalse - \doifelse\@@iadisplay\v!new - \gotonewwindowtrue - \gotonewwindowfalse - \doifelse\@@iapage\v!yes - {\global\usepagedestinationstrue} - {\global\usepagedestinationsfalse}% -\to \everysetupinteraction - -%D We have to make sure of some settings: - -\def\dolocationstartup - {\iflocation - \dosetupinteraction - \handlereferenceactions\@@iaopenaction \dosetupopenaction - \handlereferenceactions\@@iacloseaction\dosetupcloseaction - \setupinteractionscreens - \global\let\dolocationstartup\relax - \fi} - -\appendtoks \dolocationstartup \to \everyshipout - -\def\dolocationpagecheck % brr pdf dependent - {\iflocation - \handlereferenceactions\@@iaopenpageaction \dosetupopenpageaction - \handlereferenceactions\@@iaclosepageaction\dosetupclosepageaction - \fi} - -\appendtoks \dolocationpagecheck \to \everyshipout - -%D The next few macros are really horrible. For proper -%D navigation a in||line hypertext fragment must have -%D comfortable properties, so we must force some minimal -%D dimensions. On the other hand button, and here I mean those -%D pieces of text with fancy outlines and/or backgrounds, often -%D have fixed, preset dimensions. -%D -%D To make things even worse, if we choose to let the optimal -%D dimensions depend on the height and depth of a strut, a not -%D too uncommon practice in \TEX, we have to deal with the fact -%D that such a strut, set inside a box, is unknown too the -%D outside world. -%D -%D The solution lays in passing the strut characteristics in -%D a proper way, in our case by applying \type{\presetgoto}: -%D -%D \starttyping -%D {some piece of text \presetgoto} -%D \stoptyping -%D -%D This macro stores the current strut values. - -\newif\iflocationstrut -\newif\iflocationsplit - -\def\resetgoto - {\globallet\@@ia@@hoogte\!!zeropoint - \globallet\@@ia@@diepte\!!zeropoint} - -\resetgoto - -\def\presetgoto - {\iflocationstrut - \setstrut - %\xdef\@@ia@@hoogte{\the\strutht}% - %\xdef\@@ia@@diepte{\the\strutdp}% - \globallet\@@ia@@hoogte\strutheight - \globallet\@@ia@@diepte\strutdepth - \else - \globallet\@@ia@@hoogte\@@iaheight - \globallet\@@ia@@diepte\@@iadepth - \fi} - -%D In the macros that deal with making areas into hyperlinks, -%D we use: - -\newbox\driverresources - -\def\collectdriverresource#1% - {\global\setbox\driverresources\hbox{\box\driverresources#1}} - -\def\flushdriverresources - {\ifvoid\driverresources\else\box\driverresources\fi} - -% \def\dohandlegoto#1#2#3% -% {\ifsecondaryreference -% \bgroup\setbox0\hbox{#2#3}\egroup -% \else -% \hbox -% {\setbox0\hbox{#1}% -% \ifdim\wd0<\@@iawidth\relax -% \buttonwidth\@@iawidth\relax -% \else -% \buttonwidth\wd0 -% \fi -% \ifdim\ht0<\@@ia@@hoogte\relax -% \buttonheight\@@ia@@hoogte\relax -% \else -% \buttonheight\ht0 -% \fi -% \ifdim\dp0<\@@ia@@diepte\relax -% \dimen0=\@@ia@@diepte\relax % = ! -% \else -% \dimen0\dp0 -% \fi -% \advance\buttonheight \dimen0 -% \setbox2\hbox -% {\lower\dimen0\hbox -% {\dontcomplain -% \dimen0=.5\wd0 % direct skipping is faster of course -% \advance\dimen0 -.5\buttonwidth % buts this is nicer -% \hskip\dimen0#2#3}}% when visualizing things -% \naturalhbox % needed for omega / moved from plus-omg -% {\ifreversegoto -% \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0 -% \else -% \smashbox2\box2\box0 -% \fi -% \flushdriverresources}% -% \resetgoto}% -% \fi} - -\def\dohandlegoto#1#2#3% - {\ifcollectreferenceactions - % this happens here while in mkii elsewhere, better is to deal with - % in in the ref module but that's for later to deal with - \bgroup\setbox\scratchbox\hbox{#2#3}\egroup - \ifsecondaryreference \else - \resetgoto - \fi - \ifsecondaryreference\else#1\resetgoto\fi - \else\ifsecondaryreference - \bgroup\setbox\scratchbox\hbox{#2#3}\egroup - \else - \hbox - {\setbox0\hbox{#1}% - \ifdim\wd0<\@@iawidth\relax - \buttonwidth\@@iawidth\relax - \else - \buttonwidth\wd0 - \fi - \ifdim\ht0<\@@ia@@hoogte\relax - \buttonheight\@@ia@@hoogte\relax - \else - \buttonheight\ht0 - \fi - \ifdim\dp0<\@@ia@@diepte\relax - \dimen0=\@@ia@@diepte\relax % = ! - \else - \dimen0\dp0 - \fi - \advance\buttonheight \dimen0 - \setbox2\hbox - {\lower\dimen0\hbox - {\dontcomplain - \dimen0=.5\wd0 % direct skipping is faster of course - \advance\dimen0 -.5\buttonwidth % buts this is nicer - \hskip\dimen0#2#3}}% when visualizing things - \naturalhbox % needed for omega / moved from plus-omg - {\ifreversegoto - \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0 - \else - \smashbox2\box2\box0 - \fi - \flushdriverresources}% - \resetgoto}% - \fi\fi} - -%D The secondary references are processed but not typeset. The -%D special driver must collect the data needed. - -%D The width of the active area depends on the dimensions -%D preset, the actual dimens and/or the height and depth of the -%D strut. -%D -%D Normally the hyper active area is laid on top of the text. -%D This enables stacking hyperlinks on top of each other. When, -%D for some reason the opposite is prefered, one can use the -%D next boolean to signal this wish. - -\newif\ifreversegoto \reversegotofalse - -%D As long as there a natural feeling of what can be considered -%D hyper active or not, we have to tell users where they can -%D possibly click. We've already seen a few macros that deal -%D with this visualization, something we definitely do not let -%D up to the viewer. One way of telling is using a distinctive -%D typeface, another way is using color. -%D -%D There are two colors involved: one for normal hyperlinks, -%D and one for those that point to the currentpage, the -%D contrast color. - -\definecolor [interactioncolor] [r=0, g=.6, b=0] -\definecolor [interactioncontrastcolor] [r=.8, g=0, b=0] - -\definecolor [interactiekleur] [interactioncolor] -\definecolor [interactiecontrastkleur] [interactioncontrastcolor] - -%D The next few macros are responsible for highlighting hyper -%D links. The first one, \type{\showlocation}, is used in those -%D situations where the typeface is handled by the calling -%D macro. - -\def\interactioncolor % todo \??ia as argument - {\iflocation - \ifrealreferencepage - \@@iacontrastcolor - \else - \@@iacolor - \fi - \fi} - -%D CHECK WHERE USED / CONSISTENCY - -\def\showlocation#1% - {\iflocation\color[\@@iacolor]{#1\presetgoto}\else#1\fi} - -%D When local color settings are to be used, we can use the -%D next macro, where \type{#1} is a tag like \type{\??tg} and -%D \type{#2} some text. - -\def\showcoloredlocation#1#2% - {\iflocation - \color[\getvalue{#1\c!color}]{#2\presetgoto}% - \else - #2% - \fi} - -%D When we're dealing with pure page references, contrast -%D colors are used when we are already at the page mentioned. - -\def\showcontrastlocation#1#2#3% the \@EA is needed - {\iflocation - \ifnum#2=\realpageno\relax - \doifelsevaluenothing{#1\c!color} - {#3\presetgoto} - {\color[\getvalue{#1\c!contrastcolor}]{#3\presetgoto}}% - \else - \color[\getvalue{#1\c!color}]{#3\presetgoto}% - \fi - \else - #3% - \fi} - -%D The next simple macro can be used in color specifications, -%D like \type{\color[\locationcolor{green}]}. - -\def\locationcolor#1% - {\iflocation#1\fi} - -%D More tokens are spend when we want both typeface and color -%D highlighting. - -\def\dolocationattributes#1#2#3#4% - {\bgroup - \let\fontattribute\empty - \let\colorattribute\empty - \doifdefined{#1#2}{\def\fontattribute{\getvalue{#1#2}}}% - \iflocation - \doifdefined{#1#3}{\def\colorattribute{\getvalue{#1#3}}}% - \fi - \startcolor[\colorattribute]% - \@EA\doconvertfont\@EA{\fontattribute}{#4}% no \edef, but \@EA here - \stopcolor - \egroup} - -\def\navigating - {\dolocationattributes\??ia\c!style\c!color} - -%D Although not decently supported in current viewers, a -%D provisory hiding mechanims is implemented. Areas marked as -%D such, are visible on screen, but invisible on paper. Don't -%D trust this mechanism yet! - -\def\dostartinteraction - {\bgroup - \let\stopinteraction\egroup - \dowithnextbox{\dostarthide\flushnextbox\dostophide\egroup}\hbox} - -\let\startinteraction = \relax -\let\stopinteraction = \relax - -% in the future: -% -% eerst boolean invoeren bij menu, achtergrond, balk, button -% enz; verder startinteractie een argument meegeven {#1} -> -% \getvalue{#1\c!print}=={\v!ja} enz. Consequent menubutton -% gebruiken! - -\def\@@iatimestamp - {\the\normalyear - \ifnum\normalmonth<10 0\fi\the\normalmonth - \ifnum\normalday <10 0\fi\the\normalday} - -% happens in core-fld -% -% \definereference [AtOpenInitializeForm] [\v!geen] - -\setupinteraction % start fit page and reset form - [\c!state=\v!stop, - \c!page=\v!no, - \c!click=\v!yes, - \c!display=, - %\c!openaction={\v!firstpage,AtOpenInitializeForm}, - %\c!openaction={\v!firstpage,\v!ResetForm}, - %\c!openaction=\v!ResetForm, % too buggy in reader 4.05 - \c!openaction=, - \c!closeaction=, - \c!openpageaction=, - \c!closepageaction=, - \c!display=\v!normal, - \c!focus=\v!fit, - \c!menu=\v!off, - \c!style=\v!bold, - \c!calculate=, - \c!strut=\v!yes, - \c!split=\v!yes, - \c!color=interactioncolor, - \c!contrastcolor=interactioncontrastcolor, - \c!symbolset=, - \c!width=1em, - \c!height=\!!zeropoint, - \c!depth=\!!zeropoint, - \c!title=\jobname, % needed for fdf/x - \c!subtitle=, - \c!author=, - \c!keyword=, - \c!date=\@@iatimestamp] - -\protect \endinput diff --git a/tex/context/base/core-not.tex b/tex/context/base/core-not.tex deleted file mode 100644 index 70d3f8627..000000000 --- a/tex/context/base/core-not.tex +++ /dev/null @@ -1,1440 +0,0 @@ -%D \module -%D [ file=core-not, -%D version=2002.05.10, % 1997.09.15 -%D title=\CONTEXT\ Core 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 Core 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} - -\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/core-num.tex b/tex/context/base/core-num.tex deleted file mode 100644 index a86ce8a1d..000000000 --- a/tex/context/base/core-num.tex +++ /dev/null @@ -1,151 +0,0 @@ -%D \module -%D [ file=core-num, -%D version=1997.03.31, -%D title=\CONTEXT\ Core 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 Core 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/core-obj.lua b/tex/context/base/core-obj.lua deleted file mode 100644 index f879ddc8c..000000000 --- a/tex/context/base/core-obj.lua +++ /dev/null @@ -1,54 +0,0 @@ -if not modules then modules = { } end modules ['core-obj'] = { - version = 1.001, - comment = "companion to core-obj.tex", - 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 = tex.sprint - -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/core-obj.mkii b/tex/context/base/core-obj.mkii deleted file mode 100644 index 6e210a0ab..000000000 --- a/tex/context/base/core-obj.mkii +++ /dev/null @@ -1,371 +0,0 @@ -%D \module -%D [ file=core-obj, -%D version=1998.01.15, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Object Handling, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% todo, move more to mkiv, get rid of blabelgroup - -\writestatus{loading}{ConTeXt Core Macros / Object Handling} - -\unprotect - -%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/core-obj.mkiv b/tex/context/base/core-obj.mkiv deleted file mode 100644 index 560a7012d..000000000 --- a/tex/context/base/core-obj.mkiv +++ /dev/null @@ -1,234 +0,0 @@ -%D \module -%D [ file=core-obj, -%D version=1998.01.15, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Object Handling, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Object Handling} - -\unprotect - -\let\objectreference\gobblefourarguments % catch mkii tuo stuff - -\registerctxluafile{core-obj}{1.001} - -%D \macros -%D {setobject,getobject,ifinobject} -%D -%D Boxes can be considered reuable objects. Unfortunaltely once -%D passed to the \DVI\ file, such objects cannot be reused. In -%D \PDF\ however, reusing is possible and sometimes even a -%D necessity. Therefore, \CONTEXT\ supports reusable objects. -%D -%D During the \TEX\ processing run, boxes can serve the purpose -%D of objects, and the \DVI\ driver module implements objects -%D using packed boxes. -%D -%D The \PDF\ and \PDFTEX\ driver modules implement objects -%D using \PDF\ forms. There is no (real) restriction on the -%D number of objects there. -%D -%D The first application of objects in \CONTEXT\ concerned -%D \METAPOST\ graphics and fill||in form fields. The first -%D application can save lots of bytes, while the latter use is -%D more a necessity than byte saving. -%D -%D \starttyping -%D \setobject{class}{name}\somebox{} -%D \getobject{class}{name} -%D \stoptyping -%D -%D Here \type{\somebox} can be whatever box specification suits -%D \TEX. We save the dimensions of an object, although some -%D drivers will do so themselves. This means that when for -%D instance using \PDFTEX\ we could save a hash entry plus some -%D 20+ memory locations per object by delegating this -%D housekeeping to the driver. The current approach permits -%D us to keep the box characteristic too. - -\newif\ifinobject - -\def\objectplaceholder{NOT YET FLUSHED}% - -\def\presetobject#1#2% \global added - {\ifcsname\r!object#1::#2\endcsname\else - \global\@EA\let\csname\r!object#1::#2\endcsname\objectplaceholder - \fi} - -\def\dosetobject#1#2#3% \initializepaper this will move to \everyshipout - {\initializepaper - \ifcsname\r!object#2::#3\endcsname - \expandafter\gobblefivearguments - \else % tzt, overload internal referenced objects to save entries - \expandafter\dodosetobject - \fi - {#1}{#2}{#3}} - -\def\resetobject#1#2% - {\letbeundefined{\r!object#1::#2}} - -%D \macros -%D {finalizeobjectbox} -%D -%D This one provides a hook for last minute object box processing -%D we need this in \MKIV. - -\ifx\finalizeobjectbox\undefined - \let\finalizeobjectbox\gobbleoneargument -\fi - -%D Somehow there is a rounding error problem in either \PDFTEX\ -%D or in viewers, or maybe it is conforming the specs. The next -%D variable compensate for it by removing the rather tight -%D clip. - -\def\objectoffset{1cm} - -\def\dodosetobject#1#2#3% - {\bgroup - \globalpushmacro\crossreferenceobject \objectreferenced - \inobjecttrue - \dowithnextbox - {\globalpopmacro\crossreferenceobject - \dododosetobject{#1}{#2}{#3}\egroup}} - -\def\dododosetobject#1#2#3% - {\begingroup - \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox - \scratchdimen\objectoffset - \@EA\xdef\csname\r!object#2::#3\endcsname - {\noexpand\dohandleobject{#2}{#3}% - {\ifhbox\nextbox\hbox\else\vbox\fi}% - {\number\nextboxwd}{\number\nextboxht}{\number\nextboxdp}% - {\number\scratchdimen}}% - \expanded % freeze the dimensions since \dostartobject may use \nextbox - {\dostartobject{#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}% - \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint - \setbox\nextbox\vbox spread 2\scratchdimen - {\forgetall \offinterlineskip - \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}% - \fi \fi - \flushnextbox - \dostopobject - \endgroup} - -\def\getobject#1#2% - {\begingroup - \let\dohandleobject\dogetobject - \csname\r!object#1::#2\endcsname} - -\def\dogetobject#1#2#3#4#5#6#7% don't change this, should work for dvi & pdf - {\initializepaper - \forgetall - \dontshowcomposition - \setbox\scratchbox\vbox - {\doinsertobject{#1}{#2}}% - \setbox\scratchbox#3% - {\vbox to #5\scaledpoint - {\ifdim\ht\scratchbox>#5\scaledpoint - \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss - \else\ifdim\wd\scratchbox>#4\scaledpoint - \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss - \else - %\vss\box\scratchbox - \vss\hbox to #4\scaledpoint{\box\scratchbox\hss}% fix Chof - \fi\fi}}% - \box\scratchbox - \endgroup} - -%D If needed one can ask for the dimensions of an object with: -%D -%D \starttyping -%D \getobjectdimensions{class}{name} -%D \stoptyping -%D -%D The results are reported in \type {\objectwidth}, \type -%D {\objectheight} and \type {\objectdepth}. - -\def\dogetobjectdimensions#1#2#3#4#5#6#7% - {\def\objectwidth {#4\s!sp}% - \def\objectheight{#5\s!sp}% - \def\objectdepth {#6\s!sp}% - \def\objectmargin{#7\s!sp}} - -\def\getobjectdimensions#1#2% - {\let\dohandleobject\dogetobjectdimensions - \let\objectwidth \!!zeropoint - \let\objectheight\!!zeropoint - \let\objectdepth \!!zeropoint - \labelcsname\r!object#1::#2\endcsname} - -%D Apart from this kind of objects, that have typeset content, -%D we can have low level driver specific objects. Both types -%D can have references to internal representations, hidden for -%D the user. We keep track of such references by means of a -%D dedicated cross reference mechanism. Normally, objects are -%D defined before they are used, but forward referencing -%D sometimes occurs. -%D -%D \starttyping -%D \dosetobjectreference {class} {identifier} {reference value} {page} -%D \dogetobjectreference {class} {identifier} \csname -%D \stoptyping -%D -%D These commands are to be called by the \type{\startobject}, -%D \type{\stopobject} and \type{\insertobject} specials. - -\def\objectreferenced{\global\chardef\crossreferenceobject\plusone} -\def\driverreferenced{\global\chardef\crossreferenceobject\zerocount} - -\objectreferenced - -% no undefined test ! ! ! ! (pdftex fails on undefined objects) - -\def\doregisterobjectreference#1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobobjects.save("#1::#2",#3,\noexpand\the\realpageno)}}} -\def\dooverloadobjectreference#1#2#3{\ctxlua{jobobjects.set("#1::#2",#3,\the\realpageno)}} - -\def\dosetobjectreference - {\ifcase\crossreferenceobject - \objectreferenced - \expandafter\dooverloadobjectreference - \else - \expandafter\doregisterobjectreference - \fi} - -\def\dosetdriverreference - {\driverreferenced\dosetobjectreference} - -\def\defaultobjectreference#1#2{0} % driver dependent -\def\defaultobjectpage #1#2{\realfolio} - -\def\dogetobjectreference #1#2#3{\xdef#3{\ctxlua{jobobjects.number("#1::#2","\defaultobjectreference{#1}{#2}")}}} -\def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxlua{jobobjects.page("#1::#2","\defaultobjectpage{#1}{#2}")}}} - -\def\setobject {\driverreferenced\dosetobject1} -\def\settightobject{\driverreferenced\dosetobject0} - -%D \macros -%D {doifobjectfoundelse,doifobjectreferencefoundelse} -%D -%D To prevent redundant definition of objects, one can use -%D the next tests: -%D -%D \starttyping -%D \doifobjectfoundelse{class}{object}{do then}{do else} -%D \doifobjectreferencefoundelse{class}{object}{do then}{do else} -%D \stoptyping - -\def\doifobjectfoundelse#1#2% - {\ifcsname\r!object#1::#2\endcsname - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\doifobjectreferencefoundelse#1#2{\ctxlua{jobobjects.doifelse("#1::#2")}} - -\protect \endinput diff --git a/tex/context/base/core-pgr.tex b/tex/context/base/core-pgr.tex deleted file mode 100644 index ab2378441..000000000 --- a/tex/context/base/core-pgr.tex +++ /dev/null @@ -1,1687 +0,0 @@ -%D \module -%D [ file=core-pgr, % split off core-pos -%D version=1999.08.01, -%D title=\CONTEXT\ Core 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 Core Macros / Positioning Grapics} - -%D Before we come to graphics support, we have to make sure of -%D the reference point on the page. The next macro does so and -%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} -\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 - \global\positioningtrue - \global\positioningpartrue - \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 - \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/core-pos.lua b/tex/context/base/core-pos.lua deleted file mode 100644 index be2ac1915..000000000 --- a/tex/context/base/core-pos.lua +++ /dev/null @@ -1,107 +0,0 @@ -if not modules then modules = { } end modules ['core-pos'] = { - version = 1.001, - comment = "companion to core-pos.tex", - 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 texprint, concat, format = tex.print, table.concat, string.format - -jobpositions = jobpositions or { } -jobpositions.collected = jobpositions.collected or { } -jobpositions.tobesaved = jobpositions.tobesaved or { } - --- these are global since they are used often at the tex end - -ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -- global - -local function initializer() - ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -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((jpi and jpi[1]) or '0' ) end -function jobpositions.MPx(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[2]) or '0pt') end -function jobpositions.MPy(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[3]) or '0pt') end -function jobpositions.MPw(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[4]) or '0pt') end -function jobpositions.MPh(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[5]) or '0pt') end -function jobpositions.MPd(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[6]) or '0pt') end - --- the following are only for MP so there we can leave out the pt - -function jobpositions.MPxy(id) - local jpi = pcol[id] or ptbs[id] - if jpi then - texprint(format('(%s,%s)',jpi[2],jpi[3])) - else - texprint('(0,0)') - end -end -function jobpositions.MPll(id) - local jpi = pcol[id] or ptbs[id] - if jpi then - texprint(format('(%s,%s-%s)',jpi[2],jpi[3],jpi[6])) - else - texprint('(0,0)') - end -end -function jobpositions.MPlr(id) - local jpi = pcol[id] or ptbs[id] - if jpi then - texprint(format('(%s+%s,%s-%s)',jpi[2],jpi[4],jpi[3],jpi[6])) - else - texprint('(0,0)') - end -end -function jobpositions.MPur(id) - local jpi = pcol[id] or ptbs[id] - if jpi then - texprint(format('(%s+%s,%s+%s)',jpi[2],jpi[4],jpi[3],jpi[5])) - else - texprint('(0,0)') - end -end -function jobpositions.MPul(id) - local jpi = pcol[id] or ptbs[id] - if jpi then - texprint(format('(%s,%s+%s)',jpi[2],jpi[3],jpi[5])) - else - texprint('(0,0)') - end -end -function jobpositions.MPpos(id) - local jpi = pcol[id] or ptbs[id] - if jpi then - texprint(concat(jpi,',',1,6)) - else - texprint('0,0,0,0,0,0') - end -end -function jobpositions.MPplus(id,n,default) - local jpi = pcol[id] or ptbs[id] - texprint((jpi and jpi[6+n]) or default) -end -function jobpositions.MPrest(id,default) - local jpi = pcol[id] or ptbs[id] - texprint((jpi and jpi[7] and concat(jpi,",",7,#jpi)) or default) -end diff --git a/tex/context/base/core-pos.mkii b/tex/context/base/core-pos.mkii deleted file mode 100644 index 58784ed7b..000000000 --- a/tex/context/base/core-pos.mkii +++ /dev/null @@ -1,873 +0,0 @@ -%D \module -%D [ file=core-pos, -%D version=1999.08.01, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Positioning Support, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% needs a cleanup, things may change; we also need to move the mp -% related code to meta-pos - -% shorter tags, ..:achtergrond:.. etc in pos actions - -% dubbele text- * pos's eruit - -% class pos -> als gelijk aan vorige, dan niet niet definieren -% en erven, maw: -% -% 1 -> opslaan -% 2 -> undef, dus == prev -% 3 -> undef, dus == prev -% 4 -> opslaan - -\writestatus{loading}{ConTeXt Core Macros / Positioning Support} - -% todo: topskip als optie voor eerste regel achtergrond -% todo: build pos layers on top of layers -% todo: positionlayer pos van text-1 etc delen - -%D Although \TEX\ has a rather powerful channel to the outside -%D world, called \type {\special}, real communication with -%D other programs is complicated by the fact that no positional -%D information is available. Mid 1999, I discussed this with -%D \THANH, the author of \PDFTEX, and after some experiments, -%D \PDFTEX\ was extended with a simple but effective mechanism, -%D that provided positional information. The interesting -%D thought is that, although \TEX\ is frozen, similar -%D functionality could have been achieved with \type -%D {\specials} and an additional \DVI\ postprocessor. -%D -%D Since we want to be as compatible as can be, \CONTEXT\ will -%D support both methods, although the development is primarily -%D driven by the \PDFTEX\ way of doing things. Since the -%D mechanism is basically not limited to one application, for -%D the moment we stick to building the functionality around one -%D \CONTEXT\ special command, but at the same time we keep our -%D eyes open for extensions in other directions. -%D -%D A question that may arise when one reads this module, is to -%D what extend these macros are generic, in the sense that they -%D could be collected in a support module instead of a core -%D module. Since the mechanism described here will closely -%D cooperate with the \METAPOST\ support built in \CONTEXT, -%D which in turn will be tightly integrated with the \CONTEXT\ -%D overlay mechanisms, I decided to write a core module instead -%D of a support one. This makes even more sense, when one takes -%D into account that this kind of support depends on special -%D drivers. - -\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\registerparoptions - {\ifpositioningpar \ifpositioning \iftrialtypesetting \else - \ifinpagebody \else \ifmmode \else \ifinformula \else - \ifprocessingverbatim - \iflinepar \doregisterparoptions \fi - \else - \doregisterparoptions - \fi - \fi \fi \fi - \fi \fi \fi} - -\chardef\parposstrut=1 % 0 => no strut data, so fall backs used - -\newif\iftracepositions - -% \def\doregisterparoptions -% {\global\advance\parposcounter\plusone -% \begingroup -% \leftskip 1\leftskip -% \rightskip1\rightskip -% \setpositiondataplus -% {p:\number\parposcounter}% identifier -% {\the\zeropoint}% -% {\the\strutht}% -% {\the\strutdp}% -% {\the\hsize ,% 1 -% \the\leftskip ,% 2 -% \the\rightskip ,% 3 -% \the\hangindent,% 4 -% \the\hangafter ,% 5 (num) -% \the\parindent }% 6 -% %\normalhbox{\registerparsymbol}% -% \registerparsymbol -% \endgroup} - -\def\doregisterparoptions - {\global\advance\parposcounter\plusone - \setpositiondataplus - {p:\number\parposcounter}% identifier - {\the\zeropoint}% - {\the\strutht}% - {\the\strutdp}% - {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}% - %\normalhbox{\registerparsymbol}% - \iftracepositions\registerparsymbol\fi} - -\def\traceposstring#1#2#3% - {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi} - -\def\registerparsymbol - {\iftracepositions - \smashedhbox to \zeropoint - {\hss - \startcolor[blue]% - \llap{\infofont\number\parposcounter}% - \scratchdimen\onepoint - \vrule - \!!width 4\scratchdimen - \!!height2\scratchdimen - \!!depth 2\scratchdimen - \stopcolor - \hss}% - \fi} - -% \appendtoks \registerparoptions \to \everypar - -%D Eperimental code, don't use this yet: (must be sped up anyway) - -\def\@@noden{node:n:} -\def\@@nodeo{node:o:} -\def\@@nodep{node:p:} - -\def\doifelsenodelocation#1% - {\ifcsname\@@noden#1\endcsname - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\nextnodelocation#1% - {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi} - -\def\newnodelocation#1% - {\ifcsname\@@noden#1\endcsname - \setcounter{\@@noden#1}\zerocount - \letgvalue {\@@nodeo#1}\!!zerocount - \fi} - -\def\tagnodelocation#1% - {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi} - -\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}} -\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}} -\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}} - -\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}} -\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}} -\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}} - -\def\getnodelocationn#1{\countervalue{\@@noden#1}} -\def\getnodelocationo#1{\getvalue {\@@nodeo#1}} - -\chardef\nodelocationmode\plusone - -\def\analyzenodelocation#1% - {\ifcsname\@@noden#1\endcsname - \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount - \fi} - -\def\doanalyzenodelocation#1#2#3% class n default - {\begingroup - \donefalse - \ifcase\nodelocationmode - % do nothing - \else - \edef\nodelocationselfn{#2}% - \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}% - \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}% - \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}% - \scratchcounter\plusone - \doloop - {\ifnum\recurselevel=\nodelocationselfn\relax - \donetrue - \else - \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}% - \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}% - \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}% - \ifcase\nodelocationmode - \or - % ok for single column - \ifcase\nodelocationotherp\relax - \exitloop - \else\ifnum\nodelocationotherp<\nodelocationselfp\relax - \donetrue \advance\scratchcounter\plusone - \else\ifnum\nodelocationotherp>\nodelocationselfp\relax - % skip - \else\ifdim\nodelocationothery>\nodelocationselfy\relax - \donetrue \advance\scratchcounter\plusone - \else\ifdim\nodelocationothery<\nodelocationselfy\relax - % skip - \else\ifdim\nodelocationotherx<\nodelocationselfx\relax - \donetrue \advance\scratchcounter\plusone - \fi\fi\fi\fi\fi\fi - \or - % acceptable for double column - \ifcase\nodelocationotherp\relax - \exitloop - \else\ifnum\nodelocationotherp<\nodelocationselfp\relax - \donetrue \advance\scratchcounter\plusone - \else\ifnum\nodelocationotherp>\nodelocationselfp\relax - % skip - \else\ifnum\recurselevel>\nodelocationselfn\relax - \donetrue \exitloop - \else - \donetrue \advance\scratchcounter\plusone - \fi\fi\fi\fi - \else - \exitloop - \fi - \fi}% - \fi - \ifdone \else - \scratchcounter#3\relax - \fi - \setxvalue{\@@nodeo#1}{\the\scratchcounter}% - \endgroup} - -\unexpanded\def\shownodelocation#1% - {\ifcsname\@@noden#1\endcsname - \analyzenodelocation{#1}% - (#1,% - n:\getnodelocationn{#1},% - p:\getnodelocationp{#1},% - x:\getnodelocationx{#1},% - y:\getnodelocationy{#1},% - o:\getnodelocationo{#1})% - \fi} - -%D \macros -%D {doifoverlappingelse} -%D -%D A first application of positional information, is to -%D determine if two boxes do overlap: -%D -%D \starttyping -%D \doifoverlappingelse{point a}{point b} -%D {action when overlapping} -%D {action when not overlapping} -%D \stoptyping - -\def\overlappingmargin{-2\scaledpoint} - -\def\doifoverlappingelse#1#2% - {\begingroup - \donefalse - \edef\!!stringa{#1}\edef\!!stringb{#2}% - \ifnum\MPp\!!stringa=\MPp\!!stringb\relax - \!!dimena\MPx\!!stringa - \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax - \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax - \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax - \!!dimene\MPx\!!stringb - \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax - \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax - \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax - \ifdim\overlappingmargin=\zeropoint\else - \advance\!!dimena-\overlappingmargin - \advance\!!dimenb+\overlappingmargin - \advance\!!dimenc-\overlappingmargin - \advance\!!dimend+\overlappingmargin - \advance\!!dimene-\overlappingmargin - \advance\!!dimenf+\overlappingmargin - \advance\!!dimeng-\overlappingmargin - \advance\!!dimenh+\overlappingmargin - \fi - % more often eh fb eg fg - \def\checkone##1##2% - {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else - \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else - \donetrue - \fi\fi - \fi\fi}% - \def\checktwo##1##2% - {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else - \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else - \donetrue - \fi\fi - \fi\fi}% - \checkone\!!dimene\!!dimeng \ifdone \else - \checkone\!!dimene\!!dimenh \ifdone \else - \checkone\!!dimenf\!!dimeng \ifdone \else - \checkone\!!dimenf\!!dimenh \ifdone \else - \checktwo\!!dimena\!!dimenc \ifdone \else - \checktwo\!!dimena\!!dimend \ifdone \else - \checktwo\!!dimenb\!!dimene \ifdone \else - \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi - \fi - \ifdone - \endgroup\expandafter\firstoftwoarguments - \else - \endgroup\expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doifpositionsonsamepageelse, -%D doifpositionsonthispageelse} -%D -%D Instead of letting the user handle fuzzy expansion, we -%D provide a simple test on positione being on the same page. -%D -%D \starttyping -%D \doifpositionsonsamepageelse{point a}{point b} -%D {action when on same page} -%D {action when not on same page} -%D \doifpositionsonthispageelse{point a}{point b} -%D {action when on this page} -%D {action when not on this page} -%D \stoptyping - -\def\dodoifpositionsonsamepageelse#1#2#3#4% - {\bgroup - \scratchcounter#1\donefalse - \def\docommand##1% - {\ifcase\scratchcounter - \scratchcounter\MPp{##1}\donetrue - \else - \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi - \fi}% - \rawprocesscommalist[#2]\docommand - \ifdone\egroup#3\else\egroup#4\fi} - -\def\doifpositionsonsamepageelse - {\dodoifpositionsonsamepageelse{0}} - -\def\doifpositionsonthispageelse#1#2#3% - {\dodoifpositionsonsamepageelse\realfolio} - -%D Plugins: - -\let\MPv \MPplus -\let\MPvv\MPrest - -\let\MPanchor\MPpos - -\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy -\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw - -\protect \endinput diff --git a/tex/context/base/core-pos.mkiv b/tex/context/base/core-pos.mkiv deleted file mode 100644 index 16d5b229f..000000000 --- a/tex/context/base/core-pos.mkiv +++ /dev/null @@ -1,828 +0,0 @@ -%D \module -%D [ file=core-pos, -%D version=1999.08.01, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Positioning Support, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% needs a cleanup, things may change; we also need to move the mp -% related code to meta-pos - -% shorter tags, ..:achtergrond:.. etc in pos actions - -% dubbele text- * pos's eruit - -% class pos -> als gelijk aan vorige, dan niet niet definieren -% en erven, maw: -% -% 1 -> opslaan -% 2 -> undef, dus == prev -% 3 -> undef, dus == prev -% 4 -> opslaan - -\writestatus{loading}{ConTeXt Core Macros / Positioning Support} - -% 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{core-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. - -% TO BE MERGED - -\def\dolazysaveposition #1#2#3#4{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4"}}}} -\def\dolazysavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}} -\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\dosetposition#1% -% {\pdfsavepos -% \dolazysaveposition -% {#1}% -% {\noexpand\realfolio}% -% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}% -% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}}% -% -% \def\dosetpositionwhd#1#2#3#4% -% {\pdfsavepos -% \dolazysavepositionwhd -% {#1}% -% {\noexpand\realfolio}% -% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}% -% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}% -% {#2}{#3}{#4}} -% -% \def\dosetpositionplus#1#2#3#4#5% -% {\pdfsavepos -% \dolazysavepositionplus -% {#1}% -% {\noexpand\realfolio}% -% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}% -% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}% -% {#2}{#3}{#4}{#5}} - -\def\lastsavedpositionx {\the\dimexpr\pdflastxpos\scaledpoint\relax} -\def\lastsavedpositiony {\the\dimexpr\pdflastypos\scaledpoint\relax} -\let\savecurrentposition\pdfsavepos - -\def\dosetposition#1% - {\savecurrentposition - \normalexpanded{\ctxlatelua{ptbs['#1']={% - \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony"}}}} - -\def\dosetpositionwhd#1#2#3#4% - {\savecurrentposition - \normalexpanded{\ctxlatelua{ptbs['#1']={% - \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4"}}}} - -\def\dosetpositionplus#1#2#3#4#5% - {\savecurrentposition - \normalexpanded{\ctxlatelua{ptbs['#1']={% - \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4","#5"}}}} - -\let\dosetpositionpapersize\gobbletwoarguments - -\newbox\positionbox -\newif \ifpositioning - -\def\POSprefix{POS::} - -\let\setpospx \gobblefourarguments % suppress errors with mkii tuo file -\let\setpospxywhd \gobblesevenarguments % suppress errors with mkii tuo file -\let\setpospxyplus\gobbleeightarguments % suppress errors with mkii tuo file - -%D This is real tricky! The page anchor is applied to the -%D page box and therefore flushed first. So, when present, it -%D is applied to all positions except itself. - -\chardef\positionanchormode=0 % don't relocate page origin -\chardef\positionanchormode=1 % relocate page origin once - -%D The core set macros. - -\let\pospxy \gobblefourarguments -\let\pospxywhd \gobblesevenarguments -\let\pospxyplus\gobbleeightarguments - -%D Sometimes we want to trick the position handler a bit: - -\def\replacepospxywhd#1#2#3#4#5#6#7{\ctxlua{jobpositions.replace('#1',\number#2,"\the\dimexpr#3\relax","\the\dimexpr#4\relax","\the\dimexpr#5\relax","\the\dimexpr#6\relax","\the\dimexpr#7\relax")}} - -%D For postprocessing purposes, we save the number of -%D positions. - -\newcount\currentpositions % current number of positions -\newcounter\totalnofpositions % total from previous run - -\appendtoks - \expanded{\savecurrentvalue\noexpand\totalnofpositions{\the\currentpositions}}% -\to \everybye - -%D The next switch can be used to communicate a special -%D situation. Positioning and associated actions can be -%D executed any time. However, in for instance backgrounds -%D they can be collected in a layer, for instance the text -%D layer (especially the hidden text layer). In the case of -%D floats, we run into problems, since the page information is -%D not applicable when the content floats indeed. In such -%D situations one can treat positions and graphics local. - -\newif\iflocalpositioning - -%D Watch out: sometimes a pagebreak occurs inside a float -%D placement, so there we need to disable local mode. - -\appendtoks - \localpositioningtrue -\to \everyinsidefloat - -\appendtoks - \localpositioningfalse -\to \everypagebody - -\def\checkpositions - {\startnointerference - \protectlabels - \doutilities{positions}\jobname\empty\relax\relax - \global\let\checkpositions\relax - \stopnointerference} - -%D Since the positional values are to be fully expandable, we -%D need to preload them as soon as possible, which is why we -%D load the data when we start a text. - -\appendtoks \checkpositions \to \everystarttext - -%D \macros -%D {MPp, MPx, MPy, MPw, MPh, MPd, -%D MPxy, MPll, MPlr, MPur, MPul, MPpos} -%D -%D Access to the positional information is provided by macros -%D with short names that are clearly meant for \METAPOST. - -\def\MPp #1{\ctxlua{jobpositions.MPp("#1")}} -\def\MPx #1{\ctxlua{jobpositions.MPx("#1")}} -\def\MPy #1{\ctxlua{jobpositions.MPy("#1")}} -\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 - -% we can check for used entries, and if not, then not add one - -\def\registerparoptions - {\ifpositioningpar \ifpositioning \iftrialtypesetting \else - \ifinpagebody \else \ifmmode \else \ifinformula \else - \ifprocessingverbatim - \iflinepar \doregisterparoptions \fi - \else - \doregisterparoptions - \fi - \fi \fi \fi - \fi \fi \fi} - -\chardef\parposstrut=1 % 0 => no strut data, so fall backs used - -\newif\iftracepositions - -% \def\doregisterparoptions -% {\global\advance\parposcounter\plusone -% \begingroup -% \leftskip 1\leftskip -% \rightskip1\rightskip -% \setpositiondataplus -% {p:\number\parposcounter}% identifier -% {\the\zeropoint}% -% {\the\strutht}% -% {\the\strutdp}% -% {\the\hsize ,% 1 -% \the\leftskip ,% 2 -% \the\rightskip ,% 3 -% \the\hangindent,% 4 -% \the\hangafter ,% 5 (num) -% \the\parindent }% 6 -% %\normalhbox{\registerparsymbol}% -% \registerparsymbol -% \endgroup} - -\def\doregisterparoptions - {\global\advance\parposcounter\plusone - \setpositiondataplus - {p:\number\parposcounter}% identifier - {\the\zeropoint}% - {\the\strutht}% - {\the\strutdp}% - {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}% - %\normalhbox{\registerparsymbol}% - \iftracepositions\registerparsymbol\fi} - -\def\traceposstring#1#2#3% - {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi} - -\def\registerparsymbol - {\iftracepositions - \smashedhbox to \zeropoint - {\hss - \startcolor[blue]% - \llap{\infofont\number\parposcounter}% - \scratchdimen\onepoint - \vrule - \!!width 4\scratchdimen - \!!height2\scratchdimen - \!!depth 2\scratchdimen - \stopcolor - \hss}% - \fi} - -% \appendtoks \registerparoptions \to \everypar - -%D Eperimental code, don't use this yet: (must be sped up anyway) - -\def\@@noden{node:n:} -\def\@@nodeo{node:o:} -\def\@@nodep{node:p:} - -\def\doifelsenodelocation#1% - {\ifcsname\@@noden#1\endcsname - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\nextnodelocation#1% - {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi} - -\def\newnodelocation#1% - {\ifcsname\@@noden#1\endcsname - \setcounter{\@@noden#1}\zerocount - \letgvalue {\@@nodeo#1}\!!zerocount - \fi} - -\def\tagnodelocation#1% - {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi} - -\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}} -\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}} -\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}} - -\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}} -\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}} -\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}} - -\def\getnodelocationn#1{\countervalue{\@@noden#1}} -\def\getnodelocationo#1{\getvalue {\@@nodeo#1}} - -\chardef\nodelocationmode\plusone - -\def\analyzenodelocation#1% - {\ifcsname\@@noden#1\endcsname - \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount - \fi} - -\def\doanalyzenodelocation#1#2#3% class n default - {\begingroup - \donefalse - \ifcase\nodelocationmode - % do nothing - \else - \edef\nodelocationselfn{#2}% - \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}% - \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}% - \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}% - \scratchcounter\plusone - \doloop - {\ifnum\recurselevel=\nodelocationselfn\relax - \donetrue - \else - \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}% - \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}% - \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}% - \ifcase\nodelocationmode - \or - % ok for single column - \ifcase\nodelocationotherp\relax - \exitloop - \else\ifnum\nodelocationotherp<\nodelocationselfp\relax - \donetrue \advance\scratchcounter\plusone - \else\ifnum\nodelocationotherp>\nodelocationselfp\relax - % skip - \else\ifdim\nodelocationothery>\nodelocationselfy\relax - \donetrue \advance\scratchcounter\plusone - \else\ifdim\nodelocationothery<\nodelocationselfy\relax - % skip - \else\ifdim\nodelocationotherx<\nodelocationselfx\relax - \donetrue \advance\scratchcounter\plusone - \fi\fi\fi\fi\fi\fi - \or - % acceptable for double column - \ifcase\nodelocationotherp\relax - \exitloop - \else\ifnum\nodelocationotherp<\nodelocationselfp\relax - \donetrue \advance\scratchcounter\plusone - \else\ifnum\nodelocationotherp>\nodelocationselfp\relax - % skip - \else\ifnum\recurselevel>\nodelocationselfn\relax - \donetrue \exitloop - \else - \donetrue \advance\scratchcounter\plusone - \fi\fi\fi\fi - \else - \exitloop - \fi - \fi}% - \fi - \ifdone \else - \scratchcounter#3\relax - \fi - \setxvalue{\@@nodeo#1}{\the\scratchcounter}% - \endgroup} - -\unexpanded\def\shownodelocation#1% - {\ifcsname\@@noden#1\endcsname - \analyzenodelocation{#1}% - (#1,% - n:\getnodelocationn{#1},% - p:\getnodelocationp{#1},% - x:\getnodelocationx{#1},% - y:\getnodelocationy{#1},% - o:\getnodelocationo{#1})% - \fi} - -%D \macros -%D {doifoverlappingelse} -%D -%D A first application of positional information, is to -%D determine if two boxes do overlap: -%D -%D \starttyping -%D \doifoverlappingelse{point a}{point b} -%D {action when overlapping} -%D {action when not overlapping} -%D \stoptyping - -\def\overlappingmargin{-2\scaledpoint} - -\def\doifoverlappingelse#1#2% - {\begingroup - \donefalse - \edef\!!stringa{#1}\edef\!!stringb{#2}% - \ifnum\MPp\!!stringa=\MPp\!!stringb\relax - \!!dimena\MPx\!!stringa - \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax - \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax - \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax - \!!dimene\MPx\!!stringb - \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax - \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax - \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax - \ifdim\overlappingmargin=\zeropoint\else - \advance\!!dimena-\overlappingmargin - \advance\!!dimenb+\overlappingmargin - \advance\!!dimenc-\overlappingmargin - \advance\!!dimend+\overlappingmargin - \advance\!!dimene-\overlappingmargin - \advance\!!dimenf+\overlappingmargin - \advance\!!dimeng-\overlappingmargin - \advance\!!dimenh+\overlappingmargin - \fi - % more often eh fb eg fg - \def\checkone##1##2% - {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else - \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else - \donetrue - \fi\fi - \fi\fi}% - \def\checktwo##1##2% - {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else - \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else - \donetrue - \fi\fi - \fi\fi}% - \checkone\!!dimene\!!dimeng \ifdone \else - \checkone\!!dimene\!!dimenh \ifdone \else - \checkone\!!dimenf\!!dimeng \ifdone \else - \checkone\!!dimenf\!!dimenh \ifdone \else - \checktwo\!!dimena\!!dimenc \ifdone \else - \checktwo\!!dimena\!!dimend \ifdone \else - \checktwo\!!dimenb\!!dimene \ifdone \else - \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi - \fi - \ifdone - \endgroup\expandafter\firstoftwoarguments - \else - \endgroup\expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doifpositionsonsamepageelse, -%D doifpositionsonthispageelse} -%D -%D Instead of letting the user handle fuzzy expansion, we -%D provide a simple test on positione being on the same page. -%D -%D \starttyping -%D \doifpositionsonsamepageelse{point a}{point b} -%D {action when on same page} -%D {action when not on same page} -%D \doifpositionsonthispageelse{point a}{point b} -%D {action when on this page} -%D {action when not on this page} -%D \stoptyping - -\def\dodoifpositionsonsamepageelse#1#2#3#4% - {\bgroup - \scratchcounter#1\donefalse - \def\docommand##1% - {\ifcase\scratchcounter - \scratchcounter\MPp{##1}\donetrue - \else - \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi - \fi}% - \rawprocesscommalist[#2]\docommand - \ifdone\egroup#3\else\egroup#4\fi} - -\def\doifpositionsonsamepageelse - {\dodoifpositionsonsamepageelse{0}} - -\def\doifpositionsonthispageelse#1#2#3% - {\dodoifpositionsonsamepageelse\realfolio} - -%D Plugins: - -\let\MPv \MPplus -\let\MPvv\MPrest - -\let\MPanchor\MPpos - -\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy -\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw - -\protect \endinput diff --git a/tex/context/base/core-ref.tex b/tex/context/base/core-ref.tex deleted file mode 100644 index 8ca0a92bf..000000000 --- a/tex/context/base/core-ref.tex +++ /dev/null @@ -1,3038 +0,0 @@ -%D \module -%D [ file=core-ref, -%D version=1998.01.15, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Cross Referencing, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% we will merge mkii code back in here - -\writestatus{loading}{ConTeXt Core Macros / Cross Referencing} - -% todo : unknown/illegal reference no arg -% todo : +n pages check on 'samepage' (contrastcolor) - -% 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} - -%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/core-reg.tex b/tex/context/base/core-reg.tex deleted file mode 100644 index 1d139a2dc..000000000 --- a/tex/context/base/core-reg.tex +++ /dev/null @@ -1,1242 +0,0 @@ -%D \module -%D [ file=core-reg, -%D version=1999.12.27, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Register Management, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core 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} {\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/core-rul.lua b/tex/context/base/core-rul.lua deleted file mode 100644 index 6947c7f7b..000000000 --- a/tex/context/base/core-rul.lua +++ /dev/null @@ -1,42 +0,0 @@ -if not modules then modules = { } end modules ['core-rul'] = { - version = 1.001, - comment = "companion to core-rul.tex", - 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 mk.pdf.

---ldx]]-- - -function commands.doreshapeframedbox(n) - local noflines, lastlinelength = 0, 0 - if tex.wd[n] ~= 0 then - local hpack, free, copy = node.hpack, node.free, node.copy_list - local noflines, width, done = 0, 0, false - local list = tex.box[n].list - for h in node.traverse_id('hlist',list) do - done = true - local p = hpack(copy(h.list)) - lastlinelength = p.width - if lastlinelength > width then - width = lastlinelength - end - free(p) - end - if done then - if width ~= 0 then - for h in node.traverse_id('hlist',list) do - if h.width ~= width then - h.list = hpack(h.list,width,'exactly') - h.width = width - end - end - end - tex.wd[n] = width - end - end - tex.dimen["framedlastlength"] = lastlinelength - tex.count["framednoflines"] = noflines -end diff --git a/tex/context/base/core-rul.mkii b/tex/context/base/core-rul.mkii deleted file mode 100644 index 59bfd2f3c..000000000 --- a/tex/context/base/core-rul.mkii +++ /dev/null @@ -1,3637 +0,0 @@ -%D \module -%D [ file=core-rul, -%D version=1998.10.16, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Ruled Stuff Handling, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Ruled Content Handling} - -\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\dododostartframedtext[#1][#2][#3]% #3 only passed to framed, not to framedtext - {\doifsomething{#2}{\setvalue{\??kd#1\c!location}{#2}}% does not listen to #3 - \setfalse\framedtextlocationnone - \processaction % \v!low en \v!depth are already taken ! - [\framedtextparameter{#1}\c!location] - [ \v!left=>\letvalue{\??kd#1\c!left }\relax - \letvalue{\??kd#1\c!right}\hfill, - \v!right=>\letvalue{\??kd#1\c!left }\hfill - \letvalue{\??kd#1\c!right}\relax, - \v!middle=>\letvalue{\??kd#1\c!left }\hfill - \letvalue{\??kd#1\c!right}\hfill, - \v!none=>\letvalue{\??kd#1\c!left }\relax % new - \letvalue{\??kd#1\c!right}\relax % new - \settrue\framedtextlocationnone]% - \letvalue{\??kd#1\c!location}\empty - % removed 06/2001 - % \forgetparindent - % added 06/2001 [see demo-bbv] - \localhsize\hsize \checkframedtext - % so far - \setbox\framebox\vbox - \startboxedcontent - \hsize\localhsize - % \insidefloattrue % ? better - \expanded{\switchtobodyfont[\framedtextparameter{#1}\c!bodyfont]}% - \startcolor[\framedtextparameter{#1}\c!color]% - \localframed[\??kd#1][\c!strut=\v!no,#3]% todo: use delayedstrut - \bgroup - \let\\=\endgraf - \framedtextparameter{#1}\c!inner % oud spul - \doifvalue{\??kd#1\c!depthcorrection}\v!on % new, inside box - {\bgroup - \verticalstrut - % we need \nowhitespace in case of setups setting whitespace - % nb, not safe, text vs \vbox as next - \vskip-\struttotal - \nowhitespace % na vskip ! new 20/05/2004, fails with next content being box (\scale{..}) - }% - \doinhibitblank % \blank[\v!disable]% plaatst signal -\setupindenting[\framedtextparameter{#1}\c!indenting]% - \doconvertfont{\framedtextparameter{#1}\c!style}\empty - \def\dostopframedtext{\dodostopframedtext{#1}{#2}}} - -%D The \type {none} option is handy for nested usage, as -%D in the presentation styles, where we don't want -%D interference. - -\def\dodostopframedtext#1#2% % no \baselinecorrection, see faq docs - {\endgraf - \removelastskip - \doifvalue{\??kd#1\c!depthcorrection}\v!on % local and global - {\forgetall - \vskip-\struttotal - \verticalstrut - \egroup - \forgetall - \vskip-\lineheight - % will be an option, not default - % \setbaselinecorrections - % \donegbotbaselinecorrection - \verticalstrut} - \stopboxedcontent - \stopcolor - \ifconditional\framedtextlocationnone - \egroup - \box\framebox - \else\ifinsidefloat - \egroup - \box\framebox - \else - \egroup - \doplacement[\??kd#1][\c!depthcorrection=\v!off]{\box\framebox}% - \fi\fi - \egroup} - -%D Placement can be ignored: -%D -%D \starttyping -%D \hbox to \hsize \bgroup -%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext -%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext -%D \egroup -%D -%D \hbox to \hsize \bgroup -%D \setupframedtexts[location=none]% -%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext -%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext -%D \egroup -%D \stoptyping - -%D The simple brace (or group) delimited case is typeset -%D slightly different and is not aligned. - -\def\doframedtext - {\bgroup\dodoubleempty\dodoframedtext} - -\def\dodoframedtext[#1][#2]% beware! - {\expanded{\switchtobodyfont[\getvalue{\??kd#1\c!bodyfont}]}% - \localframed[\??kd#1][\c!strut=\v!no,#2]% - \bgroup - \blank[\v!disable]% - \let\\=\endgraf - \getvalue{\??kd#1\c!inner}% % kleur naar outer level - \dostartattributes{\??kd#1}\c!style\c!color\empty - \bgroup - \aftergroup\docloseframedtext - \let\next=} - -\def\docloseframedtext - {\removelastskip - \dostopattributes - \egroup - \egroup} - -%D \macros -%D {defineframed} -%D -%D One can also define simple framed texts, using: -%D -%D \showsetup{defineframed} - -\def\defineframed - {\dodoubleempty\dodefineframed} - -\def\dodefineframed[#1][#2]% - {\iffirstargument - \setvalue{#1}{\dodoubleempty\doframed[#2]}% - \fi} - -\def\doframed[#1][#2]% - {\framed[#1,#2]} - -%D \macros -%D {textrule, starttextrule, setuptextrules} -%D -%D Putting rules before and after a paragraph is very space -%D sensitive, but the next command handles that quite well. It -%D comes in two disguises: -%D -%D \startbuffer -%D \textrule[top]{fragments} -%D \input reich -%D \textrule -%D \stopbuffer -%D -%D \bgroup \typebuffer \getbuffer \egroup -%D -%D \startbuffer -%D \setuptextrules -%D [width=90pt,distance=12pt,rulecolor=blue, -%D bodyfont=small,style=\sc,color=red] -%D -%D \starttextrule{Ship Building Tools} -%D \nl \setuptolerance[tolerant] \input materie -%D \stoptextrule -%D \stopbuffer -%D -%D \bgroup \typebuffer \getbuffer \egroup -%D -%D \startbuffer -%D \setuptextrules -%D [location=inmargin, -%D bodyfont=small,style=slantedbold] -%D -%D \starttextrule{wonderful} -%D \input tufte -%D \stoptextrule -%D \stopbuffer -%D -%D \bgroup \typebuffer \getbuffer \egroup -%D -%D The formal definition of these commands is: -%D -%D \showsetup{textrule} -%D \showsetup{starttextrule} -%D \showsetup{setuptextrules} -%D -%D The implementation looks a bit complicated due to the -%D optional arguments. - -\def\setuptextrules - {\dodoubleargument\getparameters[\??tl]} - -\def\complextextrule[#1]% if needed we can make it installable - {\let\next\dobottomtextrule - \processaction - [#1] - [ \v!top=>\let\next\dotoptextrule, - \v!middle=>\let\next\domiddletextrule, - \v!bottom=>\let\next\dobottomtextrule]% - \dosinglegroupempty\next} - -\definecomplexorsimple\textrule - -\def\simpletextrule - {\dosinglegroupempty\dounknowntextrule} - -\def\docomplextextrule#1% - {\bgroup - \advance\hsize\dimexpr-\rightskip-\leftskip\relax - \setbox\scratchbox\hbox to \hsize - {\dimen4\dimexpr .5ex+.5\linewidth\relax - \dimen6\dimexpr-.5ex+.5\linewidth\relax - \doifnothing{#1}\firstargumentfalse - \iffirstargument - \doifelse\@@tllocation\v!inmargin - {\llap{\doattributes\??tl\c!style\c!color{#1}\hskip\leftmargindistance}} - {\color[\@@tlrulecolor] - {\vrule\!!height\dimen4\!!depth\dimen6\!!width\@@tlwidth}% - \hbox spread 2\dimexpr\@@tldistance\relax - {\hss\doattributes\??tl\c!style\c!color{\strut#1}\hss}}% - \fi - \color[\@@tlrulecolor] - {\leaders\hrule\!!height\dimen4\!!depth\dimen6\hfill}}% - \ht\scratchbox\strutht - \dp\scratchbox\strutdp - \noindent\box\scratchbox -%\nobreak\verticalstrut\kern-\struttotal -% evt \witruimte - \egroup} - -\def\dotoptextrule#1% - {\page[\v!preference] % interferes - %\whitespace % no - \@@tlbefore - \docomplextextrule{#1}% -% todo, option: \doifnothing{#1}{\ruledvskip-.5ex} - \nowhitespace - \@@tlinbetween - \endgraf} - -\def\dodobottomtextrule#1#2% - {\ifhmode - \endgraf - \fi - \dimen0\strutdp - \ifdim\prevdepth>\strutdp\else % was <\strutdp - \ifdim\prevdepth>\zeropoint - \advance\dimen0 -\prevdepth - \fi - \fi - \advance\dimen0 .5ex - \vskip\dimen0 -% == -% \vskip\dimexpr \strutdp + .5ex -% \ifdim\prevdepth>\strutdp\else\ifdim\prevdepth>\zeropoint-\prevdepth\fi\fi\relax -% - \@@tlinbetween - \doifelsenothing{#2} - {\bgroup - \advance\hsize\dimexpr-\rightskip-\leftskip\relax - \nointerlineskip - \moveleft-\leftskip\vbox - {\color[\@@tlrulecolor] - {\hrule\!!depth\linewidth\!!height\zeropoint\!!width\hsize}}% - \egroup} - {\docomplextextrule{#2}}% - \ifvmode\prevdepth\zeropoint\fi - #1% - \page[\v!preference]} - -\def\dobottomtextrule - {\dodobottomtextrule\@@tlafter} - -\def\domiddletextrule - {\dodobottomtextrule\@@tlinbetween} - -\def\dounknowntextrule - {\iffirstargument - \@EA\dotoptextrule - \else - \@EA\dobottomtextrule\@EA\empty - \fi} - -%D The grouped commands also supports bodyfont switching: - -\def\starttextrule#1% - {\bgroup - \def\dounknowntextrule{\domiddletextrule} - \dotoptextrule{#1} - \bgroup - \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}} - -\def\stoptextrule - {\par - \egroup - \dobottomtextrule\empty - \egroup} - -%D \macros -%D {fillinrules, setupfillinrules} -%D -%D The next few commands do not really deserve a place in a -%D core module, because they deal with specific typography. -%D Nevertheless I decided to make them part of the core, -%D because they permit us to make questionaires. Let's start -%D with some examples. -%D -%D \fillinrules[n=2,width=fit]{first} -%D \fillinrules[n=2,width=broad]{first} -%D \fillinrules[n=2,width=3cm]{first} -%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first} -%D \fillinrules[n=2]{first}{last} -%D \fillintext{first}{last} \input reich \par -%D -%D The main command is \type{\fillinrules}. This command takes -%D one and an optional second argument and sets a paragraph with -%D empty visualized lines. -%D -%D \showsetup{fillinrules} -%D \showsetup{setupfillinrules} - -\def\setupfillinrules - {\dodoubleargument\getparameters[\??il]} - -\definecomplexorsimpleempty\fillinrules - -\def\complexfillinrules[#1]% - {\def\docomplexfillinrules##1##2% - {\dodocomplexfillinrules[#1]{##1}{##2}{\thinrules - [\c!n=\@@iln,\c!interlinespace=\@@ilinterlinespace,\c!before=,\c!after=]}}% - \dodoublegroupempty\docomplexfillinrules} - -\def\dodocomplexfillinrules[#1]#2#3#4% - {\endgraf - \@@ilbefore - \begingroup - \setupfillinrules[#1]% - \noindent - \doifsomething{#2} - {\doifelse\@@ilwidth\v!fit - {\let\@@ildistance\!!zeropoint - \hbox} - {\doifelse\@@ilwidth\v!broad - {\hbox} - {\hbox to \@@ilwidth}}% - \bgroup - \doattributes\??il\c!style\c!color{\strut#2\hfill\@@ilseparator}% - \hskip\@@ildistance - \egroup}% - %\hangindent=\wd0\relax % tzt hang=yes,n - %\parindent=\hangindent - %\box0\relax - \setupwhitespace[\v!big]% - \ignorespaces - #4% - \doifsomething{#3} - {\kern\@@ildistance - \doattributes\??il\c!style\c!color{#3\strut}}% - \endgroup - \endgraf - \@@ilafter} - -%D \macros -%D {fillintext} -%D -%D To provide compatible layouts when texts and lines are -%D mixed, one can typeset a paragraph by using the command -%D \type{\fillintext}. -%D -%D \showsetup{fillintext} - -\definecomplexorsimpleempty\fillintext - -\def\complexfillintext[#1]% rather rough, using an \unhbox is suboptimal - {\def\docomplexfillintext##1##2% - {\dowithnextbox - {\dodocomplexfillinrules[#1]{##1}{\hfill##2}{\unhbox\nextbox\unskip}}% - \hbox\bgroup\let\par\egroup\ignorespaces}% - \dodoublegroupempty\docomplexfillintext} - -%D \macros -%D {fillinline, setupfillinlines} -%D -%D Another member of the family takes care of putting a (often -%D small) rule after a piece of text, like -%D -%D \startbuffer -%D \fillinline \input reich \par -%D \fillinline[margin=0cm] \input reich \par -%D \stopbuffer -%D -%D \startvoorbeeld -%D \getbuffer -%D \stopvoorbeeld -%D -%D which was typeset by saying: -%D -%D \typebuffer -%D -%D The two commands that take care of this are: -%D -%D \showsetup{fillinline} -%D \showsetup{setupfillinlines} - -\def\setupfillinlines - {\dodoubleargument\getparameters[\??iv]} - -\definecomplexorsimpleempty\fillinline - -\def\complexfillinline[#1]% - {%\endgraf % interferes with \definedescription cum suis - \@@ivbefore - \begingroup - \setupfillinlines[#1]% - \advance\rightskip \@@ivmargin - \parfillskip\zeropoint - \def\par % very dangerous - {\let\par\endgraf % -) - \ifhmode\unskip\hfill\fi - \scratchdimen\dimexpr\@@ivwidth-\@@ivdistance\relax - \ifdim\scratchdimen>\@@ivmargin\else\expandafter\rlap\fi - {\kern\@@ivdistance - \vrule - \!!width \scratchdimen - \!!height.5\linewidth - \!!depth .5\linewidth}% - \endgraf % ! - \endgroup - \endgraf % ! - \@@ilafter}} - -%D \stopdocumentation -%D \bgroup -%D -%D \setupframedtexts -%D [setuptext] -%D [background=color,backgroundcolor=white] -%D -%D \startbuffer -%D \setupbackground -%D [backgroundoffset=4pt, -%D background=screen, -%D frame=on, -%D framecolor=red, -%D leftoffset=2pt] -%D \stopbuffer -%D -%D \getbuffer -%D -%D \startbackground -%D -%D \macros -%D {setupbackground,startbackground,background} -%D -%D The section deals with backgrounds in the running text. This -%D means that texts is to be collected and split over pages. To -%D show what can be done, we provide this part of the -%D documentation with some gray background and a red frame. -%D Both the background and frame can have all characteristics -%D of \type{\framed}. This time we used the setting: -%D -%D \typebuffer -%D -%D The implementation is not that sophisticated, but suffices. -%D The main problem with this kind of functionality is to get -%D the spacing all right. - -%D Specifying the background is more or less the same as -%D specifying a framed box. -%D -%D \showsetup{setupbackground} - -\presetlocalframed[\??ag] - -\def\dosetupbackground[#1]% - {\getparameters[\??ag][#1]% - \doifelse\@@agstate\v!start - {\let\startbackground\dostartbackground - \let\stopbackground \dostopbackground - \let\background \dobackground} - {\let\startbackground\relax - \let\stopbackground \relax - \let\background \relax}} - -\def\setupbackground - {\dosingleargument\dosetupbackground} - -%D Actually typesetting the background is implemented rather -%D straightforward. We need to handle some spacing as well as -%D the (often) a bit smaller horizontal size. -%D -%D \showsetup{startbackground} -%D -%D Although we could have used a scratch one, we first -%D declare a boolean. - -% 0=no-split, 1=no-split+indent, 2=split, 3=split+indent - -\chardef\backgroundsplitmode\plusthree - -%D The \type{\vbox to \lineheight{}\vskip\zeropoint} -%D construction gives the first real line a decent height by -%D adding a dummy line. - -\def\dostartbackground - {\endgraf - \bgroup - \setbox0\vbox\bgroup - \vbox to \lineheight{}\vskip\zeropoint - \blank[\v!disable] - % \advance\hsize -\@@agleftoffset - % \advance\hsize -\@@agrightoffset - \leftskip \@@agleftoffset % new ** - \rightskip\@@agrightoffset} % new ** - -%D This dummy line is removed by \type{\setbox2=\vsplit0 to -%D \lineheight}. That way \type{\topskip} takes care of the -%D lineheight. I'll probably forget to apply this trick -%D elsewhere. - -\def\dostopbackground % improved version (i hope) - {\endgraf - \removelastskip - \egroup - \dimen2\leftskip % new ** - \forgetall - \ifinsidefloat - \chardef\backgroundsplitmode\zerocount - \fi - \ifcase\backgroundsplitmode - \localframed[\??ag][\c!offset=\v!overlay]{\box0}% - \or - \hskip\dimen2 - \localframed[\??ag][\c!offset=\v!overlay]{\box0}% - \else - \splitmaxdepth\boxmaxdepth - \splittopskip\topskip - \setbox2\vsplit0 to \lineheight % get rid of fake line - \loop - \ifdim\pagetotal=\zeropoint % empty page - \scratchdimen\textheight - \chardef\backgroundsplit\plusone % split to max height - \else - \setbox\scratchbox\vbox{\@@agbefore}% - \scratchdimen\dimexpr\pagegoal-\ht\scratchbox-\pagetotal\relax - \chardef\backgroundsplit\plustwo % split to partial height - \fi - \advance\scratchdimen\dimexpr-\@@agtopoffset-\@@agbottomoffset\relax - \ifdim\scratchdimen>2\lineheight\relax % reasonable, will be configurable - \ifdim\ht0>\scratchdimen % larger than page - \setbox2\vsplit0 to \scratchdimen - \else - \setbox2\box0 - \chardef\backgroundsplit\zerocount % no split - \fi - \setbox2\vbox \ifcase\backgroundsplit\or to \textheight \fi % max split - {\vskip\@@agtopoffset - \popsplitproperties - \unvcopy2 - \prevdepth\dp2 - \obeydepth - \vskip\@@agbottomoffset - \vfill} - \@@agbefore - \ifcase\backgroundsplit\or\or % partial split - \ifdim\pagegoal<\maxdimen - \pagegoal=1.2\pagegoal % be a bit more tolerant - \fi - \fi - \startlinecorrection - %\localframed[\??ag][\c!offset=\v!overlay]{\hskip\@@agleftoffset\box2\hskip\@@agrightoffset}% - \ifnum\backgroundsplitmode=\plusthree \hskip\dimen2 \fi % - \localframed[\??ag][\c!offset=\v!overlay]{\box2}% new ** - \stoplinecorrection - \ifcase\backgroundsplit % no split - \@@agafter - \else % some split - \vfill\eject % geen \page ! - \fi - \else - \page - \fi - \ifdim\ht0>\zeropoint \repeat - \fi - \egroup - \endgraf} - -%D As a bonus we also have a short command, that is of not -%D much use, but kept there for historic reasons. -%D -%D \showsetup{background} - -\def\dobackground - {\bgroup - \dowithnextbox - {\localframed[\??ag][\c!offset=\v!overlay]{\flushnextbox}\egroup} - \vbox} - -%D \stopdocumentation -%D \stopbackground -%D \egroup - -%D New, for the moment private; let's see when GB finds out -%D about this one and its obscure usage. It's used in: -%D -%D \startbuffer -%D \defineframedtext -%D [tabulateframe] -%D [offset=overlay, -%D backgroundoffset=3pt, -%D background=color, -%D backgroundcolor=green] -%D -%D \setuptabulate -%D [tabulate] -%D [frame=tabulateframe] -%D -%D \setuptables -%D [frame=tabulateframe] -%D -%D \input tufte -%D -%D \starttabulate[|l|l|] -%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR -%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR -%D \stoptabulate -%D -%D \input tufte -%D -%D \starttable[|l|l|] -%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR -%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR -%D \stoptable -%D \stopbuffer -%D -%D \typebuffer - -\def\defineframedcontent - {\dodoubleempty\dodefineframedcontent} - -\def\dodefineframedcontent[#1][#2]% - {\presetlocalframed[\??fc#1]% - \getparameters[\??fc#1] - [\c!leftoffset=\zeropoint, - \c!rightoffset=\getvalue{\??fc#1\c!leftoffset}, - \c!topoffset=\zeropoint, - \c!bottomoffset=\getvalue{\??fc#1\c!topoffset}, - \c!strut=\v!no, - \c!offset=\v!overlay, - \c!linecorrection=\v!no, - \c!left=, - \c!right=, - #2]} - -\let\setuplocalframed\getparameters - -\def\setupframedcontent - {\dodoubleempty\dosetupframedcontent} - -\def\dosetupframedcontent[#1][#2]% - {\def\docommand##1{\getparameters[\??fc##1][#2]}% - \processcommacommand[#1]\docommand} - -\def\startframedcontent[#1]% - {\bgroup - \let\stopframedcontent\egroup - \doifnot{#1}\v!off - {\doifdefined{\??fc#1\c!frame} - {\def\stopframedcontent{\dostopframedcontent{#1}}% - \dostartframedcontent{#1}}}} - -\def\dostartframedcontent#1% - {\setbox\framebox\hbox\bgroup - \setlocalhsize - \hsize\localhsize - \advance\hsize\dimexpr-\getvalue{\??fc#1\c!leftoffset}-\getvalue{\??fc#1\c!rightoffset} \relax - \advance\vsize\dimexpr-\getvalue{\??fc#1\c!topoffset} -\getvalue{\??fc#1\c!bottomoffset}\relax - \hskip\getvalue{\??fc#1\c!leftoffset}% - \vbox\bgroup - \vskip\getvalue{\??fc#1\c!topoffset}% - \vbox\bgroup - \forgetall - \blank[\v!disable]} - -\def\dostopframedcontent#1% - {\removelastskip - \egroup - \vskip\getvalue{\??fc#1\c!bottomoffset}% - \egroup - \hskip\getvalue{\??fc#1\c!rightoffset}% - \egroup - \doifvalue{\??fc#1\c!width}\v!fit - {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox - \ifinsidefloat - \donefalse - \else - \doifelsevalue{\??fc#1\c!linecorrection}\v!yes\donetrue\donefalse - \fi - % plaats ? - \ifdone\startlinecorrection\fi - \getvalue{\??fc#1\c!left}% new - \localframed[\??fc#1]{\box\framebox}% - \getvalue{\??fc#1\c!right}% new - \ifdone\stoplinecorrection\fi - \egroup} - -%D \macros -%D {backgroundline} -%D -%D For the moment an undocumented feature, but a cancidate -%D for going public. - -\def\backgroundline[#1]% - %{\doifsomething{#1}{\dobackgroundline{#1}}\hbox} - {\doifcolorelse{#1}{\dobackgroundline{#1}\hbox}\hbox} - -% \def\backgroundline[#1]% -% {\doifcolor{#1}{\dobackgroundline{#1}}\hbox} - -\def\dobackgroundline#1% - {\dowithnextbox - {\hbox - {\localcolortrue - \startcolor[#1]% - \vrule - \!!width \nextboxwd - \!!height\nextboxht - \!!depth \nextboxdp - \stopcolor - \hskip-\nextboxwd - \flushnextbox}}} - -%D \macros -%D {encircled} -%D -%D Some not so robust left||overs (borrowed from Knuth, -%D \TEX Book\ page 356): - -\def\encircled#1% - {{\ooalign{\hfil\raise0.07ex\hbox{{\tx#1}}\hfil\crcr\mathhexbox20D}}} - -\let\omcirkeld\encircled - -\setuplinewidth - [\v!medium] - -\setupframed - [\c!width=\v!fit, - \c!height=\v!broad, - \c!lines=, - \c!offset=0.25ex, % \defaultframeoffset - \c!empty=\v!no, - \c!frame=\v!on, - \c!topframe=, - \c!bottomframe=, - \c!leftframe=, - \c!rightframe=, - \c!radius=.5\bodyfontsize, - \c!rulethickness=\linewidth, - \c!corner=\v!rectangular, - \c!depth=\!!zeropoint, - \c!foregroundcolor=, - \c!foregroundstyle=, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!backgroundoffset=\!!zeropoint, - \c!framecolor=, - \c!frameoffset=\!!zeropoint, - \c!backgroundcorner=\framedparameter\c!corner, - \c!backgroundradius=\framedparameter\c!radius, - \c!backgrounddepth=\framedparameter\c!depth, - \c!framecorner=\framedparameter\c!corner, - \c!frameradius=\framedparameter\c!radius, - \c!framedepth=\framedparameter\c!depth, - \c!component=, - \c!align=, - \c!bottom=\vss, - \c!top=, - \c!strut=\v!yes, - \c!autostrut=\v!yes, - \c!location=\v!normal, - \c!orientation=, - \c!autowidth=\v!yes, - \c!setups=] - -\setupscreens - [%\c!factor=1.0, % obsolete - %\c!method=\v!external, % obsolete - \c!screen=0.95] - -\setupblackrules - [\c!n=3, - \c!width=1em, - \c!height=1ex, - \c!depth=\!!zeropoint, - \c!alternative=\c!a, - \c!distance=.25ex, - \c!color=] - -\setupmarginrules - [\c!level=0, - \c!rulethickness=\@@kadefaultwidth\linewidth] - -\setupthinrules - [\c!interlinespace=\v!small, - \c!n=3, - \c!before=, - \c!inbetween={\blank[\v!white]}, - \c!after=, - \c!color=, - \c!height=.5\linewidth, - \c!depth=.5\linewidth, - \c!frame=\v!on, % compatible with textbackgrounds - \c!alternative=\v!b, - \c!backgroundcolor=, - \c!background=, - \c!rulethickness=] - -\setuptextrules - [\c!location=\v!left, - \c!before=\blank, - \c!after=\blank, - \c!inbetween=, - \c!width=2em, - \c!style=\v!bold, - \c!color=, - \c!rulecolor=, - \c!bodyfont=, - \c!distance=.5em] - -\setupfillinrules - [\c!width=\v!broad, - \c!distance=1em, - \c!before=\blank, - \c!after=\blank, - \c!n=1, - \c!interlinespace=\v!small, - \c!separator=, - \c!style=\v!normal, - \c!color=] - -\setupfillinlines - [\c!width=3cm, - \c!margin=\@@ivwidth, - \c!distance=1em, - \c!before=\blank, - \c!after=\blank] - -\setupbackground - [\c!leftoffset=.5\bodyfontsize, - \c!rightoffset=\@@agleftoffset, - \c!topoffset=\!!zeropoint, - \c!bottomoffset=\@@agtopoffset, - \c!state=\v!start, - \c!radius=.5\bodyfontsize, - \c!corner=\v!rectangular, - \c!frame=\v!off, - \c!color=, - \c!depth=\!!zeropoint, - \c!background=\v!screen, - \c!backgroundcolor=\@@agcolor, - \c!screen=\@@rsscreen, - \c!before=, - \c!after=] - -\protect \endinput diff --git a/tex/context/base/core-rul.mkiv b/tex/context/base/core-rul.mkiv deleted file mode 100644 index 78c7156b8..000000000 --- a/tex/context/base/core-rul.mkiv +++ /dev/null @@ -1,3675 +0,0 @@ -%D \module -%D [ file=core-rul, -%D version=1998.10.16, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Ruled Stuff Handling, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Ruled Content Handling} - -%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{core-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. - -%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\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 - -\def\defineoverlay - {\dodoubleargument\dodefineoverlay} - -\def\dodefineoverlay[#1][#2]% - {\def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}% - \processcommalist[#1]\docommand} - -\prependtoks - \hsize\overlaywidth - \vsize\overlayheight -\to\everyoverlay - -\long\def\executedefinedoverlay#1#2% - {\bgroup - \edef\overlaywidth {\the\frameddimenwd\space}% - \edef\overlayheight{\the\dimexpr\frameddimenht+\frameddimendp\relax\space}% - \edef\overlaydepth {\the\frameddimendp\space}% - \edef\overlaycolor {\framedparameter\c!backgroundcolor}% - %\edef\overlaycorner{\framedparameter\c!backgroundcorner}% - %\edef\overlayradius{\framedparameter\c!backgroundradius}% - \let\overlayoffset\backgroundoffset % we steal this one - \setbox\scratchbox\hbox{\lower\overlaydepth\hbox{\the\everyoverlay#2}}% - \setbox\scratchbox\hbox - {\hskip-.5\dimexpr\wd\scratchbox-\overlaywidth \relax - \raise-.5\dimexpr\ht\scratchbox-\frameddimenht\relax % not overlayheight ! - \box\scratchbox}% - \wd\scratchbox\overlaywidth - \ht\scratchbox\overlayheight - \dp\scratchbox\overlaydepth - \startlayoutcomponent{o:#1}{overlay #1}% - \box\scratchbox - \stoplayoutcomponent - \egroup} - -%D The empty case is: - -\let\executeoverlay\gobblesevenarguments - -%D For testing we provide: - -\def\doifoverlayelse#1% - {\doifdefinedelse{\??ov#1}} - -%D We predefine two already familiar backgrounds: - -\setvalue{\??ov\v!screen}{\dograybox } -\setvalue{\??ov\v!color }{\docolorbox} - -% %D After all these preparations, the background macro does no -% %D bring to many surprises. One has to keep in mind that this -% %D macro starts up a call chain, depending on the background -% %D one needs: -% %D -% %D \startitemize[packed] -% %D \item a raster, color or user defined shape -% %D \item square or round corners -% %D \item a \TEX\ or driver based method -% %D \stopitemize -% %D -% %D The macro can be extended by adding commands to the token -% %D list register \type {\everybackgroundbox}. For this -% %D purpose, the name of the current background is available in -% %D \type {\currentbackgound}. - -%D The content of the box will be (temporary) saved in a box. We -%D also have an extra box for backgrounds. - -\newbox\framebox -\newbox\extraframebox - -\newtoks\everybackgroundbox - -\let\currentbackground\empty - -% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method -% {\bgroup -% \def\currentbackground{#1}% -% \the\everybackgroundbox -% \setbox\extraframebox\hbox -% {\vbox{\moveleft\backgroundoffset\hbox{\executeifdefined{\??ov\currentbackground}\donothing}}}% -% \wd\extraframebox\zeropoint % \backgroundwidth -% \ht\extraframebox\backgroundheight -% \dp\extraframebox\backgrounddepth -% \box\extraframebox % \hskip-\backgroundwidth -% \egroup} - -% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method -% {\bgroup -% \def\currentbackground{#1}% -% \ifcsname\??ov\currentbackground\endcsname -% \the\everybackgroundbox -% \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}% -% \wd\extraframebox\zeropoint % \backgroundwidth -% \ht\extraframebox\backgroundheight -% \dp\extraframebox\backgrounddepth -% \box\extraframebox % \hskip-\backgroundwidth -% \fi -% \egroup} - -\def\dodobackgroundbox - {\bgroup - \ifcsname\??ov\currentbackground\endcsname - \the\everybackgroundbox - \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}% - \wd\extraframebox\zeropoint % \backgroundwidth - \ht\extraframebox\backgroundheight - \dp\extraframebox\backgrounddepth - \box\extraframebox % \hskip-\backgroundwidth - \fi - \egroup} - -\def\dododobackgroundbox#1,#2% #2 gobbles spaces - {\edef\currentbackground{#1}% - \ifx\currentbackground\s!unknown\else - \dodobackgroundbox\expandafter\dododobackgroundbox - \fi#2} - -\let\backgroundoffset\!!zeropoint -\let\backgrounddepth \!!zeropoint -\def\backgroundwidth {\the\hsize} -\def\backgroundheight{\the\vsize} - -% todo: also \def\theforegroundbox{#1} - -% \def\dobackgroundbox#1% -% {\setbox\framebox\vbox -% {\forgetall -% \boxmaxdepth\maxdimen -% \scratchdimen \framedparameter{#1}\relax -% \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax -% \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax -% \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax -% \edef\backgroundoffset{\the\scratchdimen}% -% \edef\backgroundwidth {\the\wd\framebox}% -% \edef\backgroundheight{\the\ht\framebox}% -% \edef\backgrounddepth {\the\dp\framebox}% -% %\edef\foregroundbox{\box#1}% -% \def\foregroundbox% fuzzy but needed hack, this \vss, otherwise -% {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift -% \edef\component{\framedparameter\c!component}% -% \hbox to \backgroundwidth % in case 'foreground' is used as overlay -% {\ifx\component\empty -% \rawprocesscommalist[\framedbackground]\dodobackgroundbox -% \else -% \startlayoutcomponent{b:\component}{\s!background\space\component}% -% \rawprocesscommalist[\framedbackground]\dodobackgroundbox -% \stoplayoutcomponent -% \fi -% \box\framebox\hss}}} - -\def\normalforegroundbox% fuzzy but needed hack, this \vss, otherwise - {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift - -\def\dobackgroundbox#1% - {\setbox\framebox\vbox - {\forgetall - \boxmaxdepth\maxdimen - \scratchdimen \framedparameter{#1}\relax - \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax - \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax - \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax - \edef\backgroundoffset{\the\scratchdimen}% - \edef\backgroundwidth {\the\wd\framebox}% - \edef\backgroundheight{\the\ht\framebox}% - \edef\backgrounddepth {\the\dp\framebox}% - %\edef\foregroundbox{\box#1}% - \edef\component{\framedparameter\c!component}% - \let\foregroundbox\normalforegroundbox - \hbox to \backgroundwidth % in case 'foreground' is used as overlay - {\ifx\component\empty - \normalexpanded{\noexpand\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax - \else - \startlayoutcomponent{b:\component}{background \component}% - \normalexpanded{\noexpand\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax - \stoplayoutcomponent - \fi - \box\framebox\hss}}} - -%D One can explictly insert the foreground box. For that -%D purpose we introduce the overlay \type {foreground}. - -\defineoverlay[\v!foreground][\foregroundbox] - -%D We can specify overlays as a comma separated list of -%D overlays, a sometimes handy feature. - -%D Besides backgrounds (overlays) we also need some macros to -%D draw outlines (ruled borders). Again we have to deal with -%D square and round corners. The first category can be handled -%D by \TEX\ itself, the latter one depends on the driver. This -%D macro also support a negative offset. - -\ifx\scratchoffset\undefined \newdimen\scratchoffset \fi - -\def\dooutlinebox % we needed to move the color command in order to apply attributes properly - {\setbox\framebox\vbox % rules on top of box - {\scratchoffset \framedparameter\c!frameoffset\relax - \frameddimenwd\dimexpr\wd\framebox+2\scratchoffset\relax - \frameddimenht\dimexpr\ht\framebox+ \scratchoffset\relax - \frameddimendp\dimexpr\dp\framebox+ \scratchoffset+\framedparameter\c!framedepth\relax - \ifdim\frameddimendp<\zeropoint - \advance\frameddimenht \frameddimendp - \scratchdimen-\frameddimendp - \frameddimendp\zeropoint - \else - \scratchdimen\zeropoint - \fi - \setbox\extraframebox\hbox - {\doifsomething{\framedparameter\c!framecolor}{\color[\framedparameter\c!framecolor]}{\dostrokedbox}}% - \setbox\extraframebox\hbox - {\raise\scratchdimen\vbox - {\moveleft\scratchoffset - \box\extraframebox}}% - \wd\extraframebox\wd\framebox - \ht\extraframebox\ht\framebox - \dp\extraframebox\dp\framebox - \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}} - -\def\dostrokedbox - {\doifelse{\framedparameter\c!framecorner}\v!rectangular - {\dostrokedlinedbox} - {\ifzeropt\dimexpr\framedparameter\c!frameradius\relax % just in case of .x\bodyfontsize - \dostrokedlinedbox - \else - \dostrokedroundbox - \fi}} - -\def\dostrokedlinedbox - {\setbox\scratchbox\null - \wd\scratchbox\frameddimenwd - \ht\scratchbox\frameddimenht - \dp\scratchbox\frameddimendp - \setbox\scratchbox\vbox \bgroup - \csname t\@@frame@@\framedparameter\c!frame\framedparameter\c!topframe \endcsname - \hbox \bgroup - \csname l\@@frame@@\framedparameter\c!frame\framedparameter\c!leftframe \endcsname - \box\scratchbox - \csname r\@@frame@@\framedparameter\c!frame\framedparameter\c!rightframe \endcsname - \egroup - \csname b\@@frame@@\framedparameter\c!frame\framedparameter\c!bottomframe\endcsname - \egroup - \wd\scratchbox\frameddimenwd - \ht\scratchbox\frameddimenht - \dp\scratchbox\frameddimendp - \box\scratchbox} - -\def\@@frame@@{@@frame@@} - -% \setvalue{t\@@frame@@\v!on \v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} -% \setvalue{t\@@frame@@\v!off\v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} -% \setvalue{t\@@frame@@\v!on }{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} -% \setvalue{b\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} -% \setvalue{b\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} -% \setvalue{b\@@frame@@\v!on }{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} -% \setvalue{l\@@frame@@\v!on \v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} -% \setvalue{l\@@frame@@\v!off\v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} -% \setvalue{l\@@frame@@\v!on }{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} -% \setvalue{r\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} -% \setvalue{r\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} -% \setvalue{r\@@frame@@\v!on }{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} - -\def\@@frame@@trule{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} -\def\@@frame@@brule{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} -\def\@@frame@@rrule{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} -\def\@@frame@@lrule{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} - -\letvalue{t\@@frame@@\v!on \v!on}\@@frame@@trule -\letvalue{t\@@frame@@\v!off\v!on}\@@frame@@trule -\letvalue{t\@@frame@@\v!on }\@@frame@@trule - -\letvalue{b\@@frame@@\v!on \v!on}\@@frame@@brule -\letvalue{b\@@frame@@\v!off\v!on}\@@frame@@brule -\letvalue{b\@@frame@@\v!on }\@@frame@@brule - -\letvalue{l\@@frame@@\v!on \v!on}\@@frame@@lrule -\letvalue{l\@@frame@@\v!off\v!on}\@@frame@@lrule -\letvalue{l\@@frame@@\v!on }\@@frame@@lrule - -\letvalue{r\@@frame@@\v!on \v!on}\@@frame@@rrule -\letvalue{r\@@frame@@\v!off\v!on}\@@frame@@rrule -\letvalue{r\@@frame@@\v!on }\@@frame@@rrule - -% no overlapping rules - -\def\@@frame@@trules{\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}\nointerlineskip\kern-\ruledlinewidth} -\def\@@frame@@brules{\kern-\ruledlinewidth\nointerlineskip\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}} -\def\@@frame@@rrules{\kern-\ruledlinewidth\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth} -\def\@@frame@@lrules{\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth\kern-\ruledlinewidth} - -% small is relatively new - -\letvalue{t\@@frame@@\v!small\v!small}\@@frame@@trules -\letvalue{t\@@frame@@\v!off \v!small}\@@frame@@trules -\letvalue{t\@@frame@@\v!small }\@@frame@@trules - -\letvalue{b\@@frame@@\v!small\v!small}\@@frame@@brules -\letvalue{b\@@frame@@\v!off \v!small}\@@frame@@brules -\letvalue{b\@@frame@@\v!small }\@@frame@@brules - -\letvalue{l\@@frame@@\v!small\v!small}\@@frame@@lrules -\letvalue{l\@@frame@@\v!off \v!small}\@@frame@@lrules -\letvalue{l\@@frame@@\v!small }\@@frame@@lrules - -\letvalue{r\@@frame@@\v!small\v!small}\@@frame@@rrules -\letvalue{r\@@frame@@\v!off \v!small}\@@frame@@rrules -\letvalue{r\@@frame@@\v!small }\@@frame@@rrules - -%D I condidered using the low level support command -%D \type{\ruledhbox}, but this would slow down processing by a -%D factor~3. - -% \framed -% [width=4cm,height=3cm,rulethickness=3mm, -% frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on] -% {} -% \framed -% [width=4cm,height=3cm,rulethickness=3mm, -% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small] -% {} -% \framed -% [width=4cm,height=3cm,rulethickness=3mm, -% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on] -% {} - -%D The next few macros are probably the most misused ones in -%D \CONTEXT. They deal with putting rules around boxes, provide -%D backgrounds, offer alignment features, and some more. We -%D start with defining some booleans. These give an impression -%D of what we are going to take into account. - -% todo: chardefs - -\newif\ifboxhasoffset -\newif\ifboxhaswidth -\newif\ifboxhasheight -\newif\ifboxhasformat -\newif\ifboxhasstrut -\newif\ifboxisoverlaid -\newif\ifboxhasframe -\newif\ifdelayedstrut -\newif\ifboxhasextraoffset - -%D We also need a few \DIMENSIONS: - -\newdimen\@@localoffset -\newdimen\@@globalwidth - -%D \macros -%D {framed, setupframed} -%D -%D Ruled boxes are typeset using \type{\framed}. This command -%D is quite versatile and, although some users will probably -%D seldom use it, one cannot overlook its features. -%D -%D \showsetup{setupframed} -%D \showsetup{framed} -%D -%D This general macro is a special version of an even more -%D general case, that can easily be linked into other macros -%D that need some kind of framing. The local version is called -%D with an extra parameter: the variable identifier. The reason -%D for passing this identifier between brackets lays in the -%D mere fact that this way we can use the optional argument -%D grabbers. - -\def\defaultframeoffset{.25ex} - -\def\presetlocalframed [#1]{\letvalue{#1\s!parent}\??oi} -\def\inheritlocalframed[#1]#2[#3]{\letvalue{#1\s!parent}#3} -\def\copylocalframed [#1]#2[#3]{\setvalue{#1\s!parent}{#3}} - -\presetlocalframed[\??ol] - -% \unexpanded\def\framed -% {\bgroup -% \dodoubleempty\startlocalframed[\??ol]} - -\newcount\framednesting - -\unexpanded\def\framed - {\bgroup - \advance\framednesting\plusone - \letvalue{\??ol:\the\framednesting\s!parent}\??ol - \dodoubleempty\startlocalframed[\??ol:\the\framednesting]} - -\def\setupframed - {\dodoubleempty\dosetupframed} - -\def\dosetupframed - {\ifsecondargument - \@EA\dodoublesetupframed - \else - \@EA\dosinglesetupframed - \fi} - -\def\dosinglesetupframed[#1][#2]% - {\getparameters[\??ol][#1]} - -\def\dodoublesetupframed[#1][#2]% - {\bgroup - \let\dodoubleempty\empty - \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}% - \getvalue{#1}% - \egroup - \letvalue{#1}\globalredefinedframed} - -%D \startbuffer -%D \setupframed [framecolor=yellow] \framed{A} -%D \defineframed[myframed] [framecolor=blue] \myframed{B} -%D \setupframed [myframed] [framecolor=red] \myframed{C} -%D \stopbuffer -%D -%D \typebuffer \getbuffer -%D -%D \startbuffer -%D \presetlocalframed[myframed] -%D \setuplocalframed[myframed][width=4cm,height=2cm] -%D \localframed[myframed][framecolor=green]{oeps} -%D \stopbuffer -%D -%D \typebuffer \getbuffer - -%D \macros -%D {ifinframed} -%D -%D The normal case first presets all parameters and next starts -%D looking for the user supplied ones. The first step is -%D omitted in the local case, because these are preset at -%D declaration time and keep their values unless explictly -%D changed. By presetting the variables everytime the normal -%D command is called, we can use this command nested, without -%D the unwanted side effect of inheritance. The boolean is -%D used to speed up the color stack. - -\newif\ifinframed - -\def\localframed - {\bgroup - \dodoubleempty\startlocalframed} - -%D The next one is faster on multiple backgrounds per page. No -%D dimensions can be set, only frames and backgrounds. - -\def\fastlocalframed[#1]#2[#3]#4% 3-4 - {\bgroup - \inframedtrue - \edef\@@framed{#1}% - % some hackery (no \dimexpr) - \scratchdimen\framedparameter\c!frameoffset - \setevalue{\@@framed\c!frameoffset}{\the\scratchdimen}% - \doifnot{\framedparameter\c!backgroundoffset}\v!frame - {\scratchdimen\framedparameter\c!backgroundoffset - \setevalue{\@@framed\c!backgroundoffset}{\the\scratchdimen}}% - % so far - \setbox\framebox\hbox{#4}% - \getparameters[\@@framed][#3]% no \expanded ! - % not here, in calling macro: setups - \removeframedboxdepth - \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}% - \ifx\framedforegroundcolor\empty\else\docolorframebox\fi - \edef\overlaylinecolor{\framedparameter\c!framecolor}% - \edef\overlaylinewidth{\the\ruledlinewidth}% - \edef\@@localframing {\framedparameter\c!frame}% - \ifx\@@localframing\v!overlay \else \ifx\@@localframing\v!none \else - \edef\framedrulethickness{\framedparameter\c!rulethickness}% - \ifx\framedrulethickness\empty\else - \ruledlinewidth\framedrulethickness\relax - \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi - \fi - \dooutlinebox % real or invisible frame - \fi \fi - \edef\framedbackground{\framedparameter\c!background}% - \ifx\framedbackground\empty\else\dobackedbox\fi - \restoreframedboxdepth - \box\framebox - \egroup} - -%D Before we go into details, we present (and implement) the -%D main framing routine. I saw no real reason for splitting the -%D next two macros into smaller pieces. The content will be -%D collected in a horizontal or vertical box with fixed or free -%D dimensions and specific settings concerning aligment and -%D offsets. -%D -%D In the first few lines, we pre||expand the frame and -%D background offsets. We do so, because the can be defined in -%D terms of the main offset. However, see for instance page -%D backgrounds, when \type {#2} sets the offset to \type -%D {overlay}, both offsets become invalid. -%D -%D Because it is used so often the he next macro is (and -%D looks) rather optimized. - -\let\postprocessframebox\relax - -\let\@@framed\s!unknown - -\def\framedparameter #1{\csname\doframedparameter\@@framed#1\endcsname} -\def\framedparameterhash#1{\doframedparameterhash \@@framed#1} - -\def\doframedparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doframedparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\doframedparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doframedparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\doframedparentparameter #1#2{\ifx#1\relax\s!empty\else\doframedparameter #1#2\fi} -\def\doframedparentparameterhash#1#2{\ifx#1\relax \else\doframedparameterhash#1#2\fi} - -% \def\s!root{root} % maybe configurable - -\def\doframedparentparameter#1#2{\ifx#1\relax\doframedrootparameter#2\else\doframedparameter#1#2\fi} -\def\doframedrootparameter #1{\ifcsname\??oi#1\endcsname\??oi#1\else\s!empty\fi} - -\def\dosetframedattributes#1#2% style color - {\edef\fontattributehash {\framedparameterhash#1}% - \edef\colorattributehash{\framedparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -% defaults, kind of isolated now - -\getparameters - [\??oi] - [\c!width=\v!fit, - \c!height=\v!broad, - %\c!lines=, - \c!offset=0.25ex, % \defaultframeoffset - \c!empty=\v!no, - \c!frame=\v!on, - %\c!topframe=, - %\c!bottomframe=, - %\c!leftframe=, - %\c!rightframe=, - \c!radius=.5\bodyfontsize, - \c!rulethickness=\linewidth, - \c!corner=\v!rectangular, - \c!depth=\!!zeropoint, - %\c!foregroundcolor=, - %\c!foregroundstyle=, - %\c!background=, - %\c!backgroundscreen=, - %\c!backgroundcolor=, - \c!backgroundoffset=\!!zeropoint, - %\c!framecolor=, - \c!frameoffset=\!!zeropoint, - \c!backgroundcorner=\framedparameter\c!corner, - \c!backgroundradius=\framedparameter\c!radius, - \c!backgrounddepth=\framedparameter\c!depth, - \c!framecorner=\framedparameter\c!corner, - \c!frameradius=\framedparameter\c!radius, - \c!framedepth=\framedparameter\c!depth, - %\c!component=, - %\c!align=, - \c!bottom=\vss, - %\c!top=, - \c!strut=\v!yes, - \c!autostrut=\v!yes, - \c!location=\v!normal, - %\c!orientation=, - \c!autowidth=\v!yes, - %\c!setups= -] - -\getparameters - [\??od] % for fast version - [\c!frame=\v!off, - \c!depth=\zeropoint, - \c!offset=\v!overlay, - %\c!component=, - \c!radius=.5\bodyfontsize, - \c!rulethickness=\linewidth, - \c!corner=\v!rectangular, - \c!backgroundoffset=\!!zeropoint, - \c!frameoffset=\!!zeropoint, - \c!backgroundcorner=\framedparameter\c!corner, - \c!backgroundradius=\framedparameter\c!radius, - \c!backgrounddepth=\framedparameter\c!depth, - \c!framecorner=\framedparameter\c!corner, - \c!frameradius=\framedparameter\c!radius, - \c!framedepth=\framedparameter\c!depth, - \c!location=\v!normal] - -% so far - -\newdimen\!!framedwidth -\newdimen\!!framedheight -\newdimen\!!framedscratch % so that users can use \scratchdimen - -\let\setextraframedoffsets \relax -\let\applyextraframedoffsets\relax - -\def\startlocalframed[#1][#2]% - {\bgroup - \inframedtrue - \edef\@@framed{#1}% - % this piece of pre expansion is needed (sometimes used circular) - \!!framedscratch\framedparameter\c!frameoffset - \setevalue{\@@framed\c!frameoffset}{\the\!!framedscratch}% - \doifnot{\framedparameter\c!backgroundoffset}\v!frame - {\!!framedscratch\framedparameter\c!backgroundoffset - \setevalue{\@@framed\c!backgroundoffset}{\the\!!framedscratch}}% - % to prevent deadlock in case of self refering - \ifsecondargument % faster - \getparameters[\@@framed][#2]% here ! - \fi - % new, experimental dirty hook - \framedparameter\c!extras - % to get the right spacing - \doifsomething{\framedparameter\c!foregroundstyle} - {\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}% - % beware, both the frame and background offset can be overruled - % - \edef\doframedsetups{\framedparameter\c!setups}% - \ifx\doframedsetups\empty\else - \edef\doframedsetups{\noexpand\setups[\doframedsetups]}% - \fi - % the next macros are visible - \edef\localoffset{\framedparameter\c!offset}% - \edef\localwidth {\framedparameter\c!width}% - \edef\localheight{\framedparameter\c!height}% - \edef\localformat{\framedparameter\c!align}% - \edef\localstrut {\framedparameter\c!strut}% - % these are not - \edef\@@localautostrut {\framedparameter\c!autostrut}% - \edef\@@localframing {\framedparameter\c!frame}% - \edef\@@locallocation {\framedparameter\c!location}% - \edef\@@localorientation{\framedparameter\c!orientation}% - % - \edef\@@localautowidth {\framedparameter\c!autowidth}% - % - \ifx\@@localframing\v!overlay % no frame, no offset, no framewidth - \boxhasframefalse - \let\localoffset\v!overlay - \else\ifx\@@localframing\v!none % no frame, no framewidth - \boxhasframefalse - \else - \boxhasframetrue - \fi\fi - \ifboxhasframe - \edef\framedrulethickness{\framedparameter\c!rulethickness}% - \ifx\framedrulethickness\empty\else - \ruledlinewidth\framedrulethickness\relax - \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi - \fi - \else - \ruledlinewidth\zeropoint - \fi - \ifx\localformat\empty - \boxhasformatfalse - \else - \boxhasformattrue - \dosetraggedcommand\localformat - \edef\dobeforeframedbox{\raggedtopcommand\framedparameter\c!top}% - \edef\doafterframedbox {\framedparameter\c!bottom\raggedbottomcommand}% - \fi - \ifx\localoffset\v!none - \boxhasoffsetfalse - \boxhasstrutfalse - \boxisoverlaidfalse - \@@localoffset\ruledlinewidth - \else\ifx\localoffset\v!overlay - % \ifx\@@localframing\v!no \boxhasframefalse \fi % test first - \boxhasoffsetfalse - \boxhasstrutfalse - \boxisoverlaidtrue - \@@localoffset\zeropoint - \else - \boxhasoffsettrue - \boxhasstruttrue - \boxisoverlaidfalse - \ifx\localoffset\v!default % new per 2-6-2000 - \let\localoffset\defaultframeoffset - \letvalue{\@@framed\c!offset}\defaultframeoffset - \else - \let\defaultframeoffset\localoffset - \fi - \@@localoffset\dimexpr\localoffset+\ruledlinewidth\relax - \fi\fi - \!!framedheight\zeropoint - \!!framedwidth \zeropoint - \ifx\localwidth\v!fit - \ifboxhasformat - \boxhaswidthtrue - \!!framedwidth\hsize - \else - \boxhaswidthfalse - \fi - \else\ifx\localwidth\v!fixed % equals \v!fit but no shapebox - \ifboxhasformat - \boxhaswidthtrue - \!!framedwidth\hsize - \else - \boxhaswidthfalse - \fi - \else\ifx\localwidth\v!broad - \boxhaswidthtrue - \!!framedwidth\hsize - \else\ifx\localwidth\v!local - \boxhaswidthtrue - \setlocalhsize - \!!framedwidth\localhsize - \else - \boxhaswidthtrue - \!!framedwidth\localwidth - \fi\fi\fi\fi - \ifx\localheight\v!fit - \boxhasheightfalse % no longer: \boxhasstrutfalse - \else\ifx\localheight\v!broad - \boxhasheightfalse - \else - \boxhasheighttrue - \!!framedheight\localheight - \fi\fi - \ifboxhasheight - % obey user set height, also downward compatible - \else - \doifsomething{\framedparameter\c!lines} - {\ifcase\framedparameter\c!lines\else - \!!framedheight\framedparameter\c!lines\lineheight - \edef\localheight{\the\!!framedheight}% - \boxhasheighttrue - \fi}% - \fi - % this is now an option: width=local - % - % \ifdim\!!framedwidth=\hsize - % \parindent\zeropoint - % \setlocalhsize - % \!!framedwidth\localhsize - % \fi - % i.e. disable (colsetbackgroundproblemintechniek) - \advance\!!framedwidth -2\@@localoffset - \advance\!!framedheight -2\@@localoffset - \ifx\localstrut\v!no - \boxhasstrutfalse - \else\ifx\localstrut\v!global - \setstrut - \else\ifx\localstrut\v!local - \setfontstrut - \else - \setstrut - \fi\fi\fi - \ifboxhasstrut - \let\localbegstrut\begstrut - \let\localendstrut\endstrut - \let\localstrut \strut - \else - \let\localbegstrut\pseudobegstrut % was: \relax - \let\localendstrut\pseudoendstrut % was: \relax - \let\localstrut \pseudostrut % was: \relax - %\ifboxhasheight\ifdim\!!framedheight<\strutht % saveguard - % \let\localbegstrut\relax % but not that - % \let\localstrut \relax % save after all - %\fi\fi - \fi - \ifx\@@localautostrut\v!yes - \let\delayedbegstrut\relax - \let\delayedendstrut\relax - \let\delayedstrut \relax - \else - \let\delayedbegstrut\localbegstrut - \let\delayedendstrut\localendstrut - \let\delayedstrut \localstrut - \let\localbegstrut \relax - \let\localendstrut \relax - \let\localstrut \relax - \fi - \ifboxhasheight - \let\\\vboxednewline - \ifboxhaswidth - \let\hairline\vboxedhairline - \ifboxhasformat - \let\next\doformatboxSomeFormat - \else - \let\next\doformatboxNoFormat - \fi - \else - \let\hairline\hboxedhairline - \ifboxhasformat - \let\next\doformatboxHeight - \else - \let\next\doformatboxVSize - \fi - \fi - \else - \ifboxhaswidth - \ifboxhasformat - \let\hairline\vboxedhairline - \let\\\vboxednewline - \let\next\doformatboxWidth - \else - \let\hairline\hboxedhairline - \let\\\hboxednewline - \let\next\doformatboxHSize - \fi - \else - \let\hairline\hboxedhairline - \let\\\hboxednewline - \let\next\doformatboxNoSize - \fi - \fi - \setextraframedoffsets - \edef\framedwidth % a new feature, visible for user - {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}% - \edef\framedheight% a new feature, visible for user - {\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}% - % we need to register the (outer) color - \startregistercolor[\framedparameter\c!foregroundcolor]% - % first alternative - %\def\dowithframedbox% - % {\let\postprocessframebox\relax %new - % \aftergroup\stoplocalframed}% - % \afterassignment\dowithframedbox - % \setbox\framebox=\next} - % second alternative - %\dowithnextbox - % {\setbox\framebox\flushnextbox - % \let\postprocessframebox\relax %new - % \stoplocalframed} - % \next} - \@@startframedorientation - \afterassignment\dodowithframebox - \setbox\framebox\next} - -\def\dowithframebox - {% moved : \let\postprocessframebox\relax - \stoplocalframed} - -\def\dodowithframebox - {\aftergroup\dowithframebox} - -\let\doafterframedbox \relax -\let\dobeforeframedbox\relax - -%D Carefull analysis of this macro will learn us that not all -%D branches in the last conditionals can be encountered, that -%D is, some assignments to \type{\next} will never occur. -%D Nevertheless we implement the whole scheme, if not for -%D future extensions. - -%D \macros -%D {ifreshapeframebox} -%D -%D The last few lines tell what to do after the content of the -%D box is collected and passed to the next macro. In the case -%D of a fixed width and centered alignment, the content is -%D evaluated and used to determine the most natural width. The -%D rest of the code deals with backgrounds and frames. - -\newif\ifreshapeframebox \reshapeframeboxtrue - -%D Beware: setting \type {top} and \type {bottom} to nothing, may -%D result in a frame that is larger that the given height! try: -%D -%D \starttyping -%D \framed -%D [height=3cm,top=,bottom=,offset=overlay] -%D {\strut test \shapefill \strut test} -%D \stoptyping -%D -%D This is intended behaviour and not a bug! One can always set -%D -%D \starttyping -%D ...,bottom=\kern0pt,... -%D \stoptyping - -\def\stoplocalframed - {\dontshowcomposition - \@@stopframedorientation % hm, wrong place ! should rotate the result (after reshape) - \stopregistercolor - \handleframedlocator\c!before\@@locallocation - \ifboxhasformat - \ifx\@@localautowidth\v!force - \ifreshapeframebox\doreshapeframedbox\fi - \boxhaswidthfalse - \else - \ifx\localwidth\v!fit - \ifx\@@localautowidth\v!yes - \ifreshapeframebox\doreshapeframedbox\fi - \fi - \boxhaswidthfalse - \else\ifx\localwidth\v!fixed - \boxhaswidthfalse - \else - \resetshapeframebox - \fi\fi - \fi -\ifconditional\boxcontentneedsprocessing - \mkdoprocessboxcontents\framebox -\fi - \else - \resetshapeframebox - \fi - \ifboxhaswidth - \wd\framebox\!!framedwidth - \fi - \ifboxhasheight - \ht\framebox\!!framedheight - \fi - \doif{\framedparameter\c!empty}\v!yes - {\setbox\scratchbox\null - \wd\scratchbox\wd\framebox - \ht\scratchbox\ht\framebox - \dp\scratchbox\dp\framebox - \setbox\framebox\box\scratchbox}% - \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}% - \ifx\framedforegroundcolor\empty\else\docolorframebox\fi - \ifboxhasextraoffset - \applyextraframedoffsets - \fi - \ifboxhasoffset - \dooffsetframebox - \fi - \ifboxisoverlaid \else - \dolocateframebox - \fi - \ifx\postprocessframebox\relax \else - \let\next\postprocessframebox - \let\postprocessframebox\relax % prevent nesting - \next\framebox - \fi - \edef\overlaylinecolor{\framedparameter\c!framecolor}% - \edef\overlaylinewidth{\the\ruledlinewidth}% \@@... - \ifboxhasframe % real or invisible frame - \dooutlinebox - \fi - \edef\framedbackground{\framedparameter\c!background}% - \ifx\framedbackground\empty\else\dobackedbox\fi - \handleframedlocator\c!after\@@locallocation - \box\framebox - \egroup - \egroup} - -\def\installframedlocator#1#2#3% - {\setvalue{\??oi:\c!location:\c!before:#1}{#2}% - \setvalue{\??oi:\c!location:\c!after :#1}{#3}} - -\def\handleframedlocator#1#2% - {\getvalue{\??oi:\c!location:#1:#2}} - -\def\doprelocframedbox#1% - {\scratchdimen\dimexpr#1+\ruledlinewidth\relax - \ifboxhasoffset - \advance\scratchdimen \framedparameter\c!offset - \fi - \scratchskip\dimexpr\ht\framebox-\scratchdimen\relax} - -% \ruledhbox -% {A -% \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging} -% \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth} -% \framed[width=2cm,align=middle,location=height] {location\\equals\\height} -% B} -% \vskip2cm -% \ruledhbox -% {A -% \framed[width=2cm,align=middle,location=low] {location\\equals\\low} -% \framed[width=2cm,align=middle,location=line] {location\\equals\\line} -% \framed[width=2cm,align=middle,location=high] {location\\equals\\high} -% B} -% \vskip2cm -% \ruledhbox -% {A -% \framed[width=2cm,align=middle,location=top] {location\\equals\\top} -% \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom} -% \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi} -% \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle} -% B} - -\installframedlocator \v!hanging % best with strut=no - {} - {\dp\framebox\ht\framebox - \ht\framebox\zeropoint} - -\installframedlocator \v!depth - {} - {\ht\framebox\dimexpr\ht\framebox-\strutdp\relax - \dp\framebox\strutdp - \box\framebox} - -\installframedlocator \v!height - {} - {\dp\framebox\dimexpr\ht\framebox-\strutht\relax - \ht\framebox\strutht - \box\framebox} - -\installframedlocator \v!high - {} - {\doprelocframedbox\strutht - \setbox\framebox\hbox{\lower\scratchskip\box\framebox}% - \ht\framebox\strutht - \dp\framebox\strutdp - \hbox{\box\framebox}} - -\installframedlocator \v!line - {} - {\setbox\framebox\hbox{\lower.5\ht\framebox\box\framebox}% - \ht\framebox.5\lineheight - \dp\framebox.5\lineheight - \hbox{\box\framebox}} - -\installframedlocator \v!low - {} - {\doprelocframedbox\strutdp - \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% - \ht\framebox\strutht - \dp\framebox\strutdp - \box\framebox} - -\installframedlocator \v!top - {} - {\doprelocframedbox\strutht - \setbox\framebox\hbox{\lower\scratchskip\box\framebox}% - \ht\framebox\scratchdimen - \dp\framebox\scratchskip - \hbox{\box\framebox}} - -\installframedlocator \v!middle - {} - {\scratchdimen.5\ht\framebox - \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% - \ht\framebox\scratchdimen - \dp\framebox\scratchdimen - \hbox{\box\framebox}} - -\installframedlocator \v!lohi - {\handleframedlocator\c!before\v!middle} - {\handleframedlocator\c!after \v!middle} - -\installframedlocator \v!bottom - {} - {\doprelocframedbox\strutdp - \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% - \ht\framebox\scratchskip - \dp\framebox\scratchdimen - \hbox{\box\framebox}} - -\installframedlocator \v!keep % retains height/depth - {\removeframedboxdepth} - {\restoreframedboxdepth} - -% also used in fastlocalframed - -\newdimen\originalframedwd -\newdimen\originalframedht -\newdimen\originalframeddp - -\def\removeframedboxdepth - {\originalframedwd\wd\framebox - \originalframedht\ht\framebox - \originalframeddp\dp\framebox - \ifzeropt\originalframeddp\else\setbox\framebox\hbox{\raise\originalframeddp\box\framebox}\fi - \wd\framebox\originalframedwd - \ht\framebox\dimexpr\originalframedht+\originalframeddp\relax - \dp\framebox\zeropoint} - -\def\restoreframedboxdepth - {\ifzeropt\originalframeddp\else\setbox\framebox\hbox{\lower\originalframeddp\box\framebox}\fi - \wd\framebox\originalframedwd - \ht\framebox\originalframedht - \dp\framebox\originalframeddp} - -% \let\@@startframedorientation\relax -% \let\@@stopframedorientation \relax - -% \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax} -% \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax} -% \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax} -% \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax} -% \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax} -% \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax} -% \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax} - -\def\@@startframedorientation - {\let\@@stopframedorientation \relax - \ifx\@@localorientation\empty\else - \ifcase\@@localorientation\else - \scratchcounter\@@localorientation - \divide\scratchcounter\plustwo - \ifodd\scratchcounter - \swapmacros\framedwidth \framedheight - \swapmacros\localwidth \localheight - \swapdimens\!!framedheight\!!framedwidth - \def\@@stopframedorientation{\@@dostopframedorientation\plusone}% - \else - \def\@@stopframedorientation{\@@dostopframedorientation\zerocount}% - \fi - \fi - \fi} - -\def\@@dostopframedorientation#1% - {\ifcase#1\else - \swapmacros\framedwidth \framedheight - \swapmacros\localwidth \localheight - \swapdimens\!!framedheight\!!framedwidth - \fi - \setbox\framebox\hbox{\dorotatebox\@@localorientation\hbox{\box\framebox}}} - -%D The last conditional takes care of the special situation of -%D in||line \inframed[height=3cm]{framed} boxes. Such boxes have -%D to be \inframed{aligned} with the running text. - -\def\doinframed[#1]% we could omit #1] but readibility ... - {\framed[\c!location=\v!low,#1]} - -\unexpanded\def\inframed - {\dosingleempty\doinframed} - -%D When we set \type{empty} to \type{yes}, we get -%D ourselves a frame and/or background, but no content, so -%D actually we have a sort of phantom framed box. - -%D Because color marks and specials can interfere with -%D spacing, we provide a way to specify a foregroundcolor. - -\def\docolorframebox - {\doifcolor\framedforegroundcolor - {\setbox\framebox\hbox{\faststartcolor[\framedforegroundcolor]\box\framebox\faststopcolor}}} - %{\setbox\framebox\hbox{\doactivatecolor\framedforegroundcolor\box\framebox}}} - -%D \macros -%D {mframed, minframed} -%D -%D When Tobias asked how to frame mathematical elements in -%D formulas, Taco's posted the next macro: -%D -%D \starttyping -%D \def\mframed#1% -%D {\relax -%D \ifmmode -%D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}% -%D \else -%D \framed{$#1$}% -%D \fi} -%D \stoptyping -%D -%D Because \type {\ifinner} does not (always) reports what -%D one would expect, we move the test to the outer level. We -%D also want to pass arguments, -%D -%D \starttyping -%D \def\mframed% -%D {\dosingleempty\domframed} -%D -%D \def\domframed[#1]#2% % tzt \dowithnextmathbox ? -%D {\relax -%D \ifmmode -%D \ifinner -%D \inframed[#1]{$#2$}% -%D \else -%D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}% -%D \fi -%D \else -%D \inframed[#1]{$#2$}% -%D \fi} -%D \stoptyping -%D -%D Still better is the next alternative, if only because it -%D takes care of setting the super- and subscripts styles - -\newcount\mframedstyle - -\def\doinlinemframed[#1]#2% - {\begingroup - \mframedstyle\mathstyle\relax - \inframed[#1]{$\triggermathstyle\mframedstyle#2$}% - \endgroup} - -\def\dodisplaymframed[#1]#2% - {\begingroup - \mframedstyle\mathstyle\relax - \def\normalstrut{$\triggermathstyle\mframedstyle\vphantom{(}$}% - \framed[#1]{$\triggermathstyle\mframedstyle#2$}% - \endgroup} - -\def\mframed {\dosingleempty\dodisplaymframed} -\def\inmframed{\dosingleempty\doinlinemframed } - -%D So instead of the rather versatile \type {\framed}, we ue -%D the \type {\mframed}. -%D -%D \startbuffer -%D \startformula -%D x \times \mframed{y} \times y^{z_z} -%D x \times \inmframed{y} \times y^{z_z} -%D \stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D \getbuffer -%D -%D However, we got into troubles when we want to nest sub- and -%D superscripts, like in -%D -%D \startbuffer -%D \startformula -%D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}} -%D \stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D \getbuffer -%D -%D Therefore, we can best use \type {\super} and \type {\suber} -%D instead of \type {^} and \type {_}. Both commands take care -%D of proper font switching. -%D -%D \startbuffer -%D \startformula -%D x \times \mframed{y} \times y\super{\mframed{z}\suber{\mframed{z}}} -%D \stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D \getbuffer -%D -%D As usual, one can specify in what way the text should be -%D framed. One should be aware of the fact that, inorder to -%D preserve the proper spacing, the \type {offset} is set to -%D \type {overlay} and \type {frameoffset} is used used -%D instead. -%D -%D \startbuffer -%D \startformula -%D x \times y\super{\mframed[framecolor=red]{z}\suber{z}} -%D \stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D \getbuffer -%D -%D For inline use, we also provide the \type {\inmframed} -%D alternative: we want $x \times \inmframed{y}$ in inline -%D math, right? - -%D This previous framing macros needs a lot of alternatives for -%D putting rules around boxes, inserting offsets and aligning -%D text. Each step is handled by separate macros. - -\def\dowidenframebox#1% - {\setbox\framebox\vbox - {\kern#1\hbox{\kern#1\box\framebox\kern#1}\kern#1}} - -\def\dooffsetframebox{\dowidenframebox\localoffset} -\def\dolocateframebox{\dowidenframebox\ruledlinewidth} - -%D Let's hope that the next few examples show us enough of -%D what needs to be done by the auxiliary macros. -%D -%D \startbuffer -%D \framed[height=1cm,offset=.5cm] {rule based learning} -%D \framed[height=1cm,offset=0cm] {rule based learning} -%D \framed[height=1cm,offset=none] {rule based learning} -%D \framed[height=1cm,offset=overlay]{rule based learning} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \startlinecorrection -%D \hbox{\getbuffer} -%D \stoplinecorrection -%D -%D \startbuffer -%D \framed[offset=.5cm] {rule based learning} -%D \framed[offset=0cm] {rule based learning} -%D \framed[offset=none] {rule based learning} -%D \framed[offset=overlay]{rule based learning} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \startlinecorrection -%D \hbox{\getbuffer} -%D \stoplinecorrection -%D -%D \startbuffer -%D \framed[strut=nee,offset=.5cm] {rule based learning} -%D \framed[strut=nee,offset=0cm] {rule based learning} -%D \framed[strut=nee,offset=none] {rule based learning} -%D \framed[strut=nee,offset=overlay]{rule based learning} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \startlinecorrection -%D \hbox{\getbuffer} -%D \stoplinecorrection -%D -%D \startbuffer -%D \framed[width=3cm,align=left] {rule\\based\\learning} -%D \framed[width=3cm,align=middle] {rule\\based\\learning} -%D \framed[width=3cm,align=right] {rule\\based\\learning} -%D \framed[width=fit,align=middle] {rule\\based\\learning} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \startlinecorrection -%D \hbox{\dontcomplain\getbuffer} -%D \stoplinecorrection -%D -%D So now we're ready for the complicated stuff. We distinguish -%D between borders with straight lines and those with round -%D corners. When using the first alternative it is possible to -%D turn off one or more lines. More fancy shapes are also -%D possible by specifying dedicated backgrounds. Turning lines -%D on and off is implemented as efficient as possible and as a -%D result is interface language dependant. This next -%D implementation evolved from simpler ones. It puts for -%D instance the rules on top of the content and provides -%D additional offset capabilities. The lot of calls to other -%D macros makes this mechanism not that easy to comprehend. - -%D Getting the backgrounds right takes less code. Again we -%D have to take care of additional offsets. - -\def\dobackedbox - {\doifelsevalue{\@@framed\c!backgroundoffset}\v!frame % new - {\dobackgroundbox\c!frameoffset} - {\dobackgroundbox\c!backgroundoffset}} - -%D We handle left, right or middle alignment as well as fixed -%D or free widths and heights. Each combination gets its own -%D macro. - -%D The following code handles one-liners: \type{align={line,flushright}}. -%D Beware, since we entered a group and either or not grab the next -%D bgroup token, we need to finish the group in the oneliner mode. - -\ifx\raggedoneliner\undefined \chardef\raggedoneliner\zerocount \fi - -\def\doformatonelinerbox % beware: assumes explicit preceding bgroup - {\ifcase\raggedoneliner - \expandafter\nodoformatonelinerbox - \else - \expandafter\dodoformatonelinerbox - \fi} - -\def\dodoformatonelinerbox - {\dowithnextboxcontent - {\ignorespaces} - {\hbox to \hsize - {\ifcase\raggedstatus\or\hss\or\hss\fi - \unhbox\nextbox \removeunwantedspaces - \ifcase\raggedstatus\or \or\hss\or\hss\fi}% - \egroup} - \hbox} - -\def\nodoformatonelinerbox % grabs { - {\let\next=} - -%D The handlers: - -\def\doformatboxSomeFormat - {\vbox to \!!framedheight - \bgroup - \let\postprocessframebox\relax - \forgetall - \oninterlineskip - \hsize\!!framedwidth - \vsize\!!framedheight - \doframedsetups - \raggedcommand - \dobeforeframedbox - \bgroup - \localbegstrut - \aftergroup\localendstrut - \aftergroup\doafterframedbox - \aftergroup\egroup - \doformatonelinerbox} - -\def\doformatboxNoFormat - {\vbox to \!!framedheight - \bgroup - \let\postprocessframebox\relax - \forgetall - \oninterlineskip - \hsize\!!framedwidth - \vsize\!!framedheight - \doframedsetups - \raggedcenter - \vss - \bgroup - \localbegstrut - \aftergroup\localendstrut - \aftergroup\vss - \aftergroup\egroup - \doformatonelinerbox} - -\def\doformatboxHeight - {\vbox to \!!framedheight - \bgroup - \let\postprocessframebox\relax - \forgetall - \oninterlineskip - \doframedsetups - \raggedcommand - \vss - \bgroup - \aftergroup\localendstrut - \aftergroup\vss - \aftergroup\egroup - \localbegstrut - \doformatonelinerbox} - -\def\doformatboxWidth - {\vbox - \bgroup - \let\postprocessframebox\relax - \forgetall - \oninterlineskip - \hsize\!!framedwidth - \doframedsetups - \raggedcommand - \dobeforeframedbox - \bgroup - \localbegstrut - \aftergroup\localendstrut - \aftergroup\doafterframedbox - \aftergroup\egroup - \doformatonelinerbox} - -\def\doformatboxVSize - {\vbox to \!!framedheight - \bgroup - \let\postprocessframebox\relax - \forgetall - \vsize\!!framedheight - \doframedsetups - \vss - \bgroup - \aftergroup\vss - \aftergroup\egroup - \hbox - \bgroup - \aftergroup\egroup - \localstrut - \doformatonelinerbox} - -\def\doformatboxHSize - {\hbox to \!!framedwidth - \bgroup - \let\postprocessframebox\relax - \forgetall - \doframedsetups - \hss - \localstrut - \bgroup - \aftergroup\hss - \aftergroup\egroup - \doformatonelinerbox} - -\def\doformatboxNoSize - {\hbox - \bgroup - \let\postprocessframebox\relax - \doframedsetups - \localstrut - \doformatonelinerbox} - -\let\doframedsetups\relax - -%D On the next page we show some examples of how these macros -%D come into action. The examples show us how -%D \type {fit}, \type {broad} dimensions influence the -%D formatting. Watch the visualized struts. \footnote {Here we -%D used \type {\showstruts}.} -%D -%D \startpostponing -%D \bgroup -%D \showstruts -%D \dontcomplain -%D \startlinecorrection -%D \halign{#\enskip&#\enskip&#\enskip&#\enskip&#\enskip&#\cr -%D \framed[width=.2\hsize, height=.2\hsize, align=] {a\par b\par c}& -%D \framed[width=.2\hsize, height=broad, align=] {a\par b\par c}& -%D \framed[width=.2\hsize, height=fit, align=] {a\par b\par c}& -%D \framed[width=fit, height=.2\hsize, align=] {a\par b\par c}& -%D \framed[width=fit, height=broad, align=] {a\par b\par c}& -%D \framed[width=fit, height=fit, align=] {a\par b\par c}\cr -%D \noalign{\vskip1em} -%D \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\par b\par c}& -%D \framed[width=.2\hsize, height=broad, align=yes] {a\par b\par c}& -%D \framed[width=.2\hsize, height=fit, align=yes] {a\par b\par c}& -%D \framed[width=fit, height=.2\hsize, align=yes] {a\par b\par c}& -%D \framed[width=fit, height=broad, align=yes] {a\par b\par c}& -%D \framed[width=fit, height=fit, align=yes] {a\par b\par c}\cr -%D \noalign{\vskip1em} -%D \framed[width=.2\hsize, height=.2\hsize, align=right] {a\par b\par c}& -%D \framed[width=.2\hsize, height=broad, align=right] {a\par b\par c}& -%D \framed[width=.2\hsize, height=fit, align=right] {a\par b\par c}& -%D \framed[width=fit, height=.2\hsize, align=right] {a\par b\par c}& -%D \framed[width=fit, height=broad, align=right] {a\par b\par c}& -%D \framed[width=fit, height=fit, align=right] {a\par b\par c}\cr -%D \noalign{\vskip1em} -%D \framed[width=.2\hsize, height=.2\hsize, align=left] {a\par b\par c}& -%D \framed[width=.2\hsize, height=broad, align=left] {a\par b\par c}& -%D \framed[width=.2\hsize, height=fit, align=left] {a\par b\par c}& -%D \framed[width=fit, height=.2\hsize, align=left] {a\par b\par c}& -%D \framed[width=fit, height=broad, align=left] {a\par b\par c}& -%D \framed[width=fit, height=fit, align=left] {a\par b\par c}\cr -%D \noalign{\vskip1em} -%D \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\par b\par c}& -%D \framed[width=.2\hsize, height=broad, align=middle] {a\par b\par c}& -%D \framed[width=.2\hsize, height=fit, align=middle] {a\par b\par c}& -%D \framed[width=fit, height=.2\hsize, align=middle] {a\par b\par c}& -%D \framed[width=fit, height=broad, align=middle] {a\par b\par c}& -%D \framed[width=fit, height=fit, align=middle] {a\par b\par c}\cr} -%D \stoplinecorrection -%D \blank[2*big] -%D \egroup -%D \stoppostponing - -%D \macros -%D {framednoflines, framedlastlength} -%D -%D It is possible to let the frame macro calculate the width -%D of a centered box automatically (\type {fit}). When -%D doing so, we need to reshape the box: - -% The next implementation is frozen! It preserves the depth, -% otherwise we get problems with framed display math and auto -% width. - -\newcount\framednoflines -\newdimen\framedlastlength - -\def\resetshapeframebox - {\framednoflines \zerocount - \framedlastlength\zeropoint} - -\let\framedboxwidth \!!zeropoint -\let\framedboxheight\!!zeropoint -\let\framedboxdepth \!!zeropoint - -\chardef\reshapeframeboxmethod\plusone % 0=no flush, 1=old method 2=no depth messing - -% \newbox\luashapebox -% -% \def\doreshapeframedbox -% {\setbox\luashapebox\box\framebox -% \ctxlua{commands.doreshapeframedbox(\number\luashapebox)}% -% \setbox\framebox\box\luashapebox} - -\def\doreshapeframedbox{\ifvbox\framebox\ctxlua{commands.doreshapeframedbox(\number\framebox)}\fi} - -%D The two variables \type {\framednoflines} and \type -%D {\framedlastlength} can be used in a second pass to -%D optimized framed material. - -% torture test / strange case (much depth) / method 2 needed -% -% \startTEXpage[frame=on] -% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula -% test outside formula -% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula -% \blank[big] -% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula -% test outside formula -% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula -% \stopTEXpage - -%D The examples on the next page show how one can give the -%D frame as well as the background an additional offset and -%D even a bit more depth. The blue outline is the frame, the -%D red box is the background and the small black outline is the -%D visualization of the resulting box, that is, we applied -%D \type{\ruledhbox} to the result. - -%D \startpostponing -%D \bgroup -%D \unprotect -%D \dontcomplain -%D -%D \startbuffer -%D \vbox to \vsize -%D \bgroup -%D \startalignment[middle] -%D \vss -%D \dontleavehmode\vbox to .8\vsize -%D \bgroup -%D \hsize=300pt -%D \setupframed -%D [background=color, -%D backgroundcolorachtergrondkleur=darkred, -%D width=300pt, -%D height=60pt, -%D framecolorkaderkleur=DemoBlue, -%D rulethickness=2pt] -%D \def\status% -%D {backgroundoffset=\framedparameter\c!backgroundoffset\\ -%D frameoffset=\framedparameter\c!frameoffset\\ -%D depth=\framedparameter\c!depth} -%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}} -%D \vss -%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}} -%D \vss -%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}} -%D \vss -%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}} -%D \vss -%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}} -%D \vss -%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}} -%D \egroup -%D \vss -%D \stopalignment -%D \egroup -%D \stopbuffer -%D -%D \getbuffer \page -%D -%D {\setupframed[depth=4pt]\getbuffer} \page -%D -%D \protect -%D \egroup -%D \stoppostponing - -%D When typesetting the framed box inline, we have to keep the -%D baseline intact outside as well as inside the framed box. - -\def\doinlineframedbox - {\scratchdimen\dimexpr\strutdp+\ruledlinewidth\relax - \ifboxhasoffset - \advance\scratchdimen \framedparameter\c!offset - \fi - \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% - \ht\framebox\strutht - \dp\framebox\strutdp - \box\framebox} - -%D We can also lower the box over the natural depth of the -%D line. - -\def\doloweredframedbox - {\ht\framebox\dimexpr\ht\framebox+\dp\framebox-\strutdp\relax - \dp\framebox\strutdp - \box\framebox} - -%D Hanging the content is mainly meant for cases like the -%D following: -%D -%D \starttyping -%D \framed[strut=no] -%D {\framed[height=2cm,location=hanging]{test}% -%D \framed[height=1cm,location=hanging]{test}} -%D \stoptyping - -\def\dohangingframedbox % best with strut=no - {\scratchdimen\dimexpr\ht\framebox+\dp\framebox\relax - \ht\framebox\zeropoint - \dp\framebox\scratchdimen} - -%D We can draw lines from left to right and top to bottom by -%D using the normal \type{\hairline} command. Both directions -%D need a different treatment. -%D -%D \startbuffer -%D \framed[width=4cm] {alfa\hairline beta\hairline gamma} -%D \framed[height=2cm] {alfa\hairline beta\hairline gamma} -%D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \startlinecorrection -%D \hbox{\getbuffer} -%D \stoplinecorrection -%D -%D These macros try to adapt their behaviour as good as -%D possible to the circumstances and act as natural as -%D possible. - -\def\vboxedhairline - {\bgroup - \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi - \dimen4=\dimexpr\dimen2+\ruledlinewidth\relax - \setbox0\vbox - {\advance\hsize 2\dimen4 - \vskip\dimen2 - \hrule - \!!height\ruledlinewidth - \!!depth\zeropoint - \!!width\hsize - \vskip\dimen2}% - %\endgraf\nointerlineskip\endgraf - %\moveleft\dimen4\box0 - %\endgraf\nointerlineskip\localbegstrut - \endgraf\obeydepth\nointerlineskip - \moveleft\dimen4\box0 - \endgraf\nointerlineskip\localbegstrut % beware, we might kill it in a style using \vskip\lineheight - \egroup} % so this must not be changed - -\def\hboxedhairline % use framed dimen - {\bgroup - \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi - \ifboxhasheight - \dimen4\dimexpr\localheight/2+\strutdp-2\ruledlinewidth\relax - \dimen6\dimexpr\localheight/2-\strutdp+2\ruledlinewidth\relax - \else - \dimen4\dimexpr\strutht+\dimen2\relax - \dimen6\dimexpr\strutdp+\dimen2\relax - \fi - \unskip - \setbox\scratchbox\hbox - {\hskip\dimen2 - \vrule\!!height\dimen4\!!depth\dimen6\!!width\ruledlinewidth - \hskip\dimen2}% - \ht\scratchbox\strutht - \dp\scratchbox\strutdp - \box\scratchbox - \ignorespaces - \egroup} - -%D The argument of the frame command accepts \type{\\} as a -%D sort of newline signal. In horizontal boxes it expands to a -%D space. - -\def\vboxednewline - {\endgraf\ignorespaces} - -\def\hboxednewline - {\unskip\normalspace\ignorespaces} - -%D We can set each rule on or off. The default setting is -%D inherited from \type{frame}. An earlier implementation -%D use a bit different approach, but the new one seems more -%D natural: -%D -%D \bgroup -%D \setuptyping[margin=0pt] -%D \startlinecorrection -%D \startbuffer -%D \framed[offset=overlay,frame=on]{\darkred\blackrule} -%D \stopbuffer -%D \hbox{\getbuffer\vbox{\typebuffer}} -%D -%D \startbuffer -%D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule} -%D \stopbuffer -%D \hbox{\getbuffer\vbox{\typebuffer}} -%D -%D \startbuffer -%D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule} -%D \stopbuffer -%D \hbox{\getbuffer\vbox{\typebuffer}} -%D -%D \startbuffer -%D \framed[offset=overlay,frame=off]{\darkred\blackrule} -%D \stopbuffer -%D \hbox{\getbuffer\vbox{\typebuffer}} -%D -%D \startbuffer -%D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule} -%D \stopbuffer -%D \hbox{\getbuffer\vbox{\typebuffer}} -%D -%D \startbuffer -%D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule} -%D \stopbuffer -%D \hbox{\getbuffer\vbox{\typebuffer}} -%D \stoplinecorrection -%D \egroup - -%D \macros -%D {setupblackrules} -%D -%D The graphic capabilities of \TEX\ do not go beyond simple -%D filled rules, except of course when using specials. Let's -%D start with a warning: using this commands is far more slower -%D than using the \TEX\ primitives \type{\hrule} and -%D \type{\vrule}, but they save us some tokens. The -%D characteristics of these rule drawing command can be set by: -%D -%D \showsetup{setupblackrules} - -\def\setupblackrules - {\dodoubleargument\getparameters[\??bj]} - -%D \macros -%D {blackrule} -%D -%D The simple command draws only one rule. Its optional -%D argument can be used to specify the dimensions. By setting -%D the width, height or depth to \type {max}, one gets the -%D natural dimensions. -%D -%D \showsetup{blackrule} - -\def\doblackrule[#1]% - {\hbox\bgroup - \getparameters[\??bj][#1]% - \setstrut - \doif\@@bjwidth \v!max{\def\@@bjwidth {1em}}% - \doif\@@bjheight\v!max{\def\@@bjheight{\strutht}}% - \doif\@@bjdepth \v!max{\def\@@bjdepth {\strutdp}}% - \localstartcolor[\@@bjcolor]% - \vrule - \!!width \@@bjwidth - \!!height\@@bjheight - \!!depth \@@bjdepth - \localstopcolor - \egroup} - -\unexpanded\def\blackrule - {\dosingleempty\doblackrule} - -%D \macros -%D {blackrules} -%D -%D One can call for a sequence of black rules, if needed -%D equally spaced over the given width. -%D -%D \showsetup{blackrules} -%D -%D The two alternative calls are therefore: -%D -%D \startbuffer -%D Tell me, is this according to the \blackrules[n=6]? -%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear. -%D \stopbuffer -%D -%D \typebuffer -%D -%D or: -%D -%D \startvoorbeeld -%D \startlines -%D \getbuffer -%D \stoplines -%D \stopvoorbeeld -%D -%D We could of course have implemented this macro using -%D \type{\leaders}, but this would probably have taken more -%D tokens. - -\def\doblackrules[#1]% - {\hbox\bgroup - \getparameters[\??bj][#1]% - \!!widtha\@@bjwidth - \!!widthb\@@bjdistance - \doif\@@bjalternative\c!b - {\scratchcounter\@@bjn - \ifnum\scratchcounter=\plusone - \!!widthb\zeropoint - \else - \advance\scratchcounter \minusone - \advance\!!widtha -\scratchcounter\!!widthb - \divide \!!widtha \@@bjn - \fi}% - \localstartcolor[\@@bjcolor]% - \dorecurse\@@bjn - {\vrule - \!!width \!!widtha - \!!height\@@bjheight - \!!depth \@@bjdepth - \hskip\!!widthb}% - \unskip - \localstopcolor - \egroup} - -\unexpanded\def\blackrules - {\dosingleempty\doblackrules} - -%D The next commands can be used to draw margin rules. We -%D support two methods: \marginrule{one for in||line use} and -%D one that acts on a paragraph. Drawing a margin rule is -%D rather straightforward because we can use the commands that -%D put text in the margin. - -\def\dodrawmarginrule - {\setbox\scratchbox\hbox - {\vrule\!!depth\strutdepth\!!height\strutheight\!!width\@@karulethickness}% - \smashbox\scratchbox % no \vsmash !!! - \box\scratchbox} - -\def\drawmarginrule - {\strut\inleft{\dodrawmarginrule}} - -%D \macros -%D {marginrule} -%D -%D The first method gobbles words and simply puts a bar in the -%D margin. This method is not entirely robust. -%D -%D \showsetup{marginrule} - -\definecomplexorsimple\marginrule - -\def\simplemarginrule - {\let\processword\drawmarginrule - \processwords} - -\def\complexmarginrule[#1]% - {\ifnum#1<\@@kalevel\relax \else - \def\@@kadefaultwidth{#1}% - \expandafter\simplemarginrule - \fi} - -%D We need an auxiliary variable - -\def\@@kadefaultwidth{1} - -%D \macros -%D {setupmarginrules} -%D -%D This macro definitions show us that we can pass an optional -%D level, which is matched against the previous set one. The -%D level can be set up with -%D -%D \showsetup{setupmarginrules} - -\def\setupmarginrules - {\dodoubleargument\getparameters[\??ka]} - -%D \macros -%D {startmarginrule} -%D -%D The second method collects text and reformats it afterwards, -%D using the shapebox macros. We prevent local margin rules. -%D -%D \showsetup{startmarginrule} - -\definecomplexorsimple\startmarginrule - -\def\simplestartmarginrule - {\bgroup - \let\drawmarginrule\relax - \let\stopmarginrule\dostopmarginrule - \beginofshapebox} - -\def\complexstartmarginrule[#1]% - {\bgroup - \let\drawmarginrule\relax - \ifnum#1<\@@kalevel\relax - \let\stopmarginrule\egroup - \else - \def\@@kadefaultwidth{#1}% - \let\stopmarginrule\dostopmarginrule - \expandafter\beginofshapebox - \fi} - -\def\dostopmarginrule - {\endofshapebox - \reshapebox - {\hbox{\inleftmargin{\dodrawmarginrule}\box\shapebox}}% - \flushshapebox - \egroup} - -%D \startbuffer -%D \setupmarginrules[level=5] -%D -%D \startmarginrule[1] -%D First we set the level at~5. Next we typeset this first -%D paragraph as a level~1 one. As expected no rule show up. -%D \stopmarginrule -%D -%D \startmarginrule[5] -%D The second paragraph is a level~5 one. As we can see here, -%D the marginal rule gets a width according to its level. -%D \stopmarginrule -%D -%D \startmarginrule[8] -%D It will of course be no surprise that this third paragraph -%D has a even thicker margin rule. This behavior can be -%D overruled by specifying the width explictly. -%D \stopmarginrule -%D \stopbuffer -%D -%D In next example we show most features. Watch the rule -%D thickness adapting itself to the level. -%D -%D \startvoorbeeld -%D \getbuffer -%D \stopvoorbeeld -%D -%D We just said: -%D -%D \typebuffer - -%D \macros -%D {vl, hl} -%D -%D The command \type{\vl} draws a vertical rule \vl\ with strut -%D dimensions, multiplied with the factor specified in the -%D optional argument. The height and depth are clipped \vl[3] -%D to the baselinedistance. Its horizontal counterpart -%D \type{\hl} draws a horizontal rule \hl\ with a width of 1em, -%D multiplied with the optional factor. The horizontal rule is -%D drawn on top of the baseline. -%D -%D \showsetup{vl} -%D \showsetup{hl} - -\def\complexvl[#1]% - {\bgroup - \!!dimena#1\strutht - \!!dimenb#1\strutdp - \setbox\scratchbox\hbox - {\vrule - \!!width \linewidth - \!!height\!!dimena - \!!depth \!!dimenb}% - \dp\scratchbox\strutdp - \ht\scratchbox\strutht - \box\scratchbox - \egroup} - -\def\complexhl[#1]% - {\hbox - {\vrule - \!!width #1\s!em - \!!height\linewidth - \!!depth \zeropoint}} - -\definecomplexorsimple\vl \def\simplevl{\complexvl[1]} -\definecomplexorsimple\hl \def\simplehl{\complexhl[1]} - -%D \macros -%D {hairline, thinrule, thinrules, setupthinrules} -%D -%D Drawing thin lines can of course easily be accomplished by -%D the \TEX\ primitives \type{\hrule} and \type{\vrule}. The -%D next few macros however free us from some specifications. -%D -%D \startbuffer -%D some text -%D -%D \hairline -%D -%D some more text -%D -%D \thinrule -%D -%D more and more text -%D -%D hi \thinrule\ there -%D -%D and then the final text -%D \stopbuffer -%D -%D \typebuffer -%D -%D becomes -%D -%D \startvoorbeeld -%D \getbuffer -%D \stopvoorbeeld -%D -%D So we've got -%D -%D \showsetup{hairline} -%D \showsetup{thinrule} -%D -%D Both can be set up with: -%D -%D \showsetup{setupthinrules} -%D -%D We also have -%D -%D \showsetup{thinrules} -%D -%D which looks like: \thinrules[n=2] - -\def\thinrule - {\strut - \bgroup - \chardef\ruletype\plusone - \processaction - [\@@dlalternative] - [ \v!a=>\chardef\ruletype0,% no line - %\v!b=>\chardef\ruletype1,% height/depth - \v!c=>\chardef\ruletype2,% topheight/botdepth - % 11=>\chardef\ruletype1,% fallback for backgrounds - 0=>\chardef\ruletype0,% compatible with backgrounds - % 1=>\chardef\ruletype1,% compatible with backgrounds - 2=>\chardef\ruletype2]% compatible with backgrounds - \doifsomething\@@dlrulethickness - {\linewidth\@@dlrulethickness}% - \ifdim\linewidth=\zeropoint - \chardef\ruletype\zerocount - \else - \doifnot\@@dlframe\v!on{\chardef\ruletype\zerocount}% - \fi - \ifnum\ruletype=\plusone - \doif\@@dlheight\v!max{\let\@@dlheight\!!plusone}% - \doif\@@dldepth \v!max{\let\@@dldepth \!!plusone}% - \else - \let\@@dlheight\!!plusone - \let\@@dldepth\!!plusone - \fi - \freezedimensionwithunit\@@dlheight\strutht - \freezedimensionwithunit\@@dldepth\strutdp - \divide\linewidth \plustwo - \doifelse\@@dlbackground\v!color - {\startcolor[\@@dlbackgroundcolor]% - \ifnum\ruletype=\plustwo % prevent overshoot due to rounding - \leaders - \hrule - \!!height\dimexpr\@@dlheight-.5\linewidth\relax - \!!depth \dimexpr\@@dldepth -.5\linewidth\relax - \hfill - \else - \leaders - \hrule - \!!height\@@dlheight - \!!depth \@@dldepth - \hfill - \fi - \stopcolor - \ifcase\ruletype - % no rule - \or - \startcolor[\@@dlcolor]% - \hfillneg - \leaders\hrule\!!height\linewidth\!!depth\linewidth\hfill - \stopcolor - \or - \startcolor[\@@dlcolor]% - \hfillneg\leaders\hrule\!!height\dimexpr-\@@dldepth+\linewidth\relax\!!depth\@@dldepth\hfill - \hfillneg\leaders\hrule\!!height\@@dlheight\!!depth\dimexpr-\@@dlheight+\linewidth\relax\hfill - \stopcolor - \fi} - {\ifcase\ruletype \else - \startcolor[\@@dlcolor]% - \leaders\hrule\!!height\@@dlheight\!!depth\@@dldepth\hfill - \stopcolor - \fi}% - \strut - \carryoverpar\egroup} - -\def\hairline - {\endgraf - \thinrule - \endgraf} - -\def\dosetupthinrules[#1]% - {\getparameters[\??dl][#1]} - -\def\setupthinrules - {\dosingleargument\dosetupthinrules} - -\def\dothinrules[#1]% - {\bgroup - \dosetupthinrules[#1]% - \@@dlbefore - \assignvalue\@@dlinterlinespace\@@dlinterlinespace{1.0}{1.5}{2.0}% - \spacing\@@dlinterlinespace - \dorecurse\@@dln - {\ifnum\recurselevel=\@@dln \dothinrulesnobreak \else - \ifnum\recurselevel=2 \dothinrulesnobreak \fi\fi - \thinrule - \ifnum\recurselevel<\@@dln\relax - % test needed, else messed up whitespace - \ifx\@@dlinbetween\empty - \softbreak - \else - \endgraf - \nowhitespace - \@@dlinbetween - \fi - \fi}% - \doifelsenothing\@@dlafter - {\carryoverpar\egroup} - {\@@dlafter\egroup}} - -\def\thinrules - {\dosingleempty\dothinrules} - -%D A couple of examples are given below. -%D -%D \startbuffer -%D \setupthinrules[n=3,inbetween=,color=gray] -%D -%D test test \thinrules\ test test \par -%D test test \thinrules [color=green] test test \par -%D test test \thinrules [height=max, depth=max] test test \par -%D -%D \setupthinrules[height=.9,depth=.9] -%D -%D test test \thinrules\ test test \par -%D test test \thinrules [alternativevariant=b] test test \par -%D test test \thinrules [alternativevariant=c] test test \par -%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par -%D \stopbuffer -%D -%D \typebuffer {\getbuffer} -%D -%D There are a couple of alternative ways to visualize rules -%D using backgrounds. At first sight these may look strange, -%D but they make sense in educational settings. The -%D alternatives are more or less compatible with the more -%D advanced \METAPOST\ based implementation. -%D -%D \startbuffer[a] -%D \setupthinrules -%D [n=2, -%D backgroundcolor=gray , -%D rulethickness=1pt, -%D colorkleur=donkerblauw, -%D after=\blank, -%D before=\blank] -%D \stopbuffer -%D -%D \typebuffer[a] -%D -%D \startbuffer[b] -%D \thinrules[alternativevariant=a] -%D \thinrules[alternativevariant=b] -%D \thinrules[alternativevariant=c] -%D \stopbuffer -%D -%D \typebuffer[b] \getbuffer[a,b] -%D -%D \startbuffer[b] -%D \thinrules[alternativevariant=a,background=color] -%D \thinrules[alternativevariant=b,background=color] -%D \thinrules[alternativevariant=c,background=color] -%D \stopbuffer -%D -%D \typebuffer[b] \getbuffer[a,b] -%D -%D \startbuffer[b] -%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color] -%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color] -%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color] -%D \stopbuffer -%D -%D \typebuffer[b] \getbuffer[a,b] - -%D \macros -%D {optimizethinrules} -%D -%D By saying \type {\thinrulestrue} or \type {-false}, we -%D can influence the way dangling lines are handled. - -\newif\ifoptimizethinrules \optimizethinrulestrue - -\def\dothinrulesnobreak - {\ifoptimizethinrules\penalty500\fi} - -%D \macros -%D {startframedtext, setupframedtexts, defineframedtext} -%D -%D The general framing command we discussed previously, is not -%D entirely suited for what we call framed texts, as for -%D instance used in intermezzo's. The next examples show what -%D we have in mind. -%D -%D \startbuffer[framed-0] -%D \setupframedtexts -%D [frame=off, -%D width=\hsize, -%D background=screen] -%D -%D \startframedtext -%D By default the framed text is centered \dots -%D \stopframedtext -%D -%D \startframedtext[right] -%D \dots\ but we can also align left, middle and right. -%D \stopframedtext -%D \stopbuffer -%D -%D \startbuffer[framed-1] -%D \defineframedtext -%D [Example] -%D [width=6cm, -%D height=5cm] -%D -%D \startExample -%D \typebuffer[framed-1] -%D \stopExample -%D \stopbuffer -%D -%D \startbuffer[framed-2] -%D \defineframedtext -%D [Example] -%D [width=6cm] -%D -%D \startExample -%D \typebuffer[framed-2] -%D \stopExample -%D \stopbuffer -%D -%D \startbuffer[framed-3] -%D \defineframedtext -%D [Example] -%D [height=5cm] -%D -%D \startExample -%D \typebuffer[framed-3] -%D \stopExample -%D \stopbuffer -%D -%D \startbuffer[framed-4] -%D \defineframedtext -%D [Example] -%D [width=fit,height=broad] -%D -%D \Example{a very exciting example} -%D \stopbuffer -%D -%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup -%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup -%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup -%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup -%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup -%D -%D Here we can see that we have a predefined framed text class -%D as well as the tools for defining our own. So we have: -%D -%D \showsetup{setupframedtexts} -%D -%D as well as the definition command: -%D -%D \showsetup{defineframedtext} -%D -%D that generates two commands: -%D -%D \showsetup{start<>} -%D \showsetup{<>} -%D -%D The next definition shows the defaults. - -\def\dodefineframedtext[#1][#2]% - {\presetlocalframed[\??kd#1]% - \getparameters[\??kd#1] - [\c!width=0.75\hsize, - \c!height=\v!fit, - \c!align=\v!yes, - \c!top=, - \c!bottom=\vfill, - \c!offset=1em, - \c!bodyfont=, - \c!style=, - \c!color=, - \c!left=, - \c!right=\hfill, - \c!before=\blank, - \c!after=\blank, - \c!inner=, - \c!frame=\v!on, - \c!topframe=, - \c!bottomframe=, - \c!leftframe=, - \c!rightframe=, - \c!radius=.5\bodyfontsize, - \c!corner=\v!rectangular, - \c!foregroundcolor=, - \c!foregroundstyle=, - \c!background=, - \c!backgroundcolor=, - \c!backgroundscreen=\@@rsscreen, - \c!linecorrection=\v!on, - \c!depthcorrection=\v!on, - \c!margin=\v!standard, - \c!orientation=, - \c!indenting=, - #2]% - \setvalue{\e!start#1}{\dostartframedtext[#1]}% - \setvalue{\e!stop #1}{\dostopframedtext }% - \setvalue {#1}{\doframedtext [#1]}} - -\def\defineframedtext - {\dodoubleempty\dodefineframedtext} - -%D We define the general (and original) case by just saying: - -\defineframedtext[\v!framedtext] - -%D We need several steps before the actual job is done, -%D because we have to handle an optional identifier (and -%D because these commands evolved out of a single case). - -\def\framedtextparameter#1#2% - {\csname\??kd#1#2\endcsname} - -\def\dosetupframedtexts[#1][#2]% - {\ifsecondargument - \def\docommand##1{\getparameters[\??kd##1][#2]}% - \processcommacommand[#1]\docommand % new, #1 may be macro - \else - \getparameters[\??kd\v!framedtext][#1]% - \fi} - -\def\setupframedtexts - {\dodoubleempty\dosetupframedtexts} - -\def\dostartframedtext - {\bgroup\dotripleempty\dodostartframedtext} - -\def\dodostartframedtext[#1][#2][#3]% - {\doifassignmentelse{#2} - {\dododostartframedtext[#1][][#2]} - {\dododostartframedtext[#1][#2][#3]}} - -\setfalse\framedtextlocationnone - -\def\dododostartframedtext[#1][#2][#3]% #3 only passed to framed, not to framedtext - {\doifsomething{#2}{\setvalue{\??kd#1\c!location}{#2}}% does not listen to #3 - \setfalse\framedtextlocationnone - \processaction % \v!low en \v!depth are already taken ! - [\framedtextparameter{#1}\c!location] - [ \v!left=>\letvalue{\??kd#1\c!left }\relax - \letvalue{\??kd#1\c!right}\hfill, - \v!right=>\letvalue{\??kd#1\c!left }\hfill - \letvalue{\??kd#1\c!right}\relax, - \v!middle=>\letvalue{\??kd#1\c!left }\hfill - \letvalue{\??kd#1\c!right}\hfill, - \v!none=>\letvalue{\??kd#1\c!left }\relax % new - \letvalue{\??kd#1\c!right}\relax % new - \settrue\framedtextlocationnone]% - \letvalue{\??kd#1\c!location}\empty - % removed 06/2001 - % \forgetparindent - % added 06/2001 [see demo-bbv] - \localhsize\hsize \checkframedtext - % so far - \setbox\framebox\vbox - \startboxedcontent - \hsize\localhsize - % \insidefloattrue % ? better - \normalexpanded{\noexpand\switchtobodyfont[\framedtextparameter{#1}\c!bodyfont]}% - \startcolor[\framedtextparameter{#1}\c!color]% - \localframed[\??kd#1][\c!strut=\v!no,#3]% todo: use delayedstrut - \bgroup - \let\\=\endgraf - \framedtextparameter{#1}\c!inner % oud spul - \doifvalue{\??kd#1\c!depthcorrection}\v!on % new, inside box - {\bgroup - \verticalstrut - % we need \nowhitespace in case of setups setting whitespace - % nb, not safe, text vs \vbox as next - \vskip-\struttotal - \nowhitespace % na vskip ! new 20/05/2004, fails with next content being box (\scale{..}) - }% - \doinhibitblank % \blank[\v!disable]% plaatst signal -\setupindenting[\framedtextparameter{#1}\c!indenting]% - \doconvertfont{\framedtextparameter{#1}\c!style}\empty - \def\dostopframedtext{\dodostopframedtext{#1}{#2}}} - -%D The \type {none} option is handy for nested usage, as -%D in the presentation styles, where we don't want -%D interference. - -\def\dodostopframedtext#1#2% % no \baselinecorrection, see faq docs - {\endgraf - \removelastskip - \doifvalue{\??kd#1\c!depthcorrection}\v!on % local and global - {\forgetall - \vskip-\struttotal - \verticalstrut - \egroup - \forgetall - \vskip-\lineheight - % will be an option, not default - % \setbaselinecorrections - % \donegbotbaselinecorrection - \verticalstrut} - \stopboxedcontent - \stopcolor - \ifconditional\framedtextlocationnone - \egroup - \box\framebox - \else\ifinsidefloat - \egroup - \box\framebox - \else - \egroup - \doplacement[\??kd#1][\c!depthcorrection=\v!off]{\box\framebox}% - \fi\fi - \egroup} - -%D Placement can be ignored: -%D -%D \starttyping -%D \hbox to \hsize \bgroup -%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext -%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext -%D \egroup -%D -%D \hbox to \hsize \bgroup -%D \setupframedtexts[location=none]% -%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext -%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext -%D \egroup -%D \stoptyping - -%D The simple brace (or group) delimited case is typeset -%D slightly different and is not aligned. - -\def\doframedtext - {\bgroup\dodoubleempty\dodoframedtext} - -\def\dodoframedtext[#1][#2]% beware! - {\normalexpanded{\noexpand\switchtobodyfont[\getvalue{\??kd#1\c!bodyfont}]}% - \localframed[\??kd#1][\c!strut=\v!no,#2]% - \bgroup - \blank[\v!disable]% - \let\\=\endgraf - \getvalue{\??kd#1\c!inner}% % kleur naar outer level - \dostartattributes{\??kd#1}\c!style\c!color\empty - \bgroup - \aftergroup\docloseframedtext - \let\next=} - -\def\docloseframedtext - {\removelastskip - \dostopattributes - \egroup - \egroup} - -%D \macros -%D {defineframed} -%D -%D One can also define simple framed texts, using: -%D -%D \showsetup{defineframed} - -\def\defineframed - {\dodoubleempty\dodefineframed} - -\def\dodefineframed[#1][#2]% - {\iffirstargument - \setvalue{#1}{\dodoubleempty\doframed[#2]}% - \fi} - -\def\doframed[#1][#2]% - {\framed[#1,#2]} - -%D \macros -%D {textrule, starttextrule, setuptextrules} -%D -%D Putting rules before and after a paragraph is very space -%D sensitive, but the next command handles that quite well. It -%D comes in two disguises: -%D -%D \startbuffer -%D \textrule[top]{fragments} -%D \input reich -%D \textrule -%D \stopbuffer -%D -%D \bgroup \typebuffer \getbuffer \egroup -%D -%D \startbuffer -%D \setuptextrules -%D [width=90pt,distance=12pt,rulecolor=blue, -%D bodyfont=small,style=\sc,color=red] -%D -%D \starttextrule{Ship Building Tools} -%D \nl \setuptolerance[tolerant] \input materie -%D \stoptextrule -%D \stopbuffer -%D -%D \bgroup \typebuffer \getbuffer \egroup -%D -%D \startbuffer -%D \setuptextrules -%D [location=inmargin, -%D bodyfont=small,style=slantedbold] -%D -%D \starttextrule{wonderful} -%D \input tufte -%D \stoptextrule -%D \stopbuffer -%D -%D \bgroup \typebuffer \getbuffer \egroup -%D -%D The formal definition of these commands is: -%D -%D \showsetup{textrule} -%D \showsetup{starttextrule} -%D \showsetup{setuptextrules} -%D -%D The implementation looks a bit complicated due to the -%D optional arguments. - -\def\setuptextrules - {\dodoubleargument\getparameters[\??tl]} - -\def\complextextrule[#1]% if needed we can make it installable - {\let\next\dobottomtextrule - \processaction - [#1] - [ \v!top=>\let\next\dotoptextrule, - \v!middle=>\let\next\domiddletextrule, - \v!bottom=>\let\next\dobottomtextrule]% - \dosinglegroupempty\next} - -\definecomplexorsimple\textrule - -\def\simpletextrule - {\dosinglegroupempty\dounknowntextrule} - -\def\docomplextextrule#1% - {\bgroup - \advance\hsize\dimexpr-\rightskip-\leftskip\relax - \setbox\scratchbox\hbox to \hsize - {\dimen4\dimexpr .5ex+.5\linewidth\relax - \dimen6\dimexpr-.5ex+.5\linewidth\relax - \doifnothing{#1}\firstargumentfalse - \iffirstargument - \doifelse\@@tllocation\v!inmargin - {\llap{\doattributes\??tl\c!style\c!color{#1}\hskip\leftmargindistance}} - {\color[\@@tlrulecolor] - {\vrule\!!height\dimen4\!!depth\dimen6\!!width\@@tlwidth}% - \hbox spread 2\dimexpr\@@tldistance\relax - {\hss\doattributes\??tl\c!style\c!color{\strut#1}\hss}}% - \fi - \color[\@@tlrulecolor] - {\leaders\hrule\!!height\dimen4\!!depth\dimen6\hfill}}% - \ht\scratchbox\strutht - \dp\scratchbox\strutdp - \noindent\box\scratchbox -%\nobreak\verticalstrut\kern-\struttotal -% evt \witruimte - \egroup} - -\def\dotoptextrule#1% - {\page[\v!preference] % interferes - %\whitespace % no - \@@tlbefore - \docomplextextrule{#1}% -% todo, option: \doifnothing{#1}{\ruledvskip-.5ex} - \nowhitespace - \@@tlinbetween - \endgraf} - -\def\dodobottomtextrule#1#2% - {\ifhmode - \endgraf - \fi - \dimen0\strutdp - \ifdim\prevdepth>\strutdp\else % was <\strutdp - \ifdim\prevdepth>\zeropoint - \advance\dimen0 -\prevdepth - \fi - \fi - \advance\dimen0 .5ex - \vskip\dimen0 -% == -% \vskip\dimexpr \strutdp + .5ex -% \ifdim\prevdepth>\strutdp\else\ifdim\prevdepth>\zeropoint-\prevdepth\fi\fi\relax -% - \@@tlinbetween - \doifelsenothing{#2} - {\bgroup - \advance\hsize\dimexpr-\rightskip-\leftskip\relax - \nointerlineskip - \moveleft-\leftskip\vbox - {\color[\@@tlrulecolor] - {\hrule\!!depth\linewidth\!!height\zeropoint\!!width\hsize}}% - \egroup} - {\docomplextextrule{#2}}% - \ifvmode\prevdepth\zeropoint\fi - #1% - \page[\v!preference]} - -\def\dobottomtextrule - {\dodobottomtextrule\@@tlafter} - -\def\domiddletextrule - {\dodobottomtextrule\@@tlinbetween} - -\def\dounknowntextrule - {\iffirstargument - \@EA\dotoptextrule - \else - \@EA\dobottomtextrule\@EA\empty - \fi} - -%D The grouped commands also supports bodyfont switching: - -\def\starttextrule#1% - {\bgroup - \def\dounknowntextrule{\domiddletextrule} - \dotoptextrule{#1} - \bgroup - \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}} - -\def\stoptextrule - {\par - \egroup - \dobottomtextrule\empty - \egroup} - -%D \macros -%D {fillinrules, setupfillinrules} -%D -%D The next few commands do not really deserve a place in a -%D core module, because they deal with specific typography. -%D Nevertheless I decided to make them part of the core, -%D because they permit us to make questionaires. Let's start -%D with some examples. -%D -%D \fillinrules[n=2,width=fit]{first} -%D \fillinrules[n=2,width=broad]{first} -%D \fillinrules[n=2,width=3cm]{first} -%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first} -%D \fillinrules[n=2]{first}{last} -%D \fillintext{first}{last} \input reich \par -%D -%D The main command is \type{\fillinrules}. This command takes -%D one and an optional second argument and sets a paragraph with -%D empty visualized lines. -%D -%D \showsetup{fillinrules} -%D \showsetup{setupfillinrules} - -\def\setupfillinrules - {\dodoubleargument\getparameters[\??il]} - -\definecomplexorsimpleempty\fillinrules - -\def\complexfillinrules[#1]% - {\def\docomplexfillinrules##1##2% - {\dodocomplexfillinrules[#1]{##1}{##2}{\thinrules - [\c!n=\@@iln,\c!interlinespace=\@@ilinterlinespace,\c!before=,\c!after=]}}% - \dodoublegroupempty\docomplexfillinrules} - -\def\dodocomplexfillinrules[#1]#2#3#4% - {\endgraf - \@@ilbefore - \begingroup - \setupfillinrules[#1]% - \noindent - \doifsomething{#2} - {\doifelse\@@ilwidth\v!fit - {\let\@@ildistance\!!zeropoint - \hbox} - {\doifelse\@@ilwidth\v!broad - {\hbox} - {\hbox to \@@ilwidth}}% - \bgroup - \doattributes\??il\c!style\c!color{\strut#2\hfill\@@ilseparator}% - \hskip\@@ildistance - \egroup}% - %\hangindent=\wd0\relax % tzt hang=yes,n - %\parindent=\hangindent - %\box0\relax - \setupwhitespace[\v!big]% - \ignorespaces - #4% - \doifsomething{#3} - {\kern\@@ildistance - \doattributes\??il\c!style\c!color{#3\strut}}% - \endgroup - \endgraf - \@@ilafter} - -%D \macros -%D {fillintext} -%D -%D To provide compatible layouts when texts and lines are -%D mixed, one can typeset a paragraph by using the command -%D \type{\fillintext}. -%D -%D \showsetup{fillintext} - -\definecomplexorsimpleempty\fillintext - -\def\complexfillintext[#1]% rather rough, using an \unhbox is suboptimal - {\def\docomplexfillintext##1##2% - {\dowithnextbox - {\dodocomplexfillinrules[#1]{##1}{\hfill##2}{\unhbox\nextbox\unskip}}% - \hbox\bgroup\let\par\egroup\ignorespaces}% - \dodoublegroupempty\docomplexfillintext} - -%D \macros -%D {fillinline, setupfillinlines} -%D -%D Another member of the family takes care of putting a (often -%D small) rule after a piece of text, like -%D -%D \startbuffer -%D \fillinline \input reich \par -%D \fillinline[margin=0cm] \input reich \par -%D \stopbuffer -%D -%D \startvoorbeeld -%D \getbuffer -%D \stopvoorbeeld -%D -%D which was typeset by saying: -%D -%D \typebuffer -%D -%D The two commands that take care of this are: -%D -%D \showsetup{fillinline} -%D \showsetup{setupfillinlines} - -\def\setupfillinlines - {\dodoubleargument\getparameters[\??iv]} - -\definecomplexorsimpleempty\fillinline - -\def\complexfillinline[#1]% - {%\endgraf % interferes with \definedescription cum suis - \@@ivbefore - \begingroup - \setupfillinlines[#1]% - \advance\rightskip \@@ivmargin - \parfillskip\zeropoint - \def\par % very dangerous - {\let\par\endgraf % -) - \ifhmode\unskip\hfill\fi - \scratchdimen\dimexpr\@@ivwidth-\@@ivdistance\relax - \ifdim\scratchdimen>\@@ivmargin\else\expandafter\rlap\fi - {\kern\@@ivdistance - \vrule - \!!width \scratchdimen - \!!height.5\linewidth - \!!depth .5\linewidth}% - \endgraf % ! - \endgroup - \endgraf % ! - \@@ilafter}} - -%D \stopdocumentation -%D \bgroup -%D -%D \setupframedtexts -%D [setuptext] -%D [background=color,backgroundcolor=white] -%D -%D \startbuffer -%D \setupbackground -%D [backgroundoffset=4pt, -%D background=screen, -%D frame=on, -%D framecolor=red, -%D leftoffset=2pt] -%D \stopbuffer -%D -%D \getbuffer -%D -%D \startbackground -%D -%D \macros -%D {setupbackground,startbackground,background} -%D -%D The section deals with backgrounds in the running text. This -%D means that texts is to be collected and split over pages. To -%D show what can be done, we provide this part of the -%D documentation with some gray background and a red frame. -%D Both the background and frame can have all characteristics -%D of \type{\framed}. This time we used the setting: -%D -%D \typebuffer -%D -%D The implementation is not that sophisticated, but suffices. -%D The main problem with this kind of functionality is to get -%D the spacing all right. - -%D Specifying the background is more or less the same as -%D specifying a framed box. -%D -%D \showsetup{setupbackground} - -\presetlocalframed[\??ag] - -\def\dosetupbackground[#1]% - {\getparameters[\??ag][#1]% - \doifelse\@@agstate\v!start - {\let\startbackground\dostartbackground - \let\stopbackground \dostopbackground - \let\background \dobackground} - {\let\startbackground\relax - \let\stopbackground \relax - \let\background \relax}} - -\def\setupbackground - {\dosingleargument\dosetupbackground} - -%D Actually typesetting the background is implemented rather -%D straightforward. We need to handle some spacing as well as -%D the (often) a bit smaller horizontal size. -%D -%D \showsetup{startbackground} -%D -%D Although we could have used a scratch one, we first -%D declare a boolean. - -% 0=no-split, 1=no-split+indent, 2=split, 3=split+indent - -\chardef\backgroundsplitmode\plusthree - -%D The \type{\vbox to \lineheight{}\vskip\zeropoint} -%D construction gives the first real line a decent height by -%D adding a dummy line. - -\def\dostartbackground - {\endgraf - \bgroup - \setbox0\vbox\bgroup - \vbox to \lineheight{}\vskip\zeropoint - \blank[\v!disable] - % \advance\hsize -\@@agleftoffset - % \advance\hsize -\@@agrightoffset - \leftskip \@@agleftoffset % new ** - \rightskip\@@agrightoffset} % new ** - -%D This dummy line is removed by \type{\setbox2=\vsplit0 to -%D \lineheight}. That way \type{\topskip} takes care of the -%D lineheight. I'll probably forget to apply this trick -%D elsewhere. - -\def\dostopbackground % improved version (i hope) - {\endgraf - \removelastskip - \egroup - \dimen2\leftskip % new ** - \forgetall - \ifinsidefloat - \chardef\backgroundsplitmode\zerocount - \fi - \ifcase\backgroundsplitmode - \localframed[\??ag][\c!offset=\v!overlay]{\box0}% - \or - \hskip\dimen2 - \localframed[\??ag][\c!offset=\v!overlay]{\box0}% - \else - \splitmaxdepth\boxmaxdepth - \splittopskip\topskip - \setbox2\vsplit0 to \lineheight % get rid of fake line - \loop - \ifdim\pagetotal=\zeropoint % empty page - \scratchdimen\textheight - \chardef\backgroundsplit\plusone % split to max height - \else - \setbox\scratchbox\vbox{\@@agbefore}% - \scratchdimen\dimexpr\pagegoal-\ht\scratchbox-\pagetotal\relax - \chardef\backgroundsplit\plustwo % split to partial height - \fi - \advance\scratchdimen\dimexpr-\@@agtopoffset-\@@agbottomoffset\relax - \ifdim\scratchdimen>2\lineheight\relax % reasonable, will be configurable - \ifdim\ht0>\scratchdimen % larger than page - \setbox2\vsplit0 to \scratchdimen - \else - \setbox2\box0 - \chardef\backgroundsplit\zerocount % no split - \fi - \setbox2\vbox \ifcase\backgroundsplit\or to \textheight \fi % max split - {\vskip\@@agtopoffset - \popsplitproperties - \unvcopy2 - \prevdepth\dp2 - \obeydepth - \vskip\@@agbottomoffset - \vfill} - \@@agbefore - \ifcase\backgroundsplit\or\or % partial split - \ifdim\pagegoal<\maxdimen - \pagegoal=1.2\pagegoal % be a bit more tolerant - \fi - \fi - \startlinecorrection - %\localframed[\??ag][\c!offset=\v!overlay]{\hskip\@@agleftoffset\box2\hskip\@@agrightoffset}% - \ifnum\backgroundsplitmode=\plusthree \hskip\dimen2 \fi % - \localframed[\??ag][\c!offset=\v!overlay]{\box2}% new ** - \stoplinecorrection - \ifcase\backgroundsplit % no split - \@@agafter - \else % some split - \vfill\eject % geen \page ! - \fi - \else - \page - \fi - \ifdim\ht0>\zeropoint \repeat - \fi - \egroup - \endgraf} - -%D As a bonus we also have a short command, that is of not -%D much use, but kept there for historic reasons. -%D -%D \showsetup{background} - -\def\dobackground - {\bgroup - \dowithnextbox - {\localframed[\??ag][\c!offset=\v!overlay]{\flushnextbox}\egroup} - \vbox} - -%D \stopdocumentation -%D \stopbackground -%D \egroup - -%D New, for the moment private; let's see when GB finds out -%D about this one and its obscure usage. It's used in: -%D -%D \startbuffer -%D \defineframedtext -%D [tabulateframe] -%D [offset=overlay, -%D backgroundoffset=3pt, -%D background=color, -%D backgroundcolor=green] -%D -%D \setuptabulate -%D [tabulate] -%D [frame=tabulateframe] -%D -%D \setuptables -%D [frame=tabulateframe] -%D -%D \input tufte -%D -%D \starttabulate[|l|l|] -%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR -%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR -%D \stoptabulate -%D -%D \input tufte -%D -%D \starttable[|l|l|] -%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR -%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR -%D \stoptable -%D \stopbuffer -%D -%D \typebuffer - -\def\defineframedcontent - {\dodoubleempty\dodefineframedcontent} - -\def\dodefineframedcontent[#1][#2]% - {\presetlocalframed[\??fc#1]% - \getparameters[\??fc#1] - [\c!leftoffset=\zeropoint, - \c!rightoffset=\getvalue{\??fc#1\c!leftoffset}, - \c!topoffset=\zeropoint, - \c!bottomoffset=\getvalue{\??fc#1\c!topoffset}, - \c!strut=\v!no, - \c!offset=\v!overlay, - \c!linecorrection=\v!no, - \c!left=, - \c!right=, - #2]} - -\let\setuplocalframed\getparameters - -\def\setupframedcontent - {\dodoubleempty\dosetupframedcontent} - -\def\dosetupframedcontent[#1][#2]% - {\def\docommand##1{\getparameters[\??fc##1][#2]}% - \processcommacommand[#1]\docommand} - -\def\startframedcontent[#1]% - {\bgroup - \let\stopframedcontent\egroup - \doifnot{#1}\v!off - {\doifdefined{\??fc#1\c!frame} - {\def\stopframedcontent{\dostopframedcontent{#1}}% - \dostartframedcontent{#1}}}} - -\def\dostartframedcontent#1% - {\setbox\framebox\hbox\bgroup - \setlocalhsize - \hsize\localhsize - \advance\hsize\dimexpr-\getvalue{\??fc#1\c!leftoffset}-\getvalue{\??fc#1\c!rightoffset} \relax - \advance\vsize\dimexpr-\getvalue{\??fc#1\c!topoffset} -\getvalue{\??fc#1\c!bottomoffset}\relax - \hskip\getvalue{\??fc#1\c!leftoffset}% - \vbox\bgroup - \vskip\getvalue{\??fc#1\c!topoffset}% - \vbox\bgroup - \forgetall - \blank[\v!disable]} - -\def\dostopframedcontent#1% - {\removelastskip - \egroup - \vskip\getvalue{\??fc#1\c!bottomoffset}% - \egroup - \hskip\getvalue{\??fc#1\c!rightoffset}% - \egroup - \doifvalue{\??fc#1\c!width}\v!fit - {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox - \ifinsidefloat - \donefalse - \else - \doifelsevalue{\??fc#1\c!linecorrection}\v!yes\donetrue\donefalse - \fi - % plaats ? - \ifdone\startlinecorrection\fi - \getvalue{\??fc#1\c!left}% new - \localframed[\??fc#1]{\box\framebox}% - \getvalue{\??fc#1\c!right}% new - \ifdone\stoplinecorrection\fi - \egroup} - -%D \macros -%D {backgroundline} -%D -%D For the moment an undocumented feature, but a cancidate -%D for going public. - -\def\backgroundline[#1]% - %{\doifsomething{#1}{\dobackgroundline{#1}}\hbox} - {\doifcolorelse{#1}{\dobackgroundline{#1}\hbox}\hbox} - -% \def\backgroundline[#1]% -% {\doifcolor{#1}{\dobackgroundline{#1}}\hbox} - -\def\dobackgroundline#1% - {\dowithnextbox - {\hbox - {\localcolortrue - \startcolor[#1]% - \vrule - \!!width \nextboxwd - \!!height\nextboxht - \!!depth \nextboxdp - \stopcolor - \hskip-\nextboxwd - \flushnextbox}}} - -%D \macros -%D {encircled} -%D -%D Some not so robust left||overs (borrowed from Knuth, -%D \TEX Book\ page 356): - -\def\encircled#1% - {{\ooalign{\hfil\raise0.07ex\hbox{{\tx#1}}\hfil\crcr\mathhexbox20D}}} - -\let\omcirkeld\encircled - -\setuplinewidth - [\v!medium] - -\setupframed - [\c!width=\v!fit, - \c!height=\v!broad, - \c!lines=, - \c!offset=0.25ex, % \defaultframeoffset - \c!empty=\v!no, - \c!frame=\v!on, - \c!topframe=, - \c!bottomframe=, - \c!leftframe=, - \c!rightframe=, - \c!radius=.5\bodyfontsize, - \c!rulethickness=\linewidth, - \c!corner=\v!rectangular, - \c!depth=\!!zeropoint, - \c!foregroundcolor=, - \c!foregroundstyle=, - \c!background=, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!backgroundoffset=\!!zeropoint, - \c!framecolor=, - \c!frameoffset=\!!zeropoint, - \c!backgroundcorner=\framedparameter\c!corner, - \c!backgroundradius=\framedparameter\c!radius, - \c!backgrounddepth=\framedparameter\c!depth, - \c!framecorner=\framedparameter\c!corner, - \c!frameradius=\framedparameter\c!radius, - \c!framedepth=\framedparameter\c!depth, - \c!component=, - \c!align=, - \c!bottom=\vss, - \c!top=, - \c!strut=\v!yes, - \c!autostrut=\v!yes, - \c!location=\v!normal, - \c!orientation=, - \c!autowidth=\v!yes, - \c!setups=] - -\setupscreens - [%\c!factor=1.0, % obsolete - %\c!method=\v!external, % obsolete - \c!screen=0.95] - -\setupblackrules - [\c!n=3, - \c!width=1em, - \c!height=1ex, - \c!depth=\!!zeropoint, - \c!alternative=\c!a, - \c!distance=.25ex, - \c!color=] - -\setupmarginrules - [\c!level=0, - \c!rulethickness=\@@kadefaultwidth\linewidth] - -\setupthinrules - [\c!interlinespace=\v!small, - \c!n=3, - \c!before=, - \c!inbetween={\blank[\v!white]}, - \c!after=, - \c!color=, - \c!height=.5\linewidth, - \c!depth=.5\linewidth, - \c!frame=\v!on, % compatible with textbackgrounds - \c!alternative=\v!b, - \c!backgroundcolor=, - \c!background=, - \c!rulethickness=] - -\setuptextrules - [\c!location=\v!left, - \c!before=\blank, - \c!after=\blank, - \c!inbetween=, - \c!width=2em, - \c!style=\v!bold, - \c!color=, - \c!rulecolor=, - \c!bodyfont=, - \c!distance=.5em] - -\setupfillinrules - [\c!width=\v!broad, - \c!distance=1em, - \c!before=\blank, - \c!after=\blank, - \c!n=1, - \c!interlinespace=\v!small, - \c!separator=, - \c!style=\v!normal, - \c!color=] - -\setupfillinlines - [\c!width=3cm, - \c!margin=\@@ivwidth, - \c!distance=1em, - \c!before=\blank, - \c!after=\blank] - -\setupbackground - [\c!leftoffset=.5\bodyfontsize, - \c!rightoffset=\@@agleftoffset, - \c!topoffset=\!!zeropoint, - \c!bottomoffset=\@@agtopoffset, - \c!state=\v!start, - \c!radius=.5\bodyfontsize, - \c!corner=\v!rectangular, - \c!frame=\v!off, - \c!color=, - \c!depth=\!!zeropoint, - \c!background=\v!screen, - \c!backgroundcolor=\@@agcolor, - \c!screen=\@@rsscreen, - \c!before=, - \c!after=] - -% Experimental extension: - -\def\c!loffset{loffset} -\def\c!roffset{roffset} -\def\c!toffset{toffset} -\def\c!boffset{boffset} - -\getparameters - [\??oi] - [\c!loffset=\zeropoint, - \c!roffset=\zeropoint, - \c!toffset=\zeropoint, - \c!boffset=\zeropoint] - -\newdimen\!!framedloffset -\newdimen\!!framedroffset -\newdimen\!!framedtoffset -\newdimen\!!framedboffset - -\def\setextraframedoffsets - {\boxhasextraoffsetfalse - \!!framedloffset\framedparameter\c!loffset - \!!framedroffset\framedparameter\c!roffset - \!!framedtoffset\framedparameter\c!toffset - \!!framedboffset\framedparameter\c!boffset - \ifzeropt\!!framedloffset\else \advance\!!framedwidth -\!!framedloffset \boxhasextraoffsettrue \fi - \ifzeropt\!!framedroffset\else \advance\!!framedwidth -\!!framedroffset \boxhasextraoffsettrue \fi - \ifzeropt\!!framedtoffset\else \advance\!!framedheight-\!!framedtoffset \boxhasextraoffsettrue \fi - \ifzeropt\!!framedboffset\else \advance\!!framedheight-\!!framedboffset \boxhasextraoffsettrue \fi} - -\def\applyextraframedoffsets - {\setbox\framebox\vbox\bgroup - \vskip\!!framedtoffset - \hbox\bgroup - \hskip\!!framedloffset - \box\framebox - \hskip\!!framedroffset - \egroup - \vskip\!!framedboffset - \egroup} - -\protect \endinput diff --git a/tex/context/base/core-sec.tex b/tex/context/base/core-sec.tex deleted file mode 100644 index 6cc0fbbf9..000000000 --- a/tex/context/base/core-sec.tex +++ /dev/null @@ -1,2572 +0,0 @@ -%D \module -%D [ file=core-sec, -%D version=1997.03.31, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Sectioning, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% start-stop per section en dan combineren met sectieblok; in dat geval -% eenvoudiger per-* acties - -% nummeren per sectieblok implementeren - -% this module needs a clean up, currently some manipulations -% take place multiple times; also, some clever recursive level -% thing makes more sense - -% in manual (zie prikkels) : tussen=\blanko is enige hook om -% met kop-in-hoofd een spatiering af te dwingen - -\writestatus{loading}{ConTeXt Core Macros / Sectioning} - -\unprotect - -% new and to be tested - -\unexpanded\def\separatorlist#1% - {\ifx\sepnumber\undefined\def\sepnumber{0}\fi - \increment\sepnumber - \getfromcommacommand[#1][\sepnumber]% - \ifx\commalistelement\empty - \getcommalistsize[#1]% - \def\sepnumber{\number\commalistsize}% - \getfromcommacommand[#1][\sepnumber]% - \fi - \commalistelement} - -% \setuphead[section] [separator=\separatorlist{?,!,*}] -% \setuphead[subsection][separator=\separatorlist{??,!!,**}] -% -% \let\spr\separatorlist % this will enable this feature -% -% \setuphead[section] [separator={?,!,*}] -% \setuphead[subsection][separator={??,!!,**}] -% -% \setupheads[separator={A,B,C,D,E,F}] -% \chapter{test} -% \section{test} \subsection{test} \subsection{test} -% \section{test} \subsection{test} \subsection{test} - -% from now on, internaly numbers are separated by a period -% and postprocessed on demand; this will change to {} {} {} - -\def\numberseparator {.} % reasonable default -\def\sectionseparator{-} % was : but is now - - -\def\@@filterfirstpart [#1--#2]{#1} -\def\@@filtersecondpart [#1--#2]{#2} - -\def\@@filterblockpart [#1--#2--#3]{#1} -\def\@@filternumberpart [#1--#2--#3]{#2} -\def\@@filterpagepart [#1--#2--#3]{#3} -\def\@@filterblocknumberpart[#1--#2--#3]{#1--#2} - -\def\@@filterheadpart[#1]{\@EA\@@dofilterheadpart\@EA[#1-0]} -\def\@@filtertailpart[#1]{\@EA\@@dofiltertailpart\@EA[#1-0]} - -\def\@@dofilterheadpart[#1-#2]{#1} -\def\@@dofiltertailpart[#1-#2]{#2} - -\def\@@filterlevelpart[#1--#2--#3]{\@@dofilterlevelpart[#2-0-0-0-0]} - -\def\@@dofilterlevelpart[#1-0-0-0-#2]{#1} - -\def\gobbleuntilrelax#1\relax{} - -\def\separatednumber #1{\doseparatednumber #1.\empty\relax} -\def\removefirstprefix#1{\doremovefirstprefix#1.\empty\relax} -\def\removeallprefixes#1{\doremoveallprefixes#1.\empty\relax} - -\def\doseparatednumber#1.#2% - {#1% - \ifx#2\empty - \@EA\gobbleuntilrelax - \else \numberseparator - \@EA\doseparatednumber - \fi#2} - -\def\doremoveallprefixes#1.#2% - {\ifx#2\empty - #1\@EA\gobbleuntilrelax - \else - \@EA\doremoveallprefixes - \fi#2} - -\def\doremovefirstprefix#1.#2% - {\ifx#2\empty - #1\@EA\gobbleuntilrelax - \else - \@EA\noremovefirstprefix - \fi#2} - -\def\noremovefirstprefix#1.\empty\relax - {#1} - -% we need to expand in order to get something separatable - -\def\dohandleheadnumber#1% - {\expanded{\separatednumber{#1}}} - -\def\dodochecknumber#1#2#3% will become ugly after speed up - {\bgroup - \doifinstringelse{.0}{.#2} - {\doifnot{#3}\v!by - {%\debuggerinfo\m!systems{number #1 #3 becomes \getnumbervariable{#1\c!way}}% - \setevalue{\@@thenumber{#1}\c!way}{#3}% geen \xdef, gaat mis met \subpage - \dochecknumber{#1}}} % tricky and ugly - {\doifnotvalue{\@@thenumber{#1}\s!check}{#2} - {% new, calculate accumulated number - \scratchcounter\getvalue{\@@thenumber{#1}\c!n}\relax - \advance\scratchcounter\countervalue{\@@thenumber{#1}}\relax - \setxvalue{\@@thenumber{#1}\c!n}{\the\scratchcounter}% - % - \setcounter{\@@thenumber{#1}}{0\getvalue{\@@thenumber{#1}\c!start}}% - \setxvalue{\@@thenumber{#1}\c!way\c!local}{\getvalue{\@@thenumber{#1}\c!way}}% - \setxvalue{\@@thenumber{#1}\s!check}{#2}}}% - \egroup} - -\def\dochecknumber#1% - {\edef\currentsection{\csname\??by\csname\@@thenumber{#1}\c!way\endcsname\endcsname}% - \ifx\currentsection\empty\else - \dodochecknumber - {#1}% - {\csname\currentsection\c!number\endcsname}% - {\v!by\previoussection\currentsection}% - \fi} - -\def\checknumber[#1]% - {\bgroup - %\ifcase\blocklevel\else - \ifdoingblocks - \doifnotvalue{\@@thenumber{#1}\c!blockway}\v!no\setblockcounters - \fi - \dochecknumber{#1}% - \egroup} - -\def\rawsectionnumber#1% - {\countervalue{\??se#1}} - -\def\precedingseparator{\@@koseparator} % brrr - -\def\domakeprecedingsectionnumber[#1]% will become ugly after speed up - {\bgroup % added - \globallet\precedingsectionnumber\empty - \ifsectionnumber - \doifvalue{\??sb\@@sectionblock\c!number}\v!yes % added - {\doifelsevalue{\@@thenumber{#1}\c!sectionnumber}\v!yes - \donetrue\donefalse - \doifvalue{\@@thenumber{#1}\c!sectionnumber}\v!number - {\donetrue\let\@@sectionconversion\gobbleoneargument}% - \ifdone - \edef\currentsection - {\getvalue{\??by\getvalue{\@@thenumber{#1}\c!way\c!local}}}% - \doifnot\currentsection\zerosection - {\doifnot{\@@sectionvalue\currentsection}{0} - {\xdef\precedingsectionnumber - {\getvalue{\currentsection\c!number}% - \spr{\precedingseparator}}}}% - \fi}% - \fi - \egroup} - -\def\makeprecedingsectionnumber[#1]% - {\bgroup - %\ifnum\blocklevel>0 - %\ifcase\blocklevel\else - \ifdoingblocks - \doifnotvalue{\@@thenumber{#1}\c!blockway}\v!no\setblockcounters - \fi - \domakeprecedingsectionnumber[#1]% - \egroup} - -% \def\makesectionnumber[#1]% -% {\makeprecedingsectionnumber[#1]% -% \xdef\composedsectionnumber% -% {\precedingsectionnumber\convertednumber[#1]}}% -% -% hack needed for chinese and oldstyle in normal tex, will change - -\def\makesectionnumber[#1]% - {\bgroup - \forceunexpanded % i don't like this hack - \makeprecedingsectionnumber[#1]% - \xdef\composedsectionnumber% was \xdef maar dat gaat fout met font switches - {\precedingsectionnumber\convertednumber[#1]}% - \egroup} - -% \def\preparethenumber#1#2#3% {\??id#1} \number \result -% {\doifelsevaluenothing{#1\c!separator} -% {\let\numberseparator\empty -% \let#3#2} -% {% was \unexpanded \edef, but we need it unexpanded ! -% \edef\numberseparator{\spr{\getvalue{#1\c!separator}}}% -% \doifelsenothing{\executeifdefined{#1\c!suffix}\empty} -% {\edef#3% -% {\@EA\separatednumber\@EA{#2}% -% }}%\stp{\getvalue{#1\c!stopper}}}} -% {\edef#3% -% {\@EA\separatednumber\@EA{#2}% -% \spr{\getvalue{#1\c!separator}}% -% \getvalue{#1\c!suffix}% -% \stp{\getvalue{#1\c!stopper}}}}}} -% -% some day we do a real cleanup - -\def\analyzenumber#1#2#3% {\??id#1} \(precedingsection)number \result - {% was \unexpanded \edef, but we need it unexpanded ! - \doifelsenothing{\executeifdefined{#1\c!suffix}\empty} - {\let \numbersuffix \empty} - {\edef\numbersuffix{\spr{\getvalue{#1\c!suffix}}}}% - \doifelsenothing{\executeifdefined{#1\c!stopper}\empty} - {\let \numberstopper \empty} - {\edef\numberstopper{\spr{\getvalue{#1\c!stopper}}}}% - \doifelsenothing{\executeifdefined{#1\c!separator}\empty} - {\let \numberseparator \empty} - {\edef\numberseparator{\spr{\getvalue{#1\c!separator}}}}% - \let\numberprefix\empty} - -\def\preparefullnumber#1#2#3% {\??id#1} \(precedingsection)number \result - {\analyzenumber{#1}#2#3% - \ifx\numberseparator\empty - \edef\numberprefix{#2}% - \else - \edef\numberprefix{\@EA\separatednumber\@EA{#2}}% - \fi - \ifx\numbersuffix\empty - \ifx\numberprefix\empty - \let #3\empty - \else - \edef#3{\numberprefix\numberstopper}% - \fi - \else - \ifx\numberprefix\empty - \edef#3{\numbersuffix\numberstopper}% - \else - \edef#3{\numberprefix\numberseparator\numbersuffix\numberstopper}% - \fi - \fi} - -\def\prepareprefixnumber#1#2#3% {\??id#1} \number \result - {\analyzenumber{#1}#2#3% - \ifx\numberseparator\empty - \edef\numberprefix{#2}% - \else - \edef\numberprefix{\@EA\separatednumber\@EA{#2}}% - \fi - \let#3\numberprefix} - -\def\sectionnumberonly[#1]% - {\makesectionnumber[#1]% - \composedsectionnumber} - -% sectioning - -\newcount\nofsections - -\let\zerosection \v!text -\let\firstsection\empty -\let\lastsection \empty -\let\@@sectie \empty -\let\@@koppeling \empty - -\makecounter{\??se\v!text} - -\letvalueempty{\??se\v!text\c!before} -\letvalueempty{\??se\v!text\c!after } - -\setvalue {\v!text\c!number}{0} -\letvalueempty{\v!text\s!format} - -\letvalueempty{\??sk\v!text} -\letvalueempty{\??sk } - -\letvalue{\??by }\v!text -\letvalue{\??by\v!text }\v!text -\letvalue{\??by\v!all }\v!text -\letvalue{\??by\v!by }\v!text -\letvalue{\??by\v!by\v!text}\v!text -\letvalue{\??by\v!by\v!all }\v!text -\letvalue{\??by\v!by\v!page}\v!text % see footnotes - -\def\sectionofhead#1{\executeifdefined{\??ko#1\c!section}\s!unknown} - -\def\setupsection - {\dotripleempty\dosetupsection} - -\def\dosetupsection[#1]% - {\doifdefinedelse{\??se#1} - {\dodosetupsection[#1]}% - {\dodosetupsection[\sectionofhead{#1}]}} - -\def\dodosetupsection[#1][#2][#3]% - {\doifdefined{\??se#1} - {\ifthirdargument - \getparameters[\??se#1#2][#3]% - \else - \getparameters[\??se#1][#2]% - \fi - \doifelsevalue{\??se#1\c!previousnumber}\v!yes - {\setvalue{#1\c!number}{\@@longsectionnumber {#1}}} - {\setvalue{#1\c!number}{\@@shortsectionnumber{#1}}}}} - -\def\docouplemarking[#1][#2]% - {\doifdefinedelse{\??ko#2\c!section} - {\docouplemarking[#1][\getvalue{\??ko#2\c!section}]} - {\def\donexttrackcommando##1% - {\edef\coupledmarkings{\getvalue{\??se##1\c!marking}}% - \doifelse{##1}{#2} - {\addtocommalist{#1}\coupledmarkings} - {\removefromcommalist{#1}\coupledmarkings}% - \setevalue{\??se##1\c!marking}{\coupledmarkings}% - \donexttracklevel{##1}}% - \donexttracklevel{\zerosection}}} % \firstsection - -\def\couplemarking - {\dodoubleargument\docouplemarking} - -\def\decouplemarking[#1]% - {\couplemarking[#1][]} - -\def\definesection[#1]% - {\doifundefined{\??se#1} - {\doifelsenothing\firstsection - {\def\firstsection{#1}% - \setevalue{\??se#1\c!before}{\v!text}% - \setevalue{\??se\v!text\c!after}{#1}} - {\setevalue{\??se\commalistelement\c!after}{#1}% commalistelement ? - \setevalue{\??se#1\c!before}{\lastsection}% - \setevalue{\??se\lastsection\c!after}{#1}}% - \advance\nofsections \plusone - \setevalue{\??se#1\c!level}{\the\nofsections}% - \letvalue{\??se#1\c!after}\empty - \setvalue{\e!next#1}{\@@nextsectionnumber{#1}}% - \setvalue{#1\c!number}{\@@longsectionnumber{#1}}% - \setvalue{#1\s!format}{\@@longformatnumber{#1}}% - \setevalue{\??by#1}{#1}% - \setevalue{\??by\v!by#1}{#1}% - \makecounter{\??se#1}% - \makecounter{\??se\v!last#1}% GB - \edef\lastsection{#1}% - \setvalue{\??sk#1}{#1}% - \letvalue{\??se#1\c!marking}\empty - \setupsection[#1][\c!previousnumber=\v!yes]}}% - -\def\previoussection#1{\csname\??se#1\c!before\endcsname} -\def\nextsection #1{\csname\??se#1\c!after \endcsname} - -\let\preservedsection\v!unknown % \def\preservedsection{\firstsection} - -\def\checkpreservevalueafter#1% GB - {\ifnum\getvalue{\??se#1\c!level}<\nofsections - \edef\preservedsection{\getvalue{\??se#1\c!after}}% - \ifconditional\@@resetsubheadnumbers - \setcounter{\??se\v!last\preservedsection}\zerocount % {0}% - \else - \setcounter{\??se\v!last\preservedsection}{\countervalue{\??se\preservedsection}}% - \fi - \fi} - -\def\@@setsectionnumber#1#2% - {\letgvalueempty{\??se#1\s!start}% signal i.p.v. boolean - \setcounter{\??se#1}{#2}% - \checkpreservevalueafter{#1}% GB - \resetsectioncounters{#1}% - \checkpagecounter} - -\def\@@nextsectionnumber#1% patched by GB - {\letgvalueempty{\??se#1\s!start}% signal i.p.v. boolean - \ifnum\countervalue{\??se\v!last#1}>\zerocount - \setcounter{\??se#1}{\countervalue{\??se\v!last#1}}% - \setcounter{\??se\v!last#1}\zerocount % {0}% - \fi - \pluscounter{\??se#1}% - \checkpreservevalueafter{#1}% - \resetsectioncounters{#1}% - \checkpagecounter} - -\def\@@sectionvalue#1% % nog niet overal doorgevoerd - {\countervalue{\??se#1}} % zoeken op \??se - -% suited for chinese too: - -\def\@@sectionconversion#1#2% a doublure with \@@shortsectionnumber - {\ifnum#2=0 0\else % else troubles with \uchar - \@EA\ifx\csname\??se#1\@@sectionblock\c!conversion\endcsname\relax - \@EA\ifx\csname\??se#1\c!conversion\endcsname\relax - #2% - \else - \convertnumber{\getvalue{\??se#1\c!conversion}}{#2}% - \fi - \else - \convertnumber{\getvalue{\??se#1\@@sectionblock\c!conversion}}{#2}% - \fi - \fi} - -% \def\@@sectionlevel#1% -% {\ifundefined{\??se#1\c!level}0\else\getvalue{\??se#1\c!level}\fi} - -\def\@@sectionlevel#1% - {\executeifdefined{\??se#1\c!level}0} - -% Omdat een markering kan worden herdefinieerd moeten we -% eerst testen of er wel een keten||afhankelijkheid is. - -\def\resetsectionmarks#1% can invoke a break - {\ifundefined{\??se#1}% - \fastresetmarker[\mainmarking{#1}]% % redundant \mainmarking - \else - \let\donexttrackcommando\doresetsectionmarks - \donexttracklevel{#1}% - \fi} - -\def\doresetsectionmarks#1% - {\ifundefined{\??se#1\c!marking}\else % skip zero level - \fastresetmarkerlist[\csname\??se#1\c!marking\endcsname]% - \fi - \donexttracklevel{#1}} - -% I'm not sure if the next one is better: -% -% \def\doresetsectionmarks#1% -% {\ifundefined{\??se#1\c!markering}% skip zero level -% \donexttracklevel{#1}% -% \else -% \fastresetmarkerlist[\csname\??se#1\c!markering\endcsname]% -% \fi} -% -% and indeed, it isn't, actually, it does not work at all, so let's drop it. - -% packaged: -% -% \def\resetsectioncounters#1% -% {\def\donexttrackcommando##1% -% {\resetcounter{\??se##1}% -% \donexttracklevel{##1}}% -% \donexttracklevel{#1}} -% -% nicer -% -% \def\doresetsectioncounters#1% -% {\resetcounter{\??se#1}% -% \donexttracklevel{#1}} -% -% obey eigennummer - -\def\doresetsectioncounters#1% - {\resetcounter{\??se#1}% - \letgvalue{\??se#1\c!ownnumber}\relax - \donexttracklevel{#1}} - -\def\resetsectioncounters % #1 - {\let\donexttrackcommando\doresetsectioncounters - \donexttracklevel} % #1 - -% bij checken kan geen prefix worden bekeken, anders vallen -% er titels buiten de inhoudsopgave - -% evt ook level gaan opslaan tbv snelle selectie - -% \def\makesectionformat -% {\edef\sectionformat -% {\@@sectiontype\sectionseparator -% \csname\lastsection\s!format\endcsname}} - -\unprotected \def\makesectionformat % we don't want eigennummers here - {\pushmacro\@@shortsectionnumber - \let\@@shortsectionnumber\@@sectionvalue - \edef\sectionformat - {\@@sectiontype\sectionseparator - \csname\lastsection\s!format\endcsname}% - \popmacro\@@shortsectionnumber} - -\def\dobacktracklevel#1% - {\doifnot{\previoussection{#1}}\zerosection - {\dobacktrackcommando{\previoussection{#1}}}} - -\def\donexttracklevel#1% - {\doifnot{#1}\lastsection - {\donexttrackcommando{\nextsection{#1}}}} - -\chardef\alltoclevels\zerocount - -\let\currentlevel\empty - -\def\dosetcurrentlevel#1% - {\global\chardef\alltoclevels\zerocount - \xdef\currentlevel{\getvalue{\lastsection\s!format}}} - -\def\dosetpreviouslevel#1% - {\global\chardef\alltoclevels\plusone - \globallet\currentlevel\empty - \def\dobacktrackcommando##1% - {\ifnum\countervalue{\??se##1}>\zerocount - \global\chardef\alltoclevels\zerocount - \xdef\currentlevel{\getvalue{\previoussection{##1}\s!format}}% - \else - \dobacktracklevel{##1}% - \fi}% - \dobacktrackcommando\lastsection} - -\def\dosettextlevel#1% - {\global\chardef\alltoclevels\plusone - \globallet\currentlevel\empty} - -\def\dosetotherlevel#1% - {\doifdefinedelse{\??ko#1\c!section} % beter alteratief: ook - {\edef\@@sectie{\getvalue{\??ko#1\c!section}}} % hoofdstuk\c!format - {\edef\@@sectie{#1}}% - \doifdefinedelse{\??se\@@sectie} - {\global\chardef\alltoclevels\zerocount - \xdef\currentlevel{\getvalue{\@@sectie\s!format}}} - {\global\chardef\alltoclevels\plusone - \globallet\currentlevel\empty - \def\dobacktrackcommando##1% - {\@EA\ifx\csname\??se##1\c!start\endcsname\relax - \dobacktracklevel{##1}% - \else - \ifnum\countervalue{\??se##1}>\zerocount - \global\chardef\alltoclevels\zerocount - \xdef\currentlevel{\getvalue{##1\s!format}}% - \else - \dobacktracklevel{##1}% - \fi - \fi}% - \dobacktrackcommando\lastsection}} - -% \def\ignoresectionconversion % brrr -% {\let\@@sectionconversion\secondoftwoarguments} - -% todo: criterium=appendix|frontmatter|.... - -\def\dosetfilterlevel#1#2% beware: this one is \let - {\bgroup - \let\@@shortsectionnumber\@@sectionvalue -% \ignoresectionconversion - \edef\askedlevel{#1}% - \edef\askedfilter{#2}% - \ifx\askedlevel\v!current - \dosetcurrentlevel\askedlevel - \else\ifx\askedlevel\v!previous - \dosetpreviouslevel\askedlevel - \else\ifx\askedlevel\v!all - \global\chardef\alltoclevels\plusone - \else\ifx\askedlevel\v!text - \global\chardef\alltoclevels\plusone - \else - \edef\byaskedlevel{\csname\??by\askedlevel\endcsname}% - \ifx\byaskedlevel\v!text - \dosettextlevel\askedlevel - \else - \dosetotherlevel\askedlevel - \fi - \fi\fi\fi\fi - % experiment - \ifx\askedfilter\empty \else - \xdef\currentlevel{\currentlevel\sectionseparator\askedfilter}% - \fi - \egroup} - -% \def\dontsetfilterlevel#1#2% -% {\let\currentlevel\somesavedlevel -% \chardef\alltoclevels\zerocount} - -\def\dontsetfilterlevel#1#2% - {\let\currentlevel\somesavedlevel - \let\@@sectiontype\@@tocsectiontype - \chardef\alltoclevels\zerocount} - -\def\honorlocalfilterlevel % local lists will be real local - {\let\dosetfilterlevel\dontsetfilterlevel} - -% cleaner -% -% \def\doifnextlevelelse[#1::#2]#3#4% -% {\ifcase\alltoclevels -% \doifelse{\@@sectiontype}{#1} -% {\doifinstringelse{=\currentlevel:}{=:#2:} -% {\doifinstringelse{=\currentlevel:0}{=:#2:}{#4}{#3}} -% {#4}} -% {#4}% -% \else -% #3% -% \fi} -% -% \def\doifprevlevelelse[#1::#2]#3#4% -% {\ifcase\alltoclevels -% \doifelse{\@@sectiontype}{#1} -% {\doifinstringelse{=\currentlevel:}{=:#2:}{#3}{#4}} -% {#4}% -% \else -% #3% -% \fi} -% -% faster -% -% \def\doifnextlevelelse[#1::#2]% -% {\ifcase\alltoclevels -% \doifelse{\@@sectiontype}{#1} -% {\doifinstringelse{=\currentlevel:}{=:#2:} -% {\doifinstringelse{=\currentlevel:0}{=:#2:}\donefalse\donetrue} -% \donefalse} -% \donefalse -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -% \def\doifprevlevelelse[#1::#2]% -% {\ifcase\alltoclevels -% \doifelse{\@@sectiontype}{#1} -% {\doifinstringelse{=\currentlevel:}{=:#2:}\donetrue\donefalse} -% \donefalse -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -% meaner -% -% \setuplist -% [chapter] -% [after={\startcolumns\placelist[section]\stopcolumns}] - -\def\somesavedlevel{0} - -% \def\dosavesomelevel[#1:0:0:0:#2]% -% {\def\somesavedlevel{:#1}} - -% \def\doifnextlevelelse[#1::#2]% -% {\dosavesomelevel[#2:0:0:0:0]% -% \ifcase\alltoclevels -% \doifelse{\@@sectiontype}{#1} -% {\doifinstringelse{=\currentlevel:}{=:#2:} -% {\doifinstringelse{=\currentlevel:0}{=:#2:}\donefalse\donetrue} -% \donefalse} -% \donefalse -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -% \def\doifprevlevelelse[#1::#2]% -% {\dosavesomelevel[#2:0:0:0:0]% -% \ifcase\alltoclevels -% \doifelse{\@@sectiontype}{#1} -% {\doifinstringelse{=\currentlevel:}{=:#2:}\donetrue\donefalse} -% \donefalse -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -% again faster: - -% \def\doifnextlevelelse[#1::#2]% beware: this one is \let -% {\dosavesomelevel[#2:0:0:0:0]% -% \ifcase\alltoclevels -% \ifnum\@@sectiontype=#1 -% \def\levelstring{=:#2:}% -% \doifincsnameelse{=\currentlevel:}\levelstring -% {\doifincsnameelse{=\currentlevel:0}\levelstring\donefalse\donetrue} -% \donefalse -% \else -% \donefalse -% \fi -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -%\def\doifprevlevelelse[#1::#2]% beware: this one is \let -% {\dosavesomelevel[#2:0:0:0:0]% -% \ifcase\alltoclevels -% \ifnum\@@sectiontype=#1 -% \doifinstringelse{=\currentlevel:}{=:#2:}\donetrue\donefalse -% \else -% \donefalse -% \fi -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -% \let\doiftoclevelelse\doifnextlevelelse -% \let\doifreglevelelse\doifprevlevelelse -% \let\doifblklevelelse\doifprevlevelelse -% -% we want to be able to overload them globally - -% This will be reimplemented some day soon -% -% {nn}{xx}{yy} -% -% -> \scan{..}{..}{0} met 0 als sentinel - -% still not perfect -% -% \def\doifnextlevelelse[#1]% !! this one is \let / uti seperator -- -% {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}% -% \ifcase\alltoclevels -% \ifnum\@@sectiontype=\@@filterblockpart[#1]\relax -% \edef\levelstring{=\sectionseparator\@@filternumberpart[#1]\sectionseparator}% -% \doifincsnameelse{=\currentlevel\sectionseparator}\levelstring -% {\doifincsnameelse{=\currentlevel\sectionseparator0}\levelstring -% \donefalse -% \donetrue} -% \donefalse -% \else -% \donefalse -% \fi -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} -% -% \def\doifprevlevelelse[#1]% !! this one is \let / uti seperator -- -% {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}% -% \ifcase\alltoclevels -% \ifnum\@@sectiontype=\@@filterblockpart[#1]\relax -% \doifinstringelse -% {=\currentlevel\sectionseparator} -% {=\sectionseparator\@@filternumberpart[#1]\sectionseparator} -% \donetrue\donefalse -% \else -% \donefalse -% \fi -% \else -% \donetrue -% \fi -% \ifdone -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} - -\def\doifnextlevelelse[#1]% !! this one is \let / uti seperator -- - {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}% - \edef\@@tocsectiontype{\@@filterblockpart[#1]}% needed for nested tocs - \ifcase\alltoclevels - \ifnum\@@sectiontype=\@@tocsectiontype\relax - \edef\levelstring{=\sectionseparator\@@filternumberpart[#1]\sectionseparator}% - \doifincsnameelse{=\currentlevel\sectionseparator}\levelstring - {\doifincsnameelse{=\currentlevel\sectionseparator0}\levelstring - \donefalse - \donetrue} - \donefalse - \else - \donefalse - \fi - \else - \donetrue - \fi - \ifdone - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\doifprevlevelelse[#1]% !! this one is \let / uti seperator -- - {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}% - \edef\@@tocsectiontype{\@@filterblockpart[#1]}% needed for nested tocs - \ifcase\alltoclevels - \ifnum\@@sectiontype=\@@tocsectiontype\relax - \doifinstringelse - {=\currentlevel\sectionseparator} - {=\sectionseparator\@@filternumberpart[#1]\sectionseparator} - \donetrue\donefalse - \else - \donefalse - \fi - \else - \donetrue - \fi - \ifdone - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -% we need to cover the special case of nested lists in section blocks -% -% \starttext -% -% \def\ChapterEntry#1#2#3% -% {chapter : \hbox to \hsize{\strut\bf#2\hss#3}\endgraf\placelist[section]} -% -% \startfrontmatter % optional -% \placelist[chapter][alternative=command,command=\ChapterEntry,criterium=text] \page -% \stopfrontmatter % optional -% -% \startbodymatter % optional -% \chapter{first} \section{one} test \section{two} test \page -% \chapter{second} \section{alpha} test \section{beta} test \page -% \stopbodymatter % optional -% -% \stoptext - -\def\doiftoclevelelse{\doifnextlevelelse} -\def\doifreglevelelse{\doifprevlevelelse} -\def\doifblklevelelse{\doifprevlevelelse} - -\def\@@longformatnumber#1% - {\csname\previoussection{#1}\s!format\endcsname - \sectionseparator - \@@shortsectionnumber{#1}} - -% \def\@@longsectionnumber#1% -% {\ifnum\countervalue{\??se\previoussection{#1}}>\zerocount -% \csname\previoussection{#1}\c!nummer\endcsname.% -% \fi -% \@@shortsectionnumber{#1}} - -\def\@@longsectionnumber#1% - {\ifreversesectionnumbers - \@@shortsectionnumber{#1}% - \ifnum\countervalue{\??se\previoussection{#1}}>\zerocount - .\csname\previoussection{#1}\c!number\endcsname - \fi - \else - \ifnum\countervalue{\??se\previoussection{#1}}>\zerocount - \csname\previoussection{#1}\c!number\endcsname.% - \fi - \@@shortsectionnumber{#1}% - \fi} - -% suited for chinese too: -% -% \def\@@shortsectionnumber#1% -% {\@EA\ifx\csname\??se#1\@@sectionblock\c!conversie\endcsname\relax -% \@@sectionvalue{#1}% -% \else -% \@@sectionconversion{#1}{\@@sectionvalue{#1}}% -% \fi} -% -% obey eigennummer -% -% \def\@@shortsectionnumber#1% -% {\@EA\ifx\csname\??se#1\c!eigennummer\endcsname\relax -% \@EA\ifx\csname\??se#1\@@sectionblock\c!conversie\endcsname\relax -% \@EA\ifx\csname\??se#1\c!conversie\endcsname\relax -% \@@sectionvalue{#1}% -% \else -% \@@sectionconversion{#1}{\@@sectionvalue{#1}}% -% \fi -% \else -% \@@sectionconversion{#1}{\@@sectionvalue{#1}}% -% \fi -% \else -% \csname\??se#1\c!eigennummer\endcsname -% \fi} - -\def\@@shortsectionnumber#1% - {\@EA\ifx\csname\??se#1\c!ownnumber\endcsname\relax - \@EA\ifx\csname\??se#1\@@sectionblock\c!conversion\endcsname\relax - \@EA\ifx\csname\??se#1\c!conversion\endcsname\relax - \@@sectionvalue{#1}% - \else - \@@sectionconversion{#1}{\@@sectionvalue{#1}}% - \fi - \else - \@@sectionconversion{#1}{\@@sectionvalue{#1}}% - \fi - \else - \csname\??se#1\c!ownnumber\endcsname - \fi} - -\def\dosetlocalsectionblock#1#2#3% new \edef's - {\edef\@@sectiontype {#1}% - \edef\@@sectionblock {#2}% - \edef\@@sectionblocks{#3}} - -% beware, the \resetsectionmarks generates some nodes that -% will result in an additional last page, which needs to be -% captured at the end - -% \def\doaroundsectionblock#1% -% {\doifvaluesomething{\??sb#1\c!page} -% {\ExpandFirstAfter\page[\getvalue{\??sb#1\c!page}]}% -% \resetsectioncounters\zerosection % was firstsection -% \resetsectionmarks\zerosection} - -% \def\dostartsectionblock#1#2% -% {\begingroup -% \doaroundsectionblock{#1}% % going to a new page or so -% \getvalue{\??sb#1}% % set name of section block -% \getsectionblockenvironment{#1}% % special settings, grouped -% %\expandafter\csname#2true\endcsname % obsolete -% \setsystemmode{#1}% % can be used in conditionals -% \getvalue{\??sb\@@sectionblock\c!before}% this one is not to be moved! -% \showmessage\m!structures1\@@sectionblocks} - -% \def\dostopsectionblock -% {\showmessage\m!structures2\@@sectionblocks -% \getvalue{\??sb\@@sectionblock\c!after}% don't move -% \doaroundsectionblock\@@sectionblock -% \endgroup} - -\def\doaroundsectionblock - {\doifvaluesomething{\??sb\@@sectionblock\c!page} - {\page[\getvalue{\??sb\@@sectionblock\c!page}]}% - \resetsectioncounters\zerosection % was firstsection - \resetsectionmarks\zerosection} - -\def\dostartsectionblock#1#2% - {\begingroup - \getvalue{\??sb#1}% - \doaroundsectionblock -% \doifvaluesomething{\??sb\@@sectionblock\c!page}{\page[\getvalue{\??sb\@@sectionblock\c!page}]}% -% \resetsectioncounters\zerosection % was firstsection -% \resetsectionmarks\zerosection - \getsectionblockenvironment\@@sectionblock - \setsystemmode\@@sectionblock - \getvalue{\??sb\@@sectionblock\c!before}% - \showmessage\m!structures1\@@sectionblocks} - -\def\dostopsectionblock - {\showmessage\m!structures2\@@sectionblocks - \getvalue{\??sb\@@sectionblock\c!after}% don't move - \doaroundsectionblock -% \doifvaluesomething{\??sb\@@sectionblock\c!page}{\page[\getvalue{\??sb\@@sectionblock\c!page}]}% -% \resetsectioncounters\zerosection % was firstsection -% \resetsectionmarks\zerosection - \endgroup} - -\def\dosetupsectionblock[#1]% [#2] - {\getparameters[\??sb#1]} - -\def\setupsectionblock - {\dodoubleargument\dosetupsectionblock} - -\long\def\setsectionblockenvironment#1#2% - {\long\setvalue{\??sb\s!do#1}{\do{#2}}} - -\def\getsectionblockenvironment#1% - {\let\do\firstofoneargument\getvalue{\??sb\s!do#1}} - -\setvalue{\e!start\v!sectionblockenvironment}% - {\dosingleargument\dostartsectionblockenvironment} - -\def\dostartsectionblockenvironment[#1]% evt \pushendofline \popendofline - {\long\def\do##1##2{\setsectionblockenvironment{#1}{##1##2}}% - \grabuntil{\e!stop\v!sectionblockenvironment}{\getvalue{\??sb\s!do#1}}} - -%D \starttyping -%D \startsectionblockenvironment[frontpart] -%D \setuppagenumbering[conversion=romannumerals] -%D \stopsectionblockenvironment -%D -%D \startsectionblockenvironment[bodypart] -%D \setuppagenumber[number=1] -%D \stopsectionblockenvironment -%D -%D \startsectionblockenvironment[frontpart] -%D \setuppagenumbering[conversion=character] -%D \stopsectionblockenvironment -%D -%D \starttext -%D \startfrontmatter \chapter{test} \stopfrontmatter -%D \startbodymatter \chapter{test} \stopbodymatter -%D \startappendices \chapter{test} \stopappendices -%D \stoptext -%D \stoptyping - -% We used to use the first char as id, but a counter is -% better, because in english we get a name clash. - -\newcounter\currentsectionblock - -\def\currentsection{\@@sectionblock} - -\def\dodefinesectionblock[#1][#2][#3]% - {\getparameters - [\??sb#1] - [\c!number=\v!yes, - \c!page=\v!right, % anders worden marks te vroeg gereset ! - %\c!before=, - %\c!after=, - #3]% - \expandafter\newif\csname if#2\endcsname % better a mode - \doglobal\increment\currentsectionblock - \setsectionblockenvironment{#1}{}% - \setevalue{\??sb #1}{\noexpand\dosetlocalsectionblock{\currentsectionblock}{#1}{#2}}% - \setvalue {\e!start#2}{\dostartsectionblock{#1}{#2}}% - \setvalue {\e!stop #2}{\dostopsectionblock}} - -\def\definesectionblock - {\dotripleargument\dodefinesectionblock} - -\def\sectionblocklabel#1#2% - {\@EA\ifx\csname\??ko#1\@@sectionblock\c!label\endcsname\relax - \labeltexts{#1}{#2}% - \else - \labeltexts{\getvalue{\??ko#1\@@sectionblock\c!label}}{#2}% - \fi} - -\dosetlocalsectionblock{2}{\v!bodypart}{\v!bodymatter} % hm, dirty - -\def\setsectiontype[#1]% - {\getvalue{\??sb#1}} - -\def\writesection#1#2#3% #3 -> \asciititle - {\bgroup - \edef\!!stringa{#1}% - \@EA\writestatus\@EA - {\!!stringa} - {\ifsectionnumber#2\else(#2)\fi\normalspace\asciititle}% - \egroup} - -\def\@@kolevel{1} \def\headlevel{\@@kolevel} - -\def\dohandlepagebreakAA#1% - {\ifnum\lastpenalty>0 - \global\pagebreakdisabledtrue - \fi} - -% \setuphead[section][aligntitle=float] % permits title next to sidefloat -% -% \placefigure[left]{}{} \section{\dorecurse{10}{bagger }} \input tufte - -% \def\dohandlepagebreakAB#1% will be replaced by a more clever (signaling) mechanism (in beta) -% {\doifnotvalue{\??ko#1\c!aligntitle}\v!float\flushsidefloats -% \getvalue{\??ko#1\c!before}% -% % \whitespace vervangen door \noindent elders -% \relax -% \ifpagebreakdisabled -% \global\pagebreakdisabledfalse -% \else -% \!!countb\getvalue{\??se\@@sectie\c!level}\relax -% \ifnum\!!countb>\@@kolevel\relax -% \!!counta20000 -% \multiply\!!countb 500 -% \advance\!!counta \!!countb -% \dosomebreak{\penalty\!!counta}% -% \else -% \dosomebreak\allowbreak -% \fi -% \fi -% \doifvalue{\??ko#1\c!aligntitle}\v!float\indent -% \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}} - -\chardef\somebreakmethod\plusone - -\def\dohandlepagebreakAB#1% will be replaced by a more clever (signaling) mechanism (in beta) - {\doifnotvalue{\??ko#1\c!aligntitle}\v!float\flushsidefloats - \getvalue{\??ko#1\c!before}% - % \whitespace vervangen door \noindent elders - \relax - \ifpagebreakdisabled - \global\pagebreakdisabledfalse - \else - \ifcase\somebreakmethod - % 0 = nothing - \or - % 1 = old weighted version - \!!countb\getvalue{\??se\@@sectie\c!level}\relax - \ifnum\!!countb>\@@kolevel\relax - \!!counta20000 - \multiply\!!countb 500 - \advance\!!counta \!!countb - \dosomebreak{\penalty\!!counta}% - \else - \dosomebreak\allowbreak % brr - \fi - \or - % 2 = strict version - \dosomebreak{\penalty\maxdimen}% - \else - % nothing - \fi - \fi - \doifvalue{\??ko#1\c!aligntitle}\v!float\indent - \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}} - -\def\dohandlepagebreakBB#1#2#3% - {%\doifinsetelse{\getvalue{\??tk#2\c!state}}{\v!normal,\v!start} - \doifelselayouttextline{#2} - {\doifvaluesomething{\??ko#1#3} - {\setuplayouttext[#2][\c!state=\getvalue{\??ko#1#3}]}} - \donothing} - -\def\dohandlepagebreakB#1% - {\doifvaluesomething{\??ko#1\c!page} - {\def\resetcurrentsectionmarks% toegevoegd, zie \page - {\resetsectionmarks{\previoussection\@@sectie}}% - \page[\getvalue{\??ko#1\c!page}]% - \dohandlepagebreakBB{#1}\v!header\c!header - \dohandlepagebreakBB{#1}\v!text \c!text - \dohandlepagebreakBB{#1}\v!footer\c!footer}} - -\def\dohandlepagebreakX#1% zie doordefinieren / boven - {\bgroup - \!!countb\@@kolevel - \advance\!!countb #1 - \multiply\!!countb 500 - \!!counta20000 - \advance\!!counta \!!countb - \dosomebreak{\penalty\!!counta}% - \egroup} - -\newconditional\ignorehandlepagebreak - -\def\handlepagebreak#1% - {\ifconditional\ignorehandlepagebreak - \setfalse\ignorehandlepagebreak - \else - \dohandlepagebreakAA{#1}% - \ifnum\countervalue{\??se\previoussection\@@sectie}>\zerocount\relax - \ifnum\countervalue{\??se\@@sectie}>\zerocount - \dohandlepagebreakB{#1}% - \else - \doifnotvalue{\??ko#1\c!continue}\v!yes{\dohandlepagebreakB{#1}}% - \fi - \else - \dohandlepagebreakB{#1}% - \fi - \dohandlepagebreakAB{#1}% - \fi} - -\def\handlenopagebreak#1% - {\ifconditional\ignorehandlepagebreak - \setfalse\ignorehandlepagebreak - \else - \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}% - \nobreak - \fi} - -\def\localheadheight {\strutht} -\def\localheaddepth {\strutdp} -\def\localheadlineheight{\lineheight} - -\def\dolocalheadsetup#1% koppeling met standaard kopcommando / engels - {\forgetall % traag dus ... - \doifvaluesomething{\??ko#1\c!align} % wordt al expanded in spa - {\expanded{\setupalign[\getvalue{\??ko#1\c!align}]}}% - \doifvaluesomething{\??ko#1\c!tolerance} % wordt al expanded in spa - {\expanded{\setuptolerance[\getvalue{\??ko#1\c!tolerance}]}}% - \doifvalue{\??ko#1\c!strut}\v!no % wordt al expanded in spa - {\setnostrut}% new - \def\\{\crlf\strut\ignorespaces}} - -\def\localkopsetup{\localheadsetup} % kan tzt weg - -% todo: make them conditionals: - -\newif\ifincrementnumber -\newif\ifreversesectionnumbers % todo: key/val -\newif\ifsectionnumber \sectionnumbertrue -\newif\ifdisplaysectionhead \displaysectionheadtrue -\newif\ifplacehead -\newif\ifemptyhead -\newif\ifwritetolist -\newif\ifheadnumber -\newif\ifheadnumbercontent % niet meer wijzigen / wordt mode -\newif\ifheadprefix -\newif\ifsomeheadconversion - -% new - -\newconditional\@@resetsubheadnumbers - -\def\setsectieenkoppeling#1% - {\edef\@@koppeling{\getvalue{\??ko#1\c!coupling}}% - \edef\@@sectie{\getvalue{\??ko#1\c!section}}% - \doifnothing\@@koppeling - {\edef\@@koppeling{#1}}% - \doifnothing\@@sectie - {\edef\@@sectie{\getvalue{\??ko\@@koppeling\c!section}}}} - -% \handlepagebreak komt het eerst omdat eventueel -% subpaginanummers moeten worden afgehandeld. Vervolgens -% worden de nummers opgehoogd en referenties geset, dan -% volgt de kop en tot slot de worden de marks en de prefix -% geset. - -% \hoofdstuk {tekst} -% \hoofdstuk tekst -% \hoofdstuk - -\let\finalsectionnumber\empty - -\def\dofinalsectionnumber - {\ifundefined{\@@sectie\c!number}\else - \ifsomeheadconversion - \@@shortsectionnumber\@@sectie - \else - \getvalue{\@@sectie\c!number}% - \fi - \fi} - -\def\findsectionnumber#1#2#3% class file title / uti seperator -- - {\begingroup - \setsectieenkoppeling{#1}% - \xdef\foundsectionnumber{1}% - \def\dolistelement##1##2##3##4##5##6% - {\doif{##1}{#1} - {\ConvertConstantAfter\doif{##4}{#3} - {\global\utilitydonetrue - \scratchcounter=0\getvalue{\??se\@@sectie\c!level}% - % - %\advance\scratchcounter 2 - %\@EA\def\@EA\do\@EA####\@EA1\sectionseparator####2]% - % {\advance\scratchcounter -1 - % \ifcase\scratchcounter - % \xdef\foundsectionnumber{####1}% - % \else - % \do####2]% - % \fi}% - %\do##5]}}}% - % - \def\do####1\relax % :/- clean - {\advance\scratchcounter \minusone - \ifcase\scratchcounter - \xdef\foundsectionnumber{\@@filterheadpart[####1]}% - \else - \@EAEAEA\do\@@filtertailpart[####1]\relax - \fi}% - \@EA\do\@@filternumberpart[##5]\relax}}}% - \setbox0\vbox - {\doutilities{#1}{#2}{#1}\relax\relax}% - \endgroup - \doifnumberelse\foundsectionnumber - {\doif\foundsectionnumber\!!zerocount - {\globallet\foundsectionnumber\!!plusone}} - {\globallet\foundsectionnumber\!!plusone}% an appendix or so - \setupheadnumber[#1][\foundsectionnumber]% - \setupheadnumber[#1][-1]} - -% deal with eigennummer - -\def\setsomeheadconversion#1#2% - {\someheadconversionfalse - \doifelsevalue{\??ko#1\c!ownnumber}\v!yes - {\setgvalue{\??se\@@sectie\c!ownnumber}{#2}% - \def\someheadconversion{#2}} - {\letgvalue{\??se\@@sectie\c!ownnumber}\relax - \determineheadnumber[#1]% - \@EA\ifx\csname\??se\@@sectie\@@sectionblock\c!headconversion\endcsname\relax - \@EA\ifx\csname\??se\@@sectie\c!headconversion\endcsname\relax - \def\someheadconversion{#2}% - \else - \@EA\ifx\csname\??se\@@sectie\c!headconversion\endcsname\empty - \def\someheadconversion{#2}% - \else - \someheadconversiontrue - \def\someheadconversion% - {\fullsectionnumber{#1}{\getvalue{\??se\@@sectie\c!headconversion}}{#2}}% - \fi - \fi - \else - \@EA\ifx\csname\??se\@@sectie\@@sectionblock\c!headconversion\endcsname\empty - \def\someheadconversion{#2}% - \else - \someheadconversiontrue - \def\someheadconversion% - {\fullsectionnumber{#1}{\getvalue{\??se\@@sectie\@@sectionblock\c!headconversion}}{#2}}% - \fi - \fi}} - -\def\writtenfullsectionnumber - {\string\fullsectionnumber} - -\def\ignoredfullsectionnumber#1#2#3% - {#3} - -\let\storedfullsectionnumber\relax - -\def\expandablefullsectionnumber#1#2#3% - {\convertnumber{#2}{#3}} - -\unexpanded\def\naturalfullsectionnumber#1#2#3% - {\sectionblocklabel{#1}{\convertnumber{#2}{#3}}} - -\unexpanded\def\limitedfullsectionnumber#1#2#3% - {\convertnumber{#2}{#3}} - -\def\setfullsectionnumber#1% - {\doifelsevalue{#1\c!headconversion}\v!yes - {\doifelsevalue{#1\c!headlabel}\v!yes - {\let\fullsectionnumber\naturalfullsectionnumber} - {\let\fullsectionnumber\limitedfullsectionnumber}} - {\let\fullsectionnumber\ignoredfullsectionnumber}} - -\let\fullsectionnumber\limitedfullsectionnumber - -% \dodododoconstructhead IS NON GROUPED, SO WE NEED TO RESTORE !!!! -% -% dit kan dus beter \everyaroundhead zijn - -\let\currentheadnumber\empty -\let\currentheadtext \empty - -\def\dodoconstructhead#1[#2]#3% [ref] {title} - {\doifelsevalue{\??ko#1\c!ownnumber}\v!yes - {\doquadruplegroupempty\dododoconstructhead{#1}{#2}{#3}} - {\fourthargumentfalse \dododoconstructhead{#1}{#2}{#3}{}}} - -\def\dododoconstructhead#1#2#3#4% [ref] {own} {title} - {\iffourthargument - \def\next{\dodododoconstructhead{#1}[#2]{#3}{#4}}% - \else - \def\next{\dodododoconstructhead{#1}[#2]{\finalsectionnumber}{#3}}% - \fi - \next} - -% pas met \ExpandFirstAfter op bij twee||taligheid - -\ifx\dohandleheadnumber\undefined - \let\dohandleheadnumber\firstofoneargument -\fi - -\unexpanded\def\\{\space} - -\def\emptyheadcorrection % experimental, should work - {\ifemptyhead % well with na=\blank - \vskip-\lineheight - \dosomebreak\nobreak - \kern\zeropoint - \prevdepth\strutdepth - \fi} - -\let\localkopprefix\empty - -\def\headparameter#1% to do: everywhere in core-sec - {\executeifdefined{\??ko\currenthead#1}\empty} - -% todo: write to list etc in both args or in enclosing h/vbox else it gets -% lost when no #1 or #2 is typeset - -% we will use variables here - -\def\dodododoconstructhead#1[#2]#3#4% [ref] {number} {title} - {\def\currenthead{#1}% dus #1 overal vervangen - \let\finalsectionnumber\dofinalsectionnumber % overloaded ungrouped -) - \unexpanded\def\\{\space}% - \edef\numberseparator{\spr{\getvalue{\??ko\currenthead\c!separator}}}% - \flushingcolumnfloatsfalse % {number} can be \finalsectionnumber - \someheadconversionfalse - \let\fullsectionnumber\limitedfullsectionnumber - \setsectieenkoppeling{#1}% - \doifelsevaluenothing{\??ko#1\c!prefix} - \headprefixfalse\headprefixtrue - \ifheadprefix - \doifelsevalue{\??ko#1\c!prefix}{+} - {\doifelsenothing{#2} - {\def\localkopprefix{+}} - {\def\localkopprefix{#2}}} % eigenlijk alleen eerste - {\edef\localkoprefix{\getvalue{\??ko#1\c!prefix}}}% - \else - \let\localkoprefix\empty - \fi - \placeheadtrue - \processaction - [\getvalue{\??ko#1\c!placehead}] - [ \v!yes=>\emptyheadfalse, - \v!empty=>\emptyheadtrue, - \v!no=>\emptyheadtrue\placeheadfalse]% - \doifelsevalue{\??ko#1\c!resetnumber}\v!no - {\setfalse\@@resetsubheadnumbers}% - {\settrue \@@resetsubheadnumbers}% - \writetolistfalse - \processaction - [\getvalue{\??ko#1\c!incrementnumber}] - [ \v!yes=>\incrementnumbertrue, - \v!no=>\incrementnumberfalse, - \v!list=>\incrementnumberfalse - % beware, since no numbers are used, no nested lists are - % possible here - \writetolisttrue, - \s!unknown=>{\ifx\currentproduct\empty - \findsectionnumber{#1}\commalistelement{#4}% - \fi - \incrementnumbertrue}]% - \edef\numberheaddistance {\getvalue{\??ko#1\c!distance}}% - \edef\numberheadalternative{\getvalue{\??ko#1\c!alternative}}% - \doifelsevalue{\??ko:\numberheadalternative}\v!horizontal - \displaysectionheadfalse - \displaysectionheadtrue - \ifsectionnumber - \doifelsevalue{\??sb\@@sectionblock\c!number}\v!yes - {\doifelsevalue{\??ko#1\c!number}\v!yes - \headnumbertrue - \headnumberfalse} - {\headnumberfalse}% - \else - \headnumberfalse - \fi - \defconvertexpanded\asciititle{\getvalue{\??ko#1\c!expansion}}{#4}% - % - \gdef\currentheadtext{#4}% scheelt args - \globallet\currentheadnumber\empty - % - \ifincrementnumber - \ifplacehead - \checknexthead\handlepagebreak{#1}% - \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...] - \ifheadprefix - %\setupreferencing[\c!prefix=-]% - \setupreferenceprefix[-]% - \fi - \getvalue{\e!next\@@sectie}% - \ifheadnumber - \setsomeheadconversion{#1}{#3}% - \let\fullsectionnumber\expandablefullsectionnumber - \xdef\currentheadnumber{\someheadconversion}% - \getvalue{\??ko#1\c!inbetween}% - \ifsomeheadconversion - \let\fullsectionnumber\naturalfullsectionnumber - \doplaceheadnumbertext - {#1} - {\setsectionlistreference{\@@sectie}{#1}% - \pagetype[\@@koppeling]% - \let\fullsectionnumber\writtenfullsectionnumber - \rawreference\s!sec{#2}{{\someheadconversion}{\asciititle}}% - \resetsectionmarks\@@sectie - \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}% - \let\fullsectionnumber\writtenfullsectionnumber - \dowritetolist\@@koppeling\someheadconversion{#4}\v!head}% - {\dohandleheadnumber\someheadconversion}% handle is new - {#4} - {\marking[#1]{#4}% - \let\fullsectionnumber\storedfullsectionnumber - \expanded{\marking[#1\v!number]{\someheadconversion}}}% - \let\fullsectionnumber\ignoredfullsectionnumber - \writesection{#1}{\someheadconversion}{#4}% - \else - \doplaceheadnumbertext - {#1} - {\setsectionlistreference{\@@sectie}{#1}% - \pagetype[\@@koppeling]% - \rawreference\s!sec{#2}{{#3}{\asciititle}}% - \resetsectionmarks\@@sectie - \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}% - \dowritetolist\@@koppeling{#3}{#4}\v!head} - {\sectionblocklabel{#1}{\dohandleheadnumber{#3}}}% handle is new - {#4} - {\marking[#1]{#4}% - \doifelsevalue{\??ko#1\c!ownnumber}\v!yes % rommelig omdat - {\edef\finalsectionnumber{#3}} % #3 al is toegekend - {\determineheadnumber[#1]}% migreert naar 3e argument - \expanded{\marking[#1\v!number]{\finalsectionnumber}}}% - \writesection{#1}{#3}{#4}% - \fi - \else - \getvalue{\??ko#1\c!inbetween}% - \doplaceheadtext - {#1} - {\setsectionlistreference{\@@sectie}{#1}% - \pagetype[\@@koppeling]% - \rawreference\s!sec{#2}{{#3}{\asciititle}}% - \resetsectionmarks\@@sectie - \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}% - \doifelsevalue{\??ko#1\c!ownnumber}\v!yes % brrr, new per 18/1/2005, sometimes we need - {\dowritetolist\@@koppeling{#3}{#4}\v!head} % entries in the list (special purpose) but - {\dowritetolist\@@koppeling {}{#4}\v!head}% not in the header, ok we could pop in a command - }% \dowritetolist\@@koppeling{}{#4}\v!head} - {#4} - {\marking[#1]{#4}% - \doifelsevalue{\??ko#1\c!ownnumber}\v!yes % brrr - {\edef\finalsectionnumber{#3}} - {\determineheadnumber[#1]}% - % todo : geen markering (leeg maken) - \expanded{\marking[#1\v!number]{\finalsectionnumber}}}% - \writesection{#1}{-}{#4}% - \fi - \ifheadprefix - \setupreferenceprefix[\localkopprefix]% - \fi - \ifdisplaysectionhead - \dosomebreak\nobreak - \emptyheadcorrection - \getvalue{\??ko#1\c!after}% - \fi - \else - % Whatever future tex's will do with nodes, - % we assume a node here, because other \c!after=\blank - % will fail! See 'prikkels' - % - % so, maybe we need an explicit \kern - % - % do nothing / should be vbox to 0pt - % - \checknexthead\dohandlepagebreakB{#1}% toegevoegd ivm subpaginanr / tug sheets - \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...] - \ifheadprefix - \setupreferenceprefix[-]% - \fi - \getvalue{\e!next\@@sectie}% - \ifheadnumber - \setsomeheadconversion{#1}{#3}% - \let\fullsectionnumber\expandablefullsectionnumber - \xdef\currentheadnumber{\someheadconversion}% - \fi - \getvalue{\??ko#1\c!inbetween}% documenteren, is enige hook - \bgroup - \setsectionlistreference{\@@sectie}{#1}% - \resetsectionmarks\@@sectie - \marking[#1]{#4}% - \doifelsevalue{\??ko#1\c!ownnumber}\v!yes - {\edef\finalsectionnumber{#3}} - {\determineheadnumber[#1]}% - \expanded{\marking[#1\v!number]{\finalsectionnumber}}% - \pagetype[\@@koppeling]% -% \bgroup - \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}% - \ifheadnumber - \rawreference\s!sec{#2}{{#3}{\asciititle}}% - \dowritetolist\@@koppeling{#3}{#4}\v!head - \writesection{#1}{#3}{#4}% - \else % hm, also no own number - \rawreference\s!sec{#2}{{#3}{\asciititle}}% - \dowritetolist\@@koppeling{}{#4}\v!head - \writesection{#1}{-}{#4}% - \fi - \egroup - \ifheadprefix - \setupreferenceprefix[\localkopprefix]% - \fi - \fi - \else - % todo : ref prefix - \ifplacehead - \checknexthead\handlepagebreak{#1}% - \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...] - \getvalue{\??ko#1\c!inbetween}% - \doplaceheadtext - {#1} - {\forcesectiontolist{#1}{#4}% - \rawreference\s!sec{#2}{{#3}{\asciititle}}} % #3 ? - {#4} - %{}% new: - {\marking[#1]{#4}% - \marking[#1\v!number]{}}% - \writesection{#1}{-}{#4}% - \ifdisplaysectionhead - \dosomebreak\nobreak - \emptyheadcorrection - \getvalue{\??ko#1\c!after}% - \fi - \else - % do nothing / should be vbox to 0pt - \checknexthead\handlepagebreak{#1}% - \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...] - \getvalue{\??ko#1\c!inbetween}% - \forcesectiontolist{#1}{#4}% - \rawreference\s!sec{#2}{{#3}{\asciititle}}% #3 ? - \marking[#1]{#4}% - \marking[#1\v!number]{}% - \writesection{#1}{-}{#4}% - \fi - \fi - \flushingcolumnfloatstrue - \someheadconversionfalse - \setfalse\ignorehandlepagebreak - \let\fullsectionnumber\limitedfullsectionnumber - % ignorespaces prevents spaces creeping in when after=\dontleavehmode - \ifdisplaysectionhead\ignorespaces\else\expandafter\GotoPar\fi} - -\def\forcesectiontolist#1#2% - {\ifwritetolist - % we need to make sure that there is a number set (non - % zero) else the list mechanism cannot determine the - % level - \bgroup - \setupheadnumber[#1][+1]% traag, wordt \getvalue{\c!next...} - \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}% - \dowritetolist\@@koppeling{}{#2}\v!head - \setupheadnumber[#1][-1]% traag, wordt \getvalue{\c!previous...} - \egroup - \fi} - -\let\previoussectionformat\empty -\let\currentsectionformat \empty - -\let\updatelistreferences \relax -\let\updatedlistreferences\empty - -\def\setsectionlistreference#1#2% - {\ifnum\countervalue{\??se\previoussection{#1}}>0\relax - \xdef\previoussectionformat{\@@longformatnumber{\previoussection{#1}}}% - \else - \globallet\previoussectionformat\empty - \fi - \xdef\currentsectionformat{\@@longformatnumber{#1}}} - -\def\startlistreferences#1% - {\thisissomeinternal{\s!lst}{#1\currentsectionformat}% - \setxvalue{\s!lst:#1}{\realfolio}% to be sure - \setxvalue{\s!lst:#1\currentsectionformat}{\realfolio}% - \setxvalue{\e!previouslocal#1}{\s!lst:#1\previoussectionformat}% - \setxvalue{\e!currentlocal#1}{\s!lst:#1\currentsectionformat}% - \doifelse{\currentsectionformat}{} - {\setglobalcrossreference - {\e!previous#1}{}{\realfolio}{}} - {\setglobalsystemreference\rt!list - {\e!previous#1}{\getvalue{\e!previouslocal#1}}}% - \def\stoplistreferences{\dostoplistreferences{#1}}} - -\def\dostoplistreferences#1% - {\ifutilitydone - \addtocommalist{#1}\updatedlistreferences % nog global (\doglobal) - \globallet\updatedlistreferences\updatedlistreferences % een noodverbandje - \gdef\updatelistreferences% - {\def\docommand####1% - {\setglobalsystemreference\rt!list - {\e!previous####1}{\getvalue{\e!currentlocal####1}}}% - \processcommacommand[\updatedlistreferences]\docommand - \globallet\updatelistreferences\relax - \globallet\updatedlistreferences\empty}% - \fi} - -\let\stoplistreferences\relax - -\appendtoks - \updatelistreferences -\to\aftereverypage - -% \prevdepth\strutdp % is belangrijk, vergelijk naast elkaar: -% -% \subject{test} \input tufte -% \subject{test} \strut \input tufte -% \subject{test} \placelist[...] - -% todo: kap - -% to be documented: \placeheadtext \placeheadnumber - -\unexpanded\def\placeheadtext - {\doquintupleempty\doplaceheadtextornumber - [\c!textstyle][\c!textcolor][\empty]} - -\unexpanded\def\placeheadnumber - {\doquintupleempty\doplaceheadtextornumber - [\c!numberstyle][\c!numbercolor][\v!number]} - -\def\doplaceheadtextornumber[#1][#2][#3][#4][#5]% - {\bgroup - \edef\@@sectie{\??ko\iffifthargument#5\else#4\fi}% - \dostartattributes\@@sectie\c!style\c!color\empty - \dontconvertfont - \dostartattributes\@@sectie{#1}{#2}\empty - \setupinterlinespace - \begstrut\getmarking[\mainmarking{#4#3}]\endstrut - \endgraf - \dostopattributes - \dostopattributes - \egroup} - -\chardef\headtimingmode=0 - -% \chardef\headtimingmode=1 % 0 also works ok now too -% -% Martin Kolarik's problem: -% -% \setuphead[section][command=\doTitle] -% -% \def\doTitle#1#2% -% {\ruledvbox{\forgetall \hsize=4cm -% \ruledhbox{\ruledvtop{#1}\ruledvtop{#2}}}} -% -% \section{test test test test test test test test test test -% test test test test test test test} - -\newevery \everyheadstart \relax - -\def\placeheadmargintexts#1% - {\the\everyheadstart - \doifvalue{\??ko#1\c!margintext}\v!yes\placemargincontent} - -\def\doplaceheadtext#1#2#3#4% - {\beginheadplacement{#1}% - \ifemptyhead % = needed - \setbox0=\ifvertical\vbox\else\hbox\fi to \zeropoint - {\headnumbercontentfalse - \resetsystemmode\v!sectionnumber - #2}% - \makestrutofbox0 - \else % = needed - \setbox0=\ifvertical\vbox\else\hbox\fi % \vhbox - {\headnumbercontentfalse - \resetsystemmode\v!sectionnumber - % less interfering - \ifcase\headtimingmode\or#2\fi - % outerside font determines distance - \dosetfontattribute{\??ko#1}\c!style - % but we don't want color to influence user commands - % todo: get the if-else out of it - \getvalue{\??ko#1\c!command} - {} % no number - {\dostartattributes{\??ko#1}\c!style\c!color\empty - \dostartattributes{\??ko#1}\c!textstyle\c!textcolor\empty - \dontconvertfont - \ifdisplaysectionhead - \setupinterlinespace - \else - \setupspacing - \fi - % \ifcase\headtimingmode#2\fi % can introduce cr - \getvalue{\??ko#1\c!commandbefore}% - \placeheadmargintexts{#1}% binnen #3? - \ifdisplaysectionhead - \getvalue{\??ko#1\c!textcommand}% struts can be nilled with \setnostrut - {\setstrut - \begstrut - \ifcase\headtimingmode\hbox{#2}\fi - \executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#3}% - \endstrut}% \hbox prevents break - \xdef\localheadheight {\the\strutht}% - \xdef\localheaddepth {\the\strutdp}% - \xdef\localheadlineheight{\the\lineheight}% - % == \globallet\localheaddepth\strutdepth - \else - \ifcase\headtimingmode#2\fi - \getvalue{\??ko#1\c!textcommand}% - {\executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#3}}% - \fi - \getvalue{\??ko#1\c!commandafter}% - \ifdisplaysectionhead\endgraf\fi - \dostopattributes - \dostopattributes}}% - \fi - \endheadplacement{#1}{#4}} - -\def\doplaceheadnumbertext#1#2#3#4#5% maybe move modes outside box - {\beginheadplacement{#1}% - \ifemptyhead % = needed - \setbox0=\ifvertical\vbox\else\hbox\fi to \zeropoint - {\doiftextelse{#3} - {\setsystemmode \v!sectionnumber\headnumbercontenttrue } - {\resetsystemmode\v!sectionnumber\headnumbercontentfalse}% - #2}% - \makestrutofbox0 - \else % = needed - \setbox0=\ifvertical\vbox\else\hbox\fi % \vhbox - {\doiftextelse{#3} - {\setsystemmode \v!sectionnumber\headnumbercontenttrue } - {\resetsystemmode\v!sectionnumber\headnumbercontentfalse}% - % less interfering - \ifcase\headtimingmode\or#2\fi - % outerside font determines distance - \dosetfontattribute{\??ko#1}\c!style - % but we don't want color to influence user commands - \getvalue{\??ko#1\c!command}% - {\dostartattributes{\??ko#1}\c!style\c!color\empty - \dostartattributes{\??ko#1}\c!numberstyle\c!numbercolor\empty - % \getvalue{\??ko#1\c!commandbefore}% strange, why here? moved 21/11/2005 - \placeheadmargintexts{#1}% binnen #3? - \ifdisplaysectionhead - % can be nilled with \setnostrut - \getvalue{\??ko#1\c!numbercommand}% - {\setstrut - \begstrut - \executeifdefined{\??ko#1\c!deepnumbercommand}\firstofoneargument{#3}% - \endstrut}% - \else - \getvalue{\??ko#1\c!numbercommand}% - {\executeifdefined{\??ko#1\c!deepnumbercommand}\firstofoneargument{#3}}% - \fi - \dostopattributes - \dostopattributes} - {\dostartattributes{\??ko#1}\c!style\c!color\empty - \dostartattributes{\??ko#1}\c!textstyle\c!textcolor\empty - \dontconvertfont - \ifdisplaysectionhead - \setupinterlinespace - \else - \setupspacing - \fi - % \ifcase\headtimingmode#2\fi % can introduce cr - \getvalue{\??ko#1\c!commandbefore}% makes more sense here - \placeheadmargintexts{#1}% binnen #3? - \ifdisplaysectionhead - \getvalue{\??ko#1\c!textcommand}% struts can be nilled with \setnostrut - {\setstrut - \begstrut - \ifcase\headtimingmode\hbox{#2}\fi - \executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#4}% - \endstrut}% \hbox prevents break - \xdef\localheadheight {\the\strutht}% - \xdef\localheaddepth {\the\strutdp}% - \xdef\localheadlineheight{\the\lineheight}% - % == \globallet\localheaddepth\strutdepth - \else - \ifcase\headtimingmode#2\fi % inside textcommand ? - \getvalue{\??ko#1\c!textcommand}% - {\executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#4}}% - \fi - \getvalue{\??ko#1\c!commandafter}% - \ifdisplaysectionhead\endgraf\fi - \dostopattributes - \dostopattributes}}% - \fi - \endheadplacement{#1}{#5}} - -%D \starttyping -%D \def\StretchedBox#1% -%D {\framed -%D [frame=off,offset=.5em,align=middle,width=broad] -%D {\sc\def\stretchedspaceamount{.3em}\stretchednormalcase{#1}}} -%D -%D \definehead[MySubject][subject] -%D \setuphead [MySubject][deeptextcommand=\StretchedBox] -%D -%D \MySubject{feeling stretched feeling stretched feeling stretched feeling stretched} -%D \stoptyping - -\newsignal\headsignal -\let\headlastlinewidth\!!zeropoint - -\def\beginheadplacement#1% - {\bgroup - \setsystemmode{#1}% to be documented - \ifgridsnapping\iftracegridsnapping\showstruts\fi\fi - \xdef\localheadheight {\the\strutht}% - \xdef\localheaddepth {\the\strutdp}% - \xdef\localheadlineheight{\the\lineheight}% - % == \globallet\localheaddepth\strutdp - \everypar\emptytoks % needed indeed - \noindent % ipv \whitespace elders, na \forgetall ! - \bgroup - \doifinsetelse{\getvalue{\??ko#1\c!aligntitle}}{\v!yes,\v!float}% new - {\skip0 1\leftskip - \skip2 1\rightskip - \xdef\localheadskip{\the\skip0}% - \forgetall - \leftskip\skip0 - \rightskip\skip2 - \setlocalhsize\hsize\localhsize - \forgetbothskips} - {\globallet\localheadskip\!!zeropoint - \forgetall}% - \dontcomplain - \postponenotes - \iflocation\ifdisplaysectionhead\else\noninterferingmarks\fi\fi - \resetinteractionparameter\c!style - \resetinteractionparameter\c!color - \resetinteractionparameter\c!contrastcolor - \strictouterreferencestrue % tzt instelling - \def\localheadsetup{\dolocalheadsetup{#1}}% - \startsynchronization} - -% \setuphead[chapter] [style=\bfd,after=,hang=line] % fit broad 2 -% \setuphead[section] [style=\bfc,after=,hang=line] -% \setuphead[subsection] [style=\bfb,after=,hang=line] -% \setuphead[subsubsection] [style=\bfa,after=,hang=line] -% \setuphead[subsubsubsection][style=\bf ,after=,hang=line] -% -% \chapter {Test} \input tufte \page -% \section {Test} \input tufte \page -% \subsection {Test} \input tufte \page -% \subsubsection {Test} \input tufte \page -% \subsubsubsection{Test} \input tufte \page -% -% \chapter {Test\\Test} \input tufte \page -% \section {Test\\Test} \input tufte \page -% \subsection {Test\\Test} \input tufte \page -% \subsubsection {Test\\Test} \input tufte \page -% \subsubsubsection{Test\\Test} \input tufte \page - -\def\hangheadplacement - {\scratchdimen\localheadlineheight - \bgroup - \openlineheight\scratchdimen - \scratchdimen\ht0 - \advance\scratchdimen\dp0 - \getnoflines\scratchdimen - \advance\noflines\minusone - \expanded{\egroup\noflines\the\noflines}% brrr - \setbox0\hbox{\lower\noflines\scratchdimen\box0}% - \scratchdimen\ht0 - \advance\scratchdimen\dp0 - \advance\scratchdimen-\localheadheight - \advance\scratchdimen+\strutdp - \ht0 \strutht - \dp0 \strutdp - \edef\localheaddepth{\the\strutdp}} - -\newconditional\continuoussectionhead % oeps, \newif\ifcontinuoushead got lost - -\def\endheadplacement#1#2% - {\doifelsevalue{\??rf#1\c!state}\v!start - {\doifvaluenothing{\??ko#1\c!file}{\autocrossdocumentfalse}} - {\autocrossdocumentfalse}% - % no message needed here, should be a proper switch - \noflines\zerocount - \ifdisplaysectionhead - % new (tod tight == one following line up) - \processaction - [\getvalue{\??ko#1\c!hang}] - [ \v!line=>\hangheadplacement\noflines\zerocount, - \v!broad=>\hangheadplacement\getnoflines\scratchdimen, - \v!fit=>\hangheadplacement\getrawnoflines\scratchdimen, - \v!none=>\noflines\zerocount, - \v!default=>\noflines\zerocount, - \v!unknown=>\hangheadplacement\noflines0\commalistelement\advance\noflines\minusone]% - % so far - \let\headlastlinewidth\!!zeropoint - \snaptogrid[\getvalue{\??ko#1\c!grid}]\hbox - {\hskip\localheadskip - \hskip\getvalue{\??ko#1\c!margin}\relax - \iflocation - \ifautocrossdocument - \doifreferencefoundelse{\getvalue{\??ko#1\c!file}::#1} - {\edef\currentinnerreference{\s!aut:\currenttextreference}% stored in - \gotoouterlocation{}{\box0}} % text slot - {\hbox{\box0}}% - \else - \hbox{\box0}% - \fi - \else - \hbox{\box0}% - \fi}% - \doflushnotes % new, not really needed - \endgraf - \ifvmode - \ifnum\noflines>\zerocount - \dorecurse\noflines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}% - \fi - \nointerlineskip - \dosomebreak\nobreak - \fi - #2% - \else - \strut - \doflushnotes % new, here since we're in par mode - \iflocation - \ifautocrossdocument - \hhboxindent=\ifconditional\continuoussectionhead\headlastlinewidth\else\zeropoint\fi - \unhhbox0\with{\gotobox{\box\hhbox}[\getvalue{\??ko#1\c!file}::#1]}% - \advance\lasthhboxwidth by \numberheaddistance - \xdef\headlastlinewidth{\the\lasthhboxwidth}% - \else - \unhbox0 - \globallet\headlastlinewidth\!!zeropoint - \fi - \else - \unhbox0 - \globallet\headlastlinewidth\!!zeropoint - \fi - #2% - \dimen0=\numberheaddistance - \hskip\dimen0 \!!plus \dimen0 \!!minus .25\dimen0 - \hskip\headsignal\ignorespaces - \fi - \ifdisplaysectionhead \ifvmode - \ifgridsnapping % important, font related depth, see comment - \prevdepth\strutdp - \else - \prevdepth\localheaddepth - \fi - \fi \fi - \stopsynchronization - \egroup - \egroup - \ifdisplaysectionhead - \dochecknextindentation{\??ko#1}% - \else - \nonoindentation % recently added, was a bug - \fi} - -\def\checknexthead#1#2% nog optioneel - {\ifhmode - \scratchcounter=\lastpenalty\unpenalty % no beauty in this - \ifdim\lastskip=\headsignal - \handlenopagebreak{#1}% - \global\settrue\continuoussectionhead - \else - \penalty\scratchcounter - \global\setfalse\continuoussectionhead - #1{#2}% - \fi - \else - \global\setfalse\continuoussectionhead - #1{#2}% - \fi} - -\def\dosetupheadnumber[#1][#2#3]% todo: = (don't reset) - {\bgroup - \setsectieenkoppeling{#1}% - \doifinstringelse{#2}{+-} - {\doifelsenothing{#3} - {\@@nextsectionnumber\@@sectie} - {\!!counta=#2#3\relax - \advance\!!counta \@@sectionvalue\@@sectie - \@@setsectionnumber\@@sectie\!!counta}} - {\@@setsectionnumber\@@sectie{#2#3}}% - \egroup} - -\def\setupheadnumber - {\dodoubleargument\dosetupheadnumber} - -\def\currentheadnumber{0} - -\def\determineheadnumber[#1]% - {\bgroup - \setsectieenkoppeling{#1}% - \xdef\currentheadnumber{\@@sectionvalue{\@@sectie}}% - \egroup} - -\def\complexheadnumber[#1]% - {\bgroup - \edef\currentheadnumber{#1}% - \doifinsetelse{-}{#1} % br undocumented - {\removefromcommalist{-}\currentheadnumber % br - \setsectieenkoppeling\currentheadnumber - \setupsection[\@@sectie][\c!previousnumber=\v!no]}% - {\setsectieenkoppeling\currentheadnumber}% - \xdef\currentheadnumber{\@@sectionvalue{\@@sectie}}% - \doifnot{\currentheadnumber}{0}{\finalsectionnumber}% - \egroup} - -\def\simpleheadnumber - {\currentheadnumber} - -\definecomplexorsimple\headnumber - -\def\alinea - {\par} - -% nice testcase -% -% \setupheads[aligntitle=yes] -% -% \startnarrower -% \subject{\dorecurse{100}{x }} -% \section{\dorecurse{100}{x }} -% \input tufte \par -% \setupheads[alternative=inmargin] -% \subject{\dorecurse{100}{x }} -% \section{\dorecurse{100}{x }} -% \input tufte \par -% \stopnarrower - -\let\numberheadalternative\v!normal - -\def\defineheadplacement - {\dodoubleargument\dodefineheadplacement} - -\def\dodefineheadplacement[#1][#2]% #3#4 - {\setvalue{\??ko:#1}{#2}% - \setvalue{\??ko::#1}} - -\def\normalplacehead - {\executeifdefined - {\??ko::\numberheadalternative} - {\getvalue{\??ko::\v!normal}}} - -\defineheadplacement[\v!paragraph][\v!vertical]#1#2% - {\vbox - {\localheadsetup - \begstrut\ifheadnumbercontent#1\hskip\numberheaddistance\fi#2}} - -% \defineheadplacement[\v!normal][\v!vertical]#1#2% -% {\ifheadnumbercontent -% \setbox0\hbox{{#1}\hskip\numberheaddistance}% -% \vbox -% {\localheadsetup -% \hangindent 1\wd0 -% \hangafter 1 -% \noindent -% \unhbox0 % don't use \strut's here! -% #2}% -% \else -% \vbox -% {\localheadsetup\noindent#2}% -% \fi} -% -% enhanced version: - -% \setuphead -% [chapter] -% [numberwidth=2cm,hang=line,after={\blank[3*line]}] -% -% \chapter{Oeps oeps oeps} \input tufte \section{Oeps} -% \chapter{Oeps oeps oeps} \section{Oeps} \input tufte - -\defineheadplacement[\v!normal][\v!vertical]#1#2% - {\vbox - {\localheadsetup - \edef\headwidth {\headparameter\c!width }% - \edef\headnumberwidth{\headparameter\c!numberwidth}% - \edef\headtextwidth {\headparameter\c!textwidth }% - \ifheadnumbercontent - \ifx\headwidth\empty - \else - \ifx\headnumberwidth\empty - \ifx\headtextwidth\empty\else - \edef\headnumberwidth{\the\dimexpr\headwidth-\headtextwidth\relax}% - \fi - \else - \ifx\headtextwidth\empty - \edef\headtextwidth{\the\dimexpr\headwidth-\headnumberwidth\relax}% - \fi - \fi - \hsize\headwidth - \fi - \ifx\headnumberwidth\empty\else - \let\numberheaddistance\!!zeropoint - \fi - \setbox\scratchbox\hbox \ifx\headnumberwidth\empty\else to \headnumberwidth\fi{{#1}}% - \scratchdimen\dimexpr\wd\scratchbox+\numberheaddistance\relax - \ifx\headtextwidth\empty\else - \hsize\dimexpr\scratchdimen+\headparameter\c!textwidth\relax - \fi - \hangindent\scratchdimen - \hangafter \plusone - \noindent - \box\scratchbox\hskip\numberheaddistance - \else - \ifx\headtextwidth\empty - \ifx\headwidth\empty - \else - \hsize\headwidth - \fi - \else - \hsize\headtextwidth - \fi - \noindent - \fi - #2}} - -\def\placeheadmargin#1#2% - {\vbox - {\localheadsetup - \begstrut % use one \strut here! - \dontleavehmode % in case there is no strut, else side effects with llap - \ifheadnumbercontent - \llap{\hbox to 5em{\hfill{#1}\hskip\localheadskip\hskip\leftmargindistance}}% introduces whitespace - % maybe better: - % \inleftmargin{\hbox{\hss{#1}\hskip\localheadskip}}% - \fi - {#2}}} - -\defineheadplacement[\v!inmargin][\v!vertical]#1#2{\placeheadmargin{#1}{#2}} -\defineheadplacement[\v!margin] [\v!vertical]#1#2{\placeheadmargin{#1}{#2}} - -\defineheadplacement[\v!middle][\v!vertical]#1#2% - {\vbox - {\localheadsetup - \veryraggedcenter - \let\\\endgraf - \let\crlf\endgraf - \ifheadnumbercontent\strut#1\par\fi\begstrut#2}} - -\defineheadplacement[\v!text][\v!horizontal]#1#2% - {\bgroup - \localheadsetup % no stretch in distance - \ifheadnumbercontent{#1}\kern\numberheaddistance\fi{\begstrut#2}% - \egroup} - -\def\placeheadlohi#1#2#3% - {\ifheadnumbercontent - \setbox0\hbox{#2} - \setbox2=#1{\localheadsetup\advance\hsize-\wd0\relax#3}% - \hbox{\box0\hskip\numberheaddistance\box2}% - \else - #1{\localheadsetup\noindent#3}% - \fi} - -% onder/boven lijnt het nummer op de onderste/bovenste regel -% uit van een meerregelige kop - -\defineheadplacement[\v!bottom][\v!vertical]#1#2{\placeheadlohi\vbox{#1}{#2}} -\defineheadplacement[\v!top] [\v!vertical]#1#2{\placeheadlohi\vtop{#1}{#2}} - -% default == instellingen -% koppeling == koppen, breaks, marks, enz. -% sectie == nummering - -\let\@@kolist=\empty - -\def\dododefinehead#1#2% % don't preset prefix to much - {\presetlabeltext[#1=]% - \getparameters - [\??ko#1] - [\c!numberstyle=\getvalue{\??ko#1\c!style}, - \c!textstyle=\getvalue{\??ko#1\c!style}, - \c!numbercolor=\getvalue{\??ko#1\c!color}, - \c!textcolor=\getvalue{\??ko#1\c!color}]% - % deeptextcommand and deepnumbercommand are left undefined ! - \doifassignmentelse{#2} - {\getparameters - [\??ko#1] - [\c!section=\getvalue{\??ko\getvalue{\??ko#1\c!coupling}\c!section}, - \c!default=, - \c!coupling=, - \c!prefix=, - \c!before=, - \c!after=, - \c!distance=\!!zeropoint, - \c!page=, - \c!header=, - \c!text=, - \c!footer=, - \c!style=, - \c!numbercommand=, - \c!textcommand=, - \c!ownnumber=\v!no, - \c!number=\v!yes, - \c!color=, - \c!continue=\v!yes, - \c!placehead=\v!yes, - \c!resetnumber=\v!yes, - \c!incrementnumber=\v!yes, - \c!alternative=\@@koalternative, - \c!command=\normalplacehead, - \c!separator=\@@koseparator, - \c!stopper=\@@kostopper, - \c!align=\@@koalign, - \c!aligntitle=\@@koaligntitle, - \c!tolerance=\@@kotolerance, - \c!indentnext=\@@koindentnext, - \c!strut=\@@kostrut, - \c!hang=\@@kohang, - \c!file=, - \c!expansion=, - \c!grid=, - \c!margintext=, - \c!margin=\@@komargin, - #2]% - \ConvertToConstant\doifnot{#1}{\getvalue{\??ko#1\c!default}} - {\doifsomething{\getvalue{\??ko#1\c!default}} - {\copyparameters - [\??ko#1][\??ko\getvalue{\??ko#1\c!default}] - [\c!before,\c!after,\c!command,\c!file,\c!page,\c!continue, - \c!header,\c!text,\c!footer,\c!separator,\c!stopper,\c!resetnumber, - \c!number,\c!ownnumber,\c!placehead,\c!incrementnumber, - \c!style,\c!color,\c!distance,\c!alternative,\c!indentnext, - % new per 20/03/3002 (o-pbu-l) / was too confusing - % \c!numberstyle,\c!textstyle,\c!expansion, - % again too confusing - \c!align,\c!aligntitle,\c!tolerance,\c!grid,\c!hang,\c!strut, - \c!numbercommand,\c!textcommand,\c!margintext,\c!margin]}}% - \getparameters[\??ko#1][#2]% - \doifsomething{\getvalue{\??ko#1\c!section}} - {\doifelsemarking{#1}% \doifundefined{\??mk#1} - {}% marking #1 already defined - {\definemarking[#1]% - \couplemarking[#1][\getvalue{\??ko#1\c!section}]% - \definemarking[#1\v!number]% - \couplemarking[#1\v!number][\getvalue{\??ko#1\c!section}]}}% - \doifundefined{\??li#1}{\definelist[#1]}} - {\ConvertToConstant\doifelse{#1}{#2} - {\doifundefined{\??li#1}{\definelist[#1]}} - {\copyparameters - [\??ko#1][\??ko#2] - [\c!level,\c!section,\c!coupling,\c!prefix, - \c!before,\c!after,\c!command,\c!file,\c!page,\c!continue, - \c!separator,\c!stopper, - \c!header,\c!text,\c!footer,\c!resetnumber, - \c!number,\c!ownnumber,\c!placehead,\c!incrementnumber, - \c!style,\c!color,\c!distance,\c!alternative,\c!indentnext, - % new per 20/03/3002 (o-pbu-l) / was too confusing - % \c!numberstyle,\c!textstyle,\c!expansion, - % again too confusing - \c!align,\c!aligntitle,\c!tolerance,\c!grid,\c!hang,\c!strut, - \c!numbercommand,\c!textcommand,\c!margintext,\c!margin]% - \getparameters[\??ko#1][\c!expansion=]% iig een value, rather fuzzy - \definemarking[#1][#2]% - \definemarking[#1\v!number][#2\v!number]% - \doifundefined{\??li#1}{\definelist[#1][#2]}}}% - \addtocommalist{#1}\@@kolist - \setevalue{\??sk#1}{\getvalue{\??ko#1\c!coupling}}% - \setevalue{\??by#1}{\getvalue{\??ko#1\c!section}}% - \setevalue{\??by\v!by#1}{\getvalue{\??ko#1\c!section}}% - \setvalue{#1}{\dodoubleempty\doconstructhead[#1]}} - -\def\dodefinehead[#1][#2]% - {\doifelsenothing{#2} - {% todo: message that it's an invalid definition - \setvalue{#1}{\endgraf[#1]\kern.5em}} - {\doifassignmentelse{#2} - {\dododefinehead{#1}{#2}} - {\doifdefined{\??ko#2\c!section} - {\dododefinehead{#1}{#2}}}}} - -\def\definehead - {\dodoubleemptywithset\dodefinehead} - -\def\doconstructhead[#1][#2]% - {\dowithpargument{\dodoconstructhead{#1}[#2]}} - -\def\dosetuphead[#1][#2]% - {\getparameters[\??ko#1][#2]% - % The next check prevents hard to trace problems. I once - % set \c!command to nothing and (quite natural) got the - % wrong references etc. The whole bunch should be boxed! - \expandafter\defconvertedcommand\expandafter\ascii\csname\??ko#1\c!command\endcsname - \doifnothing\ascii{\setvalue{\??ko#1\c!command}{\normalplacehead}}} - -\def\setuphead - {\dodoubleargumentwithset\dosetuphead} - -\def\dosetupheads[#1]% - {\getparameters[\??ko][#1]% - \doifelse{\@@kosectionnumber}\v!yes\sectionnumbertrue\sectionnumberfalse} - -\def\setupheads - {\dosingleargument\dosetupheads} - -\def\systemsuppliedchapter {\getvalue{\v!chapter}} -\def\systemsuppliedtitle {\getvalue{\v!title}} - -% a left over - -\def\complexbijlage[#1]#2% - {\page[\v!right] - \setuppagenumbering[\c!state=\v!stop] - \systemsuppliedchapter[#1]{#2} - \page[\v!right] - \setuppagenumbering[\c!state=\v!start] - \setuppagenumbering[\c!number=1]} - -\setvalue{\v!appendix}% - {\complexorsimpleempty\bijlage} - -\setupheads - [\c!alternative=\v!normal, - \c!sectionnumber=\v!yes, - \c!separator=., - \c!stopper=, - \c!limittext=\v!yes, - \c!align=, - \c!aligntitle=, - \c!tolerance=, - \c!strut=, - \c!indentnext=\v!no, - \c!margin=\zeropoint, - \c!hang=\v!none, - \c!command=] - -\definesectionblock [\v!frontpart] [\v!frontmatter] [\c!number=\v!no] -\definesectionblock [\v!bodypart] [\v!bodymatter] [\c!number=\v!yes] -\definesectionblock [\v!appendix] [\v!appendices] [\c!number=\v!yes] -\definesectionblock [\v!backpart] [\v!backmatter] [\c!number=\v!no] - -\definesection[\s!section-1] % part -\definesection[\s!section-2] % chapter -\definesection[\s!section-3] % section -\definesection[\s!section-4] % subsection -\definesection[\s!section-5] % subsubsection -\definesection[\s!section-6] % subsubsubsection -\definesection[\s!section-7] % subsubsubsubsection - -% \c!eigennummer ook hier? - -\definehead - [\v!part] - [\c!section=\s!section-1, - \c!ownnumber=\v!no] - -\definehead - [\v!chapter] - [\c!section=\s!section-2, - \c!ownnumber=\v!no] - -\definehead - [\v!section] - [\c!section=\s!section-3, - \c!ownnumber=\v!no] - -\definehead - [\v!subsection] - [\c!section=\s!section-4, - \c!default=\v!section, - \c!ownnumber=\v!no] - -\definehead - [\v!subsubsection] - [\c!section=\s!section-5, - \c!default=\v!subsection, - \c!ownnumber=\v!no] - -\definehead - [\v!subsubsubsection] - [\c!section=\s!section-6, - \c!default=\v!subsubsection, - \c!ownnumber=\v!no] - -\definehead - [\v!subsubsubsubsection] - [\c!section=\s!section-7, - \c!default=\v!subsubsubsection, - \c!ownnumber=\v!no] - -\definehead - [\v!title] - [\c!coupling=\v!chapter, - \c!default=\v!chapter, - \c!incrementnumber=\v!no] - -\definehead - [\v!subject] - [\c!coupling=\v!section, - \c!default=\v!section, - \c!incrementnumber=\v!no] - -\definehead - [\v!subsubject] - [\c!coupling=\v!subsection, - \c!default=\v!subsection, - \c!incrementnumber=\v!no] - -\definehead - [\v!subsubsubject] - [\c!coupling=\v!subsubsection, - \c!default=\v!subsubsection, - \c!incrementnumber=\v!no] - -\definehead - [\v!subsubsubsubject] - [\c!coupling=\v!subsubsubsection, - \c!default=\v!subsubsubsection, - \c!incrementnumber=\v!no] - -\definehead - [\v!subsubsubsubsubject] - [\c!coupling=\v!subsubsubsubsection, - \c!default=\v!subsubsubsubsection, - \c!incrementnumber=\v!no] - -\setupsection - [\s!section-2] - [\v!appendix\c!conversion=\v!Character, - \c!previousnumber=\v!no] - -\setuphead - [\v!part] - [\c!placehead=\v!no] - -\setuphead - [\v!chapter] - [\v!appendix\c!label=\v!appendix, - \v!bodypart\c!label=\v!chapter] % bijlageconversie=\Character - -\setuphead - [\v!section] - [\v!appendix\c!label=\v!section, - \v!bodypart\c!label=\v!section] % bijlageconversie=\Character - -\setuphead - [\v!subsection] - [\v!appendix\c!label=\v!subsection, - \v!bodypart\c!label=\v!subsection] % bijlageconversie=\Character - -\setuphead - [\v!subsubsection] - [\v!appendix\c!label=\v!subsubsection, - \v!bodypart\c!label=\v!subsubsection] % bijlageconversie=\Character - -\setuphead - [\v!part,\v!chapter] - [%\c!align=, - %\c!indentnext=\v!no, - \c!continue=\v!no, - \c!page=\v!right, - \c!header=, - \c!style=\tfc, - \c!distance=.75em, - \c!before={\blank[2*\v!big]}, - \c!after={\blank[2*\v!big]}] - -\setuphead - [\v!section] - [%\c!align=, - %\c!indentnext=\v!no, - \c!style=\tfa, - \c!distance=.75em, - \c!before={\blank[2*\v!big]}, - \c!after=\blank] - -\setuphead % nieuw - [\v!subsection] - [\c!page=] - -\definecombinedlist - [\v!content] - [\v!part, - \v!chapter, - \v!section, - \v!subsection, - \v!subsubsection, - \v!subsubsubsection, - \v!subsubsubsubsection] - [\c!level=\v!subsubsubsubsection, - \c!criterium=\v!local] - -\setuplist - [\v!part] - [\c!before={\blank\page[\v!preference]}, - \c!after=\blank, - \c!label=\v!yes, - \c!separator=:, - \c!distance=1em] - -\setuplist - [\v!chapter] - [\c!before={\blank\page[\v!preference]}, - \c!after=] - -\setuplist [\v!part] [\c!width=0em] -\setuplist [\v!chapter] [\c!width=2em] -\setuplist [\v!section] [\c!width=3em] -\setuplist [\v!subsection] [\c!width=4em] -\setuplist [\v!subsubsection] [\c!width=5em] -\setuplist [\v!subsubsubsection] [\c!width=6em] -\setuplist [\v!subsubsubsubsection] [\c!width=7em] - -% hm - -\setuppagenumbering % na instellen hoofdteksten ! - [\c!alternative=\v!singlesided, - \c!location={\v!header,\v!middle}, - \c!conversion=\v!numbers, - \c!width=, % in geval van \v!marginedge - \c!left=, - \c!right=, - \c!way=\v!by\v!part, - \c!text=, - \v!chapter\v!number=\v!no, % v - \v!part\v!number=\v!yes, % v - \c!numberseparator=--, - \c!textseparator=\tfskip, - \c!state=\v!start, - \c!command=, - \c!strut=\v!yes, % nieuw - \c!style=, % \v!normal, % empty, otherwise conflict - \c!color=] - -\protect \endinput diff --git a/tex/context/base/core-snc.tex b/tex/context/base/core-snc.tex deleted file mode 100644 index 99c7d58f6..000000000 --- a/tex/context/base/core-snc.tex +++ /dev/null @@ -1,179 +0,0 @@ -%D \module -%D [ file=core-snc, -%D version=2003.12.01, -%D title=\CONTEXT\ Core 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 Core 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 - -\setupcolors[state=start] - -\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/core-spa.mkiv b/tex/context/base/core-spa.mkiv index dfb84da53..8dba73ac1 100644 --- a/tex/context/base/core-spa.mkiv +++ b/tex/context/base/core-spa.mkiv @@ -691,7 +691,7 @@ \dosetupblank\appliedblankskip }%\let\deblanko\v!big} -\def\dodefineblank[#1][#2]% +\def\dodefineblank[#1][#2]% why #1 commalist? {\def\docommand##1{\setvalue{\??bo##1}{#2}}% \processcommalist[#1]\docommand} diff --git a/tex/context/base/core-swd.tex b/tex/context/base/core-swd.tex deleted file mode 100644 index ade3e6caa..000000000 --- a/tex/context/base/core-swd.tex +++ /dev/null @@ -1,125 +0,0 @@ -%D \module -%D [ file=core-swd, -%D version=2007.08.14, -%D title=\CONTEXT\ Core 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 - -\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/core-syn.tex b/tex/context/base/core-syn.tex deleted file mode 100644 index b5c87c487..000000000 --- a/tex/context/base/core-syn.tex +++ /dev/null @@ -1,438 +0,0 @@ -%D \module -%D [ file=core-syn, -%D version=1997.03.31, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Synonyms and Sorts, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core 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/core-trf.tex b/tex/context/base/core-trf.tex deleted file mode 100644 index c7fa8d42b..000000000 --- a/tex/context/base/core-trf.tex +++ /dev/null @@ -1,577 +0,0 @@ -%D \module -%D [ file=core-fig, -%D version=2006.08.26, % overhaul/split of 1997.03.31 core-fig -%D title=\CONTEXT\ Core 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 Core 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 - \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} - {\scaleboxoutervsize\scaleparameter\c!maxheight}% - \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/core-ver.mkii b/tex/context/base/core-ver.mkii deleted file mode 100644 index dd8f5f84f..000000000 --- a/tex/context/base/core-ver.mkii +++ /dev/null @@ -1,1334 +0,0 @@ -%D \module -%D [ file=core-ver, -%D version=2000.05.09, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Verbatim, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Verbatim} - -\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.tex\to\filename - \readsysfile\filename\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 - {% \language\minusone % extra bonus, the \null should do the job too - \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip - \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}% - \spaceskip.5em\relax} - -\unexpanded\def\typ - {\bgroup - \let\@@tylines\v!hyphenated - \futurelet\next\dodotype} - -%D \macros -%D {tex,arg,mat,dis} -%D -%D Sometimes, for instance when we pass verbatim text as an -%D argument, the fixed \CATCODES\ interfere with our wishes. An -%D experimental implementation of character by character -%D processing of verbatim text did overcome this limitation, -%D but we've decided not to use that slow and sometimes -%D troublesome solution. Instead we stick to some 'old' -%D \CONTEXT\ macros for typesetting typical \TEX\ characters. -%D -%D The next implementation is more clear but less versatile, -%D so we treated it for a beter one. -%D -%D \starttyping -%D \def\dospecialtype#1#2% -%D {\bgroup -%D \initializetype -%D \catcode`\{=\@@begingroup -%D \catcode`\}=\@@endgroup -%D \def\dospecialtype% -%D {\def\dospecialtype{#2\egroup}% -%D \bgroup -%D \aftergroup\dospecialtype -%D #1}% -%D \afterassignment\dospecialtype -%D \let\next=} -%D -%D \unexpanded\def\tex{\dospecialtype\texescape\relax} -%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument} -%D \unexpanded\def\mat{\dospecialtype\$\$} -%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}} -%D \stoptyping - -\def\setgroupedtype - {\let\currenttypingclass\??ty - \initializetype - \verbatimcolor - %\setcatcodetable \typcatcodesa - \catcode`\{=\@@begingroup - \catcode`\}=\@@endgroup} - -\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}} -\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}} -\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}} -\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}} - -%D \macros -%D {starttyping} -%D -%D Display verbatim is realized far more easy, which is mostly -%D due to the fact that we use \type{\stop...} as delimiter. -%D The implementation inherits some features, for instance the -%D support of linenumbering, which can best be studied in the -%D documented support module. - -\let\currenttyping \empty -\let\currenttypingclass\??ty % saveguard - -% \def\typingparameter#1% -% {\executeifdefined -% {\currenttypingclass\currenttyping#1}% -% {\executeifdefined{\currenttypingclass#1}\empty}} - -\def\typingparameter#1% - {\ifcsname\currenttypingclass\currenttyping#1\endcsname - \csname\currenttypingclass\currenttyping#1\endcsname - \else\ifcsname\currenttypingclass#1\endcsname - \csname\currenttypingclass#1\endcsname - \fi\fi} - -\def\settypingparameter#1#2% - {\setvalue{\currenttypingclass\currenttyping#1}{#2}} - -\def\setxtypingparameter#1#2% - {\setxvalue{\currenttypingclass\currenttyping#1}{#2}} - -% \def\initializetyping -% {%\donefalse -% \switchtobodyfont[\typingparameter\c!bodyfont]% -% \donefalse -% \scratchskip\typingparameter\c!oddmargin\relax -% \ifzeropt\scratchskip\else\donetrue\fi -% \scratchskip\typingparameter\c!evenmargin\relax -% \ifzeropt\scratchskip\else\donetrue\fi -% \ifdone -% \def\doopenupverbatimline -% {\getpagestatus -% \ifrightpage -% \hskip\typingparameter\c!oddmargin\relax -% \else -% \hskip\typingparameter\c!evenmargin\relax -% \fi}% -% \else -% \doadaptleftskip{\typingparameter\c!margin}% -% \fi -% \doifdefinedelse{\??bo\typingparameter\c!blank} -% {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}} -% {\edef\!!stringa{\typingparameter\c!blank}}% -% \processaction -% [\!!stringa] -% [ \v!standard=>\scratchskip\ctxparskip, -% \v!small=>\scratchskip\blankokleinmaat, -% \v!medium=>\scratchskip\blankomiddelmaat, -% \v!big=>\scratchskip\blankogrootmaat, -% \v!halfline=>\scratchskip.5\baselineskip, -% \v!line=>\scratchskip\baselineskip, -% \v!none=>\scratchskip\zeropoint, -% \s!unknown=>\scratchskip\commalistelement]% -% \ifgridsnapping -% \ifdim\scratchskip=.5\baselineskip\relax -% \edef\verbatimbaselineskip{\the\scratchskip}% new -% \else -% \edef\verbatimbaselineskip{\the\baselineskip}% -% \fi -% \else -% \edef\verbatimbaselineskip{\the\scratchskip}% -% \fi -% \setupcommonverbatim} - -\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip} -\setvalue{\??tp:\c!blank:\v!small }{\blankokleinmaat} -\setvalue{\??tp:\c!blank:\v!medium }{\blankomiddelmaat} -\setvalue{\??tp:\c!blank:\v!big }{\blankogrootmaat} -\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip} -\setvalue{\??tp:\c!blank:\v!line }{\baselineskip} -\setvalue{\??tp:\c!blank:\v!none }{\zeropoint} - -\def\initializetyping - {%\donefalse - \switchtobodyfont[\typingparameter\c!bodyfont]% - \donefalse - \scratchskip\typingparameter\c!oddmargin\relax - \ifzeropt\scratchskip\else\donetrue\fi - \scratchskip\typingparameter\c!evenmargin\relax - \ifzeropt\scratchskip\else\donetrue\fi - \ifdone - \def\doopenupverbatimline - {\getpagestatus - \ifrightpage - \hskip\typingparameter\c!oddmargin\relax - \else - \hskip\typingparameter\c!evenmargin\relax - \fi}% - \else - \doadaptleftskip{\typingparameter\c!margin}% - \fi - \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}% - \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax - \ifgridsnapping - \ifdim\scratchskip=.5\baselineskip\relax - \edef\verbatimbaselineskip{\the\scratchskip}% new - \else - \edef\verbatimbaselineskip{\the\baselineskip}% - \fi - \else - \edef\verbatimbaselineskip{\the\scratchskip}% - \fi - \setupcommonverbatim} - -%D The basic display verbatim commands are defined in an -%D indirect way. As we will see, they are a specific case of a -%D more general mechanism. - -% we need this hack because otherwise verbatim skips -% the first line (everything after the initial command) - -\def\dostarttyping#1% tricky non standard lookahead - {\bgroup - \let\currenttypingclass\??tp - \edef\currenttyping{#1}% - \obeylines - \futurelet\nexttoken\dodostarttyping} - -\def\dodostarttyping - {\ifx\nexttoken[% - \expandafter\dododostarttyping - \else - \expandafter\nododostarttyping - \fi} - -\def\nododostarttyping - {\dododostarttyping[]} - -\def\dododostarttyping[#1]% - {\typingparameter\c!before - \startpacked % includes \bgroup - \dosetuptypelinenumbering{#1}% - \initializetyping - \startverbatimcolor - \expanded{\processdisplayverbatim{\s!stop\currenttyping}}} - -\def\dostoptyping#1% hm, currenttyping - {\stopverbatimcolor - \stoppacked % includes \egroup - \typingparameter\c!after - \egroup - \dochecknextindentation{\??tp#1}% - \dorechecknextindentation} - -%D Line numbering for files is combined with filtering, while -%D display verbatim has the ability to continue. -%D -%D \starttyping -%D \typefile[numbering=file,start=10,stop=12]{test.tex} -%D -%D \definetyping[code][numbering=line] -%D -%D \starttext -%D \startcode -%D ... -%D ... -%D \stopcode -%D -%D \startcode[continue] -%D ... -%D ... -%D \stopcode -%D -%D \startcode[start=10] -%D ... -%D \stopcode -%D \stoptyping - -%D \macros -%D {setuptyping} -%D -%D The setup of typing accepts two arguments. The optional -%D first one identifies the user defined ones. If only one -%D argument is given, the values apply to both the standard -%D command \type{\starttyping} and \type{\typefile}. - -\def\dosetuptyping[#1][#2]% - {\ifsecondargument - \getparameters[\??tp#1][#2]% - \else - \getparameters[\??tp][#1]% - \fi} - -\def\setuptyping - {\dodoubleempty\dosetuptyping} - -%D \macros -%D {definetype} -%D -%D Specific inline verbatim commands can be defined with the -%D following command. - -\def\definetype - {\dodoubleempty\dodefinetype} - -\def\dodefinetype[#1][#2]% - {\unexpanded\setvalue{#1}{\dotype{#1}}% - \getparameters[\??ty#1][#2]} - -%D \macros -%D {definetyping} -%D -%D For most users the standard \type{\start}||\type{\stop}||pair -%D will suffice, but for documentation purposes the next -%D definition command can be of use: -%D -%D \starttyping -%D \definetyping[extratyping][margin=3em] -%D -%D \startextratyping -%D these extra ones are indented by 1 em -%D \stopextratyping -%D \stoptyping -%D -%D The definitions default to the standard typing values. - -\def\presettyping[#1][#2]% - {\copyparameters[\??tp#1][\??tp][\c!color,\c!style]% - \getparameters [\??tp#1][#2]} - -\def\dodefinetyping[#1][#2]% - {\setvalue{\e!start#1}{\dostarttyping{#1}}% - \setvalue{\e!stop #1}{\dostoptyping {#1}}% - \presettyping[#1][#2]} - -\def\definetyping - {\dodoubleempty\dodefinetyping} - -%D We can use some core color commands. These are faster than -%D the standard color switching ones and work ok on a line by -%D line basis. -%D -%D \starttyping -%D \def\setupverbatimcolor% -%D {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}% -%D \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}% -%D \def\endofpretty {\stopcolormode}} -%D \stoptyping -%D -%D Since we support a global color too, the folowing -%D definition is better: - -% \def\setupverbatimcolor% fast and local versus slow and global -% {\doifelsenothing{\typingparameter\c!color} -% {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}% -% \let\endofpretty \restorecolormode % \stopcolormode -% \let\startverbatimcolor \relax -% \let\stopverbatimcolor \relax -% \let\verbatimcolor \relax} -% {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}% -% \let\endofpretty \stopcolor -% \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}% -% \let\stopverbatimcolor \stopcolor -% \def\verbatimcolor {\getvalue{\typingparameter\c!color}}}% command ! -% \doifelsenothing{\typingparameter\c!palet} -% {\let\prettypalet\empty -% \let\endofpretty\relax -% \def\beginofpretty[##1]{}} -% {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}} -% -% let's forget about this optimization not that we have mkiv - -\def\setupverbatimcolor - {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}% - \let\endofpretty \stopcolor - \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}% - \let\stopverbatimcolor \stopcolor - \def\verbatimcolor {\getvalue{\typingparameter\c!color}}% command ! - \doifelsenothing{\typingparameter\c!palet} - {\let\prettypalet\empty - \let\endofpretty\relax - \def\beginofpretty[##1]{}} - {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}} - -\let\prettypalet \empty -\let\startverbatimcolor\relax -\let\stopverbatimcolor \relax -\let\verbatimcolor \relax - -%D In the verbatim module, there are some examples given of -%D the more obscure features of the verbatim environments. -%D -%D \startbuffer -%D \startTEX -%D \def\mathematics#1% % usage: \type {\mathematics{x^2}} -%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2} -%D \stopTEX -%D \stopbuffer -%D -%D \typebuffer -%D -%D This gives, as can be expected: -%D -%D \getbuffer -%D -%D When we want to see some typeset \TEX\ too, we can say: -%D -%D \startbuffer -%D \startTEX -%D \def\mathematics#1% %%\ N usage: \type {\mathematics{x^2}} -%D {\ifmmode#1\else$#1$\fi} %%\ N becomes: \mathematics{x^2} -%D \stopTEX -%D \stopbuffer -%D -%D \typebuffer -%D -%D or: -%D -%D \getbuffer -%D -%D In a similar way: -%D -%D \startbuffer -%D \startSQL -%D select * -- indeed, here we {\em do} select -%D from tableA -%D where 1 = 2 -%D \stopSQL -%D \stopbuffer -%D -%D \typebuffer -%D -%D gives: -%D -%D \getbuffer -%D -%D The next examples sow how we can directly call for natural -%D \TEX\ comments: -%D -%D \startbuffer -%D \setuptyping -%D [TEX] -%D [text=yes] -%D -%D \startTEX -%D \def\mathematics#1% % usage: \type {\mathematics{x^2}} -%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2} -%D \stopTEX -%D -%D \setuptyping -%D [SQL] -%D [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it] -%D -%D \startSQL -%D select * -- indeed, here we {\em do} select -%D from tableA -%D where 1 = 2 -%D \stopSQL -%D -%D \setuptyping -%D [SQL] -%D [ccommand=\tf\underbar] -%D -%D \startSQL -%D select * -- indeed, here we {\em do} select -%D from tableA -%D where 1 = 2 -%D \stopSQL -%D \stopbuffer -%D -%D \typebuffer -%D -%D Now watch: -%D -%D \getbuffer -%D -%D The natural \TEX\ typesetting was introduced when Tobias -%D and Berend started using verbatim \JAVASCRIPT\ and \SQL. - -%D \macros -%D {EveryPar, EveryLine, iflinepar} -%D -%D One of the features of these commands is the support of -%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}. -%D In the documentation of the verbatim support module we give -%D some examples of line- and paragraph numbering using these -%D macros. - -%D \macros -%D {typefile} -%D -%D Typesetting files verbatim (for the moment) only supports -%D colorization of \TEX\ sources as valid option. The other -%D setup values are inherited from display verbatim. -%D The implementation of \type{\typefile} is straightforward: - -% new feature (not yet 100\% ok) -% -% \setuptyping[file][numbering=file] -% -% \typefile[start=2,nlines=3]{zapf} -% \typefile[start=continue,nlines=13]{zapf} -% \typefile{zapf} -% -% \setuptyping[file][numbering=line] -% -% \typefile[start=4,step=3]{zapf} -% \typefile{zapf} - -\def\typefile - {\dodoubleempty\dotypefile} - -\def\dotypefile[#1][#2]#3% - {\ifsecondargument - \dodotypefile[#1][#2]{#3}% - \else\iffirstargument - \doifassignmentelse{#1} - {\dodotypefile[\v!file][#1]{#3}} - {\dodotypefile[#1][]{#3}}% - \else - \dodotypefile[\v!file][]{#3}% - \fi\fi} - -\def\dosetuptypelinenumbering#1% fuzzy - {\doifundefined{\currenttypingclass\currenttyping\c!start} - {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}% - \setuptyping[\currenttyping][#1]% - \doifelse{\typingparameter\c!numbering}\v!file - {% kind of special: filters lines ! - \setuplinenumbering[\c!method=\v!file]% - \donetrue} - {\doifelse{\typingparameter\c!numbering}\v!line - {% \setuplinenumbering defaults start/step to 1/1, so we need - \doifinsetelse\v!continue{#1,\typingparameter\c!start} - {\scratchcounter0\typingparameter\c!n - \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}% - {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}% - \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}% - \setuplinenumbering - [\c!method=\v!type, - \c!start=\typingparameter\c!start, - \c!stop=\typingparameter\c!stop, - \c!step=\typingparameter\c!step]% - \donetrue} - {\donefalse}}% - \ifdone - \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi - \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi - \def\beginofverbatimlines{\startlinenumbering}% - \def\endofverbatimlines {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}% - \fi} - -\def\reporttypingerror#1% temp hack - {\blank - \dontleavehmode\hbox\bgroup - \expanded{\defconvertedargument\noexpand\ascii{#1}}% - \tttf[\makemessage\m!verbatims1\ascii]% - \showmessage\m!verbatims1\ascii - \egroup - \blank} - -\def\dosometyping#1#2#3#4#5% - {\bgroup - \let\currenttypingclass\??tp - \edef\currenttyping{#1}% - \typingparameter\c!before - \startpacked % includes \bgroup - \dosetuptypelinenumbering{#2}% - \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal} - {\setuptyping[#1][\c!option=\v!none]}% - \doif{\typingparameter\c!option}\v!color - {\expandafter\aftersplitstring#3\at.\to\prettyidentifier - \settypingparameter\c!option{\prettyidentifier}}% - \initializetyping - \startverbatimcolor - \doifundefinedelse{\currenttypingclass#3\v!global\c!start} - {\scratchcounter\zerocount} - {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}% - \advance\scratchcounter\plusone - \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}% - \doifelsenothing{\typingparameter\c!start} - {#4} - {\doif{\typingparameter\c!start}\v!continue - {\setevalue{\currenttypingclass#1\c!start}% - {\getvalue{\currenttypingclass#3\v!global\c!start}}}% - \doifelsenothing{\typingparameter\c!stop} - {\doifelsenothing{\typingparameter\c!nlines} - {#4} - {\setxvalue{\currenttypingclass#3\v!global\c!start}% - {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}% - #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}% - {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}% - \stopverbatimcolor - \stoppacked - \typingparameter\c!after - \egroup} - -\def\doifelsetypingfile#1% sets \readfilename (we will make this proper mkiv i.e. less messy) - {\doiflocfileelse{#1} - {\firstoftwoarguments} - {\doifinputfileelse{#1} - {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments} % messy, looks wrong too - {\secondoftwoarguments}}} - -\def\dodotypefile[#1][#2]#3% - {\doifelsetypingfile{#3} - {\dosometyping{#1}{#2}{#3}{\processfileverbatim\readfilename}{\processfilelinesverbatim\readfilename}} - {\reporttypingerror{#3}}} - -%D \macros -%D {filename} -%D -%D Typesetting filenames in monospaced fonts is possible with -%D -%D \starttyping -%D \filename{here/there/filename.suffix} -%D \stoptyping -%D -%D The definition is not that spectacular. - -\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}} - -%D This leaves some settings: - -\permitshiftedendofverbatim -\optimizeverbatimtrue - -%D And a bonus macro: - -\def\verbatim#1{\defconvertedargument\ascii{#1}\ascii} - -%D The setups for display verbatim and file verbatim are -%D shared. One can adapt the extra defined typing environments, -%D but they also default to the values below. Watch the -%D alternative escape character. - -\setuptyping - [ \c!before=\blank, - \c!after=\blank, - \c!bodyfont=, - \c!color=, - \c!space=\v!off, - \c!page=\v!no, - \c!tab=\s!ascii, - \c!option=\v!none, - \c!palet=colorpretty, - \c!text=\v!no, - \c!style=\tttf, - \c!icommand=\ttsl, - \c!vcommand=, - \c!ccommand=\tttf, - \c!indentnext=\v!yes, - \c!margin=\!!zeropoint, - \c!evenmargin=\!!zeropoint, - \c!oddmargin=\!!zeropoint, - \c!blank=\v!line, - \c!escape=/, % beware \string\ , should also be accepted - \c!numbering=\v!no, - \c!lines=, - \c!empty=, - \c!start=1, - \c!stop=, - \c!step=1, - \c!continue=, - \c!nlines=] - -\definetyping[\v!typing] - -\presettyping[\v!file][] - -% \setuptyping % not needed -% [\v!file] -% [\c!start=1, -% \c!stop=, -% \c!step=1, -% \c!continue=, -% \c!nlines=] - -%D The setups for inline verbatim default to: - -\setuptype - [ \c!space=\v!off, - \c!color=, - \c!style=\tt\tf, % \tttf gives problems with {\tx \type...} - \c!page=\v!no, - \c!tab=\v!yes, - \c!palet=colorpretty, - \c!option=\v!normal] - -\definetyping[RAW] [\c!option=RAW] -\definetyping[MP] [\c!option=MP] -\definetyping[PL] [\c!option=PL] -\definetyping[PM] [\c!option=PL] -\definetyping[JS] [\c!option=JS] -\definetyping[JV] [\c!option=JV] -\definetyping[SQL] [\c!option=SQL] -\definetyping[TEX] [\c!option=TEX] -\definetyping[PAS] [\c!option=PAS] -\definetyping[PASCAL][\c!option=PAS] -\definetyping[MOD] [\c!option=PAS] -\definetyping[MODULA][\c!option=PAS] -\definetyping[DELPHI][\c!option=PAS] -\definetyping[EIFFEL][\c!option=EIF] -\definetyping[XML] [\c!option=XML] -\definetyping[LUA] [\c!option=LUA] - -\installprettytype [RAW] [RAW] - -\installprettytype [TEX] [TEX] - -\installprettytype [PERL] [PL] -\installprettytype [PL] [PL] -\installprettytype [PM] [PL] - -\installprettytype [METAPOST] [MP] -\installprettytype [METAFONT] [MP] -\installprettytype [MP] [MP] -\installprettytype [MF] [MP] - -\installprettytype [JAVASCRIPT] [JS] -\installprettytype [JAVA] [JV] -\installprettytype [JS] [JS] -\installprettytype [JV] [JV] - -\installprettytype [SQL] [SQL] - -\installprettytype [PASCAL] [PAS] -\installprettytype [PAS] [PAS] -\installprettytype [MODULA] [PAS] -\installprettytype [MOD] [PAS] - -\installprettytype [EIFFEL] [EIF] -\installprettytype [EIF] [EIF] -\installprettytype [E] [EIF] - -\installprettytype [XML] [XML] - -\installprettytype [LUA] [LUA] - -\installnewpretty M {\setupprettiesintype {MP}\setupprettytype} -\installnewpretty P {\setupprettiesintype {PL}\setupprettytype} -\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype} -\installnewpretty J {\setupprettiesintype {JV}\setupprettytype} -\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype} -\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth -\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken -\installnewpretty X {\setupprettiesintype{XML}\setupprettytype} - -%D We use the \CONTEXT\ color system for switching to and from -%D color mode. We can always redefine these colors afterwards. - -\definecolor [colorprettyone] [r=.9, g=.0, b=.0] % red -\definecolor [colorprettytwo] [r=.0, g=.8, b=.0] % green -\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue -\definecolor [colorprettyfour] [r=.8, g=.8, b=.6] % yellow - -\definecolor [grayprettyone] [s=.30] -\definecolor [grayprettytwo] [s=.45] -\definecolor [grayprettythree] [s=.60] -\definecolor [grayprettyfour] [s=.75] - -\definepalet - [colorpretty] - [ prettyone=colorprettyone, - prettytwo=colorprettytwo, - prettythree=colorprettythree, - prettyfour=colorprettyfour] - -\definepalet - [graypretty] - [ prettyone=grayprettyone, - prettytwo=grayprettytwo, - prettythree=grayprettythree, - prettyfour=grayprettyfour] - -\definepalet [TEXcolorpretty] [colorpretty] -\definepalet [TEXgraypretty] [graypretty] -\definepalet [PLcolorpretty] [colorpretty] -\definepalet [PLgraypretty] [graypretty] -\definepalet [PMcolorpretty] [colorpretty] -\definepalet [PMgraypretty] [graypretty] -\definepalet [MPcolorpretty] [colorpretty] -\definepalet [MPgraypretty] [graypretty] -\definepalet [JVcolorpretty] [colorpretty] -\definepalet [JVgraypretty] [graypretty] -\definepalet [JScolorpretty] [colorpretty] -\definepalet [JSgraypretty] [graypretty] -\definepalet [SQLcolorpretty] [colorpretty] -\definepalet [SQLgraypretty] [graypretty] -\definepalet [PAScolorpretty] [colorpretty] -\definepalet [PASgraypretty] [graypretty] -\definepalet [EIFcolorpretty] [colorpretty] -\definepalet [EIFgraypretty] [graypretty] -\definepalet [XMLcolorpretty] [colorpretty] -\definepalet [XMLgraypretty] [graypretty] -\definepalet [LUAcolorpretty] [colorpretty] -\definepalet [LUAgraypretty] [graypretty] - -\protect \endinput diff --git a/tex/context/base/core-ver.mkiv b/tex/context/base/core-ver.mkiv deleted file mode 100644 index e9c092f66..000000000 --- a/tex/context/base/core-ver.mkiv +++ /dev/null @@ -1,1179 +0,0 @@ -%D \module -%D [ file=core-ver, -%D version=2000.05.09, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Verbatim, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Core Macros / Verbatim} - -\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}} - -% \ctxluafileload{verb-tex}{} -% \ctxluafileload{verb-mp} {} -% \registerctxluafile{core-buf-tex}{} -% \registerctxluafile{core-buf-mp} {} - -\def\setupprettiesintype#1% - {\uppercasestring#1\to\ascii - \edef\prettyidentifier{\executeifdefined{\??ty\??ty\ascii}{TEX}}% - \begingroup - \lowercasestring verb-\prettyidentifier\to\filename - \doonlyonce\filename{\ctxloadluafile\filename\empty}% - \endgroup} - -\def\setupprettytype - {\processingverbatimtrue % will move - \ctxlua{buffers.visualizers.reset()}} - -\setvalue{\??tp:\c!lines:\v!yes }{\obeybreakpoints} -\setvalue{\??tp:\c!lines:\v!hyphenated}{\obeyhyphens} - -\setvalue{\??tp:\c!empty:\v!yes }{\obeyemptylines} -\setvalue{\??tp:\c!empty:\v!all }{\obeyallemptylines} - -\setvalue{\??tp:\c!option:\v!none }{\let\obeycharacters\relax} -\setvalue{\??tp:\c!option:\v!color }{\setupprettiesintype{TEX}% - \let\obeycharacters\setupprettytype - \let\obeytabs\ignoretabs} -\setvalue{\??tp:\c!option:\v!normal }{\let\obeycharacters\setupgroupedtype} -\setvalue{\??tp:\c!option:\v!commands }{\def\obeycharacters{\setupcommandsintype}% - \let\obeytabs\ignoretabs} -\setvalue{\??tp:\c!option:\v!slanted }{\let\obeycharacters\setupslantedtype - \let\obeytabs\ignoretabs} -\setvalue{\??tp:\c!option:\s!unknown }{\setupprettiesintype{\typingparameter\c!option}% - \let\obeycharacters\setupprettytype - \let\obeytabs\ignoretabs} - - -\def\setupcommonverbatim - {\recatcodeuppercharactersfalse % obey regime / encoding - % - \let\prettyidentifier\s!default - % - \doifelse{\typingparameter\c!text}\v!yes - \naturaltextexttrue - \naturaltextextfalse - \def\prettyidentifierfont{\typingparameter\c!icommand}% - \def\prettyvariablefont {\typingparameter\c!vcommand}% - \def\prettynaturalfont {\typingparameter\c!ccommand}% - % - \doif{\typingparameter\c!space}\v!on - {\def\obeyspaces{\setcontrolspaces}}% - \doif{\typingparameter\c!page }\v!no - {\def\obeypages {\ignorepages}}% - % - \doifelse{\typingparameter\c!tab}\v!yes - {\def\obeytabs{\settabskips}}% - {\doif{\typingparameter\c!tab}\s!ascii % not needed in mkiv - {\chardef\tabskipmode\plustwo % quit on >127 - \def\obeytabs{\settabskips}}}% - % - \ignorehyphens % default - \getvalue{\??tp:\c!lines:\typingparameter\c!lines}% - \getvalue{\??tp:\c!empty:\typingparameter\c!empty}% - \getvalue{\??tp:\c!option:\ifcsname\??tp:\c!option:\typingparameter\c!option\endcsname\typingparameter\c!option\else\s!unknown\fi}% - \doifnumberelse{\typingparameter\c!tab} - {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}% - \donothing - %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}% - % more generic, but beware of the \redoconvertfont (else no typing in titles and such) - \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}% - \setupverbatimcolor} - -\newtoks \everyinitializeverbatim - -\def\doinitializeverbatim - {\ctxlua{buffers.visualizers.reset()}% - \def\obs{\obeyedspace}% - \ctxlua{buffers.doifelsevisualizer("\prettyidentifier")} - {\ctxlua{buffers.setvisualizer("\prettyidentifier")}% - \localcolortrue % tricky, maybe not here - \def\bop{\bgroup\beginofpretty}% - \def\eop{\endofpretty\egroup}% - \def\sop{\endofpretty\egroup\bgroup\beginofpretty}}% - {\let\bop\donothing - \let\eop\donothing - \let\sop\donothing}% - \verbatimfont - \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. - -\def\setupcommandsintype % can also be \string\ - {\ctxlua{ - buffers.visualizers.enableescape = true - buffers.visualizers.escapetoken = \!!bs\typingparameter\c!escape\!!es - }% - \setevalue{\typingparameter\c!escape}{\typingparameter\c!escape}} - -\def\setupslantedtype - {\slantedtypepermittedtrue} - -\ifx\setupprettytype \undefined \let\setupprettytype \relax \fi -\ifx\setupslantedtype \undefined \let\setupslantedtype \relax \fi -\ifx\setupgroupedtype \undefined \let\setupgroupedtype \relax \fi -\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi - -%D The verbatim commands have a rather long and turbulent -%D history. Most users of \CONTEXT\ probably will never use -%D some of the features, but I've kept in mind that when one is -%D writing a users manual, about everything can and undoubtly -%D will be subject to a verbatim treatment. -%D -%D Verbatim command are very sensitive to argument processing, -%D which is a direct result of the \CATCODES\ being fixed at -%D reading time. With our growing understanding of \TEX, -%D especially of the mechanism that can be used for looking -%D ahead and manipulating \CATCODES, the verbatim support -%D became more and more advanced and natural. -%D -%D Typesetting inline verbatim can be accomplished by -%D \type{\type}, which in this sentence was typeset by saying -%D just \type{\type{\type}}, which in turn was typeset by -%D \unknown. Using the normal grouping characters \type{{}} is -%D the most natural way of using this command. -%D -%D A second, more or less redundant, alternative is delimiting -%D the argument with an own character. This method was -%D implemented in the context of a publication in the \MAPS, -%D where this way of delimiting is recognized by \LATEX\ users. -%D -%D The third, more original alternative, is the one using -%D \type{<<} and \type{>>} as delimiters. This alternative can -%D be used in situations where slanted typeseting is needed. - -% todo: we can use \letter... here: - -\def\lesscharacter {<} -\def\morecharacter {>} - -\chardef\texescape = `\\ -\chardef\leftargument = `\{ -\chardef\rightargument = `\} - -%D \macros -%D {type} -%D -%D We define \type{\type} as a protected command. This command -%D has several invocations: grouped, wirt boundary characters, -%D and with font switches. - -% \starttyping -% normal: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \par -% normal: \par \type{xx<..xx.. >..>xx} \par \type{<....>} \par \type{<....>} -% \setuptype[option=slanted] -% slanted: \par \type{xx<<..sl..<> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<>..>> \par -% slanted: \par \type{xx<<..sl.. xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<....>> \par -% \setuptype[option=none] -% none: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \par -% \stoptyping - -%D When writing the manual to \CONTEXT\ and documenting this -%D source we needed to typeset \type{<<} and \type{>>}. Because -%D we wanted to do this in the natural way, we've adapted the -%D original definition a bit. This implementation went through -%D several live cycles. The final implementation looks a bit -%D further and treats the lone \type{<<} and \type{>>} a bit -%D different. The \type {\null} prevents ligatures, which -%D unfortunately turn up in Lucida fonts. - -%D The following lines show what happens when we set -%D \type {option=commands}. -%D -%D \startbuffer -%D \starttyping -%D test//test test/BTEX \footnote{test test test}/ETEX test -%D test//test test/BTEX \footnote{test test test}/ETEX test -%D test test test/BTEX \bf(nota bene)/ETEX test -%D test test test /BTEX \bf(nota bene)/ETEX test -%D \stoptyping -%D \stopbuffer -%D -%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup -%D -%D this was keyed in as: -%D -%D \typebuffer - -\unexpanded\def\type{\dotype\empty} - -\def\dotype#1% was \dotype - {\bgroup - \begstrut % new, enables leading space in \type { abc } at par start / begstrut else no hyphenation - \let\currenttypingclass\??ty - \edef\currenttyping{#1}% - \catcode`\<=\@@other - \catcode`\>=\@@other - \futurelet\next\dodotype} - -\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} - -\def\dodotypeA - {\initializetype % probably too much - \verbatimcolor - \setcatcodetable \typcatcodesa - \dodotypeAA} - -\def\dodotypeAA#1% - {\doinitializeverbatim - \def\obs{\obeyedspace}% - \ctxlua{buffers.hooks.flush_line(\!!bs\detokenize{#1}\!!es)}% - \egroup} - -\def\dodotypeB#1% - {\initializetype - \verbatimcolor - \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 - \setcatcodetable \typcatcodesb - \dodotypeCC} - -\def\dodotypeCC#1% - {\doinitializeverbatim - \ifx\obeycharacters\setupprettytype % temp hack, we need a proper signal - \ctxlua{buffers.hooks.flush_line([\!!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 - \setcatcodetable \typcatcodesa - \def\dodotypeDD##1#1{\dodotypeAA{##1}}% - \dodotypeDD} - -\def\dodotypeDD#1% - {\doinitializeverbatim - \ctxlua{buffers.hooks.flush_line(\!!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 - \setupinlineverbatim} - -%D \macros -%D {setuptype} -%D -%D Some characteristics of \type{\type} can be set up by: - -\def\setuptype - {\dodoubleempty\dosetuptype} - -\def\dosetuptype[#1][#2]% - {\ifsecondargument - \getparameters[\??ty#1][#2]% - \else - \getparameters[\??ty][#1]% - \fi} - -%D \macros -%D {typ,obeyhyphens,obeybreakpoints} -%D -%D Although it's not clear from the macros, one character -%D trait of this macros, which are build on top of the support -%D module, is that they don't hyphenate. We therefore offer -%D the alternative \type{\typ}. The current implementation -%D works all right, but a decent hyphenation support of -%D \type{\tt} text will be implemented soon. - -\def\obeyhyphens - {\def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip - \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}% - \spaceskip.25em\relax} % hm a bit of stretch ! - -\def\obeybreakpoints - {\ignorehyphens - \veryraggedright} - -\def\ignorehyphens - {% \language\minusone % extra bonus, the \null should do the job too - \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip - \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}% - \spaceskip.5em\relax} - -\unexpanded\def\typ - {\bgroup - \let\@@tylines\v!hyphenated - \futurelet\next\dodotype} - -%D \macros -%D {tex,arg,mat,dis} -%D -%D Sometimes, for instance when we pass verbatim text as an -%D argument, the fixed \CATCODES\ interfere with our wishes. An -%D experimental implementation of character by character -%D processing of verbatim text did overcome this limitation, -%D but we've decided not to use that slow and sometimes -%D troublesome solution. Instead we stick to some 'old' -%D \CONTEXT\ macros for typesetting typical \TEX\ characters. -%D -%D The next implementation is more clear but less versatile, -%D so we treated it for a beter one. -%D -%D \starttyping -%D \def\dospecialtype#1#2% -%D {\bgroup -%D \initializetype -%D \catcode`\{=\@@begingroup -%D \catcode`\}=\@@endgroup -%D \def\dospecialtype% -%D {\def\dospecialtype{#2\egroup}% -%D \bgroup -%D \aftergroup\dospecialtype -%D #1}% -%D \afterassignment\dospecialtype -%D \let\next=} -%D -%D \unexpanded\def\tex{\dospecialtype\texescape\relax} -%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument} -%D \unexpanded\def\mat{\dospecialtype\$\$} -%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}} -%D \stoptyping - -\def\setgroupedtype - {\let\currenttypingclass\??ty - \initializetype - \verbatimcolor - %\setcatcodetable \typcatcodesa - \catcode`\{=\@@begingroup - \catcode`\}=\@@endgroup} - -\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}} -\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}} -\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}} -\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}} - -%D \macros -%D {starttyping} -%D -%D Display verbatim is realized far more easy, which is mostly -%D due to the fact that we use \type{\stop...} as delimiter. -%D The implementation inherits some features, for instance the -%D support of linenumbering, which can best be studied in the -%D documented support module. - -\let\currenttyping \empty -\let\currenttypingclass\??ty % saveguard - -% \def\typingparameter#1% -% {\executeifdefined -% {\currenttypingclass\currenttyping#1}% -% {\executeifdefined{\currenttypingclass#1}\empty}} - -\def\typingparameter#1% - {\ifcsname\currenttypingclass\currenttyping#1\endcsname - \csname\currenttypingclass\currenttyping#1\endcsname - \else\ifcsname\currenttypingclass#1\endcsname - \csname\currenttypingclass#1\endcsname - \fi\fi} - -\def\settypingparameter#1#2% - {\setvalue{\currenttypingclass\currenttyping#1}{#2}} - -\def\setxtypingparameter#1#2% - {\setxvalue{\currenttypingclass\currenttyping#1}{#2}} - -% \def\initializetyping -% {%\donefalse -% \switchtobodyfont[\typingparameter\c!bodyfont]% -% \donefalse -% \scratchskip\typingparameter\c!oddmargin\relax -% \ifzeropt\scratchskip\else\donetrue\fi -% \scratchskip\typingparameter\c!evenmargin\relax -% \ifzeropt\scratchskip\else\donetrue\fi -% \ifdone -% \def\doopenupverbatimline -% {\getpagestatus -% \ifrightpage -% \hskip\typingparameter\c!oddmargin\relax -% \else -% \hskip\typingparameter\c!evenmargin\relax -% \fi}% -% \else -% \doadaptleftskip{\typingparameter\c!margin}% -% \fi -% \doifdefinedelse{\??bo\typingparameter\c!blank} -% {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}} -% {\edef\!!stringa{\typingparameter\c!blank}}% -% \processaction -% [\!!stringa] -% [ \v!standard=>\scratchskip\ctxparskip, -% \v!small=>\scratchskip\blankokleinmaat, -% \v!medium=>\scratchskip\blankomiddelmaat, -% \v!big=>\scratchskip\blankogrootmaat, -% \v!halfline=>\scratchskip.5\baselineskip, -% \v!line=>\scratchskip\baselineskip, -% \v!none=>\scratchskip\zeropoint, -% \s!unknown=>\scratchskip\commalistelement]% -% \ifgridsnapping -% \ifdim\scratchskip=.5\baselineskip\relax -% \edef\verbatimbaselineskip{\the\scratchskip}% new -% \else -% \edef\verbatimbaselineskip{\the\baselineskip}% -% \fi -% \else -% \edef\verbatimbaselineskip{\the\scratchskip}% -% \fi -% \setupcommonverbatim} - -\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip} -\setvalue{\??tp:\c!blank:\v!small }{\blankokleinmaat} -\setvalue{\??tp:\c!blank:\v!medium }{\blankomiddelmaat} -\setvalue{\??tp:\c!blank:\v!big }{\blankogrootmaat} -\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip} -\setvalue{\??tp:\c!blank:\v!line }{\baselineskip} -\setvalue{\??tp:\c!blank:\v!none }{\zeropoint} - -\def\initializetyping - {%\donefalse - \switchtobodyfont[\typingparameter\c!bodyfont]% - \donefalse - \scratchskip\typingparameter\c!oddmargin\relax - \ifzeropt\scratchskip\else\donetrue\fi - \scratchskip\typingparameter\c!evenmargin\relax - \ifzeropt\scratchskip\else\donetrue\fi - \ifdone - \def\doopenupverbatimline - {\getpagestatus - \ifrightpage - \hskip\typingparameter\c!oddmargin\relax - \else - \hskip\typingparameter\c!evenmargin\relax - \fi}% - \else - \doadaptleftskip{\typingparameter\c!margin}% - \fi - \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}% - \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax - \ifgridsnapping - \ifdim\scratchskip=.5\baselineskip\relax - \edef\verbatimbaselineskip{\the\scratchskip}% new - \else - \edef\verbatimbaselineskip{\the\baselineskip}% - \fi - \else - \edef\verbatimbaselineskip{\the\scratchskip}% - \fi - \setupcommonverbatim} - -%D The basic display verbatim commands are defined in an -%D indirect way. As we will see, they are a specific case of a -%D more general mechanism. - -% we need this hack because otherwise verbatim skips -% the first line (everything after the initial command) - -\def\dostarttyping#1% tricky non standard lookahead - {\bgroup - \let\currenttypingclass\??tp - \edef\currenttyping{#1}% - \obeylines - \futurelet\nexttoken\dodostarttyping} - -\def\dodostarttyping - {\ifx\nexttoken[% - \expandafter\dododostarttyping - \else - \expandafter\nododostarttyping - \fi} - -\def\nododostarttyping - {\dododostarttyping[]} - -\def\dotypefileverbatim - {\doinitializeverbatim - \ctxlua{buffers.typefile("\readfilename")}} - -\def\dotypefilelinesverbatim#1#2% - {#1% - \doinitializeverbatim - \ctxlua{buffers.typefile("\readfilename")}% - #2} - -\def\dotypeblockverbatim#1#2% - {\dowithbuffer{_typing_}{#1}{#2} - {} - {\doinitializeverbatim - \beginofverbatimlines - \ctxlua{buffers.type("_typing_")}% - \endofverbatimlines - \getvalue{\strippedcsname#2}}} - -\def\dododostarttyping[#1]% - {\typingparameter\c!before - \startpacked % includes \bgroup - \dosetuptypelinenumbering{#1}% - \initializetyping - \startverbatimcolor - \expanded{\dotypeblockverbatim{\s!start\currenttyping}{\s!stop\currenttyping}}} - -\def\dostoptyping#1% hm, currenttyping - {\stopverbatimcolor - \stoppacked % includes \egroup - \typingparameter\c!after - \egroup - \dochecknextindentation{\??tp#1}% - \dorechecknextindentation} - -%D Line numbering for files is combined with filtering, while -%D display verbatim has the ability to continue. -%D -%D \starttyping -%D \typefile[numbering=file,start=10,stop=12]{test.tex} -%D -%D \definetyping[code][numbering=line] -%D -%D \starttext -%D \startcode -%D ... -%D ... -%D \stopcode -%D -%D \startcode[continue] -%D ... -%D ... -%D \stopcode -%D -%D \startcode[start=10] -%D ... -%D \stopcode -%D \stoptyping - -%D \macros -%D {setuptyping} -%D -%D The setup of typing accepts two arguments. The optional -%D first one identifies the user defined ones. If only one -%D argument is given, the values apply to both the standard -%D command \type{\starttyping} and \type{\typefile}. - -\def\dosetuptyping[#1][#2]% - {\ifsecondargument - \getparameters[\??tp#1][#2]% - \else - \getparameters[\??tp][#1]% - \fi} - -\def\setuptyping - {\dodoubleempty\dosetuptyping} - -%D \macros -%D {definetype} -%D -%D Specific inline verbatim commands can be defined with the -%D following command. - -\def\definetype - {\dodoubleempty\dodefinetype} - -\def\dodefinetype[#1][#2]% - {\unexpanded\setvalue{#1}{\dotype{#1}}% - \getparameters[\??ty#1][#2]} - -%D \macros -%D {definetyping} -%D -%D For most users the standard \type{\start}||\type{\stop}||pair -%D will suffice, but for documentation purposes the next -%D definition command can be of use: -%D -%D \starttyping -%D \definetyping[extratyping][margin=3em] -%D -%D \startextratyping -%D these extra ones are indented by 1 em -%D \stopextratyping -%D \stoptyping -%D -%D The definitions default to the standard typing values. - -\def\presettyping[#1][#2]% - {\copyparameters[\??tp#1][\??tp][\c!color,\c!style]% - \getparameters [\??tp#1][#2]} - -\def\dodefinetyping[#1][#2]% - {\setvalue{\e!start#1}{\dostarttyping{#1}}% - \setvalue{\e!stop #1}{\dostoptyping {#1}}% - \presettyping[#1][#2]} - -\def\definetyping - {\dodoubleempty\dodefinetyping} - -%D We can use some core color commands. These are faster than -%D the standard color switching ones and work ok on a line by -%D line basis. -%D -%D \starttyping -%D \def\setupverbatimcolor% -%D {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}% -%D \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}% -%D \def\endofpretty {\stopcolormode}} -%D \stoptyping -%D -%D Since we support a global color too, the folowing -%D definition is better: - -% \def\setupverbatimcolor% fast and local versus slow and global -% {\doifelsenothing{\typingparameter\c!color} -% {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}% -% \let\endofpretty \restorecolormode % \stopcolormode -% \let\startverbatimcolor \relax -% \let\stopverbatimcolor \relax -% \let\verbatimcolor \relax} -% {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}% -% \let\endofpretty \stopcolor -% \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}% -% \let\stopverbatimcolor \stopcolor -% \def\verbatimcolor {\getvalue{\typingparameter\c!color}}}% command ! -% \doifelsenothing{\typingparameter\c!palet} -% {\let\prettypalet\empty -% \let\endofpretty\relax -% \def\beginofpretty[##1]{}} -% {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}} -% -% let's forget about this optimization not that we have mkiv - -\def\setupverbatimcolor - {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}% - \let\endofpretty \stopcolor - \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}% - \let\stopverbatimcolor \stopcolor - \def\verbatimcolor {\getvalue{\typingparameter\c!color}}% command ! - \doifelsenothing{\typingparameter\c!palet} - {\let\prettypalet\empty - \let\endofpretty\relax - \def\beginofpretty[##1]{}} - {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}} - -\let\prettypalet \empty -\let\startverbatimcolor\relax -\let\stopverbatimcolor \relax -\let\verbatimcolor \relax - -%D In the verbatim module, there are some examples given of -%D the more obscure features of the verbatim environments. -%D -%D \startbuffer -%D \startTEX -%D \def\mathematics#1% % usage: \type {\mathematics{x^2}} -%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2} -%D \stopTEX -%D \stopbuffer -%D -%D \typebuffer -%D -%D This gives, as can be expected: -%D -%D \getbuffer -%D -%D When we want to see some typeset \TEX\ too, we can say: -%D -%D \startbuffer -%D \startTEX -%D \def\mathematics#1% %%\ N usage: \type {\mathematics{x^2}} -%D {\ifmmode#1\else$#1$\fi} %%\ N becomes: \mathematics{x^2} -%D \stopTEX -%D \stopbuffer -%D -%D \typebuffer -%D -%D or: -%D -%D \getbuffer -%D -%D In a similar way: -%D -%D \startbuffer -%D \startSQL -%D select * -- indeed, here we {\em do} select -%D from tableA -%D where 1 = 2 -%D \stopSQL -%D \stopbuffer -%D -%D \typebuffer -%D -%D gives: -%D -%D \getbuffer -%D -%D The next examples sow how we can directly call for natural -%D \TEX\ comments: -%D -%D \startbuffer -%D \setuptyping -%D [TEX] -%D [text=yes] -%D -%D \startTEX -%D \def\mathematics#1% % usage: \type {\mathematics{x^2}} -%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2} -%D \stopTEX -%D -%D \setuptyping -%D [SQL] -%D [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it] -%D -%D \startSQL -%D select * -- indeed, here we {\em do} select -%D from tableA -%D where 1 = 2 -%D \stopSQL -%D -%D \setuptyping -%D [SQL] -%D [ccommand=\tf\underbar] -%D -%D \startSQL -%D select * -- indeed, here we {\em do} select -%D from tableA -%D where 1 = 2 -%D \stopSQL -%D \stopbuffer -%D -%D \typebuffer -%D -%D Now watch: -%D -%D \getbuffer -%D -%D The natural \TEX\ typesetting was introduced when Tobias -%D and Berend started using verbatim \JAVASCRIPT\ and \SQL. - -%D \macros -%D {EveryPar, EveryLine, iflinepar} -%D -%D One of the features of these commands is the support of -%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}. -%D In the documentation of the verbatim support module we give -%D some examples of line- and paragraph numbering using these -%D macros. - -%D \macros -%D {typefile} -%D -%D Typesetting files verbatim (for the moment) only supports -%D colorization of \TEX\ sources as valid option. The other -%D setup values are inherited from display verbatim. -%D The implementation of \type{\typefile} is straightforward: - -% new feature (not yet 100\% ok) -% -% \setuptyping[file][numbering=file] -% -% \typefile[start=2,nlines=3]{zapf} -% \typefile[start=continue,nlines=13]{zapf} -% \typefile{zapf} -% -% \setuptyping[file][numbering=line] -% -% \typefile[start=4,step=3]{zapf} -% \typefile{zapf} - -\def\typefile - {\dodoubleempty\dotypefile} - -\def\dotypefile[#1][#2]#3% - {\ifsecondargument - \dodotypefile[#1][#2]{#3}% - \else\iffirstargument - \doifassignmentelse{#1} - {\dodotypefile[\v!file][#1]{#3}} - {\dodotypefile[#1][]{#3}}% - \else - \dodotypefile[\v!file][]{#3}% - \fi\fi} - -\def\dosetuptypelinenumbering#1% fuzzy - {\doifundefined{\currenttypingclass\currenttyping\c!start} - {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}% - \setuptyping[\currenttyping][#1]% - \doifelse{\typingparameter\c!numbering}\v!file - {% kind of special: filters lines ! - \setuplinenumbering[\c!method=\v!file]% - \donetrue} - {\doifelse{\typingparameter\c!numbering}\v!line - {% \setuplinenumbering defaults start/step to 1/1, so we need - \doifinsetelse\v!continue{#1,\typingparameter\c!start} - {\scratchcounter0\typingparameter\c!n - \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}% - {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}% - \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}% - \setuplinenumbering - [\c!method=\v!type, - \c!start=\typingparameter\c!start, - \c!stop=\typingparameter\c!stop, - \c!step=\typingparameter\c!step]% - \donetrue} - {\donefalse}}% - \ifdone - \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi - \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi - \def\beginofverbatimlines{\startlinenumbering}% - \def\endofverbatimlines {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}% - \fi} - -\def\reporttypingerror#1% temp hack - {\blank - \dontleavehmode\hbox\bgroup - \expanded{\defconvertedargument\noexpand\ascii{#1}}% - \tttf[\makemessage\m!verbatims1\ascii]% - \showmessage\m!verbatims1\ascii - \egroup - \blank} - -\def\dosometyping#1#2#3#4#5% - {\bgroup - \let\currenttypingclass\??tp - \edef\currenttyping{#1}% - \typingparameter\c!before - \startpacked % includes \bgroup - \dosetuptypelinenumbering{#2}% - \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal} - {\setuptyping[#1][\c!option=\v!none]}% - \doif{\typingparameter\c!option}\v!color - {\expandafter\aftersplitstring#3\at.\to\prettyidentifier - \settypingparameter\c!option{\prettyidentifier}}% - \initializetyping - \startverbatimcolor - \doifundefinedelse{\currenttypingclass#3\v!global\c!start} - {\scratchcounter\zerocount} - {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}% - \advance\scratchcounter\plusone - \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}% - \doifelsenothing{\typingparameter\c!start} - {#4} - {\doif{\typingparameter\c!start}\v!continue - {\setevalue{\currenttypingclass#1\c!start}% - {\getvalue{\currenttypingclass#3\v!global\c!start}}}% - \doifelsenothing{\typingparameter\c!stop} - {\doifelsenothing{\typingparameter\c!nlines} - {#4} - {\setxvalue{\currenttypingclass#3\v!global\c!start}% - {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}% - #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}% - {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}% - \stopverbatimcolor - \stoppacked - \typingparameter\c!after - \egroup} - -\def\doifelsetypingfile#1% sets \readfilename (we will make this proper mkiv i.e. less messy) - {\doiflocfileelse{#1} - {\firstoftwoarguments} - {\doifinputfileelse{#1} - {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments} % messy, looks wrong too - {\secondoftwoarguments}}} - -\def\dodotypefile[#1][#2]#3% - {\doifelsetypingfile{#3} - {\dosometyping{#1}{#2}{#3}\dotypefileverbatim\dotypefilelinesverbatim} - {\reporttypingerror{#3}}} - -%D \macros -%D {filename} -%D -%D Typesetting filenames in monospaced fonts is possible with -%D -%D \starttyping -%D \filename{here/there/filename.suffix} -%D \stoptyping -%D -%D The definition is not that spectacular. - -\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}} - -%D This leaves some settings: - -\permitshiftedendofverbatim -\optimizeverbatimtrue - -%D And a bonus macro: - -\def\verbatim#1{\defconvertedargument\ascii{#1}\ascii} - -%D The setups for display verbatim and file verbatim are -%D shared. One can adapt the extra defined typing environments, -%D but they also default to the values below. Watch the -%D alternative escape character. - -\setuptyping - [ \c!before=\blank, - \c!after=\blank, - \c!bodyfont=, - \c!color=, - \c!space=\v!off, - \c!page=\v!no, - \c!tab=\s!ascii, - \c!option=\v!none, - \c!palet=colorpretty, - \c!text=\v!no, - \c!style=\tttf, - \c!icommand=\ttsl, - \c!vcommand=, - \c!ccommand=\tttf, - \c!indentnext=\v!yes, - \c!margin=\!!zeropoint, - \c!evenmargin=\!!zeropoint, - \c!oddmargin=\!!zeropoint, - \c!blank=\v!line, - \c!escape=/, % beware \string\ , should also be accepted - \c!numbering=\v!no, - \c!lines=, - \c!empty=, - \c!start=1, - \c!stop=, - \c!step=1, - \c!continue=, - \c!nlines=] - -\definetyping[\v!typing] - -\presettyping[\v!file][] - -% \setuptyping % not needed -% [\v!file] -% [\c!start=1, -% \c!stop=, -% \c!step=1, -% \c!continue=, -% \c!nlines=] - -%D The setups for inline verbatim default to: - -\setuptype - [ \c!space=\v!off, - \c!color=, - \c!style=\tt\tf, % \tttf gives problems with {\tx \type...} - \c!page=\v!no, - \c!tab=\v!yes, - \c!palet=colorpretty, - \c!option=\v!normal] - -\definetyping[RAW] [\c!option=RAW] -\definetyping[MP] [\c!option=MP] -\definetyping[PL] [\c!option=PL] -\definetyping[PM] [\c!option=PL] -\definetyping[JS] [\c!option=JS] -\definetyping[JV] [\c!option=JV] -\definetyping[SQL] [\c!option=SQL] -\definetyping[TEX] [\c!option=TEX] -\definetyping[PAS] [\c!option=PAS] -\definetyping[PASCAL][\c!option=PAS] -\definetyping[MOD] [\c!option=PAS] -\definetyping[MODULA][\c!option=PAS] -\definetyping[DELPHI][\c!option=PAS] -\definetyping[EIFFEL][\c!option=EIF] -\definetyping[XML] [\c!option=XML] -\definetyping[LUA] [\c!option=LUA] - -\installprettytype [RAW] [RAW] - -\installprettytype [TEX] [TEX] - -\installprettytype [PERL] [PL] -\installprettytype [PL] [PL] -\installprettytype [PM] [PL] - -\installprettytype [METAPOST] [MP] -\installprettytype [METAFONT] [MP] -\installprettytype [MP] [MP] -\installprettytype [MF] [MP] - -\installprettytype [JAVASCRIPT] [JS] -\installprettytype [JAVA] [JV] -\installprettytype [JS] [JS] -\installprettytype [JV] [JV] - -\installprettytype [SQL] [SQL] - -\installprettytype [PASCAL] [PAS] -\installprettytype [PAS] [PAS] -\installprettytype [MODULA] [PAS] -\installprettytype [MOD] [PAS] - -\installprettytype [EIFFEL] [EIF] -\installprettytype [EIF] [EIF] -\installprettytype [E] [EIF] - -\installprettytype [XML] [XML] - -\installprettytype [LUA] [LUA] - -\installnewpretty M {\setupprettiesintype {MP}\setupprettytype} -\installnewpretty P {\setupprettiesintype {PL}\setupprettytype} -\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype} -\installnewpretty J {\setupprettiesintype {JV}\setupprettytype} -\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype} -\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth -\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken -\installnewpretty X {\setupprettiesintype{XML}\setupprettytype} - -%D We use the \CONTEXT\ color system for switching to and from -%D color mode. We can always redefine these colors afterwards. - -\definecolor [colorprettyone] [r=.9, g=.0, b=.0] % red -\definecolor [colorprettytwo] [r=.0, g=.8, b=.0] % green -\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue -\definecolor [colorprettyfour] [r=.8, g=.8, b=.6] % yellow - -\definecolor [grayprettyone] [s=.30] -\definecolor [grayprettytwo] [s=.45] -\definecolor [grayprettythree] [s=.60] -\definecolor [grayprettyfour] [s=.75] - -\definepalet - [colorpretty] - [ prettyone=colorprettyone, - prettytwo=colorprettytwo, - prettythree=colorprettythree, - prettyfour=colorprettyfour] - -\definepalet - [graypretty] - [ prettyone=grayprettyone, - prettytwo=grayprettytwo, - prettythree=grayprettythree, - prettyfour=grayprettyfour] - -\definepalet [TEXcolorpretty] [colorpretty] -\definepalet [TEXgraypretty] [graypretty] -\definepalet [PLcolorpretty] [colorpretty] -\definepalet [PLgraypretty] [graypretty] -\definepalet [PMcolorpretty] [colorpretty] -\definepalet [PMgraypretty] [graypretty] -\definepalet [MPcolorpretty] [colorpretty] -\definepalet [MPgraypretty] [graypretty] -\definepalet [JVcolorpretty] [colorpretty] -\definepalet [JVgraypretty] [graypretty] -\definepalet [JScolorpretty] [colorpretty] -\definepalet [JSgraypretty] [graypretty] -\definepalet [SQLcolorpretty] [colorpretty] -\definepalet [SQLgraypretty] [graypretty] -\definepalet [PAScolorpretty] [colorpretty] -\definepalet [PASgraypretty] [graypretty] -\definepalet [EIFcolorpretty] [colorpretty] -\definepalet [EIFgraypretty] [graypretty] -\definepalet [XMLcolorpretty] [colorpretty] -\definepalet [XMLgraypretty] [graypretty] -\definepalet [LUAcolorpretty] [colorpretty] -\definepalet [LUAgraypretty] [graypretty] - -% patched from verb-ini (todo) - -\let\beginverbatimline \relax -\let\endverbatimline \relax -\let\doopenupverbatimline\empty - -\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/core-vis.tex b/tex/context/base/core-vis.tex deleted file mode 100644 index 949cd176f..000000000 --- a/tex/context/base/core-vis.tex +++ /dev/null @@ -1,748 +0,0 @@ -%D \module -%D [ file=core-vis, -%D version=1996.06.01, -%D title=\CONTEXT\ Core 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. - -%D This module adds some more visualization cues to the ones -%D supplied in the support module. -%D -%D %\everypar dual character, \the\everypar and \everypar= -%D %\hrule cannot be grabbed in advance, switches mode -%D %\vrule cannot be grabbed in advance, switches mode -%D % -%D %\indent only explicit ones -%D %\noindent only explicit ones -%D %\par only explicit ones -%D -%D %\leftskip only if explicit one -%D %\rightskip only if explicit one - -\writestatus{loading}{ConTeXt Support Macros / Visualization} - -\unprotect - -%D \macros -%D {indent, noindent, par} -%D -%D \TeX\ acts upon paragraphs. In mosts documents paragraphs -%D are separated by empty lines, which internally are handled as -%D \type{\par}. Paragraphs can be indented or not, depending on -%D the setting of \type{\parindent}, the first token of a -%D paragraph and/or user suppressed or forced indentation. -%D -%D Because the actual typesetting is based on both explicit -%D user and implicit system actions, visualization is only -%D possible for the user supplied \type{\indent}, -%D \type{\noindent}, and \type{\par}. Other -%D 'clever' tricks will quite certainly lead to more failures -%D than successes, so we only support these three explicit -%D primitives and one macro: - -\def\showparagraphcue#1#2#3#4#5% - {\bgroup - \scratchdimen#1\relax - \dontinterfere - \dontcomplain - \boxrulewidth5\testrulewidth - #3#4\relax - \setbox\scratchbox\normalhbox to \scratchdimen - {#2{\ruledhbox to \scratchdimen - {\vrule #5 20\testrulewidth \!!width \zeropoint - \normalhss}}}% - \smashbox\scratchbox - \normalpenalty\!!tenthousand - \box\scratchbox - \egroup} - -\def\ruledhanging - {\ifdim\hangindent>\zeropoint - \ifnum\hangafter<\zerocount - \normalhbox - {\boxrulewidth5\testrulewidth - \setbox\scratchbox\ruledhbox to \hangindent - {\scratchdimen\strutht - \advance\scratchdimen \strutdp - \vrule - \!!width \zeropoint - \!!height \zeropoint - \!!depth -\hangafter\scratchdimen}% - \normalhskip-\hangindent - \smashbox\scratchbox - \raise\strutht\box\scratchbox}% - \fi - \fi} - -\def\ruledparagraphcues - {\bgroup - \dontcomplain - \normalhbox to \zeropoint - {\ifdim\leftskip>\zeropoint\relax - \showparagraphcue\leftskip\llap\relax\relax\!!depth - \normalhskip-\leftskip - \fi - \ruledhanging - \normalhskip\hsize - \ifdim\rightskip>\zeropoint\relax - \normalhskip-\rightskip - \showparagraphcue\rightskip\relax\relax\relax\!!depth - \fi}% - \egroup} - -\def\ruledpar - {\relax - \ifhmode - \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\!!height - \fi - \normalpar} - -\def\rulednoindent - {\relax - \normalnoindent - \ruledparagraphcues - \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\!!height} - -\def\ruledindent - {\relax - \normalnoindent - \ruledparagraphcues - \ifdim\parindent>\zeropoint - \showparagraphcue\parindent\relax\relax\relax\!!height - \else - \showparagraphcue{40\testrulewidth}\llap\relax\relax\!!height - \fi - \normalhskip\parindent} - -\def\dontshowimplicits - {\let\noindent \normalnoindent - \let\indent \normalindent - \let\par \normalpar} - -\def\showimplicits - {\testrulewidth \defaulttestrulewidth - \let\noindent \rulednoindent - \let\indent \ruledindent - \let\par \ruledpar} - -%D The next few||line examples show the four cues. Keep in -%D mind that we only see them when we explicitly open or close -%D a paragraph. -%D -%D \bgroup -%D \def\voorbeeld#1% -%D {#1Visualizing some \TeX\ primitives and Plain \TeX\ -%D macros can be very instructive, at least it is to me. -%D Here we see {\tt\string#1} and {\tt\string\ruledpar} in -%D action, while {\tt\string\parindent} equals -%D {\tt\the\parindent}.\ruledpar} -%D -%D \showimplicits -%D -%D \voorbeeld \indent -%D \voorbeeld \noindent -%D -%D \parindent=60pt -%D -%D \voorbeeld \indent -%D \voorbeeld \noindent -%D -%D \startnarrower -%D \voorbeeld \indent -%D \voorbeeld \noindent -%D \stopnarrower -%D \egroup -%D -%D These examples also demonstrate the visualization of -%D \type {\leftskip} and \type {\rightskip}. The macro -%D \type {\nofruledbaselines} determines the number of lines -%D shown. - -\newcounter\ruledbaselines - -\def\nofruledbaselines{3} - -\def\debuggertext#1% - {\ifx\ttxx\undefined - $\scriptscriptstyle#1$% - \else - {\ttxx#1}% - \fi} - -\def\ruledbaseline - {\vrule \!!width \zeropoint - \bgroup - \dontinterfere - \doglobal\increment\ruledbaselines - \scratchdimen\nofruledbaselines\baselineskip - \setbox\scratchbox\normalvbox to 2\scratchdimen - {\leaders - \normalhbox - {\strut - \vrule - \!!height \testrulewidth - \!!depth \testrulewidth - \!!width 120\points} - \normalvfill}% - \smashbox\scratchbox - \advance\scratchdimen \strutheightfactor\baselineskip - \setbox\scratchbox\normalhbox - {\normalhskip -48\points - \normalhbox to 24\points - {\normalhss\debuggertext\ruledbaselines\normalhskip6\points}% - \raise\scratchdimen\box\scratchbox}% - \smashbox\scratchbox - \box\scratchbox - \egroup} - -\def\showbaselines - {\testrulewidth\defaulttestrulewidth - \EveryPar{\ruledbaseline}} - -%D \macros -%D {showpagebuilder} -%D -%D The next tracing option probaly is only of use to me and a -%D few \CONTEXT\ hackers. - -\def\showpagebuilder - {\EveryPar{\doshowpagebuilder}} - -\def\doshowpagebuilder - {\strut\llap - {\startcolor[blue]\vl - \high{\infofont v:\the\vsize }\vl - \high{\infofont g:\the\pagegoal }\vl - \high{\infofont t:\the\pagetotal}\vl - \stopcolor}} - -%D \macros -%D {makecutbox, cuthbox, cutvbox, cutvtop} -%D -%D Although mainly used for marking the page, these macros can -%D also serve local use. -%D -%D \startbuffer -%D \setbox0=\vbox{a real \crlf vertical box} \makecutbox0 -%D \stopbuffer -%D -%D \typebuffer -%D -%D This marked \type{\vbox} shows up as: -%D -%D \startlinecorrection -%D \getbuffer -%D \stoplinecorrection -%D -%D The alternative macros are used as: -%D -%D \startbuffer -%D \cuthbox{a made cut box} -%D \stopbuffer -%D -%D \typebuffer -%D -%D This is typeset as: -%D -%D \startlinecorrection -%D \getbuffer -%D \stoplinecorrection -%D -%D By setting the next macros one can influence the length of -%D the marks as well as the horizontal and vertical divisions. - -\def\cutmarklength {2\bodyfontsize} -\chardef\horizontalcutmarks = 2 -\chardef\verticalcutmarks = 2 -\chardef\cutmarkoffset = 1 -\let\cutmarksymbol = \relax -\let\cutmarktoptext = \empty -\let\cutmarkbottomtext = \empty - -\def\horizontalcuts - {\normalhbox to \ruledwidth - {\dorecurse\horizontalcutmarks - {\vrule\!!width\boxrulewidth\!!height\cutmarklength\normalhfill}% - \unskip}} - -\def\verticalcuts - {\scratchdimen\ruledheight - \advance\scratchdimen \ruleddepth - \normalvbox to \scratchdimen - {\hsize\cutmarklength - \dorecurse\verticalcutmarks - {\vrule\!!height\boxrulewidth\!!width\hsize\normalvfill}% - \unskip}} - -\def\baselinecuts - {\ifdim\ruleddepth>\zeropoint - \scratchdimen\ruledheight - \advance\scratchdimen \ruleddepth - \normalvbox to \scratchdimen - {\scratchdimen\cutmarklength - \divide\scratchdimen 2 - \hsize\scratchdimen - \normalvskip\zeropoint\!!plus\ruledheight - \vrule\!!height\boxrulewidth\!!width\hsize - \normalvskip\zeropoint\!!plus\ruleddepth}% - \fi} - -\def\cutmarksymbols#1% - {\normalhbox to \ruledwidth - {\setbox\scratchbox\normalhbox to \cutmarklength - {\normalhss\infofont\cutmarksymbol\normalhss}% - \normalhss - \normalvbox to \cutmarklength - {\scratchdimen\cutmarklength - \divide\scratchdimen \plustwo - \normalvss - \hbox to \ruledwidth - {\llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% - \normalhskip\scratchdimen\hss\infofont#1\hss\normalhskip\scratchdimen - \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% - \normalvss}% - \normalhss}} - -\def\makecutbox#1% simplier with layers, todo - {\edef\ruledheight{\the\ht#1}% - \edef\ruleddepth {\the\dp#1}% - \edef\ruledwidth {\the\wd#1}% - \setbox#1\normalhbox - {\dontcomplain - \forgetall - \boxmaxdepth\maxdimen - \offinterlineskip - \scratchdimen\cutmarklength - \divide\scratchdimen \plustwo - \hsize\ruledwidth - \setbox\scratchbox\normalvbox - {\setbox\scratchbox\normalhbox{\horizontalcuts}% - \normalvskip-\cutmarkoffset\scratchdimen - \normalvskip-2\scratchdimen - \copy\scratchbox - \normalvskip\cutmarkoffset\scratchdimen - \hbox to \ruledwidth - {\setbox\scratchbox\normalhbox{\verticalcuts}% - \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% - \bgroup - \setbox\scratchbox\normalhbox{\baselinecuts}% - \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% - \normalhfill - \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}% - \egroup - \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% - \normalvskip\cutmarkoffset\scratchdimen - \copy\scratchbox}% - \ht\scratchbox\ruledheight - \dp\scratchbox\ruleddepth - \wd\scratchbox\zeropoint - \resetcolorseparation - \localstartcolor[\defaulttextcolor]% - \box\scratchbox - \ifx\cutmarksymbol\relax \else - \setbox\scratchbox\normalvbox - {\vskip-\cutmarkoffset\scratchdimen - \vskip-\cutmarklength - \normalhbox{\cutmarksymbols\cutmarktoptext}% - \vskip\cutmarkoffset\scratchdimen - \vskip\ruledheight - \vskip\ruleddepth - \vskip\cutmarkoffset\scratchdimen - \normalhbox{\cutmarksymbols\cutmarkbottomtext}}% - \ht\scratchbox\ruledheight - \dp\scratchbox\ruleddepth - \wd\scratchbox\zeropoint - \box\scratchbox - \fi - \localstopcolor - \box#1}% - \wd#1=\ruledwidth - \ht#1=\ruledheight - \dp#1=\ruleddepth} - -\def\cuthbox - {\normalhbox\bgroup - \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalhbox} - -\def\cutvbox - {\normalvbox\bgroup - \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvbox} - -\def\cutvtop - {\normalvtop\bgroup - \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvtop} - -%D \macros -%D {colormarkbox,rastermarkbox} -%D -%D This macro is used in the pagebody routine. No other use -%D is advocated here. -%D -%D \starttyping -%D \colormarkbox0 -%D \stoptyping - -\def\colormarkoffset{\cutmarkoffset} -\def\colormarklength{\cutmarklength} - -\def\colorrangeA#1#2#3#4% - {\vbox - {\scratchdimen-\colormarklength - \multiply\scratchdimen 4 - \advance\scratchdimen \ruledheight - \advance\scratchdimen \ruleddepth - \divide\scratchdimen 21 - \def\docommand##1% - {\vbox - {\hsize3em % \scratchdimen - \definecolor - [\s!dummy] - [\c!c=#2##1\else0\fi, - \c!m=#3##1\else0\fi, - \c!y=#4##1\else0\fi, - \c!k=0]% - \localstartcolor[\s!dummy]% - \hrule - \!!width 3em - \!!height \scratchdimen - \!!depth \zeropoint - \localstopcolor - \ifdim\scratchdimen>1ex - \vskip-\scratchdimen - \vbox to \scratchdimen - {\vss - \hbox to 3em - {\hss - \localstartcolor[\s!white]% - \ifdim##1\points=\zeropoint#1\else##1\fi - \localstopcolor - \hss}% - \vss}% - \fi}}% - \offinterlineskip - \processcommalist[1.00,0.95,0.75,0.50,0.25,0.05,0.00]\docommand}} - -\def\colorrangeB - {\hbox - {\scratchdimen-\colormarklength - \multiply\scratchdimen \plustwo - \advance\scratchdimen \ruledwidth - \divide\scratchdimen 11 - \def\docommand ##1 ##2 ##3##4##5##6% - {\definecolor - [\s!dummy] - [\c!c=##3##2\else0\fi, - \c!m=##4##2\else0\fi, - \c!y=##5##2\else0\fi, - \c!k=##6##2\else0\fi]% - \localstartcolor[\s!dummy]% - \vrule - \!!width \scratchdimen - \!!height \colormarklength - \!!depth \zeropoint - \localstopcolor - \ifdim\scratchdimen>2em - \hskip-\scratchdimen - \vbox to \colormarklength - {\vss - \hbox to \scratchdimen - {\hss - \localstartcolor[\s!white]% - \ifdim##2\points=.5\points##2~\fi##1% - \localstopcolor - \hss} - \vss}% - \fi}% - \docommand C .5 \iftrue \iffalse\iffalse\iffalse - \docommand M .5 \iffalse\iftrue \iffalse\iffalse - \docommand Y .5 \iffalse\iffalse\iftrue \iffalse - \docommand K .5 \iffalse\iffalse\iffalse\iftrue - \docommand C 1 \iftrue \iffalse\iffalse\iffalse - \docommand G 1 \iftrue \iffalse\iftrue \iffalse - \docommand Y 1 \iffalse\iffalse\iftrue \iffalse - \docommand R 1 \iffalse\iftrue \iftrue \iffalse - \docommand M 1 \iffalse\iftrue \iffalse\iffalse - \docommand B 1 \iftrue \iftrue \iffalse\iffalse - \docommand K 1 \iffalse\iffalse\iffalse\iftrue}} - -\def\colorrangeC - {\hbox - {\resetcolorseparation - \scratchdimen-\colormarklength - \multiply\scratchdimen 2 - \advance\scratchdimen \ruledwidth - \divide\scratchdimen 14 - \def\docommand##1% - {\definecolor[\s!dummy][\c!s=##1]% - \localstartcolor[\s!dummy]% - \vrule - \!!width \scratchdimen - \!!height \colormarklength - \!!depth \zeropoint - \localstopcolor - \ifdim\scratchdimen>2em - \hskip-\scratchdimen - \vbox to \colormarklength - {\vss - \localstartcolor[\s!white]% - \hbox to \scratchdimen{\hss##1\hss} - \localstopcolor - \vss}% - \fi}% - \processcommalist[1,.95,.9,.85,.8,.75,.7,.6,.5,.4,.3,.2,.1,0]\docommand}} - -\def\docolormarkbox#1#2% - {\edef\ruledheight{\the\ht#2}% - \edef\ruleddepth {\the\dp#2}% - \edef\ruledwidth {\the\wd#2}% - \setbox#2\hbox - {\scratchdimen\colormarklength - \divide\scratchdimen \plustwo - \forgetall - \ssxx - \setbox\scratchbox\vbox - {\offinterlineskip - \vskip-\colormarkoffset\scratchdimen - \vskip-2\scratchdimen\relax % relax needed - % beware: no \ifcase, due to nested \iftrue/\iffalse - % and lacking \fi's - \doifelse{#1}{0}% - {\vskip\colormarklength - \vskip\colormarkoffset\scratchdimen - \vskip\ruledheight} - {\hbox to \ruledwidth{\hss\hbox{\colorrangeB}\hss}% - \vskip\colormarkoffset\scratchdimen - \vbox to \ruledheight - {\vss - \hbox to \ruledwidth - {\llap{\colorrangeA C\iftrue\iffalse\iffalse\hskip\colormarkoffset\scratchdimen}% - \hfill - \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA R\iffalse\iftrue\iftrue}}% - \vss - \hbox to \ruledwidth - {\llap{\colorrangeA M\iffalse\iftrue\iffalse\hskip\colormarkoffset\scratchdimen}% - \hfill - \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA G\iftrue\iffalse\iftrue}}% - \vss - \hbox to \ruledwidth - {\llap{\colorrangeA Y\iffalse\iffalse\iftrue\hskip\colormarkoffset\scratchdimen}% - \hfill - \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA B\iftrue\iftrue\iffalse}}% - \vss}}% - \vskip\colormarkoffset\scratchdimen - \hbox to \ruledwidth - {\hss\lower\ruleddepth\hbox{\colorrangeC}\hss}}% - \ht\scratchbox\ruledheight - \dp\scratchbox\ruleddepth - \wd\scratchbox\zeropoint - \box\scratchbox - \box#2}% - \wd#2=\ruledwidth - \ht#2=\ruledheight - \dp#2=\ruleddepth} - -\def\colormarkbox % #1 - {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi1} - -\def\rastermarkbox % #1 - {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi0} - -%D \macros -%D {showwhatsits, dontshowwhatsits} -%D -%D \TEX\ has three so called whatsits: \type {\mark}, \type -%D {\write} and \type {\special}. The first one keeps track of -%D the current state at page boundaries, the last two are used -%D to communicate to the outside world. Due to fact that -%D especially \type {\write} is often used in conjunction with -%D \type {\edef}, we can only savely support that one in \ETEX. -%D -%D \bgroup \showwhatsits \setupcolors[state=start] -%D -%D Whatsits show up \color[blue]{in color} and are -%D characterized bij their first character.\footnote [some note] -%D {So we may encounter \type {w}, \type {m} and \type{s}.} -%D They are \writestatus{dummy}{demo}\color[yellow]{stacked}. -%D -%D \egroup - -\newif\ifimmediatewrite - -\ifx\eTeXversion\undefined - - \let\showwhatsits \relax - \let\dontshowwhatsits\relax - -\else - - \let\supernormalmark \normalmark % mark may already been superseded - \let\supernormalmarks \normalmarks % mark may already been superseded - - \def\showwhatsits - {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }% - \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% - \protected\def\special {\visualwhatsit0100s\normalspecial }% - \protected\def\write {\visualwhatsit001-w\normalwrite }% - \let\immediate\immediatewhatsit - \appendtoks\dontshowwhatsits\to\everystoptext} - - \def\immediatewhatsit - {\bgroup\futurelet\next\doimmediatewhatsit} - - \def\doimmediatewhatsit - {\ifx\next\write - \egroup\immediatewritetrue - \else - \egroup\expandafter\normalimmediate - \fi} - - \def\dontshowwhatsits - {\let\immediate \normalimmediate - \let\normalmark\supernormalmark - \let\special \normalspecial - \let\write \normalwrite} - - \def\visualwhatsit#1#2#3#4#5% - {\bgroup - \pushwhatsit - \dontinterfere - \dontcomplain - \dontshowcomposition - \dontshowwhatsits - \ttx - \ifvmode\donetrue\else\donefalse\fi - \setbox\scratchbox\hbox - {\ifdone\dostartgraycolormode0\else\dostartrgbcolormode#1#2#3\fi - #5\dostopcolormode}% - \setbox\scratchbox\hbox - {\ifdone\dostartrgbcolormode#1#2#3\else\dostartgraycolormode0\fi - \vrule\!!width\wd\scratchbox\dostopcolormode - \hskip-\wd\scratchbox\box\scratchbox}% - \scratchdimen1ex - \setbox\scratchbox\hbox - {\ifdone\hskip\else\raise#4\fi\scratchdimen\box\scratchbox}% - \smashbox\scratchbox - \ifdone\nointerlineskip\fi - \box\scratchbox - \ifvmode\nointerlineskip\fi - \popwhatsit - \egroup - \ifimmediatewrite - \immediatewritefalse - \expandafter\normalimmediate - \fi} - - \def\pushwhatsit - {\ifzeropt\lastskip - \ifcase\lastpenalty - \ifzeropt\lastkern - \ifhmode - \let\popwhatsit\relax - \else - \edef\popwhatsit{\prevdepth\the\prevdepth}% - \fi - \else - \ifhmode - \edef\popwhatsit{\kern\the\lastkern}\unkern - \else - \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth}% - \kern-\lastkern - \fi - \fi - \else - \ifhmode - \edef\popwhatsit{\the\lastpenalty}% - \unpenalty - \else - \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}% - %\nobreak - \fi - \fi - \else - \ifhmode - \edef\popwhatsit{\hskip\the\lastskip}\unskip - \else - \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth}% - \vskip-\lastskip - \fi - \fi} - -\fi - -%D The next macro can be used to keep track of classes of -%D boxes (handy for development cq.\ tracing). - -\def\dodotagbox#1#2#3% can be reimplemented - {\def\next##1##2##3##4% - {\vbox to \ht#2{##3\hbox to \wd#2{##1#3##2}##4}}% - \processaction - [#1] - [ l=>\next\relax\hfill\vfill\vfill, - r=>\next\hfill\relax\vfill\vfill, - t=>\next\hfill\hfill\relax\vfill, - b=>\next\hfill\hfill\vfill\relax, - lt=>\next\relax\hfill\relax\vfill, - lb=>\next\relax\hfill\vfill\relax, - rt=>\next\hfill\relax\relax\vfill, - rb=>\next\hfill\relax\vfill\relax, - tl=>\next\relax\hfill\relax\vfill, - bl=>\next\relax\hfill\vfill\relax, - tr=>\next\hfill\relax\relax\vfill, - br=>\next\hfill\relax\vfill\relax, - \s!default=>\next\hfill\hfill\vfill\vfill, - \s!unknown=>\next\hfill\hfill\vfill\vfill]} - -\def\dotagbox[#1]#2% - {\bgroup - \dowithnextbox - {\setbox\scratchbox\flushnextbox - \setbox\nextbox\ifhbox\nextbox\hbox\else\vbox\fi - \bgroup - \startoverlay - {\copy\scratchbox} - {\dodotagbox{#1}\scratchbox{\framed - [\c!background=\v!screen,\c!backgroundscreen=1]{#2}}} - \stopoverlay - \egroup - \nextboxwd\the\wd\scratchbox - \nextboxht\the\ht\scratchbox - \nextboxdp\the\dp\scratchbox - \flushnextbox - \egroup}} - -\def\tagbox - {\dosingleempty\dotagbox} - -%D \macros -%D {coloredhbox,coloredvbox,coloredvtop, -%D coloredstrut} -%D -%D The following visualizations are used in some of the manuals: - -\definecolor[boxcolor:ht][r=.5,g=.75,b=.5] -\definecolor[boxcolor:dp][r=.5,g=.5,b=.75] -\definecolor[boxcolor:wd][r=.75,g=.5,b=.5] -\definecolor[strutcolor] [r=.5,g=.25,b=.25] - -\def\coloredbox#1% - {\dowithnextbox{#1{\hbox - {\blackrule[\c!width=\nextboxwd,\c!height=\nextboxht,\c!depth=\zeropoint,\c!color=boxcolor:ht]% - \hskip-\nextboxwd - \blackrule[\c!width=\nextboxwd,\c!height=\zeropoint,\c!depth=\nextboxdp,\c!color=boxcolor:dp]% - \hskip-\nextboxwd - \box\nextbox}}}#1} - -\def\coloredhbox{\coloredbox\hbox} -\def\coloredvbox{\coloredbox\vbox} -\def\coloredvtop{\coloredbox\vtop} - -\def\coloredstrut - {\color[strutcolor]{\def\strutwidth{2\points}\setstrut\strut}} - -\protect \endinput diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 113f90470..d23a8a080 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -1897,7 +1897,7 @@ function fonts.methods.node.otf.features(head,font,attr) end ra[s] = r end -featurevalue = r and r[1] -- toto: pass to function instead + 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 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..c7f990af2 --- /dev/null +++ b/tex/context/base/grph-fig.mkiv @@ -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-inc.lua b/tex/context/base/grph-inc.lua new file mode 100644 index 000000000..2729389eb --- /dev/null +++ b/tex/context/base/grph-inc.lua @@ -0,0 +1,854 @@ +if not modules then modules = { } end modules ['grph-inc'] = { + version = 1.001, + comment = "companion to grph-inc.tex", + 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 + +--[[ +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 texsprint, format, lower = tex.sprint, string.format, string.lower + +local ctxcatcodes = tex.ctxcatcodes + +local trace_figures = false trackers.register("figures.locating",function(v) trace_figures = 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 = size:gsub("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.boxid 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", "mov", "buffer", "tex" +} + +figures.formats = { + ["pdf"] = { }, + ["mps"] = { patterns = { "%d+" } }, + ["jpg"] = { list = { "jpg", "jpeg" } }, + ["png"] = { } , + ["jbig"] = { list = { "jbig", "jbig2", "jb2" } }, + ["svg"] = { list = { "svg", "svgz" } }, + ["eps"] = { list = { "eps", "ai" } }, + ["mov"] = { list = { "mov", "avi" } }, + ["buffer"] = { list = { "tmp", "buffer", "buf" } }, + ["tex"] = { }, +} + +function figures.setlookups() + figures.suffixes, figures.patterns = { }, { } + for _, format in pairs(figures.order) do + local data = figures.formats[format] + local fs, fp = figures.suffixes, figures.patterns + if data.list then + for _, s in ipairs(data.list) do + fs[s] = format -- hash + end + else + fs[format] = format + end + if data.patterns then + for _, s in ipairs(data.patterns) do + fp[#fp+1] = { s, format } -- array + end + end + end +end + +figures.setlookups() + +local function register(tag,target,what) + local data = figures.formats[target] + if data then + local d = data[tag] + if d and not table.contains(d,what) then + d[#d+1] = what + else + data[tag] = { what } + end + else + figures.formats[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 pathlist:gmatch("([^, ]+)") do + if not table.contains(t,s) then + t[#t+1] = s + end + end + end + figures.paths, last_pathlist = t, pathlist + if trace_figures then + logs.report("figures","locations: %s",last_locationset) + logs.report("figures","path list: %s",table.concat(figures.paths)) + end +end + +-- check conversions and handle it here + +--~ local keys = img.keys() + +--~ function figures.hash(data) +--~ local i = data.status.private +--~ local t = { } +--~ for _, v in ipairs(keys) do +--~ local iv = i[v] +--~ if iv then +--~ t[#t+1] = v .. '=' .. iv +--~ end +--~ end +--~ return table.concat(t,"+") +--~ end + +function figures.hash(data) + return tostring(data.status.private) -- the +-- 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) + statistics.starttiming(figures) + 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] == "yes" + request["repeat"] = iv[request["repeat"]] == "yes" + request.preview = iv[request.preview] == "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[#callstack+1] = figuredata + return figuredata + end + function figures.pop() + figuredata = callstack[#callstack] + callstack[#callstack] = nil + statistics.stoptiming(figures) + end + -- maybe move texsprint to tex + function figures.get(category,tag,default) + local value = figuredata[category][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 function register(askedname,specification) + if specification then + local format = specification.format + if format then + local converter = figures.converters[format] + if converter then + local oldname = specification.fullname + local newformat = "pdf" -- todo, other target than pdf + local newpath = file.dirname(oldname) + local newbase = file.replacesuffix(file.basename(oldname),newformat) + local fc = specification.cache or figures.cachepaths.path + if fc and fc ~= "" and fc ~= "." then + newpath = fc + end + local subpath = specification.subpath or figures.cachepaths.subpath + if subpath and subpath ~= "" and subpath ~= "." then + newpath = newpath .. "/" .. subpath + end + local prefix = specification.prefix or figures.cachepaths.prefix + if prefix and prefix ~= "" then + newbase = prefix .. newbase + end + local newname = file.join(newpath,newbase) + dir.makedirs(newpath) + local oldtime = lfs.attributes(oldname,'modification') or 0 + local newtime = lfs.attributes(newname,'modification') or 0 + if oldtime > newtime then + converter(oldname,newname) + end + if io.exists(newname) then + specification.foundname = oldname + specification.fullname = newname + specification.prefix = prefix + specification.subpath = subpath + specification.converted = true + format = newformat + elseif io.exists(oldname) then + specification.fullname = newname + specification.converted = false + end + end + end + local found = figures.suffixes[format] -- validtypes[format] + if not found then + specification.found = false + if trace_figures then + logs.report("figures","format not supported: %s",format) + end + else + specification.found = true + if trace_figures then + if validtypes[format] then + logs.report("figures","format natively supported by backend: %s",format) + else + logs.report("figures","format supported by output file format: %s",format) + end + end + end + else + specification = { } + end + specification.foundname = specification.foundname or specification.fullname + figures.found[askedname] = specification + return specification +end + +local function locate(request) -- name, format, cache + local askedname = resolvers.clean_path(request.name) + if figures.found[askedname] then + return figures.found[askedname] + end + local askedpath= file.dirname(askedname) + local askedbase = file.basename(askedname) + local askedformat = (request.format ~= "" and request.format ~= "unknown" and request.format) or file.extname(askedname) or "" + local askedcache = request.cache + if askedformat ~= "" then + askedformat = lower(askedformat) + local format = figures.suffixes[askedformat] + if not format then + for _, pattern in ipairs(figures.patterns) do + if askedformat:find(pattern[1]) then + format = pattern[2] + break + end + end + end + if format then + local foundname = figures.exists(askedname,askedformat) + if foundname then + return register(askedname, { + askedname = askedname, + fullname = askedname, + format = format, + cache = askedcache, + foundname = foundname, + }) + end + end + if askedpath ~= "" then + -- path and type given, todo: strip pieces of path + if figures.exists(askedname,askedformat) then + return register(askedname, { + askedname = askedname, + fullname = askedname, + format = askedformat, + cache = askedcache, + }) + end + else + -- type given + for _, path in ipairs(figures.paths) do + local check = path .. "/" .. askedname + if figures.exists(check,askedformat) then + return register(check, { + askedname = askedname, + fullname = check, + format = askedformat, + cache = askedcache, + }) + 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, + }) + end + end + end + elseif askedpath ~= "" then + for _, format in ipairs(figures.order) do + local list = figures.formats[format].list or { format } + for _, suffix in ipairs(list) do + local check = file.addsuffix(askedname,suffix) + if figures.exists(check,format) then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + }) + end + end + end + else + if figures.prefer_quality then + for _, format in ipairs(figures.order) do + local list = figures.formats[format].list or { format } + for _, suffix in ipairs(list) do + local name = file.replacesuffix(askedbase,suffix) + for _, path in ipairs(figures.paths) do + local check = path .. "/" .. name + if figures.exists(check,format) then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + }) + end + end + end + end + else -- 'location' + for _, path in ipairs(figures.paths) do + for _, format in ipairs(figures.order) do + local list = figures.formats[format].list or { format } + for _, suffix in ipairs(list) do + local check = path .. "/" .. file.replacesuffix(askedbase,suffix) + if figures.exists(check,format) then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + }) + end + end + end + end + end + if figures.defaultsearch then + for _, format in ipairs(figures.order) do + local list = figures.formats[format].list or { format } + for _, suffix in ipairs(list) do + local check = resolvers.find_file(file.replacesuffix(askedname,suffix)) + if check and check ~= "" then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + }) + end + end + end + end + end + return register(askedname) +end + +-- -- -- plugins -- -- -- + +figures.existers = figures.existers or { } +figures.checkers = figures.checkers or { } +figures.includers = figures.includers or { } +figures.converters = figures.converters or { } +figures.identifiers = figures.identifiers or { } + +figures.identifiers.list = { + figures.identifiers.default +} + +function figures.identifiers.default(data) + local dr, du, ds = data.request, data.used, data.status + local l = locate(dr) + local foundname = l.foundname + local fullname = l.fullname or foundname + if fullname then + du.format = l.format or false + du.fullname = fullname -- can be cached + ds.fullname = foundname -- original + ds.format = l.format + ds.status = (l.found and 10) or 0 + end + return data +end + +function figures.identify(data) + data = data or figures.current() + for _, identifier in ipairs(figures.identifiers.list) do + data = identifier(data) + if data.status.status > 0 then + break + end + end + return data +end +function figures.exists(askedname,format) + return (figures.existers[format] or figures.existers.generic)(askedname) +end +function figures.check(data) + data = data or figures.current() + local dr, du, ds = data.request, data.used, data.status + return (figures.checkers[ds.format] or figures.checkers.generic)(data) +end +function figures.include(data) + data = data or figures.current() + local dr, du, ds = data.request, data.used, data.status + return (figures.includers[ds.format] or figures.includers.generic)(data) +end +function figures.scale(data) -- will become lua code + texsprint(ctxcatcodes,"\\doscalefigure") + return data +end +function figures.done(data) + figures.n = figures.n + 1 + data = data or figures.current() + local dr, du, ds = data.request, data.used, data.status + ds.width = tex.wd[figures.boxnumber] + ds.height = tex.ht[figures.boxnumber] + ds.xscale = ds.width/(du.width or 1) + ds.yscale = ds.height/(du.height or 1) + return data +end + +function figures.dummy(data) -- fails +--~ data = data or figures.current() +--~ local dr, du, ds = data.request, data.used, data.status +--~ local r = node.new("rule") +--~ r.width = du.width or figures.defaultwidth +--~ r.height = du.height or figures.defaultheight +--~ r.depth = du.depth or figures.defaultdepth +--~ tex.box[figures.boxnumber] = node.write(r) + texsprint(ctxcatcodes,"\\emptyfoundexternalfigure") +end + +-- -- -- generic -- -- -- + +function figures.existers.generic(askedname) +--~ local result = io.exists(askedname) +--~ result = (result==true and askedname) or result +--~ local result = resolvers.find_file(askedname) or "" + local result = resolvers.findbinfile(askedname) or "" + if result == "" then result = false end + if trace_figures then + if result then + logs.report("figures","found: %s -> %s",askedname,result) + else + logs.report("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 = du.fullname or "unknown generic", du.page or dr.page, dr.size or "crop" + local hash = name .. "->" .. page .. "->" .. size + local figure = figures.loaded[hash] + if figure == nil then + figure = img.new { filename = name, page = page, pagebox = dr.size } + figure = (figure and img.scan(figure)) or false + figures.loaded[hash] = figure + end + if figure then + du.width = figure.width + du.height = figure.height + du.pages = figure.pages + ds.private = figure + 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.page = dr.page or '1' + figure = img.copy(figure) + figure = (figure and img.clone(figure,data.request)) or false + end + figures.used[hash] = figure + end + if figure then + local n = figures.boxnumber + tex.box[n] = img.node(figure) -- img.write(figure) + tex.wd[n], tex.ht[n], tex.dp[n] = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) + ds.objectnumber = figure.objnum + texsprint(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 + dr.width = (dr.width or figures.defaultwidth):todimen() + dr.height = (dr.height or figures.defaultheight):todimen() + du.width = dr.width + du.height = dr.height + du.foundname = du.fullname + local code = backends.codeinjections { + width = du.width or dr.width, + height = du.height or dr.height, + factor = number.dimenfactors.bp, + ["repeat"] = dr["repeat"], + controls = dr.controls, + preview = dr.preview, + label = dr.label, + foundname = du.foundname, + } + texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}%s\\stopfoundexternalfigure",du.width,du.height,code)) + return data +end + +figures.includers.mov = figures.includers.nongeneric + +-- -- -- mps -- -- -- + +function figures.checkers.mps(data) + return figures.checkers.nongeneric(data,format("\\docheckfiguremps{%s}",data.used.fullname)) +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 + +-- -- -- eps -- -- -- + +function figures.converters.eps(oldname,newname) + -- hack, we need a lua based converter script, or better, we should use + -- rlx as alternative + local outputpath = file.dirname(newname) + local outputbase = file.basename(newname) + local command = format("mtxrun bin:pstopdf --outputpath=%s %s",outputpath,oldname) + os.spawn(command) +end + +figures.converters.svg = figures.converters.eps + +-- -- -- lowres -- -- -- + +--~ function figures.converters.pdf(oldname,newname) +--~ local outputpath = file.dirname(newname) +--~ local outputbase = file.basename(newname) +--~ local command = format("mtxrun bin:pstopdf --method=4 --outputpath=%s %s",outputpath,oldname) +--~ os.spawn(command) +--~ end + +figures.bases = { } +figures.bases.list = { } -- index => { basename, fullname, xmlroot } +figures.bases.used = { } -- [basename] => { basename, fullname, xmlroot } -- pointer to list +figures.bases.found = { } +figures.bases.enabled = false + +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 + end + end +end + +function bases.find(basename,askedlabel) + 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 + for _, path in ipairs(figures.paths) do + local xmlfile = path .. "/" .. basename + if io.exists(xmlfile) then + base[2] = xmlfile + base[3] = xml.load(xmlfile) + break + end + end + end + t = false + if base[2] and base[3] then -- rlx:library + for e, d, k in xml.elements(base[3],"/(*:library|figurelibrary)/*:figure/*:label") do + page = page + 1 + if xml.content(d[k]) == askedlabel then + t = { + base = file.replacesuffix(base[2],"pdf"), + format = "pdf", + name = xml.filters.text(e,"*:file"), + page = page, + } + bases.found[askedlabel] = t + return t + end + end + end + end + return t +end + +-- we can access sequential or by name + +function bases.locate(askedlabel) + for _, entry in ipairs(bases.list) do + 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..231ce902e --- /dev/null +++ b/tex/context/base/grph-inc.mkii @@ -0,0 +1,1215 @@ +%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 + +%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! + {\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]}}% + \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]% + \ifcase\figurewidth + \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} + +\protect \endinput diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv new file mode 100644 index 000000000..e55e9698a --- /dev/null +++ b/tex/context/base/grph-inc.mkiv @@ -0,0 +1,417 @@ +%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 - color separation +%D - alternative images +%D - a few more obscure things + +\registerctxluafile{grph-inc}{1.001} + +\unprotect + +%D The following registers are used (if only to be downward compatible). + +\newbox \foundexternalfigure +\newif \iftraceexternalfigures +\newif \ifskipexternalfigures +\newtoks \everyexternalfigureresets +\newtoks \everyexternalfigurechecks +\newtoks \externalfigurepostprocessors +\chardef \splitexternalfigure \zerocount % 0 nosplit 1 split/yes 2 split/no + +\let\traceexternalfigures \traceexternalfigurestrue + +\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 + +\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","\@@exdirectory")}} + +%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.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}% + % 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} + +\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\doscalefigure + {\global\setbox\foundexternalfigure\vbox{\doscalebox\??ef{\dowithfigure{\box\foundexternalfigure}}}} + +\newconditional\testexternalfigureonly + +\def\calculateexternalfigure[#1][#2][#3][#4][#5][#6]% \cmd label filename parent_id preset current + {\dontcomplain + \restorecatcodes + \forgetall + \resetfigurevariables + \dosetefparameters{#4}{#5}{#6}% + \checkfigurevariables + \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", + ["repeat"]="\@@efrepeat", + width="\@@efwidth", % can be crap + height="\@@efheight", % can be crap + } }% + \ctxlua{figures.identify()}% + \ifconditional\testexternalfigureonly + \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 + {\ifcase\figurestatus + \resetsystemmode\v!figure % todo, also: \v!resource + \else + \setsystemmode \v!figure % todo, also: \v!resource + \fi} + +\def\startfoundexternalfigure#1#2% + {\global\setbox\foundexternalfigure\vbox to #2\bgroup\vss\hbox to #1\bgroup} + +\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\ifnum\splitexternalfigure=\plustwo\else + \the\externalfigurepostprocessors + \box\foundexternalfigure + \fi\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\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}} + +\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethreearguments\fi +\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethreearguments\fi + +\let\feedbackexternalfigure\relax % \gobblefourarguments +\let\dowithfigure \relax + +% \let\lastfigureobjectname\empty + +\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]% + {\startnointerference + \testexternalfigureonly + \externalfigure[#1][#2,\c!display=,\c!object=\v!no]% + \stopnointerference} + +\let\getfiguredimensionsonly\getfiguredimensions + +\def\doiffigureelse#1% + {\getfiguredimensions[#1]% + \ifcase\figurewidth % 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 diff --git a/tex/context/base/grph-trf.mkii b/tex/context/base/grph-trf.mkii new file mode 100644 index 000000000..798a9b0b4 --- /dev/null +++ b/tex/context/base/grph-trf.mkii @@ -0,0 +1,577 @@ +%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 + \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} + {\scaleboxoutervsize\scaleparameter\c!maxheight}% + \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..798a9b0b4 --- /dev/null +++ b/tex/context/base/grph-trf.mkiv @@ -0,0 +1,577 @@ +%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 + \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} + {\scaleboxoutervsize\scaleparameter\c!maxheight}% + \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/luat-bas.mkiv b/tex/context/base/luat-bas.mkiv new file mode 100644 index 000000000..a78455173 --- /dev/null +++ b/tex/context/base/luat-bas.mkiv @@ -0,0 +1,64 @@ +%D \module +%D [ file=luat-bas, % moved from luat-lib, +%D version=2006.09.11, +%D title=\CONTEXT\ Lua Macros, +%D subtitle=Basic \LUA\ Libraries, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% \writestatus{loading}{ConTeXt Lua Macros / Basic Lua Libraries} + +%D This will move cq. become configurable. The XML like output is just +%D an example. + +% todo \let\normaleverytoks\everytoks \newtoks\everytoke \normaleverytoks{\the\everytoks} + +\chardef\statuswidth=15 +\chardef\statuswrite=16 + +\newtoks\everywritestring + +\def\writedirect {\immediate\write\statuswrite} +\def\writeline {\writedirect{}} +\def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup} + +\ifx\normalwritestatus\undefined \def\normalwritestatus#1#2{\writedirect{#1 : #2}} \fi + +% Because all libs are also on bytecodes we can start without stub. However, +% some initializations need to take place before the \TEX\ engine itself +% kicks in, especially memory settings and so. In due time we might make the +% stub smaller and just create a configuration startup file. + +\registerctxluafile{l-string} {1.001} +\registerctxluafile{l-lpeg} {1.001} +\registerctxluafile{l-boolean}{1.001} +\registerctxluafile{l-number} {1.001} +\registerctxluafile{l-math} {1.001} +\registerctxluafile{l-table} {1.001} +\registerctxluafile{l-aux} {1.001} +\registerctxluafile{l-io} {1.001} +\registerctxluafile{l-os} {1.001} +\registerctxluafile{l-file} {1.001} +\registerctxluafile{l-md5} {1.001} +\registerctxluafile{l-dir} {1.001} +\registerctxluafile{l-unicode}{1.001} +\registerctxluafile{l-utils} {1.001} +\registerctxluafile{l-dimen} {1.001} +\registerctxluafile{l-url} {1.001} +\registerctxluafile{l-set} {1.001} + +% \registerctxluafile{socket.lua}{} +% \registerctxluafile{ltn12.lua} {} +% \registerctxluafile{mime.lua} {} +% \registerctxluafile{http.lua} {} +% \registerctxluafile{url.lua} {} +% \registerctxluafile{tp.lua} {} +% \registerctxluafile{ftp.lua} {} +% %registerctxluafile{smtp.lua} {} + +\endinput diff --git a/tex/context/base/luat-bas.tex b/tex/context/base/luat-bas.tex deleted file mode 100644 index a78455173..000000000 --- a/tex/context/base/luat-bas.tex +++ /dev/null @@ -1,64 +0,0 @@ -%D \module -%D [ file=luat-bas, % moved from luat-lib, -%D version=2006.09.11, -%D title=\CONTEXT\ Lua Macros, -%D subtitle=Basic \LUA\ Libraries, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% \writestatus{loading}{ConTeXt Lua Macros / Basic Lua Libraries} - -%D This will move cq. become configurable. The XML like output is just -%D an example. - -% todo \let\normaleverytoks\everytoks \newtoks\everytoke \normaleverytoks{\the\everytoks} - -\chardef\statuswidth=15 -\chardef\statuswrite=16 - -\newtoks\everywritestring - -\def\writedirect {\immediate\write\statuswrite} -\def\writeline {\writedirect{}} -\def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup} - -\ifx\normalwritestatus\undefined \def\normalwritestatus#1#2{\writedirect{#1 : #2}} \fi - -% Because all libs are also on bytecodes we can start without stub. However, -% some initializations need to take place before the \TEX\ engine itself -% kicks in, especially memory settings and so. In due time we might make the -% stub smaller and just create a configuration startup file. - -\registerctxluafile{l-string} {1.001} -\registerctxluafile{l-lpeg} {1.001} -\registerctxluafile{l-boolean}{1.001} -\registerctxluafile{l-number} {1.001} -\registerctxluafile{l-math} {1.001} -\registerctxluafile{l-table} {1.001} -\registerctxluafile{l-aux} {1.001} -\registerctxluafile{l-io} {1.001} -\registerctxluafile{l-os} {1.001} -\registerctxluafile{l-file} {1.001} -\registerctxluafile{l-md5} {1.001} -\registerctxluafile{l-dir} {1.001} -\registerctxluafile{l-unicode}{1.001} -\registerctxluafile{l-utils} {1.001} -\registerctxluafile{l-dimen} {1.001} -\registerctxluafile{l-url} {1.001} -\registerctxluafile{l-set} {1.001} - -% \registerctxluafile{socket.lua}{} -% \registerctxluafile{ltn12.lua} {} -% \registerctxluafile{mime.lua} {} -% \registerctxluafile{http.lua} {} -% \registerctxluafile{url.lua} {} -% \registerctxluafile{tp.lua} {} -% \registerctxluafile{ftp.lua} {} -% %registerctxluafile{smtp.lua} {} - -\endinput diff --git a/tex/context/base/luat-cod.mkiv b/tex/context/base/luat-cod.mkiv new file mode 100644 index 000000000..07db36483 --- /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. + +\long\def\startruntimeluacode#1\stopruntimeluacode % only simple code (load +init) + {\ifproductionrun + \global\let\startruntimeluacode\relax + \global\let\stopruntimeluacode \relax + \else + \global\everyloadluacode\expandafter{\the\everyloadluacode#1}% + \fi + #1} % maybe no interference + +\long\def\startruntimectxluacode#1\stopruntimectxluacode + {\startruntimeluacode\ctxlua{#1}\stopruntimeluacode} + +%D Next we load the initialization code. + +\startruntimectxluacode + environment = environment or { } + environment.jobname = "\jobname" % tex.jobname + environment.initex = \ifproductionrun false \else true \fi % tex.formatname == "" + environment.version = "\fmtversion" +\stopruntimectxluacode + +% we start at 500, below this, we store predefined data (dumps) + +\newcount\luabytecodecounter \luabytecodecounter=500 + +\startruntimectxluacode + lua.bytedata = lua.bytedata or { } +\stopruntimectxluacode + +%D Handy when we expand: + +\let\stopruntimeluacode \relax +\let\stopruntimectxluacode\relax + +\long\def\lastexpanded{} % todo: elsewhere we use \@@expanded + +\long\def\expanded#1{\long\xdef\lastexpanded{\noexpand#1}\lastexpanded} + +%D More code: + +% \def\ctxluabytecode#1% executes an already loaded chunk +% {\ctxlua { +% local str = '' +% if lua.bytedata[#1] then +% str = " from file " .. lua.bytedata[#1][1] .. " version " .. lua.bytedata[#1][2] +% end +% if lua.bytecode[#1] then +% if environment.initex then +% texio.write_nl("bytecode: executing blob " .. "#1" .. str) +% assert(lua.bytecode[#1])() +% else +% texio.write_nl("bytecode: initializing blob " .. "#1" .. str) +% assert(lua.bytecode[#1])() +% lua.bytecode[#1] = nil +% end +% else +% texio.write_nl("bytecode: invalid blob " .. "#1" .. str) +% end +% }} + +\def\ctxluabytecode#1% executes an already loaded chunk + {\ctxlua { + local lbc = lua.bytecode + if lbc[#1] then + assert(lbc[#1])() + if not environment.initex then + lbc[#1] = nil + end + end + }} + +\def\ctxluabyteload#1#2% registers and compiles chunk + {\global\advance\luabytecodecounter \plusone + \expanded{\startruntimectxluacode + lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" } + \stopruntimectxluacode}% + \ctxlua { + lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" } + lua.bytecode[\the\luabytecodecounter] = environment.luafilechunk("#1") + }} + +\def\ctxloadluafile#1#2% load a (either not compiled) chunk at runtime + {\doifelsenothing{#2} + {\ctxlua{environment.loadluafile("#1")}} + {\ctxlua{environment.loadluafile("#1",#2)}}} + +\def\registerctxluafile#1#2% name version + {\ifproductionrun + \ctxloadluafile{#1}{#2}% + \else + \ctxluabyteload{#1}{#2}% can go away + \fi + \global\everyloadluacode\expandafter\expandafter\expandafter{\expandafter\the\expandafter\everyloadluacode + \expandafter\ctxluabytecode\expandafter{\the\luabytecodecounter}}% + \ctxluabytecode{\the\luabytecodecounter}} + +\everydump\expandafter{\the\everydump\ctxlua{luatex.dumpstate(environment.jobname..".lui",501)}} + +\endinput diff --git a/tex/context/base/luat-cod.tex b/tex/context/base/luat-cod.tex deleted file mode 100644 index 07db36483..000000000 --- a/tex/context/base/luat-cod.tex +++ /dev/null @@ -1,161 +0,0 @@ -%D \module -%D [ file=luat-cod, -%D version=2005.05.26, -%D title=\CONTEXT\ Lua Macros, -%D subtitle=Code, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% \writestatus{loading}{ConTeXt Lua Macros / Code} - -%D Originally we compiled the lua files externally and loaded -%D then at runtime, but when the amount grew, we realized that -%D we needed away to store them in the format, which is what -%D bytecode arrays do. And so the following is obsolete: -%D -%D \starttyping -%D \chardef\ctxluaembeddingmode \plusone -%D -%D 0 = external compilation and loading -%D 1 = runtime compilation and embedding -%D \stoptyping -%D -%D Allocation of \LUA\ engines has changed too. The original idea -%D was to have multiple \LUA\ instances and it worked that way for -%D several years. Hoewver in practice we used only one engine because -%D scripts need to share data anyway. So eventually \LUATEX\ got only -%D one instance. Because each call is reentrant there is not much -%D danger for crashes. - -\def\ctxdirectlua{\directlua\zerocount} -\def\ctxlatelua {\latelua \zerocount} - -%D Take your choice \unknown - -\let\ctxlua \ctxdirectlua -\let\luacode \ctxdirectlua -\let\lateluacode \ctxlatelua -\let\directluacode\ctxdirectlua - -%D Reporting the version of \LUA\ that we use is done as follows: - -\edef\luaversion{\ctxlua{tex.print(_VERSION)}} - -%D We want to define \LUA\ related things in the format but -%D need to reload code because \LUA\ instances themselves are -%D not dumped into the format. - -\newtoks\everyloadluacode -\newtoks\everyfinalizeluacode - -\normaleveryjob{\the\everyloadluacode\the\everyfinalizeluacode\the\everyjob} - -\newif\ifproductionrun - -%D Here we operate in the \TEX\ catcode regime as we haven't yet defined -%D catcode regimes. A chicken or egg problem. - -\long\def\startruntimeluacode#1\stopruntimeluacode % only simple code (load +init) - {\ifproductionrun - \global\let\startruntimeluacode\relax - \global\let\stopruntimeluacode \relax - \else - \global\everyloadluacode\expandafter{\the\everyloadluacode#1}% - \fi - #1} % maybe no interference - -\long\def\startruntimectxluacode#1\stopruntimectxluacode - {\startruntimeluacode\ctxlua{#1}\stopruntimeluacode} - -%D Next we load the initialization code. - -\startruntimectxluacode - environment = environment or { } - environment.jobname = "\jobname" % tex.jobname - environment.initex = \ifproductionrun false \else true \fi % tex.formatname == "" - environment.version = "\fmtversion" -\stopruntimectxluacode - -% we start at 500, below this, we store predefined data (dumps) - -\newcount\luabytecodecounter \luabytecodecounter=500 - -\startruntimectxluacode - lua.bytedata = lua.bytedata or { } -\stopruntimectxluacode - -%D Handy when we expand: - -\let\stopruntimeluacode \relax -\let\stopruntimectxluacode\relax - -\long\def\lastexpanded{} % todo: elsewhere we use \@@expanded - -\long\def\expanded#1{\long\xdef\lastexpanded{\noexpand#1}\lastexpanded} - -%D More code: - -% \def\ctxluabytecode#1% executes an already loaded chunk -% {\ctxlua { -% local str = '' -% if lua.bytedata[#1] then -% str = " from file " .. lua.bytedata[#1][1] .. " version " .. lua.bytedata[#1][2] -% end -% if lua.bytecode[#1] then -% if environment.initex then -% texio.write_nl("bytecode: executing blob " .. "#1" .. str) -% assert(lua.bytecode[#1])() -% else -% texio.write_nl("bytecode: initializing blob " .. "#1" .. str) -% assert(lua.bytecode[#1])() -% lua.bytecode[#1] = nil -% end -% else -% texio.write_nl("bytecode: invalid blob " .. "#1" .. str) -% end -% }} - -\def\ctxluabytecode#1% executes an already loaded chunk - {\ctxlua { - local lbc = lua.bytecode - if lbc[#1] then - assert(lbc[#1])() - if not environment.initex then - lbc[#1] = nil - end - end - }} - -\def\ctxluabyteload#1#2% registers and compiles chunk - {\global\advance\luabytecodecounter \plusone - \expanded{\startruntimectxluacode - lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" } - \stopruntimectxluacode}% - \ctxlua { - lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" } - lua.bytecode[\the\luabytecodecounter] = environment.luafilechunk("#1") - }} - -\def\ctxloadluafile#1#2% load a (either not compiled) chunk at runtime - {\doifelsenothing{#2} - {\ctxlua{environment.loadluafile("#1")}} - {\ctxlua{environment.loadluafile("#1",#2)}}} - -\def\registerctxluafile#1#2% name version - {\ifproductionrun - \ctxloadluafile{#1}{#2}% - \else - \ctxluabyteload{#1}{#2}% can go away - \fi - \global\everyloadluacode\expandafter\expandafter\expandafter{\expandafter\the\expandafter\everyloadluacode - \expandafter\ctxluabytecode\expandafter{\the\luabytecodecounter}}% - \ctxluabytecode{\the\luabytecodecounter}} - -\everydump\expandafter{\the\everydump\ctxlua{luatex.dumpstate(environment.jobname..".lui",501)}} - -\endinput diff --git a/tex/context/base/luat-ini.mkiv b/tex/context/base/luat-ini.mkiv new file mode 100644 index 000000000..265f1b643 --- /dev/null +++ b/tex/context/base/luat-ini.mkiv @@ -0,0 +1,218 @@ +%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}}} + +\def\startlua {\dostartlua } % tex catcodes +\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} + +\ifdefined\closelua + + \def\definenamedlua[#1]#2[#3]% no optional arg handling here yet + {\expanded{\long\def\csname dodostartnamed#1\v!code\endcsname####1\csname\e!stop#1\v!code\endcsname}% + {\normalexpanded{\endgroup\noexpand\directlua\!!name{#3}\zerocount{protect("#1\s!data")##1}}}% + \long\expandafter\def\csname\e!start#1\v!code\endcsname {\dostartnamedluacode{#1}}% + \long\expandafter\def\csname #1\v!code\endcsname##1{\directlua\!!name{#3}\zerocount{protect("#1\s!data")##1}}} + +\else + + \def\definenamedlua[#1]#2[#3]% no optional arg handling here yet + {\scratchcounter\ctxlua{lua.registername("#1","#3")}% + \expanded{\long\edef\csname dodostartnamed#1\v!code\endcsname####1\csname\e!stop#1\v!code\endcsname}% + {\endgroup\noexpand\directlua\the\scratchcounter{protect("#1\s!data")##1}}% + \long\expandafter\def \csname\e!start#1\v!code\endcsname {\dostartnamedluacode{#1}}% + \long\expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{protect("#1\s!data")##1}}} + +\fi + +%D We predefine a few. + +\definenamedlua[user] [private user instance] +\definenamedlua[third] [third party module instance] +\definenamedlua[module] [module instance] +\definenamedlua[isolated][isolated instance] + +%D In practice this works out as follows: +%D +%D \startbuffer +%D \startluacode +%D tex.print("LUA") +%D \stopluacode +%D +%D \startusercode +%D global.tex.print("USER 1") +%D tex.print("USER 2") +%D if characters then +%D tex.print("ACCESS") +%D else +%D tex.print("NO ACCESS") +%D end +%D \stopusercode +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D We need a way to pass strings safely to \LUA\ without the +%D need for tricky escaping. Compare: +%D +%D \starttyping +%D \ctxlua {something("anything tricky can go here")} +%D \ctxlua {something([\luastringsep[anything tricky can go here]\luastringsep])} +%D \stoptyping + +\def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems + +\edef\!!bs{[\luastringsep[} +\edef\!!es{]\luastringsep]} + +%D We have a the following available as primitive so there is no need +%D for it: +%D +%D \starttyping +%D \long\edef\luaescapestring#1{\!!bs#1\!!es} +%D \stoptyping + +\def\setdocumentfilename #1#2{\ctxlua{document.setfilename(#1,"#2")}} +\def\setdocumentargument #1#2{\ctxlua{document.setargument("#1","#2")}} +\def\setdefaultdocumentargument#1#2{\ctxlua{document.getargument("#1","#2")}} +\def\getdocumentfilename #1{\ctxlua{document.getfilename(#1)}} +\def\getdocumentargument #1{\ctxlua{document.getargument(#1)}} +\def\doifdocumentargumentelse #1{\doifsomethingelse{\getdocumentargument{#1}}} +\def\doifdocumentargument #1{\doifsomething {\getdocumentargument{#1}}} +\def\doifnotdocumentargument #1{\doifnothing {\getdocumentargument{#1}}} + +\let\doifelsedocumentargument\doifdocumentargumentelse + +%D A handy helper: + +\def\luaexpanded#1{\luaescapestring\expandafter{\normalexpanded{#1}}} + +\protect \endinput diff --git a/tex/context/base/luat-ini.tex b/tex/context/base/luat-ini.tex deleted file mode 100644 index 265f1b643..000000000 --- a/tex/context/base/luat-ini.tex +++ /dev/null @@ -1,218 +0,0 @@ -%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}}} - -\def\startlua {\dostartlua } % tex catcodes -\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} - -\ifdefined\closelua - - \def\definenamedlua[#1]#2[#3]% no optional arg handling here yet - {\expanded{\long\def\csname dodostartnamed#1\v!code\endcsname####1\csname\e!stop#1\v!code\endcsname}% - {\normalexpanded{\endgroup\noexpand\directlua\!!name{#3}\zerocount{protect("#1\s!data")##1}}}% - \long\expandafter\def\csname\e!start#1\v!code\endcsname {\dostartnamedluacode{#1}}% - \long\expandafter\def\csname #1\v!code\endcsname##1{\directlua\!!name{#3}\zerocount{protect("#1\s!data")##1}}} - -\else - - \def\definenamedlua[#1]#2[#3]% no optional arg handling here yet - {\scratchcounter\ctxlua{lua.registername("#1","#3")}% - \expanded{\long\edef\csname dodostartnamed#1\v!code\endcsname####1\csname\e!stop#1\v!code\endcsname}% - {\endgroup\noexpand\directlua\the\scratchcounter{protect("#1\s!data")##1}}% - \long\expandafter\def \csname\e!start#1\v!code\endcsname {\dostartnamedluacode{#1}}% - \long\expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{protect("#1\s!data")##1}}} - -\fi - -%D We predefine a few. - -\definenamedlua[user] [private user instance] -\definenamedlua[third] [third party module instance] -\definenamedlua[module] [module instance] -\definenamedlua[isolated][isolated instance] - -%D In practice this works out as follows: -%D -%D \startbuffer -%D \startluacode -%D tex.print("LUA") -%D \stopluacode -%D -%D \startusercode -%D global.tex.print("USER 1") -%D tex.print("USER 2") -%D if characters then -%D tex.print("ACCESS") -%D else -%D tex.print("NO ACCESS") -%D end -%D \stopusercode -%D \stopbuffer -%D -%D \typebuffer \getbuffer - -%D We need a way to pass strings safely to \LUA\ without the -%D need for tricky escaping. Compare: -%D -%D \starttyping -%D \ctxlua {something("anything tricky can go here")} -%D \ctxlua {something([\luastringsep[anything tricky can go here]\luastringsep])} -%D \stoptyping - -\def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems - -\edef\!!bs{[\luastringsep[} -\edef\!!es{]\luastringsep]} - -%D We have a the following available as primitive so there is no need -%D for it: -%D -%D \starttyping -%D \long\edef\luaescapestring#1{\!!bs#1\!!es} -%D \stoptyping - -\def\setdocumentfilename #1#2{\ctxlua{document.setfilename(#1,"#2")}} -\def\setdocumentargument #1#2{\ctxlua{document.setargument("#1","#2")}} -\def\setdefaultdocumentargument#1#2{\ctxlua{document.getargument("#1","#2")}} -\def\getdocumentfilename #1{\ctxlua{document.getfilename(#1)}} -\def\getdocumentargument #1{\ctxlua{document.getargument(#1)}} -\def\doifdocumentargumentelse #1{\doifsomethingelse{\getdocumentargument{#1}}} -\def\doifdocumentargument #1{\doifsomething {\getdocumentargument{#1}}} -\def\doifnotdocumentargument #1{\doifnothing {\getdocumentargument{#1}}} - -\let\doifelsedocumentargument\doifdocumentargumentelse - -%D A handy helper: - -\def\luaexpanded#1{\luaescapestring\expandafter{\normalexpanded{#1}}} - -\protect \endinput diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv new file mode 100644 index 000000000..ec781f3cf --- /dev/null +++ b/tex/context/base/luat-lib.mkiv @@ -0,0 +1,65 @@ +%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-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{l-xml} {1.001} % we want tracking + +\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-lib.tex b/tex/context/base/luat-lib.tex deleted file mode 100644 index ec781f3cf..000000000 --- a/tex/context/base/luat-lib.tex +++ /dev/null @@ -1,65 +0,0 @@ -%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-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{l-xml} {1.001} % we want tracking - -\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/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/meta-fig.mkiv b/tex/context/base/meta-fig.mkiv index c2c2e127f..b3abc9d9e 100644 --- a/tex/context/base/meta-fig.mkiv +++ b/tex/context/base/meta-fig.mkiv @@ -75,8 +75,8 @@ \getfiguredimensionsonly[#1]% [\c!object=\v!no] already set \startMPcode externalfigure "#1" - xscaled \figurewidth\space - yscaled \figureheight\space + xscaled \the\dimexpr\figurewidth \relax\space % must be points + yscaled \the\dimexpr\figureheight\relax\space % must be points #2 ; \stopMPcode \egroup} diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index bcd82c4ed..02885e8cc 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -37,6 +37,9 @@ \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. @@ -262,8 +265,8 @@ {\executeifdefined{\@@MPG#1};} % ; if not found \def\enableincludeMPgraphics - {\let\handleuseMPgraphic \secondoftwoarguments - \let\handlereusableMPgraphic\secondoftwoarguments} + {\let\handleuseMPgraphic \thirdofthreearguments + \let\handlereusableMPgraphic\thirdofthreearguments} \let\MPdrawingdata\empty @@ -767,21 +770,14 @@ \def\processMPbuffer {\dosingleempty\doprocessMPbuffer} -% this fails (keep): -% -% \def\doprocessMPbuffer[#1]% -% {\doifelsenothing{#1} -% {\doprocessMPbuffer[\jobname]} -% {\processMPgraphic{\ctxlua{tex.sprint(tex.ctxcatcodes,buffers.collect("#1"))}}}} % "\\n" -% -% this works (keep): -% -% \def\doprocessMPbuffer[#1]% -% {\doifelsenothing{#1} -% {\doprocessMPbuffer[\jobname]} % #1 can be a list of buffers, otherwise we could use: -% {\processMPgraphic{\ctxlua{tex.sprint(tex.ctxcatcodes,unpack(buffers.data["#1"]))}}}} -% -% this we use: +\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 @@ -789,9 +785,10 @@ {\doifelsenothing{#1} {\doprocessMPbuffer[\jobname]} {\beginMPgraphicgroup{#1}% - % we need this trick because tex.sprint does not interprets newlines - \ctxlua{tex.toks.mpbuffertoks=buffers.collect("\currentMPgraphicname")}% - \processMPgraphic{\the\mpbuffertoks}% + % 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 @@ -884,6 +881,25 @@ \let\stopMPcode\relax +% 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 @@ -999,10 +1015,20 @@ \disablecompoundcharacters \to \everyMPgraphic -\appendtoks +\appendtoks % before color \normalexpanded{\noexpand\definecolor[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 @@ -1285,6 +1311,75 @@ \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 + +\appendtoks + \ctxlua{metapost.set_outer_color(\number\MPcolormethod,"\PDFcolor{\currentcolorname}","")}% +\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 + +\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/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-ctx.tex b/tex/context/base/mlib-ctx.tex deleted file mode 100644 index 6f56b7e68..000000000 --- a/tex/context/base/mlib-ctx.tex +++ /dev/null @@ -1,81 +0,0 @@ -%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 index 9c5775a2d..6617e5fc0 100644 --- a/tex/context/base/mlib-pdf.lua +++ b/tex/context/base/mlib-pdf.lua @@ -247,6 +247,7 @@ function metapost.flush(result,flusher) -- pdf flusher, table en dan concat is s 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 @@ -267,7 +268,7 @@ function metapost.flush(result,flusher) -- pdf flusher, table en dan concat is s 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) + 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" diff --git a/tex/context/base/mlib-pdf.mkiv b/tex/context/base/mlib-pdf.mkiv new file mode 100644 index 000000000..92fcb28ae --- /dev/null +++ b/tex/context/base/mlib-pdf.mkiv @@ -0,0 +1,93 @@ +%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} + +% \let\MPLIBtoPDF\pdfliteral + +\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 + \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 + \MPfshowcommand{#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-pdf.tex b/tex/context/base/mlib-pdf.tex deleted file mode 100644 index 9a04d188f..000000000 --- a/tex/context/base/mlib-pdf.tex +++ /dev/null @@ -1,92 +0,0 @@ -%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} - -% \let\MPLIBtoPDF\pdfliteral - -\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 - \MPLIBboundingbox{#1}{#2}{#3}{#4}% - \forgetall - \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 - \MPfshowcommand{#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 index e210e4ee1..077bf1539 100644 --- a/tex/context/base/mlib-pps.lua +++ b/tex/context/base/mlib-pps.lua @@ -39,6 +39,54 @@ local colordata = { {}, {}, {}, {}, {} } --~ => 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" +local outercolormode = 0 +local outercolor = nooutercolor +local outertransparency = nooutertransparency +local innercolor = nooutercolor +local innertransparency = nooutertransparency + +function metapost.set_outer_color(mode,color,transparency) + -- 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 + outercolor = color or nooutercolor + outertransparency = transparency or nooutertransparency + elseif mode == 2 then + -- stand alone + outercolor = "" + outertransparency = "" + else -- 0 + outercolor = nooutercolor + outertransparency = nooutertransparency + end + innercolor = outercolor + innertransparency = outertransparency +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 @@ -54,10 +102,15 @@ function metapost.specials.register(str) -- only colors n = tonumber(data[1]) end if n then - colordata[class][n] = data + 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("[msr bug] %s", str or "?") + logs.report("mplib","problematic special: %s", str or "?") end end --~ if str:match("^%%%%MetaPostOption: multipass") then @@ -66,7 +119,7 @@ function metapost.specials.register(str) -- only colors end function metapost.colorhandler(cs, object, result, colorconverter) - local cr = "0 g 0 G" + local cr = outercolor local what = round(cs[2]*10000) local data = colordata[what] if data then @@ -122,7 +175,7 @@ function metapost.specials.tr(specification,object,result) return object, result end local after = before and function() - result[#result+1] = "/Tr0 gs" + result[#result+1] = outertransparency -- here we could revert to teh outer color return object, result end return object, before, nil, after @@ -157,7 +210,7 @@ local colorsplitter = lpeg.Ct(lpeg.splitat(":")) -- x' = sx * x + ry * y + tx -- y' = rx * x + sy * y + ty -function metapost.specials.fg(specification,object,result,flusher) +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 @@ -173,6 +226,16 @@ function metapost.specials.fg(specification,object,result,flusher) 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 + logs.report("mplib", "todo: position '%s' at (%s,%s) with (%s,%s)",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) @@ -434,82 +497,9 @@ function metapost.specials.ts(specification,object,result,flusher) end end -function metapost.colorconverter() - -- it no longer pays off to distinguish between outline and fill - -- (we now have both too, e.g. in arrows) - local model = colors.model - if model == "all" then - return function(cr) - local n = #cr - if n == 1 then - local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" - elseif 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" - else - 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" - end - end - elseif model == "rgb" then - return function(cr) - local n = #cr - if n == 1 then - local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" - end - local r, g, b - if n == 4 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 format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" - end - elseif model == "cmyk" then - return function(cr) - local n = #cr - if n == 1 then - local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" - end - local c, m, y, k - if n == 4 then - c, m, y, k = cr[1], cr[2], cr[3], cr[4] - else - c, m, y, k = rgbtocmyk(cr[1],cr[2],cr[3]) - end - return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" - end - else - return function(cr) - local s - local n = #cr - if 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 format("%.3f g %.3f G",s,s), "0 g 0 G" - end - end -end - ---~ local cmyk_fill = "%.3f %.3f %.3f %.3f k" ---~ local rgb_fill = "%.3f %.3f %.3f rg" ---~ local gray_fill = "%.3f g" ---~ local reset_fill = "0 g" - ---~ local cmyk_stroke = "%.3f %.3f %.3f %.3f K" ---~ local rgb_stroke = "%.3f %.3f %.3f RG" ---~ local gray_stroke = "%.3f G" ---~ local reset_stroke = "0 G" - metapost.reducetogray = true + function metapost.colorconverter() -- 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) @@ -518,64 +508,68 @@ function metapost.colorconverter() -- rather generic pdf, so use this elsewhere if model == "all" then return function(cr) local n = #cr - if reduce then + if n == 0 then + return checked_color_pair() + elseif reduce then if n == 1 then local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" + 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 format("%.3f g %.3f G",r,r), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",r,r)) else - return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + 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 format("%.3f g %.3f G",k,k), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",k,k)) else - return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + 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 format("%.3f g %.3f G",s,s), "0 g 0 G" + 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 format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + 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 format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + 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 model == "rgb" then return function(cr) local n = #cr - if reduce then + if n == 0 then + return checked_color_pair() + elseif reduce then if n == 1 then local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" + 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 format("%.3f g %.3f G",r,r), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",r,r)) else - return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + 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 format("%.3f g %.3f G",k,k), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",k,k)) else local r, g, b = cmyktorgb(c,m,y,k) - return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + 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 format("%.3f g %.3f G",s,s), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",s,s)) else local r, g, b if n == 3 then @@ -583,36 +577,38 @@ function metapost.colorconverter() -- rather generic pdf, so use this elsewhere else r, g, b = cr[1], cr[2], cr[3] end - return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) end end elseif model == "cmyk" then return function(cr) local n = #cr - if reduce then + if n == 0 then + return checked_color_pair() + elseif reduce then if n == 1 then local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" + 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 format("%.3f g %.3f G",r,r), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",r,r)) else local c, m, y, k = rgbtocmyk(r,g,b) - return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + 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 format("%.3f g %.3f G",k,k), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",k,k)) else - return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + 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 format("%.3f g %.3f G",s,s), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",s,s)) else local c, m, y, k if n == 3 then @@ -620,20 +616,22 @@ function metapost.colorconverter() -- rather generic pdf, so use this elsewhere else c, m, y, k = cr[1], cr[2], cr[3], cr[4] end - return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + 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 else return function(cr) local n, s = #cr, 0 - if n == 4 then + 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 format("%.3f g %.3f G",s,s), "0 g 0 G" + return checked_color_pair(format("%.3f g %.3f G",s,s)) end end end @@ -741,7 +739,7 @@ function metapost.graphic_base_pass(mpsformat,str,preamble) str, "endfig ;" -- }, true, nil, true ) - }, true, nil, not (forced_1 or forced_2)) + }, true, nil, not (forced_1 or forced_2), false) if metapost.intermediate.needed then for _, action in pairs(metapost.intermediate.actions) do action() @@ -759,7 +757,7 @@ function metapost.graphic_base_pass(mpsformat,str,preamble) "_trial_run_ := false ;", str, "endfig ;" - } ) + }, false, nil, false, false ) end -- here we could free the textext boxes metapost.free_boxes() @@ -773,7 +771,7 @@ function metapost.graphic_extra_pass() concat(metapost.text_texts_data()," ;\n"), current_graphic, "endfig ;" - }) + }, false, nil, false, true ) end function metapost.getclippath(data) diff --git a/tex/context/base/mlib-pps.mkiv b/tex/context/base/mlib-pps.mkiv new file mode 100644 index 000000000..beaef044e --- /dev/null +++ b/tex/context/base/mlib-pps.mkiv @@ -0,0 +1,61 @@ +%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} + +\def\MPLIBcircularshade#1#2#3#4#5#6#7% nr domain color-a color-b ? colorspace oordinates + {\immediate\pdfobj{<>}% + \immediate\pdfobj{<>}% + \appendtoPDFdocumentshades{/MpSh#1 \the\pdflastobj\space0 R }} + +\def\MPLIBlinearshade#1#2#3#4#5#6#7% nr domain color-a color-b ? colorspace oordinates + {\immediate\pdfobj{<>}% + \immediate\pdfobj{<>}% + \appendtoPDFdocumentshades{/MpSh#1 \the\pdflastobj\space0 R }} + +\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% + {\global\setbox#1\hbox}% {#2}} + +\def\MPLIBfreetext#1% + {\global\setbox#1\emptybox} + +% \def\MPLIBgettext#1#2#3#4#5#6#7% we can also use this for the figure and pass sx/sy +% {\ctxlua{metapost.edefsxsy(\number\wd#7,\number\ht#7,\number\dp#7)}% +% \pdfliteral{q #1 #2 #3 #4 #5 #6 cm}% +% \vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[sx=\sx,sy=\sy]{\raise\dp#7\box#7}\hss}}% +% \pdfliteral{Q}} + +\def\MPLIBgettextscaled#1#2#3% + {\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}} + +\def\MPLIBgraphictext#1% + {\startTEXpage[\c!scale=10000]#1\stopTEXpage} + +\protect \endinput diff --git a/tex/context/base/mlib-pps.tex b/tex/context/base/mlib-pps.tex deleted file mode 100644 index beaef044e..000000000 --- a/tex/context/base/mlib-pps.tex +++ /dev/null @@ -1,61 +0,0 @@ -%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} - -\def\MPLIBcircularshade#1#2#3#4#5#6#7% nr domain color-a color-b ? colorspace oordinates - {\immediate\pdfobj{<>}% - \immediate\pdfobj{<>}% - \appendtoPDFdocumentshades{/MpSh#1 \the\pdflastobj\space0 R }} - -\def\MPLIBlinearshade#1#2#3#4#5#6#7% nr domain color-a color-b ? colorspace oordinates - {\immediate\pdfobj{<>}% - \immediate\pdfobj{<>}% - \appendtoPDFdocumentshades{/MpSh#1 \the\pdflastobj\space0 R }} - -\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% - {\global\setbox#1\hbox}% {#2}} - -\def\MPLIBfreetext#1% - {\global\setbox#1\emptybox} - -% \def\MPLIBgettext#1#2#3#4#5#6#7% we can also use this for the figure and pass sx/sy -% {\ctxlua{metapost.edefsxsy(\number\wd#7,\number\ht#7,\number\dp#7)}% -% \pdfliteral{q #1 #2 #3 #4 #5 #6 cm}% -% \vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[sx=\sx,sy=\sy]{\raise\dp#7\box#7}\hss}}% -% \pdfliteral{Q}} - -\def\MPLIBgettextscaled#1#2#3% - {\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}} - -\def\MPLIBgraphictext#1% - {\startTEXpage[\c!scale=10000]#1\stopTEXpage} - -\protect \endinput diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua index 9a7ed6f39..1644feb4a 100644 --- a/tex/context/base/mlib-run.lua +++ b/tex/context/base/mlib-run.lua @@ -29,6 +29,8 @@ 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 = string.format metapost = metapost or { } @@ -143,7 +145,7 @@ function metapost.reporterror(result) metapost.report("mp error: no result object returned") elseif result.status > 0 then local t, e, l = result.term, result.error, result.log - if t then + if t and t ~= "" then metapost.report("mp terminal: %s",t) end if e then @@ -236,20 +238,41 @@ function metapost.reset(mpx) end end -function metapost.process(mpx, data, trialrun, flusher, multipass) +local mp_inp, mp_log, mp_tag = { }, { }, 0 + +function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass) local converted, result = false, {} if type(mpx) == "string" then mpx = metapost.format(mpx) -- goody end if mpx and data then statistics.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 statistics.starttiming(metapost.exectime) result = mpx:execute(d) statistics.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" @@ -267,9 +290,18 @@ function metapost.process(mpx, data, trialrun, flusher, multipass) end end else + if trace_graphics then + mp_inp:write(data) + end statistics.starttiming(metapost.exectime) - result = mpx:execute(data) + result = mpx[mpx]:execute(data) statistics.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") @@ -285,6 +317,11 @@ function metapost.process(mpx, data, trialrun, flusher, multipass) 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 statistics.stoptiming(metapost) end return converted, result diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.tex index 0fb64d98a..b24c11d58 100644 --- a/tex/context/base/mult-sys.tex +++ b/tex/context/base/mult-sys.tex @@ -504,6 +504,7 @@ \definesystemvariable {mk} % MarKering \definesystemvariable {mt} % inline MaTh \definesystemvariable {mo} % Math Options +\definesystemvariable {mp} % MetaPost \definesystemvariable {mx} % MatriX \definesystemvariable {ng} % parbuilders \definesystemvariable {nh} % new heads (structure) @@ -720,6 +721,7 @@ \definefileconstant {propprefix} {prop-} \definefileconstant {unicprefix} {unic-} \definefileconstant {sortprefix} {sort-} +\definefileconstant {prettyprefix} {pret-} \definefileconstant {moduleprefix} {m-} \definefileconstant {styleprefix} {s-} diff --git a/tex/context/base/node-fin.mkiv b/tex/context/base/node-fin.mkiv new file mode 100644 index 000000000..787706ff2 --- /dev/null +++ b/tex/context/base/node-fin.mkiv @@ -0,0 +1,78 @@ +%D \module +%D [ file=attr-ini, +%D version=2007.06.06, % probably a bit older +%D title=\CONTEXT\ Node Macros, +%D subtitle=Finalizing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Node Support / Finalizing} + +% Objects are processed indepently \unknown\ actually we may +% need a proper callback. + +\unprotect + +\registerctxluafile{node-fin}{1.001} % we might generalize this one + +\definesystemattribute[trigger] % feature inheritance + +\newbox\finalizedshipoutbox + +\def\finalizeobjectbox#1{\ctxlua{nodes.process_page(tex.box[\number#1])}} + +\def\finalizeshipoutbox#1% % hack till we have access to pdf backend + {\global\setbox\finalizedshipoutbox\hbox{#1}% + \finalizeobjectbox\finalizedshipoutbox + \hbox{\ctxlua{states.flush()}\box\finalizedshipoutbox}} + +% tricky stuff: + +\newcount\attributeboxcount + +\edef\startinheritattributes{\dosetattribute {trigger}{1}} +\edef\stopinheritattributes {\doresetattribute{trigger}} + +\def\doattributedcopy {\afterassignment\dodoattributedcopy\attributeboxcount} +\def\doattributedbox {\afterassignment\dodoattributedbox \attributeboxcount} + +\def\dodoattributedcopy + {\startinheritattributes + \ifvbox\attributeboxcount + \vbox{\unvcopy\attributeboxcount}% + \else + \hbox{\unhcopy\attributeboxcount}% + \fi + \stopinheritattributes} + +\def\dodoattributedbox + {\startinheritattributes + \ifvbox\attributeboxcount + \vbox{\unvbox\attributeboxcount}% + \else + \hbox{\unhbox\attributeboxcount}% + \fi + \stopinheritattributes} + +\def\enableattributeinheritance + {\ctxlua{states.enabletriggering()}% + \let\attributedcopy\doattributedcopy + \let\attributedbox \doattributedbox} + +\def\disableattributeinheritance + {\ctxlua{states.disabletriggering()}% + \let\attributedcopy\copy + \let\attributedbox \box} + +\disableattributeinheritance + +% \appendtoks +% \enableattributeinheritance % will become default +% \to\everyjob + +\protect \endinput diff --git a/tex/context/base/node-fin.tex b/tex/context/base/node-fin.tex deleted file mode 100644 index 787706ff2..000000000 --- a/tex/context/base/node-fin.tex +++ /dev/null @@ -1,78 +0,0 @@ -%D \module -%D [ file=attr-ini, -%D version=2007.06.06, % probably a bit older -%D title=\CONTEXT\ Node Macros, -%D subtitle=Finalizing, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Node Support / Finalizing} - -% Objects are processed indepently \unknown\ actually we may -% need a proper callback. - -\unprotect - -\registerctxluafile{node-fin}{1.001} % we might generalize this one - -\definesystemattribute[trigger] % feature inheritance - -\newbox\finalizedshipoutbox - -\def\finalizeobjectbox#1{\ctxlua{nodes.process_page(tex.box[\number#1])}} - -\def\finalizeshipoutbox#1% % hack till we have access to pdf backend - {\global\setbox\finalizedshipoutbox\hbox{#1}% - \finalizeobjectbox\finalizedshipoutbox - \hbox{\ctxlua{states.flush()}\box\finalizedshipoutbox}} - -% tricky stuff: - -\newcount\attributeboxcount - -\edef\startinheritattributes{\dosetattribute {trigger}{1}} -\edef\stopinheritattributes {\doresetattribute{trigger}} - -\def\doattributedcopy {\afterassignment\dodoattributedcopy\attributeboxcount} -\def\doattributedbox {\afterassignment\dodoattributedbox \attributeboxcount} - -\def\dodoattributedcopy - {\startinheritattributes - \ifvbox\attributeboxcount - \vbox{\unvcopy\attributeboxcount}% - \else - \hbox{\unhcopy\attributeboxcount}% - \fi - \stopinheritattributes} - -\def\dodoattributedbox - {\startinheritattributes - \ifvbox\attributeboxcount - \vbox{\unvbox\attributeboxcount}% - \else - \hbox{\unhbox\attributeboxcount}% - \fi - \stopinheritattributes} - -\def\enableattributeinheritance - {\ctxlua{states.enabletriggering()}% - \let\attributedcopy\doattributedcopy - \let\attributedbox \doattributedbox} - -\def\disableattributeinheritance - {\ctxlua{states.disabletriggering()}% - \let\attributedcopy\copy - \let\attributedbox \box} - -\disableattributeinheritance - -% \appendtoks -% \enableattributeinheritance % will become default -% \to\everyjob - -\protect \endinput diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv new file mode 100644 index 000000000..210f21229 --- /dev/null +++ b/tex/context/base/node-ini.mkiv @@ -0,0 +1,106 @@ +%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-tst}{1.001} +\registerctxluafile{node-tra}{1.001} % we might split it off (module) +\registerctxluafile{node-seq}{1.001} % we might generalize this one +\registerctxluafile{node-tsk}{1.001} +\registerctxluafile{node-tex}{1.001} +\registerctxluafile{node-res}{1.001} +\registerctxluafile{node-pro}{1.001} +\registerctxluafile{node-shp}{1.001} +\registerctxluafile{node-ser}{1.001} +\registerctxluafile{node-ext}{1.001} +\registerctxluafile{node-inj}{1.001} % we might split it off + +\newtoks \attributesresetlist + +\ifdefined \v!global \else \def\v!global{global} \fi % for metatex + +\def\defineattribute + {\dodoubleempty\dodefineattribute} + +\def\dodefineattribute[#1][#2]% alternatively we can let lua do the housekeeping + {\expandafter\newattribute\csname @attr@#1\endcsname + \expandafter \xdef\csname :attr:#1\endcsname{\number\lastallocatedattribute}% + \ctxlua{attributes.define("#1",\number\lastallocatedattribute)}% + %\writestatus\m!systems{defining attribute #1 with number \number\lastallocatedattribute}% + \doifnotinset\v!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}} + +\def\definesystemattribute + {\dodoubleempty\dodefinesystemattribute} + +\def\dodefinesystemattribute[#1][#2]% alternatively we can let lua do the housekeeping + {\scratchcounter\ctxlua{tex.print(attributes.private("#1"))}\relax + \global\expandafter\attributedef\csname @attr@#1\endcsname\scratchcounter + \expandafter \xdef\csname :attr:#1\endcsname{\number\scratchcounter}% + %\writestatus\m!systems{defining system attribute #1 with number \number\scratchcounter}% + \doifnotinset\v!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}} + +% expandable so we can \edef them for speed + +\def\dosetattribute#1#2{\csname @attr@#1\endcsname#2\relax} +\def\doresetattribute#1{\csname @attr@#1\endcsname\attributeunsetvalue} +\def\dogetattribute #1{\number\csname @attr@#1\endcsname} +\def\dogetattributeid#1{\csname :attr:#1\endcsname} + +\let\dompattribute\gobbletwoarguments + +\def\resetallattributes{\the\attributesresetlist} + +% \appendtoks +% \ctxlua { +% callbacks.push('hpack_filter') +% callbacks.push('vpack_filter') +% callbacks.push('buildpage_filter') +% callbacks.push('pre_linebreak_filter') +% callbacks.push('pre_output_filter') +% }% +% \to \everybeforeoutput +% \appendtoks +% \ctxlua { +% callbacks.pop('hpack_filter') +% callbacks.pop('vpack_filter') +% callbacks.pop('buildpage_filter') +% callbacks.pop('pre_linebreak_filter') +% callbacks.pop('pre_output_filter') +% }% +% \to \everyafteroutput + +\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)}}} + +\def\starttracingnodes[#1]{\ctxlua{nodes.tracers.characters.start("#1")}} +\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-ini.tex b/tex/context/base/node-ini.tex deleted file mode 100644 index 210f21229..000000000 --- a/tex/context/base/node-ini.tex +++ /dev/null @@ -1,106 +0,0 @@ -%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-tst}{1.001} -\registerctxluafile{node-tra}{1.001} % we might split it off (module) -\registerctxluafile{node-seq}{1.001} % we might generalize this one -\registerctxluafile{node-tsk}{1.001} -\registerctxluafile{node-tex}{1.001} -\registerctxluafile{node-res}{1.001} -\registerctxluafile{node-pro}{1.001} -\registerctxluafile{node-shp}{1.001} -\registerctxluafile{node-ser}{1.001} -\registerctxluafile{node-ext}{1.001} -\registerctxluafile{node-inj}{1.001} % we might split it off - -\newtoks \attributesresetlist - -\ifdefined \v!global \else \def\v!global{global} \fi % for metatex - -\def\defineattribute - {\dodoubleempty\dodefineattribute} - -\def\dodefineattribute[#1][#2]% alternatively we can let lua do the housekeeping - {\expandafter\newattribute\csname @attr@#1\endcsname - \expandafter \xdef\csname :attr:#1\endcsname{\number\lastallocatedattribute}% - \ctxlua{attributes.define("#1",\number\lastallocatedattribute)}% - %\writestatus\m!systems{defining attribute #1 with number \number\lastallocatedattribute}% - \doifnotinset\v!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}} - -\def\definesystemattribute - {\dodoubleempty\dodefinesystemattribute} - -\def\dodefinesystemattribute[#1][#2]% alternatively we can let lua do the housekeeping - {\scratchcounter\ctxlua{tex.print(attributes.private("#1"))}\relax - \global\expandafter\attributedef\csname @attr@#1\endcsname\scratchcounter - \expandafter \xdef\csname :attr:#1\endcsname{\number\scratchcounter}% - %\writestatus\m!systems{defining system attribute #1 with number \number\scratchcounter}% - \doifnotinset\v!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}} - -% expandable so we can \edef them for speed - -\def\dosetattribute#1#2{\csname @attr@#1\endcsname#2\relax} -\def\doresetattribute#1{\csname @attr@#1\endcsname\attributeunsetvalue} -\def\dogetattribute #1{\number\csname @attr@#1\endcsname} -\def\dogetattributeid#1{\csname :attr:#1\endcsname} - -\let\dompattribute\gobbletwoarguments - -\def\resetallattributes{\the\attributesresetlist} - -% \appendtoks -% \ctxlua { -% callbacks.push('hpack_filter') -% callbacks.push('vpack_filter') -% callbacks.push('buildpage_filter') -% callbacks.push('pre_linebreak_filter') -% callbacks.push('pre_output_filter') -% }% -% \to \everybeforeoutput -% \appendtoks -% \ctxlua { -% callbacks.pop('hpack_filter') -% callbacks.pop('vpack_filter') -% callbacks.pop('buildpage_filter') -% callbacks.pop('pre_linebreak_filter') -% callbacks.pop('pre_output_filter') -% }% -% \to \everyafteroutput - -\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)}}} - -\def\starttracingnodes[#1]{\ctxlua{nodes.tracers.characters.start("#1")}} -\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-par.mkiv b/tex/context/base/node-par.mkiv new file mode 100644 index 000000000..7f7ca9977 --- /dev/null +++ b/tex/context/base/node-par.mkiv @@ -0,0 +1,60 @@ +%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] + +\newcount\nofparbuilders + +\def\defineparbuilder[#1]% + {\global\advance\nofparbuilders\plusone + \ctxlua{parbuilders.register("#1",\number\nofparbuilders)}% + \setxvalue{\??ng:#1}{\dosetattribute{parbuilder}{\number\nofparbuilders}}} + +\def\startparbuilder[#1]% + {\edef\@@currentparbuilder{\number\dogetattribute{parbuilder}}% + \globalpushmacro\@@currentparbuilder + \getvalue{\??ng:#1}} + +\def\stopparbuilder + {\globalpopmacro\@@currentparbuilder + \dosetattribute{parbuilder}{\@@currentparbuilder}} + +% 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 + +\def\enableparbuilders {\ctxlua{callback.register('linebreak_filter', parbuilders.main)}} +\def\disableparbuilders{\ctxlua{callback.register('linebreak_filter', nil)}} + +\protect \endinput diff --git a/tex/context/base/node-par.tex b/tex/context/base/node-par.tex deleted file mode 100644 index 7f7ca9977..000000000 --- a/tex/context/base/node-par.tex +++ /dev/null @@ -1,60 +0,0 @@ -%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] - -\newcount\nofparbuilders - -\def\defineparbuilder[#1]% - {\global\advance\nofparbuilders\plusone - \ctxlua{parbuilders.register("#1",\number\nofparbuilders)}% - \setxvalue{\??ng:#1}{\dosetattribute{parbuilder}{\number\nofparbuilders}}} - -\def\startparbuilder[#1]% - {\edef\@@currentparbuilder{\number\dogetattribute{parbuilder}}% - \globalpushmacro\@@currentparbuilder - \getvalue{\??ng:#1}} - -\def\stopparbuilder - {\globalpopmacro\@@currentparbuilder - \dosetattribute{parbuilder}{\@@currentparbuilder}} - -% 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 - -\def\enableparbuilders {\ctxlua{callback.register('linebreak_filter', parbuilders.main)}} -\def\disableparbuilders{\ctxlua{callback.register('linebreak_filter', nil)}} - -\protect \endinput diff --git a/tex/context/base/pack-box.mkii b/tex/context/base/pack-box.mkii new file mode 100644 index 000000000..1be840552 --- /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} + +\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 + +\def\offset {\dodoubleempty\dooffsetbox [\hbox]} % yes or no +\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} + +\def\ltabbed{\dotabbed\relax\hss} +\def\rtabbed{\dotabbed\hss \relax} +\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 + +\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]} + +\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..1be840552 --- /dev/null +++ b/tex/context/base/pack-box.mkiv @@ -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} + +\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 + +\def\offset {\dodoubleempty\dooffsetbox [\hbox]} % yes or no +\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} + +\def\ltabbed{\dotabbed\relax\hss} +\def\rtabbed{\dotabbed\hss \relax} +\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 + +\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]} + +\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..768b1e0c9 --- /dev/null +++ b/tex/context/base/pack-lyr.mkii @@ -0,0 +1,753 @@ +%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 + \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..768b1e0c9 --- /dev/null +++ b/tex/context/base/pack-lyr.mkiv @@ -0,0 +1,753 @@ +%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 + \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-obj.lua b/tex/context/base/pack-obj.lua new file mode 100644 index 000000000..3256b3702 --- /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.tex", + 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 = tex.sprint + +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..6c1e54758 --- /dev/null +++ b/tex/context/base/pack-obj.mkiv @@ -0,0 +1,234 @@ +%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} + +%D \macros +%D {setobject,getobject,ifinobject} +%D +%D Boxes can be considered reuable objects. Unfortunaltely once +%D passed to the \DVI\ file, such objects cannot be reused. In +%D \PDF\ however, reusing is possible and sometimes even a +%D necessity. Therefore, \CONTEXT\ supports reusable objects. +%D +%D During the \TEX\ processing run, boxes can serve the purpose +%D of objects, and the \DVI\ driver module implements objects +%D using packed boxes. +%D +%D The \PDF\ and \PDFTEX\ driver modules implement objects +%D using \PDF\ forms. There is no (real) restriction on the +%D number of objects there. +%D +%D The first application of objects in \CONTEXT\ concerned +%D \METAPOST\ graphics and fill||in form fields. The first +%D application can save lots of bytes, while the latter use is +%D more a necessity than byte saving. +%D +%D \starttyping +%D \setobject{class}{name}\somebox{} +%D \getobject{class}{name} +%D \stoptyping +%D +%D Here \type{\somebox} can be whatever box specification suits +%D \TEX. We save the dimensions of an object, although some +%D drivers will do so themselves. This means that when for +%D instance using \PDFTEX\ we could save a hash entry plus some +%D 20+ memory locations per object by delegating this +%D housekeeping to the driver. The current approach permits +%D us to keep the box characteristic too. + +\newif\ifinobject + +\def\objectplaceholder{NOT YET FLUSHED}% + +\def\presetobject#1#2% \global added + {\ifcsname\r!object#1::#2\endcsname\else + \global\@EA\let\csname\r!object#1::#2\endcsname\objectplaceholder + \fi} + +\def\dosetobject#1#2#3% \initializepaper this will move to \everyshipout + {\initializepaper + \ifcsname\r!object#2::#3\endcsname + \expandafter\gobblefivearguments + \else % tzt, overload internal referenced objects to save entries + \expandafter\dodosetobject + \fi + {#1}{#2}{#3}} + +\def\resetobject#1#2% + {\letbeundefined{\r!object#1::#2}} + +%D \macros +%D {finalizeobjectbox} +%D +%D This one provides a hook for last minute object box processing +%D we need this in \MKIV. + +\ifx\finalizeobjectbox\undefined + \let\finalizeobjectbox\gobbleoneargument +\fi + +%D Somehow there is a rounding error problem in either \PDFTEX\ +%D or in viewers, or maybe it is conforming the specs. The next +%D variable compensate for it by removing the rather tight +%D clip. + +\def\objectoffset{1cm} + +\def\dodosetobject#1#2#3% + {\bgroup + \globalpushmacro\crossreferenceobject \objectreferenced + \inobjecttrue + \dowithnextbox + {\globalpopmacro\crossreferenceobject + \dododosetobject{#1}{#2}{#3}\egroup}} + +\def\dododosetobject#1#2#3% + {\begingroup + \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox + \scratchdimen\objectoffset + \@EA\xdef\csname\r!object#2::#3\endcsname + {\noexpand\dohandleobject{#2}{#3}% + {\ifhbox\nextbox\hbox\else\vbox\fi}% + {\number\nextboxwd}{\number\nextboxht}{\number\nextboxdp}% + {\number\scratchdimen}}% + \expanded % freeze the dimensions since \dostartobject may use \nextbox + {\dostartobject{#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}% + \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint + \setbox\nextbox\vbox spread 2\scratchdimen + {\forgetall \offinterlineskip + \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}% + \fi \fi + \flushnextbox + \dostopobject + \endgroup} + +\def\getobject#1#2% + {\begingroup + \let\dohandleobject\dogetobject + \csname\r!object#1::#2\endcsname} + +\def\dogetobject#1#2#3#4#5#6#7% don't change this, should work for dvi & pdf + {\initializepaper + \forgetall + \dontshowcomposition + \setbox\scratchbox\vbox + {\doinsertobject{#1}{#2}}% + \setbox\scratchbox#3% + {\vbox to #5\scaledpoint + {\ifdim\ht\scratchbox>#5\scaledpoint + \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss + \else\ifdim\wd\scratchbox>#4\scaledpoint + \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss + \else + %\vss\box\scratchbox + \vss\hbox to #4\scaledpoint{\box\scratchbox\hss}% fix Chof + \fi\fi}}% + \box\scratchbox + \endgroup} + +%D If needed one can ask for the dimensions of an object with: +%D +%D \starttyping +%D \getobjectdimensions{class}{name} +%D \stoptyping +%D +%D The results are reported in \type {\objectwidth}, \type +%D {\objectheight} and \type {\objectdepth}. + +\def\dogetobjectdimensions#1#2#3#4#5#6#7% + {\def\objectwidth {#4\s!sp}% + \def\objectheight{#5\s!sp}% + \def\objectdepth {#6\s!sp}% + \def\objectmargin{#7\s!sp}} + +\def\getobjectdimensions#1#2% + {\let\dohandleobject\dogetobjectdimensions + \let\objectwidth \!!zeropoint + \let\objectheight\!!zeropoint + \let\objectdepth \!!zeropoint + \labelcsname\r!object#1::#2\endcsname} + +%D Apart from this kind of objects, that have typeset content, +%D we can have low level driver specific objects. Both types +%D can have references to internal representations, hidden for +%D the user. We keep track of such references by means of a +%D dedicated cross reference mechanism. Normally, objects are +%D defined before they are used, but forward referencing +%D sometimes occurs. +%D +%D \starttyping +%D \dosetobjectreference {class} {identifier} {reference value} {page} +%D \dogetobjectreference {class} {identifier} \csname +%D \stoptyping +%D +%D These commands are to be called by the \type{\startobject}, +%D \type{\stopobject} and \type{\insertobject} specials. + +\def\objectreferenced{\global\chardef\crossreferenceobject\plusone} +\def\driverreferenced{\global\chardef\crossreferenceobject\zerocount} + +\objectreferenced + +% no undefined test ! ! ! ! (pdftex fails on undefined objects) + +\def\doregisterobjectreference#1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobobjects.save("#1::#2",#3,\noexpand\the\realpageno)}}} +\def\dooverloadobjectreference#1#2#3{\ctxlua{jobobjects.set("#1::#2",#3,\the\realpageno)}} + +\def\dosetobjectreference + {\ifcase\crossreferenceobject + \objectreferenced + \expandafter\dooverloadobjectreference + \else + \expandafter\doregisterobjectreference + \fi} + +\def\dosetdriverreference + {\driverreferenced\dosetobjectreference} + +\def\defaultobjectreference#1#2{0} % driver dependent +\def\defaultobjectpage #1#2{\realfolio} + +\def\dogetobjectreference #1#2#3{\xdef#3{\ctxlua{jobobjects.number("#1::#2","\defaultobjectreference{#1}{#2}")}}} +\def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxlua{jobobjects.page("#1::#2","\defaultobjectpage{#1}{#2}")}}} + +\def\setobject {\driverreferenced\dosetobject1} +\def\settightobject{\driverreferenced\dosetobject0} + +%D \macros +%D {doifobjectfoundelse,doifobjectreferencefoundelse} +%D +%D To prevent redundant definition of objects, one can use +%D the next tests: +%D +%D \starttyping +%D \doifobjectfoundelse{class}{object}{do then}{do else} +%D \doifobjectreferencefoundelse{class}{object}{do then}{do else} +%D \stoptyping + +\def\doifobjectfoundelse#1#2% + {\ifcsname\r!object#1::#2\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\doifobjectreferencefoundelse#1#2{\ctxlua{jobobjects.doifelse("#1::#2")}} + +\protect \endinput diff --git a/tex/context/base/pack-rul.lua b/tex/context/base/pack-rul.lua new file mode 100644 index 000000000..11995bfed --- /dev/null +++ b/tex/context/base/pack-rul.lua @@ -0,0 +1,42 @@ +if not modules then modules = { } end modules ['pack-rul'] = { + version = 1.001, + comment = "companion to pack-rul.tex", + 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 mk.pdf.

+--ldx]]-- + +function commands.doreshapeframedbox(n) + local noflines, lastlinelength = 0, 0 + if tex.wd[n] ~= 0 then + local hpack, free, copy = node.hpack, node.free, node.copy_list + local noflines, width, done = 0, 0, false + local list = tex.box[n].list + for h in node.traverse_id('hlist',list) do + done = true + local p = hpack(copy(h.list)) + lastlinelength = p.width + if lastlinelength > width then + width = lastlinelength + end + free(p) + end + if done then + if width ~= 0 then + for h in node.traverse_id('hlist',list) do + if h.width ~= width then + h.list = hpack(h.list,width,'exactly') + h.width = width + end + end + end + tex.wd[n] = width + end + end + tex.dimen["framedlastlength"] = lastlinelength + tex.count["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..042e8805d --- /dev/null +++ b/tex/context/base/pack-rul.mkii @@ -0,0 +1,3637 @@ +%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\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..574175dde --- /dev/null +++ b/tex/context/base/pack-rul.mkiv @@ -0,0 +1,3675 @@ +%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 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. + +%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\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 + +\def\defineoverlay + {\dodoubleargument\dodefineoverlay} + +\def\dodefineoverlay[#1][#2]% + {\def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}% + \processcommalist[#1]\docommand} + +\prependtoks + \hsize\overlaywidth + \vsize\overlayheight +\to\everyoverlay + +\long\def\executedefinedoverlay#1#2% + {\bgroup + \edef\overlaywidth {\the\frameddimenwd\space}% + \edef\overlayheight{\the\dimexpr\frameddimenht+\frameddimendp\relax\space}% + \edef\overlaydepth {\the\frameddimendp\space}% + \edef\overlaycolor {\framedparameter\c!backgroundcolor}% + %\edef\overlaycorner{\framedparameter\c!backgroundcorner}% + %\edef\overlayradius{\framedparameter\c!backgroundradius}% + \let\overlayoffset\backgroundoffset % we steal this one + \setbox\scratchbox\hbox{\lower\overlaydepth\hbox{\the\everyoverlay#2}}% + \setbox\scratchbox\hbox + {\hskip-.5\dimexpr\wd\scratchbox-\overlaywidth \relax + \raise-.5\dimexpr\ht\scratchbox-\frameddimenht\relax % not overlayheight ! + \box\scratchbox}% + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \dp\scratchbox\overlaydepth + \startlayoutcomponent{o:#1}{overlay #1}% + \box\scratchbox + \stoplayoutcomponent + \egroup} + +%D The empty case is: + +\let\executeoverlay\gobblesevenarguments + +%D For testing we provide: + +\def\doifoverlayelse#1% + {\doifdefinedelse{\??ov#1}} + +%D We predefine two already familiar backgrounds: + +\setvalue{\??ov\v!screen}{\dograybox } +\setvalue{\??ov\v!color }{\docolorbox} + +% %D After all these preparations, the background macro does no +% %D bring to many surprises. One has to keep in mind that this +% %D macro starts up a call chain, depending on the background +% %D one needs: +% %D +% %D \startitemize[packed] +% %D \item a raster, color or user defined shape +% %D \item square or round corners +% %D \item a \TEX\ or driver based method +% %D \stopitemize +% %D +% %D The macro can be extended by adding commands to the token +% %D list register \type {\everybackgroundbox}. For this +% %D purpose, the name of the current background is available in +% %D \type {\currentbackgound}. + +%D The content of the box will be (temporary) saved in a box. We +%D also have an extra box for backgrounds. + +\newbox\framebox +\newbox\extraframebox + +\newtoks\everybackgroundbox + +\let\currentbackground\empty + +% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method +% {\bgroup +% \def\currentbackground{#1}% +% \the\everybackgroundbox +% \setbox\extraframebox\hbox +% {\vbox{\moveleft\backgroundoffset\hbox{\executeifdefined{\??ov\currentbackground}\donothing}}}% +% \wd\extraframebox\zeropoint % \backgroundwidth +% \ht\extraframebox\backgroundheight +% \dp\extraframebox\backgrounddepth +% \box\extraframebox % \hskip-\backgroundwidth +% \egroup} + +% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method +% {\bgroup +% \def\currentbackground{#1}% +% \ifcsname\??ov\currentbackground\endcsname +% \the\everybackgroundbox +% \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}% +% \wd\extraframebox\zeropoint % \backgroundwidth +% \ht\extraframebox\backgroundheight +% \dp\extraframebox\backgrounddepth +% \box\extraframebox % \hskip-\backgroundwidth +% \fi +% \egroup} + +\def\dodobackgroundbox + {\bgroup + \ifcsname\??ov\currentbackground\endcsname + \the\everybackgroundbox + \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}% + \wd\extraframebox\zeropoint % \backgroundwidth + \ht\extraframebox\backgroundheight + \dp\extraframebox\backgrounddepth + \box\extraframebox % \hskip-\backgroundwidth + \fi + \egroup} + +\def\dododobackgroundbox#1,#2% #2 gobbles spaces + {\edef\currentbackground{#1}% + \ifx\currentbackground\s!unknown\else + \dodobackgroundbox\expandafter\dododobackgroundbox + \fi#2} + +\let\backgroundoffset\!!zeropoint +\let\backgrounddepth \!!zeropoint +\def\backgroundwidth {\the\hsize} +\def\backgroundheight{\the\vsize} + +% todo: also \def\theforegroundbox{#1} + +% \def\dobackgroundbox#1% +% {\setbox\framebox\vbox +% {\forgetall +% \boxmaxdepth\maxdimen +% \scratchdimen \framedparameter{#1}\relax +% \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax +% \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax +% \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax +% \edef\backgroundoffset{\the\scratchdimen}% +% \edef\backgroundwidth {\the\wd\framebox}% +% \edef\backgroundheight{\the\ht\framebox}% +% \edef\backgrounddepth {\the\dp\framebox}% +% %\edef\foregroundbox{\box#1}% +% \def\foregroundbox% fuzzy but needed hack, this \vss, otherwise +% {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift +% \edef\component{\framedparameter\c!component}% +% \hbox to \backgroundwidth % in case 'foreground' is used as overlay +% {\ifx\component\empty +% \rawprocesscommalist[\framedbackground]\dodobackgroundbox +% \else +% \startlayoutcomponent{b:\component}{\s!background\space\component}% +% \rawprocesscommalist[\framedbackground]\dodobackgroundbox +% \stoplayoutcomponent +% \fi +% \box\framebox\hss}}} + +\def\normalforegroundbox% fuzzy but needed hack, this \vss, otherwise + {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift + +\def\dobackgroundbox#1% + {\setbox\framebox\vbox + {\forgetall + \boxmaxdepth\maxdimen + \scratchdimen \framedparameter{#1}\relax + \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax + \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax + \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax + \edef\backgroundoffset{\the\scratchdimen}% + \edef\backgroundwidth {\the\wd\framebox}% + \edef\backgroundheight{\the\ht\framebox}% + \edef\backgrounddepth {\the\dp\framebox}% + %\edef\foregroundbox{\box#1}% + \edef\component{\framedparameter\c!component}% + \let\foregroundbox\normalforegroundbox + \hbox to \backgroundwidth % in case 'foreground' is used as overlay + {\ifx\component\empty + \normalexpanded{\noexpand\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax + \else + \startlayoutcomponent{b:\component}{background \component}% + \normalexpanded{\noexpand\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax + \stoplayoutcomponent + \fi + \box\framebox\hss}}} + +%D One can explictly insert the foreground box. For that +%D purpose we introduce the overlay \type {foreground}. + +\defineoverlay[\v!foreground][\foregroundbox] + +%D We can specify overlays as a comma separated list of +%D overlays, a sometimes handy feature. + +%D Besides backgrounds (overlays) we also need some macros to +%D draw outlines (ruled borders). Again we have to deal with +%D square and round corners. The first category can be handled +%D by \TEX\ itself, the latter one depends on the driver. This +%D macro also support a negative offset. + +\ifx\scratchoffset\undefined \newdimen\scratchoffset \fi + +\def\dooutlinebox % we needed to move the color command in order to apply attributes properly + {\setbox\framebox\vbox % rules on top of box + {\scratchoffset \framedparameter\c!frameoffset\relax + \frameddimenwd\dimexpr\wd\framebox+2\scratchoffset\relax + \frameddimenht\dimexpr\ht\framebox+ \scratchoffset\relax + \frameddimendp\dimexpr\dp\framebox+ \scratchoffset+\framedparameter\c!framedepth\relax + \ifdim\frameddimendp<\zeropoint + \advance\frameddimenht \frameddimendp + \scratchdimen-\frameddimendp + \frameddimendp\zeropoint + \else + \scratchdimen\zeropoint + \fi + \setbox\extraframebox\hbox + {\doifsomething{\framedparameter\c!framecolor}{\color[\framedparameter\c!framecolor]}{\dostrokedbox}}% + \setbox\extraframebox\hbox + {\raise\scratchdimen\vbox + {\moveleft\scratchoffset + \box\extraframebox}}% + \wd\extraframebox\wd\framebox + \ht\extraframebox\ht\framebox + \dp\extraframebox\dp\framebox + \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}} + +\def\dostrokedbox + {\doifelse{\framedparameter\c!framecorner}\v!rectangular + {\dostrokedlinedbox} + {\ifzeropt\dimexpr\framedparameter\c!frameradius\relax % just in case of .x\bodyfontsize + \dostrokedlinedbox + \else + \dostrokedroundbox + \fi}} + +\def\dostrokedlinedbox + {\setbox\scratchbox\null + \wd\scratchbox\frameddimenwd + \ht\scratchbox\frameddimenht + \dp\scratchbox\frameddimendp + \setbox\scratchbox\vbox \bgroup + \csname t\@@frame@@\framedparameter\c!frame\framedparameter\c!topframe \endcsname + \hbox \bgroup + \csname l\@@frame@@\framedparameter\c!frame\framedparameter\c!leftframe \endcsname + \box\scratchbox + \csname r\@@frame@@\framedparameter\c!frame\framedparameter\c!rightframe \endcsname + \egroup + \csname b\@@frame@@\framedparameter\c!frame\framedparameter\c!bottomframe\endcsname + \egroup + \wd\scratchbox\frameddimenwd + \ht\scratchbox\frameddimenht + \dp\scratchbox\frameddimendp + \box\scratchbox} + +\def\@@frame@@{@@frame@@} + +% \setvalue{t\@@frame@@\v!on \v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} +% \setvalue{t\@@frame@@\v!off\v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} +% \setvalue{t\@@frame@@\v!on }{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} +% \setvalue{b\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} +% \setvalue{b\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} +% \setvalue{b\@@frame@@\v!on }{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} +% \setvalue{l\@@frame@@\v!on \v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} +% \setvalue{l\@@frame@@\v!off\v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} +% \setvalue{l\@@frame@@\v!on }{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} +% \setvalue{r\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} +% \setvalue{r\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} +% \setvalue{r\@@frame@@\v!on }{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} + +\def\@@frame@@trule{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth} +\def\@@frame@@brule{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth} +\def\@@frame@@rrule{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth} +\def\@@frame@@lrule{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth} + +\letvalue{t\@@frame@@\v!on \v!on}\@@frame@@trule +\letvalue{t\@@frame@@\v!off\v!on}\@@frame@@trule +\letvalue{t\@@frame@@\v!on }\@@frame@@trule + +\letvalue{b\@@frame@@\v!on \v!on}\@@frame@@brule +\letvalue{b\@@frame@@\v!off\v!on}\@@frame@@brule +\letvalue{b\@@frame@@\v!on }\@@frame@@brule + +\letvalue{l\@@frame@@\v!on \v!on}\@@frame@@lrule +\letvalue{l\@@frame@@\v!off\v!on}\@@frame@@lrule +\letvalue{l\@@frame@@\v!on }\@@frame@@lrule + +\letvalue{r\@@frame@@\v!on \v!on}\@@frame@@rrule +\letvalue{r\@@frame@@\v!off\v!on}\@@frame@@rrule +\letvalue{r\@@frame@@\v!on }\@@frame@@rrule + +% no overlapping rules + +\def\@@frame@@trules{\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}\nointerlineskip\kern-\ruledlinewidth} +\def\@@frame@@brules{\kern-\ruledlinewidth\nointerlineskip\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}} +\def\@@frame@@rrules{\kern-\ruledlinewidth\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth} +\def\@@frame@@lrules{\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth\kern-\ruledlinewidth} + +% small is relatively new + +\letvalue{t\@@frame@@\v!small\v!small}\@@frame@@trules +\letvalue{t\@@frame@@\v!off \v!small}\@@frame@@trules +\letvalue{t\@@frame@@\v!small }\@@frame@@trules + +\letvalue{b\@@frame@@\v!small\v!small}\@@frame@@brules +\letvalue{b\@@frame@@\v!off \v!small}\@@frame@@brules +\letvalue{b\@@frame@@\v!small }\@@frame@@brules + +\letvalue{l\@@frame@@\v!small\v!small}\@@frame@@lrules +\letvalue{l\@@frame@@\v!off \v!small}\@@frame@@lrules +\letvalue{l\@@frame@@\v!small }\@@frame@@lrules + +\letvalue{r\@@frame@@\v!small\v!small}\@@frame@@rrules +\letvalue{r\@@frame@@\v!off \v!small}\@@frame@@rrules +\letvalue{r\@@frame@@\v!small }\@@frame@@rrules + +%D I condidered using the low level support command +%D \type{\ruledhbox}, but this would slow down processing by a +%D factor~3. + +% \framed +% [width=4cm,height=3cm,rulethickness=3mm, +% frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on] +% {} +% \framed +% [width=4cm,height=3cm,rulethickness=3mm, +% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small] +% {} +% \framed +% [width=4cm,height=3cm,rulethickness=3mm, +% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on] +% {} + +%D The next few macros are probably the most misused ones in +%D \CONTEXT. They deal with putting rules around boxes, provide +%D backgrounds, offer alignment features, and some more. We +%D start with defining some booleans. These give an impression +%D of what we are going to take into account. + +% todo: chardefs + +\newif\ifboxhasoffset +\newif\ifboxhaswidth +\newif\ifboxhasheight +\newif\ifboxhasformat +\newif\ifboxhasstrut +\newif\ifboxisoverlaid +\newif\ifboxhasframe +\newif\ifdelayedstrut +\newif\ifboxhasextraoffset + +%D We also need a few \DIMENSIONS: + +\newdimen\@@localoffset +\newdimen\@@globalwidth + +%D \macros +%D {framed, setupframed} +%D +%D Ruled boxes are typeset using \type{\framed}. This command +%D is quite versatile and, although some users will probably +%D seldom use it, one cannot overlook its features. +%D +%D \showsetup{setupframed} +%D \showsetup{framed} +%D +%D This general macro is a special version of an even more +%D general case, that can easily be linked into other macros +%D that need some kind of framing. The local version is called +%D with an extra parameter: the variable identifier. The reason +%D for passing this identifier between brackets lays in the +%D mere fact that this way we can use the optional argument +%D grabbers. + +\def\defaultframeoffset{.25ex} + +\def\presetlocalframed [#1]{\letvalue{#1\s!parent}\??oi} +\def\inheritlocalframed[#1]#2[#3]{\letvalue{#1\s!parent}#3} +\def\copylocalframed [#1]#2[#3]{\setvalue{#1\s!parent}{#3}} + +\presetlocalframed[\??ol] + +% \unexpanded\def\framed +% {\bgroup +% \dodoubleempty\startlocalframed[\??ol]} + +\newcount\framednesting + +\unexpanded\def\framed + {\bgroup + \advance\framednesting\plusone + \letvalue{\??ol:\the\framednesting\s!parent}\??ol + \dodoubleempty\startlocalframed[\??ol:\the\framednesting]} + +\def\setupframed + {\dodoubleempty\dosetupframed} + +\def\dosetupframed + {\ifsecondargument + \@EA\dodoublesetupframed + \else + \@EA\dosinglesetupframed + \fi} + +\def\dosinglesetupframed[#1][#2]% + {\getparameters[\??ol][#1]} + +\def\dodoublesetupframed[#1][#2]% + {\bgroup + \let\dodoubleempty\empty + \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}% + \getvalue{#1}% + \egroup + \letvalue{#1}\globalredefinedframed} + +%D \startbuffer +%D \setupframed [framecolor=yellow] \framed{A} +%D \defineframed[myframed] [framecolor=blue] \myframed{B} +%D \setupframed [myframed] [framecolor=red] \myframed{C} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \presetlocalframed[myframed] +%D \setuplocalframed[myframed][width=4cm,height=2cm] +%D \localframed[myframed][framecolor=green]{oeps} +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {ifinframed} +%D +%D The normal case first presets all parameters and next starts +%D looking for the user supplied ones. The first step is +%D omitted in the local case, because these are preset at +%D declaration time and keep their values unless explictly +%D changed. By presetting the variables everytime the normal +%D command is called, we can use this command nested, without +%D the unwanted side effect of inheritance. The boolean is +%D used to speed up the color stack. + +\newif\ifinframed + +\def\localframed + {\bgroup + \dodoubleempty\startlocalframed} + +%D The next one is faster on multiple backgrounds per page. No +%D dimensions can be set, only frames and backgrounds. + +\def\fastlocalframed[#1]#2[#3]#4% 3-4 + {\bgroup + \inframedtrue + \edef\@@framed{#1}% + % some hackery (no \dimexpr) + \scratchdimen\framedparameter\c!frameoffset + \setevalue{\@@framed\c!frameoffset}{\the\scratchdimen}% + \doifnot{\framedparameter\c!backgroundoffset}\v!frame + {\scratchdimen\framedparameter\c!backgroundoffset + \setevalue{\@@framed\c!backgroundoffset}{\the\scratchdimen}}% + % so far + \setbox\framebox\hbox{#4}% + \getparameters[\@@framed][#3]% no \expanded ! + % not here, in calling macro: setups + \removeframedboxdepth + \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}% + \ifx\framedforegroundcolor\empty\else\docolorframebox\fi + \edef\overlaylinecolor{\framedparameter\c!framecolor}% + \edef\overlaylinewidth{\the\ruledlinewidth}% + \edef\@@localframing {\framedparameter\c!frame}% + \ifx\@@localframing\v!overlay \else \ifx\@@localframing\v!none \else + \edef\framedrulethickness{\framedparameter\c!rulethickness}% + \ifx\framedrulethickness\empty\else + \ruledlinewidth\framedrulethickness\relax + \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi + \fi + \dooutlinebox % real or invisible frame + \fi \fi + \edef\framedbackground{\framedparameter\c!background}% + \ifx\framedbackground\empty\else\dobackedbox\fi + \restoreframedboxdepth + \box\framebox + \egroup} + +%D Before we go into details, we present (and implement) the +%D main framing routine. I saw no real reason for splitting the +%D next two macros into smaller pieces. The content will be +%D collected in a horizontal or vertical box with fixed or free +%D dimensions and specific settings concerning aligment and +%D offsets. +%D +%D In the first few lines, we pre||expand the frame and +%D background offsets. We do so, because the can be defined in +%D terms of the main offset. However, see for instance page +%D backgrounds, when \type {#2} sets the offset to \type +%D {overlay}, both offsets become invalid. +%D +%D Because it is used so often the he next macro is (and +%D looks) rather optimized. + +\let\postprocessframebox\relax + +\let\@@framed\s!unknown + +\def\framedparameter #1{\csname\doframedparameter\@@framed#1\endcsname} +\def\framedparameterhash#1{\doframedparameterhash \@@framed#1} + +\def\doframedparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doframedparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\doframedparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doframedparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\doframedparentparameter #1#2{\ifx#1\relax\s!empty\else\doframedparameter #1#2\fi} +\def\doframedparentparameterhash#1#2{\ifx#1\relax \else\doframedparameterhash#1#2\fi} + +% \def\s!root{root} % maybe configurable + +\def\doframedparentparameter#1#2{\ifx#1\relax\doframedrootparameter#2\else\doframedparameter#1#2\fi} +\def\doframedrootparameter #1{\ifcsname\??oi#1\endcsname\??oi#1\else\s!empty\fi} + +\def\dosetframedattributes#1#2% style color + {\edef\fontattributehash {\framedparameterhash#1}% + \edef\colorattributehash{\framedparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +% defaults, kind of isolated now + +\getparameters + [\??oi] + [\c!width=\v!fit, + \c!height=\v!broad, + %\c!lines=, + \c!offset=0.25ex, % \defaultframeoffset + \c!empty=\v!no, + \c!frame=\v!on, + %\c!topframe=, + %\c!bottomframe=, + %\c!leftframe=, + %\c!rightframe=, + \c!radius=.5\bodyfontsize, + \c!rulethickness=\linewidth, + \c!corner=\v!rectangular, + \c!depth=\!!zeropoint, + %\c!foregroundcolor=, + %\c!foregroundstyle=, + %\c!background=, + %\c!backgroundscreen=, + %\c!backgroundcolor=, + \c!backgroundoffset=\!!zeropoint, + %\c!framecolor=, + \c!frameoffset=\!!zeropoint, + \c!backgroundcorner=\framedparameter\c!corner, + \c!backgroundradius=\framedparameter\c!radius, + \c!backgrounddepth=\framedparameter\c!depth, + \c!framecorner=\framedparameter\c!corner, + \c!frameradius=\framedparameter\c!radius, + \c!framedepth=\framedparameter\c!depth, + %\c!component=, + %\c!align=, + \c!bottom=\vss, + %\c!top=, + \c!strut=\v!yes, + \c!autostrut=\v!yes, + \c!location=\v!normal, + %\c!orientation=, + \c!autowidth=\v!yes, + %\c!setups= +] + +\getparameters + [\??od] % for fast version + [\c!frame=\v!off, + \c!depth=\zeropoint, + \c!offset=\v!overlay, + %\c!component=, + \c!radius=.5\bodyfontsize, + \c!rulethickness=\linewidth, + \c!corner=\v!rectangular, + \c!backgroundoffset=\!!zeropoint, + \c!frameoffset=\!!zeropoint, + \c!backgroundcorner=\framedparameter\c!corner, + \c!backgroundradius=\framedparameter\c!radius, + \c!backgrounddepth=\framedparameter\c!depth, + \c!framecorner=\framedparameter\c!corner, + \c!frameradius=\framedparameter\c!radius, + \c!framedepth=\framedparameter\c!depth, + \c!location=\v!normal] + +% so far + +\newdimen\!!framedwidth +\newdimen\!!framedheight +\newdimen\!!framedscratch % so that users can use \scratchdimen + +\let\setextraframedoffsets \relax +\let\applyextraframedoffsets\relax + +\def\startlocalframed[#1][#2]% + {\bgroup + \inframedtrue + \edef\@@framed{#1}% + % this piece of pre expansion is needed (sometimes used circular) + \!!framedscratch\framedparameter\c!frameoffset + \setevalue{\@@framed\c!frameoffset}{\the\!!framedscratch}% + \doifnot{\framedparameter\c!backgroundoffset}\v!frame + {\!!framedscratch\framedparameter\c!backgroundoffset + \setevalue{\@@framed\c!backgroundoffset}{\the\!!framedscratch}}% + % to prevent deadlock in case of self refering + \ifsecondargument % faster + \getparameters[\@@framed][#2]% here ! + \fi + % new, experimental dirty hook + \framedparameter\c!extras + % to get the right spacing + \doifsomething{\framedparameter\c!foregroundstyle} + {\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}% + % beware, both the frame and background offset can be overruled + % + \edef\doframedsetups{\framedparameter\c!setups}% + \ifx\doframedsetups\empty\else + \edef\doframedsetups{\noexpand\setups[\doframedsetups]}% + \fi + % the next macros are visible + \edef\localoffset{\framedparameter\c!offset}% + \edef\localwidth {\framedparameter\c!width}% + \edef\localheight{\framedparameter\c!height}% + \edef\localformat{\framedparameter\c!align}% + \edef\localstrut {\framedparameter\c!strut}% + % these are not + \edef\@@localautostrut {\framedparameter\c!autostrut}% + \edef\@@localframing {\framedparameter\c!frame}% + \edef\@@locallocation {\framedparameter\c!location}% + \edef\@@localorientation{\framedparameter\c!orientation}% + % + \edef\@@localautowidth {\framedparameter\c!autowidth}% + % + \ifx\@@localframing\v!overlay % no frame, no offset, no framewidth + \boxhasframefalse + \let\localoffset\v!overlay + \else\ifx\@@localframing\v!none % no frame, no framewidth + \boxhasframefalse + \else + \boxhasframetrue + \fi\fi + \ifboxhasframe + \edef\framedrulethickness{\framedparameter\c!rulethickness}% + \ifx\framedrulethickness\empty\else + \ruledlinewidth\framedrulethickness\relax + \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi + \fi + \else + \ruledlinewidth\zeropoint + \fi + \ifx\localformat\empty + \boxhasformatfalse + \else + \boxhasformattrue + \dosetraggedcommand\localformat + \edef\dobeforeframedbox{\raggedtopcommand\framedparameter\c!top}% + \edef\doafterframedbox {\framedparameter\c!bottom\raggedbottomcommand}% + \fi + \ifx\localoffset\v!none + \boxhasoffsetfalse + \boxhasstrutfalse + \boxisoverlaidfalse + \@@localoffset\ruledlinewidth + \else\ifx\localoffset\v!overlay + % \ifx\@@localframing\v!no \boxhasframefalse \fi % test first + \boxhasoffsetfalse + \boxhasstrutfalse + \boxisoverlaidtrue + \@@localoffset\zeropoint + \else + \boxhasoffsettrue + \boxhasstruttrue + \boxisoverlaidfalse + \ifx\localoffset\v!default % new per 2-6-2000 + \let\localoffset\defaultframeoffset + \letvalue{\@@framed\c!offset}\defaultframeoffset + \else + \let\defaultframeoffset\localoffset + \fi + \@@localoffset\dimexpr\localoffset+\ruledlinewidth\relax + \fi\fi + \!!framedheight\zeropoint + \!!framedwidth \zeropoint + \ifx\localwidth\v!fit + \ifboxhasformat + \boxhaswidthtrue + \!!framedwidth\hsize + \else + \boxhaswidthfalse + \fi + \else\ifx\localwidth\v!fixed % equals \v!fit but no shapebox + \ifboxhasformat + \boxhaswidthtrue + \!!framedwidth\hsize + \else + \boxhaswidthfalse + \fi + \else\ifx\localwidth\v!broad + \boxhaswidthtrue + \!!framedwidth\hsize + \else\ifx\localwidth\v!local + \boxhaswidthtrue + \setlocalhsize + \!!framedwidth\localhsize + \else + \boxhaswidthtrue + \!!framedwidth\localwidth + \fi\fi\fi\fi + \ifx\localheight\v!fit + \boxhasheightfalse % no longer: \boxhasstrutfalse + \else\ifx\localheight\v!broad + \boxhasheightfalse + \else + \boxhasheighttrue + \!!framedheight\localheight + \fi\fi + \ifboxhasheight + % obey user set height, also downward compatible + \else + \doifsomething{\framedparameter\c!lines} + {\ifcase\framedparameter\c!lines\else + \!!framedheight\framedparameter\c!lines\lineheight + \edef\localheight{\the\!!framedheight}% + \boxhasheighttrue + \fi}% + \fi + % this is now an option: width=local + % + % \ifdim\!!framedwidth=\hsize + % \parindent\zeropoint + % \setlocalhsize + % \!!framedwidth\localhsize + % \fi + % i.e. disable (colsetbackgroundproblemintechniek) + \advance\!!framedwidth -2\@@localoffset + \advance\!!framedheight -2\@@localoffset + \ifx\localstrut\v!no + \boxhasstrutfalse + \else\ifx\localstrut\v!global + \setstrut + \else\ifx\localstrut\v!local + \setfontstrut + \else + \setstrut + \fi\fi\fi + \ifboxhasstrut + \let\localbegstrut\begstrut + \let\localendstrut\endstrut + \let\localstrut \strut + \else + \let\localbegstrut\pseudobegstrut % was: \relax + \let\localendstrut\pseudoendstrut % was: \relax + \let\localstrut \pseudostrut % was: \relax + %\ifboxhasheight\ifdim\!!framedheight<\strutht % saveguard + % \let\localbegstrut\relax % but not that + % \let\localstrut \relax % save after all + %\fi\fi + \fi + \ifx\@@localautostrut\v!yes + \let\delayedbegstrut\relax + \let\delayedendstrut\relax + \let\delayedstrut \relax + \else + \let\delayedbegstrut\localbegstrut + \let\delayedendstrut\localendstrut + \let\delayedstrut \localstrut + \let\localbegstrut \relax + \let\localendstrut \relax + \let\localstrut \relax + \fi + \ifboxhasheight + \let\\\vboxednewline + \ifboxhaswidth + \let\hairline\vboxedhairline + \ifboxhasformat + \let\next\doformatboxSomeFormat + \else + \let\next\doformatboxNoFormat + \fi + \else + \let\hairline\hboxedhairline + \ifboxhasformat + \let\next\doformatboxHeight + \else + \let\next\doformatboxVSize + \fi + \fi + \else + \ifboxhaswidth + \ifboxhasformat + \let\hairline\vboxedhairline + \let\\\vboxednewline + \let\next\doformatboxWidth + \else + \let\hairline\hboxedhairline + \let\\\hboxednewline + \let\next\doformatboxHSize + \fi + \else + \let\hairline\hboxedhairline + \let\\\hboxednewline + \let\next\doformatboxNoSize + \fi + \fi + \setextraframedoffsets + \edef\framedwidth % a new feature, visible for user + {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}% + \edef\framedheight% a new feature, visible for user + {\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}% + % we need to register the (outer) color + \startregistercolor[\framedparameter\c!foregroundcolor]% + % first alternative + %\def\dowithframedbox% + % {\let\postprocessframebox\relax %new + % \aftergroup\stoplocalframed}% + % \afterassignment\dowithframedbox + % \setbox\framebox=\next} + % second alternative + %\dowithnextbox + % {\setbox\framebox\flushnextbox + % \let\postprocessframebox\relax %new + % \stoplocalframed} + % \next} + \@@startframedorientation + \afterassignment\dodowithframebox + \setbox\framebox\next} + +\def\dowithframebox + {% moved : \let\postprocessframebox\relax + \stoplocalframed} + +\def\dodowithframebox + {\aftergroup\dowithframebox} + +\let\doafterframedbox \relax +\let\dobeforeframedbox\relax + +%D Carefull analysis of this macro will learn us that not all +%D branches in the last conditionals can be encountered, that +%D is, some assignments to \type{\next} will never occur. +%D Nevertheless we implement the whole scheme, if not for +%D future extensions. + +%D \macros +%D {ifreshapeframebox} +%D +%D The last few lines tell what to do after the content of the +%D box is collected and passed to the next macro. In the case +%D of a fixed width and centered alignment, the content is +%D evaluated and used to determine the most natural width. The +%D rest of the code deals with backgrounds and frames. + +\newif\ifreshapeframebox \reshapeframeboxtrue + +%D Beware: setting \type {top} and \type {bottom} to nothing, may +%D result in a frame that is larger that the given height! try: +%D +%D \starttyping +%D \framed +%D [height=3cm,top=,bottom=,offset=overlay] +%D {\strut test \shapefill \strut test} +%D \stoptyping +%D +%D This is intended behaviour and not a bug! One can always set +%D +%D \starttyping +%D ...,bottom=\kern0pt,... +%D \stoptyping + +\def\stoplocalframed + {\dontshowcomposition + \@@stopframedorientation % hm, wrong place ! should rotate the result (after reshape) + \stopregistercolor + \handleframedlocator\c!before\@@locallocation + \ifboxhasformat + \ifx\@@localautowidth\v!force + \ifreshapeframebox\doreshapeframedbox\fi + \boxhaswidthfalse + \else + \ifx\localwidth\v!fit + \ifx\@@localautowidth\v!yes + \ifreshapeframebox\doreshapeframedbox\fi + \fi + \boxhaswidthfalse + \else\ifx\localwidth\v!fixed + \boxhaswidthfalse + \else + \resetshapeframebox + \fi\fi + \fi +\ifconditional\boxcontentneedsprocessing + \mkdoprocessboxcontents\framebox +\fi + \else + \resetshapeframebox + \fi + \ifboxhaswidth + \wd\framebox\!!framedwidth + \fi + \ifboxhasheight + \ht\framebox\!!framedheight + \fi + \doif{\framedparameter\c!empty}\v!yes + {\setbox\scratchbox\null + \wd\scratchbox\wd\framebox + \ht\scratchbox\ht\framebox + \dp\scratchbox\dp\framebox + \setbox\framebox\box\scratchbox}% + \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}% + \ifx\framedforegroundcolor\empty\else\docolorframebox\fi + \ifboxhasextraoffset + \applyextraframedoffsets + \fi + \ifboxhasoffset + \dooffsetframebox + \fi + \ifboxisoverlaid \else + \dolocateframebox + \fi + \ifx\postprocessframebox\relax \else + \let\next\postprocessframebox + \let\postprocessframebox\relax % prevent nesting + \next\framebox + \fi + \edef\overlaylinecolor{\framedparameter\c!framecolor}% + \edef\overlaylinewidth{\the\ruledlinewidth}% \@@... + \ifboxhasframe % real or invisible frame + \dooutlinebox + \fi + \edef\framedbackground{\framedparameter\c!background}% + \ifx\framedbackground\empty\else\dobackedbox\fi + \handleframedlocator\c!after\@@locallocation + \box\framebox + \egroup + \egroup} + +\def\installframedlocator#1#2#3% + {\setvalue{\??oi:\c!location:\c!before:#1}{#2}% + \setvalue{\??oi:\c!location:\c!after :#1}{#3}} + +\def\handleframedlocator#1#2% + {\getvalue{\??oi:\c!location:#1:#2}} + +\def\doprelocframedbox#1% + {\scratchdimen\dimexpr#1+\ruledlinewidth\relax + \ifboxhasoffset + \advance\scratchdimen \framedparameter\c!offset + \fi + \scratchskip\dimexpr\ht\framebox-\scratchdimen\relax} + +% \ruledhbox +% {A +% \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging} +% \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth} +% \framed[width=2cm,align=middle,location=height] {location\\equals\\height} +% B} +% \vskip2cm +% \ruledhbox +% {A +% \framed[width=2cm,align=middle,location=low] {location\\equals\\low} +% \framed[width=2cm,align=middle,location=line] {location\\equals\\line} +% \framed[width=2cm,align=middle,location=high] {location\\equals\\high} +% B} +% \vskip2cm +% \ruledhbox +% {A +% \framed[width=2cm,align=middle,location=top] {location\\equals\\top} +% \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom} +% \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi} +% \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle} +% B} + +\installframedlocator \v!hanging % best with strut=no + {} + {\dp\framebox\ht\framebox + \ht\framebox\zeropoint} + +\installframedlocator \v!depth + {} + {\ht\framebox\dimexpr\ht\framebox-\strutdp\relax + \dp\framebox\strutdp + \box\framebox} + +\installframedlocator \v!height + {} + {\dp\framebox\dimexpr\ht\framebox-\strutht\relax + \ht\framebox\strutht + \box\framebox} + +\installframedlocator \v!high + {} + {\doprelocframedbox\strutht + \setbox\framebox\hbox{\lower\scratchskip\box\framebox}% + \ht\framebox\strutht + \dp\framebox\strutdp + \hbox{\box\framebox}} + +\installframedlocator \v!line + {} + {\setbox\framebox\hbox{\lower.5\ht\framebox\box\framebox}% + \ht\framebox.5\lineheight + \dp\framebox.5\lineheight + \hbox{\box\framebox}} + +\installframedlocator \v!low + {} + {\doprelocframedbox\strutdp + \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% + \ht\framebox\strutht + \dp\framebox\strutdp + \box\framebox} + +\installframedlocator \v!top + {} + {\doprelocframedbox\strutht + \setbox\framebox\hbox{\lower\scratchskip\box\framebox}% + \ht\framebox\scratchdimen + \dp\framebox\scratchskip + \hbox{\box\framebox}} + +\installframedlocator \v!middle + {} + {\scratchdimen.5\ht\framebox + \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% + \ht\framebox\scratchdimen + \dp\framebox\scratchdimen + \hbox{\box\framebox}} + +\installframedlocator \v!lohi + {\handleframedlocator\c!before\v!middle} + {\handleframedlocator\c!after \v!middle} + +\installframedlocator \v!bottom + {} + {\doprelocframedbox\strutdp + \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% + \ht\framebox\scratchskip + \dp\framebox\scratchdimen + \hbox{\box\framebox}} + +\installframedlocator \v!keep % retains height/depth + {\removeframedboxdepth} + {\restoreframedboxdepth} + +% also used in fastlocalframed + +\newdimen\originalframedwd +\newdimen\originalframedht +\newdimen\originalframeddp + +\def\removeframedboxdepth + {\originalframedwd\wd\framebox + \originalframedht\ht\framebox + \originalframeddp\dp\framebox + \ifzeropt\originalframeddp\else\setbox\framebox\hbox{\raise\originalframeddp\box\framebox}\fi + \wd\framebox\originalframedwd + \ht\framebox\dimexpr\originalframedht+\originalframeddp\relax + \dp\framebox\zeropoint} + +\def\restoreframedboxdepth + {\ifzeropt\originalframeddp\else\setbox\framebox\hbox{\lower\originalframeddp\box\framebox}\fi + \wd\framebox\originalframedwd + \ht\framebox\originalframedht + \dp\framebox\originalframeddp} + +% \let\@@startframedorientation\relax +% \let\@@stopframedorientation \relax + +% \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax} +% \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax} +% \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax} +% \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax} +% \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax} +% \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax} +% \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax} + +\def\@@startframedorientation + {\let\@@stopframedorientation \relax + \ifx\@@localorientation\empty\else + \ifcase\@@localorientation\else + \scratchcounter\@@localorientation + \divide\scratchcounter\plustwo + \ifodd\scratchcounter + \swapmacros\framedwidth \framedheight + \swapmacros\localwidth \localheight + \swapdimens\!!framedheight\!!framedwidth + \def\@@stopframedorientation{\@@dostopframedorientation\plusone}% + \else + \def\@@stopframedorientation{\@@dostopframedorientation\zerocount}% + \fi + \fi + \fi} + +\def\@@dostopframedorientation#1% + {\ifcase#1\else + \swapmacros\framedwidth \framedheight + \swapmacros\localwidth \localheight + \swapdimens\!!framedheight\!!framedwidth + \fi + \setbox\framebox\hbox{\dorotatebox\@@localorientation\hbox{\box\framebox}}} + +%D The last conditional takes care of the special situation of +%D in||line \inframed[height=3cm]{framed} boxes. Such boxes have +%D to be \inframed{aligned} with the running text. + +\def\doinframed[#1]% we could omit #1] but readibility ... + {\framed[\c!location=\v!low,#1]} + +\unexpanded\def\inframed + {\dosingleempty\doinframed} + +%D When we set \type{empty} to \type{yes}, we get +%D ourselves a frame and/or background, but no content, so +%D actually we have a sort of phantom framed box. + +%D Because color marks and specials can interfere with +%D spacing, we provide a way to specify a foregroundcolor. + +\def\docolorframebox + {\doifcolor\framedforegroundcolor + {\setbox\framebox\hbox{\faststartcolor[\framedforegroundcolor]\box\framebox\faststopcolor}}} + %{\setbox\framebox\hbox{\doactivatecolor\framedforegroundcolor\box\framebox}}} + +%D \macros +%D {mframed, minframed} +%D +%D When Tobias asked how to frame mathematical elements in +%D formulas, Taco's posted the next macro: +%D +%D \starttyping +%D \def\mframed#1% +%D {\relax +%D \ifmmode +%D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}% +%D \else +%D \framed{$#1$}% +%D \fi} +%D \stoptyping +%D +%D Because \type {\ifinner} does not (always) reports what +%D one would expect, we move the test to the outer level. We +%D also want to pass arguments, +%D +%D \starttyping +%D \def\mframed% +%D {\dosingleempty\domframed} +%D +%D \def\domframed[#1]#2% % tzt \dowithnextmathbox ? +%D {\relax +%D \ifmmode +%D \ifinner +%D \inframed[#1]{$#2$}% +%D \else +%D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}% +%D \fi +%D \else +%D \inframed[#1]{$#2$}% +%D \fi} +%D \stoptyping +%D +%D Still better is the next alternative, if only because it +%D takes care of setting the super- and subscripts styles + +\newcount\mframedstyle + +\def\doinlinemframed[#1]#2% + {\begingroup + \mframedstyle\mathstyle\relax + \inframed[#1]{$\triggermathstyle\mframedstyle#2$}% + \endgroup} + +\def\dodisplaymframed[#1]#2% + {\begingroup + \mframedstyle\mathstyle\relax + \def\normalstrut{$\triggermathstyle\mframedstyle\vphantom{(}$}% + \framed[#1]{$\triggermathstyle\mframedstyle#2$}% + \endgroup} + +\def\mframed {\dosingleempty\dodisplaymframed} +\def\inmframed{\dosingleempty\doinlinemframed } + +%D So instead of the rather versatile \type {\framed}, we ue +%D the \type {\mframed}. +%D +%D \startbuffer +%D \startformula +%D x \times \mframed{y} \times y^{z_z} +%D x \times \inmframed{y} \times y^{z_z} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D However, we got into troubles when we want to nest sub- and +%D superscripts, like in +%D +%D \startbuffer +%D \startformula +%D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D Therefore, we can best use \type {\super} and \type {\suber} +%D instead of \type {^} and \type {_}. Both commands take care +%D of proper font switching. +%D +%D \startbuffer +%D \startformula +%D x \times \mframed{y} \times y\super{\mframed{z}\suber{\mframed{z}}} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D As usual, one can specify in what way the text should be +%D framed. One should be aware of the fact that, inorder to +%D preserve the proper spacing, the \type {offset} is set to +%D \type {overlay} and \type {frameoffset} is used used +%D instead. +%D +%D \startbuffer +%D \startformula +%D x \times y\super{\mframed[framecolor=red]{z}\suber{z}} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D For inline use, we also provide the \type {\inmframed} +%D alternative: we want $x \times \inmframed{y}$ in inline +%D math, right? + +%D This previous framing macros needs a lot of alternatives for +%D putting rules around boxes, inserting offsets and aligning +%D text. Each step is handled by separate macros. + +\def\dowidenframebox#1% + {\setbox\framebox\vbox + {\kern#1\hbox{\kern#1\box\framebox\kern#1}\kern#1}} + +\def\dooffsetframebox{\dowidenframebox\localoffset} +\def\dolocateframebox{\dowidenframebox\ruledlinewidth} + +%D Let's hope that the next few examples show us enough of +%D what needs to be done by the auxiliary macros. +%D +%D \startbuffer +%D \framed[height=1cm,offset=.5cm] {rule based learning} +%D \framed[height=1cm,offset=0cm] {rule based learning} +%D \framed[height=1cm,offset=none] {rule based learning} +%D \framed[height=1cm,offset=overlay]{rule based learning} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \hbox{\getbuffer} +%D \stoplinecorrection +%D +%D \startbuffer +%D \framed[offset=.5cm] {rule based learning} +%D \framed[offset=0cm] {rule based learning} +%D \framed[offset=none] {rule based learning} +%D \framed[offset=overlay]{rule based learning} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \hbox{\getbuffer} +%D \stoplinecorrection +%D +%D \startbuffer +%D \framed[strut=nee,offset=.5cm] {rule based learning} +%D \framed[strut=nee,offset=0cm] {rule based learning} +%D \framed[strut=nee,offset=none] {rule based learning} +%D \framed[strut=nee,offset=overlay]{rule based learning} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \hbox{\getbuffer} +%D \stoplinecorrection +%D +%D \startbuffer +%D \framed[width=3cm,align=left] {rule\\based\\learning} +%D \framed[width=3cm,align=middle] {rule\\based\\learning} +%D \framed[width=3cm,align=right] {rule\\based\\learning} +%D \framed[width=fit,align=middle] {rule\\based\\learning} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \hbox{\dontcomplain\getbuffer} +%D \stoplinecorrection +%D +%D So now we're ready for the complicated stuff. We distinguish +%D between borders with straight lines and those with round +%D corners. When using the first alternative it is possible to +%D turn off one or more lines. More fancy shapes are also +%D possible by specifying dedicated backgrounds. Turning lines +%D on and off is implemented as efficient as possible and as a +%D result is interface language dependant. This next +%D implementation evolved from simpler ones. It puts for +%D instance the rules on top of the content and provides +%D additional offset capabilities. The lot of calls to other +%D macros makes this mechanism not that easy to comprehend. + +%D Getting the backgrounds right takes less code. Again we +%D have to take care of additional offsets. + +\def\dobackedbox + {\doifelsevalue{\@@framed\c!backgroundoffset}\v!frame % new + {\dobackgroundbox\c!frameoffset} + {\dobackgroundbox\c!backgroundoffset}} + +%D We handle left, right or middle alignment as well as fixed +%D or free widths and heights. Each combination gets its own +%D macro. + +%D The following code handles one-liners: \type{align={line,flushright}}. +%D Beware, since we entered a group and either or not grab the next +%D bgroup token, we need to finish the group in the oneliner mode. + +\ifx\raggedoneliner\undefined \chardef\raggedoneliner\zerocount \fi + +\def\doformatonelinerbox % beware: assumes explicit preceding bgroup + {\ifcase\raggedoneliner + \expandafter\nodoformatonelinerbox + \else + \expandafter\dodoformatonelinerbox + \fi} + +\def\dodoformatonelinerbox + {\dowithnextboxcontent + {\ignorespaces} + {\hbox to \hsize + {\ifcase\raggedstatus\or\hss\or\hss\fi + \unhbox\nextbox \removeunwantedspaces + \ifcase\raggedstatus\or \or\hss\or\hss\fi}% + \egroup} + \hbox} + +\def\nodoformatonelinerbox % grabs { + {\let\next=} + +%D The handlers: + +\def\doformatboxSomeFormat + {\vbox to \!!framedheight + \bgroup + \let\postprocessframebox\relax + \forgetall + \oninterlineskip + \hsize\!!framedwidth + \vsize\!!framedheight + \doframedsetups + \raggedcommand + \dobeforeframedbox + \bgroup + \localbegstrut + \aftergroup\localendstrut + \aftergroup\doafterframedbox + \aftergroup\egroup + \doformatonelinerbox} + +\def\doformatboxNoFormat + {\vbox to \!!framedheight + \bgroup + \let\postprocessframebox\relax + \forgetall + \oninterlineskip + \hsize\!!framedwidth + \vsize\!!framedheight + \doframedsetups + \raggedcenter + \vss + \bgroup + \localbegstrut + \aftergroup\localendstrut + \aftergroup\vss + \aftergroup\egroup + \doformatonelinerbox} + +\def\doformatboxHeight + {\vbox to \!!framedheight + \bgroup + \let\postprocessframebox\relax + \forgetall + \oninterlineskip + \doframedsetups + \raggedcommand + \vss + \bgroup + \aftergroup\localendstrut + \aftergroup\vss + \aftergroup\egroup + \localbegstrut + \doformatonelinerbox} + +\def\doformatboxWidth + {\vbox + \bgroup + \let\postprocessframebox\relax + \forgetall + \oninterlineskip + \hsize\!!framedwidth + \doframedsetups + \raggedcommand + \dobeforeframedbox + \bgroup + \localbegstrut + \aftergroup\localendstrut + \aftergroup\doafterframedbox + \aftergroup\egroup + \doformatonelinerbox} + +\def\doformatboxVSize + {\vbox to \!!framedheight + \bgroup + \let\postprocessframebox\relax + \forgetall + \vsize\!!framedheight + \doframedsetups + \vss + \bgroup + \aftergroup\vss + \aftergroup\egroup + \hbox + \bgroup + \aftergroup\egroup + \localstrut + \doformatonelinerbox} + +\def\doformatboxHSize + {\hbox to \!!framedwidth + \bgroup + \let\postprocessframebox\relax + \forgetall + \doframedsetups + \hss + \localstrut + \bgroup + \aftergroup\hss + \aftergroup\egroup + \doformatonelinerbox} + +\def\doformatboxNoSize + {\hbox + \bgroup + \let\postprocessframebox\relax + \doframedsetups + \localstrut + \doformatonelinerbox} + +\let\doframedsetups\relax + +%D On the next page we show some examples of how these macros +%D come into action. The examples show us how +%D \type {fit}, \type {broad} dimensions influence the +%D formatting. Watch the visualized struts. \footnote {Here we +%D used \type {\showstruts}.} +%D +%D \startpostponing +%D \bgroup +%D \showstruts +%D \dontcomplain +%D \startlinecorrection +%D \halign{#\enskip&#\enskip&#\enskip&#\enskip&#\enskip&#\cr +%D \framed[width=.2\hsize, height=.2\hsize, align=] {a\par b\par c}& +%D \framed[width=.2\hsize, height=broad, align=] {a\par b\par c}& +%D \framed[width=.2\hsize, height=fit, align=] {a\par b\par c}& +%D \framed[width=fit, height=.2\hsize, align=] {a\par b\par c}& +%D \framed[width=fit, height=broad, align=] {a\par b\par c}& +%D \framed[width=fit, height=fit, align=] {a\par b\par c}\cr +%D \noalign{\vskip1em} +%D \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\par b\par c}& +%D \framed[width=.2\hsize, height=broad, align=yes] {a\par b\par c}& +%D \framed[width=.2\hsize, height=fit, align=yes] {a\par b\par c}& +%D \framed[width=fit, height=.2\hsize, align=yes] {a\par b\par c}& +%D \framed[width=fit, height=broad, align=yes] {a\par b\par c}& +%D \framed[width=fit, height=fit, align=yes] {a\par b\par c}\cr +%D \noalign{\vskip1em} +%D \framed[width=.2\hsize, height=.2\hsize, align=right] {a\par b\par c}& +%D \framed[width=.2\hsize, height=broad, align=right] {a\par b\par c}& +%D \framed[width=.2\hsize, height=fit, align=right] {a\par b\par c}& +%D \framed[width=fit, height=.2\hsize, align=right] {a\par b\par c}& +%D \framed[width=fit, height=broad, align=right] {a\par b\par c}& +%D \framed[width=fit, height=fit, align=right] {a\par b\par c}\cr +%D \noalign{\vskip1em} +%D \framed[width=.2\hsize, height=.2\hsize, align=left] {a\par b\par c}& +%D \framed[width=.2\hsize, height=broad, align=left] {a\par b\par c}& +%D \framed[width=.2\hsize, height=fit, align=left] {a\par b\par c}& +%D \framed[width=fit, height=.2\hsize, align=left] {a\par b\par c}& +%D \framed[width=fit, height=broad, align=left] {a\par b\par c}& +%D \framed[width=fit, height=fit, align=left] {a\par b\par c}\cr +%D \noalign{\vskip1em} +%D \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\par b\par c}& +%D \framed[width=.2\hsize, height=broad, align=middle] {a\par b\par c}& +%D \framed[width=.2\hsize, height=fit, align=middle] {a\par b\par c}& +%D \framed[width=fit, height=.2\hsize, align=middle] {a\par b\par c}& +%D \framed[width=fit, height=broad, align=middle] {a\par b\par c}& +%D \framed[width=fit, height=fit, align=middle] {a\par b\par c}\cr} +%D \stoplinecorrection +%D \blank[2*big] +%D \egroup +%D \stoppostponing + +%D \macros +%D {framednoflines, framedlastlength} +%D +%D It is possible to let the frame macro calculate the width +%D of a centered box automatically (\type {fit}). When +%D doing so, we need to reshape the box: + +% The next implementation is frozen! It preserves the depth, +% otherwise we get problems with framed display math and auto +% width. + +\newcount\framednoflines +\newdimen\framedlastlength + +\def\resetshapeframebox + {\framednoflines \zerocount + \framedlastlength\zeropoint} + +\let\framedboxwidth \!!zeropoint +\let\framedboxheight\!!zeropoint +\let\framedboxdepth \!!zeropoint + +\chardef\reshapeframeboxmethod\plusone % 0=no flush, 1=old method 2=no depth messing + +% \newbox\luashapebox +% +% \def\doreshapeframedbox +% {\setbox\luashapebox\box\framebox +% \ctxlua{commands.doreshapeframedbox(\number\luashapebox)}% +% \setbox\framebox\box\luashapebox} + +\def\doreshapeframedbox{\ifvbox\framebox\ctxlua{commands.doreshapeframedbox(\number\framebox)}\fi} + +%D The two variables \type {\framednoflines} and \type +%D {\framedlastlength} can be used in a second pass to +%D optimized framed material. + +% torture test / strange case (much depth) / method 2 needed +% +% \startTEXpage[frame=on] +% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula +% test outside formula +% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula +% \blank[big] +% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula +% test outside formula +% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula +% \stopTEXpage + +%D The examples on the next page show how one can give the +%D frame as well as the background an additional offset and +%D even a bit more depth. The blue outline is the frame, the +%D red box is the background and the small black outline is the +%D visualization of the resulting box, that is, we applied +%D \type{\ruledhbox} to the result. + +%D \startpostponing +%D \bgroup +%D \unprotect +%D \dontcomplain +%D +%D \startbuffer +%D \vbox to \vsize +%D \bgroup +%D \startalignment[middle] +%D \vss +%D \dontleavehmode\vbox to .8\vsize +%D \bgroup +%D \hsize=300pt +%D \setupframed +%D [background=color, +%D backgroundcolorachtergrondkleur=darkred, +%D width=300pt, +%D height=60pt, +%D framecolorkaderkleur=DemoBlue, +%D rulethickness=2pt] +%D \def\status% +%D {backgroundoffset=\framedparameter\c!backgroundoffset\\ +%D frameoffset=\framedparameter\c!frameoffset\\ +%D depth=\framedparameter\c!depth} +%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}} +%D \vss +%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}} +%D \vss +%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}} +%D \vss +%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}} +%D \vss +%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}} +%D \vss +%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}} +%D \egroup +%D \vss +%D \stopalignment +%D \egroup +%D \stopbuffer +%D +%D \getbuffer \page +%D +%D {\setupframed[depth=4pt]\getbuffer} \page +%D +%D \protect +%D \egroup +%D \stoppostponing + +%D When typesetting the framed box inline, we have to keep the +%D baseline intact outside as well as inside the framed box. + +\def\doinlineframedbox + {\scratchdimen\dimexpr\strutdp+\ruledlinewidth\relax + \ifboxhasoffset + \advance\scratchdimen \framedparameter\c!offset + \fi + \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}% + \ht\framebox\strutht + \dp\framebox\strutdp + \box\framebox} + +%D We can also lower the box over the natural depth of the +%D line. + +\def\doloweredframedbox + {\ht\framebox\dimexpr\ht\framebox+\dp\framebox-\strutdp\relax + \dp\framebox\strutdp + \box\framebox} + +%D Hanging the content is mainly meant for cases like the +%D following: +%D +%D \starttyping +%D \framed[strut=no] +%D {\framed[height=2cm,location=hanging]{test}% +%D \framed[height=1cm,location=hanging]{test}} +%D \stoptyping + +\def\dohangingframedbox % best with strut=no + {\scratchdimen\dimexpr\ht\framebox+\dp\framebox\relax + \ht\framebox\zeropoint + \dp\framebox\scratchdimen} + +%D We can draw lines from left to right and top to bottom by +%D using the normal \type{\hairline} command. Both directions +%D need a different treatment. +%D +%D \startbuffer +%D \framed[width=4cm] {alfa\hairline beta\hairline gamma} +%D \framed[height=2cm] {alfa\hairline beta\hairline gamma} +%D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \hbox{\getbuffer} +%D \stoplinecorrection +%D +%D These macros try to adapt their behaviour as good as +%D possible to the circumstances and act as natural as +%D possible. + +\def\vboxedhairline + {\bgroup + \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi + \dimen4=\dimexpr\dimen2+\ruledlinewidth\relax + \setbox0\vbox + {\advance\hsize 2\dimen4 + \vskip\dimen2 + \hrule + \!!height\ruledlinewidth + \!!depth\zeropoint + \!!width\hsize + \vskip\dimen2}% + %\endgraf\nointerlineskip\endgraf + %\moveleft\dimen4\box0 + %\endgraf\nointerlineskip\localbegstrut + \endgraf\obeydepth\nointerlineskip + \moveleft\dimen4\box0 + \endgraf\nointerlineskip\localbegstrut % beware, we might kill it in a style using \vskip\lineheight + \egroup} % so this must not be changed + +\def\hboxedhairline % use framed dimen + {\bgroup + \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi + \ifboxhasheight + \dimen4\dimexpr\localheight/2+\strutdp-2\ruledlinewidth\relax + \dimen6\dimexpr\localheight/2-\strutdp+2\ruledlinewidth\relax + \else + \dimen4\dimexpr\strutht+\dimen2\relax + \dimen6\dimexpr\strutdp+\dimen2\relax + \fi + \unskip + \setbox\scratchbox\hbox + {\hskip\dimen2 + \vrule\!!height\dimen4\!!depth\dimen6\!!width\ruledlinewidth + \hskip\dimen2}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \box\scratchbox + \ignorespaces + \egroup} + +%D The argument of the frame command accepts \type{\\} as a +%D sort of newline signal. In horizontal boxes it expands to a +%D space. + +\def\vboxednewline + {\endgraf\ignorespaces} + +\def\hboxednewline + {\unskip\normalspace\ignorespaces} + +%D We can set each rule on or off. The default setting is +%D inherited from \type{frame}. An earlier implementation +%D use a bit different approach, but the new one seems more +%D natural: +%D +%D \bgroup +%D \setuptyping[margin=0pt] +%D \startlinecorrection +%D \startbuffer +%D \framed[offset=overlay,frame=on]{\darkred\blackrule} +%D \stopbuffer +%D \hbox{\getbuffer\vbox{\typebuffer}} +%D +%D \startbuffer +%D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule} +%D \stopbuffer +%D \hbox{\getbuffer\vbox{\typebuffer}} +%D +%D \startbuffer +%D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule} +%D \stopbuffer +%D \hbox{\getbuffer\vbox{\typebuffer}} +%D +%D \startbuffer +%D \framed[offset=overlay,frame=off]{\darkred\blackrule} +%D \stopbuffer +%D \hbox{\getbuffer\vbox{\typebuffer}} +%D +%D \startbuffer +%D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule} +%D \stopbuffer +%D \hbox{\getbuffer\vbox{\typebuffer}} +%D +%D \startbuffer +%D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule} +%D \stopbuffer +%D \hbox{\getbuffer\vbox{\typebuffer}} +%D \stoplinecorrection +%D \egroup + +%D \macros +%D {setupblackrules} +%D +%D The graphic capabilities of \TEX\ do not go beyond simple +%D filled rules, except of course when using specials. Let's +%D start with a warning: using this commands is far more slower +%D than using the \TEX\ primitives \type{\hrule} and +%D \type{\vrule}, but they save us some tokens. The +%D characteristics of these rule drawing command can be set by: +%D +%D \showsetup{setupblackrules} + +\def\setupblackrules + {\dodoubleargument\getparameters[\??bj]} + +%D \macros +%D {blackrule} +%D +%D The simple command draws only one rule. Its optional +%D argument can be used to specify the dimensions. By setting +%D the width, height or depth to \type {max}, one gets the +%D natural dimensions. +%D +%D \showsetup{blackrule} + +\def\doblackrule[#1]% + {\hbox\bgroup + \getparameters[\??bj][#1]% + \setstrut + \doif\@@bjwidth \v!max{\def\@@bjwidth {1em}}% + \doif\@@bjheight\v!max{\def\@@bjheight{\strutht}}% + \doif\@@bjdepth \v!max{\def\@@bjdepth {\strutdp}}% + \localstartcolor[\@@bjcolor]% + \vrule + \!!width \@@bjwidth + \!!height\@@bjheight + \!!depth \@@bjdepth + \localstopcolor + \egroup} + +\unexpanded\def\blackrule + {\dosingleempty\doblackrule} + +%D \macros +%D {blackrules} +%D +%D One can call for a sequence of black rules, if needed +%D equally spaced over the given width. +%D +%D \showsetup{blackrules} +%D +%D The two alternative calls are therefore: +%D +%D \startbuffer +%D Tell me, is this according to the \blackrules[n=6]? +%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear. +%D \stopbuffer +%D +%D \typebuffer +%D +%D or: +%D +%D \startvoorbeeld +%D \startlines +%D \getbuffer +%D \stoplines +%D \stopvoorbeeld +%D +%D We could of course have implemented this macro using +%D \type{\leaders}, but this would probably have taken more +%D tokens. + +\def\doblackrules[#1]% + {\hbox\bgroup + \getparameters[\??bj][#1]% + \!!widtha\@@bjwidth + \!!widthb\@@bjdistance + \doif\@@bjalternative\c!b + {\scratchcounter\@@bjn + \ifnum\scratchcounter=\plusone + \!!widthb\zeropoint + \else + \advance\scratchcounter \minusone + \advance\!!widtha -\scratchcounter\!!widthb + \divide \!!widtha \@@bjn + \fi}% + \localstartcolor[\@@bjcolor]% + \dorecurse\@@bjn + {\vrule + \!!width \!!widtha + \!!height\@@bjheight + \!!depth \@@bjdepth + \hskip\!!widthb}% + \unskip + \localstopcolor + \egroup} + +\unexpanded\def\blackrules + {\dosingleempty\doblackrules} + +%D The next commands can be used to draw margin rules. We +%D support two methods: \marginrule{one for in||line use} and +%D one that acts on a paragraph. Drawing a margin rule is +%D rather straightforward because we can use the commands that +%D put text in the margin. + +\def\dodrawmarginrule + {\setbox\scratchbox\hbox + {\vrule\!!depth\strutdepth\!!height\strutheight\!!width\@@karulethickness}% + \smashbox\scratchbox % no \vsmash !!! + \box\scratchbox} + +\def\drawmarginrule + {\strut\inleft{\dodrawmarginrule}} + +%D \macros +%D {marginrule} +%D +%D The first method gobbles words and simply puts a bar in the +%D margin. This method is not entirely robust. +%D +%D \showsetup{marginrule} + +\definecomplexorsimple\marginrule + +\def\simplemarginrule + {\let\processword\drawmarginrule + \processwords} + +\def\complexmarginrule[#1]% + {\ifnum#1<\@@kalevel\relax \else + \def\@@kadefaultwidth{#1}% + \expandafter\simplemarginrule + \fi} + +%D We need an auxiliary variable + +\def\@@kadefaultwidth{1} + +%D \macros +%D {setupmarginrules} +%D +%D This macro definitions show us that we can pass an optional +%D level, which is matched against the previous set one. The +%D level can be set up with +%D +%D \showsetup{setupmarginrules} + +\def\setupmarginrules + {\dodoubleargument\getparameters[\??ka]} + +%D \macros +%D {startmarginrule} +%D +%D The second method collects text and reformats it afterwards, +%D using the shapebox macros. We prevent local margin rules. +%D +%D \showsetup{startmarginrule} + +\definecomplexorsimple\startmarginrule + +\def\simplestartmarginrule + {\bgroup + \let\drawmarginrule\relax + \let\stopmarginrule\dostopmarginrule + \beginofshapebox} + +\def\complexstartmarginrule[#1]% + {\bgroup + \let\drawmarginrule\relax + \ifnum#1<\@@kalevel\relax + \let\stopmarginrule\egroup + \else + \def\@@kadefaultwidth{#1}% + \let\stopmarginrule\dostopmarginrule + \expandafter\beginofshapebox + \fi} + +\def\dostopmarginrule + {\endofshapebox + \reshapebox + {\hbox{\inleftmargin{\dodrawmarginrule}\box\shapebox}}% + \flushshapebox + \egroup} + +%D \startbuffer +%D \setupmarginrules[level=5] +%D +%D \startmarginrule[1] +%D First we set the level at~5. Next we typeset this first +%D paragraph as a level~1 one. As expected no rule show up. +%D \stopmarginrule +%D +%D \startmarginrule[5] +%D The second paragraph is a level~5 one. As we can see here, +%D the marginal rule gets a width according to its level. +%D \stopmarginrule +%D +%D \startmarginrule[8] +%D It will of course be no surprise that this third paragraph +%D has a even thicker margin rule. This behavior can be +%D overruled by specifying the width explictly. +%D \stopmarginrule +%D \stopbuffer +%D +%D In next example we show most features. Watch the rule +%D thickness adapting itself to the level. +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D We just said: +%D +%D \typebuffer + +%D \macros +%D {vl, hl} +%D +%D The command \type{\vl} draws a vertical rule \vl\ with strut +%D dimensions, multiplied with the factor specified in the +%D optional argument. The height and depth are clipped \vl[3] +%D to the baselinedistance. Its horizontal counterpart +%D \type{\hl} draws a horizontal rule \hl\ with a width of 1em, +%D multiplied with the optional factor. The horizontal rule is +%D drawn on top of the baseline. +%D +%D \showsetup{vl} +%D \showsetup{hl} + +\def\complexvl[#1]% + {\bgroup + \!!dimena#1\strutht + \!!dimenb#1\strutdp + \setbox\scratchbox\hbox + {\vrule + \!!width \linewidth + \!!height\!!dimena + \!!depth \!!dimenb}% + \dp\scratchbox\strutdp + \ht\scratchbox\strutht + \box\scratchbox + \egroup} + +\def\complexhl[#1]% + {\hbox + {\vrule + \!!width #1\s!em + \!!height\linewidth + \!!depth \zeropoint}} + +\definecomplexorsimple\vl \def\simplevl{\complexvl[1]} +\definecomplexorsimple\hl \def\simplehl{\complexhl[1]} + +%D \macros +%D {hairline, thinrule, thinrules, setupthinrules} +%D +%D Drawing thin lines can of course easily be accomplished by +%D the \TEX\ primitives \type{\hrule} and \type{\vrule}. The +%D next few macros however free us from some specifications. +%D +%D \startbuffer +%D some text +%D +%D \hairline +%D +%D some more text +%D +%D \thinrule +%D +%D more and more text +%D +%D hi \thinrule\ there +%D +%D and then the final text +%D \stopbuffer +%D +%D \typebuffer +%D +%D becomes +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D So we've got +%D +%D \showsetup{hairline} +%D \showsetup{thinrule} +%D +%D Both can be set up with: +%D +%D \showsetup{setupthinrules} +%D +%D We also have +%D +%D \showsetup{thinrules} +%D +%D which looks like: \thinrules[n=2] + +\def\thinrule + {\strut + \bgroup + \chardef\ruletype\plusone + \processaction + [\@@dlalternative] + [ \v!a=>\chardef\ruletype0,% no line + %\v!b=>\chardef\ruletype1,% height/depth + \v!c=>\chardef\ruletype2,% topheight/botdepth + % 11=>\chardef\ruletype1,% fallback for backgrounds + 0=>\chardef\ruletype0,% compatible with backgrounds + % 1=>\chardef\ruletype1,% compatible with backgrounds + 2=>\chardef\ruletype2]% compatible with backgrounds + \doifsomething\@@dlrulethickness + {\linewidth\@@dlrulethickness}% + \ifdim\linewidth=\zeropoint + \chardef\ruletype\zerocount + \else + \doifnot\@@dlframe\v!on{\chardef\ruletype\zerocount}% + \fi + \ifnum\ruletype=\plusone + \doif\@@dlheight\v!max{\let\@@dlheight\!!plusone}% + \doif\@@dldepth \v!max{\let\@@dldepth \!!plusone}% + \else + \let\@@dlheight\!!plusone + \let\@@dldepth\!!plusone + \fi + \freezedimensionwithunit\@@dlheight\strutht + \freezedimensionwithunit\@@dldepth\strutdp + \divide\linewidth \plustwo + \doifelse\@@dlbackground\v!color + {\startcolor[\@@dlbackgroundcolor]% + \ifnum\ruletype=\plustwo % prevent overshoot due to rounding + \leaders + \hrule + \!!height\dimexpr\@@dlheight-.5\linewidth\relax + \!!depth \dimexpr\@@dldepth -.5\linewidth\relax + \hfill + \else + \leaders + \hrule + \!!height\@@dlheight + \!!depth \@@dldepth + \hfill + \fi + \stopcolor + \ifcase\ruletype + % no rule + \or + \startcolor[\@@dlcolor]% + \hfillneg + \leaders\hrule\!!height\linewidth\!!depth\linewidth\hfill + \stopcolor + \or + \startcolor[\@@dlcolor]% + \hfillneg\leaders\hrule\!!height\dimexpr-\@@dldepth+\linewidth\relax\!!depth\@@dldepth\hfill + \hfillneg\leaders\hrule\!!height\@@dlheight\!!depth\dimexpr-\@@dlheight+\linewidth\relax\hfill + \stopcolor + \fi} + {\ifcase\ruletype \else + \startcolor[\@@dlcolor]% + \leaders\hrule\!!height\@@dlheight\!!depth\@@dldepth\hfill + \stopcolor + \fi}% + \strut + \carryoverpar\egroup} + +\def\hairline + {\endgraf + \thinrule + \endgraf} + +\def\dosetupthinrules[#1]% + {\getparameters[\??dl][#1]} + +\def\setupthinrules + {\dosingleargument\dosetupthinrules} + +\def\dothinrules[#1]% + {\bgroup + \dosetupthinrules[#1]% + \@@dlbefore + \assignvalue\@@dlinterlinespace\@@dlinterlinespace{1.0}{1.5}{2.0}% + \spacing\@@dlinterlinespace + \dorecurse\@@dln + {\ifnum\recurselevel=\@@dln \dothinrulesnobreak \else + \ifnum\recurselevel=2 \dothinrulesnobreak \fi\fi + \thinrule + \ifnum\recurselevel<\@@dln\relax + % test needed, else messed up whitespace + \ifx\@@dlinbetween\empty + \softbreak + \else + \endgraf + \nowhitespace + \@@dlinbetween + \fi + \fi}% + \doifelsenothing\@@dlafter + {\carryoverpar\egroup} + {\@@dlafter\egroup}} + +\def\thinrules + {\dosingleempty\dothinrules} + +%D A couple of examples are given below. +%D +%D \startbuffer +%D \setupthinrules[n=3,inbetween=,color=gray] +%D +%D test test \thinrules\ test test \par +%D test test \thinrules [color=green] test test \par +%D test test \thinrules [height=max, depth=max] test test \par +%D +%D \setupthinrules[height=.9,depth=.9] +%D +%D test test \thinrules\ test test \par +%D test test \thinrules [alternativevariant=b] test test \par +%D test test \thinrules [alternativevariant=c] test test \par +%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par +%D \stopbuffer +%D +%D \typebuffer {\getbuffer} +%D +%D There are a couple of alternative ways to visualize rules +%D using backgrounds. At first sight these may look strange, +%D but they make sense in educational settings. The +%D alternatives are more or less compatible with the more +%D advanced \METAPOST\ based implementation. +%D +%D \startbuffer[a] +%D \setupthinrules +%D [n=2, +%D backgroundcolor=gray , +%D rulethickness=1pt, +%D colorkleur=donkerblauw, +%D after=\blank, +%D before=\blank] +%D \stopbuffer +%D +%D \typebuffer[a] +%D +%D \startbuffer[b] +%D \thinrules[alternativevariant=a] +%D \thinrules[alternativevariant=b] +%D \thinrules[alternativevariant=c] +%D \stopbuffer +%D +%D \typebuffer[b] \getbuffer[a,b] +%D +%D \startbuffer[b] +%D \thinrules[alternativevariant=a,background=color] +%D \thinrules[alternativevariant=b,background=color] +%D \thinrules[alternativevariant=c,background=color] +%D \stopbuffer +%D +%D \typebuffer[b] \getbuffer[a,b] +%D +%D \startbuffer[b] +%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color] +%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color] +%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color] +%D \stopbuffer +%D +%D \typebuffer[b] \getbuffer[a,b] + +%D \macros +%D {optimizethinrules} +%D +%D By saying \type {\thinrulestrue} or \type {-false}, we +%D can influence the way dangling lines are handled. + +\newif\ifoptimizethinrules \optimizethinrulestrue + +\def\dothinrulesnobreak + {\ifoptimizethinrules\penalty500\fi} + +%D \macros +%D {startframedtext, setupframedtexts, defineframedtext} +%D +%D The general framing command we discussed previously, is not +%D entirely suited for what we call framed texts, as for +%D instance used in intermezzo's. The next examples show what +%D we have in mind. +%D +%D \startbuffer[framed-0] +%D \setupframedtexts +%D [frame=off, +%D width=\hsize, +%D background=screen] +%D +%D \startframedtext +%D By default the framed text is centered \dots +%D \stopframedtext +%D +%D \startframedtext[right] +%D \dots\ but we can also align left, middle and right. +%D \stopframedtext +%D \stopbuffer +%D +%D \startbuffer[framed-1] +%D \defineframedtext +%D [Example] +%D [width=6cm, +%D height=5cm] +%D +%D \startExample +%D \typebuffer[framed-1] +%D \stopExample +%D \stopbuffer +%D +%D \startbuffer[framed-2] +%D \defineframedtext +%D [Example] +%D [width=6cm] +%D +%D \startExample +%D \typebuffer[framed-2] +%D \stopExample +%D \stopbuffer +%D +%D \startbuffer[framed-3] +%D \defineframedtext +%D [Example] +%D [height=5cm] +%D +%D \startExample +%D \typebuffer[framed-3] +%D \stopExample +%D \stopbuffer +%D +%D \startbuffer[framed-4] +%D \defineframedtext +%D [Example] +%D [width=fit,height=broad] +%D +%D \Example{a very exciting example} +%D \stopbuffer +%D +%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup +%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup +%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup +%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup +%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup +%D +%D Here we can see that we have a predefined framed text class +%D as well as the tools for defining our own. So we have: +%D +%D \showsetup{setupframedtexts} +%D +%D as well as the definition command: +%D +%D \showsetup{defineframedtext} +%D +%D that generates two commands: +%D +%D \showsetup{start<>} +%D \showsetup{<>} +%D +%D The next definition shows the defaults. + +\def\dodefineframedtext[#1][#2]% + {\presetlocalframed[\??kd#1]% + \getparameters[\??kd#1] + [\c!width=0.75\hsize, + \c!height=\v!fit, + \c!align=\v!yes, + \c!top=, + \c!bottom=\vfill, + \c!offset=1em, + \c!bodyfont=, + \c!style=, + \c!color=, + \c!left=, + \c!right=\hfill, + \c!before=\blank, + \c!after=\blank, + \c!inner=, + \c!frame=\v!on, + \c!topframe=, + \c!bottomframe=, + \c!leftframe=, + \c!rightframe=, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!foregroundcolor=, + \c!foregroundstyle=, + \c!background=, + \c!backgroundcolor=, + \c!backgroundscreen=\@@rsscreen, + \c!linecorrection=\v!on, + \c!depthcorrection=\v!on, + \c!margin=\v!standard, + \c!orientation=, + \c!indenting=, + #2]% + \setvalue{\e!start#1}{\dostartframedtext[#1]}% + \setvalue{\e!stop #1}{\dostopframedtext }% + \setvalue {#1}{\doframedtext [#1]}} + +\def\defineframedtext + {\dodoubleempty\dodefineframedtext} + +%D We define the general (and original) case by just saying: + +\defineframedtext[\v!framedtext] + +%D We need several steps before the actual job is done, +%D because we have to handle an optional identifier (and +%D because these commands evolved out of a single case). + +\def\framedtextparameter#1#2% + {\csname\??kd#1#2\endcsname} + +\def\dosetupframedtexts[#1][#2]% + {\ifsecondargument + \def\docommand##1{\getparameters[\??kd##1][#2]}% + \processcommacommand[#1]\docommand % new, #1 may be macro + \else + \getparameters[\??kd\v!framedtext][#1]% + \fi} + +\def\setupframedtexts + {\dodoubleempty\dosetupframedtexts} + +\def\dostartframedtext + {\bgroup\dotripleempty\dodostartframedtext} + +\def\dodostartframedtext[#1][#2][#3]% + {\doifassignmentelse{#2} + {\dododostartframedtext[#1][][#2]} + {\dododostartframedtext[#1][#2][#3]}} + +\setfalse\framedtextlocationnone + +\def\dododostartframedtext[#1][#2][#3]% #3 only passed to framed, not to framedtext + {\doifsomething{#2}{\setvalue{\??kd#1\c!location}{#2}}% does not listen to #3 + \setfalse\framedtextlocationnone + \processaction % \v!low en \v!depth are already taken ! + [\framedtextparameter{#1}\c!location] + [ \v!left=>\letvalue{\??kd#1\c!left }\relax + \letvalue{\??kd#1\c!right}\hfill, + \v!right=>\letvalue{\??kd#1\c!left }\hfill + \letvalue{\??kd#1\c!right}\relax, + \v!middle=>\letvalue{\??kd#1\c!left }\hfill + \letvalue{\??kd#1\c!right}\hfill, + \v!none=>\letvalue{\??kd#1\c!left }\relax % new + \letvalue{\??kd#1\c!right}\relax % new + \settrue\framedtextlocationnone]% + \letvalue{\??kd#1\c!location}\empty + % removed 06/2001 + % \forgetparindent + % added 06/2001 [see demo-bbv] + \localhsize\hsize \checkframedtext + % so far + \setbox\framebox\vbox + \startboxedcontent + \hsize\localhsize + % \insidefloattrue % ? better + \normalexpanded{\noexpand\switchtobodyfont[\framedtextparameter{#1}\c!bodyfont]}% + \startcolor[\framedtextparameter{#1}\c!color]% + \localframed[\??kd#1][\c!strut=\v!no,#3]% todo: use delayedstrut + \bgroup + \let\\=\endgraf + \framedtextparameter{#1}\c!inner % oud spul + \doifvalue{\??kd#1\c!depthcorrection}\v!on % new, inside box + {\bgroup + \verticalstrut + % we need \nowhitespace in case of setups setting whitespace + % nb, not safe, text vs \vbox as next + \vskip-\struttotal + \nowhitespace % na vskip ! new 20/05/2004, fails with next content being box (\scale{..}) + }% + \doinhibitblank % \blank[\v!disable]% plaatst signal +\setupindenting[\framedtextparameter{#1}\c!indenting]% + \doconvertfont{\framedtextparameter{#1}\c!style}\empty + \def\dostopframedtext{\dodostopframedtext{#1}{#2}}} + +%D The \type {none} option is handy for nested usage, as +%D in the presentation styles, where we don't want +%D interference. + +\def\dodostopframedtext#1#2% % no \baselinecorrection, see faq docs + {\endgraf + \removelastskip + \doifvalue{\??kd#1\c!depthcorrection}\v!on % local and global + {\forgetall + \vskip-\struttotal + \verticalstrut + \egroup + \forgetall + \vskip-\lineheight + % will be an option, not default + % \setbaselinecorrections + % \donegbotbaselinecorrection + \verticalstrut} + \stopboxedcontent + \stopcolor + \ifconditional\framedtextlocationnone + \egroup + \box\framebox + \else\ifinsidefloat + \egroup + \box\framebox + \else + \egroup + \doplacement[\??kd#1][\c!depthcorrection=\v!off]{\box\framebox}% + \fi\fi + \egroup} + +%D Placement can be ignored: +%D +%D \starttyping +%D \hbox to \hsize \bgroup +%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext +%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext +%D \egroup +%D +%D \hbox to \hsize \bgroup +%D \setupframedtexts[location=none]% +%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext +%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext +%D \egroup +%D \stoptyping + +%D The simple brace (or group) delimited case is typeset +%D slightly different and is not aligned. + +\def\doframedtext + {\bgroup\dodoubleempty\dodoframedtext} + +\def\dodoframedtext[#1][#2]% beware! + {\normalexpanded{\noexpand\switchtobodyfont[\getvalue{\??kd#1\c!bodyfont}]}% + \localframed[\??kd#1][\c!strut=\v!no,#2]% + \bgroup + \blank[\v!disable]% + \let\\=\endgraf + \getvalue{\??kd#1\c!inner}% % kleur naar outer level + \dostartattributes{\??kd#1}\c!style\c!color\empty + \bgroup + \aftergroup\docloseframedtext + \let\next=} + +\def\docloseframedtext + {\removelastskip + \dostopattributes + \egroup + \egroup} + +%D \macros +%D {defineframed} +%D +%D One can also define simple framed texts, using: +%D +%D \showsetup{defineframed} + +\def\defineframed + {\dodoubleempty\dodefineframed} + +\def\dodefineframed[#1][#2]% + {\iffirstargument + \setvalue{#1}{\dodoubleempty\doframed[#2]}% + \fi} + +\def\doframed[#1][#2]% + {\framed[#1,#2]} + +%D \macros +%D {textrule, starttextrule, setuptextrules} +%D +%D Putting rules before and after a paragraph is very space +%D sensitive, but the next command handles that quite well. It +%D comes in two disguises: +%D +%D \startbuffer +%D \textrule[top]{fragments} +%D \input reich +%D \textrule +%D \stopbuffer +%D +%D \bgroup \typebuffer \getbuffer \egroup +%D +%D \startbuffer +%D \setuptextrules +%D [width=90pt,distance=12pt,rulecolor=blue, +%D bodyfont=small,style=\sc,color=red] +%D +%D \starttextrule{Ship Building Tools} +%D \nl \setuptolerance[tolerant] \input materie +%D \stoptextrule +%D \stopbuffer +%D +%D \bgroup \typebuffer \getbuffer \egroup +%D +%D \startbuffer +%D \setuptextrules +%D [location=inmargin, +%D bodyfont=small,style=slantedbold] +%D +%D \starttextrule{wonderful} +%D \input tufte +%D \stoptextrule +%D \stopbuffer +%D +%D \bgroup \typebuffer \getbuffer \egroup +%D +%D The formal definition of these commands is: +%D +%D \showsetup{textrule} +%D \showsetup{starttextrule} +%D \showsetup{setuptextrules} +%D +%D The implementation looks a bit complicated due to the +%D optional arguments. + +\def\setuptextrules + {\dodoubleargument\getparameters[\??tl]} + +\def\complextextrule[#1]% if needed we can make it installable + {\let\next\dobottomtextrule + \processaction + [#1] + [ \v!top=>\let\next\dotoptextrule, + \v!middle=>\let\next\domiddletextrule, + \v!bottom=>\let\next\dobottomtextrule]% + \dosinglegroupempty\next} + +\definecomplexorsimple\textrule + +\def\simpletextrule + {\dosinglegroupempty\dounknowntextrule} + +\def\docomplextextrule#1% + {\bgroup + \advance\hsize\dimexpr-\rightskip-\leftskip\relax + \setbox\scratchbox\hbox to \hsize + {\dimen4\dimexpr .5ex+.5\linewidth\relax + \dimen6\dimexpr-.5ex+.5\linewidth\relax + \doifnothing{#1}\firstargumentfalse + \iffirstargument + \doifelse\@@tllocation\v!inmargin + {\llap{\doattributes\??tl\c!style\c!color{#1}\hskip\leftmargindistance}} + {\color[\@@tlrulecolor] + {\vrule\!!height\dimen4\!!depth\dimen6\!!width\@@tlwidth}% + \hbox spread 2\dimexpr\@@tldistance\relax + {\hss\doattributes\??tl\c!style\c!color{\strut#1}\hss}}% + \fi + \color[\@@tlrulecolor] + {\leaders\hrule\!!height\dimen4\!!depth\dimen6\hfill}}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \noindent\box\scratchbox +%\nobreak\verticalstrut\kern-\struttotal +% evt \witruimte + \egroup} + +\def\dotoptextrule#1% + {\page[\v!preference] % interferes + %\whitespace % no + \@@tlbefore + \docomplextextrule{#1}% +% todo, option: \doifnothing{#1}{\ruledvskip-.5ex} + \nowhitespace + \@@tlinbetween + \endgraf} + +\def\dodobottomtextrule#1#2% + {\ifhmode + \endgraf + \fi + \dimen0\strutdp + \ifdim\prevdepth>\strutdp\else % was <\strutdp + \ifdim\prevdepth>\zeropoint + \advance\dimen0 -\prevdepth + \fi + \fi + \advance\dimen0 .5ex + \vskip\dimen0 +% == +% \vskip\dimexpr \strutdp + .5ex +% \ifdim\prevdepth>\strutdp\else\ifdim\prevdepth>\zeropoint-\prevdepth\fi\fi\relax +% + \@@tlinbetween + \doifelsenothing{#2} + {\bgroup + \advance\hsize\dimexpr-\rightskip-\leftskip\relax + \nointerlineskip + \moveleft-\leftskip\vbox + {\color[\@@tlrulecolor] + {\hrule\!!depth\linewidth\!!height\zeropoint\!!width\hsize}}% + \egroup} + {\docomplextextrule{#2}}% + \ifvmode\prevdepth\zeropoint\fi + #1% + \page[\v!preference]} + +\def\dobottomtextrule + {\dodobottomtextrule\@@tlafter} + +\def\domiddletextrule + {\dodobottomtextrule\@@tlinbetween} + +\def\dounknowntextrule + {\iffirstargument + \@EA\dotoptextrule + \else + \@EA\dobottomtextrule\@EA\empty + \fi} + +%D The grouped commands also supports bodyfont switching: + +\def\starttextrule#1% + {\bgroup + \def\dounknowntextrule{\domiddletextrule} + \dotoptextrule{#1} + \bgroup + \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}} + +\def\stoptextrule + {\par + \egroup + \dobottomtextrule\empty + \egroup} + +%D \macros +%D {fillinrules, setupfillinrules} +%D +%D The next few commands do not really deserve a place in a +%D core module, because they deal with specific typography. +%D Nevertheless I decided to make them part of the core, +%D because they permit us to make questionaires. Let's start +%D with some examples. +%D +%D \fillinrules[n=2,width=fit]{first} +%D \fillinrules[n=2,width=broad]{first} +%D \fillinrules[n=2,width=3cm]{first} +%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first} +%D \fillinrules[n=2]{first}{last} +%D \fillintext{first}{last} \input reich \par +%D +%D The main command is \type{\fillinrules}. This command takes +%D one and an optional second argument and sets a paragraph with +%D empty visualized lines. +%D +%D \showsetup{fillinrules} +%D \showsetup{setupfillinrules} + +\def\setupfillinrules + {\dodoubleargument\getparameters[\??il]} + +\definecomplexorsimpleempty\fillinrules + +\def\complexfillinrules[#1]% + {\def\docomplexfillinrules##1##2% + {\dodocomplexfillinrules[#1]{##1}{##2}{\thinrules + [\c!n=\@@iln,\c!interlinespace=\@@ilinterlinespace,\c!before=,\c!after=]}}% + \dodoublegroupempty\docomplexfillinrules} + +\def\dodocomplexfillinrules[#1]#2#3#4% + {\endgraf + \@@ilbefore + \begingroup + \setupfillinrules[#1]% + \noindent + \doifsomething{#2} + {\doifelse\@@ilwidth\v!fit + {\let\@@ildistance\!!zeropoint + \hbox} + {\doifelse\@@ilwidth\v!broad + {\hbox} + {\hbox to \@@ilwidth}}% + \bgroup + \doattributes\??il\c!style\c!color{\strut#2\hfill\@@ilseparator}% + \hskip\@@ildistance + \egroup}% + %\hangindent=\wd0\relax % tzt hang=yes,n + %\parindent=\hangindent + %\box0\relax + \setupwhitespace[\v!big]% + \ignorespaces + #4% + \doifsomething{#3} + {\kern\@@ildistance + \doattributes\??il\c!style\c!color{#3\strut}}% + \endgroup + \endgraf + \@@ilafter} + +%D \macros +%D {fillintext} +%D +%D To provide compatible layouts when texts and lines are +%D mixed, one can typeset a paragraph by using the command +%D \type{\fillintext}. +%D +%D \showsetup{fillintext} + +\definecomplexorsimpleempty\fillintext + +\def\complexfillintext[#1]% rather rough, using an \unhbox is suboptimal + {\def\docomplexfillintext##1##2% + {\dowithnextbox + {\dodocomplexfillinrules[#1]{##1}{\hfill##2}{\unhbox\nextbox\unskip}}% + \hbox\bgroup\let\par\egroup\ignorespaces}% + \dodoublegroupempty\docomplexfillintext} + +%D \macros +%D {fillinline, setupfillinlines} +%D +%D Another member of the family takes care of putting a (often +%D small) rule after a piece of text, like +%D +%D \startbuffer +%D \fillinline \input reich \par +%D \fillinline[margin=0cm] \input reich \par +%D \stopbuffer +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D which was typeset by saying: +%D +%D \typebuffer +%D +%D The two commands that take care of this are: +%D +%D \showsetup{fillinline} +%D \showsetup{setupfillinlines} + +\def\setupfillinlines + {\dodoubleargument\getparameters[\??iv]} + +\definecomplexorsimpleempty\fillinline + +\def\complexfillinline[#1]% + {%\endgraf % interferes with \definedescription cum suis + \@@ivbefore + \begingroup + \setupfillinlines[#1]% + \advance\rightskip \@@ivmargin + \parfillskip\zeropoint + \def\par % very dangerous + {\let\par\endgraf % -) + \ifhmode\unskip\hfill\fi + \scratchdimen\dimexpr\@@ivwidth-\@@ivdistance\relax + \ifdim\scratchdimen>\@@ivmargin\else\expandafter\rlap\fi + {\kern\@@ivdistance + \vrule + \!!width \scratchdimen + \!!height.5\linewidth + \!!depth .5\linewidth}% + \endgraf % ! + \endgroup + \endgraf % ! + \@@ilafter}} + +%D \stopdocumentation +%D \bgroup +%D +%D \setupframedtexts +%D [setuptext] +%D [background=color,backgroundcolor=white] +%D +%D \startbuffer +%D \setupbackground +%D [backgroundoffset=4pt, +%D background=screen, +%D frame=on, +%D framecolor=red, +%D leftoffset=2pt] +%D \stopbuffer +%D +%D \getbuffer +%D +%D \startbackground +%D +%D \macros +%D {setupbackground,startbackground,background} +%D +%D The section deals with backgrounds in the running text. This +%D means that texts is to be collected and split over pages. To +%D show what can be done, we provide this part of the +%D documentation with some gray background and a red frame. +%D Both the background and frame can have all characteristics +%D of \type{\framed}. This time we used the setting: +%D +%D \typebuffer +%D +%D The implementation is not that sophisticated, but suffices. +%D The main problem with this kind of functionality is to get +%D the spacing all right. + +%D Specifying the background is more or less the same as +%D specifying a framed box. +%D +%D \showsetup{setupbackground} + +\presetlocalframed[\??ag] + +\def\dosetupbackground[#1]% + {\getparameters[\??ag][#1]% + \doifelse\@@agstate\v!start + {\let\startbackground\dostartbackground + \let\stopbackground \dostopbackground + \let\background \dobackground} + {\let\startbackground\relax + \let\stopbackground \relax + \let\background \relax}} + +\def\setupbackground + {\dosingleargument\dosetupbackground} + +%D Actually typesetting the background is implemented rather +%D straightforward. We need to handle some spacing as well as +%D the (often) a bit smaller horizontal size. +%D +%D \showsetup{startbackground} +%D +%D Although we could have used a scratch one, we first +%D declare a boolean. + +% 0=no-split, 1=no-split+indent, 2=split, 3=split+indent + +\chardef\backgroundsplitmode\plusthree + +%D The \type{\vbox to \lineheight{}\vskip\zeropoint} +%D construction gives the first real line a decent height by +%D adding a dummy line. + +\def\dostartbackground + {\endgraf + \bgroup + \setbox0\vbox\bgroup + \vbox to \lineheight{}\vskip\zeropoint + \blank[\v!disable] + % \advance\hsize -\@@agleftoffset + % \advance\hsize -\@@agrightoffset + \leftskip \@@agleftoffset % new ** + \rightskip\@@agrightoffset} % new ** + +%D This dummy line is removed by \type{\setbox2=\vsplit0 to +%D \lineheight}. That way \type{\topskip} takes care of the +%D lineheight. I'll probably forget to apply this trick +%D elsewhere. + +\def\dostopbackground % improved version (i hope) + {\endgraf + \removelastskip + \egroup + \dimen2\leftskip % new ** + \forgetall + \ifinsidefloat + \chardef\backgroundsplitmode\zerocount + \fi + \ifcase\backgroundsplitmode + \localframed[\??ag][\c!offset=\v!overlay]{\box0}% + \or + \hskip\dimen2 + \localframed[\??ag][\c!offset=\v!overlay]{\box0}% + \else + \splitmaxdepth\boxmaxdepth + \splittopskip\topskip + \setbox2\vsplit0 to \lineheight % get rid of fake line + \loop + \ifdim\pagetotal=\zeropoint % empty page + \scratchdimen\textheight + \chardef\backgroundsplit\plusone % split to max height + \else + \setbox\scratchbox\vbox{\@@agbefore}% + \scratchdimen\dimexpr\pagegoal-\ht\scratchbox-\pagetotal\relax + \chardef\backgroundsplit\plustwo % split to partial height + \fi + \advance\scratchdimen\dimexpr-\@@agtopoffset-\@@agbottomoffset\relax + \ifdim\scratchdimen>2\lineheight\relax % reasonable, will be configurable + \ifdim\ht0>\scratchdimen % larger than page + \setbox2\vsplit0 to \scratchdimen + \else + \setbox2\box0 + \chardef\backgroundsplit\zerocount % no split + \fi + \setbox2\vbox \ifcase\backgroundsplit\or to \textheight \fi % max split + {\vskip\@@agtopoffset + \popsplitproperties + \unvcopy2 + \prevdepth\dp2 + \obeydepth + \vskip\@@agbottomoffset + \vfill} + \@@agbefore + \ifcase\backgroundsplit\or\or % partial split + \ifdim\pagegoal<\maxdimen + \pagegoal=1.2\pagegoal % be a bit more tolerant + \fi + \fi + \startlinecorrection + %\localframed[\??ag][\c!offset=\v!overlay]{\hskip\@@agleftoffset\box2\hskip\@@agrightoffset}% + \ifnum\backgroundsplitmode=\plusthree \hskip\dimen2 \fi % + \localframed[\??ag][\c!offset=\v!overlay]{\box2}% new ** + \stoplinecorrection + \ifcase\backgroundsplit % no split + \@@agafter + \else % some split + \vfill\eject % geen \page ! + \fi + \else + \page + \fi + \ifdim\ht0>\zeropoint \repeat + \fi + \egroup + \endgraf} + +%D As a bonus we also have a short command, that is of not +%D much use, but kept there for historic reasons. +%D +%D \showsetup{background} + +\def\dobackground + {\bgroup + \dowithnextbox + {\localframed[\??ag][\c!offset=\v!overlay]{\flushnextbox}\egroup} + \vbox} + +%D \stopdocumentation +%D \stopbackground +%D \egroup + +%D New, for the moment private; let's see when GB finds out +%D about this one and its obscure usage. It's used in: +%D +%D \startbuffer +%D \defineframedtext +%D [tabulateframe] +%D [offset=overlay, +%D backgroundoffset=3pt, +%D background=color, +%D backgroundcolor=green] +%D +%D \setuptabulate +%D [tabulate] +%D [frame=tabulateframe] +%D +%D \setuptables +%D [frame=tabulateframe] +%D +%D \input tufte +%D +%D \starttabulate[|l|l|] +%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR +%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR +%D \stoptabulate +%D +%D \input tufte +%D +%D \starttable[|l|l|] +%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR +%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer + +\def\defineframedcontent + {\dodoubleempty\dodefineframedcontent} + +\def\dodefineframedcontent[#1][#2]% + {\presetlocalframed[\??fc#1]% + \getparameters[\??fc#1] + [\c!leftoffset=\zeropoint, + \c!rightoffset=\getvalue{\??fc#1\c!leftoffset}, + \c!topoffset=\zeropoint, + \c!bottomoffset=\getvalue{\??fc#1\c!topoffset}, + \c!strut=\v!no, + \c!offset=\v!overlay, + \c!linecorrection=\v!no, + \c!left=, + \c!right=, + #2]} + +\let\setuplocalframed\getparameters + +\def\setupframedcontent + {\dodoubleempty\dosetupframedcontent} + +\def\dosetupframedcontent[#1][#2]% + {\def\docommand##1{\getparameters[\??fc##1][#2]}% + \processcommacommand[#1]\docommand} + +\def\startframedcontent[#1]% + {\bgroup + \let\stopframedcontent\egroup + \doifnot{#1}\v!off + {\doifdefined{\??fc#1\c!frame} + {\def\stopframedcontent{\dostopframedcontent{#1}}% + \dostartframedcontent{#1}}}} + +\def\dostartframedcontent#1% + {\setbox\framebox\hbox\bgroup + \setlocalhsize + \hsize\localhsize + \advance\hsize\dimexpr-\getvalue{\??fc#1\c!leftoffset}-\getvalue{\??fc#1\c!rightoffset} \relax + \advance\vsize\dimexpr-\getvalue{\??fc#1\c!topoffset} -\getvalue{\??fc#1\c!bottomoffset}\relax + \hskip\getvalue{\??fc#1\c!leftoffset}% + \vbox\bgroup + \vskip\getvalue{\??fc#1\c!topoffset}% + \vbox\bgroup + \forgetall + \blank[\v!disable]} + +\def\dostopframedcontent#1% + {\removelastskip + \egroup + \vskip\getvalue{\??fc#1\c!bottomoffset}% + \egroup + \hskip\getvalue{\??fc#1\c!rightoffset}% + \egroup + \doifvalue{\??fc#1\c!width}\v!fit + {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox + \ifinsidefloat + \donefalse + \else + \doifelsevalue{\??fc#1\c!linecorrection}\v!yes\donetrue\donefalse + \fi + % plaats ? + \ifdone\startlinecorrection\fi + \getvalue{\??fc#1\c!left}% new + \localframed[\??fc#1]{\box\framebox}% + \getvalue{\??fc#1\c!right}% new + \ifdone\stoplinecorrection\fi + \egroup} + +%D \macros +%D {backgroundline} +%D +%D For the moment an undocumented feature, but a cancidate +%D for going public. + +\def\backgroundline[#1]% + %{\doifsomething{#1}{\dobackgroundline{#1}}\hbox} + {\doifcolorelse{#1}{\dobackgroundline{#1}\hbox}\hbox} + +% \def\backgroundline[#1]% +% {\doifcolor{#1}{\dobackgroundline{#1}}\hbox} + +\def\dobackgroundline#1% + {\dowithnextbox + {\hbox + {\localcolortrue + \startcolor[#1]% + \vrule + \!!width \nextboxwd + \!!height\nextboxht + \!!depth \nextboxdp + \stopcolor + \hskip-\nextboxwd + \flushnextbox}}} + +%D \macros +%D {encircled} +%D +%D Some not so robust left||overs (borrowed from Knuth, +%D \TEX Book\ page 356): + +\def\encircled#1% + {{\ooalign{\hfil\raise0.07ex\hbox{{\tx#1}}\hfil\crcr\mathhexbox20D}}} + +\let\omcirkeld\encircled + +\setuplinewidth + [\v!medium] + +\setupframed + [\c!width=\v!fit, + \c!height=\v!broad, + \c!lines=, + \c!offset=0.25ex, % \defaultframeoffset + \c!empty=\v!no, + \c!frame=\v!on, + \c!topframe=, + \c!bottomframe=, + \c!leftframe=, + \c!rightframe=, + \c!radius=.5\bodyfontsize, + \c!rulethickness=\linewidth, + \c!corner=\v!rectangular, + \c!depth=\!!zeropoint, + \c!foregroundcolor=, + \c!foregroundstyle=, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!backgroundoffset=\!!zeropoint, + \c!framecolor=, + \c!frameoffset=\!!zeropoint, + \c!backgroundcorner=\framedparameter\c!corner, + \c!backgroundradius=\framedparameter\c!radius, + \c!backgrounddepth=\framedparameter\c!depth, + \c!framecorner=\framedparameter\c!corner, + \c!frameradius=\framedparameter\c!radius, + \c!framedepth=\framedparameter\c!depth, + \c!component=, + \c!align=, + \c!bottom=\vss, + \c!top=, + \c!strut=\v!yes, + \c!autostrut=\v!yes, + \c!location=\v!normal, + \c!orientation=, + \c!autowidth=\v!yes, + \c!setups=] + +\setupscreens + [%\c!factor=1.0, % obsolete + %\c!method=\v!external, % obsolete + \c!screen=0.95] + +\setupblackrules + [\c!n=3, + \c!width=1em, + \c!height=1ex, + \c!depth=\!!zeropoint, + \c!alternative=\c!a, + \c!distance=.25ex, + \c!color=] + +\setupmarginrules + [\c!level=0, + \c!rulethickness=\@@kadefaultwidth\linewidth] + +\setupthinrules + [\c!interlinespace=\v!small, + \c!n=3, + \c!before=, + \c!inbetween={\blank[\v!white]}, + \c!after=, + \c!color=, + \c!height=.5\linewidth, + \c!depth=.5\linewidth, + \c!frame=\v!on, % compatible with textbackgrounds + \c!alternative=\v!b, + \c!backgroundcolor=, + \c!background=, + \c!rulethickness=] + +\setuptextrules + [\c!location=\v!left, + \c!before=\blank, + \c!after=\blank, + \c!inbetween=, + \c!width=2em, + \c!style=\v!bold, + \c!color=, + \c!rulecolor=, + \c!bodyfont=, + \c!distance=.5em] + +\setupfillinrules + [\c!width=\v!broad, + \c!distance=1em, + \c!before=\blank, + \c!after=\blank, + \c!n=1, + \c!interlinespace=\v!small, + \c!separator=, + \c!style=\v!normal, + \c!color=] + +\setupfillinlines + [\c!width=3cm, + \c!margin=\@@ivwidth, + \c!distance=1em, + \c!before=\blank, + \c!after=\blank] + +\setupbackground + [\c!leftoffset=.5\bodyfontsize, + \c!rightoffset=\@@agleftoffset, + \c!topoffset=\!!zeropoint, + \c!bottomoffset=\@@agtopoffset, + \c!state=\v!start, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!frame=\v!off, + \c!color=, + \c!depth=\!!zeropoint, + \c!background=\v!screen, + \c!backgroundcolor=\@@agcolor, + \c!screen=\@@rsscreen, + \c!before=, + \c!after=] + +% Experimental extension: + +\def\c!loffset{loffset} +\def\c!roffset{roffset} +\def\c!toffset{toffset} +\def\c!boffset{boffset} + +\getparameters + [\??oi] + [\c!loffset=\zeropoint, + \c!roffset=\zeropoint, + \c!toffset=\zeropoint, + \c!boffset=\zeropoint] + +\newdimen\!!framedloffset +\newdimen\!!framedroffset +\newdimen\!!framedtoffset +\newdimen\!!framedboffset + +\def\setextraframedoffsets + {\boxhasextraoffsetfalse + \!!framedloffset\framedparameter\c!loffset + \!!framedroffset\framedparameter\c!roffset + \!!framedtoffset\framedparameter\c!toffset + \!!framedboffset\framedparameter\c!boffset + \ifzeropt\!!framedloffset\else \advance\!!framedwidth -\!!framedloffset \boxhasextraoffsettrue \fi + \ifzeropt\!!framedroffset\else \advance\!!framedwidth -\!!framedroffset \boxhasextraoffsettrue \fi + \ifzeropt\!!framedtoffset\else \advance\!!framedheight-\!!framedtoffset \boxhasextraoffsettrue \fi + \ifzeropt\!!framedboffset\else \advance\!!framedheight-\!!framedboffset \boxhasextraoffsettrue \fi} + +\def\applyextraframedoffsets + {\setbox\framebox\vbox\bgroup + \vskip\!!framedtoffset + \hbox\bgroup + \hskip\!!framedloffset + \box\framebox + \hskip\!!framedroffset + \egroup + \vskip\!!framedboffset + \egroup} + +\protect \endinput diff --git a/tex/context/base/page-flt.tex b/tex/context/base/page-flt.tex deleted file mode 100644 index 91cb25e6b..000000000 --- a/tex/context/base/page-flt.tex +++ /dev/null @@ -1,2159 +0,0 @@ -%D \module -%D [ file=page-flt, -%D version=2000.10.20, -%D title=\CONTEXT\ Page 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 Page Macros / Floating Bodies} - -%D Some of the sidefloat settings should move to page-sid; now it's quite -%D fuzzy the way the variables are set/reset. - -\unprotect - -\ifx\addlocalbackgroundtobox\undefined \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi - -\def\placefloats{\doflushfloats} % keep this one - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -% messages moved - -\def\floatparameter #1{\csname\??fl\currentfloat#1\endcsname} -\def\floatcaptionparameter#1{\csname\??kj\currentfloat#1\endcsname} - -% \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/page-lyr.tex b/tex/context/base/page-lyr.tex deleted file mode 100644 index fe542233f..000000000 --- a/tex/context/base/page-lyr.tex +++ /dev/null @@ -1,753 +0,0 @@ -%D \module -%D [ file=page-lyr, -%D version=2000.10.20, -%D title=\CONTEXT\ Page 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 Page 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 - \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/page-num.tex b/tex/context/base/page-num.tex deleted file mode 100644 index 95eeea806..000000000 --- a/tex/context/base/page-num.tex +++ /dev/null @@ -1,534 +0,0 @@ -%D \module -%D [ file=page-num, % moved here from main-001 -%D version=1997.03.31, -%D title=\CONTEXT\ Page 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 Page 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/pret-lua.lua b/tex/context/base/pret-lua.lua new file mode 100644 index 000000000..81e02c360 --- /dev/null +++ b/tex/context/base/pret-lua.lua @@ -0,0 +1,259 @@ +if not modules then modules = { } end modules ['pret-lua'] = { + version = 1.001, + comment = "companion to buff-ver.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local 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 + +buffers.visualizers.lua = buffers.visualizers.lua or { } +buffers.visualizers.lua.identifiers = buffers.visualizers.lua.identifiers or { } + +-- borrowed from scite + +buffers.visualizers.lua.identifiers.core = { + "and", "break", "do", "else", "elseif", "end", "false", "for", "function", + "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", + "true", "until", "while" +} + +buffers.visualizers.lua.identifiers.base = { + "assert", "collectgarbage", "dofile", "error", "gcinfo", "loadfile", + "loadstring", "print", "rawget", "rawset", "require", "tonumber", + "tostring", "type", "unpack", +} + +buffers.visualizers.lua.identifiers.five = { + "_G", "getfenv", "getmetatable", "ipairs", "loadlib", "next", "pairs", + "pcall", "rawequal", "setfenv", "setmetatable", "xpcall", "string", "table", + "math", "coroutine", "io", "os", "debug", "load", "module", "select" +} + +buffers.visualizers.lua.identifiers.libs = { + -- coroutine + "coroutine.create", "coroutine.resume", "coroutine.status", "coroutine.wrap", + "coroutine.yield", "coroutine.running", + -- package + "package.cpath", "package.loaded", "package.loadlib", "package.path", + -- 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.log10", "math.max", "math.min math.mod math.pi", "math.pow", + "math.rad", "math.random", "math.randomseed", "math.sin", "math.sqrt", + "math.tan", "math.cosh", "math.fmod", "math.modf", "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.maxn", "table.concat", "table.foreach", "table.foreachi", "table.getn", + "table.sort", "table.insert", "table.remove", "table.setn", + -- 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" +} + +local known_words = { } + +for k,v in pairs(buffers.visualizers.lua.identifiers) do + for _,w in pairs(v) do + known_words[w] = k + end +end + +buffers.visualizers.lua.styles = { + core = "", + base = "\\sl ", + five = "\\sl ", + libs = "\\sl ", +} + +local styles = buffers.visualizers.lua.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 buffers.visualizers.lua.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) + +function buffers.visualizers.lua.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 = nil, nil + for c in utfcharacters(code) do + if c == "[" then + if p == "[" then + inlongstring = true + state = change_state(states["[["],state) + texwrite(p,c) + state = finish_state(state) + p = nil + else + p = c + end + elseif c == "]" then + if p == "]" then + inlongstring = false + state = change_state(states["]]"],state) + texwrite(p,c) + state = finish_state(state) + p = nil + else + p = c + end + else + if p then + state = change_state(states[c],state) + texwrite(p,c) + state = finish_state(state) + p = nil + end + if c == " " then + if word then + state = flush_lua_word(state,word) + word = nil + end + texsprint(ctxcatcodes,"\\obs") + elseif inlongstring then + texwrite(c) + elseif instr then + 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 + texwrite(c) + end + elseif c == '"' or c == "'" then + instr = true + state = change_state(states[c],state) + texwrite(c) + 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 + 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 + if c == " " then texsprint(ctxcatcodes,"\\obs") else texwrite(c) end + end + end + end + if comment then + incomment = true + state = change_state(states['--'], state) + texwrite("[[") + state = finish_state(state) + texwrite(comment) + 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..c4904e2d4 --- /dev/null +++ b/tex/context/base/pret-mp.lua @@ -0,0 +1,235 @@ +if not modules then modules = { } end modules ['pret-mp'] = { + version = 1.001, + comment = "companion to buff-ver.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local utfbyte, utffind = utf.byte, utf.find +local texsprint, texwrite = tex.sprint, tex.write +local ctxcatcodes = tex.ctxcatcodes + +buffers.visualizers.mp = buffers.visualizers.mp or { } +buffers.visualizers.mp.identifiers = buffers.visualizers.mp.identifiers or { } + +buffers.visualizers.mp.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' +} + +buffers.visualizers.mp.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' +} + +buffers.visualizers.mp.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' +} + +buffers.visualizers.mp.styles = buffers.visualizers.mp.styles or { + primitives = "", + plain = "\\sl", + metafun = "\\sl", +} + +local styles = buffers.visualizers.mp.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 pairs(buffers.visualizers.mp.identifiers) do + for _,w in pairs(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 buffers.visualizers.mp.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..7b3c116a5 --- /dev/null +++ b/tex/context/base/pret-tex.lua @@ -0,0 +1,85 @@ +if not modules then modules = { } end modules ['pret-tex'] = { + version = 1.001, + comment = "companion to buff-ver.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local 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 + +buffers.visualizers.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 buffers.visualizers.tex.flush_line(str,nested) + local state, first = 0, false + buffers.currentcolors = colors + for c in utfcharacters(str) do + 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)) + 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/s-abr-01.tex b/tex/context/base/s-abr-01.tex index f7665177d..8c2f6ebab 100644 --- a/tex/context/base/s-abr-01.tex +++ b/tex/context/base/s-abr-01.tex @@ -314,7 +314,12 @@ \def\NEWPAGE {\SystemSpecialB{newpage}} \def\NEWLINE {\SystemSpecialB{newline}} -\def\THANH {H\`an Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh} + +\doifmodeelse {mkiv} { + \def\THANH{Han The Thanh} % todo +} { + \def\THANH{H\`an Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh} +} %def\THANH {H\`an Th\ecircumflexacute\ Th\`anh} diff --git a/tex/context/base/scrn-fld.mkii b/tex/context/base/scrn-fld.mkii new file mode 100644 index 000000000..60511ac2b --- /dev/null +++ b/tex/context/base/scrn-fld.mkii @@ -0,0 +1,1080 @@ +%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 + +\newif\ifdefinemainfield \definemainfieldfalse + +%D We need to keep track of cloned (related) fields and so by +%D maintaining lists of field clones. +%D +%D The first alternative used a two pass data list and was +%D implemented as follows: +%D +%D \starttyping +%D \def\getmainfieldkids#1% +%D {\let\@@DriverFieldKids\empty +%D \ifdefinemainfield +%D \definetwopasslist{fld:#1}% defined by system +%D \doloop +%D {\gettwopassdata{fld:#1}% +%D \iftwopassdatafound +%D %\addtocommalist\twopassdata\@@DriverFieldKids +%D \appendtocommalist\twopassdata\@@DriverFieldKids +%D \else +%D \exitloop +%D \fi}% +%D \fi} +%D \stoptyping +%D +%D However, the next alternative is much faster when we have +%D a field with thousands of clones, something not that +%D imaginary. +%D +%D \starttyping +%D \def\getmainfieldkids#1% +%D {\let\@@DriverFieldKids\empty +%D \ifdefinemainfield +%D \definetwopasslist{fld:#1}% runtime defined by system +%D \getnamedtwopassdatalist{fld:#1}\@@DriverFieldKids +%D \fi} +%D \stoptyping +%D +%D The data is written by file using: +%D +%D \starttyping +%D \newcounter\nofmainfieldkids +%D +%D \def\setmainfieldkid#1#2% +%D {\doglobal\increment\nofmainfieldkids +%D \savetwopassdata{fld:#1}{\nofmainfieldkids}{#2}} +%D \stoptyping +%D +%D The trade of of this mechanism is that for each cloned or +%D copied field, the uitlity file is to be read in order to +%D fetch the data. +%D +%D The next, much faster alternative uses a dedicated % +%D reference mechanism. + +\def\setmainfieldkid#1#2% + {\immediatewriteutilitycommand{\fieldreference{#1}{#2}}} + +\def\checkfieldreferences + {\startnointerference + \protectlabels + \doutilities{fieldreferences}\jobname\empty\relax\relax + \global\let\checkfieldreferences\relax + \stopnointerference} + +\def\setfieldreferences + {\def\fieldreference##1##2% + {\ifundefined{\r!widget##1}% + \setxvalue{\r!widget##1}{##2}% + \else + \edef\!!stringa{\getvalue{\r!widget##1}}% + \setxvalue{\r!widget##1}{\!!stringa,##2}% + \fi}} + +\def\resetfieldreferences + {\let\fieldreference\gobbletwoarguments} + +\def\getmainfieldkids#1% + {\checkfieldreferences + \ifdefinemainfield + \doifundefinedelse{\r!widget#1}% + {\let\@@DriverFieldKids\empty} + {\@EA\let\@EA\@@DriverFieldKids\csname\r!widget#1\endcsname}% + \else + \let\@@DriverFieldKids\empty + \fi} + +\resetfieldreferences + +%D Of course it costs a few more tokens to implement, but it's +%D worth the memory: running for instance the 2000 page +%D english examns publishing on demand document went down from +%D 1350 seconds to less than 950 on a 650 Mhz pentium. + +\def\definefield + {\definemainfieldfalse\doquintupleempty\dodefinefield} + +\def\definemainfield + {\definemainfieldtrue \doquintupleempty\dodefinefield} + +\let\collectedfields\empty +\newcounter\numberoffields +\newcounter\totalnumberoffields + +\def\savenumberoffields + {\ifcase\numberoffields\relax\else + \savecurrentvalue\totalnumberoffields\numberoffields + \fi} + +\appendtoks \savenumberoffields \to \everybye % \everylastshipout + +% \def\presetfieldreferences +% {\ifnum\totalnumberoffields>0 +% \definereference[AtOpenInitializeForm][\v!ResetForm]% +% \fi} +% +% \definereference[AtOpenInitializeForm][\v!geen] +% +% \appendtoks \presetfieldreferences \to \everycheckreferences + +\def\dodefinefield[#1][#2][#3][#4][#5]% + {\ifsecondargument + \edef\currentfieldname{#1}% just in case we're inside a loop + \doifundefinedelse{define#2field} + {\writestatus\m!fields{unknown field type #2}} + {\doifundefined{fielddata\currentfieldname} + {\getmainfieldkids\currentfieldname + \ifdefinemainfield + \ifx\@@DriverFieldKids\empty + \let\@@DriverFieldMode\fieldlonermode + \else + \let\@@DriverFieldMode\fieldparentmode + \fi + \def\@@DriverFieldAuto{1}% + \else + \let\@@DriverFieldMode\fieldlonermode + \def\@@DriverFieldAuto{0}% + \fi + \def\@@DriverFieldFree{0}% + \getvalue{define#2field}{\currentfieldname}{#2}{#3}{#4}{#5}}}% + \else + \writestatus\m!fields{pass fieldname and fieldtype}% + \fi} + +\def\definelinefield#1#2#3#4#5% + {\setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{#4}} + +\let\definetextfield=\definelinefield + +\def\definechoicefield#1#2#3#4#5% + {\doifelsenothing{#4} + {\def\@@DriverFieldValues{yes,no}} + {\def\@@DriverFieldValues{#4}}% + \doifelsenothing{#5} + {\dogetcommacommandelement2\from\@@DriverFieldValues \to\@@DriverFieldDefault + \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} + {\def\@@DriverFieldDefault{#5}}% + \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} + +\let\definepopupfield=\definechoicefield +\let\definecombofield=\definechoicefield + +%\def\definecheckfield#1#2#3#4#5% +% {\doifelsenothing{#4} +% {\definedefaultsymbols +% \def\@@DriverFieldValues{defaultyes}} +% {\def\@@DriverFieldValues{#4}}% +% \doifelsenothing{#5} +% {\dogetcommacommandelement2\from\@@DriverFieldValues\to\@@DriverFieldDefault +% \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} +% {\def\@@DriverFieldDefault{#5}}% +% \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} + +%D Since these fields have an on/off state only, we pass 1/0 +%D to the driver as default values. + +\def\definecheckfield#1#2#3#4#5% + {\doifelsenothing{#4} + {\definedefaultsymbols + \def\@@DriverFieldValues{defaultyes}} + {\def\@@DriverFieldValues{#4}}% + \doifelsenothing{#5} + {\def\@@DriverFieldDefault{2}} + {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldDefault + \doifinstringelse{#5}{\@@DriverFieldDefault} + {\def\@@DriverFieldDefault{1}} + {\def\@@DriverFieldDefault{0}}}% + \setfield + {#1}{#2}{}{}{\@@DriverFieldKids}{#3}% + {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}% + {\@@DriverFieldValues}{\@@DriverFieldDefault}} + +\let\definepushfield=\definecheckfield + +\def\defineradiofield#1#2#3#4#5% + {\iffourthargument + \doifelsenothing{#5} + {\dogetcommacommandelement1\from#4\to\SavedFieldDefault + \dogetcommacommandelement1\from\SavedFieldDefault\to\SavedFieldDefault} + {\def\SavedFieldDefault{#5}}% +% when opt works +% \@EA\beforesplitstring\SavedFieldDefault\at=>\to\SavedFieldDefault + \ifx\@@DriverFieldKids\empty + \setfield{#1}{#2}{}{}{#4}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% + \else + \setfield{#1}{#2}{}{}{#4,\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% + \fi +% + \def\docommand##1% + {\doifelse{##1}\SavedFieldDefault + {\def\@@DriverFieldDefault{##1}}% + {\let\@@DriverFieldDefault\empty}% + \setfield{##1}{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% +% when opt works +% \def\docommand##1% +% {\@EA\beforesplitstring##1\at=>\to\FieldValue +% \doifelse\FieldValue\SavedFieldDefault +% {\let\@@DriverFieldDefault\FieldValue}% +% {\let\@@DriverFieldDefault\empty}% +% \setfield\FieldValue{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% + \processcommalist[#4]\docommand + \else + \writestatus\m!fields{pass values too}% + \fi} + +\def\definesubfield + {\dotripleempty\dodefinesubfield} + +\def\dodefinesubfield[#1][#2][#3]% for the moment only radio ones + {\ifsecondargument + \def\docommand##1% + {\getfield{##1}% + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field ##1}% to do + \else + \doifsomething{#2} + {\edef\@@DriverFieldGroup{#2}}% + \doifelsenothing{#3} + {\definedefaultsymbols + \def\@@DriverFieldValues{defaultyes}} + {\def\@@DriverFieldValues{#3}}% + \changefield{##1}% + \fi}% + \processcommalist[#1]\docommand + \else + \writestatus\m!fields{pass fieldname, setupgroup, values and default}% + \fi} + +\def\doclonefield[#1][#2][#3][#4]% parent children setupgroup values + {\ifsecondargument + \getfield{#1}% +\iftrialtypesetting\else + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field #1}% + \else + \let\@@DriverFieldMode\fieldparentmode + %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% + \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% + \processcommalist[#2]\docommand + \changefield{#1}% + \let\@@DriverFieldAutoParent\@@DriverFieldAuto + \def\@@DriverFieldParent{#1}% + \let\@@DriverFieldKids\empty + \let\@@DriverFieldRoot\empty + \let\@@DriverFieldMode\fieldchildmode + \def\@@DriverFieldFree{0}% + \def\@@DriverFieldAuto{0}% + \doifsomething{#3}{\edef\@@DriverFieldGroup{#3}}% + \doifsomething{#4}{\edef\@@DriverFieldValues{#4}}% + \def\docommand##1% + {\ifcase\@@DriverFieldAutoParent\else + \setmainfieldkid{\@@DriverFieldParent}{##1}% + \fi + \changefield{##1}}% + \processcommalist[#2]\docommand + \fi +\fi + \else + \writestatus\m!fields{pass parent field and clones}% + \fi} + +\def\clonefield + {\doquadrupleempty\doclonefield} + +\def\docopyfield[#1][#2]% parent children + {\ifsecondargument + \getfield{#1}% +\iftrialtypesetting\else + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field #1}% + \else + \let\@@DriverFieldMode\fieldparentmode + %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% + \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% + \processcommalist[#2]\docommand + \changefield{#1}% + \let\@@DriverFieldAutoParent\@@DriverFieldAuto + \def\@@DriverFieldParent{#1}% + \let\@@DriverFieldKids\empty + \let\@@DriverFieldRoot\empty + \let\@@DriverFieldMode\fieldcopymode + \def\@@DriverFieldFree{0}% + \def\@@DriverFieldAuto{0}% + \def\docommand##1% + {\ifcase\@@DriverFieldAutoParent\else + \setmainfieldkid{\@@DriverFieldParent}{##1}% + \fi + \changefield{##1}}% + \processcommalist[#2]\docommand + \fi +\fi + \else + \writestatus\m!fields{pass parent field and copies}% + \fi} + +\def\copyfield{\dodoubleempty\docopyfield} + +\unexpanded\def\field {\dotripleempty\dofield[\dohandlefield]} +\unexpanded\def\fitfield{\dotripleempty\dofield[\dohandlefitfield]} + +\def\dofield[#1][#2][#3]% + {\iffirstargument + \bgroup + \getfield{#2}% + \ifsecondargument + \def\@@DriverFieldLabel{#3}% + \else + \let\@@DriverFieldLabel\@@DriverFieldName + \fi + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field #2}% + \else\ifcase\@@DriverFieldFree\relax + \doifdefinedelse{\strippedcsname\setupfield\@@DriverFieldGroup} + {\let\dosetupfield=#1\getvalue{\strippedcsname\setupfield\@@DriverFieldGroup}} + {#1[\@@DriverFieldName][\v!label,\v!frame,\v!horizontal][][][]}% +\iftrialtypesetting\else + \def\@@DriverFieldFree{1}% + \changefield{#2}% +\fi + \else\ifcase\@@DriverFieldAuto\relax + % \writestatus\m!fields{field #2 already typeset}% + \else + % \writestatus\m!fields{field #2 automatically copied}% + \nextsystemfield + \copyfield[\@@DriverFieldName][\currentsystemfield]% + \dotripleempty\dofield[#1][\currentsystemfield][#3]% get the if's right + \fi\fi\fi + \egroup + \fi} + +\def\typesetfield + {\useJSscripts[fld]% + \ifx\@@DriverFieldRoot\empty \else + \let\@@SavedFieldName\@@DriverFieldName + \getfield\@@DriverFieldRoot + \ifcase\@@DriverFieldFree\relax + \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot + \dopresetrecord +\iftrialtypesetting\else + \def\@@DriverFieldFree{1}% + \changefield\@@DriverFieldName +\fi + \fi + \getfield\@@SavedFieldName + \fi + \ifx\@@DriverFieldKids\empty + \donefalse + \else + \donetrue + \fi + \ifdone + \let\@@DriverFieldParent\@@DriverFieldName + %\addtocommalist\@@DriverFieldParent\@@DriverFieldKids + \appendtocommalist\@@DriverFieldParent\@@DriverFieldKids + \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot + \dopresetfield + \let\@@DriverFieldMode\fieldchildmode + \fi + \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot + \dopresetfield} + +\def\dopresetfield + {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType field}\fi\fi} + +\def\dopresetrecord + {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType record}\fi\fi} + +\def\dodefinethefieldset[#1][#2]% + {\dodefinefieldset{#1}{#2}} + +\def\definefieldset% + {\dodoubleargument\dodefinethefieldset} + +\def\normaldodosetupfield[#1][#2][#3][#4][#5]% + {\doifdefinedelse{\strippedcsname\setupfield#1} + {\pushmacro\dosetupfield + \def\dosetupfield[##1][##2][##3][##4][##5]% + {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][##2,#2][##3,#3][##4,#4][##5,#5]}}% + \getvalue{\strippedcsname\setupfield#1}% + \popmacro\dosetupfield} + {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}}} + +\let\dodosetupfield\normaldodosetupfield + +\def\donosetupfield[#1][#2][#3][#4][#5]% + {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}} + +\def\dosetupfield[#1][#2][#3][#4][#5]% + {\iffifthargument + \def\docommand##1{\dodosetupfield[##1][#2][#3][#4][#5]}% + \processcommalist[#1]\docommand + \else\ifthirdargument + \def\docommand##1{\dodosetupfield[##1][#2][][][#3]}% + \processcommalist[#1]\docommand + \else\ifsecondargument + \doifelse{#2}\v!reset + {\def\docommand##1{\donosetupfield[#1][][][][]}} + {\def\docommand##1{\dodosetupfield[##1][][][][#2]}}% + \processcommalist[#1]\docommand + \else\iffirstargument + \def\docommand##1{\dodosetupfield[##1][][][][]}% + \processcommalist[#1]\docommand + \else + \writestatus\m!fields{provide either 1, 2, 3 or 5 arguments}% + \fi\fi\fi\fi} + +\def\setupfield + {\doquintupleempty\dosetupfield} + +\def\dosetupfields[#1][#2][#3][#4]% + {\ifsecondargument + \def\dodosetupfield[##1][##2][##3][##4][##5]% + {\doifdefinedelse{\strippedcsname\setupfield##1} + {\def\dosetupfield[####1][####2][####3][####4][####5]% + {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,####2,##2][#2,####3,##3][#3,####4,##4][#4,####5,##5]}}% + \getvalue{\strippedcsname\setupfield##1}} + {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,##2][#2,##3][#3,##4][#4,##5]}}}% + \else\iffirstargument + \doifelse{#1}\v!reset + {\resetfields} + {\setupfields[][][][#1]}% checken + \else + \writestatus\m!fields{provide either 1 or 4 arguments}% + \fi\fi} + +\def\setupfields + {\doquadrupleempty\dosetupfields} + +\def\resetfields + {\let\dodosetupfield\normaldodosetupfield} + +% \setupfields[\v!reset] + +% opties: veld, label, kader, vertikaal/horizontaal + +\newif\ifShowFieldLabel +\newif\ifShowFieldFrame +\newif\ifVerticalField +\newif\ifHorizontalField + +% way to slow/complicated, we need some simple alternative +% as well + +\def\dohandlefield[#1][#2][#3][#4][#5]% + {\presetlocalframed[\??fd]% + \processallactionsinset + [#2] + [ \v!reset=>\ShowFieldLabelfalse\ShowFieldFramefalse + \HorizontalFieldfalse\VerticalFieldfalse, + \v!label=>\ShowFieldLabeltrue, + \v!frame=>\ShowFieldFrametrue, + \v!horizontal=>\HorizontalFieldtrue, + \v!vertical=>\VerticalFieldtrue]% + \ifVerticalField + \getparameters[\??fd] + [\c!distance=\!!zeropoint,\c!inbetween=\vskip\@@localoffset, + \c!align=\v!right,\c!width=20em]% + \else\ifHorizontalField + \getparameters[\??fd] + [\c!distance=\@@localoffset,\c!inbetween=,\c!align=\c!left, + \c!height=10ex]% + \else + \getparameters[\??fd] + [\c!distance=\!!zeropoint,\c!inbetween=,\c!align=\c!left]% + \fi\fi + \getparameters[\??fd] + [\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=,#3]% + \reshapeframeboxfalse % else ugly spacing + \ifShowFieldFrame + \localframed[\??fd][\c!strut=\v!no,\c!align=]\bgroup + \else + \vbox\bgroup + \fi + \dontcomplain + \ifShowFieldLabel + \setbox0\hbox + {\reshapeframeboxtrue % else wrong dimensions + \framed + [\c!style=,\c!color=,\c!align=\c!right,#4] + {\@@DriverFieldLabel}}% + \fi + \setbox2\hbox + {\reshapeframeboxtrue % else wrong dimensions + \ifVerticalField + \setupframed[\c!height=6ex,\c!width=\hsize]% + \else\ifHorizontalField + \setupframed[\c!height=\vsize,\c!width=20em]% + \else + \setupframed[\c!height=2cm,\c!width=2cm]% + \fi\fi + \framed + [\c!align=\v!right,\c!strut=\v!no,#5] + {\getparameters + [\??fd] + [\c!color=,\c!style=,\c!align=\v!right,\c!option=, + \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, + \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, + \c!focusin=,\c!focusout=, + \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, + \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5]% + \scratchdimen\framedwidth \edef\@@DriverFieldWidth {\the\scratchdimen}% + \scratchdimen\framedheight\edef\@@DriverFieldHeight{\the\scratchdimen}% + \vfill + \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}} + \vss}}% + \ifShowFieldLabel + \ifVerticalField + \vbox + {\copy0 + \@@fdinbetween + \copy2}% + \else + \hbox + {\vbox \ifdim\ht2>\ht0 to \ht2 \fi + {\@@fdbefore + \copy0 + \@@fdafter}% + \hskip\@@fddistance + \vbox \ifdim\ht0>\ht2 to \ht0 \fi + {\@@fdbefore + \box2 + \@@fdafter}}% + \fi + \else + \box2 + \fi + \egroup} + +\chardef\fitfieldmode\plusone % 3 = best + +\def\dohandlefitfield[#1][#2][#3][#4][#5]% alleen check + {\presetlocalframed[\??fd]% + \localframed + [\??fd] + [\c!n=1024, % beware: weblink plug in truncates + \c!strut=\v!no,\c!color=,\c!style=,\c!option=, + \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, + \c!focusin=,\c!focusout=, + \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, + \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, + \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5,\c!align=] + {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldValue + \ifx\@@DriverFieldValue\empty + \let\@@DriverFieldValue\@@DriverFieldDefault + \fi + \dopresetfieldsymbol\@@DriverFieldValue + \setbox\scratchbox\hbox{\dogetfieldsymbol\@@DriverFieldValue}% + \scratchdimen\wd\scratchbox \edef\@@DriverFieldWidth {\the\scratchdimen}% + \scratchdimen\ht\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% + \ifcase\fitfieldmode + \typesetfield + \or % 1 = ignore depth (original, assumed no depth, actually a bug) + \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% + \or % 2 = add depth to height, but no depth in result + \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% + \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% + \or % 3 = add depth to height, and apply depth to result + \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% + \hbox to \wd\scratchbox{\lower\dp\scratchbox\hbox{\typesetfield}\hfill}% + \fi}} + +%D Common stuff + +\newcounter\nofsystemfields + +\def\nextsystemfield + {\doglobal\increment\nofsystemfields + \def\currentsystemfield{sys::\nofsystemfields}} + +%D An example: + +\def\fillinfield + {\dosingleempty\dofillinfield} + +\def\dofillinfield[#1]#2% + {\dontleavehmode + \hbox + {\forgetall + \setupfields[\v!reset]% + \nextsystemfield + \useJSscripts[ans]% + \doifelsenothing{#1} + {\def\therightanswer{#2}} + {\def\therightanswer{#1}}% + \setbox0\hbox{#2}% + \setbox2\hbox{\therightanswer}% + \dimen0=\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi + \advance\dimen0 .2em + \definefield + [\currentsystemfield][line][systemfield]% + \setupfield + [systemfield] + [\c!n=1024, % beware: weblink plugin truncates + \c!location=\v!low,\c!strut=\v!yes,\c!fieldoffset=0pt, + \c!height=1.2\openlineheight,\c!width=\dimen0,\c!offset=\v!overlay, + \c!style=,\c!align=\v!middle,\c!frame=\v!off, + \c!color=red,\c!fieldbackgroundcolor=\s!white,\c!fieldframecolor=blue, + \c!validate=JS(Check_Answer{\currentsystemfield,\therightanswer})]% + \switchtobodyfont + [\c!small]% + \hbox to \wd0 + {\copy0\hskip-\wd0\hss\field[\currentsystemfield]\hss}}} + +%D and another one: + +\def\tooltip + {\dosingleempty\dotooltip} + +\def\dotooltip[#1]#2#3% + {\bgroup + \setupfields[\v!reset]% + \useJSscripts[fld]% + \setbox0\hbox + {\dontcomplain + \nextsystemfield + \setbox0\hbox{#2}% + \definesymbol + [\currentsystemfield:txt] + [{\inframed[\c!frame=\v!off,\c!background=\v!screen]{#3}}]% + \setbox2\hbox{\symbol[\currentsystemfield:txt]}% + \definefield + [\currentsystemfield:txt][check] + [dummy][\currentsystemfield:txt][\currentsystemfield:txt]% + \setupfield + [dummy] + [\c!frame=\v!off, + \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), + \c!option=\v!hidden]% + \hbox to \zeropoint + {\dimen0\wd2\advance\dimen0 -\wd0 + \doifelse{#1}\v!left + {\hskip-\dimen0} + {\doif{#1}\v!middle + {\hskip-.5\dimen0}}% + \lower\openlineheight\hbox to \zeropoint + {\fitfield[\currentsystemfield:txt]}}% + \dimen0=\ifdim\wd0=\zeropoint 3em\else\wd0\fi + \definesymbol + [\currentsystemfield:but] + [{\framed[\c!height=2ex,\c!width=\dimen0,\c!frame=\v!off]{}}]% + \definefield + [\currentsystemfield:but][push] + [dummy][\currentsystemfield:but][\currentsystemfield:but]% + \setupfield + [dummy] + [\c!frame=\v!off, + \c!option=, + \c!regionin=JS(Vide_Field{\currentsystemfield:txt}), + \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), + \c!fieldlayer=\@@iafieldlayer]% + \lower2ex\hbox to \zeropoint + {\fitfield[\currentsystemfield:but]}% + #2}% + \ht0\strutht\dp0\strutdp\box0 + \egroup} + +%D And one more: + +\def\definefieldstack + {\dotripleargument\dodefinefieldstack} + +\def\dodefinefieldstack[#1][#2][#3]% name, symbols, settings + {\doifundefined{fieldstack:#1} + {\setgvalue{fieldstack:#1}{\dodofieldstack[#1][#2][#3]}}} + +\def\dodofieldstack[#1][#2][#3]% start=n, 0 == leeg + {\bgroup + \getparameters[\??fd][\c!start=1,#3]% + \setupfields[\v!reset]% + \definesymbol[\v!empty][]% + \useJSscripts[fld][FieldStack]% + \newcounter\stackedfieldnumber + \def\dododofieldstack##1% + {\increment\stackedfieldnumber + \ifnum\stackedfieldnumber=\@@fdstart\relax + \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][##1]% + \else + \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][\v!empty]% + \fi}% + \processcommalist[#2]\dododofieldstack + \setupfield[#1][\v!reset]% added + \setupfield[#1][\c!option=\v!readonly,#3]% #3 swapped + \newcounter\stackedfieldnumber + \def\dododofieldstack##1% + {\doglobal\increment\stackedfieldnumber + \fitfield[#1:\stackedfieldnumber]\egroup\bgroup}% + \startoverlay + \bgroup + \globalprocesscommalist[#2]\dododofieldstack + \egroup + \stopoverlay + \egroup} + +\def\dofieldstack[#1][#2][#3]% + {\ifsecondargument + \dodefinefieldstack[#1][#2][#3]\fieldstack[#1]% + \else + \getvalue{fieldstack:#1}\setgvalue{fieldstack:#1}{[#1]}% + \fi} + +\def\fieldstack + {\dotripleempty\dofieldstack} + +%D When submitting a form, we need to tell the driver module +%D that we want \FDF\ or \HTML. + +\def\setupforms + {\dodoubleargument\getparameters[\??fr]} + +\def\checksubmitform#1% + {\setsubmitoutputformat\@@frmethod} + +\setexecutecommandcheck {submitform} \checksubmitform + +\setupforms + [\c!method=HTML] + +\protect \endinput diff --git a/tex/context/base/scrn-fld.mkiv b/tex/context/base/scrn-fld.mkiv new file mode 100644 index 000000000..604b675c0 --- /dev/null +++ b/tex/context/base/scrn-fld.mkiv @@ -0,0 +1,1079 @@ +%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% + {\doifobjectfoundelse{SYM}{#1} + {} + {\settightobject{SYM}{#1}\hbox{\symbol[#1]}% + \flushatshipout + {\setbox0\hbox{\hskip-\maxdimen\getobject{SYM}{#1}}% + \smashbox0\box0}}} + +\def\presetfieldsymbols[#1]% slow + {\def\dopresetfieldsymbols##1% + {\processcommalist[##1]\dopresetfieldsymbol}% + \@EA\processcommalist\@EA[#1]\dopresetfieldsymbols} + +\def\definedefaultsymbols + {\definesymbol[defaultyes][$\times$]% + \definesymbol[defaultno][$\cdot$]} + +\def\resetfieldsymbol[#1]% for experimental usage only + {\resetobject{SYM}{#1}} + +%D The interface to the specials. DEFAULT NOG ANDERS + +\def\preparefieldvariables % evt \def's at the outer level (test) or \edef's here for fast testing + {\let\@@DriverFieldNumber \@@fdn + \let\@@DriverFieldStyle \@@fdstyle + \let\@@DriverFieldColor \@@fdcolor + \let\@@DriverFieldBackgroundColor\@@fdfieldbackgroundcolor + \let\@@DriverFieldFrameColor \@@fdfieldframecolor + \let\@@DriverFieldLayer \@@fdfieldlayer + \let\@@DriverFieldOption \@@fdoption + \let\@@DriverFieldAlign \@@fdalign + \let\@@DriverFieldClickIn \@@fdclickin + \let\@@DriverFieldClickOut \@@fdclickout + \let\@@DriverFieldRegionIn \@@fdregionin + \let\@@DriverFieldRegionOut \@@fdregionout + \let\@@DriverFieldAfterKey \@@fdafterkey + \let\@@DriverFieldFormat \@@fdformat + \let\@@DriverFieldValidate \@@fdvalidate + \let\@@DriverFieldCalculate \@@fdcalculate + \let\@@DriverFieldFocusIn \@@fdfocusin + \let\@@DriverFieldFocusOut \@@fdfocusout} + +% todo : remove arguments, consider DriverField a namespace + +\def\presetlinefield + {\preparefieldvariables + \dopresetlinefield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldNumber} + {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} + {\@@DriverFieldOption} + {\@@DriverFieldAlign} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presettextfield + {\preparefieldvariables + \dopresettextfield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldNumber} + {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} + {\@@DriverFieldOption} + {\@@DriverFieldAlign} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetchoicefield + {\preparefieldvariables + \dopresetchoicefield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} + {\@@DriverFieldOption} + {\@@DriverFieldValues} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetpopupfield + {\preparefieldvariables + \dopresetpopupfield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} + {\@@DriverFieldOption} + {\@@DriverFieldValues} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetcombofield + {\preparefieldvariables + \dopresetcombofield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor} + {\@@DriverFieldOption} + {\@@DriverFieldValues} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetcheckfield + {\preparefieldvariables + \presetfieldsymbols[\@@DriverFieldValues]% + \dopresetcheckfield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldOption} + {\@@DriverFieldValues} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetpushfield + {\preparefieldvariables + %\edef\@@DriverFieldValues{{\@@DriverFieldValues}}% makes sure {a,b,c} is passed + \presetfieldsymbols[\@@DriverFieldValues]% + \dopresetpushfield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldOption} + {\@@DriverFieldValues} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetradiofield + {\preparefieldvariables + \presetfieldsymbols[\@@DriverFieldValues]% + \dopresetradiofield + {\@@DriverFieldName} + {\@@DriverFieldWidth} + {\@@DriverFieldHeight} + {\@@DriverFieldDefault} + {\@@DriverFieldOption} + {\@@DriverFieldRoot} + {\@@DriverFieldValues} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\presetradiorecord + {\preparefieldvariables + \dopresetradiorecord + {\@@DriverFieldName} + {\@@DriverFieldDefault} + {\@@DriverFieldOption} + {\@@DriverFieldKids} + {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,% + \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,% + \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}} + +\def\setfieldmodes#1#2#3% + {\xdef\@@DriverFieldMode{#1}% % 0 1 2 3 + \xdef\@@DriverFieldFree{#2}% % 0 1 + \xdef\@@DriverFieldAuto{#3}} % 0 1 + +\newevery\everysetfield\relax + +\def\doiffieldelse#1{\doifdefinedelse{fielddata#1}} + +\def\setfield#1#2#3#4#5#6#7#8#9% + {\bgroup + \doglobal\increment\numberoffields + \iftracefields + \doglobal\addtocommalist{#1}\collectedfields + \fi + \the\everysetfield + \setxvalue{fielddata#1}% kortere tag #7 needs expansion etc + {\noexpand\dosetfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}% + \egroup} + +\def\dosetfield#1#2#3#4#5#6#7#8#9% + {\xdef\@@DriverFieldName {#1}% + \xdef\@@DriverFieldType {#2}% + \xdef\@@DriverFieldRoot {#3}% + \xdef\@@DriverFieldParent {#4}% + \xdef\@@DriverFieldKids {#5}% + \xdef\@@DriverFieldGroup {#6}% + \setfieldmodes #7% + \bgroup + \def\par{\string\n\string\n}% + \xdef\@@DriverFieldValues {#8}% + \xdef\@@DriverFieldDefault{#9}% + \egroup} + +\def\changefield#1% + {\setfield{#1}\@@DriverFieldType\@@DriverFieldRoot\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldGroup + {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}\@@DriverFieldValues\@@DriverFieldDefault} + +\def\getfield#1% name + {\doifundefinedelse{fielddata#1} + {\dosetfield{#1}\empty\empty\empty\empty\empty{\empty00}\empty\empty} + {\getvalue{fielddata#1}}} + +\newif\iftracefields \tracefieldsfalse + +\let\tracefields\tracefieldstrue + +\def\doshowfields[#1]% todo: tabulate van maken en runtime + {\bgroup + \switchtobodyfont[8pt,tt]% + \doifsomething{#1}{\def\collectedfields{#1}}% + \ifx\collectedfields\empty + \par specify [fieldlist] or say \type{\tracefieldstrue} first\par + \else + \def\normalizedfieldmode##1##2##3% + {\ifcase0##2 \else\sl\fi + \ifcase0##1 loner\or parent\or clone\or copy\fi}% + \def\dosetfield##1##2##3##4##5##6##7##8##9% + {##1&##2&##3&##4&##5&##6&\normalizedfieldmode##7&##8&##9\cr}% + \halign + {&##\strut\hss\quad\cr + \noalign{\hrule}% + NAME &TYPE &ROOT & + PARENT&KIDS &GROUP & + MODE &VALUES&DEFAULT\cr + \noalign{\hrule}% + \@EA\globalprocesscommalist\@EA[\collectedfields]\getfield + \noalign{\hrule}}% + \fi + \egroup} + +\def\showfields + {\dosingleempty\doshowfields} + +\def\dologfields[#1]% + {\bgroup + \immediate\openout\scratchwrite=fields.log + \doifsomething{#1}{\def\collectedfields{#1}}% + \ifx\colledtedfields\empty + \immediate\write\scratchwrite{use \tracefieldstrue}% + \else + \def\normalizedfieldmode##1##2##3% + {\edef\@@DriverFieldMode + {\ifcase##1 loner \or parent \or clone \or copy \fi + \ifcase##2 \else(done)\fi}}% + \def\dosetfield##1##2##3##4##5##6##7##8##9% + {\normalizedfieldmode##7% + \immediate\write\scratchwrite + {N=##1 / T=##2 / R=##3 / P=##4 / K=##5 / G=##6 / + M=\@@DriverFieldMode\space/ V=##8 / D=##9}}% + \processcommacommand[\collectedfields]\getfield + \fi + \immediate\closeout\scratchwrite + \egroup} + +\def\logfields + {\dosingleempty\doLogFields} + +%D \starttyping +%D \definefield [name] [type] [group] [values] [default] +%D +%D \definefield [WWWW] [text] [textsetup] [default text] +%D \definefield [XXXX] [push] [pushsetup] [yes,no] [yes] +%D \definefield [XXXX] [check] [checksetup] [yes,no] [yes] +%D \definefield [YYYY] [combo] [combosetup] [a,b,c,d] [b] +%D \definefield [ZZZZ] [radio] [radiosetup] [W,X,Y,Z] [Y] +%D +%D \definesubfield [W] [subsetup] [p,q] +%D \definesubfield [X,Y] [subsetup] [p,r] +%D \definesubfield [Z] [subsetup] [y,z] +%D +%D evt \definemainfield ... wanneer geplaatst voor subs gegeven +%D +%D \clonefield [XXXX] [XX,YY] [mysetup] [on,off] +%D \clonefield [Z] [AA,BB] [somesetup] [true,false] +%D \clonefield [Z] [CC,DD] [anothersetup] +%D +%D \copyfield [XXXX] [PP,QQ,RR] +%D +%D \field[XXXX] +%D \fitfield[XXXX] +%D \stoptyping + +\newif\ifdefinemainfield \definemainfieldfalse + +%D We need to keep track of cloned (related) fields and so by +%D maintaining lists of field clones. +%D +%D The first alternative used a two pass data list and was +%D implemented as follows: +%D +%D \starttyping +%D \def\getmainfieldkids#1% +%D {\let\@@DriverFieldKids\empty +%D \ifdefinemainfield +%D \definetwopasslist{fld:#1}% defined by system +%D \doloop +%D {\gettwopassdata{fld:#1}% +%D \iftwopassdatafound +%D %\addtocommalist\twopassdata\@@DriverFieldKids +%D \appendtocommalist\twopassdata\@@DriverFieldKids +%D \else +%D \exitloop +%D \fi}% +%D \fi} +%D \stoptyping +%D +%D However, the next alternative is much faster when we have +%D a field with thousands of clones, something not that +%D imaginary. +%D +%D \starttyping +%D \def\getmainfieldkids#1% +%D {\let\@@DriverFieldKids\empty +%D \ifdefinemainfield +%D \definetwopasslist{fld:#1}% runtime defined by system +%D \getnamedtwopassdatalist{fld:#1}\@@DriverFieldKids +%D \fi} +%D \stoptyping +%D +%D The data is written by file using: +%D +%D \starttyping +%D \newcounter\nofmainfieldkids +%D +%D \def\setmainfieldkid#1#2% +%D {\doglobal\increment\nofmainfieldkids +%D \savetwopassdata{fld:#1}{\nofmainfieldkids}{#2}} +%D \stoptyping +%D +%D The trade of of this mechanism is that for each cloned or +%D copied field, the uitlity file is to be read in order to +%D fetch the data. +%D +%D The next, much faster alternative uses a dedicated % +%D reference mechanism. + +\def\setmainfieldkid#1#2% + {\immediatewriteutilitycommand{\fieldreference{#1}{#2}}} + +\def\checkfieldreferences + {\startnointerference + \protectlabels + \doutilities{fieldreferences}\jobname\empty\relax\relax + \global\let\checkfieldreferences\relax + \stopnointerference} + +\def\setfieldreferences + {\def\fieldreference##1##2% + {\ifundefined{\r!widget##1}% + \setxvalue{\r!widget##1}{##2}% + \else + \edef\!!stringa{\getvalue{\r!widget##1}}% + \setxvalue{\r!widget##1}{\!!stringa,##2}% + \fi}} + +\def\resetfieldreferences + {\let\fieldreference\gobbletwoarguments} + +\def\getmainfieldkids#1% + {\checkfieldreferences + \ifdefinemainfield + \doifundefinedelse{\r!widget#1}% + {\let\@@DriverFieldKids\empty} + {\@EA\let\@EA\@@DriverFieldKids\csname\r!widget#1\endcsname}% + \else + \let\@@DriverFieldKids\empty + \fi} + +\resetfieldreferences + +%D Of course it costs a few more tokens to implement, but it's +%D worth the memory: running for instance the 2000 page +%D english examns publishing on demand document went down from +%D 1350 seconds to less than 950 on a 650 Mhz pentium. + +\def\definefield + {\definemainfieldfalse\doquintupleempty\dodefinefield} + +\def\definemainfield + {\definemainfieldtrue \doquintupleempty\dodefinefield} + +\let\collectedfields\empty +\newcounter\numberoffields +\newcounter\totalnumberoffields + +\def\savenumberoffields + {\ifcase\numberoffields\relax\else + \savecurrentvalue\totalnumberoffields\numberoffields + \fi} + +\appendtoks \savenumberoffields \to \everybye % \everylastshipout + +% \def\presetfieldreferences +% {\ifnum\totalnumberoffields>0 +% \definereference[AtOpenInitializeForm][\v!ResetForm]% +% \fi} +% +% \definereference[AtOpenInitializeForm][\v!geen] +% +% \appendtoks \presetfieldreferences \to \everycheckreferences + +\def\dodefinefield[#1][#2][#3][#4][#5]% + {\ifsecondargument + \edef\currentfieldname{#1}% just in case we're inside a loop + \doifundefinedelse{define#2field} + {\writestatus\m!fields{unknown field type #2}} + {\doifundefined{fielddata\currentfieldname} + {\getmainfieldkids\currentfieldname + \ifdefinemainfield + \ifx\@@DriverFieldKids\empty + \let\@@DriverFieldMode\fieldlonermode + \else + \let\@@DriverFieldMode\fieldparentmode + \fi + \def\@@DriverFieldAuto{1}% + \else + \let\@@DriverFieldMode\fieldlonermode + \def\@@DriverFieldAuto{0}% + \fi + \def\@@DriverFieldFree{0}% + \getvalue{define#2field}{\currentfieldname}{#2}{#3}{#4}{#5}}}% + \else + \writestatus\m!fields{pass fieldname and fieldtype}% + \fi} + +\def\definelinefield#1#2#3#4#5% + {\setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{#4}} + +\let\definetextfield=\definelinefield + +\def\definechoicefield#1#2#3#4#5% + {\doifelsenothing{#4} + {\def\@@DriverFieldValues{yes,no}} + {\def\@@DriverFieldValues{#4}}% + \doifelsenothing{#5} + {\dogetcommacommandelement2\from\@@DriverFieldValues \to\@@DriverFieldDefault + \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} + {\def\@@DriverFieldDefault{#5}}% + \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} + +\let\definepopupfield=\definechoicefield +\let\definecombofield=\definechoicefield + +%\def\definecheckfield#1#2#3#4#5% +% {\doifelsenothing{#4} +% {\definedefaultsymbols +% \def\@@DriverFieldValues{defaultyes}} +% {\def\@@DriverFieldValues{#4}}% +% \doifelsenothing{#5} +% {\dogetcommacommandelement2\from\@@DriverFieldValues\to\@@DriverFieldDefault +% \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault} +% {\def\@@DriverFieldDefault{#5}}% +% \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}} + +%D Since these fields have an on/off state only, we pass 1/0 +%D to the driver as default values. + +\def\definecheckfield#1#2#3#4#5% + {\doifelsenothing{#4} + {\definedefaultsymbols + \def\@@DriverFieldValues{defaultyes}} + {\def\@@DriverFieldValues{#4}}% + \doifelsenothing{#5} + {\def\@@DriverFieldDefault{2}} + {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldDefault + \doifinstringelse{#5}{\@@DriverFieldDefault} + {\def\@@DriverFieldDefault{1}} + {\def\@@DriverFieldDefault{0}}}% + \setfield + {#1}{#2}{}{}{\@@DriverFieldKids}{#3}% + {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}% + {\@@DriverFieldValues}{\@@DriverFieldDefault}} + +\let\definepushfield=\definecheckfield + +\def\defineradiofield#1#2#3#4#5% + {\iffourthargument + \doifelsenothing{#5} + {\dogetcommacommandelement1\from#4\to\SavedFieldDefault + \dogetcommacommandelement1\from\SavedFieldDefault\to\SavedFieldDefault} + {\def\SavedFieldDefault{#5}}% +% when opt works +% \@EA\beforesplitstring\SavedFieldDefault\at=>\to\SavedFieldDefault + \ifx\@@DriverFieldKids\empty + \setfield{#1}{#2}{}{}{#4}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% + \else + \setfield{#1}{#2}{}{}{#4,\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}% + \fi +% + \def\docommand##1% + {\doifelse{##1}\SavedFieldDefault + {\def\@@DriverFieldDefault{##1}}% + {\let\@@DriverFieldDefault\empty}% + \setfield{##1}{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% +% when opt works +% \def\docommand##1% +% {\@EA\beforesplitstring##1\at=>\to\FieldValue +% \doifelse\FieldValue\SavedFieldDefault +% {\let\@@DriverFieldDefault\FieldValue}% +% {\let\@@DriverFieldDefault\empty}% +% \setfield\FieldValue{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}% + \processcommalist[#4]\docommand + \else + \writestatus\m!fields{pass values too}% + \fi} + +\def\definesubfield + {\dotripleempty\dodefinesubfield} + +\def\dodefinesubfield[#1][#2][#3]% for the moment only radio ones + {\ifsecondargument + \def\docommand##1% + {\getfield{##1}% + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field ##1}% to do + \else + \doifsomething{#2} + {\edef\@@DriverFieldGroup{#2}}% + \doifelsenothing{#3} + {\definedefaultsymbols + \def\@@DriverFieldValues{defaultyes}} + {\def\@@DriverFieldValues{#3}}% + \changefield{##1}% + \fi}% + \processcommalist[#1]\docommand + \else + \writestatus\m!fields{pass fieldname, setupgroup, values and default}% + \fi} + +\def\doclonefield[#1][#2][#3][#4]% parent children setupgroup values + {\ifsecondargument + \getfield{#1}% +\iftrialtypesetting\else + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field #1}% + \else + \let\@@DriverFieldMode\fieldparentmode + %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% + \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% + \processcommalist[#2]\docommand + \changefield{#1}% + \let\@@DriverFieldAutoParent\@@DriverFieldAuto + \def\@@DriverFieldParent{#1}% + \let\@@DriverFieldKids\empty + \let\@@DriverFieldRoot\empty + \let\@@DriverFieldMode\fieldchildmode + \def\@@DriverFieldFree{0}% + \def\@@DriverFieldAuto{0}% + \doifsomething{#3}{\edef\@@DriverFieldGroup{#3}}% + \doifsomething{#4}{\edef\@@DriverFieldValues{#4}}% + \def\docommand##1% + {\ifcase\@@DriverFieldAutoParent\else + \setmainfieldkid{\@@DriverFieldParent}{##1}% + \fi + \changefield{##1}}% + \processcommalist[#2]\docommand + \fi +\fi + \else + \writestatus\m!fields{pass parent field and clones}% + \fi} + +\def\clonefield + {\doquadrupleempty\doclonefield} + +\def\docopyfield[#1][#2]% parent children + {\ifsecondargument + \getfield{#1}% +\iftrialtypesetting\else + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field #1}% + \else + \let\@@DriverFieldMode\fieldparentmode + %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}% + \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}% + \processcommalist[#2]\docommand + \changefield{#1}% + \let\@@DriverFieldAutoParent\@@DriverFieldAuto + \def\@@DriverFieldParent{#1}% + \let\@@DriverFieldKids\empty + \let\@@DriverFieldRoot\empty + \let\@@DriverFieldMode\fieldcopymode + \def\@@DriverFieldFree{0}% + \def\@@DriverFieldAuto{0}% + \def\docommand##1% + {\ifcase\@@DriverFieldAutoParent\else + \setmainfieldkid{\@@DriverFieldParent}{##1}% + \fi + \changefield{##1}}% + \processcommalist[#2]\docommand + \fi +\fi + \else + \writestatus\m!fields{pass parent field and copies}% + \fi} + +\def\copyfield{\dodoubleempty\docopyfield} + +\unexpanded\def\field {\dotripleempty\dofield[\dohandlefield]} +\unexpanded\def\fitfield{\dotripleempty\dofield[\dohandlefitfield]} + +\def\dofield[#1][#2][#3]% + {\iffirstargument + \bgroup + \getfield{#2}% + \ifsecondargument + \def\@@DriverFieldLabel{#3}% + \else + \let\@@DriverFieldLabel\@@DriverFieldName + \fi + \ifx\@@DriverFieldType\empty + \writestatus\m!fields{unknown field #2}% + \else\ifcase\@@DriverFieldFree\relax + \doifdefinedelse{\strippedcsname\setupfield\@@DriverFieldGroup} + {\let\dosetupfield=#1\getvalue{\strippedcsname\setupfield\@@DriverFieldGroup}} + {#1[\@@DriverFieldName][\v!label,\v!frame,\v!horizontal][][][]}% +\iftrialtypesetting\else + \def\@@DriverFieldFree{1}% + \changefield{#2}% +\fi + \else\ifcase\@@DriverFieldAuto\relax + % \writestatus\m!fields{field #2 already typeset}% + \else + % \writestatus\m!fields{field #2 automatically copied}% + \nextsystemfield + \copyfield[\@@DriverFieldName][\currentsystemfield]% + \dotripleempty\dofield[#1][\currentsystemfield][#3]% get the if's right + \fi\fi\fi + \egroup + \fi} + +\def\typesetfield + {\useJSscripts[fld]% + \ifx\@@DriverFieldRoot\empty \else + \let\@@SavedFieldName\@@DriverFieldName + \getfield\@@DriverFieldRoot + \ifcase\@@DriverFieldFree\relax + \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot + \dopresetrecord +\iftrialtypesetting\else + \def\@@DriverFieldFree{1}% + \changefield\@@DriverFieldName +\fi + \fi + \getfield\@@SavedFieldName + \fi + \ifx\@@DriverFieldKids\empty + \donefalse + \else + \donetrue + \fi + \ifdone + \let\@@DriverFieldParent\@@DriverFieldName + %\addtocommalist\@@DriverFieldParent\@@DriverFieldKids + \appendtocommalist\@@DriverFieldParent\@@DriverFieldKids + \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot + \dopresetfield + \let\@@DriverFieldMode\fieldchildmode + \fi + \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot + \dopresetfield} + +\def\dopresetfield + {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType field}\fi\fi} + +\def\dopresetrecord + {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType record}\fi\fi} + +\def\dodefinethefieldset[#1][#2]% + {\dodefinefieldset{#1}{#2}} + +\def\definefieldset% + {\dodoubleargument\dodefinethefieldset} + +\def\normaldodosetupfield[#1][#2][#3][#4][#5]% + {\doifdefinedelse{\strippedcsname\setupfield#1} + {\pushmacro\dosetupfield + \def\dosetupfield[##1][##2][##3][##4][##5]% + {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][##2,#2][##3,#3][##4,#4][##5,#5]}}% + \getvalue{\strippedcsname\setupfield#1}% + \popmacro\dosetupfield} + {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}}} + +\let\dodosetupfield\normaldodosetupfield + +\def\donosetupfield[#1][#2][#3][#4][#5]% + {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}} + +\def\dosetupfield[#1][#2][#3][#4][#5]% + {\iffifthargument + \def\docommand##1{\dodosetupfield[##1][#2][#3][#4][#5]}% + \processcommalist[#1]\docommand + \else\ifthirdargument + \def\docommand##1{\dodosetupfield[##1][#2][][][#3]}% + \processcommalist[#1]\docommand + \else\ifsecondargument + \doifelse{#2}\v!reset + {\def\docommand##1{\donosetupfield[#1][][][][]}} + {\def\docommand##1{\dodosetupfield[##1][][][][#2]}}% + \processcommalist[#1]\docommand + \else\iffirstargument + \def\docommand##1{\dodosetupfield[##1][][][][]}% + \processcommalist[#1]\docommand + \else + \writestatus\m!fields{provide either 1, 2, 3 or 5 arguments}% + \fi\fi\fi\fi} + +\def\setupfield + {\doquintupleempty\dosetupfield} + +\def\dosetupfields[#1][#2][#3][#4]% + {\ifsecondargument + \def\dodosetupfield[##1][##2][##3][##4][##5]% + {\doifdefinedelse{\strippedcsname\setupfield##1} + {\def\dosetupfield[####1][####2][####3][####4][####5]% + {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,####2,##2][#2,####3,##3][#3,####4,##4][#4,####5,##5]}}% + \getvalue{\strippedcsname\setupfield##1}} + {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,##2][#2,##3][#3,##4][#4,##5]}}}% + \else\iffirstargument + \doifelse{#1}\v!reset + {\resetfields} + {\setupfields[][][][#1]}% checken + \else + \writestatus\m!fields{provide either 1 or 4 arguments}% + \fi\fi} + +\def\setupfields + {\doquadrupleempty\dosetupfields} + +\def\resetfields + {\let\dodosetupfield\normaldodosetupfield} + +% \setupfields[\v!reset] + +% opties: veld, label, kader, vertikaal/horizontaal + +\newif\ifShowFieldLabel +\newif\ifShowFieldFrame +\newif\ifVerticalField +\newif\ifHorizontalField + +% way to slow/complicated, we need some simple alternative +% as well + +\def\dohandlefield[#1][#2][#3][#4][#5]% + {\presetlocalframed[\??fd]% + \processallactionsinset + [#2] + [ \v!reset=>\ShowFieldLabelfalse\ShowFieldFramefalse + \HorizontalFieldfalse\VerticalFieldfalse, + \v!label=>\ShowFieldLabeltrue, + \v!frame=>\ShowFieldFrametrue, + \v!horizontal=>\HorizontalFieldtrue, + \v!vertical=>\VerticalFieldtrue]% + \ifVerticalField + \getparameters[\??fd] + [\c!distance=\!!zeropoint,\c!inbetween=\vskip\@@localoffset, + \c!align=\v!right,\c!width=20em]% + \else\ifHorizontalField + \getparameters[\??fd] + [\c!distance=\@@localoffset,\c!inbetween=,\c!align=\c!left, + \c!height=10ex]% + \else + \getparameters[\??fd] + [\c!distance=\!!zeropoint,\c!inbetween=,\c!align=\c!left]% + \fi\fi + \getparameters[\??fd] + [\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=,#3]% + \reshapeframeboxfalse % else ugly spacing + \ifShowFieldFrame + \localframed[\??fd][\c!strut=\v!no,\c!align=]\bgroup + \else + \vbox\bgroup + \fi + \dontcomplain + \ifShowFieldLabel + \setbox0\hbox + {\reshapeframeboxtrue % else wrong dimensions + \framed + [\c!style=,\c!color=,\c!align=\c!right,#4] + {\@@DriverFieldLabel}}% + \fi + \setbox2\hbox + {\reshapeframeboxtrue % else wrong dimensions + \ifVerticalField + \setupframed[\c!height=6ex,\c!width=\hsize]% + \else\ifHorizontalField + \setupframed[\c!height=\vsize,\c!width=20em]% + \else + \setupframed[\c!height=2cm,\c!width=2cm]% + \fi\fi + \framed + [\c!align=\v!right,\c!strut=\v!no,#5] + {\getparameters + [\??fd] + [\c!color=,\c!style=,\c!align=\v!right,\c!option=, + \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, + \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, + \c!focusin=,\c!focusout=, + \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, + \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5]% + \scratchdimen\framedwidth \edef\@@DriverFieldWidth {\the\scratchdimen}% + \scratchdimen\framedheight\edef\@@DriverFieldHeight{\the\scratchdimen}% + \vfill + \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}} + \vss}}% + \ifShowFieldLabel + \ifVerticalField + \vbox + {\copy0 + \@@fdinbetween + \copy2}% + \else + \hbox + {\vbox \ifdim\ht2>\ht0 to \ht2 \fi + {\@@fdbefore + \copy0 + \@@fdafter}% + \hskip\@@fddistance + \vbox \ifdim\ht0>\ht2 to \ht0 \fi + {\@@fdbefore + \box2 + \@@fdafter}}% + \fi + \else + \box2 + \fi + \egroup} + +\chardef\fitfieldmode\plusone % 3 = best + +\def\dohandlefitfield[#1][#2][#3][#4][#5]% alleen check + {\presetlocalframed[\??fd]% + \localframed + [\??fd] + [\c!n=1024, % beware: weblink plug in truncates + \c!strut=\v!no,\c!color=,\c!style=,\c!option=, + \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=, + \c!focusin=,\c!focusout=, + \c!afterkey=,\c!format=,\c!validate=,\c!calculate=, + \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=, + \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5,\c!align=] + {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldValue + \ifx\@@DriverFieldValue\empty + \let\@@DriverFieldValue\@@DriverFieldDefault + \fi + \dopresetfieldsymbol\@@DriverFieldValue + \setbox\scratchbox\hbox{\dogetfieldsymbol\@@DriverFieldValue}% + \scratchdimen\wd\scratchbox \edef\@@DriverFieldWidth {\the\scratchdimen}% + \scratchdimen\ht\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% + \ifcase\fitfieldmode + \typesetfield + \or % 1 = ignore depth (original, assumed no depth, actually a bug) + \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% + \or % 2 = add depth to height, but no depth in result + \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% + \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% + \or % 3 = add depth to height, and apply depth to result + \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}% + \hbox to \wd\scratchbox{\lower\dp\scratchbox\hbox{\typesetfield}\hfill}% + \fi}} + +%D Common stuff + +\newcounter\nofsystemfields + +\def\nextsystemfield + {\doglobal\increment\nofsystemfields + \def\currentsystemfield{sys::\nofsystemfields}} + +%D An example: + +\def\fillinfield + {\dosingleempty\dofillinfield} + +\def\dofillinfield[#1]#2% + {\dontleavehmode + \hbox + {\forgetall + \setupfields[\v!reset]% + \nextsystemfield + \useJSscripts[ans]% + \doifelsenothing{#1} + {\def\therightanswer{#2}} + {\def\therightanswer{#1}}% + \setbox0\hbox{#2}% + \setbox2\hbox{\therightanswer}% + \dimen0=\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi + \advance\dimen0 .2em + \definefield + [\currentsystemfield][line][systemfield]% + \setupfield + [systemfield] + [\c!n=1024, % beware: weblink plugin truncates + \c!location=\v!low,\c!strut=\v!yes,\c!fieldoffset=0pt, + \c!height=1.2\openlineheight,\c!width=\dimen0,\c!offset=\v!overlay, + \c!style=,\c!align=\v!middle,\c!frame=\v!off, + \c!color=red,\c!fieldbackgroundcolor=\s!white,\c!fieldframecolor=blue, + \c!validate=JS(Check_Answer{\currentsystemfield,\therightanswer})]% + \switchtobodyfont + [\c!small]% + \hbox to \wd0 + {\copy0\hskip-\wd0\hss\field[\currentsystemfield]\hss}}} + +%D and another one: + +\def\tooltip + {\dosingleempty\dotooltip} + +\def\dotooltip[#1]#2#3% + {\bgroup + \setupfields[\v!reset]% + \useJSscripts[fld]% + \setbox0\hbox + {\dontcomplain + \nextsystemfield + \setbox0\hbox{#2}% + \definesymbol + [\currentsystemfield:txt] + [{\inframed[\c!frame=\v!off,\c!background=\v!screen]{#3}}]% + \setbox2\hbox{\symbol[\currentsystemfield:txt]}% + \definefield + [\currentsystemfield:txt][check] + [dummy][\currentsystemfield:txt][\currentsystemfield:txt]% + \setupfield + [dummy] + [\c!frame=\v!off, + \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), + \c!option=\v!hidden]% + \hbox to \zeropoint + {\dimen0\wd2\advance\dimen0 -\wd0 + \doifelse{#1}\v!left + {\hskip-\dimen0} + {\doif{#1}\v!middle + {\hskip-.5\dimen0}}% + \lower\openlineheight\hbox to \zeropoint + {\fitfield[\currentsystemfield:txt]}}% + \dimen0=\ifdim\wd0=\zeropoint 3em\else\wd0\fi + \definesymbol + [\currentsystemfield:but] + [{\framed[\c!height=2ex,\c!width=\dimen0,\c!frame=\v!off]{}}]% + \definefield + [\currentsystemfield:but][push] + [dummy][\currentsystemfield:but][\currentsystemfield:but]% + \setupfield + [dummy] + [\c!frame=\v!off, + \c!option=, + \c!regionin=JS(Vide_Field{\currentsystemfield:txt}), + \c!regionout=JS(Hide_Field{\currentsystemfield:txt}), + \c!fieldlayer=\@@iafieldlayer]% + \lower2ex\hbox to \zeropoint + {\fitfield[\currentsystemfield:but]}% + #2}% + \ht0\strutht\dp0\strutdp\box0 + \egroup} + +%D And one more: + +\def\definefieldstack + {\dotripleargument\dodefinefieldstack} + +\def\dodefinefieldstack[#1][#2][#3]% name, symbols, settings + {\doifundefined{fieldstack:#1} + {\setgvalue{fieldstack:#1}{\dodofieldstack[#1][#2][#3]}}} + +\def\dodofieldstack[#1][#2][#3]% start=n, 0 == leeg + {\bgroup + \getparameters[\??fd][\c!start=1,#3]% + \setupfields[\v!reset]% + \definesymbol[\v!empty][]% + \useJSscripts[fld][FieldStack]% + \newcounter\stackedfieldnumber + \def\dododofieldstack##1% + {\increment\stackedfieldnumber + \ifnum\stackedfieldnumber=\@@fdstart\relax + \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][##1]% + \else + \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][\v!empty]% + \fi}% + \processcommalist[#2]\dododofieldstack + \setupfield[#1][\v!reset]% added + \setupfield[#1][\c!option=\v!readonly,#3]% #3 swapped + \newcounter\stackedfieldnumber + \def\dododofieldstack##1% + {\doglobal\increment\stackedfieldnumber + \fitfield[#1:\stackedfieldnumber]\egroup\bgroup}% + \startoverlay + \bgroup + \globalprocesscommalist[#2]\dododofieldstack + \egroup + \stopoverlay + \egroup} + +\def\dofieldstack[#1][#2][#3]% + {\ifsecondargument + \dodefinefieldstack[#1][#2][#3]\fieldstack[#1]% + \else + \getvalue{fieldstack:#1}\setgvalue{fieldstack:#1}{[#1]}% + \fi} + +\def\fieldstack + {\dotripleempty\dofieldstack} + +%D When submitting a form, we need to tell the driver module +%D that we want \FDF\ or \HTML. + +\def\setupforms + {\dodoubleargument\getparameters[\??fr]} + +\def\checksubmitform#1% + {\setsubmitoutputformat\@@frmethod} + +\setexecutecommandcheck {submitform} \checksubmitform + +\setupforms + [\c!method=HTML] + +\protect \endinput diff --git a/tex/context/base/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..c9fcbd29a --- /dev/null +++ b/tex/context/base/scrn-hlp.mkiv @@ -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-int.mkii b/tex/context/base/scrn-int.mkii new file mode 100644 index 000000000..38d50a350 --- /dev/null +++ b/tex/context/base/scrn-int.mkii @@ -0,0 +1,2217 @@ +%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}% + \letgvalue{\s!link:#1:f}\twopassdata + \getlasttwopassdata{\s!link:#1}% + \letgvalue{\s!link:#1:l}\twopassdata + \letgvalue{\s!link:#1:s}\noftwopassitems + \gettwopassdata{\s!link:#1}% + \letgvalue{\s!link:#1:c}\twopassdata + \letgvalue{\s!link:#1:n}\twopassdata}} + +\def\koppeling[#1]#2% + {\bgroup + \definieerkoppeling[#1]% + \doglobal\increment\numberoflinks + \gettwopassdata{\s!link:#1}% + \edef\numberoflinks{0\getvalue{\s!link:#1:s}}% + \edef\firstlink {0\getvalue{\s!link:#1:f}}% + \edef\lastlink {0\getvalue{\s!link:#1:l}}% + \edef\currentlink {0\getvalue{\s!link:#1:n}}% + \edef\prevlink {0\getvalue{\s!link:#1:c}}% + \iftwopassdatafound + \edef\nextlink{0\twopassdata}% + \letgvalue{\s!link:#1:n}\nextlink + \letgvalue{\s!link:#1:c}\currentlink + \else + \edef\nextlink{0\getvalue{\s!link:#1:l}}% + \fi + \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% + \ifnum\noflinks<\plustwo + \locationfalse + \fi + \iflocation + \hbox + {\setinteractionparameter\c!width\!!zeropoint + \dogotosomepage\??lk\gotobegincharacter\firstlink\hss + \ifnum\noflinks>\plustwo + \hskip\@@lkdistance + \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss + \fi + \hskip\@@lkdistance + #2\relax + \hskip\@@lkdistance + \ifnum\noflinks>\plustwo + \dogotosomepage\??lk\goforwardcharacter\nextlink\hss + \hskip\@@lkdistance + \fi + \dogotosomepage\??lk\gotoendcharacter\lastlink}% + \else + \hbox{#2}% + \fi + \egroup} + +\def\definieerkoppeling[#1]% % local loading ! + {\doifundefined{\s!link:#1:\s!list} + {\expanded{\definetwopasslist{\s!link:#1}}% \expanded{\doloadtwopassdata{\s!link:#1}}% + \getfirsttwopassdata{\s!link:#1}% + \let\firstlink\twopassdata + \getlasttwopassdata{\s!link:#1}% + \let\lastlink\twopassdata + \let\noflinks\noftwopassitems + \gettwopassdata{\s!link:#1}% + \let\currentlink\twopassdata + \let\nextlink\twopassdata + \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}}} + +\def\koppeling[#1]#2% + {\bgroup + \definieerkoppeling[#1]% + \doglobal\increment\numberoflinks + \gettwopassdata{\s!link:#1}% + \def\next[##1:##2:##3:##4:##5]% + {\edef\firstlink {0##1}% + \edef\lastlink {0##2}% + \edef\noflinks {0##3}% + \edef\prevlink {0##4}% + \edef\currentlink{0##5}}% + \expanded{\next[\getvalue{\s!link:#1:}]}% + \edef\nextlink{0\iftwopassdatafound\twopassdata\else\lastlink\fi}% + \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}% + \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% + \ifnum\noflinks<\plustwo + \locationfalse + \fi + \iflocation + \hbox + {\setinteractionparameter\c!width\!!zeropoint + #2\relax + \hskip\@@lkdistance + \dogotosomepage\??lk\gotobegincharacter\firstlink\hss + \ifnum\noflinks>\plustwo + \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss + \fi + \ifnum\noflinks>\plustwo + \dogotosomepage\??lk\goforwardcharacter\nextlink\hss + \hskip\@@lkdistance + \fi + \dogotosomepage\??lk\gotoendcharacter\lastlink}% + \else + \hbox{#2}% + \fi + \egroup} + +\let\setupinteractionscreens\empty + +\def\docalculateinteractionscreen + {\doifelse\@@scwidth\v!fit + {\!!widtha\leftcombitotal + \ifdim\backspace>\!!widtha\ifdim\backspace>\zeropoint\relax + \advance\backspace -\!!widtha + \fi\fi + \advance\!!widtha\rightcombitotal + \advance\!!widtha 2\dimexpr\@@scbackspace+\@@schoroffset\relax} + {\doifelse\@@scwidth\v!max + {\!!widtha\printpaperwidth} + {\!!widtha\@@scwidth}}% + \doifelse\@@scheight\v!fit + {\!!heighta\dimexpr\topheight+\topdistance\relax + \ifdim\topspace>\!!heighta\ifdim\topspace>\zeropoint\relax + \advance\topspace -\!!heighta + \fi\fi + \advance\!!heighta \dimexpr\makeupheight+\bottomdistance+\bottomheight\relax + \advance\!!heighta 2\dimexpr\@@sctopspace+\@@scveroffset\relax} + {\doifelse\@@scheight\v!max + {\!!heighta\printpaperheight} + {\!!heighta\@@scheight}}% + \doif\@@scdelay\v!none{\let\@@scdelay\zerocountervalue}} + +% The macro is not to be changed; only the \@@ia-variables +% may be set! ConTeXt is the producer but we no longer +% mention the pragma site, since we don't want to be bothered +% with remarks about third party documents and/or associated +% with documents produced outside our control. + +\def\doprepareidentity % beware, we need to construct + {\let\!!stringa\@@iakeyword % an unexpanded space separated + \let\@@iakeyword\empty % list of keywords from a comma + \def\doprepareidentity##1% % separated one + {\ifx\@@iakeyword\empty + \appended\def\@@iakeyword{##1}% + \else + \appended\def\@@iakeyword{ ##1}% + \fi}% + \@EA\processcommalist\@EA[\!!stringa]\doprepareidentity + \global\let\doprepareidentity\relax} + +%D The Creator field is changed per 12/04/2006 due to user presure. This +%D means that I need to put my own status info someplace else. + +\def\initializeidentity + {\doprepareidentity + \dosetupidentity % no \expanded{..} will be done in special (else no pdfdoc) + {\@@iatitle}{\@@iasubtitle}{\@@iaauthor}% + {ConTeXt - \contextversion}% + {\@@iadate}{\@@iakeyword}% + \global\let\initializeidentity\relax} + +\appendtoks \initializeidentity \to \everyshipout + +\def\initializepaper + {\bgroup + \ifx\@@ppleft \empty + \ifx\@@ppright\empty + \ifx\@@pptop \empty + \ifx\@@ppbottom \empty + \ifx\@@pcstate\v!start + \locationfalse\fi\else + \locationfalse\fi\else + \locationfalse\fi\else + \locationfalse\fi\else + \locationfalse\fi + \iflocation % without screen settings + \egroup + \dosetuppaper\papersize\paperwidth\paperheight + \else + \egroup + \dosetuppaper\printpapersize\printpaperwidth\printpaperheight + \fi} + +\appendtoks \initializepaper \to \everyshipout + +\def\doinitializepaper + {\bgroup + \docalculateinteractionscreen + \ifdim\!!widtha>\paperwidth\ifdim\!!widtha>\zeropoint + \paperwidth\!!widtha + \fi\fi + \ifdim\!!heighta>\paperheight\ifdim\!!heighta>\zeropoint + \paperheight\!!heighta + \fi\fi + \dosetuppaper + {\printpapersize} + {\the\paperwidth} + {\the\paperheight}% + \egroup} + +\let\@@pcscreendata\empty + +\def\dosetupinteractionscreens % met a, b en \number + {\doifnot\@@pcstate\v!start\dodosetupinteractionscreens} + +\setvalue{\??sc\c!option\v!max }{1} % tzt share with driver +\setvalue{\??sc\c!option\v!bookmark }{2} % tzt share with driver +\setvalue{\??sc\c!option\v!fit }{3} % tzt share with driver +\setvalue{\??sc\c!option\v!doublesided}{4} % tzt share with driver + +\def\dodosetupinteractionscreens % met a, b en \number + {\bgroup + \docalculateinteractionscreen + \!!counte=0\getvalue{\??sc\c!option\@@scoption}\relax + % niet waterdicht + \doifnot{\the\!!widtha\the\!!heighta}\@@pcscreendata + {\xdef\@@pcscreendata{\the\!!widtha\the\!!heighta}% + \showmessage\m!interactions1{\withoutpt\the\!!widtha,\withoutpt\the\!!heighta}}% + % needs to be split: dimensions for each page + % and mode per document and only once ! + \dosetupscreen \backoffset\topoffset\!!widtha\!!heighta{\the\!!counte}% + \dosetupcropbox\backoffset\topoffset\!!widtha\!!heighta + \egroup} + +\def\dosetupinteractionscreen[#1]% + {\getparameters[\??sc][#1]% + \ifproductionrun + \let\initializepaper\doinitializepaper + \let\setupinteractionscreens\dosetupinteractionscreens + \fi} + +\appendtoks \setupinteractionscreens \to \everyfirstshipout % needed to get option=max etc working +\appendtoks \setupinteractionscreens \to \everyshipout % needed for page/screen dimensions + +\def\setupinteractionscreen + {\dosingleempty\dosetupinteractionscreen} + +%D Due to requests I finally decided to support bookmarks, a +%D driver dependant way of showing tables of content. The most +%D simple way of support is hooking bookmark generation into +%D the existing list mechanisms. That way users can generate +%D bookmarks automatically, although its entirely valid to add +%D bookmarks by defining alternative ones. These will be added +%D at the appropriate place in the list. + +% \hoofdstuk{het eerste hoofdstuk} +% +% \bookmark {de eerste bookmark} % optional overruled hoofdstuk +% +% .... text .... +% +% \placebookmarks [hoofdstuk,paragraaf,subparagraaf,subsubparagraaf,mylist] +% [open list] +% +% \bookmark[mylist]{whatever} + +\def\@@bookmark {bm::} +\def\@@booklevel{bl::} +\def\@@bookcount{bc::} + +\definelist[\@@bookmark] + +\newtoks\postponedbookmarks + +\def\flushpostponedbookmark + {\the\postponedbookmarks + \global\postponedbookmarks\emptytoks} + +\def\simplebookmark#1% + {\doglobal\prependtoks + \writetolist[\@@bookmark]{}{#1}% + \to\postponedbookmarks} + +\def\complexbookmark[#1]#2% + {\doglobal\appendtoks\writetolist[#1]{}{#2}\to\postponedbookmarks} + +\definecomplexorsimple\bookmark + +\newif\iftracebookmarks \tracebookmarksfalse + +\let\tracebookmarks\tracebookmarkstrue + +\def\placebookmarks + {\dodoubleempty\doplacebookmarks} + +\def\doplacebookmarks[#1][#2]% + {\iflocation + \iffirstargument + \bgroup + \ifsecondargument + \doifelse{#2}\v!all + {\edef\openbookmarklist{#1}} + {\edef\openbookmarklist{#2}}% + \else + \let\openbookmarklist\empty + \fi + \global\let\bookmarklevellist\empty + \def\bookmarklevelcount{0}% + \doprocessbookmarks[#1]\dogetbookmarkelement + \dolistelement{}{}{}{}{}{}% needed to finish the first pass + \doprocessbookmarks[#1]\doputbookmarkelement + \flushbookmark + \egroup + \else + \expanded{\placebookmarks\@EA[\getvalue{\??ih\v!content\c!list}]}% + \fi + \fi} + +\def\doprocessbookmarks[#1]#2% + {\let\dolistelement#2\relax + \scratchcounter\zerocount + \def\docommand##1% + {\advance\scratchcounter \plusone + \getlistlevel[##1]\listlevel{\the\scratchcounter}% + \setxvalue{\@@bookcount\the\scratchcounter}{1}% + \setxvalue{\@@booklevel##1}{\listlevel}}% + \processcommalist[#1]\docommand + \setxvalue{\@@bookcount0}{1}% + \global\chardef\currentbookmarklevel\zerocount + \global\chardef\previousbookmarklevel\zerocount + \doutilities{listentries,#1,\@@bookmark}\jobname{#1}\relax\relax} + +\def\dodogetbookmarkelement#1#2#3#4#5#6% + {\doifelsenothing{#1} + {\global\chardef\currentbookmarklevel\zerocount} + {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% + \ifnum\currentbookmarklevel>\previousbookmarklevel + \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% + \else\ifnum\currentbookmarklevel<\previousbookmarklevel + \bgroup + \!!counta\previousbookmarklevel + \doloop + {\let\bookmarktag\empty + \!!countb\!!counta + \advance\!!countb \minusone + \dorecurse\!!countb + {\edef\bookmarktag + {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% + \edef\bookmarklevelcount + {\getvalue{\@@bookcount\the\!!counta}}% + \xdef\bookmarklevellist + {\bookmarklevellist/\bookmarktag:\bookmarklevelcount/}% + \advance\!!counta \minusone + \ifnum\!!counta=\currentbookmarklevel + \exitloop + \fi}% + \egroup + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax + \else + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax + \fi\fi + \global\utilitydonetrue + \global\chardef\previousbookmarklevel\currentbookmarklevel} + +\def\getbookmarklevelcount + {\@EA\def\@EA\docommand\@EA[\@EA##\@EA1\@EA/\bookmarktag:##2/##3]% + {\def\bookmarklevelcount{##2}}% + \@EA\@EA\@EA\docommand\@EA\@EA\@EA[\@EA\bookmarklevellist\@EA/\bookmarktag:0/]} + +\def\dodoputbookmarkelement#1#2#3#4#5#6% + {\doifelsenothing{#1} + {\global\chardef\currentbookmarklevel\zerocount} + {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% + \ifnum\currentbookmarklevel>\previousbookmarklevel + \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% + \else\ifnum\currentbookmarklevel<\previousbookmarklevel + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax + \else + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax + \fi\fi + \let\bookmarktag\empty + \!!countb\currentbookmarklevel + \dorecurse\!!countb + {\edef\bookmarktag + {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% + \getbookmarklevelcount + \iftracebookmarks + \bgroup + \par + \bookmarktag\quad + \dorecurse\currentbookmarklevel{\quad}\unskip#1\quad + (\bookmarklevelcount)\quad + \egroup + \fi + \global\chardef\previousbookmarklevel\currentbookmarklevel + \global\utilitydonetrue + \insertsomebookmark{#1}{\the\currentbookmarklevel}{\bookmarklevelcount}{#4}{#6}} + +\def\dogetbookmarkelement#1#2#3#4#5#6% + {\doifnot{#1}\@@bookmark + {\dodogetbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\doputbookmarkelement#1#2#3#4#5#6% + {\doifelse{#1}\@@bookmark + {\localbookmark{#4}} + {\flushbookmark + \dodoputbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} + +\let\flushbookmark\relax +\let\localbookmark\gobbleoneargument + +\def\insertsomebookmark#1#2#3#4#5% + {\gdef\flushbookmark + {\doinsertsomebookmark{#1}{#2}{#3}{#4}{#5}{g}}% + \gdef\localbookmark##1% + {\doinsertsomebookmark{#1}{#2}{#3}{##1}{#5}{l}}} + +\def\doinsertsomebookmark#1#2#3#4#5#6% + {\global\utilitydonetrue + \global\let\localbookmark\gobbleoneargument + \global\let\flushbookmark\relax + \doifinstringelse{#1}\openbookmarklist + {\chardef\openbookmark\plusone} + {\chardef\openbookmark\zerocount}% + \iftracebookmarks(#6: #4)\quad(\the\openbookmark)\par\fi + \doinsertbookmark{#2}{#3}{#4}{#5}{\openbookmark}} + +% \startinteractionmenu[rechts] +% \but [eerste] eerste \\ +% \txt hello world \\ +% \but [tweede] tweede \\ +% \nop \\ +% \but [tweede] tweede \\ +% \rul whow \\ +% \but [tweede] tweede \\ +% \raw hello world \\ +% \but [tweede] tweede \\ +% \com \vfill \\ +% \but [derde] derde \\ +% \stopinteractionmenu + +\newif\iflocationmenupermitted + +\def\testinteractionmenu#1% + {\iflocation + \doifelse\@@iamenu\v!on + {\doifelsevalue{\??am#1\c!state}\v!start + {\global\locationmenupermittedtrue} + {\global\locationmenupermittedfalse}} + {\global\locationmenupermittedfalse}% + \else + \global\locationmenupermittedfalse + \fi} + +\def\dodisableinteractionmenu[#1][#2][#3]% + {\def\dododisableinteractionmenu##1% + {\doifelse{#3}{} + {\letvalue{\??am##1\c!obstruction}\empty} + {\edef\interactieblokkade{\getvalue{\??am##1\c!obstruction}} + \def\docommand####1{#1{####1}{\interactieblokkade}}% #1 = \remove or \add + \processcommalist[#3]\docommand + \setevalue{\??am##1\c!obstruction}{\interactieblokkade}}}% + \processcommalist[#2]\dododisableinteractionmenu} + +\def\disableinteractionmenu + {\dotripleempty\dodisableinteractionmenu[\addtocommalist]} + +\def\enableinteractionmenu + {\dotripleempty\dodisableinteractionmenu[\removefromcommalist]} + +% ja : kader/achtergrond met tekst +% leeg : kader/achtergrond maar geen tekst +% nee : alleen ruimte reserveren +% geen : helemaal weglaten + +\newif\iflocationdummy +\newif\ifskippedmenuitem + +\newif\iflocationempty +\newif\iflocationclick + +% ja : kader/achtergrond met tekst +% leeg : kader/achtergrond maar geen tekst +% nee : alleen ruimte reserveren +% geen : helemaal weglaten +% +% \setupinteractionmenu[right][samepage=yes, unknownreference=yes] +% \setupinteractionmenu[right][samepage=empty,unknownreference=empty] +% \setupinteractionmenu[right][samepage=no, unknownreference=no] +% \setupinteractionmenu[right][samepage=none, unknownreference=none] +% +% \startinteractionmenu[right] +% \but [firstpage] first \\ +% \but [lastpage] last \\ +% \but [somepage] crap \\ +% \stopinteractionmenu + +\def\dosetlocationboxcontent#1[#2]#3[#4]% + {\global\skippedmenuitemfalse + \setbox\locationbox\hbox + {\resetgoto % anders cyclische aanroep ! + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}}% + \iflocationclick + \hbox{\gotolocation{#4}{\box\locationbox}}% + \else + \hbox{\box\locationbox}% + \fi} + +\let\dosetlocationboxyes\dosetlocationboxcontent + +\def\dosetlocationboxempty#1[% + {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,} + +\def\dosetlocationboxno#1[% + {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,\c!frame=,\c!background=,} + +\def\dosetlocationboxnone#1[#2]#3[#4]% + {\global\skippedmenuitemtrue} + +\def\setlocationboxyes#1[#2]#3[#4]% + {\locationclicktrue + \setbox\locationbox\hbox + {\resetgoto % anders cyclische aanroep ! + \global\skippedmenuitemfalse + \gotolocation + {#4}% % needed + {\ifrealreferencepage + \ifcase\csname\??am\??am\csname#1\c!samepage\endcsname\endcsname\relax + \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \global\skippedmenuitemtrue + \fi + \else + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \fi}}% + \ifskippedmenuitem\else\box\locationbox\fi} + +\def\setlocationboxnop#1[#2]#3[#4]% + {\locationclickfalse + \setbox\locationbox\hbox + {\resetgoto % anders cyclische aanroep ! + \global\skippedmenuitemfalse + \ifcase\csname\??am\??am\csname#1\c!unknownreference\endcsname\endcsname\relax + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \global\skippedmenuitemtrue + \fi}% + \ifskippedmenuitem\else\box\locationbox\fi} + +\def\setlocationboxraw#1[#2]#3[#4]% + {\localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}} + +\def\setlocationbox#1[#2]#3[#4]% + {\bgroup % really needed ! + \edef\permittedreferences{\csname#1\c!obstruction\endcsname}% + \doifreferencepermittedelse{#4}% + {\setlocationboxyes{#1}[#2]{#3}[#4]}% + {\setlocationboxnop{#1}[#2]{#3}[#4]}% + \egroup} + +\def\setlocationnop#1[#2]#3% + {\localframed[#1][#2]{#3}} + +\def\executeamboxcommands#1#2#3#4#5% + {%\processaction + % [\getvalue{\??am#1\c!dummy}] + % [ \v!yes=>\chardef\handleunknownmenuitem=0\relax, + % \v!empty=>\chardef\handleunknownmenuitem=1\relax, + % \v!no=>\chardef\handleunknownmenuitem=2\relax]% + \getvalue{\??am#1#3}\relax + \setamboxcommands{#1}{#4}% + \ignorespaces#2\unskip + \getvalue{\??am#1#5}} + +\newcounter\currentamposition + +\newtoks\everysetmenucommands + +\def\setamboxcommands#1#2% + {\def\currentmenu{#1}% % kan nog eerder + \def\currentsubmenu{#2}% % ? ? + \doglobal\newcounter\currentamposition + \the\everysetmenucommands} + +\def\menu@@amboxcommand#1\\% + {\dontleavehmode + \bgroup + \ignorespaces#1\unskip\relax + \ifskippedmenuitem \else + \getvalue{\??am\currentmenu\currentsubmenu}% + \fi + \egroup + \ignorespaces} + +\appendtoks + \let\@@amboxcommand\menu@@amboxcommand +\to \everysetmenucommands + +\def\menu@raw[#1]#2\\% + {\@@amboxcommand\gotobox{\ignorespaces#2\unskip}[#1]\\}% + +\def\menu@but[#1]#2\\% + {\@@amboxcommand\do@@amposition\currentmenu{#1}{\setlocationbox{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}\\}% + +\def\menu@got[#1]#2\\% pas op! offset + {\@@amboxcommand\setlocationbox{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]\\}% + +\def\menu@nop#1\\% + {\@@amboxcommand\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]\\}% + +\def\menu@txt#1\\% + {\@@amboxcommand\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}\\}% + +\def\menu@rul#1\\% ook \do@@amposition ! + {\@@amboxcommand\localframed[\??am\currentmenu][]{\ignorespaces#1\unskip}\\}% + +\def\menu@com#1\\% + {\ignorespaces#1\unskip\ignorespaces}% + +\appendtoks + \let\raw\menu@raw + \let\but\menu@but + \let\got\menu@got + \let\nop\menu@nop + \let\txt\menu@txt + \let\rul\menu@rul + \let\com\menu@com +\to \everysetmenucommands + +\ifx\do@@amposition\undefined + \let\do@@amposition\gobbletwoarguments % hook for positional thingies +\fi + +\let\currentmenu\empty + +% beware : never change the concept of pbgoffset + +\def\menuparameter#1{\csname\??am\currentmenu#1\endcsname} + +\def\@@amhbox#1#2#3#4% + {\def\currentmenu{#3}% + \testinteractionmenu{#3}% + \iflocationmenupermitted + \bgroup + \showcomposition + \scratchdimen\dimexpr + \makeupwidth + +\pagebackgroundhoffset + +\pagebackgroundhoffset + -\menuparameter\c!leftoffset + -\menuparameter\c!rightoffset + \relax + \setbox\scratchbox\hbox to \scratchdimen + {\forgetall\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}% + \setbox\scratchbox\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}% + \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet) + \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax + \box\scratchbox + \egroup + \else + #1\relax + \fi} + +\def\@@amvbox#1#2#3#4% don't change skipping, this one works! + {\def\currentmenu{#3}% + \testinteractionmenu{#3}% + \iflocationmenupermitted + \bgroup + \showcomposition + \scratchdimen\dimexpr + \textheight + +\pagebackgroundvoffset + +\pagebackgroundvoffset + +\pagebackgrounddepth + -\menuparameter\c!topoffset + -\menuparameter\c!bottomoffset + \relax + \setbox\scratchbox\vbox to \scratchdimen + {\forgetall % Voor't geval de afstand + %\setupblank[\v!standard]% % (tijdelijk) is aangepast. + \restorestandardblank + \hsize#2\relax + \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}% + \setbox\scratchbox\vbox{\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}}% + \setbox\scratchbox\vbox + {\ht\scratchbox\zeropoint + \vskip\dimexpr-\pagebackgroundvoffset+\menuparameter\c!topoffset\relax + \box\scratchbox + \vskip\pagebackgroundvoffset}% overbodig + \ht\scratchbox\textheight + \wd\scratchbox#2\relax + \box\scratchbox + \egroup + \else + #1\relax + \fi} + +\ifx\do@@ammenuposition\undefined + \let\do@@ammenuposition\gobbleoneargument % hook for positional thingies +\fi + +\setvalue{\??am\s!do\v!right }{\@@amvbox{\dodummypageskip\v!right }\rightedgewidth} +\setvalue{\??am\s!do\v!left }{\@@amvbox{\dodummypageskip\v!left }\leftedgewidth } +\setvalue{\??am\s!do\v!top }{\@@amhbox{\dodummypageskip\v!top }\topheight } +\setvalue{\??am\s!do\v!bottom}{\@@amhbox{\dodummypageskip\v!bottom}\bottomheight } + +\def\dointeractionmenu#1#2% + {\getvalue{\??am\s!do\getvalue{\??am#1\c!location}}{#1}{#2}} + +\unexpanded\def\interactionmenu[#1]% + {\getvalue{\??am\c!menu#1}} + +\def\horizontalinteractionmenu#1#2#3#4% + {\ifdim#2>\zeropoint % new + \scratchdimen\zeropoint + \setbox\scratchbox\hbox + {\def\docommand##1% + {\doifnotvalue{\??am##1\c!state}\v!none + {\hskip\scratchdimen + \setbox2\hbox to #2 + {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% + \doifelsevalue{\??am##1\c!distance}\v!overlay + {\scratchdimen\zeropoint + \wd2\zeropoint}% + {\scratchdimen\getvalue{\??am##1\c!distance}}% + \box2}}% + \startinteraction + \processcommacommand[\getvalue{\??am#1}]\docommand + \stopinteraction}% + \wd\scratchbox#2\relax + \box\scratchbox + \fi} + +\def\verticalinteractionmenu#1#2#3#4% + {\ifdim#2>\zeropoint % new + \scratchdimen\zeropoint + \setbox\scratchbox\vbox + {\def\docommand##1% + {\doifnotvalue{\??am##1\c!state}\v!none + {\vskip\scratchdimen + \setbox2\vbox to #2 + {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% + \doifelsevalue{\??am##1\c!distance}\v!overlay + {\scratchdimen\zeropoint + \offinterlineskip + \dp2\zeropoint + \ht2\zeropoint}% + {\scratchdimen\getvalue{\??am##1\c!distance}}% + \box2}}% + \startinteraction + \processcommacommand[\getvalue{\??am#1}]\docommand + \stopinteraction}% + \ht\scratchbox#2\relax + \dp\scratchbox\zeropoint + \box\scratchbox + \fi} + +\letvalue{\??am\v!left }\empty +\letvalue{\??am\v!right}\empty +\letvalue{\??am\v!top }\empty +\letvalue{\??am\v!bottom }\empty + +% todo : \defineinteractionmenuclass + +\def\interactionmenus[#1]% + {\iflocation + \getvalue{\??am\??am\c!menu#1}% + \else + \dodummypageskip{#1}% + \fi} + +\setvalue{\??am\??am\c!menu\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth \c!left \c!right} +\setvalue{\??am\??am\c!menu\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth\c!left \c!right} +\setvalue{\??am\??am\c!menu\v!top }{\verticalinteractionmenu \v!top \topheight \c!before\c!after} +\setvalue{\??am\??am\c!menu\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight \c!before\c!after} + +% this can be implemented with the following command (which +% is new, undocumented, experimental, untested, etc etc) + +\def\defineinteractionmenuclass + {\dodoubleargument\dodefineinteractionmenuclass} + +\def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri + {\doifelse{#2}\v!vertical + {\setvalue{\??am\??am\c!menu#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}\c!before\c!after}} + {\setvalue{\??am\??am\c!menu#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}\c!left\c!right }}} + +% \setupinteraction[menu=on,state=start] +% +% \defineinteractionmenuclass[test] [vertical] +% \defineinteractionmenuclass[another][horizontal] +% +% \defineinteractionmenu[test] [left][state=start,width=4cm] +% \defineinteractionmenu[another][top] [state=start,height=1cm] +% +% \startinteractionmenu[test] +% \but [firstpage] test-a \\ +% \but [nextpage] test-b \\ +% \stopinteractionmenu +% +% \startinteractionmenu[another] +% \but [firstpage] test-a \\ +% \but [nextpage] test-b \\ +% \stopinteractionmenu +% +% \setupheadertexts[{\interactionmenu[another]}] +% +% \starttext +% +% test \interactionmenu[test] \page +% test \interactionmenu[test] \page +% +% \stoptext + +%D This can save complicated menu macros when one want to +%D keep control over parts of a menu (i.e.\ turn them on and +%D off). We could have achieved something similar with modes. + +\def\local@@ambox#1#2#3#4% don't change skipping, this one works! + {\bgroup + \testinteractionmenu{#3}% + \iflocationmenupermitted + \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after + \else + #1\relax + \fi + \egroup} + +\def\includemenu[#1]% + {\doifvalue{\??am#1\c!state}\v!local + {\bgroup + \letvalue{\??am#1\c!state}\v!start + \let\@@amvbox\local@@ambox + \let\@@amhbox\local@@ambox + \getvalue{\??am\c!menu#1}% + \egroup}} + +%D We also need an explicit position control some day. I'll +%D do that when I need it. [The stacking order.] + +\newif\ifextendedmenu + +% [name] [location] +% [name] [location] [pars] + +\def\defineinteractionmenu + {\dotripleempty\dodefineinteractionmenu} + +\def\dodefineinteractionmenu[#1][#2][#3]% + {% main settings + \letvalue{\??am\c!menu#1}\empty + \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}% + \presetlocalframed[\??am#1]% + % register location + \expanded{\addtocommalist{#1}\@EA\noexpand\csname\??am#2\endcsname}% + % inherit settings + \doifnot{#1}{#2} + {\copyparameters[\??am#1][\??am#2] + [\c!left,\c!middle,\c!right,\c!before,\c!after,\c!inbetween,% + \c!width,\c!height,\c!distance,\c!offset,% + \c!frame,\c!framecolor,\c!rulethickness,% + \c!background,\c!backgroundcolor,\c!backgroundscreen,% + \c!style,\c!color,\c!contrastcolor,\c!samepage,\c!unknownreference,% + \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]}% + % additional settings + \getparameters[\??am#1][\c!location=#2,\c!obstruction=,#3]} + +\def\setupinteractionmenu + {\dodoubleargument\dosetupinteractionmenu} + +\def\dosetupinteractionmenu[#1][#2]% + {\def\docommand##1{\getparameters[\??am##1][#2]}% + \processcommalist[#1]\docommand} + +\expandafter\chardef\csname\??am\??am\v!yes \endcsname\zerocount +\expandafter\chardef\csname\??am\??am\v!empty\endcsname\plusone +\expandafter\chardef\csname\??am\??am\v!no \endcsname\plustwo +\expandafter\chardef\csname\??am\??am\v!none \endcsname\plusthree +\expandafter\chardef\csname\??am\??am \endcsname\plusone % default + +\processbetween{\v!interactionmenu}\dostartinteractionmenu + +\def\dostartinteractionmenu#1% + {\dodostartinteractionmenu#1\dodostopinteractionmenu} + +\def\dodostartinteractionmenu[#1]#2\dodostopinteractionmenu + {\setvalue{\??am\c!menu#1}{\extendedmenutrue\dointeractionmenu{#1}{#2}}} + +\def\resetinteractionmenu[#1]% + {\letvalue{\??am\c!menu#1}\empty} + +\def\dodomenulistelement#1#2#3#4#5#6#7% + {\setbox0=\hbox + {\let\gotolocation\gobbleoneargument % hack to catch last [] + %\locationclickfalse % ipv ^ + \docheckrealreferencepage{#7}% + \setlocationboxyes + {\??am#1}% % needed ! + []% no settings + {\limitatetext{#5}{\getvalue{\??li#2\c!maxwidth}}{\unknown}}% % needed ! + []}% normally the destination, catch by gobble + \@@amboxcommand\do@@amposition{#1}{#7}% beware, we pass the pagenumber + {\ignorespaces\linklisttoelement{#3}{#6}{#7}{\box0}\unskip}\\} + +% \scherm moet worden als \page + +\def\screen + {\dosingleempty\doscreen} + +\def\doscreen[#1]% + {\iflocation\page[#1]\fi} + +\unexpanded\def\menubutton + {\dodoubleempty\domenubutton} + +\def\domenubutton[#1]% + {\iffirstargument + \ifsecondargument + \@EAEAEA\domenubuttonB + \else + \doifassignmentelse{#1} + {\@EAEAEA\domenubuttonC} + {\@EAEAEA\domenubuttonD}% + \fi + \else + \@EA\domenubuttonA + \fi[#1]} + +\def\domenubuttonA[#1][#2]#3[#4]% normal button, no parameters + {\bgroup + %\locationdummytrue + \setlocationbox\??bt[]{#3}[#4]% + \egroup} + +\def\domenubuttonB[#1][#2]#3[#4]% menu button, with parameters + {\bgroup + %\locationdummytrue + \setlocationbox{\??am#1}[#2]{#3}[#4]% + \egroup} + +\def\domenubuttonC[#1][#2]#3[#4]% normal button, with parameters + {\bgroup + %\locationdummytrue + \setlocationbox\??bt[#1]{#3}[#4]% + \egroup} + +\def\domenubuttonD[#1][#2]#3[#4]% menu button, no parameters + {\bgroup + %\locationdummytrue + \setlocationbox{\??am#1}[]{#3}[#4]% + \egroup} + +\def\menubox + {\dodoubleempty\domenubox} + +\def\domenubox[#1][#2]#3% + {\bgroup + \let\setlocationbox\setlocationboxraw + \domenubutton[#1][#2]#3[]% + \egroup} + +% Hier volgen de synchronisatiemacro's: + +\def\syncprefix{sync} + +%def\syncmarker{syncmark} +%\definemarking[\syncmarker] +%\setupmarking[\syncmarker][\c!expansie=\v!ja] + +\newmark\syncmarker + +\newcounter\synccounter + +\newif\ifsynchronisation + +\def\startsynchronization% + {\iflocation\ifsynchronisation + \doglobal\increment\synccounter + \fi\fi} + +\def\stopsynchronization% + {\iflocation\ifsynchronisation + %\thisisdestination{\syncprefix:\synccounter}% + \pagereference[\syncprefix:\synccounter]% + \ifvmode + \@EA\setmark\@EA\syncmarker\@EA{\synccounter} % \marking[\syncmarker]{\synccounter}% + \else + \showmessage\m!interactions4\synccounter + \fi + \fi\fi} + +\def\synchronize% + {\startsynchronization + \stopsynchronization} + +\def\dosetupsynchronization[#1]% + {\getparameters[\??sy][#1]% + \doifelse\@@systate\v!start + \synchronisationtrue + \synchronisationfalse} + +\def\setupsynchronization + {\dosingleargument\dosetupsynchronization} + +\def\definesynchronization + {\dosingleargument\dodefinesynchronization} + +\def\setupsynchronizationbar + {\dodoubleargument\getparameters[\??ba]} + +\presetlocalframed[\??ba] + +\setvalue{synchronisatie\v!page}[#1]% + {\bgroup + %\setupinteraction[\c!width=\!!zeropoint]% + \setinteractionparameter\c!width\!!zeropoint + \setbox0\hbox + {\localframed[\??ba][]{\dolocationattributes\??ba\c!style\c!color{\strut\@@batext}}}% + \dontcomplain + \def\atthebottom + {\leaders\hrule\!!depth1ex\!!height-.5ex\hfil}% + \def\atthetop##1##2##3% + {\dimen0=\wd0 + \divide\dimen0 3 + \multiply\dimen0 ##2\relax + \dimen2=.25em % brrr + \advance\dimen0 -##3\dimen2 + %\gotodestination + % {}{#1}{\syncprefix:##1}{} + % {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}}% + \gotobox + {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}% + [#1::\syncprefix:##1]}% + \hbox + {\def\check##1##2% + {\edef##2{0##1\syncmarker}% + \ifnum0##2=0 \def##2{1}\fi}% + \check\gettopmark\top + \check\getfirstmark\first + \check\getbotmark\bot + \setbox2\hbox to \wd0 + {\ifnum\top=\first\relax + \ifnum\first=\bot\relax + \atthetop\first30\relax + \else + \atthetop\first21\hss\atthetop\bot11\relax + \fi + \else + \ifnum\first=\bot\relax + \atthetop\top11\hss\atthetop\first21\relax + \else + \atthetop\top11\hss\atthetop\first11\hss\atthetop\bot11\relax + \fi + \fi}% + \wd2=\zeropoint\box2 + \box0\relax}% + \egroup} + +\setvalue{synchronisatie\v!local}[#1]% + {\bgroup + %\setupinteraction[\c!width=\!!zeropoint]% + \setinteractionparameter\c!width\!!zeropoint + \def\blackrule{\hbox{\vrule\!!height.5em\!!width.5em}}% + %\gotodestination + % {}{##1}{\syncprefix:#1}{0} + % {\color[\locationcolor\@@bacolor]{\blackrule}}% + \gotobox % + {\color[\locationcolor\@@bacolor]{\blackrule}}% + [#1::\syncprefix:\synccounter]% + \egroup} + +\def\synchronizationbar[#1][#2]% + {\iflocation\ifsynchronisation + \bgroup + \setupsynchronizationbar + [\c!text=\getvalue{doc:des:#1},#2]% + \getvalue{synchronisatie\@@baalternative}[#1]% + \egroup + \fi\fi} + +% A nice application of glue. All this code will be rewritten and +% generalized. + +\newbox\interactionbarbox + +\newif\ifbarsymbol + +\def\dogotosomepage#1#2#3% nog checken ! + {\checkreferences % nodig ?? + \hbox + {\iflocation + \ifnum#3=\realpageno + #2% + \else + \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% + \fi + \else + #2% + \fi}} + +\def\dogotosomecontrastpage#1#2#3% nog checken, may replace previous + {\checkreferences % nodig ?? + \hbox + {\iflocation + \ifnum#3=\realpageno + \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!contrastcolor}{#2}}% + \else + \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% + \fi + \else + #2% + \fi}} + +\presetlocalframed[\??ib] + +\def\interactionbara % we need better control over contrastcolor + {\iflocation % maybe just use gotopage and set colors + \bgroup + \setinteractionparameter\c!width\zeropoint + \setupblackrules[\c!height=\v!max,\c!depth=\v!max]% + \!!widthb\dimexpr\@@ibwidth-2.75\emwidth\relax + \!!widtha\dimexpr\!!widthb/\lastpage\relax + \bgroup + \advance\realpageno\minusone + \ifvoid\interactionbarbox + \bgroup + \processaction + [\@@ibstep] + [ \v!small=>\scratchdimen.25\emwidth, + \v!medium=>\scratchdimen.5\emwidth, + \v!big=>\scratchdimen\emwidth, + \s!unknown=>\scratchdimen\!!widtha]% + \ifdim\!!widtha<\scratchdimen\relax + \!!counta\numexpr\scratchdimen/\!!widtha\relax + \else + \!!counta\@@ibstep\relax + \fi + \!!widtha\!!counta\!!widtha + \setbox\scratchbox\hbox{\blackrule[\c!width=\!!widtha,\c!color=middlegray]}% color here, else no mkiv + \global\setbox\interactionbarbox\hbox to \!!widthb + {\hss + \dostepwiserecurse\plusone\lastpage\!!counta + {\gotorealpage\empty\empty\recurselevel{\copy\scratchbox}}% + \hss}% + \global\wd\interactionbarbox\zeropoint + \egroup + \fi + \egroup + \noindent + \strut + \hbox to \@@ibwidth + {\dontcomplain + \setupblackrules[\c!width=\emwidth]% + \dogotosomecontrastpage\??ib\blackrule\firstpage + \hss + \copy\interactionbarbox + \hbox to \!!widthb + {\ifdim\!!widtha<\emwidth + \!!widtha\emwidth + \fi + \setupblackrules[\c!width=\!!widtha]% + \ifnum\realpageno>\plusone + \!!counta\numexpr\realpageno-\plustwo\relax + \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow + \dogotosomepage\??ib\blackrule\prevpage + \fi + \dogotosomecontrastpage\??ib{\blackrule[\c!width=.5em]}\realpageno + \ifnum\realpageno<\lastpage\relax + \dogotosomepage\??ib\blackrule\nextpage + \!!counta\numexpr\lastpage-\realpageno-\plusone\relax + \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow + \fi}% + \hss + \dogotosomecontrastpage\??ib\blackrule\lastpage}% + \egroup + \fi} + +\def\interactionbarb + {\ifnum\lastpage>\firstpage\relax + \interactionbuttons[\v!firstpage,\v!previouspage,\v!nextpage,\v!lastpage]% + \fi} + +\def\interactionbarc + {\iflocation + \ifnum\lastpage>\plusone + \hbox to \@@ibwidth + {\setupblackrules[\c!height=\@@ibheight,\c!depth=\@@ibdepth]% + \scratchdimen\dimexpr(\@@ibwidth-4\emwidth)/\numexpr\lastpage+\minusone\relax\relax + \!!widtha\numexpr\realpageno+\minusone\relax\scratchdimen + \!!widthb\numexpr\lastpage-\realpageno\relax\scratchdimen + \startcolor[\locationcolor\@@ibcolor]% + \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\firstpage + \hss + \dogotosomepage\empty{\blackrule[\c!width=\!!widtha]}\prevpage + \color[\@@ibcontrastcolor]{\blackrule[\c!width=\emwidth]}% + \dogotosomepage\empty{\blackrule[\c!width=\!!widthb]}\nextpage + \hss + \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\lastpage + \stopcolor}% + \fi + \fi} + +\def\interactionbard + {\iflocation\ifshowingsubpage + \ifnum\nofsubpages>\plusone + \hbox \bgroup + \setinteractionparameter\c!width\!!zeropoint + \ifbarsymbol + \setupsymbolset[\@@iasymbolset]% + \def\dogotox##1% + {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi]}}% + \else + \def\dogotox##1% + {\hbox{\vrule\!!height\@@ibheight\!!depth \@@ibdepth\!!width \@@ibwidth}}% + \fi + \dostepwiserecurse\plusone\nofsubpages\plusone + {\bgroup + \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax + \ifnum\scratchcounter<\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter + \else\ifnum\scratchcounter=\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter + \else + \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter + \fi\fi + \egroup + \hskip\@@ibdistance}% + \unskip % not needed + \egroup + \fi + \fi\fi} + +\def\interactionbare% KAN WORDEN GECOMBINEERD MET D + {\iflocation\ifshowingsubpage + \ifnum\nofsubpages>\plusone + \bgroup + \!!widthb\dimexpr\nofsubpages\dimexpr\@@ibdistance\relax-\@@ibdistance\relax % (n-1) + \!!widtha\dimexpr(\@@ibwidth-\!!widthb)/\nofsubpages\relax + \ifdim\!!widtha<\@@ibdistance\relax + \interactionbarf + \else + \setinteractionparameter\c!width\!!zeropoint + \noindent + \hbox to \@@ibwidth + \bgroup + \ifbarsymbol + \setupsymbolset[\@@iasymbolset]% + \def\dogotox##1% + {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi}}% + \else + \def\dogotox##1% + {\hbox{\vrule\!!height\@@ibheight\!!depth\@@ibdepth\!!width\!!widtha}}% + \fi + \dostepwiserecurse\plusone\nofsubpages\plusone + {\bgroup + \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax + \ifnum\scratchcounter<\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter + \else\ifnum\scratchcounter=\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter + \else + \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter + \fi\fi + \egroup + \hss}% + \unskip + \egroup + \fi + \egroup + \fi + \fi\fi} + +\def\interactionbarf % !! KAN WORDEN GECOMBINEERD MET D !! + {\iflocation\ifshowingsubpage + \ifnum\nofsubpages>\plusone + \setinteractionparameter\c!width\!!zeropoint + \noindent + \hbox to \@@ibwidth + \bgroup + \!!countb\zerocount + \loop % todo: \doloop + \advance\!!countb \plusone + %\!!countc\nofsubpages \divide\!!countc \!!countb \advance\!!countc \plusone + \!!countc\numexpr(\nofsubpages/\!!countb)+\plusone\relax % rounding + \!!widthb\@@ibdistance + \multiply\!!widthb \!!countc + \advance\!!widthb -\@@ibdistance + \!!widtha\@@ibwidth + \advance\!!widtha -\!!widthb + \divide\!!widtha \!!countc + \ifdim\!!widtha<\@@ibdistance\relax + \repeat + \ifnum\!!countc>\plusone + % this is not that well tested + \advance\!!countc \minustwo + \!!widtha-\@@ibdistance + \!!widtha\!!countc\!!widtha + \advance\!!widtha \@@ibwidth + \advance\!!countc \plusone + \divide\!!widtha \!!countc + \fi + \ifbarsymbol + \setupsymbolset[\@@iasymbolset]% + \def\dogotox##1% + {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!somewhere\or\v!somewhere\or\v!next\fi}}% + \else + \def\dogotox##1% + {\hbox + {\!!heighta\@@ibheight + \!!deptha\@@ibdepth + \ifcase##1\relax + \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha + \or + \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha + \or + \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha + \or + \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha + \or + \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha + \fi}}% + \fi + \!!countc\numexpr\realpageno-\plustwo\relax + \!!countd\numexpr\realpageno+\plustwo\relax + \ifnum\!!countc<\plusone \!!countc\plusone \fi + \!!countf\zerocount + \dostepwiserecurse\firstsubpage\lastsubpage\plusone + {\!!doneafalse + \advance\!!countf \plusone + \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi + \ifnum\recurselevel=\lastsubpage\relax \!!doneatrue \fi + \if!!donea + \ifnum\recurselevel<\realpageno + \dogotosomecontrastpage\??ib{\dogotox0}\recurselevel + \else\ifnum\recurselevel>\realpageno + \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel + \else + \dogotosomecontrastpage\??ib{\dogotox4}\recurselevel + \fi\fi + \hss + \!!countf\zerocount + \else\ifnum\!!countf=\!!countb + \ifnum\recurselevel<\realpageno + \dogotosomecontrastpage\??ib{\dogotox1}\recurselevel + \else\ifnum\recurselevel>\realpageno + \dogotosomecontrastpage\??ib{\dogotox3}\recurselevel + \else + \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel + \fi\fi + \hss + \!!countf\zerocount + \fi\fi}% + \unskip + \egroup + \fi + \fi\fi} + +\def\interactionbarg + {\ifnum\lastsubpage>\firstsubpage\relax + \interactionbuttons[\v!firstsubpage,\v!previoussubpage,\v!nextsubpage,\v!lastsubpage]% + \fi} + +\def\checkinteractionbar#1#2#3% + {\ifdim\@@ibwidth=\zeropoint\def\@@ibwidth{#1}\fi + \doifnothing\@@ibheight{\def\@@ibheight{#2}}% + \doifnothing\@@ibdepth{\def\@@ibdepth{#3}}} + +\def\complexinteractionbar[#1]% + {\doifelse{#1}\v!reset + {\global\setbox\interactionbarbox\emptybox}% + {\bgroup + \iflocation + \checksubpages % goes wrong / loads \numberofpages too + \getparameters[\??ib][#1]% + \doif\@@ibstate\v!start + {\startinteraction + \processaction % breedte defaults ! + [\@@ibalternative] + [ c=>\checkinteractionbar{10em}\v!max \v!max, + d=>\checkinteractionbar{.5em}{.5em} \!!zeropoint, + e=>\checkinteractionbar{10em}{.5em} \!!zeropoint, + f=>\checkinteractionbar{10em}{.5em} \!!zeropoint, + \s!default=>\checkinteractionbar{10em}\v!broad\!!zeropoint, + \s!unknown=>\checkinteractionbar{10em}\v!broad\!!zeropoint]% + \doifelse\@@ibsymbol\v!yes + \barsymboltrue\barsymbolfalse + \getvalue{interactionbar\@@ibalternative}% + \stopinteraction}% + \fi + \egroup}} + +\definecomplexorsimpleempty\interactionbar + +\def\setupinteractionbar + {\dodoubleargument\getparameters[\??ib]} + +% Er wordt vooralsnog uitgegaan van een symmetrische +% start-stop situatie. + +\def\c!profiel!! {profiel:} % brrr +\def\c!versie!! {versie:} + +\def\dodefineprofile[#1][#2]% + {\iflocation + \def\dododefineprofile##1% + {\def\dodododefineprofile####1% + {\doifdefinedelse{\c!profiel!!####1}% + {\edef\!!stringa{\getvalue{\c!profiel!!####1}}% + \setevalue{\c!profiel!!####1}{\!!stringa,##1}}% + {\setevalue{\c!profiel!!####1}{##1}}}% + \processcommalist[#2]\dodododefineprofile}% + \processcommalist[#1]\dododefineprofile + \fi} + +\def\defineprofile% + {\dodoubleargument\dodefineprofile} + +% Als met \getpar wordt gewerkt, dan moet \next worden toegepast. + +% TZT initialisatie! + +\def\profilepage{} + +\let\dosetprofilepage\relax +\let\dogetprofilepage\relax + +\def\processprofile#1[#2]% + {\iflocation + \par % needed for pdftex + \bgroup + \dosetprofilepage + \dogetprofilepage + \def\processoneprofile##1##2% + {\ExpandBothAfter\doifinsetelse{##2}{\processedprofiles}% + {\doifsomething{##1}{(##1)}}% + {\addtocommalist{##2}\processedprofiles + ##1\relax + \ifcase#1\relax + \dobeginofprofile{##2}\paperwidth\paperheight\profilepage + \else + \doendofprofile + \fi}}% + \let\processedprofiles\empty + \def\doprocessprofile##1% + {\doifelse{\@@pfoption}{\v!test}% + {\goodbreak\blank\nobreak\tt[\space + \ifcase#1\v!start\else\v!stop\fi profiel\space ##1:\space + \doifdefinedelse{\c!profiel!!##1}% + {\def\dodoprocessprofile####1% + {\processoneprofile + {\goto{####1}[\c!profiel!!####1]}% + {####1}% + \space}% + \processcommacommand + [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}% + {- }% + ]\nobreak\blank}% + {\doifdefined{\c!profiel!!##1}% + {\def\dodoprocessprofile####1% + {\processoneprofile{}{####1}}% + \processcommacommand + [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}}}% + \processcommalist[#2]\doprocessprofile + \egroup + \par % needed for pdftex + \fi} + +\def\startprofile[#1]% + {\iflocation + \bgroup + \addtocommalist{#1}\actualprofile + \def\stopprofile% + {\processprofile1[#1]% + \egroup}% + \def\next{\processprofile0[#1]}% % \DoAfterFi \processprofile0[#1]% + \else % ^^^^^^^^^^ will be obsolete + \let\next\relax % since ugly and never used + \fi + \next} + +\let\stopprofile\relax + +\def\dofollowprofile#1[#2]% + {\iflocation + \hbox + {\dohandlegoto + {\dolocationattributes\??ia\c!style\c!color{#1\presetgoto}}% + {\dostartgotoprofile\buttonwidth\buttonheight{#2}}% + {\dostopgotoprofile}}% + \else + {#1}% + \fi} + +\def\followprofile#1[#2]% + {\iflocation + \doif\@@pfoption\v!test{\pagereference[\c!profiel!!#2]}% + \dofollowprofile{#1}[#2]% + \fi} + +\def\setupprofiles% + {\dodoubleargument\getparameters[\??pf]} + +% Als er nog geen tekst op de pagina staat, dan heeft het +% profiel betrekking op het bovenstaande, dus soms een vorige +% pagina! Vreemd, omdat PDF paginagewijs werkt. Gelukkig +% biedt /page een oplossing. Echter: expansie van een +% \special kan niet worden uitgesteld, zodat alleen een +% two-pass een oplossing vormt. Het onderstaande kan komen +% te vervallen als Acrobat dit ondervangt. Het scheelt een +% pass en een lijst. +% +% Er kunnen eventueel twee lijsten worden gebruikt. Een voor +% het begin (start) en een voor het eind (stop). Nu staat +% alles in een lijst. + +\definetwopasslist\s!profile + +\newcounter\currentprofile + +\def\dosetprofilepage% + {\doglobal\increment\currentprofile + \lazysavetwopassdata{\s!profile}{\currentprofile}{\noexpand\realfolio}} + +\def\dogetprofilepage% + {\gettwopassdata{\s!profile}% + \let\profilepage=\twopassdata} + +% is this stuff used at all + +\newcounter\versionlevel +\newcounter\versionorder + +\newif\ifrecentversion + +\let\oldatcharacter=@ + +\def\minimumversion{0} +\def\actualversion{0} + +\def\dosetupversions[#1]% + {\getparameters[\??ve][#1] + \stripcharacter.\from\@@venumber\to\minimumversion} + +\def\setupversions + {\dosingleargument\dosetupversions} + +\definetwopasslist\s!versionbegin +\definetwopasslist\s!versionend + +\let\actualprofile\empty + +\def\doresetpageversion + {\lazysavetwopassdata{\s!versionend}{\versionorder}{\noexpand\realfolio}} + +\def\dosetpageversion#1% + {\recentversiontrue + \doglobal\increment\versionorder\relax + \lazysavetwopassdata{\s!versionbegin}{\versionorder}{\noexpand\realfolio}% + \let\resetpageversion\doresetpageversion} + +\def\recentcontributions{} + +\def\checkrecentcontributions% + {\gettwopassdata{\s!versionbegin}% + \iftwopassdatafound + \!!counta\twopassdata\relax + \gettwopassdata{\s!versionend}% + \iftwopassdatafound + \!!countb\twopassdata\relax + \doglobal\increment\versionorder\relax + \savetwopassdata{\s!versionbegin}{\versionorder}{\the\!!counta}% + \savetwopassdata{\s!versionend }{\versionorder}{\the\!!countb}% + \dostepwiserecurse\!!counta\!!countb\plusone + {\@EA\doglobal\@EA\addtocommalist\@EA{\recurselevel}{\recentcontributions}}% + \let\next\checkrecentcontributions + \else + \let\next\relax + \fi + \else + \let\next\relax + \fi + \next} + +\def\docheckpageversion + {\ExpandBothAfter\doifinsetelse{\realfolio}{\recentcontributions} + {\pageselectedtrue}% + {\pageselectedfalse}} + +\let\setpageversion \gobbleoneargument +\let\resetpageversion \relax +\let\checkpageversion \relax + +\def\complexstartversion[#1]% + {\bgroup + \doifelsenothing\actualprofile + {\startprofile[#1]}% + {\startprofile[#1,\actualprofile]}% + \def\docomplexstartversie##1% + {\stripcharacter.\from##1\to\actualversion + \ifnum\versionlevel>\zerocount\relax + \ifnum\actualversion=\zerocount + \setpageversion\actualversion % unknown version + \else + \ifnum\actualversion<\minimumversion\relax + \relax % old version + \else + \setpageversion\actualversion % new version + \fi + \fi + \fi}% + \doglobal\increment\versionlevel\relax + \doifelsenothing{#1} + {\docomplexstartversie{0}}% + {\processcommalist[#1]\docomplexstartversie}} + +\definecomplexorsimpleempty\startversion + +\def\stopversion + {\stopprofile + \doglobal\decrement\versionlevel + \ifnum\versionlevel<\zerocount + \showmessage\m!versions1\empty + \else + \resetpageversion + \egroup + \fi} + +\def\markversion + {\showmessage\m!versions2\empty + \let\setpageversion\dosetpageversion + \let\resetpageversion\relax + \let\checkpageversion\relax} + +\def\selectversion + {\checkrecentcontributions + \showmessage\m!versions3\recentcontributions + \let\setpageversio\gobbleoneargument + \let\resetpageversion\relax + \let\checkpageversion\docheckpageversion} + +\def\dodefineversion[#1][#2]% + {\setvalue{\c!versie!!#1}{#2}% + \defineprofile[#1][#2]} + +\def\defineversion + {\dodoubleargument\dodefineversion} + +\def\followversion + {\followprofile} + +\def\followprofileversion#1[#2][#3]% + {\def\docommand##1% + {\defineprofile[#2#3][##1]}% + \processcommacommand[\getvalue{\c!versie!!#3}]\docommand + \followprofile#1[#2#3]} + +\newcounter\currentpagetransition + +\newif\ifrandomtransitions + +\def\setuppagetransitions% + {\dosingleempty\dosetuppagetransitions} + +\def\dosetuppagetransitions[#1]% + {\doifelsenothing{#1} + {\doifnot\@@scdelay\v!none + {\let\setpagetransition\setsomepagedelay}} + {\doifelse{#1}\v!start + {\doifnot\@@scdelay\v!none + {\let\setpagetransition\setsomepagedelay}} + {\doglobal\newcounter\currentpagetransition + \doifinsetelse{#1}{\v!reset,\v!stop} + {\let\setpagetransition\relax} + {\let\setpagetransition\setsomepagetransition + \doifinsetelse\v!random{#1} + {\randomtransitionstrue}{\randomtransitionsfalse}% + \edef\userpagetransitions{#1}% + \@EA\removefromcommalist\@EA{\v!random}\userpagetransitions + \ifx\userpagetransitions\empty + \let\userpagetransitions\pagetransitions + \fi}}}} + +\def\setsomepagedelay + {\expanded{\dosetpagetransition{0}{\@@scdelay}}} + +\def\setsomepagetransition + {\iflocation + \ifrandomtransitions + \expanded{\getcommalistsize[\userpagetransitions]}% + \getrandomnumber\currentpagetransition1\commalistsize + \else + \doglobal\increment\currentpagetransition + \fi + \expanded{\getfromcommalist[\userpagetransitions][\currentpagetransition]}% + \doifnumberelse\commalistelement + {\expanded{\getfromcommalist[\pagetransitions][\commalistelement]}} + {}% + \ifx\commalistelement\empty + \doglobal\newcounter\currentpagetransition + \setsomepagetransition + \else + \doifelse\@@scdelay\v!none + {\expanded{\dosetpagetransition{\commalistelement}{0}}} + {\expanded{\dosetpagetransition{\commalistelement}{\@@scdelay}}}% + \fi + \fi} + +\prependtoks \setpagetransition \to \everyshipout + +% temporary here + +%D \startbuffer +%D \dorecurse{10} +%D {\horizontalpositionbar +%D \pos\recurselevel \min1 \max10 +%D \token\framed{\recurselevel}% +%D \\} +%D +%D \hbox to 15em +%D {\hss +%D \dorecurse{10} +%D {\verticalpositionbar\pos\recurselevel\min1\max10\token\blackrule\\ +%D \hss}} +%D \stopbuffer + +\def\horizontalpositionbar\pos#1\min#2\max#3\token#4\\% + {\hbox to \hsize + {\hskip\zeropoint\!!plus #1\!!fill + \hskip\zeropoint\!!plus-#2\!!fill + #4\relax + \hskip\zeropoint\!!plus #3\!!fill + \hskip\zeropoint\!!plus-#1\!!fill}} + +\def\verticalpositionbar\pos#1\min#2\max#3\token#4\\% + {\vbox to \vsize + {\vskip\zeropoint\!!plus #1\!!fill + \vskip\zeropoint\!!plus-#2\!!fill + \hbox{#4}\relax + \vskip\zeropoint\!!plus #3\!!fill + \vskip\zeropoint\!!plus-#1\!!fill}} + +\def\horizontalgrowingbar\pos#1\min#2\max#3\height#4\depth#5\\% + {\hbox to \hsize + {\scratchcounter#1% + \advance\scratchcounter -#2% + \advance\scratchcounter \plusone + \leaders\vrule\hskip\zeropoint\!!plus \scratchcounter\!!fill + \vrule\!!width\zeropoint\!!height#4\!!depth#5% + \hskip\zeropoint\!!plus #3\!!fill + \hskip\zeropoint\!!plus-#1\!!fill}} + +\def\verticalgrowingbar\pos#1\min#2\max#3\width#4\\% + {\vbox to \vsize + {\scratchcounter#1% + \advance\scratchcounter -#2% + \advance\scratchcounter \plusone + \leaders\hrule\vskip\zeropoint\!!plus\scratchcounter\!!fill + \hrule\!!width#4\!!height\zeropoint\!!depth\zeropoint + \vskip\zeropoint\!!plus #3\!!fill + \vskip\zeropoint\!!plus-#1\!!fill}} + +\newbox\commentbox + +\def\doflushcommentanchors + {\let\next\relax % new + \processaction + [\@@cclocation] + [% \v!text=>\let\next\relax, % new + \v!inmargin=>\let\next\inmargin, % brr not the same as inleft|rightmargin + \v!leftedge=>\let\next\inleftedge, + \v!rightedge=>\let\next\inrightedge, + \v!leftmargin=>\let\next\inleftmargin, + \v!rightmargin=>\let\next\inrightmargin]% + \next{\hbox{\raise\strutht\box\commentbox}}} + +\def\flushcommentanchors % in everypar so indirect + {\ifvoid\commentbox\else \doflushcommentanchors \fi} + +\def\setupcomment + {\dodoubleargument\getparameters[\??cc]} + +\setvalue{\e!start\v!comment}% the dummy triple gobbles trailing spaces + {\dotripleempty\dostartcommentaar} + +\def\comment + {\dodoubleempty\docomment} + +\def\dodocomment#1% + {\!!widtha\@@ccwidth + \!!heighta\@@ccheight + \doifelse\@@ccoption\v!max + {\let\@@ccopen \!!plusone}{\let\@@ccopen \!!zerocount}% + \doifelse\@@ccoption\v!buffer + {\let\@@cccollect\!!plusone}{\let\@@cccollect\!!zerocount}% + \preparecommentvariables + \doinsertcomment + \@@cctitle\!!widtha\!!heighta + \@@cccolor\@@ccopen\@@ccsymbol + \@@cccollect{#1}} + +\def\preparecommentvariables % more will move here as with fields + {\let\@@DriverCommentLayer\@@cctextlayer} + +\def\dopreparecommentaar#1#2% + {\doifassignmentelse{#1} + {\getparameters[\??cc][#1]} + {\getparameters[\??cc][\c!title=#1,#2]}% + \obeylines + \doif\@@ccspace\v!yes\obeyspaces} + +\def\dostartcommentaar[#1][#2][#3]% + {\bgroup + \doifelse\@@ccstate\v!start + {\dopreparecommentaar{#1}{#2}% + \long\def\docommand##1% + {\global\setbox\commentbox\frozenhbox + {\hbox to \zeropoint + {\struttedbox{\tbox{\dodocomment{##1}}}\hss}% + \hskip\ifvoid\commentbox\@@ccmargin\else\@@ccdistance\fi + \box\commentbox}% + \egroup}}% + {\long\def\docommand##1% + {\egroup}}% + \grabuntil{\e!stop\v!comment}\docommand} + +\letvalue{\e!stop\v!comment}\relax % handy for \expanded{...} + +\def\docomment[#1][#2]#3% + {\doif\@@ccstate\v!start + {\hbox to \zeropoint + {\dopreparecommentaar{#1}{#2}% + \hskip-\@@ccmargin + \struttedbox{\tbox{\dodocomment{#3}}\hss}}}% + \ignorespaces} + +% \startcomment +% hello beautiful\\world +% \stopcomment +% +% \startcomment[hello] +% hello << \'e\'erste >> +% beautiful +% world +% \stopcomment +% +% \startcomment[hello][color=green,width=4cm,height=3cm] +% hello \leftguillemot\ \'e\'erste \rightguillemot\ +% beautiful +% world +% \stopcommentaar +% +% \startcomment[hello][color=green,width=4cm,height=3cm] +% hello \leftguillemot\ \'e\'erste \rightguillemot\ test +% +% beautiful +% +% world +% \stopcomment +% +% \startcomment[symbol=Balloon] +% Do we want this kind of rubish? And, why isn't this and +% some more features related to text annotations so poorly +% (actually not) documented? Anyhow, by providing this +% functionality we demonstrate that \pdfTeX\ can do it. By +% the way, it's funny that when in Acrobat we scale up the +% text, the symbols scale down. +% \stopcomment + +% \definesymbol [comment-normal][{\externalfigure[cow.pdf]}] +% \definesymbol [comment-down] [{\externalfigure[cow.pdf]}] +% +% \def\CowSymbol#1#2% +% {\scale +% [\c!height=#1] +% {\startMPcode +% loadfigure "koe.mp" number 1 ; +% refill currentpicture withcolor #2 ; +% \stopMPcode}} +% +% \definesymbol [comment-normal] +% [\CowSymbol{4ex}{red}] +% +% \definesymbol [comment-down] +% [\CowSymbol{4ex}{green}] +% +% \setupcomment +% [\c!symbol={comment-normal,comment-down}, +% \c!option=\v!buffer] +% +% \setupfootertexts[\placecomments] + +\def\placecomments + {\doflushcomments} + +% \setupinteraction[state=start] +% +% \useattachment[test.tex] +% \useattachment[whatever][test.tex] +% \useattachment[whatever][newname][test.tex] +% \useattachment[whatever][title][newname][test.tex] +% +% % \setupattachments[\c!symbol={symbol-normal,symbol-down}] +% +% \starttext \attachment[whatever] \stoptext + +\definesystemvariable{at} + +\def\useattachment + {\doquadrupleempty\douseattachment} + +\def\douseattachment[#1][#2][#3][#4]% tag title newname filename + {\iffourthargument + \setgvalue{\??at:#1}{{#2}{#3}{#4}}% tooltip kind of case + \else\ifthirdargument + \setgvalue{\??at:#1}{{#2}{#2}{#3}}% full path case + \else\ifsecondargument + \setgvalue{\??at:#1}{{#2}{#2}{#2}}% obvious case + \else + \setgvalue{\??at:#1}{{#1}{#1}{#1}}% worst case + \fi\fi\fi} + +\let\attachmenttitle\empty +\let\attachmentname \empty +\let\attachmentfile \empty + +\def\getattachmentdata[#1]% + {\edef\attachmenttitle{\filterfromvalue{\??at:#1}31}% description + \edef\attachmentname {\filterfromvalue{\??at:#1}32}% new name + \edef\attachmentfile {\filterfromvalue{\??at:#1}33}% original + \expandafter\splitstring\attachmentname\at.\to\!!stringa\and\!!stringb + \ifx\!!stringb\empty % no suffix, so we need to inherit it + \expandafter\splitstring\attachmentfile\at.\to\!!stringc\and\!!stringd + \edef\attachmentname{\attachmentname.\!!stringd}% + \fi} + +\def\attachment + {\dodoubleempty\doattachment} + +\def\doattachment[#1][#2]% currently title equals newname + {\iflocation + \ifsecondargument + \doifundefined{\??at:#2} + {\showmessage\m!interactions6{#2}% + \useattachment[#2]}% + \doif\@@atstate\v!start + {\bgroup + \getattachmentdata[#2]% + \doiffileelse\attachmentfile + {\setupattachments[#1]% + \presetattachmentvariables +\struttedbox{\tbox{% + \doattachfile + \attachmenttitle + {1em}\strutheight\strutdepth\@@atcolor\@@atsymbol + \attachmentname + \attachmentfile}% +}}% + {\showmessage\m!interactions5\attachmentfile}% + \egroup}% + \else\iffirstargument + \attachment[][#1]% + \fi\fi + \fi} + +\def\presetattachmentvariables + {\let\@@DriverAttachmentLayer\@@attextlayer} + +\def\setupattachments + {\dodoubleempty\getparameters[\??at]} + +\setupattachments + [\c!state=\v!start, + \c!color=\@@iacolor, + \c!textlayer=, + \c!symbol=] + +% jammer, tussen/midden had erin gemoeten; \c!commando toevoegen + +\def\registermenucommand#1% + {{\textonly\noindent#1\space}} % no math switching + +\def\doregistermenubuttons[#1][#2]% [menu id] [register] + {\bgroup + \ifsecondargument + \setupinteractionmenu + [#1][\c!unknownreference=\v!yes,\c!samepage=\v!yes]% + \def\docommand##1% + {\registermenucommand{\menubutton[#1]{##1}[#2:##1]}}% + \else + \def\docommand##1% + {\registermenucommand + {\button + [\c!unknownreference=\v!yes,\c!samepage=\v!yes] + {##1}[#1:##1]}}% + \fi + \handletokens abcdefghijklmnopqrstuvwxyz\with\docommand % moet anders + \egroup} + +\def\registermenubuttons + {\dodoubleempty\doregistermenubuttons} + +\stelkoppelingenin + [\c!distance=.25em, + \c!width=\v!fit, + \c!location=\v!low, + \c!color=\@@iacolor, + \c!frame=\v!off, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=] + +\defineinteractionmenu + [\v!right] + [\v!right] + [\c!before=, + \c!after=\vfil, + \c!inbetween=\blank, + \c!distance=\bodyfontsize, % 12pt + \c!left=\hss, + \c!right=\hss, + \c!width=\rightedgewidth, + \c!height=\v!broad] + +\defineinteractionmenu + [\v!left] + [\v!left] + [\c!before=, + \c!after=\vfil, + \c!inbetween=\blank, + \c!distance=\bodyfontsize, % 12pt + \c!left=\hss, + \c!right=\hss, + \c!width=\leftedgewidth, + \c!height=\v!broad] + +\defineinteractionmenu + [\v!bottom] + [\v!bottom] + [\c!before=\vss, + \c!after=\vss, + \c!middle=\hfil, + \c!distance=\bodyfontsize, % 12pt + \c!width=\v!fit, + \c!height=\v!broad] + +\defineinteractionmenu + [\v!top] + [\v!top] + [\c!before=\vss, + \c!after=\vss, + \c!middle=\hfil, + \c!distance=\bodyfontsize, % 12pt + \c!width=\v!fit, + \c!height=\v!broad] + +\setupinteractionmenu + [\v!left,\v!right,\v!top,\v!bottom] + [\c!offset=.25em, + \c!position=\v!no, + \c!frame=\v!on, + \c!background=, + \c!backgroundcolor=, + \c!backgroundscreen=\@@rsscreen, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!state=\v!start, + \c!samepage=\v!yes, + \c!unknownreference=\v!empty, + \c!topoffset=\!!zeropoint, + \c!bottomoffset=\!!zeropoint, + \c!leftoffset=\!!zeropoint, + \c!rightoffset=\!!zeropoint] + +\def\placeleftedgetextblock % Is \hss/\hsize really needed here? + {\hbox to \leftedgewidth % (check outer level and settings) + {\hsize\leftedgewidth\hss\interactionmenus[\v!left]}} + +\def\placerightedgetextblock % Is \hss/\hsize really needed here? + {\hbox to \rightedgewidth % (check outer level and settings) + {\hsize\rightedgewidth\interactionmenus[\v!right]\hss}} + +\def\placetoptextblock + {\vbox to \topheight + {\vsize\topheight + \csname\??tk\v!top\c!before\endcsname + \interactionmenus[\v!top]% + \csname\??tk\v!top\c!after\endcsname + \kern\zeropoint}} + +\def\placebottomtextblock + {\vbox to \bottomheight + {\vsize\bottomheight + \csname\??tk\v!bottom\c!before\endcsname + \interactionmenus[\v!bottom]% + \csname\??tk\v!bottom\c!after\endcsname + \kern\zeropoint}} + +\ifx\leftedgetextcontent\undefined \else + + \appendtoks \placeleftedgetextblock \hskip-\leftedgewidth \to \leftedgetextcontent + \appendtoks \placerightedgetextblock \hskip-\rightedgewidth \to \rightedgetextcontent + \appendtoks \placetoptextblock \vskip-\topheight \to \toptextcontent + \appendtoks \placebottomtextblock \vskip-\bottomheight \to \bottomtextcontent + +\fi + +\setupinteractionscreen + [\c!width=\printpaperwidth, + \c!height=\printpaperheight, + \c!horoffset=\!!zeropoint, + \c!veroffset=\!!zeropoint, + \c!backspace=\backspace, + \c!topspace=\topspace, + \c!option=\v!min, + \c!delay=\v!none] + +\setupbuttons + [\c!state=\v!start, + \c!width=\v!fit, + \c!height=\v!broad, + \c!offset=0.25em, + \c!frame=\v!on, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!samepage=\v!yes, + \c!unknownreference=\v!yes] + +\setupinteractionbar + [\c!state=\v!start, + \c!alternative=a, + \c!symbol=\v!no, + \c!width=\rightedgewidth, + \c!height=, % these are taken care + \c!depth=, % of at calling time + \c!distance=.5em, % beter relateren aan breedte + \c!step=1, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!frame=\v!on, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!samepage=\v!yes, + \c!unknownreference=\v!yes] + +\setupsynchronizationbar + [\c!alternative=\v!page, + \c!width=\rightedgewidth, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=] + +\setupsynchronization + [\c!state=\v!stop] + +\setupprofiles + [\c!option=] + +\setuppagetransitions + [\v!reset] + +\setupcomment + [\c!state=\v!start, + \c!margin=2.5em, + \c!distance=1em, + \c!width=.3\textwidth, + \c!height=.2\textheight, + \c!color=\@@iacolor, + \c!title=, + \c!space=\v!no, + \c!symbol=\v!normal, + \c!location=\v!inmargin, + \c!option=, + \c!textlayer=] + +\setupversions % beware, @ is made active here, + [\c!number=1, % therefore we set this one at the end + \c!style=\ss, + \c!color=] + +\protect \endinput diff --git a/tex/context/base/scrn-int.mkiv b/tex/context/base/scrn-int.mkiv new file mode 100644 index 000000000..e47f5745e --- /dev/null +++ b/tex/context/base/scrn-int.mkiv @@ -0,0 +1,2036 @@ +%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}% + \letgvalue{\s!link:#1:f}\twopassdata + \getlasttwopassdata{\s!link:#1}% + \letgvalue{\s!link:#1:l}\twopassdata + \letgvalue{\s!link:#1:s}\noftwopassitems + \gettwopassdata{\s!link:#1}% + \letgvalue{\s!link:#1:c}\twopassdata + \letgvalue{\s!link:#1:n}\twopassdata}} + +\def\koppeling[#1]#2% + {\bgroup + \definieerkoppeling[#1]% + \doglobal\increment\numberoflinks + \gettwopassdata{\s!link:#1}% + \edef\numberoflinks{0\getvalue{\s!link:#1:s}}% + \edef\firstlink {0\getvalue{\s!link:#1:f}}% + \edef\lastlink {0\getvalue{\s!link:#1:l}}% + \edef\currentlink {0\getvalue{\s!link:#1:n}}% + \edef\prevlink {0\getvalue{\s!link:#1:c}}% + \iftwopassdatafound + \edef\nextlink{0\twopassdata}% + \letgvalue{\s!link:#1:n}\nextlink + \letgvalue{\s!link:#1:c}\currentlink + \else + \edef\nextlink{0\getvalue{\s!link:#1:l}}% + \fi + \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% + \ifnum\noflinks<\plustwo + \locationfalse + \fi + \iflocation + \hbox + {\setinteractionparameter\c!width\!!zeropoint + \dogotosomepage\??lk\gotobegincharacter\firstlink\hss + \ifnum\noflinks>\plustwo + \hskip\@@lkdistance + \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss + \fi + \hskip\@@lkdistance + #2\relax + \hskip\@@lkdistance + \ifnum\noflinks>\plustwo + \dogotosomepage\??lk\goforwardcharacter\nextlink\hss + \hskip\@@lkdistance + \fi + \dogotosomepage\??lk\gotoendcharacter\lastlink}% + \else + \hbox{#2}% + \fi + \egroup} + +\def\definieerkoppeling[#1]% % local loading ! + {\doifundefined{\s!link:#1:\s!list} + {\expanded{\definetwopasslist{\s!link:#1}}% \expanded{\doloadtwopassdata{\s!link:#1}}% + \getfirsttwopassdata{\s!link:#1}% + \let\firstlink\twopassdata + \getlasttwopassdata{\s!link:#1}% + \let\lastlink\twopassdata + \let\noflinks\noftwopassitems + \gettwopassdata{\s!link:#1}% + \let\currentlink\twopassdata + \let\nextlink\twopassdata + \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}}} + +\def\koppeling[#1]#2% + {\bgroup + \definieerkoppeling[#1]% + \doglobal\increment\numberoflinks + \gettwopassdata{\s!link:#1}% + \def\next[##1:##2:##3:##4:##5]% + {\edef\firstlink {0##1}% + \edef\lastlink {0##2}% + \edef\noflinks {0##3}% + \edef\prevlink {0##4}% + \edef\currentlink{0##5}}% + \expanded{\next[\getvalue{\s!link:#1:}]}% + \edef\nextlink{0\iftwopassdatafound\twopassdata\else\lastlink\fi}% + \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}% + \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}% + \ifnum\noflinks<\plustwo + \locationfalse + \fi + \iflocation + \hbox + {\setinteractionparameter\c!width\!!zeropoint + #2\relax + \hskip\@@lkdistance + \dogotosomepage\??lk\gotobegincharacter\firstlink\hss + \ifnum\noflinks>\plustwo + \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss + \fi + \ifnum\noflinks>\plustwo + \dogotosomepage\??lk\goforwardcharacter\nextlink\hss + \hskip\@@lkdistance + \fi + \dogotosomepage\??lk\gotoendcharacter\lastlink}% + \else + \hbox{#2}% + \fi + \egroup} + +\let\setupinteractionscreens\empty + +\def\docalculateinteractionscreen + {\doifelse\@@scwidth\v!fit + {\!!widtha\leftcombitotal + \ifdim\backspace>\!!widtha\ifdim\backspace>\zeropoint\relax + \advance\backspace -\!!widtha + \fi\fi + \advance\!!widtha\rightcombitotal + \advance\!!widtha 2\dimexpr\@@scbackspace+\@@schoroffset\relax} + {\doifelse\@@scwidth\v!max + {\!!widtha\printpaperwidth} + {\!!widtha\@@scwidth}}% + \doifelse\@@scheight\v!fit + {\!!heighta\dimexpr\topheight+\topdistance\relax + \ifdim\topspace>\!!heighta\ifdim\topspace>\zeropoint\relax + \advance\topspace -\!!heighta + \fi\fi + \advance\!!heighta \dimexpr\makeupheight+\bottomdistance+\bottomheight\relax + \advance\!!heighta 2\dimexpr\@@sctopspace+\@@scveroffset\relax} + {\doifelse\@@scheight\v!max + {\!!heighta\printpaperheight} + {\!!heighta\@@scheight}}% + \doif\@@scdelay\v!none{\let\@@scdelay\zerocountervalue}} + +% The macro is not to be changed; only the \@@ia-variables +% may be set! ConTeXt is the producer but we no longer +% mention the pragma site, since we don't want to be bothered +% with remarks about third party documents and/or associated +% with documents produced outside our control. + +\def\doprepareidentity % beware, we need to construct + {\let\!!stringa\@@iakeyword % an unexpanded space separated + \let\@@iakeyword\empty % list of keywords from a comma + \def\doprepareidentity##1% % separated one + {\ifx\@@iakeyword\empty + \appended\def\@@iakeyword{##1}% + \else + \appended\def\@@iakeyword{ ##1}% + \fi}% + \@EA\processcommalist\@EA[\!!stringa]\doprepareidentity + \global\let\doprepareidentity\relax} + +%D The Creator field is changed per 12/04/2006 due to user presure. This +%D means that I need to put my own status info someplace else. + +\def\initializeidentity + {\doprepareidentity + \dosetupidentity % no \expanded{..} will be done in special (else no pdfdoc) + {\@@iatitle}{\@@iasubtitle}{\@@iaauthor}% + {ConTeXt - \contextversion}% + {\@@iadate}{\@@iakeyword}% + \global\let\initializeidentity\relax} + +\appendtoks \initializeidentity \to \everyshipout + +\def\initializepaper + {\bgroup + \ifx\@@ppleft \empty + \ifx\@@ppright\empty + \ifx\@@pptop \empty + \ifx\@@ppbottom \empty + \ifx\@@pcstate\v!start + \locationfalse\fi\else + \locationfalse\fi\else + \locationfalse\fi\else + \locationfalse\fi\else + \locationfalse\fi + \iflocation % without screen settings + \egroup + \dosetuppaper\papersize\paperwidth\paperheight + \else + \egroup + \dosetuppaper\printpapersize\printpaperwidth\printpaperheight + \fi} + +\appendtoks \initializepaper \to \everyshipout + +\def\doinitializepaper + {\bgroup + \docalculateinteractionscreen + \ifdim\!!widtha>\paperwidth\ifdim\!!widtha>\zeropoint + \paperwidth\!!widtha + \fi\fi + \ifdim\!!heighta>\paperheight\ifdim\!!heighta>\zeropoint + \paperheight\!!heighta + \fi\fi + \dosetuppaper + {\printpapersize} + {\the\paperwidth} + {\the\paperheight}% + \egroup} + +\let\@@pcscreendata\empty + +\def\dosetupinteractionscreens % met a, b en \number + {\doifnot\@@pcstate\v!start\dodosetupinteractionscreens} + +\setvalue{\??sc\c!option\v!max }{1} % tzt share with driver +\setvalue{\??sc\c!option\v!bookmark }{2} % tzt share with driver +\setvalue{\??sc\c!option\v!fit }{3} % tzt share with driver +\setvalue{\??sc\c!option\v!doublesided}{4} % tzt share with driver + +\def\dodosetupinteractionscreens % met a, b en \number + {\bgroup + \docalculateinteractionscreen + \!!counte=0\getvalue{\??sc\c!option\@@scoption}\relax + % niet waterdicht + \doifnot{\the\!!widtha\the\!!heighta}\@@pcscreendata + {\xdef\@@pcscreendata{\the\!!widtha\the\!!heighta}% + \showmessage\m!interactions1{\withoutpt\the\!!widtha,\withoutpt\the\!!heighta}}% + % needs to be split: dimensions for each page + % and mode per document and only once ! + \dosetupscreen \backoffset\topoffset\!!widtha\!!heighta{\the\!!counte}% + \dosetupcropbox\backoffset\topoffset\!!widtha\!!heighta + \egroup} + +\def\dosetupinteractionscreen[#1]% + {\getparameters[\??sc][#1]% + \ifproductionrun + \let\initializepaper\doinitializepaper + \let\setupinteractionscreens\dosetupinteractionscreens + \fi} + +\appendtoks \setupinteractionscreens \to \everyfirstshipout % needed to get option=max etc working +\appendtoks \setupinteractionscreens \to \everyshipout % needed for page/screen dimensions + +\def\setupinteractionscreen + {\dosingleempty\dosetupinteractionscreen} + +% \startinteractionmenu[rechts] +% \but [eerste] eerste \\ +% \txt hello world \\ +% \but [tweede] tweede \\ +% \nop \\ +% \but [tweede] tweede \\ +% \rul whow \\ +% \but [tweede] tweede \\ +% \raw hello world \\ +% \but [tweede] tweede \\ +% \com \vfill \\ +% \but [derde] derde \\ +% \stopinteractionmenu + +\newif\iflocationmenupermitted + +\def\testinteractionmenu#1% + {\iflocation + \doifelse\@@iamenu\v!on + {\doifelsevalue{\??am#1\c!state}\v!start + {\global\locationmenupermittedtrue} + {\global\locationmenupermittedfalse}} + {\global\locationmenupermittedfalse}% + \else + \global\locationmenupermittedfalse + \fi} + +\def\dodisableinteractionmenu[#1][#2][#3]% + {\def\dododisableinteractionmenu##1% + {\doifelse{#3}{} + {\letvalue{\??am##1\c!obstruction}\empty} + {\edef\interactieblokkade{\getvalue{\??am##1\c!obstruction}} + \def\docommand####1{#1{####1}{\interactieblokkade}}% #1 = \remove or \add + \processcommalist[#3]\docommand + \setevalue{\??am##1\c!obstruction}{\interactieblokkade}}}% + \processcommalist[#2]\dododisableinteractionmenu} + +\def\disableinteractionmenu + {\dotripleempty\dodisableinteractionmenu[\addtocommalist]} + +\def\enableinteractionmenu + {\dotripleempty\dodisableinteractionmenu[\removefromcommalist]} + +% ja : kader/achtergrond met tekst +% leeg : kader/achtergrond maar geen tekst +% nee : alleen ruimte reserveren +% geen : helemaal weglaten + +\newif\iflocationdummy +\newif\ifskippedmenuitem + +\newif\iflocationempty +\newif\iflocationclick + +% ja : kader/achtergrond met tekst +% leeg : kader/achtergrond maar geen tekst +% nee : alleen ruimte reserveren +% geen : helemaal weglaten +% +% \setupinteractionmenu[right][samepage=yes, unknownreference=yes] +% \setupinteractionmenu[right][samepage=empty,unknownreference=empty] +% \setupinteractionmenu[right][samepage=no, unknownreference=no] +% \setupinteractionmenu[right][samepage=none, unknownreference=none] +% +% \startinteractionmenu[right] +% \but [firstpage] first \\ +% \but [lastpage] last \\ +% \but [somepage] crap \\ +% \stopinteractionmenu + +\def\dosetlocationboxcontent#1[#2]#3[#4]% + {\global\skippedmenuitemfalse + \setbox\locationbox\hbox + {\resetgoto % anders cyclische aanroep ! + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}}% + \iflocationclick + \hbox{\gotolocation{#4}{\box\locationbox}}% + \else + \hbox{\box\locationbox}% + \fi} + +\let\dosetlocationboxyes\dosetlocationboxcontent + +\def\dosetlocationboxempty#1[% + {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,} + +\def\dosetlocationboxno#1[% + {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,\c!frame=,\c!background=,} + +\def\dosetlocationboxnone#1[#2]#3[#4]% + {\global\skippedmenuitemtrue} + +\def\setlocationboxyes#1[#2]#3[#4]% + {\locationclicktrue + \setbox\locationbox\hbox + {\resetgoto % anders cyclische aanroep ! + \global\skippedmenuitemfalse + \gotolocation + {#4}% % needed + {\ifrealreferencepage + \ifcase\csname\??am\??am\csname#1\c!samepage\endcsname\endcsname\relax + \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \global\skippedmenuitemtrue + \fi + \else + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \fi}}% + \ifskippedmenuitem\else\box\locationbox\fi} + +\def\setlocationboxnop#1[#2]#3[#4]% + {\locationclickfalse + \setbox\locationbox\hbox + {\resetgoto % anders cyclische aanroep ! + \global\skippedmenuitemfalse + \ifcase\csname\??am\??am\csname#1\c!unknownreference\endcsname\endcsname\relax + \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}% + \or + \global\skippedmenuitemtrue + \fi}% + \ifskippedmenuitem\else\box\locationbox\fi} + +\def\setlocationboxraw#1[#2]#3[#4]% + {\localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}} + +\def\setlocationbox#1[#2]#3[#4]% + {\bgroup % really needed ! + \edef\permittedreferences{\csname#1\c!obstruction\endcsname}% + \doifreferencepermittedelse{#4}% + {\setlocationboxyes{#1}[#2]{#3}[#4]}% + {\setlocationboxnop{#1}[#2]{#3}[#4]}% + \egroup} + +\def\setlocationnop#1[#2]#3% + {\localframed[#1][#2]{#3}} + +\def\executeamboxcommands#1#2#3#4#5% + {%\processaction + % [\getvalue{\??am#1\c!dummy}] + % [ \v!yes=>\chardef\handleunknownmenuitem=0\relax, + % \v!empty=>\chardef\handleunknownmenuitem=1\relax, + % \v!no=>\chardef\handleunknownmenuitem=2\relax]% + \getvalue{\??am#1#3}\relax + \setamboxcommands{#1}{#4}% + \ignorespaces#2\unskip + \getvalue{\??am#1#5}} + +\newcounter\currentamposition + +\newtoks\everysetmenucommands + +\def\setamboxcommands#1#2% + {\def\currentmenu{#1}% % kan nog eerder + \def\currentsubmenu{#2}% % ? ? + \doglobal\newcounter\currentamposition + \the\everysetmenucommands} + +\def\menu@@amboxcommand#1\\% + {\dontleavehmode + \bgroup + \ignorespaces#1\unskip\relax + \ifskippedmenuitem \else + \getvalue{\??am\currentmenu\currentsubmenu}% + \fi + \egroup + \ignorespaces} + +\appendtoks + \let\@@amboxcommand\menu@@amboxcommand +\to \everysetmenucommands + +\def\menu@raw[#1]#2\\% + {\@@amboxcommand\gotobox{\ignorespaces#2\unskip}[#1]\\}% + +\def\menu@but[#1]#2\\% + {\@@amboxcommand\do@@amposition\currentmenu{#1}{\setlocationbox{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}\\}% + +\def\menu@got[#1]#2\\% pas op! offset + {\@@amboxcommand\setlocationbox{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]\\}% + +\def\menu@nop#1\\% + {\@@amboxcommand\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]\\}% + +\def\menu@txt#1\\% + {\@@amboxcommand\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}\\}% + +\def\menu@rul#1\\% ook \do@@amposition ! + {\@@amboxcommand\localframed[\??am\currentmenu][]{\ignorespaces#1\unskip}\\}% + +\def\menu@com#1\\% + {\ignorespaces#1\unskip\ignorespaces}% + +\appendtoks + \let\raw\menu@raw + \let\but\menu@but + \let\got\menu@got + \let\nop\menu@nop + \let\txt\menu@txt + \let\rul\menu@rul + \let\com\menu@com +\to \everysetmenucommands + +\ifx\do@@amposition\undefined + \let\do@@amposition\gobbletwoarguments % hook for positional thingies +\fi + +\let\currentmenu\empty + +% beware : never change the concept of pbgoffset + +\def\menuparameter#1{\csname\??am\currentmenu#1\endcsname} + +\def\@@amhbox#1#2#3#4% + {\def\currentmenu{#3}% + \testinteractionmenu{#3}% + \iflocationmenupermitted + \bgroup + \showcomposition + \scratchdimen\dimexpr + \makeupwidth + +\pagebackgroundhoffset + +\pagebackgroundhoffset + -\menuparameter\c!leftoffset + -\menuparameter\c!rightoffset + \relax + \setbox\scratchbox\hbox to \scratchdimen + {\forgetall\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}% + \setbox\scratchbox\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}% + \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet) + \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax + \box\scratchbox + \egroup + \else + #1\relax + \fi} + +\def\@@amvbox#1#2#3#4% don't change skipping, this one works! + {\def\currentmenu{#3}% + \testinteractionmenu{#3}% + \iflocationmenupermitted + \bgroup + \showcomposition + \scratchdimen\dimexpr + \textheight + +\pagebackgroundvoffset + +\pagebackgroundvoffset + +\pagebackgrounddepth + -\menuparameter\c!topoffset + -\menuparameter\c!bottomoffset + \relax + \setbox\scratchbox\vbox to \scratchdimen + {\forgetall % Voor't geval de afstand + %\setupblank[\v!standard]% % (tijdelijk) is aangepast. + \restorestandardblank + \hsize#2\relax + \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}% + \setbox\scratchbox\vbox{\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}}% + \setbox\scratchbox\vbox + {\ht\scratchbox\zeropoint + \vskip\dimexpr-\pagebackgroundvoffset+\menuparameter\c!topoffset\relax + \box\scratchbox + \vskip\pagebackgroundvoffset}% overbodig + \ht\scratchbox\textheight + \wd\scratchbox#2\relax + \box\scratchbox + \egroup + \else + #1\relax + \fi} + +\ifx\do@@ammenuposition\undefined + \let\do@@ammenuposition\gobbleoneargument % hook for positional thingies +\fi + +\setvalue{\??am\s!do\v!right }{\@@amvbox{\dodummypageskip\v!right }\rightedgewidth} +\setvalue{\??am\s!do\v!left }{\@@amvbox{\dodummypageskip\v!left }\leftedgewidth } +\setvalue{\??am\s!do\v!top }{\@@amhbox{\dodummypageskip\v!top }\topheight } +\setvalue{\??am\s!do\v!bottom}{\@@amhbox{\dodummypageskip\v!bottom}\bottomheight } + +\def\dointeractionmenu#1#2% + {\getvalue{\??am\s!do\getvalue{\??am#1\c!location}}{#1}{#2}} + +\unexpanded\def\interactionmenu[#1]% + {\getvalue{\??am\c!menu#1}} + +\def\horizontalinteractionmenu#1#2#3#4% + {\ifdim#2>\zeropoint % new + \scratchdimen\zeropoint + \setbox\scratchbox\hbox + {\def\docommand##1% + {\doifnotvalue{\??am##1\c!state}\v!none + {\hskip\scratchdimen + \setbox2\hbox to #2 + {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% + \doifelsevalue{\??am##1\c!distance}\v!overlay + {\scratchdimen\zeropoint + \wd2\zeropoint}% + {\scratchdimen\getvalue{\??am##1\c!distance}}% + \box2}}% + \startinteraction + \processcommacommand[\getvalue{\??am#1}]\docommand + \stopinteraction}% + \wd\scratchbox#2\relax + \box\scratchbox + \fi} + +\def\verticalinteractionmenu#1#2#3#4% + {\ifdim#2>\zeropoint % new + \scratchdimen\zeropoint + \setbox\scratchbox\vbox + {\def\docommand##1% + {\doifnotvalue{\??am##1\c!state}\v!none + {\vskip\scratchdimen + \setbox2\vbox to #2 + {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}% + \doifelsevalue{\??am##1\c!distance}\v!overlay + {\scratchdimen\zeropoint + \offinterlineskip + \dp2\zeropoint + \ht2\zeropoint}% + {\scratchdimen\getvalue{\??am##1\c!distance}}% + \box2}}% + \startinteraction + \processcommacommand[\getvalue{\??am#1}]\docommand + \stopinteraction}% + \ht\scratchbox#2\relax + \dp\scratchbox\zeropoint + \box\scratchbox + \fi} + +\letvalue{\??am\v!left }\empty +\letvalue{\??am\v!right}\empty +\letvalue{\??am\v!top }\empty +\letvalue{\??am\v!bottom }\empty + +% todo : \defineinteractionmenuclass + +\def\interactionmenus[#1]% + {\iflocation + \getvalue{\??am\??am\c!menu#1}% + \else + \dodummypageskip{#1}% + \fi} + +\setvalue{\??am\??am\c!menu\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth \c!left \c!right} +\setvalue{\??am\??am\c!menu\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth\c!left \c!right} +\setvalue{\??am\??am\c!menu\v!top }{\verticalinteractionmenu \v!top \topheight \c!before\c!after} +\setvalue{\??am\??am\c!menu\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight \c!before\c!after} + +% this can be implemented with the following command (which +% is new, undocumented, experimental, untested, etc etc) + +\def\defineinteractionmenuclass + {\dodoubleargument\dodefineinteractionmenuclass} + +\def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri + {\doifelse{#2}\v!vertical + {\setvalue{\??am\??am\c!menu#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}\c!before\c!after}} + {\setvalue{\??am\??am\c!menu#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}\c!left\c!right }}} + +% \setupinteraction[menu=on,state=start] +% +% \defineinteractionmenuclass[test] [vertical] +% \defineinteractionmenuclass[another][horizontal] +% +% \defineinteractionmenu[test] [left][state=start,width=4cm] +% \defineinteractionmenu[another][top] [state=start,height=1cm] +% +% \startinteractionmenu[test] +% \but [firstpage] test-a \\ +% \but [nextpage] test-b \\ +% \stopinteractionmenu +% +% \startinteractionmenu[another] +% \but [firstpage] test-a \\ +% \but [nextpage] test-b \\ +% \stopinteractionmenu +% +% \setupheadertexts[{\interactionmenu[another]}] +% +% \starttext +% +% test \interactionmenu[test] \page +% test \interactionmenu[test] \page +% +% \stoptext + +%D This can save complicated menu macros when one want to +%D keep control over parts of a menu (i.e.\ turn them on and +%D off). We could have achieved something similar with modes. + +\def\local@@ambox#1#2#3#4% don't change skipping, this one works! + {\bgroup + \testinteractionmenu{#3}% + \iflocationmenupermitted + \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after + \else + #1\relax + \fi + \egroup} + +\def\includemenu[#1]% + {\doifvalue{\??am#1\c!state}\v!local + {\bgroup + \letvalue{\??am#1\c!state}\v!start + \let\@@amvbox\local@@ambox + \let\@@amhbox\local@@ambox + \getvalue{\??am\c!menu#1}% + \egroup}} + +%D We also need an explicit position control some day. I'll +%D do that when I need it. [The stacking order.] + +\newif\ifextendedmenu + +% [name] [location] +% [name] [location] [pars] + +\def\defineinteractionmenu + {\dotripleempty\dodefineinteractionmenu} + +\def\dodefineinteractionmenu[#1][#2][#3]% + {% main settings + \letvalue{\??am\c!menu#1}\empty + \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}% + \presetlocalframed[\??am#1]% + % register location + \expanded{\addtocommalist{#1}\@EA\noexpand\csname\??am#2\endcsname}% + % inherit settings + \doifnot{#1}{#2} + {\copyparameters[\??am#1][\??am#2] + [\c!left,\c!middle,\c!right,\c!before,\c!after,\c!inbetween,% + \c!width,\c!height,\c!distance,\c!offset,% + \c!frame,\c!framecolor,\c!rulethickness,% + \c!background,\c!backgroundcolor,\c!backgroundscreen,% + \c!style,\c!color,\c!contrastcolor,\c!samepage,\c!unknownreference,% + \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]}% + % additional settings + \getparameters[\??am#1][\c!location=#2,\c!obstruction=,#3]} + +\def\setupinteractionmenu + {\dodoubleargument\dosetupinteractionmenu} + +\def\dosetupinteractionmenu[#1][#2]% + {\def\docommand##1{\getparameters[\??am##1][#2]}% + \processcommalist[#1]\docommand} + +\expandafter\chardef\csname\??am\??am\v!yes \endcsname\zerocount +\expandafter\chardef\csname\??am\??am\v!empty\endcsname\plusone +\expandafter\chardef\csname\??am\??am\v!no \endcsname\plustwo +\expandafter\chardef\csname\??am\??am\v!none \endcsname\plusthree +\expandafter\chardef\csname\??am\??am \endcsname\plusone % default + +\processbetween{\v!interactionmenu}\dostartinteractionmenu + +\def\dostartinteractionmenu#1% + {\dodostartinteractionmenu#1\dodostopinteractionmenu} + +\def\dodostartinteractionmenu[#1]#2\dodostopinteractionmenu + {\setvalue{\??am\c!menu#1}{\extendedmenutrue\dointeractionmenu{#1}{#2}}} + +\def\resetinteractionmenu[#1]% + {\letvalue{\??am\c!menu#1}\empty} + +\def\dodomenulistelement#1#2#3#4#5#6#7% + {\setbox0=\hbox + {\let\gotolocation\gobbleoneargument % hack to catch last [] + %\locationclickfalse % ipv ^ + \docheckrealreferencepage{#7}% + \setlocationboxyes + {\??am#1}% % needed ! + []% no settings + {\limitatetext{#5}{\getvalue{\??li#2\c!maxwidth}}{\unknown}}% % needed ! + []}% normally the destination, catch by gobble + \@@amboxcommand\do@@amposition{#1}{#7}% beware, we pass the pagenumber + {\ignorespaces\linklisttoelement{#3}{#6}{#7}{\box0}\unskip}\\} + +% \scherm moet worden als \page + +\def\screen + {\dosingleempty\doscreen} + +\def\doscreen[#1]% + {\iflocation\page[#1]\fi} + +\unexpanded\def\menubutton + {\dodoubleempty\domenubutton} + +\def\domenubutton[#1]% + {\iffirstargument + \ifsecondargument + \@EAEAEA\domenubuttonB + \else + \doifassignmentelse{#1} + {\@EAEAEA\domenubuttonC} + {\@EAEAEA\domenubuttonD}% + \fi + \else + \@EA\domenubuttonA + \fi[#1]} + +\def\domenubuttonA[#1][#2]#3[#4]% normal button, no parameters + {\bgroup + %\locationdummytrue + \setlocationbox\??bt[]{#3}[#4]% + \egroup} + +\def\domenubuttonB[#1][#2]#3[#4]% menu button, with parameters + {\bgroup + %\locationdummytrue + \setlocationbox{\??am#1}[#2]{#3}[#4]% + \egroup} + +\def\domenubuttonC[#1][#2]#3[#4]% normal button, with parameters + {\bgroup + %\locationdummytrue + \setlocationbox\??bt[#1]{#3}[#4]% + \egroup} + +\def\domenubuttonD[#1][#2]#3[#4]% menu button, no parameters + {\bgroup + %\locationdummytrue + \setlocationbox{\??am#1}[]{#3}[#4]% + \egroup} + +\def\menubox + {\dodoubleempty\domenubox} + +\def\domenubox[#1][#2]#3% + {\bgroup + \let\setlocationbox\setlocationboxraw + \domenubutton[#1][#2]#3[]% + \egroup} + +% Hier volgen de synchronisatiemacro's: + +\def\syncprefix{sync} + +%def\syncmarker{syncmark} +%\definemarking[\syncmarker] +%\setupmarking[\syncmarker][\c!expansie=\v!ja] + +\newmark\syncmarker + +\newcounter\synccounter + +\newif\ifsynchronisation + +\def\startsynchronization% + {\iflocation\ifsynchronisation + \doglobal\increment\synccounter + \fi\fi} + +\def\stopsynchronization% + {\iflocation\ifsynchronisation + %\thisisdestination{\syncprefix:\synccounter}% + \pagereference[\syncprefix:\synccounter]% + \ifvmode + \@EA\setmark\@EA\syncmarker\@EA{\synccounter} % \marking[\syncmarker]{\synccounter}% + \else + \showmessage\m!interactions4\synccounter + \fi + \fi\fi} + +\def\synchronize% + {\startsynchronization + \stopsynchronization} + +\def\dosetupsynchronization[#1]% + {\getparameters[\??sy][#1]% + \doifelse\@@systate\v!start + \synchronisationtrue + \synchronisationfalse} + +\def\setupsynchronization + {\dosingleargument\dosetupsynchronization} + +\def\definesynchronization + {\dosingleargument\dodefinesynchronization} + +\def\setupsynchronizationbar + {\dodoubleargument\getparameters[\??ba]} + +\presetlocalframed[\??ba] + +\setvalue{synchronisatie\v!page}[#1]% + {\bgroup + %\setupinteraction[\c!width=\!!zeropoint]% + \setinteractionparameter\c!width\!!zeropoint + \setbox0\hbox + {\localframed[\??ba][]{\dolocationattributes\??ba\c!style\c!color{\strut\@@batext}}}% + \dontcomplain + \def\atthebottom + {\leaders\hrule\!!depth1ex\!!height-.5ex\hfil}% + \def\atthetop##1##2##3% + {\dimen0=\wd0 + \divide\dimen0 3 + \multiply\dimen0 ##2\relax + \dimen2=.25em % brrr + \advance\dimen0 -##3\dimen2 + %\gotodestination + % {}{#1}{\syncprefix:##1}{} + % {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}}% + \gotobox + {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}% + [#1::\syncprefix:##1]}% + \hbox + {\def\check##1##2% + {\edef##2{0##1\syncmarker}% + \ifnum0##2=0 \def##2{1}\fi}% + \check\gettopmark\top + \check\getfirstmark\first + \check\getbotmark\bot + \setbox2\hbox to \wd0 + {\ifnum\top=\first\relax + \ifnum\first=\bot\relax + \atthetop\first30\relax + \else + \atthetop\first21\hss\atthetop\bot11\relax + \fi + \else + \ifnum\first=\bot\relax + \atthetop\top11\hss\atthetop\first21\relax + \else + \atthetop\top11\hss\atthetop\first11\hss\atthetop\bot11\relax + \fi + \fi}% + \wd2=\zeropoint\box2 + \box0\relax}% + \egroup} + +\setvalue{synchronisatie\v!local}[#1]% + {\bgroup + %\setupinteraction[\c!width=\!!zeropoint]% + \setinteractionparameter\c!width\!!zeropoint + \def\blackrule{\hbox{\vrule\!!height.5em\!!width.5em}}% + %\gotodestination + % {}{##1}{\syncprefix:#1}{0} + % {\color[\locationcolor\@@bacolor]{\blackrule}}% + \gotobox % + {\color[\locationcolor\@@bacolor]{\blackrule}}% + [#1::\syncprefix:\synccounter]% + \egroup} + +\def\synchronizationbar[#1][#2]% + {\iflocation\ifsynchronisation + \bgroup + \setupsynchronizationbar + [\c!text=\getvalue{doc:des:#1},#2]% + \getvalue{synchronisatie\@@baalternative}[#1]% + \egroup + \fi\fi} + +% A nice application of glue. All this code will be rewritten and +% generalized. + +\newbox\interactionbarbox + +\newif\ifbarsymbol + +\def\dogotosomepage#1#2#3% nog checken ! + {\hbox + {\iflocation + \ifnum#3=\realpageno + #2% + \else + \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% + \fi + \else + #2% + \fi}} + +\def\dogotosomecontrastpage#1#2#3% nog checken, may replace previous + {\checkreferences % nodig ?? + \hbox + {\iflocation + \ifnum#3=\realpageno + \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!contrastcolor}{#2}}% + \else + \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}% + \fi + \else + #2% + \fi}} + +\presetlocalframed[\??ib] + +\def\interactionbara % we need better control over contrastcolor + {\iflocation % maybe just use gotopage and set colors + \bgroup + \setinteractionparameter\c!width\zeropoint + \setupblackrules[\c!height=\v!max,\c!depth=\v!max]% + \!!widthb\dimexpr\@@ibwidth-2.75\emwidth\relax + \!!widtha\dimexpr\!!widthb/\lastpage\relax + \bgroup + \advance\realpageno\minusone + \ifvoid\interactionbarbox + \bgroup + \processaction + [\@@ibstep] + [ \v!small=>\scratchdimen.25\emwidth, + \v!medium=>\scratchdimen.5\emwidth, + \v!big=>\scratchdimen\emwidth, + \s!unknown=>\scratchdimen\!!widtha]% + \ifdim\!!widtha<\scratchdimen\relax + \!!counta\numexpr\scratchdimen/\!!widtha\relax + \else + \!!counta\@@ibstep\relax + \fi + \!!widtha\!!counta\!!widtha + \setbox\scratchbox\hbox{\blackrule[\c!width=\!!widtha,\c!color=middlegray]}% color here, else no mkiv + \global\setbox\interactionbarbox\hbox to \!!widthb + {\hss + \dostepwiserecurse\plusone\lastpage\!!counta + {\gotorealpage\empty\empty\recurselevel{\copy\scratchbox}}% + \hss}% + \global\wd\interactionbarbox\zeropoint + \egroup + \fi + \egroup + \noindent + \strut + \hbox to \@@ibwidth + {\dontcomplain + \setupblackrules[\c!width=\emwidth]% + \dogotosomecontrastpage\??ib\blackrule\firstpage + \hss + \copy\interactionbarbox + \hbox to \!!widthb + {\ifdim\!!widtha<\emwidth + \!!widtha\emwidth + \fi + \setupblackrules[\c!width=\!!widtha]% + \ifnum\realpageno>\plusone + \!!counta\numexpr\realpageno-\plustwo\relax + \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow + \dogotosomepage\??ib\blackrule\prevpage + \fi + \dogotosomecontrastpage\??ib{\blackrule[\c!width=.5em]}\realpageno + \ifnum\realpageno<\lastpage\relax + \dogotosomepage\??ib\blackrule\nextpage + \!!counta\numexpr\lastpage-\realpageno-\plusone\relax + \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow + \fi}% + \hss + \dogotosomecontrastpage\??ib\blackrule\lastpage}% + \egroup + \fi} + +\def\interactionbarb + {\ifnum\lastpage>\firstpage\relax + \interactionbuttons[\v!firstpage,\v!previouspage,\v!nextpage,\v!lastpage]% + \fi} + +\def\interactionbarc + {\iflocation + \ifnum\lastpage>\plusone + \hbox to \@@ibwidth + {\setupblackrules[\c!height=\@@ibheight,\c!depth=\@@ibdepth]% + \scratchdimen\dimexpr(\@@ibwidth-4\emwidth)/\numexpr\lastpage+\minusone\relax\relax + \!!widtha\numexpr\realpageno+\minusone\relax\scratchdimen + \!!widthb\numexpr\lastpage-\realpageno\relax\scratchdimen + \startcolor[\locationcolor\@@ibcolor]% + \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\firstpage + \hss + \dogotosomepage\empty{\blackrule[\c!width=\!!widtha]}\prevpage + \color[\@@ibcontrastcolor]{\blackrule[\c!width=\emwidth]}% + \dogotosomepage\empty{\blackrule[\c!width=\!!widthb]}\nextpage + \hss + \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\lastpage + \stopcolor}% + \fi + \fi} + +\def\interactionbard + {\iflocation\ifshowingsubpage + \ifnum\nofsubpages>\plusone + \hbox \bgroup + \setinteractionparameter\c!width\!!zeropoint + \ifbarsymbol + \setupsymbolset[\@@iasymbolset]% + \def\dogotox##1% + {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi]}}% + \else + \def\dogotox##1% + {\hbox{\vrule\!!height\@@ibheight\!!depth \@@ibdepth\!!width \@@ibwidth}}% + \fi + \dostepwiserecurse\plusone\nofsubpages\plusone + {\bgroup + \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax + \ifnum\scratchcounter<\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter + \else\ifnum\scratchcounter=\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter + \else + \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter + \fi\fi + \egroup + \hskip\@@ibdistance}% + \unskip % not needed + \egroup + \fi + \fi\fi} + +\def\interactionbare% KAN WORDEN GECOMBINEERD MET D + {\iflocation\ifshowingsubpage + \ifnum\nofsubpages>\plusone + \bgroup + \!!widthb\dimexpr\nofsubpages\dimexpr\@@ibdistance\relax-\@@ibdistance\relax % (n-1) + \!!widtha\dimexpr(\@@ibwidth-\!!widthb)/\nofsubpages\relax + \ifdim\!!widtha<\@@ibdistance\relax + \interactionbarf + \else + \setinteractionparameter\c!width\!!zeropoint + \noindent + \hbox to \@@ibwidth + \bgroup + \ifbarsymbol + \setupsymbolset[\@@iasymbolset]% + \def\dogotox##1% + {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi}}% + \else + \def\dogotox##1% + {\hbox{\vrule\!!height\@@ibheight\!!depth\@@ibdepth\!!width\!!widtha}}% + \fi + \dostepwiserecurse\plusone\nofsubpages\plusone + {\bgroup + \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax + \ifnum\scratchcounter<\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter + \else\ifnum\scratchcounter=\realpageno\relax + \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter + \else + \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter + \fi\fi + \egroup + \hss}% + \unskip + \egroup + \fi + \egroup + \fi + \fi\fi} + +\def\interactionbarf % !! KAN WORDEN GECOMBINEERD MET D !! + {\iflocation\ifshowingsubpage + \ifnum\nofsubpages>\plusone + \setinteractionparameter\c!width\!!zeropoint + \noindent + \hbox to \@@ibwidth + \bgroup + \!!countb\zerocount + \loop % todo: \doloop + \advance\!!countb \plusone + %\!!countc\nofsubpages \divide\!!countc \!!countb \advance\!!countc \plusone + \!!countc\numexpr(\nofsubpages/\!!countb)+\plusone\relax % rounding + \!!widthb\@@ibdistance + \multiply\!!widthb \!!countc + \advance\!!widthb -\@@ibdistance + \!!widtha\@@ibwidth + \advance\!!widtha -\!!widthb + \divide\!!widtha \!!countc + \ifdim\!!widtha<\@@ibdistance\relax + \repeat + \ifnum\!!countc>\plusone + % this is not that well tested + \advance\!!countc \minustwo + \!!widtha-\@@ibdistance + \!!widtha\!!countc\!!widtha + \advance\!!widtha \@@ibwidth + \advance\!!countc \plusone + \divide\!!widtha \!!countc + \fi + \ifbarsymbol + \setupsymbolset[\@@iasymbolset]% + \def\dogotox##1% + {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!somewhere\or\v!somewhere\or\v!next\fi}}% + \else + \def\dogotox##1% + {\hbox + {\!!heighta\@@ibheight + \!!deptha\@@ibdepth + \ifcase##1\relax + \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha + \or + \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha + \or + \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha + \or + \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha + \or + \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha + \fi}}% + \fi + \!!countc\numexpr\realpageno-\plustwo\relax + \!!countd\numexpr\realpageno+\plustwo\relax + \ifnum\!!countc<\plusone \!!countc\plusone \fi + \!!countf\zerocount + \dostepwiserecurse\firstsubpage\lastsubpage\plusone + {\!!doneafalse + \advance\!!countf \plusone + \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi + \ifnum\recurselevel=\lastsubpage\relax \!!doneatrue \fi + \if!!donea + \ifnum\recurselevel<\realpageno + \dogotosomecontrastpage\??ib{\dogotox0}\recurselevel + \else\ifnum\recurselevel>\realpageno + \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel + \else + \dogotosomecontrastpage\??ib{\dogotox4}\recurselevel + \fi\fi + \hss + \!!countf\zerocount + \else\ifnum\!!countf=\!!countb + \ifnum\recurselevel<\realpageno + \dogotosomecontrastpage\??ib{\dogotox1}\recurselevel + \else\ifnum\recurselevel>\realpageno + \dogotosomecontrastpage\??ib{\dogotox3}\recurselevel + \else + \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel + \fi\fi + \hss + \!!countf\zerocount + \fi\fi}% + \unskip + \egroup + \fi + \fi\fi} + +\def\interactionbarg + {\ifnum\lastsubpage>\firstsubpage\relax + \interactionbuttons[\v!firstsubpage,\v!previoussubpage,\v!nextsubpage,\v!lastsubpage]% + \fi} + +\def\checkinteractionbar#1#2#3% + {\ifdim\@@ibwidth=\zeropoint\def\@@ibwidth{#1}\fi + \doifnothing\@@ibheight{\def\@@ibheight{#2}}% + \doifnothing\@@ibdepth{\def\@@ibdepth{#3}}} + +\def\complexinteractionbar[#1]% + {\doifelse{#1}\v!reset + {\global\setbox\interactionbarbox\emptybox}% + {\bgroup + \iflocation + \checksubpages % goes wrong / loads \numberofpages too + \getparameters[\??ib][#1]% + \doif\@@ibstate\v!start + {\startinteraction + \processaction % breedte defaults ! + [\@@ibalternative] + [ c=>\checkinteractionbar{10em}\v!max \v!max, + d=>\checkinteractionbar{.5em}{.5em} \!!zeropoint, + e=>\checkinteractionbar{10em}{.5em} \!!zeropoint, + f=>\checkinteractionbar{10em}{.5em} \!!zeropoint, + \s!default=>\checkinteractionbar{10em}\v!broad\!!zeropoint, + \s!unknown=>\checkinteractionbar{10em}\v!broad\!!zeropoint]% + \doifelse\@@ibsymbol\v!yes + \barsymboltrue\barsymbolfalse + \getvalue{interactionbar\@@ibalternative}% + \stopinteraction}% + \fi + \egroup}} + +\definecomplexorsimpleempty\interactionbar + +\def\setupinteractionbar + {\dodoubleargument\getparameters[\??ib]} + +% Er wordt vooralsnog uitgegaan van een symmetrische +% start-stop situatie. + +\def\c!profiel!! {profiel:} % brrr +\def\c!versie!! {versie:} + +\def\dodefineprofile[#1][#2]% + {\iflocation + \def\dododefineprofile##1% + {\def\dodododefineprofile####1% + {\doifdefinedelse{\c!profiel!!####1}% + {\edef\!!stringa{\getvalue{\c!profiel!!####1}}% + \setevalue{\c!profiel!!####1}{\!!stringa,##1}}% + {\setevalue{\c!profiel!!####1}{##1}}}% + \processcommalist[#2]\dodododefineprofile}% + \processcommalist[#1]\dododefineprofile + \fi} + +\def\defineprofile% + {\dodoubleargument\dodefineprofile} + +% Als met \getpar wordt gewerkt, dan moet \next worden toegepast. + +% TZT initialisatie! + +\def\profilepage{} + +\let\dosetprofilepage\relax +\let\dogetprofilepage\relax + +\def\processprofile#1[#2]% + {\iflocation + \par % needed for pdftex + \bgroup + \dosetprofilepage + \dogetprofilepage + \def\processoneprofile##1##2% + {\ExpandBothAfter\doifinsetelse{##2}{\processedprofiles}% + {\doifsomething{##1}{(##1)}}% + {\addtocommalist{##2}\processedprofiles + ##1\relax + \ifcase#1\relax + \dobeginofprofile{##2}\paperwidth\paperheight\profilepage + \else + \doendofprofile + \fi}}% + \let\processedprofiles\empty + \def\doprocessprofile##1% + {\doifelse{\@@pfoption}{\v!test}% + {\goodbreak\blank\nobreak\tt[\space + \ifcase#1\v!start\else\v!stop\fi profiel\space ##1:\space + \doifdefinedelse{\c!profiel!!##1}% + {\def\dodoprocessprofile####1% + {\processoneprofile + {\goto{####1}[\c!profiel!!####1]}% + {####1}% + \space}% + \processcommacommand + [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}% + {- }% + ]\nobreak\blank}% + {\doifdefined{\c!profiel!!##1}% + {\def\dodoprocessprofile####1% + {\processoneprofile{}{####1}}% + \processcommacommand + [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}}}% + \processcommalist[#2]\doprocessprofile + \egroup + \par % needed for pdftex + \fi} + +\def\startprofile[#1]% + {\iflocation + \bgroup + \addtocommalist{#1}\actualprofile + \def\stopprofile% + {\processprofile1[#1]% + \egroup}% + \def\next{\processprofile0[#1]}% % \DoAfterFi \processprofile0[#1]% + \else % ^^^^^^^^^^ will be obsolete + \let\next\relax % since ugly and never used + \fi + \next} + +\let\stopprofile\relax + +\def\dofollowprofile#1[#2]% + {\iflocation + \hbox + {\dohandlegoto + {\dolocationattributes\??ia\c!style\c!color{#1\presetgoto}}% + {\dostartgotoprofile\buttonwidth\buttonheight{#2}}% + {\dostopgotoprofile}}% + \else + {#1}% + \fi} + +\def\followprofile#1[#2]% + {\iflocation + \doif\@@pfoption\v!test{\pagereference[\c!profiel!!#2]}% + \dofollowprofile{#1}[#2]% + \fi} + +\def\setupprofiles% + {\dodoubleargument\getparameters[\??pf]} + +% Als er nog geen tekst op de pagina staat, dan heeft het +% profiel betrekking op het bovenstaande, dus soms een vorige +% pagina! Vreemd, omdat PDF paginagewijs werkt. Gelukkig +% biedt /page een oplossing. Echter: expansie van een +% \special kan niet worden uitgesteld, zodat alleen een +% two-pass een oplossing vormt. Het onderstaande kan komen +% te vervallen als Acrobat dit ondervangt. Het scheelt een +% pass en een lijst. +% +% Er kunnen eventueel twee lijsten worden gebruikt. Een voor +% het begin (start) en een voor het eind (stop). Nu staat +% alles in een lijst. + +\definetwopasslist\s!profile + +\newcounter\currentprofile + +\def\dosetprofilepage% + {\doglobal\increment\currentprofile + \lazysavetwopassdata{\s!profile}{\currentprofile}{\noexpand\realfolio}} + +\def\dogetprofilepage% + {\gettwopassdata{\s!profile}% + \let\profilepage=\twopassdata} + +% is this stuff used at all + +\newcounter\versionlevel +\newcounter\versionorder + +\newif\ifrecentversion + +\let\oldatcharacter=@ + +\def\minimumversion{0} +\def\actualversion{0} + +\def\dosetupversions[#1]% + {\getparameters[\??ve][#1] + \stripcharacter.\from\@@venumber\to\minimumversion} + +\def\setupversions + {\dosingleargument\dosetupversions} + +\definetwopasslist\s!versionbegin +\definetwopasslist\s!versionend + +\let\actualprofile\empty + +\def\doresetpageversion + {\lazysavetwopassdata{\s!versionend}{\versionorder}{\noexpand\realfolio}} + +\def\dosetpageversion#1% + {\recentversiontrue + \doglobal\increment\versionorder\relax + \lazysavetwopassdata{\s!versionbegin}{\versionorder}{\noexpand\realfolio}% + \let\resetpageversion\doresetpageversion} + +\def\recentcontributions{} + +\def\checkrecentcontributions% + {\gettwopassdata{\s!versionbegin}% + \iftwopassdatafound + \!!counta\twopassdata\relax + \gettwopassdata{\s!versionend}% + \iftwopassdatafound + \!!countb\twopassdata\relax + \doglobal\increment\versionorder\relax + \savetwopassdata{\s!versionbegin}{\versionorder}{\the\!!counta}% + \savetwopassdata{\s!versionend }{\versionorder}{\the\!!countb}% + \dostepwiserecurse\!!counta\!!countb\plusone + {\@EA\doglobal\@EA\addtocommalist\@EA{\recurselevel}{\recentcontributions}}% + \let\next\checkrecentcontributions + \else + \let\next\relax + \fi + \else + \let\next\relax + \fi + \next} + +\def\docheckpageversion + {\ExpandBothAfter\doifinsetelse{\realfolio}{\recentcontributions} + {\pageselectedtrue}% + {\pageselectedfalse}} + +\let\setpageversion \gobbleoneargument +\let\resetpageversion \relax +\let\checkpageversion \relax + +\def\complexstartversion[#1]% + {\bgroup + \doifelsenothing\actualprofile + {\startprofile[#1]}% + {\startprofile[#1,\actualprofile]}% + \def\docomplexstartversie##1% + {\stripcharacter.\from##1\to\actualversion + \ifnum\versionlevel>\zerocount\relax + \ifnum\actualversion=\zerocount + \setpageversion\actualversion % unknown version + \else + \ifnum\actualversion<\minimumversion\relax + \relax % old version + \else + \setpageversion\actualversion % new version + \fi + \fi + \fi}% + \doglobal\increment\versionlevel\relax + \doifelsenothing{#1} + {\docomplexstartversie{0}}% + {\processcommalist[#1]\docomplexstartversie}} + +\definecomplexorsimpleempty\startversion + +\def\stopversion + {\stopprofile + \doglobal\decrement\versionlevel + \ifnum\versionlevel<\zerocount + \showmessage\m!versions1\empty + \else + \resetpageversion + \egroup + \fi} + +\def\markversion + {\showmessage\m!versions2\empty + \let\setpageversion\dosetpageversion + \let\resetpageversion\relax + \let\checkpageversion\relax} + +\def\selectversion + {\checkrecentcontributions + \showmessage\m!versions3\recentcontributions + \let\setpageversio\gobbleoneargument + \let\resetpageversion\relax + \let\checkpageversion\docheckpageversion} + +\def\dodefineversion[#1][#2]% + {\setvalue{\c!versie!!#1}{#2}% + \defineprofile[#1][#2]} + +\def\defineversion + {\dodoubleargument\dodefineversion} + +\def\followversion + {\followprofile} + +\def\followprofileversion#1[#2][#3]% + {\def\docommand##1% + {\defineprofile[#2#3][##1]}% + \processcommacommand[\getvalue{\c!versie!!#3}]\docommand + \followprofile#1[#2#3]} + +\newcounter\currentpagetransition + +\newif\ifrandomtransitions + +\def\setuppagetransitions% + {\dosingleempty\dosetuppagetransitions} + +\def\dosetuppagetransitions[#1]% + {\doifelsenothing{#1} + {\doifnot\@@scdelay\v!none + {\let\setpagetransition\setsomepagedelay}} + {\doifelse{#1}\v!start + {\doifnot\@@scdelay\v!none + {\let\setpagetransition\setsomepagedelay}} + {\doglobal\newcounter\currentpagetransition + \doifinsetelse{#1}{\v!reset,\v!stop} + {\let\setpagetransition\relax} + {\let\setpagetransition\setsomepagetransition + \doifinsetelse\v!random{#1} + {\randomtransitionstrue}{\randomtransitionsfalse}% + \edef\userpagetransitions{#1}% + \@EA\removefromcommalist\@EA{\v!random}\userpagetransitions + \ifx\userpagetransitions\empty + \let\userpagetransitions\pagetransitions + \fi}}}} + +\def\setsomepagedelay + {\expanded{\dosetpagetransition{0}{\@@scdelay}}} + +\def\setsomepagetransition + {\iflocation + \ifrandomtransitions + \expanded{\getcommalistsize[\userpagetransitions]}% + \getrandomnumber\currentpagetransition1\commalistsize + \else + \doglobal\increment\currentpagetransition + \fi + \expanded{\getfromcommalist[\userpagetransitions][\currentpagetransition]}% + \doifnumberelse\commalistelement + {\expanded{\getfromcommalist[\pagetransitions][\commalistelement]}} + {}% + \ifx\commalistelement\empty + \doglobal\newcounter\currentpagetransition + \setsomepagetransition + \else + \doifelse\@@scdelay\v!none + {\expanded{\dosetpagetransition{\commalistelement}{0}}} + {\expanded{\dosetpagetransition{\commalistelement}{\@@scdelay}}}% + \fi + \fi} + +\prependtoks \setpagetransition \to \everyshipout + +% temporary here + +%D \startbuffer +%D \dorecurse{10} +%D {\horizontalpositionbar +%D \pos\recurselevel \min1 \max10 +%D \token\framed{\recurselevel}% +%D \\} +%D +%D \hbox to 15em +%D {\hss +%D \dorecurse{10} +%D {\verticalpositionbar\pos\recurselevel\min1\max10\token\blackrule\\ +%D \hss}} +%D \stopbuffer + +\def\horizontalpositionbar\pos#1\min#2\max#3\token#4\\% + {\hbox to \hsize + {\hskip\zeropoint\!!plus #1\!!fill + \hskip\zeropoint\!!plus-#2\!!fill + #4\relax + \hskip\zeropoint\!!plus #3\!!fill + \hskip\zeropoint\!!plus-#1\!!fill}} + +\def\verticalpositionbar\pos#1\min#2\max#3\token#4\\% + {\vbox to \vsize + {\vskip\zeropoint\!!plus #1\!!fill + \vskip\zeropoint\!!plus-#2\!!fill + \hbox{#4}\relax + \vskip\zeropoint\!!plus #3\!!fill + \vskip\zeropoint\!!plus-#1\!!fill}} + +\def\horizontalgrowingbar\pos#1\min#2\max#3\height#4\depth#5\\% + {\hbox to \hsize + {\scratchcounter#1% + \advance\scratchcounter -#2% + \advance\scratchcounter \plusone + \leaders\vrule\hskip\zeropoint\!!plus \scratchcounter\!!fill + \vrule\!!width\zeropoint\!!height#4\!!depth#5% + \hskip\zeropoint\!!plus #3\!!fill + \hskip\zeropoint\!!plus-#1\!!fill}} + +\def\verticalgrowingbar\pos#1\min#2\max#3\width#4\\% + {\vbox to \vsize + {\scratchcounter#1% + \advance\scratchcounter -#2% + \advance\scratchcounter \plusone + \leaders\hrule\vskip\zeropoint\!!plus\scratchcounter\!!fill + \hrule\!!width#4\!!height\zeropoint\!!depth\zeropoint + \vskip\zeropoint\!!plus #3\!!fill + \vskip\zeropoint\!!plus-#1\!!fill}} + +\newbox\commentbox + +\def\doflushcommentanchors + {\let\next\relax % new + \processaction + [\@@cclocation] + [% \v!text=>\let\next\relax, % new + \v!inmargin=>\let\next\inmargin, % brr not the same as inleft|rightmargin + \v!leftedge=>\let\next\inleftedge, + \v!rightedge=>\let\next\inrightedge, + \v!leftmargin=>\let\next\inleftmargin, + \v!rightmargin=>\let\next\inrightmargin]% + \next{\hbox{\raise\strutht\box\commentbox}}} + +\def\flushcommentanchors % in everypar so indirect + {\ifvoid\commentbox\else \doflushcommentanchors \fi} + +\def\setupcomment + {\dodoubleargument\getparameters[\??cc]} + +\setvalue{\e!start\v!comment}% the dummy triple gobbles trailing spaces + {\dotripleempty\dostartcommentaar} + +\def\comment + {\dodoubleempty\docomment} + +\def\dodocomment#1% + {\!!widtha\@@ccwidth + \!!heighta\@@ccheight + \doifelse\@@ccoption\v!max + {\let\@@ccopen \!!plusone}{\let\@@ccopen \!!zerocount}% + \doifelse\@@ccoption\v!buffer + {\let\@@cccollect\!!plusone}{\let\@@cccollect\!!zerocount}% + \preparecommentvariables + \doinsertcomment + \@@cctitle\!!widtha\!!heighta + \@@cccolor\@@ccopen\@@ccsymbol + \@@cccollect{#1}} + +\def\preparecommentvariables % more will move here as with fields + {\let\@@DriverCommentLayer\@@cctextlayer} + +\def\dopreparecommentaar#1#2% + {\doifassignmentelse{#1} + {\getparameters[\??cc][#1]} + {\getparameters[\??cc][\c!title=#1,#2]}% + \obeylines + \doif\@@ccspace\v!yes\obeyspaces} + +\def\dostartcommentaar[#1][#2][#3]% + {\bgroup + \doifelse\@@ccstate\v!start + {\dopreparecommentaar{#1}{#2}% + \long\def\docommand##1% + {\global\setbox\commentbox\frozenhbox + {\hbox to \zeropoint + {\struttedbox{\tbox{\dodocomment{##1}}}\hss}% + \hskip\ifvoid\commentbox\@@ccmargin\else\@@ccdistance\fi + \box\commentbox}% + \egroup}}% + {\long\def\docommand##1% + {\egroup}}% + \grabuntil{\e!stop\v!comment}\docommand} + +\letvalue{\e!stop\v!comment}\relax % handy for \expanded{...} + +\def\docomment[#1][#2]#3% + {\doif\@@ccstate\v!start + {\hbox to \zeropoint + {\dopreparecommentaar{#1}{#2}% + \hskip-\@@ccmargin + \struttedbox{\tbox{\dodocomment{#3}}\hss}}}% + \ignorespaces} + +% \startcomment +% hello beautiful\\world +% \stopcomment +% +% \startcomment[hello] +% hello << \'e\'erste >> +% beautiful +% world +% \stopcomment +% +% \startcomment[hello][color=green,width=4cm,height=3cm] +% hello \leftguillemot\ \'e\'erste \rightguillemot\ +% beautiful +% world +% \stopcommentaar +% +% \startcomment[hello][color=green,width=4cm,height=3cm] +% hello \leftguillemot\ \'e\'erste \rightguillemot\ test +% +% beautiful +% +% world +% \stopcomment +% +% \startcomment[symbol=Balloon] +% Do we want this kind of rubish? And, why isn't this and +% some more features related to text annotations so poorly +% (actually not) documented? Anyhow, by providing this +% functionality we demonstrate that \pdfTeX\ can do it. By +% the way, it's funny that when in Acrobat we scale up the +% text, the symbols scale down. +% \stopcomment + +% \definesymbol [comment-normal][{\externalfigure[cow.pdf]}] +% \definesymbol [comment-down] [{\externalfigure[cow.pdf]}] +% +% \def\CowSymbol#1#2% +% {\scale +% [\c!height=#1] +% {\startMPcode +% loadfigure "koe.mp" number 1 ; +% refill currentpicture withcolor #2 ; +% \stopMPcode}} +% +% \definesymbol [comment-normal] +% [\CowSymbol{4ex}{red}] +% +% \definesymbol [comment-down] +% [\CowSymbol{4ex}{green}] +% +% \setupcomment +% [\c!symbol={comment-normal,comment-down}, +% \c!option=\v!buffer] +% +% \setupfootertexts[\placecomments] + +\def\placecomments + {\doflushcomments} + +% \setupinteraction[state=start] +% +% \useattachment[test.tex] +% \useattachment[whatever][test.tex] +% \useattachment[whatever][newname][test.tex] +% \useattachment[whatever][title][newname][test.tex] +% +% % \setupattachments[\c!symbol={symbol-normal,symbol-down}] +% +% \starttext \attachment[whatever] \stoptext + +\definesystemvariable{at} + +\def\useattachment + {\doquadrupleempty\douseattachment} + +\def\douseattachment[#1][#2][#3][#4]% tag title newname filename + {\iffourthargument + \setgvalue{\??at:#1}{{#2}{#3}{#4}}% tooltip kind of case + \else\ifthirdargument + \setgvalue{\??at:#1}{{#2}{#2}{#3}}% full path case + \else\ifsecondargument + \setgvalue{\??at:#1}{{#2}{#2}{#2}}% obvious case + \else + \setgvalue{\??at:#1}{{#1}{#1}{#1}}% worst case + \fi\fi\fi} + +\let\attachmenttitle\empty +\let\attachmentname \empty +\let\attachmentfile \empty + +\def\getattachmentdata[#1]% + {\edef\attachmenttitle{\filterfromvalue{\??at:#1}31}% description + \edef\attachmentname {\filterfromvalue{\??at:#1}32}% new name + \edef\attachmentfile {\filterfromvalue{\??at:#1}33}% original + \expandafter\splitstring\attachmentname\at.\to\!!stringa\and\!!stringb + \ifx\!!stringb\empty % no suffix, so we need to inherit it + \expandafter\splitstring\attachmentfile\at.\to\!!stringc\and\!!stringd + \edef\attachmentname{\attachmentname.\!!stringd}% + \fi} + +\def\attachment + {\dodoubleempty\doattachment} + +\def\doattachment[#1][#2]% currently title equals newname + {\iflocation + \ifsecondargument + \doifundefined{\??at:#2} + {\showmessage\m!interactions6{#2}% + \useattachment[#2]}% + \doif\@@atstate\v!start + {\bgroup + \getattachmentdata[#2]% + \doiffileelse\attachmentfile + {\setupattachments[#1]% + \presetattachmentvariables +\struttedbox{\tbox{% + \doattachfile + \attachmenttitle + {1em}\strutheight\strutdepth\@@atcolor\@@atsymbol + \attachmentname + \attachmentfile}% +}}% + {\showmessage\m!interactions5\attachmentfile}% + \egroup}% + \else\iffirstargument + \attachment[][#1]% + \fi\fi + \fi} + +\def\presetattachmentvariables + {\let\@@DriverAttachmentLayer\@@attextlayer} + +\def\setupattachments + {\dodoubleempty\getparameters[\??at]} + +\setupattachments + [\c!state=\v!start, + \c!color=\@@iacolor, + \c!textlayer=, + \c!symbol=] + +% jammer, tussen/midden had erin gemoeten; \c!commando toevoegen + +\def\registermenucommand#1% + {{\textonly\noindent#1\space}} % no math switching + +\def\doregistermenubuttons[#1][#2]% [menu id] [register] + {\bgroup + \ifsecondargument + \setupinteractionmenu + [#1][\c!unknownreference=\v!yes,\c!samepage=\v!yes]% + \def\docommand##1% + {\registermenucommand{\menubutton[#1]{##1}[#2:##1]}}% + \else + \def\docommand##1% + {\registermenucommand + {\button + [\c!unknownreference=\v!yes,\c!samepage=\v!yes] + {##1}[#1:##1]}}% + \fi + \handletokens abcdefghijklmnopqrstuvwxyz\with\docommand % moet anders + \egroup} + +\def\registermenubuttons + {\dodoubleempty\doregistermenubuttons} + +\stelkoppelingenin + [\c!distance=.25em, + \c!width=\v!fit, + \c!location=\v!low, + \c!color=\@@iacolor, + \c!frame=\v!off, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=] + +\defineinteractionmenu + [\v!right] + [\v!right] + [\c!before=, + \c!after=\vfil, + \c!inbetween=\blank, + \c!distance=\bodyfontsize, % 12pt + \c!left=\hss, + \c!right=\hss, + \c!width=\rightedgewidth, + \c!height=\v!broad] + +\defineinteractionmenu + [\v!left] + [\v!left] + [\c!before=, + \c!after=\vfil, + \c!inbetween=\blank, + \c!distance=\bodyfontsize, % 12pt + \c!left=\hss, + \c!right=\hss, + \c!width=\leftedgewidth, + \c!height=\v!broad] + +\defineinteractionmenu + [\v!bottom] + [\v!bottom] + [\c!before=\vss, + \c!after=\vss, + \c!middle=\hfil, + \c!distance=\bodyfontsize, % 12pt + \c!width=\v!fit, + \c!height=\v!broad] + +\defineinteractionmenu + [\v!top] + [\v!top] + [\c!before=\vss, + \c!after=\vss, + \c!middle=\hfil, + \c!distance=\bodyfontsize, % 12pt + \c!width=\v!fit, + \c!height=\v!broad] + +\setupinteractionmenu + [\v!left,\v!right,\v!top,\v!bottom] + [\c!offset=.25em, + \c!position=\v!no, + \c!frame=\v!on, + \c!background=, + \c!backgroundcolor=, + \c!backgroundscreen=\@@rsscreen, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!state=\v!start, + \c!samepage=\v!yes, + \c!unknownreference=\v!empty, + \c!topoffset=\!!zeropoint, + \c!bottomoffset=\!!zeropoint, + \c!leftoffset=\!!zeropoint, + \c!rightoffset=\!!zeropoint] + +\def\placeleftedgetextblock % Is \hss/\hsize really needed here? + {\hbox to \leftedgewidth % (check outer level and settings) + {\hsize\leftedgewidth\hss\interactionmenus[\v!left]}} + +\def\placerightedgetextblock % Is \hss/\hsize really needed here? + {\hbox to \rightedgewidth % (check outer level and settings) + {\hsize\rightedgewidth\interactionmenus[\v!right]\hss}} + +\def\placetoptextblock + {\vbox to \topheight + {\vsize\topheight + \csname\??tk\v!top\c!before\endcsname + \interactionmenus[\v!top]% + \csname\??tk\v!top\c!after\endcsname + \kern\zeropoint}} + +\def\placebottomtextblock + {\vbox to \bottomheight + {\vsize\bottomheight + \csname\??tk\v!bottom\c!before\endcsname + \interactionmenus[\v!bottom]% + \csname\??tk\v!bottom\c!after\endcsname + \kern\zeropoint}} + +\ifx\leftedgetextcontent\undefined \else + + \appendtoks \placeleftedgetextblock \hskip-\leftedgewidth \to \leftedgetextcontent + \appendtoks \placerightedgetextblock \hskip-\rightedgewidth \to \rightedgetextcontent + \appendtoks \placetoptextblock \vskip-\topheight \to \toptextcontent + \appendtoks \placebottomtextblock \vskip-\bottomheight \to \bottomtextcontent + +\fi + +\setupinteractionscreen + [\c!width=\printpaperwidth, + \c!height=\printpaperheight, + \c!horoffset=\!!zeropoint, + \c!veroffset=\!!zeropoint, + \c!backspace=\backspace, + \c!topspace=\topspace, + \c!option=\v!min, + \c!delay=\v!none] + +\setupbuttons + [\c!state=\v!start, + \c!width=\v!fit, + \c!height=\v!broad, + \c!offset=0.25em, + \c!frame=\v!on, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!samepage=\v!yes, + \c!unknownreference=\v!yes] + +\setupinteractionbar + [\c!state=\v!start, + \c!alternative=a, + \c!symbol=\v!no, + \c!width=\rightedgewidth, + \c!height=, % these are taken care + \c!depth=, % of at calling time + \c!distance=.5em, % beter relateren aan breedte + \c!step=1, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!frame=\v!on, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!samepage=\v!yes, + \c!unknownreference=\v!yes] + +\setupsynchronizationbar + [\c!alternative=\v!page, + \c!width=\rightedgewidth, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=] + +\setupsynchronization + [\c!state=\v!stop] + +\setupprofiles + [\c!option=] + +\setuppagetransitions + [\v!reset] + +\setupcomment + [\c!state=\v!start, + \c!margin=2.5em, + \c!distance=1em, + \c!width=.3\textwidth, + \c!height=.2\textheight, + \c!color=\@@iacolor, + \c!title=, + \c!space=\v!no, + \c!symbol=\v!normal, + \c!location=\v!inmargin, + \c!option=, + \c!textlayer=] + +\setupversions % beware, @ is made active here, + [\c!number=1, % therefore we set this one at the end + \c!style=\ss, + \c!color=] + +\protect \endinput diff --git a/tex/context/base/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..441951eff --- /dev/null +++ b/tex/context/base/scrn-nav.mkiv @@ -0,0 +1,425 @@ +%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 When I started implementing hypertext support, the macros +%D were mostly dealing with things related to locations, that +%D is click in this location and goto that one. The +%D functionality of many macro depends on the output medium: +%D paper or screen. The next boolean holds the state: + +\newif\iflocation \def\ifinteractief{\iflocation} % upw comp + +%D We also allocate a scratchbox: + +\newbox\locationbox + +%D There is no interaction at all unless enabled by saying: +%D +%D \starttyping +%D \setupinteraction[state=start] +%D \stoptyping +%D +%D The other settings are: +%D +%D \showsetup{setupinteraction} +%D +%D In the special driver modules we introduced a switch that +%D forces page destinations (instead of named ones). We set +%D this switch here. + +\def\setinteractionparameter#1#2% use with case, no checking done + {\setvalue{\??ia#1}{#2}} % pass #2, can be \blabla + +\def\resetinteractionparameter#1% use with case, no checking done + {\letvalue{\??ia#1}\empty} + +% \def\interactionparameter#1% +% {\csname\??ia#1\endcsname} + +\newtoks\everysetupinteraction + +\def\setupinteraction + {\dosingleargument\dodosetupinteraction} + +\def\dodosetupinteraction[#1]% % \dosetupinteraction == special + {\getparameters[\??ia][#1]% + \the\everysetupinteraction} + +% todo, move partial append to where the action happens + +\appendtoks + \doifelse\@@iastate\v!start + {\iflocation\else + \showmessage\m!interactions2{\ifusepagedestinations\space(PAGE)\fi}% + \global\locationtrue + \fi} + {\iflocation + \showmessage\m!interactions3{\ifusepagedestinations\space(PAGE)\fi}% + \global\locationfalse + \fi}% + \iflocation + \setsystemmode \v!interaction + \else + \resetsystemmode\v!interaction + \fi + \dosetuppageview\@@iafocus + \doifsomething\@@iacalculate + {\doregistercalculationset\@@iacalculate}% + \doifelse\@@iastrut\v!yes + \locationstruttrue + \locationstrutfalse + \doifelse\@@iaclick\v!yes + \highlighthyperlinkstrue + \highlighthyperlinksfalse + \doifelse\@@iasplit\v!yes + \locationsplittrue + \locationsplitfalse + \doifelse\@@iadisplay\v!new + \gotonewwindowtrue + \gotonewwindowfalse + \doifelse\@@iapage\v!yes + {\global\usepagedestinationstrue} + {\global\usepagedestinationsfalse}% +\to \everysetupinteraction + +%D We have to make sure of some settings: + +\def\dolocationstartup + {\iflocation + \dosetupinteraction + \handlereferenceactions\@@iaopenaction \dosetupopenaction + \handlereferenceactions\@@iacloseaction\dosetupcloseaction + \setupinteractionscreens + \global\let\dolocationstartup\relax + \fi} + +\appendtoks \dolocationstartup \to \everyshipout + +\def\dolocationpagecheck % brr pdf dependent + {\iflocation + \handlereferenceactions\@@iaopenpageaction \dosetupopenpageaction + \handlereferenceactions\@@iaclosepageaction\dosetupclosepageaction + \fi} + +\appendtoks \dolocationpagecheck \to \everyshipout + +%D The next few macros are really horrible. For proper +%D navigation a in||line hypertext fragment must have +%D comfortable properties, so we must force some minimal +%D dimensions. On the other hand button, and here I mean those +%D pieces of text with fancy outlines and/or backgrounds, often +%D have fixed, preset dimensions. +%D +%D To make things even worse, if we choose to let the optimal +%D dimensions depend on the height and depth of a strut, a not +%D too uncommon practice in \TEX, we have to deal with the fact +%D that such a strut, set inside a box, is unknown too the +%D outside world. +%D +%D The solution lays in passing the strut characteristics in +%D a proper way, in our case by applying \type{\presetgoto}: +%D +%D \starttyping +%D {some piece of text \presetgoto} +%D \stoptyping +%D +%D This macro stores the current strut values. + +\newif\iflocationstrut +\newif\iflocationsplit + +\def\resetgoto + {\globallet\@@ia@@hoogte\!!zeropoint + \globallet\@@ia@@diepte\!!zeropoint} + +\resetgoto + +\def\presetgoto + {\iflocationstrut + \setstrut + %\xdef\@@ia@@hoogte{\the\strutht}% + %\xdef\@@ia@@diepte{\the\strutdp}% + \globallet\@@ia@@hoogte\strutheight + \globallet\@@ia@@diepte\strutdepth + \else + \globallet\@@ia@@hoogte\@@iaheight + \globallet\@@ia@@diepte\@@iadepth + \fi} + +%D In the macros that deal with making areas into hyperlinks, +%D we use: + +\newbox\driverresources + +\def\collectdriverresource#1% + {\global\setbox\driverresources\hbox{\box\driverresources#1}} + +\def\flushdriverresources + {\ifvoid\driverresources\else\box\driverresources\fi} + +% \def\dohandlegoto#1#2#3% +% {\ifsecondaryreference +% \bgroup\setbox0\hbox{#2#3}\egroup +% \else +% \hbox +% {\setbox0\hbox{#1}% +% \ifdim\wd0<\@@iawidth\relax +% \buttonwidth\@@iawidth\relax +% \else +% \buttonwidth\wd0 +% \fi +% \ifdim\ht0<\@@ia@@hoogte\relax +% \buttonheight\@@ia@@hoogte\relax +% \else +% \buttonheight\ht0 +% \fi +% \ifdim\dp0<\@@ia@@diepte\relax +% \dimen0=\@@ia@@diepte\relax % = ! +% \else +% \dimen0\dp0 +% \fi +% \advance\buttonheight \dimen0 +% \setbox2\hbox +% {\lower\dimen0\hbox +% {\dontcomplain +% \dimen0=.5\wd0 % direct skipping is faster of course +% \advance\dimen0 -.5\buttonwidth % buts this is nicer +% \hskip\dimen0#2#3}}% when visualizing things +% \naturalhbox % needed for omega / moved from plus-omg +% {\ifreversegoto +% \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0 +% \else +% \smashbox2\box2\box0 +% \fi +% \flushdriverresources}% +% \resetgoto}% +% \fi} + +\def\dohandlegoto#1#2#3% + {\ifcollectreferenceactions + % this happens here while in mkii elsewhere, better is to deal with + % in in the ref module but that's for later to deal with + \bgroup\setbox\scratchbox\hbox{#2#3}\egroup + \ifsecondaryreference \else + \resetgoto + \fi + \ifsecondaryreference\else#1\resetgoto\fi + \else\ifsecondaryreference + \bgroup\setbox\scratchbox\hbox{#2#3}\egroup + \else + \hbox + {\setbox0\hbox{#1}% + \ifdim\wd0<\@@iawidth\relax + \buttonwidth\@@iawidth\relax + \else + \buttonwidth\wd0 + \fi + \ifdim\ht0<\@@ia@@hoogte\relax + \buttonheight\@@ia@@hoogte\relax + \else + \buttonheight\ht0 + \fi + \ifdim\dp0<\@@ia@@diepte\relax + \dimen0=\@@ia@@diepte\relax % = ! + \else + \dimen0\dp0 + \fi + \advance\buttonheight \dimen0 + \setbox2\hbox + {\lower\dimen0\hbox + {\dontcomplain + \dimen0=.5\wd0 % direct skipping is faster of course + \advance\dimen0 -.5\buttonwidth % buts this is nicer + \hskip\dimen0#2#3}}% when visualizing things + \naturalhbox % needed for omega / moved from plus-omg + {\ifreversegoto + \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0 + \else + \smashbox2\box2\box0 + \fi + \flushdriverresources}% + \resetgoto}% + \fi\fi} + +%D The secondary references are processed but not typeset. The +%D special driver must collect the data needed. + +%D The width of the active area depends on the dimensions +%D preset, the actual dimens and/or the height and depth of the +%D strut. +%D +%D Normally the hyper active area is laid on top of the text. +%D This enables stacking hyperlinks on top of each other. When, +%D for some reason the opposite is prefered, one can use the +%D next boolean to signal this wish. + +\newif\ifreversegoto \reversegotofalse + +%D As long as there a natural feeling of what can be considered +%D hyper active or not, we have to tell users where they can +%D possibly click. We've already seen a few macros that deal +%D with this visualization, something we definitely do not let +%D up to the viewer. One way of telling is using a distinctive +%D typeface, another way is using color. +%D +%D There are two colors involved: one for normal hyperlinks, +%D and one for those that point to the currentpage, the +%D contrast color. + +\definecolor [interactioncolor] [r=0, g=.6, b=0] +\definecolor [interactioncontrastcolor] [r=.8, g=0, b=0] + +\definecolor [interactiekleur] [interactioncolor] +\definecolor [interactiecontrastkleur] [interactioncontrastcolor] + +%D The next few macros are responsible for highlighting hyper +%D links. The first one, \type{\showlocation}, is used in those +%D situations where the typeface is handled by the calling +%D macro. + +\def\interactioncolor % todo \??ia as argument + {\iflocation + \ifrealreferencepage + \@@iacontrastcolor + \else + \@@iacolor + \fi + \fi} + +%D CHECK WHERE USED / CONSISTENCY + +\def\showlocation#1% + {\iflocation\color[\@@iacolor]{#1\presetgoto}\else#1\fi} + +%D When local color settings are to be used, we can use the +%D next macro, where \type{#1} is a tag like \type{\??tg} and +%D \type{#2} some text. + +\def\showcoloredlocation#1#2% + {\iflocation + \color[\getvalue{#1\c!color}]{#2\presetgoto}% + \else + #2% + \fi} + +%D When we're dealing with pure page references, contrast +%D colors are used when we are already at the page mentioned. + +\def\showcontrastlocation#1#2#3% the \@EA is needed + {\iflocation + \ifnum#2=\realpageno\relax + \doifelsevaluenothing{#1\c!color} + {#3\presetgoto} + {\color[\getvalue{#1\c!contrastcolor}]{#3\presetgoto}}% + \else + \color[\getvalue{#1\c!color}]{#3\presetgoto}% + \fi + \else + #3% + \fi} + +%D The next simple macro can be used in color specifications, +%D like \type{\color[\locationcolor{green}]}. + +\def\locationcolor#1% + {\iflocation#1\fi} + +%D More tokens are spend when we want both typeface and color +%D highlighting. + +\def\dolocationattributes#1#2#3#4% + {\bgroup + \let\fontattribute\empty + \let\colorattribute\empty + \doifdefined{#1#2}{\def\fontattribute{\getvalue{#1#2}}}% + \iflocation + \doifdefined{#1#3}{\def\colorattribute{\getvalue{#1#3}}}% + \fi + \startcolor[\colorattribute]% + \@EA\doconvertfont\@EA{\fontattribute}{#4}% no \edef, but \@EA here + \stopcolor + \egroup} + +\def\navigating + {\dolocationattributes\??ia\c!style\c!color} + +%D Although not decently supported in current viewers, a +%D provisory hiding mechanims is implemented. Areas marked as +%D such, are visible on screen, but invisible on paper. Don't +%D trust this mechanism yet! + +\def\dostartinteraction + {\bgroup + \let\stopinteraction\egroup + \dowithnextbox{\dostarthide\flushnextbox\dostophide\egroup}\hbox} + +\let\startinteraction = \relax +\let\stopinteraction = \relax + +% in the future: +% +% eerst boolean invoeren bij menu, achtergrond, balk, button +% enz; verder startinteractie een argument meegeven {#1} -> +% \getvalue{#1\c!print}=={\v!ja} enz. Consequent menubutton +% gebruiken! + +\def\@@iatimestamp + {\the\normalyear + \ifnum\normalmonth<10 0\fi\the\normalmonth + \ifnum\normalday <10 0\fi\the\normalday} + +% happens in core-fld +% +% \definereference [AtOpenInitializeForm] [\v!geen] + +\setupinteraction % start fit page and reset form + [\c!state=\v!stop, + \c!page=\v!no, + \c!click=\v!yes, + \c!display=, + %\c!openaction={\v!firstpage,AtOpenInitializeForm}, + %\c!openaction={\v!firstpage,\v!ResetForm}, + %\c!openaction=\v!ResetForm, % too buggy in reader 4.05 + \c!openaction=, + \c!closeaction=, + \c!openpageaction=, + \c!closepageaction=, + \c!display=\v!normal, + \c!focus=\v!fit, + \c!menu=\v!off, + \c!style=\v!bold, + \c!calculate=, + \c!strut=\v!yes, + \c!split=\v!yes, + \c!color=interactioncolor, + \c!contrastcolor=interactioncontrastcolor, + \c!symbolset=, + \c!width=1em, + \c!height=\!!zeropoint, + \c!depth=\!!zeropoint, + \c!title=\jobname, % needed for fdf/x + \c!subtitle=, + \c!author=, + \c!keyword=, + \c!date=\@@iatimestamp] + +\protect \endinput diff --git a/tex/context/base/scrp-ini.mkiv b/tex/context/base/scrp-ini.mkiv new file mode 100644 index 000000000..3382ef4b6 --- /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] +\definesystemattribute[prestat] + +%D Since scripts need specific \LUA\ code we use hard coded attribute +%D values, but we might have more tricks at some time, so we use a +%D proper define macro too. + +\unprotect + +\def\s!attribute{attribute} + +\def\namedscriptparameter#1#2% + {\csname\doscriptparameter{\??ls#1}#2\endcsname} + +\def\scriptparameter#1% + {\csname\doscriptparameter{\??ls\currentscript}#1\endcsname} + +\def\doscriptparameter#1#2% + {\ifcsname#1#2\endcsname#1#2\else\expandafter\doscriptparentparameter\csname#1\s!parent\endcsname#2\fi} + +\def\doscriptparentparameter#1#2% + {\ifx#1\relax\s!empty\else\doscriptparameter#1#2\fi} + +% \def\scriptparameterhash#1% +% {\doscriptparameterhash{\??ls\currentscript}#1} +% +% \def\doscriptparameterhash#1#2% +% {\ifcsname#1#2\endcsname#1\else\expandafter\doscriptparentparameterhash\csname#1\s!parent\endcsname#2\fi} +% +% \def\doscriptparentparameterhash#1#2% +% {\ifx#1\relax\else\doscriptparameterhash#1#2\fi} + +% when #2 == string, then only synonym, no settings + +\def\definescript + {\dodoubleargument\dodefinescript} + +\def\dodefinescript[#1][#2]% + {\doifassignmentelse{#2} + {\getparameters[\??ls#1][\c!method=,\s!parent=,#2]% + \doifelsenothing{\namedscriptparameter{#1}\c!method} + {\letvalue {\??ls#1\s!attribute}\attributeunsetvalue}% + {\setevalue{\??ls#1\s!attribute}{\ctxlua{scripts.define("\namedscriptparameter{#1}\c!method")}}}}% + {\getparameters[\??ls#1][\s!parent=#2]}% + \setvalue{#1}{\dosetscript{#1}}} + +\def\setupscript + {\dodoubleargument\dosetupscript} + +\def\dosetupscript[#1][#2]% + {\getparameters[\??ls#1][#2]} + +\def\dosetscript#1% + {\def\currentscript{#1}% + \edef\currentscriptattribute{\scriptparameter\s!attribute}% + \ifx\currentscriptattribute\empty + \let\currentscript\empty + \doresetattribute{preproc}% + \else + \dosetattribute{preproc}\currentscriptattribute % we can speed this up by storing the attribute in ??ls:a:#1 + \fi} + +\def\setscript [#1]{\dosetscript{#1}} +\def\startscript[#1]{\begingroup\dosetscript{#1}} +\def\stopscript {\endgroup} + +% \setscript[hangul] \hangul \startscript[hangul] + +\definescript[latin] [\c!method=] % resets the attribute +\definescript[hangul][\c!method=hangul] +\definescript[hanzi] [\c!method=hanzi] + +\protect \endinput diff --git a/tex/context/base/scrp-ini.tex b/tex/context/base/scrp-ini.tex deleted file mode 100644 index 3382ef4b6..000000000 --- a/tex/context/base/scrp-ini.tex +++ /dev/null @@ -1,91 +0,0 @@ -%D \module -%D [ file=scrp-ini, -%D version=2009.02.06, -%D title=\CONTEXT\ Script Macros, -%D subtitle=Initialization, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% here we collect code from other places (was organized differently) - -\registerctxluafile{scrp-ini}{1.001} -\registerctxluafile{scrp-cjk}{1.001} - -\definesystemattribute[preproc] -\definesystemattribute[prestat] - -%D Since scripts need specific \LUA\ code we use hard coded attribute -%D values, but we might have more tricks at some time, so we use a -%D proper define macro too. - -\unprotect - -\def\s!attribute{attribute} - -\def\namedscriptparameter#1#2% - {\csname\doscriptparameter{\??ls#1}#2\endcsname} - -\def\scriptparameter#1% - {\csname\doscriptparameter{\??ls\currentscript}#1\endcsname} - -\def\doscriptparameter#1#2% - {\ifcsname#1#2\endcsname#1#2\else\expandafter\doscriptparentparameter\csname#1\s!parent\endcsname#2\fi} - -\def\doscriptparentparameter#1#2% - {\ifx#1\relax\s!empty\else\doscriptparameter#1#2\fi} - -% \def\scriptparameterhash#1% -% {\doscriptparameterhash{\??ls\currentscript}#1} -% -% \def\doscriptparameterhash#1#2% -% {\ifcsname#1#2\endcsname#1\else\expandafter\doscriptparentparameterhash\csname#1\s!parent\endcsname#2\fi} -% -% \def\doscriptparentparameterhash#1#2% -% {\ifx#1\relax\else\doscriptparameterhash#1#2\fi} - -% when #2 == string, then only synonym, no settings - -\def\definescript - {\dodoubleargument\dodefinescript} - -\def\dodefinescript[#1][#2]% - {\doifassignmentelse{#2} - {\getparameters[\??ls#1][\c!method=,\s!parent=,#2]% - \doifelsenothing{\namedscriptparameter{#1}\c!method} - {\letvalue {\??ls#1\s!attribute}\attributeunsetvalue}% - {\setevalue{\??ls#1\s!attribute}{\ctxlua{scripts.define("\namedscriptparameter{#1}\c!method")}}}}% - {\getparameters[\??ls#1][\s!parent=#2]}% - \setvalue{#1}{\dosetscript{#1}}} - -\def\setupscript - {\dodoubleargument\dosetupscript} - -\def\dosetupscript[#1][#2]% - {\getparameters[\??ls#1][#2]} - -\def\dosetscript#1% - {\def\currentscript{#1}% - \edef\currentscriptattribute{\scriptparameter\s!attribute}% - \ifx\currentscriptattribute\empty - \let\currentscript\empty - \doresetattribute{preproc}% - \else - \dosetattribute{preproc}\currentscriptattribute % we can speed this up by storing the attribute in ??ls:a:#1 - \fi} - -\def\setscript [#1]{\dosetscript{#1}} -\def\startscript[#1]{\begingroup\dosetscript{#1}} -\def\stopscript {\endgroup} - -% \setscript[hangul] \hangul \startscript[hangul] - -\definescript[latin] [\c!method=] % resets the attribute -\definescript[hangul][\c!method=hangul] -\definescript[hanzi] [\c!method=hanzi] - -\protect \endinput diff --git a/tex/context/base/strc-bkm.mkiv b/tex/context/base/strc-bkm.mkiv new file mode 100644 index 000000000..9298a9d8e --- /dev/null +++ b/tex/context/base/strc-bkm.mkiv @@ -0,0 +1,92 @@ +%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: + +\def\placebookmarks + {\dodoubleempty\doplacebookmarks} + +\def\doplacebookmarks[#1][#2]% + {\iflocation + \iffirstargument + \ctxlua{structure.bookmarks.register("#1","#2")}% + \else + \normalexpanded{\noexpand\placebookmarks[\getvalue{\??ih\v!content\c!list}]}% + \fi + \fi} + +\appendtoks\ctxlua{structure.bookmarks.place()}\to\everystoptext + +\protect \endinput + +% \starttext +% \setupinteraction[state=start]\setupinteractionscreen[option=bookmark] +% \placebookmarks[chapter,section,subsection][chapter] +% \chapter{First} +% \bookmark{The First Indeed} +% \section{alpha} +% \bookmark[chapter]{The First Indeed Again} +% \section{beta} +% \chapter{Second} +% \bookmark{The Second Indeed} +% \section{gamma \tex{radiation}} +% \subsection{a} +% \subsection{b} +% \section{delta} +% \section{epsilon} +% \chapter{Third \relax} +% \chapter{我〈能吞下玻璃而不傷身〉體。} % whatever that means +% \chapter{Idris Samawi Hamid ادريس سماوي حامد} +% \stoptext diff --git a/tex/context/base/strc-bkm.tex b/tex/context/base/strc-bkm.tex deleted file mode 100644 index dd6352356..000000000 --- a/tex/context/base/strc-bkm.tex +++ /dev/null @@ -1,90 +0,0 @@ -%D \module -%D [ file=strc-bkm, -%D version=2009.04.01, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Bookmarks, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Bookmarks} - -\registerctxluafile{strc-bkm}{1.001} - -\unprotect - -%D Due to requests I finally decided to support bookmarks, a -%D driver dependant way of showing tables of content. The most -%D simple way of support is hooking bookmark generation into -%D the existing list mechanisms. That way users can generate -%D bookmarks automatically, although its entirely valid to add -%D bookmarks by defining alternative ones. These will be added -%D at the appropriate place in the list. - -% \hoofdstuk{het eerste hoofdstuk} -% -% \bookmark {de eerste bookmark} % optional overruled hoofdstuk -% -% .... text .... -% -% \placebookmarks [hoofdstuk,paragraaf,subparagraaf,subsubparagraaf,mylist] -% [open list] -% -% \bookmark[mylist]{whatever} - -%D This will go away. - -\let\flushpostponedbookmark\relax - -%D We have better ways now. - -\unexpanded\def\bookmark - {\dosingleempty\dobookmark} - -\def\dobookmark[#1]#2% - {\begingroup - \simplifycommands - \ctxlua{structure.bookmarks.overload("#1",\!!bs\detokenize\expandafter{\normalexpanded{#2}}\!!es)}% - \endgroup} - -%D Placement \unknown\ look how simple compared to \MKII: - -\def\placebookmarks - {\dodoubleempty\doplacebookmarks} - -\def\doplacebookmarks[#1][#2]% - {\iflocation - \iffirstargument - \ctxlua{structure.bookmarks.register("#1","#2")}% - \else - \normalexpanded{\noexpand\placebookmarks[\getvalue{\??ih\v!content\c!list}]}% - \fi - \fi} - -\appendtoks\ctxlua{structure.bookmarks.place()}\to\everystoptext - -\protect \endinput - -% \starttext -% \setupinteraction[state=start]\setupinteractionscreen[option=bookmark] -% \placebookmarks[chapter,section,subsection][chapter] -% \chapter{First} -% \bookmark{The First Indeed} -% \section{alpha} -% \bookmark[chapter]{The First Indeed Again} -% \section{beta} -% \chapter{Second} -% \bookmark{The Second Indeed} -% \section{gamma \tex{radiation}} -% \subsection{a} -% \subsection{b} -% \section{delta} -% \section{epsilon} -% \chapter{Third \relax} -% \chapter{我〈能吞下玻璃而不傷身〉體。} % whatever that means -% \chapter{Idris Samawi Hamid ادريس سماوي حامد} -% \stoptext diff --git a/tex/context/base/strc-blk.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..90d2ff9ab --- /dev/null +++ b/tex/context/base/strc-blk.mkiv @@ -0,0 +1,110 @@ +%D \module +%D [ file=strc-blk, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Blockmoves, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Blockmoves} + +\registerctxluafile{strc-blk}{1.001} + +\unprotect + +% we run on top of buffers and sections +% +% todo: prefix numbers (needs further integration elsewhere) +% check functionality +% alternative files (needs further integration elsewhere) + +\def\blockparameter#1#2{\ifcsname\??tb#1#2\endcsname\csname\??tb#1#2\endcsname\fi} + +\def\setupblockparameters{\dodoubleargument \dosetupblock} % fast one (for compatibility) +\def\setupblock {\dodoubleargumentwithset\dosetupblock} % handles set + +\def\dosetupblock[#1]{\getparameters[\??tb#1]} % [#1][#2]} + +\def\defineblock + {\dosingleargument\dodefineblock} + +\def\dodefineblock[#1]% + {\getparameters + [\??tb#1] + [\c!before=\blank, + \c!after=\blank, + \c!inner=, + \c!style=, + \c!file=]% todo + \ctxlua{structure.blocks.define("#1")}% + \setvalue{\e!begin#1}{\dodoubleempty\dobeginofblock[#1]}% + \letvalue{\e!end#1}\relax} + +\long\def\dobeginofblock[#1][#2]% + {\normalexpanded{\noexpand\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}} + {}{\ctxlua{structure.blocks.save("#1","#2","@block@")}}}% before after + +\def\dostarthiddenblock + {\startnointerference + \dostartnormalblock} + +\def\dostophiddenblock + {\dostopnormalblock + \stopnointerference} + +% order matters: \c!before (think of: \c!before=\startitemize) + +\let\doblocksetups\gobbleoneargument + +\def\dostartnormalblock#1% name + {\bgroup +\visibletrue + \edef\currentblock{#1}% + \doblocksetups\currentblock + \let\doblocksetups\gobbleoneargument + \blockparameter\currentblock\c!before + \dosetfontattribute{\??tb\currentblock}\c!style + \dosetcolorattribute{\??tb\currentblock}\c!color + \blockparameter\currentblock\c!inner + \ignorespaces} + +\def\dostopnormalblock + {\removeunwantedspaces + \blockparameter\currentblock\c!after + \par % todo: alternative = text, paragraph + \egroup} + +\def\dosetblockstate[#1][#2][#3]% state name tag + {\ctxlua{structure.blocks.setstate("#1","#2","#3")}} + +\def\doselectblocks[#1][#2][#3][#4]% state name tag setups + {\begingroup + \doifassignmentelse{#3} + {\getparameters[\??tb\??tb][\c!criterium=\v!text,#3]% + \def\doblocksetups##1{\getparameters[\??tb##1][#3]}% + \ctxlua{structure.blocks.select("#1","#2","","\@@tb@@tbcriterium")}} + {\getparameters[\??tb\??tb][\c!criterium=\v!text,#4]% + \def\doblocksetups##1{\getparameters[\??tb##1][#4]}% + \ctxlua{structure.blocks.select("#1","#2","#3","\@@tb@@tbcriterium")}}% + \endgroup} + +% hide: save, if [+] also hidden execute +% keep: save and normal execute + +\def\hideblocks{\dotripleempty\dosetblockstate[hide]} +\def\keepblocks{\dotripleempty\dosetblockstate[keep]} + +% use : normal execute unless [-] +% process: hidden execute unless [-] +% select : idem use + +\def\useblocks {\doquadrupleempty\doselectblocks[use]} +\def\processblocks{\doquadrupleempty\doselectblocks[process]} +\def\selectblocks {\doquadrupleempty\doselectblocks[use]} + +\protect \endinput diff --git a/tex/context/base/strc-blk.tex b/tex/context/base/strc-blk.tex deleted file mode 100644 index 90d2ff9ab..000000000 --- a/tex/context/base/strc-blk.tex +++ /dev/null @@ -1,110 +0,0 @@ -%D \module -%D [ file=strc-blk, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Blockmoves, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Blockmoves} - -\registerctxluafile{strc-blk}{1.001} - -\unprotect - -% we run on top of buffers and sections -% -% todo: prefix numbers (needs further integration elsewhere) -% check functionality -% alternative files (needs further integration elsewhere) - -\def\blockparameter#1#2{\ifcsname\??tb#1#2\endcsname\csname\??tb#1#2\endcsname\fi} - -\def\setupblockparameters{\dodoubleargument \dosetupblock} % fast one (for compatibility) -\def\setupblock {\dodoubleargumentwithset\dosetupblock} % handles set - -\def\dosetupblock[#1]{\getparameters[\??tb#1]} % [#1][#2]} - -\def\defineblock - {\dosingleargument\dodefineblock} - -\def\dodefineblock[#1]% - {\getparameters - [\??tb#1] - [\c!before=\blank, - \c!after=\blank, - \c!inner=, - \c!style=, - \c!file=]% todo - \ctxlua{structure.blocks.define("#1")}% - \setvalue{\e!begin#1}{\dodoubleempty\dobeginofblock[#1]}% - \letvalue{\e!end#1}\relax} - -\long\def\dobeginofblock[#1][#2]% - {\normalexpanded{\noexpand\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}} - {}{\ctxlua{structure.blocks.save("#1","#2","@block@")}}}% before after - -\def\dostarthiddenblock - {\startnointerference - \dostartnormalblock} - -\def\dostophiddenblock - {\dostopnormalblock - \stopnointerference} - -% order matters: \c!before (think of: \c!before=\startitemize) - -\let\doblocksetups\gobbleoneargument - -\def\dostartnormalblock#1% name - {\bgroup -\visibletrue - \edef\currentblock{#1}% - \doblocksetups\currentblock - \let\doblocksetups\gobbleoneargument - \blockparameter\currentblock\c!before - \dosetfontattribute{\??tb\currentblock}\c!style - \dosetcolorattribute{\??tb\currentblock}\c!color - \blockparameter\currentblock\c!inner - \ignorespaces} - -\def\dostopnormalblock - {\removeunwantedspaces - \blockparameter\currentblock\c!after - \par % todo: alternative = text, paragraph - \egroup} - -\def\dosetblockstate[#1][#2][#3]% state name tag - {\ctxlua{structure.blocks.setstate("#1","#2","#3")}} - -\def\doselectblocks[#1][#2][#3][#4]% state name tag setups - {\begingroup - \doifassignmentelse{#3} - {\getparameters[\??tb\??tb][\c!criterium=\v!text,#3]% - \def\doblocksetups##1{\getparameters[\??tb##1][#3]}% - \ctxlua{structure.blocks.select("#1","#2","","\@@tb@@tbcriterium")}} - {\getparameters[\??tb\??tb][\c!criterium=\v!text,#4]% - \def\doblocksetups##1{\getparameters[\??tb##1][#4]}% - \ctxlua{structure.blocks.select("#1","#2","#3","\@@tb@@tbcriterium")}}% - \endgroup} - -% hide: save, if [+] also hidden execute -% keep: save and normal execute - -\def\hideblocks{\dotripleempty\dosetblockstate[hide]} -\def\keepblocks{\dotripleempty\dosetblockstate[keep]} - -% use : normal execute unless [-] -% process: hidden execute unless [-] -% select : idem use - -\def\useblocks {\doquadrupleempty\doselectblocks[use]} -\def\processblocks{\doquadrupleempty\doselectblocks[process]} -\def\selectblocks {\doquadrupleempty\doselectblocks[use]} - -\protect \endinput diff --git a/tex/context/base/strc-def.mkiv b/tex/context/base/strc-def.mkiv new file mode 100644 index 000000000..f24ee2023 --- /dev/null +++ b/tex/context/base/strc-def.mkiv @@ -0,0 +1,302 @@ +%D [ file=strc-def, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Definitions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Definitions} + +% \registerctxluafile{strc-def}{1.001} + +\unprotect + +% \def\installparameterhandler#1#2#3#4#5#6#7#8#9{% +% \def#3##1{\csname#5{#1#2}##1\endcsname}% +% \def#4##1{#6{#1#2}##1}% +% % +% \def#5##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#7\csname##1\s!parent\endcsname##2\fi}% +% \def#6##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#8\csname##1\s!parent\endcsname##2\fi}% +% % +% \def#7##1##2{\ifx##1\relax\s!empty\else#5##1##2\fi}% +% \def#8##1##2{\ifx##1\relax \else#6##1##2\fi}% +% % +% \def#9##1##2% style color +% {\edef\fontattributehash {#4##1}% +% \edef\colorattributehash{#4##2}% +% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash ##1\fi +% \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash##2\fi}% +% % +% } + +% \installparameterhandler +% \empty +% \@@framed +% \framedparameter +% \framedparameterhash +% \doframedparameter +% \doframedparameterhash +% \doframedparentparameter +% \doframedparentparameterhash +% \dosetframedattributes + + +% \setupheads + +\setupstructureheads[% + %\c!after=, + %\c!align=, + %\c!aligntitle=, + \c!alternative=\v!normal, + %\c!before=, + %\c!color=, + \c!command=\normalplacehead, + \c!continue=\v!yes, + %\c!coupling=, + %\c!deepnumbercommand=, + %\c!deeptextcommand=, + %\c!default=, + \c!distance=\!!zeropoint, + \c!expansion=\v!no, + %\c!file=, + %\c!footer=, + %\c!grid=, + \c!hang=\v!none, + %\c!header=, + \c!incrementnumber=\v!yes, + \c!indentnext=\v!no, + %\c!label=, + \c!limittext=\v!yes, + \c!margin=\zeropoint, + %\c!margintext=, + \c!number=\v!yes, + \c!numbercolor=\structureheadparameter\c!color, + %\c!numbercommand=, + \c!numberstyle=\structureheadparameter\c!style, + \c!ownnumber=\v!no, + %\c!page=, + \c!placehead=\v!yes, + %\c!prefix=, + \c!previousnumber=\v!yes, + \c!resetnumber=\v!yes, + %\c!section=, + \c!sectionconversionset=\s!default, + \c!sectionnumber=\v!yes, + %\c!sectionsegments=, + \c!sectionseparatorset=\s!default, + \c!sectionset=\v!all, + %\c!sectionstopper=, + %\c!strut=, + %\c!style=, + %\c!text=, + \c!textcolor=\structureheadparameter\c!color, + %\c!textcommand=, + \c!textstyle=\structureheadparameter\c!style, + %\c!tolerance= + ] + +% \setupstructureblock[appendix][sectionconversionset=appendix] +% \setupstructurehead[chapter][sectionconversionset=\structureblockparameter\c!sectionconversionset] % \structureblockparameter] + +\definestructureseparatorset [\s!default] [] [.] +\definestructureconversionset [\s!default] [] [numbers] +\definestructureresetset [\s!default] [] [0] +\definestructureprefixset [\s!default] [section-1,section-2,section-3] [] + +\definestructureprefixset [\v!all] [section-1,section-2,section-3,section-4,section-5,section-6,section-7,section-8] [] + +\definestructureprefixset [\v!part] [section-1] [] +\definestructureprefixset [\v!chapter] [section-2] [] + +\definestructureseparatorset [\v!appendix:\s!default] [] [.] +\definestructureconversionset [\v!appendix:\s!default] [Romannumerals,Characters] [numbers] +\definestructureresetset [\v!appendix:\s!default] [] [0] + +% \definesectionblock + +\definestructureblock [\v!frontpart] [\v!frontmatter] [\c!number=\v!no] +\definestructureblock [\v!bodypart] [\v!bodymatter] [\c!number=\v!yes] +\definestructureblock [\v!appendix] [\v!appendices] [\c!number=\v!yes] +\definestructureblock [\v!backpart] [\v!backmatter] [\c!number=\v!no] + +\setstructureblock [\v!bodypart] % default + +\appendtoks + \setstructureblock [\v!bodypart]% default +\to \everyjob + +% \definesection + +\definestructuresection[\s!section-1] % part +\definestructuresection[\s!section-2] % chapter +\definestructuresection[\s!section-3] % section +\definestructuresection[\s!section-4] % subsection +\definestructuresection[\s!section-5] % subsubsection +\definestructuresection[\s!section-6] % subsubsubsection +\definestructuresection[\s!section-7] % subsubsubsubsection + +% \definehead + +\definestructurehead + [\v!part] + [\c!section=\s!section-1] + +\definestructurehead + [\v!chapter] + [\c!section=\s!section-2] + +\definestructurehead + [\v!section] + [\c!section=\s!section-3] + +\definestructurehead + [\v!subsection] + [\c!section=\s!section-4, + \c!default=\v!section] + +\definestructurehead + [\v!subsubsection] + [\c!section=\s!section-5, + \c!default=\v!subsection] + +\definestructurehead + [\v!subsubsubsection] + [\c!section=\s!section-6, + \c!default=\v!subsubsection] + +\definestructurehead + [\v!subsubsubsubsection] + [\c!section=\s!section-7, + \c!default=\v!subsubsubsection] + +\definestructurehead + [\v!title] + [\c!coupling=\v!chapter, + \c!default=\v!chapter, + \c!incrementnumber=\v!no] + +\definestructurehead + [\v!subject] + [\c!coupling=\v!section, + \c!default=\v!section, + \c!incrementnumber=\v!no] + +\definestructurehead + [\v!subsubject] + [\c!coupling=\v!subsection, + \c!default=\v!subsection, + \c!incrementnumber=\v!no] + +\definestructurehead + [\v!subsubsubject] + [\c!coupling=\v!subsubsection, + \c!default=\v!subsubsection, + \c!incrementnumber=\v!no] + +\definestructurehead + [\v!subsubsubsubject] + [\c!coupling=\v!subsubsubsection, + \c!default=\v!subsubsubsection, + \c!incrementnumber=\v!no] + +\definestructurehead + [\v!subsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsection, + \c!default=\v!subsubsubsubsection, + \c!incrementnumber=\v!no] + +\setupstructurehead + [\v!part] + [\c!placehead=\v!no] + +\setupstructurehead + [\v!chapter] + [\v!appendix\c!label=\v!appendix, + \v!bodypart\c!label=\v!chapter] % bijlageconversie=\Character + +\setupstructurehead + [\v!section] + [\v!appendix\c!label=\v!section, + \v!bodypart\c!label=\v!section] % bijlageconversie=\Character + +\setupstructurehead + [\v!subsection] + [\v!appendix\c!label=\v!subsection, + \v!bodypart\c!label=\v!subsection] % bijlageconversie=\Character + +\setupstructurehead + [\v!subsubsection] + [\v!appendix\c!label=\v!subsubsection, + \v!bodypart\c!label=\v!subsubsection] % bijlageconversie=\Character + +% \setuphead + +\setupstructurehead + [\v!part,\v!chapter] + [%\c!align=, + %\c!indentnext=\v!no, + \c!continue=\v!no, + \c!page=\v!right, + \c!header=, + \c!style=\tfc, + \c!distance=.75em, + \c!before={\blank[2*\v!big]}, + \c!after={\blank[2*\v!big]}] + +\setupstructurehead + [\v!section] + [%\c!align=, + %\c!indentnext=\v!no, + \c!style=\tfa, + \c!distance=.75em, + \c!before={\blank[2*\v!big]}, + \c!after=\blank] + +\setupstructurehead % nieuw + [\v!subsection] + [\c!page=] + +% brrr + +% \definestructurecounter[\v!page][\c!start=1] % todo: setup + +% lists + +\definecombinedlist + [\v!content] + [\v!part, + \v!chapter, + \v!section, + \v!subsection, + \v!subsubsection, + \v!subsubsubsection, + \v!subsubsubsubsection] + [\c!level=\v!subsubsubsubsection, + \c!criterium=\v!local] + +\setuplist + [\v!part] + [\c!before={\blank\page[\v!preference]}, + \c!after=\blank, + \c!label=\v!yes, + \c!distance=1em] + +\setuplist + [\v!chapter] + [\c!before={\blank\page[\v!preference]}, + \c!after=] + +\setuplist [\v!part] [\c!width=0em] +\setuplist [\v!chapter] [\c!width=2em] +\setuplist [\v!section] [\c!width=3em] +\setuplist [\v!subsection] [\c!width=4em] +\setuplist [\v!subsubsection] [\c!width=5em] +\setuplist [\v!subsubsubsection] [\c!width=6em] +\setuplist [\v!subsubsubsubsection] [\c!width=7em] + +\protect \endinput diff --git a/tex/context/base/strc-def.tex b/tex/context/base/strc-def.tex deleted file mode 100644 index f24ee2023..000000000 --- a/tex/context/base/strc-def.tex +++ /dev/null @@ -1,302 +0,0 @@ -%D [ file=strc-def, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Definitions, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Definitions} - -% \registerctxluafile{strc-def}{1.001} - -\unprotect - -% \def\installparameterhandler#1#2#3#4#5#6#7#8#9{% -% \def#3##1{\csname#5{#1#2}##1\endcsname}% -% \def#4##1{#6{#1#2}##1}% -% % -% \def#5##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#7\csname##1\s!parent\endcsname##2\fi}% -% \def#6##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#8\csname##1\s!parent\endcsname##2\fi}% -% % -% \def#7##1##2{\ifx##1\relax\s!empty\else#5##1##2\fi}% -% \def#8##1##2{\ifx##1\relax \else#6##1##2\fi}% -% % -% \def#9##1##2% style color -% {\edef\fontattributehash {#4##1}% -% \edef\colorattributehash{#4##2}% -% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash ##1\fi -% \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash##2\fi}% -% % -% } - -% \installparameterhandler -% \empty -% \@@framed -% \framedparameter -% \framedparameterhash -% \doframedparameter -% \doframedparameterhash -% \doframedparentparameter -% \doframedparentparameterhash -% \dosetframedattributes - - -% \setupheads - -\setupstructureheads[% - %\c!after=, - %\c!align=, - %\c!aligntitle=, - \c!alternative=\v!normal, - %\c!before=, - %\c!color=, - \c!command=\normalplacehead, - \c!continue=\v!yes, - %\c!coupling=, - %\c!deepnumbercommand=, - %\c!deeptextcommand=, - %\c!default=, - \c!distance=\!!zeropoint, - \c!expansion=\v!no, - %\c!file=, - %\c!footer=, - %\c!grid=, - \c!hang=\v!none, - %\c!header=, - \c!incrementnumber=\v!yes, - \c!indentnext=\v!no, - %\c!label=, - \c!limittext=\v!yes, - \c!margin=\zeropoint, - %\c!margintext=, - \c!number=\v!yes, - \c!numbercolor=\structureheadparameter\c!color, - %\c!numbercommand=, - \c!numberstyle=\structureheadparameter\c!style, - \c!ownnumber=\v!no, - %\c!page=, - \c!placehead=\v!yes, - %\c!prefix=, - \c!previousnumber=\v!yes, - \c!resetnumber=\v!yes, - %\c!section=, - \c!sectionconversionset=\s!default, - \c!sectionnumber=\v!yes, - %\c!sectionsegments=, - \c!sectionseparatorset=\s!default, - \c!sectionset=\v!all, - %\c!sectionstopper=, - %\c!strut=, - %\c!style=, - %\c!text=, - \c!textcolor=\structureheadparameter\c!color, - %\c!textcommand=, - \c!textstyle=\structureheadparameter\c!style, - %\c!tolerance= - ] - -% \setupstructureblock[appendix][sectionconversionset=appendix] -% \setupstructurehead[chapter][sectionconversionset=\structureblockparameter\c!sectionconversionset] % \structureblockparameter] - -\definestructureseparatorset [\s!default] [] [.] -\definestructureconversionset [\s!default] [] [numbers] -\definestructureresetset [\s!default] [] [0] -\definestructureprefixset [\s!default] [section-1,section-2,section-3] [] - -\definestructureprefixset [\v!all] [section-1,section-2,section-3,section-4,section-5,section-6,section-7,section-8] [] - -\definestructureprefixset [\v!part] [section-1] [] -\definestructureprefixset [\v!chapter] [section-2] [] - -\definestructureseparatorset [\v!appendix:\s!default] [] [.] -\definestructureconversionset [\v!appendix:\s!default] [Romannumerals,Characters] [numbers] -\definestructureresetset [\v!appendix:\s!default] [] [0] - -% \definesectionblock - -\definestructureblock [\v!frontpart] [\v!frontmatter] [\c!number=\v!no] -\definestructureblock [\v!bodypart] [\v!bodymatter] [\c!number=\v!yes] -\definestructureblock [\v!appendix] [\v!appendices] [\c!number=\v!yes] -\definestructureblock [\v!backpart] [\v!backmatter] [\c!number=\v!no] - -\setstructureblock [\v!bodypart] % default - -\appendtoks - \setstructureblock [\v!bodypart]% default -\to \everyjob - -% \definesection - -\definestructuresection[\s!section-1] % part -\definestructuresection[\s!section-2] % chapter -\definestructuresection[\s!section-3] % section -\definestructuresection[\s!section-4] % subsection -\definestructuresection[\s!section-5] % subsubsection -\definestructuresection[\s!section-6] % subsubsubsection -\definestructuresection[\s!section-7] % subsubsubsubsection - -% \definehead - -\definestructurehead - [\v!part] - [\c!section=\s!section-1] - -\definestructurehead - [\v!chapter] - [\c!section=\s!section-2] - -\definestructurehead - [\v!section] - [\c!section=\s!section-3] - -\definestructurehead - [\v!subsection] - [\c!section=\s!section-4, - \c!default=\v!section] - -\definestructurehead - [\v!subsubsection] - [\c!section=\s!section-5, - \c!default=\v!subsection] - -\definestructurehead - [\v!subsubsubsection] - [\c!section=\s!section-6, - \c!default=\v!subsubsection] - -\definestructurehead - [\v!subsubsubsubsection] - [\c!section=\s!section-7, - \c!default=\v!subsubsubsection] - -\definestructurehead - [\v!title] - [\c!coupling=\v!chapter, - \c!default=\v!chapter, - \c!incrementnumber=\v!no] - -\definestructurehead - [\v!subject] - [\c!coupling=\v!section, - \c!default=\v!section, - \c!incrementnumber=\v!no] - -\definestructurehead - [\v!subsubject] - [\c!coupling=\v!subsection, - \c!default=\v!subsection, - \c!incrementnumber=\v!no] - -\definestructurehead - [\v!subsubsubject] - [\c!coupling=\v!subsubsection, - \c!default=\v!subsubsection, - \c!incrementnumber=\v!no] - -\definestructurehead - [\v!subsubsubsubject] - [\c!coupling=\v!subsubsubsection, - \c!default=\v!subsubsubsection, - \c!incrementnumber=\v!no] - -\definestructurehead - [\v!subsubsubsubsubject] - [\c!coupling=\v!subsubsubsubsection, - \c!default=\v!subsubsubsubsection, - \c!incrementnumber=\v!no] - -\setupstructurehead - [\v!part] - [\c!placehead=\v!no] - -\setupstructurehead - [\v!chapter] - [\v!appendix\c!label=\v!appendix, - \v!bodypart\c!label=\v!chapter] % bijlageconversie=\Character - -\setupstructurehead - [\v!section] - [\v!appendix\c!label=\v!section, - \v!bodypart\c!label=\v!section] % bijlageconversie=\Character - -\setupstructurehead - [\v!subsection] - [\v!appendix\c!label=\v!subsection, - \v!bodypart\c!label=\v!subsection] % bijlageconversie=\Character - -\setupstructurehead - [\v!subsubsection] - [\v!appendix\c!label=\v!subsubsection, - \v!bodypart\c!label=\v!subsubsection] % bijlageconversie=\Character - -% \setuphead - -\setupstructurehead - [\v!part,\v!chapter] - [%\c!align=, - %\c!indentnext=\v!no, - \c!continue=\v!no, - \c!page=\v!right, - \c!header=, - \c!style=\tfc, - \c!distance=.75em, - \c!before={\blank[2*\v!big]}, - \c!after={\blank[2*\v!big]}] - -\setupstructurehead - [\v!section] - [%\c!align=, - %\c!indentnext=\v!no, - \c!style=\tfa, - \c!distance=.75em, - \c!before={\blank[2*\v!big]}, - \c!after=\blank] - -\setupstructurehead % nieuw - [\v!subsection] - [\c!page=] - -% brrr - -% \definestructurecounter[\v!page][\c!start=1] % todo: setup - -% lists - -\definecombinedlist - [\v!content] - [\v!part, - \v!chapter, - \v!section, - \v!subsection, - \v!subsubsection, - \v!subsubsubsection, - \v!subsubsubsubsection] - [\c!level=\v!subsubsubsubsection, - \c!criterium=\v!local] - -\setuplist - [\v!part] - [\c!before={\blank\page[\v!preference]}, - \c!after=\blank, - \c!label=\v!yes, - \c!distance=1em] - -\setuplist - [\v!chapter] - [\c!before={\blank\page[\v!preference]}, - \c!after=] - -\setuplist [\v!part] [\c!width=0em] -\setuplist [\v!chapter] [\c!width=2em] -\setuplist [\v!section] [\c!width=3em] -\setuplist [\v!subsection] [\c!width=4em] -\setuplist [\v!subsubsection] [\c!width=5em] -\setuplist [\v!subsubsubsection] [\c!width=6em] -\setuplist [\v!subsubsubsubsection] [\c!width=7em] - -\protect \endinput diff --git a/tex/context/base/strc-des.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..eb7d7a6bc --- /dev/null +++ b/tex/context/base/strc-des.mkiv @@ -0,0 +1,994 @@ +%D \module +%D [ file=strc-blk, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Descriptions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Descriptions} + +\registerctxluafile{strc-des}{1.001} + +%D In order to be more flexible with theorems Aditya Mahajan added +%D support for titles and endsymbols. At the same time we added more +%D flexible support for inheriting numbers. +%D +%D \startbuffer +%D \defineenumeration[one] +%D \defineenumeration[two] [one] +%D \defineenumeration[three] [number=one,style=slanted] +%D \defineenumeration[four] [three] +%D \defineenumeration[five] [three] [number=five] +%D +%D \startone test test 1 \stopone +%D \starttwo test test 2 \stoptwo +%D \startthree test test 3 \stopthree +%D \startfour test test 4 \stopfour +%D \startfive test test 1 \stopfive +%D \stopbuffer +%D +%D \typebuffer \start \getbuffer \stop + +% list and titles are experimental +% +% \definedescription[test] [location=left,hang=4,headalign={right},distance=1em,list=test] +% \defineenumeration[lemma][title=yes,right=:,textdistance=1em, location=top, titlestyle=\bs,list=lemma] +% \defineenumeration[ammel][title=yes,right=:,textdistance=.5em,location=left,titlestyle=\it,width=9em] +% +% \placelist[enumeration:lemma] +% \placelist[description:test][width=0pt] +% +% \starttest {something something something} \input zapf \stoptest +% \startlemma {with a title of a certain length} \input tufte \stoplemma +% \startammel {with a title} \input zapf \stopammel +% +% \defineenumeration[lemma][...] +% \defineenumeration[titledlemma][lemma][title=yes,right=:,text=lemma,list=lemma] + +\unprotect + +% description parameters + +\def\descriptionparameter #1{\csname\dodescriptionparameter{\??dd\currentdescription }#1\endcsname} +\def\descriptionmainparameter #1{\csname\dodescriptionparameter{\??dd\currentdescriptionmain }#1\endcsname} +\def\descriptionnumberparameter#1{\csname\dodescriptionparameter{\??dd\currentdescriptionnumber}#1\endcsname} + +\def\detokenizeddescriptionparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??dd\currentdescription#1\endcsname}} + +\def\dodescriptionparameter#1#2% + {\ifcsname#1#2\endcsname#1#2\else\expandafter\dodescriptionparentparameter\csname#1\s!parent\endcsname#2\fi} + +\def\dodescriptionparentparameter#1#2% + {\ifx#1\relax\s!empty\else\dodescriptionparameter#1#2\fi} + +% description hashes (needed for style/color) + +\def\descriptionparameterhash #1{\dodescriptionparameterhash{\??dd\currentdescription }#1} +\def\descriptionmainparameterhash#1{\dodescriptionparameterhash{\??dd\currentdescriptionmain}#1} + +\def\dodescriptionparameterhash#1#2% + {\ifcsname#1#2\endcsname#1\else\expandafter\dodescriptionparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dodescriptionparentparameterhash#1#2% + {\ifx#1\relax\else\dodescriptionparameterhash#1#2\fi} + +\def\dosetdescriptionattributes#1#2% style color + {\edef\fontattributehash {\descriptionparameterhash#1}% + \edef\colorattributehash{\descriptionparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +% typesetting code + +\newbox \descriptionheadbox +\newskip \leftdescriptionskip +\newskip \rightdescriptionskip +\newdimen \descriptionsheadwidth % replaces \!!widtha +\newdimen \descriptionsheaddistance % replaces \!!widthb + +\setvalue{@@description\v!left }{\@@descriptionhang\@@descriptionleftpure \@@descriptionlefthang \@@descriptionleftmargin } +\setvalue{@@description\v!right}{\@@descriptionhang\@@descriptionrightpure\@@descriptionrighthang\@@descriptionrightmargin} + +\def\@@descriptionhang#1#2#3% \next still needed? + {\processaction + [\descriptionparameter\c!hang] + [ \v!none=>\let\next#1,% + 0=>\let\next#1,% + \v!margin=>\let\next#3,% + \s!unknown=>\let\next#2,% + \s!default=>\let\next#1]% + \next} + +\def\@@descriptionleftpure + {\def\\{\crlf}% + \noindent + \leftskip\dimexpr\leftdescriptionskip+\descriptionsheadwidth\relax + \rightskip\rightdescriptionskip + \@@makedescriptionpurebox\raggedright + \advance\leftskip\descriptionsheaddistance + \llap + {\hbox to \leftskip + {\hskip\leftdescriptionskip + \copy\descriptionheadbox\hss}}% + \@@dodescription} + +\def\@@descriptionrightpure + {\def\\{\crlf}% + \noindent + \leftskip\leftdescriptionskip + \rightskip\dimexpr\rightdescriptionskip+\descriptionsheadwidth\relax + \@@makedescriptionpurebox\raggedleft + \rlap + {\hskip\dimexpr\hsize-\leftskip-\rightskip\relax + \copy\descriptionheadbox + \hskip\rightdescriptionskip}% + \advance\rightskip \descriptionsheaddistance + \@@dodescription} + +\def\@@descriptionleftmargin + {\def\\{\crlf}% + \noindent + \llap + {\@@makedescriptionpurebox\raggedright + \hbox to \descriptionparameter\c!width{\copy\descriptionheadbox\hss}% + \hskip\descriptionparameter\c!distance}% + \@@dodescription} + +\def\@@descriptionrightmargin % whatever this means + {\def\\{\crlf}% + \noindent + \rlap + {\hskip\descriptionparameter\c!distance + \@@makedescriptionpurebox\raggedright + \hbox to \descriptionparameter\c!width{\copy\descriptionheadbox\hss}}% + \@@dodescription} + +\def\@@makedescriptionpurebox#1% + {\setbox\descriptionheadbox\vtop + {\dontcomplain + \hsize\descriptionsheadwidth + \leftskip\zeropoint + \rightskip\zeropoint + #1\setupalign[\descriptionparameter\c!align]% + \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% + \ht\descriptionheadbox\strutht + \dp\descriptionheadbox\strutdp} + +\def\@@descriptionlefthang + {\def\\{\crlf}% + \dontcomplain + \advance\descriptionsheadwidth \descriptionsheaddistance + \hangindent\descriptionsheadwidth + \@@makedescriptionhangbox\raggedright{\advance\rightskip \descriptionsheaddistance}% + \noindent + \llap + {\dontshowcomposition + \vtop to \zeropoint{\box\descriptionheadbox}}% + \@@dodescription} + +\def\@@descriptionrighthang + {\def\\{\crlf}% + \dontcomplain + \advance\descriptionsheadwidth \descriptionsheaddistance + \hangindent-\descriptionsheadwidth + \@@makedescriptionhangbox\raggedleft{\advance\leftskip \descriptionsheaddistance}% + \noindent + \rlap + {\dontcomplain + \dontshowcomposition + \hbox to \dimexpr\hsize-\leftskip-\rightskip\relax % can be a macro + {\hss\vtop to \zeropoint{\box\descriptionheadbox}}}% + \@@dodescription} + +\def\@@makedescriptionhangbox#1#2% + {\setbox\descriptionheadbox\vtop % \vbox gaat fout in hang + {\forgetall + \dontcomplain + \hsize\descriptionsheadwidth + #1\setupalign[\descriptionparameter\c!align]#2% + \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% + \ht\descriptionheadbox\strutht + \dp\descriptionheadbox\strutdp + \doifsomething{\descriptionparameter\c!hang} + {\doifinsetelse{\descriptionparameter\c!hang}{\v!fit,\v!broad} + {\scratchdimen\htdp\descriptionheadbox + \doif{\descriptionparameter\c!hang}\v!broad + {\advance\scratchdimen .5\strutht}% + \getnoflines\scratchdimen + \hangafter-\noflines} + {\hangafter-\descriptionparameter\c!hang}}} + +\setvalue{@@description\v!top}% + {%\page[\v!preference]% % Weg ermee! + %\dosomebreak{\goodbreak}% % Dit is beter en nodig! + \dohandlepagebreakX\plusone % En dit moet het maar worden. + \let\\=\space + \noindent + \copy\descriptionheadbox\par + \nobreak + %\descriptionparameter\c!inbetween % .. brrrr ... : + \doifelsenothing{\descriptionparameter\c!inbetween}{\blank}{\descriptionparameter\c!inbetween}% + \nobreak + \@@dodescription} + +\def\do@@description#1% + {\def\\{\crlf}% + \noindent + #1{\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% + \@@dodescription} + +\setvalue{@@description\v!inmargin }{\do@@description\inmargin} +\setvalue{@@description\v!inleft }{\do@@description\inleft } +\setvalue{@@description\v!inright }{\do@@description\inright } +\setvalue{@@description\v!margin }{\do@@description\inmargin} +\setvalue{@@description\v!leftmargin }{\do@@description\inleft } +\setvalue{@@description\v!rightmargin }{\do@@description\inright } +\setvalue{@@description\v!innermargin }{\do@@description\ininner } +\setvalue{@@description\v!outermargin }{\do@@description\inouter } + +\setvalue{@@description\v!serried\v!fit}% + {\def\\{\crlf}% + \noindent + \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox + \hskip\descriptionsheaddistance % toegevoegd + \@@dodescription} + +\setvalue{@@description\v!serried\v!broad}% + {\def\\{\crlf}% + \noindent + \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox + \hskip\descriptionsheaddistance \!!plus .5\descriptionsheaddistance \!!minus .25\descriptionsheaddistance + \@@dodescription} + +\setvalue{@@description\v!serried\v!wide}% + {\def\\{\crlf}% + \noindent + \hbox to \descriptionsheadwidth + {\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox\hss}% + \hskip\descriptionsheaddistance + \@@dodescription} + +\setvalue{@@description\v!serried}% + {\processaction + [\descriptionparameter\c!width] + [ \v!fit=>\let\next\v!fit, + \v!broad=>\let\next\v!broad, + \s!unknown=>\let\next\v!wide, + \s!default=>\let\next\v!broad]% + \getvalue{@@description\v!serried\next}} + +\setvalue{@@description\v!hanging}% + {\def\\{\crlf}% + \noindent + \advance\leftskip -\leftskipadaption \relax + \ifdim\leftskipadaption=\zeropoint + \leftskipadaption1.5em\relax % just some default + \ifnum\nesteddescriptionstate=\plusone + \ifdim\leftskip>\zeropoint \relax + \leftskipadaption\leftskip + \fi + \fi + \fi + \ifnum\nesteddescriptionstate>\zerocount % was \ifnum\nesteddescriptionstate=\plusone + \advance\leftskip \leftskipadaption % but we're already further on + \fi + \hskip-\leftskipadaption + \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox + \kern\ifdim\descriptionsheaddistance=\zeropoint .75em\else\descriptionsheaddistance\fi + \@@dodescription} + +%D A bonus definition +%D +%D \starttyping +%D \setupfootnotedefinition[location=command,headcommand=\llap] +%D \stoptyping + +% \setvalue{@@description\v!command}% +% {\do@@description{\executeifdefined{\descriptionparameterhash\c!headcommand}\framed}} + +\setvalue{@@description\v!command}% + {\noindent + \descriptionparameter\c!headcommand{\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% + \@@dodescription} + +%D A new key 'headalign' in definitions. + +\def\resetdescriptions % to be used in e.g. footnotes + {\chardef\nesteddescriptionstate\zerocount} + +\resetdescriptions + +\def\@@dostartdescription + {\descriptionparameter\c!before + \begingroup + \doadaptleftskip{\descriptionparameter\c!margin}% + \showcomposition + \descriptionsheaddistance\descriptionparameter\c!distance\relax + \ifdim\descriptionsheaddistance=\zeropoint\relax + \doif{\descriptionparameter\c!width}\v!broad{\descriptionsheaddistance=1em}% + \fi + \setbox\descriptionheadbox\hbox + {\forgetall\dontcomplain + \trialtypesettingtrue + \doifelsenothing{\descriptionparameter\c!sample} + {\dodescriptionhandler + {\begstrut\descriptionparameter\c!text\ignorespaces\currentdescriptiontext\endstrut}}% + {\dodescriptionhandler + {\begstrut\descriptionparameter\c!text\descriptionparameter\c!sample\endstrut}}}% + \assignwidth + \descriptionsheadwidth + {\descriptionparameter\c!width} + {\unhcopy\descriptionheadbox} + \descriptionsheaddistance + \setbox\descriptionheadbox\hbox + {\forgetall\dontcomplain + \doifelse{\descriptionparameter\c!location}\v!serried % brrr, hack + {\dodescriptionhandler + {\begstrut\descriptionparameter\c!text\currentdescriptiontext\endstrut}} + {\dodescriptionhandler + {\vtop + {\hsize\dimexpr\descriptionsheadwidth-\descriptionsheaddistance\relax + \begstrut\descriptionparameter\c!text\ignorespaces\currentdescriptiontext\endstrut}}}}% + \doifelse{\descriptionparameter\c!aligntitle}\v!no + {\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip} + {\ifcase\nesteddescriptionstate\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip\fi}% + \normalexpanded{\noexpand\indenting[\descriptionparameter\c!indenting]}% + % better a system mode + \ifcase\nesteddescriptionstate + \chardef\nesteddescriptionstate\plusone + \or + \chardef\nesteddescriptionstate\plustwo + \fi % now happens elsewhere : \noindent\ignorespaces + \@@resetdescriptionclosesymbol} + +\def\@@stopdescription + {\@@placedescriptionclosesymbol + \par % else we loose + \endgroup + \descriptionparameter\c!after % which currentdescription is taken here? + \egroup % temporary hack + \checknextindentation[\descriptionparameter\c!indentnext] + \dorechecknextindentation} + +\def\@@dodescription + {\dosetdescriptionattributes\c!style\c!color + \ignorespaces} + +% starters: + +\def\@@startdescription[#1]% + {\doifelse{\descriptionparameter\c!title}\v!yes + {\permitspacesbetweengroups + \dodoublegroupempty{\dohandledescriptionstart[#1]}} + {\dohandledescriptionstart[#1]{}}} + +\def\@@description[#1]% + {\doifelse{\descriptionparameter\c!title}\v!yes + {\permitspacesbetweengroups + \dodoublegroupempty{\dohandledescriptiondo[#1]}} + {\dohandledescriptiondo[#1]{}}} + +% these call: + +\long\def\@@somedescription[#1]#2% + {\dowithpar + {\bgroup % temporary hack + \@@makedescription[#1]{#2}}% + {\@@stopdescription}} + +\long\def\@@startsomedescription[#1]#2% + {\bgroup % temporary hack + \BeforePar{\@@makedescription[#1]{#2}}% + \GotoPar} + +\def\@@dostartdescriptionindeed + {\edef\currentdescriptionlocation{\descriptionparameter\c!location}% + \ifx\currentdescriptionlocation\empty + \let\currentdescriptionlocation\v!left + \fi + \ifcsname @@description\currentdescriptionlocation\endcsname \else + \let\currentdescriptionlocation\v!left + \fi + \@@dostartdescription + \csname @@description\currentdescriptionlocation\endcsname} % args not needed + +\def\@@makedescription[#1]#2% + {\postponenotes % new, assumes grouping + \doenumerationcheckconditions + \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#2},\c!bookmark=,][]% + \@@dostartdescriptionindeed} + +\def\dostartstoreddescription + {\@@dostartdescriptionindeed} + +\def\dostopstoreddescription + {\@@stopdescription} + +% % % % % % % % % % % % + +% helpers + +% todo: \dosetfontattributewithhash \descriptionparameterhash\c!headstyle + +% setup descriptions + +\def\setupdescriptions + {\dodoubleempty\dosetupdescriptions} + +\def\dosetupdescriptions[#1][#2]% % beter: \iffirstargument + {\ifsecondargument + \dodoubleargumentwithset\dodosetupdescriptions[#1][#2]% + \else + \dodosetupdescriptions[][#1]% + \fi} + +\def\dodosetupdescriptions[#1]% [#2]% + {\getparameters[\??dd#1]} % [#2]} + +% define descriptions + +\def\definedescription + {\dotripleemptywithset\dodefinedescription} + +\def\dodefinedescription[#1][#2][#3]% to be simplified cf enumeration + {\dodescriptioninit{#1}% + \getparameters[\??dd#1][\c!text=,\s!handler=\v!description,\c!title=\v!yes]% + \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi + \ifdone + \getparameters[\??dd#1][\s!parent=\??dd,\c!text=,\s!handler=\v!description,#2]% + \dodefinedescriptioncommands{#1}{\??dd}% + \else % clone + \getparameters[\??dd#1][\s!parent=\??dd#2,\c!text=,\s!handler=\v!description,#3]% clone + \dodefinedescriptioncommands{#1}{\??dd#2}% + \fi} + +\def\dodefinedescriptioncommands#1#2% + {\unexpanded\setevalue {#1}{\noexpand\dodescriptioncommand{#1}}% + \unexpanded\setevalue{\e!start#1}{\noexpand\dodescriptionstart {#1}}% + \unexpanded\setevalue{\e!stop #1}{\noexpand\dodescriptionstop {#1}}} + +% handle descriptions + +\def\dodescriptioninit#1% + {\let\currentdescriptionmain \empty + \let\currentdescriptionlevel \empty + \edef\currentdescriptionname {#1}% + \edef\currentdescription {#1}} + +\def\dodescriptioncommand#1{\dodescriptioninit{#1}\dosingleempty\@@description} +\def\dodescriptionstart #1{\dodescriptioninit{#1}\dosingleempty\@@startdescription} +\def\dodescriptionstop #1{\dodescriptioninit{#1}\@@stopdescription} + +\def\dodescriptionhandler {\csname\??dd:\descriptionparameter\s!handler:\s!handler \endcsname} +\def\dohandledescriptiondo {\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!do \endcsname} +\def\dohandledescriptionstart{\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!start\endcsname} + +% implementation + +% beware: with footnotes #2 can be something messy but then #1 is +% empty anyway, so we have an extra safeguard + +\newtoks \everydescription + +\setvalue{\??dd:\v!description:\s!handler }{\@@dodescriptionhandler} +\setvalue{\??dd:\v!description:\s!handler:\s!do }{\@@somedescription} +\setvalue{\??dd:\v!description:\s!handler:\s!start}{\@@startsomedescription} + +\def\@@dodescriptionhandler#1% + {\strut + \dodescriptionheadtext{#1}% + \iftrialtypesetting \else + \currentdescriptionsynchronize + \fi} + +\def\dodescriptionheadtext#1% title + {\begingroup + \dosetdescriptionattributes\c!headstyle\c!headcolor + \the\everydescription + \descriptionparameter\c!command{\strut#1}% probably incomplete + \endgroup} + +% setup enumerations + +\def\setupenumerations + {\dodoubleempty\dosetupenumerations} + +\def\dodosetupenumerations[#1][#2]% + {\doenumerationinit{#1}{1}\empty + \getparameters[\??dd#1][#2]% + \dosetupenumerationcounter{#1}} + +\def\dosetupenumerations[#1][#2]% + {\ifsecondargument + \dodoubleargumentwithset\dodosetupenumerations[#1][#2]% + \else + \getparameters[\??dn][#1]% + \fi} + +% define enumerations + +\def\defineenumeration + {\dotripleemptywithset\dodefineenumeration} + +\def\dodefineenumeration[#1][#2][#3]% #2 or #3 assignment + {\doenumerationinit{#1}{1}\empty + \getparameters[\??dd#1][\c!text=#1,\c!state=\v!start,\s!handler=\v!enumeration,\c!levels=4]% + \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi + \ifdone % independent + \getparameters[\??dd#1][\s!counter=#1,#2]% + \dodefineenumerationcommands{#1}{1}{}{\??dn}% + \let\@@subslevel\empty + \dostepwiserecurse{2}{\descriptionparameter\c!levels}{1} + {\normalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel\v!sub}{\??dd\@@subslevel#1}}% + \edef\@@subslevel{\@@subslevel\v!sub}}% + \else % clone + \getparameters[\??dd#1][\s!counter=#2,#3]% + \let\@@subslevel\empty + \dorecurse{\descriptionparameter\c!levels} + {\noemalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel}{\??dd\@@subslevel#2}}% + \edef\@@subslevel{\@@subslevel\v!sub}}% + \fi + \edef\currentdescriptioncounter{\descriptionparameter\c!number}% + \ifx\currentdescriptioncounter\empty + \ifdone\dodefineenumerationcounter{#1}\fi + \else\ifx\currentdescriptioncounter\v!yes + \ifdone\dodefineenumerationcounter{#1}\fi + \else\ifx\currentdescriptioncounter\v!no + \ifdone\dodefineenumerationcounter{#1}\fi + \else + \letvalue{\??dd#1\s!counter}\currentdescriptioncounter % ? + \doifstructurecounterelse{\currentdescriptioncounter}{}{\dodefineenumerationcounter\currentdescriptioncounter}% + \fi\fi\fi} + +\newtoks\everysetupenumerationcounter +\let\currentenumerationcountername\empty + +\def\dosetupenumerationcounter#1% + {\edef\currentenumerationcountername{#1}% only used in the token list + \edef\currentdiscription{#1}% + \the\everysetupenumerationcounter} + +\appendtoks + \dostructurecountersetup\currentenumerationcountername\descriptionparameter +\to \everysetupenumerationcounter + +\def\dodefineenumerationcounter#1% todo: fast inheritance (was mainparameter + {\definestructurecounter[#1]% + \dosetupenumerationcounter{#1}} + +\def\dodefineenumerationcommands#1#2#3#4% since we use \currentdescription, we need an edef + {\setevalue{\??dd#3#1\s!parent}{#4}% + \unexpanded\setevalue {#3#1}{\noexpand\doenumerationcommand{#1}{#2}{#3}}% + \unexpanded\setevalue{\e!start#3#1}{\noexpand\doenumerationstart {#1}{#2}{#3}}% + \unexpanded\setevalue{\e!stop #3#1}{\noexpand\doenumerationstop {#1}{#2}{#3}}} + +% handle enumeration + +\def\currentdescriptionnumber {\csname\??dd\currentdescriptionmain\s!counter\endcsname}% no edef (yet) +\def\specificdescriptionnumber#1{\csname\??dd#1\s!counter\endcsname}% no edef (yet) + +\def\doenumerationinit#1#2#3% + {\edef\currentdescriptionmain {#1}% + \edef\currentdescriptionlevel{#2}% + \edef\currentdescriptionname {#1}% + \edef\currentdescription {#3#1}} + +\def\doenumerationcommand#1#2#3{\doenumerationinit{#1}{#2}{#3}\dosingleempty\@@description} +\def\doenumerationstart #1#2#3{\doenumerationinit{#1}{#2}{#3}\dosingleempty\@@startdescription} +\def\doenumerationstop #1#2#3{\doenumerationinit{#1}{#2}{#3}\@@stopdescription} + +\def\doresetenumerationnumber#1#2#3{\doresetsubstructurecounter [\specificdescriptionnumber{#1}][#2]} +\def\dosetenumerationnumber#1#2#3#4{\dosetsubstructurecounter [\specificdescriptionnumber{#1}][#2]{#4}} +\def\donextenumerationnumber #1#2#3{\doincrementsubstructurecounter[\specificdescriptionnumber{#1}][#2]} + +% implementation + +\newtoks \everyenumeration +\newconditional\enumerationnumberenabled +\chardef \enumerationcouplingmode \zerocount +\def \enumerationdisablenumbersignal {-} + +\appendtoks \disablepseudocaps \to \everyenumeration % sorry, uppercase causes troubles + +\letvalue{\??dd:\c!couplingway:\v!local }\plusone +\letvalue{\??dd:\c!couplingway:\v!global}\plustwo + +\setvalue{\??dd:\v!enumeration:\s!handler }{\@@doenumerationhandler} +\setvalue{\??dd:\v!enumeration:\s!handler:\s!do }{\@@somedescription} +\setvalue{\??dd:\v!enumeration:\s!handler:\s!start}{\@@startsomedescription} + +\def\@@doenumerationhandler#1% + {\strut + \ifconditional\enumerationnumberenabled + \iftrialtypesetting + \doenumerationfullnumber\showdntext{#1}% + \doenumerationcouplingsymbol + \else + \doenumerationregistercoupling + \doenumerationfullnumber\showdntext{#1}% + \doenumerationcouplingsymbol + \fi + \else + \doenumerationfullnumber\showdnpuretext{#1}% + \fi + \iftrialtypesetting \else + \currentdescriptionsynchronize + \fi} + +\def\doenumerationsavecounter {\savestructurecounter[\currentdescriptionnumber]} +\def\doenumerationrestorecounter {\restorestructurecounter[\currentdescriptionnumber]} +\def\doenumerationincrementcounter{\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} + +\def\doenumerationcheckconditions + {\doifelse{\descriptionparameter\c!number}\v!yes + {\ifx\currentdescriptionreference\enumerationdisablenumbersignal + \setfalse\enumerationnumberenabled \else \settrue\enumerationnumberenabled + \fi}% + {\setfalse\enumerationnumberenabled}% + \chardef\enumerationcouplingmode \iflocation + \executeifdefined{\??dd:\c!couplingway:\descriptionparameter\c!coupling}\zerocount + \else + \zerocount + \fi} + +\def\doenumerationregistercoupling + {\iflocation + \ifcase\enumerationcouplingmode + \or + % todo + \or + % todo + \fi + \fi} + +\def\doenumerationcouplingsymbol + {\iflocation\ifcase\enumerationcouplingmode \else + % todo + \fi\fi} + +\def\currentdescriptiontext + {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} + +\def\currentenumerationfullnumber + {\ctxlua{structure.lists.savednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} + +\def\doenumerationfullnumber#1#2% text, title + {\begingroup + \dosetdescriptionattributes\c!headstyle\c!headcolor + \the\everyenumeration + \descriptionparameter\c!command + {\strut + #1% + \descriptionparameter\c!left + \currentenumerationfullnumber + % save cq. treat expansion etc + \doifsomething{#2} + {\doif{\descriptionparameter\c!title}\v!yes + {\begingroup + \dosetdescriptionattributes\c!titlestyle\c!titlecolor + \hskip\descriptionparameter\c!titledistance + \descriptionparameter\c!titlecommand + {\descriptionparameter\c!titleleft + \begstrut#2\endstrut + \descriptionparameter\c!titleright}% + \endgroup}}% + % + \descriptionparameter\c!stopper + \descriptionparameter\c!right}% + \endgroup} + +\def\showdnpuretext{\strut\descriptionparameter\c!text} % geen spatie +\def\showdnlisttext{\descriptionparameter\c!listtext} % space in default +\def\showdntext {\doifsomething{\descriptionparameter\c!text}{\descriptionparameter\c!text\removeunwantedspaces\fixedspace}} + +\unexpanded\def\structurecounterreference#1% + {[enumref: #1]} + +% you can use \placeclosesymbol or \qed to place a symbol at the end of a +% description + +\def\@@resetdescriptionclosesymbol + {\global\@EA\settrue\csname\??dd\currentdescription:mrk\endcsname + \let\placeclosesymbol\@@placedescriptionclosesymbol + \let\qed \@@placedescriptionclosesymbol} + +\def\@@placedescriptionclosesymbol + {\ifconditional\csname\??dd\currentdescription:mrk\endcsname + \global\@EA\setfalse\csname\??dd\currentdescription:mrk\endcsname + \doifsomething{\descriptionparameter\c!closesymbol}{\descriptionparameter\c!closecommand{\descriptionparameter\c!closesymbol}}% + \fi} + +\newif\ifnodescriptioncaption + +\def\doifelsedescriptioncomponent + {\ctxlua{structure.lists.doifstoredelse(currentdescriptionnumberentry)}} + +\def\dodescriptioncomponent + {\doifelsedescriptioncomponent\nododescriptioncomponent\dododescriptioncomponent} + +\def\nododescriptioncomponent[#1][#2]% #1=interfaced-settings, #2=optional user data + {} + +\def\dododescriptioncomponent[#1][#2]% #1=interfaced-settings, #2=optional user data + {\begingroup % similar to structure so we might generalize this + \getparameters[\??dd\currentdescription][#1]% + \edef\currentdescriptionexpansion{\descriptionparameter\c!expansion}% + \ifx\currentdescriptionexpansion\s!xml + \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}% + \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}% + \xmlstartraw + \xdef\currentdescriptionlisttitle {\descriptionparameter\c!title}% + \xmlstopraw + \globallet\currentdescriptioncoding\s!xml + \else + \ifx\currentdescriptionexpansion\v!yes + \xdef\currentdescriptiontitle {\descriptionparameter\c!title}% + \xdef\currentdescriptionbookmark{\descriptionparameter\c!bookmark}% + \else + \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}% + \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}% + \fi + \globallet\currentdescriptionlisttitle \currentdescriptiontitle + \globallet\currentdescriptioncoding\s!tex + \fi + \xdef\currentdescriptionlabel {\descriptionparameter\c!label}% + \xdef\currentdescriptionreference {\descriptionparameter\c!reference}% + % + \doif{\descriptionparameter\c!title}\v!none{\global\nodescriptioncaptiontrue\global\nodescriptionnumbertrue}% will become obsolete + % + \ifconditional\enumerationnumberenabled + \doifelsedescriptioncomponent\donothing\doenumerationincrementcounter + \fi + % + \ifnodescriptioncaption + \glet\currentdescriptionlistnumber \relax + \glet\currentdescriptionsynchronize\relax + \else + \setnextinternalreference + \xdef\currentdescriptionnumberentry{\ctxlua{structure.lists.push{ + metadata = { + kind = "description", + name = "\currentdescriptionname", + level = structure.sections.currentlevel(), + catcodes = \the\catcodetable, + }, + references = { + internal = \nextinternalreference, + reference = "\currentdescriptionreference", + referenceprefix = "\referenceprefix", + block = "\currentstructureblock", + section = structure.sections.currentid(), + }, + titledata = { + label = \!!bs\detokenize\expandafter{\currentdescriptionlabel }\!!es, + title = \!!bs\detokenize\expandafter{\currentdescriptiontitle }\!!es, + \ifx\currentdescriptionbookmark\currentdescriptiontitle \else + bookmark = \!!bs\detokenize\expandafter{\currentdescriptionbookmark}\!!es, + \fi + \ifx\currentdescriptionlisttitle\currentdescriptiontitle \else % \ifx\currentdescriptionsaveinlist\v!no + list = \!!bs\detokenize\expandafter{\currentdescriptionlisttitle }\!!es, + \fi % \fi + }, + \ifconditional\enumerationnumberenabled + prefixdata = { + prefix = "\descriptionparameter\c!prefix", + separatorset = "\descriptionparameter\c!prefixseparatorset", + conversion = \!!bs\descriptionparameter\c!prefixconversion\!!es, + conversionset = "\descriptionparameter\c!prefixconversionset", + set = "\descriptionparameter\c!prefixset", + segments = "\descriptionparameter\c!prefixsegments", + connector = \!!bs\descriptionparameter\c!prefixconnector\!!es, + }, + numberdata = { + numbers = structure.counters.compact("\currentdescriptionname",nil,true), + separatorset = "\descriptionparameter\c!numberseparatorset", + conversion = "\descriptionparameter\c!numberconversion", + conversionset = "\descriptionparameter\c!numberconversionset", + stopper = \!!bs\descriptionparameter\c!numberstopper\!!es, + segments = "\descriptionparameter\c!numbersegments", + }, + \fi + userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) + } + }}% + \xdef\currentdescriptionsynchronize % make this a macro because shared + {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% + \noexpand\ctxlatelua{structure.lists.enhance(\currentdescriptionnumberentry)}}% + \fi + \endgroup} + +\installstructurelistprocessor{description}{\usestructurelistprocessor{number+title}} + +% labels, we could share with enumerations and forget about the text; anyhow, figure +% labels etc can use enumerations; we keep labels for compatibility reasons; we need +% the slightly different namespace; we can still define structure counters directly +% (multiple levels) and use an enumeration without following text + +% unfinished + +\def\setuplabels + {\getparameters[\??db]} + +\def\definelabel + {\dotripleargumentwithset\dodefinelabel} + +\def\dodefinelabel[#1][#2][#3]% #2 or #3 assignment + {\doenumerationinit{#1}{1}\empty + \getparameters[\??dd#1][\c!command=,\c!state=\v!start,\c!location=,\c!text=#1]% + \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi + \ifdone + % an independent one + \getparameters[\??dd#1][\s!counter=#1,\s!parent=\??db,#2]% + \dodefinelabelcommands{#1}{\??db}% + \dodefineenumerationcounter{#1}% + \else + \getparameters[\??dd#1][\s!counter=#1,\s!parent=\??dd#2,#3]% + \dodefinelabelcommands{#1}{\??dd#2}% + \fi} + +\def\dodefinelabelcommands#1#2% + {\unexpanded\setevalue {#1}{\noexpand\dolabelnumbercommand {#1}}% + \unexpanded\setevalue{\c!reset #1}{\noexpand\doresetlabelnumber {#1}}% + %\unexpanded\setevalue{\c!set #1}{\noexpand\dosetlabelnumber {#1}}% [#2] or {#2} ? + \unexpanded\setevalue{\e!next #1}{\noexpand\donextlabelnumber {#1}}% + \unexpanded\setevalue{\e!increment#1}{\noexpand\doincrementlabelnumber{#1}}% + \unexpanded\setevalue{\c!current #1}{\noexpand\docurrentlabelnumber {#1}}} + +% this is just for downward compatibility, we might drop it + +\setvalue{\??db:\c!location:\v!inmargin}{\inmargin} +\setvalue{\??db:\c!location:\v!inleft }{\inleft} +\setvalue{\??db:\c!location:\v!inright }{\inright} +\setvalue{\??db:\c!location:\v!margin }{\inmargin} + +\def\dolabelinit#1% + {\def\currentdescriptionmain{#1}% + \def\currentdescription {#1}% + \def\currentdescriptionlevel{1}} + +\def\docurrentlabelnumber #1{\dolabelinit{#1}\dosingleempty\dodocurrentlabelnumber} +\def\donextlabelnumber #1{\dolabelinit{#1}\dosingleempty\dodonextlabelnumber} +\def\dolabelnumbercommand #1{\dolabelinit{#1}\dosingleempty\dodolabelnumbercommand} + +\def\doresetlabelnumber #1{\dolabelinit{#1}\doresetsubstructurecounter [\currentdescriptionnumber][\currentdescriptionlevel]} +\def\dosetlabelnumber #1#2{\dolabelinit{#1}\dosetsubstructurecounter [\currentdescriptionnumber][\currentdescriptionlevel]{#2}} +\def\doincrementlabelnumber #1{\dolabelinit{#1}\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} + +\def\dodocurrentlabelnumber[#1]% + {\dontleavehmode + \writestatus{!!!}{todo: reference of label}% +% \rawreference{lab}{#1}{\composedsectionnumber}% + \dotextprefix{\descriptionparameter\c!text}% + \convertedsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} + +\def\dodonextlabelnumber[#1]% todo: ref + {\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]% + \dodocurrentlabelnumber[\currentdescriptionnumber]} + +\def\dodolabelnumbercommand[#1]% todo: ref + {\dontleavehmode + \descriptionparameter\c!before + \begingroup + \doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]% + \dosetdescriptionattributes\c!headstyle\c!headcolor + \executeifdefined{\??db:\c!location:\descriptionparameter\c!location}{\descriptionparameter\c!command}{\dodocurrentlabelnumber[#1]}% + \endgroup + \descriptionparameter\c!after} + +% to be reimplmented + +\def\setupindentations + {\dodoubleempty\dosetupindentations} + +\def\dosetupindentations[#1][#2]% + {\ifsecondargument + \dodoubleargumentwithset\dodosetupindentations[#1][#2]% + \else + \dodosetupindentations[][#1]% + \fi} + +\def\dodosetupindentations[#1][#2]% + {\getparameters[\??ds#1][#2]} + +\def\defineindenting + {\dodoubleargumentwithset\dodefineindenting} + +\def\dodefineindenting[#1][#2]% + {\copyparameters[\??ds#1][\??ds] + [\c!text,\c!separator,\c!width,\c!style,\c!color, + \c!headstyle,\c!sample,\c!before,\c!after,\c!distance]% + \getparameters[\??ds#1][#2]% + \unexpanded\setvalue {#1}{\dododefineindenting{#1}{0}{1}}% + \unexpanded\setvalue {\v!sub#1}{\dododefineindenting{#1}{1}{2}}% + \unexpanded\setvalue{\v!sub\v!sub#1}{\dododefineindenting{#1}{2}{3}}} + +\def\dododefineindenting#1#2#3% + {\par + \getvalue{\??ds#1\c!before}% + \begingroup + \doifvaluenothing{\??ds#1\c!sample} + {\setvalue{\??ds#1\c!sample}{\getvalue{\??ds#1\c!text}}}% + \assignwidth + {\descriptionsheadwidth} + {\getvalue{\??ds#1\c!width}} + {\doattributes + {\??ds#1}\c!headstyle\c!headcolor + {\getvalue{\??ds#1\c!sample}% + \spr{\getvalue{\??ds#1\c!separator}}}} + {\getvalue{\??ds#1\c!distance}}% + \advance\descriptionsheadwidth \getvalue{\??ds#1\c!distance}% + \setbox\scratchbox\hbox to \descriptionsheadwidth + {\doattributes + {\??ds#1}\c!headstyle\c!headcolor + {\strut + \getvalue{\??ds#1\c!text}% + \hss + \spr{\getvalue{\??ds#1\c!separator}}% + \hskip\getvalue{\??ds#1\c!distance}}}% + \parindent\zeropoint + \hskip#2\descriptionsheadwidth\indent\box\scratchbox + \hangindent#3\descriptionsheadwidth + \doattributes{\??ds#1}\c!style\c!color\empty + \AfterPar{\endgroup\getvalue{\??ds#1\c!after}}% must be redone + \GetPar} + +\setupdescriptions + [\c!location=\v!left, + \c!headstyle=\v!bold, + \c!titlestyle=\v!bold, + \c!style=\v!normal, + \c!color=, + \c!headcolor=, + \c!titlecolor=, + \c!width=8em, + \c!distance=0pt, + \c!titledistance=0.5em, + \c!hang=, + \c!sample=, + \c!align=, + \c!margin=\v!no, + \c!before=\blank, + \c!inbetween=\blank, + \c!after=\blank, + \c!indentnext=\v!yes, + \c!indenting=\v!never, + \c!titleleft=(, + \c!titleright=), + \c!closesymbol=, + \c!closecommand=\wordright, + \c!command=, + \c!titlecommand=] + +\setupenumerations + [\c!location=\v!top, + \c!text=, + \c!way=\v!by\v!text, + \c!prefixconnector=., + \c!stopper=, + \c!number=\v!yes, % else description + \c!start=0, + \s!parent=\??dd] + +\setuplabels + [\s!parent=\??dn] + +\setupindentations + [\c!style=\v!normal, + \c!headstyle=\v!normal, + \c!color=, + \c!headcolor=, + \c!width=\v!fit, + \c!text=\unknown, + \c!sample=, + \c!before=\blank, + \c!after=\blank, + \c!distance=1em, + \c!separator={ :}] + +\protect \endinput diff --git a/tex/context/base/strc-des.tex b/tex/context/base/strc-des.tex deleted file mode 100644 index 1b196974a..000000000 --- a/tex/context/base/strc-des.tex +++ /dev/null @@ -1,1018 +0,0 @@ -%D \module -%D [ file=strc-blk, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Descriptions, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Descriptions} - -\registerctxluafile{strc-des}{1.001} - -%D In order to be more flexible with theorems Aditya Mahajan added -%D support for titles and endsymbols. At the same time we added more -%D flexible support for inheriting numbers. -%D -%D \startbuffer -%D \defineenumeration[one] -%D \defineenumeration[two] [one] -%D \defineenumeration[three] [number=one,style=slanted] -%D \defineenumeration[four] [three] -%D \defineenumeration[five] [three] [number=five] -%D -%D \startone test test 1 \stopone -%D \starttwo test test 2 \stoptwo -%D \startthree test test 3 \stopthree -%D \startfour test test 4 \stopfour -%D \startfive test test 1 \stopfive -%D \stopbuffer -%D -%D \typebuffer \start \getbuffer \stop - -% list and titles are experimental -% -% \definedescription[test] [location=left,hang=4,headalign={right},distance=1em,list=test] -% \defineenumeration[lemma][title=yes,right=:,textdistance=1em, location=top, titlestyle=\bs,list=lemma] -% \defineenumeration[ammel][title=yes,right=:,textdistance=.5em,location=left,titlestyle=\it,width=9em] -% -% \placelist[enumeration:lemma] -% \placelist[description:test][width=0pt] -% -% \starttest {something something something} \input zapf \stoptest -% \startlemma {with a title of a certain length} \input tufte \stoplemma -% \startammel {with a title} \input zapf \stopammel -% -% \defineenumeration[lemma][...] -% \defineenumeration[titledlemma][lemma][title=yes,right=:,text=lemma,list=lemma] - -\unprotect - -% description parameters - -\def\descriptionparameter #1{\csname\dodescriptionparameter{\??dd\currentdescription }#1\endcsname} -\def\descriptionmainparameter #1{\csname\dodescriptionparameter{\??dd\currentdescriptionmain }#1\endcsname} -\def\descriptionnumberparameter#1{\csname\dodescriptionparameter{\??dd\currentdescriptionnumber}#1\endcsname} - -\def\detokenizeddescriptionparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??dd\currentdescription#1\endcsname}} - -\def\dodescriptionparameter#1#2% - {\ifcsname#1#2\endcsname#1#2\else\expandafter\dodescriptionparentparameter\csname#1\s!parent\endcsname#2\fi} - -\def\dodescriptionparentparameter#1#2% - {\ifx#1\relax\s!empty\else\dodescriptionparameter#1#2\fi} - -% description hashes (needed for style/color) - -\def\descriptionparameterhash #1{\dodescriptionparameterhash{\??dd\currentdescription }#1} -\def\descriptionmainparameterhash#1{\dodescriptionparameterhash{\??dd\currentdescriptionmain}#1} - -\def\dodescriptionparameterhash#1#2% - {\ifcsname#1#2\endcsname#1\else\expandafter\dodescriptionparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dodescriptionparentparameterhash#1#2% - {\ifx#1\relax\else\dodescriptionparameterhash#1#2\fi} - -\def\dosetdescriptionattributes#1#2% style color - {\edef\fontattributehash {\descriptionparameterhash#1}% - \edef\colorattributehash{\descriptionparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -% typesetting code - -\newbox \descriptionheadbox -\newskip \leftdescriptionskip -\newskip \rightdescriptionskip -\newdimen \descriptionsheadwidth % replaces \!!widtha -\newdimen \descriptionsheaddistance % replaces \!!widthb - -\setvalue{@@description\v!left }{\@@descriptionhang\@@descriptionleftpure \@@descriptionlefthang \@@descriptionleftmargin } -\setvalue{@@description\v!right}{\@@descriptionhang\@@descriptionrightpure\@@descriptionrighthang\@@descriptionrightmargin} - -\def\@@descriptionhang#1#2#3% \next still needed? - {\processaction - [\descriptionparameter\c!hang] - [ \v!none=>\let\next#1,% - 0=>\let\next#1,% - \v!margin=>\let\next#3,% - \s!unknown=>\let\next#2,% - \s!default=>\let\next#1]% - \next} - -\def\@@descriptionleftpure - {\def\\{\crlf}% - \noindent - \leftskip\dimexpr\leftdescriptionskip+\descriptionsheadwidth\relax - \rightskip\rightdescriptionskip - \@@makedescriptionpurebox\raggedright - \advance\leftskip\descriptionsheaddistance - \llap - {\hbox to \leftskip - {\hskip\leftdescriptionskip - \copy\descriptionheadbox\hss}}% - \@@dodescription} - -\def\@@descriptionrightpure - {\def\\{\crlf}% - \noindent - \leftskip\leftdescriptionskip - \rightskip\dimexpr\rightdescriptionskip+\descriptionsheadwidth\relax - \@@makedescriptionpurebox\raggedleft - \rlap - {\hskip\dimexpr\hsize-\leftskip-\rightskip\relax - \copy\descriptionheadbox - \hskip\rightdescriptionskip}% - \advance\rightskip \descriptionsheaddistance - \@@dodescription} - -\def\@@descriptionleftmargin - {\def\\{\crlf}% - \noindent - \llap - {\@@makedescriptionpurebox\raggedright - \hbox to \descriptionparameter\c!width{\copy\descriptionheadbox\hss}% - \hskip\descriptionparameter\c!distance}% - \@@dodescription} - -\def\@@descriptionrightmargin % whatever this means - {\def\\{\crlf}% - \noindent - \rlap - {\hskip\descriptionparameter\c!distance - \@@makedescriptionpurebox\raggedright - \hbox to \descriptionparameter\c!width{\copy\descriptionheadbox\hss}}% - \@@dodescription} - -\def\@@makedescriptionpurebox#1% - {\setbox\descriptionheadbox\vtop - {\dontcomplain - \hsize\descriptionsheadwidth - \leftskip\zeropoint - \rightskip\zeropoint - #1\setupalign[\descriptionparameter\c!align]% - \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% - \ht\descriptionheadbox\strutht - \dp\descriptionheadbox\strutdp} - -\def\@@descriptionlefthang - {\def\\{\crlf}% - \dontcomplain - \advance\descriptionsheadwidth \descriptionsheaddistance - \hangindent\descriptionsheadwidth - \@@makedescriptionhangbox\raggedright{\advance\rightskip \descriptionsheaddistance}% - \noindent - \llap - {\dontshowcomposition - \vtop to \zeropoint{\box\descriptionheadbox}}% - \@@dodescription} - -\def\@@descriptionrighthang - {\def\\{\crlf}% - \dontcomplain - \advance\descriptionsheadwidth \descriptionsheaddistance - \hangindent-\descriptionsheadwidth - \@@makedescriptionhangbox\raggedleft{\advance\leftskip \descriptionsheaddistance}% - \noindent - \rlap - {\dontcomplain - \dontshowcomposition - \hbox to \dimexpr\hsize-\leftskip-\rightskip\relax % can be a macro - {\hss\vtop to \zeropoint{\box\descriptionheadbox}}}% - \@@dodescription} - -\def\@@makedescriptionhangbox#1#2% - {\setbox\descriptionheadbox\vtop % \vbox gaat fout in hang - {\forgetall - \dontcomplain - \hsize\descriptionsheadwidth - #1\setupalign[\descriptionparameter\c!align]#2% - \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% - \ht\descriptionheadbox\strutht - \dp\descriptionheadbox\strutdp - \doifsomething{\descriptionparameter\c!hang} - {\doifinsetelse{\descriptionparameter\c!hang}{\v!fit,\v!broad} - {\scratchdimen\htdp\descriptionheadbox - \doif{\descriptionparameter\c!hang}\v!broad - {\advance\scratchdimen .5\strutht}% - \getnoflines\scratchdimen - \hangafter-\noflines} - {\hangafter-\descriptionparameter\c!hang}}} - -\setvalue{@@description\v!top}% - {%\page[\v!preference]% % Weg ermee! - %\dosomebreak{\goodbreak}% % Dit is beter en nodig! - \dohandlepagebreakX\plusone % En dit moet het maar worden. - \let\\=\space - \noindent - \copy\descriptionheadbox\par - \nobreak - %\descriptionparameter\c!inbetween % .. brrrr ... : - \doifelsenothing{\descriptionparameter\c!inbetween}{\blank}{\descriptionparameter\c!inbetween}% - \nobreak - \@@dodescription} - -\def\do@@description#1% - {\def\\{\crlf}% - \noindent - #1{\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% - \@@dodescription} - -\setvalue{@@description\v!inmargin }{\do@@description\inmargin} -\setvalue{@@description\v!inleft }{\do@@description\inleft } -\setvalue{@@description\v!inright }{\do@@description\inright } -\setvalue{@@description\v!margin }{\do@@description\inmargin} -\setvalue{@@description\v!leftmargin }{\do@@description\inleft } -\setvalue{@@description\v!rightmargin }{\do@@description\inright } -\setvalue{@@description\v!innermargin }{\do@@description\ininner } -\setvalue{@@description\v!outermargin }{\do@@description\inouter } - -\setvalue{@@description\v!serried\v!fit}% - {\def\\{\crlf}% - \noindent - \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox - \hskip\descriptionsheaddistance % toegevoegd - \@@dodescription} - -\setvalue{@@description\v!serried\v!broad}% - {\def\\{\crlf}% - \noindent - \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox - \hskip\descriptionsheaddistance \!!plus .5\descriptionsheaddistance \!!minus .25\descriptionsheaddistance - \@@dodescription} - -\setvalue{@@description\v!serried\v!wide}% - {\def\\{\crlf}% - \noindent - \hbox to \descriptionsheadwidth - {\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox\hss}% - \hskip\descriptionsheaddistance - \@@dodescription} - -\setvalue{@@description\v!serried}% - {\processaction - [\descriptionparameter\c!width] - [ \v!fit=>\let\next\v!fit, - \v!broad=>\let\next\v!broad, - \s!unknown=>\let\next\v!wide, - \s!default=>\let\next\v!broad]% - \getvalue{@@description\v!serried\next}} - -\setvalue{@@description\v!hanging}% - {\def\\{\crlf}% - \noindent - \advance\leftskip -\leftskipadaption \relax - \ifdim\leftskipadaption=\zeropoint - \leftskipadaption1.5em\relax % just some default - \ifnum\nesteddescriptionstate=\plusone - \ifdim\leftskip>\zeropoint \relax - \leftskipadaption\leftskip - \fi - \fi - \fi - \ifnum\nesteddescriptionstate>\zerocount % was \ifnum\nesteddescriptionstate=\plusone - \advance\leftskip \leftskipadaption % but we're already further on - \fi - \hskip-\leftskipadaption - \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox - \kern\ifdim\descriptionsheaddistance=\zeropoint .75em\else\descriptionsheaddistance\fi - \@@dodescription} - -%D A bonus definition -%D -%D \starttyping -%D \setupfootnotedefinition[location=command,headcommand=\llap] -%D \stoptyping - -% \setvalue{@@description\v!command}% -% {\do@@description{\executeifdefined{\descriptionparameterhash\c!headcommand}\framed}} - -\setvalue{@@description\v!command}% - {\noindent - \descriptionparameter\c!headcommand{\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}% - \@@dodescription} - -%D A new key 'headalign' in definitions. - -\def\resetdescriptions % to be used in e.g. footnotes - {\chardef\nesteddescriptionstate\zerocount} - -\resetdescriptions - -\def\@@dostartdescription - {\descriptionparameter\c!before - \begingroup - \doadaptleftskip{\descriptionparameter\c!margin}% - \showcomposition - \descriptionsheaddistance\descriptionparameter\c!distance\relax - \ifdim\descriptionsheaddistance=\zeropoint\relax - \doif{\descriptionparameter\c!width}\v!broad{\descriptionsheaddistance=1em}% - \fi - \setbox\descriptionheadbox\hbox - {\forgetall\dontcomplain - \trialtypesettingtrue - \doifelsenothing{\descriptionparameter\c!sample} - {\dodescriptionhandler - {\begstrut\descriptionparameter\c!text\ignorespaces\currentdescriptiontext\endstrut}}% - {\dodescriptionhandler - {\begstrut\descriptionparameter\c!text\descriptionparameter\c!sample\endstrut}}}% - \assignwidth - \descriptionsheadwidth - {\descriptionparameter\c!width} - {\unhcopy\descriptionheadbox} - \descriptionsheaddistance - \setbox\descriptionheadbox\hbox - {\forgetall\dontcomplain - \doifelse{\descriptionparameter\c!location}\v!serried % brrr, hack - {\dodescriptionhandler - {\begstrut\descriptionparameter\c!text\currentdescriptiontext\endstrut}} - {\dodescriptionhandler - {\vtop - {\hsize\dimexpr\descriptionsheadwidth-\descriptionsheaddistance\relax - \begstrut\descriptionparameter\c!text\ignorespaces\currentdescriptiontext\endstrut}}}}% - \doifelse{\descriptionparameter\c!aligntitle}\v!no - {\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip} - {\ifcase\nesteddescriptionstate\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip\fi}% - \normalexpanded{\noexpand\indenting[\descriptionparameter\c!indenting]}% - % better a system mode - \ifcase\nesteddescriptionstate - \chardef\nesteddescriptionstate\plusone - \or - \chardef\nesteddescriptionstate\plustwo - \fi % now happens elsewhere : \noindent\ignorespaces - \@@resetdescriptionclosesymbol} - -\def\@@stopdescription - {\@@placedescriptionclosesymbol - \par % else we loose - \endgroup - \descriptionparameter\c!after % which currentdescription is taken here? - \egroup % temporary hack - \checknextindentation[\descriptionparameter\c!indentnext] - \dorechecknextindentation} - -\def\@@dodescription - {\dosetdescriptionattributes\c!style\c!color - \ignorespaces} - -% starters: - -\def\@@startdescription[#1]% - {\doifelse{\descriptionparameter\c!title}\v!yes - {\permitspacesbetweengroups - \dodoublegroupempty{\dohandledescriptionstart[#1]}} - {\dohandledescriptionstart[#1]{}}} - -\def\@@description[#1]% - {\doifelse{\descriptionparameter\c!title}\v!yes - {\permitspacesbetweengroups - \dodoublegroupempty{\dohandledescriptiondo[#1]}} - {\dohandledescriptiondo[#1]{}}} - -% these call: - -\long\def\@@somedescription[#1]#2% - {\dowithpar - {\bgroup % temporary hack - \@@makedescription[#1]{#2}}% - {\@@stopdescription}} - -\long\def\@@startsomedescription[#1]#2% - {\bgroup % temporary hack - \BeforePar{\@@makedescription[#1]{#2}}% - \GotoPar} - -\def\@@dostartdescriptionindeed - {\edef\currentdescriptionlocation{\descriptionparameter\c!location}% - \ifx\currentdescriptionlocation\empty - \let\currentdescriptionlocation\v!left - \fi - \ifcsname @@description\currentdescriptionlocation\endcsname \else - \let\currentdescriptionlocation\v!left - \fi - \@@dostartdescription - \csname @@description\currentdescriptionlocation\endcsname} % args not needed - -\def\@@makedescription[#1]#2% - {\postponenotes % new, assumes grouping - \doenumerationcheckconditions - \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#2},\c!bookmark=,][]% - \@@dostartdescriptionindeed} - -\def\dostartstoreddescription - {\@@dostartdescriptionindeed} - -\def\dostopstoreddescription - {\@@stopdescription} - -% % % % % % % % % % % % - -% helpers - -% todo: \dosetfontattributewithhash \descriptionparameterhash\c!headstyle - -% setup descriptions - -\def\setupdescriptions - {\dodoubleempty\dosetupdescriptions} - -\def\dosetupdescriptions[#1][#2]% % beter: \iffirstargument - {\ifsecondargument - \dodoubleargumentwithset\dodosetupdescriptions[#1][#2]% - \else - \dodosetupdescriptions[][#1]% - \fi} - -\def\dodosetupdescriptions[#1]% [#2]% - {\getparameters[\??dd#1]} % [#2]} - -% define descriptions - -\def\definedescription - {\dotripleemptywithset\dodefinedescription} - -\def\dodefinedescription[#1][#2][#3]% to be simplified cf enumeration - {\dodescriptioninit{#1}% - \getparameters[\??dd#1][\c!text=,\s!handler=\v!description,\c!title=\v!yes]% - \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi - \ifdone - \getparameters[\??dd#1][\s!parent=\??dd,\c!text=,\s!handler=\v!description,#2]% - \dodefinedescriptioncommands{#1}{\??dd}% - \else % clone - \getparameters[\??dd#1][\s!parent=\??dd#2,\c!text=,\s!handler=\v!description,#3]% clone - \dodefinedescriptioncommands{#1}{\??dd#2}% - \fi} - -\def\dodefinedescriptioncommands#1#2% - {\unexpanded\setevalue {#1}{\noexpand\dodescriptioncommand{#1}}% - \unexpanded\setevalue{\e!start#1}{\noexpand\dodescriptionstart {#1}}% - \unexpanded\setevalue{\e!stop #1}{\noexpand\dodescriptionstop {#1}}} - -% handle descriptions - -\def\dodescriptioninit#1% - {\let\currentdescriptionmain \empty - \let\currentdescriptionlevel \empty - \edef\currentdescriptionname {#1}% - \edef\currentdescription {#1}} - -\def\dodescriptioncommand#1{\dodescriptioninit{#1}\dosingleempty\@@description} -\def\dodescriptionstart #1{\dodescriptioninit{#1}\dosingleempty\@@startdescription} -\def\dodescriptionstop #1{\dodescriptioninit{#1}\@@stopdescription} - -\def\dodescriptionhandler {\csname\??dd:\descriptionparameter\s!handler:\s!handler \endcsname} -\def\dohandledescriptiondo {\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!do \endcsname} -\def\dohandledescriptionstart{\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!start\endcsname} - -% implementation - -% beware: with footnotes #2 can be something messy but then #1 is -% empty anyway, so we have an extra safeguard - -\newtoks \everydescription - -\setvalue{\??dd:\v!description:\s!handler }{\@@dodescriptionhandler} -\setvalue{\??dd:\v!description:\s!handler:\s!do }{\@@somedescription} -\setvalue{\??dd:\v!description:\s!handler:\s!start}{\@@startsomedescription} - -\def\@@dodescriptionhandler#1% - {\strut - \dodescriptionheadtext{#1}% - \iftrialtypesetting \else - \currentdescriptionsynchronize - \fi} - -\def\dodescriptionheadtext#1% title - {\begingroup - \dosetdescriptionattributes\c!headstyle\c!headcolor - \the\everydescription - \descriptionparameter\c!command{\strut#1}% probably incomplete - \endgroup} - -% setup enumerations - -\def\setupenumerations - {\dodoubleempty\dosetupenumerations} - -\def\dodosetupenumerations[#1][#2]% - {\doenumerationinit{#1}{1}\empty - \getparameters[\??dd#1][#2]% - \dosetupenumerationcounter{#1}} - -\def\dosetupenumerations[#1][#2]% - {\ifsecondargument - \dodoubleargumentwithset\dodosetupenumerations[#1][#2]% - \else - \getparameters[\??dn][#1]% - \fi} - -% define enumerations - -\def\defineenumeration - {\dotripleemptywithset\dodefineenumeration} - -\def\dodefineenumeration[#1][#2][#3]% #2 or #3 assignment - {\doenumerationinit{#1}{1}\empty - \getparameters[\??dd#1][\c!text=#1,\c!state=\v!start,\s!handler=\v!enumeration,\c!levels=4]% - \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi - \ifdone % independent - \getparameters[\??dd#1][\s!counter=#1,#2]% - \dodefineenumerationcommands{#1}{1}{}{\??dn}% - \let\@@subslevel\empty - \dostepwiserecurse{2}{\descriptionparameter\c!levels}{1} - {\normalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel\v!sub}{\??dd\@@subslevel#1}}% - \edef\@@subslevel{\@@subslevel\v!sub}}% - \else % clone - \getparameters[\??dd#1][\s!counter=#2,#3]% - \let\@@subslevel\empty - \dorecurse{\descriptionparameter\c!levels} - {\noemalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel}{\??dd\@@subslevel#2}}% - \edef\@@subslevel{\@@subslevel\v!sub}}% - \fi - \edef\currentdescriptioncounter{\descriptionparameter\c!number}% - \ifx\currentdescriptioncounter\empty - \ifdone\dodefineenumerationcounter{#1}\fi - \else\ifx\currentdescriptioncounter\v!yes - \ifdone\dodefineenumerationcounter{#1}\fi - \else\ifx\currentdescriptioncounter\v!no - \ifdone\dodefineenumerationcounter{#1}\fi - \else - \letvalue{\??dd#1\s!counter}\currentdescriptioncounter % ? - \doifstructurecounterelse{\currentdescriptioncounter}{}{\dodefineenumerationcounter\currentdescriptioncounter}% - \fi\fi\fi} - -\newtoks\everysetupenumerationcounter -\let\currentenumerationcountername\empty - -\def\dosetupenumerationcounter#1% - {\edef\currentenumerationcountername{#1}% only used in the token list - \edef\currentdiscription{#1}% - \the\everysetupenumerationcounter} - -\appendtoks - \dostructurecountersetup\currentenumerationcountername\descriptionparameter -\to \everysetupenumerationcounter - -\def\dodefineenumerationcounter#1% todo: fast inheritance (was mainparameter - {\definestructurecounter[#1]% - \dosetupenumerationcounter{#1}} - -\def\dodefineenumerationcommands#1#2#3#4% since we use \currentdescription, we need an edef - {\setevalue{\??dd#3#1\s!parent}{#4}% - \unexpanded\setevalue {#3#1}{\noexpand\doenumerationcommand{#1}{#2}{#3}}% - \unexpanded\setevalue{\e!start#3#1}{\noexpand\doenumerationstart {#1}{#2}{#3}}% - \unexpanded\setevalue{\e!stop #3#1}{\noexpand\doenumerationstop {#1}{#2}{#3}}} - -% handle enumeration - -\def\currentdescriptionnumber {\csname\??dd\currentdescriptionmain\s!counter\endcsname}% no edef (yet) -\def\specificdescriptionnumber#1{\csname\??dd#1\s!counter\endcsname}% no edef (yet) - -\def\doenumerationinit#1#2#3% - {\edef\currentdescriptionmain {#1}% - \edef\currentdescriptionlevel{#2}% - \edef\currentdescriptionname {#1}% - \edef\currentdescription {#3#1}} - -\def\doenumerationcommand#1#2#3{\doenumerationinit{#1}{#2}{#3}\dosingleempty\@@description} -\def\doenumerationstart #1#2#3{\doenumerationinit{#1}{#2}{#3}\dosingleempty\@@startdescription} -\def\doenumerationstop #1#2#3{\doenumerationinit{#1}{#2}{#3}\@@stopdescription} - -\def\doresetenumerationnumber#1#2#3{\doresetsubstructurecounter [\specificdescriptionnumber{#1}][#2]} -\def\dosetenumerationnumber#1#2#3#4{\dosetsubstructurecounter [\specificdescriptionnumber{#1}][#2]{#4}} -\def\donextenumerationnumber #1#2#3{\doincrementsubstructurecounter[\specificdescriptionnumber{#1}][#2]} - -% implementation - -\newtoks \everyenumeration -\newconditional\enumerationnumberenabled -\chardef \enumerationcouplingmode \zerocount -\def \enumerationdisablenumbersignal {-} - -\appendtoks \disablepseudocaps \to \everyenumeration % sorry, uppercase causes troubles - -\letvalue{\??dd:\c!couplingway:\v!local }\plusone -\letvalue{\??dd:\c!couplingway:\v!global}\plustwo - -\setvalue{\??dd:\v!enumeration:\s!handler }{\@@doenumerationhandler} -\setvalue{\??dd:\v!enumeration:\s!handler:\s!do }{\@@somedescription} -\setvalue{\??dd:\v!enumeration:\s!handler:\s!start}{\@@startsomedescription} - -\def\@@doenumerationhandler#1% - {\strut - \ifconditional\enumerationnumberenabled - \iftrialtypesetting - \doenumerationfullnumber\showdntext{#1}% - \doenumerationcouplingsymbol - \else - \doenumerationregistercoupling - \doenumerationfullnumber\showdntext{#1}% - \doenumerationcouplingsymbol - \fi - \else - \doenumerationfullnumber\showdnpuretext{#1}% - \fi - \iftrialtypesetting \else - \currentdescriptionsynchronize - \fi} - -\def\doenumerationsavecounter {\savestructurecounter[\currentdescriptionnumber]} -\def\doenumerationrestorecounter {\restorestructurecounter[\currentdescriptionnumber]} -\def\doenumerationincrementcounter{\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} - -\def\doenumerationcheckconditions - {\doifelse{\descriptionparameter\c!number}\v!yes - {\ifx\currentdescriptionreference\enumerationdisablenumbersignal - \setfalse\enumerationnumberenabled \else \settrue\enumerationnumberenabled - \fi}% - {\setfalse\enumerationnumberenabled}% - \chardef\enumerationcouplingmode \iflocation - \executeifdefined{\??dd:\c!couplingway:\descriptionparameter\c!coupling}\zerocount - \else - \zerocount - \fi} - -\def\doenumerationregistercoupling - {\iflocation - \ifcase\enumerationcouplingmode - \or - % todo - \or - % todo - \fi - \fi} - -\def\doenumerationcouplingsymbol - {\iflocation\ifcase\enumerationcouplingmode \else - % todo - \fi\fi} - -\def\currentdescriptiontext - {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} - -\def\currentenumerationfullnumber - {\ctxlua{structure.lists.savednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} - -\def\doenumerationfullnumber#1#2% text, title - {\begingroup - \dosetdescriptionattributes\c!headstyle\c!headcolor - \the\everyenumeration - \descriptionparameter\c!command - {\strut - #1% - \descriptionparameter\c!left - \currentenumerationfullnumber - % save cq. treat expansion etc - \doifsomething{#2} - {\doif{\descriptionparameter\c!title}\v!yes - {\begingroup - \dosetdescriptionattributes\c!titlestyle\c!titlecolor - \hskip\descriptionparameter\c!titledistance - \descriptionparameter\c!titlecommand - {\descriptionparameter\c!titleleft - \begstrut#2\endstrut - \descriptionparameter\c!titleright}% - \endgroup}}% - % - \descriptionparameter\c!stopper - \descriptionparameter\c!right}% - \endgroup} - -\def\showdnpuretext{\strut\descriptionparameter\c!text} % geen spatie -\def\showdnlisttext{\descriptionparameter\c!listtext} % space in default -\def\showdntext {\doifsomething{\descriptionparameter\c!text}{\descriptionparameter\c!text\removeunwantedspaces\fixedspace}} - -\unexpanded\def\structurecounterreference#1% - {[enumref: #1]} - -% you can use \placeclosesymbol or \qed to place a symbol at the end of a -% description - -\def\@@resetdescriptionclosesymbol - {\global\@EA\settrue\csname\??dd\currentdescription:mrk\endcsname - \let\placeclosesymbol\@@placedescriptionclosesymbol - \let\qed \@@placedescriptionclosesymbol} - -\def\@@placedescriptionclosesymbol - {\ifconditional\csname\??dd\currentdescription:mrk\endcsname - \global\@EA\setfalse\csname\??dd\currentdescription:mrk\endcsname - \doifsomething{\descriptionparameter\c!closesymbol}{\descriptionparameter\c!closecommand{\descriptionparameter\c!closesymbol}}% - \fi} - -\newif\ifnodescriptioncaption - -\def\doifelsedescriptioncomponent - {\ctxlua{structure.lists.doifstoredelse(currentdescriptionnumberentry)}} - -\def\dodescriptioncomponent - {\doifelsedescriptioncomponent\nododescriptioncomponent\dododescriptioncomponent} - -\def\nododescriptioncomponent[#1][#2]% #1=interfaced-settings, #2=optional user data - {} - -\def\dododescriptioncomponent[#1][#2]% #1=interfaced-settings, #2=optional user data - {\begingroup % similar to structure so we might generalize this - \getparameters[\??dd\currentdescription][#1]% - \edef\currentdescriptionexpansion{\descriptionparameter\c!expansion}% - \ifx\currentdescriptionexpansion\s!xml - \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}% - \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}% - \xmlstartraw - \xdef\currentdescriptionlisttitle {\descriptionparameter\c!title}% - \xmlstopraw - \globallet\currentdescriptioncoding\s!xml - \else - \ifx\currentdescriptionexpansion\v!yes - \xdef\currentdescriptiontitle {\descriptionparameter\c!title}% - \xdef\currentdescriptionbookmark{\descriptionparameter\c!bookmark}% - \else - \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}% - \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}% - \fi - \globallet\currentdescriptionlisttitle \currentdescriptiontitle - \globallet\currentdescriptioncoding\s!tex - \fi - \xdef\currentdescriptionlabel {\descriptionparameter\c!label}% - \xdef\currentdescriptionreference {\descriptionparameter\c!reference}% - % - \doif{\descriptionparameter\c!title}\v!none{\global\nodescriptioncaptiontrue\global\nodescriptionnumbertrue}% will become obsolete - % - \ifconditional\enumerationnumberenabled - \doifelsedescriptioncomponent\donothing\doenumerationincrementcounter - \fi - % - \ifnodescriptioncaption - \glet\currentdescriptionlistnumber \relax - \glet\currentdescriptionsynchronize\relax - \else - \setnextinternalreference - \xdef\currentdescriptionnumberentry{\ctxlua{structure.lists.push{ - metadata = { - kind = "description", - name = "\currentdescriptionname", - level = structure.sections.currentlevel(), - catcodes = \the\catcodetable, - }, - references = { - internal = \nextinternalreference, - reference = "\currentdescriptionreference", - referenceprefix = "\referenceprefix", - block = "\currentstructureblock", - section = structure.sections.currentid(), - }, - titledata = { - label = \!!bs\detokenize\expandafter{\currentdescriptionlabel }\!!es, - title = \!!bs\detokenize\expandafter{\currentdescriptiontitle }\!!es, - \ifx\currentdescriptionbookmark\currentdescriptiontitle \else - bookmark = \!!bs\detokenize\expandafter{\currentdescriptionbookmark}\!!es, - \fi - \ifx\currentdescriptionlisttitle\currentdescriptiontitle \else % \ifx\currentdescriptionsaveinlist\v!no - list = \!!bs\detokenize\expandafter{\currentdescriptionlisttitle }\!!es, - \fi % \fi - }, - \ifconditional\enumerationnumberenabled - prefixdata = { - prefix = "\descriptionparameter\c!prefix", - separatorset = "\descriptionparameter\c!prefixseparatorset", - conversion = \!!bs\descriptionparameter\c!prefixconversion\!!es, - conversionset = "\descriptionparameter\c!prefixconversionset", - set = "\descriptionparameter\c!prefixset", - segments = "\descriptionparameter\c!prefixsegments", - connector = \!!bs\descriptionparameter\c!prefixconnector\!!es, - }, - numberdata = { - numbers = structure.counters.compact("\currentdescriptionname",nil,true), - separatorset = "\descriptionparameter\c!numberseparatorset", - conversion = "\descriptionparameter\c!numberconversion", - conversionset = "\descriptionparameter\c!numberconversionset", - stopper = \!!bs\descriptionparameter\c!numberstopper\!!es, - segments = "\descriptionparameter\c!numbersegments", - }, - \fi - userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) - } - }}% - \xdef\currentdescriptionsynchronize % make this a macro because shared - {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% - \noexpand\ctxlatelua{structure.lists.enhance(\currentdescriptionnumberentry)}}% - \fi - \endgroup} - -\installstructurelistprocessor{description}{\usestructurelistprocessor{number+title}} - -% labels, we could share with enumerations and forget about the text; anyhow, figure -% labels etc can use enumerations; we keep labels for compatibility reasons; we need -% the slightly different namespace; we can still define structure counters directly -% (multiple levels) and use an enumeration without following text - -% unfinished - -\def\setuplabels - {\getparameters[\??db]} - -\def\definelabel - {\dotripleargumentwithset\dodefinelabel} - -\def\dodefinelabel[#1][#2][#3]% #2 or #3 assignment - {\doenumerationinit{#1}{1}\empty - \getparameters[\??dd#1][\c!command=,\c!state=\v!start,\c!location=,\c!text=#1]% - \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi - \ifdone - % an independent one - \getparameters[\??dd#1][\s!counter=#1,\s!parent=\??db,#2]% - \dodefinelabelcommands{#1}{\??db}% - \dodefineenumerationcounter{#1}% - \else - \getparameters[\??dd#1][\s!counter=#1,\s!parent=\??dd#2,#3]% - \dodefinelabelcommands{#1}{\??dd#2}% - \fi} - -\def\dodefinelabelcommands#1#2% - {\unexpanded\setevalue {#1}{\noexpand\dolabelnumbercommand {#1}}% - \unexpanded\setevalue{\c!reset #1}{\noexpand\doresetlabelnumber {#1}}% - %\unexpanded\setevalue{\c!set #1}{\noexpand\dosetlabelnumber {#1}}% [#2] or {#2} ? - \unexpanded\setevalue{\e!next #1}{\noexpand\donextlabelnumber {#1}}% - \unexpanded\setevalue{\e!increment#1}{\noexpand\doincrementlabelnumber{#1}}% - \unexpanded\setevalue{\c!current #1}{\noexpand\docurrentlabelnumber {#1}}} - -% this is just for downward compatibility, we might drop it - -\setvalue{\??db:\c!location:\v!inmargin}{\inmargin} -\setvalue{\??db:\c!location:\v!inleft }{\inleft} -\setvalue{\??db:\c!location:\v!inright }{\inright} -\setvalue{\??db:\c!location:\v!margin }{\inmargin} - -\def\dolabelinit#1% - {\def\currentdescriptionmain{#1}% - \def\currentdescription {#1}% - \def\currentdescriptionlevel{1}} - -\def\docurrentlabelnumber #1{\dolabelinit{#1}\dosingleempty\dodocurrentlabelnumber} -\def\donextlabelnumber #1{\dolabelinit{#1}\dosingleempty\dodonextlabelnumber} -\def\dolabelnumbercommand #1{\dolabelinit{#1}\dosingleempty\dodolabelnumbercommand} - -\def\doresetlabelnumber #1{\dolabelinit{#1}\doresetsubstructurecounter [\currentdescriptionnumber][\currentdescriptionlevel]} -\def\dosetlabelnumber #1#2{\dolabelinit{#1}\dosetsubstructurecounter [\currentdescriptionnumber][\currentdescriptionlevel]{#2}} -\def\doincrementlabelnumber #1{\dolabelinit{#1}\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} - -\def\dodocurrentlabelnumber[#1]% - {\dontleavehmode - \writestatus{!!!}{todo: reference of label}% -% \rawreference{lab}{#1}{\composedsectionnumber}% - \dotextprefix{\descriptionparameter\c!text}% - \convertedsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} - -\def\dodonextlabelnumber[#1]% todo: ref - {\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]% - \dodocurrentlabelnumber[\currentdescriptionnumber]} - -\def\dodolabelnumbercommand[#1]% todo: ref - {\dontleavehmode - \descriptionparameter\c!before - \begingroup - \doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]% - \dosetdescriptionattributes\c!headstyle\c!headcolor - \executeifdefined{\??db:\c!location:\descriptionparameter\c!location}{\descriptionparameter\c!command}{\dodocurrentlabelnumber[#1]}% - \endgroup - \descriptionparameter\c!after} - -% to be reimplmented - -\def\setupindentations - {\dodoubleempty\dosetupindentations} - -\def\dosetupindentations[#1][#2]% - {\ifsecondargument - \dodoubleargumentwithset\dodosetupindentations[#1][#2]% - \else - \dodosetupindentations[][#1]% - \fi} - -\def\dodosetupindentations[#1][#2]% - {\getparameters[\??ds#1][#2]} - -\def\defineindenting - {\dodoubleargumentwithset\dodefineindenting} - -\def\dodefineindenting[#1][#2]% - {\copyparameters[\??ds#1][\??ds] - [\c!text,\c!separator,\c!width,\c!style,\c!color, - \c!headstyle,\c!sample,\c!before,\c!after,\c!distance]% - \getparameters[\??ds#1][#2]% - \unexpanded\setvalue {#1}{\dododefineindenting{#1}{0}{1}}% - \unexpanded\setvalue {\v!sub#1}{\dododefineindenting{#1}{1}{2}}% - \unexpanded\setvalue{\v!sub\v!sub#1}{\dododefineindenting{#1}{2}{3}}} - -\def\dododefineindenting#1#2#3% - {\par - \getvalue{\??ds#1\c!before}% - \begingroup - \doifvaluenothing{\??ds#1\c!sample} - {\setvalue{\??ds#1\c!sample}{\getvalue{\??ds#1\c!text}}}% - \assignwidth - {\descriptionsheadwidth} - {\getvalue{\??ds#1\c!width}} - {\doattributes - {\??ds#1}\c!headstyle\c!headcolor - {\getvalue{\??ds#1\c!sample}% - \spr{\getvalue{\??ds#1\c!separator}}}} - {\getvalue{\??ds#1\c!distance}}% - \advance\descriptionsheadwidth \getvalue{\??ds#1\c!distance}% - \setbox\scratchbox\hbox to \descriptionsheadwidth - {\doattributes - {\??ds#1}\c!headstyle\c!headcolor - {\strut - \getvalue{\??ds#1\c!text}% - \hss - \spr{\getvalue{\??ds#1\c!separator}}% - \hskip\getvalue{\??ds#1\c!distance}}}% - \parindent\zeropoint - \hskip#2\descriptionsheadwidth\indent\box\scratchbox - \hangindent#3\descriptionsheadwidth - \doattributes{\??ds#1}\c!style\c!color\empty - \AfterPar{\endgroup\getvalue{\??ds#1\c!after}}% must be redone - \GetPar} - -\setupdescriptions - [\c!location=\v!left, - \c!headstyle=\v!bold, - \c!titlestyle=\v!bold, - \c!style=\v!normal, - \c!color=, - \c!headcolor=, - \c!titlecolor=, - \c!width=8em, - \c!distance=0pt, - \c!titledistance=0.5em, - \c!hang=, - \c!sample=, - \c!align=, - \c!margin=\v!no, - \c!before=\blank, - \c!inbetween=\blank, - \c!after=\blank, - \c!indentnext=\v!yes, - \c!indenting=\v!never, - \c!titleleft=(, - \c!titleright=), - \c!closesymbol=, - \c!closecommand=\wordright, - \c!command=, - \c!titlecommand=] - -\setupenumerations - [\c!location=\v!top, -% \c!headstyle=\v!bold, -% \c!titlestyle=\v!bold, -% \c!style=\v!normal, -% \c!headcolor=, -% \c!titlecolor=, -% \c!color=, -% \c!width=8em, -% \c!distance=0pt, -% \c!titledistance=0.5em, -% \c!hang=, -% \c!sample=, -% \c!align=, -% \c!margin=\v!no, -% \c!before=\blank, -% \c!inbetween=\blank, -% \c!after=\blank, -% \c!indentnext=\v!yes, -% \c!indenting=\v!never, -% \c!titleleft=(, -% \c!titleright=), -% \c!closesymbol=, -% \c!closecommand=\wordright, -% \c!command=, -% \c!titlecommand=, - \c!text=, - \c!way=\v!by\v!text, - \c!prefixconnector=., - \c!stopper=, - \c!number=\v!yes, % else description - \c!start=0, - \s!parent=\??dd] - -\setuplabels - [\s!parent=\??dn] - -\setupindentations - [\c!style=\v!normal, - \c!headstyle=\v!normal, - \c!color=, - \c!headcolor=, - \c!width=\v!fit, - \c!text=\unknown, - \c!sample=, - \c!before=\blank, - \c!after=\blank, - \c!distance=1em, - \c!separator={ :}] - -\protect \endinput diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua index e0df8294a..cc8f46f6c 100644 --- a/tex/context/base/strc-doc.lua +++ b/tex/context/base/strc-doc.lua @@ -465,10 +465,10 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref if ownnumber ~= "" then processors.sprint(ctxcatcodes,ownnumber) -- elseif conversion and conversion ~= "" then - -- tex.sprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) + -- texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups) - tex.sprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) + texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) else local theconversion = sets.get("structure:conversions",block,conversion,index,"numbers") processors.sprint(ctxcatcodes,theconversion,function(str) diff --git a/tex/context/base/strc-doc.mkiv b/tex/context/base/strc-doc.mkiv new file mode 100644 index 000000000..e76e015a9 --- /dev/null +++ b/tex/context/base/strc-doc.mkiv @@ -0,0 +1,166 @@ +%D \module +%D [ file=strc-doc, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Document Structure, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Document Structure} + +\registerctxluafile{strc-doc}{1.001} + +\unprotect + +% We operate in a \type {@@ns} namespace. All data is passed through +% variables. Of course we can built another interface on top of this +% that accepts multiple arguments. We might change this approach and +% remove this layer. + +\def\currentstructurecounter{0} + +\definesystemvariable {ns} + +\def\structureparameter#1{\csname\??ns#1\endcsname} + +\def\detokenizedstructureparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??ns#1\endcsname}} + +\def\structurecomponent{\dodoubleempty\dostructurecomponent} + +\getparameters % initialization, used not grouped anyway + [\??ns] + [\c!number=,\c!level=,\c!name=,\c!title=,\c!bookmark=,\c!label=,\c!coupling=,\c!ownnumber=, + \c!sectionseparatorset=\s!default,\c!sectionconversionset=\s!default, + \c!sectionstopper=,\c!sectionsegments=, + \c!reset=,\c!reference=, + \c!expansion=\v!no, + \c!saveinlist=\v!yes, + \c!command=\showstructuredata] + +\def\dostructurecomponent[#1][#2]% #1=interfaced-settings, #2=optional user data (not yet supported) + {\begingroup + \getparameters[\??ns][#1]% + \xdef\currentstructurename {\structureparameter\c!name}% + \xdef\currentstructurecoupling {\structureparameter\c!coupling}% + \xdef\currentstructureownnumber{\structureparameter\c!ownnumber}% optional own number + \xdef\currentstructurelevel {\structureparameter\c!level}% + \edef\currentstructureexpansion{\structureparameter\c!expansion} + \ifx\currentstructureexpansion\s!xml + % goes via lua anyway + \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% + \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}% + % + \xmlstartraw + \xdef\currentstructurelisttitle {\structureparameter\c!title}% + \xmlstopraw + \globallet\currentstructurecoding\s!xml + \else + \ifx\currentstructureexpansion\v!yes + \xdef\currentstructuretitle {\structureparameter\c!title}% + \xdef\currentstructurebookmark{\structureparameter\c!bookmark}% + \else + \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% + \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}% + \iflocation \ifx\currentstructurebookmark\empty + \begingroup + \simplifycommands + \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}% + \endgroup + \fi \fi + \fi + \globallet\currentstructurelisttitle \currentstructuretitle + \globallet\currentstructurecoding\s!tex + \fi + \xdef\currentstructurelabel {\structureparameter\c!label}% + \xdef\currentstructurereference {\structureparameter\c!reference}% + \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}% + \xdef\currentstructureshownumber {\structureparameter\c!number}% + \xdef\currentstructuresaveinlist {\structureparameter\c!saveinlist}% + \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}% + \setnextinternalreference + \xdef\currentstructurenumber{\ctxlua{ % todo: combine with next call, adapt marks accordingly + structure.sections.somelevel { + references = { + internal = \nextinternalreference, + block = "\currentstructureblock", + reference = "\currentstructurereference", + referenceprefix = "\currentstructurereferenceprefix", + }, + directives = { + resetset = "\structureparameter\c!reset", + hidenumber = not toboolean("\currentstructureincrementnumber",true), % incremented but hidden + }, + metadata = { + kind = "section", + name = "\currentstructurename", + catcodes = \the\catcodetable, + coding = "\currentstructurecoding", + xmlroot = \ifx\currentstructurecoding\s!xml "\xmldocument" \else nil \fi, + \ifx\currentstructuresaveinlist\v!no + nolist = true, + \fi + }, + titledata = { % we can add mark and reference + label = \!!bs\detokenize\expandafter{\currentstructurelabel }\!!es, + title = \!!bs\detokenize\expandafter{\currentstructuretitle }\!!es, + \ifx\currentstructurebookmark\currentstructuretitle \else + bookmark = \!!bs\detokenize\expandafter{\currentstructurebookmark }\!!es, + \fi + \ifx\currentstructurelisttitle\currentstructuretitle \else \ifx\currentstructuresaveinlist\v!no + list = \!!bs\detokenize\expandafter{\currentstructurelisttitle}\!!es, + \fi \fi + }, + numberdata = { + separatorset = "\structureparameter\c!sectionseparatorset", + conversion = "\structureparameter\c!sectionconversion", % for good old times sake + conversionset = "\structureparameter\c!sectionconversionset", + stopper = \!!bs\structureparameter\c!sectionstopper\!!es, + set = "\structureparameter\c!sectionset", + segments = "\structureparameter\c!sectionsegments", + ownnumber = "\currentstructureownnumber", + hidenumber = \ifx\currentstructureshownumber\v!no true\else nil\fi, % titles + }, + userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) + } + }}% + \xdef\currentstructurelistnumber{\ctxlua{structure.lists.push(structure.sections.current())}}% + % \currentstructuresynchronize has to be called someplace, since it introduces a node + \setstructuresynchronization\currentstructurelistnumber + \structureparameter\c!command + \endgroup} + +\let\currentstructurenumber \!!zerocount +\let\currentstructurecounter \!!zerocount +\let\previousstructurecounter\!!zerocount + +\def\setstructuresynchronization#1% + {\xdef\currentstructuresynchronize + {\noexpand\ctxlua{jobreferences.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference)}% + \noexpand\ctxlatelua{structure.lists.enhance(#1)}}} + +\def\reportcurrentstructure{\ctxlua{structure.sections.writestatus()}} + +% Beware: we need to flush the data to the list explicitly. This is because +% node in inserted and we may want control over when that happens. + +\def\showstructuredata + {\par + \dontleavehmode + \currentstructuresynchronize + [\currentstructurename: \showstructurelevel: \currentstructuretitle] + \par} + +% We can access the (stored) data with the following macros. + +\def\structurevalue #1{\ctxlua{structure.sections.get("#1")}} +\def\structureuservalue#1{\ctxlua{structure.sections.getuser("#1")}} +\def\structurenumber {\ctxlua{structure.sections.fullnumber()}} + +\def\structurecctvalue #1{\ctxlua{structure.sections.get("#1",nil,true)}} + +\protect \endinput diff --git a/tex/context/base/strc-doc.tex b/tex/context/base/strc-doc.tex deleted file mode 100644 index e76e015a9..000000000 --- a/tex/context/base/strc-doc.tex +++ /dev/null @@ -1,166 +0,0 @@ -%D \module -%D [ file=strc-doc, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Document Structure, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Document Structure} - -\registerctxluafile{strc-doc}{1.001} - -\unprotect - -% We operate in a \type {@@ns} namespace. All data is passed through -% variables. Of course we can built another interface on top of this -% that accepts multiple arguments. We might change this approach and -% remove this layer. - -\def\currentstructurecounter{0} - -\definesystemvariable {ns} - -\def\structureparameter#1{\csname\??ns#1\endcsname} - -\def\detokenizedstructureparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??ns#1\endcsname}} - -\def\structurecomponent{\dodoubleempty\dostructurecomponent} - -\getparameters % initialization, used not grouped anyway - [\??ns] - [\c!number=,\c!level=,\c!name=,\c!title=,\c!bookmark=,\c!label=,\c!coupling=,\c!ownnumber=, - \c!sectionseparatorset=\s!default,\c!sectionconversionset=\s!default, - \c!sectionstopper=,\c!sectionsegments=, - \c!reset=,\c!reference=, - \c!expansion=\v!no, - \c!saveinlist=\v!yes, - \c!command=\showstructuredata] - -\def\dostructurecomponent[#1][#2]% #1=interfaced-settings, #2=optional user data (not yet supported) - {\begingroup - \getparameters[\??ns][#1]% - \xdef\currentstructurename {\structureparameter\c!name}% - \xdef\currentstructurecoupling {\structureparameter\c!coupling}% - \xdef\currentstructureownnumber{\structureparameter\c!ownnumber}% optional own number - \xdef\currentstructurelevel {\structureparameter\c!level}% - \edef\currentstructureexpansion{\structureparameter\c!expansion} - \ifx\currentstructureexpansion\s!xml - % goes via lua anyway - \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% - \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}% - % - \xmlstartraw - \xdef\currentstructurelisttitle {\structureparameter\c!title}% - \xmlstopraw - \globallet\currentstructurecoding\s!xml - \else - \ifx\currentstructureexpansion\v!yes - \xdef\currentstructuretitle {\structureparameter\c!title}% - \xdef\currentstructurebookmark{\structureparameter\c!bookmark}% - \else - \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% - \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}% - \iflocation \ifx\currentstructurebookmark\empty - \begingroup - \simplifycommands - \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}% - \endgroup - \fi \fi - \fi - \globallet\currentstructurelisttitle \currentstructuretitle - \globallet\currentstructurecoding\s!tex - \fi - \xdef\currentstructurelabel {\structureparameter\c!label}% - \xdef\currentstructurereference {\structureparameter\c!reference}% - \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}% - \xdef\currentstructureshownumber {\structureparameter\c!number}% - \xdef\currentstructuresaveinlist {\structureparameter\c!saveinlist}% - \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}% - \setnextinternalreference - \xdef\currentstructurenumber{\ctxlua{ % todo: combine with next call, adapt marks accordingly - structure.sections.somelevel { - references = { - internal = \nextinternalreference, - block = "\currentstructureblock", - reference = "\currentstructurereference", - referenceprefix = "\currentstructurereferenceprefix", - }, - directives = { - resetset = "\structureparameter\c!reset", - hidenumber = not toboolean("\currentstructureincrementnumber",true), % incremented but hidden - }, - metadata = { - kind = "section", - name = "\currentstructurename", - catcodes = \the\catcodetable, - coding = "\currentstructurecoding", - xmlroot = \ifx\currentstructurecoding\s!xml "\xmldocument" \else nil \fi, - \ifx\currentstructuresaveinlist\v!no - nolist = true, - \fi - }, - titledata = { % we can add mark and reference - label = \!!bs\detokenize\expandafter{\currentstructurelabel }\!!es, - title = \!!bs\detokenize\expandafter{\currentstructuretitle }\!!es, - \ifx\currentstructurebookmark\currentstructuretitle \else - bookmark = \!!bs\detokenize\expandafter{\currentstructurebookmark }\!!es, - \fi - \ifx\currentstructurelisttitle\currentstructuretitle \else \ifx\currentstructuresaveinlist\v!no - list = \!!bs\detokenize\expandafter{\currentstructurelisttitle}\!!es, - \fi \fi - }, - numberdata = { - separatorset = "\structureparameter\c!sectionseparatorset", - conversion = "\structureparameter\c!sectionconversion", % for good old times sake - conversionset = "\structureparameter\c!sectionconversionset", - stopper = \!!bs\structureparameter\c!sectionstopper\!!es, - set = "\structureparameter\c!sectionset", - segments = "\structureparameter\c!sectionsegments", - ownnumber = "\currentstructureownnumber", - hidenumber = \ifx\currentstructureshownumber\v!no true\else nil\fi, % titles - }, - userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) - } - }}% - \xdef\currentstructurelistnumber{\ctxlua{structure.lists.push(structure.sections.current())}}% - % \currentstructuresynchronize has to be called someplace, since it introduces a node - \setstructuresynchronization\currentstructurelistnumber - \structureparameter\c!command - \endgroup} - -\let\currentstructurenumber \!!zerocount -\let\currentstructurecounter \!!zerocount -\let\previousstructurecounter\!!zerocount - -\def\setstructuresynchronization#1% - {\xdef\currentstructuresynchronize - {\noexpand\ctxlua{jobreferences.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference)}% - \noexpand\ctxlatelua{structure.lists.enhance(#1)}}} - -\def\reportcurrentstructure{\ctxlua{structure.sections.writestatus()}} - -% Beware: we need to flush the data to the list explicitly. This is because -% node in inserted and we may want control over when that happens. - -\def\showstructuredata - {\par - \dontleavehmode - \currentstructuresynchronize - [\currentstructurename: \showstructurelevel: \currentstructuretitle] - \par} - -% We can access the (stored) data with the following macros. - -\def\structurevalue #1{\ctxlua{structure.sections.get("#1")}} -\def\structureuservalue#1{\ctxlua{structure.sections.getuser("#1")}} -\def\structurenumber {\ctxlua{structure.sections.fullnumber()}} - -\def\structurecctvalue #1{\ctxlua{structure.sections.get("#1",nil,true)}} - -\protect \endinput diff --git a/tex/context/base/strc-flt.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..b0ff9893b --- /dev/null +++ b/tex/context/base/strc-flt.mkiv @@ -0,0 +1,2173 @@ +%D \module +%D [ file=strc-flt, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Float Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Float Numbering} + +\registerctxluafile{strc-flt}{1.001} + +\unprotect + +%D This module needs a cleanup and will be split in +%D strc-flt.tex and page-flt.mkiv cq. page-flt.mkii. + +\ifx\addlocalbackgroundtobox\undefined \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi + +\def\placefloats{\doflushfloats} % keep this one + +\let\currentfloat\empty + +\def\letfloatparameter #1{\expandafter\csname\??fl\currentfloat#1\endcsname} + +\def\floatparameter #1{\csname\dofloatparameter{\??fl\currentfloat}#1\endcsname} +\def\floatsharedparameter#1{\csname \??fl #1\endcsname} +\def\floatparameterhash #1{\dofloatparameterhash {\??fl\currentfloat}#1} + +\def\dofloatparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dofloatparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dofloatparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dofloatparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dofloatparentparameter #1#2{\ifx#1\relax\s!empty\else\dofloatparameter #1#2\fi} +\def\dofloatparentparameterhash#1#2{\ifx#1\relax \else\dofloatparameterhash#1#2\fi} + +\def\detokenizedfloatparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??fl\currentfloat#1\endcsname}} + +\def\dosetfloatattributes#1#2% style color + {\edef\fontattributehash {\floatparameterhash#1}% + \edef\colorattributehash{\floatparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\def\floatcaptionparameter #1{\csname\dofloatcaptionparameter{\??kj\currentfloat}#1\endcsname} +\def\floatcaptionparameterhash#1{\dofloatcaptionparameterhash {\??kj\currentfloat}#1} + +\def\dofloatcaptionparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dofloatcaptionparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dofloatcaptionparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dofloatcaptionparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dofloatcaptionparentparameter #1#2{\ifx#1\relax\s!empty\else\dofloatcaptionparameter #1#2\fi} +\def\dofloatcaptionparentparameterhash#1#2{\ifx#1\relax \else\dofloatcaptionparameterhash#1#2\fi} + +\def\detokenizedcaptionparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??kj\currentfloat#1\endcsname}} + +\def\dosetfloatcaptionattributes#1#2% style color + {\edef\fontattributehash {\floatcaptionparameterhash#1}% + \edef\colorattributehash{\floatcaptionparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\def\dohandlenextfloatindent + {\checknextindentation[\floatparameter\c!indentnext]% + \dorechecknextindentation} + +%D The two shared (parent) definitions: + +% todo: everysetupfloat everysetupcaption for all floats + +\def\setupfloats {\dosingleargument\dosetupfloats} % was \??bk +\def\setupcaptions{\dosingleargument\dosetupcaptions} + +\let\alldefinedfloats\empty + +\def\doprocessallfloats#1% + {\def\doprocesssomefloat##1{\def\currentfloat{##1}#1}% + \processcommacommand[\alldefinedfloats]\doprocesssomefloat} + +\def\dosetupfloats [#1]{\getparameters[\??fl][#1]\doprocessallfloats{\the\everysetupfloat}} +\def\dosetupcaptions[#1]{\getparameters[\??kj][#1]\doprocessallfloats{\the\everysetupcaption}} + +% \def\dosetupfloats [#1]{\getparameters[\??fl][#1]} +% \def\dosetupcaptions[#1]{\getparameters[\??kj][#1]} + +\setupcaptions + [\c!location=\v!bottom, + \c!grid=, + \c!before=, % not used (yet) + \c!inbetween={\blank[\v!medium]}, + \c!after=, % not used (yet) + \c!spacebefore=, + \c!spaceinbetween=, % replaces fuzzy inbetween dual usage + \c!spaceafter=, + \c!width=\v!fit, + \c!minwidth=\v!fit, % id est: the width of the floatbox in some cases + \c!headstyle=\v!bold, + \c!headcolor=, + \c!leftmargin=\zeropoint, + \c!rightmargin=\zeropoint, + \c!outermargin=\zeropoint, + \c!innermargin=\zeropoint, + \c!setups=, + \c!style=\v!normal, + \c!color=, + \c!textstyle=, + \c!textcolor=, + \c!align=, + \c!number=\v!yes, +\c!prefix=\v!no, +\c!prefixconnector=., +\c!way=bychapter, +\c!prefixsegments=2:2, +% \c!way=\@@nrway, +% \c!blockway=\@@nrblockway, +% \c!sectionnumber=\@@nrsectionnumber, +% \c!separator=\@@koseparator, +% \c!stopper=\@@kostopper, +% \c!suffix=\floatcaptionsuffix, % hook + \c!distance=1em, + \c!conversion=\v!numbers, + \c!command=] + +% we can comment some of these + +\setupfloats + [\c!location=\v!middle, + \c!width=8\lineheight, + \c!height=6\lineheight, + \c!offset=\v!overlay, + \c!frame=\v!off, + \c!strut=\v!no, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!background=, + \c!backgroundscreen=, + \c!backgroundcolor=, + \c!backgroundoffset=\!!zeropoint, + \c!topframe=, + \c!bottomframe=, + \c!leftframe=, + \c!rightframe=, + \c!frameoffset=\!!zeropoint, + \c!before=, + \c!after=, + \c!spacebefore=\v!big, + \c!spaceafter=\v!big, + \c!sidespacebefore=\floatsharedparameter\c!spacebefore, + \c!sidespaceafter=\floatsharedparameter\c!spaceafter, + \c!sidealign=\v!normal, + \c!textmethod=\ifgridsnapping2\else0\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) + \c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) + \c!indentnext=\v!no, + \c!margin=1em, + \c!method=1, + \c!cache=\v!yes, % when no, then intermediate flush + \c!leftmargin=\zeropoint, % displacement in 'normal floats' + \c!rightmargin=\zeropoint, % idem + \c!innermargin=\zeropoint, % idem + \c!outermargin=\zeropoint, % idem + \c!leftmargindistance=\zeropoint, + \c!rightmargindistance=\floatparameter\c!leftmargindistance, + \c!ntop=2, + \c!nbottom=0, + \c!nlines=4, + \c!local=, + \c!bottombefore=, % e.g. \vfill + \c!bottomafter=, + \c!default=\v!figure, + \c!numbering=\v!yes] + +\def\@@bknumbering {\floatsharedparameter\c!numbering } % global one +\def\@@bkspaceafter {\floatsharedparameter\c!spaceafter } % global one +\def\@@bkspacebefore{\floatsharedparameter\c!spacebefore} % global one +\def\@@bknbottom {\floatsharedparameter\c!nbottom } % global one +\def\@@bkntop {\floatsharedparameter\c!ntop } % global one +\def\@@bknlines {\floatsharedparameter\c!nlines } % global one +\def\@@bkmargin {\floatsharedparameter\c!margin } % global one +\def\@@bkcache {\floatsharedparameter\c!cache } % global one + +% float +% +% [%\c!width=8\lineheight, % 15\bodyfontsize, +% %\c!height=6\lineheight, % 10\bodyfontsize, +% \c!offset=\v!overlay, +% \c!width=\v!fit, +% \c!height=\v!fit, +% \c!minwidth=, +% \c!maxwidth=, +% \c!maxheight=, +% \c!criterium=, +% % inherited +% \c!pageboundaries=, +% \c!default=]% + +% number +% +% [\c!text=#1, +% \c!location=\v!intext, +% \c!way=\floatcaptionparameter\c!way, +% \c!blockway=\floatcaptionparameter\c!blockway, +% \c!sectionnumber=\floatcaptionparameter\c!sectionnumber, +% \c!conversion=\floatcaptionparameter\c!conversion]% + + +%D Individial settings: + +\def\setupfloat {\dodoubleargument\dosetupfloat} +\def\setupcaption{\dodoubleargument\dosetupcaption} + +\newtoks\everysetupfloat +\newtoks\everysetupcaption + +\def\dosetupfloat[#1][#2]% + {\def\docommand##1{\getparameters[\??fl##1][#2]\the\everysetupfloat}% + \processcommalist[#1]\docommand} + +\def\dosetupcaption[#1][#2]% + {\def\docommand##1{\getparameters[\??kj##1][#2]\the\everysetupcaption}% + \processcommalist[#1]\docommand} + +\appendtoks + \dostructurecountersetup\currentfloat\floatcaptionparameter +\to \everysetupcaption + +%D Definitions: + +\def\definefloat + {\dotripleempty\dodefinefloat} + +\def\dodefinefloat[#1][#2][#3]% #1=naam #2=meervoud #3=parent + {\ifthirdargument + \redodefinefloat[#1][#2][#3]% + \else\ifsecondargument + \dododefinefloat[#1][#2]% + \else + \dododefinefloat[#1][#1]% + \fi\fi} + +\presetlocalframed[\??fl] + +\def\dododefinefloat[#1][#2]% + {\copylocalframed[\??fl#1][\??fl]% + \definestructurecounter[#1]% + \addtocommalist{#1}\alldefinedfloats + \setupfloat[#1][\s!parent=\??fl]% + \setupcaption[#1][\s!parent=\??kj]% + \definelist[#1]% + \presetlabeltext[#1=\Word{#1}~]% + \presetheadtext[#2=\Word{#2}]% + \dodefinefloatcommands[#1][#2]% + }% \newnodelocation{\v!float\@@thenumber{#1}}} + +\def\redodefinefloat[#1][#2][#3]% + {\copylocalframed[\??fl#1][\??fl#3]% + \setupfloat[#1][\s!parent=\??fl#3]% + \setupcaption[#1][\s!parent=\??kj#3]% + \definestructurecounter[#1][#3]% + \definelist[#1][#3]% + \presetlabeltext[#1=\Word{#3}]% + \presetheadtext[#2=\Word{#2}]% + \dodefinefloatcommands[#1][#2]} + +\def\dodefinefloatcommands[#1][#2]% + {\setvalue {\e!place\e!listof#2}{\dodoubleempty\doplacelist[#1]}% + \setvalue {\e!complete\e!listof#2}{\dotripleempty\dodocompletelist[#1][#2]}% + \setvalue {\e!place#1}{\dotripleempty\docomplexplacefloat[#1]}% + \setvalue {\e!reserve#1}{\doquadrupleempty\docomplexreserveblock[#1]}% + \setvalue {\e!start#1\e!text}{\dotripleempty\docomplexstarttextblock[#1]}% + \setvalue {\e!stop#1\e!text}{\dostoptextfloat}% + \setvalue{\e!start\e!reserve#1\e!text}{\doquadrupleempty\docomplexstartreservetextblock[#1]}% + \setvalue {\e!stop\e!reserve#1\e!text}{\dostoptextfloat}% + \setvalue {\e!emptyone#1}{\doemptyfloatblock{#1}}% + \setvalue {\e!emptytwo#1}{\doemptyfloatblock{#1}}} + +%D Fallback float body: + +\def\doemptyfloatblock#1% + {\framed + [\c!frame=\v!on, + \c!width=\floatsharedparameter\c!width, + \c!height=\floatsharedparameter\c!height, + \c!location=\v!normal, + \c!offset=\floatsharedparameter\c!offset]% + {\getmessage\m!floatblocks{12}\empty}} + +%D Data. We can generalize this to lists. + +\newif\ifnofloatcaption +\newif\ifnofloatnumber +\newif\ifemptyfloatcaption + +\def\getfloatparameters {\getparameters[\??fl\currentfloat]} +\def\getcaptionparameters{\getparameters[\??kj\currentfloat]} + +\installstructurelistprocessor{float}{\usestructurelistprocessor{number+title}} + +\def\thecurrentfloatnumber + {\ifnofloatcaption \else \ifnofloatnumber \else +% \labeltexts\currentfloat{\convertedstructurecounter[\currentfloat]}% ! ! todo: use a lua call instead +\ifx\currentfloatnumber\relax\else + \labeltexts\currentfloat{\ctxlua{structure.lists.savednumber("\currentfloat",\currentfloatnumber)}}% +\fi + \fi \fi} + +\def\thecurrentfloatcaption + {\ifnofloatcaption \else +\ifx\currentfloatnumber\relax\else + \ctxlua{structure.lists.savedtitle("\currentfloat",\currentfloatnumber)}% +\fi + \fi} + +%D Captions. + +\let\floatcaptionsuffix\empty % an optional suffix +\let\floatcaptionnumber\empty % a logical counter + +% the split is needed when for instance the float goes into +% a multi page field and the list of figs becomes larger than +% one page: cycle between 'only flush when object ref ok' +% and 'one/many page fig list'; see "uguide finometer" +% +% potential sync bug with sectionblocks, see uguide.tex + +% NOT YET REDONE ! ! ! ! ! + + \def\placefloatcaption + {\dodoubleempty\doplacefloatcaption} + + \long\def\doplacefloatcaption[#1][#2]#3% + {\setfloatcaption[#1][#2]{#3}% + \placefloatcaptiontext[#1]% + \placefloatcaptionreference[#1]} + + \def\setfloatcaption % \dosetfloatcaption already in use + {\dodoubleempty\dodosetfloatcaption} % beware, name clash + + \long\def\dodosetfloatcaption[#1][#2]#3% to do namespace for number/ascii + {\ifnofloatnumber % also handle trialtypesetting + \letgvalue{@fl@r@#1}\relax + \letgvalue{@fl@t@#1}\relax + \else + \preparefloatnumber{#1}% + \letgvalue{@fl@n@#1}\composedsectionnumber + % indirect macro can be more efficient + \setgvalue{@fl@r@#1}% + {\tracefloatnumber{#1}% + \ifconditional\retainfloatnumber\else + % \dowritetolist{#1}{\getvalue{@fl@n@#1}}{#3}{#1}% + % \gdefconvertedargument\flasciititle{#3}% \asciititle is global + % \doifsomething{#2}{\rawreference\s!flt{#2}{{\getvalue{@fl@n@#1}}{\flasciititle}}}% + \fi + \letgvalue{@fl@r@#1}\relax}% nils + \setgvalue{@fl@t@#1}% + {\preparefullnumber{\??kj#1}{\getvalue{@fl@n@#1}}\preparednumber + \begingroup + \dosetfloatcaptionattributes\c!style\c!color + \begingroup + \dosetfloatcaptionattributes\c!headstyle\c!headcolor + \labeltexts{#1}{\preparednumber}% + \endgroup + \begingroup + \dosetfloatcaptionattributes\c!textstyle\c!textcolor + \dotfskip{\floatcaptionparameter\c!distance}#3% + \endgroup + \endgroup}% + \fi} + + \long\def\dodosetfloatcaption[#1][#2]#3% to do namespace for number/ascii + {\letgvalue{@fl@r@#1}\relax + \letgvalue{@fl@t@#1}\relax} + + \def\placefloatcaptiontext [#1]{\getvalue{@fl@t@#1}} + \def\placefloatcaptionnumber [#1]{\getvalue{@fl@n@#1}} + \def\placefloatcaptionreference[#1]{\getvalue{@fl@r@#1}} + + % still needed for uguide + + \let\placefloatlabel \placefloatcaption + \let\placefloatlabeltext \placefloatcaptiontext + \let\placefloatlabelreference \placefloatcaptionreference + +% TILL HERE + +\newbox\captionbox + +\long\def\putcompletecaption#1#2% + {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}% + %\floatcaptionparameter\c!before % test for side effects first + \noindent + \gdef\lastcaptiontag{\strut#1}% was xdef + \begingroup + \dosetfloatcaptionattributes\c!style\c!color + \ifnofloatnumber + \else + \hbox{\dosetfloatcaptionattributes\c!headstyle\c!headcolor\strut#1}% + \ifnofloatcaption \else \ifemptyfloatcaption \else + \doifelsenothing{\floatcaptionparameter\c!spaceinbetween} + {\scratchskip\floatcaptionparameter\c!distance\relax + \dotfskip\scratchskip\emergencystretch.5\scratchskip} + {\blank[\floatcaptionparameter\c!spaceinbetween]}% + \fi \fi + \fi + \ifnofloatcaption + \globallet\lastcaptionht\!!zeropoint + \globallet\lastcaptiondp\!!zeropoint + \else + \dosetfloatcaptionattributes\c!textstyle\c!textcolor + \xdef\lastcaptionht{\strutheight}% + \xdef\lastcaptiondp{\strutdepth}% + \begstrut#2\endstrut\endgraf + \fi + \endgroup + %\floatcaptionparameter\c!after % test for side effects first + \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}} + +\let\lastcaptionht\!!zeropoint +\let\lastcaptiondp\!!zeropoint + +\newbox\tempcaptionbox + +\newif\iftracecaptions + +\def\settracedcaptionbox + {\iftracecaptions\setbox\tempcaptionbox\ruledhbox{\box\tempcaptionbox}\fi} + +% \definefloat [figure-1] [figure] +% \definefloat [figure-2] [figure] +% \setupfloat [figure-1] [location=left,leftmargin=10mm] +% \setupfloat [figure-2] [location=left,leftmargin=-5mm] +% \setupcaption [figure-1] [align=flushleft] +% \setupcaption [figure-2] [align=flushleft,leftmargin=15mm] +% +% \startsetups somefigure +% \ifdim\wd\nextbox>\textwidth +% \placefloat[figure-2][][]{}{\box\nextbox} +% \else +% \placefloat[figure-1][][]{}{\box\nextbox} +% \fi +% \stopsetups +% +% \def\setupswithbox[#1]{\dowithnextbox{\setups[#1]}\vbox} +% +% test \setupswithbox[somefigure]{\framed[width=3cm] {}} test +% test \setupswithbox[somefigure]{\framed[width=\dimexpr\textwidth+3cm\relax]{}} test + +\def\dosetcaptionthings + {\setups[\floatcaptionparameter\c!setups]% expanded ? + %\advance\leftskip \floatcaptionparameter\c!leftmargin + %\advance\rightskip\floatcaptionparameter\c!rightmargin + \relax} + +\def\dofakecaptionthings + {\hbox{\dosetcaptionthings\hskip\leftskip\hskip\rightskip}} + +\long\def\docheckcaptioncontent#1#2% + {\ifnofloatcaption \else + \setbox\tempcaptionbox\hbox + {\trialtypesettingtrue + \notesenabledfalse + \putcompletecaption{#1}{#2}}% + % new, \placefigure{\XMLflush{somecaption}}{} passes earlier empty check + % so here we misuse the scratch box; actually this means that the previous + % test can go away (some day, when i redo this module) + \ifdim\wd\tempcaptionbox=\zeropoint + \global\emptyfloatcaptiontrue + \ifnofloatnumber + \global\nofloatcaptiontrue + \fi + \else + \setbox\tempcaptionbox\hbox{\dosetcaptionthings\hskip\leftskip\box\tempcaptionbox}% yet incomplete + \fi + \fi} + +% the tricky part of getting float related two pass data is +% that we should fetch is early but can only save it with +% the composed float box; this determines the order: get it +% before saving it + +\definetwopasslist{\s!float\s!data} \newcounter\noffloatdata + +\let\twopassfloatdata\realpageno % used for odd/even determination, can be combined with nodelocation + +\def\dosavefloatdata % \expanded + {\doglobal\increment\noffloatdata + \lazysavetaggedtwopassdata{\s!float\s!data}{\noffloatdata}{\noffloatpages}{\noexpand\realfolio}}% later {}{}{}{} and \getfirst... + +\def\dogetfloatdata % precedes save ! + {\doglobal\increment\noffloatpages + \findtwopassdata{\s!float\s!data}{\noffloatpages}% + \iftwopassdatafound + \globallet\twopassfloatdata\twopassdata + \else + \globallet\twopassfloatdata\realpageno % \realfolio + \fi} + +\def\tracefloatnumber#1% + {\doifnot{\floatsharedparameter\c!numbering}\v!nocheck{\tagnodelocation{\v!float\@@thenumber{#1}}}} + +\newconditional\retainfloatnumber + +\def\preparefloatnumber#1% + {\xdef\floatcaptionnumber{#1}% + \doifelsenodelocation{\v!float\@@thenumber{#1}} + \donothing {\chardef\nodelocationmode\zerocount}% + \doifelse{\floatsharedparameter\c!numbering}\v!nocheck + {\incrementnumber[#1]% + \makesectionnumber[#1]% + \ifconditional\retainfloatnumber\decrementnumber[#1]\fi} + {\ifinsidecolumns + \chardef\nodelocationmode\zerocount + % to be perfected: + % \chardef\nodelocationmode\plustwo + \fi +% FOR THE MOMENT NOT AVAILABLE +\chardef\nodelocationmode\zerocount +% BUT NOT THAT HARD TO DO + \ifcase\nodelocationmode + \incrementnumber[#1]% + \makesectionnumber[#1]% + \ifconditional\retainfloatnumber\decrementnumber[#1]\fi + \else + % force check, so that we get a proper way-sync and + % can use the accumulated number + % \checknumber[#1]% \incrementnumber does this + \incrementnumber[#1]% + \savenumber[#1]% + % the real work is done here + \nextnodelocation{\v!float\@@thenumber{#1}}% better \nextfloatnumber + \analyzenodelocation{\v!float\@@thenumber{#1}}% + \scratchcounter\getnodelocationo{\v!float\@@thenumber{#1}}% + \advance\scratchcounter\minusone + % here we correct for 'per whatever handling' + \advance\scratchcounter-\accumulatednumber[#1]% + \setnumber[#1]\scratchcounter + \incrementnumber[#1]% + \makesectionnumber[#1]% + \restorenumber[#1]% + % now we're back to normal numbering + \fi}} + +%D test case: +%D +%D \starttyping +%D \setupfloat[figure][criterium=\marginwidth,fallback=bottom] +%D \dorecurse{3}{ +%D \chapter{test} +%D \placefigure[bottom]{1}{\framed{bottom}} +%D test +%D \placetable[bottom]{1}{\framed{table}} +%D test +%D \placetable{2}{\framed{table}} +%D test +%D \placefigure[left]{2}{\framed{left but way too wide}} +%D \input tufte +%D \placefigure[left]{3}{\framed{left but ok}} +%D \input tufte } +%D \stoptyping + +% A complication is that we may have to handle a pagebreak +% first, which in turn may issue a (postponed) float. +% Therefore we may not trust on variable assignments before +% we're realy dealing with the float. Some day I'll root out +% the global settings. + +\def\docomplexplacefloat[#1][#2]% [#3]#4% + {\edef\currentfloat{#1}% + \doifnothing\currentfloat{\let\currentfloat\v!figure}% + \doifelsenothing{#2} + {\edef\floatlocation{\floatparameter\c!default}} + {\edef\floatlocation{#2}}% + \doifinsetelse\v!split{#2} + {\normalexpanded{\noexpand\dodocomplexsplitfloat[\currentfloat][\floatlocation]}} + {\normalexpanded{\noexpand\dodocomplexplacefloat[\currentfloat][\floatlocation]}}} + +\long\def\dodocomplexsplitfloat[#1][#2][#3]#4% + {\splitfloat{\dodocomplexplacefloat[#1][#2][#3]{#4}}} + +\def\flushfloatslist + {\v!left,\v!right,\v!inner,\v!outer,% + \v!backspace,\v!cutspace,% + \v!inleft,\v!inright,\v!inmargin,% + \v!leftmargin,\v!rightmargin,\v!leftedge,\v!rightedge,% + \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,% + \v!text,\v!opposite}% \v!page + +\long\def\dodocomplexplacefloat[#1][#2][#3]#4% + {\flushnotes + \flushsidefloats % here ! + \ifsomefloatwaiting + % this was \checkwaitingfloats spread all over + \doifinsetelse\v!always{#2} + {\showmessage\m!floatblocks5\empty} + {\normalexpanded{\noexpand\doifcommonelse{#2}{\flushfloatslist}}\doflushfloats\donothing}% + % but which should be done before using box \floatbox + \fi + \ifmargeblokken + \doifinset\v!margin{#2}\endgraf + \fi + \global\insidefloattrue + \begingroup % ** + \ifmargeblokken + \doifinset\v!margin{#2}{\hsize\@@mbwidth}% + \fi + \the\everyinsidefloat + \let\@@extrafloat\empty + \presetmorefloatvariables{#2}% + \dowithnextboxcontent % better a \the\everyfloattoks + {\setlocalfloathsize + \floatparameter\c!inner + \fuzzysnappingfalse + \postponenotes} % new + {\doifsomething{\floatparameter\c!criterium} + {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax + \edef\forcedfloatmethod{\floatvariable\c!fallback}% + \ifx\forcedfloatmethod\empty\let\forcedfloatmethod\v!here\fi + \fi}% + \xdocompletefloat{#1}{#3}{#2}{#4}% ** not yet done + % we need to carry over the par because of side floats + \doifnotinset\v!text{#2}{\carryoverpar\endgroup}% + \global\sidefloatdownshift \zeropoint + \global\sidefloatextrashift\zeropoint + \ifparfloat + \doifinset\v!reset{#2}\forgetsidefloats + \doinhibitblank + \fi}% better move this to side floats + \vbox} + +\def\xxdocompletefloat#1#2% + {\rightorleftpageaction{\let\@@extrafloat#1}{\let\@@extrafloat#2}} + +\chardef\textfloatmethod=0 % 0=raw 1=safe (.99) 2=tight (-1pt) +\chardef\sidefloatmethod=1 % 0=raw 1=safe (.99) 2=tight (-1pt) + +\let\floatrotation\!!zerocount + +\long\def\presetfloatvariables#1#2#3#4% + {\doifcommonelse + {#2} + {\v!left,\v!right,\v!inner,\v!outer,% + \v!inleft,\v!inright,\v!inmargin,% + \v!backspace,\v!cutspace,% + \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,% + \v!leftmargin,\v!leftedge,\v!rightmargin,\v!rightedge} + {\global\parfloattrue} + {\global\parfloatfalse}% + \ifinsidecolumns + \global\parfloatfalse + \fi + \global\sidefloatshift\zeropoint + \global\sidefloatmaximum\zeropoint + \global\chardef\sidefloatmethod\floatparameter\c!sidemethod + \global\chardef\textfloatmethod\floatparameter\c!textmethod + \global\chardef\sidefloatalign\zerocount + \globallet\floatrotation\!!zerocount + \calculatefloatskips + \ifparfloat + \processaction + [\floatparameter\c!sidealign] + [\v!height=>\global\chardef\sidefloatalign\plusone,% + \v!line=>\global\chardef\sidefloatalign\plustwo,% (***) + \v!depth=>\global\chardef\sidefloatalign\plusthree,% + \v!grid=>\global\chardef\sidefloatalign\plusfour,% + \v!halfline=>\global\chardef\sidefloatalign\plusfive]% + % todo (test first): \doifinset\v!lokaal{#2}{\chardef\sidefloatalign\zerocount}% + \ifcase\sidefloatalign\relax % todo: optie v!lokaal => \else + \doifinset\v!height {#2}{\global\chardef\sidefloatalign\plusone}% + \doifinset\v!line {#2}{\global\chardef\sidefloatalign\plustwo}% + \doifinset\v!depth {#2}{\global\chardef\sidefloatalign\plusthree}% + \doifinset\v!grid {#2}{\global\chardef\sidefloatalign\plusfour}% + \doifinset\v!halfline{#2}{\global\chardef\sidefloatalign\plusfive}% meant for 'none' + \fi + \doifinset\v!high{#2}{\global\sidefloattopskip \zeropoint}% + \doifinset\v!low {#2}{\global\sidefloatbottomskip\zeropoint}% + \doifinset\v!fit {#2} + {\global\sidefloattopskip \zeropoint + \global\sidefloatbottomskip\zeropoint + \global\floatsideskip \zeropoint}% + \else + \processallactionsinset + [#2] + [ 90=>\globallet\floatrotation\commalistelement,% + 180=>\globallet\floatrotation\commalistelement,% + 270=>\globallet\floatrotation\commalistelement]% + \fi + \doifinsetelse\v!nonumber{#2} + {\global\nofloatnumbertrue} + {\doifelse{\floatcaptionparameter\c!number}\v!yes + {\global\nofloatnumberfalse} + {\global\nofloatnumbertrue}}% + % this has to change + \ConvertToConstant\doifelse{#4}{} + {\global\emptyfloatcaptiontrue} + {\global\emptyfloatcaptionfalse}% + \doifinsetelse\v!none{#2} + {\global\nofloatcaptiontrue} + {\ConvertToConstant\doifelse{#4}\v!none + {\global\nofloatcaptiontrue} + {\global\nofloatcaptionfalse}}% + \doif{\floatcaptionparameter\c!number}\v!none % new + {\global\nofloatcaptiontrue}% + \ifemptyfloatcaption \ifnofloatnumber + \global\nofloatcaptiontrue + \fi \fi} + +% documenteren in details + +\def\presetmorefloatvariables#1% + {\doifelse{\floatparameter\c!local}\v!yes % fout keyword + \globalcenterfloatboxtrue + \globalcenterfloatboxfalse + \ifglobalcenterfloatbox + \localcenterfloatboxtrue + \else + \doifinsetelse\v!local{#1} + \localcenterfloatboxtrue + \localcenterfloatboxfalse + \fi + \doifnotcommon{\v!always,\v!here,\v!force}{#1} % ! ! ! ! ! ! + {\globalcenterfloatboxfalse + \localcenterfloatboxfalse}} + +\let\naturalfloatheight\!!zeropoint +\let\naturalfloatwidth \!!zeropoint +\let\naturalfloatdepth \!!zeropoint + +\def\setnaturalfloatdimensions#1% + {\xdef\naturalfloatheight{\the\ht#1}% + \xdef\naturalfloatwidth {\the\wd#1}% + \xdef\naturalfloatdepth {\the\dp#1}} + +\long\def\doifelsemainfloatbody#1#2% + {\ifinsidesplitfloat\ifconditional\splitfloatfirstdone#2\else#1\fi\else#1\fi} + +% todo: optional user pars + +\long\def\docompletefloat#1#2#3#4#5% #1:floatclass #2:reference #3:optionlist #4:caption #5:box number + {\presetfloatvariables{#1}{#3}{#2}{#5}% check this one + \bgroup + % prepare structure data + % + % \dofloatcomponent[\c!name=#1,\c!reference=#2,\c!bookmark=,\c!title={#4}][]% ifnofloatnumber ifnofloatcaption \tracefloatnumber{#1}% + % + \dostructurecountercomponent + {float}% + \getcaptionparameters + \floatcaptionparameter + \detokenizedcaptionparameter + \relax + \relax + \relax + [\c!name=\currentfloat,\s!counter=\currentfloat,% + \s!hascaption=\ifnofloatcaption \v!no\else\v!yes\fi,% + \s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,% + \s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi,% + \c!reference=#2,\c!title={#4},\c!bookmark=]% + []% + \globallet\currentfloatnumber \laststructurecounternumber + \globallet\currentfloatsynchronize\laststructurecountersynchronize + % + % check float box + \setnaturalfloatdimensions#5% + \global\setbox\floatbox\vbox{\floatparameter\c!command{\box#5}}% + \setnaturalfloatdimensions\floatbox + \ifdim\htdp\floatbox=\zeropoint + \showmessage\m!floatblocks{11}\empty + \global\setbox\floatbox\vbox{\doemptyfloatblock{#1}}% + \fi + % deal with lack of caption + \global\setbox\floatbox\vbox + {\doifelsemainfloatbody\currentfloatsynchronize\donothing + \unvbox\floatbox + \ifnofloatcaption + \vss + \fi}% gets rid of the depth (unless tabulate) + \egroup + % place the float + \dofloat{#3}{\thecurrentfloatnumber}{\thecurrentfloatcaption}% + \global\insidefloatfalse} + +\def\setlocalfloathsize + {\iflocalcenterfloatbox + \seteffectivehsize + \hsize\localhsize + \fi} + +\newevery \everyinsidefloat \relax + +\appendtoks + \everyinsidefloat\emptytoks % in case it's called earlier + \dogetfloatdata +\to \everyinsidefloat + +%\appendtoks +% \fuzzysnappingfalse +%\to \everyinsidefloat + +\def\doifrightpagefloatelse + {\ifdoublesided + \ifsinglesided + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\doifoddfloatpageelse + \fi + \else + \@EA\firstoftwoarguments + \fi} + +\def\doifoddfloatpageelse + {\ifodd\purenumber\twopassfloatdata\space + \@EA\firstoftwoarguments + \else + \@EA\secondoftwoarguments + \fi} + +\appendtoks + \let\rightorleftpageaction\doifrightpagefloatelse +\to \everyinsidefloat + +\newif\ifextrafloatactions \extrafloatactionstrue + +% \let\movesidefloat\gobbleoneargument + +% new : \place...[leftmargin,-2*line]; we need to catch fxtb:2*3 +% watch out: line alone aligns on the line ! ! ! + +\def\movesidefloat[#1]% (-)n*line|x=,y= + {\global\sidefloatdownshift \zeropoint + \global\sidefloatextrashift\zeropoint + \doifassignmentelse{#1}% + {\bgroup + \getparameters[\??fl][\c!x=\zeropoint,\c!y=\zeropoint,#1]% + \ifgridsnapping + \getnoflines\@@fly + \global\sidefloatdownshift\noflines\lineheight + \else + \global\sidefloatdownshift\@@fly + \fi + \global\sidefloatextrashift\@@flx + \egroup} + {\movedownsidefloat[#1]}} + +\def\movedownsidefloat[#1]% already in core + {\bgroup + \cleanupfeatures + \doifinstringelse{:}{#1} + \donothing + {\def\docommand##1% + {\processaction + [##1]% + [ \v!line=>\dodocommand+,% + +\v!line=>\dodocommand+,% + -\v!line=>\dodocommand-]}% + \def\dodocommand##1% + {\ifdone\else\global\sidefloatdownshift\zeropoint\donetrue\fi + \global\advance\sidefloatdownshift##1\lineheight}% + \donefalse\normalexpanded{\noexpand\dorepeatwithcommand[#1]}\docommand + \def\docommand##1% + {\processaction + [##1]% + [ \v!hang=>\dodocommand+,% + +\v!hang=>\dodocommand+,% + -\v!hang=>\dodocommand-]}% + \def\dodocommand##1% inefficient but who cares + {\ifdone\else\global\sidefloatsidelines\zeropoint\donetrue\fi + \global\advance\sidefloatsidelines\plusone\relax}% + \donefalse\normalexpanded{\noexpand\dorepeatwithcommand[#1]}\docommand}% + \egroup} + +\def\hangsidefloat[#1]% + {\global\sidefloatsidelines#1\relax} + +\long\def\xdocompletefloat#1#2#3#4% + {\ifextrafloatactions + \doifinsetelse\v!text{#3} + {% fuzzy, text overloads left, since then it's a directive + \docompletefloat{#1}{#2}{#3}{#4}\nextbox} + {\let\@@extrafloat\empty + % \sidefloatdownshift will be reset afterwards, and can + % already be set at this point + \processallactionsinset + [#3] % ininner/inouter : for old times sake + [ \v!inner=>\xxdocompletefloat\v!left \v!right, + \v!outer=>\xxdocompletefloat\v!right \v!left, + \v!innermargin=>\xxdocompletefloat\v!leftmargin \v!rightmargin, + \v!outermargin=>\xxdocompletefloat\v!rightmargin\v!leftmargin, + \v!inneredge=>\xxdocompletefloat\v!leftedge \v!rightedge, + \v!outeredge=>\xxdocompletefloat\v!rightedge \v!leftedge, + \v!backspace=>\xxdocompletefloat\v!backspace \v!cutspace, + \v!cutspace=>\xxdocompletefloat\v!cutspace \v!backspace, +% \v!margin=>\xxdocompletefloat\v!cutspace \v!backspace, + \v!left=>\xxdocompletefloat\v!left \v!left, + \v!right=>\xxdocompletefloat\v!right \v!right, + \v!line=>, % only -n*line is handled (see ***) + \s!unknown=>{\movedownsidefloat[\commalistelement]}]% + \ifx\@@extrafloat\empty + \docompletefloat{#1}{#2}{#3}{#4}\nextbox + \else + \docompletefloat{#1}{#2}{\@@extrafloat,#3}{#4}\nextbox + \fi}% + \else % downward compatible + \docompletefloat{#1}{#2}{#3}{#4}\nextbox + \fi} + +% pas op, maxbreedte niet instellen als plaats=links/rechts + +\def\setlocalfloatdimensions#1% + {\global\sidefloatshift \zeropoint % duplicate + \global\sidefloatmaximum\zeropoint\relax % duplicate + \ifextrafloatactions + \ifdim\sidefloatdownshift=\zeropoint\else + \global\setbox\floatbox\vbox + {\vskip\sidefloatdownshift\nointerlineskip\box\floatbox}% + \fi + \doifsomething{\floatparameter\c!minwidth} + {\scratchdimen\floatparameter\c!minwidth\relax + \ifdim\wd\floatbox<\scratchdimen + \global\setbox\floatbox\hbox to \scratchdimen + {\doifnot{\floatparameter\c!location}\v!left \hss + \box\floatbox% + \doifnot{\floatparameter\c!location}\v!right\hss}% + \fi}% + % todo: rand / rug + \doifinset\v!hanging{#1} + {\doifcommonelse{\v!inleft,\v!leftmargin}{#1} + {\letfloatparameter\c!maxwidth\leftmarginwidth}% + {\doifcommon{\v!inright,\v!rightmargin}{#1} + {\letfloatparameter\c!maxwidth\rightmarginwidth}}}% + \doifsomething{\floatparameter\c!maxwidth} + {\scratchdimen\floatparameter\c!maxwidth\relax + \ifdim\wd\floatbox>\scratchdimen + \doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge + \v!inleft,\v!leftmargin,\v!leftedge}{#1} + {\global\sidefloatmaximum\scratchdimen} + {\global\setbox\floatbox\hbox to \scratchdimen + {\doifcommonelse{\v!right,\v!left}{#1} + {\doifnotinset\v!right{#1}\hss + \box\floatbox + \doifnotinset\v!left{#1}\hss}% + {\doifnot{\floatparameter\c!location}\v!left\hss + \box\floatbox + \doifnot{\floatparameter\c!location}\v!right\hss}}}% + \fi}% + \fi} + +\def\docomplexstarttextblock[#1][#2][#3]% + {\flushnotes + \flushsidefloats % hoort eigenlijk niet hier + \docomplexplacefloat[#1][\v!text,#2,\v!left][#3]} + +\long\def\docomplexreserveblock[#1][#2][#3][#4]#5% + {\getvalue{\e!place#1}[#3][#4]{#5}{\localframed[\??fl#1][#2]{#1}}} + +\def\docomplexstartreservetextblock[#1][#2][#3][#4]% + {\flushsidefloats % hoort eigenlijk niet hier + \docomplexreserveblock[#1][#2][\v!text,#3,\v!left][#4]} + +\def\placefloat + {\dotripleempty\docomplexplacefloat} + +\installinsertion\topins +\installinsertion\botins + +\newdimen\botinserted +\newdimen\topinserted + +%D Extra float registers. + +\newif\ifsomefloatwaiting \somefloatwaitingfalse +\newif\ifroomforfloat \roomforfloattrue +\newif\ifnofloatpermitted \nofloatpermittedfalse + +\newcount\totalnoffloats \totalnoffloats =0 +\newcount\savednoffloats \savednoffloats =0 +\newcount\noffloatinserts \noffloatinserts=0 + +\newbox\floatlist +\newbox\savedfloatlist + +\newif\ifflushingfloats \flushingfloatsfalse + +\newbox\floattext + +\newdimen\floattextwidth +\newdimen\floattextheight + +\newbox\floatbox +\newbox\savedfloatbox + +\newdimen\floatwidth +\newdimen\floatheight + +% In \dofloatinfomessage wordt {{ }} gebruikt omdat anders +% binnen \startpostponing...\stoppostponing geen goede +% melding in de marge volgt: \ifinner is dan namelijk true. + +\def\dofloatinfomessage#1#2#3% + {\bgroup + \showmessage\m!floatblocks{#2}{#3}% + \setmessagetext\m!floatblocks{#2}% + \@EA\floatinfo\@EA#1\@EA{\currentmessagetext}% + \egroup} + +\def\dosavefloatinfo + {\dofloatinfomessage>2{\the\totalnoffloats}} + +\def\dofloatflushedinfo + {\bgroup + \!!counta\totalnoffloats + \advance\!!counta -\savednoffloats + \dofloatinfomessage<3{\the\!!counta}% + \egroup} + +\def\doinsertfloatinfo + {\dofloatinfomessage<4{\the\totalnoffloats}} + +\def\dogetfloat + {\ifsomefloatwaiting + \global\setbox\floatlist\vbox + {\unvbox\floatlist + \global\setbox\globalscratchbox\lastbox}% + \ifcenterfloatbox + \ifdim\wd\globalscratchbox<\hsize + \setbox\floatbox\hbox to \hsize{\hss\box\globalscratchbox\hss}% + \else + \setbox\floatbox\box\globalscratchbox % local ! + % retain special alignments + \ifinsidecolumns + \ifdim\wd\floatbox>\makeupwidth + \wd\floatbox\makeupwidth + \fi + \fi + \fi + \else + \setbox\floatbox\box\globalscratchbox % local ! + \fi + \global\advance\savednoffloats \minusone + \ifcase\savednoffloats + \global\somefloatwaitingfalse + \fi + \else + \global\savednoffloats\zerocount + \global\setbox\floatbox\emptybox + \fi} + +\def\uncenteredfloatbox + {\ifcenterfloatbox + \ifhbox\floatbox\relax % remove centering + \ifdim\wd\floatbox=\hsize + \ifhbox\floatbox + \setbox\scratchbox\hbox + {\unhbox\floatbox + \unskip\unskip + \global\setbox\globalscratchbox\lastbox}% + \box\globalscratchbox + \else + \box\floatbox + \fi + \else + \box\floatbox + \fi + \else + \box\floatbox + \fi + \else + \box\floatbox + \fi} + +\def\dosavefloat + {\global\setbox\floatlist\vbox + {\nointerlineskip + \uncenteredfloatbox + \unvbox\floatlist}% + \global\advance\savednoffloats \plusone + \global\somefloatwaitingtrue + \dosavefloatinfo + \nonoindentation} + +\def\doresavefloat + {\global\setbox\floatlist\vbox + {\nointerlineskip + \unvbox\floatlist + \uncenteredfloatbox}% + \global\advance\savednoffloats \plusone + \global\somefloatwaitingtrue} + +\def\doreversesavefloat + {\global\setbox\floatlist\vbox + {\nointerlineskip + \unvbox\floatlist + \uncenteredfloatbox}% + \global\advance\savednoffloats \plusone + \global\somefloatwaitingtrue + \dosavefloatinfo} + +% better (todo): \savednofsavedfloats + +\def\dosavefloatstatus + {\global\setbox\savedfloatlist\copy\floatlist + \global\setbox\savedfloatbox \copy\floatbox + \xdef\dorestorefloatstatus + {\global\setbox\floatlist\box\savedfloatlist + \global\setbox\floatbox \box\savedfloatbox + \global\savednoffloats\the\savednoffloats}} + +\let\dorestorefloatstatus\relax + +\ifx\doflushfloats\undefined \let\doflushfloats\relax \fi +\ifx\flushfloatbox\undefined \let\flushfloatbox\relax \fi + +% needed in the splitter: + +\newcount\savedsavednoffloats + +\let\dopopsavedfloats\relax + +\def\dopushsavedfloats + {\global\setbox\savedfloatlist\box\floatlist + \global\savedsavednoffloats\savednoffloats + \global\savednoffloats\savednoffloats + \global\somefloatwaitingfalse + \gdef\dopopsavedfloats + {\global\advance\savednoffloats\savedsavednoffloats + \global\setbox\floatlist\vbox\bgroup + \ifvoid\floatlist \else\unvbox\floatlist \fi + \ifvoid\savedfloatlist\else\unvbox\savedfloatlist\fi + \egroup + \global\ifcase\savednoffloats + \somefloatwaitingfalse\else\somefloatwaitingtrue\fi + \globallet\dopopsavedfloats\relax}} + +\def\doflushsavedfloats % simplified \OTRONEdodoflushfloats + {\doloop + {\ifsomefloatwaiting + \dogetfloat + \dofloatflushedinfo + \docheckiffloatfits + \ifroomforfloat + \doplacefloatbox + \else + \doreversesavefloat + \exitloop + \fi + \else + \exitloop + \fi}} + +% top and bottom + +\newif\iftopofinsert +\newif\iftestfloatbox +\newif\ifcenterfloatbox \centerfloatboxtrue +\newif\iflocalcenterfloatbox \localcenterfloatboxfalse +\newif\ifglobalcenterfloatbox \globalcenterfloatboxfalse + +% beter de laatste skip buiten de \insert uitvoeren, +% bovendien bij volle flush onder baseline. + +\def\betweenfloatblanko% assumes that spaceafter is present + {\bgroup + \setbox0\vbox{\strut\blank[\floatsharedparameter\c!spacebefore]\strut}% + \setbox2\vbox{\strut\blank[\floatsharedparameter\c!spaceafter]\strut}% + \ifdim\ht0>\ht2 + \blank[-\floatsharedparameter\c!spaceafter,\floatsharedparameter\c!spacebefore]% + \fi + \egroup} + +\def\doplacefloatbox + {%\forgetall % NO + \whitespace + \blank[\floatsharedparameter\c!spacebefore] + \flushfloatbox + \blank[\floatsharedparameter\c!spaceafter]} + +\ifx\someherefloat\undefined \let\someherefloat\doplacefloatbox \fi +\ifx\somefixdfloat\undefined \let\somefixdfloat\doplacefloatbox \fi +\ifx\somepagefloat\undefined \let\somepagefloat\doplacefloatbox \fi +\ifx\sometopsfloat\undefined \let\sometopsfloat\doplacefloatbox \fi +\ifx\somebotsfloat\undefined \let\somebotsfloat\doplacefloatbox \fi + +\ifx\somesidefloat\undefined \let\somesidefloat\doplacefloatbox \fi +\ifx\somefacefloat\undefined \let\somefacefloat\doplacefloatbox \fi +\ifx\sometextfloat\undefined \let\sometextfloat\doplacefloatbox \fi + +% brr, wordt deze niet overladen in page-one? weg er mee + +% \def\somepagefloat[#1]% links, rechts, midden, hoog, midden, laag +% {%\checkwaitingfloats{#1}% +% \global\setbox\collectedpagefloats\vbox +% {\unvbox\collectedpagefloats +% \vbox to \textheight +% {\doifnotinset\v!high{#1}\vfill +% \box\floatbox +% \doifnotinset\v!low{#1}\vfill}% +% \goodbreak}% +% \doinsertfloatinfo} + +% \def\OTRONEsomepagefloat[#1]% +% {%\checkwaitingfloats{#1}% +% \global\setbox\collectedpagefloats\vbox +% {\ifvoid\collectedpagefloats\else\unvbox\collectedpagefloats\fi +% \vbox to \textheight % vss and unvbox catch too high and limited floats +% {\vss +% \doifnotinset\v!high{#1}\vfill +% \unvbox\floatbox +% \doifnotinset\v!low{#1}\vfill +% \vss}% +% \goodbreak}% +% \doinsertfloatinfo} + +% test case: +% +% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=0.9\textheight,color=green]} +% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.0\textheight,color=green]} +% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.1\textheight,color=green]} + +\def\sometextfloat[#1]% lang, links, rechts, hoog, midden, laag, offset + {%\checkwaitingfloats{#1}% + \gdef\dostoptextfloat{\dodostoptextfloat[#1]}% brr global + \global\floattextwidth\hsize + \global\floatwidth\wd\floatbox + \global\floatheight\ht\floatbox % forget about the depth + \global\advance\floattextwidth -\floatwidth + \global\advance\floattextwidth -\floatsharedparameter\c!margin\relax % was \tfskipsize + \doifinsetelse\v!tall{#1} + {\floattextheight\pagegoal + \advance\floattextheight -\pagetotal + \advance\floattextheight -\bigskipamount % lelijk + \ifdim\floattextheight>\textheight + \floattextheight\textheight + \fi + \boxmaxdepth\zeropoint \relax % toegevoegd + \ifdim\floattextheight<\floatheight + \floattextheight\floatheight + \fi + \setbox\floattext\vbox to \floattextheight} + {\setbox\floattext\vbox}% + \bgroup + \forgetall \setupblank \setupwhitespace % new, also needed for footnotes + \blank[\v!disable] + \hsize\floattextwidth + \ignorespaces} + +\def\dodostoptextfloat[#1]% % de tekst kan beter in een soort + {\egroup % kadertekst zonder kader, is flexibeler + \doifnotinset\v!tall{#1}% en beter + {\ifdim\ht\floattext<\floatheight + \floattextheight\floatheight + \else + \floattextheight\ht\floattext + \fi}% + \setbox\floatbox\vbox to \floattextheight + {\hsize\floatwidth + \doifinsetelse\v!both{#1}% + {\doifinsetelse\v!low{#1} + {\vfill\box\floatbox} + {\doifinsetelse\v!middle{#1} + {\vfill\box\floatbox\vfill} + {\box\floatbox\vfill}}} + {\box\floatbox\vfill}}% + \setbox\floattext\vbox to \floattextheight + {\hsize\floattextwidth + \doifinsetelse\v!low{#1} + {\vfill + \box\floattext + \doifinset\c!offset{#1}{\whitespace\blank}} + {\doifinsetelse\v!middle{#1} + {\vfill + \box\floattext + \vfill} + {\doifinset\v!offset{#1}{\whitespace\blank}% + \box\floattext + \vfill}}}% + \doifinsetelse\v!right{#1}% \floatmethod + {\setbox\floatbox\hbox to \hsize + {\box\floattext + \hfill + \box\floatbox}} + {\setbox\floatbox\hbox to \hsize + {\box\floatbox + \hfill + \box\floattext}}% + \baselinecorrection + \whitespace + \blank[\floatsharedparameter\c!spacebefore]% + \doifnotinset\v!tall{#1}% + {\dp\floatbox\openstrutdepth}% dp\strutbox}% % toegevoegd + \box\floatbox + \blank[\floatsharedparameter\c!spaceafter]% + \endgroup % ** + \doinsertfloatinfo} + +\def\somefacefloat[#1]% links, rechts, midden, hoog, midden, laag + {%\checkwaitingfloats{#1}% + \startopposite\box\floatbox\stopopposite + \doinsertfloatinfo} + +\def\someelsefloat[#1]% + {\doifinsetelse\v!here{#1} + {\doifinsetelse\v!always{#1} + {\page[\v!preference]% + \docheckiffloatfits + \ifroomforfloat + \placesomeherefloat[#1]% + \else + \showmessage\m!floatblocks9\empty + \doreversesavefloat + \fi} + {\ifsomefloatwaiting + \dosavefloat + \else + \page[\v!preference]% + \docheckiffloatfits + \ifroomforfloat + \placesomeherefloat[#1]% + \else + \dosavefloat + \fi + \fi}} + {\doifinsetelse\v!always{#1} + {\docheckiffloatfits + \ifroomforfloat + \sometopbottomfloat[#1] + \else + \showmessage\m!floatblocks9\empty + \doreversesavefloat + \fi} + {\docheckiffloatfits + \ifroomforfloat + \sometopbottomfloat[#1] + \else + \dosavefloat + \fi}}} + +\def\floatautofactor{.5} + +\def\sometopbottomfloat[#1]% + {\doifelse\floatmethod\v!auto + {\ifdim\pagetotal<\floatautofactor\pagegoal % when empty page, maxdimen + \placesometopsfloat[#1]% + \else + \placesomebotsfloat[#1]% + \fi} + {\doifelse\floatmethod\v!top + {\placesometopsfloat[#1]} + {\doifelse\floatmethod\v!bottom + {\placesomebotsfloat[#1]} + {\placesomeherefloat[#1]}}}} + +% De onderstaande macro wordt gebruikt bij de macros +% voor het plaatsen van tabellen en figuren (klopt niet +% meer). +% +% \dofloat {plaats} {label1} {label2} +% \docompletefloat {nummer} {referentie} {plaats} {label} {inhoud} +% \box\floatbox inhoud+referentie +% \do???float#1 #1 = boxnummer + +\newdimen\floatsideskip \floatsideskip =12pt +\newdimen\floattopskip \floattopskip =\floattopskip +\newdimen\floatbottomskip \floatbottomskip=\floattopskip + +\newdimen\sidefloattopskip \sidefloattopskip =\floattopskip +\newdimen\sidefloatbottomskip \sidefloatbottomskip=\floatbottomskip + +\newskip\sidefloatdownshift +\newskip\sidefloatleftshift +\newskip\sidefloatrightshift + +\def\sidefloattopoffset {\openstrutdepth} % {\strutdp} + +\newcount\noftopfloats \noftopfloats=2 +\newcount\nofbotfloats \nofbotfloats=0 + +\def\docalculatefloatskip#1#2% + {\doifelsenothing{#2} + {\global#1\zeropoint} + {\doifelse{#2}\v!none + {\global#1\zeropoint} + {\setbox\scratchbox\vbox{\whitespace\normalexpanded{\noexpand\blank[#2]}}% + \global#1\ht\scratchbox}}} + +\def\calculatefloatskips + {{\docalculatefloatskip\floattopskip{\floatsharedparameter\c!spacebefore}% + \docalculatefloatskip\floatbottomskip{\floatsharedparameter\c!spaceafter}% + \docalculatefloatskip\sidefloattopskip{\floatsharedparameter\c!sidespacebefore}% + \docalculatefloatskip\sidefloatbottomskip{\floatsharedparameter\c!sidespaceafter}% + \gdef\sidefloattopoffset{\openstrutdepth}% was \def + \global\floatsideskip\floatsharedparameter\c!margin + \global\sidefloatleftshift\floatparameter\c!leftmargindistance + \global\sidefloatrightshift\floatparameter\c!rightmargindistance + \global\noftopfloats\floatsharedparameter\c!ntop\relax + \global\nofbotfloats\floatsharedparameter\c!nbottom\relax}} + +\def\borderedfloatbox + {\localframed + [\??fl\currentfloat] + [\c!location=\v!normal,\c!width=\wd\floatbox,\c!height=\htdp\floatbox] + {\box\floatbox}} + +\newbox\tempfloatbox + +% minwidth=fit,width=max : no overshoot, as wide as graphic + +\ifx\moveboxontogrid\undefined \let\movecaptionontogrid\gobblethreearguments \fi + +\def\locatefloatbox + {\chardef\alignstrutmode\zerocount + \shiftalignedline + {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}% + {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}% + \alignedline{\floatparameter\c!location}\v!middle} + +\def\locatecaptionbox + {\chardef\alignstrutmode\zerocount + \shiftalignedline + {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}% + {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}% + \alignedline{\floatparameter\c!location}\v!middle} + +\long\def\dosetpagfloat#1#2#3% \copy wegwerken + {\bgroup + \setlocalfloathsize + \ifnum\floatrotation>0 + \swapdimens\hsize\vsize + \fi + \forgetall + \postponenotes + \dontcomplain + \setbox\tempfloatbox\vbox{\borderedfloatbox}% + \let\locatefloat \locatefloatbox + \let\locatecaption\locatecaptionbox + \docheckcaptioncontent{#2}{#3}% + \ifcase\floatparameter\c!method + \or % automatic + \ifnofloatcaption + \dopreparenocaption{#1}{#2}{#3}% + \edef\width{\the\wd\floatbox}% + \doglobal\addlocalbackgroundtobox\floatbox + \else + % todo: installable maken, variant/method=auto vs macro + \dopreparedocaption{#1}{#2}{#3}% + \settracedcaptionbox + \edef\width{\the\wd\tempfloatbox}% + \addlocalbackgroundtobox\tempfloatbox + \setbox\tempcaptionbox\hbox + {\dosetcaptionthings + \floatcaptionparameter\c!command{\box\tempcaptionbox}}% + \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht + \addlocalbackgroundtobox\tempcaptionbox + \buildfloatbox + \fi + \or % semi automatic + \or % manual + \fi + \ifnum\floatrotation>0 + \global\setbox\floatbox\vbox + {\rotate[\c!rotation=\floatrotation]{\box\floatbox}}% + \edef\width{\the\wd\tempfloatbox}% + \else + \postcenterfloatbox\width + \fi + \egroup} + +\def\captionminwidth {15\bodyfontsize} +\def\captionovershoot {2em} + +\def\dopreparenocaption#1#2#3% + {\global\setbox\floatbox\vbox % pas op als wd groter dan hsize + {\ifinsidecolumns\ifdim\wd\tempfloatbox>\hsize + \let\locatefloat\relax + \fi\fi + \locatefloat{\copy\tempfloatbox}}} + +\def\dopreparedocaption#1#2#3% + {\doifinsetelse{\floatcaptionparameter\c!location}{\v!top,\v!bottom} + {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max} + {\doifelse{\floatcaptionparameter\c!minwidth}\v!fit + {\doifelse{\floatcaptionparameter\c!width}\v!max + {\dopreparestackcaptionmax{#1}{#2}{#3}} + {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox % wider caption + \doifelse{\floatcaptionparameter\c!width}\v!fit + {\dopreparestackcaptionaut{#1}{#2}{#3}} + {\dopreparestackcaptionwid{#1}{#2}{#3}}% + \else + \dopreparestackcaptionmin{#1}{#2}{#3}% + \fi}} + {\dopreparestackcaptionfix{#1}{#2}{#3}}}% + {\dopreparesidewidthcaption{#1}{#2}{#3}}}% new, special effects (see icare) + {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max} + {\dopreparesideautocaption{#1}{#2}{#3}} + {\dopreparesidewidthcaption{#1}{#2}{#3}}}} + +% \def\dosettempcaptionbox +% {\dosetraggedvbox{\floatcaptionparameter\c!align}% +% \setbox\tempcaptionbox\raggedbox} + +\def\dosettempcaptionbox + {\setbox\tempcaptionbox\vbox\bgroup + %expanded{\setupalign[\v!new,\v!reset,\floatcaptionparameter\c!align,\v!old]}% wrong! see icare + \normalexpanded{\noexpand\setupalign[\v!reset,\floatcaptionparameter\c!align]}% i need to check what reset does + \dosetcaptionthings + \let\next} + +\def\dopreparesideautocaption#1#2#3% + {\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\floatparameter\c!margin\relax % was \tfskipsize\relax + \ifdim\wd\tempcaptionbox>\scratchdimen + \ifdim\wd\tempcaptionbox<1.3\scratchdimen + \scratchdimen0.8\scratchdimen + \fi + \fi + \dosettempcaptionbox + {\hsize\scratchdimen + \putcompletecaption{#2}{#3}}} + +\def\dopreparesidewidthcaption#1#2#3% + {\dosettempcaptionbox + {\hsize\floatcaptionparameter\c!width + \putcompletecaption{#2}{#3}}} + +\def\dopreparestackcaptionfix#1#2#3% + {\dosettempcaptionbox + {\hsize\floatcaptionparameter\c!minwidth % special effects + \putcompletecaption{#2}{#3}}} + +\def\dopreparestackcaptionmax#1#2#3% + {\dosettempcaptionbox + {\hsize\wd\tempfloatbox + \putcompletecaption{#2}{#3}}} + +\def\dopreparestackcaptionwid#1#2#3% + {\dosettempcaptionbox + {\hsize\floatcaptionparameter\c!width + \putcompletecaption{#2}{#3}}} + +\def\dopreparestackcaptionmin#1#2#3% + {\dosettempcaptionbox + {\hsize\wd\tempfloatbox + \doifnothing{\floatcaptionparameter\c!align}\raggedcenter % on purpose overloads align ! + \putcompletecaption{#2}{#3}}} + +\def\dopreparestackcaptionaut#1#2#3% + {\doifsomething{\floatcaptionparameter\c!align} + {\doifnotinset{\v!middle}{\floatcaptionparameter\c!align}% + {\let\captionovershoot\!!zeropoint}}% + \edef\captionhsize{\the\wd\tempfloatbox}% + \ifdim\captionhsize>\hsize + % float is wider than \hsize + \dosettempcaptionbox + {\trialtypesettingtrue + \hsize\captionhsize + \notesenabledfalse + \putcompletecaption{#2}{#3}}% + \ifdim\ht\scratchbox>\lineheight % more lines + \dosettempcaptionbox + {\hsize\captionhsize + \advance\hsize -\captionovershoot\relax + \ifdim\hsize<\captionminwidth\relax + \hsize\captionhsize + \fi + \putcompletecaption{#2}{#3}}% + \else + \dosettempcaptionbox + {\hsize\captionhsize + \putcompletecaption{#2}{#3}}% + \fi + \else + % float is smaller of equal to \hsize + \ifdim\captionhsize<\captionminwidth\relax + \scratchdimen\captionminwidth % float smaller than min width + \edef\captionhsize{\the\scratchdimen}% + \fi + \setbox\scratchbox\vbox % test with overshoot + {\trialtypesettingtrue + \scratchdimen\captionhsize + \advance\scratchdimen \captionovershoot + \advance\scratchdimen 3em % an average word length + \ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi + \notesenabledfalse + \putcompletecaption{#2}{#3}}% + \ifdim\ht\scratchbox>\lineheight + % at least an average word longer than a line + \dosettempcaptionbox + {\scratchdimen\captionhsize + \advance\scratchdimen \captionovershoot + \ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi + \putcompletecaption{#2}{#3}}% + \else + % just over a line, don't use an overshoot % % % todo: outer/inner and such + \doifcommonelse{\floatcaptionparameter\c!align}{\v!left,\v!right,\v!flushleft,\v!flushright} + {\dosettempcaptionbox + {\hsize\captionhsize + % strange : \raggedcenter + \putcompletecaption{#2}{#3}}} + {% nicer + \dosettempcaptionbox + {\hsize\captionhsize + \doifnothing{\floatcaptionparameter\c!align}\raggedcenter% overloads + \putcompletecaption{#2}{#3}}}% + \fi + \fi} + +\def\dopreparesidecaption#1#2#3% + {\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\floatparameter\c!margin\relax % was \tfskipsize\relax + \ifdim\wd\tempcaptionbox>\scratchdimen + \ifdim\wd\tempcaptionbox<1.3\scratchdimen + \scratchdimen0.8\scratchdimen + \fi + \fi + \dosettempcaptionbox % \setbox\tempcaptionbox\vbox + {\hsize\scratchdimen + \doifnothing{\floatcaptionparameter\c!align}\raggedright % on purpose overloads align ! + \putcompletecaption{#2}{#3}}} + +\newdimen\tempfloatheight +\newdimen\tempfloatwidth + +\def\dofloatboxbetweenstack + {\endgraf\nointerlineskip\floatcaptionparameter\c!inbetween\endgraf} + +\def\dofloatboxdefaultbuilder % done + {\locatefloat{\box\tempfloatbox}} + +\def\dofloatboxnextrightbuilder#1% + {\ifparfloat \hbox \else \expandafter \locatefloat \fi + {\tempfloatheight\ht\tempfloatbox + \box\tempfloatbox + \normalexpanded{\noexpand\doifnotinset{\v!hang}{\floatcaptionparameter\c!location}}{\dotfskip{\floatcaptionparameter\c!distance}}% + \vbox to\tempfloatheight{#1}}} + +\def\dofloatboxnextleftbuilder#1% + {\ifparfloat \hbox \else \expandafter \locatefloat \fi + {\tempfloatheight\ht\tempfloatbox + \vbox to\tempfloatheight{#1}% + \normalexpanded{\noexpand\doifnotinset{\v!hang}{\floatcaptionparameter\c!location}}{\dotfskip{\floatcaptionparameter\c!distance}}% + \box\tempfloatbox}} + +\def\dofloatboxnextouterbuilder + {\doifrightpagefloatelse\dofloatboxnextrightbuilder\dofloatboxnextleftbuilder} +\def\dofloatboxnextinnerbuilder + {\doifrightpagefloatelse\dofloatboxnextleftbuilder\dofloatboxnextrightbuilder} + +\def\dofloatboxnextrighthangbuilder#1% + {\ifparfloat \hbox \else \expandafter \locatefloat \fi + {\tempfloatheight\ht\tempfloatbox + \box\tempfloatbox + \vbox to\tempfloatheight{#1}}} + +\def\dofloatboxnextlefthangbuilder#1% + {\ifparfloat \hbox \else \expandafter \locatefloat \fi + {\tempfloatheight\ht\tempfloatbox + \vbox to\tempfloatheight{#1}% + \box\tempfloatbox}} + +\def\dodofloatboxnextrightmarginbuilder#1#2% + {\ifparfloat + \hbox\bgroup + \tempfloatheight\ht\tempfloatbox + \box\tempfloatbox + \hsmash{\hskip#1\vbox to\tempfloatheight{#2}}% + \egroup + \else + \begingroup + \tempfloatheight\ht\tempfloatbox + \everyrightofalignedline{\hsmash{\hskip#1\vbox to\tempfloatheight{#2}}}% + \locatefloat{\box\tempfloatbox}% + \endgroup + \fi} + +\def\dodofloatboxnextleftmarginbuilder#1#2% + {\ifparfloat + \hbox\bgroup + \tempfloatheight\ht\tempfloatbox + \hsmash{\hskip-\dimexpr#1+\wd\tempcaptionbox\relax\vbox to\tempfloatheight{#2}}% + \box\tempfloatbox + \egroup + \else + \begingroup + \tempfloatheight\ht\tempfloatbox + \everyleftofalignedline{\hsmash{\hskip-\dimexpr#1+\wd\tempcaptionbox\relax\vbox to\tempfloatheight{#2}}}% + \locatefloat{\box\tempfloatbox}% + \endgroup + \fi} + +\def\dofloatboxnextrightmarginbuilder{\dodofloatboxnextrightmarginbuilder\rightmargindistance} +\def\dofloatboxnextleftmarginbuilder {\dodofloatboxnextleftmarginbuilder \leftmargindistance } + +\def\dofloatboxnextoutermarginbuilder + {\doifrightpagefloatelse + {\dodofloatboxnextrightmarginbuilder\rightmargindistance} + {\dodofloatboxnextleftmarginbuilder \rightmargindistance}} + +\def\dofloatboxnextinnermarginbuilder + {\doifrightpagefloatelse + {\dodofloatboxnextleftmarginbuilder \leftmargindistance} + {\dodofloatboxnextrightmarginbuilder\leftmargindistance}} + +\def\dofloatboxnextbuilder % beware, we first check on left/rightmargin because there can be left/right also + {\let\next\dofloatboxnextleftbuilder + \normalexpanded{\noexpand\processallactionsinset[\floatcaptionparameter\c!location]} + [ \v!outermargin=>\let\next\dofloatboxnextoutermarginbuilder, + \v!innermargin=>\let\next\dofloatboxnextinnermarginbuilder, + \v!leftmargin=>\let\next\dofloatboxnextleftmarginbuilder, + \v!rightmargin=>\let\next\dofloatboxnextrightmarginbuilder, + \v!lefthanging=>\let\next\dofloatboxnextlefthangbuilder, + \v!righthanging=>\let\next\dofloatboxnextrighthangbuilder, + \v!outer=>\let\next\dofloatboxnextouterbuilder, + \v!inner=>\let\next\dofloatboxnextinnerbuilder, + \v!left=>\let\next\dofloatboxnextleftbuilder, + \v!right=>\let\next\dofloatboxnextrightbuilder]% + \next} + +\def\dofloatboxsidebuilder + {\ifparfloat + \let\next\dofloatboxhighbuilder + \else + \let\next\dofloatboxmiddlebuilder + \expanded{\processallactionsinset[\floatcaptionparameter\c!location]} + [ \v!low=>\let\next\dofloatboxlowbuilder, + \v!middle=>\let\next\dofloatboxmiddlebuilder, + \v!high=>\let\next\dofloatboxhighbuilder]% + \fi + \next} + +\def\doflushfloatleftcaptionhang + {\hsmash{\llap{\box\tempcaptionbox\dotfskip{\floatcaptionparameter\c!distance}}}} +\def\doflushfloatrightcaptionhang + {\hsmash{\rlap{\dotfskip{\floatcaptionparameter\c!distance}\box\tempcaptionbox}}} + +\def\doflushfloatcaptionhang + {\expanded{\doifinsetelse{\v!righthanging}{\floatcaptionparameter\c!location}} + {\doflushfloatrightcaptionhang} + {\expanded{\doifinsetelse{\v!lefthanging}{\floatcaptionparameter\c!location}} + {\doflushfloatleftcaptionhang} + {\expanded{\doifinsetelse{\v!hang}{\floatcaptionparameter\c!location}} + {\expanded{\doifinsetelse{\v!outer}{\floatcaptionparameter\c!location}} + {\doifrightpagefloatelse{\doflushfloatrightcaptionhang}{\doflushfloatleftcaptionhang}} + {\expanded{\doifinsetelse{\v!right}{\floatcaptiondirectives}} + {\doflushfloatrightcaptionhang} + {\doflushfloatleftcaptionhang}}} + {\box\tempcaptionbox}}}} + +\def\dofloatboxhighbuilder + {\dofloatboxnextbuilder{\dofloatboxbetweenstack\doflushfloatcaptionhang\vfill}} + +\def\dofloatboxlowbuilder + {\dofloatboxnextbuilder{\vfill\doflushfloatcaptionhang\dofloatboxbetweenstack}} + +\def\dofloatboxmiddlebuilder + {\dofloatboxnextbuilder{\vfill\box\tempcaptionbox\vfill}} + +% \definefloat +% [lefty][lefties][figure] +% \setupfloat +% [lefty] +% [default=left, +% rightmargindistance=-2cm, +% leftmargindistance=-2cm] +% \setupcaption +% [lefty] +% [location={bottom,overlay}] +% +% \starttext +% \placelefty{}{} \input tufte \input tufte +% \placelefty{}{} \input tufte \input tufte +% \stoptext + +\def\bothangfloat#1{\ruledvbox to \ht\tempfloatbox{#1\vss}} +\def\tophangfloat#1{\ruledvbox to \ht\tempfloatbox{\vss#1}} + +\def\dofloatboxnormaltopstackbuilder + {\expanded{\doifinset{\v!overlay}{\floatcaptionparameter\c!location}}\tophangfloat + {\tempfloatwidth\wd\tempfloatbox + \ifparfloat + \hbox{\locatesidefloat{\box\tempcaptionbox}}% + \dofloatboxbetweenstack + \hbox{\hbox {\box\tempfloatbox }}% + \else + \hbox{\locatetextfloat{\box\tempcaptionbox}} + \dofloatboxbetweenstack + \hbox{\locatefloat {\box\tempfloatbox }}% + \fi}} + +\def\dofloatboxnormalbotstackbuilder + {\expanded{\doifinset{\v!overlay}{\floatcaptionparameter\c!location}}\bothangfloat + {\tempfloatwidth\wd\tempfloatbox + \ifparfloat + \hbox{\hbox {\box\tempfloatbox }}% + \dofloatboxbetweenstack + \hbox{\locatesidefloat{\box\tempcaptionbox}}% + \else + \hbox{\locatefloat {\box\tempfloatbox }}% + \dofloatboxbetweenstack + \hbox{\locatetextfloat{\box\tempcaptionbox}}% + \fi}} + +\def\dofloatboxgridtopstackbuilder + {\dp\tempcaptionbox\strutdepth + \setbox\scratchbox\vbox + {\tempfloatwidth\wd\tempfloatbox + \ifparfloat + \locatesidefloat{\box\tempcaptionbox}% + \vss\dofloatboxbetweenstack + \hbox {\box\tempfloatbox }% + \else + \locatetextfloat{\box\tempcaptionbox}% + \vss\dofloatboxbetweenstack + \locatefloat {\box\tempfloatbox }% + \fi}% + \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy + \vbox to \noflines\lineheight{\unvbox\scratchbox}} + +\def\dofloatboxgridbotstackbuilder + {\dp\tempcaptionbox\strutdepth + \setbox\scratchbox\vbox + {\tempfloatwidth\wd\tempfloatbox + \ifparfloat + \hbox {\box\tempfloatbox }% + \vss\dofloatboxbetweenstack + \locatesidefloat{\box\tempcaptionbox}% + \else + \locatefloat {\box\tempfloatbox }% + \vss\dofloatboxbetweenstack + \locatetextfloat{\box\tempcaptionbox}% + \fi}% + \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy + \vbox to \noflines\lineheight{\unvbox\scratchbox}} + +\def\dofloatboxstretchtopstackbuilder + {\dp\tempcaptionbox\strutdepth + \setbox\scratchbox\vbox + {\locatecaption{\copy\tempcaptionbox}% + \locatefloat {\copy\tempfloatbox }}% + \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy + \vbox to \noflines\lineheight + {\tempfloatwidth\wd\tempfloatbox + \ifparfloat + \locatesidefloat{\box\tempcaptionbox}% + \vss\dofloatboxbetweenstack\vss + \hbox {\box\tempfloatbox }% + \else + \locatetextfloat{\box\tempcaptionbox}% + \vss\dofloatboxbetweenstack\vss + \locatefloat {\box\tempfloatbox }% + \fi}} + +\def\dofloatboxstretchbotstackbuilder + {\dp\tempcaptionbox\strutdepth + \setbox\scratchbox\vbox + {\locatefloat {\copy\tempfloatbox }% + \locatecaption{\copy\tempcaptionbox}}% + \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy + \vbox to \noflines\lineheight + {\tempfloatwidth\wd\tempfloatbox + \ifparfloat + \hbox {\box\tempfloatbox }% + \vss\dofloatboxbetweenstack\vss + \locatesidefloat{\box\tempcaptionbox} + \else + \locatefloat {\box\tempfloatbox }% + \vss\dofloatboxbetweenstack\vss + \locatetextfloat{\box\tempcaptionbox}% + \fi}} + +\def\dofloatboxtopbuilder + {\let\next\dofloatboxnormaltopstackbuilder + \expanded{\processfirstactioninset[\floatcaptionparameter\c!location]} + [ \v!grid=>\let\next\dofloatboxgridstackbuilder, + \v!stretch=>\let\next\dofloatboxstretchstackbuilder]% + \next} + +\def\dofloatboxbottombuilder + {\let\next\dofloatboxnormalbotstackbuilder + \expanded{\processfirstactioninset[\floatcaptionparameter\c!location]} + [ \v!grid=>\let\next\dofloatboxgridstackbuilder, + \v!stretch=>\let\next\dofloatboxstretchstackbuilder]% + \next} + +\def\relocatecaptionright#1{\locatecaption{\hbox to \tempfloatwidth{\hss#1}}} +\def\relocatecaptionleft #1{\locatecaption{\hbox to \tempfloatwidth{#1\hss}}} + +\long\def\installfloatboxbuilder#1#2{\setvalue{\??kj:#1}{#2}} + +\def\buildfloatbox + {\global\setbox\floatbox\vbox + {\setlocalfloathsize + \forgetall + \let\floatcaptionarrangement\s!default + \def\docommand##1% + {\doifdefined{\??kj:##1}{\def\floatcaptionarrangement{##1}\quitcommalist}}% + \processcommacommand[\floatcaptionparameter\c!location]\docommand + \executeifdefined{\??kj:\floatcaptionarrangement}{\getvalue{\??kj:\s!default}}}} + +\def\locatetextfloat + {\let\next\locatecaption + \expanded{\processallactionsinset[\floatcaptionparameter\c!location]} + [ \v!left=>\let\next\relocatecaptionleft, + \v!right=>\let\next\relocatecaptionright, + \v!inner=>\doifrightpagefloatelse{\let\next\relocatecaptionleft }{\let\next\relocatecaptionright}, + \v!outer=>\doifrightpagefloatelse{\let\next\relocatecaptionright}{\let\next\relocatecaptionleft }]% + \next} + +\installfloatboxbuilder \v!none \dofloatboxdefaultbuilder +\installfloatboxbuilder \s!default \dofloatboxdefaultbuilder +\installfloatboxbuilder \v!high \dofloatboxhighbuilder +\installfloatboxbuilder \v!low \dofloatboxlowbuilder +\installfloatboxbuilder \v!middle \dofloatboxmiddlebuilder + +\installfloatboxbuilder \v!left \dofloatboxsidebuilder +\installfloatboxbuilder \v!right \dofloatboxsidebuilder + +\installfloatboxbuilder \v!top \dofloatboxtopbuilder +\installfloatboxbuilder \v!bottom \dofloatboxbottombuilder + +% \setuplayout[grid=yes] \showgrid \setupcaptions[style=smallbodyfont,location=grid,inbetween=] +% +% \starttext +% test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=yes]} test \page +% test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=yes]} test \page +% test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=depth]} test \page +% test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=depth]} test \page +% \stoptext + +\newif\ifpostponecolumnfloats \postponecolumnfloatsfalse % don't change + +\chardef\postcenterfloatmethod\plusone + +\def\postcenterfloatbox#1% + {\scratchdimen + \ifcase\postcenterfloatmethod + #1% \wd\floatbox + \or\ifinsidecolumns + \ifpostponecolumnfloats\makeupwidth\else#1\fi + \else\ifdim#1>\hsize + \hsize + \else + \wd\floatbox + \fi\fi\fi + \global\setbox\floatbox\hbox to \scratchdimen + % {\hfill\box\floatbox\hfill}} % geen \hss, gaat mis in kolommen ! + % {\hss \box\floatbox\hss }} % wel \hss, anders mis in colset + {\ifglobalcenterfloatbox + \donetrue + \else\iflocalcenterfloatbox + \donetrue + \else + \donefalse + \fi\fi + \ifdim\scratchdimen>\effectivehsize + \donefalse + \fi + \hss\ifdone\hskip\effectiveleftskip\fi + \box\floatbox + \ifdone\hskip\effectiverightskip\fi\hss}} + +\long\def\dosetparfloat#1#2#3% + {\bgroup + \forgetall + \postponenotes + \dontcomplain + %\showcomposition + \setbox\tempfloatbox\vbox{\borderedfloatbox}% + \addlocalbackgroundtobox\tempfloatbox % no \doglobal + \docheckcaptioncontent{#2}{#3}% + \ifnofloatcaption + \global\setbox\floatbox\vbox{\box\tempfloatbox}% + \else + \dopreparedosidecaption{#1}{#2}{#3}% + \settracedcaptionbox + \setbox\tempcaptionbox\hbox{\floatcaptionparameter\c!command{\box\tempcaptionbox}}% + \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht + \addlocalbackgroundtobox\tempcaptionbox % no \doglobal + \buildsidefloatbox + \fi + \egroup} + +\def\dopreparedosidecaption#1#2#3% will be enhanced + {\doifelse{\floatcaptionparameter\c!width}\v!max + {\dosettempcaptionbox + {\hsize\wd\tempfloatbox + \putcompletecaption{#2}{#3}}}% + {\doifelse{\floatcaptionparameter\c!width}\v!fit + {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox\relax + \setbox\tempcaptionbox\vbox + {\forgetall % needed? + \hsize\wd\tempfloatbox + \dosetcaptionthings + \putcompletecaption{#2}{#3}}% + \else + \setbox\tempcaptionbox\hbox to \wd\tempfloatbox + {\hss\box\tempcaptionbox\hss}% + \fi} + {\dosettempcaptionbox + {\hsize\floatcaptionparameter\c!width % \wd\tempfloatbox + \putcompletecaption{#2}{#3}}}}} + +\def\buildsidefloatbox + {\let\locatefloat \relax + \let\locatecaption\relax + \def\locatesidefloat##1% + {\begingroup + \chardef\alignstrutmode\zerocount + \hsize\tempfloatwidth \forgetall + \alignedline{\floatparameter\c!location}\v!middle{##1}% + \endgroup}% + \buildfloatbox} + +\newif\ifparfloat + +\long\def\dosetfloatbox#1#2#3% todo : \global\setbox + {\ifvisible + \par + \edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}% + \ifparfloat\@EA\dosetparfloat\else\@EA\dosetpagfloat\fi{#1}{#2}{#3}% + \setlocalfloatdimensions{#1}% + \setbox\floatbox\hbox + {\dosavefloatdata\restoretextcolor{\box\floatbox}}% + \global\floatheight\ht\floatbox + \global\advance\floatheight \dp\floatbox + \global\floatwidth\wd\floatbox + \global\advance\totalnoffloats \plusone + \doifnotinset\v!margin{#1} % gaat namelijk nog fout + {\setbox\floatbox\vbox + {\parindent\zeropoint + \doifconcepttracing{\inleftmargin{\framed{\infofont\the\totalnoffloats}}}% + \box\floatbox}}% + \wd\floatbox\floatwidth + \dimen0=\floatheight + \advance\dimen0 \lineheight + \ifdim\dimen0<\textheight + \else + \global\floatheight\textheight + \global\advance\floatheight -\lineheight + \ht\floatbox\floatheight + \dp\floatbox\zeropoint + \showmessage\m!floatblocks{10}{\the\totalnoffloats}% + \fi + \fi} + +\newcounter\noxfloatlocations + +\long\def\dofloat#1#2#3% #1 is optionlist + {\dosetfloatbox{#1}{#2}{#3}% + \dogetfloatbox{#1}\empty} + +\def\dooutput{\sidefloatoutput} % redefinition of \dooutput + +\definefloat + [\v!figure] + [\v!figures] + +\definefloat + [\v!table] + [\v!tables] + +\setupfloat + [\v!table] + [\c!frame=\v!off] + +\definefloat + [\v!intermezzo] + [\v!intermezzi] + +\definefloat + [\v!graphic] + [\v!graphics] + +% float strategy, replaces some of the above macros + +\let\floatmethod \empty +\let\floatcolumn \empty +\let\floatrow \empty +\let\forcedfloatmethod\empty + +\def\dogetfloatbox#1#2% + {\ifvisible + \doifelsenothing{#2} + {\getfromcommalist[#1][1]% + \@EA\beforesplitstring\commalistelement\at:\to\floatmethod + \@EA\aftersplitstring \commalistelement\at:\to\floatcolumn + \@EA\aftersplitstring \floatcolumn\at*\to\floatrow + \@EA\beforesplitstring\floatcolumn\at*\to\floatcolumn + % todo: nog algemeen otr + \ifx\OTRSETsetpreferedcolumnslot\undefined\else + \OTRSETsetpreferedcolumnslot\floatcolumn\floatrow + \fi} + {\let\floatcolumn\empty + \let\floatrow\empty + \edef\floatmethod{#2}}% + \doifundefined{\string\floatmethod\floatmethod} + {\let\floatmethod\v!here}% + \doifsomething\forcedfloatmethod + {\edef\floatmethod{\forcedfloatmethod}}% + %\getvalue{\string\floatmethod\floatmethod}[#1]% + \getvalue{\string\floatmethod\floatmethod}[\floatmethod,#1]% + \fi} + +\def\installfloathandler#1#2% #1=keyword #2=handler + {\setvalue{\string\floatmethod#1}{#2}} + +\installfloathandler \v!here \someherefloat +\installfloathandler \v!force \somefixdfloat +\installfloathandler \v!left \someleftsidefloat +\installfloathandler \v!right \somerightsidefloat +\installfloathandler \v!text \sometextfloat +\installfloathandler \v!top \sometopfloat +\installfloathandler \v!bottom \somebottomfloat +\installfloathandler \v!auto \someautofloat +\installfloathandler \v!margin \somemarginfloat +\installfloathandler \v!opposite \somefacefloat +\installfloathandler \v!page \somepagefloat +\installfloathandler \v!leftpage \someleftpagefloat +\installfloathandler \v!rightpage \somerightpagefloat +\installfloathandler \v!inmargin \someinmarginfloat +\installfloathandler \v!inleft \someinleftmarginfloat +\installfloathandler \v!inright \someinrightmarginfloat +\installfloathandler \v!leftmargin \someinleftmarginfloat +\installfloathandler \v!rightmargin \someinrightmarginfloat +\installfloathandler \v!leftedge \someinleftedgefloat +\installfloathandler \v!rightedge \someinrightedgefloat + +\installfloathandler \v!backspace \somebackspacefloat +\installfloathandler \v!cutspace \somecutspacefloat + +\installfloathandler {tblr} \someslotfloat +\installfloathandler {lrtb} \someslotfloat +\installfloathandler {tbrl} \someslotfloat +\installfloathandler {rltb} \someslotfloat +\installfloathandler {btlr} \someslotfloat +\installfloathandler {lrbt} \someslotfloat +\installfloathandler {btrl} \someslotfloat +\installfloathandler {rlbt} \someslotfloat +\installfloathandler {fxtb} \someslotfloat +\installfloathandler {fxbt} \someslotfloat + +\def\placesomeslotfloat {\OTRcommand\someslotfloat} +\def\placesomeherefloat {\OTRcommand\someherefloat} +\def\placesomefixdfloat {\OTRcommand\somefixdfloat} +\def\placesomepagefloat {\OTRcommand\somepagefloat} +\def\placesomeleftpagefloat {\OTRcommand\someleftpagefloat} +\def\placesomerightpagefloat{\OTRcommand\somerightpagefloat} +\def\placesometopsfloat {\OTRcommand\sometopsfloat} +\def\placesomebotsfloat {\OTRcommand\somebotsfloat} +\def\placesomesidefloat {\OTRcommand\somesidefloat} +\def\placesomefacefloat {\OTRcommand\somefacefloat} + +\def\someleftsidefloat [#1]{\somesidefloat[#1]\presetindentation} +\def\somerightsidefloat [#1]{\somesidefloat[#1]} +\def\sometopfloat [#1]{\someelsefloat[#1]\nonoindentation} +\def\somebottomfloat [#1]{\someelsefloat[#1]} +\def\someautofloat [#1]{\someelsefloat[#1]} +\def\somemarginfloat [#1]{\somenextfloat[#1]\nonoindentation} +\def\someinleftmarginfloat [#1]{\somesidefloat[#1]} +\def\someinrightmarginfloat[#1]{\somesidefloat[#1]} +\def\someinleftedgefloat [#1]{\somesidefloat[#1]} +\def\someinrightedgefloat [#1]{\somesidefloat[#1]} +\def\someinmarginfloat [#1]{\somesidefloat[#1]} +\def\someherefloat [#1]{\someelsefloat[\v!here,#1]} + +\def\somebackspacefloat [#1]{\somesidefloat[#1]} +\def\somecutspacefloat [#1]{\somesidefloat[#1]} + +\def\somefixdfloat {\placesomefixdfloat} +\def\somepagefloat {\placesomepagefloat} +\def\someleftpagefloat {\placesomeleftpagefloat} +\def\somerightpagefloat{\placesomerightpagefloat} +\def\somefacefloat {\placesomefacefloat} +\def\someslotfloat {\placesomeslotfloat} + +\protect \endinput diff --git a/tex/context/base/strc-flt.tex b/tex/context/base/strc-flt.tex deleted file mode 100644 index b0ff9893b..000000000 --- a/tex/context/base/strc-flt.tex +++ /dev/null @@ -1,2173 +0,0 @@ -%D \module -%D [ file=strc-flt, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Float Numbering, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Float Numbering} - -\registerctxluafile{strc-flt}{1.001} - -\unprotect - -%D This module needs a cleanup and will be split in -%D strc-flt.tex and page-flt.mkiv cq. page-flt.mkii. - -\ifx\addlocalbackgroundtobox\undefined \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi - -\def\placefloats{\doflushfloats} % keep this one - -\let\currentfloat\empty - -\def\letfloatparameter #1{\expandafter\csname\??fl\currentfloat#1\endcsname} - -\def\floatparameter #1{\csname\dofloatparameter{\??fl\currentfloat}#1\endcsname} -\def\floatsharedparameter#1{\csname \??fl #1\endcsname} -\def\floatparameterhash #1{\dofloatparameterhash {\??fl\currentfloat}#1} - -\def\dofloatparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dofloatparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\dofloatparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dofloatparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dofloatparentparameter #1#2{\ifx#1\relax\s!empty\else\dofloatparameter #1#2\fi} -\def\dofloatparentparameterhash#1#2{\ifx#1\relax \else\dofloatparameterhash#1#2\fi} - -\def\detokenizedfloatparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??fl\currentfloat#1\endcsname}} - -\def\dosetfloatattributes#1#2% style color - {\edef\fontattributehash {\floatparameterhash#1}% - \edef\colorattributehash{\floatparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -\def\floatcaptionparameter #1{\csname\dofloatcaptionparameter{\??kj\currentfloat}#1\endcsname} -\def\floatcaptionparameterhash#1{\dofloatcaptionparameterhash {\??kj\currentfloat}#1} - -\def\dofloatcaptionparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dofloatcaptionparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\dofloatcaptionparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dofloatcaptionparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dofloatcaptionparentparameter #1#2{\ifx#1\relax\s!empty\else\dofloatcaptionparameter #1#2\fi} -\def\dofloatcaptionparentparameterhash#1#2{\ifx#1\relax \else\dofloatcaptionparameterhash#1#2\fi} - -\def\detokenizedcaptionparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??kj\currentfloat#1\endcsname}} - -\def\dosetfloatcaptionattributes#1#2% style color - {\edef\fontattributehash {\floatcaptionparameterhash#1}% - \edef\colorattributehash{\floatcaptionparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -\def\dohandlenextfloatindent - {\checknextindentation[\floatparameter\c!indentnext]% - \dorechecknextindentation} - -%D The two shared (parent) definitions: - -% todo: everysetupfloat everysetupcaption for all floats - -\def\setupfloats {\dosingleargument\dosetupfloats} % was \??bk -\def\setupcaptions{\dosingleargument\dosetupcaptions} - -\let\alldefinedfloats\empty - -\def\doprocessallfloats#1% - {\def\doprocesssomefloat##1{\def\currentfloat{##1}#1}% - \processcommacommand[\alldefinedfloats]\doprocesssomefloat} - -\def\dosetupfloats [#1]{\getparameters[\??fl][#1]\doprocessallfloats{\the\everysetupfloat}} -\def\dosetupcaptions[#1]{\getparameters[\??kj][#1]\doprocessallfloats{\the\everysetupcaption}} - -% \def\dosetupfloats [#1]{\getparameters[\??fl][#1]} -% \def\dosetupcaptions[#1]{\getparameters[\??kj][#1]} - -\setupcaptions - [\c!location=\v!bottom, - \c!grid=, - \c!before=, % not used (yet) - \c!inbetween={\blank[\v!medium]}, - \c!after=, % not used (yet) - \c!spacebefore=, - \c!spaceinbetween=, % replaces fuzzy inbetween dual usage - \c!spaceafter=, - \c!width=\v!fit, - \c!minwidth=\v!fit, % id est: the width of the floatbox in some cases - \c!headstyle=\v!bold, - \c!headcolor=, - \c!leftmargin=\zeropoint, - \c!rightmargin=\zeropoint, - \c!outermargin=\zeropoint, - \c!innermargin=\zeropoint, - \c!setups=, - \c!style=\v!normal, - \c!color=, - \c!textstyle=, - \c!textcolor=, - \c!align=, - \c!number=\v!yes, -\c!prefix=\v!no, -\c!prefixconnector=., -\c!way=bychapter, -\c!prefixsegments=2:2, -% \c!way=\@@nrway, -% \c!blockway=\@@nrblockway, -% \c!sectionnumber=\@@nrsectionnumber, -% \c!separator=\@@koseparator, -% \c!stopper=\@@kostopper, -% \c!suffix=\floatcaptionsuffix, % hook - \c!distance=1em, - \c!conversion=\v!numbers, - \c!command=] - -% we can comment some of these - -\setupfloats - [\c!location=\v!middle, - \c!width=8\lineheight, - \c!height=6\lineheight, - \c!offset=\v!overlay, - \c!frame=\v!off, - \c!strut=\v!no, - \c!radius=.5\bodyfontsize, - \c!corner=\v!rectangular, - \c!background=, - \c!backgroundscreen=, - \c!backgroundcolor=, - \c!backgroundoffset=\!!zeropoint, - \c!topframe=, - \c!bottomframe=, - \c!leftframe=, - \c!rightframe=, - \c!frameoffset=\!!zeropoint, - \c!before=, - \c!after=, - \c!spacebefore=\v!big, - \c!spaceafter=\v!big, - \c!sidespacebefore=\floatsharedparameter\c!spacebefore, - \c!sidespaceafter=\floatsharedparameter\c!spaceafter, - \c!sidealign=\v!normal, - \c!textmethod=\ifgridsnapping2\else0\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) - \c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) - \c!indentnext=\v!no, - \c!margin=1em, - \c!method=1, - \c!cache=\v!yes, % when no, then intermediate flush - \c!leftmargin=\zeropoint, % displacement in 'normal floats' - \c!rightmargin=\zeropoint, % idem - \c!innermargin=\zeropoint, % idem - \c!outermargin=\zeropoint, % idem - \c!leftmargindistance=\zeropoint, - \c!rightmargindistance=\floatparameter\c!leftmargindistance, - \c!ntop=2, - \c!nbottom=0, - \c!nlines=4, - \c!local=, - \c!bottombefore=, % e.g. \vfill - \c!bottomafter=, - \c!default=\v!figure, - \c!numbering=\v!yes] - -\def\@@bknumbering {\floatsharedparameter\c!numbering } % global one -\def\@@bkspaceafter {\floatsharedparameter\c!spaceafter } % global one -\def\@@bkspacebefore{\floatsharedparameter\c!spacebefore} % global one -\def\@@bknbottom {\floatsharedparameter\c!nbottom } % global one -\def\@@bkntop {\floatsharedparameter\c!ntop } % global one -\def\@@bknlines {\floatsharedparameter\c!nlines } % global one -\def\@@bkmargin {\floatsharedparameter\c!margin } % global one -\def\@@bkcache {\floatsharedparameter\c!cache } % global one - -% float -% -% [%\c!width=8\lineheight, % 15\bodyfontsize, -% %\c!height=6\lineheight, % 10\bodyfontsize, -% \c!offset=\v!overlay, -% \c!width=\v!fit, -% \c!height=\v!fit, -% \c!minwidth=, -% \c!maxwidth=, -% \c!maxheight=, -% \c!criterium=, -% % inherited -% \c!pageboundaries=, -% \c!default=]% - -% number -% -% [\c!text=#1, -% \c!location=\v!intext, -% \c!way=\floatcaptionparameter\c!way, -% \c!blockway=\floatcaptionparameter\c!blockway, -% \c!sectionnumber=\floatcaptionparameter\c!sectionnumber, -% \c!conversion=\floatcaptionparameter\c!conversion]% - - -%D Individial settings: - -\def\setupfloat {\dodoubleargument\dosetupfloat} -\def\setupcaption{\dodoubleargument\dosetupcaption} - -\newtoks\everysetupfloat -\newtoks\everysetupcaption - -\def\dosetupfloat[#1][#2]% - {\def\docommand##1{\getparameters[\??fl##1][#2]\the\everysetupfloat}% - \processcommalist[#1]\docommand} - -\def\dosetupcaption[#1][#2]% - {\def\docommand##1{\getparameters[\??kj##1][#2]\the\everysetupcaption}% - \processcommalist[#1]\docommand} - -\appendtoks - \dostructurecountersetup\currentfloat\floatcaptionparameter -\to \everysetupcaption - -%D Definitions: - -\def\definefloat - {\dotripleempty\dodefinefloat} - -\def\dodefinefloat[#1][#2][#3]% #1=naam #2=meervoud #3=parent - {\ifthirdargument - \redodefinefloat[#1][#2][#3]% - \else\ifsecondargument - \dododefinefloat[#1][#2]% - \else - \dododefinefloat[#1][#1]% - \fi\fi} - -\presetlocalframed[\??fl] - -\def\dododefinefloat[#1][#2]% - {\copylocalframed[\??fl#1][\??fl]% - \definestructurecounter[#1]% - \addtocommalist{#1}\alldefinedfloats - \setupfloat[#1][\s!parent=\??fl]% - \setupcaption[#1][\s!parent=\??kj]% - \definelist[#1]% - \presetlabeltext[#1=\Word{#1}~]% - \presetheadtext[#2=\Word{#2}]% - \dodefinefloatcommands[#1][#2]% - }% \newnodelocation{\v!float\@@thenumber{#1}}} - -\def\redodefinefloat[#1][#2][#3]% - {\copylocalframed[\??fl#1][\??fl#3]% - \setupfloat[#1][\s!parent=\??fl#3]% - \setupcaption[#1][\s!parent=\??kj#3]% - \definestructurecounter[#1][#3]% - \definelist[#1][#3]% - \presetlabeltext[#1=\Word{#3}]% - \presetheadtext[#2=\Word{#2}]% - \dodefinefloatcommands[#1][#2]} - -\def\dodefinefloatcommands[#1][#2]% - {\setvalue {\e!place\e!listof#2}{\dodoubleempty\doplacelist[#1]}% - \setvalue {\e!complete\e!listof#2}{\dotripleempty\dodocompletelist[#1][#2]}% - \setvalue {\e!place#1}{\dotripleempty\docomplexplacefloat[#1]}% - \setvalue {\e!reserve#1}{\doquadrupleempty\docomplexreserveblock[#1]}% - \setvalue {\e!start#1\e!text}{\dotripleempty\docomplexstarttextblock[#1]}% - \setvalue {\e!stop#1\e!text}{\dostoptextfloat}% - \setvalue{\e!start\e!reserve#1\e!text}{\doquadrupleempty\docomplexstartreservetextblock[#1]}% - \setvalue {\e!stop\e!reserve#1\e!text}{\dostoptextfloat}% - \setvalue {\e!emptyone#1}{\doemptyfloatblock{#1}}% - \setvalue {\e!emptytwo#1}{\doemptyfloatblock{#1}}} - -%D Fallback float body: - -\def\doemptyfloatblock#1% - {\framed - [\c!frame=\v!on, - \c!width=\floatsharedparameter\c!width, - \c!height=\floatsharedparameter\c!height, - \c!location=\v!normal, - \c!offset=\floatsharedparameter\c!offset]% - {\getmessage\m!floatblocks{12}\empty}} - -%D Data. We can generalize this to lists. - -\newif\ifnofloatcaption -\newif\ifnofloatnumber -\newif\ifemptyfloatcaption - -\def\getfloatparameters {\getparameters[\??fl\currentfloat]} -\def\getcaptionparameters{\getparameters[\??kj\currentfloat]} - -\installstructurelistprocessor{float}{\usestructurelistprocessor{number+title}} - -\def\thecurrentfloatnumber - {\ifnofloatcaption \else \ifnofloatnumber \else -% \labeltexts\currentfloat{\convertedstructurecounter[\currentfloat]}% ! ! todo: use a lua call instead -\ifx\currentfloatnumber\relax\else - \labeltexts\currentfloat{\ctxlua{structure.lists.savednumber("\currentfloat",\currentfloatnumber)}}% -\fi - \fi \fi} - -\def\thecurrentfloatcaption - {\ifnofloatcaption \else -\ifx\currentfloatnumber\relax\else - \ctxlua{structure.lists.savedtitle("\currentfloat",\currentfloatnumber)}% -\fi - \fi} - -%D Captions. - -\let\floatcaptionsuffix\empty % an optional suffix -\let\floatcaptionnumber\empty % a logical counter - -% the split is needed when for instance the float goes into -% a multi page field and the list of figs becomes larger than -% one page: cycle between 'only flush when object ref ok' -% and 'one/many page fig list'; see "uguide finometer" -% -% potential sync bug with sectionblocks, see uguide.tex - -% NOT YET REDONE ! ! ! ! ! - - \def\placefloatcaption - {\dodoubleempty\doplacefloatcaption} - - \long\def\doplacefloatcaption[#1][#2]#3% - {\setfloatcaption[#1][#2]{#3}% - \placefloatcaptiontext[#1]% - \placefloatcaptionreference[#1]} - - \def\setfloatcaption % \dosetfloatcaption already in use - {\dodoubleempty\dodosetfloatcaption} % beware, name clash - - \long\def\dodosetfloatcaption[#1][#2]#3% to do namespace for number/ascii - {\ifnofloatnumber % also handle trialtypesetting - \letgvalue{@fl@r@#1}\relax - \letgvalue{@fl@t@#1}\relax - \else - \preparefloatnumber{#1}% - \letgvalue{@fl@n@#1}\composedsectionnumber - % indirect macro can be more efficient - \setgvalue{@fl@r@#1}% - {\tracefloatnumber{#1}% - \ifconditional\retainfloatnumber\else - % \dowritetolist{#1}{\getvalue{@fl@n@#1}}{#3}{#1}% - % \gdefconvertedargument\flasciititle{#3}% \asciititle is global - % \doifsomething{#2}{\rawreference\s!flt{#2}{{\getvalue{@fl@n@#1}}{\flasciititle}}}% - \fi - \letgvalue{@fl@r@#1}\relax}% nils - \setgvalue{@fl@t@#1}% - {\preparefullnumber{\??kj#1}{\getvalue{@fl@n@#1}}\preparednumber - \begingroup - \dosetfloatcaptionattributes\c!style\c!color - \begingroup - \dosetfloatcaptionattributes\c!headstyle\c!headcolor - \labeltexts{#1}{\preparednumber}% - \endgroup - \begingroup - \dosetfloatcaptionattributes\c!textstyle\c!textcolor - \dotfskip{\floatcaptionparameter\c!distance}#3% - \endgroup - \endgroup}% - \fi} - - \long\def\dodosetfloatcaption[#1][#2]#3% to do namespace for number/ascii - {\letgvalue{@fl@r@#1}\relax - \letgvalue{@fl@t@#1}\relax} - - \def\placefloatcaptiontext [#1]{\getvalue{@fl@t@#1}} - \def\placefloatcaptionnumber [#1]{\getvalue{@fl@n@#1}} - \def\placefloatcaptionreference[#1]{\getvalue{@fl@r@#1}} - - % still needed for uguide - - \let\placefloatlabel \placefloatcaption - \let\placefloatlabeltext \placefloatcaptiontext - \let\placefloatlabelreference \placefloatcaptionreference - -% TILL HERE - -\newbox\captionbox - -\long\def\putcompletecaption#1#2% - {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}% - %\floatcaptionparameter\c!before % test for side effects first - \noindent - \gdef\lastcaptiontag{\strut#1}% was xdef - \begingroup - \dosetfloatcaptionattributes\c!style\c!color - \ifnofloatnumber - \else - \hbox{\dosetfloatcaptionattributes\c!headstyle\c!headcolor\strut#1}% - \ifnofloatcaption \else \ifemptyfloatcaption \else - \doifelsenothing{\floatcaptionparameter\c!spaceinbetween} - {\scratchskip\floatcaptionparameter\c!distance\relax - \dotfskip\scratchskip\emergencystretch.5\scratchskip} - {\blank[\floatcaptionparameter\c!spaceinbetween]}% - \fi \fi - \fi - \ifnofloatcaption - \globallet\lastcaptionht\!!zeropoint - \globallet\lastcaptiondp\!!zeropoint - \else - \dosetfloatcaptionattributes\c!textstyle\c!textcolor - \xdef\lastcaptionht{\strutheight}% - \xdef\lastcaptiondp{\strutdepth}% - \begstrut#2\endstrut\endgraf - \fi - \endgroup - %\floatcaptionparameter\c!after % test for side effects first - \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}} - -\let\lastcaptionht\!!zeropoint -\let\lastcaptiondp\!!zeropoint - -\newbox\tempcaptionbox - -\newif\iftracecaptions - -\def\settracedcaptionbox - {\iftracecaptions\setbox\tempcaptionbox\ruledhbox{\box\tempcaptionbox}\fi} - -% \definefloat [figure-1] [figure] -% \definefloat [figure-2] [figure] -% \setupfloat [figure-1] [location=left,leftmargin=10mm] -% \setupfloat [figure-2] [location=left,leftmargin=-5mm] -% \setupcaption [figure-1] [align=flushleft] -% \setupcaption [figure-2] [align=flushleft,leftmargin=15mm] -% -% \startsetups somefigure -% \ifdim\wd\nextbox>\textwidth -% \placefloat[figure-2][][]{}{\box\nextbox} -% \else -% \placefloat[figure-1][][]{}{\box\nextbox} -% \fi -% \stopsetups -% -% \def\setupswithbox[#1]{\dowithnextbox{\setups[#1]}\vbox} -% -% test \setupswithbox[somefigure]{\framed[width=3cm] {}} test -% test \setupswithbox[somefigure]{\framed[width=\dimexpr\textwidth+3cm\relax]{}} test - -\def\dosetcaptionthings - {\setups[\floatcaptionparameter\c!setups]% expanded ? - %\advance\leftskip \floatcaptionparameter\c!leftmargin - %\advance\rightskip\floatcaptionparameter\c!rightmargin - \relax} - -\def\dofakecaptionthings - {\hbox{\dosetcaptionthings\hskip\leftskip\hskip\rightskip}} - -\long\def\docheckcaptioncontent#1#2% - {\ifnofloatcaption \else - \setbox\tempcaptionbox\hbox - {\trialtypesettingtrue - \notesenabledfalse - \putcompletecaption{#1}{#2}}% - % new, \placefigure{\XMLflush{somecaption}}{} passes earlier empty check - % so here we misuse the scratch box; actually this means that the previous - % test can go away (some day, when i redo this module) - \ifdim\wd\tempcaptionbox=\zeropoint - \global\emptyfloatcaptiontrue - \ifnofloatnumber - \global\nofloatcaptiontrue - \fi - \else - \setbox\tempcaptionbox\hbox{\dosetcaptionthings\hskip\leftskip\box\tempcaptionbox}% yet incomplete - \fi - \fi} - -% the tricky part of getting float related two pass data is -% that we should fetch is early but can only save it with -% the composed float box; this determines the order: get it -% before saving it - -\definetwopasslist{\s!float\s!data} \newcounter\noffloatdata - -\let\twopassfloatdata\realpageno % used for odd/even determination, can be combined with nodelocation - -\def\dosavefloatdata % \expanded - {\doglobal\increment\noffloatdata - \lazysavetaggedtwopassdata{\s!float\s!data}{\noffloatdata}{\noffloatpages}{\noexpand\realfolio}}% later {}{}{}{} and \getfirst... - -\def\dogetfloatdata % precedes save ! - {\doglobal\increment\noffloatpages - \findtwopassdata{\s!float\s!data}{\noffloatpages}% - \iftwopassdatafound - \globallet\twopassfloatdata\twopassdata - \else - \globallet\twopassfloatdata\realpageno % \realfolio - \fi} - -\def\tracefloatnumber#1% - {\doifnot{\floatsharedparameter\c!numbering}\v!nocheck{\tagnodelocation{\v!float\@@thenumber{#1}}}} - -\newconditional\retainfloatnumber - -\def\preparefloatnumber#1% - {\xdef\floatcaptionnumber{#1}% - \doifelsenodelocation{\v!float\@@thenumber{#1}} - \donothing {\chardef\nodelocationmode\zerocount}% - \doifelse{\floatsharedparameter\c!numbering}\v!nocheck - {\incrementnumber[#1]% - \makesectionnumber[#1]% - \ifconditional\retainfloatnumber\decrementnumber[#1]\fi} - {\ifinsidecolumns - \chardef\nodelocationmode\zerocount - % to be perfected: - % \chardef\nodelocationmode\plustwo - \fi -% FOR THE MOMENT NOT AVAILABLE -\chardef\nodelocationmode\zerocount -% BUT NOT THAT HARD TO DO - \ifcase\nodelocationmode - \incrementnumber[#1]% - \makesectionnumber[#1]% - \ifconditional\retainfloatnumber\decrementnumber[#1]\fi - \else - % force check, so that we get a proper way-sync and - % can use the accumulated number - % \checknumber[#1]% \incrementnumber does this - \incrementnumber[#1]% - \savenumber[#1]% - % the real work is done here - \nextnodelocation{\v!float\@@thenumber{#1}}% better \nextfloatnumber - \analyzenodelocation{\v!float\@@thenumber{#1}}% - \scratchcounter\getnodelocationo{\v!float\@@thenumber{#1}}% - \advance\scratchcounter\minusone - % here we correct for 'per whatever handling' - \advance\scratchcounter-\accumulatednumber[#1]% - \setnumber[#1]\scratchcounter - \incrementnumber[#1]% - \makesectionnumber[#1]% - \restorenumber[#1]% - % now we're back to normal numbering - \fi}} - -%D test case: -%D -%D \starttyping -%D \setupfloat[figure][criterium=\marginwidth,fallback=bottom] -%D \dorecurse{3}{ -%D \chapter{test} -%D \placefigure[bottom]{1}{\framed{bottom}} -%D test -%D \placetable[bottom]{1}{\framed{table}} -%D test -%D \placetable{2}{\framed{table}} -%D test -%D \placefigure[left]{2}{\framed{left but way too wide}} -%D \input tufte -%D \placefigure[left]{3}{\framed{left but ok}} -%D \input tufte } -%D \stoptyping - -% A complication is that we may have to handle a pagebreak -% first, which in turn may issue a (postponed) float. -% Therefore we may not trust on variable assignments before -% we're realy dealing with the float. Some day I'll root out -% the global settings. - -\def\docomplexplacefloat[#1][#2]% [#3]#4% - {\edef\currentfloat{#1}% - \doifnothing\currentfloat{\let\currentfloat\v!figure}% - \doifelsenothing{#2} - {\edef\floatlocation{\floatparameter\c!default}} - {\edef\floatlocation{#2}}% - \doifinsetelse\v!split{#2} - {\normalexpanded{\noexpand\dodocomplexsplitfloat[\currentfloat][\floatlocation]}} - {\normalexpanded{\noexpand\dodocomplexplacefloat[\currentfloat][\floatlocation]}}} - -\long\def\dodocomplexsplitfloat[#1][#2][#3]#4% - {\splitfloat{\dodocomplexplacefloat[#1][#2][#3]{#4}}} - -\def\flushfloatslist - {\v!left,\v!right,\v!inner,\v!outer,% - \v!backspace,\v!cutspace,% - \v!inleft,\v!inright,\v!inmargin,% - \v!leftmargin,\v!rightmargin,\v!leftedge,\v!rightedge,% - \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,% - \v!text,\v!opposite}% \v!page - -\long\def\dodocomplexplacefloat[#1][#2][#3]#4% - {\flushnotes - \flushsidefloats % here ! - \ifsomefloatwaiting - % this was \checkwaitingfloats spread all over - \doifinsetelse\v!always{#2} - {\showmessage\m!floatblocks5\empty} - {\normalexpanded{\noexpand\doifcommonelse{#2}{\flushfloatslist}}\doflushfloats\donothing}% - % but which should be done before using box \floatbox - \fi - \ifmargeblokken - \doifinset\v!margin{#2}\endgraf - \fi - \global\insidefloattrue - \begingroup % ** - \ifmargeblokken - \doifinset\v!margin{#2}{\hsize\@@mbwidth}% - \fi - \the\everyinsidefloat - \let\@@extrafloat\empty - \presetmorefloatvariables{#2}% - \dowithnextboxcontent % better a \the\everyfloattoks - {\setlocalfloathsize - \floatparameter\c!inner - \fuzzysnappingfalse - \postponenotes} % new - {\doifsomething{\floatparameter\c!criterium} - {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax - \edef\forcedfloatmethod{\floatvariable\c!fallback}% - \ifx\forcedfloatmethod\empty\let\forcedfloatmethod\v!here\fi - \fi}% - \xdocompletefloat{#1}{#3}{#2}{#4}% ** not yet done - % we need to carry over the par because of side floats - \doifnotinset\v!text{#2}{\carryoverpar\endgroup}% - \global\sidefloatdownshift \zeropoint - \global\sidefloatextrashift\zeropoint - \ifparfloat - \doifinset\v!reset{#2}\forgetsidefloats - \doinhibitblank - \fi}% better move this to side floats - \vbox} - -\def\xxdocompletefloat#1#2% - {\rightorleftpageaction{\let\@@extrafloat#1}{\let\@@extrafloat#2}} - -\chardef\textfloatmethod=0 % 0=raw 1=safe (.99) 2=tight (-1pt) -\chardef\sidefloatmethod=1 % 0=raw 1=safe (.99) 2=tight (-1pt) - -\let\floatrotation\!!zerocount - -\long\def\presetfloatvariables#1#2#3#4% - {\doifcommonelse - {#2} - {\v!left,\v!right,\v!inner,\v!outer,% - \v!inleft,\v!inright,\v!inmargin,% - \v!backspace,\v!cutspace,% - \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,% - \v!leftmargin,\v!leftedge,\v!rightmargin,\v!rightedge} - {\global\parfloattrue} - {\global\parfloatfalse}% - \ifinsidecolumns - \global\parfloatfalse - \fi - \global\sidefloatshift\zeropoint - \global\sidefloatmaximum\zeropoint - \global\chardef\sidefloatmethod\floatparameter\c!sidemethod - \global\chardef\textfloatmethod\floatparameter\c!textmethod - \global\chardef\sidefloatalign\zerocount - \globallet\floatrotation\!!zerocount - \calculatefloatskips - \ifparfloat - \processaction - [\floatparameter\c!sidealign] - [\v!height=>\global\chardef\sidefloatalign\plusone,% - \v!line=>\global\chardef\sidefloatalign\plustwo,% (***) - \v!depth=>\global\chardef\sidefloatalign\plusthree,% - \v!grid=>\global\chardef\sidefloatalign\plusfour,% - \v!halfline=>\global\chardef\sidefloatalign\plusfive]% - % todo (test first): \doifinset\v!lokaal{#2}{\chardef\sidefloatalign\zerocount}% - \ifcase\sidefloatalign\relax % todo: optie v!lokaal => \else - \doifinset\v!height {#2}{\global\chardef\sidefloatalign\plusone}% - \doifinset\v!line {#2}{\global\chardef\sidefloatalign\plustwo}% - \doifinset\v!depth {#2}{\global\chardef\sidefloatalign\plusthree}% - \doifinset\v!grid {#2}{\global\chardef\sidefloatalign\plusfour}% - \doifinset\v!halfline{#2}{\global\chardef\sidefloatalign\plusfive}% meant for 'none' - \fi - \doifinset\v!high{#2}{\global\sidefloattopskip \zeropoint}% - \doifinset\v!low {#2}{\global\sidefloatbottomskip\zeropoint}% - \doifinset\v!fit {#2} - {\global\sidefloattopskip \zeropoint - \global\sidefloatbottomskip\zeropoint - \global\floatsideskip \zeropoint}% - \else - \processallactionsinset - [#2] - [ 90=>\globallet\floatrotation\commalistelement,% - 180=>\globallet\floatrotation\commalistelement,% - 270=>\globallet\floatrotation\commalistelement]% - \fi - \doifinsetelse\v!nonumber{#2} - {\global\nofloatnumbertrue} - {\doifelse{\floatcaptionparameter\c!number}\v!yes - {\global\nofloatnumberfalse} - {\global\nofloatnumbertrue}}% - % this has to change - \ConvertToConstant\doifelse{#4}{} - {\global\emptyfloatcaptiontrue} - {\global\emptyfloatcaptionfalse}% - \doifinsetelse\v!none{#2} - {\global\nofloatcaptiontrue} - {\ConvertToConstant\doifelse{#4}\v!none - {\global\nofloatcaptiontrue} - {\global\nofloatcaptionfalse}}% - \doif{\floatcaptionparameter\c!number}\v!none % new - {\global\nofloatcaptiontrue}% - \ifemptyfloatcaption \ifnofloatnumber - \global\nofloatcaptiontrue - \fi \fi} - -% documenteren in details - -\def\presetmorefloatvariables#1% - {\doifelse{\floatparameter\c!local}\v!yes % fout keyword - \globalcenterfloatboxtrue - \globalcenterfloatboxfalse - \ifglobalcenterfloatbox - \localcenterfloatboxtrue - \else - \doifinsetelse\v!local{#1} - \localcenterfloatboxtrue - \localcenterfloatboxfalse - \fi - \doifnotcommon{\v!always,\v!here,\v!force}{#1} % ! ! ! ! ! ! - {\globalcenterfloatboxfalse - \localcenterfloatboxfalse}} - -\let\naturalfloatheight\!!zeropoint -\let\naturalfloatwidth \!!zeropoint -\let\naturalfloatdepth \!!zeropoint - -\def\setnaturalfloatdimensions#1% - {\xdef\naturalfloatheight{\the\ht#1}% - \xdef\naturalfloatwidth {\the\wd#1}% - \xdef\naturalfloatdepth {\the\dp#1}} - -\long\def\doifelsemainfloatbody#1#2% - {\ifinsidesplitfloat\ifconditional\splitfloatfirstdone#2\else#1\fi\else#1\fi} - -% todo: optional user pars - -\long\def\docompletefloat#1#2#3#4#5% #1:floatclass #2:reference #3:optionlist #4:caption #5:box number - {\presetfloatvariables{#1}{#3}{#2}{#5}% check this one - \bgroup - % prepare structure data - % - % \dofloatcomponent[\c!name=#1,\c!reference=#2,\c!bookmark=,\c!title={#4}][]% ifnofloatnumber ifnofloatcaption \tracefloatnumber{#1}% - % - \dostructurecountercomponent - {float}% - \getcaptionparameters - \floatcaptionparameter - \detokenizedcaptionparameter - \relax - \relax - \relax - [\c!name=\currentfloat,\s!counter=\currentfloat,% - \s!hascaption=\ifnofloatcaption \v!no\else\v!yes\fi,% - \s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,% - \s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi,% - \c!reference=#2,\c!title={#4},\c!bookmark=]% - []% - \globallet\currentfloatnumber \laststructurecounternumber - \globallet\currentfloatsynchronize\laststructurecountersynchronize - % - % check float box - \setnaturalfloatdimensions#5% - \global\setbox\floatbox\vbox{\floatparameter\c!command{\box#5}}% - \setnaturalfloatdimensions\floatbox - \ifdim\htdp\floatbox=\zeropoint - \showmessage\m!floatblocks{11}\empty - \global\setbox\floatbox\vbox{\doemptyfloatblock{#1}}% - \fi - % deal with lack of caption - \global\setbox\floatbox\vbox - {\doifelsemainfloatbody\currentfloatsynchronize\donothing - \unvbox\floatbox - \ifnofloatcaption - \vss - \fi}% gets rid of the depth (unless tabulate) - \egroup - % place the float - \dofloat{#3}{\thecurrentfloatnumber}{\thecurrentfloatcaption}% - \global\insidefloatfalse} - -\def\setlocalfloathsize - {\iflocalcenterfloatbox - \seteffectivehsize - \hsize\localhsize - \fi} - -\newevery \everyinsidefloat \relax - -\appendtoks - \everyinsidefloat\emptytoks % in case it's called earlier - \dogetfloatdata -\to \everyinsidefloat - -%\appendtoks -% \fuzzysnappingfalse -%\to \everyinsidefloat - -\def\doifrightpagefloatelse - {\ifdoublesided - \ifsinglesided - \@EAEAEA\firstoftwoarguments - \else - \@EAEAEA\doifoddfloatpageelse - \fi - \else - \@EA\firstoftwoarguments - \fi} - -\def\doifoddfloatpageelse - {\ifodd\purenumber\twopassfloatdata\space - \@EA\firstoftwoarguments - \else - \@EA\secondoftwoarguments - \fi} - -\appendtoks - \let\rightorleftpageaction\doifrightpagefloatelse -\to \everyinsidefloat - -\newif\ifextrafloatactions \extrafloatactionstrue - -% \let\movesidefloat\gobbleoneargument - -% new : \place...[leftmargin,-2*line]; we need to catch fxtb:2*3 -% watch out: line alone aligns on the line ! ! ! - -\def\movesidefloat[#1]% (-)n*line|x=,y= - {\global\sidefloatdownshift \zeropoint - \global\sidefloatextrashift\zeropoint - \doifassignmentelse{#1}% - {\bgroup - \getparameters[\??fl][\c!x=\zeropoint,\c!y=\zeropoint,#1]% - \ifgridsnapping - \getnoflines\@@fly - \global\sidefloatdownshift\noflines\lineheight - \else - \global\sidefloatdownshift\@@fly - \fi - \global\sidefloatextrashift\@@flx - \egroup} - {\movedownsidefloat[#1]}} - -\def\movedownsidefloat[#1]% already in core - {\bgroup - \cleanupfeatures - \doifinstringelse{:}{#1} - \donothing - {\def\docommand##1% - {\processaction - [##1]% - [ \v!line=>\dodocommand+,% - +\v!line=>\dodocommand+,% - -\v!line=>\dodocommand-]}% - \def\dodocommand##1% - {\ifdone\else\global\sidefloatdownshift\zeropoint\donetrue\fi - \global\advance\sidefloatdownshift##1\lineheight}% - \donefalse\normalexpanded{\noexpand\dorepeatwithcommand[#1]}\docommand - \def\docommand##1% - {\processaction - [##1]% - [ \v!hang=>\dodocommand+,% - +\v!hang=>\dodocommand+,% - -\v!hang=>\dodocommand-]}% - \def\dodocommand##1% inefficient but who cares - {\ifdone\else\global\sidefloatsidelines\zeropoint\donetrue\fi - \global\advance\sidefloatsidelines\plusone\relax}% - \donefalse\normalexpanded{\noexpand\dorepeatwithcommand[#1]}\docommand}% - \egroup} - -\def\hangsidefloat[#1]% - {\global\sidefloatsidelines#1\relax} - -\long\def\xdocompletefloat#1#2#3#4% - {\ifextrafloatactions - \doifinsetelse\v!text{#3} - {% fuzzy, text overloads left, since then it's a directive - \docompletefloat{#1}{#2}{#3}{#4}\nextbox} - {\let\@@extrafloat\empty - % \sidefloatdownshift will be reset afterwards, and can - % already be set at this point - \processallactionsinset - [#3] % ininner/inouter : for old times sake - [ \v!inner=>\xxdocompletefloat\v!left \v!right, - \v!outer=>\xxdocompletefloat\v!right \v!left, - \v!innermargin=>\xxdocompletefloat\v!leftmargin \v!rightmargin, - \v!outermargin=>\xxdocompletefloat\v!rightmargin\v!leftmargin, - \v!inneredge=>\xxdocompletefloat\v!leftedge \v!rightedge, - \v!outeredge=>\xxdocompletefloat\v!rightedge \v!leftedge, - \v!backspace=>\xxdocompletefloat\v!backspace \v!cutspace, - \v!cutspace=>\xxdocompletefloat\v!cutspace \v!backspace, -% \v!margin=>\xxdocompletefloat\v!cutspace \v!backspace, - \v!left=>\xxdocompletefloat\v!left \v!left, - \v!right=>\xxdocompletefloat\v!right \v!right, - \v!line=>, % only -n*line is handled (see ***) - \s!unknown=>{\movedownsidefloat[\commalistelement]}]% - \ifx\@@extrafloat\empty - \docompletefloat{#1}{#2}{#3}{#4}\nextbox - \else - \docompletefloat{#1}{#2}{\@@extrafloat,#3}{#4}\nextbox - \fi}% - \else % downward compatible - \docompletefloat{#1}{#2}{#3}{#4}\nextbox - \fi} - -% pas op, maxbreedte niet instellen als plaats=links/rechts - -\def\setlocalfloatdimensions#1% - {\global\sidefloatshift \zeropoint % duplicate - \global\sidefloatmaximum\zeropoint\relax % duplicate - \ifextrafloatactions - \ifdim\sidefloatdownshift=\zeropoint\else - \global\setbox\floatbox\vbox - {\vskip\sidefloatdownshift\nointerlineskip\box\floatbox}% - \fi - \doifsomething{\floatparameter\c!minwidth} - {\scratchdimen\floatparameter\c!minwidth\relax - \ifdim\wd\floatbox<\scratchdimen - \global\setbox\floatbox\hbox to \scratchdimen - {\doifnot{\floatparameter\c!location}\v!left \hss - \box\floatbox% - \doifnot{\floatparameter\c!location}\v!right\hss}% - \fi}% - % todo: rand / rug - \doifinset\v!hanging{#1} - {\doifcommonelse{\v!inleft,\v!leftmargin}{#1} - {\letfloatparameter\c!maxwidth\leftmarginwidth}% - {\doifcommon{\v!inright,\v!rightmargin}{#1} - {\letfloatparameter\c!maxwidth\rightmarginwidth}}}% - \doifsomething{\floatparameter\c!maxwidth} - {\scratchdimen\floatparameter\c!maxwidth\relax - \ifdim\wd\floatbox>\scratchdimen - \doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge - \v!inleft,\v!leftmargin,\v!leftedge}{#1} - {\global\sidefloatmaximum\scratchdimen} - {\global\setbox\floatbox\hbox to \scratchdimen - {\doifcommonelse{\v!right,\v!left}{#1} - {\doifnotinset\v!right{#1}\hss - \box\floatbox - \doifnotinset\v!left{#1}\hss}% - {\doifnot{\floatparameter\c!location}\v!left\hss - \box\floatbox - \doifnot{\floatparameter\c!location}\v!right\hss}}}% - \fi}% - \fi} - -\def\docomplexstarttextblock[#1][#2][#3]% - {\flushnotes - \flushsidefloats % hoort eigenlijk niet hier - \docomplexplacefloat[#1][\v!text,#2,\v!left][#3]} - -\long\def\docomplexreserveblock[#1][#2][#3][#4]#5% - {\getvalue{\e!place#1}[#3][#4]{#5}{\localframed[\??fl#1][#2]{#1}}} - -\def\docomplexstartreservetextblock[#1][#2][#3][#4]% - {\flushsidefloats % hoort eigenlijk niet hier - \docomplexreserveblock[#1][#2][\v!text,#3,\v!left][#4]} - -\def\placefloat - {\dotripleempty\docomplexplacefloat} - -\installinsertion\topins -\installinsertion\botins - -\newdimen\botinserted -\newdimen\topinserted - -%D Extra float registers. - -\newif\ifsomefloatwaiting \somefloatwaitingfalse -\newif\ifroomforfloat \roomforfloattrue -\newif\ifnofloatpermitted \nofloatpermittedfalse - -\newcount\totalnoffloats \totalnoffloats =0 -\newcount\savednoffloats \savednoffloats =0 -\newcount\noffloatinserts \noffloatinserts=0 - -\newbox\floatlist -\newbox\savedfloatlist - -\newif\ifflushingfloats \flushingfloatsfalse - -\newbox\floattext - -\newdimen\floattextwidth -\newdimen\floattextheight - -\newbox\floatbox -\newbox\savedfloatbox - -\newdimen\floatwidth -\newdimen\floatheight - -% In \dofloatinfomessage wordt {{ }} gebruikt omdat anders -% binnen \startpostponing...\stoppostponing geen goede -% melding in de marge volgt: \ifinner is dan namelijk true. - -\def\dofloatinfomessage#1#2#3% - {\bgroup - \showmessage\m!floatblocks{#2}{#3}% - \setmessagetext\m!floatblocks{#2}% - \@EA\floatinfo\@EA#1\@EA{\currentmessagetext}% - \egroup} - -\def\dosavefloatinfo - {\dofloatinfomessage>2{\the\totalnoffloats}} - -\def\dofloatflushedinfo - {\bgroup - \!!counta\totalnoffloats - \advance\!!counta -\savednoffloats - \dofloatinfomessage<3{\the\!!counta}% - \egroup} - -\def\doinsertfloatinfo - {\dofloatinfomessage<4{\the\totalnoffloats}} - -\def\dogetfloat - {\ifsomefloatwaiting - \global\setbox\floatlist\vbox - {\unvbox\floatlist - \global\setbox\globalscratchbox\lastbox}% - \ifcenterfloatbox - \ifdim\wd\globalscratchbox<\hsize - \setbox\floatbox\hbox to \hsize{\hss\box\globalscratchbox\hss}% - \else - \setbox\floatbox\box\globalscratchbox % local ! - % retain special alignments - \ifinsidecolumns - \ifdim\wd\floatbox>\makeupwidth - \wd\floatbox\makeupwidth - \fi - \fi - \fi - \else - \setbox\floatbox\box\globalscratchbox % local ! - \fi - \global\advance\savednoffloats \minusone - \ifcase\savednoffloats - \global\somefloatwaitingfalse - \fi - \else - \global\savednoffloats\zerocount - \global\setbox\floatbox\emptybox - \fi} - -\def\uncenteredfloatbox - {\ifcenterfloatbox - \ifhbox\floatbox\relax % remove centering - \ifdim\wd\floatbox=\hsize - \ifhbox\floatbox - \setbox\scratchbox\hbox - {\unhbox\floatbox - \unskip\unskip - \global\setbox\globalscratchbox\lastbox}% - \box\globalscratchbox - \else - \box\floatbox - \fi - \else - \box\floatbox - \fi - \else - \box\floatbox - \fi - \else - \box\floatbox - \fi} - -\def\dosavefloat - {\global\setbox\floatlist\vbox - {\nointerlineskip - \uncenteredfloatbox - \unvbox\floatlist}% - \global\advance\savednoffloats \plusone - \global\somefloatwaitingtrue - \dosavefloatinfo - \nonoindentation} - -\def\doresavefloat - {\global\setbox\floatlist\vbox - {\nointerlineskip - \unvbox\floatlist - \uncenteredfloatbox}% - \global\advance\savednoffloats \plusone - \global\somefloatwaitingtrue} - -\def\doreversesavefloat - {\global\setbox\floatlist\vbox - {\nointerlineskip - \unvbox\floatlist - \uncenteredfloatbox}% - \global\advance\savednoffloats \plusone - \global\somefloatwaitingtrue - \dosavefloatinfo} - -% better (todo): \savednofsavedfloats - -\def\dosavefloatstatus - {\global\setbox\savedfloatlist\copy\floatlist - \global\setbox\savedfloatbox \copy\floatbox - \xdef\dorestorefloatstatus - {\global\setbox\floatlist\box\savedfloatlist - \global\setbox\floatbox \box\savedfloatbox - \global\savednoffloats\the\savednoffloats}} - -\let\dorestorefloatstatus\relax - -\ifx\doflushfloats\undefined \let\doflushfloats\relax \fi -\ifx\flushfloatbox\undefined \let\flushfloatbox\relax \fi - -% needed in the splitter: - -\newcount\savedsavednoffloats - -\let\dopopsavedfloats\relax - -\def\dopushsavedfloats - {\global\setbox\savedfloatlist\box\floatlist - \global\savedsavednoffloats\savednoffloats - \global\savednoffloats\savednoffloats - \global\somefloatwaitingfalse - \gdef\dopopsavedfloats - {\global\advance\savednoffloats\savedsavednoffloats - \global\setbox\floatlist\vbox\bgroup - \ifvoid\floatlist \else\unvbox\floatlist \fi - \ifvoid\savedfloatlist\else\unvbox\savedfloatlist\fi - \egroup - \global\ifcase\savednoffloats - \somefloatwaitingfalse\else\somefloatwaitingtrue\fi - \globallet\dopopsavedfloats\relax}} - -\def\doflushsavedfloats % simplified \OTRONEdodoflushfloats - {\doloop - {\ifsomefloatwaiting - \dogetfloat - \dofloatflushedinfo - \docheckiffloatfits - \ifroomforfloat - \doplacefloatbox - \else - \doreversesavefloat - \exitloop - \fi - \else - \exitloop - \fi}} - -% top and bottom - -\newif\iftopofinsert -\newif\iftestfloatbox -\newif\ifcenterfloatbox \centerfloatboxtrue -\newif\iflocalcenterfloatbox \localcenterfloatboxfalse -\newif\ifglobalcenterfloatbox \globalcenterfloatboxfalse - -% beter de laatste skip buiten de \insert uitvoeren, -% bovendien bij volle flush onder baseline. - -\def\betweenfloatblanko% assumes that spaceafter is present - {\bgroup - \setbox0\vbox{\strut\blank[\floatsharedparameter\c!spacebefore]\strut}% - \setbox2\vbox{\strut\blank[\floatsharedparameter\c!spaceafter]\strut}% - \ifdim\ht0>\ht2 - \blank[-\floatsharedparameter\c!spaceafter,\floatsharedparameter\c!spacebefore]% - \fi - \egroup} - -\def\doplacefloatbox - {%\forgetall % NO - \whitespace - \blank[\floatsharedparameter\c!spacebefore] - \flushfloatbox - \blank[\floatsharedparameter\c!spaceafter]} - -\ifx\someherefloat\undefined \let\someherefloat\doplacefloatbox \fi -\ifx\somefixdfloat\undefined \let\somefixdfloat\doplacefloatbox \fi -\ifx\somepagefloat\undefined \let\somepagefloat\doplacefloatbox \fi -\ifx\sometopsfloat\undefined \let\sometopsfloat\doplacefloatbox \fi -\ifx\somebotsfloat\undefined \let\somebotsfloat\doplacefloatbox \fi - -\ifx\somesidefloat\undefined \let\somesidefloat\doplacefloatbox \fi -\ifx\somefacefloat\undefined \let\somefacefloat\doplacefloatbox \fi -\ifx\sometextfloat\undefined \let\sometextfloat\doplacefloatbox \fi - -% brr, wordt deze niet overladen in page-one? weg er mee - -% \def\somepagefloat[#1]% links, rechts, midden, hoog, midden, laag -% {%\checkwaitingfloats{#1}% -% \global\setbox\collectedpagefloats\vbox -% {\unvbox\collectedpagefloats -% \vbox to \textheight -% {\doifnotinset\v!high{#1}\vfill -% \box\floatbox -% \doifnotinset\v!low{#1}\vfill}% -% \goodbreak}% -% \doinsertfloatinfo} - -% \def\OTRONEsomepagefloat[#1]% -% {%\checkwaitingfloats{#1}% -% \global\setbox\collectedpagefloats\vbox -% {\ifvoid\collectedpagefloats\else\unvbox\collectedpagefloats\fi -% \vbox to \textheight % vss and unvbox catch too high and limited floats -% {\vss -% \doifnotinset\v!high{#1}\vfill -% \unvbox\floatbox -% \doifnotinset\v!low{#1}\vfill -% \vss}% -% \goodbreak}% -% \doinsertfloatinfo} - -% test case: -% -% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=0.9\textheight,color=green]} -% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.0\textheight,color=green]} -% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.1\textheight,color=green]} - -\def\sometextfloat[#1]% lang, links, rechts, hoog, midden, laag, offset - {%\checkwaitingfloats{#1}% - \gdef\dostoptextfloat{\dodostoptextfloat[#1]}% brr global - \global\floattextwidth\hsize - \global\floatwidth\wd\floatbox - \global\floatheight\ht\floatbox % forget about the depth - \global\advance\floattextwidth -\floatwidth - \global\advance\floattextwidth -\floatsharedparameter\c!margin\relax % was \tfskipsize - \doifinsetelse\v!tall{#1} - {\floattextheight\pagegoal - \advance\floattextheight -\pagetotal - \advance\floattextheight -\bigskipamount % lelijk - \ifdim\floattextheight>\textheight - \floattextheight\textheight - \fi - \boxmaxdepth\zeropoint \relax % toegevoegd - \ifdim\floattextheight<\floatheight - \floattextheight\floatheight - \fi - \setbox\floattext\vbox to \floattextheight} - {\setbox\floattext\vbox}% - \bgroup - \forgetall \setupblank \setupwhitespace % new, also needed for footnotes - \blank[\v!disable] - \hsize\floattextwidth - \ignorespaces} - -\def\dodostoptextfloat[#1]% % de tekst kan beter in een soort - {\egroup % kadertekst zonder kader, is flexibeler - \doifnotinset\v!tall{#1}% en beter - {\ifdim\ht\floattext<\floatheight - \floattextheight\floatheight - \else - \floattextheight\ht\floattext - \fi}% - \setbox\floatbox\vbox to \floattextheight - {\hsize\floatwidth - \doifinsetelse\v!both{#1}% - {\doifinsetelse\v!low{#1} - {\vfill\box\floatbox} - {\doifinsetelse\v!middle{#1} - {\vfill\box\floatbox\vfill} - {\box\floatbox\vfill}}} - {\box\floatbox\vfill}}% - \setbox\floattext\vbox to \floattextheight - {\hsize\floattextwidth - \doifinsetelse\v!low{#1} - {\vfill - \box\floattext - \doifinset\c!offset{#1}{\whitespace\blank}} - {\doifinsetelse\v!middle{#1} - {\vfill - \box\floattext - \vfill} - {\doifinset\v!offset{#1}{\whitespace\blank}% - \box\floattext - \vfill}}}% - \doifinsetelse\v!right{#1}% \floatmethod - {\setbox\floatbox\hbox to \hsize - {\box\floattext - \hfill - \box\floatbox}} - {\setbox\floatbox\hbox to \hsize - {\box\floatbox - \hfill - \box\floattext}}% - \baselinecorrection - \whitespace - \blank[\floatsharedparameter\c!spacebefore]% - \doifnotinset\v!tall{#1}% - {\dp\floatbox\openstrutdepth}% dp\strutbox}% % toegevoegd - \box\floatbox - \blank[\floatsharedparameter\c!spaceafter]% - \endgroup % ** - \doinsertfloatinfo} - -\def\somefacefloat[#1]% links, rechts, midden, hoog, midden, laag - {%\checkwaitingfloats{#1}% - \startopposite\box\floatbox\stopopposite - \doinsertfloatinfo} - -\def\someelsefloat[#1]% - {\doifinsetelse\v!here{#1} - {\doifinsetelse\v!always{#1} - {\page[\v!preference]% - \docheckiffloatfits - \ifroomforfloat - \placesomeherefloat[#1]% - \else - \showmessage\m!floatblocks9\empty - \doreversesavefloat - \fi} - {\ifsomefloatwaiting - \dosavefloat - \else - \page[\v!preference]% - \docheckiffloatfits - \ifroomforfloat - \placesomeherefloat[#1]% - \else - \dosavefloat - \fi - \fi}} - {\doifinsetelse\v!always{#1} - {\docheckiffloatfits - \ifroomforfloat - \sometopbottomfloat[#1] - \else - \showmessage\m!floatblocks9\empty - \doreversesavefloat - \fi} - {\docheckiffloatfits - \ifroomforfloat - \sometopbottomfloat[#1] - \else - \dosavefloat - \fi}}} - -\def\floatautofactor{.5} - -\def\sometopbottomfloat[#1]% - {\doifelse\floatmethod\v!auto - {\ifdim\pagetotal<\floatautofactor\pagegoal % when empty page, maxdimen - \placesometopsfloat[#1]% - \else - \placesomebotsfloat[#1]% - \fi} - {\doifelse\floatmethod\v!top - {\placesometopsfloat[#1]} - {\doifelse\floatmethod\v!bottom - {\placesomebotsfloat[#1]} - {\placesomeherefloat[#1]}}}} - -% De onderstaande macro wordt gebruikt bij de macros -% voor het plaatsen van tabellen en figuren (klopt niet -% meer). -% -% \dofloat {plaats} {label1} {label2} -% \docompletefloat {nummer} {referentie} {plaats} {label} {inhoud} -% \box\floatbox inhoud+referentie -% \do???float#1 #1 = boxnummer - -\newdimen\floatsideskip \floatsideskip =12pt -\newdimen\floattopskip \floattopskip =\floattopskip -\newdimen\floatbottomskip \floatbottomskip=\floattopskip - -\newdimen\sidefloattopskip \sidefloattopskip =\floattopskip -\newdimen\sidefloatbottomskip \sidefloatbottomskip=\floatbottomskip - -\newskip\sidefloatdownshift -\newskip\sidefloatleftshift -\newskip\sidefloatrightshift - -\def\sidefloattopoffset {\openstrutdepth} % {\strutdp} - -\newcount\noftopfloats \noftopfloats=2 -\newcount\nofbotfloats \nofbotfloats=0 - -\def\docalculatefloatskip#1#2% - {\doifelsenothing{#2} - {\global#1\zeropoint} - {\doifelse{#2}\v!none - {\global#1\zeropoint} - {\setbox\scratchbox\vbox{\whitespace\normalexpanded{\noexpand\blank[#2]}}% - \global#1\ht\scratchbox}}} - -\def\calculatefloatskips - {{\docalculatefloatskip\floattopskip{\floatsharedparameter\c!spacebefore}% - \docalculatefloatskip\floatbottomskip{\floatsharedparameter\c!spaceafter}% - \docalculatefloatskip\sidefloattopskip{\floatsharedparameter\c!sidespacebefore}% - \docalculatefloatskip\sidefloatbottomskip{\floatsharedparameter\c!sidespaceafter}% - \gdef\sidefloattopoffset{\openstrutdepth}% was \def - \global\floatsideskip\floatsharedparameter\c!margin - \global\sidefloatleftshift\floatparameter\c!leftmargindistance - \global\sidefloatrightshift\floatparameter\c!rightmargindistance - \global\noftopfloats\floatsharedparameter\c!ntop\relax - \global\nofbotfloats\floatsharedparameter\c!nbottom\relax}} - -\def\borderedfloatbox - {\localframed - [\??fl\currentfloat] - [\c!location=\v!normal,\c!width=\wd\floatbox,\c!height=\htdp\floatbox] - {\box\floatbox}} - -\newbox\tempfloatbox - -% minwidth=fit,width=max : no overshoot, as wide as graphic - -\ifx\moveboxontogrid\undefined \let\movecaptionontogrid\gobblethreearguments \fi - -\def\locatefloatbox - {\chardef\alignstrutmode\zerocount - \shiftalignedline - {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}% - {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}% - \alignedline{\floatparameter\c!location}\v!middle} - -\def\locatecaptionbox - {\chardef\alignstrutmode\zerocount - \shiftalignedline - {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}% - {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}% - \alignedline{\floatparameter\c!location}\v!middle} - -\long\def\dosetpagfloat#1#2#3% \copy wegwerken - {\bgroup - \setlocalfloathsize - \ifnum\floatrotation>0 - \swapdimens\hsize\vsize - \fi - \forgetall - \postponenotes - \dontcomplain - \setbox\tempfloatbox\vbox{\borderedfloatbox}% - \let\locatefloat \locatefloatbox - \let\locatecaption\locatecaptionbox - \docheckcaptioncontent{#2}{#3}% - \ifcase\floatparameter\c!method - \or % automatic - \ifnofloatcaption - \dopreparenocaption{#1}{#2}{#3}% - \edef\width{\the\wd\floatbox}% - \doglobal\addlocalbackgroundtobox\floatbox - \else - % todo: installable maken, variant/method=auto vs macro - \dopreparedocaption{#1}{#2}{#3}% - \settracedcaptionbox - \edef\width{\the\wd\tempfloatbox}% - \addlocalbackgroundtobox\tempfloatbox - \setbox\tempcaptionbox\hbox - {\dosetcaptionthings - \floatcaptionparameter\c!command{\box\tempcaptionbox}}% - \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht - \addlocalbackgroundtobox\tempcaptionbox - \buildfloatbox - \fi - \or % semi automatic - \or % manual - \fi - \ifnum\floatrotation>0 - \global\setbox\floatbox\vbox - {\rotate[\c!rotation=\floatrotation]{\box\floatbox}}% - \edef\width{\the\wd\tempfloatbox}% - \else - \postcenterfloatbox\width - \fi - \egroup} - -\def\captionminwidth {15\bodyfontsize} -\def\captionovershoot {2em} - -\def\dopreparenocaption#1#2#3% - {\global\setbox\floatbox\vbox % pas op als wd groter dan hsize - {\ifinsidecolumns\ifdim\wd\tempfloatbox>\hsize - \let\locatefloat\relax - \fi\fi - \locatefloat{\copy\tempfloatbox}}} - -\def\dopreparedocaption#1#2#3% - {\doifinsetelse{\floatcaptionparameter\c!location}{\v!top,\v!bottom} - {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max} - {\doifelse{\floatcaptionparameter\c!minwidth}\v!fit - {\doifelse{\floatcaptionparameter\c!width}\v!max - {\dopreparestackcaptionmax{#1}{#2}{#3}} - {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox % wider caption - \doifelse{\floatcaptionparameter\c!width}\v!fit - {\dopreparestackcaptionaut{#1}{#2}{#3}} - {\dopreparestackcaptionwid{#1}{#2}{#3}}% - \else - \dopreparestackcaptionmin{#1}{#2}{#3}% - \fi}} - {\dopreparestackcaptionfix{#1}{#2}{#3}}}% - {\dopreparesidewidthcaption{#1}{#2}{#3}}}% new, special effects (see icare) - {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max} - {\dopreparesideautocaption{#1}{#2}{#3}} - {\dopreparesidewidthcaption{#1}{#2}{#3}}}} - -% \def\dosettempcaptionbox -% {\dosetraggedvbox{\floatcaptionparameter\c!align}% -% \setbox\tempcaptionbox\raggedbox} - -\def\dosettempcaptionbox - {\setbox\tempcaptionbox\vbox\bgroup - %expanded{\setupalign[\v!new,\v!reset,\floatcaptionparameter\c!align,\v!old]}% wrong! see icare - \normalexpanded{\noexpand\setupalign[\v!reset,\floatcaptionparameter\c!align]}% i need to check what reset does - \dosetcaptionthings - \let\next} - -\def\dopreparesideautocaption#1#2#3% - {\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\floatparameter\c!margin\relax % was \tfskipsize\relax - \ifdim\wd\tempcaptionbox>\scratchdimen - \ifdim\wd\tempcaptionbox<1.3\scratchdimen - \scratchdimen0.8\scratchdimen - \fi - \fi - \dosettempcaptionbox - {\hsize\scratchdimen - \putcompletecaption{#2}{#3}}} - -\def\dopreparesidewidthcaption#1#2#3% - {\dosettempcaptionbox - {\hsize\floatcaptionparameter\c!width - \putcompletecaption{#2}{#3}}} - -\def\dopreparestackcaptionfix#1#2#3% - {\dosettempcaptionbox - {\hsize\floatcaptionparameter\c!minwidth % special effects - \putcompletecaption{#2}{#3}}} - -\def\dopreparestackcaptionmax#1#2#3% - {\dosettempcaptionbox - {\hsize\wd\tempfloatbox - \putcompletecaption{#2}{#3}}} - -\def\dopreparestackcaptionwid#1#2#3% - {\dosettempcaptionbox - {\hsize\floatcaptionparameter\c!width - \putcompletecaption{#2}{#3}}} - -\def\dopreparestackcaptionmin#1#2#3% - {\dosettempcaptionbox - {\hsize\wd\tempfloatbox - \doifnothing{\floatcaptionparameter\c!align}\raggedcenter % on purpose overloads align ! - \putcompletecaption{#2}{#3}}} - -\def\dopreparestackcaptionaut#1#2#3% - {\doifsomething{\floatcaptionparameter\c!align} - {\doifnotinset{\v!middle}{\floatcaptionparameter\c!align}% - {\let\captionovershoot\!!zeropoint}}% - \edef\captionhsize{\the\wd\tempfloatbox}% - \ifdim\captionhsize>\hsize - % float is wider than \hsize - \dosettempcaptionbox - {\trialtypesettingtrue - \hsize\captionhsize - \notesenabledfalse - \putcompletecaption{#2}{#3}}% - \ifdim\ht\scratchbox>\lineheight % more lines - \dosettempcaptionbox - {\hsize\captionhsize - \advance\hsize -\captionovershoot\relax - \ifdim\hsize<\captionminwidth\relax - \hsize\captionhsize - \fi - \putcompletecaption{#2}{#3}}% - \else - \dosettempcaptionbox - {\hsize\captionhsize - \putcompletecaption{#2}{#3}}% - \fi - \else - % float is smaller of equal to \hsize - \ifdim\captionhsize<\captionminwidth\relax - \scratchdimen\captionminwidth % float smaller than min width - \edef\captionhsize{\the\scratchdimen}% - \fi - \setbox\scratchbox\vbox % test with overshoot - {\trialtypesettingtrue - \scratchdimen\captionhsize - \advance\scratchdimen \captionovershoot - \advance\scratchdimen 3em % an average word length - \ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi - \notesenabledfalse - \putcompletecaption{#2}{#3}}% - \ifdim\ht\scratchbox>\lineheight - % at least an average word longer than a line - \dosettempcaptionbox - {\scratchdimen\captionhsize - \advance\scratchdimen \captionovershoot - \ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi - \putcompletecaption{#2}{#3}}% - \else - % just over a line, don't use an overshoot % % % todo: outer/inner and such - \doifcommonelse{\floatcaptionparameter\c!align}{\v!left,\v!right,\v!flushleft,\v!flushright} - {\dosettempcaptionbox - {\hsize\captionhsize - % strange : \raggedcenter - \putcompletecaption{#2}{#3}}} - {% nicer - \dosettempcaptionbox - {\hsize\captionhsize - \doifnothing{\floatcaptionparameter\c!align}\raggedcenter% overloads - \putcompletecaption{#2}{#3}}}% - \fi - \fi} - -\def\dopreparesidecaption#1#2#3% - {\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\floatparameter\c!margin\relax % was \tfskipsize\relax - \ifdim\wd\tempcaptionbox>\scratchdimen - \ifdim\wd\tempcaptionbox<1.3\scratchdimen - \scratchdimen0.8\scratchdimen - \fi - \fi - \dosettempcaptionbox % \setbox\tempcaptionbox\vbox - {\hsize\scratchdimen - \doifnothing{\floatcaptionparameter\c!align}\raggedright % on purpose overloads align ! - \putcompletecaption{#2}{#3}}} - -\newdimen\tempfloatheight -\newdimen\tempfloatwidth - -\def\dofloatboxbetweenstack - {\endgraf\nointerlineskip\floatcaptionparameter\c!inbetween\endgraf} - -\def\dofloatboxdefaultbuilder % done - {\locatefloat{\box\tempfloatbox}} - -\def\dofloatboxnextrightbuilder#1% - {\ifparfloat \hbox \else \expandafter \locatefloat \fi - {\tempfloatheight\ht\tempfloatbox - \box\tempfloatbox - \normalexpanded{\noexpand\doifnotinset{\v!hang}{\floatcaptionparameter\c!location}}{\dotfskip{\floatcaptionparameter\c!distance}}% - \vbox to\tempfloatheight{#1}}} - -\def\dofloatboxnextleftbuilder#1% - {\ifparfloat \hbox \else \expandafter \locatefloat \fi - {\tempfloatheight\ht\tempfloatbox - \vbox to\tempfloatheight{#1}% - \normalexpanded{\noexpand\doifnotinset{\v!hang}{\floatcaptionparameter\c!location}}{\dotfskip{\floatcaptionparameter\c!distance}}% - \box\tempfloatbox}} - -\def\dofloatboxnextouterbuilder - {\doifrightpagefloatelse\dofloatboxnextrightbuilder\dofloatboxnextleftbuilder} -\def\dofloatboxnextinnerbuilder - {\doifrightpagefloatelse\dofloatboxnextleftbuilder\dofloatboxnextrightbuilder} - -\def\dofloatboxnextrighthangbuilder#1% - {\ifparfloat \hbox \else \expandafter \locatefloat \fi - {\tempfloatheight\ht\tempfloatbox - \box\tempfloatbox - \vbox to\tempfloatheight{#1}}} - -\def\dofloatboxnextlefthangbuilder#1% - {\ifparfloat \hbox \else \expandafter \locatefloat \fi - {\tempfloatheight\ht\tempfloatbox - \vbox to\tempfloatheight{#1}% - \box\tempfloatbox}} - -\def\dodofloatboxnextrightmarginbuilder#1#2% - {\ifparfloat - \hbox\bgroup - \tempfloatheight\ht\tempfloatbox - \box\tempfloatbox - \hsmash{\hskip#1\vbox to\tempfloatheight{#2}}% - \egroup - \else - \begingroup - \tempfloatheight\ht\tempfloatbox - \everyrightofalignedline{\hsmash{\hskip#1\vbox to\tempfloatheight{#2}}}% - \locatefloat{\box\tempfloatbox}% - \endgroup - \fi} - -\def\dodofloatboxnextleftmarginbuilder#1#2% - {\ifparfloat - \hbox\bgroup - \tempfloatheight\ht\tempfloatbox - \hsmash{\hskip-\dimexpr#1+\wd\tempcaptionbox\relax\vbox to\tempfloatheight{#2}}% - \box\tempfloatbox - \egroup - \else - \begingroup - \tempfloatheight\ht\tempfloatbox - \everyleftofalignedline{\hsmash{\hskip-\dimexpr#1+\wd\tempcaptionbox\relax\vbox to\tempfloatheight{#2}}}% - \locatefloat{\box\tempfloatbox}% - \endgroup - \fi} - -\def\dofloatboxnextrightmarginbuilder{\dodofloatboxnextrightmarginbuilder\rightmargindistance} -\def\dofloatboxnextleftmarginbuilder {\dodofloatboxnextleftmarginbuilder \leftmargindistance } - -\def\dofloatboxnextoutermarginbuilder - {\doifrightpagefloatelse - {\dodofloatboxnextrightmarginbuilder\rightmargindistance} - {\dodofloatboxnextleftmarginbuilder \rightmargindistance}} - -\def\dofloatboxnextinnermarginbuilder - {\doifrightpagefloatelse - {\dodofloatboxnextleftmarginbuilder \leftmargindistance} - {\dodofloatboxnextrightmarginbuilder\leftmargindistance}} - -\def\dofloatboxnextbuilder % beware, we first check on left/rightmargin because there can be left/right also - {\let\next\dofloatboxnextleftbuilder - \normalexpanded{\noexpand\processallactionsinset[\floatcaptionparameter\c!location]} - [ \v!outermargin=>\let\next\dofloatboxnextoutermarginbuilder, - \v!innermargin=>\let\next\dofloatboxnextinnermarginbuilder, - \v!leftmargin=>\let\next\dofloatboxnextleftmarginbuilder, - \v!rightmargin=>\let\next\dofloatboxnextrightmarginbuilder, - \v!lefthanging=>\let\next\dofloatboxnextlefthangbuilder, - \v!righthanging=>\let\next\dofloatboxnextrighthangbuilder, - \v!outer=>\let\next\dofloatboxnextouterbuilder, - \v!inner=>\let\next\dofloatboxnextinnerbuilder, - \v!left=>\let\next\dofloatboxnextleftbuilder, - \v!right=>\let\next\dofloatboxnextrightbuilder]% - \next} - -\def\dofloatboxsidebuilder - {\ifparfloat - \let\next\dofloatboxhighbuilder - \else - \let\next\dofloatboxmiddlebuilder - \expanded{\processallactionsinset[\floatcaptionparameter\c!location]} - [ \v!low=>\let\next\dofloatboxlowbuilder, - \v!middle=>\let\next\dofloatboxmiddlebuilder, - \v!high=>\let\next\dofloatboxhighbuilder]% - \fi - \next} - -\def\doflushfloatleftcaptionhang - {\hsmash{\llap{\box\tempcaptionbox\dotfskip{\floatcaptionparameter\c!distance}}}} -\def\doflushfloatrightcaptionhang - {\hsmash{\rlap{\dotfskip{\floatcaptionparameter\c!distance}\box\tempcaptionbox}}} - -\def\doflushfloatcaptionhang - {\expanded{\doifinsetelse{\v!righthanging}{\floatcaptionparameter\c!location}} - {\doflushfloatrightcaptionhang} - {\expanded{\doifinsetelse{\v!lefthanging}{\floatcaptionparameter\c!location}} - {\doflushfloatleftcaptionhang} - {\expanded{\doifinsetelse{\v!hang}{\floatcaptionparameter\c!location}} - {\expanded{\doifinsetelse{\v!outer}{\floatcaptionparameter\c!location}} - {\doifrightpagefloatelse{\doflushfloatrightcaptionhang}{\doflushfloatleftcaptionhang}} - {\expanded{\doifinsetelse{\v!right}{\floatcaptiondirectives}} - {\doflushfloatrightcaptionhang} - {\doflushfloatleftcaptionhang}}} - {\box\tempcaptionbox}}}} - -\def\dofloatboxhighbuilder - {\dofloatboxnextbuilder{\dofloatboxbetweenstack\doflushfloatcaptionhang\vfill}} - -\def\dofloatboxlowbuilder - {\dofloatboxnextbuilder{\vfill\doflushfloatcaptionhang\dofloatboxbetweenstack}} - -\def\dofloatboxmiddlebuilder - {\dofloatboxnextbuilder{\vfill\box\tempcaptionbox\vfill}} - -% \definefloat -% [lefty][lefties][figure] -% \setupfloat -% [lefty] -% [default=left, -% rightmargindistance=-2cm, -% leftmargindistance=-2cm] -% \setupcaption -% [lefty] -% [location={bottom,overlay}] -% -% \starttext -% \placelefty{}{} \input tufte \input tufte -% \placelefty{}{} \input tufte \input tufte -% \stoptext - -\def\bothangfloat#1{\ruledvbox to \ht\tempfloatbox{#1\vss}} -\def\tophangfloat#1{\ruledvbox to \ht\tempfloatbox{\vss#1}} - -\def\dofloatboxnormaltopstackbuilder - {\expanded{\doifinset{\v!overlay}{\floatcaptionparameter\c!location}}\tophangfloat - {\tempfloatwidth\wd\tempfloatbox - \ifparfloat - \hbox{\locatesidefloat{\box\tempcaptionbox}}% - \dofloatboxbetweenstack - \hbox{\hbox {\box\tempfloatbox }}% - \else - \hbox{\locatetextfloat{\box\tempcaptionbox}} - \dofloatboxbetweenstack - \hbox{\locatefloat {\box\tempfloatbox }}% - \fi}} - -\def\dofloatboxnormalbotstackbuilder - {\expanded{\doifinset{\v!overlay}{\floatcaptionparameter\c!location}}\bothangfloat - {\tempfloatwidth\wd\tempfloatbox - \ifparfloat - \hbox{\hbox {\box\tempfloatbox }}% - \dofloatboxbetweenstack - \hbox{\locatesidefloat{\box\tempcaptionbox}}% - \else - \hbox{\locatefloat {\box\tempfloatbox }}% - \dofloatboxbetweenstack - \hbox{\locatetextfloat{\box\tempcaptionbox}}% - \fi}} - -\def\dofloatboxgridtopstackbuilder - {\dp\tempcaptionbox\strutdepth - \setbox\scratchbox\vbox - {\tempfloatwidth\wd\tempfloatbox - \ifparfloat - \locatesidefloat{\box\tempcaptionbox}% - \vss\dofloatboxbetweenstack - \hbox {\box\tempfloatbox }% - \else - \locatetextfloat{\box\tempcaptionbox}% - \vss\dofloatboxbetweenstack - \locatefloat {\box\tempfloatbox }% - \fi}% - \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy - \vbox to \noflines\lineheight{\unvbox\scratchbox}} - -\def\dofloatboxgridbotstackbuilder - {\dp\tempcaptionbox\strutdepth - \setbox\scratchbox\vbox - {\tempfloatwidth\wd\tempfloatbox - \ifparfloat - \hbox {\box\tempfloatbox }% - \vss\dofloatboxbetweenstack - \locatesidefloat{\box\tempcaptionbox}% - \else - \locatefloat {\box\tempfloatbox }% - \vss\dofloatboxbetweenstack - \locatetextfloat{\box\tempcaptionbox}% - \fi}% - \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy - \vbox to \noflines\lineheight{\unvbox\scratchbox}} - -\def\dofloatboxstretchtopstackbuilder - {\dp\tempcaptionbox\strutdepth - \setbox\scratchbox\vbox - {\locatecaption{\copy\tempcaptionbox}% - \locatefloat {\copy\tempfloatbox }}% - \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy - \vbox to \noflines\lineheight - {\tempfloatwidth\wd\tempfloatbox - \ifparfloat - \locatesidefloat{\box\tempcaptionbox}% - \vss\dofloatboxbetweenstack\vss - \hbox {\box\tempfloatbox }% - \else - \locatetextfloat{\box\tempcaptionbox}% - \vss\dofloatboxbetweenstack\vss - \locatefloat {\box\tempfloatbox }% - \fi}} - -\def\dofloatboxstretchbotstackbuilder - {\dp\tempcaptionbox\strutdepth - \setbox\scratchbox\vbox - {\locatefloat {\copy\tempfloatbox }% - \locatecaption{\copy\tempcaptionbox}}% - \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy - \vbox to \noflines\lineheight - {\tempfloatwidth\wd\tempfloatbox - \ifparfloat - \hbox {\box\tempfloatbox }% - \vss\dofloatboxbetweenstack\vss - \locatesidefloat{\box\tempcaptionbox} - \else - \locatefloat {\box\tempfloatbox }% - \vss\dofloatboxbetweenstack\vss - \locatetextfloat{\box\tempcaptionbox}% - \fi}} - -\def\dofloatboxtopbuilder - {\let\next\dofloatboxnormaltopstackbuilder - \expanded{\processfirstactioninset[\floatcaptionparameter\c!location]} - [ \v!grid=>\let\next\dofloatboxgridstackbuilder, - \v!stretch=>\let\next\dofloatboxstretchstackbuilder]% - \next} - -\def\dofloatboxbottombuilder - {\let\next\dofloatboxnormalbotstackbuilder - \expanded{\processfirstactioninset[\floatcaptionparameter\c!location]} - [ \v!grid=>\let\next\dofloatboxgridstackbuilder, - \v!stretch=>\let\next\dofloatboxstretchstackbuilder]% - \next} - -\def\relocatecaptionright#1{\locatecaption{\hbox to \tempfloatwidth{\hss#1}}} -\def\relocatecaptionleft #1{\locatecaption{\hbox to \tempfloatwidth{#1\hss}}} - -\long\def\installfloatboxbuilder#1#2{\setvalue{\??kj:#1}{#2}} - -\def\buildfloatbox - {\global\setbox\floatbox\vbox - {\setlocalfloathsize - \forgetall - \let\floatcaptionarrangement\s!default - \def\docommand##1% - {\doifdefined{\??kj:##1}{\def\floatcaptionarrangement{##1}\quitcommalist}}% - \processcommacommand[\floatcaptionparameter\c!location]\docommand - \executeifdefined{\??kj:\floatcaptionarrangement}{\getvalue{\??kj:\s!default}}}} - -\def\locatetextfloat - {\let\next\locatecaption - \expanded{\processallactionsinset[\floatcaptionparameter\c!location]} - [ \v!left=>\let\next\relocatecaptionleft, - \v!right=>\let\next\relocatecaptionright, - \v!inner=>\doifrightpagefloatelse{\let\next\relocatecaptionleft }{\let\next\relocatecaptionright}, - \v!outer=>\doifrightpagefloatelse{\let\next\relocatecaptionright}{\let\next\relocatecaptionleft }]% - \next} - -\installfloatboxbuilder \v!none \dofloatboxdefaultbuilder -\installfloatboxbuilder \s!default \dofloatboxdefaultbuilder -\installfloatboxbuilder \v!high \dofloatboxhighbuilder -\installfloatboxbuilder \v!low \dofloatboxlowbuilder -\installfloatboxbuilder \v!middle \dofloatboxmiddlebuilder - -\installfloatboxbuilder \v!left \dofloatboxsidebuilder -\installfloatboxbuilder \v!right \dofloatboxsidebuilder - -\installfloatboxbuilder \v!top \dofloatboxtopbuilder -\installfloatboxbuilder \v!bottom \dofloatboxbottombuilder - -% \setuplayout[grid=yes] \showgrid \setupcaptions[style=smallbodyfont,location=grid,inbetween=] -% -% \starttext -% test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=yes]} test \page -% test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=yes]} test \page -% test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=depth]} test \page -% test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=depth]} test \page -% \stoptext - -\newif\ifpostponecolumnfloats \postponecolumnfloatsfalse % don't change - -\chardef\postcenterfloatmethod\plusone - -\def\postcenterfloatbox#1% - {\scratchdimen - \ifcase\postcenterfloatmethod - #1% \wd\floatbox - \or\ifinsidecolumns - \ifpostponecolumnfloats\makeupwidth\else#1\fi - \else\ifdim#1>\hsize - \hsize - \else - \wd\floatbox - \fi\fi\fi - \global\setbox\floatbox\hbox to \scratchdimen - % {\hfill\box\floatbox\hfill}} % geen \hss, gaat mis in kolommen ! - % {\hss \box\floatbox\hss }} % wel \hss, anders mis in colset - {\ifglobalcenterfloatbox - \donetrue - \else\iflocalcenterfloatbox - \donetrue - \else - \donefalse - \fi\fi - \ifdim\scratchdimen>\effectivehsize - \donefalse - \fi - \hss\ifdone\hskip\effectiveleftskip\fi - \box\floatbox - \ifdone\hskip\effectiverightskip\fi\hss}} - -\long\def\dosetparfloat#1#2#3% - {\bgroup - \forgetall - \postponenotes - \dontcomplain - %\showcomposition - \setbox\tempfloatbox\vbox{\borderedfloatbox}% - \addlocalbackgroundtobox\tempfloatbox % no \doglobal - \docheckcaptioncontent{#2}{#3}% - \ifnofloatcaption - \global\setbox\floatbox\vbox{\box\tempfloatbox}% - \else - \dopreparedosidecaption{#1}{#2}{#3}% - \settracedcaptionbox - \setbox\tempcaptionbox\hbox{\floatcaptionparameter\c!command{\box\tempcaptionbox}}% - \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht - \addlocalbackgroundtobox\tempcaptionbox % no \doglobal - \buildsidefloatbox - \fi - \egroup} - -\def\dopreparedosidecaption#1#2#3% will be enhanced - {\doifelse{\floatcaptionparameter\c!width}\v!max - {\dosettempcaptionbox - {\hsize\wd\tempfloatbox - \putcompletecaption{#2}{#3}}}% - {\doifelse{\floatcaptionparameter\c!width}\v!fit - {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox\relax - \setbox\tempcaptionbox\vbox - {\forgetall % needed? - \hsize\wd\tempfloatbox - \dosetcaptionthings - \putcompletecaption{#2}{#3}}% - \else - \setbox\tempcaptionbox\hbox to \wd\tempfloatbox - {\hss\box\tempcaptionbox\hss}% - \fi} - {\dosettempcaptionbox - {\hsize\floatcaptionparameter\c!width % \wd\tempfloatbox - \putcompletecaption{#2}{#3}}}}} - -\def\buildsidefloatbox - {\let\locatefloat \relax - \let\locatecaption\relax - \def\locatesidefloat##1% - {\begingroup - \chardef\alignstrutmode\zerocount - \hsize\tempfloatwidth \forgetall - \alignedline{\floatparameter\c!location}\v!middle{##1}% - \endgroup}% - \buildfloatbox} - -\newif\ifparfloat - -\long\def\dosetfloatbox#1#2#3% todo : \global\setbox - {\ifvisible - \par - \edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}% - \ifparfloat\@EA\dosetparfloat\else\@EA\dosetpagfloat\fi{#1}{#2}{#3}% - \setlocalfloatdimensions{#1}% - \setbox\floatbox\hbox - {\dosavefloatdata\restoretextcolor{\box\floatbox}}% - \global\floatheight\ht\floatbox - \global\advance\floatheight \dp\floatbox - \global\floatwidth\wd\floatbox - \global\advance\totalnoffloats \plusone - \doifnotinset\v!margin{#1} % gaat namelijk nog fout - {\setbox\floatbox\vbox - {\parindent\zeropoint - \doifconcepttracing{\inleftmargin{\framed{\infofont\the\totalnoffloats}}}% - \box\floatbox}}% - \wd\floatbox\floatwidth - \dimen0=\floatheight - \advance\dimen0 \lineheight - \ifdim\dimen0<\textheight - \else - \global\floatheight\textheight - \global\advance\floatheight -\lineheight - \ht\floatbox\floatheight - \dp\floatbox\zeropoint - \showmessage\m!floatblocks{10}{\the\totalnoffloats}% - \fi - \fi} - -\newcounter\noxfloatlocations - -\long\def\dofloat#1#2#3% #1 is optionlist - {\dosetfloatbox{#1}{#2}{#3}% - \dogetfloatbox{#1}\empty} - -\def\dooutput{\sidefloatoutput} % redefinition of \dooutput - -\definefloat - [\v!figure] - [\v!figures] - -\definefloat - [\v!table] - [\v!tables] - -\setupfloat - [\v!table] - [\c!frame=\v!off] - -\definefloat - [\v!intermezzo] - [\v!intermezzi] - -\definefloat - [\v!graphic] - [\v!graphics] - -% float strategy, replaces some of the above macros - -\let\floatmethod \empty -\let\floatcolumn \empty -\let\floatrow \empty -\let\forcedfloatmethod\empty - -\def\dogetfloatbox#1#2% - {\ifvisible - \doifelsenothing{#2} - {\getfromcommalist[#1][1]% - \@EA\beforesplitstring\commalistelement\at:\to\floatmethod - \@EA\aftersplitstring \commalistelement\at:\to\floatcolumn - \@EA\aftersplitstring \floatcolumn\at*\to\floatrow - \@EA\beforesplitstring\floatcolumn\at*\to\floatcolumn - % todo: nog algemeen otr - \ifx\OTRSETsetpreferedcolumnslot\undefined\else - \OTRSETsetpreferedcolumnslot\floatcolumn\floatrow - \fi} - {\let\floatcolumn\empty - \let\floatrow\empty - \edef\floatmethod{#2}}% - \doifundefined{\string\floatmethod\floatmethod} - {\let\floatmethod\v!here}% - \doifsomething\forcedfloatmethod - {\edef\floatmethod{\forcedfloatmethod}}% - %\getvalue{\string\floatmethod\floatmethod}[#1]% - \getvalue{\string\floatmethod\floatmethod}[\floatmethod,#1]% - \fi} - -\def\installfloathandler#1#2% #1=keyword #2=handler - {\setvalue{\string\floatmethod#1}{#2}} - -\installfloathandler \v!here \someherefloat -\installfloathandler \v!force \somefixdfloat -\installfloathandler \v!left \someleftsidefloat -\installfloathandler \v!right \somerightsidefloat -\installfloathandler \v!text \sometextfloat -\installfloathandler \v!top \sometopfloat -\installfloathandler \v!bottom \somebottomfloat -\installfloathandler \v!auto \someautofloat -\installfloathandler \v!margin \somemarginfloat -\installfloathandler \v!opposite \somefacefloat -\installfloathandler \v!page \somepagefloat -\installfloathandler \v!leftpage \someleftpagefloat -\installfloathandler \v!rightpage \somerightpagefloat -\installfloathandler \v!inmargin \someinmarginfloat -\installfloathandler \v!inleft \someinleftmarginfloat -\installfloathandler \v!inright \someinrightmarginfloat -\installfloathandler \v!leftmargin \someinleftmarginfloat -\installfloathandler \v!rightmargin \someinrightmarginfloat -\installfloathandler \v!leftedge \someinleftedgefloat -\installfloathandler \v!rightedge \someinrightedgefloat - -\installfloathandler \v!backspace \somebackspacefloat -\installfloathandler \v!cutspace \somecutspacefloat - -\installfloathandler {tblr} \someslotfloat -\installfloathandler {lrtb} \someslotfloat -\installfloathandler {tbrl} \someslotfloat -\installfloathandler {rltb} \someslotfloat -\installfloathandler {btlr} \someslotfloat -\installfloathandler {lrbt} \someslotfloat -\installfloathandler {btrl} \someslotfloat -\installfloathandler {rlbt} \someslotfloat -\installfloathandler {fxtb} \someslotfloat -\installfloathandler {fxbt} \someslotfloat - -\def\placesomeslotfloat {\OTRcommand\someslotfloat} -\def\placesomeherefloat {\OTRcommand\someherefloat} -\def\placesomefixdfloat {\OTRcommand\somefixdfloat} -\def\placesomepagefloat {\OTRcommand\somepagefloat} -\def\placesomeleftpagefloat {\OTRcommand\someleftpagefloat} -\def\placesomerightpagefloat{\OTRcommand\somerightpagefloat} -\def\placesometopsfloat {\OTRcommand\sometopsfloat} -\def\placesomebotsfloat {\OTRcommand\somebotsfloat} -\def\placesomesidefloat {\OTRcommand\somesidefloat} -\def\placesomefacefloat {\OTRcommand\somefacefloat} - -\def\someleftsidefloat [#1]{\somesidefloat[#1]\presetindentation} -\def\somerightsidefloat [#1]{\somesidefloat[#1]} -\def\sometopfloat [#1]{\someelsefloat[#1]\nonoindentation} -\def\somebottomfloat [#1]{\someelsefloat[#1]} -\def\someautofloat [#1]{\someelsefloat[#1]} -\def\somemarginfloat [#1]{\somenextfloat[#1]\nonoindentation} -\def\someinleftmarginfloat [#1]{\somesidefloat[#1]} -\def\someinrightmarginfloat[#1]{\somesidefloat[#1]} -\def\someinleftedgefloat [#1]{\somesidefloat[#1]} -\def\someinrightedgefloat [#1]{\somesidefloat[#1]} -\def\someinmarginfloat [#1]{\somesidefloat[#1]} -\def\someherefloat [#1]{\someelsefloat[\v!here,#1]} - -\def\somebackspacefloat [#1]{\somesidefloat[#1]} -\def\somecutspacefloat [#1]{\somesidefloat[#1]} - -\def\somefixdfloat {\placesomefixdfloat} -\def\somepagefloat {\placesomepagefloat} -\def\someleftpagefloat {\placesomeleftpagefloat} -\def\somerightpagefloat{\placesomerightpagefloat} -\def\somefacefloat {\placesomefacefloat} -\def\someslotfloat {\placesomeslotfloat} - -\protect \endinput diff --git a/tex/context/base/strc-ini.mkiv b/tex/context/base/strc-ini.mkiv new file mode 100644 index 000000000..619442998 --- /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. + +\def\definestructureresetset {\dotripleempty\dodefinestructureresetset} +\def\definestructureseparatorset {\dotripleempty\dodefinestructureseparatorset} +\def\definestructureconversionset{\dotripleempty\dodefinestructureconversionset} +\def\definestructureprefixset {\dotripleempty\dodefinestructureprefixset} + +\def\dodefinestructureresetset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:resets", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}",true)}} +\def\dodefinestructureseparatorset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:separators", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} +\def\dodefinestructureconversionset[#1][#2][#3]{\ctxlua{structure.sets.define("structure:conversions","#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} +\def\dodefinestructureprefixset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:prefixes", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} + +% \definestructureseparatorset [weird][!,?,*][:] % tex content +% \definestructureconversionset[weird][numbers,characters,romannumerals][numbers] % symbolic names +% \definestructureresetset [weird][0,0,1][0] % numbers + +\protect \endinput diff --git a/tex/context/base/strc-ini.tex b/tex/context/base/strc-ini.tex deleted file mode 100644 index 619442998..000000000 --- a/tex/context/base/strc-ini.tex +++ /dev/null @@ -1,88 +0,0 @@ -%D \module -%D [ file=strc-flt, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Initialization \& Helpers, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Initialization & Helpers} - -\registerctxluafile{strc-ini}{1.001} - -\unprotect - -% \def\zerosection{0} -% \def\resetsectionmarks{} -% \setuppagenumbering - -% maybe use structurecomponent more consistently as name below - -% segments: 0:100 2:3 chapter:subsection 3 (=self+2) (alternative: sectionset) - -% section : [sectionnumber(s)] -% sectionseparatorset (default) sectionconversionset (default) sectionstopper () sectionset sectionsegments - -% lists : [sectionnumber(s)] [text] [prefix(es)[separator]][pagenumber(s)] -% sectionseparatorset (default) sectionconversionset (default) sectionstopper sectionset sectionsegments -% prefixseparatorset (default) prefixconversionset (default) prefixstopper (.) prefixset prefixsegments -% pageseparatorset (default) pageconversionset (default) pagestopper () pagesegments -% prefix (no) - -% counter : [prefix(es)[separator]][number(s)] -% prefixseparatorset (default) prefixconversionset (default) prefixstopper (.) prefixset prefixsegments -% numberseparatorset (default) numberconversionset (default) numberstopper () numbersegments -% prefix (no) - -% pagenumber: [prefix(es)[separator]][pagenumber(s)] -% prefixseparatorset (default) prefixconversionset (default) prefixstopper (.) prefixset prefixsegments -% pageseparatorset (default) pageconversionset (default) pagestopper () -% prefix (no) - -% text mark reference list -% section P P P P -% float P.N P.N P.N -% itemize P.N P.N -% enumerate P.N P.N P.N -% formula P.N P.N -% footnote P.N P.N P.N -% number P.N P.N - -% number prefix section page - -% [text|marking|reference|list]:[number|prefix|pagenumber|pageprefix]:[separatorset|conversionset|conversion|stopper|set|segments|resetset|order] - -% figure caption : text:number:* text:prefix:* -> \setupcaption[figure][...]; stores defaults -% figure list : list:number:* list:prefix:* list:pagenumber:* list:pageprefix:* -> \setuplist[figure][...]; takes stored defaults for number and pagenumber] -% figure reference: reference:number:* reference:prefix:* reference:pagenumber:* reference:pageprefix:* -> \setupreference[figure]]...]; takes stored defaults - -% This module deals with structure: section headers, list and -% numbering and eventually cross referencing. These components are -% rather interwoven and therefore an inbetween layer is used. -% Eventually this will replace the corresponding code in core-sec, -% core-lst, core-num and core-ref. - -% We collect operations that deal with things like formatting on each -% level of a number in sets. This is all handles at the \LUA\ end. -% References to such sets travel with the multipass information. - -\def\definestructureresetset {\dotripleempty\dodefinestructureresetset} -\def\definestructureseparatorset {\dotripleempty\dodefinestructureseparatorset} -\def\definestructureconversionset{\dotripleempty\dodefinestructureconversionset} -\def\definestructureprefixset {\dotripleempty\dodefinestructureprefixset} - -\def\dodefinestructureresetset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:resets", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}",true)}} -\def\dodefinestructureseparatorset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:separators", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} -\def\dodefinestructureconversionset[#1][#2][#3]{\ctxlua{structure.sets.define("structure:conversions","#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} -\def\dodefinestructureprefixset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:prefixes", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} - -% \definestructureseparatorset [weird][!,?,*][:] % tex content -% \definestructureconversionset[weird][numbers,characters,romannumerals][numbers] % symbolic names -% \definestructureresetset [weird][0,0,1][0] % numbers - -\protect \endinput diff --git a/tex/context/base/strc-itm.mkii b/tex/context/base/strc-itm.mkii new file mode 100644 index 000000000..0148f83ca --- /dev/null +++ b/tex/context/base/strc-itm.mkii @@ -0,0 +1,1328 @@ +%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} + +% 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}{0}% + \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..dd639d72b --- /dev/null +++ b/tex/context/base/strc-itm.mkiv @@ -0,0 +1,1195 @@ +%D \module +%D [ file=strc-itm, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Itemgroups, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Itemgroups} + +\registerctxluafile{strc-itm}{1.001} + +\unprotect + +\newconditional\sublistitem \setfalse\sublistitem +\newconditional\symbollistitem \setfalse\symbollistitem +\newconditional\headlistitem \setfalse\headlistitem +\newconditional\introlistitem \setfalse\introlistitem +\newconditional\randomizeitems \setfalse\randomizeitems +\newconditional\autointrolistitem \setfalse\autointrolistitem +\newconditional\optimizelistitem \settrue \optimizelistitem +\newconditional\packlistitem \setfalse\packlistitem +\newconditional\paragraphlistitem \setfalse\paragraphlistitem +\newconditional\textlistitem \setfalse\textlistitem +\newconditional\firstlistitem \setfalse\firstlistitem +\newconditional\beforelistitem \setfalse\beforelistitem +\newconditional\afterlistitem \setfalse\afterlistitem +\newconditional\nowhitelistitem \setfalse\nowhitelistitem +\newconditional\joinedlistitem \setfalse\joinedwhitelistitem +\newconditional\reverselistitem \setfalse\reverselistitem +\newconditional\continuelistitems \setfalse\continuelistitems +\newconditional\fittinglistitems \setfalse\fittinglistitems + +\newcount\noflists +\newcount\currentnoflists +\newcount\noflistelements +\newcount\itemcolumndepth +\newcount\itemdepth +\newcount\maxitemdepth \maxitemdepth=6 + +\newdimen\itemgrouplistwidth +\newdimen\itemgroupaskedwidth +\newbox \itemgroupitembox + +\def\currentitemgroupcounter{itemgroup:\currentitemgroup} + +\let\currentitemlevel \!!zerocount +\let\currentitemgroup \empty +\let\currentnofitems \!!zerocount +\def\currentitemnumber {\dorawsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]} +\let\currentrepeatstart \empty + +\def\dolistreference + {\iftrialtypesetting \else % no need for different treatment of \continuelistitems + \ctxlua{structure.itemgroups.register("\currentitemgroup",\number\noflistelements,"\getitemparameter\currentitemlevel\c!maxwidth")}% + \fi} + +\def\checkcurrentnofitems % we could do this at the lua end and save a call + {\edef\currentnofitems {\ctxlua{structure.itemgroups.nofitems("\currentitemgroup",\number\currentnoflists)}}% + \edef\currentitemmaxwidth{\ctxlua{structure.itemgroups.maxwidth("\currentitemgroup",\number\currentnoflists)}\scaledpoint}} + +\def\dohandleitemreference % we will make a decent number helper + {\ifx\currentitemreference \empty \else + \setnextinternalreference + \ctxlua { + jobreferences.set("\s!full", "\referenceprefix","\currentitemreference", + { + metadata = { + kind = "list", + catcodes = \the\catcodetable, + xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text + }, + references = { + internal = \nextinternalreference, + section = structure.sections.currentid(), + }, + numberdata = structure.helpers.simplify { + numbers = structure.counters.compact("\currentitemgroupcounter",nil,true), + separatorset = "\structurecounterparameter\currentitemgroupcounter\c!numberseparatorset", + conversion = "\structurecounterparameter\currentitemgroupcounter\c!numberconversion", + conversionset = "\structurecounterparameter\currentitemgroupcounter\c!numberconversionset", + % for the moment no stopper, we need to make references configurable first + % stopper = \!!bs\structurecounterparameter\currentitemgroupcounter\c!numberstopper\!!es, + segments = "\structurecounterparameter\currentitemgroupcounter\c!numbersegments", + }, + }) + jobreferences.setinternalreference("\referenceprefix","\currentitemreference",\nextinternalreference) + }% + \fi} + +% \startitemize[n,packed] +% \item test \item test \item test +% \stopitemize +% +% \startitemize[n,packed,reverse] +% \item test \item test \item test +% \stopitemize +% +% \startitemize[n,packed,reverse] \item test \item test \stopitemize +% \startitemize[continue] +% \item test \startitemize[n,packed] \item test \item test \stopitemize +% \item test +% \item test +% \stopitemize +% \startitemize[continue] \item test \stopitemize +% +% \startitemize[n,packed] \item test \item test \stopitemize +% \startitemize[continue] \item test \stopitemize +% \startitemize[continue] \item test \stopitemize + +\def\itemparameter #1#2{\csname\doitemparameter{\??op\currentitemgroup#1}#2\endcsname} +\def\itemparameterhash#1#2{\doitemparameterhash {\??op\currentitemgroup#1}#2} + + +\def\doitemparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doitemparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\doitemparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doitemparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\doitemparentparameter #1#2{\ifx#1\relax\s!empty\else\doitemparameter #1#2\fi} +\def\doitemparentparameterhash#1#2{\ifx#1\relax \else\doitemparameterhash#1#2\fi} + +\def\dosetitemattributes#1#2#3% style color + {\edef\fontattributehash {\itemparameterhash#1#2}% + \edef\colorattributehash{\itemparameterhash#1#3}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #2\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#3\fi} + +\def\setitemparameter #1#2{\@EA \def\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} +\def\esetitemparameter#1#2{\@EA\edef\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} +\def\xsetitemparameter#1#2{\@EA\xdef\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} +\def\letitemparameter #1#2{\@EA \let\csname\??op\currentitemgroup#1#2\endcsname} +\let\getitemparameter \itemparameter + +\def\@@globalitemsymbol #1{\??op\currentitemgroup\c!symbol\s!global#1} +\def\@@localitemsymbol #1{\??op\currentitemgroup\c!symbol\s!local #1} +\def\@@currentitemsymbol#1{\??op\currentitemgroup\c!symbol #1} + +\def\@@itemcounter{\s!itemcount\currentitemgroup} + +\def\doitembreak#1{\ifconditional\optimizelistitem\ifconditional\textlistitem\else\dosomebreak#1\fi\fi} + +\def\allowitembreak {\doitembreak\allowbreak} +\def\noitembreak {\doitembreak\nobreak} +\def\itembreakspecial {\doitembreak\itembreak} +\def\noitembreakspecial{\doitembreak\itemnobreak} + +\def\itembreak {\flushnotes\penalty-5\relax} % -10 +\def\itemnobreak{\flushnotes\penalty+5\ifinsidecolumns\else00\fi\relax} % +5 + +\def\initializeitemgrouplevel#1% + {\ifcsname\??op\currentitemgroup#1\s!parent\endcsname + % ok + \else\ifnum#1>\plusone + \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup\the\numexpr#1-1\relax}% + \else + \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup}% + \fi\fi} + +\def\defineitemgroup + {\dotripleempty\dodefineitemgroup} + +\def\dodefineitemgroup[#1][#2][#3]% todo: clone + {\doifsomething{#1} + {\pushmacro\currentitemgroup + \def\currentitemgroup{#1}% + \setvalue{\e!start#1}{\startitemgroup[#1]}% + \setvalue{\e!stop#1}{\stopitemgroup}% + \setvalue{\e!setup#1\e!endsetup}{\setupitemgroup[#1]}% for old times sake + \doifelsenothing{#2} + {\getparameters[\??op#1][\s!parent=\??oo,#3]}% + {\doifassignmentelse{#2} + {\getparameters[\??op#1][\s!parent=\??oo,#2]}% + {\getparameters[\??op#1][\s!parent=\??op#2,#3]}}% + \dorecurse\maxitemdepth{\initializeitemgrouplevel\recurselevel}% + \definestructurecounter[itemgroup:#1]% + \popmacro\currentitemgroup}} + +\def\setupitemgroups % [#1] + {\dodoubleargument\getparameters[\??oo]} % [#1] + +\def\packitems + {\ifcase\currentitemlevel \else \settrue\packlistitem \fi} + +\def\dosetupitemgroupvariable[#1]% [#2]% niveau instellingen + {\doifelsenothing{#1} + {\getparameters[\??op\currentitemgroup\currentitemlevel]}% + {\getparameters[\??op\currentitemgroup#1]}} + +\def\dosetupitemgroupconstant#1% + {\global\setitemparameter\currentitemlevel\c!maxwidth{0}% + \processcommacommand[#1]\dodosetupitemgroupconstant} % expansion of #2 is handy for xml + +\def\dodosetupitemgroupconstant#1% + {\edef\itemgroupconstantvalue{#1}% + \ifx\itemgroupconstantvalue\empty\else + \splitstring\itemgroupconstantvalue\at*\to\itemgroupfirst\and\itemgroupsecond + \ifcsname\??op:::\itemgroupfirst\endcsname\csname\??op:::\itemgroupfirst\endcsname\fi + \fi} + +\newconditional\inlinelistitem \setfalse\inlinelistitem + +\setvalue{\??op:::\v!packed }{\packitems} +\setvalue{\??op:::\v!intro }{\settrue\introlistitem} % here? not set to false +\setvalue{\??op:::\v!autointro}{\settrue\autointrolistitem} +\setvalue{\??op:::\v!broad }{\ifx\itemgroupsecond\empty\def\itemgroupsecond{1}\fi + \letitemparameter\currentitemlevel\c!factor\itemgroupsecond} +\setvalue{\??op:::\v!text }{\settrue\textlistitem + \settrue\inlinelistitem + \settrue\joinedlistitem + \packitems} +\setvalue{\??op:::\v!columns }{\packitems} +\setvalue{\??op:::\v!before }{\settrue\beforelistitem} +\setvalue{\??op:::\v!after }{\settrue\afterlistitem} +\setvalue{\??op:::\v!nowhite }{\settrue\nowhitelistitem} +\setvalue{\??op:::\v!margin }{\setitemparameter\currentitemlevel\c!width{-2em}} % signal +\setvalue{\??op:::\v!inmargin }{\setitemparameter\currentitemlevel\c!width{-2em}} % signal +\setvalue{\??op:::\v!atmargin }{\doifnot\currentitemlevel{1}{\setitemparameter\currentitemlevel\c!width{0em}}} % signal +\setvalue{\??op:::\v!intext }{\settrue\inlinelistitem} +\setvalue{\??op:::\v!loose }{\setfalse\optimizelistitem} +\setvalue{\??op:::\v!fit }{\settrue\fittinglistitems} +\setvalue{\??op:::\v!nofit }{\setfalse\fittinglistitems} +\setvalue{\??op:v:\v!paragraph}{\settrue\paragraphlistitem + \packitems} +\setvalue{\??op:::\v!joinedup }{\settrue\joinedlistitem + \packitems} +\setvalue{\??op:::\v!serried }{\edef\itemgroupsecond{-\ifx\itemgroupsecond\empty1\else\itemgroupsecond\fi}% + \letitemparameter\currentitemlevel\c!factor\itemgroupsecond} +\setvalue{\??op:::\v!stopper }{\letitemparameter\currentitemlevel\c!placestopper\v!yes} % keep {} +\setvalue{\??op:::\v!unpacked }{\setfalse\packlistitem} +\setvalue{\??op:::\v!repeat }{\settrue\repeatlistitem} +\setvalue{\??op:::\v!reverse }{\settrue\reverselistitem} +\setvalue{\??op:::\v!standard }{\dosetupstandarditemgroup\currentitemlevel} + +\def\dosetupstandarditemgroup#1% + {\getparameters + [\??op\currentitemgroup#1] + [\c!width=1.5em,\c!factor=0,\c!distance=.5em,\c!inner=, + \c!beforehead=,\c!afterhead=\blank,\c!before=\blank,\c!inbetween=\blank,\c!after=\blank]} + +% \def\packeditemspacing{\empty} + +% \setupwhitespace[big] +% \starttext +% test \startitemize[joinedup] \item test \item test \stopitemize test \par +% test \startitemize[joinedup,nowhite] \item test \item test \stopitemize test \par +% test \startitemize[joinedup,nowhite,before] \item test \item test \stopitemize test \par +% test \startitemize[joinedup,nowhite,after] \item test \item test \stopitemize test \par +% \stoptext + +\def\itembeforecommand + {\ifconditional\nowhitelistitem + \ifconditional\beforelistitem + \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!before\fi + \else + \nowhitespace + \fi + \else\ifconditional\joinedlistitem + % \empty + \else + \getitemparameter\currentitemlevel\c!before + \fi\fi} + +\def\itemaftercommand + {\ifconditional\nowhitelistitem + \ifconditional\afterlistitem + \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!after\fi + \else + \nowhitespace + \fi + \else\ifconditional\joinedlistitem + % \empty + \else + \getitemparameter\currentitemlevel\c!after + \fi\fi} + +\def\iteminbetweencommand + {\ifconditional\nowhitelistitem + \nowhitespace + \else\ifconditional\joinedlistitem + % \empty + \else + \getitemparameter\currentitemlevel\c!inbetween + \fi\fi} + +\def\itembeforeheadcommand + {\ifconditional\nowhitelistitem + \nowhitespace + \else\ifconditional\joinedlistitem + % \empty + \else + \getitemparameter\currentitemlevel\c!beforehead + \fi\fi} + +\def\itemafterheadcommand + {\ifconditional\nowhitelistitem + \nowhitespace + \else\ifconditional\joinedlistitem + % \empty + \else + \getitemparameter\currentitemlevel\c!afterhead + \fi\fi} + +\def\dododododosetupitemgroup[#1][#2]% + {\doifassignmentelse{#2}% + {\dosetupitemgroupvariable[#1][#2]}% + {\setitemparameter{#1}\c!option{#2}}}% + +\def\dodododosetupitemgroup[#1][#2]% + {\doifsomething{#2} + {\doifelse{#1}\v!each + {\dorecurse\maxitemdepth{\normalexpanded{\noexpand\dododododosetupitemgroup[\recurselevel]}[#2]}} + {\normalexpanded{\noexpand\dododododosetupitemgroup[#1]}[#2]}}} + +% \def\dododosetupitemgroup[#1][#2]% +% {\doifelsenothing{#2} +% {\doifelsenothing{#1} +% {\dodododosetupitemgroup[\currentitemlevel][#2]} +% {\dodododosetupitemgroup[#1][#2]}} +% {\ifcase\currentitemlevel\relax +% \dodododosetupitemgroup[\v!each][#1]% +% \else +% \dodododosetupitemgroup[\currentitemlevel][#1]% +% \fi}} + +\def\dododosetupitemgroup[#1][#2]% + {\doifelsenothing{#2} + {\doifsomething{#1} + {\ifcase\currentitemlevel\relax + \dodododosetupitemgroup[\v!each][#1]% + \else + \dodododosetupitemgroup[\currentitemlevel][#1]% + \fi}}% + {\doifelsenothing{#1} + {\ifcase\currentitemlevel\relax + \dodododosetupitemgroup[\v!each][#2]% + \else + \dodododosetupitemgroup[\currentitemlevel][#2]% + \fi} + {\dodododosetupitemgroup[#1][#2]}}} + +\def\dodosetupitemgroup[#1][#2][#3][#4]% + {\pushmacro\currentitemgroup + \def\currentitemgroup{#1}% + \dododosetupitemgroup[#2][#3]% + \doifsomething{#4}{\dododosetupitemgroup[#2][#4]}% + \popmacro\currentitemgroup} + +\def\dosetupitemgroup[#1][#2][#3][#4]% + {\def\docommand##1{\dodosetupitemgroup[##1][#2][#3][#4]}% + \processcommalist[#1]\docommand} + +\def\setupitemgroup + {\doquadrupleempty\dosetupitemgroup} + +\def\doadvanceitem + {\ifconditional\sublistitem\else\ifconditional\symbollistitem\else + \doincrementsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]% + \fi\fi} + +\def\setitemlevel#1% + {\ifnum\currentitemlevel>\zerocount + \settrue\firstlistitem + \ifconditional\continuelistitems\else + \dorestartsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]{\the\numexpr\getitemparameter\currentitemlevel\c!start-1\relax}% + \fi + \fi} + +\unexpanded\def\actualitemnumber + {\ifconditional\repeatlistitem + \ifcase\currentitemlevel\or\else + \doactualitemnumber + \fi + \else + \doactualitemnumber + \fi} + +\def\doactualitemnumber + {\begingroup + \setupstructurecounter + [\currentitemgroupcounter] + [\c!prefix=\v!no, + \c!numberorder=\ifconditional\reverselistitem\v!reverse\else\v!normal\fi, + \c!numberstopper=\expdoif{\getitemparameter\currentitemlevel\c!placestopper}\v!yes{\getitemparameter\currentitemlevel\c!stopper}, + %\c!numberseparatorset=, + %\c!numberconversionset=, + \c!numberconversion=\currentitemsymbol, + \c!numbersegments=\ifx\currentrepeatstart\empty\else\currentrepeatstart:\fi\number\currentitemlevel]% + \ifconditional\reverselistitem + \convertedstructurecounter[\currentitemgroupcounter]% [\number\currentitemlevel]% + \else + \convertedstructurecounter[\currentitemgroupcounter]% [\number\currentitemlevel]% + \fi + \dohandleitemreference + \endgroup} + +\def\unknownitemsymbol{?} + +\def\setitemmark#1% % en pas op: resets \docommand ; todo: conversionset + {\doifsymboldefinedelse{#1} + {\edef\currentitemsymbol{#1}% + \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}% + \setgvalue{\@@localitemsymbol \currentitemlevel}{\unknownitemsymbol}% + \def\listitem{\symbol[\currentitemsymbol]}% + \let\@@opsymbol\empty}% + {\doifconversiondefinedelse{#1} + {\edef\currentitemsymbol{#1}% + \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}% + \setgvalue{\@@localitemsymbol\currentitemlevel }{\actualitemnumber }% + \def\listitem + {\ifconditional\textlistitem + % maybe block stopper here, but one can as well clone an + % itemgroup then + \getitemparameter\currentitemlevel\c!lefttext + \getvalue{\@@localitemsymbol\currentitemlevel}% + \getitemparameter\currentitemlevel\c!righttext + \else + \getitemparameter\currentitemlevel\c!left + \getvalue{\@@localitemsymbol\currentitemlevel}% + \getitemparameter\currentitemlevel\c!right + \fi}% + \let\@@opsymbol\empty}% + {}}} + +\def\calculatelistwidth#1% distance deals with 'broad' + {\itemgrouplistwidth\getitemparameter#1\c!distance\relax + \ifnum\getitemparameter#1\c!factor>\zerocount + \ifdim\itemgrouplistwidth=\zeropoint \itemgrouplistwidth=.5em\fi + \fi + \multiply\itemgrouplistwidth \getitemparameter#1\c!factor + \advance \itemgrouplistwidth \getitemparameter#1\c!width\relax} + +% The next conditionals deal with \item \startitemgroup. It +% looks like a hack to skip back, but that way we preserve +% the indentation and bullet placement. It's a rather +% untested feature. + +\newconditional\concatnextitem \setfalse\concatnextitem +\newconditional\autoconcatnextitem \settrue \autoconcatnextitem +\newsignal \itemsignal + +\def\startitemgroup + {\dotripleempty\dostartitemgroup} + +\def\dostartitemgroup[#1][#2][#3]% + {\bgroup + \ifnum\currentitemlevel=\zerocount + \def\currentitemgroup{#1}% no nested mixing of itemgroups + \fi + \ifthirdargument + \dodostartitemgroup[#2][#3]% + \else + \doifassignmentelse{#2} + {\dodostartitemgroup[][#2]} + {\dodostartitemgroup[#2][]}% + \fi} + +\def\dodostartitemgroup[#1]% [#2]% + {\relax % prevents lookahead + \ifnum\currentitemlevel=\maxitemdepth\relax + \showmessage\m!layouts9{\number\maxitemdepth}% + \let\itemincrement\zerocount + \else + \let\itemincrement\plusone + \fi + \global\advance\itemdepth\itemincrement + \xdef\currentitemlevel{\number\itemdepth}% + \edef\itemgroupoptions{\getitemparameter\currentitemlevel\c!option}% + \ifx\itemgroupoptions\empty + \edef\itemgroupoptions{#1}% + \else + \doifsomething{#1}{\edef\itemgroupoptions{\itemgroupoptions,#1}}% + \fi + \normalexpanded{\noexpand\redostartitemgroup[\itemgroupoptions]}}% [#2] + +\let\startcollectitems\relax +\let\stopcollectitems \relax + +%D A nice example of a plugin: +%D +%D \startbuffer +%D \startitemize[a,random,packed] +%D \startitem first \stopitem \startitem second \stopitem +%D \startitem third \stopitem \startitem fourth \stopitem +%D \stopitemize +%D +%D \startitemize[a,random,packed] +%D \startitem first \stopitem \startitem second \stopitem +%D \startitem third \stopitem \startitem fourth \stopitem +%D \stopitemize +%D +%D \startitemize[a,packed] +%D \startitem first \stopitem \startitem second \stopitem +%D \startitem third \stopitem \startitem fourth \stopitem +%D \stopitemize +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +% better collectitems als conditional and a real plugin mechanism (some day) + +\@EA\long\@EA\def\@EA\collectitemgroupitem\@EA#\@EA1\csname\e!stop\v!item\endcsname + {\increment\itemcollectcounter + \long\setvalue{\v!item*\itemcollectcounter}{\item#1\par}} + +\def\flushcollecteditems + {\ifconditional\randomizeitems + \getrandomnumber\itemcollectcounternow\plusone\itemcollectcounter + \else + \increment\itemcollectcounternow + \fi + \doifdefined{\v!item*\itemcollectcounternow} + {\getvalue{\v!item*\itemcollectcounternow}% + \letbeundefined{\v!item*\itemcollectcounternow}% + \increment\itemcollectcounterdone}% + \ifnum\itemcollectcounterdone<\itemcollectcounter\relax + \expandafter\flushcollecteditems + \fi} + +\def\stopcollectitems + {\ifconditional\randomizeitems + \newcounter\itemcollectcounterdone + \ifnum\itemcollectcounter>\zerocount + \@EAEAEA\flushcollecteditems + \fi + \fi} + +\def\startcollectitems + {\ifconditional\randomizeitems + \newcounter\itemcollectcounter + \letvalue{\e!start\v!item}\collectitemgroupitem + \fi} + +%D End of plugin. + +\ifx\startcolumns\undefined \def\startcolumns[#1]{} \fi +\ifx\stopcolumns \undefined \let\stopcolumns\relax \fi + +\def\dosetsymalign#1% hm, we should use one of the core-spa macros or make a helper + {\processaction + [#1] + [ \v!flushleft=>\let\symalignleft\relax, + \v!right=>\let\symalignleft\relax, + \v!flushright=>\let\symalignleft\hfill, + \v!left=>\let\symalignleft\hfill, + \v!middle=>\let\symalignleft\hfil, + \v!center=>\let\symalignleft\hfil]} + +\def\redostartitemgroup[#1][#2]% + {\setfalse\inlinelistitem % new, no indent (leftskip) + \setfalse\concatnextitem % new, concat + \setfalse\txtlistitem + \ifhmode + \ifconditional\autoconcatnextitem % new, concat + \ifdim\lastskip=\itemsignal % new, concat + \settrue\concatnextitem % new, concat + \fi % new, concat + \fi % new, concat + \ifconditional\textlistitem\else\doifnotinset\v!text{#1}\par\fi % suboptimal + \fi + \begingroup + % new where, ok or not / we should integrate random, intro, continue here + % beware, the following no longer inherit from the previous level, is this ok? + \setfalse\reverselistitem + \setfalse\introlistitem + \setfalse\autointrolistitem + \setfalse\beforelistitem + \setfalse\afterlistitem + \setfalse\nowhitelistitem + \setfalse\randomizeitems + % + \doifinsetelse\v!intro {#1}{\settrue\introlistitem }{\setfalse\introlistitem }% + \doifinsetelse\v!random {#1}{\settrue\randomizeitems }{\setfalse\randomizeitems }% + \doifinsetelse\v!continue{#1}{\settrue\continuelistitems}{\setfalse\continuelistitems}% + % == \doifinsetelse\v!intro{#1}\settrue\setfalse\introlistitem + \global\advance\noflists\plusone + \currentnoflists\noflists + \noflistelements\zerocount + \setfalse\headlistitem + \setfalse\sublistitem + \setfalse\symbollistitem + \let\marsymbol\relax + \globallet\doitemdestination\empty + \let\symsymbol\empty + \let\symalignleft\relax + \the\itemgroupcommands + \checkcurrentnofitems + % \getitemparameter\currentitemlevel\empty + \let\listitem\empty % ** start value + \doifelsenothing{#1} % iffirstargument + {\edef\@@opsymbol{\noexpand\getitemparameter\currentitemlevel\noexpand\c!symbol}% + \letgvalueempty{\@@globalitemsymbol\currentitemlevel}% + \global\letitemparameter\currentitemlevel\v!continue\empty + \dosetupitemgroupvariable[\currentitemlevel][#2]} + {\dosetupitemgroupconstant{#1}% + \dosetupitemgroupvariable[\currentitemlevel][#2]% + \ifconditional\continuelistitems + \edef\@@opsymbol{\executeifdefined{\@@globalitemsymbol\currentitemlevel}{\currentitemlevel}}% + \getitemparameter\currentitemlevel\v!continue + \else + \edef\@@opsymbol{\noexpand\getitemparameter\currentitemlevel\noexpand\c!symbol}% + \global\setitemparameter\currentitemlevel\v!continue + {\dosetupitemgroupconstant{#1}% + \dosetupitemgroupvariable[\currentitemlevel][#2]}% + \fi + \def\docommand##1% \setitemmark resets \docommand + {\doifnot{##1}{0}{\setitemmark{##1}}}% + % \processcommalist[#1,\@@opsymbol]\docommand + \processcommalist[#1]\docommand}% ** preset sequence or provided sequence + % moved to here, after settings + \ifnum\currentitemlevel=\plusone % NIEUW + \doadaptleftskip {\getitemparameter\currentitemlevel\c!margin}% + \doadaptleftskip {\getitemparameter\currentitemlevel\c!leftmargin}% + \doadaptrightskip{\getitemparameter\currentitemlevel\c!rightmargin}% + \fi + \dosetraggedcommand{\getitemparameter\currentitemlevel\c!align}\raggedcommand + \dosetsymalign{\getitemparameter\currentitemlevel\c!symalign}% + \doifsomething{\getitemparameter\currentitemlevel\c!indenting} + {\normalexpanded{\noexpand\setupindenting[\getitemparameter\currentitemlevel\c!indenting]}}% + % + \setitemlevel{#1}% moved to here + \ifx\listitem\empty + \setitemmark\@@opsymbol % ** default value + \ifx\listitem\empty + \edef\currentitemsymbol{\currentitemlevel}% ** fall back + \fi + \fi + \ifconditional\autointrolistitem\ifnum\prevgraf<3 + \settrue\introlistitem + \fi\fi + \ifconditional\paragraphlistitem + \ifnum\currentitemlevel>\plusone + \letitemparameter\currentitemlevel\c!inbetween\empty + \fi + \fi + \ifconditional\packlistitem + \letitemparameter\currentitemlevel\c!inbetween\empty + \fi + \doifinset\v!columns{#1}% + {\ifinsidecolumns\else\ifcase\itemcolumndepth + \global\itemcolumndepth\currentitemlevel\relax + \itembeforecommand + \processfirstactioninset + [#1] + [ \v!one=>\setitemparameter\currentitemlevel\c!n{1}, + \v!two=>\setitemparameter\currentitemlevel\c!n{2}, + \v!three=>\setitemparameter\currentitemlevel\c!n{3}, + \v!four=>\setitemparameter\currentitemlevel\c!n{4}, + \v!five=>\setitemparameter\currentitemlevel\c!n{5}, + \s!unknown=>\@EA\!!counta\getitemparameter\currentitemlevel\c!n]% + \startcolumns + [\c!n=\getitemparameter\currentitemlevel\c!n, + \c!height=, + \c!rule=\v!off, + \c!balance=\v!yes, + \c!align=\v!no]% + \fi\fi}% + \ifconditional\fittinglistitems + \ifdim\currentitemmaxwidth>\zeropoint + \esetitemparameter\currentitemlevel\c!width{\currentitemmaxwidth}% + \fi + \fi + \calculatelistwidth\currentitemlevel + \ifdim\itemgrouplistwidth>\zeropoint\relax + \ifconditional\inlinelistitem\else + \advance\leftskip\itemgrouplistwidth\relax + \fi + \fi + \startcollectitems} + +% test / example +% +% \startnarrower[left] \startcolumns[n=3] \startitemize +% \item \input ward \item \input ward \item \input ward +% \stopitemize \stopcolumns\stopnarrower \blank +% +% \startnarrower[left] \startitemize[columns,three] +% \item \input ward \item \input ward \item \input ward +% \stopitemize \stopnarrower \blank +% +% \setupitemize[leftmargin=1.5em] \startitemize[columns,three] +% \item \input ward \item \input ward \item \input ward +% \stopitemize \blank + +\def\stopitemgroup + {\stopcollectitems + \ifconditional\textlistitem + \removeunwantedspaces\space\ignorespaces + \else + \par + \fi + \dolistreference + \ifconditional\firstlistitem \else \endgroup \fi % toegevoegd, eerste \som opent groep + \ifnum\itemcolumndepth=\currentitemlevel\relax + \stopcolumns + \global\itemcolumndepth\zerocount + \itemaftercommand + \dontrechecknextindentation + \else + \ifnum\currentitemlevel=\plusone + \allowitembreak + \itemaftercommand + \checknextindentation[\getitemparameter\currentitemlevel\c!indentnext]% + \else + % nieuw, not yet nobreak handling + \ifcase\autoitemgroupspacing + \itemaftercommand + \or + \itemaftercommand + \fi + \dontrechecknextindentation + \fi + \fi + % new test, needed in sidefloats (surfaced in volker's proceedings) + \ifconditional\textlistitem % else forgotten + \endgroup + \global\advance\itemdepth-\itemincrement + \xdef\currentitemlevel{\number\itemdepth}% + \egroup + \else + \endgroup + \global\advance\itemdepth-\itemincrement + \xdef\currentitemlevel{\number\itemdepth}% + \egroup + \par + \fi + \dorechecknextindentation} + +\newtoks\itemgroupcommands + +\def\itemgroupitem + {\doitemgroupitem} + +\def\itemgroupnoitem + {\doitemgroupnoitem} + +\def\itemgroupbutton[#1]% + {\gdef\doitemdestination{#1}% + \itemgroupitem} + +\def\itemgroupdummy + {\itemgroupsymbol{\strut}\strut} + +\def\itemgroupsubitem + {\settrue\sublistitem + \itemgroupitem} + +\def\itemgroupsymbol#1% + {\def\symsymbol{#1}% + \settrue\symbollistitem + \itemgroupitem} + +\def\itemgroupedge#1% + {\itemgroupsymbol + {\calculatelistwidth\currentitemlevel + \hbox to \itemgrouplistwidth + {#1\hskip\getitemparameter\currentitemlevel\c!distance}}} + +\def\itemgrouphead + {\settrue\headlistitem\doitemgrouphead} + +\def\itemgroupitems + {\dosingleempty\doitemgroupitems} + +\def\doitemgroupitems[#1]% + {\itemgroupedge + {\dorecurse{0\getitemparameter\currentitemlevel\c!items}{\listitem\hss}% + \unskip}} + +\def\itemgroupmargin#1% + {\def\marsymbol + {\llap + {\dosetitemattributes\currentitemlevel\c!marstyle\c!marcolor{#1}% + \hskip\leftskip\hskip\leftmargindistance}}% + \itemgroupitem} + +\appendtoks \let\item \itemgroupitem \to \itemgroupcommands +\appendtoks \let\noitem \itemgroupnoitem \to \itemgroupcommands +\appendtoks \letvalue\v!item \itemgroupitem \to \itemgroupcommands +\appendtoks \let\itm \itemgroupitem \to \itemgroupcommands +\appendtoks \let\but \itemgroupbutton \to \itemgroupcommands +\appendtoks \let\nop \itemgroupdummy \to \itemgroupcommands +\appendtoks \letvalue\v!sub \itemgroupsubitem \to \itemgroupcommands +\appendtoks \letvalue\v!sym \itemgroupsymbol \to \itemgroupcommands +\appendtoks \letvalue\v!ran \itemgroupedge \to \itemgroupcommands +\appendtoks \letvalue\v!head \itemgrouphead \to \itemgroupcommands +\appendtoks \letvalue\v!its \itemgroupitems \to \itemgroupcommands +\appendtoks \letvalue\v!mar \itemgroupmargin \to \itemgroupcommands + +% todo : \startitem .. \stopitem + +\appendtoks + \letvalue{\e!start\v!item}\itemgroupitem + \letvalue{\e!stop \v!item}\endgraf +\to \itemgroupcommands + +\appendtoks + \setvalue{\e!start\v!head}#1{\itemgrouphead#1\par}% + \letvalue{\e!stop \v!head}\endgraf +\to \itemgroupcommands + +% \startitemize +% \starthead {xx} test \stophead +% \startitem test \stopitem +% \startitem test \stopitem +% \stopitemize + +% Sometimes the user demands get pretty weird: +% +% \startitemize +% \item test +% \item test +% \headsym{xx} test \par test +% \stopitemize + +% aligned items +% +% \startitemize[n,fit,broad][itemalign=flushright] +% \dorecurse{100}{\item The first item.} +% \stopitemize +% +% \setupitemgroup[itemize][each][fit] +% \setupitemgroup[itemize][each][distance=.5em,factor=1,itemalign=flushright] +% +% \startitemize[n] +% \dorecurse{100}{\item The first item.} +% \stopitemize + +\appendtoks \let\headsym \itemgroupheadsym \to \itemgroupcommands + +\def\itemgroupheadsym#1% + {\def\symsymbol{#1}% + \settrue\symbollistitem + \settrue\headlistitem + \doitemgrouphead} + +% \defineitemgroup[gbitemize] +% \setupitemgroup[gbitemize][each][headstyle=bold] + +% \startgbitemize +% \txt{italian} some italians like this kind of cross||breed between +% an itemize and a description +% \txt{sicilians} i wonder how many sicilian mathematicians do a thesis +% on the math involved in predicting the next big bang of the vulcano +% \stopgbitemize + +\appendtoks \letvalue\v!txt\itemgrouptext \to \itemgroupcommands + +\newconditional\txtlistitem \setfalse\txtlistitem + +\def\itemgrouptext#1% + {\def\symsymbol{#1}% + \settrue\symbollistitem + \settrue\txtlistitem + \itemgroupitem} + +\def\dodotxtitem + {\scratchdimen\wd\itemgroupitembox + \advance \scratchdimen \getitemparameter\currentitemlevel\c!distance\relax + \ifdim\scratchdimen>\itemgrouplistwidth + \advance\scratchdimen -\itemgrouplistwidth + \else + \scratchdimen\zeropoint + \fi + \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hss}}% was: \hfill + \hskip\scratchdimen} + +\def\optimizelistitemsbreak + {\ifcase\itemcolumndepth \ifconditional\optimizelistitem + \ifcase \currentnofitems \else + \ifnum\currentnofitems=\plusthree + \ifnum\noflistelements>\plusone + \noitembreakspecial + \fi + \else\ifnum\currentnofitems>\plusthree + \ifnum\noflistelements=\plustwo + \ifconditional\introlistitem + \noitembreak + \else + \noitembreakspecial + \fi + \else\ifnum\currentnofitems=\noflistelements\relax + \noitembreakspecial + \else\ifnum\noflistelements>\plustwo + \itembreakspecial + \else + \ifconditional\introlistitem\else\itembreakspecial\fi + \fi\fi\fi + \fi\fi + \fi + \fi\fi} + +\def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken + {\ifconditional\textlistitem + % begin of item + \else + \par + \fi + \advance\noflistelements\plusone + \optimizelistitemsbreak + \noindent + \setbox\itemgroupitembox\hbox + {\ifconditional\headlistitem + \ifconditional\symbollistitem + \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}% + \else + \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor{\listitem}% + \fi + \else + \ifconditional\symbollistitem + \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}% + \else + \dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}% + \fi + \fi}% + \ifconditional\fittinglistitems + \ifdim\wd\itemgroupitembox>\getitemparameter\currentitemlevel\c!maxwidth sp\relax + \xsetitemparameter\currentitemlevel\c!maxwidth{\number\wd\itemgroupitembox}% + \fi + \ifdim\currentitemmaxwidth>\zeropoint + \setbox\itemgroupitembox\simplealignedbox{\getitemparameter\currentitemlevel\c!itemalign}{\currentitemmaxwidth}{\box\itemgroupitembox}% + \fi + \fi + \doifsomething\doitemdestination + {\setbox\itemgroupitembox\hbox{\goto{\box\itemgroupitembox}[\doitemdestination]}}% + \globallet\doitemdestination\empty + \itemgroupaskedwidth\getitemparameter\currentitemlevel\c!width\relax + % new, prevents loops when symbol is (not yet found) graphic + \ht\itemgroupitembox\strutheight + \dp\itemgroupitembox\strutdepth + % so that content differs per run (esp mp graphics afterwards) + \checkforrepeatedlistitem + \ifdim\itemgroupaskedwidth<\zeropoint\relax + \llap{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hskip\leftmargindistance}% + \else + \ifdim\itemgroupaskedwidth=\zeropoint\relax + \calculatelistwidth1% + \else + \calculatelistwidth\currentitemlevel + \fi + \ifconditional\textlistitem + \hbox{\ifconditional\sublistitem+\fi\box\itemgroupitembox\hskip\interwordspace}\nobreak + \else\ifconditional\inlinelistitem + \hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hss}% was: \hfill + \else\ifconditional\txtlistitem + \dodotxtitem + \else + % todo: align+marge binnen de hbox + \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi + \symalignleft + \box\itemgroupitembox\hfil + \hskip\getitemparameter\currentitemlevel\c!distance% T h + }}% + \fi\fi\fi + \fi + \forceunexpanded % needed for m conversion (\os) / i need to look into this + \setevalue{\@@currentitemsymbol\currentitemlevel}% + {\getvalue{\@@localitemsymbol\currentitemlevel}}% still problems with \uchar ? + %{\noexpand\getvalue{\@@localitemsymbol\currentitemlevel}}% no, spoils subrefs + \resetunexpanded + \setfalse\headlistitem + \setfalse\sublistitem + \setfalse\symbollistitem + \EveryPar{\ignorespaces}% needed ? + \ignorespaces} + +% For Wolfgang Schuster + +% \startitemize[n,repeat] +% \noitem \startitemize[a] \item Item 1.a. \item Item 1.b. \stopitemize +% \noitem \startitemize[a] \item Item 2.a. \item Item 2.b. \stopitemize +% \stopitemize + +\def\donolistitem % reduced \dolistitem + {\advance\noflistelements\plusone + \setbox\itemgroupitembox\hbox + {\dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}}% + \checkforrepeatedlistitem + \ignorespaces} + +\def\doitemgroupnoitem + {\doadvanceitem\donolistitem} + +% For Frank Grieshaber and Mojca Miklavec: + +\newconditional\repeatlistitem + +\def\checkforrepeatedlistitem + {\ifconditional\repeatlistitem + \ifx\currentrepeatstart\empty + \edef\currentrepeatstart{\the\numexpr\currentitemlevel-1}% + \fi + \setbox\itemgroupitembox\hbox to \wd\itemgroupitembox{\hskip-\itemgroupaskedwidth\box\itemgroupitembox}% what a hack ! + \fi} + +% \startbuffer +% \item +% \startitemize[n] +% \item item 1.1 +% \item item 1.2 +% \startitemize[n] \item item 1.2.1 \item item 1.2.2 \stopitemize +% \item item 1.3 +% \stopitemize +% \item +% \startitemize[n] \item item 2.1 \item item 2.2 \stopitemize +% \item item 3 +% \startitemize[n] \item item 3.1 \item item 3.2 \stopitemize +% \item +% \startitemize[n] \item item 4.1 \item item 4.2 \stopitemize +% \stopbuffer +% +% \startitemize[n,repeat,6*broad,packed] \getbuffer \stopitemize \blank[3*big] +% \startitemize[n,repeat,packed] \getbuffer \stopitemize \blank[3*big] +% \setupitemize[each][atmargin][width=3em] +% \startitemize[n,repeat,packed] \getbuffer \stopitemize + +\chardef\autoitemgroupspacing=2 % 0 = voor/na, 1=tussen als geen voor 2=(prev)tussen=old/normal + +\def\complexdoitemgroupitem[#1]% + {\def\currentitemreference{#1}% + \ifconditional\textlistitem + % begin of item + \else + \par + \fi + \ifconditional\concatnextitem % new, concat + \noitembreak % new, concat + \fi % new, concat + \doadvanceitem + \ifconditional\firstlistitem + \setfalse\firstlistitem + \begingroup + \ifcase\currentitemlevel + \or % 1 + \ifcase\itemcolumndepth + \ifconditional\introlistitem\noitembreak\fi + \itembeforecommand + \ifconditional\introlistitem\noitembreak\fi + \fi + \else % 2 en hoger + \ifconditional\paragraphlistitem \else + \edef\previtemlevel{\the\numexpr\currentitemlevel-1}% + \ifcase\autoitemgroupspacing\relax % nieuw + \itembeforecommand + \or + \doifelsenothing\itembeforecommand\itembeforecommand{\getitemparameter\previtemlevel\c!inbetween}% + \else + \getitemparameter\previtemlevel\c!inbetween + \fi + \fi + \fi + \else + \ifconditional\textlistitem % was bugged: \inlinelistitem + \removeunwantedspaces\hskip\emwidth\!!plus\interwordstretch\!!minus\interwordshrink\relax % new per 2006/10/20 + \else + \iteminbetweencommand + \fi + \fi + \ifconditional\concatnextitem + \vskip-\dimexpr\lastskip+\lineheight\relax + \nobreak + \fi + \dolistitem + \relax + \ifconditional\packlistitem + \setupwhitespace[\v!none]% + \fi + \getitemparameter\currentitemlevel\c!inner + \marsymbol + \let\marsymbol\relax + \strut % added 11-08-99 +% \dohandleitemreference + \setfalse\concatnextitem % new, concat + \nobreak % else problems with intext items + \hskip\itemsignal % new, concat + \getitemparameter\currentitemlevel\c!command} % \defaultitemcommand + +\def\defaultitemcommand + {\EveryPar{\ignorespaces}% needed ? + \ignorespaces} + +% For Giuseppe "Oblomov" Bilotta, inspired on a suggestion by Taco +% Hoekwater. +% +% \def\MyItemCommand#1{{\bf#1}\quad} +% \setupitemgroup[itemize][command=\MyItemCommand] +% +% \startitemize +% \item {test} is this okay? +% \item {test} is this okay? +% \item {test} is this okay? +% \stopitemize + +\def\complexitem[#1]#2\par % todo: no two pass data + {\startitemgroup[#1]% + \complexdoitemgroupitem[]\begstrut#2\endstrut\par + \stopitemgroup} + +\definecomplexorsimpleempty\item +\definecomplexorsimpleempty\doitemgroupitem + +\def\complexhead[#1]#2\par#3\par + {\startitemgroup[#1]% + \complexdoitemgrouphead[]\begstrut#2\endstrut\par\begstrut#3\endstrut\par + \stopitemgroup} + +% the next solution accepts \head test \type{x{x}x} test ... + +\def\complexdoitemgrouphead[#1]% beter in \complexdosom hangen met een if + {\ifconditional\firstlistitem\else\allowitembreak\fi + \ifconditional\packlistitem\else\itembeforeheadcommand\fi + \ifconditional\firstlistitem\ifconditional\introlistitem\else\ifcase\currentitemlevel % incr in \complexdosom + \allowitembreak + \fi\fi\fi + \complexdoitemgroupitem[#1]% + \bgroup + \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor\empty + \ignorespaces + \let\par\enditemhead} % brrrr but simple anyway + +\def\enditemhead + {\removeunwantedspaces + \egroup + \ifconditional\textlistitem + \space\ignorespaces + \else + \par + \fi + \noitembreak + \ifconditional\packlistitem\else\itemafterheadcommand\fi + \noitembreak + \noindentation} + +\definecomplexorsimpleempty\head +\definecomplexorsimpleempty\doitemgrouphead + +\def\sym#1% + {\noindent + \begingroup + \setbox\scratchbox\hbox{\trialtypesettingtrue#1}% + \setbox\scratchbox\hbox + \ifdim\wd\scratchbox<1em to 1.5\else spread 1\fi em{#1\hfil}% + \normalexpanded{\box\scratchbox\endgroup\hangindent\the\wd\scratchbox}% + \ignorespaces} + +\setupitemgroups + [\c!margin=\zeropoint, + \c!leftmargin=\zeropoint, + \c!rightmargin=\zeropoint, + \c!indentnext=\v!yes, + \c!width=1.5em, + \c!factor=0, + \c!distance=.5em, + %\c!align=\v!normal, % definitely not \v!normal, see mails and + %\c!align=, % debug reports of David A & Patrick G on context list + %\c!symalign=, + %\c!color=, + %\c!indenting=, % untouched if empty + %\c!style=, + \c!marstyle=\c!type, % \c! ??? + %\c!symstyle=, + %\c!headstyle=, + %\c!marcolor=, + %\c!symcolor=, + %\c!headcolor=, + %\c!beforehead=, + \c!afterhead=\blank, + \c!before=\blank, + \c!inbetween=\blank, + \c!after=\blank, + %\c!stopper=., + \c!placestopper=\v!yes, + \c!stopper=., + %\c!inner=, + \c!n=2, + \c!items=4, + \c!lefttext=(, + \c!righttext=), + \c!start=1, + %\c!option=, + \c!command=\defaultitemcommand, + \c!symbol=\currentitemlevel] + +\setupitemgroups + [\c!numberseparatorset=, + \c!numberconversionset=, + \c!numberstopper=., + \c!numbersegments=1] + +\defineitemgroup [\v!itemize] + +\protect \endinput diff --git a/tex/context/base/strc-itm.tex b/tex/context/base/strc-itm.tex deleted file mode 100644 index dd639d72b..000000000 --- a/tex/context/base/strc-itm.tex +++ /dev/null @@ -1,1195 +0,0 @@ -%D \module -%D [ file=strc-itm, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Itemgroups, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Itemgroups} - -\registerctxluafile{strc-itm}{1.001} - -\unprotect - -\newconditional\sublistitem \setfalse\sublistitem -\newconditional\symbollistitem \setfalse\symbollistitem -\newconditional\headlistitem \setfalse\headlistitem -\newconditional\introlistitem \setfalse\introlistitem -\newconditional\randomizeitems \setfalse\randomizeitems -\newconditional\autointrolistitem \setfalse\autointrolistitem -\newconditional\optimizelistitem \settrue \optimizelistitem -\newconditional\packlistitem \setfalse\packlistitem -\newconditional\paragraphlistitem \setfalse\paragraphlistitem -\newconditional\textlistitem \setfalse\textlistitem -\newconditional\firstlistitem \setfalse\firstlistitem -\newconditional\beforelistitem \setfalse\beforelistitem -\newconditional\afterlistitem \setfalse\afterlistitem -\newconditional\nowhitelistitem \setfalse\nowhitelistitem -\newconditional\joinedlistitem \setfalse\joinedwhitelistitem -\newconditional\reverselistitem \setfalse\reverselistitem -\newconditional\continuelistitems \setfalse\continuelistitems -\newconditional\fittinglistitems \setfalse\fittinglistitems - -\newcount\noflists -\newcount\currentnoflists -\newcount\noflistelements -\newcount\itemcolumndepth -\newcount\itemdepth -\newcount\maxitemdepth \maxitemdepth=6 - -\newdimen\itemgrouplistwidth -\newdimen\itemgroupaskedwidth -\newbox \itemgroupitembox - -\def\currentitemgroupcounter{itemgroup:\currentitemgroup} - -\let\currentitemlevel \!!zerocount -\let\currentitemgroup \empty -\let\currentnofitems \!!zerocount -\def\currentitemnumber {\dorawsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]} -\let\currentrepeatstart \empty - -\def\dolistreference - {\iftrialtypesetting \else % no need for different treatment of \continuelistitems - \ctxlua{structure.itemgroups.register("\currentitemgroup",\number\noflistelements,"\getitemparameter\currentitemlevel\c!maxwidth")}% - \fi} - -\def\checkcurrentnofitems % we could do this at the lua end and save a call - {\edef\currentnofitems {\ctxlua{structure.itemgroups.nofitems("\currentitemgroup",\number\currentnoflists)}}% - \edef\currentitemmaxwidth{\ctxlua{structure.itemgroups.maxwidth("\currentitemgroup",\number\currentnoflists)}\scaledpoint}} - -\def\dohandleitemreference % we will make a decent number helper - {\ifx\currentitemreference \empty \else - \setnextinternalreference - \ctxlua { - jobreferences.set("\s!full", "\referenceprefix","\currentitemreference", - { - metadata = { - kind = "list", - catcodes = \the\catcodetable, - xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text - }, - references = { - internal = \nextinternalreference, - section = structure.sections.currentid(), - }, - numberdata = structure.helpers.simplify { - numbers = structure.counters.compact("\currentitemgroupcounter",nil,true), - separatorset = "\structurecounterparameter\currentitemgroupcounter\c!numberseparatorset", - conversion = "\structurecounterparameter\currentitemgroupcounter\c!numberconversion", - conversionset = "\structurecounterparameter\currentitemgroupcounter\c!numberconversionset", - % for the moment no stopper, we need to make references configurable first - % stopper = \!!bs\structurecounterparameter\currentitemgroupcounter\c!numberstopper\!!es, - segments = "\structurecounterparameter\currentitemgroupcounter\c!numbersegments", - }, - }) - jobreferences.setinternalreference("\referenceprefix","\currentitemreference",\nextinternalreference) - }% - \fi} - -% \startitemize[n,packed] -% \item test \item test \item test -% \stopitemize -% -% \startitemize[n,packed,reverse] -% \item test \item test \item test -% \stopitemize -% -% \startitemize[n,packed,reverse] \item test \item test \stopitemize -% \startitemize[continue] -% \item test \startitemize[n,packed] \item test \item test \stopitemize -% \item test -% \item test -% \stopitemize -% \startitemize[continue] \item test \stopitemize -% -% \startitemize[n,packed] \item test \item test \stopitemize -% \startitemize[continue] \item test \stopitemize -% \startitemize[continue] \item test \stopitemize - -\def\itemparameter #1#2{\csname\doitemparameter{\??op\currentitemgroup#1}#2\endcsname} -\def\itemparameterhash#1#2{\doitemparameterhash {\??op\currentitemgroup#1}#2} - - -\def\doitemparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doitemparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\doitemparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doitemparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\doitemparentparameter #1#2{\ifx#1\relax\s!empty\else\doitemparameter #1#2\fi} -\def\doitemparentparameterhash#1#2{\ifx#1\relax \else\doitemparameterhash#1#2\fi} - -\def\dosetitemattributes#1#2#3% style color - {\edef\fontattributehash {\itemparameterhash#1#2}% - \edef\colorattributehash{\itemparameterhash#1#3}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #2\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#3\fi} - -\def\setitemparameter #1#2{\@EA \def\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} -\def\esetitemparameter#1#2{\@EA\edef\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} -\def\xsetitemparameter#1#2{\@EA\xdef\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} -\def\letitemparameter #1#2{\@EA \let\csname\??op\currentitemgroup#1#2\endcsname} -\let\getitemparameter \itemparameter - -\def\@@globalitemsymbol #1{\??op\currentitemgroup\c!symbol\s!global#1} -\def\@@localitemsymbol #1{\??op\currentitemgroup\c!symbol\s!local #1} -\def\@@currentitemsymbol#1{\??op\currentitemgroup\c!symbol #1} - -\def\@@itemcounter{\s!itemcount\currentitemgroup} - -\def\doitembreak#1{\ifconditional\optimizelistitem\ifconditional\textlistitem\else\dosomebreak#1\fi\fi} - -\def\allowitembreak {\doitembreak\allowbreak} -\def\noitembreak {\doitembreak\nobreak} -\def\itembreakspecial {\doitembreak\itembreak} -\def\noitembreakspecial{\doitembreak\itemnobreak} - -\def\itembreak {\flushnotes\penalty-5\relax} % -10 -\def\itemnobreak{\flushnotes\penalty+5\ifinsidecolumns\else00\fi\relax} % +5 - -\def\initializeitemgrouplevel#1% - {\ifcsname\??op\currentitemgroup#1\s!parent\endcsname - % ok - \else\ifnum#1>\plusone - \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup\the\numexpr#1-1\relax}% - \else - \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup}% - \fi\fi} - -\def\defineitemgroup - {\dotripleempty\dodefineitemgroup} - -\def\dodefineitemgroup[#1][#2][#3]% todo: clone - {\doifsomething{#1} - {\pushmacro\currentitemgroup - \def\currentitemgroup{#1}% - \setvalue{\e!start#1}{\startitemgroup[#1]}% - \setvalue{\e!stop#1}{\stopitemgroup}% - \setvalue{\e!setup#1\e!endsetup}{\setupitemgroup[#1]}% for old times sake - \doifelsenothing{#2} - {\getparameters[\??op#1][\s!parent=\??oo,#3]}% - {\doifassignmentelse{#2} - {\getparameters[\??op#1][\s!parent=\??oo,#2]}% - {\getparameters[\??op#1][\s!parent=\??op#2,#3]}}% - \dorecurse\maxitemdepth{\initializeitemgrouplevel\recurselevel}% - \definestructurecounter[itemgroup:#1]% - \popmacro\currentitemgroup}} - -\def\setupitemgroups % [#1] - {\dodoubleargument\getparameters[\??oo]} % [#1] - -\def\packitems - {\ifcase\currentitemlevel \else \settrue\packlistitem \fi} - -\def\dosetupitemgroupvariable[#1]% [#2]% niveau instellingen - {\doifelsenothing{#1} - {\getparameters[\??op\currentitemgroup\currentitemlevel]}% - {\getparameters[\??op\currentitemgroup#1]}} - -\def\dosetupitemgroupconstant#1% - {\global\setitemparameter\currentitemlevel\c!maxwidth{0}% - \processcommacommand[#1]\dodosetupitemgroupconstant} % expansion of #2 is handy for xml - -\def\dodosetupitemgroupconstant#1% - {\edef\itemgroupconstantvalue{#1}% - \ifx\itemgroupconstantvalue\empty\else - \splitstring\itemgroupconstantvalue\at*\to\itemgroupfirst\and\itemgroupsecond - \ifcsname\??op:::\itemgroupfirst\endcsname\csname\??op:::\itemgroupfirst\endcsname\fi - \fi} - -\newconditional\inlinelistitem \setfalse\inlinelistitem - -\setvalue{\??op:::\v!packed }{\packitems} -\setvalue{\??op:::\v!intro }{\settrue\introlistitem} % here? not set to false -\setvalue{\??op:::\v!autointro}{\settrue\autointrolistitem} -\setvalue{\??op:::\v!broad }{\ifx\itemgroupsecond\empty\def\itemgroupsecond{1}\fi - \letitemparameter\currentitemlevel\c!factor\itemgroupsecond} -\setvalue{\??op:::\v!text }{\settrue\textlistitem - \settrue\inlinelistitem - \settrue\joinedlistitem - \packitems} -\setvalue{\??op:::\v!columns }{\packitems} -\setvalue{\??op:::\v!before }{\settrue\beforelistitem} -\setvalue{\??op:::\v!after }{\settrue\afterlistitem} -\setvalue{\??op:::\v!nowhite }{\settrue\nowhitelistitem} -\setvalue{\??op:::\v!margin }{\setitemparameter\currentitemlevel\c!width{-2em}} % signal -\setvalue{\??op:::\v!inmargin }{\setitemparameter\currentitemlevel\c!width{-2em}} % signal -\setvalue{\??op:::\v!atmargin }{\doifnot\currentitemlevel{1}{\setitemparameter\currentitemlevel\c!width{0em}}} % signal -\setvalue{\??op:::\v!intext }{\settrue\inlinelistitem} -\setvalue{\??op:::\v!loose }{\setfalse\optimizelistitem} -\setvalue{\??op:::\v!fit }{\settrue\fittinglistitems} -\setvalue{\??op:::\v!nofit }{\setfalse\fittinglistitems} -\setvalue{\??op:v:\v!paragraph}{\settrue\paragraphlistitem - \packitems} -\setvalue{\??op:::\v!joinedup }{\settrue\joinedlistitem - \packitems} -\setvalue{\??op:::\v!serried }{\edef\itemgroupsecond{-\ifx\itemgroupsecond\empty1\else\itemgroupsecond\fi}% - \letitemparameter\currentitemlevel\c!factor\itemgroupsecond} -\setvalue{\??op:::\v!stopper }{\letitemparameter\currentitemlevel\c!placestopper\v!yes} % keep {} -\setvalue{\??op:::\v!unpacked }{\setfalse\packlistitem} -\setvalue{\??op:::\v!repeat }{\settrue\repeatlistitem} -\setvalue{\??op:::\v!reverse }{\settrue\reverselistitem} -\setvalue{\??op:::\v!standard }{\dosetupstandarditemgroup\currentitemlevel} - -\def\dosetupstandarditemgroup#1% - {\getparameters - [\??op\currentitemgroup#1] - [\c!width=1.5em,\c!factor=0,\c!distance=.5em,\c!inner=, - \c!beforehead=,\c!afterhead=\blank,\c!before=\blank,\c!inbetween=\blank,\c!after=\blank]} - -% \def\packeditemspacing{\empty} - -% \setupwhitespace[big] -% \starttext -% test \startitemize[joinedup] \item test \item test \stopitemize test \par -% test \startitemize[joinedup,nowhite] \item test \item test \stopitemize test \par -% test \startitemize[joinedup,nowhite,before] \item test \item test \stopitemize test \par -% test \startitemize[joinedup,nowhite,after] \item test \item test \stopitemize test \par -% \stoptext - -\def\itembeforecommand - {\ifconditional\nowhitelistitem - \ifconditional\beforelistitem - \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!before\fi - \else - \nowhitespace - \fi - \else\ifconditional\joinedlistitem - % \empty - \else - \getitemparameter\currentitemlevel\c!before - \fi\fi} - -\def\itemaftercommand - {\ifconditional\nowhitelistitem - \ifconditional\afterlistitem - \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!after\fi - \else - \nowhitespace - \fi - \else\ifconditional\joinedlistitem - % \empty - \else - \getitemparameter\currentitemlevel\c!after - \fi\fi} - -\def\iteminbetweencommand - {\ifconditional\nowhitelistitem - \nowhitespace - \else\ifconditional\joinedlistitem - % \empty - \else - \getitemparameter\currentitemlevel\c!inbetween - \fi\fi} - -\def\itembeforeheadcommand - {\ifconditional\nowhitelistitem - \nowhitespace - \else\ifconditional\joinedlistitem - % \empty - \else - \getitemparameter\currentitemlevel\c!beforehead - \fi\fi} - -\def\itemafterheadcommand - {\ifconditional\nowhitelistitem - \nowhitespace - \else\ifconditional\joinedlistitem - % \empty - \else - \getitemparameter\currentitemlevel\c!afterhead - \fi\fi} - -\def\dododododosetupitemgroup[#1][#2]% - {\doifassignmentelse{#2}% - {\dosetupitemgroupvariable[#1][#2]}% - {\setitemparameter{#1}\c!option{#2}}}% - -\def\dodododosetupitemgroup[#1][#2]% - {\doifsomething{#2} - {\doifelse{#1}\v!each - {\dorecurse\maxitemdepth{\normalexpanded{\noexpand\dododododosetupitemgroup[\recurselevel]}[#2]}} - {\normalexpanded{\noexpand\dododododosetupitemgroup[#1]}[#2]}}} - -% \def\dododosetupitemgroup[#1][#2]% -% {\doifelsenothing{#2} -% {\doifelsenothing{#1} -% {\dodododosetupitemgroup[\currentitemlevel][#2]} -% {\dodododosetupitemgroup[#1][#2]}} -% {\ifcase\currentitemlevel\relax -% \dodododosetupitemgroup[\v!each][#1]% -% \else -% \dodododosetupitemgroup[\currentitemlevel][#1]% -% \fi}} - -\def\dododosetupitemgroup[#1][#2]% - {\doifelsenothing{#2} - {\doifsomething{#1} - {\ifcase\currentitemlevel\relax - \dodododosetupitemgroup[\v!each][#1]% - \else - \dodododosetupitemgroup[\currentitemlevel][#1]% - \fi}}% - {\doifelsenothing{#1} - {\ifcase\currentitemlevel\relax - \dodododosetupitemgroup[\v!each][#2]% - \else - \dodododosetupitemgroup[\currentitemlevel][#2]% - \fi} - {\dodododosetupitemgroup[#1][#2]}}} - -\def\dodosetupitemgroup[#1][#2][#3][#4]% - {\pushmacro\currentitemgroup - \def\currentitemgroup{#1}% - \dododosetupitemgroup[#2][#3]% - \doifsomething{#4}{\dododosetupitemgroup[#2][#4]}% - \popmacro\currentitemgroup} - -\def\dosetupitemgroup[#1][#2][#3][#4]% - {\def\docommand##1{\dodosetupitemgroup[##1][#2][#3][#4]}% - \processcommalist[#1]\docommand} - -\def\setupitemgroup - {\doquadrupleempty\dosetupitemgroup} - -\def\doadvanceitem - {\ifconditional\sublistitem\else\ifconditional\symbollistitem\else - \doincrementsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]% - \fi\fi} - -\def\setitemlevel#1% - {\ifnum\currentitemlevel>\zerocount - \settrue\firstlistitem - \ifconditional\continuelistitems\else - \dorestartsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]{\the\numexpr\getitemparameter\currentitemlevel\c!start-1\relax}% - \fi - \fi} - -\unexpanded\def\actualitemnumber - {\ifconditional\repeatlistitem - \ifcase\currentitemlevel\or\else - \doactualitemnumber - \fi - \else - \doactualitemnumber - \fi} - -\def\doactualitemnumber - {\begingroup - \setupstructurecounter - [\currentitemgroupcounter] - [\c!prefix=\v!no, - \c!numberorder=\ifconditional\reverselistitem\v!reverse\else\v!normal\fi, - \c!numberstopper=\expdoif{\getitemparameter\currentitemlevel\c!placestopper}\v!yes{\getitemparameter\currentitemlevel\c!stopper}, - %\c!numberseparatorset=, - %\c!numberconversionset=, - \c!numberconversion=\currentitemsymbol, - \c!numbersegments=\ifx\currentrepeatstart\empty\else\currentrepeatstart:\fi\number\currentitemlevel]% - \ifconditional\reverselistitem - \convertedstructurecounter[\currentitemgroupcounter]% [\number\currentitemlevel]% - \else - \convertedstructurecounter[\currentitemgroupcounter]% [\number\currentitemlevel]% - \fi - \dohandleitemreference - \endgroup} - -\def\unknownitemsymbol{?} - -\def\setitemmark#1% % en pas op: resets \docommand ; todo: conversionset - {\doifsymboldefinedelse{#1} - {\edef\currentitemsymbol{#1}% - \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}% - \setgvalue{\@@localitemsymbol \currentitemlevel}{\unknownitemsymbol}% - \def\listitem{\symbol[\currentitemsymbol]}% - \let\@@opsymbol\empty}% - {\doifconversiondefinedelse{#1} - {\edef\currentitemsymbol{#1}% - \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}% - \setgvalue{\@@localitemsymbol\currentitemlevel }{\actualitemnumber }% - \def\listitem - {\ifconditional\textlistitem - % maybe block stopper here, but one can as well clone an - % itemgroup then - \getitemparameter\currentitemlevel\c!lefttext - \getvalue{\@@localitemsymbol\currentitemlevel}% - \getitemparameter\currentitemlevel\c!righttext - \else - \getitemparameter\currentitemlevel\c!left - \getvalue{\@@localitemsymbol\currentitemlevel}% - \getitemparameter\currentitemlevel\c!right - \fi}% - \let\@@opsymbol\empty}% - {}}} - -\def\calculatelistwidth#1% distance deals with 'broad' - {\itemgrouplistwidth\getitemparameter#1\c!distance\relax - \ifnum\getitemparameter#1\c!factor>\zerocount - \ifdim\itemgrouplistwidth=\zeropoint \itemgrouplistwidth=.5em\fi - \fi - \multiply\itemgrouplistwidth \getitemparameter#1\c!factor - \advance \itemgrouplistwidth \getitemparameter#1\c!width\relax} - -% The next conditionals deal with \item \startitemgroup. It -% looks like a hack to skip back, but that way we preserve -% the indentation and bullet placement. It's a rather -% untested feature. - -\newconditional\concatnextitem \setfalse\concatnextitem -\newconditional\autoconcatnextitem \settrue \autoconcatnextitem -\newsignal \itemsignal - -\def\startitemgroup - {\dotripleempty\dostartitemgroup} - -\def\dostartitemgroup[#1][#2][#3]% - {\bgroup - \ifnum\currentitemlevel=\zerocount - \def\currentitemgroup{#1}% no nested mixing of itemgroups - \fi - \ifthirdargument - \dodostartitemgroup[#2][#3]% - \else - \doifassignmentelse{#2} - {\dodostartitemgroup[][#2]} - {\dodostartitemgroup[#2][]}% - \fi} - -\def\dodostartitemgroup[#1]% [#2]% - {\relax % prevents lookahead - \ifnum\currentitemlevel=\maxitemdepth\relax - \showmessage\m!layouts9{\number\maxitemdepth}% - \let\itemincrement\zerocount - \else - \let\itemincrement\plusone - \fi - \global\advance\itemdepth\itemincrement - \xdef\currentitemlevel{\number\itemdepth}% - \edef\itemgroupoptions{\getitemparameter\currentitemlevel\c!option}% - \ifx\itemgroupoptions\empty - \edef\itemgroupoptions{#1}% - \else - \doifsomething{#1}{\edef\itemgroupoptions{\itemgroupoptions,#1}}% - \fi - \normalexpanded{\noexpand\redostartitemgroup[\itemgroupoptions]}}% [#2] - -\let\startcollectitems\relax -\let\stopcollectitems \relax - -%D A nice example of a plugin: -%D -%D \startbuffer -%D \startitemize[a,random,packed] -%D \startitem first \stopitem \startitem second \stopitem -%D \startitem third \stopitem \startitem fourth \stopitem -%D \stopitemize -%D -%D \startitemize[a,random,packed] -%D \startitem first \stopitem \startitem second \stopitem -%D \startitem third \stopitem \startitem fourth \stopitem -%D \stopitemize -%D -%D \startitemize[a,packed] -%D \startitem first \stopitem \startitem second \stopitem -%D \startitem third \stopitem \startitem fourth \stopitem -%D \stopitemize -%D \stopbuffer -%D -%D \typebuffer \getbuffer - -% better collectitems als conditional and a real plugin mechanism (some day) - -\@EA\long\@EA\def\@EA\collectitemgroupitem\@EA#\@EA1\csname\e!stop\v!item\endcsname - {\increment\itemcollectcounter - \long\setvalue{\v!item*\itemcollectcounter}{\item#1\par}} - -\def\flushcollecteditems - {\ifconditional\randomizeitems - \getrandomnumber\itemcollectcounternow\plusone\itemcollectcounter - \else - \increment\itemcollectcounternow - \fi - \doifdefined{\v!item*\itemcollectcounternow} - {\getvalue{\v!item*\itemcollectcounternow}% - \letbeundefined{\v!item*\itemcollectcounternow}% - \increment\itemcollectcounterdone}% - \ifnum\itemcollectcounterdone<\itemcollectcounter\relax - \expandafter\flushcollecteditems - \fi} - -\def\stopcollectitems - {\ifconditional\randomizeitems - \newcounter\itemcollectcounterdone - \ifnum\itemcollectcounter>\zerocount - \@EAEAEA\flushcollecteditems - \fi - \fi} - -\def\startcollectitems - {\ifconditional\randomizeitems - \newcounter\itemcollectcounter - \letvalue{\e!start\v!item}\collectitemgroupitem - \fi} - -%D End of plugin. - -\ifx\startcolumns\undefined \def\startcolumns[#1]{} \fi -\ifx\stopcolumns \undefined \let\stopcolumns\relax \fi - -\def\dosetsymalign#1% hm, we should use one of the core-spa macros or make a helper - {\processaction - [#1] - [ \v!flushleft=>\let\symalignleft\relax, - \v!right=>\let\symalignleft\relax, - \v!flushright=>\let\symalignleft\hfill, - \v!left=>\let\symalignleft\hfill, - \v!middle=>\let\symalignleft\hfil, - \v!center=>\let\symalignleft\hfil]} - -\def\redostartitemgroup[#1][#2]% - {\setfalse\inlinelistitem % new, no indent (leftskip) - \setfalse\concatnextitem % new, concat - \setfalse\txtlistitem - \ifhmode - \ifconditional\autoconcatnextitem % new, concat - \ifdim\lastskip=\itemsignal % new, concat - \settrue\concatnextitem % new, concat - \fi % new, concat - \fi % new, concat - \ifconditional\textlistitem\else\doifnotinset\v!text{#1}\par\fi % suboptimal - \fi - \begingroup - % new where, ok or not / we should integrate random, intro, continue here - % beware, the following no longer inherit from the previous level, is this ok? - \setfalse\reverselistitem - \setfalse\introlistitem - \setfalse\autointrolistitem - \setfalse\beforelistitem - \setfalse\afterlistitem - \setfalse\nowhitelistitem - \setfalse\randomizeitems - % - \doifinsetelse\v!intro {#1}{\settrue\introlistitem }{\setfalse\introlistitem }% - \doifinsetelse\v!random {#1}{\settrue\randomizeitems }{\setfalse\randomizeitems }% - \doifinsetelse\v!continue{#1}{\settrue\continuelistitems}{\setfalse\continuelistitems}% - % == \doifinsetelse\v!intro{#1}\settrue\setfalse\introlistitem - \global\advance\noflists\plusone - \currentnoflists\noflists - \noflistelements\zerocount - \setfalse\headlistitem - \setfalse\sublistitem - \setfalse\symbollistitem - \let\marsymbol\relax - \globallet\doitemdestination\empty - \let\symsymbol\empty - \let\symalignleft\relax - \the\itemgroupcommands - \checkcurrentnofitems - % \getitemparameter\currentitemlevel\empty - \let\listitem\empty % ** start value - \doifelsenothing{#1} % iffirstargument - {\edef\@@opsymbol{\noexpand\getitemparameter\currentitemlevel\noexpand\c!symbol}% - \letgvalueempty{\@@globalitemsymbol\currentitemlevel}% - \global\letitemparameter\currentitemlevel\v!continue\empty - \dosetupitemgroupvariable[\currentitemlevel][#2]} - {\dosetupitemgroupconstant{#1}% - \dosetupitemgroupvariable[\currentitemlevel][#2]% - \ifconditional\continuelistitems - \edef\@@opsymbol{\executeifdefined{\@@globalitemsymbol\currentitemlevel}{\currentitemlevel}}% - \getitemparameter\currentitemlevel\v!continue - \else - \edef\@@opsymbol{\noexpand\getitemparameter\currentitemlevel\noexpand\c!symbol}% - \global\setitemparameter\currentitemlevel\v!continue - {\dosetupitemgroupconstant{#1}% - \dosetupitemgroupvariable[\currentitemlevel][#2]}% - \fi - \def\docommand##1% \setitemmark resets \docommand - {\doifnot{##1}{0}{\setitemmark{##1}}}% - % \processcommalist[#1,\@@opsymbol]\docommand - \processcommalist[#1]\docommand}% ** preset sequence or provided sequence - % moved to here, after settings - \ifnum\currentitemlevel=\plusone % NIEUW - \doadaptleftskip {\getitemparameter\currentitemlevel\c!margin}% - \doadaptleftskip {\getitemparameter\currentitemlevel\c!leftmargin}% - \doadaptrightskip{\getitemparameter\currentitemlevel\c!rightmargin}% - \fi - \dosetraggedcommand{\getitemparameter\currentitemlevel\c!align}\raggedcommand - \dosetsymalign{\getitemparameter\currentitemlevel\c!symalign}% - \doifsomething{\getitemparameter\currentitemlevel\c!indenting} - {\normalexpanded{\noexpand\setupindenting[\getitemparameter\currentitemlevel\c!indenting]}}% - % - \setitemlevel{#1}% moved to here - \ifx\listitem\empty - \setitemmark\@@opsymbol % ** default value - \ifx\listitem\empty - \edef\currentitemsymbol{\currentitemlevel}% ** fall back - \fi - \fi - \ifconditional\autointrolistitem\ifnum\prevgraf<3 - \settrue\introlistitem - \fi\fi - \ifconditional\paragraphlistitem - \ifnum\currentitemlevel>\plusone - \letitemparameter\currentitemlevel\c!inbetween\empty - \fi - \fi - \ifconditional\packlistitem - \letitemparameter\currentitemlevel\c!inbetween\empty - \fi - \doifinset\v!columns{#1}% - {\ifinsidecolumns\else\ifcase\itemcolumndepth - \global\itemcolumndepth\currentitemlevel\relax - \itembeforecommand - \processfirstactioninset - [#1] - [ \v!one=>\setitemparameter\currentitemlevel\c!n{1}, - \v!two=>\setitemparameter\currentitemlevel\c!n{2}, - \v!three=>\setitemparameter\currentitemlevel\c!n{3}, - \v!four=>\setitemparameter\currentitemlevel\c!n{4}, - \v!five=>\setitemparameter\currentitemlevel\c!n{5}, - \s!unknown=>\@EA\!!counta\getitemparameter\currentitemlevel\c!n]% - \startcolumns - [\c!n=\getitemparameter\currentitemlevel\c!n, - \c!height=, - \c!rule=\v!off, - \c!balance=\v!yes, - \c!align=\v!no]% - \fi\fi}% - \ifconditional\fittinglistitems - \ifdim\currentitemmaxwidth>\zeropoint - \esetitemparameter\currentitemlevel\c!width{\currentitemmaxwidth}% - \fi - \fi - \calculatelistwidth\currentitemlevel - \ifdim\itemgrouplistwidth>\zeropoint\relax - \ifconditional\inlinelistitem\else - \advance\leftskip\itemgrouplistwidth\relax - \fi - \fi - \startcollectitems} - -% test / example -% -% \startnarrower[left] \startcolumns[n=3] \startitemize -% \item \input ward \item \input ward \item \input ward -% \stopitemize \stopcolumns\stopnarrower \blank -% -% \startnarrower[left] \startitemize[columns,three] -% \item \input ward \item \input ward \item \input ward -% \stopitemize \stopnarrower \blank -% -% \setupitemize[leftmargin=1.5em] \startitemize[columns,three] -% \item \input ward \item \input ward \item \input ward -% \stopitemize \blank - -\def\stopitemgroup - {\stopcollectitems - \ifconditional\textlistitem - \removeunwantedspaces\space\ignorespaces - \else - \par - \fi - \dolistreference - \ifconditional\firstlistitem \else \endgroup \fi % toegevoegd, eerste \som opent groep - \ifnum\itemcolumndepth=\currentitemlevel\relax - \stopcolumns - \global\itemcolumndepth\zerocount - \itemaftercommand - \dontrechecknextindentation - \else - \ifnum\currentitemlevel=\plusone - \allowitembreak - \itemaftercommand - \checknextindentation[\getitemparameter\currentitemlevel\c!indentnext]% - \else - % nieuw, not yet nobreak handling - \ifcase\autoitemgroupspacing - \itemaftercommand - \or - \itemaftercommand - \fi - \dontrechecknextindentation - \fi - \fi - % new test, needed in sidefloats (surfaced in volker's proceedings) - \ifconditional\textlistitem % else forgotten - \endgroup - \global\advance\itemdepth-\itemincrement - \xdef\currentitemlevel{\number\itemdepth}% - \egroup - \else - \endgroup - \global\advance\itemdepth-\itemincrement - \xdef\currentitemlevel{\number\itemdepth}% - \egroup - \par - \fi - \dorechecknextindentation} - -\newtoks\itemgroupcommands - -\def\itemgroupitem - {\doitemgroupitem} - -\def\itemgroupnoitem - {\doitemgroupnoitem} - -\def\itemgroupbutton[#1]% - {\gdef\doitemdestination{#1}% - \itemgroupitem} - -\def\itemgroupdummy - {\itemgroupsymbol{\strut}\strut} - -\def\itemgroupsubitem - {\settrue\sublistitem - \itemgroupitem} - -\def\itemgroupsymbol#1% - {\def\symsymbol{#1}% - \settrue\symbollistitem - \itemgroupitem} - -\def\itemgroupedge#1% - {\itemgroupsymbol - {\calculatelistwidth\currentitemlevel - \hbox to \itemgrouplistwidth - {#1\hskip\getitemparameter\currentitemlevel\c!distance}}} - -\def\itemgrouphead - {\settrue\headlistitem\doitemgrouphead} - -\def\itemgroupitems - {\dosingleempty\doitemgroupitems} - -\def\doitemgroupitems[#1]% - {\itemgroupedge - {\dorecurse{0\getitemparameter\currentitemlevel\c!items}{\listitem\hss}% - \unskip}} - -\def\itemgroupmargin#1% - {\def\marsymbol - {\llap - {\dosetitemattributes\currentitemlevel\c!marstyle\c!marcolor{#1}% - \hskip\leftskip\hskip\leftmargindistance}}% - \itemgroupitem} - -\appendtoks \let\item \itemgroupitem \to \itemgroupcommands -\appendtoks \let\noitem \itemgroupnoitem \to \itemgroupcommands -\appendtoks \letvalue\v!item \itemgroupitem \to \itemgroupcommands -\appendtoks \let\itm \itemgroupitem \to \itemgroupcommands -\appendtoks \let\but \itemgroupbutton \to \itemgroupcommands -\appendtoks \let\nop \itemgroupdummy \to \itemgroupcommands -\appendtoks \letvalue\v!sub \itemgroupsubitem \to \itemgroupcommands -\appendtoks \letvalue\v!sym \itemgroupsymbol \to \itemgroupcommands -\appendtoks \letvalue\v!ran \itemgroupedge \to \itemgroupcommands -\appendtoks \letvalue\v!head \itemgrouphead \to \itemgroupcommands -\appendtoks \letvalue\v!its \itemgroupitems \to \itemgroupcommands -\appendtoks \letvalue\v!mar \itemgroupmargin \to \itemgroupcommands - -% todo : \startitem .. \stopitem - -\appendtoks - \letvalue{\e!start\v!item}\itemgroupitem - \letvalue{\e!stop \v!item}\endgraf -\to \itemgroupcommands - -\appendtoks - \setvalue{\e!start\v!head}#1{\itemgrouphead#1\par}% - \letvalue{\e!stop \v!head}\endgraf -\to \itemgroupcommands - -% \startitemize -% \starthead {xx} test \stophead -% \startitem test \stopitem -% \startitem test \stopitem -% \stopitemize - -% Sometimes the user demands get pretty weird: -% -% \startitemize -% \item test -% \item test -% \headsym{xx} test \par test -% \stopitemize - -% aligned items -% -% \startitemize[n,fit,broad][itemalign=flushright] -% \dorecurse{100}{\item The first item.} -% \stopitemize -% -% \setupitemgroup[itemize][each][fit] -% \setupitemgroup[itemize][each][distance=.5em,factor=1,itemalign=flushright] -% -% \startitemize[n] -% \dorecurse{100}{\item The first item.} -% \stopitemize - -\appendtoks \let\headsym \itemgroupheadsym \to \itemgroupcommands - -\def\itemgroupheadsym#1% - {\def\symsymbol{#1}% - \settrue\symbollistitem - \settrue\headlistitem - \doitemgrouphead} - -% \defineitemgroup[gbitemize] -% \setupitemgroup[gbitemize][each][headstyle=bold] - -% \startgbitemize -% \txt{italian} some italians like this kind of cross||breed between -% an itemize and a description -% \txt{sicilians} i wonder how many sicilian mathematicians do a thesis -% on the math involved in predicting the next big bang of the vulcano -% \stopgbitemize - -\appendtoks \letvalue\v!txt\itemgrouptext \to \itemgroupcommands - -\newconditional\txtlistitem \setfalse\txtlistitem - -\def\itemgrouptext#1% - {\def\symsymbol{#1}% - \settrue\symbollistitem - \settrue\txtlistitem - \itemgroupitem} - -\def\dodotxtitem - {\scratchdimen\wd\itemgroupitembox - \advance \scratchdimen \getitemparameter\currentitemlevel\c!distance\relax - \ifdim\scratchdimen>\itemgrouplistwidth - \advance\scratchdimen -\itemgrouplistwidth - \else - \scratchdimen\zeropoint - \fi - \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hss}}% was: \hfill - \hskip\scratchdimen} - -\def\optimizelistitemsbreak - {\ifcase\itemcolumndepth \ifconditional\optimizelistitem - \ifcase \currentnofitems \else - \ifnum\currentnofitems=\plusthree - \ifnum\noflistelements>\plusone - \noitembreakspecial - \fi - \else\ifnum\currentnofitems>\plusthree - \ifnum\noflistelements=\plustwo - \ifconditional\introlistitem - \noitembreak - \else - \noitembreakspecial - \fi - \else\ifnum\currentnofitems=\noflistelements\relax - \noitembreakspecial - \else\ifnum\noflistelements>\plustwo - \itembreakspecial - \else - \ifconditional\introlistitem\else\itembreakspecial\fi - \fi\fi\fi - \fi\fi - \fi - \fi\fi} - -\def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken - {\ifconditional\textlistitem - % begin of item - \else - \par - \fi - \advance\noflistelements\plusone - \optimizelistitemsbreak - \noindent - \setbox\itemgroupitembox\hbox - {\ifconditional\headlistitem - \ifconditional\symbollistitem - \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}% - \else - \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor{\listitem}% - \fi - \else - \ifconditional\symbollistitem - \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}% - \else - \dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}% - \fi - \fi}% - \ifconditional\fittinglistitems - \ifdim\wd\itemgroupitembox>\getitemparameter\currentitemlevel\c!maxwidth sp\relax - \xsetitemparameter\currentitemlevel\c!maxwidth{\number\wd\itemgroupitembox}% - \fi - \ifdim\currentitemmaxwidth>\zeropoint - \setbox\itemgroupitembox\simplealignedbox{\getitemparameter\currentitemlevel\c!itemalign}{\currentitemmaxwidth}{\box\itemgroupitembox}% - \fi - \fi - \doifsomething\doitemdestination - {\setbox\itemgroupitembox\hbox{\goto{\box\itemgroupitembox}[\doitemdestination]}}% - \globallet\doitemdestination\empty - \itemgroupaskedwidth\getitemparameter\currentitemlevel\c!width\relax - % new, prevents loops when symbol is (not yet found) graphic - \ht\itemgroupitembox\strutheight - \dp\itemgroupitembox\strutdepth - % so that content differs per run (esp mp graphics afterwards) - \checkforrepeatedlistitem - \ifdim\itemgroupaskedwidth<\zeropoint\relax - \llap{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hskip\leftmargindistance}% - \else - \ifdim\itemgroupaskedwidth=\zeropoint\relax - \calculatelistwidth1% - \else - \calculatelistwidth\currentitemlevel - \fi - \ifconditional\textlistitem - \hbox{\ifconditional\sublistitem+\fi\box\itemgroupitembox\hskip\interwordspace}\nobreak - \else\ifconditional\inlinelistitem - \hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hss}% was: \hfill - \else\ifconditional\txtlistitem - \dodotxtitem - \else - % todo: align+marge binnen de hbox - \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi - \symalignleft - \box\itemgroupitembox\hfil - \hskip\getitemparameter\currentitemlevel\c!distance% T h - }}% - \fi\fi\fi - \fi - \forceunexpanded % needed for m conversion (\os) / i need to look into this - \setevalue{\@@currentitemsymbol\currentitemlevel}% - {\getvalue{\@@localitemsymbol\currentitemlevel}}% still problems with \uchar ? - %{\noexpand\getvalue{\@@localitemsymbol\currentitemlevel}}% no, spoils subrefs - \resetunexpanded - \setfalse\headlistitem - \setfalse\sublistitem - \setfalse\symbollistitem - \EveryPar{\ignorespaces}% needed ? - \ignorespaces} - -% For Wolfgang Schuster - -% \startitemize[n,repeat] -% \noitem \startitemize[a] \item Item 1.a. \item Item 1.b. \stopitemize -% \noitem \startitemize[a] \item Item 2.a. \item Item 2.b. \stopitemize -% \stopitemize - -\def\donolistitem % reduced \dolistitem - {\advance\noflistelements\plusone - \setbox\itemgroupitembox\hbox - {\dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}}% - \checkforrepeatedlistitem - \ignorespaces} - -\def\doitemgroupnoitem - {\doadvanceitem\donolistitem} - -% For Frank Grieshaber and Mojca Miklavec: - -\newconditional\repeatlistitem - -\def\checkforrepeatedlistitem - {\ifconditional\repeatlistitem - \ifx\currentrepeatstart\empty - \edef\currentrepeatstart{\the\numexpr\currentitemlevel-1}% - \fi - \setbox\itemgroupitembox\hbox to \wd\itemgroupitembox{\hskip-\itemgroupaskedwidth\box\itemgroupitembox}% what a hack ! - \fi} - -% \startbuffer -% \item -% \startitemize[n] -% \item item 1.1 -% \item item 1.2 -% \startitemize[n] \item item 1.2.1 \item item 1.2.2 \stopitemize -% \item item 1.3 -% \stopitemize -% \item -% \startitemize[n] \item item 2.1 \item item 2.2 \stopitemize -% \item item 3 -% \startitemize[n] \item item 3.1 \item item 3.2 \stopitemize -% \item -% \startitemize[n] \item item 4.1 \item item 4.2 \stopitemize -% \stopbuffer -% -% \startitemize[n,repeat,6*broad,packed] \getbuffer \stopitemize \blank[3*big] -% \startitemize[n,repeat,packed] \getbuffer \stopitemize \blank[3*big] -% \setupitemize[each][atmargin][width=3em] -% \startitemize[n,repeat,packed] \getbuffer \stopitemize - -\chardef\autoitemgroupspacing=2 % 0 = voor/na, 1=tussen als geen voor 2=(prev)tussen=old/normal - -\def\complexdoitemgroupitem[#1]% - {\def\currentitemreference{#1}% - \ifconditional\textlistitem - % begin of item - \else - \par - \fi - \ifconditional\concatnextitem % new, concat - \noitembreak % new, concat - \fi % new, concat - \doadvanceitem - \ifconditional\firstlistitem - \setfalse\firstlistitem - \begingroup - \ifcase\currentitemlevel - \or % 1 - \ifcase\itemcolumndepth - \ifconditional\introlistitem\noitembreak\fi - \itembeforecommand - \ifconditional\introlistitem\noitembreak\fi - \fi - \else % 2 en hoger - \ifconditional\paragraphlistitem \else - \edef\previtemlevel{\the\numexpr\currentitemlevel-1}% - \ifcase\autoitemgroupspacing\relax % nieuw - \itembeforecommand - \or - \doifelsenothing\itembeforecommand\itembeforecommand{\getitemparameter\previtemlevel\c!inbetween}% - \else - \getitemparameter\previtemlevel\c!inbetween - \fi - \fi - \fi - \else - \ifconditional\textlistitem % was bugged: \inlinelistitem - \removeunwantedspaces\hskip\emwidth\!!plus\interwordstretch\!!minus\interwordshrink\relax % new per 2006/10/20 - \else - \iteminbetweencommand - \fi - \fi - \ifconditional\concatnextitem - \vskip-\dimexpr\lastskip+\lineheight\relax - \nobreak - \fi - \dolistitem - \relax - \ifconditional\packlistitem - \setupwhitespace[\v!none]% - \fi - \getitemparameter\currentitemlevel\c!inner - \marsymbol - \let\marsymbol\relax - \strut % added 11-08-99 -% \dohandleitemreference - \setfalse\concatnextitem % new, concat - \nobreak % else problems with intext items - \hskip\itemsignal % new, concat - \getitemparameter\currentitemlevel\c!command} % \defaultitemcommand - -\def\defaultitemcommand - {\EveryPar{\ignorespaces}% needed ? - \ignorespaces} - -% For Giuseppe "Oblomov" Bilotta, inspired on a suggestion by Taco -% Hoekwater. -% -% \def\MyItemCommand#1{{\bf#1}\quad} -% \setupitemgroup[itemize][command=\MyItemCommand] -% -% \startitemize -% \item {test} is this okay? -% \item {test} is this okay? -% \item {test} is this okay? -% \stopitemize - -\def\complexitem[#1]#2\par % todo: no two pass data - {\startitemgroup[#1]% - \complexdoitemgroupitem[]\begstrut#2\endstrut\par - \stopitemgroup} - -\definecomplexorsimpleempty\item -\definecomplexorsimpleempty\doitemgroupitem - -\def\complexhead[#1]#2\par#3\par - {\startitemgroup[#1]% - \complexdoitemgrouphead[]\begstrut#2\endstrut\par\begstrut#3\endstrut\par - \stopitemgroup} - -% the next solution accepts \head test \type{x{x}x} test ... - -\def\complexdoitemgrouphead[#1]% beter in \complexdosom hangen met een if - {\ifconditional\firstlistitem\else\allowitembreak\fi - \ifconditional\packlistitem\else\itembeforeheadcommand\fi - \ifconditional\firstlistitem\ifconditional\introlistitem\else\ifcase\currentitemlevel % incr in \complexdosom - \allowitembreak - \fi\fi\fi - \complexdoitemgroupitem[#1]% - \bgroup - \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor\empty - \ignorespaces - \let\par\enditemhead} % brrrr but simple anyway - -\def\enditemhead - {\removeunwantedspaces - \egroup - \ifconditional\textlistitem - \space\ignorespaces - \else - \par - \fi - \noitembreak - \ifconditional\packlistitem\else\itemafterheadcommand\fi - \noitembreak - \noindentation} - -\definecomplexorsimpleempty\head -\definecomplexorsimpleempty\doitemgrouphead - -\def\sym#1% - {\noindent - \begingroup - \setbox\scratchbox\hbox{\trialtypesettingtrue#1}% - \setbox\scratchbox\hbox - \ifdim\wd\scratchbox<1em to 1.5\else spread 1\fi em{#1\hfil}% - \normalexpanded{\box\scratchbox\endgroup\hangindent\the\wd\scratchbox}% - \ignorespaces} - -\setupitemgroups - [\c!margin=\zeropoint, - \c!leftmargin=\zeropoint, - \c!rightmargin=\zeropoint, - \c!indentnext=\v!yes, - \c!width=1.5em, - \c!factor=0, - \c!distance=.5em, - %\c!align=\v!normal, % definitely not \v!normal, see mails and - %\c!align=, % debug reports of David A & Patrick G on context list - %\c!symalign=, - %\c!color=, - %\c!indenting=, % untouched if empty - %\c!style=, - \c!marstyle=\c!type, % \c! ??? - %\c!symstyle=, - %\c!headstyle=, - %\c!marcolor=, - %\c!symcolor=, - %\c!headcolor=, - %\c!beforehead=, - \c!afterhead=\blank, - \c!before=\blank, - \c!inbetween=\blank, - \c!after=\blank, - %\c!stopper=., - \c!placestopper=\v!yes, - \c!stopper=., - %\c!inner=, - \c!n=2, - \c!items=4, - \c!lefttext=(, - \c!righttext=), - \c!start=1, - %\c!option=, - \c!command=\defaultitemcommand, - \c!symbol=\currentitemlevel] - -\setupitemgroups - [\c!numberseparatorset=, - \c!numberconversionset=, - \c!numberstopper=., - \c!numbersegments=1] - -\defineitemgroup [\v!itemize] - -\protect \endinput diff --git a/tex/context/base/strc-lst.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..22c189c77 --- /dev/null +++ b/tex/context/base/strc-lst.mkiv @@ -0,0 +1,944 @@ +%D \module +%D [ file=strc-lst, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Lists, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Lists} + +\registerctxluafile{strc-lst}{1.001} + +\unprotect + +\def\currentstructurelistnumber{0} + +% nmstate -> no pagenumber if not start +% autocrossdocument -> todo +% expansion -> todo +% auto refs to lists (chain) -> todo (\dododowritetolist) +% todo: \normalexpanded{\noexpand\everylistentry\emptytoks\the\everylistentry}% \emptytoks, else loop + +% \def\linklisttoelement#1#2#3#4{#4}% list location format page data + +\def\linklisttoelement#1#2#3#4% % list location format page data + {\gotonextinternal\currentlist{#1}{#3}{#4}} + +% interface to lua + +% we have to deal with compatible processing, i.e. list elements that have two +% elements plus a pagenumber + +\let\listentry\gobblesixarguments + +\def\currentlist {\s!unknown} +\def\currentlistmethod{entry} +\def\currentlistindex {0} + +\def\setlistparameter#1#2#3{\@EA\def\csname\??li#1#2\endcsname{#3}} % often +%def\listparameter #1{\ifcsname\??li\currentlist#1\endcsname\csname\??li\currentlist#1\endcsname\fi} + +% interface + +\def\listparameter #1{\csname\dolistparameter{\??li\currentlist}#1\endcsname} +\def\namedlistparameter#1#2{\csname\dolistparameter{\??li #1}#2\endcsname} +\def\listparameterhash #1{\dolistparameterhash {\??li\currentlist}#1} + +\def\dolistparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dolistparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dolistparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dolistparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dolistparentparameter #1#2{\ifx#1\relax\s!empty\else\dolistparameter #1#2\fi} +\def\dolistparentparameterhash#1#2{\ifx#1\relax \else\dolistparameterhash#1#2\fi} + +\def\dosetlistattributes#1#2% style color + {\edef\fontattributehash {\listparameterhash#1}% + \edef\colorattributehash{\listparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\def\donestedlistattributes#1#2% + {\dosetlistattributes#1#2% + \ifx\colorattributehash\empty \else + \resetinteractionparameter\c!color + \resetinteractionparameter\c!contrastcolor + \fi} + +% handling + + +% The next code injects data into the list at the current level. + +\def\structurelistinject{\dotripleempty\dostructurelistinject} + +\def\dostructurelistinject[#1][#2][#3]% + {\begingroup + \edef\currentlistname{#1}% + \setnextinternalreference + \edef\currentlistnumber{\ctxlua{structure.lists.push{ + references = { + internal = \nextinternalreference, + section = structure.sections.currentid(), + }, + metadata = { + kind = "#2", + name = "\currentlistname", + level = structure.sections.currentlevel(), + catcodes = \the\catcodetable, + }, + userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + }}}% + \expanded{\ctxlatelua{structure.lists.enhance(\currentlistnumber)}}% + \endgroup} + +\def\structurelistlocation + {\ctxlua{structure.lists.location("\currentlist",\currentlistindex)}} + +\def\structurelistpagenumber + {\ctxlua{structure.lists.prefixedpage( + "\currentlist", + \currentlistindex, + { + separatorset = "\listparameter\c!pageprefixseparatorset", + conversionset = "\listparameter\c!pageprefixconversionset", + set = "\listparameter\c!pageprefixset", + segments = "\listparameter\c!pageprefixsegments", + connector = \!!bs\listparameter\c!pageprefixconnector\!!es, + }, + { + prefix = "\listparameter\c!pageprefix", + conversionset = "\listparameter\c!pageconversionset", + stopper = \!!bs\listparameter\c!pagestopper\!!es, + } + )}} + +\def\structurelistrealpagenumber + {\ctxlua{structure.lists.realpage("\currentlist",\currentlistindex)}} + +\def\structurelistfirst + {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"first")}} + +\def\structurelistsecond + {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"second")}} + +% \appendtoks +% \to \everystructurelist + +\def\placestructurelist#1#2#3% + {\ctxlua{structure.lists.process("#1","#2","#3")}} + +\def\analysestructurelist#1#2#3% + {\ctxlua{structure.lists.analyze("#1","#2","#3")}} + +\def\firststructureelementinlist#1% + {\ctxlua{commands.first_in_list("#1")}} + +\def\structurelistsize + {\ctxlua{structure.lists.size()}} + +\def\@@structurelistprocess{structurelist:process:} + +\def\installstructurelistprocessor#1#2% + {\expandafter\def\csname\@@structurelistprocess#1\endcsname{#2}} + +\def\usestructurelistprocessor#1% + {\csname\@@structurelistprocess#1\endcsname} + +\installstructurelistprocessor\s!default + {no list method} + +\def\processlistofstructure#1#2#3% name, method, n + {\edef\currentlist {#1}% + \edef\currentlistmethod{#2}% + \edef\currentlistindex {#3}% + \csname\@@structurelistprocess + \ifcsname\@@structurelistprocess\currentlist:\currentlistmethod\endcsname\currentlist:\currentlistmethod\else + \ifcsname\@@structurelistprocess\currentlistmethod \endcsname\currentlistmethod \else + \ifcsname\@@structurelistprocess\currentlist \endcsname\currentlist \else + \s!default \fi\fi\fi + \endcsname} + +% \installstructcurelistprocessor{pubs:userdata} +% {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"bibref")}} + +\installstructurelistprocessor{command} + {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"command")}} + +\installstructurelistprocessor{section} + {\dodolistelement + \currentlist + \structurelistlocation + \structurelistgenericnumber + \structurelistgenerictitle + \structurelistpagenumber + \structurelistrealpagenumber} + +% so far (todo: also recursive) + +\def\listalternativeparameter#1% + {\csname\??li\??li\listparameter\c!alternative#1\endcsname} + +\def\setuplistalternative[#1]% + {\dodoubleargument\getparameters[\??li\??li#1]} + +\def\listfill {\listalternativeparameter\c!command } +\def\listskip {\listalternativeparameter\c!distance} +\def\listwidth {\listalternativeparameter\c!width } +\def\liststretch{\listalternativeparameter\c!stretch } + +% a : nr - tit - pag +% b : nr - tit - fill - pag +% c : nr - tit - dots - pag + +\setuplistalternative[a][\c!distance=0pt,\c!width=2em,\c!stretch=10em,\c!command=\hskip.25em\relax] +\setuplistalternative[b][\c!distance=5em,\c!width=2em,\c!stretch=10em,\c!command=\hfill] +\setuplistalternative[c][\c!distance=5em,\c!width=0pt,\c!stretch=10em,\c!command=\hskip.5em\listdots\hskip.5em\relax] + +\def\listdots{\leaders\hbox to .5em{\hss.\hss}\hfill} + +\setvalue{\??li\c!alternative}{\getvalue{\??li\c!alternative b}} +\getvalue{\??li\c!alternative} + +\def\dosetuplist[#1][#2]% slow -) + {\def\docommand##1{\getparameters[\??li##1][#2]}% + \processcommalist[#1]\docommand} + +\def\setuplist + {\dodoubleargument\dosetuplist} + +\def\dodefinelist[#1][#2][#3]% + {\presetlocalframed[\??li#1]% still inefficient (will change when we redu core-rul) + \doifassignmentelse{#2} + {\getparameters[\??li#1][\s!parent=\??li,#2]} + {\doifelsenothing{#2} + {\getparameters[\??li#1][\s!parent=\??li]} + {\getparameters[\??li#1][\s!parent=\??li#2,#3]}}} + +\def\setuplists % new, but not for users (hardly handy) + {\dodoubleargument\getparameters[\??li]} + +\setuplists + [\c!height=\v!broad, + \c!depth=\v!broad, + \c!offset=0.25em, + %\c!maxwidth=, + \c!state=\v!start, + \c!coupling=\v!off, + \c!criterium=\v!local, + \c!number=0, + \c!width=3em, + \c!alternative=\c!b, + \c!style=\v!normal, + \c!textstyle=\listparameter\c!style, + \c!numberstyle=\listparameter\c!style, + \c!pagestyle=\listparameter\c!style, + %\c!color=, + \c!textcolor=\listparameter\c!color, + \c!numbercolor=\listparameter\c!color, + \c!pagecolor=\listparameter\c!color, + \c!numbercommand=\listnumbercommand, + \c!textcommand=\listtextcommand, + \c!pagecommand=\listpagecommand, + \c!pagenumber=\v!yes, + \c!headnumber=\v!yes, + %\c!pageboundaries=, + \c!margin=\!!zeropoint, + %\c!aligntitle=, + %\c!before=, + %\c!after=, + %\c!inbetween=, + %\c!symbol=, + \c!interaction=\v!sectionnumber, + \c!label=\v!no, + \c!distance=\!!zeropoint, + \c!limittext=\@@kolimittext, + %\c!sectionseparatorset=, + %\c!sectionconversionset=, + %\c!sectionstopper=, + %\c!sectionset=, + %\c!sectionsegments=, + %\c!prefix=\v!no, + %\c!prefixseparatorset=, + %\c!prefixconversionset=, + %\c!prefixstopper=., + %\c!prefixset=, + %\c!prefixsegments=, + %\c!pageseparatorset=, + %\c!pageconversionset=, + %\c!pagestopper=, + %\c!expansion=, + % \c!prefixconnector=., % maybe inherit from setupheads + % \c!pageprefix=\v!no, % is unset, inherits + % \c!pageprefixconnector=\listparameter\c!prefixconnector, + ]% \c!pagesegments=2:2] + +\def\definelist + {\dotripleempty\dodefinelist} + +\def\placelist + {\dodoubleempty\doplacelist} + +\def\placerawlist + {\dodoubleempty\doplacerawlist} + +\def\dobeginoflist + {\begingroup + \startpacked[\v!blank]} + +\def\doendoflist + {\stoppacked + \endgroup} + +\def\doplacelist[#1][#2]% + {\dobeginoflist + \doplacerawlist[#1][#2]% + \doendoflist} + +\newtoks\everystructurelist + +% writing to lists + +\def\writetolist[#1]{\gobbletwoarguments} +\let\dowritetolist \gobblefourarguments +\let\dodowritetolist\gobblefourarguments + +\def\writebetweenlist[#1]#2% + {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][command][command={#2}]}} + +\def\writedatatolist + {\dodoubleargument\dowritedatatolist} + +\def\dowritedatatolist[#1][#2]% + {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][userdata][#2]}} + +\def\writetolist[#1]#2#3% + {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][simple][first={#2},second={#3}]}} + +\installstructurelistprocessor{simple} + {\dodolistelement + \currentlist + \structurelistlocation + \structurelistfirst + \structurelistsecond + \structurelistpagenumber + \structurelistrealpagenumber} + +% % % + +\def\doplacerawlist[#1][#2]% listreferences will be redone + {\begingroup + \dosetuplist[#1][#2]% + \edef\currentlist{\firststructureelementinlist{#1}}% + \the\everystructurelist + \doif{\listparameter\c!coupling}\v!on{\startlistreferences{#1}}% + \placestructurelist{#1}{\listparameter\c!criterium}{\listparameter\c!number}% + \stoplistreferences + \endgroup + \dosetlistmode} + +\def\dosetlistmode % utilitydone will disappear + {\ifcase\structurelistsize\relax + \utilitydonefalse \resetsystemmode\v!list + \else + \utilitydonetrue \setsystemmode \v!list + \fi} + +\def\systemsuppliedchapter {\getvalue{\v!chapter}} % brrr +\def\systemsuppliedtitle {\getvalue{\v!title}} % brrr + +\def\dodocompletelist[#1][#2][#3]% enkelvoud, meervoud, instellingen + {\normalexpanded{\noexpand\systemsuppliedtitle[#2]{\noexpand\headtext{#2}}}% expansion needed for v! vs french ! + \doplacelist[#1][#3]} + +\def\docompletelist[#1][#2]% + {\dodocompletelist[#1][#1][#2]} + +\def\completelist + {\dodoubleempty\docompletelist} + +\def\listelements {} % list of page breaks +\def\listnumbercommand #1{#1} % no strut due to interactive version +\def\listtextcommand #1{\begstrut#1\endstrut} +\def\listpagecommand #1{\strut#1} + +\def\doassigndimen#1#2#3% + {\doifinsetelse{#2}{\v!fit,\v!broad}{#1=#3}{#1=#2}\relax} + +\def\listsymbol[#1]#2% + {\begingroup + \edef\currentlist{#1}% + \edef\currentlistnumber{#2}% + \currentlistsymbol + \endgroup} + +% Beware, the list symbol macro gets an argument passed, i.e. when this +% argument is not picked up, the symbol becomes a kind of prefix. + +% for historical reasons we're stuck to symbols, so in order to generalize, +% we have to hook it into the symbol handler; we need a beter clean up later +% +% < 2005 +% +% \def\dosetlistsymbol % #1 +% {\executeifdefined{listsymbol@\listparameter\c!symbol}\listsymbol@default} % {#1} +% +% >= 2005 +% +% at this symbol level, we have access to the raw 'number' in +% \currentlistnumber + +\definesymbol[\v!list][\v!none ][\listsymbol@none ] +\definesymbol[\v!list][\v!one ][\listsymbol@one ] +\definesymbol[\v!list][\v!two ][\listsymbol@two ] +\definesymbol[\v!list][\v!three ][\listsymbol@three ] +\definesymbol[\v!list][\s!default][\listsymbol@default] +\definesymbol[\v!list][\s!unknown][\listsymbol@unknown] + +\def\currentlistsymbol + {\doifinsymbolsetelse\v!list{\listparameter\c!symbol} + {\directsymbol\v!list{\listparameter\c!symbol}} + {\directsymbol\v!list\s!default}} + +\def\listsymbol@none + {\doassigndimen\scratchdimen{\listparameter\c!width}{1.5em}% + \hbox to \scratchdimen{}} + +\def\listsymbol@one + {\strut$\bullet$} + +\def\listsymbol@two + {\vrule\!!width1em\!!height1ex\!!depth\zeropoint} + +\def\listsymbol@three + {\begingroup + \doassigndimen{\dimen0}{\listparameter\c!width }{1.5em}% + \doassigndimen{\dimen2}{\listparameter\c!height}{1ex}% + \doassigndimen{\dimen4}{\listparameter\c!depth }\zeropoint + \vrule\!!width\dimen0\!!height\dimen2\!!depth\dimen4% + \endgroup} + +\def\listsymbol@default + {% prefix = no, none, yes + \strut + \doif{\listparameter\c!label}\v!yes{\leftlabeltext\currentlist}% + \currentlistnumber + \listparameter\c!stopper + \doif{\listparameter\c!label}\v!yes{\rightlabeltext\currentlist}} + +\def\listsymbol@default + {% todo: + % prefix=no (first gone)|none (all gone)|yes + % number=no|yes + \strut + \doifelse{\listparameter\c!label}\v!yes + {\leftlabeltext\currentlist + \currentlistnumber + \listparameter\c!stopper + \rightlabeltext\currentlist} + {\currentlistnumber + \listparameter\c!stopper}} + +\def\listsymbol@unknown + {\listparameter\c!symbol} + +% so far for list symbols + +\def\@@dodolistelement{dodolistelement} + +\def\dosomelistelement#1#2#3{#1 #2 #3} + +\setvalue{\@@dodolistelement a}{\let\dosomelistelement\dodofixdlistelementABC} +\setvalue{\@@dodolistelement b}{\let\dosomelistelement\dodofixdlistelementABC} +\setvalue{\@@dodolistelement c}{\let\dosomelistelement\dodofixdlistelementABC} +\setvalue{\@@dodolistelement d}{\let\dosomelistelement\dodofixdlistelementD} +\setvalue{\@@dodolistelement e}{\let\dosomelistelement\dodofixdlistelementE} +\setvalue{\@@dodolistelement f}{\let\dosomelistelement\dodofixdlistelementF} +\setvalue{\@@dodolistelement g}{\let\dosomelistelement\dodofixdlistelementG} + +\setvalue{\@@dodolistelement\v!none }{\def\dosomelistelement{\dodofreevlistelement}} +\setvalue{\@@dodolistelement\v!vertical }{\def\dosomelistelement{\dodofreevlistelement}} +\setvalue{\@@dodolistelement\v!horizontal}{\def\dosomelistelement{\dodofreehlistelement}} +\setvalue{\@@dodolistelement\v!command }{\let\dosomelistelement\dodocommandlistelement} + +% \setuplist +% [section] +% [alternative=MyListItem, +% after=\blank, +% before=\blank] +% +% \definelistplacement[MyListItem][none]#1#2#3% +% {(#1) (#2) (#3)} + +\def\definelistplacement + {\dodoubleempty\dodefinelistplacement} + +\def\dodefinelistplacement[#1][#2]% + {\setvalue{\@@dodolistelement#1}% + {\doifelsenothing{#2} + {\getvalue{\@@dodolistelement\v!command}}% + {\executeifdefined{\@@dodolistelement#2}{\getvalue{\@@dodolistelement\v!command}}}% + \setvalue{\??li\currentlist\c!command}{\getvalue{\@@dodolistelement::#1}}}% + \setvalue{\@@dodolistelement::#1}} + +% don't mess arround with endgraf/grouping else we loose leftskip + +% \strippedcsname\dodolistelement + +\def\newlineinlist{\space} + +\let\currentlist\s!unknown + +\def\docurrentlistalternative + {\edef\currentlistalternative{\listparameter\c!alternative}% + \ifx\currentlistalternative\empty + [unknown list alternative]% + \else + \executeifdefined{\@@dodolistelement\currentlistalternative}{[unknown list alternative: \currentlistalternative]}% + \fi} + +\def\dodolistelement#1#2#3#4#5#6% + {\edef\currentlist{#1}% + \edef\currentlistnumber{#3}% + \docurrentlistalternative + %\showcomposition + \let\@@iawidth\!!zeropoint % moet boolean worden + \begingroup + \edef\listelements{\listparameter\c!pageboundaries}% + \normalexpanded{\noexpand\doifinset{#3}{\listelements}} + {\showmessage\m!systems{14}{#3}% + \page}% + \endgroup + \dontcomplain + %\setfullsectionnumber{\??li\currentlist}% todo + \dosomelistelement{#1}{#2}{#3}{#4}{#5}{#6}% + \global\utilitydonetrue} % ? + +\def\dodocommandlistelement#1#2#3#4#5#6% + {\doifdefinedelse{\??li#1\c!command} + {\listparameter\c!command{#3}{#4}{#5}} + {[\currentlist: #3 -- #4 -- #5]}} + +\def\dodofreelistelement#1#2#3#4#5#6#7#8% + {\def\makelistelement##1##2% + {\noindent % new and needed + \hbox + {\doifelse{\listparameter\c!interaction}{##1} % \??li ipv \??ia + {\setbox0\hbox{\showcontrastlocation{\??li\currentlist}{#6}{##2}}% + \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}% + {##2}}}% + \listparameter\c!before% can be \hskip + \doifdefinedelse{\??li#1\c!command} + {\makelistelement{\listparameter\c!interaction}% this forces all + {\listparameter\c!command + {#3}% geen conversies etc + {#4}% geen conversies etc + {#5}}}% geen command + {#7% + \vbox + {\forgetall + \makelistelement\v!all + {\doif{\listparameter\c!headnumber}\v!yes + {\makelistelement\v!sectionnumber + {\donestedlistattributes\c!numberstyle\c!numbercolor + {\listparameter\c!numbercommand{\currentlistsymbol}}}}% + \makelistelement\v!text + {\donestedlistattributes\c!textstyle\c!textcolor + {\let\\=\newlineinlist + \dontconvertfont + \listparameter\c!textcommand{#4}}}% + \doif{\listparameter\c!pagenumber}\v!yes + {\doifsomething{#5} + {\makelistelement\v!pagenumber + {\donestedlistattributes\c!pagestyle\c!pagecolor + {\listparameter\c!pagecommand{#5}}}}}}}% + #8}% + \listparameter\c!after} + +\def\dodofreehlistelement#1#2#3#4#5#6% + {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6} + {\noindent}{}} + +\def\dodofreevlistelement#1#2#3#4#5#6% % \nointerlineskip needed, + {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6} % otherwise wrong spacing + {\ifvmode\nointerlineskip\fi} % at multi-line lists + {\ifvmode\nointerlineskip\fi\endgraf\allowbreak}} % test is saveguard + +% to be documented: align, hang + +\def\limitatedlistentry#1% + {\doifelsenothing{\listparameter\c!maxwidth} + {\listparameter\c!textcommand{#1}} + {\listparameter\c!textcommand + {\limitatetext + {#1}% + {\listparameter\c!maxwidth}% + {\splitsymbol{\listparameter\c!limittext}}}}} + +\def\dodofixdlistelementABC#1#2#3#4#5#6% weeden + {\endgraf + \leftskip\listparameter\c!margin% na de \endgraf ! + \listparameter\c!before + \!!widthc\listparameter\c!distance + \doifelse{\listparameter\c!width}\v!fit + {\!!widtha\zeropoint} + {\doifelsenothing{#3} + {\doifelse{\listparameter\c!aligntitle}\v!yes + {\!!widtha\zeropoint + \!!widthc\zeropoint} + {\!!widtha\listparameter\c!width}} + {\!!widtha\listparameter\c!width}}% + \getvalue{\??li\c!alternative\listparameter\c!alternative}% + \endgraf + \def\makelistelement##1##2% + {\doifelse{\listparameter\c!interaction}{##1} + {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}% + \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}% + {\hbox{##2}}}% + \doif{\listparameter\c!interaction}\v!text % not supported ! ! ! ! ! ! text == all + {\setlistparameter\currentlist\c!interaction\v!all}% + % \dontleavehmode % new, else no margin, but wrong, better (else \indent as well): + \noindent + \makelistelement\v!all + {\setlocalhsize + \hsize\localhsize + \hbox to \hsize + {\forgetall + \dosetlistattributes\c!style\c!color + \!!widthb\hsize + \doifelse{\listparameter\c!headnumber}\v!yes + {\setbox2\hbox \ifdim\!!widtha>\zeropoint to \!!widtha \fi + {\makelistelement\v!sectionnumber + {\donestedlistattributes\c!numberstyle\c!numbercolor + {\listparameter\c!numbercommand{\currentlistsymbol}}% + \hfill}}} + {\!!widtha\zeropoint + \!!widthc\zeropoint + \setbox2\hbox{}}% + \setbox4\hbox + {\doif{\listparameter\c!pagenumber}\v!yes + {\doifsomething{#5} % \listwidth is new ; temp hack + {\hbox \ifdim\listwidth>\zeropoint to \listwidth\fi + {\hfill + \makelistelement\v!pagenumber + {\donestedlistattributes\c!pagestyle\c!pagecolor + {\listparameter\c!pagecommand{#5}}}}}}}% + \vbox + {\hsize\!!widthb + \setupalign[\listparameter\c!align]% + \ifdim\!!widtha<\hsize + \hangindent\wd2 + \dimen2=\!!widthc % \listparameter\c!distance + \advance\hangindent \dimen2 + \hangafter\plusone + \doif{\listparameter\c!hang}\v!no{\hangafter\zerocount}% + \ifdim\wd4=\zeropoint % \ifvoid4 + % we kunnen gewoon afbreken aan het eind + \else + \ifdim\listskip>\zeropoint\relax + \rightskip\listskip\!!plus\liststretch\relax + \parfillskip-\rightskip + \fi + \fi + \else + \dimen2\zeropoint + \fi + \parindent\zeropoint\relax + \leavevmode + \box2\relax + \hskip\dimen2 + \bgroup + \donestedlistattributes\c!textstyle\c!textcolor + {\let\\=\newlineinlist + \dontconvertfont + %\listparameter\c!textcommand{#4}}% + \limitatedlistentry{#4}}% + %\carryoverpar % new otherwise wrong linespacing + \egroup + \ifdim\wd4=\zeropoint\relax % \ifvoid4 + % \ifdim\!!widtha<\hsize \hfill\strut \fi % spoils align + \else + \nobreak\listfill + \box4\relax + \relax + \fi}% + \hss}}% new + \endgraf % new, else problems with nointerlinespace and prevdepth + \nointerlineskip % anders verkeerde spatiering bij multi-line + \endgraf + \allowbreak + \listparameter\c!after} + +% % example from the context list +% +% \setuphead [part] [page=right,placehead=yes] +% \setuplist [chapter] [alternative=d,before=\blank,after=\blank] +% \setuplist [part] [before=\blank,after=\blank] +% +% \starttext +% \startnarrower[2*right] \placecontent \stopnarrower +% \blank[4*big] +% \startsetups chapter +% \blank \startnarrower[3*middle] \placecontent[criterium=local] \stopnarrower +% \stopsetups +% \placelist[part][criterium=text,after=\setups{chapter}] +% +% \part{First part} \chapter{Chapter one} \chapter{Chapter two} +% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five} +% \part{Second part} \chapter{Chapter one} \chapter{Chapter two} +% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five} +% \part{Third part} \chapter{Chapter one} \chapter{Chapter two} +% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five} +% \stoptext + +% overrulen interactie kan sneller, bv door hulpconstanten +% te gebruiken en die te letten + +\def\dodofixdlistelementD#1#2#3#4#5#6% + {%\leftskip=\listparameter\c!margin + \ifvmode + \advance\leftskip\listparameter\c!margin% AANGEPAST + \fi + \bgroup + \ifvmode + \noindent\leavevmode % leavevmode ? ? ? + \fi + \doif{\listparameter\c!interaction}\v!text % not supported + {\setlistparameter\currentlist\c!interaction\v!sectionnumber}% + \doif{\listparameter\c!interaction}\v!all % not supported + {\setlistparameter\currentlist\c!interaction\v!sectionnumber}% + \def\makelistelement##1##2% + {\doifelse{\listparameter\c!interaction}{##1} + {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}% + \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}% + {\hbox{##2}}}% + \setbox4\hbox + {\doif{\listparameter\c!pagenumber}\v!yes + {\doifsomething{#5} + {\makelistelement\v!pagenumber + {\donestedlistattributes\c!pagestyle\c!pagecolor + {\listparameter\c!pagecommand{#5}}}}}}% + \doif{\listparameter\c!headnumber}\v!yes + {\donetrue + \doifnothing{#3}{\doifnothing{\listparameter\c!symbol}\donefalse}% + % == \doifnothing{#3\listparameter\c!symbol}\donefalse + \ifdone + \hbox + {\listparameter\c!left + \makelistelement\v!sectionnumber + {\donestedlistattributes\c!numberstyle\c!numbercolor + {\listparameter\c!numbercommand{\currentlistsymbol}}}% + \listparameter\c!right + \hskip.5em}% + \nobreak + \fi}% + \tolerance3500 % niet zomaar veranderen + \donestedlistattributes\c!textstyle\c!textcolor + {\let\\=\newlineinlist + \dontconvertfont + %\listparameter\c!textcommand{#4}}% + \limitatedlistentry{#4}}% + \ifvoid4\else + \nobreak + \hskip.75em\relax + \nobreak + \box4 + \fi + \dimen0=\listparameter\c!distance\relax + \ifdim\dimen0<1em\relax + \hskip1em\!!plus1em\!!minus.25em\relax + \else + \hskip\dimen0\!!plus.5\dimen0\!!minus.25\dimen0\relax + \fi + \egroup} + +\def\dodofixdlistelementE#1% + {\dodofixdlistelementEFG + {\setupinteraction[\c!strut=\v!no]} + {\localframed[\??li\currentlist][\c!depth=\!!zeropoint,\c!color=]} + {}} + +\def\dodofixdlistelementF#1% + {\dodofixdlistelementEFG + {} + {\dosetraggedhbox{\listparameter\c!align}\raggedbox} + {}} + +\def\dodofixdlistelementG#1% + {\dodofixdlistelementEFG + {} + \midaligned + {}} + +\def\dodofixdlistelementEFG#1#2#3#4#5#6#7#8% + {\noindent + \bgroup + \def\makelistelement##1##2% isolated by Wolfgang Schuster + {\doifelse{\listparameter\c!interaction}{##1} + {#2{##2}} + {\setbox0\hbox{#2{\showcontrastlocation\??ia{#8}{##2}}}% + \linklisttoelement{#4}{#7}{#8}{\box0}}}% + \makelistelement\v!no + {\let\\=\newlineinlist + #1% in case E nils the strut (still needed?) + \dosetlistattributes\c!style\c!color + \ignorespaces\dontconvertfont\setstrut + \begstrut + \limitatedlistentry{#6}% + \endstrut}% + \egroup + \par + \listparameter\c!inbetween} + +\def\listlength{\utilitylistlength} +\def\listwidth {\utilitylistwidth} +\def\listheight{\utilitylistheight} + +\def\utilitylistlength {0} +\def\utilitylistwidth {0pt} % no longer supported +\def\utilitylistheight {0pt} % no longer supported + +\def\dodeterminelistcharacteristics[#1][#2]% + {\begingroup + \dosetuplist[#1][#2]% + \edef\currentlist{\firststructureelementinlist{#1}}% + \the\everystructurelist + \analysestructurelist{#1}{\listparameter\c!criterium}{\listparameter\c!number}% + \xdef\utilitylistlength{\structurelistsize}% + \endgroup + \dosetlistmode} + +\def\determinelistcharacteristics + {\dodoubleempty\dodeterminelistcharacteristics} + +\def\combinedlistparameter#1{\csname\??ih\currentcombinedlist#1\endcsname} + +\def\setupcombinedlist + {\dodoubleargument\dosetupcombinedlist} + +\def\dosetupcombinedlist[#1][#2]% + {\getparameters[\??ih#1][#2]% + \edef\currentcombinedlist{#1}% + \normalexpanded{\noexpand\setuplist[\combinedlistparameter\c!list]}[#2]} + +\def\definecombinedlist + {\dotripleempty\dodefinecombinedlist} + +\def\dodefinecombinedlist[#1][#2][#3]% + {\getparameters + [\??ih#1] + [\c!criterium=\v!local,\c!number=0,\c!list={#2},#3]% + \setvalue{\e!setup#1\e!endsetup}{\dodoubleempty\dosetupcombinedlist[#1]}% + \setvalue{\e!place#1}{\dodoubleempty\doplacecombinedlist[#1]}% + \setvalue{\e!complete#1}{\dodoubleempty\docompletecombinedlist[#1]}} + +\def\placecombinedlist + {\dodoubleempty\doplacecombinedlist} + +\def\doplacecombinedlist[#1][#2]% we can move much of the analysis to lua + {\begingroup + % level is no longer supported + \def\currentcombinedlist{#1}% + \getparameters[\??ih#1][#2]% + \edef\combinedlist{\combinedlistparameter\c!list}% + \the\everystructurelist + \doif{\combinedlistparameter\c!coupling}\v!on{\startlistreferences{#1}}% + \dobeginoflist + \normalexpanded{\noexpand\dosetuplist[\combinedlist][#2]}% + \placestructurelist{\combinedlist}{\combinedlistparameter\c!criterium}{\combinedlistparameter\c!number}% + \doendoflist + \stoplistreferences + \endgroup + \dosetlistmode} + +\def\docompletecombinedlist[#1][#2]% + {\normalexpanded{\noexpand\systemsuppliedtitle[#1]{\noexpand\headtext{#1}}}% expansion due to v! vs french ! + \doplacecombinedlist[#1][#2]} + +% lists that have a number/title are kind of generic and can share code + +\installstructurelistprocessor{number+title} + {\dodolistelement + \currentlist + \structurelistlocation + \structurelistgenericnumber + \structurelistgenerictitle + \structurelistpagenumber + \structurelistrealpagenumber} + +\def\structurelistgenerictitle + {\ctxlua{structure.lists.title("\currentlist",\currentlistindex)}} + +\def\structurelistgenericnumber{\ctxlua{ + structure.lists.prefixednumber("\currentlist",\currentlistindex, { + prefix = "\listparameter\c!prefix", + separatorset = "\listparameter\c!prefixseparatorset", + conversionset = "\listparameter\c!prefixconversionset", + stopper = \!!bs\listparameter\c!prefixstopper\!!es, + set = "\listparameter\c!prefixset", + segments = "\listparameter\c!prefixsegments", + connector = \!!bs\listparameter\c!prefixconnector\!!es, + }, + { + separatorset = "\listparameter\c!numberseparatorset", + conversionset = "\listparameter\c!numberconversionset", + stopper = \!!bs\listparameter\c!numberstopper\!!es, + segments = "\listparameter\c!numbersegments", + } )}} + +% new and yet undocumented (used in cocoa qa), temporarily disabled in mkiv +% +% \setupremaininglistlength +% [left=\hss nog~,right=~ingangen] +% +% \resetremaininglistlength +% [section][settings] +% +% \placelist +% [section] +% [before=\showremaininglistlength] +% +% \dorecurse{100}{\section{hans}} +% +% \definesystemvariable {ll} % ListLength +% +% \def\setupremaininglistlength[#1]% +% {\getparameters[\??ll][#1]% +% \globallet\listlengthcounter\!!zerocount} +% +% \setupremaininglistlength +% [\c!left=\hss,\c!right=,\c!number=\v!yes, +% \c!before=\blank,\c!after=\page, +% \c!style=\v!smallnormal,\c!color=] +% +% \def\resetremaininglistlength +% {\dodoubleempty\doresetremaininglistlength} +% +% \def\doresetremaininglistlength[#1][#2]% +% {\determinelistcharacteristics[#1][#2]% +% \xdef\listlengthcounter{\number\utilitylistlength}} +% +% \def\showremaininglistlength +% {\bgroup +% \ifnum\listlengthcounter>\plusone +% \setbox\scratchbox\vbox +% {\@@llbefore\par\horizontalstrut\par\horizontalstrut\par\@@llafter}% +% \scratchdimen\pagetotal +% \advance\scratchdimen \ht\scratchbox +% \advance\scratchdimen \dp\scratchbox +% \ifdim\scratchdimen>\pagegoal +% \@@llbefore +% \nobreak\hbox to \hsize +% {\doifnot\@@llnumber\v!yes{\let\listlengthcounter\empty}% +% \doattributes\??ll\c!style\c!color{\@@llleft\listlengthcounter\@@llright}} +% \@@llafter +% \fi +% \fi +% \doglobal\decrement\listlengthcounter\relax +% \egroup} + +\protect \endinput diff --git a/tex/context/base/strc-lst.tex b/tex/context/base/strc-lst.tex deleted file mode 100644 index 22c189c77..000000000 --- a/tex/context/base/strc-lst.tex +++ /dev/null @@ -1,944 +0,0 @@ -%D \module -%D [ file=strc-lst, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Lists, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Lists} - -\registerctxluafile{strc-lst}{1.001} - -\unprotect - -\def\currentstructurelistnumber{0} - -% nmstate -> no pagenumber if not start -% autocrossdocument -> todo -% expansion -> todo -% auto refs to lists (chain) -> todo (\dododowritetolist) -% todo: \normalexpanded{\noexpand\everylistentry\emptytoks\the\everylistentry}% \emptytoks, else loop - -% \def\linklisttoelement#1#2#3#4{#4}% list location format page data - -\def\linklisttoelement#1#2#3#4% % list location format page data - {\gotonextinternal\currentlist{#1}{#3}{#4}} - -% interface to lua - -% we have to deal with compatible processing, i.e. list elements that have two -% elements plus a pagenumber - -\let\listentry\gobblesixarguments - -\def\currentlist {\s!unknown} -\def\currentlistmethod{entry} -\def\currentlistindex {0} - -\def\setlistparameter#1#2#3{\@EA\def\csname\??li#1#2\endcsname{#3}} % often -%def\listparameter #1{\ifcsname\??li\currentlist#1\endcsname\csname\??li\currentlist#1\endcsname\fi} - -% interface - -\def\listparameter #1{\csname\dolistparameter{\??li\currentlist}#1\endcsname} -\def\namedlistparameter#1#2{\csname\dolistparameter{\??li #1}#2\endcsname} -\def\listparameterhash #1{\dolistparameterhash {\??li\currentlist}#1} - -\def\dolistparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dolistparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\dolistparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dolistparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dolistparentparameter #1#2{\ifx#1\relax\s!empty\else\dolistparameter #1#2\fi} -\def\dolistparentparameterhash#1#2{\ifx#1\relax \else\dolistparameterhash#1#2\fi} - -\def\dosetlistattributes#1#2% style color - {\edef\fontattributehash {\listparameterhash#1}% - \edef\colorattributehash{\listparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -\def\donestedlistattributes#1#2% - {\dosetlistattributes#1#2% - \ifx\colorattributehash\empty \else - \resetinteractionparameter\c!color - \resetinteractionparameter\c!contrastcolor - \fi} - -% handling - - -% The next code injects data into the list at the current level. - -\def\structurelistinject{\dotripleempty\dostructurelistinject} - -\def\dostructurelistinject[#1][#2][#3]% - {\begingroup - \edef\currentlistname{#1}% - \setnextinternalreference - \edef\currentlistnumber{\ctxlua{structure.lists.push{ - references = { - internal = \nextinternalreference, - section = structure.sections.currentid(), - }, - metadata = { - kind = "#2", - name = "\currentlistname", - level = structure.sections.currentlevel(), - catcodes = \the\catcodetable, - }, - userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) - }}}% - \expanded{\ctxlatelua{structure.lists.enhance(\currentlistnumber)}}% - \endgroup} - -\def\structurelistlocation - {\ctxlua{structure.lists.location("\currentlist",\currentlistindex)}} - -\def\structurelistpagenumber - {\ctxlua{structure.lists.prefixedpage( - "\currentlist", - \currentlistindex, - { - separatorset = "\listparameter\c!pageprefixseparatorset", - conversionset = "\listparameter\c!pageprefixconversionset", - set = "\listparameter\c!pageprefixset", - segments = "\listparameter\c!pageprefixsegments", - connector = \!!bs\listparameter\c!pageprefixconnector\!!es, - }, - { - prefix = "\listparameter\c!pageprefix", - conversionset = "\listparameter\c!pageconversionset", - stopper = \!!bs\listparameter\c!pagestopper\!!es, - } - )}} - -\def\structurelistrealpagenumber - {\ctxlua{structure.lists.realpage("\currentlist",\currentlistindex)}} - -\def\structurelistfirst - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"first")}} - -\def\structurelistsecond - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"second")}} - -% \appendtoks -% \to \everystructurelist - -\def\placestructurelist#1#2#3% - {\ctxlua{structure.lists.process("#1","#2","#3")}} - -\def\analysestructurelist#1#2#3% - {\ctxlua{structure.lists.analyze("#1","#2","#3")}} - -\def\firststructureelementinlist#1% - {\ctxlua{commands.first_in_list("#1")}} - -\def\structurelistsize - {\ctxlua{structure.lists.size()}} - -\def\@@structurelistprocess{structurelist:process:} - -\def\installstructurelistprocessor#1#2% - {\expandafter\def\csname\@@structurelistprocess#1\endcsname{#2}} - -\def\usestructurelistprocessor#1% - {\csname\@@structurelistprocess#1\endcsname} - -\installstructurelistprocessor\s!default - {no list method} - -\def\processlistofstructure#1#2#3% name, method, n - {\edef\currentlist {#1}% - \edef\currentlistmethod{#2}% - \edef\currentlistindex {#3}% - \csname\@@structurelistprocess - \ifcsname\@@structurelistprocess\currentlist:\currentlistmethod\endcsname\currentlist:\currentlistmethod\else - \ifcsname\@@structurelistprocess\currentlistmethod \endcsname\currentlistmethod \else - \ifcsname\@@structurelistprocess\currentlist \endcsname\currentlist \else - \s!default \fi\fi\fi - \endcsname} - -% \installstructcurelistprocessor{pubs:userdata} -% {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"bibref")}} - -\installstructurelistprocessor{command} - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"command")}} - -\installstructurelistprocessor{section} - {\dodolistelement - \currentlist - \structurelistlocation - \structurelistgenericnumber - \structurelistgenerictitle - \structurelistpagenumber - \structurelistrealpagenumber} - -% so far (todo: also recursive) - -\def\listalternativeparameter#1% - {\csname\??li\??li\listparameter\c!alternative#1\endcsname} - -\def\setuplistalternative[#1]% - {\dodoubleargument\getparameters[\??li\??li#1]} - -\def\listfill {\listalternativeparameter\c!command } -\def\listskip {\listalternativeparameter\c!distance} -\def\listwidth {\listalternativeparameter\c!width } -\def\liststretch{\listalternativeparameter\c!stretch } - -% a : nr - tit - pag -% b : nr - tit - fill - pag -% c : nr - tit - dots - pag - -\setuplistalternative[a][\c!distance=0pt,\c!width=2em,\c!stretch=10em,\c!command=\hskip.25em\relax] -\setuplistalternative[b][\c!distance=5em,\c!width=2em,\c!stretch=10em,\c!command=\hfill] -\setuplistalternative[c][\c!distance=5em,\c!width=0pt,\c!stretch=10em,\c!command=\hskip.5em\listdots\hskip.5em\relax] - -\def\listdots{\leaders\hbox to .5em{\hss.\hss}\hfill} - -\setvalue{\??li\c!alternative}{\getvalue{\??li\c!alternative b}} -\getvalue{\??li\c!alternative} - -\def\dosetuplist[#1][#2]% slow -) - {\def\docommand##1{\getparameters[\??li##1][#2]}% - \processcommalist[#1]\docommand} - -\def\setuplist - {\dodoubleargument\dosetuplist} - -\def\dodefinelist[#1][#2][#3]% - {\presetlocalframed[\??li#1]% still inefficient (will change when we redu core-rul) - \doifassignmentelse{#2} - {\getparameters[\??li#1][\s!parent=\??li,#2]} - {\doifelsenothing{#2} - {\getparameters[\??li#1][\s!parent=\??li]} - {\getparameters[\??li#1][\s!parent=\??li#2,#3]}}} - -\def\setuplists % new, but not for users (hardly handy) - {\dodoubleargument\getparameters[\??li]} - -\setuplists - [\c!height=\v!broad, - \c!depth=\v!broad, - \c!offset=0.25em, - %\c!maxwidth=, - \c!state=\v!start, - \c!coupling=\v!off, - \c!criterium=\v!local, - \c!number=0, - \c!width=3em, - \c!alternative=\c!b, - \c!style=\v!normal, - \c!textstyle=\listparameter\c!style, - \c!numberstyle=\listparameter\c!style, - \c!pagestyle=\listparameter\c!style, - %\c!color=, - \c!textcolor=\listparameter\c!color, - \c!numbercolor=\listparameter\c!color, - \c!pagecolor=\listparameter\c!color, - \c!numbercommand=\listnumbercommand, - \c!textcommand=\listtextcommand, - \c!pagecommand=\listpagecommand, - \c!pagenumber=\v!yes, - \c!headnumber=\v!yes, - %\c!pageboundaries=, - \c!margin=\!!zeropoint, - %\c!aligntitle=, - %\c!before=, - %\c!after=, - %\c!inbetween=, - %\c!symbol=, - \c!interaction=\v!sectionnumber, - \c!label=\v!no, - \c!distance=\!!zeropoint, - \c!limittext=\@@kolimittext, - %\c!sectionseparatorset=, - %\c!sectionconversionset=, - %\c!sectionstopper=, - %\c!sectionset=, - %\c!sectionsegments=, - %\c!prefix=\v!no, - %\c!prefixseparatorset=, - %\c!prefixconversionset=, - %\c!prefixstopper=., - %\c!prefixset=, - %\c!prefixsegments=, - %\c!pageseparatorset=, - %\c!pageconversionset=, - %\c!pagestopper=, - %\c!expansion=, - % \c!prefixconnector=., % maybe inherit from setupheads - % \c!pageprefix=\v!no, % is unset, inherits - % \c!pageprefixconnector=\listparameter\c!prefixconnector, - ]% \c!pagesegments=2:2] - -\def\definelist - {\dotripleempty\dodefinelist} - -\def\placelist - {\dodoubleempty\doplacelist} - -\def\placerawlist - {\dodoubleempty\doplacerawlist} - -\def\dobeginoflist - {\begingroup - \startpacked[\v!blank]} - -\def\doendoflist - {\stoppacked - \endgroup} - -\def\doplacelist[#1][#2]% - {\dobeginoflist - \doplacerawlist[#1][#2]% - \doendoflist} - -\newtoks\everystructurelist - -% writing to lists - -\def\writetolist[#1]{\gobbletwoarguments} -\let\dowritetolist \gobblefourarguments -\let\dodowritetolist\gobblefourarguments - -\def\writebetweenlist[#1]#2% - {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][command][command={#2}]}} - -\def\writedatatolist - {\dodoubleargument\dowritedatatolist} - -\def\dowritedatatolist[#1][#2]% - {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][userdata][#2]}} - -\def\writetolist[#1]#2#3% - {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][simple][first={#2},second={#3}]}} - -\installstructurelistprocessor{simple} - {\dodolistelement - \currentlist - \structurelistlocation - \structurelistfirst - \structurelistsecond - \structurelistpagenumber - \structurelistrealpagenumber} - -% % % - -\def\doplacerawlist[#1][#2]% listreferences will be redone - {\begingroup - \dosetuplist[#1][#2]% - \edef\currentlist{\firststructureelementinlist{#1}}% - \the\everystructurelist - \doif{\listparameter\c!coupling}\v!on{\startlistreferences{#1}}% - \placestructurelist{#1}{\listparameter\c!criterium}{\listparameter\c!number}% - \stoplistreferences - \endgroup - \dosetlistmode} - -\def\dosetlistmode % utilitydone will disappear - {\ifcase\structurelistsize\relax - \utilitydonefalse \resetsystemmode\v!list - \else - \utilitydonetrue \setsystemmode \v!list - \fi} - -\def\systemsuppliedchapter {\getvalue{\v!chapter}} % brrr -\def\systemsuppliedtitle {\getvalue{\v!title}} % brrr - -\def\dodocompletelist[#1][#2][#3]% enkelvoud, meervoud, instellingen - {\normalexpanded{\noexpand\systemsuppliedtitle[#2]{\noexpand\headtext{#2}}}% expansion needed for v! vs french ! - \doplacelist[#1][#3]} - -\def\docompletelist[#1][#2]% - {\dodocompletelist[#1][#1][#2]} - -\def\completelist - {\dodoubleempty\docompletelist} - -\def\listelements {} % list of page breaks -\def\listnumbercommand #1{#1} % no strut due to interactive version -\def\listtextcommand #1{\begstrut#1\endstrut} -\def\listpagecommand #1{\strut#1} - -\def\doassigndimen#1#2#3% - {\doifinsetelse{#2}{\v!fit,\v!broad}{#1=#3}{#1=#2}\relax} - -\def\listsymbol[#1]#2% - {\begingroup - \edef\currentlist{#1}% - \edef\currentlistnumber{#2}% - \currentlistsymbol - \endgroup} - -% Beware, the list symbol macro gets an argument passed, i.e. when this -% argument is not picked up, the symbol becomes a kind of prefix. - -% for historical reasons we're stuck to symbols, so in order to generalize, -% we have to hook it into the symbol handler; we need a beter clean up later -% -% < 2005 -% -% \def\dosetlistsymbol % #1 -% {\executeifdefined{listsymbol@\listparameter\c!symbol}\listsymbol@default} % {#1} -% -% >= 2005 -% -% at this symbol level, we have access to the raw 'number' in -% \currentlistnumber - -\definesymbol[\v!list][\v!none ][\listsymbol@none ] -\definesymbol[\v!list][\v!one ][\listsymbol@one ] -\definesymbol[\v!list][\v!two ][\listsymbol@two ] -\definesymbol[\v!list][\v!three ][\listsymbol@three ] -\definesymbol[\v!list][\s!default][\listsymbol@default] -\definesymbol[\v!list][\s!unknown][\listsymbol@unknown] - -\def\currentlistsymbol - {\doifinsymbolsetelse\v!list{\listparameter\c!symbol} - {\directsymbol\v!list{\listparameter\c!symbol}} - {\directsymbol\v!list\s!default}} - -\def\listsymbol@none - {\doassigndimen\scratchdimen{\listparameter\c!width}{1.5em}% - \hbox to \scratchdimen{}} - -\def\listsymbol@one - {\strut$\bullet$} - -\def\listsymbol@two - {\vrule\!!width1em\!!height1ex\!!depth\zeropoint} - -\def\listsymbol@three - {\begingroup - \doassigndimen{\dimen0}{\listparameter\c!width }{1.5em}% - \doassigndimen{\dimen2}{\listparameter\c!height}{1ex}% - \doassigndimen{\dimen4}{\listparameter\c!depth }\zeropoint - \vrule\!!width\dimen0\!!height\dimen2\!!depth\dimen4% - \endgroup} - -\def\listsymbol@default - {% prefix = no, none, yes - \strut - \doif{\listparameter\c!label}\v!yes{\leftlabeltext\currentlist}% - \currentlistnumber - \listparameter\c!stopper - \doif{\listparameter\c!label}\v!yes{\rightlabeltext\currentlist}} - -\def\listsymbol@default - {% todo: - % prefix=no (first gone)|none (all gone)|yes - % number=no|yes - \strut - \doifelse{\listparameter\c!label}\v!yes - {\leftlabeltext\currentlist - \currentlistnumber - \listparameter\c!stopper - \rightlabeltext\currentlist} - {\currentlistnumber - \listparameter\c!stopper}} - -\def\listsymbol@unknown - {\listparameter\c!symbol} - -% so far for list symbols - -\def\@@dodolistelement{dodolistelement} - -\def\dosomelistelement#1#2#3{#1 #2 #3} - -\setvalue{\@@dodolistelement a}{\let\dosomelistelement\dodofixdlistelementABC} -\setvalue{\@@dodolistelement b}{\let\dosomelistelement\dodofixdlistelementABC} -\setvalue{\@@dodolistelement c}{\let\dosomelistelement\dodofixdlistelementABC} -\setvalue{\@@dodolistelement d}{\let\dosomelistelement\dodofixdlistelementD} -\setvalue{\@@dodolistelement e}{\let\dosomelistelement\dodofixdlistelementE} -\setvalue{\@@dodolistelement f}{\let\dosomelistelement\dodofixdlistelementF} -\setvalue{\@@dodolistelement g}{\let\dosomelistelement\dodofixdlistelementG} - -\setvalue{\@@dodolistelement\v!none }{\def\dosomelistelement{\dodofreevlistelement}} -\setvalue{\@@dodolistelement\v!vertical }{\def\dosomelistelement{\dodofreevlistelement}} -\setvalue{\@@dodolistelement\v!horizontal}{\def\dosomelistelement{\dodofreehlistelement}} -\setvalue{\@@dodolistelement\v!command }{\let\dosomelistelement\dodocommandlistelement} - -% \setuplist -% [section] -% [alternative=MyListItem, -% after=\blank, -% before=\blank] -% -% \definelistplacement[MyListItem][none]#1#2#3% -% {(#1) (#2) (#3)} - -\def\definelistplacement - {\dodoubleempty\dodefinelistplacement} - -\def\dodefinelistplacement[#1][#2]% - {\setvalue{\@@dodolistelement#1}% - {\doifelsenothing{#2} - {\getvalue{\@@dodolistelement\v!command}}% - {\executeifdefined{\@@dodolistelement#2}{\getvalue{\@@dodolistelement\v!command}}}% - \setvalue{\??li\currentlist\c!command}{\getvalue{\@@dodolistelement::#1}}}% - \setvalue{\@@dodolistelement::#1}} - -% don't mess arround with endgraf/grouping else we loose leftskip - -% \strippedcsname\dodolistelement - -\def\newlineinlist{\space} - -\let\currentlist\s!unknown - -\def\docurrentlistalternative - {\edef\currentlistalternative{\listparameter\c!alternative}% - \ifx\currentlistalternative\empty - [unknown list alternative]% - \else - \executeifdefined{\@@dodolistelement\currentlistalternative}{[unknown list alternative: \currentlistalternative]}% - \fi} - -\def\dodolistelement#1#2#3#4#5#6% - {\edef\currentlist{#1}% - \edef\currentlistnumber{#3}% - \docurrentlistalternative - %\showcomposition - \let\@@iawidth\!!zeropoint % moet boolean worden - \begingroup - \edef\listelements{\listparameter\c!pageboundaries}% - \normalexpanded{\noexpand\doifinset{#3}{\listelements}} - {\showmessage\m!systems{14}{#3}% - \page}% - \endgroup - \dontcomplain - %\setfullsectionnumber{\??li\currentlist}% todo - \dosomelistelement{#1}{#2}{#3}{#4}{#5}{#6}% - \global\utilitydonetrue} % ? - -\def\dodocommandlistelement#1#2#3#4#5#6% - {\doifdefinedelse{\??li#1\c!command} - {\listparameter\c!command{#3}{#4}{#5}} - {[\currentlist: #3 -- #4 -- #5]}} - -\def\dodofreelistelement#1#2#3#4#5#6#7#8% - {\def\makelistelement##1##2% - {\noindent % new and needed - \hbox - {\doifelse{\listparameter\c!interaction}{##1} % \??li ipv \??ia - {\setbox0\hbox{\showcontrastlocation{\??li\currentlist}{#6}{##2}}% - \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}% - {##2}}}% - \listparameter\c!before% can be \hskip - \doifdefinedelse{\??li#1\c!command} - {\makelistelement{\listparameter\c!interaction}% this forces all - {\listparameter\c!command - {#3}% geen conversies etc - {#4}% geen conversies etc - {#5}}}% geen command - {#7% - \vbox - {\forgetall - \makelistelement\v!all - {\doif{\listparameter\c!headnumber}\v!yes - {\makelistelement\v!sectionnumber - {\donestedlistattributes\c!numberstyle\c!numbercolor - {\listparameter\c!numbercommand{\currentlistsymbol}}}}% - \makelistelement\v!text - {\donestedlistattributes\c!textstyle\c!textcolor - {\let\\=\newlineinlist - \dontconvertfont - \listparameter\c!textcommand{#4}}}% - \doif{\listparameter\c!pagenumber}\v!yes - {\doifsomething{#5} - {\makelistelement\v!pagenumber - {\donestedlistattributes\c!pagestyle\c!pagecolor - {\listparameter\c!pagecommand{#5}}}}}}}% - #8}% - \listparameter\c!after} - -\def\dodofreehlistelement#1#2#3#4#5#6% - {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6} - {\noindent}{}} - -\def\dodofreevlistelement#1#2#3#4#5#6% % \nointerlineskip needed, - {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6} % otherwise wrong spacing - {\ifvmode\nointerlineskip\fi} % at multi-line lists - {\ifvmode\nointerlineskip\fi\endgraf\allowbreak}} % test is saveguard - -% to be documented: align, hang - -\def\limitatedlistentry#1% - {\doifelsenothing{\listparameter\c!maxwidth} - {\listparameter\c!textcommand{#1}} - {\listparameter\c!textcommand - {\limitatetext - {#1}% - {\listparameter\c!maxwidth}% - {\splitsymbol{\listparameter\c!limittext}}}}} - -\def\dodofixdlistelementABC#1#2#3#4#5#6% weeden - {\endgraf - \leftskip\listparameter\c!margin% na de \endgraf ! - \listparameter\c!before - \!!widthc\listparameter\c!distance - \doifelse{\listparameter\c!width}\v!fit - {\!!widtha\zeropoint} - {\doifelsenothing{#3} - {\doifelse{\listparameter\c!aligntitle}\v!yes - {\!!widtha\zeropoint - \!!widthc\zeropoint} - {\!!widtha\listparameter\c!width}} - {\!!widtha\listparameter\c!width}}% - \getvalue{\??li\c!alternative\listparameter\c!alternative}% - \endgraf - \def\makelistelement##1##2% - {\doifelse{\listparameter\c!interaction}{##1} - {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}% - \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}% - {\hbox{##2}}}% - \doif{\listparameter\c!interaction}\v!text % not supported ! ! ! ! ! ! text == all - {\setlistparameter\currentlist\c!interaction\v!all}% - % \dontleavehmode % new, else no margin, but wrong, better (else \indent as well): - \noindent - \makelistelement\v!all - {\setlocalhsize - \hsize\localhsize - \hbox to \hsize - {\forgetall - \dosetlistattributes\c!style\c!color - \!!widthb\hsize - \doifelse{\listparameter\c!headnumber}\v!yes - {\setbox2\hbox \ifdim\!!widtha>\zeropoint to \!!widtha \fi - {\makelistelement\v!sectionnumber - {\donestedlistattributes\c!numberstyle\c!numbercolor - {\listparameter\c!numbercommand{\currentlistsymbol}}% - \hfill}}} - {\!!widtha\zeropoint - \!!widthc\zeropoint - \setbox2\hbox{}}% - \setbox4\hbox - {\doif{\listparameter\c!pagenumber}\v!yes - {\doifsomething{#5} % \listwidth is new ; temp hack - {\hbox \ifdim\listwidth>\zeropoint to \listwidth\fi - {\hfill - \makelistelement\v!pagenumber - {\donestedlistattributes\c!pagestyle\c!pagecolor - {\listparameter\c!pagecommand{#5}}}}}}}% - \vbox - {\hsize\!!widthb - \setupalign[\listparameter\c!align]% - \ifdim\!!widtha<\hsize - \hangindent\wd2 - \dimen2=\!!widthc % \listparameter\c!distance - \advance\hangindent \dimen2 - \hangafter\plusone - \doif{\listparameter\c!hang}\v!no{\hangafter\zerocount}% - \ifdim\wd4=\zeropoint % \ifvoid4 - % we kunnen gewoon afbreken aan het eind - \else - \ifdim\listskip>\zeropoint\relax - \rightskip\listskip\!!plus\liststretch\relax - \parfillskip-\rightskip - \fi - \fi - \else - \dimen2\zeropoint - \fi - \parindent\zeropoint\relax - \leavevmode - \box2\relax - \hskip\dimen2 - \bgroup - \donestedlistattributes\c!textstyle\c!textcolor - {\let\\=\newlineinlist - \dontconvertfont - %\listparameter\c!textcommand{#4}}% - \limitatedlistentry{#4}}% - %\carryoverpar % new otherwise wrong linespacing - \egroup - \ifdim\wd4=\zeropoint\relax % \ifvoid4 - % \ifdim\!!widtha<\hsize \hfill\strut \fi % spoils align - \else - \nobreak\listfill - \box4\relax - \relax - \fi}% - \hss}}% new - \endgraf % new, else problems with nointerlinespace and prevdepth - \nointerlineskip % anders verkeerde spatiering bij multi-line - \endgraf - \allowbreak - \listparameter\c!after} - -% % example from the context list -% -% \setuphead [part] [page=right,placehead=yes] -% \setuplist [chapter] [alternative=d,before=\blank,after=\blank] -% \setuplist [part] [before=\blank,after=\blank] -% -% \starttext -% \startnarrower[2*right] \placecontent \stopnarrower -% \blank[4*big] -% \startsetups chapter -% \blank \startnarrower[3*middle] \placecontent[criterium=local] \stopnarrower -% \stopsetups -% \placelist[part][criterium=text,after=\setups{chapter}] -% -% \part{First part} \chapter{Chapter one} \chapter{Chapter two} -% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five} -% \part{Second part} \chapter{Chapter one} \chapter{Chapter two} -% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five} -% \part{Third part} \chapter{Chapter one} \chapter{Chapter two} -% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five} -% \stoptext - -% overrulen interactie kan sneller, bv door hulpconstanten -% te gebruiken en die te letten - -\def\dodofixdlistelementD#1#2#3#4#5#6% - {%\leftskip=\listparameter\c!margin - \ifvmode - \advance\leftskip\listparameter\c!margin% AANGEPAST - \fi - \bgroup - \ifvmode - \noindent\leavevmode % leavevmode ? ? ? - \fi - \doif{\listparameter\c!interaction}\v!text % not supported - {\setlistparameter\currentlist\c!interaction\v!sectionnumber}% - \doif{\listparameter\c!interaction}\v!all % not supported - {\setlistparameter\currentlist\c!interaction\v!sectionnumber}% - \def\makelistelement##1##2% - {\doifelse{\listparameter\c!interaction}{##1} - {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}% - \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}% - {\hbox{##2}}}% - \setbox4\hbox - {\doif{\listparameter\c!pagenumber}\v!yes - {\doifsomething{#5} - {\makelistelement\v!pagenumber - {\donestedlistattributes\c!pagestyle\c!pagecolor - {\listparameter\c!pagecommand{#5}}}}}}% - \doif{\listparameter\c!headnumber}\v!yes - {\donetrue - \doifnothing{#3}{\doifnothing{\listparameter\c!symbol}\donefalse}% - % == \doifnothing{#3\listparameter\c!symbol}\donefalse - \ifdone - \hbox - {\listparameter\c!left - \makelistelement\v!sectionnumber - {\donestedlistattributes\c!numberstyle\c!numbercolor - {\listparameter\c!numbercommand{\currentlistsymbol}}}% - \listparameter\c!right - \hskip.5em}% - \nobreak - \fi}% - \tolerance3500 % niet zomaar veranderen - \donestedlistattributes\c!textstyle\c!textcolor - {\let\\=\newlineinlist - \dontconvertfont - %\listparameter\c!textcommand{#4}}% - \limitatedlistentry{#4}}% - \ifvoid4\else - \nobreak - \hskip.75em\relax - \nobreak - \box4 - \fi - \dimen0=\listparameter\c!distance\relax - \ifdim\dimen0<1em\relax - \hskip1em\!!plus1em\!!minus.25em\relax - \else - \hskip\dimen0\!!plus.5\dimen0\!!minus.25\dimen0\relax - \fi - \egroup} - -\def\dodofixdlistelementE#1% - {\dodofixdlistelementEFG - {\setupinteraction[\c!strut=\v!no]} - {\localframed[\??li\currentlist][\c!depth=\!!zeropoint,\c!color=]} - {}} - -\def\dodofixdlistelementF#1% - {\dodofixdlistelementEFG - {} - {\dosetraggedhbox{\listparameter\c!align}\raggedbox} - {}} - -\def\dodofixdlistelementG#1% - {\dodofixdlistelementEFG - {} - \midaligned - {}} - -\def\dodofixdlistelementEFG#1#2#3#4#5#6#7#8% - {\noindent - \bgroup - \def\makelistelement##1##2% isolated by Wolfgang Schuster - {\doifelse{\listparameter\c!interaction}{##1} - {#2{##2}} - {\setbox0\hbox{#2{\showcontrastlocation\??ia{#8}{##2}}}% - \linklisttoelement{#4}{#7}{#8}{\box0}}}% - \makelistelement\v!no - {\let\\=\newlineinlist - #1% in case E nils the strut (still needed?) - \dosetlistattributes\c!style\c!color - \ignorespaces\dontconvertfont\setstrut - \begstrut - \limitatedlistentry{#6}% - \endstrut}% - \egroup - \par - \listparameter\c!inbetween} - -\def\listlength{\utilitylistlength} -\def\listwidth {\utilitylistwidth} -\def\listheight{\utilitylistheight} - -\def\utilitylistlength {0} -\def\utilitylistwidth {0pt} % no longer supported -\def\utilitylistheight {0pt} % no longer supported - -\def\dodeterminelistcharacteristics[#1][#2]% - {\begingroup - \dosetuplist[#1][#2]% - \edef\currentlist{\firststructureelementinlist{#1}}% - \the\everystructurelist - \analysestructurelist{#1}{\listparameter\c!criterium}{\listparameter\c!number}% - \xdef\utilitylistlength{\structurelistsize}% - \endgroup - \dosetlistmode} - -\def\determinelistcharacteristics - {\dodoubleempty\dodeterminelistcharacteristics} - -\def\combinedlistparameter#1{\csname\??ih\currentcombinedlist#1\endcsname} - -\def\setupcombinedlist - {\dodoubleargument\dosetupcombinedlist} - -\def\dosetupcombinedlist[#1][#2]% - {\getparameters[\??ih#1][#2]% - \edef\currentcombinedlist{#1}% - \normalexpanded{\noexpand\setuplist[\combinedlistparameter\c!list]}[#2]} - -\def\definecombinedlist - {\dotripleempty\dodefinecombinedlist} - -\def\dodefinecombinedlist[#1][#2][#3]% - {\getparameters - [\??ih#1] - [\c!criterium=\v!local,\c!number=0,\c!list={#2},#3]% - \setvalue{\e!setup#1\e!endsetup}{\dodoubleempty\dosetupcombinedlist[#1]}% - \setvalue{\e!place#1}{\dodoubleempty\doplacecombinedlist[#1]}% - \setvalue{\e!complete#1}{\dodoubleempty\docompletecombinedlist[#1]}} - -\def\placecombinedlist - {\dodoubleempty\doplacecombinedlist} - -\def\doplacecombinedlist[#1][#2]% we can move much of the analysis to lua - {\begingroup - % level is no longer supported - \def\currentcombinedlist{#1}% - \getparameters[\??ih#1][#2]% - \edef\combinedlist{\combinedlistparameter\c!list}% - \the\everystructurelist - \doif{\combinedlistparameter\c!coupling}\v!on{\startlistreferences{#1}}% - \dobeginoflist - \normalexpanded{\noexpand\dosetuplist[\combinedlist][#2]}% - \placestructurelist{\combinedlist}{\combinedlistparameter\c!criterium}{\combinedlistparameter\c!number}% - \doendoflist - \stoplistreferences - \endgroup - \dosetlistmode} - -\def\docompletecombinedlist[#1][#2]% - {\normalexpanded{\noexpand\systemsuppliedtitle[#1]{\noexpand\headtext{#1}}}% expansion due to v! vs french ! - \doplacecombinedlist[#1][#2]} - -% lists that have a number/title are kind of generic and can share code - -\installstructurelistprocessor{number+title} - {\dodolistelement - \currentlist - \structurelistlocation - \structurelistgenericnumber - \structurelistgenerictitle - \structurelistpagenumber - \structurelistrealpagenumber} - -\def\structurelistgenerictitle - {\ctxlua{structure.lists.title("\currentlist",\currentlistindex)}} - -\def\structurelistgenericnumber{\ctxlua{ - structure.lists.prefixednumber("\currentlist",\currentlistindex, { - prefix = "\listparameter\c!prefix", - separatorset = "\listparameter\c!prefixseparatorset", - conversionset = "\listparameter\c!prefixconversionset", - stopper = \!!bs\listparameter\c!prefixstopper\!!es, - set = "\listparameter\c!prefixset", - segments = "\listparameter\c!prefixsegments", - connector = \!!bs\listparameter\c!prefixconnector\!!es, - }, - { - separatorset = "\listparameter\c!numberseparatorset", - conversionset = "\listparameter\c!numberconversionset", - stopper = \!!bs\listparameter\c!numberstopper\!!es, - segments = "\listparameter\c!numbersegments", - } )}} - -% new and yet undocumented (used in cocoa qa), temporarily disabled in mkiv -% -% \setupremaininglistlength -% [left=\hss nog~,right=~ingangen] -% -% \resetremaininglistlength -% [section][settings] -% -% \placelist -% [section] -% [before=\showremaininglistlength] -% -% \dorecurse{100}{\section{hans}} -% -% \definesystemvariable {ll} % ListLength -% -% \def\setupremaininglistlength[#1]% -% {\getparameters[\??ll][#1]% -% \globallet\listlengthcounter\!!zerocount} -% -% \setupremaininglistlength -% [\c!left=\hss,\c!right=,\c!number=\v!yes, -% \c!before=\blank,\c!after=\page, -% \c!style=\v!smallnormal,\c!color=] -% -% \def\resetremaininglistlength -% {\dodoubleempty\doresetremaininglistlength} -% -% \def\doresetremaininglistlength[#1][#2]% -% {\determinelistcharacteristics[#1][#2]% -% \xdef\listlengthcounter{\number\utilitylistlength}} -% -% \def\showremaininglistlength -% {\bgroup -% \ifnum\listlengthcounter>\plusone -% \setbox\scratchbox\vbox -% {\@@llbefore\par\horizontalstrut\par\horizontalstrut\par\@@llafter}% -% \scratchdimen\pagetotal -% \advance\scratchdimen \ht\scratchbox -% \advance\scratchdimen \dp\scratchbox -% \ifdim\scratchdimen>\pagegoal -% \@@llbefore -% \nobreak\hbox to \hsize -% {\doifnot\@@llnumber\v!yes{\let\listlengthcounter\empty}% -% \doattributes\??ll\c!style\c!color{\@@llleft\listlengthcounter\@@llright}} -% \@@llafter -% \fi -% \fi -% \doglobal\decrement\listlengthcounter\relax -% \egroup} - -\protect \endinput diff --git a/tex/context/base/strc-mar.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..8dbbb232c --- /dev/null +++ b/tex/context/base/strc-mar.mkiv @@ -0,0 +1,493 @@ +%D \module +%D [ file=strc-mar, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Markings, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Markings} + +\registerctxluafile{strc-mar}{1.001} + +\unprotect + +%D Old stuff. + +\newtoks \listofmarks + +\let \getmarks \gobbleoneargument +\let \getallmarks \relax +\let \getsplitmarks \gobbleoneargument +\let \getallsplitmarks \relax + +%D \macros +%D {expandmarks} +%D +%D We can force expansion of marks with the following switch. + +% Synchronizing marks is a rather tricky and messy business. When +% setting a mark, a node is added to the list in order for to \TEX\ +% be able to figure out the 3 current marks when a page is made +% (last mark on previous page, first on current page, last on +% current page; in \LUATEX\ we might at one point have the first on +% the next page as well). + +% Resetting a mark is not easy. An empty one will not erase the last +% one on the previous page for instance. In \LUATEX\ we can clear a +% marks state register with \type {\clearmarks} but since this is an +% immediate operation it might have unwanted side effects when \TEX\ +% has collected several pages of text and finishing off these pages +% uses marks. + +% In \MKIV\ we provide a model that permits some control over the +% way marks are used. It is not entirely compatible with \MKII\ but +% in practice this is not a real problem. Quality has a price. + +% In fact we define multiple marks per visible mark and define +% additional ones on the fly. This has some price in terms of used +% mark registers but given the way that we fill marks in \MKIV\ +% their accumulated content is not really the issue. Also, +% periodically we cleanup any leftovers. + +\newif\ifexpandmarks \expandmarkstrue + +\def\marksomecs #1#2{\csname\string#1:m:\number#2\endcsname} +\def\markautocs #1{\csname\string#1:m:\number\csname\string#1:s\endcsname\endcsname} +\def\markmaincs #1{\csname\string#1:m\endcsname} +\def\markresetcs #1{\csname\string#1:r\endcsname} +\def\markstatecs #1{\csname\string#1:s\endcsname} +\def\markcurrentcs#1{\csname\string#1:c\endcsname} +\def\marktokscs #1{\csname\string#1:t\endcsname} + +\def\renewmarks#1% + {\ifx#1\relax + % \writestatus\m!systems{defining low level mark: \string#1}% + \newmarks#1% + \else + \clearmarks#1% + \fi} + +\def\definenewmark#1% + {\ifcsname\string#1:m\endcsname\else + \@EA\@EA\@EA\newcount \markstatecs #1\global\markstatecs#1\plusone + \@EA\@EA\@EA\renewmarks\markautocs #1% + \@EA\@EA\@EA\renewmarks\markmaincs #1% + \@EA\@EA\@EA\renewmarks\markresetcs #1% + \@EA\@EA\@EA\newtoks \marktokscs #1% + \@EA\@EA\@EA\let \markcurrentcs#1\empty + \listofmarks\expandafter{\the\listofmarks\checkmark#1}% + \fi} + +\long\def\setmark#1#2% marks expand + {\@EA\@EA\@EA\xdef \markcurrentcs#1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% + \marks\markautocs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level + \marks\markmaincs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level + \marks\markresetcs #1{\number\markstatecs#1}} + +\def\resetmark#1% + {\global\advance\markstatecs#1\plusone + \@EA\@EA\@EA\glet\markcurrentcs#1\empty + \@EA\@EA\@EA\renewmarks\markautocs#1% + \the\marktokscs#1\relax} + +\def\addmarkreset#1#2% + {\global\marktokscs#2\@EA{\the\marktokscs#2\resetmark#1}} + +% already there: \prependtoks \getallmarks \to \everybeforepagebody +% +% \def\getallmarks{\the\listofmarks} + +\let\checkmark\gobbleoneargument + +\prependtoks \clearmarkswhenemptypage \to \everybeforepagebody + +\def\clearmarkswhenemptypage + {\iffalse % check if page is empty + \clearallmarks + \fi} + +\def\clearallmarks + {\let\checkmark\clearmarkchain + \the\listofmarks + \let\checkmark\gobbleoneargument} + +\def\clearmarkchain#1% + {\@EA\@EA\@EA\clearmarks\markmaincs#1% + \@EA\@EA\@EA\clearmarks\markresetcs#1% + \@EA\doclearmarkchain\@EA{\number\csname\string#1:s\endcsname}#1% + \@EA\@EA\@EA\glet\markcurrentcs#1\empty + \global\markstatecs#1\plusone} + +\def\doclearmarkchain#1#2% + {\@EA\@EA\@EA\clearmarks\marksomecs#1{#2}% + \@EA\doclearmarkchain\@EA#1\@EA{\number\numexpr#2+\minusone}} + +% Fetching (expandable versions, so no intermediate counter): + +\def\currenttopmarknumber #1{\number0\topmarks \markresetcs#1} +\def\currentfirstmarknumber#1{\number0\firstmarks\markresetcs#1} +\def\currentbotmarknumber #1{\number0\botmarks \markresetcs#1} + +\def\checkedcurrentmarkrange#1{[\currenttopmarknumber#1,\currentfirstmarknumber#1,\currentbotmarknumber#1]} + +\def\checkedcurrentmarks{\markcurrentcs} % #1 shared current mark + +\let\currentsplittopmarknumber\currenttopmarknumber +\let\normalsplittopmarks \normaltopmarks + +\def\uncheckedautotopmark {\normaltopmarks \markautocs} % #1 +\def\uncheckedautofirstmark {\normalfirstmarks \markautocs} % #1 +\def\uncheckedautobotmark {\normalbotmarks \markautocs} % #1 +\def\uncheckedautosplittopmark {\normalsplittopmarks \markautocs} % #1 +\def\uncheckedautosplitfirstmark {\normalsplitfirstmarks\markautocs} % #1 +\def\uncheckedautosplitbotmark {\normalsplitbotmarks \markautocs} % #1 + +\def\uncheckedmaintopmark {\normaltopmarks \markmaincs} % #1 +\def\uncheckedmainfirstmark {\normalfirstmarks \markmaincs} % #1 +\def\uncheckedmainbotmark {\normalbotmarks \markmaincs} % #1 +\def\uncheckedmainsplittopmark {\normalsplittopmarks \markmaincs} % #1 +\def\uncheckedmainsplitfirstmark {\normalsplitfirstmarks\markmaincs} % #1 +\def\uncheckedmainsplitbotmark {\normalsplitbotmarks \markmaincs} % #1 + +\def\checkedpagetopmarks #1{\ifcase\currentbotmarknumber #1\else\normaltopmarks \marksomecs#1{\currentbotmarknumber #1}\fi} +\def\checkedpagefirstmarks #1{\ifcase\currentbotmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentbotmarknumber #1}\fi} +\def\checkedpagebotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi} +\def\checkedpagesplittopmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi} +\def\checkedpagesplitfirstmarks#1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitbotmarknumber #1}\fi} +\def\checkedpagesplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi} + +\def\checkedfulltopmarks #1{\ifcase\currenttopmarknumber #1\else\normaltopmarks \marksomecs#1{\currenttopmarknumber #1}\fi} +\def\checkedfullfirstmarks #1{\ifcase\currentfirstmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentfirstmarknumber #1}\fi} +\def\checkedfullbotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi} +\def\checkedfullsplittopmarks #1{\ifcase\currentsplittopmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplittopmarknumber #1}\fi} +\def\checkedfullsplitfirstmarks#1{\ifcase\currentsplitfirstmarknumber#1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitfirstmarknumber#1}\fi} +\def\checkedfullsplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi} + +% Interface macros: + +\def\getcurrentmark {\checkedcurrentmarks } +\def\gettopmark {\checkedfulltopmarks } +\def\getfirstmark {\checkedfullfirstmarks } +\def\getbotmark {\checkedfullbotmarks } +\def\getsplittopmark {\checkedfullsplittopmarks } +\def\getsplitfirstmark {\checkedfullsplitfirstmarks} +\def\getsplitbotmark {\checkedfullsplitbotmarks } + +\def\getbottommark {\getbotmark} +\def\getsplitbottommark{\getsplitbotmark} + +%D Some of these will go away (in the process of rewriting). + +\let \newmark \definenewmark +\let \newpersistentmark \newmarks +\let \normalsetmark \setmark +\let \rawnewmark \newmarks +\let \rawdefinemark \newmarks +\let \rawsetmark \normalmarks +\let \rawgettopmark \normaltopmarks +\let \rawgetfirstmark \normalfirstmarks +\let \rawgetbotmark \normalbotmarks +\let \rawgetsplitbotmark \normalsplitbotmarks +\let \rawgetsplitfirstmark \normalsplitfirstmarks +\let \rawgetsplittopmark \normalsplitfirstmarks + +\let \noninterferingmarks \relax % old color interference related hack + +%D Next comes the layer around the previous mechanism. +%D +%D Parameters + +\def\markingparameter #1#2{\csname\domarkingparameter{\??mk#1}#2\endcsname} +\def\domarkingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\@EA\domarkingparentparameter\csname#1\s!parent\endcsname#2\fi} +\def\domarkingparentparameter#1#2{\ifx#1\relax\s!empty\else\domarkingparameter#1#2\fi} +\def\markingcoupling #1{\ifcsname\??mk#1\c!coupling\endcsname\@EA\markingcoupling\csname\??mk#1\c!coupling\endcsname\else#1\fi} + +\let\mainmarking\markingcoupling % compatibility + +\def\doifelsemarking#1% + {\ifcsname\??mk#1\c!coupling\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\dowithmarkcommandone#1#2% \command {mark} + {\expandafter#1\csname\??mk:\markingcoupling{#2}\endcsname} + +\def\dowithmarkcommandtwo#1#2#3% \command {mark} {mark} + {\expandafter#1\csname\??mk:\markingcoupling{#2}\expandafter\endcsname\csname\??mk:\markingcoupling{#3}\endcsname} + +\def\setupmarking + {\dodoubleargument\dosetupmarking} + +\def\dosetupmarking[#1][#2]% + {\def\docommand##1{\getparameters[\??mk##1][#2]}% + \processcommalist[#1]\docommand} + +%D The filtercommand key is used to hook in a filtering command. Users are +%D adviced not to misuse this key. + +\getparameters + [\??mk] + [\c!expansion=\v!no, % saves a macro + \c!separator={\space\emdash\space}, + \c!limittext=\@@kolimittext, + \c!filtercommand=\firstofoneargument, + \c!state=\v!start] + +\let\alldefinedmarks\empty + +\def\definemarking + {\dodoubleempty\dodefinemarking} + +\def\dodefinemarking[#1][#2]% + {\doifelsenothing{#2}\donormaldefinemarking\docloneddefinemarking[#1][#2]} + +\def\donormaldefinemarking[#1][#2]% #2 empty + {\ifcsname\??mk#1\s!parent\endcsname + % already defined + \else + \letgvalue{\??mk#1\s!parent}\??mk + \dowithmarkcommandone\newmark{#1}% + \doglobal\addtocommalist{#2}\alldefinedmarks + \ifproductionrun\showmessage\m!systems{13}{#1,[#1]}\fi + \fi} + +\def\docloneddefinemarking[#1][#2]% + {\ifcsname\??mk#1\s!parent\endcsname \else \ifcsname\??mk#2\s!parent\endcsname + \doifnot{#1}{#2}% + {\setxvalue{\??mk#1\s!parent}{\??mk#2}% + \setxvalue{\??mk#1\c!coupling}{#2}% + \ifproductionrun\showmessage\m!systems{13}{#1,[#2]}\fi}% + \fi \fi} + +\def\decouplemarking[#1]% + {\letbeundefined{\??mk#1\c!coupling}} + +\def\couplemarking[#1]#2[#3]% couple 1 to 2 (this macro is not really needed) + {\setvalue{\??mk#1\c!coupling}{#3}} + +\def\relatemarking[#1]#2[#3]% define 1 as child of 2 + {\dowithmarkcommandtwo\addmarkreset{#1}{#3}} + +\def\definerawmarking[#1]% + {\dododefinemarking[#1][#1]% + \getgparameters[\??mk#1][\c!limittext=]} % global ! + +% \decouplemarking[#1]% % no coupling with sections + +\def\fastresetmarker#1% + {\ifcsname\??mk#1\s!parent\endcsname + \dowithmarkcommandone\resetmark{#1}% + \fi} + +\def\fastresetmarkerlist[#1]% + {\normalexpanded{\noexpand\rawprocesscommalist[#1]}\fastresetmarker} + +\def\resetmarking + {\dosingleargument\doresetmarking} + +\def\doresetmarking[#1]% + {\processcommalist[#1]\fastresetmarker} + +%D Used elsewhere: + +\let\nomarking\empty + +%D Basic fetching: + +\letvalue{\??mk::\??mk::\v!previous}\firstoffourarguments +\letvalue{\??mk::\??mk::\v!first }\secondoffourarguments +\letvalue{\??mk::\??mk::\v!last }\thirdoffourarguments +\letvalue{\??mk::\??mk::\v!current }\fourthoffourarguments + +\letvalue{\??mk\??mk\v!previous}\gettopmark +\letvalue{\??mk\??mk\v!first }\getfirstmark +\letvalue{\??mk\??mk\v!last }\getbotmark +\letvalue{\??mk\??mk\v!current }\getcurrentmark + +\letvalue{\??mk\??mk\v!column:\v!first}\getsplitfirstmark +\letvalue{\??mk\??mk\v!column:\v!last }\getsplitbottommark + +\def\fetchmark[#1]#2[#3]% % expandable / never use \unexpanded + {\ifcsname\??mk::#1\endcsname % saved mark + \markingparameter{#1}\c!filtercommand{\csname\??mk::\??mk::#3\@EA\@EA\@EA\endcsname\csname\??mk::#1\endcsname}% + \else\ifcsname\??mk#1\s!parent\endcsname % real mark + \markingparameter{#1}\c!filtercommand{\expandafter\dowithmarkcommandone\csname\??mk\??mk#3\endcsname{#1}}% + \fi\fi} + +\def\fetchtwomarks[#1]% + {\dofetchtwomarks[#1][#1]} + +\def\fetchallmarks[#1]% + {\dofetchallmarks[#1][#1]} + +\def\dofetchtwomarks[#1][#2]% class class:tag + {\doifsomething{\fetchmark[#2][\v!first]} + {\fetchmark[#2][\v!first]% + \doifsomething{\fetchmark[#2][\v!last]} + {\doifnot{\fetchmark[#2][\v!first]}{\fetchmark[#2][\v!last]} + {\markingparameter{#1}\c!separator\fetchmark[#2][\v!last]}}}} + +\def\dofetchallmarks[#1][#2]% + {\doifsomething{\fetchmark[#2][\v!first]} + {\doifsomething{\fetchmark[#2][\v!previous]} + {\doifnot{\fetchmark[#2][\v!previous]}{\fetchmark[#2][\v!first]} + {\fetchmark[#2][\v!previous]\markingparameter{#1}\c!separator}}}% + \fetchtwomarks[#1][#2]} + +% \newtoks \everymarking + +% \def\Interesting{\doifmodeelse{*\v!marking}{Interesting}{Boring}} +% \setupheadertexts[chapter] +% \starttext +% \chapter{This Is \Interesting} +% \stoptext + +\def\markingnomarking#1{\splitsequence{\markingparameter{#1}\c!limittext}} % #2 + +\def\dogetmarking[#1][#2][#3]% + {\doif{\markingparameter{#1}\c!state}\v!start + {\bgroup + \setsystemmode\v!marking + \the\everymarking + \def\nomarking{\markingnomarking{#1}}% just for good old times, might disappear + \ifthirdargument + \dodogetmarking{#3}{#1}{#1:#2}{#3}% + \else + \dodogetmarking{#2}{#1}{#1}{#2}% + \fi + \egroup}} + +\def\dodogetmarking#1#2#3#4% to be made faster + {\processaction % slow + [#1] + [ \v!both=>{\dofetchtwomarks[#2][#3]}, + \v!all=>{\dofetchallmarks[#2][#3]}, + \s!default=>{\fetchmark[#3][\v!first]}, + \s!unknown=>{\fetchmark[#3][#4]}]} + +\def\nogetmarking[#1][#2][#3]% + {} + +\unexpanded\def\getmarking + {\dotripleargument\dogetmarking} + +\let\setsomemark\setmark + +\def\setmarking + {\dosingleargument\dosetmarking} + +\def\dosetmarking[#1]#2% + {\ifcsname\??mk#1\s!parent\endcsname + \begingroup + \doifelse{\markingparameter{#1}\c!expansion}\v!yes\expandmarkstrue\expandmarksfalse + \dowithmarkcommandone\setsomemark{#1}{#2}% + \endgroup + \fi} + +\let\marking\setmarking + +% to be adapted for mkiv: +% +% this version can be used when a page is built up in steps without +% feedback of the otr'd list to the mvl (i.e.\ a page made of pages, +% as in column sets where content is buffered) + +% reset at begin +% preset before page +% bubble in column +% refresh at end + +% marks is a kind of toks, so maybe we need a low level \the\marks +% +% use \normalunexpanded here + +\def\refreshsavedmark[#1][#2]% mark tag (packing saves many hash entries) + {\setxvalue{\??mk::#1:#2}% + {{\@EA\ifx\csname\??mk::#1:pp\endcsname\relax + % empty + \else + \csname\??mk::#1:pp\endcsname + \fi}% + {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax + \fetchmark[#1][\v!first]% + \else + \csname\??mk::#1:ff\endcsname + \fi}% + {\fetchmark[#1][\v!last]}% + {\fetchmark[#1][\v!current]}}% + \setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!first]}% + \letgvalue{\??mk::#1:ff}\relax + } + +\def\bubblesavedmark[#1][#2]% no packing (not now, maybe make a six-pack later) + {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax + \setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}% + \fi} + +\def\resetsavedmark[#1][#2]% mark tag + {\doifelsenothing{\fetchmark[#1][\v!previous]} + {\letgvalue{\??mk::#1:pp}\relax} + {\setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!previous]}}% + \doifelsenothing{\fetchmark[#1][\v!first]} + {\letgvalue{\??mk::#1:ff}\relax} + {\setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}}% + \letgvalue{\??mk::#1:#2}\emptysavedmark} + +\def\presetsavedmark[#1][#2]% mark tag + {\letgvalue{\??mk::#1:#2}\emptysavedmark} + +\def\emptysavedmark{{}{}{}{}} + +% new (can be used in column sets) +% +% \getsavedmarking[M][previous] +% \getsavedmarking[M][first] +% \getsavedmarking[M][last] + +\def\getsavedmarking + {\dodoubleargument\dogetsavedmarking} + +\def\dogetsavedmarking[#1][#2]% + {\doifelse{#2}\v!previous + {\getmarking[#1][1][\v!previous]} + {\doifelse{#2}\v!first + {\getmarking[#1][1][\v!first]} + {\getmarking[#1][\v!last]}}} + +%D And then \unknown\ we had a chaptertitle packaged in a +%D makeup environment. And we don't want to loose marks there! + +\newbox\collectedmarks + +\def\flushmarks % use with care to avoid empty pages + {\ifvoid\collectedmarks\else\unhbox\collectedmarks\fi} + +\def\postponemarks + {\let\setsomemark\postponemark} + +\def\postponemark#1#2% + {\global\setbox\collectedmarks\hbox{\unhbox\collectedmarks\setmark{#1}{#2}}} + +\protect \endinput + +% todo: make it work in balancing +% +% \definemarking[vers][] +% \setupheadertexts +% [\doiftext{\getmarking[vers][first]} +% {\doiftextelse{\getmarking[vers][column:last]} +% {\getmarking[vers][first] -- \getmarking[vers][column:last]} +% {\getmarking[vers][first]}}] +% \starttext +% \startcolumns[n=2,balance=no] +% \dorecurse{10}{\normalexpanded{\noexpand\marking[vers]{\recurselevel}} \recurselevel:\dorecurse{4}{\input ward } \endgraf} +% \stopcolumns +% \stoptext diff --git a/tex/context/base/strc-mar.tex b/tex/context/base/strc-mar.tex deleted file mode 100644 index 8dbbb232c..000000000 --- a/tex/context/base/strc-mar.tex +++ /dev/null @@ -1,493 +0,0 @@ -%D \module -%D [ file=strc-mar, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Markings, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Markings} - -\registerctxluafile{strc-mar}{1.001} - -\unprotect - -%D Old stuff. - -\newtoks \listofmarks - -\let \getmarks \gobbleoneargument -\let \getallmarks \relax -\let \getsplitmarks \gobbleoneargument -\let \getallsplitmarks \relax - -%D \macros -%D {expandmarks} -%D -%D We can force expansion of marks with the following switch. - -% Synchronizing marks is a rather tricky and messy business. When -% setting a mark, a node is added to the list in order for to \TEX\ -% be able to figure out the 3 current marks when a page is made -% (last mark on previous page, first on current page, last on -% current page; in \LUATEX\ we might at one point have the first on -% the next page as well). - -% Resetting a mark is not easy. An empty one will not erase the last -% one on the previous page for instance. In \LUATEX\ we can clear a -% marks state register with \type {\clearmarks} but since this is an -% immediate operation it might have unwanted side effects when \TEX\ -% has collected several pages of text and finishing off these pages -% uses marks. - -% In \MKIV\ we provide a model that permits some control over the -% way marks are used. It is not entirely compatible with \MKII\ but -% in practice this is not a real problem. Quality has a price. - -% In fact we define multiple marks per visible mark and define -% additional ones on the fly. This has some price in terms of used -% mark registers but given the way that we fill marks in \MKIV\ -% their accumulated content is not really the issue. Also, -% periodically we cleanup any leftovers. - -\newif\ifexpandmarks \expandmarkstrue - -\def\marksomecs #1#2{\csname\string#1:m:\number#2\endcsname} -\def\markautocs #1{\csname\string#1:m:\number\csname\string#1:s\endcsname\endcsname} -\def\markmaincs #1{\csname\string#1:m\endcsname} -\def\markresetcs #1{\csname\string#1:r\endcsname} -\def\markstatecs #1{\csname\string#1:s\endcsname} -\def\markcurrentcs#1{\csname\string#1:c\endcsname} -\def\marktokscs #1{\csname\string#1:t\endcsname} - -\def\renewmarks#1% - {\ifx#1\relax - % \writestatus\m!systems{defining low level mark: \string#1}% - \newmarks#1% - \else - \clearmarks#1% - \fi} - -\def\definenewmark#1% - {\ifcsname\string#1:m\endcsname\else - \@EA\@EA\@EA\newcount \markstatecs #1\global\markstatecs#1\plusone - \@EA\@EA\@EA\renewmarks\markautocs #1% - \@EA\@EA\@EA\renewmarks\markmaincs #1% - \@EA\@EA\@EA\renewmarks\markresetcs #1% - \@EA\@EA\@EA\newtoks \marktokscs #1% - \@EA\@EA\@EA\let \markcurrentcs#1\empty - \listofmarks\expandafter{\the\listofmarks\checkmark#1}% - \fi} - -\long\def\setmark#1#2% marks expand - {\@EA\@EA\@EA\xdef \markcurrentcs#1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% - \marks\markautocs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level - \marks\markmaincs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level - \marks\markresetcs #1{\number\markstatecs#1}} - -\def\resetmark#1% - {\global\advance\markstatecs#1\plusone - \@EA\@EA\@EA\glet\markcurrentcs#1\empty - \@EA\@EA\@EA\renewmarks\markautocs#1% - \the\marktokscs#1\relax} - -\def\addmarkreset#1#2% - {\global\marktokscs#2\@EA{\the\marktokscs#2\resetmark#1}} - -% already there: \prependtoks \getallmarks \to \everybeforepagebody -% -% \def\getallmarks{\the\listofmarks} - -\let\checkmark\gobbleoneargument - -\prependtoks \clearmarkswhenemptypage \to \everybeforepagebody - -\def\clearmarkswhenemptypage - {\iffalse % check if page is empty - \clearallmarks - \fi} - -\def\clearallmarks - {\let\checkmark\clearmarkchain - \the\listofmarks - \let\checkmark\gobbleoneargument} - -\def\clearmarkchain#1% - {\@EA\@EA\@EA\clearmarks\markmaincs#1% - \@EA\@EA\@EA\clearmarks\markresetcs#1% - \@EA\doclearmarkchain\@EA{\number\csname\string#1:s\endcsname}#1% - \@EA\@EA\@EA\glet\markcurrentcs#1\empty - \global\markstatecs#1\plusone} - -\def\doclearmarkchain#1#2% - {\@EA\@EA\@EA\clearmarks\marksomecs#1{#2}% - \@EA\doclearmarkchain\@EA#1\@EA{\number\numexpr#2+\minusone}} - -% Fetching (expandable versions, so no intermediate counter): - -\def\currenttopmarknumber #1{\number0\topmarks \markresetcs#1} -\def\currentfirstmarknumber#1{\number0\firstmarks\markresetcs#1} -\def\currentbotmarknumber #1{\number0\botmarks \markresetcs#1} - -\def\checkedcurrentmarkrange#1{[\currenttopmarknumber#1,\currentfirstmarknumber#1,\currentbotmarknumber#1]} - -\def\checkedcurrentmarks{\markcurrentcs} % #1 shared current mark - -\let\currentsplittopmarknumber\currenttopmarknumber -\let\normalsplittopmarks \normaltopmarks - -\def\uncheckedautotopmark {\normaltopmarks \markautocs} % #1 -\def\uncheckedautofirstmark {\normalfirstmarks \markautocs} % #1 -\def\uncheckedautobotmark {\normalbotmarks \markautocs} % #1 -\def\uncheckedautosplittopmark {\normalsplittopmarks \markautocs} % #1 -\def\uncheckedautosplitfirstmark {\normalsplitfirstmarks\markautocs} % #1 -\def\uncheckedautosplitbotmark {\normalsplitbotmarks \markautocs} % #1 - -\def\uncheckedmaintopmark {\normaltopmarks \markmaincs} % #1 -\def\uncheckedmainfirstmark {\normalfirstmarks \markmaincs} % #1 -\def\uncheckedmainbotmark {\normalbotmarks \markmaincs} % #1 -\def\uncheckedmainsplittopmark {\normalsplittopmarks \markmaincs} % #1 -\def\uncheckedmainsplitfirstmark {\normalsplitfirstmarks\markmaincs} % #1 -\def\uncheckedmainsplitbotmark {\normalsplitbotmarks \markmaincs} % #1 - -\def\checkedpagetopmarks #1{\ifcase\currentbotmarknumber #1\else\normaltopmarks \marksomecs#1{\currentbotmarknumber #1}\fi} -\def\checkedpagefirstmarks #1{\ifcase\currentbotmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentbotmarknumber #1}\fi} -\def\checkedpagebotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi} -\def\checkedpagesplittopmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi} -\def\checkedpagesplitfirstmarks#1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitbotmarknumber #1}\fi} -\def\checkedpagesplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi} - -\def\checkedfulltopmarks #1{\ifcase\currenttopmarknumber #1\else\normaltopmarks \marksomecs#1{\currenttopmarknumber #1}\fi} -\def\checkedfullfirstmarks #1{\ifcase\currentfirstmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentfirstmarknumber #1}\fi} -\def\checkedfullbotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi} -\def\checkedfullsplittopmarks #1{\ifcase\currentsplittopmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplittopmarknumber #1}\fi} -\def\checkedfullsplitfirstmarks#1{\ifcase\currentsplitfirstmarknumber#1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitfirstmarknumber#1}\fi} -\def\checkedfullsplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi} - -% Interface macros: - -\def\getcurrentmark {\checkedcurrentmarks } -\def\gettopmark {\checkedfulltopmarks } -\def\getfirstmark {\checkedfullfirstmarks } -\def\getbotmark {\checkedfullbotmarks } -\def\getsplittopmark {\checkedfullsplittopmarks } -\def\getsplitfirstmark {\checkedfullsplitfirstmarks} -\def\getsplitbotmark {\checkedfullsplitbotmarks } - -\def\getbottommark {\getbotmark} -\def\getsplitbottommark{\getsplitbotmark} - -%D Some of these will go away (in the process of rewriting). - -\let \newmark \definenewmark -\let \newpersistentmark \newmarks -\let \normalsetmark \setmark -\let \rawnewmark \newmarks -\let \rawdefinemark \newmarks -\let \rawsetmark \normalmarks -\let \rawgettopmark \normaltopmarks -\let \rawgetfirstmark \normalfirstmarks -\let \rawgetbotmark \normalbotmarks -\let \rawgetsplitbotmark \normalsplitbotmarks -\let \rawgetsplitfirstmark \normalsplitfirstmarks -\let \rawgetsplittopmark \normalsplitfirstmarks - -\let \noninterferingmarks \relax % old color interference related hack - -%D Next comes the layer around the previous mechanism. -%D -%D Parameters - -\def\markingparameter #1#2{\csname\domarkingparameter{\??mk#1}#2\endcsname} -\def\domarkingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\@EA\domarkingparentparameter\csname#1\s!parent\endcsname#2\fi} -\def\domarkingparentparameter#1#2{\ifx#1\relax\s!empty\else\domarkingparameter#1#2\fi} -\def\markingcoupling #1{\ifcsname\??mk#1\c!coupling\endcsname\@EA\markingcoupling\csname\??mk#1\c!coupling\endcsname\else#1\fi} - -\let\mainmarking\markingcoupling % compatibility - -\def\doifelsemarking#1% - {\ifcsname\??mk#1\c!coupling\endcsname - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\dowithmarkcommandone#1#2% \command {mark} - {\expandafter#1\csname\??mk:\markingcoupling{#2}\endcsname} - -\def\dowithmarkcommandtwo#1#2#3% \command {mark} {mark} - {\expandafter#1\csname\??mk:\markingcoupling{#2}\expandafter\endcsname\csname\??mk:\markingcoupling{#3}\endcsname} - -\def\setupmarking - {\dodoubleargument\dosetupmarking} - -\def\dosetupmarking[#1][#2]% - {\def\docommand##1{\getparameters[\??mk##1][#2]}% - \processcommalist[#1]\docommand} - -%D The filtercommand key is used to hook in a filtering command. Users are -%D adviced not to misuse this key. - -\getparameters - [\??mk] - [\c!expansion=\v!no, % saves a macro - \c!separator={\space\emdash\space}, - \c!limittext=\@@kolimittext, - \c!filtercommand=\firstofoneargument, - \c!state=\v!start] - -\let\alldefinedmarks\empty - -\def\definemarking - {\dodoubleempty\dodefinemarking} - -\def\dodefinemarking[#1][#2]% - {\doifelsenothing{#2}\donormaldefinemarking\docloneddefinemarking[#1][#2]} - -\def\donormaldefinemarking[#1][#2]% #2 empty - {\ifcsname\??mk#1\s!parent\endcsname - % already defined - \else - \letgvalue{\??mk#1\s!parent}\??mk - \dowithmarkcommandone\newmark{#1}% - \doglobal\addtocommalist{#2}\alldefinedmarks - \ifproductionrun\showmessage\m!systems{13}{#1,[#1]}\fi - \fi} - -\def\docloneddefinemarking[#1][#2]% - {\ifcsname\??mk#1\s!parent\endcsname \else \ifcsname\??mk#2\s!parent\endcsname - \doifnot{#1}{#2}% - {\setxvalue{\??mk#1\s!parent}{\??mk#2}% - \setxvalue{\??mk#1\c!coupling}{#2}% - \ifproductionrun\showmessage\m!systems{13}{#1,[#2]}\fi}% - \fi \fi} - -\def\decouplemarking[#1]% - {\letbeundefined{\??mk#1\c!coupling}} - -\def\couplemarking[#1]#2[#3]% couple 1 to 2 (this macro is not really needed) - {\setvalue{\??mk#1\c!coupling}{#3}} - -\def\relatemarking[#1]#2[#3]% define 1 as child of 2 - {\dowithmarkcommandtwo\addmarkreset{#1}{#3}} - -\def\definerawmarking[#1]% - {\dododefinemarking[#1][#1]% - \getgparameters[\??mk#1][\c!limittext=]} % global ! - -% \decouplemarking[#1]% % no coupling with sections - -\def\fastresetmarker#1% - {\ifcsname\??mk#1\s!parent\endcsname - \dowithmarkcommandone\resetmark{#1}% - \fi} - -\def\fastresetmarkerlist[#1]% - {\normalexpanded{\noexpand\rawprocesscommalist[#1]}\fastresetmarker} - -\def\resetmarking - {\dosingleargument\doresetmarking} - -\def\doresetmarking[#1]% - {\processcommalist[#1]\fastresetmarker} - -%D Used elsewhere: - -\let\nomarking\empty - -%D Basic fetching: - -\letvalue{\??mk::\??mk::\v!previous}\firstoffourarguments -\letvalue{\??mk::\??mk::\v!first }\secondoffourarguments -\letvalue{\??mk::\??mk::\v!last }\thirdoffourarguments -\letvalue{\??mk::\??mk::\v!current }\fourthoffourarguments - -\letvalue{\??mk\??mk\v!previous}\gettopmark -\letvalue{\??mk\??mk\v!first }\getfirstmark -\letvalue{\??mk\??mk\v!last }\getbotmark -\letvalue{\??mk\??mk\v!current }\getcurrentmark - -\letvalue{\??mk\??mk\v!column:\v!first}\getsplitfirstmark -\letvalue{\??mk\??mk\v!column:\v!last }\getsplitbottommark - -\def\fetchmark[#1]#2[#3]% % expandable / never use \unexpanded - {\ifcsname\??mk::#1\endcsname % saved mark - \markingparameter{#1}\c!filtercommand{\csname\??mk::\??mk::#3\@EA\@EA\@EA\endcsname\csname\??mk::#1\endcsname}% - \else\ifcsname\??mk#1\s!parent\endcsname % real mark - \markingparameter{#1}\c!filtercommand{\expandafter\dowithmarkcommandone\csname\??mk\??mk#3\endcsname{#1}}% - \fi\fi} - -\def\fetchtwomarks[#1]% - {\dofetchtwomarks[#1][#1]} - -\def\fetchallmarks[#1]% - {\dofetchallmarks[#1][#1]} - -\def\dofetchtwomarks[#1][#2]% class class:tag - {\doifsomething{\fetchmark[#2][\v!first]} - {\fetchmark[#2][\v!first]% - \doifsomething{\fetchmark[#2][\v!last]} - {\doifnot{\fetchmark[#2][\v!first]}{\fetchmark[#2][\v!last]} - {\markingparameter{#1}\c!separator\fetchmark[#2][\v!last]}}}} - -\def\dofetchallmarks[#1][#2]% - {\doifsomething{\fetchmark[#2][\v!first]} - {\doifsomething{\fetchmark[#2][\v!previous]} - {\doifnot{\fetchmark[#2][\v!previous]}{\fetchmark[#2][\v!first]} - {\fetchmark[#2][\v!previous]\markingparameter{#1}\c!separator}}}% - \fetchtwomarks[#1][#2]} - -% \newtoks \everymarking - -% \def\Interesting{\doifmodeelse{*\v!marking}{Interesting}{Boring}} -% \setupheadertexts[chapter] -% \starttext -% \chapter{This Is \Interesting} -% \stoptext - -\def\markingnomarking#1{\splitsequence{\markingparameter{#1}\c!limittext}} % #2 - -\def\dogetmarking[#1][#2][#3]% - {\doif{\markingparameter{#1}\c!state}\v!start - {\bgroup - \setsystemmode\v!marking - \the\everymarking - \def\nomarking{\markingnomarking{#1}}% just for good old times, might disappear - \ifthirdargument - \dodogetmarking{#3}{#1}{#1:#2}{#3}% - \else - \dodogetmarking{#2}{#1}{#1}{#2}% - \fi - \egroup}} - -\def\dodogetmarking#1#2#3#4% to be made faster - {\processaction % slow - [#1] - [ \v!both=>{\dofetchtwomarks[#2][#3]}, - \v!all=>{\dofetchallmarks[#2][#3]}, - \s!default=>{\fetchmark[#3][\v!first]}, - \s!unknown=>{\fetchmark[#3][#4]}]} - -\def\nogetmarking[#1][#2][#3]% - {} - -\unexpanded\def\getmarking - {\dotripleargument\dogetmarking} - -\let\setsomemark\setmark - -\def\setmarking - {\dosingleargument\dosetmarking} - -\def\dosetmarking[#1]#2% - {\ifcsname\??mk#1\s!parent\endcsname - \begingroup - \doifelse{\markingparameter{#1}\c!expansion}\v!yes\expandmarkstrue\expandmarksfalse - \dowithmarkcommandone\setsomemark{#1}{#2}% - \endgroup - \fi} - -\let\marking\setmarking - -% to be adapted for mkiv: -% -% this version can be used when a page is built up in steps without -% feedback of the otr'd list to the mvl (i.e.\ a page made of pages, -% as in column sets where content is buffered) - -% reset at begin -% preset before page -% bubble in column -% refresh at end - -% marks is a kind of toks, so maybe we need a low level \the\marks -% -% use \normalunexpanded here - -\def\refreshsavedmark[#1][#2]% mark tag (packing saves many hash entries) - {\setxvalue{\??mk::#1:#2}% - {{\@EA\ifx\csname\??mk::#1:pp\endcsname\relax - % empty - \else - \csname\??mk::#1:pp\endcsname - \fi}% - {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax - \fetchmark[#1][\v!first]% - \else - \csname\??mk::#1:ff\endcsname - \fi}% - {\fetchmark[#1][\v!last]}% - {\fetchmark[#1][\v!current]}}% - \setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!first]}% - \letgvalue{\??mk::#1:ff}\relax - } - -\def\bubblesavedmark[#1][#2]% no packing (not now, maybe make a six-pack later) - {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax - \setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}% - \fi} - -\def\resetsavedmark[#1][#2]% mark tag - {\doifelsenothing{\fetchmark[#1][\v!previous]} - {\letgvalue{\??mk::#1:pp}\relax} - {\setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!previous]}}% - \doifelsenothing{\fetchmark[#1][\v!first]} - {\letgvalue{\??mk::#1:ff}\relax} - {\setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}}% - \letgvalue{\??mk::#1:#2}\emptysavedmark} - -\def\presetsavedmark[#1][#2]% mark tag - {\letgvalue{\??mk::#1:#2}\emptysavedmark} - -\def\emptysavedmark{{}{}{}{}} - -% new (can be used in column sets) -% -% \getsavedmarking[M][previous] -% \getsavedmarking[M][first] -% \getsavedmarking[M][last] - -\def\getsavedmarking - {\dodoubleargument\dogetsavedmarking} - -\def\dogetsavedmarking[#1][#2]% - {\doifelse{#2}\v!previous - {\getmarking[#1][1][\v!previous]} - {\doifelse{#2}\v!first - {\getmarking[#1][1][\v!first]} - {\getmarking[#1][\v!last]}}} - -%D And then \unknown\ we had a chaptertitle packaged in a -%D makeup environment. And we don't want to loose marks there! - -\newbox\collectedmarks - -\def\flushmarks % use with care to avoid empty pages - {\ifvoid\collectedmarks\else\unhbox\collectedmarks\fi} - -\def\postponemarks - {\let\setsomemark\postponemark} - -\def\postponemark#1#2% - {\global\setbox\collectedmarks\hbox{\unhbox\collectedmarks\setmark{#1}{#2}}} - -\protect \endinput - -% todo: make it work in balancing -% -% \definemarking[vers][] -% \setupheadertexts -% [\doiftext{\getmarking[vers][first]} -% {\doiftextelse{\getmarking[vers][column:last]} -% {\getmarking[vers][first] -- \getmarking[vers][column:last]} -% {\getmarking[vers][first]}}] -% \starttext -% \startcolumns[n=2,balance=no] -% \dorecurse{10}{\normalexpanded{\noexpand\marking[vers]{\recurselevel}} \recurselevel:\dorecurse{4}{\input ward } \endgraf} -% \stopcolumns -% \stoptext diff --git a/tex/context/base/strc-mat.mkii b/tex/context/base/strc-mat.mkii new file mode 100644 index 000000000..342f3f3fb --- /dev/null +++ b/tex/context/base/strc-mat.mkii @@ -0,0 +1,2923 @@ +%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 + \prevdepth-\maxdimen % texbook pagina 79-80 + % otherwise problems at the top of a page, don't remove: + \verticalstrut + \vskip-\struttotal + \vskip-\baselineskip + \fi + \fi + $$\setdisplaydimensions + \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..482426b48 --- /dev/null +++ b/tex/context/base/strc-mat.mkiv @@ -0,0 +1,933 @@ +%D \module +%D [ file=strc-mat, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Math Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Math Numbering} + +\registerctxluafile{strc-mat}{1.001} + +\unprotect + +\definestructureconversionset[\v!formula][number,characters] + +\setupformulas + [%\c!way=\@@nrway, + %\c!blockway=, + %\c!sectionnumber=\@@nrsectionnumber, + %\c!conversion=\v!numbers, + \c!location=\v!right, + \c!left=(, + \c!right=), + %\c!numberstyle=, + %\c!numbercolor=, + %\c!numbercommand=, + \c!spacebefore=\v!big, + \c!spaceafter=\formulaparameter\c!spacebefore, + \c!leftmargin=\!!zeropoint, + \c!rightmargin=\!!zeropoint, + %\c!margin=, + \c!indentnext=\v!no, + \c!alternative=\s!default, + %\c!align=, + \c!strut=\v!no, + %\c!separator=\@@koseparator, + %\c!grid=, + \c!distance=1em] + +\definestructurecounter + [\v!formula] + +\setupstructurecounter + [\v!formula] + [\c!numberconversionset=\v!formula] + +\def\storecurrentformulanumber#1#2#3% ref, todo:str, \sync % todo: title etc (like float) + {\dostructurecountercomponent + {formula}% + \getfloatparameters + \formulaparameter + \detokenizedformulaparameter + \relax + \relax + \relax + [\c!name=\currentformula,\s!counter=\currentformula,% + \s!hascaption=\v!yes,\s!hasnumber=\v!yes,\s!hastitle=\v!yes,% + \c!reference=#1,\c!title=,\c!bookmark=]% + [#2]% + \globallet\currentformulanumber\laststructurecounternumber + \globallet#3\laststructurecountersynchronize} + +\def\thecurrentformulanumber + {%\ifnoformulacaption \else \ifnoformulanumber \else + \labeltexts\currentformula{\convertedstructurecounter[formula]}% ! ! todo: use a lua call instead + }%\fi \fi} + +\def\placecurrentformulanumber + {\currentformulassynchronize + \currentformulasynchronize + \currentsubformulasynchronize + \thecurrentformulanumber} %\convertedstructurecounter[\v!formula]\relax} + +\def\doformulareference#1#2% + {\doifsomething{#1}{\doifnotinset{#1}{+,-}{\rawreference\s!for{#1}{#2}}}} + +\def\doformulanumber + {\dotripleempty\dodoformulanumber} + +\def\dodoformulanumber[#1][#2][#3]% + {\doquadruplegroupempty\dododoformulanumber{#1}{#2}{#3}} + +\let\subformulasreference\empty % temp hack + +\let\currentformulasynchronize \relax +\let\currentformulassynchronize\relax + +\def\dododoformulanumber#1#2#3#4% (#1,#2)=outer(ref,sub) (#3,#4)=inner(ref,sub) + {\hbox\bgroup + \ifconditional\handleformulanumber + \ifconditional\incrementformulanumber + \ifconditional\insidesubformulas + \incrementsubstructurecounter[\v!formula][2]% + \else + \incrementstructurecounter[\v!formula]% + \fi + \fi + % + % main counter + \setbox0\hbox{\ignorespaces#2\unskip}% + \ifdim\wd0>\zeropoint + \setsubstructurecounterown[\v!formula][2]{#2}% \detokenize? + \fi + \edef\currentformulareference{#1}% + \ifx\currentformulareference\empty + \glet\currentformulasynchronize\relax + \else + \storecurrentformulanumber\currentformulareference\empty\currentformulasynchronize + \fi + % subcounter + \setbox0\hbox{\ignorespaces#4\unskip}% + \ifdim\wd0>\zeropoint + \setsubstructurecounterown[\v!formula][2]{#4}% \detokenize? + \fi + \edef\currentsubformulareference{#3}% + \ifx\currentsubformulareference\empty + \glet\currentsubformulasynchronize\relax + \else + \storecurrentformulanumber\currentsubformulareference\empty\currentsubformulasynchronize + \fi + % + \rm % nodig ? + \doif{\formulaparameter\c!location}\v!right{\hskip\formulaparameter\c!distance}% + \formulaparameter\c!numbercommand + {\dosetformulaattributes\c!numberstyle\c!numbercolor + \strut + \formulaparameter\c!left + \labeltexts\v!formula{\ignorespaces\placecurrentformulanumber\unskip}% + \formulaparameter\c!right}% + \doif{\formulaparameter\c!location}\v!left{\hskip\formulaparameter\c!distance}% + \fi + \egroup} + +\let\donestedformulanumber\gobbletwoarguments + +\definelist[\v!formula] + +\global\let\doflushformulalistentry\gobbleoneargument + +\def\setformulalistentry#1% + {\gdef\doflushformulalistentry##1% + {\normalexpanded{\noexpand\writetolist[\v!formula]{##1}}{#1}% + \global\let\doflushformulalistentry\gobbleoneargument}} + +\newconditional\handleformulanumber +\newconditional\incrementformulanumber +\newconditional\insidesubformulas + +\newif\ifinformula + +\let\doplaceformulanumber\empty + +%D We need a hook into the plain math alignment macros +%D +%D \starttyping +%D \displaylines +%D \eqalignno +%D \eqalignno +%D \stoptyping +%D +%D Otherwise we get a missing \type {$$} error reported. + +\def\resetdisplaymatheq + {\let\normalleqno\relax \let\leqno\relax + \let\normalreqno\relax \let\eqno \relax + \let\doplaceformulanumber\empty} + +%D + +\def\defineformula + {\dodoubleempty\dodefineformula} + +\def\dodefineformula[#1][#2]% + {\doifsomething{#1} + {\getparameters[\??fm#1][\s!parent=\??fm,#2]% + \definelist[#1]% + \setvalue{\e!start#1\v!formula}{\dostartformula{#1}}% + \setvalue{\e!stop #1\v!formula}{\dostopformula}}} + +\def\defineformulaalternative + {\dotripleargument\dodefineformulaalternative} + +\def\dodefineformulaalternative[#1][#2][#3]% + {\setvalue{\e!start#1\v!formula}{#2}% + \setvalue{\e!stop #1\v!formula}{#3}} + +% sp = single line paragraph sd = single line display +% mp = multi line paragraph md = multy line display + +\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath] +\defineformulaalternative[\s!single] [\startdisplaymath][\stopdisplaymath] +\defineformulaalternative[\s!multi] [\startdisplaymath][\stopdisplaymath] + +\defineformula + [sp] + [\c!spacebefore=\v!none, + \c!spaceafter=\v!none, + \c!indentnext=\v!no, + \c!alternative=\s!single] + +\defineformula + [sd] + [\c!spacebefore=\v!none, + \c!spaceafter=\v!none, + \c!indentnext=\v!yes, + \c!alternative=\s!single] + +\defineformula + [mp] + [\c!indentnext=\v!no, + \c!alternative=\s!multi] + +\defineformula + [md] + [\c!indentnext=\v!yes, + \c!alternative=\s!multi] + +%D \macros +%D {setupsubformulas, startsubformulas} + +\def\subformulaparameter#1{\ifcname\??fn#1\endcsname\cname\??fn#1\endcsname\fi} + +\def\setupsubformulas + {\dodoubleargument\getparameters[\??fn]} + +\setupsubformulas + [\c!indentnext=\formulaparameter\c!indentnext] + +% \setupsubformulas[conversion=romannumerals] +% +% \placeformula +% \startsubformulas[Maxwell] +% \startformulas +% \startformula \startalign +% \NC \nabla\cdot\bf E \NC = \frac{\rho}{\varepsilon_0} \NR[Maxwell 1] +% \NC \nabla\times\bf E \NC = - \frac{\partial\bf B}{\partial t} \NR[Maxwell II] +% \stopalign \stopformula +% \startformula \startalign +% \NC \nabla\cdot \bf B \NC = 0 \NR[Maxwell III] +% \NC \nabla\times\bf B \NC = \mu_0{\bf j}+\varepsilon_0\mu_0\frac{\partial\bf E}{\partial t} \NR[Maxwell IV] +% \stopalign \stopformula +% \stopformulas +% \stopsubformulas +% +% Maxwell : \in [Maxwell] and II : \in [Maxwell II] + +%D Tricky stuff: + +\newdimen\lastlinewidth + +% test \par \dorecurse{10}{test } \moveformula \startformula test \stopformula test \endgraf +% test \par \dorecurse{10}{test } \startformula test \stopformula test \endgraf +% \dorecurse{30}{\bpar \dorecurse\recurselevel{test } \epar \startformula formula \stopformula} + +\def\setlastlinewidth + {\resetlastlinewidth + \ifoptimizedisplayspacing\ifmmode\else\ifhmode + \bgroup + \forgetdisplayskips + \displaywidowpenalty\widowpenalty % brrr, else widowpenalty does not work + \everymath \emptytoks + \everydisplay\emptytoks + $$\strut\global\lastlinewidth\predisplaysize$$ + \vskip-\lineheight + \vskip\zeropoint + \egroup + \fi\fi\fi} + +\def\resetlastlinewidth + {\global\lastlinewidth\zeropoint\relax} + +\abovedisplayskip \zeropoint +\abovedisplayshortskip \zeropoint % evt. 0pt minus 3pt +\belowdisplayskip \zeropoint +\belowdisplayshortskip \zeropoint % evt. 0pt minus 3pt + +\predisplaypenalty \zerocount +\postdisplaypenalty \zerocount % -5000 gaat mis, zie penalty bij \paragraaf + +% we don't use the skip's + +\def\displayskipsize#1#2% obsolete + {\ifdim\ctxparskip>\zeropoint + #1\ctxparskip\!!plus#2\ctxparskip\!!minus#2\ctxparskip\relax + \else + #1\lineheight\!!plus#2\lineheight\!!minus#2\lineheight\relax + \fi} + +\def\forgetdisplayskips % to do + {\abovedisplayskip \zeropoint + \belowdisplayskip \zeropoint + \abovedisplayshortskip\zeropoint + \belowdisplayshortskip\zeropoint} + +\setvalue{\e!start\v!formula}{\dostartformula{}} +\setvalue{\e!stop \v!formula}{\dostopformula} + +\def\predisplaysizethreshhold{2em} % was 3em + +\def\leftdisplayskip {\leftskip} +\def\rightdisplayskip {\rightskip} +\def\leftdisplaymargin {\formulaparameter\c!leftmargin} +\def\rightdisplaymargin {\formulaparameter\c!rightmargin} +\def\displaygridsnapping{\formulaparameter\c!grid} + +\def\beforedisplayspace + {\doifnot{\formulaparameter\c!spacebefore}\v!none{\blank[\formulaparameter\c!spacebefore]}} + +\def\afterdisplayspace + {\doifnot{\formulaparameter\c!spaceafter }\v!none{\blank[\formulaparameter\c!spaceafter ]}} + +\def\setpredisplaysize#1% + {\predisplaysize#1\relax + \ifdim\predisplaysize<\maxdimen + \ifdim\predisplaysize>\zeropoint + \advance\predisplaysize \predisplaysizethreshhold + \fi + \advance\predisplaysize \displayindent % needed ? + \ifdim\predisplaysize>\hsize + \predisplaysize\hsize + \fi + \else + \predisplaysize\zeropoint + \fi} + +\def\setdisplaydimensions + {\displayindent\leftdisplayskip + \advance\displayindent\leftdisplaymargin + \displaywidth\hsize +% \setlocalhsize +% \displaywidth\localhsize + \ifdim\hangindent>\zeropoint + \advance\displayindent\hangindent + \else + \advance\displaywidth\hangindent + \fi + \advance\displaywidth\dimexpr-\displayindent-\rightdisplayskip-\rightdisplaymargin\relax + \hsize\displaywidth} % new, else overfull in itemize + +\newif\ifoptimizedisplayspacing + +\def\dostartformula#1% + {\dodoubleempty\dodostartformula[#1]} + +\newskip\formulaparskip +\newskip\formulastrutht +\newskip\formulastrutdp + +% hm, invoke otr in hmode in order to move skips to mvl, could be an option + +%D \startbuffer +%D \startformula[9pt] x = 1 \stopformula +%D \startformula[7pt] x = 1 \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\dodostartformula[#1][#2]% setting leftskip adaption is slow ! + {% todo: test first + % + % \ifdim\lastskip>\zeropoint + % \resetlastlinewidth % else problems with in between stuff without \epar + % \fi + \bgroup % HERE + \def\currentformula{#1}% + \the\everybeforedisplayformula + \formulaparskip\parskip + \formulastrutdp\strutdepth + \formulastrutht\strutheight + \doifsomething{#2}{\switchtoformulabodyfont[#2]}% + \parskip\formulaparskip + % may look better in itemizations + \doif{\formulaparameter\c!option}\v!middle + {\def\leftdisplayskip{\zeropoint}% + \def\rightdisplayskip{\zeropoint}}% + % this was an experiment + \doifsomething{\formulaparameter\c!margin}% so we test first + {\dosetleftskipadaption{\formulaparameter\c!margin}% + \edef\leftdisplaymargin{\the\leftskipadaption}}% overloaded + \long\def\dostartformula##1{\bgroup\let\dostopformula\egroup}% + \freezedimenmacro\leftdisplayskip + \freezedimenmacro\rightdisplayskip + \freezedimenmacro\leftdisplaymargin + \freezedimenmacro\rightdisplaymargin + \freezedimenmacro\predisplaysizethreshhold + \forgetdisplayskips + \ifoptimizedisplayspacing + \ifdim\lastlinewidth>\zeropoint + \abovedisplayshortskip-\strutht\relax + \fi + \else + \resetlastlinewidth + \fi + \getvalue{\e!start\formulaparameter\c!alternative\v!formula}} + +\def\switchtoformulabodyfont{\switchtobodyfont} + +\setvalue{\v!formula}{\dosingleempty\doformula} + +\def\doformula[#1]#2% + {\begingroup + \doifsomething{#1}{\switchtoformulabodyfont[#1]}% + % not : \def\doformula[##1]##2{\mathematics{##2}}% + \mathematics{#2}% + \endgroup} + +\def\dostopformula + {\doplaceformulanumber + \getvalue{\e!stop\formulaparameter\c!alternative\v!formula}% + \resetlastlinewidth + \nonoindentation + \checknextindentation[\formulaparameter\c!indentnext]% + \egroup + \hangafter\minusone % added for side floats + \hangindent\zeropoint % added for side floats + \setfalse\handleformulanumber + \dorechecknextindentation} % here ? + +\def\startdisplaymath + {\ifgridsnapping + \beforedisplayspace + \snapmathtogrid\vbox + \bgroup + \informulatrue + %\forgetall % breaks side floats + \else + \bgroup + \parskip\formulaparskip % ! ! + \informulatrue + %\forgetall % otherwise backgrounds fail + \ifdim\lastskip<\zeropoint\else + \par + \ifvmode \ifdim\parskip>\zeropoint\relax + \whitespace \vskip-\parskip % kind of forces and cancels again + \fi \fi + \fi + \doif\displaygridcorrection{-\v!top}{\kern-\strutht}% new, currently only option/default + \beforedisplayspace + \par + \ifvmode + \prevdepth-\maxdimen % texbook pagina 79-80 + % otherwise problems at the top of a page + \verticalstrut + \vskip-\struttotal + \vskip-\baselineskip + \fi + \fi + $$\setdisplaydimensions + \setpredisplaysize\lastlinewidth + \startinnermath} + +\def\stopdisplaymath + {\stopinnermath + $$% + \ifgridsnapping + \egroup + \afterdisplayspace + \else + \par\ifvmode\ifdim\parskip>\zeropoint\whitespace\vskip-\parskip\fi\fi + \afterdisplayspace + \egroup + \fi + \globallet\displaylinecorrection\empty + \gdef\displaygridcorrection{\displaygridsnapping}} + +\newif\ifclipdisplaymath \clipdisplaymathtrue +\def\displaymathclipfactor{1.1} + +\def\snapmathtogrid % to do \dp + {\dowithnextbox + {\bgroup + \donefalse + \ifclipdisplaymath + \ifdim\nextboxht<\displaymathclipfactor\lineheight + \donetrue + \fi + \fi + \ifdone + \nextboxht\lineheight + \else + \getnoflines\nextboxht + \setbox\nextbox\vbox to \noflines\lineheight{\vfill\flushnextbox\vfill}% + \setbox\nextbox\hbox{\lower\strutdepth\flushnextbox}% + \fi + \snaptogrid[\displaygridcorrection]\hbox{\flushnextbox}% + \egroup}} + +\def\displaygridcorrection{\displaygridsnapping} +\let\displaygridcorrection\empty + +\def\moveformula + {\dosingleempty\domoveformula} + +\def\domoveformula[#1]% brr gaat mogelijk fout + {\iffirstargument + \xdef\displaygridcorrection{#1}% + \else + \gdef\displaygridcorrection{-\v!top}% handy with short preline + \fi + \globallet\displaylinecorrection\displaygridcorrection} + +\let\startinnermath\empty +\let\stopinnermath \empty + +% \defineformulaalternative[multi][\begindmath][\enddmath] +% +% \fakewords{20}{40}\epar +% \placeformula {a} $$ \fakespacingformula $$ +% \fakewords{20}{40}\epar +% \placeformula {b} \startformule \fakespacingformula \stopformule +% \placeformula {b} \startformule \fakespacingformula \stopformule +% \fakewords{20}{40}\epar +% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule +% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule +% \fakewords{20}{40}\epar +% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule +% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule +% \fakewords{20}{40}\epar +% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule +% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule +% \fakewords{20}{40}\epar +% \placeformula {f} \startspformule \fakespacingformula \stopspformule +% \placeformula {f} \startspformule \fakespacingformula \stopspformule +% \fakewords{20}{40} + +\def\placeformula + {\settrue\incrementformulanumber + \dodoubleempty\doplaceformula} + +\def\placesubformula + {\setfalse\incrementformulanumber + \dodoubleempty\doplaceformula} + +\def\startsubformulas + {\dosingleempty\dostartsubformulas} + +\def\dostartsubformulas[#1]% + {\ifconditional\incrementformulanumber + \incrementstructurecounter[\v!formula]% + \edef\subformulasreference{#1}% messy + \ifx\subformulasreference\empty + \glet\currentformulassynchronize\relax + \else + \storecurrentformulanumber\subformulasreference\empty\currentformulassynchronize + \fi + \fi + \settrue\insidesubformulas} + +\def\stopsubformulas + {\setfalse\insidesubformulas + \resetlastlinewidth + \nonoindentation + \checknextindentation[\formulaparameter\c!indentnext]% + \dorechecknextindentation} % here ? + +%D Named subformulas + +\def\startnamedsubformulas + {\dosingleempty\dostartnamedsubformulas} + +\def\dostartnamedsubformulas[#1]#2% + {\setformulalistentry{#2}% + \startsubformulas[#1]} + +\def\stopnamedsubformulas + {\stopsubformulas} + +%D Experimental goodie: +%D +%D \startbuffer +%D \placelist[formula][criterium=text] \blank[2*big] +%D \placenamedformula[one]{first} \startformula a = 1 \stopformula \endgraf +%D \placeformula \startformula a = 2 \stopformula \endgraf +%D \placenamedformula {second} \startformula a = 3 \stopformula \endgraf +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\placenamedformula + {\dosingleempty\doplacenamedformula} + +\def\doplacenamedformula[#1]#2% + {\iffirstargument + \def\next{\placeformula[#1]}% + \else + \let\next\placeformula + \fi + \setformulalistentry{#2}% + \next} + +%D The implementation of placement is a bit ugly: + +\def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces + {\def\redoplaceformula + {\bgroup + \ifx\next\bgroup + \egroup \@EA\moreplaceformula % [ref]{} + \else + \let\nextnext$% no def + \ifx\next\nextnext + \egroup \@EAEAEA\dispplaceformula % [ref]$$ + \else + \egroup \@EAEAEA\dodoplaceformula % [ref]\start + \fi + \fi[#1]{}}% + \futurelet\next\redoplaceformula} + +\long\def\moreplaceformula[#1]#2#3#4% #2 dummy #4 gobbles spaces + {\def\redoplaceformula + {\bgroup + \let\nextnext$% no def + \ifx\next\nextnext + \egroup \@EA\dispplaceformula % [ref]$$ + \else + \egroup \@EA\dodoplaceformula % [ref]\start + \fi + [#1]{#3}}% + \futurelet\next\redoplaceformula#4} + +\let\startplaceformula\placeformula +\let\stopplaceformula \relax + +\def\startformulas#1\stopformulas % new / to be internationalized + {\bgroup + \let\currentformula\empty + \forgetdisplayskips + \startdisplaymath + \setlocalhsize + \long\def\startformula##1\stopformula + {\advance\scratchcounter\plusone}% + \scratchcounter\zerocount + #1% preroll + \ifcase\scratchcounter\else + \divide \hsize \scratchcounter + \fi + \hbox to \localhsize \bgroup + \hss + \def\normalstartformula{\vskip-\strutdepth$$}% i hate this + \def\normalstopformula {$$}% + \def\startformula {$\vcenter\bgroup\normalstartformula}% + \def\stopformula {\normalstopformula\egroup$\hss}% + #1% + \egroup + \stopdisplaymath + \egroup + \hangafter\minusone % added for side floats + \hangindent\zeropoint} % added for side floats + +\def\dispplaceformula[#1]#2$$#3$$% + {\dodoplaceformula[#1]{#2}\dostartformula{}#3\dostopformula} + +\def\dodoplaceformula[#1]#2% messy, needs a clean up + {\doifelse{#1}{-} + {\setfalse\handleformulanumber} + {\doifelse{#2}{-} + {\setfalse\handleformulanumber} + {\settrue\handleformulanumber}}% + \ifconditional\handleformulanumber + \def\formulanumber + {%\global\let\subformulanumber\doformulanumber % no, bug + \doformulanumber[#1][#2]}% + \def\donestedformulanumber##1##2% + {\doifsomething{##1} + {\doifelse{##1}{+}{\doformulanumber[#1]}{\doformulanumber[##1]}[##2][]{}}}% + \def\subformulanumber + {\setfalse\incrementformulanumber + \formulanumber}% + \gdef\doplaceformulanumber + {\global\let\doplaceformulanumber\empty + \doifelse{\formulaparameter\c!location}\v!left + {\normalleqno{\doformulanumber[#1][#2][]{}}} + {\normalreqno{\doformulanumber[#1][#2][]{}}}}% + \else + \def\formulanumber{\doformulanumber[#1][#2]}% + \let\donestedformulanumber\gobbletwoarguments + \let\subformulanumber\doformulanumber % was \global + \global\let\doplaceformulanumber\empty + \fi} + +%D Here we implement a basic math alignment mechanism. Numbers +%D are also handled. The macros \type {\startinnermath} and +%D \type {\stopinnermath} can be overloaded in specialized +%D modules. + +\def\startinnermath + {\getvalue{\e!start\??fm\formulaparameter\c!align}} + +\def\stopinnermath + {\getvalue{\e!stop \??fm\formulaparameter\c!align}} + +\def\mathinnerstrut + {\doif{\formulaparameter\c!strut}\v!yes\strut} + +\long\def\defineinnermathhandler#1#2#3% + {\setvalue{\e!start\??fm#1}{#2}% + \setvalue{\e!stop \??fm#1}{#3}} + +\newif\iftracemath + +\def\mathhbox + {\iftracemath\ruledhbox\else\hbox\fi} + +\chardef\mathraggedstatus=0 % normal left center right +\chardef\mathnumberstatus=0 % nothing normal shift_right +\let\mathnumbercorrection\!!zeropoint + +\def\startmathbox#1% + {\hsize\displaywidth + \global\chardef\mathnumberstatus\plusone + \chardef\mathraggedstatus#1\relax + \let\mathnumbercorrection\!!zeropoint + \global\let\@eqno \empty \def\eqno {\gdef\@eqno }% + \global\let\@leqno\empty \def\leqno{\gdef\@leqno}% + % added + \let\normalreqno\eqno + \let\normalleqno\leqno + % added + \doplaceformulanumber + \setbox\scratchbox\mathhbox to \displaywidth\bgroup + \mathinnerstrut + $% + \displaystyle + \ifcase\mathraggedstatus\or\hfill\or\hfill\fi} + +\def\llappedmathno + {\ifcase\mathraggedstatus\or + \@eqno + \or + \llap{\@eqno}% + \or + \llap{\@eqno}% + \fi} + +\def\rlappedmathno + {\ifcase\mathraggedstatus\or + \rlap{\@leqno}% + \or + \rlap{\@leqno}% + \or + \@leqno + \fi} + +\def\stopmathbox + {$% + \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi + \egroup + \setbox0\hbox{\unhcopy\scratchbox}% + \scratchdimen\wd0 + \ifdim\scratchdimen>\displaywidth + \donetrue + \else + \donefalse + \fi + \hbox to \displaywidth\bgroup + \ifcase\mathnumberstatus + \box\scratchbox + \or + \ifx\@leqno\empty + \ifx\@eqno\empty + \box\scratchbox + \else + \ifdone + \vbox{\box\scratchbox\hbox to \displaywidth{\hss\llappedmathno}}% + \else + \hss\box\scratchbox\llappedmathno % hss makes room for number + \fi + \fi + \else + \ifdone + \vbox{\hbox to \displaywidth{\rlappedmathno\hss}\box\scratchbox}% + \else + \rlappedmathno\box\scratchbox\hss % hss makes room for number + \fi + \fi + \or + \hskip\mathnumbercorrection + \box\scratchbox + \hss + \else + \box\scratchbox + \fi + \egroup} + +\defineinnermathhandler\v!left {\startmathbox\plusone }{\stopmathbox} +\defineinnermathhandler\v!middle {\startmathbox\plustwo }{\stopmathbox} +\defineinnermathhandler\v!right {\startmathbox\plusthree}{\stopmathbox} +\defineinnermathhandler\v!flushleft {\startmathbox\plusthree}{\stopmathbox} +\defineinnermathhandler\v!center {\startmathbox\plustwo }{\stopmathbox} +\defineinnermathhandler\v!flushright{\startmathbox\plusone }{\stopmathbox} + +%D [The examples below are in english and don't process in the +%D documentation style, which will be english some day.] +%D +%D Normally a formula is centered, but in case you want to +%D align it left or right, you can set up formulas to behave +%D that way. Normally a formula will adapt is left indentation +%D to the environment: +%D +%D \startbuffer +%D \fakewords{20}{40}\epar +%D \startitemize +%D \item \fakewords{20}{40}\epar +%D \placeformula \startformula \fakeformula \stopformula +%D \item \fakewords{20}{40}\epar +%D \stopitemize +%D \fakewords{20}{40}\epar +%D \stopbuffer +%D +%D % \getbuffer +%D +%D In the next examples we explicitly align formulas to the +%D left (\type {\raggedleft}), center and right (\type +%D {\raggedright}): +%D +%D \startbuffer +%D \setupformulas[align=left] +%D \startformula\fakeformula\stopformula +%D \setupformulas[align=middle] +%D \startformula\fakeformula\stopformula +%D \setupformulas[align=right] +%D \startformula\fakeformula\stopformula +%D \stopbuffer +%D +%D \typebuffer +%D +%D Or in print: +%D +%D % {\getbuffer} +%D +%D With formula numbers these formulas look as follows: +%D +%D \startbuffer +%D \setupformulas[align=left] +%D \placeformula \startformula\fakeformula\stopformula +%D \setupformulas[align=middle] +%D \placeformula \startformula\fakeformula\stopformula +%D \setupformulas[align=right] +%D \placeformula \startformula\fakeformula\stopformula +%D \stopbuffer +%D +%D % {\getbuffer} +%D +%D This was keyed in as: +%D +%D \typebuffer +%D +%D When tracing is turned on (\type {\tracemathtrue}) you can +%D visualize the bounding box of the formula, +%D +%D % {\tracemathtrue\getbuffer} +%D +%D As you can see, the dimensions are the natural ones, but if +%D needed you can force a normalized line: +%D +%D \startbuffer +%D \setupformulas[strut=yes] +%D \placeformula \startformula \fakeformula \stopformula +%D \stopbuffer +%D +%D \typebuffer +%D +%D This time we get a more spacy result. +%D +%D % {\tracemathtrue\getbuffer} +%D +%D We will now show a couple of more settings and combinations +%D of settings. In centered formulas, the number takes no space +%D +%D \startbuffer +%D \setupformulas[align=middle] +%D \startformula \fakeformula \stopformula +%D \placeformula \startformula \fakeformula \stopformula +%D \stopbuffer +%D +%D \typebuffer % {\tracemathtrue\getbuffer} +%D +%D You can influence the placement of the whole box with the +%D parameters \type {leftmargin} and \type {rightmargin}. +%D +%D \startbuffer +%D \setupformulas[align=right,leftmargin=3em] +%D \startformula \fakeformula \stopformula +%D \placeformula \startformula \fakeformula \stopformula +%D +%D \setupformulas[align=left,rightmargin=1em] +%D \startformula \fakeformula \stopformula +%D \placeformula \startformula \fakeformula \stopformula +%D \stopbuffer +%D +%D \typebuffer % {\tracemathtrue\getbuffer} +%D +%D You can also inherit the margin from the environment. +%D +%D \startbuffer +%D \setupformulas[align=right,margin=standard] +%D \startformula \fakeformula \stopformula +%D \placeformula \startformula \fakeformula \stopformula +%D \stopbuffer +%D +%D \typebuffer % {\tracemathtrue\getbuffer} +%D +%D The distance between the formula and the number is only +%D applied when the formula is left or right aligned. +%D +%D \startbuffer +%D \setupformulas[align=left,distance=2em] +%D \startformula \fakeformula \stopformula +%D \placeformula \startformula \fakeformula \stopformula +%D \stopbuffer +%D +%D \typebuffer % {\tracemathtrue\getbuffer} + +\protect \endinput + +% \abovedisplayshortskip0pt \belowdisplayshortskip0pt \abovedisplayskip0pt \belowdisplayskip0pt \forgetall +% +% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% test plus \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% +% \parskip\baselineskip +% +% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% test plus \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par +% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par diff --git a/tex/context/base/strc-mat.tex b/tex/context/base/strc-mat.tex deleted file mode 100644 index 482426b48..000000000 --- a/tex/context/base/strc-mat.tex +++ /dev/null @@ -1,933 +0,0 @@ -%D \module -%D [ file=strc-mat, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Math Numbering, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Math Numbering} - -\registerctxluafile{strc-mat}{1.001} - -\unprotect - -\definestructureconversionset[\v!formula][number,characters] - -\setupformulas - [%\c!way=\@@nrway, - %\c!blockway=, - %\c!sectionnumber=\@@nrsectionnumber, - %\c!conversion=\v!numbers, - \c!location=\v!right, - \c!left=(, - \c!right=), - %\c!numberstyle=, - %\c!numbercolor=, - %\c!numbercommand=, - \c!spacebefore=\v!big, - \c!spaceafter=\formulaparameter\c!spacebefore, - \c!leftmargin=\!!zeropoint, - \c!rightmargin=\!!zeropoint, - %\c!margin=, - \c!indentnext=\v!no, - \c!alternative=\s!default, - %\c!align=, - \c!strut=\v!no, - %\c!separator=\@@koseparator, - %\c!grid=, - \c!distance=1em] - -\definestructurecounter - [\v!formula] - -\setupstructurecounter - [\v!formula] - [\c!numberconversionset=\v!formula] - -\def\storecurrentformulanumber#1#2#3% ref, todo:str, \sync % todo: title etc (like float) - {\dostructurecountercomponent - {formula}% - \getfloatparameters - \formulaparameter - \detokenizedformulaparameter - \relax - \relax - \relax - [\c!name=\currentformula,\s!counter=\currentformula,% - \s!hascaption=\v!yes,\s!hasnumber=\v!yes,\s!hastitle=\v!yes,% - \c!reference=#1,\c!title=,\c!bookmark=]% - [#2]% - \globallet\currentformulanumber\laststructurecounternumber - \globallet#3\laststructurecountersynchronize} - -\def\thecurrentformulanumber - {%\ifnoformulacaption \else \ifnoformulanumber \else - \labeltexts\currentformula{\convertedstructurecounter[formula]}% ! ! todo: use a lua call instead - }%\fi \fi} - -\def\placecurrentformulanumber - {\currentformulassynchronize - \currentformulasynchronize - \currentsubformulasynchronize - \thecurrentformulanumber} %\convertedstructurecounter[\v!formula]\relax} - -\def\doformulareference#1#2% - {\doifsomething{#1}{\doifnotinset{#1}{+,-}{\rawreference\s!for{#1}{#2}}}} - -\def\doformulanumber - {\dotripleempty\dodoformulanumber} - -\def\dodoformulanumber[#1][#2][#3]% - {\doquadruplegroupempty\dododoformulanumber{#1}{#2}{#3}} - -\let\subformulasreference\empty % temp hack - -\let\currentformulasynchronize \relax -\let\currentformulassynchronize\relax - -\def\dododoformulanumber#1#2#3#4% (#1,#2)=outer(ref,sub) (#3,#4)=inner(ref,sub) - {\hbox\bgroup - \ifconditional\handleformulanumber - \ifconditional\incrementformulanumber - \ifconditional\insidesubformulas - \incrementsubstructurecounter[\v!formula][2]% - \else - \incrementstructurecounter[\v!formula]% - \fi - \fi - % - % main counter - \setbox0\hbox{\ignorespaces#2\unskip}% - \ifdim\wd0>\zeropoint - \setsubstructurecounterown[\v!formula][2]{#2}% \detokenize? - \fi - \edef\currentformulareference{#1}% - \ifx\currentformulareference\empty - \glet\currentformulasynchronize\relax - \else - \storecurrentformulanumber\currentformulareference\empty\currentformulasynchronize - \fi - % subcounter - \setbox0\hbox{\ignorespaces#4\unskip}% - \ifdim\wd0>\zeropoint - \setsubstructurecounterown[\v!formula][2]{#4}% \detokenize? - \fi - \edef\currentsubformulareference{#3}% - \ifx\currentsubformulareference\empty - \glet\currentsubformulasynchronize\relax - \else - \storecurrentformulanumber\currentsubformulareference\empty\currentsubformulasynchronize - \fi - % - \rm % nodig ? - \doif{\formulaparameter\c!location}\v!right{\hskip\formulaparameter\c!distance}% - \formulaparameter\c!numbercommand - {\dosetformulaattributes\c!numberstyle\c!numbercolor - \strut - \formulaparameter\c!left - \labeltexts\v!formula{\ignorespaces\placecurrentformulanumber\unskip}% - \formulaparameter\c!right}% - \doif{\formulaparameter\c!location}\v!left{\hskip\formulaparameter\c!distance}% - \fi - \egroup} - -\let\donestedformulanumber\gobbletwoarguments - -\definelist[\v!formula] - -\global\let\doflushformulalistentry\gobbleoneargument - -\def\setformulalistentry#1% - {\gdef\doflushformulalistentry##1% - {\normalexpanded{\noexpand\writetolist[\v!formula]{##1}}{#1}% - \global\let\doflushformulalistentry\gobbleoneargument}} - -\newconditional\handleformulanumber -\newconditional\incrementformulanumber -\newconditional\insidesubformulas - -\newif\ifinformula - -\let\doplaceformulanumber\empty - -%D We need a hook into the plain math alignment macros -%D -%D \starttyping -%D \displaylines -%D \eqalignno -%D \eqalignno -%D \stoptyping -%D -%D Otherwise we get a missing \type {$$} error reported. - -\def\resetdisplaymatheq - {\let\normalleqno\relax \let\leqno\relax - \let\normalreqno\relax \let\eqno \relax - \let\doplaceformulanumber\empty} - -%D - -\def\defineformula - {\dodoubleempty\dodefineformula} - -\def\dodefineformula[#1][#2]% - {\doifsomething{#1} - {\getparameters[\??fm#1][\s!parent=\??fm,#2]% - \definelist[#1]% - \setvalue{\e!start#1\v!formula}{\dostartformula{#1}}% - \setvalue{\e!stop #1\v!formula}{\dostopformula}}} - -\def\defineformulaalternative - {\dotripleargument\dodefineformulaalternative} - -\def\dodefineformulaalternative[#1][#2][#3]% - {\setvalue{\e!start#1\v!formula}{#2}% - \setvalue{\e!stop #1\v!formula}{#3}} - -% sp = single line paragraph sd = single line display -% mp = multi line paragraph md = multy line display - -\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath] -\defineformulaalternative[\s!single] [\startdisplaymath][\stopdisplaymath] -\defineformulaalternative[\s!multi] [\startdisplaymath][\stopdisplaymath] - -\defineformula - [sp] - [\c!spacebefore=\v!none, - \c!spaceafter=\v!none, - \c!indentnext=\v!no, - \c!alternative=\s!single] - -\defineformula - [sd] - [\c!spacebefore=\v!none, - \c!spaceafter=\v!none, - \c!indentnext=\v!yes, - \c!alternative=\s!single] - -\defineformula - [mp] - [\c!indentnext=\v!no, - \c!alternative=\s!multi] - -\defineformula - [md] - [\c!indentnext=\v!yes, - \c!alternative=\s!multi] - -%D \macros -%D {setupsubformulas, startsubformulas} - -\def\subformulaparameter#1{\ifcname\??fn#1\endcsname\cname\??fn#1\endcsname\fi} - -\def\setupsubformulas - {\dodoubleargument\getparameters[\??fn]} - -\setupsubformulas - [\c!indentnext=\formulaparameter\c!indentnext] - -% \setupsubformulas[conversion=romannumerals] -% -% \placeformula -% \startsubformulas[Maxwell] -% \startformulas -% \startformula \startalign -% \NC \nabla\cdot\bf E \NC = \frac{\rho}{\varepsilon_0} \NR[Maxwell 1] -% \NC \nabla\times\bf E \NC = - \frac{\partial\bf B}{\partial t} \NR[Maxwell II] -% \stopalign \stopformula -% \startformula \startalign -% \NC \nabla\cdot \bf B \NC = 0 \NR[Maxwell III] -% \NC \nabla\times\bf B \NC = \mu_0{\bf j}+\varepsilon_0\mu_0\frac{\partial\bf E}{\partial t} \NR[Maxwell IV] -% \stopalign \stopformula -% \stopformulas -% \stopsubformulas -% -% Maxwell : \in [Maxwell] and II : \in [Maxwell II] - -%D Tricky stuff: - -\newdimen\lastlinewidth - -% test \par \dorecurse{10}{test } \moveformula \startformula test \stopformula test \endgraf -% test \par \dorecurse{10}{test } \startformula test \stopformula test \endgraf -% \dorecurse{30}{\bpar \dorecurse\recurselevel{test } \epar \startformula formula \stopformula} - -\def\setlastlinewidth - {\resetlastlinewidth - \ifoptimizedisplayspacing\ifmmode\else\ifhmode - \bgroup - \forgetdisplayskips - \displaywidowpenalty\widowpenalty % brrr, else widowpenalty does not work - \everymath \emptytoks - \everydisplay\emptytoks - $$\strut\global\lastlinewidth\predisplaysize$$ - \vskip-\lineheight - \vskip\zeropoint - \egroup - \fi\fi\fi} - -\def\resetlastlinewidth - {\global\lastlinewidth\zeropoint\relax} - -\abovedisplayskip \zeropoint -\abovedisplayshortskip \zeropoint % evt. 0pt minus 3pt -\belowdisplayskip \zeropoint -\belowdisplayshortskip \zeropoint % evt. 0pt minus 3pt - -\predisplaypenalty \zerocount -\postdisplaypenalty \zerocount % -5000 gaat mis, zie penalty bij \paragraaf - -% we don't use the skip's - -\def\displayskipsize#1#2% obsolete - {\ifdim\ctxparskip>\zeropoint - #1\ctxparskip\!!plus#2\ctxparskip\!!minus#2\ctxparskip\relax - \else - #1\lineheight\!!plus#2\lineheight\!!minus#2\lineheight\relax - \fi} - -\def\forgetdisplayskips % to do - {\abovedisplayskip \zeropoint - \belowdisplayskip \zeropoint - \abovedisplayshortskip\zeropoint - \belowdisplayshortskip\zeropoint} - -\setvalue{\e!start\v!formula}{\dostartformula{}} -\setvalue{\e!stop \v!formula}{\dostopformula} - -\def\predisplaysizethreshhold{2em} % was 3em - -\def\leftdisplayskip {\leftskip} -\def\rightdisplayskip {\rightskip} -\def\leftdisplaymargin {\formulaparameter\c!leftmargin} -\def\rightdisplaymargin {\formulaparameter\c!rightmargin} -\def\displaygridsnapping{\formulaparameter\c!grid} - -\def\beforedisplayspace - {\doifnot{\formulaparameter\c!spacebefore}\v!none{\blank[\formulaparameter\c!spacebefore]}} - -\def\afterdisplayspace - {\doifnot{\formulaparameter\c!spaceafter }\v!none{\blank[\formulaparameter\c!spaceafter ]}} - -\def\setpredisplaysize#1% - {\predisplaysize#1\relax - \ifdim\predisplaysize<\maxdimen - \ifdim\predisplaysize>\zeropoint - \advance\predisplaysize \predisplaysizethreshhold - \fi - \advance\predisplaysize \displayindent % needed ? - \ifdim\predisplaysize>\hsize - \predisplaysize\hsize - \fi - \else - \predisplaysize\zeropoint - \fi} - -\def\setdisplaydimensions - {\displayindent\leftdisplayskip - \advance\displayindent\leftdisplaymargin - \displaywidth\hsize -% \setlocalhsize -% \displaywidth\localhsize - \ifdim\hangindent>\zeropoint - \advance\displayindent\hangindent - \else - \advance\displaywidth\hangindent - \fi - \advance\displaywidth\dimexpr-\displayindent-\rightdisplayskip-\rightdisplaymargin\relax - \hsize\displaywidth} % new, else overfull in itemize - -\newif\ifoptimizedisplayspacing - -\def\dostartformula#1% - {\dodoubleempty\dodostartformula[#1]} - -\newskip\formulaparskip -\newskip\formulastrutht -\newskip\formulastrutdp - -% hm, invoke otr in hmode in order to move skips to mvl, could be an option - -%D \startbuffer -%D \startformula[9pt] x = 1 \stopformula -%D \startformula[7pt] x = 1 \stopformula -%D \stopbuffer -%D -%D \typebuffer \getbuffer - -\def\dodostartformula[#1][#2]% setting leftskip adaption is slow ! - {% todo: test first - % - % \ifdim\lastskip>\zeropoint - % \resetlastlinewidth % else problems with in between stuff without \epar - % \fi - \bgroup % HERE - \def\currentformula{#1}% - \the\everybeforedisplayformula - \formulaparskip\parskip - \formulastrutdp\strutdepth - \formulastrutht\strutheight - \doifsomething{#2}{\switchtoformulabodyfont[#2]}% - \parskip\formulaparskip - % may look better in itemizations - \doif{\formulaparameter\c!option}\v!middle - {\def\leftdisplayskip{\zeropoint}% - \def\rightdisplayskip{\zeropoint}}% - % this was an experiment - \doifsomething{\formulaparameter\c!margin}% so we test first - {\dosetleftskipadaption{\formulaparameter\c!margin}% - \edef\leftdisplaymargin{\the\leftskipadaption}}% overloaded - \long\def\dostartformula##1{\bgroup\let\dostopformula\egroup}% - \freezedimenmacro\leftdisplayskip - \freezedimenmacro\rightdisplayskip - \freezedimenmacro\leftdisplaymargin - \freezedimenmacro\rightdisplaymargin - \freezedimenmacro\predisplaysizethreshhold - \forgetdisplayskips - \ifoptimizedisplayspacing - \ifdim\lastlinewidth>\zeropoint - \abovedisplayshortskip-\strutht\relax - \fi - \else - \resetlastlinewidth - \fi - \getvalue{\e!start\formulaparameter\c!alternative\v!formula}} - -\def\switchtoformulabodyfont{\switchtobodyfont} - -\setvalue{\v!formula}{\dosingleempty\doformula} - -\def\doformula[#1]#2% - {\begingroup - \doifsomething{#1}{\switchtoformulabodyfont[#1]}% - % not : \def\doformula[##1]##2{\mathematics{##2}}% - \mathematics{#2}% - \endgroup} - -\def\dostopformula - {\doplaceformulanumber - \getvalue{\e!stop\formulaparameter\c!alternative\v!formula}% - \resetlastlinewidth - \nonoindentation - \checknextindentation[\formulaparameter\c!indentnext]% - \egroup - \hangafter\minusone % added for side floats - \hangindent\zeropoint % added for side floats - \setfalse\handleformulanumber - \dorechecknextindentation} % here ? - -\def\startdisplaymath - {\ifgridsnapping - \beforedisplayspace - \snapmathtogrid\vbox - \bgroup - \informulatrue - %\forgetall % breaks side floats - \else - \bgroup - \parskip\formulaparskip % ! ! - \informulatrue - %\forgetall % otherwise backgrounds fail - \ifdim\lastskip<\zeropoint\else - \par - \ifvmode \ifdim\parskip>\zeropoint\relax - \whitespace \vskip-\parskip % kind of forces and cancels again - \fi \fi - \fi - \doif\displaygridcorrection{-\v!top}{\kern-\strutht}% new, currently only option/default - \beforedisplayspace - \par - \ifvmode - \prevdepth-\maxdimen % texbook pagina 79-80 - % otherwise problems at the top of a page - \verticalstrut - \vskip-\struttotal - \vskip-\baselineskip - \fi - \fi - $$\setdisplaydimensions - \setpredisplaysize\lastlinewidth - \startinnermath} - -\def\stopdisplaymath - {\stopinnermath - $$% - \ifgridsnapping - \egroup - \afterdisplayspace - \else - \par\ifvmode\ifdim\parskip>\zeropoint\whitespace\vskip-\parskip\fi\fi - \afterdisplayspace - \egroup - \fi - \globallet\displaylinecorrection\empty - \gdef\displaygridcorrection{\displaygridsnapping}} - -\newif\ifclipdisplaymath \clipdisplaymathtrue -\def\displaymathclipfactor{1.1} - -\def\snapmathtogrid % to do \dp - {\dowithnextbox - {\bgroup - \donefalse - \ifclipdisplaymath - \ifdim\nextboxht<\displaymathclipfactor\lineheight - \donetrue - \fi - \fi - \ifdone - \nextboxht\lineheight - \else - \getnoflines\nextboxht - \setbox\nextbox\vbox to \noflines\lineheight{\vfill\flushnextbox\vfill}% - \setbox\nextbox\hbox{\lower\strutdepth\flushnextbox}% - \fi - \snaptogrid[\displaygridcorrection]\hbox{\flushnextbox}% - \egroup}} - -\def\displaygridcorrection{\displaygridsnapping} -\let\displaygridcorrection\empty - -\def\moveformula - {\dosingleempty\domoveformula} - -\def\domoveformula[#1]% brr gaat mogelijk fout - {\iffirstargument - \xdef\displaygridcorrection{#1}% - \else - \gdef\displaygridcorrection{-\v!top}% handy with short preline - \fi - \globallet\displaylinecorrection\displaygridcorrection} - -\let\startinnermath\empty -\let\stopinnermath \empty - -% \defineformulaalternative[multi][\begindmath][\enddmath] -% -% \fakewords{20}{40}\epar -% \placeformula {a} $$ \fakespacingformula $$ -% \fakewords{20}{40}\epar -% \placeformula {b} \startformule \fakespacingformula \stopformule -% \placeformula {b} \startformule \fakespacingformula \stopformule -% \fakewords{20}{40}\epar -% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule -% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule -% \fakewords{20}{40}\epar -% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule -% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule -% \fakewords{20}{40}\epar -% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule -% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule -% \fakewords{20}{40}\epar -% \placeformula {f} \startspformule \fakespacingformula \stopspformule -% \placeformula {f} \startspformule \fakespacingformula \stopspformule -% \fakewords{20}{40} - -\def\placeformula - {\settrue\incrementformulanumber - \dodoubleempty\doplaceformula} - -\def\placesubformula - {\setfalse\incrementformulanumber - \dodoubleempty\doplaceformula} - -\def\startsubformulas - {\dosingleempty\dostartsubformulas} - -\def\dostartsubformulas[#1]% - {\ifconditional\incrementformulanumber - \incrementstructurecounter[\v!formula]% - \edef\subformulasreference{#1}% messy - \ifx\subformulasreference\empty - \glet\currentformulassynchronize\relax - \else - \storecurrentformulanumber\subformulasreference\empty\currentformulassynchronize - \fi - \fi - \settrue\insidesubformulas} - -\def\stopsubformulas - {\setfalse\insidesubformulas - \resetlastlinewidth - \nonoindentation - \checknextindentation[\formulaparameter\c!indentnext]% - \dorechecknextindentation} % here ? - -%D Named subformulas - -\def\startnamedsubformulas - {\dosingleempty\dostartnamedsubformulas} - -\def\dostartnamedsubformulas[#1]#2% - {\setformulalistentry{#2}% - \startsubformulas[#1]} - -\def\stopnamedsubformulas - {\stopsubformulas} - -%D Experimental goodie: -%D -%D \startbuffer -%D \placelist[formula][criterium=text] \blank[2*big] -%D \placenamedformula[one]{first} \startformula a = 1 \stopformula \endgraf -%D \placeformula \startformula a = 2 \stopformula \endgraf -%D \placenamedformula {second} \startformula a = 3 \stopformula \endgraf -%D \stopbuffer -%D -%D \typebuffer \getbuffer - -\def\placenamedformula - {\dosingleempty\doplacenamedformula} - -\def\doplacenamedformula[#1]#2% - {\iffirstargument - \def\next{\placeformula[#1]}% - \else - \let\next\placeformula - \fi - \setformulalistentry{#2}% - \next} - -%D The implementation of placement is a bit ugly: - -\def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces - {\def\redoplaceformula - {\bgroup - \ifx\next\bgroup - \egroup \@EA\moreplaceformula % [ref]{} - \else - \let\nextnext$% no def - \ifx\next\nextnext - \egroup \@EAEAEA\dispplaceformula % [ref]$$ - \else - \egroup \@EAEAEA\dodoplaceformula % [ref]\start - \fi - \fi[#1]{}}% - \futurelet\next\redoplaceformula} - -\long\def\moreplaceformula[#1]#2#3#4% #2 dummy #4 gobbles spaces - {\def\redoplaceformula - {\bgroup - \let\nextnext$% no def - \ifx\next\nextnext - \egroup \@EA\dispplaceformula % [ref]$$ - \else - \egroup \@EA\dodoplaceformula % [ref]\start - \fi - [#1]{#3}}% - \futurelet\next\redoplaceformula#4} - -\let\startplaceformula\placeformula -\let\stopplaceformula \relax - -\def\startformulas#1\stopformulas % new / to be internationalized - {\bgroup - \let\currentformula\empty - \forgetdisplayskips - \startdisplaymath - \setlocalhsize - \long\def\startformula##1\stopformula - {\advance\scratchcounter\plusone}% - \scratchcounter\zerocount - #1% preroll - \ifcase\scratchcounter\else - \divide \hsize \scratchcounter - \fi - \hbox to \localhsize \bgroup - \hss - \def\normalstartformula{\vskip-\strutdepth$$}% i hate this - \def\normalstopformula {$$}% - \def\startformula {$\vcenter\bgroup\normalstartformula}% - \def\stopformula {\normalstopformula\egroup$\hss}% - #1% - \egroup - \stopdisplaymath - \egroup - \hangafter\minusone % added for side floats - \hangindent\zeropoint} % added for side floats - -\def\dispplaceformula[#1]#2$$#3$$% - {\dodoplaceformula[#1]{#2}\dostartformula{}#3\dostopformula} - -\def\dodoplaceformula[#1]#2% messy, needs a clean up - {\doifelse{#1}{-} - {\setfalse\handleformulanumber} - {\doifelse{#2}{-} - {\setfalse\handleformulanumber} - {\settrue\handleformulanumber}}% - \ifconditional\handleformulanumber - \def\formulanumber - {%\global\let\subformulanumber\doformulanumber % no, bug - \doformulanumber[#1][#2]}% - \def\donestedformulanumber##1##2% - {\doifsomething{##1} - {\doifelse{##1}{+}{\doformulanumber[#1]}{\doformulanumber[##1]}[##2][]{}}}% - \def\subformulanumber - {\setfalse\incrementformulanumber - \formulanumber}% - \gdef\doplaceformulanumber - {\global\let\doplaceformulanumber\empty - \doifelse{\formulaparameter\c!location}\v!left - {\normalleqno{\doformulanumber[#1][#2][]{}}} - {\normalreqno{\doformulanumber[#1][#2][]{}}}}% - \else - \def\formulanumber{\doformulanumber[#1][#2]}% - \let\donestedformulanumber\gobbletwoarguments - \let\subformulanumber\doformulanumber % was \global - \global\let\doplaceformulanumber\empty - \fi} - -%D Here we implement a basic math alignment mechanism. Numbers -%D are also handled. The macros \type {\startinnermath} and -%D \type {\stopinnermath} can be overloaded in specialized -%D modules. - -\def\startinnermath - {\getvalue{\e!start\??fm\formulaparameter\c!align}} - -\def\stopinnermath - {\getvalue{\e!stop \??fm\formulaparameter\c!align}} - -\def\mathinnerstrut - {\doif{\formulaparameter\c!strut}\v!yes\strut} - -\long\def\defineinnermathhandler#1#2#3% - {\setvalue{\e!start\??fm#1}{#2}% - \setvalue{\e!stop \??fm#1}{#3}} - -\newif\iftracemath - -\def\mathhbox - {\iftracemath\ruledhbox\else\hbox\fi} - -\chardef\mathraggedstatus=0 % normal left center right -\chardef\mathnumberstatus=0 % nothing normal shift_right -\let\mathnumbercorrection\!!zeropoint - -\def\startmathbox#1% - {\hsize\displaywidth - \global\chardef\mathnumberstatus\plusone - \chardef\mathraggedstatus#1\relax - \let\mathnumbercorrection\!!zeropoint - \global\let\@eqno \empty \def\eqno {\gdef\@eqno }% - \global\let\@leqno\empty \def\leqno{\gdef\@leqno}% - % added - \let\normalreqno\eqno - \let\normalleqno\leqno - % added - \doplaceformulanumber - \setbox\scratchbox\mathhbox to \displaywidth\bgroup - \mathinnerstrut - $% - \displaystyle - \ifcase\mathraggedstatus\or\hfill\or\hfill\fi} - -\def\llappedmathno - {\ifcase\mathraggedstatus\or - \@eqno - \or - \llap{\@eqno}% - \or - \llap{\@eqno}% - \fi} - -\def\rlappedmathno - {\ifcase\mathraggedstatus\or - \rlap{\@leqno}% - \or - \rlap{\@leqno}% - \or - \@leqno - \fi} - -\def\stopmathbox - {$% - \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi - \egroup - \setbox0\hbox{\unhcopy\scratchbox}% - \scratchdimen\wd0 - \ifdim\scratchdimen>\displaywidth - \donetrue - \else - \donefalse - \fi - \hbox to \displaywidth\bgroup - \ifcase\mathnumberstatus - \box\scratchbox - \or - \ifx\@leqno\empty - \ifx\@eqno\empty - \box\scratchbox - \else - \ifdone - \vbox{\box\scratchbox\hbox to \displaywidth{\hss\llappedmathno}}% - \else - \hss\box\scratchbox\llappedmathno % hss makes room for number - \fi - \fi - \else - \ifdone - \vbox{\hbox to \displaywidth{\rlappedmathno\hss}\box\scratchbox}% - \else - \rlappedmathno\box\scratchbox\hss % hss makes room for number - \fi - \fi - \or - \hskip\mathnumbercorrection - \box\scratchbox - \hss - \else - \box\scratchbox - \fi - \egroup} - -\defineinnermathhandler\v!left {\startmathbox\plusone }{\stopmathbox} -\defineinnermathhandler\v!middle {\startmathbox\plustwo }{\stopmathbox} -\defineinnermathhandler\v!right {\startmathbox\plusthree}{\stopmathbox} -\defineinnermathhandler\v!flushleft {\startmathbox\plusthree}{\stopmathbox} -\defineinnermathhandler\v!center {\startmathbox\plustwo }{\stopmathbox} -\defineinnermathhandler\v!flushright{\startmathbox\plusone }{\stopmathbox} - -%D [The examples below are in english and don't process in the -%D documentation style, which will be english some day.] -%D -%D Normally a formula is centered, but in case you want to -%D align it left or right, you can set up formulas to behave -%D that way. Normally a formula will adapt is left indentation -%D to the environment: -%D -%D \startbuffer -%D \fakewords{20}{40}\epar -%D \startitemize -%D \item \fakewords{20}{40}\epar -%D \placeformula \startformula \fakeformula \stopformula -%D \item \fakewords{20}{40}\epar -%D \stopitemize -%D \fakewords{20}{40}\epar -%D \stopbuffer -%D -%D % \getbuffer -%D -%D In the next examples we explicitly align formulas to the -%D left (\type {\raggedleft}), center and right (\type -%D {\raggedright}): -%D -%D \startbuffer -%D \setupformulas[align=left] -%D \startformula\fakeformula\stopformula -%D \setupformulas[align=middle] -%D \startformula\fakeformula\stopformula -%D \setupformulas[align=right] -%D \startformula\fakeformula\stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D Or in print: -%D -%D % {\getbuffer} -%D -%D With formula numbers these formulas look as follows: -%D -%D \startbuffer -%D \setupformulas[align=left] -%D \placeformula \startformula\fakeformula\stopformula -%D \setupformulas[align=middle] -%D \placeformula \startformula\fakeformula\stopformula -%D \setupformulas[align=right] -%D \placeformula \startformula\fakeformula\stopformula -%D \stopbuffer -%D -%D % {\getbuffer} -%D -%D This was keyed in as: -%D -%D \typebuffer -%D -%D When tracing is turned on (\type {\tracemathtrue}) you can -%D visualize the bounding box of the formula, -%D -%D % {\tracemathtrue\getbuffer} -%D -%D As you can see, the dimensions are the natural ones, but if -%D needed you can force a normalized line: -%D -%D \startbuffer -%D \setupformulas[strut=yes] -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D This time we get a more spacy result. -%D -%D % {\tracemathtrue\getbuffer} -%D -%D We will now show a couple of more settings and combinations -%D of settings. In centered formulas, the number takes no space -%D -%D \startbuffer -%D \setupformulas[align=middle] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} -%D -%D You can influence the placement of the whole box with the -%D parameters \type {leftmargin} and \type {rightmargin}. -%D -%D \startbuffer -%D \setupformulas[align=right,leftmargin=3em] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D -%D \setupformulas[align=left,rightmargin=1em] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} -%D -%D You can also inherit the margin from the environment. -%D -%D \startbuffer -%D \setupformulas[align=right,margin=standard] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} -%D -%D The distance between the formula and the number is only -%D applied when the formula is left or right aligned. -%D -%D \startbuffer -%D \setupformulas[align=left,distance=2em] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} - -\protect \endinput - -% \abovedisplayshortskip0pt \belowdisplayshortskip0pt \abovedisplayskip0pt \belowdisplayskip0pt \forgetall -% -% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% test plus \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% -% \parskip\baselineskip -% -% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% test plus \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par -% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par diff --git a/tex/context/base/strc-not.lua b/tex/context/base/strc-not.lua index 78e7b6acd..115de7b9d 100644 --- a/tex/context/base/strc-not.lua +++ b/tex/context/base/strc-not.lua @@ -44,7 +44,8 @@ function notes.store(tag,n) nd[#nd+1] = n local state = notestates[tag] if state.kind ~= "insert" then - state.start = #nd +--~ state.start = #nd + state.start = state.start or #nd end tex.write(#nd) end @@ -102,7 +103,7 @@ end function notes.getstate(tag) local state = notestates[tag] - texsprint((state and state.kind ) or "unknown") + texsprint(ctxcatcodes,(state and state.kind ) or "unknown") end function notes.doifcontent(tag) diff --git a/tex/context/base/strc-not.mkii b/tex/context/base/strc-not.mkii new file mode 100644 index 000000000..40e06c9a4 --- /dev/null +++ b/tex/context/base/strc-not.mkii @@ -0,0 +1,1440 @@ +%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} + +\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..7dc998451 --- /dev/null +++ b/tex/context/base/strc-not.mkiv @@ -0,0 +1,1154 @@ +%D \module +%D [ file=strc-not, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Note Handling, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Note Handling} + +\registerctxluafile{strc-not}{1.001} + +\unprotect + +% obsolete + +\let\autopostponenotes\relax + +% removed: +% +% \pushsomestates +% +% core-ins -> obsolete +% +% saveinsertiondata +% restoreinsertiondata +% saveinsertionbox +% eraseinsertionbackup +% restoreinsertionbackup +% +% \def\doprocessnotescs#1#2% #1 == \cs that takes arg +% {\def\currentnote{#2}\@EA#1\csname\??vn:\currentnote\endcsname} +% \def\processnotescs#1{\processcommacommand[\noteinsertions]{\doprocessnotescs#1}} +% \def\noteinsertion #1{\csname\??vn:#1\endcsname} + +\def\savenotedata {\writestatus{todo}{save note data}} +\def\restorenotedata {\writestatus{todo}{restore note data}} +\def\savenotecontent {\writestatus{todo}{save note content}} +\def\restorenotecontent{\writestatus{todo}{restore note content}} +\def\erasenotebackup {\writestatus{todo}{erase note backup}} + +% page-set: + +\def\enablenotes {\writestatus{todo}{enable notes}} +\def\disablenotes {\writestatus{todo}{disable notes}} +\def\savenotes {\writestatus{todo}{save notes}} +\def\flushsavednotes{\writestatus{todo}{flush notes}} + +% experiment: (compare scope=text and scope=page) +% +% \definenote[mynote][way=bytext,location=text,width=\leftmarginwidth,scope=page,rule=,before=,after=,factor=0] +% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][] + +%D Footnotes are can be characterized by three components: +%D +%D \startitemize[packed] +%D \item a small number \footnote {a footnote number} or +%D symbol {\setupfootnotes [conversion=set 2]\footnote +%D {a footnote}} +%D \item and a similar mark at the bottom of the page +%D \item followed by some additional text +%D \stopitemize +%D +%D Because footnotes are declared at the location of their +%D reference they can be seen as a special kind of +%D floating bodies. Their placement is postponed but has to be +%D taken into account in the pagebreak calculations. This kind +%D of calculations are forced by using \type{\insert}s and dealing +%D with all cases is not trivial. + +%D \macros +%D {notesenabled} +%D +%D We need a couple of states because at some moments we don't want +%D to mess around with inserts at all. Take for instance a table +%D of contents. And so we can temporary disable footnotes by saying +%D +%D \starttyping +%D \notesenabledfalse +%D \stoptyping + +\newif\ifnotesenabled \notesenabledtrue + +\appendtoks \notesenabledfalse \to \everymarking + +%D Often we need to process the whole set of notes and to make that +%D fast, we use a token register: + +\newtoks\tobeprocessednotes + +\def\processnotes#1% #1: \macro that uses \currentnote + {\def\doprocesssomenote##1{\edef\currentdescription{##1}\edef\currentnote{##1}#1}% + \the\tobeprocessednotes} + +%D Notes have their own paremater handlers. The complication here +%D is that we use descriptions to typeset the note, so we have several +%D resolvers. + +\let\currentnote\v!footnote + +\def\noteparameter #1{\csname\donoteparameter{\??vn\currentnote}#1\endcsname} +\def\noteparameterhash#1{\donoteparameterhash {\??vn\currentnote}#1} + +\def\donoteparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\donoteparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\donoteparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\donoteparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\donoteparentparameter #1#2{\ifx#1\relax\s!empty\else\donoteparameter #1#2\fi} +\def\donoteparentparameterhash#1#2{\ifx#1\relax \else\donoteparameterhash#1#2\fi} + +\def\detokenizednoteparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??vn#1\endcsname}} + +\def\dosetnoteattributes#1#2% style color + {\edef\fontattributehash {\noteparameterhash#1}% + \edef\colorattributehash{\noteparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +%D \macros +%D {setupnote,setupnotedefinition} +%D +%D We can influence footnote typesetting with the setup +%D command: +%D +%D \showsetup{setupnotes} +%D \showsetup{setupnote} +%D +%D The definition command indicate that we can frame the footnote +%D area. The footnotes themselves are treated as descriptions. +%D +%D \showsetup{definenote} +%D +%D It's sort of a custom to precede footnotes by a horizontal +%D rule and although fancy rules like +%D +%D \starttyping +%D \hbox to 10em{\hskip-3em\dotfill} +%D \stoptyping +%D +%D Are quite ligitimate, we default to a simple one 20\% of the +%D text width. + +\def\setupnotes + {\dodoubleargument\getparameters[\??vn]} + +\setupnotes + [\c!location=\v!page, + \c!way=\v!by\v!part, + \c!sectionnumber=\v!no, + %\c!conversion=, + \c!rule=\v!on, + \c!before=\blank, + \c!bodyfont=\v!small, + %\c!style=, + %\c!color=, + %\c!after=, + %\c!rulecolor=, + \c!rulethickness=\linewidth, + \c!frame=\v!off, + \c!margindistance=.5em, + \c!columndistance=1em, + \c!distance=.125em, + \c!align=\v!normal, + \c!tolerance=\v!tolerant, + \c!split=\v!tolerant, + %\c!width=\makeupwidth, + %\c!width=\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi, + \c!width=\defaultnotewidth, + \c!height=\textheight, + \c!numbercommand=\high, + \c!command=\noteparameter\c!numbercommand, % downward compatible + \c!separator=,% \@@koseparator, + \c!textcommand=\high, + \c!textstyle=\tx, + %\c!textcolor=, + \c!interaction=\v!yes, + %\c!factor=, + %\c!scope=, % \v!text \v!page +\c!prefixconnector=., +\c!prefix=\v!no, + \c!next=\autoinsertnextspace, % new, experimental with startnotes + \c!n=1] + +\def\@@defaultnotedefloc{\v!inleft} +\def\@@defaultnotedefdis{\!!zeropoint} + +% also s!root +% +% \definedescription +% [\??vn\??vn] +% [\c!location=\@@defaultnotedefloc, +% \c!distance=\@@defaultnotedefdis, +% \c!width=\v!fit, +% \c!headstyle=\noteparameter\c!style, +% \c!headcolor=\noteparameter\c!color, +% \c!before=, +% \c!after=] + +\def\startnotedef{\resetdescriptions\csname\e!start\??vn\??vn\currentnote\endcsname} +\def\stopnotedef {\csname\e!stop \??vn\??vn\currentnote\endcsname} + +\def\currentnoteins{\csname\??vn:\currentnote\endcsname} + +\newtoks \everysetupnote + +\def\definenote + {\dodoubleempty\dodefinenote} + +\def\dodefinenote[#1][#2]% + {\edef\currentnote{#1}% + \ifcsname\??vn:\currentnote\endcsname\else + \@EA\installinsertion\csname\??vn:\currentnote\endcsname\relax + \appendtoks\doprocesssomenote{#1}\to\tobeprocessednotes + \fi + \defineenumeration % description + [\currentnote] + [\c!location=\@@defaultnotedefloc, + \c!distance=\@@defaultnotedefdis, + \c!width=\v!fit, + \c!headstyle=\noteparameter\c!style, + \c!headcolor=\noteparameter\c!color, +\s!handler=\v!note, + \c!text=, + \c!before=, + \c!after=]% + \setupenumerations + [\currentnote] + [\s!parent=\??vn\currentnote, + \c!number=\v!yes] % no inheritance from decriptions which is okay + \presetlocalframed + [\??vn\currentnote]% + \getparameters + [\??vn\currentnote] + [\s!parent=\??vn,#2]% + \definestructurecounter + [\currentnote]% + \ctxlua{structure.notes.define("\currentnote","insert",\number\csname\??vn:\currentnote\endcsname)}% + \the\everysetupnote} + +\let\setupnotedefinition\setupenumerations + +\appendtoks + \setupenumerations[\currentnote][]% +\to \everysetupnote + +\def\setupnote + {\dodoubleempty\dosetupnote} + +\def\dosetupnote[#1][#2]% + {\edef\currentnote{#1}% + \ifsecondargument + \getparameters[\??vn\currentnote][#2]% + \the\everysetupnote + \fi + \dochecknote} + +\appendtoks + \letvalue{\??vn\c!rule:\currentnote}\normalnoterule % hm +\to \everysetupnote + +\appendtoks + \processaction + [\noteparameter\c!rule] + [ \v!on=>\letvalue{\??vn\c!rule:\currentnote}\normalnoterule, + \v!off=>\letvalue{\??vn\c!rule:\currentnote}\relax, + \s!default=>\letvalue{\??vn\c!rule:\currentnote}\relax, + \s!unknown=>\setvalue{\??vn\c!rule:\currentnote}{\noteparameter\c!rule}]% +\to \everysetupnote + +\appendtoks + \processaction % todo + [\noteparameter\c!split] + [ \v!tolerant=>\notepenalty\zeropoint, + \v!strict=>\notepenalty9999, + \v!verystrict=>\notepenalty\maxdimen, + \s!default=>\notepenalty\zeropoint, + \s!unknown=>\notepenalty\commalistelement]% +\to \everysetupnote + +%D The following switch can be used to disable limiting the +%D height of the footnote area, something that is needed in +%D multi column balancing. Use this switch with care. + +\newif\ifnotelimit \notelimittrue % shared + +% bottomnotes endnotes +% clevernotes + +\appendtoks + \doifsomething{\noteparameter\c!factor} + {\ifnum\noteparameter\c!factor<\zerocount\else + \count\currentnoteins\noteparameter\c!factor + \fi}% +\to \everysetupnote + +% compatibility (will go away) + +\newif\ifendnotes +\newif\ifbottomnotes + +% locations: + +\def\s!noteloc{nodeloc} % 1=page 2=columns 3=lastcolumn 4=firstcolumn 5=none +\def\s!notepos{nodepos} % 0=nothing 1=high 2=bottom +\def\s!notefmt{nodefmt} % 1 text +\def\s!notecol{nodecol} + +\def\clevernotes % compatibility hack + {\numexpr\ifcase\noteparameter\s!noteloc\or0\or2\or2\or1\else0\fi\relax} + +\def\setnotelocation #1{\expandafter\chardef\csname\??vn\currentnote\s!noteloc\endcsname#1\relax} +\def\setnoteposition #1{\expandafter\chardef\csname\??vn\currentnote\s!notepos\endcsname#1\relax} +\def\setnoteformatting#1{\expandafter\chardef\csname\??vn\currentnote\s!notefmt\endcsname#1\relax} +\def\setnotecolumns #1{\expandafter\chardef\csname\??vn\currentnote\s!notecol\endcsname#1\relax} + +\def\currentnofcolumns{\@@kln} + +\def\dochecknote + {% node states + \setnotelocation\plusone + \setnoteposition\plustwo + \processallactionsinset + [\noteparameter\c!location] + [ \v!page=>\setnotelocation \plusone, + \v!columns=>\setnotelocation \plustwo, + \v!firstcolumn=>\setnotelocation \plusthree, + \v!lastcolumn=>\setnotelocation \plusfour, + \v!none=>\setnotelocation \plusfive, + \v!text=>\setnotelocation \plusfive + \setnoteformatting\plusone, % test + \v!high=>\setnoteposition \plusone, + \v!bottom=>\setnoteposition \plustwo]% + % compatibility hack + \ifnum\noteparameter\s!noteloc=\plusfive \endnotestrue \else \endnotesfalse \fi + \ifnum\noteparameter\s!notepos=\plustwo \bottomnotestrue \else \bottomnotesfalse \fi + % set column multiplier + \edef\currentnotenofcolumns{\noteparameter\c!n}% + \ifx\currentnotenofcolumns\empty + \let\currentnotenofcolumns\!!plusone + \fi + \ifcase\noteparameter\s!noteloc\or + % page + \scratchcounter \currentnotenofcolumns + \or + % columns + \scratchcounter\ifnum\currentnofcolumns=\zerocount \plusone \else \currentnotenofcolumns \fi \relax + \or + % firstcolumn + \scratchcounter\plusone + \or + % lastcolumn + \scratchcounter\plusone + \or + % text + \scratchcounter\currentnotenofcolumns + \fi + % column factor + \global\count\currentnoteins\plusthousand + \global\count\currentnoteins\numexpr\plusthousand/\scratchcounter\relax + % maximize height + \ifnotelimit + \global\dimen\currentnoteins\dimexpr\noteparameter\c!height*\scratchcounter\relax + \fi + % distance + \begingroup + \setbox\scratchbox\vbox + {\forgetall + \noteparameter\c!before + \placenoterule + \noteparameter\c!after}% + \global\skip\currentnoteins\ht\scratchbox + \endgroup + % play safe + \ifnum\noteparameter\s!noteloc=\plusfive + \ctxlua{structure.notes.setstate("\currentnote","store")}% + % text notes (e.g. end notes) but we don't use inserts anyway + \global\dimen\currentnoteins\maxdimen + \global\count\currentnoteins\zerocount + \global\skip \currentnoteins\zeropoint + \fi} + +\def\checknotes + {\processnotes\dochecknote} + +% D When \type{n} exceeds~1, footnotes are typeset in +% D multi||columns, using the algoritm presented on page~397 +% D of \TEX book. Footnotes can be places on a per page basis +% D or whereever suitable. When we set~\type{n} to~0, we get a +% D rearanged paragraph, typeset by the algoritms on pages 398 +% D and~389 (at least in \MKII). We definitely did not reinvent +% D that wheel. + +% Example of using factor: +% +% \definenote[mynote][way=bypage,location=text,width=\marginwidth,rule=,before=,factor=0] +% \setuplayout[backspace=5cm,margin=3cm,margindistance=.5cm,width=middle] +% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][] +% \starttext +% \dorecurse{10}{test \mynote{one one one one one one} \input zapf \mynote{one one one one one one} } +% \stoptext + +%D The noterule can be a graphic and therefore calling this +%D setup macro at every skipswitch is tricky (many many MP +%D runs). Let's just reserve a few points, that probably match +%D those of the stretch component. + +\def\placenoterule + {\getvalue{\??vn\c!rule:\currentnote}} + +\def\normalnoterule + {\ifvmode + \color + [\noteparameter\c!rulecolor] + {\hrule\!!width .2\hsize\!!height\noteparameter\c!rulethickness\!!depth \zeropoint}% + \kern\strutdepth + \fi} + +\ifx\setnotehsize\undefined + + \def\setnotehsize{\hsize\noteparameter\c!width\relax} % can be overloaded + +\fi + +%D The formatting depends on the width of the table, so we +%D have to set \type {n} to zero. +%D +%D \starttyping +%D \startbuffer +%D \bTABLE +%D \bTR \bTD one \footnote{\dorecurse{10}{abcd }} \eTD \bTD two \eTD \eTR +%D \bTR \bTD three fout five six seven eight nine \eTD \bTD ten \eTD \eTR +%D \eTABLE +%D \stopbuffer +%D +%D \startlocalfootnotes[n=0,location={text,none}] +%D \placelegend[n=2]{\getbuffer}{\placelocalfootnotes} +%D \stoplocalfootnotes +%D \stoptyping + +%D \macros +%D {footnote} +%D +%D A footnote can have a reference as optional argument and +%D therefore its formal specification looks like: +%D +%D \showsetup{footnote} +%D +%D This command has one optional command: the reference. By +%D saying \type{[-]} the number is omitted. The footnote +%D command is not that sensitive to spacing, so it's quite +%D legal to say: +%D +%D \startbuffer +%D Users of \CONTEXT\ must keep both feet \footnote{Given they +%D have two.} on the ground and not get confused \footnote{Or +%D even crazy.} by all those obscure \footnote{But fortunately +%D readable.} parameters. +%D \stopbuffer +%D +%D \typebuffer +%D +%D When setting the \type{conversion} to \type{set 2} we get +%D something like: +%D +%D \bgroup +%D \startnarrower +%D \setupfootnotes[conversion=set 1] +%D \getbuffer +%D \stopnarrower +%D \egroup +%D +%D Typesetting footnotes is, at least for the moment, disabled +%D when reshaping boxes. +%D +%D The additional macro \type {\footnotetext} and the +%D associated \type {\note} macro were implemented at +%D request of users on the mailing list and a suggestion by +%D taco to split of the symbol placement. I decided to +%D merge this functionality with the existing \type {\note} +%D functionality. + +%D The next implementation runs on top of enumerations (only in \MKIV). + +% TODO: \ifnotesenabled + +\newif\ifnotesymbol \notesymboltrue + +\def\setnote [#1]{\getvalue{#1}} +\def\setnotetext[#1]{\global\settrue\skipnoteplacement\getvalue{#1}} + +\def\domovednote#1#2#3#4% + {\ifcase\ctxlua{structure.notes.deltapage("#1",#2)}\or\symbol[#3]\or\symbol[#4]\fi} + +\setvalue{\??dd:\v!note:\s!handler }{\@@doenumerationhandler} +\setvalue{\??dd:\v!note:\s!handler:\s!do }{\@@somenotedescription} +\setvalue{\??dd:\v!note:\s!handler:\s!start}{\@@startsomenotedescription} + +\def\@@somenotedescription {\@@notemakedescription} +\def\@@startsomenotedescription{\@@notemakedescription} + +\newconditional\skipnoteplacement + +\def\@@notemakedescription[#1]#2#3% todo ... proper [key=value] etc + {\begingroup + \doenumerationcheckconditions + \let\currentnote\currentdescriptionmain + \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#3},\c!bookmark=,][]% + \xdef\currentnotenumber{\ctxlua{structure.notes.store("\currentnote",\currentdescriptionnumberentry)}}% + \settrue\processingnote + \ifconditional\skipnoteplacement + \globallet\lastnotesymbol\dolastnotesymbol + \else + \iftypesettinglines % otherwise problems with \type {xxx} + \ignorelines % makes footnotes work in \startlines ... \stoplines + \fi + \ifnotesymbol + \dolastnotesymbol + \else + \unskip\unskip + \globallet\lastnotesymbol\dolastnotesymbol + \fi + \fi + \ifconditional\postponingnotes + \global\settrue\postponednote + \else + \handlenoteinsert\currentnote\currentnotenumber + \fi + \ifconditional\skipnoteplacement \else + \kern\notesignal\relax % \relax is needed to honor spaces + \iftrialtypesetting \else \global\setfalse\skipnoteplacement \fi + \fi + \endgroup} + +\def\dolastnotesymbol{\typesetsomenotesymbol\currentnote\currentnotenumber} + +\def\dotypesetsomenotesymbol#1#2% + {\dodonotesymbol + {\synchronizesomenotesymbol{#1}{#2}% + \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry + \domovednote{#1}{#2}\v!previouspage\v!nextpage}} + +\def\typesetsomenotesymbol#1#2% + {\removeunwantedspaces + \doifitalicelse\/\donothing % Charles IV \footnote{the fourth} + \ifdim\lastkern=\notesignal + \dodonotesymbol{\kern\noteparameter\c!distance}% gets the font right, hack ! + \fi + \nobreak + \doifelse{\noteparameter\c!interaction}\v!no + {\dotypesetsomenotesymbol{#1}{#2}} + {\gotobox{\dotypesetsomenotesymbol{#1}{#2}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f: + \globallet\lastnotesymbol\relax} + +\def\currentnotedescriptiontext % todo: can be other number + {\ctxlua{structure.notes.title("\currentnote",\currentdescriptionnumberentry)}} + +\def\currentnoteenumerationfullnumber + {\doifelse{\noteparameter\c!interaction}\v!no + {\docurrentnoteenumerationfullnumber}% + {\gotobox + {\docurrentnoteenumerationfullnumber}% + [page(\ctxlua{structure.notes.getsymbolpage("\currentnote",\currentdescriptionnumberentry)})]}} + +\def\docurrentnoteenumerationfullnumber + {\noteparameter\c!numbercommand + {\ctxlua{structure.notes.number("\currentnote",\currentdescriptionnumberentry)}% + \domovednote\currentdescription\currentdescriptionnumberentry\v!nextpage\v!previouspage}} + +\def\synchronizesomenotesymbol#1#2% called more often than needed + {\expanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2)}}} + +\def\handlenoteinsert#1#2% + {\begingroup + \edef\currentnote{#1}% + \the\everybeforenoteinsert + \insert\currentnoteins\bgroup + \the\everyinsidenoteinsert + \handlenoteitself{#1}{#2}% + \egroup + \the\everyafternoteinsert + \endgroup} + +\def\handlenoteitself#1#2% tg, id + {\edef\currentdescription{#1}% + \edef\currentnote{#1}% + \edef\currentdescriptionnumberentry{#2}% + \let\currentdescriptiontext\currentnotedescriptiontext + \let\currentenumerationfullnumber\currentnoteenumerationfullnumber + \dostartstoreddescription\begstrut\currentnotedescriptiontext\endstrut\dostopstoreddescription} + +\def\dostartstoreddescription + {\bgroup\@@dostartdescriptionindeed} + +\def\dostopstoreddescription + {\@@stopdescription} + +%D The main typesetting routine is more or less the same as the +%D \PLAIN\ \TEX\ one, except that we only handle one type while +%D \PLAIN\ also has something \type{\v...}. In most cases +%D footnotes can be handled by a straight insert, but we do so +%D by using an indirect call to the \type{\insert} primitive. + +%D Making footnote numbers active is not always that logical, +%D Making footnote numbers active is not always that logical, +%D especially when we keep the reference and text at one page. +%D On the other hand we need interactivity when we refer to +%D previous notes or use end notes. Therefore we support +%D interactive footnote numbers in two ways \footnote{This +%D feature was implemented years after we were able to do so, +%D mainly because endnotes had to be supported.} that is, +%D automatically (vise versa) and by user supplied reference. + +\newcount\internalnotereference + +\let\startpushnote=\relax +\let\stoppushnote =\relax + +\newsignal\notesignal +\newcount \notepenalty + +\notepenalty=0 % needed in order to split in otrset + +\newconditional\processingnote +\newconditional\postponednote + +\newtoks\everybeforenoteinsert +\newtoks\everyinsidenoteinsert +\newtoks\everyafternoteinsert + +\appendtoks + \let\doflushnotes\relax + \let\postponenotes\relax + \forgetall +\to \everybeforenoteinsert + +\appendtoks + \doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment + \penalty\notepenalty + \forgetall + \setnotebodyfont + \redoconvertfont % to undo \undo calls in in headings etc + \splittopskip\strutht % not actually needed here + \splitmaxdepth\strutdp % not actually needed here + \leftmargindistance\noteparameter\c!margindistance + \rightmargindistance\leftmargindistance + \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ? + \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ? + \fi +\to \everyinsidenoteinsert + +\let\lastnotesymbol\relax + +%D \macros +%D {note} +%D +%D Refering to a note is accomplished by the rather short +%D command: +%D +%D \showsetup{note} +%D +%D This command is implemented rather straightforward as: + +\def\notesymbol + {\dodoubleempty\donotesymbol} + +\def\donotesymbol[#1][#2]% + {\bgroup + \ifnotesenabled + \edef\currentnote{#1}% + \ifsecondargument + \unskip + \dodonotesymbol{\in[#2]}% + \else + \dodonotesymbol\lastnotesymbol + \fi + \fi + \egroup} + +\def\dodonotesymbol#1% + {\noteparameter\c!textcommand{\dosetnoteattributes\c!textstyle\c!textcolor#1}} + +%D Normally footnotes are saved as inserts that are called upon +%D as soon as the pagebody is constructed. The footnote +%D insertion routine looks just like the \PLAIN\ \TEX\ one, +%D except that we check for the end note state. + +% testcase for split bottom alignment see (a) below +% +% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}} + +\def\placenoteinserts + {\processnotes\doplacenoteinserts} + +\def\unvboxed {\ifvmode\unvbox \else\box \fi} +\def\unvcopied{\ifvmode\unvcopy\else\copy\fi} + +\def\doplacenoteinserts + {\relax\ifdim\ht\currentnoteins>\zeropoint\relax + \ifnum\noteparameter\s!noteloc=\plusfive + \else + \endgraf + \ifvmode + \whitespace + \noteparameter\c!before + \fi + \placenoterule % alleen in ..mode + \bgroup + \setnotebodyfont + \setbox\scratchbox\hbox + {% this should be checked, smells like a mix-up + % does not split: \ifcase\noteparameter\c!n\unvbox\else\box\fi\currentnoteins + \ifcase\noteparameter\c!n\relax + \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins + \or + \iftrialtypesetting\copy\else\box\fi\currentnoteins + \obeydepth % (a) added , since split footnotes will not align properly + \else + \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins + \fi}% + \setbox\scratchbox\hbox + {\localframed + [\??vn\currentnote] + [\c!width=\v!fit, + \c!height=\v!fit, + \c!strut=\v!no, + \c!offset=\v!overlay] + {\ifdim\dp\scratchbox=\zeropoint % this hack is needed because \vadjust + \hbox{\lower\strutdp\box\scratchbox}% % in margin number placement + \else % hides the (always) present depth + \box\scratchbox + \fi}}% + \setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}% + \dp\scratchbox\strutdepth % so we know that it has the note bodyfont depth + \box\scratchbox + \egroup + \endgraf + \ifvmode + \noteparameter\c!after + \fi + \fi + \fi} + +%D Supporting end notes is surprisingly easy. Even better, we +%D can combine this feature with solving the common \TEX\ +%D problem of disappearing inserts when they're called for in +%D deeply nested boxes. The general case looks like: +%D +%D \starttyping +%D \postponenotes +%D \.box{whatever we want with footnotes} +%D \flushnotes +%D \stoptyping +%D +%D This alternative can be used in headings, captions, tables +%D etc. The latter one sometimes calls for notes local to +%D the table, which can be realized by saying +%D +%D \starttyping +%D \setlocalfootnotes +%D some kind of table with local footnotes +%D \placelocalfootnotes +%D \stoptyping +%D +%D Postponing is accomplished by simply redefining the (local) +%D insert operation. A not too robust method uses the +%D \type{\insert} primitive when possible. This method fails in +%D situations where it's not entirely clear in what mode \TEX\ +%D is. Therefore the auto method can is to be overruled when +%D needed. + +\newconditional\postponingnotes + +% we need a proper state: normal, postponing, flushing + +\def\postponenotes + {\ifconditional\postponingnotes\else + \global\settrue\postponingnotes + \ctxlua{structure.notes.postpone()}% + \fi} + +% \def\flushnotes +% {\ifconditional\processingnote \else +% \ifconditional\postponednote +% \ifinner \else +% \ifinpagebody \else +% %ifvmode % less interference, but also less secure +% \doflushnotes +% %fi +% \fi +% \fi +% \fi +% \fi} + +\def\flushnotes + {\ifconditional\postponednote + \flushnotesindeed + \fi} + +\def\flushnotesindeed + {\ifconditional\processingnote \else + \ifinner \else + \ifinpagebody \else + %ifvmode % less interference, but also less secure + \doflushnotes + %fi + \fi + \fi + \fi} + +\def\doflushnotes % also called directly, \ifvoid is needed ! + {\begingroup + \let\doflushnotes\relax + \let\postponenotes\relax + \ifconditional\processingnote \else + \ifconditional\postponednote + \processnotes\dodoflushnotes + \global\setfalse\postponednote + \setfalse\postponingnotes + \fi + \fi + \endgroup} + +\def\dodoflushnotes % per class, todo: handle endnotes here + {%\writestatus{notes}{flushing \currentnote}% + \global\setfalse\postponingnotes + \ctxlua{structure.notes.flush("\currentnote","postpone")}} + +%D \macros +%D {startlocalfootnotes,placelocalfootnotes} +%D +%D The next two macros can be used in for instance tables, as +%D we'll demonstrate later on. +%D +%D \showsetup{startlocalfootnotes} +%D \showsetup{placelocalfootnotes} + +% todo: compatibility mode: when first arg is assignment or missing, then all + +\newtoks\everyplacelocalnotes + +\appendtoks + \let\doflushnotes\relax + \let\postponenotes\relax +\to \everyplacelocalnotes + +\def\defaultnotewidth{\makeupwidth} % {\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi} + +\def\startlocalnotes + {\dosingleempty\dostartlocalnotes} + +\def\dostartlocalnotes[#1]% + {\def\localnoteslist{#1}% + \processcommacommand[\localnoteslist]\dodostartlocalnotes} + +\def\stoplocalnotes + {\processcommacommand[\localnoteslist]\dodostoplocalnotes} + +\def\dodostartlocalnotes#1% + {\savestructurecounter[#1]% + \resetstructurecounter[#1]% + \ctxlua{structure.notes.save("#1","store")}} + +\def\dodostoplocalnotes#1% + {\restorestructurecounter[#1]% + \ctxlua{structure.notes.restore("#1")}} + +\def\placelocalnotes + {\dodoubleempty\doplacelocalnotes} + +\def\doplacelocalnotes[#1][#2]% + {\doif{\ctxlua{structure.notes.getstate("#1")}}{store}{\dodoplacelocalnotes{#2}{#1}}} + +\def\dodoplacelocalnotes#1#2% settings note + {\begingroup + \the\everyplacelocalnotes + % beware, we cannot trust setting \currentnote here + \getparameters[\??vn#2][\c!width=\v!fit,\c!height=\v!fit,\c!strut=\v!no,\c!offset=\v!overlay,#1]% we only need a selective one + \donotealternative{#2}% + \endgroup + \dochecknote} % we need to restore the old state + +%D These commands can be used like: +%D +%D \startbuffer +%D \startlocalnotes[width=.3\hsize,n=0] +%D \placetable +%D {Some Table} +%D \placeontopofeachother +%D {\starttable[|l|r|] +%D \HL +%D \VL Nota\footnote{Bene} \VL Bene\footnote{Nota} \VL\SR +%D \VL Bene\footnote{Nota} \VL Nota\footnote{Bene} \VL\SR +%D \HL +%D \stoptable} +%D {\placelocalnotes} +%D \stoplocalnotes +%D \stopbuffer +%D +%D \typebuffer +%D +%D Because this table placement macro expect box content, and +%D thanks to the grouping of the local footnotes, we don't need +%D additional braces. +%D +%D \getbuffer + +%D \macros +%D {placefootnotes} +%D +%D We still have no decent command for placing footnotes +%D somewhere else than at the bottom of the page (for which no +%D user action is needed). Footnotes (endnotes) can be +%D placed by using +%D +%D \showsetup{placefootnotes} + +\def\placebottomnotes + {\processnotes\placenoteinserts} + +\def\placenotes + {\dodoubleempty\doplacenotes} + +\def\doplacenotes[#1][#2]% + {\processcommalist[#1]{\dodoplacenotes{#2}}} + +\def\dodoplacenotes#1#2% settings note + {\edef\currentnote{#2}% + \doifelse{\ctxlua{structure.notes.getstate("#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} + + \def\fakenotes + {\ifhmode\endgraf\fi\ifvmode + \calculatetotalclevernoteheight + \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi + \fi} + + \def\fakepagenotes + {\ifhmode\endgraf\fi\ifvmode + \calculatetotalpagenoteheight + \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi + \fi} + + \newdimen\totalnoteheight + + \def\doaddtototalnoteheight#1% + {\ifdim\ht#1>\zeropoint + \advance\totalnoteheight\ht #1% + \advance\totalnoteheight\skip#1% + \fi} + + \def\docalculatetotalnoteheight + {\ifcase\clevernotes % tricky here ! ! ! to be sorted out ! ! ! + \doaddtototalnoteheight\currentnoteins + \else + \doaddtototalnoteheight\currentbackupnoteins + \fi} + + \def\docalculatetotalclevernoteheight + {\ifcase\clevernotes \else % tricky here ! ! ! to be sorted out ! ! ! + \doaddtototalnoteheight\currentnoteins + \fi} + + \def\docalculatetotalpagenoteheight + {\doaddtototalnoteheight\currentnoteins} + + \def\calculatetotalnoteheight {\totalnoteheight\zeropoint\processnotes\docalculatetotalnoteheight} + \def\calculatetotalclevernoteheight{\totalnoteheight\zeropoint\processnotes\docalculatetotalclevernoteheight} + \def\calculatetotalpagenoteheight {\totalnoteheight\zeropoint\processnotes\docalculatetotalpagenoteheight} + + \newif\ifnotespresent + + \def\dochecknotepresence + {\ifdim\ht\currentnoteins>\zeropoint + \notespresenttrue + \fi} + + \def\checknotepresence + {\notespresentfalse + \processnotes\dochecknotepresence} + +%D Now how can this mechanism be hooked into \CONTEXT\ without +%D explictly postponing footnotes? The solution turned out to +%D be rather simple: +%D +%D \starttyping +%D \everypar {...\flushnotes...} +%D \neverypar {...\postponenotes} +%D \stoptyping +%D +%D and +%D +%D \starttyping +%D \def\ejectinsert% +%D {... +%D \flushnotes +%D ...} +%D \stoptyping +%D +%D We can use \type{\neverypar} because in most commands +%D sensitive to footnote gobbling we disable \type{\everypar} +%D in favor for \type{\neverypar}. In fact, this footnote +%D implementation is the first to use this scheme. + +%D This is a nasty and new secondary footnote flusher. It +%D can be hooked into \type {\everypar} like: +%D +%D \starttyping +%D \appendtoks \synchronizenotes \to \everypar +%D \stoptyping + + % \def\dosynchronizenotes + % {\ifvoid\currentnoteins\else\insert\currentnoteins{\unvbox\currentnoteins}\fi} + % + % \def\synchronizenotes + % {\processnotes\dosynchronizenotes} + +\let\synchronizenotes\relax + +%D When typesetting footnotes, we have to return to the +%D footnote specific bodyfont size, which is in most cases derived +%D from the global document bodyfont size. In the previous macros +%D we already used a footnote specific font setting macro. + +\def\setnotebodyfont + {\let\setnotebodyfont\relax + \restoreglobalbodyfont + \switchtobodyfont[\noteparameter\c!bodyfont]% + \setuptolerance[\noteparameter\c!tolerance]% + \setupalign[\noteparameter\c!align]} + +%D The footnote mechanism defaults to a traditional one +%D column way of showing them. By default we precede them by +%D a small line. + +\ifx\v!endnote\undefined \def\v!endnote{endnote} \fi + +\definenote [\v!footnote] +\definenote [\v!endnote ] [\c!location=\v!none] % else no break + +%D Compatibility macros: + + \def\setupfootnotedefinition{\setupnotedefinition [\v!footnote]} + \def\setupfootnotes {\setupnote [\v!footnote]} +%unexpanded \def\footnote {\setnote [\v!footnote]} +\unexpanded \def\footnotetext {\setnotetext [\v!footnote]} + %def\note {\dodoubleempty\notesymbol [\v!footnote]} % alleen footnote + \def\placefootnotes {\dodoubleempty\doplacefootnotes [\v!footnote]} + \def\placelocalfootnotes {\dodoubleempty\doplacelocalfootnotes[\v!footnote]} + \def\startlocalfootnotes {\startlocalnotes [\v!footnote]} % alleen footnote + \def\stoplocalfootnotes {\stoplocalnotes } + \def\flushfootnotes {\flushnotes} + \def\doflushfootnotes {\doflushnotes} + +\def\doplacefootnotes [#1][#2]{\ifsecondargument\placenotes [#1][#2,\c!height=\textheight]\else\placenotes [#1]\fi} +\def\doplacelocalfootnotes[#1][#2]{\ifsecondargument\placelocalnotes[#1][#2,\c!height=\textheight]\else\placelocalnotes[#1]\fi} + +\def\note{\dodoubleempty\donote} + +\def\donote[#1][#2]{\ifsecondargument\donotesymbol[#1][#2]\else\secondargumenttrue\donotesymbol[\v!footnote][#1]\fi} + +%D New trickery: + +\def\ownnotesymbol#1% #1 gets number passed + {\executeifdefined{\??vn::\currentnote}\empty} + +\def\setnotesymbol[#1]#2#3% + {\prewordbreak % prevent lookback + \setgvalue{\??vn::#1}{#3} + \dolastnotesymbol} + +\def\ownnote[#1]#2#3#4% + {\setnotesymbol[#1]{#2}{#3}% + \setnotetext [#1]{#4}} + +\defineconversion + [ownnote] + [\ownnotesymbol] + +\protect \endinput diff --git a/tex/context/base/strc-not.tex b/tex/context/base/strc-not.tex deleted file mode 100644 index ca0d3c0a4..000000000 --- a/tex/context/base/strc-not.tex +++ /dev/null @@ -1,1154 +0,0 @@ -%D \module -%D [ file=strc-not, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Note Handling, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Note Handling} - -\registerctxluafile{strc-not}{1.001} - -\unprotect - -% obsolete - -\let\autopostponenotes\relax - -% removed: -% -% \pushsomestates -% -% core-ins -> obsolete -% -% saveinsertiondata -% restoreinsertiondata -% saveinsertionbox -% eraseinsertionbackup -% restoreinsertionbackup -% -% \def\doprocessnotescs#1#2% #1 == \cs that takes arg -% {\def\currentnote{#2}\@EA#1\csname\??vn:\currentnote\endcsname} -% \def\processnotescs#1{\processcommacommand[\noteinsertions]{\doprocessnotescs#1}} -% \def\noteinsertion #1{\csname\??vn:#1\endcsname} - -\def\savenotedata {\writestatus{todo}{save note data}} -\def\restorenotedata {\writestatus{todo}{restore note data}} -\def\savenotecontent {\writestatus{todo}{save note content}} -\def\restorenotecontent{\writestatus{todo}{restore note content}} -\def\erasenotebackup {\writestatus{todo}{erase note backup}} - -% page-set: - -\def\enablenotes {\writestatus{todo}{enable notes}} -\def\disablenotes {\writestatus{todo}{disable notes}} -\def\savenotes {\writestatus{todo}{save notes}} -\def\flushsavednotes{\writestatus{todo}{flush notes}} - -% experiment: (compare scope=text and scope=page) -% -% \definenote[mynote][way=bytext,location=text,width=\leftmarginwidth,scope=page,rule=,before=,after=,factor=0] -% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][] - -%D Footnotes are can be characterized by three components: -%D -%D \startitemize[packed] -%D \item a small number \footnote {a footnote number} or -%D symbol {\setupfootnotes [conversion=set 2]\footnote -%D {a footnote}} -%D \item and a similar mark at the bottom of the page -%D \item followed by some additional text -%D \stopitemize -%D -%D Because footnotes are declared at the location of their -%D reference they can be seen as a special kind of -%D floating bodies. Their placement is postponed but has to be -%D taken into account in the pagebreak calculations. This kind -%D of calculations are forced by using \type{\insert}s and dealing -%D with all cases is not trivial. - -%D \macros -%D {notesenabled} -%D -%D We need a couple of states because at some moments we don't want -%D to mess around with inserts at all. Take for instance a table -%D of contents. And so we can temporary disable footnotes by saying -%D -%D \starttyping -%D \notesenabledfalse -%D \stoptyping - -\newif\ifnotesenabled \notesenabledtrue - -\appendtoks \notesenabledfalse \to \everymarking - -%D Often we need to process the whole set of notes and to make that -%D fast, we use a token register: - -\newtoks\tobeprocessednotes - -\def\processnotes#1% #1: \macro that uses \currentnote - {\def\doprocesssomenote##1{\edef\currentdescription{##1}\edef\currentnote{##1}#1}% - \the\tobeprocessednotes} - -%D Notes have their own paremater handlers. The complication here -%D is that we use descriptions to typeset the note, so we have several -%D resolvers. - -\let\currentnote\v!footnote - -\def\noteparameter #1{\csname\donoteparameter{\??vn\currentnote}#1\endcsname} -\def\noteparameterhash#1{\donoteparameterhash {\??vn\currentnote}#1} - -\def\donoteparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\donoteparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\donoteparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\donoteparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\donoteparentparameter #1#2{\ifx#1\relax\s!empty\else\donoteparameter #1#2\fi} -\def\donoteparentparameterhash#1#2{\ifx#1\relax \else\donoteparameterhash#1#2\fi} - -\def\detokenizednoteparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??vn#1\endcsname}} - -\def\dosetnoteattributes#1#2% style color - {\edef\fontattributehash {\noteparameterhash#1}% - \edef\colorattributehash{\noteparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -%D \macros -%D {setupnote,setupnotedefinition} -%D -%D We can influence footnote typesetting with the setup -%D command: -%D -%D \showsetup{setupnotes} -%D \showsetup{setupnote} -%D -%D The definition command indicate that we can frame the footnote -%D area. The footnotes themselves are treated as descriptions. -%D -%D \showsetup{definenote} -%D -%D It's sort of a custom to precede footnotes by a horizontal -%D rule and although fancy rules like -%D -%D \starttyping -%D \hbox to 10em{\hskip-3em\dotfill} -%D \stoptyping -%D -%D Are quite ligitimate, we default to a simple one 20\% of the -%D text width. - -\def\setupnotes - {\dodoubleargument\getparameters[\??vn]} - -\setupnotes - [\c!location=\v!page, - \c!way=\v!by\v!part, - \c!sectionnumber=\v!no, - %\c!conversion=, - \c!rule=\v!on, - \c!before=\blank, - \c!bodyfont=\v!small, - %\c!style=, - %\c!color=, - %\c!after=, - %\c!rulecolor=, - \c!rulethickness=\linewidth, - \c!frame=\v!off, - \c!margindistance=.5em, - \c!columndistance=1em, - \c!distance=.125em, - \c!align=\v!normal, - \c!tolerance=\v!tolerant, - \c!split=\v!tolerant, - %\c!width=\makeupwidth, - %\c!width=\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi, - \c!width=\defaultnotewidth, - \c!height=\textheight, - \c!numbercommand=\high, - \c!command=\noteparameter\c!numbercommand, % downward compatible - \c!separator=,% \@@koseparator, - \c!textcommand=\high, - \c!textstyle=\tx, - %\c!textcolor=, - \c!interaction=\v!yes, - %\c!factor=, - %\c!scope=, % \v!text \v!page -\c!prefixconnector=., -\c!prefix=\v!no, - \c!next=\autoinsertnextspace, % new, experimental with startnotes - \c!n=1] - -\def\@@defaultnotedefloc{\v!inleft} -\def\@@defaultnotedefdis{\!!zeropoint} - -% also s!root -% -% \definedescription -% [\??vn\??vn] -% [\c!location=\@@defaultnotedefloc, -% \c!distance=\@@defaultnotedefdis, -% \c!width=\v!fit, -% \c!headstyle=\noteparameter\c!style, -% \c!headcolor=\noteparameter\c!color, -% \c!before=, -% \c!after=] - -\def\startnotedef{\resetdescriptions\csname\e!start\??vn\??vn\currentnote\endcsname} -\def\stopnotedef {\csname\e!stop \??vn\??vn\currentnote\endcsname} - -\def\currentnoteins{\csname\??vn:\currentnote\endcsname} - -\newtoks \everysetupnote - -\def\definenote - {\dodoubleempty\dodefinenote} - -\def\dodefinenote[#1][#2]% - {\edef\currentnote{#1}% - \ifcsname\??vn:\currentnote\endcsname\else - \@EA\installinsertion\csname\??vn:\currentnote\endcsname\relax - \appendtoks\doprocesssomenote{#1}\to\tobeprocessednotes - \fi - \defineenumeration % description - [\currentnote] - [\c!location=\@@defaultnotedefloc, - \c!distance=\@@defaultnotedefdis, - \c!width=\v!fit, - \c!headstyle=\noteparameter\c!style, - \c!headcolor=\noteparameter\c!color, -\s!handler=\v!note, - \c!text=, - \c!before=, - \c!after=]% - \setupenumerations - [\currentnote] - [\s!parent=\??vn\currentnote, - \c!number=\v!yes] % no inheritance from decriptions which is okay - \presetlocalframed - [\??vn\currentnote]% - \getparameters - [\??vn\currentnote] - [\s!parent=\??vn,#2]% - \definestructurecounter - [\currentnote]% - \ctxlua{structure.notes.define("\currentnote","insert",\number\csname\??vn:\currentnote\endcsname)}% - \the\everysetupnote} - -\let\setupnotedefinition\setupenumerations - -\appendtoks - \setupenumerations[\currentnote][]% -\to \everysetupnote - -\def\setupnote - {\dodoubleempty\dosetupnote} - -\def\dosetupnote[#1][#2]% - {\edef\currentnote{#1}% - \ifsecondargument - \getparameters[\??vn\currentnote][#2]% - \the\everysetupnote - \fi - \dochecknote} - -\appendtoks - \letvalue{\??vn\c!rule:\currentnote}\normalnoterule % hm -\to \everysetupnote - -\appendtoks - \processaction - [\noteparameter\c!rule] - [ \v!on=>\letvalue{\??vn\c!rule:\currentnote}\normalnoterule, - \v!off=>\letvalue{\??vn\c!rule:\currentnote}\relax, - \s!default=>\letvalue{\??vn\c!rule:\currentnote}\relax, - \s!unknown=>\setvalue{\??vn\c!rule:\currentnote}{\noteparameter\c!rule}]% -\to \everysetupnote - -\appendtoks - \processaction % todo - [\noteparameter\c!split] - [ \v!tolerant=>\notepenalty\zeropoint, - \v!strict=>\notepenalty9999, - \v!verystrict=>\notepenalty\maxdimen, - \s!default=>\notepenalty\zeropoint, - \s!unknown=>\notepenalty\commalistelement]% -\to \everysetupnote - -%D The following switch can be used to disable limiting the -%D height of the footnote area, something that is needed in -%D multi column balancing. Use this switch with care. - -\newif\ifnotelimit \notelimittrue % shared - -% bottomnotes endnotes -% clevernotes - -\appendtoks - \doifsomething{\noteparameter\c!factor} - {\ifnum\noteparameter\c!factor<\zerocount\else - \count\currentnoteins\noteparameter\c!factor - \fi}% -\to \everysetupnote - -% compatibility (will go away) - -\newif\ifendnotes -\newif\ifbottomnotes - -% locations: - -\def\s!noteloc{nodeloc} % 1=page 2=columns 3=lastcolumn 4=firstcolumn 5=none -\def\s!notepos{nodepos} % 0=nothing 1=high 2=bottom -\def\s!notefmt{nodefmt} % 1 text -\def\s!notecol{nodecol} - -\def\clevernotes % compatibility hack - {\numexpr\ifcase\noteparameter\s!noteloc\or0\or2\or2\or1\else0\fi\relax} - -\def\setnotelocation #1{\expandafter\chardef\csname\??vn\currentnote\s!noteloc\endcsname#1\relax} -\def\setnoteposition #1{\expandafter\chardef\csname\??vn\currentnote\s!notepos\endcsname#1\relax} -\def\setnoteformatting#1{\expandafter\chardef\csname\??vn\currentnote\s!notefmt\endcsname#1\relax} -\def\setnotecolumns #1{\expandafter\chardef\csname\??vn\currentnote\s!notecol\endcsname#1\relax} - -\def\currentnofcolumns{\@@kln} - -\def\dochecknote - {% node states - \setnotelocation\plusone - \setnoteposition\plustwo - \processallactionsinset - [\noteparameter\c!location] - [ \v!page=>\setnotelocation \plusone, - \v!columns=>\setnotelocation \plustwo, - \v!firstcolumn=>\setnotelocation \plusthree, - \v!lastcolumn=>\setnotelocation \plusfour, - \v!none=>\setnotelocation \plusfive, - \v!text=>\setnotelocation \plusfive - \setnoteformatting\plusone, % test - \v!high=>\setnoteposition \plusone, - \v!bottom=>\setnoteposition \plustwo]% - % compatibility hack - \ifnum\noteparameter\s!noteloc=\plusfive \endnotestrue \else \endnotesfalse \fi - \ifnum\noteparameter\s!notepos=\plustwo \bottomnotestrue \else \bottomnotesfalse \fi - % set column multiplier - \edef\currentnotenofcolumns{\noteparameter\c!n}% - \ifx\currentnotenofcolumns\empty - \let\currentnotenofcolumns\!!plusone - \fi - \ifcase\noteparameter\s!noteloc\or - % page - \scratchcounter \currentnotenofcolumns - \or - % columns - \scratchcounter\ifnum\currentnofcolumns=\zerocount \plusone \else \currentnotenofcolumns \fi \relax - \or - % firstcolumn - \scratchcounter\plusone - \or - % lastcolumn - \scratchcounter\plusone - \or - % text - \scratchcounter\currentnotenofcolumns - \fi - % column factor - \global\count\currentnoteins\plusthousand - \global\count\currentnoteins\numexpr\plusthousand/\scratchcounter\relax - % maximize height - \ifnotelimit - \global\dimen\currentnoteins\dimexpr\noteparameter\c!height*\scratchcounter\relax - \fi - % distance - \begingroup - \setbox\scratchbox\vbox - {\forgetall - \noteparameter\c!before - \placenoterule - \noteparameter\c!after}% - \global\skip\currentnoteins\ht\scratchbox - \endgroup - % play safe - \ifnum\noteparameter\s!noteloc=\plusfive - \ctxlua{structure.notes.setstate("\currentnote","store")}% - % text notes (e.g. end notes) but we don't use inserts anyway - \global\dimen\currentnoteins\maxdimen - \global\count\currentnoteins\zerocount - \global\skip \currentnoteins\zeropoint - \fi} - -\def\checknotes - {\processnotes\dochecknote} - -% D When \type{n} exceeds~1, footnotes are typeset in -% D multi||columns, using the algoritm presented on page~397 -% D of \TEX book. Footnotes can be places on a per page basis -% D or whereever suitable. When we set~\type{n} to~0, we get a -% D rearanged paragraph, typeset by the algoritms on pages 398 -% D and~389 (at least in \MKII). We definitely did not reinvent -% D that wheel. - -% Example of using factor: -% -% \definenote[mynote][way=bypage,location=text,width=\marginwidth,rule=,before=,factor=0] -% \setuplayout[backspace=5cm,margin=3cm,margindistance=.5cm,width=middle] -% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][] -% \starttext -% \dorecurse{10}{test \mynote{one one one one one one} \input zapf \mynote{one one one one one one} } -% \stoptext - -%D The noterule can be a graphic and therefore calling this -%D setup macro at every skipswitch is tricky (many many MP -%D runs). Let's just reserve a few points, that probably match -%D those of the stretch component. - -\def\placenoterule - {\getvalue{\??vn\c!rule:\currentnote}} - -\def\normalnoterule - {\ifvmode - \color - [\noteparameter\c!rulecolor] - {\hrule\!!width .2\hsize\!!height\noteparameter\c!rulethickness\!!depth \zeropoint}% - \kern\strutdepth - \fi} - -\ifx\setnotehsize\undefined - - \def\setnotehsize{\hsize\noteparameter\c!width\relax} % can be overloaded - -\fi - -%D The formatting depends on the width of the table, so we -%D have to set \type {n} to zero. -%D -%D \starttyping -%D \startbuffer -%D \bTABLE -%D \bTR \bTD one \footnote{\dorecurse{10}{abcd }} \eTD \bTD two \eTD \eTR -%D \bTR \bTD three fout five six seven eight nine \eTD \bTD ten \eTD \eTR -%D \eTABLE -%D \stopbuffer -%D -%D \startlocalfootnotes[n=0,location={text,none}] -%D \placelegend[n=2]{\getbuffer}{\placelocalfootnotes} -%D \stoplocalfootnotes -%D \stoptyping - -%D \macros -%D {footnote} -%D -%D A footnote can have a reference as optional argument and -%D therefore its formal specification looks like: -%D -%D \showsetup{footnote} -%D -%D This command has one optional command: the reference. By -%D saying \type{[-]} the number is omitted. The footnote -%D command is not that sensitive to spacing, so it's quite -%D legal to say: -%D -%D \startbuffer -%D Users of \CONTEXT\ must keep both feet \footnote{Given they -%D have two.} on the ground and not get confused \footnote{Or -%D even crazy.} by all those obscure \footnote{But fortunately -%D readable.} parameters. -%D \stopbuffer -%D -%D \typebuffer -%D -%D When setting the \type{conversion} to \type{set 2} we get -%D something like: -%D -%D \bgroup -%D \startnarrower -%D \setupfootnotes[conversion=set 1] -%D \getbuffer -%D \stopnarrower -%D \egroup -%D -%D Typesetting footnotes is, at least for the moment, disabled -%D when reshaping boxes. -%D -%D The additional macro \type {\footnotetext} and the -%D associated \type {\note} macro were implemented at -%D request of users on the mailing list and a suggestion by -%D taco to split of the symbol placement. I decided to -%D merge this functionality with the existing \type {\note} -%D functionality. - -%D The next implementation runs on top of enumerations (only in \MKIV). - -% TODO: \ifnotesenabled - -\newif\ifnotesymbol \notesymboltrue - -\def\setnote [#1]{\getvalue{#1}} -\def\setnotetext[#1]{\global\settrue\skipnoteplacement\getvalue{#1}} - -\def\domovednote#1#2#3#4% - {\ifcase\ctxlua{structure.notes.deltapage("#1",#2)}\or\symbol[#3]\or\symbol[#4]\fi} - -\setvalue{\??dd:\v!note:\s!handler }{\@@doenumerationhandler} -\setvalue{\??dd:\v!note:\s!handler:\s!do }{\@@somenotedescription} -\setvalue{\??dd:\v!note:\s!handler:\s!start}{\@@startsomenotedescription} - -\def\@@somenotedescription {\@@notemakedescription} -\def\@@startsomenotedescription{\@@notemakedescription} - -\newconditional\skipnoteplacement - -\def\@@notemakedescription[#1]#2#3% todo ... proper [key=value] etc - {\begingroup - \doenumerationcheckconditions - \let\currentnote\currentdescriptionmain - \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#3},\c!bookmark=,][]% - \xdef\currentnotenumber{\ctxlua{structure.notes.store("\currentnote",\currentdescriptionnumberentry)}}% - \settrue\processingnote - \ifconditional\skipnoteplacement - \globallet\lastnotesymbol\dolastnotesymbol - \else - \iftypesettinglines % otherwise problems with \type {xxx} - \ignorelines % makes footnotes work in \startlines ... \stoplines - \fi - \ifnotesymbol - \dolastnotesymbol - \else - \unskip\unskip - \globallet\lastnotesymbol\dolastnotesymbol - \fi - \fi - \ifconditional\postponingnotes - \global\settrue\postponednote - \else - \handlenoteinsert\currentnote\currentnotenumber - \fi - \ifconditional\skipnoteplacement \else - \kern\notesignal\relax % \relax is needed to honor spaces - \iftrialtypesetting \else \global\setfalse\skipnoteplacement \fi - \fi - \endgroup} - -\def\dolastnotesymbol{\typesetsomenotesymbol\currentnote\currentnotenumber} - -\def\dotypesetsomenotesymbol#1#2% - {\dodonotesymbol - {\synchronizesomenotesymbol{#1}{#2}% - \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry - \domovednote{#1}{#2}\v!previouspage\v!nextpage}} - -\def\typesetsomenotesymbol#1#2% - {\removeunwantedspaces - \doifitalicelse\/\donothing % Charles IV \footnote{the fourth} - \ifdim\lastkern=\notesignal - \dodonotesymbol{\kern\noteparameter\c!distance}% gets the font right, hack ! - \fi - \nobreak - \doifelse{\noteparameter\c!interaction}\v!no - {\dotypesetsomenotesymbol{#1}{#2}} - {\gotobox{\dotypesetsomenotesymbol{#1}{#2}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f: - \globallet\lastnotesymbol\relax} - -\def\currentnotedescriptiontext % todo: can be other number - {\ctxlua{structure.notes.title("\currentnote",\currentdescriptionnumberentry)}} - -\def\currentnoteenumerationfullnumber - {\doifelse{\noteparameter\c!interaction}\v!no - {\docurrentnoteenumerationfullnumber}% - {\gotobox - {\docurrentnoteenumerationfullnumber}% - [page(\ctxlua{structure.notes.getsymbolpage("\currentnote",\currentdescriptionnumberentry)})]}} - -\def\docurrentnoteenumerationfullnumber - {\noteparameter\c!numbercommand - {\ctxlua{structure.notes.number("\currentnote",\currentdescriptionnumberentry)}% - \domovednote\currentdescription\currentdescriptionnumberentry\v!nextpage\v!previouspage}} - -\def\synchronizesomenotesymbol#1#2% called more often than needed - {\expanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2)}}} - -\def\handlenoteinsert#1#2% - {\begingroup - \edef\currentnote{#1}% - \the\everybeforenoteinsert - \insert\currentnoteins\bgroup - \the\everyinsidenoteinsert - \handlenoteitself{#1}{#2}% - \egroup - \the\everyafternoteinsert - \endgroup} - -\def\handlenoteitself#1#2% tg, id - {\edef\currentdescription{#1}% - \edef\currentnote{#1}% - \edef\currentdescriptionnumberentry{#2}% - \let\currentdescriptiontext\currentnotedescriptiontext - \let\currentenumerationfullnumber\currentnoteenumerationfullnumber - \dostartstoreddescription\begstrut\currentnotedescriptiontext\endstrut\dostopstoreddescription} - -\def\dostartstoreddescription - {\bgroup\@@dostartdescriptionindeed} - -\def\dostopstoreddescription - {\@@stopdescription} - -%D The main typesetting routine is more or less the same as the -%D \PLAIN\ \TEX\ one, except that we only handle one type while -%D \PLAIN\ also has something \type{\v...}. In most cases -%D footnotes can be handled by a straight insert, but we do so -%D by using an indirect call to the \type{\insert} primitive. - -%D Making footnote numbers active is not always that logical, -%D Making footnote numbers active is not always that logical, -%D especially when we keep the reference and text at one page. -%D On the other hand we need interactivity when we refer to -%D previous notes or use end notes. Therefore we support -%D interactive footnote numbers in two ways \footnote{This -%D feature was implemented years after we were able to do so, -%D mainly because endnotes had to be supported.} that is, -%D automatically (vise versa) and by user supplied reference. - -\newcount\internalnotereference - -\let\startpushnote=\relax -\let\stoppushnote =\relax - -\newsignal\notesignal -\newcount \notepenalty - -\notepenalty=0 % needed in order to split in otrset - -\newconditional\processingnote -\newconditional\postponednote - -\newtoks\everybeforenoteinsert -\newtoks\everyinsidenoteinsert -\newtoks\everyafternoteinsert - -\appendtoks - \let\doflushnotes\relax - \let\postponenotes\relax - \forgetall -\to \everybeforenoteinsert - -\appendtoks - \doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment - \penalty\notepenalty - \forgetall - \setnotebodyfont - \redoconvertfont % to undo \undo calls in in headings etc - \splittopskip\strutht % not actually needed here - \splitmaxdepth\strutdp % not actually needed here - \leftmargindistance\noteparameter\c!margindistance - \rightmargindistance\leftmargindistance - \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ? - \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ? - \fi -\to \everyinsidenoteinsert - -\let\lastnotesymbol\relax - -%D \macros -%D {note} -%D -%D Refering to a note is accomplished by the rather short -%D command: -%D -%D \showsetup{note} -%D -%D This command is implemented rather straightforward as: - -\def\notesymbol - {\dodoubleempty\donotesymbol} - -\def\donotesymbol[#1][#2]% - {\bgroup - \ifnotesenabled - \edef\currentnote{#1}% - \ifsecondargument - \unskip - \dodonotesymbol{\in[#2]}% - \else - \dodonotesymbol\lastnotesymbol - \fi - \fi - \egroup} - -\def\dodonotesymbol#1% - {\noteparameter\c!textcommand{\dosetnoteattributes\c!textstyle\c!textcolor#1}} - -%D Normally footnotes are saved as inserts that are called upon -%D as soon as the pagebody is constructed. The footnote -%D insertion routine looks just like the \PLAIN\ \TEX\ one, -%D except that we check for the end note state. - -% testcase for split bottom alignment see (a) below -% -% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}} - -\def\placenoteinserts - {\processnotes\doplacenoteinserts} - -\def\unvboxed {\ifvmode\unvbox \else\box \fi} -\def\unvcopied{\ifvmode\unvcopy\else\copy\fi} - -\def\doplacenoteinserts - {\relax\ifdim\ht\currentnoteins>\zeropoint\relax - \ifnum\noteparameter\s!noteloc=\plusfive - \else - \endgraf - \ifvmode - \whitespace - \noteparameter\c!before - \fi - \placenoterule % alleen in ..mode - \bgroup - \setnotebodyfont - \setbox\scratchbox\hbox - {% this should be checked, smells like a mix-up - % does not split: \ifcase\noteparameter\c!n\unvbox\else\box\fi\currentnoteins - \ifcase\noteparameter\c!n\relax - \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins - \or - \iftrialtypesetting\copy\else\box\fi\currentnoteins - \obeydepth % (a) added , since split footnotes will not align properly - \else - \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins - \fi}% - \setbox\scratchbox\hbox - {\localframed - [\??vn\currentnote] - [\c!width=\v!fit, - \c!height=\v!fit, - \c!strut=\v!no, - \c!offset=\v!overlay] - {\ifdim\dp\scratchbox=\zeropoint % this hack is needed because \vadjust - \hbox{\lower\strutdp\box\scratchbox}% % in margin number placement - \else % hides the (always) present depth - \box\scratchbox - \fi}}% - \setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}% - \dp\scratchbox\strutdepth % so we know that it has the note bodyfont depth - \box\scratchbox - \egroup - \endgraf - \ifvmode - \noteparameter\c!after - \fi - \fi - \fi} - -%D Supporting end notes is surprisingly easy. Even better, we -%D can combine this feature with solving the common \TEX\ -%D problem of disappearing inserts when they're called for in -%D deeply nested boxes. The general case looks like: -%D -%D \starttyping -%D \postponenotes -%D \.box{whatever we want with footnotes} -%D \flushnotes -%D \stoptyping -%D -%D This alternative can be used in headings, captions, tables -%D etc. The latter one sometimes calls for notes local to -%D the table, which can be realized by saying -%D -%D \starttyping -%D \setlocalfootnotes -%D some kind of table with local footnotes -%D \placelocalfootnotes -%D \stoptyping -%D -%D Postponing is accomplished by simply redefining the (local) -%D insert operation. A not too robust method uses the -%D \type{\insert} primitive when possible. This method fails in -%D situations where it's not entirely clear in what mode \TEX\ -%D is. Therefore the auto method can is to be overruled when -%D needed. - -\newconditional\postponingnotes - -% we need a proper state: normal, postponing, flushing - -\def\postponenotes - {\ifconditional\postponingnotes\else - \global\settrue\postponingnotes - \ctxlua{structure.notes.postpone()}% - \fi} - -% \def\flushnotes -% {\ifconditional\processingnote \else -% \ifconditional\postponednote -% \ifinner \else -% \ifinpagebody \else -% %ifvmode % less interference, but also less secure -% \doflushnotes -% %fi -% \fi -% \fi -% \fi -% \fi} - -\def\flushnotes - {\ifconditional\postponednote - \flushnotesindeed - \fi} - -\def\flushnotesindeed - {\ifconditional\processingnote \else - \ifinner \else - \ifinpagebody \else - %ifvmode % less interference, but also less secure - \doflushnotes - %fi - \fi - \fi - \fi} - -\def\doflushnotes % also called directly, \ifvoid is needed ! - {\begingroup - \let\doflushnotes\relax - \let\postponenotes\relax - \ifconditional\processingnote \else - \ifconditional\postponednote - \processnotes\dodoflushnotes - \global\setfalse\postponednote - \setfalse\postponingnotes - \fi - \fi - \endgroup} - -\def\dodoflushnotes % per class, todo: handle endnotes here - {%\writestatus{notes}{flushing \currentnote}% - \global\setfalse\postponingnotes - \ctxlua{structure.notes.flush("\currentnote","postpone")}} - -%D \macros -%D {startlocalfootnotes,placelocalfootnotes} -%D -%D The next two macros can be used in for instance tables, as -%D we'll demonstrate later on. -%D -%D \showsetup{startlocalfootnotes} -%D \showsetup{placelocalfootnotes} - -% todo: compatibility mode: when first arg is assignment or missing, then all - -\newtoks\everyplacelocalnotes - -\appendtoks - \let\doflushnotes\relax - \let\postponenotes\relax -\to \everyplacelocalnotes - -\def\defaultnotewidth{\makeupwidth} % {\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi} - -\def\startlocalnotes - {\dosingleempty\dostartlocalnotes} - -\def\dostartlocalnotes[#1]% - {\def\localnoteslist{#1}% - \processcommacommand[\localnoteslist]\dodostartlocalnotes} - -\def\stoplocalnotes - {\processcommacommand[\localnoteslist]\dodostoplocalnotes} - -\def\dodostartlocalnotes#1% - {\savestructurecounter[#1]% - \resetstructurecounter[#1]% - \ctxlua{structure.notes.save("#1","store")}} - -\def\dodostoplocalnotes#1% - {\restorestructurecounter[#1]% - \ctxlua{structure.notes.restore("#1")}} - -\def\placelocalnotes - {\dodoubleempty\doplacelocalnotes} - -\def\doplacelocalnotes[#1][#2]% - {\doif{\ctxlua{structure.notes.getstate("#1")}}{store}{\dodoplacelocalnotes{#2}{#1}}} - -\def\dodoplacelocalnotes#1#2% settings note - {\begingroup - \the\everyplacelocalnotes - % beware, we cannot trust setting \currentnote here - \getparameters[\??vn#2][\c!width=\v!fit,\c!height=\v!fit,\c!strut=\v!no,\c!offset=\v!overlay,#1]% we only need a selective one - \donotealternative{#2}% - \endgroup - \dochecknote} % we need to restore the old state - -%D These commands can be used like: -%D -%D \startbuffer -%D \startlocalnotes[width=.3\hsize,n=0] -%D \placetable -%D {Some Table} -%D \placeontopofeachother -%D {\starttable[|l|r|] -%D \HL -%D \VL Nota\footnote{Bene} \VL Bene\footnote{Nota} \VL\SR -%D \VL Bene\footnote{Nota} \VL Nota\footnote{Bene} \VL\SR -%D \HL -%D \stoptable} -%D {\placelocalnotes} -%D \stoplocalnotes -%D \stopbuffer -%D -%D \typebuffer -%D -%D Because this table placement macro expect box content, and -%D thanks to the grouping of the local footnotes, we don't need -%D additional braces. -%D -%D \getbuffer - -%D \macros -%D {placefootnotes} -%D -%D We still have no decent command for placing footnotes -%D somewhere else than at the bottom of the page (for which no -%D user action is needed). Footnotes (endnotes) can be -%D placed by using -%D -%D \showsetup{placefootnotes} - -\def\placebottomnotes - {\processnotes\placenoteinserts} - -\def\placenotes - {\dodoubleempty\doplacenotes} - -\def\doplacenotes[#1][#2]% - {\processcommalist[#1]{\dodoplacenotes{#2}}} - -\def\dodoplacenotes#1#2% settings note - {\edef\currentnote{#2}% - \doifelse{\ctxlua{structure.notes.getstate("#1")}}{store} - \dodoplacelocalnotes - \dodoplaceglobalnotes - {#1}{#2}} - -\def\dodoplaceglobalnotes#1#2% - {\begingroup - \setupnote[#2][#1]% - \doplacenoteinserts - \endgroup - \the\everysetupnote} % to be checkes - -%D Placement - -\long\def\installnotealternative#1#2% - {\setvalue{\??vn:\c!alternative:#1}{#2}} - -\def\doifnotescollected#1% - {\ctxlua{structure.notes.doifcontent("#1")}} - -\def\donotealternative#1% - {\edef\currentnote{#1}% - \doifnotescollected\currentnote - {\endgraf - \ifvmode - \whitespace - \noteparameter\c!before - \fi - \begingroup - \setnotebodyfont - \getvalue{\??vn:\c!alternative:\noteparameter\c!alternative}% - \endgroup - \ifvmode - \noteparameter\c!after - \fi}} - -\setvalue{\??vn:\c!alternative:}{\getvalue{\??vn:\c!alternative:\v!none}} - -%D A stupid alternative is also provided: -%D -%D \starttyping -%D \setupfootnotes[location=text,alternative=none] -%D \stoptyping - -\def\flushlocalnotes#1{\ctxlua{structure.notes.flush("#1","store")}} - -\installnotealternative \v!none - {\flushlocalnotes\currentnote} - -\installnotealternative \v!grid % test if n > 0 - {\snaptogrid\hbox - {\localframed - [\??vn\currentnote] - {\flushlocalnotes\currentnote}}} - -\installnotealternative \v!fixed % test if n > 0 - {\localframed - [\??vn\currentnote] - {\flushlocalnotes\currentnote}} - -\installnotealternative \v!columns % redundant - {\localframed - [\??vn\currentnote] - {\edef\currentnotewidth{\noteparameter\c!width}% - \doifdimensionelse\currentnotewidth\donothing - {\edef\currentnotewidth{\the\hsize}}% -% \setupinmargin[\c!align=\v!left]% - \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\currentnotewidth]% - \flushlocalnotes\currentnote - \stopsimplecolumns}} - -%D \macros -%D {fakenotes} - - \def\fakenotes - {\ifhmode\endgraf\fi\ifvmode - \calculatetotalclevernoteheight - \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi - \fi} - - \def\fakepagenotes - {\ifhmode\endgraf\fi\ifvmode - \calculatetotalpagenoteheight - \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi - \fi} - - \newdimen\totalnoteheight - - \def\doaddtototalnoteheight#1% - {\ifdim\ht#1>\zeropoint - \advance\totalnoteheight\ht #1% - \advance\totalnoteheight\skip#1% - \fi} - - \def\docalculatetotalnoteheight - {\ifcase\clevernotes % tricky here ! ! ! to be sorted out ! ! ! - \doaddtototalnoteheight\currentnoteins - \else - \doaddtototalnoteheight\currentbackupnoteins - \fi} - - \def\docalculatetotalclevernoteheight - {\ifcase\clevernotes \else % tricky here ! ! ! to be sorted out ! ! ! - \doaddtototalnoteheight\currentnoteins - \fi} - - \def\docalculatetotalpagenoteheight - {\doaddtototalnoteheight\currentnoteins} - - \def\calculatetotalnoteheight {\totalnoteheight\zeropoint\processnotes\docalculatetotalnoteheight} - \def\calculatetotalclevernoteheight{\totalnoteheight\zeropoint\processnotes\docalculatetotalclevernoteheight} - \def\calculatetotalpagenoteheight {\totalnoteheight\zeropoint\processnotes\docalculatetotalpagenoteheight} - - \newif\ifnotespresent - - \def\dochecknotepresence - {\ifdim\ht\currentnoteins>\zeropoint - \notespresenttrue - \fi} - - \def\checknotepresence - {\notespresentfalse - \processnotes\dochecknotepresence} - -%D Now how can this mechanism be hooked into \CONTEXT\ without -%D explictly postponing footnotes? The solution turned out to -%D be rather simple: -%D -%D \starttyping -%D \everypar {...\flushnotes...} -%D \neverypar {...\postponenotes} -%D \stoptyping -%D -%D and -%D -%D \starttyping -%D \def\ejectinsert% -%D {... -%D \flushnotes -%D ...} -%D \stoptyping -%D -%D We can use \type{\neverypar} because in most commands -%D sensitive to footnote gobbling we disable \type{\everypar} -%D in favor for \type{\neverypar}. In fact, this footnote -%D implementation is the first to use this scheme. - -%D This is a nasty and new secondary footnote flusher. It -%D can be hooked into \type {\everypar} like: -%D -%D \starttyping -%D \appendtoks \synchronizenotes \to \everypar -%D \stoptyping - - % \def\dosynchronizenotes - % {\ifvoid\currentnoteins\else\insert\currentnoteins{\unvbox\currentnoteins}\fi} - % - % \def\synchronizenotes - % {\processnotes\dosynchronizenotes} - -\let\synchronizenotes\relax - -%D When typesetting footnotes, we have to return to the -%D footnote specific bodyfont size, which is in most cases derived -%D from the global document bodyfont size. In the previous macros -%D we already used a footnote specific font setting macro. - -\def\setnotebodyfont - {\let\setnotebodyfont\relax - \restoreglobalbodyfont - \switchtobodyfont[\noteparameter\c!bodyfont]% - \setuptolerance[\noteparameter\c!tolerance]% - \setupalign[\noteparameter\c!align]} - -%D The footnote mechanism defaults to a traditional one -%D column way of showing them. By default we precede them by -%D a small line. - -\ifx\v!endnote\undefined \def\v!endnote{endnote} \fi - -\definenote [\v!footnote] -\definenote [\v!endnote ] [\c!location=\v!none] % else no break - -%D Compatibility macros: - - \def\setupfootnotedefinition{\setupnotedefinition [\v!footnote]} - \def\setupfootnotes {\setupnote [\v!footnote]} -%unexpanded \def\footnote {\setnote [\v!footnote]} -\unexpanded \def\footnotetext {\setnotetext [\v!footnote]} - %def\note {\dodoubleempty\notesymbol [\v!footnote]} % alleen footnote - \def\placefootnotes {\dodoubleempty\doplacefootnotes [\v!footnote]} - \def\placelocalfootnotes {\dodoubleempty\doplacelocalfootnotes[\v!footnote]} - \def\startlocalfootnotes {\startlocalnotes [\v!footnote]} % alleen footnote - \def\stoplocalfootnotes {\stoplocalnotes } - \def\flushfootnotes {\flushnotes} - \def\doflushfootnotes {\doflushnotes} - -\def\doplacefootnotes [#1][#2]{\ifsecondargument\placenotes [#1][#2,\c!height=\textheight]\else\placenotes [#1]\fi} -\def\doplacelocalfootnotes[#1][#2]{\ifsecondargument\placelocalnotes[#1][#2,\c!height=\textheight]\else\placelocalnotes[#1]\fi} - -\def\note{\dodoubleempty\donote} - -\def\donote[#1][#2]{\ifsecondargument\donotesymbol[#1][#2]\else\secondargumenttrue\donotesymbol[\v!footnote][#1]\fi} - -%D New trickery: - -\def\ownnotesymbol#1% #1 gets number passed - {\executeifdefined{\??vn::\currentnote}\empty} - -\def\setnotesymbol[#1]#2#3% - {\prewordbreak % prevent lookback - \setgvalue{\??vn::#1}{#3} - \dolastnotesymbol} - -\def\ownnote[#1]#2#3#4% - {\setnotesymbol[#1]{#2}{#3}% - \setnotetext [#1]{#4}} - -\defineconversion - [ownnote] - [\ownnotesymbol] - -\protect \endinput diff --git a/tex/context/base/strc-num.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..82558cd61 --- /dev/null +++ b/tex/context/base/strc-num.mkiv @@ -0,0 +1,450 @@ +%D \module +%D [ file=strc-num, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Basic Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Basic Numbering} + +\registerctxluafile{strc-num}{1.001} + +\unprotect + +% we need to rework this, i.e. clone like itm, des etc with \s!parent + +% numbering + +% \definestructurecounter[name] +% \setupstructurecounter[name][wijze=,blok=,tekst=,plaats=,conversie=,start=] +% \setstructurecounter[name]{value} +% \resetstructurecounter[name] +% \incrementstructurecounter[name] +% \decrementstructurecounter[name] +% \savestructurecounter[name] +% \restorestructurecounter[name] +% \convertedstructurecounter[name] % depricated: \getstructurecounter[name] +% \rawstructurecounter[name] + +% private (defined in core-sec.tex) +% +% \nextstructurecounter[name][tag][reference] +% \currentstructurecounter[name] + +% todo: better inheritane system + +\definesystemvariable {nn} + +\def\setupstructurecountering{\dodoubleempty\getparameters[\??nn]} + +\setupstructurecountering + [\c!way=\v!by\v!chapter, +% \c!blockway=, +% \c!prefixstopper=, +\c!prefixconnector=., +\c!prefixsegments=\thenamedstructurecounterlevel\currentstructurecounter, +\c!start=0, +\c!state=\v!start, + \c!prefix=\v!yes, + \c!state=\v!start] + +% \letvalue{\??nn\s!empty}\empty + +\def\structurecounterparameter#1#2% + {\csname + \ifcsname\??nn#1#2\endcsname + \??nn#1#2% + \else\ifcsname\??nn\@@thestructurecounter{#1}#2\endcsname + \??nn\@@thestructurecounter{#1}#2% + \else\ifcsname\??nn#2\endcsname + \??nn#2% + \else + \s!empty + \fi\fi\fi + \endcsname} + +\def\@@thestructurecounter#1% + {\ifcsname\??nn#1\c!number\endcsname + \expandafter\@@thestructurecounter\csname\??nn#1\c!number\endcsname + \else + #1% + \fi} + +% \def\structurecounterparameter #1#2{\csname\dostructurecounterparameter{\??nn#1}#2\endcsname} +% \def\dostructurecounterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructurecounterparentparameter\csname#1\s!number\endcsname#2\fi} +% \def\dostructurecounterparentparameter#1#2{\ifx#1\relax\s!empty\else\dostructurecounterparameter#1#2\fi} + +% + +\def\definestructurecounter + {\dodoubleempty\dodefinestructurecounter} + +\def\dodefinestructurecounter[#1][#2]% + {\doifassignmentelse{#2} + {\dododefinestructurecounter[#1][#2]} + {\doifelsenothing{#2} + {\dododefinestructurecounter[#1][]} + {\donodefinestructurecounter[#1][#2]}}} + +\def\dododefinestructurecounter[#1][#2]% + {\getparameters + [\??nn#1] + [\s!counter=,#2]% counter is for internal purposes + \ctxlua{structure.counters.define("#1", + tonumber("\structurecounterparameter{#1}\c!start") or 0, + tonumber("\structurecounterparameter{#1}\s!counter") or 0 + )}% + \docheckstructurecountersetup{#1}} + +\def\donodefinestructurecounter[#1][#2]% + {\getparameters[\??nn#1][\c!number=#2]% + \docheckstructurecountersetup{#1}} + +\def\setupstructurecounter + {\dodoubleargument\dosetupstructurecounter} + +\def\dosetupstructurecounter[#1][#2]% + {\getparameters[\??nn#1][\c!start=,#2]% + \docheckstructurecountersetup{#1}} + +\def\structurecounterway#1% slow, we need to store it at the tex end + {\ctxlua{structure.sections.way("\structurecounterparameter{#1}\c!way","\v!by")}} + +\def\thenamedstructurecounterlevel#1% +% {\thenamedstructureheadlevel{\structurecounterway{\structurecounterparameter{#1}\c!way}}} + {\thenamedstructureheadlevel{\structurecounterway{#1}}} + +\def\docheckstructurecountersetup#1% + {% this can be done at the lua end / a bit messy here ... todo ... + \ifcsname\??nn#1\c!number\endcsname + \doifelsevalue {\??nn#1\c!number}{#1} {\letbeundefined{\??nn#1\c!number}}% + {\doifvaluenothing{\??nn#1\c!number} {\letbeundefined{\??nn#1\c!number}}}% + \fi + \ifcsname\??nn#1\c!number\endcsname + % it's a clone + \else + \edef\currentstructurecounterlevel{\thenamedstructurecounterlevel{#1}}% + \ctxlua{ + structure.counters.restart("#1",1,"\structurecounterparameter{#1}\c!start") + structure.counters.setstate("#1","\structurecounterparameter{#1}\c!state") + structure.counters.setlevel("#1",\currentstructurecounterlevel) + structure.sections.setchecker("#1",\currentstructurecounterlevel,structure.counters.reset) + }% + \fi} + +\def\doifstructurecounterelse#1{\ctxlua{structure.counters.doifelse("\@@thestructurecounter{#1}")}} +\def\doifstructurecounter #1{\ctxlua{structure.counters.doif ("\@@thestructurecounter{#1}")}} +\def\doifnotstructurecounter #1{\ctxlua{structure.counters.doifnot ("\@@thestructurecounter{#1}")}} + +\def\setstructurecounter [#1]#2{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",1,\number#2)}} +\def\setstructurecounterown [#1]#2{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",1,"#2")}} +\def\resetstructurecounter [#1]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",1)}} +\def\restartstructurecounter [#1]#2{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",1,#2)}} +\def\savestructurecounter [#1]{\ctxlua{structure.counters.save ("\@@thestructurecounter{#1}")}} +\def\restorestructurecounter [#1]{\ctxlua{structure.counters.restore("\@@thestructurecounter{#1}")}} +\def\incrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,1)}} +\def\decrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,-1)}} +\def\rawstructurecounter [#1]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",1)}} +\def\laststructurecounter [#1]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",1)}} +\def\firststructurecounter [#1]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",1)}} +\def\nextstructurecounter [#1]{\ctxlua{structure.counters.next ("\@@thestructurecounter{#1}",1)}} +\def\prevstructurecounter [#1]{\ctxlua{structure.counters.prev ("\@@thestructurecounter{#1}",1)}} +\def\structurecountersubs [#1]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",1)}} + +\def\tracestructurecounter [#1]{\ctxlua{structure.counters.trace ("\@@thestructurecounter{#1}")}} + +\def\incrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,1))}} +\def\decrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,-1))}} + +\def\setsubstructurecounter {\dodoubleargument\dosetsubstructurecounter} +\def\setsubstructurecounterown {\dodoubleargument\dosetsubstructurecounterown} +\def\resetsubstructurecounter {\dodoubleargument\doresetsubstructurecounter} +\def\restartsubstructurecounter {\dodoubleargument\dorestartsubstructurecounter} +\def\incrementsubstructurecounter {\dodoubleargument\doincrementsubstructurecounter} +\def\decrementsubstructurecounter {\dodoubleargument\dodecrementsubstructurecounter} +\def\rawsubstructurecounter {\dodoubleargument\dorawsubstructurecounter} + +\def\dosetsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",#2,\number#3)}} +\def\dosetsubstructurecounterown [#1][#2]#3{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",#2,"#3")}} +\def\doresetsubstructurecounter [#1][#2]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",#2)}} +\def\dorestartsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",#2,#3)}} +\def\doincrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,1)}} +\def\dodecrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,-1)}} +\def\dorawsubstructurecounter [#1][#2]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",#2)}} +\def\dolastsubstructurecounter [#1][#2]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",#2)}} +\def\dofirstsubstructurecounter [#1][#2]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",#2)}} +\def\dosubstructurecountersubs [#1][#2]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",#2)}} + +% The bypage check needs a multipass reference and therefore +% we only check for it when we increment and know that some +% content will be placed. We could also check for spreads. + +% to be checked ! + +\def\docheckstructurecounterbypage#1% since we call lua to get the way we can as well do all in lua + {\doif{\structurecounterway{#1}}\v!page{\checkpagechange{#1}\ifpagechanged\resetstructurecounter[#1]\fi}} + +\def\incrementstructurecounter[#1]% + {\docheckstructurecounterbypage{#1}% + \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",1,1)}} + +\def\doincrementsubstructurecounter[#1][#2]% + {\docheckstructurecounterbypage{#1} + \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",#2,1)}} + +\def\convertedstructurecounter + {\dodoubleempty\doconvertedstructurecounter} + +\def\doconvertedstructurecounter[#1][#2]% + {\begingroup + \ifsecondargument\getparameters[\??nn#1][#2]\fi + \ctxlua{structure.counters.prefixedconverted( + "\@@thestructurecounter{#1}", + { + prefix = "\structurecounterparameter{#1}\c!prefix", + separatorset = "\structurecounterparameter{#1}\c!prefixseparatorset", + conversion = "\structurecounterparameter{#1}\c!prefixconversion", + conversionset = "\structurecounterparameter{#1}\c!prefixconversionset", + stopper = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es, + set = "\structurecounterparameter{#1}\c!prefixset", + segments = "\structurecounterparameter{#1}\c!prefixsegments", + connector = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es, + }, + { + order = "\structurecounterparameter{#1}\c!numberorder", + separatorset = "\structurecounterparameter{#1}\c!numberseparatorset", + conversion = \!!bs\structurecounterparameter{#1}\c!numberconversion\!!es, + conversionset = "\structurecounterparameter{#1}\c!numberconversionset", + stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es, + segments = "\structurecounterparameter{#1}\c!numbersegments", + type = "\structurecounterparameter{#1}\c!type", + } + )}% + \endgroup} + +\def\convertedsubstructurecounter + {\dotripleempty\doconvertedsubstructurecounter} + +\def\doconvertedsubstructurecounter[#1][#2][#3]% #2 can be n or n:m + {\ifsecondargument + \doconvertedstructurecounter[#1][\c!numbersegments=#2,#3]% + \else + \secondargumentfalse\doconvertedstructurecounter[#1][]% + \fi} + +\let\getstructurecounter\convertedstructurecounter + +\def\doifdefinedstructurecounter #1{\doifdefined {\csname\s!structurecounter#1\c!number\endcsname}} +\def\doifundefinedstructurecounter #1{\doifundefined {\csname\s!number#1\c!number\endcsname}} +\def\doifdefinedstructurecounterelse#1{\doifdefinedelse{\csname\s!number#1\c!number\endcsname}} + +\ifx\checkstructurecounter\undefined \def\checkstructurecounter[#1]{} \fi + +\def\checkstructurecounter[#1]{} + +%D What follows is a compatibility layer. This will be phased out (at +%D least from core usage). + +\def\reset + {\dosingleargument\doreset} + +\def\doreset[#1]% + {\processcommalist[#1]\dodoreset} + +\def\dodoreset#1% + {\csname\s!reset#1\endcsname}% + +\let \numberparameter \structurecounterparameter % {name}\c!key + +\let \definenumber \definestructurecounter % [name] +\let \setupnumber \setupstructurecounter % [name][setups] + +\let \setnumber \setstructurecounter % [name]{value} +\let \resetnumber \resetstructurecounter % [name] +\let \savenumber \savestructurecounter % [name] +\let \restorenumber \restorestructurecounter % [name] +\let \incrementnumber \incrementstructurecounter % [name] +\let \decrementnumber \decrementstructurecounter % [name] +\let \rawnumber \rawstructurecounter % [name] +\let \getnumber \getstructurecounter % [name] +\let \convertednumber \getstructurecounter % [name] + +\let \doifdefinednumber \doifstructurecounter % {number}{true} +\let \doifundefinednumber \doifnotstructurecounter % {number}{true} +\let \doifdefinednumberelse \doifstructurecounterelse % {number}{true}{false} + +% weird one + +\def\accumulatednumber[#1]{} + +% funny, here, todo: these are the defaults + +\def\setupnumbering + {\dodoubleempty\getparameters[\??nr]} + +\setupnumbering + [\c!way=\v!by\v!chapter, + \c!blockway=, + \c!state=\v!start] + +\def\numberingparameter#1{\csname\??nr#1\endcsname} + +% \c!prefixconnector=., +% \c!stopper=, + +% \c!prefix=\v!no, +% \c!prefixconnector=., +% \c!way=bychapter, +% \c!prefixsegments=2:2, + + +%D Helpers: + +% call: +% +% \dostructurecountercomponent +% \currentfloat +% \getfloatparameters \floatparameter \detokenizedfloatparameter +% \hascaption \hastitle \hasnumber +% [settings][userdata] +% +% sets: +% +% \laststructurecounternumber +% \laststructurecountersynchronize + +\newconditional\hasstructurecountercaption +\newconditional\hasstructurecountertitle +\newconditional\hasstructurecounternumber + +\def\dostructurecountercomponent#1#2#3#4#5#6#7[#8][#9]% + {\begingroup + % + #2[#8]% + \edef\hasstructurecountercaption{#3\s!hascaption}% + \edef\hasstructurecountertitle{#3\s!hastitle}% + \edef\hasstructurecounternumber{#3\s!hasnumber}% + % + \edef\currentname{#3\c!name}% + \ifx\currentname\empty + \edef\currentname{#1}% + \fi + \edef\currentcounter{#3\s!counter}% + \ifx\currentcounter\empty + \let\currentcounter\currentname + \fi + % + \doif{#3\c!title}\v!none{\setfalse\hasstructurecountercaption\setfalse\hasstructurecounternumber}% will become obsolete + % + \ifx\hasstructurecounternumber\v!yes + \incrementstructurecounter[\currentcounter]% + \fi + % + \ifx\hasstructurecountercaption\v!yes + \edef\currentexpansion{#3\c!expansion}% + \ifx\currentexpansion\s!xml + \edef\currenttitle{#4\c!title}% + \edef\currentbookmark{#4\c!bookmark}% + \xmlstartraw + \edef\currentlisttitle{#3\c!title}% + \xmlstopraw + \let\currentcoding\s!xml + \else + \ifx\currentexpansion\v!yes + \edef\currenttitle{#3\c!title}% + \edef\currentbookmark{#3\c!bookmark}% + \else + \edef\currenttitle{#4\c!title}% + \edef\currentbookmark{#4\c!bookmark}% + \fi + \let\currentlisttitle\currenttitle + \let\currentcoding\s!tex + \fi + \edef\currentlabel{#3\c!label}% + \edef\currentreference{#3\c!reference}% + \setnextinternalreference + \xdef\laststructurecounternumber{\ctxlua{structure.lists.push{ + metadata = { + kind = "#1", + name = "\currentname", + level = structure.sections.currentlevel(), + catcodes = \the\catcodetable, + }, + references = { + internal = \nextinternalreference, + reference = "\currentreference", + referenceprefix = "\referenceprefix", + block = "\currentstructureblock", + section = structure.sections.currentid(), + }, + titledata = { + label = \!!bs\detokenize\expandafter{\currentlabel }\!!es, + title = \!!bs\detokenize\expandafter{\currenttitle }\!!es, + \ifx\currentbookmark\currenttitle \else + bookmark = \!!bs\detokenize\expandafter{\currentbookmark }\!!es, + \fi + \ifx\currentlisttitle\currenttitle \else + list = \!!bs\detokenize\expandafter{\currentlisttitle}\!!es, + \fi + }, + \ifx\hasstructurecountercaption\v!yes + prefixdata = { + prefix = "#3\c!prefix", + separatorset = "#3\c!prefixseparatorset", + conversion = \!!bs#3\c!prefixconversion\!!es, + conversionset = "#3\c!prefixconversionset", + set = "#3\c!prefixset", + segments = "#3\c!prefixsegments", + connector = \!!bs#3\c!prefixconnector\!!es, + }, + numberdata = { + numbers = structure.counters.compact("\currentcounter",nil,true), + separatorset = "#3\c!numberseparatorset", + conversion = \!!bs#3\c!numberconversion\!!es, + conversionset = "#3\c!numberconversionset", + stopper = \!!bs#3\c!numberstopper\!!es, + segments = "#3\c!numbersegments", + }, + \fi + userdata = structure.helpers.touserdata(\!!bs\detokenize{#9}\!!es) + } + }}% + \xdef\laststructurecountersynchronize % make this a macro because shared + {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% + \noexpand\ctxlatelua{structure.lists.enhance(\laststructurecounternumber)}}% + \else + \glet\laststructurecounternumber \relax + \glet\laststructurecountersynchronize\relax + \fi + \endgroup} + +\def\dostructurecountersetup#1#2% name \someparameter + {\setupstructurecounter + [#1] + [ \c!start=#2\c!start, + \c!state=#2\c!state, + \c!way=#2\c!way, + % + \c!prefix=#2\c!prefix, + \c!prefixseparatorset=#2\c!prefixseparatorset, + \c!prefixconversion=#2\c!prefixconversion, + \c!prefixconversionset=#2\c!prefixconversionset, + \c!prefixstopper=#2\c!prefixstopper, + \c!prefixset=#2\c!prefixset, + \c!prefixsegments=#2\c!prefixsegments, + \c!prefixset=#2\c!prefixset, + \c!prefixconnector=#2\c!prefixconnector, + % + \c!numberseparatorset=#2\c!numberseparatorset, + \c!numberconversion=#2\c!numberconversion, + \c!numberconversionset=#2\c!numberconversionset, + \c!numberstopper=#2\c!numberstopper, + \c!numbersegments=#2\c!numbersegments]} + +\protect \endinput diff --git a/tex/context/base/strc-num.tex b/tex/context/base/strc-num.tex deleted file mode 100644 index 8b723575b..000000000 --- a/tex/context/base/strc-num.tex +++ /dev/null @@ -1,440 +0,0 @@ -%D \module -%D [ file=strc-num, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Basic Numbering, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Basic Numbering} - -\registerctxluafile{strc-num}{1.001} - -\unprotect - -% we need to rework this, i.e. clone like itm, des etc with \s!parent - -% numbering - -% \definestructurecounter[name] -% \setupstructurecounter[name][wijze=,blok=,tekst=,plaats=,conversie=,start=] -% \setstructurecounter[name]{value} -% \resetstructurecounter[name] -% \incrementstructurecounter[name] -% \decrementstructurecounter[name] -% \savestructurecounter[name] -% \restorestructurecounter[name] -% \convertedstructurecounter[name] % depricated: \getstructurecounter[name] -% \rawstructurecounter[name] - -% private (defined in core-sec.tex) -% -% \nextstructurecounter[name][tag][reference] -% \currentstructurecounter[name] - -% todo: better inheritane system - -\definesystemvariable {nn} - -\def\setupstructurecountering{\dodoubleempty\getparameters[\??nn]} - -\setupstructurecountering - [\c!way=\v!by\v!chapter, -% \c!blockway=, -% \c!prefixstopper=, -\c!prefixconnector=., -\c!prefixsegments=\thenamedstructurecounterlevel\currentstructurecounter, -\c!start=0, -\c!state=\v!start, - \c!prefix=\v!yes, - \c!state=\v!start] - -% \letvalue{\??nn\s!empty}\empty - -\def\structurecounterparameter#1#2% - {\csname - \ifcsname\??nn#1#2\endcsname - \??nn#1#2% - \else\ifcsname\??nn\@@thestructurecounter{#1}#2\endcsname - \??nn\@@thestructurecounter{#1}#2% - \else\ifcsname\??nn#2\endcsname - \??nn#2% - \else - \s!empty - \fi\fi\fi - \endcsname} - -\def\@@thestructurecounter#1% - {\ifcsname\??nn#1\c!number\endcsname - \expandafter\@@thestructurecounter\csname\??nn#1\c!number\endcsname - \else - #1% - \fi} - -% \def\structurecounterparameter #1#2{\csname\dostructurecounterparameter{\??nn#1}#2\endcsname} -% \def\dostructurecounterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructurecounterparentparameter\csname#1\s!number\endcsname#2\fi} -% \def\dostructurecounterparentparameter#1#2{\ifx#1\relax\s!empty\else\dostructurecounterparameter#1#2\fi} - -% - -\def\definestructurecounter - {\dodoubleempty\dodefinestructurecounter} - -\def\dodefinestructurecounter[#1][#2]% - {\doifassignmentelse{#2} - {\dododefinestructurecounter[#1][#2]} - {\doifelsenothing{#2} - {\dododefinestructurecounter[#1][]} - {\donodefinestructurecounter[#1][#2]}}} - -\def\dododefinestructurecounter[#1][#2]% - {\getparameters - [\??nn#1] - [\s!counter=,#2]% counter is for internal purposes - \ctxlua{structure.counters.define("#1", - tonumber("\structurecounterparameter{#1}\c!start") or 0, - tonumber("\structurecounterparameter{#1}\s!counter") or 0 - )}% - \docheckstructurecountersetup{#1}} - -\def\donodefinestructurecounter[#1][#2]% - {\getparameters[\??nn#1][\c!number=#2]% - \docheckstructurecountersetup{#1}} - -\def\setupstructurecounter - {\dodoubleargument\dosetupstructurecounter} - -\def\dosetupstructurecounter[#1][#2]% - {\getparameters[\??nn#1][\c!start=,#2]% - \docheckstructurecountersetup{#1}} - -\def\structurecounterway#1% slow, we need to store it at the tex end - {\ctxlua{structure.sections.way("\structurecounterparameter{#1}\c!way","\v!by")}} - -\def\thenamedstructurecounterlevel#1% -% {\thenamedstructureheadlevel{\structurecounterway{\structurecounterparameter{#1}\c!way}}} - {\thenamedstructureheadlevel{\structurecounterway{#1}}} - -\def\docheckstructurecountersetup#1% - {% this can be done at the lua end / a bit messy here ... todo ... - \ifcsname\??nn#1\c!number\endcsname - \doifelsevalue {\??nn#1\c!number}{#1} {\letbeundefined{\??nn#1\c!number}}% - {\doifvaluenothing{\??nn#1\c!number} {\letbeundefined{\??nn#1\c!number}}}% - \fi - \ifcsname\??nn#1\c!number\endcsname - % it's a clone - \else - \edef\currentstructurecounterlevel{\thenamedstructurecounterlevel{#1}}% - \ctxlua{ - structure.counters.restart("#1",1,"\structurecounterparameter{#1}\c!start") - structure.counters.setstate("#1","\structurecounterparameter{#1}\c!state") - structure.counters.setlevel("#1",\currentstructurecounterlevel) - structure.sections.setchecker("#1",\currentstructurecounterlevel,structure.counters.reset) - }% - \fi} - -\def\doifstructurecounterelse#1{\ctxlua{structure.counters.doifelse("\@@thestructurecounter{#1}")}} -\def\doifstructurecounter #1{\ctxlua{structure.counters.doif ("\@@thestructurecounter{#1}")}} -\def\doifnotstructurecounter #1{\ctxlua{structure.counters.doifnot ("\@@thestructurecounter{#1}")}} - -\def\setstructurecounter [#1]#2{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",1,\number#2)}} -\def\setstructurecounterown [#1]#2{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",1,"#2")}} -\def\resetstructurecounter [#1]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",1)}} -\def\restartstructurecounter [#1]#2{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",1,#2)}} -\def\savestructurecounter [#1]{\ctxlua{structure.counters.save ("\@@thestructurecounter{#1}")}} -\def\restorestructurecounter [#1]{\ctxlua{structure.counters.restore("\@@thestructurecounter{#1}")}} -\def\incrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,1)}} -\def\decrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,-1)}} -\def\rawstructurecounter [#1]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",1)}} -\def\laststructurecounter [#1]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",1)}} -\def\firststructurecounter [#1]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",1)}} -\def\nextstructurecounter [#1]{\ctxlua{structure.counters.next ("\@@thestructurecounter{#1}",1)}} -\def\prevstructurecounter [#1]{\ctxlua{structure.counters.prev ("\@@thestructurecounter{#1}",1)}} -\def\structurecountersubs [#1]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",1)}} - -\def\tracestructurecounter [#1]{\ctxlua{structure.counters.trace ("\@@thestructurecounter{#1}")}} - -\def\incrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,1))}} -\def\decrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,-1))}} - -\def\setsubstructurecounter {\dodoubleargument\dosetsubstructurecounter} -\def\setsubstructurecounterown {\dodoubleargument\dosetsubstructurecounterown} -\def\resetsubstructurecounter {\dodoubleargument\doresetsubstructurecounter} -\def\restartsubstructurecounter {\dodoubleargument\dorestartsubstructurecounter} -\def\incrementsubstructurecounter {\dodoubleargument\doincrementsubstructurecounter} -\def\decrementsubstructurecounter {\dodoubleargument\dodecrementsubstructurecounter} -\def\rawsubstructurecounter {\dodoubleargument\dorawsubstructurecounter} - -\def\dosetsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",#2,\number#3)}} -\def\dosetsubstructurecounterown [#1][#2]#3{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",#2,"#3")}} -\def\doresetsubstructurecounter [#1][#2]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",#2)}} -\def\dorestartsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",#2,#3)}} -\def\doincrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,1)}} -\def\dodecrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,-1)}} -\def\dorawsubstructurecounter [#1][#2]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",#2)}} -\def\dolastsubstructurecounter [#1][#2]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",#2)}} -\def\dofirstsubstructurecounter [#1][#2]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",#2)}} -\def\dosubstructurecountersubs [#1][#2]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",#2)}} - -% The bypage check needs a multipass reference and therefore -% we only check for it when we increment and know that some -% content will be placed. We could also check for spreads. - -% to be checked ! - -\def\docheckstructurecounterbypage#1% since we call lua to get the way we can as well do all in lua - {\doif{\structurecounterway{#1}}\v!page{\checkpagechange{#1}\ifpagechanged\resetstructurecounter[#1]\fi}} - -\def\incrementstructurecounter[#1]% - {\docheckstructurecounterbypage{#1}% - \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",1,1)}} - -\def\doincrementsubstructurecounter[#1][#2]% - {\docheckstructurecounterbypage{#1} - \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",#2,1)}} - -\def\convertedstructurecounter - {\dodoubleempty\doconvertedstructurecounter} - -\def\doconvertedstructurecounter[#1][#2]% - {\begingroup - \ifsecondargument\getparameters[\??nn#1][#2]\fi - \ctxlua{structure.counters.prefixedconverted( - "\@@thestructurecounter{#1}", - { - prefix = "\structurecounterparameter{#1}\c!prefix", - separatorset = "\structurecounterparameter{#1}\c!prefixseparatorset", - conversion = "\structurecounterparameter{#1}\c!prefixconversion", - conversionset = "\structurecounterparameter{#1}\c!prefixconversionset", - stopper = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es, - set = "\structurecounterparameter{#1}\c!prefixset", - segments = "\structurecounterparameter{#1}\c!prefixsegments", - connector = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es, - }, - { - order = "\structurecounterparameter{#1}\c!numberorder", - separatorset = "\structurecounterparameter{#1}\c!numberseparatorset", - conversion = \!!bs\structurecounterparameter{#1}\c!numberconversion\!!es, - conversionset = "\structurecounterparameter{#1}\c!numberconversionset", - stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es, - segments = "\structurecounterparameter{#1}\c!numbersegments", - type = "\structurecounterparameter{#1}\c!type", - } - )}% - \endgroup} - -\def\convertedsubstructurecounter - {\dotripleempty\doconvertedsubstructurecounter} - -\def\doconvertedsubstructurecounter[#1][#2][#3]% #2 can be n or n:m - {\ifsecondargument - \doconvertedstructurecounter[#1][\c!numbersegments=#2,#3]% - \else - \secondargumentfalse\doconvertedstructurecounter[#1][]% - \fi} - -\let\getstructurecounter\convertedstructurecounter - -\def\doifdefinedstructurecounter #1{\doifdefined {\csname\s!structurecounter#1\c!number\endcsname}} -\def\doifundefinedstructurecounter #1{\doifundefined {\csname\s!number#1\c!number\endcsname}} -\def\doifdefinedstructurecounterelse#1{\doifdefinedelse{\csname\s!number#1\c!number\endcsname}} - -\ifx\checkstructurecounter\undefined \def\checkstructurecounter[#1]{} \fi - -\def\checkstructurecounter[#1]{} - -%D What follows is a compatibility layer. This will be phased out (at -%D least from core usage). - -\def\reset - {\dosingleargument\doreset} - -\def\doreset[#1]% - {\processcommalist[#1]\dodoreset} - -\def\dodoreset#1% - {\csname\s!reset#1\endcsname}% - -\let \numberparameter \structurecounterparameter % {name}\c!key - -\let \definenumber \definestructurecounter % [name] -\let \setupnumber \setupstructurecounter % [name][setups] - -\let \setnumber \setstructurecounter % [name]{value} -\let \resetnumber \resetstructurecounter % [name] -\let \savenumber \savestructurecounter % [name] -\let \restorenumber \restorestructurecounter % [name] -\let \incrementnumber \incrementstructurecounter % [name] -\let \decrementnumber \decrementstructurecounter % [name] -\let \rawnumber \rawstructurecounter % [name] -\let \getnumber \getstructurecounter % [name] -\let \convertednumber \getstructurecounter % [name] - -\let \doifdefinednumber \doifstructurecounter % {number}{true} -\let \doifundefinednumber \doifnotstructurecounter % {number}{true} -\let \doifdefinednumberelse \doifstructurecounterelse % {number}{true}{false} - -% weird one - -\def\accumulatednumber[#1]{} - -% funny, here, todo: these are the defaults - -\def\setupnumbering - {\dodoubleempty\getparameters[\??nr]} - -\setupnumbering - [\c!way=\v!by\v!chapter, - \c!blockway=, - \c!sectionnumber=\v!yes, - \c!state=\v!start] - -%D Helpers: - -% call: -% -% \dostructurecountercomponent -% \currentfloat -% \getfloatparameters \floatparameter \detokenizedfloatparameter -% \hascaption \hastitle \hasnumber -% [settings][userdata] -% -% sets: -% -% \laststructurecounternumber -% \laststructurecountersynchronize - -\newconditional\hasstructurecountercaption -\newconditional\hasstructurecountertitle -\newconditional\hasstructurecounternumber - -\def\dostructurecountercomponent#1#2#3#4#5#6#7[#8][#9]% - {\begingroup - % - #2[#8]% - \edef\hasstructurecountercaption{#3\s!hascaption}% - \edef\hasstructurecountertitle{#3\s!hastitle}% - \edef\hasstructurecounternumber{#3\s!hasnumber}% - % - \edef\currentname{#3\c!name}% - \ifx\currentname\empty - \edef\currentname{#1}% - \fi - \edef\currentcounter{#3\s!counter}% - \ifx\currentcounter\empty - \let\currentcounter\currentname - \fi - % - \doif{#3\c!title}\v!none{\setfalse\hasstructurecountercaption\setfalse\hasstructurecounternumber}% will become obsolete - % - \ifx\hasstructurecounternumber\v!yes - \incrementstructurecounter[\currentcounter]% - \fi - % - \ifx\hasstructurecountercaption\v!yes - \edef\currentexpansion{#3\c!expansion}% - \ifx\currentexpansion\s!xml - \edef\currenttitle{#4\c!title}% - \edef\currentbookmark{#4\c!bookmark}% - \xmlstartraw - \edef\currentlisttitle{#3\c!title}% - \xmlstopraw - \let\currentcoding\s!xml - \else - \ifx\currentexpansion\v!yes - \edef\currenttitle{#3\c!title}% - \edef\currentbookmark{#3\c!bookmark}% - \else - \edef\currenttitle{#4\c!title}% - \edef\currentbookmark{#4\c!bookmark}% - \fi - \let\currentlisttitle\currenttitle - \let\currentcoding\s!tex - \fi - \edef\currentlabel{#3\c!label}% - \edef\currentreference{#3\c!reference}% - \setnextinternalreference - \xdef\laststructurecounternumber{\ctxlua{structure.lists.push{ - metadata = { - kind = "#1", - name = "\currentname", - level = structure.sections.currentlevel(), - catcodes = \the\catcodetable, - }, - references = { - internal = \nextinternalreference, - reference = "\currentreference", - referenceprefix = "\referenceprefix", - block = "\currentstructureblock", - section = structure.sections.currentid(), - }, - titledata = { - label = \!!bs\detokenize\expandafter{\currentlabel }\!!es, - title = \!!bs\detokenize\expandafter{\currenttitle }\!!es, - \ifx\currentbookmark\currenttitle \else - bookmark = \!!bs\detokenize\expandafter{\currentbookmark }\!!es, - \fi - \ifx\currentlisttitle\currenttitle \else - list = \!!bs\detokenize\expandafter{\currentlisttitle}\!!es, - \fi - }, - \ifx\hasstructurecountercaption\v!yes - prefixdata = { - prefix = "#3\c!prefix", - separatorset = "#3\c!prefixseparatorset", - conversion = \!!bs#3\c!prefixconversion\!!es, - conversionset = "#3\c!prefixconversionset", - set = "#3\c!prefixset", - segments = "#3\c!prefixsegments", - connector = \!!bs#3\c!prefixconnector\!!es, - }, - numberdata = { - numbers = structure.counters.compact("\currentcounter",nil,true), - separatorset = "#3\c!numberseparatorset", - conversion = \!!bs#3\c!numberconversion\!!es, - conversionset = "#3\c!numberconversionset", - stopper = \!!bs#3\c!numberstopper\!!es, - segments = "#3\c!numbersegments", - }, - \fi - userdata = structure.helpers.touserdata(\!!bs\detokenize{#9}\!!es) - } - }}% - \xdef\laststructurecountersynchronize % make this a macro because shared - {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% - \noexpand\ctxlatelua{structure.lists.enhance(\laststructurecounternumber)}}% - \else - \glet\laststructurecounternumber \relax - \glet\laststructurecountersynchronize\relax - \fi - \endgroup} - -\def\dostructurecountersetup#1#2% name \someparameter - {\setupstructurecounter - [#1] - [ \c!start=#2\c!start, - \c!state=#2\c!state, - \c!way=#2\c!way, - % - \c!prefix=#2\c!prefix, - \c!prefixseparatorset=#2\c!prefixseparatorset, - \c!prefixconversion=#2\c!prefixconversion, - \c!prefixconversionset=#2\c!prefixconversionset, - \c!prefixstopper=#2\c!prefixstopper, - \c!prefixset=#2\c!prefixset, - \c!prefixsegments=#2\c!prefixsegments, - \c!prefixset=#2\c!prefixset, - \c!prefixconnector=#2\c!prefixconnector, - % - \c!numberseparatorset=#2\c!numberseparatorset, - \c!numberconversion=#2\c!numberconversion, - \c!numberconversionset=#2\c!numberconversionset, - \c!numberstopper=#2\c!numberstopper, - \c!numbersegments=#2\c!numbersegments]} - -\protect \endinput diff --git a/tex/context/base/strc-pag.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..2b7c3fc21 --- /dev/null +++ b/tex/context/base/strc-pag.mkiv @@ -0,0 +1,506 @@ +%D \module +%D [ file=strc-pag, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Pagenumbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Pagenumbering} + +\registerctxluafile{strc-pag}{1.001} + +\unprotect + +% Hacks: + +\let\preparepageprefix\gobbleoneargument +\let\checkrealpage \relax +\let\checksubpages \relax +\let\setpagecounters \relax + +% Allocation: + +\countdef\realpageno = 0 \realpageno = 1 +\countdef\userpageno = 1 \userpageno = 1 +\countdef\subpageno = 2 \subpageno = 0 % !! +\countdef\arrangeno = 3 \arrangeno = 0 % !! + +\let\pageno\userpageno + +\def\realfolio{\the\realpageno} +\def\userfolio{\the\userpageno} +\def\subfolio {\the\subpageno } + +\newtoks\everyinitializepagecounters + +\def\initializepagecounters{\the\everyinitializepagecounters} + +\appendtoks + \initializepagecounters +\to \everyjob + +% Page numbers are kind of independent of each other and therefore they +% all get their own counter. After all, it's easier to combine them in +% a pseudo counterset than to deal with a complex set itself. + +% \definestructureprefixset [mine][section-1,section-2] +% \definestructureseparatorset[mine][:] +% +% \setupuserpagenumber +% [way=bypart, +% prefix=yes, +% prefixset=mine, +% prefixseparatorset=mine] + +\definestructurecounter[\s!realpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=0] +\definestructurecounter[\s!userpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=1] +\definestructurecounter[\s!subpage] [\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=2] + +\newtoks\everysetuprealpagenumber % todo: set state: none, start, stop, reset +\newtoks\everysetupuserpagenumber % todo: set state: none, start, stop, reset +\newtoks\everysetupsubpagenumber % todo: set state: none, start, stop, reset + +\def\setuprealpagenumber{\dosingleargument\dosetuprealpagenumber} +\def\setupuserpagenumber{\dosingleargument\dosetupuserpagenumber} +\def\setupsubpagenumber {\dosingleargument\dosetupsubpagenumber} + +\def\dosavepagenumberstate#1{\edef\oldpagenumberstate{\structurecounterparameter#1\c!state}} + +\def\dosetuprealpagenumber[#1]{\dosavepagenumberstate\s!realpage\dosetupstructurecounter[\s!realpage][#1]\the\everysetuprealpagenumber} +\def\dosetupuserpagenumber[#1]{\dosavepagenumberstate\s!userpage\dosetupstructurecounter[\s!userpage][#1]\the\everysetupuserpagenumber} +\def\dosetupsubpagenumber [#1]{\dosavepagenumberstate\s!subpage \dosetupstructurecounter[\s!subpage ][#1]\the\everysetupsubpagenumber } + +\def\resetrealpagenumber {} % not permitted +\def\resetuserpagenumber {\resetstructurecounter[\s!userpage]} +\def\resetsubpagenumber {\resetstructurecounter[\s!subpage]} + +\appendtoks + \setstructurecounter[\s!realpage]\realpageno + \setstructurecounter[\s!userpage]\userpageno + \setstructurecounter[\s!subpage] \subpageno +\to \everyinitializepagecounters + +\let\setuppagenumber\setupuserpagenumber +\let\resetpagenumber\resetuserpagenumber + +% { +% prefix = "\structurecounterparameter{#1}\c!prefix", +% separatorset = "\structurecounterparameter{#1}\c!prefixseparatorset", +% conversion = "\structurecounterparameter{#1}\c!prefixconversion", +% conversionset = "\structurecounterparameter{#1}\c!prefixconversionset", +% stopper = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es, +% set = "\structurecounterparameter{#1}\c!prefixset", +% segments = "\structurecounterparameter{#1}\c!prefixsegments", +% connector = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es, +% }, +% { +% order = "\structurecounterparameter{#1}\c!numberorder", +% separatorset = "\structurecounterparameter{#1}\c!numberseparatorset", +% conversion = "\structurecounterparameter{#1}\c!numberconversion", +% conversionset = "\structurecounterparameter{#1}\c!numberconversionset", +% stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es, +% segments = "\structurecounterparameter{#1}\c!numbersegments", +% type = "\structurecounterparameter{#1}\c!type", +% } + +\def\savecurrentpagestate + {\ctxlua{structure.pages.save { + prefix = "\structurecounterparameter\s!userpage\c!prefix", + separatorset = "\structurecounterparameter\s!userpage\c!prefixseparatorset", + conversion = "\structurecounterparameter\s!userpage\c!prefixconversion", + conversionset = "\structurecounterparameter\s!userpage\c!prefixconversionset", + set = "\structurecounterparameter\s!userpage\c!prefixset", + stopper = \!!bs\structurecounterparameter\s!userpage\c!prefixstopper\!!es, + segments = "\structurecounterparameter\s!userpage\c!prefixsegments", + connector = \!!bs\structurecounterparameter\s!userpage\c!prefixconnector\!!es, + }}} + +\prependtoks + \savecurrentpagestate +\to \everyshipout + +\def\pushpagestate{\setxvalue{\??nm:\s!userpage:\c!state}{\structurecounterparameter\s!userpage\c!state}} +\def\poppagestate {\normalexpanded{\noexpand\setuppagenumber[\c!state=\getvalue{\??nm:\s!userpage:\c!state}]}} + +\setuppagenumber + [\c!way=\v!by\v!text, + \c!prefix=\v!no, + \c!prefixset=\v!part, + \c!prefixconnector=\endash, + \c!state=\v!start] + +\setupsubpagenumber + [\c!way=\v!by\v!part, + \c!state=\v!stop] + +% We don't want conflicts when \type {\pageno} is used by other +% packages, like \CWEB, so we redefine \type {\pageno}. + +\newcount\pageno \pageno\userpageno \let\folio\userfolio + +\appendtoks + \global\pageno\userpageno +\to \everyinitializepagecounters + +% Counters + +\def\firstpage {1} \def\prevpage {1} \def\nextpage {1} \def\lastpage {1} +\def\firstuserpage{1} \def\prevuserpage{1} \def\nextuserpage{1} \def\lastuserpage{1} +\def\firstsubpage {1} \def\prevsubpage {1} \def\nextsubpage {1} \def\lastsubpage {1} + +% Renderers: + +\def\realpagenumber{\convertedstructurecounter[\s!realpage]} +\def\userpagenumber{\convertedstructurecounter[\s!userpage]} +\def\subpagenumber {\convertedstructurecounter[\s!subpage]} + +\def\pagenumber {\rawstructurecounter[\s!userpage]} +\def\prefixedpagenumber{\convertedstructurecounter[\s!userpage]} % \userpagenumber + +\def\firstrealpagenumber{\convertedstructurecounter[\s!realpage][\c!type=\v!first]} +\def\firstuserpagenumber{\convertedstructurecounter[\s!userpage][\c!type=\v!first]} +\def\firstsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!first]} + +\def\lastrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!last]} +\def\lastuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!last]} +\def\lastsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!last]} + +\def\prevrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!previous]} +\def\prevuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!previous]} +\def\prevsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!previous]} + +\def\nextrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!next]} +\def\nextuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!next]} +\def\nextsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!next]} + +\appendtoks + \decrementstructurecounter[\s!realpage]% + \decrementstructurecounter[\s!userpage]% + \decrementstructurecounter[\s!subpage]% +\to\everygoodbye + +% Equivalents (compatibility): +% +% todo: maybe leave lastpage etc lua calls + +\def\realpage{\realfolio} +\def\userpage{\userfolio} +\def\subpage {\subfolio} + +% \def\firstrealpage{\firstpage} +% \def\prevrealpage {\prevpage} +% \def\nextrealpage {\nextpage} +% \def\lastrealpage {\lastpage} + +\def\firstrealpage{\firststructurecounter[\s!realpage]} +\def\prevrealpage {\prevstructurecounter[\s!realpage]} +\def\nextrealpage {\nextstructurecounter[\s!realpage]} +\def\lastrealpage {\laststructurecounter[\s!realpage]} + +\let\firstpage\firstrealpage +\let\prevpage \prevrealpage +\let\nextpage \nextrealpage +\let\lastpage \lastrealpage + +\def\nofrealpages {\lastrealpage} \def\totalnumberofpages{\lastrealpage} +\def\nofuserpages {\lastuserpage} \def\lastpagenumber {\lastuserpage} +\def\nofsubpages {\lastsubpage } + +% Hooks: + +\appendtoks +% \xdef\lastpage{\laststructurecounter[\s!realpage]}% + \xdef\currentpage{\the\realpageno}% + \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage\fi +\to \everyinitializepagecounters + +% \def\savenofpages +% {\global\realpageno\decrementedstructurecounter[\s!realpage]\relax +% \global\pageno \decrementedstructurecounter[\s!userpage]\relax} + +\let\savenofpages\relax + +% States: + +\newif\ifrightpage \rightpagetrue +\newif\ifdoublesided +\newif\ifsinglesided + +% Real page numbers: + +\def\gotonextrealpage + {\global\realpageno\incrementedstructurecounter[\s!realpage]\relax + \ifnum\realpageno>\lastpage + \xdef\lastpage{\realfolio}% + \fi + \setpagereference\v!firstpage\firstpage + \setpagereference\v!lastpage\lastpage + \ifnum\realpageno>\plusone + \xdef\prevpage{\the\numexpr\realpageno+\minusone}% + \setpagereference\v!backward\prevpage + \else + \global\let\prevpage\firstpage + \setpagereference\v!backward\lastpage + \fi + \setpagereference\v!previouspage\prevpage + \ifnum\realpageno<\lastpage\relax + \xdef\nextpage{\the\numexpr\realpageno+\plusone}% + \setpagereference\v!page\nextpage + \setpagereference\v!forward\nextpage + \glet\nextnextpage\nextpage + \ifodd\nextpage\relax + \setpagereference\v!nextoddpage\nextnextpage + \else + \setpagereference\v!nextevenpage\nextnextpage + \fi + \xdef\nextnextpage{\the\numexpr\realpageno+\plustwo}% + \ifnum\nextnextpage>\lastpage\else + \ifodd\nextnextpage\relax + \setpagereference\v!nextoddpage\nextnextpage + \else + \setpagereference\v!nextevenpage\nextnextpage + \fi + \fi + \else + \glet\nextpage\lastpage + \setpagereference\v!page\firstpage + \setpagereference\v!forward\firstpage + \setpagereference\v!nextoddpage\lastpage + \setpagereference\v!nextevenpage\lastpage + \fi + \setpagereference\v!nextpage\realfolio} + +% Pagenumbers: + +\def\dodecrementpagenumber{\global\userpageno\decrementedstructurecounter[\s!userpage]\relax\global\pageno\userpageno} +\def\doincrementpagenumber{\global\userpageno\incrementedstructurecounter[\s!userpage]\relax\global\pageno\userpageno} + +\def\dosynchronizepagenumber{\global\let\@@pnstate\v!start} + +\def\decrementpagenumber{\getvalue{\??pn-\structurecounterparameter\s!userpage\c!state}} +\def\incrementpagenumber{\getvalue{\??pn+\structurecounterparameter\s!userpage\c!state}} + +\letvalue{\??pn-\v!start}\dodecrementpagenumber +\letvalue{\??pn-\v!none }\dodecrementpagenumber +\letvalue{\??pn-\v!empty}\dodecrementpagenumber + +\letvalue{\??pn+\v!start}\doincrementpagenumber +\letvalue{\??pn+\v!none }\doincrementpagenumber +\setvalue{\??pn+\v!empty}{\doincrementpagenumber\dosynchronizepagenumber} +\letvalue{\??pn+\v!keep }\dosynchronizepagenumber + +% todo: check if number set, and reset it after testing; also take care of \global\shiftedrealpagenotrue + +% Subpagenumbers: + +\def\gotonextsubpage + {\global\subpageno\incrementedstructurecounter[\s!subpage]\relax + \ifnum\subpageno>\lastsubpage + \xdef\lastsubpage{\subfolio}% + \fi + \setpagereference\v!firstsubpage\firstsubpage + \setpagereference\v!lastsubpage\lastsubpage + \ifnum\subpageno>\plusone + \xdef\prevsubpage{\the\numexpr\subpageno+\minusone}% + \setpagereference\v!subbackward\prevsubpage + \else + \global\let\prevsubpage\firstsubpage + \setpagereference\v!subbackward\lastsubpage + \fi + \setpagereference\v!previoussubpage\prevsubpage + \ifnum\subpageno<\lastsubpage\relax + \xdef\nextsubpage{\the\numexpr\subpageno+\plusone}% + \setpagereference\v!subpage\nextsubpage + \setpagereference\v!subforward\nextsubpage + \glet\nextnextpage\nextsubpage + \xdef\nextnextpage{\the\numexpr\subpageno+\plustwo}% + \else + \glet\nextsubpage\lastsubpage + \setpagereference\v!subpage\firstsubpage + \setpagereference\v!subforward\firstsubpage + \fi + \setpagereference\v!nextsubpage\subfolio} + +% Control: + +\def\getpagestatus % hierboven gebruiken + {\ifdoublesided + \global\rightpagetrue + % todo: \global\rightpagetrue or \global\rightpagefalse + \else + \global\rightpagetrue + \fi} + +% Setup general page numbering + +\newtoks\everysetuppagenumbering + +\def\setuppagenumbering + {\dosingleempty\dosetuppagenumbering} + +\def\dosetuppagenumbering[#1]% + {\getparameters[\??nm][#1]\the\everysetuppagenumbering} + +\appendtoks + \singlesidedfalse + \doublesidedfalse + \ExpandFirstAfter\processallactionsinset + [\@@nmalternative] + [ \v!singlesided=>\singlesidedtrue, + \v!doublesided=>\doublesidedtrue]% + \ifx\trackingmarginnotestrue\undefined\else + \ifdoublesided + \trackingmarginnotestrue + \else + \trackingmarginnotesfalse + \fi + \fi + \dosetpagenumberlocation +\to \everysetuppagenumbering + +\appendtoks + \ifdefined \recalculatebackgrounds \recalculatebackgrounds \fi +\to \everysetuppagenumbering + +% The numbered location handler is there because we need to be downward +% compatible. So, in fact there can be multiple handlers active at the +% same time, but only the current one does something. +% +% thsi code might move to page-txt + +\newcount\currentpagenumberlocation + +\def\dosetpagenumberlocation + {\advance\currentpagenumberlocation\plusone + \ifx\@@nmlocation\empty \else + \let\@@pagenumbervlocation\v!footer + \let\@@pagenumberhlocation\v!text + \let\@@pagenumberxlocation\c!middletext + \normalexpanded{\noexpand\processallactionsinset[\@@nmlocation]} + [ \v!header=>\let\@@pagenumbervlocation\v!header, + \v!footer=>\let\@@pagenumbervlocation\v!footer, + \v!middle=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!middletext, + \v!left=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!lefttext, + \v!right=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!righttext, + \v!inleft=>\let\@@pagenumberhlocation\v!margin\let\@@pagenumberxlocation\c!lefttext, + \v!inright=>\let\@@pagenumberhlocation\v!margin\let\@@pagenumberxlocation\c!righttext, + \v!inmargin=>\let\@@pagenumberhlocation\v!margin\def\@@pagenumberxlocation{\ifdoublesided\c!margintext\else\c!righttext\fi}, + \v!margin=>\let\@@pagenumberhlocation\v!margin\def\@@pagenumberxlocation{\ifdoublesided\c!margintext\else\c!righttext\fi}, + \v!atmargin=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!marginedgetext, + \v!marginedge=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!marginedgetext]% + \normalexpanded{\noexpand\setspecificlayouttext + {\@@pagenumbervlocation}{\@@pagenumberhlocation}{\@@pagenumberxlocation}% + {\noexpand\doplacepagenumberatlocation{\number\currentpagenumberlocation}}}% + \fi} + +\def\setspecificlayouttext#1#2#3#4{\setvalue{\??tk#1#2#3}{#4}} % weird place + +\appendtoks + \dosetpagenumberlocation +\to \everyinitializepagecounters + +\def\doplacepagenumberatlocation#1% + {\ifnum#1=\currentpagenumberlocation\relax\expandafter\placelocationpagenumber\fi} + +% Rendering: + +\unexpanded\def\placelocationpagenumber + {\ifnum\userpagenumberstate=\plustwo + \ifnum\overallpagenumberstate=\plusone + \doif\@@nmstrut\v!yes\strut + \@@nmcommand{\doattributes\??nm\c!style\c!color{\@@nmleft\labeltexts\v!pagenumber{\prefixedpagenumber}\@@nmright}}% + \fi + \fi} + +\unexpanded\def\completepagenumber + {\ifnum\userpagenumberstate=\plustwo + \ifnum\overallpagenumberstate=\plusone + \@@nmleft\labeltexts\v!pagenumber\prefixedpagenumber\@@nmright + \fi + \fi} + +\unexpanded\def\placepagenumber + {\ifnum\userpagenumberstate=\plustwo + \ifnum\overallpagenumberstate=\plusone + \labeltexts\v!pagenumber\pagenumber + \fi + \fi} + +\unexpanded\def\referencepagenumber[#1]% + {\doifelsenothing{#1}{?}{}} + +% The numbered location handler is there because we need to be downward +% compatible. So, in fact there can be multiple handlers active at the +% same time, but only the current one does something. + +\chardef\realpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible +\chardef\userpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible +\chardef\subpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible +\chardef\overallpagenumberstate=1 % general number: 0=invisible, 1=visible + +\def\checkpagenumberstatechange#1#2% + {\edef\newpagenumberstate{\structurecounterparameter#1\c!state}% + \ifx\newpagenumberstate\oldpagenumberstate \else + \doifelse\newpagenumberstate\v!start + {\chardef#2\plustwo}% + {\chardef#2\zerocount}% + \fi} + +\appendtoks % todo: set state: none, start, stop, reset + \checkpagenumberstatechange\s!realpage\realpagenumberstate +\to \everysetuprealpagenumber + +\appendtoks % todo: set state: none, start, stop, reset + \checkpagenumberstatechange\s!userpage\userpagenumberstate +\to \everysetupuserpagenumber + +\appendtoks % todo: set state: none, start, stop, reset + \checkpagenumberstatechange\s!subpage\subpagenumberstate +\to \everysetupsubpagenumber + +\appendtoks % todo: set state: none, start, stop, reset + \doifelse\@@nmstate\v!start + {\chardef\overallpagenumberstate\plusone}% + {\chardef\overallpagenumberstate\zerocount}% +\to \everysetuppagenumbering + +% Done + +% \c!way=\v!by\v!part +% \c!text= +% \v!chapter\v!number=\v!no +% \v!part\v!number=\v!yes +% \c!numberseparator=-- +% \c!conversion=\v!numbers + +\setuppagenumbering + [\c!alternative=\v!singlesided, + \c!location={\v!header,\v!middle}, + \c!width=, % in geval van \v!marginedge + \c!left=, + \c!right=, + \c!textseparator=\tfskip, + \c!state=\v!start, + \c!command=, + \c!strut=\v!yes, + \c!style=, % empty, otherwise conflict + \c!color=] + +% just for downward compatbility + +\appendtoks + \edef\askeduserpagenumber{\structurecounterparameter\s!userpage\c!number}% + \ifx\askeduserpagenumber\empty \else + \normalexpanded{\noexpand\setuppagenumber[\c!start=\structurecounterparameter\s!userpage\c!number,\c!number=]}% + \fi +\to\everysetupuserpagenumber % todo: set state: none, start, stop, reset + +\initializepagecounters + +\protect \endinput diff --git a/tex/context/base/strc-pag.tex b/tex/context/base/strc-pag.tex deleted file mode 100644 index 2b7c3fc21..000000000 --- a/tex/context/base/strc-pag.tex +++ /dev/null @@ -1,506 +0,0 @@ -%D \module -%D [ file=strc-pag, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Pagenumbering, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Pagenumbering} - -\registerctxluafile{strc-pag}{1.001} - -\unprotect - -% Hacks: - -\let\preparepageprefix\gobbleoneargument -\let\checkrealpage \relax -\let\checksubpages \relax -\let\setpagecounters \relax - -% Allocation: - -\countdef\realpageno = 0 \realpageno = 1 -\countdef\userpageno = 1 \userpageno = 1 -\countdef\subpageno = 2 \subpageno = 0 % !! -\countdef\arrangeno = 3 \arrangeno = 0 % !! - -\let\pageno\userpageno - -\def\realfolio{\the\realpageno} -\def\userfolio{\the\userpageno} -\def\subfolio {\the\subpageno } - -\newtoks\everyinitializepagecounters - -\def\initializepagecounters{\the\everyinitializepagecounters} - -\appendtoks - \initializepagecounters -\to \everyjob - -% Page numbers are kind of independent of each other and therefore they -% all get their own counter. After all, it's easier to combine them in -% a pseudo counterset than to deal with a complex set itself. - -% \definestructureprefixset [mine][section-1,section-2] -% \definestructureseparatorset[mine][:] -% -% \setupuserpagenumber -% [way=bypart, -% prefix=yes, -% prefixset=mine, -% prefixseparatorset=mine] - -\definestructurecounter[\s!realpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=0] -\definestructurecounter[\s!userpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=1] -\definestructurecounter[\s!subpage] [\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=2] - -\newtoks\everysetuprealpagenumber % todo: set state: none, start, stop, reset -\newtoks\everysetupuserpagenumber % todo: set state: none, start, stop, reset -\newtoks\everysetupsubpagenumber % todo: set state: none, start, stop, reset - -\def\setuprealpagenumber{\dosingleargument\dosetuprealpagenumber} -\def\setupuserpagenumber{\dosingleargument\dosetupuserpagenumber} -\def\setupsubpagenumber {\dosingleargument\dosetupsubpagenumber} - -\def\dosavepagenumberstate#1{\edef\oldpagenumberstate{\structurecounterparameter#1\c!state}} - -\def\dosetuprealpagenumber[#1]{\dosavepagenumberstate\s!realpage\dosetupstructurecounter[\s!realpage][#1]\the\everysetuprealpagenumber} -\def\dosetupuserpagenumber[#1]{\dosavepagenumberstate\s!userpage\dosetupstructurecounter[\s!userpage][#1]\the\everysetupuserpagenumber} -\def\dosetupsubpagenumber [#1]{\dosavepagenumberstate\s!subpage \dosetupstructurecounter[\s!subpage ][#1]\the\everysetupsubpagenumber } - -\def\resetrealpagenumber {} % not permitted -\def\resetuserpagenumber {\resetstructurecounter[\s!userpage]} -\def\resetsubpagenumber {\resetstructurecounter[\s!subpage]} - -\appendtoks - \setstructurecounter[\s!realpage]\realpageno - \setstructurecounter[\s!userpage]\userpageno - \setstructurecounter[\s!subpage] \subpageno -\to \everyinitializepagecounters - -\let\setuppagenumber\setupuserpagenumber -\let\resetpagenumber\resetuserpagenumber - -% { -% prefix = "\structurecounterparameter{#1}\c!prefix", -% separatorset = "\structurecounterparameter{#1}\c!prefixseparatorset", -% conversion = "\structurecounterparameter{#1}\c!prefixconversion", -% conversionset = "\structurecounterparameter{#1}\c!prefixconversionset", -% stopper = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es, -% set = "\structurecounterparameter{#1}\c!prefixset", -% segments = "\structurecounterparameter{#1}\c!prefixsegments", -% connector = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es, -% }, -% { -% order = "\structurecounterparameter{#1}\c!numberorder", -% separatorset = "\structurecounterparameter{#1}\c!numberseparatorset", -% conversion = "\structurecounterparameter{#1}\c!numberconversion", -% conversionset = "\structurecounterparameter{#1}\c!numberconversionset", -% stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es, -% segments = "\structurecounterparameter{#1}\c!numbersegments", -% type = "\structurecounterparameter{#1}\c!type", -% } - -\def\savecurrentpagestate - {\ctxlua{structure.pages.save { - prefix = "\structurecounterparameter\s!userpage\c!prefix", - separatorset = "\structurecounterparameter\s!userpage\c!prefixseparatorset", - conversion = "\structurecounterparameter\s!userpage\c!prefixconversion", - conversionset = "\structurecounterparameter\s!userpage\c!prefixconversionset", - set = "\structurecounterparameter\s!userpage\c!prefixset", - stopper = \!!bs\structurecounterparameter\s!userpage\c!prefixstopper\!!es, - segments = "\structurecounterparameter\s!userpage\c!prefixsegments", - connector = \!!bs\structurecounterparameter\s!userpage\c!prefixconnector\!!es, - }}} - -\prependtoks - \savecurrentpagestate -\to \everyshipout - -\def\pushpagestate{\setxvalue{\??nm:\s!userpage:\c!state}{\structurecounterparameter\s!userpage\c!state}} -\def\poppagestate {\normalexpanded{\noexpand\setuppagenumber[\c!state=\getvalue{\??nm:\s!userpage:\c!state}]}} - -\setuppagenumber - [\c!way=\v!by\v!text, - \c!prefix=\v!no, - \c!prefixset=\v!part, - \c!prefixconnector=\endash, - \c!state=\v!start] - -\setupsubpagenumber - [\c!way=\v!by\v!part, - \c!state=\v!stop] - -% We don't want conflicts when \type {\pageno} is used by other -% packages, like \CWEB, so we redefine \type {\pageno}. - -\newcount\pageno \pageno\userpageno \let\folio\userfolio - -\appendtoks - \global\pageno\userpageno -\to \everyinitializepagecounters - -% Counters - -\def\firstpage {1} \def\prevpage {1} \def\nextpage {1} \def\lastpage {1} -\def\firstuserpage{1} \def\prevuserpage{1} \def\nextuserpage{1} \def\lastuserpage{1} -\def\firstsubpage {1} \def\prevsubpage {1} \def\nextsubpage {1} \def\lastsubpage {1} - -% Renderers: - -\def\realpagenumber{\convertedstructurecounter[\s!realpage]} -\def\userpagenumber{\convertedstructurecounter[\s!userpage]} -\def\subpagenumber {\convertedstructurecounter[\s!subpage]} - -\def\pagenumber {\rawstructurecounter[\s!userpage]} -\def\prefixedpagenumber{\convertedstructurecounter[\s!userpage]} % \userpagenumber - -\def\firstrealpagenumber{\convertedstructurecounter[\s!realpage][\c!type=\v!first]} -\def\firstuserpagenumber{\convertedstructurecounter[\s!userpage][\c!type=\v!first]} -\def\firstsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!first]} - -\def\lastrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!last]} -\def\lastuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!last]} -\def\lastsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!last]} - -\def\prevrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!previous]} -\def\prevuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!previous]} -\def\prevsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!previous]} - -\def\nextrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!next]} -\def\nextuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!next]} -\def\nextsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!next]} - -\appendtoks - \decrementstructurecounter[\s!realpage]% - \decrementstructurecounter[\s!userpage]% - \decrementstructurecounter[\s!subpage]% -\to\everygoodbye - -% Equivalents (compatibility): -% -% todo: maybe leave lastpage etc lua calls - -\def\realpage{\realfolio} -\def\userpage{\userfolio} -\def\subpage {\subfolio} - -% \def\firstrealpage{\firstpage} -% \def\prevrealpage {\prevpage} -% \def\nextrealpage {\nextpage} -% \def\lastrealpage {\lastpage} - -\def\firstrealpage{\firststructurecounter[\s!realpage]} -\def\prevrealpage {\prevstructurecounter[\s!realpage]} -\def\nextrealpage {\nextstructurecounter[\s!realpage]} -\def\lastrealpage {\laststructurecounter[\s!realpage]} - -\let\firstpage\firstrealpage -\let\prevpage \prevrealpage -\let\nextpage \nextrealpage -\let\lastpage \lastrealpage - -\def\nofrealpages {\lastrealpage} \def\totalnumberofpages{\lastrealpage} -\def\nofuserpages {\lastuserpage} \def\lastpagenumber {\lastuserpage} -\def\nofsubpages {\lastsubpage } - -% Hooks: - -\appendtoks -% \xdef\lastpage{\laststructurecounter[\s!realpage]}% - \xdef\currentpage{\the\realpageno}% - \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage\fi -\to \everyinitializepagecounters - -% \def\savenofpages -% {\global\realpageno\decrementedstructurecounter[\s!realpage]\relax -% \global\pageno \decrementedstructurecounter[\s!userpage]\relax} - -\let\savenofpages\relax - -% States: - -\newif\ifrightpage \rightpagetrue -\newif\ifdoublesided -\newif\ifsinglesided - -% Real page numbers: - -\def\gotonextrealpage - {\global\realpageno\incrementedstructurecounter[\s!realpage]\relax - \ifnum\realpageno>\lastpage - \xdef\lastpage{\realfolio}% - \fi - \setpagereference\v!firstpage\firstpage - \setpagereference\v!lastpage\lastpage - \ifnum\realpageno>\plusone - \xdef\prevpage{\the\numexpr\realpageno+\minusone}% - \setpagereference\v!backward\prevpage - \else - \global\let\prevpage\firstpage - \setpagereference\v!backward\lastpage - \fi - \setpagereference\v!previouspage\prevpage - \ifnum\realpageno<\lastpage\relax - \xdef\nextpage{\the\numexpr\realpageno+\plusone}% - \setpagereference\v!page\nextpage - \setpagereference\v!forward\nextpage - \glet\nextnextpage\nextpage - \ifodd\nextpage\relax - \setpagereference\v!nextoddpage\nextnextpage - \else - \setpagereference\v!nextevenpage\nextnextpage - \fi - \xdef\nextnextpage{\the\numexpr\realpageno+\plustwo}% - \ifnum\nextnextpage>\lastpage\else - \ifodd\nextnextpage\relax - \setpagereference\v!nextoddpage\nextnextpage - \else - \setpagereference\v!nextevenpage\nextnextpage - \fi - \fi - \else - \glet\nextpage\lastpage - \setpagereference\v!page\firstpage - \setpagereference\v!forward\firstpage - \setpagereference\v!nextoddpage\lastpage - \setpagereference\v!nextevenpage\lastpage - \fi - \setpagereference\v!nextpage\realfolio} - -% Pagenumbers: - -\def\dodecrementpagenumber{\global\userpageno\decrementedstructurecounter[\s!userpage]\relax\global\pageno\userpageno} -\def\doincrementpagenumber{\global\userpageno\incrementedstructurecounter[\s!userpage]\relax\global\pageno\userpageno} - -\def\dosynchronizepagenumber{\global\let\@@pnstate\v!start} - -\def\decrementpagenumber{\getvalue{\??pn-\structurecounterparameter\s!userpage\c!state}} -\def\incrementpagenumber{\getvalue{\??pn+\structurecounterparameter\s!userpage\c!state}} - -\letvalue{\??pn-\v!start}\dodecrementpagenumber -\letvalue{\??pn-\v!none }\dodecrementpagenumber -\letvalue{\??pn-\v!empty}\dodecrementpagenumber - -\letvalue{\??pn+\v!start}\doincrementpagenumber -\letvalue{\??pn+\v!none }\doincrementpagenumber -\setvalue{\??pn+\v!empty}{\doincrementpagenumber\dosynchronizepagenumber} -\letvalue{\??pn+\v!keep }\dosynchronizepagenumber - -% todo: check if number set, and reset it after testing; also take care of \global\shiftedrealpagenotrue - -% Subpagenumbers: - -\def\gotonextsubpage - {\global\subpageno\incrementedstructurecounter[\s!subpage]\relax - \ifnum\subpageno>\lastsubpage - \xdef\lastsubpage{\subfolio}% - \fi - \setpagereference\v!firstsubpage\firstsubpage - \setpagereference\v!lastsubpage\lastsubpage - \ifnum\subpageno>\plusone - \xdef\prevsubpage{\the\numexpr\subpageno+\minusone}% - \setpagereference\v!subbackward\prevsubpage - \else - \global\let\prevsubpage\firstsubpage - \setpagereference\v!subbackward\lastsubpage - \fi - \setpagereference\v!previoussubpage\prevsubpage - \ifnum\subpageno<\lastsubpage\relax - \xdef\nextsubpage{\the\numexpr\subpageno+\plusone}% - \setpagereference\v!subpage\nextsubpage - \setpagereference\v!subforward\nextsubpage - \glet\nextnextpage\nextsubpage - \xdef\nextnextpage{\the\numexpr\subpageno+\plustwo}% - \else - \glet\nextsubpage\lastsubpage - \setpagereference\v!subpage\firstsubpage - \setpagereference\v!subforward\firstsubpage - \fi - \setpagereference\v!nextsubpage\subfolio} - -% Control: - -\def\getpagestatus % hierboven gebruiken - {\ifdoublesided - \global\rightpagetrue - % todo: \global\rightpagetrue or \global\rightpagefalse - \else - \global\rightpagetrue - \fi} - -% Setup general page numbering - -\newtoks\everysetuppagenumbering - -\def\setuppagenumbering - {\dosingleempty\dosetuppagenumbering} - -\def\dosetuppagenumbering[#1]% - {\getparameters[\??nm][#1]\the\everysetuppagenumbering} - -\appendtoks - \singlesidedfalse - \doublesidedfalse - \ExpandFirstAfter\processallactionsinset - [\@@nmalternative] - [ \v!singlesided=>\singlesidedtrue, - \v!doublesided=>\doublesidedtrue]% - \ifx\trackingmarginnotestrue\undefined\else - \ifdoublesided - \trackingmarginnotestrue - \else - \trackingmarginnotesfalse - \fi - \fi - \dosetpagenumberlocation -\to \everysetuppagenumbering - -\appendtoks - \ifdefined \recalculatebackgrounds \recalculatebackgrounds \fi -\to \everysetuppagenumbering - -% The numbered location handler is there because we need to be downward -% compatible. So, in fact there can be multiple handlers active at the -% same time, but only the current one does something. -% -% thsi code might move to page-txt - -\newcount\currentpagenumberlocation - -\def\dosetpagenumberlocation - {\advance\currentpagenumberlocation\plusone - \ifx\@@nmlocation\empty \else - \let\@@pagenumbervlocation\v!footer - \let\@@pagenumberhlocation\v!text - \let\@@pagenumberxlocation\c!middletext - \normalexpanded{\noexpand\processallactionsinset[\@@nmlocation]} - [ \v!header=>\let\@@pagenumbervlocation\v!header, - \v!footer=>\let\@@pagenumbervlocation\v!footer, - \v!middle=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!middletext, - \v!left=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!lefttext, - \v!right=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!righttext, - \v!inleft=>\let\@@pagenumberhlocation\v!margin\let\@@pagenumberxlocation\c!lefttext, - \v!inright=>\let\@@pagenumberhlocation\v!margin\let\@@pagenumberxlocation\c!righttext, - \v!inmargin=>\let\@@pagenumberhlocation\v!margin\def\@@pagenumberxlocation{\ifdoublesided\c!margintext\else\c!righttext\fi}, - \v!margin=>\let\@@pagenumberhlocation\v!margin\def\@@pagenumberxlocation{\ifdoublesided\c!margintext\else\c!righttext\fi}, - \v!atmargin=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!marginedgetext, - \v!marginedge=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!marginedgetext]% - \normalexpanded{\noexpand\setspecificlayouttext - {\@@pagenumbervlocation}{\@@pagenumberhlocation}{\@@pagenumberxlocation}% - {\noexpand\doplacepagenumberatlocation{\number\currentpagenumberlocation}}}% - \fi} - -\def\setspecificlayouttext#1#2#3#4{\setvalue{\??tk#1#2#3}{#4}} % weird place - -\appendtoks - \dosetpagenumberlocation -\to \everyinitializepagecounters - -\def\doplacepagenumberatlocation#1% - {\ifnum#1=\currentpagenumberlocation\relax\expandafter\placelocationpagenumber\fi} - -% Rendering: - -\unexpanded\def\placelocationpagenumber - {\ifnum\userpagenumberstate=\plustwo - \ifnum\overallpagenumberstate=\plusone - \doif\@@nmstrut\v!yes\strut - \@@nmcommand{\doattributes\??nm\c!style\c!color{\@@nmleft\labeltexts\v!pagenumber{\prefixedpagenumber}\@@nmright}}% - \fi - \fi} - -\unexpanded\def\completepagenumber - {\ifnum\userpagenumberstate=\plustwo - \ifnum\overallpagenumberstate=\plusone - \@@nmleft\labeltexts\v!pagenumber\prefixedpagenumber\@@nmright - \fi - \fi} - -\unexpanded\def\placepagenumber - {\ifnum\userpagenumberstate=\plustwo - \ifnum\overallpagenumberstate=\plusone - \labeltexts\v!pagenumber\pagenumber - \fi - \fi} - -\unexpanded\def\referencepagenumber[#1]% - {\doifelsenothing{#1}{?}{}} - -% The numbered location handler is there because we need to be downward -% compatible. So, in fact there can be multiple handlers active at the -% same time, but only the current one does something. - -\chardef\realpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible -\chardef\userpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible -\chardef\subpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible -\chardef\overallpagenumberstate=1 % general number: 0=invisible, 1=visible - -\def\checkpagenumberstatechange#1#2% - {\edef\newpagenumberstate{\structurecounterparameter#1\c!state}% - \ifx\newpagenumberstate\oldpagenumberstate \else - \doifelse\newpagenumberstate\v!start - {\chardef#2\plustwo}% - {\chardef#2\zerocount}% - \fi} - -\appendtoks % todo: set state: none, start, stop, reset - \checkpagenumberstatechange\s!realpage\realpagenumberstate -\to \everysetuprealpagenumber - -\appendtoks % todo: set state: none, start, stop, reset - \checkpagenumberstatechange\s!userpage\userpagenumberstate -\to \everysetupuserpagenumber - -\appendtoks % todo: set state: none, start, stop, reset - \checkpagenumberstatechange\s!subpage\subpagenumberstate -\to \everysetupsubpagenumber - -\appendtoks % todo: set state: none, start, stop, reset - \doifelse\@@nmstate\v!start - {\chardef\overallpagenumberstate\plusone}% - {\chardef\overallpagenumberstate\zerocount}% -\to \everysetuppagenumbering - -% Done - -% \c!way=\v!by\v!part -% \c!text= -% \v!chapter\v!number=\v!no -% \v!part\v!number=\v!yes -% \c!numberseparator=-- -% \c!conversion=\v!numbers - -\setuppagenumbering - [\c!alternative=\v!singlesided, - \c!location={\v!header,\v!middle}, - \c!width=, % in geval van \v!marginedge - \c!left=, - \c!right=, - \c!textseparator=\tfskip, - \c!state=\v!start, - \c!command=, - \c!strut=\v!yes, - \c!style=, % empty, otherwise conflict - \c!color=] - -% just for downward compatbility - -\appendtoks - \edef\askeduserpagenumber{\structurecounterparameter\s!userpage\c!number}% - \ifx\askeduserpagenumber\empty \else - \normalexpanded{\noexpand\setuppagenumber[\c!start=\structurecounterparameter\s!userpage\c!number,\c!number=]}% - \fi -\to\everysetupuserpagenumber % todo: set state: none, start, stop, reset - -\initializepagecounters - -\protect \endinput diff --git a/tex/context/base/strc-prc.mkiv b/tex/context/base/strc-prc.mkiv new file mode 100644 index 000000000..a81cfddd1 --- /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). + +\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-prc.tex b/tex/context/base/strc-prc.tex deleted file mode 100644 index a81cfddd1..000000000 --- a/tex/context/base/strc-prc.tex +++ /dev/null @@ -1,84 +0,0 @@ -%D \module -%D [ file=strc-prc, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Processors, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Processors} - -\registerctxluafile{strc-prc}{1.001} - -\unprotect - -%D Processors are used when we cannot easily associate typesetting directives -%D with (for instance) structural elements. Instead of ending up with numerous -%D additional definitions we can group treatments in so called processors. -%D -%D An example of where processors can be used is in separator sets (these are -%D related to typesetting numbers using structure). -%D -%D \starttyping -%D \defineprocessor[demo][style=\bfb,color=red] -%D \stoptyping -%D -%D This defines a processor named \type {demo}. Such a name ends up as prefix in -%D for instance: -%D -%D \starttyping -%D \definestructureseparatorset [demosep] [demo->!,demo->?,demo->!,demo->?] [demo->@] -%D \stoptyping -%D -%D Here the \type {!} and \type {?} are just the seperator characters that end -%D up between part, chapter, section, etc.\ numbers. The third argument defines the -%D default. When a separator is inserted, the \type{demo} processor will be applied. -%D Here the number will be separated by red slightly bigger than normal bold -%D exclamation marks and questionmarks -%D -%D Valid keys for defining a processor are \type {style}, \type {color}, \type {left}, -%D \type {right}, and \type {command} (the given command takes one argument). - -\def\defineprocessor - {\dodoubleargument\dodefineprocessor} - -\def\dodefineprocessor[#1][#2]% - {\ifsecondargument - \letbeundefined{\??po#1\c!command}% - \ctxlua{structure.processors.register("#1")}% - \getparameters[\??po#1][\c!style=,\c!color=,\c!left=,\c!right=,#2]% - \else - \letbeundefined{\??po#1\c!style}% - \ctxlua{structure.processors.reset("#1")}% - \fi} - -%D The following command can be used by users but normally it will be -%D invoked behind the screens. After all, processor prefixes need to -%D be split off first. - -\unexpanded\def\applyprocessor#1% - {\ifcsname\??po#1\c!style\endcsname - \expandafter\dodoapplyprocessor - \else - \expandafter\secondoftwoarguments - \fi{#1}} - -\def\dodoapplyprocessor#1#2% - {\begingroup - \dostartattributes{\??po#1}\c!style\c!color - \csname\??po#1\c!left\endcsname - \ifcsname\??po#1\c!command\endcsname - \csname\??po#1\c!command\endcsname{#2}% - \else - #2% - \fi - \csname\??po#1\c!right\endcsname - \dostopattributes - \endgroup} - -\protect \endinput diff --git a/tex/context/base/strc-ref.mkii b/tex/context/base/strc-ref.mkii new file mode 100644 index 000000000..d06319d07 --- /dev/null +++ b/tex/context/base/strc-ref.mkii @@ -0,0 +1,3038 @@ +%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} + +%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..23fc3e01e --- /dev/null +++ b/tex/context/base/strc-ref.mkiv @@ -0,0 +1,1905 @@ +%D \module +%D [ file=strc-ref, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Cross Referencing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} + +\registerctxluafile{strc-ref}{1.001} + +\unprotect + +%D This module is a (partial) rewrite of core-ref.tex for \MKIV. As +%D such it will be a moving target for a while. + +%D Later we will do a further cleanup and move much of the code to +%D \LUA\ (i.e.\ better backend integration). + +\let\mainreference\gobblefivearguments + +% this will go when we got rid of the tuo file + +\let\currentfolioreference \!!zerocount % only used in xml-fo +\let\resetreferences \relax +\let\setreferences \relax +\let\showcurrentreference \relax +\let\setexecutecommandcheck\gobbletwoarguments + +\def\s!full{full} +\def\s!text{text} +\def\s!page{page} + +% todo : unknown/illegal reference no arg +% todo : +n pages check on 'samepage' (contrastcolor) +% todo : multiple text in reference + +% Makes more sense to build action data first, especially now +% openaction etc are supported. +% +% \definespecial\doexecuteactionchain w h +% \definespecial\dosetgotolocation +% \definespecial\dosetexecuteJScode +% ... + +%D This module deals with referencing. In \CONTEXT\ referencing +%D is one of the core features, although at a first glance +%D probably nobody will notice. This is good, because +%D referencing should be as hidden as possible. +%D +%D In paper documents, referencing comes down to cross +%D referencing, but in their interactive counterparts, is also +%D involves navigation. Many features implemented here are +%D therefore closely related to navigation. +%D +%D Many \CONTEXT\ commands can optionally be fed with a +%D reference. Such a reference, when called upon, returns the +%D number of a figure, table, chapter etc, a piece of text, or +%D a pagenumber. +%D +%D There are three ways of defining a reference: +%D +%D \starttyping +%D \pagereference[here] +%D \textreference[here]{some text} +%D \stoptyping +%D +%D the third alternative combines them in: +%D +%D \starttyping +%D \reference[here]{some text} +%D \stoptyping + +\def\textreference {\dosingleargument\dotextreference} +\def\pagereference {\dosingleargument\dopagereference} +\def\reference {\dosingleargument\doreference } + +%D These are implemented in a low level form as: + +\def\dotextreference[#1]{\dosetreference\s!text{#1}} +\def\dopagereference[#1]{\dosetreference\s!page{#1}{}} +\def\doreference [#1]{\dosetreference\s!full{#1}} + +%D Actually there is not much difference between a text and a +%D full reference, but it's the concept that counts. The low +%D level implementation is: + +\newcount\crossreferencenumber + +\def\dofinishfullreference#1#2% + {\normalexpanded{\noexpand\ctxlatelua{jobreferences.enhance("#1","#2")}}% + \referenceinfo>{#1\letterbar#2}} + +\let\dofinishpagereference\dofinishfullreference + +\def\dofinishtextreference#1#2% + {\normalexpanded{\noexpand\ctxlatelua{jobreferences.enhance("#1","#2",{})}}% + \referenceinfo>{#1\letterbar#2}} + +\def\dosetreference#1#2#3% kind labels text -> todo: userdata + {\ifreferencing + \global\advance\crossreferencenumber\plusone + \edef\currentreferencekind{#1}% + \edef\currentreferencelabels{#2}% + \edef\currentreferenceexpansion{\@@rfexpansion}% {\referenceparameter\c!expansion} + \ifx\currentreferencelabels\empty \else + \ifx\currentreferenceexpansion\s!xml + \xmlstartraw + \xdef\currentreferencetext{#3}% + \xmlstopraw + \globallet\currentreferencecoding\s!xml + \else + \ifx\currentreferenceexpansion\v!yes + \xdef\currentreferencetext{#3}% + \else + \xdef\currentreferencetext{\detokenize{#3}}% + \fi + \globallet\currentreferencecoding\s!tex + \fi + \setnextinternalreference + \ctxlua { + jobreferences.set("\currentreferencekind", "\referenceprefix","\currentreferencelabels", + { + references = { + internal = \nextinternalreference, + block = "\currentstructureblock", + section = structure.sections.currentid(), + }, + metadata = { + kind = "#1", + catcodes = \the\catcodetable, + xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text + }, + entries = { + text = \!!bs\currentreferencetext\!!es + } + }) + jobreferences.setinternalreference("\referenceprefix","\currentreferencelabels",\nextinternalreference) + }% + \fi + \fi} + +%D For compatibility we provide: + +\def\rawreference #1#2#3{\dosetreference\s!full{#2}{#3}} % tag, labels, text +\def\rawpagereference #1#2{\dosetreference\s!page{#2}{}} % tag, labels +\def\rawtextreference#1#2#3{\dosetreference\s!text{#2}{#3}} % tag, labels, text + +\def\defaultreferencepage#1{[[[#1]]]} +\def\defaultreferencetext#1{[[[#1]]]} + +%D These macros depend on three other ones, +%D \type {\makesectionformat}, that generated \type +%D {\sectionformat}, \type {\pagenumber}. The not yet used +%D argument \type{#1} is a tag that specifies the type of +%D reference. + +%D \macros +%D {everyreference} +%D +%D For rather tricky purposes, one can assign sanitizing +%D macros to \type{\everyreference} (no longer that relevant). + +\newevery \everyreference \relax + +%D This is really needed, since for instance Polish has a +%D different alphabet and needs accented entries in registers. + +\appendtoks + \cleanupfeatures +\to \everyreference + +%D We did not yet discuss prefixing. Especially in interactive +%D documents, it's not always easy to keep track of duplicate +%D references. The prefix mechanism, which we will describe +%D later on, solves this problem. By (automatically) adding a +%D prefix one keeps references local, but the global ones in +%D view. To enable this feature, we explictly split the prefix +%D from the reference. + +\let\referenceprefix\empty + +%D For a long time the only way to access an external file was +%D to use the file prefix (\type {somefile::}. However, when +%D you split up a document, redefining the references may be +%D such a pain, that another approach is feasible. By setting +%D the \type {autofile} variable to \type {yes} or \type +%D {page}, you can access the reference directly. +%D +%D \starttabulate[||||] +%D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR +%D \NC $\star$ \NC \NC \NC\NR +%D \NC $\star$ \NC $\star$ \NC $\star$ \NC\NR +%D \NC \NC $\star$ \NC \NC\NR +%D \stoptabulate + +\def\usereferences[#1]% + {\writestatus\m!systems{references from other files are handled automatically}} + +%D As mentioned we will also use the cross reference mechanism +%D for navigational purposes. The main reason for this is that +%D we want to treat both categories alike: +%D +%D \starttyping +%D \goto{go back}[PreviousJump] +%D \goto{colofon}[colofon page] +%D \stoptyping +%D +%D Here \type{PreviousJump} is handled by the viewer, while the +%D \type{colofon page} reference is, apart from hyperlinking, a +%D rather normal reference. +%D +%D We already saw that cross refences are written to and read +%D from a file. The pure navigational ones don't need to be +%D written to file, but both for fast processing and +%D transparant integration, they are saved internally as a sort +%D of reference. We can easily distinguish such system +%D references from real cross reference ones by their tag. +%D +%D We also use the odd/even characteristic to determine the +%D page state. + +\let\currentrealreference \empty +\let\currentpagereference \empty +\let\currenttextreference \empty +\let\currentreferenceorder \empty +\let\currentsubtextreference \empty +\let\currentsubsubtextreference\empty + +%D System references only have one component: + +\newif\ifforwardreference +\newif\ifrealreferencepage + +\def\docheckrealreferencepage#1% todo + {\doifnumberelse{#1} + {\ifnum#1=\realpageno + \realreferencepagetrue + \else + \realreferencepagefalse + \fi} + {\realreferencepagefalse}} + +%D Text references can contain more than one entry and +%D therefore we check for +%D +%D \starttyping +%D {entry} +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D {{entry}{entry}{entry}} +%D \stoptyping +%D +%D and split accordingly. + +% todo: + +\def\doifforwardreferenceelse#1#2% todo + {\iffalse} + +%D Cross references appear as numbers (figure~1.1, chapter~2) +%D or pagenumbers (page~2, page 3--2), and are called with +%D \type{\in} and \type{\at}. In interactive documents we also +%D have \type{\goto}, \type{\button} and alike. These are more +%D versatile and look like: +%D +%D \starttyping +%D \goto[reference] +%D \goto[outer reference::] +%D \goto[outer reference::inner reference] +%D \goto[operation(argument)] +%D \goto[operation(action{argument,argument})] +%D \goto[action] +%D \goto[action{argument}] +%D \stoptyping +%D +%D The first one is a normal reference, the second and third +%D are references to a file or \URL. The brace delimited +%D references for instance refer to a \JAVASCRIPT. The last +%D example shows that we can pass arguments to the actions. +%D +%D When we split off the components of such a reference, the +%D results are available in: +%D +%D \starttyping +%D \currentreferencespecial +%D \currentreferenceoperation +%D \currentreferencearguments +%D \currentinnerreference +%D \currentouterreference +%D \currentfullreference +%D \stoptyping + +\newif\ifreferencefound + +\let\currentfullreference \empty +\let\currentreferencespecial \empty +\let\currentreferenceoperation\empty +\let\currentreferencearguments\empty +\let\currentouterreference \empty +\let\currentinnerreference \empty + +\def\setreferencevariables#1#2#3#4#5% + {\def\currentreferencespecial {#1}% + \def\currentreferenceoperation{#2}% + \def\currentreferencearguments{#3}% + \def\currentouterreference {#4}% + \def\currentinnerreference {#5}} + +%D Now we've come to the testing step. As we can see below, +%D this macro does bit more than testing: it also resolves +%D the reference. This means that whenever we test for the +%D existance of a reference at an outer level, we have all the +%D relevant properties of that reference avaliable inside the +%D true branche~(\type{#2}). +%D +%D The prefix has to do with localizing references. When a +%D prefix is set, looking for a reference comes to looking for +%D the prefixed one, and when not found, looking for the non +%D prefixed one. Consider for instance the prefix set to +%D \type{sidetrack}. +%D +%D \starttyping +%D \pagereference[important] +%D \pagereference[unimportant] +%D \setupreferencing[prefix=sidetrack] +%D \pagereference[important] +%D \stoptyping +%D +%D results in saving (writing) the references +%D +%D \starttyping +%D ...{}{important} +%D ...{}{unimportant} +%D ...{sidetrack}{important}... +%D \stoptyping +%D +%D Now when we call for \type{unimportant}, we will indeed get +%D the pagenumber associated to this reference. But when we +%D call for \type{important}, while the prefix is still set, we +%D will get the pagenumber bound to the prefixed one. +%D +%D {\em Some day, when processing time and memory are no longer +%D performance factors, we will introduce multi||level +%D prefixes.} +%D +%D Before we start analyzing, I introduce a general +%D definition macro. Consider: +%D +%D \starttyping +%D \goto{do}[JS(My_Script{"test",123}),titlepage] +%D \stoptyping +%D +%D This can also be achieved by: +%D +%D \starttyping +%D \definereference[startup][JS(My_Script{"test",123}),titlepage] +%D \goto{do}[REF(startup)] +%D \stoptyping +%D +%D Now is this is a handy feature or not? +%D +%D \showsetup{definereference} +%D +%D We can trace references by setting the next switch to +%D true. + +\def\definereference + {\dodoubleempty\dodefinereference} + +\def\dodefinereference[#1][#2]% + {\ctxlua{jobreferences.define("\referenceprefix","#1",\!!bs\detokenize{#2}\!!es)}} + +\def\resetreference[#1]% + {\ctxlua{jobreferences.reset("\referenceprefix","#1")}} + +\def\setpagereference#1#2% name, specification + {\ctxlua{jobreferences.define("","#1",\!!bs\v!page(\luaescapestring{#2})\!!es)}} + +%D Chained references are defined as: +%D +%D \starttyping +%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)] +%D \stoptyping +%D +%D Actually supporting chains is up to the special driver. Here +%D we only provide the hooks. + +\newif \ifsecondaryreference +\newcount\nofsecondaryreferences + +% the counter stuff should move to the (mkiv) backend + +\def\doifreferencefoundelse#1% + {\ctxlua{jobreferences.doifelse("\referenceprefix","#1")}} + +\def\doprocessreferenceelse#1#2#3% + {\doresetgotowhereever + \nofsecondaryreferences\zerocount + \def\primaryreferencefoundaction {\secondaryreferencefalse#2}% + \def\secondaryreferencefoundaction{\advance\nofsecondaryreferences\plusone\secondaryreferencetrue#2}% + \def\referenceunknownaction {#3}% + \ctxlua{jobreferences.handle("\referenceprefix","#1")}% + \doresetgotowhereever} % to prevent problems with direct goto's + +%D The inner case is simple. Only two cases have to be taken +%D care of: +%D +%D \starttyping +%D \goto{some text}[reference] +%D \goto{some text}[prefix:reference] +%D \stoptyping +%D +%D References to other files however are treated strict or +%D tolerant, depending on their loading and availability: +%D +%D \starttyping +%D \useexternaldocument[somefile][filename][a nice description] +%D +%D \goto{checked reference}[somefile::reference] +%D \goto{unchecked reference}[somefile::] +%D \goto{unchecked reference}[anotherfile::reference] +%D \stoptyping +%D +%D An unknown reference is reported on the screen, in the log +%D file and, when enabled, in the left margin of the text. + +\def\reportreferenceerror#1#2% only once (keep track in lua) + {\ifinpagebody \else + \doifconcepttracing{\doifsomething{#2}{\inleft{\infofont\doboundtext{#2}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}% + \fi + \showmessage\m!references{#1}{[\referenceprefix][#2]}} + +\def\unknownreference{\reportreferenceerror1} +\def\illegalreference{\reportreferenceerror4} + +%D When a reference is not found, we typeset a placeholder +%D (two glyphs are often enough to represent the reference +%D text). + +\def\dummyreference{{\tttf ??}} + +%D To prevent repetitive messages concerning a reference +%D being defined, we set such an unknown reference to an empty +%D one after the first encounter. + +%D Sometimes we want to temporary put a reference out of +%D order. An example can be found in the menu macros. +%D +%D \starttyping +%D \doifreferencepermittedelse{reference}{set}{true}{false} +%D \stoptyping +%D +%D The second argument can be a comma seperated list. + +\let\permittedreferences\empty + + \def\doifreferencepermittedelse#1#2#3% ref found notfound + {\doprocessreferenceelse{#1} + {\donetrue + \ifx\permittedreferences\empty \else + \docheckifreferencepermitted{#1}% + \fi + \ifdone#2\else#3\fi} + {#3\unknownreference{#1}}} + + \def\docheckifreferencepermitted#1% + {\ifx\currentinnerreference\empty + \ifx\currentouterreference\empty \else + \doifinstring{\currentouterreference::}\permittedreferences\donefalse + \fi + \else\ifx\currentouterreference\empty + \doifinstring{\currentinnerreference}\permittedreferences\donefalse + \else + \doifinstring{\currentouterreference::\currentinnerreference}\permittedreferences\donefalse + \fi\fi} + +%D Apart from cross references supplied by the user, \CONTEXT\ +%D generates cross references itself. Most of them are not +%D saved as a reference, but stored with their source, for +%D instance a list or an index entry. Such automatically +%D generated, for the user invisible, references are called +%D {\em internal references}. The user supplied ones are +%D labeled as {\em external references}. +%D +%D A second important characteristic is that when we want to +%D support different backends (viewers), we need to support +%D named destinations as well as page numbers. I invite readers +%D to take a glance at the special driver modules to understand +%D the fine points of this. As a result we will deal with {\em +%D locations} as well as {\em real page numbers}. We explictly +%D call this pagenumber a real one, because it is independant +%D of the page numbering scheme used in the document. +%D +%D One of the reasons for \CONTEXT\ being the first \TEX\ base +%D macropackage to support sophisticated interactive \PDF\ +%D files, lays in the mere fact that real page numbers are +%D available in most two pass data, like references, list data +%D and index entries. +%D +%D We will speak of \type{thisis...} when we are marking a +%D location, and \type{goto...} when we point to such a +%D location. The latter one can be seen as a hyperlink to the +%D former one. In the next macros one we use constructs like: +%D +%D \starttyping +%D \dostart... +%D \dostop... +%D \stoptyping +%D +%D Such macros are used to invoke the relevant specials from +%D the special driver modules (see \type{spec-ini}). The flag +%D \type{\iflocation} signals if we're in interactive mode. + +\def\thisisdestination#1% destination + {\iflocation \ifusepagedestinations \else + \dostartthisislocation{#1}\dostopthisislocation + \fi \fi} + +\def\thisisrealpage#1% pagenumber + {\iflocation + \dostartthisisrealpage{#1}\dostopthisisrealpage + \fi} + +%D The previous tho macros were easy ones, opposite to their +%D counterparts. A common component in these is: +%D +%D \starttyping +%D \dohandlegoto{..}{..}{..} +%D \stoptyping +%D +%D Here data can be whatever needs highlighting, e.g. {\em +%D figure 2.4}, and the start and stop entries handle the +%D specials. The two \DIMENSIONS\ \type{\buttonwidth} and +%D \type{\buttonheight} have to be set when handling the +%D data~(\type{#2}). + +\ifx\buttonheight\undefined \newdimen\buttonheight \fi +\ifx\buttonwidth \undefined \newdimen\buttonwidth \fi + +\def\gotodestination#1#2#3#4#5% url file destination page data + {\iflocation + \ifusepagedestinations + \gotorealpage{#1}{#2}{\number#4}{#5}% + \else + \dohandlegoto + {#5}% + {\the\everyreference\dostartgotolocation\buttonwidth\buttonheight{#1}{#2}{#3}{\number#4}}% + {\dostopgotolocation}% + \fi + \else + {#5}% + \fi} + + \def\gotorealpage#1#2#3#4% url file page data + {\iflocation + \dohandlegoto + {#4}% + {\dostartgotorealpage\buttonwidth\buttonheight{#1}{#2}{\number#3}}% + {\dostopgotorealpage}% + \else + {#4}% + \fi} + +\def\gotoinnerpage#1#2% page data + {\iflocation + \dohandlegoto + {#2}% + {\dostartgotorealpage\buttonwidth\buttonheight\empty\empty{\number#1}}% + {\dostopgotorealpage}% + \else + {#2}% + \fi} + +\def\gotoouterfilepage#1#2#3% file page data + {\iflocation + \dohandlegoto + {#3}% + {\dostartgotorealpage\buttonwidth\buttonheight\empty{#1}{\number#2}}% + {\dostopgotorealpage}% + \else + {#3}% + \fi} + +%D \macros +%D {setreferencefilename} +%D +%D This command can be used in the special drivers to +%D uppercase filenames. This is needed when one wants to +%D produce \CDROM's conforming to ISO9660. We consider is the +%D savest to enable this feature by default. We cannot handle +%D uppercase here, since the suffix is handled in the special +%D driver. Conversion is taken care of by: +%D +%D \starttyping +%D \setreferencefilename somefilename\to\SomeFileName +%D \stoptyping + +\chardef\referencefilecase=0 + + \def\setreferencefilename#1\to#2% + {\ifcase\referencefilecase + \edef#2{#1}% + \or + \uppercasestring#1\to#2% + \or + \lowercasestring#1\to#2% + \else + \edef#2{#1}% + \fi} + +%D Internal references can best be set using the next few +%D macros. Setting such references to unique values is +%D completely up to the macros that call them. +%D +%D \starttyping +%D \thisissomeinternal{tag}{identifier} +%D \gotosomeinternal {tag}{identifier}{pagenumber}{text} +%D \stoptyping + +\def\thisissomeinternal#1#2% tag reference + {\doifsomething{#2}{\thisisdestination{#1:#2}}} + +\def\gotosomeinternal#1#2% #3#4 + {\gotodestination\empty\empty{#1:#2}} + +%D An automatic mechanism is provided too: +%D +%D \starttyping +%D \thisisnextinternal{tag} +%D \gotonextinternal {tag}{number}{pagenumber}{text} +%D \stoptyping +%D +%D The first macro increments a counter. The value of this +%D counter is available in the macro \type{\nextinternalreference} +%D and should be saved somewhere (for instance in a file) for +%D future reference. The second argument of +%D \type {\gotonextinternal} takes such a saved number. One can +%D turn on tracing these references, in which case the +%D references are a bit more verbose. + +\newcount\locationcount + +\newif\ifinternalnamedreferences \internalnamedreferencestrue + +\def\nextinternalreference + {\the\locationcount} + +\def\setnextinternalreference + {\global\advance\locationcount\plusone} + +\def\thisisnextinternal#1% #1 will be removed when we are done with mkiv + {\ifinternalnamedreferences + \thisisdestination{\s!aut:\nextinternalreference}% + \fi} + +\def\insertnextinternal#1% + {\ifinternalnamedreferences + \thisisdestination{\s!aut:\number#1}% + \fi} + +\def\gotonextinternal#1#2#3#4% #1 will be removed when we are done with mkiv + {\ifinternalnamedreferences + \gotodestination\empty\empty{\s!aut:#2}{#3}{#4}% + \else + \gotorealpage\empty\empty{#3}{#4}% + \fi} + +%D We already went through a lot of problems to sort out what +%D kind of reference we're dealing with. Sorting out the user +%D supplied cross references (show/goto this or that) as well +%D as user supplied system references (invoke this or that) is +%D already taken care of in the test routine, but we still have +%D to direct the request to the right (first) routine. + +\def\gotolocation#1#2{\doprocessreferenceelse{#1}{#2}{\unknownreference{#1}}} % obsolete + +%D An inner reference refers to some place in the document +%D itself. + + \def\gotoinnerlocation#1% #2% + {\gotodestination\empty\empty{\referenceprefix\currentinnerreference}\currentrealreference} % {#2} + +\def\gotoinner#1#2#3% prefix inner page data + {\gotodestination\empty\empty{#1#2}{#3}} % {#4} + +%D The outer location refers to another document, specified as +%D file or \URL. + + \def\gotoouterlocation#1#2% % page checken! + {\bgroup + \let\referenceprefix\empty + \setouterlocation\currentouterreference + \ifx\currentinnerreference\empty + \gotorealpage\otherURL\otherfile1{#2}% + \else + \gotodestination\otherURL\otherfile\currentinnerreference\currentrealreference{#2}% + \fi + \egroup} + +\def\gotoouterfile#1#2% file location page data #3 #4 + {\doifelsenothing{#2}{\gotorealpage\empty{#1}}{\gotodestination\empty{#1}{#2}}} + +\def\gotoouterfilepage#1% file page data + {\gotorealpage\empty{#1}\empty} + +\def\gotoouterfilelocation% file location page data + {\gotodestination\empty} + +\def\gotoouterurl#1#2% url args data #2 + {\gotodestination{#1}\empty{#2}1} + +%D Special locations are those that are accessed by saying +%D things like: +%D +%D \starttyping +%D \goto{calculate total}[JS(summarize{10,23,56}] +%D \stoptyping +%D +%D After several intermediate steps this finally arrives at +%D the next macro and expands into (simplified): +%D +%D \starttyping +%D \gotoJSlocation{total{summarize{10,23,56}}}{calculate total} +%D \stoptyping +%D +%D The first argument is the full reference, the second one +%D is the text, in some kind of manipulated form. In practice +%D we split references, so we get: +%D +%D \starttyping +%D \gotoJSlocation{summarize{10,23,56}}{calculate} +%D \gotoJSlocation{summarize{10,23,56}}{total} +%D \stoptyping +%D +%D where \type{calculate} and \type{total} are colored, boxed +%D or whatever \type{\goto} is told to do. +%D +%D The macro \type{\gotoJSlocation} can use \type +%D {\currentreferenceoperation} (in our example +%D \type{summarize}) and \type{\currentreference} (here +%D being \type {10,23,56}) to perform its task. + + \def\gotospeciallocation + {\executeifdefined{goto\currentreferencespecial location}\gobbleoneargument} + +%D Such special macros can be defined by: + + \def\definespeciallocation#1% + {\setvalue{goto#1location}} + +%D The associated test is to be defined by: + +\def\definespecialtest#1% + {\setvalue{\s!do:\v!test:#1}} + +%D This \type{\def} alike macro is to be used as: +%D +%D \starttyping +%D \definespeciallocation{JS}#1#2{... #1 ... #2 ...} +%D \stoptyping +%D +%D In module \type {java-ini} one can see that \type +%D {\gotoJSlocation} looks much like the previous goto +%D definitions. + +%D In this module we define three system references: one for +%D handling navigational, viewer specific, commands, another +%D for jumping to special pages, like the first or last one, +%D and a third reference for linking tree like lists, like +%D tables of contents. The latter two adapt themselves to the +%D current state. +%D +%D An example of an action is: +%D +%D \starttyping +%D \goto{some action}[PreviousJump] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[\v!action(PreviousJump] +%D \stoptyping + +% compatibility hack + +\def\setglobalsystemreference#1#2#3{\definereference[#2][\v!action(#3)]} + +% action actions + +\def\gotoactionspecial#1#2#3#4% special operation arguments data + {\begingroup + \iflocation + \dohandlegoto + {#4}% + {\dostartexecutecommand\buttonwidth\buttonheight{#2}{#3}}% + {\dostopexecutecommand}% + \else + #4% + \fi + \endgroup} + +\def\gotopagespecial#1#2#3#4% page(n) page(+n) page(-n) page(file::1) + {\begingroup + \iflocation + \doifnonzeropositiveelse{#2} + {\doifinstringelse+{#2} + {\edef\currenttargetpage{\the\numexpr\realpageno#2}} + {\doifinstringelse-{#2} + {\edef\currenttargetpage{\the\numexpr\realpageno#2}} + {\edef\currenttargetpage{#2}}}}% + {\edef\currenttargetpage{1}}% + \docheckrealreferencepage\currenttargetpage % new + \gotorealpage\empty\empty\currenttargetpage{#4}% + \else + #4% + \fi + \endgroup} + +%D It is possible to disable the writing of references to the +%D utility file by setting: + +\newif\ifreferencing \referencingtrue + +%D One can also activate an automatic prefix mechanism. By +%D setting the \type{\prefix} variable to \type{+}, the prefix +%D is incremented, when set to \type{-} or empty, the prefix is +%D reset. Other values become the prefix. + +\newcount\prefixcounter + +%D These settings are accomplished by: +%D +%D \showsetup{setupreferencing} +%D +%D In interactive documents verbose references don't always +%D make sense (what is a page number in an unnumbered +%D document). By setting the \type{interaction} variable, one +%D can influences the way interactive references are set. + +\chardef\autocrossfilereferences=0 + +\def\setupreferencing + {\dosingleargument\dosetupreferencing} + +\def\dosetupreferencing[#1]% + {\getparameters + [\??rf] + [\c!prefix=\s!unknown,#1]% + \processaction + [\@@rfstate] + [ \v!stop=>\referencingfalse, + \v!start=>\referencingtrue]% + \processaction + [\@@rfinteraction] + [ \v!all=>\let\dowantedreference\docompletereference, + \v!label=>\let\dowantedreference\dolabelonlyreference, + \v!text=>\let\dowantedreference\dotextonlyreference, + \v!symbol=>\let\dowantedreference\dosymbolreference]% + \chardef\autocrossfilereferences\zerocount + \processaction + [\@@rfautofile] + [ \v!yes=>\chardef\autocrossfilereferences\plusone, + \v!page=>\chardef\autocrossfilereferences\plustwo]% + \chardef\referencefilecase\zerocount + \processaction[\@@rfconvertfile] + [ \v!yes=>\chardef\referencefilecase\plusone, + \v!big=>\chardef\referencefilecase\plusone, + \v!small=>\chardef\referencefilecase\plustwo]% + \setupreferenceprefix[\@@rfprefix]% + \doifelse\@@rfglobal\v!yes + {\settrue \autoglobalfilereferences} + {\setfalse\autoglobalfilereferences}} + +\def\incrementreferenceprefix{+} +\def\decrementreferenceprefix{-} + +\def\setupreferenceprefix[#1]% + {\edef\@@rfprefix{#1}% + \ifx\@@rfprefix\empty + \let\referenceprefix\empty + \else\ifx\@@rfprefix\incrementreferenceprefix + \advance\prefixcounter \plusone % should be global + \edef\referenceprefix{\the\prefixcounter:}% + \let\@@rfprefix\s!unknown + \else\ifx\@@rfprefix\decrementreferenceprefix + \let\referenceprefix\empty + \let\@@rfprefix\s!unknown + \else\ifx\@@rfprefix\s!unknown + % forget about it + \else + \edef\referenceprefix{\@@rfprefix:}% + \fi\fi\fi\fi} + +%D \macros +%D {handlereferenceactions, +%D collectreferenceactions} +%D +%D Sometimes we need to pass the actions connected to +%D references to variables instead of rectangular areas on +%D which one can click. The next macro collects the actions +%D and passes them to a handle. This is a rather dreadfull +%D hack! +%D +%D \starttyping +%D \handlereferenceactions{references}\handle +%D \stoptyping +%D +%D So, \type {\handle} does the final job, which in for +%D instance the \PDF\ drivers comes down to doing something +%D with \type {\lastPDFaction}. + +\newif\ifcollectreferenceactions + +\def\handlereferenceactions#1#2% + {\doifsomething{#1} + {\bgroup + \collectreferenceactionstrue + \doprocessreferenceelse{#1}{#2}{\unknownreference{#1}}% + \egroup}} + +%D The most straightforward way of retrieving references is +%D using \type{\ref}. Consider the reference: +%D +%D \startbuffer +%D \reference[my ref]{{Look}{Here}{I am}} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D We can ask for upto five reference components: +%D +%D \startbuffer +%D user page reference: \ref[p][my ref] +%D text reference: \ref[t][my ref] +%D real page reference: \ref[r][my ref] +%D sub text reference: \ref[s][my ref] +%D extra text reference: \ref[e][my ref] +%D \stopbuffer +%D +%D \typebuffer +%D +%D And get back: +%D +%D \startlines +%D \getbuffer +%D \stoplines + +\def\ref{\dodoubleargument\doref} + +\def\reftypep{\currentpagereference} +\def\reftypet{\currenttextreference} +\def\reftyper{\currentrealreference} +\def\reftypes{\currentsubtextreference} +\def\reftypee{\currentsubsubtextreference} + +\def\doref[#1][#2]% + {\ifsecondargument +% \doifreferencefoundelse{#2} +% {\executeifdefined{reftype#1}\reftypep} +% {\unknownreference{#2}\dummyreference}% + \else + \dummyreference + \fi} + +%D We can typeset a reference using \type{\in}, \type{\at} and +%D \type{\about} and goto specific locations using +%D \type{\goto}. The last one does not make that much sense in +%D a paper document. To complicate things, \PLAIN\ \TEX\ also +%D implements an \type {\in} but fortunately that one only +%D makes sense in math mode. +%D +%D Typesetting the reference is a bit more complicated than one +%D would at first sight expect. This is due to the fact that we +%D distinguish three (five) alternative calls: +%D +%D \placefigure +%D [here][three calls] +%D {Three alternatives reference calls.} +%D {\startcombination[1*3] +%D {\framed{\type{ \in }}} {a} +%D {\framed{\type{ \at }}} {b} +%D {\framed{\type{\goto}}} {c} +%D \stopcombination} +%D +%D \startbuffer +%D \in figure[fig:three calls] +%D \in{figure}[fig:three calls] +%D \in figure a[fig:three calls] +%D \in{figure}{a}[fig:three calls] +%D figure~\in[fig:three calls] +%D \stopbuffer +%D +%D \typebuffer +%D +%D This turns up as: +%D +%D \startlines +%D \getbuffer +%D \stoplines +%D +%D The dual \type{{}} results in a split reference. In a +%D document meant for paper, one is tempted to use the last +%D (most straightforward) alternative. When a document is also +%D meant voor electronic distribution, the former alternatives +%D have preference, because everything between the \type{\in} +%D and~\type{[} becomes active (and when asked for, typeset +%D in a different color and typeface). + +\definecommand in {\dospecialin} +\definecommand at {\dospecialat} +\definecommand about {\dospecialabout} +\definecommand from {\dospecialfrom} +\definecommand over {\dospecialabout} % needed here, else math problems + +\def\currentreferencenumber{\ctxlua{jobreferences.filter("number")}} +\def\currentreferencepage {\ctxlua{jobreferences.filter("page")}} +\def\currentreferencetitle {\ctxlua{jobreferences.filter("title")}} + +\unexpanded\def\dospecialin{\doinatreference\currentreferencenumber} +\unexpanded\def\dospecialat{\doinatreference\currentreferencepage} + +\def\doinatreference#1% + {\doifnextoptionalelse{\dodoinatreference{#1}{}}{\dodoinatreference{#1}}} + +\def\dodoinatreference#1% + {\def\dododoinatreference{\dodododoinatreference{#1}}% + \futurelet\next\dododoinatreference} + +\unexpanded\def\dospecialabout[#1]% + {\dontleavehmode + \bgroup + \@@rfleft + \doprocessreferenceelse{#1} + {\let\crlf\space + \let\\\space + \let\dogotofixed\dogotospace + \dogotospace{\limitatetext\currentreferencetitle\@@rfwidth\unknown}[#1]} + {\unknownreference{#1}\dummyreference}% + \@@rfright + \referenceinfo{<}{#1}% + \egroup} + +%D We arrived at the last step. Before we do the typesetting, +%D we forget all previous (paragraph bound) settings and make +%D sure that we remain in horizontal mode. Next we choose +%D among the several representations. + +%D The previously discussed setup macro lets us specify the +%D representation of references. A symbol reference does not +%D show the specific data, like the number of a figure, but +%D shows one of: \hbox {$^\goforwardcharacter$ +%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending +%D on the direction to go. + + \def\dosymbolreference#1#2[#3]% todo + {\bgroup + \setupsymbolset[\@@iasymbolset]% + \removelastskip + \ifx\currentreferencespecial\empty + \ifx\currentouterreference\empty + \ifnum0\currentrealreference=\zerocount + \ifhmode\strut\high{\symbol[\v!nowhere]}\fi + \else\ifnum0\currentrealreference>\realpageno + \dodosymbolreference{#2}{\high{\symbol[\v!next]}}% + \else\ifnum0\currentrealreference<\realpageno + \dodosymbolreference{#2}{\high{\symbol[\v!previous]}}% + \else + \ifhmode\strut\high{\symbol[\v!nowhere]}\fi + \fi\fi\fi + \else + \gotoouterlocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}% + \fi + \else + \gotospeciallocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}% + \fi + \egroup} + + \def\dodosymbolreference#1#2% todo + {#1\hbox{\gotorealpage\empty\empty\currentrealreference{\dolocationattributes\??ia\c!style\c!color{#2}}}} + +%D The other alternatives just conform their names: only the +%D label, only the text, or the label and the text. + +\def\dounknownreference#1#2[#3]% + {\unknownreference{#3}\dotextprefix{#2}\dummyreference}% + +\def\docompletereference#1#2[#3]% + {\iflocationsplit + \doifsomespaceelse{#2}\dogotospace\dogotofixed{\dotextprefix{#2}#1}[#3]% + \else + \dogotofixed{\dotextprefix{#2}#1}[#3]% + \fi} + +\def\dolabelonlyreference#1#2[#3]% + {\doifsomespaceelse{#2} + {\doifsomething{#2}{\dogotospace{#2}[#3]}} + {\dogotofixed{\dotextprefix{#2}}[#3]}} + +\def\dotextonlyreference#1#2[#3]% + {\dotextprefix{#2}\dogotofixed{#1}[#3]} + +\let\dowantedreference\docompletereference + +%D \macros +%D {definereferenceformat} +%D +%D The next few macros were made for for David Arnold and Taco +%D Hoekwater. They can be used for predefining reference +%D texts, and thereby stimulate efficiency. +%D +%D [more documentation will be added] +%D +%D \starttyping +%D \definereferenceformat[informula] [left=(,right=),text=formula] +%D \definereferenceformat[informulas] [left=(,right=),text=formulas] +%D \definereferenceformat[andformula] [left=(,right=),text=and] +%D \definereferenceformat[andformulas][left=(,right=),text=and] +%D +%D \informula [b] and \informula [for:c] +%D the \informula {formulas}[b] \informula {and} [for:c] +%D the \informulas {formulas}[b] \informula {and} [for:c] +%D the \informulas [b] \informula {en} [for:c] +%D the \informulas [b] \andformula [for:c] +%D \stoptyping +%D +%D Instead of a text, one can specify a label, which should +%D be defined with \type {\setuplabeltext}. + +% todo: inherit + +\def\definereferenceformat + {\dodoubleargument\dodefinereferenceformat} + +\def\dodefinereferenceformat[#1][#2]% + {\iffirstargument + \getparameters[\??rf#1] + [\c!left=, % of the number + \c!right=, % of the number + \c!text=, % before the number + \c!label=, % can be {left}{right} + \c!command=\in, + #2]% + \unexpanded\setvalue{#1}% + {\dontleavehmode\doexecutereferenceformat{#1}}% + \fi} + +\def\noexecutelabelreferenceformat#1% + {\doifvaluesomething{\??rf#1\c!text} + {\gdef\textofreference{\csname\??rf#1\c!text\endcsname}}% + \csname\??rf#1\c!command\endcsname} + +\def\doexecutelabelreferenceformat#1% + {\csname\??rf#1\c!command\endcsname + {\leftlabeltext {\csname\??rf#1\c!label\endcsname}}% + {\rightlabeltext{\csname\??rf#1\c!label\endcsname}}} + +\def\doexecutereferenceformat#1% + {\gdef\leftofreference {\csname\??rf#1\c!left \endcsname}% + \gdef\rightofreference{\csname\??rf#1\c!right\endcsname}% + \global\let\textofreference\empty % otherwise ~ added + \doifelsevaluenothing{\??rf#1\c!label} + \noexecutelabelreferenceformat\doexecutelabelreferenceformat{#1}} + +\let\leftofreference \relax +\let\rightofreference\relax +\let\textofreference \relax + +% fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]% + +\def\dodododoinatreference#1#2#3[#4]% no \removeunwantedspaces (fails on metafun) + {\ifx\next\bgroup + \dododododoinatreference{\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]% + \else + \dododododoinatreference{\leftofreference#1\rightofreference}{#2#3}[#4]% + \fi} + +\let\dosymbolreference\dowantedreference + +\def\dododododoinatreference#1#2[#3]% + {\dontleavehmode % replaces \leaveoutervmode + \begingroup + \forgetall + \postponenotes + \doifreferencefoundelse{#3} + {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#3]}% + {\dounknownreference{#1}{#2}[#3]}% + \referenceinfo<{#3}% + \endgroup} + + +%D In interactive documents going to a specific location is not +%D bound to cross references. The \type{\goto} commands can be +%D used to let users access another part of the document. In +%D this respect, interactive tables of contents and registers +%D can be considered goto's. Because in fact a \type{\goto} is +%D just a reference without reference specific data, the +%D previous macros are implemented using the goto +%D functionality. +%D +%D \showsetup{goto} +%D +%D One important chaacteristic is that the first argument of +%D \type{\goto} (and therefore \type{\at} and \type{\in} is +%D split at spaces. This means that, although hyphenation is +%D prevented, long references can cross line endings. + +\newif\ifsharesimilarreferences \sharesimilarreferencestrue +\newcount\similarreference % 0=noppes 1=create/refer 2,3,..=refer + +\unexpanded\def\goto#1#2% + {\dogoto{#1}#2} + +\def\dogoto#1[#2]% + {\dontleavehmode + \bgroup + \postponenotes + % todo: handle empty #1 + \doifelsenothing{#1} + {\dosymbolreference{}{}[#2]} + {\dogotospace{#1}[#2]}% + \egroup + \referenceinfo{<}{#2}} + +% inefficient, we need to save the shared one (just reuse last command in lua) + +\def\dogotospace#1[#2]% + {\iflocationsplit + \ifsecondaryreference + \setbox\scratchbox\hbox % will change anyway + \fi % due to space insertion + {\let\dogotospace\dogotofixed + \iflocation + \def\processisolatedword##1% + {\ifisolatedwords\ifsharesimilarreferences + \global\advance\similarreference \plusone + \fi\fi + \hbox\bgroup + \doprocessreferenceelse{#2}{##1\presetgoto}{\unknownreference{#2}##1\relax}% + \egroup}% + \doattributes\??ia\c!style\c!color{\processisolatedwords{#1}\processisolatedword}% + \else + #1\relax % \relax prevents #1's next macros from gobbling \fi + \fi}% + \else + \iflocation + \hbox{\doattributes\??ia\c!style\c!color{\doprocessreferenceelse{#2}{#1\presetgoto}{\unknownreference{#2}#1\relax}}}% + \else + #1\relax % \relax prevents #1's next macros from gobbling \fi + \fi + \fi + \global\similarreference\zerocount} + +\def\dogotofixed#1[#2]% + {{\iflocation + \hbox{\doattributes\??ia\c!style\c!color{\doprocessreferenceelse{#2}{#1\presetgoto}{\unknownreference{#2}#1\relax}}}% + \else + #1% + \fi}} + +%D In case the auto split feature is not needed or even not +%D even wanted, \type{\gotobox} can be used. + +\unexpanded\def\gotobox#1[#2]% + {\dontleavehmode + \bgroup + \locationstrutfalse + \doprocessreferenceelse{#2} + {\dogotofixed{#1}[#2]} + {\hbox{\unknownreference{#2}#1}}% + \referenceinfo{<}{#2}% + \egroup} + +%D An reference to another document can be specified as a file +%D or as an \URL. Both are handled by the same mechanism and +%D can be issued by saying something like: +%D +%D \starttyping +%D \goto[dictionary::the letter a] +%D \stoptyping +%D +%D One can imagine that many references to such a dictionary +%D are made, so in most cases such a document reference in an +%D indirect one. +%D +%D \showsetup{useexternaldocument} +%D +%D For example: +%D +%D \starttyping +%D \useexternaldocument +%D [dictionary][engldict] +%D [The Famous English Dictionary] +%D \stoptyping +%D +%D The next macro implements these relations, and also take +%D care of loading the document specific references. +%D +%D The \URL\ alternative takes four arguments: +%D +%D \showsetup{useURL} +%D +%D like: +%D +%D \starttyping +%D \useURL +%D [dictionary][http://www.publisher.com/public][engldict] +%D [The Famous English Dictionary] +%D \stoptyping +%D +%D Several specifications are possible: +%D +%D \starttyping +%D \useURL [id] [url] [file] [description] +%D \useURL [id] [url] [file] +%D \useURL [id] [url] +%D \stoptyping +%D +%D This time we don't load the references when no file is +%D specified. This is logical when one keeps in mind that a +%D valid \URL\ can also be a mail address. + +\def\usefile{\dotripleargument\dousefile} +\def\useurl {\doquadrupleempty\douseurl} + +\let\useURL \useurl +\let\useexternaldocument\usefile + +\def\douseurl[#1][#2][#3][#4]% + {\ctxlua{jobreferences.urls.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es,\!!bs\detokenize{#4}\!!es)}} + +\def\dousefile[#1][#2][#3]% + {\ctxlua{jobreferences.files.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} + +% \doifsomething\@@urstyle{\let\@@iastyle\@@urstyle\let\@@urstyle\empty}% +% \doifsomething\@@urcolor{\let\@@iacolor\@@urcolor\let\@@urcolor\empty}% + +%D \macros +%D {url,setupurl} +%D +%D We also have: \type{\url} for directly calling the +%D description. So we can say: +%D +%D \starttyping +%D \useURL [one] [http://www.test.nl] +%D \useURL [two] [http://www.test.nl] [] [Some Site] +%D +%D \url[one] or \from[two] or \goto{Whatever Site}[URL(two)] +%D \stoptyping +%D +%D An \URL\ can be set up with +%D +%D \showsetup{setupurl} + +\def\setupurl + {\dodoubleargument\getparameters[\??ur]} + +\unexpanded\def\url[#1]% + {\dontleavehmode + \begingroup + \dosetfontattribute\??ur\c!style + \dosetcolorattribute\??ur\c!color + \ctxlua{jobreferences.urls.get("#1","\@@uralternative","\@@urspace")}% + \dostopattributes + \endgroup} + +%D This macro is hooked into a support macro, and thereby +%D \URL's break ok, according to the setting of a switch, +%D +%D \startbuffer +%D \useURL +%D [test] +%D [sentence_sentence%sentence#sentence~sentence/sentence//sentence:sentence.sentence] +%D \stopbuffer +%D +%D \typebuffer +%D +%D Such an \URL\ is, depending on the settings, hyphenated as: +%D +%D \getbuffer +%D +%D \startlinecorrection +%D \hbox to \hsize +%D {\hss\en +%D \setupreferencing[urlalternative=both]% +%D \vbox{\hsize.25cm\hbox{\bf both}\prewordbreak\url[test]}% +%D \hss +%D \setupreferencing[urlalternative=before]% +%D \vbox{\hsize.25cm\hbox{\bf before}\prewordbreak\url[test]}% +%D \hss +%D \setupreferencing[urlalternative=after]% +%D \vbox{\hsize.25cm\hbox{\bf after}\prewordbreak\url[test]}% +%D \hss} +%D \stoplinecorrection +%D +%D By setting \type{urlspace=yes} one can get slightly better +%D spacing when using very long \URL's. +%D +%D When defining the external source of information, one can +%D also specify a suitable name (the last argument). This name +%D can be called upon with: +%D +%D \showsetup{from} + +\def\dospecialfrom + {\dosingleempty\dodospecialfrom} + +\def\dodospecialfrom[#1]% + {\dontleavehmode\ctxlua{jobreferences.from("#1","","")}} + +%D We also support: +%D +%D \starttyping +%D \goto{some text}[file(identifier{location}] +%D \stoptyping +%D +%D which is completely equivalent with +%D +%D \starttyping +%D \goto{some text}[identifier::location] +%D \stoptyping + +\def\gotofilespecial#1#2#3#4% special operation arguments data + {\begingroup\iflocation\gotoouterfile{#2}{#3}{#4}\else#4\fi\endgroup} + +\def\gotourlspecial#1#2#3#4% special operation arguments data + {\begingroup\iflocation\gotoouterurl{#2}{#3}{#4}\else#4\fi\endgroup} + +%D A special case of references are those to programs. These, +%D very system dependant references are implemented by abusing +%D some of the previous macros. +%D +%D \showsetup{setupprograms} +%D \showsetup{defineprogram} +%D \showsetup{program} % changed functionality ! +%D +%D The latter gives access to the description of the program, +%D being the last argument to the definition command. + +% also lua, like urls and files + +\def\setupprograms + {\dodoubleargument\getparameters[\??pr]} + +\def\defineprogram + {\dotripleargument\dodefineprogram} + +\def\dodefineprogram[#1][#2][#3]% + {\ctxlua{jobreferences.programs.define("#1","#2","#3")}} + +\def\program[#1]% incompatible, more consistent, hardy used anyway + {\dontleavehmode + \begingroup + \dosetfontattribute\??pr\c!style + \dosetcolorattribute\??pr\c!color + \ctxlua{jobreferences.programs.get("#1","\@@pralternative","\@@prspace")}% + \endgroup} + +% needs an update: program(abc{arg}) + +\def\gotoprogramspecial#1#2#3#4% special operation arguments data + {\begingroup + \iflocation + \dohandlegoto + {#4}% + {\dostartrunprogram\buttonwidth\buttonheight{\@@prdirectory#2}{#3}}% + {\dostoprunprogram}% + \else + #4% + \fi + \endgroup} + +%D As we can see, we directly use the special reference +%D mechanism, which means that +%D +%D \starttyping +%D \goto{some text}[program(name{args})] +%D \stoptyping +%D +%D is valid. + +%D The next macro provides access to the actual pagenumbers. +%D When documenting and sanitizing the original reference +%D macros, I decided to keep the present meaning as well as to +%D make this meaning available as a special reference method. +%D So now one can use: +%D +%D \starttyping +%D \gotopage{some text}[location] +%D \gotopage{some text}[number] +%D \gotopage{some text}[file::number] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[page(location)] +%D \goto{some text}[page(number)] +%D \goto{some text}[file::page(number)] +%D \stoptyping +%D +%D Here location is a keyword like \type{nextpage}. +%D +%D \showsetup{gotopage} + +\def\definepage + {\dodoubleargument\dodefinepage} + +\def\dodefinepage[#1][#2]% + {\definereference[#1][page(#1)]} + +\def\gotopage#1[#2]% + {\goto{#1}[\v!page(#2)]} + +%D The previous definitions are somewhat obsolete so we don't +%D use it here. + +%D A still very rudimentary|/|experimental forward|/|backward +%D reference mechanism is provided by the macro \type{\atpage}: +%D +%D \starttyping +%D ... \somewhere{backward text}{forward text}[someref] ... +%D ... \atpage[someref] ... +%D \stoptyping +%D +%D In future versions there will be more sophisticated + +%D support, also suitable for references to floating bodies. + +\def\analysedreference#1% + {\ctxlua{jobreferences.analysis("\referenceprefix","#1")}} + +\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 % todo + {\dontleavehmode + \ifcase\analysedreference{#4}\relax + \unknownreference{#4}#1/#2% + \or + \doifelsenothing{#2}{\dosymbolreference{}{}[#4]}{\dogotospace{#2}[#4]}% + \or % forward + \doifelsenothing{#1}{\dosymbolreference{}{}[#4]}{\dogotospace{#1}[#4]}% + \or % backward + \doifelsenothing{#2}{\dosymbolreference{}{}[#4]}{\dogotospace{#2}[#4]}% + \fi + \referenceinfo{<}{#4}} + +\unexpanded\def\atpage[#1]% todo + {\dontleavehmode +% \docheckrealreferencepage{}% +% \doifreferencefoundelse{#1} +% {\ifrealreferencepage +% \ifforwardreference +% \dogotofixed{\labeltext\v!hencefore}[#1]% +% \else +% \dogotofixed{\labeltext\v!hereafter}[#1]% +% \fi +% \else +% \dogotofixed{\labeltexts\v!atpage\currentpagereference}[#1]% +% \fi} +% {\unknownreference{#1}% +% \labeltexts\v!page\dummyreference}% + \referenceinfo{<}{#1}} + +%D We can cross link documents by using: +%D +%D \showsetup{coupledocument} +%D +%D like: +%D +%D \starttyping +%D \coupledocument[print][somefile][chapter,section] +%D \stoptyping +%D +%D After which when applicable, we have available the +%D references: +%D +%D \starttyping +%D \goto{print version}[print::chapter] +%D \stoptyping +%D +%D and alike. The title placement definition macros have a +%D key \type{file}, which is interpreted as the file to jump +%D to, that is, when one clicks on the title. + +\newif\ifautocrossdocument + +\def\coupledocument + {\doquadrupleempty\docoupledocument} + +\def\docoupledocument[#1][#2][#3][#4]% [name] [file] [sections] [description] + {\ifthirdargument + % this will be done differently (when it's needed) + \fi} + +%D Buttons are just what their names says: things that can be +%D clicked (pushed) on. They are similar to \type{\goto}, +%D except that the text argument is not interpreted. +%D Furthermore one can apply anything to them that can be done +%D with \type{\framed}. +%D +%D \startbuffer +%D \button[width=3cm,height=1.5cm]{Exit}[ExitViewer] +%D \stopbuffer +%D +%D \typebuffer +%D +%D gives +%D +%D \getbuffer +%D +%D This command is formally specified as: +%D +%D \showsetup{button} +%D +%D The characteristics can be set with: +%D +%D \showsetup{setupbuttons} + +\def\setupbuttons + {\dodoubleargument\getparameters[\??bt]} + +\definecomplexorsimpleempty\button + +\def\complexbutton + {\docomplexbutton\??bt} + +\presetlocalframed[\??bt] + +\long\def\docomplexbutton#1[#2]#3#4% get rid of possible space before [#4] + {\dodocomplexbutton#1[#2]{#3}#4} % #4 == [ + +\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie + +\long\def\dodocomplexbutton#1[#2]#3[#4]% #3 can contain [] -> {#3} later + {\begingroup + \doifvalue{#1\c!state}\v!stop\locationfalse + \iflocation + \resetgoto + \ConvertConstantAfter\doifelse{#3}\v!none\hphantom\hbox + {\doifelsenothing{#4} + {\setlocationboxnop#1[#2]{#3}[#4]} + {\doifreferencefoundelse{#4} % INEFFICIENT + {\setlocationboxyes#1[#2]{#3}[#4]} + {\unknownreference{#4}% + \setlocationboxnop#1[#2]{#3}[#4]}}}% + \fi + \endgroup} + +%D Interaction buttons, in fact a row of tiny buttons, are +%D typically only used for navigational purposed. The next +%D macro builds such a row based on a specification list. +%D +%D \startbuffer +%D \interactionbuttons +%D [width=\hsize][page,PreviousJump,ExitViewer] +%D \stopbuffer +%D +%D \typebuffer +%D +%D gives +%D +%D \getbuffer +%D +%D Apart from individual entries, one can use \type{page} and +%D \type {subpage} as shortcuts to their four associated buttons. +%D The symbols are derived from the symbols linked to the +%D entries. + +% does not work well with for instance SomeRef{whatever} + +\def\interactionbuttons + {\dodoubleempty\dointeractionbuttons} + +\def\dointeractionbuttons[#1][#2]% er is een verdeel macro \horizontalfractions + {\iflocation + % BUG: fails when frame=off; best is to rewrite this macro + \bgroup + \doif\@@ibstate\v!stop\locationfalse + \iflocation + \ifsecondargument + \setupinteractionbar[#1]% + \checkinteractionbar{1.5em}\v!broad\!!zeropoint % brrrrr + \setbox2\hbox{\localframed[\??ib][\c!background=]{\symbol[\@@iasymbolset][\v!previouspage]}}% + \!!heighta\ht2 % needed because we default to nothing + \setupinteractionbar[\c!strut=\v!no]% + \setinteractionparameter\c!width\!!zeropoint + \!!counta\zerocount % new, was 1 + \processallactionsinset + [#2] + [ \v!page=>\advance\!!counta 4, + \v!subpage=>\advance\!!counta 4, + \s!unknown=>\advance\!!counta 1]% + \ifdim\@@ibwidth=\zeropoint + \!!widtha2em + \advance\!!widtha \@@ibdistance % new + \!!widthb\!!counta\!!widtha + \advance\!!widthb -\@@ibdistance % new + \else + \!!widtha\@@ibwidth + \!!widthb\@@ibdistance % new + \multiply\!!widthb \!!counta % new + \advance\!!widthb -\@@ibdistance % new + \advance\!!widtha -\!!widthb % new + \divide\!!widtha \!!counta + \!!widthb\@@ibwidth + \fi + \def\goto##1% clash ? + {\setnostrut + \edef\localreference{##1}% + \normalexpanded{\noexpand\dodocomplexbutton\??ib[\c!height=\the\!!heighta,\c!width=\the\!!widtha]}% + {\dontleavehmode\symbol[\@@iasymbolset][\localreference]}% + [\localreference]% + \hss}% + \hbox to \!!widthb + {\processallactionsinset + [#2] + [ \v!page=>\goto\v!firstpage + \goto\v!nextpage + \goto\v!previouspage + \goto\v!lastpage, + \v!subpage=>\goto\v!firstsubpage + \goto\v!nextsubpage + \goto\v!previoussubpage + \goto\v!lastsubpage, + \s!unknown=>\goto\commalistelement]% + \unskip}% + \else + \interactionbuttons[][#1]% + \fi + \fi + \egroup + \fi} + +%D \macros +%D {overlaybutton} +%D +%D For converience we provide: +%D +%D \starttyping +%D \overlaybutton[reference] +%D \stoptyping +%D +%D This command can be used to define overlays an/or can be +%D used in the whatevertext areas, like: +%D +%D \starttyping +%D \defineoverlay[PrevPage][\overlaybutton{PrevPage}] +%D \setupbackgrounds[page][background=PrevPage] +%D \setuptexttexts[\overlaybutton{NextPage}] +%D \stoptyping +%D +%D For practical reasons, this macro accepts square brackets +%D as well as braces. + +\definecomplexorsimple\overlaybutton + +\def\simpleoverlaybutton#1% + {\complexoverlaybutton[#1]} + +\def\complexoverlaybutton[#1]% + {\iflocation + \doprocessreferenceelse{#1} + {\overlayfakebox {#1}} + {\unknownreference{#1}}% + \fi} + +\def\overlayfakebox#1% + {\hbox + {\setbox\scratchbox\null + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \locationstrutfalse + \box\scratchbox}} + +%D \macros +%D {dotextprefix} +%D +%D In previous macros we used \type {\dotextprefix} to +%D generate a space between a label and a number. +%D +%D \starttyping +%D \dotextprefix{text} +%D \stoptyping +%D +%D Only when \type {text} is not empty, a space is inserted. + +\def\dotextprefix#1% + {\begingroup + \global\labeltextdonefalse % this is an ugly dependancy, + \setbox\scratchbox\hbox{#1}% to be solved some day + \ifdim\wd\scratchbox>\zeropoint + \unhbox\scratchbox + \iflabeltextdone\else\@@rfseparator\fi + \else + \unhbox\scratchbox + \fi + \endgroup} + +%D In the next settings we see some variables that were not +%D used here and that concern the way the pagenumbers refered +%D to are typeset. + +\setupreferencing + [\c!state=\v!start, + \c!autofile=\v!no, + \v!part\c!number=\v!yes, + \v!chapter\c!number=\v!no, + \c!interaction=\v!all, + \c!convertfile=\v!no, + %\c!strut=\v!no, % some day an option + \c!prefix=, + \c!width=.75\makeupwidth, + \c!left=\quotation\bgroup, + \c!right=\egroup, + \c!global=\v!no, + \c!expansion=\v!no, + \c!separator=\nonbreakablespace] + +\setupurl + [\c!alternative=\v!both, + \c!space=\v!no, + \c!style=\v!type, + \c!color=] + +\setupprograms + [\c!directory=, + \c!alternative=\v!both, + \c!space=\v!no, + \c!style=\v!type, + \c!color=] + +\definereference [\v!CloseDocument ] [action(close)] +\definereference [\v!ExitViewer ] [action(exit)] +\definereference [\v!FirstPage ] [action(first)] +\definereference [\v!LastPage ] [action(last)] +\definereference [\v!NextJump ] [action(forward)] +\definereference [\v!NextPage ] [action(next)] +\definereference [\v!PauseMovie ] [action(pausemovie)] +\definereference [\v!PauseSound ] [action(pausesound)] +\definereference [\v!PauseRendering ] [action(pauserendering)] +\definereference [\v!PreviousJump ] [action(backward)] +\definereference [\v!PreviousPage ] [action(previous)] +\definereference [\v!PrintDocument ] [action(print)] +\definereference [\v!SaveForm ] [action(exportform)] +\definereference [\v!LoadForm ] [action(importform)] +\definereference [\v!ResetForm ] [action(resetform)] +\definereference [\v!ResumeMovie ] [action(resumemovie)] +\definereference [\v!ResumeSound ] [action(resumesound)] +\definereference [\v!ResumeRendering ] [action(resumerendering)] +\definereference [\v!SaveDocument ] [action(save)] +\definereference [\v!SaveNamedDocument] [action(savenamed)] +\definereference [\v!OpenNamedDocument] [action(opennamed)] +\definereference [\v!SearchDocument ] [action(search)] +\definereference [\v!SearchAgain ] [action(searchagain)] +\definereference [\v!StartMovie ] [action(startmovie)] +\definereference [\v!StartSound ] [action(startsound)] +\definereference [\v!StartRendering ] [action(startrendering)] +\definereference [\v!StopMovie ] [action(stopmovie)] +\definereference [\v!StopSound ] [action(stopsound)] +\definereference [\v!StopRendering ] [action(stoprendering)] +\definereference [\v!SubmitForm ] [action(submitform)] +\definereference [\v!ToggleViewer ] [action(toggle)] +\definereference [\v!ViewerHelp ] [action(help)] +\definereference [\v!HideField ] [action(hide)] +\definereference [\v!ShowField ] [action(show)] +\definereference [\v!GotoPage ] [action(gotopage)] +\definereference [\v!GotoPage ] [action(gotopage)] +\definereference [\v!Query ] [action(query)] +\definereference [\v!QueryAgain ] [action(queryagain)] +\definereference [\v!FitWidth ] [action(fitwidth)] +\definereference [\v!FitHeight ] [action(fitheight)] +\definereference [\v!ShowThumbs ] [action(thumbnails)] +\definereference [\v!ShowBookmarks ] [action(bookmarks)] + +\definereference [\v!firstpage] [page(\firstpage)] +\definereference [\v!previouspage] [page(\prevpage)] +\definereference [\v!nextpage] [page(\nextpage)] +\definereference [\v!lastpage] [page(\lastpage)] +\definereference [\v!firstsubpage] [page(\firstsubpage)] +\definereference [\v!previoussubpage] [page(\prevsubpage)] +\definereference [\v!nextsubpage] [page(\nextsubpage)] +\definereference [\v!lastsubpage] [page(\lastsubpage)] +\definereference [\v!first] [page(\firstpage)] +\definereference [\v!previous] [page(\prevpage)] +\definereference [\v!next] [page(\nextpage)] +\definereference [\v!last] [page(\lastpage)] +\definereference [\v!first\v!sub] [page(\firstsubpage)] +\definereference [\v!previous\v!sub] [page(\prevsubpage)] +\definereference [\v!next\v!sub] [page(\nextsubpage)] +\definereference [\v!last\v!sub] [page(\lastsubpage)] + +%D We cannot set up buttons (not yet, this one calls a menu macro): + +\protect \endinput diff --git a/tex/context/base/strc-ref.tex b/tex/context/base/strc-ref.tex deleted file mode 100644 index 23fc3e01e..000000000 --- a/tex/context/base/strc-ref.tex +++ /dev/null @@ -1,1905 +0,0 @@ -%D \module -%D [ file=strc-ref, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Cross Referencing, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} - -\registerctxluafile{strc-ref}{1.001} - -\unprotect - -%D This module is a (partial) rewrite of core-ref.tex for \MKIV. As -%D such it will be a moving target for a while. - -%D Later we will do a further cleanup and move much of the code to -%D \LUA\ (i.e.\ better backend integration). - -\let\mainreference\gobblefivearguments - -% this will go when we got rid of the tuo file - -\let\currentfolioreference \!!zerocount % only used in xml-fo -\let\resetreferences \relax -\let\setreferences \relax -\let\showcurrentreference \relax -\let\setexecutecommandcheck\gobbletwoarguments - -\def\s!full{full} -\def\s!text{text} -\def\s!page{page} - -% todo : unknown/illegal reference no arg -% todo : +n pages check on 'samepage' (contrastcolor) -% todo : multiple text in reference - -% Makes more sense to build action data first, especially now -% openaction etc are supported. -% -% \definespecial\doexecuteactionchain w h -% \definespecial\dosetgotolocation -% \definespecial\dosetexecuteJScode -% ... - -%D This module deals with referencing. In \CONTEXT\ referencing -%D is one of the core features, although at a first glance -%D probably nobody will notice. This is good, because -%D referencing should be as hidden as possible. -%D -%D In paper documents, referencing comes down to cross -%D referencing, but in their interactive counterparts, is also -%D involves navigation. Many features implemented here are -%D therefore closely related to navigation. -%D -%D Many \CONTEXT\ commands can optionally be fed with a -%D reference. Such a reference, when called upon, returns the -%D number of a figure, table, chapter etc, a piece of text, or -%D a pagenumber. -%D -%D There are three ways of defining a reference: -%D -%D \starttyping -%D \pagereference[here] -%D \textreference[here]{some text} -%D \stoptyping -%D -%D the third alternative combines them in: -%D -%D \starttyping -%D \reference[here]{some text} -%D \stoptyping - -\def\textreference {\dosingleargument\dotextreference} -\def\pagereference {\dosingleargument\dopagereference} -\def\reference {\dosingleargument\doreference } - -%D These are implemented in a low level form as: - -\def\dotextreference[#1]{\dosetreference\s!text{#1}} -\def\dopagereference[#1]{\dosetreference\s!page{#1}{}} -\def\doreference [#1]{\dosetreference\s!full{#1}} - -%D Actually there is not much difference between a text and a -%D full reference, but it's the concept that counts. The low -%D level implementation is: - -\newcount\crossreferencenumber - -\def\dofinishfullreference#1#2% - {\normalexpanded{\noexpand\ctxlatelua{jobreferences.enhance("#1","#2")}}% - \referenceinfo>{#1\letterbar#2}} - -\let\dofinishpagereference\dofinishfullreference - -\def\dofinishtextreference#1#2% - {\normalexpanded{\noexpand\ctxlatelua{jobreferences.enhance("#1","#2",{})}}% - \referenceinfo>{#1\letterbar#2}} - -\def\dosetreference#1#2#3% kind labels text -> todo: userdata - {\ifreferencing - \global\advance\crossreferencenumber\plusone - \edef\currentreferencekind{#1}% - \edef\currentreferencelabels{#2}% - \edef\currentreferenceexpansion{\@@rfexpansion}% {\referenceparameter\c!expansion} - \ifx\currentreferencelabels\empty \else - \ifx\currentreferenceexpansion\s!xml - \xmlstartraw - \xdef\currentreferencetext{#3}% - \xmlstopraw - \globallet\currentreferencecoding\s!xml - \else - \ifx\currentreferenceexpansion\v!yes - \xdef\currentreferencetext{#3}% - \else - \xdef\currentreferencetext{\detokenize{#3}}% - \fi - \globallet\currentreferencecoding\s!tex - \fi - \setnextinternalreference - \ctxlua { - jobreferences.set("\currentreferencekind", "\referenceprefix","\currentreferencelabels", - { - references = { - internal = \nextinternalreference, - block = "\currentstructureblock", - section = structure.sections.currentid(), - }, - metadata = { - kind = "#1", - catcodes = \the\catcodetable, - xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text - }, - entries = { - text = \!!bs\currentreferencetext\!!es - } - }) - jobreferences.setinternalreference("\referenceprefix","\currentreferencelabels",\nextinternalreference) - }% - \fi - \fi} - -%D For compatibility we provide: - -\def\rawreference #1#2#3{\dosetreference\s!full{#2}{#3}} % tag, labels, text -\def\rawpagereference #1#2{\dosetreference\s!page{#2}{}} % tag, labels -\def\rawtextreference#1#2#3{\dosetreference\s!text{#2}{#3}} % tag, labels, text - -\def\defaultreferencepage#1{[[[#1]]]} -\def\defaultreferencetext#1{[[[#1]]]} - -%D These macros depend on three other ones, -%D \type {\makesectionformat}, that generated \type -%D {\sectionformat}, \type {\pagenumber}. The not yet used -%D argument \type{#1} is a tag that specifies the type of -%D reference. - -%D \macros -%D {everyreference} -%D -%D For rather tricky purposes, one can assign sanitizing -%D macros to \type{\everyreference} (no longer that relevant). - -\newevery \everyreference \relax - -%D This is really needed, since for instance Polish has a -%D different alphabet and needs accented entries in registers. - -\appendtoks - \cleanupfeatures -\to \everyreference - -%D We did not yet discuss prefixing. Especially in interactive -%D documents, it's not always easy to keep track of duplicate -%D references. The prefix mechanism, which we will describe -%D later on, solves this problem. By (automatically) adding a -%D prefix one keeps references local, but the global ones in -%D view. To enable this feature, we explictly split the prefix -%D from the reference. - -\let\referenceprefix\empty - -%D For a long time the only way to access an external file was -%D to use the file prefix (\type {somefile::}. However, when -%D you split up a document, redefining the references may be -%D such a pain, that another approach is feasible. By setting -%D the \type {autofile} variable to \type {yes} or \type -%D {page}, you can access the reference directly. -%D -%D \starttabulate[||||] -%D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR -%D \NC $\star$ \NC \NC \NC\NR -%D \NC $\star$ \NC $\star$ \NC $\star$ \NC\NR -%D \NC \NC $\star$ \NC \NC\NR -%D \stoptabulate - -\def\usereferences[#1]% - {\writestatus\m!systems{references from other files are handled automatically}} - -%D As mentioned we will also use the cross reference mechanism -%D for navigational purposes. The main reason for this is that -%D we want to treat both categories alike: -%D -%D \starttyping -%D \goto{go back}[PreviousJump] -%D \goto{colofon}[colofon page] -%D \stoptyping -%D -%D Here \type{PreviousJump} is handled by the viewer, while the -%D \type{colofon page} reference is, apart from hyperlinking, a -%D rather normal reference. -%D -%D We already saw that cross refences are written to and read -%D from a file. The pure navigational ones don't need to be -%D written to file, but both for fast processing and -%D transparant integration, they are saved internally as a sort -%D of reference. We can easily distinguish such system -%D references from real cross reference ones by their tag. -%D -%D We also use the odd/even characteristic to determine the -%D page state. - -\let\currentrealreference \empty -\let\currentpagereference \empty -\let\currenttextreference \empty -\let\currentreferenceorder \empty -\let\currentsubtextreference \empty -\let\currentsubsubtextreference\empty - -%D System references only have one component: - -\newif\ifforwardreference -\newif\ifrealreferencepage - -\def\docheckrealreferencepage#1% todo - {\doifnumberelse{#1} - {\ifnum#1=\realpageno - \realreferencepagetrue - \else - \realreferencepagefalse - \fi} - {\realreferencepagefalse}} - -%D Text references can contain more than one entry and -%D therefore we check for -%D -%D \starttyping -%D {entry} -%D \stoptyping -%D -%D or -%D -%D \starttyping -%D {{entry}{entry}{entry}} -%D \stoptyping -%D -%D and split accordingly. - -% todo: - -\def\doifforwardreferenceelse#1#2% todo - {\iffalse} - -%D Cross references appear as numbers (figure~1.1, chapter~2) -%D or pagenumbers (page~2, page 3--2), and are called with -%D \type{\in} and \type{\at}. In interactive documents we also -%D have \type{\goto}, \type{\button} and alike. These are more -%D versatile and look like: -%D -%D \starttyping -%D \goto[reference] -%D \goto[outer reference::] -%D \goto[outer reference::inner reference] -%D \goto[operation(argument)] -%D \goto[operation(action{argument,argument})] -%D \goto[action] -%D \goto[action{argument}] -%D \stoptyping -%D -%D The first one is a normal reference, the second and third -%D are references to a file or \URL. The brace delimited -%D references for instance refer to a \JAVASCRIPT. The last -%D example shows that we can pass arguments to the actions. -%D -%D When we split off the components of such a reference, the -%D results are available in: -%D -%D \starttyping -%D \currentreferencespecial -%D \currentreferenceoperation -%D \currentreferencearguments -%D \currentinnerreference -%D \currentouterreference -%D \currentfullreference -%D \stoptyping - -\newif\ifreferencefound - -\let\currentfullreference \empty -\let\currentreferencespecial \empty -\let\currentreferenceoperation\empty -\let\currentreferencearguments\empty -\let\currentouterreference \empty -\let\currentinnerreference \empty - -\def\setreferencevariables#1#2#3#4#5% - {\def\currentreferencespecial {#1}% - \def\currentreferenceoperation{#2}% - \def\currentreferencearguments{#3}% - \def\currentouterreference {#4}% - \def\currentinnerreference {#5}} - -%D Now we've come to the testing step. As we can see below, -%D this macro does bit more than testing: it also resolves -%D the reference. This means that whenever we test for the -%D existance of a reference at an outer level, we have all the -%D relevant properties of that reference avaliable inside the -%D true branche~(\type{#2}). -%D -%D The prefix has to do with localizing references. When a -%D prefix is set, looking for a reference comes to looking for -%D the prefixed one, and when not found, looking for the non -%D prefixed one. Consider for instance the prefix set to -%D \type{sidetrack}. -%D -%D \starttyping -%D \pagereference[important] -%D \pagereference[unimportant] -%D \setupreferencing[prefix=sidetrack] -%D \pagereference[important] -%D \stoptyping -%D -%D results in saving (writing) the references -%D -%D \starttyping -%D ...{}{important} -%D ...{}{unimportant} -%D ...{sidetrack}{important}... -%D \stoptyping -%D -%D Now when we call for \type{unimportant}, we will indeed get -%D the pagenumber associated to this reference. But when we -%D call for \type{important}, while the prefix is still set, we -%D will get the pagenumber bound to the prefixed one. -%D -%D {\em Some day, when processing time and memory are no longer -%D performance factors, we will introduce multi||level -%D prefixes.} -%D -%D Before we start analyzing, I introduce a general -%D definition macro. Consider: -%D -%D \starttyping -%D \goto{do}[JS(My_Script{"test",123}),titlepage] -%D \stoptyping -%D -%D This can also be achieved by: -%D -%D \starttyping -%D \definereference[startup][JS(My_Script{"test",123}),titlepage] -%D \goto{do}[REF(startup)] -%D \stoptyping -%D -%D Now is this is a handy feature or not? -%D -%D \showsetup{definereference} -%D -%D We can trace references by setting the next switch to -%D true. - -\def\definereference - {\dodoubleempty\dodefinereference} - -\def\dodefinereference[#1][#2]% - {\ctxlua{jobreferences.define("\referenceprefix","#1",\!!bs\detokenize{#2}\!!es)}} - -\def\resetreference[#1]% - {\ctxlua{jobreferences.reset("\referenceprefix","#1")}} - -\def\setpagereference#1#2% name, specification - {\ctxlua{jobreferences.define("","#1",\!!bs\v!page(\luaescapestring{#2})\!!es)}} - -%D Chained references are defined as: -%D -%D \starttyping -%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)] -%D \stoptyping -%D -%D Actually supporting chains is up to the special driver. Here -%D we only provide the hooks. - -\newif \ifsecondaryreference -\newcount\nofsecondaryreferences - -% the counter stuff should move to the (mkiv) backend - -\def\doifreferencefoundelse#1% - {\ctxlua{jobreferences.doifelse("\referenceprefix","#1")}} - -\def\doprocessreferenceelse#1#2#3% - {\doresetgotowhereever - \nofsecondaryreferences\zerocount - \def\primaryreferencefoundaction {\secondaryreferencefalse#2}% - \def\secondaryreferencefoundaction{\advance\nofsecondaryreferences\plusone\secondaryreferencetrue#2}% - \def\referenceunknownaction {#3}% - \ctxlua{jobreferences.handle("\referenceprefix","#1")}% - \doresetgotowhereever} % to prevent problems with direct goto's - -%D The inner case is simple. Only two cases have to be taken -%D care of: -%D -%D \starttyping -%D \goto{some text}[reference] -%D \goto{some text}[prefix:reference] -%D \stoptyping -%D -%D References to other files however are treated strict or -%D tolerant, depending on their loading and availability: -%D -%D \starttyping -%D \useexternaldocument[somefile][filename][a nice description] -%D -%D \goto{checked reference}[somefile::reference] -%D \goto{unchecked reference}[somefile::] -%D \goto{unchecked reference}[anotherfile::reference] -%D \stoptyping -%D -%D An unknown reference is reported on the screen, in the log -%D file and, when enabled, in the left margin of the text. - -\def\reportreferenceerror#1#2% only once (keep track in lua) - {\ifinpagebody \else - \doifconcepttracing{\doifsomething{#2}{\inleft{\infofont\doboundtext{#2}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}% - \fi - \showmessage\m!references{#1}{[\referenceprefix][#2]}} - -\def\unknownreference{\reportreferenceerror1} -\def\illegalreference{\reportreferenceerror4} - -%D When a reference is not found, we typeset a placeholder -%D (two glyphs are often enough to represent the reference -%D text). - -\def\dummyreference{{\tttf ??}} - -%D To prevent repetitive messages concerning a reference -%D being defined, we set such an unknown reference to an empty -%D one after the first encounter. - -%D Sometimes we want to temporary put a reference out of -%D order. An example can be found in the menu macros. -%D -%D \starttyping -%D \doifreferencepermittedelse{reference}{set}{true}{false} -%D \stoptyping -%D -%D The second argument can be a comma seperated list. - -\let\permittedreferences\empty - - \def\doifreferencepermittedelse#1#2#3% ref found notfound - {\doprocessreferenceelse{#1} - {\donetrue - \ifx\permittedreferences\empty \else - \docheckifreferencepermitted{#1}% - \fi - \ifdone#2\else#3\fi} - {#3\unknownreference{#1}}} - - \def\docheckifreferencepermitted#1% - {\ifx\currentinnerreference\empty - \ifx\currentouterreference\empty \else - \doifinstring{\currentouterreference::}\permittedreferences\donefalse - \fi - \else\ifx\currentouterreference\empty - \doifinstring{\currentinnerreference}\permittedreferences\donefalse - \else - \doifinstring{\currentouterreference::\currentinnerreference}\permittedreferences\donefalse - \fi\fi} - -%D Apart from cross references supplied by the user, \CONTEXT\ -%D generates cross references itself. Most of them are not -%D saved as a reference, but stored with their source, for -%D instance a list or an index entry. Such automatically -%D generated, for the user invisible, references are called -%D {\em internal references}. The user supplied ones are -%D labeled as {\em external references}. -%D -%D A second important characteristic is that when we want to -%D support different backends (viewers), we need to support -%D named destinations as well as page numbers. I invite readers -%D to take a glance at the special driver modules to understand -%D the fine points of this. As a result we will deal with {\em -%D locations} as well as {\em real page numbers}. We explictly -%D call this pagenumber a real one, because it is independant -%D of the page numbering scheme used in the document. -%D -%D One of the reasons for \CONTEXT\ being the first \TEX\ base -%D macropackage to support sophisticated interactive \PDF\ -%D files, lays in the mere fact that real page numbers are -%D available in most two pass data, like references, list data -%D and index entries. -%D -%D We will speak of \type{thisis...} when we are marking a -%D location, and \type{goto...} when we point to such a -%D location. The latter one can be seen as a hyperlink to the -%D former one. In the next macros one we use constructs like: -%D -%D \starttyping -%D \dostart... -%D \dostop... -%D \stoptyping -%D -%D Such macros are used to invoke the relevant specials from -%D the special driver modules (see \type{spec-ini}). The flag -%D \type{\iflocation} signals if we're in interactive mode. - -\def\thisisdestination#1% destination - {\iflocation \ifusepagedestinations \else - \dostartthisislocation{#1}\dostopthisislocation - \fi \fi} - -\def\thisisrealpage#1% pagenumber - {\iflocation - \dostartthisisrealpage{#1}\dostopthisisrealpage - \fi} - -%D The previous tho macros were easy ones, opposite to their -%D counterparts. A common component in these is: -%D -%D \starttyping -%D \dohandlegoto{..}{..}{..} -%D \stoptyping -%D -%D Here data can be whatever needs highlighting, e.g. {\em -%D figure 2.4}, and the start and stop entries handle the -%D specials. The two \DIMENSIONS\ \type{\buttonwidth} and -%D \type{\buttonheight} have to be set when handling the -%D data~(\type{#2}). - -\ifx\buttonheight\undefined \newdimen\buttonheight \fi -\ifx\buttonwidth \undefined \newdimen\buttonwidth \fi - -\def\gotodestination#1#2#3#4#5% url file destination page data - {\iflocation - \ifusepagedestinations - \gotorealpage{#1}{#2}{\number#4}{#5}% - \else - \dohandlegoto - {#5}% - {\the\everyreference\dostartgotolocation\buttonwidth\buttonheight{#1}{#2}{#3}{\number#4}}% - {\dostopgotolocation}% - \fi - \else - {#5}% - \fi} - - \def\gotorealpage#1#2#3#4% url file page data - {\iflocation - \dohandlegoto - {#4}% - {\dostartgotorealpage\buttonwidth\buttonheight{#1}{#2}{\number#3}}% - {\dostopgotorealpage}% - \else - {#4}% - \fi} - -\def\gotoinnerpage#1#2% page data - {\iflocation - \dohandlegoto - {#2}% - {\dostartgotorealpage\buttonwidth\buttonheight\empty\empty{\number#1}}% - {\dostopgotorealpage}% - \else - {#2}% - \fi} - -\def\gotoouterfilepage#1#2#3% file page data - {\iflocation - \dohandlegoto - {#3}% - {\dostartgotorealpage\buttonwidth\buttonheight\empty{#1}{\number#2}}% - {\dostopgotorealpage}% - \else - {#3}% - \fi} - -%D \macros -%D {setreferencefilename} -%D -%D This command can be used in the special drivers to -%D uppercase filenames. This is needed when one wants to -%D produce \CDROM's conforming to ISO9660. We consider is the -%D savest to enable this feature by default. We cannot handle -%D uppercase here, since the suffix is handled in the special -%D driver. Conversion is taken care of by: -%D -%D \starttyping -%D \setreferencefilename somefilename\to\SomeFileName -%D \stoptyping - -\chardef\referencefilecase=0 - - \def\setreferencefilename#1\to#2% - {\ifcase\referencefilecase - \edef#2{#1}% - \or - \uppercasestring#1\to#2% - \or - \lowercasestring#1\to#2% - \else - \edef#2{#1}% - \fi} - -%D Internal references can best be set using the next few -%D macros. Setting such references to unique values is -%D completely up to the macros that call them. -%D -%D \starttyping -%D \thisissomeinternal{tag}{identifier} -%D \gotosomeinternal {tag}{identifier}{pagenumber}{text} -%D \stoptyping - -\def\thisissomeinternal#1#2% tag reference - {\doifsomething{#2}{\thisisdestination{#1:#2}}} - -\def\gotosomeinternal#1#2% #3#4 - {\gotodestination\empty\empty{#1:#2}} - -%D An automatic mechanism is provided too: -%D -%D \starttyping -%D \thisisnextinternal{tag} -%D \gotonextinternal {tag}{number}{pagenumber}{text} -%D \stoptyping -%D -%D The first macro increments a counter. The value of this -%D counter is available in the macro \type{\nextinternalreference} -%D and should be saved somewhere (for instance in a file) for -%D future reference. The second argument of -%D \type {\gotonextinternal} takes such a saved number. One can -%D turn on tracing these references, in which case the -%D references are a bit more verbose. - -\newcount\locationcount - -\newif\ifinternalnamedreferences \internalnamedreferencestrue - -\def\nextinternalreference - {\the\locationcount} - -\def\setnextinternalreference - {\global\advance\locationcount\plusone} - -\def\thisisnextinternal#1% #1 will be removed when we are done with mkiv - {\ifinternalnamedreferences - \thisisdestination{\s!aut:\nextinternalreference}% - \fi} - -\def\insertnextinternal#1% - {\ifinternalnamedreferences - \thisisdestination{\s!aut:\number#1}% - \fi} - -\def\gotonextinternal#1#2#3#4% #1 will be removed when we are done with mkiv - {\ifinternalnamedreferences - \gotodestination\empty\empty{\s!aut:#2}{#3}{#4}% - \else - \gotorealpage\empty\empty{#3}{#4}% - \fi} - -%D We already went through a lot of problems to sort out what -%D kind of reference we're dealing with. Sorting out the user -%D supplied cross references (show/goto this or that) as well -%D as user supplied system references (invoke this or that) is -%D already taken care of in the test routine, but we still have -%D to direct the request to the right (first) routine. - -\def\gotolocation#1#2{\doprocessreferenceelse{#1}{#2}{\unknownreference{#1}}} % obsolete - -%D An inner reference refers to some place in the document -%D itself. - - \def\gotoinnerlocation#1% #2% - {\gotodestination\empty\empty{\referenceprefix\currentinnerreference}\currentrealreference} % {#2} - -\def\gotoinner#1#2#3% prefix inner page data - {\gotodestination\empty\empty{#1#2}{#3}} % {#4} - -%D The outer location refers to another document, specified as -%D file or \URL. - - \def\gotoouterlocation#1#2% % page checken! - {\bgroup - \let\referenceprefix\empty - \setouterlocation\currentouterreference - \ifx\currentinnerreference\empty - \gotorealpage\otherURL\otherfile1{#2}% - \else - \gotodestination\otherURL\otherfile\currentinnerreference\currentrealreference{#2}% - \fi - \egroup} - -\def\gotoouterfile#1#2% file location page data #3 #4 - {\doifelsenothing{#2}{\gotorealpage\empty{#1}}{\gotodestination\empty{#1}{#2}}} - -\def\gotoouterfilepage#1% file page data - {\gotorealpage\empty{#1}\empty} - -\def\gotoouterfilelocation% file location page data - {\gotodestination\empty} - -\def\gotoouterurl#1#2% url args data #2 - {\gotodestination{#1}\empty{#2}1} - -%D Special locations are those that are accessed by saying -%D things like: -%D -%D \starttyping -%D \goto{calculate total}[JS(summarize{10,23,56}] -%D \stoptyping -%D -%D After several intermediate steps this finally arrives at -%D the next macro and expands into (simplified): -%D -%D \starttyping -%D \gotoJSlocation{total{summarize{10,23,56}}}{calculate total} -%D \stoptyping -%D -%D The first argument is the full reference, the second one -%D is the text, in some kind of manipulated form. In practice -%D we split references, so we get: -%D -%D \starttyping -%D \gotoJSlocation{summarize{10,23,56}}{calculate} -%D \gotoJSlocation{summarize{10,23,56}}{total} -%D \stoptyping -%D -%D where \type{calculate} and \type{total} are colored, boxed -%D or whatever \type{\goto} is told to do. -%D -%D The macro \type{\gotoJSlocation} can use \type -%D {\currentreferenceoperation} (in our example -%D \type{summarize}) and \type{\currentreference} (here -%D being \type {10,23,56}) to perform its task. - - \def\gotospeciallocation - {\executeifdefined{goto\currentreferencespecial location}\gobbleoneargument} - -%D Such special macros can be defined by: - - \def\definespeciallocation#1% - {\setvalue{goto#1location}} - -%D The associated test is to be defined by: - -\def\definespecialtest#1% - {\setvalue{\s!do:\v!test:#1}} - -%D This \type{\def} alike macro is to be used as: -%D -%D \starttyping -%D \definespeciallocation{JS}#1#2{... #1 ... #2 ...} -%D \stoptyping -%D -%D In module \type {java-ini} one can see that \type -%D {\gotoJSlocation} looks much like the previous goto -%D definitions. - -%D In this module we define three system references: one for -%D handling navigational, viewer specific, commands, another -%D for jumping to special pages, like the first or last one, -%D and a third reference for linking tree like lists, like -%D tables of contents. The latter two adapt themselves to the -%D current state. -%D -%D An example of an action is: -%D -%D \starttyping -%D \goto{some action}[PreviousJump] -%D \stoptyping -%D -%D as well as: -%D -%D \starttyping -%D \goto{some text}[\v!action(PreviousJump] -%D \stoptyping - -% compatibility hack - -\def\setglobalsystemreference#1#2#3{\definereference[#2][\v!action(#3)]} - -% action actions - -\def\gotoactionspecial#1#2#3#4% special operation arguments data - {\begingroup - \iflocation - \dohandlegoto - {#4}% - {\dostartexecutecommand\buttonwidth\buttonheight{#2}{#3}}% - {\dostopexecutecommand}% - \else - #4% - \fi - \endgroup} - -\def\gotopagespecial#1#2#3#4% page(n) page(+n) page(-n) page(file::1) - {\begingroup - \iflocation - \doifnonzeropositiveelse{#2} - {\doifinstringelse+{#2} - {\edef\currenttargetpage{\the\numexpr\realpageno#2}} - {\doifinstringelse-{#2} - {\edef\currenttargetpage{\the\numexpr\realpageno#2}} - {\edef\currenttargetpage{#2}}}}% - {\edef\currenttargetpage{1}}% - \docheckrealreferencepage\currenttargetpage % new - \gotorealpage\empty\empty\currenttargetpage{#4}% - \else - #4% - \fi - \endgroup} - -%D It is possible to disable the writing of references to the -%D utility file by setting: - -\newif\ifreferencing \referencingtrue - -%D One can also activate an automatic prefix mechanism. By -%D setting the \type{\prefix} variable to \type{+}, the prefix -%D is incremented, when set to \type{-} or empty, the prefix is -%D reset. Other values become the prefix. - -\newcount\prefixcounter - -%D These settings are accomplished by: -%D -%D \showsetup{setupreferencing} -%D -%D In interactive documents verbose references don't always -%D make sense (what is a page number in an unnumbered -%D document). By setting the \type{interaction} variable, one -%D can influences the way interactive references are set. - -\chardef\autocrossfilereferences=0 - -\def\setupreferencing - {\dosingleargument\dosetupreferencing} - -\def\dosetupreferencing[#1]% - {\getparameters - [\??rf] - [\c!prefix=\s!unknown,#1]% - \processaction - [\@@rfstate] - [ \v!stop=>\referencingfalse, - \v!start=>\referencingtrue]% - \processaction - [\@@rfinteraction] - [ \v!all=>\let\dowantedreference\docompletereference, - \v!label=>\let\dowantedreference\dolabelonlyreference, - \v!text=>\let\dowantedreference\dotextonlyreference, - \v!symbol=>\let\dowantedreference\dosymbolreference]% - \chardef\autocrossfilereferences\zerocount - \processaction - [\@@rfautofile] - [ \v!yes=>\chardef\autocrossfilereferences\plusone, - \v!page=>\chardef\autocrossfilereferences\plustwo]% - \chardef\referencefilecase\zerocount - \processaction[\@@rfconvertfile] - [ \v!yes=>\chardef\referencefilecase\plusone, - \v!big=>\chardef\referencefilecase\plusone, - \v!small=>\chardef\referencefilecase\plustwo]% - \setupreferenceprefix[\@@rfprefix]% - \doifelse\@@rfglobal\v!yes - {\settrue \autoglobalfilereferences} - {\setfalse\autoglobalfilereferences}} - -\def\incrementreferenceprefix{+} -\def\decrementreferenceprefix{-} - -\def\setupreferenceprefix[#1]% - {\edef\@@rfprefix{#1}% - \ifx\@@rfprefix\empty - \let\referenceprefix\empty - \else\ifx\@@rfprefix\incrementreferenceprefix - \advance\prefixcounter \plusone % should be global - \edef\referenceprefix{\the\prefixcounter:}% - \let\@@rfprefix\s!unknown - \else\ifx\@@rfprefix\decrementreferenceprefix - \let\referenceprefix\empty - \let\@@rfprefix\s!unknown - \else\ifx\@@rfprefix\s!unknown - % forget about it - \else - \edef\referenceprefix{\@@rfprefix:}% - \fi\fi\fi\fi} - -%D \macros -%D {handlereferenceactions, -%D collectreferenceactions} -%D -%D Sometimes we need to pass the actions connected to -%D references to variables instead of rectangular areas on -%D which one can click. The next macro collects the actions -%D and passes them to a handle. This is a rather dreadfull -%D hack! -%D -%D \starttyping -%D \handlereferenceactions{references}\handle -%D \stoptyping -%D -%D So, \type {\handle} does the final job, which in for -%D instance the \PDF\ drivers comes down to doing something -%D with \type {\lastPDFaction}. - -\newif\ifcollectreferenceactions - -\def\handlereferenceactions#1#2% - {\doifsomething{#1} - {\bgroup - \collectreferenceactionstrue - \doprocessreferenceelse{#1}{#2}{\unknownreference{#1}}% - \egroup}} - -%D The most straightforward way of retrieving references is -%D using \type{\ref}. Consider the reference: -%D -%D \startbuffer -%D \reference[my ref]{{Look}{Here}{I am}} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \getbuffer -%D -%D We can ask for upto five reference components: -%D -%D \startbuffer -%D user page reference: \ref[p][my ref] -%D text reference: \ref[t][my ref] -%D real page reference: \ref[r][my ref] -%D sub text reference: \ref[s][my ref] -%D extra text reference: \ref[e][my ref] -%D \stopbuffer -%D -%D \typebuffer -%D -%D And get back: -%D -%D \startlines -%D \getbuffer -%D \stoplines - -\def\ref{\dodoubleargument\doref} - -\def\reftypep{\currentpagereference} -\def\reftypet{\currenttextreference} -\def\reftyper{\currentrealreference} -\def\reftypes{\currentsubtextreference} -\def\reftypee{\currentsubsubtextreference} - -\def\doref[#1][#2]% - {\ifsecondargument -% \doifreferencefoundelse{#2} -% {\executeifdefined{reftype#1}\reftypep} -% {\unknownreference{#2}\dummyreference}% - \else - \dummyreference - \fi} - -%D We can typeset a reference using \type{\in}, \type{\at} and -%D \type{\about} and goto specific locations using -%D \type{\goto}. The last one does not make that much sense in -%D a paper document. To complicate things, \PLAIN\ \TEX\ also -%D implements an \type {\in} but fortunately that one only -%D makes sense in math mode. -%D -%D Typesetting the reference is a bit more complicated than one -%D would at first sight expect. This is due to the fact that we -%D distinguish three (five) alternative calls: -%D -%D \placefigure -%D [here][three calls] -%D {Three alternatives reference calls.} -%D {\startcombination[1*3] -%D {\framed{\type{ \in }}} {a} -%D {\framed{\type{ \at }}} {b} -%D {\framed{\type{\goto}}} {c} -%D \stopcombination} -%D -%D \startbuffer -%D \in figure[fig:three calls] -%D \in{figure}[fig:three calls] -%D \in figure a[fig:three calls] -%D \in{figure}{a}[fig:three calls] -%D figure~\in[fig:three calls] -%D \stopbuffer -%D -%D \typebuffer -%D -%D This turns up as: -%D -%D \startlines -%D \getbuffer -%D \stoplines -%D -%D The dual \type{{}} results in a split reference. In a -%D document meant for paper, one is tempted to use the last -%D (most straightforward) alternative. When a document is also -%D meant voor electronic distribution, the former alternatives -%D have preference, because everything between the \type{\in} -%D and~\type{[} becomes active (and when asked for, typeset -%D in a different color and typeface). - -\definecommand in {\dospecialin} -\definecommand at {\dospecialat} -\definecommand about {\dospecialabout} -\definecommand from {\dospecialfrom} -\definecommand over {\dospecialabout} % needed here, else math problems - -\def\currentreferencenumber{\ctxlua{jobreferences.filter("number")}} -\def\currentreferencepage {\ctxlua{jobreferences.filter("page")}} -\def\currentreferencetitle {\ctxlua{jobreferences.filter("title")}} - -\unexpanded\def\dospecialin{\doinatreference\currentreferencenumber} -\unexpanded\def\dospecialat{\doinatreference\currentreferencepage} - -\def\doinatreference#1% - {\doifnextoptionalelse{\dodoinatreference{#1}{}}{\dodoinatreference{#1}}} - -\def\dodoinatreference#1% - {\def\dododoinatreference{\dodododoinatreference{#1}}% - \futurelet\next\dododoinatreference} - -\unexpanded\def\dospecialabout[#1]% - {\dontleavehmode - \bgroup - \@@rfleft - \doprocessreferenceelse{#1} - {\let\crlf\space - \let\\\space - \let\dogotofixed\dogotospace - \dogotospace{\limitatetext\currentreferencetitle\@@rfwidth\unknown}[#1]} - {\unknownreference{#1}\dummyreference}% - \@@rfright - \referenceinfo{<}{#1}% - \egroup} - -%D We arrived at the last step. Before we do the typesetting, -%D we forget all previous (paragraph bound) settings and make -%D sure that we remain in horizontal mode. Next we choose -%D among the several representations. - -%D The previously discussed setup macro lets us specify the -%D representation of references. A symbol reference does not -%D show the specific data, like the number of a figure, but -%D shows one of: \hbox {$^\goforwardcharacter$ -%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending -%D on the direction to go. - - \def\dosymbolreference#1#2[#3]% todo - {\bgroup - \setupsymbolset[\@@iasymbolset]% - \removelastskip - \ifx\currentreferencespecial\empty - \ifx\currentouterreference\empty - \ifnum0\currentrealreference=\zerocount - \ifhmode\strut\high{\symbol[\v!nowhere]}\fi - \else\ifnum0\currentrealreference>\realpageno - \dodosymbolreference{#2}{\high{\symbol[\v!next]}}% - \else\ifnum0\currentrealreference<\realpageno - \dodosymbolreference{#2}{\high{\symbol[\v!previous]}}% - \else - \ifhmode\strut\high{\symbol[\v!nowhere]}\fi - \fi\fi\fi - \else - \gotoouterlocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}% - \fi - \else - \gotospeciallocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}% - \fi - \egroup} - - \def\dodosymbolreference#1#2% todo - {#1\hbox{\gotorealpage\empty\empty\currentrealreference{\dolocationattributes\??ia\c!style\c!color{#2}}}} - -%D The other alternatives just conform their names: only the -%D label, only the text, or the label and the text. - -\def\dounknownreference#1#2[#3]% - {\unknownreference{#3}\dotextprefix{#2}\dummyreference}% - -\def\docompletereference#1#2[#3]% - {\iflocationsplit - \doifsomespaceelse{#2}\dogotospace\dogotofixed{\dotextprefix{#2}#1}[#3]% - \else - \dogotofixed{\dotextprefix{#2}#1}[#3]% - \fi} - -\def\dolabelonlyreference#1#2[#3]% - {\doifsomespaceelse{#2} - {\doifsomething{#2}{\dogotospace{#2}[#3]}} - {\dogotofixed{\dotextprefix{#2}}[#3]}} - -\def\dotextonlyreference#1#2[#3]% - {\dotextprefix{#2}\dogotofixed{#1}[#3]} - -\let\dowantedreference\docompletereference - -%D \macros -%D {definereferenceformat} -%D -%D The next few macros were made for for David Arnold and Taco -%D Hoekwater. They can be used for predefining reference -%D texts, and thereby stimulate efficiency. -%D -%D [more documentation will be added] -%D -%D \starttyping -%D \definereferenceformat[informula] [left=(,right=),text=formula] -%D \definereferenceformat[informulas] [left=(,right=),text=formulas] -%D \definereferenceformat[andformula] [left=(,right=),text=and] -%D \definereferenceformat[andformulas][left=(,right=),text=and] -%D -%D \informula [b] and \informula [for:c] -%D the \informula {formulas}[b] \informula {and} [for:c] -%D the \informulas {formulas}[b] \informula {and} [for:c] -%D the \informulas [b] \informula {en} [for:c] -%D the \informulas [b] \andformula [for:c] -%D \stoptyping -%D -%D Instead of a text, one can specify a label, which should -%D be defined with \type {\setuplabeltext}. - -% todo: inherit - -\def\definereferenceformat - {\dodoubleargument\dodefinereferenceformat} - -\def\dodefinereferenceformat[#1][#2]% - {\iffirstargument - \getparameters[\??rf#1] - [\c!left=, % of the number - \c!right=, % of the number - \c!text=, % before the number - \c!label=, % can be {left}{right} - \c!command=\in, - #2]% - \unexpanded\setvalue{#1}% - {\dontleavehmode\doexecutereferenceformat{#1}}% - \fi} - -\def\noexecutelabelreferenceformat#1% - {\doifvaluesomething{\??rf#1\c!text} - {\gdef\textofreference{\csname\??rf#1\c!text\endcsname}}% - \csname\??rf#1\c!command\endcsname} - -\def\doexecutelabelreferenceformat#1% - {\csname\??rf#1\c!command\endcsname - {\leftlabeltext {\csname\??rf#1\c!label\endcsname}}% - {\rightlabeltext{\csname\??rf#1\c!label\endcsname}}} - -\def\doexecutereferenceformat#1% - {\gdef\leftofreference {\csname\??rf#1\c!left \endcsname}% - \gdef\rightofreference{\csname\??rf#1\c!right\endcsname}% - \global\let\textofreference\empty % otherwise ~ added - \doifelsevaluenothing{\??rf#1\c!label} - \noexecutelabelreferenceformat\doexecutelabelreferenceformat{#1}} - -\let\leftofreference \relax -\let\rightofreference\relax -\let\textofreference \relax - -% fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]% - -\def\dodododoinatreference#1#2#3[#4]% no \removeunwantedspaces (fails on metafun) - {\ifx\next\bgroup - \dododododoinatreference{\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]% - \else - \dododododoinatreference{\leftofreference#1\rightofreference}{#2#3}[#4]% - \fi} - -\let\dosymbolreference\dowantedreference - -\def\dododododoinatreference#1#2[#3]% - {\dontleavehmode % replaces \leaveoutervmode - \begingroup - \forgetall - \postponenotes - \doifreferencefoundelse{#3} - {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#3]}% - {\dounknownreference{#1}{#2}[#3]}% - \referenceinfo<{#3}% - \endgroup} - - -%D In interactive documents going to a specific location is not -%D bound to cross references. The \type{\goto} commands can be -%D used to let users access another part of the document. In -%D this respect, interactive tables of contents and registers -%D can be considered goto's. Because in fact a \type{\goto} is -%D just a reference without reference specific data, the -%D previous macros are implemented using the goto -%D functionality. -%D -%D \showsetup{goto} -%D -%D One important chaacteristic is that the first argument of -%D \type{\goto} (and therefore \type{\at} and \type{\in} is -%D split at spaces. This means that, although hyphenation is -%D prevented, long references can cross line endings. - -\newif\ifsharesimilarreferences \sharesimilarreferencestrue -\newcount\similarreference % 0=noppes 1=create/refer 2,3,..=refer - -\unexpanded\def\goto#1#2% - {\dogoto{#1}#2} - -\def\dogoto#1[#2]% - {\dontleavehmode - \bgroup - \postponenotes - % todo: handle empty #1 - \doifelsenothing{#1} - {\dosymbolreference{}{}[#2]} - {\dogotospace{#1}[#2]}% - \egroup - \referenceinfo{<}{#2}} - -% inefficient, we need to save the shared one (just reuse last command in lua) - -\def\dogotospace#1[#2]% - {\iflocationsplit - \ifsecondaryreference - \setbox\scratchbox\hbox % will change anyway - \fi % due to space insertion - {\let\dogotospace\dogotofixed - \iflocation - \def\processisolatedword##1% - {\ifisolatedwords\ifsharesimilarreferences - \global\advance\similarreference \plusone - \fi\fi - \hbox\bgroup - \doprocessreferenceelse{#2}{##1\presetgoto}{\unknownreference{#2}##1\relax}% - \egroup}% - \doattributes\??ia\c!style\c!color{\processisolatedwords{#1}\processisolatedword}% - \else - #1\relax % \relax prevents #1's next macros from gobbling \fi - \fi}% - \else - \iflocation - \hbox{\doattributes\??ia\c!style\c!color{\doprocessreferenceelse{#2}{#1\presetgoto}{\unknownreference{#2}#1\relax}}}% - \else - #1\relax % \relax prevents #1's next macros from gobbling \fi - \fi - \fi - \global\similarreference\zerocount} - -\def\dogotofixed#1[#2]% - {{\iflocation - \hbox{\doattributes\??ia\c!style\c!color{\doprocessreferenceelse{#2}{#1\presetgoto}{\unknownreference{#2}#1\relax}}}% - \else - #1% - \fi}} - -%D In case the auto split feature is not needed or even not -%D even wanted, \type{\gotobox} can be used. - -\unexpanded\def\gotobox#1[#2]% - {\dontleavehmode - \bgroup - \locationstrutfalse - \doprocessreferenceelse{#2} - {\dogotofixed{#1}[#2]} - {\hbox{\unknownreference{#2}#1}}% - \referenceinfo{<}{#2}% - \egroup} - -%D An reference to another document can be specified as a file -%D or as an \URL. Both are handled by the same mechanism and -%D can be issued by saying something like: -%D -%D \starttyping -%D \goto[dictionary::the letter a] -%D \stoptyping -%D -%D One can imagine that many references to such a dictionary -%D are made, so in most cases such a document reference in an -%D indirect one. -%D -%D \showsetup{useexternaldocument} -%D -%D For example: -%D -%D \starttyping -%D \useexternaldocument -%D [dictionary][engldict] -%D [The Famous English Dictionary] -%D \stoptyping -%D -%D The next macro implements these relations, and also take -%D care of loading the document specific references. -%D -%D The \URL\ alternative takes four arguments: -%D -%D \showsetup{useURL} -%D -%D like: -%D -%D \starttyping -%D \useURL -%D [dictionary][http://www.publisher.com/public][engldict] -%D [The Famous English Dictionary] -%D \stoptyping -%D -%D Several specifications are possible: -%D -%D \starttyping -%D \useURL [id] [url] [file] [description] -%D \useURL [id] [url] [file] -%D \useURL [id] [url] -%D \stoptyping -%D -%D This time we don't load the references when no file is -%D specified. This is logical when one keeps in mind that a -%D valid \URL\ can also be a mail address. - -\def\usefile{\dotripleargument\dousefile} -\def\useurl {\doquadrupleempty\douseurl} - -\let\useURL \useurl -\let\useexternaldocument\usefile - -\def\douseurl[#1][#2][#3][#4]% - {\ctxlua{jobreferences.urls.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es,\!!bs\detokenize{#4}\!!es)}} - -\def\dousefile[#1][#2][#3]% - {\ctxlua{jobreferences.files.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} - -% \doifsomething\@@urstyle{\let\@@iastyle\@@urstyle\let\@@urstyle\empty}% -% \doifsomething\@@urcolor{\let\@@iacolor\@@urcolor\let\@@urcolor\empty}% - -%D \macros -%D {url,setupurl} -%D -%D We also have: \type{\url} for directly calling the -%D description. So we can say: -%D -%D \starttyping -%D \useURL [one] [http://www.test.nl] -%D \useURL [two] [http://www.test.nl] [] [Some Site] -%D -%D \url[one] or \from[two] or \goto{Whatever Site}[URL(two)] -%D \stoptyping -%D -%D An \URL\ can be set up with -%D -%D \showsetup{setupurl} - -\def\setupurl - {\dodoubleargument\getparameters[\??ur]} - -\unexpanded\def\url[#1]% - {\dontleavehmode - \begingroup - \dosetfontattribute\??ur\c!style - \dosetcolorattribute\??ur\c!color - \ctxlua{jobreferences.urls.get("#1","\@@uralternative","\@@urspace")}% - \dostopattributes - \endgroup} - -%D This macro is hooked into a support macro, and thereby -%D \URL's break ok, according to the setting of a switch, -%D -%D \startbuffer -%D \useURL -%D [test] -%D [sentence_sentence%sentence#sentence~sentence/sentence//sentence:sentence.sentence] -%D \stopbuffer -%D -%D \typebuffer -%D -%D Such an \URL\ is, depending on the settings, hyphenated as: -%D -%D \getbuffer -%D -%D \startlinecorrection -%D \hbox to \hsize -%D {\hss\en -%D \setupreferencing[urlalternative=both]% -%D \vbox{\hsize.25cm\hbox{\bf both}\prewordbreak\url[test]}% -%D \hss -%D \setupreferencing[urlalternative=before]% -%D \vbox{\hsize.25cm\hbox{\bf before}\prewordbreak\url[test]}% -%D \hss -%D \setupreferencing[urlalternative=after]% -%D \vbox{\hsize.25cm\hbox{\bf after}\prewordbreak\url[test]}% -%D \hss} -%D \stoplinecorrection -%D -%D By setting \type{urlspace=yes} one can get slightly better -%D spacing when using very long \URL's. -%D -%D When defining the external source of information, one can -%D also specify a suitable name (the last argument). This name -%D can be called upon with: -%D -%D \showsetup{from} - -\def\dospecialfrom - {\dosingleempty\dodospecialfrom} - -\def\dodospecialfrom[#1]% - {\dontleavehmode\ctxlua{jobreferences.from("#1","","")}} - -%D We also support: -%D -%D \starttyping -%D \goto{some text}[file(identifier{location}] -%D \stoptyping -%D -%D which is completely equivalent with -%D -%D \starttyping -%D \goto{some text}[identifier::location] -%D \stoptyping - -\def\gotofilespecial#1#2#3#4% special operation arguments data - {\begingroup\iflocation\gotoouterfile{#2}{#3}{#4}\else#4\fi\endgroup} - -\def\gotourlspecial#1#2#3#4% special operation arguments data - {\begingroup\iflocation\gotoouterurl{#2}{#3}{#4}\else#4\fi\endgroup} - -%D A special case of references are those to programs. These, -%D very system dependant references are implemented by abusing -%D some of the previous macros. -%D -%D \showsetup{setupprograms} -%D \showsetup{defineprogram} -%D \showsetup{program} % changed functionality ! -%D -%D The latter gives access to the description of the program, -%D being the last argument to the definition command. - -% also lua, like urls and files - -\def\setupprograms - {\dodoubleargument\getparameters[\??pr]} - -\def\defineprogram - {\dotripleargument\dodefineprogram} - -\def\dodefineprogram[#1][#2][#3]% - {\ctxlua{jobreferences.programs.define("#1","#2","#3")}} - -\def\program[#1]% incompatible, more consistent, hardy used anyway - {\dontleavehmode - \begingroup - \dosetfontattribute\??pr\c!style - \dosetcolorattribute\??pr\c!color - \ctxlua{jobreferences.programs.get("#1","\@@pralternative","\@@prspace")}% - \endgroup} - -% needs an update: program(abc{arg}) - -\def\gotoprogramspecial#1#2#3#4% special operation arguments data - {\begingroup - \iflocation - \dohandlegoto - {#4}% - {\dostartrunprogram\buttonwidth\buttonheight{\@@prdirectory#2}{#3}}% - {\dostoprunprogram}% - \else - #4% - \fi - \endgroup} - -%D As we can see, we directly use the special reference -%D mechanism, which means that -%D -%D \starttyping -%D \goto{some text}[program(name{args})] -%D \stoptyping -%D -%D is valid. - -%D The next macro provides access to the actual pagenumbers. -%D When documenting and sanitizing the original reference -%D macros, I decided to keep the present meaning as well as to -%D make this meaning available as a special reference method. -%D So now one can use: -%D -%D \starttyping -%D \gotopage{some text}[location] -%D \gotopage{some text}[number] -%D \gotopage{some text}[file::number] -%D \stoptyping -%D -%D as well as: -%D -%D \starttyping -%D \goto{some text}[page(location)] -%D \goto{some text}[page(number)] -%D \goto{some text}[file::page(number)] -%D \stoptyping -%D -%D Here location is a keyword like \type{nextpage}. -%D -%D \showsetup{gotopage} - -\def\definepage - {\dodoubleargument\dodefinepage} - -\def\dodefinepage[#1][#2]% - {\definereference[#1][page(#1)]} - -\def\gotopage#1[#2]% - {\goto{#1}[\v!page(#2)]} - -%D The previous definitions are somewhat obsolete so we don't -%D use it here. - -%D A still very rudimentary|/|experimental forward|/|backward -%D reference mechanism is provided by the macro \type{\atpage}: -%D -%D \starttyping -%D ... \somewhere{backward text}{forward text}[someref] ... -%D ... \atpage[someref] ... -%D \stoptyping -%D -%D In future versions there will be more sophisticated - -%D support, also suitable for references to floating bodies. - -\def\analysedreference#1% - {\ctxlua{jobreferences.analysis("\referenceprefix","#1")}} - -\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 % todo - {\dontleavehmode - \ifcase\analysedreference{#4}\relax - \unknownreference{#4}#1/#2% - \or - \doifelsenothing{#2}{\dosymbolreference{}{}[#4]}{\dogotospace{#2}[#4]}% - \or % forward - \doifelsenothing{#1}{\dosymbolreference{}{}[#4]}{\dogotospace{#1}[#4]}% - \or % backward - \doifelsenothing{#2}{\dosymbolreference{}{}[#4]}{\dogotospace{#2}[#4]}% - \fi - \referenceinfo{<}{#4}} - -\unexpanded\def\atpage[#1]% todo - {\dontleavehmode -% \docheckrealreferencepage{}% -% \doifreferencefoundelse{#1} -% {\ifrealreferencepage -% \ifforwardreference -% \dogotofixed{\labeltext\v!hencefore}[#1]% -% \else -% \dogotofixed{\labeltext\v!hereafter}[#1]% -% \fi -% \else -% \dogotofixed{\labeltexts\v!atpage\currentpagereference}[#1]% -% \fi} -% {\unknownreference{#1}% -% \labeltexts\v!page\dummyreference}% - \referenceinfo{<}{#1}} - -%D We can cross link documents by using: -%D -%D \showsetup{coupledocument} -%D -%D like: -%D -%D \starttyping -%D \coupledocument[print][somefile][chapter,section] -%D \stoptyping -%D -%D After which when applicable, we have available the -%D references: -%D -%D \starttyping -%D \goto{print version}[print::chapter] -%D \stoptyping -%D -%D and alike. The title placement definition macros have a -%D key \type{file}, which is interpreted as the file to jump -%D to, that is, when one clicks on the title. - -\newif\ifautocrossdocument - -\def\coupledocument - {\doquadrupleempty\docoupledocument} - -\def\docoupledocument[#1][#2][#3][#4]% [name] [file] [sections] [description] - {\ifthirdargument - % this will be done differently (when it's needed) - \fi} - -%D Buttons are just what their names says: things that can be -%D clicked (pushed) on. They are similar to \type{\goto}, -%D except that the text argument is not interpreted. -%D Furthermore one can apply anything to them that can be done -%D with \type{\framed}. -%D -%D \startbuffer -%D \button[width=3cm,height=1.5cm]{Exit}[ExitViewer] -%D \stopbuffer -%D -%D \typebuffer -%D -%D gives -%D -%D \getbuffer -%D -%D This command is formally specified as: -%D -%D \showsetup{button} -%D -%D The characteristics can be set with: -%D -%D \showsetup{setupbuttons} - -\def\setupbuttons - {\dodoubleargument\getparameters[\??bt]} - -\definecomplexorsimpleempty\button - -\def\complexbutton - {\docomplexbutton\??bt} - -\presetlocalframed[\??bt] - -\long\def\docomplexbutton#1[#2]#3#4% get rid of possible space before [#4] - {\dodocomplexbutton#1[#2]{#3}#4} % #4 == [ - -\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie - -\long\def\dodocomplexbutton#1[#2]#3[#4]% #3 can contain [] -> {#3} later - {\begingroup - \doifvalue{#1\c!state}\v!stop\locationfalse - \iflocation - \resetgoto - \ConvertConstantAfter\doifelse{#3}\v!none\hphantom\hbox - {\doifelsenothing{#4} - {\setlocationboxnop#1[#2]{#3}[#4]} - {\doifreferencefoundelse{#4} % INEFFICIENT - {\setlocationboxyes#1[#2]{#3}[#4]} - {\unknownreference{#4}% - \setlocationboxnop#1[#2]{#3}[#4]}}}% - \fi - \endgroup} - -%D Interaction buttons, in fact a row of tiny buttons, are -%D typically only used for navigational purposed. The next -%D macro builds such a row based on a specification list. -%D -%D \startbuffer -%D \interactionbuttons -%D [width=\hsize][page,PreviousJump,ExitViewer] -%D \stopbuffer -%D -%D \typebuffer -%D -%D gives -%D -%D \getbuffer -%D -%D Apart from individual entries, one can use \type{page} and -%D \type {subpage} as shortcuts to their four associated buttons. -%D The symbols are derived from the symbols linked to the -%D entries. - -% does not work well with for instance SomeRef{whatever} - -\def\interactionbuttons - {\dodoubleempty\dointeractionbuttons} - -\def\dointeractionbuttons[#1][#2]% er is een verdeel macro \horizontalfractions - {\iflocation - % BUG: fails when frame=off; best is to rewrite this macro - \bgroup - \doif\@@ibstate\v!stop\locationfalse - \iflocation - \ifsecondargument - \setupinteractionbar[#1]% - \checkinteractionbar{1.5em}\v!broad\!!zeropoint % brrrrr - \setbox2\hbox{\localframed[\??ib][\c!background=]{\symbol[\@@iasymbolset][\v!previouspage]}}% - \!!heighta\ht2 % needed because we default to nothing - \setupinteractionbar[\c!strut=\v!no]% - \setinteractionparameter\c!width\!!zeropoint - \!!counta\zerocount % new, was 1 - \processallactionsinset - [#2] - [ \v!page=>\advance\!!counta 4, - \v!subpage=>\advance\!!counta 4, - \s!unknown=>\advance\!!counta 1]% - \ifdim\@@ibwidth=\zeropoint - \!!widtha2em - \advance\!!widtha \@@ibdistance % new - \!!widthb\!!counta\!!widtha - \advance\!!widthb -\@@ibdistance % new - \else - \!!widtha\@@ibwidth - \!!widthb\@@ibdistance % new - \multiply\!!widthb \!!counta % new - \advance\!!widthb -\@@ibdistance % new - \advance\!!widtha -\!!widthb % new - \divide\!!widtha \!!counta - \!!widthb\@@ibwidth - \fi - \def\goto##1% clash ? - {\setnostrut - \edef\localreference{##1}% - \normalexpanded{\noexpand\dodocomplexbutton\??ib[\c!height=\the\!!heighta,\c!width=\the\!!widtha]}% - {\dontleavehmode\symbol[\@@iasymbolset][\localreference]}% - [\localreference]% - \hss}% - \hbox to \!!widthb - {\processallactionsinset - [#2] - [ \v!page=>\goto\v!firstpage - \goto\v!nextpage - \goto\v!previouspage - \goto\v!lastpage, - \v!subpage=>\goto\v!firstsubpage - \goto\v!nextsubpage - \goto\v!previoussubpage - \goto\v!lastsubpage, - \s!unknown=>\goto\commalistelement]% - \unskip}% - \else - \interactionbuttons[][#1]% - \fi - \fi - \egroup - \fi} - -%D \macros -%D {overlaybutton} -%D -%D For converience we provide: -%D -%D \starttyping -%D \overlaybutton[reference] -%D \stoptyping -%D -%D This command can be used to define overlays an/or can be -%D used in the whatevertext areas, like: -%D -%D \starttyping -%D \defineoverlay[PrevPage][\overlaybutton{PrevPage}] -%D \setupbackgrounds[page][background=PrevPage] -%D \setuptexttexts[\overlaybutton{NextPage}] -%D \stoptyping -%D -%D For practical reasons, this macro accepts square brackets -%D as well as braces. - -\definecomplexorsimple\overlaybutton - -\def\simpleoverlaybutton#1% - {\complexoverlaybutton[#1]} - -\def\complexoverlaybutton[#1]% - {\iflocation - \doprocessreferenceelse{#1} - {\overlayfakebox {#1}} - {\unknownreference{#1}}% - \fi} - -\def\overlayfakebox#1% - {\hbox - {\setbox\scratchbox\null - \wd\scratchbox\overlaywidth - \ht\scratchbox\overlayheight - \locationstrutfalse - \box\scratchbox}} - -%D \macros -%D {dotextprefix} -%D -%D In previous macros we used \type {\dotextprefix} to -%D generate a space between a label and a number. -%D -%D \starttyping -%D \dotextprefix{text} -%D \stoptyping -%D -%D Only when \type {text} is not empty, a space is inserted. - -\def\dotextprefix#1% - {\begingroup - \global\labeltextdonefalse % this is an ugly dependancy, - \setbox\scratchbox\hbox{#1}% to be solved some day - \ifdim\wd\scratchbox>\zeropoint - \unhbox\scratchbox - \iflabeltextdone\else\@@rfseparator\fi - \else - \unhbox\scratchbox - \fi - \endgroup} - -%D In the next settings we see some variables that were not -%D used here and that concern the way the pagenumbers refered -%D to are typeset. - -\setupreferencing - [\c!state=\v!start, - \c!autofile=\v!no, - \v!part\c!number=\v!yes, - \v!chapter\c!number=\v!no, - \c!interaction=\v!all, - \c!convertfile=\v!no, - %\c!strut=\v!no, % some day an option - \c!prefix=, - \c!width=.75\makeupwidth, - \c!left=\quotation\bgroup, - \c!right=\egroup, - \c!global=\v!no, - \c!expansion=\v!no, - \c!separator=\nonbreakablespace] - -\setupurl - [\c!alternative=\v!both, - \c!space=\v!no, - \c!style=\v!type, - \c!color=] - -\setupprograms - [\c!directory=, - \c!alternative=\v!both, - \c!space=\v!no, - \c!style=\v!type, - \c!color=] - -\definereference [\v!CloseDocument ] [action(close)] -\definereference [\v!ExitViewer ] [action(exit)] -\definereference [\v!FirstPage ] [action(first)] -\definereference [\v!LastPage ] [action(last)] -\definereference [\v!NextJump ] [action(forward)] -\definereference [\v!NextPage ] [action(next)] -\definereference [\v!PauseMovie ] [action(pausemovie)] -\definereference [\v!PauseSound ] [action(pausesound)] -\definereference [\v!PauseRendering ] [action(pauserendering)] -\definereference [\v!PreviousJump ] [action(backward)] -\definereference [\v!PreviousPage ] [action(previous)] -\definereference [\v!PrintDocument ] [action(print)] -\definereference [\v!SaveForm ] [action(exportform)] -\definereference [\v!LoadForm ] [action(importform)] -\definereference [\v!ResetForm ] [action(resetform)] -\definereference [\v!ResumeMovie ] [action(resumemovie)] -\definereference [\v!ResumeSound ] [action(resumesound)] -\definereference [\v!ResumeRendering ] [action(resumerendering)] -\definereference [\v!SaveDocument ] [action(save)] -\definereference [\v!SaveNamedDocument] [action(savenamed)] -\definereference [\v!OpenNamedDocument] [action(opennamed)] -\definereference [\v!SearchDocument ] [action(search)] -\definereference [\v!SearchAgain ] [action(searchagain)] -\definereference [\v!StartMovie ] [action(startmovie)] -\definereference [\v!StartSound ] [action(startsound)] -\definereference [\v!StartRendering ] [action(startrendering)] -\definereference [\v!StopMovie ] [action(stopmovie)] -\definereference [\v!StopSound ] [action(stopsound)] -\definereference [\v!StopRendering ] [action(stoprendering)] -\definereference [\v!SubmitForm ] [action(submitform)] -\definereference [\v!ToggleViewer ] [action(toggle)] -\definereference [\v!ViewerHelp ] [action(help)] -\definereference [\v!HideField ] [action(hide)] -\definereference [\v!ShowField ] [action(show)] -\definereference [\v!GotoPage ] [action(gotopage)] -\definereference [\v!GotoPage ] [action(gotopage)] -\definereference [\v!Query ] [action(query)] -\definereference [\v!QueryAgain ] [action(queryagain)] -\definereference [\v!FitWidth ] [action(fitwidth)] -\definereference [\v!FitHeight ] [action(fitheight)] -\definereference [\v!ShowThumbs ] [action(thumbnails)] -\definereference [\v!ShowBookmarks ] [action(bookmarks)] - -\definereference [\v!firstpage] [page(\firstpage)] -\definereference [\v!previouspage] [page(\prevpage)] -\definereference [\v!nextpage] [page(\nextpage)] -\definereference [\v!lastpage] [page(\lastpage)] -\definereference [\v!firstsubpage] [page(\firstsubpage)] -\definereference [\v!previoussubpage] [page(\prevsubpage)] -\definereference [\v!nextsubpage] [page(\nextsubpage)] -\definereference [\v!lastsubpage] [page(\lastsubpage)] -\definereference [\v!first] [page(\firstpage)] -\definereference [\v!previous] [page(\prevpage)] -\definereference [\v!next] [page(\nextpage)] -\definereference [\v!last] [page(\lastpage)] -\definereference [\v!first\v!sub] [page(\firstsubpage)] -\definereference [\v!previous\v!sub] [page(\prevsubpage)] -\definereference [\v!next\v!sub] [page(\nextsubpage)] -\definereference [\v!last\v!sub] [page(\lastsubpage)] - -%D We cannot set up buttons (not yet, this one calls a menu macro): - -\protect \endinput diff --git a/tex/context/base/strc-reg.mkii b/tex/context/base/strc-reg.mkii new file mode 100644 index 000000000..8d824bd9d --- /dev/null +++ b/tex/context/base/strc-reg.mkii @@ -0,0 +1,1242 @@ +%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} {\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..b764525e1 --- /dev/null +++ b/tex/context/base/strc-reg.mkiv @@ -0,0 +1,907 @@ +%D \module +%D [ file=strc-reg, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Registers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Registers} + +\registerctxluafile{strc-reg}{1.001} + +\unprotect + +% todo: tag:: becomes rendering +% todo: language, character, linked, location + +%D Helper: + +\def\doflushatpar{\ifvmode\expandafter\dogotopar\else\expandafter\firstofoneargument\fi} + +% In plaats van + kan een & worden gebruikt. Ook kan als +% eerste karakter worden opgegeven wat de scheider is. +% +% \index {entry} +% \index[key] {entry} +% \index[pageclass::] {entry} +% \index[pageclass::key]{entry} +% \index {textclass::entry} +% \index[key] {textclass::entry} +% \index[pageclass::] {textclass::entry} +% \index[pageclass::key]{textclass::entry} + +%D Parameters: + +\let\currentregister\empty + +\def\registerparameter#1{\csname\??id\currentregister#1\endcsname} + +\def\registerparameter #1{\csname\doregisterparameter{\??id\currentregister}#1\endcsname} +\def\registerparameterhash#1{\doregisterparameterhash {\??id\currentregister}#1} + +\def\doregisterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doregisterparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\doregisterparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doregisterparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\doregisterparentparameter #1#2{\ifx#1\relax\s!empty\else\doregisterparameter #1#2\fi} +\def\doregisterparentparameterhash#1#2{\ifx#1\relax \else\doregisterparameterhash#1#2\fi} + +\def\dosetregisterattributes#1#2% style color + {\edef\fontattributehash {\registerparameterhash#1}% + \edef\colorattributehash{\registerparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +%D Setup: + +\newtoks\everysetupregister + +\def\setupregisters + {\dotripleempty\dosetupregisters} + +\def\dosetupregisters[#1][#2][#3]% + {\ifthirdargument + \def\dodosetupregister##1{\getparameters[\??id##1#2][#3]}% + \processcommalist[#1]\dodosetupregister + \else\ifsecondargument + \def\dodosetupregister##1{\edef\currentregister{##1}\getparameters[\??id##1][#2]\the\everysetupregister}% + \processcommalist[#1]\dodosetupregister + \else + \getparameters[\??id][#1]% + \fi\fi} + +\let\setupregister\setupregisters + +\setupregisters + [\c!n=2, + \c!balance=\v!yes, % \v!no komt niet zo vaak voor + \c!align=\v!flushleft, + \c!tolerance=\v!stretch, + \c!before=\blank, + %\c!after=, + %\c!symbol=, + \c!compress=\v!no, + \c!interaction=\v!pagenumber, + \c!alternative=\v!a, + \c!distance=1em, + \c!style=\v!bold, + \c!pagestyle=\v!slanted, + \c!indicator=\v!yes, + \c!criterium=\v!all, + %\c!command=, + \c!referencing=\v!on, + \c!location=\v!middle, + %\c!maxwidth=, + \c!number=\v!no, + \c!unknownreference=\v!empty, + \c!prefix=\v!both, + %\c!expansion=, + \c!pageprefixconnector=\endash, + \c!pagesegments=2:2, + \c!file=\jobname, + %\c!deeptextcommand=, % undefined by default ! + \s!language=\currentmainlanguage]% + +%D Definition: + +\def\defineregister + {\dodoubleargument\dodefineregister} + +\def\dodefineregister[#1][#2]% #2? + {\setupregister[#1][\s!parent=\??id]% + \ctxlua{jobregisters.define('#1')}% + \presetheadtext[#1=\Word{#1}]% + \unexpanded\setvalue{#1}{\dodoubleempty\doregister[#1]}% + \unexpanded\setvalue{\e!see#1}{\dodoubleempty\doseeregister[#1]}% +% \unexpanded\setvalue{\e!coupled#1}{\dolinkedregister{#1}}% + \setvalue{\e!place#1}{\placeregister[#1]}% + \setvalue{\e!complete#1}{\completeregister[#1]}% + \setvalue{\e!setup#1\e!endsetup}[##1]{\getparameters[\??id#1][##1]}} + +%D Registering: + +\newif\ifwritetoregister \writetoregistertrue + +% tzt variant met n entries, parameters en userdata (altnum) + +\def\doprocesspageregister#1#2#3#4#5% register tag key altnum entry + {\begingroup + \edef\currentregister{#1}% + \edef\currentregistertag{#2}% + \edef\currentregisterexpansion{\registerparameter\c!expansion}% + \edef\currentregisterownnumber{\registerparameter\c!ownnumber}% + \ifx\currentregisterexpansion\s!xml + \xmlstartraw + \xdef\currentregisterentries{\detokenize{#5}}% not ok yet + \xmlstopraw + \globallet\currentregistercoding\s!xml + \else + \ifx\currentregisterexpansion\v!yes + \xdef\currentregisterentries{#5}% not ok yet + \else + \xdef\currentregisterentries{\detokenize{#5}}% not ok yet + \fi + \globallet\currentregistercoding\s!tex + \fi + \setnextinternalreference + % we could consider storing register entries in list + \xdef\currentregisternumber{\ctxlua{ + jobregisters.store { + metadata = { + kind = "entry", + name = "\currentregister", + level = structure.sections.currentlevel(), + catcodes = \the\catcodetable, + own = \ifx\currentregisterownnumber\v!yes "#4" \else nil \fi, % can be used instead of pagenumber + }, + references = { + internal = \nextinternalreference, + section = structure.sections.currentid(), + }, + entries = { + % we need a special one for xml, this is just a single one + \!!bs\currentregisterentries\!!es, \!!bs#3\!!es + }, + } + } }% + \xdef\currentregistersynchronize % make this a macro because shared + {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% + \ifx\currentregisterownnumber\v!yes \else + \noexpand\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}% + \fi}% + \ifx\currentregistertag\empty \else + \setxvalue{\??id#1->#2}{\noexpand\dofinishpageregister{\currentregister}{\currentregisternumber}}% + \fi + \currentregistersynchronize % here? + \endgroup} + +\def\dofinishpageregister#1#2% + {\ctxlatelua{jobregisters.extend("#1",#2,\ctxlua{tex.write(structure.currentsectionnumber())}}} + +\def\doregister[#1][#2]% + {\def\currentregister{#1}% + \doifelse{\registerparameter\c!ownnumber}\v!yes\dodoregister\donoregister{#1}{#2}} + +\def\donoregister #1#2{\doflushatpar{\doprocesspageregister{#1}{}{}{#2}}} % register key - entry +\def\dodoregister#1#2#3{\doflushatpar{\doprocesspageregister{#1}{}{#2}{#3}}} % register key altnum entry + +\def\startregister{\doquadrupleempty\dostartregister} +\def\stopregister {\dodoubleargument\dostopregister} + +% a synonym, so that we can nest with overlap without syntax check problems + +\let\openregisterrange \startregister +\let\closeregisterrange\stopregister + +\def\dostartregister[#1][#2][#3][#4]#5% + {\iffourthargument + % #1=register #2=tag #3=own #4=sortkey #5=entry + \doflushatpar{\doprocesspageregister{#1}{#2}{#4}{#3}{#5}}% + \else + % #1=register #2=tag #3=sortkey #5=entry + \doflushatpar{\doprocesspageregister{#1}{#2}{#3}{}{#5}}% + \fi} + +\def\dostopregister[#1][#2]% + {\ifcsname\??id#1->#2\endcsname + \getvalue{\??id#1->#2}% + \letgvalue{\??id#1->#2}\relax + \fi} + +\def\doseeregister[#1][#2]#3#4% + {\doflushatpar{\doprocessseeregister{#1}{#2}{#3}{#4}}} + +\def\doprocessseeregister#1#2#3#4% register key entry seeword + {\begingroup + \edef\currentregister{#1}% + \edef\currentregisterexpansion{\registerparameter\c!expansion}% + \ifx\currentregisterexpansion\s!xml + \xmlstartraw + \xdef\currentregisterentries{\detokenize{#3}}% not ok yet + \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet + \xmlstopraw + \globallet\currentregistercoding\s!xml + \else + \ifx\currentregisterexpansion\v!yes + \xdef\currentregisterentries{#3}% not ok yet + \xdef\currentregisterseeword{#4}% not ok yet + \else + \xdef\currentregisterentries{\detokenize{#3}}% not ok yet + \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet + \fi + \globallet\currentregistercoding\s!tex + \fi + \setnextinternalreference + % we could consider storing register entries in list + \ctxlua{ jobregisters.store { + metadata = { + kind = "see", + name = "\currentregister", + level = structure.sections.currentlevel(), + catcodes = \the\catcodetable, + }, + references = { + internal = \nextinternalreference, + section = structure.sections.currentid(), + }, + entries = { + % we need a special one for xml, this is just a single one + "\currentregisterentries", "#2" + }, + seeword = { + text = "\currentregisterseeword" + }, + } + }% + \endgroup} + +%D Rendering: + +\let\utilityregisterlength\!!zerocount + +\def\determineregistercharacteristics + {\dodoubleempty\dodetermineregistercharacteristics} + +\def\dodetermineregistercharacteristics[#1][#2]% + {\edef\utilityregisterlength{\ctxlua{jobregisters.analyse('\currentregister')}}% + \ifcase\utilityregisterlength\relax + \resetsystemmode\v!register + \else + \setsystemmode \v!register + \fi} + +\newtoks\everyplaceregister + +\appendtoks + \dontcomplain +\to \everyplaceregister + +\def\placeregister + {\dodoubleempty\doplaceregister} + +\def\doplaceregister[#1][#2]% + {\iffirstargument + \begingroup + \edef\currentregister{#1}% + \setupregister[\currentregister][#2]% + \the\everyplaceregister + \startcolumns + [\c!n=\registerparameter\c!n, + \c!balance=\registerparameter\c!balance, + \c!align=\registerparameter\c!align, + \c!tolerance=\registerparameter\c!tolerance]% + \startpacked[\v!blank]% + \ctxlua{jobregisters.process('\currentregister',{ + language = "\registerparameter\s!language", + compress = "\registerparameter\c!compress", + criterium = "\registerparameter\c!criterium", + }, + { +% prefix = "\registerparameter\c!pageprefix", + separatorset = "\registerparameter\c!pageprefixseparatorset", + conversionset = "\registerparameter\c!pageprefixconversionset", + stopper = \!!bs\registerparameter\c!pageprefixstopper\!!es, + set = "\registerparameter\c!pageprefixset", + segments = "\registerparameter\c!pageprefixsegments", + connector = \!!bs\registerparameter\c!pageprefixconnector\!!es, + }, + { + prefix = "\registerparameter\c!pageprefix", + separatorset = "\registerparameter\c!pageseparatorset", + conversionset = "\registerparameter\c!pageconversionset", + stopper = \!!bs\registerparameter\c!pagestopper\!!es, + segments = "\registerparameter\c!pagesegments", + } + )}% + \stoppacked + \stopcolumns + \endgroup + \fi} + +\def\dolimitedregisterentry#1{\limitatetext{#1}\currentregistermaxwidth\unknown}% + +\appendtoks + \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}% + \ifx\currentregistermaxwidth\empty + \let\limitedregisterentry\firstofoneargument + \else + \let\limitedregisterentry\dolimitedregisterentry + \fi +\to \everyplaceregister + +\def\completeregister + {\dodoubleempty\docompleteregister} + +\def\docompleteregister[#1][#2]% + {\iffirstargument + \begingroup + \edef\currentregister{#1}% + % the expansion is needed because we don't want \v!'s in the tuo file (french) + \normalexpanded{\noexpand\systemsuppliedchapter[\currentregister]{\noexpand\headtext{\currentregister}}}% + \placeregister[\currentregister][#2]% + \page[\v!yes]% + \endgroup + \fi} + +% test case for collapsing (experimental, for Steffen Wolfrum) +% +% \starttext +% \placeregister[index][collapse=no] \blank[2*big] +% \placeregister[index][collapse=yes] \blank[2*big] +% \placeregister[index][collapse=akk] \page +% \dorecurse{10}{test 1:!\index{test} test \page} +% \dorecurse{5} {test 2:\recurselevel \page} +% \dorecurse{10}{test 3:!\index{test} test \page} +% \dorecurse{5} {test 4:\recurselevel \page} +% \dorecurse{1} {test 5:!\index{test} test \page} +% \dorecurse{5} {test 6:\recurselevel \page} +% \dorecurse{10}{test 7:!\index{test} test \page} +% \dorecurse{5} {test 8:\recurselevel \page} +% oeps \index{oeps} +% xxxx \index{xxxx} +% todo \index{todo} +% \stoptext + +%D Character rendering (sections): + +\def\defaultregistercharacter#1% + {\doifsomething{#1} + {\doifelse{\registerparameter\c!indicator}\v!yes + {\executeifdefined{\strippedcsname\doregistercharacter\registerparameter\c!alternative}\doregistercharactera{#1}} + {\noregistercharacter{#1}}}} + +\def\noregistercharacter#1% + {\registerparameter\c!before + \goodbreak} + +% a = + +\def\doregistercharactera#1% + {\registerparameter\c!before + \vskip\lineheight\goodbreak\vskip-\lineheight + \ifhmode\unskip\else\noindent\fi % brrr + \begingroup\dosetregisterattributes\c!style\c!color + \registerparameter\c!command{\strut#1}% + \endgroup + \registerparameter\c!after + \par\nobreak} + +% b = + +\def\doregistercharacterb#1% here no lineheight hackery ! ! ! + {\registerparameter\c!before + \ifhmode\unskip\else\noindent\fi % brrr + \begingroup\dosetregisterattributes\c!style\c!color + \registerparameter\c!command{\strut#1}% + \endgroup + \registerparameter\c!after + \nobreak} + +% extra: + +\def\doregistercharacterA#1{\doregistercharactera{\WORD{#1}}} +\def\doregistercharacterB#1{\doregistercharacterb{\WORD{#1}}} + +%D The following macros are the interface to the rendering. These are +%D generated by \LUA. This might change. + +\def\startregisteroutput + {\endgraf} + +\def\stopregisteroutput + {\endgraf} + +\def\startregisterentries#1% depth + {\endgraf + \begingroup + \dosetregisterattributes\c!textstyle\c!textcolor + \advance\leftskip\numexpr#1-1\relax\dimexpr\registerparameter\c!distance\relax + \hangindent\registerparameter\c!distance\hangafter\plusone} + +\def\stopregisterentries + {\endgraf + \endgroup} + +\def\startregistersection#1% title + {\registercharacter{#1}\endgraf} + +\def\stopregistersection + {\endgraf} + +\newconditional\registerpagedone + +\def\startregisterpages + {\begingroup + \setfalse\registerpagedone + \dosetregisterattributes\c!pagestyle\c!pagecolor} + +\def\stopregisterpages + {\endgroup} + +\def\startregisterseewords + {\begingroup + \setfalse\registerpagedone + \dosetregisterattributes\c!pagestyle\c!pagecolor} + +\def\stopregisterseewords + {\endgroup} + +\def\registerpageseparator% todo: , configurable + {\ifconditional\registerpagedone + \registerpageseparatorsymbol + \else + \hskip\registerparameter\c!distance\relax + \settrue\registerpagedone + \fi} + +\def\registeronepage#1% content + {\registerpageseparator\registerparameter\c!pagecommand{#1}} + +\def\registerpagerange#1#2% content, content todo: -- configurable + {\registerpageseparator\registerparameter\c!pagecommand{#1}|--|\registerparameter\c!pagecommand{#2}} + +\def\registeroneword#1% content + {\registerpageseparator\registerseeword{#1}} + +\def\defaultregisterentry #1{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#1}}}} +\def\defaultregisterseeword#1{\labeltexts\v!see{#1}} + +\let\registerseeword \defaultregisterseeword +\let\registerentry \defaultregisterentry +\let\registercharacter\defaultregistercharacter + +%D A few specific rendering variants: + +% \def\doregisterpagelocation#1#2% +% {\nextregisterpage +% \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}} + +% todo: \installregisterpagehandler + +\def\registerpagebuttonsymbol{\vrule\!!width1em\!!height1ex\!!depth\zeropoint\relax} + +\setvalue{\??id:\c!symbol :\c!n}{\def\registerpageseparatorsymbol{, }\let\registerpagenumberhandler\firstofoneargument} +\setvalue{\??id:\c!symbol :\c!a}{\def\registerpageseparatorsymbol{, }\let\registerpagenumberhandler\firstofoneargument} % now done via conversion +\setvalue{\??id:\c!symbol:\v!none}{\let\registerpageseparatorsymbol\empty\let\registerpagenumberhandler\gobbleoneargument} +\setvalue{\??id:\c!symbol :1}{\let\registerpageseparatorsymbol\space\def\registerpagenumberhandler{\symbol[1]\gobbleoneargument}} +\setvalue{\??id:\c!symbol :2}{\let\registerpageseparatorsymbol\space\def\registerpagenumberhandler{\registerpagebuttonsymbol\gobbleoneargument}} + +\def\setregisterpagerendering + {\edef\currentregisterpagesymbol{\registerparameter\c!symbol}% + \ifx\currentregisterpagesymbol\empty + \csname\??id:\c!symbol:\c!n\endcsname + \else\ifcsname\??id:\c!symbol:\currentregisterpagesymbol\endcsname + \csname\??id:\c!symbol:\currentregisterpagesymbol\endcsname + \else + \let\registerpageseparatorsymbol\space + \def\registerpagenumberhandle{\registerparameter\c!symbol\gobbleoneargument}% + \fi\fi} + +\appendtoks + \setregisterpagerendering +\to \everyplaceregister + +%D Don't use \type{\string#2}; another hack is needed, since +%D \type {#2} can be \type {\string} itself. +% +% \def\doregisterreference[#1]#2% +% {\doifsomething{#2} +% {\doif{\registerparameter\c!referencing}\v!on +% {\pagereference[#1:\strippedcsname#2]}}} + +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % + +%D The following code will be reimplemented (not that hard) when it's needed +%D again and/or when I'm bored. + +% \def\getalllistreferences#1#2% +% {\gdefconvertexpanded\currentregisterentry{\getvalue{\??id#1\c!expansion}}{#2}% +% \doifdefinedelse{\??id#1\??id\currentregisterentry} +% {\edef\alllistreferences% +% {\getvalue{\??id#1\??id\currentregisterentry}}% +% \beforesplitstring\alllistreferences\at::\to\internallistreference +% \aftersplitstring \alllistreferences\at::\to\alllistreferences} +% {\let\alllistreferences\empty +% \def\internallistreference{0}}} + +% \def\dosetlinkregister#1% is die page reference echt nodig? +% {\setregisterpage{#1}% +% \global\let\currentregisterentry\empty +% \global\firstsubentrytrue % not needed +% \global\firstsubsubentrytrue % not needed too +% \setvalue{#1\s!entrya}##1{\dosetlinkregisterentrya{#1}{##1}}% +% \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}} + +% \def\dosetlinkregisterentrya#1#2% +% {\global\utilitydonetrue +% \c!entryletter +% \iflocation +% \getalllistreferences{#1}{#2}% +% % no \endgraf +% \hangindent1em\noindent\c!entryreference +% % +% %\thisissomeinternal{\s!lin}{\internallistreference}% +% % +% \pagereference[-:\s!lin:\internallistreference]% -: added +% % +% \getcommacommandsize[\alllistreferences]% +% \getfromcommacommand[\alllistreferences][1]% +% \ifnum\commalistsize=1 +% \let\firstlistreference\empty +% \let\midlistreference\commalistelement +% \let\lastlistreference\empty +% \else +% \let\firstlistreference\commalistelement +% \getfromcommacommand[\alllistreferences][\commalistsize]% +% \let\lastlistreference\commalistelement +% \ifnum\commalistsize=2 +% \let\midlistreference\empty +% \else +% \!!counta\commalistsize +% \divide\!!counta 2 +% \getfromcommacommand[\alllistreferences][\!!counta]% +% \let\midlistreference\commalistelement +% \fi +% \fi +% % aangepast +% \def\dodocommand[##1-##2]% +% {\gotonextinternal{\s!ind}{##1}{##2}{\box0}}% +% \doifelsevalue{\??id#1\c!interaction}\v!pagenumber +% {\limitedregisterentry{#1}{#2}} % paginanummer +% {{\setbox0\hbox{\limitedregisterentry{#1}{\begstrut#2}}% +% \ifx\firstlistreference\empty % tekst,alles +% \ifx\midlistreference\empty +% \box0 +% \else +% \expandafter\dodocommand\expandafter[\midlistreference]% +% \fi +% \else +% \expandafter\dodocommand\expandafter[\firstlistreference]% +% \fi}}% +% \doifvalue{\??id#1\c!number}\v!yes +% {\hskip\getvalue{\??id#1\c!distance}(\commalistsize)}% +% \doifnotvalue{\??id#1\c!interaction}\v!text % paginanummer,alles +% {\def\docommand##1##2% +% {{\setbox0\hbox{\showlocation{\hbox to 1em{\hss\symbol[##2]\hss}}}% +% \ifx##1\empty +% % \hskip\wd0 % (optioneel maken) +% \else +% \expandafter\dodocommand\expandafter[##1]% +% \fi}}% +% \hskip\getvalue{\??id#1\c!distance}% +% \docommand\firstlistreference\v!previous +% \docommand\midlistreference\v!somewhere +% \docommand\lastlistreference\v!next}% +% % tot hier +% \else +% % no \endgraf +% \noindent\c!entryreference +% \limitedregisterentry{#1}{#2}% +% \fi +% \endgraf} + +% \def\dosetregister#1% +% {\doifelsevalue{\??id#1\c!coupling}\v!yes +% {\ifautoregisterhack +% \dosetautoregister{#1}% +% \else +% \dosetlinkregister{#1}% +% \fi} +% {\dosetpageregister{#1}}} + +\def\dosetregister#1% + {\dosetpageregister{#1}} + +% \newcounter\internallistreference + +% \def\doloadregisterlinks#1% +% {\setregisterpage{#1}% +% \global\let\currentregisterentry\empty +% \global\firstregisterpagetrue +% \setvalue{#1\s!entrya}##1% +% {\global\firstregisterpagetrue +% \gdefconvertedargument\currentregisterentry{##1}% global nodig? +% \doglobal\increment\internallistreference}% +% \setvalue{#1\s!from}% +% {\getvalue{#1\s!page}}% +% \ifautoregisterhack +% \setvalue{#1\s!page}##1##2##3##4% +% {\doifreglevelelse[##3] +% {\global\utilitydonetrue +% \iffirstregisterpage +% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname +% {\internallistreference::##4}% +% \else % catches errors in index +% \ifcsname\??id#1\??id\currentregisterentry\endcsname +% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname +% {\csname\??id#1\??id\currentregisterentry\endcsname,##4}% +% \fi +% \fi} +% {}}% +% \else +% \setvalue{#1\s!page}##1##2##3##4% +% {\doifreglevelelse[##3] +% {\global\utilitydonetrue +% \iffirstregisterpage +% \global\firstregisterpagefalse +% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname +% {\internallistreference::##2-##4}% +% \else % catches errors in index +% \ifcsname\??id#1\??id\currentregisterentry\endcsname +% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname +% {\csname\??id#1\??id\currentregisterentry\endcsname,##2-##4}% +% \fi +% \fi} +% {}}% +% \fi} + +% \def\docoupleregister[#1][#2]% +% {\iflocation +% \ifcase0\countervalue{autolink:#1}\relax % only once +% \begingroup +% \let\dosetregister\doloadregisterlinks +% \def\currentregister{#1}% +% \setupregister[#1][#2]% +% \mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister +% \endgroup +% \ifautoregisterhack +% \doinitializeautoregister{#1}% +% \else +% \doinitializelinkregister{#1}% +% \fi +% \fi +% \fi} + +% \def\coupleregister +% {\dodoubleempty\docoupleregister} + +% \def\dodocommandprolinrefAA[#1-#2]% +% {\def\lastlistreference{#1-#2}} + +% \def\dodocommandprolinrefA[#1-#2]% +% {\def\lastlistreference{#1-#2}% +% \ifx\firstlistreference\empty +% \let\firstlistreference\lastlistreference +% \fi +% \ifnum#1<\nextinternalreference\relax +% \let\prevlistreference\lastlistreference +% \else\ifnum#1>\nextinternalreference\relax +% \let\nextlistreference\lastlistreference +% \let\dodocommandprolinrefA\dodocommandprolinrefAA +% \else +% \let\selflistreference\lastlistreference +% \fi\fi} + +% \def\docommandprolinrefA#1% +% {\dodocommandprolinrefA[#1]} + +% \def\dodocommandprolinrefB[#1-#2]% +% {\gotonextinternal{\s!ind}{#1}{#2}{\box0}} + +% \def\docommandprolinrefB#1#2#3% +% {\bgroup +% \ifx#2\empty +% \doifvalue{\??id#1\c!unknownreference}\v!empty{\hskip1em}% +% \else +% \setbox0\hbox to 1em{\hss\showlocation{\symbol[#3]}\hss}% +% \expandafter\dodocommandprolinrefB\expandafter[#2]% +% \fi +% \egroup} + +% \def\doprocesslinkregister[#1][#2]#3% +% {\hbox +% {\doprocesspageregister{}{#2}{}{#3}% +% \let\firstlistreference\empty +% \let\lastlistreference\empty +% \let\selflistreference\empty +% \let\prevlistreference\empty +% \let\nextlistreference\empty +% \getalllistreferences{#1}{#3}% +% \ifx\alllistreferences\empty \else +% \normalexpanded{\noexpand\rawprocesscommalist[\alllistreferences]}\docommandprolinrefA +% \fi +% \ifx\prevlistreference\empty +% \let\prevlistreference\lastlistreference +% \fi +% \ifx\nextlistreference\empty +% \let\nextlistreference\firstlistreference +% \fi +% \ifx\prevlistreference\selflistreference +% \let\prevlistreference\empty +% \let\nextlistreference\empty +% \fi +% \setalignmentswitch{\getvalue{\??id#1\c!location}}% +% \ifcase\alignmentswitch +% % links +% \docommandprolinrefB{#1}\prevlistreference\v!previous +% \docommandprolinrefB{#1}\nextlistreference\v!next +% \or +% % midden +% \docommandprolinrefB{#1}\prevlistreference\v!previous +% \or +% % rechts +% \fi +% \doifreferencefoundelse{\s!lin:\internallistreference} +% {\gotosomeinternal +% \s!lin \internallistreference \currentrealreference +% {\showlocation{\limitedregisterentry{#1}{#3}}}} +% {\hbox{\limitedregisterentry{#1}{#3}}}% +% \ifcase\alignmentswitch +% % links +% \or +% % midden +% \docommandprolinrefB{#1}\nextlistreference\v!next +% \or +% % rechts +% \docommandprolinrefB{#1}\prevlistreference\v!previous +% \docommandprolinrefB{#1}\nextlistreference\v!next +% \fi}} + +% \def\doprocesslinkedregister[#1][#2]#3% page auto link +% {\bgroup +% \chardef\registerpagestatus\plusone +% \def\currentregister{#1}% +% \iflocation % \next is not needed +% \ifautoregisterhack +% \def\next{\doprocessautoregister[#1][#2]}% +% \else +% \def\next{\doprocesslinkregister[#1][#2]}% +% \fi +% \else +% \def\next{\doprocesspageregister{}{#2}{}}% +% \fi +% \next{#3}% +% \egroup} + +% \def\dodolinkedregister[#1][#2]#3% page auto link +% {\doflushatpar{\doprocesslinkedregister[#1][#2]{#3}}} + +% \def\dolinkedregister#1% +% {\dodoubleempty\dodolinkedregister[#1]} + +% \def\dosetautoregister#1% +% {\makecounter{autolink:#1}% +% \setregisterpage{#1}% +% \global\let\currentregisterentry\empty +% \global\firstsubentrytrue % not needed +% \global\firstsubsubentrytrue % not needed too +% \setvalue{#1\s!entrya}##1{\dosetautoregisterentrya{#1}{##1}}% +% \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}} + +% \def\dosetautoregisterentrya#1#2% +% {\global\utilitydonetrue +% \c!entryletter +% \iflocation +% \getalllistreferences{#1}{#2}% +% \endgraf\hangindent1em\noindent\c!entryreference +% \pagereference[-:\s!lin:\internallistreference]% +% \pluscounter{autolink:#1}% +% \bgroup +% %\setupinteraction[\c!color=,\c!contrastcolor=,\c!style=]% kan sneller +% \resetinteractionparameter\c!color +% \resetinteractionparameter\c!contrastcolor +% \resetinteractionparameter\c!style +% \gotobox +% {\limitedregisterentry{#1}{\begstrut#2}}% +% [JS(SetRegisterEntry{\v!register,\countervalue{autolink:#1},#2,{\alllistreferences}})]% +% \egroup +% \else +% \endgraf\noindent\c!entryreference +% \limitedregisterentry{#1}{#2}% +% \fi} + +% \def\doprocessautoregister[#1][#2]#3% +% {\hbox +% {\doprocesspageregister{}{#2}{}{#3}% +% \doifreferencefoundelse{\s!lin:\internallistreference} +% {\gotosomeinternal \s!lin +% {\internallistreference}{\currentrealreference} +% {\showlocation{\limitedregisterentry{#1}{#3}}}} +% {\hbox{\limitedregisterentry{#1}{#3}}}}} + +% \appendmacro aan openpaginaactie (in shipout) + +%D The first implementation used one main field with clones. +%D In a 2500 page document this resulted in a rather (anoying) +%D long start||up time. This \quote {every page its own field} +%D solution, combined with a \quote {page open action}, works +%D much faster, but is conceptually pretty weak. + +% \def\complexregisterfield[#1]% +% {\definefield[#1:\realfolio][line][\v!register]% +% \field[#1:\realfolio]} + +% \def\simpleregisterfield +% {\complexregisterfield[\v!register]} + +% \definecomplexorsimple\registerfield + +% \appendtoks +% % for now +% \setupfield +% [\v!register] +% [\c!width=10em, +% \c!height=3ex, +% \c!align=\v!middle, +% \c!option=\v!readonly, +% \c!location=\v!low] +% \to \everydump + +% \def\doinitializeautoregister#1% +% {\useJSscripts[reg]% +% \useJSpreamblenow{LinkedRegisters}% +% \setupinteraction[\c!openpageaction=JS(UpdateRegisterField{\v!register})]% +% \definereference[\v!reset\v!register][JS(ResetRegisterEntry{\v!register})]% +% \definereference[\v!first\v!register][JS(GotoFirstRegisterEntry{\v!register})]% +% \definereference[\v!previous\v!register][JS(GotoPreviousRegisterEntry{\v!register})]% +% \definereference[\v!next\v!register][JS(GotoNextRegisterEntry{\v!register})]% +% \definereference[\v!last\v!register][JS(GotoLastRegisterEntry{\v!register})]} + +% \def\doinitializelinkregister#1% +% {} + +% todo ruwe register + +%D Default index: + +\defineregister + [\v!index] + [\v!indices] + +% \setupregister[index][koppeling=ja] +% +% \stelveldenin +% [register][achtergrond=raster,kader=uit] +% +% \stelvoettekstenin +% [{\field[index]}] +% +% \stelhoofdtekstenin +% [{\naar {first}[eersteindex]\quad +% \naar{previous}[vorigeindex]\quad +% \naar {next}[volgendeindex]\quad +% \naar {last}[laatsteindex]\quad\quad +% \naar {index}[index]}] +% +% \starttekst +% +% oeps~~~\gekoppeldeindex{oeps} \blanko +% flop~~~\gekoppeldeindex{flop} \blanko +% test~~~\gekoppeldeindex{test} \pagina +% flop~~~\gekoppeldeindex{flop} \blanko +% test~~~\gekoppeldeindex{test} \pagina +% oeps~~~\gekoppeldeindex{oeps} \blanko +% test~~~\gekoppeldeindex{test} \pagina +% flop~~~\gekoppeldeindex{flop} \blanko +% oeps~~~\gekoppeldeindex{oeps} \pagina +% +% \volledigeindex + +\protect \endinput diff --git a/tex/context/base/strc-reg.tex b/tex/context/base/strc-reg.tex deleted file mode 100644 index b764525e1..000000000 --- a/tex/context/base/strc-reg.tex +++ /dev/null @@ -1,907 +0,0 @@ -%D \module -%D [ file=strc-reg, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Registers, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Registers} - -\registerctxluafile{strc-reg}{1.001} - -\unprotect - -% todo: tag:: becomes rendering -% todo: language, character, linked, location - -%D Helper: - -\def\doflushatpar{\ifvmode\expandafter\dogotopar\else\expandafter\firstofoneargument\fi} - -% In plaats van + kan een & worden gebruikt. Ook kan als -% eerste karakter worden opgegeven wat de scheider is. -% -% \index {entry} -% \index[key] {entry} -% \index[pageclass::] {entry} -% \index[pageclass::key]{entry} -% \index {textclass::entry} -% \index[key] {textclass::entry} -% \index[pageclass::] {textclass::entry} -% \index[pageclass::key]{textclass::entry} - -%D Parameters: - -\let\currentregister\empty - -\def\registerparameter#1{\csname\??id\currentregister#1\endcsname} - -\def\registerparameter #1{\csname\doregisterparameter{\??id\currentregister}#1\endcsname} -\def\registerparameterhash#1{\doregisterparameterhash {\??id\currentregister}#1} - -\def\doregisterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doregisterparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\doregisterparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doregisterparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\doregisterparentparameter #1#2{\ifx#1\relax\s!empty\else\doregisterparameter #1#2\fi} -\def\doregisterparentparameterhash#1#2{\ifx#1\relax \else\doregisterparameterhash#1#2\fi} - -\def\dosetregisterattributes#1#2% style color - {\edef\fontattributehash {\registerparameterhash#1}% - \edef\colorattributehash{\registerparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -%D Setup: - -\newtoks\everysetupregister - -\def\setupregisters - {\dotripleempty\dosetupregisters} - -\def\dosetupregisters[#1][#2][#3]% - {\ifthirdargument - \def\dodosetupregister##1{\getparameters[\??id##1#2][#3]}% - \processcommalist[#1]\dodosetupregister - \else\ifsecondargument - \def\dodosetupregister##1{\edef\currentregister{##1}\getparameters[\??id##1][#2]\the\everysetupregister}% - \processcommalist[#1]\dodosetupregister - \else - \getparameters[\??id][#1]% - \fi\fi} - -\let\setupregister\setupregisters - -\setupregisters - [\c!n=2, - \c!balance=\v!yes, % \v!no komt niet zo vaak voor - \c!align=\v!flushleft, - \c!tolerance=\v!stretch, - \c!before=\blank, - %\c!after=, - %\c!symbol=, - \c!compress=\v!no, - \c!interaction=\v!pagenumber, - \c!alternative=\v!a, - \c!distance=1em, - \c!style=\v!bold, - \c!pagestyle=\v!slanted, - \c!indicator=\v!yes, - \c!criterium=\v!all, - %\c!command=, - \c!referencing=\v!on, - \c!location=\v!middle, - %\c!maxwidth=, - \c!number=\v!no, - \c!unknownreference=\v!empty, - \c!prefix=\v!both, - %\c!expansion=, - \c!pageprefixconnector=\endash, - \c!pagesegments=2:2, - \c!file=\jobname, - %\c!deeptextcommand=, % undefined by default ! - \s!language=\currentmainlanguage]% - -%D Definition: - -\def\defineregister - {\dodoubleargument\dodefineregister} - -\def\dodefineregister[#1][#2]% #2? - {\setupregister[#1][\s!parent=\??id]% - \ctxlua{jobregisters.define('#1')}% - \presetheadtext[#1=\Word{#1}]% - \unexpanded\setvalue{#1}{\dodoubleempty\doregister[#1]}% - \unexpanded\setvalue{\e!see#1}{\dodoubleempty\doseeregister[#1]}% -% \unexpanded\setvalue{\e!coupled#1}{\dolinkedregister{#1}}% - \setvalue{\e!place#1}{\placeregister[#1]}% - \setvalue{\e!complete#1}{\completeregister[#1]}% - \setvalue{\e!setup#1\e!endsetup}[##1]{\getparameters[\??id#1][##1]}} - -%D Registering: - -\newif\ifwritetoregister \writetoregistertrue - -% tzt variant met n entries, parameters en userdata (altnum) - -\def\doprocesspageregister#1#2#3#4#5% register tag key altnum entry - {\begingroup - \edef\currentregister{#1}% - \edef\currentregistertag{#2}% - \edef\currentregisterexpansion{\registerparameter\c!expansion}% - \edef\currentregisterownnumber{\registerparameter\c!ownnumber}% - \ifx\currentregisterexpansion\s!xml - \xmlstartraw - \xdef\currentregisterentries{\detokenize{#5}}% not ok yet - \xmlstopraw - \globallet\currentregistercoding\s!xml - \else - \ifx\currentregisterexpansion\v!yes - \xdef\currentregisterentries{#5}% not ok yet - \else - \xdef\currentregisterentries{\detokenize{#5}}% not ok yet - \fi - \globallet\currentregistercoding\s!tex - \fi - \setnextinternalreference - % we could consider storing register entries in list - \xdef\currentregisternumber{\ctxlua{ - jobregisters.store { - metadata = { - kind = "entry", - name = "\currentregister", - level = structure.sections.currentlevel(), - catcodes = \the\catcodetable, - own = \ifx\currentregisterownnumber\v!yes "#4" \else nil \fi, % can be used instead of pagenumber - }, - references = { - internal = \nextinternalreference, - section = structure.sections.currentid(), - }, - entries = { - % we need a special one for xml, this is just a single one - \!!bs\currentregisterentries\!!es, \!!bs#3\!!es - }, - } - } }% - \xdef\currentregistersynchronize % make this a macro because shared - {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% - \ifx\currentregisterownnumber\v!yes \else - \noexpand\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}% - \fi}% - \ifx\currentregistertag\empty \else - \setxvalue{\??id#1->#2}{\noexpand\dofinishpageregister{\currentregister}{\currentregisternumber}}% - \fi - \currentregistersynchronize % here? - \endgroup} - -\def\dofinishpageregister#1#2% - {\ctxlatelua{jobregisters.extend("#1",#2,\ctxlua{tex.write(structure.currentsectionnumber())}}} - -\def\doregister[#1][#2]% - {\def\currentregister{#1}% - \doifelse{\registerparameter\c!ownnumber}\v!yes\dodoregister\donoregister{#1}{#2}} - -\def\donoregister #1#2{\doflushatpar{\doprocesspageregister{#1}{}{}{#2}}} % register key - entry -\def\dodoregister#1#2#3{\doflushatpar{\doprocesspageregister{#1}{}{#2}{#3}}} % register key altnum entry - -\def\startregister{\doquadrupleempty\dostartregister} -\def\stopregister {\dodoubleargument\dostopregister} - -% a synonym, so that we can nest with overlap without syntax check problems - -\let\openregisterrange \startregister -\let\closeregisterrange\stopregister - -\def\dostartregister[#1][#2][#3][#4]#5% - {\iffourthargument - % #1=register #2=tag #3=own #4=sortkey #5=entry - \doflushatpar{\doprocesspageregister{#1}{#2}{#4}{#3}{#5}}% - \else - % #1=register #2=tag #3=sortkey #5=entry - \doflushatpar{\doprocesspageregister{#1}{#2}{#3}{}{#5}}% - \fi} - -\def\dostopregister[#1][#2]% - {\ifcsname\??id#1->#2\endcsname - \getvalue{\??id#1->#2}% - \letgvalue{\??id#1->#2}\relax - \fi} - -\def\doseeregister[#1][#2]#3#4% - {\doflushatpar{\doprocessseeregister{#1}{#2}{#3}{#4}}} - -\def\doprocessseeregister#1#2#3#4% register key entry seeword - {\begingroup - \edef\currentregister{#1}% - \edef\currentregisterexpansion{\registerparameter\c!expansion}% - \ifx\currentregisterexpansion\s!xml - \xmlstartraw - \xdef\currentregisterentries{\detokenize{#3}}% not ok yet - \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet - \xmlstopraw - \globallet\currentregistercoding\s!xml - \else - \ifx\currentregisterexpansion\v!yes - \xdef\currentregisterentries{#3}% not ok yet - \xdef\currentregisterseeword{#4}% not ok yet - \else - \xdef\currentregisterentries{\detokenize{#3}}% not ok yet - \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet - \fi - \globallet\currentregistercoding\s!tex - \fi - \setnextinternalreference - % we could consider storing register entries in list - \ctxlua{ jobregisters.store { - metadata = { - kind = "see", - name = "\currentregister", - level = structure.sections.currentlevel(), - catcodes = \the\catcodetable, - }, - references = { - internal = \nextinternalreference, - section = structure.sections.currentid(), - }, - entries = { - % we need a special one for xml, this is just a single one - "\currentregisterentries", "#2" - }, - seeword = { - text = "\currentregisterseeword" - }, - } - }% - \endgroup} - -%D Rendering: - -\let\utilityregisterlength\!!zerocount - -\def\determineregistercharacteristics - {\dodoubleempty\dodetermineregistercharacteristics} - -\def\dodetermineregistercharacteristics[#1][#2]% - {\edef\utilityregisterlength{\ctxlua{jobregisters.analyse('\currentregister')}}% - \ifcase\utilityregisterlength\relax - \resetsystemmode\v!register - \else - \setsystemmode \v!register - \fi} - -\newtoks\everyplaceregister - -\appendtoks - \dontcomplain -\to \everyplaceregister - -\def\placeregister - {\dodoubleempty\doplaceregister} - -\def\doplaceregister[#1][#2]% - {\iffirstargument - \begingroup - \edef\currentregister{#1}% - \setupregister[\currentregister][#2]% - \the\everyplaceregister - \startcolumns - [\c!n=\registerparameter\c!n, - \c!balance=\registerparameter\c!balance, - \c!align=\registerparameter\c!align, - \c!tolerance=\registerparameter\c!tolerance]% - \startpacked[\v!blank]% - \ctxlua{jobregisters.process('\currentregister',{ - language = "\registerparameter\s!language", - compress = "\registerparameter\c!compress", - criterium = "\registerparameter\c!criterium", - }, - { -% prefix = "\registerparameter\c!pageprefix", - separatorset = "\registerparameter\c!pageprefixseparatorset", - conversionset = "\registerparameter\c!pageprefixconversionset", - stopper = \!!bs\registerparameter\c!pageprefixstopper\!!es, - set = "\registerparameter\c!pageprefixset", - segments = "\registerparameter\c!pageprefixsegments", - connector = \!!bs\registerparameter\c!pageprefixconnector\!!es, - }, - { - prefix = "\registerparameter\c!pageprefix", - separatorset = "\registerparameter\c!pageseparatorset", - conversionset = "\registerparameter\c!pageconversionset", - stopper = \!!bs\registerparameter\c!pagestopper\!!es, - segments = "\registerparameter\c!pagesegments", - } - )}% - \stoppacked - \stopcolumns - \endgroup - \fi} - -\def\dolimitedregisterentry#1{\limitatetext{#1}\currentregistermaxwidth\unknown}% - -\appendtoks - \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}% - \ifx\currentregistermaxwidth\empty - \let\limitedregisterentry\firstofoneargument - \else - \let\limitedregisterentry\dolimitedregisterentry - \fi -\to \everyplaceregister - -\def\completeregister - {\dodoubleempty\docompleteregister} - -\def\docompleteregister[#1][#2]% - {\iffirstargument - \begingroup - \edef\currentregister{#1}% - % the expansion is needed because we don't want \v!'s in the tuo file (french) - \normalexpanded{\noexpand\systemsuppliedchapter[\currentregister]{\noexpand\headtext{\currentregister}}}% - \placeregister[\currentregister][#2]% - \page[\v!yes]% - \endgroup - \fi} - -% test case for collapsing (experimental, for Steffen Wolfrum) -% -% \starttext -% \placeregister[index][collapse=no] \blank[2*big] -% \placeregister[index][collapse=yes] \blank[2*big] -% \placeregister[index][collapse=akk] \page -% \dorecurse{10}{test 1:!\index{test} test \page} -% \dorecurse{5} {test 2:\recurselevel \page} -% \dorecurse{10}{test 3:!\index{test} test \page} -% \dorecurse{5} {test 4:\recurselevel \page} -% \dorecurse{1} {test 5:!\index{test} test \page} -% \dorecurse{5} {test 6:\recurselevel \page} -% \dorecurse{10}{test 7:!\index{test} test \page} -% \dorecurse{5} {test 8:\recurselevel \page} -% oeps \index{oeps} -% xxxx \index{xxxx} -% todo \index{todo} -% \stoptext - -%D Character rendering (sections): - -\def\defaultregistercharacter#1% - {\doifsomething{#1} - {\doifelse{\registerparameter\c!indicator}\v!yes - {\executeifdefined{\strippedcsname\doregistercharacter\registerparameter\c!alternative}\doregistercharactera{#1}} - {\noregistercharacter{#1}}}} - -\def\noregistercharacter#1% - {\registerparameter\c!before - \goodbreak} - -% a = - -\def\doregistercharactera#1% - {\registerparameter\c!before - \vskip\lineheight\goodbreak\vskip-\lineheight - \ifhmode\unskip\else\noindent\fi % brrr - \begingroup\dosetregisterattributes\c!style\c!color - \registerparameter\c!command{\strut#1}% - \endgroup - \registerparameter\c!after - \par\nobreak} - -% b = - -\def\doregistercharacterb#1% here no lineheight hackery ! ! ! - {\registerparameter\c!before - \ifhmode\unskip\else\noindent\fi % brrr - \begingroup\dosetregisterattributes\c!style\c!color - \registerparameter\c!command{\strut#1}% - \endgroup - \registerparameter\c!after - \nobreak} - -% extra: - -\def\doregistercharacterA#1{\doregistercharactera{\WORD{#1}}} -\def\doregistercharacterB#1{\doregistercharacterb{\WORD{#1}}} - -%D The following macros are the interface to the rendering. These are -%D generated by \LUA. This might change. - -\def\startregisteroutput - {\endgraf} - -\def\stopregisteroutput - {\endgraf} - -\def\startregisterentries#1% depth - {\endgraf - \begingroup - \dosetregisterattributes\c!textstyle\c!textcolor - \advance\leftskip\numexpr#1-1\relax\dimexpr\registerparameter\c!distance\relax - \hangindent\registerparameter\c!distance\hangafter\plusone} - -\def\stopregisterentries - {\endgraf - \endgroup} - -\def\startregistersection#1% title - {\registercharacter{#1}\endgraf} - -\def\stopregistersection - {\endgraf} - -\newconditional\registerpagedone - -\def\startregisterpages - {\begingroup - \setfalse\registerpagedone - \dosetregisterattributes\c!pagestyle\c!pagecolor} - -\def\stopregisterpages - {\endgroup} - -\def\startregisterseewords - {\begingroup - \setfalse\registerpagedone - \dosetregisterattributes\c!pagestyle\c!pagecolor} - -\def\stopregisterseewords - {\endgroup} - -\def\registerpageseparator% todo: , configurable - {\ifconditional\registerpagedone - \registerpageseparatorsymbol - \else - \hskip\registerparameter\c!distance\relax - \settrue\registerpagedone - \fi} - -\def\registeronepage#1% content - {\registerpageseparator\registerparameter\c!pagecommand{#1}} - -\def\registerpagerange#1#2% content, content todo: -- configurable - {\registerpageseparator\registerparameter\c!pagecommand{#1}|--|\registerparameter\c!pagecommand{#2}} - -\def\registeroneword#1% content - {\registerpageseparator\registerseeword{#1}} - -\def\defaultregisterentry #1{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#1}}}} -\def\defaultregisterseeword#1{\labeltexts\v!see{#1}} - -\let\registerseeword \defaultregisterseeword -\let\registerentry \defaultregisterentry -\let\registercharacter\defaultregistercharacter - -%D A few specific rendering variants: - -% \def\doregisterpagelocation#1#2% -% {\nextregisterpage -% \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}} - -% todo: \installregisterpagehandler - -\def\registerpagebuttonsymbol{\vrule\!!width1em\!!height1ex\!!depth\zeropoint\relax} - -\setvalue{\??id:\c!symbol :\c!n}{\def\registerpageseparatorsymbol{, }\let\registerpagenumberhandler\firstofoneargument} -\setvalue{\??id:\c!symbol :\c!a}{\def\registerpageseparatorsymbol{, }\let\registerpagenumberhandler\firstofoneargument} % now done via conversion -\setvalue{\??id:\c!symbol:\v!none}{\let\registerpageseparatorsymbol\empty\let\registerpagenumberhandler\gobbleoneargument} -\setvalue{\??id:\c!symbol :1}{\let\registerpageseparatorsymbol\space\def\registerpagenumberhandler{\symbol[1]\gobbleoneargument}} -\setvalue{\??id:\c!symbol :2}{\let\registerpageseparatorsymbol\space\def\registerpagenumberhandler{\registerpagebuttonsymbol\gobbleoneargument}} - -\def\setregisterpagerendering - {\edef\currentregisterpagesymbol{\registerparameter\c!symbol}% - \ifx\currentregisterpagesymbol\empty - \csname\??id:\c!symbol:\c!n\endcsname - \else\ifcsname\??id:\c!symbol:\currentregisterpagesymbol\endcsname - \csname\??id:\c!symbol:\currentregisterpagesymbol\endcsname - \else - \let\registerpageseparatorsymbol\space - \def\registerpagenumberhandle{\registerparameter\c!symbol\gobbleoneargument}% - \fi\fi} - -\appendtoks - \setregisterpagerendering -\to \everyplaceregister - -%D Don't use \type{\string#2}; another hack is needed, since -%D \type {#2} can be \type {\string} itself. -% -% \def\doregisterreference[#1]#2% -% {\doifsomething{#2} -% {\doif{\registerparameter\c!referencing}\v!on -% {\pagereference[#1:\strippedcsname#2]}}} - -% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % -% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % -% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - -%D The following code will be reimplemented (not that hard) when it's needed -%D again and/or when I'm bored. - -% \def\getalllistreferences#1#2% -% {\gdefconvertexpanded\currentregisterentry{\getvalue{\??id#1\c!expansion}}{#2}% -% \doifdefinedelse{\??id#1\??id\currentregisterentry} -% {\edef\alllistreferences% -% {\getvalue{\??id#1\??id\currentregisterentry}}% -% \beforesplitstring\alllistreferences\at::\to\internallistreference -% \aftersplitstring \alllistreferences\at::\to\alllistreferences} -% {\let\alllistreferences\empty -% \def\internallistreference{0}}} - -% \def\dosetlinkregister#1% is die page reference echt nodig? -% {\setregisterpage{#1}% -% \global\let\currentregisterentry\empty -% \global\firstsubentrytrue % not needed -% \global\firstsubsubentrytrue % not needed too -% \setvalue{#1\s!entrya}##1{\dosetlinkregisterentrya{#1}{##1}}% -% \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}} - -% \def\dosetlinkregisterentrya#1#2% -% {\global\utilitydonetrue -% \c!entryletter -% \iflocation -% \getalllistreferences{#1}{#2}% -% % no \endgraf -% \hangindent1em\noindent\c!entryreference -% % -% %\thisissomeinternal{\s!lin}{\internallistreference}% -% % -% \pagereference[-:\s!lin:\internallistreference]% -: added -% % -% \getcommacommandsize[\alllistreferences]% -% \getfromcommacommand[\alllistreferences][1]% -% \ifnum\commalistsize=1 -% \let\firstlistreference\empty -% \let\midlistreference\commalistelement -% \let\lastlistreference\empty -% \else -% \let\firstlistreference\commalistelement -% \getfromcommacommand[\alllistreferences][\commalistsize]% -% \let\lastlistreference\commalistelement -% \ifnum\commalistsize=2 -% \let\midlistreference\empty -% \else -% \!!counta\commalistsize -% \divide\!!counta 2 -% \getfromcommacommand[\alllistreferences][\!!counta]% -% \let\midlistreference\commalistelement -% \fi -% \fi -% % aangepast -% \def\dodocommand[##1-##2]% -% {\gotonextinternal{\s!ind}{##1}{##2}{\box0}}% -% \doifelsevalue{\??id#1\c!interaction}\v!pagenumber -% {\limitedregisterentry{#1}{#2}} % paginanummer -% {{\setbox0\hbox{\limitedregisterentry{#1}{\begstrut#2}}% -% \ifx\firstlistreference\empty % tekst,alles -% \ifx\midlistreference\empty -% \box0 -% \else -% \expandafter\dodocommand\expandafter[\midlistreference]% -% \fi -% \else -% \expandafter\dodocommand\expandafter[\firstlistreference]% -% \fi}}% -% \doifvalue{\??id#1\c!number}\v!yes -% {\hskip\getvalue{\??id#1\c!distance}(\commalistsize)}% -% \doifnotvalue{\??id#1\c!interaction}\v!text % paginanummer,alles -% {\def\docommand##1##2% -% {{\setbox0\hbox{\showlocation{\hbox to 1em{\hss\symbol[##2]\hss}}}% -% \ifx##1\empty -% % \hskip\wd0 % (optioneel maken) -% \else -% \expandafter\dodocommand\expandafter[##1]% -% \fi}}% -% \hskip\getvalue{\??id#1\c!distance}% -% \docommand\firstlistreference\v!previous -% \docommand\midlistreference\v!somewhere -% \docommand\lastlistreference\v!next}% -% % tot hier -% \else -% % no \endgraf -% \noindent\c!entryreference -% \limitedregisterentry{#1}{#2}% -% \fi -% \endgraf} - -% \def\dosetregister#1% -% {\doifelsevalue{\??id#1\c!coupling}\v!yes -% {\ifautoregisterhack -% \dosetautoregister{#1}% -% \else -% \dosetlinkregister{#1}% -% \fi} -% {\dosetpageregister{#1}}} - -\def\dosetregister#1% - {\dosetpageregister{#1}} - -% \newcounter\internallistreference - -% \def\doloadregisterlinks#1% -% {\setregisterpage{#1}% -% \global\let\currentregisterentry\empty -% \global\firstregisterpagetrue -% \setvalue{#1\s!entrya}##1% -% {\global\firstregisterpagetrue -% \gdefconvertedargument\currentregisterentry{##1}% global nodig? -% \doglobal\increment\internallistreference}% -% \setvalue{#1\s!from}% -% {\getvalue{#1\s!page}}% -% \ifautoregisterhack -% \setvalue{#1\s!page}##1##2##3##4% -% {\doifreglevelelse[##3] -% {\global\utilitydonetrue -% \iffirstregisterpage -% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname -% {\internallistreference::##4}% -% \else % catches errors in index -% \ifcsname\??id#1\??id\currentregisterentry\endcsname -% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname -% {\csname\??id#1\??id\currentregisterentry\endcsname,##4}% -% \fi -% \fi} -% {}}% -% \else -% \setvalue{#1\s!page}##1##2##3##4% -% {\doifreglevelelse[##3] -% {\global\utilitydonetrue -% \iffirstregisterpage -% \global\firstregisterpagefalse -% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname -% {\internallistreference::##2-##4}% -% \else % catches errors in index -% \ifcsname\??id#1\??id\currentregisterentry\endcsname -% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname -% {\csname\??id#1\??id\currentregisterentry\endcsname,##2-##4}% -% \fi -% \fi} -% {}}% -% \fi} - -% \def\docoupleregister[#1][#2]% -% {\iflocation -% \ifcase0\countervalue{autolink:#1}\relax % only once -% \begingroup -% \let\dosetregister\doloadregisterlinks -% \def\currentregister{#1}% -% \setupregister[#1][#2]% -% \mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister -% \endgroup -% \ifautoregisterhack -% \doinitializeautoregister{#1}% -% \else -% \doinitializelinkregister{#1}% -% \fi -% \fi -% \fi} - -% \def\coupleregister -% {\dodoubleempty\docoupleregister} - -% \def\dodocommandprolinrefAA[#1-#2]% -% {\def\lastlistreference{#1-#2}} - -% \def\dodocommandprolinrefA[#1-#2]% -% {\def\lastlistreference{#1-#2}% -% \ifx\firstlistreference\empty -% \let\firstlistreference\lastlistreference -% \fi -% \ifnum#1<\nextinternalreference\relax -% \let\prevlistreference\lastlistreference -% \else\ifnum#1>\nextinternalreference\relax -% \let\nextlistreference\lastlistreference -% \let\dodocommandprolinrefA\dodocommandprolinrefAA -% \else -% \let\selflistreference\lastlistreference -% \fi\fi} - -% \def\docommandprolinrefA#1% -% {\dodocommandprolinrefA[#1]} - -% \def\dodocommandprolinrefB[#1-#2]% -% {\gotonextinternal{\s!ind}{#1}{#2}{\box0}} - -% \def\docommandprolinrefB#1#2#3% -% {\bgroup -% \ifx#2\empty -% \doifvalue{\??id#1\c!unknownreference}\v!empty{\hskip1em}% -% \else -% \setbox0\hbox to 1em{\hss\showlocation{\symbol[#3]}\hss}% -% \expandafter\dodocommandprolinrefB\expandafter[#2]% -% \fi -% \egroup} - -% \def\doprocesslinkregister[#1][#2]#3% -% {\hbox -% {\doprocesspageregister{}{#2}{}{#3}% -% \let\firstlistreference\empty -% \let\lastlistreference\empty -% \let\selflistreference\empty -% \let\prevlistreference\empty -% \let\nextlistreference\empty -% \getalllistreferences{#1}{#3}% -% \ifx\alllistreferences\empty \else -% \normalexpanded{\noexpand\rawprocesscommalist[\alllistreferences]}\docommandprolinrefA -% \fi -% \ifx\prevlistreference\empty -% \let\prevlistreference\lastlistreference -% \fi -% \ifx\nextlistreference\empty -% \let\nextlistreference\firstlistreference -% \fi -% \ifx\prevlistreference\selflistreference -% \let\prevlistreference\empty -% \let\nextlistreference\empty -% \fi -% \setalignmentswitch{\getvalue{\??id#1\c!location}}% -% \ifcase\alignmentswitch -% % links -% \docommandprolinrefB{#1}\prevlistreference\v!previous -% \docommandprolinrefB{#1}\nextlistreference\v!next -% \or -% % midden -% \docommandprolinrefB{#1}\prevlistreference\v!previous -% \or -% % rechts -% \fi -% \doifreferencefoundelse{\s!lin:\internallistreference} -% {\gotosomeinternal -% \s!lin \internallistreference \currentrealreference -% {\showlocation{\limitedregisterentry{#1}{#3}}}} -% {\hbox{\limitedregisterentry{#1}{#3}}}% -% \ifcase\alignmentswitch -% % links -% \or -% % midden -% \docommandprolinrefB{#1}\nextlistreference\v!next -% \or -% % rechts -% \docommandprolinrefB{#1}\prevlistreference\v!previous -% \docommandprolinrefB{#1}\nextlistreference\v!next -% \fi}} - -% \def\doprocesslinkedregister[#1][#2]#3% page auto link -% {\bgroup -% \chardef\registerpagestatus\plusone -% \def\currentregister{#1}% -% \iflocation % \next is not needed -% \ifautoregisterhack -% \def\next{\doprocessautoregister[#1][#2]}% -% \else -% \def\next{\doprocesslinkregister[#1][#2]}% -% \fi -% \else -% \def\next{\doprocesspageregister{}{#2}{}}% -% \fi -% \next{#3}% -% \egroup} - -% \def\dodolinkedregister[#1][#2]#3% page auto link -% {\doflushatpar{\doprocesslinkedregister[#1][#2]{#3}}} - -% \def\dolinkedregister#1% -% {\dodoubleempty\dodolinkedregister[#1]} - -% \def\dosetautoregister#1% -% {\makecounter{autolink:#1}% -% \setregisterpage{#1}% -% \global\let\currentregisterentry\empty -% \global\firstsubentrytrue % not needed -% \global\firstsubsubentrytrue % not needed too -% \setvalue{#1\s!entrya}##1{\dosetautoregisterentrya{#1}{##1}}% -% \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}} - -% \def\dosetautoregisterentrya#1#2% -% {\global\utilitydonetrue -% \c!entryletter -% \iflocation -% \getalllistreferences{#1}{#2}% -% \endgraf\hangindent1em\noindent\c!entryreference -% \pagereference[-:\s!lin:\internallistreference]% -% \pluscounter{autolink:#1}% -% \bgroup -% %\setupinteraction[\c!color=,\c!contrastcolor=,\c!style=]% kan sneller -% \resetinteractionparameter\c!color -% \resetinteractionparameter\c!contrastcolor -% \resetinteractionparameter\c!style -% \gotobox -% {\limitedregisterentry{#1}{\begstrut#2}}% -% [JS(SetRegisterEntry{\v!register,\countervalue{autolink:#1},#2,{\alllistreferences}})]% -% \egroup -% \else -% \endgraf\noindent\c!entryreference -% \limitedregisterentry{#1}{#2}% -% \fi} - -% \def\doprocessautoregister[#1][#2]#3% -% {\hbox -% {\doprocesspageregister{}{#2}{}{#3}% -% \doifreferencefoundelse{\s!lin:\internallistreference} -% {\gotosomeinternal \s!lin -% {\internallistreference}{\currentrealreference} -% {\showlocation{\limitedregisterentry{#1}{#3}}}} -% {\hbox{\limitedregisterentry{#1}{#3}}}}} - -% \appendmacro aan openpaginaactie (in shipout) - -%D The first implementation used one main field with clones. -%D In a 2500 page document this resulted in a rather (anoying) -%D long start||up time. This \quote {every page its own field} -%D solution, combined with a \quote {page open action}, works -%D much faster, but is conceptually pretty weak. - -% \def\complexregisterfield[#1]% -% {\definefield[#1:\realfolio][line][\v!register]% -% \field[#1:\realfolio]} - -% \def\simpleregisterfield -% {\complexregisterfield[\v!register]} - -% \definecomplexorsimple\registerfield - -% \appendtoks -% % for now -% \setupfield -% [\v!register] -% [\c!width=10em, -% \c!height=3ex, -% \c!align=\v!middle, -% \c!option=\v!readonly, -% \c!location=\v!low] -% \to \everydump - -% \def\doinitializeautoregister#1% -% {\useJSscripts[reg]% -% \useJSpreamblenow{LinkedRegisters}% -% \setupinteraction[\c!openpageaction=JS(UpdateRegisterField{\v!register})]% -% \definereference[\v!reset\v!register][JS(ResetRegisterEntry{\v!register})]% -% \definereference[\v!first\v!register][JS(GotoFirstRegisterEntry{\v!register})]% -% \definereference[\v!previous\v!register][JS(GotoPreviousRegisterEntry{\v!register})]% -% \definereference[\v!next\v!register][JS(GotoNextRegisterEntry{\v!register})]% -% \definereference[\v!last\v!register][JS(GotoLastRegisterEntry{\v!register})]} - -% \def\doinitializelinkregister#1% -% {} - -% todo ruwe register - -%D Default index: - -\defineregister - [\v!index] - [\v!indices] - -% \setupregister[index][koppeling=ja] -% -% \stelveldenin -% [register][achtergrond=raster,kader=uit] -% -% \stelvoettekstenin -% [{\field[index]}] -% -% \stelhoofdtekstenin -% [{\naar {first}[eersteindex]\quad -% \naar{previous}[vorigeindex]\quad -% \naar {next}[volgendeindex]\quad -% \naar {last}[laatsteindex]\quad\quad -% \naar {index}[index]}] -% -% \starttekst -% -% oeps~~~\gekoppeldeindex{oeps} \blanko -% flop~~~\gekoppeldeindex{flop} \blanko -% test~~~\gekoppeldeindex{test} \pagina -% flop~~~\gekoppeldeindex{flop} \blanko -% test~~~\gekoppeldeindex{test} \pagina -% oeps~~~\gekoppeldeindex{oeps} \blanko -% test~~~\gekoppeldeindex{test} \pagina -% flop~~~\gekoppeldeindex{flop} \blanko -% oeps~~~\gekoppeldeindex{oeps} \pagina -% -% \volledigeindex - -\protect \endinput diff --git a/tex/context/base/strc-ren.mkiv b/tex/context/base/strc-ren.mkiv new file mode 100644 index 000000000..c2b8ffd83 --- /dev/null +++ b/tex/context/base/strc-ren.mkiv @@ -0,0 +1,467 @@ +%D \module +%D [ file=strc-ren, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Section Rendering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Section Rendering} + +\unprotect + +\chardef\headtimingmode=0 + +% \chardef\headtimingmode=1 % 0 also works ok now too +% +% Martin Kolarik's problem: +% +% \setuphead[section][command=\doTitle] +% \def\doTitle#1#2{\ruledvbox{\forgetall \hsize=4cm \ruledhbox{\ruledvtop{#1}\ruledvtop{#2}}}} +% \section{test test test test test test test test test test test test test test test test test} + +\newevery \everyheadstart \relax + +\def\placeheadmargintexts + {\the\everyheadstart + \doif{\structureheadparameter\c!margintext}\v!yes\placemargincontent} + +\def\doplaceheadtextcomponent#1#2% + {\begingroup + \dosetstructureheadattributes\c!style\c!color + \dosetstructureheadattributes\c!textstyle\c!textcolor + \dontconvertfont + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \setupinterlinespace + \else + \setupspacing + \fi + % \ifcase\headtimingmode#1\fi % can introduce cr + \structureheadparameter\c!commandbefore + \placeheadmargintexts + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \structureheadparameter\c!textcommand% struts can be nilled with \setnostrut + {\setstrut + \begstrut + \ifcase\headtimingmode\hbox{#1}\fi + \executeifdefined{\??nh\currentstructurehead\c!deeptextcommand}\firstofoneargument{#2}% + \endstrut}% \hbox prevents break + \xdef\localheadheight {\the\strutht}% + \xdef\localheaddepth {\the\strutdp}% + \xdef\localheadlineheight{\the\lineheight}% + % == \globallet\localheaddepth\strutdepth + \else + \ifcase\headtimingmode#1\fi + \structureheadparameter\c!textcommand + {\executeifdefined{\??nh\currentstructurehead\c!deeptextcommand}\firstofoneargument{#2}}% + \fi + \structureheadparameter\c!commandafter + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \endgraf + \fi + \endgroup} + +\def\doplaceheadnumbercomponent#1#2% + {\begingroup + \dosetstructureheadattributes\c!style\c!color + \dosetstructureheadattributes\c!numberstyle\c!numbercolor + % \getvalue{\??ko\currentstructurehead\c!commandbefore}% strange, why here? moved 21/11/2005 + \placeheadmargintexts + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + % can be nilled with \setnostrut + \structureheadparameter\c!numbercommand + {\setstrut + \begstrut + \executeifdefined{\??nh\currentstructurehead\c!deepnumbercommand}\firstofoneargument{#2}% + \endstrut}% + \else + \structureheadparameter\c!numbercommand + {\executeifdefined{\??nh\currentstructurehead\c!deepnumbercommand}\firstofoneargument{#2}}% + \fi + \endgroup} + +% \newif\ifheadnumbercontent +% \newif\ifemptyhead +% \newif\ifdisplaysectionhead + +\def\doplacestructureheadtext#1#2#3% nodes, text, endstuff + {\beginheadplacement +\postponenotes + \doresettructureheadnumbercontent + \ifconditional\structureheadleaveempty % \ifemptyhead + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi to \zeropoint{#1}% + \makestrutofbox\sectionheadbox + \else + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi + {\doresettructureheadnumbercontent + \ifcase\headtimingmode\or#1\fi % outerside font determines distance + \dosetfontattribute{\??nh\currentstructurehead}\c!style % but we don't want color to influence user command, todo: get the if-else out of it + \structureheadparameter\c!command{}{\doplaceheadtextcomponent{#1}{#2}}}% + \fi + \endheadplacement{#3}} + +\def\doplacestructureheadnumbertext#1#2#3#4% nodes number text nodes + {\beginheadplacement +\postponenotes + \doiftextelse{#2}\dosettructureheadnumbercontent\doresettructureheadnumbercontent + \ifconditional\structureheadleaveempty % \ifemptyhead % = needed + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi to \zeropoint{#1}% + \makestrutofbox\sectionheadbox + \else % = needed + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi + {\ifcase\headtimingmode\or#1\fi + \dosetfontattribute{\??nh\currentstructurehead}\c!style + \structureheadparameter\c!command{\doplaceheadnumbercomponent{#1}{#2}}{\doplaceheadtextcomponent{#1}{#3}}}% + \fi + \endheadplacement{#4}} + +\def\placestructureheadnumbertext + {\doplacestructureheadnumbertext\empty\getstructureheadnumber\getstructureheadtitle\getstructureheadsyncs} + +\def\placestructureheadtext + {\doplacestructureheadtext\empty\getstructureheadtitle\getstructureheadsyncs} + +\def\placestructureheadnothing + {\getstructureheadsyncs} + +%D \starttyping +%D \def\StretchedBox#1% +%D {\framed +%D [frame=off,offset=.5em,align=middle,width=broad] +%D {\sc\def\stretchedspaceamount{.3em}\stretchednormalcase{#1}}} +%D +%D \definehead[MySubject][subject] +%D \setuphead [MySubject][deeptextcommand=\StretchedBox] +%D +%D \MySubject{feeling stretched feeling stretched feeling stretched feeling stretched} +%D \stoptyping + +\let\headlastlinewidth\!!zeropoint + +\def\localheadheight {\strutht} +\def\localheaddepth {\strutdp} +\def\localheadlineheight{\lineheight} + +\def\dolocalheadsetup % koppeling met standaard kopcommando / engels + {\forgetall % traag dus ... + \doifsomething{\structureheadparameter\c!align } {\normalexpanded{\noexpand\setupalign [\structureheadparameter\c!align ]}}% + \doifsomething{\structureheadparameter\c!tolerance} {\normalexpanded{\noexpand\setuptolerance[\structureheadparameter\c!tolerance]}}% + \doif {\structureheadparameter\c!strut }\v!no{\setnostrut}% new + \def\\{\crlf\strut\ignorespaces}} + +\def\beginheadplacement + {\bgroup + \setsystemmode\currentstructurehead + \ifgridsnapping\iftracegridsnapping\showstruts\fi\fi + \xdef\localheadheight {\the\strutht}% + \xdef\localheaddepth {\the\strutdp}% + \xdef\localheadlineheight{\the\lineheight}% + % == \globallet\localheaddepth\strutdp + \everypar\emptytoks % needed indeed + \noindent % ipv \whitespace elders, na \forgetall ! + \bgroup + \doifinsetelse{\structureheadparameter\c!aligntitle}{\v!yes,\v!float}% new + {\skip0 1\leftskip + \skip2 1\rightskip + \xdef\localheadskip{\the\skip0}% + \forgetall + \leftskip\skip0 + \rightskip\skip2 + \setlocalhsize\hsize\localhsize + \forgetbothskips} + {\globallet\localheadskip\!!zeropoint + \forgetall}% + \dontcomplain + \postponenotes + \iflocation + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \else + \noninterferingmarks + \fi + \fi + \resetinteractionparameter\c!style + \resetinteractionparameter\c!color + \resetinteractionparameter\c!contrastcolor + %\strictouterreferencestrue % tzt instelling + \let\localheadsetup\dolocalheadsetup + \startsynchronization} + +% \setuphead[chapter] [style=\bfd,after=,hang=line] % fit broad 2 +% \setuphead[section] [style=\bfc,after=,hang=line] +% \setuphead[subsection] [style=\bfb,after=,hang=line] +% \setuphead[subsubsection] [style=\bfa,after=,hang=line] +% \setuphead[subsubsubsection][style=\bf ,after=,hang=line] +% +% \chapter {Test} \input tufte \page +% \section {Test} \input tufte \page +% \subsection {Test} \input tufte \page +% \subsubsection {Test} \input tufte \page +% \subsubsubsection{Test} \input tufte \page +% +% \chapter {Test\\Test} \input tufte \page +% \section {Test\\Test} \input tufte \page +% \subsection {Test\\Test} \input tufte \page +% \subsubsection {Test\\Test} \input tufte \page +% \subsubsubsection{Test\\Test} \input tufte \page + +\def\hangheadplacement + {\scratchdimen\localheadlineheight + \bgroup + \openlineheight\scratchdimen + \scratchdimen\htdp0% + \getnoflines\scratchdimen + \advance\noflines\minusone + \normalexpanded{\egroup\noflines\the\noflines}% brrr + \setbox0\hbox{\lower\noflines\scratchdimen\box0}% + \scratchdimen\dimexpr\htdp0-\localheadheight+\strutdp\relax + \ht0 \strutht + \dp0 \strutdp + \edef\localheaddepth{\the\strutdp}} + +\newconditional\continuoussectionhead % oeps, \newif\ifcontinuoushead got lost +\newbox\sectionheadbox + +\def\endheadplacement#1% + {\doifelse{\structureheadparameter\c!state}\v!start + {\doifnothing{\structureheadparameter\c!file}{\autocrossdocumentfalse}} + {\autocrossdocumentfalse}% + % no message needed here, should be a proper switch + \noflines\zerocount + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + % new (tod tight == one following line up) + \processaction + [\structureheadparameter\c!hang] + [ \v!line=>\hangheadplacement\noflines\zerocount, + \v!broad=>\hangheadplacement\getnoflines\scratchdimen, + \v!fit=>\hangheadplacement\getrawnoflines\scratchdimen, + \v!none=>\noflines\zerocount, + \v!default=>\noflines\zerocount, + \v!unknown=>\hangheadplacement\noflines\numexpr0\commalistelement-1\relax]% + % so far + \let\headlastlinewidth\!!zeropoint + \snaptogrid[\structureheadparameter\c!grid]\hbox + {\hskip\localheadskip + \hskip\structureheadparameter\c!margin\relax + \iflocation +% \ifautocrossdocument +% \doifreferencefoundelse{\structureheadparameter\c!file::\currentstructurehead} +% {\edef\currentinnerreference{\s!aut:\currenttextreference}% stored in +% \gotoouterlocation{}{\box\sectionheadbox}} % text slot +% {\hbox{\box\sectionheadbox}}% +% \else + \hbox{\box\sectionheadbox}% +% \fi + \else + \hbox{\box\sectionheadbox}% + \fi}% + \doflushnotes % new, not really needed + \endgraf + \ifvmode + \ifnum\noflines>\zerocount + \dorecurse\noflines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}% to be checked + \fi + \nointerlineskip + \dosomebreak\nobreak + \fi + #1% + \else + \strut + \doflushnotes % new, here since we're in par mode + \iflocation + \ifautocrossdocument + \hhboxindent=\ifconditional\continuoussectionhead\headlastlinewidth\else\zeropoint\fi + \unhhbox\sectionheadbox\with{\gotobox{\box\hhbox}[\structureheadparameter\c!file::\currentstructurehead]}% + \advance\lasthhboxwidth by \numberheaddistance + \xdef\headlastlinewidth{\the\lasthhboxwidth}% + \else + \unhbox\sectionheadbox + \globallet\headlastlinewidth\!!zeropoint + \fi + \else + \unhbox\sectionheadbox + \globallet\headlastlinewidth\!!zeropoint + \fi + #1% + \hskip\numberheaddistance\!!plus\numberheaddistance\!!minus.25\dimexpr\numberheaddistance\relax + \hskip\continuousstructureheadsignal\ignorespaces + \fi + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \ifvmode + \ifgridsnapping % important, font related depth, see comment + \prevdepth\strutdp + \else + \prevdepth\localheaddepth + \fi + \fi + \fi + \stopsynchronization + \egroup + \egroup + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \checknextindentation[\structureheadparameter\c!indentnext]% + \else + \nonoindentation % recently added, was a bug + \fi} + +% nice testcase +% +% \setupheads[aligntitle=yes] +% +% \startnarrower +% \subject{\dorecurse{100}{x }} +% \section{\dorecurse{100}{x }} +% \input tufte \par +% \setupheads[alternative=inmargin] +% \subject{\dorecurse{100}{x }} +% \section{\dorecurse{100}{x }} +% \input tufte \par +% \stopnarrower + +\let\numberheadalternative\v!normal + +\def\defineheadplacement + {\dodoubleargument\dodefineheadplacement} + +\def\dodefineheadplacement[#1][#2]% #3#4 + {\setvalue{\??ns:#1}{#2}% + \setvalue{\??ns::#1}} + +\def\normalplacehead + {\executeifdefined + {\??ns::\numberheadalternative} + {\getvalue{\??ns::\v!normal}}} + +\defineheadplacement[\v!paragraph][\v!vertical]#1#2% + {\vbox + {\localheadsetup + \begstrut + \ifconditional\structureheadshownumber % \ifheadnumbercontent + #1\hskip\numberheaddistance + \fi + #2}} + +% \defineheadplacement[\v!normal][\v!vertical]#1#2% +% {\ifconditional\structureheadshownumber % \ifheadnumbercontent +% \setbox0\hbox{{#1}\hskip\numberheaddistance}% +% \vbox +% {\localheadsetup +% \hangindent 1\wd0 +% \hangafter 1 +% \noindent +% \unhbox0 % don't use \strut's here! +% #2}% +% \else +% \vbox +% {\localheadsetup\noindent#2}% +% \fi} +% +% enhanced version: + +% \setuphead +% [chapter] +% [numberwidth=2cm,hang=line,after={\blank[3*line]}] +% +% \chapter{Oeps oeps oeps} \input tufte \section{Oeps} +% \chapter{Oeps oeps oeps} \section{Oeps} \input tufte + +\defineheadplacement[\v!normal][\v!vertical]#1#2% + {\vbox + {\localheadsetup + \edef\headwidth {\structureheadparameter\c!width }% + \edef\headnumberwidth{\structureheadparameter\c!numberwidth}% + \edef\headtextwidth {\structureheadparameter\c!textwidth }% + \ifconditional\structureheadshownumber % \ifheadnumbercontent + \ifx\headwidth\empty + \else + \ifx\headnumberwidth\empty + \ifx\headtextwidth\empty\else + \edef\headnumberwidth{\the\dimexpr\headwidth-\headtextwidth\relax}% + \fi + \else + \ifx\headtextwidth\empty + \edef\headtextwidth{\the\dimexpr\headwidth-\headnumberwidth\relax}% + \fi + \fi + \hsize\headwidth + \fi + \ifx\headnumberwidth\empty\else + \let\numberheaddistance\!!zeropoint + \fi + \setbox\scratchbox\hbox \ifx\headnumberwidth\empty\else to \headnumberwidth\fi{{#1}}% + \scratchdimen\dimexpr\wd\scratchbox+\numberheaddistance\relax + \ifx\headtextwidth\empty\else + \hsize\dimexpr\scratchdimen+\headparameter\c!textwidth\relax + \fi + \hangindent\scratchdimen + \hangafter \plusone + \noindent + \box\scratchbox\hskip\numberheaddistance + \else + \ifx\headtextwidth\empty + \ifx\headwidth\empty + \else + \hsize\headwidth + \fi + \else + \hsize\headtextwidth + \fi + \noindent + \fi + #2}} + +\def\placeheadmargin#1#2% + {\vbox + {\localheadsetup + \begstrut % use one \strut here! + \dontleavehmode % in case there is no strut, else side effects with llap + \ifconditional\structureheadshownumber % \ifheadnumbercontent + \llap{\hbox to 5em{\hfill{#1}\hskip\localheadskip\hskip\leftmargindistance}}% introduces whitespace + % maybe better: + % \inleftmargin{\hbox{\hss{#1}\hskip\localheadskip}}% + \fi + {#2}}} + +\defineheadplacement[\v!inmargin][\v!vertical]#1#2{\placeheadmargin{#1}{#2}} +\defineheadplacement[\v!margin] [\v!vertical]#1#2{\placeheadmargin{#1}{#2}} + +\defineheadplacement[\v!middle][\v!vertical]#1#2% + {\vbox + {\localheadsetup + \veryraggedcenter + \let\\\endgraf + \let\crlf\endgraf + \ifconditional\structureheadshownumber % \ifheadnumbercontent + \strut#1\par + \fi + \begstrut#2}} + +\defineheadplacement[\v!text][\v!horizontal]#1#2% + {\bgroup + \localheadsetup % no stretch in distance + \ifconditional\structureheadshownumber % \ifheadnumbercontent + {#1}\kern\numberheaddistance + \fi + {\begstrut#2}% + \egroup} + +\def\placeheadlohi#1#2#3% + {\ifconditional\structureheadshownumber % \ifheadnumbercontent + \setbox0\hbox{#2} + \setbox2=#1{\localheadsetup\advance\hsize-\wd0\relax#3}% + \hbox{\box0\hskip\numberheaddistance\box2}% + \else + #1{\localheadsetup\noindent#3}% + \fi} + +% onder/boven lijnt het nummer op de onderste/bovenste regel +% uit van een meerregelige kop + +\defineheadplacement[\v!bottom][\v!vertical]#1#2{\placeheadlohi\vbox{#1}{#2}} +\defineheadplacement[\v!top] [\v!vertical]#1#2{\placeheadlohi\vtop{#1}{#2}} + +\protect \endinput diff --git a/tex/context/base/strc-ren.tex b/tex/context/base/strc-ren.tex deleted file mode 100644 index c2b8ffd83..000000000 --- a/tex/context/base/strc-ren.tex +++ /dev/null @@ -1,467 +0,0 @@ -%D \module -%D [ file=strc-ren, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Section Rendering, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Section Rendering} - -\unprotect - -\chardef\headtimingmode=0 - -% \chardef\headtimingmode=1 % 0 also works ok now too -% -% Martin Kolarik's problem: -% -% \setuphead[section][command=\doTitle] -% \def\doTitle#1#2{\ruledvbox{\forgetall \hsize=4cm \ruledhbox{\ruledvtop{#1}\ruledvtop{#2}}}} -% \section{test test test test test test test test test test test test test test test test test} - -\newevery \everyheadstart \relax - -\def\placeheadmargintexts - {\the\everyheadstart - \doif{\structureheadparameter\c!margintext}\v!yes\placemargincontent} - -\def\doplaceheadtextcomponent#1#2% - {\begingroup - \dosetstructureheadattributes\c!style\c!color - \dosetstructureheadattributes\c!textstyle\c!textcolor - \dontconvertfont - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \setupinterlinespace - \else - \setupspacing - \fi - % \ifcase\headtimingmode#1\fi % can introduce cr - \structureheadparameter\c!commandbefore - \placeheadmargintexts - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \structureheadparameter\c!textcommand% struts can be nilled with \setnostrut - {\setstrut - \begstrut - \ifcase\headtimingmode\hbox{#1}\fi - \executeifdefined{\??nh\currentstructurehead\c!deeptextcommand}\firstofoneargument{#2}% - \endstrut}% \hbox prevents break - \xdef\localheadheight {\the\strutht}% - \xdef\localheaddepth {\the\strutdp}% - \xdef\localheadlineheight{\the\lineheight}% - % == \globallet\localheaddepth\strutdepth - \else - \ifcase\headtimingmode#1\fi - \structureheadparameter\c!textcommand - {\executeifdefined{\??nh\currentstructurehead\c!deeptextcommand}\firstofoneargument{#2}}% - \fi - \structureheadparameter\c!commandafter - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \endgraf - \fi - \endgroup} - -\def\doplaceheadnumbercomponent#1#2% - {\begingroup - \dosetstructureheadattributes\c!style\c!color - \dosetstructureheadattributes\c!numberstyle\c!numbercolor - % \getvalue{\??ko\currentstructurehead\c!commandbefore}% strange, why here? moved 21/11/2005 - \placeheadmargintexts - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - % can be nilled with \setnostrut - \structureheadparameter\c!numbercommand - {\setstrut - \begstrut - \executeifdefined{\??nh\currentstructurehead\c!deepnumbercommand}\firstofoneargument{#2}% - \endstrut}% - \else - \structureheadparameter\c!numbercommand - {\executeifdefined{\??nh\currentstructurehead\c!deepnumbercommand}\firstofoneargument{#2}}% - \fi - \endgroup} - -% \newif\ifheadnumbercontent -% \newif\ifemptyhead -% \newif\ifdisplaysectionhead - -\def\doplacestructureheadtext#1#2#3% nodes, text, endstuff - {\beginheadplacement -\postponenotes - \doresettructureheadnumbercontent - \ifconditional\structureheadleaveempty % \ifemptyhead - \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi to \zeropoint{#1}% - \makestrutofbox\sectionheadbox - \else - \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi - {\doresettructureheadnumbercontent - \ifcase\headtimingmode\or#1\fi % outerside font determines distance - \dosetfontattribute{\??nh\currentstructurehead}\c!style % but we don't want color to influence user command, todo: get the if-else out of it - \structureheadparameter\c!command{}{\doplaceheadtextcomponent{#1}{#2}}}% - \fi - \endheadplacement{#3}} - -\def\doplacestructureheadnumbertext#1#2#3#4% nodes number text nodes - {\beginheadplacement -\postponenotes - \doiftextelse{#2}\dosettructureheadnumbercontent\doresettructureheadnumbercontent - \ifconditional\structureheadleaveempty % \ifemptyhead % = needed - \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi to \zeropoint{#1}% - \makestrutofbox\sectionheadbox - \else % = needed - \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi - {\ifcase\headtimingmode\or#1\fi - \dosetfontattribute{\??nh\currentstructurehead}\c!style - \structureheadparameter\c!command{\doplaceheadnumbercomponent{#1}{#2}}{\doplaceheadtextcomponent{#1}{#3}}}% - \fi - \endheadplacement{#4}} - -\def\placestructureheadnumbertext - {\doplacestructureheadnumbertext\empty\getstructureheadnumber\getstructureheadtitle\getstructureheadsyncs} - -\def\placestructureheadtext - {\doplacestructureheadtext\empty\getstructureheadtitle\getstructureheadsyncs} - -\def\placestructureheadnothing - {\getstructureheadsyncs} - -%D \starttyping -%D \def\StretchedBox#1% -%D {\framed -%D [frame=off,offset=.5em,align=middle,width=broad] -%D {\sc\def\stretchedspaceamount{.3em}\stretchednormalcase{#1}}} -%D -%D \definehead[MySubject][subject] -%D \setuphead [MySubject][deeptextcommand=\StretchedBox] -%D -%D \MySubject{feeling stretched feeling stretched feeling stretched feeling stretched} -%D \stoptyping - -\let\headlastlinewidth\!!zeropoint - -\def\localheadheight {\strutht} -\def\localheaddepth {\strutdp} -\def\localheadlineheight{\lineheight} - -\def\dolocalheadsetup % koppeling met standaard kopcommando / engels - {\forgetall % traag dus ... - \doifsomething{\structureheadparameter\c!align } {\normalexpanded{\noexpand\setupalign [\structureheadparameter\c!align ]}}% - \doifsomething{\structureheadparameter\c!tolerance} {\normalexpanded{\noexpand\setuptolerance[\structureheadparameter\c!tolerance]}}% - \doif {\structureheadparameter\c!strut }\v!no{\setnostrut}% new - \def\\{\crlf\strut\ignorespaces}} - -\def\beginheadplacement - {\bgroup - \setsystemmode\currentstructurehead - \ifgridsnapping\iftracegridsnapping\showstruts\fi\fi - \xdef\localheadheight {\the\strutht}% - \xdef\localheaddepth {\the\strutdp}% - \xdef\localheadlineheight{\the\lineheight}% - % == \globallet\localheaddepth\strutdp - \everypar\emptytoks % needed indeed - \noindent % ipv \whitespace elders, na \forgetall ! - \bgroup - \doifinsetelse{\structureheadparameter\c!aligntitle}{\v!yes,\v!float}% new - {\skip0 1\leftskip - \skip2 1\rightskip - \xdef\localheadskip{\the\skip0}% - \forgetall - \leftskip\skip0 - \rightskip\skip2 - \setlocalhsize\hsize\localhsize - \forgetbothskips} - {\globallet\localheadskip\!!zeropoint - \forgetall}% - \dontcomplain - \postponenotes - \iflocation - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \else - \noninterferingmarks - \fi - \fi - \resetinteractionparameter\c!style - \resetinteractionparameter\c!color - \resetinteractionparameter\c!contrastcolor - %\strictouterreferencestrue % tzt instelling - \let\localheadsetup\dolocalheadsetup - \startsynchronization} - -% \setuphead[chapter] [style=\bfd,after=,hang=line] % fit broad 2 -% \setuphead[section] [style=\bfc,after=,hang=line] -% \setuphead[subsection] [style=\bfb,after=,hang=line] -% \setuphead[subsubsection] [style=\bfa,after=,hang=line] -% \setuphead[subsubsubsection][style=\bf ,after=,hang=line] -% -% \chapter {Test} \input tufte \page -% \section {Test} \input tufte \page -% \subsection {Test} \input tufte \page -% \subsubsection {Test} \input tufte \page -% \subsubsubsection{Test} \input tufte \page -% -% \chapter {Test\\Test} \input tufte \page -% \section {Test\\Test} \input tufte \page -% \subsection {Test\\Test} \input tufte \page -% \subsubsection {Test\\Test} \input tufte \page -% \subsubsubsection{Test\\Test} \input tufte \page - -\def\hangheadplacement - {\scratchdimen\localheadlineheight - \bgroup - \openlineheight\scratchdimen - \scratchdimen\htdp0% - \getnoflines\scratchdimen - \advance\noflines\minusone - \normalexpanded{\egroup\noflines\the\noflines}% brrr - \setbox0\hbox{\lower\noflines\scratchdimen\box0}% - \scratchdimen\dimexpr\htdp0-\localheadheight+\strutdp\relax - \ht0 \strutht - \dp0 \strutdp - \edef\localheaddepth{\the\strutdp}} - -\newconditional\continuoussectionhead % oeps, \newif\ifcontinuoushead got lost -\newbox\sectionheadbox - -\def\endheadplacement#1% - {\doifelse{\structureheadparameter\c!state}\v!start - {\doifnothing{\structureheadparameter\c!file}{\autocrossdocumentfalse}} - {\autocrossdocumentfalse}% - % no message needed here, should be a proper switch - \noflines\zerocount - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - % new (tod tight == one following line up) - \processaction - [\structureheadparameter\c!hang] - [ \v!line=>\hangheadplacement\noflines\zerocount, - \v!broad=>\hangheadplacement\getnoflines\scratchdimen, - \v!fit=>\hangheadplacement\getrawnoflines\scratchdimen, - \v!none=>\noflines\zerocount, - \v!default=>\noflines\zerocount, - \v!unknown=>\hangheadplacement\noflines\numexpr0\commalistelement-1\relax]% - % so far - \let\headlastlinewidth\!!zeropoint - \snaptogrid[\structureheadparameter\c!grid]\hbox - {\hskip\localheadskip - \hskip\structureheadparameter\c!margin\relax - \iflocation -% \ifautocrossdocument -% \doifreferencefoundelse{\structureheadparameter\c!file::\currentstructurehead} -% {\edef\currentinnerreference{\s!aut:\currenttextreference}% stored in -% \gotoouterlocation{}{\box\sectionheadbox}} % text slot -% {\hbox{\box\sectionheadbox}}% -% \else - \hbox{\box\sectionheadbox}% -% \fi - \else - \hbox{\box\sectionheadbox}% - \fi}% - \doflushnotes % new, not really needed - \endgraf - \ifvmode - \ifnum\noflines>\zerocount - \dorecurse\noflines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}% to be checked - \fi - \nointerlineskip - \dosomebreak\nobreak - \fi - #1% - \else - \strut - \doflushnotes % new, here since we're in par mode - \iflocation - \ifautocrossdocument - \hhboxindent=\ifconditional\continuoussectionhead\headlastlinewidth\else\zeropoint\fi - \unhhbox\sectionheadbox\with{\gotobox{\box\hhbox}[\structureheadparameter\c!file::\currentstructurehead]}% - \advance\lasthhboxwidth by \numberheaddistance - \xdef\headlastlinewidth{\the\lasthhboxwidth}% - \else - \unhbox\sectionheadbox - \globallet\headlastlinewidth\!!zeropoint - \fi - \else - \unhbox\sectionheadbox - \globallet\headlastlinewidth\!!zeropoint - \fi - #1% - \hskip\numberheaddistance\!!plus\numberheaddistance\!!minus.25\dimexpr\numberheaddistance\relax - \hskip\continuousstructureheadsignal\ignorespaces - \fi - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \ifvmode - \ifgridsnapping % important, font related depth, see comment - \prevdepth\strutdp - \else - \prevdepth\localheaddepth - \fi - \fi - \fi - \stopsynchronization - \egroup - \egroup - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \checknextindentation[\structureheadparameter\c!indentnext]% - \else - \nonoindentation % recently added, was a bug - \fi} - -% nice testcase -% -% \setupheads[aligntitle=yes] -% -% \startnarrower -% \subject{\dorecurse{100}{x }} -% \section{\dorecurse{100}{x }} -% \input tufte \par -% \setupheads[alternative=inmargin] -% \subject{\dorecurse{100}{x }} -% \section{\dorecurse{100}{x }} -% \input tufte \par -% \stopnarrower - -\let\numberheadalternative\v!normal - -\def\defineheadplacement - {\dodoubleargument\dodefineheadplacement} - -\def\dodefineheadplacement[#1][#2]% #3#4 - {\setvalue{\??ns:#1}{#2}% - \setvalue{\??ns::#1}} - -\def\normalplacehead - {\executeifdefined - {\??ns::\numberheadalternative} - {\getvalue{\??ns::\v!normal}}} - -\defineheadplacement[\v!paragraph][\v!vertical]#1#2% - {\vbox - {\localheadsetup - \begstrut - \ifconditional\structureheadshownumber % \ifheadnumbercontent - #1\hskip\numberheaddistance - \fi - #2}} - -% \defineheadplacement[\v!normal][\v!vertical]#1#2% -% {\ifconditional\structureheadshownumber % \ifheadnumbercontent -% \setbox0\hbox{{#1}\hskip\numberheaddistance}% -% \vbox -% {\localheadsetup -% \hangindent 1\wd0 -% \hangafter 1 -% \noindent -% \unhbox0 % don't use \strut's here! -% #2}% -% \else -% \vbox -% {\localheadsetup\noindent#2}% -% \fi} -% -% enhanced version: - -% \setuphead -% [chapter] -% [numberwidth=2cm,hang=line,after={\blank[3*line]}] -% -% \chapter{Oeps oeps oeps} \input tufte \section{Oeps} -% \chapter{Oeps oeps oeps} \section{Oeps} \input tufte - -\defineheadplacement[\v!normal][\v!vertical]#1#2% - {\vbox - {\localheadsetup - \edef\headwidth {\structureheadparameter\c!width }% - \edef\headnumberwidth{\structureheadparameter\c!numberwidth}% - \edef\headtextwidth {\structureheadparameter\c!textwidth }% - \ifconditional\structureheadshownumber % \ifheadnumbercontent - \ifx\headwidth\empty - \else - \ifx\headnumberwidth\empty - \ifx\headtextwidth\empty\else - \edef\headnumberwidth{\the\dimexpr\headwidth-\headtextwidth\relax}% - \fi - \else - \ifx\headtextwidth\empty - \edef\headtextwidth{\the\dimexpr\headwidth-\headnumberwidth\relax}% - \fi - \fi - \hsize\headwidth - \fi - \ifx\headnumberwidth\empty\else - \let\numberheaddistance\!!zeropoint - \fi - \setbox\scratchbox\hbox \ifx\headnumberwidth\empty\else to \headnumberwidth\fi{{#1}}% - \scratchdimen\dimexpr\wd\scratchbox+\numberheaddistance\relax - \ifx\headtextwidth\empty\else - \hsize\dimexpr\scratchdimen+\headparameter\c!textwidth\relax - \fi - \hangindent\scratchdimen - \hangafter \plusone - \noindent - \box\scratchbox\hskip\numberheaddistance - \else - \ifx\headtextwidth\empty - \ifx\headwidth\empty - \else - \hsize\headwidth - \fi - \else - \hsize\headtextwidth - \fi - \noindent - \fi - #2}} - -\def\placeheadmargin#1#2% - {\vbox - {\localheadsetup - \begstrut % use one \strut here! - \dontleavehmode % in case there is no strut, else side effects with llap - \ifconditional\structureheadshownumber % \ifheadnumbercontent - \llap{\hbox to 5em{\hfill{#1}\hskip\localheadskip\hskip\leftmargindistance}}% introduces whitespace - % maybe better: - % \inleftmargin{\hbox{\hss{#1}\hskip\localheadskip}}% - \fi - {#2}}} - -\defineheadplacement[\v!inmargin][\v!vertical]#1#2{\placeheadmargin{#1}{#2}} -\defineheadplacement[\v!margin] [\v!vertical]#1#2{\placeheadmargin{#1}{#2}} - -\defineheadplacement[\v!middle][\v!vertical]#1#2% - {\vbox - {\localheadsetup - \veryraggedcenter - \let\\\endgraf - \let\crlf\endgraf - \ifconditional\structureheadshownumber % \ifheadnumbercontent - \strut#1\par - \fi - \begstrut#2}} - -\defineheadplacement[\v!text][\v!horizontal]#1#2% - {\bgroup - \localheadsetup % no stretch in distance - \ifconditional\structureheadshownumber % \ifheadnumbercontent - {#1}\kern\numberheaddistance - \fi - {\begstrut#2}% - \egroup} - -\def\placeheadlohi#1#2#3% - {\ifconditional\structureheadshownumber % \ifheadnumbercontent - \setbox0\hbox{#2} - \setbox2=#1{\localheadsetup\advance\hsize-\wd0\relax#3}% - \hbox{\box0\hskip\numberheaddistance\box2}% - \else - #1{\localheadsetup\noindent#3}% - \fi} - -% onder/boven lijnt het nummer op de onderste/bovenste regel -% uit van een meerregelige kop - -\defineheadplacement[\v!bottom][\v!vertical]#1#2{\placeheadlohi\vbox{#1}{#2}} -\defineheadplacement[\v!top] [\v!vertical]#1#2{\placeheadlohi\vtop{#1}{#2}} - -\protect \endinput diff --git a/tex/context/base/strc-sbe.mkiv b/tex/context/base/strc-sbe.mkiv new file mode 100644 index 000000000..de7c2af63 --- /dev/null +++ b/tex/context/base/strc-sbe.mkiv @@ -0,0 +1,137 @@ +%D \module +%D [ file=strc-sbe, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Section Block Environments, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Section Block Environments} + +\unprotect + +% \def\ChapterEntry#1#2#3% +% {chapter : \hbox to \hsize{\strut\bf#2\hss#3}\endgraf\placelist[section]} +% +% \startfrontmatter % optional +% \placelist[chapter][alternative=command,command=\ChapterEntry,criterium=text] \page +% \stopfrontmatter % optional +% +% \startbodymatter % optional +% \chapter{first} \section{one} test \section{two} test \page +% \chapter{second} \section{alpha} test \section{beta} test \page +% \stopbodymatter % optional + +\definesystemvariable {nb} + +\def\v!structureblockenvironment{structureblockenvironment} + +\def\definestructureblock{\dotripleargument\dodefinestructureblock} +\def\setupstructureblock {\dodoubleargument\dosetupstructureblock} +\def\setstructureblock {\dosingleargument\dosetstructureblock} + +% \def\structureblockparameter#1{\executeifdefined{\??nb\currentstructureblock#1}\empty} + +\def\structureblockparameter#1% + {\csname + \ifcsname\??nb\currentstructureblock#1\endcsname\??nb\currentstructureblock#1\else\s!empty\fi + \endcsname} + +\newtoks \everybeforestructureblock +\newtoks \everyafterstructureblock + +\def\dodefinestructureblock[#1][#2][#3]% singular plural settings + {\getparameters + [\??nb#1] + [\c!number=\v!yes, + \c!page=\v!right, % anders worden marks te vroeg gereset ! + #3]% + \expandafter\newif\csname if#2\endcsname % better a mode + \setstructureblockenvironment{#1}\empty + \setvalue {\e!start#2}{\startstructureblock[#1]}% + \setvalue {\e!stop #2}{\stopstructureblock}} + +\appendtoks + \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}% +% TODO \resetsectionmarks\zerosection + \getstructureblockenvironment\currentstructureblock + \structureblockparameter\c!before % don't move +\to \everybeforestructureblock + +\appendtoks + \structureblockparameter\c!after % don't move + \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}% +% TODO \resetsectionmarks\zerosection +\to \everyafterstructureblock + +\def\dosetupstructureblock[#1]% + {\getparameters[\??nb#1]}% [#2] + +\def\dosetstructureblock[#1]% used to set the default + {\edef\currentstructureblock{\ctxlua{structure.sections.setblock("#1")}}} + +\let\currentstructureblock\s!unknown + +\def\startstructureblock[#1]% + {\begingroup + \edef\currentstructureblock{\ctxlua{structure.sections.pushblock("#1")}}% + \csname #1true\endcsname % for old times sake + \setsystemmode\currentstructureblock + \the\everybeforestructureblock\relax + \showmessage\m!structures1\currentstructureblock} + +\def\stopstructureblock + {\showmessage\m!structures2\currentstructureblock + \the\everyafterstructureblock\relax + \edef\currentstructureblock{\ctxlua{structure.sections.popblock()}}% + \endgroup} + +\long\def\setstructureblockenvironment#1#2% + {\long\setvalue{\??nb\s!do#1}{\do{#2}}} + +\def\getstructureblockenvironment#1% + {\let\do\firstofoneargument + \structureblockparameter{\s!do#1}} + +%D \starttyping +%D \startsectionblockenvironment[frontpart] +%D \setuppagenumbering[conversion=romannumerals] +%D \stopsectionblockenvironment +%D +%D \startsectionblockenvironment[bodypart] +%D \setuppagenumber[number=1] +%D \stopsectionblockenvironment +%D +%D \startsectionblockenvironment[frontpart] +%D \setuppagenumbering[conversion=character] +%D \stopsectionblockenvironment +%D +%D \starttext +%D \startfrontmatter \chapter{test} \stopfrontmatter +%D \startbodymatter \chapter{test} \stopbodymatter +%D \startappendices \chapter{test} \stopappendices +%D \stoptext +%D \stoptyping + +\setvalue{\e!start\v!structureblockenvironment}% + {\dosingleargument\dostartstructureblockenvironment} + +\def\dostartstructureblockenvironment[#1]% evt \pushendofline \popendofline + {\long\def\do##1##2{\setstructureblockenvironment{#1}{##1##2}}% + \grabuntil{\e!stop\v!structureblockenvironment}{\structureblockparameter{\s!do#1}}} + +% this will become: (we ran in parallel for a while during transition) + +\setvalue{\e!start\v!sectionblockenvironment}% + {\dosingleargument\dostartsectionblockenvironment} + +\def\dostartsectionblockenvironment[#1]% evt \pushendofline \popendofline + {\long\def\do##1##2{\setstructureblockenvironment{#1}{##1##2}}% + \grabuntil{\e!stop\v!sectionblockenvironment}{\structureblockparameter{\s!do#1}}} + +\protect \endinput diff --git a/tex/context/base/strc-sbe.tex b/tex/context/base/strc-sbe.tex deleted file mode 100644 index de7c2af63..000000000 --- a/tex/context/base/strc-sbe.tex +++ /dev/null @@ -1,137 +0,0 @@ -%D \module -%D [ file=strc-sbe, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Section Block Environments, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Section Block Environments} - -\unprotect - -% \def\ChapterEntry#1#2#3% -% {chapter : \hbox to \hsize{\strut\bf#2\hss#3}\endgraf\placelist[section]} -% -% \startfrontmatter % optional -% \placelist[chapter][alternative=command,command=\ChapterEntry,criterium=text] \page -% \stopfrontmatter % optional -% -% \startbodymatter % optional -% \chapter{first} \section{one} test \section{two} test \page -% \chapter{second} \section{alpha} test \section{beta} test \page -% \stopbodymatter % optional - -\definesystemvariable {nb} - -\def\v!structureblockenvironment{structureblockenvironment} - -\def\definestructureblock{\dotripleargument\dodefinestructureblock} -\def\setupstructureblock {\dodoubleargument\dosetupstructureblock} -\def\setstructureblock {\dosingleargument\dosetstructureblock} - -% \def\structureblockparameter#1{\executeifdefined{\??nb\currentstructureblock#1}\empty} - -\def\structureblockparameter#1% - {\csname - \ifcsname\??nb\currentstructureblock#1\endcsname\??nb\currentstructureblock#1\else\s!empty\fi - \endcsname} - -\newtoks \everybeforestructureblock -\newtoks \everyafterstructureblock - -\def\dodefinestructureblock[#1][#2][#3]% singular plural settings - {\getparameters - [\??nb#1] - [\c!number=\v!yes, - \c!page=\v!right, % anders worden marks te vroeg gereset ! - #3]% - \expandafter\newif\csname if#2\endcsname % better a mode - \setstructureblockenvironment{#1}\empty - \setvalue {\e!start#2}{\startstructureblock[#1]}% - \setvalue {\e!stop #2}{\stopstructureblock}} - -\appendtoks - \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}% -% TODO \resetsectionmarks\zerosection - \getstructureblockenvironment\currentstructureblock - \structureblockparameter\c!before % don't move -\to \everybeforestructureblock - -\appendtoks - \structureblockparameter\c!after % don't move - \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}% -% TODO \resetsectionmarks\zerosection -\to \everyafterstructureblock - -\def\dosetupstructureblock[#1]% - {\getparameters[\??nb#1]}% [#2] - -\def\dosetstructureblock[#1]% used to set the default - {\edef\currentstructureblock{\ctxlua{structure.sections.setblock("#1")}}} - -\let\currentstructureblock\s!unknown - -\def\startstructureblock[#1]% - {\begingroup - \edef\currentstructureblock{\ctxlua{structure.sections.pushblock("#1")}}% - \csname #1true\endcsname % for old times sake - \setsystemmode\currentstructureblock - \the\everybeforestructureblock\relax - \showmessage\m!structures1\currentstructureblock} - -\def\stopstructureblock - {\showmessage\m!structures2\currentstructureblock - \the\everyafterstructureblock\relax - \edef\currentstructureblock{\ctxlua{structure.sections.popblock()}}% - \endgroup} - -\long\def\setstructureblockenvironment#1#2% - {\long\setvalue{\??nb\s!do#1}{\do{#2}}} - -\def\getstructureblockenvironment#1% - {\let\do\firstofoneargument - \structureblockparameter{\s!do#1}} - -%D \starttyping -%D \startsectionblockenvironment[frontpart] -%D \setuppagenumbering[conversion=romannumerals] -%D \stopsectionblockenvironment -%D -%D \startsectionblockenvironment[bodypart] -%D \setuppagenumber[number=1] -%D \stopsectionblockenvironment -%D -%D \startsectionblockenvironment[frontpart] -%D \setuppagenumbering[conversion=character] -%D \stopsectionblockenvironment -%D -%D \starttext -%D \startfrontmatter \chapter{test} \stopfrontmatter -%D \startbodymatter \chapter{test} \stopbodymatter -%D \startappendices \chapter{test} \stopappendices -%D \stoptext -%D \stoptyping - -\setvalue{\e!start\v!structureblockenvironment}% - {\dosingleargument\dostartstructureblockenvironment} - -\def\dostartstructureblockenvironment[#1]% evt \pushendofline \popendofline - {\long\def\do##1##2{\setstructureblockenvironment{#1}{##1##2}}% - \grabuntil{\e!stop\v!structureblockenvironment}{\structureblockparameter{\s!do#1}}} - -% this will become: (we ran in parallel for a while during transition) - -\setvalue{\e!start\v!sectionblockenvironment}% - {\dosingleargument\dostartsectionblockenvironment} - -\def\dostartsectionblockenvironment[#1]% evt \pushendofline \popendofline - {\long\def\do##1##2{\setstructureblockenvironment{#1}{##1##2}}% - \grabuntil{\e!stop\v!sectionblockenvironment}{\structureblockparameter{\s!do#1}}} - -\protect \endinput diff --git a/tex/context/base/strc-sec.mkii b/tex/context/base/strc-sec.mkii new file mode 100644 index 000000000..ef85d1e7a --- /dev/null +++ b/tex/context/base/strc-sec.mkii @@ -0,0 +1,2572 @@ +%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 + +% \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..a45564c43 --- /dev/null +++ b/tex/context/base/strc-sec.mkiv @@ -0,0 +1,667 @@ +%D \module +%D [ file=strc-sec, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Sectioning, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Sectioning} + +\unprotect + +% compatibility issue: +% +% \def\setfullsectionnumber #1{} +% \def\preparefullnumber #1{} +% \def\fullsectionnumber {1--1--1} +% \def\makesectionnumber [#1]{} +% \def\makesectionformat {} +% \def\sectionformat {1--1-1-1-1-1-1} +% \def\composedsectionnumber{} +% \def\@@kolist{} + +% \setuphead[section] [separator=\separatorlist{?,!,*}] +% \setuphead[subsection][separator=\separatorlist{??,!!,**}] +% +% \let\spr\separatorlist % this will enable this feature +% +% \setuphead[section] [separator={?,!,*}] +% \setuphead[subsection][separator={??,!!,**}] +% +% \setupheads[separator={A,B,C,D,E,F}] +% \chapter{test} +% \section{test} \subsection{test} \subsection{test} +% \section{test} \subsection{test} \subsection{test} + +% lua interface + +\def\setstructurelevel #1#2{\ctxlua{structure.sections.setlevel("#1","#2")}} % name, level|parent +\def\getstructurelevel #1{\ctxlua{structure.sections.getcurrentlevel("#1")}}% name +\def\setstructurenumber #1#2{\ctxlua{structure.sections.setnumber(#1,"#2")}} % level, number (+/-) +\def\getstructurenumber #1{\ctxlua{structure.sections.getnumber(#1)}} % level +\def\getfullstructurenumber#1{\ctxlua{structure.sections.fullnumber(#1)}} % level + +% interface + +\def\structureheadparameter #1{\csname\dostructureheadparameter{\??nh\currentstructurehead}#1\endcsname} +\def\structureheadparameterhash#1{\dostructureheadparameterhash {\??nh\currentstructurehead}#1} + +\def\dostructureheadparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructureheadparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dostructureheadparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dostructureheadparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dostructureheadparentparameter #1#2{\ifx#1\relax\s!empty\else\dostructureheadparameter #1#2\fi} +\def\dostructureheadparentparameterhash#1#2{\ifx#1\relax \else\dostructureheadparameterhash#1#2\fi} + +\def\dosetstructureheadattributes#1#2% style color + {\edef\fontattributehash {\structureheadparameterhash#1}% + \edef\colorattributehash{\structureheadparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +% so far + +\newcount\maxstructuredepth + +\let\laststructuresectionname\empty + +\def\definestructuresection[#1]% + {\doifundefined{\??nh#1} + {\global\advance\maxstructuredepth\plusone + \setevalue{\??nh#1\c!level}{\the\maxstructuredepth}% + \setstructurelevel{#1}{\the\maxstructuredepth}% +% \letvalue{\??nh#1\c!marking}\empty % ? + %\writestatus{structure}{#1\ifx\laststructuresectionname\empty\else\space->\space\laststructuresectionname\fi}% + \normalexpanded{\noexpand\getparameters[\??nh#1][\s!parent=\??nh\laststructuresectionname]}% + \definemarking[#1]% + \ifnum\maxstructuredepth>\plusone +% \normalexpanded{\noexpand\couplemarking[#1][\laststructuresectionname]}% so, the child inherits settings from the parent + \normalexpanded{\noexpand\relatemarking[#1][\laststructuresectionname]}% so, the parent will reset the child + \fi + \xdef\laststructuresectionname{#1}}} + +\def\setupstructuresection + {\dotripleempty\dosetupstructuresection} + +\def\dosetupstructuresection[#1]% + {\doifdefinedelse{\??nh#1} + {\dodosetupstructuresection[#1]} + {\dodosetupstructuresection[\structuresectionheadsection{#1}]}} + +\def\dodosetupstructuresection[#1][#2][#3]% + {\ifthirdargument + \getparameters[\??nh#1#2][#3]% ? probably sectionblock + \else + \getparameters[\??nh#1][#2]% + \fi} + +\def\structuresectionlevel#1% + {\executeifdefined{\??nh#1\c!level}0} + +% head -> structurehead + +\let\currentstructurehead\empty +\newtoks\everystructureheadsetup + +\def\setupstructureheads{\dosingleargument\dosetupstructureheads} +\def\setupstructurehead {\dodoubleempty\dosetupstructurehead} +\def\definestructurehead{\dodoubleempty\dodefinestructurehead} + +\newif\ifsectionnumber % maybe conditional + +\def\dosetupstructureheads[#1]% + {\getparameters[\??nh][#1]% + \doifelse{\structureheadparameter\c!sectionnumber}\v!yes\sectionnumbertrue\sectionnumberfalse} + +\def\dosetupstructurehead[#1][#2]% we move the test for command being nothing elsewhere (needed, else hard to trace) + {\processcommalist[#1]{\dodosetupstructurehead{#2}}} + +\def\dodosetupstructurehead#1#2% + {\getparameters[\??nh#2][#1]% + \the\everystructureheadsetup} + +\def\dodefinestructurehead[#1][#2]% + {\processcommalist[#1]{\dododefinestructurehead{#2}}} + +\def\dododefinestructurehead#1#2% #1: parameters|parent, #2: self + {\doifsomethingelse{#2} + {\doifassignmentelse{#1} + \dodefineuniquestructurehead + {\doifdefinedelse{\??nh#1\s!parent} % just a check + \dodefineclonedstructurehead + \dodefineerrorstructurehead}} + \dodefineerrorstructurehead + {#2}{#1}} + +\def\dodefineerrorstructurehead#1#2% + {\setvalue{#1}{\par error: #1 is undefined\par}} + +% deeptextcommand and deepnumbercommand are left undefined ! + +\def\dodefineuniquestructurehead#1#2% class, parameters + {\def\currentstructurehead{#1}% + \presetlabeltext[#1=]% + \getparameters[\??nh#1][\c!label=#1,#2]% + \edef\currentstructureheaddefault{\structureheadparameter\c!default}% + \edef\currentstructureheadsection{\structureheadparameter\c!section}% + \edef\currentstructureheadparent + {\??nh + \ifx\currentstructurehead\currentstructureheaddefault + \currentstructureheadsection + \else\ifx\currentstructureheaddefault\empty + \currentstructureheadsection + \else + \currentstructureheaddefault + \fi\fi}% + \normalexpanded{\noexpand\getparameters[\??nh#1][\s!parent=\currentstructureheadparent]}% \setevalue{\??nh#1\s!parent}{\currentstructureheadparent}% + \ifx\currentstructureheadsection\empty + %\writestatus{structure}{#1->\currentstructureheadparent}% + \else + %\writestatus{structure}{#1->\currentstructureheadparent\space(\currentstructureheadsection)}% + % todo: filtercommand + \definemarking[#1][\currentstructureheadsection]% + \definemarking[#1\v!number][#1]% + \setupmarking[#1][\c!filtercommand=\sectionheadmarkingtitle{#1}]% + \setupmarking[#1\c!number][\c!filtercommand=\sectionheadmarkingnumber{#1}]% + \fi + \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}% definestructurelist ? + \the\everystructureheadsetup} + +\def\sectionheadmarkingtitle #1#2{\ctxlua{structure.marks.title("#1","#2")}} +\def\sectionheadmarkingnumber#1#2{\ctxlua{structure.marks.number("#1","#2")}} + +\def\dodefineclonedstructurehead#1#2% class parent + {\def\currentstructurehead{#1}% + \presetlabeltext[#1=]% + \doifelse{#1}{#2} + {\getparameters[\??nh#1][\c!label=#1]% + \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}}% definestructurelist ? + {\getparameters[\??nh#1][\s!parent=\??nh#2,\c!label=#1]% + \definemarking[#1][#2]% + \definemarking[#1\v!number][#2\c!number]% + \doifundefined{\??li#1}{\definelist[#1][#2][\c!prefix=\v!no]}}% definestructurelist ? + \the\everystructureheadsetup} + +\appendtoks + \setstructurelevel\currentstructurehead{\structuresectionheadsection{\structuresectionheadcoupling\currentstructurehead}}% + \doifelse{\structureheadparameter\c!ownnumber}\v!yes + {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadown[\currentstructurehead]}} + {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadnop[\currentstructurehead]}}% + \setevalue{\e!start\currentstructurehead}{\noexpand\dostartstructurehead[\currentstructurehead]}% + \setevalue{\e!stop\currentstructurehead }{\noexpand\dostopstructurehead[\currentstructurehead]}% +\to \everystructureheadsetup + +% todo, check if section is defined + +\def\structuresectionheadcoupling#1% + {\ifcsname\??nh#1\c!coupling\endcsname + \expandafter\structuresectionheadcoupling\csname\??nh#1\c!coupling\endcsname\else#1% + \fi} + +\def\structuresectionheadsection#1% + {\ifcsname\??nh#1\c!section\endcsname + \expandafter\structuresectionheadcoupling\csname\??nh#1\c!section\endcsname\else#1% + \fi} + +% head construction + +\def\dohandlestructureheadown{\dodoubleempty\dodohandlestructureheadown} % [ref] {nr} {title} +\def\dohandlestructureheadnop{\dodoubleempty\dodohandlestructureheadnop} % [ref] {title} +\def\dostartstructurehead {\dotripleempty\dodostartstructurehead} % [settings] [userdata] + +\newconditional\currentstructureown + +\def\dodohandlestructureheadown[#1][#2]#3#4% + {\settrue\currentstructureown + \dohandlestructurehead{#1}{\c!reference=#2,\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title -- + +\def\dodohandlestructureheadnop[#1][#2]#3% + {\setfalse\currentstructureown + \dohandlestructurehead{#1}{\c!reference=#2,\c!title={#3}}{}} % name ref nr title -- + +\newtoks\everybeforestructurehead % hook, todo: before/after keys +\newtoks\everyafterstructurehead % hook, todo: before/after keys + +\def\dodostartstructurehead[#1][#2][#3]% for the moment no grouping, too annoying with page breaks + {\setfalse\currentstructureown + \globalpushmacro\currentstructurehead + \xdef\currentstructurehead{#1}% + \the\everybeforestructurehead + \dohandlestructurehead{#1}{#2}{#3}} % name -- -- -- userdata + +\def\dostopstructurehead[#1]% + {\globalpopmacro\currentstructurehead + \doifnot{#1}\currentstructurehead{\writestatus\m!systems{missing \letterbackslash\e!stop#1}}% + \xdef\currentstructurehead{#1}% recover + \the\everyafterstructurehead} + +% \newconditional\structurereversesectionnumbers % todo: key/val + +\newconditional\structureheadtolist +\newconditional\structureheaddoincrement +\newconditional\structureheaddoplace +\newconditional\structureheadleaveempty +\newconditional\structureheadshownumber +\newconditional\structureheadisdisplay + +\let\structureheadprefix\empty \def\structureheadprefixplus{+} + +% When do we reset the referenceprefix? This needs to be checked. Does it work +% at all? + +\def\setstructureheadreference#1% reference + {\edef\structureheadreference{#1}% + \edef\structureheadreferenceprefix{\structureheadparameter\c!prefix}% + \ifx\structureheadreferenceprefix\empty + \setupreferenceprefix[]% yes or no? + \else\ifx\structureheadreferenceprefix\structureheadreferenceprefixplus + \ifx\structureheadreference\empty + \setupreferenceprefix[\structureheadreferenceprefixplus] + \else + \setupreferenceprefix[#1]% we assume just one reference + \fi + \else + \setupreferenceprefix[\structureheadreferenceprefix]% + \fi\fi} + +\setvalue{\??nh:\c!incrementnumber:\v!yes }{\settrue \structureheaddoincrement\settrue \structureheadtolist} +\setvalue{\??nh:\c!incrementnumber:\v!no }{\setfalse\structureheaddoincrement\setfalse\structureheadtolist} +\setvalue{\??nh:\c!incrementnumber:\v!list }{\setfalse\structureheaddoincrement\settrue \structureheadtolist} +\setvalue{\??nh:\c!incrementnumber:\s!empty}{\settrue \structureheaddoincrement\settrue \structureheadtolist} + +\def\setstructureheadincrement + {\edef\currentstructureheadincrement{\structureheadparameter\c!incrementnumber}% + \ifcsname\??nh:\c!incrementnumber:\currentstructureheadincrement\endcsname + \csname\??nh:\c!incrementnumber:\currentstructureheadincrement\endcsname + \else + \settrue \structureheaddoincrement\settrue \structureheadtolist + % \filterstructureheadnumber + \fi} + +\def\filterstructureheadnumber + {\settrue\structureheaddoincrement + \settrue\structureheadtolist + \ifx\currentproduct\empty + % todo : filter from other toc (number, file, title) + % use : \currentstructureheadincrement as spec + \fi} + +\def\setstructureheadplacement + {\settrue\structureheaddoplace + \setfalse\structureheadleaveempty + \processaction + [\structureheadparameter\c!placehead] + [ \v!yes=>, + \v!empty=>\settrue\structureheadleaveempty, + \v!no=>\settrue\structureheadleaveempty\setfalse\structureheaddoplace]} + +\def\setstructureheadreset % todo, also set resetset here + {\doifelse{\structureheadparameter\c!resetnumber}\v!no + {\setfalse\@@resetsubheadnumbers}% + {\settrue \@@resetsubheadnumbers}} + +\def\setstructureheaddisplay + {\doifelsevalue{\??nh:\structureheadparameter\c!alternative}\v!horizontal + {\setfalse\structureheadisdisplay} + {\settrue \structureheadisdisplay}} + +\def\dosettructureheadnumbercontent + {\setsystemmode \v!sectionnumber + \settrue\structureheadshownumber} + +\def\doresettructureheadnumbercontent + {\resetsystemmode\v!sectionnumber + \setfalse\structureheadshownumber} + +\def\setstructureheadnumber + {\ifsectionnumber + \doifelse{\structureblockparameter\c!number}\v!yes % todo + {\doifelse{\structureheadparameter\c!number}\v!yes + {\settrue\structureheadshownumber} + {\setfalse\structureheadshownumber}} + {\setfalse\structureheadshownumber}% + \else + \setfalse\structureheadshownumber + \fi} + +% \defconvertexpanded\asciititle{\getvalue{\??ko#1\c!expansion}}{#4}% + +% \unexpanded\def\\{\space} + +\def\thestructureheadsynchonization + {\pagetype[\currentstructureheadcoupling]% hm also number + \normalexpanded{\noexpand\setmarking[\currentstructureheadcoupling]{\currentstructurelistnumber}}% + \currentstructuresynchronize} + +\def\thestructureheadnumber{\labeltexts{\structureheadparameter\c!label}{\structurenumber}} +\def\thestructureheadtitle {\structurecctvalue{titledata.title}} + +\let\currentstructurehead \empty +\let\currentstructureheadcoupling\empty +\let\currentstructureheadsection \empty +\let\currentstructureheadlevel \!!zerocount +\let\currentstructureheadcounter \!!zerocount + +\def\doregisterstructurehead#1#2#3% name data userdata + {\structurecomponent + [\c!label={\structureheadparameter\c!label}, + \c!incrementnumber=\ifconditional\structureheaddoincrement\v!yes\else\v!no\fi, % not that needed + \c!saveinlist=\ifconditional\structureheadtolist\v!yes\else\v!no\fi, + \c!level=\currentstructureheadlevel, + \c!name=#1, + \c!number=\ifconditional\structureheadshownumber\v!yes\else\v!no\fi, + \c!bookmark=, + \c!expansion=\structureheadparameter\c!expansion, + \c!reset=\structureheadparameter\c!reset, + \c!sectionseparatorset=\structureheadparameter\c!sectionseparatorset, + \c!sectionconversionset=\structureheadparameter\c!sectionconversionset, + \c!sectionconversion=\structureheadparameter\c!conversion, % just for compatibility + \c!sectionstopper=\structureheadparameter\c!sectionstopper, + \c!sectionset=\structureheadparameter\c!sectionset, + \c!sectionsegments=\structureheadparameter\c!sectionsegments, + \c!reference=\structureheadreference, + \c!referenceprefix=\structureheadreferenceprefix, + \c!command=, + #2]% + [#3]% + \reportcurrentstructure} + +\unexpanded\def\placeheadtext {\doquintupleempty\doplaceheadtextornumber[\c!textstyle] [\c!textcolor] [\empty]} +\unexpanded\def\placeheadnumber{\doquintupleempty\doplaceheadtextornumber[\c!numberstyle][\c!numbercolor][\v!number]} + +\def\doplaceheadtextornumber[#1][#2][#3][#4][#5]% + {\dontleavehmode + \begingroup + \xdef\currentstructurehead {\iffifthargument#5\else#4\fi}% + \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}% + \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}% + \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}% + \dosetstructureheadattributes\c!style\c!color + \dosetstructureheadattributes#1#2% + \dontconvertfont + \setupinterlinespace + % temp hack most be fixed (see s-pre-61) + % \begstrut\getmarking[#4#3]\endstrut + \doifelse{#3}\v!number\currentheadnumber\currentheadtext + \endgraf + \endgroup} + +\def\dohandlestructurehead#1#2#3% name data userdata + {\xdef\currentstructurehead {#1}% + \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}% + \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}% + \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}% + %writestatus\m!systems{setup: \currentstructurehead,\currentstructureheadcoupling,\currentstructureheadsection,\currentstructureheadlevel}% + % + \setstructureheadreference{#3}% will change + \setstructureheadincrement + \setstructureheadplacement + \setstructureheadreset + \setstructureheaddisplay + \setstructureheadnumber + % + \unexpanded\def\\{\space}% + \flushingcolumnfloatsfalse + % + % todo: also mark (for header) + % + % we might remove the lower level + % + % not here, after optional \page: \doregisterstructurehead{#1}{#2}{#3}% + % +% \xdef\currentstructureheadcounter{\currentstructurecounter}% lua call + % + % \currentstructuresynchronize % will move + % + \edef\numberheaddistance {\structureheadparameter\c!distance }% compatibility + \edef\numberheadalternative{\structureheadparameter\c!alternative}% compatibility + % + \let\getstructureheadnumber\empty + \let\getstructureheadtitle \empty + \let\getstructureheadsyncs \empty + \ifconditional\structureheaddoincrement + \ifconditional\structureheaddoplace + \dostructureheadspacingbeforeyes + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \let\getstructureheadtitle\thestructureheadtitle + \ifconditional\structureheadshownumber + \let\getstructureheadnumber\thestructureheadnumber + \placestructureheadnumbertext + \else + \placestructureheadtext + \fi + \dostructureheadspacingafteryes + \else + \dostructureheadspacingbeforenop % toegevoegd ivm subpaginanr / tug sheets + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadnothing % just flush 'm + \dostructureheadspacingafternop + \fi + \else + \ifconditional\structureheaddoplace + \dostructureheadspacingbeforeyes + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadtitle\thestructureheadtitle + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadtext + \dostructureheadspacingafteryes + \else + % do nothing / should be vbox to 0pt + \dostructureheadspacingbeforenop + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadnothing % just flush 'm + \dostructureheadspacingafternop + \fi + \fi + \flushingcolumnfloatstrue + \setfalse\ignorehandlepagebreak + % ignorespaces prevents spaces creeping in when after=\dontleavehmode + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \ignorespaces + \else + \expandafter\GotoPar + \fi} + +% typesetting + +\def\placestructureheadnumbertext + {\getstructureheadnumber/\getstructureheadtitle + \getstructureheadsyncs} + +\def\placestructureheadtext + {\getstructureheadtitle + \getstructureheadsyncs} + +\def\placestructureheadnothing + {\getstructureheadsyncs} + +% pagebreaks + +\newcount\precedingstructurelevel \precedingstructurelevel\plusone +\newconditional\ignorehandlepagebreak + +\def\dostructureheadspacingbeforeyes + {\docheckstructureheadbefore\dohandlestructureheadpagebreak + \structureheadparameter\c!inbetween} + +\def\dostructureheadspacingbeforenop + {\docheckstructureheadbefore\docheckstructureheadlayout + \structureheadparameter\c!inbetween} + +\def\dostructureheadspacingafteryes + {\ifconditional\structureheadisdisplay + \dosomebreak\nobreak + \ifconditional\structureheadleaveempty % inlined \emptyheadcorrection (with after=\blank) + \vskip-\lineheight + \dosomebreak\nobreak + \kern\zeropoint + \prevdepth\strutdepth + \fi + \structureheadparameter\c!after + \fi} + +\def\dostructureheadspacingafternop + {} + +\newsignal\continuousstructureheadsignal + +\def\docheckstructureheadbefore#1% + {\ifhmode + \scratchcounter\lastpenalty\unpenalty % no beauty in this + \ifdim\lastskip=\continuousstructureheadsignal + % no page break + \ifconditional\ignorehandlepagebreak + \setfalse\ignorehandlepagebreak + \else + \global\precedingstructurelevel\currentstructureheadlevel + \nobreak + \fi + \global\settrue\continuoussectionhead + \else + \penalty\scratchcounter + \global\setfalse\continuoussectionhead + #1% + \fi + \else + \global\setfalse\continuoussectionhead + #1% + \fi} + +\def\dodocheckstructureheadlayout#1#2% + {\doifelselayouttextline{#1} + {\doifsomething{\structureheadparameter#2}{\expanded{\setuplayouttext[#1][\c!state=\structureheadparameter#2]}}} + \donothing} + +\def\docheckstructureheadlayout + {\doifsomething{\structureheadparameter\c!page} + {\page[\structureheadparameter\c!page]% + \dodocheckstructureheadlayout\v!header\c!header + \dodocheckstructureheadlayout\v!text \c!text + \dodocheckstructureheadlayout\v!footer\c!footer}} + +\def\currentstructurecounter {\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead)}} +\def\previousstructurecounter{\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead-1)}} + +\def\dohandlestructureheadpagebreak + {%[[\currentstructurehead @\thenamedstructureheadlevel\currentstructurehead/prev:\previousstructurecounter/curr:\currentstructurecounter]] + \ifconditional\ignorehandlepagebreak + \setfalse\ignorehandlepagebreak + \else + \ifnum\lastpenalty>\zerocount + \global\pagebreakdisabledtrue + \fi + % beware, these numbers are not yet know here + \doifelse{\structureheadparameter\c!continue}\v!yes + {\ifnum\previousstructurecounter=\zerocount + \docheckstructureheadlayout + \else\ifnum\currentstructurecounter>\zerocount + \docheckstructureheadlayout + \fi\fi}% + {\docheckstructureheadlayout}% + \doifnot{\structureheadparameter\c!aligntitle}\v!float\flushsidefloats + \structureheadparameter\c!before + \relax + \ifpagebreakdisabled + \global\pagebreakdisabledfalse + \else + \dopreventbreakafterstructureheadauto + \fi + \doif{\structureheadparameter\c!aligntitle}\v!float\indent + \global\precedingstructurelevel\currentstructureheadlevel + \fi} + +% the next one was: \somebreakmethod + +\chardef\somestructureheadbreakmethod\plusone % 0=nothing, 1=weighted, 2=strict, 3=vspacing + +\def\dopreventbreakafterstructureheadauto % used after \c!before + {\ifcase\somestructureheadbreakmethod + % 0 = nothing + \or + % 1 = old weighted version + \ifnum\currentstructureheadlevel>\precedingstructurelevel + \dosomebreak{\penalty\numexpr20000+500*\currentstructureheadlevel\relax}% + \else + \dosomebreak\allowbreak % brr + \fi + \or + % 2 = strict version + \dosomebreak{\penalty\maxdimen}% + \or + % 3 = vspacing + \vspacing[\v!samepage]% if preceded by ! then a loop + \else + % nothing + \fi} + +\def\dopreventbreakafterstructureheadspec#1% see enumerations etc + {\ifcase\somestructureheadbreakmethod + % 0 = nothing + \or + % 1 = old weighted version + \dosomebreak{\penalty\numexpr20000+500*(\currentstructureheadlevel+#1)\relax}% + \or + % 2 = strict version + \dosomebreak{\penalty\maxdimen}% + \or + % 3 = vspacing + \vspacing[\v!samepage]% + \else + % nothing + \fi} + +\def\dohandlepagebreakX{\dopreventbreakafterstructureheadspec} % no \let so we can redefind + +% todo: + +\def\thecurrentstructureheadlevel#1% + {\getstructurelevel{#1}} + +\def\thenamedstructureheadlevel#1% + {\structuresectionlevel{\structuresectionheadsection{\structuresectionheadcoupling{#1}}}} + +\def\setupheadnumber + {\dodoubleargument\dosetupheadnumber} + +\def\dosetupheadnumber[#1][#2]% todo: reset if at other level + {\setstructurenumber{\thecurrentstructureheadlevel{#1}}{#2}} + +\def\currentstructureheadnumber{0} % ==> \currentheadnumber + +\def\determineheadnumber[#1]% + {\xdef\currentstructureheadnumber{\getstructurenumber{\thecurrentstructureheadlevel{#1}}}} + +\def\structureheadnumber + {\dosingleempty\dostructureheadnumber} + +\def\dostructureheadnumber[#1]% simple case is just a number + {\getfullstructurenumber{\iffirstargument\thecurrentstructureheadlevel{#1}\fi}} + +% compatibility code (after all, we might offer different structure handlers as well + +\let\definesectionblock \definestructureblock +\let\definesection \definestructuresection +\let\setupsection \setupstructuresection +\let\setupheads \setupstructureheads +\let\definehead \definestructurehead +\let\setuphead \setupstructurehead +\let\headnumber \structureheadnumber +\let\setupsectionblock \setupstructureblock +\let\currentheadnumber \thestructureheadnumber +\let\currentheadtext \thestructureheadtitle +\let\sectioncountervalue\structurevalue + +% list references, will be redone in lua when we need it + +\let\startlistreferences\relax +\let\stoplistreferences \relax + +\protect \endinput diff --git a/tex/context/base/strc-sec.tex b/tex/context/base/strc-sec.tex deleted file mode 100644 index a45564c43..000000000 --- a/tex/context/base/strc-sec.tex +++ /dev/null @@ -1,667 +0,0 @@ -%D \module -%D [ file=strc-sec, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Sectioning, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Sectioning} - -\unprotect - -% compatibility issue: -% -% \def\setfullsectionnumber #1{} -% \def\preparefullnumber #1{} -% \def\fullsectionnumber {1--1--1} -% \def\makesectionnumber [#1]{} -% \def\makesectionformat {} -% \def\sectionformat {1--1-1-1-1-1-1} -% \def\composedsectionnumber{} -% \def\@@kolist{} - -% \setuphead[section] [separator=\separatorlist{?,!,*}] -% \setuphead[subsection][separator=\separatorlist{??,!!,**}] -% -% \let\spr\separatorlist % this will enable this feature -% -% \setuphead[section] [separator={?,!,*}] -% \setuphead[subsection][separator={??,!!,**}] -% -% \setupheads[separator={A,B,C,D,E,F}] -% \chapter{test} -% \section{test} \subsection{test} \subsection{test} -% \section{test} \subsection{test} \subsection{test} - -% lua interface - -\def\setstructurelevel #1#2{\ctxlua{structure.sections.setlevel("#1","#2")}} % name, level|parent -\def\getstructurelevel #1{\ctxlua{structure.sections.getcurrentlevel("#1")}}% name -\def\setstructurenumber #1#2{\ctxlua{structure.sections.setnumber(#1,"#2")}} % level, number (+/-) -\def\getstructurenumber #1{\ctxlua{structure.sections.getnumber(#1)}} % level -\def\getfullstructurenumber#1{\ctxlua{structure.sections.fullnumber(#1)}} % level - -% interface - -\def\structureheadparameter #1{\csname\dostructureheadparameter{\??nh\currentstructurehead}#1\endcsname} -\def\structureheadparameterhash#1{\dostructureheadparameterhash {\??nh\currentstructurehead}#1} - -\def\dostructureheadparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructureheadparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\dostructureheadparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dostructureheadparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dostructureheadparentparameter #1#2{\ifx#1\relax\s!empty\else\dostructureheadparameter #1#2\fi} -\def\dostructureheadparentparameterhash#1#2{\ifx#1\relax \else\dostructureheadparameterhash#1#2\fi} - -\def\dosetstructureheadattributes#1#2% style color - {\edef\fontattributehash {\structureheadparameterhash#1}% - \edef\colorattributehash{\structureheadparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -% so far - -\newcount\maxstructuredepth - -\let\laststructuresectionname\empty - -\def\definestructuresection[#1]% - {\doifundefined{\??nh#1} - {\global\advance\maxstructuredepth\plusone - \setevalue{\??nh#1\c!level}{\the\maxstructuredepth}% - \setstructurelevel{#1}{\the\maxstructuredepth}% -% \letvalue{\??nh#1\c!marking}\empty % ? - %\writestatus{structure}{#1\ifx\laststructuresectionname\empty\else\space->\space\laststructuresectionname\fi}% - \normalexpanded{\noexpand\getparameters[\??nh#1][\s!parent=\??nh\laststructuresectionname]}% - \definemarking[#1]% - \ifnum\maxstructuredepth>\plusone -% \normalexpanded{\noexpand\couplemarking[#1][\laststructuresectionname]}% so, the child inherits settings from the parent - \normalexpanded{\noexpand\relatemarking[#1][\laststructuresectionname]}% so, the parent will reset the child - \fi - \xdef\laststructuresectionname{#1}}} - -\def\setupstructuresection - {\dotripleempty\dosetupstructuresection} - -\def\dosetupstructuresection[#1]% - {\doifdefinedelse{\??nh#1} - {\dodosetupstructuresection[#1]} - {\dodosetupstructuresection[\structuresectionheadsection{#1}]}} - -\def\dodosetupstructuresection[#1][#2][#3]% - {\ifthirdargument - \getparameters[\??nh#1#2][#3]% ? probably sectionblock - \else - \getparameters[\??nh#1][#2]% - \fi} - -\def\structuresectionlevel#1% - {\executeifdefined{\??nh#1\c!level}0} - -% head -> structurehead - -\let\currentstructurehead\empty -\newtoks\everystructureheadsetup - -\def\setupstructureheads{\dosingleargument\dosetupstructureheads} -\def\setupstructurehead {\dodoubleempty\dosetupstructurehead} -\def\definestructurehead{\dodoubleempty\dodefinestructurehead} - -\newif\ifsectionnumber % maybe conditional - -\def\dosetupstructureheads[#1]% - {\getparameters[\??nh][#1]% - \doifelse{\structureheadparameter\c!sectionnumber}\v!yes\sectionnumbertrue\sectionnumberfalse} - -\def\dosetupstructurehead[#1][#2]% we move the test for command being nothing elsewhere (needed, else hard to trace) - {\processcommalist[#1]{\dodosetupstructurehead{#2}}} - -\def\dodosetupstructurehead#1#2% - {\getparameters[\??nh#2][#1]% - \the\everystructureheadsetup} - -\def\dodefinestructurehead[#1][#2]% - {\processcommalist[#1]{\dododefinestructurehead{#2}}} - -\def\dododefinestructurehead#1#2% #1: parameters|parent, #2: self - {\doifsomethingelse{#2} - {\doifassignmentelse{#1} - \dodefineuniquestructurehead - {\doifdefinedelse{\??nh#1\s!parent} % just a check - \dodefineclonedstructurehead - \dodefineerrorstructurehead}} - \dodefineerrorstructurehead - {#2}{#1}} - -\def\dodefineerrorstructurehead#1#2% - {\setvalue{#1}{\par error: #1 is undefined\par}} - -% deeptextcommand and deepnumbercommand are left undefined ! - -\def\dodefineuniquestructurehead#1#2% class, parameters - {\def\currentstructurehead{#1}% - \presetlabeltext[#1=]% - \getparameters[\??nh#1][\c!label=#1,#2]% - \edef\currentstructureheaddefault{\structureheadparameter\c!default}% - \edef\currentstructureheadsection{\structureheadparameter\c!section}% - \edef\currentstructureheadparent - {\??nh - \ifx\currentstructurehead\currentstructureheaddefault - \currentstructureheadsection - \else\ifx\currentstructureheaddefault\empty - \currentstructureheadsection - \else - \currentstructureheaddefault - \fi\fi}% - \normalexpanded{\noexpand\getparameters[\??nh#1][\s!parent=\currentstructureheadparent]}% \setevalue{\??nh#1\s!parent}{\currentstructureheadparent}% - \ifx\currentstructureheadsection\empty - %\writestatus{structure}{#1->\currentstructureheadparent}% - \else - %\writestatus{structure}{#1->\currentstructureheadparent\space(\currentstructureheadsection)}% - % todo: filtercommand - \definemarking[#1][\currentstructureheadsection]% - \definemarking[#1\v!number][#1]% - \setupmarking[#1][\c!filtercommand=\sectionheadmarkingtitle{#1}]% - \setupmarking[#1\c!number][\c!filtercommand=\sectionheadmarkingnumber{#1}]% - \fi - \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}% definestructurelist ? - \the\everystructureheadsetup} - -\def\sectionheadmarkingtitle #1#2{\ctxlua{structure.marks.title("#1","#2")}} -\def\sectionheadmarkingnumber#1#2{\ctxlua{structure.marks.number("#1","#2")}} - -\def\dodefineclonedstructurehead#1#2% class parent - {\def\currentstructurehead{#1}% - \presetlabeltext[#1=]% - \doifelse{#1}{#2} - {\getparameters[\??nh#1][\c!label=#1]% - \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}}% definestructurelist ? - {\getparameters[\??nh#1][\s!parent=\??nh#2,\c!label=#1]% - \definemarking[#1][#2]% - \definemarking[#1\v!number][#2\c!number]% - \doifundefined{\??li#1}{\definelist[#1][#2][\c!prefix=\v!no]}}% definestructurelist ? - \the\everystructureheadsetup} - -\appendtoks - \setstructurelevel\currentstructurehead{\structuresectionheadsection{\structuresectionheadcoupling\currentstructurehead}}% - \doifelse{\structureheadparameter\c!ownnumber}\v!yes - {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadown[\currentstructurehead]}} - {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadnop[\currentstructurehead]}}% - \setevalue{\e!start\currentstructurehead}{\noexpand\dostartstructurehead[\currentstructurehead]}% - \setevalue{\e!stop\currentstructurehead }{\noexpand\dostopstructurehead[\currentstructurehead]}% -\to \everystructureheadsetup - -% todo, check if section is defined - -\def\structuresectionheadcoupling#1% - {\ifcsname\??nh#1\c!coupling\endcsname - \expandafter\structuresectionheadcoupling\csname\??nh#1\c!coupling\endcsname\else#1% - \fi} - -\def\structuresectionheadsection#1% - {\ifcsname\??nh#1\c!section\endcsname - \expandafter\structuresectionheadcoupling\csname\??nh#1\c!section\endcsname\else#1% - \fi} - -% head construction - -\def\dohandlestructureheadown{\dodoubleempty\dodohandlestructureheadown} % [ref] {nr} {title} -\def\dohandlestructureheadnop{\dodoubleempty\dodohandlestructureheadnop} % [ref] {title} -\def\dostartstructurehead {\dotripleempty\dodostartstructurehead} % [settings] [userdata] - -\newconditional\currentstructureown - -\def\dodohandlestructureheadown[#1][#2]#3#4% - {\settrue\currentstructureown - \dohandlestructurehead{#1}{\c!reference=#2,\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title -- - -\def\dodohandlestructureheadnop[#1][#2]#3% - {\setfalse\currentstructureown - \dohandlestructurehead{#1}{\c!reference=#2,\c!title={#3}}{}} % name ref nr title -- - -\newtoks\everybeforestructurehead % hook, todo: before/after keys -\newtoks\everyafterstructurehead % hook, todo: before/after keys - -\def\dodostartstructurehead[#1][#2][#3]% for the moment no grouping, too annoying with page breaks - {\setfalse\currentstructureown - \globalpushmacro\currentstructurehead - \xdef\currentstructurehead{#1}% - \the\everybeforestructurehead - \dohandlestructurehead{#1}{#2}{#3}} % name -- -- -- userdata - -\def\dostopstructurehead[#1]% - {\globalpopmacro\currentstructurehead - \doifnot{#1}\currentstructurehead{\writestatus\m!systems{missing \letterbackslash\e!stop#1}}% - \xdef\currentstructurehead{#1}% recover - \the\everyafterstructurehead} - -% \newconditional\structurereversesectionnumbers % todo: key/val - -\newconditional\structureheadtolist -\newconditional\structureheaddoincrement -\newconditional\structureheaddoplace -\newconditional\structureheadleaveempty -\newconditional\structureheadshownumber -\newconditional\structureheadisdisplay - -\let\structureheadprefix\empty \def\structureheadprefixplus{+} - -% When do we reset the referenceprefix? This needs to be checked. Does it work -% at all? - -\def\setstructureheadreference#1% reference - {\edef\structureheadreference{#1}% - \edef\structureheadreferenceprefix{\structureheadparameter\c!prefix}% - \ifx\structureheadreferenceprefix\empty - \setupreferenceprefix[]% yes or no? - \else\ifx\structureheadreferenceprefix\structureheadreferenceprefixplus - \ifx\structureheadreference\empty - \setupreferenceprefix[\structureheadreferenceprefixplus] - \else - \setupreferenceprefix[#1]% we assume just one reference - \fi - \else - \setupreferenceprefix[\structureheadreferenceprefix]% - \fi\fi} - -\setvalue{\??nh:\c!incrementnumber:\v!yes }{\settrue \structureheaddoincrement\settrue \structureheadtolist} -\setvalue{\??nh:\c!incrementnumber:\v!no }{\setfalse\structureheaddoincrement\setfalse\structureheadtolist} -\setvalue{\??nh:\c!incrementnumber:\v!list }{\setfalse\structureheaddoincrement\settrue \structureheadtolist} -\setvalue{\??nh:\c!incrementnumber:\s!empty}{\settrue \structureheaddoincrement\settrue \structureheadtolist} - -\def\setstructureheadincrement - {\edef\currentstructureheadincrement{\structureheadparameter\c!incrementnumber}% - \ifcsname\??nh:\c!incrementnumber:\currentstructureheadincrement\endcsname - \csname\??nh:\c!incrementnumber:\currentstructureheadincrement\endcsname - \else - \settrue \structureheaddoincrement\settrue \structureheadtolist - % \filterstructureheadnumber - \fi} - -\def\filterstructureheadnumber - {\settrue\structureheaddoincrement - \settrue\structureheadtolist - \ifx\currentproduct\empty - % todo : filter from other toc (number, file, title) - % use : \currentstructureheadincrement as spec - \fi} - -\def\setstructureheadplacement - {\settrue\structureheaddoplace - \setfalse\structureheadleaveempty - \processaction - [\structureheadparameter\c!placehead] - [ \v!yes=>, - \v!empty=>\settrue\structureheadleaveempty, - \v!no=>\settrue\structureheadleaveempty\setfalse\structureheaddoplace]} - -\def\setstructureheadreset % todo, also set resetset here - {\doifelse{\structureheadparameter\c!resetnumber}\v!no - {\setfalse\@@resetsubheadnumbers}% - {\settrue \@@resetsubheadnumbers}} - -\def\setstructureheaddisplay - {\doifelsevalue{\??nh:\structureheadparameter\c!alternative}\v!horizontal - {\setfalse\structureheadisdisplay} - {\settrue \structureheadisdisplay}} - -\def\dosettructureheadnumbercontent - {\setsystemmode \v!sectionnumber - \settrue\structureheadshownumber} - -\def\doresettructureheadnumbercontent - {\resetsystemmode\v!sectionnumber - \setfalse\structureheadshownumber} - -\def\setstructureheadnumber - {\ifsectionnumber - \doifelse{\structureblockparameter\c!number}\v!yes % todo - {\doifelse{\structureheadparameter\c!number}\v!yes - {\settrue\structureheadshownumber} - {\setfalse\structureheadshownumber}} - {\setfalse\structureheadshownumber}% - \else - \setfalse\structureheadshownumber - \fi} - -% \defconvertexpanded\asciititle{\getvalue{\??ko#1\c!expansion}}{#4}% - -% \unexpanded\def\\{\space} - -\def\thestructureheadsynchonization - {\pagetype[\currentstructureheadcoupling]% hm also number - \normalexpanded{\noexpand\setmarking[\currentstructureheadcoupling]{\currentstructurelistnumber}}% - \currentstructuresynchronize} - -\def\thestructureheadnumber{\labeltexts{\structureheadparameter\c!label}{\structurenumber}} -\def\thestructureheadtitle {\structurecctvalue{titledata.title}} - -\let\currentstructurehead \empty -\let\currentstructureheadcoupling\empty -\let\currentstructureheadsection \empty -\let\currentstructureheadlevel \!!zerocount -\let\currentstructureheadcounter \!!zerocount - -\def\doregisterstructurehead#1#2#3% name data userdata - {\structurecomponent - [\c!label={\structureheadparameter\c!label}, - \c!incrementnumber=\ifconditional\structureheaddoincrement\v!yes\else\v!no\fi, % not that needed - \c!saveinlist=\ifconditional\structureheadtolist\v!yes\else\v!no\fi, - \c!level=\currentstructureheadlevel, - \c!name=#1, - \c!number=\ifconditional\structureheadshownumber\v!yes\else\v!no\fi, - \c!bookmark=, - \c!expansion=\structureheadparameter\c!expansion, - \c!reset=\structureheadparameter\c!reset, - \c!sectionseparatorset=\structureheadparameter\c!sectionseparatorset, - \c!sectionconversionset=\structureheadparameter\c!sectionconversionset, - \c!sectionconversion=\structureheadparameter\c!conversion, % just for compatibility - \c!sectionstopper=\structureheadparameter\c!sectionstopper, - \c!sectionset=\structureheadparameter\c!sectionset, - \c!sectionsegments=\structureheadparameter\c!sectionsegments, - \c!reference=\structureheadreference, - \c!referenceprefix=\structureheadreferenceprefix, - \c!command=, - #2]% - [#3]% - \reportcurrentstructure} - -\unexpanded\def\placeheadtext {\doquintupleempty\doplaceheadtextornumber[\c!textstyle] [\c!textcolor] [\empty]} -\unexpanded\def\placeheadnumber{\doquintupleempty\doplaceheadtextornumber[\c!numberstyle][\c!numbercolor][\v!number]} - -\def\doplaceheadtextornumber[#1][#2][#3][#4][#5]% - {\dontleavehmode - \begingroup - \xdef\currentstructurehead {\iffifthargument#5\else#4\fi}% - \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}% - \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}% - \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}% - \dosetstructureheadattributes\c!style\c!color - \dosetstructureheadattributes#1#2% - \dontconvertfont - \setupinterlinespace - % temp hack most be fixed (see s-pre-61) - % \begstrut\getmarking[#4#3]\endstrut - \doifelse{#3}\v!number\currentheadnumber\currentheadtext - \endgraf - \endgroup} - -\def\dohandlestructurehead#1#2#3% name data userdata - {\xdef\currentstructurehead {#1}% - \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}% - \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}% - \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}% - %writestatus\m!systems{setup: \currentstructurehead,\currentstructureheadcoupling,\currentstructureheadsection,\currentstructureheadlevel}% - % - \setstructureheadreference{#3}% will change - \setstructureheadincrement - \setstructureheadplacement - \setstructureheadreset - \setstructureheaddisplay - \setstructureheadnumber - % - \unexpanded\def\\{\space}% - \flushingcolumnfloatsfalse - % - % todo: also mark (for header) - % - % we might remove the lower level - % - % not here, after optional \page: \doregisterstructurehead{#1}{#2}{#3}% - % -% \xdef\currentstructureheadcounter{\currentstructurecounter}% lua call - % - % \currentstructuresynchronize % will move - % - \edef\numberheaddistance {\structureheadparameter\c!distance }% compatibility - \edef\numberheadalternative{\structureheadparameter\c!alternative}% compatibility - % - \let\getstructureheadnumber\empty - \let\getstructureheadtitle \empty - \let\getstructureheadsyncs \empty - \ifconditional\structureheaddoincrement - \ifconditional\structureheaddoplace - \dostructureheadspacingbeforeyes - \doregisterstructurehead{#1}{#2}{#3}% after optional \page - \let\getstructureheadsyncs\thestructureheadsynchonization - \let\getstructureheadtitle\thestructureheadtitle - \ifconditional\structureheadshownumber - \let\getstructureheadnumber\thestructureheadnumber - \placestructureheadnumbertext - \else - \placestructureheadtext - \fi - \dostructureheadspacingafteryes - \else - \dostructureheadspacingbeforenop % toegevoegd ivm subpaginanr / tug sheets - \doregisterstructurehead{#1}{#2}{#3}% after optional \page - \let\getstructureheadsyncs\thestructureheadsynchonization - \placestructureheadnothing % just flush 'm - \dostructureheadspacingafternop - \fi - \else - \ifconditional\structureheaddoplace - \dostructureheadspacingbeforeyes - \doregisterstructurehead{#1}{#2}{#3}% after optional \page - \let\getstructureheadtitle\thestructureheadtitle - \let\getstructureheadsyncs\thestructureheadsynchonization - \placestructureheadtext - \dostructureheadspacingafteryes - \else - % do nothing / should be vbox to 0pt - \dostructureheadspacingbeforenop - \doregisterstructurehead{#1}{#2}{#3}% after optional \page - \let\getstructureheadsyncs\thestructureheadsynchonization - \placestructureheadnothing % just flush 'm - \dostructureheadspacingafternop - \fi - \fi - \flushingcolumnfloatstrue - \setfalse\ignorehandlepagebreak - % ignorespaces prevents spaces creeping in when after=\dontleavehmode - \ifconditional\structureheadisdisplay % \ifdisplaysectionhead - \ignorespaces - \else - \expandafter\GotoPar - \fi} - -% typesetting - -\def\placestructureheadnumbertext - {\getstructureheadnumber/\getstructureheadtitle - \getstructureheadsyncs} - -\def\placestructureheadtext - {\getstructureheadtitle - \getstructureheadsyncs} - -\def\placestructureheadnothing - {\getstructureheadsyncs} - -% pagebreaks - -\newcount\precedingstructurelevel \precedingstructurelevel\plusone -\newconditional\ignorehandlepagebreak - -\def\dostructureheadspacingbeforeyes - {\docheckstructureheadbefore\dohandlestructureheadpagebreak - \structureheadparameter\c!inbetween} - -\def\dostructureheadspacingbeforenop - {\docheckstructureheadbefore\docheckstructureheadlayout - \structureheadparameter\c!inbetween} - -\def\dostructureheadspacingafteryes - {\ifconditional\structureheadisdisplay - \dosomebreak\nobreak - \ifconditional\structureheadleaveempty % inlined \emptyheadcorrection (with after=\blank) - \vskip-\lineheight - \dosomebreak\nobreak - \kern\zeropoint - \prevdepth\strutdepth - \fi - \structureheadparameter\c!after - \fi} - -\def\dostructureheadspacingafternop - {} - -\newsignal\continuousstructureheadsignal - -\def\docheckstructureheadbefore#1% - {\ifhmode - \scratchcounter\lastpenalty\unpenalty % no beauty in this - \ifdim\lastskip=\continuousstructureheadsignal - % no page break - \ifconditional\ignorehandlepagebreak - \setfalse\ignorehandlepagebreak - \else - \global\precedingstructurelevel\currentstructureheadlevel - \nobreak - \fi - \global\settrue\continuoussectionhead - \else - \penalty\scratchcounter - \global\setfalse\continuoussectionhead - #1% - \fi - \else - \global\setfalse\continuoussectionhead - #1% - \fi} - -\def\dodocheckstructureheadlayout#1#2% - {\doifelselayouttextline{#1} - {\doifsomething{\structureheadparameter#2}{\expanded{\setuplayouttext[#1][\c!state=\structureheadparameter#2]}}} - \donothing} - -\def\docheckstructureheadlayout - {\doifsomething{\structureheadparameter\c!page} - {\page[\structureheadparameter\c!page]% - \dodocheckstructureheadlayout\v!header\c!header - \dodocheckstructureheadlayout\v!text \c!text - \dodocheckstructureheadlayout\v!footer\c!footer}} - -\def\currentstructurecounter {\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead)}} -\def\previousstructurecounter{\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead-1)}} - -\def\dohandlestructureheadpagebreak - {%[[\currentstructurehead @\thenamedstructureheadlevel\currentstructurehead/prev:\previousstructurecounter/curr:\currentstructurecounter]] - \ifconditional\ignorehandlepagebreak - \setfalse\ignorehandlepagebreak - \else - \ifnum\lastpenalty>\zerocount - \global\pagebreakdisabledtrue - \fi - % beware, these numbers are not yet know here - \doifelse{\structureheadparameter\c!continue}\v!yes - {\ifnum\previousstructurecounter=\zerocount - \docheckstructureheadlayout - \else\ifnum\currentstructurecounter>\zerocount - \docheckstructureheadlayout - \fi\fi}% - {\docheckstructureheadlayout}% - \doifnot{\structureheadparameter\c!aligntitle}\v!float\flushsidefloats - \structureheadparameter\c!before - \relax - \ifpagebreakdisabled - \global\pagebreakdisabledfalse - \else - \dopreventbreakafterstructureheadauto - \fi - \doif{\structureheadparameter\c!aligntitle}\v!float\indent - \global\precedingstructurelevel\currentstructureheadlevel - \fi} - -% the next one was: \somebreakmethod - -\chardef\somestructureheadbreakmethod\plusone % 0=nothing, 1=weighted, 2=strict, 3=vspacing - -\def\dopreventbreakafterstructureheadauto % used after \c!before - {\ifcase\somestructureheadbreakmethod - % 0 = nothing - \or - % 1 = old weighted version - \ifnum\currentstructureheadlevel>\precedingstructurelevel - \dosomebreak{\penalty\numexpr20000+500*\currentstructureheadlevel\relax}% - \else - \dosomebreak\allowbreak % brr - \fi - \or - % 2 = strict version - \dosomebreak{\penalty\maxdimen}% - \or - % 3 = vspacing - \vspacing[\v!samepage]% if preceded by ! then a loop - \else - % nothing - \fi} - -\def\dopreventbreakafterstructureheadspec#1% see enumerations etc - {\ifcase\somestructureheadbreakmethod - % 0 = nothing - \or - % 1 = old weighted version - \dosomebreak{\penalty\numexpr20000+500*(\currentstructureheadlevel+#1)\relax}% - \or - % 2 = strict version - \dosomebreak{\penalty\maxdimen}% - \or - % 3 = vspacing - \vspacing[\v!samepage]% - \else - % nothing - \fi} - -\def\dohandlepagebreakX{\dopreventbreakafterstructureheadspec} % no \let so we can redefind - -% todo: - -\def\thecurrentstructureheadlevel#1% - {\getstructurelevel{#1}} - -\def\thenamedstructureheadlevel#1% - {\structuresectionlevel{\structuresectionheadsection{\structuresectionheadcoupling{#1}}}} - -\def\setupheadnumber - {\dodoubleargument\dosetupheadnumber} - -\def\dosetupheadnumber[#1][#2]% todo: reset if at other level - {\setstructurenumber{\thecurrentstructureheadlevel{#1}}{#2}} - -\def\currentstructureheadnumber{0} % ==> \currentheadnumber - -\def\determineheadnumber[#1]% - {\xdef\currentstructureheadnumber{\getstructurenumber{\thecurrentstructureheadlevel{#1}}}} - -\def\structureheadnumber - {\dosingleempty\dostructureheadnumber} - -\def\dostructureheadnumber[#1]% simple case is just a number - {\getfullstructurenumber{\iffirstargument\thecurrentstructureheadlevel{#1}\fi}} - -% compatibility code (after all, we might offer different structure handlers as well - -\let\definesectionblock \definestructureblock -\let\definesection \definestructuresection -\let\setupsection \setupstructuresection -\let\setupheads \setupstructureheads -\let\definehead \definestructurehead -\let\setuphead \setupstructurehead -\let\headnumber \structureheadnumber -\let\setupsectionblock \setupstructureblock -\let\currentheadnumber \thestructureheadnumber -\let\currentheadtext \thestructureheadtitle -\let\sectioncountervalue\structurevalue - -% list references, will be redone in lua when we need it - -\let\startlistreferences\relax -\let\stoplistreferences \relax - -\protect \endinput diff --git a/tex/context/base/strc-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.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..a739be902 --- /dev/null +++ b/tex/context/base/strc-syn.mkiv @@ -0,0 +1,392 @@ +%D \module +%D [ file=strc-syn, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Synonyms and Sorting, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Synonyms and Sorting} + +\registerctxluafile{strc-syn}{1.001} + +\unprotect + +% general help, can be shared + +% simplifiedcommands -> flag in lua +% +% expansion +% criterium -> when start, then flag in list +% command-> wanneer? +% state -> flagging enabled +% conversion ? +% todo: register xml mode etc + +% split but common in lua + +\def\preprocessexpansion#1#2#3#4% + {\ifx#1\s!xml + \xmlstartraw + \xdef#2{#4}% + \xmlstopraw + \globallet#3\s!xml + \else + \ifx#1\v!yes + \xdef#2{#4}% + \else + \xdef#2{\detokenize{#4}}% + \fi + \globallet#3\s!tex + \fi} + +\let\currentsynonym\empty + +\def\synonymparameter #1{\csname\dosynonymparameter{\??sm\currentsynonym}#1\endcsname} +\def\synonymparameterhash#1{\dosynonymparameterhash {\??sm\currentsynonym}#1} + +\def\dosynonymparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dosynonymparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dosynonymparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dosynonymparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dosynonymparentparameter #1#2{\ifx#1\relax\s!empty\else\dosynonymparameter #1#2\fi} +\def\dosynonymparentparameterhash#1#2{\ifx#1\relax \else\dosynonymparameterhash#1#2\fi} + +\def\dosetsynonymattributes#1#2% style color + {\edef\fontattributehash {\synonymparameterhash#1}% + \edef\colorattributehash{\synonymparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\newtoks\everysetupsynonyms + +\def\setupsynonyms + {\dodoubleargument\dosetupsynonyms} + +\def\dosetupsynonyms[#1][#2]% + {\ifsecondargument + \getparameters[\??sm#1][#2]% + \else + \getparameters[\??sm][#1]% + \fi + \the\everysetupsynonyms} + +\setupsynonyms + [\c!state=\v!start, + %\c!synonymstyle=, + %\c!textstyle=, + %\c!headstyle=, + %\c!headcolor=, + %\c!criterium=, + \c!location=\v!left, + \c!width=5em, + \c!distance=0pt, + %\c!sample=, + %\c!hang=, + %\c!align=, + %\c!before=, + %\c!inbetween=, + %\c!after=, + \c!indentnext=\v!no, + %\c!expansion=, + \s!language=\currentmainlanguage] + +\def\definesynonyms + {\doquadrupleempty\dodefinesynonyms} + +\def\dodefinesynonyms[#1][#2][#3][#4]% name plural \meaning \use + {\iffourthargument + \unexpanded\def#4##1{\doinsertsynonym{#1}{##1}}% name tag + \ifthirdargument + \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning + \fi + \setvalue{#1}{\definesynonym[\v!no][#1]}% \name + \else + \ifthirdargument + \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning + \fi + \setvalue{#1}{\definesynonym[\v!yes][#1]}% \name + \fi + \getparameters[\??sm#1][\s!parent=\??sm]% + \presetheadtext[#2=\Word{#2}]% changes the \if...argument + %\ctxlua{joblists.define('#1')}% + \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??sm#1]}% to be obsolete + \setvalue{\e!place \e!listof#2}{\doplacelistofsynonyms{#1}{#2}}% + \setvalue{\e!complete\e!listof#2}{\docompletelistofsynonyms{#1}{#2}}} + +\def\definesynonym + {\dotripleempty\dodefinesynonym} + +\def\dodefinesynonym[#1][#2][#3]#4#5% + {\begingroup + \edef\currentsynonym{#2}% + \edef\currentsynonymtag{#3}% + \ifx\currentsynonymtag\empty + \edef\currentsynonymtag{#4}% + \fi + \ifx\currentsynonymtag\empty + % todo: error message + \else + \edef\currentsynonymexpansion{\synonymparameter\c!expansion}% + \preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}% + \preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}% + \ctxlua{joblists.register("\currentsynonym", "synonym", { + metadata = { + catcodes = \the\catcodetable, + coding = "\currentsynonymcoding", + xmlroot = \ifx\currentsynonymcoding\s!xml "\xmldocument" \else nil \fi, + }, + definition = { + tag = "\currentsynonymtag", + synonym = \!!bs\currentsynonymtext\!!es, + meaning = \!!bs\currentsynonymmeaning\!!es, + used = false, + } + })}% + \doif{#1}\v!yes{\unexpanded\setxvalue\currentsynonymtag{\noexpand\doinsertsynonym{\currentsynonym}{\currentsynonymtag}}}% + \fi + \endgroup} + +\def\doinsertsynonym#1#2% name tag + {\begingroup + % no kap currently, of .. we need to map cap onto WORD + \dosetsynonymattributes\c!synonymstyle\c!synonymcolor + \ctxlua{joblists.synonym("#1","#2")}% + \endgroup} + +\def\doinsertsynonymmeaning#1#2% name tag + {\begingroup + % no kap currently, of .. we need to map cap onto WORD + \dosetsynonymattributes\c!textstyle\c!textcolor + \ctxlua{joblists.meaning("#1","#2")}% + \endgroup} + +\def\doplacelistofsynonyms#1#2% + {\begingroup + \def\currentsynonym{#1}% +\definedescription % todo, per class + [syndef] + [\c!location=\synonymparameter\c!location, + \c!width=\synonymparameter\c!width, + \c!distance=\synonymparameter\c!distance, + \c!sample=\synonymparameter\c!sample, + \c!hang=\synonymparameter\c!hang, + \c!align=\synonymparameter\c!align, + \c!before=\synonymparameter\c!before, + \c!inbetween=\synonymparameter\c!inbetween, + \c!after=\synonymparameter\c!after, + \c!indentnext=\synonymparameter\c!indentnext, + \c!headstyle=\synonymparameter\c!headstyle, + \c!headcolor=\synonymparameter\c!headcolor, + \c!style=, + \c!color=]% + \startpacked + \ctxlua{joblists.process('#1',{ criterium = "\synonymparameter\c!criterium" })}% + \stoppacked + \endgroup} + +\def\docompletelistofsynonyms#1#2% expansion needed to avoid v! (due to french active !) + {\normalexpanded{\noexpand\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% + \doplacelistofsynonyms{#1}{#2}% + \page[\v!yes]} + +\let\startsynonymoutput \relax +\let\stopsynonymoutput \relax +\let\startsynonymsection\gobbleoneargument +\let\stopsynonymsection \relax + +\def\synonymentry#1#2#3% + {\syndef{\dosetsynonymattributes\c!textstyle\c!textcolor#2}#3\par} + +\let\currentsorting\empty + +% we can share if we also have synonymprefix = so + +\def\sortingparameter #1{\csname\dosortingparameter{\??so\currentsorting}#1\endcsname} +\def\sortingparameterhash#1{\dosortingparameterhash {\??so\currentsorting}#1} + +\def\dosortingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dosortingparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dosortingparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dosortingparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dosortingparentparameter #1#2{\ifx#1\relax\s!empty\else\dosortingparameter #1#2\fi} +\def\dosortingparentparameterhash#1#2{\ifx#1\relax \else\dosortingparameterhash#1#2\fi} + +\def\dosetsortingattributes#1#2% style color + {\edef\fontattributehash {\sortingparameterhash#1}% + \edef\colorattributehash{\sortingparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\newtoks\everysetupsorting + +\def\setupsorting + {\dodoubleargument\dosetupsorting} + +\def\dosetupsorting[#1][#2]% + {\ifsecondargument + \getparameters[\??so#1][#2]% + \else + \getparameters[\??so][#1]% + \fi + \the\everysetupsorting} + +\setupsorting + [\c!state=\v!start, + %\c!command=, % we test for defined ! + %\c!criterium=, + %\c!style=, + %\c!before=, + \c!after=\endgraf, + %\c!expansion=, + \s!language=\currentmainlanguage] + +\def\definesorting + {\dotripleempty\dodefinesorting} + +% if #3=\relax or \v!none, then no command but still protected + +\def\dodefinesorting[#1][#2][#3]% + {\ifthirdargument + \doifnot{#3}\v!none + {\ifx#3\relax \else + \def#3##1{\doinsertsort{#1}{##1}}% + \fi}% + \setvalue{#1}{\definesort[\v!no][#1]}% + \else + \setvalue{#1}{\definesort[\v!yes][#1]}% + \fi + \getparameters[\??so#1][\s!parent=\??so]% + \presetheadtext[#2=\Word{#2}]% after \ifthirdargument -) + %\ctxlua{joblists.define('#1')}% + \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??so#1]}% to be obsolete + \setvalue{\e!place \e!listof#2}{\doplacelistofsortings{#1}{#2}}% + \setvalue{\e!complete\e!listof#2}{\docompletelistofsortings{#1}{#2}}} + + +\def\definesort + {\dotripleempty\dodefinesort} + +\def\dodefinesort[#1][#2][#3]#4% + {\begingroup + \edef\currentsorting{#2}% + \edef\currentsortingtag{#3}% + \ifx\currentsortingtag\empty + \edef\currentsortingtag{#4}% + \fi + \ifx\currentsortingtag\empty + % todo: error message + \else + \edef\currentsortingexpansion{\sortingparameter\c!expansion}% + \preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}% + \ctxlua{joblists.register("\currentsorting", "sorting", { + metadata = { + catcodes = \the\catcodetable, + coding = "\currentsortingcoding", + xmlroot = \ifx\currentsortingcoding\s!xml "\xmldocument" \else nil \fi, + }, + definition = { + tag = "\currentsortingtag", + synonym = \!!bs\currentsortingtext\!!es, + % used = false, + } + })}% + \doif{#1}\v!yes{\unexpanded\setxvalue\currentsortingtag{\noexpand\doinsertsort{\currentsorting}{\currentsortingtag}}}% + \fi + \endgroup} + +\def\doinsertsort#1#2% name tag + {\begingroup + % no kap currently, of .. we need to map cap onto WORD + \dosetsynonymattributes\c!style\c!color + \ctxlua{joblists.synonym("#1","#2")}% + \endgroup} + +% before after +% +% maybe just 'commandset' and then combine + +\def\doplacelistofsorts#1% NOG EEN RUWE VERSIE MAKEN ZONDER WITRUIMTE ETC ETC + {\begingroup + \def\currentsorting{#1}% + \startpacked + \ctxlua{joblists.process('#1',{})}% + \stoppacked + \endgroup} + +\def\docompletelistofsorts#1#2% + {\normalexpanded{\noexpand\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% + \doplacelistofsorts{#1}% + \page[\v!yes]} + +\let\startsortingoutput \relax +\let\stopsortingoutput \relax +\let\startsortingsection\gobbleoneargument +\let\stopsortingsection \relax + +\def\sortingentry#1#2#3% + {\begingroup\dosetsortingattributes\c!style\c!color#2\endgroup\par} % todo + +%D Here we define a support macro that can sort simple comma +%D separated lists. It's a multi-list variant of a prototype +%D written by Taco. + +% \def\mkloadsortedlist#1% class +% {\bgroup +% \getvalue{\s!set#1}% +% \ctxlua{joblists.process('#1')}% +% \getvalue{\s!reset#1}% +% \egroup} + +% \def\processlistofsorts[#1]% +% {\mkloadsortedlist{#1}} + +% \newcounter\nofsortedalphalists + +% \def\sortalphacommacommand#1% +% {\begingroup +% \doglobal\increment\nofsortedalphalists +% \edef\currentsortedalphalist{alpha:\nofsortedalphalists}% +% \definesorting[\currentsortedalphalist][\currentsortedalphalist]% +% \processcommacommand[#1]{\getvalue\currentsortedalphalist}% +% \global\let\sortedcommalist\empty +% \def\makesortedlist##1{\doglobal\appendtocommalist{##1}\sortedcommalist}% +% \setupsorting[\currentsortedalphalist][\c!criterium=\v!all,\c!command=\makesortedlist]% +% \processlistofsorts[\currentsortedalphalist]% +% \endgroup +% \dodoglobal\let#1\sortedcommalist} + +% \starttext +% \def\whatever{a,b,q,d,r,f} \sortalphacommacommand\whatever \whatever \endgraf +% \def\whatever{ax,bx,qx,dx,rx,fx} \sortalphacommacommand\whatever \whatever \endgraf +% \stoptext + +%D Presets. + +\definesynonyms + [\v!abbreviation] + [\v!abbreviations] + [\infull] + +\setupsynonyms + [\v!abbreviation] + [\c!textstyle=\v!capital] + +\definesorting + [\v!logo] + [\v!logos] + % no [\logogram] + +\definesynonyms + [\v!unit] + [\v!units] + [\unitmeaning] + +\setupsynonyms + [\v!unit] + [\c!textstyle=\dimension] + +\protect \endinput diff --git a/tex/context/base/strc-syn.tex b/tex/context/base/strc-syn.tex deleted file mode 100644 index a739be902..000000000 --- a/tex/context/base/strc-syn.tex +++ /dev/null @@ -1,392 +0,0 @@ -%D \module -%D [ file=strc-syn, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=Synonyms and Sorting, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / Synonyms and Sorting} - -\registerctxluafile{strc-syn}{1.001} - -\unprotect - -% general help, can be shared - -% simplifiedcommands -> flag in lua -% -% expansion -% criterium -> when start, then flag in list -% command-> wanneer? -% state -> flagging enabled -% conversion ? -% todo: register xml mode etc - -% split but common in lua - -\def\preprocessexpansion#1#2#3#4% - {\ifx#1\s!xml - \xmlstartraw - \xdef#2{#4}% - \xmlstopraw - \globallet#3\s!xml - \else - \ifx#1\v!yes - \xdef#2{#4}% - \else - \xdef#2{\detokenize{#4}}% - \fi - \globallet#3\s!tex - \fi} - -\let\currentsynonym\empty - -\def\synonymparameter #1{\csname\dosynonymparameter{\??sm\currentsynonym}#1\endcsname} -\def\synonymparameterhash#1{\dosynonymparameterhash {\??sm\currentsynonym}#1} - -\def\dosynonymparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dosynonymparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\dosynonymparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dosynonymparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dosynonymparentparameter #1#2{\ifx#1\relax\s!empty\else\dosynonymparameter #1#2\fi} -\def\dosynonymparentparameterhash#1#2{\ifx#1\relax \else\dosynonymparameterhash#1#2\fi} - -\def\dosetsynonymattributes#1#2% style color - {\edef\fontattributehash {\synonymparameterhash#1}% - \edef\colorattributehash{\synonymparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -\newtoks\everysetupsynonyms - -\def\setupsynonyms - {\dodoubleargument\dosetupsynonyms} - -\def\dosetupsynonyms[#1][#2]% - {\ifsecondargument - \getparameters[\??sm#1][#2]% - \else - \getparameters[\??sm][#1]% - \fi - \the\everysetupsynonyms} - -\setupsynonyms - [\c!state=\v!start, - %\c!synonymstyle=, - %\c!textstyle=, - %\c!headstyle=, - %\c!headcolor=, - %\c!criterium=, - \c!location=\v!left, - \c!width=5em, - \c!distance=0pt, - %\c!sample=, - %\c!hang=, - %\c!align=, - %\c!before=, - %\c!inbetween=, - %\c!after=, - \c!indentnext=\v!no, - %\c!expansion=, - \s!language=\currentmainlanguage] - -\def\definesynonyms - {\doquadrupleempty\dodefinesynonyms} - -\def\dodefinesynonyms[#1][#2][#3][#4]% name plural \meaning \use - {\iffourthargument - \unexpanded\def#4##1{\doinsertsynonym{#1}{##1}}% name tag - \ifthirdargument - \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning - \fi - \setvalue{#1}{\definesynonym[\v!no][#1]}% \name - \else - \ifthirdargument - \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning - \fi - \setvalue{#1}{\definesynonym[\v!yes][#1]}% \name - \fi - \getparameters[\??sm#1][\s!parent=\??sm]% - \presetheadtext[#2=\Word{#2}]% changes the \if...argument - %\ctxlua{joblists.define('#1')}% - \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??sm#1]}% to be obsolete - \setvalue{\e!place \e!listof#2}{\doplacelistofsynonyms{#1}{#2}}% - \setvalue{\e!complete\e!listof#2}{\docompletelistofsynonyms{#1}{#2}}} - -\def\definesynonym - {\dotripleempty\dodefinesynonym} - -\def\dodefinesynonym[#1][#2][#3]#4#5% - {\begingroup - \edef\currentsynonym{#2}% - \edef\currentsynonymtag{#3}% - \ifx\currentsynonymtag\empty - \edef\currentsynonymtag{#4}% - \fi - \ifx\currentsynonymtag\empty - % todo: error message - \else - \edef\currentsynonymexpansion{\synonymparameter\c!expansion}% - \preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}% - \preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}% - \ctxlua{joblists.register("\currentsynonym", "synonym", { - metadata = { - catcodes = \the\catcodetable, - coding = "\currentsynonymcoding", - xmlroot = \ifx\currentsynonymcoding\s!xml "\xmldocument" \else nil \fi, - }, - definition = { - tag = "\currentsynonymtag", - synonym = \!!bs\currentsynonymtext\!!es, - meaning = \!!bs\currentsynonymmeaning\!!es, - used = false, - } - })}% - \doif{#1}\v!yes{\unexpanded\setxvalue\currentsynonymtag{\noexpand\doinsertsynonym{\currentsynonym}{\currentsynonymtag}}}% - \fi - \endgroup} - -\def\doinsertsynonym#1#2% name tag - {\begingroup - % no kap currently, of .. we need to map cap onto WORD - \dosetsynonymattributes\c!synonymstyle\c!synonymcolor - \ctxlua{joblists.synonym("#1","#2")}% - \endgroup} - -\def\doinsertsynonymmeaning#1#2% name tag - {\begingroup - % no kap currently, of .. we need to map cap onto WORD - \dosetsynonymattributes\c!textstyle\c!textcolor - \ctxlua{joblists.meaning("#1","#2")}% - \endgroup} - -\def\doplacelistofsynonyms#1#2% - {\begingroup - \def\currentsynonym{#1}% -\definedescription % todo, per class - [syndef] - [\c!location=\synonymparameter\c!location, - \c!width=\synonymparameter\c!width, - \c!distance=\synonymparameter\c!distance, - \c!sample=\synonymparameter\c!sample, - \c!hang=\synonymparameter\c!hang, - \c!align=\synonymparameter\c!align, - \c!before=\synonymparameter\c!before, - \c!inbetween=\synonymparameter\c!inbetween, - \c!after=\synonymparameter\c!after, - \c!indentnext=\synonymparameter\c!indentnext, - \c!headstyle=\synonymparameter\c!headstyle, - \c!headcolor=\synonymparameter\c!headcolor, - \c!style=, - \c!color=]% - \startpacked - \ctxlua{joblists.process('#1',{ criterium = "\synonymparameter\c!criterium" })}% - \stoppacked - \endgroup} - -\def\docompletelistofsynonyms#1#2% expansion needed to avoid v! (due to french active !) - {\normalexpanded{\noexpand\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% - \doplacelistofsynonyms{#1}{#2}% - \page[\v!yes]} - -\let\startsynonymoutput \relax -\let\stopsynonymoutput \relax -\let\startsynonymsection\gobbleoneargument -\let\stopsynonymsection \relax - -\def\synonymentry#1#2#3% - {\syndef{\dosetsynonymattributes\c!textstyle\c!textcolor#2}#3\par} - -\let\currentsorting\empty - -% we can share if we also have synonymprefix = so - -\def\sortingparameter #1{\csname\dosortingparameter{\??so\currentsorting}#1\endcsname} -\def\sortingparameterhash#1{\dosortingparameterhash {\??so\currentsorting}#1} - -\def\dosortingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dosortingparentparameter \csname#1\s!parent\endcsname#2\fi} -\def\dosortingparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dosortingparentparameterhash\csname#1\s!parent\endcsname#2\fi} - -\def\dosortingparentparameter #1#2{\ifx#1\relax\s!empty\else\dosortingparameter #1#2\fi} -\def\dosortingparentparameterhash#1#2{\ifx#1\relax \else\dosortingparameterhash#1#2\fi} - -\def\dosetsortingattributes#1#2% style color - {\edef\fontattributehash {\sortingparameterhash#1}% - \edef\colorattributehash{\sortingparameterhash#2}% - \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi - \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} - -\newtoks\everysetupsorting - -\def\setupsorting - {\dodoubleargument\dosetupsorting} - -\def\dosetupsorting[#1][#2]% - {\ifsecondargument - \getparameters[\??so#1][#2]% - \else - \getparameters[\??so][#1]% - \fi - \the\everysetupsorting} - -\setupsorting - [\c!state=\v!start, - %\c!command=, % we test for defined ! - %\c!criterium=, - %\c!style=, - %\c!before=, - \c!after=\endgraf, - %\c!expansion=, - \s!language=\currentmainlanguage] - -\def\definesorting - {\dotripleempty\dodefinesorting} - -% if #3=\relax or \v!none, then no command but still protected - -\def\dodefinesorting[#1][#2][#3]% - {\ifthirdargument - \doifnot{#3}\v!none - {\ifx#3\relax \else - \def#3##1{\doinsertsort{#1}{##1}}% - \fi}% - \setvalue{#1}{\definesort[\v!no][#1]}% - \else - \setvalue{#1}{\definesort[\v!yes][#1]}% - \fi - \getparameters[\??so#1][\s!parent=\??so]% - \presetheadtext[#2=\Word{#2}]% after \ifthirdargument -) - %\ctxlua{joblists.define('#1')}% - \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??so#1]}% to be obsolete - \setvalue{\e!place \e!listof#2}{\doplacelistofsortings{#1}{#2}}% - \setvalue{\e!complete\e!listof#2}{\docompletelistofsortings{#1}{#2}}} - - -\def\definesort - {\dotripleempty\dodefinesort} - -\def\dodefinesort[#1][#2][#3]#4% - {\begingroup - \edef\currentsorting{#2}% - \edef\currentsortingtag{#3}% - \ifx\currentsortingtag\empty - \edef\currentsortingtag{#4}% - \fi - \ifx\currentsortingtag\empty - % todo: error message - \else - \edef\currentsortingexpansion{\sortingparameter\c!expansion}% - \preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}% - \ctxlua{joblists.register("\currentsorting", "sorting", { - metadata = { - catcodes = \the\catcodetable, - coding = "\currentsortingcoding", - xmlroot = \ifx\currentsortingcoding\s!xml "\xmldocument" \else nil \fi, - }, - definition = { - tag = "\currentsortingtag", - synonym = \!!bs\currentsortingtext\!!es, - % used = false, - } - })}% - \doif{#1}\v!yes{\unexpanded\setxvalue\currentsortingtag{\noexpand\doinsertsort{\currentsorting}{\currentsortingtag}}}% - \fi - \endgroup} - -\def\doinsertsort#1#2% name tag - {\begingroup - % no kap currently, of .. we need to map cap onto WORD - \dosetsynonymattributes\c!style\c!color - \ctxlua{joblists.synonym("#1","#2")}% - \endgroup} - -% before after -% -% maybe just 'commandset' and then combine - -\def\doplacelistofsorts#1% NOG EEN RUWE VERSIE MAKEN ZONDER WITRUIMTE ETC ETC - {\begingroup - \def\currentsorting{#1}% - \startpacked - \ctxlua{joblists.process('#1',{})}% - \stoppacked - \endgroup} - -\def\docompletelistofsorts#1#2% - {\normalexpanded{\noexpand\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% - \doplacelistofsorts{#1}% - \page[\v!yes]} - -\let\startsortingoutput \relax -\let\stopsortingoutput \relax -\let\startsortingsection\gobbleoneargument -\let\stopsortingsection \relax - -\def\sortingentry#1#2#3% - {\begingroup\dosetsortingattributes\c!style\c!color#2\endgroup\par} % todo - -%D Here we define a support macro that can sort simple comma -%D separated lists. It's a multi-list variant of a prototype -%D written by Taco. - -% \def\mkloadsortedlist#1% class -% {\bgroup -% \getvalue{\s!set#1}% -% \ctxlua{joblists.process('#1')}% -% \getvalue{\s!reset#1}% -% \egroup} - -% \def\processlistofsorts[#1]% -% {\mkloadsortedlist{#1}} - -% \newcounter\nofsortedalphalists - -% \def\sortalphacommacommand#1% -% {\begingroup -% \doglobal\increment\nofsortedalphalists -% \edef\currentsortedalphalist{alpha:\nofsortedalphalists}% -% \definesorting[\currentsortedalphalist][\currentsortedalphalist]% -% \processcommacommand[#1]{\getvalue\currentsortedalphalist}% -% \global\let\sortedcommalist\empty -% \def\makesortedlist##1{\doglobal\appendtocommalist{##1}\sortedcommalist}% -% \setupsorting[\currentsortedalphalist][\c!criterium=\v!all,\c!command=\makesortedlist]% -% \processlistofsorts[\currentsortedalphalist]% -% \endgroup -% \dodoglobal\let#1\sortedcommalist} - -% \starttext -% \def\whatever{a,b,q,d,r,f} \sortalphacommacommand\whatever \whatever \endgraf -% \def\whatever{ax,bx,qx,dx,rx,fx} \sortalphacommacommand\whatever \whatever \endgraf -% \stoptext - -%D Presets. - -\definesynonyms - [\v!abbreviation] - [\v!abbreviations] - [\infull] - -\setupsynonyms - [\v!abbreviation] - [\c!textstyle=\v!capital] - -\definesorting - [\v!logo] - [\v!logos] - % no [\logogram] - -\definesynonyms - [\v!unit] - [\v!units] - [\unitmeaning] - -\setupsynonyms - [\v!unit] - [\c!textstyle=\dimension] - -\protect \endinput diff --git a/tex/context/base/strc-xml.mkiv b/tex/context/base/strc-xml.mkiv new file mode 100644 index 000000000..04c5e71b8 --- /dev/null +++ b/tex/context/base/strc-xml.mkiv @@ -0,0 +1,87 @@ +%D \module +%D [ file=strc-xml, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=XML Processing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / XML Processing} + +\unprotect + +\startxmlsetups xml:ctx:tocentry + \xmlsetsetup{\xmldocument}{ctx:tocentry}{xml:ctx:tocentry} +\stopxmlsetups + +\xmlregistersetup{xml:ctx:tocentry} + +\startxmlsetups xml:ctx:tocentry + \xmlflush{#1} +\stopxmlsetups + +\protect \endinput + +% test.xml + + + + +
+ Some <b>bold</b> title <b>bold <i>bold</i> oeps</b> and more + +

a paragraph of text

+

another paragraph of text

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

a paragraph of text

+

another paragraph of text

+
+
+
+ +% test.tex + +\setupstructurehead[chapter][expansion=xml] + +\startxmlsetups xml:demo:define:base + \xmlsetsetup{demo}{document|section|p|b|i}{xml:demo:*} +\stopxmlsetups + +\xmlregisterdocumentsetup{demo}{xml:demo:define:base} + +\startxmlsetups xml:demo:document + \title{Contents} + \placelist[chapter] + \page + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:demo:section + \chapter{\xmltext{#1}{/title}} + \xmlfirst{#1}{/content} +\stopxmlsetups + +\startxmlsetups xml:demo:p + \xmlflush{#1}\endgraf +\stopxmlsetups + +\startxmlsetups xml:demo:b + \bgroup\bf\xmlflush{#1}\egroup +\stopxmlsetups + +\startxmlsetups xml:demo:i + \bgroup\it\xmlflush{#1}\egroup +\stopxmlsetups + +\starttext + \xmlprocessfile{demo}{oeps.xml}{} +\stoptext diff --git a/tex/context/base/strc-xml.tex b/tex/context/base/strc-xml.tex deleted file mode 100644 index 04c5e71b8..000000000 --- a/tex/context/base/strc-xml.tex +++ /dev/null @@ -1,87 +0,0 @@ -%D \module -%D [ file=strc-xml, -%D version=2008.10.20, -%D title=\CONTEXT\ Structure Macros, -%D subtitle=XML Processing, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE / Hans Hagen] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Structure Macros / XML Processing} - -\unprotect - -\startxmlsetups xml:ctx:tocentry - \xmlsetsetup{\xmldocument}{ctx:tocentry}{xml:ctx:tocentry} -\stopxmlsetups - -\xmlregistersetup{xml:ctx:tocentry} - -\startxmlsetups xml:ctx:tocentry - \xmlflush{#1} -\stopxmlsetups - -\protect \endinput - -% test.xml - - - - -
- Some <b>bold</b> title <b>bold <i>bold</i> oeps</b> and more - -

a paragraph of text

-

another paragraph of text

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

a paragraph of text

-

another paragraph of text

-
-
-
- -% test.tex - -\setupstructurehead[chapter][expansion=xml] - -\startxmlsetups xml:demo:define:base - \xmlsetsetup{demo}{document|section|p|b|i}{xml:demo:*} -\stopxmlsetups - -\xmlregisterdocumentsetup{demo}{xml:demo:define:base} - -\startxmlsetups xml:demo:document - \title{Contents} - \placelist[chapter] - \page - \xmlflush{#1} -\stopxmlsetups - -\startxmlsetups xml:demo:section - \chapter{\xmltext{#1}{/title}} - \xmlfirst{#1}{/content} -\stopxmlsetups - -\startxmlsetups xml:demo:p - \xmlflush{#1}\endgraf -\stopxmlsetups - -\startxmlsetups xml:demo:b - \bgroup\bf\xmlflush{#1}\egroup -\stopxmlsetups - -\startxmlsetups xml:demo:i - \bgroup\it\xmlflush{#1}\egroup -\stopxmlsetups - -\starttext - \xmlprocessfile{demo}{oeps.xml}{} -\stoptext diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv new file mode 100644 index 000000000..c6a7c2499 --- /dev/null +++ b/tex/context/base/syst-aux.mkiv @@ -0,0 +1,6866 @@ +%D \module +%D [ file=syst-gen, +%D version=1996.03.20, +%D title=\CONTEXT\ System Macros, +%D subtitle=General, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Some of the macros will move to syst-obs as they might become +%D obsolete once we've redone the bibliography module. Of course +%D the handy helpers will stay. + +%D This is a stripped down combination of: +%D +%D \startitemize +%D \item \type {syst-gen.tex} +%D \item \type {syst-ext.tex} +%D \item \type {syst-new.tex} +%D \stopitemize +%D +%D We keep them around (for \MKII) so you can find comments, +%D experiences, intermediate versions and cleaner variants +%D there (and also non-\ETEX\ variants). +%D +%D Contrary to the older files, we now assume that this one +%D is used in \CONTEXT\ and therefore we might also assume that +%D some basic functionality is available. +%D +%D Some of the macros here are used in the bibliography module. They +%D will be moved to a separate syst module some once the bib module +%D is made \MKIV. + +\unprotect + +\let\reportprotectionstate\relax + +%D \macros +%D {doifolderversionelse} +%D +%D We start with a macro specially for Aditya who wants to be able +%D to use development versions of \MKIV\ for real documents. +%D +%D \starttyping +%D \doifolderversionelse\contextversion{2001.02.03}{yes}{no} +%D \doifolderversionelse\contextversion{3001.02.03}{yes}{no} +%D \stoptyping +%D +%D The \type {yyyy.mm.dd} syntax is rather strict. + +\def\@@versiontonumber#1.#2.#3#4#5\relax + {\numexpr#1*\plustenthousand+#2*\plushundred+#3#4\relax} + +\def\doifolderversionelse#1#2% + {\normalexpanded{\noexpand\ifnum\noexpand\@@versiontonumber#1\relax<\noexpand\@@versiontonumber#2\relax}\relax + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {normalspace} +%D +%D There is already \type{\space} but just to be sure we also +%D provide: + +\def\normalspace{ } + +%D \macros +%D {!!count, !!toks, !!dimen, !!box, +%D !!width, !!height, !!depth, !!string, !!done} +%D +%D We define some more \COUNTERS\ and \DIMENSIONS. We also +%D define some shortcuts to the local scatchregisters~0, 2, 4, +%D 6 and~8. + +\newcount\!!counta \newtoks\!!toksa \newdimen\!!dimena \newbox\!!boxa +\newcount\!!countb \newtoks\!!toksb \newdimen\!!dimenb \newbox\!!boxb +\newcount\!!countc \newtoks\!!toksc \newdimen\!!dimenc \newbox\!!boxc +\newcount\!!countd \newtoks\!!toksd \newdimen\!!dimend \newbox\!!boxd +\newcount\!!counte \newtoks\!!tokse \newdimen\!!dimene \newbox\!!boxe +\newcount\!!countf \newtoks\!!toksf \newdimen\!!dimenf \newbox\!!boxf + \newdimen\!!dimeng + \newdimen\!!dimenh + \newdimen\!!dimeni + \newdimen\!!dimenj + \newdimen\!!dimenk + +\let\!!stringa\empty \let\!!stringb\empty \let\!!stringc\empty +\let\!!stringd\empty \let\!!stringe\empty \let\!!stringf\empty + +\newdimen\!!widtha \newdimen\!!heighta \newdimen\!!deptha +\newdimen\!!widthb \newdimen\!!heightb \newdimen\!!depthb +\newdimen\!!widthc \newdimen\!!heightc \newdimen\!!depthc +\newdimen\!!widthd \newdimen\!!heightd \newdimen\!!depthd + +\newif\if!!donea \newif\if!!doneb \newif\if!!donec +\newif\if!!doned \newif\if!!donee \newif\if!!donef + +\def\!!zerocount {0} % alongside \zerocount +\def\!!minusone {-1} % alongside \minusone +\def\!!plusone {1} % alongside \plusone + +\ifdefined\data \else \let\data \relax \fi % dep checker + +%D \macros +%D {s!,c!,e!,p!,v!,@@,??} +%D +%D To save memory, we use constants (sometimes called +%D variables). Redefining these constants can have disastrous +%D results. + +\def\v!prefix! {v!} \def\c!prefix! {c!} +\def\s!prefix! {s!} \def\p!prefix! {p!} + +\def\s!next {next} \def\s!default {default} +\def\s!dummy {dummy} \def\s!unknown {unknown} + +\def\s!do {do} \def\s!dodo {dodo} + +\def\s!complex {complex} \def\s!start {start} +\def\s!simple {simple} \def\s!stop {stop} + +\def\s!empty {empty} + +%D \macros +%D {@EA,@EAEA,@EAEAEA,@EAEAEAEAEAEA,expanded,startexpanded} +%D +%D When in unprotected mode, to be entered with +%D \type{\unprotect}, one can use \type{\@EA} as equivalent +%D of \type{\expandafter}. + +\let\@NX\noexpand +\let\@EA\expandafter + +\def\@EAEA {\expandafter\expandafter} +\def\@EAEAEA{\expandafter\expandafter\expandafter} + +\def\@EAEAEAEAEAEA{\expandafter\@EAEAEA\expandafter} + +%D Sometimes we pass macros as arguments to commands that +%D don't expand them before interpretation. Such commands can +%D be enclosed with \type{\expanded}, like: +%D +%D \starttyping +%D \expanded{\setupsomething[\alfa]} +%D \stoptyping +%D +%D Such situations occur for instance when \type{\alfa} is a +%D commalist or when data stored in macros is fed to index of +%D list commands. If needed, one should use \type{\noexpand} +%D inside the argument. Later on we will meet some more clever +%D alternatives to this command. + +\long\def\@@expanded{} % always long; global (less restores) + +\long\def\expanded#1% + {\long\xdef\@@expanded{\noexpand#1}\@@expanded} + +%D Beware, the next one has no \type {\noexpand} before its +%D argument. + +\long\def\startexpanded#1\stopexpanded % see x-fo for example + {\long\xdef\@@expanded{#1}\@@expanded} + +%D Recent \TEX's have a primitive \expanded + +% \long\def\expanded +% {\normalexpanded\bgroup\noexpand\gobblenexttoken} + +%D \macros +%D {safeexpanded,everysafeexpanded} +%D +%D In addition we provide: + +\newtoks\everysafeexpanded + +\long\def\safeexpanded#1% why the \noexpand + {\begingroup + \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#1}% + \endgroup + \@@expanded} + +\def\safeedef#1#2% + {\begingroup + \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}% + \endgroup + \let#1\@@expanded} + +\def\safexdef#1#2% + {\begingroup + \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}% + \endgroup + \global\let#1\@@expanded} + +%D You can append protective measures to the token register if +%D needed, as we will do later. + +%D \macros +%D {expandoneargafter,expandtwoargsafter} +%D +%D These two commands make macros more readable by hiding a +%D lot of \type {\expandafter}'s. They expand the arguments +%D after the first command. +%D +%D \starttyping +%D \expandoneargafter \command{\abc} +%D \expandtwoargsafter\command{\abc}{\def} +%D \stoptyping +%D +%D These commands expect the arguments to be macros. + +\def\expandoneargafter #1{\@EA#1\@EA} +\def\expandtwoargsafter#1#2{\@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA#2\@EA}\@EA} + +%D These two do a full expansion: + +\def\fullexpandoneargafter #1#2{\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded} +\def\fullexpandtwoargsafter#1#2#3{\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded} + +%D \macros +%D {gobbleoneargument,gobble...arguments} +%D +%D The next set of macros just do nothing, except that they +%D get rid of a number of arguments. + +\long\def\gobbleoneargument #1{} +\long\def\gobbletwoarguments #1#2{} +\long\def\gobblethreearguments #1#2#3{} +\long\def\gobblefourarguments #1#2#3#4{} +\long\def\gobblefivearguments #1#2#3#4#5{} +\long\def\gobblesixarguments #1#2#3#4#5#6{} +\long\def\gobblesevenarguments #1#2#3#4#5#6#7{} +\long\def\gobbleeightarguments #1#2#3#4#5#6#7#8{} +\long\def\gobbleninearguments #1#2#3#4#5#6#7#8#9{} +\long\def\gobbletenarguments #1{\gobbleninearguments} + +%D \macros +%D {doifnextcharelse} +%D +%D When we started using \TEX\ in the late eighties, our +%D first experiences with programming concerned a simple shell +%D around \LATEX. The commands probably use most at \PRAGMA, +%D are the itemizing ones. One of those few shell commands took +%D care of an optional argument, that enabled us to specify +%D what kind of item symbol we wanted. Without understanding +%D anything we were able to locate a \LATEX\ macro that could +%D be used to inspect the next character. +%D +%D It's this macro that the ancester of the next one presented +%D here. It executes one of two actions, dependant of the next +%D character. Disturbing spaces and line endings, which are +%D normally interpreted as spaces too, are skipped. +%D +%D \starttyping +%D \doifnextcharelse {karakter} {then ...} {else ...} +%D \stoptyping +%D +%D This macro differs from the original in the use of \type +%D {\localnext} because we don't want clashes with \type +%D {\next}. + +\long\def\doifnextcharelse#1#2#3% #1 should not be {} ! + {\let\charactertoken=#1% = needed here + \def\!!stringa{#2}% + \def\!!stringb{#3}% + \futurelet\nexttoken\inspectnextcharacter} + +\def\inspectnextcharacter + {\ifx\nexttoken\blankspace + \@EA\reinspectnextcharacter + \else + \@EA\inspectnextcharacterindeed + \fi} +\def\inspectnextcharacterindeed + {\ifx\nexttoken\charactertoken + \@EA\!!stringa + \else + \@EA\!!stringb + \fi} + +%D Because we will mostly use this macro for testing if the next +%D character is \type {[}, we also make a slightly faster variant +%D as it is not uncommon to have tens of thousands of calls to this +%D test in a run. Of course it also is more convenient to read a +%D trace then. + +\let\nextoptionalcharactertoken=[ + +\long\def\doifnextoptionalelse#1#2% + {\def\nextoptionalcommandyes{#1}% + \def\nextoptionalcommandnop{#2}% + \futurelet\nexttoken\inspectnextoptionalcharacter} + +\def\inspectnextoptionalcharacter + {\ifx\nexttoken\blankspace + \@EA\reinspectnextoptionalcharacter + \else + \@EA\inspectnextoptionalcharacterindeed + \fi} +\def\inspectnextoptionalcharacterindeed + {\ifx\nexttoken\nextoptionalcharactertoken + \@EA\nextoptionalcommandyes + \else + \@EA\nextoptionalcommandnop + \fi} + +\let\nextbgroupcharactertoken\bgroup + +\long\def\doifnextbgroupelse#1#2% + {\def\nextbgroupcommandyes{#1}% + \def\nextbgroupcommandnop{#2}% + \futurelet\nexttoken\inspectnextbgroupcharacter} + +\def\inspectnextbgroupcharacter + {\ifx\nexttoken\blankspace + \@EA\reinspectnextbgroupcharacter + \else + \@EA\inspectnextbgroupcharacterindeed + \fi} +\def\inspectnextbgroupcharacterindeed + {\ifx\nexttoken\nextbgroupcharactertoken + \@EA\nextbgroupcommandyes + \else + \@EA\nextbgroupcommandnop + \fi} + +%D This macro uses some auxiliary macros. Although we were able +%D to program quite complicated things, I only understood these +%D after rereading the \TEX book. The trick is in using a +%D command with a one character name. Such commands differ from +%D the longer ones in the fact that trailing spaces are {\em +%D not} skipped. This enables us to indirectly define a long +%D named macro that gobbles a space. +%D +%D In the first line we define \type{\blankspace}. Next we +%D make \type{\:} equivalent to \type{\reinspect...}. This +%D one||character command is expanded before the next +%D \type{\def} comes into action. This way the space after +%D \type{\:} becomes a delimiter of the longer named +%D \type{\reinspectnextcharacter}. + +\let\next\: + +\def\:{\let\blankspace= } \: + +\def\:{\reinspectnextcharacter} +\expandafter\def\: {\futurelet\nexttoken\inspectnextcharacter} + +\def\:{\reinspectnextoptionalcharacter} +\expandafter\def\: {\futurelet\nexttoken\inspectnextoptionalcharacter} + +\def\:{\reinspectnextbgroupcharacter} +\expandafter\def\: {\futurelet\nexttoken\inspectnextbgroupcharacter} + +\let\:\next + +%D \macros +%D {setvalue,setgvalue,setevalue,setxvalue, +%D letvalue,letgvalue,getvalue,resetvalue, +%D undefinevalue,ignorevalue} +%D +%D \TEX's primitive \type{\csname} can be used to construct +%D all kind of commands that cannot be defined with +%D \type{\def} and \type{\let}. Every macro programmer sooner +%D or later wants macros like these. +%D +%D \starttyping +%D \setvalue {name}{...} = \def\name{...} +%D \setgvalue {name}{...} = \gdef\name{...} +%D \setevalue {name}{...} = \edef\name{...} +%D \setxvalue {name}{...} = \xdef\name{...} +%D \letvalue {name}=\... = \let\name=\... +%D \letgvalue {name}=\... = \global\let\name=\... +%D \getvalue {name} = \name +%D \resetvalue {name} = \def\name{} +%D \stoptyping +%D +%D As we will see, \CONTEXT\ uses these commands many times, +%D which is mainly due to its object oriented and parameter +%D driven character. + +\def\setvalue #1{\expandafter \def\csname#1\endcsname} +\def\setgvalue #1{\expandafter\gdef\csname#1\endcsname} +\def\setevalue #1{\expandafter\edef\csname#1\endcsname} +\def\setxvalue #1{\expandafter\xdef\csname#1\endcsname} +\def\getvalue #1{\csname#1\endcsname} +\def\letvalue #1{\expandafter\let\csname#1\endcsname} +\def\letgvalue #1{\global\expandafter\let\csname#1\endcsname} +\def\resetvalue #1{\expandafter\let\csname#1\endcsname\empty} +\def\undefinevalue#1{\expandafter\let\csname#1\endcsname\undefined} +\def\ignorevalue#1#2{\expandafter\let\csname#1\endcsname\empty} + +%D \macros +%D {globallet,glet} +%D +%D In \CONTEXT\ of May 2000 using \type {\globallet} +%D instead of the two tokens will save us some +%D $300\times4=1200$ bytes of format file on a 32~bit +%D system. So: + +\def\globallet{\global\let} \let\glet\globallet + +%D \macros +%D {donottest,unexpanded} +%D +%D When expansion of a macro gives problems, we can precede it +%D by \type{\donottest}. It seems that protection is one of the +%D burdens of developers of packages, so maybe that's why in +%D \ETEX\ protection is solved in a more robust way. +%D +%D Because we use thi smodule onl in \MKIV, we have removed the +%D old protection code. +%D +%D \starttyping +%D \unexpanded\def\somecommand{... ... ...} +%D \stoptyping + +\let \donottest \firstofoneargument % we need to weed +\let \honorunexpanded \empty % we need to weed +\let \forceunexpanded \empty % we need to weed +\let \resetunexpanded \empty % we need to weed + +\let \unexpanded \normalprotected + +%D \macros +%D {doifundefined,doifdefined, +%D doifundefinedelse,doifdefinedelse, +%D doifalldefinedelse} +%D +%D The standard way of testing if a macro is defined is +%D comparing its meaning with another undefined one, usually +%D \type{\undefined}. To garantee correct working of the next +%D set of macros, \type{\undefined} may never be defined! +%D +%D \starttyping +%D \doifundefined {string} {...} +%D \doifdefined {string} {...} +%D \doifundefinedelse {string} {then ...} {else ...} +%D \doifdefinedelse {string} {then ...} {else ...} +%D \doifalldefinedelse {commalist} {then ...} {else ...} +%D \stoptyping +%D +%D Every macroname that \TEX\ builds gets an entry in the hash +%D table, which is of limited size. It is expected that e-\TeX\ +%D will offer a less memory||consuming alternative. + +%D Although it will probably never be a big problem, it is good +%D to be aware of the difference between testing on a macro +%D name to be build by using \type{\csname} and +%D \type{\endcsname} and testing the \type{\name} directly. +%D +%D \starttyping +%D \expandafter\ifx\csname NameA\endcsname\relax ... \else ... \fi +%D +%D \ifundefined\NameB ... \else ... \fi +%D \stoptyping + +\def\ifundefined#1% ongelukkige naam .. obsolete + {\unless\ifcsname#1\endcsname} + +% \def\p!doifundefined#1% +% {\edef\p!defined{#1}% +% \unless\ifcsname\detokenize\@EA{\p!defined}\endcsname} + +% \def\doifundefinedelse#1% +% {\edef\p!defined{#1}% +% \ifcsname\detokenize\@EA{\p!defined}\endcsname +% \expandafter\secondoftwoarguments +% \else +% \expandafter\firstoftwoarguments +% \fi} + +% \def\doifdefinedelse#1% +% {\edef\p!defined{#1}% +% \ifcsname\detokenize\@EA{\p!defined}\endcsname +% \expandafter\firstoftwoarguments +% \else +% \expandafter\secondoftwoarguments +% \fi} + +% \def\doifundefined#1% +% {\edef\p!defined{#1}% +% \ifcsname\detokenize\@EA{\p!defined}\endcsname +% \expandafter\gobbleoneargument +% \else +% \expandafter\firstofoneargument +% \fi} + +% \def\doifdefined#1% +% {\edef\p!defined{#1}% +% \ifcsname\detokenize\@EA{\p!defined}\endcsname +% \expandafter\firstofoneargument +% \else +% \expandafter\gobbleoneargument +% \fi} + +\ifdefined\suppressifcsnameerror + + \suppressifcsnameerror\plusone + + \def\doifundefinedelse#1% + {\ifcsname#1\endcsname + \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments + \fi} + + \def\doifdefinedelse#1% + {\ifcsname#1\endcsname + \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments + \fi} + + \def\doifundefined#1% + {\ifcsname#1\endcsname + \@EA\gobbleoneargument\else\@EA\firstofoneargument + \fi} + + \def\doifdefined#1% + {\ifcsname#1\endcsname + \@EA\firstofoneargument\else\@EA\gobbleoneargument + \fi} + +\else + + \def\doifundefinedelse#1% + {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname + \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments + \fi} + + \def\doifdefinedelse#1% + {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname + \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments + \fi} + + \def\doifundefined#1% + {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname + \@EA\gobbleoneargument\else\@EA\firstofoneargument + \fi} + + \def\doifdefined#1% + {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname + \@EA\firstofoneargument\else\@EA\gobbleoneargument + \fi} + +\fi + +%D \macros +%D {letbeundefined} +%D +%D Testing for being undefined comes down to testing on \type +%D {\relax} when we use \type {\csname}, but when using \type +%D {\ifx}, we test on being \type {\undefined}! In \ETEX\ we +%D have \type {\ifcsname} and that way of testing on existance +%D is not the same as the one described here. Therefore we +%D introduce: + +\def\letbeundefined#1% potential stack buildup when used \global + {\expandafter\let\csname#1\endcsname\undefined} + +\def\localundefine#1% conditional + {\ifcsname#1\endcsname\expandafter\let\csname#1\endcsname\undefined\fi} + +\def\globalundefine#1% conditional + {\ifcsname#1\endcsname\expandafter\global\let\csname#1\endcsname\undefined\fi} + +%D Beware, being \type {\undefined} in \ETEX\ means that the macro +%D {\em is} defined! + +%D When we were developing the scientific units module, we +%D encountered different behavior in text and math mode, which +%D was due to this grouping subtilities. We therefore decided +%D to use \type{\begingroup} instead of \type{\bgroup}. + +\def\docheckonedefined#1% + {\ifcsname#1\endcsname\else + \donefalse + \expandafter\quitcommalist % added + \fi} + +\def\doifalldefinedelse#1% + {\begingroup + \donetrue \processcommalist[#1]\docheckonedefined + \ifdone + \endgroup\expandafter\firstoftwoarguments + \else + \endgroup\expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doif,doifelse,doifnot, +%D donottest} +%D +%D Programming in \TEX\ differs from programming in procedural +%D languages like \MODULA. This means that one --- well, let me +%D speek for myself --- tries to do the things in the well +%D known way. Therefore the next set of \type{\ifthenelse} +%D commands were between the first ones we needed. A few years +%D later, the opposite became true: when programming in +%D \MODULA, I sometimes miss handy things like grouping, +%D runtime redefinition, expansion etc. While \MODULA\ taught +%D me to structure, \TEX\ taught me to think recursive. +%D +%D \starttyping +%D \doif {string1} {string2} {...} +%D \doifnot {string1} {string2} {...} +%D \doifelse {string1} {string2} {then ...}{else ...} +%D \stoptyping +%D +%D When expansion gives problems, we can precede the +%D troublemaker with \type{\donottest}. + +\long\def\doif#1#2% + {\edef\!!stringa{#1}\edef\!!stringb{#2}% + \ifx\!!stringa\!!stringb + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\doifnot#1#2% + {\edef\!!stringa{#1}\edef\!!stringb{#2}% + \ifx\!!stringa\!!stringb + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\long\def\doifelse#1#2% + {\edef\!!stringa{#1}\edef\!!stringb{#2}% + \ifx\!!stringa\!!stringb + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifempty,doifemptyelse,doifnotempty} +%D +%D We complete our set of conditionals with: +%D +%D \starttyping +%D \doifempty {string} {...} +%D \doifnotempty {string} {...} +%D \doifemptyelse {string} {then ...} {else ...} +%D \stoptyping +%D +%D This time, the string is not expanded. + +\long\def\doifemptyelse#1% + {\def\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\long\def\doifempty#1% + {\def\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\doifnotempty#1% + {\def\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +%D \macros +%D {doifinset,doifnotinset,doifinsetelse} +%D +%D We can check if a string is present in a comma separated +%D set of strings. Depending on the result, some action is +%D taken. +%D +%D \starttyping +%D \doifinset {string} {string,...} {...} +%D \doifnotinset {string} {string,...} {...} +%D \doifinsetelse {string} {string,...} {then ...} {else ...} +%D \stoptyping + +% !0nop=\doifinsetelse{ccc}{,}{yes}{nop} +% !0nop=\doifinsetelse{ccc}{,,}{yes}{nop} +% !0nop=\doifinsetelse{ccc}{,,,}{yes}{nop} + +% !1nop=\doifinsetelse{}{}{yes}{nop} +% !2yes=\doifinsetelse{aaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop} +% !3nop=\doifinsetelse{aaa}{bbb}{yes}{nop} +% !4yes=\doifinsetelse{aaa}{aaa}{yes}{nop} +% !5nop=\doifinsetelse{aaaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop} +% !6nop=\doifinsetelse{}{}{yes}{nop} +% !7nop=\doifinsetelse{}{aaa}{yes}{nop} +% !8nop=\doifinsetelse{aaa}{}{yes}{nop} + +% !1=\doifinset{}{}{yes} +% !2yes=\doifinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes} +% !3=\doifinset{aaa}{bbb}{yes} +% !4yes=\doifinset{aaa}{aaa}{yes} +% !5=\doifinset{}{}{yes} +% !6=\doifinset{aaa}{}{yes} + +% !1yes=\doifnotinset{}{}{yes} +% !2=\doifnotinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes} +% !3yes=\doifnotinset{aaa}{bbb}{yes} +% !4=\doifnotinset{aaa}{aaa}{yes} +% !5yes=\doifnotinset{}{}{yes} +% !6yes=\doifnotinset{aaa}{}{yes} + +\def\rightoptionalbracket{]} + +\long\def\doquitifiteminsetelse#1],\relax{\firstoftwoarguments} +\long\def\doquitifiteminset #1],\relax{\firstofoneargument} +\long\def\doquitifitemnotinset #1],\relax{\gobbleoneargument} + +\long\def\redoifinsetelse{\expandafter\docheckifiteminsetelse\!!stringb,],\relax} +\long\def\redoifinset {\expandafter\docheckifiteminset \!!stringb,],\relax} +\long\def\redoifnotinset {\expandafter\docheckifitemnotinset \!!stringb,],\relax} + +\long\def\doifinsetelse#1% make this two step too + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\thirdofthreearguments + \else + \expandafter\dodoifinsetelse + \fi} +\long\def\dodoifinsetelse#1% + {\edef\!!stringb{#1}% + \ifx\!!stringb\empty + \expandafter\secondoftwoarguments + \else + \expandafter\redoifinsetelse + \fi} + +\long\def\doifinset#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\gobbletwoarguments + \else + \expandafter\dodoifinset + \fi} +\long\def\dodoifinset#1% + {\edef\!!stringb{#1}% + \ifx\!!stringb\empty + \expandafter\gobbleoneargument + \else + \expandafter\redoifinset + \fi} + +\long\def\doifnotinset#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\secondoftwoarguments + \else + \expandafter\dodoifnotinset + \fi} +\long\def\dodoifnotinset#1% + {\edef\!!stringb{#1}% + \ifx\!!stringb\empty + \expandafter\firstofoneargument + \else + \expandafter\redoifnotinset % ...]{true} + \fi} + +\def\docheckifiteminsetelse#1,#2% #2 eats up preceding space + {\edef\!!stringb{#1}% + \ifx\!!stringb\empty + \expandafter\docheckifiteminsetelse + \else + \expandafter\dodocheckifiteminsetelse + \fi#2} +\def\dodocheckifiteminsetelse + {\ifx\!!stringb\rightoptionalbracket + \expandafter\thirdofthreearguments + \else + \expandafter\dododocheckifiteminsetelse + \fi} +\def\dododocheckifiteminsetelse + {\ifx\!!stringa\!!stringb + \expandafter\doquitifiteminsetelse + \else + \expandafter\docheckifiteminsetelse + \fi} + +\def\docheckifiteminset#1,#2% #2 eats up preceding space + {\edef\!!stringb{#1}% + \ifx\!!stringb\empty + \expandafter\docheckifiteminset + \else + \expandafter\dodocheckifiteminset + \fi#2} +\def\dodocheckifiteminset + {\ifx\!!stringb\rightoptionalbracket + \expandafter\gobbletwoarguments + \else + \expandafter\dododocheckifiteminset + \fi} +\def\dododocheckifiteminset + {\ifx\!!stringa\!!stringb + \expandafter\doquitifiteminset + \else + \expandafter\docheckifiteminset + \fi} + +\def\docheckifitemnotinset#1,#2% #2 eats up preceding space + {\edef\!!stringb{#1}% + \ifx\!!stringb\empty + \expandafter\docheckifitemnotinset + \else + \expandafter\dodocheckifitemnotinset + \fi#2} +\def\dodocheckifitemnotinset + {\ifx\!!stringb\rightoptionalbracket + \expandafter\secondoftwoarguments + \else + \expandafter\dododocheckifitemnotinset + \fi} +\def\dododocheckifitemnotinset + {\ifx\!!stringa\!!stringb + \expandafter\doquitifitemnotinset + \else + \expandafter\docheckifitemnotinset + \fi} + +%D \macros +%D {doifcommon,doifnotcommon,doifcommonelse} +%D +%D Probably the most time consuming tests are those that test +%D for overlap in sets of strings. +%D +%D \starttyping +%D \doifcommon {string,...} {string,...} {...} +%D \doifnotcommon {string,...} {string,...} {...} +%D \doifcommonelse {string,...} {string,...} {then ...} {else ...} +%D \stoptyping + +% !1yes=\doifcommonelse{aaa,bbb,ccc}{aaa,bbb,ccc}{yes}{nop} +% !2nop=\doifcommonelse{aaa,bbb,ccc}{ddd,eee,fff}{yes}{nop} +% !3nop=\doifcommonelse{aaa}{ddd,eee,fff}{yes}{nop} +% !4yes=\doifcommonelse{aaa}{aaa}{yes}{nop} +% !5nop=\doifcommonelse{bbb}{aaa}{yes}{nop} +% !6nop=\doifcommonelse{}{aaa,bbb,ccc}{yes}{nop} +% !7nop=\doifcommonelse{aaa,bbb,ccc}{}{yes}{nop} +% !8nop=\doifcommonelse{}{}{yes}{nop} + +% !9nop=\doifcommonelse{,,}{,,}{yes}{nop} +% !9yes=\doifcommonelse{,a,}{,a,}{yes}{nop} +% !9yes=\doifcommonelse{,,a,}{,a,}{yes}{nop} +% !9yes=\doifcommonelse{,a,}{,,a,}{yes}{nop} +% !9yes=\doifcommonelse{,a,}{,,,a,}{yes}{nop} +% !9yes=\doifcommonelse{,,a,}{,,,a,}{yes}{nop} + +% \def\p!doifcommonelse#1#2#3#4% +% {\donefalse +% \def\p!docommoncheck##1{\doifinset{##1}{#4}\donetrue\ifdone\quitcommalist\fi}% +% \processcommalist[#3]\p!docommoncheck +% \ifdone\expandafter#1\else\expandafter#2\fi} +% +% \def\doifcommonelse +% {\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments} +% +% \def\doifcommon +% {\p!doifcommonelse\firstofoneargument \gobbleoneargument} +% +% \def\doifnotcommon +% {\p!doifcommonelse\gobbleoneargument \firstofoneargument} + +\long\def\doquitifcommonelse#1],\relax#2],\relax{\firstoftwoarguments} + +\long\def\doquitifcommonelsenop{\secondoftwoarguments} + +\def\docheckifcommonelseone#1,#2% + {\edef\!!stringc{#1}% + \ifx\!!stringc\rightoptionalbracket + \expandafter\thirdofthreearguments + \else + \expandafter\p!docommoncheck + \fi#2} + +\def\docheckifcommonelsetwo#1,#2% we can do an empty #1 check too + {\edef\commalistelement{#1}% + \ifx\commalistelement\rightoptionalbracket + \expandafter\redocheckifcommonelseone + \else + \expandafter\dodocheckifcommonelsetwo + \fi#2} + +\def\dodocheckifcommonelsetwo + {\ifx\commalistelement\empty + \expandafter\docheckifcommonelsetwo + \else + \expandafter\dododocheckifcommonelsetwo + \fi} + +\def\dododocheckifcommonelsetwo + {\ifx\!!stringc\commalistelement + \expandafter\doquitifcommonelse + \else + \expandafter\docheckifcommonelsetwo + \fi} + +\def\redocheckifcommonelseone#1{\docheckifcommonelseone} + +\def\p!doifcommonelse#1#2#3#4% + {\edef\!!stringa{#3}% + \edef\!!stringb{#4}% + \ifx\!!stringa\empty + \expandafter\secondoftwoarguments + \else\ifx\!!stringb\empty + \expandafter\expandafter\expandafter\secondoftwoarguments + \else + \expandafter\expandafter\expandafter\pp!doifcommonelse + \fi\fi + #1#2} + +% \def\p!doifcommonelse#1#2#3% +% {\edef\!!stringa{#3}% +% \ifx\!!stringa\empty +% \expandafter\secondofthreearguments +% \else +% \expandafter\p!dodoifcommonelse +% \fi +% #1#2} % #4 + +% \def\p!dodoifcommonelse#1#2#3% +% {\edef\!!stringb{#3}% +% \ifx\!!stringb\empty +% \expandafter\secondoftwoarguments +% \else +% \expandafter\pp!doifcommonelse +% \fi#1#2} + +\def\pp!doifcommonelse + {\def\p!docommoncheck{\expandafter\docheckifcommonelsetwo\!!stringb,],\relax}% + \expandafter\docheckifcommonelseone\!!stringa,],\relax} + +\def\doifcommonelse{\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments} +\def\doifcommon {\p!doifcommonelse\firstofoneargument \gobbleoneargument } +\def\doifnotcommon {\p!doifcommonelse\gobbleoneargument \firstofoneargument } + +%D \macros +%D {processcommalist,processcommacommand,quitcommalist, +%D processcommalistwithparameters} +%D +%D We've already seen some macros that take care of comma +%D separated lists. Such list can be processed with +%D +%D \starttyping +%D \processcommalist[string,string,...]\commando +%D \stoptyping +%D +%D The user supplied command \type{\commando} receives one +%D argument: the string. This command permits nesting and +%D spaces after commas are skipped. Empty sets are no problem. +%D +%D \startbuffer +%D \def\dosomething#1{(#1)} +%D +%D 1: \processcommalist [\hbox{$a,b,c,d,e,f$}] \dosomething \par +%D 2: \processcommalist [{a,b,c,d,e,f}] \dosomething \par +%D 3: \processcommalist [{a,b,c},d,e,f] \dosomething \par +%D 4: \processcommalist [a,b,{c,d,e},f] \dosomething \par +%D 5: \processcommalist [a{b,c},d,e,f] \dosomething \par +%D 6: \processcommalist [{a,b}c,d,e,f] \dosomething \par +%D 7: \processcommalist [] \dosomething \par +%D 8: \processcommalist [{[}] \dosomething \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D Before we show the result, we present the macro's: + +\newcount\commalevel + +\def\dododoprocesscommaitem + {\csname\s!next\the\commalevel\endcsname} + +% \def\dodoprocesscommaitem +% {\ifx\nexttoken\blankspace +% \@EA\redoprocesscommaitem +% \else\ifx\nexttoken]% +% \@EAEAEA\gobbleoneargument +% \else +% \@EAEAEA\dododoprocesscommaitem +% \fi\fi} + +\def\dodoprocesscommaitem + {\ifx\nexttoken\blankspace + \@EA\redoprocesscommaitem + \else + \@EA\dodoprocesscommaitemindeed + \fi} +\def\dodoprocesscommaitemindeed + {\ifx\nexttoken]% + \@EA\gobbleoneargument + \else + \@EA\dododoprocesscommaitem + \fi} + +\def\doprocesscommaitem + {\futurelet\nexttoken\dodoprocesscommaitem} + +%D Empty arguments are not processed. Empty items (\type{,,}) +%D however are treated. We have to check for the special case +%D \type{[{a,b,c}]}. + +\def\processcommalist[% + {\futurelet\nexttoken\docheckcommaitem} + +\def\docheckcommaitem + {\ifx\nexttoken]% + \expandafter\gobblethreearguments + \else + \expandafter\doprocesscommalist + \fi + \relax} % this one preserved the next {} + +\def\doprocesscommalist#1]#2% + {\global\advance\commalevel \plusone + \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% + {#2{##1}\doprocesscommaitem}% + \@EA\dodoprocesscommaitem\gobbleoneargument#1,]\relax + \global\advance\commalevel \minusone } + +%D One way of quitting a commalist halfway is: + +\def\quitcommalist + {\begingroup\let\doprocesscommaitem\doquitcommalist} + +\def\doquitcommalist#1]% + {\endgroup} + +\def\quitprevcommalist + {\begingroup\let\doprocesscommaitem\doquitprevcommalist} + +\def\doquitprevcommalist#1]% + {\let\doprocesscommaitem\doquitcommalist} + +%D The hack we used for checking the next character +%D \type {\doifnextcharelse} is also used here. + +\def\:{\redoprocesscommaitem} + +\expandafter\def\: {\futurelet\nexttoken\dodoprocesscommaitem} + +%D The previous examples lead to: +%D +%D \getbuffer + +%D When a list is saved in a macro, we can use a construction +%D like: +%D +%D \starttyping +%D \expandafter\processcommalist\expandafter[\list]\command +%D \stoptyping +%D +%D Such solutions suit most situations, but we wanted a bit +%D more. +%D +%D \starttyping +%D \processcommacommand[string,\stringset,string]\commando +%D \stoptyping +%D +%D where \type{\stringset} is a predefined set, like: +%D +%D \starttyping +%D \def\first{aap,noot,mies} +%D \def\second{laatste} +%D +%D \processcommacommand[\first]\message +%D \processcommacommand[\first,second,third]\message +%D \processcommacommand[\first,between,\second]\message +%D \stoptyping +%D +%D Commands that are part of the list are expanded, so the +%D use of this macro has its limits. + +% \def\processcommacommand[#1]% +% {\expanded{\processcommalist[#1]}} + +\def\processcommacommand[#1]% + {\expandafter\processcommalist\expandafter[\normalexpanded{#1}]} + +%D The argument to \type{\command} is not delimited. Because +%D we often use \type{[]} as delimiters, we also have: +%D +%D \starttyping +%D \processcommalistwithparameters[string,string,...]\command +%D \stoptyping +%D +%D where \type{\command} looks like: +%D +%D \starttyping +%D \def\command[#1]{... #1 ...} +%D \stoptyping + +\def\processcommalistwithparameters[#1]#2% + {\def\docommand##1{#2[##1]}% + \processcommalist[#1]\docommand} + +%D \macros +%D {processaction, +%D processfirstactioninset, +%D processallactionsinset} +%D +%D \CONTEXT\ makes extensive use of a sort of case or switch +%D command. Depending of the presence of one or more provided +%D items, some actions is taken. These macros can be nested +%D without problems. +%D +%D \starttyping +%D \processaction [x] [a=>\a,b=>\b,c=>\c] +%D \processfirstactioninset [x,y,z] [a=>\a,b=>\b,c=>\c] +%D \processallactionsinset [x,y,z] [a=>\a,b=>\b,c=>\c] +%D \stoptyping +%D +%D We can supply both a \type{default} action and an action +%D to be undertaken when an \type{unknown} value is met: +%D +%D \starttyping +%D \processallactionsinset +%D [x,y,z] +%D [ a=>\a, +%D b=>\b, +%D c=>\c, +%D default=>\default, +%D unknown=>\unknown{... \commalistelement ...}] +%D \stoptyping +%D +%D When \type{#1} is empty, this macro scans list \type{#2} for +%D the keyword \type{default} and executed the related action +%D if present. When \type{#1} is non empty and not in the list, +%D the action related to \type{unknown} is executed. Both +%D keywords must be at the end of list \type{#2}. Afterwards, +%D the actually found keyword is available in +%D \type{\commalistelement}. An advanced example of the use of +%D this macro can be found in \PPCHTEX, where we completely +%D rely on \TEX\ for interpreting user supplied keywords like +%D \type{SB}, \type{SB1..6}, \type{SB125} etc. + +\newcount\processlevel + +\def\p!compareprocessactionA[#1=>#2][#3]% + {\edef\!!stringb{#1}% + \ifx\!!stringb\s!default + \let\commalistelement\empty + #2% + \fi} + +% met \quitcommalist tot meer dan 25\% sneller + +\def\p!compareprocessactionB[#1=>#2][#3]% + {\expandedaction\!!stringb{#1}% + \ifx\!!stringa\!!stringb + \def\commalistelement{#3}% + #2% + \expandafter\quitcommalist + \else + \edef\!!stringb{#1}% + \ifx\!!stringb\s!unknown + \def\commalistelement{#3}% beware of loops + #2% + \fi + \fi} + +\def\processaction[#1]#2[% + {\expandedaction\!!stringa{#1}% + \ifx\!!stringa\empty + \let\p!compareprocessaction\p!compareprocessactionA + \else + \let\p!compareprocessaction\p!compareprocessactionB + \fi + \def\p!doprocessaction##1% + {\p!compareprocessaction[##1][#1]}% + \processnextcommalist\relax\expandactions\p!doprocessaction[} + +\def\p!compareprocessactionC[#1=>#2][#3]% + {\expandedaction\!!stringa{#1}% + \expandedaction\!!stringb{#3}% + \ifx\!!stringa\!!stringb + \def\commalistelement{#3}% + #2% + \expandafter\quitprevcommalist + \else + \edef\!!stringa{#1}% + \ifx\!!stringa\s!unknown + \def\commalistelement{#3}% + #2% + \fi + \fi} + +\def\processfirstactioninset[#1]% + {\expandedaction\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\processaction + \else + \expandafter\processfirstactionsinsetindeed + \fi + [#1]} + +\def\processfirstactionsinsetindeed[#1]#2[#3]% + {\def\p!doprocessaction##1% + {\def\p!dodoprocessaction####1% + {\p!compareprocessactionC[####1][##1]}% + \processcommalist[#3]\p!dodoprocessaction}% + \processcommalist[#1]\p!doprocessaction + \expandactions} + +\def\p!compareprocessactionD[#1=>#2][#3]% + {\expandedaction\!!stringa{#1}% + \expandedaction\!!stringb{#3}% + \ifx\!!stringa\!!stringb + \def\commalistelement{#3}% + #2% + \expandafter\quitcommalist + \else + \edef\!!stringa{#1}% + \ifx\!!stringa\s!unknown + \def\commalistelement{#3}% + #2% + \fi + \fi} + +\def\doprocessallactionsinset + {\csname\s!do\the\processlevel\endcsname} + +\def\processallactionsinset[#1]% + {\expandedaction\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\processaction + \else + \expandafter\processallactionsinsetindeed + \fi + [#1]} + +\def\processallactionsinsetindeed[#1]#2[#3]% + {\advance\processlevel \plusone + \expandafter\def\csname\s!do\the\processlevel\endcsname##1% + {\def\p!dodoprocessaction####1% + {\p!compareprocessactionD[####1][##1]}% + \processcommalist[#3]\p!dodoprocessaction}% + \processcommalist[#1]\doprocessallactionsinset + \advance\processlevel \minusone + \expandactions} + +%D These macros use: + +\def\processnextcommalist#1#2#3[#4#5]% + {#1% + \let\nexttoken#4% + \global\advance\commalevel \plusone + \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% + {#3{##1}\doprocesscommaitem}% + \dodoprocesscommaitem#4#5,]\relax + \global\advance\commalevel \minusone + #2} + +%D \macros +%D {unexpandedprocessaction, +%D unexpandedprocessfirstactioninset, +%D unexpandedprocessallactionsinset} +%D +%D Now what are those expansion commands doing there. Well, +%D sometimes we want to compare actions that may consist off +%D commands (i.e. are no constants). In such occasions we can +%D use the a bit slower alternatives: + +\def\unexpandedprocessfirstactioninset{\dontexpandactions\processfirstactioninset} +\def\unexpandedprocessaction {\dontexpandactions\processaction} +\def\unexpandedprocessallactionsinset {\dontexpandactions\processallactionsinset} + +%D By default we expand actions: + +\def\expandactions{\let\expandedaction\edef} \expandactions + +%D But when needed we convert the strings to meaningful +%D sequences of characters. + +\def\unexpandedaction#1>{} + +\def\noexpandedaction#1#2% + {\def\@@convertedargument{#2}% + \@EA\edef\@EA#1\@EA{\@EA\unexpandedaction\meaning\@@convertedargument}} + +\def\dontexpandactions + {\let\expandedaction\noexpandedaction} + +%D \macros +%D {getfirstcharacter, firstcharacter, remainingcharacters, doiffirstcharacter} +%D +%D Sometimes the action to be undertaken depends on the +%D next character. This macro get this character and puts it in +%D \type{\firstcharacter}. +%D +%D \starttyping +%D \getfirstcharacter {string} +%D \stoptyping +%D +%D A two step expansion is used to prevent problems with +%D complicated arguments, for instance arguments that +%D consist of two or more expandable tokens. + +\def\dogetfirstcharacter#1#2\relax + {\def\firstcharacter{#1}% + \def\remainingcharacters{#2}} + +\def\getfirstcharacter#1% + {\edef\!!stringa{#1}% + \expandafter\dogetfirstcharacter\!!stringa\relax} + +\def\doiffirstcharelse#1#2% char string +% kort (maar onleesbaar) +% {\expanded{\dogetfirstcharacter#2}\\\doifelse{#1}\firstcharacter} +% korter (en begrijpelijk)) + {\getfirstcharacter{#2}\doifelse{#1}\firstcharacter} +% snel (maar zelden gebruikt, dus niet zo belangrijk) +% {\getfirstcharacter{#2}% +% \edef\!!stringa{#1}% +% \ifx\!!stringa\firstcharacter +% \expandafter\firstoftwoarguments +% \else +% \expandafter\secondoftwoarguments +% \fi} + +%D \macros +%D {doifinstringelse, doifincsnameelse} +%D +%D We can check for the presence of a substring in a given +%D sequence of characters. +%D +%D \starttyping +%D \doifinsetelse {substring} {string} {then ...} {else ...} +%D \stoptyping + +\long\def\doifinstringelse#1% + {\edef\@@@instring{#1}% expand #1 here + \ifx\@@@instring\empty + \@EA\thirdofthreearguments + \else + \@EA\dodoifinstringelse + \fi} + +\long\def\dodoifinstringelse#1% + {\p!doifinstringelse\@@@instring{#1}% + \@EA\firstoftwoarguments + \else + \@EA\secondoftwoarguments + \fi} + +\long\def\doifinstring#1%% + {\edef\@@@instring{#1}% expand #1 here + \ifx\@@@instring\empty + \@EA\gobbletwoarguments + \else + \@EA\dodoifinstring + \fi} + +\long\def\dodoifinstring#1% + {\p!doifinstringelse\@@@instring{#1}% + \@EA\firstofoneargument + \else + \@EA\gobbleoneargument + \fi} + +\long\def\doifnotinstring#1%% + {\edef\@@@instring{#1}% expand #1 here + \ifx\@@@instring\empty + \@EA\gobbletwoarguments + \else + \@EA\dodoifnotinstring + \fi} + +\long\def\dodoifnotinstring#1% + {\p!doifinstringelse\@@@instring{#1}% + \@EA\gobbleoneargument + \else + \@EA\firstofoneargument + \fi} + +% replaces prev + +% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} +% {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here +% \expanded{\pp!doifinstringelse#2#1}@@\war} % expand #2 here + +\long\def\p!doifinstringelse#1#2% ##2 can be {abc} + {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here + \expandafter\pp!doifinstringelse\normalexpanded{#2#1}@@\war} % expand #2 here + +% faster but at some costs +% +% \def\setp!doifinstringelse#1#2% ##2 can be {abc} +% {\long\expandafter\gdef\csname @diie:#1\@EA\endcsname\@EA##\@EA1#1##2##3\war{\unless\if##2@}}% expand #1 here +% +% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} +% {\ifcsname @diie:#1\endcsname \else +% \setp!doifinstringelse{#1}{#2}% +% \fi +% \csname @diie:#1\expandafter\endcsname\normalexpanded{#2#1}@@\war} % expand #2 here + +%D The next alternative proved to be upto twice as fast on +%D tasks like checking reserved words in pretty verbatim +%D typesetting! This is mainly due to the fact that passing +%D (expanded) strings is much slower that passing a macro. +%D +%D \starttyping +%D \doifincsnameelse {substring} {\string} {then ...} {else ...} +%D \stoptyping +%D +%D Where \type{\doifinstringelse} does as much expansion as +%D possible, the latter alternative does minimal (one level) +%D expansion. + +\long\def\p!doifincsnameelse#1#2% + {\long\def\pp!doifincsnameelse##1#1##2##3\war + {\unless\if##2@}% + \@EA\pp!doifincsnameelse#2#1@@\war} + +\long\def\doifincsnameelse#1#2% % #3#4% + {\edef\@@@instring{#1}% + \@EA\p!doifincsnameelse\@EA{\@@@instring}{#2}% % #3\else#4\fi} + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifnumberelse} +%D +%D The next macro executes a command depending of the outcome +%D of a test on numerals. This is probably one of the fastest +%D test possible, exept from a less robust 10||step +%D \type{\if}||ladder or some tricky \type{\lcode} checking. +%D +%D \starttyping +%D \doifnumberelse {string} {then ...} {else ...} +%D \stoptyping +%D +%D The macro accepts \type{123}, \type{abc}, \type{{}}, +%D \type{\getal} and \type{\the\count...}. This macro is a +%D rather dirty one. + +\long\def\doifnumberelse#1% does not accept counters + {\ifcase0\ifcase1#1\or\or\or\or\or\or\or\or\or\else1\fi\space + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +%D \macros +%D {makerawcommalist, +%D rawdoinsetelse, +%D rawprocesscommalist, +%D rawprocessaction} +%D +%D Some of the commands mentioned earlier are effective but +%D slow. When one is desperately in need of faster alternatives +%D and when the conditions are predictable safe, the \type{\raw} +%D alternatives come into focus. A major drawback is that +%D they do not take \type{\c!constants} into account, simply +%D because no expansion is done. This is no problem with +%D \type{\rawprocesscommalist}, because this macro does not +%D compare anything. Expandable macros are permitted as search +%D string. +%D +%D \starttyping +%D \makerawcommalist[string,string,...]\stringlist +%D \rawdoifinsetelse{string}{string,...}{...}{...} +%D \rawprocesscommalist[string,string,...]\commando +%D \rawprocessaction[x][a=>\a,b=>\b,c=>\c] +%D \stoptyping +%D +%D Spaces embedded in the list, for instance after commas, +%D spoil the search process. The gain in speed depends on the +%D length of the argument (the longer the argument, the less +%D we gain). + +\def\makerawcommalist[#1]#2% use \processnext ... here + {\def\domakerawcommalist##1% we don't expand ##1 + {\ifx#2\empty + \def#2{##1}% + \else + \@EA\def\@EA#2\@EA{#2,##1}% + \fi}% + \let#2\empty + \processcommalist[#1]\domakerawcommalist} + +\def\rawprocesscommaitem#1,#2% #2 eats up preceding space + {\if]#1\else + \csname\s!next\the\commalevel\endcsname{#1}% + \expandafter\rawprocesscommaitem + \fi#2} + +\def\rawprocesscommalist[#1]#2% accepteert ook [\cs] + {\global\advance\commalevel \plusone + \expandafter\let\csname\s!next\the\commalevel\endcsname#2% + \expandafter\rawprocesscommaitem#1,],% \relax + \global\advance\commalevel \minusone } + +\def\rawprocesscommacommand[#1]% not really needed + {\expanded{\rawprocesscommalist[#1]}} + +% \def\rawdoifinsetelse#1#2{\doifinstringelse{,#1,}{,#2,}} +% \def\rawdoifinset #1#2{\doifinstring {,#1,}{,#2,}} + +\def\@@rawempty{,,} + +\long\def\rawdoifinsetelse#1% + {\edef\@@@instring{,#1,}% expand #1 here + \ifx\@@@instring\@@rawempty + \@EA\thirdofthreearguments + \else + \@EA\rawdodoifinsetelse + \fi} + +\long\def\rawdodoifinsetelse#1% + {\p!doifinstringelse\@@@instring{,#1,}% + \@EA\firstoftwoarguments + \else + \@EA\secondoftwoarguments + \fi} + +\long\def\rawdoifinset#1% + {\edef\@@@instring{,#1,}% expand #1 here + \ifx\@@@instring\@@rawempty + \@EA\gobbletwoarguments + \else + \@EA\rawdodoifinset + \fi} + +\long\def\rawdodoifinset#1%% + {\p!doifinstringelse\@@@instring{,#1,}% + \@EA\firstofoneargument + \else + \@EA\gobbleoneargument + \fi} + +%D Some more raw material: + +\def\p!rawprocessaction[#1][#2]% + {\def\pp!rawprocessaction##1,#1=>##2,##3\war% + {\if##3@\else + \def\!!processaction{##2}% + \fi}% + \pp!rawprocessaction,#2,#1=>,@\war} + +\def\rawprocessaction[#1]#2[#3]% + {\edef\!!stringa{#1}% + \edef\!!stringb{undefined}% better \!!undefined + \let\!!processaction\!!stringb + \ifx\!!stringa\empty + \@EA\p!rawprocessaction\@EA[\s!default][#3]% + \else + \expandafter\p!rawprocessaction\expandafter[\!!stringa][#3]% + \ifx\!!processaction\!!stringb + \@EA\p!rawprocessaction\@EA[\s!unknown][#3]% + \fi + \fi + \ifx\!!processaction\!!stringb + \else + \!!processaction + \fi} + +%D When we process the list \type{a,b,c,d,e}, the raw routine +%D takes over 30\% less time, when we feed $20+$ character +%D strings we gain about 20\%. Alternatives which use +%D \type{\futurelet} perform worse. Part of the speedup is +%D due to the \type{\let} and \type{\expandafter} in the test. + +%D \macros +%D {dosetvalue,dosetevalue,dosetgvalue,docopyvalue,doresetvalue, +%D dogetvalue} +%D +%D When we are going to do assignments, we have to take +%D multi||linguality into account. For the moment we keep +%D things simple and single||lingual. +%D +%D \starttyping +%D \dosetvalue {label} {variable} {value} +%D \dosetevalue {label} {variable} {value} +%D \dosetgvalue {label} {variable} {value} +%D \docopyvalue {to label} {from label} {variable} +%D \doresetvalue {label} {variable} +%D \stoptyping +%D +%D These macros are in fact auxiliary ones and are not meant +%D for use outside the assignment macros. + +\def\dosetvalue#1#2% #3 + {\@EA\def\csname#1#2\endcsname} % {#3}} + +\def\dosetevalue#1#2% #3 + {\@EA\edef\csname#1#2\endcsname} % {#3}} + +\def\dosetgvalue#1#2% #3 + {\@EA\gdef\csname#1#2\endcsname} % {#3}} + +\def\doresetvalue#1#2% + {\@EA\let\csname#1#2\endcsname\empty} + +\def\doignorevalue#1#2#3% + {\@EA\let\csname#1#2\endcsname\empty} + +\def\docopyvalue#1#2#3% + {\@EA\def\csname#1#3\endcsname{\csname#2#3\endcsname}} + +%D \macros +%D {doassign,undoassign,doassignempty} +%D +%D Assignments are the backbone of \CONTEXT. Abhorred by the +%D concept of style file hacking, we took a considerable effort +%D in building a parameterized system. Unfortunately there is a +%D price to pay in terms of speed. Compared to other packages +%D and taking the functionality of \CONTEXT\ into account, the +%D total size of the format file is still very acceptable. Now +%D how are these assignments done. +%D +%D Assignments can be realized with: +%D +%D \starttyping +%D \doassign[label][variable=value] +%D \undoassign[label][variable=value] +%D \stoptyping +%D +%D and: +%D +%D \starttyping +%D \doassignempty[label][variable=value] +%D \stoptyping +%D +%D Assignments like \type{\doassign} are compatible with: +%D +%D \starttyping +%D \def\labelvariable{value} +%D \stoptyping +%D +%D We do check for the presence of an \type{=} and loudly +%D complain of it's missed. We will redefine this macro later +%D on, when a more advanced message mechanism is implemented. + +\newif\iferrorisfatal + +\def\waitonfatalerror + {\iferrorisfatal\wait\fi} + +\def\showassignerror#1#2% + {\writestatus{setup}{missing or ungrouped '=' after '#1' in line #2}% + \waitonfatalerror} + +\def\doassignempty[#1][#2=#3]% + {\ifcsname#1#2\endcsname\else\dosetvalue{#1}{#2}{#3}\fi} + +%D \macros +%D {getparameters,geteparameters,getgparameters, +%D forgetparameters} +%D +%D Using the assignment commands directly is not our +%D ideal of user friendly interfacing, so we take some further +%D steps. +%D +%D \starttyping +%D \getparameters [label] [...=...,...=...] +%D \forgetparameters [label] [...=...,...=...] +%D \stoptyping +%D +%D Again, the label identifies the category a variable +%D belongs to. The second argument can be a comma separated +%D list of assignments. +%D +%D \starttyping +%D \getparameters +%D [demo] +%D [alfa=1, +%D beta=2] +%D \stoptyping +%D +%D is equivalent to +%D +%D \starttyping +%D \def\demoalfa{1} +%D \def\demobeta{2} +%D \stoptyping +%D +%D +%D In the pre||multi||lingual stadium \CONTEXT\ took the next +%D approach. With +%D +%D \starttyping +%D \def\??demo {@@demo} +%D \def\!!alfa {alfa} +%D \def\!!beta {beta} +%D \stoptyping +%D +%D calling +%D +%D \starttyping +%D \getparameters +%D [\??demo] +%D [\!!alfa=1, +%D \!!beta=2] +%D \stoptyping +%D +%D lead to: +%D +%D \starttyping +%D \def\@@demoalfa{1} +%D \def\@@demobeta{2} +%D \stoptyping +%D +%D Because we want to be able to distinguish the \type{!!} +%D pre||tagged user supplied variables from internal +%D counterparts, we will introduce a slightly different tag in +%D the multi||lingual modules. There we will use \type{c!} or +%D \type{v!}, depending on the context. +%D +%D By calling \type{\p!doassign} directly, we save ourselves +%D some argument passing and gain some speed. Whatever +%D optimizations we do, this command will always be one of the +%D bigger bottlenecks. +%D +%D The alternative \type{\geteparameters} --- it's funny to +%D see that this alternative saw the light so lately --- can be +%D used to do expanded assigments. + +\let\currentvalue\empty + +\def\getparameters {\dogetparameters\dosetvalue} +\def\geteparameters {\dogetparameters\dosetevalue} +\def\getgparameters {\dogetparameters\dosetgvalue} +\def\forgetparameters{\dogetparameters\doignorevalue} + +\let\getexpandedparameters=\geteparameters + +% \def\dogetparameters#1[#2]#3[#4% +% {\if\noexpand#4]% +% \expandafter\gobbleoneargument +% \else +% \def\p!dogetparameter{\p!doassign#1#2}% +% \expandafter\xdogetparameters +% \fi#4} + +\def\dogetparameters#1[#2]#3[#4% + {\if\noexpand#4]% + \expandafter\gobbleoneargument + \else + \let\setsomevalue#1% + \def\p!dogetparameter{\p!doassign#2}% + \expandafter\xdogetparameters + \fi#4} + +\def\xdogetparameters#1]% + {\xprocesscommaitem#1,],\@relax@} + +\long\def\xprocesscommaitem#1,#2% #2 takes space before , + {\if,#1,% dirty trick for testing #1=empty + \@EA\xprocesscommaitem + \else\if]#1% + \@EAEAEA\gobbleoneargument + \else + \p!dogetparameter\@relax@#1==\empty\@relax@ + \@EAEAEA\xprocesscommaitem + \fi\fi#2} + +\def\xshowassignerror#1#2#3% + {\showassignerror{#2}{\the\inputlineno\space(#1)}} + +% \def\p!n!doassign#1#2\@relax@#3=#4=#5#6\@relax@ +% {\ifx\empty#3\empty +% \@EA\xshowassignerror +% \else\ifx#5\empty +% \@EAEAEA\xshowassignerror +% \else +% \@EAEAEA#1% +% \fi\fi +% {#2}{#3}{#4}} + +% \def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@ +% {\ifx\empty#3\empty +% \@EA\xshowassignerror +% \else\ifx#5\empty +% \@EAEAEA\xshowassignerror +% \else +% \ifcsname#2#3\endcsname +% \@EA\let\@EA\currentvalue\csname#2#3\endcsname +% \else +% \let\currentvalue\empty +% \fi +% \@EAEAEA#1% +% \fi\fi +% {#2}{#3}{#4}} + +\def\p!n!doassign#1\@relax@#2=#3=#4#5\@relax@ + {\ifx\empty#2\empty + \@EA\xshowassignerror + \else\ifx#4\empty + \@EAEAEA\xshowassignerror + \else + \@EAEAEA\setsomevalue + \fi\fi + {#1}{#2}{#3}} + + +\def\p!e!doassign#1\@relax@#2=#3=#4#5\@relax@ + {\ifx\empty#2\empty + \@EA\xshowassignerror + \else\ifx#4\empty + \@EAEAEA\xshowassignerror + \else + \ifcsname#1#2\endcsname + \@EA\let\@EA\currentvalue\csname#1#2\endcsname + \else + \let\currentvalue\empty + \fi + \@EAEAEA\setsomevalue + \fi\fi + {#1}{#2}{#3}} + +\let\p!doassign\p!n!doassign + +% \def\doassign [#1][#2]{\p!doassign\dosetvalue #1\@relax@#2==\empty\@relax@} +% \def\doeassign [#1][#2]{\p!doassign\dosetevalue #1\@relax@#2==\empty\@relax@} +% \def\undoassign[#1][#2]{\p!doassign\doresetvalue#1\@relax@#2==\empty\@relax@} + +\def\doassign [#1][#2]{\let\setsomevalue\dosetvalue \p!doassign#1\@relax@#2==\empty\@relax@} +\def\doeassign [#1][#2]{\let\setsomevalue\dosetevalue \p!doassign#1\@relax@#2==\empty\@relax@} +\def\undoassign[#1][#2]{\let\setsomevalue\doresetvalue\p!doassign#1\@relax@#2==\empty\@relax@} + +%D \macros{currentvalue} +%D +%D Just in case a \type{\getparameter} argument itself ends up +%D inside a \type{\write} or other expandable location, our +%D new macro needs a default value. +%D +%D \starttyping +%D \getparameters[xxx][aaa=bbb]\par +%D \getparameters[xxx][=bbb]\par +%D \getparameters[xxx][aaa=]\par +%D \getparameters[xxx][=]\par +%D \getparameters[xxx][aaa]\par +%D \stoptyping + +%D \macros {expandparameters} +%D +%D Example usage: +%D +%D \startbuffer +%D \getparameters[taco][name=taco] +%D \convertcommand\taconame\to\ascii \ascii +%D \expandparameters \getparameters[taco][name=\currentvalue\space hoekwater] +%D \convertcommand\taconame\to\ascii \ascii +%D \getparameters[taco][name=\currentvalue\space hoekwater] +%D \convertcommand\taconame\to\ascii \ascii +%D \stopbuffer +%D +%D \typebuffer +%D \startlines +%D \getbuffer +%D \stoplines + +%D Here we hook in the code (beware, this is the optimized get **): + +\def\xdoget@n@parameters#1]% + {\xprocesscommaitem#1,],\@relax@} + +\def\xdoget@e@parameters#1]% + {\let\dosetnvalue\dosetvalue + \let\dosetvalue\dosetevalue + \let\p!doassign\p!e!doassign + \xprocesscommaitem#1,],\@relax@ + \let\p!doassign\p!n!doassign + \let\dosetvalue\dosetnvalue + \let\xdogetparameters\xdoget@n@parameters + \let\currentvalue\empty} + +\let\xdogetparameters\xdoget@n@parameters % ** + +\def\expandparameters{\let\xdogetparameters\xdoget@e@parameters} + +%D \macros +%D {getemptyparameters} +%D +%D Sometimes we explicitly want variables to default to an +%D empty string, so we welcome: +%D +%D \starttyping +%D \getemptyparameters [label] [...=...,...=...] +%D \stoptyping + +\def\getemptyparameters[#1]#2[#3]% + {\def\p!dogetemptyparameter##1{\doassignempty[#1][##1]}% + \processcommalist[#3]\p!dogetemptyparameter} + +%D \macros +%D {copyparameters} +%D +%D Some \CONTEXT\ commands take their default setups from +%D others. All commands that are able to provide backgounds +%D or rules around some content, for instance default to the +%D standard command for ruled boxes. Is situations like this +%D we can use: +%D +%D \starttyping +%D \copyparameters [to-label] [from-label] [name1,name2,...] +%D \stoptyping +%D +%D For instance +%D +%D \starttyping +%D \copyparameters +%D [internal][external] +%D [alfa,beta] +%D \stoptyping +%D +%D Leads to: +%D +%D \starttyping +%D \def\internalalfa {\externalalfa} +%D \def\internalbeta {\externalbeta} +%D \stoptyping +%D +%D By using \type{\docopyvalue} we've prepared this command +%D for use in a multi||lingual environment. + +\def\copyparameters[#1]#2[#3]#4[#5]% + {\doifnot{#1}{#3} + {\def\docopyparameter{\docopyvalue{#1}{#3}}% ##1 + \processcommalist[#5]\docopyparameter}} + +%D \macros +%D {ifparameters,checkparameters} +%D +%D A slightly different one is \type{\checkparameters}, which +%D also checks on the presence of a~\type{=}. +%D +%D The boolean \type{\ifparameters} can be used afterwards. +%D Combining both in one \type{\if}||macro would lead to +%D problems with nested \type{\if}'s. +%D +%D \starttyping +%D \checkparameters[argument] +%D \stoptyping + +\newif\ifparameters + +\def\p!checkparameters#1=#2#3\war% + {\if#2@\parametersfalse\else\parameterstrue\fi} + +\def\checkparameters[#1]% + {\p!checkparameters#1=@@\war} + +%D \macros +%D {getfromcommalist,getfromcommacommand, +%D commalistelement, +%D getcommalistsize,getcommacommandsize} +%D +%D It's possible to get an element from a commalist or a +%D command representing a commalist. +%D +%D \starttyping +%D \getfromcommalist [string] [n] +%D \getfromcommacommand [string,\strings,string,...] [n] +%D \stoptyping +%D +%D The difference betwee the two of them is the same as the +%D difference between \type{\processcomma...}. The found string +%D is stored in \type{\commalistelement}. +%D +%D We can calculate the size of a comma separated list by +%D using: +%D +%D \starttyping +%D \getcommalistsize [string,string,...] +%D \getcommacommandsize [string,\strings,string,...] +%D \stoptyping +%D +%D Afterwards, the length is available in the macro +%D \type{\commalistsize} (not a \COUNTER). + +\newcount\commalistcounter + +\def\commalistsize{0} + +\def\p!dogetcommalistsize#1% + {\advance\commalistcounter\plusone} + +\def\getcommalistsize#1]% don't loose [{#1}] + {\commalistcounter\zerocount + \processcommalist#1]\p!dogetcommalistsize % was [{#1}] + \edef\commalistsize{\the\commalistcounter}} + +\def\getcommacommandsize[#1]% + {\edef\commacommand{#1}% + \scratchtoks\expandafter{\expandafter[\commacommand]}% + \expandafter\getcommalistsize\the\scratchtoks } + +% to be tested first +% +% \def\getcommacommandsize[#1]% +% {\expanded{\getcommalistsize[#1]}} + +% \def\p!dogetfromcommalist#1% +% {\advance\commalistcounter \minusone +% \ifcase\commalistcounter +% \def\commalistelement{#1}% +% \begingroup\def\doprocesscommaitem##1]{\endgroup}% +% \fi} + +\def\p!dogetfromcommalist#1% + {\advance\commalistcounter \minusone + \ifcase\commalistcounter + \def\commalistelement{#1}% + \expandafter\quitcommalist + \fi} + +\def\getfromcommalist[#1]#2[#3]% + {\let\commalistelement\empty + \commalistcounter#3\relax + \processcommalist[#1]\p!dogetfromcommalist} + +\def\getfromcommacommand[#1]% + {\expanded{\getfromcommalist[#1]}} + +%D Watertight (and efficient) solutions are hard to find, due +%D to the handling of braces during parameters passing and +%D scanning. Nevertheless: +%D +%D \startbuffer +%D \def\dosomething#1{(#1=\commalistsize) } +%D +%D \getcommalistsize [\hbox{$a,b,c,d,e,f$}] \dosomething 1 +%D \getcommalistsize [{a,b,c,d,e,f}] \dosomething 1 +%D \getcommalistsize [{a,b,c},d,e,f] \dosomething 4 +%D \getcommalistsize [a,b,{c,d,e},f] \dosomething 4 +%D \getcommalistsize [a{b,c},d,e,f] \dosomething 4 +%D \getcommalistsize [{a,b}c,d,e,f] \dosomething 4 +%D \getcommalistsize [] \dosomething 0 +%D \getcommalistsize [{[}] \dosomething 1 +%D \stopbuffer +%D +%D \typebuffer +%D +%D reports: +%D +%D \getbuffer + +%D \macros +%D {dogetcommalistelement,dogetcommacommandelement} +%D +%D For low level (fast) purposes, we can also use the next +%D alternative, which can handle 8~elements at most. +%D +%D \starttyping +%D \dogetcommalistelement1\from a,b,c\to\commalistelement +%D \stoptyping + +\def\dodogetcommalistelement#1\from#2,#3,#4,#5,#6,#7,#8\to#9% + {\edef#9{\ifcase#1\relax\or#2\or#3\or#4\or#5\or#6\or#7\or#8\fi}} + +\def\dogetcommalistelement#1\from#2\to% + {\dodogetcommalistelement#1\from#2,,,,,,\to} + +% check sources + +\def\dogetcommacommandelement#1\from#2\to% + {\@EA\dodogetcommalistelement\@EA#1\@EA\from#2,,,,,,\to} + +%D \macros +%D {dosingleargument,dodoubleargument,dotripleargument, +%D doquadrupleargument,doquintupleargument,dosixtupleargument, +%D doseventupleargument} +%D +%D When working with delimited arguments, spaces and +%D lineendings can interfere. The next set of macros uses +%D \TEX' internal scanner for grabbing everything between +%D arguments. Forgive me the funny names. +%D +%D \starttyping +%D \dosingleargument\commando = \commando[#1] +%D \dodoubleargument\commando = \commando[#1][#2] +%D \dotripleargument\commando = \commando[#1][#2][#3] +%D \doquadrupleargument\commando = \commando[#1][#2][#3][#4] +%D \doquintupleargument\commando = \commando[#1][#2][#3][#4][#5] +%D \dosixtupleargument\commando = \commando[#1][#2][#3][#4][#5][#6] +%D \doseventupleargument\command = \commando[#1][#2][#3][#4][#5][#6][#7] +%D \stoptyping +%D +%D These macros are used in the following way: +%D +%D \starttyping +%D \def\dosetupsomething[#1][#2]% +%D {... #1 ... #2 ...} +%D +%D \def\setupsomething +%D {\dodoubleargument\dosetupsomething} +%D \stoptyping +%D +%D The implementation can be surprisingly simple and needs no +%D further explanation, like: +%D +%D \starttyping +%D \def\dosingleargument#1[#2]% +%D {#1[#2]} +%D \def\dotripleargument#1[#2]#3[#4]#5[#6]% +%D {#1[#2][#4][#6]} +%D \def\doquintupleargument#1% +%D {\def\dodoquintupleargument[##1]##2[##3]##4[##5]##6[##7]##8[##9]% +%D {#1[##1][##3][##5][##7][##9]}% +%D \dodoquintupleargument} +%D \stoptyping +%D +%D Because \TEX\ accepts 9~arguments at most, we have to use +%D two||step solution when getting five or more arguments. +%D +%D When developing more and more of the real \CONTEXT, we +%D started using some alternatives that provided empty +%D arguments (in fact optional ones) whenever the user failed +%D to supply them. Because this more complicated macros enable +%D us to do some checking, we reimplemented the non||empty +%D ones. + +\def\dosingleargument {\let\expectedarguments\plusone \dosingleempty } +\def\dodoubleargument {\let\expectedarguments\plustwo \dodoubleempty } +\def\dotripleargument {\let\expectedarguments\plusthree \dotripleempty } +\def\doquadrupleargument {\let\expectedarguments\plusfour \doquadrupleempty } +\def\doquintupleargument {\let\expectedarguments\plusfive \doquintupleempty } +\def\dosixtupleargument {\let\expectedarguments\plussix \dosixtupleempty } +\def\doseventupleargument{\let\expectedarguments\plusseven \doseventupleempty} + +%D \macros +%D {iffirstagument,ifsecondargument,ifthirdargument, +%D iffourthargument,iffifthargument,ifsixthargument, +%D ifseventhargument} +%D +%D We use some signals for telling the calling macros if all +%D wanted arguments are indeed supplied by the user. + +\newif\iffirstargument +\newif\ifsecondargument +\newif\ifthirdargument +\newif\iffourthargument +\newif\iffifthargument +\newif\ifsixthargument +\newif\ifseventhargument + +%D \macros +%D {dosingleempty,dodoubleempty,dotripleempty, +%D doquadrupleempty,doquintupleempty,dosixtupeempty, +%D doseventupleempty} +%D +%D The empty argument supplying macros mentioned before, look +%D like: +%D +%D \starttyping +%D \dosingleempty \command +%D \dodoubleempty \command +%D \dotripleempty \command +%D \doquadrupleempty \command +%D \doquintupleempty \command +%D \dosixtupleempty \command +%D \doseventupleempty\command +%D \stoptyping +%D +%D So \type{\dodoubleempty} leades to: +%D +%D \starttyping +%D \command[#1][#2] +%D \command[#1][] +%D \command[][] +%D \stoptyping +%D +%D Depending of the generousity of the user. Afterwards one can +%D use the \type{\if...argument} boolean. For novice: watch +%D the stepwise doubling of \type{#}'s + +% idea: \ignorespaces afterwards + +\chardef\noexpectedarguments=0 +\chardef\expectedarguments =0 + +\def\showargumenterror#1#2% + {\writestatus{systems}{\number#1 argument(s) expected in line #2}} + +\def\doshowargumenterror + {\ifnum\expectedarguments>\noexpectedarguments + \showargumenterror{\number\expectedarguments}{\number\inputlineno}% + \fi + \noshowargumenterror} + +\def\noshowargumenterror + {\let\expectedarguments\noexpectedarguments} + +\long\def\dogetargument#1#2#3#4% + {\let\charactertoken=#1% + \def\!!stringa{\noshowargumenterror#3\dodogetargument}% + \def\!!stringb{\doshowargumenterror#4\dodogetargument#1#2}% + \futurelet\nexttoken\inspectnextcharacter} + +\def\getsingleempty#1#2#3% + {\def\dodogetargument% + {#3}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\getdoubleempty#1#2#3% + {\def\dodogetargument#1##1#2% + {\def\dodogetargument% + {#3#1{##1}#2}% + \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\gettripleempty#1#2#3% + {\def\dodogetargument#1##1#2% + {\def\dodogetargument#1####1#2% + {\def\dodogetargument% + {#3#1{##1}#2% + #1{####1}#2}% + \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% + \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\getquadrupleempty#1#2#3% + {\def\dodogetargument#1##1#2% + {\def\dodogetargument#1####1#2% + {\def\dodogetargument#1########1#2% + {\def\dodogetargument% + {#3#1{##1}#2% + #1{####1}#2% + #1{########1}#2}% + \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% + \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% + \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\getquintupleempty#1#2#3% + {\def\dodogetargument#1##1#2% + {\def\dodogetargument#1####1#2% + {\def\dodogetargument#1########1#2% + {\def\dodogetargument#1################1#2% + {\def\dodogetargument% + {#3#1{##1}#2% + #1{####1}#2% + #1{########1}#2% + #1{################1}#2}% + \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% + \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% + \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% + \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\getsixtupleempty#1#2#3% + {\def\dodogetargument#1##1#2% + {\def\dodogetargument#1####1#2% + {\def\dodogetargument#1########1#2% + {\def\dodogetargument#1################1#2% + {\def\dodogetargument#1################################1#2% + {\def\dodogetargument% + {#3#1{##1}#2% + #1{####1}#2% + #1{########1}#2% + #1{################1}#2% + #1{################################1}#2}% + \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% + \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% + \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% + \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% + \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\getseventupleempty#1#2#3% + {\def\dodogetargument#1##1#2% + {\def\dodogetargument#1####1#2% + {\def\dodogetargument#1########1#2% + {\def\dodogetargument#1################1#2% + {\def\dodogetargument#1################################1#2% + {\def\dodogetargument#1################################% + ################################1#2% + {\def\dodogetargument% + {#3#1{##1}#2% + #1{####1}#2% + #1{########1}#2% + #1{################1}#2% + #1{################################1}#2% + #1{################################% + ################################1}#2}% + \dogetargument#1#2\seventhargumenttrue\seventhargumentfalse}% + \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% + \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% + \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% + \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% + \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% + \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +\def\dosingleempty {\getsingleempty []} +\def\dodoubleempty {\getdoubleempty []} +\def\dotripleempty {\gettripleempty []} +\def\doquadrupleempty {\getquadrupleempty []} +\def\doquintupleempty {\getquintupleempty []} +\def\dosixtupleempty {\getsixtupleempty []} +\def\doseventupleempty{\getseventupleempty[]} + +%D Because some of these are called quite often, we will now +%D replace the more general version by alternatives tuned for +%D speed. + +\def\dosingleempty#1% 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[]}} + +\def\definecomplexorsimple#1% + {\unexpanded\edef#1% + {\noexpand\docomplexorsimple + \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname + \@EA\noexpand\csname\s!simple \strippedcsname#1\endcsname}} + +\def\definecomplexorsimpleempty#1% + {\unexpanded\edef#1% + {\noexpand\docomplexorsimpleempty + \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname}} + +%D These commands are called as: +%D +%D \starttyping +%D \definecomplexorsimple\command +%D \stoptyping +%D +%D Of course, we must have available +%D +%D \starttyping +%D \def\complexcommand[#1]{...} +%D \def\simplecommand {...} +%D \stoptyping +%D +%D Using this construction saves a few string now and then. + +%D \macros +%D {dosinglegroupempty,dodoublegroupempty,dotriplegroupempty, +%D doquadruplegroupempty, doquintuplegroupempty} +%D +%D We've already seen some commands that take care of +%D optional arguments between \type{[]}. The next two commands +%D handle the ones with \type{{}}. They are called as: +%D +%D \starttyping +%D \dosinglegroupempty \ineedONEargument +%D \dodoublegroupempty \ineedTWOarguments +%D \dotriplegroupempty \ineedTHREEarguments +%D \doquadruplegroupempty \ineedFOURarguments +%D \doquintuplegroupempty \ineedFIVEarguments +%D \stoptyping + +%D We can add additional definitions later when we have defined +%D \type {\appendtoks}. + +\def \permitspacesbetweengroups{\let\@@permitspacesbetweengroups\zerocount} +\def\dontpermitspacesbetweengroups{\let\@@permitspacesbetweengroups\plusone} + +\dontpermitspacesbetweengroups + +%D We can avoid the nasty if handling in \type {syst-gen} by splitting +%D the lot in pieces so that we have no nested \type {\nextarguments} +%D potentially being an \type {conditional} token. Okay, these macros +%D are not called that often but it saves crap when tracing. + +% \def\dogetgroupargument#1#2% +% {\let\dogroupargumentyes#1% +% \let\dogroupargumentnop#2% +% \futurelet\nextargument\dodogetgroupargument} + +\def\dodogetgroupargument + {\ifx\nextargument\bgroup + \expandafter\dodogetgroupargumentA + \else + \expandafter\dodogetgroupargumentB + \fi} + +\def\dodogetgroupargumentA + {\noshowargumenterror + \dogroupargumentyes\dodogetargument} + +% \def\dodogetgroupargumentB +% {\ifcase\@@permitspacesbetweengroups +% \expandafter\dodogetgroupargumentC +% \else +% \expandafter\dodogetgroupargumentD +% \fi} + +% \def\dodogetgroupargumentC +% {\ifx\nextargument\lineending +% \expandafter\dodogetgroupargumentE +% \else +% \expandafter\dodogetgroupargumentF +% \fi} + +\def\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: + +\def\define#1% + {\ifdefined#1% + \message{[\noexpand#1is already defined]}% + \expandafter\def\expandafter\gobbleddefinition + \else + \expandafter\def + \fi#1} + +\def\redefine#1% + {\ifdefined#1% + \message{[\noexpand#1is redefined]}% + \fi + \def#1} + +% \define\hans{hans} +% \redefine\hans{hans} +% \define\hans#1[]#2#3{hans} + +%D The next variant fits nicely in the setups syntax: +%D +%D \starttyping +%D \starttexdefinition bagger [#1] #2 +%D oeps +%D #1 +%D oeps +%D \stoptexdefinition +%D +%D \bagger [a] {b} +%D \stoptyping + +\bgroup \obeylines + +\gdef\starttexdefinition% + {\bgroup% + \obeylines% + \dostarttexdefinition} + +\gdef\dostarttexdefinition #1 #2 + {\catcode13=\@@ignore% + \dodostarttexdefinition{#1}{#2}}% + +\long\gdef\dodostarttexdefinition#1#2#3\stoptexdefinition% + {\egroup% + \long\setvalue{#1}#2{#3}} + +\egroup + +%D \macros +%D {newcounter, +%D increment,decrement} +%D +%D Unfortunately the number of \COUNTERS\ in \TEX\ is limited, +%D but fortunately we can store numbers in a macro. We can +%D increment such pseudo \COUNTERS\ with \type{\increment}. +%D +%D \starttyping +%D \increment(\counter,20) +%D \increment(\counter,-4) +%D \increment(\counter) +%D \increment\counter +%D \stoptyping +%D +%D After this sequence of commands, the value of +%D \type{\counter} is 20, 16, 17 and~18. Of course there is +%D also the complementary command \type{\decrement}. +%D +%D Global assignments are possible too, using \type{\doglobal}: +%D +%D \starttyping +%D \doglobal\increment\counter +%D \stoptyping +%D +%D When \type{\counter} is undefined, it's value is initialized +%D at~0. It is nevertheless better to define a \COUNTER\ +%D explicitly. One reason could be that the \COUNTER\ can be +%D part of a test with \type{\ifnum} and this conditional does +%D not accept undefined macro's. The \COUNTER\ in our example +%D can for instance be defined with: +%D +%D \starttyping +%D \newcounter\counter +%D \stoptyping +%D +%D The command \type{\newcounter} must not be confused with +%D \type{\newcount}! Of course this mechanism is much slower +%D than using \TEX's \COUNTERS\ directly. In practice +%D \COUNTERS\ (and therefore our pseudo counters too) are +%D seldom the bottleneck in the processing of a text. Apart +%D from some other incompatilities we want to mention a pitfal +%D when using \type{\ifnum}. +%D +%D \starttyping +%D \ifnum\normalcounter=\pseudocounter \doif \else \doelse \fi +%D \ifnum\pseudocounter=\normalcounter \doif \else \doelse \fi +%D \stoptyping +%D +%D In the first test, \TEX\ continues it's search for the +%D second number after reading \type{\pseudocounter}, while +%D in the second test, it stops reading after having +%D encountered a real one. Tests like the first one therefore +%D can give unexpected results, for instance execution +%D of \type{\doif} even if both numbers are unequal. + +\def\zerocountervalue{0} + +\def\newcounter#1% + {\dodoglobal\let#1\zerocountervalue} + +%D Nowadays we don't mind a few more tokens if we can gain a +%D bit of speed. + +\def\doincrement#1% + {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\plusone \relax}} +\def\dodecrement#1% + {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\minusone\relax}} + +\def\dododoincrement#1,#2)% + {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+#2\relax}} +\def\dodododecrement#1,#2)% + {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi-#2\relax}} + +\def\dodoincrement(#1% + {\doifnextcharelse,{\dododoincrement#1}{\dododoincrement#1,\plusone}} +\def\dododecrement(#1% + {\doifnextcharelse,{\dodododecrement#1}{\dodododecrement#1,\plusone}} + +\def\fastincrement#1{\dodoglobal\edef#1{\the\numexpr#1+\plusone \relax}} +\def\fastdecrement#1{\dodoglobal\edef#1{\the\numexpr#1+\minusone\relax}} + +\def\increment{\doifnextcharelse(\dodoincrement\doincrement} +\def\decrement{\doifnextcharelse(\dododecrement\dodecrement} + +\def\incrementvalue#1{\expandafter\increment\csname#1\endcsname} +\def\decrementvalue#1{\expandafter\decrement\csname#1\endcsname} + +%D \macros +%D {newsignal} +%D +%D When writing advanced macros, we cannot do without +%D signaling. A signal is a small (invisible) kern or penalty +%D that signals the next macro that something just happened. +%D This macro can take any action depending on the previous +%D signal. Signals must be unique and the next macro takes care +%D of that. +%D +%D \starttyping +%D \newsignal\somesignal +%D \stoptyping +%D +%D Signals old dimensions and can be used in skips, kerns and +%D tests like \type{\ifdim}. + +\newdimen\maximumsignal % step is about 0.00025pt + +\def\newsignal#1% + {\ifdefined#1\else + \advance\maximumsignal 2sp % to be save in rounding + \edef#1{\the\maximumsignal}% + \fi} + +\let\newskimen\newdimen % it's all etex or later now + +%D \macros +%D {strippedcsname} +%D +%D The next macro can be very useful when using \type{\csname} +%D like in: +%D +%D \starttyping +%D \csname if\strippedcsname\something\endcsname +%D \stoptyping + +\ifdefined\letterbackslash \else + {\catcode`.=0 .catcode`.\ 12 .xdef.letterbackslash{.string\}} % hack +\fi + +\def\strippedcsname#1% this permits \strippedcsname{\xxx} and \strippedcsname{xxx} + {\expandafter\dostrippedcsname\string#1} + +\def\dostrippedcsname#1% + {\if\noexpand#1\letterbackslash\else#1\fi} + +%D \macros +%D {savenormalmeaning} +%D +%D We will use this one in: + +\def\savenormalmeaning#1% + {\ifcsname normal\strippedcsname#1\endcsname \else + \letvalue{normal\strippedcsname#1}#1% + \fi} + +%D \macros +%D {newconditional, +%D settrue, setfalse, +%D ifconditional} +%D +%D \TEX's lacks boolean variables, although the \PLAIN\ format +%D implements \type{\newif}. The main disadvantage of this +%D scheme is that it takes three hash table entries. A more +%D memory saving alternative is presented here. A conditional +%D is defined by: +%D +%D \starttyping +%D \newconditional\doublesided +%D \setfalse +%D \stoptyping +%D Setting a conditional is done by \type{\settrue} and +%D \type{\setfalse}: +%D +%D \starttyping +%D \settrue\doublesided +%D \setfalse +%D \stoptyping +%D while testing is accomplished by: +%D +%D \starttyping +%D \ifconditional\doublesided ... \else ... \fi +%D \setfalse +%D \stoptyping +%D We cannot use the simple scheme: +%D +%D \starttyping +%D \def\settrue#1{\let#1=\iftrue} +%D \def\settrue#1{\let#1=\iffalse} +%D \stoptyping +%D +%D Such an implementation gives problems with nested +%D conditionals. The next implementation is abaou as fast +%D and just as straightforward: + +% \def\settrue #1{\chardef#1\zerocount} +% \def\setfalse#1{\chardef#1\plusone} + +\def\settrue #1{\let#1\zerocount} +\def\setfalse#1{\let#1\plusone} + +\let\newconditional = \setfalse +\let\ifconditional = \ifcase + +%D \macros +%D {ifzeropt} +%D +%D The next macro is both cosmetic and byte saving. It is +%D pretty \type{\if}||safe too. It can be used in cases +%D like: +%D +%D \starttyping +%D \ifzeropt \somedimen ... \else ... \fi +%D \stoptyping + +\let\ifzeropt\ifcase + +%D \macros +%D {dorecurse,recurselevel,recursedepth, +%D dostepwiserecurse, +%D for} +%D +%D \TEX\ does not offer us powerfull for||loop mechanisms. On +%D the other hand its recursion engine is quite unique. We +%D therefore identify the for||looping macros by this method. +%D The most simple alternative is the one that only needs a +%D number. +%D +%D \starttyping +%D \dorecurse {n} {whatever we want} +%D \stoptyping +%D +%D This macro can be nested without problems and therefore be +%D used in situations where \PLAIN\ \TEX's \type{\loop} macro +%D ungracefully fails. The current value of the counter is +%D available in \type{\recurselevel}, before as well as after +%D the \typ{whatever we wat} stuff. +%D +%D \starttyping +%D \dorecurse % inner loop +%D {10} +%D {\recurselevel: % outer value +%D \dorecurse % inner loop +%D {\recurselevel} % outer value +%D {\recurselevel} % inner value +%D \dorecurse % inner loop +%D {\recurselevel} % outer value +%D {\recurselevel} % inner value +%D \endgraf} +%D \stoptyping +%D +%D In this example the first, second and fourth +%D \type{\recurselevel} concern the outer loop, while the third +%D and fifth one concern the inner loop. The depth of the +%D nesting is available for inspection in \type{\recursedepth}. +%D +%D Both \type{\recurselevel} and \type{\recursedepth} are +%D macros. The real \COUNTERS\ are hidden from the user because +%D we don't want any interference. + +\newcount\outerrecurse +\newcount\innerrecurse + +\def\recursedepth{\the\outerrecurse} +\def\recurselevel{0} + +\let\nextrecurse\relax + +\def\@@irecurse{@@ir@@} % ecurse} % stepper +\def\@@arecurse{@@ar@@} % ecurse} % action + +\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#4}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \ifnum#3>0\relax + \ifnum#2<#1\relax + \let\nextrecurse\exitstepwiserecurse + \else + \let\nextrecurse\dodostepwiserecurse + \fi + \else + \ifnum#3<0\relax + \ifnum#1<#2\relax + \let\nextrecurse\exitstepwiserecurse + \else + \let\nextrecurse\dodostepwisereverse + \fi + \else + \let\nextrecurse\exitstepwiserecurse + \fi + \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} + +\long\def\dodostepwiserecurse#1#2#3% from to step + {\ifnum#1>#2\relax + \@EA\nodostepwiserecurse + \else + \def\recurselevel{#1}% + \@EAEAEA\redostepwiserecurse\@EA + \fi\@EA{\the\numexpr\recurselevel+#3\relax}{#2}{#3}} + +\def\expandrecursecontent + {\csname\@@arecurse\recursedepth\endcsname} + +\def\redostepwiserecurse + {\expandrecursecontent\dodostepwiserecurse} + +\long\def\dodostepwisereverse#1#2#3% from to step + {\ifnum#1<#2\relax + \@EA\nodostepwiserecurse + \else + \def\recurselevel{#1}% + \@EAEAEA\redostepwisereverse\@EA + \fi\@EA{\the\numexpr\recurselevel#3\relax}{#2}{#3}} + +\long\def\dodostepwisereverse#1#2#3% from to step + {\ifnum#1<#2\relax + \@EA\nodostepwiserecurse + \else + \def\recurselevel{#1}% + \innerrecurse#1\relax + \advance\innerrecurse#3\relax + \@EAEAEA\redostepwisereverse\@EA + \fi\@EA{\the\innerrecurse}{#2}{#3}} + +\def\redostepwisereverse + {\expandrecursecontent\dodostepwisereverse} + +\def\exitstepwiserecurse + {\nodostepwiserecurse\relax} + +\def\nodostepwiserecurse#1#2#3#4% + {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse \minusone} + +\def\nonostepwiserecurse#1#2#3% + {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse \minusone} + +\def\dorecurse#1% + {\dostepwiserecurse1{#1}1} + +%D As we can see here, the simple command \type{\dorecurse} is +%D a special case of the more general: +%D +%D \starttyping +%D \dostepwiserecurse {from} {to} {step} {action} +%D \stoptyping +%D +%D This commands accepts positive and negative steps. Illegal +%D values are handles as good as possible and the macro accepts +%D numbers and \COUNTERS. +%D +%D \starttyping +%D \dostepwiserecurse {1} {10} {2} {...} +%D \dostepwiserecurse {10} {1} {-2} {...} +%D \stoptyping +%D +%D Because the simple case is used often, we implement it +%D more efficiently: + +\long\def\dorecurse#1% + {\ifcase#1\relax + \expandafter\gobbletwoarguments + \or + \expandafter\ydorecurse + \else + \expandafter\xdorecurse + \fi{#1}} + +\long\def\xdorecurse#1#2% + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#2}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \@EA\dodorecurse\@EA1\@EA{\number#1}} + +\long\def\ydorecurse#1#2% + {\global\advance\outerrecurse \plusone + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \let\recurselevel\!!plusone + #2% + \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse \minusone} + +\long\def\dodorecurse#1#2% from to + {\ifnum#1>#2\relax + \@EA\nodorecurse + \else + \def\recurselevel{#1}% + \@EAEAEA\redorecurse + \fi\@EA{\the\numexpr\recurselevel+\plusone\relax}{#2}} + +\long\def\dodorecurse#1#2% from to + {\ifnum#1>#2\relax + \@EA\nodorecurse + \else + \def\recurselevel{#1}% + \innerrecurse#1\advance\innerrecurse\plusone + \@EAEAEA\redorecurse + \fi\@EA{\the\innerrecurse}{#2}} + +\def\redorecurse + {\expandrecursecontent\dodorecurse} + +\def\nodorecurse#1#2#3% + {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse \minusone } + +%D \macros +%D {doloop,exitloop} +%D +%D Sometimes loops are not determined by counters, but by +%D (a combinations of) conditions. We therefore implement a +%D straightforward loop, which can only be left when we +%D explictly exit it. Nesting is supported. First we present +%D a more extensive alternative. +%D +%D \starttyping +%D \doloop +%D {Some kind of typesetting punishment \par +%D \ifnum\pageno>100 \exitloop \fi} +%D \stoptyping +%D +%D When needed, one can call for \type{\looplevel} and +%D \type{\loopdepth}. + +\let\endofloop\donothing + +\long\def\doloop#1% + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#1}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \let\endofloop\dodoloop + \dodoloop1} % no \plusone else \recurselevel wrong + +\long\def\dodoloop#1% + {\def\recurselevel{#1}% + \@EA\redoloop\@EA{\the\numexpr\recurselevel+\plusone\relax}} + +\def\redoloop + {\expandrecursecontent\endofloop} + +\def\nodoloop#1% + {\let\endofloop\dodoloop % new, permits nested \doloop's + \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse\minusone} + +\def\exitloop % \exitloop quits at end + {\let\endofloop\nodoloop} + +\long\def\exitloopnow#1\endofloop % \exitloopnow quits directly + {\nodoloop} + +%D The loop is executed at least once, so beware of situations +%D like: +%D +%D \starttyping +%D \doloop {\exitloop some commands} +%D \stoptyping +%D +%D It's just a matter of putting the text into the \type{\if} +%D statement that should be there anyway, like in: +%D +%D \starttyping +%D \doloop {\ifwhatever \exitloop \else some commands\fi} +%D \stoptyping +%D +%D You can also quit a loop immediately, by using \type +%D {\exitloopnow} instead. Beware, this is more sensitive +%D for conditional errors. + +%D Krzysztof Leszczynski suggested to provide access to the level by +%D means of a \type {#1}. I decided to pass the more frquently used +%D level as \type {#1} and the less favoured depth as \type {#2}. The +%D intended usage is: +%D +%D \starttyping +%D \dorecurse{3}{\definesymbol[test-#1][xx-#1]} +%D +%D \def\test{\dorecurse{3}{\definesymbol[test-##1][xx-##1]}} \test +%D +%D \symbol[test-1]\quad\symbol[test-2]\quad\symbol[test-3] +%D \stoptyping +%D +%D Since the hashed arguments are expanded, we don't need tricky +%D expansion here. +%D +%D \starttyping +%D \dorecurse{3}{\expanded{\definesymbol[test-\recurselevel][xx-\recurselevel]}} +%D \stoptyping + +\def\expandrecursecontent + {\csname\@@arecurse\recursedepth\@EA\@EA\@EA\endcsname\@EA\@EA\@EA{\@EA\recurselevel\@EA}\@EA{\recursedepth}} + +\long\def\xdorecurse#1#2% + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \@EA\dodorecurse\@EA1\@EA{\number#1}} + +\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \ifnum#3>0\relax + \ifnum#2<#1\relax + \let\nextrecurse\exitstepwiserecurse + \else + \let\nextrecurse\dodostepwiserecurse + \fi + \else + \ifnum#3<0\relax + \ifnum#1<#2\relax + \let\nextrecurse\exitstepwiserecurse + \else + \let\nextrecurse\dodostepwisereverse + \fi + \else + \let\nextrecurse\exitstepwiserecurse + \fi + \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} + +\long\def\doloop#1% + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \let\endofloop\dodoloop + \dodoloop1} % no \plusone else \recurselevel wrong + +% EXPERIMENT + +% faster + +\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \ifnum#3>\zerocount + \ifnum#2<#1\relax + \let\nextrecurse\exitstepwiserecurse + \else + \let\nextrecurse\dodostepwiserecurse + \fi + \else + \ifnum#3<\zerocount + \ifnum#1<#2\relax + \let\nextrecurse\exitstepwiserecurse + \else + \let\nextrecurse\dodostepwisereverse + \fi + \else + \let\nextrecurse\exitstepwiserecurse + \fi + \fi + \expandafter\nextrecurse\normalexpanded{{\number#1}{\number#2}{\number#3}}} + +% slightly faster + +\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 + {\global\advance\outerrecurse \plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \csname @swr% + \ifnum#3>\zerocount + \ifnum#2<#1\else d\fi + \else\ifnum#3<\zerocount + \ifnum#1<#2\else r\fi + \fi\fi + \expandafter\endcsname\normalexpanded{{\number#1}{\number#2}{\number#3}}} + +\let\@swr \exitstepwiserecurse +\let\@swrd\dodostepwiserecurse +\let\@swrr\dodostepwisereverse + +%D For special purposes: + +\newcount\fastrecursecounter +\newcount\lastrecursecounter +\newcount\steprecursecounter + +\def\dofastrecurse#1#2#3#4% + {\def\fastrecursebody{#4}% + \fastrecursecounter#1\relax + \lastrecursecounter#2\relax + \steprecursecounter#3\relax + \def\recurselevel{\number\fastrecursecounter}% + \dodofastrecurse} + +\def\dodofastrecurse + {\ifnum\fastrecursecounter>\lastrecursecounter\else + \fastrecursebody + \advance\fastrecursecounter\steprecursecounter + \expandafter\dodofastrecurse + \fi} + +%D This alternative looks a bit different and uses a +%D pseudo counter. When this macro is nested, we have to use +%D different counters. This time we use keywords. +%D +%D \starttyping +%D \def\alfa{2} \def\beta{100} \def\gamma{3} +%D +%D \for \n=55 \to 100 \step 1 \do {... \n ...} +%D \for \n=\alfa \to \beta \step \gamma \do {... \n ...} +%D \for \n=\n \to 120 \step 1 \do {... \n ...} +%D \for \n=120 \to 100 \step -3 \do {... \n ...} +%D \for \n=55 \to 100 \step 2 \do {... \n ...} +%D \stoptyping +%D +%D Only in the third example we need to predefine \type{\n}. +%D The use of \type{\od} as a dilimiter would have made nested +%D use more problematic. + +%D Don't use this one, it's kind of obsolete. + +\def\for#1=#2\to#3\step#4\do#5% + {\dostepwiserecurse{#2}{#3}{#4} + {\let#1\recurselevel#5\let#1\recurselevel}} + +%D \macros +%D {newevery,everyline,EveryLine,EveryPar} +%D +%D Lets skip to something quite different. It's common use +%D to use \type {\everypar} for special purposes. In \CONTEXT\ +%D we use this primitive for locating sidefloats. This means +%D that when user assignments to \type {\everypar} can interfere +%D with those of the package. We therefore introduce +%D \type {\EveryPar}. +%D +%D The same goes for \type {\EveryLine}. Because \TEX\ offers +%D no \type {\everyline} primitive, we have to call for +%D \type {\everyline} when we are working on a line by line +%D basis. Just by calling \type {\EveryPar{}} and +%D \type {\EveryLine{}} we restore the old situation. + +% \dorecurse{2}{ +% \expanded{\everypar{before \recurselevel\space}} +% \EveryPar{x } [before \recurselevel\space x] \par +% \EveryPar{y } [before \recurselevel\space y] \par +% \EveryPar{} [before \recurselevel] \par +% \EveryPar{x } \EveryPar{y } \EveryPar{} [before \recurselevel] \par +% \EveryPar{y } \everypar{before } [before] \par +% } + +% retrofit this into mkii + +\def\dowithevery#1% + {\expandafter\removetoks\expandafter\the\csname t\strippedcsname#1\endcsname\from#1% + \expandafter\appendtoks\expandafter\the\csname t\strippedcsname#1\endcsname\to #1% + \csname t\strippedcsname#1\endcsname} + +\def\newevery#1#2% + {\newtoks#1% we test for redefinition elsewhere + \ifx#2\relax\else\ifdefined#2\else + \expandafter\newtoks\csname t\strippedcsname#1\endcsname + \def#2{\dowithevery#1}% + \fi\fi} + +%D This one permits definitions like: + +\newevery \everypar \EveryPar % we get a warning which is ok +\newevery \everyline \EveryLine + +%D and how about: + +\newevery \neverypar \NeveryPar + +%D Which we're going to use indeed! When the second argument +%D equals \type {\relax}, the first token list is created +%D unless it is already defined. + +%D Technically spoken we could have used the method we are +%D going to present in the visual debugger. First we save +%D the primitive \type{\everypar}: +%D +%D \starttyping +%D \let\normaleverypar=\everypar +%D \stoptyping +%D +%D Next we allocate a \TOKENLIST\ named \type{\everypar}, +%D which means that \type{\everypar} is no longer a primitive +%D but something like \type{\toks44}. +%D +%D \starttyping +%D \newtoks\everypar +%D \stoptyping +%D +%D Because \TEX\ now executes \type{\normaleverypar} instead +%D of \type{\everypar}, we are ready to assign some tokens to +%D this internally known and used \TOKENLIST. +%D +%D \starttyping +%D \normaleverypar={all the things the system wants to do \the\everypar} +%D \stoptyping +%D +%D Where the user can provide his own tokens to be expanded +%D every time he expects them to expand. +%D +%D \starttyping +%D \everypar={something the user wants to do} +%D \stoptyping +%D +%D We don't use this method because it undoubtly leads to +%D confusing situations, especially when other packages are +%D used, but it's this kind of tricks that make \TEX\ so +%D powerful. + +%D \macros +%D {convertargument,convertcommand,convertvalue} +%D +%D Some persistent experimenting led us to the next macro. This +%D macro converts a parameter or an expanded macro to it's +%D textual meaning. +%D +%D \starttyping +%D \convertargument ... \to \command +%D \stoptyping +%D +%D For example, +%D +%D \starttyping +%D \convertargument{one \two \three{four}}\to\ascii +%D \stoptyping +%D +%D The resulting macro \type{\ascii} can be written to a file +%D or the terminal without problems. In \CONTEXT\ we use this +%D macro for generating registers and tables of contents. +%D +%D The second conversion alternative accepts a command: +%D +%D \starttyping +%D \convertcommand\command\to\ascii +%D \stoptyping +%D +%D Both commands accept the prefix \type{\doglobal} for global +%D assignments. + +\def\convertvalue#1\to + {\expandafter\convertcommand\csname#1\endcsname\to} + +\def\defconvertedvalue#1#2% less sensitive for \to + {\@EA\defconvertedcommand\@EA#1\csname#2\endcsname} + +%D \macros +%D {doifassignmentelse} +%D +%D A lot of \CONTEXT\ commands take optional arguments, for +%D instance: +%D +%D \starttyping +%D \dothisorthat[alfa,beta] +%D \dothisorthat[first=foo,second=bar] +%D \dothisorthat[alfa,beta][first=foo,second=bar] +%D \stoptyping +%D +%D Although a combined solution is possible, we prefer a +%D seperation. The next command takes care of propper +%D handling of such multi||faced commands. +%D +%D \starttyping +%D \doifassignmentelse {...} {then ...} {else ...} +%D \stoptyping + +% \def\doifassignmentelse#1% +% {\convertargument#1\to\ascii +% \doifinstringelse=\ascii} + +% \def\doifassignmentelse#1% +% {\edef\ascii{\detokenize{#1}}% +% \ifx\ascii\empty +% \expandafter\secondoftwoarguments +% \else +% \expandafter\docheckifassignmentelse +% \fi} + +% \long\def\dodoifassignmentelse +% {\expandafter\dododoifnotassignmentelse\ascii=@@\@end@ +% \expandafter\secondoftwoarguments +% \else +% \expandafter\firstoftwoarguments +% \fi} + +\long\def\docheckifassignmentelse#1=#2#3\@end@{\if#2@}% + +\long\def\doifassignmentelse#1% + {\expandafter\docheckifassignmentelse\detokenize{#1}=@@\@end@ + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +% D \macros +% D {convertasciiafter} +% D +% D Sometimes we need to convert an argument to a string (letters +% D only), for instance when we compare it with another string: +% D +% D \starttyping +% D \convertasciiafter\doifinstringelse{em}{\ascii}{...} +% D \stoptyping +% +% \def\convertasciiafter#1#2% +% {\@EA#1\@EA{\detokenize{#2}}} + +%D In \ETEX\ we can use \type {\detokenize} and gain some +%D speed, but in general far less that 1\% for \type +%D {\convertargument} and nil for \type {\convertcommand}. +%D This macro is more robust than the pure \TEX\ one, +%D something I found out when primitives like \type +%D {\jobname} were fed (or something undefined). + +\long\def\convertargument#1\to#2{\dodoglobal\edef#2{\detokenize{#1}}} +\long\def\convertcommand #1\to#2{\dodoglobal\edef#2{\@EA\detokenize\@EA{#1}}} % hm, only second is also ok + +\long\def\defconvertedargument #1#2{\edef#1{\detokenize {#2}}} +\long\def\defconvertedcommand #1#2{\edef#1{\detokenize\@EA{#2}}} +\long\def\edefconvertedargument#1#2{\edef#1{#2}% + \edef#1{\detokenize\@EA{#1}}} +\long\def\gdefconvertedargument#1#2{\xdef#1{\detokenize {#2}}} +\long\def\gdefconvertedcommand #1#2{\xdef#1{\detokenize\@EA{#2}}} +\long\def\xdefconvertedargument#1#2{\xdef#1{#2}% + \xdef#1{\detokenize\@EA{#1}}} + +%D When you try to convert a primitive command, you'll find +%D out that the \ETEX\ method fails on for instance \type +%D {\jobname} in the sense that it returns the filename +%D instead of just \type {\jobname}. So far this does not +%D give real problems. + +%D This is typically a macro that one comes to after reading +%D the \TEX book carefully. Even then, the definite solution +%D was found after rereading the \TEX book. The first +%D implementation was: +%D +%D \starttyping +%D \def\doconvertargument#1->#2\\\\{#2} +%D \stoptyping +%D +%D The \type{-}, the delimiter \type{\\\\} and the the second +%D argument are completely redundant. + +%D \macros +%D {showvalue,showargument} +%D +%D Two handy macros for testing purposes only: + +\def\showvalue#1% + {\expandafter\show\csname#1\endcsname} + +\def\showvalue#1% + {\ifcsname#1\endcsname + \expandafter\show\csname#1\endcsname + \else + \show\undefined + \fi} + +%D \macros +%D {doifmeaningelse} +%D +%D We can use both commands in testing, but alas, not all +%D meanings expand to something \type {->}. This is no problem +%D in the \ETEX\ implementation, but since we want +%D compatibility, we need: +%D +%D \starttyping +%D \doifmeaningelse {\next} {\something} {true} {false} +%D \stoptyping +%D +%D Watch the one level expansion of the second argument. + +\def\doifmeaningelse#1#2% + {\edef\!!stringa{\meaning#1}% + \def \!!stringb{#2}% + \edef\!!stringb{\meaning\!!stringb}% + \ifx\!!stringa\!!stringb + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifsamestringselse,doifsamestring,doifnotsamestring} +%D +%D The next comparison macro converts the arguments into +%D expanded strings. This command can be used to compare for +%D instance \type {\jobname} with a name stored in a macro. +%D +%D \starttyping +%D \doifelse {\jobname}{oeps}{YES}{NO} +%D \doifsamestringelse{\jobname}{oeps}{YES}{NO} +%D \stoptyping + +% \def\@@doifsamestringelse#1#2#3#4% +% {\edef\!!stringa{#3}\convertcommand\!!stringa\to\!!stringa +% \edef\!!stringb{#4}\convertcommand\!!stringb\to\!!stringb +% \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi} + +\def\@@doifsamestringelse#1#2#3#4% + {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#3}}}% + \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#4}}}% + \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi} + +\def\doifsamestringelse{\@@doifsamestringelse\firstoftwoarguments\secondoftwoarguments} +\def\doifsamestring {\@@doifsamestringelse\firstofoneargument\gobbleoneargument} +\def\doifnotsamestring {\@@doifsamestringelse\gobbleoneargument\firstofoneargument} + +%D \macros +%D {ExpandFirstAfter,ExpandSecondAfter,ExpandBothAfter} +%D +%D These three commands support expansion of arguments before +%D executing the commands that uses them. We can best +%D illustrate this with an example. +%D +%D \starttyping +%D \def\first {alfa,beta,gamma} +%D \def\second {alfa,epsilon,zeta} +%D +%D \ExpandFirstAfter \doifcommon {\first} {alfa} {\message{OK}} +%D \ExpandSecondAfter \doifcommon {alfa} {\second} {\message{OK}} +%D \ExpandBothAfter \doifcommon {\first} {\second} {\message{OK}} +%D +%D \ExpandFirstAfter\processcommalist[\first]\message +%D +%D \ExpandAfter \doifcommon {\first} {alfa} {\message{OK}} +%D \stoptyping +%D +%D The first three calls result in the threefold message +%D \type{OK}, the fourth one shows the three elements of +%D \type{\first}. The command \type{\ExpandFirstAfter} takes +%D care of (first) arguments that are delimited by \type{[ ]}, +%D but the faster \type{\ExpandAfter} does not. + +\def\simpleExpandFirstAfter#1% + {\long\xdef\@@expanded{\noexpand\ExpandCommand{#1}}\@@expanded} + +\def\complexExpandFirstAfter[#1]% + {\long\xdef\@@expanded{\noexpand\ExpandCommand[#1]}\@@expanded} + +\def\ExpandFirstAfter#1% + {\let\ExpandCommand#1% + \doifnextoptionalelse\complexExpandFirstAfter\simpleExpandFirstAfter} + +\def\ExpandSecondAfter#1#2#3% + {\scratchtoks{#2}% + \long\xdef\@@expanded{\noexpand#1{\the\scratchtoks}{#3}}\@@expanded} + +\def\ExpandBothAfter#1#2#3% + {\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded} + +\def\ExpandAfter#1#2% + {\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded} + +%D Now we can for instance define \type{\ifinstringelse} as: + +\def\ifinstringelse + {\ExpandBothAfter\p!doifinstringelse} + +%D \macros +%D {ConvertToConstant,ConvertConstantAfter} +%D +%D When comparing arguments with a constant, we can get into +%D trouble when this argument consists of tricky expandable +%D commands. One solution for this is converting the +%D argument to a string of unexpandable characters. To make +%D comparison possible, we have to convert the constant too +%D +%D \starttyping +%D \ConvertToConstant\doifelse {...} {...} {then ...} {else ...} +%D \stoptyping +%D +%D This construction is only needed when the first argument +%D can give troubles. Misuse can slow down processing. +%D +%D \starttyping +%D \ConvertToConstant\doifelse{\c!alfa} {\c!alfa}{...}{...} +%D \ConvertToConstant\doifelse{alfa} {\c!alfa}{...}{...} +%D \ConvertToConstant\doifelse{alfa} {alfa} {...}{...} +%D \ConvertToConstant\doifelse{alfa \alfa test}{\c!alfa}{...}{...} +%D \stoptyping +%D +%D In examples~2 and~3 both arguments equal, in~1 and~4 +%D they differ. + +\long\def\ConvertToConstant#1#2#3% + {\edef\!!stringa{\expandafter\detokenize\expandafter{#2}}% + \edef\!!stringb{\expandafter\detokenize\expandafter{#3}}% + #1{\!!stringa}{\!!stringb}} + +%D When the argument \type{#1} consists of commands, we had +%D better use +%D +%D \starttyping +%D \ConvertConstantAfter\processaction[#1][...] +%D \ConvertConstantAfter\doifelse{#1}{\v!something}{}{} +%D \stoptyping +%D +%D This commands accepts things like: +%D +%D \starttyping +%D \v!constant +%D constant +%D \hbox to \hsize{\rubish} +%D \stoptyping +%D +%D As we will see in the core modules, this macro permits +%D constructions like: +%D +%D \starttyping +%D \setupfootertexts[...][...] +%D \setupfootertexts[margin][...][...] +%D \setupfootertexts[\v!margin][...][...] +%D \stoptyping +%D +%D where \type{...} can be anything legally \TEX. + +\def\CheckConstantAfter#1#2% + {\@EA\convertargument\v!prefix!\to\ascii + \convertargument#1\to#2\relax + \doifinstringelse\ascii{#2} + {\expandafter\convertargument#1\to#2} + {}} + +\def\ConvertConstantAfter#1#2#3% + {\CheckConstantAfter{#2}\asciia + \CheckConstantAfter{#3}\asciib + #1{\asciia}{\asciib}} + +%D \macros +%D {assignifempty} +%D +%D We can assign a default value to an empty macro using: +%D +%D \starttyping +%D \assignifempty \macros {default value} +%D \stoptyping +%D +%D We don't explicitly test if the macro is defined. + +\def\assignifempty#1#2% can be sped up + {\doifsomething{#1}{\def#1{#2}}} % {\doifnot{#1}{}{\def#1{#2}}} + +%D \macros +%D {gobbleuntil,grabuntil,gobbleuntilrelax, +%D processbetween,processuntil} +%D +%D In \TEX\ gobbling usually stand for skipping arguments, so +%D here are our gobbling macros. +%D +%D In \CONTEXT\ we use a lot of \type{\start}||\type{\stop} +%D like constructions. Sometimes, the \type{\stop} is used as a +%D hard coded delimiter like in: +%D +%D \starttyping +%D \def\startcommand#1\stopcommand% +%D {... #1 ...} +%D \stoptyping +%D +%D In many cases the \type{\start}||\type{\stop} pair is +%D defined at format generation time or during a job. This +%D means that we cannot hardcode the \type{\stop} criterium. +%D Only after completely understanding \type{\csname} and +%D \type{\expandafter} I was able to to implement a solution, +%D starting with: +%D +%D \starttyping +%D \grabuntil{stop}\command +%D \stoptyping +%D +%D This commands executes, after having encountered +%D \type {\stop} the command \type {\command}. This command +%D receives as argument the text preceding the \type {\stop}. +%D This means that: +%D +%D \starttyping +%D \def\starthello% +%D {\grabuntil{stophello}\message} +%D +%D \starthello Hello world!\stophello +%D \stoptyping +%D +%D results in: \type{\message{Hello world!}}. + +\def\dograbuntil#1#2% + {\long\def\next##1#1{#2{##1}}\next} + +\def\grabuntil#1% + {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}} + +%D The next command build on this mechanism: +%D +%D \starttyping +%D \processbetween{string}\command +%D \stoptyping +%D +%D Here: +%D +%D \starttyping +%D \processbetween{hello}\message +%D \starthello Hello again!\stophello +%D \stoptyping +%D +%D leads to: \type{\message{Hello again!}}. The command +%D +%D \starttyping +%D \gobbleuntil{sequence} +%D \stoptyping +%D +%D is related to these commands. This one simply throws away +%D everything preceding \type{\command}. + +\long\def\processbetween#1#2% + {\setvalue{\s!start#1}{\grabuntil{\s!stop#1}{#2}}} + +\def\gobbleuntil#1% + {\long\def\next##1#1{}\next} + +\def\gobbleuntilrelax#1\relax + {} + +%D The next one simply expands the pickup up tokens. +%D +%D \starttyping +%D \processuntil{sequence} +%D \stoptyping + +\def\processuntil#1% + {\long\def\next##1#1{##1}\next} + +%D \macros +%D {groupedcommand} +%D +%D Commands often manipulate argument as in: +%D +%D \starttyping +%D \def\doezomaarwat#1{....#1....} +%D \stoptyping +%D +%D A disadvantage of this approach is that the tokens that +%D form \type{#1} are fixed the the moment the argument is read +%D in. Normally this is no problem, but for instance verbatim +%D environments adapt the \CATCODES\ of characters and therefore +%D are not always happy with already fixed tokens. +%D +%D Another problem arises when the argument is grouped not by +%D \type{{}} but by \type{\bgroup} and \type{\egroup}. Such an +%D argument fails, because the \type{\bgroup} is een as the +%D argument (which is quite normal). +%D +%D The next macro offers a solution for both unwanted +%D situations: +%D +%D \starttyping +%D \groupedcommand {before} {after} +%D \stoptyping +%D +%D Which can be used like: +%D +%D \starttyping +%D \def\cite% +%D {\groupedcommand{\rightquote\rightquote}{\leftquote\leftquote}} +%D \stoptyping +%D +%D This command is equivalent to, but more 'robust' than: +%D +%D \starttyping +%D \def\cite#1% +%D {\rightquote\rightquote#1\leftquote\leftquote} +%D \stoptyping +%D +%D \starttyping +%D \def\rightword% +%D {\groupedcommand{\hfill\hbox}{\parfillskip\!!zeropoint}} +%D +%D .......... \rightword{the right way} +%D \stoptyping +%D +%D Here \TEX\ typesets \type{\bf the right way} unbreakable +%D at the end of the line. The solution mentioned before does +%D not work here. We also handle +%D +%D \starttyping +%D to be \bold{bold} or not, that's the question +%D \stoptyping +%D +%D and +%D +%D \starttyping +%D to be {\bold bold} or not, that's the question +%D \stoptyping +%D +%D This alternative checks for a \type{\bgroup} token first. +%D The internal alternative does not accept the box handling +%D mentioned before, but further nesting works all right. The +%D extra \type{\bgroup}||\type{\egroup} is needed to keep +%D \type{\AfterGroup} both into sight and local. + +\long\def\HandleGroup#1#2% + {\bgroup + \long\def\BeforeGroup{\bgroup#1\bgroup\aftergroup\AfterGroup}% + \long\def\AfterGroup {#2\egroup\egroup}% + \afterassignment\BeforeGroup + \let\next=} + +\long\def\HandleSimpleGroup#1#2% no inner group (so no kerning interference) + {\bgroup + %long\def\BeforeGroup{\bgroup#1\aftergroup\AfterGroup}% interferes + \long\def\BeforeGroup{\bgroup\aftergroup\AfterGroup#1}% + \long\def\AfterGroup {#2\egroup}% + \afterassignment\BeforeGroup + \let\next=} + +\long\def\HandleNoGroup#1#2% + {\long\def\AfterGroup{#2\egroup}% + \bgroup\aftergroup\AfterGroup#1} + +%D I considered it a nuisance that +%D +%D \starttyping +%D \color[green] +%D {as grass} +%D \stoptyping +%D +%D was not interpreted as one would expect. This is due to the +%D fact that \type{\futurelet} obeys blank spaces, and a +%D line||ending token is treated as a blank space. So the final +%D implementation became: + +\long\unexpanded\def\groupedcommand#1#2% + {\doifnextbgroupelse{\HandleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}} + +\long\unexpanded\def\simplegroupedcommand#1#2% + {\doifnextbgroupelse{\HandleSimpleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}} + +%D Users should be aware of the fact that grouping can +%D interfere with ones paragraph settings that are executed +%D after the paragraph is closed. One should therefore +%D explictly close the paragraph with \type{\par}, else the +%D settings will be forgotten and not applied. So it's: +%D +%D \starttyping +%D \def\BoldRaggedCenter% +%D {\groupedcommand{\raggedcenter\bf}{\par}} +%D \stoptyping + +%D \macros +%D {checkdefined} +%D +%D The bigger the system, the greater the change that +%D user defined commands collide with those that are part of +%D the system. The next macro gives a warning when a command is +%D already defined. We considered blocking the definition, but +%D this is not always what we want. +%D +%D \starttyping +%D \checkdefined {category} {class} {command} +%D \stoptyping +%D +%D The user is warned with the suggestion to use +%D \type{CAPITALS}. This suggestion is feasible, because +%D \CONTEXT only defines lowcased macros. + +\def\showdefinederror#1#2% + {\writestatus\m!systems{#1 #2 replaces a macro, use CAPITALS!}} + +\def\checkdefined#1#2#3% + {\doifdefined{#3}{\showdefinederror{#2}{#3}}} + +%D \macros +%D {GotoPar,GetPar} +%D +%D Typesetting a paragraph in a special way can be done by +%D first grabbing the contents of the paragraph and processing +%D this contents grouped. The next macro for instance typesets +%D a paragraph in boldface. +%D +%D \starttyping +%D \def\remark#1\par% +%D {\bgroup\bf#1\egroup} +%D \stoptyping +%D +%D This macro has to be called like +%D +%D \starttyping +%D \remark some text ... ending with \par +%D \stoptyping +%D +%D Instead of \type{\par} we can of course use an empty line. +%D When we started typesetting with \TEX, we already had +%D produced lots of text in plain \ASCII. In producing such +%D simple formatted texts, we adopted an open layout, and when +%D switching to \TEX, we continued this open habit. Although +%D \TEX\ permits a cramped and badly formatted source, it adds +%D to confusion and sometimes introduces errors. So we prefer: +%D +%D \starttyping +%D \remark +%D +%D some text ... ending with an empty line +%D \stoptyping +%D +%D We are going to implement a mechanism that allows such open +%D specifications. The definition of the macro handling +%D \type{\remark} becomes: +%D +%D \starttyping +%D \def\remark% +%D {\BeforePar{\bgroup\bf}% +%D \AfterPar{\egroup}% +%D \GetPar} +%D \stoptyping +%D +%D A macro like \type{\GetPar} can be defined in several +%D ways. The recent version, the fourth one in a row, +%D originally was far more complicated, but some functionality +%D has been moved to other macros. +%D +%D We start with the more simple but in some cases more +%D appropriate alternative is \type{\GotoPar}. This one leaves +%D \type{\par} unchanged and is therefore more robust. On the +%D other hand, \type{\AfterPar} is not supported. + +\newtoks\BeforePar +\newtoks\AfterPar + +\let\endoflinetoken=^^M + +\def\redowithpar\par + {\doifnextcharelse\par\redowithpar\dodowithpar}% + +\def\dowithpar#1#2% + {\def\dodowithpar##1\par{#1##1#2}% + \redowithpar\par} + +\def\redogotopar\par + {\doifnextcharelse\par\redogotopar\dodogotopar}% + +\def\dogotopar#1% + {\def\dodogotopar{#1}% + \redogotopar\par} + +\def\GetPar + {\expanded + {\dowithpar + {\the\BeforePar + \BeforePar\emptytoks} + {\the\AfterPar + \BeforePar\emptytoks + \AfterPar\emptytoks}}} + +\def\GotoPar + {\expanded + {\dogotopar + {\the\BeforePar + \BeforePar\emptytoks}}} + +%D \macros +%D {dowithpargument,dowithwargument} +%D +%D The next macros are a variation on \type{\GetPar}. When +%D macros expect an argument, it interprets a grouped sequence +%D of characters a one token. While this adds to robustness and +%D less ambiguous situations, we sometimes want to be a bit +%D more flexible, or at least want to be a bit more tolerant +%D to user input. +%D +%D We start with a commands that acts on paragraphs. This +%D command is called as: +%D +%D \starttyping +%D \dowithpargument\command +%D \dowithpargument{\command ... } +%D \stoptyping +%D +%D In \CONTEXT\ we use this one to read in the titles of +%D chapters, sections etc. The commands responsible for these +%D activities accept several alternative ways of argument +%D passing. In these examples, the \type{\par} can be omitted +%D when an empty line is present. +%D +%D \starttyping +%D \command{...} +%D \command ... \par +%D \command +%D {...} +%D \command +%D ... \par +%D \stoptyping + +\def\dowithpargument#1% + {\def\nextpar##1 \par{#1{##1}}% + \def\nextarg##1{#1{##1}}% + \doifnextbgroupelse\nextarg{\doifnextcharelse\par{#1{}}\nextpar}} + +%D The \type{p} in the previous command stands for paragraph. +%D When we want to act upon words we can use the \type{w} +%D alternative. +%D +%D \starttyping +%D \dowithwargument\command +%D \dowithwargument{... \command ...} +%D \stoptyping +%D +%D The main difference bwteen two alternatives is in the +%D handling of \type{\par}'s. This time the space token acts +%D as a delimiter. +%D +%D \starttyping +%D \command{...} +%D \command ... +%D \command +%D {...} +%D \command +%D ... +%D \stoptyping + +\def\dowithwargument#1% + {\def\nextwar##1 {#1{##1}}% + \def\nextarg##1{#1{##1}}% + \doifnextbgroupelse\nextarg\nextwar} + +%D \macros +%D {dorepeat,dorepeatwithcommand} +%D +%D When doing repetitive tasks, we stromgly advice to use +%D \type{\dorecurse}. The next alternative however, suits +%D better some of the \CONTEXT\ interface commands. +%D +%D \starttyping +%D \dorepeat[n*\command] +%D \stoptyping +%D +%D The value of the used \COUNTER\ can be called within +%D \type{\command} by \type{\repeater}. +%D +%D A slightly different alternative is: +%D +%D \starttyping +%D \dorepeatwithcommand[n*{...}]\command +%D \stoptyping +%D +%D When we call for something like: +%D +%D \starttyping +%D \dorepeatwithcommand[3*{Hello}]\message +%D \stoptyping +%D +%D we get ourselves three \type{\message{Hello}} messages in +%D a row. In both commands, the \type{n*} is optional. When this +%D specification is missing, the command executes once. + +% this one is obsolete: + +\def\dorepeat[#1]% + {\dodorepeat#1*\empty*\relax} + +\long\def\dodorepeat#1*#2#3*#4\relax + {\ifx#2\empty#1\else\dorecurse{#1}{#2#3}\fi} + +\def\repeater + {\recurselevel} + +% this one will be kept + +\def\dorepeatwithcommand[#1]% + {\dodorepeatwithcommand#1*\empty*\relax} + +\long\def\dodorepeatwithcommand#1*#2#3*#4\relax#5% + {\ifx#2\empty\redorepeatwithcommand[#1]#5\else\dododorepeatwithcommand{#1}{#2}{#3}#5\fi} + +\long\def\dododorepeatwithcommand#1#2#3#4% + {\ifx#2\empty % redundant but gives cleaner extensions + #4{#1}% + \else\ifnum#1<\zerocount + \bgroup\scratchcounter#1% + \expanded{\egroup\noexpand\dorecurse{\number-\scratchcounter}}{#4{-#2#3}}% + \else\ifx#2+% + \dorecurse{#1}{#4{#3}}% + \else + \dorecurse{#1}{#4{#2#3}}% + \fi\fi\fi} + +\def\redorepeatwithcommand[#1]#2% + {#2{#1}} + +%D The extension hook permits something like: +%D +%D \starttyping +%D \bgroup +%D +%D \catcode`\*=\@@superscript +%D +%D \gdef\redorepeatwithcommand[#1]% +%D {\redodorepeatwithcommand#1*\empty*\relax} +%D +%D \long\gdef\redodorepeatwithcommand#1*#2#3*#4\relax#5% +%D {\dododorepeatwithcommand{#1}{#2}{#3}#5} +%D +%D \egroup +%D \stoptyping +%D +%D although one may wonder if changing the catcode of \type {*} is wise. + +%D \macros +%D {normalbgroup,normalgroup} +%D +%D No comment. + +\let\normalbgroup\bgroup +\let\normalegroup\egroup + +%D \macros +%D {doifstringinstringelse} +%D +%D The next macro is meant for situations where both strings +%D are macros. This save some unneeded expansion. +%D +%D \starttyping +%D \long\def\doifstringinstringelse#1#2% +%D {\p!doifinstringelse#1#2% +%D \@EA\firstoftwoarguments +%D \else +%D \@EA\secondoftwoarguments +%D \fi} +%D \stoptyping +%D +%D A bit faster is: + +\def\pp!doifstringinstringelse#1% + {\if#1@% + \@EA\secondoftwoarguments + \else + \@EA\firstoftwoarguments + \fi} + +\long\def\doifstringinstringelse#1#2% + {\long\@EA\def\@EA\p!doifstringinstringelse\@EA##\@EA1#1##2##3\war + {\pp!doifstringinstringelse##2}% + \@EA\@EA\@EA\p!doifstringinstringelse\@EA#2#1@@\war} + +%D \macros +%D {appendtoks,prependtoks,appendtoksonce,prependtoksonce, +%D doifintokselse,flushtoks,dotoks} +%D +%D We use \TOKENLISTS\ sparsely within \CONTEXT, because the +%D comma separated lists are more suitable for the user +%D interface. Nevertheless we have: +%D +%D \starttyping +%D (\doglobal) \appendtoks ... \to\tokenlist +%D (\doglobal) \prependtoks ... \to\tokenlist +%D (\doglobal) \flushtoks\tokenlist +%D \dotoks\tokenlist +%D \stoptyping +%D +%D Er worden eerst enkele klad||registers gedefinieerd. These +%D macros are clones of the ones implemented in page~378 of +%D Knuth's \TeX book. + +\newtoks\@@scratchtoks + +\def\appendtoks {\doappendtoks \relax} +\def\prependtoks {\doprependtoks \relax} +\def\appendtoksonce {\doappendtoksonce \relax} +\def\prependtoksonce{\doprependtoksonce\relax} + +\def\dodoappendtoks + {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@toks\the\@@scratchtoks}} + +\def\dodoprependtoks + {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@scratchtoks\the\@@toks}} + +\long\def\doappendtoks#1\to#2% + {\def\@@toks{#2}% + \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoappendtoks} + +\long\def\doprependtoks#1\to#2% + {\def\@@toks{#2}% + \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoprependtoks} + +\long\def\doappendtoksonce#1\to#2% + {\def\@@toks{#2}% + \@@scratchtoks\@EA{\gobbleoneargument#1}% + \doifintokselse\@@scratchtoks\@@toks\donothing\dodoappendtoks} + +\long\def\doprependtoksonce#1\to#2% + {\def\@@toks{#2}% + \@@scratchtoks\@EA{\gobbleoneargument#1}% + \doifintokselse\@@scratchtoks\@@toks\donothing\dodoprependtoks} + +%D The test macro: + +\def\doifintokselse#1#2% #1 en #2 zijn toks + {\edef\asciia{\detokenize\expandafter{\the#1}}% + \edef\asciib{\detokenize\expandafter{\the#2}}% + \doifstringinstringelse\asciia\asciib} + +%D A nice one too: + +% {\scratchtoks{abc} \removetoks b\from\scratchtoks [\the\scratchtoks]} +% {\scratchtoks{abc} \removetoks x\from\scratchtoks [\the\scratchtoks]} +% {\scratchtoks{} \removetoks x\from\scratchtoks [\the\scratchtoks]} +% {\scratchtoks{xaa} \removetoks x\from\scratchtoks [\the\scratchtoks]} +% {\scratchtoks{a\relax b} \removetoks \relax\from\scratchtoks [\showthe\scratchtoks]} + +\def\removetoks#1\from#2% + {\def\doremovetoks##1#1##2\empty\empty\empty##3\\% + {\def\!!stringa{##3}% + \ifx\!!stringa\empty#2{##1}\else#2{##1##2}\fi}% + \expandafter\doremovetoks\the#2\empty\empty\empty#1\empty\empty\empty\\} + +%D Also: + +\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to} +\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to} + +%D Hm. + +\def\flushtoks#1% nb: can reassing to #1 again, hence the indirectness + {\@@scratchtoks#1\relax + \dodoglobal#1\emptytoks + \the\@@scratchtoks\relax} + +\let\dotoks\the + +%D \macros +%D {makecounter,pluscounter,minuscounter, +%D resetcounter,setcounter,countervalue} +%D +%D Declaring, setting and resetting \COUNTERS\ can be done +%D with the next set of commands. +%D +%D \starttyping +%D \makecounter {name} +%D \pluscounter {name} +%D \minuscounter {name} +%D \resetcounter {name} +%D \setcounter {name} {value} +%D \countervalue {name} +%D \stoptyping + +\def\makecounter#1% + {\global\@EA\let\csname#1\endcsname\zerocountervalue} % see earlier + +\def\countervalue#1% + {\ifcsname#1\endcsname\csname#1\endcsname\fi} + +\def\pluscounter#1% + {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname+\plusone\relax}} + +\def\minuscounter#1% + {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname-\plusone\relax}} + +\def\resetcounter#1% + {\global\@EA\let\csname#1\endcsname\zerocountervalue} + +\def\setcounter#1#2% + {\@EA\xdef\csname#1\endcsname{\the\numexpr#2\relax}} + +\def\savecounter#1% + {\@EA\xdef\csname ! #1 !\endcsname{\the\numexpr\csname#1\endcsname\relax}} + +\def\restorecounter#1% + {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname ! #1 !\endcsname\relax}} + +%D \macros +%D {beforesplitstring,aftersplitstring} +%D +%D These both commands split a string at a given point in two +%D parts, so \type{x.y} becomes \type{x} or \type{y}. +%D +%D \starttyping +%D \beforesplitstring test.tex\at.\to\filename +%D \aftersplitstring test.tex\at.\to\extension +%D \stoptyping +%D +%D The first routine looks (and is indeed) a bit simpler than +%D the second one. The alternative looking more or less like +%D the first one did not always give the results we needed. +%D Both implementations show some insight in the manipulation +%D of arguments. + +\def\beforesplitstring#1\at#2\to#3% + {\def\dosplitstring##1#2##2#2##3\\% + {\def#3{##1}}% + \@EA\dosplitstring#1#2#2\\} + +\def\aftersplitstring#1\at#2\to#3% + {\def\dosplitstring##1#2##2@@@##3\\% + {\def#3{##2}}% + \@EA\dosplitstring#1@@@#2@@@\\} + +%D \macros +%D {splitstring,greedysplitstring} +%D +%D A bonus macro. + +\def\splitstring#1\at#2\to#3\and#4% + {\def\dosplitstring##1#2##2\empty\empty\empty##3\\% + {\def#3{##1}% + \def\dosplitstring{##3}% + \ifx\dosplitstring\empty + \let#4\empty + \else + \def#4{##2}% + \fi}% + \@EA\dosplitstring#1\empty\empty\empty#2\empty\empty\empty\\} + +\def\greedysplitstring#1\at#2\to#3\and#4% + {\edef\asciib{#1}% + \let\asciic\asciib + \let#3\empty + \let#4\empty + \doloop + {\expandafter\splitstring\asciib\at#2\to\asciia\and\asciib + \ifx\asciib\empty + \exitloop + \else + % not \edef#3{\ifx#3\empty\else#3#2\fi\asciia} else + % /root/path fails because then #3==empty + \edef#3{\ifcase\recurselevel\or\else#3#2\fi\asciia}% + \let#4\asciib + \fi}% + \ifx#3\empty\let#3\asciic\fi} + +%D \macros +%D {beforetestandsplitstring, +%D aftertestandsplitstring, +%D testandsplitstring} + +\def\beforetestandsplitstring#1\at#2\to#3% + {\def\dosplitstring##1#2##2#2##3##4\\% + {\ifx##3\empty\let#3\empty\else\def#3{##1}\fi}% + \@EA\dosplitstring#1#2#2\empty\\} + +\def\aftertestandsplitstring#1\at#2\to#3% + {\def\dosplitstring ##1#2##2@@@##3##4\\% + {\ifx##3\empty\let#3\empty\else\def#3{##2}\fi}% + \@EA\dosplitstring #1@@@#2@@@\empty\\} + +\def\testandsplitstring#1\at#2\to#3\and#4% + {\def\dosplitstring##1#2##2#2##3##4\\% + {\ifx##3\empty\let#3\empty\let#4\empty\else\def#3{##1}\def#4{##2}\fi}% + \@EA\dosplitstring#1#2#2\empty\\} + +%D \macros +%D {removesubstring} +%D +%D A first application of the two routines defined above is: +%D +%D \starttyping +%D \removesubstring-\from first-last\to\nothyphenated +%D \stoptyping +%D +%D Which in terms of \TEX\ looks like: + +\def\removesubstring#1\from#2\to#3% + {\splitstring#2\to\!!stringa\and\!!stringb + \dodoglobal#3{\!!stringa\!!stringb}} + +%D \macros +%D {appendtocommalist,prependtocommalist, +%D addtocommalist,removefromcommalist} +%D +%D When working with comma separated lists, one sooner or +%D later want the tools to append or remove items from such a +%D list. When we add an item, we first check if it's already +%D there. This means that every item in the list is unique. +%D +%D \starttyping +%D \addtocommalist {alfa} \name +%D \addtocommalist {beta} \name +%D \addtocommalist {gamma} \name +%D \removefromcommalist {beta} \name +%D \stoptyping +%D +%D These commands can be prefixed with \type{\doglobal}. The +%D implementation of the second command is more complecated, +%D because we have to take leading spaces into account. Keep in +%D mind that users may provide lists with spaces after the +%D commas. When one item is left, we also have to get rid of +%D trailing spaces. +%D +%D \starttyping +%D \def\words{alfa, beta, gamma, delta} +%D \def\words{alfa,beta,gamma,delta} +%D \stoptyping +%D +%D Removing an item takes more time than adding one. +%D +%D A fast appending alternative, without any testing, is +%D also provided: +%D +%D \starttyping +%D \appendtocommalist {something} \name +%D \prependtocommalist {something} \name +%D \stoptyping +%D +%D This can be implemented as follows: +%D +%D \starttyping +%D \def\appendtocommalist#1#2% +%D {\ifx#2\empty +%D \dodoglobal\edef#2{#1}% +%D \else % no test on empty +%D \dodoglobal\edef#2{#2,#1}% +%D \fi} +%D +%D \def\prependtocommalist#1#2% +%D {\ifx#2\empty +%D \dodoglobal\edef#2{#1}% +%D \else % no test on empty +%D \dodoglobal\edef#2{#1,#2}% +%D \fi} +%D \stoptyping +%D +%D The faster alternatives are: + +\def\appendtocommalist#1#2% + {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}} + +\def\prependtocommalist#1#2% + {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}} + +\def\addtocommalist#1#2% {item} \cs + {\rawdoifinsetelse{#1}#2\resetglobal + {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}} + +\def\pretocommalist#1#2% {item} \cs + {\rawdoifinsetelse{#1}#2\resetglobal + {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}} + +\def\robustdoifinsetelse#1#2% + {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#1}}}% + \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#2}}}% + \rawdoifinsetelse\!!stringa\!!stringb} + +\def\robustaddtocommalist#1#2% {item} \cs + {\robustdoifinsetelse{#1}#2\resetglobal + {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}} + +\def\robustpretocommalist#1#2% {item} \cs + {\robustdoifinsetelse{#1}#2\resetglobal + {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}} + +\def\xsplitstring#1#2% \cs {str} + {\def\dosplitstring##1,#2,##2,#2,##3\\% + {\edef\!!stringa{\bcleanedupcommalist##1\empty\empty\relax}% + \edef\!!stringb{\acleanedupcommalist##2,,\relax}}% + \@EA\dosplitstring\@EA,#1,,#2,,#2,\\} + +\def\bcleanedupcommalist#1#2#3\relax{\if#1,\else#1\fi\if#2,\else#2\fi#3} +\def\bcleanedupcommalist#1#2\relax{\if#1,\else#1\fi#2} +\def\acleanedupcommalist#1,,#2\relax{#1} + +\def\removefromcommalist#1#2% to be sped up + {\rawdoifinsetelse{#1}#2% + {\normalexpanded{\noexpand\xsplitstring\noexpand#2{#1}}% + \dodoglobal\edef#2% + {\ifx\!!stringa\empty + \!!stringb + \else + \!!stringa\ifx\!!stringb\empty\else,\!!stringb\fi + \fi}} + \resetglobal} + +%D \macros +%D {substituteincommalist} +%D +%D Slow but seldom used, so for the moment we stick to this +%D implementation. +%D +%D \starttyping +%D \substituteincommalist{old}{new}{list} +%D \stoptyping + +\def\substituteincommalist#1#2#3% old, new, list (slooow) + {\edef\!!stringb{#1}% + \edef\!!stringd{#2}% + \let\!!stringa#3% + \let#3\empty + \def\dosubstituteincommalist##1% + {\edef\!!stringc{##1}% + \ifx\!!stringb\!!stringc + \ifx\!!stringd\empty\else + \edef#3{#3\ifx#3\empty\else,\fi\!!stringd}% + \fi + \def\docommand####1{\edef#3{#3,####1}}% + \else + \edef#3{#3\ifx#3\empty\else,\fi##1}% + \fi}% + \@EA\rawprocesscommacommand\@EA[\!!stringa]\dosubstituteincommalist} + +%D A not so useful macro: + +\def\dodofrontstrip[#1#2]#3% + {\ifx#1\space + \def#3{#2}% + \else + \def#3{#1#2}% + \fi} + +\def\dofrontstrip#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty \else + \@EA\dodofrontstrip\@EA[#1]#1% + \fi} + +%D \macros +%D {replaceincommalist} +%D +%D The next macro can be used to replace an indexed element +%D in a commalist: +%D +%D \starttyping +%D \replaceincommalist\MyList{2} +%D \stoptyping +%D +%D Element~2 will be replaced by the current meaning of the macro +%D \type {\newcommalistelement}. The old meaning is saved in +%D \type {\commalistelement}. The replacement honors grouped items, +%D like in: +%D +%D \starttyping +%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3} +%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3} +%D \def\MyList{a,{b,c},d,e,f} \replaceincommalist\MyList{3} +%D \def\MyList{a,b,c,{d,e,f}} \replaceincommalist\MyList{3} +%D \stoptyping + +\let\newcommalistelement\empty + +\def\replaceincommalist#1#2% #1 = commalistelement #2 = position starts at 1 + {\def\doreplaceincommalist##1% + {\ifnum\commalistcounter=#2\relax + \ifx\newcommalistelement\empty\else + \ifx\newcommalist\empty + \let\newcommalist\newcommalistelement + \else + \@EA\@EA\@EA\def\@EA\@EA\@EA\newcommalist\@EA\@EA\@EA + {\@EA\newcommalist\@EA,\newcommalistelement}% + \fi + \fi + \def\commalistelement{##1}% + \else + \ifx\newcommalist\empty + \ifx\nexttoken\bgroup % is known -) + \def\newcommalist{{##1}}% + \else + \def\newcommalist{##1}% + \fi + \else + \ifx\nexttoken\bgroup % is known -) + \@EA\def\@EA\newcommalist\@EA{\newcommalist,{##1}}% + \else + \@EA\def\@EA\newcommalist\@EA{\newcommalist,##1}% + \fi + \fi + \fi + \advance\commalistcounter\plusone}% + \let\commalistelement\empty + \let\newcommalist\empty + \commalistcounter\plusone + \@EA\processcommalist\@EA[#1]\doreplaceincommalist + \dodoglobal\let#1\newcommalist} + +%D \macros +%D {globalprocesscommalist} +%D +%D The commalist processing commands are characterized by the +%D fact that the way they handle expansion as well as the fact +%D that they can be nested. This makes them kind of useless for +%D handling comma lists in alignments. In these situations the +%D next macro can be of use. + +\def\globalprocesscommaitem#1,% + {\if]#1\else + \globalcommacommand{#1}% + \expandafter\globalprocesscommaitem + \fi} + +\def\globalprocesscommalist[#1]#2% + {\global\let\globalcommacommand#2% + \expandafter\globalprocesscommaitem#1,],} + +%D \macros +%D {withoutpt,PtToCm, +%D numberofpoints,dimensiontocount} +%D +%D We can convert point into centimeters with: +%D +%D \starttyping +%D \PtToCm{dimension} +%D \stoptyping + +{\catcode`\.=\@@other + \catcode`\p=\@@other + \catcode`\t=\@@other + \gdef\WITHOUTPT#1pt{#1}} + +\def\withoutpt#1% + {\expandafter\WITHOUTPT#1} + +%D The capitals are needed because \type{p} and \type{t} have +%D \CATCODE~12, while macronames only permit tokens with the +%D \CATCODE~11. As a result we cannot use the \type{.group} +%D primitives. Those who want to know more about this kind of +%D manipulations, we advice to study the \TEX book in detail. +%D Because this macro does not do any assignment, we can use it +%D in the following way too. + +\def\PtToCm#1% + {\withoutpt\the\dimexpr0.0351459804\dimexpr#1\relax\relax cm} + +%D We also support: +%D +%D \starttyping +%D \numberofpoints {dimension} +%D \dimensiontocount {dimension} {\count} +%D \stoptyping +%D +%D Both macros return a rounded number. + +% \dimensiontocount{10.49pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.49pt} +% \dimensiontocount{10.51pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.51pt} + +\def\dimensiontocount#1#2{#2\numexpr\dimexpr#1\relax/\maxcard\relax} +\def\numberofpoints #1{\the\numexpr\dimexpr#1\relax/\maxcard\relax} + +%D \macros +%D {swapdimens,swapmacros} +%D +%D Simple but effective are the next two macros. There name +%D exactly states their purpose. The \type{\scratchdimen} and +%D \type{\!!stringa} can only be swapped when being the first +%D argument. + +\def\swapdimens#1#2% + {\scratchdimen #1\redoglobal #1#2\dodoglobal #2\scratchdimen} + +\def\swapmacros#1#2% + {\let\!!stringa#1\redoglobal\let#1#2\dodoglobal\let#2\!!stringa} + +%D \macros +%D {pushmacro,popmacro} +%D +%D Premature and a bit of beta, we offer: +%D +%D \starttyping +%D \pushmacro\macro +%D \popmacro\macro +%D \stoptyping +%D +%D Beware: global! + +\def\@sl@{@sl@} +\def\@sg@{@sg@} + +\let\@@pushedmacro\empty + +\def\globalpushmacro#1% + {\xdef\@@pushedmacro{\string#1}% + \ifcsname\@sg@\@@pushedmacro\endcsname \else + \@EA\newcount\csname\@sg@\@@pushedmacro\endcsname + \fi + \global\advance\csname\@sg@\@@pushedmacro\endcsname \plusone + \global\@EA\let\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} + +\def\globalpopmacro#1% + {\xdef\@@pushedmacro{\string#1}% + \global\@EA\let\@EA#1\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname + \global\advance\csname\@sg@\@@pushedmacro\endcsname \minusone} + +\def\localpushmacro#1% this one can be used to push a value over an \egroup + {\xdef\@@pushedmacro{\string#1}% + \ifcsname\@sl@\@@pushedmacro\endcsname \else + \@EA\newcount\csname\@sl@\@@pushedmacro\endcsname + \fi + \global\advance\csname\@sl@\@@pushedmacro\endcsname \plusone + \global\@EA\let\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} + +\def\localpopmacro#1% + {\xdef\@@pushedmacro{\string#1}% + \@EA\let\@EA#1\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname + \global\advance\csname\@sl@\@@pushedmacro\endcsname \minusone } + +\let\pushmacro\localpushmacro +\let\popmacro \localpopmacro + +%D \macros +%D {setlocalhsize} +%D +%D Sometimes we need to work with the \type{\hsize} that is +%D corrected for indentation and left and right skips. The +%D corrected value is available in \type{\localhsize}, which +%D needs to be calculated with \type{\setlocalhsize} first. +%D +%D \starttyping +%D \setlocalhsize \hbox to \localhsize{...} +%D \setlocalhsize[-1em] \hbox to \localhsize{...} +%D \setlocalhsize[.5ex] \hbox to \localhsize{...} +%D \stoptyping +%D +%D These examples show us that an optional can be used. The +%D value provided is added to \type{\localhsize}. + +\newdimen\localhsize + +\def\complexsetlocalhsize[#1]% don't change ! + {\localhsize\hsize + \ifnum\hangafter<\zerocount + \advance\localhsize\ifdim\hangindent>\zeropoint-\fi\hangindent + \fi + \advance\localhsize -\leftskip + \advance\localhsize -\rightskip + \advance\localhsize #1\relax} + +\def\simplesetlocalhsize + {\complexsetlocalhsize[\zeropoint]} + +\definecomplexorsimple\setlocalhsize + +%D \macros +%D {doifvalue,doifnotvalue,doifelsevalue, +%D doifnothing,doifsomething,doifelsenothing, +%D doifvaluenothing,doifvaluesomething,doifelsevaluenothing} +%D +%D These long named \type{\if} commands can be used to access +%D macros (or variables) that are normally accessed by using +%D \type{\getvalue}. Using these alternatives safes us three +%D tokens per call. Anyone familiar with the not||values +%D ones, can derive their meaning from the definitions. + + \def\doifvalue#1{\doif {\csname#1\endcsname}} + \def\doifnotvalue#1{\doifnot {\csname#1\endcsname}} + \def\doifelsevalue#1{\doifelse{\csname#1\endcsname}} + + \def\doifnothing#1{\doif {#1}{}} + \def\doifsomething#1{\doifnot {#1}{}} + \def\doifelsenothing#1{\doifelse{#1}{}} + + \def\doifvaluenothing#1{\doif {\csname#1\endcsname}{}} + \def\doifvaluesomething#1{\doifnot {\csname#1\endcsname}{}} +\def\doifelsevaluenothing#1{\doifelse{\csname#1\endcsname}{}} + +%D Faster but spoiling inheritance (copying parameters): +%D +%D \starttyping +%D \def\doifelsevaluesomething#1#2#3% +%D {\expandafter\ifx\csname#1\endcsname\empty#3\else#2\fi} +%D +%D \def\doifvaluesomething#1#2% +%D {\expandafter\ifx\csname#1\endcsname\empty\else#2\fi} +%D +%D \def\doifvaluenothing#1#2% +%D {\expandafter\ifx\csname#1\endcsname\empty#2\fi} +%D \stoptyping +%D +%D Slightly more efficient: + + \def\doifnothing{\doif \empty} + \def\doifsomething{\doifnot \empty} +\def\doifelsenothing{\doifelse\empty} + +%D The somewhat faster alternatives are: + +\long\def\doifvalue#1#2% + {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% + \ifx\!!stringa\!!stringb + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\doifnotvalue#1#2% + {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% + \ifx\!!stringa\!!stringb + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\long\def\doifelsevalue#1#2% + {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% + \ifx\!!stringa\!!stringb + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\long\def\doifnothing#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\doifsomething#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\long\def\doifelsenothing#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\long\def\doifsomethingelse#1% + {\edef\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +\long\def\doifvaluenothing#1% + {\edef\!!stringa{\csname#1\endcsname}% + \ifx\!!stringa\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\doifvaluesomething#1% + {\edef\!!stringa{\csname#1\endcsname}% + \ifx\!!stringa\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\long\def\doifelsevaluenothing#1% + {\edef\!!stringa{\csname#1\endcsname}% + \ifx\!!stringa\empty + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifemptyelsevalue, doifemptyvalue, doifnotemptyvalue} +%D +%D Also handy: + +\def\doifemptyelsevalue#1% + {\@EA\ifx\csname#1\endcsname\empty + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\doifemptyvalue#1% + {\@EA\ifx\csname#1\endcsname\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\def\doifnotemptyvalue#1% + {\@EA\ifx\csname#1\endcsname\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +%D \macros +%D {doifallcommonelse} +%D +%D A complete match of two sets can be tested with +%D \type {\doifallcommonelse}, where the first two +%D arguments are sets. + +\def\@@doifallcommonelse#1#2#3#4% slow + {\def\p!docommoncheck##1% + {\doifnotinset{##1}{#4}\donefalse + \ifdone\else\expandafter\quitcommalist\fi}% + \donetrue + \processcommalist[#3]\p!docommoncheck + \ifdone\expandafter#1\else\expandafter#2\fi} + +\def\doifallcommonelse + {\@@doifallcommonelse\firstoftwoarguments\secondoftwoarguments} + +\def\doifallcommon + {\@@doifallcommonelse\firstofonearguments\gobbleoneargument} + +\def\doifnotallcommon + {\@@doifallcommonelse\gobbleoneargument\firstofonearguments} + +%D \macros +%D {DOIF,DOIFELSE,DOIFNOT} +%D +%D \TEX\ is case sensitive. When comparing arguments, this +%D feature sometimes is less desirable, for instance when we +%D compare filenames. The next three alternatives upcase their +%D arguments before comparing them. +%D +%D \starttyping +%D \DOIF {string1} {string2} {...} +%D \DOIFNOT {string1} {string2} {...} +%D \DOIFELSE {string1} {string2} {then ...}{else ...} +%D \stoptyping +%D +%D We have to use a two||step implementation, because the +%D expansion has to take place outside \type{\uppercase}. + +\def\p!DOIF#1#2% + {\uppercase{\ifinstringelse{$#1$}{$#2$}}% + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\def\p!DOIFNOT#1#2% + {\uppercase{\ifinstringelse{$#1$}{$#2$}}% + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\def\p!DOIFELSE#1#2% + {\uppercase{\ifinstringelse{$#1$}{$#2$}}% + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\p!DOIFINSTRINGELSE#1#2% + {\uppercase{\ifinstringelse{#1}{#2}}% + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\DOIF {\ExpandBothAfter\p!DOIF} +\def\DOIFNOT {\ExpandBothAfter\p!DOIFNOT} +\def\DOIFELSE {\ExpandBothAfter\p!DOIFELSE} +\def\DOIFINSTRINGELSE {\ExpandBothAfter\p!DOIFINSTRINGELSE} + +%D \macros +%D {dosingleargumentwithset, +%D dodoubleargumentwithset,dodoubleemptywithset, +%D dotripleargumentwithset,dotripleemptywithset} +%D +%D These maybe too mysterious macros enable us to handle more +%D than one setup at once. +%D +%D \starttyping +%D \dosingleargumentwithset \command[#1] +%D \dodoubleargumentwithset \command[#1][#2] +%D \dotripleargumentwithset \command[#1][#2][#3] +%D \dodoubleemptywithset \command[#1][#2] +%D \dotripleemptywithset \command[#1][#2][#3] +%D \stoptyping +%D +%D The first macro calls \type{\command[##1]} for each string +%D in the set~\type{#1}. The second one calls for +%D \type{\commando[##1][#2]} and the third, well one may guess. +%D These commands support constructions like: +%D +%D \starttyping +%D \def\dodefinesomething[#1][#2]% +%D {\getparameters[\??xx#1][#2]} +%D +%D \def\definesomething% +%D {\dodoubleargumentwithset\dodefinesomething} +%D \stoptyping +%D +%D Which accepts calls like: +%D +%D \starttyping +%D \definesomething[alfa,beta,...][variable=...,...] +%D \stoptyping +%D +%D Now a whole bunch of variables like \type{\@@xxalfavariable} +%D and \type{\@@xxbetavariable} is defined. + +\def\dodoublewithset[#1][#2]% + {\doifsomething{#1} + {\def\@@dodowithsetcommand##1{\@@dowithsetcommand[##1][#2]}% + \processcommalist[#1]\@@dodowithsetcommand}} + +\def\dotriplewithset[#1][#2][#3]% + {\doifsomething{#1} + {\def\@@dodowithsetcommand##1{\@@dowithsetcommand[##1][#2][#3]}% + \processcommalist[#1]\@@dodowithsetcommand}} + +\def\dodoubleemptywithset #1{\let\@@dowithsetcommand#1\dodoubleempty \dodoublewithset} % \command +\def\dodoubleargumentwithset#1{\let\@@dowithsetcommand#1\dodoubleargument\dodoublewithset} % \command + +\def\dotripleemptywithset #1{\let\@@dowithsetcommand#1\dotripleempty \dotriplewithset} % \command +\def\dotripleargumentwithset#1{\let\@@dowithsetcommand#1\dotripleargument\dotriplewithset} % \command + +%D \macros +%D {stripcharacters,stripspaces} +%D +%D The next command was needed first when we implemented +%D the \CONTEXT\ interactivity macros. When we use labeled +%D destinations, we often cannot use all the characters we +%D want. We therefore strip some of the troublemakers, like +%D spaces, from the labels before we write them to the +%D \DVI||file, which passes them to for instance a PostScript +%D file. +%D +%D \starttyping +%D \stripspaces\from\one\to\two +%D \stoptyping +%D +%D Both the old string \type{\one} and the new one \type{\two} +%D are expanded. This command is a special case of: +%D +%D \starttyping +%D \stripcharacter\char\from\one\to\two +%D \stoptyping +%D +%D As we can see below, spaces following a control sequence are +%D to enclosed in \type{{}}. + +\def\stripcharacter#1\from#2\to#3% + {\def\dostripcharacter##1#1##2\end + {\edef\!!strippedstring{\!!strippedstring##1}% + \doifnotempty{##2}{\dostripcharacter##2\end}}% + \let\!!strippedstring\empty + \edef\!!stringa{#2}% + \@EA\dostripcharacter\!!stringa#1\end + \dodoglobal\let#3\!!strippedstring} + +\def\stripspaces\from#1\to#2% will become \unspacestring#1\from#2 + {\stripcharacter{ }\from#1\to#2} + +%D \macros +%D {unspacestring} +%D +%D The next macro does the same but is more compatible with other macros, +%D like \type {\convert...}. + +\def\unspacestring#1\to#2% + {\stripcharacter{ }\from#1\to#2} + +%D \macros +%D {executeifdefined} +%D +%D \CONTEXT\ uses one auxiliary file for all data concerning +%D tables of contents, references, two||pass optimizations, +%D sorted lists etc. This file is loaded as many times as +%D needed. During such a pass we skip the commands thate are of +%D no use at that moment. Because we don't want to come into +%D trouble with undefined auxiliary commands, we call the +%D macros in a way similar to \type{\getvalue}. The next macro +%D take care of such executions and when not defined, gobbles +%D the unwanted arguments. +%D +%D \starttyping +%D \executeifdefined{name}\gobbleoneargument +%D \stoptyping +%D +%D We can of course gobble more arguments using the +%D appropriate gobbling command. + +\newif\ifexecuted % general purpose + +\def\executeifdefined#1% #2 / never change this one again + {\ifcsname#1\endcsname + \csname#1\expandafter\expandafter\expandafter\endcsname\expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +%D This one also has the advantage that it is fully +%D expandable and that it can be used after an assignment. + +%D \macros +%D {doifsomespaceelse} +%D +%D The next command checks a string on the presence of a space +%D and executed a command accordingly. +%D +%D \starttyping +%D \doifsomespaceelse {tekst} {then ...} {else ...} +%D \stoptyping +%D +%D We use this command in \CONTEXT\ for determing if an +%D argument must be broken into words when made interactive. +%D Watch the use of \type{\noexpand}. + +%D Is this one still needed? + +\def\p!doifsomespaceelse#1 #2#3\war{\if\noexpand#2@} + +\long\def\doifsomespaceelse#1% % #2#3% + {\p!doifsomespaceelse#1 @ @\war % #3\else#2\fi} + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +%D \macros +%D {adaptdimension,balancedimensions} +%D +%D Again we introduce some macros that are closely related to +%D an interface aspect of \CONTEXT. The first command can be +%D used to adapt a \DIMENSION. +%D +%D \starttyping +%D \adaptdimension {dimension} {value} +%D \stoptyping +%D +%D When the value is preceed by a \type{+} or minus, the +%D dimension is advanced accordingly, otherwise it gets the +%D value. + +\def\doadaptdimension#1#2\\#3\\% + {\if#1+% + \dodoglobal\advance + \else\if#1-% + \dodoglobal\advance + \else + \dodoglobal + \fi\fi + #3 #1#2\relax} + +\def\adaptdimension#1#2% + {\expandafter\doadaptdimension#2\\#1\\} + +%D A second command takes two \DIMENSIONS. Both are adapted, +%D depending on the sign of the given value. +%D maat. This time we take the value as it is, and don't look +%D explicitly at the preceding sign. +%D +%D \starttyping +%D \balancedimensions {dimension 1} {dimension 2} {value} +%D \stoptyping +%D +%D When a positive value is given, the first dimension is +%D incremented, the second ond is decremented. A negative value +%D has the opposite result. + +\def\balancedimensions#1#2#3% + {\scratchdimen#3\relax + \redoglobal\advance#1 \scratchdimen + \dodoglobal\advance#2 -\scratchdimen} + +%D Both commands can be preceded by \type{\doglobal}. Here we +%D use \type{\redo} first, because \type{\dodo} resets the +%D global character. + +%D \macros +%D {processseparatedlist} +%D +%D Maybe a bit late, but here is a more general version of the +%D \type{\processcommalist} command. This time we don't handle +%D nesting but accept arbitrary seperators. +%D +%D \starttyping +%D \processseparatedlist[list][separator]\command +%D \stoptyping +%D +%D One can think of things like: +%D +%D \starttyping +%D \processseparatedlist[alfa+beta+gamma][+]\message +%D \stoptyping +%D +%D We want to handle all situations, like: +%D +%D \startbuffer +%D \processseparatedlist[{aap noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} +%D \processseparatedlist[{aap} {noot}][ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} +%D \processseparatedlist[aap {noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} +%D \processseparatedlist[aap noot] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D Therefore we smuggle a \type {\relax} in front of the +%D argument, which we remove afterwards. + +\def\doprocessseparatedlist#1]#2[#3]#4% + {\def\dodoprocessseparatedlist##1##2#3% + {\def\!!stringa{##2}% suggested by VZ + \if]##1% + \let\dodoprocessseparatedlist\relax + \else\ifx\blankspace\!!stringa + #4{##1}% + \else\if]##2% + \let\dodoprocessseparatedlist\relax + \else + #4{##1##2}% + \fi\fi\fi + \dodoprocessseparatedlist}% + \@EA\dodoprocessseparatedlist\gobbleoneargument#1#3]#3} + +\def\processseparatedlist[% + {\doprocessseparatedlist\relax} + +%D \macros +%D {processlist} +%D +%D An even more general list processing macro is the +%D following one: +%D +%D \starttyping +%D \processlist{beginsym}{endsym}{separator}\docommand list +%D \stoptyping +%D +%D This one supports arbitrary open and close symbols as well +%D as user defined separators. +%D +%D \starttyping +%D \processlist(){=>}\docommand(a=>b=>c=>d) +%D \stoptyping + +\long\def\processlist#1#2#3#4% no blank skipping ! + {\def\doprocesslist##1#2% + {\def\dodoprocesslist####1####2#3% + {\ifx#2####1% + \let\dodoprocesslist\relax + \else\ifx#2####2% + \let\dodoprocesslist\relax + \else + #4{####1####2}% + \fi\fi + \dodoprocesslist}% + \expandafter\dodoprocesslist\gobbleoneargument##1#3#2#3}% + \def\dodoprocesslist#1% + {\doprocesslist\relax}% + \dodoprocesslist} + +%D \macros +%D {processassignlist} +%D +%D Is possible to combine an assignment list with one +%D containing keywords. Assignments are treated accordingly, +%D keywords are treated by \type{\command}. +%D +%D \starttyping +%D \processassignlist[...=...,...=...,...]\commando +%D \stoptyping +%D +%D This command can be integrated in \type{\getparameters}, but +%D we decided best not to do so. + +\def\processassignlist#1[#2]#3% + {\def\p!dodogetparameter[##1=##2=##3]% + {\doifnot{##3}\relax{#3{##1}}}% + \def\p!dogetparameter##1% + {\p!dodogetparameter[##1==\relax]}% + \processcommalist[#2]\p!dogetparameter} + +%D \macros +%D {untextargument +%D untexcommand} +%D +%D When manipulating data(bases) and for instance generating +%D index entries, the next three macros can be of help: +%D +%D \starttyping +%D \untextargument{...}\to\name +%D \untexcommand {...}\to\name +%D \stoptyping +%D +%D They remove braces and backslashes and give us something to +%D sort. + +\def\untexsomething + {\begingroup + \catcode`\{=\@@ignore + \catcode`\}=\@@ignore + \escapechar\minusone + \dountexsomething} + +\long\def\dountexsomething#1#2\to#3% + {\doglobal#1#2\to\untexedargument + \endgroup + \let#3\untexedargument} + +\def\untexargument{\untexsomething\convertargument} +\def\untexcommand {\untexsomething\convertcommand} + +%D \macros +%D {ScaledPointsToBigPoints,ScaledPointsToWholeBigPoints} +%D +%D One characteristic of \POSTSCRIPT\ and \PDF\ is that both +%D used big points (\TEX's bp). The next macros convert points +%D and scaled points into big points. +%D +%D \starttyping +%D \ScaledPointsToBigPoints {number} \target +%D \ScaledPointsToWholeBigPoints {number} \target +%D \stoptyping +%D +%D The magic factor $72/72.27$ can be found in most \TEX\ +%D related books. + +% \PointsToBigPoints{10.53940pt}\test \test +% \PointsToBigPoints{10.53941pt}\test \test +% \PointsToBigPoints{10.53942pt}\test \test + +% \PointsToWholeBigPoints{10.53940pt}\test \test +% \PointsToWholeBigPoints{10.53941pt}\test \test +% \PointsToWholeBigPoints{10.53942pt}\test \test + +\def\PointsToBigPoints#1#2% + {\edef#2{\withoutpt\the\dimexpr.996264\dimexpr#1\relax\relax}} + +\def\PointsToWholeBigPoints#1#2% + {\edef#2{\the\numexpr\dimexpr.996264\dimexpr#1\relax\relax/\maxcard\relax}} + +\def\ScaledPointsToBigPoints #1{\PointsToBigPoints {\number#1\scaledpoint}} +\def\ScaledPointsToWholeBigPoints#1{\PointsToWholeBigPoints{\number#1\scaledpoint}} + +%D \macros +%D {PointsToReal} +%D +%D Points can be stripped from their suffix by using +%D \type{\withoutpt}. The next macro enveloppes this macro. +%D +%D \starttyping +%D \PointsToReal {dimension} \target +%D \stoptyping + +\def\PointsToReal#1#2% + {\scratchdimen#1% + \edef#2{\withoutpt\the\scratchdimen}} + +%D \macros +%D {dontleavehmode} +%D +%D Sometimes when we enter a paragraph with some command, the +%D first token gets the whole first line. We can prevent this +%D by saying: +%D +%D \starttyping +%D \dontleavehmode +%D \stoptyping +%D +%D This command is used in for instance the language module +%D \type{lang-ini}. The first version was: +%D +%D \starttyping +%D \def\dontleavehmode{\ifhmode\else\ifmmode\else$ $\fi\fi} +%D \stoptyping +%D +%D Next, Taco came with a better alternative (using mathsurround): +%D +%D \starttyping +%D \def\dontleavehmode +%D {\ifhmode\else \ifmmode\else +%D {\mathsurround\zeropoint\everymath\emptytoks$ $}% +%D \fi \fi} +%D \stoptyping +%D +%D And finaly we got the following alternative, one that avoids +%D interfering grouping at the cost of a box. + +\newbox\@@dlhbox + +\unexpanded \def\dontleavehmode + {\ifhmode\else \ifmmode\else + \setbox\@@dlhbox\hbox{\mathsurround\zeropoint\everymath\emptytoks$ $}\unhbox\@@dlhbox + \fi \fi} + +%D But, if you run a recent version of \TEX, we can use the new +%D primitive: + +\ifdefined\normalquitvmode \let\dontleavehmode\normalquitvmode \fi + +%D \macros +%D {uppercasestring,lowercasestring} +%D +%D The names tell what they do: +%D +%D \starttyping +%D \uppercasestring somestring\to\somestring +%D \lowercasestring somestring\to\somestring +%D \stoptyping +%D +%D the first argument may be a \type{\macro}. + +\def\uppercasestring#1\to#2% first @EA redundant + {\uppercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}} + +\def\lowercasestring#1\to#2% first @EA redundant + {\lowercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}} + +%D \macros +%D {handletokens} +%D +%D With the next macro we enter a critical area of macro +%D expansion. What we want is a macro that looks like: +%D +%D \starttyping +%D \handletokens some tokens\with \somemacro +%D \stoptyping +%D +%D A bonus example: +%D +%D \starttyping +%D \hbox{\handletokens tekst en meer tekst\with\ruledhbox} +%D +%D \def\weetikveel#1{\if#1\blankspace\space\else\ruledhbox{#1}\fi} +%D +%D \hbox{\handletokens tekst en meer tekst\with\weetikveel} +%D \stoptyping + +%D \macros +%D {counttoken,counttokens} +%D +%D For the few occasions that we want to know the number of +%D specific tokens in a string, we can use: +%D +%D \starttyping +%D \counttoken token\in string\to \somecount +%D \counttokens string\to \somecount +%D \stoptyping +%D +%D This macro, that for instance is used in \type{cont-tab}, +%D takes a real counter. The macro can be preceded by \type +%D {\doglobal}. + +\def\counttoken#1\in#2\to#3% + {\scratchcounter\zerocount + \def\!!stringa{#1}% + \def\!!stringb{\end}% + \def\docounttoken##1% obeys {} + {\def\!!stringc{##1}% + \ifx\!!stringb\!!stringc \else + \ifx\!!stringa\!!stringc + \advance\scratchcounter\plusone + \fi + \expandafter\docounttoken + \fi}% + \docounttoken#2\end + \dodoglobal#3\scratchcounter} + +\def\counttokens#1\to#2% + {\scratchcounter\zerocount + \def\docounttoken##1{\advance\scratchcounter\plusone}% + \handletokens#1\with\docounttoken + \dodoglobal#2\scratchcounter} + +%D \macros +%D {splitofftokens} +%D +%D Running this one not always gives the expected results. +%D Consider for instance the macro for which I originally +%D wrote this token handler. + +\long\def\splitofftokens#1\from#2\to#3% slow but hardly used + {\ifnum#1>\zerocount + \scratchcounter#1\relax + \def\dosplitofftokens##1% + {\ifnum\scratchcounter>\zerocount + \advance\scratchcounter \minusone + \edef#3{#3##1}% + \fi}% + % \let#3\empty % #3 can be #2, so: + \@EA\let\@EA#3\@EA\empty + \@EA\handletokens#2\with\dosplitofftokens + \else + \edef#3{#2}% + \fi} + +%D This macro can be called like: +%D +%D \startbuffer[example] +%D \splitofftokens10\from01234567 890123456789\to\test [\test] +%D \stopbuffer +%D +%D However, the characters that we expect to find in +%D \type{\test} just don't show up there. The reason for this +%D is not that logical but follows from \TEX's sometimes +%D mysterious way of expanding. Look at this: +%D +%D \startbuffer[next] +%D \def\next{a} \edef\test{\next} [\test] +%D \let\next=b \edef\test{\test\next} [\test] +%D \let\next=c \edef\test{\next} [\test] +%D \let\next=d \edef\test{\test\next} [\test] +%D \let\next=e \@EA\edef\@EA\test\@EA{\test\next} [\test] +%D \stopbuffer +%D +%D \typebuffer[next] +%D +%D Careful reading shows that inside an \type{\edef} macro's +%D that are \type{\let} are not expanded! +%D +%D \unprotect\getbuffer[next]\protect +%D +%D That's why we finally end up with a macro that looks +%D ahead by using an assignment, this time by using \type +%D {\futurelet}, and grabbing an argument as well. That +%D way we can handle the sentinal, a blank space and grouped +%D tokens. + +\def\dohandletokens % \nexthandledtoken is part of interface + {\futurelet\nexthandledtoken\dodohandletokens} + +\long\def\handletokens#1\with#2% + {\gdef\dododohandletokens{#2}% permits more complex #2's + \dohandletokens#1\end} + +\def\dodohandletokens + {\ifx\nexthandledtoken\blankspace + \expandafter\dodohandletokensone + \else\ifx\nexthandledtoken\end + \expandafter\expandafter\expandafter\gobbletwoarguments % also gobble the \end + \else + \expandafter\expandafter\expandafter\dodohandletokenstwo + \fi\fi *} + +\def\dodohandletokensone * % + {\dododohandletokens{ }\dohandletokens} + +\long\def\dodohandletokenstwo *#1% + {\dododohandletokens{#1}\dohandletokens} + +%D This macro is tested on: +%D +%D \def\xxx#1{[#1]} +%D +%D \startlines +%D \handletokens abc\with\xxx +%D \handletokens a b c\with\xxx +%D \handletokens a b c\with\xxx +%D \handletokens a{bc}d\with\xxx +%D \handletokens a\space bc \with\xxx +%D \stoplines +%D +%D And our previous example shows up as: +%D +%D \getbuffer[example] + +%D \macros +%D {iftrialtypesetting, ifvisible} +%D +%D The next boolean is at first sight a strange one. Sometimes +%D one does a trial typesetting run, for instance to determine +%D dimensions. Some mechanisms, like object inclusion, can fail +%D on such trials. Temporary setting the next boolean to true, +%D helps a lot. The second boolena can be used to inhibit +%D processing completely. + +\newif\iftrialtypesetting \trialtypesettingfalse +\newif\ifvisible \visibletrue + +%D \macros +%D {startlocal, startglobal} +%D +%D The next four macros are rather self explaining: +%D +%D \starttyping +%D \startlocal +%D whatever assignments +%D \stoplocal +%D +%D \startglobal +%D whatever assignments +%D \stopglobal +%D \stoptyping +%D +%D These macros are meant for those who know the difference +%D between local and global assignments and are aware of the +%D possible unwanted side effect + +\def\dostartglobaldefs#1#2% + {\scratchcounter\globaldefs + \ifnum\globaldefs#1\zerocount + \globaldefs-\globaldefs + \fi + \advance\globaldefs#2\plusone + \expandafter\chardef\csname@gd@\the\globaldefs\endcsname\scratchcounter} + +\def\dostopglobaldefs + {\globaldefs\ifcsname @gd@\the\globaldefs\endcsname\zerocount} + +\def\startlocal {\dostartglobaldefs>-} +\def\stoplocal {\dostopglobaldefs} +\def\startglobal {\dostartglobaldefs<+} +\def\stopglobal {\dostopglobaldefs} + +%D \macros +%D {twodigitrounding} +%D +%D When using \type {\special}s or \type {\pdfliteral}s, it +%D sometimes makes sense to limit the precission. The next +%D macro rounds a real number to two digits. It takes one +%D argument and only works in \ETEX. + +\def\dointegerrounding #1.#2\relax {#1} +\def\doonedigitrounding #1.#2#3\relax {\ifx#2*#1\else#1.#2\fi} +\def\dotwodigitrounding #1.#2#3#4\relax {\ifx#2*#1\else#1.#2#3\fi} +\def\dothreedigitrounding#1.#2#3#4#5\relax{\ifx#2*#1\else#1.#2#3#4\fi} + +\def\integerrounding#1% + {\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.5\points \relax .\relax} +\def\onedigitrounding#1% + {\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.05\points \relax 00.*0\relax} +\def\twodigitrounding#1% + {\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.005\points \relax 000.*00\relax} +\def\threedigitrounding#1% + {\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax0000.*00\relax} + +%D \macros +%D {processcontent} +%D +%D This is the first occasion where \TEX\ and \ETEX\ are no +%D longer compatible, although in many cases things go ok. +%D Beware of verbatim, i.e. catcode changes. +%D +%D \starttyping +%D \def\starthans% +%D {\processcontent{stophans}\test{\message{\test}\wait}} +%D \stoptyping +%D +%D This macro is first used in the tabulation macros. + +\def\processcontent#1% + {\begingroup\@EA\doprocesscontent\csname#1\endcsname} + +\def\doprocesscontent#1#2#3% + {\long\def\doprocesscontent##1#1% + {\endgroup\long\def#2{##1}#3}% + \doprocesscontent} + +%D \macros +%D {dogobblesingleempty, dogobbledoubleempty} +%D +%D These two macros savely grab and dispose two arguments. + +\def\dogobblesingleempty{\dosingleempty\dodogobblesingleempty} +\def\dogobbledoubleempty{\dodoubleempty\dodogobbledoubleempty} + +\def\dodogobblesingleempty [#1]{} +\def\dodogobbledoubleempty[#1][#2]{} + +\let\gobblesingleempty\dogobblesingleempty % also used +\let\gobbledoubleempty\dogobbledoubleempty % also used + +%D \macros +%D {sortcommalist,sortcommacommand, +%D donumericcompare,comparedresult} +%D +%D Sometimes we need to sort a commalist, so here is Taco's +%D solution. This will in many cases be a list that is stored +%D in a \type{\csname}, so both commalist and commacommands are +%D supported. The sorting algorithm is very simple, so the list +%D should not be too long or sorting will be very slow. +%D +%D \starttyping +%D \sortcommalist[10,2,4,5,6,1,2,3,4,10,20]\donumericcompare +%D +%D \def\test{10,2,4,5,6,1,2,3,4,10,20} +%D +%D \sortcommacommand[\test]\donumericcompare +%D \stoptyping +%D +%D In both cases, the result is available in the macro \type +%D {\sortedcommalist}. +%D +%D Parameter \type{#2} is a macro that should accept two +%D parameters, and it has to decide which one is larger, by +%D setting the counter \type{\comparedresult} to~0 (for equal), +%D 1~(if it's first argument is larger), or~2 (if it's second +%D argument is larger). +%D +%D As said, these macro are largely written by Taco, and are +%D (maybe therefore) also the first application of \type +%D {\replaceincommalist}. + +\newcount\comparedresult + +\def\sortcommacommand[#1]% + {\@EA\sortcommalist\@EA[#1]} + +\def\sortcommalist[#1]#2% + {\getcommalistsize[#1]% + \ifnum\commalistsize>1 + \let\sortedcommalist\empty + \let\comparecommand#2% + \processcommalist[#1]\dosortcommacommand + \else + \def\sortedcommalist{#1}% + \fi} + +\def\dosortcommacommand#1% + {\ifx\sortedcommalist\empty + \def\sortedcommalist{#1}% + \else + \def\!!tempa{#1}% + \ifx\!!tempa\empty\else + \scratchcounter\plusone + \@EA\getcommalistsize\@EA[\sortedcommalist]% + \@EA\processcommalist\@EA[\sortedcommalist]\docompareitems + \fi + \fi} + +%D All those \type{\expandafter}'s are there because I do not +%D want to use \type{\edef}. + +\def\docompareitems#1% + {\doifnotempty{#1} + {\@EA\comparecommand\@EA{\!!tempa}{#1}\relax + %\ifcase\compareresult % equal + \ifnum\comparedresult<2 + \ifnum\scratchcounter=\commalistsize + \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist + \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}% + \fi + %\or % new element larger + % \ifnum\scratchcounter=\commalistsize + % \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist + % \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}% + % \fi + \else % old element larger + \@EA\def\@EA\newcommalistelement\@EA{\!!tempa,#1}% + \replaceincommalist\sortedcommalist\scratchcounter + \expandafter\quitcommalist + \fi}% + \advance\scratchcounter \plusone} % bug, was \minusone + +%D The macro \type{\donumericcompare} considers everything +%D that is not a number to be larger than any number. + +% 0: both are equal, 1: #1 is larger, 2: #2 is larger + +\def\thenumericcompare#1#2% no \relax es inside hee + {\doifnumberelse{#1} + {\doifnumberelse{#2}{\ifnum#1>#2 \plusone\else\ifnum#1<#2 \plustwo\else\zerocount\fi\fi}\plustwo} + \plusone} + +\def\donumericcompare + {\comparedresult\thenumericcompare} + +%D \macros +%D {@True, @False, @Not, @And} +%D +%D Some predicate logic functions, used in for instance the +%D math module. + +\def\@True {00} +\def\@False {01} +\def\@Not #1{0\ifcase#11 \or\@EA 1\else \@EA 0\fi} +\def\@And #1#2{0\ifcase#1#2 \@EA 0\else \@EA 1\fi} + +%D \macros +%D {setdimensionwithunit, freezedimensionwithunit} +%D +%D The next assignments are all valid: +%D +%D \starttyping +%D \setdimensionwithunit\scratchdimen{10} {cm} +%D \setdimensionwithunit\scratchdimen{10cm}{cm} +%D \setdimensionwithunit\scratchdimen{10cm}{} +%D \freezedimensionwithunit\SomeWidth{\textwidth} +%D \freezedimensionwithunit\SomeDepth{\dp\strutbox} +%D \stoptyping +%D +%D As an alternative for the next macro we can use a global +%D assignment inside a box. The \type{\empty}'s permits +%D gobbling while preventing spurious \type{\relax}'s. + +\def\setdimensionwithunit#1#2#3% number unit dimension / nice trick + {\afterassignment\gobblefourarguments#1=#2#3pt\relax\empty\empty\empty\empty} + +\def\freezedimensionwithunit#1#2% + {\setdimensionwithunit\scratchdimen#1{#2}\edef#1{\the\scratchdimen}} + +%D \macros +%D {doifsometokselse} +%D +%D Not that fast I guess, but here's a way to test for token +%D registers being empty. + +\def\doifsometokselse#1% % #2#3% + {\edef\!!stringa{\the#1}% + \ifx\!!stringa\empty % #3\else#2\fi} + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +%D \macros +%D {startstrictinspectnextcharacter} +%D +%D This one if for Taco's bibliography module: + +\let\normalinspectnextcharacter\inspectnextcharacter + +\def\strictinspectnextcharacter% no user macro ! + {\ifx\nexttoken\charactertoken + \expandafter\!!stringa + \else + \expandafter\!!stringb + \fi} + +% better: push/pop + +\def\startstrictinspectnextcharacter + {\let\inspectnextcharacter\strictinspectnextcharacter} + +\def\stopstrictinspectnextcharacter + {\let\inspectnextcharacter\normalinspectnextcharacter} + +%D \macros +%D {gobblespacetokens} +%D +%D This macro needs a speed-up! + +%\def\gobblespacetokens +% {\doifnextcharelse\empty\donothing\donothing} % no {}\do\do ! + +\def\gobblespacetokens + {\afterassignment\nexttoken\let\nexttoken=} + +%D \macros +%D {verbatimargument} +%D +%D As the name says, this macro converts its argument to a +%D (rather safe) string. + +\let\verbatimstring\detokenize + +%D These are needed in ordinal number conversions: + +\def\lastdigit#1% + {\@EA\thelastdigit\number#1\relax} + +\def\thelastdigit#1#2% + {\ifx#2\relax#1\else\@EA\thelastdigit\@EA#2\fi} + +\def\lasttwodigits#1% + {\@EA\thelasttwodigits\@EA0\number#1\relax} + +\def\thelasttwodigits#1#2#3% 0 dig ... \relax + {\ifx#3\relax#1#2\else\@EA\thelasttwodigits\@EA#2\@EA#3\fi} + +%D \macros +%D {serializecommalist} +%D +%D Concatenate commalists: + +\def\serializecommalist[#1]% + {\let\serializedcommalist\empty + \def\docommand##1{\edef\serializedcommalist{\serializedcommalist##1}}% + \processcommacommand[#1]\docommand} + +%D \macros +%D {purenumber} +%D +%D Sometimes we need control over when \TEX\ stops reading a +%D number, especially in full expandable macros where using +%D \type {\relax} would lead to disasters. +%D +%D \starttyping +%D \ifodd\purenumber{...}\space ... \else ... \fi +%D \stoptyping +%D +%D Here we use a space as number delimiter in combination +%D with a space- and relax-less \type {\purenumber}. This +%D macro works ok with \type {\the}, \type {\number} as well +%D as \ETEX's \type {\numexpr}. + +\def\purenumber#1{\@EA\firstofoneargument\@EA{\number#1}} + +%D \macros +%D {filterfromvalue} +%D +%D \starttyping +%D \setvalue{xx}{{A}{B}{C}} +%D +%D \filterfromvalue{xx}{3}{3} +%D \filterfromvalue{xx}{3}{2} +%D \filterfromvalue{xx}{3}{1} +%D \stoptyping +%D +%D An alternative is to store 'max' in the list, say: +%D +%D \starttyping +%D \setvalue{xx}{3{A}{B}{C}} +%D +%D \filterfromvalues{3}{xx}{3} +%D \filterfromvalues{3}{xx}{2} +%D \filterfromvalues{3}{xx}{1} +%D \stoptyping +%D +%D I'll implement this when I'm in \quotation {writing dirty +%D macros mood}. + +\def\dofilterfromstr#1#2% max n % no need to be fast + {\expandafter \expandafter \expandafter \strippedcsname + \ifcase#1\or \ifcase#2\or + \firstofoneargument \else + \gobbleoneargument \fi + \or \ifcase#2\or + \firstoftwoarguments \or + \secondoftwoarguments \else + \gobbletwoarguments \fi + \or \ifcase#2\or + \firstofthreearguments \or + \secondofthreearguments \or + \thirdofthreearguments \else + \gobblethreearguments \fi + \or \ifcase#2\or + \firstoffourarguments \or + \secondoffourarguments \or + \thirdoffourarguments \or + \fourthoffourarguments \else + \gobblefourarguments \fi + \or \ifcase#2\or + \firstoffivearguments \or + \secondoffivearguments \or + \thirdoffivearguments \or + \fourthoffivearguments \or + \fifthoffivearguments \else + \gobblefivearguments \fi + \fi} + +\def\filterfromvalue#1#2#3% value max n + {\@EA\@EAEAEA\csname % we use the fact that an + \@EA\ifx\csname#1\endcsname\relax % undefined cs has become \relax + \strippedcsname\gobbleoneargument % which we then gobble here + \else + \dofilterfromstr{#2}{#3}% + \fi + \endcsname\csname#1\endcsname} + +\def\filterfromnext#1#2% max n {..}{..}{..}{..} + {\csname\dofilterfromstr{#1}{#2}\endcsname} + +%D \macros +%D {definemeasure} +%D +%D \starttyping +%D \definemeasure[mywidth][\dimexpr(\textwidth-1cm)] +%D +%D ... \measure{mywidth} ... +%D \stoptyping + +\def\??dm{@@dm} % brrr + +\def\definemeasure + {\dodoubleargument\dodefinemeasure} + +\def\dodefinemeasure[#1][#2]% + {\expandafter\def\csname\??dm#1\endcsname{#2}} + +% #2 could be omitted, but we want to support spaces +% +% \setmeasure {x} {1cm} +% \setmeasure {xx} {1cm} +% \setmeasure {xxx}{1cm} + +\def\setmeasure #1#2{\expandafter\def \csname\??dm#1\endcsname{#2}} % quick way +\def\setemeasure#1#2{\expandafter\edef\csname\??dm#1\endcsname{#2}} % quick way +\def\setgmeasure#1#2{\expandafter\gdef\csname\??dm#1\endcsname{#2}} % quick way +\def\setxmeasure#1#2{\expandafter\xdef\csname\??dm#1\endcsname{#2}} % quick way + +\def\measure#1% + {\ifcsname\??dm#1\endcsname\csname\??dm#1\endcsname\else\zeropoint\fi} + +%D \macros +%D {doifdimensionelse} +%D +%D This is a dirty one: we simply append a unit and discard it when needed. + +\def\doifdimensionelse#1% + {\afterassignment\dodoifdimensionelse\scratchdimen#1pt\relax} + +\def\dodoifdimensionelse#1% + {\ifx#1\relax + \expandafter\secondoftwoarguments + \else % #1=p ... t\relax + \expandafter\thirdoffourarguments + \fi} + +%D \macros +%D {comparedimension,comparedimensioneps} +%D +%D This is a dirty one: we simply append a unit and discard it when needed. + +\newdimen\roundingeps \roundingeps=10sp + +\def\comparedimension#1#2% + {\chardef\compresult + \ifdim#1<#2% + \zerocount + \else\ifdim#1<#2% + \plusone + \else + \plustwo + \fi\fi} + +\def\comparedimensioneps#1#2% todo: use eps feature + {\chardef\compresult + \ifdim\dimexpr#1-#2\relax<\roudingeps + \zerocount + \else\ifdim\dimexpr#2-#1\relax<\roudingeps + \zerocount + \else\ifdim#1<#2% + \plusone + \else + \plustwo + \fi\fi\fi} + +% % % % % % % % % % % % % % % % % % % % % % + +% pretty ugly but fast + +% \copycsname xxx\endcsname\csname ..\endcsname + +\def\copycsname{\@EA\@EA\@EA\let\@EA\@EA\csname} + +% \letcscsname \crap \csname ..\endcsname +% \letcsnamecs \csname ..\endcsname\crap +% \letcsnamecsname\csname ..\endcsname\csname ..\endcsname + +\def\letcscsname {\@EA\let\@EA} +\def\letcsnamecs {\@EA\let} +\def\letcsnamecsname{\@EA\@EA\@EA\let\@EA\@EA} + +% another one, add an item to a commalist + +\def\addvalue#1#2% cs item + {\ifcsname#1\endcsname\else\expandafter\let\csname#1\endcsname\empty\fi + \normalexpanded{\noexpand\addtocommalist{#2}\@EA\noexpand\csname#1\endcsname}} + +\def\unspaced#1% + {\dounspaced#1\end} + +\def\dounspaced#1% + {\ifx#1\end + \@EA\gobbleoneargument + \else + \ifx#1\blankspace\else#1\fi + \fi + \dounspaced} + +\def\unspaceargument#1\to#2% + {\scratchcounter\catcode32\relax + \catcode32\@@ignore\scantextokens{\edef#2{#1}}% + \catcode32\scratchcounter} + +\def\unspaceafter#1#2% + {\unspaceargument#2\to\ascii + \expandafter#1\expandafter{\ascii}} + +% sometimes handy: + +\def\doifhasspaceelse#1% + {\edef\!!stringa{#1}% + \normalexpanded{\noexpand\dodoifhasspaceelse#1\space}\empty\relax} + +\def\dodoifhasspaceelse#1 #2#3\relax % \space\empty\relax + {\ifx\!!stringa\space + \@EA\firstoftwoarguments + \else\ifx#2\empty + \@EAEAEA\secondoftwoarguments + \else + \@EAEAEA\firstoftwoarguments + \fi\fi} + +% this will replace loadfile once and alike !!! todo + +\def\@flg@{@flg@} + +\def\setflag #1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\zerocount} +\def\resetflag#1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\plusone} + +\let\ifflagged\ifcase + +\def\flag#1{\csname\@flg@#1\endcsname} + +\def\doifelseflagged#1% + {\@EA\ifx\csname\@flg@#1\endcsname\relax + \@EA\secondoftwoarguments + \else\ifcase\csname\@flg@#1\endcsname + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\secondoftwoarguments + \fi\fi} + +\def\doifnotflagged#1% + {\@EA\ifx\csname\@flg@#1\endcsname\relax + \@EA\firstofoneargument + \else\ifcase\csname\@flg@#1\endcsname + \@EAEAEA\gobbleoneargument + \else + \@EAEAEA\firstofoneargument + \fi\fi} + +\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey % [bypasses k!prefix] + {\@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#1#5\endcsname}} + +% \buildarray[test][aa,bb,cc,dd,ee,ff] +% \setarrayelement{test}{1}{qq} +% \arrayelement{test}{1} +% \arraylength{test} +% +% \def\buildarray[#1][#2]% +% {\scratchcounter=0 +% \def\docommand##1% +% {\advance\scratchcounter by 1 +% \setvalue{@@aa#1\the\scratchcounter}{##1}}% +% \processcommalist[#2]\docommand +% \setevalue{@@aa#1}{\the\scratchcounter}}% +% +% \def\setarrayelement#1#2{\setvalue{@@aa#1#2}} +% \def\arrayelement #1#2{\getvalue{@@aa#1#2}} +% \def\arraylength #1{\getvalue{@@aa#1}} + +% \newsignal\junksignal +% +% \def\setjunksignal% +% {\ifhmode +% \hskip\junksignal +% \let\removejunkspaces\doremovejunkspaces +% \else +% \let\removejunkspaces\relax +% \fi} +% +% \def\doremovejunkspaces% +% {\doloop{\ifdim\lastskip=\junksignal\unskip\else\exitloop\fi}} + +\def\dodoifnonzeropositiveelse#1#2\end % #3#4% + {\ifx#1\relax + \ifcase\scratchcounter + \endgroup + \@EAEAEA\secondoftwoarguments + \else + \endgroup + \@EAEAEA\firstoftwoarguments + \fi + \else + \endgroup + \@EA\secondoftwoarguments + \fi} + +\def\doifnonzeropositiveelse#1% + {\begingroup\afterassignment\dodoifnonzeropositiveelse\scratchcounter=0#1\relax\empty\end} + +% here ? + +\def\dosetrawvalue #1#2#3{\@EA \def\csname#1#2\endcsname{#3}} +\def\dosetrawevalue#1#2#3{\@EA\edef\csname#1#2\endcsname{#3}} +\def\dosetrawgvalue#1#2#3{\@EA\gdef\csname#1#2\endcsname{#3}} +\def\dosetrawxvalue#1#2#3{\@EA\xdef\csname#1#2\endcsname{#3}} + +\def\getrawparameters {\dogetparameters\dosetrawvalue } +\def\getraweparameters {\dogetparameters\dosetrawevalue} +\def\getrawgparameters {\dogetparameters\dosetrawgvalue} +\def\getrawxparameters {\dogetparameters\dosetrawxvalue} + +\def\globalgetrawparameters{\dogetparameters\dosetrawgvalue} % obsolete + +\def\splitskip#1% + {\scratchskip#1\relax + \dimen0\scratchskip + \dimen2\gluestretch\scratchskip + \dimen4\glueshrink\scratchskip} + +\newcount\modcounter + +\def\dosetmodulo#1#2#3% + {\modcounter#1\divide\modcounter#2\multiply\modcounter#2% + #3#1\advance#3-\modcounter} + +\def\dosetdivision#1#2#3% + {#3#1\divide#3 #2\relax} + +\def\DoMod#1by#2to#3{\dosetmodulo {#1}{#2}{#3}} +\def\DoDiv#1by#2to#3{\dosetdivision{#1}{#2}{#3}} + +\def\dounprotected#1\par + {#1\protect} + +\def\unprotected + {\unprotect\dounprotected} + +% awaiting the definitive implementation + +\ifdefined\resettimer \else + \let\resettimer \relax + \newcount\elapsedtime +\fi + +\newcount\featuretest + +\def\testfeature#1#2% + {\def\dotestfeature + {\advance\featuretest \plusone + \ifnum\featuretest>#1\else#2\expandafter\dotestfeature\fi}% + \retestfeature} + +\def\retestfeature % timer support is new per 10/5/2005 + {\bgroup + \ifcase\interactionmode\let\wait\relax\fi + \writestatus\m!systems{starting feature test}\wait + \resettimer + \featuretest\zerocount \dotestfeature + \writestatus\m!systems{feature test done (\elapsedseconds s)}% + \wait + \egroup} + +\def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax} + +\def\showtimer#1% + {\writestatus{runtime}{\elapsedseconds\space s / #1}} + +\def\testfeatureonce#1#2% + {\let\wait\relax\testfeature{#1}{#2}\end} + +%D \macros +%D {freezedimenmacro} +%D +%D This macro is use as: +%D +%D \starttyping +%D \freezedimenmacro\leftmargindistance +%D \stoptyping + +\def\freezedimenmacro#1% + {\edef#1{\the\dimexpr#1}} + +%D The next macro negates a macro (dimension or number, or actually, whatever. +%D It's a typical example of \type {\if} usage: +%D +%D \starttyping +%D \if-\whatever \else-\whatever\fi => else => -whatever +%D \if--\whatever\else-\whatever\fi => then => whatever +%D \stoptyping + +\def\negated#1{\if-#1\else-#1\fi} % does only work in macros or text + +% This permits things like ^\index{hans}^, where hans is +% duplicated in the text. + +\newif\ifduplicate + +\bgroup + +\gdef\checkduplication % in line with Knuth + {\ifmmode\expandafter^\else\expandafter\startduplication\fi} + +\gdef\insideduplication + {\ifmmode\expandafter^\else\expandafter\egroup\fi} + +\catcode`\^=\@@active + +\gdef\enableduplication + {\catcode`\^=\@@active \let^\checkduplication} + +\gdef\disableduplication + {\catcode`\^=\@@superscript} + +\gdef\startduplication + {\bgroup \duplicatetrue \let^\insideduplication} + +\egroup + +\def\gobbleassigndimen#1\\{} + +\def\assigndimen#1#2% + {\afterassignment\gobbleassigndimen#1=#2\!!zeropoint\\} + +\def\setusage#1% + {\@EA\let\csname#1\endcsname\iftrue} + +\def\resetusage#1% + {\@EA\let\csname#1\endcsname\iffalse} + +\def\ifusage#1% + {\ifcsname#1\endcsname\else + \resetusage{#1}% + \fi + \csname#1\endcsname} + +%D Very handy, more efficient than \type{{}}, and more readable +%D than \type {\empty}. + +\let\donothing\empty + +% The following macros are used in XML handling. + +\long\setvalue{@u@s@"}#1#2"{#2} \long\setvalue{@g@s@"}#1#2"{\scratchtoks{#2}} +\long\setvalue{@u@s@'}#1#2'{#2} \long\setvalue{@g@s@'}#1#2'{\scratchtoks{#2}} +\long\setvalue{@u@s@ }#1#2 {#2} \long\setvalue{@g@s@ }#1#2 {\scratchtoks{#2}} + +\long\def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1} +\long\def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1} + +\def\dowithgrabbedstring#1% + {\def\@@dowithgrabbedstring{#1}% + \afterassignment\@@dowithgrabbedstring\grabstring} + +\def\expifequalelse#1#2% + {\@@ifequal#1\relax\relax\@@and#2\relax\relax\@@then} + +\def\@@ifequal#1#2\@@and#3% + {\ifx#1\relax + \ifx#3\relax + \@EAEAEA\@@if@@equal@@true + \else + \@EAEAEA\@@if@@equal@@false + \fi + \else + \ifx#3\relax + \@EAEAEAEAEAEA\@@if@@equal@@false + \else\ifx#1#3% + % go on + \else + \@EAEAEAEAEAEA\@@if@@equal@@false + \fi\fi + \fi + \@@ifequal#2\@@and} + +\long\def\@@if@@equal@@true #1\@@then#2#3{#2} +\long\def\@@if@@equal@@false#1\@@then#2#3{#3} + +%D new stuff : + +\def\partialexpanded#1% + {\let\@@notexpanded\noexpand + \long\xdef\@@expanded{\noexpand#1}% + \let\@@notexpanded\empty + \@@expanded} + +\def\appended#1#2#3{\@EA#1\@EA#2\@EA{#2#3}} +\def\appendvalue #1{\@EA\appended\@EA \def\csname#1\endcsname} +\def\appendgvalue#1{\@EA\appended\@EA\gdef\csname#1\endcsname} + +\def\prepended#1#2#3{\scratchtoks{#3}\@EA\@EA\@EA#1\@EA\@EA\@EA#2\@EA\@EA\@EA{\@EA\the\@EA\scratchtoks#2}} +\def\prependvalue #1{\@EA\prepended\@EA \def\csname#1\endcsname} +\def\prependgvalue#1{\@EA\prepended\@EA\gdef\csname#1\endcsname} + +%D \macros +%D {compresscommacommandnrs,compresscommalistnrs,compressedcommalistnrs, +%D compresscommacommand,compresscommalist,compressedcommalist, +%D reversecommacommand,reversecommalist,reversedcommalist} +%D +%D The following two list processing macros are needed by Taco's +%D bibliography module. The numbers compressor converts the +%D list in a list of ranges. The normal compressor remove duplicate +%D and empty entries. + +\def\compresscommalistnrs[#1]% + {\let\compressedlist\empty + \!!counta\maxdimen + \!!countb\maxdimen + \processcommalist[#1]\docompresslistnrs + \ifnum\!!counta=\maxdimen\else\dodocompresslistnrs\fi} + +\def\compresscommacommandnrs[#1]% + {\normalexpanded{\noexpand\compresscommalistnrs[#1]}} + +\def\docompresslistnrs#1% + {\edef\commalistelement{#1}% + \ifx\commalistelement\empty\else + \ifnum\!!counta=\maxdimen + \!!counta\commalistelement\relax + \!!countb\!!counta + \else + \advance\!!countb\plusone + \ifnum\commalistelement>\!!countb + \advance\!!countb\minusone + \dodocompresslistnrs + \!!counta\commalistelement\relax + \!!countb\!!counta + \fi + \fi + \fi} + +\def\dodocompresslistnrs + {\edef\compressedlist + {\ifx\compressedlist\empty\else\compressedlist,\fi + {\the\!!counta}{\ifnum\!!countb>\!!counta\the\!!countb\fi}}} + +%D \def\test#1{{\tttf#1->\compresscommalistnrs[#1]\defconvertedcommand\ascii\compressedlist\ascii}} +%D \startlines +%D \test{} +%D \test{1} +%D \test{1,3} +%D \test{1,3,4} +%D \test{1,3,3,4,5} +%D \test{1,3,3,4,5,8} +%D \test{1,3,3,4,5,5,8,10} +%D \test{1,3,4,5,8,10,11} +%D \test{1,,3,,4,,5,,8,,10,,11,} +%D \stoplines + +\def\compresscommalist[#1]% + {\let\compressedlist\empty + \let\!!stringa\empty + \processcommalist[#1]\docompresslist} + +\def\compresscommacommand[#1]% + {\normalexpanded{\noexpand\compresscommalist[#1]}} + +\def\docompresslist#1% + {\edef\commalistelement{#1}% + \ifx\commalistelement\empty \else + \ifx\!!stringa\commalistelement \else + \ifx\compressedlist\empty + \def\compressedlist{#1}% + \else + \appended\def\compressedlist{,#1}% + \fi + \let\!!stringa\commalistelement + \fi + \fi} + +%D \def\test#1{{\tttf#1->\compresscommalist[#1]\defconvertedcommand\ascii\compressedlist\ascii}} +%D \startlines +%D \test{} +%D \test{1} +%D \test{1,3} +%D \test{1,3,4} +%D \test{1,3,3,4,5} +%D \test{1,3,3,4,5,8} +%D \test{1,3,3,4,5,5,8,10} +%D \test{1,3,4,5,8,10,11} +%D \test{1,,3,,4,,5,,8,,10,,11,} +%D \stoplines + +\def\reversecommalist[#1]% + {\let\reversedlist\empty + \processcommalist[#1]\doreverselist} + +\def\doreverselist#1% + {\ifx\reversedlist\empty + \def\reversedlist{#1}% + \else + \prepended\def\reversedlist{#1,}% + \fi} + +\def\reversecommacommand[#1]% + {\normalexpanded{\noexpand\reversecommalist[#1]}} + +%D \def\test#1{{\tttf#1->\reversecommalist[#1]\defconvertedcommand\ascii\reversedlist\ascii}} +%D \startlines +%D \test{} +%D \test{1} +%D \test{1,3} +%D \test{1,3,4} +%D \test{1,3,3,4,5} +%D \test{1,3,3,4,5,8} +%D \test{1,3,3,4,5,5,8,10} +%D \test{1,3,4,5,8,10,11} +%D \test{1,,3,,4,,5,,8,,10,,11,} +%D \stoplines + +%D \macros +%D {stripstring} +%D +%D Needed in bookmarks: +%D +%D \starttyping +%D {\sanitizePDFdocencoding test \CONTEXT\ test \to\oeps\stripstring\oeps\tttf[\oeps]} +%D \stoptyping + +\def\stripstring#1% #1 is \cs + {\edef\cs{\ctxlua + {tex.sprint(tex.vrbcatcodes,string.strip(\!!bs\detokenize\expandafter{#1}\!!es))}}} + +%D \macros +%D {dowithrange} +%D +%D This one is for Mojca Miklavec, who made me aware of the fact that +%D \type {page-imp.tex} was not the best place to hide it. + +\def\dowithrange#1#2% #2 takes number + {\splitstring#1\at:\to\fromrange\and\torange + \ifx\torange\empty\let\torange\fromrange\fi + \dostepwiserecurse\fromrange\torange1{#2{\recurselevel}}} + +%D \macros {uncompresslist} +%D +%D When given a list like \type{1,4-7,9} as argument, this macro +%D will store the expanded commalist in \type{\uncompressedlist}. +%D +%D \startbuffer +%D \def\MojcaHasToDoTheTasks[#1]#2% +%D {{\uncompresslist[#1]% +%D \def\processitem##1{I have to do ##1 #2\par}% +%D \processcommacommand[\uncompressedlist]\processitem}} +%D +%D \MojcaHasToDoTheTasks [1-4,7,9-11] {until tomorrow} +%D \stopbuffer +%D +%D Here is an example of how to use \type {\uncompresslist}: +%D \typebuffer +%D +%D The output of this is: +%D +%D \getbuffer + +\def\uncompresslist[#1]% by TH + {\let\uncompressedlist\empty + \def\docompressedlistitem##1-##2-% + {\@EA\dorecurse\@EA + {\the\numexpr1+##2-##1\relax}% + {\@EA\appendtocommalist\@EA{\the\numexpr##1-1+####1\relax}\uncompressedlist}}% + \def\douncompresslist##1% + {\doifinstringelse{-}{##1} + {\docompressedlistitem##1-} + {\appendtocommalist{##1}\uncompressedlist}}% + \processcommalist[#1]\douncompresslist} + +%D \macros +%D {ignoreimplicitspaces} +%D +%D \startbuffer +%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignorespaces} +%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b} +%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignoreimplicitspaces} +%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b} +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\ignoreimplicitspaces + {\doifnextcharelse\relax\relax\relax} + +%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 + +\def\startnointerference % not even grouped ! + {\setbox\nointerferencebox\vbox + \bgroup} + +\def\stopnointerference + {\egroup + \setbox\nointerferencebox\emptybox} + +% \def\appendtovaluelist#1#2% +% {\ifcsname#1\endcsname +% \expandafter\ifx\csname#1\endcsname\empty +% \expandafter\def\csname#1\endcsname{#2}% +% \else +% \expandafter\def\csname#1\expandafter\expandafter\expandafter\endcsname +% \expandafter\expandafter\expandafter{\csname#1\endcsname,#2}% +% \fi +% \else +% \expandafter\def\csname#1\endcsname{#2}% +% \fi} +% +% or +% +% \def\appendtovaluelist#1% +% {\ifcsname#1\endcsname +% \expandafter\ifx\csname#1\endcsname\empty +% \expandafter\noappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname +% \else +% \expandafter\doappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname +% \fi +% \else +% \expandafter\noappendtovaluelist\csname#1\expandafter\endcsname +% \fi} + +% \def\doappendtovaluelist#1#2{\expandafter\def\expandafter#1\expandafter{#1,#2}} +% \def\noappendtovaluelist#1#2{\def#1{#2}} + +% \appendtovaluelist{mylist}{aap} +% \appendtovaluelist{mylist}{noot} +% \appendtovaluelist{mylist}{mies} + +% \showvalue{mylist} + +\protect \endinput diff --git a/tex/context/base/syst-aux.tex b/tex/context/base/syst-aux.tex deleted file mode 100644 index 3b9d6803f..000000000 --- a/tex/context/base/syst-aux.tex +++ /dev/null @@ -1,6841 +0,0 @@ -%D \module -%D [ file=syst-gen, -%D version=1996.03.20, -%D title=\CONTEXT\ System Macros, -%D subtitle=General, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D Some of the macros will move to syst-obs as they might become -%D obsolete once we've redone the bibliography module. Of course -%D the handy helpers will stay. - -%D This is a stripped down combination of: -%D -%D \startitemize -%D \item \type {syst-gen.tex} -%D \item \type {syst-ext.tex} -%D \item \type {syst-new.tex} -%D \stopitemize -%D -%D We keep them around (for \MKII) so you can find comments, -%D experiences, intermediate versions and cleaner variants -%D there (and also non-\ETEX\ variants). -%D -%D Contrary to the older files, we now assume that this one -%D is used in \CONTEXT\ and therefore we might also assume that -%D some basic functionality is available. -%D -%D Some of the macros here are used in the bibliography module. They -%D will be moved to a separate syst module some once the bib module -%D is made \MKIV. - -\unprotect - -\let\reportprotectionstate\relax - -%D \macros -%D {doifolderversionelse} -%D -%D We start with a macro specially for Aditya who wants to be able -%D to use development versions of \MKIV\ for real documents. -%D -%D \starttyping -%D \doifolderversionelse\contextversion{2001.02.03}{yes}{no} -%D \doifolderversionelse\contextversion{3001.02.03}{yes}{no} -%D \stoptyping -%D -%D The \type {yyyy.mm.dd} syntax is rather strict. - -\def\@@versiontonumber#1.#2.#3#4#5\relax - {\numexpr#1*\plustenthousand+#2*\plushundred+#3#4\relax} - -\def\doifolderversionelse#1#2% - {\normalexpanded{\noexpand\ifnum\noexpand\@@versiontonumber#1\relax<\noexpand\@@versiontonumber#2\relax}\relax - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {normalspace} -%D -%D There is already \type{\space} but just to be sure we also -%D provide: - -\def\normalspace{ } - -%D \macros -%D {!!count, !!toks, !!dimen, !!box, -%D !!width, !!height, !!depth, !!string, !!done} -%D -%D We define some more \COUNTERS\ and \DIMENSIONS. We also -%D define some shortcuts to the local scatchregisters~0, 2, 4, -%D 6 and~8. - -\newcount\!!counta \newtoks\!!toksa \newdimen\!!dimena \newbox\!!boxa -\newcount\!!countb \newtoks\!!toksb \newdimen\!!dimenb \newbox\!!boxb -\newcount\!!countc \newtoks\!!toksc \newdimen\!!dimenc \newbox\!!boxc -\newcount\!!countd \newtoks\!!toksd \newdimen\!!dimend \newbox\!!boxd -\newcount\!!counte \newtoks\!!tokse \newdimen\!!dimene \newbox\!!boxe -\newcount\!!countf \newtoks\!!toksf \newdimen\!!dimenf \newbox\!!boxf - \newdimen\!!dimeng - \newdimen\!!dimenh - \newdimen\!!dimeni - \newdimen\!!dimenj - \newdimen\!!dimenk - -\let\!!stringa\empty \let\!!stringb\empty \let\!!stringc\empty -\let\!!stringd\empty \let\!!stringe\empty \let\!!stringf\empty - -\newdimen\!!widtha \newdimen\!!heighta \newdimen\!!deptha -\newdimen\!!widthb \newdimen\!!heightb \newdimen\!!depthb -\newdimen\!!widthc \newdimen\!!heightc \newdimen\!!depthc -\newdimen\!!widthd \newdimen\!!heightd \newdimen\!!depthd - -\newif\if!!donea \newif\if!!doneb \newif\if!!donec -\newif\if!!doned \newif\if!!donee \newif\if!!donef - -\def\!!zerocount {0} % alongside \zerocount -\def\!!minusone {-1} % alongside \minusone -\def\!!plusone {1} % alongside \plusone - -\ifdefined\data \else \let\data \relax \fi % dep checker - -%D \macros -%D {s!,c!,e!,p!,v!,@@,??} -%D -%D To save memory, we use constants (sometimes called -%D variables). Redefining these constants can have disastrous -%D results. - -\def\v!prefix! {v!} \def\c!prefix! {c!} -\def\s!prefix! {s!} \def\p!prefix! {p!} - -\def\s!next {next} \def\s!default {default} -\def\s!dummy {dummy} \def\s!unknown {unknown} - -\def\s!do {do} \def\s!dodo {dodo} - -\def\s!complex {complex} \def\s!start {start} -\def\s!simple {simple} \def\s!stop {stop} - -\def\s!empty {empty} - -%D \macros -%D {@EA,@EAEA,@EAEAEA,@EAEAEAEAEAEA,expanded,startexpanded} -%D -%D When in unprotected mode, to be entered with -%D \type{\unprotect}, one can use \type{\@EA} as equivalent -%D of \type{\expandafter}. - -\let\@NX\noexpand -\let\@EA\expandafter - -\def\@EAEA {\expandafter\expandafter} -\def\@EAEAEA{\expandafter\expandafter\expandafter} - -\def\@EAEAEAEAEAEA{\expandafter\@EAEAEA\expandafter} - -%D Sometimes we pass macros as arguments to commands that -%D don't expand them before interpretation. Such commands can -%D be enclosed with \type{\expanded}, like: -%D -%D \starttyping -%D \expanded{\setupsomething[\alfa]} -%D \stoptyping -%D -%D Such situations occur for instance when \type{\alfa} is a -%D commalist or when data stored in macros is fed to index of -%D list commands. If needed, one should use \type{\noexpand} -%D inside the argument. Later on we will meet some more clever -%D alternatives to this command. - -\long\def\@@expanded{} % always long; global (less restores) - -\long\def\expanded#1% - {\long\xdef\@@expanded{\noexpand#1}\@@expanded} - -%D Beware, the next one has no \type {\noexpand} before its -%D argument. - -\long\def\startexpanded#1\stopexpanded % see x-fo for example - {\long\xdef\@@expanded{#1}\@@expanded} - -%D Recent \TEX's have a primitive \expanded - -% \long\def\expanded -% {\normalexpanded\bgroup\noexpand\gobblenexttoken} - -%D \macros -%D {safeexpanded,everysafeexpanded} -%D -%D In addition we provide: - -\newtoks\everysafeexpanded - -\long\def\safeexpanded#1% why the \noexpand - {\begingroup - \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#1}% - \endgroup - \@@expanded} - -\def\safeedef#1#2% - {\begingroup - \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}% - \endgroup - \let#1\@@expanded} - -\def\safexdef#1#2% - {\begingroup - \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}% - \endgroup - \global\let#1\@@expanded} - -%D You can append protective measures to the token register if -%D needed, as we will do later. - -%D \macros -%D {expandoneargafter,expandtwoargsafter} -%D -%D These two commands make macros more readable by hiding a -%D lot of \type {\expandafter}'s. They expand the arguments -%D after the first command. -%D -%D \starttyping -%D \expandoneargafter \command{\abc} -%D \expandtwoargsafter\command{\abc}{\def} -%D \stoptyping -%D -%D These commands expect the arguments to be macros. - -\def\expandoneargafter #1{\@EA#1\@EA} -\def\expandtwoargsafter#1#2{\@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA#2\@EA}\@EA} - -%D These two do a full expansion: - -\def\fullexpandoneargafter #1#2{\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded} -\def\fullexpandtwoargsafter#1#2#3{\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded} - -%D \macros -%D {gobbleoneargument,gobble...arguments} -%D -%D The next set of macros just do nothing, except that they -%D get rid of a number of arguments. - -\long\def\gobbleoneargument #1{} -\long\def\gobbletwoarguments #1#2{} -\long\def\gobblethreearguments #1#2#3{} -\long\def\gobblefourarguments #1#2#3#4{} -\long\def\gobblefivearguments #1#2#3#4#5{} -\long\def\gobblesixarguments #1#2#3#4#5#6{} -\long\def\gobblesevenarguments #1#2#3#4#5#6#7{} -\long\def\gobbleeightarguments #1#2#3#4#5#6#7#8{} -\long\def\gobbleninearguments #1#2#3#4#5#6#7#8#9{} -\long\def\gobbletenarguments #1{\gobbleninearguments} - -%D \macros -%D {doifnextcharelse} -%D -%D When we started using \TEX\ in the late eighties, our -%D first experiences with programming concerned a simple shell -%D around \LATEX. The commands probably use most at \PRAGMA, -%D are the itemizing ones. One of those few shell commands took -%D care of an optional argument, that enabled us to specify -%D what kind of item symbol we wanted. Without understanding -%D anything we were able to locate a \LATEX\ macro that could -%D be used to inspect the next character. -%D -%D It's this macro that the ancester of the next one presented -%D here. It executes one of two actions, dependant of the next -%D character. Disturbing spaces and line endings, which are -%D normally interpreted as spaces too, are skipped. -%D -%D \starttyping -%D \doifnextcharelse {karakter} {then ...} {else ...} -%D \stoptyping -%D -%D This macro differs from the original in the use of \type -%D {\localnext} because we don't want clashes with \type -%D {\next}. - -\long\def\doifnextcharelse#1#2#3% #1 should not be {} ! - {\let\charactertoken=#1% = needed here - \def\!!stringa{#2}% - \def\!!stringb{#3}% - \futurelet\nexttoken\inspectnextcharacter} - -\def\inspectnextcharacter - {\ifx\nexttoken\blankspace - \@EA\reinspectnextcharacter - \else - \@EA\inspectnextcharacterindeed - \fi} -\def\inspectnextcharacterindeed - {\ifx\nexttoken\charactertoken - \@EA\!!stringa - \else - \@EA\!!stringb - \fi} - -%D Because we will mostly use this macro for testing if the next -%D character is \type {[}, we also make a slightly faster variant -%D as it is not uncommon to have tens of thousands of calls to this -%D test in a run. Of course it also is more convenient to read a -%D trace then. - -\let\nextoptionalcharactertoken=[ - -\long\def\doifnextoptionalelse#1#2% - {\def\nextoptionalcommandyes{#1}% - \def\nextoptionalcommandnop{#2}% - \futurelet\nexttoken\inspectnextoptionalcharacter} - -\def\inspectnextoptionalcharacter - {\ifx\nexttoken\blankspace - \@EA\reinspectnextoptionalcharacter - \else - \@EA\inspectnextoptionalcharacterindeed - \fi} -\def\inspectnextoptionalcharacterindeed - {\ifx\nexttoken\nextoptionalcharactertoken - \@EA\nextoptionalcommandyes - \else - \@EA\nextoptionalcommandnop - \fi} - -\let\nextbgroupcharactertoken\bgroup - -\long\def\doifnextbgroupelse#1#2% - {\def\nextbgroupcommandyes{#1}% - \def\nextbgroupcommandnop{#2}% - \futurelet\nexttoken\inspectnextbgroupcharacter} - -\def\inspectnextbgroupcharacter - {\ifx\nexttoken\blankspace - \@EA\reinspectnextbgroupcharacter - \else - \@EA\inspectnextbgroupcharacterindeed - \fi} -\def\inspectnextbgroupcharacterindeed - {\ifx\nexttoken\nextbgroupcharactertoken - \@EA\nextbgroupcommandyes - \else - \@EA\nextbgroupcommandnop - \fi} - -%D This macro uses some auxiliary macros. Although we were able -%D to program quite complicated things, I only understood these -%D after rereading the \TEX book. The trick is in using a -%D command with a one character name. Such commands differ from -%D the longer ones in the fact that trailing spaces are {\em -%D not} skipped. This enables us to indirectly define a long -%D named macro that gobbles a space. -%D -%D In the first line we define \type{\blankspace}. Next we -%D make \type{\:} equivalent to \type{\reinspect...}. This -%D one||character command is expanded before the next -%D \type{\def} comes into action. This way the space after -%D \type{\:} becomes a delimiter of the longer named -%D \type{\reinspectnextcharacter}. - -\let\next\: - -\def\:{\let\blankspace= } \: - -\def\:{\reinspectnextcharacter} -\expandafter\def\: {\futurelet\nexttoken\inspectnextcharacter} - -\def\:{\reinspectnextoptionalcharacter} -\expandafter\def\: {\futurelet\nexttoken\inspectnextoptionalcharacter} - -\def\:{\reinspectnextbgroupcharacter} -\expandafter\def\: {\futurelet\nexttoken\inspectnextbgroupcharacter} - -\let\:\next - -%D \macros -%D {setvalue,setgvalue,setevalue,setxvalue, -%D letvalue,letgvalue,getvalue,resetvalue, -%D undefinevalue,ignorevalue} -%D -%D \TEX's primitive \type{\csname} can be used to construct -%D all kind of commands that cannot be defined with -%D \type{\def} and \type{\let}. Every macro programmer sooner -%D or later wants macros like these. -%D -%D \starttyping -%D \setvalue {name}{...} = \def\name{...} -%D \setgvalue {name}{...} = \gdef\name{...} -%D \setevalue {name}{...} = \edef\name{...} -%D \setxvalue {name}{...} = \xdef\name{...} -%D \letvalue {name}=\... = \let\name=\... -%D \letgvalue {name}=\... = \global\let\name=\... -%D \getvalue {name} = \name -%D \resetvalue {name} = \def\name{} -%D \stoptyping -%D -%D As we will see, \CONTEXT\ uses these commands many times, -%D which is mainly due to its object oriented and parameter -%D driven character. - -\def\setvalue #1{\expandafter \def\csname#1\endcsname} -\def\setgvalue #1{\expandafter\gdef\csname#1\endcsname} -\def\setevalue #1{\expandafter\edef\csname#1\endcsname} -\def\setxvalue #1{\expandafter\xdef\csname#1\endcsname} -\def\getvalue #1{\csname#1\endcsname} -\def\letvalue #1{\expandafter\let\csname#1\endcsname} -\def\letgvalue #1{\global\expandafter\let\csname#1\endcsname} -\def\resetvalue #1{\expandafter\let\csname#1\endcsname\empty} -\def\undefinevalue#1{\expandafter\let\csname#1\endcsname\undefined} -\def\ignorevalue#1#2{\expandafter\let\csname#1\endcsname\empty} - -%D \macros -%D {globallet,glet} -%D -%D In \CONTEXT\ of May 2000 using \type {\globallet} -%D instead of the two tokens will save us some -%D $300\times4=1200$ bytes of format file on a 32~bit -%D system. So: - -\def\globallet{\global\let} \let\glet\globallet - -%D \macros -%D {donottest,unexpanded} -%D -%D When expansion of a macro gives problems, we can precede it -%D by \type{\donottest}. It seems that protection is one of the -%D burdens of developers of packages, so maybe that's why in -%D \ETEX\ protection is solved in a more robust way. -%D -%D Because we use thi smodule onl in \MKIV, we have removed the -%D old protection code. -%D -%D \starttyping -%D \unexpanded\def\somecommand{... ... ...} -%D \stoptyping - -\let \donottest \firstofoneargument % we need to weed -\let \honorunexpanded \empty % we need to weed -\let \forceunexpanded \empty % we need to weed -\let \resetunexpanded \empty % we need to weed - -\let \unexpanded \normalprotected - -%D \macros -%D {doifundefined,doifdefined, -%D doifundefinedelse,doifdefinedelse, -%D doifalldefinedelse} -%D -%D The standard way of testing if a macro is defined is -%D comparing its meaning with another undefined one, usually -%D \type{\undefined}. To garantee correct working of the next -%D set of macros, \type{\undefined} may never be defined! -%D -%D \starttyping -%D \doifundefined {string} {...} -%D \doifdefined {string} {...} -%D \doifundefinedelse {string} {then ...} {else ...} -%D \doifdefinedelse {string} {then ...} {else ...} -%D \doifalldefinedelse {commalist} {then ...} {else ...} -%D \stoptyping -%D -%D Every macroname that \TEX\ builds gets an entry in the hash -%D table, which is of limited size. It is expected that e-\TeX\ -%D will offer a less memory||consuming alternative. - -%D Although it will probably never be a big problem, it is good -%D to be aware of the difference between testing on a macro -%D name to be build by using \type{\csname} and -%D \type{\endcsname} and testing the \type{\name} directly. -%D -%D \starttyping -%D \expandafter\ifx\csname NameA\endcsname\relax ... \else ... \fi -%D -%D \ifundefined\NameB ... \else ... \fi -%D \stoptyping - -\def\ifundefined#1% ongelukkige naam .. obsolete - {\unless\ifcsname#1\endcsname} - -% \def\p!doifundefined#1% -% {\edef\p!defined{#1}% -% \unless\ifcsname\detokenize\@EA{\p!defined}\endcsname} - -% \def\doifundefinedelse#1% -% {\edef\p!defined{#1}% -% \ifcsname\detokenize\@EA{\p!defined}\endcsname -% \expandafter\secondoftwoarguments -% \else -% \expandafter\firstoftwoarguments -% \fi} - -% \def\doifdefinedelse#1% -% {\edef\p!defined{#1}% -% \ifcsname\detokenize\@EA{\p!defined}\endcsname -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} - -% \def\doifundefined#1% -% {\edef\p!defined{#1}% -% \ifcsname\detokenize\@EA{\p!defined}\endcsname -% \expandafter\gobbleoneargument -% \else -% \expandafter\firstofoneargument -% \fi} - -% \def\doifdefined#1% -% {\edef\p!defined{#1}% -% \ifcsname\detokenize\@EA{\p!defined}\endcsname -% \expandafter\firstofoneargument -% \else -% \expandafter\gobbleoneargument -% \fi} - -\ifdefined\suppressifcsnameerror - - \suppressifcsnameerror\plusone - - \def\doifundefinedelse#1% - {\ifcsname#1\endcsname - \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments - \fi} - - \def\doifdefinedelse#1% - {\ifcsname#1\endcsname - \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments - \fi} - - \def\doifundefined#1% - {\ifcsname#1\endcsname - \@EA\gobbleoneargument\else\@EA\firstofoneargument - \fi} - - \def\doifdefined#1% - {\ifcsname#1\endcsname - \@EA\firstofoneargument\else\@EA\gobbleoneargument - \fi} - -\else - - \def\doifundefinedelse#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments - \fi} - - \def\doifdefinedelse#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments - \fi} - - \def\doifundefined#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\gobbleoneargument\else\@EA\firstofoneargument - \fi} - - \def\doifdefined#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\firstofoneargument\else\@EA\gobbleoneargument - \fi} - -\fi - -%D \macros -%D {letbeundefined} -%D -%D Testing for being undefined comes down to testing on \type -%D {\relax} when we use \type {\csname}, but when using \type -%D {\ifx}, we test on being \type {\undefined}! In \ETEX\ we -%D have \type {\ifcsname} and that way of testing on existance -%D is not the same as the one described here. Therefore we -%D introduce: - -\def\letbeundefined#1% potential stack buildup when used \global - {\expandafter\let\csname#1\endcsname\undefined} - -\def\localundefine#1% conditional - {\ifcsname#1\endcsname\expandafter\let\csname#1\endcsname\undefined\fi} - -\def\globalundefine#1% conditional - {\ifcsname#1\endcsname\expandafter\global\let\csname#1\endcsname\undefined\fi} - -%D Beware, being \type {\undefined} in \ETEX\ means that the macro -%D {\em is} defined! - -%D When we were developing the scientific units module, we -%D encountered different behavior in text and math mode, which -%D was due to this grouping subtilities. We therefore decided -%D to use \type{\begingroup} instead of \type{\bgroup}. - -\def\docheckonedefined#1% - {\ifcsname#1\endcsname\else - \donefalse - \expandafter\quitcommalist % added - \fi} - -\def\doifalldefinedelse#1% - {\begingroup - \donetrue \processcommalist[#1]\docheckonedefined - \ifdone - \endgroup\expandafter\firstoftwoarguments - \else - \endgroup\expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doif,doifelse,doifnot, -%D donottest} -%D -%D Programming in \TEX\ differs from programming in procedural -%D languages like \MODULA. This means that one --- well, let me -%D speek for myself --- tries to do the things in the well -%D known way. Therefore the next set of \type{\ifthenelse} -%D commands were between the first ones we needed. A few years -%D later, the opposite became true: when programming in -%D \MODULA, I sometimes miss handy things like grouping, -%D runtime redefinition, expansion etc. While \MODULA\ taught -%D me to structure, \TEX\ taught me to think recursive. -%D -%D \starttyping -%D \doif {string1} {string2} {...} -%D \doifnot {string1} {string2} {...} -%D \doifelse {string1} {string2} {then ...}{else ...} -%D \stoptyping -%D -%D When expansion gives problems, we can precede the -%D troublemaker with \type{\donottest}. - -\long\def\doif#1#2% - {\edef\!!stringa{#1}\edef\!!stringb{#2}% - \ifx\!!stringa\!!stringb - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\long\def\doifnot#1#2% - {\edef\!!stringa{#1}\edef\!!stringb{#2}% - \ifx\!!stringa\!!stringb - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -\long\def\doifelse#1#2% - {\edef\!!stringa{#1}\edef\!!stringb{#2}% - \ifx\!!stringa\!!stringb - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doifempty,doifemptyelse,doifnotempty} -%D -%D We complete our set of conditionals with: -%D -%D \starttyping -%D \doifempty {string} {...} -%D \doifnotempty {string} {...} -%D \doifemptyelse {string} {then ...} {else ...} -%D \stoptyping -%D -%D This time, the string is not expanded. - -\long\def\doifemptyelse#1% - {\def\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\long\def\doifempty#1% - {\def\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\long\def\doifnotempty#1% - {\def\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -%D \macros -%D {doifinset,doifnotinset,doifinsetelse} -%D -%D We can check if a string is present in a comma separated -%D set of strings. Depending on the result, some action is -%D taken. -%D -%D \starttyping -%D \doifinset {string} {string,...} {...} -%D \doifnotinset {string} {string,...} {...} -%D \doifinsetelse {string} {string,...} {then ...} {else ...} -%D \stoptyping - -% !0nop=\doifinsetelse{ccc}{,}{yes}{nop} -% !0nop=\doifinsetelse{ccc}{,,}{yes}{nop} -% !0nop=\doifinsetelse{ccc}{,,,}{yes}{nop} - -% !1nop=\doifinsetelse{}{}{yes}{nop} -% !2yes=\doifinsetelse{aaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop} -% !3nop=\doifinsetelse{aaa}{bbb}{yes}{nop} -% !4yes=\doifinsetelse{aaa}{aaa}{yes}{nop} -% !5nop=\doifinsetelse{aaaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop} -% !6nop=\doifinsetelse{}{}{yes}{nop} -% !7nop=\doifinsetelse{}{aaa}{yes}{nop} -% !8nop=\doifinsetelse{aaa}{}{yes}{nop} - -% !1=\doifinset{}{}{yes} -% !2yes=\doifinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes} -% !3=\doifinset{aaa}{bbb}{yes} -% !4yes=\doifinset{aaa}{aaa}{yes} -% !5=\doifinset{}{}{yes} -% !6=\doifinset{aaa}{}{yes} - -% !1yes=\doifnotinset{}{}{yes} -% !2=\doifnotinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes} -% !3yes=\doifnotinset{aaa}{bbb}{yes} -% !4=\doifnotinset{aaa}{aaa}{yes} -% !5yes=\doifnotinset{}{}{yes} -% !6yes=\doifnotinset{aaa}{}{yes} - -\def\rightoptionalbracket{]} - -\long\def\doquitifiteminsetelse#1],\relax{\firstoftwoarguments} -\long\def\doquitifiteminset #1],\relax{\firstofoneargument} -\long\def\doquitifitemnotinset #1],\relax{\gobbleoneargument} - -\long\def\redoifinsetelse{\expandafter\docheckifiteminsetelse\!!stringb,],\relax} -\long\def\redoifinset {\expandafter\docheckifiteminset \!!stringb,],\relax} -\long\def\redoifnotinset {\expandafter\docheckifitemnotinset \!!stringb,],\relax} - -\long\def\doifinsetelse#1% make this two step too - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\thirdofthreearguments - \else - \expandafter\dodoifinsetelse - \fi} -\long\def\dodoifinsetelse#1% - {\edef\!!stringb{#1}% - \ifx\!!stringb\empty - \expandafter\secondoftwoarguments - \else - \expandafter\redoifinsetelse - \fi} - -\long\def\doifinset#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\gobbletwoarguments - \else - \expandafter\dodoifinset - \fi} -\long\def\dodoifinset#1% - {\edef\!!stringb{#1}% - \ifx\!!stringb\empty - \expandafter\gobbleoneargument - \else - \expandafter\redoifinset - \fi} - -\long\def\doifnotinset#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\secondoftwoarguments - \else - \expandafter\dodoifnotinset - \fi} -\long\def\dodoifnotinset#1% - {\edef\!!stringb{#1}% - \ifx\!!stringb\empty - \expandafter\firstofoneargument - \else - \expandafter\redoifnotinset % ...]{true} - \fi} - -\def\docheckifiteminsetelse#1,#2% #2 eats up preceding space - {\edef\!!stringb{#1}% - \ifx\!!stringb\empty - \expandafter\docheckifiteminsetelse - \else - \expandafter\dodocheckifiteminsetelse - \fi#2} -\def\dodocheckifiteminsetelse - {\ifx\!!stringb\rightoptionalbracket - \expandafter\thirdofthreearguments - \else - \expandafter\dododocheckifiteminsetelse - \fi} -\def\dododocheckifiteminsetelse - {\ifx\!!stringa\!!stringb - \expandafter\doquitifiteminsetelse - \else - \expandafter\docheckifiteminsetelse - \fi} - -\def\docheckifiteminset#1,#2% #2 eats up preceding space - {\edef\!!stringb{#1}% - \ifx\!!stringb\empty - \expandafter\docheckifiteminset - \else - \expandafter\dodocheckifiteminset - \fi#2} -\def\dodocheckifiteminset - {\ifx\!!stringb\rightoptionalbracket - \expandafter\gobbletwoarguments - \else - \expandafter\dododocheckifiteminset - \fi} -\def\dododocheckifiteminset - {\ifx\!!stringa\!!stringb - \expandafter\doquitifiteminset - \else - \expandafter\docheckifiteminset - \fi} - -\def\docheckifitemnotinset#1,#2% #2 eats up preceding space - {\edef\!!stringb{#1}% - \ifx\!!stringb\empty - \expandafter\docheckifitemnotinset - \else - \expandafter\dodocheckifitemnotinset - \fi#2} -\def\dodocheckifitemnotinset - {\ifx\!!stringb\rightoptionalbracket - \expandafter\secondoftwoarguments - \else - \expandafter\dododocheckifitemnotinset - \fi} -\def\dododocheckifitemnotinset - {\ifx\!!stringa\!!stringb - \expandafter\doquitifitemnotinset - \else - \expandafter\docheckifitemnotinset - \fi} - -%D \macros -%D {doifcommon,doifnotcommon,doifcommonelse} -%D -%D Probably the most time consuming tests are those that test -%D for overlap in sets of strings. -%D -%D \starttyping -%D \doifcommon {string,...} {string,...} {...} -%D \doifnotcommon {string,...} {string,...} {...} -%D \doifcommonelse {string,...} {string,...} {then ...} {else ...} -%D \stoptyping - -% !1yes=\doifcommonelse{aaa,bbb,ccc}{aaa,bbb,ccc}{yes}{nop} -% !2nop=\doifcommonelse{aaa,bbb,ccc}{ddd,eee,fff}{yes}{nop} -% !3nop=\doifcommonelse{aaa}{ddd,eee,fff}{yes}{nop} -% !4yes=\doifcommonelse{aaa}{aaa}{yes}{nop} -% !5nop=\doifcommonelse{bbb}{aaa}{yes}{nop} -% !6nop=\doifcommonelse{}{aaa,bbb,ccc}{yes}{nop} -% !7nop=\doifcommonelse{aaa,bbb,ccc}{}{yes}{nop} -% !8nop=\doifcommonelse{}{}{yes}{nop} - -% !9nop=\doifcommonelse{,,}{,,}{yes}{nop} -% !9yes=\doifcommonelse{,a,}{,a,}{yes}{nop} -% !9yes=\doifcommonelse{,,a,}{,a,}{yes}{nop} -% !9yes=\doifcommonelse{,a,}{,,a,}{yes}{nop} -% !9yes=\doifcommonelse{,a,}{,,,a,}{yes}{nop} -% !9yes=\doifcommonelse{,,a,}{,,,a,}{yes}{nop} - -% \def\p!doifcommonelse#1#2#3#4% -% {\donefalse -% \def\p!docommoncheck##1{\doifinset{##1}{#4}\donetrue\ifdone\quitcommalist\fi}% -% \processcommalist[#3]\p!docommoncheck -% \ifdone\expandafter#1\else\expandafter#2\fi} -% -% \def\doifcommonelse -% {\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments} -% -% \def\doifcommon -% {\p!doifcommonelse\firstofoneargument \gobbleoneargument} -% -% \def\doifnotcommon -% {\p!doifcommonelse\gobbleoneargument \firstofoneargument} - -\long\def\doquitifcommonelse#1],\relax#2],\relax{\firstoftwoarguments} - -\long\def\doquitifcommonelsenop{\secondoftwoarguments} - -\def\docheckifcommonelseone#1,#2% - {\edef\!!stringc{#1}% - \ifx\!!stringc\rightoptionalbracket - \expandafter\thirdofthreearguments - \else - \expandafter\p!docommoncheck - \fi#2} - -\def\docheckifcommonelsetwo#1,#2% we can do an empty #1 check too - {\edef\commalistelement{#1}% - \ifx\commalistelement\rightoptionalbracket - \expandafter\redocheckifcommonelseone - \else - \expandafter\dodocheckifcommonelsetwo - \fi#2} - -\def\dodocheckifcommonelsetwo - {\ifx\commalistelement\empty - \expandafter\docheckifcommonelsetwo - \else - \expandafter\dododocheckifcommonelsetwo - \fi} - -\def\dododocheckifcommonelsetwo - {\ifx\!!stringc\commalistelement - \expandafter\doquitifcommonelse - \else - \expandafter\docheckifcommonelsetwo - \fi} - -\def\redocheckifcommonelseone#1{\docheckifcommonelseone} - -\def\p!doifcommonelse#1#2#3#4% - {\edef\!!stringa{#3}% - \edef\!!stringb{#4}% - \ifx\!!stringa\empty - \expandafter\secondoftwoarguments - \else\ifx\!!stringb\empty - \expandafter\expandafter\expandafter\secondoftwoarguments - \else - \expandafter\expandafter\expandafter\pp!doifcommonelse - \fi\fi - #1#2} - -% \def\p!doifcommonelse#1#2#3% -% {\edef\!!stringa{#3}% -% \ifx\!!stringa\empty -% \expandafter\secondofthreearguments -% \else -% \expandafter\p!dodoifcommonelse -% \fi -% #1#2} % #4 - -% \def\p!dodoifcommonelse#1#2#3% -% {\edef\!!stringb{#3}% -% \ifx\!!stringb\empty -% \expandafter\secondoftwoarguments -% \else -% \expandafter\pp!doifcommonelse -% \fi#1#2} - -\def\pp!doifcommonelse - {\def\p!docommoncheck{\expandafter\docheckifcommonelsetwo\!!stringb,],\relax}% - \expandafter\docheckifcommonelseone\!!stringa,],\relax} - -\def\doifcommonelse{\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments} -\def\doifcommon {\p!doifcommonelse\firstofoneargument \gobbleoneargument } -\def\doifnotcommon {\p!doifcommonelse\gobbleoneargument \firstofoneargument } - -%D \macros -%D {processcommalist,processcommacommand,quitcommalist, -%D processcommalistwithparameters} -%D -%D We've already seen some macros that take care of comma -%D separated lists. Such list can be processed with -%D -%D \starttyping -%D \processcommalist[string,string,...]\commando -%D \stoptyping -%D -%D The user supplied command \type{\commando} receives one -%D argument: the string. This command permits nesting and -%D spaces after commas are skipped. Empty sets are no problem. -%D -%D \startbuffer -%D \def\dosomething#1{(#1)} -%D -%D 1: \processcommalist [\hbox{$a,b,c,d,e,f$}] \dosomething \par -%D 2: \processcommalist [{a,b,c,d,e,f}] \dosomething \par -%D 3: \processcommalist [{a,b,c},d,e,f] \dosomething \par -%D 4: \processcommalist [a,b,{c,d,e},f] \dosomething \par -%D 5: \processcommalist [a{b,c},d,e,f] \dosomething \par -%D 6: \processcommalist [{a,b}c,d,e,f] \dosomething \par -%D 7: \processcommalist [] \dosomething \par -%D 8: \processcommalist [{[}] \dosomething \par -%D \stopbuffer -%D -%D \typebuffer -%D -%D Before we show the result, we present the macro's: - -\newcount\commalevel - -\def\dododoprocesscommaitem - {\csname\s!next\the\commalevel\endcsname} - -% \def\dodoprocesscommaitem -% {\ifx\nexttoken\blankspace -% \@EA\redoprocesscommaitem -% \else\ifx\nexttoken]% -% \@EAEAEA\gobbleoneargument -% \else -% \@EAEAEA\dododoprocesscommaitem -% \fi\fi} - -\def\dodoprocesscommaitem - {\ifx\nexttoken\blankspace - \@EA\redoprocesscommaitem - \else - \@EA\dodoprocesscommaitemindeed - \fi} -\def\dodoprocesscommaitemindeed - {\ifx\nexttoken]% - \@EA\gobbleoneargument - \else - \@EA\dododoprocesscommaitem - \fi} - -\def\doprocesscommaitem - {\futurelet\nexttoken\dodoprocesscommaitem} - -%D Empty arguments are not processed. Empty items (\type{,,}) -%D however are treated. We have to check for the special case -%D \type{[{a,b,c}]}. - -\def\processcommalist[% - {\futurelet\nexttoken\docheckcommaitem} - -\def\docheckcommaitem - {\ifx\nexttoken]% - \expandafter\gobblethreearguments - \else - \expandafter\doprocesscommalist - \fi - \relax} % this one preserved the next {} - -\def\doprocesscommalist#1]#2% - {\global\advance\commalevel \plusone - \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% - {#2{##1}\doprocesscommaitem}% - \@EA\dodoprocesscommaitem\gobbleoneargument#1,]\relax - \global\advance\commalevel \minusone } - -%D One way of quitting a commalist halfway is: - -\def\quitcommalist - {\begingroup\let\doprocesscommaitem\doquitcommalist} - -\def\doquitcommalist#1]% - {\endgroup} - -\def\quitprevcommalist - {\begingroup\let\doprocesscommaitem\doquitprevcommalist} - -\def\doquitprevcommalist#1]% - {\let\doprocesscommaitem\doquitcommalist} - -%D The hack we used for checking the next character -%D \type {\doifnextcharelse} is also used here. - -\def\:{\redoprocesscommaitem} - -\expandafter\def\: {\futurelet\nexttoken\dodoprocesscommaitem} - -%D The previous examples lead to: -%D -%D \getbuffer - -%D When a list is saved in a macro, we can use a construction -%D like: -%D -%D \starttyping -%D \expandafter\processcommalist\expandafter[\list]\command -%D \stoptyping -%D -%D Such solutions suit most situations, but we wanted a bit -%D more. -%D -%D \starttyping -%D \processcommacommand[string,\stringset,string]\commando -%D \stoptyping -%D -%D where \type{\stringset} is a predefined set, like: -%D -%D \starttyping -%D \def\first{aap,noot,mies} -%D \def\second{laatste} -%D -%D \processcommacommand[\first]\message -%D \processcommacommand[\first,second,third]\message -%D \processcommacommand[\first,between,\second]\message -%D \stoptyping -%D -%D Commands that are part of the list are expanded, so the -%D use of this macro has its limits. - -% \def\processcommacommand[#1]% -% {\expanded{\processcommalist[#1]}} - -\def\processcommacommand[#1]% - {\expandafter\processcommalist\expandafter[\normalexpanded{#1}]} - -%D The argument to \type{\command} is not delimited. Because -%D we often use \type{[]} as delimiters, we also have: -%D -%D \starttyping -%D \processcommalistwithparameters[string,string,...]\command -%D \stoptyping -%D -%D where \type{\command} looks like: -%D -%D \starttyping -%D \def\command[#1]{... #1 ...} -%D \stoptyping - -\def\processcommalistwithparameters[#1]#2% - {\def\docommand##1{#2[##1]}% - \processcommalist[#1]\docommand} - -%D \macros -%D {processaction, -%D processfirstactioninset, -%D processallactionsinset} -%D -%D \CONTEXT\ makes extensive use of a sort of case or switch -%D command. Depending of the presence of one or more provided -%D items, some actions is taken. These macros can be nested -%D without problems. -%D -%D \starttyping -%D \processaction [x] [a=>\a,b=>\b,c=>\c] -%D \processfirstactioninset [x,y,z] [a=>\a,b=>\b,c=>\c] -%D \processallactionsinset [x,y,z] [a=>\a,b=>\b,c=>\c] -%D \stoptyping -%D -%D We can supply both a \type{default} action and an action -%D to be undertaken when an \type{unknown} value is met: -%D -%D \starttyping -%D \processallactionsinset -%D [x,y,z] -%D [ a=>\a, -%D b=>\b, -%D c=>\c, -%D default=>\default, -%D unknown=>\unknown{... \commalistelement ...}] -%D \stoptyping -%D -%D When \type{#1} is empty, this macro scans list \type{#2} for -%D the keyword \type{default} and executed the related action -%D if present. When \type{#1} is non empty and not in the list, -%D the action related to \type{unknown} is executed. Both -%D keywords must be at the end of list \type{#2}. Afterwards, -%D the actually found keyword is available in -%D \type{\commalistelement}. An advanced example of the use of -%D this macro can be found in \PPCHTEX, where we completely -%D rely on \TEX\ for interpreting user supplied keywords like -%D \type{SB}, \type{SB1..6}, \type{SB125} etc. - -\newcount\processlevel - -\def\p!compareprocessactionA[#1=>#2][#3]% - {\edef\!!stringb{#1}% - \ifx\!!stringb\s!default - \let\commalistelement\empty - #2% - \fi} - -% met \quitcommalist tot meer dan 25\% sneller - -\def\p!compareprocessactionB[#1=>#2][#3]% - {\expandedaction\!!stringb{#1}% - \ifx\!!stringa\!!stringb - \def\commalistelement{#3}% - #2% - \expandafter\quitcommalist - \else - \edef\!!stringb{#1}% - \ifx\!!stringb\s!unknown - \def\commalistelement{#3}% beware of loops - #2% - \fi - \fi} - -\def\processaction[#1]#2[% - {\expandedaction\!!stringa{#1}% - \ifx\!!stringa\empty - \let\p!compareprocessaction\p!compareprocessactionA - \else - \let\p!compareprocessaction\p!compareprocessactionB - \fi - \def\p!doprocessaction##1% - {\p!compareprocessaction[##1][#1]}% - \processnextcommalist\relax\expandactions\p!doprocessaction[} - -\def\p!compareprocessactionC[#1=>#2][#3]% - {\expandedaction\!!stringa{#1}% - \expandedaction\!!stringb{#3}% - \ifx\!!stringa\!!stringb - \def\commalistelement{#3}% - #2% - \expandafter\quitprevcommalist - \else - \edef\!!stringa{#1}% - \ifx\!!stringa\s!unknown - \def\commalistelement{#3}% - #2% - \fi - \fi} - -\def\processfirstactioninset[#1]% - {\expandedaction\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\processaction - \else - \expandafter\processfirstactionsinsetindeed - \fi - [#1]} - -\def\processfirstactionsinsetindeed[#1]#2[#3]% - {\def\p!doprocessaction##1% - {\def\p!dodoprocessaction####1% - {\p!compareprocessactionC[####1][##1]}% - \processcommalist[#3]\p!dodoprocessaction}% - \processcommalist[#1]\p!doprocessaction - \expandactions} - -\def\p!compareprocessactionD[#1=>#2][#3]% - {\expandedaction\!!stringa{#1}% - \expandedaction\!!stringb{#3}% - \ifx\!!stringa\!!stringb - \def\commalistelement{#3}% - #2% - \expandafter\quitcommalist - \else - \edef\!!stringa{#1}% - \ifx\!!stringa\s!unknown - \def\commalistelement{#3}% - #2% - \fi - \fi} - -\def\doprocessallactionsinset - {\csname\s!do\the\processlevel\endcsname} - -\def\processallactionsinset[#1]% - {\expandedaction\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\processaction - \else - \expandafter\processallactionsinsetindeed - \fi - [#1]} - -\def\processallactionsinsetindeed[#1]#2[#3]% - {\advance\processlevel \plusone - \expandafter\def\csname\s!do\the\processlevel\endcsname##1% - {\def\p!dodoprocessaction####1% - {\p!compareprocessactionD[####1][##1]}% - \processcommalist[#3]\p!dodoprocessaction}% - \processcommalist[#1]\doprocessallactionsinset - \advance\processlevel \minusone - \expandactions} - -%D These macros use: - -\def\processnextcommalist#1#2#3[#4#5]% - {#1% - \let\nexttoken#4% - \global\advance\commalevel \plusone - \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% - {#3{##1}\doprocesscommaitem}% - \dodoprocesscommaitem#4#5,]\relax - \global\advance\commalevel \minusone - #2} - -%D \macros -%D {unexpandedprocessaction, -%D unexpandedprocessfirstactioninset, -%D unexpandedprocessallactionsinset} -%D -%D Now what are those expansion commands doing there. Well, -%D sometimes we want to compare actions that may consist off -%D commands (i.e. are no constants). In such occasions we can -%D use the a bit slower alternatives: - -\def\unexpandedprocessfirstactioninset{\dontexpandactions\processfirstactioninset} -\def\unexpandedprocessaction {\dontexpandactions\processaction} -\def\unexpandedprocessallactionsinset {\dontexpandactions\processallactionsinset} - -%D By default we expand actions: - -\def\expandactions{\let\expandedaction\edef} \expandactions - -%D But when needed we convert the strings to meaningful -%D sequences of characters. - -\def\unexpandedaction#1>{} - -\def\noexpandedaction#1#2% - {\def\@@convertedargument{#2}% - \@EA\edef\@EA#1\@EA{\@EA\unexpandedaction\meaning\@@convertedargument}} - -\def\dontexpandactions - {\let\expandedaction\noexpandedaction} - -%D \macros -%D {getfirstcharacter, firstcharacter, remainingcharacters, doiffirstcharacter} -%D -%D Sometimes the action to be undertaken depends on the -%D next character. This macro get this character and puts it in -%D \type{\firstcharacter}. -%D -%D \starttyping -%D \getfirstcharacter {string} -%D \stoptyping -%D -%D A two step expansion is used to prevent problems with -%D complicated arguments, for instance arguments that -%D consist of two or more expandable tokens. - -\def\dogetfirstcharacter#1#2\relax - {\def\firstcharacter{#1}% - \def\remainingcharacters{#2}} - -\def\getfirstcharacter#1% - {\edef\!!stringa{#1}% - \expandafter\dogetfirstcharacter\!!stringa\relax} - -\def\doiffirstcharelse#1#2% char string -% kort (maar onleesbaar) -% {\expanded{\dogetfirstcharacter#2}\\\doifelse{#1}\firstcharacter} -% korter (en begrijpelijk)) - {\getfirstcharacter{#2}\doifelse{#1}\firstcharacter} -% snel (maar zelden gebruikt, dus niet zo belangrijk) -% {\getfirstcharacter{#2}% -% \edef\!!stringa{#1}% -% \ifx\!!stringa\firstcharacter -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} - -%D \macros -%D {doifinstringelse, doifincsnameelse} -%D -%D We can check for the presence of a substring in a given -%D sequence of characters. -%D -%D \starttyping -%D \doifinsetelse {substring} {string} {then ...} {else ...} -%D \stoptyping - -\long\def\doifinstringelse#1% - {\edef\@@@instring{#1}% expand #1 here - \ifx\@@@instring\empty - \@EA\thirdofthreearguments - \else - \@EA\dodoifinstringelse - \fi} - -\long\def\dodoifinstringelse#1% - {\p!doifinstringelse\@@@instring{#1}% - \@EA\firstoftwoarguments - \else - \@EA\secondoftwoarguments - \fi} - -\long\def\doifinstring#1%% - {\edef\@@@instring{#1}% expand #1 here - \ifx\@@@instring\empty - \@EA\gobbletwoarguments - \else - \@EA\dodoifinstring - \fi} - -\long\def\dodoifinstring#1% - {\p!doifinstringelse\@@@instring{#1}% - \@EA\firstofoneargument - \else - \@EA\gobbleoneargument - \fi} - -\long\def\doifnotinstring#1%% - {\edef\@@@instring{#1}% expand #1 here - \ifx\@@@instring\empty - \@EA\gobbletwoarguments - \else - \@EA\dodoifnotinstring - \fi} - -\long\def\dodoifnotinstring#1% - {\p!doifinstringelse\@@@instring{#1}% - \@EA\gobbleoneargument - \else - \@EA\firstofoneargument - \fi} - -% replaces prev - -% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} -% {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here -% \expanded{\pp!doifinstringelse#2#1}@@\war} % expand #2 here - -\long\def\p!doifinstringelse#1#2% ##2 can be {abc} - {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here - \expandafter\pp!doifinstringelse\normalexpanded{#2#1}@@\war} % expand #2 here - -% faster but at some costs -% -% \def\setp!doifinstringelse#1#2% ##2 can be {abc} -% {\long\expandafter\gdef\csname @diie:#1\@EA\endcsname\@EA##\@EA1#1##2##3\war{\unless\if##2@}}% expand #1 here -% -% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} -% {\ifcsname @diie:#1\endcsname \else -% \setp!doifinstringelse{#1}{#2}% -% \fi -% \csname @diie:#1\expandafter\endcsname\normalexpanded{#2#1}@@\war} % expand #2 here - -%D The next alternative proved to be upto twice as fast on -%D tasks like checking reserved words in pretty verbatim -%D typesetting! This is mainly due to the fact that passing -%D (expanded) strings is much slower that passing a macro. -%D -%D \starttyping -%D \doifincsnameelse {substring} {\string} {then ...} {else ...} -%D \stoptyping -%D -%D Where \type{\doifinstringelse} does as much expansion as -%D possible, the latter alternative does minimal (one level) -%D expansion. - -\long\def\p!doifincsnameelse#1#2% - {\long\def\pp!doifincsnameelse##1#1##2##3\war - {\unless\if##2@}% - \@EA\pp!doifincsnameelse#2#1@@\war} - -\long\def\doifincsnameelse#1#2% % #3#4% - {\edef\@@@instring{#1}% - \@EA\p!doifincsnameelse\@EA{\@@@instring}{#2}% % #3\else#4\fi} - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doifnumberelse} -%D -%D The next macro executes a command depending of the outcome -%D of a test on numerals. This is probably one of the fastest -%D test possible, exept from a less robust 10||step -%D \type{\if}||ladder or some tricky \type{\lcode} checking. -%D -%D \starttyping -%D \doifnumberelse {string} {then ...} {else ...} -%D \stoptyping -%D -%D The macro accepts \type{123}, \type{abc}, \type{{}}, -%D \type{\getal} and \type{\the\count...}. This macro is a -%D rather dirty one. - -\long\def\doifnumberelse#1% does not accept counters - {\ifcase0\ifcase1#1\or\or\or\or\or\or\or\or\or\else1\fi\space - \expandafter\secondoftwoarguments - \else - \expandafter\firstoftwoarguments - \fi} - -%D \macros -%D {makerawcommalist, -%D rawdoinsetelse, -%D rawprocesscommalist, -%D rawprocessaction} -%D -%D Some of the commands mentioned earlier are effective but -%D slow. When one is desperately in need of faster alternatives -%D and when the conditions are predictable safe, the \type{\raw} -%D alternatives come into focus. A major drawback is that -%D they do not take \type{\c!constants} into account, simply -%D because no expansion is done. This is no problem with -%D \type{\rawprocesscommalist}, because this macro does not -%D compare anything. Expandable macros are permitted as search -%D string. -%D -%D \starttyping -%D \makerawcommalist[string,string,...]\stringlist -%D \rawdoifinsetelse{string}{string,...}{...}{...} -%D \rawprocesscommalist[string,string,...]\commando -%D \rawprocessaction[x][a=>\a,b=>\b,c=>\c] -%D \stoptyping -%D -%D Spaces embedded in the list, for instance after commas, -%D spoil the search process. The gain in speed depends on the -%D length of the argument (the longer the argument, the less -%D we gain). - -\def\makerawcommalist[#1]#2% use \processnext ... here - {\def\domakerawcommalist##1% we don't expand ##1 - {\ifx#2\empty - \def#2{##1}% - \else - \@EA\def\@EA#2\@EA{#2,##1}% - \fi}% - \let#2\empty - \processcommalist[#1]\domakerawcommalist} - -\def\rawprocesscommaitem#1,#2% #2 eats up preceding space - {\if]#1\else - \csname\s!next\the\commalevel\endcsname{#1}% - \expandafter\rawprocesscommaitem - \fi#2} - -\def\rawprocesscommalist[#1]#2% accepteert ook [\cs] - {\global\advance\commalevel \plusone - \expandafter\let\csname\s!next\the\commalevel\endcsname#2% - \expandafter\rawprocesscommaitem#1,],% \relax - \global\advance\commalevel \minusone } - -\def\rawprocesscommacommand[#1]% not really needed - {\expanded{\rawprocesscommalist[#1]}} - -% \def\rawdoifinsetelse#1#2{\doifinstringelse{,#1,}{,#2,}} -% \def\rawdoifinset #1#2{\doifinstring {,#1,}{,#2,}} - -\def\@@rawempty{,,} - -\long\def\rawdoifinsetelse#1% - {\edef\@@@instring{,#1,}% expand #1 here - \ifx\@@@instring\@@rawempty - \@EA\thirdofthreearguments - \else - \@EA\rawdodoifinsetelse - \fi} - -\long\def\rawdodoifinsetelse#1% - {\p!doifinstringelse\@@@instring{,#1,}% - \@EA\firstoftwoarguments - \else - \@EA\secondoftwoarguments - \fi} - -\long\def\rawdoifinset#1% - {\edef\@@@instring{,#1,}% expand #1 here - \ifx\@@@instring\@@rawempty - \@EA\gobbletwoarguments - \else - \@EA\rawdodoifinset - \fi} - -\long\def\rawdodoifinset#1%% - {\p!doifinstringelse\@@@instring{,#1,}% - \@EA\firstofoneargument - \else - \@EA\gobbleoneargument - \fi} - -%D Some more raw material: - -\def\p!rawprocessaction[#1][#2]% - {\def\pp!rawprocessaction##1,#1=>##2,##3\war% - {\if##3@\else - \def\!!processaction{##2}% - \fi}% - \pp!rawprocessaction,#2,#1=>,@\war} - -\def\rawprocessaction[#1]#2[#3]% - {\edef\!!stringa{#1}% - \edef\!!stringb{undefined}% better \!!undefined - \let\!!processaction\!!stringb - \ifx\!!stringa\empty - \@EA\p!rawprocessaction\@EA[\s!default][#3]% - \else - \expandafter\p!rawprocessaction\expandafter[\!!stringa][#3]% - \ifx\!!processaction\!!stringb - \@EA\p!rawprocessaction\@EA[\s!unknown][#3]% - \fi - \fi - \ifx\!!processaction\!!stringb - \else - \!!processaction - \fi} - -%D When we process the list \type{a,b,c,d,e}, the raw routine -%D takes over 30\% less time, when we feed $20+$ character -%D strings we gain about 20\%. Alternatives which use -%D \type{\futurelet} perform worse. Part of the speedup is -%D due to the \type{\let} and \type{\expandafter} in the test. - -%D \macros -%D {dosetvalue,dosetevalue,dosetgvalue,docopyvalue,doresetvalue, -%D dogetvalue} -%D -%D When we are going to do assignments, we have to take -%D multi||linguality into account. For the moment we keep -%D things simple and single||lingual. -%D -%D \starttyping -%D \dosetvalue {label} {variable} {value} -%D \dosetevalue {label} {variable} {value} -%D \dosetgvalue {label} {variable} {value} -%D \docopyvalue {to label} {from label} {variable} -%D \doresetvalue {label} {variable} -%D \stoptyping -%D -%D These macros are in fact auxiliary ones and are not meant -%D for use outside the assignment macros. - -\def\dosetvalue#1#2% #3 - {\@EA\def\csname#1#2\endcsname} % {#3}} - -\def\dosetevalue#1#2% #3 - {\@EA\edef\csname#1#2\endcsname} % {#3}} - -\def\dosetgvalue#1#2% #3 - {\@EA\gdef\csname#1#2\endcsname} % {#3}} - -\def\doresetvalue#1#2% - {\@EA\let\csname#1#2\endcsname\empty} - -\def\doignorevalue#1#2#3% - {\@EA\let\csname#1#2\endcsname\empty} - -\def\docopyvalue#1#2#3% - {\@EA\def\csname#1#3\endcsname{\csname#2#3\endcsname}} - -%D \macros -%D {doassign,undoassign,doassignempty} -%D -%D Assignments are the backbone of \CONTEXT. Abhorred by the -%D concept of style file hacking, we took a considerable effort -%D in building a parameterized system. Unfortunately there is a -%D price to pay in terms of speed. Compared to other packages -%D and taking the functionality of \CONTEXT\ into account, the -%D total size of the format file is still very acceptable. Now -%D how are these assignments done. -%D -%D Assignments can be realized with: -%D -%D \starttyping -%D \doassign[label][variable=value] -%D \undoassign[label][variable=value] -%D \stoptyping -%D -%D and: -%D -%D \starttyping -%D \doassignempty[label][variable=value] -%D \stoptyping -%D -%D Assignments like \type{\doassign} are compatible with: -%D -%D \starttyping -%D \def\labelvariable{value} -%D \stoptyping -%D -%D We do check for the presence of an \type{=} and loudly -%D complain of it's missed. We will redefine this macro later -%D on, when a more advanced message mechanism is implemented. - -\newif\iferrorisfatal - -\def\waitonfatalerror - {\iferrorisfatal\wait\fi} - -\def\showassignerror#1#2% - {\writestatus{setup}{missing or ungrouped '=' after '#1' in line #2}% - \waitonfatalerror} - -\def\doassignempty[#1][#2=#3]% - {\ifcsname#1#2\endcsname\else\dosetvalue{#1}{#2}{#3}\fi} - -%D \macros -%D {getparameters,geteparameters,getgparameters, -%D forgetparameters} -%D -%D Using the assignment commands directly is not our -%D ideal of user friendly interfacing, so we take some further -%D steps. -%D -%D \starttyping -%D \getparameters [label] [...=...,...=...] -%D \forgetparameters [label] [...=...,...=...] -%D \stoptyping -%D -%D Again, the label identifies the category a variable -%D belongs to. The second argument can be a comma separated -%D list of assignments. -%D -%D \starttyping -%D \getparameters -%D [demo] -%D [alfa=1, -%D beta=2] -%D \stoptyping -%D -%D is equivalent to -%D -%D \starttyping -%D \def\demoalfa{1} -%D \def\demobeta{2} -%D \stoptyping -%D -%D -%D In the pre||multi||lingual stadium \CONTEXT\ took the next -%D approach. With -%D -%D \starttyping -%D \def\??demo {@@demo} -%D \def\!!alfa {alfa} -%D \def\!!beta {beta} -%D \stoptyping -%D -%D calling -%D -%D \starttyping -%D \getparameters -%D [\??demo] -%D [\!!alfa=1, -%D \!!beta=2] -%D \stoptyping -%D -%D lead to: -%D -%D \starttyping -%D \def\@@demoalfa{1} -%D \def\@@demobeta{2} -%D \stoptyping -%D -%D Because we want to be able to distinguish the \type{!!} -%D pre||tagged user supplied variables from internal -%D counterparts, we will introduce a slightly different tag in -%D the multi||lingual modules. There we will use \type{c!} or -%D \type{v!}, depending on the context. -%D -%D By calling \type{\p!doassign} directly, we save ourselves -%D some argument passing and gain some speed. Whatever -%D optimizations we do, this command will always be one of the -%D bigger bottlenecks. -%D -%D The alternative \type{\geteparameters} --- it's funny to -%D see that this alternative saw the light so lately --- can be -%D used to do expanded assigments. - -\let\currentvalue\empty - -\def\getparameters {\dogetparameters\dosetvalue} -\def\geteparameters {\dogetparameters\dosetevalue} -\def\getgparameters {\dogetparameters\dosetgvalue} -\def\forgetparameters{\dogetparameters\doignorevalue} - -\let\getexpandedparameters=\geteparameters - -% \def\dogetparameters#1[#2]#3[#4% -% {\if\noexpand#4]% -% \expandafter\gobbleoneargument -% \else -% \def\p!dogetparameter{\p!doassign#1#2}% -% \expandafter\xdogetparameters -% \fi#4} - -\def\dogetparameters#1[#2]#3[#4% - {\if\noexpand#4]% - \expandafter\gobbleoneargument - \else - \let\setsomevalue#1% - \def\p!dogetparameter{\p!doassign#2}% - \expandafter\xdogetparameters - \fi#4} - -\def\xdogetparameters#1]% - {\xprocesscommaitem#1,],\@relax@} - -\long\def\xprocesscommaitem#1,#2% #2 takes space before , - {\if,#1,% dirty trick for testing #1=empty - \@EA\xprocesscommaitem - \else\if]#1% - \@EAEAEA\gobbleoneargument - \else - \p!dogetparameter\@relax@#1==\empty\@relax@ - \@EAEAEA\xprocesscommaitem - \fi\fi#2} - -\def\xshowassignerror#1#2#3% - {\showassignerror{#2}{\the\inputlineno\space(#1)}} - -% \def\p!n!doassign#1#2\@relax@#3=#4=#5#6\@relax@ -% {\ifx\empty#3\empty -% \@EA\xshowassignerror -% \else\ifx#5\empty -% \@EAEAEA\xshowassignerror -% \else -% \@EAEAEA#1% -% \fi\fi -% {#2}{#3}{#4}} - -% \def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@ -% {\ifx\empty#3\empty -% \@EA\xshowassignerror -% \else\ifx#5\empty -% \@EAEAEA\xshowassignerror -% \else -% \ifcsname#2#3\endcsname -% \@EA\let\@EA\currentvalue\csname#2#3\endcsname -% \else -% \let\currentvalue\empty -% \fi -% \@EAEAEA#1% -% \fi\fi -% {#2}{#3}{#4}} - -\def\p!n!doassign#1\@relax@#2=#3=#4#5\@relax@ - {\ifx\empty#2\empty - \@EA\xshowassignerror - \else\ifx#4\empty - \@EAEAEA\xshowassignerror - \else - \@EAEAEA\setsomevalue - \fi\fi - {#1}{#2}{#3}} - - -\def\p!e!doassign#1\@relax@#2=#3=#4#5\@relax@ - {\ifx\empty#2\empty - \@EA\xshowassignerror - \else\ifx#4\empty - \@EAEAEA\xshowassignerror - \else - \ifcsname#1#2\endcsname - \@EA\let\@EA\currentvalue\csname#1#2\endcsname - \else - \let\currentvalue\empty - \fi - \@EAEAEA\setsomevalue - \fi\fi - {#1}{#2}{#3}} - -\let\p!doassign\p!n!doassign - -% \def\doassign [#1][#2]{\p!doassign\dosetvalue #1\@relax@#2==\empty\@relax@} -% \def\doeassign [#1][#2]{\p!doassign\dosetevalue #1\@relax@#2==\empty\@relax@} -% \def\undoassign[#1][#2]{\p!doassign\doresetvalue#1\@relax@#2==\empty\@relax@} - -\def\doassign [#1][#2]{\let\setsomevalue\dosetvalue \p!doassign#1\@relax@#2==\empty\@relax@} -\def\doeassign [#1][#2]{\let\setsomevalue\dosetevalue \p!doassign#1\@relax@#2==\empty\@relax@} -\def\undoassign[#1][#2]{\let\setsomevalue\doresetvalue\p!doassign#1\@relax@#2==\empty\@relax@} - -%D \macros{currentvalue} -%D -%D Just in case a \type{\getparameter} argument itself ends up -%D inside a \type{\write} or other expandable location, our -%D new macro needs a default value. -%D -%D \starttyping -%D \getparameters[xxx][aaa=bbb]\par -%D \getparameters[xxx][=bbb]\par -%D \getparameters[xxx][aaa=]\par -%D \getparameters[xxx][=]\par -%D \getparameters[xxx][aaa]\par -%D \stoptyping - -%D \macros {expandparameters} -%D -%D Example usage: -%D -%D \startbuffer -%D \getparameters[taco][name=taco] -%D \convertcommand\taconame\to\ascii \ascii -%D \expandparameters \getparameters[taco][name=\currentvalue\space hoekwater] -%D \convertcommand\taconame\to\ascii \ascii -%D \getparameters[taco][name=\currentvalue\space hoekwater] -%D \convertcommand\taconame\to\ascii \ascii -%D \stopbuffer -%D -%D \typebuffer -%D \startlines -%D \getbuffer -%D \stoplines - -%D Here we hook in the code (beware, this is the optimized get **): - -\def\xdoget@n@parameters#1]% - {\xprocesscommaitem#1,],\@relax@} - -\def\xdoget@e@parameters#1]% - {\let\dosetnvalue\dosetvalue - \let\dosetvalue\dosetevalue - \let\p!doassign\p!e!doassign - \xprocesscommaitem#1,],\@relax@ - \let\p!doassign\p!n!doassign - \let\dosetvalue\dosetnvalue - \let\xdogetparameters\xdoget@n@parameters - \let\currentvalue\empty} - -\let\xdogetparameters\xdoget@n@parameters % ** - -\def\expandparameters{\let\xdogetparameters\xdoget@e@parameters} - -%D \macros -%D {getemptyparameters} -%D -%D Sometimes we explicitly want variables to default to an -%D empty string, so we welcome: -%D -%D \starttyping -%D \getemptyparameters [label] [...=...,...=...] -%D \stoptyping - -\def\getemptyparameters[#1]#2[#3]% - {\def\p!dogetemptyparameter##1{\doassignempty[#1][##1]}% - \processcommalist[#3]\p!dogetemptyparameter} - -%D \macros -%D {copyparameters} -%D -%D Some \CONTEXT\ commands take their default setups from -%D others. All commands that are able to provide backgounds -%D or rules around some content, for instance default to the -%D standard command for ruled boxes. Is situations like this -%D we can use: -%D -%D \starttyping -%D \copyparameters [to-label] [from-label] [name1,name2,...] -%D \stoptyping -%D -%D For instance -%D -%D \starttyping -%D \copyparameters -%D [internal][external] -%D [alfa,beta] -%D \stoptyping -%D -%D Leads to: -%D -%D \starttyping -%D \def\internalalfa {\externalalfa} -%D \def\internalbeta {\externalbeta} -%D \stoptyping -%D -%D By using \type{\docopyvalue} we've prepared this command -%D for use in a multi||lingual environment. - -\def\copyparameters[#1]#2[#3]#4[#5]% - {\doifnot{#1}{#3} - {\def\docopyparameter{\docopyvalue{#1}{#3}}% ##1 - \processcommalist[#5]\docopyparameter}} - -%D \macros -%D {ifparameters,checkparameters} -%D -%D A slightly different one is \type{\checkparameters}, which -%D also checks on the presence of a~\type{=}. -%D -%D The boolean \type{\ifparameters} can be used afterwards. -%D Combining both in one \type{\if}||macro would lead to -%D problems with nested \type{\if}'s. -%D -%D \starttyping -%D \checkparameters[argument] -%D \stoptyping - -\newif\ifparameters - -\def\p!checkparameters#1=#2#3\war% - {\if#2@\parametersfalse\else\parameterstrue\fi} - -\def\checkparameters[#1]% - {\p!checkparameters#1=@@\war} - -%D \macros -%D {getfromcommalist,getfromcommacommand, -%D commalistelement, -%D getcommalistsize,getcommacommandsize} -%D -%D It's possible to get an element from a commalist or a -%D command representing a commalist. -%D -%D \starttyping -%D \getfromcommalist [string] [n] -%D \getfromcommacommand [string,\strings,string,...] [n] -%D \stoptyping -%D -%D The difference betwee the two of them is the same as the -%D difference between \type{\processcomma...}. The found string -%D is stored in \type{\commalistelement}. -%D -%D We can calculate the size of a comma separated list by -%D using: -%D -%D \starttyping -%D \getcommalistsize [string,string,...] -%D \getcommacommandsize [string,\strings,string,...] -%D \stoptyping -%D -%D Afterwards, the length is available in the macro -%D \type{\commalistsize} (not a \COUNTER). - -\newcount\commalistcounter - -\def\commalistsize{0} - -\def\p!dogetcommalistsize#1% - {\advance\commalistcounter\plusone} - -\def\getcommalistsize#1]% don't loose [{#1}] - {\commalistcounter\zerocount - \processcommalist#1]\p!dogetcommalistsize % was [{#1}] - \edef\commalistsize{\the\commalistcounter}} - -\def\getcommacommandsize[#1]% - {\edef\commacommand{#1}% - \scratchtoks\expandafter{\expandafter[\commacommand]}% - \expandafter\getcommalistsize\the\scratchtoks } - -% to be tested first -% -% \def\getcommacommandsize[#1]% -% {\expanded{\getcommalistsize[#1]}} - -% \def\p!dogetfromcommalist#1% -% {\advance\commalistcounter \minusone -% \ifcase\commalistcounter -% \def\commalistelement{#1}% -% \begingroup\def\doprocesscommaitem##1]{\endgroup}% -% \fi} - -\def\p!dogetfromcommalist#1% - {\advance\commalistcounter \minusone - \ifcase\commalistcounter - \def\commalistelement{#1}% - \expandafter\quitcommalist - \fi} - -\def\getfromcommalist[#1]#2[#3]% - {\let\commalistelement\empty - \commalistcounter#3\relax - \processcommalist[#1]\p!dogetfromcommalist} - -\def\getfromcommacommand[#1]% - {\expanded{\getfromcommalist[#1]}} - -%D Watertight (and efficient) solutions are hard to find, due -%D to the handling of braces during parameters passing and -%D scanning. Nevertheless: -%D -%D \startbuffer -%D \def\dosomething#1{(#1=\commalistsize) } -%D -%D \getcommalistsize [\hbox{$a,b,c,d,e,f$}] \dosomething 1 -%D \getcommalistsize [{a,b,c,d,e,f}] \dosomething 1 -%D \getcommalistsize [{a,b,c},d,e,f] \dosomething 4 -%D \getcommalistsize [a,b,{c,d,e},f] \dosomething 4 -%D \getcommalistsize [a{b,c},d,e,f] \dosomething 4 -%D \getcommalistsize [{a,b}c,d,e,f] \dosomething 4 -%D \getcommalistsize [] \dosomething 0 -%D \getcommalistsize [{[}] \dosomething 1 -%D \stopbuffer -%D -%D \typebuffer -%D -%D reports: -%D -%D \getbuffer - -%D \macros -%D {dogetcommalistelement,dogetcommacommandelement} -%D -%D For low level (fast) purposes, we can also use the next -%D alternative, which can handle 8~elements at most. -%D -%D \starttyping -%D \dogetcommalistelement1\from a,b,c\to\commalistelement -%D \stoptyping - -\def\dodogetcommalistelement#1\from#2,#3,#4,#5,#6,#7,#8\to#9% - {\edef#9{\ifcase#1\relax\or#2\or#3\or#4\or#5\or#6\or#7\or#8\fi}} - -\def\dogetcommalistelement#1\from#2\to% - {\dodogetcommalistelement#1\from#2,,,,,,\to} - -% check sources - -\def\dogetcommacommandelement#1\from#2\to% - {\@EA\dodogetcommalistelement\@EA#1\@EA\from#2,,,,,,\to} - -%D \macros -%D {dosingleargument,dodoubleargument,dotripleargument, -%D doquadrupleargument,doquintupleargument,dosixtupleargument, -%D doseventupleargument} -%D -%D When working with delimited arguments, spaces and -%D lineendings can interfere. The next set of macros uses -%D \TEX' internal scanner for grabbing everything between -%D arguments. Forgive me the funny names. -%D -%D \starttyping -%D \dosingleargument\commando = \commando[#1] -%D \dodoubleargument\commando = \commando[#1][#2] -%D \dotripleargument\commando = \commando[#1][#2][#3] -%D \doquadrupleargument\commando = \commando[#1][#2][#3][#4] -%D \doquintupleargument\commando = \commando[#1][#2][#3][#4][#5] -%D \dosixtupleargument\commando = \commando[#1][#2][#3][#4][#5][#6] -%D \doseventupleargument\command = \commando[#1][#2][#3][#4][#5][#6][#7] -%D \stoptyping -%D -%D These macros are used in the following way: -%D -%D \starttyping -%D \def\dosetupsomething[#1][#2]% -%D {... #1 ... #2 ...} -%D -%D \def\setupsomething -%D {\dodoubleargument\dosetupsomething} -%D \stoptyping -%D -%D The implementation can be surprisingly simple and needs no -%D further explanation, like: -%D -%D \starttyping -%D \def\dosingleargument#1[#2]% -%D {#1[#2]} -%D \def\dotripleargument#1[#2]#3[#4]#5[#6]% -%D {#1[#2][#4][#6]} -%D \def\doquintupleargument#1% -%D {\def\dodoquintupleargument[##1]##2[##3]##4[##5]##6[##7]##8[##9]% -%D {#1[##1][##3][##5][##7][##9]}% -%D \dodoquintupleargument} -%D \stoptyping -%D -%D Because \TEX\ accepts 9~arguments at most, we have to use -%D two||step solution when getting five or more arguments. -%D -%D When developing more and more of the real \CONTEXT, we -%D started using some alternatives that provided empty -%D arguments (in fact optional ones) whenever the user failed -%D to supply them. Because this more complicated macros enable -%D us to do some checking, we reimplemented the non||empty -%D ones. - -\def\dosingleargument {\let\expectedarguments\plusone \dosingleempty } -\def\dodoubleargument {\let\expectedarguments\plustwo \dodoubleempty } -\def\dotripleargument {\let\expectedarguments\plusthree \dotripleempty } -\def\doquadrupleargument {\let\expectedarguments\plusfour \doquadrupleempty } -\def\doquintupleargument {\let\expectedarguments\plusfive \doquintupleempty } -\def\dosixtupleargument {\let\expectedarguments\plussix \dosixtupleempty } -\def\doseventupleargument{\let\expectedarguments\plusseven \doseventupleempty} - -%D \macros -%D {iffirstagument,ifsecondargument,ifthirdargument, -%D iffourthargument,iffifthargument,ifsixthargument, -%D ifseventhargument} -%D -%D We use some signals for telling the calling macros if all -%D wanted arguments are indeed supplied by the user. - -\newif\iffirstargument -\newif\ifsecondargument -\newif\ifthirdargument -\newif\iffourthargument -\newif\iffifthargument -\newif\ifsixthargument -\newif\ifseventhargument - -%D \macros -%D {dosingleempty,dodoubleempty,dotripleempty, -%D doquadrupleempty,doquintupleempty,dosixtupeempty, -%D doseventupleempty} -%D -%D The empty argument supplying macros mentioned before, look -%D like: -%D -%D \starttyping -%D \dosingleempty \command -%D \dodoubleempty \command -%D \dotripleempty \command -%D \doquadrupleempty \command -%D \doquintupleempty \command -%D \dosixtupleempty \command -%D \doseventupleempty\command -%D \stoptyping -%D -%D So \type{\dodoubleempty} leades to: -%D -%D \starttyping -%D \command[#1][#2] -%D \command[#1][] -%D \command[][] -%D \stoptyping -%D -%D Depending of the generousity of the user. Afterwards one can -%D use the \type{\if...argument} boolean. For novice: watch -%D the stepwise doubling of \type{#}'s - -% idea: \ignorespaces afterwards - -\chardef\noexpectedarguments=0 -\chardef\expectedarguments =0 - -\def\showargumenterror#1#2% - {\writestatus{systems}{\number#1 argument(s) expected in line #2}} - -\def\doshowargumenterror - {\ifnum\expectedarguments>\noexpectedarguments - \showargumenterror{\number\expectedarguments}{\number\inputlineno}% - \fi - \noshowargumenterror} - -\def\noshowargumenterror - {\let\expectedarguments\noexpectedarguments} - -\long\def\dogetargument#1#2#3#4% - {\let\charactertoken=#1% - \def\!!stringa{\noshowargumenterror#3\dodogetargument}% - \def\!!stringb{\doshowargumenterror#4\dodogetargument#1#2}% - \futurelet\nexttoken\inspectnextcharacter} - -\def\getsingleempty#1#2#3% - {\def\dodogetargument% - {#3}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getdoubleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument% - {#3#1{##1}#2}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\gettripleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getquadrupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getquintupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument#1################1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2% - #1{################1}#2}% - \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getsixtupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument#1################1#2% - {\def\dodogetargument#1################################1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2% - #1{################1}#2% - #1{################################1}#2}% - \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% - \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getseventupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument#1################1#2% - {\def\dodogetargument#1################################1#2% - {\def\dodogetargument#1################################% - ################################1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2% - #1{################1}#2% - #1{################################1}#2% - #1{################################% - ################################1}#2}% - \dogetargument#1#2\seventhargumenttrue\seventhargumentfalse}% - \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% - \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\dosingleempty {\getsingleempty []} -\def\dodoubleempty {\getdoubleempty []} -\def\dotripleempty {\gettripleempty []} -\def\doquadrupleempty {\getquadrupleempty []} -\def\doquintupleempty {\getquintupleempty []} -\def\dosixtupleempty {\getsixtupleempty []} -\def\doseventupleempty{\getseventupleempty[]} - -%D Because some of these are called quite often, we will now -%D replace the more general version by alternatives tuned for -%D speed. - -\def\dosingleempty#1% - {\noshowargumenterror % \relax % prevents lookahead, brr - \doifnextoptionalelse - {\firstargumenttrue#1} - {\dosinglefakeempty#1}} - -\def\dodoubleempty#1% - {\noshowargumenterror % \relax % prevents lookahead, brr - \doifnextoptionalelse - {\dodoubletestempty#1} - {\dodoublefakeempty#1}} - -\def\dotripleempty#1% - {\noshowargumenterror % \relax % prevents lookahead, brr - \doifnextoptionalelse - {\dotripletestempty#1} - {\dotriplefakeempty#1}} - -\def\dosinglefakeempty#1% - {\firstargumentfalse#1[]} - -\def\dodoublefakeempty#1% - {\firstargumentfalse\secondargumentfalse#1[][]} - -\def\dotriplefakeempty#1% - {\firstargumentfalse\secondargumentfalse\thirdargumentfalse#1[][][]} - -\long\def\dodoubletestempty#1[#2]% - {\firstargumenttrue - \doifnextoptionalelse - {\secondargumenttrue #1[{#2}]} - {\secondargumentfalse#1[{#2}][]}} - -\long\def\dotripletestempty#1[#2]% - {\firstargumenttrue - \doifnextoptionalelse - {\dotripletestemptyx #1[{#2}]} - {\secondargumentfalse - \thirdargumentfalse #1[{#2}][][]}} - -\long\def\dotripletestemptyx#1[#2][#3]% - {\secondargumenttrue - \doifnextoptionalelse - {\thirdargumenttrue #1[{#2}][{#3}]} - {\thirdargumentfalse#1[{#2}][{#3}][]}} - -%D \macros -%D {strippedcsname} -%D -%D The next macro can be very useful when using \type{\csname} -%D like in: -%D -%D \starttyping -%D \csname if\strippedcsname\something\endcsname -%D \stoptyping -%D -%D This expands to \type{\ifsomething}. - -\def\strippedcsname - {\expandafter\gobbleoneargument\string} - -%D \macros -%D {complexorsimple,complexorsimpleempty} -%D -%D Setups can be optional. A command expecting a setup is -%D prefixed by \type{\complex}, a command without one gets the -%D prefix \type{\simple}. Commands like this can be defined by: -%D -%D \starttyping -%D \complexorsimple\command -%D \stoptyping -%D -%D When \type{\command} is followed by a \type{[setup]}, then -%D -%D \starttyping -%D \complexcommand [setup] -%D \stoptyping -%D -%D executes, else we get -%D -%D \starttyping -%D \simplecommand -%D \stoptyping -%D -%D An alternative for \type{\complexorsimple} is: -%D -%D \starttyping -%D \complexorsimpleempty {command} -%D \stoptyping -%D -%D Depending on the presence of \type{[setup]}, this one -%D leads to one of: -%D -%D \starttyping -%D \complexcommando [setup] -%D \complexcommando [] -%D \stoptyping -%D -%D Many \CONTEXT\ commands started as complex or simple ones, -%D but changed into more versatile (more object oriented) ones -%D using the \type{\get..argument} commands. - -\def\complexorsimple#1% - {% \relax % prevents lookahead, brrr - \doifnextoptionalelse - {\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname} - {\firstargumentfalse\csname\s!simple \strippedcsname#1\endcsname}} - -\def\complexorsimpleempty#1% - {% \relax % prevents lookahead, brrr - \doifnextoptionalelse - {\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname} - {\firstargumentfalse\csname\s!complex\strippedcsname#1\endcsname[]}} - -%D \macros -%D {definecomplexorsimple,definecomplexorsimpleempty} -%D -%D The previous commands are used that often that we found it -%D worthwile to offer two more alternatives. Watch the build -%D in protection. - -\def\docomplexorsimple#1#2% - {\doifnextoptionalelse{\firstargumenttrue#1}{\firstargumentfalse#2}} - -\def\docomplexorsimpleempty#1% - {\doifnextoptionalelse{\firstargumenttrue#1}{\firstargumentfalse#1[]}} - -\def\definecomplexorsimple#1% - {\unexpanded\edef#1% - {\noexpand\docomplexorsimple - \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname - \@EA\noexpand\csname\s!simple \strippedcsname#1\endcsname}} - -\def\definecomplexorsimpleempty#1% - {\unexpanded\edef#1% - {\noexpand\docomplexorsimpleempty - \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname}} - -%D These commands are called as: -%D -%D \starttyping -%D \definecomplexorsimple\command -%D \stoptyping -%D -%D Of course, we must have available -%D -%D \starttyping -%D \def\complexcommand[#1]{...} -%D \def\simplecommand {...} -%D \stoptyping -%D -%D Using this construction saves a few string now and then. - -%D \macros -%D {dosinglegroupempty,dodoublegroupempty,dotriplegroupempty, -%D doquadruplegroupempty, doquintuplegroupempty} -%D -%D We've already seen some commands that take care of -%D optional arguments between \type{[]}. The next two commands -%D handle the ones with \type{{}}. They are called as: -%D -%D \starttyping -%D \dosinglegroupempty \ineedONEargument -%D \dodoublegroupempty \ineedTWOarguments -%D \dotriplegroupempty \ineedTHREEarguments -%D \doquadruplegroupempty \ineedFOURarguments -%D \doquintuplegroupempty \ineedFIVEarguments -%D \stoptyping - -%D We can add additional definitions later when we have defined -%D \type {\appendtoks}. - -\def \permitspacesbetweengroups{\let\@@permitspacesbetweengroups\zerocount} -\def\dontpermitspacesbetweengroups{\let\@@permitspacesbetweengroups\plusone} - -\dontpermitspacesbetweengroups - -%D We can avoid the nasty if handling in \type {syst-gen} by splitting -%D the lot in pieces so that we have no nested \type {\nextarguments} -%D potentially being an \type {conditional} token. Okay, these macros -%D are not called that often but it saves crap when tracing. - -\def\dogetgroupargument#1#2% - {\let\dogroupargumentyes#1% - \let\dogroupargumentnop#2% - \futurelet\nextargument\dodogetgroupargument} - -\def\dodogetgroupargument - {\ifx\nextargument\bgroup - \expandafter\dodogetgroupargumentA - \else - \expandafter\dodogetgroupargumentB - \fi} - -\def\dodogetgroupargumentA - {\noshowargumenterror - \dogroupargumentyes\dodogetargument} - -\def\dodogetgroupargumentB - {\ifcase\@@permitspacesbetweengroups - \expandafter\dodogetgroupargumentC - \else - \expandafter\dodogetgroupargumentD - \fi} - -\def\dodogetgroupargumentC - {\ifx\nextargument\lineending - \expandafter\dodogetgroupargumentE - \else - \expandafter\dodogetgroupargumentF - \fi} - -\def\dodogetgroupargumentD - {\doshowargumenterror - \dogroupargumentnop\dodogetargument{}} - -\def\dodogetgroupargumentE - {\begingroup\def\\ {\endgroup\dogetgroupargument\dogroupargumentyes\dogroupargumentnop}\\} - -\def\dodogetgroupargumentF - {\ifx\nextargument\blankspace - \expandafter\dodogetgroupargumentE % G - \else - \expandafter\dodogetgroupargumentD % H - \fi} - -\def\dogetgroupargument#1#2% - {\let\dogroupargumentyes#1% - \let\dogroupargumentnop#2% - \futurelet\nextargument\dodogetgroupargument} - -\def\dosinglegroupempty#1% - {\def\dodogetargument% - {\dontpermitspacesbetweengroups - #1}% - \dogetgroupargument\firstargumenttrue\firstargumentfalse} - -\def\dodoublegroupempty#1% - {\def\dodogetargument##1% - {\def\dodogetargument% - {\dontpermitspacesbetweengroups - #1{##1}}% - \dogetgroupargument\secondargumenttrue\secondargumentfalse}% - \dogetgroupargument\firstargumenttrue\firstargumentfalse} - -\def\dotriplegroupempty#1% - {\def\dodogetargument##1% - {\def\dodogetargument####1% - {\def\dodogetargument% - {\dontpermitspacesbetweengroups - #1{##1}{####1}}% - \dogetgroupargument\thirdargumenttrue\thirdargumentfalse}% - \dogetgroupargument\secondargumenttrue\secondargumentfalse}% - \dogetgroupargument\firstargumenttrue\firstargumentfalse} - -\def\doquadruplegroupempty#1% - {\def\dodogetargument##1% - {\def\dodogetargument####1% - {\def\dodogetargument########1% - {\def\dodogetargument% - {\dontpermitspacesbetweengroups - #1{##1}{####1}{########1}}% - \dogetgroupargument\fourthargumenttrue\fourthargumentfalse}% - \dogetgroupargument\thirdargumenttrue\thirdargumentfalse}% - \dogetgroupargument\secondargumenttrue\secondargumentfalse}% - \dogetgroupargument\firstargumenttrue\firstargumentfalse} - -\def\doquintuplegroupempty#1% - {\def\dodogetargument##1% - {\def\dodogetargument####1% - {\def\dodogetargument########1% - {\def\dodogetargument################1% - {\def\dodogetargument% - {\dontpermitspacesbetweengroups - #1{##1}{####1}{########1}{################1}}% - \dogetgroupargument\fifthargumenttrue\fifthargumentfalse}% - \dogetgroupargument\fourthargumenttrue\fourthargumentfalse}% - \dogetgroupargument\thirdargumenttrue\thirdargumentfalse}% - \dogetgroupargument\secondargumenttrue\secondargumentfalse}% - \dogetgroupargument\firstargumenttrue\firstargumentfalse} - -%D These macros can explictly take care of spaces, which means -%D that the next definition and calls are valid: -%D -%D \starttyping -%D \def\test#1#2#3{[#1#2#3]} -%D -%D \dotriplegroupempty\test {a}{b}{c} -%D \dotriplegroupempty\test {a}{b} -%D \dotriplegroupempty\test {a} -%D \dotriplegroupempty\test -%D \dotriplegroupempty\test {a} {b} {c} -%D \dotriplegroupempty\test {a} {b} -%D \dotriplegroupempty\test -%D {a} -%D {b} -%D \stoptyping -%D -%D And alike. - -%D \macros -%D {firstofoneargument, firstoftwoarguments, firstofthreearguments -%D secondoftwoarguments, secondofthreearguments, -%D thirdofthreearguments} -%D -%D The next six macros (dedicated to Taco) can conveniently -%D used to select arguments. Their names explain their -%D functionality. - -\long\def\firstofoneargument #1{#1} - -\long\def\firstoftwoarguments #1#2{#1} -\long\def\secondoftwoarguments #1#2{#2} - -\long\def\firstofthreearguments #1#2#3{#1} -\long\def\secondofthreearguments #1#2#3{#2} -\long\def\thirdofthreearguments #1#2#3{#3} - -\long\def\firstoffourarguments #1#2#3#4{#1} -\long\def\secondoffourarguments #1#2#3#4{#2} -\long\def\thirdoffourarguments #1#2#3#4{#3} -\long\def\fourthoffourarguments #1#2#3#4{#4} - -\long\def\firstoffivearguments #1#2#3#4#5{#1} -\long\def\secondoffivearguments #1#2#3#4#5{#2} -\long\def\thirdoffivearguments #1#2#3#4#5{#3} -\long\def\fourthoffivearguments #1#2#3#4#5{#4} -\long\def\fifthoffivearguments #1#2#3#4#5{#5} - -\long\def\firstofsixarguments #1#2#3#4#5#6{#1} -\long\def\secondofsixarguments#1#2#3#4#5#6{#2} -\long\def\thirdofsixarguments #1#2#3#4#5#6{#3} -\long\def\fourthofsixarguments#1#2#3#4#5#6{#4} -\long\def\fifthofsixarguments #1#2#3#4#5#6{#5} -\long\def\sixthofsixarguments #1#2#3#4#5#6{#6} - -%D \macros -%D {globalletempty,letempty,letvalueempty,letgvalueempty} -%D -%D Trivial: - -\def\letempty #1{\let#1\empty} -\def\globalletempty#1{\global\let#1\empty} - -\def\letvalueempty #1{\expandafter\let\csname#1\endcsname\empty} -\def\letgvalueempty#1{\global\expandafter\let\csname#1\endcsname\empty} - -%D \macros -%D {wait} -%D -%D The next macro hardly needs explanation. Because no -%D nesting is to be expected, we can reuse \type{\wait} within -%D \type{\wait} itself. - -\def\wait - {\begingroup - \read16 to \wait - \endgroup} - -%D \macros -%D {writestring,writeline,writebanner, -%D writestatus,statuswidth,normalwritestatus} -%D -%D Maybe one didn't notice, but we've already introduced a -%D macro for showing messages. In the multi||lingual modules, -%D we will also introduce a mechanism for message passing. For -%D the moment we stick to the core macros: -%D -%D \starttyping -%D \writestring {string} -%D \writeline -%D \writestatus {category} {message} -%D \stoptyping -%D -%D Messages are formatted. One can provide the maximum with -%D of the identification string with the macro \type -%D {\statuswidth}. - -\chardef\statuswidth=15 -\chardef\statuswrite=16 - -\ifdefined\writestring \else - - \newtoks\everywritestring - - \def\writedirect {\immediate\write\statuswrite} - \def\writeline {\writedirect{}} - \def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup} - -\fi - -\def\normalwritestatus#1#2% - {\writestring{\expandafter\dosplitstatus\expandafter\statuswidth#1% - \space\space\space\space\space\space\space - \space\space\space\space\space\space\space - \space\space\space\space\space\space\end - \space:\space#2}} - -\def\dosplitstatus#1#2% - {\ifcase#1 \expandafter\nosplitstatus\fi#2% - \expandafter\dosplitstatus\expandafter{\the\numexpr#1+\minusone\relax}} - -\def\nosplitstatus#1\end - {} - -%D \macros -%D {debuggerinfo} -%D -%D For debugging purposes we can enhance macros with the -%D next alternative. Here \type{debuggerinfo} stands for both -%D a macro accepting two arguments and a boolean (in fact a -%D few macro's too). - -\newif\ifdebuggerinfo - -\def\debuggerinfo#1#2% - {\ifdebuggerinfo - \writestatus{debugger}{#1:: #2}% - \fi} - -\ifdefined\writestatus \else \let\writestatus\normalwritestatus \fi -\ifdefined\writebanner \else \def\writebanner{\writestring} \fi - -% % % % % % % % % % % % % % % % % % % % % % % % - -%D \macros -%D {rawgetparameters} -%D -%D A raw and dirty alternative for \type {\getparameters}; no -%D checking is done! - -\def\rawsetparameter#1=#2,% - {\if]#1\else - \expandafter\def\csname\rawparameterprefix#1\endcsname{#2}% - \expandafter\rawsetparameter - \fi} - -\def\rawgetparameters[#1][#2% some 5-10% faster - {\ifx#2]% test is needed, else bomb on [#1][] - \expandafter\gobbleoneargument - \else - \def\rawparameterprefix{#1}% - \expandafter\dorawgetparameters - \fi#2} - -\def\dorawgetparameters#1]% - {\expandafter\rawsetparameter#1,]=,} - -%D \macros -%D {doglobal, -%D redoglobal,dodoglobal,resetglobal} -%D -%D The two macros \type {\redoglobal} and \type{\dodoglobal} are -%D used in this and some other modules to enforce a user -%D specified \type {\doglobal} action. The last and often only -%D global assignment in a macro is done with -%D \type {\dodoglobal}, but all preceding ones with -%D \type {\redoglobal}. When using only alternatives, one can -%D reset this mechanism with \type {\resetglobal}. - -\def\resetglobal - {\let\redoglobal\relax - \let\dodoglobal\relax} - -\resetglobal - -\def\doglobal - {\ifx\redoglobal\relax - \let\redoglobal\global - \let\dodoglobal\@@dodoglobal - \fi} - -\def\@@dodoglobal - {\resetglobal\global} - -\def\saveglobal - {\let\@@dodoglobal\dodoglobal - \let\@@redoglobal\redoglobal} - -\def\restoreglobal - {\let\redoglobal\@@redoglobal - \let\dodoglobal\@@dodoglobal} - -%D A very useful application of this macro is \type {\newif}, -%D \TEX's fake boolean type. Not being a primitive, -%D \type {\global} hopelessly fails here. But a slight -%D adaption of Knuth's original macro permits: -%D -%D \starttyping -%D \doglobal\newif\iftest -%D \stoptyping -%D -%D Of course one can still say: -%D -%D \starttyping -%D \global\testtrue -%D \global\testfalse -%D \stoptyping -%D -%D Apart from the prefixes, a few more \type{\expandafters} -%D are needed: - -\def\newif#1% - {\scratchcounter\escapechar - \escapechar\minusone - \expandafter\expandafter\expandafter - \redoglobal\expandafter\expandafter\expandafter - \edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}% - \expandafter\expandafter\expandafter - \redoglobal\expandafter\expandafter\expandafter - \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}% - \dodoglobal\@if#1{false}% - \escapechar\scratchcounter} - -%D Also new: - -\def\define#1% - {\ifdefined#1% - \message{[\noexpand#1is already defined]}% - \expandafter\def\expandafter\gobbleddefinition - \else - \expandafter\def - \fi#1} - -\def\redefine#1% - {\ifdefined#1% - \message{[\noexpand#1is redefined]}% - \fi - \def#1} - -% \define\hans{hans} -% \redefine\hans{hans} -% \define\hans#1[]#2#3{hans} - -%D The next variant fits nicely in the setups syntax: -%D -%D \starttyping -%D \starttexdefinition bagger [#1] #2 -%D oeps -%D #1 -%D oeps -%D \stoptexdefinition -%D -%D \bagger [a] {b} -%D \stoptyping - -\bgroup \obeylines - -\gdef\starttexdefinition% - {\bgroup% - \obeylines% - \dostarttexdefinition} - -\gdef\dostarttexdefinition #1 #2 - {\catcode13=\@@ignore% - \dodostarttexdefinition{#1}{#2}}% - -\long\gdef\dodostarttexdefinition#1#2#3\stoptexdefinition% - {\egroup% - \long\setvalue{#1}#2{#3}} - -\egroup - -%D \macros -%D {newcounter, -%D increment,decrement} -%D -%D Unfortunately the number of \COUNTERS\ in \TEX\ is limited, -%D but fortunately we can store numbers in a macro. We can -%D increment such pseudo \COUNTERS\ with \type{\increment}. -%D -%D \starttyping -%D \increment(\counter,20) -%D \increment(\counter,-4) -%D \increment(\counter) -%D \increment\counter -%D \stoptyping -%D -%D After this sequence of commands, the value of -%D \type{\counter} is 20, 16, 17 and~18. Of course there is -%D also the complementary command \type{\decrement}. -%D -%D Global assignments are possible too, using \type{\doglobal}: -%D -%D \starttyping -%D \doglobal\increment\counter -%D \stoptyping -%D -%D When \type{\counter} is undefined, it's value is initialized -%D at~0. It is nevertheless better to define a \COUNTER\ -%D explicitly. One reason could be that the \COUNTER\ can be -%D part of a test with \type{\ifnum} and this conditional does -%D not accept undefined macro's. The \COUNTER\ in our example -%D can for instance be defined with: -%D -%D \starttyping -%D \newcounter\counter -%D \stoptyping -%D -%D The command \type{\newcounter} must not be confused with -%D \type{\newcount}! Of course this mechanism is much slower -%D than using \TEX's \COUNTERS\ directly. In practice -%D \COUNTERS\ (and therefore our pseudo counters too) are -%D seldom the bottleneck in the processing of a text. Apart -%D from some other incompatilities we want to mention a pitfal -%D when using \type{\ifnum}. -%D -%D \starttyping -%D \ifnum\normalcounter=\pseudocounter \doif \else \doelse \fi -%D \ifnum\pseudocounter=\normalcounter \doif \else \doelse \fi -%D \stoptyping -%D -%D In the first test, \TEX\ continues it's search for the -%D second number after reading \type{\pseudocounter}, while -%D in the second test, it stops reading after having -%D encountered a real one. Tests like the first one therefore -%D can give unexpected results, for instance execution -%D of \type{\doif} even if both numbers are unequal. - -\def\zerocountervalue{0} - -\def\newcounter#1% - {\dodoglobal\let#1\zerocountervalue} - -%D Nowadays we don't mind a few more tokens if we can gain a -%D bit of speed. - -\def\doincrement#1% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\plusone \relax}} -\def\dodecrement#1% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\minusone\relax}} - -\def\dododoincrement#1,#2)% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+#2\relax}} -\def\dodododecrement#1,#2)% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi-#2\relax}} - -\def\dodoincrement(#1% - {\doifnextcharelse,{\dododoincrement#1}{\dododoincrement#1,\plusone}} -\def\dododecrement(#1% - {\doifnextcharelse,{\dodododecrement#1}{\dodododecrement#1,\plusone}} - -\def\fastincrement#1{\dodoglobal\edef#1{\the\numexpr#1+\plusone \relax}} -\def\fastdecrement#1{\dodoglobal\edef#1{\the\numexpr#1+\minusone\relax}} - -\def\increment{\doifnextcharelse(\dodoincrement\doincrement} -\def\decrement{\doifnextcharelse(\dododecrement\dodecrement} - -\def\incrementvalue#1{\expandafter\increment\csname#1\endcsname} -\def\decrementvalue#1{\expandafter\decrement\csname#1\endcsname} - -%D \macros -%D {newsignal} -%D -%D When writing advanced macros, we cannot do without -%D signaling. A signal is a small (invisible) kern or penalty -%D that signals the next macro that something just happened. -%D This macro can take any action depending on the previous -%D signal. Signals must be unique and the next macro takes care -%D of that. -%D -%D \starttyping -%D \newsignal\somesignal -%D \stoptyping -%D -%D Signals old dimensions and can be used in skips, kerns and -%D tests like \type{\ifdim}. - -\newdimen\maximumsignal % step is about 0.00025pt - -\def\newsignal#1% - {\ifdefined#1\else - \advance\maximumsignal 2sp % to be save in rounding - \edef#1{\the\maximumsignal}% - \fi} - -\let\newskimen\newdimen % it's all etex or later now - -%D \macros -%D {strippedcsname} -%D -%D The next macro can be very useful when using \type{\csname} -%D like in: -%D -%D \starttyping -%D \csname if\strippedcsname\something\endcsname -%D \stoptyping - -\ifdefined\letterbackslash \else - {\catcode`.=0 .catcode`.\ 12 .xdef.letterbackslash{.string\}} % hack -\fi - -\def\strippedcsname#1% this permits \strippedcsname{\xxx} and \strippedcsname{xxx} - {\expandafter\dostrippedcsname\string#1} - -\def\dostrippedcsname#1% - {\if\noexpand#1\letterbackslash\else#1\fi} - -%D \macros -%D {savenormalmeaning} -%D -%D We will use this one in: - -\def\savenormalmeaning#1% - {\ifcsname normal\strippedcsname#1\endcsname \else - \letvalue{normal\strippedcsname#1}#1% - \fi} - -%D \macros -%D {newconditional, -%D settrue, setfalse, -%D ifconditional} -%D -%D \TEX's lacks boolean variables, although the \PLAIN\ format -%D implements \type{\newif}. The main disadvantage of this -%D scheme is that it takes three hash table entries. A more -%D memory saving alternative is presented here. A conditional -%D is defined by: -%D -%D \starttyping -%D \newconditional\doublesided -%D \setfalse -%D \stoptyping -%D Setting a conditional is done by \type{\settrue} and -%D \type{\setfalse}: -%D -%D \starttyping -%D \settrue\doublesided -%D \setfalse -%D \stoptyping -%D while testing is accomplished by: -%D -%D \starttyping -%D \ifconditional\doublesided ... \else ... \fi -%D \setfalse -%D \stoptyping -%D We cannot use the simple scheme: -%D -%D \starttyping -%D \def\settrue#1{\let#1=\iftrue} -%D \def\settrue#1{\let#1=\iffalse} -%D \stoptyping -%D -%D Such an implementation gives problems with nested -%D conditionals. The next implementation is abaou as fast -%D and just as straightforward: - -% \def\settrue #1{\chardef#1\zerocount} -% \def\setfalse#1{\chardef#1\plusone} - -\def\settrue #1{\let#1\zerocount} -\def\setfalse#1{\let#1\plusone} - -\let\newconditional = \setfalse -\let\ifconditional = \ifcase - -%D \macros -%D {ifzeropt} -%D -%D The next macro is both cosmetic and byte saving. It is -%D pretty \type{\if}||safe too. It can be used in cases -%D like: -%D -%D \starttyping -%D \ifzeropt \somedimen ... \else ... \fi -%D \stoptyping - -\let\ifzeropt\ifcase - -%D \macros -%D {dorecurse,recurselevel,recursedepth, -%D dostepwiserecurse, -%D for} -%D -%D \TEX\ does not offer us powerfull for||loop mechanisms. On -%D the other hand its recursion engine is quite unique. We -%D therefore identify the for||looping macros by this method. -%D The most simple alternative is the one that only needs a -%D number. -%D -%D \starttyping -%D \dorecurse {n} {whatever we want} -%D \stoptyping -%D -%D This macro can be nested without problems and therefore be -%D used in situations where \PLAIN\ \TEX's \type{\loop} macro -%D ungracefully fails. The current value of the counter is -%D available in \type{\recurselevel}, before as well as after -%D the \typ{whatever we wat} stuff. -%D -%D \starttyping -%D \dorecurse % inner loop -%D {10} -%D {\recurselevel: % outer value -%D \dorecurse % inner loop -%D {\recurselevel} % outer value -%D {\recurselevel} % inner value -%D \dorecurse % inner loop -%D {\recurselevel} % outer value -%D {\recurselevel} % inner value -%D \endgraf} -%D \stoptyping -%D -%D In this example the first, second and fourth -%D \type{\recurselevel} concern the outer loop, while the third -%D and fifth one concern the inner loop. The depth of the -%D nesting is available for inspection in \type{\recursedepth}. -%D -%D Both \type{\recurselevel} and \type{\recursedepth} are -%D macros. The real \COUNTERS\ are hidden from the user because -%D we don't want any interference. - -\newcount\outerrecurse -\newcount\innerrecurse - -\def\recursedepth{\the\outerrecurse} -\def\recurselevel{0} - -\let\nextrecurse\relax - -\def\@@irecurse{@@ir@@} % ecurse} % stepper -\def\@@arecurse{@@ar@@} % ecurse} % action - -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \ifnum#3>0\relax - \ifnum#2<#1\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwiserecurse - \fi - \else - \ifnum#3<0\relax - \ifnum#1<#2\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwisereverse - \fi - \else - \let\nextrecurse\exitstepwiserecurse - \fi - \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} - -\long\def\dodostepwiserecurse#1#2#3% from to step - {\ifnum#1>#2\relax - \@EA\nodostepwiserecurse - \else - \def\recurselevel{#1}% - \@EAEAEA\redostepwiserecurse\@EA - \fi\@EA{\the\numexpr\recurselevel+#3\relax}{#2}{#3}} - -\def\expandrecursecontent - {\csname\@@arecurse\recursedepth\endcsname} - -\def\redostepwiserecurse - {\expandrecursecontent\dodostepwiserecurse} - -\long\def\dodostepwisereverse#1#2#3% from to step - {\ifnum#1<#2\relax - \@EA\nodostepwiserecurse - \else - \def\recurselevel{#1}% - \@EAEAEA\redostepwisereverse\@EA - \fi\@EA{\the\numexpr\recurselevel#3\relax}{#2}{#3}} - -\long\def\dodostepwisereverse#1#2#3% from to step - {\ifnum#1<#2\relax - \@EA\nodostepwiserecurse - \else - \def\recurselevel{#1}% - \innerrecurse#1\relax - \advance\innerrecurse#3\relax - \@EAEAEA\redostepwisereverse\@EA - \fi\@EA{\the\innerrecurse}{#2}{#3}} - -\def\redostepwisereverse - {\expandrecursecontent\dodostepwisereverse} - -\def\exitstepwiserecurse - {\nodostepwiserecurse\relax} - -\def\nodostepwiserecurse#1#2#3#4% - {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname - \global\advance\outerrecurse \minusone} - -\def\nonostepwiserecurse#1#2#3% - {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname - \global\advance\outerrecurse \minusone} - -\def\dorecurse#1% - {\dostepwiserecurse1{#1}1} - -%D As we can see here, the simple command \type{\dorecurse} is -%D a special case of the more general: -%D -%D \starttyping -%D \dostepwiserecurse {from} {to} {step} {action} -%D \stoptyping -%D -%D This commands accepts positive and negative steps. Illegal -%D values are handles as good as possible and the macro accepts -%D numbers and \COUNTERS. -%D -%D \starttyping -%D \dostepwiserecurse {1} {10} {2} {...} -%D \dostepwiserecurse {10} {1} {-2} {...} -%D \stoptyping -%D -%D Because the simple case is used often, we implement it -%D more efficiently: - -\long\def\dorecurse#1% - {\ifcase#1\relax - \expandafter\gobbletwoarguments - \or - \expandafter\ydorecurse - \else - \expandafter\xdorecurse - \fi{#1}} - -\long\def\xdorecurse#1#2% - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#2}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \@EA\dodorecurse\@EA1\@EA{\number#1}} - -\long\def\ydorecurse#1#2% - {\global\advance\outerrecurse \plusone - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \let\recurselevel\!!plusone - #2% - \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname - \global\advance\outerrecurse \minusone} - -\long\def\dodorecurse#1#2% from to - {\ifnum#1>#2\relax - \@EA\nodorecurse - \else - \def\recurselevel{#1}% - \@EAEAEA\redorecurse - \fi\@EA{\the\numexpr\recurselevel+\plusone\relax}{#2}} - -\long\def\dodorecurse#1#2% from to - {\ifnum#1>#2\relax - \@EA\nodorecurse - \else - \def\recurselevel{#1}% - \innerrecurse#1\advance\innerrecurse\plusone - \@EAEAEA\redorecurse - \fi\@EA{\the\innerrecurse}{#2}} - -\def\redorecurse - {\expandrecursecontent\dodorecurse} - -\def\nodorecurse#1#2#3% - {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname - \global\advance\outerrecurse \minusone } - -%D \macros -%D {doloop,exitloop} -%D -%D Sometimes loops are not determined by counters, but by -%D (a combinations of) conditions. We therefore implement a -%D straightforward loop, which can only be left when we -%D explictly exit it. Nesting is supported. First we present -%D a more extensive alternative. -%D -%D \starttyping -%D \doloop -%D {Some kind of typesetting punishment \par -%D \ifnum\pageno>100 \exitloop \fi} -%D \stoptyping -%D -%D When needed, one can call for \type{\looplevel} and -%D \type{\loopdepth}. - -\let\endofloop\donothing - -\long\def\doloop#1% - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#1}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \let\endofloop\dodoloop - \dodoloop1} % no \plusone else \recurselevel wrong - -\long\def\dodoloop#1% - {\def\recurselevel{#1}% - \@EA\redoloop\@EA{\the\numexpr\recurselevel+\plusone\relax}} - -\def\redoloop - {\expandrecursecontent\endofloop} - -\def\nodoloop#1% - {\let\endofloop\dodoloop % new, permits nested \doloop's - \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname - \global\advance\outerrecurse\minusone} - -\def\exitloop % \exitloop quits at end - {\let\endofloop\nodoloop} - -\long\def\exitloopnow#1\endofloop % \exitloopnow quits directly - {\nodoloop} - -%D The loop is executed at least once, so beware of situations -%D like: -%D -%D \starttyping -%D \doloop {\exitloop some commands} -%D \stoptyping -%D -%D It's just a matter of putting the text into the \type{\if} -%D statement that should be there anyway, like in: -%D -%D \starttyping -%D \doloop {\ifwhatever \exitloop \else some commands\fi} -%D \stoptyping -%D -%D You can also quit a loop immediately, by using \type -%D {\exitloopnow} instead. Beware, this is more sensitive -%D for conditional errors. - -%D Krzysztof Leszczynski suggested to provide access to the level by -%D means of a \type {#1}. I decided to pass the more frquently used -%D level as \type {#1} and the less favoured depth as \type {#2}. The -%D intended usage is: -%D -%D \starttyping -%D \dorecurse{3}{\definesymbol[test-#1][xx-#1]} -%D -%D \def\test{\dorecurse{3}{\definesymbol[test-##1][xx-##1]}} \test -%D -%D \symbol[test-1]\quad\symbol[test-2]\quad\symbol[test-3] -%D \stoptyping -%D -%D Since the hashed arguments are expanded, we don't need tricky -%D expansion here. -%D -%D \starttyping -%D \dorecurse{3}{\expanded{\definesymbol[test-\recurselevel][xx-\recurselevel]}} -%D \stoptyping - -\def\expandrecursecontent - {\csname\@@arecurse\recursedepth\@EA\@EA\@EA\endcsname\@EA\@EA\@EA{\@EA\recurselevel\@EA}\@EA{\recursedepth}} - -\long\def\xdorecurse#1#2% - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \@EA\dodorecurse\@EA1\@EA{\number#1}} - -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \ifnum#3>0\relax - \ifnum#2<#1\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwiserecurse - \fi - \else - \ifnum#3<0\relax - \ifnum#1<#2\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwisereverse - \fi - \else - \let\nextrecurse\exitstepwiserecurse - \fi - \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} - -\long\def\doloop#1% - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \let\endofloop\dodoloop - \dodoloop1} % no \plusone else \recurselevel wrong - -% EXPERIMENT - -% faster - -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \ifnum#3>\zerocount - \ifnum#2<#1\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwiserecurse - \fi - \else - \ifnum#3<\zerocount - \ifnum#1<#2\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwisereverse - \fi - \else - \let\nextrecurse\exitstepwiserecurse - \fi - \fi - \expandafter\nextrecurse\normalexpanded{{\number#1}{\number#2}{\number#3}}} - -% slightly faster - -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \csname @swr% - \ifnum#3>\zerocount - \ifnum#2<#1\else d\fi - \else\ifnum#3<\zerocount - \ifnum#1<#2\else r\fi - \fi\fi - \expandafter\endcsname\normalexpanded{{\number#1}{\number#2}{\number#3}}} - -\let\@swr \exitstepwiserecurse -\let\@swrd\dodostepwiserecurse -\let\@swrr\dodostepwisereverse - -%D For special purposes: - -\newcount\fastrecursecounter -\newcount\lastrecursecounter -\newcount\steprecursecounter - -\def\dofastrecurse#1#2#3#4% - {\def\fastrecursebody{#4}% - \fastrecursecounter#1\relax - \lastrecursecounter#2\relax - \steprecursecounter#3\relax - \def\recurselevel{\number\fastrecursecounter}% - \dodofastrecurse} - -\def\dodofastrecurse - {\ifnum\fastrecursecounter>\lastrecursecounter\else - \fastrecursebody - \advance\fastrecursecounter\steprecursecounter - \expandafter\dodofastrecurse - \fi} - -%D This alternative looks a bit different and uses a -%D pseudo counter. When this macro is nested, we have to use -%D different counters. This time we use keywords. -%D -%D \starttyping -%D \def\alfa{2} \def\beta{100} \def\gamma{3} -%D -%D \for \n=55 \to 100 \step 1 \do {... \n ...} -%D \for \n=\alfa \to \beta \step \gamma \do {... \n ...} -%D \for \n=\n \to 120 \step 1 \do {... \n ...} -%D \for \n=120 \to 100 \step -3 \do {... \n ...} -%D \for \n=55 \to 100 \step 2 \do {... \n ...} -%D \stoptyping -%D -%D Only in the third example we need to predefine \type{\n}. -%D The use of \type{\od} as a dilimiter would have made nested -%D use more problematic. - -%D Don't use this one, it's kind of obsolete. - -\def\for#1=#2\to#3\step#4\do#5% - {\dostepwiserecurse{#2}{#3}{#4} - {\let#1\recurselevel#5\let#1\recurselevel}} - -%D \macros -%D {newevery,everyline,EveryLine,EveryPar} -%D -%D Lets skip to something quite different. It's common use -%D to use \type {\everypar} for special purposes. In \CONTEXT\ -%D we use this primitive for locating sidefloats. This means -%D that when user assignments to \type {\everypar} can interfere -%D with those of the package. We therefore introduce -%D \type {\EveryPar}. -%D -%D The same goes for \type {\EveryLine}. Because \TEX\ offers -%D no \type {\everyline} primitive, we have to call for -%D \type {\everyline} when we are working on a line by line -%D basis. Just by calling \type {\EveryPar{}} and -%D \type {\EveryLine{}} we restore the old situation. - -% \dorecurse{2}{ -% \expanded{\everypar{before \recurselevel\space}} -% \EveryPar{x } [before \recurselevel\space x] \par -% \EveryPar{y } [before \recurselevel\space y] \par -% \EveryPar{} [before \recurselevel] \par -% \EveryPar{x } \EveryPar{y } \EveryPar{} [before \recurselevel] \par -% \EveryPar{y } \everypar{before } [before] \par -% } - -% retrofit this into mkii - -\def\dowithevery#1% - {\expandafter\removetoks\expandafter\the\csname t\strippedcsname#1\endcsname\from#1% - \expandafter\appendtoks\expandafter\the\csname t\strippedcsname#1\endcsname\to #1% - \csname t\strippedcsname#1\endcsname} - -\def\newevery#1#2% - {\newtoks#1% we test for redefinition elsewhere - \ifx#2\relax\else\ifdefined#2\else - \expandafter\newtoks\csname t\strippedcsname#1\endcsname - \def#2{\dowithevery#1}% - \fi\fi} - -%D This one permits definitions like: - -\newevery \everypar \EveryPar % we get a warning which is ok -\newevery \everyline \EveryLine - -%D and how about: - -\newevery \neverypar \NeveryPar - -%D Which we're going to use indeed! When the second argument -%D equals \type {\relax}, the first token list is created -%D unless it is already defined. - -%D Technically spoken we could have used the method we are -%D going to present in the visual debugger. First we save -%D the primitive \type{\everypar}: -%D -%D \starttyping -%D \let\normaleverypar=\everypar -%D \stoptyping -%D -%D Next we allocate a \TOKENLIST\ named \type{\everypar}, -%D which means that \type{\everypar} is no longer a primitive -%D but something like \type{\toks44}. -%D -%D \starttyping -%D \newtoks\everypar -%D \stoptyping -%D -%D Because \TEX\ now executes \type{\normaleverypar} instead -%D of \type{\everypar}, we are ready to assign some tokens to -%D this internally known and used \TOKENLIST. -%D -%D \starttyping -%D \normaleverypar={all the things the system wants to do \the\everypar} -%D \stoptyping -%D -%D Where the user can provide his own tokens to be expanded -%D every time he expects them to expand. -%D -%D \starttyping -%D \everypar={something the user wants to do} -%D \stoptyping -%D -%D We don't use this method because it undoubtly leads to -%D confusing situations, especially when other packages are -%D used, but it's this kind of tricks that make \TEX\ so -%D powerful. - -%D \macros -%D {convertargument,convertcommand,convertvalue} -%D -%D Some persistent experimenting led us to the next macro. This -%D macro converts a parameter or an expanded macro to it's -%D textual meaning. -%D -%D \starttyping -%D \convertargument ... \to \command -%D \stoptyping -%D -%D For example, -%D -%D \starttyping -%D \convertargument{one \two \three{four}}\to\ascii -%D \stoptyping -%D -%D The resulting macro \type{\ascii} can be written to a file -%D or the terminal without problems. In \CONTEXT\ we use this -%D macro for generating registers and tables of contents. -%D -%D The second conversion alternative accepts a command: -%D -%D \starttyping -%D \convertcommand\command\to\ascii -%D \stoptyping -%D -%D Both commands accept the prefix \type{\doglobal} for global -%D assignments. - -\def\convertvalue#1\to - {\expandafter\convertcommand\csname#1\endcsname\to} - -\def\defconvertedvalue#1#2% less sensitive for \to - {\@EA\defconvertedcommand\@EA#1\csname#2\endcsname} - -%D \macros -%D {doifassignmentelse} -%D -%D A lot of \CONTEXT\ commands take optional arguments, for -%D instance: -%D -%D \starttyping -%D \dothisorthat[alfa,beta] -%D \dothisorthat[first=foo,second=bar] -%D \dothisorthat[alfa,beta][first=foo,second=bar] -%D \stoptyping -%D -%D Although a combined solution is possible, we prefer a -%D seperation. The next command takes care of propper -%D handling of such multi||faced commands. -%D -%D \starttyping -%D \doifassignmentelse {...} {then ...} {else ...} -%D \stoptyping - -% \def\doifassignmentelse#1% -% {\convertargument#1\to\ascii -% \doifinstringelse=\ascii} - -% \def\doifassignmentelse#1% -% {\edef\ascii{\detokenize{#1}}% -% \ifx\ascii\empty -% \expandafter\secondoftwoarguments -% \else -% \expandafter\docheckifassignmentelse -% \fi} - -% \long\def\dodoifassignmentelse -% {\expandafter\dododoifnotassignmentelse\ascii=@@\@end@ -% \expandafter\secondoftwoarguments -% \else -% \expandafter\firstoftwoarguments -% \fi} - -\long\def\docheckifassignmentelse#1=#2#3\@end@{\if#2@}% - -\long\def\doifassignmentelse#1% - {\expandafter\docheckifassignmentelse\detokenize{#1}=@@\@end@ - \expandafter\secondoftwoarguments - \else - \expandafter\firstoftwoarguments - \fi} - -% D \macros -% D {convertasciiafter} -% D -% D Sometimes we need to convert an argument to a string (letters -% D only), for instance when we compare it with another string: -% D -% D \starttyping -% D \convertasciiafter\doifinstringelse{em}{\ascii}{...} -% D \stoptyping -% -% \def\convertasciiafter#1#2% -% {\@EA#1\@EA{\detokenize{#2}}} - -%D In \ETEX\ we can use \type {\detokenize} and gain some -%D speed, but in general far less that 1\% for \type -%D {\convertargument} and nil for \type {\convertcommand}. -%D This macro is more robust than the pure \TEX\ one, -%D something I found out when primitives like \type -%D {\jobname} were fed (or something undefined). - -\long\def\convertargument#1\to#2{\dodoglobal\edef#2{\detokenize{#1}}} -\long\def\convertcommand #1\to#2{\dodoglobal\edef#2{\@EA\detokenize\@EA{#1}}} % hm, only second is also ok - -\long\def\defconvertedargument #1#2{\edef#1{\detokenize {#2}}} -\long\def\defconvertedcommand #1#2{\edef#1{\detokenize\@EA{#2}}} -\long\def\edefconvertedargument#1#2{\edef#1{#2}% - \edef#1{\detokenize\@EA{#1}}} -\long\def\gdefconvertedargument#1#2{\xdef#1{\detokenize {#2}}} -\long\def\gdefconvertedcommand #1#2{\xdef#1{\detokenize\@EA{#2}}} -\long\def\xdefconvertedargument#1#2{\xdef#1{#2}% - \xdef#1{\detokenize\@EA{#1}}} - -%D When you try to convert a primitive command, you'll find -%D out that the \ETEX\ method fails on for instance \type -%D {\jobname} in the sense that it returns the filename -%D instead of just \type {\jobname}. So far this does not -%D give real problems. - -%D This is typically a macro that one comes to after reading -%D the \TEX book carefully. Even then, the definite solution -%D was found after rereading the \TEX book. The first -%D implementation was: -%D -%D \starttyping -%D \def\doconvertargument#1->#2\\\\{#2} -%D \stoptyping -%D -%D The \type{-}, the delimiter \type{\\\\} and the the second -%D argument are completely redundant. - -%D \macros -%D {showvalue,showargument} -%D -%D Two handy macros for testing purposes only: - -\def\showvalue#1% - {\expandafter\show\csname#1\endcsname} - -\def\showvalue#1% - {\ifcsname#1\endcsname - \expandafter\show\csname#1\endcsname - \else - \show\undefined - \fi} - -%D \macros -%D {doifmeaningelse} -%D -%D We can use both commands in testing, but alas, not all -%D meanings expand to something \type {->}. This is no problem -%D in the \ETEX\ implementation, but since we want -%D compatibility, we need: -%D -%D \starttyping -%D \doifmeaningelse {\next} {\something} {true} {false} -%D \stoptyping -%D -%D Watch the one level expansion of the second argument. - -\def\doifmeaningelse#1#2% - {\edef\!!stringa{\meaning#1}% - \def \!!stringb{#2}% - \edef\!!stringb{\meaning\!!stringb}% - \ifx\!!stringa\!!stringb - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doifsamestringselse,doifsamestring,doifnotsamestring} -%D -%D The next comparison macro converts the arguments into -%D expanded strings. This command can be used to compare for -%D instance \type {\jobname} with a name stored in a macro. -%D -%D \starttyping -%D \doifelse {\jobname}{oeps}{YES}{NO} -%D \doifsamestringelse{\jobname}{oeps}{YES}{NO} -%D \stoptyping - -% \def\@@doifsamestringelse#1#2#3#4% -% {\edef\!!stringa{#3}\convertcommand\!!stringa\to\!!stringa -% \edef\!!stringb{#4}\convertcommand\!!stringb\to\!!stringb -% \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi} - -\def\@@doifsamestringelse#1#2#3#4% - {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#3}}}% - \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#4}}}% - \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi} - -\def\doifsamestringelse{\@@doifsamestringelse\firstoftwoarguments\secondoftwoarguments} -\def\doifsamestring {\@@doifsamestringelse\firstofoneargument\gobbleoneargument} -\def\doifnotsamestring {\@@doifsamestringelse\gobbleoneargument\firstofoneargument} - -%D \macros -%D {ExpandFirstAfter,ExpandSecondAfter,ExpandBothAfter} -%D -%D These three commands support expansion of arguments before -%D executing the commands that uses them. We can best -%D illustrate this with an example. -%D -%D \starttyping -%D \def\first {alfa,beta,gamma} -%D \def\second {alfa,epsilon,zeta} -%D -%D \ExpandFirstAfter \doifcommon {\first} {alfa} {\message{OK}} -%D \ExpandSecondAfter \doifcommon {alfa} {\second} {\message{OK}} -%D \ExpandBothAfter \doifcommon {\first} {\second} {\message{OK}} -%D -%D \ExpandFirstAfter\processcommalist[\first]\message -%D -%D \ExpandAfter \doifcommon {\first} {alfa} {\message{OK}} -%D \stoptyping -%D -%D The first three calls result in the threefold message -%D \type{OK}, the fourth one shows the three elements of -%D \type{\first}. The command \type{\ExpandFirstAfter} takes -%D care of (first) arguments that are delimited by \type{[ ]}, -%D but the faster \type{\ExpandAfter} does not. - -\def\simpleExpandFirstAfter#1% - {\long\xdef\@@expanded{\noexpand\ExpandCommand{#1}}\@@expanded} - -\def\complexExpandFirstAfter[#1]% - {\long\xdef\@@expanded{\noexpand\ExpandCommand[#1]}\@@expanded} - -\def\ExpandFirstAfter#1% - {\let\ExpandCommand#1% - \doifnextoptionalelse\complexExpandFirstAfter\simpleExpandFirstAfter} - -\def\ExpandSecondAfter#1#2#3% - {\scratchtoks{#2}% - \long\xdef\@@expanded{\noexpand#1{\the\scratchtoks}{#3}}\@@expanded} - -\def\ExpandBothAfter#1#2#3% - {\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded} - -\def\ExpandAfter#1#2% - {\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded} - -%D Now we can for instance define \type{\ifinstringelse} as: - -\def\ifinstringelse - {\ExpandBothAfter\p!doifinstringelse} - -%D \macros -%D {ConvertToConstant,ConvertConstantAfter} -%D -%D When comparing arguments with a constant, we can get into -%D trouble when this argument consists of tricky expandable -%D commands. One solution for this is converting the -%D argument to a string of unexpandable characters. To make -%D comparison possible, we have to convert the constant too -%D -%D \starttyping -%D \ConvertToConstant\doifelse {...} {...} {then ...} {else ...} -%D \stoptyping -%D -%D This construction is only needed when the first argument -%D can give troubles. Misuse can slow down processing. -%D -%D \starttyping -%D \ConvertToConstant\doifelse{\c!alfa} {\c!alfa}{...}{...} -%D \ConvertToConstant\doifelse{alfa} {\c!alfa}{...}{...} -%D \ConvertToConstant\doifelse{alfa} {alfa} {...}{...} -%D \ConvertToConstant\doifelse{alfa \alfa test}{\c!alfa}{...}{...} -%D \stoptyping -%D -%D In examples~2 and~3 both arguments equal, in~1 and~4 -%D they differ. - -\long\def\ConvertToConstant#1#2#3% - {\edef\!!stringa{\expandafter\detokenize\expandafter{#2}}% - \edef\!!stringb{\expandafter\detokenize\expandafter{#3}}% - #1{\!!stringa}{\!!stringb}} - -%D When the argument \type{#1} consists of commands, we had -%D better use -%D -%D \starttyping -%D \ConvertConstantAfter\processaction[#1][...] -%D \ConvertConstantAfter\doifelse{#1}{\v!something}{}{} -%D \stoptyping -%D -%D This commands accepts things like: -%D -%D \starttyping -%D \v!constant -%D constant -%D \hbox to \hsize{\rubish} -%D \stoptyping -%D -%D As we will see in the core modules, this macro permits -%D constructions like: -%D -%D \starttyping -%D \setupfootertexts[...][...] -%D \setupfootertexts[margin][...][...] -%D \setupfootertexts[\v!margin][...][...] -%D \stoptyping -%D -%D where \type{...} can be anything legally \TEX. - -\def\CheckConstantAfter#1#2% - {\@EA\convertargument\v!prefix!\to\ascii - \convertargument#1\to#2\relax - \doifinstringelse\ascii{#2} - {\expandafter\convertargument#1\to#2} - {}} - -\def\ConvertConstantAfter#1#2#3% - {\CheckConstantAfter{#2}\asciia - \CheckConstantAfter{#3}\asciib - #1{\asciia}{\asciib}} - -%D \macros -%D {assignifempty} -%D -%D We can assign a default value to an empty macro using: -%D -%D \starttyping -%D \assignifempty \macros {default value} -%D \stoptyping -%D -%D We don't explicitly test if the macro is defined. - -\def\assignifempty#1#2% can be sped up - {\doifsomething{#1}{\def#1{#2}}} % {\doifnot{#1}{}{\def#1{#2}}} - -%D \macros -%D {gobbleuntil,grabuntil,gobbleuntilrelax, -%D processbetween,processuntil} -%D -%D In \TEX\ gobbling usually stand for skipping arguments, so -%D here are our gobbling macros. -%D -%D In \CONTEXT\ we use a lot of \type{\start}||\type{\stop} -%D like constructions. Sometimes, the \type{\stop} is used as a -%D hard coded delimiter like in: -%D -%D \starttyping -%D \def\startcommand#1\stopcommand% -%D {... #1 ...} -%D \stoptyping -%D -%D In many cases the \type{\start}||\type{\stop} pair is -%D defined at format generation time or during a job. This -%D means that we cannot hardcode the \type{\stop} criterium. -%D Only after completely understanding \type{\csname} and -%D \type{\expandafter} I was able to to implement a solution, -%D starting with: -%D -%D \starttyping -%D \grabuntil{stop}\command -%D \stoptyping -%D -%D This commands executes, after having encountered -%D \type {\stop} the command \type {\command}. This command -%D receives as argument the text preceding the \type {\stop}. -%D This means that: -%D -%D \starttyping -%D \def\starthello% -%D {\grabuntil{stophello}\message} -%D -%D \starthello Hello world!\stophello -%D \stoptyping -%D -%D results in: \type{\message{Hello world!}}. - -\def\dograbuntil#1#2% - {\long\def\next##1#1{#2{##1}}\next} - -\def\grabuntil#1% - {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}} - -%D The next command build on this mechanism: -%D -%D \starttyping -%D \processbetween{string}\command -%D \stoptyping -%D -%D Here: -%D -%D \starttyping -%D \processbetween{hello}\message -%D \starthello Hello again!\stophello -%D \stoptyping -%D -%D leads to: \type{\message{Hello again!}}. The command -%D -%D \starttyping -%D \gobbleuntil{sequence} -%D \stoptyping -%D -%D is related to these commands. This one simply throws away -%D everything preceding \type{\command}. - -\long\def\processbetween#1#2% - {\setvalue{\s!start#1}{\grabuntil{\s!stop#1}{#2}}} - -\def\gobbleuntil#1% - {\long\def\next##1#1{}\next} - -\def\gobbleuntilrelax#1\relax - {} - -%D The next one simply expands the pickup up tokens. -%D -%D \starttyping -%D \processuntil{sequence} -%D \stoptyping - -\def\processuntil#1% - {\long\def\next##1#1{##1}\next} - -%D \macros -%D {groupedcommand} -%D -%D Commands often manipulate argument as in: -%D -%D \starttyping -%D \def\doezomaarwat#1{....#1....} -%D \stoptyping -%D -%D A disadvantage of this approach is that the tokens that -%D form \type{#1} are fixed the the moment the argument is read -%D in. Normally this is no problem, but for instance verbatim -%D environments adapt the \CATCODES\ of characters and therefore -%D are not always happy with already fixed tokens. -%D -%D Another problem arises when the argument is grouped not by -%D \type{{}} but by \type{\bgroup} and \type{\egroup}. Such an -%D argument fails, because the \type{\bgroup} is een as the -%D argument (which is quite normal). -%D -%D The next macro offers a solution for both unwanted -%D situations: -%D -%D \starttyping -%D \groupedcommand {before} {after} -%D \stoptyping -%D -%D Which can be used like: -%D -%D \starttyping -%D \def\cite% -%D {\groupedcommand{\rightquote\rightquote}{\leftquote\leftquote}} -%D \stoptyping -%D -%D This command is equivalent to, but more 'robust' than: -%D -%D \starttyping -%D \def\cite#1% -%D {\rightquote\rightquote#1\leftquote\leftquote} -%D \stoptyping -%D -%D \starttyping -%D \def\rightword% -%D {\groupedcommand{\hfill\hbox}{\parfillskip\!!zeropoint}} -%D -%D .......... \rightword{the right way} -%D \stoptyping -%D -%D Here \TEX\ typesets \type{\bf the right way} unbreakable -%D at the end of the line. The solution mentioned before does -%D not work here. We also handle -%D -%D \starttyping -%D to be \bold{bold} or not, that's the question -%D \stoptyping -%D -%D and -%D -%D \starttyping -%D to be {\bold bold} or not, that's the question -%D \stoptyping -%D -%D This alternative checks for a \type{\bgroup} token first. -%D The internal alternative does not accept the box handling -%D mentioned before, but further nesting works all right. The -%D extra \type{\bgroup}||\type{\egroup} is needed to keep -%D \type{\AfterGroup} both into sight and local. - -\long\def\HandleGroup#1#2% - {\bgroup - \long\def\BeforeGroup{\bgroup#1\bgroup\aftergroup\AfterGroup}% - \long\def\AfterGroup {#2\egroup\egroup}% - \afterassignment\BeforeGroup - \let\next=} - -\long\def\HandleSimpleGroup#1#2% no inner group (so no kerning interference) - {\bgroup - %long\def\BeforeGroup{\bgroup#1\aftergroup\AfterGroup}% interferes - \long\def\BeforeGroup{\bgroup\aftergroup\AfterGroup#1}% - \long\def\AfterGroup {#2\egroup}% - \afterassignment\BeforeGroup - \let\next=} - -\long\def\HandleNoGroup#1#2% - {\long\def\AfterGroup{#2\egroup}% - \bgroup\aftergroup\AfterGroup#1} - -%D I considered it a nuisance that -%D -%D \starttyping -%D \color[green] -%D {as grass} -%D \stoptyping -%D -%D was not interpreted as one would expect. This is due to the -%D fact that \type{\futurelet} obeys blank spaces, and a -%D line||ending token is treated as a blank space. So the final -%D implementation became: - -\long\unexpanded\def\groupedcommand#1#2% - {\doifnextbgroupelse{\HandleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}} - -\long\unexpanded\def\simplegroupedcommand#1#2% - {\doifnextbgroupelse{\HandleSimpleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}} - -%D Users should be aware of the fact that grouping can -%D interfere with ones paragraph settings that are executed -%D after the paragraph is closed. One should therefore -%D explictly close the paragraph with \type{\par}, else the -%D settings will be forgotten and not applied. So it's: -%D -%D \starttyping -%D \def\BoldRaggedCenter% -%D {\groupedcommand{\raggedcenter\bf}{\par}} -%D \stoptyping - -%D \macros -%D {checkdefined} -%D -%D The bigger the system, the greater the change that -%D user defined commands collide with those that are part of -%D the system. The next macro gives a warning when a command is -%D already defined. We considered blocking the definition, but -%D this is not always what we want. -%D -%D \starttyping -%D \checkdefined {category} {class} {command} -%D \stoptyping -%D -%D The user is warned with the suggestion to use -%D \type{CAPITALS}. This suggestion is feasible, because -%D \CONTEXT only defines lowcased macros. - -\def\showdefinederror#1#2% - {\writestatus\m!systems{#1 #2 replaces a macro, use CAPITALS!}} - -\def\checkdefined#1#2#3% - {\doifdefined{#3}{\showdefinederror{#2}{#3}}} - -%D \macros -%D {GotoPar,GetPar} -%D -%D Typesetting a paragraph in a special way can be done by -%D first grabbing the contents of the paragraph and processing -%D this contents grouped. The next macro for instance typesets -%D a paragraph in boldface. -%D -%D \starttyping -%D \def\remark#1\par% -%D {\bgroup\bf#1\egroup} -%D \stoptyping -%D -%D This macro has to be called like -%D -%D \starttyping -%D \remark some text ... ending with \par -%D \stoptyping -%D -%D Instead of \type{\par} we can of course use an empty line. -%D When we started typesetting with \TEX, we already had -%D produced lots of text in plain \ASCII. In producing such -%D simple formatted texts, we adopted an open layout, and when -%D switching to \TEX, we continued this open habit. Although -%D \TEX\ permits a cramped and badly formatted source, it adds -%D to confusion and sometimes introduces errors. So we prefer: -%D -%D \starttyping -%D \remark -%D -%D some text ... ending with an empty line -%D \stoptyping -%D -%D We are going to implement a mechanism that allows such open -%D specifications. The definition of the macro handling -%D \type{\remark} becomes: -%D -%D \starttyping -%D \def\remark% -%D {\BeforePar{\bgroup\bf}% -%D \AfterPar{\egroup}% -%D \GetPar} -%D \stoptyping -%D -%D A macro like \type{\GetPar} can be defined in several -%D ways. The recent version, the fourth one in a row, -%D originally was far more complicated, but some functionality -%D has been moved to other macros. -%D -%D We start with the more simple but in some cases more -%D appropriate alternative is \type{\GotoPar}. This one leaves -%D \type{\par} unchanged and is therefore more robust. On the -%D other hand, \type{\AfterPar} is not supported. - -\newtoks\BeforePar -\newtoks\AfterPar - -\let\endoflinetoken=^^M - -\def\redowithpar\par - {\doifnextcharelse\par\redowithpar\dodowithpar}% - -\def\dowithpar#1#2% - {\def\dodowithpar##1\par{#1##1#2}% - \redowithpar\par} - -\def\redogotopar\par - {\doifnextcharelse\par\redogotopar\dodogotopar}% - -\def\dogotopar#1% - {\def\dodogotopar{#1}% - \redogotopar\par} - -\def\GetPar - {\expanded - {\dowithpar - {\the\BeforePar - \BeforePar\emptytoks} - {\the\AfterPar - \BeforePar\emptytoks - \AfterPar\emptytoks}}} - -\def\GotoPar - {\expanded - {\dogotopar - {\the\BeforePar - \BeforePar\emptytoks}}} - -%D \macros -%D {dowithpargument,dowithwargument} -%D -%D The next macros are a variation on \type{\GetPar}. When -%D macros expect an argument, it interprets a grouped sequence -%D of characters a one token. While this adds to robustness and -%D less ambiguous situations, we sometimes want to be a bit -%D more flexible, or at least want to be a bit more tolerant -%D to user input. -%D -%D We start with a commands that acts on paragraphs. This -%D command is called as: -%D -%D \starttyping -%D \dowithpargument\command -%D \dowithpargument{\command ... } -%D \stoptyping -%D -%D In \CONTEXT\ we use this one to read in the titles of -%D chapters, sections etc. The commands responsible for these -%D activities accept several alternative ways of argument -%D passing. In these examples, the \type{\par} can be omitted -%D when an empty line is present. -%D -%D \starttyping -%D \command{...} -%D \command ... \par -%D \command -%D {...} -%D \command -%D ... \par -%D \stoptyping - -\def\dowithpargument#1% - {\def\nextpar##1 \par{#1{##1}}% - \def\nextarg##1{#1{##1}}% - \doifnextbgroupelse\nextarg{\doifnextcharelse\par{#1{}}\nextpar}} - -%D The \type{p} in the previous command stands for paragraph. -%D When we want to act upon words we can use the \type{w} -%D alternative. -%D -%D \starttyping -%D \dowithwargument\command -%D \dowithwargument{... \command ...} -%D \stoptyping -%D -%D The main difference bwteen two alternatives is in the -%D handling of \type{\par}'s. This time the space token acts -%D as a delimiter. -%D -%D \starttyping -%D \command{...} -%D \command ... -%D \command -%D {...} -%D \command -%D ... -%D \stoptyping - -\def\dowithwargument#1% - {\def\nextwar##1 {#1{##1}}% - \def\nextarg##1{#1{##1}}% - \doifnextbgroupelse\nextarg\nextwar} - -%D \macros -%D {dorepeat,dorepeatwithcommand} -%D -%D When doing repetitive tasks, we stromgly advice to use -%D \type{\dorecurse}. The next alternative however, suits -%D better some of the \CONTEXT\ interface commands. -%D -%D \starttyping -%D \dorepeat[n*\command] -%D \stoptyping -%D -%D The value of the used \COUNTER\ can be called within -%D \type{\command} by \type{\repeater}. -%D -%D A slightly different alternative is: -%D -%D \starttyping -%D \dorepeatwithcommand[n*{...}]\command -%D \stoptyping -%D -%D When we call for something like: -%D -%D \starttyping -%D \dorepeatwithcommand[3*{Hello}]\message -%D \stoptyping -%D -%D we get ourselves three \type{\message{Hello}} messages in -%D a row. In both commands, the \type{n*} is optional. When this -%D specification is missing, the command executes once. - -% this one is obsolete: - -\def\dorepeat[#1]% - {\dodorepeat#1*\empty*\relax} - -\long\def\dodorepeat#1*#2#3*#4\relax - {\ifx#2\empty#1\else\dorecurse{#1}{#2#3}\fi} - -\def\repeater - {\recurselevel} - -% this one will be kept - -\def\dorepeatwithcommand[#1]% - {\dodorepeatwithcommand#1*\empty*\relax} - -\long\def\dodorepeatwithcommand#1*#2#3*#4\relax#5% - {\ifx#2\empty\redorepeatwithcommand[#1]#5\else\dododorepeatwithcommand{#1}{#2}{#3}#5\fi} - -\long\def\dododorepeatwithcommand#1#2#3#4% - {\ifx#2\empty % redundant but gives cleaner extensions - #4{#1}% - \else\ifnum#1<\zerocount - \bgroup\scratchcounter#1% - \expanded{\egroup\noexpand\dorecurse{\number-\scratchcounter}}{#4{-#2#3}}% - \else\ifx#2+% - \dorecurse{#1}{#4{#3}}% - \else - \dorecurse{#1}{#4{#2#3}}% - \fi\fi\fi} - -\def\redorepeatwithcommand[#1]#2% - {#2{#1}} - -%D The extension hook permits something like: -%D -%D \starttyping -%D \bgroup -%D -%D \catcode`\*=\@@superscript -%D -%D \gdef\redorepeatwithcommand[#1]% -%D {\redodorepeatwithcommand#1*\empty*\relax} -%D -%D \long\gdef\redodorepeatwithcommand#1*#2#3*#4\relax#5% -%D {\dododorepeatwithcommand{#1}{#2}{#3}#5} -%D -%D \egroup -%D \stoptyping -%D -%D although one may wonder if changing the catcode of \type {*} is wise. - -%D \macros -%D {normalbgroup,normalgroup} -%D -%D No comment. - -\let\normalbgroup\bgroup -\let\normalegroup\egroup - -%D \macros -%D {doifstringinstringelse} -%D -%D The next macro is meant for situations where both strings -%D are macros. This save some unneeded expansion. -%D -%D \starttyping -%D \long\def\doifstringinstringelse#1#2% -%D {\p!doifinstringelse#1#2% -%D \@EA\firstoftwoarguments -%D \else -%D \@EA\secondoftwoarguments -%D \fi} -%D \stoptyping -%D -%D A bit faster is: - -\def\pp!doifstringinstringelse#1% - {\if#1@% - \@EA\secondoftwoarguments - \else - \@EA\firstoftwoarguments - \fi} - -\long\def\doifstringinstringelse#1#2% - {\long\@EA\def\@EA\p!doifstringinstringelse\@EA##\@EA1#1##2##3\war - {\pp!doifstringinstringelse##2}% - \@EA\@EA\@EA\p!doifstringinstringelse\@EA#2#1@@\war} - -%D \macros -%D {appendtoks,prependtoks,appendtoksonce,prependtoksonce, -%D doifintokselse,flushtoks,dotoks} -%D -%D We use \TOKENLISTS\ sparsely within \CONTEXT, because the -%D comma separated lists are more suitable for the user -%D interface. Nevertheless we have: -%D -%D \starttyping -%D (\doglobal) \appendtoks ... \to\tokenlist -%D (\doglobal) \prependtoks ... \to\tokenlist -%D (\doglobal) \flushtoks\tokenlist -%D \dotoks\tokenlist -%D \stoptyping -%D -%D Er worden eerst enkele klad||registers gedefinieerd. These -%D macros are clones of the ones implemented in page~378 of -%D Knuth's \TeX book. - -\newtoks\@@scratchtoks - -\def\appendtoks {\doappendtoks \relax} -\def\prependtoks {\doprependtoks \relax} -\def\appendtoksonce {\doappendtoksonce \relax} -\def\prependtoksonce{\doprependtoksonce\relax} - -\def\dodoappendtoks - {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@toks\the\@@scratchtoks}} - -\def\dodoprependtoks - {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@scratchtoks\the\@@toks}} - -\long\def\doappendtoks#1\to#2% - {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoappendtoks} - -\long\def\doprependtoks#1\to#2% - {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoprependtoks} - -\long\def\doappendtoksonce#1\to#2% - {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}% - \doifintokselse\@@scratchtoks\@@toks\donothing\dodoappendtoks} - -\long\def\doprependtoksonce#1\to#2% - {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}% - \doifintokselse\@@scratchtoks\@@toks\donothing\dodoprependtoks} - -%D The test macro: - -\def\doifintokselse#1#2% #1 en #2 zijn toks - {\edef\asciia{\detokenize\expandafter{\the#1}}% - \edef\asciib{\detokenize\expandafter{\the#2}}% - \doifstringinstringelse\asciia\asciib} - -%D A nice one too: - -% {\scratchtoks{abc} \removetoks b\from\scratchtoks [\the\scratchtoks]} -% {\scratchtoks{abc} \removetoks x\from\scratchtoks [\the\scratchtoks]} -% {\scratchtoks{} \removetoks x\from\scratchtoks [\the\scratchtoks]} -% {\scratchtoks{xaa} \removetoks x\from\scratchtoks [\the\scratchtoks]} -% {\scratchtoks{a\relax b} \removetoks \relax\from\scratchtoks [\showthe\scratchtoks]} - -\def\removetoks#1\from#2% - {\def\doremovetoks##1#1##2\empty\empty\empty##3\\% - {\def\!!stringa{##3}% - \ifx\!!stringa\empty#2{##1}\else#2{##1##2}\fi}% - \expandafter\doremovetoks\the#2\empty\empty\empty#1\empty\empty\empty\\} - -%D Also: - -\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to} -\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to} - -%D Hm. - -\def\flushtoks#1% nb: can reassing to #1 again, hence the indirectness - {\@@scratchtoks#1\relax - \dodoglobal#1\emptytoks - \the\@@scratchtoks\relax} - -\let\dotoks\the - -%D \macros -%D {makecounter,pluscounter,minuscounter, -%D resetcounter,setcounter,countervalue} -%D -%D Declaring, setting and resetting \COUNTERS\ can be done -%D with the next set of commands. -%D -%D \starttyping -%D \makecounter {name} -%D \pluscounter {name} -%D \minuscounter {name} -%D \resetcounter {name} -%D \setcounter {name} {value} -%D \countervalue {name} -%D \stoptyping - -\def\makecounter#1% - {\global\@EA\let\csname#1\endcsname\zerocountervalue} % see earlier - -\def\countervalue#1% - {\ifcsname#1\endcsname\csname#1\endcsname\fi} - -\def\pluscounter#1% - {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname+\plusone\relax}} - -\def\minuscounter#1% - {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname-\plusone\relax}} - -\def\resetcounter#1% - {\global\@EA\let\csname#1\endcsname\zerocountervalue} - -\def\setcounter#1#2% - {\@EA\xdef\csname#1\endcsname{\the\numexpr#2\relax}} - -\def\savecounter#1% - {\@EA\xdef\csname ! #1 !\endcsname{\the\numexpr\csname#1\endcsname\relax}} - -\def\restorecounter#1% - {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname ! #1 !\endcsname\relax}} - -%D \macros -%D {beforesplitstring,aftersplitstring} -%D -%D These both commands split a string at a given point in two -%D parts, so \type{x.y} becomes \type{x} or \type{y}. -%D -%D \starttyping -%D \beforesplitstring test.tex\at.\to\filename -%D \aftersplitstring test.tex\at.\to\extension -%D \stoptyping -%D -%D The first routine looks (and is indeed) a bit simpler than -%D the second one. The alternative looking more or less like -%D the first one did not always give the results we needed. -%D Both implementations show some insight in the manipulation -%D of arguments. - -\def\beforesplitstring#1\at#2\to#3% - {\def\dosplitstring##1#2##2#2##3\\% - {\def#3{##1}}% - \@EA\dosplitstring#1#2#2\\} - -\def\aftersplitstring#1\at#2\to#3% - {\def\dosplitstring##1#2##2@@@##3\\% - {\def#3{##2}}% - \@EA\dosplitstring#1@@@#2@@@\\} - -%D \macros -%D {splitstring,greedysplitstring} -%D -%D A bonus macro. - -\def\splitstring#1\at#2\to#3\and#4% - {\def\dosplitstring##1#2##2\empty\empty\empty##3\\% - {\def#3{##1}% - \def\dosplitstring{##3}% - \ifx\dosplitstring\empty - \let#4\empty - \else - \def#4{##2}% - \fi}% - \@EA\dosplitstring#1\empty\empty\empty#2\empty\empty\empty\\} - -\def\greedysplitstring#1\at#2\to#3\and#4% - {\edef\asciib{#1}% - \let\asciic\asciib - \let#3\empty - \let#4\empty - \doloop - {\expandafter\splitstring\asciib\at#2\to\asciia\and\asciib - \ifx\asciib\empty - \exitloop - \else - % not \edef#3{\ifx#3\empty\else#3#2\fi\asciia} else - % /root/path fails because then #3==empty - \edef#3{\ifcase\recurselevel\or\else#3#2\fi\asciia}% - \let#4\asciib - \fi}% - \ifx#3\empty\let#3\asciic\fi} - -%D \macros -%D {beforetestandsplitstring, -%D aftertestandsplitstring, -%D testandsplitstring} - -\def\beforetestandsplitstring#1\at#2\to#3% - {\def\dosplitstring##1#2##2#2##3##4\\% - {\ifx##3\empty\let#3\empty\else\def#3{##1}\fi}% - \@EA\dosplitstring#1#2#2\empty\\} - -\def\aftertestandsplitstring#1\at#2\to#3% - {\def\dosplitstring ##1#2##2@@@##3##4\\% - {\ifx##3\empty\let#3\empty\else\def#3{##2}\fi}% - \@EA\dosplitstring #1@@@#2@@@\empty\\} - -\def\testandsplitstring#1\at#2\to#3\and#4% - {\def\dosplitstring##1#2##2#2##3##4\\% - {\ifx##3\empty\let#3\empty\let#4\empty\else\def#3{##1}\def#4{##2}\fi}% - \@EA\dosplitstring#1#2#2\empty\\} - -%D \macros -%D {removesubstring} -%D -%D A first application of the two routines defined above is: -%D -%D \starttyping -%D \removesubstring-\from first-last\to\nothyphenated -%D \stoptyping -%D -%D Which in terms of \TEX\ looks like: - -\def\removesubstring#1\from#2\to#3% - {\splitstring#2\to\!!stringa\and\!!stringb - \dodoglobal#3{\!!stringa\!!stringb}} - -%D \macros -%D {appendtocommalist,prependtocommalist, -%D addtocommalist,removefromcommalist} -%D -%D When working with comma separated lists, one sooner or -%D later want the tools to append or remove items from such a -%D list. When we add an item, we first check if it's already -%D there. This means that every item in the list is unique. -%D -%D \starttyping -%D \addtocommalist {alfa} \name -%D \addtocommalist {beta} \name -%D \addtocommalist {gamma} \name -%D \removefromcommalist {beta} \name -%D \stoptyping -%D -%D These commands can be prefixed with \type{\doglobal}. The -%D implementation of the second command is more complecated, -%D because we have to take leading spaces into account. Keep in -%D mind that users may provide lists with spaces after the -%D commas. When one item is left, we also have to get rid of -%D trailing spaces. -%D -%D \starttyping -%D \def\words{alfa, beta, gamma, delta} -%D \def\words{alfa,beta,gamma,delta} -%D \stoptyping -%D -%D Removing an item takes more time than adding one. -%D -%D A fast appending alternative, without any testing, is -%D also provided: -%D -%D \starttyping -%D \appendtocommalist {something} \name -%D \prependtocommalist {something} \name -%D \stoptyping -%D -%D This can be implemented as follows: -%D -%D \starttyping -%D \def\appendtocommalist#1#2% -%D {\ifx#2\empty -%D \dodoglobal\edef#2{#1}% -%D \else % no test on empty -%D \dodoglobal\edef#2{#2,#1}% -%D \fi} -%D -%D \def\prependtocommalist#1#2% -%D {\ifx#2\empty -%D \dodoglobal\edef#2{#1}% -%D \else % no test on empty -%D \dodoglobal\edef#2{#1,#2}% -%D \fi} -%D \stoptyping -%D -%D The faster alternatives are: - -\def\appendtocommalist#1#2% - {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}} - -\def\prependtocommalist#1#2% - {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}} - -\def\addtocommalist#1#2% {item} \cs - {\rawdoifinsetelse{#1}#2\resetglobal - {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}} - -\def\pretocommalist#1#2% {item} \cs - {\rawdoifinsetelse{#1}#2\resetglobal - {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}} - -\def\robustdoifinsetelse#1#2% - {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#1}}}% - \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#2}}}% - \rawdoifinsetelse\!!stringa\!!stringb} - -\def\robustaddtocommalist#1#2% {item} \cs - {\robustdoifinsetelse{#1}#2\resetglobal - {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}} - -\def\robustpretocommalist#1#2% {item} \cs - {\robustdoifinsetelse{#1}#2\resetglobal - {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}} - -\def\xsplitstring#1#2% \cs {str} - {\def\dosplitstring##1,#2,##2,#2,##3\\% - {\edef\!!stringa{\bcleanedupcommalist##1\empty\empty\relax}% - \edef\!!stringb{\acleanedupcommalist##2,,\relax}}% - \@EA\dosplitstring\@EA,#1,,#2,,#2,\\} - -\def\bcleanedupcommalist#1#2#3\relax{\if#1,\else#1\fi\if#2,\else#2\fi#3} -\def\bcleanedupcommalist#1#2\relax{\if#1,\else#1\fi#2} -\def\acleanedupcommalist#1,,#2\relax{#1} - -\def\removefromcommalist#1#2% to be sped up - {\rawdoifinsetelse{#1}#2% - {\normalexpanded{\noexpand\xsplitstring\noexpand#2{#1}}% - \dodoglobal\edef#2% - {\ifx\!!stringa\empty - \!!stringb - \else - \!!stringa\ifx\!!stringb\empty\else,\!!stringb\fi - \fi}} - \resetglobal} - -%D \macros -%D {substituteincommalist} -%D -%D Slow but seldom used, so for the moment we stick to this -%D implementation. -%D -%D \starttyping -%D \substituteincommalist{old}{new}{list} -%D \stoptyping - -\def\substituteincommalist#1#2#3% old, new, list (slooow) - {\edef\!!stringb{#1}% - \edef\!!stringd{#2}% - \let\!!stringa#3% - \let#3\empty - \def\dosubstituteincommalist##1% - {\edef\!!stringc{##1}% - \ifx\!!stringb\!!stringc - \ifx\!!stringd\empty\else - \edef#3{#3\ifx#3\empty\else,\fi\!!stringd}% - \fi - \def\docommand####1{\edef#3{#3,####1}}% - \else - \edef#3{#3\ifx#3\empty\else,\fi##1}% - \fi}% - \@EA\rawprocesscommacommand\@EA[\!!stringa]\dosubstituteincommalist} - -%D A not so useful macro: - -\def\dodofrontstrip[#1#2]#3% - {\ifx#1\space - \def#3{#2}% - \else - \def#3{#1#2}% - \fi} - -\def\dofrontstrip#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty \else - \@EA\dodofrontstrip\@EA[#1]#1% - \fi} - -%D \macros -%D {replaceincommalist} -%D -%D The next macro can be used to replace an indexed element -%D in a commalist: -%D -%D \starttyping -%D \replaceincommalist\MyList{2} -%D \stoptyping -%D -%D Element~2 will be replaced by the current meaning of the macro -%D \type {\newcommalistelement}. The old meaning is saved in -%D \type {\commalistelement}. The replacement honors grouped items, -%D like in: -%D -%D \starttyping -%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3} -%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3} -%D \def\MyList{a,{b,c},d,e,f} \replaceincommalist\MyList{3} -%D \def\MyList{a,b,c,{d,e,f}} \replaceincommalist\MyList{3} -%D \stoptyping - -\let\newcommalistelement\empty - -\def\replaceincommalist#1#2% #1 = commalistelement #2 = position starts at 1 - {\def\doreplaceincommalist##1% - {\ifnum\commalistcounter=#2\relax - \ifx\newcommalistelement\empty\else - \ifx\newcommalist\empty - \let\newcommalist\newcommalistelement - \else - \@EA\@EA\@EA\def\@EA\@EA\@EA\newcommalist\@EA\@EA\@EA - {\@EA\newcommalist\@EA,\newcommalistelement}% - \fi - \fi - \def\commalistelement{##1}% - \else - \ifx\newcommalist\empty - \ifx\nexttoken\bgroup % is known -) - \def\newcommalist{{##1}}% - \else - \def\newcommalist{##1}% - \fi - \else - \ifx\nexttoken\bgroup % is known -) - \@EA\def\@EA\newcommalist\@EA{\newcommalist,{##1}}% - \else - \@EA\def\@EA\newcommalist\@EA{\newcommalist,##1}% - \fi - \fi - \fi - \advance\commalistcounter\plusone}% - \let\commalistelement\empty - \let\newcommalist\empty - \commalistcounter\plusone - \@EA\processcommalist\@EA[#1]\doreplaceincommalist - \dodoglobal\let#1\newcommalist} - -%D \macros -%D {globalprocesscommalist} -%D -%D The commalist processing commands are characterized by the -%D fact that the way they handle expansion as well as the fact -%D that they can be nested. This makes them kind of useless for -%D handling comma lists in alignments. In these situations the -%D next macro can be of use. - -\def\globalprocesscommaitem#1,% - {\if]#1\else - \globalcommacommand{#1}% - \expandafter\globalprocesscommaitem - \fi} - -\def\globalprocesscommalist[#1]#2% - {\global\let\globalcommacommand#2% - \expandafter\globalprocesscommaitem#1,],} - -%D \macros -%D {withoutpt,PtToCm, -%D numberofpoints,dimensiontocount} -%D -%D We can convert point into centimeters with: -%D -%D \starttyping -%D \PtToCm{dimension} -%D \stoptyping - -{\catcode`\.=\@@other - \catcode`\p=\@@other - \catcode`\t=\@@other - \gdef\WITHOUTPT#1pt{#1}} - -\def\withoutpt#1% - {\expandafter\WITHOUTPT#1} - -%D The capitals are needed because \type{p} and \type{t} have -%D \CATCODE~12, while macronames only permit tokens with the -%D \CATCODE~11. As a result we cannot use the \type{.group} -%D primitives. Those who want to know more about this kind of -%D manipulations, we advice to study the \TEX book in detail. -%D Because this macro does not do any assignment, we can use it -%D in the following way too. - -\def\PtToCm#1% - {\withoutpt\the\dimexpr0.0351459804\dimexpr#1\relax\relax cm} - -%D We also support: -%D -%D \starttyping -%D \numberofpoints {dimension} -%D \dimensiontocount {dimension} {\count} -%D \stoptyping -%D -%D Both macros return a rounded number. - -% \dimensiontocount{10.49pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.49pt} -% \dimensiontocount{10.51pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.51pt} - -\def\dimensiontocount#1#2{#2\numexpr\dimexpr#1\relax/\maxcard\relax} -\def\numberofpoints #1{\the\numexpr\dimexpr#1\relax/\maxcard\relax} - -%D \macros -%D {swapdimens,swapmacros} -%D -%D Simple but effective are the next two macros. There name -%D exactly states their purpose. The \type{\scratchdimen} and -%D \type{\!!stringa} can only be swapped when being the first -%D argument. - -\def\swapdimens#1#2% - {\scratchdimen #1\redoglobal #1#2\dodoglobal #2\scratchdimen} - -\def\swapmacros#1#2% - {\let\!!stringa#1\redoglobal\let#1#2\dodoglobal\let#2\!!stringa} - -%D \macros -%D {pushmacro,popmacro} -%D -%D Premature and a bit of beta, we offer: -%D -%D \starttyping -%D \pushmacro\macro -%D \popmacro\macro -%D \stoptyping -%D -%D Beware: global! - -\def\@sl@{@sl@} -\def\@sg@{@sg@} - -\let\@@pushedmacro\empty - -\def\globalpushmacro#1% - {\xdef\@@pushedmacro{\string#1}% - \ifcsname\@sg@\@@pushedmacro\endcsname \else - \@EA\newcount\csname\@sg@\@@pushedmacro\endcsname - \fi - \global\advance\csname\@sg@\@@pushedmacro\endcsname \plusone - \global\@EA\let\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} - -\def\globalpopmacro#1% - {\xdef\@@pushedmacro{\string#1}% - \global\@EA\let\@EA#1\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname - \global\advance\csname\@sg@\@@pushedmacro\endcsname \minusone} - -\def\localpushmacro#1% this one can be used to push a value over an \egroup - {\xdef\@@pushedmacro{\string#1}% - \ifcsname\@sl@\@@pushedmacro\endcsname \else - \@EA\newcount\csname\@sl@\@@pushedmacro\endcsname - \fi - \global\advance\csname\@sl@\@@pushedmacro\endcsname \plusone - \global\@EA\let\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} - -\def\localpopmacro#1% - {\xdef\@@pushedmacro{\string#1}% - \@EA\let\@EA#1\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname - \global\advance\csname\@sl@\@@pushedmacro\endcsname \minusone } - -\let\pushmacro\localpushmacro -\let\popmacro \localpopmacro - -%D \macros -%D {setlocalhsize} -%D -%D Sometimes we need to work with the \type{\hsize} that is -%D corrected for indentation and left and right skips. The -%D corrected value is available in \type{\localhsize}, which -%D needs to be calculated with \type{\setlocalhsize} first. -%D -%D \starttyping -%D \setlocalhsize \hbox to \localhsize{...} -%D \setlocalhsize[-1em] \hbox to \localhsize{...} -%D \setlocalhsize[.5ex] \hbox to \localhsize{...} -%D \stoptyping -%D -%D These examples show us that an optional can be used. The -%D value provided is added to \type{\localhsize}. - -\newdimen\localhsize - -\def\complexsetlocalhsize[#1]% don't change ! - {\localhsize\hsize - \ifnum\hangafter<\zerocount - \advance\localhsize\ifdim\hangindent>\zeropoint-\fi\hangindent - \fi - \advance\localhsize -\leftskip - \advance\localhsize -\rightskip - \advance\localhsize #1\relax} - -\def\simplesetlocalhsize - {\complexsetlocalhsize[\zeropoint]} - -\definecomplexorsimple\setlocalhsize - -%D \macros -%D {doifvalue,doifnotvalue,doifelsevalue, -%D doifnothing,doifsomething,doifelsenothing, -%D doifvaluenothing,doifvaluesomething,doifelsevaluenothing} -%D -%D These long named \type{\if} commands can be used to access -%D macros (or variables) that are normally accessed by using -%D \type{\getvalue}. Using these alternatives safes us three -%D tokens per call. Anyone familiar with the not||values -%D ones, can derive their meaning from the definitions. - - \def\doifvalue#1{\doif {\csname#1\endcsname}} - \def\doifnotvalue#1{\doifnot {\csname#1\endcsname}} - \def\doifelsevalue#1{\doifelse{\csname#1\endcsname}} - - \def\doifnothing#1{\doif {#1}{}} - \def\doifsomething#1{\doifnot {#1}{}} - \def\doifelsenothing#1{\doifelse{#1}{}} - - \def\doifvaluenothing#1{\doif {\csname#1\endcsname}{}} - \def\doifvaluesomething#1{\doifnot {\csname#1\endcsname}{}} -\def\doifelsevaluenothing#1{\doifelse{\csname#1\endcsname}{}} - -%D Faster but spoiling inheritance (copying parameters): -%D -%D \starttyping -%D \def\doifelsevaluesomething#1#2#3% -%D {\expandafter\ifx\csname#1\endcsname\empty#3\else#2\fi} -%D -%D \def\doifvaluesomething#1#2% -%D {\expandafter\ifx\csname#1\endcsname\empty\else#2\fi} -%D -%D \def\doifvaluenothing#1#2% -%D {\expandafter\ifx\csname#1\endcsname\empty#2\fi} -%D \stoptyping -%D -%D Slightly more efficient: - - \def\doifnothing{\doif \empty} - \def\doifsomething{\doifnot \empty} -\def\doifelsenothing{\doifelse\empty} - -%D The somewhat faster alternatives are: - -\long\def\doifvalue#1#2% - {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% - \ifx\!!stringa\!!stringb - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\long\def\doifnotvalue#1#2% - {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% - \ifx\!!stringa\!!stringb - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -\long\def\doifelsevalue#1#2% - {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% - \ifx\!!stringa\!!stringb - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\long\def\doifnothing#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\long\def\doifsomething#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -\long\def\doifelsenothing#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\long\def\doifsomethingelse#1% - {\edef\!!stringa{#1}% - \ifx\!!stringa\empty - \expandafter\secondoftwoarguments - \else - \expandafter\firstoftwoarguments - \fi} - -\long\def\doifvaluenothing#1% - {\edef\!!stringa{\csname#1\endcsname}% - \ifx\!!stringa\empty - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\long\def\doifvaluesomething#1% - {\edef\!!stringa{\csname#1\endcsname}% - \ifx\!!stringa\empty - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -\long\def\doifelsevaluenothing#1% - {\edef\!!stringa{\csname#1\endcsname}% - \ifx\!!stringa\empty - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -%D \macros -%D {doifemptyelsevalue, doifemptyvalue, doifnotemptyvalue} -%D -%D Also handy: - -\def\doifemptyelsevalue#1% - {\@EA\ifx\csname#1\endcsname\empty - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\doifemptyvalue#1% - {\@EA\ifx\csname#1\endcsname\empty - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\def\doifnotemptyvalue#1% - {\@EA\ifx\csname#1\endcsname\empty - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -%D \macros -%D {doifallcommonelse} -%D -%D A complete match of two sets can be tested with -%D \type {\doifallcommonelse}, where the first two -%D arguments are sets. - -\def\@@doifallcommonelse#1#2#3#4% slow - {\def\p!docommoncheck##1% - {\doifnotinset{##1}{#4}\donefalse - \ifdone\else\expandafter\quitcommalist\fi}% - \donetrue - \processcommalist[#3]\p!docommoncheck - \ifdone\expandafter#1\else\expandafter#2\fi} - -\def\doifallcommonelse - {\@@doifallcommonelse\firstoftwoarguments\secondoftwoarguments} - -\def\doifallcommon - {\@@doifallcommonelse\firstofonearguments\gobbleoneargument} - -\def\doifnotallcommon - {\@@doifallcommonelse\gobbleoneargument\firstofonearguments} - -%D \macros -%D {DOIF,DOIFELSE,DOIFNOT} -%D -%D \TEX\ is case sensitive. When comparing arguments, this -%D feature sometimes is less desirable, for instance when we -%D compare filenames. The next three alternatives upcase their -%D arguments before comparing them. -%D -%D \starttyping -%D \DOIF {string1} {string2} {...} -%D \DOIFNOT {string1} {string2} {...} -%D \DOIFELSE {string1} {string2} {then ...}{else ...} -%D \stoptyping -%D -%D We have to use a two||step implementation, because the -%D expansion has to take place outside \type{\uppercase}. - -\def\p!DOIF#1#2% - {\uppercase{\ifinstringelse{$#1$}{$#2$}}% - \expandafter\firstofoneargument - \else - \expandafter\gobbleoneargument - \fi} - -\def\p!DOIFNOT#1#2% - {\uppercase{\ifinstringelse{$#1$}{$#2$}}% - \expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -\def\p!DOIFELSE#1#2% - {\uppercase{\ifinstringelse{$#1$}{$#2$}}% - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\p!DOIFINSTRINGELSE#1#2% - {\uppercase{\ifinstringelse{#1}{#2}}% - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\DOIF {\ExpandBothAfter\p!DOIF} -\def\DOIFNOT {\ExpandBothAfter\p!DOIFNOT} -\def\DOIFELSE {\ExpandBothAfter\p!DOIFELSE} -\def\DOIFINSTRINGELSE {\ExpandBothAfter\p!DOIFINSTRINGELSE} - -%D \macros -%D {dosingleargumentwithset, -%D dodoubleargumentwithset,dodoubleemptywithset, -%D dotripleargumentwithset,dotripleemptywithset} -%D -%D These maybe too mysterious macros enable us to handle more -%D than one setup at once. -%D -%D \starttyping -%D \dosingleargumentwithset \command[#1] -%D \dodoubleargumentwithset \command[#1][#2] -%D \dotripleargumentwithset \command[#1][#2][#3] -%D \dodoubleemptywithset \command[#1][#2] -%D \dotripleemptywithset \command[#1][#2][#3] -%D \stoptyping -%D -%D The first macro calls \type{\command[##1]} for each string -%D in the set~\type{#1}. The second one calls for -%D \type{\commando[##1][#2]} and the third, well one may guess. -%D These commands support constructions like: -%D -%D \starttyping -%D \def\dodefinesomething[#1][#2]% -%D {\getparameters[\??xx#1][#2]} -%D -%D \def\definesomething% -%D {\dodoubleargumentwithset\dodefinesomething} -%D \stoptyping -%D -%D Which accepts calls like: -%D -%D \starttyping -%D \definesomething[alfa,beta,...][variable=...,...] -%D \stoptyping -%D -%D Now a whole bunch of variables like \type{\@@xxalfavariable} -%D and \type{\@@xxbetavariable} is defined. - -\def\dodoublewithset[#1][#2]% - {\doifsomething{#1} - {\def\@@dodowithsetcommand##1{\@@dowithsetcommand[##1][#2]}% - \processcommalist[#1]\@@dodowithsetcommand}} - -\def\dotriplewithset[#1][#2][#3]% - {\doifsomething{#1} - {\def\@@dodowithsetcommand##1{\@@dowithsetcommand[##1][#2][#3]}% - \processcommalist[#1]\@@dodowithsetcommand}} - -\def\dodoubleemptywithset #1{\let\@@dowithsetcommand#1\dodoubleempty \dodoublewithset} % \command -\def\dodoubleargumentwithset#1{\let\@@dowithsetcommand#1\dodoubleargument\dodoublewithset} % \command - -\def\dotripleemptywithset #1{\let\@@dowithsetcommand#1\dotripleempty \dotriplewithset} % \command -\def\dotripleargumentwithset#1{\let\@@dowithsetcommand#1\dotripleargument\dotriplewithset} % \command - -%D \macros -%D {stripcharacters,stripspaces} -%D -%D The next command was needed first when we implemented -%D the \CONTEXT\ interactivity macros. When we use labeled -%D destinations, we often cannot use all the characters we -%D want. We therefore strip some of the troublemakers, like -%D spaces, from the labels before we write them to the -%D \DVI||file, which passes them to for instance a PostScript -%D file. -%D -%D \starttyping -%D \stripspaces\from\one\to\two -%D \stoptyping -%D -%D Both the old string \type{\one} and the new one \type{\two} -%D are expanded. This command is a special case of: -%D -%D \starttyping -%D \stripcharacter\char\from\one\to\two -%D \stoptyping -%D -%D As we can see below, spaces following a control sequence are -%D to enclosed in \type{{}}. - -\def\stripcharacter#1\from#2\to#3% - {\def\dostripcharacter##1#1##2\end - {\edef\!!strippedstring{\!!strippedstring##1}% - \doifnotempty{##2}{\dostripcharacter##2\end}}% - \let\!!strippedstring\empty - \edef\!!stringa{#2}% - \@EA\dostripcharacter\!!stringa#1\end - \dodoglobal\let#3\!!strippedstring} - -\def\stripspaces\from#1\to#2% will become \unspacestring#1\from#2 - {\stripcharacter{ }\from#1\to#2} - -%D \macros -%D {unspacestring} -%D -%D The next macro does the same but is more compatible with other macros, -%D like \type {\convert...}. - -\def\unspacestring#1\to#2% - {\stripcharacter{ }\from#1\to#2} - -%D \macros -%D {executeifdefined} -%D -%D \CONTEXT\ uses one auxiliary file for all data concerning -%D tables of contents, references, two||pass optimizations, -%D sorted lists etc. This file is loaded as many times as -%D needed. During such a pass we skip the commands thate are of -%D no use at that moment. Because we don't want to come into -%D trouble with undefined auxiliary commands, we call the -%D macros in a way similar to \type{\getvalue}. The next macro -%D take care of such executions and when not defined, gobbles -%D the unwanted arguments. -%D -%D \starttyping -%D \executeifdefined{name}\gobbleoneargument -%D \stoptyping -%D -%D We can of course gobble more arguments using the -%D appropriate gobbling command. - -\newif\ifexecuted % general purpose - -\def\executeifdefined#1% #2 / never change this one again - {\ifcsname#1\endcsname - \csname#1\expandafter\expandafter\expandafter\endcsname\expandafter\gobbleoneargument - \else - \expandafter\firstofoneargument - \fi} - -%D This one also has the advantage that it is fully -%D expandable and that it can be used after an assignment. - -%D \macros -%D {doifsomespaceelse} -%D -%D The next command checks a string on the presence of a space -%D and executed a command accordingly. -%D -%D \starttyping -%D \doifsomespaceelse {tekst} {then ...} {else ...} -%D \stoptyping -%D -%D We use this command in \CONTEXT\ for determing if an -%D argument must be broken into words when made interactive. -%D Watch the use of \type{\noexpand}. - -%D Is this one still needed? - -\def\p!doifsomespaceelse#1 #2#3\war{\if\noexpand#2@} - -\long\def\doifsomespaceelse#1% % #2#3% - {\p!doifsomespaceelse#1 @ @\war % #3\else#2\fi} - \expandafter\secondoftwoarguments - \else - \expandafter\firstoftwoarguments - \fi} - -%D \macros -%D {adaptdimension,balancedimensions} -%D -%D Again we introduce some macros that are closely related to -%D an interface aspect of \CONTEXT. The first command can be -%D used to adapt a \DIMENSION. -%D -%D \starttyping -%D \adaptdimension {dimension} {value} -%D \stoptyping -%D -%D When the value is preceed by a \type{+} or minus, the -%D dimension is advanced accordingly, otherwise it gets the -%D value. - -\def\doadaptdimension#1#2\\#3\\% - {\if#1+% - \dodoglobal\advance - \else\if#1-% - \dodoglobal\advance - \else - \dodoglobal - \fi\fi - #3 #1#2\relax} - -\def\adaptdimension#1#2% - {\expandafter\doadaptdimension#2\\#1\\} - -%D A second command takes two \DIMENSIONS. Both are adapted, -%D depending on the sign of the given value. -%D maat. This time we take the value as it is, and don't look -%D explicitly at the preceding sign. -%D -%D \starttyping -%D \balancedimensions {dimension 1} {dimension 2} {value} -%D \stoptyping -%D -%D When a positive value is given, the first dimension is -%D incremented, the second ond is decremented. A negative value -%D has the opposite result. - -\def\balancedimensions#1#2#3% - {\scratchdimen#3\relax - \redoglobal\advance#1 \scratchdimen - \dodoglobal\advance#2 -\scratchdimen} - -%D Both commands can be preceded by \type{\doglobal}. Here we -%D use \type{\redo} first, because \type{\dodo} resets the -%D global character. - -%D \macros -%D {processseparatedlist} -%D -%D Maybe a bit late, but here is a more general version of the -%D \type{\processcommalist} command. This time we don't handle -%D nesting but accept arbitrary seperators. -%D -%D \starttyping -%D \processseparatedlist[list][separator]\command -%D \stoptyping -%D -%D One can think of things like: -%D -%D \starttyping -%D \processseparatedlist[alfa+beta+gamma][+]\message -%D \stoptyping -%D -%D We want to handle all situations, like: -%D -%D \startbuffer -%D \processseparatedlist[{aap noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} -%D \processseparatedlist[{aap} {noot}][ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} -%D \processseparatedlist[aap {noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} -%D \processseparatedlist[aap noot] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii} -%D \stopbuffer -%D -%D \typebuffer \getbuffer -%D -%D Therefore we smuggle a \type {\relax} in front of the -%D argument, which we remove afterwards. - -\def\doprocessseparatedlist#1]#2[#3]#4% - {\def\dodoprocessseparatedlist##1##2#3% - {\def\!!stringa{##2}% suggested by VZ - \if]##1% - \let\dodoprocessseparatedlist\relax - \else\ifx\blankspace\!!stringa - #4{##1}% - \else\if]##2% - \let\dodoprocessseparatedlist\relax - \else - #4{##1##2}% - \fi\fi\fi - \dodoprocessseparatedlist}% - \@EA\dodoprocessseparatedlist\gobbleoneargument#1#3]#3} - -\def\processseparatedlist[% - {\doprocessseparatedlist\relax} - -%D \macros -%D {processlist} -%D -%D An even more general list processing macro is the -%D following one: -%D -%D \starttyping -%D \processlist{beginsym}{endsym}{separator}\docommand list -%D \stoptyping -%D -%D This one supports arbitrary open and close symbols as well -%D as user defined separators. -%D -%D \starttyping -%D \processlist(){=>}\docommand(a=>b=>c=>d) -%D \stoptyping - -\long\def\processlist#1#2#3#4% no blank skipping ! - {\def\doprocesslist##1#2% - {\def\dodoprocesslist####1####2#3% - {\ifx#2####1% - \let\dodoprocesslist\relax - \else\ifx#2####2% - \let\dodoprocesslist\relax - \else - #4{####1####2}% - \fi\fi - \dodoprocesslist}% - \expandafter\dodoprocesslist\gobbleoneargument##1#3#2#3}% - \def\dodoprocesslist#1% - {\doprocesslist\relax}% - \dodoprocesslist} - -%D \macros -%D {processassignlist} -%D -%D Is possible to combine an assignment list with one -%D containing keywords. Assignments are treated accordingly, -%D keywords are treated by \type{\command}. -%D -%D \starttyping -%D \processassignlist[...=...,...=...,...]\commando -%D \stoptyping -%D -%D This command can be integrated in \type{\getparameters}, but -%D we decided best not to do so. - -\def\processassignlist#1[#2]#3% - {\def\p!dodogetparameter[##1=##2=##3]% - {\doifnot{##3}\relax{#3{##1}}}% - \def\p!dogetparameter##1% - {\p!dodogetparameter[##1==\relax]}% - \processcommalist[#2]\p!dogetparameter} - -%D \macros -%D {untextargument -%D untexcommand} -%D -%D When manipulating data(bases) and for instance generating -%D index entries, the next three macros can be of help: -%D -%D \starttyping -%D \untextargument{...}\to\name -%D \untexcommand {...}\to\name -%D \stoptyping -%D -%D They remove braces and backslashes and give us something to -%D sort. - -\def\untexsomething - {\begingroup - \catcode`\{=\@@ignore - \catcode`\}=\@@ignore - \escapechar\minusone - \dountexsomething} - -\long\def\dountexsomething#1#2\to#3% - {\doglobal#1#2\to\untexedargument - \endgroup - \let#3\untexedargument} - -\def\untexargument{\untexsomething\convertargument} -\def\untexcommand {\untexsomething\convertcommand} - -%D \macros -%D {ScaledPointsToBigPoints,ScaledPointsToWholeBigPoints} -%D -%D One characteristic of \POSTSCRIPT\ and \PDF\ is that both -%D used big points (\TEX's bp). The next macros convert points -%D and scaled points into big points. -%D -%D \starttyping -%D \ScaledPointsToBigPoints {number} \target -%D \ScaledPointsToWholeBigPoints {number} \target -%D \stoptyping -%D -%D The magic factor $72/72.27$ can be found in most \TEX\ -%D related books. - -% \PointsToBigPoints{10.53940pt}\test \test -% \PointsToBigPoints{10.53941pt}\test \test -% \PointsToBigPoints{10.53942pt}\test \test - -% \PointsToWholeBigPoints{10.53940pt}\test \test -% \PointsToWholeBigPoints{10.53941pt}\test \test -% \PointsToWholeBigPoints{10.53942pt}\test \test - -\def\PointsToBigPoints#1#2% - {\edef#2{\withoutpt\the\dimexpr.996264\dimexpr#1\relax\relax}} - -\def\PointsToWholeBigPoints#1#2% - {\edef#2{\the\numexpr\dimexpr.996264\dimexpr#1\relax\relax/\maxcard\relax}} - -\def\ScaledPointsToBigPoints #1{\PointsToBigPoints {\number#1\scaledpoint}} -\def\ScaledPointsToWholeBigPoints#1{\PointsToWholeBigPoints{\number#1\scaledpoint}} - -%D \macros -%D {PointsToReal} -%D -%D Points can be stripped from their suffix by using -%D \type{\withoutpt}. The next macro enveloppes this macro. -%D -%D \starttyping -%D \PointsToReal {dimension} \target -%D \stoptyping - -\def\PointsToReal#1#2% - {\scratchdimen#1% - \edef#2{\withoutpt\the\scratchdimen}} - -%D \macros -%D {dontleavehmode} -%D -%D Sometimes when we enter a paragraph with some command, the -%D first token gets the whole first line. We can prevent this -%D by saying: -%D -%D \starttyping -%D \dontleavehmode -%D \stoptyping -%D -%D This command is used in for instance the language module -%D \type{lang-ini}. The first version was: -%D -%D \starttyping -%D \def\dontleavehmode{\ifhmode\else\ifmmode\else$ $\fi\fi} -%D \stoptyping -%D -%D Next, Taco came with a better alternative (using mathsurround): -%D -%D \starttyping -%D \def\dontleavehmode -%D {\ifhmode\else \ifmmode\else -%D {\mathsurround\zeropoint\everymath\emptytoks$ $}% -%D \fi \fi} -%D \stoptyping -%D -%D And finaly we got the following alternative, one that avoids -%D interfering grouping at the cost of a box. - -\newbox\@@dlhbox - -\unexpanded \def\dontleavehmode - {\ifhmode\else \ifmmode\else - \setbox\@@dlhbox\hbox{\mathsurround\zeropoint\everymath\emptytoks$ $}\unhbox\@@dlhbox - \fi \fi} - -%D But, if you run a recent version of \TEX, we can use the new -%D primitive: - -\ifdefined\normalquitvmode \let\dontleavehmode\normalquitvmode \fi - -%D \macros -%D {uppercasestring,lowercasestring} -%D -%D The names tell what they do: -%D -%D \starttyping -%D \uppercasestring somestring\to\somestring -%D \lowercasestring somestring\to\somestring -%D \stoptyping -%D -%D the first argument may be a \type{\macro}. - -\def\uppercasestring#1\to#2% first @EA redundant - {\uppercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}} - -\def\lowercasestring#1\to#2% first @EA redundant - {\lowercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}} - -%D \macros -%D {handletokens} -%D -%D With the next macro we enter a critical area of macro -%D expansion. What we want is a macro that looks like: -%D -%D \starttyping -%D \handletokens some tokens\with \somemacro -%D \stoptyping -%D -%D A bonus example: -%D -%D \starttyping -%D \hbox{\handletokens tekst en meer tekst\with\ruledhbox} -%D -%D \def\weetikveel#1{\if#1\blankspace\space\else\ruledhbox{#1}\fi} -%D -%D \hbox{\handletokens tekst en meer tekst\with\weetikveel} -%D \stoptyping - -%D \macros -%D {counttoken,counttokens} -%D -%D For the few occasions that we want to know the number of -%D specific tokens in a string, we can use: -%D -%D \starttyping -%D \counttoken token\in string\to \somecount -%D \counttokens string\to \somecount -%D \stoptyping -%D -%D This macro, that for instance is used in \type{cont-tab}, -%D takes a real counter. The macro can be preceded by \type -%D {\doglobal}. - -\def\counttoken#1\in#2\to#3% - {\scratchcounter\zerocount - \def\!!stringa{#1}% - \def\!!stringb{\end}% - \def\docounttoken##1% obeys {} - {\def\!!stringc{##1}% - \ifx\!!stringb\!!stringc \else - \ifx\!!stringa\!!stringc - \advance\scratchcounter\plusone - \fi - \expandafter\docounttoken - \fi}% - \docounttoken#2\end - \dodoglobal#3\scratchcounter} - -\def\counttokens#1\to#2% - {\scratchcounter\zerocount - \def\docounttoken##1{\advance\scratchcounter\plusone}% - \handletokens#1\with\docounttoken - \dodoglobal#2\scratchcounter} - -%D \macros -%D {splitofftokens} -%D -%D Running this one not always gives the expected results. -%D Consider for instance the macro for which I originally -%D wrote this token handler. - -\long\def\splitofftokens#1\from#2\to#3% slow but hardly used - {\ifnum#1>\zerocount - \scratchcounter#1\relax - \def\dosplitofftokens##1% - {\ifnum\scratchcounter>\zerocount - \advance\scratchcounter \minusone - \edef#3{#3##1}% - \fi}% - % \let#3\empty % #3 can be #2, so: - \@EA\let\@EA#3\@EA\empty - \@EA\handletokens#2\with\dosplitofftokens - \else - \edef#3{#2}% - \fi} - -%D This macro can be called like: -%D -%D \startbuffer[example] -%D \splitofftokens10\from01234567 890123456789\to\test [\test] -%D \stopbuffer -%D -%D However, the characters that we expect to find in -%D \type{\test} just don't show up there. The reason for this -%D is not that logical but follows from \TEX's sometimes -%D mysterious way of expanding. Look at this: -%D -%D \startbuffer[next] -%D \def\next{a} \edef\test{\next} [\test] -%D \let\next=b \edef\test{\test\next} [\test] -%D \let\next=c \edef\test{\next} [\test] -%D \let\next=d \edef\test{\test\next} [\test] -%D \let\next=e \@EA\edef\@EA\test\@EA{\test\next} [\test] -%D \stopbuffer -%D -%D \typebuffer[next] -%D -%D Careful reading shows that inside an \type{\edef} macro's -%D that are \type{\let} are not expanded! -%D -%D \unprotect\getbuffer[next]\protect -%D -%D That's why we finally end up with a macro that looks -%D ahead by using an assignment, this time by using \type -%D {\futurelet}, and grabbing an argument as well. That -%D way we can handle the sentinal, a blank space and grouped -%D tokens. - -\def\dohandletokens % \nexthandledtoken is part of interface - {\futurelet\nexthandledtoken\dodohandletokens} - -\long\def\handletokens#1\with#2% - {\gdef\dododohandletokens{#2}% permits more complex #2's - \dohandletokens#1\end} - -\def\dodohandletokens - {\ifx\nexthandledtoken\blankspace - \expandafter\dodohandletokensone - \else\ifx\nexthandledtoken\end - \expandafter\expandafter\expandafter\gobbletwoarguments % also gobble the \end - \else - \expandafter\expandafter\expandafter\dodohandletokenstwo - \fi\fi *} - -\def\dodohandletokensone * % - {\dododohandletokens{ }\dohandletokens} - -\long\def\dodohandletokenstwo *#1% - {\dododohandletokens{#1}\dohandletokens} - -%D This macro is tested on: -%D -%D \def\xxx#1{[#1]} -%D -%D \startlines -%D \handletokens abc\with\xxx -%D \handletokens a b c\with\xxx -%D \handletokens a b c\with\xxx -%D \handletokens a{bc}d\with\xxx -%D \handletokens a\space bc \with\xxx -%D \stoplines -%D -%D And our previous example shows up as: -%D -%D \getbuffer[example] - -%D \macros -%D {iftrialtypesetting, ifvisible} -%D -%D The next boolean is at first sight a strange one. Sometimes -%D one does a trial typesetting run, for instance to determine -%D dimensions. Some mechanisms, like object inclusion, can fail -%D on such trials. Temporary setting the next boolean to true, -%D helps a lot. The second boolena can be used to inhibit -%D processing completely. - -\newif\iftrialtypesetting \trialtypesettingfalse -\newif\ifvisible \visibletrue - -%D \macros -%D {startlocal, startglobal} -%D -%D The next four macros are rather self explaining: -%D -%D \starttyping -%D \startlocal -%D whatever assignments -%D \stoplocal -%D -%D \startglobal -%D whatever assignments -%D \stopglobal -%D \stoptyping -%D -%D These macros are meant for those who know the difference -%D between local and global assignments and are aware of the -%D possible unwanted side effect - -\def\dostartglobaldefs#1#2% - {\scratchcounter\globaldefs - \ifnum\globaldefs#1\zerocount - \globaldefs-\globaldefs - \fi - \advance\globaldefs#2\plusone - \expandafter\chardef\csname@gd@\the\globaldefs\endcsname\scratchcounter} - -\def\dostopglobaldefs - {\globaldefs\ifcsname @gd@\the\globaldefs\endcsname\zerocount} - -\def\startlocal {\dostartglobaldefs>-} -\def\stoplocal {\dostopglobaldefs} -\def\startglobal {\dostartglobaldefs<+} -\def\stopglobal {\dostopglobaldefs} - -%D \macros -%D {twodigitrounding} -%D -%D When using \type {\special}s or \type {\pdfliteral}s, it -%D sometimes makes sense to limit the precission. The next -%D macro rounds a real number to two digits. It takes one -%D argument and only works in \ETEX. - -\def\dointegerrounding #1.#2\relax {#1} -\def\doonedigitrounding #1.#2#3\relax {\ifx#2*#1\else#1.#2\fi} -\def\dotwodigitrounding #1.#2#3#4\relax {\ifx#2*#1\else#1.#2#3\fi} -\def\dothreedigitrounding#1.#2#3#4#5\relax{\ifx#2*#1\else#1.#2#3#4\fi} - -\def\integerrounding#1% - {\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.5\points \relax .\relax} -\def\onedigitrounding#1% - {\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.05\points \relax 00.*0\relax} -\def\twodigitrounding#1% - {\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.005\points \relax 000.*00\relax} -\def\threedigitrounding#1% - {\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax0000.*00\relax} - -%D \macros -%D {processcontent} -%D -%D This is the first occasion where \TEX\ and \ETEX\ are no -%D longer compatible, although in many cases things go ok. -%D Beware of verbatim, i.e. catcode changes. -%D -%D \starttyping -%D \def\starthans% -%D {\processcontent{stophans}\test{\message{\test}\wait}} -%D \stoptyping -%D -%D This macro is first used in the tabulation macros. - -\def\processcontent#1% - {\begingroup\@EA\doprocesscontent\csname#1\endcsname} - -\def\doprocesscontent#1#2#3% - {\long\def\doprocesscontent##1#1% - {\endgroup\long\def#2{##1}#3}% - \doprocesscontent} - -%D \macros -%D {dogobblesingleempty, dogobbledoubleempty} -%D -%D These two macros savely grab and dispose two arguments. - -\def\dogobblesingleempty{\dosingleempty\dodogobblesingleempty} -\def\dogobbledoubleempty{\dodoubleempty\dodogobbledoubleempty} - -\def\dodogobblesingleempty [#1]{} -\def\dodogobbledoubleempty[#1][#2]{} - -\let\gobblesingleempty\dogobblesingleempty % also used -\let\gobbledoubleempty\dogobbledoubleempty % also used - -%D \macros -%D {sortcommalist,sortcommacommand, -%D donumericcompare,comparedresult} -%D -%D Sometimes we need to sort a commalist, so here is Taco's -%D solution. This will in many cases be a list that is stored -%D in a \type{\csname}, so both commalist and commacommands are -%D supported. The sorting algorithm is very simple, so the list -%D should not be too long or sorting will be very slow. -%D -%D \starttyping -%D \sortcommalist[10,2,4,5,6,1,2,3,4,10,20]\donumericcompare -%D -%D \def\test{10,2,4,5,6,1,2,3,4,10,20} -%D -%D \sortcommacommand[\test]\donumericcompare -%D \stoptyping -%D -%D In both cases, the result is available in the macro \type -%D {\sortedcommalist}. -%D -%D Parameter \type{#2} is a macro that should accept two -%D parameters, and it has to decide which one is larger, by -%D setting the counter \type{\comparedresult} to~0 (for equal), -%D 1~(if it's first argument is larger), or~2 (if it's second -%D argument is larger). -%D -%D As said, these macro are largely written by Taco, and are -%D (maybe therefore) also the first application of \type -%D {\replaceincommalist}. - -\newcount\comparedresult - -\def\sortcommacommand[#1]% - {\@EA\sortcommalist\@EA[#1]} - -\def\sortcommalist[#1]#2% - {\getcommalistsize[#1]% - \ifnum\commalistsize>1 - \let\sortedcommalist\empty - \let\comparecommand#2% - \processcommalist[#1]\dosortcommacommand - \else - \def\sortedcommalist{#1}% - \fi} - -\def\dosortcommacommand#1% - {\ifx\sortedcommalist\empty - \def\sortedcommalist{#1}% - \else - \def\!!tempa{#1}% - \ifx\!!tempa\empty\else - \scratchcounter\plusone - \@EA\getcommalistsize\@EA[\sortedcommalist]% - \@EA\processcommalist\@EA[\sortedcommalist]\docompareitems - \fi - \fi} - -%D All those \type{\expandafter}'s are there because I do not -%D want to use \type{\edef}. - -\def\docompareitems#1% - {\doifnotempty{#1} - {\@EA\comparecommand\@EA{\!!tempa}{#1}\relax - %\ifcase\compareresult % equal - \ifnum\comparedresult<2 - \ifnum\scratchcounter=\commalistsize - \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist - \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}% - \fi - %\or % new element larger - % \ifnum\scratchcounter=\commalistsize - % \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist - % \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}% - % \fi - \else % old element larger - \@EA\def\@EA\newcommalistelement\@EA{\!!tempa,#1}% - \replaceincommalist\sortedcommalist\scratchcounter - \expandafter\quitcommalist - \fi}% - \advance\scratchcounter \plusone} % bug, was \minusone - -%D The macro \type{\donumericcompare} considers everything -%D that is not a number to be larger than any number. - -% 0: both are equal, 1: #1 is larger, 2: #2 is larger - -\def\thenumericcompare#1#2% no \relax es inside hee - {\doifnumberelse{#1} - {\doifnumberelse{#2}{\ifnum#1>#2 \plusone\else\ifnum#1<#2 \plustwo\else\zerocount\fi\fi}\plustwo} - \plusone} - -\def\donumericcompare - {\comparedresult\thenumericcompare} - -%D \macros -%D {@True, @False, @Not, @And} -%D -%D Some predicate logic functions, used in for instance the -%D math module. - -\def\@True {00} -\def\@False {01} -\def\@Not #1{0\ifcase#11 \or\@EA 1\else \@EA 0\fi} -\def\@And #1#2{0\ifcase#1#2 \@EA 0\else \@EA 1\fi} - -%D \macros -%D {setdimensionwithunit, freezedimensionwithunit} -%D -%D The next assignments are all valid: -%D -%D \starttyping -%D \setdimensionwithunit\scratchdimen{10} {cm} -%D \setdimensionwithunit\scratchdimen{10cm}{cm} -%D \setdimensionwithunit\scratchdimen{10cm}{} -%D \freezedimensionwithunit\SomeWidth{\textwidth} -%D \freezedimensionwithunit\SomeDepth{\dp\strutbox} -%D \stoptyping -%D -%D As an alternative for the next macro we can use a global -%D assignment inside a box. The \type{\empty}'s permits -%D gobbling while preventing spurious \type{\relax}'s. - -\def\setdimensionwithunit#1#2#3% number unit dimension / nice trick - {\afterassignment\gobblefourarguments#1=#2#3pt\relax\empty\empty\empty\empty} - -\def\freezedimensionwithunit#1#2% - {\setdimensionwithunit\scratchdimen#1{#2}\edef#1{\the\scratchdimen}} - -%D \macros -%D {doifsometokselse} -%D -%D Not that fast I guess, but here's a way to test for token -%D registers being empty. - -\def\doifsometokselse#1% % #2#3% - {\edef\!!stringa{\the#1}% - \ifx\!!stringa\empty % #3\else#2\fi} - \expandafter\secondoftwoarguments - \else - \expandafter\firstoftwoarguments - \fi} - -%D \macros -%D {startstrictinspectnextcharacter} -%D -%D This one if for Taco's bibliography module: - -\let\normalinspectnextcharacter\inspectnextcharacter - -\def\strictinspectnextcharacter% no user macro ! - {\ifx\nexttoken\charactertoken - \expandafter\!!stringa - \else - \expandafter\!!stringb - \fi} - -% better: push/pop - -\def\startstrictinspectnextcharacter - {\let\inspectnextcharacter\strictinspectnextcharacter} - -\def\stopstrictinspectnextcharacter - {\let\inspectnextcharacter\normalinspectnextcharacter} - -%D \macros -%D {gobblespacetokens} -%D -%D This macro needs a speed-up! - -%\def\gobblespacetokens -% {\doifnextcharelse\empty\donothing\donothing} % no {}\do\do ! - -\def\gobblespacetokens - {\afterassignment\nexttoken\let\nexttoken=} - -%D \macros -%D {verbatimargument} -%D -%D As the name says, this macro converts its argument to a -%D (rather safe) string. - -\let\verbatimstring\detokenize - -%D These are needed in ordinal number conversions: - -\def\lastdigit#1% - {\@EA\thelastdigit\number#1\relax} - -\def\thelastdigit#1#2% - {\ifx#2\relax#1\else\@EA\thelastdigit\@EA#2\fi} - -\def\lasttwodigits#1% - {\@EA\thelasttwodigits\@EA0\number#1\relax} - -\def\thelasttwodigits#1#2#3% 0 dig ... \relax - {\ifx#3\relax#1#2\else\@EA\thelasttwodigits\@EA#2\@EA#3\fi} - -%D \macros -%D {serializecommalist} -%D -%D Concatenate commalists: - -\def\serializecommalist[#1]% - {\let\serializedcommalist\empty - \def\docommand##1{\edef\serializedcommalist{\serializedcommalist##1}}% - \processcommacommand[#1]\docommand} - -%D \macros -%D {purenumber} -%D -%D Sometimes we need control over when \TEX\ stops reading a -%D number, especially in full expandable macros where using -%D \type {\relax} would lead to disasters. -%D -%D \starttyping -%D \ifodd\purenumber{...}\space ... \else ... \fi -%D \stoptyping -%D -%D Here we use a space as number delimiter in combination -%D with a space- and relax-less \type {\purenumber}. This -%D macro works ok with \type {\the}, \type {\number} as well -%D as \ETEX's \type {\numexpr}. - -\def\purenumber#1{\@EA\firstofoneargument\@EA{\number#1}} - -%D \macros -%D {filterfromvalue} -%D -%D \starttyping -%D \setvalue{xx}{{A}{B}{C}} -%D -%D \filterfromvalue{xx}{3}{3} -%D \filterfromvalue{xx}{3}{2} -%D \filterfromvalue{xx}{3}{1} -%D \stoptyping -%D -%D An alternative is to store 'max' in the list, say: -%D -%D \starttyping -%D \setvalue{xx}{3{A}{B}{C}} -%D -%D \filterfromvalues{3}{xx}{3} -%D \filterfromvalues{3}{xx}{2} -%D \filterfromvalues{3}{xx}{1} -%D \stoptyping -%D -%D I'll implement this when I'm in \quotation {writing dirty -%D macros mood}. - -\def\dofilterfromstr#1#2% max n % no need to be fast - {\expandafter \expandafter \expandafter \strippedcsname - \ifcase#1\or \ifcase#2\or - \firstofoneargument \else - \gobbleoneargument \fi - \or \ifcase#2\or - \firstoftwoarguments \or - \secondoftwoarguments \else - \gobbletwoarguments \fi - \or \ifcase#2\or - \firstofthreearguments \or - \secondofthreearguments \or - \thirdofthreearguments \else - \gobblethreearguments \fi - \or \ifcase#2\or - \firstoffourarguments \or - \secondoffourarguments \or - \thirdoffourarguments \or - \fourthoffourarguments \else - \gobblefourarguments \fi - \or \ifcase#2\or - \firstoffivearguments \or - \secondoffivearguments \or - \thirdoffivearguments \or - \fourthoffivearguments \or - \fifthoffivearguments \else - \gobblefivearguments \fi - \fi} - -\def\filterfromvalue#1#2#3% value max n - {\@EA\@EAEAEA\csname % we use the fact that an - \@EA\ifx\csname#1\endcsname\relax % undefined cs has become \relax - \strippedcsname\gobbleoneargument % which we then gobble here - \else - \dofilterfromstr{#2}{#3}% - \fi - \endcsname\csname#1\endcsname} - -\def\filterfromnext#1#2% max n {..}{..}{..}{..} - {\csname\dofilterfromstr{#1}{#2}\endcsname} - -%D \macros -%D {definemeasure} -%D -%D \starttyping -%D \definemeasure[mywidth][\dimexpr(\textwidth-1cm)] -%D -%D ... \measure{mywidth} ... -%D \stoptyping - -\def\??dm{@@dm} % brrr - -\def\definemeasure - {\dodoubleargument\dodefinemeasure} - -\def\dodefinemeasure[#1][#2]% - {\expandafter\def\csname\??dm#1\endcsname{#2}} - -% #2 could be omitted, but we want to support spaces -% -% \setmeasure {x} {1cm} -% \setmeasure {xx} {1cm} -% \setmeasure {xxx}{1cm} - -\def\setmeasure #1#2{\expandafter\def \csname\??dm#1\endcsname{#2}} % quick way -\def\setemeasure#1#2{\expandafter\edef\csname\??dm#1\endcsname{#2}} % quick way -\def\setgmeasure#1#2{\expandafter\gdef\csname\??dm#1\endcsname{#2}} % quick way -\def\setxmeasure#1#2{\expandafter\xdef\csname\??dm#1\endcsname{#2}} % quick way - -\def\measure#1% - {\ifcsname\??dm#1\endcsname\csname\??dm#1\endcsname\else\zeropoint\fi} - -%D \macros -%D {doifdimensionelse} -%D -%D This is a dirty one: we simply append a unit and discard it when needed. - -\def\doifdimensionelse#1% - {\afterassignment\dodoifdimensionelse\scratchdimen#1pt\relax} - -\def\dodoifdimensionelse#1% - {\ifx#1\relax - \expandafter\secondoftwoarguments - \else % #1=p ... t\relax - \expandafter\thirdoffourarguments - \fi} - -%D \macros -%D {comparedimension,comparedimensioneps} -%D -%D This is a dirty one: we simply append a unit and discard it when needed. - -\newdimen\roundingeps \roundingeps=10sp - -\def\comparedimension#1#2% - {\chardef\compresult - \ifdim#1<#2% - \zerocount - \else\ifdim#1<#2% - \plusone - \else - \plustwo - \fi\fi} - -\def\comparedimensioneps#1#2% todo: use eps feature - {\chardef\compresult - \ifdim\dimexpr#1-#2\relax<\roudingeps - \zerocount - \else\ifdim\dimexpr#2-#1\relax<\roudingeps - \zerocount - \else\ifdim#1<#2% - \plusone - \else - \plustwo - \fi\fi\fi} - -% % % % % % % % % % % % % % % % % % % % % % - -% pretty ugly but fast - -% \copycsname xxx\endcsname\csname ..\endcsname - -\def\copycsname{\@EA\@EA\@EA\let\@EA\@EA\csname} - -% \letcscsname \crap \csname ..\endcsname -% \letcsnamecs \csname ..\endcsname\crap -% \letcsnamecsname\csname ..\endcsname\csname ..\endcsname - -\def\letcscsname {\@EA\let\@EA} -\def\letcsnamecs {\@EA\let} -\def\letcsnamecsname{\@EA\@EA\@EA\let\@EA\@EA} - -% another one, add an item to a commalist - -\def\addvalue#1#2% cs item - {\ifcsname#1\endcsname\else\expandafter\let\csname#1\endcsname\empty\fi - \normalexpanded{\noexpand\addtocommalist{#2}\@EA\noexpand\csname#1\endcsname}} - -\def\unspaced#1% - {\dounspaced#1\end} - -\def\dounspaced#1% - {\ifx#1\end - \@EA\gobbleoneargument - \else - \ifx#1\blankspace\else#1\fi - \fi - \dounspaced} - -\def\unspaceargument#1\to#2% - {\scratchcounter\catcode32\relax - \catcode32\@@ignore\scantextokens{\edef#2{#1}}% - \catcode32\scratchcounter} - -\def\unspaceafter#1#2% - {\unspaceargument#2\to\ascii - \expandafter#1\expandafter{\ascii}} - -% sometimes handy: - -\def\doifhasspaceelse#1% - {\edef\!!stringa{#1}% - \normalexpanded{\noexpand\dodoifhasspaceelse#1\space}\empty\relax} - -\def\dodoifhasspaceelse#1 #2#3\relax % \space\empty\relax - {\ifx\!!stringa\space - \@EA\firstoftwoarguments - \else\ifx#2\empty - \@EAEAEA\secondoftwoarguments - \else - \@EAEAEA\firstoftwoarguments - \fi\fi} - -% this will replace loadfile once and alike !!! todo - -\def\@flg@{@flg@} - -\def\setflag #1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\zerocount} -\def\resetflag#1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\plusone} - -\let\ifflagged\ifcase - -\def\flag#1{\csname\@flg@#1\endcsname} - -\def\doifelseflagged#1% - {\@EA\ifx\csname\@flg@#1\endcsname\relax - \@EA\secondoftwoarguments - \else\ifcase\csname\@flg@#1\endcsname - \@EAEAEA\firstoftwoarguments - \else - \@EAEAEA\secondoftwoarguments - \fi\fi} - -\def\doifnotflagged#1% - {\@EA\ifx\csname\@flg@#1\endcsname\relax - \@EA\firstofoneargument - \else\ifcase\csname\@flg@#1\endcsname - \@EAEAEA\gobbleoneargument - \else - \@EAEAEA\firstofoneargument - \fi\fi} - -\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey % [bypasses k!prefix] - {\@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#1#5\endcsname}} - -% \buildarray[test][aa,bb,cc,dd,ee,ff] -% \setarrayelement{test}{1}{qq} -% \arrayelement{test}{1} -% \arraylength{test} -% -% \def\buildarray[#1][#2]% -% {\scratchcounter=0 -% \def\docommand##1% -% {\advance\scratchcounter by 1 -% \setvalue{@@aa#1\the\scratchcounter}{##1}}% -% \processcommalist[#2]\docommand -% \setevalue{@@aa#1}{\the\scratchcounter}}% -% -% \def\setarrayelement#1#2{\setvalue{@@aa#1#2}} -% \def\arrayelement #1#2{\getvalue{@@aa#1#2}} -% \def\arraylength #1{\getvalue{@@aa#1}} - -% \newsignal\junksignal -% -% \def\setjunksignal% -% {\ifhmode -% \hskip\junksignal -% \let\removejunkspaces\doremovejunkspaces -% \else -% \let\removejunkspaces\relax -% \fi} -% -% \def\doremovejunkspaces% -% {\doloop{\ifdim\lastskip=\junksignal\unskip\else\exitloop\fi}} - -\def\dodoifnonzeropositiveelse#1#2\end % #3#4% - {\ifx#1\relax - \ifcase\scratchcounter - \endgroup - \@EAEAEA\secondoftwoarguments - \else - \endgroup - \@EAEAEA\firstoftwoarguments - \fi - \else - \endgroup - \@EA\secondoftwoarguments - \fi} - -\def\doifnonzeropositiveelse#1% - {\begingroup\afterassignment\dodoifnonzeropositiveelse\scratchcounter=0#1\relax\empty\end} - -% here ? - -\def\dosetrawvalue #1#2#3{\@EA \def\csname#1#2\endcsname{#3}} -\def\dosetrawevalue#1#2#3{\@EA\edef\csname#1#2\endcsname{#3}} -\def\dosetrawgvalue#1#2#3{\@EA\gdef\csname#1#2\endcsname{#3}} -\def\dosetrawxvalue#1#2#3{\@EA\xdef\csname#1#2\endcsname{#3}} - -\def\getrawparameters {\dogetparameters\dosetrawvalue } -\def\getraweparameters {\dogetparameters\dosetrawevalue} -\def\getrawgparameters {\dogetparameters\dosetrawgvalue} -\def\getrawxparameters {\dogetparameters\dosetrawxvalue} - -\def\globalgetrawparameters{\dogetparameters\dosetrawgvalue} % obsolete - -\def\splitskip#1% - {\scratchskip#1\relax - \dimen0\scratchskip - \dimen2\gluestretch\scratchskip - \dimen4\glueshrink\scratchskip} - -\newcount\modcounter - -\def\dosetmodulo#1#2#3% - {\modcounter#1\divide\modcounter#2\multiply\modcounter#2% - #3#1\advance#3-\modcounter} - -\def\dosetdivision#1#2#3% - {#3#1\divide#3 #2\relax} - -\def\DoMod#1by#2to#3{\dosetmodulo {#1}{#2}{#3}} -\def\DoDiv#1by#2to#3{\dosetdivision{#1}{#2}{#3}} - -\def\dounprotected#1\par - {#1\protect} - -\def\unprotected - {\unprotect\dounprotected} - -% awaiting the definitive implementation - -\ifdefined\resettimer \else - \let\resettimer \relax - \newcount\elapsedtime -\fi - -\newcount\featuretest - -\def\testfeature#1#2% - {\def\dotestfeature - {\advance\featuretest \plusone - \ifnum\featuretest>#1\else#2\expandafter\dotestfeature\fi}% - \retestfeature} - -\def\retestfeature % timer support is new per 10/5/2005 - {\bgroup - \ifcase\interactionmode\let\wait\relax\fi - \writestatus\m!systems{starting feature test}\wait - \resettimer - \featuretest\zerocount \dotestfeature - \writestatus\m!systems{feature test done (\elapsedseconds s)}% - \wait - \egroup} - -\def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax} - -\def\showtimer#1% - {\writestatus{runtime}{\elapsedseconds\space s / #1}} - -\def\testfeatureonce#1#2% - {\let\wait\relax\testfeature{#1}{#2}\end} - -%D \macros -%D {freezedimenmacro} -%D -%D This macro is use as: -%D -%D \starttyping -%D \freezedimenmacro\leftmargindistance -%D \stoptyping - -\def\freezedimenmacro#1% - {\edef#1{\the\dimexpr#1}} - -%D The next macro negates a macro (dimension or number, or actually, whatever. -%D It's a typical example of \type {\if} usage: -%D -%D \starttyping -%D \if-\whatever \else-\whatever\fi => else => -whatever -%D \if--\whatever\else-\whatever\fi => then => whatever -%D \stoptyping - -\def\negated#1{\if-#1\else-#1\fi} % does only work in macros or text - -% This permits things like ^\index{hans}^, where hans is -% duplicated in the text. - -\newif\ifduplicate - -\bgroup - -\gdef\checkduplication % in line with Knuth - {\ifmmode\expandafter^\else\expandafter\startduplication\fi} - -\gdef\insideduplication - {\ifmmode\expandafter^\else\expandafter\egroup\fi} - -\catcode`\^=\@@active - -\gdef\enableduplication - {\catcode`\^=\@@active \let^\checkduplication} - -\gdef\disableduplication - {\catcode`\^=\@@superscript} - -\gdef\startduplication - {\bgroup \duplicatetrue \let^\insideduplication} - -\egroup - -\def\gobbleassigndimen#1\\{} - -\def\assigndimen#1#2% - {\afterassignment\gobbleassigndimen#1=#2\!!zeropoint\\} - -\def\setusage#1% - {\@EA\let\csname#1\endcsname\iftrue} - -\def\resetusage#1% - {\@EA\let\csname#1\endcsname\iffalse} - -\def\ifusage#1% - {\ifcsname#1\endcsname\else - \resetusage{#1}% - \fi - \csname#1\endcsname} - -%D Very handy, more efficient than \type{{}}, and more readable -%D than \type {\empty}. - -\let\donothing\empty - -% The following macros are used in XML handling. - -\long\setvalue{@u@s@"}#1#2"{#2} \long\setvalue{@g@s@"}#1#2"{\scratchtoks{#2}} -\long\setvalue{@u@s@'}#1#2'{#2} \long\setvalue{@g@s@'}#1#2'{\scratchtoks{#2}} -\long\setvalue{@u@s@ }#1#2 {#2} \long\setvalue{@g@s@ }#1#2 {\scratchtoks{#2}} - -\long\def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1} -\long\def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1} - -\def\dowithgrabbedstring#1% - {\def\@@dowithgrabbedstring{#1}% - \afterassignment\@@dowithgrabbedstring\grabstring} - -\def\expifequalelse#1#2% - {\@@ifequal#1\relax\relax\@@and#2\relax\relax\@@then} - -\def\@@ifequal#1#2\@@and#3% - {\ifx#1\relax - \ifx#3\relax - \@EAEAEA\@@if@@equal@@true - \else - \@EAEAEA\@@if@@equal@@false - \fi - \else - \ifx#3\relax - \@EAEAEAEAEAEA\@@if@@equal@@false - \else\ifx#1#3% - % go on - \else - \@EAEAEAEAEAEA\@@if@@equal@@false - \fi\fi - \fi - \@@ifequal#2\@@and} - -\long\def\@@if@@equal@@true #1\@@then#2#3{#2} -\long\def\@@if@@equal@@false#1\@@then#2#3{#3} - -%D new stuff : - -\def\partialexpanded#1% - {\let\@@notexpanded\noexpand - \long\xdef\@@expanded{\noexpand#1}% - \let\@@notexpanded\empty - \@@expanded} - -\def\appended#1#2#3{\@EA#1\@EA#2\@EA{#2#3}} -\def\appendvalue #1{\@EA\appended\@EA \def\csname#1\endcsname} -\def\appendgvalue#1{\@EA\appended\@EA\gdef\csname#1\endcsname} - -\def\prepended#1#2#3{\scratchtoks{#3}\@EA\@EA\@EA#1\@EA\@EA\@EA#2\@EA\@EA\@EA{\@EA\the\@EA\scratchtoks#2}} -\def\prependvalue #1{\@EA\prepended\@EA \def\csname#1\endcsname} -\def\prependgvalue#1{\@EA\prepended\@EA\gdef\csname#1\endcsname} - -%D \macros -%D {compresscommacommandnrs,compresscommalistnrs,compressedcommalistnrs, -%D compresscommacommand,compresscommalist,compressedcommalist, -%D reversecommacommand,reversecommalist,reversedcommalist} -%D -%D The following two list processing macros are needed by Taco's -%D bibliography module. The numbers compressor converts the -%D list in a list of ranges. The normal compressor remove duplicate -%D and empty entries. - -\def\compresscommalistnrs[#1]% - {\let\compressedlist\empty - \!!counta\maxdimen - \!!countb\maxdimen - \processcommalist[#1]\docompresslistnrs - \ifnum\!!counta=\maxdimen\else\dodocompresslistnrs\fi} - -\def\compresscommacommandnrs[#1]% - {\normalexpanded{\noexpand\compresscommalistnrs[#1]}} - -\def\docompresslistnrs#1% - {\edef\commalistelement{#1}% - \ifx\commalistelement\empty\else - \ifnum\!!counta=\maxdimen - \!!counta\commalistelement\relax - \!!countb\!!counta - \else - \advance\!!countb\plusone - \ifnum\commalistelement>\!!countb - \advance\!!countb\minusone - \dodocompresslistnrs - \!!counta\commalistelement\relax - \!!countb\!!counta - \fi - \fi - \fi} - -\def\dodocompresslistnrs - {\edef\compressedlist - {\ifx\compressedlist\empty\else\compressedlist,\fi - {\the\!!counta}{\ifnum\!!countb>\!!counta\the\!!countb\fi}}} - -%D \def\test#1{{\tttf#1->\compresscommalistnrs[#1]\defconvertedcommand\ascii\compressedlist\ascii}} -%D \startlines -%D \test{} -%D \test{1} -%D \test{1,3} -%D \test{1,3,4} -%D \test{1,3,3,4,5} -%D \test{1,3,3,4,5,8} -%D \test{1,3,3,4,5,5,8,10} -%D \test{1,3,4,5,8,10,11} -%D \test{1,,3,,4,,5,,8,,10,,11,} -%D \stoplines - -\def\compresscommalist[#1]% - {\let\compressedlist\empty - \let\!!stringa\empty - \processcommalist[#1]\docompresslist} - -\def\compresscommacommand[#1]% - {\normalexpanded{\noexpand\compresscommalist[#1]}} - -\def\docompresslist#1% - {\edef\commalistelement{#1}% - \ifx\commalistelement\empty \else - \ifx\!!stringa\commalistelement \else - \ifx\compressedlist\empty - \def\compressedlist{#1}% - \else - \appended\def\compressedlist{,#1}% - \fi - \let\!!stringa\commalistelement - \fi - \fi} - -%D \def\test#1{{\tttf#1->\compresscommalist[#1]\defconvertedcommand\ascii\compressedlist\ascii}} -%D \startlines -%D \test{} -%D \test{1} -%D \test{1,3} -%D \test{1,3,4} -%D \test{1,3,3,4,5} -%D \test{1,3,3,4,5,8} -%D \test{1,3,3,4,5,5,8,10} -%D \test{1,3,4,5,8,10,11} -%D \test{1,,3,,4,,5,,8,,10,,11,} -%D \stoplines - -\def\reversecommalist[#1]% - {\let\reversedlist\empty - \processcommalist[#1]\doreverselist} - -\def\doreverselist#1% - {\ifx\reversedlist\empty - \def\reversedlist{#1}% - \else - \prepended\def\reversedlist{#1,}% - \fi} - -\def\reversecommacommand[#1]% - {\normalexpanded{\noexpand\reversecommalist[#1]}} - -%D \def\test#1{{\tttf#1->\reversecommalist[#1]\defconvertedcommand\ascii\reversedlist\ascii}} -%D \startlines -%D \test{} -%D \test{1} -%D \test{1,3} -%D \test{1,3,4} -%D \test{1,3,3,4,5} -%D \test{1,3,3,4,5,8} -%D \test{1,3,3,4,5,5,8,10} -%D \test{1,3,4,5,8,10,11} -%D \test{1,,3,,4,,5,,8,,10,,11,} -%D \stoplines - -%D \macros -%D {stripstring} -%D -%D Needed in bookmarks: -%D -%D \starttyping -%D {\sanitizePDFdocencoding test \CONTEXT\ test \to\oeps\stripstring\oeps\tttf[\oeps]} -%D \stoptyping - -\def\stripstring#1% #1 is \cs - {\edef\cs{\ctxlua - {tex.sprint(tex.vrbcatcodes,string.strip(\!!bs\detokenize\expandafter{#1}\!!es))}}} - -%D \macros -%D {dowithrange} -%D -%D This one is for Mojca Miklavec, who made me aware of the fact that -%D \type {page-imp.tex} was not the best place to hide it. - -\def\dowithrange#1#2% #2 takes number - {\splitstring#1\at:\to\fromrange\and\torange - \ifx\torange\empty\let\torange\fromrange\fi - \dostepwiserecurse\fromrange\torange1{#2{\recurselevel}}} - -%D \macros {uncompresslist} -%D -%D When given a list like \type{1,4-7,9} as argument, this macro -%D will store the expanded commalist in \type{\uncompressedlist}. -%D -%D \startbuffer -%D \def\MojcaHasToDoTheTasks[#1]#2% -%D {{\uncompresslist[#1]% -%D \def\processitem##1{I have to do ##1 #2\par}% -%D \processcommacommand[\uncompressedlist]\processitem}} -%D -%D \MojcaHasToDoTheTasks [1-4,7,9-11] {until tomorrow} -%D \stopbuffer -%D -%D Here is an example of how to use \type {\uncompresslist}: -%D \typebuffer -%D -%D The output of this is: -%D -%D \getbuffer - -\def\uncompresslist[#1]% by TH - {\let\uncompressedlist\empty - \def\docompressedlistitem##1-##2-% - {\@EA\dorecurse\@EA - {\the\numexpr1+##2-##1\relax}% - {\@EA\appendtocommalist\@EA{\the\numexpr##1-1+####1\relax}\uncompressedlist}}% - \def\douncompresslist##1% - {\doifinstringelse{-}{##1} - {\docompressedlistitem##1-} - {\appendtocommalist{##1}\uncompressedlist}}% - \processcommalist[#1]\douncompresslist} - -%D \macros -%D {ignoreimplicitspaces} -%D -%D \startbuffer -%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignorespaces} -%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b} -%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignoreimplicitspaces} -%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b} -%D \stopbuffer -%D -%D \typebuffer \getbuffer - -\def\ignoreimplicitspaces - {\doifnextcharelse\relax\relax\relax} - -% new -% -% \startnointerference -% all kind of code -% \stopnointerference - -\newbox\nointerferencebox - -\def\startnointerference % not even grouped ! - {\setbox\nointerferencebox\vbox - \bgroup} - -\def\stopnointerference - {\egroup - \setbox\nointerferencebox\emptybox} - -% \def\appendtovaluelist#1#2% -% {\ifcsname#1\endcsname -% \expandafter\ifx\csname#1\endcsname\empty -% \expandafter\def\csname#1\endcsname{#2}% -% \else -% \expandafter\def\csname#1\expandafter\expandafter\expandafter\endcsname -% \expandafter\expandafter\expandafter{\csname#1\endcsname,#2}% -% \fi -% \else -% \expandafter\def\csname#1\endcsname{#2}% -% \fi} -% -% or -% -% \def\appendtovaluelist#1% -% {\ifcsname#1\endcsname -% \expandafter\ifx\csname#1\endcsname\empty -% \expandafter\noappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname -% \else -% \expandafter\doappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname -% \fi -% \else -% \expandafter\noappendtovaluelist\csname#1\expandafter\endcsname -% \fi} - -% \def\doappendtovaluelist#1#2{\expandafter\def\expandafter#1\expandafter{#1,#2}} -% \def\noappendtovaluelist#1#2{\def#1{#2}} - -% \appendtovaluelist{mylist}{aap} -% \appendtovaluelist{mylist}{noot} -% \appendtovaluelist{mylist}{mies} - -% \showvalue{mylist} - -\protect \endinput diff --git a/tex/context/base/syst-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-lua.tex b/tex/context/base/syst-lua.tex deleted file mode 100644 index 40cd9f756..000000000 --- a/tex/context/base/syst-lua.tex +++ /dev/null @@ -1,37 +0,0 @@ -%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/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/task-ini.tex b/tex/context/base/task-ini.tex deleted file mode 100644 index ef32ee87d..000000000 --- a/tex/context/base/task-ini.tex +++ /dev/null @@ -1,22 +0,0 @@ -%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/toks-ini.mkiv b/tex/context/base/toks-ini.mkiv new file mode 100644 index 000000000..932c05f32 --- /dev/null +++ b/tex/context/base/toks-ini.mkiv @@ -0,0 +1,78 @@ +%D \module +%D [ file=toks-ini, +%D version=2007.03.03, +%D title=\CONTEXT\ Token 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 Token Support / Initialization} + +\registerctxluafile{toks-ini}{1.001} + +\unprotect + +%D Handy for manuals \unknown + +\def\starttokens [#1]{\ctxlua{collectors.install("#1", "stoptokens")}} +\let\stoptokens \relax +\def\flushtokens [#1]{\ctxlua{collectors.flush("#1")}} +\def\showtokens [#1]{\ctxlua{collectors.show("#1")}} +\def\testtokens [#1]{\ctxlua{collectors.with_words("#1")}} +\def\registertoken #1{\ctxlua{collectors.register("#1")}} + +%D Inspired by a prototype by Taco for Thomas cum suis. + +% \defineremapper[babelgreek] +% +% \remapcharacter[babelgreek][`a]{\alpha} +% \remapcharacter[babelgreek][`b]{\beta} +% \remapcharacter[babelgreek][`c]{\gamma} +% \remapcharacter[babelgreek][`d]{OEPS} +% +% \starttext +% +% [\startbabelgreek +% a b c some stuff here \blank[big] oeps b d +% \stopbabelgreek] +% +% [\babelgreek{some stuff here}] +% +% \stoptext + +% incompatible with mkii ! ! ! ! so we need other names here +% +% \def\dograbuntil#1#2% +% {\long\def\next##1#1{#2##1}\next} +% +% \def\grabuntil#1% +% {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}} + +\def\dostartremapper#1% + {\ctxlua{collectors.install("#1", "\e!stop#1")}} + +\def\dostopremapper#1% + {\ctxlua{collectors.handle("#1",function(str) return collectors.remapper.convert("#1",str) end, true)}} + +\def\remaptokens#1% + {\ctxlua{collectors.handle("#1",function(str) return collectors.remapper.convert("#1",str) end)}} + +\def\defineremapper[#1]% + {\setvalue{\e!start#1}{\dostartremapper{#1}}% + \setvalue{\e!stop #1}{\dostopremapper {#1}}% + \def\next##1{\setvalue{#1}####1{\getvalue{\e!start#1}####1##1}}% + \expandafter\next\csname\e!stop#1\endcsname} + +\def\remapcharacter + {\dodoubleempty\doremapcharacter} + +\def\doremapcharacter[#1][#2]#3% + {\ctxlua{collectors.install("store", "ctxlua")}#3% + \ctxlua{collectors.remapper.store("store","#1",\number#2)}} + +\protect \endinput diff --git a/tex/context/base/toks-ini.tex b/tex/context/base/toks-ini.tex deleted file mode 100644 index 932c05f32..000000000 --- a/tex/context/base/toks-ini.tex +++ /dev/null @@ -1,78 +0,0 @@ -%D \module -%D [ file=toks-ini, -%D version=2007.03.03, -%D title=\CONTEXT\ Token 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 Token Support / Initialization} - -\registerctxluafile{toks-ini}{1.001} - -\unprotect - -%D Handy for manuals \unknown - -\def\starttokens [#1]{\ctxlua{collectors.install("#1", "stoptokens")}} -\let\stoptokens \relax -\def\flushtokens [#1]{\ctxlua{collectors.flush("#1")}} -\def\showtokens [#1]{\ctxlua{collectors.show("#1")}} -\def\testtokens [#1]{\ctxlua{collectors.with_words("#1")}} -\def\registertoken #1{\ctxlua{collectors.register("#1")}} - -%D Inspired by a prototype by Taco for Thomas cum suis. - -% \defineremapper[babelgreek] -% -% \remapcharacter[babelgreek][`a]{\alpha} -% \remapcharacter[babelgreek][`b]{\beta} -% \remapcharacter[babelgreek][`c]{\gamma} -% \remapcharacter[babelgreek][`d]{OEPS} -% -% \starttext -% -% [\startbabelgreek -% a b c some stuff here \blank[big] oeps b d -% \stopbabelgreek] -% -% [\babelgreek{some stuff here}] -% -% \stoptext - -% incompatible with mkii ! ! ! ! so we need other names here -% -% \def\dograbuntil#1#2% -% {\long\def\next##1#1{#2##1}\next} -% -% \def\grabuntil#1% -% {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}} - -\def\dostartremapper#1% - {\ctxlua{collectors.install("#1", "\e!stop#1")}} - -\def\dostopremapper#1% - {\ctxlua{collectors.handle("#1",function(str) return collectors.remapper.convert("#1",str) end, true)}} - -\def\remaptokens#1% - {\ctxlua{collectors.handle("#1",function(str) return collectors.remapper.convert("#1",str) end)}} - -\def\defineremapper[#1]% - {\setvalue{\e!start#1}{\dostartremapper{#1}}% - \setvalue{\e!stop #1}{\dostopremapper {#1}}% - \def\next##1{\setvalue{#1}####1{\getvalue{\e!start#1}####1##1}}% - \expandafter\next\csname\e!stop#1\endcsname} - -\def\remapcharacter - {\dodoubleempty\doremapcharacter} - -\def\doremapcharacter[#1][#2]#3% - {\ctxlua{collectors.install("store", "ctxlua")}#3% - \ctxlua{collectors.remapper.store("store","#1",\number#2)}} - -\protect \endinput diff --git a/tex/context/base/trac-deb.mkiv b/tex/context/base/trac-deb.mkiv new file mode 100644 index 000000000..870c452ad --- /dev/null +++ b/tex/context/base/trac-deb.mkiv @@ -0,0 +1,43 @@ +%D \module +%D [ file=trac-deb, +%D version=2005.11.06, +%D title=\CONTEXT\ Tracing Macros, +%D subtitle=Debugger, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Tracing Macros / Debugger} + +\registerctxluafile{trac-deb}{1.001} + +\def\showdebuginfo{\ctxlua{tracers.showdebuginfo()}} +\def\overloaderror{\ctxlua{tracers.overloaderror()}} + +\def\breakpoint{\showdebuginfo\wait} + +\appendtoks + \ctxlua { + if debugger.tracing() then + debugger.enable() ; + end + }% +\to \everyjob + +\appendtoks + \ctxlua { + if debugger.tracing() then + debugger.disable() ; + debugger.savestats("\jobname-luacalls.log") ; + end + }% +\to \everybye + +\def\showtrackers {\ctxlua{trackers.show()}} +\def\resettrackers {\ctxlua{trackers.reset()}} +\def\enabletrackers [#1]{\ctxlua{trackers.enable("#1")}} +\def\disabletrackers[#1]{\ctxlua{trackers.disable("#1")}} diff --git a/tex/context/base/trac-deb.tex b/tex/context/base/trac-deb.tex deleted file mode 100644 index 870c452ad..000000000 --- a/tex/context/base/trac-deb.tex +++ /dev/null @@ -1,43 +0,0 @@ -%D \module -%D [ file=trac-deb, -%D version=2005.11.06, -%D title=\CONTEXT\ Tracing Macros, -%D subtitle=Debugger, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Tracing Macros / Debugger} - -\registerctxluafile{trac-deb}{1.001} - -\def\showdebuginfo{\ctxlua{tracers.showdebuginfo()}} -\def\overloaderror{\ctxlua{tracers.overloaderror()}} - -\def\breakpoint{\showdebuginfo\wait} - -\appendtoks - \ctxlua { - if debugger.tracing() then - debugger.enable() ; - end - }% -\to \everyjob - -\appendtoks - \ctxlua { - if debugger.tracing() then - debugger.disable() ; - debugger.savestats("\jobname-luacalls.log") ; - end - }% -\to \everybye - -\def\showtrackers {\ctxlua{trackers.show()}} -\def\resettrackers {\ctxlua{trackers.reset()}} -\def\enabletrackers [#1]{\ctxlua{trackers.enable("#1")}} -\def\disabletrackers[#1]{\ctxlua{trackers.disable("#1")}} diff --git a/tex/context/base/trac-lmx.mkiv b/tex/context/base/trac-lmx.mkiv new file mode 100644 index 000000000..a47d2b8bb --- /dev/null +++ b/tex/context/base/trac-lmx.mkiv @@ -0,0 +1,16 @@ +%D \module +%D [ file=trac-lmx, +%D version=2005.09.02, +%D title=\CONTEXT\ Tracing Macros, +%D subtitle=LMX, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Tracing Macros / LMX} + +\registerctxluafile{trac-lmx}{1.001} diff --git a/tex/context/base/trac-lmx.tex b/tex/context/base/trac-lmx.tex deleted file mode 100644 index a47d2b8bb..000000000 --- a/tex/context/base/trac-lmx.tex +++ /dev/null @@ -1,16 +0,0 @@ -%D \module -%D [ file=trac-lmx, -%D version=2005.09.02, -%D title=\CONTEXT\ Tracing Macros, -%D subtitle=LMX, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Tracing Macros / LMX} - -\registerctxluafile{trac-lmx}{1.001} diff --git a/tex/context/base/trac-vis.mkii b/tex/context/base/trac-vis.mkii new file mode 100644 index 000000000..23ded2af9 --- /dev/null +++ b/tex/context/base/trac-vis.mkii @@ -0,0 +1,748 @@ +%D \module +%D [ file=trac-vis, % was core-vis, +%D version=1996.06.01, +%D title=\CONTEXT\ Tracking Macros, +%D subtitle=Visualization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module adds some more visualization cues to the ones +%D supplied in the support module. +%D +%D %\everypar dual character, \the\everypar and \everypar= +%D %\hrule cannot be grabbed in advance, switches mode +%D %\vrule cannot be grabbed in advance, switches mode +%D % +%D %\indent only explicit ones +%D %\noindent only explicit ones +%D %\par only explicit ones +%D +%D %\leftskip only if explicit one +%D %\rightskip only if explicit one + +\writestatus{loading}{ConTeXt Tracking Macros / Visualization} + +\unprotect + +%D \macros +%D {indent, noindent, par} +%D +%D \TeX\ acts upon paragraphs. In mosts documents paragraphs +%D are separated by empty lines, which internally are handled as +%D \type{\par}. Paragraphs can be indented or not, depending on +%D the setting of \type{\parindent}, the first token of a +%D paragraph and/or user suppressed or forced indentation. +%D +%D Because the actual typesetting is based on both explicit +%D user and implicit system actions, visualization is only +%D possible for the user supplied \type{\indent}, +%D \type{\noindent}, and \type{\par}. Other +%D 'clever' tricks will quite certainly lead to more failures +%D than successes, so we only support these three explicit +%D primitives and one macro: + +\def\showparagraphcue#1#2#3#4#5% + {\bgroup + \scratchdimen#1\relax + \dontinterfere + \dontcomplain + \boxrulewidth5\testrulewidth + #3#4\relax + \setbox\scratchbox\normalhbox to \scratchdimen + {#2{\ruledhbox to \scratchdimen + {\vrule #5 20\testrulewidth \!!width \zeropoint + \normalhss}}}% + \smashbox\scratchbox + \normalpenalty\!!tenthousand + \box\scratchbox + \egroup} + +\def\ruledhanging + {\ifdim\hangindent>\zeropoint + \ifnum\hangafter<\zerocount + \normalhbox + {\boxrulewidth5\testrulewidth + \setbox\scratchbox\ruledhbox to \hangindent + {\scratchdimen\strutht + \advance\scratchdimen \strutdp + \vrule + \!!width \zeropoint + \!!height \zeropoint + \!!depth -\hangafter\scratchdimen}% + \normalhskip-\hangindent + \smashbox\scratchbox + \raise\strutht\box\scratchbox}% + \fi + \fi} + +\def\ruledparagraphcues + {\bgroup + \dontcomplain + \normalhbox to \zeropoint + {\ifdim\leftskip>\zeropoint\relax + \showparagraphcue\leftskip\llap\relax\relax\!!depth + \normalhskip-\leftskip + \fi + \ruledhanging + \normalhskip\hsize + \ifdim\rightskip>\zeropoint\relax + \normalhskip-\rightskip + \showparagraphcue\rightskip\relax\relax\relax\!!depth + \fi}% + \egroup} + +\def\ruledpar + {\relax + \ifhmode + \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\!!height + \fi + \normalpar} + +\def\rulednoindent + {\relax + \normalnoindent + \ruledparagraphcues + \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\!!height} + +\def\ruledindent + {\relax + \normalnoindent + \ruledparagraphcues + \ifdim\parindent>\zeropoint + \showparagraphcue\parindent\relax\relax\relax\!!height + \else + \showparagraphcue{40\testrulewidth}\llap\relax\relax\!!height + \fi + \normalhskip\parindent} + +\def\dontshowimplicits + {\let\noindent \normalnoindent + \let\indent \normalindent + \let\par \normalpar} + +\def\showimplicits + {\testrulewidth \defaulttestrulewidth + \let\noindent \rulednoindent + \let\indent \ruledindent + \let\par \ruledpar} + +%D The next few||line examples show the four cues. Keep in +%D mind that we only see them when we explicitly open or close +%D a paragraph. +%D +%D \bgroup +%D \def\voorbeeld#1% +%D {#1Visualizing some \TeX\ primitives and Plain \TeX\ +%D macros can be very instructive, at least it is to me. +%D Here we see {\tt\string#1} and {\tt\string\ruledpar} in +%D action, while {\tt\string\parindent} equals +%D {\tt\the\parindent}.\ruledpar} +%D +%D \showimplicits +%D +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D +%D \parindent=60pt +%D +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D +%D \startnarrower +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D \stopnarrower +%D \egroup +%D +%D These examples also demonstrate the visualization of +%D \type {\leftskip} and \type {\rightskip}. The macro +%D \type {\nofruledbaselines} determines the number of lines +%D shown. + +\newcounter\ruledbaselines + +\def\nofruledbaselines{3} + +\def\debuggertext#1% + {\ifx\ttxx\undefined + $\scriptscriptstyle#1$% + \else + {\ttxx#1}% + \fi} + +\def\ruledbaseline + {\vrule \!!width \zeropoint + \bgroup + \dontinterfere + \doglobal\increment\ruledbaselines + \scratchdimen\nofruledbaselines\baselineskip + \setbox\scratchbox\normalvbox to 2\scratchdimen + {\leaders + \normalhbox + {\strut + \vrule + \!!height \testrulewidth + \!!depth \testrulewidth + \!!width 120\points} + \normalvfill}% + \smashbox\scratchbox + \advance\scratchdimen \strutheightfactor\baselineskip + \setbox\scratchbox\normalhbox + {\normalhskip -48\points + \normalhbox to 24\points + {\normalhss\debuggertext\ruledbaselines\normalhskip6\points}% + \raise\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox + \egroup} + +\def\showbaselines + {\testrulewidth\defaulttestrulewidth + \EveryPar{\ruledbaseline}} + +%D \macros +%D {showpagebuilder} +%D +%D The next tracing option probaly is only of use to me and a +%D few \CONTEXT\ hackers. + +\def\showpagebuilder + {\EveryPar{\doshowpagebuilder}} + +\def\doshowpagebuilder + {\strut\llap + {\startcolor[blue]\vl + \high{\infofont v:\the\vsize }\vl + \high{\infofont g:\the\pagegoal }\vl + \high{\infofont t:\the\pagetotal}\vl + \stopcolor}} + +%D \macros +%D {makecutbox, cuthbox, cutvbox, cutvtop} +%D +%D Although mainly used for marking the page, these macros can +%D also serve local use. +%D +%D \startbuffer +%D \setbox0=\vbox{a real \crlf vertical box} \makecutbox0 +%D \stopbuffer +%D +%D \typebuffer +%D +%D This marked \type{\vbox} shows up as: +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection +%D +%D The alternative macros are used as: +%D +%D \startbuffer +%D \cuthbox{a made cut box} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This is typeset as: +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection +%D +%D By setting the next macros one can influence the length of +%D the marks as well as the horizontal and vertical divisions. + +\def\cutmarklength {2\bodyfontsize} +\chardef\horizontalcutmarks = 2 +\chardef\verticalcutmarks = 2 +\chardef\cutmarkoffset = 1 +\let\cutmarksymbol = \relax +\let\cutmarktoptext = \empty +\let\cutmarkbottomtext = \empty + +\def\horizontalcuts + {\normalhbox to \ruledwidth + {\dorecurse\horizontalcutmarks + {\vrule\!!width\boxrulewidth\!!height\cutmarklength\normalhfill}% + \unskip}} + +\def\verticalcuts + {\scratchdimen\ruledheight + \advance\scratchdimen \ruleddepth + \normalvbox to \scratchdimen + {\hsize\cutmarklength + \dorecurse\verticalcutmarks + {\vrule\!!height\boxrulewidth\!!width\hsize\normalvfill}% + \unskip}} + +\def\baselinecuts + {\ifdim\ruleddepth>\zeropoint + \scratchdimen\ruledheight + \advance\scratchdimen \ruleddepth + \normalvbox to \scratchdimen + {\scratchdimen\cutmarklength + \divide\scratchdimen 2 + \hsize\scratchdimen + \normalvskip\zeropoint\!!plus\ruledheight + \vrule\!!height\boxrulewidth\!!width\hsize + \normalvskip\zeropoint\!!plus\ruleddepth}% + \fi} + +\def\cutmarksymbols#1% + {\normalhbox to \ruledwidth + {\setbox\scratchbox\normalhbox to \cutmarklength + {\normalhss\infofont\cutmarksymbol\normalhss}% + \normalhss + \normalvbox to \cutmarklength + {\scratchdimen\cutmarklength + \divide\scratchdimen \plustwo + \normalvss + \hbox to \ruledwidth + {\llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% + \normalhskip\scratchdimen\hss\infofont#1\hss\normalhskip\scratchdimen + \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% + \normalvss}% + \normalhss}} + +\def\makecutbox#1% simplier with layers, todo + {\edef\ruledheight{\the\ht#1}% + \edef\ruleddepth {\the\dp#1}% + \edef\ruledwidth {\the\wd#1}% + \setbox#1\normalhbox + {\dontcomplain + \forgetall + \boxmaxdepth\maxdimen + \offinterlineskip + \scratchdimen\cutmarklength + \divide\scratchdimen \plustwo + \hsize\ruledwidth + \setbox\scratchbox\normalvbox + {\setbox\scratchbox\normalhbox{\horizontalcuts}% + \normalvskip-\cutmarkoffset\scratchdimen + \normalvskip-2\scratchdimen + \copy\scratchbox + \normalvskip\cutmarkoffset\scratchdimen + \hbox to \ruledwidth + {\setbox\scratchbox\normalhbox{\verticalcuts}% + \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% + \bgroup + \setbox\scratchbox\normalhbox{\baselinecuts}% + \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% + \normalhfill + \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}% + \egroup + \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% + \normalvskip\cutmarkoffset\scratchdimen + \copy\scratchbox}% + \ht\scratchbox\ruledheight + \dp\scratchbox\ruleddepth + \wd\scratchbox\zeropoint + \resetcolorseparation + \localstartcolor[\defaulttextcolor]% + \box\scratchbox + \ifx\cutmarksymbol\relax \else + \setbox\scratchbox\normalvbox + {\vskip-\cutmarkoffset\scratchdimen + \vskip-\cutmarklength + \normalhbox{\cutmarksymbols\cutmarktoptext}% + \vskip\cutmarkoffset\scratchdimen + \vskip\ruledheight + \vskip\ruleddepth + \vskip\cutmarkoffset\scratchdimen + \normalhbox{\cutmarksymbols\cutmarkbottomtext}}% + \ht\scratchbox\ruledheight + \dp\scratchbox\ruleddepth + \wd\scratchbox\zeropoint + \box\scratchbox + \fi + \localstopcolor + \box#1}% + \wd#1=\ruledwidth + \ht#1=\ruledheight + \dp#1=\ruleddepth} + +\def\cuthbox + {\normalhbox\bgroup + \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalhbox} + +\def\cutvbox + {\normalvbox\bgroup + \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvbox} + +\def\cutvtop + {\normalvtop\bgroup + \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvtop} + +%D \macros +%D {colormarkbox,rastermarkbox} +%D +%D This macro is used in the pagebody routine. No other use +%D is advocated here. +%D +%D \starttyping +%D \colormarkbox0 +%D \stoptyping + +\def\colormarkoffset{\cutmarkoffset} +\def\colormarklength{\cutmarklength} + +\def\colorrangeA#1#2#3#4% + {\vbox + {\scratchdimen-\colormarklength + \multiply\scratchdimen 4 + \advance\scratchdimen \ruledheight + \advance\scratchdimen \ruleddepth + \divide\scratchdimen 21 + \def\docommand##1% + {\vbox + {\hsize3em % \scratchdimen + \definecolor + [\s!dummy] + [\c!c=#2##1\else0\fi, + \c!m=#3##1\else0\fi, + \c!y=#4##1\else0\fi, + \c!k=0]% + \localstartcolor[\s!dummy]% + \hrule + \!!width 3em + \!!height \scratchdimen + \!!depth \zeropoint + \localstopcolor + \ifdim\scratchdimen>1ex + \vskip-\scratchdimen + \vbox to \scratchdimen + {\vss + \hbox to 3em + {\hss + \localstartcolor[\s!white]% + \ifdim##1\points=\zeropoint#1\else##1\fi + \localstopcolor + \hss}% + \vss}% + \fi}}% + \offinterlineskip + \processcommalist[1.00,0.95,0.75,0.50,0.25,0.05,0.00]\docommand}} + +\def\colorrangeB + {\hbox + {\scratchdimen-\colormarklength + \multiply\scratchdimen \plustwo + \advance\scratchdimen \ruledwidth + \divide\scratchdimen 11 + \def\docommand ##1 ##2 ##3##4##5##6% + {\definecolor + [\s!dummy] + [\c!c=##3##2\else0\fi, + \c!m=##4##2\else0\fi, + \c!y=##5##2\else0\fi, + \c!k=##6##2\else0\fi]% + \localstartcolor[\s!dummy]% + \vrule + \!!width \scratchdimen + \!!height \colormarklength + \!!depth \zeropoint + \localstopcolor + \ifdim\scratchdimen>2em + \hskip-\scratchdimen + \vbox to \colormarklength + {\vss + \hbox to \scratchdimen + {\hss + \localstartcolor[\s!white]% + \ifdim##2\points=.5\points##2~\fi##1% + \localstopcolor + \hss} + \vss}% + \fi}% + \docommand C .5 \iftrue \iffalse\iffalse\iffalse + \docommand M .5 \iffalse\iftrue \iffalse\iffalse + \docommand Y .5 \iffalse\iffalse\iftrue \iffalse + \docommand K .5 \iffalse\iffalse\iffalse\iftrue + \docommand C 1 \iftrue \iffalse\iffalse\iffalse + \docommand G 1 \iftrue \iffalse\iftrue \iffalse + \docommand Y 1 \iffalse\iffalse\iftrue \iffalse + \docommand R 1 \iffalse\iftrue \iftrue \iffalse + \docommand M 1 \iffalse\iftrue \iffalse\iffalse + \docommand B 1 \iftrue \iftrue \iffalse\iffalse + \docommand K 1 \iffalse\iffalse\iffalse\iftrue}} + +\def\colorrangeC + {\hbox + {\resetcolorseparation + \scratchdimen-\colormarklength + \multiply\scratchdimen 2 + \advance\scratchdimen \ruledwidth + \divide\scratchdimen 14 + \def\docommand##1% + {\definecolor[\s!dummy][\c!s=##1]% + \localstartcolor[\s!dummy]% + \vrule + \!!width \scratchdimen + \!!height \colormarklength + \!!depth \zeropoint + \localstopcolor + \ifdim\scratchdimen>2em + \hskip-\scratchdimen + \vbox to \colormarklength + {\vss + \localstartcolor[\s!white]% + \hbox to \scratchdimen{\hss##1\hss} + \localstopcolor + \vss}% + \fi}% + \processcommalist[1,.95,.9,.85,.8,.75,.7,.6,.5,.4,.3,.2,.1,0]\docommand}} + +\def\docolormarkbox#1#2% + {\edef\ruledheight{\the\ht#2}% + \edef\ruleddepth {\the\dp#2}% + \edef\ruledwidth {\the\wd#2}% + \setbox#2\hbox + {\scratchdimen\colormarklength + \divide\scratchdimen \plustwo + \forgetall + \ssxx + \setbox\scratchbox\vbox + {\offinterlineskip + \vskip-\colormarkoffset\scratchdimen + \vskip-2\scratchdimen\relax % relax needed + % beware: no \ifcase, due to nested \iftrue/\iffalse + % and lacking \fi's + \doifelse{#1}{0}% + {\vskip\colormarklength + \vskip\colormarkoffset\scratchdimen + \vskip\ruledheight} + {\hbox to \ruledwidth{\hss\hbox{\colorrangeB}\hss}% + \vskip\colormarkoffset\scratchdimen + \vbox to \ruledheight + {\vss + \hbox to \ruledwidth + {\llap{\colorrangeA C\iftrue\iffalse\iffalse\hskip\colormarkoffset\scratchdimen}% + \hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA R\iffalse\iftrue\iftrue}}% + \vss + \hbox to \ruledwidth + {\llap{\colorrangeA M\iffalse\iftrue\iffalse\hskip\colormarkoffset\scratchdimen}% + \hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA G\iftrue\iffalse\iftrue}}% + \vss + \hbox to \ruledwidth + {\llap{\colorrangeA Y\iffalse\iffalse\iftrue\hskip\colormarkoffset\scratchdimen}% + \hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA B\iftrue\iftrue\iffalse}}% + \vss}}% + \vskip\colormarkoffset\scratchdimen + \hbox to \ruledwidth + {\hss\lower\ruleddepth\hbox{\colorrangeC}\hss}}% + \ht\scratchbox\ruledheight + \dp\scratchbox\ruleddepth + \wd\scratchbox\zeropoint + \box\scratchbox + \box#2}% + \wd#2=\ruledwidth + \ht#2=\ruledheight + \dp#2=\ruleddepth} + +\def\colormarkbox % #1 + {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi1} + +\def\rastermarkbox % #1 + {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi0} + +%D \macros +%D {showwhatsits, dontshowwhatsits} +%D +%D \TEX\ has three so called whatsits: \type {\mark}, \type +%D {\write} and \type {\special}. The first one keeps track of +%D the current state at page boundaries, the last two are used +%D to communicate to the outside world. Due to fact that +%D especially \type {\write} is often used in conjunction with +%D \type {\edef}, we can only savely support that one in \ETEX. +%D +%D \bgroup \showwhatsits \setupcolors[state=start] +%D +%D Whatsits show up \color[blue]{in color} and are +%D characterized bij their first character.\footnote [some note] +%D {So we may encounter \type {w}, \type {m} and \type{s}.} +%D They are \writestatus{dummy}{demo}\color[yellow]{stacked}. +%D +%D \egroup + +\newif\ifimmediatewrite + +\ifx\eTeXversion\undefined + + \let\showwhatsits \relax + \let\dontshowwhatsits\relax + +\else + + \let\supernormalmark \normalmark % mark may already been superseded + \let\supernormalmarks \normalmarks % mark may already been superseded + + \def\showwhatsits + {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }% + \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% + \protected\def\special {\visualwhatsit0100s\normalspecial }% + \protected\def\write {\visualwhatsit001-w\normalwrite }% + \let\immediate\immediatewhatsit + \appendtoks\dontshowwhatsits\to\everystoptext} + + \def\immediatewhatsit + {\bgroup\futurelet\next\doimmediatewhatsit} + + \def\doimmediatewhatsit + {\ifx\next\write + \egroup\immediatewritetrue + \else + \egroup\expandafter\normalimmediate + \fi} + + \def\dontshowwhatsits + {\let\immediate \normalimmediate + \let\normalmark\supernormalmark + \let\special \normalspecial + \let\write \normalwrite} + + \def\visualwhatsit#1#2#3#4#5% + {\bgroup + \pushwhatsit + \dontinterfere + \dontcomplain + \dontshowcomposition + \dontshowwhatsits + \ttx + \ifvmode\donetrue\else\donefalse\fi + \setbox\scratchbox\hbox + {\ifdone\dostartgraycolormode0\else\dostartrgbcolormode#1#2#3\fi + #5\dostopcolormode}% + \setbox\scratchbox\hbox + {\ifdone\dostartrgbcolormode#1#2#3\else\dostartgraycolormode0\fi + \vrule\!!width\wd\scratchbox\dostopcolormode + \hskip-\wd\scratchbox\box\scratchbox}% + \scratchdimen1ex + \setbox\scratchbox\hbox + {\ifdone\hskip\else\raise#4\fi\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \ifdone\nointerlineskip\fi + \box\scratchbox + \ifvmode\nointerlineskip\fi + \popwhatsit + \egroup + \ifimmediatewrite + \immediatewritefalse + \expandafter\normalimmediate + \fi} + + \def\pushwhatsit + {\ifzeropt\lastskip + \ifcase\lastpenalty + \ifzeropt\lastkern + \ifhmode + \let\popwhatsit\relax + \else + \edef\popwhatsit{\prevdepth\the\prevdepth}% + \fi + \else + \ifhmode + \edef\popwhatsit{\kern\the\lastkern}\unkern + \else + \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth}% + \kern-\lastkern + \fi + \fi + \else + \ifhmode + \edef\popwhatsit{\the\lastpenalty}% + \unpenalty + \else + \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}% + %\nobreak + \fi + \fi + \else + \ifhmode + \edef\popwhatsit{\hskip\the\lastskip}\unskip + \else + \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth}% + \vskip-\lastskip + \fi + \fi} + +\fi + +%D The next macro can be used to keep track of classes of +%D boxes (handy for development cq.\ tracing). + +\def\dodotagbox#1#2#3% can be reimplemented + {\def\next##1##2##3##4% + {\vbox to \ht#2{##3\hbox to \wd#2{##1#3##2}##4}}% + \processaction + [#1] + [ l=>\next\relax\hfill\vfill\vfill, + r=>\next\hfill\relax\vfill\vfill, + t=>\next\hfill\hfill\relax\vfill, + b=>\next\hfill\hfill\vfill\relax, + lt=>\next\relax\hfill\relax\vfill, + lb=>\next\relax\hfill\vfill\relax, + rt=>\next\hfill\relax\relax\vfill, + rb=>\next\hfill\relax\vfill\relax, + tl=>\next\relax\hfill\relax\vfill, + bl=>\next\relax\hfill\vfill\relax, + tr=>\next\hfill\relax\relax\vfill, + br=>\next\hfill\relax\vfill\relax, + \s!default=>\next\hfill\hfill\vfill\vfill, + \s!unknown=>\next\hfill\hfill\vfill\vfill]} + +\def\dotagbox[#1]#2% + {\bgroup + \dowithnextbox + {\setbox\scratchbox\flushnextbox + \setbox\nextbox\ifhbox\nextbox\hbox\else\vbox\fi + \bgroup + \startoverlay + {\copy\scratchbox} + {\dodotagbox{#1}\scratchbox{\framed + [\c!background=\v!screen,\c!backgroundscreen=1]{#2}}} + \stopoverlay + \egroup + \nextboxwd\the\wd\scratchbox + \nextboxht\the\ht\scratchbox + \nextboxdp\the\dp\scratchbox + \flushnextbox + \egroup}} + +\def\tagbox + {\dosingleempty\dotagbox} + +%D \macros +%D {coloredhbox,coloredvbox,coloredvtop, +%D coloredstrut} +%D +%D The following visualizations are used in some of the manuals: + +\definecolor[boxcolor:ht][r=.5,g=.75,b=.5] +\definecolor[boxcolor:dp][r=.5,g=.5,b=.75] +\definecolor[boxcolor:wd][r=.75,g=.5,b=.5] +\definecolor[strutcolor] [r=.5,g=.25,b=.25] + +\def\coloredbox#1% + {\dowithnextbox{#1{\hbox + {\blackrule[\c!width=\nextboxwd,\c!height=\nextboxht,\c!depth=\zeropoint,\c!color=boxcolor:ht]% + \hskip-\nextboxwd + \blackrule[\c!width=\nextboxwd,\c!height=\zeropoint,\c!depth=\nextboxdp,\c!color=boxcolor:dp]% + \hskip-\nextboxwd + \box\nextbox}}}#1} + +\def\coloredhbox{\coloredbox\hbox} +\def\coloredvbox{\coloredbox\vbox} +\def\coloredvtop{\coloredbox\vtop} + +\def\coloredstrut + {\color[strutcolor]{\def\strutwidth{2\points}\setstrut\strut}} + +\protect \endinput diff --git a/tex/context/base/trac-vis.mkiv b/tex/context/base/trac-vis.mkiv new file mode 100644 index 000000000..23ded2af9 --- /dev/null +++ b/tex/context/base/trac-vis.mkiv @@ -0,0 +1,748 @@ +%D \module +%D [ file=trac-vis, % was core-vis, +%D version=1996.06.01, +%D title=\CONTEXT\ Tracking Macros, +%D subtitle=Visualization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module adds some more visualization cues to the ones +%D supplied in the support module. +%D +%D %\everypar dual character, \the\everypar and \everypar= +%D %\hrule cannot be grabbed in advance, switches mode +%D %\vrule cannot be grabbed in advance, switches mode +%D % +%D %\indent only explicit ones +%D %\noindent only explicit ones +%D %\par only explicit ones +%D +%D %\leftskip only if explicit one +%D %\rightskip only if explicit one + +\writestatus{loading}{ConTeXt Tracking Macros / Visualization} + +\unprotect + +%D \macros +%D {indent, noindent, par} +%D +%D \TeX\ acts upon paragraphs. In mosts documents paragraphs +%D are separated by empty lines, which internally are handled as +%D \type{\par}. Paragraphs can be indented or not, depending on +%D the setting of \type{\parindent}, the first token of a +%D paragraph and/or user suppressed or forced indentation. +%D +%D Because the actual typesetting is based on both explicit +%D user and implicit system actions, visualization is only +%D possible for the user supplied \type{\indent}, +%D \type{\noindent}, and \type{\par}. Other +%D 'clever' tricks will quite certainly lead to more failures +%D than successes, so we only support these three explicit +%D primitives and one macro: + +\def\showparagraphcue#1#2#3#4#5% + {\bgroup + \scratchdimen#1\relax + \dontinterfere + \dontcomplain + \boxrulewidth5\testrulewidth + #3#4\relax + \setbox\scratchbox\normalhbox to \scratchdimen + {#2{\ruledhbox to \scratchdimen + {\vrule #5 20\testrulewidth \!!width \zeropoint + \normalhss}}}% + \smashbox\scratchbox + \normalpenalty\!!tenthousand + \box\scratchbox + \egroup} + +\def\ruledhanging + {\ifdim\hangindent>\zeropoint + \ifnum\hangafter<\zerocount + \normalhbox + {\boxrulewidth5\testrulewidth + \setbox\scratchbox\ruledhbox to \hangindent + {\scratchdimen\strutht + \advance\scratchdimen \strutdp + \vrule + \!!width \zeropoint + \!!height \zeropoint + \!!depth -\hangafter\scratchdimen}% + \normalhskip-\hangindent + \smashbox\scratchbox + \raise\strutht\box\scratchbox}% + \fi + \fi} + +\def\ruledparagraphcues + {\bgroup + \dontcomplain + \normalhbox to \zeropoint + {\ifdim\leftskip>\zeropoint\relax + \showparagraphcue\leftskip\llap\relax\relax\!!depth + \normalhskip-\leftskip + \fi + \ruledhanging + \normalhskip\hsize + \ifdim\rightskip>\zeropoint\relax + \normalhskip-\rightskip + \showparagraphcue\rightskip\relax\relax\relax\!!depth + \fi}% + \egroup} + +\def\ruledpar + {\relax + \ifhmode + \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\!!height + \fi + \normalpar} + +\def\rulednoindent + {\relax + \normalnoindent + \ruledparagraphcues + \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\!!height} + +\def\ruledindent + {\relax + \normalnoindent + \ruledparagraphcues + \ifdim\parindent>\zeropoint + \showparagraphcue\parindent\relax\relax\relax\!!height + \else + \showparagraphcue{40\testrulewidth}\llap\relax\relax\!!height + \fi + \normalhskip\parindent} + +\def\dontshowimplicits + {\let\noindent \normalnoindent + \let\indent \normalindent + \let\par \normalpar} + +\def\showimplicits + {\testrulewidth \defaulttestrulewidth + \let\noindent \rulednoindent + \let\indent \ruledindent + \let\par \ruledpar} + +%D The next few||line examples show the four cues. Keep in +%D mind that we only see them when we explicitly open or close +%D a paragraph. +%D +%D \bgroup +%D \def\voorbeeld#1% +%D {#1Visualizing some \TeX\ primitives and Plain \TeX\ +%D macros can be very instructive, at least it is to me. +%D Here we see {\tt\string#1} and {\tt\string\ruledpar} in +%D action, while {\tt\string\parindent} equals +%D {\tt\the\parindent}.\ruledpar} +%D +%D \showimplicits +%D +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D +%D \parindent=60pt +%D +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D +%D \startnarrower +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D \stopnarrower +%D \egroup +%D +%D These examples also demonstrate the visualization of +%D \type {\leftskip} and \type {\rightskip}. The macro +%D \type {\nofruledbaselines} determines the number of lines +%D shown. + +\newcounter\ruledbaselines + +\def\nofruledbaselines{3} + +\def\debuggertext#1% + {\ifx\ttxx\undefined + $\scriptscriptstyle#1$% + \else + {\ttxx#1}% + \fi} + +\def\ruledbaseline + {\vrule \!!width \zeropoint + \bgroup + \dontinterfere + \doglobal\increment\ruledbaselines + \scratchdimen\nofruledbaselines\baselineskip + \setbox\scratchbox\normalvbox to 2\scratchdimen + {\leaders + \normalhbox + {\strut + \vrule + \!!height \testrulewidth + \!!depth \testrulewidth + \!!width 120\points} + \normalvfill}% + \smashbox\scratchbox + \advance\scratchdimen \strutheightfactor\baselineskip + \setbox\scratchbox\normalhbox + {\normalhskip -48\points + \normalhbox to 24\points + {\normalhss\debuggertext\ruledbaselines\normalhskip6\points}% + \raise\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox + \egroup} + +\def\showbaselines + {\testrulewidth\defaulttestrulewidth + \EveryPar{\ruledbaseline}} + +%D \macros +%D {showpagebuilder} +%D +%D The next tracing option probaly is only of use to me and a +%D few \CONTEXT\ hackers. + +\def\showpagebuilder + {\EveryPar{\doshowpagebuilder}} + +\def\doshowpagebuilder + {\strut\llap + {\startcolor[blue]\vl + \high{\infofont v:\the\vsize }\vl + \high{\infofont g:\the\pagegoal }\vl + \high{\infofont t:\the\pagetotal}\vl + \stopcolor}} + +%D \macros +%D {makecutbox, cuthbox, cutvbox, cutvtop} +%D +%D Although mainly used for marking the page, these macros can +%D also serve local use. +%D +%D \startbuffer +%D \setbox0=\vbox{a real \crlf vertical box} \makecutbox0 +%D \stopbuffer +%D +%D \typebuffer +%D +%D This marked \type{\vbox} shows up as: +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection +%D +%D The alternative macros are used as: +%D +%D \startbuffer +%D \cuthbox{a made cut box} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This is typeset as: +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection +%D +%D By setting the next macros one can influence the length of +%D the marks as well as the horizontal and vertical divisions. + +\def\cutmarklength {2\bodyfontsize} +\chardef\horizontalcutmarks = 2 +\chardef\verticalcutmarks = 2 +\chardef\cutmarkoffset = 1 +\let\cutmarksymbol = \relax +\let\cutmarktoptext = \empty +\let\cutmarkbottomtext = \empty + +\def\horizontalcuts + {\normalhbox to \ruledwidth + {\dorecurse\horizontalcutmarks + {\vrule\!!width\boxrulewidth\!!height\cutmarklength\normalhfill}% + \unskip}} + +\def\verticalcuts + {\scratchdimen\ruledheight + \advance\scratchdimen \ruleddepth + \normalvbox to \scratchdimen + {\hsize\cutmarklength + \dorecurse\verticalcutmarks + {\vrule\!!height\boxrulewidth\!!width\hsize\normalvfill}% + \unskip}} + +\def\baselinecuts + {\ifdim\ruleddepth>\zeropoint + \scratchdimen\ruledheight + \advance\scratchdimen \ruleddepth + \normalvbox to \scratchdimen + {\scratchdimen\cutmarklength + \divide\scratchdimen 2 + \hsize\scratchdimen + \normalvskip\zeropoint\!!plus\ruledheight + \vrule\!!height\boxrulewidth\!!width\hsize + \normalvskip\zeropoint\!!plus\ruleddepth}% + \fi} + +\def\cutmarksymbols#1% + {\normalhbox to \ruledwidth + {\setbox\scratchbox\normalhbox to \cutmarklength + {\normalhss\infofont\cutmarksymbol\normalhss}% + \normalhss + \normalvbox to \cutmarklength + {\scratchdimen\cutmarklength + \divide\scratchdimen \plustwo + \normalvss + \hbox to \ruledwidth + {\llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% + \normalhskip\scratchdimen\hss\infofont#1\hss\normalhskip\scratchdimen + \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% + \normalvss}% + \normalhss}} + +\def\makecutbox#1% simplier with layers, todo + {\edef\ruledheight{\the\ht#1}% + \edef\ruleddepth {\the\dp#1}% + \edef\ruledwidth {\the\wd#1}% + \setbox#1\normalhbox + {\dontcomplain + \forgetall + \boxmaxdepth\maxdimen + \offinterlineskip + \scratchdimen\cutmarklength + \divide\scratchdimen \plustwo + \hsize\ruledwidth + \setbox\scratchbox\normalvbox + {\setbox\scratchbox\normalhbox{\horizontalcuts}% + \normalvskip-\cutmarkoffset\scratchdimen + \normalvskip-2\scratchdimen + \copy\scratchbox + \normalvskip\cutmarkoffset\scratchdimen + \hbox to \ruledwidth + {\setbox\scratchbox\normalhbox{\verticalcuts}% + \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% + \bgroup + \setbox\scratchbox\normalhbox{\baselinecuts}% + \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% + \normalhfill + \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}% + \egroup + \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% + \normalvskip\cutmarkoffset\scratchdimen + \copy\scratchbox}% + \ht\scratchbox\ruledheight + \dp\scratchbox\ruleddepth + \wd\scratchbox\zeropoint + \resetcolorseparation + \localstartcolor[\defaulttextcolor]% + \box\scratchbox + \ifx\cutmarksymbol\relax \else + \setbox\scratchbox\normalvbox + {\vskip-\cutmarkoffset\scratchdimen + \vskip-\cutmarklength + \normalhbox{\cutmarksymbols\cutmarktoptext}% + \vskip\cutmarkoffset\scratchdimen + \vskip\ruledheight + \vskip\ruleddepth + \vskip\cutmarkoffset\scratchdimen + \normalhbox{\cutmarksymbols\cutmarkbottomtext}}% + \ht\scratchbox\ruledheight + \dp\scratchbox\ruleddepth + \wd\scratchbox\zeropoint + \box\scratchbox + \fi + \localstopcolor + \box#1}% + \wd#1=\ruledwidth + \ht#1=\ruledheight + \dp#1=\ruleddepth} + +\def\cuthbox + {\normalhbox\bgroup + \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalhbox} + +\def\cutvbox + {\normalvbox\bgroup + \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvbox} + +\def\cutvtop + {\normalvtop\bgroup + \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvtop} + +%D \macros +%D {colormarkbox,rastermarkbox} +%D +%D This macro is used in the pagebody routine. No other use +%D is advocated here. +%D +%D \starttyping +%D \colormarkbox0 +%D \stoptyping + +\def\colormarkoffset{\cutmarkoffset} +\def\colormarklength{\cutmarklength} + +\def\colorrangeA#1#2#3#4% + {\vbox + {\scratchdimen-\colormarklength + \multiply\scratchdimen 4 + \advance\scratchdimen \ruledheight + \advance\scratchdimen \ruleddepth + \divide\scratchdimen 21 + \def\docommand##1% + {\vbox + {\hsize3em % \scratchdimen + \definecolor + [\s!dummy] + [\c!c=#2##1\else0\fi, + \c!m=#3##1\else0\fi, + \c!y=#4##1\else0\fi, + \c!k=0]% + \localstartcolor[\s!dummy]% + \hrule + \!!width 3em + \!!height \scratchdimen + \!!depth \zeropoint + \localstopcolor + \ifdim\scratchdimen>1ex + \vskip-\scratchdimen + \vbox to \scratchdimen + {\vss + \hbox to 3em + {\hss + \localstartcolor[\s!white]% + \ifdim##1\points=\zeropoint#1\else##1\fi + \localstopcolor + \hss}% + \vss}% + \fi}}% + \offinterlineskip + \processcommalist[1.00,0.95,0.75,0.50,0.25,0.05,0.00]\docommand}} + +\def\colorrangeB + {\hbox + {\scratchdimen-\colormarklength + \multiply\scratchdimen \plustwo + \advance\scratchdimen \ruledwidth + \divide\scratchdimen 11 + \def\docommand ##1 ##2 ##3##4##5##6% + {\definecolor + [\s!dummy] + [\c!c=##3##2\else0\fi, + \c!m=##4##2\else0\fi, + \c!y=##5##2\else0\fi, + \c!k=##6##2\else0\fi]% + \localstartcolor[\s!dummy]% + \vrule + \!!width \scratchdimen + \!!height \colormarklength + \!!depth \zeropoint + \localstopcolor + \ifdim\scratchdimen>2em + \hskip-\scratchdimen + \vbox to \colormarklength + {\vss + \hbox to \scratchdimen + {\hss + \localstartcolor[\s!white]% + \ifdim##2\points=.5\points##2~\fi##1% + \localstopcolor + \hss} + \vss}% + \fi}% + \docommand C .5 \iftrue \iffalse\iffalse\iffalse + \docommand M .5 \iffalse\iftrue \iffalse\iffalse + \docommand Y .5 \iffalse\iffalse\iftrue \iffalse + \docommand K .5 \iffalse\iffalse\iffalse\iftrue + \docommand C 1 \iftrue \iffalse\iffalse\iffalse + \docommand G 1 \iftrue \iffalse\iftrue \iffalse + \docommand Y 1 \iffalse\iffalse\iftrue \iffalse + \docommand R 1 \iffalse\iftrue \iftrue \iffalse + \docommand M 1 \iffalse\iftrue \iffalse\iffalse + \docommand B 1 \iftrue \iftrue \iffalse\iffalse + \docommand K 1 \iffalse\iffalse\iffalse\iftrue}} + +\def\colorrangeC + {\hbox + {\resetcolorseparation + \scratchdimen-\colormarklength + \multiply\scratchdimen 2 + \advance\scratchdimen \ruledwidth + \divide\scratchdimen 14 + \def\docommand##1% + {\definecolor[\s!dummy][\c!s=##1]% + \localstartcolor[\s!dummy]% + \vrule + \!!width \scratchdimen + \!!height \colormarklength + \!!depth \zeropoint + \localstopcolor + \ifdim\scratchdimen>2em + \hskip-\scratchdimen + \vbox to \colormarklength + {\vss + \localstartcolor[\s!white]% + \hbox to \scratchdimen{\hss##1\hss} + \localstopcolor + \vss}% + \fi}% + \processcommalist[1,.95,.9,.85,.8,.75,.7,.6,.5,.4,.3,.2,.1,0]\docommand}} + +\def\docolormarkbox#1#2% + {\edef\ruledheight{\the\ht#2}% + \edef\ruleddepth {\the\dp#2}% + \edef\ruledwidth {\the\wd#2}% + \setbox#2\hbox + {\scratchdimen\colormarklength + \divide\scratchdimen \plustwo + \forgetall + \ssxx + \setbox\scratchbox\vbox + {\offinterlineskip + \vskip-\colormarkoffset\scratchdimen + \vskip-2\scratchdimen\relax % relax needed + % beware: no \ifcase, due to nested \iftrue/\iffalse + % and lacking \fi's + \doifelse{#1}{0}% + {\vskip\colormarklength + \vskip\colormarkoffset\scratchdimen + \vskip\ruledheight} + {\hbox to \ruledwidth{\hss\hbox{\colorrangeB}\hss}% + \vskip\colormarkoffset\scratchdimen + \vbox to \ruledheight + {\vss + \hbox to \ruledwidth + {\llap{\colorrangeA C\iftrue\iffalse\iffalse\hskip\colormarkoffset\scratchdimen}% + \hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA R\iffalse\iftrue\iftrue}}% + \vss + \hbox to \ruledwidth + {\llap{\colorrangeA M\iffalse\iftrue\iffalse\hskip\colormarkoffset\scratchdimen}% + \hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA G\iftrue\iffalse\iftrue}}% + \vss + \hbox to \ruledwidth + {\llap{\colorrangeA Y\iffalse\iffalse\iftrue\hskip\colormarkoffset\scratchdimen}% + \hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA B\iftrue\iftrue\iffalse}}% + \vss}}% + \vskip\colormarkoffset\scratchdimen + \hbox to \ruledwidth + {\hss\lower\ruleddepth\hbox{\colorrangeC}\hss}}% + \ht\scratchbox\ruledheight + \dp\scratchbox\ruleddepth + \wd\scratchbox\zeropoint + \box\scratchbox + \box#2}% + \wd#2=\ruledwidth + \ht#2=\ruledheight + \dp#2=\ruleddepth} + +\def\colormarkbox % #1 + {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi1} + +\def\rastermarkbox % #1 + {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi0} + +%D \macros +%D {showwhatsits, dontshowwhatsits} +%D +%D \TEX\ has three so called whatsits: \type {\mark}, \type +%D {\write} and \type {\special}. The first one keeps track of +%D the current state at page boundaries, the last two are used +%D to communicate to the outside world. Due to fact that +%D especially \type {\write} is often used in conjunction with +%D \type {\edef}, we can only savely support that one in \ETEX. +%D +%D \bgroup \showwhatsits \setupcolors[state=start] +%D +%D Whatsits show up \color[blue]{in color} and are +%D characterized bij their first character.\footnote [some note] +%D {So we may encounter \type {w}, \type {m} and \type{s}.} +%D They are \writestatus{dummy}{demo}\color[yellow]{stacked}. +%D +%D \egroup + +\newif\ifimmediatewrite + +\ifx\eTeXversion\undefined + + \let\showwhatsits \relax + \let\dontshowwhatsits\relax + +\else + + \let\supernormalmark \normalmark % mark may already been superseded + \let\supernormalmarks \normalmarks % mark may already been superseded + + \def\showwhatsits + {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }% + \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% + \protected\def\special {\visualwhatsit0100s\normalspecial }% + \protected\def\write {\visualwhatsit001-w\normalwrite }% + \let\immediate\immediatewhatsit + \appendtoks\dontshowwhatsits\to\everystoptext} + + \def\immediatewhatsit + {\bgroup\futurelet\next\doimmediatewhatsit} + + \def\doimmediatewhatsit + {\ifx\next\write + \egroup\immediatewritetrue + \else + \egroup\expandafter\normalimmediate + \fi} + + \def\dontshowwhatsits + {\let\immediate \normalimmediate + \let\normalmark\supernormalmark + \let\special \normalspecial + \let\write \normalwrite} + + \def\visualwhatsit#1#2#3#4#5% + {\bgroup + \pushwhatsit + \dontinterfere + \dontcomplain + \dontshowcomposition + \dontshowwhatsits + \ttx + \ifvmode\donetrue\else\donefalse\fi + \setbox\scratchbox\hbox + {\ifdone\dostartgraycolormode0\else\dostartrgbcolormode#1#2#3\fi + #5\dostopcolormode}% + \setbox\scratchbox\hbox + {\ifdone\dostartrgbcolormode#1#2#3\else\dostartgraycolormode0\fi + \vrule\!!width\wd\scratchbox\dostopcolormode + \hskip-\wd\scratchbox\box\scratchbox}% + \scratchdimen1ex + \setbox\scratchbox\hbox + {\ifdone\hskip\else\raise#4\fi\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \ifdone\nointerlineskip\fi + \box\scratchbox + \ifvmode\nointerlineskip\fi + \popwhatsit + \egroup + \ifimmediatewrite + \immediatewritefalse + \expandafter\normalimmediate + \fi} + + \def\pushwhatsit + {\ifzeropt\lastskip + \ifcase\lastpenalty + \ifzeropt\lastkern + \ifhmode + \let\popwhatsit\relax + \else + \edef\popwhatsit{\prevdepth\the\prevdepth}% + \fi + \else + \ifhmode + \edef\popwhatsit{\kern\the\lastkern}\unkern + \else + \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth}% + \kern-\lastkern + \fi + \fi + \else + \ifhmode + \edef\popwhatsit{\the\lastpenalty}% + \unpenalty + \else + \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}% + %\nobreak + \fi + \fi + \else + \ifhmode + \edef\popwhatsit{\hskip\the\lastskip}\unskip + \else + \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth}% + \vskip-\lastskip + \fi + \fi} + +\fi + +%D The next macro can be used to keep track of classes of +%D boxes (handy for development cq.\ tracing). + +\def\dodotagbox#1#2#3% can be reimplemented + {\def\next##1##2##3##4% + {\vbox to \ht#2{##3\hbox to \wd#2{##1#3##2}##4}}% + \processaction + [#1] + [ l=>\next\relax\hfill\vfill\vfill, + r=>\next\hfill\relax\vfill\vfill, + t=>\next\hfill\hfill\relax\vfill, + b=>\next\hfill\hfill\vfill\relax, + lt=>\next\relax\hfill\relax\vfill, + lb=>\next\relax\hfill\vfill\relax, + rt=>\next\hfill\relax\relax\vfill, + rb=>\next\hfill\relax\vfill\relax, + tl=>\next\relax\hfill\relax\vfill, + bl=>\next\relax\hfill\vfill\relax, + tr=>\next\hfill\relax\relax\vfill, + br=>\next\hfill\relax\vfill\relax, + \s!default=>\next\hfill\hfill\vfill\vfill, + \s!unknown=>\next\hfill\hfill\vfill\vfill]} + +\def\dotagbox[#1]#2% + {\bgroup + \dowithnextbox + {\setbox\scratchbox\flushnextbox + \setbox\nextbox\ifhbox\nextbox\hbox\else\vbox\fi + \bgroup + \startoverlay + {\copy\scratchbox} + {\dodotagbox{#1}\scratchbox{\framed + [\c!background=\v!screen,\c!backgroundscreen=1]{#2}}} + \stopoverlay + \egroup + \nextboxwd\the\wd\scratchbox + \nextboxht\the\ht\scratchbox + \nextboxdp\the\dp\scratchbox + \flushnextbox + \egroup}} + +\def\tagbox + {\dosingleempty\dotagbox} + +%D \macros +%D {coloredhbox,coloredvbox,coloredvtop, +%D coloredstrut} +%D +%D The following visualizations are used in some of the manuals: + +\definecolor[boxcolor:ht][r=.5,g=.75,b=.5] +\definecolor[boxcolor:dp][r=.5,g=.5,b=.75] +\definecolor[boxcolor:wd][r=.75,g=.5,b=.5] +\definecolor[strutcolor] [r=.5,g=.25,b=.25] + +\def\coloredbox#1% + {\dowithnextbox{#1{\hbox + {\blackrule[\c!width=\nextboxwd,\c!height=\nextboxht,\c!depth=\zeropoint,\c!color=boxcolor:ht]% + \hskip-\nextboxwd + \blackrule[\c!width=\nextboxwd,\c!height=\zeropoint,\c!depth=\nextboxdp,\c!color=boxcolor:dp]% + \hskip-\nextboxwd + \box\nextbox}}}#1} + +\def\coloredhbox{\coloredbox\hbox} +\def\coloredvbox{\coloredbox\vbox} +\def\coloredvtop{\coloredbox\vtop} + +\def\coloredstrut + {\color[strutcolor]{\def\strutwidth{2\points}\setstrut\strut}} + +\protect \endinput diff --git a/tex/context/base/typo-brk.mkiv b/tex/context/base/typo-brk.mkiv new file mode 100644 index 000000000..90561fc9e --- /dev/null +++ b/tex/context/base/typo-brk.mkiv @@ -0,0 +1,77 @@ +%D \module +%D [ file=typo-brk, +%D version=2009.03.27, % code moved from core-spa.mkiv +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Breakpoints, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Breakpoints} + +\unprotect + +\registerctxluafile{typo-brk}{1.001} + +\definesystemattribute[breakpoint] + +% compound stuff (under construction) + +\newbox\breakpointbox + +\definesystemvariable {bp} % BreakPoint + +\exhyphenchar=\minusone % we use a different order then base tex, so we really need this + +\newcount \maxbreakpointsid + +\def\definebreakpoints + {\dosingleargument\dodefinebreakpoints} + +\def\dodefinebreakpoints[#1]% + {\ifcsname\??bp:#1\endcsname \else + \global\advance\maxbreakpointsid\plusone + \setxvalue{\??bp:#1}{\the\maxbreakpointsid}% + \fi} + +\def\installbreakpoint + {\dotripleempty\doinstallbreakpoint} + +% hm, we cannot prebuild lists, font dependent + +\def\doinstallbreakpoint[#1][#2][#3]% + {\ifcsname\??bp:#1\endcsname + \begingroup + \getparameters[\??bp][\c!type=1,\c!nleft=3,\c!nright=3,\s!language=,#3]% + \ctxlua{breakpoints.setreplacement(\csname\??bp:#1\endcsname,#2,\@@bptype,\@@bpnleft,\@@bpnright,"\@@bplanguage")}% + \endgroup + \fi} + +\def\setbreakpoints + {\ctxlua{breakpoints.enabled=true}% + \gdef\setbreakpoints[##1]{\dosetattribute{breakpoint}{\csname\??bp:##1\endcsname}}% + \setbreakpoints} + +\letvalue{\??bp:\s!reset}\attributeunsetvalue + +\definebreakpoints[compound] + +\installbreakpoint [compound] [\number`+] [\c!left=3,\c!right=3,\c!type=1] +\installbreakpoint [compound] [\number`-] [\c!left=3,\c!right=3,\c!type=1] +\installbreakpoint [compound] [\number`/] [\c!left=3,\c!right=3,\c!type=1] +\installbreakpoint [compound] [\number`(] [\c!left=3,\c!right=3,\c!type=2] +\installbreakpoint [compound] [\number`)] [\c!left=3,\c!right=3,\c!type=3] + +% \mainlanguage[czech] +% \installbreakpoint [compound] [\number`-] [language=cs,left=3,right=3,type=4] +% \setbreakpoints[compound] +% \start \hsize 1mm test-test \par \stop + +% \setbreakpoints[compound] + +\protect \endinput + diff --git a/tex/context/base/typo-brk.tex b/tex/context/base/typo-brk.tex deleted file mode 100644 index 90561fc9e..000000000 --- a/tex/context/base/typo-brk.tex +++ /dev/null @@ -1,77 +0,0 @@ -%D \module -%D [ file=typo-brk, -%D version=2009.03.27, % code moved from core-spa.mkiv -%D title=\CONTEXT\ Typesetting Macros, -%D subtitle=Breakpoints, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Typesetting Macros / Breakpoints} - -\unprotect - -\registerctxluafile{typo-brk}{1.001} - -\definesystemattribute[breakpoint] - -% compound stuff (under construction) - -\newbox\breakpointbox - -\definesystemvariable {bp} % BreakPoint - -\exhyphenchar=\minusone % we use a different order then base tex, so we really need this - -\newcount \maxbreakpointsid - -\def\definebreakpoints - {\dosingleargument\dodefinebreakpoints} - -\def\dodefinebreakpoints[#1]% - {\ifcsname\??bp:#1\endcsname \else - \global\advance\maxbreakpointsid\plusone - \setxvalue{\??bp:#1}{\the\maxbreakpointsid}% - \fi} - -\def\installbreakpoint - {\dotripleempty\doinstallbreakpoint} - -% hm, we cannot prebuild lists, font dependent - -\def\doinstallbreakpoint[#1][#2][#3]% - {\ifcsname\??bp:#1\endcsname - \begingroup - \getparameters[\??bp][\c!type=1,\c!nleft=3,\c!nright=3,\s!language=,#3]% - \ctxlua{breakpoints.setreplacement(\csname\??bp:#1\endcsname,#2,\@@bptype,\@@bpnleft,\@@bpnright,"\@@bplanguage")}% - \endgroup - \fi} - -\def\setbreakpoints - {\ctxlua{breakpoints.enabled=true}% - \gdef\setbreakpoints[##1]{\dosetattribute{breakpoint}{\csname\??bp:##1\endcsname}}% - \setbreakpoints} - -\letvalue{\??bp:\s!reset}\attributeunsetvalue - -\definebreakpoints[compound] - -\installbreakpoint [compound] [\number`+] [\c!left=3,\c!right=3,\c!type=1] -\installbreakpoint [compound] [\number`-] [\c!left=3,\c!right=3,\c!type=1] -\installbreakpoint [compound] [\number`/] [\c!left=3,\c!right=3,\c!type=1] -\installbreakpoint [compound] [\number`(] [\c!left=3,\c!right=3,\c!type=2] -\installbreakpoint [compound] [\number`)] [\c!left=3,\c!right=3,\c!type=3] - -% \mainlanguage[czech] -% \installbreakpoint [compound] [\number`-] [language=cs,left=3,right=3,type=4] -% \setbreakpoints[compound] -% \start \hsize 1mm test-test \par \stop - -% \setbreakpoints[compound] - -\protect \endinput - diff --git a/tex/context/base/typo-cap.mkiv b/tex/context/base/typo-cap.mkiv new file mode 100644 index 000000000..45a932200 --- /dev/null +++ b/tex/context/base/typo-cap.mkiv @@ -0,0 +1,204 @@ +%D \module +%D [ file=typo-cap, +%D version=2009.03.27, % code moved from core-spa.mkiv +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Mirroring, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Caps} + +\unprotect + +\registerctxluafile{typo-cap}{1.001} + +\definesystemattribute[case] + +%D \macros +%D {Word, Words, WORD, WORDS} +%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} + +% test \WORD{test TEST \TeX} test +% test \word{test TEST \TeX} test +% test \Word{test TEST \TeX} test + +\def\setcharactercasing + {\ctxlua{cases.enabled=true}% + \gdef\setcharactercasing[##1]{\dosetattribute{case}{\number##1}}% + \setcharactercasing} + +\unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\plusone ]}{}} +\unexpanded\def\word {\groupedcommand{\setcharactercasing[\plustwo ]}{}} +\unexpanded\def\Word {\groupedcommand{\setcharactercasing[\plusthree]}{}} +\unexpanded\def\Words{\groupedcommand{\setcharactercasing[\plusfour ]}{}} + +\let\WORDS\WORD +\let\words\word + +%D \macros +%D {kap,KAP,Kap,Kaps,nokap,userealcaps,usepseudocaps} +%D +%D We already introduced \type{\cap} as way to capitalize +%D words. This command comes in several versions: +%D +%D \startbuffer +%D \cap {let's put on a \cap{cap}} +%D \cap {let's put on a \nocap{cap}} +%D \CAP {let's put on a \\{cap}} +%D \Cap {let's put on a \\{cap}} +%D \Caps{let's put on a cap} +%D \stopbuffer +%D +%D \typebuffer +%D +%D Note the use of \type{\nocap}, \type{\\} and the nested +%D \type{\cap}. +%D +%D \startvoorbeeld +%D \startlines +%D \getbuffer +%D \stoplines +%D \stopvoorbeeld +%D +%D These macros show te main reason why we introduced the +%D smaller \type{\tx} and \type{\txx}. +%D +%D \starttyping +%D \cap\romannumerals{1995} +%D \stoptyping +%D +%D This at first sight unusual capitilization is completely +%D legal. +%D +%D \showsetup{smallcapped} +%D \showsetup{notsmallcapped} +%D \showsetup{CAPPED} +%D \showsetup{SmallCapped} +%D \showsetup{SmallCaps} +%D +%D The difference between pseudo and real caps is demonstrated +%D below: +%D +%D \startbuffer +%D \usepseudocaps \cap{Hans Hagen} +%D \userealcaps \cap{Hans Hagen} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D The \type {\bgroup} trickery below is needed because of +%D \type {\groupedcommand}. + +\let\disablepseudocaps\relax % maybe used elsewhere + +\newconditional\pseudocapsenabled + +\def\usepseudocaps{\settrue \pseudocapsenabled} +\def\userealcaps {\setfalse\pseudocapsenabled} + +\usepseudocaps + +% we use char0 as placeholder for the larger font + +\unexpanded\def\pseudosmallcapped{\groupedcommand{\setcharactercasing[\plusone ]\char\zerocount\tx}{}} % all upper +\unexpanded\def\pseudoSmallcapped{\groupedcommand{\setcharactercasing[\plusfive]\char\zerocount\tx}{}} % one upper + font +\unexpanded\def\pseudoSmallCapped{\groupedcommand{\setcharactercasing[\plussix ]\char\zerocount\tx}{}} % some upper + font + +\unexpanded\def\realsmallcapped {\groupedcommand{\sc\setcharactercasing[\plusone ]}{}} % all lower +\unexpanded\def\realSmallcapped {\groupedcommand{\sc\setcharactercasing[\plusthree]}{}} % one upper + font +\unexpanded\def\realSmallCapped {\groupedcommand{\sc\setcharactercasing[\plusfour ]}{}} % some upper + +\unexpanded\def\dohandlesmallcaps + {\ifconditional\pseudocapsenabled + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\unexpanded\def\smallcapped{\dohandlesmallcaps\pseudosmallcapped\realsmallcapped} +\unexpanded\def\Smallcapped{\dohandlesmallcaps\pseudoSmallcapped\realSmallcapped} +\unexpanded\def\SmallCapped{\dohandlesmallcaps\pseudoSmallCapped\realSmallCapped} + +\unexpanded\def\autocap{\ifmmode\expandafter\normalcap\else\expandafter\smallcapped\fi} + +\appendtoks + \let\normalcap\cap % mathmode cap + \let\cap\autocap +\to \everydump + +\let\kap\cap % for old times sake +\let\Caps\SmallCapped % for old times sake + +\let\normalsmallcapped\smallcapped +\let\normalWORD \WORD +\let\normalword \word + +%D \macros +%D {setupcapitals} +%D +%D By default we use pseudo small caps in titles. This can be +%D set up with: +%D +%D \showsetup{setupcapitals} + +\let\normalsmallcapped\smallcapped + +\def\setupcapitals + {\dosingleempty\dosetupcapitals} + +\def\dosetupcapitals[#1]% + {\getparameters[\??kk][#1]% + \doifelse\@@kktitle\v!yes + {\definealternativestyle[\v!capital][\normalsmallcapped][\normalsmallcapped]% + \definealternativestyle[\v!smallcaps][\sc][\sc]} + {\definealternativestyle[\v!capital][\normalsmallcapped][\normalWORD]% + \definealternativestyle[\v!smallcaps][\sc][\normalWORD]}% + \doifelse\@@kksc\v!yes\userealcaps\usepseudocaps} + +\let\uppercased\normalWORD +\let\lowercased\normalword + +\setupcapitals + [\c!title=\v!yes, + \c!sc=\v!no] + +% \definestartstop is not yet in available at core-spa time +% +% \startrandomized \input tufte \stoprandomized +% +% \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=] + +\def\randomizetext{\groupedcommand{\dosetattribute{case}{8}}{}} + +\protect \endinput diff --git a/tex/context/base/typo-cap.tex b/tex/context/base/typo-cap.tex deleted file mode 100644 index 49ca64957..000000000 --- a/tex/context/base/typo-cap.tex +++ /dev/null @@ -1,214 +0,0 @@ -%D \module -%D [ file=typo-cap, -%D version=2009.03.27, % code moved from core-spa.mkiv -%D title=\CONTEXT\ Typesetting Macros, -%D subtitle=Mirroring, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Typesetting Macros / Caps} - -\unprotect - -\registerctxluafile{typo-cap}{1.001} - -\definesystemattribute[case] - -%D \macros -%D {Word, Words, WORD, WORDS, doprocesswords} -%D -%D This is probably not the right place to present the next set -%D of macros. -%D -%D \starttyping -%D \Word {far too many words} -%D \Words{far too many words} -%D \WORD {far too many words} -%D \WORDS{far too many words} -%D \stoptyping -%D -%D \typebuffer -%D -%D This calls result in: -%D -%D \startvoorbeeld -%D \startlines -%D \getbuffer -%D \stoplines -%D \stopvoorbeeld -%D -%D \showsetup{Word} -%D \showsetup{Words} -%D \showsetup{WORD} -%D \showsetup{WORDS} - -% \def\doprocesswords#1 #2\od -% {\ConvertToConstant\doifnot{#1}{} -% {\processword{#1} % -% \doprocesswords#2 \od}} -% -% \def\processwords#1% -% {\doprocesswords#1 \od\unskip} -% -% \let\processword\relax - -% test \WORD{test TEST \TeX} test -% test \word{test TEST \TeX} test -% test \Word{test TEST \TeX} test - -\def\setcharactercasing - {\ctxlua{cases.enabled=true}% - \gdef\setcharactercasing[##1]{\dosetattribute{case}{\number##1}}% - \setcharactercasing} - -\unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\plusone ]}{}} -\unexpanded\def\word {\groupedcommand{\setcharactercasing[\plustwo ]}{}} -\unexpanded\def\Word {\groupedcommand{\setcharactercasing[\plusthree]}{}} -\unexpanded\def\Words{\groupedcommand{\setcharactercasing[\plusfour ]}{}} - -\let\WORDS\WORD -\let\words\word - -%D \macros -%D {kap,KAP,Kap,Kaps,nokap,userealcaps,usepseudocaps} -%D -%D We already introduced \type{\cap} as way to capitalize -%D words. This command comes in several versions: -%D -%D \startbuffer -%D \cap {let's put on a \cap{cap}} -%D \cap {let's put on a \nocap{cap}} -%D \CAP {let's put on a \\{cap}} -%D \Cap {let's put on a \\{cap}} -%D \Caps{let's put on a cap} -%D \stopbuffer -%D -%D \typebuffer -%D -%D Note the use of \type{\nocap}, \type{\\} and the nested -%D \type{\cap}. -%D -%D \startvoorbeeld -%D \startlines -%D \getbuffer -%D \stoplines -%D \stopvoorbeeld -%D -%D These macros show te main reason why we introduced the -%D smaller \type{\tx} and \type{\txx}. -%D -%D \starttyping -%D \cap\romannumerals{1995} -%D \stoptyping -%D -%D This at first sight unusual capitilization is completely -%D legal. -%D -%D \showsetup{smallcapped} -%D \showsetup{notsmallcapped} -%D \showsetup{CAPPED} -%D \showsetup{SmallCapped} -%D \showsetup{SmallCaps} -%D -%D The difference between pseudo and real caps is demonstrated -%D below: -%D -%D \startbuffer -%D \usepseudocaps \cap{Hans Hagen} -%D \userealcaps \cap{Hans Hagen} -%D \stopbuffer -%D -%D \typebuffer -%D -%D \getbuffer -%D -%D The \type {\bgroup} trickery below is needed because of -%D \type {\groupedcommand}. - -\let\disablepseudocaps\relax % maybe used elsewhere - -\newconditional\pseudocapsenabled - -\def\usepseudocaps{\settrue \pseudocapsenabled} -\def\userealcaps {\setfalse\pseudocapsenabled} - -\usepseudocaps - -% we use char0 as placeholder for the larger font - -\unexpanded\def\pseudosmallcapped{\groupedcommand{\setcharactercasing[\plusone ]\char\zerocount\tx}{}} % all upper -\unexpanded\def\pseudoSmallcapped{\groupedcommand{\setcharactercasing[\plusfive]\char\zerocount\tx}{}} % one upper + font -\unexpanded\def\pseudoSmallCapped{\groupedcommand{\setcharactercasing[\plussix ]\char\zerocount\tx}{}} % some upper + font - -\unexpanded\def\realsmallcapped {\groupedcommand{\sc\setcharactercasing[\plusone ]}{}} % all lower -\unexpanded\def\realSmallcapped {\groupedcommand{\sc\setcharactercasing[\plusthree]}{}} % one upper + font -\unexpanded\def\realSmallCapped {\groupedcommand{\sc\setcharactercasing[\plusfour ]}{}} % some upper - -\unexpanded\def\dohandlesmallcaps - {\ifconditional\pseudocapsenabled - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\unexpanded\def\smallcapped{\dohandlesmallcaps\pseudosmallcapped\realsmallcapped} -\unexpanded\def\Smallcapped{\dohandlesmallcaps\pseudoSmallcapped\realSmallcapped} -\unexpanded\def\SmallCapped{\dohandlesmallcaps\pseudoSmallCapped\realSmallCapped} - -\unexpanded\def\autocap{\ifmmode\expandafter\normalcap\else\expandafter\smallcapped\fi} - -\appendtoks - \let\normalcap\cap % mathmode cap - \let\cap\autocap -\to \everydump - -\let\kap\cap % for old times sake -\let\Caps\SmallCapped % for old times sake - -\let\normalsmallcapped\smallcapped -\let\normalWORD \WORD -\let\normalword \word - -%D \macros -%D {setupcapitals} -%D -%D By default we use pseudo small caps in titles. This can be -%D set up with: -%D -%D \showsetup{setupcapitals} - -\let\normalsmallcapped\smallcapped - -\def\setupcapitals - {\dosingleempty\dosetupcapitals} - -\def\dosetupcapitals[#1]% - {\getparameters[\??kk][#1]% - \doifelse\@@kktitle\v!yes - {\definealternativestyle[\v!capital][\normalsmallcapped][\normalsmallcapped]% - \definealternativestyle[\v!smallcaps][\sc][\sc]} - {\definealternativestyle[\v!capital][\normalsmallcapped][\normalWORD]% - \definealternativestyle[\v!smallcaps][\sc][\normalWORD]}% - \doifelse\@@kksc\v!yes\userealcaps\usepseudocaps} - -\let\uppercased\normalWORD -\let\lowercased\normalword - -\setupcapitals - [\c!title=\v!yes, - \c!sc=\v!no] - -% \definestartstop is not yet in available at core-spa time -% -% \startrandomized \input tufte \stoprandomized -% -% \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=] - -\def\randomizetext{\groupedcommand{\dosetattribute{case}{8}}{}} - -\protect \endinput diff --git a/tex/context/base/typo-ini.mkii b/tex/context/base/typo-ini.mkii new file mode 100644 index 000000000..1317021ef --- /dev/null +++ b/tex/context/base/typo-ini.mkii @@ -0,0 +1,40 @@ +%D \module +%D [ file=typo-ini, +%D version=2000.16.09, +%D title=\CONTEXT\ Typographic 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 Since \CONTEXT\ is dealing with typographics, isn't +%D September 2000 a bit late to start writing this module? It +%D may seem so, but since more and more languages are +%D supported, we think it is time to isolate language specific +%D typographic extensions in modules. The first language that +%D demands this is Chinese, and more will follow. + +\writestatus{loading}{ConTeXt Typographic Macros / Initialization} + +\unprotect + +%D \macros +%D {ifvertical} +%D +%D The following switch can be used to signal macros that they +%D should adapt their behaviour. + +\newif\ifvertical % maybe also ifreverse + +%D \macros +%D {vhbox} +%D +%D A stupid but useful macro. + +\def\vhbox{\ifvertical\vbox\else\hbox\fi} + +\protect \endinput diff --git a/tex/context/base/typo-ini.mkiv b/tex/context/base/typo-ini.mkiv new file mode 100644 index 000000000..1317021ef --- /dev/null +++ b/tex/context/base/typo-ini.mkiv @@ -0,0 +1,40 @@ +%D \module +%D [ file=typo-ini, +%D version=2000.16.09, +%D title=\CONTEXT\ Typographic 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 Since \CONTEXT\ is dealing with typographics, isn't +%D September 2000 a bit late to start writing this module? It +%D may seem so, but since more and more languages are +%D supported, we think it is time to isolate language specific +%D typographic extensions in modules. The first language that +%D demands this is Chinese, and more will follow. + +\writestatus{loading}{ConTeXt Typographic Macros / Initialization} + +\unprotect + +%D \macros +%D {ifvertical} +%D +%D The following switch can be used to signal macros that they +%D should adapt their behaviour. + +\newif\ifvertical % maybe also ifreverse + +%D \macros +%D {vhbox} +%D +%D A stupid but useful macro. + +\def\vhbox{\ifvertical\vbox\else\hbox\fi} + +\protect \endinput diff --git a/tex/context/base/typo-ini.tex b/tex/context/base/typo-ini.tex deleted file mode 100644 index 1317021ef..000000000 --- a/tex/context/base/typo-ini.tex +++ /dev/null @@ -1,40 +0,0 @@ -%D \module -%D [ file=typo-ini, -%D version=2000.16.09, -%D title=\CONTEXT\ Typographic 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 Since \CONTEXT\ is dealing with typographics, isn't -%D September 2000 a bit late to start writing this module? It -%D may seem so, but since more and more languages are -%D supported, we think it is time to isolate language specific -%D typographic extensions in modules. The first language that -%D demands this is Chinese, and more will follow. - -\writestatus{loading}{ConTeXt Typographic Macros / Initialization} - -\unprotect - -%D \macros -%D {ifvertical} -%D -%D The following switch can be used to signal macros that they -%D should adapt their behaviour. - -\newif\ifvertical % maybe also ifreverse - -%D \macros -%D {vhbox} -%D -%D A stupid but useful macro. - -\def\vhbox{\ifvertical\vbox\else\hbox\fi} - -\protect \endinput diff --git a/tex/context/base/typo-krn.mkiv b/tex/context/base/typo-krn.mkiv new file mode 100644 index 000000000..e2f10d806 --- /dev/null +++ b/tex/context/base/typo-krn.mkiv @@ -0,0 +1,59 @@ +%D \module +%D [ file=typo-krn, +%D version=2009.03.27, % code moved from core-spa.mkiv +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Spacing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Kerning} + +\unprotect + +\registerctxluafile{typo-krn}{1.001} + +\definesystemattribute[kern] + +% more +% +% {\setcharacterkerning[extrakerning]\input davis\relax} + +\newcount \maxcharacterkerningid + +\def\definecharacterkerning + {\dosingleargument\dodefinecharacterkerning} + +\def\dodefinecharacterkerning[#1]% + {\ifcsname\??ck#1\endcsname \else + \global\advance\maxcharacterkerningid\plusone + \setxvalue{\??ck:#1}{\the\maxcharacterkerningid}% + \fi} + +\def\setupcharacterkerning + {\dodoubleargument\dosetupcharacterkerning} + +\def\dosetupcharacterkerning[#1][#2]% + {\ifcsname\??ck:#1\endcsname + \begingroup + \getparameters[\??ck][\c!factor=0,#2]% + \ctxlua{kerns.setspacing(\getvalue{\??ck:#1},\@@ckfactor)}% + \endgroup + \fi} + +\def\setcharacterkerning + {\ctxlua{kerns.enabled=true}% + \gdef\setcharacterkerning[##1]{\dosetattribute{kern}{\csname\??ck:##1\endcsname}}% + \setcharacterkerning} + +\letvalue{\??ck:\s!reset}\attributeunsetvalue + +\definecharacterkerning[extrakerning] + +\setupcharacterkerning[extrakerning][\c!factor=.125] + +\protect \endinput diff --git a/tex/context/base/typo-krn.tex b/tex/context/base/typo-krn.tex deleted file mode 100644 index e2f10d806..000000000 --- a/tex/context/base/typo-krn.tex +++ /dev/null @@ -1,59 +0,0 @@ -%D \module -%D [ file=typo-krn, -%D version=2009.03.27, % code moved from core-spa.mkiv -%D title=\CONTEXT\ Typesetting Macros, -%D subtitle=Spacing, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Typesetting Macros / Kerning} - -\unprotect - -\registerctxluafile{typo-krn}{1.001} - -\definesystemattribute[kern] - -% more -% -% {\setcharacterkerning[extrakerning]\input davis\relax} - -\newcount \maxcharacterkerningid - -\def\definecharacterkerning - {\dosingleargument\dodefinecharacterkerning} - -\def\dodefinecharacterkerning[#1]% - {\ifcsname\??ck#1\endcsname \else - \global\advance\maxcharacterkerningid\plusone - \setxvalue{\??ck:#1}{\the\maxcharacterkerningid}% - \fi} - -\def\setupcharacterkerning - {\dodoubleargument\dosetupcharacterkerning} - -\def\dosetupcharacterkerning[#1][#2]% - {\ifcsname\??ck:#1\endcsname - \begingroup - \getparameters[\??ck][\c!factor=0,#2]% - \ctxlua{kerns.setspacing(\getvalue{\??ck:#1},\@@ckfactor)}% - \endgroup - \fi} - -\def\setcharacterkerning - {\ctxlua{kerns.enabled=true}% - \gdef\setcharacterkerning[##1]{\dosetattribute{kern}{\csname\??ck:##1\endcsname}}% - \setcharacterkerning} - -\letvalue{\??ck:\s!reset}\attributeunsetvalue - -\definecharacterkerning[extrakerning] - -\setupcharacterkerning[extrakerning][\c!factor=.125] - -\protect \endinput diff --git a/tex/context/base/typo-mir.mkiv b/tex/context/base/typo-mir.mkiv new file mode 100644 index 000000000..fe9d793e0 --- /dev/null +++ b/tex/context/base/typo-mir.mkiv @@ -0,0 +1,144 @@ +%D \module +%D [ file=typo-mir, +%D version=2009.03.27, % code moved from core-spa.mkiv +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Mirroring, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Mirroring} + +\unprotect + +\registerctxluafile{typo-mir}{1.001} + +\definesystemattribute[mirror] + +% experimental mirroring + +\def\setcharactermirroring + {\ctxlua{mirror.enabled=true}% + \gdef\setcharactermirroring[##1]{\dosetattribute{mirror}{\number##1}}% + \setcharactermirroring} + +\def\resetcharactermirroring + {\doresetattribute{mirror}} + +\newtoks\everysetupdirections + +\def\setupdirections[#1]% there will be more like setting up directions themselves + {\getparameters[\??di][#1]% + \the\everysetupdirections} + +\chardef\directionsbidimode=0 + +\letvalue{\??di:bidi:\v!off }\zerocount +\letvalue{\??di:bidi:\v!global}\plusone +\letvalue{\??di:bidi:\v!local }\plustwo +\letvalue{\??di:bidi:\v!on }\plustwo + +\appendtoks + \chardef\directionsbidimode\executeifdefined{\??di:bidi:\@@dibidi}\zerocount\relax + \ifcase\directionsbidimode + \resetcharactermirroring + \or + \setcharactermirroring[1]% global, chars + \or + \setcharactermirroring[2]% local, attributes + \or + \setcharactermirroring[1]% default + \fi +\to \everysetupdirections + +% bidi: local=obey grouping, global=ignore grouping (unicode has no grouping) + +\setupdirections % maybe start/stop + [bidi=\v!off] + +\unexpanded\def\bidilre{\utfchar{"0x202A}} +\unexpanded\def\bidirle{\utfchar{"0x202B}} +\unexpanded\def\bidipop{\utfchar{"0x202C}} +\unexpanded\def\bidilro{\utfchar{"0x202D}} +\unexpanded\def\bidirlo{\utfchar{"0x202E}} + +\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi} +\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi} +\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setcharactermirroring[3]\fi} +\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setcharactermirroring[4]\fi} + +% for the moment: \setcharactermirroring[\plusone] + +\protect \endinput + +% bidi test + +\definefontfeature + [arab] + [mode=node,language=dflt,script=arab, + init=yes,medi=yes,fina=yes,isol=yes, + liga=yes,dlig=yes,rlig=yes,clig=yes, + mark=yes,mkmk=yes,kern=yes,curs=yes] + +\font\Arabic=arabtype*arab at 20pt + +\def\LATIN{LATIN} {\setcharactermirroring[1]} % enable this +\def\ARAB {محمد} + +\startluacode + function document.split_tokens(str) + for s in str:bytes() do + tex.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s)) + end + end +\stopluacode + +\def\biditest#1#2#3% font text raw + {\dontleavehmode\hbox + {\framed[offset=overlay]{\tttf#2}\quad + \ctxlua{mirror.trace = true}% + \framed[offset=overlay]{#1#3}\quad + \ctxlua{mirror.trace = false} + \tttf\ctxlua{document.split_tokens([[\detokenize{#3}]])}}} + +\startbuffer[bidi-sample] +\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par +\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par +\biditest\Arabic{LATIN ARAB}{\textdir TLT{\bidilro \LATIN\ \ARAB}}\par % right -> left +\biditest\Arabic{LATIN ARAB}{\textdir TRT{\bidilro \LATIN\ \ARAB}}\par % right -> left +\biditest\Arabic{BARA NITAL}{\textdir TLT{\bidirlo \LATIN\ \ARAB}}\par % left -> right +\biditest\Arabic{BARA NITAL}{\textdir TRT{\bidirlo \LATIN\ \ARAB}}\par % left -> right +\stopbuffer + +\startbuffer[bidi-sample] +\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par +\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par +\biditest\Arabic{LATIN ARAB}{\textdir TLT\bidilro \LATIN\ \ARAB}\par % right -> left +\biditest\Arabic{LATIN ARAB}{\textdir TRT\bidilro \LATIN\ \ARAB}\par % right -> left +\biditest\Arabic{BARA NITAL}{\textdir TLT\bidirlo \LATIN\ \ARAB}\par % left -> right +\biditest\Arabic{BARA NITAL}{\textdir TRT\bidirlo \LATIN\ \ARAB}\par % left -> right +\stopbuffer + +\startbuffer[bidi-setup] +\setupdirections[bidi=off] +\stopbuffer + +{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} + +\startbuffer[bidi-setup] +\setupdirections[bidi=global] +\stopbuffer + +{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} + +\startbuffer[bidi-setup] +\setupdirections[bidi=local] +\stopbuffer + +{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} + +\stoptext diff --git a/tex/context/base/typo-mir.tex b/tex/context/base/typo-mir.tex deleted file mode 100644 index fe9d793e0..000000000 --- a/tex/context/base/typo-mir.tex +++ /dev/null @@ -1,144 +0,0 @@ -%D \module -%D [ file=typo-mir, -%D version=2009.03.27, % code moved from core-spa.mkiv -%D title=\CONTEXT\ Typesetting Macros, -%D subtitle=Mirroring, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Typesetting Macros / Mirroring} - -\unprotect - -\registerctxluafile{typo-mir}{1.001} - -\definesystemattribute[mirror] - -% experimental mirroring - -\def\setcharactermirroring - {\ctxlua{mirror.enabled=true}% - \gdef\setcharactermirroring[##1]{\dosetattribute{mirror}{\number##1}}% - \setcharactermirroring} - -\def\resetcharactermirroring - {\doresetattribute{mirror}} - -\newtoks\everysetupdirections - -\def\setupdirections[#1]% there will be more like setting up directions themselves - {\getparameters[\??di][#1]% - \the\everysetupdirections} - -\chardef\directionsbidimode=0 - -\letvalue{\??di:bidi:\v!off }\zerocount -\letvalue{\??di:bidi:\v!global}\plusone -\letvalue{\??di:bidi:\v!local }\plustwo -\letvalue{\??di:bidi:\v!on }\plustwo - -\appendtoks - \chardef\directionsbidimode\executeifdefined{\??di:bidi:\@@dibidi}\zerocount\relax - \ifcase\directionsbidimode - \resetcharactermirroring - \or - \setcharactermirroring[1]% global, chars - \or - \setcharactermirroring[2]% local, attributes - \or - \setcharactermirroring[1]% default - \fi -\to \everysetupdirections - -% bidi: local=obey grouping, global=ignore grouping (unicode has no grouping) - -\setupdirections % maybe start/stop - [bidi=\v!off] - -\unexpanded\def\bidilre{\utfchar{"0x202A}} -\unexpanded\def\bidirle{\utfchar{"0x202B}} -\unexpanded\def\bidipop{\utfchar{"0x202C}} -\unexpanded\def\bidilro{\utfchar{"0x202D}} -\unexpanded\def\bidirlo{\utfchar{"0x202E}} - -\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi} -\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi} -\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setcharactermirroring[3]\fi} -\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setcharactermirroring[4]\fi} - -% for the moment: \setcharactermirroring[\plusone] - -\protect \endinput - -% bidi test - -\definefontfeature - [arab] - [mode=node,language=dflt,script=arab, - init=yes,medi=yes,fina=yes,isol=yes, - liga=yes,dlig=yes,rlig=yes,clig=yes, - mark=yes,mkmk=yes,kern=yes,curs=yes] - -\font\Arabic=arabtype*arab at 20pt - -\def\LATIN{LATIN} {\setcharactermirroring[1]} % enable this -\def\ARAB {محمد} - -\startluacode - function document.split_tokens(str) - for s in str:bytes() do - tex.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s)) - end - end -\stopluacode - -\def\biditest#1#2#3% font text raw - {\dontleavehmode\hbox - {\framed[offset=overlay]{\tttf#2}\quad - \ctxlua{mirror.trace = true}% - \framed[offset=overlay]{#1#3}\quad - \ctxlua{mirror.trace = false} - \tttf\ctxlua{document.split_tokens([[\detokenize{#3}]])}}} - -\startbuffer[bidi-sample] -\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{LATIN ARAB}{\textdir TLT{\bidilro \LATIN\ \ARAB}}\par % right -> left -\biditest\Arabic{LATIN ARAB}{\textdir TRT{\bidilro \LATIN\ \ARAB}}\par % right -> left -\biditest\Arabic{BARA NITAL}{\textdir TLT{\bidirlo \LATIN\ \ARAB}}\par % left -> right -\biditest\Arabic{BARA NITAL}{\textdir TRT{\bidirlo \LATIN\ \ARAB}}\par % left -> right -\stopbuffer - -\startbuffer[bidi-sample] -\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{LATIN ARAB}{\textdir TLT\bidilro \LATIN\ \ARAB}\par % right -> left -\biditest\Arabic{LATIN ARAB}{\textdir TRT\bidilro \LATIN\ \ARAB}\par % right -> left -\biditest\Arabic{BARA NITAL}{\textdir TLT\bidirlo \LATIN\ \ARAB}\par % left -> right -\biditest\Arabic{BARA NITAL}{\textdir TRT\bidirlo \LATIN\ \ARAB}\par % left -> right -\stopbuffer - -\startbuffer[bidi-setup] -\setupdirections[bidi=off] -\stopbuffer - -{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} - -\startbuffer[bidi-setup] -\setupdirections[bidi=global] -\stopbuffer - -{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} - -\startbuffer[bidi-setup] -\setupdirections[bidi=local] -\stopbuffer - -{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} - -\stoptext diff --git a/tex/context/base/typo-spa.mkiv b/tex/context/base/typo-spa.mkiv new file mode 100644 index 000000000..d1b855edd --- /dev/null +++ b/tex/context/base/typo-spa.mkiv @@ -0,0 +1,69 @@ +%D \module +%D [ file=typo-spa, +%D version=2009.03.27, % code moved from cors-spa.mkiv +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Spacing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Spacing} + +\unprotect + +\registerctxluafile{typo-spa}{1.001} + +\definesystemattribute[spacing] + +% experimental spacing +% +% test: oeps {\setcharacterspacing[frenchpunctuation]x: xx \bfd x: xx} oeps: test + +\newcount \maxcharacterspacingid + +\def\definecharacterspacing[#1]% + {\ifcsname\??ch#1\endcsname \else + \global\advance\maxcharacterspacingid\plusone + \setxvalue{\??ch:#1}{\the\maxcharacterspacingid}% + \fi} + +\def\setupcharacterspacing + {\dotripleargument\dosetupcharacterspacing} + +\def\dosetupcharacterspacing[#1][#2][#3]% + {\ifcsname\??ch:#1\endcsname + \begingroup % for the moment we use modes, in ordere to avoid interface translation + \getparameters[\??ch][\c!left=0,\c!right=0,\c!alternative=0,#3]% + \ctxlua{spacings.setspacing(\getvalue{\??ch:#1},\number#2,\@@chleft,\@@chright,\@@chalternative)}% + \endgroup + \fi} + +\def\setcharacterspacing + {\ctxlua{spacings.enabled=true}% + \gdef\setcharacterspacing[##1]{\dosetattribute{spacing}{\csname\??ch:##1\endcsname}}% + \setcharacterspacing} + +\def\resetcharacterspacing + {\doresetattribute{spacing}} + +\letvalue{\??ch:\s!reset}\attributeunsetvalue + +% \setcharacterspacing[frenchpunctuation] +% «\type{bla}»\crlf « \type{bla}»\crlf +% «bla »\crlf « bla»\crlf « bla »\crlf +% bla: bla\crlf bla : bla + +\definecharacterspacing [frenchpunctuation] % name may change / unit is em + +\setupcharacterspacing [frenchpunctuation] ["003A] [\c!left =.25,\c!alternative=1] % : % strip preceding space(char) +\setupcharacterspacing [frenchpunctuation] ["003B] [\c!left =.25,\c!alternative=1] % ; % strip preceding space(char) +\setupcharacterspacing [frenchpunctuation] ["003F] [\c!left =.25,\c!alternative=1] % ? % strip preceding space(char) +\setupcharacterspacing [frenchpunctuation] ["0021] [\c!left =.25,\c!alternative=1] % ! % strip preceding space(char) +\setupcharacterspacing [frenchpunctuation] ["00AB] [\c!right=.25,\c!alternative=1] % guillemotleft/leftguillemot % strip following space(char) +\setupcharacterspacing [frenchpunctuation] ["00BB] [\c!left =.25,\c!alternative=1] % guillemotright/rightguillemot % strip preceding space(char) + +\protect \endinput diff --git a/tex/context/base/typo-spa.tex b/tex/context/base/typo-spa.tex deleted file mode 100644 index d1b855edd..000000000 --- a/tex/context/base/typo-spa.tex +++ /dev/null @@ -1,69 +0,0 @@ -%D \module -%D [ file=typo-spa, -%D version=2009.03.27, % code moved from cors-spa.mkiv -%D title=\CONTEXT\ Typesetting Macros, -%D subtitle=Spacing, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Typesetting Macros / Spacing} - -\unprotect - -\registerctxluafile{typo-spa}{1.001} - -\definesystemattribute[spacing] - -% experimental spacing -% -% test: oeps {\setcharacterspacing[frenchpunctuation]x: xx \bfd x: xx} oeps: test - -\newcount \maxcharacterspacingid - -\def\definecharacterspacing[#1]% - {\ifcsname\??ch#1\endcsname \else - \global\advance\maxcharacterspacingid\plusone - \setxvalue{\??ch:#1}{\the\maxcharacterspacingid}% - \fi} - -\def\setupcharacterspacing - {\dotripleargument\dosetupcharacterspacing} - -\def\dosetupcharacterspacing[#1][#2][#3]% - {\ifcsname\??ch:#1\endcsname - \begingroup % for the moment we use modes, in ordere to avoid interface translation - \getparameters[\??ch][\c!left=0,\c!right=0,\c!alternative=0,#3]% - \ctxlua{spacings.setspacing(\getvalue{\??ch:#1},\number#2,\@@chleft,\@@chright,\@@chalternative)}% - \endgroup - \fi} - -\def\setcharacterspacing - {\ctxlua{spacings.enabled=true}% - \gdef\setcharacterspacing[##1]{\dosetattribute{spacing}{\csname\??ch:##1\endcsname}}% - \setcharacterspacing} - -\def\resetcharacterspacing - {\doresetattribute{spacing}} - -\letvalue{\??ch:\s!reset}\attributeunsetvalue - -% \setcharacterspacing[frenchpunctuation] -% «\type{bla}»\crlf « \type{bla}»\crlf -% «bla »\crlf « bla»\crlf « bla »\crlf -% bla: bla\crlf bla : bla - -\definecharacterspacing [frenchpunctuation] % name may change / unit is em - -\setupcharacterspacing [frenchpunctuation] ["003A] [\c!left =.25,\c!alternative=1] % : % strip preceding space(char) -\setupcharacterspacing [frenchpunctuation] ["003B] [\c!left =.25,\c!alternative=1] % ; % strip preceding space(char) -\setupcharacterspacing [frenchpunctuation] ["003F] [\c!left =.25,\c!alternative=1] % ? % strip preceding space(char) -\setupcharacterspacing [frenchpunctuation] ["0021] [\c!left =.25,\c!alternative=1] % ! % strip preceding space(char) -\setupcharacterspacing [frenchpunctuation] ["00AB] [\c!right=.25,\c!alternative=1] % guillemotleft/leftguillemot % strip following space(char) -\setupcharacterspacing [frenchpunctuation] ["00BB] [\c!left =.25,\c!alternative=1] % guillemotright/rightguillemot % strip preceding space(char) - -\protect \endinput diff --git a/tex/context/base/verb-lua.lua b/tex/context/base/verb-lua.lua deleted file mode 100644 index 9ba22c1f2..000000000 --- a/tex/context/base/verb-lua.lua +++ /dev/null @@ -1,216 +0,0 @@ --- filename : type-lua.lua --- comment : companion to core-buf.tex --- author : Hans Hagen, PRAGMA-ADE, Hasselt NL --- copyright: PRAGMA ADE / ConTeXt Development Team --- license : see context related readme files - --- BROKEN : result is now table - -local utf = unicode.utf8 - -local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues - -local ctxcatcodes = tex.ctxcatcodes - -if not buffers then buffers = { } end -if not buffers.visualizers then buffers.visualizers = { } end -if not buffers.visualizers.lua then buffers.visualizers.lua = { } end - -buffers.visualizers.lua.identifiers = { } - --- borrowed from scite - -buffers.visualizers.lua.identifiers.core = { - "and", "break", "do", "else", "elseif", "end", "false", "for", "function", - "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", - "true", "until", "while" -} - -buffers.visualizers.lua.identifiers.base = { - "assert", "collectgarbage", "dofile", "error", "gcinfo", "loadfile", - "loadstring", "print", "rawget", "rawset", "require", "tonumber", - "tostring", "type", "unpack", -} - -buffers.visualizers.lua.identifiers.five = { - "_G", "getfenv", "getmetatable", "ipairs", "loadlib", "next", "pairs", - "pcall", "rawequal", "setfenv", "setmetatable", "xpcall", "string", "table", - "math", "coroutine", "io", "os", "debug", "load", "module", "select" -} - -buffers.visualizers.lua.identifiers.libs = { - -- coroutine - "coroutine.create", "coroutine.resume", "coroutine.status", "coroutine.wrap", - "coroutine.yield", "coroutine.running", - -- package - "package.cpath", "package.loaded", "package.loadlib", "package.path", - -- 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.log10", "math.max", "math.min math.mod math.pi", "math.pow", - "math.rad", "math.random", "math.randomseed", "math.sin", "math.sqrt", - "math.tan", "math.cosh", "math.fmod", "math.modf", "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.maxn", "table.concat", "table.foreach", "table.foreachi", "table.getn", - "table.sort", "table.insert", "table.remove", "table.setn", - -- 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" -} - -buffers.visualizers.lua.words = { } - -for k,v in pairs(buffers.visualizers.lua.identifiers) do - for _,w in pairs(v) do - buffers.visualizers.lua.words[w] = k - end -end - -buffers.visualizers.lua.styles = { } - -buffers.visualizers.lua.styles.core = "" -buffers.visualizers.lua.styles.base = "\\sl " -buffers.visualizers.lua.styles.five = "\\sl " -buffers.visualizers.lua.styles.libs = "\\sl " - --- btex .. etex - -buffers.visualizers.lua.colors = { - "prettyone", - "prettytwo", - "prettythree", - "prettyfour", -} - -buffers.visualizers.lua.states = { - ['1']=1, ['2']=1, ['3']=1, ['4']=1, ['5']=1, ['6']=1, ['7']=1, ['8']=1, ['9']=1, ['0']=1, - ['--']=4, - ['"']=3, ["'"]=3, - ['+']=1, ['-']=1, ['*']=1, ['/']=1, ['%']=1, ['^']=1, -} - -buffers.visualizers.lua.options = { } - -buffers.visualizers.lua.options.colorize_strings = false -buffers.visualizers.lua.options.colorize_comments = false - -function buffers.flush_lua_word(state, word, result) - if #word>0 then - local id = buffers.visualizers.lua.words[word] - if id then - state, result = buffers.change_state(2, state, result) - if buffers.visualizers.lua.styles[id] then - state, result = buffers.finish_state(state,result .. buffers.visualizers.lua.styles[id] .. word) - else - state, result = buffers.finish_state(state,result .. word) - end - return state, result - else - state, result = buffers.finish_state(state,result) - return state, result .. buffers.escaped(word) -- cmp mp - end - else - state, result = buffers.finish_state(state,result) - return state, result - end -end - -buffers.visualizers.lua.states.incomment = false - --- to be sped up - -function buffers.visualizers.lua.flush_line(str, nested) - local result, state = { }, 0 - local instr, inesc, incom = false, false, false - local c, p - local sb, ss, sf = string.byte, string.sub, string.find - local code, comment ---~ buffers.currentcolors = buffers.visualizers.lua.colors ---~ if sf(str,"^%-%-%[") then ---~ buffers.visualizers.lua.states.incomment = true ---~ code, comment, incom = "", str, true ---~ elseif sf(str,"^%]%-%-") then ---~ buffers.visualizers.lua.states.incomment = false ---~ code, comment, incom = "", str, true ---~ elseif buffers.visualizers.lua.states.incomment then ---~ code, comment, incom = "", str, true ---~ else ---~ code, comment = string.match(str,"^(.-)%-%-(.*)$") ---~ if not code then ---~ code, comment = str, "" ---~ end ---~ end ---~ -- bla bla1 bla.bla ---~ for c in utfcharacters(code) do ---~ if instr then ---~ if c == s then ---~ if inesc then ---~ result = result .. "\\char" .. sb(c) .. " " ---~ inesc = false ---~ else ---~ state, result = buffers.change_state(buffers.visualizers.lua.states[c], state, result) ---~ instr = false ---~ result = result .. "\\char" .. sb(c) .. " " ---~ state, result = buffers.finish_state(state,result) ---~ end ---~ elseif c == "\\" then ---~ inesc = not inesc ---~ result = result .. buffers.escaped_chr(c) ---~ else ---~ inesc = false ---~ result = result .. buffers.escaped_chr(c) ---~ end ---~ elseif sf(c,"^([\'\"])$") then ---~ s, instr = c, true ---~ state, result = buffers.change_state(buffers.visualizers.lua.states[c], state, result) ---~ result = result .. "\\char" .. sb(c) .. " " ---~ if not buffers.visualizers.lua.options.colorize_strings then ---~ state, result = buffers.finish_state(state,result) ---~ end ---~ elseif c == " " then ---~ state, result = buffers.flush_lua_word(state, word, result) ---~ word = "" ---~ result = result .. "\\obs " ---~ elseif sf(c,"^[%a]$") then ---~ state, result = buffers.finish_state(state,result) ---~ word = word .. c ---~ elseif (#word > 1) and sf(c,"^[%d%.%_]$") then ---~ word = word .. c ---~ else ---~ state, result = buffers.flush_lua_word(state, word, result) ---~ word = "" ---~ state, result = buffers.change_state(buffers.visualizers.lua.states[c], state, result) ---~ result = result .. "\\char" .. sb(c) .. " " ---~ instr = (c == '"') ---~ end ---~ end ---~ state, result = buffers.flush_lua_word(state, word, result) ---~ if comment ~= "" then ---~ state, result = buffers.change_state(buffers.visualizers.lua.states['--'], state, result) ---~ if not incom then ---~ result = result .. buffers.escaped("--") ---~ end ---~ if buffers.visualizers.lua.options.colorize_comments then ---~ state, result = buffers.finish_state(state,result) ---~ result = result .. buffers.escaped(comment) ---~ else ---~ result = result .. buffers.escaped(comment) ---~ state, result = buffers.finish_state(state,result) ---~ end ---~ else ---~ state, result = buffers.finish_state(state,result) ---~ end ---~ tex.sprint(ctxcatcodes,result) - return "not yet finished" -end diff --git a/tex/context/base/verb-mp.lua b/tex/context/base/verb-mp.lua deleted file mode 100644 index 4ff957b41..000000000 --- a/tex/context/base/verb-mp.lua +++ /dev/null @@ -1,238 +0,0 @@ --- filename : type-mp.lua --- comment : companion to core-buf.tex --- author : Hans Hagen, PRAGMA-ADE, Hasselt NL --- copyright: PRAGMA ADE / ConTeXt Development Team --- license : see context related readme files - -local utf = unicode.utf8 - -local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues - -if not buffers then buffers = { } end -if not buffers.visualizers then buffers.visualizers = { } end -if not buffers.visualizers.mp then buffers.visualizers.mp = { } end - -buffers.visualizers.mp.identifiers = { } - -buffers.visualizers.mp.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' -} - -buffers.visualizers.mp.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' -} - -buffers.visualizers.mp.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', - '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' -} - -buffers.visualizers.mp.words = { } - -for k,v in pairs(buffers.visualizers.mp.identifiers) do - for _,w in pairs(v) do - buffers.visualizers.mp.words[w] = k - end -end - -buffers.visualizers.mp.styles = { } - -buffers.visualizers.mp.styles.primitives = "" -buffers.visualizers.mp.styles.plain = "\\sl " -buffers.visualizers.mp.styles.metafun = "\\sl " - --- btex .. etex - -buffers.visualizers.mp.colors = { - "prettyone", - "prettytwo", - "prettythree", - "prettyfour", -} - -buffers.visualizers.mp.states = { - [';']=1, ['$']=1, ['@']=1, ['#']=1, - ['\\']=2, - ['(']=3, [')']=3, ['[']=3, [']']=3, [':']=3, ['=']=3, ['<']=3, ['>']=3, - ['-']=4, ['+']=4, ['/']=4, ['*']=4, ['|']=4, ['`']=4, ['!']=4, ['?']=4, ['^']=4, ['&']=4, ['%']=4, - ['%']=4, ['.']=4, [',']=4 -} - -function buffers.flush_mp_word(state, word, intex, result) - if #word>0 then - if intex then - if word == 'etex' then - state = buffers.change_state(2, state, result) - result[#result+1] = word - state = buffers.finish_state(state,result) - return state, false - else - result[#result+1] = word - return state, true - end - else - local id = buffers.visualizers.mp.words[word] - if id then - state = buffers.change_state(2, state, result) - if buffers.visualizers.mp.styles[id] then - result[#result+1] = buffers.visualizers.mp.styles[id] .. word - else - result[#result+1] = word - end - state = buffers.finish_state(state,result) - return state, (word == 'btex') or (word == 'verbatimtex') - else - state = buffers.finish_state(state,result) - result[#result+1] = word - return state, intex - end - end - else - state = buffers.finish_state(state,result) - 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 buffers.visualizers.mp.flush_line_(str,nested) - local result, state, word = { }, 0, "" - local instr, intex, incomment = false, false, false - local byte, find = utf.byte, utf.find - local finish, change = buffers.finish_state, buffers.change_state - buffers.currentcolors = buffers.visualizers.mp.colors - for c in utfcharacters(str) do - if incomment then - result[#result+1] = buffers.escaped_chr(c) - elseif c == '%' then - state = change(buffers.visualizers.mp.states[c], state, result) - incomment = true - result[#result+1] = "\\char" .. byte(c) .. " " - state = finish(state,result) - elseif instr then - if c == '"' then - state = change(buffers.visualizers.mp.states[c], state, result) - instr = false - result[#result+1] = "\\char" .. byte(c) .. " " - state = finish(state,result) - elseif find(c,"^[%a%d]$") then - result[#result+1] = c - else - result[#result+1] = "\\char" .. byte(c) .. " " - end - elseif c == " " then - state, intex = buffers.flush_mp_word_(state, word, intex, result) - word = "" - result[#result+1] = "\\obs " - elseif intex then - if find(c,"^[%a]$") then - word = word .. c - else - state, intex = buffers.flush_mp_word_(state, word, intex, result) - word = "" - if intex then - if find(c,"^[%d]$") then - result[#result+1] = c - else - result[#result+1] = "\\char" .. byte(c) .. " " - end - else - state = change(buffers.visualizers.mp.states[c], state, result) - result[#result+1] = "\\char" .. byte(c) .. " " - end - end - elseif find(c,"^[%a]$") then - state = finish(state,result) - word = word .. c - else - state, intex = buffers.flush_mp_word_(state, word, intex, result) - word = "" - state = change(buffers.visualizers.mp.states[c], state, result) - result[#result+1] = "\\char" .. byte(c) .. " " - instr = (c == '"') - end - end - state, intex = buffers.flush_mp_word_(state, word, intex, result) - state = finish(state,result) - buffers.flush_result(result,false) -end diff --git a/tex/context/base/verb-tex.lua b/tex/context/base/verb-tex.lua deleted file mode 100644 index 98e6eccb4..000000000 --- a/tex/context/base/verb-tex.lua +++ /dev/null @@ -1,126 +0,0 @@ --- filename : type-tex.lua --- comment : companion to core-buf.tex --- author : Hans Hagen, PRAGMA-ADE, Hasselt NL --- copyright: PRAGMA ADE / ConTeXt Development Team --- license : see context related readme files - -local utf = unicode.utf8 - -local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues - -if not buffers then buffers = { } end -if not buffers.visualizers then buffers.visualizers = { } end -if not buffers.visualizers.tex then buffers.visualizers.tex = { } end - -buffers.visualizers.tex.colors = { - "prettytwo", - "prettyone", - "prettythree", - "prettyfour" -} - -buffers.visualizers.tex.states = { - ['$']=2, ['{']=2, ['}']=2, - ['[']=3, [']']=3, ['(']=3, [')']=3, ['<']=3, ['>']=3, ['#']=3, ['=']=3, ['"']=3, - ['/']=4, ['^']=4, ['_']=4, ['-']=4, ['&']=4, ['+']=4, ["'"]=4, ['`']=4, ['|']=4, ['%']=4 -} - --- using a table to store the result does not make sense here (actually, --- it's substantial slower since we're flushing lines on the fly) --- --- we could use a special catcode regime: only \ { } - -function buffers.visualizers.tex.flush_line(str,nested) - local result, state = { }, 0 - local first, escaping = false, false - local byte, find = utf.byte, utf.find - local finish, change = buffers.finish_state, buffers.change_state - buffers.currentcolors = buffers.visualizers.tex.colors - for c in utfcharacters(str) do - if c == " " then - if escaping then - result[#result+1] = " " - else - state = finish(state, result) - result[#result+1] = "\\obs " - end - escaping, first = false, false - elseif c == "\t" then - if escaping then - result[#result+1] = " " - else - state = finish(state, result) - result[#result+1] = "\\obs " - end - if buffers.visualizers.enabletab then - result[#result+1] = string.rep("\\obs ",i%buffers.visualizers.tablength) - end - escaping, first = false, false - elseif buffers.visualizers.enableescape and (c == buffers.visualizers.escapetoken) then - if escaping then - if first then - if find(c,"^[%a%!%?%@]$") then - result[#result+1] =c - else - result[#result+1] ="\\char" .. byte(c) .. " " - end - first = false - else - result[#result+1] = "\\" - first = true - end - else - state = finish(state, result) - result[#result+1] = "\\" - escaping, first = true, true - end - elseif escaping then - if find(c,"^[%a%!%?%@]$") then - result[#result+1] = c - else - result[#result+1] = "\\char" .. byte(c) .. " " - end - first = false - elseif first then - state = 1 - if find(c,"^[%a%!%?%@]$") then - result[#result+1] = c - else - result[#result+1] = "\\char" .. byte(c) .. " " - state = finish(state, result) - end - first = false - elseif state == 1 then - if find(c,"^[%a%!%?%@]$") then - result[#result+1] = c - first = false - elseif c == "\\" then - state = change(1, state, result) - result[#result+1] = "\\char" .. byte(c) .. " " - first = true - else - state = change(buffers.visualizers.tex.states[c], state, result) - if state == 0 then - result[#result+1] = c - else - result[#result+1] = "\\char" .. byte(c) .. " " - end - first = false - end - elseif c == "\\" then - first = true - state = change(1, state, result) - result[#result+1] = "\\char" .. byte(c) .. " " - else - state = change(buffers.visualizers.tex.states[c], state, result) - if state == 0 then - result[#result+1] = c - else - result[#result+1] = "\\char" .. byte(c) .. " " - end - first = false - end - end - state = finish(state, result) - buffers.flush_result(result,nested) -end diff --git a/tex/context/test/chem-str-test.tex b/tex/context/test/chem-str-test.tex new file mode 100644 index 000000000..fd6a8227a --- /dev/null +++ b/tex/context/test/chem-str-test.tex @@ -0,0 +1,560 @@ +% Beware, integrated ppchtex support is incomplete and under +% construction so when you depend on the full functionality +% you need to use the module! +% +% For testing new functionality: +% +% \startMPextensions +% input "mp-chem.mp" ; +% \stopMPextensions +% \startluacode +% dofile(resolvers.find_file("chem-str.lua","tex")) +% \stopluacode +% \setbox\scratchbox\hbox{\startMPcode\stopMPcode} + +\enabletrackers[chemistry.structure] + +\starttext + +\defineprocessor[ch:r][color=red] +\defineprocessor[ch:g][color=green] +\defineprocessor[ch:b][color=blue] + +\setupchemical[frame=on,offset=3pt] + +\startbuffer[test-set] + + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV1,B] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV2,B] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV3,B] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV4,B] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV5,B] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV6,B] \stopchemical \quad + + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,AU] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,AD] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,EB] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,DB] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,ER] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,DR] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,BR] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,SB] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,-SB] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,+SB] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,C] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CC] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CD] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CCD] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,SR] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,-SR] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,+SR] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,RD] \stopchemical \quad + + \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,Z] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RZ] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,+R,+RZ] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,-R,-RZ] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,RB,RZ] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,+RB,+RZ][a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,-RB,-RZ][a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RT] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RTT] [a,b,c,d,e,f] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RBT] [a,b,c,d,e,f] \stopchemical \quad + + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RN] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RTN] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RBN] \stopchemical \quad + + \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RN] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT1,B,R,RN] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT2,B,R,RN] \stopchemical \quad + \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT3,B,R,RN] \stopchemical \quad + +\stopbuffer + +\dontcomplain + +% \startTEXpage + +\setupchemicalframed[frame=on] + +% \startTEXpage +% \noindent \startchemical \chemical[THREE, B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT1,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT2,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT3,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT4,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical + +% \noindent \startchemical \chemical[THREE, B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical + +% \noindent \startchemical \chemical[THREE, B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical +% \stopTEXpage + +% \startTEXpage +% \noindent \startchemical \chemical[SIX,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical + +% \noindent \startchemical \chemical[SIX,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical + +% \noindent \startchemical \chemical[SIX,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[SIX,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \stopTEXpage + +% \startTEXpage +% \noindent \startchemical \chemical[FIVE,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical + +% \noindent \startchemical \chemical[FIVE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical + +% \noindent \startchemical \chemical[FIVE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[FIVE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \stopTEXpage + +% \startTEXpage +% \noindent \startchemical \chemical[FOUR,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical + +% \noindent \startchemical \chemical[FOUR,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical + +% \noindent \startchemical \chemical[FOUR,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[FOUR,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \stopTEXpage + +% \startTEXpage +% \noindent \startchemical \chemical[THREE,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical + +% \noindent \startchemical \chemical[THREE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical + +% \noindent \startchemical \chemical[THREE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \noindent \startchemical \chemical[THREE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical +% \stopTEXpage + +% \startTEXpage +% \noindent \startchemical \chemical[EIGHT,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical + +% \noindent \startchemical \chemical[EIGHT,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical + +% \noindent \startchemical \chemical[EIGHT,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical +% \noindent \startchemical \chemical[EIGHT,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical +% \stopTEXpage + +% \enabletrackers[chemistry.molecules] + +% \startchemicalformula +% \chemical{S} +% \chemical{+} +% \chemical{O_2} +% \chemical{GIVES} +% \chemical{\+{4}{S}} +% \chemical{\+{4}{S}\-{2}{O_2}} +% \chemical{\-{2}{O_2}} +% \stopchemicalformula + +% \startformula +% \chemical{S} +% \chemical{+} +% \chemical{O_2} +% \chemical{GIVES} +% \chemical{\+{4}{S}} +% \chemical{\+{4}{S}\-{2}{O_2}} +% \chemical{\-{2}{O_2}} +% \stopformula + + +\startTEXpage[offset=2cm] + +\startchemical[width=fit,size=small,scale=small,frame=on] + \chemical[SIX,B] +\stopchemical + +% \startchemical[width=fit,size=small,scale=small,frame=on] +% \chemical[ONE,SB258] +% \stopchemical + +% \startchemical[width=fit,size=small,scale=small,frame=on] +% \chemical[ONE,ROT3,SB258] +% \stopchemical + +% \startchemical[width=fit,size=small,scale=small,frame=on] +% \chemical[FIVE,ROT3,SB34,+SB2,-SB5,Z345,DR35,SR4,CRZ35,SUB1,ONE,SB258,Z0,Z28][C,N,C,O,O,CH,COOC_2H_5,COOC_2H_5] +% \stopchemical + +% \startchemical[scale=small,width=8000,height=8000,frame=on] +% \chemical[SIX,SB2356,DB14,Z2346,SR36,RZ36] [C,N,C,C,H,H_2] +% \chemical[PB:Z1,ONE,Z0,DIR8,Z0,SB24,DB7,Z27,PE][C,C,CH_3,O] +% \chemical[PB:Z5,ONE,Z0,DIR6,Z0,SB24,DB7,Z47,PE][C,C,H_3C,O] +% \chemical[SR24,RZ24] [CH_3,H_3C] +% \stopchemical + +% \startchemical[scale=small,width=6000,height=6000,frame=on] +% \chemical[SIX,SB2356,DB14,Z,SR36,RZ36,SR1245,RZ24][C,C,N,C,C,C,H,H_2,CH_3,H_3C] +% \chemical[PB:RZ1,ONE,Z0,SB2,DB7,Z27,PE][C,CH_3,O] +% \chemical[PB:RZ5,ONE,Z0,SB4,DB7,Z47,PE][C,H_3C,O] +% \stopchemical + +% \startchemical[width=fit,size=small,scale=small,frame=on] +% \chemical +% [SIX,B,C,ADJ1,FIVE,ROT3,SB34,+SB2,-SB5,Z345,DR35,SR4,CRZ35,SUB1,ONE,OFF1,SB258,Z0,Z28] +% [C,N,C,O,O,CH,COOC_2H_5,COOC_2H_5] +% \stopchemical + +% \startchemical[width=fit,height=fit,frame=on,scale=small] +% \chemical +% [ONE,SB15,DB7,Z057,3OFF1,MOV1,Z0,3OFF1,MOV1, +% Z017,SB1357,MOV3,Z0,MOV3,SB1357,Z013,3OFF5, +% MOV5,Z0,3OFF5,SB5,Z5] +% [C,H_2N,NH,(CH_2)_3,C,COOH,H,\SL{NH},C,COOH,H, +% (CH_2)_2,HOOC] +% \stopchemical + +% \startchemical[width=fit,height=fit,frame=on,scale=small] +% \chemical +% [ONE,SB15,DB7,Z057,3OFF1,MOV1,Z0,3OFF1,MOV1,Z017,SB1357,MOV3,Z0,MOV3,SB1357,Z013,3OFF5,MOV5,Z0,3OFF5,SB5,Z5] +% [C,H_2N,NH,(CH_2)_3,C,COOH,H,\SL{NH},C,COOH,H,(CH_2)_2,HOOC] +% \stopchemical + +% \startchemical +% \chemical[ONE,Z0,DB,Z][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8] +% \stopchemical + +% \startchemical +% \chemical[ONE,Z0,SB,Z][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8] +% \stopchemical + +% \startchemical +% \chemical[ONE,Z0,DB,CZ][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8] +% \stopchemical + +% \startchemical +% [width=fit,top=2000,bottom=2000, +% scale=small,size=small]% +% \chemical +% [ONE, +% SAVE, +% Z0,SB731,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1, +% RESTORE, +% SAVE, +% SUB4,ONE,Z0,SB3,SB1,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1, +% RESTORE, +% SUB2,ONE,Z0,SB7,SB1,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1] +% [\SR{HC},O,C,O,C_{19}H_{39}, +% \SR{H_{2}C},O,C,O,C_{17}H_{29}, +% \SR{H_{2}C},O,C,O,C_{21}H_{41}] +% \stopchemical + +% \chemical[width=fit,height=fit,frame=on,scale=small] +% [ONE,Z0,MOV7,SB1357,Z017,3OFF5,MOV5,Z0,3OFF5,MOV5,SB15,DB7,Z057,MOV0,MOV3,SB1357,Z013,MOV5,3OFF5,Z0,6OFF5,SB5,Z5] +% [\SL{NH},C,COOH,H,(CH_2)_3,C,H_2H,NH,C,COOH,H,(CH_2)_2,HOOC] +% \stopchemical + +% \chemical[width=fit,height=fit,frame=on,scale=small] +% [ONE,Z0,MOV7,SB1357,Z017,3OFF5,MOV5,Z0,3OFF5,MOV5,SB15,DB7,Z057,MOV0,MOV3,SB1357,Z013,MOV5,3OFF5,Z0,6OFF5,SB5,Z5] +% [\SL{NH},C,COOH,H,(CH_2)_3,C,H_2H,NH,C,COOH,H,(CH_2)_2,HOOC] +% \stopchemical + +% \startchemical[width=fit,top=1500,bottom=3500] +% \chemical[ONE,Z0,DB1,SB3,SB7,Z7,MOV1,Z0,SB3,SB7,Z3,Z7,MOV0,SUB2,SIX,B,R6,C][C,H,C,H,H] +% \chemical[ONE,Z0,DB1,SB3,SB7,Z7,MOV1,Z0,SB3,SB7,Z3,Z7,MOV0,SUB2,SIX,B,R6,C][C,H,C,H,H] +% \bottext{styreen} +% \stopchemical + +% \startchemical +% \chemical[SPACE,PLUS,SPACE] +% \stopchemical +% \startchemical[right=600] +% \chemical[ONE,CZ0][3CH_{3}OH] +% \stopchemical +% \startchemical +% \chemical[SPACE,GIVES,SPACE,SPACE][H^+/H_2O] +% \stopchemical +% \startchemical +% \chemical +% [ONE, +% SAVE, +% Z0,SB7,SB3,SB1,Z1, +% RESTORE, +% SAVE, +% SUB4,ONE,Z0,SB3,SB1,Z1, +% RESTORE, +% SUB2,ONE,Z0,SB7,SB1,Z1] +% [\SR{HC},OH, +% \SR{H_{2}C},OH, +% \SR{H_{2}C},OH] +% \stopchemical +% \startchemical +% \chemical[SPACE,PLUS,SPACE] +% \stopchemical + +% \startchemical +% \chemical +% [ONE, +% SAVE, +% Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1, +% RESTORE, +% SAVE, +% SUB4,ONE,Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1, +% RESTORE, +% SUB2,ONE,Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1] +% [C,O,C_{19}H_{39},O,CH_{3}, +% C,O,C_{17}H_{29},O,CH_{3}, +% C,O,C_{21}H_{41},O,CH_{3}] +% \stopchemical + +% \startchemical[height=4500,bottom=2500] +% \bottext{$\beta$-D-Fructopyranose} +% \chemical[SIX,FRONT,BB,B1236,+SB4,-SB5,Z5,+R12346,+RZ12346,-R12346,-RZ12346][Z_0,+R_1,+R_2,+R_3,+R_4,+R_6,-R_1,-R_2,-R_3,-R_4,-R_6] +% \stopchemical + +% \startchemical[height=4500,bottom=2500] +% \chemical[SIX,FRONT,BB,B] +% \stopchemical + +% \startchemical +% [width=fit,height=fit,frame=on] +% \chemical +% [SIX,DB135,SB246,Z,SR6,RZ6][C,C,N,\SR{HC},N,C,NH_2] +% \chemical +% [SIX,MOV1,DB1,SB23,SS6,Z1..3,SR3,RZ3][N,\SL{CH},N,H] +% \stopchemical + +% \startchemical \chemical[SIX,B,R,RZ1=a] \stopchemical +% \startchemical \chemical[SIX,B,R,RZ1..3=a] \stopchemical +% \startchemical \chemical[SIX,B,R,RZ135=a] \stopchemical +% \startchemical \chemical[SIX,B,R,RZ] [a] \stopchemical +% \startchemical \chemical[SIX,B,R,RZ] [a,b] \stopchemical +% \startchemical \chemical[SIX,B,R,RZ=a] \stopchemical + +% \definechemical[molecule] +% {\chemical +% [ONE,Z0,SB1357, +% SAVE,SUB2,SIX,B,R6,C,RESTORE, +% MOV1,Z0,SB137,MOV1,Z0,SB37,MOV1] +% [C,C,C]} + +% \startchemical[width=fit,height=fit] +% \chemical[molecule,molecule,molecule] +% \stopchemical + +% \definechemical[molecule] +% {\chemical +% [ONE,Z0,SB1357, +% SAVE,SUB2,SIX,B,R6,C,RESTORE, +% MOV1,Z0,SB137,MOV1,Z0,SB37,MOV1]} + +% \startchemical[width=fit,height=fit] +% \chemical[molecule,molecule,molecule][A,B,C,D,E,F,G,H,I] +% \stopchemical + +\stopTEXpage + +% \noindent \startchemical +% \chemical[SIX,B1..3] +% \stopchemical + +% \noindent \startchemical[width=fit,height=fit] % auto5 ipb off5 +% \chemical[SIX,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] +% \stopchemical +% \noindent \startchemical[width=fit,height=fit] % auto5 ipb off5 +% \chemical[SIX,ROT1,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] +% \stopchemical +% \startchemical[width=fit,height=fit] % auto5 ipb off5 +% \chemical[SIX,ROT2,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] +% \stopchemical +% \startchemical[width=fit,height=fit] % auto5 ipb off5 +% \chemical[SIX,ROT3,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] +% \stopchemical +% \startchemical[width=fit,height=fit] % auto5 ipb off5 +% \chemical[SIX,ROT4,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6] +% \stopchemical + +% \startchemical[width=fit,height=fit,axis=on] % auto5 ipb off5 +% \chemical[SIX,B,C,R6,PB:RZ6,ONE,CZ0,OE1,SB5,MOV5,CZ0,OFF5,OE5,PE][CH,CH_2] +% \stopchemical + +% \dontleavehmode \startchemical \chemical[SIX,B,R,RZ][1,2,3,4,5,6,] \stopchemical + +% \start +% \setupchemicalframed[frame=off] +% \dontleavehmode \startchemical[scale=medium,style=slanted,color=red,rulecolor=green,left=2000,right=4000,top=2000,bottom=2000,axis=on] \chemical[SIX,B,R,RZ][1,2,3,4,5,6,] \stopchemical + +% \dontleavehmode +% \startchemical[width=fit,height=fit] +% \chemical[SIX,B][1,2,3,4,5,6] +% \start +% \setupchemical[rulecolor=red] +% \chemical[SIX,R][1,2,3,4,5,6] +% \stop +% \chemical[SIX,RZ][1,2,3,4,5,6] +% \stopchemical +% \stop + +% \stopTEXpage + +% \stoptext + +% \startTEXpage + +% \dontleavehmode \startchemical \chemical[ONE,SB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,DB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,TB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,EP,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,ES,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,ED,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,ET,Z0][0] \stopchemical \quad + + +% \dontleavehmode \startchemical \chemical[ONE,SD,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,LDD,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,RDD,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,HB,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,BB,Z0][0] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,OE,Z0][0] \stopchemical \quad + + +% \dontleavehmode \startchemical \chemical[ONE,SB,Z] [1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,CZ][1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,ZT][a,b,c,d,e,f,g,h] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,ZN][1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,ZBT][1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,ZBN][1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,ZTT][1,2,3,4,5,6,7,8] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,ZTN][1,2,3,4,5,6,7,8] \stopchemical \quad + +% \dontleavehmode \startchemical \chemical[ONE,SB,MOV1,SB] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[ONE,SB,MOV1,SB,MOV3,SB] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,MOV1,B] \stopchemical \quad + + +% \dontleavehmode \startchemical \chemical[ONE,SB,Z0,Z][0,1,2,3,4,5,6] \stopchemical \quad +% \stopTEXpage + + +% \dorecurse{1000}{\dontleavehmode \startchemical \chemical[SIX,B,R,RZ][a,b,c,d,e,f] \stopchemical \quad} + +% \dontleavehmode \startchemical \chemical[SIX,B,R,RT] [a,b,c,d,e,f] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,R,RTT] [a,b,c,d,e,f] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,R,RBT] [a,b,c,d,e,f] \stopchemical \quad + +% \dontleavehmode \startchemical \chemical[SIX,B,R,+R,-R] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B1..4] \stopchemical \quad + +% \dontleavehmode \startchemical \chemical[SIX,B,ZN] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,ZT][A,B,C,D,E,F] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,R,AU] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,R,AD] \stopchemical \quad + +% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,SIX,B] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,FIVE,ROT1,B] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,FOUR,B] \stopchemical \quad +% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,THREE,B] \stopchemical \quad + +% \definechemical[sixring] +% {\chemical[SIX,B,R]} + +% \startchemical[frame=on,width=6000] +% \chemical[sixring,RZ][A,B,C,D,E,F] +% \stopchemical + +% \definechemical[test] +% {\chemical[SIX,SB,Z][A,B,C,D,E,F]} + +% \startchemical +% \chemical[SIX,SB,Z,ADJ1,test,ADJ1,SIX,SB,Z][a,b,c,d,e,f,g,h,j,k,l,m,P,Q,R,S,T,U,W] +% \chemical[ADJ1,SIX,SB,Z][1,2,3,4,5,6] +% \stopchemical + +% \definechemical[test]{\chemical[SIX,SB,Z]} + +% \startchemical +% \chemical[SIX,SB,Z,ADJ1,test,ADJ1,SIX,SB,Z][a,b,c,d,e,f,g,h,j,k,l,m,P,Q,R,S,T,U,W] +% \chemical[ADJ1,SIX,SB,Z][1,2,3,4,5,6] +% \stopchemical + +% \startchemical +% \chemical[ADJ1,SIX,SB,Z][a_1,a_2,a_3,a_4,a_5,\ominus] +% \stopchemical + +% \startchemical +% \chemical[SIX,SB,Z,SAVE,ADJ1,SIX,SB,Z,ADJ1,SIX,SB,Z,RESTORE,ADJ3,SIX,SB,Z][1,2,3,4,5,6,a,b,c,d,e,f,A,B,C,D,E,F,!,!,!,!,!,!] +% \stopchemical + +% $$ +% \startchemical +% \chemical[OPENCOMPLEX] +% \stopchemical +% \startchemical +% \chemical[SIX,SB,Z][1,2,3,4,5,6] +% \stopchemical +% \startchemical +% \chemical[SPACE,GIVES,SPACE][a,b] +% \stopchemical +% \startchemical +% \chemical[SIX,SB,Z][1,2,3,4,5,6] +% \stopchemical +% \startchemical +% \chemical[CLOSECOMPLEX] +% \stopchemical +% $$ + +% \stoptext + +% \page + +% \def\ChemicalKind{SIX} \getbuffer[test-set] +% \def\ChemicalKind{FIVE} \getbuffer[test-set] +% \def\ChemicalKind{FOUR} \getbuffer[test-set] +% \def\ChemicalKind{THREE} \getbuffer[test-set] + +% \startchemical +% \chemical[SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f] +% \chemical[MOV1,SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f] +% \chemical[MOV3,SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f] +% \stopchemical + +\stoptext diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 15d12a584..4772646b9 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua --- merge date : 05/28/09 11:25:26 +-- merge date : 06/02/09 09:32:43 do -- begin closure to overcome local limits and interference @@ -9084,7 +9084,7 @@ function fonts.methods.node.otf.features(head,font,attr) end ra[s] = r end -featurevalue = r and r[1] -- toto: pass to function instead + 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 -- cgit v1.2.3