summaryrefslogtreecommitdiff
path: root/tex/context
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/attr-ini.mkiv4
-rw-r--r--tex/context/base/mkiv/back-exp.lua23
-rw-r--r--tex/context/base/mkiv/buff-ver.mkiv8
-rw-r--r--tex/context/base/mkiv/buff-ver.mkxl8
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua16
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv3
-rw-r--r--tex/context/base/mkiv/context.mkxl3
-rw-r--r--tex/context/base/mkiv/driv-shp.lua72
-rw-r--r--tex/context/base/mkiv/lxml-ini.mkiv2
-rw-r--r--tex/context/base/mkiv/mult-ini.mkiv4
-rw-r--r--tex/context/base/mkiv/mult-prm.lua1
-rw-r--r--tex/context/base/mkiv/node-aux.lua230
-rw-r--r--tex/context/base/mkiv/node-cmp.lua11
-rw-r--r--tex/context/base/mkiv/node-fin.lua189
-rw-r--r--tex/context/base/mkiv/node-met.lua230
-rw-r--r--tex/context/base/mkiv/node-shp.lua108
-rw-r--r--tex/context/base/mkiv/spac-lin.mkiv54
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin27742 -> 27724 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin254471 -> 254455 bytes
-rw-r--r--tex/context/base/mkiv/strc-sec.mkiv21
-rw-r--r--tex/context/base/mkiv/syst-aux.lua22
-rw-r--r--tex/context/base/mkiv/syst-aux.mkiv6
-rw-r--r--tex/context/base/mkiv/task-ini.lua2
-rw-r--r--tex/context/base/mkiv/toks-ini.lua2
-rw-r--r--tex/context/base/mkiv/typo-plc.mkiv39
28 files changed, 391 insertions, 673 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 4433ce6fe..92f8f4cad 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2020.06.29 19:42}
+\newcontextversion{2020.07.02 16:03}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 3b40a3155..c8eddc1ab 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.06.29 19:42}
+\edef\contextversion{2020.07.02 16:03}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/attr-ini.mkiv b/tex/context/base/mkiv/attr-ini.mkiv
index 9eb1da69f..71c6478f8 100644
--- a/tex/context/base/mkiv/attr-ini.mkiv
+++ b/tex/context/base/mkiv/attr-ini.mkiv
@@ -139,8 +139,8 @@
%definesystemattribute [state] % nomath
\definesystemattribute [color] [public] % global
\definesystemattribute [colormodel] [public,global]
-% \definesystemattribute [skip]
-% \definesystemattribute [penalty]
+%definesystemattribute [skip]
+%definesystemattribute [penalty]
\definesystemattribute [transparency] [public]
\definesystemattribute [reference] [public]
\definesystemattribute [destination] [public]
diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua
index da2301db7..f247e4e27 100644
--- a/tex/context/base/mkiv/back-exp.lua
+++ b/tex/context/base/mkiv/back-exp.lua
@@ -3175,17 +3175,6 @@ local collectresults do -- too many locals otherwise
end
end
end
- elseif id == disc_code then -- probably too late
- local pre, post, replace = getdisc(n)
- if keephyphens then
- if pre and not getnext(pre) and isglyph(pre) == 0xAD then -- hyphencode then
- nofcurrentcontent = nofcurrentcontent + 1
- currentcontent[nofcurrentcontent] = hyphen
- end
- end
- if replace then
- collectresults(replace,nil)
- end
elseif id == glue_code then
-- we need to distinguish between hskips and vskips
local ca = getattr(n,a_characters)
@@ -3403,6 +3392,18 @@ end
end
elseif not localparagraph and id == localpar_code and start_of_par(n) then
localparagraph = getattr(n,a_taggedpar)
+ elseif id == disc_code then
+ -- very unlikely because we stripped them
+ local pre, post, replace = getdisc(n)
+ if keephyphens then
+ if pre and not getnext(pre) and isglyph(pre) == 0xAD then -- hyphencode then
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = hyphen
+ end
+ end
+ if replace then
+ collectresults(replace,nil)
+ end
end
p = n
pid = id
diff --git a/tex/context/base/mkiv/buff-ver.mkiv b/tex/context/base/mkiv/buff-ver.mkiv
index a3c27977f..3e1eee75a 100644
--- a/tex/context/base/mkiv/buff-ver.mkiv
+++ b/tex/context/base/mkiv/buff-ver.mkiv
@@ -811,6 +811,7 @@
\else
\buff_verbatim_type_buffer_indeed\currenttyping\empty% []
\fi\fi
+ \useindentnextparameter\typingparameter
\endgroup
\dorechecknextindentation}
@@ -825,7 +826,9 @@
\setuptyping[#1][#3]%
\fi
\buff_verbatim_type_buffer_indeed{#1}{#2}%
- \endgroup}
+ \useindentnextparameter\typingparameter
+ \endgroup
+ \dorechecknextindentation}
\unexpanded\def\buff_verbatim_type_buffer_indeed#1#2% category name
{\edef\currenttyping{#1}%
@@ -851,8 +854,7 @@
\endofverbatimlines
\dostoptagged
\stoppacked
- \typingparameter\c!after
- \dorechecknextindentation}
+ \typingparameter\c!after}
\unexpanded\def\typeinlinebuffer
{\dontleavehmode
diff --git a/tex/context/base/mkiv/buff-ver.mkxl b/tex/context/base/mkiv/buff-ver.mkxl
index 24579e05e..292365e8f 100644
--- a/tex/context/base/mkiv/buff-ver.mkxl
+++ b/tex/context/base/mkiv/buff-ver.mkxl
@@ -797,6 +797,7 @@
\else
\buff_verbatim_type_buffer_indeed\currenttyping\empty% []
\fi
+ \useindentnextparameter\typingparameter
\endgroup
\dorechecknextindentation}
@@ -811,7 +812,9 @@
\setuptyping[#1][#3]%
\fi
\buff_verbatim_type_buffer_indeed{#1}{#2}%
- \endgroup}
+ \useindentnextparameter\typingparameter
+ \endgroup
+ \dorechecknextindentation}
\unexpanded\def\buff_verbatim_type_buffer_indeed#1#2% category name
{\edef\currenttyping{#1}%
@@ -837,8 +840,7 @@
\endofverbatimlines
\dostoptagged
\stoppacked
- \typingparameter\c!after
- \dorechecknextindentation}
+ \typingparameter\c!after}
\unexpanded\def\typeinlinebuffer
{\dontleavehmode
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index 9569cf357..03c9be8f9 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -110,6 +110,10 @@ local newtoken = token.new
local createtoken = token.create
local setluatoken = token.set_lua
+local isprintable = tex.isprintable or function(n)
+ return n and (type(n) == "string" or isnode(n) or istoken(n))
+end
+
local catcodenumbers = catcodes.numbers
local ctxcatcodes = catcodenumbers.ctxcatcodes
@@ -803,7 +807,8 @@ local function writer(parent,command,...) -- already optimized before call
end
elseif typ == "thread" then
report_context("coroutines not supported as we cannot yield across boundaries")
- elseif isnode(ti) then -- slow | why {} here ?
+ -- elseif isnode(ti) or istoken(ti) then
+ elseif isprintable(ti) then
flush(currentcatcodes,"{",ti,"}")
else
local s = tostring(ti)
@@ -967,7 +972,8 @@ local caller = function(parent,f,a,...)
end
elseif typ == "thread" then
report_context("coroutines not supported as we cannot yield across boundaries")
- elseif isnode(f) then -- slow
+ -- elseif isnode(f) or istoken(f) then
+ elseif isprintable(f) then
flush(f)
else
local s = tostring(f)
@@ -1062,8 +1068,7 @@ end)
local function userdata(argument)
if isnode(argument) then
return formatters["<< %s node %i>>"](nodes.nodecodes[argument.id],tonut(argument))
- end
- if istoken(argument) then
+ elseif istoken(argument) then
local csname = argument.csname
if csname then
-- return formatters["<<\\%s>>"](csname)
@@ -1074,8 +1079,9 @@ local function userdata(argument)
return "<<function>>" -- argument.mode
end
return "<<token>>"
+ else
+ return "<<userdata>>"
end
- return "<<userdata>>"
end
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 6d6aa3e1a..21e1a320d 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.06.29 19:42}
+\newcontextversion{2020.07.02 16:03}
%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 472c2cb2d..9ad4337ed 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.06.29 19:42}
+\edef\contextversion{2020.07.02 16:03}
\edef\contextkind {beta}
%D Kind of special:
@@ -264,6 +264,7 @@
\loadmarkfile{lxml-sor}
\loadmkvifile{typo-prc}
+\loadmkivfile{typo-plc}
% \loadmarkfile{anch-pos}
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 8566fc72a..d72b40d9d 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.06.29 19:42}
+\edef\contextversion{2020.07.02 16:03}
\edef\contextkind {beta}
%D Kind of special:
@@ -252,6 +252,7 @@
\loadmarkfile{lxml-sor}
\loadmkvifile{typo-prc}
+\loadmkivfile{typo-plc}
% \loadmarkfile{anch-pos}
diff --git a/tex/context/base/mkiv/driv-shp.lua b/tex/context/base/mkiv/driv-shp.lua
index 569a1f8dc..471fa92f0 100644
--- a/tex/context/base/mkiv/driv-shp.lua
+++ b/tex/context/base/mkiv/driv-shp.lua
@@ -437,33 +437,41 @@ end
-- t[k] = v
-- return v
-- end
+--
+-- local dirstack = setmetatableindex(dirstackentry)
+--
+-- local function reset_dir_stack()
+-- dirstack = setmetatableindex(dirstackentry)
+-- end
------ dirstack = { }
-local dirstack = setmetatableindex(dirstackentry)
+local dirstack = { }
local function reset_dir_stack()
- -- dirstack = setmetatableindex(dirstackentry)
dirstack = { }
end
+local leaderlevel = 0
+
local function flushlatelua(current,h,v)
+ -- Here we assume maganement by the lua function so currently we don't
+ -- check for leaderlevel.
return backends.latelua(current,h,v)
end
local function flushwriteout(current)
- if not doing_leaders then
+ if leaderlevel == 0 then
backends.writeout(current)
end
end
local function flushopenout(current)
- if not doing_leaders then
+ if leaderlevel == 0 then
backends.openout(current)
end
end
local function flushcloseout(current)
- if not doing_leaders then
+ if leaderlevel == 0 then
backends.closeout(current)
end
end
@@ -539,8 +547,6 @@ local hlist_out, vlist_out do
-- check frequencies of nodes
hlist_out = function(this_box,current)
- local outer_doing_leaders = false
-
local ref_h = pos_h
local ref_v = pos_v
local ref_r = pos_r
@@ -635,6 +641,7 @@ local hlist_out, vlist_out do
end
end
local shift = getshift(leader)
+ leaderlevel = leaderlevel + 1
while cur_h + width <= edge do
local basepoint_h = 0
-- local basepoint_v = shift
@@ -649,16 +656,14 @@ local hlist_out, vlist_out do
end
pos_v = ref_v - shift
-- synced
- outer_doing_leaders = doing_leaders
- doing_leaders = true
if getid(leader) == vlist_code then
vlist_out(leader,getlist(leader))
else
hlist_out(leader,getlist(leader))
end
- doing_leaders = outer_doing_leaders
cur_h = cur_h + width + lx
end
+ leaderlevel = leaderlevel - 1
cur_h = edge - 10
else
cur_h = cur_h + gluewidth
@@ -746,14 +751,6 @@ local hlist_out, vlist_out do
end
end
cur_h = cur_h + width
- elseif id == disc_code then
- local replace, tail = getreplace(current)
- if replace and subtype ~= select_disc then
- -- we could flatten .. no gain
- setlink(tail,getnext(current))
- setlink(current,replace)
- setreplace(current)
- end
elseif id == kern_code then
local kern, factor = getkern(current,true)
if kern ~= 0 then
@@ -865,11 +862,22 @@ local hlist_out, vlist_out do
elseif subtype == openwhatsit_code then
flushopenout(current)
end
+ elseif id == disc_code then
+ local replace, tail = getreplace(current)
+ if replace and subtype ~= select_disc then
+ -- we could flatten .. no gain
+ setlink(tail,getnext(current))
+ setlink(current,replace)
+ setreplace(current)
+ end
-- elseif id == localpar_code and start_of_par(current) then
-- local pardir = getdirection(current) or lefttoright_code
-- if pardir == righttoleft_code then
-- end
-- end
+ else
+ -- penalty, boundary ... no dimensions
+ goto synced
end
-- There is no gain in skipping over this when we have zero progression
-- and such.
@@ -887,8 +895,6 @@ local hlist_out, vlist_out do
end
vlist_out = function(this_box,current)
- local outer_doing_leaders = false
-
local ref_h = pos_h
local ref_v = pos_v
local ref_r = pos_r
@@ -968,6 +974,7 @@ local hlist_out, vlist_out do
end
end
local shift = getshift(leader)
+ leaderlevel = leaderlevel + 1
while cur_v + total <= edge do -- todo: <= edge - total
-- synch_pos_with_cur(ref_h, ref_v, getshift(leader), cur_v + height)
if pos_r == righttoleft_code then
@@ -977,16 +984,14 @@ local hlist_out, vlist_out do
end
pos_v = ref_v - (cur_v + height)
-- synced
- outer_doing_leaders = doing_leaders
- doing_leaders = true
if getid(leader) == vlist_code then
vlist_out(leader,getlist(leader))
else
hlist_out(leader,getlist(leader))
end
- doing_leaders = outer_doing_leaders
cur_v = cur_v + total + ly
end
+ leaderlevel = leaderlevel - 1
cur_v = edge - 10
else
cur_v = cur_v + glueheight
@@ -1005,13 +1010,17 @@ local hlist_out, vlist_out do
if not orientation then
-- local basepoint_h = shift
-- local basepoint_v = height
- if boxdir ~= pos_r then
- shift = shift + width
- end
- if pos_r == righttoleft_code then
- pos_h = ref_h - shift
+ if shift == 0 then
+ pos_h = ref_h
else
- pos_h = ref_h + shift
+ if boxdir ~= pos_r then
+ shift = shift + width
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - shift
+ else
+ pos_h = ref_h + shift
+ end
end
pos_v = ref_v - (cur_v + height)
-- synced
@@ -1114,6 +1123,9 @@ local hlist_out, vlist_out do
elseif subtype == openwhatsit_code then
flushopenout(current)
end
+ else
+ -- penalty
+ goto synced
end
if pos_r == righttoleft_code then
pos_h = ref_h - cur_h
diff --git a/tex/context/base/mkiv/lxml-ini.mkiv b/tex/context/base/mkiv/lxml-ini.mkiv
index 1c7006f57..52514519a 100644
--- a/tex/context/base/mkiv/lxml-ini.mkiv
+++ b/tex/context/base/mkiv/lxml-ini.mkiv
@@ -130,7 +130,7 @@
\let\xmlposition \xmlindex
-\unexpanded\def\xmlinfo#1{\hbox{\ttxx[\clf_xmlname{#1}]}}
+\unexpanded\def\xmlinfo#1{\hbox{\ttxx[\xmlname{#1}]}}
\unexpanded\def\xmlshow#1{\startpacked\ttx\xmlverbatim{#1}\stoppacked}
% the next one is handy for mode runs because it enforces a consistent
diff --git a/tex/context/base/mkiv/mult-ini.mkiv b/tex/context/base/mkiv/mult-ini.mkiv
index 641c8a4f5..b589f38f2 100644
--- a/tex/context/base/mkiv/mult-ini.mkiv
+++ b/tex/context/base/mkiv/mult-ini.mkiv
@@ -21,6 +21,10 @@
\registerctxluafile{mult-ini}{}
+% Todo:
+
+\def\c!placeholder{placeholder}
+
%D \macros
%D [constanten,variabelen,commands]
%D {v!,c!,k!,s!,e!,m!,l!,r!,f!,p!,x!,y!}
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index 0a33fc00a..9fdf72dde 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -271,6 +271,7 @@ return {
"etoksapp",
"etokspre",
"exceptionpenalty",
+ "expand",
"expandafterpars",
"expandafterspaces",
"expandcstoken",
diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua
index d13db4bba..88acdf3c5 100644
--- a/tex/context/base/mkiv/node-aux.lua
+++ b/tex/context/base/mkiv/node-aux.lua
@@ -641,233 +641,3 @@ do
end
end
-
-if not nodes.count then
-
- local type = type
-
- local direct = node.direct
- local todirect = direct.tovaliddirect
- local tonode = direct.tonode
-
- local count = direct.count
- local length = direct.length
- local slide = direct.slide
-
- function node.count(id,first,last)
- return count(id,first and todirect(first), last and todirect(last) or nil)
- end
-
- function node.length(first,last)
- return length(first and todirect(first), last and todirect(last) or nil)
- end
-
- function node.slide(n)
- if n then
- n = slide(todirect(n))
- if n then
- return tonode(n)
- end
- end
- return nil
- end
-
- local hyphenating = direct.hyphenating
- local ligaturing = direct.ligaturing
- local kerning = direct.kerning
-
- -- kind of inconsistent
-
- function node.hyphenating(first,last)
- if first then
- local h, t = hyphenating(todirect(first), last and todirect(last) or nil)
- return h and tonode(h) or nil, t and tonode(t) or nil, true
- else
- return nil, false
- end
- end
-
- function node.ligaturing(first,last)
- if first then
- local h, t = ligaturing(todirect(first), last and todirect(last) or nil)
- return h and tonode(h) or nil, t and tonode(t) or nil, true
- else
- return nil, false
- end
- end
-
- function node.kerning(first,last)
- if first then
- local h, t = kerning(todirect(first), last and todirect(last) or nil)
- return h and tonode(h) or nil, t and tonode(t) or nil, true
- else
- return nil, false
- end
- end
-
- local protect_glyph = direct.protect_glyph
- local unprotect_glyph = direct.unprotect_glyph
- local protect_glyphs = direct.protect_glyphs
- local unprotect_glyphs = direct.unprotect_glyphs
-
- function node.protect_glyphs(first,last)
- protect_glyphs(todirect(first), last and todirect(last) or nil)
- end
-
- function node.unprotect_glyphs(first,last)
- unprotect_glyphs(todirect(first), last and todirect(last) or nil)
- end
-
- function node.protect_glyph(first)
- protect_glyph(todirect(first))
- end
-
- function node.unprotect_glyph(first)
- unprotect_glyph(todirect(first))
- end
-
- local flatten_discretionaries = direct.flatten_discretionaries
- local check_discretionaries = direct.check_discretionaries
- local check_discretionary = direct.check_discretionary
-
- function node.flatten_discretionaries(first)
- local h, count = flatten_discretionaries(todirect(first))
- return tonode(h), count
- end
-
- function node.check_discretionaries(n)
- check_discretionaries(todirect(n))
- end
-
- function node.check_discretionary(n)
- check_discretionary(todirect(n))
- end
-
- local hpack = direct.hpack
- local vpack = direct.vpack
- local list_to_hlist = direct.mlist_to_hlist
-
- function node.hpack(head,...)
- local h, badness = hpack(head and todirect(head) or nil,...)
- return tonode(h), badness
- end
-
- function node.vpack(head,...)
- local h, badness = vpack(head and todirect(head) or nil,...)
- return tonode(h), badness
- end
-
- function node.mlist_to_hlist(head,...)
- return tonode(mlist_to_hlist(head and todirect(head) or nil,...))
- end
-
- local end_of_math = direct.end_of_math
- local find_attribute = direct.find_attribute
- local first_glyph = direct.first_glyph
-
- function node.end_of_math(n)
- if n then
- n = end_of_math(todirect(n))
- if n then
- return tonode(n)
- end
- end
- return nil
- end
-
- function node.find_attribute(n,a)
- if n then
- local v, n = find_attribute(todirect(n),a)
- if n then
- return v, tonode(n)
- end
- end
- return nil
- end
-
- function node.first_glyph(first,last)
- local n = first_glyph(todirect(first), last and todirect(last) or nil)
- return n and tonode(n) or nil
- end
-
- local dimensions = direct.dimensions
- local rangedimensions = direct.rangedimensions
- local effective_glue = direct.effective_glue
-
- function node.dimensions(a,b,c,d,e)
- if type(a) == "userdata" then
- a = todirect(a)
- if type(b) == "userdata" then
- b = todirect(b)
- end
- return dimensions(a,b)
- else
- d = todirect(d)
- if type(e) == "userdata" then
- e = todirect(e)
- end
- return dimensions(a,b,c,d,e)
- end
- return 0, 0, 0
- end
-
- function node.rangedimensions(parent,first,last)
- return rangedimenensions(todirect(parent),todirect(first),last and todirect(last))
- end
-
- function node.effective_glue(list,parent)
- return effective_glue(list and todirect(list) or nil,parent and todirect(parent) or nil)
- end
-
- local uses_font = direct.uses_font
- local has_glyph = direct.has_glyph
- local protrusion_skippable = direct.protrusion_skippable
- local prepend_prevdepth = direct.prepend_prevdepth
- local make_extensible = direct.make_extensible
-
- function node.uses_font(n,f)
- return uses_font(todirect(n),f)
- end
-
- function node.has_glyph(n)
- return has_glyph(todirect(n))
- end
-
- function node.protrusion_skippable(n)
- return protrusion_skippable(todirect(n))
- end
-
- function node.prepend_prevdepth(n)
- local n, d = prepend_prevdepth(todirect(n))
- return tonode(n), d
- end
-
- function node.make_extensible(...)
- local n = make_extensible(...)
- return n and tonode(n) or nil
- end
-
- local last_node = direct.last_node
-
- function node.last_node()
- local n = last_node()
- return n and tonode(n) or nil
- end
-
- local is_zero_glue = direct.is_zero_glue
- local getglue = direct.getglue
- local setglue = direct.setglue
-
- function node.is_zero_glue(n)
- return is_zero_glue(todirect(n))
- end
-
- function node.get_glue(n)
- return get_glue(todirect(n))
- end
-
- function node.set_glue(n)
- return set_glue(todirect(n))
- end
-
-end
diff --git a/tex/context/base/mkiv/node-cmp.lua b/tex/context/base/mkiv/node-cmp.lua
index e13e93d1f..18b939999 100644
--- a/tex/context/base/mkiv/node-cmp.lua
+++ b/tex/context/base/mkiv/node-cmp.lua
@@ -1,3 +1,14 @@
+if not modules then modules = { } end modules ['node-cmp'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is a LuaTeX compatibility module. The code below is no longer
+-- present node-met or node-aux. These functions are rarely used.
+
if node.count then
return
end
diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua
index a848cef69..a67ec5905 100644
--- a/tex/context/base/mkiv/node-fin.lua
+++ b/tex/context/base/mkiv/node-fin.lua
@@ -375,6 +375,7 @@ local function selective(attribute,head,inheritance,default) -- two attributes
else
check = has_dimensions(stack)
end
+ else
end
if check then
local c = getattr(stack,attribute)
@@ -637,97 +638,97 @@ end)
-- -- --
-do
-
- local cleaners = { }
- local trace = true -- false
-
- function attributes.cleanup()
- if next(cleaners) then
- local values = setmetatableindex("table")
-
- if trace then
- starttiming(values)
- end
-
- local function check(l)
- for n, id in nextnode, l do
- if id == hlist_code or id == vlist_code or id == glue_code then
- local l = getlist(n)
- if l then
- check(l)
- end
- end
- for a in next, cleaners do
- local v = getattr(n,a)
- if v then
- -- values[a] = values[a] + 1
- values[a][v] = true
- end
- end
- end
- end
-
- local top = texgetnest("ptr")
- for i=1,top do
- local l = texgetnest(i)
- if l then
- check(tonut(l.head))
- end
- end
-
- do local l
- l = tonut(texlists.page_ins_head) if l then check(l) end
- l = tonut(texlists.contrib_head) if l then check(l) end
- l = tonut(texlists.page_discards_head) if l then check(l) end
- l = tonut(texlists.split_discards_head) if l then check(l) end
- l = tonut(texlists.page_head) if l then check(l) end
- end
-
- -- todo: traverseboxes
-
- for i=0,65535 do
- local b = getbox(i)
- if b then
- local l = getlist(b)
- if l then
- check(l)
- end
- end
- end
-
- for a, t in next, values do
- cleaners[a](a,t)
- end
-
- if trace then
- stoptiming(values)
- local a = table.sortedkeys(values)
- local t = statistics.elapsedtime(values)
- local r = tex.getcount("realpageno")
- if #a == 0 then
- logs.report("attributes","cleaning up at page %i took %s seconds, no attributes",r,t)
- else
- logs.report("attributes","cleaning up at page %i took %s seconds, attributes: % t",r,t,a)
- end
- end
- end
- end
-
- -- not yet used but when we do ... delay a call till we enable it (attr-ini.mkiv)
-
- -- local function show(a,t) for k, v in next, t do print(a,k) end end
- --
- -- attributes.registercleaner( 1, show)
- -- attributes.registercleaner( 2, show)
-
- function attributes.registercleaner(a,f)
- cleaners[a] = f
- end
-
- implement {
- name = "cleanupattributes",
- actions = attributes.cleanup,
- }
-
-end
+-- do
+--
+-- local cleaners = { }
+-- local trace = true -- false
+--
+-- function attributes.cleanup()
+-- if next(cleaners) then
+-- local values = setmetatableindex("table")
+--
+-- if trace then
+-- starttiming(values)
+-- end
+--
+-- local function check(l)
+-- for n, id in nextnode, l do
+-- if id == hlist_code or id == vlist_code or id == glue_code then
+-- local l = getlist(n)
+-- if l then
+-- check(l)
+-- end
+-- end
+-- for a in next, cleaners do
+-- local v = getattr(n,a)
+-- if v then
+-- -- values[a] = values[a] + 1
+-- values[a][v] = true
+-- end
+-- end
+-- end
+-- end
+--
+-- local top = texgetnest("ptr")
+-- for i=1,top do
+-- local l = texgetnest(i)
+-- if l then
+-- check(tonut(l.head))
+-- end
+-- end
+--
+-- do local l
+-- l = tonut(texlists.page_ins_head) if l then check(l) end
+-- l = tonut(texlists.contrib_head) if l then check(l) end
+-- l = tonut(texlists.page_discards_head) if l then check(l) end
+-- l = tonut(texlists.split_discards_head) if l then check(l) end
+-- l = tonut(texlists.page_head) if l then check(l) end
+-- end
+--
+-- -- todo: traverseboxes
+--
+-- for i=0,65535 do
+-- local b = getbox(i)
+-- if b then
+-- local l = getlist(b)
+-- if l then
+-- check(l)
+-- end
+-- end
+-- end
+--
+-- for a, t in next, values do
+-- cleaners[a](a,t)
+-- end
+--
+-- if trace then
+-- stoptiming(values)
+-- local a = table.sortedkeys(values)
+-- local t = statistics.elapsedtime(values)
+-- local r = tex.getcount("realpageno")
+-- if #a == 0 then
+-- logs.report("attributes","cleaning up at page %i took %s seconds, no attributes",r,t)
+-- else
+-- logs.report("attributes","cleaning up at page %i took %s seconds, attributes: % t",r,t,a)
+-- end
+-- end
+-- end
+-- end
+--
+-- -- not yet used but when we do ... delay a call till we enable it (attr-ini.mkiv)
+--
+-- -- local function show(a,t) for k, v in next, t do print(a,k) end end
+-- --
+-- -- attributes.registercleaner(1, show)
+-- -- attributes.registercleaner(2, show)
+--
+-- function attributes.registercleaner(a,f)
+-- cleaners[a] = f
+-- end
+--
+-- implement {
+-- name = "cleanupattributes",
+-- actions = attributes.cleanup,
+-- }
+--
+-- end
diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua
index db079c116..f472d31a9 100644
--- a/tex/context/base/mkiv/node-met.lua
+++ b/tex/context/base/mkiv/node-met.lua
@@ -629,233 +629,3 @@ end
nodes.keys = keys -- [id][subtype]
nodes.fields = nodefields -- (n)
-
-if not nodes.count then
-
- local type = type
-
- local direct = node.direct
- local todirect = direct.tovaliddirect
- local tonode = direct.tonode
-
- local count = direct.count
- local length = direct.length
- local slide = direct.slide
-
- function node.count(id,first,last)
- return count(id,first and todirect(first), last and todirect(last) or nil)
- end
-
- function node.length(first,last)
- return length(first and todirect(first), last and todirect(last) or nil)
- end
-
- function node.slide(n)
- if n then
- n = slide(todirect(n))
- if n then
- return tonode(n)
- end
- end
- return nil
- end
-
- local hyphenating = direct.hyphenating
- local ligaturing = direct.ligaturing
- local kerning = direct.kerning
-
- -- kind of inconsistent
-
- function node.hyphenating(first,last)
- if first then
- local h, t = hyphenating(todirect(first), last and todirect(last) or nil)
- return h and tonode(h) or nil, t and tonode(t) or nil, true
- else
- return nil, false
- end
- end
-
- function node.ligaturing(first,last)
- if first then
- local h, t = ligaturing(todirect(first), last and todirect(last) or nil)
- return h and tonode(h) or nil, t and tonode(t) or nil, true
- else
- return nil, false
- end
- end
-
- function node.kerning(first,last)
- if first then
- local h, t = kerning(todirect(first), last and todirect(last) or nil)
- return h and tonode(h) or nil, t and tonode(t) or nil, true
- else
- return nil, false
- end
- end
-
- local protect_glyph = direct.protect_glyph
- local unprotect_glyph = direct.unprotect_glyph
- local protect_glyphs = direct.protect_glyphs
- local unprotect_glyphs = direct.unprotect_glyphs
-
- function node.protect_glyphs(first,last)
- protect_glyphs(todirect(first), last and todirect(last) or nil)
- end
-
- function node.unprotect_glyphs(first,last)
- unprotect_glyphs(todirect(first), last and todirect(last) or nil)
- end
-
- function node.protect_glyph(first)
- protect_glyph(todirect(first))
- end
-
- function node.unprotect_glyph(first)
- unprotect_glyph(todirect(first))
- end
-
- local flatten_discretionaries = direct.flatten_discretionaries
- local check_discretionaries = direct.check_discretionaries
- local check_discretionary = direct.check_discretionary
-
- function node.flatten_discretionaries(first)
- local h, count = flatten_discretionaries(todirect(first))
- return tonode(h), count
- end
-
- function node.check_discretionaries(n)
- check_discretionaries(todirect(n))
- end
-
- function node.check_discretionary(n)
- check_discretionary(todirect(n))
- end
-
- local hpack = direct.hpack
- local vpack = direct.vpack
- local list_to_hlist = direct.mlist_to_hlist
-
- function node.hpack(head,...)
- local h, badness = hpack(head and todirect(head) or nil,...)
- return tonode(h), badness
- end
-
- function node.vpack(head,...)
- local h, badness = vpack(head and todirect(head) or nil,...)
- return tonode(h), badness
- end
-
- function node.mlist_to_hlist(head,...)
- return tonode(mlist_to_hlist(head and todirect(head) or nil,...))
- end
-
- local end_of_math = direct.end_of_math
- local find_attribute = direct.find_attribute
- local first_glyph = direct.first_glyph
-
- function node.end_of_math(n)
- if n then
- n = end_of_math(todirect(n))
- if n then
- return tonode(n)
- end
- end
- return nil
- end
-
- function node.find_attribute(n,a)
- if n then
- local v, n = find_attribute(todirect(n),a)
- if n then
- return v, tonode(n)
- end
- end
- return nil
- end
-
- function node.first_glyph(first,last)
- local n = first_glyph(todirect(first), last and todirect(last) or nil)
- return n and tonode(n) or nil
- end
-
- local dimensions = direct.dimensions
- local rangedimensions = direct.rangedimensions
- local effective_glue = direct.effective_glue
-
- function node.dimensions(a,b,c,d,e)
- if type(a) == "userdata" then
- a = todirect(a)
- if type(b) == "userdata" then
- b = todirect(b)
- end
- return dimensions(a,b)
- else
- d = todirect(d)
- if type(e) == "userdata" then
- e = todirect(e)
- end
- return dimensions(a,b,c,d,e)
- end
- return 0, 0, 0
- end
-
- function node.rangedimensions(parent,first,last)
- return rangedimenensions(todirect(parent),todirect(first),last and todirect(last))
- end
-
- function node.effective_glue(list,parent)
- return effective_glue(list and todirect(list) or nil,parent and todirect(parent) or nil)
- end
-
- local uses_font = direct.uses_font
- local has_glyph = direct.has_glyph
- local protrusion_skippable = direct.protrusion_skippable
- local prepend_prevdepth = direct.prepend_prevdepth
- local make_extensible = direct.make_extensible
-
- function node.uses_font(n,f)
- return uses_font(todirect(n),f)
- end
-
- function node.has_glyph(n)
- return has_glyph(todirect(n))
- end
-
- function node.protrusion_skippable(n)
- return protrusion_skippable(todirect(n))
- end
-
- function node.prepend_prevdepth(n)
- local n, d = prepend_prevdepth(todirect(n))
- return tonode(n), d
- end
-
- function node.make_extensible(...)
- local n = make_extensible(...)
- return n and tonode(n) or nil
- end
-
- local last_node = direct.last_node
-
- function node.last_node()
- local n = last_node()
- return n and tonode(n) or nil
- end
-
- local is_zero_glue = direct.is_zero_glue
- local getglue = direct.getglue
- local setglue = direct.setglue
-
- function node.is_zero_glue(n)
- return is_zero_glue(todirect(n))
- end
-
- function node.get_glue(n)
- return get_glue(todirect(n))
- end
-
- function node.set_glue(n)
- return set_glue(todirect(n))
- end
-
-end
diff --git a/tex/context/base/mkiv/node-shp.lua b/tex/context/base/mkiv/node-shp.lua
index 306e38f6a..7af789b1b 100644
--- a/tex/context/base/mkiv/node-shp.lua
+++ b/tex/context/base/mkiv/node-shp.lua
@@ -66,59 +66,61 @@ local removables = {
-- (like marks) is not saving much and removing empty boxes is even
-- dangerous because we can rely on dimensions (e.g. in references).
-local wipedisc = false -- we can use them in the export ... can be option
-
-local function cleanup_redundant(head) -- better name is: flatten_page
- local start = head
- while start do
- local id = getid(start)
- if id == disc_code then
- if getsubtype(start) == discretionarydisc_code then
- local _, _, replace, _, _ tail = getdisc(start,true)
- if replace then
- local prev, next = getboth(start)
- setfield(start,"replace",nil)
- if start == head then
- remove_node(head,start,true)
- head = replace
- else
- remove_node(head,start,true)
- end
- if next then
- setlink(tail,next)
- end
- if prev then
- setlink(prev,replace)
- else
- setprev(replace) -- to be sure
- end
- start = next
- elseif wipedisc then
- -- pre and post can have values
- head, start = remove_node(head,start,true)
- else
- start = getnext(start)
- end
- else
- start = getnext(start)
- end
- elseif id == hlist_code or id == vlist_code then
- local sl = getlist(start)
- if sl then
- local rl = cleanup_redundant(sl)
- if rl ~= sl then
- setlist(start,rl)
- end
- end
- start = getnext(start)
- else
- start = getnext(start)
- end
- end
- return head
-end
-
-handlers.cleanuppage = cleanup_redundant -- nut
+-- local wipedisc = false -- we can use them in the export ... can be option
+--
+-- local function cleanup_redundant(head) -- better name is: flatten_page
+-- local start = head
+-- while start do
+-- local id = getid(start)
+-- if id == disc_code then
+-- if getsubtype(start) == discretionarydisc_code then
+-- local _, _, replace, _, _ tail = getdisc(start,true)
+-- if replace then
+-- local prev, next = getboth(start)
+-- setfield(start,"replace",nil)
+-- if start == head then
+-- remove_node(head,start,true)
+-- head = replace
+-- else
+-- remove_node(head,start,true)
+-- end
+-- if next then
+-- setlink(tail,next)
+-- end
+-- if prev then
+-- setlink(prev,replace)
+-- else
+-- setprev(replace) -- to be sure
+-- end
+-- start = next
+-- elseif wipedisc then
+-- -- pre and post can have values
+-- head, start = remove_node(head,start,true)
+-- else
+-- start = getnext(start)
+-- end
+-- else
+-- start = getnext(start)
+-- end
+-- elseif id == hlist_code or id == vlist_code then
+-- local sl = getlist(start)
+-- if sl then
+-- local rl = cleanup_redundant(sl)
+-- if rl ~= sl then
+-- setlist(start,rl)
+-- end
+-- end
+-- start = getnext(start)
+-- else
+-- start = getnext(start)
+-- end
+-- end
+-- return head
+-- end
+--
+-- handlers.cleanuppage = cleanup_redundant -- nut
+
+handlers.cleanuppage = nuts.flatten_discretionaries
local function cleanup_flushed(head) -- rough
local start = head
diff --git a/tex/context/base/mkiv/spac-lin.mkiv b/tex/context/base/mkiv/spac-lin.mkiv
index 870e85954..ef87536f2 100644
--- a/tex/context/base/mkiv/spac-lin.mkiv
+++ b/tex/context/base/mkiv/spac-lin.mkiv
@@ -74,6 +74,42 @@
\let\spac_lines_break \relax
\let\spac_after_first_obeyed_line\relax
+\let\spac_lines_indent \relax
+
+%D See \type {indentation-005.tex}:
+%D
+%D \starttyping
+%D \setuplines[indentnext={0pt,10pt,15pt,20pt}]
+%D
+%D \setupindenting[yes,1em]
+%D \setuplines[indentnext={0pt,*,*}]
+%D
+%D \setuplines[indentnext={0pt,1em,*}]
+%D \starttyping
+
+\newcount\c_spac_lines_indent_cnt
+\newcount\c_spac_lines_indent_max
+\newdimen\d_spac_lines_indent
+
+\def\spac_lines_indent_indeed
+ {\ifnum\c_spac_lines_indent_cnt=\c_spac_lines_indent_max
+ \c_spac_lines_indent_cnt\plusone
+ \else
+ \advance\c_spac_lines_indent_cnt\plusone
+ \fi
+ \getfromcommacommand[\m_spac_lines_indentnext][\c_spac_lines_indent_cnt]%
+ \ifx\commalistelement\wildcardsymbol
+ \hskip\d_spac_lines_indent
+ \else
+ \scratchdimen\dimexpr\commalistelement\relax
+ \hskip\ifdim\scratchdimen=\zeropoint
+ \zeropoint
+ \else
+ \scratchdimen
+ \d_spac_lines_indent\scratchdimen
+ \fi
+ \fi
+ \relax}
\def\spac_lines_start_indeed[#1]% new: optional second argument (WS)
{\iffirstargument
@@ -96,23 +132,39 @@
\typesettinglinestrue
\setupwhitespace[\v!none]% todo use fast variant
%\obeylines % move upwards to keep spaces in the first line due to optional argument
+ %
+ \edef\m_spac_lines_indentnext{\linesparameter\c!indentnext}%
+ \getcommacommandsize[\m_spac_lines_indentnext]%
+ \c_spac_lines_indent_max\commalistsize
+ \c_spac_lines_indent_cnt\zerocount
+ \ifnum\c_spac_lines_indent_max>\plusone
+ \letlinesparameter\c!indentnext\empty
+ \let\spac_lines_indent\spac_lines_indent_indeed
+ \d_spac_lines_indent\d_spac_indentation_par
+ \else
+ \let\spac_lines_indent\relax
+ \fi
+ %
\ignorespaces
\glet\spac_after_first_obeyed_line\spac_lines_after_first_obeyed_line_a
\let\obeyedline\spac_lines_obeyed_line
\activatespacehandler{\linesparameter\c!space}%
\dostarttagged\t!line\empty
- \ignorepars} % this will become a nice lowercased helper
+ \ignorepars}
+
% we could have states instead and handle option in there
\def\spac_lines_after_first_obeyed_line_a % tzt two pass, like itemize
{\linesparameter\c!command
+ \spac_lines_indent
\linesparameter\c!left
\glet\spac_after_first_obeyed_line\spac_lines_after_first_obeyed_line_b}
\def\spac_lines_after_first_obeyed_line_b
{\spac_lines_break
\linesparameter\c!command
+ \spac_lines_indent
\linesparameter\c!left}
\def\spac_lines_obeyed_line
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 7d52b1dca..2b85fcc22 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 f800c7b59..b34a061e8 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-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv
index a1f02b740..4959ffc16 100644
--- a/tex/context/base/mkiv/strc-sec.mkiv
+++ b/tex/context/base/mkiv/strc-sec.mkiv
@@ -145,6 +145,7 @@
\xdef\currentstructureshownumber {\structureparameter\c!number}%
\xdef\currentstructuresaveinlist {\structureparameter\c!saveinlist}%
\xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}%
+ \xdef\currentstructureplaceholder {\structureparameter\c!placeholder}%
\ifx\currentstructureexpansion\s!xml
\xmlstartraw
\xdef\currentstructuretitle {\structureparameter\c!title}%
@@ -997,12 +998,26 @@
\setfalse\c_strc_sectioning_ignore_page
% ignorespaces prevents spaces creeping in when after=\dontleavehmode
\dostarttagged\t!sectioncontent\empty
- \ifconditional\headisdisplay
- \expandafter\ignorespaces
+ \ifx\currentstructureplaceholder\empty
+ \ifconditional\headisdisplay
+ \doubleexpandafter\ignorespaces
+ \else
+ \doubleexpandafter\ignorepars
+ \fi
\else
- \expandafter\ignorepars
+ \expandafter\strc_sectioning_placeholder
\fi}
+%D \starttyping
+%D \startsubject[placeholder=todo,title=one]
+%D whatever one
+%D \stopsubject
+%D \stoptyping
+
+\def\strc_sectioning_placeholder
+ {\placeholder[\currentstructureplaceholder]%
+ \gobblenested{\e!start\currenthead}{\e!stop\currenthead}{\e!stop\currenthead}}
+
% typesetting (the getters are public)
\unexpanded\def\strc_rendering_place_head_number_and_text
diff --git a/tex/context/base/mkiv/syst-aux.lua b/tex/context/base/mkiv/syst-aux.lua
index 09232488d..4d81c4140 100644
--- a/tex/context/base/mkiv/syst-aux.lua
+++ b/tex/context/base/mkiv/syst-aux.lua
@@ -936,3 +936,25 @@ if CONTEXTLMTXMODE > 0 then
}
end
+
+-- For the moment here:
+
+if CONTEXTLMTXMODE > 0 then
+
+ local create = token.create
+ local gobble = token.gobble
+
+ implement {
+ name = "gobblenested",
+ public = true,
+ protected = true,
+ arguments = "3 strings",
+ actions = function(start,stop,command)
+ gobble(create(start),create(stop))
+ if command then
+ context[command]()
+ end
+ end
+ }
+
+end
diff --git a/tex/context/base/mkiv/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv
index 20716786d..43d9c6b31 100644
--- a/tex/context/base/mkiv/syst-aux.mkiv
+++ b/tex/context/base/mkiv/syst-aux.mkiv
@@ -4976,6 +4976,12 @@
\unexpanded\def\gobbleuntilrelax#1\relax
{}
+% experimental
+
+\unexpanded\def\gobblenested#1#2#3%
+ {\normalexpanded{\def\next##1\csname#2\endcsname}{\csname#3\endcsname}%
+ \next}%
+
%D The next one simply expands the pickup up tokens.
%D
%D \starttyping
diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua
index 19fff66b8..366c7009e 100644
--- a/tex/context/base/mkiv/task-ini.lua
+++ b/tex/context/base/mkiv/task-ini.lua
@@ -68,9 +68,9 @@ appendaction("processors", "lists", "languages.visualizediscretionaries"
appendaction("processors", "after", "typesetters.marksuspects", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "nodes.handlers.cleanuppage", nil, "nut", "production")
appendaction("shipouts", "normalizers", "typesetters.showsuspects", nil, "nut", "disabled" )
appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler", nil, "nut", "disabled" )
-------------("shipouts", "normalizers", "nodes.handlers.cleanuppage", nil, "nut", "disabled" )
appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace", nil, "nut", "disabled" )
appendaction("shipouts", "normalizers", "typesetters.alignments.handler", nil, "nut", "disabled" )
appendaction("shipouts", "normalizers", "nodes.references.handler", nil, "nut", "production")
diff --git a/tex/context/base/mkiv/toks-ini.lua b/tex/context/base/mkiv/toks-ini.lua
index 184a17489..e0c093492 100644
--- a/tex/context/base/mkiv/toks-ini.lua
+++ b/tex/context/base/mkiv/toks-ini.lua
@@ -44,7 +44,7 @@ local scan_toks = token.scan_toks
local scan_string = token.scan_string
local scan_argument = token.scan_argument
local scan_delimited = token.scan_delimited
-local scan_tokenlist = token.scan_tokenlist
+local scan_tokenlist = token.scan_tokenlist or scan_string
local scan_int = token.scan_int
local scan_code = token.scan_code
local scan_token_code = token.scan_token_code
diff --git a/tex/context/base/mkiv/typo-plc.mkiv b/tex/context/base/mkiv/typo-plc.mkiv
new file mode 100644
index 000000000..dbc9f081d
--- /dev/null
+++ b/tex/context/base/mkiv/typo-plc.mkiv
@@ -0,0 +1,39 @@
+%D \module
+%D [ file=typo-plc,
+%D version=2020.07.01,
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Placeholders,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Typesetting Macros / Placeholders}
+
+\unprotect
+
+\installcorenamespace {placeholder}
+
+\installcommandhandler \??placeholder {placeholder} \??placeholder
+
+\unexpanded\def\placeholder[#1]%
+ {\begingroup
+ \edef\currentplaceholder{#1}%
+ \placeholderparameter\c!before
+ \useplaceholderstyleandcolor\c!style\c!color
+ \placeholderparameter\c!text
+ \placeholderparameter\c!after
+ \endgroup}
+
+\defineplaceholder
+ [todo]
+ %[\c!text={Still to be written!},
+ [\c!text=todo, % labeltext ?
+ \c!style=\v!bold,
+ \c!before=\blank,
+ \c!after=\blank]
+
+\protect \endinput