summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-03-01 15:15:08 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-03-01 15:15:08 +0100
commit2a958dcf22dd71ba1e4408648676d44c16d7e3bf (patch)
tree8a118b195ac47f9e926bb5083f3d0f91c352d281
parent48c3ce21b30a886099e9afc2edf683e8a47ba29e (diff)
downloadcontext-2a958dcf22dd71ba1e4408648676d44c16d7e3bf.tar.gz
2016-03-01 14:06:00
-rw-r--r--doc/context/documents/general/columnsets/columnsets.pdfbin0 -> 4513531 bytes
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-000.tex63
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-001.tex17
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-002.tex17
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-003.tex35
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-004.tex32
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-005.tex29
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-006.tex35
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-007.tex43
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-101.tex30
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-102.tex36
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-103.tex37
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-201.tex31
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-202.tex32
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-203.tex29
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-204.tex41
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-205.tex42
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-206.tex29
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-301.tex29
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-401.tex26
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-402.tex24
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-403.tex23
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-404.tex34
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-405.tex29
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-601.tex29
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-701.tex23
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-702.tex27
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-703.tex34
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-704.tex69
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-801.tex19
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-802.tex22
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-803.tex26
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-804.tex26
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-805.tex26
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-806.tex26
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-901.tex38
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-902.tex38
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets-903.tex41
-rw-r--r--doc/context/sources/general/columnsets/columnsets/columnsets.tex871
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-libraries.tex20
-rw-r--r--tex/context/base/context-version.pdfbin4169 -> 4170 bytes
-rw-r--r--tex/context/base/mkii/mult-de.mkii1
-rw-r--r--tex/context/base/mkii/mult-en.mkii1
-rw-r--r--tex/context/base/mkii/mult-fr.mkii1
-rw-r--r--tex/context/base/mkii/mult-it.mkii1
-rw-r--r--tex/context/base/mkii/mult-nl.mkii1
-rw-r--r--tex/context/base/mkii/mult-pe.mkii1
-rw-r--r--tex/context/base/mkii/mult-ro.mkii1
-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/m-newcolumnsets.mkiv38
-rw-r--r--tex/context/base/mkiv/m-newotf.mkiv89
-rw-r--r--tex/context/base/mkiv/m-oldotf.mkiv6
-rw-r--r--tex/context/base/mkiv/math-frc.mkiv22
-rw-r--r--tex/context/base/mkiv/mult-def.lua4
-rw-r--r--tex/context/base/mkiv/page-cst.lua1454
-rw-r--r--tex/context/base/mkiv/page-cst.mkiv778
-rw-r--r--tex/context/base/mkiv/page-lin.lua169
-rw-r--r--tex/context/base/mkiv/page-lin.mkvi3
-rw-r--r--tex/context/base/mkiv/spac-ver.mkiv8
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin8959 -> 8977 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin267149 -> 267251 bytes
-rw-r--r--tex/context/base/mkiv/strc-con.mkvi16
-rw-r--r--tex/context/base/mkiv/strc-des.mkvi20
-rw-r--r--tex/context/base/mkiv/strc-lst.lua4
-rw-r--r--tex/context/base/mkiv/strc-not.lua32
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi12
-rw-r--r--tex/context/base/mkiv/strc-ref.lua13
-rw-r--r--tex/context/interface/common/keys-cs.xml1
-rw-r--r--tex/context/interface/common/keys-de.xml1
-rw-r--r--tex/context/interface/common/keys-en.xml1
-rw-r--r--tex/context/interface/common/keys-fr.xml1
-rw-r--r--tex/context/interface/common/keys-it.xml1
-rw-r--r--tex/context/interface/common/keys-nl.xml1
-rw-r--r--tex/context/interface/common/keys-pe.xml1
-rw-r--r--tex/context/interface/common/keys-ro.xml1
-rw-r--r--tex/context/modules/mkiv/m-visual.mkiv4
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
78 files changed, 4558 insertions, 213 deletions
diff --git a/doc/context/documents/general/columnsets/columnsets.pdf b/doc/context/documents/general/columnsets/columnsets.pdf
new file mode 100644
index 000000000..c79c63341
--- /dev/null
+++ b/doc/context/documents/general/columnsets/columnsets.pdf
Binary files differ
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-000.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-000.tex
new file mode 100644
index 000000000..429a067de
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-000.tex
@@ -0,0 +1,63 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[visual]
+\usemodule[simulate]
+
+\dontcomplain
+
+\startenvironment columnsets-000
+
+\useMPlibrary[dum]
+
+\setupbodyfont
+ [palatino]
+
+\setuplayout
+ [grid=yes]
+
+\setuplayout
+ [backspace=20mm,
+ cutspace=15mm,
+ width=middle,
+ height=middle]
+
+\setupsystem
+ [random=1234]
+
+\setuppagenumbering
+ [alternative=doublesided,
+ location=]
+
+\setupheadertexts
+ [pagenumber][right]
+ [left][pagenumber]
+
+\setupfootertexts
+ [\inputfilename]
+
+\setupfooter
+ [style=\tttf]
+
+\setuptolerance
+ [verytolerant,stretch]
+
+\definecolor[color-1][.5(red,green)]
+\definecolor[color-2][.5(green,blue)]
+\definecolor[color-3][.5(blue,red)]
+\definecolor[color-4][.5(white,black)]
+\definecolor[color-5][.5(white,color-4)]
+
+\startuniqueMPgraphic{frame}
+ fill OverlayBox withcolor \MPcolor{color-1} ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{contrast}
+ fill OverlayBox withcolor \MPcolor{color-3} ;
+\stopuniqueMPgraphic
+
+\defineoverlay[frame] [\uniqueMPgraphic{frame}]
+\defineoverlay[contrast][\uniqueMPgraphic{contrast}]
+
+\stopenvironment
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-001.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-001.tex
new file mode 100644
index 000000000..689f4e044
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-001.tex
@@ -0,0 +1,17 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=2]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{20}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-002.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-002.tex
new file mode 100644
index 000000000..a67dd3161
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-002.tex
@@ -0,0 +1,17 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][nleft=3,nright=2,width=5cm]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{15}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-003.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-003.tex
new file mode 100644
index 000000000..eed0286f8
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-003.tex
@@ -0,0 +1,35 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=2,page=left]
+
+\setupbackgrounds[text][background=color,backgroundcolor=color-1]
+
+\setupcolumnsetstart[example][1][1][2]
+\setupcolumnsetstart[example][1][2][4]
+\setupcolumnsetstart[example][2][1][6]
+\setupcolumnsetstart[example][2][2][6]
+\setupcolumnsetstart[example][3][1][4]
+\setupcolumnsetstart[example][3][2][2]
+
+\setupcolumnsetlines[example][1][1][-2]
+\setupcolumnsetlines[example][1][2][-4]
+\setupcolumnsetlines[example][2][1][-6]
+\setupcolumnsetlines[example][2][2][-6]
+\setupcolumnsetlines[example][3][1][-4]
+\setupcolumnsetlines[example][3][2][-2]
+\setupcolumnsetlines[example][4][1][4]
+\setupcolumnsetlines[example][4][2][10]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{20}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-004.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-004.tex
new file mode 100644
index 000000000..a58ddf621
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-004.tex
@@ -0,0 +1,32 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left]
+
+\definecolor[fakerulecolor]
+
+\definecolumnsetspan[wide] [n=2,background=contrast,color=white]
+\definecolumnsetspan[wider][n=4,background=contrast,color=white]
+
+\starttext
+
+\startcolumnset[example]
+
+ \startcolumnsetspan[wider]
+ wider: \dorecurse{2}{#1: \fakewords{25}{50}\par}
+ \stopcolumnsetspan
+
+ inbetween: \fakewords{25}{50}\par
+
+ \startcolumnsetspan[wide]
+ wide : \dorecurse{2}{#1: \fakewords{25}{50}\par}
+ \stopcolumnsetspan
+
+ after: \dorecurse{15}{#1: \fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-005.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-005.tex
new file mode 100644
index 000000000..f1d970d9e
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-005.tex
@@ -0,0 +1,29 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left]
+
+\definecolumnsetspan[wide][n=2,background=contrast,color=white]
+
+\definecolor[fakerulecolor]
+
+\starttext
+
+\startcolumnset[example]
+
+ \startcolumnsetspan[wide][default=btlr]
+
+ \startsimplecolumns
+ \dorecurse{2}{\fakewords{25}{40}\par}
+ \stopsimplecolumns
+
+ \stopcolumnsetspan
+
+ \dorecurse{15}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-006.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-006.tex
new file mode 100644
index 000000000..033619970
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-006.tex
@@ -0,0 +1,35 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left]
+
+\definecolor[fakerulecolor]
+
+\definecolumnsetspan[wide][n=2,background=contrast,color=white]
+
+\starttext
+
+\startcolumnset[example]
+
+ \startcolumnsetspan[wide]
+ \fakewords{25}{50}
+ \stopcolumnsetspan
+
+ \fakewords{25}{50}
+
+ \startcolumnsetspan[wide]
+ \fakewords{25}{50}
+ \stopcolumnsetspan
+
+ \startcolumnsetspan[wide][default=btrl]
+ \fakewords{25}{50}
+ \stopcolumnsetspan
+
+ \dorecurse{15}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-007.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-007.tex
new file mode 100644
index 000000000..137a414d9
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-007.tex
@@ -0,0 +1,43 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left]
+
+\definecolor[fakerulecolor]
+
+\definecolumnsetspan[wide][n=2,background=contrast,color=white]
+
+\starttext
+
+\startbuffer
+
+ \startcolumnsetspan[wide]
+ \fakewords{25}{50}
+ \stopcolumnsetspan
+
+ \fakewords{25}{50}
+
+ \startcolumnsetspan[wide]
+ \fakewords{25}{50}
+ \stopcolumnsetspan
+
+ \startcolumnsetspan[wide][default=btrl]
+ \fakewords{25}{50}
+ \stopcolumnsetspan
+
+ \dorecurse{3}{\fakewords{100}{200}\par}
+
+\stopbuffer
+
+\startcolumnset[example]
+
+ \dorecurse{4}{\getbuffer}
+
+ \dorecurse{5}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-101.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-101.tex
new file mode 100644
index 000000000..f9c7b59cb
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-101.tex
@@ -0,0 +1,30 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\starttext
+
+\startbuffer
+\fakewords{100}{200}
+\placefigure
+ {}
+ {\externalfigure[placeholder][width=\columnsetspanwidth{1}]}
+\fakewords{100}{200}
+\placefigure
+ {}
+ {\externalfigure[placeholder][width=\columnsetspanwidth{2}]}
+\fakewords{100}{200}
+\stopbuffer
+
+\startcolumnset[example]
+
+ \dorecurse {5}{\getbuffer}
+ \dorecurse{10}{\fakewords{100}{200}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-102.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-102.tex
new file mode 100644
index 000000000..3cf4dcd0e
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-102.tex
@@ -0,0 +1,36 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\starttext
+
+\startbuffer
+\placefigure [tbrl]
+ {tblr}
+ {\externalfigure[fake][width=\columnsetspanwidth{1},lines=5]}
+\placefigure [fxtb:6*4]
+ {fxtb}
+ {\externalfigure[fake][width=\columnsetspanwidth{2},lines=5]}
+\placefigure [btlr]
+ {btlr}
+ {\externalfigure[fake][width=\columnsetspanwidth{2},lines=5]}
+\placefigure [btlr]
+ {btlr}
+ {\externalfigure[fake][width=\columnsetspanwidth{3},lines=5]}
+
+\dorecurse {5} {
+ \fakewords{100}{200}\par
+}
+\stopbuffer
+
+\startcolumnset[example]
+
+ \dorecurse{6}{\getbuffer}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-103.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-103.tex
new file mode 100644
index 000000000..f1d4dbedc
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-103.tex
@@ -0,0 +1,37 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\starttext
+
+\startcolumnset[example]
+
+\useexternalfigure[fake][fake][width=\textwidth,lines=3]
+
+\placefigure[btlr]{brlr}{\externalfigure[fake]}
+\placefigure[btlr]{brlr}{\externalfigure[fake]}
+\placefigure[btrl]{btrl}{\externalfigure[fake]}
+\placefigure[btrl]{btrl}{\externalfigure[fake]}
+\placefigure[tblr]{tblr}{\externalfigure[fake]}
+\placefigure[tblr]{tblr}{\externalfigure[fake]}
+\placefigure[tbrl]{tbrl}{\externalfigure[fake]}
+\placefigure[tbrl]{tbrl}{\externalfigure[fake]}
+
+\placefigure[lrbt]{lrbt}{\externalfigure[fake]}
+\placefigure[lrbt]{lrbt}{\externalfigure[fake]}
+\placefigure[lrtb]{lrtb}{\externalfigure[fake]}
+\placefigure[lrtb]{lrtb}{\externalfigure[fake]}
+\placefigure[rlbt]{rlbt}{\externalfigure[fake]}
+\placefigure[rlbt]{rlbt}{\externalfigure[fake]}
+\placefigure[rltb]{rltb}{\externalfigure[fake]}
+\placefigure[rltb]{rltb}{\externalfigure[fake]}
+
+\dorecurse{10}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-201.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-201.tex
new file mode 100644
index 000000000..37b26c391
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-201.tex
@@ -0,0 +1,31 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [one]
+ [type=both,
+ x=1,y=1,nx=2,ny=6,
+ background=contrast,
+ state=repeat]
+
+\definecolumnsetarea
+ [two]
+ [type=both,
+ x=4,y=10,nx=1,ny=6,
+ background=contrast,
+ state=repeat]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{40}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-202.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-202.tex
new file mode 100644
index 000000000..1721d9cbc
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-202.tex
@@ -0,0 +1,32 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [one][left]
+ [x=1,y=1,nx=2,ny=6,
+ background=contrast,state=repeat]
+
+\definecolumnsetarea
+ [two][right]
+ [x=3,y=1,nx=2,ny=6,
+ background=contrast,state=repeat]
+
+\definecolumnsetarea
+ [three][both]
+ [x=2,y=10,nx=2,ny=6,
+ background=contrast,state=repeat]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{\fakewords{50}{100}}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-203.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-203.tex
new file mode 100644
index 000000000..6c15578bc
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-203.tex
@@ -0,0 +1,29 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [one]% [left]
+ [x=1,y=1,nx=6,ny=6,
+ background=contrast,state=start]
+
+\definecolumnsetarea
+ [two]%[left]
+ [x=3,y=10,nx=4,ny=6,
+ background=contrast,state=start]
+
+\stopsetups
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{25}{\fakewords{50}{100}}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-204.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-204.tex
new file mode 100644
index 000000000..d390f468e
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-204.tex
@@ -0,0 +1,41 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[oldfun]
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [title]
+ [x=1,y=1,nx=8,ny=8,
+ background=contrast,
+ color=white,
+ align={lohi,right},
+ state=start]
+
+\setupcolumnsetareatext
+ [title]
+ [\setups{the title}]
+
+\startsetups[the title]
+
+ \GapText
+ {\dimexpr\makeupwidth+\backspace\relax}
+ {6pt}
+ {RegularBold*default} {sa 4}
+ {A Title Spanni\+ng 2 Pages}
+
+\stopsetups
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-205.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-205.tex
new file mode 100644
index 000000000..b53709770
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-205.tex
@@ -0,0 +1,42 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[oldfun]
+
+\environment columnsets-000
+
+\unprotected \def\SpreadGapText#1#2{{\def\+{\blackrule[\c!width=#1]}#2}}
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [title]
+ [x=1,y=1,nx=8,ny=8,
+ background=contrast,
+ color=white,
+ align={lohi,right},
+ state=start]
+
+\setupcolumnsetareatext
+ [title]
+ [\setups{the title}]
+
+\startsetups[the title]
+
+ \GapText
+ {\dimexpr(\makeupwidth+\backspace)} {6pt}
+ {RegularBold} {sa 4}
+ {A Title Spanni\+ng 2 Pages}
+
+\stopsetups
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-206.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-206.tex
new file mode 100644
index 000000000..8b9f524b1
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-206.tex
@@ -0,0 +1,29 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [first]
+ [x=2,y=4,nx=2,ny=8,
+ background=contrast,
+ state=start]
+
+\definecolumnsetarea
+ [second]
+ [x=1,y=20,nx=1,ny=3,
+ background=contrast,
+ state=start]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{50}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-301.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-301.tex
new file mode 100644
index 000000000..4d21f2b02
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-301.tex
@@ -0,0 +1,29 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4]
+
+\starttext
+
+\startcolumnset[example]
+
+ 1: \fakewords{50}{75} \column
+ 2: [] \fakewords{50}{75} \column[yes]
+ 3: [yes] \fakewords{50}{75} \column[page]
+ \column[page] % redundant
+ 4: [page] \fakewords{50}{75} \column[3]
+ 5: [3] \fakewords{50}{75} \column[4]
+ 6: [4] \fakewords{50}{75} \column[first]
+ 7: [first] \fakewords{50}{75} \column[last]
+ 8: [last] \fakewords{50}{75} \page
+ 9: (page) \fakewords{50}{75} \page
+ \page % redundant
+ 10: (page) \fakewords{50}{75} \column[3*5]
+ 11: [3*5] \fakewords{50}{75}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-401.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-401.tex
new file mode 100644
index 000000000..ee91e608c
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-401.tex
@@ -0,0 +1,26 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\setupbackgrounds[text][text][background=contrast]
+
+\definecolor[fakerulecolor][white]
+
+\setupcolumnset[example:2][distance=36pt]
+\setupcolumnset[example:3][distance=72pt]
+\setupcolumnset[example:4][distance=24pt]
+\setupcolumnset[example:5][distance=48pt]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{25}{\fakewords{100}{150}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-402.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-402.tex
new file mode 100644
index 000000000..00db6017c
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-402.tex
@@ -0,0 +1,24 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\setupbackgrounds[text][text][background=contrast]
+
+\setupcolumnset[example] [distance=24pt]
+\setupcolumnset[example:1][distance=96pt]
+
+\definecolor[fakerulecolor][white]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{25}{\fakewords{100}{150}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-403.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-403.tex
new file mode 100644
index 000000000..c9bc2e648
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-403.tex
@@ -0,0 +1,23 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\setupbackgrounds[text][text][background=contrast]
+
+\definecolor[fakerulecolor][white]
+
+\setupcolumnset[example][width=.15\makeupwidth]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{25}{\fakewords{100}{150}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-404.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-404.tex
new file mode 100644
index 000000000..05a25acfe
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-404.tex
@@ -0,0 +1,34 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left]
+
+\setupbackgrounds[text][text][background=contrast]
+
+\setupcolumnset[frame=on,framecolor=color-4,rulethickness=1mm]
+
+\definecolor[fakerulecolor][white]
+
+\setupcolumnset[example:1][width=2cm]
+\setupcolumnset[example:2][width=4cm]
+\setupcolumnset[example:3][width=3cm]
+
+\setupcolumnset[example:4][width=3cm]
+\setupcolumnset[example:5][width=4cm]
+\setupcolumnset[example:6][width=6cm]
+
+\starttext
+
+\startcolumnset[example]
+
+\dorecurse{15}{
+ \dorecurse{3}{\fakewords{10}{15}\par}
+ \column[yes]
+}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-405.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-405.tex
new file mode 100644
index 000000000..fa20ef34c
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-405.tex
@@ -0,0 +1,29 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\setupbackgrounds[text][text][background=contrast]
+
+\setupcolumnset[frame=on,framecolor=color-4,rulethickness=1mm]
+
+\definecolor[fakerulecolor][white]
+
+\setupcolumnset[example:1][width=.3\makeupwidth]
+
+\starttext
+
+\startcolumnset[example]
+
+ \fakewords{150}{150}
+ \column
+ \fakewords{25}{50}
+
+ \dorecurse{25}{\fakewords{50}{75}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-601.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-601.tex
new file mode 100644
index 000000000..b139210f4
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-601.tex
@@ -0,0 +1,29 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left,direction=reverse]
+
+\setupbackgrounds[text][text][background=contrast]
+
+\definecolor[fakerulecolor][color-1]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{50}{
+ \dontleavehmode
+ \snaptogrid\hbox
+ {\scale[height=2.5\lineheight]{\color[white]{#1}}}%
+ \space
+ \fakewords{30}{60}
+ %\simulatewords[n=30,m=60,min=1,max=5,color=color-1,line=yes]\par
+ \par
+ }
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-701.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-701.tex
new file mode 100644
index 000000000..b2c50cfaf
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-701.tex
@@ -0,0 +1,23 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\setupcolumnset
+ [example]
+ [background=contrast]
+
+\definecolor[fakerulecolor][white]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-702.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-702.tex
new file mode 100644
index 000000000..5b9a879c1
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-702.tex
@@ -0,0 +1,27 @@
+content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\setupcolumnset
+ [example]
+ [background=contrast,
+ backgroundoffset=4pt,
+ frame=on,
+ framecolor=white,
+ rulethickness=2pt]
+
+\definecolor[fakerulecolor][white]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-703.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-703.tex
new file mode 100644
index 000000000..549b49f61
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-703.tex
@@ -0,0 +1,34 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=4,page=left]
+
+\definecolumnsetarea
+ [title][left]
+ [x=1,y=1,nx=8,ny=8,
+ background=contrast,state=repeat]
+
+\setupcolumnsetareatext
+ [title][left][\setups{cow}]
+
+\startsetups[cow]
+
+ \externalfigure
+ [cow.pdf]
+ [height=15\lineheight,
+ width=2\dimexpr\makeupwidth+\backspace\relax]
+
+\stopsetups
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{\fakewords{50}{100}\par}
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-704.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-704.tex
new file mode 100644
index 000000000..7fa6cb313
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-704.tex
@@ -0,0 +1,69 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\startuseMPgraphic{mpos:par:columns}
+ path p ; numeric h ;
+ for i=1 upto nofmultipars :
+ p := multipars[i] ;
+ h := bbheight(p) ;
+ if multikind[i] = "single" :
+ fill p topenlarged -.5h
+ withshademethod "linear"
+ withshadedirection shadedup
+ withcolor \MPcolor{color-1} shadedinto white ;
+ fill p bottomenlarged -.5h
+ withshademethod "linear"
+ withshadedirection shadedup
+ withcolor white shadedinto \MPcolor{color-1} ;
+ elseif multikind[i] = "first" :
+ fill p
+ withshademethod "linear"
+ withshadedirection shadedup
+ withcolor \MPcolor{color-2} shadedinto white ;
+ elseif multikind[i] = "middle" :
+ fill p topenlarged -.5h
+ withshademethod "linear"
+ withshadedirection shadedup
+ withcolor \MPcolor{color-2} shadedinto white ;
+ fill p bottomenlarged -.5h
+ withshademethod "linear"
+ withshadedirection shadedup
+ withcolor white shadedinto \MPcolor{color-3} ;
+ elseif multikind[i] = "last" :
+ fill p
+ withshademethod "linear"
+ withshadedirection shadedup
+ withcolor white shadedinto \MPcolor{color-3} ;
+ fi ;
+ endfor ;
+\stopuseMPgraphic
+
+\definecolumnset
+ [example]
+ [n=4,
+ page=left]
+
+\definetextbackground
+ [shade]
+ [location=paragraph,
+ mp=mpos:par:columns,
+ before=\blank,
+ after=\blank]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse {40} {
+ \starttextbackground[shade]
+ \fakewords{10}{200}
+ \stoptextbackground
+ \par
+ }
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-801.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-801.tex
new file mode 100644
index 000000000..1a84f99ab
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-801.tex
@@ -0,0 +1,19 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset [example-1] [n=2]
+\definecolumnset [example-2] [n=3]
+
+\starttext \showgrid
+
+ \startcolumnset [example-1]
+ \dorecurse {1}{\input tufte \par}
+ \stopcolumnset
+ \startcolumnset [example-2]
+ \dorecurse {2}{\input ward \par}
+ \stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-802.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-802.tex
new file mode 100644
index 000000000..a126d0012
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-802.tex
@@ -0,0 +1,22 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset [example-1] [n=2,balance=yes]
+\definecolumnset [example-2] [n=3,balance=yes]
+
+\starttext \showgrid
+
+ \setupcolumnsetlines[example-1][1][1] [8]
+ \setupcolumnsetlines[example-1][1][2][10]
+
+ \startcolumnset [example-1]
+ \dorecurse {1}{\input tufte \par}
+ \stopcolumnset
+ \startcolumnset [example-2]
+ \dorecurse {2}{\input ward \par}
+ \stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-803.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-803.tex
new file mode 100644
index 000000000..58a278bb1
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-803.tex
@@ -0,0 +1,26 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset [example-1] [n=2,balance=yes]
+\definecolumnset [example-2] [n=3,balance=yes]
+
+\starttext \showgrid
+
+ \setupcolumnsetlines[example-1][1][1] [8]
+ \setupcolumnsetlines[example-1][1][2][10]
+
+ \setupcolumnsetlines[example-2][1][1][19]
+ \setupcolumnsetlines[example-2][1][2][18]
+ \setupcolumnsetlines[example-2][1][3][19]
+
+ \startcolumnset [example-1]
+ \dorecurse {1}{\input tufte \par}
+ \stopcolumnset
+ \startcolumnset [example-2]
+ \dorecurse {2}{\input ward \par}
+ \stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-804.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-804.tex
new file mode 100644
index 000000000..c2b7a6b1e
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-804.tex
@@ -0,0 +1,26 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset [example-1] [n=2,balance=yes]
+\definecolumnset [example-2] [n=3,balance=yes]
+
+\starttext \showgrid
+
+ \setupcolumnsetlines[example-1][1][1] [8]
+ \setupcolumnsetlines[example-1][1][2][10]
+
+ \setupcolumnsetlines[example-2][1][1] [0]
+ \setupcolumnsetlines[example-2][1][2][-2]
+ \setupcolumnsetlines[example-2][1][3] [0]
+
+ \startcolumnset [example-1]
+ \dorecurse {1}{\input tufte \par}
+ \stopcolumnset
+ \startcolumnset [example-2]
+ \dorecurse {6}{\input ward \par}
+ \stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-805.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-805.tex
new file mode 100644
index 000000000..fc80e7e9c
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-805.tex
@@ -0,0 +1,26 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset [example-1] [n=2,balance=yes]
+\definecolumnset [example-2] [n=3,balance=yes]
+
+\starttext \showgrid
+
+ \setupcolumnsetlines[example-1][1][1] [8]
+ \setupcolumnsetlines[example-1][1][2][10]
+
+ \setupcolumnsetstart[example-2][1][1][19]
+ \setupcolumnsetstart[example-2][1][2][17]
+ \setupcolumnsetstart[example-2][1][3][19]
+
+ \startcolumnset [example-1]
+ \dorecurse {1}{\input tufte \par}
+ \stopcolumnset
+ \startcolumnset [example-2]
+ \dorecurse {2}{\input ward \par}
+ \stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-806.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-806.tex
new file mode 100644
index 000000000..0322a336f
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-806.tex
@@ -0,0 +1,26 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset [example-1] [n=2,balance=yes]
+\definecolumnset [example-2] [n=3,balance=yes]
+
+\starttext \showgrid
+
+ \setupcolumnsetlines[example-1][1][1] [8]
+ \setupcolumnsetlines[example-1][1][2][10]
+
+ \setupcolumnsetstart[example-2][1][1][29]
+ \setupcolumnsetstart[example-2][1][2][29]
+ \setupcolumnsetstart[example-2][1][3][29]
+
+ \startcolumnset [example-1]
+ \dorecurse {1}{\input tufte \par}
+ \stopcolumnset
+ \startcolumnset [example-2]
+ \dorecurse {2}{\input ward \par}
+ \stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-901.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-901.tex
new file mode 100644
index 000000000..300458bf5
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-901.tex
@@ -0,0 +1,38 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=2,page=left,distance=1cm]
+
+\setupcolumnset
+ [example]
+ [background=contrast]
+
+\definecolor[fakerulecolor][white] \faketriggertrue
+
+\setuphead
+ [section]
+ [style=\bfd]
+
+\setuplinenumbering
+ [style=bold,
+ distance=0pt,
+ align=inner]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{
+ \startsection[title=foo #1]
+ \startlinenumbering
+ \fakewords{50}{100}\par
+ \stoplinenumbering
+ \stopsection
+ }
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-902.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-902.tex
new file mode 100644
index 000000000..fda2969af
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-902.tex
@@ -0,0 +1,38 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left,distance=1cm]
+
+\setupcolumnset
+ [example]
+ [background=contrast]
+
+\definecolor[fakerulecolor][white] \faketriggertrue
+
+\setuphead
+ [section]
+ [style=\bfd]
+
+\setuplinenumbering
+ [style=bold,
+ distance=0pt,
+ align=inner]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{
+ \startsection[title=foo #1]
+ \startlinenumbering
+ \fakewords{50}{100}\par
+ \stoplinenumbering
+ \stopsection
+ }
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets-903.tex b/doc/context/sources/general/columnsets/columnsets/columnsets-903.tex
new file mode 100644
index 000000000..68cd31ae2
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets-903.tex
@@ -0,0 +1,41 @@
+% content=tex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\environment columnsets-000
+
+\definecolumnset[example][n=3,page=left,distance=1cm]
+
+\setupcolumnset
+ [example]
+ [background=contrast]
+
+\definecolor[fakerulecolor][white] \faketriggertrue
+
+\setupblank
+ [line]
+
+\setuphead
+ [section]
+ [style=\bfd]
+
+\setuplinenumbering
+ [style=bold,
+ distance=0pt,
+ align=inner]
+
+\starttext
+
+\startcolumnset[example]
+
+ \dorecurse{30}{
+ \startsection[title=foo #1]
+ \startlinenumbering
+ \fakewords{50}{100}\par
+ \stoplinenumbering
+ \stopsection
+ }
+
+\stopcolumnset
+
+\stoptext
diff --git a/doc/context/sources/general/columnsets/columnsets/columnsets.tex b/doc/context/sources/general/columnsets/columnsets/columnsets.tex
new file mode 100644
index 000000000..81d6c5880
--- /dev/null
+++ b/doc/context/sources/general/columnsets/columnsets/columnsets.tex
@@ -0,0 +1,871 @@
+% engine=luatex
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\dontcomplain
+
+\definepagebreak[mine][yes]
+
+% A complete otf optima pack is too expensive for this (I only have the
+% type one set).
+%
+% \usetypescriptfile
+% [type-ghz]
+%
+% \usetypescript
+% [sans]
+% [optima-nova]
+%
+% \setupbodyfont
+% [optima-nova,11pt]
+%
+% \definefont[QuiteLarge][SansBold sa 3]
+% \definefont[NotSoLarge][SansBold sa 1.5]
+%
+% So we could use:
+%
+% \setupbodyfont
+% [pagella,11pt]
+%
+% \definefont[QuiteLarge][Bold sa 2.50]
+% \definefont[NotSoLarge][Bold sa 1.25]
+%
+% But this one has a matching sans:
+
+\setupbodyfont
+ [dejavu,11pt]
+
+\definefont[QuiteLarge][SansBold sa 2.50]
+\definefont[NotSoLarge][SansBold sa 1.25]
+
+\setuplayout
+ [backspace=.1\paperwidth,
+ topspace=.025\paperheight,
+ header=0.025\paperheight,
+ footer=0.025\paperheight,
+ headerdistance=0.025\paperheight,
+ footerdistance=0.025\paperheight,
+ width=middle,
+ height=middle]
+
+\setuppagenumbering
+ [alternative=doublesided,
+ location=]
+
+\setupwhitespace
+ [line]
+
+\setupblank
+ [line]
+
+\setuptyping
+ [blank=halfline]
+
+\startsetups [pagenumber]
+ \hbox to .2\paperwidth {
+ \hss
+ Page \pagenumber
+ \hss
+ }
+\stopsetups
+
+\setupfooter [before=\vfill,after=\vfill,style=\bf,color=color-4]
+\setupheader [before=\vfill,after=\vfill,style=\bf,color=color-4]
+
+\setupfootertexts [] [\setups{pagenumber}]
+\setupheadertexts [] [\setups{chapterhead}]
+
+\startsetups [chapterhead]
+ \hbox to .2\paperwidth {
+ \hss
+ \getmarking[chapter]
+ \hss
+ }
+\stopsetups
+
+\setuphead
+ [chapter]
+ [header=empty]
+
+\definecolor[color-1][.5(red,green)]
+\definecolor[color-2][.5(green,blue)]
+\definecolor[color-3][.5(blue,red)]
+\definecolor[color-4][.5(white,black)]
+\definecolor[color-5][.5(white,color-4)]
+\definecolor[color-6][.2(white,color-4)]
+
+\startuseMPgraphic{page}
+StartPage ;
+ path p ;
+ numeric n; n := PageNumber ;
+ numeric w; w := bbwidth(Page) ;
+ numeric h; h := bbheight(Page) ;
+ def DrawBit (expr bit, dx, dy) =
+ path p ; p := unitsquare xyscaled(w/5,h/40) shifted (dx*w/10,dy*(h-h/40)) ;
+ if n div bit > 0 :
+ n := n - (n div bit)*bit ;
+ fill p withcolor \MPcolor{color-1} ;
+ else :
+ fill p withcolor \MPcolor{color-2} ;
+ fi ;
+ enddef ;
+ DrawBit(32,7,1) ;
+ DrawBit(16,4,1) ;
+ DrawBit( 8,1,1) ;
+ DrawBit( 4,7,0) ;
+ DrawBit( 2,4,0) ;
+ DrawBit( 1,1,0) ;
+StopPage ;
+\stopuseMPgraphic
+
+\startuniqueMPgraphic{frame}
+ fill OverlayBox withcolor \MPcolor{color-5} ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{contrast}
+ fill OverlayBox withcolor \MPcolor{color-4} ;
+\stopuniqueMPgraphic
+
+\defineoverlay[page] [\useMPgraphic{page}]
+\defineoverlay[frame] [\useMPgraphic{frame}]
+\defineoverlay[contrast][\useMPgraphic{contrast}]
+
+\setupexternalfigures
+ [background=frame]
+
+\definecombination
+ [sixpages]
+ [%inbetween=\blank,
+ style=mono,
+ distance=.5\bodyfontsize,
+ width=\textwidth]
+
+\definecombination
+ [fourpages]
+ [%inbetween=\blank,
+ style=mono,
+ distance=.5\bodyfontsize,
+ width=\textwidth]
+
+\definecombination
+ [twopages]
+ [style=mono]
+
+\definemeasure[twopages] [\dimexpr\dimexpr\textwidth-3 \bodyfontsize\relax/4\relax]
+\definemeasure[fourpages] [\dimexpr\dimexpr\textwidth-3 \bodyfontsize\relax/4\relax]
+\definemeasure[eightpages][\dimexpr\dimexpr\textwidth-3 \bodyfontsize\relax/4\relax]
+\definemeasure[sixpages] [\dimexpr\dimexpr\textwidth-2.5\bodyfontsize\relax/6\relax]
+
+\starttexdefinition unexpanded OnePage #1
+ \startlinecorrection[blank]
+ \startcombination[twopages][1*1]
+ {\typesetfile[#1.tex][page=1,lines=15]} {1}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded OneSpread #1
+ \startlinecorrection[blank]
+ \startcombination[twopages][1*1]
+ {\typesetfile[#1.tex][page=2,lines=15]} {2}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded TwoPages #1
+ \startlinecorrection[blank]
+ \startcombination[twopages][2*1]
+ {\typesetfile[#1.tex][page=1,width=\measure{twopages}]} {1}
+ {\typesetfile[#1.tex][page=2,width=\measure{twopages}]} {2}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded TwoSpread #1
+ \startlinecorrection[blank]
+ \startcombination[twopages][2*1]
+ {\typesetfile[#1.tex][page=2,width=\measure{twopages}]} {2}
+ {\typesetfile[#1.tex][page=3,width=\measure{twopages}]} {3}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded FourPages #1
+ \startlinecorrection[blank]
+ \startcombination[fourpages][4*1]
+ {\typesetfile[#1.tex][page=1,width=\measure{fourpages}]} {1}
+ {\typesetfile[#1.tex][page=2,width=\measure{fourpages}]} {2}
+ {\typesetfile[#1.tex][page=3,width=\measure{fourpages}]} {3}
+ {\typesetfile[#1.tex][page=4,width=\measure{fourpages}]} {4}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded FourSpread #1
+ \startlinecorrection[blank]
+ \startcombination[fourpages][4*1]
+ {\typesetfile[#1.tex][page=2,width=\measure{fourpages}]} {2}
+ {\typesetfile[#1.tex][page=3,width=\measure{fourpages}]} {3}
+ {\typesetfile[#1.tex][page=4,width=\measure{fourpages}]} {4}
+ {\typesetfile[#1.tex][page=5,width=\measure{fourpages}]} {5}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded SixPages #1
+ \startlinecorrection[blank]
+ \startcombination[sixpages][6*1]
+ {\typesetfile[#1.tex][page=1,width=\measure{sixpages}]} {1}
+ {\typesetfile[#1.tex][page=2,width=\measure{sixpages}]} {2}
+ {\typesetfile[#1.tex][page=3,width=\measure{sixpages}]} {3}
+ {\typesetfile[#1.tex][page=4,width=\measure{sixpages}]} {4}
+ {\typesetfile[#1.tex][page=5,width=\measure{sixpages}]} {5}
+ {\typesetfile[#1.tex][page=6,width=\measure{sixpages}]} {6}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded SixSpread #1
+ \startlinecorrection[blank]
+ \startcombination[sixpages][6*1]
+ {\typesetfile[#1.tex][page=2,width=\measure{sixpages}]} {2}
+ {\typesetfile[#1.tex][page=3,width=\measure{sixpages}]} {3}
+ {\typesetfile[#1.tex][page=4,width=\measure{sixpages}]} {4}
+ {\typesetfile[#1.tex][page=5,width=\measure{sixpages}]} {5}
+ {\typesetfile[#1.tex][page=6,width=\measure{sixpages}]} {6}
+ {\typesetfile[#1.tex][page=7,width=\measure{sixpages}]} {7}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded EightPages #1
+ \startlinecorrection[blank]
+ \startcombination[fourpages][4*2]
+ {\typesetfile[#1.tex][page=1,width=\measure{eightpages}]} {#1 / 1}
+ {\typesetfile[#1.tex][page=2,width=\measure{eightpages}]} {#1 / 2}
+ {\typesetfile[#1.tex][page=3,width=\measure{eightpages}]} {#1 / 3}
+ {\typesetfile[#1.tex][page=4,width=\measure{eightpages}]} {#1 / 4}
+ {\typesetfile[#1.tex][page=5,width=\measure{eightpages}]} {#1 / 5}
+ {\typesetfile[#1.tex][page=6,width=\measure{eightpages}]} {#1 / 6}
+ {\typesetfile[#1.tex][page=7,width=\measure{eightpages}]} {#1 / 7}
+ {\typesetfile[#1.tex][page=8,width=\measure{eightpages}]} {#1 / 8}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\starttexdefinition unexpanded EightSpread #1
+ \startlinecorrection[blank]
+ \startcombination[fourpages][4*2]
+ {\typesetfile[#1.tex][page=2,width=\measure{eightpages}]} {#1 / 2}
+ {\typesetfile[#1.tex][page=3,width=\measure{eightpages}]} {#1 / 3}
+ {\typesetfile[#1.tex][page=4,width=\measure{eightpages}]} {#1 / 4}
+ {\typesetfile[#1.tex][page=5,width=\measure{eightpages}]} {#1 / 5}
+ {\typesetfile[#1.tex][page=6,width=\measure{eightpages}]} {#1 / 6}
+ {\typesetfile[#1.tex][page=7,width=\measure{eightpages}]} {#1 / 7}
+ {\typesetfile[#1.tex][page=8,width=\measure{eightpages}]} {#1 / 8}
+ {\typesetfile[#1.tex][page=9,width=\measure{eightpages}]} {#1 / 9}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
+\setuphead
+ [chapter]
+ [style=\QuiteLarge,
+ color=color-3,
+ number=no]
+
+\setuplist
+ [chapter]
+ [command=\MyListCommand,
+ alternative=command]
+
+\starttexdefinition unexpanded MyListCommand #1#2#3
+ \snaptogrid
+ [line,-line]\vbox {
+ \tfb
+ \setstrut
+ \strut#2
+ \quad#3
+ }
+\stoptexdefinition
+
+\setupmargindata
+ [style=\tttf,
+ color=color-3]
+
+\starttexdefinition unexpanded ShowFile #1
+ \margintext
+ {\cldcontext{string.match("#1","\letterpercent d+")}}
+ \typefile
+ [range={environment}]
+ {#1}
+\stoptexdefinition
+
+% \typefile[range=4] {...}
+% \typefile[range={=}]{...} % start after comment lines
+
+\starttexdefinition unexpanded ShowEnvironmentFile #1
+ \margintext
+ {\cldcontext{string.match("#1","\letterpercent d+")}}
+ \typefile
+ [range={=startenvironment}]
+ {#1}
+\stoptexdefinition
+
+\startdocument
+
+\startMPpage
+StartPage ;
+ path p ; numeric w, h, d ; picture q ;
+ if true :
+ q := image(draw textext.urt("\ssbf COLUMNS") withcolor \MPcolor{color-6}) ;
+ else :
+ q := image(draw textext.urt("\ssbf COLUMNSETS") withcolor \MPcolor{color-6}) ;
+ fi ;
+ w := bbwidth(Page) ;
+ h := bbheight(Page) ;
+ d := h/100 ;
+ fill Page withcolor \MPcolor{color-1} ;
+ p := Page xysized (w,d) ;
+ for i := 5d step 2d until h-5d :
+ fill p shifted (0,i) withcolor \MPcolor{color-2} ;
+ endfor
+ p := Page xysized(w/10,h) ;
+ for i = 0, .3, .6, .9 :
+ fill p shifted (i*w,0) withcolor \MPcolor{color-1} withtransparency(1,.75) ;
+ endfor ;
+ def do_it(expr sz, sh) =
+ p := Page xysized sz ;
+ fill p shifted sh withcolor \MPcolor{color-3} withtransparency(1,.5) ;
+ draw q xysized (bbwidth(p),bbheight(p)) shifted sh ;
+ enddef ;
+ if true :
+ do_it ((2w/10,17d),(.1w,20d)) ;
+ do_it ((2w/10,15d),(.1w,56d)) ;
+ do_it ((2w/10,21d),(.4w,66d)) ;
+ do_it ((2w/10,13d),(.7w,38d)) ;
+ do_it ((5w/10,13d),(.4w,13d)) ;
+ draw textext.urt("\ssbf Hans Hagen")
+ xysized (5w/10,5d)
+ shifted (.4w,6d)
+ withcolor \MPcolor{color-5} ;
+ else :
+ do_it ((2w/10,17d),(.1w,15d)) ;
+ do_it ((2w/10,15d),(.1w,51d)) ;
+ do_it ((2w/10,21d),(.4w,61d)) ;
+ do_it ((2w/10,13d),(.7w,31d)) ;
+ do_it ((5w/10,13d),(.4w, 7d)) ;
+ fi ;
+StopPage ;
+\stopMPpage
+
+\page[empty] \setuppagenumber[number=1]
+
+\setupbackgrounds
+ [page]
+ [background=page]
+
+\starttitle[title=Contents]
+
+ \placelist[chapter]
+
+\stoptitle
+
+\startchapter[title=Introduction]
+
+This manual introduces {\em column sets}, one of the output routines of \CONTEXT.
+Although column sets are mainly meant for typesetting journals in a
+semi||automated way, you can also use them for books. We assume that the user is
+familiar with \CONTEXT\ and only discuss the commands that are related to column
+sets.
+
+This mechanism performs okay but it needs to be used with care: an occasional
+manual intervention is needed to get optimal results. After all, we're operating
+in the area where normally click and point desktop publishing is used.
+
+\startlines
+Hans Hagen
+PRAGMA ADE
+Hasselt, 2003\endash2016
+\stoplines
+
+\stopchapter
+
+\startchapter[title=Basics]
+
+As soon as enough content is collected to build a page, \TEX\ will invoke the
+output routine. This is not a fixed piece of code, but a collection of macro
+calls. The default output routine is a meant for typesetting a single column, as
+in this document. A multi||column output routine is available as well. This
+routine mixes well with the single column one, and is activated by:
+
+\starttyping
+\startcolumns
+some text ...
+\stopcolumns
+\stoptyping
+
+In \MKIV\ a new mixed column mechanism has been introduced that will be
+developped further and eventually replace the old multi column handler. In \MKII\
+there is also a columnset mechanism that can be used to construct complex multi
+column pages. In \MKIV\ this gets replaced by grid columns. All these multi
+column mechanisms have in common that the output routine is more complex because
+now a page is in fact a collection of pages wrapped onto one. Each column is
+(from \TEX's perspective) similar to a one narrow column page. Here we focus on
+columnsets (page grids).
+
+There are some limitations to what you can do with this kind of multi columns,
+which is why we have a third routine at out disposal: {\em column sets}. This
+routine can be used for rather complex layouts with graphics all over the place,
+and text spanning columns or even spreads. There are of course some shortcomings,
+which we will discuss later.
+
+In the examples that follow we use the following style to set up the layout. The
+number in the margin serves a reference to the file where this snippet of \TEX\
+is stored.
+
+\ShowEnvironmentFile{columnsets-000}
+
+\page[mine]
+
+Before we will demonstrate more complex layouts, we will introduce a few
+features. In the next series of examples we use fake text. You can enlarge the
+pages in your viewer if you want to see more detail.
+
+\FourSpread{columnsets-001}
+
+These pages were typeset with the following code:
+
+\ShowFile{columnsets-001}
+
+We will showmost examples on a spread, so we don't show a first page. On a
+spread like above we number columns from~1 to~4, which in practice means that in
+this case columns starting on right page start with column~3!
+
+\SixPages{columnsets-001}
+
+\page[mine]
+
+The number of columns is not fixed to two. You can even have a different number
+of columns on left and right pages.
+
+\FourSpread{columnsets-002}
+
+This time the input is:
+
+\ShowFile{columnsets-002}
+
+Again, we started on a right page but showed the spreads. You can see it from the
+positioning of the header texts.
+
+\SixPages{columnsets-002}
+
+\page[mine]
+
+In order to get the balancing you want, you can manually influence the height of
+a column.
+
+\FourSpread{columnsets-003}
+
+When you set the number of column lines to a positive value, that will be the
+number of lines. A negative value will be subtracted from the maximum number of
+lines.
+
+\ShowFile{columnsets-003}
+
+\page[mine]
+
+In articles you may want to let the introduction span multiple columns. A column
+span is defined independent of a column set and shows up as follows:
+
+\FourSpread{columnsets-004}
+
+Here we've given the span a background so that it stands out.
+
+\ShowFile{columnsets-004}
+
+\page[mine]
+
+A column span can be positioned like any graphic. Later we will discuss the
+placement options in more detail, for the moment all you need to know is that
+\type {btlr} tells \CONTEXT\ to place the graphic in the left bottom of the the
+text area.
+
+\FourSpread{columnsets-005}
+
+Here we pass the \type {default} placement as parameter to the span, but you can
+also set it at definition time. We use a brute force simple column splitter to
+fake columns inside the span.
+
+\ShowFile{columnsets-005}
+
+\page[mine]
+
+You are not limited to one column span. In this sense a span is like a graphic:
+as long as there is room, it will be placed where you want it to be placed. The
+main difference between a span and a graphic is that a span expects text and
+tries to align the baselines with the rest of the text. In many ways a column
+span behaves like a framed text.
+
+\FourSpread{columnsets-006}
+
+This time we flushed one of the spans from bottom to top, starting at the right
+edge: \type {btrl}.
+
+\ShowFile{columnsets-006}
+
+\page[mine]
+
+Column spans are treated like graphics, which means that they will float if
+needed. In the process, the width is limited to the available space, which in
+some cases may lead to a smaller span than you may expect. Think of a column
+span, calculated (and prepared) in the last column and ending up on the next page
+in the first column, where a broader span would have been possible.
+
+\FourSpread{columnsets-007}
+
+\ShowFile{columnsets-007}
+
+\stopchapter
+
+\startchapter[title=Graphics]
+
+Most documents have graphics, and therefore column sets can contain them. The
+main thing that you have to keep in mind when placing graphics, is that column
+sets are based on grids. Therefore spacing around graphics is also grid based.
+
+\FourSpread{columnsets-101}
+
+\ShowFile{columnsets-101}
+
+\page[mine]
+
+You can tell \CONTEXT\ where it should place the graphic, but this will only be
+honored when there is still place.
+
+\EightSpread{columnsets-102}
+
+The prefered location is passed as a four character directive:
+
+\ShowFile{columnsets-102}
+
+\page[mine]
+
+The following directives are available:
+
+\starttabulate[|lT|p|]
+\NC btlr \NC flush from bottom to top and left to right \NC \NR
+\NC btrl \NC flush from bottom to top and right to left \NC \NR
+\NC tblr \NC flush from top to bottom and left to right \NC \NR
+\NC tbrl \NC flush from top to bottom and right to left \NC \NR
+\NC lrbt \NC flush from left to right and bottom to top \NC \NR
+\NC lrtb \NC flush from left to right and top to bottom \NC \NR
+\NC rlbt \NC flush from right to left and bottom to top \NC \NR
+\NC rltb \NC flush from right to left and top to bottom \NC \NR
+\NC here \NC try to place the graphic here \NC \NR
+\NC fixd \NC force the graphic here and don't float \NC \NR
+\NC fxtb:c*r \NC place the graphic at (c,r) or lower if needed \NC \NR
+\NC fxbt:c*r \NC place the graphic at (c,r) or higher if needed \NC \NR
+\NC tops \NC place the graphic at the top of the page \NC \NR
+\NC bots \NC place the graphic at the bottom of the page \NC \NR
+\NC page \NC place the graphic at a separate page \NC \NR
+\stoptabulate
+
+In the next example we show the directional locations:
+
+\OneSpread{columnsets-103}
+
+\ShowFile{columnsets-103}
+
+\stopchapter
+
+\startchapter[title=Areas]
+
+So far we have seen texts and graphics that span multiple columns using span
+commands and floats placement commands. We have also seen that you can define a
+different number of columns for left and right pages. Now that we have arrives at
+column areas you will see how we can span information over not only a page but
+also over pages in a spread.
+
+\FourSpread{columnsets-201}
+
+Being a framed text, by default an area is aligned at the baseline. You can lower
+an area by setting the \type {location} to \type {depth}.
+
+\ShowFile{columnsets-201}
+
+\page[mine]
+
+You can position areas on the left, right or next page or on both pages. When you
+set \type {state} to \type {repeat}, an area is repeated, otherwise it is only
+placed once.
+
+\FourSpread{columnsets-202}
+
+Here we just repeat the areas. Normally this only make sense when the content is
+worth repeating.
+
+\ShowFile{columnsets-202}
+
+\page[mine]
+
+Areas can span a spread, as is demonstrated in the next example.
+
+\FourSpread{columnsets-203}
+
+\ShowFile{columnsets-203}
+
+\page[mine]
+
+An application of a spread area is a title. In the next example we show two
+spread pages.
+
+\FourSpread{columnsets-204}
+
+Watch how we explicitly go to a left page.
+
+\ShowFile{columnsets-204}
+
+\page[mine]
+
+The \type {\GapText} macro is an experimental fun macro and is used to make sure
+that we don't end up with a clipped character.
+
+\startlinecorrection[blank]
+\startcombination
+ {\scale[width=.4\textwidth]{\clip
+ [nx=2,ny=6,x=2,y=2]
+ {\typesetfile[columnsets-204.tex][page=2]}}}
+ {left page}
+ {\scale[width=.4\textwidth]{\clip
+ [nx=2,ny=6,x=1,y=2]
+ {\typesetfile[columnsets-204.tex][page=3]}}}
+ {right page}
+\stopcombination
+\stoplinecorrection
+
+This is a typical example of the kind of optimizations that are needed when you
+make documents of styles with text that spans a spread. In the next clip we
+visualize the gap.
+
+\startlinecorrection[blank]
+\startcombination
+ {\scale[width=.4\textwidth]{\clip
+ [nx=2,ny=6,x=2,y=2]
+ {\typesetfile[columnsets-205.tex][page=2]}}}
+ {left page}
+ {\scale[width=.4\textwidth]{\clip
+ [nx=2,ny=6,x=1,y=2]
+ {\typesetfile[columnsets-205.tex][page=3]}}}
+ {right page}
+\stopcombination
+\stoplinecorrection
+
+At some moment you may want to set up an area in advance as we have done in the
+following example.
+
+\FourSpread{columnsets-206}
+
+The \type {page} key is used to specify the page in the column set that the area
+should go into. Column set pages start numbering at~1. The \type {fixed} stands
+for left or right, whatever comes first.
+
+\ShowFile{columnsets-206}
+
+\stopchapter
+
+\startchapter[title=Columns]
+
+You can use \type {\page} to go to a new page in a column set. Likewise you can
+use \type {\column} to force a column break.
+
+\FourPages{columnsets-301}
+
+This example demonstrates that you can supply \type {\column} with explicit
+directives.
+
+\ShowFile{columnsets-301}
+
+You can use \type {\column[page]} as an alternative for \type {\page}.
+
+\stopchapter
+
+\startchapter[title=Details]
+
+This chapter will cover a couple of cosmetic details of column sets. {\em Some
+features need to be improved, especially in combination with areas, graphics and
+alike. We will also provide side floats etc.}
+
+\FourSpread{columnsets-401}
+
+You can set the distance between columns for each pair of columns. {\em Todo:
+left and right page distances and margins.}
+
+\ShowFile{columnsets-401}
+
+\page[mine]
+
+When you can the distance of the first column as well. This creates a margin.
+
+\FourSpread{columnsets-402}
+
+This time we used equal distances:
+
+\ShowFile{columnsets-402}
+
+\page[mine]
+
+The width of columns is normally calculated automatically, but you can also set
+the width explicitly:
+
+\FourSpread{columnsets-403}
+
+In code:
+
+\ShowFile{columnsets-403}
+
+\page[mine]
+
+For special effects, you can set the width per column. In that case you need to
+be aware of the fact that \TEX\ works its way through the document per paragraph.
+Changing the width halfway a paragraph is possible but will affect the whole
+paragraph. Therefore, this feature works best when you also goto the next column
+explicitly.
+
+\FourSpread{columnsets-404}
+
+In code:
+
+\ShowFile{columnsets-404}
+
+\page[mine]
+
+If you really want to change the width in the middle of a paragraph, you can do a
+trial run and include a breakpoint at the palce where you want it to occur:
+
+\FourSpread{columnsets-405}
+
+In the second spread you see how the narrow hsize carries on in the wider
+column. A \type {\column} command will synchronize the hsize.
+
+\ShowFile{columnsets-405}
+
+% \page[mine]
+
+\stopchapter
+
+\startchapter[title=Directions]
+
+\FourSpread{columnsets-601}
+
+The direction of flushing columns is determined by the \type {direction}
+parameters as demonstrated below.
+
+\ShowFile{columnsets-601}
+
+% \page[mine]
+
+\stopchapter
+
+\startchapter[title=Backgrounds]
+
+As with many \CONTEXT\ components, column sets can have backgrounds.
+
+\FourSpread{columnsets-701}
+
+Watch how we use the \type {each} keyword to tell \CONTEXT\ that we want to apply
+the background to each column of the set.
+
+\ShowFile{columnsets-701}
+
+\page[mine]
+
+Normally, if you apply backgrounds this way, you will also set the background
+offset. In a similar fashion you can apply backgrounds to areas and spans. Such
+backgrounds can be a color, or any overlay or layer you want.
+
+\FourSpread{columnsets-702}
+
+Here we've set the background offset as well as the frame.
+
+\ShowFile{columnsets-702}
+
+\page[mine]
+
+When dealing with areas, you need to be aware of the fact that they are clipped,
+the content as well as the background.
+
+\FourSpread{columnsets-703}
+
+De default clip offset is two times the lineheight, except in the binding, where
+it is set to zero points. You can set the clip offset with the \type {clipoffset}
+parameter.
+
+\ShowFile{columnsets-703}
+
+\page[mine]
+
+The text background mechanism is rather well adapted to column sets. The
+following example is a variant on an example shown in the manual titled
+{details}.
+
+\EightSpread{columnsets-704}
+
+Watch how we adapt the background to the fact and extent that the text spans one
+or more columns.
+
+\ShowFile{columnsets-704}
+
+Backgrounds that follow the paragraph shape also work ok in column sets.
+
+{\em todo: an example of a bleeding graphic with column feed back (from
+techniek)}
+
+% \page[mine]
+
+\stopchapter
+
+\startchapter[title=Numbering lines]
+
+\FourSpread{columnsets-901}
+
+This example shows how numbering lines in columns works out. In a two column
+layout the numbers end up in the outer margins by default. If you want you can
+set the \type {location} to for instance \type {left} or \type {right}.
+
+\ShowFile{columnsets-901}
+
+\page[mine]
+
+\FourSpread{columnsets-902}
+
+In a three column setup the numbers end up in the left margins.Make sure you make
+the distance large enough.
+
+\ShowFile{columnsets-902}
+
+% \page[mine]
+%
+% \FourSpread{columnsets-903}
+%
+% This example shows again lune numbers but here we made sure that there is no
+% stretch in the whitespace.
+%
+% \ShowFile{columnsets-903}
+
+\stopchapter
+
+% \startchapter[title=Spanning and More]
+%
+% {\em todo: explanation} \page
+%
+% \TwoPages{columnsets-801} \ShowFile{columnsets-801} \page[mine]
+% \TwoPages{columnsets-802} \ShowFile{columnsets-802} \page[mine]
+% \TwoPages{columnsets-803} \ShowFile{columnsets-803} \page[mine]
+% \TwoPages{columnsets-804} \ShowFile{columnsets-804} \page[mine]
+% \TwoPages{columnsets-805} \ShowFile{columnsets-805} \page[mine]
+% \TwoPages{columnsets-806} \ShowFile{columnsets-806} \page[mine]
+%
+% \stopchapter
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/luatex/luatex-libraries.tex b/doc/context/sources/general/manuals/luatex/luatex-libraries.tex
index d877c9c47..62a64ffd6 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-libraries.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-libraries.tex
@@ -5541,15 +5541,17 @@ The virtual table \type {tex.lists} contains the set of internal registers that
keep track of building page lists.
\starttabulate[|lT|p|]
-\NC \bf field \NC \bf description \NC \NR
-\NC page_ins_head \NC circular list of pending insertions \NC \NR
-\NC contrib_head \NC the recent contributions \NC \NR
-\NC page_head \NC the current page content \NC \NR
-%NC temp_head \NC \NC \NR
-\NC hold_head \NC used for held-over items for next page \NC \NR
-\NC adjust_head \NC head of the current \type {\vadjust} list \NC \NR
-\NC pre_adjust_head \NC head of the current \type {\vadjust pre} list \NC \NR
-%NC align_head \NC \NC \NR
+\NC \bf field \NC \bf description \NC \NR
+\NC page_ins_head \NC circular list of pending insertions \NC \NR
+\NC contrib_head \NC the recent contributions \NC \NR
+\NC page_head \NC the current page content \NC \NR
+%NC temp_head \NC \NC \NR
+\NC hold_head \NC used for held-over items for next page \NC \NR
+\NC adjust_head \NC head of the current \type {\vadjust} list \NC \NR
+\NC pre_adjust_head \NC head of the current \type {\vadjust pre} list \NC \NR
+%NC align_head \NC \NC \NR
+\NC page_discards_head \NC head of the discarded items of a page break \NC \NR
+\NC split_discards_head \NC head of the discarded items in a vsplit \NC \NR
\stoptabulate
\subsection{Semantic nest levels}
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 83f314934..541b6a783 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii
index 50ad1776c..20cad141b 100644
--- a/tex/context/base/mkii/mult-de.mkii
+++ b/tex/context/base/mkii/mult-de.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{foregroundcolor}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{formatieren}
+\setinterfaceconstant{fractions}{fractions}
\setinterfaceconstant{frame}{rahmen}
\setinterfaceconstant{framecolor}{rahmenfarbe}
\setinterfaceconstant{framecorner}{rahmenwinkel}
diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii
index 4463d7ca9..325d5890b 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{foregroundcolor}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{format}
+\setinterfaceconstant{fractions}{fractions}
\setinterfaceconstant{frame}{frame}
\setinterfaceconstant{framecolor}{framecolor}
\setinterfaceconstant{framecorner}{framecorner}
diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii
index b68dc4baf..efd5f442b 100644
--- a/tex/context/base/mkii/mult-fr.mkii
+++ b/tex/context/base/mkii/mult-fr.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{couleurpremierplan}
\setinterfaceconstant{foregroundstyle}{stylepremierplan}
\setinterfaceconstant{format}{formatter}
+\setinterfaceconstant{fractions}{fractions}
\setinterfaceconstant{frame}{cadre}
\setinterfaceconstant{framecolor}{couleurcadre}
\setinterfaceconstant{framecorner}{coincadre}
diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii
index 42e27d824..5b2ecaa13 100644
--- a/tex/context/base/mkii/mult-it.mkii
+++ b/tex/context/base/mkii/mult-it.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{coloreprimopiano}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{format}
+\setinterfaceconstant{fractions}{fractions}
\setinterfaceconstant{frame}{cornice}
\setinterfaceconstant{framecolor}{colorecornice}
\setinterfaceconstant{framecorner}{angolocornice}
diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii
index 344433d16..dfd241c38 100644
--- a/tex/context/base/mkii/mult-nl.mkii
+++ b/tex/context/base/mkii/mult-nl.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{voorgrondkleur}
\setinterfaceconstant{foregroundstyle}{voorgrondletter}
\setinterfaceconstant{format}{formatteer}
+\setinterfaceconstant{fractions}{breuken}
\setinterfaceconstant{frame}{kader}
\setinterfaceconstant{framecolor}{kaderkleur}
\setinterfaceconstant{framecorner}{kaderhoek}
diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii
index 6548de555..4275e3874 100644
--- a/tex/context/base/mkii/mult-pe.mkii
+++ b/tex/context/base/mkii/mult-pe.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{رنگ‌پیش‌زمینه}
\setinterfaceconstant{foregroundstyle}{سبک‌پیش‌زمینه}
\setinterfaceconstant{format}{شمایل}
+\setinterfaceconstant{fractions}{fractions}
\setinterfaceconstant{frame}{قالب}
\setinterfaceconstant{framecolor}{رنگ‌قالب}
\setinterfaceconstant{framecorner}{گوشه‌قالب}
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index 0ad8eb569..9926be0ce 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -803,6 +803,7 @@
\setinterfaceconstant{foregroundcolor}{foregroundcolor}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{format}
+\setinterfaceconstant{fractions}{fractions}
\setinterfaceconstant{frame}{frame}
\setinterfaceconstant{framecolor}{culoareframe}
\setinterfaceconstant{framecorner}{coltframe}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 49bc48b60..ea60d4a45 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2016.02.26 16:09}
+\newcontextversion{2016.03.01 14:03}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 6533fb6ee..44d760fb3 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2016.02.26 16:09}
+\edef\contextversion{2016.03.01 14:03}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/m-newcolumnsets.mkiv b/tex/context/base/mkiv/m-newcolumnsets.mkiv
new file mode 100644
index 000000000..e0fe60f3f
--- /dev/null
+++ b/tex/context/base/mkiv/m-newcolumnsets.mkiv
@@ -0,0 +1,38 @@
+%D \module
+%D [ file=m-newcolumnsets,
+%D version=2016.02.29,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=New Columnsets,
+%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 module will eventually be replaced by \type {m-oldcolumnsets}.
+
+\ifdefined \definepagegrid
+ \expandafter \endinput
+\else
+ \loadmarkfile{page-cst}
+\fi
+
+% \let\definecolumnset \definepagegrid
+% \let\setupcolumnset \setuppagegrid
+% \let\setupcolumnsetlines \setuppagegridlines
+% \let\setupcolumnsetstart \setuppagegridstart
+% \let\startcolumnset \startpagegrid
+% \let\stopcolumnset \stoppagegrid
+% \let\definecolumnsetspan \definepagegridspan
+% \let\setupcolumnsetspan \setuppagegridspan
+% \let\startcolumnsetspan \startpagegridspan
+% \let\stopcolumnsetspan \stoppagegridspan
+% \let\columnsetspanwidth \pagegridspanwidth
+% \let\definecolumnsetarea \definepagegridarea
+% \let\setupcolumnsetarea \setuppagegridarea
+% \let\setupcolumnsetareatext\setuppagegridareatext
+
+\endinput
+
diff --git a/tex/context/base/mkiv/m-newotf.mkiv b/tex/context/base/mkiv/m-newotf.mkiv
deleted file mode 100644
index 267d124fa..000000000
--- a/tex/context/base/mkiv/m-newotf.mkiv
+++ /dev/null
@@ -1,89 +0,0 @@
-%D \module
-%D [ file=m-newotf,
-%D version=2015.07.08,
-%D title=\CONTEXT\ Extra Modules,
-%D subtitle=Experimental OTF Loader,
-%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.
-
-% \endinput
-
-%D This module will go away as soon as we use the new loader code by default.
-%D That will happen after extensive testing. Generic support will happen after
-%D that.
-
-\unprotect
-
-\startluacode
- local files = {
- "font-otj",
- "font-otr",
- "font-cff",
- "font-ttf",
- "font-dsp",
- "font-oup",
- "font-otl",
- "font-ots",
- "font-oto",
- "font-otd",
- "font-otc",
- "font-osd",
- "font-map",
- "font-fbk",
- "font-gds",
- }
- local report = logs.reporter("newotf")
- local findfile = resolvers.findfile
- local addsuffix = file.addsuffix
- report()
- if fonts.handlers.otf.version >= 3.000 then
- report("replacing new font loader code by experimental code")
- else
- report("replacing old font loader code by new loader code")
- end
- report()
- for i=1,#files do
- local foundfile = findfile(addsuffix(files[i],"lua"))
- if foundfile and foundfile ~= "" then
- report("loading %a",foundfile)
- dofile(foundfile)
- end
- end
- report()
-
- -- needed for testing:
-
- local nuts = nodes.nuts
- local copy_node = nuts.copy
- local kern = nuts.pool.register(nuts.pool.kern())
- local setfield = nuts.setfield
-
- nuts.setattr(kern,attributes.private('fontkern'),1) -- we can have several, attributes are shared
-
- nodes.injections.installnewkern(function(k)
- local c = copy_node(kern)
- setfield(c,"kern",k)
- return c
- end)
-
- directives.register("nodes.injections.fontkern", function(v) setfield(kern,"subtype",v and 0 or 1) end)
-
- local fonts = fonts
- local handlers = fonts.handlers
- local otf = handlers.otf -- brrr
- local afm = handlers.afm -- brrr
- local getters = fonts.getters
-
- getters.kern .opentype = otf.getkern
- getters.substitution.opentype = otf.getsubstitution
- getters.alternate .opentype = otf.getalternate
- getters.multiple .opentype = otf.getmultiple
-
-\stopluacode
-
-\protect \endinput
diff --git a/tex/context/base/mkiv/m-oldotf.mkiv b/tex/context/base/mkiv/m-oldotf.mkiv
index 418d0bc2a..96554a75d 100644
--- a/tex/context/base/mkiv/m-oldotf.mkiv
+++ b/tex/context/base/mkiv/m-oldotf.mkiv
@@ -11,12 +11,6 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% \endinput
-
-%D This module will go away as soon as we use the new loader code by default.
-%D That will happen after extensive testing. Generic support will happen after
-%D that.
-
\unprotect
\startluacode
diff --git a/tex/context/base/mkiv/math-frc.mkiv b/tex/context/base/mkiv/math-frc.mkiv
index 785e8ea8e..16ea6e9e1 100644
--- a/tex/context/base/mkiv/math-frc.mkiv
+++ b/tex/context/base/mkiv/math-frc.mkiv
@@ -393,9 +393,6 @@
% $$ {{a}\abovewithdelims()#1pt{b}} $$
% }
-% \unexpanded\def\dfrac #1#2{{\displaystyle {{#1}\normalover {#2}}}}
-% \unexpanded\def\tfrac #1#2{{\textstyle {{#1}\normalover {#2}}}}
-
\definemathfraction[i:frac] [\c!alternative=\v!inner,\c!mathstyle=] % was script and then small but nothing needed
\definemathfraction[i:tfrac][\c!alternative=\v!inner,\c!mathstyle=\s!text] % was script (before luatex fix)
\definemathfraction[i:sfrac][\c!alternative=\v!inner,\c!mathstyle=\s!scriptscript]
@@ -427,6 +424,25 @@
\unexpanded\def\sfrac{\csname\inlineordisplaymath id:sfrac\endcsname}
\unexpanded\def\dfrac{\csname\inlineordisplaymath id:dfrac\endcsname}
+\definemathfraction[ams] [\c!strut=\v!no,\c!alternative=\v!outer]
+\definemathfraction[i:ams:frac][ams][\c!mathstyle={\s!cramped,\s!text}]
+\definemathfraction[d:ams:frac][ams][\c!mathstyle={\s!cramped,\s!display}]
+
+\unexpanded\def\ctxfrac{\csname\inlineordisplaymath id:frac\endcsname}
+\unexpanded\def\amsfrac{\csname\inlineordisplaymath id:ams:frac\endcsname}
+
+% \appendtoks
+% \doifelse{\mathfractionparameter\c!option}{ams}%
+% {\let\frac\amsfrac}%
+% {\let\frac\ctxfrac}%
+% \to \everysetupmathfraction
+
+\appendtoks
+ \doifelse{\mathematicsparameter\c!fractions}{ams}%
+ {\let\frac\amsfrac}%
+ {\let\frac\ctxfrac}%
+\to \everysetupmathematics
+
% \definemathfraction[ddfrac][\c!mathstyle=\s!display]
% \definemathfraction[ttfrac][\c!mathstyle=\s!text]
% \definemathfraction[ssfrac][\c!mathstyle=\s!script]
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index a8f19c567..f4d0a01a9 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -6463,6 +6463,10 @@ return {
},
},
["constants"]={
+ ["fractions"]={
+ ["en"]="fractions",
+ ["nl"]="breuken",
+ },
["action"]={
["cs"]="akce",
["de"]="aktion",
diff --git a/tex/context/base/mkiv/page-cst.lua b/tex/context/base/mkiv/page-cst.lua
new file mode 100644
index 000000000..782bbebfc
--- /dev/null
+++ b/tex/context/base/mkiv/page-cst.lua
@@ -0,0 +1,1454 @@
+if not modules then modules = { } end modules ["page-cst"] = {
+ version = 1.001,
+ comment = "companion to page-cst.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: check what is used
+
+local next, type = next, type
+local ceil, floor, odd, round = math.ceil, math.floor, math.odd, math.round
+local lower = string.lower
+local copy = table.copy
+
+local trace_state = false trackers.register("columnsets.trace", function(v) trace_state = v end)
+local trace_detail = false trackers.register("columnsets.detail", function(v) trace_detail = v end)
+local trace_cells = false trackers.register("columnsets.cells", function(v) trace_cells = v end)
+
+local report = logs.reporter("column sets")
+
+local setmetatableindex = table.setmetatableindex
+
+local properties = nodes.properties
+
+local nodecodes = nodes.nodecodes
+local gluecodes = nodes.gluecodes
+local rulecodes = nodes.rulecodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local penalty_code = nodecodes.penalty
+local insert_code = nodecodes.ins
+local mark_code = nodecodes.mark
+local rule_code = nodecodes.rule
+
+local topskip_code = gluecodes.topskip
+local lineskip_code = gluecodes.lineskip
+local baselineskip_code = gluecodes.baselineskip
+local userskip_code = gluecodes.userskip
+
+local nuts = nodes.nuts
+local tonode = nuts.tonode
+local tonut = nuts.tonut
+
+local hpack = nuts.hpack
+local vpack = nuts.vpack
+local freenode = nuts.free
+local flushlist = nuts.flush_list
+local removenode = nuts.remove
+
+local getfield = nuts.getfield
+local setfield = nuts.setfield
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setsubtype = nuts.setsubtype
+local setbox = nuts.setbox
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getsubtype = nuts.getsubtype
+local takebox = nuts.takebox
+local takelist = nuts.takelist
+local splitbox = nuts.splitbox
+local getskip = nuts.getskip
+local getattribute = nuts.getattribute
+local copylist = nuts.copy_list
+
+local getbox = nuts.getbox
+local getcount = tex.getcount
+local getdimen = tex.getdimen
+
+local texsetbox = tex.setbox
+local texsetcount = tex.setcount
+local texsetdimen = tex.setdimen
+
+local theprop = nuts.theprop
+
+local nodepool = nuts.pool
+
+local new_hlist = nodepool.hlist
+local new_vlist = nodepool.vlist
+local new_kern = nodepool.kern
+local new_trace_rule = nodepool.rule
+local new_empty_rule = nodepool.emptyrule
+
+local context = context
+local implement = interfaces.implement
+
+local variables = interfaces.variables
+local v_here = variables.here
+local v_fixed = variables.fixed
+local v_top = variables.top
+local v_bottom = variables.bottom
+local v_repeat = variables["repeat"]
+local v_left = variables.left
+local v_right = variables.right
+local v_yes = variables.yes
+local v_page = variables.page
+local v_first = variables.first
+local v_last = variables.last
+local v_wide = variables.wide
+
+pagebuilders = pagebuilders or { } -- todo: pages.builders
+pagebuilders.columnsets = pagebuilders.columnsets or { }
+local columnsets = pagebuilders.columnsets
+
+local data = { [""] = { } }
+
+-- todo: use state
+
+local function setstate(t,start)
+ if start or not t.firstcolumn then
+ t.firstcolumn = odd(getcount("realpageno")) and 1 or 2
+ end
+ if t.firstcolumn > 1 then
+ t.firstcolumn = 1
+ t.lastcolumn = t.nofleft
+ t.state = "left"
+ else
+ t.firstcolumn = t.nofleft + 1
+ t.lastcolumn = t.firstcolumn + t.nofright - 1
+ t.state = "right"
+ end
+ t.currentcolumn = t.firstcolumn
+ t.currentrow = 1
+end
+
+function columnsets.define(t)
+ local name = t.name
+ local nofleft = t.nofleft or 1
+ local nofright = t.nofright or 1
+ local nofcolumns = nofleft + nofright
+ local dataset = data[name] or { }
+ data[name] = dataset
+ dataset.nofleft = nofleft
+ dataset.nofright = nofright
+ dataset.nofcolumns = nofcolumns
+ dataset.nofrows = t.nofrows or 1
+ dataset.distance = t.distance or getdimen("bodyfontsize")
+ dataset.maxwidth = t.maxwidth or getdimen("makeupwidth")
+ dataset.lineheight = t.lineheight or getdimen("globalbodyfontstrutheight")
+ dataset.linedepth = t.linedepth or getdimen("globalbodyfontstrutdepth")
+ --
+ dataset.cells = { }
+ dataset.currentcolumn = 1
+ dataset.currentrow = 1
+ --
+ dataset.lines = dataset.lines or setmetatableindex("table")
+ dataset.start = dataset.start or setmetatableindex("table")
+ --
+ dataset.page = 1
+ --
+ local distances = dataset.distances or setmetatableindex(function(t,k)
+ return dataset.distance
+ end)
+ dataset.distances = distances
+ --
+ local widths = dataset.widths or setmetatableindex(function(t,k)
+ return dataset.width
+ end)
+ dataset.widths = widths
+ --
+ local width = t.width
+ if not width or width == 0 then
+ local dl = 0
+ local dr = 0
+ for i=1,nofleft-1 do
+ dl = dl + distances[i]
+ end
+ for i=1,nofright-1 do
+ dr = dr + distances[nofleft+i]
+ end
+ local nl = nofleft
+ local nr = nofright
+ local wl = dataset.maxwidth
+ local wr = wl
+ for i=1,nofleft do
+ local w = rawget(widths,i)
+ if w then
+ nl = nl - 1
+ wl = wl - w
+ end
+ end
+ for i=1,nofright do
+ local w = rawget(widths,nofleft+i)
+ if w then
+ nr = nr - 1
+ wr = wr - w
+ end
+ end
+ dl = (wl - dl) / nl
+ dr = (wr - dr) / nr
+ if dl > dr then
+ report("using %s page column width %p in columnset %a","right",dr,name)
+ width = dr
+ elseif dl < dr then
+ report("using %s page column width %p in columnset %a","left",dl,name)
+ width = dl
+ else
+ width = dl
+ end
+ end
+ -- report("width %p, nleft %i, nright %i",width,nofleft,nofright)
+ width = round(width)
+ dataset.width = width
+ local spans = { }
+ dataset.spans = spans
+ for i=1,nofleft do
+ local s = { }
+ local d = 0
+ for j=1,nofleft-i+1 do
+ d = d + width
+ s[j] = round(d)
+ d = d + distances[j]
+ end
+ spans[i] = s
+ end
+ for i=1,nofright do
+ local s = { }
+ local d = 0
+ for j=1,nofright-i+1 do
+ d = d + width
+ s[j] = round(d)
+ d = d + distances[j]
+ end
+ spans[nofleft+i] = s
+ end
+ --
+ local spreads = copy(spans)
+ dataset.spreads = spreads
+ local gap = 2 * getdimen("backspace")
+ for l=1,nofleft do
+ local s = spreads[l]
+ local n = #s
+ local o = s[n] + gap
+ for r=1,nofright do
+ n = n + 1
+ s[n] = s[r] + o
+ end
+ end
+ --
+ texsetdimen("d_page_grid_column_width",dataset.width)
+ --
+ setstate(dataset,true)
+ --
+ return dataset
+end
+
+local function check(dataset)
+ local cells = dataset.cells
+ local page = dataset.page
+ local offset = odd(page) and dataset.nofleft or 0
+ local start = dataset.start
+ local list = rawget(start,page)
+ if list then
+ for c, n in next, list do
+ local column = cells[offset + c]
+ if column then
+ for r=1,n do
+ column[r] = true
+ end
+ end
+ end
+ start[page] = nil
+ end
+ local lines = dataset.lines
+ local list = rawget(lines,page)
+ local rows = dataset.nofrows
+ if list then
+ for c, n in next, list do
+ local column = cells[offset + c]
+ if column then
+ if n > 0 then
+ for r=n+1,rows do
+ column[r] = true
+ end
+ elseif n < 0 then
+ for r=rows,rows+n+1,-1 do
+ column[r] = true
+ end
+ end
+ end
+ end
+ lines[page] = nil
+ end
+end
+
+local function erase(dataset,all)
+ local cells = dataset.cells
+ local nofrows = dataset.nofrows
+ local first = 1
+ local last = dataset.nofcolumns
+ --
+ if not all then
+ first = dataset.firstcolumn or first
+ last = dataset.lastcolumn or last
+ end
+ for c=first,last do
+ local column = { }
+ for r=1,nofrows do
+ if column[r] then
+ report("slot (%i,%i) is not empty",c,r)
+ end
+ column[r] = false -- not used
+ end
+ cells[c] = column
+ end
+end
+
+function columnsets.reset(t)
+ local dataset = columnsets.define(t)
+ erase(dataset,true)
+ check(dataset)
+end
+
+function columnsets.prepareflush(name)
+ local dataset = data[name]
+ local cells = dataset.cells
+ local firstcolumn = dataset.firstcolumn
+ local lastcolumn = dataset.lastcolumn
+ local nofrows = dataset.nofrows
+ local lineheight = dataset.lineheight
+ local linedepth = dataset.linedepth
+ local widths = dataset.widths
+ local height = (lineheight+linedepth)*nofrows -- - linedepth
+ --
+ local columns = { }
+ dataset.columns = columns
+ --
+ for c=firstcolumn,lastcolumn do
+ local column = cells[c]
+ for r=1,nofrows do
+ local cell = column[r]
+ if (cell == false) or (cell == true) then
+ if trace_cells then
+ column[r] = new_trace_rule(65536*2,lineheight,linedepth)
+ else
+ column[r] = new_empty_rule(0,lineheight,linedepth)
+ end
+ end
+ end
+ for r=1,nofrows-1 do
+ setlink(column[r],column[r+1])
+ end
+ local v = new_vlist(column[1])
+ setfield(v,"height",height)
+-- setfield(v,"depth",linedepth)
+ setfield(v,"width",widths[c])
+ columns[c] = v
+ end
+ --
+ texsetcount("c_page_grid_first_column",firstcolumn)
+ texsetcount("c_page_grid_last_column",lastcolumn)
+end
+
+function columnsets.flushcolumn(name,column)
+ local dataset = data[name]
+ local columns = dataset.columns
+ local packed = columns[column]
+ setbox("b_page_grid_column",packed)
+ columns[column] = nil
+end
+
+function columnsets.finishflush(name)
+ local dataset = data[name]
+ local cells = dataset.cells
+ local firstcolumn = dataset.firstcolumn
+ local lastcolumn = dataset.lastcolumn
+ local nofrows = dataset.nofrows
+ for c=firstcolumn,lastcolumn do
+ local column = { }
+ for r=1,nofrows do
+ column[r] = false -- not used
+ end
+ cells[c] = column
+ end
+ dataset.page = dataset.page + 1
+ check(dataset)
+ setstate(dataset)
+end
+
+function columnsets.block(t)
+ local dataset = data[t.name]
+ local cells = dataset.cells
+ local nofcolumns = dataset.nofcolumns
+ local nofrows = dataset.nofrows
+ --
+ local c = t.c or 0
+ local r = t.r or 0
+ if c == 0 or r == 0 or c > nofcolumns or r > nofrows then
+ return
+ end
+ local nc = t.nc or 0
+ local nr = t.nr or 0
+ if nc == 0 then
+ return
+ end
+ if nr == 0 then
+ return
+ end
+ local rr = r + nr - 1
+ local cc = c + nc - 1
+ if rr > nofrows then
+ rr = nofrows
+ end
+ if cc > nofcolumns then
+ cc = nofcolumns
+ end
+ for i=c,cc do
+ local column = cells[i]
+ for j=r,rr do
+ column[j] = true
+ end
+ end
+end
+
+local function here(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ local rr = r + nr - 1
+ if rr > nofrows then
+ return false
+ end
+ local cc = 0
+ local wd = spans[c]
+ local wc = 0
+ local nc = 0
+ for i=c,nofcolumns do
+ nc = nc + 1
+ wc = wd[nc]
+ if not wc then
+ break
+ elseif wc >= width then
+ cc = i
+ break
+ end
+ end
+ if cc == 0 or cc > nofcolumns then
+ -- report("needed %p, no slot free at (%i,%i)",width,c,r)
+ return false
+ end
+ for i=c,cc do
+ local column = cells[i]
+ for j=r,rr do
+ if column[j] then
+ -- report("width %p, needed %p, checking (%i,%i) x (%i,%i), %s",width,wc,c,r,nc,nr,"quit")
+ return false
+ end
+ end
+ end
+ -- report("width %p, needed %p, checking (%i,%i) x (%i,%i), %s",width,wc,c,r,nc,nr,"match")
+ return c, r, nc
+end
+
+local methods = {
+ [v_here] = here,
+ [v_fixed] = here,
+ tblr = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for j=1,nofrows-nr+1 do
+ for i=c,nofcolumns do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ lrtb = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=c,nofcolumns do
+ for j=1,nofrows-nr+1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ tbrl = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for j=1,nofrows-nr+1 do
+ for i=nofcolumns,c,-1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ rltb = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=nofcolumns,c,-1 do
+ for j=1,nofrows-nr+1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ btlr = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for j=nofrows-nr+1,1,-1 do
+ for i=c,nofcolumns do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ lrbt = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=c,nofcolumns do
+ for j=nofrows-nr+1,1,-1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ btrl = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for j=nofrows-nr+1,1,-1 do
+ for i=nofcolumns,c,-1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ rlbt = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=nofcolumns,c,-1 do
+ for j=nofrows-nr+1,1,-1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ fxtb = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=c,nofcolumns do
+ for j=r,nofrows-nr+1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ r = 1
+ end
+ end
+ end,
+ fxbt = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=c,nofcolumns do
+ for j=nofrows-nr+1,r,-1 do
+ if not cells[i][j] then
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ r = 1
+ end
+ end,
+ [v_top] = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=c,nofcolumns do
+ for j=1,nofrows-nr+1 do
+ if cells[i][j] then
+ break
+ else
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+ [v_bottom] = function(c,r,nr,nofcolumns,nofrows,cells,width,spans)
+ for i=c,nofcolumns do
+ for j=1,nofrows-nr+1 do
+ if cells[i][j] then
+ break
+ else
+ local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans)
+ if c then
+ return c, r, cc
+ end
+ end
+ end
+ end
+ end,
+}
+
+local threshold = 50
+
+function columnsets.check(t)
+ local dataset = data[t.name]
+ local cells = dataset.cells
+ local nofcolumns = dataset.nofcolumns
+ local nofrows = dataset.nofrows
+ local widths = dataset.widths
+ local lineheight = dataset.lineheight
+ local linedepth = dataset.linedepth
+ local distances = dataset.distances
+ local spans = dataset.spans
+ --
+ local method = lower(t.method or "tblr")
+ local boxwidth = t.width or 0
+ local boxheight = t.height or 0
+ local boxnumber = t.box
+ local box = boxnumber and getbox(boxnumber)
+ --
+ if boxwidth > 0 and boxheight > 0 then
+ -- we're ok
+ elseif box then
+ boxwidth = getfield(box,"width")
+ boxheight = getfield(box,"height") + getfield(box,"depth")
+ else
+ report("empty box")
+ return
+ end
+ --
+ local c = t.c or 0
+ local r = t.r or 0
+ if c == 0 then
+ c = dataset.currentcolumn
+ end
+ if r == 0 then
+ r = dataset.currentrow
+ end
+ if c == 0 or r == 0 or c > nofcolumns or r > nofrows then
+ texsetcount("c_page_grid_reserved_state",5)
+ return
+ end
+-- report("checking width %p, height %p, depth %p, slot (%i,%i)",boxwidth,boxheight,boxdepth,c,r)
+ local nr = ceil(boxheight/(lineheight+linedepth))
+ --
+ local action = methods[method]
+ local cfound = false
+ local rfound = false
+ local lastcolumn = dataset.lastcolumn
+ -- if t.option == v_wide then
+ -- lastcolumn = nofcolumns
+ -- spans = dataset.spreads
+ -- end
+ if action then
+ cfound, rfound, nc = action(c,r,nr,lastcolumn,nofrows,cells,boxwidth-threshold,spans)
+ end
+ if not cfound and method ~= v_here then
+ cfound, rfound, nc = here(c,r,nr,lastcolumn,nofrows,cells,boxwidth-threshold,spans)
+ end
+ if cfound then
+ local ht = nr*(lineheight+linedepth)
+ local wd = spans[cfound][nc]
+ dataset.reserved_ht = ht
+ dataset.reserved_wd = wd
+ dataset.reserved_c = cfound
+ dataset.reserved_r = rfound
+ dataset.reserved_nc = nc
+ dataset.reserved_nr = nr
+ texsetcount("c_page_grid_reserved_state",0)
+ texsetdimen("d_page_grid_reserved_height",ht)
+ texsetdimen("d_page_grid_reserved_width",wd)
+ -- report("using (%i,%i) x (%i,%i) @ (%p,%p)",cfound,rfound,nc,nr,wd,ht)
+ else
+ dataset.reserved_ht = false
+ dataset.reserved_wd = false
+ dataset.reserved_c = false
+ dataset.reserved_r = false
+ dataset.reserved_nc = false
+ dataset.reserved_nr = false
+ texsetcount("c_page_grid_reserved_state",4)
+ -- texsetdimen("d_page_grid_reserved_height",0)
+ -- texsetdimen("d_page_grid_reserved_width",0)
+ -- report("no slot found")
+ end
+end
+
+function columnsets.put(t)
+ local dataset = data[t.name]
+ local cells = dataset.cells
+ local widths = dataset.widths
+ local lineheight = dataset.lineheight
+ local linedepth = dataset.linedepth
+ local boxnumber = t.box
+ local box = boxnumber and takebox(boxnumber)
+ --
+ local c = t.c or dataset.reserved_c
+ local r = t.r or dataset.reserved_r
+ if not c or not r then
+ -- report("no reserved slot (%i,%i)",c,r)
+ return
+ end
+ local lastc = c + dataset.reserved_nc - 1
+ local lastr = r + dataset.reserved_nr - 1
+ --
+ for i=c,lastc do
+ local column = cells[i]
+ for j=r,lastr do
+ column[j] = true
+ end
+ end
+ cells[c][r] = box
+ setfield(box,"height",lineheight)
+ setfield(box,"depth",linedepth)
+ setfield(box,"width",widths[c])
+ dataset.reserved_c = false
+ dataset.reserved_r = false
+ dataset.reserved_nc = false
+ dataset.reserved_nr = false
+ --
+end
+
+local function findgap(dataset)
+ local cells = dataset.cells
+ local nofcolumns = dataset.nofcolumns
+ local nofrows = dataset.nofrows
+ local currentrow = dataset.currentrow
+ local currentcolumn = dataset.currentcolumn
+ --
+ local foundc = 0
+ local foundr = 0
+ local foundn = 0
+ for c=currentcolumn,dataset.lastcolumn do
+ local column = cells[c]
+foundn = 0
+ for r=currentrow,nofrows do
+ if not column[r] then
+ if foundc == 0 then
+ foundc = c
+ foundr = r
+ end
+ foundn = foundn + 1
+ elseif foundn > 0 then
+ return foundc, foundr, foundn
+ end
+ end
+ if foundn > 0 then
+ return foundc, foundr, foundn
+ end
+ currentrow = 1
+ end
+end
+
+-- we can enforce grid snapping
+
+-- local function checkroom(head,available,row)
+-- if row == 1 then
+-- while head do
+-- local id = getid(head)
+-- if id == glue_code then
+-- head = getnext(head)
+-- else
+-- break
+-- end
+-- end
+-- end
+-- local used = 0
+-- local line = false
+-- while head do
+-- local id = getid(head)
+-- if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code
+-- used = used + getfield(head,"height") + getfield(head,"depth")
+-- line = true
+-- elseif id == glue_code then
+-- if line then
+-- break
+-- end
+-- used = used + getfield(head,"width")
+-- elseif id == kern_code then
+-- used = used + getfield(head,"kern")
+-- elseif id == penalty_code then
+-- end
+-- if used > available then
+-- break
+-- end
+-- head = getnext(head)
+-- end
+-- return line, used
+-- end
+
+local function checkroom(head,available,row)
+ if row == 1 then
+ while head do
+ local id = getid(head)
+ if id == glue_code then
+ head = getnext(head)
+ else
+ break
+ end
+ end
+ end
+ local used = 0
+ local line = false
+ while head do
+ local id = getid(head)
+ if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code
+ used = used + getfield(head,"height") + getfield(head,"depth")
+ line = true
+ if used > available then
+ break
+ end
+ elseif id == glue_code then
+ if line then
+ break
+ end
+ used = used + getfield(head,"width")
+ if used > available then
+ break
+ end
+ elseif id == kern_code then
+ used = used + getfield(head,"kern")
+ if used > available then
+ break
+ end
+ elseif id == penalty_code then
+ -- not good enough ... we need to look bakck too
+ if getfield(head,"penalty") >= 10000 then
+ line = false
+ else
+ break
+ end
+ end
+ head = getnext(head)
+ end
+ return line, used
+end
+
+-- we could preroll on a cheap copy .. in fact, a split loop normally works on
+-- a copy ... then we could also stepsise make the height smaller .. slow but nice
+
+-- local function findslice(dataset,head,available,column,row)
+-- local used = 0
+-- local first = nil
+-- local last = nil
+-- local line = false
+-- local lineheight = dataset.lineheight
+-- local linedepth = dataset.linedepth
+-- if row == 1 then
+-- while head do
+-- local id = getid(head)
+-- if id == glue_code then
+-- head = removenode(head,head,true)
+-- else
+-- break
+-- end
+-- end
+-- end
+-- while head do
+-- -- no direction yet, if so use backend code
+-- local id = getid(head)
+-- local hd = 0
+-- if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code
+-- hd = getfield(head,"height") + getfield(head,"depth")
+-- elseif id == glue_code then
+-- hd = getfield(head,"width")
+-- elseif id == kern_code then
+-- hd = getfield(head,"kern")
+-- elseif id == penalty_code then
+-- end
+-- if used + hd > available then
+-- if first then
+-- setnext(last)
+-- setprev(head)
+-- return used, first, head
+-- else
+-- return 0
+-- end
+-- else
+-- if not first then
+-- first = head
+-- end
+-- used = used + hd
+-- last = head
+-- head = getnext(head)
+-- end
+-- end
+-- return used, first
+-- end
+
+-- todo
+--
+-- first = takelist(done)
+-- head = takelist(rest)
+-- local tail = nuts.tail(first)
+-- if false then
+-- local disc = tex.lists.split_discards_head
+-- if disc then
+-- disc = tonut(disc)
+-- setlink(tail,disc)
+-- tail = nuts.tail(disc)
+-- tex.lists.split_discards_head = nil
+-- end
+-- end
+-- setlink(tail,head)
+
+-- We work on a copy because we need to keep properties. We can make faster copies
+-- by only doing a one-level deep copy.
+
+local function findslice(dataset,head,available,column,row)
+ local first = nil
+ local lineheight = dataset.lineheight
+ local linedepth = dataset.linedepth
+ local linetotal = lineheight + linedepth
+ local slack = 65536 -- 1pt
+ local copy = copylist(head)
+ local attempts = 0
+ local usedsize = available
+ while true do
+ attempts = attempts + 1
+ texsetbox("scratchbox",tonode(new_vlist(copy)))
+ local done = splitbox("scratchbox",usedsize,"additional")
+ local used = getfield(done,"height")
+ local rest = takebox("scratchbox")
+ if used > (usedsize+slack) then
+ if trace_detail then
+ report("at (%i,%i) available %p, used %p, overflow %p",column,row,usedsize,used,used-usedsize)
+ end
+ -- flush copy
+ flushlist(takelist(done))
+ flushlist(takelist(rest))
+ -- check it we can try again
+ usedsize = usedsize - linetotal
+ if usedsize > linetotal then
+ copy = copylist(head)
+ else
+ return 0, nil, head
+ end
+ else
+ -- flush copied box
+ flushlist(takelist(done))
+ flushlist(takelist(rest))
+ -- deal with real data
+ texsetbox("scratchbox",tonode(new_vlist(head)))
+ done = splitbox("scratchbox",usedsize,"additional")
+ rest = takebox("scratchbox")
+ used = getfield(done,"height")
+ if attempts > 1 then
+ used = available
+ end
+ first = takelist(done)
+ head = takelist(rest)
+ -- return result
+ return used, first, head
+ end
+ end
+end
+
+local nofcolumngaps = 0
+
+function columnsets.add(name,box)
+ local dataset = data[name]
+ local cells = dataset.cells
+ local nofcolumns = dataset.nofcolumns
+ local nofrows = dataset.nofrows
+ local currentrow = dataset.currentrow
+ local currentcolumn = dataset.currentcolumn
+ local lineheight = dataset.lineheight
+ local linedepth = dataset.linedepth
+ local widths = dataset.widths
+ --
+ local b = getbox(box)
+ local l = getlist(b)
+-- dataset.rest = l
+ if l then
+ setlist(b,nil)
+ local hd = lineheight + linedepth
+ while l do
+ local foundc, foundr, foundn = findgap(dataset)
+ if foundc then
+ local available = foundn * hd
+ local used, first, last = findslice(dataset,l,available,foundc,foundr)
+ if first then
+ local v
+ if used == available or (foundr+foundn > nofrows) then
+ v = vpack(first,available,"exactly")
+ else
+ v = new_vlist(first)
+ end
+ nofcolumngaps = nofcolumngaps + 1
+ -- getmetatable(v).columngap = nofcolumngaps
+ properties[v] = { columngap = nofcolumngaps }
+ -- report("setting gap %a at (%i,%i)",nofcolumngaps,foundc,foundr)
+ setfield(v,"height",lineheight)
+ setfield(v,"depth",linedepth)
+ setfield(v,"width",widths[currentcolumn])
+ local column = cells[foundc]
+ --
+ column[foundr] = v
+ used = used - hd
+ if used > 0 then
+ for r=foundr+1,foundr+foundn-1 do
+ used = used - hd
+ foundr = foundr + 1
+ column[r] = true
+ if used <= 0 then
+ break
+ end
+ end
+ end
+ currentcolumn = foundc
+ currentrow = foundr
+ dataset.currentcolumn = currentcolumn
+ dataset.currentrow = currentrow
+ l = last
+ dataset.rest = l
+ else
+ local column = cells[foundc]
+ for i=foundr,foundr+foundn-1 do
+ column[i] = true
+ end
+ l = last
+ end
+ else
+ dataset.rest = l
+ return -- save and flush
+ end
+ end
+ end
+end
+
+do
+
+ -- A split approach is more efficient than a context(followup) inside
+ -- followup itself as we need less (internal) housekeeping.
+
+ local followup = nil
+ local splitter = lpeg.splitter("*",tonumber)
+
+ columnsets["noto"] = function(t)
+ return followup()
+ end
+
+ columnsets["goto"] = function(name,target)
+ local dataset = data[name]
+ local nofcolumns = dataset.nofcolumns
+ if target == v_yes or target == "" then
+ local currentcolumn = dataset.currentcolumn
+ followup = function()
+ context(dataset.currentcolumn == currentcolumn and 1 or 0)
+ end
+ return followup()
+ end
+ if target == v_first then
+ if dataset.currentcolumn > 1 then
+ target = v_page
+ else
+ return context(0)
+ end
+ end
+ if target == v_page then
+ if dataset.currentcolumn == 1 and dataset.currentrow == 1 then
+ return context(0)
+ else
+ local currentpage = dataset.page
+ followup = function()
+ context(dataset.page == currentpage and 1 or 0)
+ end
+ return followup()
+ end
+ end
+ if target == v_last then
+ target = dataset.nofcolumns
+ if dataset.currentcolumn ~= target then
+ followup = function()
+ context(dataset.currentcolumn ~= target and 1 or 0)
+ end
+ return followup()
+ end
+ return
+ end
+ local targetpage = tonumber(target)
+ if targetpage then
+ followup = function()
+ context(dataset.currentcolumn ~= targetpage and 1 or 0)
+ end
+ return followup()
+ end
+ local targetcolumn, targetrow = lpeg.match(splitter,target)
+ if targetcolumn and targetrow then
+ if dataset.currentcolumn ~= targetcolumn and dataset.currentrow ~= targetrow then
+ followup = function()
+ if dataset.currentcolumn ~= targetcolumn then
+ context(1)
+ return
+ end
+ if dataset.currentcolumn == targetcolumn then
+ context(dataset.currentrow ~= targetrow and 1 or 0)
+ else
+ context(0)
+ end
+ end
+ return followup()
+ end
+ end
+ end
+
+end
+
+function columnsets.currentcolumn(name)
+ local dataset = data[name]
+ context(dataset.currentcolumn)
+end
+
+function columnsets.flushrest(name,box)
+ local dataset = data[name]
+ local rest = dataset.rest
+ if rest then
+ dataset.rest = nil
+ setbox("global",box,new_vlist(rest))
+ end
+end
+
+function columnsets.setvsize(name)
+ local dataset = data[name]
+ local c, r, n = findgap(dataset)
+ if n then
+ dataset.currentcolumn = c
+ dataset.currentrow = r
+ else
+ dataset.currentcolumn = 1
+ dataset.currentrow = 1
+ n = 0
+ end
+ local gap = n*(dataset.lineheight+dataset.linedepth)
+ texsetdimen("d_page_grid_gap_height",gap)
+ -- can be integrated
+ -- report("state %a, n %a, column %a, row %a",dataset.state,n,dataset.currentcolumn,dataset.currentrow)
+end
+
+function columnsets.sethsize(name)
+ local dataset = data[name]
+ texsetdimen("d_page_grid_column_width",dataset.widths[dataset.currentcolumn])
+end
+
+function columnsets.sethspan(name,span)
+ -- no checking if there is really space, so we assume it can be
+ -- placed which makes spans a very explicit feature
+ local dataset = data[name]
+ local column = dataset.currentcolumn
+ local available = dataset.lastcolumn - column + 1
+ if span > available then
+ span = available
+ end
+ local width = dataset.spans[column][span]
+ texsetdimen("d_page_grid_span_width",width)
+end
+
+function columnsets.setlines(t)
+ local dataset = data[t.name]
+ dataset.lines[t.page][t.column] = t.value
+end
+
+function columnsets.setstart(t)
+ local dataset = data[t.name]
+ dataset.start[t.page][t.column] = t.value
+end
+
+function columnsets.setproperties(t)
+ local dataset = data[t.name]
+ local column = t.column
+ dataset.distances[column] = t.distance
+ dataset.widths[column] = t.width
+end
+
+local areas = { }
+
+function columnsets.registerarea(t)
+ -- maybe metatable with values
+ areas[#areas+1] = t
+end
+
+-- state : repeat | start
+
+local ctx_page_grid_set_area = context.protected.page_grid_set_area
+
+function columnsets.flushareas(name)
+ local nofareas = #areas
+ if nofareas == 0 then
+ return
+ end
+ local dataset = data[name]
+ local page = dataset.page
+ if odd(page) then
+ -- report("checking %i areas",#areas)
+ local kept = { }
+ for i=1,nofareas do
+ local area = areas[i]
+ -- local page = area.page -- maybe use page counter in columnset
+ -- local type = area.type
+ local okay = false
+ --
+ local nofcolumns = area.nc
+ local nofrows = area.nr
+ local column = area.c
+ local row = area.r
+ columnsets.block {
+ name = name,
+ c = column,
+ r = row,
+ nc = nofcolumns,
+ nr = nofrows,
+ }
+ local left = 0
+ local start = dataset.nofleft + 1
+ local overflow = (column + nofcolumns - 1) - dataset.nofleft
+ local height = nofrows * (dataset.lineheight + dataset.linedepth)
+ local width = dataset.spreads[column][nofcolumns]
+ -- report("span, width %p, overflow %i",width,overflow)
+ if overflow > 0 then
+ local used = nofcolumns - overflow
+ left = dataset.spreads[column][used] + getdimen("backspace")
+ end
+ ctx_page_grid_set_area(name,area.name,column,row,width,height,start,left) -- or via counters / dimens
+ if area.state ~= v_repeat then
+ area = nil
+ end
+ if area then
+ kept[#kept+1] = area
+ end
+ end
+ areas = kept
+ end
+end
+
+function columnsets.setarea(t)
+ local dataset = data[t.name]
+ local cells = dataset.cells
+ local box = takebox(t.box)
+ local column = t.c
+ local row = t.r
+ if column and row then
+ setfield(box,"height",dataset.lineheight)
+ setfield(box,"depth",dataset.linedepth)
+ setfield(box,"width",dataset.widths[column])
+ cells[column][row] = box
+ end
+end
+
+-- The interface.
+
+interfaces.implement {
+ name = "definecolumnset",
+ actions = columnsets.define,
+ arguments = { {
+ { "name", "string" },
+ } }
+}
+
+interfaces.implement {
+ name = "resetcolumnset",
+ actions = columnsets.reset,
+ arguments = { {
+ { "name", "string" },
+ { "nofleft", "integer" },
+ { "nofright", "integer" },
+ { "nofrows", "integer" },
+ { "lineheight", "dimension" },
+ { "linedepth", "dimension" },
+ { "width", "dimension" },
+ { "distance", "dimension" },
+ { "maxwidth", "dimension" },
+ } }
+}
+
+interfaces.implement {
+ name = "preparecolumnsetflush",
+ actions = columnsets.prepareflush,
+ arguments = { "string" },
+}
+
+interfaces.implement {
+ name = "finishcolumnsetflush",
+ actions = columnsets.finishflush,
+ arguments = { "string" },
+}
+
+interfaces.implement {
+ name = "flushcolumnsetcolumn",
+ actions = columnsets.flushcolumn,
+ arguments = { "string" ,"integer" },
+}
+
+interfaces.implement {
+ name = "setvsizecolumnset",
+ actions = columnsets.setvsize,
+ arguments = { "string" },
+}
+
+interfaces.implement {
+ name = "sethsizecolumnset",
+ actions = columnsets.sethsize,
+ arguments = { "string" },
+}
+
+interfaces.implement {
+ name = "sethsizecolumnspan",
+ actions = columnsets.sethspan,
+ arguments = { "string" ,"integer" },
+}
+
+interfaces.implement {
+ name = "flushcolumnsetrest",
+ actions = columnsets.flushrest,
+ arguments = { "string", "integer" },
+}
+
+interfaces.implement {
+ name = "blockcolumnset",
+ actions = columnsets.block,
+ arguments = { {
+ { "name", "string" },
+ { "c", "integer" },
+ { "r", "integer" },
+ { "nc", "integer" },
+ { "nr", "integer" },
+ { "box", "integer" },
+ } }
+}
+
+interfaces.implement {
+ name = "checkcolumnset",
+ actions = columnsets.check,
+ arguments = { {
+ { "name", "string" },
+ { "method", "string" },
+ { "c", "integer" },
+ { "r", "integer" },
+ { "box", "integer" },
+ { "width", "dimension" },
+ { "height", "dimension" },
+ { "option", "string" },
+ } }
+}
+
+interfaces.implement {
+ name = "putincolumnset",
+ actions = columnsets.put,
+ arguments = { {
+ { "name", "string" },
+ { "c", "integer" },
+ { "r", "integer" },
+ { "box", "integer" },
+ } }
+}
+
+interfaces.implement {
+ name = "addtocolumnset",
+ actions = columnsets.add,
+ arguments = { "string", "integer" },
+}
+
+interfaces.implement {
+ name = "setcolumnsetlines",
+ actions = columnsets.setlines,
+ arguments = { {
+ { "name", "string" },
+ { "page", "integer" },
+ { "column", "integer" },
+ { "value", "integer" },
+ } }
+}
+
+interfaces.implement {
+ name = "setcolumnsetstart",
+ actions = columnsets.setstart,
+ arguments = { {
+ { "name", "string" },
+ { "page", "integer" },
+ { "column", "integer" },
+ { "value", "integer" },
+ } }
+}
+
+interfaces.implement {
+ name = "setcolumnsetproperties",
+ actions = columnsets.setproperties,
+ arguments = { {
+ { "name", "string" },
+ { "column", "integer" },
+ { "distance", "dimension" },
+ { "width", "dimension" },
+ } }
+}
+
+interfaces.implement {
+ name = "registercolumnsetarea",
+ actions = columnsets.registerarea,
+ arguments = { {
+ { "name", "string" },
+ { "type", "string" },
+ { "page", "integer" },
+ { "state", "string" },
+ { "c", "integer" },
+ { "r", "integer" },
+ { "nc", "integer" },
+ { "nr", "integer" },
+ } }
+}
+
+interfaces.implement {
+ name = "flushcolumnsetareas",
+ actions = columnsets.flushareas,
+ arguments = "string",
+}
+
+interfaces.implement {
+ name = "setcolumnsetarea",
+ actions = columnsets.setarea,
+ arguments = { {
+ { "name", "string" },
+ { "c", "integer" },
+ { "r", "integer" },
+ { "box", "integer" },
+ } }
+}
+
+interfaces.implement {
+ name = "columnsetgoto",
+ actions = columnsets["goto"],
+ arguments = { "string" , "string" },
+}
+
+interfaces.implement {
+ name = "columnsetnoto",
+ actions = columnsets["noto"],
+}
+
+interfaces.implement {
+ name = "columnsetcurrentcolumn",
+ actions = columnsets.currentcolumn,
+ arguments = "string",
+}
diff --git a/tex/context/base/mkiv/page-cst.mkiv b/tex/context/base/mkiv/page-cst.mkiv
new file mode 100644
index 000000000..4559ec33f
--- /dev/null
+++ b/tex/context/base/mkiv/page-cst.mkiv
@@ -0,0 +1,778 @@
+%D \module
+%D [ file=page-cst,
+%D version=2016.12.15,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Page Grids (aka Column Sets),
+%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 : markings per column
+
+%D This module is work in progress and in due time it will replace
+%D columnsets.
+
+\writestatus{loading}{ConTeXt Page Macros / Page Grids}
+
+\registerctxluafile{page-cst}{1.001}
+
+\unprotect
+
+% maybe some protected def ([esc])
+
+%D Columnsets are kind of special. They are mostly meant for special products with
+%D magazine like properties. They are normally not mixed with single column layouts
+%D and not all features of \CONTEXT\ might cooperate well with a mechanism like
+%D this. We use the name page grid because (as with other reimplementations of
+%D \MKII\ features in \MKIV, we need another namespace in order to migrate stepwise.
+%D
+%D This implementation is not neccessarily better than the previous one but it might
+%D be easier to extend it. It should be a bit more efficient.
+%D
+%D When writing this code I occasionally needed a motivational musical time||out and
+%D watching the latest Snarky Puppy DVD brought me the musically and visually videos
+%D of Jacob Collier (Piano, voice, anything) on YouTube (and yes, music keeps amazing
+%D me). It's definitely more fun to watch that than to write code like this.
+
+\definesystemconstant{pagegrid}
+
+\installcorenamespace{pagegrid}
+
+\installframedcommandhandler \??pagegrid {pagegrid} \??pagegrid
+
+\setuppagegrid
+ [\c!distance=1.5\bodyfontsize,
+ \c!n=\plustwo,
+ \c!nleft=\pagegridparameter\c!n,
+ \c!nright=\pagegridparameter\c!n,
+ %\c!align=, % inherit
+ %\c!separator=\v!none,
+ %\c!setups=,
+ \c!lines=\layoutparameter\c!lines,
+ \c!frame=\v!off,
+ \c!strut=\v!no,
+ \c!offset=\v!overlay,
+ \c!alternative=\v!local,
+ \c!width=\v!auto,
+ \c!page=,
+ \c!direction=\v!normal, % todo
+ \c!maxheight=\textheight,
+ \c!maxwidth=\makeupwidth]
+
+\appendtoks % could become an option
+ \setuevalue{\e!start\currentpagegrid}{\startpagegrid[\currentpagegrid]}%
+ \setuevalue{\e!stop \currentpagegrid}{\stoppagegrid}%
+ \clf_definecolumnset {
+ name {\currentpagegrid}%
+ }%
+\to \everydefinepagegrid
+
+\newdimen \d_page_grid_column_width
+\newdimen \d_page_grid_max_height
+\newdimen \d_page_grid_max_width
+\newdimen \d_page_grid_distance
+
+\newdimen \d_page_grid_reserved_height
+\newdimen \d_page_grid_reserved_width
+\newcount \c_page_grid_reserved_state
+
+\newdimen \d_page_grid_gap_height
+
+\newcount \c_page_grid_n_of_left
+\newcount \c_page_grid_n_of_right
+\newcount \c_page_grid_n_of_rows
+\newcount \c_page_grid_first_column
+\newcount \c_page_grid_last_column
+
+\newbox \b_page_grid_collected
+\newbox \b_page_grid_column_rest
+\newbox \b_page_grid_column
+
+\unexpanded\def\setuppagegridlines{\doquadrupleempty\page_grid_setup_lines}
+\unexpanded\def\setuppagegridstart{\doquadrupleempty\page_grid_setup_start}
+
+\def\page_grid_setup_lines[#1][#2][#3][#4]% id page col value
+ {\clf_setcolumnsetlines{name {#1} page #2 column #3 value #4}}
+
+\def\page_grid_setup_start[#1][#2][#3][#4]% id page col value
+ {\clf_setcolumnsetstart{name {#1} page #2 column #3 value #4}}
+
+\unexpanded\def\page_grid_check
+ {\dorecurse{\numexpr\pagegridparameter\c!nleft+\pagegridparameter\c!nright}
+ {\page_grid_check_column{##1}}}
+
+\unexpanded\def\page_grid_check_column#1%
+ {\chaintocurrentpagegrid{\currentpagegrid:#1}%
+ \edef\p_distance{\namedpagegridparameter{\currentpagegrid:#1}\c!distance}%
+ \edef\p_width {\namedpagegridparameter{\currentpagegrid:#1}\c!width}%
+ \clf_setcolumnsetproperties {%
+ name {\currentpagegrid}
+ column \numexpr#1\relax
+ \ifx\p_distance\empty\else
+ distance \p_distance
+ \fi
+ \ifx\p_width\empty\else\ifx\p_width\v!auto\else
+ width \p_width
+ \fi\fi
+ }}
+
+\appendtoks
+ \dorecurse{\numexpr\pagegridparameter\c!nleft+\pagegridparameter\c!nright}
+ {\chaintocurrentpagegrid{\currentpagegrid:#1}}%
+\to \everydefinepagegrid
+
+\unexpanded\def\startpagegrid
+ {\bgroup
+ \dodoubleempty\page_grid_start}
+
+\def\page_grid_start_dummy[#1][#2]%
+ {\let\page_grid_stop\egroup}
+
+\def\page_grid_start[#1][#2]%
+ {\let\page_grid_start\page_grid_start_dummy
+ \ifsecondargument
+ \edef\currentpagegrid{#1}%
+ \setupcurrentpagegrid[#2]%
+ \else\iffirstargument
+ \doifassignmentelse{#1}
+ {\let\currentpagegrid\empty
+ \setupcurrentpagegrid[#1]}%
+ {\def\currentpagegrid{#1}}%
+ \else
+ \let\currentpagegrid\empty
+ \fi\fi
+ \usepageparameter\pagegridparameter
+ \c_page_grid_n_of_left \pagegridparameter\c!nleft\relax
+ \c_page_grid_n_of_right\pagegridparameter\c!nright\relax
+ \c_page_grid_n_of_rows \pagegridparameter\c!lines\relax
+ \d_page_grid_max_width \pagegridparameter\c!maxwidth\relax
+ \d_page_grid_max_height\pagegridparameter\c!maxheight\relax
+ \d_page_grid_distance \pagegridparameter\c!distance\relax
+ %
+ \ifcase\c_page_grid_n_of_rows
+ \getrawnoflines{\dimexpr\d_page_grid_max_height-\strutheight+\topskip\relax}%
+ \c_page_grid_n_of_rows\noflines
+ \fi
+ \edef\p_width{\pagegridparameter\c!width}%
+ \insidecolumnstrue % will be different flag in addition
+ \clf_resetcolumnset {
+ name {\currentpagegrid}
+ nofrows \c_page_grid_n_of_rows
+ nofleft \c_page_grid_n_of_left
+ nofright \c_page_grid_n_of_right
+ lineheight \strutht
+ linedepth \strutdp
+ \ifx\p_width\v!auto
+ % sets \d_page_grid_column_width
+ \else
+ width \p_width
+ \fi
+ distance \d_page_grid_distance
+ maxwidth \d_page_grid_max_width
+ }%
+ %
+ \page_grid_check
+ %
+ \clf_flushcolumnsetareas{\currentpagegrid}\relax
+ \setupoutputroutine[\s!pagegrid]%
+ \page_grid_command_set_hsize
+ \page_grid_command_set_vsize
+ }%\begingroup}
+
+\unexpanded\def\stoppagegrid
+ {\page_grid_stop}
+
+\def\page_grid_stop
+ {\endgraf % needed, else wrong vsize in one par case
+ \vfill % otherwise weird \placenotes[endnotes]
+ \page_otr_command_set_vsize % needed
+ \penalty\c_page_otr_eject_penalty
+ \page_grid_command_flush_page
+ \page_otr_fill_and_eject_page
+ \page_otr_command_set_vsize % needed
+ \egroup
+ \page_otr_command_set_vsize
+ \page_otr_command_set_hsize}
+
+\unexpanded\def\reservepagegrid[#1]%
+ {\begingroup
+ \letdummyparameter\c!c\plusone
+ \letdummyparameter\c!r\plusone
+ \letdummyparameter\c!nc\plusone
+ \letdummyparameter\c!nr\plusone
+ \getdummyparameters[#1]%
+ \clf_blockcolumnset {
+ name {\currentpagegrid}
+ c \dummyparameter\c!c
+ r \dummyparameter\c!r
+ nc \dummyparameter\c!nc
+ nr \dummyparameter\c!nr
+ }%
+ \endgroup}
+
+\unexpanded\def\setpagegrid
+ {\dosingleempty\page_grid_set}
+
+\unexpanded\def\page_grid_set[#1]%
+ {\begingroup
+ \letdummyparameter\c!c\zerocount
+ \letdummyparameter\c!r\zerocount
+ \letdummyparameter\c!option\v!none
+ \getdummyparameters[#1]%
+ \dowithnextboxcs\page_grid_set_indeed\hbox}
+
+\def\page_grid_set_indeed
+ {\clf_checkcolumnset {
+ name {\currentpagegrid}
+ c \dummyparameter\c!c
+ r \dummyparameter\c!r
+ box \nextbox
+ option {\dummyparameter\c!option}
+ }%
+ \ifcase\c_page_grid_reserved_state
+ \setbox\nextbox\vpack to \d_page_grid_reserved_height \bgroup
+ \vss
+ \hpack to \d_page_grid_reserved_width \bgroup
+ \box\nextbox
+ \hss
+ \egroup
+ \vss
+ \egroup
+ \wd\nextbox\d_page_grid_reserved_width
+ \clf_putincolumnset {
+ name {\currentpagegrid}
+ box \nextbox
+ }%
+ \fi
+ \endgroup}
+
+\unexpanded\def\page_grid_command_set_vsize
+ {\clf_setvsizecolumnset{\currentpagegrid}%
+ \ifdim\d_page_grid_gap_height<\lineheight
+ \page_grid_command_flush_page
+ \page_otr_fill_and_eject_page
+ \fi
+ \global\vsize\d_page_grid_gap_height
+ \pagegoal\vsize}
+
+\unexpanded\def\page_grid_command_set_hsize
+ {\clf_sethsizecolumnset{\currentpagegrid}%
+ \hsize\d_page_grid_column_width
+ \textwidth\d_page_grid_column_width}
+
+\unexpanded\def\page_grid_command_routine
+ {\ifvoid\normalpagebox \else
+ \clf_addtocolumnset{\currentpagegrid}\normalpagebox
+ \fi
+ \page_grid_command_set_vsize
+ \page_grid_command_flush_saved_floats
+ \page_grid_command_set_vsize
+ \ifdim\d_page_grid_gap_height<\lineheight
+ \page_grid_command_flush_page
+ \fi
+ \page_grid_command_set_vsize
+ \clf_flushcolumnsetrest {\currentpagegrid}\normalpagebox
+ \ifvoid\normalpagebox \else
+ \unvbox\normalpagebox
+ \fi}
+
+\installoutputroutine\synchronizepagegrid
+ {\ifvoid\normalpagebox\else
+ \clf_addtocolumnset{\currentpagegrid}\normalpagebox
+ \page_grid_command_set_vsize
+ \clf_flushcolumnsetrest{\currentpagegrid}\normalpagebox
+ \ifvoid\normalpagebox \else
+ \unvbox\normalpagebox
+ \fi
+ \fi}
+
+% todo line numbers and marks
+
+\unexpanded\def\page_grid_command_flush_page_column#1%
+ {\scratchcounter#1\relax
+ \clf_flushcolumnsetcolumn{\currentpagegrid}\scratchcounter
+ \anch_mark_column_box\b_page_grid_column
+ \page_marks_synchronize_column\c_page_grid_first_column\c_page_grid_last_column\scratchcounter\b_page_grid_column
+ \ifnum\scratchcounter>\c_page_grid_n_of_left
+ \advance\scratchcounter-\c_page_grid_n_of_left
+ \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_right\plustwo
+ \else
+ \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_left\plustwo
+ \fi
+ \begingroup
+ \edef\currentpagegrid{\currentpagegrid:#1}%
+ \inheritedpagegridframedbox\box\b_page_grid_column
+ \endgroup}
+
+\unexpanded\def\page_grid_command_flush_page
+ {\deactivatecolor % puzzling, try ungrouped color \red or so
+ \setbox\b_page_grid_collected\hpack\bgroup
+ \clf_preparecolumnsetflush{\currentpagegrid}%
+ \letpagegridparameter\c!region\currentpagegrid
+ \doifelse{\pagegridparameter\c!direction}\v!reverse
+ {\dostepwiserecurse\c_page_grid_last_column\c_page_grid_first_column\minusone
+ {\page_grid_command_flush_page_column{##1}%
+ \ifnum##1>\plusone
+ \kern\namedpagegridparameter{\currentpagegrid:##1}\c!distance\relax
+ \fi}}%
+ {\dostepwiserecurse\c_page_grid_first_column\c_page_grid_last_column\plusone
+ {\page_grid_command_flush_page_column{##1}%
+ \ifnum##1<\c_page_grid_last_column
+ \kern\namedpagegridparameter{\currentpagegrid:##1}\c!distance\relax
+ \fi}}%
+ \clf_finishcolumnsetflush{\currentpagegrid}%
+ \egroup
+ \page_otr_construct_and_shipout\box\b_page_grid_collected
+ \clf_flushcolumnsetareas{\currentpagegrid}\relax
+ \page_grid_command_flush_saved_floats}
+
+% slow but robust
+
+\unexpanded\def\page_grid_command_next_progress
+ {\strut
+ \page_otr_flush_all_floats
+ \page_otr_eject_page
+ \ifcase\clf_columnsetnoto\else
+ \expandafter\page_grid_command_next_progress
+ \fi}
+
+\unexpanded\def\page_grid_command_handle_column
+ {\ifcase\clf_columnsetgoto{\currentpagegrid}{\page_breaks_columns_current_option}\relax\else
+ \expandafter\page_grid_command_next_progress
+ \fi}
+
+\installcolumnbreakmethod\s!pagegrid\s!unknown {\page_grid_command_handle_column}
+\installcolumnbreakmethod\s!pagegrid\v!yes {\page_grid_command_handle_column}
+
+\unexpanded\def\page_grid_command_next_page
+ {\ifcase\clf_columnsetgoto{\currentpagegrid}{\v!page}\relax\else
+ \page_grid_command_flush_page
+ \fi}
+
+\unexpanded\def\page_grid_command_next_page_and_inserts
+% {\page_otr_eject_page_and_flush_inserts}
+ {\page_otr_flush_all_floats
+ \page_grid_command_next_page}
+
+\let\page_grid_command_package_contents\page_one_command_package_contents
+
+\unexpanded\def\page_grid_command_flush_saved_floats
+ {\ifconditional\c_page_floats_flushing \else
+ \ifconditional\c_page_floats_some_waiting
+ \page_grid_command_flush_saved_floats_indeed
+ \fi
+ \fi}
+
+\unexpanded\def\page_grid_command_flush_saved_floats_indeed
+ {\page_floats_flush\s!text\plusone
+ \clf_checkcolumnset {
+ name {\currentpagegrid}
+ method {\floatmethod}
+ width \wd\floatbox
+ height \ht\floatbox
+ }%
+ \ifcase\c_page_grid_reserved_state
+ \page_grid_place_float_here_indeed
+ \page_grid_command_set_vsize % needed
+ \ifconditional\c_page_floats_some_waiting
+ \doubleexpandafter\page_grid_command_flush_saved_floats_indeed
+ \fi
+ \else
+ \page_floats_resave\s!text
+ \fi}
+
+% needs checking
+
+\unexpanded\def\page_grid_command_flush_floats
+ {\wait\global\settrue\c_page_floats_flushing
+ \ifconditional\c_page_floats_some_waiting
+ \par
+ \page_grid_command_flush_floats_indeed
+ \fi
+ \global\savednoffloats\zerocount
+ \global\setfalse\c_page_floats_some_waiting
+ \global\setfalse\c_page_floats_flushing}
+
+\def\page_grid_command_flush_floats_indeed % much in common with OTRSET
+ {\wait\ifconditional\c_page_floats_some_waiting
+ \ifconditional\c_page_floats_pack_flushed
+ \setfalse\c_page_floats_center_box % not needed as we do call directly
+ \page_floats_collect\s!text\hsize\emwidth
+ \global\setbox\floatbox\hbox to \hsize
+ {\hfil
+ \dorecurse\nofcollectedfloats
+ {\ifcase\columndirection % nog document wide
+ \page_floats_flush\s!text\plusone
+ \else
+ \page_floats_flush\s!text{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}%
+ \fi
+ \ifdim\wd\floatbox>\makeupwidth % \hsize
+ \hbox to \makeupwidth{\hss\box\floatbox\hss}%
+ \else
+ \box\floatbox
+ \fi
+ \ifnum\recurselevel<\nofcollectedfloats
+ \hfil
+ \fi}%
+ \hfil}%
+ \else
+ \page_floats_get
+ \fi
+ \doplacefloatbox
+ \expandafter\page_grid_command_flush_floats_indeed
+ \fi}
+
+% so far
+
+\unexpanded\def\page_grid_command_check_if_float_fits
+ {\clf_checkcolumnset {
+ name {\currentpagegrid}
+ method {\floatmethod}
+ % c \zerocount
+ % r \zerocount
+ box \floatbox
+ }%
+ \ifcase\c_page_grid_reserved_state
+ \global\settrue\c_page_floats_room
+ \else
+ \global\setfalse\c_page_floats_room
+ \fi}
+
+\unexpanded\def\page_grid_place_float_here_indeed
+ {\setbox\floatbox\vpack to \d_page_grid_reserved_height \bgroup
+ \vss
+ \hpack to \d_page_grid_reserved_width \bgroup
+ % \hss % no
+ \box\floatbox
+ \hss
+ \egroup
+ \vss
+ \egroup
+ \clf_putincolumnset {
+ name {\currentpagegrid}
+ box \floatbox
+ }}
+
+\def\page_grid_place_float_slot
+ {% safeguard
+ \ifx\floatmethod\empty
+ \let\floatmethod\v!here
+ \fi
+ % synchronize
+ \penalty\c_page_otr_eject_penalty
+ % push
+ \setbox\savedfloatbox\box\floatbox
+ \page_grid_command_flush_saved_floats
+ \setbox\floatbox\box\savedfloatbox
+ % pop
+ \ifconditional\c_page_floats_some_waiting
+ \page_floats_save\s!text
+ \nonoindentation
+ \else
+ \clf_checkcolumnset {
+ name {\currentpagegrid}
+ method {\floatmethod}
+ \ifx\floatcolumn\empty \else
+ c \floatcolumn
+ \fi
+ \ifx\floatrow\empty \else
+ r \floatrow
+ \fi
+ box \floatbox
+ }%
+ \ifcase\c_page_grid_reserved_state
+ \page_grid_place_float_here_indeed
+ \else
+ \page_floats_save\s!text
+ \nonoindentation
+ \fi
+ \fi}
+
+\def\page_grid_place_float_fixed % todo: fallback on here
+ {\ifx\floatcolumn\empty
+ \let\floatmethod\v!here
+ \else\ifx\floatrow\empty
+ \let\floatmethod\v!here
+ \else
+ \let\floatmethod\v!fixed
+ \fi\fi
+ \page_grid_place_float_slot}
+
+\def\page_grid_place_float_force
+ {% synchronize
+ \penalty\c_page_otr_eject_penalty
+ \clf_checkcolumnset {
+ name {\currentpagegrid}
+ method {\floatmethod}
+ box \floatbox
+ }%
+ \ifcase\c_page_grid_reserved_state
+ \page_grid_place_float_here_indeed
+ \else
+ \page_floats_save\s!text
+ \nonoindentation
+ \fi}
+
+\def\page_grid_place_float_page {\page_grid_place_float_slot} % todo: fallback on here
+
+\def\page_grid_place_float_here {\let\floatmethod\v!here\page_grid_place_float_slot}
+\def\page_grid_place_float_top {\page_grid_place_float_slot}
+\def\page_grid_place_float_bottom{\page_grid_place_float_slot}
+
+\installfloatmethod \s!pagegrid \v!here \page_grid_place_float_here
+\installfloatmethod \s!pagegrid \v!force \page_grid_place_float_force % todo
+%installfloatmethod \s!pagegrid \v!left
+%installfloatmethod \s!pagegrid \v!right
+%installfloatmethod \s!pagegrid \v!text
+\installfloatmethod \s!pagegrid \v!top \page_grid_place_float_top
+\installfloatmethod \s!pagegrid \v!bottom \page_grid_place_float_bottom
+%installfloatmethod \s!pagegrid \v!auto
+%installfloatmethod \s!pagegrid \v!margin
+%installfloatmethod \s!pagegrid \v!opposite
+\installfloatmethod \s!pagegrid \v!page \page_grid_place_float_page
+%installfloatmethod \s!pagegrid \v!leftpage
+%installfloatmethod \s!pagegrid \v!rightpage
+%installfloatmethod \s!pagegrid \v!inmargin
+%installfloatmethod \s!pagegrid \v!inleft
+%installfloatmethod \s!pagegrid \v!inright
+%installfloatmethod \s!pagegrid \v!leftmargin
+%installfloatmethod \s!pagegrid \v!rightmargin
+%installfloatmethod \s!pagegrid \v!leftedge
+%installfloatmethod \s!pagegrid \v!rightedge
+%installfloatmethod \s!pagegrid \v!somewhere
+%installfloatmethod \s!pagegrid \v!backspace
+%installfloatmethod \s!pagegrid \v!cutspace
+\installfloatmethod \s!pagegrid \s!tblr \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!lrtb \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!tbrl \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!rltb \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!fxtb \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!btlr \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!lrbt \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!btrl \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!rlbt \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!fxbt \page_grid_place_float_slot
+\installfloatmethod \s!pagegrid \s!fixd \page_grid_place_float_fixed
+
+%
+
+\unexpanded\def\page_grid_command_side_float_output
+ {} % nothing, reset anyway
+
+\unexpanded\def\page_grid_command_flush_side_floats
+ {\page_sides_forget_floats}
+
+\unexpanded\def\page_grid_command_synchronize_side_floats
+ {\page_sides_forget_floats}
+
+\unexpanded\def\page_grid_command_synchronize_hsize
+ {\page_grid_command_set_hsize}
+
+\defineoutputroutine
+ [\s!pagegrid]
+ [\s!page_otr_command_routine =\page_grid_command_routine,
+ \s!page_otr_command_package_contents =\page_grid_command_package_contents,
+ \s!page_otr_command_set_vsize =\page_grid_command_set_vsize,
+ \s!page_otr_command_set_hsize =\page_grid_command_set_hsize, % tricky, goes wrong
+ \s!page_otr_command_next_page =\page_grid_command_next_page,
+ \s!page_otr_command_next_page_and_inserts =\page_grid_command_next_page_and_inserts,
+ \s!page_otr_command_synchronize_hsize =\page_grid_command_synchronize_hsize,
+ % \s!page_otr_command_set_top_insertions =\page_grid_command_set_top_insertions,
+ % \s!page_otr_command_set_bottom_insertions =\page_grid_command_set_bottom_insertions,
+ % \s!page_otr_command_flush_top_insertions =\page_grid_command_flush_top_insertions,
+ % \s!page_otr_command_flush_bottom_insertions =\page_grid_command_flush_bottom_insertions,
+ % \s!page_otr_command_set_float_hsize =\page_grid_command_set_float_hsize,
+ \s!page_otr_command_check_if_float_fits =\page_grid_command_check_if_float_fits,
+ % \s!page_otr_command_flush_float_box =\page_grid_command_flush_float_box,
+ \s!page_otr_command_synchronize_side_floats =\page_grid_command_synchronize_side_floats,
+ \s!page_otr_command_side_float_output =\page_grid_command_side_float_output,
+ \s!page_otr_command_flush_floats =\page_grid_command_flush_floats,
+ \s!page_otr_command_flush_side_floats =\page_grid_command_flush_side_floats,
+ \s!page_otr_command_flush_saved_floats =\page_grid_command_flush_saved_floats
+ % \s!page_otr_command_flush_margin_blocks =\page_grid_command_flush_margin_blocks, % not used
+ ]
+
+% spans
+
+\installcorenamespace{pagegridspan}
+
+\installframedcommandhandler \??pagegridspan {pagegridspan} \??pagegridspan
+
+\setuppagegridspan
+ [\c!frame=\v!off,
+ \c!before=,
+ \c!after=,
+ \c!offset=\v!overlay,
+ \c!location=\v!left,
+ \c!linecorrection=\v!off,
+ \c!depthcorrection=\v!off,
+ \c!n=\plustwo,
+ \c!nlines=\zerocount,
+ \c!align=\v!normal,
+ \c!width=\d_page_grid_span_width,
+ \c!indenting=,
+ \c!indentnext=\v!yes,
+ \c!default=\v!here,
+ \c!alternative=\v!a]
+
+\newdimen\d_page_grid_span_width
+
+\unexpanded\def\startpagegridspan
+ {\dotripleempty\page_grid_span_start}
+
+\def\page_grid_span_start[#1][#2][#3]% [#3] gobbles space
+ {\endgraf % else rubish output if forgotten
+ \synchronizepagegrid
+ \bgroup
+ \forgetall
+ \edef\currentpagegridspan{#1}%
+ \clf_sethsizecolumnspan{\currentpagegrid}\pagegridspanparameter\c!n\relax
+ \setbox\scratchbox\hbox\bgroup\inheritedpagegridspanframed\bgroup
+ \usepagegridspanstyleandcolor\c!style\c!color
+ \pagegridspanparameter\c!before
+ \ignorespaces}
+
+\unexpanded\def\stoppagegridspan
+ {\removeunwantedspaces
+ \par
+ \verticalstrut
+ \kern-2\struttotal
+ \verticalstrut
+ \endgraf
+ \pagegridspanparameter\c!after
+ \egroup\egroup
+ \setpagegrid{\box\scratchbox}%
+ % todo: push into slot
+ \egroup
+ \endgraf}
+
+\def\pagegridspanwidth#1% assumes equal distances
+ {\the\dimexpr
+ #1\d_page_grid_column_width
+ +#1\d_page_grid_distance
+ - \d_page_grid_distance
+ \relax}
+
+% areas
+
+\installcorenamespace{pagegridarea}
+
+\installframedcommandhandler \??pagegridarea {pagegridarea} \??pagegridarea
+
+\setuppagegridarea
+ [\c!x=\plusone,
+ \c!y=\plusone,
+ \c!nx=\plusone,
+ \c!ny=\plusone,
+ \c!clipoffset=2\lineheight,
+ \c!leftoffset=\zeropoint,
+ \c!rightoffset=\zeropoint,
+ \c!offset=\v!overlay,
+ \c!strut=\v!no,
+ \c!frame=\v!off,
+ %\c!type=\v!next,
+ \c!align=\v!normal,
+ \c!page=\plusone,
+ \c!state=\v!stop]
+
+% type: both fixed left right next (not now), then better
+% lefttext and righttext or so
+
+\appendtoks
+ % \edef\p_type{}%
+ % \ifx\p_type\v!next
+ % \doifelseoddpage
+ % {\letpagegridareaparameter\c!type\v!right}%
+ % {\letpagegridareaparameter\c!type\v!left}%
+ % \fi
+ \clf_registercolumnsetarea {
+ name {\currentpagegridarea}
+ % type {\p_type}
+ % page \pagegridareaparameter\c!page
+ state {\pagegridareaparameter\c!state}
+ c \pagegridareaparameter\c!x
+ r \pagegridareaparameter\c!y
+ nc \pagegridareaparameter\c!nx
+ nr \pagegridareaparameter\c!ny
+ }%
+\to \everydefinepagegridarea
+
+\unexpanded\def\setuppagegridareatext
+ {\dodoubleargument\page_grid_set_area_text}
+
+\def\page_grid_set_area_text[#1][#2]%
+ {\edef\currentpagegridarea{#1}%
+ \setpagegridareaparameter\c!text{#2}}
+
+% maybe move the left/right correction to the tex end or the offset to lua
+
+\unexpanded\def\page_grid_set_area#1#2#3#4#5#6#7#8% can be optimized
+ {\begingroup
+ \edef\currentpagegridarea{#2}%
+ \setpagegridareaparameter\c!width {#5\scaledpoint}%
+ \setpagegridareaparameter\c!height{#6\scaledpoint}%
+ \setbox\nextbox\hpack\bgroup\inheritedpagegridareaframed\bgroup
+ \usepagegridareastyleandcolor\c!style\c!color
+ \ignorespaces
+ \pagegridareaparameter\c!text
+ \egroup\egroup
+ %
+ \scratchdimen#8\scaledpoint
+ \ifdim\scratchdimen>\zeropoint
+ \setbox\scratchbox\vbox\bgroup
+ \clip
+ [ \c!offset=\pagegridareaparameter\c!clipoffset,%
+ \c!rightoffset=\pagegridareaparameter\c!rightoffset,%
+ \c!width=\scratchdimen,%
+ % \c!height=
+ ]%
+ {\copy\nextbox}%
+ \egroup
+ \clf_setcolumnsetarea{name {#1} box \scratchbox c #3 r #4}%
+ \setbox\scratchbox\vbox\bgroup
+ \hskip-\layoutparameter\c!backspace % todo: #9
+ \clip
+ [ \c!offset=\pagegridareaparameter\c!clipoffset,%
+ \c!leftoffset=\pagegridareaparameter\c!rightoffset,%
+ \c!hoffset=\scratchdimen,%
+ \c!width=\dimexpr\wd\nextbox-\scratchdimen\relax,%
+ % \c!height=
+ ]%
+ {\box\nextbox}%
+ \egroup
+ \clf_setcolumnsetarea{name {#1} box \scratchbox c #7 r #4}%
+ \else
+ \setbox\scratchbox\vbox\bgroup
+ \box\nextbox % wrapping needed
+ \egroup
+ \clf_setcolumnsetarea{name {#1} box \scratchbox c #3 r #4}%
+ \fi
+ \endgroup}
+
+\let\setpagegridarea\page_grid_set_area
+
+% state start | repeat
+
+% for now (transition)
+
+\let\definecolumnset \definepagegrid
+\let\setupcolumnset \setuppagegrid
+\let\setupcolumnsetlines \setuppagegridlines
+\let\setupcolumnsetstart \setuppagegridstart
+\let\startcolumnset \startpagegrid
+\let\stopcolumnset \stoppagegrid
+\let\definecolumnsetspan \definepagegridspan
+\let\setupcolumnsetspan \setuppagegridspan
+\let\startcolumnsetspan \startpagegridspan
+\let\stopcolumnsetspan \stoppagegridspan
+\let\columnsetspanwidth \pagegridspanwidth
+\let\definecolumnsetarea \definepagegridarea
+\let\setupcolumnsetarea \setuppagegridarea
+\let\setupcolumnsetareatext\setuppagegridareatext
+
+\protect
+
diff --git a/tex/context/base/mkiv/page-lin.lua b/tex/context/base/mkiv/page-lin.lua
index 1124d80f9..5b18d9823 100644
--- a/tex/context/base/mkiv/page-lin.lua
+++ b/tex/context/base/mkiv/page-lin.lua
@@ -40,6 +40,8 @@ local v_next = variables.next
local v_page = variables.page
local v_no = variables.no
+local properties = nodes.properties
+
local nodecodes = nodes.nodecodes
local skipcodes = nodes.skipcodes
local whatcodes = nodes.whatcodes
@@ -346,74 +348,131 @@ end
-- store first and last per page
-- maybe just set marks directly
+local function findcolumngap(list)
+ -- we assume wrapped boxes, only one with numbers
+ local n = list
+ while n do
+ local id = getid(n)
+ if id == hlist_code or id == vlist_code then
+ local p = properties[n]
+ if p and p.columngap then
+ if trace_numbers then
+ report_lines("first column gap %a",p.columngap)
+ end
+ return n
+ else
+ local list = getlist(n)
+ if list then
+ local okay = findcolumngap(list)
+ if okay then
+ return okay
+ end
+ end
+ end
+ end
+ n = getnext(n)
+ end
+end
+
function boxed.stage_one(n,nested)
current_list = { }
local box = getbox(n)
- if box then
- local list = getlist(box)
- if not list then
- return
- end
- if nested then
- local id = getid(box)
- if id == vlist_code then
- if listisnumbered(list) then
- -- ok
- else
- list = findnumberedlist(list)
+ if not box then
+ return
+ end
+ local list = getlist(box)
+ if not list then
+ return
+ end
+ local last_a = nil
+ local last_v = -1
+ local skip = false
+
+ local function check()
+ for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
+ local subtype = getsubtype(n)
+ if subtype ~= line_code then
+ -- go on
+ elseif getfield(n,"height") == 0 and getfield(n,"depth") == 0 then
+ -- skip funny hlists -- todo: check line subtype
+ else
+ local a = lineisnumbered(n)
+ if a then
+ if last_a ~= a then
+ local da = data[a]
+ local ma = da.method
+ if ma == v_next then
+ skip = true
+ elseif ma == v_page then
+ da.start = 1 -- eventually we will have a normal counter
+ end
+ last_a = a
+ if trace_numbers then
+ report_lines("starting line number range %s: start %s, continue %s",a,da.start,da.continue or v_no)
+ end
+ end
+ if getattr(n,a_displaymath) then
+ if is_display_math(n) then
+ check_number(n,a,skip)
+ end
+ else
+ local v = getattr(list,a_verbatimline)
+ if not v or v ~= last_v then
+ last_v = v
+ check_number(n,a,skip)
+ else
+ check_number(n,a,skip,true)
+ end
+ end
+ skip = false
end
- else -- hlist
+ end
+ end
+ end
+
+ if nested == 0 then
+ if list then
+ check()
+ end
+ elseif nested == 1 then
+ local id = getid(box)
+ if id == vlist_code then
+ if listisnumbered(list) then
+ -- ok
+ else
list = findnumberedlist(list)
end
+ else -- hlist
+ list = findnumberedlist(list)
end
- -- we assume we have a vlist
if list then
- local last_a = nil
- local last_v = -1
- local skip = false
- for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
- local subtype = getsubtype(n)
- if subtype ~= line_code then
- -- go on
- elseif getfield(n,"height") == 0 and getfield(n,"depth") == 0 then
- -- skip funny hlists -- todo: check line subtype
- else
- local a = lineisnumbered(n)
- if a then
- if last_a ~= a then
- local da = data[a]
- local ma = da.method
- if ma == v_next then
- skip = true
- elseif ma == v_page then
- da.start = 1 -- eventually we will have a normal counter
- end
- last_a = a
- if trace_numbers then
- report_lines("starting line number range %s: start %s, continue %s",a,da.start,da.continue or v_no)
- end
- end
- if getattr(n,a_displaymath) then
- if is_display_math(n) then
- check_number(n,a,skip)
- end
- else
- local v = getattr(list,a_verbatimline)
- if not v or v ~= last_v then
- last_v = v
- check_number(n,a,skip)
- else
- check_number(n,a,skip,true)
- end
- end
- skip = false
- end
+ check()
+ end
+ elseif nested == 2 then
+ list = findcolumngap(list)
+ -- we assume we have a vlist
+ if not list then
+ return
+ end
+ for n in traverse_id(vlist_code,list) do
+ local p = properties[n]
+ if p and p.columngap then
+ if trace_numbers then
+ report_lines("found column gap %a",p.columngap)
+ end
+ list = getlist(n)
+ if list then
+ check()
end
end
end
+ else
+ -- bad call
end
end
+-- column attribute
+
function boxed.stage_two(n,m)
if #current_list > 0 then
m = m or lines.scratchbox
@@ -452,7 +511,7 @@ end
implement {
name = "linenumbersstageone",
actions = boxed.stage_one,
- arguments = { "integer", "boolean" }
+ arguments = { "integer", "integer" }
}
implement {
diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi
index 290984779..5756d870b 100644
--- a/tex/context/base/mkiv/page-lin.mkvi
+++ b/tex/context/base/mkiv/page-lin.mkvi
@@ -310,7 +310,6 @@
\b_page_lines_number #box\relax
\c_page_lines_column #column\relax
\c_page_lines_last_column#max\relax
- \c_page_lines_nesting #nesting\relax
\fullrestoreglobalbodyfont
\let\makelinenumber\page_lines_make_number % used at lua end
\setbox\b_page_lines_scratch\vbox
@@ -318,7 +317,7 @@
\offinterlineskip
\clf_linenumbersstageone
\b_page_lines_number
- \ifcase\c_page_lines_nesting false\else true\fi
+ #nesting%
\relax}%
\clf_linenumbersstagetwo
\b_page_lines_number
diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv
index c54606451..f2ddb16ea 100644
--- a/tex/context/base/mkiv/spac-ver.mkiv
+++ b/tex/context/base/mkiv/spac-ver.mkiv
@@ -1758,7 +1758,13 @@
{\dotripleempty\spac_vspacing_define_amount}
\def\spac_vspacing_define_amount[#1][#2][#3]% can be combined
- {\setvalue{\??vspacingamount#1}{\ifgridsnapping#3\else#2\fi}%
+ {\ifthirdargument
+ \setvalue{\??vspacingamount#1}{\ifgridsnapping#3\else#2\fi}%
+ \else\ifsecondargument
+ \setvalue{\??vspacingamount#1}{\ifgridsnapping\lineheight\else#2\fi}%
+ \else
+ \setvalue{\??vspacingamount#1}{\lineheight}%
+ \fi\fi
\clf_vspacingsetamount{#1}}
% \installcorenamespace{vspacingamountnormal}
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 7c90060c8..ed06b4547 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 2f6007d38..a8fc8f408 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-con.mkvi b/tex/context/base/mkiv/strc-con.mkvi
index be6e9d359..25e26bf73 100644
--- a/tex/context/base/mkiv/strc-con.mkvi
+++ b/tex/context/base/mkiv/strc-con.mkvi
@@ -135,7 +135,7 @@
\dodoubleempty\strc_constructions_start_regular}
\unexpanded\def\strc_constructions_start_regular[#1][#2]%
- {\strc_constructions_register[\c!label={\constructionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1][#2]%
+ {\strc_constructions_register[#2][\c!label={\constructionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1]%
\csname\??constructionstarthandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_constructions_stop
@@ -877,14 +877,14 @@
\let\currentconstructionlistentry\!!zerocount
-\def\strc_constructions_register
+\unexpanded\def\strc_constructions_register
{\clf_doifelselisthasentry\numexpr\currentconstructionlistentry\relax
\strc_constructions_register_nop
\strc_constructions_register_yes}
% \def\strc_constructions_register{\strc_constructions_register_yes}
-\def\strc_constructions_register_nop[#1][#2]% #1=interfaced-settings, #2=optional user data
+\def\strc_constructions_register_nop[#1][#2]% #1=optional user data #2=interfaced-settings
%{\writestatus{constructions}{reusing \currentconstruction: \number\currentconstructionlistentry}}
{}
@@ -898,9 +898,9 @@
\let\currentconstructionsynchronize\relax
\let\currentconstructionattribute \attributeunsetvalue
-\def\strc_constructions_register_yes[#1][#2]% #1=interfaced-settings, #2=optional user data
+\def\strc_constructions_register_yes[#1][#2]% #1=optional user data #2=interfaced-settings
{\begingroup % similar to structure so we might generalize this
- \setupcurrentconstruction[#1]% % xdef's will become edef's
+ \setupcurrentconstruction[#2]% % xdef's will become edef's
\xdef\currentconstructionexpansion {\constructionparameter\c!expansion}%
\xdef\currentconstructionxmlsetup {\constructionparameter\c!xmlsetup}%
\xdef\currentconstructioncatcodes {\constructionparameter\s!catcodes}%
@@ -1008,7 +1008,7 @@
\or
% symbol
\fi
- userdata {\detokenize{#2}}
+ userdata {\detokenize{#1}}
\relax
% \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}%
\clf_setinternalreference
@@ -1033,6 +1033,10 @@
{\edef\currentconstructionattribute {\clf_getinternallistreference#1}%
\edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}}
+\def\reinstatecachedconstructionnumberentry#1% was xdef | #1 = cached index can be different from real
+ {\edef\currentconstructionattribute {\clf_getinternalcachedlistreference#1}% destination
+ \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}}
+
\installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}}
% Helpers:
diff --git a/tex/context/base/mkiv/strc-des.mkvi b/tex/context/base/mkiv/strc-des.mkvi
index 83daba0fe..4376d9cdc 100644
--- a/tex/context/base/mkiv/strc-des.mkvi
+++ b/tex/context/base/mkiv/strc-des.mkvi
@@ -107,7 +107,7 @@
{\doifelseassignment{#1}\strc_descriptions_start_yes_assignment\strc_descriptions_start_yes_reference[#1]}
\unexpanded\def\strc_descriptions_start_yes_assignment[#1]% todo userdata
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1]%
\csname\??constructionstarthandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_start_yes_reference
@@ -124,11 +124,11 @@
\strc_descriptions_start_yes_normal[#1]}}
\unexpanded\def\strc_descriptions_start_yes_titled_indeed[#1]#2% todo userdata
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]%
\csname\??constructionstarthandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_start_yes_normal[#1]% todo userdata
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=]%
\csname\??constructionstarthandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_start_nop
@@ -145,11 +145,11 @@
\strc_descriptions_start_nop_normal}}%
\unexpanded\def\strc_descriptions_start_nop_titled_indeed#1%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=]%
\csname\??constructionstarthandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_start_nop_normal
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=]%
\csname\??constructionstarthandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_stop
@@ -171,7 +171,7 @@
\fi}
\unexpanded\def\strc_descriptions_yes_titled[#1]#2%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]%
\csname\??constructioncommandhandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_yes_titled[#1]%
@@ -181,11 +181,11 @@
\strc_descriptions_yes_normal[#1]}}
\unexpanded\def\strc_descriptions_yes_titled_indeed[#1]#2%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]%
\csname\??constructioncommandhandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_yes_normal[#1]%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=]%
\csname\??constructioncommandhandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_nop
@@ -202,11 +202,11 @@
\strc_descriptions_nop_normal}}
\unexpanded\def\strc_descriptions_nop_titled_indeed#1%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=]%
\csname\??constructioncommandhandler\currentconstructionhandler\endcsname}
\unexpanded\def\strc_descriptions_nop_normal
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=]%
\csname\??constructioncommandhandler\currentconstructionhandler\endcsname}
%D Handlers:
diff --git a/tex/context/base/mkiv/strc-lst.lua b/tex/context/base/mkiv/strc-lst.lua
index 79f4dfc39..770947e32 100644
--- a/tex/context/base/mkiv/strc-lst.lua
+++ b/tex/context/base/mkiv/strc-lst.lua
@@ -286,7 +286,7 @@ function lists.discard(n)
-- maybe an error message
elseif n == #cached then
cached[n] = nil
- n = n -1
+ n = n - 1
while n > 0 and cached[n] == false do
cached[n] = nil -- collect garbage
n = n - 1
@@ -330,7 +330,7 @@ function lists.enhance(n)
local kind = metadata.kind
local name = metadata.name
if trace_lists then
- report_lists("enhancing %a, name %a",n,name)
+ report_lists("enhancing %a, name %a, page %a",n,name,references.realpage or 0)
end
-- if references then
-- -- is this used ?
diff --git a/tex/context/base/mkiv/strc-not.lua b/tex/context/base/mkiv/strc-not.lua
index bf14092d1..024366438 100644
--- a/tex/context/base/mkiv/strc-not.lua
+++ b/tex/context/base/mkiv/strc-not.lua
@@ -32,7 +32,7 @@ lists.enhancers = lists.enhancers or { }
storage.register("structures/notes/states", notes.states, "structures.notes.states")
local notestates = notes.states
-local notedata = { }
+local notedata = table.setmetatableindex("table")
local variables = interfaces.variables
local context = context
@@ -51,10 +51,6 @@ local function store(tag,n)
end
--
local nd = notedata[tag]
- if not nd then
- nd = { }
- notedata[tag] = nd
- end
local nnd = #nd + 1
nd[nnd] = n
local state = notestates[tag]
@@ -66,7 +62,7 @@ local function store(tag,n)
end
state.start = state.start or nnd
end
- return #nd
+ return nnd
end
notes.store = store
@@ -79,25 +75,22 @@ implement {
local function get(tag,n) -- tricky ... only works when defined
local nd = notedata[tag]
+ if not n then
+ n = #nd
+ end
+ nd = nd[n]
if nd then
- n = n or #nd
- nd = nd[n]
- if nd then
- if trace_notes then
- report_notes("getting note %a of %a with listindex %a",n,tag,nd)
- end
- -- is this right?
--- local newdata = lists.collected[nd]
- local newdata = lists.cached[nd]
--- local newdata = lists.tobesaved[nd]
- return newdata
+ if trace_notes then
+ report_notes("getting note %a of %a with listindex %a",n,tag,nd)
end
+ -- is this right?
+ local newdata = lists.cached[nd]
+ return newdata
end
end
local function getn(tag)
- local nd = notedata[tag]
- return nd and #nd or 0
+ return #notedata[tag]
end
notes.get = get
@@ -319,7 +312,6 @@ local function getdeltapage(tag,n)
if li then
local references = li.references
if references then
-
-- local symb = structures.references.collected[""]["symb:"..tag..":"..n]
local symb = structures.references.collected[""]["*"..(references.internal or 0)]
local notepage = references.realpage or 0
diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi
index 43de7e108..f0e7ccbab 100644
--- a/tex/context/base/mkiv/strc-not.mkvi
+++ b/tex/context/base/mkiv/strc-not.mkvi
@@ -236,7 +236,7 @@
\doifelsenextoptionalcs\strc_notations_command_yes\strc_notations_command_nop}
\unexpanded\def\strc_notations_command_nop#title%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]%
\csname\??constructionnotehandler\currentconstructionhandler\endcsname
\strc_constructions_finalize
\normalexpanded{\endgroup\noteparameter\c!next}}
@@ -245,13 +245,13 @@
{\doifelseassignment{#optional}\strc_notations_command_assignment\strc_notations_command_argument[#optional]}
\unexpanded\def\strc_notations_command_assignment[#settings]%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#settings][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#settings]%
\csname\??constructionnotehandler\currentconstructionhandler\endcsname
\strc_constructions_finalize
\normalexpanded{\endgroup\noteparameter\c!next}}
\unexpanded\def\strc_notations_command_argument[#reference]#title%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]%
\csname\??constructionnotehandler\currentconstructionhandler\endcsname
\strc_constructions_finalize
\normalexpanded{\endgroup\noteparameter\c!next}}
@@ -270,13 +270,13 @@
\doifelsenextoptionalcs\strc_pickup_yes\strc_pickup_nop}
\unexpanded\def\strc_notations_start_yes[#reference]#title%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]%
\csname\??constructionnotehandler\currentconstructionhandler\endcsname
\strc_constructions_finalize
\normalexpanded{\endgroup\noteparameter\c!next}}
\unexpanded\def\strc_notations_start_nop#title%
- {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=][]%
+ {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]%
\csname\??constructionnotehandler\currentconstructionhandler\endcsname
\strc_constructions_finalize
\normalexpanded{\endgroup\noteparameter\c!next}}
@@ -1260,7 +1260,7 @@
% as we can have collected notes (e.g. in tables) we need to recover
% \currentdescriptionattribute and \currentdescriptionsynchronize
%
- \reinstateconstructionnumberentry\currentconstructionlistentry % we could store the number in the entry (e.g. needed when local notes in table)
+ \reinstatecachedconstructionnumberentry\currentconstructionlistentry % we could store the number in the entry (e.g. needed when local notes in table)
%
\dontcomplain
%begingroup
diff --git a/tex/context/base/mkiv/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua
index a937a345b..b42727bce 100644
--- a/tex/context/base/mkiv/strc-ref.lua
+++ b/tex/context/base/mkiv/strc-ref.lua
@@ -2059,12 +2059,25 @@ function references.getinternallistreference(n) -- n points into list (todo: reg
return i and destinationattributes[i] or 0
end
+function references.getinternalcachedlistreference(n) -- n points into list (todo: registers)
+ local l = lists.cached[n]
+ local i = l and l.references.internal
+ return i and destinationattributes[i] or 0
+end
+
implement {
name = "getinternallistreference",
actions = { references.getinternallistreference, context },
arguments = "integer"
}
+implement {
+ name = "getinternalcachedlistreference",
+ actions = { references.getinternalcachedlistreference, context },
+ arguments = "integer"
+}
+
+
--
function references.getcurrentmetadata(tag)
diff --git a/tex/context/interface/common/keys-cs.xml b/tex/context/interface/common/keys-cs.xml
index 26222f49d..b69efb667 100644
--- a/tex/context/interface/common/keys-cs.xml
+++ b/tex/context/interface/common/keys-cs.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='foregroundcolor'/>
<cd:constant name='foregroundstyle' value='foregroundstyle'/>
<cd:constant name='format' value='formatovat'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='ramecek'/>
<cd:constant name='framecolor' value='barvaramecku'/>
<cd:constant name='framecorner' value='rohramecku'/>
diff --git a/tex/context/interface/common/keys-de.xml b/tex/context/interface/common/keys-de.xml
index a08e04169..1268ed988 100644
--- a/tex/context/interface/common/keys-de.xml
+++ b/tex/context/interface/common/keys-de.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='foregroundcolor'/>
<cd:constant name='foregroundstyle' value='foregroundstyle'/>
<cd:constant name='format' value='formatieren'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='rahmen'/>
<cd:constant name='framecolor' value='rahmenfarbe'/>
<cd:constant name='framecorner' value='rahmenwinkel'/>
diff --git a/tex/context/interface/common/keys-en.xml b/tex/context/interface/common/keys-en.xml
index e1bf9c021..0d3be2223 100644
--- a/tex/context/interface/common/keys-en.xml
+++ b/tex/context/interface/common/keys-en.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='foregroundcolor'/>
<cd:constant name='foregroundstyle' value='foregroundstyle'/>
<cd:constant name='format' value='format'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='frame'/>
<cd:constant name='framecolor' value='framecolor'/>
<cd:constant name='framecorner' value='framecorner'/>
diff --git a/tex/context/interface/common/keys-fr.xml b/tex/context/interface/common/keys-fr.xml
index 66b75045d..5b764f99a 100644
--- a/tex/context/interface/common/keys-fr.xml
+++ b/tex/context/interface/common/keys-fr.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='couleurpremierplan'/>
<cd:constant name='foregroundstyle' value='stylepremierplan'/>
<cd:constant name='format' value='formatter'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='cadre'/>
<cd:constant name='framecolor' value='couleurcadre'/>
<cd:constant name='framecorner' value='coincadre'/>
diff --git a/tex/context/interface/common/keys-it.xml b/tex/context/interface/common/keys-it.xml
index 6f12a415a..3278d2c58 100644
--- a/tex/context/interface/common/keys-it.xml
+++ b/tex/context/interface/common/keys-it.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='coloreprimopiano'/>
<cd:constant name='foregroundstyle' value='foregroundstyle'/>
<cd:constant name='format' value='format'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='cornice'/>
<cd:constant name='framecolor' value='colorecornice'/>
<cd:constant name='framecorner' value='angolocornice'/>
diff --git a/tex/context/interface/common/keys-nl.xml b/tex/context/interface/common/keys-nl.xml
index e61900d7e..b64176707 100644
--- a/tex/context/interface/common/keys-nl.xml
+++ b/tex/context/interface/common/keys-nl.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='voorgrondkleur'/>
<cd:constant name='foregroundstyle' value='voorgrondletter'/>
<cd:constant name='format' value='formatteer'/>
+ <cd:constant name='fractions' value='breuken'/>
<cd:constant name='frame' value='kader'/>
<cd:constant name='framecolor' value='kaderkleur'/>
<cd:constant name='framecorner' value='kaderhoek'/>
diff --git a/tex/context/interface/common/keys-pe.xml b/tex/context/interface/common/keys-pe.xml
index cd05529b7..feab7b509 100644
--- a/tex/context/interface/common/keys-pe.xml
+++ b/tex/context/interface/common/keys-pe.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='رنگ‌پیش‌زمینه'/>
<cd:constant name='foregroundstyle' value='سبک‌پیش‌زمینه'/>
<cd:constant name='format' value='شمایل'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='قالب'/>
<cd:constant name='framecolor' value='رنگ‌قالب'/>
<cd:constant name='framecorner' value='گوشه‌قالب'/>
diff --git a/tex/context/interface/common/keys-ro.xml b/tex/context/interface/common/keys-ro.xml
index 511ffa767..f801b0be2 100644
--- a/tex/context/interface/common/keys-ro.xml
+++ b/tex/context/interface/common/keys-ro.xml
@@ -809,6 +809,7 @@
<cd:constant name='foregroundcolor' value='foregroundcolor'/>
<cd:constant name='foregroundstyle' value='foregroundstyle'/>
<cd:constant name='format' value='format'/>
+ <cd:constant name='fractions' value='fractions'/>
<cd:constant name='frame' value='frame'/>
<cd:constant name='framecolor' value='culoareframe'/>
<cd:constant name='framecorner' value='coltframe'/>
diff --git a/tex/context/modules/mkiv/m-visual.mkiv b/tex/context/modules/mkiv/m-visual.mkiv
index 36a69a2cb..ee48836ed 100644
--- a/tex/context/modules/mkiv/m-visual.mkiv
+++ b/tex/context/modules/mkiv/m-visual.mkiv
@@ -25,6 +25,7 @@
\definecolor[fakeparindentcolor][blue]
\newif\iffakebaseline \fakebaselinetrue
+\newif\iffaketrigger \faketriggerfalse
\unexpanded\def\fakerule#1%
{\strut
@@ -89,7 +90,8 @@
\def\dofakewords#1%
{\bgroup
\dorecurse{#1}
- {\getrandomcount\scratchcounter{1}{5}%
+ {\iffaketrigger\char\zerocount\fi % so that e.g. line numbering works
+ \getrandomcount\scratchcounter{1}{5}%
\dorecurse\scratchcounter
{\getrandomdimen\scratchdimen{.5em}{1.25em}%
\fakerule\scratchdimen}%
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 3dec0ec46..809b7ff2f 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 : 02/26/16 16:09:21
+-- merge date : 03/01/16 14:03:56
do -- begin closure to overcome local limits and interference