summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv')
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkxl2
-rw-r--r--tex/context/base/mkiv/mult-def.lua4
-rw-r--r--tex/context/base/mkiv/mult-low.lua4
-rw-r--r--tex/context/base/mkiv/mult-prm.lua8
-rw-r--r--tex/context/base/mkiv/node-aux.lua20
-rw-r--r--tex/context/base/mkiv/node-ini.lua12
-rw-r--r--tex/context/base/mkiv/pack-rul.mkxl13
-rw-r--r--tex/context/base/mkiv/spac-ali.mkxl177
-rw-r--r--tex/context/base/mkiv/spac-hor.mkxl4
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin28017 -> 28081 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin255035 -> 254914 bytes
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi6
-rw-r--r--tex/context/base/mkiv/supp-box.lmt1148
-rw-r--r--tex/context/base/mkiv/supp-box.lua23
-rw-r--r--tex/context/base/mkiv/supp-box.mkxl29
-rw-r--r--tex/context/base/mkiv/syst-fnt.mkiv34
-rw-r--r--tex/context/base/mkiv/syst-ini.mkxl5
-rw-r--r--tex/context/base/mkiv/syst-pln.mkiv7
-rw-r--r--tex/context/base/mkiv/trac-vis.lua147
-rw-r--r--tex/context/base/mkiv/typo-lin.lua94
22 files changed, 1514 insertions, 227 deletions
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 670de7fde..81c514628 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2020.08.04 10:23}
+\newcontextversion{2020.08.06 18:55}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index c5b760178..2ff801015 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.08.04 10:23}
+\edef\contextversion{2020.08.06 18:55}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index a70713337..a29b15c14 100644
--- a/tex/context/base/mkiv/context.mkxl
+++ b/tex/context/base/mkiv/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.08.04 10:23}
+\edef\contextversion{2020.08.06 18:55}
%D Kind of special:
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index b15bf8033..ab26b7192 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -9785,6 +9785,10 @@ return {
["pe"]="تصحیح‌خط",
["ro"]="corectielinie",
},
+ ["linedirection"]={
+ ["en"]="linedirection",
+ ["nl"]="regelrichting",
+ },
["lines"]={
["cs"]="radky",
["de"]="zeilen",
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 855084aaa..d7f781663 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -501,5 +501,9 @@ return {
"unsupportedcs",
--
"openout", "closeout", "write", "openin", "closein", "read", "readline", "readfromterminal",
+ --
+ "boxlines", "boxline", "setboxline", "copyboxline", "boxlineht", "boxlinedp",
+ "boxlinewd", "boxlinels", "boxliners", "boxlinelh", "boxlinerh",
+ "boxlinelp", "boxlinerp", "boxlinein",
}
}
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index ce48a6d9e..834cd29a1 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -44,7 +44,6 @@ return {
"parshapelength",
"predisplaydirection",
"protected",
- "readline",
"savinghyphcodes",
"savingvdiscards",
"scantokens",
@@ -59,7 +58,6 @@ return {
"tracinggroups",
"tracingifs",
"tracingnesting",
- "tracingscantokens",
"unexpanded",
"unless",
"widowpenalties",
@@ -380,6 +378,7 @@ return {
"nohrule",
"nokerns",
"noligs",
+ "normalizelinemode",
"nospaces",
"novrule",
"orelse",
@@ -570,7 +569,6 @@ return {
"char",
"chardef",
"cleaders",
- "closein",
"clubpenalty",
"copy",
"count",
@@ -741,7 +739,6 @@ return {
"nullfont",
"number",
"omit",
- "openin",
"or",
"ordlimits",
"outer",
@@ -750,6 +747,7 @@ return {
"over",
"overfullrule",
"overline",
+ "overshoot",
"overwithdelims",
"pagedepth",
"pagefilllstretch",
@@ -760,6 +758,7 @@ return {
"pagestretch",
"pagetotal",
"par",
+ "parfillleftskip",
"parfillskip",
"parindent",
"parshape",
@@ -775,7 +774,6 @@ return {
"prevgraf",
"radical",
"raise",
- "read",
"relax",
"relpenalty",
"right",
diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua
index 4df41d61b..407ebb09c 100644
--- a/tex/context/base/mkiv/node-aux.lua
+++ b/tex/context/base/mkiv/node-aux.lua
@@ -459,14 +459,14 @@ do
nuts.find_node = find_node
- nodes.getnormalizeline = node.getnormalizeline or function() return 0 end
- nodes.setnormalizeline = node.setnormalizeline or function() end
+ -- if CONTEXTLMTXMODE then ... end
nuts.getnormalizedline = direct.getnormalizedline or function(h)
if getid(h) == hlist_code and getsubtype(h) == line_code then
local ls, rs = 0, 0
local lh, rh = 0, 0
- local is, ps = 0, 0
+ local lp, rp = 0, 0
+ local is = 0
local h = getlist(h)
local t = findtail(h)
for n, subtype in nextglue, h do
@@ -475,10 +475,20 @@ do
elseif subtype == lefthangskip_code then lh = getwidth(n)
elseif subtype == righthangskip_code then rh = getwidth(n)
elseif subtype == indentskip_code then is = getwidth(n)
- elseif subtype == parfillskip_code then ps = getwidth(n)
+ elseif subtype == parfillskip_code then rp = getwidth(n)
end
end
- return ls, rs, lh, rh, is, ps, h, t
+ return {
+ leftskip = ls,
+ rightskip = rs,
+ lefthangskip = lh,
+ righthangskip = rh,
+ indent = is,
+ parfillrightskip = rp,
+ parfillleftskip = lp,
+ head = h,
+ tail = t,
+ }
end
end
diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua
index 797047d6b..5c2fc3809 100644
--- a/tex/context/base/mkiv/node-ini.lua
+++ b/tex/context/base/mkiv/node-ini.lua
@@ -178,11 +178,13 @@ gluevalues = allocate(swapped(gluevalues,gluevalues))
literalvalues = allocate(swapped(literalvalues,literalvalues))
if not gluecodes.indentskip then
- gluecodes.indentskip = gluecodes.userskip
- gluecodes.lefthangskip = gluecodes.userskip
- gluecodes.righthangskip = gluecodes.userskip
- gluecodes.correctionskip = gluecodes.userskip
- gluecodes.intermathskip = gluecodes.userskip
+ gluecodes.indentskip = gluecodes.userskip
+ gluecodes.lefthangskip = gluecodes.userskip
+ gluecodes.righthangskip = gluecodes.userskip
+ gluecodes.correctionskip = gluecodes.userskip
+ gluecodes.intermathskip = gluecodes.userskip
+ gluecodes.parfillleftskip = gluecodes.parfillskip
+ gluecodes.parfillrightskip = gluecodes.parfillskip
end
if CONTEXTLMTXMODE > 0 then
diff --git a/tex/context/base/mkiv/pack-rul.mkxl b/tex/context/base/mkiv/pack-rul.mkxl
index 3afd09c79..69050d1fa 100644
--- a/tex/context/base/mkiv/pack-rul.mkxl
+++ b/tex/context/base/mkiv/pack-rul.mkxl
@@ -1457,6 +1457,15 @@
{\profilegivenbox\p_profile\b_framed_normal
\setbox\b_framed_normal\vpack{\unvbox\b_framed_normal}}
+\def\pack_framed_reverse_box
+ {\ifvbox\b_framed_normal
+ \edef\p_linedirection{\framedparameter\c!linedirection}%
+ \ifx\p_linedirection\v!reverse
+ \reversevboxcontent\b_framed_normal
+ \setbox\b_framed_normal\vpack{\unvbox\b_framed_normal}%
+ \fi
+ \fi}
+
\unexpanded\def\pack_framed_finish
{%\pack_framed_stop_orientation % hm, wrong place ! should rotate the result (after reshape) .. moved down
\pack_framed_locator_before\p_framed_location
@@ -1467,6 +1476,9 @@
% \pack_framed_profile_box
% \fi
%\fi
+ \ifempty\p_framed_anchoring\else
+ \pack_framed_reverse_box
+ \fi
\ifx\p_framed_autowidth\v!force
\pack_framed_finish_a
\orelse\ifx\localwidth\v!fit
@@ -1539,6 +1551,7 @@
\fi
%
\ifx\postprocessframebox\relax \else
+ % better: \pushmacro\\postprocessframebox etc
\let\next\postprocessframebox
\let\postprocessframebox\relax % prevent nesting
\next\b_framed_normal
diff --git a/tex/context/base/mkiv/spac-ali.mkxl b/tex/context/base/mkiv/spac-ali.mkxl
index 4bf711aec..ae6aa3736 100644
--- a/tex/context/base/mkiv/spac-ali.mkxl
+++ b/tex/context/base/mkiv/spac-ali.mkxl
@@ -284,131 +284,140 @@
% \s!plus ... slower than inline
\unexpanded\def\spac_align_set_horizontal_none % should also relax \updateraggedskips
- {\raggedstatus\zerocount
+ {\raggedstatus \zerocount
\c_attr_alignstate\attributeunsetvalue
- \leftskip \plusone\leftskip
- \rightskip \plusone\rightskip
- \spaceskip \zeropoint
- \xspaceskip \zeropoint
- \parfillskip\s_zero_plus_one_fil % new
- \setfalse\raggedonelinerstate % now here
- \let\updateraggedskips\relax} % no need for adaption
+ \leftskip \plusone\leftskip
+ \rightskip \plusone\rightskip
+ \spaceskip \zeropoint
+ \xspaceskip \zeropoint
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_one_fil % new
+ \setfalse \raggedonelinerstate % now here
+ \let\updateraggedskips\relax} % no need for adaption
\unexpanded\def\spac_align_set_horizontal_left
- {\setraggedness\spac_align_set_raggedness_left
- \raggedstatus\plusone
+ {\setraggedness \spac_align_set_raggedness_left
+ \raggedstatus \plusone
\c_attr_alignstate\plusone
- \leftskip \plusone\leftskip \s!plus\spac_align_set_raggedness_left
- \rightskip \plusone\rightskip\s!plus\zeropoint
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_zero
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\spac_align_set_raggedness_left
+ \rightskip \plusone\rightskip\s!plus\zeropoint
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_center
- {\setraggedness\spac_align_set_raggedness_middle
- \raggedstatus\plustwo
+ {\setraggedness \spac_align_set_raggedness_middle
+ \raggedstatus \plustwo
\c_attr_alignstate\plustwo
- \leftskip \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
- \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_zero
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
+ \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_right
- {\setraggedness\spac_align_set_raggedness_right
- \raggedstatus\plusthree
+ {\setraggedness \spac_align_set_raggedness_right
+ \raggedstatus \plusthree
\c_attr_alignstate\plusthree
- \leftskip \plusone\leftskip \s!plus\zeropoint
- \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_right
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_one_fil
- %\parindent \parindent
+ \leftskip \plusone\leftskip \s!plus\zeropoint
+ \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_right
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_one_fil
+ %\parindent \parindent
\relax}
\unexpanded\def\spac_align_set_horizontal_very_left
- {\raggedstatus\plusone
+ {\raggedstatus \plusone
\c_attr_alignstate\plusone
- \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount
- \rightskip \plusone\rightskip\s!plus\zeropoint
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_zero
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount
+ \rightskip \plusone\rightskip\s!plus\zeropoint
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_very_center
- {\raggedstatus\plustwo
+ {\raggedstatus \plustwo
\c_attr_alignstate\plustwo
- \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount
- \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_zero
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount
+ \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_very_right
- {\raggedstatus\plusthree
+ {\raggedstatus \plusthree
\c_attr_alignstate\plusthree
- \leftskip \plusone\leftskip \s!plus\zeropoint
- \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_zero
- %\parindent \parindent
+ \leftskip \plusone\leftskip \s!plus\zeropoint
+ \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ %\parindent \parindent
\relax}
\unexpanded\def\spac_align_set_horizontal_wide_center
- {\setraggedness\spac_align_set_raggedness_middle
- \raggedstatus\plustwo
+ {\setraggedness \spac_align_set_raggedness_middle
+ \raggedstatus \plustwo
\c_attr_alignstate\plustwo
- \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount_half
- \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_half
- \spaceskip \v_spac_align_space_amount
- \xspaceskip \v_spac_align_space_amount_x
- \parfillskip\s_zero_plus_zero
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount_half
+ \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_half
+ \spaceskip \v_spac_align_space_amount
+ \xspaceskip \v_spac_align_space_amount_x
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_centered_last_line
- {\raggedstatus\zerocount
+ {\raggedstatus \zerocount
\c_attr_alignstate\attributeunsetvalue
- \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
- \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
- \spaceskip \zeropoint\relax
- \xspaceskip \zeropoint\relax
- \parfillskip\zeropoint\s!plus\v_spac_align_fill_amount_double\relax
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
+ \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
+ \spaceskip \zeropoint\relax
+ \xspaceskip \zeropoint\relax
+ \parfillleftskip \zeropoint
+ \parfillskip \zeropoint\s!plus\v_spac_align_fill_amount_double\relax
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_flushedright_last_line
- {\raggedstatus\zerocount
+ {\raggedstatus \zerocount
\c_attr_alignstate\attributeunsetvalue
- \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
- \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
- \spaceskip \zeropoint\relax
- \xspaceskip \zeropoint\relax
- \parfillskip \zeropoint
- \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
- \parfillleftmode\plustwo % \plusone checks for multiple lines
- \parindent \zeropoint
+ \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
+ \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
+ \spaceskip \zeropoint\relax
+ \xspaceskip \zeropoint\relax
+ \parfillskip \zeropoint
+ \parfillleftskip \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
+ \parindent \zeropoint
\relax}
\unexpanded\def\spac_align_set_horizontal_right_tt % a plain command
{\tttf % brrr
- \raggedstatus\plusthree
+ \raggedstatus \plusthree
\c_attr_alignstate\plusthree
- \leftskip \plusone\leftskip \s!plus\zeropoint\relax
- \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_right\relax
- \spaceskip \zeropoint\relax
- \xspaceskip \zeropoint\relax
- \parfillskip\s_zero_plus_zero
- %\parindent \parindent
+ \leftskip \plusone\leftskip \s!plus\zeropoint\relax
+ \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_right\relax
+ \spaceskip \zeropoint\relax
+ \xspaceskip \zeropoint\relax
+ \parfillleftskip \zeropoint
+ \parfillskip \s_zero_plus_zero
+ %\parindent \parindent
\relax}
\unexpanded\def\spac_align_set_horizontal_extra
diff --git a/tex/context/base/mkiv/spac-hor.mkxl b/tex/context/base/mkiv/spac-hor.mkxl
index da9593188..c9ac0a992 100644
--- a/tex/context/base/mkiv/spac-hor.mkxl
+++ b/tex/context/base/mkiv/spac-hor.mkxl
@@ -17,9 +17,7 @@
\registerctxluafile{spac-hor}{}
-\let \parfillrightskip \parfillskip
-\newskip \parfillleftskip
-\newconstant\parfillleftmode
+\let\parfillrightskip\parfillskip
\let\v_spac_indentation_current\empty % amount/keyword
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index b92bfef95..ec3637371 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 120965f03..3c1db9234 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-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi
index f288b4a72..9cd8ecbf7 100644
--- a/tex/context/base/mkiv/strc-not.mkvi
+++ b/tex/context/base/mkiv/strc-not.mkvi
@@ -2021,4 +2021,10 @@
% a\footnote{\input tufte\par\input ward\relax}
% \stoptext
+%D Bonus:
+
+\appendtoks
+ \setsystemmode\currentnote
+\to \everysynchronizenote
+
\protect \endinput
diff --git a/tex/context/base/mkiv/supp-box.lmt b/tex/context/base/mkiv/supp-box.lmt
new file mode 100644
index 000000000..cee5cf1ad
--- /dev/null
+++ b/tex/context/base/mkiv/supp-box.lmt
@@ -0,0 +1,1148 @@
+if not modules then modules = { } end modules ['supp-box'] = {
+ version = 1.001,
+ optimize = true,
+ comment = "companion to supp-box.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this is preliminary code, use insert_before etc
+
+local report_hyphenation = logs.reporter("languages","hyphenation")
+
+local tonumber, next, type = tonumber, next, type
+
+local lpegmatch = lpeg.match
+
+local tex = tex
+local context = context
+local nodes = nodes
+
+local implement = interfaces.implement
+
+local nodecodes = nodes.nodecodes
+
+local disc_code = nodecodes.disc
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glue_code = nodecodes.glue
+local penalty_code = nodecodes.penalty
+local glyph_code = nodecodes.glyph
+local localpar_code = nodecodes.localpar
+
+local indent_code = nodes.listcodes.indent
+
+local hmode_code = tex.modelevels.horizontal
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
+----- getfield = nuts.getfield
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getboth = nuts.getboth
+local getdisc = nuts.getdisc
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getlist = nuts.getlist
+local getattribute = nuts.getattribute
+local getbox = nuts.getbox
+local getdirection = nuts.getdirection
+local getwidth = nuts.getwidth
+local getheight = nuts.getheight
+local getdepth = nuts.getdepth
+local getwhd = nuts.getwhd
+local takebox = nuts.takebox
+
+----- setfield = nuts.setfield
+local setlink = nuts.setlink
+local setboth = nuts.setboth
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setbox = nuts.setbox
+local setlist = nuts.setlist
+local setdisc = nuts.setdisc
+local setwidth = nuts.setwidth
+local setheight = nuts.setheight
+local setdepth = nuts.setdepth
+local setshift = nuts.setshift
+local setsplit = nuts.setsplit
+local setattrlist = nuts.setattrlist
+local setwhd = nuts.setwhd
+
+local flush_node = nuts.flush_node
+local flush_list = nuts.flush_list
+local copy_node = nuts.copy
+local copy_list = nuts.copy_list
+local find_tail = nuts.tail
+local getdimensions = nuts.dimensions
+local hpack = nuts.hpack
+local vpack = nuts.vpack
+local traverse_id = nuts.traverse_id
+local traverse = nuts.traverse
+local free = nuts.free
+local findtail = nuts.tail
+local reverse = nuts.reverse
+
+local nextdisc = nuts.traversers.disc
+local nextdir = nuts.traversers.dir
+local nexthlist = nuts.traversers.hlist
+
+local listtoutf = nodes.listtoutf
+
+local nodepool = nuts.pool
+local new_penalty = nodepool.penalty
+local new_hlist = nodepool.hlist
+local new_glue = nodepool.glue
+
+local setlistcolor = nodes.tracers.colors.setlist
+
+local texget = tex.get
+local texgetbox = tex.getbox
+local texsetdimen = tex.setdimen
+local texgetnest = tex.getnest
+
+local function hyphenatedlist(head,usecolor)
+ local current = head and tonut(head)
+ while current do
+ local id = getid(current)
+ local prev, next = getboth(current)
+ if id == disc_code then
+ local pre, post, replace = getdisc(current)
+ if not usecolor then
+ -- nothing fancy done
+ elseif pre and post then
+ setlistcolor(pre,"darkmagenta")
+ setlistcolor(post,"darkcyan")
+ elseif pre then
+ setlistcolor(pre,"darkyellow")
+ elseif post then
+ setlistcolor(post,"darkyellow")
+ end
+ if replace then
+ flush_list(replace)
+ end
+ setdisc(current)
+ if pre then
+ setlink(prev,new_penalty(10000),pre)
+ setlink(find_tail(pre),current)
+ end
+ if post then
+ setlink(current,new_penalty(10000),post)
+ setlink(find_tail(post),next)
+ end
+ elseif id == vlist_code or id == hlist_code then
+ hyphenatedlist(getlist(current))
+ end
+ current = next
+ end
+end
+
+implement {
+ name = "hyphenatedlist",
+ arguments = { "integer", "boolean" },
+ actions = function(n,color)
+ local b = texgetbox(n)
+ if b then
+ hyphenatedlist(b.list,color)
+ end
+ end
+}
+
+-- local function hyphenatedhack(head,pre)
+-- pre = tonut(pre)
+-- for n in nextdisc, tonut(head) do
+-- local hyphen = getfield(n,"pre")
+-- if hyphen then
+-- flush_list(hyphen)
+-- end
+-- setfield(n,"pre",copy_list(pre))
+-- end
+-- end
+--
+-- commands.hyphenatedhack = hyphenatedhack
+
+local function checkedlist(list)
+ if type(list) == "number" then
+ return getlist(getbox(tonut(list)))
+ else
+ return tonut(list)
+ end
+end
+
+implement {
+ name = "showhyphenatedinlist",
+ arguments = "integer",
+ actions = function(n)
+ -- we just hyphenate (as we pass a hpack) .. a bit too much casting but ...
+ local l = languages.hyphenators.handler(tonode(checkedlist(n)))
+ report_hyphenation("show: %s",listtoutf(l,false,true))
+ end
+}
+
+local function applytochars(current,doaction,noaction,nested)
+ while current do
+ local id = getid(current)
+ if nested and (id == hlist_code or id == vlist_code) then
+ context.beginhbox()
+ applytochars(getlist(current),doaction,noaction,nested)
+ context.endhbox()
+ elseif id ~= glyph_code then
+ noaction(tonode(copy_node(current)))
+ else
+ doaction(tonode(copy_node(current)))
+ end
+ current = getnext(current)
+ end
+end
+
+local function applytowords(current,doaction,noaction,nested)
+ local start
+ while current do
+ local id = getid(current)
+ if id == glue_code then
+ if start then
+ doaction(tonode(copy_list(start,current)))
+ start = nil
+ end
+ noaction(tonode(copy_node(current)))
+ elseif nested and (id == hlist_code or id == vlist_code) then
+ context.beginhbox()
+ applytowords(getlist(current),doaction,noaction,nested)
+ context.egroup()
+ elseif not start then
+ start = current
+ end
+ current = getnext(current)
+ end
+ if start then
+ doaction(tonode(copy_list(start)))
+ end
+end
+
+local methods = {
+ char = applytochars,
+ characters = applytochars,
+ word = applytowords,
+ words = applytowords,
+}
+
+implement {
+ name = "applytobox",
+ arguments = {
+ {
+ { "box", "integer" },
+ { "command" },
+ { "method" },
+ { "nested", "boolean" },
+ }
+ },
+ actions = function(specification)
+ local list = checkedlist(specification.box)
+ local action = methods[specification.method or "char"]
+ if list and action then
+ action(list,context[specification.command or "ruledhbox"],context,specification.nested)
+ end
+ end
+}
+
+local split_char = lpeg.Ct(lpeg.C(1)^0)
+local split_word = lpeg.tsplitat(lpeg.patterns.space)
+local split_line = lpeg.tsplitat(lpeg.patterns.eol)
+
+local function processsplit(specification)
+ local str = specification.data or ""
+ local command = specification.command or "ruledhbox"
+ local method = specification.method or "word"
+ local spaced = specification.spaced
+ if method == "char" or method == "character" then
+ local words = lpegmatch(split_char,str)
+ for i=1,#words do
+ local word = words[i]
+ if word == " " then
+ if spaced then
+ context.space()
+ end
+ elseif command then
+ context[command](word)
+ else
+ context(word)
+ end
+ end
+ elseif method == "word" then
+ local words = lpegmatch(split_word,str)
+ for i=1,#words do
+ local word = words[i]
+ if spaced and i > 1 then
+ context.space()
+ end
+ if command then
+ context[command](word)
+ else
+ context(word)
+ end
+ end
+ elseif method == "line" then
+ local words = lpegmatch(split_line,str)
+ for i=1,#words do
+ local word = words[i]
+ if spaced and i > 1 then
+ context.par()
+ end
+ if command then
+ context[command](word)
+ else
+ context(word)
+ end
+ end
+ else
+ context(str)
+ end
+end
+
+implement {
+ name = "processsplit",
+ actions = processsplit,
+ arguments = {
+ {
+ { "data" },
+ { "command" },
+ { "method" },
+ { "spaced", "boolean" },
+ }
+ }
+}
+
+local a_vboxtohboxseparator = attributes.private("vboxtohboxseparator")
+
+implement {
+ name = "vboxlisttohbox",
+ arguments = { "integer", "integer", "dimen" },
+ actions = function(original,target,inbetween)
+ local current = getlist(getbox(original))
+ local head = nil
+ local tail = nil
+ while current do
+ local id = getid(current)
+ local next = getnext(current)
+ if id == hlist_code then
+ local list = getlist(current)
+ if head then
+ if inbetween > 0 then
+ local n = new_glue(0,0,inbetween)
+ setlink(tail,n)
+ tail = n
+ end
+ setlink(tail,list)
+ else
+ head = list
+ end
+ tail = find_tail(list)
+ -- remove last separator
+ if getid(tail) == hlist_code and getattribute(tail,a_vboxtohboxseparator) == 1 then
+ local temp = tail
+ local prev = getprev(tail)
+ if next then
+ local list = getlist(tail)
+ setlink(prev,list)
+ setlist(tail)
+ tail = find_tail(list)
+ else
+ tail = prev
+ end
+ flush_node(temp)
+ end
+ -- done
+ setnext(tail)
+ setlist(current)
+ end
+ current = next
+ end
+ local result = new_hlist()
+ setlist(result,head)
+ setbox(target,result)
+ -- setbox(target,new_hlist(head))
+ end
+}
+
+implement {
+ name = "hboxtovbox",
+ arguments = "integer",
+ actions = function(n)
+ local b = getbox(n)
+ local factor = texget("baselineskip",false) / texget("hsize")
+ setdepth(b,0)
+ setheight(b,getwidth(b) * factor)
+ end
+}
+
+implement {
+ name = "boxtostring",
+ arguments = "integer",
+ actions = function(n)
+ context.puretext(nodes.toutf(texgetbox(n).list)) -- helper is defined later
+ end
+}
+
+local function getnaturaldimensions(n)
+ local w = 0
+ local h = 0
+ local d = 0
+ local l = getlist(getbox(n))
+ if l then
+ w, h, d = getdimensions(l)
+ end
+ texsetdimen("lastnaturalboxwd",w)
+ texsetdimen("lastnaturalboxht",h)
+ texsetdimen("lastnaturalboxdp",d)
+ return w, h, d
+end
+
+implement {
+ name = "getnaturaldimensions",
+ arguments = "integer",
+ actions = getnaturaldimensions
+}
+
+implement {
+ name = "naturalwd",
+ arguments = "integer",
+ actions = function(n)
+ getnaturaldimensions(n)
+ context.lastnaturalboxwd(false)
+ end
+}
+
+implement {
+ name = "getnaturalwd",
+ arguments = "integer",
+ actions = function(n)
+ local w = 0
+ local h = 0
+ local d = 0
+ local l = getlist(getbox(n))
+ if l then
+ w, h, d = getdimensions(l)
+ end
+ context("\\dimexpr%i\\scaledpoint\\relax",w)
+ end
+}
+
+local function setboxtonaturalwd(n)
+ local old = takebox(n)
+ local new = hpack(getlist(old))
+ setlist(old,nil)
+ flush_node(old)
+ setbox(n,new)
+end
+
+implement {
+ name = "setnaturalwd",
+ arguments = "integer",
+ actions = setboxtonaturalwd
+}
+
+nodes.setboxtonaturalwd = setboxtonaturalwd
+
+local doifelse = commands.doifelse
+
+do
+
+ local dirvalues = nodes.dirvalues
+ local lefttoright_code = dirvalues.lefttoright
+ local righttoleft_code = dirvalues.righttoleft
+
+ local function firstdirinbox(n)
+ local b = getbox(n)
+ if b then
+ local l = getlist(b)
+ if l then
+ for d in nextdir, l do
+ return getdirection(d)
+ end
+ for h in nexthlist, l do
+ return getdirection(h)
+ end
+ end
+ end
+ return lefttoright_code
+ end
+
+ nodes.firstdirinbox = firstdirinbox
+
+ implement {
+ name = "doifelserighttoleftinbox",
+ arguments = "integer",
+ actions = function(n)
+ doifelse(firstdirinbox(n) == righttoleft_code)
+ end
+ }
+
+end
+
+-- new (handy for mp) .. might move to its own module
+
+do
+
+ local takebox = nuts.takebox
+ local flush_list = nuts.flush_list
+ local copy_list = nuts.copy_list
+ local getwhd = nuts.getwhd
+ local setbox = nuts.setbox
+ local new_hlist = nuts.pool.hlist
+
+ local boxes = { }
+ nodes.boxes = boxes
+ local cache = table.setmetatableindex("table")
+ local report = logs.reporter("boxes","cache")
+ local trace = false
+
+ trackers.register("nodes.boxes",function(v) trace = v end)
+
+ function boxes.save(category,name,b)
+ name = tonumber(name) or name
+ local b = takebox(b)
+ if trace then
+ report("category %a, name %a, %s (%s)",category,name,"save",b and "content" or "empty")
+ end
+ cache[category][name] = b or false
+ end
+
+ function boxes.savenode(category,name,n)
+ name = tonumber(name) or name
+ if trace then
+ report("category %a, name %a, %s (%s)",category,name,"save",n and "content" or "empty")
+ end
+ cache[category][name] = tonut(n) or false
+ end
+
+ function boxes.found(category,name)
+ name = tonumber(name) or name
+ return cache[category][name] and true or false
+ end
+
+ function boxes.direct(category,name,copy)
+ name = tonumber(name) or name
+ local c = cache[category]
+ local b = c[name]
+ if not b then
+ -- do nothing, maybe trace
+ elseif copy then
+ b = copy_list(b)
+ else
+ c[name] = false
+ end
+ if trace then
+ report("category %a, name %a, %s (%s)",category,name,"direct",b and "content" or "empty")
+ end
+ if b then
+ return tonode(b)
+ end
+ end
+
+ function boxes.restore(category,name,box,copy)
+ name = tonumber(name) or name
+ local c = cache[category]
+ local b = takebox(box)
+ if b then
+ flush_list(b)
+ end
+ local b = c[name]
+ if not b then
+ -- do nothing, maybe trace
+ elseif copy then
+ b = copy_list(b)
+ else
+ c[name] = false
+ end
+ if trace then
+ report("category %a, name %a, %s (%s)",category,name,"restore",b and "content" or "empty")
+ end
+ setbox(box,b or nil)
+ end
+
+ function boxes.dimensions(category,name)
+ name = tonumber(name) or name
+ local b = cache[category][name]
+ if b then
+ return getwhd(b)
+ else
+ return 0, 0, 0
+ end
+ end
+
+ function boxes.reset(category,name)
+ name = tonumber(name) or name
+ local c = cache[category]
+ if name and name ~= "" then
+ local b = c[name]
+ if b then
+ flush_list(b)
+ c[name] = false
+ end
+ if trace then
+ report("category %a, name %a, reset",category,name)
+ end
+ else
+ for k, b in next, c do
+ if b then
+ flush_list(b)
+ end
+ end
+ cache[category] = { }
+ if trace then
+ report("category %a, reset",category)
+ end
+ end
+ end
+
+ implement {
+ name = "putboxincache",
+ arguments = { "string", "string", "integer" },
+ actions = boxes.save,
+ }
+
+ implement {
+ name = "getboxfromcache",
+ arguments = { "string", "string", "integer" },
+ actions = boxes.restore,
+ }
+
+ implement {
+ name = "directboxfromcache",
+ arguments = "2 strings",
+ actions = { boxes.direct, context },
+ -- actions = function(category,name) local b = boxes.direct(category,name) if b then context(b) end end,
+ }
+
+ implement {
+ name = "directcopyboxfromcache",
+ arguments = { "string", "string", true },
+ actions = { boxes.direct, context },
+ -- actions = function(category,name) local b = boxes.direct(category,name,true) if b then context(b) end end,
+ }
+
+ implement {
+ name = "copyboxfromcache",
+ arguments = { "string", "string", "integer", true },
+ actions = boxes.restore,
+ }
+
+ implement {
+ name = "doifelseboxincache",
+ arguments = "2 strings",
+ actions = { boxes.found, doifelse },
+ }
+
+ implement {
+ name = "resetboxesincache",
+ arguments = "string",
+ actions = boxes.reset,
+ }
+
+end
+
+implement {
+ name = "lastlinewidth",
+ actions = function()
+ local head = tex.lists.page_head
+ -- list dimensions returns 3 value but we take the first
+ context(head and getdimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0)
+ end
+}
+
+implement {
+ name = "shiftbox",
+ arguments = { "integer", "dimension" },
+ actions = function(n,d)
+ setshift(getbox(n),d)
+ end,
+}
+
+implement { name = "vpackbox", arguments = "integer", actions = function(n) setbox(n,(vpack(takebox(n)))) end }
+implement { name = "hpackbox", arguments = "integer", actions = function(n) setbox(n,(hpack(takebox(n)))) end }
+
+implement { name = "vpackedbox", arguments = "integer", actions = function(n) context(vpack(takebox(n))) end }
+implement { name = "hpackedbox", arguments = "integer", actions = function(n) context(hpack(takebox(n))) end }
+
+implement {
+ name = "scangivendimensions",
+ public = true,
+ protected = true,
+ arguments = {
+ {
+ { "width", "dimension" },
+ { "height", "dimension" },
+ { "depth", "dimension" },
+ },
+ },
+ actions = function(t)
+ texsetdimen("givenwidth", t.width or 0)
+ texsetdimen("givenheight",t.height or 0)
+ texsetdimen("givendepth", t.depth or 0)
+ end,
+}
+
+local function stripglue(list)
+ local done = false
+ local first = list
+ while first do
+ local id = getid(first)
+ if id == glue_code or id == penalty_code then
+ first = getnext(first)
+ else
+ break
+ end
+ end
+ if first and first ~= list then
+ -- we have discardables
+ setsplit(getprev(first),first)
+ flush_list(list)
+ list = first
+ done = true
+ end
+ if list then
+ local tail = findtail(list)
+ local last = tail
+ while last do
+ local id = getid(last)
+ if id == glue_code or id == penalty_code then
+ last = getprev(last)
+ else
+ break
+ end
+ end
+ if last ~= tail then
+ -- we have discardables
+ flush_list(getnext(last))
+ setnext(last)
+ done = true
+ end
+ end
+ return list, done
+end
+
+local function limitate(t) -- don't pack the result !
+ local text = t.text
+ if text then
+ text = tonut(text)
+ else
+ return
+ end
+ local sentinel = t.sentinel
+ if sentinel then
+ sentinel = tonut(sentinel)
+ local s = getlist(sentinel)
+ setlist(sentinel)
+ free(sentinel)
+ sentinel = s
+ else
+ return tonode(text)
+ end
+ local width = getwidth(text)
+ local list = getlist(text)
+ local done = false
+ if t.strip then
+ list, done = stripglue(list)
+ if not list then
+ setlist(text)
+ setwidth(text,0)
+ return text
+ elseif done then
+ width = getdimensions(list)
+ setlist(text,list)
+ end
+ end
+ local left = t.left or 0
+ local right = t.right or 0
+ if left + right < width then
+ local last = nil
+ local first = nil
+ local maxleft = left
+ local maxright = right
+ local swidth = getwidth(sentinel)
+ if maxright > 0 then
+ maxleft = maxleft - swidth/2
+ maxright = maxright - swidth/2
+ else
+ maxleft = maxleft - swidth
+ end
+ for n in traverse_id(glue_code,list) do
+ local width = getdimensions(list,n)
+ if width > maxleft then
+ if not last then
+ last = n
+ end
+ break
+ else
+ last = n
+ end
+ end
+ if last and maxright > 0 then
+ for n in traverse_id(glue_code,last) do
+ local width = getdimensions(n)
+ if width < maxright then
+ first = n
+ break
+ else
+ first = n
+ end
+ end
+ end
+ if last then
+ local rest = getnext(last)
+ if rest then
+ local tail = findtail(sentinel)
+ if first and getid(first) == glue_code and getid(tail) == glue_code then
+ setwidth(first,0)
+ end
+ if last and getid(last) == glue_code and getid(sentinel) == glue_code then
+ setwidth(last,0)
+ end
+ if first and first ~= last then
+ local prev = getprev(first)
+ if prev then
+ setnext(prev)
+ end
+ setlink(tail,first)
+ end
+ setlink(last,sentinel)
+ setprev(rest)
+ flush_list(rest)
+ end
+ end
+ end
+ setlist(text)
+ free(text)
+ return tonode(list)
+end
+
+implement {
+ name = "limitated",
+ public = true,
+ protected = true,
+ arguments = {
+ {
+ { "left", "dimension" },
+ { "right", "dimension" },
+ { "text", "hbox" },
+ { "sentinel", "hbox" },
+ { "strip", "boolean" },
+ }
+ },
+ actions = function(t)
+ context.dontleavehmode()
+ context(limitate(t))
+ end,
+}
+
+-- only in lmtx:
+
+implement {
+ name = "widthuptohere",
+ public = true,
+ protected = true,
+ value = true,
+ actions = function()
+ local n = texgetnest()
+ local w = 0
+ if n.mode == hmode_code then
+ local h = hpack(getnext(tonut(n.head)))
+ w = getwidth(h)
+ setlist(h)
+ free(h)
+ end
+ return tokens.values.dimension, w
+ end,
+}
+
+implement {
+ name = "doifelseindented",
+ public = true,
+ protected = true,
+ actions = function()
+ local n = texgetnest()
+ local b = false
+ if n.mode == hmode_code then
+ n = tonut(n.head)
+ while n do
+ n = getnext(n)
+ if n then
+ local id = getid(n)
+ if id == hlist_code then
+ if getsubtype(n) == indent_code then
+ b = getwidth(n) > 0
+ break
+ end
+ elseif id ~= localpar_code then
+ break
+ end
+ end
+ end
+ end
+ commands.doifelse(b)
+ end,
+}
+
+implement {
+ name = "noflinesinbox",
+ public = true,
+ protected = false,
+ arguments = "integer",
+ actions = function(n)
+ local c = 0
+ local b = getbox(n)
+ if b then
+ b = getlist(b)
+ if b then
+ for n, id in traverse(b) do
+ if id == hlist_code or id == vlist_code then
+ c = c + 1
+ end
+ end
+ end
+ end
+ context(c)
+ end,
+}
+
+do
+
+ local takebox = tex.takebox
+
+ implement {
+ name = "thebox",
+ public = true,
+ arguments = "integer",
+ actions = function(n)
+ context(takebox(n))
+ end
+ }
+
+end
+
+-- only in lmtx
+
+implement {
+ name = "reversevboxcontent",
+ protected = true,
+ public = true,
+ arguments = "integer",
+ actions = function(n)
+ local b = getbox(n)
+ local l = b and getid(b) == vlist_code and getlist(b)
+ if l and getnext(l) then
+ setlist(b,reverse(l)) -- no re-vpack here!
+ end
+ end
+}
+
+-- only in lmtx
+
+do
+
+ local scaninteger = tokens.scanners.integer
+ local scanbox = tokens.scanners.box
+ local scandimen = tokens.scanners.dimen
+
+ local setsubtype = nuts.setsubtype
+ local removenode = nuts.remove
+ local getnormalizedline = nuts.getnormalizedline -- we can optimize this
+
+ local line_code = nodes.listcodes.line
+ local unknown_code = nodes.listcodes.unknown
+
+ local values = tokens.values
+ local dimension_value = values.dimension
+ local cardinal_value = values.cardinal
+ local list_value = values.list
+
+ local function boxlinecount(what)
+ local box = scaninteger()
+ local list = getbox(box)
+ local line = 0
+ if list then
+ list = getlist(list)
+ if list then
+ for n, subtype in nexthlist, list do
+ if subtype == line_code then
+ line = line + 1
+ end
+ end
+ end
+ end
+ if what == "value" then
+ return cardinal_value, line
+ end
+ end
+
+ local function findline()
+ local n = scaninteger()
+ local line = scaninteger()
+ local box = getbox(n)
+ if box then
+ local list = getlist(box)
+ if list then
+ for n, subtype in nexthlist, list do
+ if subtype == line_code then
+ if line == 1 then
+ return n, list, box
+ else
+ line = line - 1
+ end
+ end
+ end
+ end
+ end
+ end
+
+ local function getline(found,list,box,value)
+ local p, n = getboth(found)
+ local temp = new_hlist()
+ setsubtype(temp,line_code)
+ setwhd(temp,getwhd(found))
+ if found == list then
+ setlink(temp,n)
+ setlist(box,temp)
+ else
+ setlink(p,temp,n)
+ end
+ setboth(found)
+ setsubtype(found, unknown_code)
+ found = tonode(found)
+ if value then
+ return list_value, found
+ else
+ context(found)
+ end
+ end
+
+ local function copyline(found,list,box,value)
+ local p, n = getboth(found)
+ found = copy_list(found)
+ setsubtype(found, unknown_code)
+ found = tonode(found)
+ if value then
+ return list_value, found
+ else
+ context(found)
+ end
+ end
+
+ local function setline(found,list,box)
+ local p, n = getboth(found)
+ local temp = scanbox()
+ if temp then
+ temp = tonut(temp)
+ if found == list then
+ setlink(temp,n)
+ setlist(box,temp)
+ else
+ setlink(p,temp,n)
+ end
+ flush_node(found)
+ end
+ end
+
+ local getters = {
+ ["wd"] = function(found) return dimension_value, getwidth (found) end,
+ ["ht"] = function(found) return dimension_value, getheight(found) end,
+ ["dp"] = function(found) return dimension_value, getdepth (found) end,
+ ["ls"] = function(found) return dimension_value, getnormalizedline(found).leftskip end,
+ ["rs"] = function(found) return dimension_value, getnormalizedline(found).rightskip end,
+ ["lh"] = function(found) return dimension_value, getnormalizedline(found).lefthangskip end,
+ ["rh"] = function(found) return dimension_value, getnormalizedline(found).righthangskip end,
+ ["lp"] = function(found) return dimension_value, getnormalizedline(found).parfillleftskip end,
+ ["rp"] = function(found) return dimension_value, getnormalizedline(found).parfillrightskip end,
+ ["in"] = function(found) return dimension_value, getnormalizedline(found).indent end,
+ ["get"] = function(found,list,box) return getline(found,list,box,true) end,
+ }
+
+ local setters = {
+ ["wd"] = function(found) return setwidth (found,scandimen(false,false,true)) end,
+ ["ht"] = function(found) return setheight(found,scandimen(false,false,true)) end,
+ ["dp"] = function(found) return setdepth (found,scandimen(false,false,true)) end,
+ ["set"] = setline,
+ ["get"] = getline,
+ ["copy"] = copyline,
+ }
+
+ local report = logs.reporter("tex", "boxlines")
+
+ local function boxline(name,what)
+ local found, list, box = findline()
+ if not found then
+ report("invalid box line specification, pass box number and line number")
+ elseif what == "value" then
+ local getter = getters[name]
+ if getter then
+ return getter(found,list,box)
+ end
+ else
+ local setter = setters[name]
+ if setter then
+ return setter(found,list,box)
+ end
+ end
+ end
+
+ implement {
+ name = "boxlines", public = true, protected = true, value = true,
+ actions = boxlinecount,
+ }
+ implement {
+ name = "boxline", public = true, protected = true, value = true,
+ actions = function(what) return boxline("get",what) end,
+ }
+ implement {
+ name = "setboxline", public = true, protected = true, value = true,
+ actions = function(what) return boxline("set",what) end,
+ }
+ implement {
+ name = "copyboxline", public = true, protected = true, value = true,
+ actions = function(what) return boxline("copy",what) end,
+ }
+ implement {
+ name = "boxlineht", public = true, protected = true, value = true,
+ actions = function(what) return boxline("ht",what) end,
+ }
+ implement {
+ name = "boxlinedp", public = true, protected = true, value = true,
+ actions = function(what) return boxline("dp",what) end,
+ }
+ implement {
+ name = "boxlinewd", public = true, protected = true, value = true,
+ actions = function(what) return boxline("wd",what) end,
+ }
+ implement {
+ name = "boxlinels", public = true, protected = true, value = true,
+ actions = function(what) return boxline("ls",what) end,
+ }
+ implement {
+ name = "boxliners", public = true, protected = true, value = true,
+ actions = function(what) return boxline("rs",what) end,
+ }
+ implement {
+ name = "boxlinelh", public = true, protected = true, value = true,
+ actions = function(what) return boxline("lh",what) end,
+ }
+ implement {
+ name = "boxlinerh", public = true, protected = true, value = true,
+ actions = function(what) return boxline("rh",what) end,
+ }
+ implement {
+ name = "boxlinelp", public = true, protected = true, value = true,
+ actions = function(what) return boxline("lp",what) end,
+ }
+ implement {
+ name = "boxlinerp", public = true, protected = true, value = true,
+ actions = function(what) return boxline("rp",what) end,
+ }
+ implement {
+ name = "boxlinein", public = true, protected = true, value = true,
+ actions = function(what) return boxline("in",what) end,
+ }
+
+end
diff --git a/tex/context/base/mkiv/supp-box.lua b/tex/context/base/mkiv/supp-box.lua
index 6517e70f5..d26742a5b 100644
--- a/tex/context/base/mkiv/supp-box.lua
+++ b/tex/context/base/mkiv/supp-box.lua
@@ -51,6 +51,7 @@ local getattribute = nuts.getattribute
local getbox = nuts.getbox
local getdirection = nuts.getdirection
local getwidth = nuts.getwidth
+local getwhd = nuts.getwhd
local takebox = nuts.takebox
----- setfield = nuts.setfield
@@ -835,28 +836,6 @@ implement {
end,
}
-if CONTEXTLMTXMODE > 0 then
-
- implement {
- name = "widthuptohere",
- public = true,
- protected = true,
- value = true,
- actions = function()
- local n = texgetnest()
- local w = 0
- if n.mode == hmode_code then
- local h = hpack(getnext(tonut(n.head)))
- w = getwidth(h)
- setlist(h)
- free(h)
- end
- return tokens.values.dimension, w
- end,
- }
-
-end
-
implement {
name = "doifelseindented",
public = true,
diff --git a/tex/context/base/mkiv/supp-box.mkxl b/tex/context/base/mkiv/supp-box.mkxl
index 35d8da1b6..90bc82667 100644
--- a/tex/context/base/mkiv/supp-box.mkxl
+++ b/tex/context/base/mkiv/supp-box.mkxl
@@ -15,7 +15,7 @@
\unprotect
-\registerctxluafile{supp-box}{optimize}
+\registerctxluafile{supp-box}{autosuffix,optimize}
%D And some dimensions:
@@ -2637,10 +2637,10 @@
\fi
\egroup}
-% makes sense but too much log for overfull boxes:
-%
-% \showboxbreadth\maxdimen
-% \showboxdepth \maxdimen
+% Why not ...
+
+\showboxbreadth\plusthousand
+\showboxdepth \plusthousand
%D Moved from cont-new:
%D
@@ -2785,6 +2785,25 @@
%D
%D \typebuffer \blank \getbuffer \blank
+%D Implemented elsewhere:
+
+%D \starttyping
+%D \boxlines <box>
+%D \boxline <box> <line>
+%D \copyboxline <box> <line>
+%D \setboxline <box> <line>
+%D \boxlineht <box> <line> [<dimen>]
+%D \boxlinedp <box> <line> [<dimen>]
+%D \boxlinewd <box> <line> [<dimen>]
+%D \boxlinels <box> <line>
+%D \boxliners <box> <line>
+%D \boxlinelh <box> <line>
+%D \boxlinerh <box> <line>
+%D \boxlinelp <box> <line>
+%D \boxlinerp <box> <line>
+%D \boxlinein <box> <line>
+%D \stoptyping
+
\protect \endinput
% a bit of test code:
diff --git a/tex/context/base/mkiv/syst-fnt.mkiv b/tex/context/base/mkiv/syst-fnt.mkiv
index 764e486d2..83b57f5f7 100644
--- a/tex/context/base/mkiv/syst-fnt.mkiv
+++ b/tex/context/base/mkiv/syst-fnt.mkiv
@@ -15,23 +15,23 @@
\unprotect
-\def\fontslantperpoint {\fontdimen\plusone }
-\def\fontinterwordspace {\fontdimen\plustwo }
-\def\fontinterwordstretch{\fontdimen\plusthree}
-\def\fontinterwordshrink {\fontdimen\plusfour }
-\def\fontexheight {\fontdimen\plusfive }
-\def\fontemwidth {\fontdimen\plussix }
-\def\fontextraspace {\fontdimen\plusseven}
-
-\def\slantperpoint {\fontdimen\plusone \font}
-\def\interwordspace {\fontdimen\plustwo \font}
-\def\interwordstretch {\fontdimen\plusthree\font}
-\def\interwordshrink {\fontdimen\plusfour \font}
-\def\exheight {\fontdimen\plusfive \font}
-\def\emwidth {\fontdimen\plussix \font}
-\def\extraspace {\fontdimen\plusseven\font}
-
-\def\mathaxisheight {\Umathaxis} % takes style
+\protected\def\fontslantperpoint {\fontdimen\plusone }
+\protected\def\fontinterwordspace {\fontdimen\plustwo }
+\protected\def\fontinterwordstretch{\fontdimen\plusthree}
+\protected\def\fontinterwordshrink {\fontdimen\plusfour }
+\protected\def\fontexheight {\fontdimen\plusfive }
+\protected\def\fontemwidth {\fontdimen\plussix }
+\protected\def\fontextraspace {\fontdimen\plusseven}
+
+\protected\def\slantperpoint {\fontdimen\plusone \font}
+\protected\def\interwordspace {\fontdimen\plustwo \font}
+\protected\def\interwordstretch {\fontdimen\plusthree\font}
+\protected\def\interwordshrink {\fontdimen\plusfour \font}
+\protected\def\exheight {\fontdimen\plusfive \font}
+\protected\def\emwidth {\fontdimen\plussix \font}
+\protected\def\extraspace {\fontdimen\plusseven\font}
+
+\let \mathaxisheight \Umathaxis % takes style
\def\currentspaceskip {\interwordspace\s!plus\interwordstretch\s!minus\interwordshrink\relax}
diff --git a/tex/context/base/mkiv/syst-ini.mkxl b/tex/context/base/mkiv/syst-ini.mkxl
index 2fc4a0259..46daa66ca 100644
--- a/tex/context/base/mkiv/syst-ini.mkxl
+++ b/tex/context/base/mkiv/syst-ini.mkxl
@@ -654,9 +654,8 @@
\tracingifs \plusone
\tracingnesting \plustwo
\tracingassigns \plustwo
- \tracingfonts
- \showboxbreadth \maxdimen
- \showboxdepth \maxdimen}
+ \showboxbreadth \maxcount
+ \showboxdepth \maxcount}
\protected\def\loggingall
{\tracingall
diff --git a/tex/context/base/mkiv/syst-pln.mkiv b/tex/context/base/mkiv/syst-pln.mkiv
index 248113120..38ec9c4c1 100644
--- a/tex/context/base/mkiv/syst-pln.mkiv
+++ b/tex/context/base/mkiv/syst-pln.mkiv
@@ -13,10 +13,9 @@
\unprotect
-%D This module set a couple of variables to the plain \TEX\
-%D values. Later they might be overloaded. There is not much
-%D difference between \MKII\ and \MKIV\ but at some point they
-%D might diverge.
+%D This module set a couple of variables to the plain \TEX\ values. Later they might
+%D be overloaded. There is not much difference between \MKII\ and \MKIV\ but at some
+%D point they might diverge.
%D Build||in numeric variables.
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index febb32f75..c676f4dd7 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -63,6 +63,7 @@ local getwidth = nuts.getwidth
local getdepth = nuts.getdepth
local getshift = nuts.getshift
local getexpansion = nuts.getexpansion
+local getdirection = nuts.getdirection
local isglyph = nuts.isglyph
@@ -77,8 +78,6 @@ local apply_to_nodes = nuts.apply
local find_tail = nuts.tail
local effectiveglue = nuts.effective_glue
-local nextnode = nuts.traversers.node
-
local hpack_string = nuts.typesetters.tohpack
local texgetattribute = tex.getattribute
@@ -167,10 +166,13 @@ local modes = {
depth = 0x080000,
marginkern = 0x100000,
mathlistkern = 0x200000,
+ dir = 0x400000,
+ localpar = 0x800000,
}
local usedfont, exheight, emwidth
-local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_marginkern, l_mathlistkern, l_italic, l_origin, l_discretionary, l_expansion, l_line, l_space, l_depth
+local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_marginkern, l_mathlistkern, l_italic, l_origin, l_discretionary, l_expansion, l_line, l_space, l_depth,
+ l_dir, l_whatsit
local enabled = false
local layers = { }
@@ -181,6 +183,7 @@ local preset_makeup = preset_boxes
local preset_all = preset_makeup
+ modes.fontkern + modes.marginkern + modes.mathlistkern
+ modes.whatsit + modes.glyph + modes.user + modes.math
+ + modes.dir + modes.whatsit
function visualizers.setfont(id)
usedfont = id or current_font()
@@ -232,6 +235,8 @@ local function initialize()
l_line = layers.line
l_space = layers.space
l_depth = layers.depth
+ l_dir = layers.dir
+ l_localpar = layers.localpar
--
if not userrule then
userrule = nuts.rules.userrule
@@ -609,9 +614,7 @@ local whatsit do
if info then
-- print("hit whatsit")
else
- local tag = whatsitcodes[what]
- -- maybe different text colors per tag
- info = sometext(formatters["W:%s"](tag and tags[tag] or what),usedfont,nil,c_white)
+ info = sometext(formatters["W:%s"](what),usedfont,nil,c_white)
setattr(info,a_layer,l_whatsit)
w_cache[what] = info
end
@@ -621,6 +624,59 @@ local whatsit do
end
+local dir, localpar do
+
+ local dircodes = nodes.dircodes
+ local dirvalues = nodes.dirvalues
+
+ local cancel_code = dircodes.cancel
+ local l2r_code = dirvalues.l2r
+ local r2l_code = dirvalues.r2l
+
+ local d_cache = caches["dir"]
+
+ local tags = {
+ l2r = "L2R",
+ r2l = "R2L",
+ cancel = "CAN",
+ par = "PAR",
+ }
+
+ localpar = function(head,current)
+ local what = "par" -- getsubtype(current)
+ local info = d_cache[what]
+ if info then
+ -- print("hit localpar")
+ else
+ info = sometext(formatters["L:%s"](what),usedfont,nil,c_white)
+ setattr(info,a_layer,l_dir)
+ d_cache[what] = info
+ end
+ return head, current
+ end
+
+ dir = function(head,current)
+ local what = getsubtype(current)
+ if what == cancelcode then
+ what = "cancel"
+ elseif getdirection(current) == r2l_code then
+ what = "r2l"
+ else
+ what = "l2r"
+ end
+ local info = d_cache[what]
+ if info then
+ -- print("hit dir")
+ else
+ info = sometext(formatters["D:%s"](what),usedfont,nil,c_white)
+ setattr(info,a_layer,l_dir)
+ d_cache[what] = info
+ end
+ return head, current
+ end
+
+end
+
local user do
local u_cache = caches["user"]
@@ -870,21 +926,23 @@ end
local ruledglue do
- local gluecodes = nodes.gluecodes
- local leadercodes = nodes.gluecodes
+ local gluecodes = nodes.gluecodes
+ local leadercodes = nodes.gluecodes
- local userskip_code = gluecodes.userskip
- local spaceskip_code = gluecodes.spaceskip
- local xspaceskip_code = gluecodes.xspaceskip
- local zerospaceskip_code = gluecodes.zerospaceskip or gluecodes.userskip
- -- local keepskip_code = gluecodes.keepskip or gluecodes.userskip
- local leftskip_code = gluecodes.leftskip
- local rightskip_code = gluecodes.rightskip
- local parfillskip_code = gluecodes.parfillskip
- local indentskip_code = gluecodes.indentskip
- local correctionskip_code = gluecodes.correctionskip
+ local userskip_code = gluecodes.userskip
+ local spaceskip_code = gluecodes.spaceskip
+ local xspaceskip_code = gluecodes.xspaceskip
+ local zerospaceskip_code = gluecodes.zerospaceskip or gluecodes.userskip
+ -- local keepskip_code = gluecodes.keepskip or gluecodes.userskip
+ local leftskip_code = gluecodes.leftskip
+ local rightskip_code = gluecodes.rightskip
+ local parfillskip_code = gluecodes.parfillskip
+ local parfillleftskip_code = gluecodes.parfillleftskip or parfillskip_code
+ local parfillrightskip_code = gluecodes.parfillrightskip or parfillskip_code
+ local indentskip_code = gluecodes.indentskip
+ local correctionskip_code = gluecodes.correctionskip
- local cleaders_code = leadercodes.cleaders
+ local cleaders_code = leadercodes.cleaders
local g_cache_v = caches["vglue"]
local g_cache_h = caches["hglue"]
@@ -920,7 +978,9 @@ local ruledglue do
[spaceskip_code] = "SP",
[xspaceskip_code] = "XS",
[zerospaceskip_code] = "ZS",
- [parfillskip_code] = "PF",
+ [parfillskip_code] = "PR",
+ [parfillleftskip_code] = "PL",
+ [parfillrightskip_code] = "PR",
[indentskip_code] = "IN",
[correctionskip_code] = "CS",
}
@@ -939,7 +999,7 @@ local ruledglue do
info = sometext(amount,l_glue,c_space)
elseif subtype == leftskip_code or subtype == rightskip_code then
info = sometext(amount,l_glue,c_skip_a)
- elseif subtype == parfillskip_code or subtype == indentskip_code or subtype == correctionskip_code then
+ elseif subtype == parfillskip_code or subtype == parfillleftskip_code or subtype == parfillrightskip_code or subtype == indentskip_code or subtype == correctionskip_code then
info = sometext(amount,l_glue,c_indent)
elseif subtype == userskip_code then
if width > 0 then
@@ -1179,18 +1239,20 @@ end
do
- local disc_code = nodecodes.disc
- local kern_code = nodecodes.kern
- local glyph_code = nodecodes.glyph
- local glue_code = nodecodes.glue
- local penalty_code = nodecodes.penalty
- local whatsit_code = nodecodes.whatsit
- local user_code = nodecodes.user
- local math_code = nodecodes.math
- local hlist_code = nodecodes.hlist
- local vlist_code = nodecodes.vlist
- local marginkern_code = nodecodes.marginkern
- local mathlistkern_code = nodecodes.mathlistkern
+ local disc_code = nodecodes.disc
+ local kern_code = nodecodes.kern
+ local glyph_code = nodecodes.glyph
+ local glue_code = nodecodes.glue
+ local penalty_code = nodecodes.penalty
+ local whatsit_code = nodecodes.whatsit
+ local user_code = nodecodes.user
+ local math_code = nodecodes.math
+ local hlist_code = nodecodes.hlist
+ local vlist_code = nodecodes.vlist
+ local marginkern_code = nodecodes.marginkern
+ local mathlistkern_code = nodecodes.mathlistkern
+ local dir_code = nodecodes.dir
+ local localpar_code = nodecodes.localpar
local kerncodes = nodes.kerncodes
local fontkern_code = kerncodes.fontkern
@@ -1200,8 +1262,8 @@ do
local mathlistkern_code = kerncodes.mathlistkern
----- userkern_code = kerncodes.userkern
- local listcodes = nodes.listcodes
- local linelist_code = listcodes.line
+ local listcodes = nodes.listcodes
+ local linelist_code = listcodes.line
local cache
@@ -1226,6 +1288,8 @@ do
local trace_line = false
local trace_space = false
local trace_depth = false
+ local trace_dir = false
+ local trace_localpar = false
local current = head
local previous = nil
local attr = unsetvalue
@@ -1269,6 +1333,8 @@ do
trace_depth = false
trace_marginkern = false
trace_mathlistkern = false
+ trace_dir = false
+ trace_localpar = false
if id == kern_code then
goto kern
else
@@ -1298,6 +1364,8 @@ do
trace_depth = band(a,0x080000) ~= 0
trace_marginkern = band(a,0x100000) ~= 0
trace_mathlistkern = band(a,0x200000) ~= 0
+ trace_dir = band(a,0x400000) ~= 0
+ trace_whatsit = band(a,0x800000) ~= 0
end
elseif a == unsetvalue then
goto list
@@ -1359,6 +1427,14 @@ do
if trace_kern then
head, current = ruledkern(head,current,vertical,true)
end
+ elseif id == dir_code then
+ if trace_dir then
+ head, current = dir(head,current)
+ end
+ elseif id == localpar_code then
+ if trace_localpar then
+ head, current = localpar(head,current)
+ end
end
goto next
::kern::
@@ -1470,6 +1546,7 @@ do
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+ local nextnode = nuts.traversers.node
local last = nil
local used = nil
diff --git a/tex/context/base/mkiv/typo-lin.lua b/tex/context/base/mkiv/typo-lin.lua
index 1d523a200..95f9c13fa 100644
--- a/tex/context/base/mkiv/typo-lin.lua
+++ b/tex/context/base/mkiv/typo-lin.lua
@@ -236,53 +236,75 @@ function paragraphs.checkline(n)
return getprop(n,"line") or normalize(n,true)
end
-function paragraphs.normalize(head,islocal)
- if texgetcount("pagebodymode") > 0 then
- -- can be an option, maybe we need a proper state in lua itself ... is this check still needed?
- return head, false
+-- do we still need this:
+
+if CONTEXTLMTXMODE > 0 then
+
+ function paragraphs.normalize(head,islocal)
+ if texgetcount("pagebodymode") > 0 then
+ -- can be an option, maybe we need a proper state in lua itself ... is this check still needed?
+ return head, false
+ end
+ -- normalizer : todo, get the data, no need to normalize
+ for line, subtype in nexthlist, head do
+ if subtype == linelist_code and not getprop(line,"line") then
+ normalize(line)
+ end
+ end
+ return head, true -- true is obsolete
end
- -- this can become a separate handler but it makes sense to integrate it here
- local mode = texgetcount("parfillleftmode")
- if mode > 0 then
- local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip")
- if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then
- local last = nil -- a nut
- local done = mode == 2 -- false
- for line, subtype in nexthlist, head do
- if subtype == linelist_code and not getprop(line,"line") then
- if done then
- last = line
- else
- done = true
+
+else
+
+ function paragraphs.normalize(head,islocal)
+ if texgetcount("pagebodymode") > 0 then
+ -- can be an option, maybe we need a proper state in lua itself ... is this check still needed?
+ return head, false
+ end
+ -- this can become a separate handler but it makes sense to integrate it here
+ local mode = texgetcount("parfillleftmode")
+ if mode > 0 then
+ local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip")
+ if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then
+ local last = nil -- a nut
+ local done = mode == 2 -- false
+ for line, subtype in nexthlist, head do
+ if subtype == linelist_code and not getprop(line,"line") then
+ if done then
+ last = line
+ else
+ done = true
+ end
end
end
- end
- if last then -- only if we have more than one line
- local head = getlist(last)
- local current = head
- if current then
- if getid(current) == glue_code and getsubtype(current,leftskip_code) then
- current = getnext(current)
- end
+ if last then -- only if we have more than one line
+ local head = getlist(last)
+ local current = head
if current then
- head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink))
- if head == current then
- setlist(last,head)
+ if getid(current) == glue_code and getsubtype(current,leftskip_code) then
+ current = getnext(current)
+ end
+ if current then
+ head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink))
+ if head == current then
+ setlist(last,head)
+ end
+ -- can be a 'rehpack(h )'
+ rehpack(last)
end
- -- can be a 'rehpack(h )'
- rehpack(last)
end
end
end
end
- end
- -- normalizer
- for line, subtype in nexthlist, head do
- if subtype == linelist_code and not getprop(line,"line") then
- normalize(line)
+ -- normalizer
+ for line, subtype in nexthlist, head do
+ if subtype == linelist_code and not getprop(line,"line") then
+ normalize(line)
+ end
end
+ return head, true -- true is obsolete
end
- return head, true -- true is obsolete
+
end
-- print(nodes.idstostring(head))