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 bold title bold bold oeps and more
+
+ a paragraph of text
+ another paragraph of text
+
+
+
+ Another bold title bold bold oeps 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 bold title bold bold oeps and more
-
- a paragraph of text
- another paragraph of text
-
-
-
- Another bold title bold bold oeps 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