summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/chem-str.mkxl14
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkxl45
-rw-r--r--tex/context/base/mkiv/font-ini.mklx2
-rw-r--r--tex/context/base/mkiv/font-pre.mkxl999
-rw-r--r--tex/context/base/mkiv/font-sym.mklx8
-rw-r--r--tex/context/base/mkiv/java-ini.mkxl157
-rw-r--r--tex/context/base/mkiv/lang-def.mkiv29
-rw-r--r--tex/context/base/mkiv/lang-ini.mkxl7
-rw-r--r--tex/context/base/mkiv/lxml-css.lua6
-rw-r--r--tex/context/base/mkiv/lxml-css.mkiv4
-rw-r--r--tex/context/base/mkiv/lxml-css.mkxl76
-rw-r--r--tex/context/base/mkiv/lxml-ctx.mkiv4
-rw-r--r--tex/context/base/mkiv/lxml-ctx.mkxl58
-rw-r--r--tex/context/base/mkiv/lxml-sor.mkxl99
-rw-r--r--tex/context/base/mkiv/math-frc.mkxl113
-rw-r--r--tex/context/base/mkiv/math-inc.lua9
-rw-r--r--tex/context/base/mkiv/math-stc.mklx76
-rw-r--r--tex/context/base/mkiv/mult-low.lua6
-rw-r--r--tex/context/base/mkiv/mult-prm.lua1
-rw-r--r--tex/context/base/mkiv/node-bck.mkxl92
-rw-r--r--tex/context/base/mkiv/node-rul.mkxl618
-rw-r--r--tex/context/base/mkiv/scrn-bar.mkvi8
-rw-r--r--tex/context/base/mkiv/scrp-ini.mkiv8
-rw-r--r--tex/context/base/mkiv/spac-ali.mkxl13
-rw-r--r--tex/context/base/mkiv/spac-hor.mkxl3
-rw-r--r--tex/context/base/mkiv/spac-ver.lmt445
-rw-r--r--tex/context/base/mkiv/spac-ver.mkxl192
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin29864 -> 29918 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin256460 -> 256811 bytes
-rw-r--r--tex/context/base/mkiv/strc-bkm.mkxl182
-rw-r--r--tex/context/base/mkiv/strc-con.mklx4
-rw-r--r--tex/context/base/mkiv/strc-flt.mklx30
-rw-r--r--tex/context/base/mkiv/strc-ind.mkxl128
-rw-r--r--tex/context/base/mkiv/strc-lnt.mklx359
-rw-r--r--tex/context/base/mkiv/strc-lst.mklx1566
-rw-r--r--tex/context/base/mkiv/strc-mat.mkxl1308
-rw-r--r--tex/context/base/mkiv/strc-reg.mkxl5
-rw-r--r--tex/context/base/mkiv/strc-ren.mkxl817
-rw-r--r--tex/context/base/mkiv/strc-syn.mkxl4
-rw-r--r--tex/context/base/mkiv/strc-tag.lmt615
-rw-r--r--tex/context/base/mkiv/strc-tag.mkxl531
-rw-r--r--tex/context/base/mkiv/strc-tnt.mkxl117
-rw-r--r--tex/context/base/mkiv/strc-usr.mkxl169
-rw-r--r--tex/context/base/mkiv/supp-box.lmt16
-rw-r--r--tex/context/base/mkiv/syst-aux.mkxl142
-rw-r--r--tex/context/base/mkiv/syst-ini.mkxl15
-rw-r--r--tex/context/base/mkiv/tabl-ltb.mkiv2
-rw-r--r--tex/context/base/mkiv/tabl-ltb.mkxl6
-rw-r--r--tex/context/base/mkiv/tabl-mis.mkxl294
-rw-r--r--tex/context/base/mkiv/tabl-ntb.mkxl124
-rw-r--r--tex/context/base/mkiv/tabl-tab.mkxl18
-rw-r--r--tex/context/base/mkiv/tabl-tbl.mkxl16
-rw-r--r--tex/context/base/mkiv/tabl-tsp.mkxl575
-rw-r--r--tex/context/base/mkiv/tabl-xtb.mklx15
-rw-r--r--tex/context/base/mkiv/task-ini.mkxl22
-rw-r--r--tex/context/base/mkiv/toks-aux.lmt7
-rw-r--r--tex/context/base/mkiv/typo-dir.mkxl2
-rw-r--r--tex/context/base/mkiv/typo-mar.mkxl5
-rw-r--r--tex/context/modules/mkiv/s-system-macros.mkxl25
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
64 files changed, 9440 insertions, 781 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index e05ed3bf3..5a4a8adf0 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2020.11.17 12:39}
+\newcontextversion{2020.11.18 19:13}
%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/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index c93f19509..a78367225 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.11.17 12:39}
+\edef\contextversion{2020.11.18 19:13}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/chem-str.mkxl b/tex/context/base/mkiv/chem-str.mkxl
index 29b112c0e..5274de949 100644
--- a/tex/context/base/mkiv/chem-str.mkxl
+++ b/tex/context/base/mkiv/chem-str.mkxl
@@ -111,8 +111,8 @@
% size (small medium big)
-\edef\chemicaltoplocation{t}
-\edef\chemicalbotlocation{b}
+% \edef\chemicaltoplocation{t}
+% \edef\chemicalbotlocation{b}
\permanent\protected\def\chemicaltext#1%
{\mathematics
@@ -248,9 +248,9 @@
% kind of compatible, but text sizes instead of math sizes (i.e. tx is larger than scriptsize)
\appendtoks
- \edef\chemicalbodyfont{\chemicalparameter\c!bodyfont}% public?
- \ifempty\chemicalbodyfont
- \switchtobodyfont[\chemicalbodyfont]%
+ \edef\m_bodyfont{\chemicalparameter\c!bodyfont}%
+ \ifempty\m_bodyfont
+ \switchtobodyfont[\m_bodyfont]%
\fi
\getvalue{\??chemicalsize\chemicalparameter\c!size}%
% \to \everystructurechemical
@@ -351,14 +351,14 @@
\box\scratchboxtwo
\egroup}
-\protected\def\chemicalleft#1#2% redundant boxes thanks to visual
+\permanent\protected\def\chemicalleft#1#2% redundant boxes thanks to visual
{\hbox\bgroup % hpack ?
\setstrut
\llap{\chem_box_visual_nop{\strut#1}}%
\chem_box_visual_nop{\strut#2}%
\egroup}
-\protected\def\chemicalright#1#2% redundant boxes thanks to visual
+\permanent\protected\def\chemicalright#1#2% redundant boxes thanks to visual
{\hbox\bgroup % hpack ?
\setstrut
\chem_box_visual_yes{\strut#2}%
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 74eb639aa..b55138767 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2020.11.17 12:39}
+\newcontextversion{2020.11.18 19:13}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index de68f0d2f..bd7941cf1 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.11.17 12:39}
+\edef\contextversion{2020.11.18 19:13}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 07dd01ae5..4a2ea9d5d 100644
--- a/tex/context/base/mkiv/context.mkxl
+++ b/tex/context/base/mkiv/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.11.17 12:39}
+\edef\contextversion{2020.11.18 19:13}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
@@ -223,7 +223,7 @@
\loadmkxlfile{colo-grp} % optional
\loadmkxlfile{colo-ext}
-\loadmarkfile{node-bck} % overloads anch-pgr (experimental and undocumented)
+\loadmkxlfile{node-bck} % overloads anch-pgr (experimental and undocumented)
\loadmarkfile{pack-cut}
@@ -245,22 +245,22 @@
\loadmarkfile{pack-fen}
\loadmkxlfile{lxml-ini}
-\loadmarkfile{lxml-sor}
+\loadmkxlfile{lxml-sor}
\loadmkvifile{typo-prc}
\loadmkivfile{typo-plc}
\loadmklxfile{strc-ini}
-\loadmarkfile{strc-tag}
+\loadmkxlfile{strc-tag}
\loadmkxlfile{strc-doc}
\loadmkxlfile{strc-num}
\loadmkxlfile{strc-mar}
\loadmkxlfile{strc-sbe}
-\loadmkvifile{strc-lst}
+\loadmklxfile{strc-lst}
\loadmkxlfile{strc-sec}
\loadmkxlfile{strc-pag} % hm, depends on core-num
-\loadmarkfile{strc-ren}
-\loadmarkfile{strc-xml}
+\loadmkxlfile{strc-ren}
+%loadmarkfile{strc-xml}
\loadmarkfile{strc-def} % might happen later
\loadmklxfile{strc-ref}
%loadmarkfile{strc-reg}
@@ -288,7 +288,7 @@
\loadmklxfile{strc-des}
\loadmklxfile{strc-enu}
-\loadmarkfile{strc-ind}
+\loadmkxlfile{strc-ind}
\loadmkxlfile{strc-lab}
\loadmkxlfile{strc-syn}
@@ -359,9 +359,9 @@
\loadmarkfile{page-com} % optional (after scrn-pag)
-\loadmarkfile{strc-bkm} % bookmarks
+\loadmkxlfile{strc-bkm} % bookmarks
-\loadmarkfile{java-ini}
+\loadmkxlfile{java-ini}
\loadmkvifile{scrn-fld}
\loadmkvifile{scrn-hlp}
@@ -378,7 +378,7 @@
\loadmklxfile{font-sty}
\loadmkvifile{font-set}
\loadmklxfile{font-emp}
-\loadmarkfile{font-pre}
+\loadmkxlfile{font-pre}
\loadmarkfile{font-unk}
\loadmkxlfile{font-tra}
\loadmkxlfile{font-chk}
@@ -392,7 +392,7 @@
\loadmarkfile{typo-par} % par builders (uses fonts)
\loadmkxlfile{tabl-com}
-\loadmarkfile{tabl-pln}
+%loadmarkfile{tabl-pln}
\loadmkxlfile{tabl-tab} % thrd-tab stripped and merged
@@ -401,13 +401,13 @@
\loadmkxlfile{tabl-nte}
\loadmkxlfile{tabl-ltb}
\loadmkxlfile{tabl-frm}
-\loadmarkfile{tabl-tsp}
+\loadmkxlfile{tabl-tsp}
\loadmklxfile{tabl-xtb}
-\loadmarkfile{tabl-mis}
+\loadmkxlfile{tabl-mis}
\loadmkxlfile{typo-lan}
-\loadmarkfile{lxml-css}
+\loadmkxlfile{lxml-css}
\loadmkxlfile{spac-chr} % depends on fonts
@@ -479,7 +479,6 @@
\loadmarkfile{math-for}
\loadmarkfile{math-def} % also saves some meanings
\loadmkxlfile{math-ali}
-%loadmarkfile{math-arr}
\loadmklxfile{math-stc}
\loadmkxlfile{math-frc}
\loadmarkfile{math-mis}
@@ -494,7 +493,7 @@
%loadmarkfile{math-lan}
\loadmkxlfile{math-toy}
-\loadmarkfile{strc-mat}
+\loadmkxlfile{strc-mat}
\loadmkxlfile{chem-ini}
\loadmkxlfile{chem-str}
@@ -502,13 +501,13 @@
\loadmkxlfile{typo-scr}
\loadmkxlfile{phys-dim}
-\loadmarkfile{node-rul} % beware, defined \underbar so after math
+\loadmkxlfile{node-rul} % beware, defined \underbar so after math
\loadmklxfile{font-sol} % font solutions
\loadmklxfile{strc-not}
-\loadmkvifile{strc-lnt}
-\loadmkivfile{strc-tnt}
-\loadmkivfile{strc-usr}
+\loadmklxfile{strc-lnt}
+\loadmkxlfile{strc-tnt}
+\loadmkxlfile{strc-usr}
\loadmkxlfile{pack-com}
\loadmkxlfile{typo-del}
@@ -549,8 +548,6 @@
\loadmarkfile{cont-log}
-% \loadmarkfile{task-ini}
-
\loadmkxlfile{cldf-ver} % verbatim, this can come late
\loadmkxlfile{cldf-com} % commands, this can come late
@@ -580,7 +577,7 @@
\loadmarkfile{math-inc} % an experiment
\loadmkxlfile{publ-inc} % an experiment
-\loadmarkfile{task-ini}
+\loadmkxlfile{task-ini}
\loadmarkfile{syst-cmp} % compatibility stuff moved here
diff --git a/tex/context/base/mkiv/font-ini.mklx b/tex/context/base/mkiv/font-ini.mklx
index cdd89c5d0..75db6e276 100644
--- a/tex/context/base/mkiv/font-ini.mklx
+++ b/tex/context/base/mkiv/font-ini.mklx
@@ -612,7 +612,7 @@
\def\font_basics_check_text_bodyfont_step#whatever#body% size can be empty (checking needed as \bf is already defined)
{\ifcsname#whatever\endcsname\else
- \setugvalue{#whatever}{#body}%
+ \permanent\setugvalue{#whatever}{#body}%
\fi}
\def\font_basics_check_text_bodyfont#style#alternative#size% size can be empty (checking needed as \bf is already defined)
diff --git a/tex/context/base/mkiv/font-pre.mkxl b/tex/context/base/mkiv/font-pre.mkxl
new file mode 100644
index 000000000..8468fbbd7
--- /dev/null
+++ b/tex/context/base/mkiv/font-pre.mkxl
@@ -0,0 +1,999 @@
+%D \module
+%D [ file=font-pre,
+%D version=2012.01.04, % moved from font-ini
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=Predefined,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Font Macros / Predefined}
+
+\unprotect
+
+%D A basic set of features is defined here.
+
+% beware, base mode + dynamics can give weird effects
+
+% frac : with numr dnom
+%
+% vkrn valt vert vrt2 vpal : when vertical
+%
+% rtlm rtla : in r2l runs
+% ltrm ltra : in l2r runs
+%
+% rvrn : variable fonts
+%
+% rtbd lfbd : opbd
+%
+% rkrf rphf vatu vjmo tjmo rclt psts pstf ljmo haln
+% pres pref nukt
+% abvs abvm blwm blws cjct blwf akhn (indic)
+% half
+% abvf cfar (khmer)
+%
+% ccmp locl calt clig liga rlig
+%
+% mkmk mark kern (palt pwid) curs (by choice but some fonts need it)
+%
+% init medi isol fina (unicode)
+% fin3 fin2 med2 : syriac
+%
+% cpsp : percentage spacing (todo)
+%
+% dtls flac :math
+
+\definefontfeature
+ [always]
+ [mode=node, % we had 'auto', but let's try 'node' for a while and see what the impact is
+ script=auto, % on speed; 'base' just doesn't play well with dynamics; some day we can even
+ autoscript=position,
+ autolanguage=position,
+ kern=yes, % consider skipping the base passes when no base mode is used
+ mark=yes,
+ mkmk=yes,
+ curs=yes]
+
+\definefontfeature
+ [default]
+ [always]
+ [liga=yes,
+% ccmp=yes, % maybe too
+% locl=yes, % maybe too
+% calt=yes, % maybe too
+% clig=yes, % maybe too
+% rlig=yes, % maybe too
+ tlig=yes,
+ trep=yes] % texligatures=yes,texquotes=yes
+
+\definefontfeature
+ [original] % a clone of default so we can revert
+ [default]
+
+\definefontfeature
+ [smallcaps]
+ [always]
+ [smcp=yes,
+ tlig=yes,
+ trep=yes] % texligatures=yes,texquotes=yes
+
+\definefontfeature
+ [oldstyle]
+ [always]
+ [onum=yes,
+ liga=yes,
+ tlig=yes,
+ trep=yes] % texligatures=yes,texquotes=yes
+
+\definefontfeature
+ [inlinenumbers]
+ [pnum=yes,
+ tnum=no]
+
+\definefontfeature
+ [tabularnumbers]
+ [tnum=yes,
+ pnum=no]
+
+\definefontfeature
+ [oldstylenumbers]
+ [onum=yes]
+
+\definefontfeature
+ [zero]
+ [zero=yes]
+
+% \definefontfeature
+% [newstyle]
+% [onum=no]
+
+\definefontfeature % == default unless redefined
+ [ligatures]
+ [always]
+ [liga=yes,
+ tlig=yes,
+ trep=yes]
+
+\definefontfeature
+ [letterspacing]
+ [liga=no,
+ rlig=no,
+ clig=no,
+ dlig=no,
+ ccmp=yes,
+ keepligatures=auto]
+
+\definefontfeature % can be used for type1 fonts
+ [complete]
+ [always]
+ [compose=yes,
+ liga=yes,
+% ccmp=yes,
+% locl=yes,
+% calt=yes,
+% clig=yes,
+% rlig=yes,
+ tlig=yes,
+ trep=yes]
+
+\definefontfeature
+ [none]
+ [mode=none,
+ features=no]
+
+\definefontfeature
+ [semitic-complete]
+ [mode=node,analyze=yes,language=dflt,ccmp=yes,
+ autoscript=position,autolanguage=position,
+ init=yes,medi=yes,fina=yes,isol=yes,
+ % fin2=yes,fin3=yes,med2=yes,
+ mark=yes,mkmk=yes,kern=yes,curs=yes,
+ liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes]
+
+\definefontfeature
+ [semitic-simple]
+ [mode=node,analyze=yes,language=dflt,ccmp=yes,
+ autoscript=position,autolanguage=position,
+ init=yes,medi=yes,fina=yes,isol=yes,
+ % fin2=yes,fin3=yes,med2=yes,
+ mark=yes,mkmk=yes,kern=yes,curs=yes,
+ rlig=yes,calt=yes]
+
+\definefontfeature
+ [arabic]
+ [semitic-complete]
+ [script=arab]
+
+\definefontfeature
+ [syriac]
+ [arabic]
+ [fin2=yes,fin3=yes,med2=yes]
+
+\definefontfeature
+ [reordercombining]
+ [reordercombining=yes]
+
+\definefontfeature
+ [hebrew]
+ [semitic-complete]
+ [script=hebr,
+ reordercombining=yes] % seems to work best with reasonable fonts
+
+\definefontfeature
+ [simplearabic]
+ [semitic-simple]
+ [script=arab]
+
+\definefontfeature
+ [simplehebrew]
+ [semitic-simple]
+ [script=hebr]
+
+% indic
+
+\definefontfeature
+ [indic-common]
+ [mode=node,
+ language=dflt,
+ % localized
+ locl=yes,
+ % positioning
+ kern=yes,
+ dist=yes,
+ % above/below base marks
+ abvm=yes,
+ blwm=yes,
+ % basic shaping
+ nukt=yes,
+ akhn=yes,
+ rphf=yes,
+ % presentation
+ pres=yes,
+ abvs=yes,
+ blws=yes,
+ psts=yes,
+ haln=yes,
+ calt=yes]
+
+\definefontfeature
+ [devanagari-one]
+ [indic-common]
+ [script=deva,
+ % basic shaping
+ rkrf=yes,
+ blwf=yes,
+ half=yes,
+ vatu=yes,
+ cjct=yes]
+
+\definefontfeature
+ [bengali-one]
+ [indic-common]
+ [script=beng,
+ % basic shaping
+ blwf=yes,
+ half=yes,
+ pstf=yes,
+ vatu=yes,
+ cjct=yes,
+ % presentation
+ init=yes]
+
+\definefontfeature
+ [gujarati-one]
+ [indic-common]
+ [script=gujr,
+ % basic shaping
+ rkrf=yes,
+ blwf=yes,
+ half=yes,
+ vatu=yes,
+ cjct=yes]
+
+\definefontfeature
+ [gurmukhi-one]
+ [indic-common]
+ [script=guru,
+ % basic shaping
+ blwf=yes,
+ half=yes,
+ pstf=yes,
+ vatu=yes,
+ cjct=yes]
+
+\definefontfeature
+ [kannada-one]
+ [indic-common]
+ [script=knda,
+ % basic shaping
+ pref=yes,
+ blwf=yes,
+ half=yes,
+ pstf=yes,
+ cjct=yes]
+
+\definefontfeature
+ [malayalam-one]
+ [indic-common]
+ [script=mlym,
+ % basic shaping
+ pref=yes,
+ blwf=yes,
+ half=yes,
+ pstf=yes,
+ cjct=yes]
+
+\definefontfeature
+ [oriya-one]
+ [indic-common]
+ [script=orya,
+ % basic shaping
+ blwf=yes,
+ pstf=yes,
+ cjct=yes]
+
+\definefontfeature
+ [tamil-one]
+ [indic-common]
+ [script=taml,
+ % basic shaping
+ pref=yes,
+ half=yes]
+
+\definefontfeature
+ [telugu-one]
+ [indic-common]
+ [script=telu,
+ % basic shaping
+ pref=yes,
+ blwf=yes,
+ half=yes,
+ pstf=yes,
+ cjct=yes]
+
+\definefontfeature [devanagari-two] [devanagari-one] [script=dev2]
+\definefontfeature [bengali-two] [bengali-one] [script=bng2]
+\definefontfeature [gujarati-two] [gujarati-one] [script=gjr2]
+\definefontfeature [gurmukhi-two] [gurmukhi-one] [script=gur2]
+\definefontfeature [kannada-two] [kannada-one] [script=knd2]
+\definefontfeature [malayalam-two] [malayalam-one] [script=mlm2]
+\definefontfeature [oriya-two] [oriya-one] [script=ory2]
+\definefontfeature [tamil-two] [tamil-one] [script=tml2]
+\definefontfeature [telugu-two] [telugu-one] [script=tel2]
+
+% mongolian
+
+\definefontfeature
+ [mongolian]
+ [default]
+ [script=mong,
+ init=yes,medi=yes,fina=yes,isol=yes,
+ rlig=yes,rclt=yes,calt=yes,
+ %dlig=yes,cswh=yes, % optional
+ mset]
+
+% tibetan
+
+\definefontfeature
+ [tibetan]
+ [always]
+ [script=tibt,
+ language=dflt,
+ locl=yes,
+ ccmp=yes,
+ abvs=yes,
+ blws=yes,
+ calt=yes,
+ liga=yes,
+ abvm=yes,
+ blwm=yes]
+
+% cjk
+
+\definefontfeature
+ [jamoforms]
+ [ljmo=yes,
+ tjmo=yes,
+ vjmo=yes]
+
+% \definefontfeature
+% [japanese]
+% [default]
+% [language=jan]
+
+% \definefontfeature
+% [simplified-chinese]
+% [default]
+% [language=zhs]
+
+% \definefontfeature
+% [traditional-chinese]
+% [default]
+% [language=zht]
+
+% \definefontfeature
+% [chinese]
+% [simplified-chinese]
+
+% \definefontfeature
+% [korean]
+% [default]
+% [language=kor]
+
+% symbols:
+
+\definefontfeature
+ [dingbats]
+ [mode=base,
+ goodies=dingbats,
+ unicoding=yes]
+
+% math:
+
+\definefontfeature
+ [mathematics]
+ [mode=base,
+ kern=yes,
+ % liga=yes, % makes no sense
+ % tlig=yes, % makes no sense
+ % trep=yes, % makes no sense
+ mathnolimitsmode={0,800}, % this looks okay on the average font
+ mathalternates=yes,
+ mathitalics=yes, % we pass them
+ mathdimensions=all,
+ % mathgaps=yes,
+ language=dflt,
+ script=math]
+
+\ifdefined\mathnolimitsmode
+ \mathnolimitsmode\plusone % font driven (only opentype)
+\fi
+
+\ifdefined\mathitalicsmode
+ \mathitalicsmode\plusone % simple noads become zero
+ % \mathitalicsmode\plustwo % idem but inner is kept (for testing)
+\fi
+
+% \adaptfontfeature[*math*][mathnolimitsmode=1000] % only subscript
+
+\definefontfeature
+ [mathematics-l2r]
+ [mathematics]
+ []
+
+% \definefontfeature
+% [mathematics-r2l]
+% [mathematics]
+% [language=ara,
+% rtlm=yes,
+% locl=yes]
+
+\definefontfeature
+ [mathematics-r2l]
+ [mathematics]
+ [rtlm=yes,
+ locl=yes]
+
+\definefontfeature[virtualmath] [mathematics] % downward compatibility
+\definefontfeature[virtualmath-l2r] [mathematics-l2r] % downward compatibility
+\definefontfeature[virtualmath-r2l] [mathematics-r2l] % downward compatibility
+
+\definefontfeature[math-text] [mathematics] [ssty=no]
+\definefontfeature[math-script] [mathematics] [ssty=1,mathsize=yes]
+\definefontfeature[math-scriptscript] [mathematics] [ssty=2,mathsize=yes]
+
+\definefontfeature[math-text-l2r] [mathematics-l2r] [ssty=no]
+\definefontfeature[math-script-l2r] [mathematics-l2r] [ssty=1,mathsize=yes]
+\definefontfeature[math-scriptscript-l2r] [mathematics-l2r] [ssty=2,mathsize=yes]
+
+\definefontfeature[math-text-r2l] [mathematics-r2l] [ssty=no]
+\definefontfeature[math-script-r2l] [mathematics-r2l] [ssty=1,mathsize=yes]
+\definefontfeature[math-scriptscript-r2l] [mathematics-r2l] [ssty=2,mathsize=yes]
+
+\definefontfeature[math-nostack-text] [math-text] [nostackmath=yes]
+\definefontfeature[math-nostack-script] [math-script] [nostackmath=yes]
+\definefontfeature[math-nostack-scriptscript][math-scriptscript][nostackmath=yes]
+
+% \definefontfeature[mathtext] [math-text]
+% \definefontfeature[mathscript] [math-script]
+% \definefontfeature[mathscriptscript] [math-scriptscript]
+
+\definefontfeature
+ [missing]
+ [missing=yes]
+
+%D Nice to have too:
+
+\definefontfeature
+ [quality]
+ [expansion=quality,
+ protrusion=quality]
+
+\definefontfeature
+ [fullprotrusion]
+ [protrusion=pure]
+
+\definefontfeature
+ [slanted]
+ [slant=.2]
+
+% \definefontfeature
+% [boldened]
+% [extend=1.2]
+
+%D Neat:
+
+% By eye:
+%
+% \definefontfeature[boldened-10][effect={width=0.10,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.125,extend=1.025,squeeze=0.99250}]
+% \definefontfeature[boldened-15][effect={width=0.15,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.250,extend=1.050,squeeze=0.98750}]
+% \definefontfeature[boldened-20][effect={width=0.20,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.375,extend=1.075,squeeze=0.98125}]
+% \definefontfeature[boldened-30][effect={width=0.30,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.500,extend=1.100,squeeze=0.97500}]
+%
+% By calculation:
+%
+% \definefontfeature[boldened-10][effect={width=0.10,delta=1.0,hdelta=0.02500,ddelta=0.02500,vshift=0.02500,extend=1.050,squeeze=0.99500}]
+% \definefontfeature[boldened-15][effect={width=0.15,delta=1.0,hdelta=0.05625,ddelta=0.05625,vshift=0.05625,extend=1.075,squeeze=0.99250}]
+% \definefontfeature[boldened-20][effect={width=0.20,delta=1.0,hdelta=0.10000,ddelta=0.10000,vshift=0.10000,extend=1.100,squeeze=0.99000}]
+% \definefontfeature[boldened-30][effect={width=0.30,delta=1.0,hdelta=0.22500,ddelta=0.22500,vshift=0.22500,extend=1.150,squeeze=0.98500}]
+%
+% So we can do this:
+
+\definefontfeature[boldened-10][effect={width=0.10,auto=yes}]
+\definefontfeature[boldened-15][effect={width=0.15,auto=yes}]
+\definefontfeature[boldened-20][effect={width=0.20,auto=yes}]
+\definefontfeature[boldened-25][effect={width=0.25,auto=yes}]
+\definefontfeature[boldened-30][effect={width=0.30,auto=yes}]
+
+\definefontfeature
+ [boldened]
+ [boldened-30]
+
+%D Emoji etc:
+
+\definefontfeature[bandw:overlay][ccmp=yes,dist=yes]
+\definefontfeature[color:overlay][ccmp=yes,dist=yes,colr=yes]
+%definefontfeature[bandw:svg] [ccmp=yes,dist=yes]
+\definefontfeature[color:svg] [ccmp=yes,dist=yes,svg=yes]
+%definefontfeature[bandw:bitmap] [ccmp=yes,dist=yes,sbix=yes]
+\definefontfeature[color:bitmap] [ccmp=yes,dist=yes,sbix=yes] % also cblc
+
+% Plus an automatic one:
+
+\definefontfeature[color] [ccmp=yes,dist=yes,color=auto]
+
+%D We define some colors that are used in tracing (for instance \OPENTYPE\
+%D features). We cannot yet inherit because no colors are predefined.
+
+\definecolor[font:init][r=.75]
+\definecolor[font:medi][g=.75]
+\definecolor[font:fina][b=.75]
+\definecolor[font:isol][r=.75,g=.75] % [y=.75]
+\definecolor[font:mark][r=.75,b=.75] % [m=.75]
+\definecolor[font:rest][b=.75,g=.75] % [c=.75]
+
+\definecolor[font:0] [s=1]
+\definecolor[font:1] [r=.75]
+\definecolor[font:2] [g=.75]
+\definecolor[font:3] [b=.75]
+\definecolor[font:4] [r=.75,g=.75]
+\definecolor[font:5] [r=.75,b=.75]
+\definecolor[font:6] [b=.75,g=.75]
+\definecolor[font:7] [r=.75]
+\definecolor[font:8] [g=.75]
+\definecolor[font:9] [b=.75]
+
+\definecolor[f:r:t][a=1,t=.25,r=1]
+\definecolor[f:g:t][a=1,t=.25,g=1]
+\definecolor[f:b:t][a=1,t=.25,b=1]
+\definecolor[f:c:t][a=1,t=.25,c=1]
+\definecolor[f:m:t][a=1,t=.25,m=1]
+\definecolor[f:y:t][a=1,t=.25,y=1]
+\definecolor[f:k:t][a=1,t=.25,s=0]
+\definecolor[f:s:t][a=1,t=.25,s=0]
+
+\definepalet % weird place
+ [layout]
+ [grid=trace:dr,
+ page=trace:dg,
+ profile=f:s:t,
+ one=f:y:t,
+ mix=f:b:t]
+
+%D Now we're up to some definitions.
+
+\definebodyfontenvironment
+ [\s!default]
+ [ \s!text=1.0,
+ \s!script=0.7,
+ \s!scriptscript=0.5,
+ \s!a=1.200,
+ \s!b=1.440,
+ \s!c=1.728,
+ \s!d=2.074,
+ *=\font_currentfontscale, % wildcard
+ \s!x=0.8,
+ \s!xx=0.6,
+ \v!big=1.2,
+ \v!small=0.8,
+ \c!interlinespace=,
+ \s!em=\v!slanted]
+
+\definebodyfontenvironment
+ [20.7pt]
+ [ \s!text=20.7pt,
+ \s!script=\!!fourteenpointfour,
+ \s!scriptscript=\!!twelvepoint,
+ \s!x=17.3pt,
+ \s!xx=\!!fourteenpointfour,
+ \v!big=20.7pt, % !!!!
+ \v!small=17.3pt]
+
+\definebodyfontenvironment
+ [17.3pt]
+ [ \s!text=17.3pt,
+ \s!script=\!!twelvepoint,
+ \s!scriptscript=\!!tenpoint,
+ \s!x=\!!fourteenpointfour,
+ \s!xx=\!!twelvepoint,
+ \v!big=20.7pt,
+ \v!small=\!!fourteenpointfour]
+
+\definebodyfontenvironment
+ [\!!fourteenpointfour]
+ [ \s!text=\!!fourteenpointfour,
+ \s!script=\!!elevenpoint,
+ \s!scriptscript=\!!ninepoint,
+ \s!x=\!!twelvepoint,
+ \s!xx=\!!tenpoint,
+ \v!big=17.3pt,
+ \v!small=\!!twelvepoint]
+
+\definebodyfontenvironment
+ [\!!twelvepoint]
+ [ \s!text=\!!twelvepoint,
+ \s!script=\!!ninepoint,
+ \s!scriptscript=\!!sevenpoint,
+ \s!x=\!!tenpoint,
+ \s!xx=\!!eightpoint,
+ \v!big=\!!fourteenpointfour,
+ \v!small=\!!tenpoint]
+
+\definebodyfontenvironment
+ [\!!elevenpoint]
+ [ \s!text=\!!elevenpoint,
+ \s!script=\!!eightpoint,
+ \s!scriptscript=\!!sixpoint,
+ \s!x=\!!ninepoint,
+ \s!xx=\!!sevenpoint,
+ \v!big=\!!twelvepoint,
+ \v!small=\!!ninepoint]
+
+\definebodyfontenvironment
+ [\!!tenpoint]
+ [ \s!text=\!!tenpoint,
+ \s!script=\!!sevenpoint,
+ \s!scriptscript=\!!fivepoint,
+ \s!x=\!!eightpoint,
+ \s!xx=\!!sixpoint,
+ \v!big=\!!twelvepoint,
+ \v!small=\!!eightpoint]
+
+\definebodyfontenvironment
+ [\!!ninepoint]
+ [ \s!text=\!!ninepoint,
+ \s!script=\!!sevenpoint,
+ \s!scriptscript=\!!fivepoint,
+ \s!x=\!!sevenpoint,
+ \s!xx=\!!fivepoint,
+ \v!big=\!!elevenpoint,
+ \v!small=\!!sevenpoint]
+
+\definebodyfontenvironment
+ [\!!eightpoint]
+ [ \s!text=\!!eightpoint,
+ \s!script=\!!sixpoint,
+ \s!scriptscript=\!!fivepoint,
+ \s!x=\!!sixpoint,
+ \s!xx=\!!fivepoint,
+ \v!big=\!!tenpoint,
+ \v!small=\!!sixpoint]
+
+\definebodyfontenvironment
+ [\!!sevenpoint]
+ [ \s!text=\!!sevenpoint,
+ \s!script=\!!sixpoint,
+ \s!scriptscript=\!!fivepoint,
+ \s!x=\!!sixpoint,
+ \s!xx=\!!fivepoint,
+ \v!big=\!!ninepoint,
+ \v!small=\!!fivepoint]
+
+\definebodyfontenvironment
+ [\!!sixpoint]
+ [ \s!text=\!!sixpoint,
+ \s!script=\!!fivepoint,
+ \s!scriptscript=\!!fivepoint,
+ \s!x=\!!fivepoint,
+ \s!xx=\!!fivepoint,
+ \v!big=\!!eightpoint,
+ \v!small=\!!fivepoint]
+
+\definebodyfontenvironment
+ [\!!fivepoint]
+ [ \s!text=\!!fivepoint,
+ \s!script=\!!fivepoint,
+ \s!scriptscript=\!!fivepoint,
+ \s!x=\!!fivepoint,
+ \s!xx=\!!fivepoint,
+ \v!big=\!!sevenpoint,
+ \v!small=\!!fivepoint]
+
+\definebodyfontenvironment
+ [\!!fourpoint]
+ [ \s!text=\!!fourpoint,
+ \s!script=\!!fourpoint,
+ \s!scriptscript=\!!fourpoint,
+ \s!x=\!!fourpoint,
+ \s!xx=\!!fourpoint,
+ \v!big=\!!sixpoint,
+ \v!small=\!!fourpoint]
+
+\definebodyfontswitch [fourteenpointfour] [\!!fourteenpointfour]
+\definebodyfontswitch [twelvepoint] [\!!twelvepoint]
+\definebodyfontswitch [elevenpoint] [\!!elevenpoint]
+\definebodyfontswitch [tenpoint] [\!!tenpoint]
+\definebodyfontswitch [ninepoint] [\!!ninepoint]
+\definebodyfontswitch [eightpoint] [\!!eightpoint]
+\definebodyfontswitch [sevenpoint] [\!!sevenpoint]
+\definebodyfontswitch [sixpoint] [\!!sixpoint]
+\definebodyfontswitch [fivepoint] [\!!fivepoint]
+\definebodyfontswitch [fourpoint] [\!!fourpoint]
+
+%D So far.
+
+\definefontstyle [\s!hw] [\s!hw]
+\definefontstyle [\s!cg] [\s!cg]
+
+\definefontstyle [\v!roman,\v!serif,\v!regular] [\s!rm]
+\definefontstyle [\v!sansserif,\v!sans,\v!support] [\s!ss]
+\definefontstyle [\v!teletype,\v!type,\v!mono] [\s!tt]
+\definefontstyle [\v!handwritten] [\s!hw]
+\definefontstyle [\v!calligraphic] [\s!cg]
+\definefontstyle [\v!math,\v!mathematics] [\s!mm]
+
+\definefontalternative[\s!tf]
+\definefontalternative[\s!bf]
+\definefontalternative[\s!it]
+\definefontalternative[\s!sl]
+\definefontalternative[\s!bs]
+\definefontalternative[\s!bi]
+\definefontalternative[\s!sc]
+
+\definefontsize[\s!a] \definefontsize[\s!b]
+\definefontsize[\s!c] \definefontsize[\s!d]
+
+\definealternativestyle [\v!mediaeval] [\os] []
+\definealternativestyle [\v!normal] [\tf] []
+\definealternativestyle [\v!bold] [\bf] []
+\definealternativestyle [\v!type] [\tt] []
+\definealternativestyle [\v!mono] [\tt] []
+\definealternativestyle [\v!slanted] [\sl] []
+\definealternativestyle [\v!italic] [\it] []
+\definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] []
+\definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] []
+
+\definealternativestyle [\v!small,\v!smallnormal] [\setsmallbodyfont\tf] []
+\definealternativestyle [\v!smallbold] [\setsmallbodyfont\bf] []
+\definealternativestyle [\v!smalltype] [\setsmallbodyfont\tt] []
+\definealternativestyle [\v!smallitalic,\v!smallslanted] [\setsmallbodyfont\sl] []
+\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\setsmallbodyfont\bs] []
+\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\setsmallbodyfont\bi] []
+
+\definealternativestyle [\v!bigger] [\setbigbodyfont \tf] []
+\definealternativestyle [\v!smaller] [\setsmallbodyfont\tf] []
+
+\definealternativestyle [\v!sans,\v!sansserif] [\ss]
+\definealternativestyle [\v!roman,\v!serif,\v!regular] [\rm]
+\definealternativestyle [\v!handwritten] [\hw]
+\definealternativestyle [\v!calligraphic] [\cg]
+
+\definealternativestyle [\v!sansnormal] [\ss\tf] []
+\definealternativestyle [\v!sansbold] [\ss\bf] []
+\definealternativestyle [\v!serifnormal] [\rm\tf] []
+\definealternativestyle [\v!serifbold] [\rm\bf] []
+\definealternativestyle [\v!mononormal] [\tt\tf] []
+\definealternativestyle [\v!monobold] [\tt\bf] []
+
+\definealternativestyle [typeface] [\typeface] [] % no translation here (quite basic)
+\definealternativestyle [boldface] [\boldface] []
+\definealternativestyle [slantedface] [\slantedface] []
+\definealternativestyle [italicface] [\italicface] []
+\definealternativestyle [swapface] [\swapface] []
+
+\definealternativestyle [emphasize] [\em] [\em] % new
+
+% For Alan:
+
+\definealternativestyle
+ [\v!camel]
+ [{\setcharactercasing[\v!camel]}]
+ [{\setcharactercasing[\v!camel]}]
+
+% % maybe we need interface neutral as well (for use in cld):
+%
+% \letcscsname\mediaeval \csname\v!mediaeval \endcsname
+% \letcscsname\normal \csname\v!normal \endcsname
+% \letcscsname\bold \csname\v!bold \endcsname
+% \letcscsname\mono \csname\v!mono \endcsname
+% \letcscsname\slanted \csname\v!slanted \endcsname
+% \letcscsname\italic \csname\v!italic \endcsname
+% \letcscsname\boldslanted \csname\v!boldslanted \endcsname
+% \letcscsname\slantedbold \csname\v!slantedbold \endcsname
+% \letcscsname\bolditalic \csname\v!bolditalic \endcsname
+% \letcscsname\italicbold \csname\v!italicbold \endcsname
+%
+% \letcscsname\small \csname\v!small \endcsname
+% \letcscsname\smallnormal \csname\v!smallnormal \endcsname
+% \letcscsname\smallbold \csname\v!smallbold \endcsname
+% \letcscsname\smalltype \csname\v!smalltype \endcsname
+% \letcscsname\smallslanted \csname\v!smallslanted \endcsname
+% \letcscsname\smallboldslanted\csname\v!smallboldslanted\endcsname
+% \letcscsname\smallslantedbold\csname\v!smallslantedbold\endcsname
+% \letcscsname\smallbolditalic \csname\v!smallbolditalic \endcsname
+% \letcscsname\smallitalicbold \csname\v!smallitalicbold \endcsname
+%
+% \letcscsname\bigger \csname\v!bigger \endcsname
+% \letcscsname\smaller \csname\v!smaller \endcsname
+%
+% \letcscsname\sans \csname\v!sans \endcsname
+% \letcscsname\sansserif \csname\v!sansserif \endcsname
+% \letcscsname\sansbold \csname\v!sansbold \endcsname
+
+%D We can go on and on and on:
+%D
+%D \starttyping
+%D \setupbodyfontenvironment[default][p=0.8,q=0.6]
+%D \definefontsize[p]
+%D \definefontsize[q]
+%D \stoptyping
+
+%D Slow but handy:
+
+\definealternativestyle [\v!smallbodyfont] [\setsmallbodyfont] []
+\definealternativestyle [\v!bigbodyfont] [\setbigbodyfont] []
+
+%D We treat {\sc Small Caps} and \cap {Pseudo Caps} a bit different. We also provide
+%D an \WORD {uppercase} style.
+
+\definealternativestyle [\v!WORD] [{\setcharactercasing[\v!WORD ]}] [{\setcharactercasing[\v!WORD ]}]
+\definealternativestyle [\v!word] [{\setcharactercasing[\v!word ]}] [{\setcharactercasing[\v!word ]}]
+\definealternativestyle [\v!Word] [{\setcharactercasing[\v!Word ]}] [{\setcharactercasing[\v!Word ]}]
+\definealternativestyle [\v!Words] [{\setcharactercasing[\v!Words ]}] [{\setcharactercasing[\v!Words ]}]
+\definealternativestyle [\v!capital] [{\setcharactercasing[\v!capital]}] [{\setcharactercasing[\v!capital]}]
+\definealternativestyle [\v!Capital] [{\setcharactercasing[\v!Capital]}] [{\setcharactercasing[\v!Capital]}]
+\definealternativestyle [\v!mixed] [{\setcharactercasing[\v!mixed ]}] [{\setcharactercasing[\v!mixed ]}]
+
+\definealternativestyle [\v!cap] [{\setcharactercasing[\v!cap ]}] [{\setcharactercasing[\v!cap ]}]
+\definealternativestyle [\v!Cap] [{\setcharactercasing[\v!Cap ]}] [{\setcharactercasing[\v!Cap ]}]
+
+%D From now (2013-03-17) on we have:
+
+\definefontfeature[f:smallcaps][smcp=yes]
+\definefontfeature[f:oldstyle] [onum=yes]
+\definefontfeature[f:tabular] [tnum=yes]
+\definefontfeature[f:superiors][sups=yes]
+\definefontfeature[f:inferiors][subs=yes]
+\definefontfeature[f:fractions][frac=yes]
+\definefontfeature[f:kern] [kern=yes]
+\definefontfeature[f:kerns] [kern=yes]
+
+\definealternativestyle [\v!smallcaps] [\setsmallcaps] [\setsmallcaps]
+\definealternativestyle [\v!oldstyle] [\setoldstyle ] [\setoldstyle ]
+\definealternativestyle [\v!fractions] [\setfractions\resetbreakpoints] [\setfractions\resetbreakpoints]
+
+\permanent\protected\def\setsmallcaps{\doaddfeature{f:smallcaps}}
+\permanent\protected\def\setoldstyle {\doaddfeature{f:oldstyle}}
+\permanent\protected\def\settabular {\doaddfeature{f:tabular}}
+\permanent\protected\def\setsuperiors{\doaddfeature{f:superiors}}
+\permanent\protected\def\setfractions{\doaddfeature{f:fractions}}
+
+% \permanent\protected\def\frc#1#2%
+% {\dontleavehmode
+% \begingroup
+% \addff{frac}%
+% \resetbreakpoints
+% #1/#2%
+% \endgroup}
+
+%D \macros
+%D {uppercasing, lowercasing}
+
+\definefontfeature[lowercasing][lowercasing=yes]
+\definefontfeature[uppercasing][uppercasing=yes]
+
+\permanent\protected\def\uppercasing{\addff{uppercasing}}
+\permanent\protected\def\lowercasing{\addff{lowercasing}}
+
+%D \macros
+%D {tinyfont}
+%D
+%D By default we load the Computer Modern Roman fonts (but not yet at this moment)
+%D and activate the 12pt roman bodyfont. Sans serif and teletype are also available
+%D and can be called for by \type {\ss} and \type {\tt}. Loading takes place
+%D elsewhere. For tracing purposes we define:
+
+\definefont[tinyfont][file:dejavusansmono at 1ex]
+
+%D \macros
+%D {infofont}
+%D
+%D The second situation occurs when we enable the info mode, and put all kind of
+%D status information in the margin. We don't want huge switches to the main
+%D bodyfont and style, so here too we use a direct method.
+
+\pushoverloadmode
+
+\let\infofont \relax
+\let\infofontbold \relax
+\let\smallinfofont \relax
+\let\smallinfofontbold\relax
+
+\definefont[infofont] [file:dejavusansmono*none at 6pt]
+\definefont[infofontbold] [file:dejavusansmono-bold*none at 6pt]
+\definefont[smallinfofont] [file:dejavusansmono*none at 3pt]
+\definefont[smallinfofontbold][file:dejavusansmono-bold*none at 3pt]
+
+%D Optimization (later we overload in math). Also needed in order to get \type {\ss}
+%D properly defined.
+
+\permanent\protected\def\normaltf{\let\fontalternative\s!tf\font_helpers_synchronize_font}
+\permanent\protected\def\normalbf{\let\fontalternative\s!bf\font_helpers_synchronize_font}
+\permanent\protected\def\normalit{\let\fontalternative\s!it\font_helpers_synchronize_font}
+\permanent\protected\def\normalsl{\let\fontalternative\s!sl\font_helpers_synchronize_font}
+\permanent\protected\def\normalbi{\let\fontalternative\s!bi\font_helpers_synchronize_font}
+\permanent\protected\def\normalbs{\let\fontalternative\s!bs\font_helpers_synchronize_font}
+
+\let\tf\normaltf
+\let\bf\normalbf
+\let\it\normalit
+\let\sl\normalsl
+\let\bi\normalbi
+\let\bs\normalbs
+
+\permanent\protected\def\normalrm{\font_helpers_set_current_font_style{\s!rm}}
+\permanent\protected\def\normalss{\font_helpers_set_current_font_style{\s!ss}}
+\permanent\protected\def\normaltt{\font_helpers_set_current_font_style{\s!tt}}
+
+\let\rm\normalrm
+\let\ss\normalss
+\let\tt\normaltt
+
+\popoverloadmode
+
+\protect \endinput
+
+% LM math vs CM math (analysis by Taco):
+%
+% Computer Modern Roman : Donald Knuth
+% Latin Modern : LM Font Revision Team
+%
+% lmex10.tfm % identical
+% lmmi5.tfm % identical
+% lmmi6.tfm % identical
+% lmmi7.tfm % identical
+% lmmi8.tfm % identical
+% lmmi9.tfm % identical
+% lmmi10.tfm % identical
+% lmmi12.tfm % identical
+% lmmib10.tfm % identical
+% lmsy5.tfm % extra chars: 254,255 (octal)
+% lmsy6.tfm % extra chars: 254,255 (octal)
+% lmsy7.tfm % extra chars: 254,255 (octal)
+% lmsy8.tfm % extra chars: 254,255 (octal)
+% lmsy9.tfm % extra chars: 254,255 (octal)
+% lmsy10.tfm % extra chars: 254,255 (octal)
+% lmbsy10.tfm % extra chars: 254,255 (octal)
+%
+% From the 'AMS' set:
+%
+% lmmib5.tfm % identical
+% lmmib7.tfm % identical
+% lmbsy5.tfm % extra chars: 254,255 (octal)
+% lmbsy7.tfm % extra chars: 254,255 (octal)
+%
+% The two extra characters are:
+%
+% /lessorequalslant
+% /greaterorequalslant
+
+% \unprotect
+%
+% \definehighlight[\v!italic ][\c!command=\v!no,\c!style=\v!italic]
+% \definehighlight[\v!bold ][\c!command=\v!no,\c!style=\v!bold]
+% \definehighlight[\v!bolditalic][\c!command=\v!no,\c!style=\v!bolditalic]
+% \definehighlight[\v!mono] [\c!command=\v!no,\c!style=\v!mono]
+% \definehighlight[\v!monobold] [\c!command=\v!no,\c!style=\v!monobold]
+%
+% \definehighlight[important] [\c!command=\v!no,\c!style=\v!bold]
+% \definehighlight[unimportant] [\c!command=\v!no,\c!color=darkgray]
+% \definehighlight[warning] [\c!command=\v!no,\c!style=\v!bold,\c!color=darkblue]
+% \definehighlight[error] [\c!command=\v!no,\c!style=\v!bold,\c!color=darkred]
+%
+% \protect
+%
+% \starttext
+% \highlight[italic] {italic}
+% \highlight[bolditalic] {bolditalic}
+% \highlight[bold] {bold}
+% \highlight[mono] {mono}
+% \highlight[monobold] {monobold}
+% \highlight[important] {important}
+% \highlight[unimportant]{unimportant}
+% \highlight[warning] {warning}
+% \highlight[error] {error}
+% \stoptext
diff --git a/tex/context/base/mkiv/font-sym.mklx b/tex/context/base/mkiv/font-sym.mklx
index 80b47edab..d95314099 100644
--- a/tex/context/base/mkiv/font-sym.mklx
+++ b/tex/context/base/mkiv/font-sym.mklx
@@ -180,10 +180,10 @@
\permanent\protected\def\getscaledglyph#scale#name#content%
{{\setscaledstyledsymbolicfont\fontbody{#scale}{#name}\doifelsenumber{#content}\char\donothing#content}}
-\let\getglyph \getglyphstyled % old
-\let\getrawglyph \getglyphdirect % old
-\let\symbolicsizedfont\setscaledstyledsymbolicfont % old
-\let\symbolicfont \setstyledsymbolicfont % old
+\aliased\let\getglyph \getglyphstyled % old, soon obsolete
+\aliased\let\getrawglyph \getglyphdirect % old, soon obsolete
+\aliased\let\symbolicsizedfont\setscaledstyledsymbolicfont % old, soon obsolete
+\aliased\let\symbolicfont \setstyledsymbolicfont % old, soon obsolete
\permanent\protected\def\symbolicscaledfont{\setscaledstyledsymbolicfont\fontbody}
diff --git a/tex/context/base/mkiv/java-ini.mkxl b/tex/context/base/mkiv/java-ini.mkxl
new file mode 100644
index 000000000..513dc20e3
--- /dev/null
+++ b/tex/context/base/mkiv/java-ini.mkxl
@@ -0,0 +1,157 @@
+%D \module
+%D [ file=java-ini,
+%D version=1998.01.30,
+%D title=\CONTEXT\ JavaScript Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt JavaScript Macros / Initialization}
+
+\registerctxluafile{java-ini}{}
+
+\unprotect
+
+%D \macros
+%D {JS*}
+%D
+%D Because \JAVASCRIPT's are activated by the user, for instance by activating on a
+%D button, their support is closely related to the referencing mechanism.
+%D Integration takes place by
+%D
+%D \starttyping
+%D \goto{calculate total}[Sum()]
+%D \stoptyping
+%D
+%D The \type {()} classify this as a script. If they are absent, the keyword is
+%D treated as a normal reference. One can pass arguments to such a script by saying:
+%D
+%D \starttyping
+%D \goto{calculate total}[Sum(1.5,2.3)]
+%D \stoptyping
+
+%D \macros
+%D {startJScode}
+%D
+%D A piece of \JAVASCRIPT\ code is defined by saying:
+%D
+%D \starttyping
+%D \startJScode{name}
+%D name = 4 ;
+%D \stopJScode
+%D \stoptyping
+%D
+%D This assumes uses no preamble or presumes that the preamble is always loaded, the
+%D next definition also tells \CONTEXT\ to actually include the preamble needed.
+%D
+%D \starttyping
+%D \startJScode{uses} used {later}
+%D uses = 6 ;
+%D \stopJScode
+%D \stoptyping
+%D
+%D \macros
+%D {startJSpreamble}
+%D
+%D One can define insert \JAVASCRIPT\ code at the document level by using:
+%D
+%D \starttyping
+%D \startJSpreamble{oeps}
+%D oeps = 1 ;
+%D \stopJSpreamble
+%D \stoptyping
+%D
+%D which is the same as:
+%D
+%D \starttyping
+%D \startJSpreamble{now} used now
+%D now = 2 ;
+%D \stopJSpreamble
+%D \stoptyping
+%D
+%D while the next definition is only included when actually used.
+%D
+%D \starttyping
+%D \startJSpreamble{later} used later
+%D later = 3 ;
+%D \stopJSpreamble
+%D \stoptyping
+%D
+%D This command may be used more that once, but always before the first page is
+%D shipped out.
+%D
+%D \macros
+%D {setJSpreamble, addtoJSpreamble}
+%D
+%D In addition to the previous preamble definitions, we can set a preamble \quote
+%D {in||line} and add tokens to a preamble.
+%D
+%D \macros
+%D {useJSpreamblenow}
+%D
+%D This macro can be used to force inclusion of postponed \JAVASCRIPT\ preambles.
+
+\def\m_java_escape_u{\letterbackslash u}
+
+\permanent\protected\def\startJScode
+ {\begingroup
+ \obeylualines
+ \obeyluatokens
+ \let\u\m_java_escape_u
+ \java_start_code}
+
+\def\java_start_code#1\stopJScode
+ {\normalexpanded{\endgroup\clf_storejavascriptcode{#1}}}
+
+\aliased\let\stopJScode\relax
+
+\permanent\protected\def\startJSpreamble
+ {\begingroup
+ \obeylualines
+ \obeyluatokens
+ \let\u\m_java_escape_u
+ \java_start_preamble}
+
+\def\java_start_preamble#1\stopJSpreamble
+ {\normalexpanded{\endgroup\clf_storejavascriptpreamble{#1}}}
+
+\aliased\let\stopJSpreamble\relax
+
+\permanent\protected\def\setJSpreamble #1#2{\clf_setjavascriptpreamble {#1}{#2}}
+\permanent\protected\def\addtoJSpreamble#1#2{\clf_addtojavascriptpreamble{#1}{#2}}
+
+%D \macros
+%D {useJSscripts}
+%D
+%D In due time, users will build their collections of scripts, which can be used
+%D (loaded) when applicable. Although not all public, we will provide some general
+%D purpose scripts, collected in files with names like \type {java-...}. One can
+%D load these scripts with \type {\useJSscripts}, like:
+%D
+%D \starttyping
+%D \useJSscripts[fld]
+%D \stoptyping
+%D
+%D The not so complicated implementation of this macro is:
+
+\permanent\tolerant\protected\def\useJSscripts[#1]#*[#2]%
+ {\clf_usejavascriptscripts {#1}% two steps as this one calls tex code
+ \clf_usejavascriptpreamble{#2}}% so this one comes later
+
+\permanent\tolerant\protected\def\useJSpreamble[#1]%
+ {\clf_usejavascriptpreamble{#1}}% so this one comes later
+
+%D Here:
+
+\definefilesynonym[java-imp-fld.mkiv] [java-imp-fields.mkiv]
+\definefilesynonym[java-imp-stp.mkiv] [java-imp-steps.mkiv]
+\definefilesynonym[java-imp-fil.mkiv] [java-imp-print.mkiv]
+\definefilesynonym[java-imp-rhh.mkiv] [java-imp-highlight.mkiv]
+\definefilesynonym[java-imp-exa.mkiv] [java-imp-example.mkiv]
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/lang-def.mkiv b/tex/context/base/mkiv/lang-def.mkiv
index f2364a128..5698bb4af 100644
--- a/tex/context/base/mkiv/lang-def.mkiv
+++ b/tex/context/base/mkiv/lang-def.mkiv
@@ -256,17 +256,18 @@
\c!date={\v!day,{.},\space,\v!month,\space,\v!year}]
\installlanguage
- [\s!sl]
- [\c!spacing=\v!packed,
- \c!leftsentence=\hbox{\endash\space},
- \c!rightsentence=\hbox{\space\endash},
- \c!leftsubsentence=\endash,
- \c!rightsubsentence=\endash,
- \c!leftquote=\guilsingleright,
- \c!rightquote=\guilsingleleft,
- \c!leftquotation=\rightguillemot,
- \c!rightquotation=\leftguillemot,
- \c!date={\v!day,{.},\space,\v!month,\space,\v!year}]
+ [\s!sl]
+ [\c!command=\v!no,
+ \c!spacing=\v!packed,
+ \c!leftsentence=\hbox{\endash\space},
+ \c!rightsentence=\hbox{\space\endash},
+ \c!leftsubsentence=\endash,
+ \c!rightsubsentence=\endash,
+ \c!leftquote=\guilsingleright,
+ \c!rightquote=\guilsingleleft,
+ \c!leftquotation=\rightguillemot,
+ \c!rightquotation=\leftguillemot,
+ \c!date={\v!day,{.},\space,\v!month,\space,\v!year}]
\installlanguage [\s!polish] [\s!pl]
\installlanguage [\s!czech] [\s!cs]
@@ -509,7 +510,8 @@
\installlanguage
[\s!lt]
- [\c!spacing=\v!packed,
+ [\c!command=\v!no,
+ \c!spacing=\v!packed,
\c!leftsentence=\emdash,
\c!rightsentence=\emdash,
\c!leftsubsentence=\emdash,
@@ -653,7 +655,8 @@
\installlanguage
[\s!it]
- [\c!spacing=\v!packed,
+ [\c!command=\v!no,
+ \c!spacing=\v!packed,
\c!leftsentence=\emdash,
\c!rightsentence=\emdash,
\c!leftsubsentence=\endash,
diff --git a/tex/context/base/mkiv/lang-ini.mkxl b/tex/context/base/mkiv/lang-ini.mkxl
index 0565a7844..8ca8d7e8e 100644
--- a/tex/context/base/mkiv/lang-ini.mkxl
+++ b/tex/context/base/mkiv/lang-ini.mkxl
@@ -197,8 +197,8 @@
\doifelselanguage{#1}
{\getparameters[\??language#1][#2]}
{\setvalue{\??languagelinked#1}{#1}%
- \lang_basics_install_indeed{#1}{#1}%
- \getparameters[\??language#1][\c!state=\v!start,#2]}%
+ \getparameters[\??language#1][\c!state=\v!start,#2]%
+ \lang_basics_install_indeed{#1}{#1}}%
\edef\currentsetuplanguage{#1}%
\clf_definelanguage{#1}{\specificlanguageparameter{#1}\s!default}%
\the\everysetuplanguage
@@ -209,7 +209,8 @@
\fi}
\def\lang_basics_install_indeed#1#2%
- {\ifcsname#1\endcsname\else\setuvalue{#1}{\lang_basics_set_current[#2]}\fi}
+ {\doifnot{\specificlanguageparameter{#1}\c!command}\v!no
+ {\ifcsname#1\endcsname\else\frozen\instance\setuvalue{#1}{\lang_basics_set_current[#2]}\fi}}
%D When the second argument is a language identifier, a synonym is created. This
%D feature is present because we used dutch mnemonics in the dutch version, but
diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua
index f783a9224..76cc4891e 100644
--- a/tex/context/base/mkiv/lxml-css.lua
+++ b/tex/context/base/mkiv/lxml-css.lua
@@ -1065,13 +1065,15 @@ end
-- -- faster interface (1.02):
interfaces.implement {
- name = "xmlstylevalue",
+ name = "xmlcssstylevalue",
+ public = true,
actions = css.stylevalue,
arguments = "2 strings",
}
interfaces.implement {
- name = "xmlmappedstylevalue",
+ name = "xmlcssmappedstylevalue",
+ public = true,
actions = css.mappedstylevalue,
arguments = "3 strings",
}
diff --git a/tex/context/base/mkiv/lxml-css.mkiv b/tex/context/base/mkiv/lxml-css.mkiv
index 04000a6ca..271afdb7d 100644
--- a/tex/context/base/mkiv/lxml-css.mkiv
+++ b/tex/context/base/mkiv/lxml-css.mkiv
@@ -69,8 +69,8 @@
% \xmlregistersetup{html:settings}
% \xmlprocessbuffer{main}{temp}{}
-\let\xmlcssstylevalue \clf_xmlstylevalue
-\let\xmlcssmappedstylevalue\clf_xmlmappedstylevalue
+% \xmlcssstylevalue % defined at lua end
+% \xmlcssmappedstylevalue % defined at lua end
\protect \endinput
diff --git a/tex/context/base/mkiv/lxml-css.mkxl b/tex/context/base/mkiv/lxml-css.mkxl
new file mode 100644
index 000000000..c7c8d8afd
--- /dev/null
+++ b/tex/context/base/mkiv/lxml-css.mkxl
@@ -0,0 +1,76 @@
+%D \module
+%D [ file=lxml-css,
+%D version=2010.01.28,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Css Helpers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\registerctxluafile{lxml-css}{}
+
+\unprotect
+
+\permanent\def\ctxmodulecss#1{\ctxlua{moduledata.css.#1}}
+
+% No stable interface yet.
+
+% \edef\CellPadding{\xmlatt{#1}{cellpadding}}
+% \ifx\CellPadding\empty
+% \edef\CellPadding{.25ex}
+% \else
+% \edef\CellPadding{\cssgetsinglepadding{\xmlatt{#1}{cellpadding}}}
+% \fi
+%
+% \starttexdefinition cssgetsinglepadding #1
+% \ctxlua {
+% context((moduledata.css.padding(
+% "#1",
+% \number\dimexpr0.1ex,
+% \number\dimexpr0.01\hsize,
+% \number\dimexpr1ex,
+% \number\dimexpr1em
+% ))) % returns 4 values therefore ()
+% }sp
+% \stoptexdefinition
+
+% \startxmlsetups html:settings
+% \xmlsetsetup{#1}{p}{html:p}
+% \stopxmlsetups
+%
+% \xmlmapvalue{ctx-before} {one} {\page BEFORE\par}
+% \xmlmapvalue{ctx-after} {two} {\par AFTER\page}
+% \xmlmapvalue{text-decoration}{underline}{U}
+% \xmlmapvalue{text-decoration}{overline} {O}
+%
+% \startxmlsetups html:p
+% \testfeatureonce{100000}{
+% \edef\foo{\xmlcssstylevalue{#1}{ctx-before}\xmlcssstylevalue{#1}{ctx-after}}
+% }
+% \page {\tttf style="\xmlatt{#1}{style}"} : \elapsedtime\ s \page
+% \xmlvalue{ctx-before}{\xmlcssstylevalue{#1}{ctx-before}}{}
+% \xmlflush{#1}
+% (\xmlcssstylevalue{#1}{text-decoration})
+% (\xmlcssmappedstylevalue{#1}{text-decoration}{text-decoration})
+% \xmlvalue{ctx-after} {\xmlcssstylevalue{#1}{ctx-after}}{}
+% \stopxmlsetups
+%
+% \startbuffer[temp]
+% <body>
+% <p style='ctx-before: one; text-decoration: underline overline; ctx-after: two;'>foo 1</p>
+% <p>foo 2</p>
+% </body>
+% \stopbuffer
+%
+% \xmlregistersetup{html:settings}
+% \xmlprocessbuffer{main}{temp}{}
+
+% \xmlcssstylevalue % defined at lua end
+% \xmlcssmappedstylevalue % defined at lua end
+
+\protect \endinput
+
diff --git a/tex/context/base/mkiv/lxml-ctx.mkiv b/tex/context/base/mkiv/lxml-ctx.mkiv
index e0beb22bf..7d44d61be 100644
--- a/tex/context/base/mkiv/lxml-ctx.mkiv
+++ b/tex/context/base/mkiv/lxml-ctx.mkiv
@@ -11,8 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D Experimental. This might change! Also, it might become a module
-%D instead if core code.
+%D Experimental. This might change! Also, it might become a module instead if
+%D core code.
\writestatus{loading}{ConTeXt XML Support / Goodies}
diff --git a/tex/context/base/mkiv/lxml-ctx.mkxl b/tex/context/base/mkiv/lxml-ctx.mkxl
new file mode 100644
index 000000000..f4b2edc79
--- /dev/null
+++ b/tex/context/base/mkiv/lxml-ctx.mkxl
@@ -0,0 +1,58 @@
+%D \module
+%D [ file=lxml-ctx,
+%D version=2007.08.17,
+%D title=\CONTEXT\ \XML\ Support,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Experimental. This might change! Also, it might become a module
+%D instead if core code.
+
+\writestatus{loading}{ConTeXt XML Support / Goodies}
+
+\registerctxluafile{lxml-ctx}{}
+
+\unprotect
+
+\settrue \xmllshowbuffer
+\setfalse\xmllshowtitle
+\settrue \xmllshowwarning
+
+\definehead
+ [lshowtitle]
+ [subsubsubsubsubject]
+
+\setuphead
+ [lshowtitle]
+ [\c!style=\tta]
+
+\permanent\protected\def\xmllshow#1%
+ {\ctxlua{xml.ctx.tshow {
+ pattern = \!!bs\detokenize{#1}\!!es,
+ \ifconditional\xmllshowtitle
+ title = "lshowtitle",
+ \fi
+ \ifconditional\xmllshowwarning
+ warning = true,
+ \fi
+ } }}
+
+\permanent\protected\def\xmllshowbuffer#1#2#3%
+ {\ctxlua{xml.ctx.tshow {
+ pattern = \!!bs\detokenize{#2}\!!es,
+ \ifconditional\xmllshowbuffer
+ xmlroot = "#1",
+ attribute = "#3",
+ \fi
+ \ifconditional\xmllshowwarning
+ warning = true,
+ \fi
+ } }}
+
+\protect
diff --git a/tex/context/base/mkiv/lxml-sor.mkxl b/tex/context/base/mkiv/lxml-sor.mkxl
new file mode 100644
index 000000000..798047e04
--- /dev/null
+++ b/tex/context/base/mkiv/lxml-sor.mkxl
@@ -0,0 +1,99 @@
+%D \module
+%D [ file=lxml-sor,
+%D version=2009.08.24,
+%D title=\CONTEXT\ \XML\ Support,
+%D subtitle=Sorting,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D THIS IS VERY EXPERIMENTAL!
+
+\writestatus{loading}{ConTeXt XML Support / Sorting}
+
+\registerctxluafile{lxml-sor}{}
+
+\unprotect
+
+%D The flusher is unexpandable so that it can be used in tables (noalign
+%D interferences).
+
+% todo: public implementors
+
+\permanent\protected\def\xmlresetsorter #1{\ctxlxml{sorters.reset("#1")}}
+\permanent\protected\def\xmladdsortentry#1#2#3{\ctxlxml{sorters.add("#1","#2",\!!bs#3\!!es)}}
+\permanent\protected\def\xmlshowsorter #1{\ctxlxml{sorters.show("#1")}}
+\permanent \def\xmlflushsorter #1#2{\ctxlxml{sorters.flush("#1","#2")}}
+\permanent\protected\def\xmlsortentries #1{\ctxlxml{sorters.sort("#1")}}
+
+\protect \endinput
+
+\startbuffer[test]
+<demo>
+ <entry>
+ <category>one</category>
+ <key>alpha</key>
+ <content>alpha indeed</content>
+ </entry>
+ <entry>
+ <category>one</category>
+ <key>gamma</key>
+ <content>gamma indeed</content>
+ </entry>
+ <entry>
+ <category>one</category>
+ <key>beta</key>
+ <content>beta indeed</content>
+ </entry>
+ <entry>
+ <category>two</category>
+ <key>alpha</key>
+ <content>alpha again</content>
+ </entry>
+ <entry>
+ <category>two</category>
+ <key>gamma</key>
+ <content>gamma again</content>
+ </entry>
+ <entry>
+ <category>two</category>
+ <key>beta</key>
+ <content>beta again</content>
+ </entry>
+</demo>
+\stopbuffer
+
+\startxmlsetups xml:mysetups
+ \xmlsetsetup{\xmldocument}{demo|entry|content}{xml:*}
+\stopxmlsetups
+
+\xmlregistersetup{xml:mysetups}
+
+\startxmlsetups xml:demo
+ \xmlresetsorter{demo}
+ \xmlfilter{#1}{entry/command(xml:entry:getkeys)}
+ \blank sortkeys: \blank\xmlshowsorter{demo}\blank
+ \xmlsortentries{demo}
+ \xmlflushsorter{demo}{xml:entry:flush}
+\stopxmlsetups
+
+\startxmlsetups xml:entry:getkeys
+ \xmladdsortentry{demo}{#1}{\xmltext{#1}{category}}
+ \xmladdsortentry{demo}{#1}{\xmltext{#1}{key|entry}}
+\stopxmlsetups
+
+\startxmlsetups xml:entry:flush
+ \xmltext{#1}{content}\par
+\stopxmlsetups
+
+\startxmlsetups xml:entry
+ \xmltext{#1}{content}\par
+\stopxmlsetups
+
+\starttext
+ \xmlprocessbuffer{main}{test}{}
+\stoptext
diff --git a/tex/context/base/mkiv/math-frc.mkxl b/tex/context/base/mkiv/math-frc.mkxl
index 485053fa5..b232868cd 100644
--- a/tex/context/base/mkiv/math-frc.mkxl
+++ b/tex/context/base/mkiv/math-frc.mkxl
@@ -278,45 +278,128 @@
% todo: store first state and reuse second time
+% \def\math_fraction_inner_normal#1#2%
+% {\Ustack{%
+% {%
+% {\usemathstyleparameter\mathfractionparameter{\m_fractions_strut_top#1}}%
+% \math_frac_command
+% {\usemathstyleparameter\mathfractionparameter{\m_fractions_strut_bot#2}}%
+% }%
+% }%
+% \math_frac_wrapup}
+%
+% \def\math_fraction_outer_normal#1#2%
+% {\Ustack{%
+% \usemathstyleparameter\mathfractionparameter
+% {%
+% {\m_fractions_strut_top#1}%
+% \math_frac_command
+% {\m_fractions_strut_bot#2}%
+% }%
+% }%
+% \math_frac_wrapup}
+%
+% \def\math_fraction_both_normal#1#2%
+% {\Ustack{%
+% \usemathstyleparameter\mathfractionparameter
+% {%
+% {\usemathstyleparameter\mathfractionparameter\m_fractions_strut_top#1}%
+% \math_frac_command
+% {\usemathstyleparameter\mathfractionparameter\m_fractions_strut_bot#2}%
+% }%
+% }%
+% \math_frac_wrapup}
+%
+% \def\math_fraction_inner_margin#1#2%
+% {\Ustack{%
+% {%
+% {\kern\d_math_fraction_margin
+% \usemathstyleparameter\mathfractionparameter{\m_fractions_strut_top#1}%
+% \kern\d_math_fraction_margin}%
+% \math_frac_command
+% {\kern\d_math_fraction_margin
+% \usemathstyleparameter\mathfractionparameter{\m_fractions_strut_bot#2}%
+% \kern\d_math_fraction_margin}%
+% }%
+% }%
+% \math_frac_wrapup}
+%
+% \def\math_fraction_outer_margin#1#2%
+% {\Ustack{%
+% \usemathstyleparameter\mathfractionparameter
+% {%
+% {\kern\d_math_fraction_margin
+% \m_fractions_strut_top#1%
+% \kern\d_math_fraction_margin}%
+% \math_frac_command
+% {\kern\d_math_fraction_margin
+% \m_fractions_strut_bot#2%
+% \kern\d_math_fraction_margin}%
+% }%
+% }%
+% \math_frac_wrapup}
+%
+% \def\math_fraction_both_margin#1#2%
+% {\Ustack{%
+% \usemathstyleparameter\mathfractionparameter
+% {%
+% {\kern\d_math_fraction_margin
+% \usemathstyleparameter\mathfractionparameter\m_fractions_strut_top#1%
+% \kern\d_math_fraction_margin}%
+% \math_frac_command
+% {\kern\d_math_fraction_margin
+% \usemathstyleparameter\mathfractionparameter\m_fractions_strut_bot#2%
+% \kern\d_math_fraction_margin}%
+% }%
+% }%
+% \math_frac_wrapup}
+
+\def\math_frac_command_u
+ {\clf_umathfraction
+ {\mathfractionparameter\c!rule}%
+ \ifx\p_math_fraction_fences\empty
+ \mathfractionparameter\c!left \space
+ \mathfractionparameter\c!right\space
+ \else
+ \math_frac_no_delim\space
+ \math_frac_no_delim\space
+ \fi
+ \dimexpr\mathfractionparameter\c!rulethickness\relax
+ \relax}
+
\def\math_fraction_inner_normal#1#2%
- {\Ustack{%
- {%
+ {\Ustack{% forces num style
+ \math_frac_command_u
{\usemathstyleparameter\mathfractionparameter{\m_fractions_strut_top#1}}%
- \math_frac_command
{\usemathstyleparameter\mathfractionparameter{\m_fractions_strut_bot#2}}%
- }%
}%
\math_frac_wrapup}
\def\math_fraction_outer_normal#1#2%
- {\Ustack{%
+ {\Ustack{% forces num style
\usemathstyleparameter\mathfractionparameter
- {%
+ \math_frac_command_u
{\m_fractions_strut_top#1}%
- \math_frac_command
{\m_fractions_strut_bot#2}%
- }%
}%
\math_frac_wrapup}
\def\math_fraction_both_normal#1#2%
- {\Ustack{%
+ {\Ustack{% forces num style
\usemathstyleparameter\mathfractionparameter
- {%
+ \math_frac_command_u
{\usemathstyleparameter\mathfractionparameter\m_fractions_strut_top#1}%
- \math_frac_command
{\usemathstyleparameter\mathfractionparameter\m_fractions_strut_bot#2}%
- }%
}%
\math_frac_wrapup}
\def\math_fraction_inner_margin#1#2%
{\Ustack{%
{%
+ \math_frac_command_u
{\kern\d_math_fraction_margin
\usemathstyleparameter\mathfractionparameter{\m_fractions_strut_top#1}%
\kern\d_math_fraction_margin}%
- \math_frac_command
{\kern\d_math_fraction_margin
\usemathstyleparameter\mathfractionparameter{\m_fractions_strut_bot#2}%
\kern\d_math_fraction_margin}%
@@ -328,10 +411,10 @@
{\Ustack{%
\usemathstyleparameter\mathfractionparameter
{%
+ \math_frac_command_u
{\kern\d_math_fraction_margin
\m_fractions_strut_top#1%
\kern\d_math_fraction_margin}%
- \math_frac_command
{\kern\d_math_fraction_margin
\m_fractions_strut_bot#2%
\kern\d_math_fraction_margin}%
@@ -343,10 +426,10 @@
{\Ustack{%
\usemathstyleparameter\mathfractionparameter
{%
+ \math_frac_command_u
{\kern\d_math_fraction_margin
\usemathstyleparameter\mathfractionparameter\m_fractions_strut_top#1%
\kern\d_math_fraction_margin}%
- \math_frac_command
{\kern\d_math_fraction_margin
\usemathstyleparameter\mathfractionparameter\m_fractions_strut_bot#2%
\kern\d_math_fraction_margin}%
diff --git a/tex/context/base/mkiv/math-inc.lua b/tex/context/base/mkiv/math-inc.lua
index 010d29a35..7c32adde6 100644
--- a/tex/context/base/mkiv/math-inc.lua
+++ b/tex/context/base/mkiv/math-inc.lua
@@ -20,6 +20,8 @@ local undent = buffers.undent
local f_entity = string.formatters["&x%X;"]
local f_blob = string.formatters['<?xml version="2.0"?>\n\n<!-- formula %i -->\n\n%s']
+local report_tags = logs.reporter("structure","tags")
+
local all = nil
local back = nil
@@ -62,7 +64,12 @@ local function getblob(n)
local root = xml.load(full)
for c in xml.collected(root,"formulacontent") do
local index = tonumber(c.at.n)
- all[index] = f_blob(index,beautify(xmltext(c,"math") or ""))
+ local data = beautify(xmltext(c,"math") or "")
+ if index and data then
+ all[index] = f_blob(index,data)
+ else
+ report_tags("no formula content id")
+ end
end
local it = mathematics.alphabets.regular.it
for k, v in next, it.digits do back[v] = k end
diff --git a/tex/context/base/mkiv/math-stc.mklx b/tex/context/base/mkiv/math-stc.mklx
index 2017fec1d..1ee8e85a2 100644
--- a/tex/context/base/mkiv/math-stc.mklx
+++ b/tex/context/base/mkiv/math-stc.mklx
@@ -1167,18 +1167,18 @@
\definemathunderextensible [\v!bottom] [underrightharpoondown] ["21C1]
\definemathunderextensible [\v!bottom] [underrightharpoonup] ["21C0]
-% We don't use overline and underline. This is one of the overlooked aspects of
-% unicode cq. opentype math: why treat rules different than e.g. arrows and
-% accents. It is a bit unfortunate that the opportunity to move math to new
-% technologies happened outside the tex domain (and/or some aspects were kept while
-% in fact they were side effects of limitations of traditional fonts). From the
-% unicode aware tex engines' implementation point of view things could have been
-% done a bit nicer but then: the community didn't seem to care too much and just
-% has to follow now.
-%
-% Anyhow, we use a character based approach so that at least we get unicode stuff
-% in the backend (okay, we still need to deal with some cut and paste issues but at
-% least we now know what we deal with.
+%D We don't use overline and underline. This is one of the overlooked aspects of
+%D unicode cq. opentype math: why treat rules different than e.g. arrows and
+%D accents. It is a bit unfortunate that the opportunity to move math to new
+%D technologies happened outside the tex domain (and/or some aspects were kept while
+%D in fact they were side effects of limitations of traditional fonts). From the
+%D unicode aware tex engines' implementation point of view things could have been
+%D done a bit nicer but then: the community didn't seem to care too much and just
+%D has to follow now.
+%D
+%D Anyhow, we use a character based approach so that at least we get unicode stuff
+%D in the backend (okay, we still need to deal with some cut and paste issues but at
+%D least we now know what we deal with.
% alternatively we can move the original to FE*
@@ -1202,19 +1202,19 @@
%D For mathml:
-\definemathdoubleextensible [\v!both] [overbarunderbar] ["FE33E] ["FE33F]
-\definemathdoubleextensible [\v!both] [overbraceunderbrace] ["FE3DE] ["FE3DF]
-\definemathdoubleextensible [\v!both] [overparentunderparent] ["FE3DC] ["FE3DD]
-\definemathdoubleextensible [\v!both] [overbracketunderbracket] ["FE3B4] ["FE3B5]
+\definemathdoubleextensible [\v!both] [overbarunderbar] ["FE33E] ["FE33F]
+\definemathdoubleextensible [\v!both] [overbraceunderbrace] ["FE3DE] ["FE3DF]
+\definemathdoubleextensible [\v!both] [overparentunderparent] ["FE3DC] ["FE3DD]
+\definemathdoubleextensible [\v!both] [overbracketunderbracket] ["FE3B4] ["FE3B5]
-\definemathovertextextensible [\v!bothtext] [overbartext] ["FE33E]
-\definemathundertextextensible [\v!bothtext] [underbartext] ["FE33F]
-\definemathovertextextensible [\v!bothtext] [overbracetext] ["FE3DE]
-\definemathundertextextensible [\v!bothtext] [underbracetext] ["FE3DF]
-\definemathovertextextensible [\v!bothtext] [overparenttext] ["FE3DC]
-\definemathundertextextensible [\v!bothtext] [underparenttext] ["FE3DD]
-\definemathovertextextensible [\v!bothtext] [overbrackettext] ["FE3B4]
-\definemathundertextextensible [\v!bothtext] [underbrackettext] ["FE3B5]
+\definemathovertextextensible [\v!bothtext] [overbartext] ["FE33E]
+\definemathundertextextensible [\v!bothtext] [underbartext] ["FE33F]
+\definemathovertextextensible [\v!bothtext] [overbracetext] ["FE3DE]
+\definemathundertextextensible [\v!bothtext] [underbracetext] ["FE3DF]
+\definemathovertextextensible [\v!bothtext] [overparenttext] ["FE3DC]
+\definemathundertextextensible [\v!bothtext] [underparenttext] ["FE3DD]
+\definemathovertextextensible [\v!bothtext] [overbrackettext] ["FE3B4]
+\definemathundertextextensible [\v!bothtext] [underbrackettext] ["FE3B5]
%D Some bonus ones (for the moment here):
@@ -1302,14 +1302,26 @@
\defineextensiblefiller [Leftrightarrowfill] ["27FA]
%\defineextensiblefiller[Rightleftarrowfill] [.....]
-%defineextensiblefiller [overbarfill] ["FE33E] % untested
-%defineextensiblefiller [underbarfill] ["FE33F] % untested
-\defineextensiblefiller [overbracefill] ["FE3DE] % untested
-\defineextensiblefiller [underbracefill] ["FE3DF] % untested
-\defineextensiblefiller [overparentfill] ["FE3DC] % untested
-\defineextensiblefiller [underparentfill] ["FE3DD] % untested
-\defineextensiblefiller [overbracketfill] ["FE3B4] % untested
-\defineextensiblefiller [underbracketfill] ["FE3B5] % untested
+% These are fishy ... we need to check this because now these commands relax (there
+% are some entries in char-def.)
+%
+% %definemathoverextensible [overbarfill] ["FE33E]
+% %definemathunderextensible [underbarfill] ["FE33F]
+% \definemathoverextensible [overbracefill] ["FE3DE]
+% \definemathunderextensible [underbracefill] ["FE3DF]
+% \definemathoverextensible [overparentfill] ["FE3DC]
+% \definemathunderextensible [underparentfill] ["FE3DD]
+% \definemathoverextensible [overbracketfill] ["FE3B4]
+% \definemathunderextensible [underbracketfill] ["FE3B5]
+%
+% %defineextensiblefiller [overbarfill] ["FE33E]
+% %defineextensiblefiller [underbarfill] ["FE33F]
+% \defineextensiblefiller [overbracefill] ["FE3DE]
+% \defineextensiblefiller [underbracefill] ["FE3DF]
+% \defineextensiblefiller [overparentfill] ["FE3DC]
+% \defineextensiblefiller [underparentfill] ["FE3DD]
+% \defineextensiblefiller [overbracketfill] ["FE3B4]
+% \defineextensiblefiller [underbracketfill] ["FE3B5]
%D Extra:
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index e72c3ab22..be507394d 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -161,7 +161,7 @@ return {
"automaticpenaltyhyphenationmodecode", "explicitpenaltyhyphenationmodecode",
"permitgluehyphenationmodecode", "permitallhyphenationmodecode", "permitmathreplacehyphenationmodecode",
--
- "normalizelinemodecode", "indentskipmodecode", "swaphangindentmodecode", "swapparskipmodecode", "breakafterdirmodecode",
+ "normalizelinecode", "parindentskipcode", "swaphangindentcode", "swapparsshapecode", "breakafterdircode", "removemarginkernscode",
--
"noligaturingcode", "nokerningcode", "noleftligaturecode", "noleftkerncode", "norightligaturecode", "norightkerncode",
"noexpansioncode", "noprotrusioncode",
@@ -257,6 +257,10 @@ return {
"scratchbox", "globalscratchbox", "privatescratchbox",
"scratchmacro", "scratchmacroone", "scratchmacrotwo",
--
+ "scratchconditiontrue", "scratchconditionfalse", "ifscratchcondition",
+ "scratchconditiononetrue", "scratchconditiononefalse", "ifscratchconditionone",
+ "scratchconditiontwotrue", "scratchconditiontwofalse", "ifscratchconditiontwo",
+ --
"globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree",
--
"groupedcommand", "groupedcommandcs",
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index 1ab4e6aba..3d0f65dba 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -393,6 +393,7 @@ return {
"outputbox",
"overloaded",
"overloadmode",
+ "parametercount",
"parattr",
"pardirection",
"permanent",
diff --git a/tex/context/base/mkiv/node-bck.mkxl b/tex/context/base/mkiv/node-bck.mkxl
new file mode 100644
index 000000000..e37d65b1c
--- /dev/null
+++ b/tex/context/base/mkiv/node-bck.mkxl
@@ -0,0 +1,92 @@
+%D \module
+%D [ file=node-bck,
+%D version=2009.06.08,
+%D title=\CONTEXT\ Node Macros,
+%D subtitle=Backgrounds,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Node Support / Backgrounds}
+
+%D This is first attempt to replacing backgrounds in a few tables
+%D mechanisms. When used more frequently, we can store the color
+%D spec in the attribute.
+
+\unprotect
+
+\registerctxluafile{node-bck}{optimize}
+
+% \backgroundvbox[green] {\input tufte } \par
+% \backgroundvbox[blue] {\input ward } \par
+% \backgroundvbox[red] {\input knuth } \par
+% \backgroundhbox[yellow]{\rotate[rotation=45]{hello world}} \par
+
+\permanent\def\colorattr#1%
+ {\ifcsname\??colorattribute\currentcolorprefix#1\endcsname
+ \node_backgrounds_thecolorattr{\currentcolorprefix#1}%
+ \orelse\ifcsname\??colorattribute#1\endcsname
+ \node_backgrounds_thecolorattr{#1}%
+ \fi}
+
+\def\node_backgrounds_thecolorattr#1%
+ {attr \colormodelattribute \c_attr_colormodel
+ attr \colorattribute \lastnamedcs
+ attr \transparencyattribute \thetransparencyattribute{#1} } % can be optimized
+
+\permanent\def\thecolorattr#1%
+ {attr \colormodelattribute \c_attr_colormodel
+ attr \colorattribute \csname\??colorattribute#1\endcsname
+ attr \transparencyattribute \thetransparencyattribute{#1} } % can be optimized
+
+\permanent\def\backgroundcolorattr#1%
+ {\ifcsname\??colorattribute\currentcolorprefix#1\endcsname
+ \node_backgrounds_thebackgroundcolorattr{\currentcolorprefix#1}%
+ \orelse\ifcsname\??colorattribute#1\endcsname
+ \node_backgrounds_thebackgroundcolorattr{#1}%
+ \fi}
+
+\permanent\def\thebackgroundcolorattr#1%
+ {attr \backgroundattribute \plusone
+ attr \colormodelattribute \c_attr_colormodel
+ attr \colorattribute \csname\??colorattribute#1\endcsname
+ attr \transparencyattribute \thetransparencyattribute{#1} } % can be optimized
+
+\def\node_backgrounds_thebackgroundcolorattr#1%
+ {attr \backgroundattribute \plusone
+ attr \colormodelattribute \c_attr_colormodel
+ attr \colorattribute \lastnamedcs
+ attr \transparencyattribute \thetransparencyattribute{#1} } % can be optimized
+
+\permanent\def\thealignbackgroundcolorattr#1%
+ {attr \alignbackgroundattribute \plusone
+ attr \colormodelattribute \c_attr_colormodel
+ attr \colorattribute \csname\??colorattribute#1\endcsname
+ attr \transparencyattribute \thetransparencyattribute{#1} } % can be optimized
+
+\permanent\protected\def\backgroundhbox{\node_backgrounds_boxes_add\hbox}
+\permanent\protected\def\backgroundvbox{\node_backgrounds_boxes_add\vbox}
+\permanent\protected\def\backgroundvtop{\node_backgrounds_boxes_add\vtop}
+\permanent\protected\def\backgroundline{\dontleavehmode\node_backgrounds_boxes_add\hbox}
+
+% \def\node_backgrounds_boxes_add#1[#2]%
+% {\begingroup
+% \clf_enablebackgroundboxes
+% \dousecolorparameter{#2}%
+% \normalexpanded{\endgroup#1
+% attr \backgroundattribute \plusone
+% attr \colormodelattribute \the\c_attr_colormodel
+% attr \colorattribute \the\c_attr_color
+% attr \transparencyattribute \the\c_attr_transparency}}
+%
+% more efficient:
+
+\def\node_backgrounds_boxes_add#1[#2]%
+ {\clf_enablebackgroundboxes
+ #1\backgroundcolorattr{#2}}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/node-rul.mkxl b/tex/context/base/mkiv/node-rul.mkxl
new file mode 100644
index 000000000..3697e92ef
--- /dev/null
+++ b/tex/context/base/mkiv/node-rul.mkxl
@@ -0,0 +1,618 @@
+%D \module
+%D [ file=node-rul,
+%D version=2009.11.03, % 1995.10.10,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Bars,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: ex and and em traveling with attribute
+% todo: this will move to typo-rul + ctxcommands
+
+\writestatus{loading}{ConTeXt Core Macros / Bars}
+
+%D \macros
+%D {underbar,underbars,
+%D overbar,overbars,
+%D overstrike,overstrikes,
+%D setupbar}
+%D
+%D In the rare case that we need undelined words, for instance because all font
+%D alternatives are already in use, one can use \type {\underbar} and \type
+%D {\overstrike} and their plural forms.
+%D
+%D \startbuffer
+%D \underbars {drawing \underbar{bars} under words is a typewriter leftover}
+%D \overstrikes {striking words makes them \overstrike {unreadable} but
+%D sometimes even \overbar {top lines} come into view.}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D
+%D The formal definitions are:
+%D
+%D \showsetup{underbar}
+%D \showsetup{underbars}
+%D \showsetup{overbar}
+%D \showsetup{overbars}
+%D \showsetup{overstrike}
+%D \showsetup{overstrikes}
+%D
+%D \showsetup{setupbars}
+%D
+%D Units can be any normal \TEX\ unit:
+%D
+%D \startbuffer
+%D \setupbars[unit=mm,rulethickness=1] bar\startbar[underbar]foo\stopbar bar\blank
+%D \setupbars[unit=ex,rulethickness=1] bar\startbar[underbar]foo\stopbar bar\blank
+%D \setupbars[unit=pt,rulethickness=1] bar\startbar[underbar]foo\stopbar bar\blank
+%D \setupbars[unit=pt,rulethickness=10pt] bar\startbar[underbar]foo\stopbar bar
+%D \stopbuffer
+%D
+%D \typebuffer \blank \getbuffer \blank
+%D
+%D As with many early usage of \LUA\ in \MKIV\ this mechanism explores a way
+%D to deal with local settings at the \TEX\ end and remembering parameters
+%D at the \LUA\ end. We might do things differently now, but as settings normally
+%D don't change that often, we're not in a hurry to do that now. The problem at
+%D the \LUA\ end is that we don't know when to clean up.
+
+\unprotect
+
+%definesystemattribute[ruled]
+%definesystemattribute[shifted]
+
+\registerctxluafile{node-rul}{optimize}
+
+\installcorenamespace{bar}
+\installcorenamespace{barindex}
+\installcorenamespace{barattribute}
+\installcorenamespace{barstack}
+
+\installcommandhandler \??bar {bar} \??bar
+
+\newtoks\t_node_rules_checklist
+
+\let\c_node_rules_index\relax % temporary synonym
+\let\p_node_rules_color\empty
+
+\aliased\let\setupbars\setupbar
+
+\appendtoks
+ \ifsecondargument
+ \node_rules_define
+ \else
+ \the\t_node_rules_checklist
+ \fi
+\to \everysetupbar
+
+\appendtoks
+ \ifcsname\??barindex\currentbar\endcsname
+ \lastnamedcs\zerocount
+ \else
+ \expandafter\newcount\csname\??barindex\currentbar\endcsname
+ \fi
+ % \normalexpanded{\t_node_rules_checklist{\node_rules_redefine{\currentbar}\the\t_node_rules_checklist}}%
+ \normalexpanded{\t_node_rules_checklist{\the\t_node_rules_checklist\relax\node_rules_redefine{\currentbar}}}%
+ % \etoksapp\t_node_rules_checklist{\node_rules_redefine{\currentbar}}%
+ \node_rules_define
+ \frozen\instance\setuevalue\currentbar{\node_rules_direct{\currentbar}}%
+\to \everydefinebar
+
+\newbox\b_node_rules
+
+\protected\def\node_rules_define
+ {\edef\p_node_rules_color{\barparameter\c!color}%
+ \edef\p_node_text{\barparameter\c!text}%
+ \ifx\p_node_text\empty\else
+ \setbox\b_node_rules\hbox{\p_node_text}%
+ \fi
+ \setevalue{\??barattribute\currentbar}{\number
+ \clf_definerule
+ continue {\barparameter\c!continue}%
+ unit {\barparameter\c!unit}%
+ order {\barparameter\c!order}%
+ rulethickness {\barparameter\c!rulethickness}%
+ method \barparameter\c!method
+ max \barparameter\c!max\space % number
+ mp {\includeMPgraphic{\barparameter\c!mp}}
+ ma \thecolormodelattribute
+ ca \thecolorattribute\p_node_rules_color
+ ta \thetransparencyattribute\p_node_rules_color
+ offset \barparameter\c!offset\space % number
+ dy \barparameter\c!dy\space % number
+ empty {\barparameter\c!empty}%
+ \ifx\p_node_text\empty\else
+ % not that useful and efficient, more for testing something
+ text \b_node_rules
+ repeat {\barparameter\c!repeat}%
+ \fi
+ \relax}}
+
+\protected\def\node_rules_redefine#1%
+ {\def\currentbar{#1}\node_rules_define}
+
+\protected\def\node_rules_direct#1%
+ {\groupedcommand
+ {\node_rules_set{#1}\barparameter\c!left}%
+ {\relax\barparameter\c!right}}
+
+\permanent\protected\def\inlinebar[#1]%
+ {\node_rules_direct{#1}}
+
+% \protected\def\inlinecurrentbar
+% {\node_rules_direct{\currentbar}}
+
+% store in properties
+
+\permanent\protected\def\node_rules_set#1% maybe reverse the 1000 (also maybe use more attributes instead of settings)
+ {\edef\currentbar{#1}%
+ \usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ % maybe: \usebarstyleandcolor\c!textgroundstyle\c!textcolor
+ % todo: move this to lua .. we callout anyway
+ \expandafter\let\expandafter\c_node_rules_index\csname\??barindex#1\endcsname
+ \advance\c_node_rules_index\plusone
+ \clf_enablerules % will be relaxed
+ \c_attr_ruled\numexpr
+ \plusthousand*\c_node_rules_index
+ % optimizing this one needs testing
+ +\csname\??barattribute#1\ifcsname\??bar#1:\number\c_node_rules_index\s!parent\endcsname:\number\c_node_rules_index\fi\endcsname
+ \relax}
+
+\permanent\protected\def\resetbar
+ {\c_attr_ruled\attributeunsetvalue}
+
+\permanent\protected\def\nobar
+ {\groupedcommand
+ {\resetbar\barparameter\c!left}%
+ {\relax\barparameter\c!right}}
+
+\permanent\protected\def\startbar[#1]%
+ {\begingroup
+ \node_rules_set{#1}%
+ \ignorespaces
+ \barparameter\c!left}
+
+\permanent\protected\def\stopbar
+ {\removeunwantedspaces
+ \barparameter\c!right
+ \endgroup}
+
+\permanent\protected\def\setbar[#1]%
+ {\node_rules_set{#1}}
+
+\aliased\let\directsetbar\node_rules_set
+
+% ungrouped
+
+\newcount\c_node_rules_nesting % todo: same as colors
+
+\permanent\protected\def\pushbar[#1]%
+ {\global\advance\c_node_rules_nesting\plusone
+ \expandafter\edef\csname\??barstack\number\c_node_rules_nesting\endcsname{\c_attr_ruled\the\c_attr_ruled}%
+ \node_rules_set{#1}}
+
+\permanent\protected\def\popbar
+ {\csname\??barstack\number\c_node_rules_nesting\endcsname
+ \global\advance\c_node_rules_nesting\minusone}
+
+\setupbars
+ [\c!method=0, % new: 0=center nested, 1=stack nested
+ \c!continue=\v!no,
+ \c!empty=, % new: yes = hide text
+ \c!offset=0, % upwards, replaces: topoffset bottomoffset
+ \c!dy=0,
+ \c!max=3,
+ \c!style=,
+ \c!rulethickness=.1,
+ \c!order=\v!foreground,
+ \c!unit=ex, % so now we are relative
+ \c!color=] % replaces: rulecolor
+
+% \definebar[touchbar] [\c!method=0,\c!dy=-0.4,\c!offset=-0.0]
+% \definebar[touchbars] [touchbar] [\c!continue=\v!yes]
+
+\pushoverloadmode
+
+\aliased\let\normalmathoverbar \overbar
+\aliased\let\normalmathunderbar \underbar
+\aliased\let\normalmathoverstrike \overstrike
+\aliased\let\normalmathunderstrike\understrike
+
+\definebar[\v!overbar] [\c!method=1,\c!dy=0.4,\c!offset=1.8,\c!continue=\v!yes]
+\definebar[\v!underbar] [\c!method=1,\c!dy=-0.4,\c!offset=-0.3,\c!continue=\v!yes]
+\definebar[\v!overstrike][\c!method=0,\c!dy=0.4,\c!offset=0.5,\c!continue=\v!yes]
+
+\definebar
+ [\v!understrike]
+ [\c!method=0,
+ \c!offset=1.375,
+ \c!rulethickness=2.5,
+ \c!continue=\v!yes,
+ \c!order=\v!background,
+ \c!color=lightgray]
+
+\definebar[\v!overbars] [\v!overbar] [\c!continue=\v!no]
+\definebar[\v!underbars] [\v!underbar] [\c!continue=\v!no]
+\definebar[\v!overstrikes] [\v!overstrike] [\c!continue=\v!no]
+\definebar[\v!understrikes][\v!understrike][\c!continue=\v!no]
+
+\definebar
+ [\v!hiddenbar]
+ [\v!underbar]
+ [\c!continue=\v!yes,
+ \c!empty=\v!yes,
+ \c!left=\zwj,
+ \c!right=\zwj]
+
+% \setupbar[\v!overstrike][continue=all]
+
+% we want these always so ...
+
+\ifdefined\normalmathunderbar
+ \enforced\permanent\expandafter\let\expandafter\normaltextunderbar\csname\v!underbar\endcsname
+ \enforced\permanent\protected\def\underbar{\mathortext\normalmathunderbar\normaltextunderbar}
+\else
+ \enforced\permanent\expandafter\let\expandafter\underbar\csname\v!underbar\endcsname
+\fi
+
+\ifdefined\normalmathoverbar
+ \enforced\permanent\expandafter\let\expandafter\normaltextoverbar\csname\v!overbar\endcsname
+ \enforced\permanent\protected\def\overbar{\mathortext\normalmathoverbar\normaltextoverbar}
+\else
+ \enforced\permanent\expandafter\let\expandafter\overbar\csname\v!overbar\endcsname
+\fi
+
+\ifdefined\normalmathunderstrike
+ \enforced\permanent\expandafter\let\expandafter\normaltextunderstrike\csname\v!understrike\endcsname
+ \enforced\permanent\protected\def\understrike{\mathortext\normalmathunderstrike\normaltextunderstrike}
+\else
+ \enforced\permanent\expandafter\let\expandafter\understrike\csname\v!understrike\endcsname
+\fi
+
+\ifdefined\normalmathoverstrike
+ \enforced\permanent\expandafter\let\expandafter\normaltextoverstrike\csname\v!overstrike\endcsname
+ \enforced\permanent\protected\def\overstrike{\mathortext\normalmathoverstrike \normaltextoverstrike}
+\else
+ \enforced\permanent\expandafter\let\expandafter\overstrike\csname\v!overstrike\endcsname
+\fi
+
+\enforced\permanent\expandafter\let\expandafter\overstrikes\csname\v!overstrikes\endcsname
+\enforced\permanent\expandafter\let\expandafter\underbars \csname\v!underbars \endcsname
+\enforced\permanent\expandafter\let\expandafter\overbars \csname\v!overbars \endcsname
+
+\enforced\permanent\protected\def\setupunderbar[#1]% too incompatible for the moment
+ {}
+
+\popoverloadmode
+
+%D An experimental new feature:
+%D
+%D \startbuffer
+%D test {\red\underrandoms{test me}} and \underrandom{test} or \underrandom{grep} \blank
+%D test {\red\underdashes {test me}} and \underdash {test} or \underdash {grep} \blank
+%D test {\red\underdots {test me}} and \underdot {test} or \underdot {grep} \blank
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\startuseMPgraphic{rules:under:random}
+ draw
+ ((0,RuleDepth) ... (RuleWidth,RuleDepth)) randomized (4*RuleThickness)
+ shifted (0,RuleFactor*RuleOffset)
+ withpen pencircle scaled RuleThickness
+ withcolor RuleColor ;
+ setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{rules:under:dash}
+ draw
+ ((0,RuleDepth) -- (RuleWidth,RuleDepth))
+ shifted (0,RuleFactor*RuleOffset)
+ dashed dashpattern(on RuleFactor/2 off RuleFactor/2)
+ withpen pencircle scaled RuleThickness
+ withcolor RuleColor ;
+ setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{rules:under:dots}
+ path p ; p := (0,RuleDepth) -- (RuleWidth,RuleDepth) ;
+ numeric l ; l := arclength(p);
+ l := l mod RuleThickness/4;
+ draw
+ p
+ shifted (l,RuleFactor*RuleOffset)
+ dashed dashpattern(off 2RuleThickness+l on 0 off 2RuleThickness)
+ withpen pencircle scaled 2RuleThickness
+ withcolor RuleColor ;
+ setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
+\stopuseMPgraphic
+
+\definebar
+ [undergraphic]
+ [\c!mp=rules:under:dash,
+ \c!offset=-.2,
+ \c!order=\v!background]
+
+\definebar[underrandom] [undergraphic][\c!mp=rules:under:random]
+\definebar[underrandoms][underrandom] [\c!continue=\v!yes]
+
+\definebar[underdash] [undergraphic][\c!mp=rules:under:dash]
+\definebar[underdashes] [underdash] [\c!continue=\v!yes]
+
+\definebar[underdot] [undergraphic][\c!mp=rules:under:dots]
+\definebar[underdots] [underdot] [\c!continue=\v!yes]
+
+%D This will move: (a bit duplicated)
+
+\installcorenamespace{shift}
+\installcorenamespace{shiftindex}
+\installcorenamespace{shiftattribute}
+
+\installcommandhandler \??shift {shift} \??shift
+
+\newtoks\t_node_shifts_checklist
+
+\let\c_node_shifts_index\relax % temporary synonym
+
+\let\setupshifts\setupshift
+
+\appendtoks
+ \ifsecondargument
+ \node_shifts_define
+ \else
+ \the\t_node_shifts_checklist
+ \fi
+\to \everysetupshift
+
+\appendtoks
+ \ifcsname\??shiftindex\currentshift\endcsname
+ \lastnamedcs\zerocount
+ \else
+ \expandafter\newcount\csname\??shiftindex\currentshift\endcsname
+ \fi
+ \normalexpanded{\t_node_shifts_checklist{\the\t_node_shifts_checklist\node_shifts_redefine{\currentshift}}}% order ?
+ \node_shifts_define
+ \setuevalue\currentshift{\node_shifts_direct{\currentshift}}%
+\to \everydefineshift
+
+\protected\def\node_shifts_define
+ {\setevalue{\??shiftattribute\currentshift}{\number
+ \clf_defineshift
+ continue {\shiftparameter\c!continue}%
+ unit {\shiftparameter\c!unit}%
+ method \shiftparameter\c!method
+ dy \shiftparameter\c!dy % number
+ \relax}}
+
+\protected\def\node_shifts_redefine#1%
+ {\def\currentshift{#1}\node_shifts_define}
+
+% \protected\def\node_shifts_set
+% {\clf_enableshifts
+% \glet\node_shifts_set\node_shifts_set_indeed
+% \node_shifts_set}
+%
+% \def\node_shifts_set_indeed#1% todo: check parent !
+
+\protected\def\node_shifts_set#1% todo: check parent ! todo: move attr etc to lua
+ {\def\currentshift{#1}%
+ \expandafter\let\expandafter\c_node_shifts_index\csname\??shiftindex#1\endcsname
+ \advance\c_node_shifts_index\plusone
+ \clf_enableshifts % will be relaxed
+ \c_attr_shifted\numexpr
+ \plusthousand*\c_node_shifts_index
+ +\csname\??shiftattribute#1\ifcsname\??shift#1:\number\c_node_shifts_index\s!parent\endcsname:\number\c_node_shifts_index\fi\endcsname
+ \relax
+ \useshiftstyleandcolor\c!style\c!color
+ \dosetupisolatedalign{\shiftparameter\c!align}} % weird feature that i probably needed once
+
+\protected\def\startshift[#1]%
+ {\begingroup
+ \node_shifts_set{#1}%
+ \ignorespaces}
+
+\protected\def\stopshift
+ {\removeunwantedspaces
+ \endgroup}
+
+% \protected\def\node_shifts_direct#1%
+% {\doisolatedgroupedalign{\node_shifts_set{#1}}\donothing}
+
+\protected\def\node_shifts_direct#1%
+ {\groupedcommand
+ {\begingroup\dostartisolation\begingroup\node_shifts_set{#1}\ignorespaces}
+ {\removeunwantedspaces\endgroup\dostopisolation\endgroup}}
+
+\setupshifts
+ [\c!method=0,
+ \c!continue=\v!no,
+ \c!dy=0,
+ \c!unit=ex,
+ \c!align=,
+ \c!style=,
+ \c!color=]
+
+\defineshift [\v!shiftup] [\c!method=0,\c!dy=-1,\c!unit=ex,\c!continue=\v!yes,\c!style=\txx,\c!color=]
+\defineshift [\v!shiftdown] [\c!method=1,\c!dy=.3,\c!unit=ex,\c!continue=\v!yes,\c!style=\txx,\c!color=]
+
+% we want these always so ...
+
+\expandafter\let\expandafter\shiftup \csname\v!shiftup \endcsname
+\expandafter\let\expandafter\shiftdown \csname\v!shiftdown \endcsname
+
+% This is a weird helper:
+
+\protected\def\dostartisolation{\signalcharacter}
+\protected\def\dostopisolation {\signalcharacter}
+\protected\def\doisolator {\signalcharacter}
+
+\protected\def\dosetupisolatedalign#1%
+ {\doisolator
+ \setupalign[#1]\relax}
+
+\protected\def\doisolatedgroupedalign#1#2%
+ {\groupedcommand
+ {\begingroup\dostartisolation\begingroup#1}
+ {#2\endgroup\dostopisolation\endgroup}}
+
+%D More rules.
+
+% The following code rocks and was written with the Toto Live in Poland bluray
+% in loop mode on my 5.1 surround development setup (the Toto lineup with Simon
+% Phillips on drums). The Amsterdam concert is equally energizing.
+
+\installcorenamespace{linefiller}
+\installcorenamespace{linefillerindex}
+\installcorenamespace{linefillerattribute}
+
+\installcommandhandler \??linefiller {linefiller} \??linefiller
+
+\definesystemattribute[linefiller][public]
+
+\newtoks\t_node_linefiller_checklist
+
+\let\c_node_linefiller_index\relax % temporary synonym
+
+\aliased\let\setuplinefillers\setuplinefiller
+
+\appendtoks
+ \ifsecondargument
+ \node_linefiller_define
+ \else
+ \the\t_node_linefiller_checklist
+ \fi
+\to \everysetuplinefiller
+
+\appendtoks
+ \ifcsname\??linefillerindex\currentlinefiller\endcsname
+ \lastnamedcs\zerocount
+ \else
+ \expandafter\newcount\csname\??linefillerindex\currentlinefiller\endcsname
+ \fi
+ \etoksapp\t_node_linefiller_checklist{\t_node_linefiller_checklist\node_linefiller_redefine{\currentlinefiller}}%
+ \node_linefiller_define
+\to \everydefinelinefiller
+
+\protected\def\node_linefiller_define
+ {\edef\p_node_rules_color{\linefillerparameter\c!color}%
+ \setevalue{\??linefillerattribute\currentlinefiller}{\number
+ \clf_definelinefiller
+ %method \linefillerparameter\c!method
+ location {\linefillerparameter\c!location}%
+ scope {\linefillerparameter\c!scope}%
+ mp {\includeMPgraphic{\linefillerparameter\c!mp}}%
+ ma \thecolormodelattribute
+ ca \thecolorattribute\p_node_rules_color
+ ta \thetransparencyattribute\p_node_rules_color
+ height \dimexpr\linefillerparameter\c!height\relax
+ depth \dimexpr\linefillerparameter\c!depth\relax
+ distance \dimexpr\linefillerparameter\c!distance\relax
+ threshold \dimexpr\linefillerparameter\c!threshold\relax
+ rulethickness \dimexpr\linefillerparameter\c!rulethickness\relax
+ \relax}}
+
+\protected\def\node_linefiller_redefine#1%
+ {\def\currentlinefiller{#1}\node_linefiller_define}
+
+\protected\def\node_linefiller_set#1% todo: check parent ! todo: move attr etc to lua
+ {\def\currentlinefiller{#1}%
+ \expandafter\let\expandafter\c_node_linefiller_index\csname\??linefillerindex#1\endcsname
+ \advance\c_node_linefiller_index\plusone
+ \clf_enablelinefillers
+ \c_attr_linefiller\numexpr
+ \plusthousand*\c_node_linefiller_index
+ +\csname\??linefillerattribute#1\ifcsname\??linefiller#1:\number\c_node_linefiller_index\s!parent\endcsname:\number\c_node_linefiller_index\fi\endcsname
+ \relax}
+
+\permanent\tolerant\protected\def\startlinefiller[#1]#*[#2]%
+ {\begingroup
+ \par
+ \def\currentlinefiller{#1}%
+ \ifargument#1\or
+ % we need to update settings
+ \setuplinefiller[#1][#2]% no \setupcurrentlinefiller as we need to update settings
+ \fi
+ \node_linefiller_set{#1}%
+ \linefillerparameter\c!before
+ \usealignparameter\linefillerparameter
+ \uselinefillerstyleandcolor\c!textstyle\c!textcolor} % bars have foregroundcolor
+
+\permanent\protected\def\stoplinefiller
+ {\par
+ \linefillerparameter\c!after
+ \endgroup}
+
+\permanent\protected\def\setlinefiller[#1]%
+ {\node_linefiller_set{#1}}
+
+\setuplinefillers
+ [%c!method=0,
+ %c!mp=,
+ \c!location=\v!both,
+ \c!scope=\v!local,
+ \c!distance=\zeropoint,
+ \c!threshold=\zeropoint,
+ \c!rulethickness=\linewidth,
+ \c!height=\linewidth,
+ \c!depth=\zeropoint,
+ %\c!textcolor=,
+ %\c!textstyle=,
+ %\c!align=,
+ %\c!before=,
+ %\c!after=,
+ \c!color=]
+
+\definelinefiller
+ [filler]
+ [\c!height=.75\exheight,
+ %\c!mp=rules:filler:demo,
+ %\c!threshold=.25\emwidth,
+ \c!distance=.25\emwidth,
+ \c!rulethickness=.25\exheight]
+
+%D Bonus:
+%D
+%D \starttyping
+%D \startuseMPgraphic{foo}
+%D fill unitsquare
+%D xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
+%D shifted (-ExHeight/8,ExHeight/16)
+%D withcolor RuleColor ;
+%D \stopuseMPgraphic
+%D
+%D \definelinefiller[foo][mp=foo,color=darkred]
+%D
+%D \linefillerhbox[foo]{OEPS}
+%D \stoptyping
+
+\protected\def\node_backgrounds_filler_box#1#2[#3]%
+ {\bgroup
+ \clf_enablebackgroundboxes
+ \dowithnextbox{%
+ \node_linefiller_set{#3}% already sets the attribute
+ #1%
+ attr \backgroundattribute \plusone
+ % attr \linefillerattribute \the\c_attr_linefiller
+ {\box\nextbox}%
+ \egroup}%
+ #2}
+
+\permanent\protected\def\linefillerhbox{\node_backgrounds_filler_box\hpack\hbox}
+\permanent\protected\def\linefillervbox{\node_backgrounds_filler_box\vpack\vbox}
+\permanent\protected\def\linefillervtop{\node_backgrounds_filler_box\tpack\vtop}
+
+%D Bonus:
+
+\permanent\protected\def\autorule{\clf_autorule} % todo: public implementor
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/scrn-bar.mkvi b/tex/context/base/mkiv/scrn-bar.mkvi
index c089eb945..4b50a437d 100644
--- a/tex/context/base/mkiv/scrn-bar.mkvi
+++ b/tex/context/base/mkiv/scrn-bar.mkvi
@@ -343,13 +343,13 @@
\ifnum\scratchcounterthree<\plusone \scratchcounterthree\plusone \fi
\scratchcounterfive\zerocount
\dostepwiserecurse\firstsubpage\lastsubpage\plusone
- {\!!doneafalse
+ {\donefalse
\advance\scratchcounterfive \plusone
- \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi
- \ifnum\recurselevel=\lastsubpage \relax \!!doneatrue \fi
+ \ifnum\recurselevel=\firstsubpage\relax \donetrue \fi
+ \ifnum\recurselevel=\lastsubpage \relax \donetrue \fi
\scratchcountersix\therealsubpageno\recurselevel\relax
\c_scrn_bar_mode
- \if!!donea
+ \ifdone
\ifnum\scratchcountersix<\realpageno
\zerocount
\else\ifnum\scratchcountersix>\realpageno
diff --git a/tex/context/base/mkiv/scrp-ini.mkiv b/tex/context/base/mkiv/scrp-ini.mkiv
index dccea2ee0..ab934fe3b 100644
--- a/tex/context/base/mkiv/scrp-ini.mkiv
+++ b/tex/context/base/mkiv/scrp-ini.mkiv
@@ -59,9 +59,9 @@
% presets are global and are currently defined in lua
-\appendtoks
- \setuevalue\currentscript{\setscript[\currentscript]}%
-\to \everydefinescript
+% \appendtoks
+% \setuevalue\currentscript{\setscript[\currentscript]}%
+% \to \everydefinescript
\unexpanded\def\scripts_basics_set
{\clf_setscript{\currentscript}{\scriptparameter\c!method}{\scriptparameter\c!preset}}
@@ -96,7 +96,7 @@
% \def\scripts_basics_set_splitter_list[#1][#2]%
% {\ctxcommand{setscriptsplitterlist("#1","#2")}
-% \setscript[hangul] \hangul \startscript[hangul]
+% \setscript[hangul] \startscript[hangul]
\definescript [hangul] [\c!method=hangul]
\definescript [hanzi] [\c!method=hanzi]
diff --git a/tex/context/base/mkiv/spac-ali.mkxl b/tex/context/base/mkiv/spac-ali.mkxl
index bc43db8ff..5cb494682 100644
--- a/tex/context/base/mkiv/spac-ali.mkxl
+++ b/tex/context/base/mkiv/spac-ali.mkxl
@@ -21,12 +21,6 @@
\registerctxluafile{spac-ali}{optimize}
-\immutable\chardef\normalizelinemodecode = "01
-\immutable\chardef\indentskipmodecode = "02
-\immutable\chardef\swaphangindentmodecode = "04
-\immutable\chardef\swapparskipmodecode = "08
-\immutable\chardef\breakafterdirmodecode = "10
-
\definesystemattribute[realign] [public] % might be combined with the next one
\definesystemattribute[alignstate][public] % will make a single attributes for several states
@@ -508,7 +502,7 @@
{\bottomraggednessmode\plustwo
\settopskip}
-\let\normalbottom\alignbottom % downward compatible
+\aliased\let\normalbottom\alignbottom % downward compatible
\permanent\protected\def\setbottomalignmode#1%
{\bottomraggednessmode#1%
@@ -1241,4 +1235,9 @@
\permanent\def\usedirectionparameterreverse#1{\begincsname\??reverse#1\c!direction\endcsname}
+%D Now official:
+
+\permanent\protected\def\spaceorpar
+ {\endgraf\ifhmode\space\fi}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/spac-hor.mkxl b/tex/context/base/mkiv/spac-hor.mkxl
index 450e4fd76..b6f92947e 100644
--- a/tex/context/base/mkiv/spac-hor.mkxl
+++ b/tex/context/base/mkiv/spac-hor.mkxl
@@ -19,6 +19,9 @@
\let\parfillrightskip\parfillskip
+\bitwiseflip \normalizelinemode \parindentskipcode
+\bitwiseflip \normalizelinemode \normalizelinecode
+
\let\v_spac_indentation_current\empty % amount/keyword
\newdimen \d_spac_indentation_par
diff --git a/tex/context/base/mkiv/spac-ver.lmt b/tex/context/base/mkiv/spac-ver.lmt
index 2cda39586..90eeacf26 100644
--- a/tex/context/base/mkiv/spac-ver.lmt
+++ b/tex/context/base/mkiv/spac-ver.lmt
@@ -765,301 +765,196 @@ do
end
end
- do -- old variant
-
- local ctx_fixedblankskip = context.fixedblankskip
- local ctx_flexibleblankskip = context.flexibleblankskip
- local ctx_setblankcategory = context.setblankcategory
- local ctx_setblankorder = context.setblankorder
- local ctx_setblankpenalty = context.setblankpenalty
- ----- ctx_setblankhandling = context.setblankhandling
- local ctx_flushblankhandling = context.flushblankhandling
- local ctx_addpredefinedblankskip = context.addpredefinedblankskip
- local ctx_addaskedblankskip = context.addaskedblankskip
- local ctx_setblankpacked = context.setblankpacked
-
- local ctx_pushlogger = context.pushlogger
- local ctx_startblankhandling = context.startblankhandling
- local ctx_stopblankhandling = context.stopblankhandling
- local ctx_poplogger = context.poplogger
-
- local pattern = nil
-
- local packed = categories.packed
-
- local function handler(amount, keyword, detail)
- if not keyword then
- report_vspacing("unknown directive %a",s)
- else
- local mk = map[keyword]
- if mk then
- lpegmatch(pattern,mk)
- elseif keyword == k_fixed then
- ctx_fixedblankskip()
- elseif keyword == k_flexible then
- ctx_flexibleblankskip()
- elseif keyword == k_category then
- local category = tonumber(detail)
- if category == packed then
- ctx_setblankpacked()
- elseif category then
- ctx_setblankcategory(category)
- ctx_flushblankhandling()
- end
- elseif keyword == k_order and detail then
- local order = tonumber(detail)
- if order then
- ctx_setblankorder(order)
- end
- elseif keyword == k_penalty and detail then
- local penalty = tonumber(detail)
- if penalty then
- ctx_setblankpenalty(penalty)
- end
- else
- amount = tonumber(amount) or 1
- local sk = skip[keyword]
- if sk then
- ctx_addpredefinedblankskip(amount,keyword)
- else -- no check
- ctx_addaskedblankskip(amount,keyword)
- end
- end
- end
- end
-
- local splitter = ((multiplier + singlefier) * keyword * (category + Cc(false))) / handler
- pattern = (splitter + separator^1)^0
-
- function vspacing.analyze(str)
- if trace_vspacing then
- ctx_pushlogger(report_vspacing)
- ctx_startblankhandling()
- lpegmatch(pattern,str)
- ctx_stopblankhandling()
- ctx_poplogger()
- else
- ctx_startblankhandling()
- lpegmatch(pattern,str)
- ctx_stopblankhandling()
- end
- end
-
+ local expandmacro = token.expand_macro
+ -- local runlocal = tex.runlocal
+ -- local setmacro = tokens.setters.macro
+ -- local settoks = tex.settoks
+ local toscaled = tex.toscaled
+
+ local setattrs = nuts.setattrs
+
+ local b_done = false
+ local b_packed = false
+
+ local b_amount = 0
+ local b_stretch = 0
+ local b_shrink = 0
+ local b_category = false
+ local b_penalty = false
+ local b_order = false
+ local b_fixed = false
+ local b_grid = false
+
+ local pattern = nil
+
+ local packed = categories.packed
+
+ local gluefactor = .25
+
+ local ctx_ignoreparskip = context.core.ignoreparskip
+
+ local function before()
+ b_amount = 0
+ b_stretch = 0
+ b_shrink = 0
+ b_category = 1
+ b_penalty = false
+ b_order = false
+ b_fixed = b_grid
end
- do -- new variant
-
- local expandmacro = token.expand_macro
- -- local runlocal = tex.runlocal
- -- local setmacro = tokens.setters.macro
- -- local settoks = tex.settoks
- local toscaled = tex.toscaled
-
- local setattrs = nuts.setattrs
-
- local b_done = false
- local b_packed = false
-
- local b_amount = 0
- local b_stretch = 0
- local b_shrink = 0
- local b_category = false
- local b_penalty = false
- local b_order = false
- local b_fixed = false
- local b_grid = false
-
- local pattern = nil
-
- local packed = categories.packed
-
- local gluefactor = .25
-
- local ctx_ignoreparskip = context.core.ignoreparskip
-
- -- local ctx_vspacingfromtempstring = context.core.vspacingfromtempstring
- -- local ctx_vspacingfromscratchtoks = context.core.vspacingfromscratchtoks
-
- -- local ctx_vspacingpredefinedvalue = context.core.vspacingpredefinedvalue
- --
- -- local cache = table.setmetatableindex(function(t,k)
- -- local v = function() ctx_vspacingpredefinedvalue(k) end
- -- t[k] = v
- -- return v
- -- end)
-
- local function before()
- b_amount = 0
- b_stretch = 0
- b_shrink = 0
- b_category = 1
- b_penalty = false
- b_order = false
- b_fixed = b_grid
- end
-
- local function after()
- if fixed then
- b_stretch = 0
- b_shrink = 0
- else
- b_stretch = gluefactor * b_amount
- b_shrink = gluefactor * b_amount
- end
+ local function after()
+ if fixed then
+ b_stretch = 0
+ b_shrink = 0
+ else
+ b_stretch = gluefactor * b_amount
+ b_shrink = gluefactor * b_amount
end
+ end
- -- use a cache for predefined ones
-
- -- local function inject()
- -- local n = new_glue(b_amount,b_stretch,b_shrink)
- -- if b_category then
- -- setattr(n,a_skipcategory,b_category)
- -- end
- -- if b_penalty then
- -- setattr(n,a_skippenalty,b_penalty)
- -- end
- -- if b_order then
- -- setattr(n,a_skiporder,b_order or 1)
- -- end
- -- write_node(n)
- -- end
+ -- use a cache for predefined ones
- local function inject()
- local n = new_glue(b_amount,b_stretch,b_shrink)
- setattrs(n,false,a_skipcategory,b_category,a_skippenalty,b_penalty,a_skiporder,b_order or 1)
- write_node(n)
- end
+ local function inject()
+ local n = new_glue(b_amount,b_stretch,b_shrink)
+ setattrs(n,false,a_skipcategory,b_category,a_skippenalty,b_penalty,a_skiporder,b_order or 1)
+ write_node(n)
+ end
- local function flush()
- after()
- if b_done then
- inject()
- b_done = false
- end
- before()
+ local function flush()
+ after()
+ if b_done then
+ inject()
+ b_done = false
end
+ before()
+ end
- -- local cmd = token.create("vspacingfromtempstring")
- local cmd = token.create("vspacingpredefinedvalue")
+ -- local cmd = token.create("vspacingfromtempstring")
+ -- local cmd = token.create("vspacingpredefinedvalue") -- not yet known
- local function handler(multiplier, keyword, detail)
- if not keyword then
- report_vspacing("unknown directive %a",s)
+ local function handler(multiplier, keyword, detail)
+ if not keyword then
+ report_vspacing("unknown directive %a",s)
+ else
+ local mk = map[keyword]
+ if mk then
+ lpegmatch(pattern,mk)
+ elseif keyword == k_fixed then
+ b_fixed = true
+ elseif keyword == k_flexible then
+ b_flexible = false
+ elseif keyword == k_category then
+ local category = tonumber(detail)
+ if category == packed then
+ b_packed = true
+ elseif category then
+ b_category = category
+ b_done = true
+ flush()
+ end
+ elseif keyword == k_order and detail then
+ local order = tonumber(detail)
+ if order then
+ b_order = order
+ end
+ elseif keyword == k_penalty and detail then
+ local penalty = tonumber(detail)
+ if penalty then
+ flush()
+ b_done = true
+ b_category = 3
+ b_penalty = penalty
+ flush()
+ end
else
- local mk = map[keyword]
- if mk then
- lpegmatch(pattern,mk)
- elseif keyword == k_fixed then
- b_fixed = true
- elseif keyword == k_flexible then
- b_flexible = false
- elseif keyword == k_category then
- local category = tonumber(detail)
- if category == packed then
- b_packed = true
- elseif category then
- b_category = category
- b_done = true
- flush()
- end
- elseif keyword == k_order and detail then
- local order = tonumber(detail)
- if order then
- b_order = order
+ local amount, stretch, shrink
+ multiplier = tonumber(multiplier) or 1
+ local sk = skip[keyword]
+ if sk then
+ -- multiplier, keyword
+ -- best, for now, todo: runlocal with arguments
+ expandmacro("vspacingpredefinedvalue",true,keyword)
+ -- expandmacro(cmd,true,keyword)
+ -- setmacro("tempstring",keyword)
+ -- runlocal(cmd)
+ -- nicest
+ -- runlocal(cache[keyword])
+ -- fast
+ -- settoks("scratchtoks",keyword)
+ -- runlocal("vspacingfromscratchtoks")
+ -- middleground
+ -- setmacro("tempstring",keyword)
+ -- runlocal(ctx_vspacingfromtempstring)
+ --
+ amount, stretch, shrink = texgetglue("scratchskip")
+ if not stretch then
+ stretch = 0
end
- elseif keyword == k_penalty and detail then
- local penalty = tonumber(detail)
- if penalty then
- flush()
- b_done = true
- b_category = 3
- b_penalty = penalty
- flush()
+ if not shrink then
+ shrink = 0
end
- else
- local amount, stretch, shrink
- multiplier = tonumber(multiplier) or 1
- local sk = skip[keyword]
- if sk then
- -- multiplier, keyword
- -- best, for now, todo: runlocal with arguments
- -- expandmacro("vspacingpredefinedvalue",true,keyword)
- expandmacro(cmd,true,keyword)
- -- setmacro("tempstring",keyword)
- -- runlocal(cmd)
- -- nicest
- -- runlocal(cache[keyword])
- -- fast
- -- settoks("scratchtoks",keyword)
- -- runlocal("vspacingfromscratchtoks")
- -- middleground
- -- setmacro("tempstring",keyword)
- -- runlocal(ctx_vspacingfromtempstring)
- --
- amount, stretch, shrink = texgetglue("scratchskip")
- if stretch == 0 and shrink == 0 then
- stretch = gluefactor * amount -- always unless grid
- shrink = stretch -- always unless grid
- end
- else -- no check, todo: parse plus and minus
- amount = toscaled(keyword)
+ if stretch == 0 and shrink == 0 then
stretch = gluefactor * amount -- always unless grid
shrink = stretch -- always unless grid
end
- -- we look at fixed later
- b_amount = b_amount + multiplier * amount
- b_stretch = b_stretch + multiplier * stretch
- b_shrink = b_shrink + multiplier * shrink
- b_done = true
+ else -- no check, todo: parse plus and minus
+ amount = toscaled(keyword)
+ stretch = gluefactor * amount -- always unless grid
+ shrink = stretch -- always unless grid
end
+ -- we look at fixed later
+ b_amount = b_amount + multiplier * amount
+ b_stretch = b_stretch + multiplier * stretch
+ b_shrink = b_shrink + multiplier * shrink
+ b_done = true
end
end
+ end
- -- alternatively we can make a table and have a keyword -> split cache but this is probably
- -- not really a bottleneck
+ -- alternatively we can make a table and have a keyword -> split cache but this is probably
+ -- not really a bottleneck
- local splitter = ((multiplier + singlefier) * keyword * (category + Cc(false))) / handler
- pattern = (splitter + separator^1)^0
+ local splitter = ((multiplier + singlefier) * keyword * (category + Cc(false))) / handler
+ pattern = (splitter + separator^1)^0
- function vspacing.inject(grid,str)
- if trace_vspacing then
- -- ctx_pushlogger(report_vspacing)
- end
- b_done = false
- b_packed = false
- b_grid = gridsnapping
- before()
- lpegmatch(pattern,str)
- after()
- if b_done then
- inject()
- end
- if b_packed then
- ctx_ignoreparskip()
- end
- if trace_vspacing then
- -- ctx_poplogger()
- end
+ function vspacing.inject(grid,str)
+ if trace_vspacing then
+ -- ctx_pushlogger(report_vspacing)
end
-
- function vspacing.injectpenalty(penalty)
- local n = new_glue()
- setattrs(n,false,a_skipcategory,categories.penalty,a_skippenalty,penalty,a_skiporder,1)
- write_node(n)
+ b_done = false
+ b_packed = false
+ b_grid = gridsnapping
+ before()
+ lpegmatch(pattern,str)
+ after()
+ if b_done then
+ inject()
end
-
- function vspacing.injectskip(amount)
- local n = new_glue(amount)
- setattrs(n,false,a_skipcategory,categories.largest,a_skippenalty,false,a_skiporder,1)
- write_node(n)
+ if b_packed then
+ ctx_ignoreparskip()
end
-
- function vspacing.injectdisable(amount)
- local n = new_glue()
- setattrs(n,false,a_skipcategory,categories.disable,a_skippenalty,false,a_skiporder,1)
- write_node(n)
+ if trace_vspacing then
+ -- ctx_poplogger()
end
+ end
+
+ function vspacing.injectpenalty(penalty)
+ local n = new_glue()
+ setattrs(n,false,a_skipcategory,categories.penalty,a_skippenalty,penalty,a_skiporder,1)
+ write_node(n)
+ end
+
+ function vspacing.injectskip(amount)
+ local n = new_glue(amount)
+ setattrs(n,false,a_skipcategory,categories.largest,a_skippenalty,false,a_skiporder,1)
+ write_node(n)
+ end
+ function vspacing.injectdisable(amount)
+ local n = new_glue()
+ setattrs(n,false,a_skipcategory,categories.disable,a_skippenalty,false,a_skiporder,1)
+ write_node(n)
end
end
@@ -2466,12 +2361,12 @@ do
-- old variant
- implement {
- name = "vspacing",
- actions = vspacing.analyze,
- scope = "private",
- arguments = "string"
- }
+-- implement {
+-- name = "vspacing",
+-- actions = vspacing.analyze,
+-- scope = "private",
+-- arguments = "string"
+-- }
-- new variant
diff --git a/tex/context/base/mkiv/spac-ver.mkxl b/tex/context/base/mkiv/spac-ver.mkxl
index 3cc8dbcad..92adce2c6 100644
--- a/tex/context/base/mkiv/spac-ver.mkxl
+++ b/tex/context/base/mkiv/spac-ver.mkxl
@@ -1931,6 +1931,10 @@
\def\spac_vspacing_no_topskip % use grouped
{\c_attr_skipcategory\pluseleven}
+%permanent\def\vspacingfromscratchtoks {\scratchdimen\dimexpr\csname\??vspacingamount\the\scratchtoks\endcsname\relax}
+\permanent\def\vspacingpredefinedvalue#1{\scratchskip\glueexpr\csname\??vspacingamount#1\endcsname\relax}
+%permanent\def\vspacingfromtempstring {\scratchdimen\dimexpr\csname\??vspacingamount\tempstring\endcsname\relax}
+
% \installcorenamespace{vspacingamountnormal}
% \installcorenamespace{vspacingamountgrid}
@@ -1976,81 +1980,6 @@
\relax
\to \everyafterblankhandling
-\permanent\protected\def\setblankpacked
- {\settrue\c_space_ignore_parskip}
-
-\permanent\protected\def\setblankcategory#1%
- {\settrue\c_space_vspacing_done
- \c_attr_skipcategory#1\relax}
-
-\permanent\protected\def\setblankorder#1%
- {\c_attr_skiporder#1\relax}
-
-\permanent\protected\def\fixedblankskip
- {\settrue\c_space_vspacing_fixed}
-
-\permanent\protected\def\flexibleblankskip
- {\setfalse\c_space_vspacing_fixed}
-
-% \protected\def\addblankskip#1#2#3%
-% {\settrue\c_space_vspacing_done
-% \advance\s_spac_vspacing_temp#1\dimexpr\ifgridsnapping#3\else#2\fi\relax\relax}
-
-\permanent\protected\def\setblankpenalty#1%
- {\flushblankhandling
- \settrue\c_space_vspacing_done
- \c_attr_skipcategory\plusthree
- \c_attr_skippenalty #1\relax
- \flushblankhandling}
-
-\permanent\protected\def\startblankhandling % move this to \vspacing
- {\par
- \ifvmode
- \expandafter\dostartblankhandling
- \else
- \expandafter\nostartblankhandling
- \fi}
-
-\permanent\protected\def\nostartblankhandling#1\stopblankhandling
- {}
-
-\permanent\def\dostartblankhandling
- {\begingroup
- \setfalse\c_space_vspacing_done
- \setfalse\c_space_ignore_parskip
- \the\everybeforeblankhandling}
-
-\permanent\protected\def\stopblankhandling
- {\the\everyafterblankhandling
- \ifconditional\c_space_vspacing_done
- \vskip\s_spac_vspacing_temp
- \fi
- \ifconditional\c_space_ignore_parskip
- \endgroup\ignoreparskip
- \else
- \endgroup
- \fi}
-
-\permanent\protected\def\flushblankhandling
- {\the\everyafterblankhandling
- \ifconditional\c_space_vspacing_done
- \vskip\s_spac_vspacing_temp
- \setfalse\c_space_vspacing_done
- \fi
- \the\everybeforeblankhandling}
-
-\permanent\protected\def\addpredefinedblankskip#1#2%
- {\settrue\c_space_vspacing_done
- \advance\s_spac_vspacing_temp#1\dimexpr\csname\??vspacingamount#2\endcsname\relax}
-
-% \protected\def\addpredefinedblankskip#1#2%
-% {\settrue\c_space_vspacing_done
-% \advance\s_spac_vspacing_temp#1\dimexpr\the\csname\ifgridsnapping g\else n\fi>#2\endcsname\relax}
-
-\permanent\protected\def\addaskedblankskip#1#2%
- {\settrue\c_space_vspacing_done
- \advance\s_spac_vspacing_temp#1\dimexpr#2\relax}
-
% The main spacer:
% \protected\def\vspacing
@@ -2081,29 +2010,16 @@
\expandafter\spac_vspacing_nop_ignore
\fi}
-\def\spac_vspacing_yes_indeed[#1]%
- {\ifmmode\else\par\clf_vspacing{#1}\fi}
+\def\spac_vspacing_yes_indeed[#1]{\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{#1}\fi\fi}
+\def\spac_vspacing_nop_indeed {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{\currentvspacing}\fi\fi}
-\def\spac_vspacing_yes_ignore[#1]%
- {\ifmmode\else\par\fi}
-
-\def\spac_vspacing_nop_indeed
- {\ifmmode\else\par\clf_vspacing{\currentvspacing}\fi}
-
-\def\spac_vspacing_nop_ignore
- {\ifmmode\else\par\fi}
+\def\spac_vspacing_yes_ignore[#1]{\ifmmode\else\par\fi}
+\def\spac_vspacing_nop_ignore {\ifmmode\else\par\fi}
\installcorenamespace{vspacing}
-\protected\def\directvspacing#1%
- {\par
- \ifchkdim#1\or
- \spac_vspacing_dim_preset{\the\dimexpr#1}%
- \orelse\ifcsname\??vspacing#1\endcsname
- \lastnamedcs
- \else
- \spac_vspacing_yes_preset{#1}%
- \fi}
+\permanent\protected\def\directvspacing#1%
+ {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{\iftok{#1}\emptytoks\currentvspacing\else#1\fi}\fi\fi}
\def\spac_vspacing_dim_preset#1%
{\ifcsname\??vspacing#1\endcsname
@@ -2119,16 +2035,6 @@
%\writestatus{}{}%
\csname\??vspacing#1\endcsname}
-\def\spac_vspacing_yes_indeed[#1]%
- {\ifmmode\else
- \directvspacing{#1}%
- \fi}
-
-\def\spac_vspacing_nop_indeed
- {\ifmmode\else
- \directvspacing\currentvspacing
- \fi}
-
\permanent\protected\def\directdefaultvspacing
{\ifinpagebody % somewhat weird
\directvspacing\currentvspacing
@@ -2153,21 +2059,8 @@
%D Handy (and faster):
-\permanent\protected\def\directvpenalty#1%
- {\begingroup
- \c_attr_skipcategory\plusthree
- \c_attr_skippenalty #1\relax
- \c_attr_skiporder \attributeunsetvalue
- \vskip\zeropoint
- \endgroup}
-
-\permanent\protected\def\directvskip#1%
- {\begingroup
- \c_attr_skipcategory\plusone
- \c_attr_skippenalty \attributeunsetvalue
- \c_attr_skiporder \attributeunsetvalue
- \vskip#1\relax
- \endgroup}
+\permanent\protected\def\directvpenalty#1{\ifmmode\else\par\ifvmode\clf_injectvpenalty#1\relax\fi\fi}
+\permanent\protected\def\directvskip #1{\ifmmode\else\par\ifvmode\clf_injectvskip #1\relax\fi\fi}
%D These depend on bigskipamount cum suis so we'd better sync them:
@@ -2310,13 +2203,7 @@
%
% but use the following more efficient variant instead:
-\permanent\protected\def\inhibitblank
- {\ifvmode
- \begingroup
- \c_attr_skipcategory\plusfive
- \vskip\zeropoint
- \endgroup
- \fi}
+\permanent\protected\def\inhibitblank{\ifmmode\else\par\ifvmode\clf_injectdisable\fi\fi}
\let\doinhibitblank\inhibitblank % keep this command, used in styles
@@ -2578,57 +2465,4 @@
\protected\def\ignoreparskip{\c_spac_vspacing_ignore_parskip\plusone}
-% experimental (for the moment only for hh and ws)
-
-%def\vspacingfromscratchtoks {\scratchdimen\dimexpr\csname\??vspacingamount\the\scratchtoks\endcsname\relax}
-\def\vspacingpredefinedvalue#1{\scratchskip\glueexpr\csname\??vspacingamount#1\endcsname\relax}
-%def\vspacingfromtempstring {\scratchdimen\dimexpr\csname\??vspacingamount\tempstring\endcsname\relax}
-
-\let\spac_vspacing_yes_indeed_old\spac_vspacing_yes_indeed
-\let\spac_vspacing_nop_indeed_old\spac_vspacing_nop_indeed
-\let\directvspacing_old \directvspacing
-
-\def\spac_vspacing_yes_indeed_new[#1]%
- {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{#1}\fi\fi}
-
-\def\spac_vspacing_nop_indeed_new
- {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{\currentvspacing}\fi\fi}
-
-\protected\def\directvspacing_new#1%
-%{\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{#1}\fi\fi}
- {\ifmmode\else\par\ifvmode\clf_injectvspacing\ifgridsnapping\plusone\else\zerocount\fi{\iftok{#1}\emptytoks\currentvspacing\else#1\fi}\fi\fi}
-
-\let\directvpenalty_old\directvpenalty
-\let\directvskip_old \directvskip
-\let\inhibitblank_old \inhibitblank
-
-\protected\def\directvpenalty_new#1{\ifmmode\else\par\ifvmode\clf_injectvpenalty#1\relax\fi\fi}
-\protected\def\directvskip_new #1{\ifmmode\else\par\ifvmode\clf_injectvskip #1\relax\fi\fi}
-\protected\def\inhibitblank_new {\ifmmode\else\par\ifvmode\clf_injectdisable \fi\fi}
-
-% we need to ensure \enforced
-
-\def\spac_vspacing_temp_yes
- {\writestatus{vspacing}{enabling experimental handler}%
- \enforced\let\spac_vspacing_yes_indeed\spac_vspacing_yes_indeed_new
- \enforced\let\spac_vspacing_nop_indeed\spac_vspacing_nop_indeed_new
- \enforced\let\directvspacing\directvspacing_new
- \enforced\let\directvpenalty\directvpenalty_new
- \enforced\let\directvskip\directvskip_new
- \enforced\let\inhibitblank\inhibitblank_new}
-
-\def\spac_vspacing_temp_nop
- {\writestatus{vspacing}{disabling experimental handler}%
- \enforced\let\spac_vspacing_yes_indeed\spac_vspacing_yes_indeed_old
- \enforced\let\spac_vspacing_nop_indeed\spac_vspacing_nop_indeed_old
- \enforced\let\directvspacing\directvspacing_old
- \enforced\let\directvpenalty\directvpenalty_old
- \enforced\let\directvskip\directvskip_old
- \enforced\let\inhibitblank\inhibitblank_old}
-
-\installtexdirective
- {vspacing.experimental}
- {\spac_vspacing_temp_yes}
- {\spac_vspacing_temp_nop}
-
\protect \endinput
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 564a75c84..842543ac0 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index a65fd3799..30b41d6e6 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-bkm.mkxl b/tex/context/base/mkiv/strc-bkm.mkxl
new file mode 100644
index 000000000..c5bd87324
--- /dev/null
+++ b/tex/context/base/mkiv/strc-bkm.mkxl
@@ -0,0 +1,182 @@
+%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 ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Bookmarks}
+
+\registerctxluafile{strc-bkm}{}
+
+% \enabledirectives[references.bookmarks.preroll]
+
+\unprotect
+
+%D Bookmarks are a very viewer dependent feature. They are mostly used as additional
+%D table of contents and therefore relate directly to lists.
+%D
+%D A bookmark list is added to the document only when interaction is enabled. The
+%D given lists are bookmarked and a second argument specifies the opened bookmark
+%D trees.
+%D
+%D \starttyping
+%D \placebookmarks
+%D [chapter,section,subsection,mylist]
+%D [chapter]
+%D \stoptyping
+%D
+%D You can overloads the last set bookmark in a sectioning command:
+%D
+%D \starttyping
+%D \chapter {the first chapter}
+%D \bookmark {the first bookmark}
+%D \stoptyping
+%D
+%D However, in practice you can better use \type {\startchapter} and set the \type
+%D {bookmark} parameter.
+%D
+%D You can add entries to the bookmarklist:
+%D
+%D \starttyping
+%D \bookmark[mylist]{whatever}
+%D \stoptyping
+%D
+%D Use force to get titles in the bookmarklist. This is somewhat tricky as one does
+%D not want \quotation {Contents} in a table of contents but it has to be in the
+%D bookmark list.
+
+\installcorenamespace{bookmark}
+
+\installsetuponlycommandhandler \??bookmark {bookmark} % installdirectparametersethandler
+
+\setupbookmark
+ [\c!force=\v!no, % it's easier to force that to inhibit
+ \c!number=\v!yes, % might become v!no
+ \c!sectionblock=\v!no] % show sectionblock level + title
+
+\aliased\let\setupbookmarks\setupbookmark
+
+\permanent\protected\def\bookmark
+ {\iflocation
+ \expandafter\strc_bookmarks_bookmark_yes
+ \else
+ \expandafter\strc_bookmarks_bookmark_nop
+ \fi}
+
+\tolerant\def\strc_bookmarks_bookmark_yes[#1]#:#2%
+ {\begingroup
+ \simplifycommands
+ \ifnum\thenamedheadlevel{#1}>\zerocount
+ \clf_overloadbookmark{#1}{\detokenize\expandafter{\normalexpanded{#2}}}%
+ \else
+ \writetolist[#1]{#2}{}% todo: a dedicated bookmark writer
+ \fi
+ \endgroup}
+
+\tolerant\def\strc_bookmarks_bookmark_nop[#1]#:#2%
+ {}
+
+\permanent\protected\def\placebookmarks
+ {\iflocation
+ \expandafter\strc_bookmarks_place_yes
+ \else
+ \expandafter\gobblethreeoptionals
+ \fi}
+
+\let\m_bookmarks_names \empty
+\let\m_bookmarks_opened\empty
+
+\tolerant\def\strc_bookmarks_place_yes[#1]#*[#2]#*[#3]%
+ {\begingroup
+ \edef\m_bookmarks_names{#1}%
+ \edef\m_bookmarks_opened{#2}%
+ \ifempty\m_bookmarks_names
+ \edef\m_bookmarks_names{\namedlistparameter\v!content\c!list}%
+ \fi
+ \ifempty\m_bookmarks_names
+ \let\m_bookmarks_names\v!all
+ \fi
+ \ifparameters\or\or
+ \doifelseassignment{#2}{\let\m_bookmarks_opened\empty\setupcurrentbookmark[#2]}\donothing
+ \or
+ \setupcurrentbookmark[#3]% no every so not all possible
+ \fi
+ \clf_registerbookmark
+ names {\m_bookmarks_names}%
+ opened {\m_bookmarks_opened}%
+ force {\bookmarkparameter\c!force}%
+ number {\bookmarkparameter\c!number}%
+ \relax
+ \endgroup}
+
+\appendtoks
+ \clf_setupbookmarks
+ separatorset {\bookmarkparameter\c!numberseparatorset}%
+ conversionset {\bookmarkparameter\c!numberconversionset}%
+ starter {\bookmarkparameter\c!numberstarter}%
+ stopper {\bookmarkparameter\c!numberstopper}%
+ segments {\bookmarkparameter\c!numbersegments}%
+ showblocktitle {\bookmarkparameter\c!sectionblock}%
+ \relax
+\to \everysetupbookmark
+
+%D There is a plugin mechanism but this is for experts only. The intermediate
+%D data structures are stable.
+%D
+%D \starttyping
+%D \startluacode
+%D structures.bookmarks.installhandler("check before","before",function(levels)
+%D logs.report("extra bookmarks","before (normal bookmarks)")
+%D inspect(levels)
+%D logs.report("extra bookmarks","before (extra bookmarks)")
+%D inspect(structures.bookmarks.extras.get())
+%D return levels
+%D end)
+%D structures.bookmarks.installhandler("check after", "after", function(levels)
+%D logs.report("extra bookmarks","after (merged bookmarks)")
+%D inspect(levels)
+%D return levels
+%D end)
+%D \stopluacode
+%D \starttyping
+%D
+%D This mechanism was added when bookmark inclusion became (optional) part of graphic
+%D inclusion (which is needed by Taco).
+%D
+%D \starttyping
+%D \getfiguredimensions[somefile.pdf]
+%D \dorecurse {\noffigurepages} {
+%D \startTEXpage
+%D \externalfigure[somefile.pdf][interaction=bookmark,page=\recurselevel]
+%D \stopTEXpage
+%D }
+%D \starttyping
+
+\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/mkiv/strc-con.mklx b/tex/context/base/mkiv/strc-con.mklx
index bdc18de81..08420a7ef 100644
--- a/tex/context/base/mkiv/strc-con.mklx
+++ b/tex/context/base/mkiv/strc-con.mklx
@@ -534,8 +534,8 @@
\newbox \constructionheadbox
\newskip \leftconstructionskip
\newskip \rightconstructionskip
-\newdimen \constructionsheadwidth % replaces \!!widtha % TODO: proper namespace dimens
-\newdimen \constructionsheaddistance % replaces \!!widthb % TODO: proper namespace dimens
+\newdimen \constructionsheadwidth
+\newdimen \constructionsheaddistance
\def\strc_constructions_set_hang_box#1% messy left/rightskip
{\setbox\constructionheadbox\vtop % \vbox gaat fout in hang
diff --git a/tex/context/base/mkiv/strc-flt.mklx b/tex/context/base/mkiv/strc-flt.mklx
index bbe027fd2..994ca288a 100644
--- a/tex/context/base/mkiv/strc-flt.mklx
+++ b/tex/context/base/mkiv/strc-flt.mklx
@@ -254,17 +254,17 @@
\strc_floats_define_commands{#1}{#2}}
\def\strc_floats_define_commands#1#2%
- {\setuvalue {\e!place\e!listof#2}{\dodoubleempty\strc_lists_place[#1]}% call will change
- \setuvalue {\e!complete\e!listof#2}{\dotripleempty\strc_lists_complete_indeed[#1][#2]}% call will change
- \setuevalue {\e!place#1}{\strc_floats_place[#1]}%
- \setuevalue {\e!start\e!place#1}{\strc_floats_start_place[#1]}%
- \setuevalue {\e!stop\e!place#1}{\strc_floats_stop_place}%
- \setuevalue {\e!start#1\e!text}{\strc_floats_start_text[#1]}%
- \setuevalue {\e!stop#1\e!text}{\strc_floats_stop_text}%
+ {\frozen\instance\setuevalue{\e!place\e!listof#2}{\strc_lists_place[#1]}% call will change
+ \frozen\instance\setuevalue{\e!complete\e!listof#2}{\strc_lists_complete[#1][#2]}% call will change
+ \frozen\instance\setuevalue{\e!place#1}{\strc_floats_place[#1]}%
+ \frozen\instance\setuevalue{\e!start\e!place#1}{\strc_floats_start_place[#1]}%
+ \frozen\instance\setuevalue{\e!stop\e!place#1}{\strc_floats_stop_place}%
+ \frozen\instance\setuevalue{\e!start#1\e!text}{\strc_floats_start_text[#1]}%
+ \frozen\instance\setuevalue{\e!stop#1\e!text}{\strc_floats_stop_text}%
% these will become obsolete:
- \setuevalue {\e!reserve#1}{\strc_floats_reserve[#1]}%
+ \setuevalue{\e!reserve#1}{\strc_floats_reserve[#1]}%
\setuevalue{\e!start\e!reserve#1\e!text}{\strc_floats_start_reserve_text[#1]}%
- \setuevalue {\e!stop\e!reserve#1\e!text}{\strc_floats_stop_reserve_text}}
+ \setuevalue{\e!stop\e!reserve#1\e!text}{\strc_floats_stop_reserve_text}}
%D Fallback float body:
@@ -1256,24 +1256,24 @@
{\begincsname\??floatmovement#setting\endcsname}
\def\strc_floats_move_down_line#sign%
- {\if!!donea \else
+ {\ifscratchconditionone \else
\global\d_page_sides_downshift\zeropoint
- \!!doneatrue
+ \scratchconditiononetrue
\fi
\global\advance\d_page_sides_downshift#sign\lineheight}
\def\strc_floats_move_down_hang#lines%
- {\if!!doneb \else
+ {\ifscratchconditiontwo \else
\global\c_page_sides_n_of_lines\zerocount
- \!!donebtrue
+ \scratchconditiontwotrue
\fi
\global\advance\c_page_sides_n_of_lines#lines\relax}
\permanent\protected\def\movedownsidefloat[#settings]% already in core
{\unless\ifhastok:{#settings}%
\begingroup
- \!!doneafalse
- \!!donebfalse
+ \scratchconditiononefalse
+ \scratchconditiontwofalse
\normalexpanded{\dorepeatwithcommand[#settings]}\strc_floats_move_down
\endgroup
\fi}
diff --git a/tex/context/base/mkiv/strc-ind.mkxl b/tex/context/base/mkiv/strc-ind.mkxl
new file mode 100644
index 000000000..31d7eb575
--- /dev/null
+++ b/tex/context/base/mkiv/strc-ind.mkxl
@@ -0,0 +1,128 @@
+%D \module
+%D [ file=strc-ind, % was part of strc-des,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Indented Text,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Indented Text}
+
+\unprotect
+
+%D \macros
+%D {defineindentedtext,
+%D setupindentedtext}
+%D
+%D Ok, we keep it but with a different command as it all looks too
+%D much like indentation and indenting. We also assume start/stop
+%D usage or some explicit par.
+
+\installcorenamespace{indentedtext}
+
+\installcommandhandler \??indentedtext {indentedtext} \??indentedtext
+
+%D \startbuffer
+%D \defineindentedtext[one][text=one]
+%D \defineindentedtext[two][text=two]
+%D
+%D \one test test \par
+%D \subone test test \par
+%D \subtwo test test \par
+%D \subsubone test test \par
+%D
+%D \startone
+%D test test
+%D \startone
+%D test test
+%D \startone
+%D test test
+%D \stopone
+%D \starttwo
+%D test test
+%D \startone
+%D test test
+%D \stopone
+%D \stoptwo
+%D \stopone
+%D \stopone
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\newcount\c_strc_indentedtexts_nesting
+\newdimen\d_strc_indentedtexts_width
+\newdimen\d_strc_indentedtexts_distance
+
+\appendtoks
+ \frozen\instance\setuevalue {\e!start\currentindentedtext}{\strc_indentedtexts_start{\currentindentedtext}\c_strc_indentedtexts_nesting}%
+ \frozen\instance\setuevalue {\e!stop \currentindentedtext}{\strc_indentedtexts_stop}%
+ % to be avoided ... might go away
+ \frozen\instance\setuevalue {\currentindentedtext}{\strc_indentedtexts_direct{\currentindentedtext}{0}}%
+ \frozen\instance\setuevalue {\v!sub\currentindentedtext}{\strc_indentedtexts_direct{\currentindentedtext}{1}}%
+ \frozen\instance\setuevalue{\v!sub\v!sub\currentindentedtext}{\strc_indentedtexts_direct{\currentindentedtext}{2}}%
+\to \everydefineindentedtext
+
+\protected\def\strc_indentedtexts_start#1#2% we need to get rid of \spr
+ {\par
+ \begingroup
+ \edef\currentindentedtext{#1}%
+ \c_strc_indentedtexts_nesting#2\relax
+ \indentedtextparameter\c!before
+ \d_strc_indentedtexts_distance\indentedtextparameter\c!distance\relax
+ \doifnothing{\indentedtextparameter\c!sample}
+ {\setindentedtextparameter\c!sample{\indentedtextparameter\c!text}}%
+ \assignwidth
+ {\indentedtextparameter\c!width}
+ {\d_strc_indentedtexts_width}
+ {\useindentedtextstyleandcolor\c!headstyle\c!headcolor
+ \indentedtextparameter\c!sample
+ \spr{\indentedtextparameter\c!separator}}
+ {\d_strc_indentedtexts_distance}%
+ \advance\d_strc_indentedtexts_width \d_strc_indentedtexts_distance
+ \setbox\scratchbox\hbox to \d_strc_indentedtexts_width
+ {\useindentedtextstyleandcolor\c!headstyle\c!headcolor
+ \strut
+ \indentedtextparameter\c!text
+ \hss
+ \spr{\indentedtextparameter\c!separator}%
+ \hskip\d_strc_indentedtexts_distance}%
+ \parindent\zeropoint
+ \hskip\c_strc_indentedtexts_nesting\d_strc_indentedtexts_width
+ \advance\c_strc_indentedtexts_nesting\plusone
+ \dontleavehmode\box\scratchbox
+ \hangindent\c_strc_indentedtexts_nesting\d_strc_indentedtexts_width
+ \useindentedtextstyleandcolor\c!style\c!color}
+
+\protected\def\strc_indentedtexts_stop
+ {\indentedtextparameter\c!after
+ \par
+ \endgroup}
+
+\permanent\tolerant\protected\def\startindentedtext[#1]%
+ {\strc_indentedtexts_start{#1}\c_strc_indentedtexts_nesting}
+
+\permanent\let\stopindentedtext\strc_indentedtexts_stop
+
+\protected\def\strc_indentedtexts_direct#1#2#3\par % no longer clever grabpar trickery
+ {\strc_indentedtexts_start{#1}{#2}#3\strc_indentedtexts_stop}
+
+\setupindentedtext
+ [\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/mkiv/strc-lnt.mklx b/tex/context/base/mkiv/strc-lnt.mklx
new file mode 100644
index 000000000..f24c93ee4
--- /dev/null
+++ b/tex/context/base/mkiv/strc-lnt.mklx
@@ -0,0 +1,359 @@
+%D \module
+%D [ file=strc-lnt,
+%D version=2002.05.10,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Line Notes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: mkvi #
+
+\writestatus{loading}{ConTeXt Structure Macros / Line Notes}
+
+%D This module loads on top of the footnote and line numbering macros.
+
+\unprotect
+
+\installcorenamespace{linenote}
+
+\aliased\let\setuplinenote\setupnote
+
+\newcount\c_strc_linenotes
+\newtoks\everydefinelinenote
+
+\permanent\tolerant\protected\def\definelinenote[#1]#*[#2]#*[#3]%
+ {\ifarguments
+ % error
+ \orelse\ifcsname\??linenote#1\endcsname
+ % there might be files that define the default 'linenote'
+ \ifparameters\or\or
+ \setupnote[#1][#2]%
+ \or
+ \setupnote[#1][#3]%
+ \fi
+ \else
+ \ifparameters\or
+ \definenote[#1]%
+ \or
+ \definenote[#1][#2]%
+ \or
+ \definenote[#1][#2][#3]%
+ \fi
+ \pushmacro\currentnote
+ \edef\currentnote{#1}
+ \letcsname\??linenote\currentnote\expandafter\endcsname\csname\currentnote\endcsname % use copy command
+ \frozen\instance\setuevalue {\currentnote}{\strc_linenotes_direct{\currentnote}}%
+ \frozen\instance\setuevalue{\e!start\currentnote}{\strc_linenotes_start {\currentnote}}%
+ \frozen\instance\setuevalue{\e!stop \currentnote}{\strc_linenotes_stop }%
+ \the\everydefinelinenote
+ \popmacro\currentnote
+ \fi}
+
+\protected\def\strc_linenotes_direct#1#2%
+ {\global\advance\c_strc_linenotes\plusone
+ \strc_linenotes_indeed{#1}{\the\c_strc_linenotes}{#2}%
+ \strc_linenotes_traced\empty
+ \normalexpanded{\someline[\the\c_strc_linenotes]}}
+
+\protected\def\strc_linenotes_start#1[#2]#3%
+ {\global\advance\c_strc_linenotes\plusone
+ \keepunwantedspaces
+ \strc_linenotes_indeed{#1}{#2}{#3}%
+ \strc_linenotes_traced{#2}%
+ \startline[#2]}
+
+\protected\def\strc_linenotes_stop[#1]%
+ {\stopline[#1]}
+
+\let\m_page_lines_previous_to \relax
+\let\m_page_lines_previous_from\relax
+
+\let\m_page_lines_current_to \relax
+\let\m_page_lines_current_from \relax
+
+\newconditional\c_page_lines_current_to
+\newconditional\c_page_lines_current_from
+
+\installcorenamespace{linenotespreviousfrom}
+\installcorenamespace{linenotespreviousto}
+
+\letvalue\??linenotespreviousfrom\empty
+\letvalue\??linenotespreviousto \empty
+
+% maybe do this in lua
+
+\def\page_lines_in_from{\in[lr:b:\currentlinenotereference]}
+\def\page_lines_in_to {\in[lr:e:\currentlinenotereference]}
+
+\protected\def\strc_linenotes_range_normal#1% order
+ {\doifelsereferencefound{lr:b:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_from
+ \ifconditional\c_page_lines_current_from
+ \xdef\m_page_lines_current_from{\currentreferencelinenumber}%
+ \doifelsereferencefound{lr:e:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_to
+ \ifconditional\c_page_lines_current_to
+ \xdef\m_page_lines_current_to{\currentreferencelinenumber}%
+ \page_lines_in_from
+ \ifx\m_page_lines_current_from\m_page_lines_current_to \else
+ \endash
+ \page_lines_in_to
+ \fi
+ \else
+ \page_lines_in_from
+ \fi
+ \else
+ \page_lines_in_from
+ \fi}
+
+\protected\def\strc_linenotes_range_sparse#1% order
+ {\doifelsereferencefound{lr:b:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_from
+ \ifconditional\c_page_lines_current_from
+ \xdef\m_page_lines_current_from{\currentreferencelinenumber}%
+ \doifelsereferencefound{lr:e:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_to
+ \ifconditional\c_page_lines_current_to
+ \xdef\m_page_lines_current_to{\currentreferencelinenumber}%
+ \ifx\m_page_lines_previous_from\m_page_lines_current_from
+ \ifx\m_page_lines_previous_to\m_page_lines_current_to \else
+ \page_lines_in_from
+ \ifx\m_page_lines_current_from\m_page_lines_current_to\else\endash\page_lines_in_to\fi
+ \fi
+ \else
+ \page_lines_in_from
+ \ifx\m_page_lines_current_from\m_page_lines_current_to\else\endash\page_lines_in_to\fi
+ \fi
+ \else
+ \page_lines_in_from
+ \fi
+ \else
+ \ifx\m_page_lines_previous_from\m_page_lines_current_from \else
+ \page_lines_in_from
+ \fi
+ \fi}
+
+\let\currentlinenotereference\empty
+
+\protected\def\strc_linenotes_indeed#1#2#3%
+ {\begingroup
+ % we keep things local so we can use it as regular note too
+ \edef\currentnotation{#1}%
+ \edef\currentlinenotereference{#2}%
+ \xdef\m_page_lines_previous_from{\begincsname\??linenotespreviousfrom\currentnotation\endcsname}%
+ \xdef\m_page_lines_previous_to {\begincsname\??linenotespreviousto \currentnotation\endcsname}%
+ \strc_linenotes_check_compression
+ \let\currentnote\currentnotation
+ \letnotationparameter\c!numbercommand\linenotelinenumber% todo: deep hook
+ \letnoteparameter \c!textcommand \gobbleoneargument % todo: deep hook
+ \csname\??linenote\currentnotation\endcsname{#3}%
+ \global\letcsname\??linenotespreviousfrom\currentnotation\endcsname\m_page_lines_current_from
+ \global\letcsname\??linenotespreviousto \currentnotation\endcsname\m_page_lines_current_to
+ \endgroup}
+
+% compression
+
+\installcorenamespace{linenotescompressmethod}
+
+% compress=yes|no
+% compressmethod=separator|stopper
+
+\setvalue{\??linenotescompressmethod\v!separator}%
+ {\edef\p_compressseparator{\noteparameter\c!compressseparator}%
+ \scratchskip\noteparameter\c!compressdistance\relax
+ \ifempty\p_compressseparator
+ \hskip\scratchskip
+ \else
+ \hskip.5\scratchskip
+ \begingroup\p_compressseparator\endgroup
+ \hskip.5\scratchskip
+ \fi}
+
+\setvalue{\??linenotescompressmethod\v!stopper}%
+ {\edef\p_compressstopper{\noteparameter\c!compressstopper}%
+ \scratchskip\noteparameter\c!compressdistance\relax
+ \ifempty\p_compressstopper
+ \hskip\scratchskip
+ \else
+ \begingroup\p_compressstopper\endgroup
+ \hskip.5\scratchskip
+ \fi}
+
+\setvalue{\??linenotescompressmethod\v!space}%
+ {\hskip\noteparameter\c!compressdistance\relax}
+
+\def\strc_linenotes_check_compression
+ {\edef\p_linenotes_compress {\noteparameter\c!compress}%
+ \edef\p_linenotes_compressmethod{\noteparameter\c!compressmethod}%
+ \ifx\p_linenotes_compress\v!yes
+ \let\linenotelinenumber\strc_linenotes_range_sparse
+ \else
+ \let\linenotelinenumber\strc_linenotes_range_normal
+ \fi
+ \ifcsname\??linenotescompressmethod\p_linenotes_compressmethod\endcsname \else
+ \let\p_linenotes_compressmethod\v!space
+ \fi}
+
+\def\strc_linenotes_inbetween % \ifcsname\??linenote\currentnote\expandafter\endcsname
+ {\begincsname\??linenotescompressmethod\p_linenotes_compressmethod\endcsname}
+
+\def\strc_notes_compress_distance{\emwidth \s!plus .5\emwidth \s!minus .25\emwidth}
+
+\setupnotes
+ [%c\compress=\v!no,
+ \c!compressdistance=\strc_notes_compress_distance,
+ \c!compressseparator=\symbol{\v!compressseparator},
+ \c!compressstopper=\symbol{\v!compressstopper}]
+
+\appendtoks
+ \letnoteparameter\c!inbetween\strc_linenotes_inbetween
+\to \everydefinelinenote
+
+% where to hook this one in? resetcounter has no hook:
+
+\permanent\protected\def\doresetlinenotecompression#1% \strc_linenotes_reset_previous
+ {\global\letcsname\??linenotespreviousfrom#1\endcsname\empty
+ \global\letcsname\??linenotespreviousto #1\endcsname\empty}
+
+\definesymbol
+ [\v!compressseparator]
+ [\hbox{\vl\thinspace\vl}] % \space removed
+
+\definesymbol
+ [\v!compressstopper]
+ [,]
+
+% \setupnotations
+% [%c\compress=\v!no,
+% \c!compressseparator=\symbol\v!compressseparator]
+
+\let\strc_linenotes_traced\gobbleoneargument
+
+\def\strc_linenotes_traced_indeed#1%
+ {\iftracelinenotes
+ \hpack to \zeropoint
+ {\forgetall
+ \hsize\zeropoint
+ \hss
+ \vpack to \strutheight{\llap{\red\infofont\setstrut\the\c_strc_linenotes}\vss}%
+ {\color[blue]{\vl}}%
+ \vpack to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}%
+ \hss}%
+ \prewordbreak
+ \fi}
+
+\permanent\protected\def\tracelinenotes
+ {\let\strc_linenotes_traced\strc_linenotes_traced_indeed}
+
+% We predefine one, namely \type {\linenote} cum suis.
+
+\definelinenote[\v!linenote]
+
+%D Use these when not properly nested:
+
+\aliased\let\fromlinenote\startlinenote
+\aliased\let\tolinenote \stoplinenote
+
+% beware: line numbers are added later on so grouping setups is a bad idea
+%
+% \startbuffer[test]
+% \startlinenumbering[100]
+% test \linenote {oeps 1} test test test test test test
+% test \startlinenote [well] {oeps X} test test test test test test
+% test \linenote {oeps 2} test test test test test test
+% test \linenote {oeps 3} test test test test test test
+% test \linenote {oeps 4} test test test test test test
+% test \linenote {oeps 5} test test test test test test
+% test \stoplinenote [well] test test test test test test
+% \stoplinenumbering
+% \stopbuffer
+%
+% \typebuffer[test] \getbuffer[test] \page
+%
+% \startbuffer[setup]
+% \setuplinenumbering
+% [align=flushleft]
+% \stopbuffer
+%
+% \typebuffer[setup] \getbuffer[setup,test] \page
+%
+% \startbuffer[setup]
+% \setuplinenumbering
+% [width=4em,
+% distance=1em,
+% align=flushright]
+% \stopbuffer
+%
+% \typebuffer[setup] \getbuffer[setup,test] \page
+%
+% \startbuffer[setup]
+% \setuplinenumbering
+% [width=4em,
+% align=flushleft]
+% \stopbuffer
+%
+% \typebuffer[setup] \getbuffer[setup,test] \page
+%
+% \startbuffer[setup]
+% \setuplinenumbering
+% [width=2em,
+% distance=.5em,
+% align=middle]
+% \stopbuffer
+%
+% \typebuffer[setup] \getbuffer[setup,test] \page
+%
+% \startbuffer[setup]
+% \setuplinenumbering
+% [conversion=romannumerals,
+% start=1,
+% step=1,
+% location=text,
+% style=slanted,
+% color=blue,
+% width=1.5em]
+% \stopbuffer
+%
+% \typebuffer[setup] \getbuffer[setup] \startnarrower\getbuffer[test]\stopnarrower \page
+%
+% \startbuffer[setup]
+% \setuplinenumbering
+% [width=4em,
+% left=--,
+% right=--,
+% align=middle]
+% \stopbuffer
+%
+% \typebuffer[setup] \getbuffer[setup,test] \page
+%
+% \startbuffer[setup-1]
+% \setuplinenumbering
+% [style=\bfxx,
+% command=\WatchThis]
+% \stopbuffer
+%
+% \startbuffer[setup-2]
+% \def\WatchThis#1%
+% {\ifodd\linenumber
+% \definecolor[linecolor][red]%
+% \else
+% \definecolor[linecolor][green]%
+% \fi
+% \inframed
+% [offset=1pt,frame=off,background=color,backgroundcolor=linecolor]
+% {#1}}
+% \stopbuffer
+%
+% \typebuffer[setup-1,setup-2] \getbuffer[setup-1,setup-2,test] \page
+%
+% \startbuffer[setup-1]
+% \setuplinenumbering
+% [location=inright,
+% style=\bfxx,
+% command=\WatchThis]
+% \stopbuffer
+%
+% \typebuffer[setup-1] \getbuffer[setup-1,setup-2,test] \page
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/strc-lst.mklx b/tex/context/base/mkiv/strc-lst.mklx
new file mode 100644
index 000000000..2e088766a
--- /dev/null
+++ b/tex/context/base/mkiv/strc-lst.mklx
@@ -0,0 +1,1566 @@
+%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 \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Lists}
+
+\registerctxluafile{strc-lst}{}
+
+% clean up in progress ...
+%
+% also (long term) todo:
+%
+% autocrossdocument
+% auto refs to lists (chain)
+%
+% TODO: strut=yes|no
+%
+% \lists -> strc_lists
+
+\unprotect
+
+%D Lists are mostly used for tables of contents but are in fact a rather generic
+%D feature of \CONTEXT. We seperate between storage and rendering and the current
+%D implementation is a reworked version of all that was added in steps. As lists
+%D are used frequently compatibility is an important aspect. A couple of rendering
+%D alternatives are provided here but more are possible.
+
+\installcorenamespace{list}
+
+\installframedcommandhandler \??list {list} \??list
+
+\aliased\let\setuplists\setuplist % yes or no
+
+\setuplist
+ [\c!height=\v!broad,
+ \c!depth=\v!broad,
+ \c!offset=.25\emwidth,
+ \c!state=\v!start,
+ \c!coupling=\v!off,
+ \c!criterium=\v!local,
+ \c!reference=,% was number which was sort of obsolete
+ \c!width=3\emwidth,
+ %\c!maxwidth=,
+ \c!distance=\zeropoint,
+ \c!margin=\zeropoint,
+ \c!alternative=\c!b,
+ \c!style=\v!normal,
+ %\c!color=,
+ \c!textstyle=\listparameter\c!style, % \currentliststyleparameter (but then we need to set it in every ...)
+ \c!numberstyle=\listparameter\c!style, % \currentliststyleparameter
+ \c!pagestyle=\listparameter\c!style, % \currentliststyleparameter
+ \c!textcolor=\listparameter\c!color, % \currentlistcolorparameter (but then we need to set it in every ...)
+ \c!numbercolor=\listparameter\c!color, % \currentlistcolorparameter
+ \c!pagecolor=\listparameter\c!color, % \currentlistcolorparameter
+ \c!numbercommand=\firstofoneargument,
+ \c!textcommand=\firstofoneargument,
+ \c!pagecommand=\firstofoneargument,
+ \c!pagenumber=\v!yes, % better: 'first'
+ \c!headnumber=\v!yes, % better: 'second'
+% \c!sectionnumber=\listparameter\c!headnumber, % use this instead
+ \c!interaction=\v!all, % was \v!sectionnumber, % or make this headnumber (or accept both)
+ \c!label=\v!no,
+ %\c!extras=,
+ %\c!aligntitle=,
+ %\c!before=,
+ %\c!after=,
+ %\c!inbetween=,
+ %\c!symbol=,
+ %\c!expansion=,
+ \c!limittext=\languageparameter\c!limittext] % not used currently
+
+%D Helpers:
+
+\permanent\protected\def\usenestedliststyleandcolor#style#color% will change
+ {\useliststyleandcolor#style#color%
+ % how about style
+ \ifempty\currentcolorparameter \else
+ \resetinteractionparameter\c!color
+ \resetinteractionparameter\c!contrastcolor
+ \fi}
+
+\permanent\protected\def\doifelselist#tag% can also move to \installcommandhandler
+ {\ifcsname\namedlisthash{#tag}\s!parent\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\aliased\let\doiflistelse\doifelselist
+
+%D Regular list entries are bound to a specific location in order to get the right
+%D pagenumber etc.\ associated. When pushing something inbetween (in mkiv) it ends
+%D up directtly in the list. This is the default because otherwise users will wonder
+%D why spacing might get messed up (due to an unseen but present node). It is
+%D possible to force a location by explicitly setting \type {location} to \type
+%D {here}.
+%D
+%D Another way to force a certain order is to set the \type {order} variable when
+%D placing a list. The \type {command} option only pushes commands into the right
+%D order, and \type {all} orders all entries (which might be too much). In this case
+%D no specific location is needed with the inbetween method. Maybe additional
+%D mechanisms show up some day. See \type {inbetween-001.tex} for an example.
+
+% command : location=none
+% userdata : location=none
+% simple : location=here
+
+\installcorenamespace {listlocations}
+
+% \permanent\protected\def\doifelseinlistentry#1%
+% {\ifcsname\??listlocations#1\endcsname
+% \ifnum\lastnamedcs=\structurelistlocation\relax
+% \doubleexpandafter\firstoftwoarguments
+% \else
+% \doubleexpandafter\secondoftwoarguments
+% \fi
+% \else
+% \expandafter\secondoftwoarguments
+% \fi}
+
+\permanent\protected\def\doifelseinlistentry#1%
+ {\unless\ifcsname\??listlocations#1\endcsname
+ \expandafter\secondoftwoarguments
+ \orelse\ifnum\lastnamedcs=\structurelistlocation\relax
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\permanent\protected\def\doifelseincurrentlistentry
+ {\doifelseinlistentry\currentlist}
+
+\permanent\protected\def\structurelistinject[#tag]%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \doifelse{\listparameter\c!state}\v!start\strc_lists_inject_yes\strc_lists_inject_nop}
+
+\tolerant\protected\def\strc_lists_inject_nop[#settings]#spacer[#userdata]%
+ {\endgroup}
+
+\def\strc_lists_inject_enhance#listindex%
+ {\expandafter\clf_deferredenhancelist\number#listindex\relax}
+
+\tolerant\protected\def\strc_lists_inject_yes[#settings]#spacer[#userdata]% can be used directly
+ {\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped (use \let...
+ \edef\p_location{\listparameter\c!location}%
+ \setnextinternalreference
+ \scratchcounter\clf_addtolist
+ references {
+ internal \locationcount
+ % block {\currentsectionblock}
+ % section structures.sections.currentid()
+ % location {\p_location}
+ }
+ metadata {
+ kind {\listparameter\c!type}
+ name {\currentlist}
+ % level structures.sections.currentlevel()
+ catcodes \catcodetable
+ }
+ userdata {\detokenize\expandafter{\normalexpanded{#userdata}}}
+ \relax
+ \edef\currentlistnumber{\the\scratchcounter}%
+ \setxvalue{\??listlocations\currentlist}{\the\locationcount}%
+ \ifx\p_location\v!here
+ % this branch injects nodes !
+ \strc_lists_inject_enhance{\currentlistnumber}%
+ \clf_setinternalreference
+ internal \locationcount
+ view {\interactionparameter\c!focus}%
+ \relax % this will change
+ \xdef\currentstructurelistattribute{\the\lastdestinationattribute}%
+ \dontleavehmode\hpack attr \destinationattribute \lastdestinationattribute{}% todo
+ \else
+ % and this one doesn't
+ \clf_enhancelist\currentlistnumber\relax
+ \fi
+ \endgroup}
+
+% todo: make like \strc_references_direct_full_user ... with {}{}{}
+
+\protected\def\strc_lists_inject_direct[#tag]% [#settings][#userdata]
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \strc_lists_inject_yes} % [#settings][#userdata]
+
+\permanent\protected\def\writebetweenlist[#tag]%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \doifelse{\namedlistparameter{#tag}\c!state}\v!start
+ \strc_lists_write_between_yes
+ \strc_lists_write_between_nop}
+
+\tolerant\def\strc_lists_write_between_yes[#settings]#:#command%
+ {\strc_lists_inject_yes[#settings,\c!type=\s!command][command={#command}]}
+
+\tolerant\def\strc_lists_write_between_nop[#settings]#:#command%
+ {\endgroup}
+
+\permanent\protected\def\writedatatolist[#tag]%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \doifelse{\namedlistparameter{#tag}\c!state}\v!start
+ \strc_lists_write_data_to_yes
+ \strc_lists_write_data_to_nop}
+
+\tolerant\def\strc_lists_write_data_to_yes[#settings]#spacer[#userdata]%
+ {\ifthirdargument % no need to have an extra step ... used seldom
+ \strc_lists_inject_yes[#settings,\c!type=\s!userdata][#userdata]%
+ \else
+ \strc_lists_inject_yes[\c!type=\s!userdata][#settings]%
+ \fi}
+
+\tolerant\def\strc_lists_write_data_to_nop[#settings]#spacer[#userdata]%
+ {\endgroup}
+
+\permanent\protected\def\writetolist[#tag]%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \doifelse{\namedlistparameter{#tag}\c!state}\v!start
+ \strc_lists_write_to_yes
+ \strc_lists_write_to_nop}
+
+\tolerant\def\strc_lists_write_to_yes[#settings]#:#first#second% no \s!first because we don't expand user settings
+ {\strc_lists_inject_yes[\c!location=\v!here,#settings,\c!type=\s!simple][first={#first},second={#second}]}
+
+\tolerant\def\strc_lists_write_to_nop[#settings]#:#first#second%
+ {\endgroup} % \strc_lists_inject_nop[][]
+
+%D When placing a list either one or a set can be giving. This makes it possible to
+%D flush for instance an nested (or merged) table of contents. Keep in mind that
+%D placing a list is what we do most (think of tables of contents, figures, etc.\
+%D but other usage is also possible in which case low level commands have to be
+%D used.
+
+\newtoks\everystructurelist
+
+\permanent\tolerant\protected\def\placelist[#taglist]#spacer[#settings]%
+ {\begingroup
+ \startpacked[\v!blank]%
+ \edef\m_list {#taglist}%
+ \edef\m_first{\firststructureelementinlist{#taglist}}%
+ \ifx\m_list\m_first
+ % use settings of first
+ \else
+ % use settings of root
+ \let\m_first\empty
+ \fi
+ \strc_lists_place_indeed\m_first\m_list{#settings}%
+ \stoppacked
+ \endgroup}
+
+\permanent\tolerant\protected\def\placerawlist[#tag]#spacer[#settings]% just one list
+ {\strc_lists_place_indeed\empty{#tag}{#settings}}
+
+\aliased\let\strc_lists_place\placelist % used in strc-flt
+
+\def\strc_lists_place_indeed#tag#list#settings%
+ {\begingroup
+ \the\t_lists_every_renderingcleanup % \let\currentlistentrylocation\empty
+ \edef\currentlist{#tag}%
+ \setupcurrentlist[#settings]%
+ \the\everystructurelist
+ % \doif{\listparameter\c!coupling}\v!on{\startlistreferences{#tag}}%
+ \strc_lists_place_current % maybe inline
+ {#list}%
+ {\listparameter\c!criterium}%
+ {\listparameter\c!reference}%
+ {\listparameter\c!extras}%
+ {\listparameter\c!order}%
+ % \stoplistreferences
+ \par % todo: only when vertical list mode
+ \endgroup
+ \strc_lists_set_mode}
+
+\def\strc_lists_set_mode
+ {\ifcase\structurelistsize\relax
+ \resetsystemmode\v!list
+ \else
+ \setsystemmode \v!list
+ \fi}
+
+%D Complete lists are just lists but with a title. They were originally introduced
+%D to minimize the number for commands in a document source but nowadays that is
+%D less an issue in the sense that the extra few lines are neglectable to the rest.
+
+\ifdefined\startnamedsection \else \let\startnamedsection\relax \fi
+\ifdefined\stopnamedsection \else \let\stopnamedsection \relax \fi
+\ifdefined\headtext \else \let\headtext \relax \fi
+
+\permanent\tolerant\protected\def\completelist[#tag]#spacer[#settings]%
+ {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#tag},\c!reference=#tag]}% {} around ref ?
+ \strc_lists_place[#tag][#settings]%
+ \stopnamedsection}
+
+\permanent\tolerant\protected\def\strc_lists_complete[#singular]#spacer[#plural]#spacer[#settings]% used in strc-flt
+ {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#plural},\c!reference=#singular]}% {} around ref ?
+ \strc_lists_place[#singular][#settings]%
+ \stopnamedsection}
+
+%D Combined list provide a nice level of abstraction.
+%D
+%D \starttyping
+%D \definecombinedlist[whatever][a,b,c][settings]
+%D \stoptyping
+
+\permanent\tolerant\protected\def\definecombinedlist[#tag]#spacer[#list]#spacer[#settings]%
+ {\definelist[#tag][\c!criterium=\v!local,\c!reference=,\c!alternative=,\c!list={#list},#settings]% inherits from root
+ \frozen\instance\setvalue{\e!setup#tag\e!endsetup}{\setupcombinedlist[#tag]}%
+ \frozen\instance\setvalue{\e!place#tag}{\placecombinedlist[#tag]}%
+ \frozen\instance\setvalue{\e!complete#tag}{\strc_lists_complete[#tag]}}
+
+\permanent\tolerant\protected\def\setupcombinedlist[#tag]#spacer[#settings]%
+ {\ifarguments\or\or
+ \setuplist[#tag][#settings]% we don't want to mess up the parent
+ \fi}
+
+\permanent\tolerant\protected\def\placecombinedlist[#tag]#spacer[#settings]% i.e. no list set in settings
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \setupcurrentlist[#settings]%
+ \edef\m_strc_list_alternative{\listparameter\c!alternative}% we only inherit alternative
+ \strc_lists_place_indeed{#tag}{\listparameter\c!list}{#settings}%
+ \endgroup}
+
+%D Given that some variables are set, we can ask for some properties of
+%D an entry.
+
+\mutable\def\currentstructurelistnumber{0} % injection
+\mutable\def\currentlistmethod {entry} % typesetting
+\mutable\def\currentlistindex {0} % typesetting (maybe also a real counter)
+
+\permanent\protected\def\savedlistnumber #1#2{\clf_savedlistnumber {#1}\numexpr#2\relax}
+\permanent\protected\def\savedlisttitle #1#2{\clf_savedlisttitle {#1}\numexpr#2\relax}
+\permanent\protected\def\savedlistprefixednumber#1#2{\clf_savedlistprefixednumber{#1}\numexpr#2\relax}
+
+\newconditional\c_lists_show_realpage
+
+\installcorenamespace {listpagenumber}
+
+\setvalue{\??listpagenumber\v!always }{\settrue\c_lists_show_page\settrue\c_lists_has_page}
+\setvalue{\??listpagenumber\v!yes }{\settrue\c_lists_show_page}
+\setvalue{\??listpagenumber\s!realpage}{\settrue\c_lists_show_page\settrue\c_lists_show_realpage}
+
+\def\strc_lists_process_pagenumber#1%
+ {\begincsname\??listpagenumber#1\endcsname}
+
+\def\structurelistlocation
+ {\clf_listlocation\numexpr\currentlistindex\relax}
+
+\def\structurelistrealpagenumber
+ {\clf_listrealpage{\currentlist}\numexpr\currentlistindex\relax}
+
+\protected\def\structurelistpagenumber
+ {\dostarttagged\t!listpage\empty
+ \ifconditional\c_lists_show_realpage
+ \clf_listrealpage{\currentlist}\numexpr\currentlistindex\relax
+ \else
+ \clf_listprefixedpage
+ {\currentlist}%
+ \currentlistindex
+ {
+ separatorset {\listparameter\c!pageprefixseparatorset}
+ conversionset {\listparameter\c!pageprefixconversionset}
+ set {\listparameter\c!pageprefixset}
+ segments {\listparameter\c!pageprefixsegments}
+ connector {\listparameter\c!pageprefixconnector}
+ }%
+ {
+ prefix {\listparameter\c!pageprefix}
+ conversionset {\listparameter\c!pageconversionset}
+ starter {\listparameter\c!pagestarter}
+ stopper {\listparameter\c!pagestopper}
+ }%
+ \relax
+ \fi
+ \dostoptagged}
+
+\permanent\protected\def\structurelistuservariable#name%
+ {\dostarttagged\t!listdata{#name}%
+ \clf_listuserdata{\currentlist}\currentlistindex{#name}%
+ \dostoptagged}
+
+\permanent\def\rawstructurelistuservariable#name%
+ {\clf_listuserdata{\currentlist}\currentlistindex{#name}}
+
+\permanent\protected\def\structurelistfirst {\structurelistuservariable\s!first } % s!
+\permanent\protected\def\structurelistsecond{\structurelistuservariable\s!second} % s!
+
+\permanent\def\rawstructurelistfirst {\rawstructurelistuservariable\s!first } % s! % was \protected
+\permanent\def\rawstructurelistsecond{\rawstructurelistuservariable\s!second} % s! % was \protected
+
+\permanent\protected\def\doifelsestructurelisthaspage
+ {\clf_doifelselisthaspage{\currentlist}\numexpr\currentlistindex\relax}
+
+\permanent\protected\def\doifelsestructurelisthasnumber
+ {\clf_doifelselisthasnumber{\currentlist}\numexpr\currentlistindex\relax}
+
+\aliased\let\doifstructurelisthaspageelse \doifelsestructurelisthaspage
+\aliased\let\doifstructurelisthasnumberelse\doifelsestructurelisthasnumber
+
+\permanent\protected\def\structurelistgenerictitle
+ {\dostarttagged\t!listcontent\empty
+ \clf_listtitle{\currentlist}\currentlistindex\relax
+ \dostoptagged}
+
+\permanent\protected\def\structurelistgenericnumber % tricky, we need to delay tagging as we have nested lua calls
+ {\dostarttagged\t!listtag\empty
+ \clf_listprefixednumber
+ {\currentlist}%
+ \currentlistindex
+ {%
+ prefix {\listparameter\c!prefix}%
+ separatorset {\listparameter\c!prefixseparatorset}%
+ conversionset {\listparameter\c!prefixconversionset}%
+ starter {\listparameter\c!prefixstarter}%
+ stopper {\listparameter\c!prefixstopper}%
+ set {\listparameter\c!prefixset}%
+ segments {\listparameter\c!prefixsegments}%
+ connector {\listparameter\c!prefixconnector}%
+ }%
+ {%
+ separatorset {\listparameter\c!numberseparatorset}%
+ conversionset {\listparameter\c!numberconversionset}%
+ starter {\listparameter\c!numberstarter}%
+ stopper {\listparameter\c!numberstopper}%
+ segments {\listparameter\c!numbersegments}%
+ }%
+ \relax
+ \dostoptagged}
+
+% TODO: pass extra tag name (contents, figures, bibliography ...)
+
+\protected\def\strc_lists_place_current#list#criterium#reference#extras#order% beware, not a user command
+ {\dostarttaggedchained\t!list\empty\??list
+ \clf_processlist
+ names {#list}
+ criterium {#criterium}
+ reference {#reference}
+ extras {#extras}
+ order {#order}
+ \relax
+ \dostoptagged}
+
+\protected\def\strc_lists_analyze#list#criterium#reference%
+ {\clf_analyzelist
+ names {#list}
+ criterium {#criterium}
+ reference {#reference}
+ \relax}
+
+\permanent\def\firststructureelementinlist#list% expandable
+ {\firstinset{#list}}
+
+\permanent\def\structurelistsize
+ {\clf_listsize}
+
+%D Depending on what kind of list we have (e.g.\ a section related one) processors
+%D can be defined.
+
+% push pop test:
+%
+% \starttext
+% \placelist[chapter] [after={\placelist[section][criterium=local]}]
+% \chapter{One} \section{Alpha} \section{Beta}
+% \chapter{Two} \section{First} \section{Second}
+% \stoptext
+
+\installcorenamespace{structurelistprocessor} % the topmost list handler
+\installcorenamespace{listextra} % control of that handler
+
+\installcommandhandler \??listextra {listextra} \??listextra
+
+\definelistextra % example
+ [\v!page]
+ [\c!before={\showmessage\m!system{14}{\currentlist/\currentlistindex}\page}]
+
+\permanent\protected\def\installstructurelistprocessor#tag#meaning%
+ {\expandafter\normaldef\csname\??structurelistprocessor#tag\endcsname{#meaning}}
+
+\permanent\def\usestructurelistprocessor#tag%
+ {\csname\??structurelistprocessor#tag\endcsname}
+
+\let\dotaglistlocation\relax
+
+\def\strc_lists_entry_process_default
+ {no list method}
+
+\def\strc_lists_entry_process % assume things to be set up
+ {\listextraparameter\c!before
+ \dostarttagged\t!listitem\currentlist
+ \dotaglistlocation
+ \ifcsname\??structurelistprocessor\currentlist:\currentlistmethod\endcsname\lastnamedcs\orelse
+ \ifcsname\??structurelistprocessor\currentlistmethod \endcsname\lastnamedcs\orelse
+ \ifcsname\??structurelistprocessor\currentlist \endcsname\lastnamedcs\else
+ \strc_lists_entry_process_default\fi
+ \dostoptagged
+ \listextraparameter\c!after}
+
+\protected\def\strclistsentryprocess#tag#method#index#extra% This one is called at the lua end!
+ {\clf_pushlist#index\relax
+ %\let\currentlistentrylocation\empty
+ \edef\currentlist {#tag}%
+ \edef\currentlistmethod{#method}%
+ \edef\currentlistindex {#index}%
+ \edef\currentlistextra {#extra}%
+ \strc_lists_entry_process
+ \clf_poplist}
+
+% lists that have a number/title are kind of generic and can share code
+
+\installstructurelistprocessor\s!default
+ {\strc_lists_entry_process_default}
+
+\installstructurelistprocessor\s!simple
+ {\let\currentlistentrynumber \structurelistfirst
+ \let\currentlistentrytitle \structurelistsecond
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+\installstructurelistprocessor\s!command
+ {\clf_listuserdata{\currentlist}\currentlistindex{\s!command}}
+
+\installstructurelistprocessor{section}
+ {\let\currentlistentrynumber \structurelistgenericnumber
+ \let\currentlistentrytitle \structurelistgenerictitle
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+\installstructurelistprocessor{number+title}
+ {\let\currentlistentrynumber \structurelistgenericnumber
+ \let\currentlistentrytitle \structurelistgenerictitle
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+% example of usage elsewhere:
+%
+% \installstructcurelistprocessor{pubs:userdata}
+% {\clf_listuserdata{\currentlist}\currentlistindex{bibref}}
+
+%D List symbols are used in interactive documents where no numbers are used but
+%D nevertheless structure is present. Beware, the list symbol macro gets an argument
+%D passed, i.e. when this argument is not picked up, the symbol becomes a kind of
+%D prefix. It's not really a user command (and might even get protected).
+
+\permanent\protected\def\listsymbol[#tag]#number%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \def\currentlistentrynumber{#number}% no edef else tag problems
+ \currentlistsymbol
+ \endgroup}
+
+%D For historical reasons we're stuck to symbols, so in order to generalize, we have
+%D to hook it into the symbol handle. One way to deal with this is to use a
+%D different key and as it makes sense to use setups instead of def's we use a new
+%D key \quote {renderingsetup} which is the name of a setup.
+
+\def\strc_lists_assign_dimen#dimension#key#default%
+ {\edef\m_strc_list_dimen{\listparameter#key}%
+ \doifelseinset\m_strc_list_dimen{\v!fit,\v!broad}{#dimension#default}{#dimension\m_strc_list_dimen}\relax}
+
+\definesymbol[\v!list][\v!none ][\strc_lists_symbol_none]
+\definesymbol[\v!list][\v!one ][\strc_lists_symbol_one]
+\definesymbol[\v!list][\v!two ][\strc_lists_symbol_two]
+\definesymbol[\v!list][\v!three ][\strc_lists_symbol_three]
+\definesymbol[\v!list][\s!default][\strc_lists_symbol_default]
+\definesymbol[\v!list][\s!unknown][\strc_lists_symbol_unknown]
+
+\permanent\protected\def\currentlistsymbol
+ {\edef\p_symbol{\listparameter\c!symbol}%
+ \doifelseinsymbolset\v!list\p_symbol
+ {\directsymbol\v!list\p_symbol}
+ {\directsymbol\v!list\s!default}}
+
+\protected\def\strc_lists_symbol_none
+ {\strc_lists_assign_dimen\scratchwidth\c!width{1.5\emwidth}%
+ \hpack to \scratchwidth{}}
+
+\protected\def\strc_lists_symbol_one
+ {\strut\symbol[bullet]}
+
+\protected\def\strc_lists_symbol_two
+ {\vrule\s!width\emwidth\s!height\exheight\s!depth\zeropoint\relax}
+
+\protected\def\strc_lists_symbol_three
+ {\begingroup
+ \strc_lists_assign_dimen\scratchwidth \c!width {1.5\emwidth}%
+ \strc_lists_assign_dimen\scratchheight\c!height\exheight
+ \strc_lists_assign_dimen\scratchdepth \c!depth \zeropoint
+ \vrule\s!width\scratchwidth\s!height\scratchheight\s!depth\scratchdepth
+ \endgroup}
+
+\protected\def\strc_lists_symbol_unknown
+ {\listparameter\c!symbol}
+
+\installcorenamespace{listsymbollabels}
+
+\def\strc_lists_symbol_label_unknown
+ {\leftlabeltext\currentlistlabel
+ \listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper
+ \rightlabeltext\currentlistlabel}
+
+\protected\def\strc_lists_symbol_default
+ {\dontleavehmode
+ \strut
+ \begingroup
+ \edef\currentlistlabel{\listparameter\c!label}% can be used in label
+ \ifcsname\??listsymbollabels\currentlistlabel\endcsname
+ \lastnamedcs
+ \else
+ \strc_lists_symbol_label_unknown
+ \fi
+ \endgroup}
+
+\letvalue{\??listsymbollabels\s!unknown}\strc_lists_symbol_default
+
+\setvalue{\??listsymbollabels}% default (empty)
+ {\listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper}
+
+\setvalue{\??listsymbollabels\v!no}% also default
+ {\listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper}
+
+\setvalue{\??listsymbollabels\v!none}% real minimal (as suggested by WS)
+ {\currentlistentrynumber}
+
+\setvalue{\??listsymbollabels\v!yes}% auto (use value stored in tuc file)
+ {\edef\currentlistlabel{\clf_listlabel\currentlistindex{\currentlistlabel}}%
+ \leftlabeltext\currentlistlabel
+ \listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper
+ \rightlabeltext\currentlistlabel}
+
+% a : nr - tit - pag
+% b : nr - tit - fill - pag
+% c : nr - tit - dots - pag
+% d : inline
+% e : interaction
+% f : interaction
+% g : interaction
+
+\installcorenamespace{listalternative} % specific ways of rendering a list
+\installcorenamespace{listrenderings} % a namespace for setups (rather local)
+
+\installcommandhandler \??listalternative {listalternative} \??listalternative
+
+% Commands are bound to specific list instances as often these are quite special
+% and don't apply to multiple. So, being strict saves us resets.
+
+% \installcorenamespace{listfiller}
+%
+% \protected\def\installlistfiller#1#2%
+% {\setuvalue{\??listfiller#1}{#2}}
+%
+% \protected\def\listfiller#1%
+% {\begincsname\??listfiller#1\endcsname}
+%
+% \protected\def\currentlistfiller
+% {\begingroup
+% \edef\p_filler{\listalternativeparameter\c!filler}%
+% \ifcsname\??listfiller\p_filler\endcsname
+% \lastnamedcs
+% \else
+% \p_filler
+% \fi
+% \endgroup}
+%
+% \installlistfiller\v!sym % original one
+% {\begingroup
+% \scratchdimen.5\emwidth
+% \hskip\scratchdimen
+% \gleaders
+% \hbox to \scratchdimen
+% {\hss
+% \uselistalternativestyleandcolor\c!symstyle\c!symcolor
+% \listalternativeparameter\c!symbol
+% \hss}%
+% \hfill
+% \hskip\scratchdimen
+% \endgroup}
+%
+% \installlistfiller\v!symbol % new one (make that default?)
+% {\begingroup
+% \scratchdimen.5\emwidth
+% \hskip\scratchdimen
+% \gleaders
+% \hbox spread .5\scratchdimen
+% {\hss
+% \uselistalternativestyleandcolor\c!symstyle\c!symcolor
+% \listalternativeparameter\c!symbol
+% \hss}%
+% \hfill
+% \hskip\scratchdimen
+% \endgroup}
+%
+% \installlistfiller\v!width
+% {\hfill}
+%
+% \installlistfiller\v!space
+% {\hskip.25\emwidth\relax}
+
+\setuplistalternative
+ [\c!command=\directlistparameter\c!command,
+ \c!symbol=.]
+
+\permanent\protected\def\currentlistfiller
+ {\checkedfiller{\listalternativeparameter\c!filler}}
+
+\definelistalternative
+ [a]
+ [\c!distance=0pt,
+ \c!width=2em,
+ \c!stretch=10em,
+ \c!filler=\hskip.25em\relax,
+ \c!renderingsetup=\??listrenderings:abc]
+
+\definelistalternative
+ [b]
+ [\c!distance=5em,
+ \c!width=2em,
+ \c!stretch=10em,
+ \c!filler=\hfill,
+ \c!renderingsetup=\??listrenderings:abc]
+
+\definelistalternative
+ [c]
+ [\c!distance=5em,
+ \c!width=0pt,
+ \c!stretch=10em,
+ \c!filler=\hskip.5em\gleaders\hbox to .5\emwidth{\hss.\hss}\hfill\hskip.5em\relax,
+ \c!renderingsetup=\??listrenderings:abc]
+
+\definelistalternative
+ [d]
+ [\c!renderingsetup=\??listrenderings:d]
+
+\definelistalternative
+ [e]
+ [\c!renderingsetup=\??listrenderings:e]
+
+\definelistalternative
+ [f]
+ [\c!renderingsetup=\??listrenderings:f]
+
+\definelistalternative
+ [g]
+ [\c!renderingsetup=\??listrenderings:g]
+
+\definelistalternative
+ [\v!command]
+ [\c!renderingsetup=\??listrenderings:command]
+
+\definelistalternative
+ [\v!none]
+ [\c!renderingsetup=\??listrenderings:none]
+
+\definelistalternative
+ [\v!vertical]
+ [\c!before=\ifvmode\nointerlineskip\fi,
+ \c!after=\ifvmode\nointerlineskip\fi\endgraf\allowbreak,
+ \c!renderingsetup=\??listrenderings:generic]
+
+\definelistalternative
+ [\v!horizontal]
+ [\c!before=\noindent,
+ \c!after=,
+ \c!renderingsetup=\??listrenderings:generic]
+
+% \setuplist
+% [section]
+% [alternative=MyListItem,
+% after=\blank,
+% before=\blank]
+%
+% \definelistplacement[MyListItem][command]#1#2#3{(#1) (#2) (#3)}
+% \definelistplacement[MyListItem][command]{\whatever}
+%
+% this is a compatibility command, best use the regular defined with command=
+% either set in the alternative or in the list
+
+\installcorenamespace{listelementcommand} % the old plugin model
+
+\permanent\tolerant\protected\def\definelistplacement[#tag]#spacer[#method]%
+ {\edef\p_method{#method}%
+ \ifempty\p_method
+ \let\p_method\v!command
+ \fi
+ \normalexpanded{\definelistalternative[#tag][\p_method]}[\c!command=\strc_lists_placement_command]%
+ \doifelsenextbgroup
+ {\strc_lists_define_placement_yes{#tag}}
+ {\strc_lists_define_placement_nop{#tag}}}
+
+% indirect definition: <three ignore arguments>: {\bla}
+
+\def\strc_lists_define_placement_yes#tag%
+ {\protected\defcsname\??listelementcommand#tag\endcsname##1##2##3}
+
+% direct definition: <three arguments>{\bla}
+
+\def\strc_lists_define_placement_nop#tag%
+ {\protected\defcsname\??listelementcommand#tag\endcsname}
+
+\def\strc_lists_placement_command
+ {\csname\??listelementcommand\currentlistalternative\endcsname}
+
+%D The rendering macros.
+
+\newbox \b_strc_lists_number
+\newbox \b_strc_lists_text
+\newbox \b_strc_lists_page
+
+\newtoks \t_lists_every_renderingsetup
+\newtoks \t_lists_every_renderingtext
+\newtoks \t_lists_every_renderingsynchronize
+\newtoks \t_lists_every_renderingcleanup
+
+\newconditional\c_lists_has_number
+\newconditional\c_lists_has_page
+\newconditional\c_lists_show_number
+\newconditional\c_lists_show_page
+
+\mutable\let\currentlistentrylocation \empty % watch the 'entry' in the name
+\mutable\let\currentlistentrynumber \empty % watch the 'entry' in the name
+\mutable\let\currentlistentrytitle \empty % watch the 'entry' in the name
+\mutable\let\currentlistentrypagenumber\empty % watch the 'entry' in the name
+
+\appendtoks
+ \dontcomplain
+ % \letinteractionparameter\c!width\zeropoint % a weird one
+\to \t_lists_every_renderingsetup
+
+\appendtoks
+ % better is to use a special list entry but we keep this for compatibility
+ \enforced\let\\\space
+ % so expanding this token register has to come *after* the font switch
+ \dontconvertfont % (**) this has to become an option (see publ)
+\to \t_lists_every_renderingtext
+
+\appendtoks
+ % because we want to avoid redundant lua calls we expand the
+ % location beforehand
+ \ifempty\currentlistentrylocation
+ \edef\currentlistentrylocation{\structurelistlocation}% needs attention
+ \fi
+ % because these tests happen often and because we're dealing with
+ % rather complex composed data we have special conditionals; keep
+ % in mind that testing for empty fails do to tagging being applied
+% \edef\p_pagenumber{\listparameter\c!pagenumber}%
+% \ifx\p_pagenumber\v!always
+% \settrue\c_lists_has_page
+% \settrue\c_lists_show_page
+% \else
+% \doifelsestructurelisthaspage\settrue\setfalse\c_lists_has_page
+% \ifx\p_pagenumber\v!yes
+% \settrue\c_lists_show_page
+% \else
+% \setfalse\c_lists_show_page
+% \fi
+% \fi
+ \setfalse\c_lists_show_page % necessary?
+ \processcommacommand[\listparameter\c!pagenumber]\strc_lists_process_pagenumber
+ \ifconditional\c_lists_has_page \else
+ \doifelsestructurelisthaspage\settrue\setfalse\c_lists_has_page
+ \fi
+ % always forces number placement (in bib we use a forced number)
+ \edef\p_headnumber{\listparameter\c!headnumber}%
+ \ifx\p_headnumber\v!always
+ \settrue\c_lists_has_number
+ \settrue\c_lists_show_number
+ \else
+ \doifelsestructurelisthasnumber\settrue\setfalse\c_lists_has_number
+ \ifx\p_headnumber\v!yes
+ \settrue\c_lists_show_number
+ \else
+ \setfalse\c_lists_show_number
+ \fi
+ \fi
+ \strc_lists_interaction_check
+\to \t_lists_every_renderingsetup
+
+\appendtoks
+ \strc_references_flush_destination_nodes
+\to \t_lists_every_renderingsynchronize
+
+\appendtoks
+ % as we don't want any interference we clear some variables
+ % afterwards
+ \let\currentlistentrylocation \empty
+ \let\currentlistentrynumber \empty
+ \let\currentlistentrytitle \empty
+ \let\currentlistentrypagenumber\empty
+ \setfalse\c_lists_has_page
+ \setfalse\c_lists_has_number
+ \setfalse\c_lists_show_page
+ \setfalse\c_lists_show_realpage
+ \setfalse\c_lists_show_number
+\to \t_lists_every_renderingcleanup
+
+\let\m_strc_list_alternative\empty % combined
+
+\protected\def\strc_lists_apply_renderingsetup
+ {\the\t_lists_every_renderingsetup
+ % now we group
+ \begingroup
+ \ifempty\m_strc_list_alternative
+ \edef\currentlistalternative{\listparameter\c!alternative}%
+ \else
+ \let\currentlistalternative\m_strc_list_alternative
+ \fi
+ \directsetup{\listalternativeparameter\c!renderingsetup}\relax
+ \endgroup
+ % till here, where we reset locals
+ \the\t_lists_every_renderingcleanup}
+
+% todo: provide packager via attributes
+
+\doinstallinjector\s!list
+
+\installcorenamespace{listalternativemethods} % the general wrapper of a rendering
+
+\startsetups[\??listrenderings:none]
+ % nothing, nb we use the [] syntax here because we end with a \cs
+\stopsetups
+
+\permanent\protected\def\currentlistentrytitlesynchronize
+ {\the\t_lists_every_renderingsynchronize}
+
+\permanent\protected\def\currentlistentrytitlerendered
+ {\currentlistentrytitlesynchronize\currentlistentrytitle}
+
+\startsetups[\??listrenderings:command]
+ \edef\p_command{\listalternativeparameter\c!command}%
+ \ifempty\p_command
+ [\currentlist: \currentlistentrynumber\space -- \currentlistentrytitle\space -- \currentlistentrypagenumber]%
+ \else
+ \p_command
+ \currentlistentrynumber
+ \currentlistentrytitlerendered % {\currentlistentrytitlesynchronize\currentlistentrytitle}
+ \currentlistentrypagenumber
+ \fi
+\stopsetups
+
+% \startsetups[\??listrenderings:\v!vertical]
+% \directsetup{\??listrenderings:generic}
+% \stopsetups
+
+% \startsetups[\??listrenderings:\v!horizontal]
+% \directsetup{\??listrenderings:generic}
+% \stopsetups
+
+\startsetups[\??listrenderings:generic]
+ \typo_injectors_check_list
+ \listparameter\c!before % can be \hskip
+ \edef\p_command{\listalternativeparameter\c!command}
+ \ifempty\p_command
+ \listalternativeparameter\c!before
+ \vbox {
+ \forgetall
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all {
+ \ifconditional\c_lists_show_number
+ % \ifconditional\c_lists_has_page
+ \hbox \strc_lists_get_reference_attribute\v!number {
+ \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
+ \listparameter\c!numbercommand\currentlistsymbol
+ }
+ % \fi
+ \fi
+ \hbox \strc_lists_get_reference_attribute\v!text {
+ \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
+ \the\t_lists_every_renderingtext
+ \the\t_lists_every_renderingsynchronize
+ \listparameter\c!textcommand\currentlistentrytitle
+ }
+ \ifconditional\c_lists_show_page
+ \ifconditional\c_lists_has_page
+ \hbox \strc_lists_get_reference_attribute\v!pagenumber {
+ \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
+ \listparameter\c!pagecommand\currentlistentrypagenumber
+ }
+ \fi
+ \fi
+ }
+ }
+ \listalternativeparameter\c!after
+ \else
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \p_command\currentlistentrynumber\currentlistentrytitle\currentlistentrypagenumber
+ }
+ \fi
+ \listparameter\c!after
+\stopsetups
+
+% to be documented: align, hang
+
+\startsetups[\??listrenderings:abc]
+ \endgraf % are we grouped?
+ \typo_injectors_check_list
+ % \advance % yes or no ... \rightskip is also honored
+ \leftskip\listparameter\c!margin % after \endgraf !
+ \listparameter\c!before
+ \endgraf
+ \edef\p_width{\listparameter\c!width}
+ \scratchdistance\listparameter\c!distance\relax
+ \ifx\p_width\v!fit
+ \scratchwidth\zeropoint
+ \orelse\ifconditional\c_lists_has_number
+ \scratchwidth\p_width
+ \else
+ \edef\p_aligntitle{\listparameter\c!aligntitle}
+ \ifx\p_aligntitle\v!yes
+ \scratchwidth\zeropoint
+ \scratchdistance\zeropoint
+ \else
+ \scratchwidth\p_width
+ \fi
+ \fi
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \setlocalhsize
+ \hsize\localhsize
+ \hbox to \hsize {
+ \forgetall
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \scratchhsize\hsize
+ \ifconditional\c_lists_has_number
+ \ifconditional\c_lists_show_number
+ \setbox\b_strc_lists_number
+% \hbox
+% \strc_lists_get_reference_attribute\v!number
+% \ifdim\scratchwidth>\zeropoint to \scratchwidth \fi
+ \simplealignedboxplus
+ \scratchwidth
+ {\listparameter\c!numberalign}
+ {\strc_lists_get_reference_attribute\v!number}
+ {
+ \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
+ \listparameter\c!numbercommand\currentlistsymbol
+% \hfill
+ }
+ \else
+ \setbox\b_strc_lists_number\emptyhbox
+ \fi
+ \else
+ \scratchwidth\zeropoint
+ \scratchdistance\zeropoint
+ \setbox\b_strc_lists_number\emptyhbox
+ \fi
+ \ifconditional\c_lists_has_page
+ \ifconditional\c_lists_show_page
+ \setbox\b_strc_lists_page\hpack {
+ \scratchdimen\listalternativeparameter\c!width
+ \hbox \strc_lists_get_reference_attribute\v!pagenumber \ifdim\scratchdimen>\zeropoint to \scratchdimen\fi {
+ \hfill
+ \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
+ \strut
+ \listparameter\c!pagecommand\currentlistentrypagenumber
+ }
+ }
+ \else
+ \setbox\b_strc_lists_page\emptyhbox
+ \fi
+ \else
+ \setbox\b_strc_lists_page\emptyhbox
+ \fi
+ \vbox {
+ \hsize\scratchhsize
+ \usealignparameter\listparameter
+ \ifdim\scratchwidth<\hsize
+ % we have leftskip so we'd better just skip back instead of messing
+ % with hang*
+ \edef\p_hang{\listparameter\c!hang}
+ \hangindent\dimexpr\wd\b_strc_lists_number+\scratchdistance\relax
+ \hangafter\ifx\p_hang\v!no\zerocount\else\plusone\fi
+ \scratchdimen\listalternativeparameter\c!distance\relax
+ \ifzeropt\wd\b_strc_lists_page \else \ifdim\scratchdimen>\zeropoint\relax
+ \rightskip\scratchdimen\s!plus\listalternativeparameter\c!stretch\relax
+ \parfillskip-\rightskip
+ \fi \fi
+ \else
+ \scratchdistance\zeropoint
+ \fi
+ \parindent\zeropoint
+ \dontleavehmode % this nils hang: i need to figure out why
+ % % topaligned
+ %
+ % \scratchdimen\wd\b_strc_lists_number
+ % \setbox\b_strc_lists_number\hbox to \hsize{\box\b_strc_lists_number\hss\box\b_strc_lists_page}%
+ % \wd\b_strc_lists_number\scratchdimen
+ %
+ \box\b_strc_lists_number
+ \hskip\scratchdistance\relax
+ \begingroup
+ \strc_lists_set_reference_attribute\v!text
+ \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
+ \the\t_lists_every_renderingtext
+ \the\t_lists_every_renderingsynchronize
+ \setstrut % needs checking, new here
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ \endgroup
+ \ifzeropt\wd\b_strc_lists_page\else
+ \nobreak
+ \currentlistfiller
+ \box\b_strc_lists_page
+ \fi
+ }
+ \hss
+ }
+ }% new
+ \endgraf % new, else problems with nointerlinespace and prevdepth
+ \nointerlineskip % anders verkeerde spatiering bij multi-line
+ \endgraf
+ \allowbreak
+ \listparameter\c!after
+\stopsetups
+
+% % 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
+
+\startsetups[\??listrenderings:d]
+ \ifvmode
+ \advance\leftskip\listparameter\c!margin
+ \fi
+ \begingroup
+ \ifvmode
+ \noindent
+ \fi
+ \begingroup
+ \strc_lists_set_reference_attribute\v!all
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \strc_lists_get_destination_attribute
+ \begingroup
+ \ifconditional\c_lists_show_number
+ \donetrue
+ \ifconditional\c_lists_has_number \else
+ \edef\p_symbol{\listparameter\c!symbol}
+ \ifempty\p_symbol
+ \donefalse
+ \fi
+ \fi
+ \ifdone
+ \begingroup
+ \strc_lists_set_reference_attribute\v!number
+ \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
+ \listparameter\c!left
+ \listparameter\c!numbercommand\currentlistsymbol
+ \listparameter\c!right
+ \endgroup
+ \kern.5\emwidth\relax
+ \nobreak
+ \fi
+ \fi
+ \endgroup
+ \begingroup
+ \strc_lists_set_reference_attribute\v!text
+ \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
+ \the\t_lists_every_renderingtext
+ \the\t_lists_every_renderingsynchronize
+ \setstrut % needs checking, new here
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ \endgroup
+ \begingroup
+ \ifconditional\c_lists_has_page
+ \ifconditional\c_lists_show_page
+ \nobreak
+ \hskip.75\emwidth\relax
+ \nobreak
+ \strc_lists_set_reference_attribute\v!pagenumber
+ \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
+ \strut
+ \listparameter\c!pagecommand\currentlistentrypagenumber
+ \fi
+ \fi
+ \endgroup
+ \scratchdistance\listparameter\c!distance\relax
+ \ifdim\scratchdistance<\emwidth
+ \hskip\emwidth\s!plus\emwidth\s!minus.25\emwidth\relax
+ \else
+ \hskip\scratchdistance\s!plus.5\scratchdistance\s!minus.25\scratchdistance\relax
+ \fi
+ \endgroup
+ \endgroup
+\stopsetups
+
+\startsetups[\??listrenderings:e]
+ \typo_injectors_check_list
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \letlistparameter\c!depth\zeropoint
+ \letlistparameter\c!color\empty
+ \inheritedlistframed {
+ \letinteractionparameter\c!strut\v!no % still needed?
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \the\t_lists_every_renderingtext
+ \the\t_lists_every_renderingsynchronize
+ \setstrut
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ }
+ }
+ \par
+ \listparameter\c!inbetween
+\stopsetups
+
+\startsetups[\??listrenderings:f]
+ \typo_injectors_check_list
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \dosetraggedhbox{\listparameter\c!align}%
+ \raggedbox {
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \the\t_lists_every_renderingtext
+ \the\t_lists_every_renderingsynchronize
+ \setstrut
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ }
+ }
+ \par
+ \listparameter\c!inbetween
+\stopsetups
+
+\startsetups[\??listrenderings:g]
+ \typo_injectors_check_list
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \midaligned {
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \the\t_lists_every_renderingtext
+ \the\t_lists_every_renderingsynchronize
+ \setstrut
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ }
+ }
+ \par
+ \listparameter\c!inbetween
+\stopsetups
+
+%D This is a new one, similar to vertical and horizontal but better suited when
+%D no command is set (WS):
+
+\definelistalternative
+ [\v!interactive]
+ [\c!renderingsetup=\??listrenderings:interactive,
+ \c!before=\endgraf, % new per 2014-11-08
+ \c!after=\endgraf] % new per 2014-11-08
+
+\startsetups[\??listrenderings:interactive]
+ \edef\p_command{\listalternativeparameter\c!command}%
+ \typo_injectors_check_list
+ \listparameter\c!before
+ \noindent % otherwise annotations are mirrored up
+ \typo_injectors_mark_list
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \ifempty\p_command
+ [
+ \currentlist:\space
+ \currentlistentrynumber
+ \space\emdash\space
+ \currentlistentrytitle
+ \space\emdash\space
+ \currentlistentrypagenumber
+ ]
+ \else
+ \p_command\currentlistentrynumber\currentlistentrytitle\currentlistentrypagenumber
+ \fi
+ }
+ \listparameter\c!after
+\stopsetups
+
+%D One special for publications (as Alan loves to hangindent). No fonts and such
+%D (for now). No interaction either as that is dealt with elsewhere.
+%D
+%D \currentlistsymbol
+%D \currentlistentrynumber
+%D \currentlistentrytitle
+%D \currentlistentrypagenumber % not really used
+
+\definelistalternative
+ [\v!paragraph]
+ [\c!filler=\v!space,
+ \c!renderingsetup=\??listrenderings:\v!paragraph]
+
+\startsetups[\??listrenderings:\v!paragraph]
+ \endgraf % are we grouped?
+ \typo_injectors_check_list % ?
+ \listparameter\c!before
+ \endgraf
+ \begingroup
+ \forgetall
+ \noindent
+ \parindent\zeropoint
+ \edef\p_width{\listparameter\c!width}%
+ \edef\p_distance{\listparameter\c!distance}% we are nice for bib users
+ \edef\p_margin{\listparameter\c!margin}% we are nice for bib users
+ \ifx\p_distance\v!none
+ \scratchdistance\zeropoint
+ \else
+ \scratchdistance\p_distance
+ \fi
+ \ifx\p_margin\v!none
+ \scratchoffset\zeropoint
+ \else
+ \scratchoffset\p_margin
+ \fi
+ \ifx\p_width\v!fit
+ \scratchwidth\zeropoint
+ \leftskip\scratchoffset
+ \else
+ \scratchwidth\p_width
+ \ifzeropt\scratchoffset
+ \leftskip\dimexpr\scratchwidth+\scratchdistance\relax
+ \else
+ \leftskip\scratchoffset
+ \fi
+ \fi
+ \usealignparameter\listparameter
+ \hskip-\leftskip
+ \ifconditional\c_lists_has_number
+ \ifconditional\c_lists_show_number
+ \setbox\scratchbox
+ \simplealignedbox\scratchwidth{\listparameter\c!numberalign}
+ \bgroup
+ \useliststyleandcolor\c!numberstyle\c!numbercolor
+ \currentlistsymbol
+ \egroup
+ \ifdim\wd\scratchbox>\zeropoint
+ \box\scratchbox
+ \hskip\scratchdistance\relax
+ \fi
+ \fi
+ \fi
+ \begingroup
+ \useliststyleandcolor\c!textstyle\c!textcolor
+ \setstrut
+ \begstrut
+ \currentlistentrytitle
+ \endstrut
+ \endgroup
+ \ifconditional\c_lists_has_page
+ \ifconditional\c_lists_show_page
+ \nobreak
+ \currentlistfiller
+ \begingroup
+ \useliststyleandcolor\c!pagestyle\c!pagecolor
+ \currentlistentrypagenumber
+ \endgroup
+ \fi
+ \fi
+ \endgraf
+ \endgroup
+ \allowbreak
+ \listparameter\c!after
+\stopsetups
+
+%D List elements are packaged in such a way that we can click on them in an
+%D interactive document. Here are a few helpers.
+
+\newconstant\a_strc_lists_reference
+\newconstant\a_strc_lists_destination
+
+\installcorenamespace{listinteractions}
+
+\letvalue{\??listinteractions\v!number }\v!number
+\letvalue{\??listinteractions\v!sectionnumber}\v!number
+\letvalue{\??listinteractions\v!text }\v!text
+\letvalue{\??listinteractions\v!title }\v!text
+\letvalue{\??listinteractions\v!page }\v!pagenumber
+\letvalue{\??listinteractions\v!pagenumber }\v!pagenumber
+\letvalue{\??listinteractions\v!all }\v!all
+\letvalue{\??listinteractions\v!yes }\v!all
+
+\permanent\def\listboxproperties {\strc_lists_get_reference_attribute}
+\permanent\def\listrenderingsetup {\the\t_lists_every_renderingtext}
+\permanent\def\listrenderingsynchronize{\the\t_lists_every_renderingsynchronize}
+
+\protected\def\strc_lists_interaction_check
+ {\iflocation
+ \strc_lists_interaction_check_yes
+ \else
+ \strc_lists_interaction_check_nop
+ \fi}
+
+\def\strc_lists_interaction_check_yes_yes
+ {\edef\p_interaction_forward{\listparameter\c!interaction}%
+ \ifcsname\??listinteractions\p_interaction_forward\endcsname
+ %\expandafter\let\expandafter\p_interaction_forward\csname\??listinteractions\p_interaction_forward\endcsname
+ \expandafter\let\expandafter\p_interaction_forward\lastnamedcs
+ \strc_references_get_simple_reference{internal(\currentlistentrylocation)}%
+ \a_strc_lists_reference\currentreferenceattribute
+ \else
+ \a_strc_lists_reference\attributeunsetvalue
+ \fi
+ \ifnum\a_strc_lists_reference=\attributeunsetvalue
+ \let\strc_lists_get_reference_attribute\gobbleoneargument
+ \let\strc_lists_set_reference_attribute\gobbleoneargument
+ \let\strc_lists_set_style_color \strc_lists_set_style_color_normal
+ \else
+ \let\strc_lists_get_reference_attribute\strc_lists_get_reference_attribute_indeed
+ \let\strc_lists_set_reference_attribute\strc_lists_set_reference_attribute_indeed
+ \let\strc_lists_set_style_color \strc_lists_set_style_color_special
+ \fi
+ \edef\p_interaction_backward{\namedheadparameter\currentlist\c!interaction}% \namedheadparameter !
+ \ifx\p_interaction_backward\v!list
+ \strc_references_set_simple_reference{*\currentlistentrylocation}%
+ \a_strc_lists_destination\currentdestinationattribute
+ \else
+ \a_strc_lists_destination\attributeunsetvalue
+ \fi
+ \ifnum\a_strc_lists_destination=\attributeunsetvalue
+ \let\strc_lists_get_destination_attribute\empty
+ \let\strc_lists_set_destination_attribute\empty
+ \else
+ \let\strc_lists_get_destination_attribute\strc_lists_get_destination_attribute_indeed
+ \let\strc_lists_set_destination_attribute\strc_lists_set_destination_attribute_indeed
+ \fi}
+
+\def\strc_lists_interaction_check_yes_nop
+ {\a_strc_lists_reference \attributeunsetvalue
+ \a_strc_lists_destination\attributeunsetvalue
+ \let\strc_lists_get_reference_attribute\gobbleoneargument
+ \let\strc_lists_set_reference_attribute\gobbleoneargument
+ \let\strc_lists_get_destination_attribute\empty
+ \let\strc_lists_set_destination_attribute\empty
+ \let\strc_lists_set_style_color\strc_lists_set_style_color_normal}
+
+\def\strc_lists_interaction_check_yes
+ {\ifempty\currentlistentrylocation
+ \strc_lists_interaction_check_yes_nop
+ \orelse\ifnum\currentlistentrylocation=\zerocount
+ \strc_lists_interaction_check_yes_nop
+ \else
+ \strc_lists_interaction_check_yes_yes
+ \fi}
+
+\def\strc_lists_interaction_check_nop
+ {\let\strc_lists_get_reference_attribute \gobbleoneargument
+ \let\strc_lists_set_reference_attribute \gobbleoneargument
+ \let\strc_lists_get_destination_attribute\empty
+ \let\strc_lists_set_destination_attribute\empty
+ \let\strc_lists_set_style_color \strc_lists_set_style_color_normal}
+
+\strc_lists_interaction_check_nop
+
+\def\strc_lists_get_reference_attribute_indeed#element%
+ {\ifx#element\p_interaction_forward
+ attr \referenceattribute\a_strc_lists_reference
+ \fi}
+
+\def\strc_lists_set_reference_attribute_indeed#element%
+ {\ifx#element\p_interaction_forward
+ \c_attr_reference\a_strc_lists_reference
+ \fi}
+
+\def\strc_lists_get_destination_attribute_indeed
+ {attr \destinationattribute\number\a_strc_lists_destination}
+
+\def\strc_lists_set_destination_attribute_indeed
+ {\c_attr_destination\a_strc_lists_destination}
+
+\protected\def\strc_lists_set_style_color_normal#style#color#element%
+ {\useliststyleandcolor#style#color}
+
+\protected\def\strc_lists_set_style_color_special#style#color#element%
+ {\useliststyleandcolor#style#color%
+ \ifempty\currentcolorparameter
+ \ifx#element\p_interaction_forward
+ \setlocationcolor
+ \fi
+ % \else
+ % \resetinteractionparameter\c!color
+ % \resetinteractionparameter\c!contrastcolor
+ \fi}
+
+\let\strc_lists_set_style_color\strc_lists_set_style_color_normal
+
+%D A helper:
+
+\def\strc_lists_limitated_text#text%
+ {\edef\p_maxwidth{\listparameter\c!maxwidth}%
+ \ifempty\p_maxwidth
+ \listparameter\c!textcommand{#text}%
+ \else
+ \listparameter\c!textcommand{\limitatetext{#text}\p_maxwidth{\splitsymbol{\listparameter\c!limittext}}}%
+ \fi}
+
+% public helpers
+
+\permanent\protected\def\startcurrentlistentrywrapper
+ {\hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute\bgroup}
+
+\aliased\let\stopcurrentlistentrywrapper\egroup
+
+\aliased\let\currentlistentryreferenceattribute \strc_lists_get_reference_attribute
+\aliased\let\currentlistentrydestinationattribute\strc_lists_get_destination_attribute
+\aliased\let\currentlistentrylimitedtext \strc_lists_limitated_text
+
+% todo:
+
+\def\utilitylistlength{\listlength} % old name ... uses in styles
+
+\mutable\let\listlength\!!zerocount % better use listmode
+
+\permanent\tolerant\protected\def\determinelistcharacteristics[#list]#spacer[#settings]%
+ {\begingroup
+ \edef\currentlist{\firststructureelementinlist{#list}}%
+ \ifempty\currentlist
+ \endgroup
+ \let\listlength\!!zerocount
+ \else
+ \setupcurrentlist[#settings]%
+ \strc_lists_analyze{#list}{\listparameter\c!criterium}{\listparameter\c!reference}%
+ \normalexpanded{\endgroup\noexpand\edef\noexpand\listlength{\structurelistsize}}%
+ \fi
+ \strc_lists_set_mode}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/strc-mat.mkxl b/tex/context/base/mkiv/strc-mat.mkxl
new file mode 100644
index 000000000..e72be7d3e
--- /dev/null
+++ b/tex/context/base/mkiv/strc-mat.mkxl
@@ -0,0 +1,1308 @@
+%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 \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Math Numbering}
+
+\registerctxluafile{strc-mat}{}
+
+% -- we have potential for captions
+% -- this module will use the commandhandler
+% -- key/value pairs will be added (I have no time now)
+
+\unprotect
+
+\setupformulas
+ [%\c!way=,
+ %\c!blockway=,
+ %\c!sectionnumber=,
+ %\c!conversion=\v!numbers,
+ %\c!numberstyle=,
+ %\c!numbercolor=,
+ %\c!numbercommand=,
+ %\c!margin=,
+ %\c!align=,
+ %\c!separator=,
+ \c!grid=\v!math,
+ \c!location=\v!right,
+ \c!left=(,
+ \c!right=),
+ \c!expansion=\v!yes, % maybe automatically
+ \c!spacebefore=\v!big,
+ \c!spaceafter=\formulaparameter\c!spacebefore,
+ \c!width=\hsize,
+ \c!leftmargin=\zeropoint,
+ \c!rightmargin=\zeropoint,
+ \c!indentnext=\v!no,
+ \c!alternative=\s!default,
+ \c!strut=\v!no,
+ \c!numberstrut=\v!yes, % \v!no \v!yes \v!always
+ \c!distance=2\emwidth]
+
+\setupformulaframed
+ [%c!location=<auto set>,
+ %c!width=<auto set>,
+ %c!align=<auto set>,
+ \c!offset=.5\exheight]
+
+\ifdefined\matheqnogapstep
+ % we're ok, now we have that quad in the distance which is
+ % more consistent and not depending on the text font in math
+ \matheqnogapstep\zerocount
+\else
+ % we will keep this for a while
+ \setupformulas[\c!distance=\emwidth]
+\fi
+
+% \ifdefined\mathdisplayskipmode
+% \mathdisplayskipmode\plustwo % only when not zero / needs adapted space handler
+% \fi
+
+% \mathdisplayskipmode\plusthree
+%
+% \hbox\bgroup
+% \setbox0\vbox\bgroup
+% xxxxxxxxx\par
+% \vskip-\baselineskip
+% $$a^2_2$$\par
+% xxxxxxxxx\par
+% \egroup
+% \box0
+% \vbox\bgroup
+% xxxxxxxxx\par
+% \vskip-\baselineskip
+% $$a^2$$\par
+% xxxxxxxxx\par
+% \egroup
+% \vbox\bgroup
+% xxxxxxxxx
+% \vskip-\baselineskip
+% $$a_2$$
+% xxxxxxxxx
+% \egroup
+% \egroup
+%
+% \hbox\bgroup
+% \setbox0\vbox\bgroup
+% xxxxxxxxx\par
+% \ctxlua{tex.prevdepth=-1000 *65536}
+% $$a^2_2$$\par
+% xxxxxxxxx\par
+% \egroup
+% \box0
+% \vbox\bgroup
+% xxxxxxxxx\par
+% \ctxlua{tex.prevdepth=-1000 *65536}
+% $$a^2$$\par
+% xxxxxxxxx\par
+% \egroup
+% \vbox\bgroup
+% xxxxxxxxx
+% \ctxlua{tex.prevdepth=-1000 *65536}
+% $$a_2$$
+% xxxxxxxxx
+% \egroup
+% \egroup
+
+\setupsubformulas % subformulas could be last in chain
+ [\c!indentnext=\formulaparameter\c!indentnext]
+
+\definecounter % one ?
+ [\v!formula]
+
+\defineconversionset
+ [\v!formula]
+ [numbers,characters] % no \v! ?
+
+\installcounterassociation{formula} \registerformulacounter\v!formula % currently we only have one
+
+\appendtoks
+ \synchronizeformulacounters
+\to \everysetupformula
+
+% \appendtoks
+% \synchronizeformulacounters
+% \to \everydefineformula
+
+\setupformulas
+ [\c!numberconversionset=\v!formula] % why forgotten
+
+\appendtoks
+ \normalexpanded{\definelist[\currentformula]}% is expansion needed?
+ \frozen\instance\setuevalue{\e!start\currentformula\v!formula}{\strc_formulas_start_formula{\currentformula}}%
+ \frozen\instance\setuevalue{\e!stop \currentformula\v!formula}{\strc_formulas_stop_formula}%
+\to \everydefineformula
+
+\definelist[\v!formula]
+
+\permanent\setuvalue{\e!start\v!formula}{\strc_formulas_start_formula{}}
+\permanent\setuvalue{\e!stop \v!formula}{\strc_formulas_stop_formula}
+
+\let\strc_formulas_start_formula\relax % defined later
+\let\strc_formulas_stop_formula \relax % defined later
+
+\permanent\tolerant\protected\def\defineformulaalternative[#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]
+
+\newtoks\everyresetformulas
+
+\appendtoks
+ \let\currentformula\empty % to be checked:
+\to \everyresetformulas
+
+% implementation
+
+\protected\def\strc_formulas_store_number#1#2#3#4#5% ref, todo:str, \sync % todo: title etc (like float)
+ {\settrue\c_strc_formulas_handle_number
+ \strc_counters_register_component
+ {formula}%
+ \setupcurrentformula \formulaparameter \detokenizedformulaparameter
+ \relax \relax \relax
+ [\c!name=\v!formula,\s!counter=\v!formula,%
+ \s!hascaption=\v!yes,\s!hastitle=\v!yes,\s!hasnumber=\v!yes,%\s!haslevel=#6,%
+ \c!reference=#1,\c!title=\namedformulaentry,\c!bookmark=]%
+ [#2]%
+ \glet\namedformulaentry\empty % \relax
+ \glet#3\m_strc_counters_last_registered_index
+ \glet#4\m_strc_counters_last_registered_synchronize
+ \glet#5\m_strc_counters_last_registered_attribute}
+
+% modes: 0=unset, 1=forced, 2=none, 3=reference
+
+\newconstant\c_strc_formulas_place_number_mode
+\newconstant\c_strc_formulas_number_mode
+\newconstant\c_strc_formulas_sub_number_mode
+\newconstant\c_strc_formulas_nested_number_mode
+
+\appendtoks
+ \c_strc_formulas_place_number_mode \zerocount
+ \c_strc_formulas_number_mode \zerocount
+ \c_strc_formulas_sub_number_mode \zerocount
+ \c_strc_formulas_nested_number_mode\zerocount
+\to \everyresetformulas
+
+\newconditional\c_strc_formulas_handle_number
+\newconditional\c_strc_formulas_inside_place
+\newconditional\c_strc_formulas_inside_place_sub
+\newconditional\c_strc_formulas_inside_formulas
+\newconditional\c_strc_formulas_inside_formulas_sub
+
+\appendtoks
+ \global\setfalse\c_strc_formulas_inside_place
+ \global\setfalse\c_strc_formulas_inside_place_sub
+\to \everyresetformulas
+
+\def\strc_formulas_place_number_noneed
+ {\doif{\formulaparameter\c!numberstrut}\v!always\strut}
+
+\def\strc_formulas_place_numbering % place formula
+ {\settrue\c_strc_formulas_handle_number
+ \strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference
+ \ifnum\c_strc_formulas_place_number_mode=\plustwo
+ \glet\strc_formulas_place_number\strc_formulas_place_number_noneed
+ \else
+ \glet\strc_formulas_place_number\strc_formulas_place_number_indeed
+ \fi
+ \glet\strc_formulas_place_number_nested\strc_formulas_place_number_nested_indeed}
+
+\def\strc_formulas_handle_number % formulas
+ {\strc_formulas_check_reference\c_strc_formulas_number_mode\currentformulasreference}
+
+\def\strc_formulas_handle_sub_number_indeed % sub formulas
+ {\strc_formulas_check_reference\c_strc_formulas_sub_number_mode\currentsubformulasreference
+ \strc_counters_increment\v!formula
+ \strc_formulas_store_number
+ \currentsubformulasreference
+ \empty
+ \currentsubformulasnumber
+ \currentsubformulassynchronize
+ \currentsubformulasattribute}
+
+\def\strc_formulas_handle_sub_number % sub formulas
+ {\iftrialtypesetting
+ \strc_counters_save\v!formula
+ \strc_formulas_handle_sub_number_indeed
+ \strc_counters_restore\v!formula
+ \else
+ \strc_formulas_handle_sub_number_indeed
+ \fi}
+
+\let\strc_formulas_reference_trace\relax
+\let\strc_formulas_reference_show \relax
+
+\permanent\protected\def\placecurrentformulanumber
+ {\begingroup
+ \rm % determines the distance and main font
+ \edef\p_location{\formulaparameter\c!location}%
+ \ifx\p_location\v!right
+ \hskip\formulaparameter\c!distance
+ \fi
+ \begingroup
+ \useformulastyleandcolor\c!numberstyle\c!numbercolor
+ \formulaparameter\c!numbercommand
+ {\edef\p_strut{\formulaparameter\c!numberstrut}%
+ \ifx\p_strut\v!always
+ \strut
+ \orelse\ifx\p_strut\v!yes
+ \strut
+ \fi
+ \formulaparameter\c!left
+ \namedtaggedlabeltexts
+ \t!formulalabel \v!formula
+ \t!formulanumber\v!formula
+ {\ignorespaces\strc_formulas_place_current_number\removeunwantedspaces}%
+ \formulaparameter\c!right}%
+ \endgroup
+ \ifx\p_location\v!left
+ \hskip\formulaparameter\c!distance
+ \fi
+ \endgroup}
+
+\protected\def\strc_formulas_place_current_number
+ {\ifempty\namedformulaentry
+ \strc_formulas_handle_current_references
+ \labeltexts\currentformula{\convertedcounter[\v!formula][]}%
+ \else
+ \expandafter % hm, the next one reset \namedformulaentry
+ \strc_formulas_handle_current_references
+ \namedformulaentry
+ \fi}
+
+\permanent\def\theformuladestinationattribute#1%
+ {\iflocation\ifx#1\relax\orelse\ifempty#1\else
+ \c_attr_destination#1%
+ \glet#1\relax
+ \fi\fi}
+
+\let\currentplaceformulaattribute\relax
+\let\currentformulaattribute \relax
+\let\currentsubformulaattribute \relax
+\let\currentformulasattribute \relax
+
+\let\currentplaceformulanumber\relax
+\let\currentformulanumber \relax
+\let\currentsubformulanumber \relax
+\let\currentformulasnumber \relax
+
+\mutable\let\currentformulasreference \empty
+\mutable\let\currentformulareference \empty
+\mutable\let\currentsubformulareference \empty
+\mutable\let\currentnestedformulareference\empty
+
+\appendtoks
+ \glet\currentformulasreference \empty
+ \glet\currentformulareference \empty
+ \glet\currentsubformulareference \empty
+ \glet\currentnestedformulareference\empty
+\to \everyresetformulas
+
+\mutable\let\currentformulassuffix \empty
+\mutable\let\currentformulasuffix \empty
+\mutable\let\currentsubformulasuffix \empty
+\mutable\let\currentnestedformulasuffix\empty
+
+\appendtoks
+ \glet\currentformulassuffix \empty
+ \glet\currentformulasuffix \empty
+ \glet\currentsubformulasuffix \empty
+ \glet\currentnestedformulasuffix\empty
+\to \everyresetformulas
+
+\let\currentplaceformulasynchronize\relax
+\let\currentformulasynchronize \relax
+\let\currentsubformulasynchronize \relax
+\let\currentformulassynchronize \relax
+
+\appendtoks
+ \glet\currentplaceformulasynchronize \relax
+ \glet\currentformulassynchronize \relax
+ \glet\currentsubformulassynchronize \relax
+ \glet\currentnestedformulasynchronize\relax
+\to \everyresetformulas
+
+% currently we do the number, some day we will do the (sub) formula
+
+\def\strc_formulas_handle_current_references
+ {\strc_formulas_reference_show
+ \ifnum\c_strc_formulas_place_number_mode=\plusthree
+ \strc_formulas_store_number
+ \currentplaceformulareference
+ \empty
+ \currentplaceformulanumber
+ \currentplaceformulasynchronize
+ \currentplaceformulaattribute
+ \currentplaceformulasynchronize
+ \glet\currentplaceformulasynchronize\relax
+ \theformuladestinationattribute\currentplaceformulaattribute
+ \fi
+ \ifnum\c_strc_formulas_number_mode=\plusthree
+ \strc_formulas_store_number
+ \currentformulasreference
+ \empty
+ \currentformulasnumber
+ \currentformulassynchronize
+ \currentformulasattribute
+ \currentformulassynchronize
+ \glet\currentformulassynchronize\relax
+ \theformuladestinationattribute\currentformulasattribute
+ \fi
+ \ifnum\c_strc_formulas_sub_number_mode=\plusthree
+ \currentsubformulassynchronize
+ \glet\currentsubformulassynchronize\relax
+ \fi
+ \ifnum\c_strc_formulas_nested_number_mode=\plusthree
+ \strc_formulas_store_number
+ \currentnestedformulareference
+ \empty
+ \currentnestedformulanumber
+ \currentnestedformulasynchronize
+ \currentnestedformulaattribute
+ \currentnestedformulasynchronize
+ \glet\currentnestedformulasynchronize\relax
+ \theformuladestinationattribute\currentnestedformulaattribute
+ \fi}
+
+% needs checking ... too many:
+
+\def\strc_formulas_handle_numbering_indeed
+ {\ifempty\namedformulaentry
+ \strc_counters_increment\v!formula
+ \doiftext\currentplaceformulasuffix{\strc_counters_setown_sub\v!formula\plustwo\currentplaceformulasuffix}%
+ \fi
+ \placecurrentformulanumber}
+
+\def\strc_formulas_handle_numbering
+ {\iftrialtypesetting
+ \strc_counters_save\v!formula
+ \strc_formulas_handle_numbering_indeed
+ \strc_counters_restore\v!formula
+ \else
+ \strc_formulas_handle_numbering_indeed
+ \fi}
+
+\def\strc_formulas_handle_sub_numbering_indeed
+ {\let\strc_formulas_handle_sub_numbering\relax % else error: see math/numbering-001.tex
+ \doifelsetext\currentsubformulasuffix
+ {\strc_counters_setown_sub\v!formula\plustwo\currentsubformulasuffix}
+ {\strc_counters_increment_sub\v!formula\plustwo}%
+ \placecurrentformulanumber}
+
+\def\strc_formulas_handle_sub_numbering
+ {\iftrialtypesetting
+ \strc_counters_save\v!formula
+ \strc_formulas_handle_sub_numbering_indeed
+ \strc_counters_restore\v!formula
+ \else
+ \strc_formulas_handle_sub_numbering_indeed
+ \fi}
+
+\def\strc_formulas_number_indeed
+ {\ifconditional\c_strc_formulas_handle_number
+ \hbox\bgroup
+ % main counter
+ \ifconditional\c_strc_formulas_inside_formulas_sub
+ % nothing
+ \else
+ \ifcase\c_strc_formulas_number_mode
+ \ifcase\c_strc_formulas_place_number_mode
+ \strc_formulas_handle_numbering
+ \or
+ \strc_formulas_handle_numbering
+ \or
+ % nothing
+ \or
+ \strc_formulas_handle_numbering
+ \fi
+ \or
+ \strc_formulas_handle_numbering
+ \or
+ % nothing
+ \or
+ \strc_formulas_handle_numbering
+ \fi
+ \fi
+ % subcounter
+ \ifconditional\c_strc_formulas_inside_formulas_sub
+ \ifcase\c_strc_formulas_sub_number_mode
+ \strc_formulas_handle_sub_numbering % was nothing
+ \or
+ \strc_formulas_handle_sub_numbering
+ \or
+ % nothing
+ \or
+ \strc_formulas_handle_sub_numbering
+ \fi
+ \fi
+ \strc_formulas_reference_trace
+ \egroup
+ \fi}
+
+\installstructurelistprocessor\v!formula % to be checked ...
+ {\let\currentlistentrynumber \structurelistgenericnumber
+ \let\currentlistentrytitle \structurelistgenerictitle
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+\newif\ifinformula
+
+%D We need a hook into the plain math alignment macros
+%D
+%D \starttyping
+%D \displaylines
+%D \eqalignno
+%D \eqalignno
+%D \stoptyping
+%D
+%D Otherwise we get a missing \type {$$} error reported.
+
+\pushoverloadmode
+
+\let\reqno\eqno % no longer valid as we just nil it
+
+\let\math_native_leqno\leqno
+\let\math_native_reqno\reqno
+
+\protected\def\normaleqno#1{\writestatus\m!system{no native (l)eqno equation number support}}
+
+\let\normalleqno\normaleqno
+\let\normalreqno\normaleqno
+
+\let\leqno\normaleqno
+\let\reqno\normaleqno
+\let\eqno \normaleqno
+
+\popoverloadmode
+
+%D \macros
+%D {startsubformulas}
+
+% \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:
+
+\abovedisplayskip \zeropoint
+\abovedisplayshortskip \zeropoint % evt. 0pt minus 3pt
+\belowdisplayskip \zeropoint
+\belowdisplayshortskip \zeropoint % evt. 0pt minus 3pt
+
+\predisplaypenalty \zerocount
+\postdisplaypenalty \zerocount % -5000 goes wrong, see penalty at \section
+\mathdisplayskipmode \plusthree % because align also adds
+
+% \predisplaygapfactor \zerocount % default is 2000
+
+\protected\def\strc_formulas_forget_display_skips
+ {\mathdisplayskipmode \plusthree
+ \abovedisplayskip \zeropoint
+ \belowdisplayskip \zeropoint
+ \abovedisplayshortskip\zeropoint
+ \belowdisplayshortskip\zeropoint}
+
+\newdimen\d_strc_formulas_display_skip_left
+\newdimen\d_strc_formulas_display_skip_right
+\newdimen\d_strc_formulas_display_margin_left
+\newdimen\d_strc_formulas_display_margin_right
+\newdimen\d_strc_formulas_display_pre_threshold
+\newdimen\d_strc_formulas_display_width
+
+\newconstant\c_strc_formulas_mode % this will go away
+\newconstant\c_strc_formulas_space_model
+
+\newconstant\c_strc_math_vertical % experiment
+
+\c_strc_formulas_mode \plustwo % 0=native 1=simple (old) 2=align (new)
+\c_strc_formulas_space_model\plusthree % replaces \plusone, we might use \plusfour in the future
+
+\newconditional\c_strc_formulas_tight
+
+\newbox\b_strc_formulas_number
+\newbox\b_strc_formulas_content
+
+\def\strc_formulas_flush_content_and_number
+ {\noindentation
+ % \dontleavehmode
+ \kern\d_strc_formulas_display_margin_left
+ \ifcase\wd\b_strc_formulas_number
+ \hbox to \displaywidth \bgroup
+ \hfill
+ \box\b_strc_formulas_content
+ \hfill
+ \egroup
+ \orelse\ifdim\dimexpr\wd\b_strc_formulas_content+\wd\b_strc_formulas_number\relax>\displaywidth
+ \vbox \bgroup
+ \hsize\displaywidth
+ \box\b_strc_formulas_content
+ \par
+ \ifx\p_location\v!left
+ \box\b_strc_formulas_number\hfill
+ \else
+ \hfill\box\b_strc_formulas_number
+ \fi
+ \egroup
+ \else
+ \hbox to \displaywidth \bgroup
+ \ifx\p_location\v!left
+ \rlap{\box\b_strc_formulas_number}%
+ \hfill\box\b_strc_formulas_content\hfill
+ \else
+ \hfill\box\b_strc_formulas_content\hfill
+ \llap{\box\b_strc_formulas_number}%
+ \fi
+ \egroup
+ \fi}
+
+\installcorenamespace{mathdisplayspacemodel}
+
+\setvalue{\??mathdisplayspacemodel\v!before:1}% old
+ {\ifx\p_spacebefore\v!none
+ % nothing
+ \else
+ \directvspacing\p_spacebefore
+ \fi}
+
+\setvalue{\??mathdisplayspacemodel\v!after:1}% old
+ {\prevdepth .5\strutdp
+ \edef\p_spaceafter{\formulaparameter\c!spaceafter}%
+ \ifx\p_spaceafter\v!none
+ % nothing
+ \else
+ \directvspacing\p_spaceafter
+ \fi}
+
+\setvalue{\??mathdisplayspacemodel\v!before:2}% old
+ {\ifx\p_spacebefore\v!none
+ % nothing
+ \else
+ \directvspacing\p_spacebefore
+ \fi
+ \prevdepth-\maxdimen} % texbook pagina 79-80
+
+\setvalue{\??mathdisplayspacemodel\v!after:2}% old
+ {\prevdepth\lineheight
+ \edef\p_spaceafter{\formulaparameter\c!spaceafter}%
+ \ifx\p_spaceafter\v!none
+ % nothing
+ \else
+ \directvspacing\p_spaceafter
+ \fi}
+
+\setvalue{\??mathdisplayspacemodel\v!before:3}%
+ {% not ok, try \stopformula\par\startformula vs \stopformula\startformula
+ \let\m_spacebefore\empty
+ \ifvmode
+ \ifdim\lastskip>\zeropoint\else
+ \ifdim\prevdepth<\zeropoint\else
+ \ifdim\prevdepth<\strutdp
+ % maybe add a tracing option here
+ \ifgridsnapping
+ \let\m_spacebefore\v!depth
+ \else
+ \edef\m_spacebefore{\the\dimexpr\strutdp-\prevdepth\relax}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \nointerlineskip
+ \fi
+ \ifempty\m_spacebefore
+ \ifx\p_spacebefore\v!none
+ % nothing
+ \orelse\ifempty\p_spacebefore
+ \directvspacing\currentvspacing
+ \else
+ \directvspacing{\p_spacebefore,\the\scratchdimen}%
+ \fi
+ \else
+ \ifx\p_spacebefore\v!none
+ \directvspacing{\m_spacebefore}%
+ \orelse\ifempty\p_spacebefore
+ \directvspacing{\m_spacebefore,\currentvspacing}%
+ \else
+ \directvspacing{\m_spacebefore,\p_spacebefore}%
+ \fi
+ \fi}
+
+\setvalue{\??mathdisplayspacemodel\v!after:3}%
+ {\prevdepth\strutdp % \directvspacing\v!depth
+ \ifx\p_spaceafter\v!none
+ % nothing
+ \orelse\ifempty\p_spaceafter
+ \directvspacing\currentvspacing
+ \else
+ \directvspacing\p_spaceafter
+ \fi}
+
+\newconditional\c_math_model_four_indeed
+
+\setvalue{\??mathdisplayspacemodel\v!before:4}%
+ {% not ok, try \stopformula\par\startformula vs \stopformula\startformula
+ \ifvmode
+ \ifinner
+ \csname\??mathdisplayspacemodel\v!before:3\endcsname
+ \else
+ \settrue\c_math_model_four_indeed
+ \forcestrutdepth
+ \nointerlineskip
+ \ifx\p_spacebefore\v!none
+ % nothing
+ \orelse\ifempty\p_spacebefore
+ \directvspacing\currentvspacing
+ \else
+ \directvspacing{\p_spacebefore,\the\scratchdimen}%
+ \fi
+ \fi
+ \else
+ \csname\??mathdisplayspacemodel\v!before:3\endcsname
+ \fi}
+
+\setvalue{\??mathdisplayspacemodel\v!after:4}%
+ {\ifconditional\c_math_model_four_indeed
+ \setfalse\c_math_model_four_indeed
+ \forcestrutdepth
+ \else
+ \prevdepth\strutdp % \directvspacing\v!depth
+ \fi
+ \ifx\p_spaceafter\v!none
+ % nothing
+ \orelse\ifempty\p_spaceafter
+ \directvspacing\currentvspacing
+ \else
+ \directvspacing\p_spaceafter
+ \fi}
+
+\permanent\protected\def\setdisplaymathspacemodel[#1]%
+ {\ifcsname\??mathdisplayspacemodel\v!before:\number#1\endcsname
+ \c_strc_formulas_space_model#1\relax
+ \fi}
+
+% \newtoks\everybeforedisplay
+% \appendtoks\page_sides_check_floats_indeed\to\everybeforedisplay
+
+\permanent\protected\def\beforedisplayspace
+ {\ifhmode
+ \par
+ \fi
+ \ifvmode
+ \edef\p_spacebefore{\formulaparameter\c!spacebefore}%
+ \begincsname\??mathdisplayspacemodel\v!before:\number\c_strc_formulas_space_model\endcsname
+ \fi
+ \ifhmode
+ \par
+ \fi
+ \page_sides_check_floats_indeed} % probably needs more
+
+\permanent\protected\def\afterdisplayspace
+ {\ifhmode
+ \par
+ \fi
+ \ifvmode
+ \edef\p_spaceafter{\formulaparameter\c!spaceafter}%
+ \begincsname\??mathdisplayspacemodel\v!after:\number\c_strc_formulas_space_model\endcsname
+ \fi
+ \ifhmode
+ \par
+ \fi}
+
+\permanent\protected\def\setdisplaydimensions
+ {\displayindent\dimexpr
+ \d_strc_formulas_display_skip_left
+ +\d_strc_formulas_display_margin_left
+ \relax
+ \displaywidth\d_strc_formulas_display_width
+ %\setlocalhsize
+ %\displaywidth\localhsize
+ \ifdim\hangindent>\zeropoint
+ \advance\displayindent\hangindent
+ \else
+ \advance\displaywidth\hangindent
+ \fi
+ \advance\displaywidth\dimexpr
+ -\displayindent
+ -\d_strc_formulas_display_skip_right
+ -\d_strc_formulas_display_margin_right
+ \relax
+ \hsize\displaywidth} % new, else overfull in itemize
+
+\protected\def\strc_formulas_start_formula#1%
+ {\dodoubleempty\strc_formulas_start_formula_indeed[#1]}
+
+% \newskip\formulastrutht
+% \newskip\formulastrutdp
+
+%D \startbuffer
+%D \startformula[9pt] x = 1 \stopformula
+%D \startformula[7pt] x = 1 \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\setvalue{\??formulaoption\v!packed}%
+ {\c_strc_formulas_space_model\zerocount}
+
+\setvalue{\??formulaoption\v!tight}%
+ {\settrue\c_strc_formulas_tight}
+
+\setvalue{\??formulaoption\v!middle}%
+ {\d_strc_formulas_display_skip_left \zeropoint
+ \d_strc_formulas_display_skip_right\zeropoint}
+
+\setvalue{\??formulaoption\v!depth}%
+ {\c_strc_formulas_space_model\plusfour}
+
+\setvalue{\??formulaoption\v!line}%
+ {\ifgridsnapping
+ \setformulaparameter\c!grid{\v!math:\v!line}%
+ \fi}
+
+\setvalue{\??formulaoption\v!halfline}%
+ {\ifgridsnapping
+ \setformulaparameter\c!grid{\v!math:\v!halfline}%
+ \fi}
+
+\setvalue{\??formulaoption-\v!line}%
+ {\ifgridsnapping
+ \setformulaparameter\c!grid{\v!math:-\v!line}%
+ \fi}
+
+\setvalue{\??formulaoption-\v!halfline}%
+ {\ifgridsnapping
+ \setformulaparameter\c!grid{\v!math:-\v!halfline}%
+ \fi}
+
+% when we have 1.0.6 we wil use \mathpenaltiesmode
+%
+% \prebinoppenalty -100
+% \prerelpenalty -100
+
+\def\strc_math_set_split
+ {\edef\p_split{\formulaparameter\c!split}%
+ \ifx\p_split\v!yes
+ \global\c_strc_math_vertical\plusone
+ \orelse\ifx\p_split\v!page
+ \global\c_strc_math_vertical\plustwo
+ \else
+ \global\c_strc_math_vertical\zerocount
+ \fi
+ \ifcase\c_strc_math_vertical
+ % \mathpenaltiesmode \zerocount
+ \clf_setmathpenalties\zerocount
+ \clf_resetmathhang
+ \else
+ % \mathpenaltiesmode \plusone
+ \clf_setmathpenalties\plusone
+ \edef\p_hang{\formulaparameter\c!hang}%
+ \ifx\p_hang\v!none
+ \global\setfalse\c_strc_math_indent
+ \clf_resetmathhang
+ \else
+ \global\settrue\c_strc_math_indent
+ \clf_setmathhang {%
+ method {\p_hang}%
+ distance \formulaparameter\c!distance
+ }%
+ \fi
+ \fi}
+
+\setupformula
+ [\c!split=\v!no,
+ \c!distance=\zeropoint,
+ %\c!interlinespace=1.5\lineheight,
+ \c!interlinespace=,
+ \c!hang=\v!none]
+
+% for the moment (when testing) we use a penalty 1
+
+\protected\def\strc_math_align_here{\ifmmode\penalty\plusone\fi}%
+\protected\def\strc_math_break_here{\ifmmode\hfill\break \fi}%
+
+\appendtoks
+ \let\alignhere\strc_math_align_here
+ \let\breakhere\strc_math_break_here
+\to \everymathematics
+
+\protected\def\strc_formulas_start_formula_indeed[#1][#2]% setting leftskip adaption is slow !
+ {\ifhmode
+ \par
+ \fi
+ \bgroup % HERE
+ \iftrialtypesetting\else
+ \global\advance\c_strc_formulas_n\plusone
+ \fi
+ \def\currentformula{#1}%
+ \strc_math_set_split
+ \dostarttaggedchained\t!formula\currentformula\??formula
+ \setfalse\c_strc_formulas_tight
+ \d_strc_formulas_display_skip_left \leftskip
+ \d_strc_formulas_display_skip_right \rightskip
+ \d_strc_formulas_display_width \formulaparameter\c!width\relax
+ \d_strc_formulas_display_margin_left \formulaparameter\c!leftmargin\relax
+ \d_strc_formulas_display_margin_right\formulaparameter\c!rightmargin\relax
+ \ifsecondargument
+ \doifelseassignment{#2}% this is new, so that we can also set the grid
+ {\setupcurrentformula[#2]%
+ \edef\p_option{\formulaparameter\c!option}}%
+ {\edef\p_option{\formulaparameter\c!option}%
+ \edef\p_option{\ifempty\p_option\else\p_option,\fi#2}}%
+ \else
+ \edef\p_option{\formulaparameter\c!option}%
+ \fi
+ \ifempty\p_option \else
+ \rawprocesscommacommand[\p_option]\strc_formulas_option
+ \fi
+ \edef\p_margin{\formulaparameter\c!margin}%
+ \ifempty\p_margin \else
+ \dosetleftskipadaption\p_margin
+ \d_strc_formulas_display_margin_left\leftskipadaption
+ \fi
+ \let\strc_formulas_start_formula\strc_formulas_start_formula_nested
+ \strc_formulas_forget_display_skips
+ \the\everybeforedisplayformula
+ \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname}
+
+\protected\def\strc_formulas_start_formula_nested#1%
+ {\bgroup
+ \let\strc_formulas_stop_formula\strc_formulas_stop_formula_nested
+ \dostarttagged\t!subformula\empty}
+
+\protected\def\strc_formulas_stop_formula_nested
+ {\dostoptagged
+ \egroup}
+
+% tagging of formulanumbers is not ok (we get two display maths blobs)
+
+\newcount\c_strc_formulas_n
+
+\ifdefined\dotagregisterformula \else \let\dotagregisterformula\gobbleoneargument \fi
+
+\protected\def\strc_formulas_stop_formula
+ {\strc_formulas_place_number % in case it hasn't happened yet
+ \strc_formulas_flush_number % in case we are in native mode
+ \dostarttagged\t!formulacontent\empty
+ \dotagregisterformula\c_strc_formulas_n
+ \csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname
+ \dostoptagged
+ \dostoptagged
+ \nonoindentation
+ \useindentnextparameter\formulaparameter
+ \egroup
+ \hangafter\minusone % added for side floats
+ \hangindent\zeropoint % added for side floats
+ \setfalse\c_strc_formulas_handle_number
+ \the\everyresetformulas
+ \dorechecknextindentation} % here ?
+
+% experiment:
+
+\def\strc_formulas_set_grid_snapping
+ {\edef\p_grid{\formulaparameter\c!grid}%
+ \ifempty\p_grid \else
+ \spac_grids_snap_value_auto\p_grid
+ \fi}
+
+\appendtoks
+ \ifgridsnapping
+ \strc_formulas_set_grid_snapping
+ \fi
+\to \everybeforedisplayformula
+
+% \protected\def\switchtoformulabodyfont
+% {\switchtobodyfont}
+
+\setuvalue{\v!formula}{\dosingleempty\strc_formulas_formula}
+
+\def\strc_formulas_formula[#1]#2% todo: tagged
+ {\begingroup
+ \edef\p_direct{#1}%
+ \ifempty\p_direct \else
+ \rawprocesscommalist[\p_direct]\strc_formulas_option
+ \fi
+ % not : \def\strc_formulas_formula[##1]##2{\mathematics{##2}}%
+ \mathematics{#2}%
+ \endgroup}
+
+%D \starttyping
+%D % test \par % no preceding hlist
+%D % $$x$$ % preceding hlist
+%D % \noindent $$x$$ % no preceding hlist
+%D \startformula x \stopformula % now has \noindent (in mkii we messed with baselineskip)
+%D \stoptyping
+
+\permanent\protected\def\startdisplaymath
+ {\ifhmode
+ \par
+ \fi
+ \bgroup
+ \informulatrue
+ \beforedisplayspace
+ \setdisplaydimensions
+ \ifcase\c_strc_formulas_mode
+ \noindent % prevents that tex injects empty line (when using native display mechanism)
+ \Ucheckedstartdisplaymath
+ \the\everydisplay % new (probably too much)
+ \or
+ \setbox\b_strc_formulas_content\hbox\bgroup
+ \normalUstartmath
+ \displaystyle
+ \the\everydisplay % new (probably too much)
+ \else
+ \expandafter\startinnermath
+ \fi
+ \begingroup} % less interference with upcoming a \over b
+
+\permanent\protected\def\stopdisplaymath
+ {\endgroup % less interference with upcoming a \over b
+ \ifcase\c_strc_formulas_mode
+ \Ucheckedstopdisplaymath
+ \or
+ \normalUstopmath
+ \egroup
+ \strc_formulas_flush_content_and_number
+ \else
+ \expandafter\stopinnermath
+ \fi
+ \afterdisplayspace
+ \egroup}
+
+% already defined
+%
+% \let\startinnermath\empty
+% \let\stopinnermath \empty
+
+% \defineformulaalternative[multi][\begindmath][\enddmath]
+%
+% \fakewords{20}{40}\epar
+% \placeformula {a} $$ \fakespacingformula $$
+% \fakewords{20}{40}\epar
+% \placeformula {b} \startformule \fakespacingformula \stopformule
+% \placeformula {b} \startformule \fakespacingformula \stopformule
+% \fakewords{20}{40}\epar
+% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
+% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
+% \fakewords{20}{40}\epar
+% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
+% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
+% \fakewords{20}{40}\epar
+% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
+% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
+% \fakewords{20}{40}\epar
+% \placeformula {f} \startspformule \fakespacingformula \stopspformule
+% \placeformula {f} \startspformule \fakespacingformula \stopspformule
+% \fakewords{20}{40}
+
+\permanent\protected\def\startsubformulas
+ {\dosingleempty\strc_formulas_start_sub_formulas}
+
+\def\strc_formulas_start_sub_formulas[#1]%
+ {\edef\currentsubformulasreference{#1}%
+ \global\settrue\c_strc_formulas_inside_formulas_sub
+ \strc_formulas_handle_sub_number}
+
+\permanent\protected\def\stopsubformulas
+ {\nonoindentation
+ \useindentnextparameter\subformulaparameter
+ \the\everyresetformulas % to be checked
+ \global\setfalse\c_strc_formulas_inside_formulas_sub
+ \dorechecknextindentation} % here ?
+
+%D Named subformulas (to be redone)
+
+\permanent\protected\def\startnamedsubformulas
+ {\dosingleempty\strc_formulas_start_named_sub_formulas}
+
+\def\strc_formulas_start_named_sub_formulas[#1]#2%
+ {\setformulalistentry{#2}%
+ \startsubformulas[#1]}
+
+\permanent\protected\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
+
+\permanent\protected\def\startformulas{\strc_formulas_start_formulas}
+
+\permanent\letcsname\e!stop\v!formulas\endcsname\relax
+
+\protected\def\strc_formulas_nested_formula_start
+ {\hbox to \displaywidth \bgroup
+ \hsize\displaywidth
+ \hss
+ %\Ustartmath
+ \dostarttagged\t!formulacontent\empty
+ \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname}
+
+\protected\def\strc_formulas_nested_formula_stop
+ {\csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname
+ \dostoptagged
+ %\Ustopmath
+ \hss
+ \egroup
+ \hss}
+
+\normalexpanded{\tolerant\def\noexpand\strc_formulas_start_formulas[#1]#:#2\csname\e!stop\v!formulas\endcsname}%
+ {\startformula
+ \dostarttagged\t!formulaset\empty
+ \global\settrue\c_strc_formulas_inside_formulas
+ \edef\currentformulasreference{#1}%
+ \strc_formulas_handle_number
+ \let\currentformula\empty
+ \strc_formulas_forget_display_skips
+ \enforced\protected\def\startformula
+ {\advance\scratchcounter\plusone
+ \expandafter\gobbleuntil\csname\e!stop\v!formula\endcsname}%
+ \scratchcounter\zerocount
+ #2% preroll
+ \hbox to \displaywidth \bgroup
+ \divide\displaywidth\scratchcounter
+ \hss
+ \enforced\let\startformula\strc_formulas_nested_formula_start
+ \enforced\let\stopformula \strc_formulas_nested_formula_stop
+ #2%
+ \egroup
+ \global\setfalse\c_strc_formulas_inside_formulas
+ \dostoptagged
+ \stopformula
+ \the\everyresetformulas
+ \hangafter\minusone % added for side floats
+ \hangindent\zeropoint} % added for side floats
+
+% place
+
+\def\m_strc_formulas_flag_inhibit{-}
+\def\m_strc_formulas_flag_force {+}
+
+\def\strc_formulas_check_reference#1#2%
+ {#1\unless\ifempty\namedformulaentry % \relax % new 29/8/2010
+ \plusthree
+ \orelse\ifempty#2%
+ \zerocount
+ \orelse\ifx#2\m_strc_formulas_flag_force
+ \plusone
+ \orelse\ifx#2\m_strc_formulas_flag_inhibit
+ \plustwo
+ \else
+ \plusthree
+ \fi}
+
+\permanent\protected\def\formulanumber
+ {\strc_formulas_number} % for the moment
+
+\tolerant\protected\def\strc_formulas_number[#1]%
+ {\def\currentformulareference{#1}%
+ \strc_formulas_place_number_in_box}
+
+\permanent\protected\def\placeformula {\global\settrue\c_strc_formulas_inside_place}
+\permanent\protected\def\placesubformula{\global\settrue\c_strc_formulas_inside_place_sub}
+
+\tolerant\protected\def\strc_formulas_place[#1]%
+ {\def\currentplaceformulareference{#1}%
+ \let\currentplaceformulasuffix\empty
+ \doifelsenextbgroup\strc_formulas_place_yes\strc_formulas_place_nop} % [ref]{}
+
+\protected\def\strc_formulas_place_yes#1%
+ {\def\currentplaceformulasuffix{#1}%
+ \strc_formulas_place_nop}
+
+\protected\def\strc_formulas_place_nop
+ {\doifelsenextchar$\strc_formulas_place_pickup\strc_formulas_place_indeed} % [ref]$$ [ref]\start
+
+\protected\def\strc_formulas_place_indeed
+ {\strc_formulas_place_numbering}
+
+\protected\def\strc_formulas_place_pickup$$#1$$%
+ {\strc_formulas_place_numbering
+ \strc_formulas_start_formula{}#1\strc_formulas_stop_formula}
+
+% \let\startplaceformula\placeformula
+% \let\stopplaceformula \relax
+
+% \startplaceformula \startformula e=mc^2 \stopformula \stopplaceformula
+% \startplaceformula[-] \startformula e=mc^2 \stopformula \stopplaceformula
+% \startplaceformula[x] \startformula e=mc^2 \stopformula \stopplaceformula
+% \startplaceformula[reference=foo] \startformula e=mc^2 \stopformula \stopplaceformula
+% \startplaceformula[title=whatever] \startformula e=mc^2 \stopformula \stopplaceformula
+% \startplaceformula[suffix=x] \startformula e=mc^2 \stopformula \stopplaceformula
+
+\let\currentplaceformulareference\empty
+\let\currentplaceformulasuffix \empty
+
+\permanent\tolerant\protected\def\startplaceformula[#1]%
+ {\begingroup
+ \global\settrue\c_strc_formulas_inside_place
+ \ifparameter#1\or
+ \expandafter\strc_formulas_start_place_yes
+ \else
+ \expandafter\strc_formulas_start_place_nop
+ \fi[#1]}
+
+\def\strc_formulas_start_place_yes[#1]%
+ {\doifassignmentelse{#1}\strc_formulas_start_place_parameters\strc_formulas_start_place_reference[#1]}
+
+\def\strc_formulas_start_place_nop[#1]%
+ {\let\currentplaceformulareference\empty
+ \let\currentplaceformulasuffix \empty
+ \strc_formulas_place_nop}
+
+\def\strc_formulas_start_place_reference[#1]%
+ {\edef\currentplaceformulareference{#1}%
+ \let\currentplaceformulasuffix\empty
+ %\doifelsenextbgroup\strc_formulas_place_yes\strc_formulas_place_nop} % [ref]{}
+ \strc_formulas_place_nop}
+
+\def\strc_formulas_start_place_parameters[#1]%
+ {\letdummyparameter\c!title \empty
+ \letdummyparameter\c!reference\empty
+ \letdummyparameter\c!suffix \empty
+ \getdummyparameters[#1]%
+ \edef\currentplaceformulatitle {\dummyparameter\c!title}%
+ \edef\currentplaceformulareference{\dummyparameter\c!reference}%
+ \edef\currentplaceformulasuffix {\dummyparameter\c!suffix}%
+ \ifempty\currentplaceformulatitle\else
+ \normalexpanded{\setformulalistentry{\currentplaceformulatitle}}%
+ \fi
+ \doifelsenextbgroup\strc_formulas_place_yes\strc_formulas_place_nop} % [ref]{}
+
+\permanent\protected\def\stopplaceformula
+ {\relax
+ \endgroup}
+
+% to be checked
+
+\let\strc_formulas_place_number \relax
+\let\strc_formulas_place_number_nested\gobbletwoarguments
+
+\def\strc_formulas_place_number_nested_indeed#1#2%
+ {\def\currentnestedformulareference{#1}%
+ \def\currentnestedformulasuffix{#2}%
+ \strc_formulas_check_reference\c_strc_formulas_nested_number_mode\currentnestedformulareference
+ \ifcase\c_strc_formulas_nested_number_mode
+ % nothing
+ \or
+ \glet\strc_formulas_place_number\relax
+ \expandafter\strc_formulas_number % hm, looks ahead for []
+ \or
+ % nothing
+ \or
+ \glet\strc_formulas_place_number\relax
+ \expandafter\strc_formulas_number % hm, looks ahead for []
+ \fi}
+
+\def\strc_formulas_place_number_indeed
+ {\strc_formulas_place_number_in_box}
+
+\def\strc_formulas_place_number_in_box
+ {\dostarttagged\t!formulacaption\empty
+ \global\setbox\b_strc_formulas_number\naturalhbox{\strc_formulas_number_indeed}%
+ \dostoptagged}
+
+\def\strc_formulas_flush_number
+ {\ifcase\c_strc_formulas_mode
+ \ifzeropt\wd\b_strc_formulas_number
+ % nothing to be done
+ \orelse\ifx\p_location\v!left
+ \math_native_leqno{\box\b_strc_formulas_number}%
+ \else
+ \math_native_reqno{\box\b_strc_formulas_number}%
+ \fi
+ \fi}
+
+% todo
+
+\permanent\tolerant\protected\def\placenamedformula[#1]%
+ {\ifarguments
+ \expandafter\strc_formulase_place_named_nop
+ \else
+ \expandafter\strc_formulase_place_named_yes
+ \fi[#1]}
+
+\def\strc_formulase_place_named_yes[#1]#2%
+ {\setformulalistentry{#2}%
+ \placeformula[#1]}
+
+\def\strc_formulase_place_named_nop[#1]#2%
+ {\setformulalistentry{#2}%
+ \placeformula}
+
+\mutable\let\namedformulaentry\empty % \relax % this will become a key/value so that we can do bookmarks
+
+\permanent\protected\def\setformulalistentry#1%
+ {\gdef\namedformulaentry{#1}}
+
+\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/mkiv/strc-reg.mkxl b/tex/context/base/mkiv/strc-reg.mkxl
index 31f73ca69..97933ffb8 100644
--- a/tex/context/base/mkiv/strc-reg.mkxl
+++ b/tex/context/base/mkiv/strc-reg.mkxl
@@ -643,8 +643,11 @@
}%
\relax}
+% \def\strc_registers_limited_entry#1%
+% {\limitatetext{#1}\currentregistermaxwidth\unknown}%
+
\def\strc_registers_limited_entry#1%
- {\limitatetext{#1}\currentregistermaxwidth\unknown}%
+ {\limitated left \currentregistermaxwidth sentinel {\unknown} text {#1} freeze true\relax}
\aliased\let\limitedregisterentry\firstofoneargument
diff --git a/tex/context/base/mkiv/strc-ren.mkxl b/tex/context/base/mkiv/strc-ren.mkxl
new file mode 100644
index 000000000..2d553964b
--- /dev/null
+++ b/tex/context/base/mkiv/strc-ren.mkxl
@@ -0,0 +1,817 @@
+%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 \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Section Rendering}
+
+\unprotect
+
+\newbox\b_strc_rendering_head
+
+\newdimen\d_strc_rendering_local_leftoffset
+\newdimen\d_strc_rendering_local_rightoffset
+
+% 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}
+
+% \newtoks\everyheadstart % not used currently
+
+\protected\def\strc_rendering_initialize_style_and_color
+ {\ifconditional\headisdisplay
+ \expandafter\strc_rendering_initialize_style_and_color_display
+ \else
+ \expandafter\strc_rendering_initialize_style_and_color_inline
+ \fi}
+
+\protected\def\strc_rendering_initialize_style_and_color_display#1#2%
+ {\dontconvertfont
+ \edef\p_strc_rendering_interlinespace{\headparameter\c!interlinespace}%
+ \ifempty\p_strc_rendering_interlinespace
+ % here the interline space is only set when style sets no space
+ \setfalse\fontattributeisset % use the currentfontparameter state instead
+ \setfalse\interlinespaceisset
+ \useheadstyleandcolor\c!style\c!color\relax
+ \ifconditional\fontattributeisset \ifconditional\interlinespaceisset \else
+ \setupinterlinespace
+ \fi \fi
+ \setfalse\fontattributeisset
+ \useheadstyleandcolor#1#2\relax
+ \ifconditional\fontattributeisset \ifconditional\interlinespaceisset \else
+ \setupinterlinespace
+ \fi \fi
+ \else
+ % here the set interline space overloads any other set space in the style
+ \setfalse\fontattributeisset
+ \useheadstyleandcolor\c!style\c!color\relax
+ \ifconditional\fontattributeisset
+ \dosetupcheckedinterlinespace\p_strc_rendering_interlinespace
+ \fi
+ \setfalse\fontattributeisset
+ \useheadstyleandcolor#1#2\relax
+ \ifconditional\fontattributeisset
+ \dosetupcheckedinterlinespace\p_strc_rendering_interlinespace
+ \fi
+ \fi}
+
+\protected\def\strc_rendering_initialize_style_and_color_inline#1#2%
+ {\dontconvertfont
+ \setfalse\fontattributeisset
+ \useheadstyleandcolor\c!style\c!color\relax
+ \ifconditional\fontattributeisset
+ \updateraggedskips % \setupspacing
+ \fi
+ \setfalse\fontattributeisset
+ \useheadstyleandcolor#1#2\relax
+ \ifconditional\fontattributeisset
+ \updateraggedskips % \setupspacing
+ \fi}
+
+\let\currentstructurereferenceattribute\attributeunsetvalue
+
+\permanent\def\headreferenceattributes
+ {\iflocation
+ % \ctxlua{structures.lists.taglocation(\the\locationcount)}% maybe ... tags entry as used
+ attr \destinationattribute \currentstructureattribute
+ attr \referenceattribute \currentstructurereferenceattribute
+ % attr \internalattribute \locationcount
+ \fi}
+
+\permanent\def\setinlineheadreferenceattributes
+ {\ifconditional\headisdisplay \else \iflocation
+ \c_attr_destination\currentstructureattribute
+ \c_attr_reference \currentstructurereferenceattribute
+ % \c_attr_internal \locationcount
+ \fi \fi}
+
+\permanent\protected\def\docheckheadreference
+ {\edef\currentheadinteraction{\headparameter\c!interaction}%
+ \ifx\currentheadinteraction\v!list
+ % setuphead[<section>][interaction=list,...]
+ \strc_references_get_simple_reference{*\the\locationcount}%
+ \let\currentstructurereferenceattribute\currentreferenceattribute
+ \orelse\ifx\currentheadinteraction\v!reference
+ % setuphead[<section>][interaction=reference,...] start<section>[backreference=abc,...]
+ \edef\currentheadbackreference{\structurevariable\c!backreference}% weird, was references.backreference
+ \ifempty\currentheadbackreference \else
+ \strc_references_get_simple_reference\currentheadbackreference
+ \let\currentstructurereferenceattribute\currentreferenceattribute
+ \fi
+ \else
+ % maybe auto: backreference when given, else list
+ \fi}
+
+% a bit messy ... empty in place instead of self .. might change (or use special
+% whatsig (invisible user one)
+
+\protected\def\strc_rendering_place_head_text
+ {\strc_rendering_start_placement
+ \setheadmarking
+ \doresetstructureheadnumbercontent
+ \ifconditional\c_strc_sectioning_empty
+ \setbox\b_strc_rendering_head\hpack \headreferenceattributes to \zeropoint{\strut}%
+ \else
+ \docheckheadreference
+ \setbox\b_strc_rendering_head\hbox \headreferenceattributes
+ {\spac_grids_set_local_snapping{\headparameter\c!internalgrid}%
+ \doresetstructureheadnumbercontent
+ \useheadstyleparameter\c!style
+ \setinlineheadreferenceattributes
+ \strc_rendering_inject_text}%
+ \fi
+ \strc_rendering_stop_placement}
+
+\protected\def\strc_rendering_place_head_number_and_text
+ {\strc_rendering_start_placement
+ \setheadmarking
+ \doifelsetext\getheadnumber
+ \dosetstructureheadnumbercontent
+ \doresetstructureheadnumbercontent
+ \ifconditional\c_strc_sectioning_empty
+ \setbox\b_strc_rendering_head\hpack \headreferenceattributes to \zeropoint{\strut}%
+ \else % = needed
+ \docheckheadreference
+ \setbox\b_strc_rendering_head\hbox \headreferenceattributes
+ {\spac_grids_set_local_snapping{\headparameter\c!internalgrid}%
+ \useheadstyleparameter\c!style
+ \setinlineheadreferenceattributes
+ \strc_rendering_inject_number_and_text}%
+ \fi
+ \strc_rendering_stop_placement}
+
+\protected\def\strc_rendering_place_head_empty
+ {\hpack\headreferenceattributes{\getheadsyncs}}
+
+%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
+
+% helpers
+
+\permanent\protected\def\headhbox{\hbox\headreferenceattributes}
+\permanent\protected\def\headvbox{\vbox\headreferenceattributes}
+
+\permanent\protected\def\startlocalheadsetup{\bgroup\strc_rendering_initialize_spacing}
+\permanent\protected\def\stoplocalheadsetup {\egroup}
+
+\protected\def\strc_rendering_initialize_spacing
+ {\forgetall % local !
+ \edef\p_align{\headparameter\c!align}%
+ \ifempty\p_align \else
+ \setupalign[\p_align]%
+ \fi
+ \edef\p_tolerance{\headparameter\c!tolerance}%
+ \ifempty\p_tolerance \else
+ \setuptolerance[\p_tolerance]%
+ \fi
+ \edef\p_strut{\headparameter\c!strut}%
+ \ifx\p_strut\v!no
+ \setnostrut
+ \fi
+ \enforced\let\\\strc_rendering_shortcut_backslash}
+
+\protected\def\strc_rendering_shortcut_backslash
+ {\crlf
+ \strut
+ \ignorespaces}
+
+\def\strc_rendering_start_placement
+ {\bgroup
+ \setsystemmode\currenthead
+ \strc_rendering_initialize_alternatives
+ \strc_rendering_initialize_dimensions
+ \strc_rendering_initialize_line_state
+ \reseteverypar % needed indeed
+ \noindent % ipv \whitespace elders, na \forgetall !
+ \bgroup
+ \synctexpushline
+ \edef\p_aligntitle{\headparameter\c!aligntitle}%
+ \ifx\p_aligntitle\v!yes
+ \strc_rendering_initialize_hsize_local
+ \orelse\ifx\p_aligntitle\v!float
+ \strc_rendering_initialize_hsize_local
+ \else
+ \strc_rendering_initialize_hsize_global
+ \fi
+ \setfalse\inhibitmargindata % brrrr is set in forgetall
+ \dontcomplain
+ \postponenotes
+ \strc_rendering_initialize_interaction
+ % delayed
+ \let\localheadsetup \strc_rendering_initialize_spacing % historic name
+ \let\headsetupspacing\strc_rendering_initialize_spacing}
+
+\def\strc_rendering_initialize_interaction
+ {\resetinteractionparameter\c!style
+ \resetinteractionparameter\c!color
+ \resetinteractionparameter\c!contrastcolor}
+
+% \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
+
+\newdimen\d_strc_rendering_hang_height
+\newcount\n_strc_rendering_hang_lines
+
+\newdimen\d_strc_rendering_local_height
+\newdimen\d_strc_rendering_local_depth
+\newdimen\d_strc_rendering_local_lineheight
+
+\def\strc_rendering_initialize_line_state
+ {\global\d_strc_rendering_local_height\strutht
+ \global\d_strc_rendering_local_depth\strutdp
+ \global\d_strc_rendering_local_lineheight\lineheight}
+
+\def\strc_rendering_check_hang
+ {\begingroup
+ \openlineheight\d_strc_rendering_local_lineheight
+ \d_strc_rendering_hang_height\htdp\b_strc_rendering_head
+ \getnoflines\d_strc_rendering_hang_height
+ \normalexpanded{\endgroup\n_strc_rendering_hang_lines\the\numexpr\noflines-\plusone\relax}% brrr
+ \setbox\b_strc_rendering_head\hpack{\lower\n_strc_rendering_hang_lines\d_strc_rendering_hang_height\box\b_strc_rendering_head}%
+ \d_strc_rendering_hang_height\dimexpr\htdp\b_strc_rendering_head-\d_strc_rendering_local_height+\strutdp\relax
+ \ht\b_strc_rendering_head\strutht
+ \dp\b_strc_rendering_head\strutdp
+ \d_strc_rendering_local_depth\strutdp}
+
+\installcorenamespace{headplacementcheckhang}
+
+\setvalue{\??headplacementcheckhang\v!line }{\strc_rendering_check_hang
+ \n_strc_rendering_hang_lines\zerocount}
+\setvalue{\??headplacementcheckhang\v!broad }{\strc_rendering_check_hang
+ \getnoflines\d_strc_rendering_hang_height}
+\setvalue{\??headplacementcheckhang\v!fit }{\strc_rendering_check_hang
+ \getrawnoflines\d_strc_rendering_hang_height}
+\setvalue{\??headplacementcheckhang\v!none }{\n_strc_rendering_hang_lines\zerocount}
+\setvalue{\??headplacementcheckhang }{\n_strc_rendering_hang_lines\zerocount}
+\setvalue{\??headplacementcheckhang\s!unknown}{\strc_rendering_check_hang
+ \n_strc_rendering_hang_lines\numexpr\headparameter\c!hang-\plusone\relax}
+
+\def\strc_rendering_initialize_line_hang
+ {\ifconditional\headisdisplay
+ \expandnamespaceparameter\??headplacementcheckhang\headparameter\c!hang\s!unknown
+ \relax
+ \else
+ \n_strc_rendering_hang_lines \zerocount
+ \d_strc_rendering_hang_height\zeropoint
+ \fi}
+
+\def\strc_rendering_initialize_hsize_local
+ {\global\d_strc_rendering_local_leftoffset \leftskip
+ \global\d_strc_rendering_local_rightoffset\rightskip
+ % \forgetall
+ % \leftskip \d_strc_rendering_local_leftoffset % no stretch
+ % \rightskip\d_strc_rendering_local_rightoffset % no stretch
+ % \setlocalhsize
+ % \hsize\localhsize
+ % \forgetbothskips}
+ \scratchwidth\availablehsize
+ \forgetall
+ \hsize\scratchwidth}
+
+\def\strc_rendering_initialize_hsize_global
+ {\global\d_strc_rendering_local_leftoffset \zeropoint
+ \global\d_strc_rendering_local_rightoffset\zeropoint
+ \forgetall}
+
+% \def\strc_sectioning_stay_on_this_line
+% {\directcheckedvspacing{-\v!line,\v!samepage,\v!nowhite}%
+% \directcheckedvspacing\v!disable}
+%
+% we now use \ignoreparskip, so:
+
+\def\strc_sectioning_stay_on_this_line
+ {\directcheckedvspacing{-\v!line,\v!samepage}%
+ \directcheckedvspacing\v!disable}
+
+\def\strc_rendering_stop_placement
+ {\n_strc_rendering_hang_lines\zerocount
+ \ifconditional\headisdisplay
+ \strc_rendering_initialize_line_hang
+ % kind of special, we want to snap heads also according to local specs local
+ \setbox\b_strc_rendering_head\hbox
+ {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax
+ \box\b_strc_rendering_head
+ \getheadsyncs % a latelua why not in the box
+ }%
+ \ifgridsnapping
+ \applygridmethod
+ {\headparameter\c!grid}%
+ {\ifconditional\headisdisplay
+ \strc_rendering_initialize_style_and_color_display\c!textstyle\c!textcolor
+ \fi}%
+ {\box\b_strc_rendering_head}
+ \else
+ \box\b_strc_rendering_head
+ \fi
+ \flushnotes % new, not really needed
+ \endgraf
+ \ifvmode
+ \ifnum\n_strc_rendering_hang_lines>\zerocount
+ \dorecurse\n_strc_rendering_hang_lines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}% to be checked
+ \fi
+ \nointerlineskip
+ \dosomebreak\nobreak
+ \fi
+% \getheadsyncs % a latelua why not in the box
+ \else
+ % somehow this goes ok even when we push in the margin probably because we gobble pars
+ % in the process of collecting index entries etc
+ \strut
+ \flushnotes % new, here since we're in par mode
+ \unhbox\b_strc_rendering_head
+ \getheadsyncs % a latelua
+ \ifconditional\headissomewhere
+ \strc_sectioning_stay_on_this_line % test case: alternative=margintext and \startparagraph ..
+ \else
+ %\hskip\headnumberdistance\s!plus\headnumberdistance\s!minus.25\dimexpr\headnumberdistance\relax
+ \hskip\headtextdistance\relax
+ \strc_sectioning_inject_continuous_signal
+ \fi
+ \fi
+ \ifconditional\headisdisplay
+ \ifvmode
+ \ifgridsnapping % important, font related depth, see comment
+ \prevdepth\strutdp
+ \else
+ \prevdepth\d_strc_rendering_local_depth
+ \fi
+ \fi
+ \fi
+ \synctexpopline
+ \egroup
+ \egroup
+ \ifconditional\headisdisplay
+ \useindentnextparameter\headparameter
+ \orelse\ifconditional\headissomewhere
+ \ignoreparskip
+ \noindentation
+ \else
+ \ignoreparskip
+ \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
+
+% \dodefineheadplacement[sectiona][vertical]{#1->#2}
+% \dodefineheadplacement[sectionb][vertical]#1#2{#1->#2}
+%
+% \setuphead[section][alternative=sectiona]
+% \setuphead[subsection][alternative=sectionb]
+
+% \startsetups[\??headrenderings:\v!vertical:\v!sectiona]
+% ... there will be a more public namespace
+% \stopsetups
+
+\installcorenamespace{headplacementalternative}
+\installcorenamespace{headrenderings}
+\installcorenamespace{headalternative}
+
+\installcommandhandler \??headalternative {headalternative} \??headalternative % or just \??head
+
+\setupheadalternative
+ [%\c!width=\headparameter\c!width,
+ %\c!distance=\headparameter\c!distance,
+ \c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\currentheadalternative]
+
+\let\currentheadalternative \v!normal
+\let\currentheadrenderingsetup \empty
+\let\currentheadrenderingalternative\v!vertical
+
+\permanent\tolerant\protected\def\defineheadplacement[#1]#*[#2]%
+ {\doifelsenextbgroup
+ {\strc_rendering_define_placement_yes[#1][#2]}%
+ {\strc_rendering_define_placement_nop[#1][#2]}}
+
+\def\strc_rendering_define_placement_yes[#1][#2]%
+ {\defineheadalternative[#1][\c!alternative=#2,\c!renderingsetup=\??headrenderings:\v!command]%
+ \setuvalue{\??headplacementalternative#1}##1##2}
+
+\def\strc_rendering_define_placement_nop[#1][#2]%
+ {\defineheadalternative[#1][\c!alternative=#2,\c!renderingsetup=\??headrenderings:\v!command]%
+ \setuvalue{\??headplacementalternative#1}}
+
+% these can be used in setups:
+%
+% \headnumbercontent
+% \headtextcontent
+%
+% \headwidth
+% \headtextwidth
+% \headnumberdistance
+% \headnumberwidth
+% \headsetupspacing
+%
+% \headshownumber
+% \headisdisplay
+
+\let\headnumbercontent\empty
+\let\headtextcontent \empty
+
+\newdimen\headwidth
+\newdimen\headtextwidth
+\newskip \headtextdistance
+\newdimen\headnumberdistance
+\newdimen\headnumberwidth
+
+% \newconditional\headshownumber % defined already
+% \newconditional\headisdisplay % defined already
+
+\protected\def\strc_rendering_initialize_alternatives
+ {\edef\currentheadalternative{\headparameter\c!alternative}%
+ \ifcsname\currentheadalternativehash\s!parent\endcsname \else
+ \let\currentheadalternative\v!normal % cf. mkii
+ \fi
+ \edef\currentheadrenderingsetup{\headalternativeparameter\c!renderingsetup}%
+ \edef\currentheadrenderingalternative{\headalternativeparameter\c!alternative}%
+ \ifempty\currentheadrenderingalternative
+ \let\currentheadrenderingalternative\v!vertical
+ \fi
+ \ifx\currentheadrenderingalternative\v!horizontal
+ \global\setfalse\headisdisplay % global
+ \global\setfalse\headissomewhere % global
+ \orelse\ifx\currentheadrenderingalternative\v!somewhere
+ \global\setfalse\headisdisplay % global
+ \global\settrue \headissomewhere % global
+ \else
+ \global\settrue \headisdisplay % global
+ \global\setfalse\headissomewhere % global
+ \fi}
+
+\protected\def\strc_rendering_initialize_dimensions
+ {\headwidth \headparameter\c!width \relax % \zeropoint == unset
+ \headnumberwidth \headparameter\c!numberwidth \relax % \zeropoint == unset
+ \headnumberdistance\headparameter\c!distance \relax
+ \headtextdistance \headparameter\c!textdistance\relax
+ \headtextwidth \headparameter\c!textwidth \relax} % \zeropoint == unset
+
+\permanent\protected\def\headtextcontent
+ {\begingroup
+ \strc_rendering_initialize_style_and_color\c!textstyle\c!textcolor
+ \headparameter\c!commandbefore\relax
+ \ifcsname\currentheadhash\c!deeptextcommand\endcsname
+ %\expandafter\let\expandafter\deepstructuretitlecommand\csname\currentheadhash\c!deeptextcommand\endcsname
+ \expandafter\let\expandafter\deepstructuretitlecommand\lastnamedcs
+ \fi
+ \ifconditional\headisdisplay
+ % struts can be nilled with \setnostrut
+ \headparameter\c!textcommand{\setstrut\begstrut\getheadtitle\endstrut}%
+ \global\d_strc_rendering_local_height\strutht
+ \global\d_strc_rendering_local_depth\strutdp
+ \global\d_strc_rendering_local_lineheight\lineheight
+ \headparameter\c!commandafter\relax
+ \endgraf
+ \else
+ \headparameter\c!textcommand{\getheadtitle}%
+ \headparameter\c!commandafter\relax
+ \fi
+ \endgroup}
+
+\permanent\protected\def\headnumbercontent
+ {\begingroup
+ \strc_rendering_initialize_style_and_color\c!numberstyle\c!numbercolor
+ \ifcsname\currentheadhash\c!deepnumbercommand\endcsname
+ %\expandafter\let\expandafter\deepstructurenumbercommand\csname\currentheadhash\c!deepnumbercommand\endcsname
+ \expandafter\let\expandafter\deepstructurenumbercommand\lastnamedcs
+ \fi
+ \ifconditional\headisdisplay
+ % can be nilled with \setnostrut
+ \headparameter\c!numbercommand{\setstrut\begstrut\getheadnumber\endstrut}%
+ \else
+ \headparameter\c!numbercommand{\getheadnumber}%
+ \fi
+ \endgroup}
+
+\permanent\protected\def\fakedheadnumber{\vphantom{0}} % needed for mathplus
+
+% \permanent\protected\def\fakeheadnumbercontent
+% {\hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}}
+
+\permanent\protected\def\fakeheadnumbercontent
+ {\edef\p_hidenumber{\headparameter\c!hidenumber}%
+ \ifx\p_hidenumber\v!yes\else
+ \hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}%
+ \fi}
+
+\permanent\protected\def\strc_rendering_inject_number_and_text
+ {\edef\p_command{\headparameter\c!command}% assumes \protected definition
+ \ifempty\p_command
+ \directsetup\currentheadrenderingsetup
+ \else
+ \p_command\headnumbercontent\headtextcontent
+ \fi}
+
+\protected\def\strc_rendering_inject_text
+ {\edef\p_command{\headparameter\c!command}% assumes \protected definition
+ \ifempty\p_command
+ \directsetup\currentheadrenderingsetup
+ \else
+ \p_command\empty\headtextcontent
+ \fi}
+
+\startsetups[\??headrenderings:\v!command]
+ \csname\??headplacementalternative\currentheadalternative\endcsname \headnumbercontent \headtextcontent
+\stopsetups
+
+% obsolete
+%
+% \def\normalplacehead % hooks into \c!command
+% {\csname\??headplacementalternative\ifcsname\??headplacementalternative\currentheadalternative\endcsname\currentheadalternative\else\v!normal\fi\endcsname}
+
+\defineheadalternative
+ [\v!paragraph]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!paragraph]
+
+\startsetups[\??headrenderings:\v!paragraph]
+ \vbox {
+ \headsetupspacing
+ \begstrut
+ \ifconditional\headshownumber % \ifheadnumbercontent
+ \headnumbercontent
+ \hskip\headnumberdistance
+ \fi
+ \headtextcontent
+ }
+\stopsetups
+
+% \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
+
+\defineheadalternative
+ [\v!normal]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!normal]
+
+\startsetups[\??headrenderings:\v!normal]
+ \vbox {
+ \headsetupspacing
+ \ifconditional\headshownumber
+ \ifzeropt\headwidth \else
+ \ifzeropt\headnumberwidth
+ \ifzeropt\headtextwidth \else
+ \headnumberwidth\dimexpr\headwidth-\headtextwidth\relax
+ \fi
+ \else
+ \ifzeropt\headtextwidth
+ \headtextwidth\dimexpr\headwidth-\headnumberwidth\relax
+ \fi
+ \fi
+ \hsize\headwidth
+ \fi
+ \ifzeropt\headnumberwidth \else
+ \headnumberdistance\zeropoint
+ \fi
+ \setbox\scratchbox\hbox \ifzeropt\headnumberwidth\else to \headnumberwidth\fi{\headnumbercontent}
+ \scratchdimen\dimexpr\wd\scratchbox+\headnumberdistance\relax
+ \ifzeropt\headtextwidth \else
+ \hsize\dimexpr\scratchdimen+\headtextwidth\relax
+ \fi
+ \hangindent\scratchdimen
+ \hangafter \plusone
+ \noindent
+ \box\scratchbox
+ \hskip\headnumberdistance
+ \else
+ \ifzeropt\headtextwidth
+ \ifzeropt\headwidth \else
+ \hsize\headwidth
+ \fi
+ \else
+ \hsize\headtextwidth
+ \fi
+ \noindent
+ \fakeheadnumbercontent % will also be done in the other ones (force consistency with numbered)
+ \fi
+ \headtextcontent
+ }
+\stopsetups
+
+\defineheadalternative
+ [\v!inmargin]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!inmargin]
+
+\startsetups[\??headrenderings:\v!inmargin]
+ \vbox {
+ \headsetupspacing
+ \dontleavehmode % in case there is no strut, else side effects with llap
+ \begstrut % use one \strut here!
+ \ifconditional\headshownumber
+ \doifelsesomething {\headparameter\c!location} {
+ % kind of new
+ \margindata [\headparameter\c!location] {
+ \headnumbercontent
+ }
+ } {
+ % normal backward compatible variant
+ \llap {
+ \signalrightpage
+ \hbox {
+ \hfill
+ \headnumbercontent
+ \doifelserightpage{
+ \scratchdistance\leftmargindistance
+ } {
+ \scratchdistance\rightmargindistance
+ }
+ \hskip\dimexpr\d_strc_rendering_local_leftoffset+\scratchdistance\relax
+ }
+ }
+ }
+ \else
+ \fakeheadnumbercontent % will also be done in the other ones (force consistency with numbered)
+ \fi
+ \headtextcontent
+ }
+\stopsetups
+
+\defineheadalternative
+ [\v!margin]
+ [\v!inmargin]
+
+% \startsetups[\??headrenderings:\v!vertical:\v!margin]
+% \directsetup{\??headrenderings:\v!vertical:\v!inmargin}
+% \stopsetups
+
+%D This one is for head based numbering usage: foo 1.2 and so:
+
+\defineheadalternative
+ [\v!reverse]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!reverse]
+
+\startsetups[\??headrenderings:\v!reverse]
+ \vbox {
+ \headsetupspacing
+ \noindent
+ \begstrut
+ \setfalse\headisdisplay % so a kind of mix
+ \headtextcontent
+ \ifconditional\headshownumber
+ \kern\headnumberdistance
+ \headnumbercontent
+ \else
+ \fakeheadnumbercontent
+ \fi
+ \endstrut
+ }
+\stopsetups
+
+\defineheadalternative
+ [\v!middle]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!middle]
+
+\startsetups[\??headrenderings:\v!middle]
+ \vbox {
+ \headsetupspacing
+ \veryraggedcenter
+ \enforced\let\\\endgraf
+ \enforced\let\crlf\endgraf
+ \ifconditional\headshownumber
+ \strut
+ \headnumbercontent
+ \par
+ \else
+ \fakeheadnumbercontent
+ \fi
+ \begstrut
+ \headtextcontent
+ \endstrut
+ }
+\stopsetups
+
+\defineheadalternative
+ [\v!text]
+ [\c!alternative=\v!horizontal,
+ \c!renderingsetup=\??headrenderings:\v!text]
+
+\startsetups[\??headrenderings:\v!text]
+ \begingroup
+ \headsetupspacing % no stretch in distance
+ \ifconditional\headshownumber
+ \headnumbercontent
+ \kern\headnumberdistance
+ \fi
+ \begstrut
+ \headtextcontent
+ \endstrut
+ \endgroup
+\stopsetups
+
+% onder/boven lijnt het nummer op de onderste/bovenste regel uit van een meerregelige kop
+
+\defineheadalternative
+ [\v!bottom]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!bottom]
+
+\startsetups[\??headrenderings:\v!bottom]
+ \ifconditional\headshownumber
+ \setbox\scratchboxone\hbox {
+ \headnumbercontent
+ }
+ \setbox\scratchboxtwo\vbox {
+ \headsetupspacing
+ \advance\hsize-\wd\scratchboxone\relax
+ \headtextcontent
+ }
+ \hpack {
+ \box\scratchboxone
+ \hskip\headnumberdistance
+ \box\scratchboxtwo
+ }
+ \else
+ \vbox {
+ \headsetupspacing
+ \noindent
+ \headtextcontent
+ }
+ \fi
+\stopsetups
+
+\defineheadalternative
+ [\v!top]
+ [\c!alternative=\v!vertical,
+ \c!renderingsetup=\??headrenderings:\v!top]
+
+\startsetups[\??headrenderings:\v!top]
+ \ifconditional\headshownumber
+ \setbox\scratchboxone\hbox {
+ \headnumbercontent
+ }
+ \setbox\scratchboxtwo\vtop {
+ \headsetupspacing
+ \advance\hsize-\wd\scratchboxone\relax
+ \headtextcontent
+ }
+ \hpack {
+ \box\scratchboxone
+ \hskip\headnumberdistance
+ \box\scratchboxtwo
+ }
+ \else
+ \vtop{
+ \headsetupspacing
+ \noindent
+ \headtextcontent
+ }
+ \fi
+\stopsetups
+
+% see typo-mar.mkiv:
+%
+% \defineheadalternative
+% [\v!margintext]
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/strc-syn.mkxl b/tex/context/base/mkiv/strc-syn.mkxl
index 337f1d71a..d658e5467 100644
--- a/tex/context/base/mkiv/strc-syn.mkxl
+++ b/tex/context/base/mkiv/strc-syn.mkxl
@@ -240,8 +240,8 @@
\else
\frozen\instance\setuvalue{#1}{\definesynonym[\v!yes][#1]}% \name
\fi
- \ifnum\lastarguments>\plustwo
- \protected\frozen\instance\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
+ \ifparameter#3\or
+ \frozen\instance\protected\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
\fi
\edef\currentsynonym{#1}%
%
diff --git a/tex/context/base/mkiv/strc-tag.lmt b/tex/context/base/mkiv/strc-tag.lmt
new file mode 100644
index 000000000..11049abe0
--- /dev/null
+++ b/tex/context/base/mkiv/strc-tag.lmt
@@ -0,0 +1,615 @@
+if not modules then modules = { } end modules ['strc-tag'] = {
+ version = 1.001,
+ comment = "companion to strc-tag.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is rather experimental code. Tagging happens on the fly and there are two analysers
+-- involved: the pdf backend tagger and the exporter. They share data but there are subtle
+-- differences. Each tag carries a specification and these can be accessed by attribute (the
+-- end of the chain tag) or by so called fullname which is a tagname combined with a number.
+
+local type, next = type, next
+local insert, remove, unpack, concat, merge = table.insert, table.remove, table.unpack, table.concat, table.merge
+local find, topattern, format = string.find, string.topattern, string.format
+local lpegmatch, P, S, C, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Cc
+local allocate = utilities.storage.allocate
+local settings_to_hash = utilities.parsers.settings_to_hash
+local setmetatableindex = table.setmetatableindex
+
+local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end)
+
+local report_tags = logs.reporter("structure","tags")
+
+local attributes = attributes
+local structures = structures
+local implement = interfaces.implement
+
+local a_tagged = attributes.private('tagged')
+
+local unsetvalue = attributes.unsetvalue
+local codeinjections = backends.codeinjections
+
+local texgetattribute = tex.getattribute
+local texsetattribute = tex.setattribute
+
+local taglist = allocate() -- access by attribute
+local specifications = allocate() -- access by fulltag
+local labels = allocate()
+local stack = { }
+local chain = { }
+local ids = { }
+local enabled = false
+local tagcontext = { }
+local tagpatterns = { }
+local lasttags = { }
+local stacksize = 0
+local metadata = nil -- applied to the next element
+local documentdata = { }
+local extradata = false
+
+local tags = structures.tags
+tags.taglist = taglist -- can best be hidden
+tags.labels = labels
+tags.patterns = tagpatterns
+tags.specifications = specifications
+
+function tags.current()
+ if stacksize > 0 then
+ return stack[stacksize] -- maybe copy or proxy
+ end
+end
+
+-- Tags are internally stored as:
+--
+-- tag>number tag>number tag>number
+
+local p_splitter = C((1-S(">"))^1) * P(">") * C(P(1)^1)
+tagpatterns.splitter = p_splitter
+
+local properties = allocate { -- todo: more "record = true" to improve formatting
+
+ document = { pdf = "Div", nature = "display" },
+
+ division = { pdf = "Div", nature = "display" },
+ paragraph = { pdf = "P", nature = "mixed" },
+ p = { pdf = "P", nature = "mixed" },
+ construct = { pdf = "Span", nature = "inline" },
+ highlight = { pdf = "Span", nature = "inline" },
+
+ section = { pdf = "Sect", nature = "display" },
+ sectioncaption = { pdf = "Div", nature = "display", record = true },
+ sectiontitle = { pdf = "H", nature = "mixed" },
+ sectionnumber = { pdf = "H", nature = "mixed" },
+ sectioncontent = { pdf = "Div", nature = "display" },
+
+ itemgroup = { pdf = "L", nature = "display" },
+ item = { pdf = "LI", nature = "display" },
+ itemtag = { pdf = "Lbl", nature = "mixed" },
+ itemcontent = { pdf = "LBody", nature = "mixed" },
+ itemhead = { pdf = "Div", nature = "display" },
+ itembody = { pdf = "Div", nature = "display" },
+
+ description = { pdf = "Div", nature = "display" },
+ descriptiontag = { pdf = "Div", nature = "mixed" },
+ descriptioncontent = { pdf = "Div", nature = "mixed" },
+ descriptionsymbol = { pdf = "Span", nature = "inline" }, -- note reference
+
+ verbatimblock = { pdf = "Code", nature = "display" },
+ verbatimlines = { pdf = "Code", nature = "display" },
+ verbatimline = { pdf = "Code", nature = "mixed" },
+ verbatim = { pdf = "Code", nature = "inline" },
+
+ lines = { pdf = "Code", nature = "display" },
+ line = { pdf = "Code", nature = "mixed" },
+ linenumber = { pdf = "Span", nature = "inline" },
+
+ synonym = { pdf = "Span", nature = "inline" },
+ sorting = { pdf = "Span", nature = "inline" },
+
+ register = { pdf = "Div", nature = "display" },
+ registerlocation = { pdf = "Span", nature = "inline" },
+ registersection = { pdf = "Div", nature = "display" },
+ registertag = { pdf = "Span", nature = "mixed" },
+ registerentries = { pdf = "Div", nature = "display" },
+ registerentry = { pdf = "Div", nature = "display" },
+ registercontent = { pdf = "Span", nature = "mixed" },
+ registersee = { pdf = "Span", nature = "mixed" },
+ registerpages = { pdf = "Span", nature = "mixed" },
+ registerpage = { pdf = "Span", nature = "mixed" },
+ registerseparator = { pdf = "Span", nature = "inline" },
+ registerpagerange = { pdf = "Span", nature = "mixed" },
+
+ table = { pdf = "Table", nature = "display" },
+ tablerow = { pdf = "TR", nature = "display" },
+ tablecell = { pdf = "TD", nature = "mixed" },
+ tableheadcell = { pdf = "TH", nature = "mixed" },
+ tablehead = { pdf = "THEAD", nature = "display" },
+ tablebody = { pdf = "TBODY", nature = "display" },
+ tablefoot = { pdf = "TFOOT", nature = "display" },
+
+ tabulate = { pdf = "Table", nature = "display" },
+ tabulaterow = { pdf = "TR", nature = "display" },
+ tabulatecell = { pdf = "TD", nature = "mixed" },
+ tabulateheadcell = { pdf = "TH", nature = "mixed" },
+ tabulatehead = { pdf = "THEAD", nature = "display" },
+ tabulatebody = { pdf = "TBODY", nature = "display" },
+ tabulatefoot = { pdf = "TFOOT", nature = "display" },
+
+ list = { pdf = "TOC", nature = "display" },
+ listitem = { pdf = "TOCI", nature = "display" },
+ listtag = { pdf = "Lbl", nature = "mixed" },
+ listcontent = { pdf = "P", nature = "mixed" },
+ listdata = { pdf = "P", nature = "mixed" },
+ listpage = { pdf = "Reference", nature = "mixed" },
+ listtext = { pdf = "Span", nature = "inline" },
+
+ delimitedblock = { pdf = "BlockQuote", nature = "display" },
+ delimited = { pdf = "Quote", nature = "inline" },
+ delimitedcontent = { pdf = "Span", nature = "inline" },
+ delimitedsymbol = { pdf = "Span", nature = "inline" },
+ subsentence = { pdf = "Span", nature = "inline" },
+ subsentencecontent = { pdf = "Span", nature = "inline" },
+ subsentencesymbol = { pdf = "Span", nature = "inline" },
+
+ label = { pdf = "Span", nature = "mixed" },
+ number = { pdf = "Span", nature = "mixed" },
+
+ float = { pdf = "Div", nature = "display" }, -- Figure
+ floatcaption = { pdf = "Caption", nature = "mixed" },
+ floatlabel = { pdf = "Span", nature = "inline" },
+ floatnumber = { pdf = "Span", nature = "inline" },
+ floattext = { pdf = "Span", nature = "mixed" },
+ floatcontent = { pdf = "P", nature = "mixed" },
+
+ image = { pdf = "P", nature = "mixed" },
+ mpgraphic = { pdf = "P", nature = "mixed" },
+
+ formulaset = { pdf = "Div", nature = "display" },
+ formula = { pdf = "Div", nature = "display" }, -- Formula
+ formulacaption = { pdf = "Span", nature = "mixed" },
+ formulalabel = { pdf = "Span", nature = "mixed" },
+ formulanumber = { pdf = "Span", nature = "mixed" },
+ formulacontent = { pdf = "P", nature = "display" },
+ subformula = { pdf = "Div", nature = "display" },
+
+ link = { pdf = "Link", nature = "inline" },
+ reference = { pdf = "Span", nature = "inline" },
+
+ margintextblock = { pdf = "Span", nature = "inline" },
+ margintext = { pdf = "Span", nature = "inline" },
+ marginanchor = { pdf = "Span", nature = "inline" },
+
+ math = { pdf = "Div", nature = "inline" }, -- no display
+ mn = { pdf = "Span", nature = "mixed" },
+ mi = { pdf = "Span", nature = "mixed" },
+ mo = { pdf = "Span", nature = "mixed" },
+ ms = { pdf = "Span", nature = "mixed" },
+ mrow = { pdf = "Span", nature = "display" },
+ msubsup = { pdf = "Span", nature = "display" },
+ msub = { pdf = "Span", nature = "display" },
+ msup = { pdf = "Span", nature = "display" },
+ merror = { pdf = "Span", nature = "mixed" },
+ munderover = { pdf = "Span", nature = "display" },
+ munder = { pdf = "Span", nature = "display" },
+ mover = { pdf = "Span", nature = "display" },
+ mtext = { pdf = "Span", nature = "mixed" },
+ mfrac = { pdf = "Span", nature = "display" },
+ mroot = { pdf = "Span", nature = "display" },
+ msqrt = { pdf = "Span", nature = "display" },
+ mfenced = { pdf = "Span", nature = "display" },
+ maction = { pdf = "Span", nature = "display" },
+
+ mstacker = { pdf = "Span", nature = "display" }, -- these are only internally used
+ mstackertop = { pdf = "Span", nature = "display" }, -- these are only internally used
+ mstackerbot = { pdf = "Span", nature = "display" }, -- these are only internally used
+ mstackermid = { pdf = "Span", nature = "display" }, -- these are only internally used
+
+ mtable = { pdf = "Table", nature = "display" }, -- might change
+ mtr = { pdf = "TR", nature = "display" }, -- might change
+ mtd = { pdf = "TD", nature = "display" }, -- might change
+
+ ignore = { pdf = "Span", nature = "mixed" }, -- used internally
+ private = { pdf = "Span", nature = "mixed" }, -- for users (like LS) when they need it
+ metadata = { pdf = "Div", nature = "display" },
+ metavariable = { pdf = "Span", nature = "mixed" },
+
+ mid = { pdf = "Span", nature = "inline" },
+ sub = { pdf = "Span", nature = "inline" },
+ sup = { pdf = "Span", nature = "inline" },
+ subsup = { pdf = "Span", nature = "inline" },
+
+ combination = { pdf = "Span", nature = "display" },
+ combinationpair = { pdf = "Span", nature = "display" },
+ combinationcontent = { pdf = "Span", nature = "mixed" },
+ combinationcaption = { pdf = "Span", nature = "mixed" },
+
+ publications = { pdf = "Div", nature = "display" },
+ publication = { pdf = "Div", nature = "mixed" },
+ pubfld = { pdf = "Span", nature = "inline" },
+
+ block = { pdf = "Div", nature = "display" },
+ userdata = { pdf = "Div", nature = "display" },
+
+}
+
+tags.properties = properties
+
+local patterns = setmetatableindex(function(t,tag)
+ local v = topattern("^" .. tag .. ">")
+ t[tag] = v
+ return v
+end)
+
+function tags.locatedtag(tag)
+ local attribute = texgetattribute(a_tagged)
+ if attribute >= 0 then
+ local specification = taglist[attribute]
+ if specification then
+ local taglist = specification.taglist
+ local pattern = patterns[tag]
+ for i=#taglist,1,-1 do
+ local t = taglist[i]
+ if find(t,pattern) then
+ return t
+ end
+ end
+ end
+ else
+ -- enabled but not auto
+ end
+ return false -- handy as bogus index
+end
+
+function structures.atlocation(str)
+ local specification = taglist[texgetattribute(a_tagged)]
+ if specification then
+ if list then
+ local taglist = specification.taglist
+ local pattern = patterns[str]
+ for i=#list,1,-1 do
+ if find(list[i],pattern) then
+ return true
+ end
+ end
+ end
+ end
+end
+
+function tags.setproperty(tag,key,value)
+ local p = properties[tag]
+ if p then
+ p[key] = value
+ else
+ properties[tag] = { [key] = value }
+ end
+end
+
+function tags.setaspect(key,value)
+ local tag = chain[stacksize]
+ if tag then
+ local p = properties[tag]
+ if p then
+ p[key] = value
+ else
+ properties[tag] = { [key] = value }
+ end
+ end
+end
+
+function tags.registermetadata(data)
+ local d = settings_to_hash(data)
+ if #chain > 1 then
+ if metadata then
+ merge(metadata,d)
+ else
+ metadata = d
+ end
+ else
+ merge(documentdata,d)
+ end
+end
+
+function tags.getmetadata()
+ return documentdata or { }
+end
+
+function tags.registerextradata(name,serializer)
+ if type(serializer) == "function" then
+ if extradata then
+ extradata[name] = serializer
+ else
+ extradata = { [name] = serializer }
+ end
+ end
+end
+
+function tags.getextradata()
+ return extradata
+end
+
+function tags.start(tag,specification)
+ if not enabled then
+ codeinjections.enabletags()
+ enabled = true
+ end
+ --
+ labels[tag] = tag -- can go away
+ --
+ local attribute = #taglist + 1
+ local tagindex = (ids[tag] or 0) + 1
+ --
+ local completetag = tag .. ">" .. tagindex
+ --
+ ids[tag] = tagindex
+ lasttags[tag] = tagindex
+ stacksize = stacksize + 1
+ --
+ chain[stacksize] = completetag
+ stack[stacksize] = attribute
+ tagcontext[tag] = completetag
+ --
+ local tagnesting = { unpack(chain,1,stacksize) } -- a copy so we can add actualtext
+ --
+ if specification then
+ specification.attribute = attribute
+ specification.tagindex = tagindex
+ specification.taglist = tagnesting
+ specification.tagname = tag
+ if metadata then
+ specification.metadata = metadata
+ metadata = nil
+ end
+ local userdata = specification.userdata
+ if userdata == "" then
+ specification.userdata = nil
+ elseif type(userdata) == "string" then
+ specification.userdata = settings_to_hash(userdata)
+ end
+ local detail = specification.detail
+ if detail == "" then
+ specification.detail = nil
+ end
+ local parents = specification.parents
+ if parents == "" then
+ specification.parents = nil
+ end
+ else
+ specification = {
+ attribute = attribute,
+ tagindex = tagindex,
+ taglist = tagnesting,
+ tagname = tag,
+ metadata = metadata,
+ }
+ metadata = nil
+ end
+ --
+ taglist[attribute] = specification
+ specifications[completetag] = specification
+ --
+ if completetag == "document>1" then
+ specification.metadata = documentdata
+ end
+ --
+ texsetattribute(a_tagged,attribute)
+ return attribute
+end
+
+function tags.restart(attribute)
+ stacksize = stacksize + 1
+ if type(attribute) == "number" then
+ local taglist = taglist[attribute].taglist
+ chain[stacksize] = taglist[#taglist]
+ else
+ chain[stacksize] = attribute -- a string
+ attribute = #taglist + 1
+ taglist[attribute] = { taglist = { unpack(chain,1,stacksize) } }
+ end
+ stack[stacksize] = attribute
+ texsetattribute(a_tagged,attribute)
+ return attribute
+end
+
+function tags.stop()
+ if stacksize > 0 then
+ stacksize = stacksize - 1
+ end
+ local t = stack[stacksize]
+ if not t then
+ if trace_tags then
+ report_tags("ignoring end tag, previous chain: %s",stacksize > 0 and concat(chain," ",1,stacksize) or "none")
+ end
+ t = unsetvalue
+ end
+ texsetattribute(a_tagged,t)
+ return t
+end
+
+function tags.getid(tag,detail)
+ return ids[tag] or "?"
+end
+
+function tags.last(tag)
+ return lasttags[tag] -- or false
+end
+
+function tags.lastinchain(tag)
+ if tag and tag ~= "" then
+ return tagcontext[tag]
+ else
+ return chain[stacksize]
+ end
+end
+
+local strip = C((1-S(">"))^1)
+
+function tags.elementtag()
+ local fulltag = chain[stacksize]
+ if fulltag then
+ return lpegmatch(strip,fulltag)
+ end
+end
+
+function tags.strip(fulltag)
+ return lpegmatch(strip,fulltag)
+end
+
+function tags.setuserproperties(tag,list)
+ if not list or list == "" then
+ tag, list = chain[stacksize], tag
+ else
+ tag = tagcontext[tag]
+ end
+ if tag then -- an attribute now
+ local l = settings_to_hash(list)
+ local s = specifications[tag]
+ if s then
+ local u = s.userdata
+ if u then
+ for k, v in next, l do
+ u[k] = v
+ end
+ else
+ s.userdata = l
+ end
+ else
+ -- error
+ end
+ end
+end
+
+function tags.handler(head) -- we need a dummy
+ return head, false
+end
+
+statistics.register("structure elements", function()
+ if enabled then
+ if stacksize > 0 then
+ return format("%s element chains identified, open chain: %s ",#taglist,concat(chain," => ",1,stacksize))
+ else
+ return format("%s element chains identified",#taglist)
+ end
+ end
+end)
+
+directives.register("backend.addtags", function(v)
+ if not enabled then
+ codeinjections.enabletags()
+ enabled = true
+ end
+end)
+
+-- interface
+
+local starttag = tags.start
+
+implement {
+ name = "strc_tags_start",
+ public = true,
+ protected = true,
+ actions = starttag,
+ arguments = "argument",
+}
+
+implement {
+ name = "strc_tags_stop",
+ public = true,
+ protected = true,
+ actions = tags.stop,
+}
+
+implement {
+ name = "strc_tags_start_userdata",
+ public = true,
+ protected = true,
+ actions = function(tag,userdata) starttag(tag,{ userdata = userdata }) end,
+ arguments = { "optional", "optional" },
+}
+
+implement {
+ name = "strc_tags_start_detail",
+ public = true,
+ protected = true,
+ actions = function(tag,detail) starttag(tag,{ detail = detail }) end,
+ arguments = "2 arguments",
+}
+
+implement {
+ name = "strc_tags_start_ignore",
+ public = true,
+ protected = true,
+ actions = function(detail) starttag("ignore",{ detail = detail }) end,
+ arguments = { "argument" },
+}
+
+implement {
+ name = "strc_tags_start_chained",
+ public = true,
+ protected = true,
+ actions = function(tag,detail,parents) starttag(tag,{ detail = detail, parents = parents }) end,
+ arguments = "3 arguments",
+}
+
+implement {
+ name = "strc_tags_set_aspect",
+ public = true,
+ protected = true,
+ actions = tags.setaspect,
+ arguments = "2 arguments"
+}
+
+implement {
+ name = "settagproperty",
+ actions = tags.setproperty,
+ arguments = "3 arguments"
+}
+
+implement {
+ name = "setelementbackendtag",
+ public = true,
+ protected = true,
+ actions = tags.setproperty,
+ arguments = { "optional", "'backend'", "optional" },
+}
+
+implement {
+ name = "setelementnature",
+ public = true,
+ protected = true,
+ actions = tags.setproperty,
+ arguments = { "optional", "'nature'", "optional" },
+}
+
+implement {
+ name = "strc_tags_get_element_tag",
+ public = true,
+ protected = true,
+ actions = { tags.elementtag, context }
+}
+
+implement {
+ name = "strc_tags_set_element_user_properties",
+ public = true,
+ protected = true,
+ actions = tags.setuserproperties,
+ arguments = { "optional", "optional" },
+}
+
+implement {
+ name = "doifelseinelement",
+ public = true,
+ protected = true,
+ actions = { structures.atlocation, commands.testcase },
+ arguments = "argument",
+}
+
+implement {
+ name = "settaggedmetadata",
+ public = true,
+ protected = true,
+ actions = tags.registermetadata,
+ arguments = "optional",
+}
diff --git a/tex/context/base/mkiv/strc-tag.mkxl b/tex/context/base/mkiv/strc-tag.mkxl
new file mode 100644
index 000000000..ebe1f4c2f
--- /dev/null
+++ b/tex/context/base/mkiv/strc-tag.mkxl
@@ -0,0 +1,531 @@
+%D \module
+%D [ file=strc-tag,
+%D version=2010.07.16,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Tags,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% labels: no language needed
+% key/values and other names might change (and probably will)
+
+\writestatus{loading}{ConTeXt Structure Macros / Tags}
+
+\registerctxluafile{strc-tag}{autosuffix}
+
+\unprotect
+
+%D Eventually these labels will either move to the modules where they're used, or
+%D they will en dup in mult-tag.
+
+\definetagconstant{document} % Div
+
+\definetagconstant{division} % Div
+\definetagconstant{paragraph} % P
+\definetagconstant{p} % P
+\definetagconstant{construct} % Span
+\definetagconstant{highlight} % Span
+
+\definetagconstant{section} % Sect
+\definetagconstant{sectioncaption} % Div
+\definetagconstant{sectiontitle} % H
+\definetagconstant{sectionnumber} % H
+\definetagconstant{sectioncontent} % Div
+
+\definetagconstant{itemgroup} % L
+\definetagconstant{item} % Li
+\definetagconstant{itemtag} % Lbl
+\definetagconstant{itemcontent} % LBody
+\definetagconstant{itemhead} % Div
+\definetagconstant{itembody} % Div
+
+\definetagconstant{description} % Li
+\definetagconstant{descriptiontag} % Lbl
+\definetagconstant{descriptioncontent} % LBody
+\definetagconstant{descriptionsymbol} % Span
+
+\aliastagconstant{construction} {description}
+\aliastagconstant{constructiontag} {descriptiontag}
+\aliastagconstant{constructioncontent}{descriptioncontent}
+\aliastagconstant{constructionsymbol} {descriptionsymbol}
+
+\definetagconstant{verbatimblock} % Code
+\definetagconstant{verbatimlines} % Code
+\definetagconstant{verbatimline} % Code
+\definetagconstant{verbatim} % Code
+
+\definetagconstant{lines} % Code
+\definetagconstant{line} % Code
+\definetagconstant{linenumber} % Span
+
+\definetagconstant{sorting} % Span
+\definetagconstant{synonym} % Span
+
+\definetagconstant{register} % Div
+\definetagconstant{registerlocation} % Span
+\definetagconstant{registersection} % Div
+\definetagconstant{registertag} % Span
+\definetagconstant{registerentries} % Div
+\definetagconstant{registerentry} % Span
+\definetagconstant{registercontent} % Span
+\definetagconstant{registersee} % Span
+\definetagconstant{registerpages} % Span
+\definetagconstant{registerpage} % Span
+\definetagconstant{registerpagerange} % Span
+\definetagconstant{registerfrompage} % Span
+\definetagconstant{registertopage} % Span
+\definetagconstant{registerseparator} % Span
+
+\definetagconstant{table} % Table
+\definetagconstant{tablerow} % TR
+\definetagconstant{tablecell} % TD
+\definetagconstant{tableheadcell} % TH
+\definetagconstant{tablehead} % THEAD
+\definetagconstant{tablebody} % TBODY
+\definetagconstant{tablefoot} % TFOOT
+
+\definetagconstant{tabulate} % Table
+\definetagconstant{tabulaterow} % TR
+\definetagconstant{tabulatecell} % TD
+\definetagconstant{tabulateheadcell} % TH
+\definetagconstant{tabulatehead} % THEAD
+\definetagconstant{tabulatebody} % TBODY
+\definetagconstant{tabulatefoot} % TFOOT
+
+\definetagconstant{math} % math
+\definetagconstant{mtable} % Table
+\definetagconstant{mtr} % TR
+\definetagconstant{mtd} % TD
+\definetagconstant{maction} %
+\definetagconstant{mstacker}
+\definetagconstant{mstackertop}
+\definetagconstant{mstackermid}
+\definetagconstant{mstackerbot}
+
+\aliastagconstant{mtablerow} {mtr}
+\aliastagconstant{mtablecell}{mtd}
+
+\definetagconstant{munderover} % special cases
+\definetagconstant{munder} % special cases
+\definetagconstant{mover} % special cases
+
+\definetagconstant{list} % TOC
+\definetagconstant{listitem} % TOCI
+\definetagconstant{listtag} % Lbl
+\definetagconstant{listcontent} % P
+\definetagconstant{listdata} % P
+\definetagconstant{listpage} % Reference
+\definetagconstant{listtext} % Span
+
+\definetagconstant{delimited} % BlockQuote
+%definetagconstant{delimited} % Quote
+\definetagconstant{delimitedsymbol} % Span
+\definetagconstant{delimitedcontent} % Span
+
+\aliastagconstant{delimitedblock}{delimited}
+
+\definetagconstant{subsentence} % Span
+\definetagconstant{subsentencecontent} % Span
+\definetagconstant{subsentencesymbol} % Span
+
+\definetagconstant{float} % Div
+\definetagconstant{floatcaption} % Caption
+\definetagconstant{floatlabel} % Span
+\definetagconstant{floattext} % Span
+\definetagconstant{floatnumber} % Span
+\definetagconstant{floatcontent} % P
+
+\definetagconstant{image} % P
+
+\definetagconstant{mpgraphic} % P
+
+\definetagconstant{formulaset} % Div
+\definetagconstant{formula} % Div
+\definetagconstant{formulacaption} % Span
+\definetagconstant{formulalabel} % Span
+\definetagconstant{formulanumber} % P
+\definetagconstant{formulacontent} % P
+\definetagconstant{subformula} % Div
+
+\definetagconstant{link} % Link
+\definetagconstant{reference} % Span
+
+\definetagconstant{margintext} % Span
+\definetagconstant{margintextblock} % Div
+\definetagconstant{marginanchor} % Span
+
+% we might opt for verbose variants so this is experimental:
+
+\definetagconstant{label} % Span
+\definetagconstant{number} % Span
+
+\definetagconstant{ignore} % Span
+\definetagconstant{private} % Span
+
+\definetagconstant{mid} % Span
+\definetagconstant{sub} % Span
+\definetagconstant{sup} % Span
+\definetagconstant{subsup} % Span
+
+\definetagconstant{unit} % Span
+\definetagconstant{quantity} % Span
+%definetagconstant{number} % Span
+
+\definetagconstant{combination} % Span
+\definetagconstant{combinationpair} % Span
+\definetagconstant{combinationcontent} % Span
+\definetagconstant{combinationcaption} % Span
+
+\definetagconstant{publications} % Span
+\definetagconstant{publication} % Span
+\definetagconstant{pubfld} % Span
+
+\definetagconstant{block} % Div
+\definetagconstant{userdata} % Div
+
+% \setuptaglabeltext
+% [en]
+% [\t!document=document]
+
+% the real code
+
+\definesystemattribute[tagged][public]
+\definesystemattribute[image] [public]
+
+% \setelementbackendtag [#1][#2] % define at the lua end
+% \setelementnature [#1][#2] % define at the lua end
+
+\permanent\protected\def\ignoretagsinexport[#1]{\clf_ignoretagsinexport{#1}} % todo: public implementor
+
+\installcorenamespace{tagging}
+
+\installsetuponlycommandhandler \??tagging {tagging}
+
+\def\strc_tags_report_hyphen#1%
+ {\writestatus\m!languages{setting #1 to U+00AD}}
+
+\protected\def\strc_tags_patch_hyphen
+ {% for the moment here
+ \ifnum\languageparameter\s!lefthyphenchar>\zerocount
+ \setuplanguage[\s!default][\s!lefthyphenchar="AD]%
+ \strc_tags_report_hyphen\s!lefthyphenchar
+ \fi
+ \ifnum\languageparameter\s!righthyphenchar>\zerocount
+ \setuplanguage[\s!default][\s!righthyphenchar="AD]%
+ \strc_tags_report_hyphen\s!righthyphenchar
+ \fi
+ \let\strc_tags_report_hyphen\gobbleoneargument}
+
+% It makes no sense to have labels ... maybe some day as a last 'replace' in the export
+% which might be more efficient then ... okay, we now cannot overload but who cares.
+
+% \strc_tags_start_userdata % defined at the lua end
+% \strc_tags_stop % defined at the lua end
+% \strc_tags_set_aspect % defined at the lua end
+% \strc_tags_get_element_tag % defined at the lua end
+% \strc_tags_set_element_user_properties % defined at the lua end
+
+\permanent\protected\def\strc_tags_element_start_yes
+ {\iftrialtypesetting
+ \expandafter\gobbletwooptionals
+ \else
+ \expandafter\strc_tags_start_userdata
+ \fi}
+
+\permanent\protected\def\strc_tags_element_stop_yes
+ {\iftrialtypesetting
+ % nothing
+ \else
+ \expandafter\strc_tags_stop
+ \fi}
+
+\protected\def\strc_tags_enable_elements
+ {\strc_tags_patch_hyphen
+ \enforced\let\startelement \strc_tags_element_start_yes
+ \enforced\let\stopelement \strc_tags_element_stop_yes
+ \enforced\let\dosettagproperty\strc_tags_set_aspect}
+
+\protected\def\strc_tags_disable_elements
+ {\enforced\let\startelement \gobbletwooptionals
+ \enforced\let\stopelement \relax
+ \enforced\let\dosettagproperty\gobbletwoarguments}
+
+% beware: making these unexpanded spoils tables (noalign problem)
+
+\def\strc_tags_enabled_start_no_detail
+ {\iftrialtypesetting
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\strc_tags_start
+ \fi}
+
+\def\strc_tags_enabled_start_detail
+ {\iftrialtypesetting
+ \expandafter\gobbletwoarguments
+ \else
+ \expandafter\strc_tags_start_detail
+ \fi}
+
+\def\strc_tags_enabled_start_chained
+ {\iftrialtypesetting
+ \expandafter\gobblethreearguments
+ \else
+ \expandafter\strc_tags_start_chained_indeed
+ \fi}
+
+\def\strc_tags_enabled_start_ignore
+ {\iftrialtypesetting
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\strc_tags_start_ignore
+ \fi}
+
+\def\strc_tags_enabled_stop
+ {\iftrialtypesetting
+ % do nothing
+ \else
+ \expandafter\strc_tags_stop
+ \fi}
+
+\def\strc_tags_start_chained_indeed#1#2#3{\strc_tags_start_chained{#1}{#2}{\getcurrentparentchain#3{#2}}}
+
+\newconditional\c_strc_tags_enabled
+
+\permanent\let\dotaggedplaceholder\empty
+
+\immutable\chardef\strc_tags_placeholder_char\zerocount % "FFFC
+
+\protected\def\strc_tags_enable_indeed
+ {\enforced\let\dotaggedplaceholder \strc_tags_placeholder_char
+ \enforced\let\dostarttagged \strc_tags_enabled_start_detail
+ \enforced\let\dostarttaggednodetail\strc_tags_enabled_start_no_detail
+ \enforced\let\dostarttaggedchained \strc_tags_enabled_start_chained
+ \enforced\let\dostoptagged \strc_tags_enabled_stop
+ \enforced\let\dostartignoretagging \strc_tags_enabled_start_ignore
+ \enforced\let\dostopignoretagging \strc_tags_stop}
+
+\protected\def\strc_tags_enable
+ {% once enable one is toast
+ \global\settrue\c_strc_tags_enabled
+ % and gets:
+ \strc_tags_enable_indeed}
+
+\protected\def\strc_tags_disable
+ {\ifconditional\c_strc_tags_enabled
+ % so now all are artifacts
+ \enforced\let\dotaggedplaceholder \strc_tags_placeholder_char
+ \enforced\let\dostarttagged \gobbletwoarguments
+ \enforced\let\dostarttaggednodetail\gobbleoneargument
+ \enforced\let\dostarttaggedchained \gobblethreearguments
+ \enforced\let\dostoptagged \donothing
+ \else
+ % initial
+ \enforced\let\dotaggedplaceholder \empty
+ \enforced\let\dostarttagged \gobbletwoarguments
+ \enforced\let\dostarttaggednodetail\gobbleoneargument
+ \enforced\let\dostarttaggedchained \gobblethreearguments
+ \enforced\let\dostoptagged \donothing
+ \enforced\let\dostartignoretagging \donothing
+ \enforced\let\dostopignoretagging \donothing
+ \fi}
+
+% for luigi (beware: fully expandable):
+
+\protected\def\strc_tags_setup_element_user_properties
+ {\iftrialtypesetting
+ \expandafter\gobbletwooptionals
+ \else
+ \expandafterstrc_set_element_user_properties
+ \fi}
+
+\protected\def\strc_tags_enable_properties
+ {\let\getelementtag \strc_tags_get_element_tag
+ \let\setupelementuserproperties\strc_tags_set_element_user_properties}
+
+\protected\def\strc_tags_disable_properties
+ {\let\getelementtag \donothing
+ \let\setupelementuserproperties\gobbletwooptionals}
+
+%D The triggers:
+
+\newtoks\everyenableelements
+\newtoks\everydisableelements
+
+\appendtoks
+ \strc_tags_enable_elements
+ \strc_tags_enable_properties
+ \doifelse{\taggingparameter\c!method}\v!auto\strc_tags_enable\strc_tags_disable
+\to \everyenableelements
+
+\appendtoks
+ \strc_tags_disable_elements
+ \strc_tags_disable_properties
+ \strc_tags_disable
+\to \everydisableelements
+
+\appendtoks
+ \doifelse{\taggingparameter\c!state}\v!start{\the\everyenableelements}{\the\everydisableelements}%
+\to \everysetuptagging
+
+\permanent\protected\def\forgettagging
+ {\c_attr_tagged\attributeunsetvalue}
+
+\setuptagging
+ [\c!state=\v!stop,
+ \c!method=\v!auto]
+
+% Cf suggestion by Wolfgang we now have named paragraphs. Watch out, the content
+% is grouped but only when we have an instance.
+%
+% \defineparagraph[red] [color=red]
+% \defineparagraph[bold][style=bold]
+%
+% \startparagraph \input ward \stopparagraph
+% \startparagraph[red] \input ward \stopparagraph
+% \startparagraph[bold] \input ward \stopparagraph
+
+\installcorenamespace {paragraph}
+\installcommandhandler \??paragraph {paragraph} \??paragraph
+
+\setupparagraph % someday maybe also strut (beg/end) and align
+ [\c!color=,
+ \c!style=]
+
+\ifdefined\dotagparagraph \else \let\dotagparagraph\gobbleoneargument \fi
+
+\permanent\tolerant\protected\def\startparagraph[#1]#*[#2]%
+ {\endgraf % we end before the group
+ \begingroup
+ \ifarguments
+ \let\currentparagraph\empty
+ \or
+ \ifhastok={#1}%
+ \let\currentparagraph\empty
+ \setupcurrentparagraph[#1]
+ \else
+ \edef\currentparagraph{#1}%
+ \fi
+ \or
+ \edef\currentparagraph{#1}%
+ \setupcurrentparagraph[#2]%
+ \fi
+ \useparagraphstyleandcolor\c!style\c!color
+ \usealignparameter\paragraphparameter
+ \usesetupsparameter\paragraphparameter
+ \dostarttagged\t!paragraph\currentparagraph
+ \dotagparagraph{\paragraphparameter\c!align}}
+
+\permanent\protected\def\stopparagraph
+ {\dostoptagged
+ \endgraf % we end inside the group
+ \endgroup}
+
+\aliased\let\startpar\startparagraph
+\aliased\let\stoppar \stopparagraph
+
+\def\strc_tags_document_start_indeed
+ {\glet\strc_tags_document_start_indeed\relax
+ \dostarttagged\t!document\empty}
+
+\def\strc_tags_document_stop_indeed
+ {\glet\strc_tags_document_stop_indeed\relax
+ \dostoptagged}
+
+\appendtoks
+ \strc_tags_document_start_indeed % here because otherwise products don't get a root (starttext before env)
+\to \everyenableelements
+
+% \appendtoks
+% \strc_tags_document_start_indeed
+% \to \everystarttext
+
+\appendtoks
+ \strc_tags_document_stop_indeed
+\to \everystoptext
+
+\appendtoks
+ \strc_tags_disable_elements
+ \strc_tags_disable
+\to \everybeforepagebody
+
+% This doesn't work well either, so instead we handle the ornaments in the tagging
+% in a different way (see attr -> false code).
+
+% \appendtoks
+% \dostartignoretagging
+% \to \everybeforepagebody
+%
+% \appendtoks
+% \dostopignoretagging
+% \to \everyafterpagebody
+
+% \doifelseinelement{structure:section} {yes} {no}
+% \doifelseinelement{structure:chapter} {yes} {no}
+% \doifelseinelement{division:*-structure:chapter} {yes} {no}
+
+\aliased\let\doifinelementelse\doifelseinelement % define at the lua end
+
+\permanent\protected\def\taggedlabeltexts#1#2#3% experimental: label, numberdetail, numbercontent
+ {\begingroup
+ \dostarttagged\t!label{#1}%
+ \labeltexts{#1}%
+ {\dostoptagged
+ \dostarttagged\t!number{#2}%
+ #3%
+ \dostoptagged
+ \dostarttagged\t!label{#1}}%
+ \dostoptagged
+ \endgroup}
+
+\permanent\protected\def\namedtaggedlabeltexts#1#2#3#4#5% experimental: labeltag label numbertag numberdetail numbercontent
+ {\begingroup
+ \dostarttagged{#1}{#2}%
+ \labeltexts{#2}%
+ {\dostoptagged
+ \dostarttagged{#3}{#4}%
+ #5%
+ \dostoptagged
+ \dostarttagged{#1}{#2}}%
+ \dostoptagged
+ \endgroup}
+
+%D Metadata is added after the following structure element so here we get some as
+%D child of the document root and some as child of the chapter element.
+%D
+%D \settaggedmetadata[title=Hello World!,author=Hans Hagen]
+%D
+%D \starttyping
+%D \starttext
+%D \startelement[ignore]
+%D \input tufte
+%D \stopelement
+%D \par \input ward \par
+%D \settaggedmetadata[whatever=Again and Again]
+%D \startchapter[title=test]
+%D \input ward
+%D \stopchapter
+%D \stoptext
+%D \stoptyping
+
+% \settaggedmetadata[#1] % define at the lua end
+
+%D An overload:
+
+\pushoverloadmode
+
+\aliased\let\strc_tagged_saved_bpar\bpar
+\aliased\let\strc_tagged_saved_epar\epar
+
+\enforced\permanent\protected\def\bpar{\dostarttagged\t!paragraph\empty\strc_tagged_saved_bpar}
+\enforced\permanent\protected\def\epar{\strc_tagged_saved_epar\dostoptagged}
+
+\popoverloadmode
+
+% \permanent\def\untagged{attr \taggedattribute\attributeunsetvalue}
+
+\protect
diff --git a/tex/context/base/mkiv/strc-tnt.mkxl b/tex/context/base/mkiv/strc-tnt.mkxl
new file mode 100644
index 000000000..4129117f0
--- /dev/null
+++ b/tex/context/base/mkiv/strc-tnt.mkxl
@@ -0,0 +1,117 @@
+%D \module
+%D [ file=strc-tnt,
+%D version=2019.05.30, % based on older code
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Text Notes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D \macros
+%D {definetextnote,setuptextnote}
+%D
+%D \startbuffer
+%D \definetextnote
+%D [textnote]
+%D
+%D \startbuffer
+%D Test test test \textnote [n=5] {alpha}. test test test test tets test test
+%D \textnote [n=10] {beta}. Test test test test tets test test \textnote [n=12]
+%D {gamma}. Test test test test tets test test \textnote [n=24] {delta}. Test test
+%D test test test test \textnote {epsilon} test test \textnote [n=*] {zeta}.
+%D \stopbuffer
+%D
+%D \blank {\setuptextnote[empty=yes] \getbuffer\par} \blank
+%D \blank {\setuptextnote[empty=number] \getbuffer\par} \blank
+%D \blank {\setuptextnote[empty=none] \getbuffer\par} \blank
+%D \blank { \getbuffer\par} \blank
+%D
+%D \blank[2*big]
+%D
+%D \placenotes[textnote:note][criterium=text]
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\installcorenamespace{textnote}
+
+\installcommandhandler \??textnote {textnote} \??textnote
+
+\definebar
+ [\v!textnote:\v!underbar]
+ [\v!underbar]
+
+\definenote
+ [\v!textnote:\v!note]
+
+\setuptextnote
+ [\c!rule=\v!textnote:\v!underbar,
+ \c!note=\v!textnote:\v!note,
+ \c!n=10] % * will use the real space
+
+\appendtoks
+ \frozen\instance\setuevalue{\currenttextnote}{\educ_textnote[\currenttextnote]}%
+\to \everydefinetextnote
+
+\tolerant\protected\def\educ_textnote[#1]#*[#2]#:#3%
+ {\dontleavehmode
+ \begingroup
+ \def\currenttextnote{#1}%
+ \ifparameter#2\or\setupcurrenttextnote[#2]\fi
+ \edef\p_n{\textnoteparameter\c!n}%
+ \edef\p_empty{\textnoteparameter\c!empty}%
+ \edef\currentbar{\textnoteparameter\c!rule}%
+ \edef\currentnote{\textnoteparameter\c!note}%
+ \ifx\p_n\wildcardsymbol
+ \donefalse
+ \ifx\p_empty\v!yes
+ \donetrue
+ \orelse\ifx\p_empty\v!number
+ \donetrue
+ \orelse\ifx\p_empty\v!none
+ \donetrue
+ \fi
+ \ifdone
+ \setupbar[\currentbar][\c!empty=\v!yes]%
+ \fi
+ \inlinebar[\currentbar]\bgroup
+ \wordboundary#3%
+ \ifx\p_empty\v!yes
+ \setnotetext[\currentnote]{#3}%
+ \orelse\ifx\p_empty\v!number
+ \runninghbox{\resetbar\setnote[\currentnote]{#3}}%
+ \orelse\ifx\p_empty\v!none
+ \setupnote[\currentnote][\c!location=\v!none]%
+ \runninghbox{\resetbar\setnote[\currentnote]{#3}}%
+ \fi
+ \egroup
+ \else
+ \inlinebar[\currentbar]\bgroup
+ \scratchcounter\numexpr\p_n/\plustwo\relax
+ \ifx\p_empty\v!yes
+ \interwordspacesbefore\scratchcounter
+ \setnotetext[\currentnote]{#3}%
+ \interwordspacesafter\scratchcounter
+ \orelse\ifx\p_empty\v!number
+ \interwordspacesbefore\scratchcounter
+ \zwnj\runninghbox{\resetbar\setnote[\currentnote]{#3}}\zwnj
+ \interwordspacesafter\scratchcounter
+ \orelse\ifx\p_empty\v!none
+ \setupnote[\currentnote][\c!location=\v!none]%
+ \interwordspacesbefore\scratchcounter
+ \zwnj\runninghbox{\resetbar\setnote[\currentnote]{#3}}\zwnj
+ \interwordspacesafter\scratchcounter
+ \else
+ #3%
+ \fi
+ \egroup
+ \fi
+ \endgroup}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/strc-usr.mkxl b/tex/context/base/mkiv/strc-usr.mkxl
new file mode 100644
index 000000000..28d398194
--- /dev/null
+++ b/tex/context/base/mkiv/strc-usr.mkxl
@@ -0,0 +1,169 @@
+%D \module
+%D [ file=strc-bkm,
+%D version=2009.04.01,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Bookmarks,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Userdata}
+
+\registerctxluafile{strc-usr}{}
+
+%D It's a bit like blocks that also use buffers but more lightweight and with
+%D inplace settings.
+%D
+%D \starttyping
+%D \defineuserdata [test] [style=italic]
+%D
+%D \samplefile{klein}
+%D
+%D \startuserdata [before=\blank,after=\blank,color=red]
+%D \samplefile{greenfield}
+%D \stopuserdata
+%D
+%D \samplefile{sapolsky}
+%D
+%D \startuserdata [test]
+%D \samplefile{bryson}
+%D \stopuserdata
+%D
+%D \samplefile{jojomayer}
+%D
+%D \startuserdata [test] [before=\blank,after=\blank,color=red]
+%D \samplefile{linden}
+%D \stopuserdata
+%D
+%D \samplefile{montgomery}
+%D \stoptyping
+%D
+%D Or from \LUA:
+%D
+%D \starttyping
+%D \startluacode
+%D context.startuserdata({color="blue"})
+%D context.samplefile("klein")
+%D context.stopuserdata()
+%D \stopluacode
+%D \stoptyping
+%D
+%D An example of an alternative:
+%D
+%D \starttyping
+%D \defineuserdataalternative [epigraph] [renderingsetup=userdata:epigraph]
+%D
+%D \startsetups [userdata:epigraph]
+%D \startframedtext [location=right,frame=off,align={flushleft,broad},style=\tfx,offset=.25ex,width=.5\textwidth]
+%D \begstrut\inlinebuffer[userdata]\endstrut
+%D \hairline
+%D \wordright{\userdataparameter{author}}
+%D \stopframedtext
+%D \stopsetups
+%D
+%D \defineuserdata
+%D [epigraph]
+%D [alternative=epigraph]
+%D
+%D \startuserdata [epigraph] [author={Sean B. Carrol}]
+%D The fraction of fossil olfactory receptor genes is significantly higher in
+%D all species with full color vision. This suggests that the evolution of
+%D trichromatic vision --- which allows these primates to detect food, mates,
+%D and danger with visual cues --- has reduced their reliance on the sense of
+%D smell.
+%D \stopuserdata
+%D
+%D \startuserdata [epigraph] [author={Sean B. Carrol}]
+%D \samplefile{carrol}
+%D \stopuserdata
+%D \stoptyping
+
+\unprotect
+
+\installnamespace {userdata}
+\installnamespace {userdataalternative}
+\installnamespace {userdatarenderings}
+
+\installcommandhandler \????userdata {userdata} \????userdata
+\installcommandhandler \????userdataalternative {userdataalternative} \????userdataalternative
+
+\permanent\protected\def\startuserdata
+ {\begingroup
+ \let\currentuserdata\empty
+ \doifelsenextoptionalcs\userdata_start_delayed\userdata_start_indeed}
+
+% This variant works only when the userdata instance exists while the assignment check
+% can also be used with undefined instances which falls back to the global settings.
+%
+% \def\userdata_start_delayed[#1]%
+% {\ifcsname\nameduserdatahash{\detokenize\expandafter{\normalexpanded{#1}}}\s!parent\endcsname
+% \expandafter\userdata_start_delayed_name
+% \else
+% \expandafter\userdata_start_delayed_parameters
+% \fi[#1]}
+
+\def\userdata_start_delayed[#1]%
+ {\doifelseassignmentcs{#1}%
+ \userdata_start_delayed_parameters
+ \userdata_start_delayed_name
+ [#1]}
+
+\def\userdata_start_delayed_parameters[#1]%
+ {\setupcurrentuserdata[#1]%
+ \userdata_start_indeed}
+
+\def\userdata_start_delayed_name[#1]%
+ {\edef\currentuserdata{#1}%
+ \checkuserdataparent
+ \doifelsenextoptionalcs\userdata_start_delayed_parameters\userdata_start_indeed}
+
+\def\userdata_start_indeed
+ {\grabbufferdatadirect\s!userdata{\csstring\startuserdata}{\csstring\stopuserdata}}
+
+\permanent\protected\def\stopuserdata
+ {\userdataparameter\c!before % HH: moved, so we obey the outer spacing
+ \dostarttagged\t!userdata\currentuserdata % HH: added, maybe move up ?
+ \begingroup
+ \useuserdatastyleandcolor\c!style\c!color
+ \usealignparameter\userdataparameter % HH: added
+ \edef\currentuserdataalternative{\userdataparameter\c!alternative}%
+ \ifcsname\currentuserdataalternativehash\s!parent\endcsname \else
+ \let\currentuserdataalternative\s!default
+ \fi
+ \usesetupsparameter\userdataparameter
+ \edef\p_renderingsetup{\userdataalternativeparameter\c!renderingsetup}%
+ \directsetup\p_renderingsetup
+ \endgroup
+ \dostoptagged
+ \userdataparameter\c!after % HH: moved
+ \endgroup}
+
+\permanent\protected\def\getuserdata
+ {\getbufferdata[\s!userdata]}
+
+\permanent\protected\def\getinlineuserdata
+ {\inlinebuffer[\s!userdata]}
+
+\defineuserdataalternative
+ [\s!default]
+ [\c!renderingsetup=\????userdatarenderings:\s!default]
+
+% \startsetups[\????userdatarenderings:\s!default]
+% \userdataparameter\c!before
+% \usesetupsparameter\userdataparameter
+% \getbufferdata[\s!userdata]
+% \userdataparameter\c!after
+% \stopsetups
+
+\startsetups[\????userdatarenderings:\s!default]
+ \getuserdata
+\stopsetups
+
+\setupuserdata
+ [\c!alternative=\s!default]
+
+\protect
diff --git a/tex/context/base/mkiv/supp-box.lmt b/tex/context/base/mkiv/supp-box.lmt
index 8a308f90f..41013da9a 100644
--- a/tex/context/base/mkiv/supp-box.lmt
+++ b/tex/context/base/mkiv/supp-box.lmt
@@ -71,6 +71,7 @@ local setshift = nuts.setshift
local setsplit = nuts.setsplit
local setattrlist = nuts.setattrlist
local setwhd = nuts.setwhd
+local setglue = nuts.setglue
local flush_node = nuts.flush_node
local flush_list = nuts.flush_list
@@ -85,6 +86,7 @@ local traverse = nuts.traverse
local free = nuts.free
local findtail = nuts.tail
local reverse = nuts.reverse
+local effective_glue= nuts.effective_glue
local nextdisc = nuts.traversers.disc
local nextdir = nuts.traversers.dir
@@ -769,7 +771,8 @@ local function limitate(t) -- don't pack the result !
end
local left = t.left or 0
local right = t.right or 0
- if left + right < width then
+ local total = left + right
+ if total < width then
local last = nil
local first = nil
local maxleft = left
@@ -828,6 +831,16 @@ local function limitate(t) -- don't pack the result !
end
setlist(text)
free(text)
+
+ if t.freeze then
+ local l = hpack(list,total,"exactly")
+ for n in traverse_id(glue_code,list) do
+ setglue(n,(effective_glue(n,l)))
+ end
+ setlist(l)
+ flush_node(l)
+ end
+
return tonode(list)
end
@@ -842,6 +855,7 @@ implement {
{ "text", "hbox" },
{ "sentinel", "hbox" },
{ "strip", "boolean" },
+ { "freeze", "boolean" },
}
},
actions = function(t)
diff --git a/tex/context/base/mkiv/syst-aux.mkxl b/tex/context/base/mkiv/syst-aux.mkxl
index d3e75fd07..8847cb6b1 100644
--- a/tex/context/base/mkiv/syst-aux.mkxl
+++ b/tex/context/base/mkiv/syst-aux.mkxl
@@ -93,48 +93,20 @@
\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 define some shortcuts to
-%D the local scatchregisters~0, 2, 4, 6 and~8. These are kind of obsolete and
-%D eventually they might get dropped!
-
-\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} % ...
-\def\!!plusone {1} % ...
-\def\!!plustwo {2} % ...
-\def\!!plusthree {3} % ...
-\def\!!plusfour {4} % ...
-\def\!!plusfive {5} % ...
-\def\!!plussix {6} % ...
-\def\!!plusseven {7} % ...
-\def\!!pluseight {8} % ...
-\def\!!plusnine {9} % alongside \plusnine
+\newif\if!!donea \newif\if!!doneb \newif\if!!donec % soon obsolete in lmtx
+\newif\if!!doned \newif\if!!donee \newif\if!!donef % soon obsolete in lmtx
+
+\immutable\def\!!zerocount {0} % alongside \zerocount
+\immutable\def\!!minusone {-1} % ...
+\immutable\def\!!plusone {1} % ...
+\immutable\def\!!plustwo {2} % ...
+\immutable\def\!!plusthree {3} % ...
+\immutable\def\!!plusfour {4} % ...
+\immutable\def\!!plusfive {5} % ...
+\immutable\def\!!plussix {6} % ...
+\immutable\def\!!plusseven {7} % ...
+\immutable\def\!!pluseight {8} % ...
+\immutable\def\!!plusnine {9} % alongside \plusnine
\setnewconstant \uprotationangle 0
\setnewconstant\rightrotationangle 90
@@ -819,8 +791,8 @@
\expandafter\syst_helpers_process_comma_item_gobble
\fi}
-\def\syst_helpers_process_comma_item_next
- {\expandafterspaces\syst_helpers_process_comma_item}
+% \def\syst_helpers_process_comma_item_next
+% {\expandafterspaces\syst_helpers_process_comma_item}
% \protected\def\processcommalist[#1]#2%
% {\pushmacro\commalistcommand
@@ -834,16 +806,37 @@
% \normalexpanded{\noexpand\expandafterspaces\syst_helpers_process_comma_item#1,}\ignorearguments\ignorearguments\ignorearguments
% \popmacro\commalistcommand}
-\permanent\protected\def\processcommalist[#*#+]#2%
+% \permanent\protected\def\processcommalist[#*#+]#2%
+% {\pushmacro\commalistcommand
+% \def\commalistcommand{#2}%
+% \expandafterspaces\syst_helpers_process_comma_item#1,\ignorearguments\ignorearguments\ignorearguments
+% \popmacro\commalistcommand}
+%
+% \permanent\protected\def\processcommacommand[#*#+]#2%
+% {\pushmacro\commalistcommand
+% \def\commalistcommand{#2}%
+% \normalexpanded{\noexpand\expandafterspaces\syst_helpers_process_comma_item#1,}\ignorearguments\ignorearguments\ignorearguments
+% \popmacro\commalistcommand}
+
+\tolerant\protected\def\syst_helpers_process_comma_item#*#1,%
+ {\ifarguments\or
+ \commalistcommand{#1}%
+ \expandafter\syst_helpers_process_comma_item_next
+ \fi}
+
+\def\syst_helpers_process_comma_item_next
+ {\expandafterspaces\syst_helpers_process_comma_item}
+
+\permanent\protected\def\processcommalist[#1]#2%
{\pushmacro\commalistcommand
\def\commalistcommand{#2}%
- \expandafterspaces\syst_helpers_process_comma_item#1,\ignorearguments\ignorearguments\ignorearguments
+ \syst_helpers_process_comma_item#1\ignorearguments\ignorearguments\ignorearguments
\popmacro\commalistcommand}
-\permanent\protected\def\processcommacommand[#*#+]#2%
+\permanent\protected\def\processcommacommand[#1]#2%
{\pushmacro\commalistcommand
\def\commalistcommand{#2}%
- \normalexpanded{\noexpand\expandafterspaces\syst_helpers_process_comma_item#1,}\ignorearguments\ignorearguments\ignorearguments
+ \normalexpanded{\syst_helpers_process_comma_item#1}\ignorearguments\ignorearguments\ignorearguments
\popmacro\commalistcommand}
% \let\syst_helpers_process_comma_item_next_a \syst_helpers_process_comma_item_next
@@ -5376,23 +5369,31 @@
% \syst_helpers_process_separated_list_step}%
% \expandafter\syst_helpers_process_separated_list_step\gobbleoneargument#1#2]#2}
-\def\syst_helpers_process_separated_list#1]#*[#2]#3%
- {\def\syst_helpers_process_separated_list_step##1##2#2%
- {\def\m_syst_string_one{##2}% suggested by VZ
- \if]##1%
- \orelse\ifx\blankspace\m_syst_string_one
+% \def\syst_helpers_process_separated_list#1]#*[#2]#3%
+% {\def\syst_helpers_process_separated_list_step##1##2#2%
+% {\def\m_syst_string_one{##2}% suggested by VZ
+% \if]##1%
+% \orelse\ifx\blankspace\m_syst_string_one
+% #3{##1}%
+% \expandafter\syst_helpers_process_separated_list_step
+% \orelse\if]##2%
+% \else
+% #3{##1##2}%
+% \expandafter\syst_helpers_process_separated_list_step
+% \fi
+% }%
+% \expandafter\syst_helpers_process_separated_list_step\gobbleoneargument#1#2]#2}
+
+% \permanent\protected\def\processseparatedlist[%
+% {\syst_helpers_process_separated_list\relax}
+
+\permanent\protected\def\processseparatedlist[#+]#*[#2]#3%
+ {\tolerant\def\syst_helpers_process_separated_list_step##1#2%
+ {\ifarguments\or
#3{##1}%
\expandafter\syst_helpers_process_separated_list_step
- \orelse\if]##2%
- \else
- #3{##1##2}%
- \expandafter\syst_helpers_process_separated_list_step
- \fi
- }%
- \expandafter\syst_helpers_process_separated_list_step\gobbleoneargument#1#2]#2}
-
-\permanent\protected\def\processseparatedlist[%
- {\syst_helpers_process_separated_list\relax}
+ \fi}%
+ \syst_helpers_process_separated_list_step#1\ignorearguments\ignorearguments}
%D \macros
%D {processlist}
@@ -6659,4 +6660,19 @@
\ifflags#1=\protectedflagcode\etoksapp\scratchtoks{\ifdone \space\fi protected}\donetrue\fi
\expandafter\endgroup\expandafter\endlocalcontrol\the\scratchtoks}
+%D \macros
+%D {resetmacros}
+%D
+%D The next macro can be used to reset a macro:
+%D
+%D \starttyping
+%D \resetmacros[startfoo,\stopfoo]
+%D \stoptyping
+
+\permanent\protected\def\syst_reset_macro#1%
+ {\overloaded\letcsname\csstring#1\endcsname\undefined} % so only frozen (instances(
+
+\permanent\protected\def\resetmacros[#1]%
+ {\processcommalist[#1]\syst_reset_macro}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/syst-ini.mkxl b/tex/context/base/mkiv/syst-ini.mkxl
index 8cb2b8c1c..d495e12af 100644
--- a/tex/context/base/mkiv/syst-ini.mkxl
+++ b/tex/context/base/mkiv/syst-ini.mkxl
@@ -351,11 +351,10 @@
% \permanent\protected\def\newattribute{\syst_basics_allocate\c_syst_last_allocated_attribute\attribute\attributedef\c_syst_max_allocated_register}
-%D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force
-%D strings instead of tokens that take more memory. It's a trick to trick to force
-%D strings. This macro is never used in \CONTEXT.
-
-\permanent\protected\def\newhelp#1#2{\newtoks#1#1\expandafter{\detokenize{#2}}}
+% %D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force
+% %D strings instead of tokens that take more memory.
+%
+% \permanent\protected\def\newhelp#1#2{\newtoks#1#1\expandafter{\detokenize{#2}}}
%D \macros
%D {scratchcounter,
@@ -399,7 +398,7 @@
%D \macros
%D {tempstring}
-\let\tempstring\empty
+\mutable\let\tempstring\empty
%D \macros
%D {scratchwidth, scratchheight, scratchdepth, scratchoffset, scratchdistance}
@@ -607,6 +606,10 @@
\newif\ifdone
\newif\iffound
+\newif\ifscratchcondition
+\newif\ifscratchconditionone
+\newif\ifscratchconditiontwo
+
\let\htdp\boxtotal
%D A few shortcuts:
diff --git a/tex/context/base/mkiv/tabl-ltb.mkiv b/tex/context/base/mkiv/tabl-ltb.mkiv
index de90d6585..0650cf9ce 100644
--- a/tex/context/base/mkiv/tabl-ltb.mkiv
+++ b/tex/context/base/mkiv/tabl-ltb.mkiv
@@ -503,7 +503,7 @@
\fi
\global\d_tabl_lines_width\wd\b_tabl_lines_cell
\tabl_lines_start_part
- \if!!doneb \else \ifcase\c_tabl_lines_repeat \else
+ \if!!donea \else \ifcase\c_tabl_lines_repeat \else
% check for left/right page
\ifcase\c_tabl_lines_page\donetrue\or\donetrue\or\donefalse\fi\ifdone
% insert repeater
diff --git a/tex/context/base/mkiv/tabl-ltb.mkxl b/tex/context/base/mkiv/tabl-ltb.mkxl
index 1ab2a2c4b..5058e26f8 100644
--- a/tex/context/base/mkiv/tabl-ltb.mkxl
+++ b/tex/context/base/mkiv/tabl-ltb.mkxl
@@ -445,7 +445,7 @@
\fi
\else
\donefalse
- \!!doneafalse
+ \scratchconditiononefalse
\ifcase\c_tabl_lines_repeat\else
% calculate ahead
\ifnum\c_tabl_lines_repeat=\numexpr\c_tabl_lines_column-\plustwo\relax
@@ -453,7 +453,7 @@
\fi
\fi
\ifdone
- \!!doneatrue
+ \scratchconditiononetrue
% collecting repeater
\orelse\ifdim\d_tabl_lines_width>\hsize
\donetrue
@@ -478,7 +478,7 @@
\fi
\global\d_tabl_lines_width\wd\b_tabl_lines_cell
\tabl_lines_start_part
- \if!!doneb \else \ifcase\c_tabl_lines_repeat \else
+ \ifscratchconditionone \else \ifcase\c_tabl_lines_repeat \else
% check for left/right page
\ifcase\c_tabl_lines_page\donetrue\or\donetrue\or\donefalse\fi\ifdone
% insert repeater
diff --git a/tex/context/base/mkiv/tabl-mis.mkxl b/tex/context/base/mkiv/tabl-mis.mkxl
new file mode 100644
index 000000000..14bd08b46
--- /dev/null
+++ b/tex/context/base/mkiv/tabl-mis.mkxl
@@ -0,0 +1,294 @@
+%D \module
+%D [ file=tabl-mis,
+%D version=2012.06.28,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Miscellaneous,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Table Macros / Miscellaneous}
+
+\unprotect
+
+%D \macros
+%D {somekindoftab,kindoftabposition}
+%D
+%D This macro can be used to create tabs:
+%D
+%D \starttyping
+%D \setupheadertexts[{\somekindoftab[alternative=horizontal]{\framed{\kindoftabposition}}}]
+%D \setuptexttexts [{\somekindoftab[alternative=vertical] {\framed{\kindoftabposition}}}]
+%D
+%D \starttext
+%D \showframe \dorecurse{10}{test\page}
+%D \stoptext
+%D \stoptyping
+%D
+%D (This rather old but updated code used to be in \type {core-mis.mkiv}.)
+
+\let\kindoftabposition\!!zerocount
+
+\permanent\tolerant\protected\def\somekindoftab[#1]%
+ {\bgroup
+ \getdummyparameters
+ [\c!alternative=\v!vertical,
+ \c!width=\textwidth,\c!height=\textheight,
+ \c!n=\lastpage,\c!m=\realpageno,
+ #1]%
+ \doifelse{\directdummyparameter\c!alternative}\v!vertical
+ {\typo_kindoftab_indeed\vbox\vskip\c!height}
+ {\typo_kindoftab_indeed\hbox\hskip\c!width }}
+
+\def\typo_kindoftab_indeed#1#2#3#4%
+ {#1 to \directdummyparameter#3 \bgroup
+ \forgetall
+ \scratchnx\directdummyparameter\c!n\relax
+ \scratchmx\directdummyparameter\c!m\relax
+ \edef\kindoftabposition{\the\scratchmx}%
+ \ifnum\scratchmx>\plusone
+ #2\zeropoint \s!plus \the\numexpr\scratchmx-\plusone \relax\s!fill\relax
+ \fi
+ #4% can use \kindoftabposition
+ \ifnum\scratchmx<\scratchnx\relax
+ #2\zeropoint \s!plus \the\numexpr\scratchnx-\scratchmx\relax\s!fill\relax
+ \fi
+ \egroup
+ \egroup}
+
+%D The following paragraphs mechanism is probably one of the oldest of \CONTEXT\ and
+%D mostly served as a table mechanism capable of dealing with paragraphs. Nowadays
+%D one can also use tabulate or natural tables.
+%D
+%D \startbuffer
+%D \defineparagraphs[sample][n=2,rule=on]
+%D
+%D \startsample
+%D first \nextsample
+%D second \nextsample
+%D third
+%D \stopsample
+%D
+%D \startsample
+%D \input tufte \nextsample
+%D \input ward \nextsample
+%D \input davis \nextsample
+%D \input zapf
+%D \stopsample
+%D
+%D \startparagraphs[sample]
+%D first \nextsample
+%D second \nextsample
+%D third
+%D \stopparagraphs
+%D
+%D \startparagraphs[sample]
+%D \startparagraphscell
+%D first
+%D \stopparagraphscell
+%D \startparagraphscell
+%D second
+%D \stopparagraphscell
+%D \startparagraphscell
+%D third
+%D \stopparagraphscell
+%D \stopparagraphs
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\installcorenamespace{paragraphs}
+
+\installframedcommandhandler \??paragraphs {paragraphs} \??paragraphs
+
+\setupparagraphs
+ [\c!n=3,
+ \c!offset=\zeropoint,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!distance=\emwidth,
+ \c!height=\v!fit,
+ \c!width=\availablehsize,
+ \c!rule=\v!off,
+ \c!command=,
+ \c!align=,
+ \c!tolerance=\v!tolerant, % obsolete
+ \c!rulethickness=\linewidth,
+ \c!rulecolor=,
+ \c!style=,
+ \c!color=,
+ \c!frame=\v!off,
+ \c!top=\vss,
+ \c!bottom=\vfill]
+
+\aliased\let\typo_paragraphs_setup_saved\setupparagraphs
+
+\overloaded\permanent\tolerant\protected\def\setupparagraphs[#1]#*[#2]#*[#3]% we are downward compatible with [each] and [1,3]
+ {\ifarguments\or
+ \typo_paragraphs_setup_saved[#1]%
+ \or
+ \typo_paragraphs_setup_saved[#1][#2]%
+ \or
+ \doifelse{#2}\v!each
+ {\dorecurse{\namedparagraphsparameter{#1}\c!n}%
+ {\normalexpanded{\typo_paragraphs_setup_saved[#1:\recurselevel]}[#3]}}%
+ {\def\typo_paragraphs_setup_step##1{\typo_paragraphs_setup_saved[#1:##1][#3]}%
+ \processcommalist[#2]\typo_paragraphs_setup_step}%
+ \fi}
+
+\appendtoks
+ \frozen\instance\letvalue{\e!next \currentparagraphs}\nextparagraphs
+ \frozen\instance\letvalue\currentparagraphs\nextparagraphs
+ \frozen\instance\setuevalue{\e!start\currentparagraphs}{\startparagraphs[\currentparagraphs]}%
+ \frozen\instance\letvalue{\e!stop \currentparagraphs}\stopparagraphs
+ %frozen\instance\setuevalue{\e!setup\currentparagraph\e!endsetup}{\typo_paragraphs_setup_saved[\currentparagraphs]}%
+ \dorecurse{\paragraphsparameter\c!n}
+ {\normalexpanded{\typo_paragraphs_setup_saved[\currentparagraphs:\recurselevel][\c!width=,\s!parent=\??paragraphs\currentparagraphs]}}%
+ \typo_paragraphs_setup_saved[\currentparagraphs:1][\c!distance=\zeropoint]%
+\to \everydefineparagraphs
+
+\newcount\c_typo_paragraphs_n
+\newcount\c_typo_paragraphs_max
+\newdimen\d_typo_paragraphs_width
+\newdimen\d_typo_paragraphs_auto
+
+\permanent\protected\def\startparagraphs[#1]% quite slow
+ {\bgroup % (1)
+ \edef\currentparagraphs{#1}%
+ % \paragraphsparameter\c!before
+ \edef\p_width{\paragraphsparameter\c!width}%
+ \ifempty\p_width
+ \d_typo_paragraphs_width\availablehsize
+ \else
+ \d_typo_paragraphs_width\p_width\relax
+ \fi
+ \advance\d_typo_paragraphs_width-2\dimexpr\paragraphsparameter\c!offset\relax
+ \c_typo_paragraphs_max\paragraphsparameter\c!n\relax
+ \d_typo_paragraphs_auto\d_typo_paragraphs_width\relax
+ \scratchcounter\zerocount
+ \dorecurse\c_typo_paragraphs_max
+ {\edef\p_width{\namedparagraphsparameter{\currentparagraphs:\recurselevel}\c!width}%
+ \ifempty\p_width
+ \advance\scratchcounter\plusone
+ \else
+ \advance\d_typo_paragraphs_auto-\p_width\relax
+ \fi
+ \ifnum\recurselevel>\plusone
+ \advance\d_typo_paragraphs_auto-\namedparagraphsparameter{\currentparagraphs:\recurselevel}\c!distance\relax
+ \fi}%
+ \ifnum\scratchcounter>\zerocount
+ \divide\d_typo_paragraphs_auto\scratchcounter
+ \else
+ \d_typo_paragraphs_auto\zeropoint
+ \fi
+ \parindent\zeropoint
+ \c_typo_paragraphs_n\zerocount
+ \enforced\let\\\typo_paragraphs_next % downward compatible
+ \edef\p_offset{\paragraphsparameter\c!offset}%
+ \doifelsedimension\p_offset
+ {\scratchoffset\p_offset}%
+ {\scratchoffset\zeropoint}%
+ \setbox\scratchbox\hpack
+ \bgroup % (2)
+ \forgetall
+ \advance\hsize-2\scratchoffset
+ \let\typo_paragraphs_start_cell\typo_paragraphs_start_cell_indeed
+ \let\typo_paragraphs_stop_cell \typo_paragraphs_stop_cell_indeed
+ \typo_paragraphs_start_cell_indeed}
+
+\permanent\protected\def\stopparagraphs
+ {\stopparagraphscell
+ \egroup % (2)
+ \letparagraphsparameter\c!align\v!flushleft % normal
+ \paragraphsparameter\c!before
+ \dontleavehmode\inheritedparagraphsframed{\box\scratchbox}%
+ \paragraphsparameter\c!after
+ \egroup} % (1)
+
+\permanent\protected\def\nextparagraphs
+ {\stopparagraphscell
+ \startparagraphscell}
+
+\permanent\protected\def\startparagraphscell
+ {\typo_paragraphs_start_cell}
+
+\def\typo_paragraphs_start_cell_indeed
+ {\removeunwantedspaces
+ \advance\c_typo_paragraphs_n\plusone
+ \ifnum\c_typo_paragraphs_n>\c_typo_paragraphs_max
+ \expandafter\typo_paragraphs_start_cell_nop
+ \else
+ \expandafter\typo_paragraphs_start_cell_yes
+ \fi}
+
+\def\typo_paragraphs_start_cell_nop
+ {\begingroup
+ % message: too many cells in paragraphs
+ \let\typo_paragraphs_start_cell\relax
+ \let\typo_paragraphs_stop_cell\typo_paragraphs_stop_cell_indeed
+ \setbox\scratchbox\vbox\bgroup}
+
+\def\typo_paragraphs_start_cell_yes
+ {\begingroup
+ \let\typo_paragraphs_start_cell\relax
+ \let\typo_paragraphs_stop_cell\typo_paragraphs_stop_cell_indeed
+ \edef\currentparagraphs{\currentparagraphs:\the\c_typo_paragraphs_n}%
+ \ifnum\c_typo_paragraphs_n>\plusone
+ \typo_paragraphs_separator
+ \fi
+ \edef\p_height{\paragraphsparameter\c!height}%
+ \edef\p_width {\paragraphsparameter\c!width }%
+ \useparagraphsstyleandcolor\c!style\c!color
+ \setbox\scratchbox\vtop \ifempty\p_height \orelse\ifx\p_height\v!fit \else to \p_height \fi
+ \bgroup % (2)
+ \blank[\v!disable]%
+ \paragraphsparameter\c!top
+ \hsize\ifempty\p_width \d_typo_paragraphs_auto \else \p_width \fi \relax
+ \usealignparameter\paragraphsparameter
+ \paragraphsparameter\c!inner
+ \everypar{\begstrut\everypar\emptytoks}%
+ \ignorespaces
+ \paragraphsparameter\c!command}
+
+\permanent\protected\def\stopparagraphscell
+ {\typo_paragraphs_stop_cell
+ \let\typo_paragraphs_stop_cell\relax}
+
+\def\typo_paragraphs_stop_cell_indeed
+ {\ifnum\c_typo_paragraphs_n>\c_typo_paragraphs_max
+ \expandafter\typo_paragraphs_stop_cell_nop
+ \else
+ \expandafter\typo_paragraphs_stop_cell_yes
+ \fi}
+
+\def\typo_paragraphs_stop_cell_nop
+ {\egroup
+ \endgroup}
+
+\def\typo_paragraphs_stop_cell_yes
+ {\ifvmode
+ \removelastskip
+ \else
+ \removeunwantedspaces
+ \endstrut
+ \endgraf
+ \fi
+ \paragraphsparameter\c!bottom
+ \egroup % (2)
+ \dontleavehmode\hpack{\raise\strutheight\box\scratchbox}%
+ \endgroup}
+
+\def\typo_paragraphs_separator
+ {\scratchdistance\paragraphsparameter\c!distance
+ \doif{\paragraphsparameter\c!rule}\v!on
+ {\scratchwidth\paragraphsparameter\c!rulethickness
+ \scratchdistance\dimexpr(\scratchdistance-\scratchwidth)/2\relax
+ \hskip\scratchdistance
+ \color[\paragraphsparameter\c!rulecolor]{\vrule\s!width\scratchwidth}}%
+ \hskip\scratchdistance}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/tabl-ntb.mkxl b/tex/context/base/mkiv/tabl-ntb.mkxl
index f47c67802..8883a29e3 100644
--- a/tex/context/base/mkiv/tabl-ntb.mkxl
+++ b/tex/context/base/mkiv/tabl-ntb.mkxl
@@ -1414,17 +1414,17 @@
\def\tabl_ntb_pass_two#1 #2 % meer in cellD
{\d_tabl_ntb_width\zeropoint
\scratchcounter\c_tabl_ntb_col
- \!!counta\tabl_ntb_get_col{#1}{#2}\relax
- \ifcase\!!counta\or
+ \scratchcounterone\tabl_ntb_get_col{#1}{#2}\relax
+ \ifcase\scratchcounterone\or
\advance\d_tabl_ntb_width\dimexpr
\tabl_ntb_get_wid\scratchcounter
\relax
\advance\scratchcounter\plusone
\else
- \dorecurse\!!counta
+ \dorecurse\scratchcounterone
{\advance\d_tabl_ntb_width\dimexpr
\tabl_ntb_get_wid\scratchcounter
- \ifnum\recurselevel<\!!counta
+ \ifnum\recurselevel<\scratchcounterone
+\d_tabl_ntb_columndistance
+\tabl_ntb_get_dis\scratchcounter
\fi
@@ -1441,36 +1441,36 @@
\def\tabl_ntb_pass_three#1 #2 %
{% height
\dostarttagged\t!tablecell\empty
- \!!counta \tabl_ntb_get_col{#1}{#2}\relax
- \!!countb \tabl_ntb_get_row{#1}{#2}\relax
- \!!heighta\tabl_ntb_get_ht {#1}{#2}\relax
- \tablecellcolumns\!!counta % used later so don't adapt these
- \tablecellrows \!!countb % used later so don't adapt these
+ \scratchcounterone\tabl_ntb_get_col{#1}{#2}\relax
+ \scratchcountertwo\tabl_ntb_get_row{#1}{#2}\relax
+ \scratchheight\tabl_ntb_get_ht {#1}{#2}\relax
+ \tablecellcolumns\scratchcounterone % used later so don't adapt these
+ \tablecellrows \scratchcountertwo % used later so don't adapt these
\d_tabl_ntb_height\zeropoint
- \ifnum\!!counta=\c_tabl_ntb_maximum_col\relax
+ \ifnum\scratchcounterone=\c_tabl_ntb_maximum_col\relax
% case: nc=maxcolumns
\else
\scratchcounter#1\relax
- \dorecurse\!!countb
+ \dorecurse\scratchcountertwo
{\advance\d_tabl_ntb_height\tabl_ntb_get_hei\scratchcounter
\advance\scratchcounter\plusone}%
- \ifdim\d_tabl_ntb_height<\!!heighta\relax
- \d_tabl_ntb_height\!!heighta
+ \ifdim\d_tabl_ntb_height<\scratchheight\relax
+ \d_tabl_ntb_height\scratchheight
\fi
\fi
% width
\d_tabl_ntb_width\zeropoint
\scratchcounter\c_tabl_ntb_col
- \ifcase\!!counta\or
+ \ifcase\scratchcounterone\or
\advance\d_tabl_ntb_width\dimexpr
\tabl_ntb_get_wid\scratchcounter
\relax
\advance\scratchcounter\plusone
\else
- \dorecurse\!!counta
+ \dorecurse\scratchcounterone
{\advance\d_tabl_ntb_width\dimexpr
\tabl_ntb_get_wid\scratchcounter
- \ifnum\recurselevel<\!!counta
+ \ifnum\recurselevel<\scratchcounterone
+\d_tabl_ntb_columndistance
+\tabl_ntb_get_dis\scratchcounter
\fi
@@ -1482,7 +1482,7 @@
\dotagTABLEsignal % maybe we need to add some packaging in this case
\tabl_ntb_get_txt{#1}{#2}%
\egroup
- \ifnum\!!counta=\c_tabl_ntb_maximum_col\relax
+ \ifnum\scratchcounterone=\c_tabl_ntb_maximum_col\relax
% case: nc=maxcolumns
\else
\scratchdimen\tabl_ntb_get_hei{#1}%
@@ -1491,11 +1491,11 @@
\ht\scratchbox\scratchdimen
\fi
\dp\scratchbox\zeropoint
- \edef\!!stringa{\tabl_ntb_get_ref{#1}{#2}}%
- \ifempty\!!stringa
+ \edef\scratchmacro{\tabl_ntb_get_ref{#1}{#2}}%
+ \ifempty\scratchmacro
\box\scratchbox
\else
- \normalexpanded{\noexpand\directgotobox{\box\scratchbox}[\!!stringa]}% to be checked
+ \normalexpanded{\directgotobox{\box\scratchbox}[\scratchmacro]}% to be checked
\fi
\dostoptagged} % right spot
@@ -1622,28 +1622,28 @@
\def\tabl_ntb_stretch_widths % more variants, e.g. a max to \dimend
{\ifcase\c_tabl_ntb_maximum_col\else % else division by zero
- \!!dimend\zeropoint
- \!!dimene\dimexpr
+ \scratchdimenfour\zeropoint
+ \scratchdimenfive\dimexpr
\hsize
-\d_tabl_ntb_leftmargindistance
-\d_tabl_ntb_rightmargindistance
+\d_tabl_ntb_columndistance
\relax
\dorecurse\c_tabl_ntb_maximum_col
- {\advance\!!dimend\dimexpr
+ {\advance\scratchdimenfour\dimexpr
\tabl_ntb_get_wid\recurselevel
\relax
- \advance\!!dimene\dimexpr
+ \advance\scratchdimenfive\dimexpr
-\tabl_ntb_get_dis\recurselevel
-\d_tabl_ntb_columndistance
\relax}%
\relax
% distribute width (stretch)
- \ifdim\!!dimend<\!!dimene
- \advance\!!dimend-\!!dimene
- \divide\!!dimend\c_tabl_ntb_maximum_col
+ \ifdim\scratchdimenfour<\scratchdimenfive
+ \advance\scratchdimenfour-\scratchdimenfive
+ \divide\scratchdimenfour\c_tabl_ntb_maximum_col
\dorecurse\c_tabl_ntb_maximum_col
- {\tabl_ntb_set_wid\recurselevel{\the\dimexpr\tabl_ntb_get_wid\recurselevel-\!!dimend\relax}}%
+ {\tabl_ntb_set_wid\recurselevel{\the\dimexpr\tabl_ntb_get_wid\recurselevel-\scratchdimenfour\relax}}%
\fi
\fi}
@@ -1683,26 +1683,26 @@
\def\tabl_ntb_split_box
{\resettsplit
- \def\tsplitminimumfreelines{2}%
- \def\tsplitminimumfreespace{\dimexpr\extratblsplitheight+\naturaltablelocalparameter\c!splitoffset\relax}%
- \def\tsplitbeforeresult {\beforeTABLEsplitbox}%
- \def\tsplitafterresult {\afterTABLEsplitbox}%
- \def\tsplitafter {\m_tabl_ntb_after_split}%
- \def\tsplitbefore {\m_tabl_ntb_before_split}% supported ?
- \setbox\tsplitcontent\vbox{\tabl_ntb_flush_content}%
+ \c_split_minimum_free_lines\plustwo
+ \d_split_minimum_free_space\dimexpr\extratblsplitheight+\naturaltablelocalparameter\c!splitoffset\relax
+ \t_split_before_result{\beforeTABLEsplitbox}%
+ \t_split_after_result{\afterTABLEsplitbox}%
+ \t_split_after{\m_tabl_ntb_after_split}%
+ \t_split_before{\m_tabl_ntb_before_split}% not used (yet)
+ \setbox\b_split_content\vbox{\tabl_ntb_flush_content}%
\ifmultipleTBLheads
\dorecurse\c_tabl_ntb_n_of_head_lines
- {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight
- \setbox\tsplithead\vbox{\unvcopy\tsplithead\unvcopy\scratchbox}}% \vpack ?
+ {\setbox\scratchbox\vsplit\b_split_content to \lineheight
+ \setbox\b_split_head\vbox{\unvcopy\b_split_head\unvcopy\scratchbox}}% \vpack ?
\dorecurse\c_tabl_ntb_n_of_next_lines
- {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight
- \setbox\tsplitnext\vbox{\unvcopy\tsplitnext\unvcopy\scratchbox}}% \vpack ?
+ {\setbox\scratchbox\vsplit\b_split_content to \lineheight
+ \setbox\b_split_next\vbox{\unvcopy\b_split_next\unvcopy\scratchbox}}% \vpack ?
\fi
\edef\p_spaceinbetween{\naturaltablelocalparameter\c!spaceinbetween}%
\ifempty\p_spaceinbetween\else
\blank[\p_spaceinbetween]%
\fi
- \def\postprocesstsplit{\postprocessTABLEsplitbox{\box\tsplitresult}}%
+ \def\postprocesstsplit{\postprocessTABLEsplitbox{\box\b_split_result}}%
\handletsplit}
% ! ! ! ! TODO: naast \postprocessTABLEsplitbox ook evt \postprocessTABLEbox voor niet split
@@ -1720,8 +1720,8 @@
\def\tabl_ntb_check_widths_indeed#1%
{\ifconditional\c_tabl_ntb_trace_widths\tabl_ntb_show_widths B#1\fi
- \!!counta\zerocount
- \!!dimena\dimexpr
+ \scratchcounterone\zerocount
+ \scratchdimenone\dimexpr
\hsize
-\d_tabl_ntb_leftmargindistance
-\d_tabl_ntb_rightmargindistance
@@ -1729,38 +1729,38 @@
\relax
\dorecurse\c_tabl_ntb_maximum_col
{\scratchdimen\tabl_ntb_get_aut\recurselevel\relax
- \advance\!!dimena\dimexpr
+ \advance\scratchdimenone\dimexpr
-\tabl_ntb_get_dis\recurselevel
-\d_tabl_ntb_columndistance
\relax
\ifdim\scratchdimen>\zeropoint\relax
- \advance\!!dimena -\scratchdimen
+ \advance\scratchdimenone -\scratchdimen
\else
\scratchdimen\tabl_ntb_get_wid\recurselevel\relax
\ifdim\scratchdimen>\d_tabl_ntb_maxwidth\relax
\ifcase#1\else\tabl_ntb_let_wid\recurselevel\zeropoint\fi
- \advance\!!counta \plusone
+ \advance\scratchcounterone \plusone
\orelse\ifdim\scratchdimen>\zeropoint\relax
- \advance\!!dimena -\scratchdimen
+ \advance\scratchdimenone -\scratchdimen
\else
% eigenlijk moet dit alleen als de kolom wordt overspannen door een
% vorige, maw extra dubbele loop en status var
\ifnum\c_tabl_ntb_encountered_max=\c_tabl_ntb_maximum_col % *nx* bah
- \advance\!!counta \plusone % setting maxwidth to a large value also works
+ \advance\scratchcounterone \plusone % setting maxwidth to a large value also works
\fi
\fi
\fi}%
\ifconditional\c_tabl_ntb_trace_widths\tabl_ntb_show_widths M#1\fi
- \ifcase\!!counta \else \divide\!!dimena \!!counta \fi
+ \ifcase\scratchcounterone \else \divide\scratchdimenone \scratchcounterone \fi
\dorecurse\c_tabl_ntb_maximum_col
{\scratchdimen\tabl_ntb_get_wid\recurselevel\relax
\ifcase#1\relax
- \ifdim\scratchdimen<\!!dimena % take natural width
+ \ifdim\scratchdimen<\scratchdimenone % take natural width
\tabl_ntb_set_aut\recurselevel{\the\scratchdimen}%
\fi
\else
\ifzeropt\scratchdimen % auto set width
- \tabl_ntb_set_wid\recurselevel{\the\!!dimena}%
+ \tabl_ntb_set_wid\recurselevel{\the\scratchdimenone}%
\fi
\fi}%
\ifconditional\c_tabl_ntb_trace_widths\tabl_ntb_show_widths E#1\fi}
@@ -1768,9 +1768,9 @@
% todo: use scratchcounters, not !! ones
\def\tabl_ntb_check_heights_one_indeed
- {\!!countb\tabl_ntb_get_row\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three\relax
+ {\scratchcountertwo\tabl_ntb_get_row\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three\relax
% check row span
- \ifnum\!!countb>\plusone
+ \ifnum\scratchcountertwo>\plusone
% current height in row
\dimen0=\tabl_ntb_get_ht\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three
% find nearest height in row
@@ -1778,8 +1778,8 @@
\dorecurse\c_tabl_ntb_maximum_col
{\ifnum\recurselevel=\c_tabl_ntb_current_col_three\else
\ifcsname\tabl_ntb_row_pattern\c_tabl_ntb_current_row_three\recurselevel\endcsname
- \!!countc=\tabl_ntb_get_row\c_tabl_ntb_current_row_three\recurselevel\relax
- \ifnum\!!countc=\plusone
+ \scratchcounterthree\tabl_ntb_get_row\c_tabl_ntb_current_row_three\recurselevel\relax
+ \ifnum\scratchcounterthree=\plusone
\dimen4=\tabl_ntb_get_ht\c_tabl_ntb_current_row_three\recurselevel\relax
\ifdim\dimen2<\dimen4
\dimen2=\dimen4
@@ -1790,25 +1790,25 @@
\c_tabl_ntb_current_row_four\c_tabl_ntb_current_row_three
% calculate cummulative height
\dimen4=\dimen2
- \!!countc\c_tabl_ntb_current_row_three
- \advance\!!countc\minusone
- \dorecurse\!!countb
+ \scratchcounterthree\c_tabl_ntb_current_row_three
+ \advance\scratchcounterthree\minusone
+ \dorecurse\scratchcountertwo
{\ifnum\c_tabl_ntb_current_row_four=\c_tabl_ntb_current_row_three\else
\advance\dimen4 \tabl_ntb_get_hei\c_tabl_ntb_current_row_four
\fi
- \ifnum\recurselevel=\!!countb\else
- \tabl_ntb_set_nob\!!countc
- \advance\!!countc\plusone
+ \ifnum\recurselevel=\scratchcountertwo\else
+ \tabl_ntb_set_nob\scratchcounterthree
+ \advance\scratchcounterthree\plusone
\fi
\advance\c_tabl_ntb_current_row_four\plusone}%
% distribute overshoot equally
\ifdim\dimen2>\zeropoint % new: test on natural-003
\ifdim\dimen4<\dimen0
\advance\dimen0 -\dimen4
- \divide\dimen0 \!!countb
+ \divide\dimen0 \scratchcountertwo
\c_tabl_ntb_current_row_four\c_tabl_ntb_current_row_three
\tabl_ntb_set_hei\c_tabl_ntb_current_row_three{\the\dimen2}%
- \dorecurse\!!countb
+ \dorecurse\scratchcountertwo
{\dorecurse\c_tabl_ntb_maximum_col
{\ifnum\recurselevel=\c_tabl_ntb_current_col_three\else
\scratchdimen\dimexpr\tabl_ntb_get_ht\c_tabl_ntb_current_row_four\recurselevel+\dimen0\relax
diff --git a/tex/context/base/mkiv/tabl-tab.mkxl b/tex/context/base/mkiv/tabl-tab.mkxl
index 96eade4b4..e6449396c 100644
--- a/tex/context/base/mkiv/tabl-tab.mkxl
+++ b/tex/context/base/mkiv/tabl-tab.mkxl
@@ -1563,20 +1563,20 @@
\def\tabl_table_split_box#1%
{\resettsplit
- \def\tsplitminimumfreelines{2}%
- \def\tsplitminimumfreespace{\zeropoint}%
- \setbox\tsplitcontent\box#1%
+ \c_split_minimum_free_lines\plustwo
+ \d_split_minimum_free_space\zeropoint
+ \setbox\b_split_content\box#1%
\ifconditional\c_tabl_table_repeat_head \ifconditional\hassometablehead
- \setbox\tsplithead\vsplit\tsplitcontent to \lineheight
- \setbox\tsplithead\vbox{\unvbox\tsplithead}% \vpack ?
+ \setbox\b_split_head\vsplit\b_split_content to \lineheight
+ \setbox\b_split_head\vbox{\unvbox\b_split_head}% \vpack ?
\fi \fi
\ifconditional\c_tabl_table_repeat_tail \ifconditional\hassometabletail
- \setbox\tsplittail\vsplit\tsplitcontent to \lineheight
- \setbox\tsplittail\vbox{\unvbox\tsplittail}% \vpack ?
+ \setbox\b_split_tail\vsplit\b_split_content to \lineheight
+ \setbox\b_split_tail\vbox{\unvbox\b_split_tail}% \vpack ?
\fi \fi
\ifinsidefloat\else
- \def\tsplitbeforeresult{\startbaselinecorrection}%
- \def\tsplitafterresult {\stopbaselinecorrection}%
+ \t_split_before_result{\startbaselinecorrection}%
+ \t_split_after_result {\stopbaselinecorrection}%
\fi
\handletsplit}
diff --git a/tex/context/base/mkiv/tabl-tbl.mkxl b/tex/context/base/mkiv/tabl-tbl.mkxl
index 1149a38d7..723758fb8 100644
--- a/tex/context/base/mkiv/tabl-tbl.mkxl
+++ b/tex/context/base/mkiv/tabl-tbl.mkxl
@@ -2310,8 +2310,8 @@
\dostarttaggedchained\t!tabulate\empty\??tabulation
\dostarttagged\t!tabulaterow\empty
\setfalse\inhibitmargindata % new per 2012.06.13 ... really needed
- % \everycr\expandafter{\the\everycr\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
- \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
+% % \everycr\expandafter{\the\everycr\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
+% \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row\dostoptagged\dostarttagged\t!tabulaterow\empty}}%
\expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}%
\dostoptagged
\dostoptagged
@@ -2370,14 +2370,14 @@
\def\tabl_split_box_indeed#1%
{\resettsplit
- \def\tsplitminimumfreelines{2}%
- \def\tsplitminimumfreespace{0pt}%
- \setbox\tsplitcontent\box#1%
+ \c_split_minimum_free_lines\plustwo
+ \d_split_minimum_free_space\zeropoint
+ \setbox\b_split_content\box#1%
\ifcase\c_tabl_tabulate_repeathead\or
- \setbox\tsplithead\vsplit\tsplitcontent to \lineheight
- \setbox\tsplithead\vbox{\unvbox\tsplithead}%
+ \setbox\b_split_head\vsplit\b_split_content to \lineheight
+ \setbox\b_split_head\vbox{\unvbox\b_split_head}%
\or
- \setbox\tsplithead\vbox{\hbox{\strut\tabulationparameter\c!title}}%
+ \setbox\b_split_head\vbox{\hbox{\strut\tabulationparameter\c!title}}%
\fi
\handletsplit}
diff --git a/tex/context/base/mkiv/tabl-tsp.mkxl b/tex/context/base/mkiv/tabl-tsp.mkxl
new file mode 100644
index 000000000..f09a5d9d8
--- /dev/null
+++ b/tex/context/base/mkiv/tabl-tsp.mkxl
@@ -0,0 +1,575 @@
+%D \module
+%D [ file=tabl-tsp,
+%D version=2000.10.20,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Splitting,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Table Macros / Splitting}
+
+%D The code in this file is moved here from other places and needs a mkiv cleanup.
+%D As it mostly targets at tables the code lives in the tabl and page namespaces.
+
+% work in progress
+
+\unprotect
+
+%D Although the name resembles floats, and therefore this should be a page module,
+%D we decided to make it core functionality because the table code depends on it.
+%D Othrwise there would be too much overloading afterwards involved. Actually, the
+%D float part is rather generic and not that related to floats.
+
+% \splitfloat [settings] {\placetable[optional args]{test}} {content}
+
+%D When \type {inbetween} is made empty instead of the default \type {\page}, we
+%D will get delayed flushing and text may continue below the graphic.
+%D
+%D \starttyping
+%D \dorecurse{2}{\input tufte }
+%D
+%D \splitfloat[lines=auto,inbetween=]
+%D {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}}
+%D {\bTABLE[split=yes]
+%D \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR
+%D \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR
+%D \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR
+%D \bTR \bTD 14 \eTD \bTD test \eTD \eTR
+%D \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR
+%D \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR
+%D \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR
+%D \bTR \bTD 24 \eTD \bTD test \eTD \eTR
+%D \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR
+%D \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR
+%D \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR
+%D \bTR \bTD 34 \eTD \bTD test \eTD \eTR
+%D \eTABLE}
+%D
+%D \dorecurse{10}{\input tufte }
+%D \stoptyping
+
+\installcorenamespace{floatsplitting}
+
+\installdirectcommandhandler \??floatsplitting {floatsplitting} % \??floatsplitting
+
+\setupfloatsplitting
+ [\c!conversion=\v!character, % \v!romannumerals
+ \c!lines=3,
+ \c!before=,
+ \c!inbetween=\page,
+ \c!after=]
+
+\newconditional\splitfloatfirstdone
+\newconditional\somenextsplitofffloat
+\newconditional\splitfloatdone
+\newconditional\onlyonesplitofffloat \settrue\onlyonesplitofffloat
+
+\newif \ifinsidesplitfloat % will become conditional
+
+\newcount \noffloatssplits
+\newtoks \everysplitfloatsetup
+
+\let \extrasplitfloatlines \!!zerocount
+\let \splitfloatfinalizer \relax
+
+\mutable\let \floatcaptionsuffix \empty
+
+\permanent\tolerant\protected\def\splitfloat[#1]#:#2% nog dubbele refs
+ {\bgroup
+ \global\setfalse\splitfloatdone
+ \aftergroup\page_split_float_check
+ \insidefloattrue
+ \insidesplitfloattrue
+ \setupcurrentfloatsplitting[#1]%
+ \global\noffloatssplits\zerocount
+ \let\floatcaptionsuffix\page_split_float_suffix
+ \edef\extrasplitfloatlines{\floatsplittingparameter\c!lines}%
+ \the\everysplitfloatsetup
+ \def\splitfloatcommand{#2}%
+ \global\settrue \onlyonesplitofffloat
+ \global\setfalse\somenextsplitofffloat
+ \page_floats_push_saved
+ \floatsplittingparameter\c!before
+ \let\next} % \bgroup
+
+\protected\def\page_split_float_suffix
+ {\begingroup
+ \usefloatsplittingstyleandcolor\c!style\c!color % only the suffix
+ \convertnumber{\floatsplittingparameter\c!conversion}\noffloatssplits
+ \endgroup}
+
+\protected\def\page_split_float_check
+ {\ifconditional\splitfloatdone
+ \splitfloatfinalizer % a weird place (could interfere with flushing)
+ \else
+ \blank
+ \begingroup
+ \tttf \dontleavehmode \getmessage\m!floatblocks{13}\empty
+ \endgroup
+ \blank
+ \showmessage\m!floatblocks{13}\empty
+ \fi}
+
+\def\page_split_float_process % nextbox
+ {\ifinsidesplitfloat
+ \expandafter\page_split_float_process_yes
+ \else
+ \expandafter\page_split_float_process_nop
+ \fi}
+
+\def\page_split_float_process_yes
+ {\dowithnextboxcs\page_split_float_process_finish\vbox}
+
+\def\page_split_float_process_finish
+ {\forgetall
+ \dontcomplain
+ \global\settrue\splitfloatdone
+ % \nodelocationmode\zerocount % bypass auto-renumbering
+ \global\advance\noffloatssplits\plusone
+ \ifcase\noffloatssplits\relax \or
+ \ifconditional\onlyonesplitofffloat
+ \let\floatcaptionsuffix\empty
+ \fi
+ \fi
+ \bgroup
+ \ifconditional\somenextsplitofffloat
+ \notesenabledfalse % best here, experimental, brrr; test with note in caption
+ \fi
+ \splitfloatcommand{\box\nextbox}%
+ \egroup
+ \ifconditional\somenextsplitofffloat
+ \edef\p_inbetween{\floatsplittingparameter\c!inbetween}%
+ \ifempty\p_inbetween
+ \ifconditional\splitfloatfirstdone\else\page\fi
+ \else
+ \p_inbetween
+ \fi
+ \else
+ \floatsplittingparameter\c!after
+ \page_floats_pop_saved
+ \page_floats_flush_saved
+ \fi
+ \global\settrue\splitfloatfirstdone}
+
+\def\page_split_float_process_nop
+ {\dowithnextboxcs\page_split_float_process_nop_finish\vbox}
+
+\def\page_split_float_process_nop_finish
+ {\forgetall
+ \dontcomplain
+ \box\nextbox % maybe an option to unvbox
+ \global\settrue\splitfloatfirstdone}
+
+\def\page_split_float_check_content#1% box
+ {\ifinsidesplitfloat
+ % \ifdim\ht#1=\zeropoint % funny: \ifcase does not check for overflow
+ \ifcase\ht#1\relax
+ \global\setfalse\somenextsplitofffloat
+ \else
+ \global\settrue \somenextsplitofffloat
+ \global\setfalse\onlyonesplitofffloat
+ \fi
+ \fi}
+
+\def\page_split_float_check_caption#1% depends on page-flt .. pretty messy
+ {\edef\extrasplitfloatlines{\extrasplitfloatlines}%
+ \ifx\extrasplitfloatlines\v!auto
+ \bgroup
+ \forcelocalfloats
+ \setuplocalfloats[\c!before=,\c!after=,\c!inbetween=]%
+ % This controls samepage resetting too but it also messes up the numbering
+ % so I need another fix.
+% \settrialtypesetting
+ \splitfloatcommand{\hbox to #1{\strut}}% dummy line
+% \resettrialtypesetting
+ \setbox\scratchbox\vbox{\flushlocalfloats}% \vpack ?
+ \getnoflines{\ht\scratchbox}%
+ \resetlocalfloats
+ \advance\noflines\minusone % compensate dummy line
+ \normalexpanded{\egroup\noexpand\edef\noexpand\extrasplitfloatlines{\the\noflines}}%
+ \global\settrue\usesamefloatnumber
+ \else
+ \doifelsenumber\extrasplitfloatlines\donothing{\def\extrasplitfloatlines{1}}%
+ \fi}
+
+\permanent\protected\def\doifnotinsidesplitfloat
+ {\ifinsidesplitfloat
+ \expandafter\gobbleoneargument
+ \fi}
+
+%D Table splitter, on top of previous code:
+
+% todo: keep tail to rest, so we need a lookahead
+
+\newbox\b_split_content
+\newbox\b_split_result
+\newbox\b_split_head
+\newbox\b_split_next
+\newbox\b_split_tail
+
+\newtoks\t_split_before_result
+\newtoks\t_split_after_result
+\newtoks\t_split_before
+\newtoks\t_split_inbetween
+\newtoks\t_split_after
+
+\newtoks\everyresettsplit
+
+\newcount\c_split_minimum_free_lines
+
+\newdimen\d_split_minimum_free_space
+\newdimen\d_split_available_height
+\newdimen\d_split_inbetween_height
+
+\newconditional\c_tabl_split_done
+\newconditional\c_tabl_split_head
+\newconditional\c_tabl_split_full
+
+\newconditional\tabl_split_forced_page
+
+\appendtoks
+ \c_split_minimum_free_lines\zerocount
+ \d_split_minimum_free_space\zeropoint
+ \setbox\b_split_content \emptyvbox
+ \setbox\b_split_result \emptyvbox
+ \setbox\b_split_head \emptyvbox
+ \setbox\b_split_next \emptyvbox
+ \setbox\b_split_tail \emptyvbox
+ \t_split_before_result \emptytoks
+ \t_split_after_result \emptytoks
+ \t_split_inbetween \emptytoks
+ \t_split_before \emptytoks
+ \t_split_after \emptytoks
+ \let\postprocesstsplit \donothing
+\to \everyresettsplit
+
+\permanent\protected\def\resettsplit
+ {\the\everyresettsplit}
+
+\resettsplit
+
+\def\tsplitdirectwidth{\hsize}
+
+\protected\def\handletsplit
+ {\page_split_float_check_caption{\wd\b_split_content}%
+ \global\setfalse\splitfloatfirstdone
+ \testpagesync % new, sync, but still tricky
+ [\number\c_split_minimum_free_lines]
+ [\dimexpr\d_split_minimum_free_space+\extrasplitfloatlines\lineheight\relax]%
+ \setbox\scratchbox\vbox{\the\t_split_inbetween}%
+ \d_split_inbetween_height\htdp\scratchbox
+ \setfalse\c_tabl_split_done
+ \doloop\tabl_split_loop_body
+ \global\setfalse\usesamefloatnumber % new, prevent next increment
+ \global\setfalse\splitfloatfirstdone} % we can use this one for tests
+
+\def\tabl_split_loop_body
+ {\ifinsidecolumns
+ % brrr, assumes empty columns
+ \global\setfalse\splitfloatfirstdone
+ \d_split_available_height\textheight
+ \settrue\c_tabl_split_full
+ \else
+ \ifconditional\splitfloatfirstdone
+ \d_split_available_height\textheight
+ \settrue\c_tabl_split_full
+ \orelse\ifdim\pagegoal<\maxdimen
+ \d_split_available_height\dimexpr\pagegoal-\pagetotal\relax
+ \setfalse\c_tabl_split_full
+ \else
+ \d_split_available_height\textheight
+ \settrue\c_tabl_split_full
+ \fi
+ \fi
+ \d_split_available_height \dimexpr
+ \d_split_available_height
+ -\d_split_inbetween_height
+ -\d_split_minimum_free_space
+ -\extrasplitfloatlines\lineheight
+ \relax
+ \ifdim\htdp\b_split_tail>\zeropoint
+ \advance\d_split_available_height-\htdp\b_split_tail
+ \fi
+ \setbox\b_split_result\vbox
+ {\ifdim\ht\b_split_head>\zeropoint
+ \unvcopy\b_split_head
+ \the\t_split_inbetween
+ \fi}%
+ \ifconditional\c_tabl_split_done \else
+ \ifdim\ht\b_split_next>\zeropoint
+ \setbox\b_split_head\box\b_split_next
+ \fi
+ \fi
+ \settrue\c_tabl_split_done
+ \ifdim\ht\b_split_result>\zeropoint
+ \settrue\c_tabl_split_head % table head
+ \else
+ \setfalse\c_tabl_split_head % no tablehead
+ \fi
+ \splittopskip\zeropoint
+ \doloop % inner loop
+ {\setbox\scratchbox\vsplit\b_split_content to \onepoint % \lineheight
+ \setbox\scratchbox\vbox % \vpack
+ {\unvbox\scratchbox
+ \setbox\scratchbox\vbox % \vpack
+ {\splitdiscards
+ \ifnum\lastpenalty>-\plustenthousand\else
+ % so that \bTR[before=\page] works
+ \global\settrue\tabl_split_forced_page
+ \fi}}%
+ \ifconditional\tabl_split_forced_page
+ \global\setfalse\tabl_split_forced_page
+ \setbox\b_split_result\vbox
+ {\unvbox\b_split_result
+ \the\t_split_inbetween
+ \unvbox\scratchbox}%
+ \exitloop
+ \orelse\ifdim\dimexpr\d_split_available_height-\htdp\scratchbox-\htdp\b_split_result\relax>\zeropoint
+ \setbox\b_split_result\vbox
+ {\unvbox\b_split_result
+ \the\t_split_inbetween
+ \unvbox\scratchbox}%
+ \ifvoid\b_split_content \exitloop \fi
+ \orelse\ifconditional\c_tabl_split_head
+ % we only have a tablehead so far
+ \setbox\b_split_result\vbox{\unvbox\b_split_result\unvbox\scratchbox}% \vpack
+ \exitloop
+ \orelse\ifconditional\c_tabl_split_full
+ % we have text height available, but the (one) cell is too
+ % large to fit, so, in order to avoid loops/deadcycles we do:
+ \setbox\b_split_result\vbox
+ {\unvbox\b_split_result
+ \the\t_split_inbetween
+ \unvbox\scratchbox}%
+ \exitloop
+ \else
+ \setbox\b_split_content\vbox
+ {\unvbox\scratchbox
+ \the\t_split_inbetween
+ \ifvoid\b_split_content\else\unvbox\b_split_content\fi}%
+ \exitloop
+ \fi
+ \setfalse\c_tabl_split_head
+ \setfalse\c_tabl_split_full}%
+ \postprocesstsplit
+ \page_split_float_check_content\b_split_content
+ \ifvoid\b_split_content
+ \setbox\b_split_result\vbox
+ {\unvbox\b_split_result
+ \the\t_split_inbetween
+ \unvcopy\b_split_tail}%
+ \page_split_float_process{\the\t_split_before_result\box\b_split_result\the\t_split_after_result}%
+ \doifnotinsidesplitfloat{\the\t_split_after}%
+ \endgraf
+ \exitloop
+ \else
+ % hack
+ \ifdim\pagegoal<\maxdimen
+ \pagegoal\dimexpr\pagegoal+\lineheight\relax % etex
+ \fi
+ % brrr
+ \ifdim\ht\b_split_result>\zeropoint
+ \setbox\b_split_result\vbox
+ {\unvbox\b_split_result
+ \the\t_split_inbetween
+ \unvcopy\b_split_tail}%
+ \page_split_float_process{\the\t_split_before_result\box\b_split_result\the\t_split_after_result}%
+ \doifnotinsidesplitfloat{\the\t_split_after}%
+ \endgraf
+ \global\settrue\usesamefloatnumber % new, prevent next increment
+ \fi
+ \ifinsidecolumns
+ \goodbreak % was \doifnotinsidesplitfloat\goodbreak
+ \else
+ \page % was \doifnotinsidesplitfloat\page
+ \fi
+ \fi}
+
+%D The next one assumes that the split takes place elsewhere. This is used in
+%D xtables.
+
+\aliased\let\resetdirecttsplit\resettsplit
+
+\permanent\protected\def\handledirecttsplit
+ {\page_split_float_check_caption{\tsplitdirectwidth}%
+ \global\setfalse\splitfloatfirstdone
+ \testpagesync % new, sync, but still tricky
+ [\number\c_split_minimum_free_lines]
+ [\dimexpr\d_split_minimum_free_space+\extrasplitfloatlines\lineheight\relax]%
+ \doloop\tabl_split_direct_loop_body
+ \global\setfalse\usesamefloatnumber % new, prevent next increment
+ \global\setfalse\splitfloatfirstdone} % we can use this one for tests
+
+\def\tabl_split_direct_loop_body
+ {\ifinsidecolumns
+ \global\setfalse\splitfloatfirstdone
+ \d_split_available_height\textheight
+ \orelse\ifconditional\splitfloatfirstdone
+ \d_split_available_height\textheight
+ \orelse\ifdim\pagegoal<\maxdimen
+ \d_split_available_height\dimexpr\pagegoal-\pagetotal\relax
+ \else
+ \d_split_available_height\textheight
+ \fi
+ \d_split_available_height\dimexpr
+ \d_split_available_height
+ -\d_split_minimum_free_space
+ -\extrasplitfloatlines\lineheight
+ \relax
+ \tsplitdirectsplitter\d_split_available_height % also sets state
+ \ifdim\ht\b_split_result>\zeropoint
+ \ifconditional\somenextsplitofffloat
+ \global\setfalse\onlyonesplitofffloat
+ \fi
+ \ifdim\pagegoal<\maxdimen
+ \pagegoal\dimexpr\pagegoal+\lineheight\relax % etex
+ \fi
+ \page_split_float_process{\the\t_split_before_result\box\b_split_result\the\t_split_after_result}%
+ \global\settrue\usesamefloatnumber % new, prevent next increment
+ \endgraf
+ \ifconditional\somenextsplitofffloat
+ \ifinsidecolumns
+ \goodbreak
+ \else
+ \page
+ \fi
+ \fi
+ \global\settrue\splitfloatfirstdone
+ \orelse\ifconditional\somenextsplitofffloat
+ \ifinsidecolumns
+ \goodbreak
+ \else
+ \page % no room
+ \fi
+ \else
+ \exitloop
+ \fi}
+
+%D Maybe handy:
+%D
+%D \starttyping
+%D \splitfloat
+%D {\placefigure{some caption}}
+%D {\startsplittext
+%D \typefile[option=TEX,before=,after=]{oeps.tex}
+%D \stopsplittext}
+%D \stoptyping
+
+\permanent\def\handlesplittext#1%
+ {\setbox\b_split_result\vbox
+ {\vsplit\b_split_content to \dimexpr#1-\lineheight\relax}}
+
+\permanent\protected\def\startsplittext
+ {\begingroup
+ \resettsplit
+ \c_split_minimum_free_lines\zerocount
+ \d_split_minimum_free_space\zeropoint
+ \let\extrasplitfloatlines \!!plusone
+ \let\tsplitdirectsplitter \handlesplittext
+ \setbox\b_split_content\vbox\bgroup
+ \insidefloattrue}
+
+\permanent\protected\def\stopsplittext
+ {\egroup
+ \handledirecttsplit
+ \endgroup}
+
+\protect \endinput
+
+% test cases
+
+% \setupTABLE[split=repeat]
+%
+% \input tufte \endgraf
+% \splitfloat[lines=11]
+% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}}
+% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \splitfloat[lines=0]
+% {}
+% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE}
+% \input tufte \endgraf \page
+%
+% \input tufte \endgraf
+% \bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE
+% \input tufte \page
+
+% \setuptabulate[split=yes]
+%
+% \input tufte \endgraf
+% \splitfloat[lines=11]
+% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}}
+% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \splitfloat[lines=0]
+% {}
+% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate
+% \input tufte \page
+
+% \setuptables[split=yes]
+%
+% \newtoks\TestToks
+%
+% \TestToks\emptytoks
+% \appendtoks\starttablehead\to\TestToks
+% \dorecurse{3}{\appendtoks\VL head \VL head \VL \SR\to\TestToks}
+% \appendtoks\stoptablehead\to\TestToks
+% \appendtoks\starttabletail\to\TestToks
+% \dorecurse{3}{\appendtoks\VL tail \VL tail \VL \SR\to\TestToks}
+% \appendtoks\stoptabletail\to\TestToks
+% \appendtoks\starttables[|c|c|]\to\TestToks
+% \dorecurse{100}{\appendtoks\VL test \VL test \VL \SR\to\TestToks}
+% \appendtoks\stoptables\to\TestToks
+%
+% \input tufte \endgraf
+% \splitfloat[lines=auto] % [lines=11]
+% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}}
+% {\the\TestToks}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \splitfloat[lines=0]
+% {}
+% {\the\TestToks}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \the\TestToks
+% \input tufte \page
+%
+% multiple floats
+%
+% \starttext
+% \dorecurse{3}{\input tufte } \endgraf
+% \dorecurse{5}{\placefigure{}{\framed[height=.5\textheight]{}}}
+% \splitfloat[lines=auto,inbetween=]
+% {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}}
+% {\bTABLE[split=yes]
+% \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR
+% \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR
+% \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR
+% \bTR \bTD 14 \eTD \bTD test \eTD \eTR
+% \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR
+% \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR
+% \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR
+% \bTR \bTD 24 \eTD \bTD test \eTD \eTR
+% \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR
+% \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR
+% \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR
+% \bTR \bTD 34 \eTD \bTD test \eTD \eTR
+% \eTABLE}
+% \dorecurse{10}{\input tufte }
+% \stoptext
diff --git a/tex/context/base/mkiv/tabl-xtb.mklx b/tex/context/base/mkiv/tabl-xtb.mklx
index 41e7c9b86..906355d42 100644
--- a/tex/context/base/mkiv/tabl-xtb.mklx
+++ b/tex/context/base/mkiv/tabl-xtb.mklx
@@ -68,13 +68,6 @@
% cells: option=fixed : nils autostretch (not yet complete)
% \setbox\scratchbox\hbox attr \taggedattribute \c_attr_tagged {...}
-%
-% \let\tsplitbeforeresult\donothing
-% \let\tsplitafterresult \donothing
-% \let\tsplitinbetween \donothing
-% \let\tsplitbefore \donothing
-% \let\tsplitafter \donothing
-% \let\postprocesstsplit \donothing
\aliased\let\dotagxtablecell \relax % names will change
\aliased\let\dotagxtablesignal\relax % names will change
@@ -426,15 +419,15 @@
\protected\def\tabl_x_flush_float_split
{\resetdirecttsplit
- \edef\extrasplitfloatlines {\xtableparameter\c!split}%
- \edef\tsplitminimumfreespace{\the\dimexpr\extratxtablesplitheight+\xtableparameter\c!splitoffset\relax}%
- % \edef\tsplitminimumfreelines{2}% not needed here as we're precise enough
+ \edef\extrasplitfloatlines{\xtableparameter\c!split}%
+ \d_split_minimum_free_space\dimexpr\extratxtablesplitheight+\xtableparameter\c!splitoffset\relax
+ %\c_split_minimum_free_lines\plustwo % not needed here as we're precise enough
\let\tsplitdirectsplitter\tabl_x_split_splitter
\let\tsplitdirectwidth \d_tabl_x_final_width
\handledirecttsplit}
\protected\def\tabl_x_split_splitter#height%
- {\setbox\tsplitresult\vbox
+ {\setbox\b_split_result\vbox
{\clf_x_table_flush
method {\v!split}%
height \dimexpr#height\relax
diff --git a/tex/context/base/mkiv/task-ini.mkxl b/tex/context/base/mkiv/task-ini.mkxl
new file mode 100644
index 000000000..77e4fa985
--- /dev/null
+++ b/tex/context/base/mkiv/task-ini.mkxl
@@ -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 \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Task Handler / initialization}
+
+\unprotect
+
+%D Maybe we will make things configureable (speed up and such).
+
+\registerctxluafile{task-ini}{}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/toks-aux.lmt b/tex/context/base/mkiv/toks-aux.lmt
index e1a4e89b3..03f4dc2c1 100644
--- a/tex/context/base/mkiv/toks-aux.lmt
+++ b/tex/context/base/mkiv/toks-aux.lmt
@@ -133,6 +133,7 @@ local glyphoptioncodes = { }
local hyphenationcodes = { }
local frozenparcodes = { }
local flagcodes = { }
+local normalizecodes = { }
for k, v in next, tex.getgroupvalues() do
groupcodes[k] = gsub(v,"[_ ]","")
@@ -149,6 +150,9 @@ end
for k, v in next, tex.getflagvalues() do
flagcodes[k] = gsub(v,"[_ ]","")
end
+for k, v in next, tex.getnormalizevalues() do
+ normalizecodes[k] = gsub(v,"[_ ]","")
+end
if environment.initex then
@@ -160,6 +164,7 @@ if environment.initex then
for k, v in next, hyphenationcodes do texintegerdef(v .. "hyphenationmodecode",k,"immutable") end
for k, v in next, frozenparcodes do texintegerdef("frozen" .. v .. "code", k,"immutable") end
for k, v in next, flagcodes do texintegerdef(v .. "flagcode", k,"immutable") end
+ for k, v in next, normalizecodes do texintegerdef(v .. "code", k,"immutable") end
end
@@ -168,9 +173,11 @@ glyphoptioncodes = utilities.storage.allocate(table.swapped(glyphoptioncodes
hyphenationcodes = utilities.storage.allocate(table.swapped(hyphenationcodes,hyphenationcodes))
frozenparcodes = utilities.storage.allocate(table.swapped(frozenparcodes, frozenparcodes))
flagcodes = utilities.storage.allocate(table.swapped(flagcodes, flagcodes))
+normalizecodes = utilities.storage.allocate(table.swapped(normalizecodes, normalizecodes))
tex.groupcodes = groupcodes
tex.glyphoptioncodes = glyphoptioncodes
tex.hyphenationcodes = hyphenationcodes
tex.frozenparcodes = frozenparcodes
tex.flagcodes = flagcodes
+tex.normalizecodes = normalizecodes
diff --git a/tex/context/base/mkiv/typo-dir.mkxl b/tex/context/base/mkiv/typo-dir.mkxl
index ac7924603..55fabffc0 100644
--- a/tex/context/base/mkiv/typo-dir.mkxl
+++ b/tex/context/base/mkiv/typo-dir.mkxl
@@ -89,7 +89,7 @@
\appendtoks
\edef\p_option{\directionsparameter\c!break}% name can change
- \bitwiseflip\normalizelinemode\ifx\p_option\v!both\else-\fi\breakafterdirmodecode
+ \bitwiseflip\normalizelinemode\ifx\p_option\v!both\else-\fi\breakafterdircode
\to \everysetupdirections
% bidi: local=obey grouping, global=ignore grouping (unicode has no grouping)
diff --git a/tex/context/base/mkiv/typo-mar.mkxl b/tex/context/base/mkiv/typo-mar.mkxl
index 8c8fc218e..5d6f15f21 100644
--- a/tex/context/base/mkiv/typo-mar.mkxl
+++ b/tex/context/base/mkiv/typo-mar.mkxl
@@ -313,11 +313,8 @@
%D Downward compatible hack:
-\permanent\protected\def\typo_margins_space_or_par
- {\endgraf\ifhmode\space\fi}
-
\appendtoks
- \enforced\let\\\typo_margins_space_or_par
+ \enforced\let\\\spaceorpar
\to \everymargindatacontent
%D Another one:
diff --git a/tex/context/modules/mkiv/s-system-macros.mkxl b/tex/context/modules/mkiv/s-system-macros.mkxl
index a28a27775..91aad763a 100644
--- a/tex/context/modules/mkiv/s-system-macros.mkxl
+++ b/tex/context/modules/mkiv/s-system-macros.mkxl
@@ -110,18 +110,21 @@
local whatever = find(k,"^[a-z][a-z][a-z]+_")
local filename = files[k]
local csname = context.escape(k)
- ctx_NC() if dealtwith then context("+") elseif whatever then context("-") elseif instance then context("!")end
- ctx_NC() if primitive then ctx_bold(csname) else context(csname) end
+ ctx_NC() if dealtwith then context("+")
+ elseif whatever then context("-")
+ elseif instance then context("!") end
+ ctx_NC() if primitive then ctx_bold(csname) else
+ context(csname) end
ctx_NC() if parameters then context(parameters > 0 and parameters or "-") end
- ctx_NC() context(cscommand)
- ctx_NC() if primitive then context(primitive) end
- ctx_NC() if permanent then context(permanent) end
- ctx_NC() if frozen then context(frozen) end
- ctx_NC() if immutable then context(immutable) end
- ctx_NC() if mutable then context(mutable) end
- ctx_NC() if instance then context(instance) end
- ctx_NC() if noaligned then context(noaligned) end
- ctx_NC() if filename then context(hashnames[filename]) end
+ ctx_NC() context(cscommand)
+ ctx_NC() if primitive then context(primitive) end
+ ctx_NC() if permanent then context(permanent) end
+ ctx_NC() if frozen then context(frozen) end
+ ctx_NC() if immutable then context(immutable) end
+ ctx_NC() if mutable then context(mutable) end
+ ctx_NC() if instance then context(instance) end
+ ctx_NC() if noaligned then context(noaligned) end
+ ctx_NC() if filename then context(hashnames[filename]) end
ctx_NC() ctx_NR()
if visible then
total = total + 1
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index a7b27b278..142d53e44 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2020-11-17 12:39
+-- merge date : 2020-11-18 19:13
do -- begin closure to overcome local limits and interference