summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/context/lua/mtx-context.lua2
-rw-r--r--scripts/context/lua/mtxrun.lua125
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua125
-rw-r--r--scripts/context/stubs/unix/mtxrun125
-rw-r--r--tex/context/base/bibl-bib.mkiv6
-rw-r--r--tex/context/base/buff-ver.mkiv18
-rw-r--r--tex/context/base/cont-fil.mkii (renamed from tex/context/base/cont-fil.tex)0
-rw-r--r--tex/context/base/cont-fil.mkiv124
-rw-r--r--tex/context/base/cont-log.tex70
-rw-r--r--tex/context/base/cont-new.mkii2
-rw-r--r--tex/context/base/cont-new.tex2
-rw-r--r--tex/context/base/context.mkii20
-rw-r--r--tex/context/base/context.mkiv20
-rw-r--r--tex/context/base/context.tex2
-rw-r--r--tex/context/base/core-env.lua37
-rw-r--r--tex/context/base/core-env.mkiv20
-rw-r--r--tex/context/base/core-job.mkiv2
-rw-r--r--tex/context/base/core-mis.mkiv1
-rw-r--r--tex/context/base/core-sys.mkiv16
-rw-r--r--tex/context/base/core-var.mkiv4
-rw-r--r--tex/context/base/data-env.lua2
-rw-r--r--tex/context/base/data-res.lua45
-rw-r--r--tex/context/base/data-tmp.lua21
-rw-r--r--tex/context/base/font-ini.mkiv84
-rw-r--r--tex/context/base/font-otf.lua10
-rw-r--r--tex/context/base/grph-inc.lua54
-rw-r--r--tex/context/base/grph-inc.mkiv17
-rw-r--r--tex/context/base/grph-wnd.lua47
-rw-r--r--tex/context/base/l-number.lua16
-rw-r--r--tex/context/base/lang-spa.mkii (renamed from tex/context/base/lang-spa.tex)0
-rw-r--r--tex/context/base/lang-spa.mkiv76
-rw-r--r--tex/context/base/luat-cod.mkiv2
-rw-r--r--tex/context/base/luat-fmt.lua9
-rw-r--r--tex/context/base/meta-xml.mkii (renamed from tex/context/base/meta-xml.tex)0
-rw-r--r--tex/context/base/meta-xml.mkiv20
-rw-r--r--tex/context/base/mult-cld.lua262
-rw-r--r--tex/context/base/mult-cld.mkiv11
-rw-r--r--tex/context/base/mult-clm.lua12
-rw-r--r--tex/context/base/mult-def.mkii (renamed from tex/context/base/mult-def.tex)8
-rw-r--r--tex/context/base/mult-def.mkiv31
-rw-r--r--tex/context/base/mult-fst.mkii36
-rw-r--r--tex/context/base/mult-fst.mkiv (renamed from tex/context/base/mult-fst.tex)24
-rw-r--r--tex/context/base/mult-ini.mkiv10
-rw-r--r--tex/context/base/mult-pe.tex1700
-rw-r--r--tex/context/base/mult-sys.mkii (renamed from tex/context/base/mult-sys.tex)4
-rw-r--r--tex/context/base/mult-sys.mkiv901
-rw-r--r--tex/context/base/s-abr-04.tex22
-rw-r--r--tex/context/base/sort-ini.lua4
-rw-r--r--tex/context/base/spac-hor.mkiv4
-rw-r--r--tex/context/base/strc-not.mkiv2
-rw-r--r--tex/context/base/supp-ali.mkii (renamed from tex/context/base/supp-ali.tex)0
-rw-r--r--tex/context/base/supp-ali.mkiv173
-rw-r--r--tex/context/base/supp-box.mkii (renamed from tex/context/base/supp-box.tex)4
-rw-r--r--tex/context/base/supp-box.mkiv3126
-rw-r--r--tex/context/base/supp-fun.mkii (renamed from tex/context/base/supp-fun.tex)0
-rw-r--r--tex/context/base/supp-fun.mkiv746
-rw-r--r--tex/context/base/supp-num.mkii (renamed from tex/context/base/supp-num.tex)0
-rw-r--r--tex/context/base/supp-num.mkiv509
-rw-r--r--tex/context/base/supp-vis.mkii (renamed from tex/context/base/supp-vis.tex)0
-rw-r--r--tex/context/base/supp-vis.mkiv1907
-rw-r--r--tex/context/base/syst-aux.mkiv19
-rw-r--r--tex/context/base/syst-con.mkiv18
-rw-r--r--tex/context/base/syst-lua.mkiv3
-rw-r--r--tex/context/base/trac-set.lua31
-rw-r--r--tex/context/base/util-lua.lua1
-rw-r--r--tex/context/bib/bibl-apa.tex34
-rw-r--r--tex/generic/context/luatex-fonts-merged.lua12
-rw-r--r--web2c/contextcnf.lua5
68 files changed, 10281 insertions, 462 deletions
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index cee926a6e..38cffe63e 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -589,7 +589,7 @@ scripts.context.defaultformats = {
-- "plain"
}
-local function analyze(filename)
+local function analyze(filename) -- only files on current path
local f = io.open(file.addsuffix(filename,"tex"))
if f then
local t = { }
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index f83f0d41d..a42713378 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -1589,7 +1589,8 @@ if not modules then modules = { } end modules ['l-number'] = {
}
local tostring = tostring
-local format, floor, insert, match = string.format, math.floor, table.insert, string.match
+local format, floor, insert, match = string.format, math.floor, string.match
+local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
number = number or { }
@@ -1657,6 +1658,19 @@ function number.clearbit(x, p)
return hasbit(x, p) and x - p or x
end
+function number.tobitstring(n)
+ if n == 0 then
+ return "0"
+ else
+ local t = { }
+ while n > 0 do
+ insert(t,1,n % 2 > 0 and 1 or 0)
+ n = floor(n/2)
+ end
+ return concat(t)
+ end
+end
+
end -- of closure
@@ -3443,7 +3457,6 @@ function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: clean
end
-
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4233,13 +4246,13 @@ local setters = utilities.setters
local data = { } -- maybe just local
-- We can initialize from the cnf file. This is sort of tricky as
--- laster defined setters also need to be initialized then. If set
+-- later defined setters also need to be initialized then. If set
-- this way, we need to ensure that they are not reset later on.
-local trace_initialize = false
+local trace_initialize = false -- only for testing during development
-local function report(what,filename,name,key,value)
- texio.write_nl(format("%s setter, filename: %s, name: %s, key: %s, value: %s",what,filename,name,key,value))
+local function report(a,b,...)
+ texio.write_nl(format("%-16s> %s",a,format(b,...)))
end
function setters.initialize(filename,name,values) -- filename only for diagnostics
@@ -4254,7 +4267,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
if functions then
if #functions > 0 and not functions.value then
if trace_initialize then
- report("doing",filename,name,key,value)
+ report(name,"executing %s (%s -> %s)",key,filename,tostring(value))
end
for i=1,#functions do
functions[i](value)
@@ -4262,7 +4275,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions.value = value
else
if trace_initialize then
- report("skipping",filename,name,key,value)
+ report(name,"skipping %s (%s -> %s)",key,filename,tostring(value))
end
end
else
@@ -4271,7 +4284,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions = { default = value }
data[key] = functions
if trace_initialize then
- report("storing",filename,name,key,value)
+ report(name,"storing %s (%s -> %s)",key,filename,tostring(value))
end
end
end
@@ -4341,11 +4354,17 @@ function setters.register(t,what,...)
if not functions then
functions = { }
data[what] = functions
+ if trace_initialize then
+ report(t.name,"defining %s",what)
+ end
end
local default = functions.default -- can be set from cnf file
for _, fnc in next, { ... } do
local typ = type(fnc)
if typ == "string" then
+ if trace_initialize then
+ report(t.name,"coupling %s to %s",what,fnc)
+ end
local s = fnc -- else wrong reference
fnc = function(value) set(t,s,value) end
elseif typ ~= "function" then
@@ -4353,9 +4372,12 @@ function setters.register(t,what,...)
end
if fnc then
functions[#functions+1] = fnc
- if default then
- fnc(default)
- functions.value = default
+ -- default: set at command line or in cnf file
+ -- value : set in tex run (needed when loading runtime)
+ local value = functions.value or default
+ if value ~= nil then
+ fnc(value)
+ functions.value = value
end
end
end
@@ -4405,7 +4427,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- commands.writestatus(category,format("%-25s modules: %2i default: %5s value: %5s",name,modules,default,value))
+ commands.writestatus(category,format("%-30s modules: %2i default: %5s value: %5s",name,modules,default,value))
end
end
commands.writestatus("","")
@@ -9415,7 +9437,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[file.extname(str)] or 'tex'
+ return suffixmap[file.extname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
@@ -9479,6 +9501,21 @@ local report_resolvers = logs.new("resolvers")
local resolvers = resolvers
+-- intermezzo
+
+local directive_cleanup = false directives.register("system.compile.cleanup", function(v) directive_cleanup = v end)
+local directive_strip = true directives.register("system.compile.strip", function(v) directive_strip = v end)
+
+local compile = utilities.lua.compile
+
+function utilities.lua.compile(luafile,lucfile,cleanup,strip)
+ if cleanup == nil then cleanup = directive_cleanup end
+ if strip == nil then strip = directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
+end
+
+-- end of intermezzo
+
caches = caches or { }
local caches = caches
@@ -9723,9 +9760,7 @@ function caches.savedata(filepath,filename,data,raw)
else
table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
end
- local cleanup = resolvers.booleanvariable("PURGECACHE", false)
- local strip = resolvers.booleanvariable("LUACSTRIP", true)
- utilities.lua.compile(tmaname, tmcname, cleanup, strip)
+ utilities.lua.compile(tmaname,tmcname)
end
-- moved from data-res:
@@ -9787,7 +9822,7 @@ function caches.savecontent(cachename,dataname,content)
if trace_locating then
report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname)
end
- if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip
+ if utilities.lua.compile(luaname,lucname) then
if trace_locating then
report_resolvers("'%s' compiled to '%s'",dataname,lucname)
end
@@ -9924,6 +9959,8 @@ local dangerous = resolvers.dangerous
local suffixmap = resolvers.suffixmap
local alternatives = resolvers.alternatives
+resolvers.defaultsuffixes = { "tex" } -- "mkiv", "cld" -- too tricky
+
resolvers.instance = resolvers.instance or nil -- the current one (slow access)
local instance = resolvers.instance or nil -- the current one (fast access)
@@ -10748,27 +10785,17 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
else
local forcedname, ok, suffix = "", false, fileextname(filename)
if suffix == "" then -- why
- if instance.format == "" then
- forcedname = filename .. ".tex"
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing standard filetype 'tex'")
- end
- result, ok = { forcedname }, true
- end
- else
- local format_suffixes = suffixes[instance.format]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s = format_suffixes[i]
- forcedname = filename .. "." .. s
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing format filetype '%s'", s)
- end
- result, ok = { forcedname }, true
- break
+ local format_suffixes = instance.format == "" and resolvers.defaultsuffixes or suffixes[instance.format]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s = format_suffixes[i]
+ forcedname = filename .. "." .. s
+ if resolvers.isreadable.file(forcedname) then
+ if trace_locating then
+ report_resolvers("no suffix, forcing format filetype '%s'", s)
end
+ result, ok = { forcedname }, true
+ break
end
end
end
@@ -10833,11 +10860,14 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
if instance.format == "" then
if ext == "" or not suffixmap[ext] then
- local forcedname = filename .. '.tex'
- wantedfiles[#wantedfiles+1] = forcedname
- filetype = resolvers.formatofsuffix(forcedname)
- if trace_locating then
- report_resolvers("forcing filetype '%s'",filetype)
+ local defaultsuffixes = resolvers.defaultsuffixes
+ for i=1,#defaultsuffixes do
+ local forcedname = filename .. '.' .. defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1] = forcedname
+ filetype = resolvers.formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolvers("forcing filetype '%s'",filetype)
+ end
end
else
filetype = resolvers.formatofsuffix(filename)
@@ -12591,6 +12621,9 @@ if not modules then modules = { } end modules ['luat-fmt'] = {
license = "see context related readme files"
}
+
+local format = string.format
+
-- helper for mtxrun
local quote = string.quote
@@ -12655,7 +12688,7 @@ function environment.make_format(name)
utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
-- compile stub file (does not save that much as we don't use this stub at startup any more)
local strip = resolvers.booleanvariable("LUACSTRIP", true)
- if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
logs.simple("using compiled initialization file: %s",lucstubname)
usedluastub = lucstubname
else
@@ -12668,7 +12701,7 @@ function environment.make_format(name)
return
end
-- generate format
- local command = string.format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
+ local command = format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
logs.simple("running command: %s\n",command)
os.spawn(command)
-- remove related mem files
@@ -12707,7 +12740,7 @@ function environment.run_format(name,data,more)
logs.simple("no luc/lua with name: %s",barename)
else
local q = string.quote
- local command = string.format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
+ local command = format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
logs.simple("running command: %s",command)
os.spawn(command)
end
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index f83f0d41d..a42713378 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -1589,7 +1589,8 @@ if not modules then modules = { } end modules ['l-number'] = {
}
local tostring = tostring
-local format, floor, insert, match = string.format, math.floor, table.insert, string.match
+local format, floor, insert, match = string.format, math.floor, string.match
+local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
number = number or { }
@@ -1657,6 +1658,19 @@ function number.clearbit(x, p)
return hasbit(x, p) and x - p or x
end
+function number.tobitstring(n)
+ if n == 0 then
+ return "0"
+ else
+ local t = { }
+ while n > 0 do
+ insert(t,1,n % 2 > 0 and 1 or 0)
+ n = floor(n/2)
+ end
+ return concat(t)
+ end
+end
+
end -- of closure
@@ -3443,7 +3457,6 @@ function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: clean
end
-
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4233,13 +4246,13 @@ local setters = utilities.setters
local data = { } -- maybe just local
-- We can initialize from the cnf file. This is sort of tricky as
--- laster defined setters also need to be initialized then. If set
+-- later defined setters also need to be initialized then. If set
-- this way, we need to ensure that they are not reset later on.
-local trace_initialize = false
+local trace_initialize = false -- only for testing during development
-local function report(what,filename,name,key,value)
- texio.write_nl(format("%s setter, filename: %s, name: %s, key: %s, value: %s",what,filename,name,key,value))
+local function report(a,b,...)
+ texio.write_nl(format("%-16s> %s",a,format(b,...)))
end
function setters.initialize(filename,name,values) -- filename only for diagnostics
@@ -4254,7 +4267,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
if functions then
if #functions > 0 and not functions.value then
if trace_initialize then
- report("doing",filename,name,key,value)
+ report(name,"executing %s (%s -> %s)",key,filename,tostring(value))
end
for i=1,#functions do
functions[i](value)
@@ -4262,7 +4275,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions.value = value
else
if trace_initialize then
- report("skipping",filename,name,key,value)
+ report(name,"skipping %s (%s -> %s)",key,filename,tostring(value))
end
end
else
@@ -4271,7 +4284,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions = { default = value }
data[key] = functions
if trace_initialize then
- report("storing",filename,name,key,value)
+ report(name,"storing %s (%s -> %s)",key,filename,tostring(value))
end
end
end
@@ -4341,11 +4354,17 @@ function setters.register(t,what,...)
if not functions then
functions = { }
data[what] = functions
+ if trace_initialize then
+ report(t.name,"defining %s",what)
+ end
end
local default = functions.default -- can be set from cnf file
for _, fnc in next, { ... } do
local typ = type(fnc)
if typ == "string" then
+ if trace_initialize then
+ report(t.name,"coupling %s to %s",what,fnc)
+ end
local s = fnc -- else wrong reference
fnc = function(value) set(t,s,value) end
elseif typ ~= "function" then
@@ -4353,9 +4372,12 @@ function setters.register(t,what,...)
end
if fnc then
functions[#functions+1] = fnc
- if default then
- fnc(default)
- functions.value = default
+ -- default: set at command line or in cnf file
+ -- value : set in tex run (needed when loading runtime)
+ local value = functions.value or default
+ if value ~= nil then
+ fnc(value)
+ functions.value = value
end
end
end
@@ -4405,7 +4427,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- commands.writestatus(category,format("%-25s modules: %2i default: %5s value: %5s",name,modules,default,value))
+ commands.writestatus(category,format("%-30s modules: %2i default: %5s value: %5s",name,modules,default,value))
end
end
commands.writestatus("","")
@@ -9415,7 +9437,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[file.extname(str)] or 'tex'
+ return suffixmap[file.extname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
@@ -9479,6 +9501,21 @@ local report_resolvers = logs.new("resolvers")
local resolvers = resolvers
+-- intermezzo
+
+local directive_cleanup = false directives.register("system.compile.cleanup", function(v) directive_cleanup = v end)
+local directive_strip = true directives.register("system.compile.strip", function(v) directive_strip = v end)
+
+local compile = utilities.lua.compile
+
+function utilities.lua.compile(luafile,lucfile,cleanup,strip)
+ if cleanup == nil then cleanup = directive_cleanup end
+ if strip == nil then strip = directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
+end
+
+-- end of intermezzo
+
caches = caches or { }
local caches = caches
@@ -9723,9 +9760,7 @@ function caches.savedata(filepath,filename,data,raw)
else
table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
end
- local cleanup = resolvers.booleanvariable("PURGECACHE", false)
- local strip = resolvers.booleanvariable("LUACSTRIP", true)
- utilities.lua.compile(tmaname, tmcname, cleanup, strip)
+ utilities.lua.compile(tmaname,tmcname)
end
-- moved from data-res:
@@ -9787,7 +9822,7 @@ function caches.savecontent(cachename,dataname,content)
if trace_locating then
report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname)
end
- if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip
+ if utilities.lua.compile(luaname,lucname) then
if trace_locating then
report_resolvers("'%s' compiled to '%s'",dataname,lucname)
end
@@ -9924,6 +9959,8 @@ local dangerous = resolvers.dangerous
local suffixmap = resolvers.suffixmap
local alternatives = resolvers.alternatives
+resolvers.defaultsuffixes = { "tex" } -- "mkiv", "cld" -- too tricky
+
resolvers.instance = resolvers.instance or nil -- the current one (slow access)
local instance = resolvers.instance or nil -- the current one (fast access)
@@ -10748,27 +10785,17 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
else
local forcedname, ok, suffix = "", false, fileextname(filename)
if suffix == "" then -- why
- if instance.format == "" then
- forcedname = filename .. ".tex"
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing standard filetype 'tex'")
- end
- result, ok = { forcedname }, true
- end
- else
- local format_suffixes = suffixes[instance.format]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s = format_suffixes[i]
- forcedname = filename .. "." .. s
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing format filetype '%s'", s)
- end
- result, ok = { forcedname }, true
- break
+ local format_suffixes = instance.format == "" and resolvers.defaultsuffixes or suffixes[instance.format]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s = format_suffixes[i]
+ forcedname = filename .. "." .. s
+ if resolvers.isreadable.file(forcedname) then
+ if trace_locating then
+ report_resolvers("no suffix, forcing format filetype '%s'", s)
end
+ result, ok = { forcedname }, true
+ break
end
end
end
@@ -10833,11 +10860,14 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
if instance.format == "" then
if ext == "" or not suffixmap[ext] then
- local forcedname = filename .. '.tex'
- wantedfiles[#wantedfiles+1] = forcedname
- filetype = resolvers.formatofsuffix(forcedname)
- if trace_locating then
- report_resolvers("forcing filetype '%s'",filetype)
+ local defaultsuffixes = resolvers.defaultsuffixes
+ for i=1,#defaultsuffixes do
+ local forcedname = filename .. '.' .. defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1] = forcedname
+ filetype = resolvers.formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolvers("forcing filetype '%s'",filetype)
+ end
end
else
filetype = resolvers.formatofsuffix(filename)
@@ -12591,6 +12621,9 @@ if not modules then modules = { } end modules ['luat-fmt'] = {
license = "see context related readme files"
}
+
+local format = string.format
+
-- helper for mtxrun
local quote = string.quote
@@ -12655,7 +12688,7 @@ function environment.make_format(name)
utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
-- compile stub file (does not save that much as we don't use this stub at startup any more)
local strip = resolvers.booleanvariable("LUACSTRIP", true)
- if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
logs.simple("using compiled initialization file: %s",lucstubname)
usedluastub = lucstubname
else
@@ -12668,7 +12701,7 @@ function environment.make_format(name)
return
end
-- generate format
- local command = string.format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
+ local command = format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
logs.simple("running command: %s\n",command)
os.spawn(command)
-- remove related mem files
@@ -12707,7 +12740,7 @@ function environment.run_format(name,data,more)
logs.simple("no luc/lua with name: %s",barename)
else
local q = string.quote
- local command = string.format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
+ local command = format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
logs.simple("running command: %s",command)
os.spawn(command)
end
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index f83f0d41d..a42713378 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -1589,7 +1589,8 @@ if not modules then modules = { } end modules ['l-number'] = {
}
local tostring = tostring
-local format, floor, insert, match = string.format, math.floor, table.insert, string.match
+local format, floor, insert, match = string.format, math.floor, string.match
+local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
number = number or { }
@@ -1657,6 +1658,19 @@ function number.clearbit(x, p)
return hasbit(x, p) and x - p or x
end
+function number.tobitstring(n)
+ if n == 0 then
+ return "0"
+ else
+ local t = { }
+ while n > 0 do
+ insert(t,1,n % 2 > 0 and 1 or 0)
+ n = floor(n/2)
+ end
+ return concat(t)
+ end
+end
+
end -- of closure
@@ -3443,7 +3457,6 @@ function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: clean
end
-
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4233,13 +4246,13 @@ local setters = utilities.setters
local data = { } -- maybe just local
-- We can initialize from the cnf file. This is sort of tricky as
--- laster defined setters also need to be initialized then. If set
+-- later defined setters also need to be initialized then. If set
-- this way, we need to ensure that they are not reset later on.
-local trace_initialize = false
+local trace_initialize = false -- only for testing during development
-local function report(what,filename,name,key,value)
- texio.write_nl(format("%s setter, filename: %s, name: %s, key: %s, value: %s",what,filename,name,key,value))
+local function report(a,b,...)
+ texio.write_nl(format("%-16s> %s",a,format(b,...)))
end
function setters.initialize(filename,name,values) -- filename only for diagnostics
@@ -4254,7 +4267,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
if functions then
if #functions > 0 and not functions.value then
if trace_initialize then
- report("doing",filename,name,key,value)
+ report(name,"executing %s (%s -> %s)",key,filename,tostring(value))
end
for i=1,#functions do
functions[i](value)
@@ -4262,7 +4275,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions.value = value
else
if trace_initialize then
- report("skipping",filename,name,key,value)
+ report(name,"skipping %s (%s -> %s)",key,filename,tostring(value))
end
end
else
@@ -4271,7 +4284,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions = { default = value }
data[key] = functions
if trace_initialize then
- report("storing",filename,name,key,value)
+ report(name,"storing %s (%s -> %s)",key,filename,tostring(value))
end
end
end
@@ -4341,11 +4354,17 @@ function setters.register(t,what,...)
if not functions then
functions = { }
data[what] = functions
+ if trace_initialize then
+ report(t.name,"defining %s",what)
+ end
end
local default = functions.default -- can be set from cnf file
for _, fnc in next, { ... } do
local typ = type(fnc)
if typ == "string" then
+ if trace_initialize then
+ report(t.name,"coupling %s to %s",what,fnc)
+ end
local s = fnc -- else wrong reference
fnc = function(value) set(t,s,value) end
elseif typ ~= "function" then
@@ -4353,9 +4372,12 @@ function setters.register(t,what,...)
end
if fnc then
functions[#functions+1] = fnc
- if default then
- fnc(default)
- functions.value = default
+ -- default: set at command line or in cnf file
+ -- value : set in tex run (needed when loading runtime)
+ local value = functions.value or default
+ if value ~= nil then
+ fnc(value)
+ functions.value = value
end
end
end
@@ -4405,7 +4427,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- commands.writestatus(category,format("%-25s modules: %2i default: %5s value: %5s",name,modules,default,value))
+ commands.writestatus(category,format("%-30s modules: %2i default: %5s value: %5s",name,modules,default,value))
end
end
commands.writestatus("","")
@@ -9415,7 +9437,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[file.extname(str)] or 'tex'
+ return suffixmap[file.extname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
@@ -9479,6 +9501,21 @@ local report_resolvers = logs.new("resolvers")
local resolvers = resolvers
+-- intermezzo
+
+local directive_cleanup = false directives.register("system.compile.cleanup", function(v) directive_cleanup = v end)
+local directive_strip = true directives.register("system.compile.strip", function(v) directive_strip = v end)
+
+local compile = utilities.lua.compile
+
+function utilities.lua.compile(luafile,lucfile,cleanup,strip)
+ if cleanup == nil then cleanup = directive_cleanup end
+ if strip == nil then strip = directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
+end
+
+-- end of intermezzo
+
caches = caches or { }
local caches = caches
@@ -9723,9 +9760,7 @@ function caches.savedata(filepath,filename,data,raw)
else
table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
end
- local cleanup = resolvers.booleanvariable("PURGECACHE", false)
- local strip = resolvers.booleanvariable("LUACSTRIP", true)
- utilities.lua.compile(tmaname, tmcname, cleanup, strip)
+ utilities.lua.compile(tmaname,tmcname)
end
-- moved from data-res:
@@ -9787,7 +9822,7 @@ function caches.savecontent(cachename,dataname,content)
if trace_locating then
report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname)
end
- if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip
+ if utilities.lua.compile(luaname,lucname) then
if trace_locating then
report_resolvers("'%s' compiled to '%s'",dataname,lucname)
end
@@ -9924,6 +9959,8 @@ local dangerous = resolvers.dangerous
local suffixmap = resolvers.suffixmap
local alternatives = resolvers.alternatives
+resolvers.defaultsuffixes = { "tex" } -- "mkiv", "cld" -- too tricky
+
resolvers.instance = resolvers.instance or nil -- the current one (slow access)
local instance = resolvers.instance or nil -- the current one (fast access)
@@ -10748,27 +10785,17 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
else
local forcedname, ok, suffix = "", false, fileextname(filename)
if suffix == "" then -- why
- if instance.format == "" then
- forcedname = filename .. ".tex"
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing standard filetype 'tex'")
- end
- result, ok = { forcedname }, true
- end
- else
- local format_suffixes = suffixes[instance.format]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s = format_suffixes[i]
- forcedname = filename .. "." .. s
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing format filetype '%s'", s)
- end
- result, ok = { forcedname }, true
- break
+ local format_suffixes = instance.format == "" and resolvers.defaultsuffixes or suffixes[instance.format]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s = format_suffixes[i]
+ forcedname = filename .. "." .. s
+ if resolvers.isreadable.file(forcedname) then
+ if trace_locating then
+ report_resolvers("no suffix, forcing format filetype '%s'", s)
end
+ result, ok = { forcedname }, true
+ break
end
end
end
@@ -10833,11 +10860,14 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
if instance.format == "" then
if ext == "" or not suffixmap[ext] then
- local forcedname = filename .. '.tex'
- wantedfiles[#wantedfiles+1] = forcedname
- filetype = resolvers.formatofsuffix(forcedname)
- if trace_locating then
- report_resolvers("forcing filetype '%s'",filetype)
+ local defaultsuffixes = resolvers.defaultsuffixes
+ for i=1,#defaultsuffixes do
+ local forcedname = filename .. '.' .. defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1] = forcedname
+ filetype = resolvers.formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolvers("forcing filetype '%s'",filetype)
+ end
end
else
filetype = resolvers.formatofsuffix(filename)
@@ -12591,6 +12621,9 @@ if not modules then modules = { } end modules ['luat-fmt'] = {
license = "see context related readme files"
}
+
+local format = string.format
+
-- helper for mtxrun
local quote = string.quote
@@ -12655,7 +12688,7 @@ function environment.make_format(name)
utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
-- compile stub file (does not save that much as we don't use this stub at startup any more)
local strip = resolvers.booleanvariable("LUACSTRIP", true)
- if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
logs.simple("using compiled initialization file: %s",lucstubname)
usedluastub = lucstubname
else
@@ -12668,7 +12701,7 @@ function environment.make_format(name)
return
end
-- generate format
- local command = string.format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
+ local command = format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
logs.simple("running command: %s\n",command)
os.spawn(command)
-- remove related mem files
@@ -12707,7 +12740,7 @@ function environment.run_format(name,data,more)
logs.simple("no luc/lua with name: %s",barename)
else
local q = string.quote
- local command = string.format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
+ local command = format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
logs.simple("running command: %s",command)
os.spawn(command)
end
diff --git a/tex/context/base/bibl-bib.mkiv b/tex/context/base/bibl-bib.mkiv
index 020f6e921..a2d194eee 100644
--- a/tex/context/base/bibl-bib.mkiv
+++ b/tex/context/base/bibl-bib.mkiv
@@ -455,9 +455,11 @@
\def\dodoloadbibtexpublicationalternative#1%
{\doonlyonce{#1}
- {\readsysfile{bxml-#1.mkiv}
+ {\startreadingfile
+ \readsysfile{bxml-#1.mkiv}
{\showmessage\m!publications{6}{bxml-#1}}
- {\showmessage\m!publications{1}{bxml-#1}}}}
+ {\showmessage\m!publications{1}{bxml-#1}}%
+ \stopreadingfile}}
\appendtoks
\doloadbibtexpublicationalternative
diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv
index 155872a10..3be410300 100644
--- a/tex/context/base/buff-ver.mkiv
+++ b/tex/context/base/buff-ver.mkiv
@@ -138,11 +138,15 @@
\let\noverbatimeop\ignoreendofpretty
\let\noverbatimsop\ignorebeginofpretty
+\setvalue{\??tp:\c!space:\v!on }{\let\obs\fastcontrolspace}
+\setvalue{\??tp:\c!space:\v!stretch}{\let\obs\specialstretchedspace
+ \let\specialobeyedspace\specialstretchedspace % I need to clean
+ \let\obeyedspace\specialstretchedspace} % up this mess.
+\setvalue{\??tp:\c!space:\v!normal }{\let\obs\specialobeyedspace}
+
\def\doinitializeverbatim % todo: combine all in one call is faster
{\ctxlua{buffers.visualizers.reset()}%
- \doifelse{\typingparameter\c!space}\v!on
- {\let\obs\fastcontrolspace}%
- {\let\obs\specialobeyedspace}%
+ \executeifdefined{\??tp:\c!space:\typingparameter\c!space}{\let\obs\specialobeyedspace}%
\edef\askedverbatimtab{\typingparameter\c!tab}%
\doifelse\askedverbatimtab\v!no
{\ctxlua{buffers.settablength(1)}}
@@ -441,11 +445,12 @@
%D works all right, but a decent hyphenation support of
%D \type{\tt} text will be implemented soon.
-\def\specialobeyedspace {\hskip\interwordspace\relax} % better than spaceskip
-\def\specialcontrolspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}
+\def\specialobeyedspace {\hskip\interwordspace\relax} % better than spaceskip
+\def\specialstretchedspace{\hskip.5\interwordspace\!!plus.125\interwordstretch\relax} % more but not less
+\def\specialcontrolspace {\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}
\def\obeyhyphens
- {\let\obeyedspace \specialobeyedspace
+ {\let\obeyedspace \specialobeyedspace % maybe \specialstretchedspace
\let\controlspace\specialcontrolspace
\spaceskip.25em\relax} % hm a bit of stretch !
@@ -462,6 +467,7 @@
\unexpanded\def\typ
{\bgroup
\let\@@tylines\v!hyphenated
+ \let\specialobeyedspace\specialstretchedspace
\futurelet\next\dodotype}
%D \macros
diff --git a/tex/context/base/cont-fil.tex b/tex/context/base/cont-fil.mkii
index b295872ca..b295872ca 100644
--- a/tex/context/base/cont-fil.tex
+++ b/tex/context/base/cont-fil.mkii
diff --git a/tex/context/base/cont-fil.mkiv b/tex/context/base/cont-fil.mkiv
new file mode 100644
index 000000000..b295872ca
--- /dev/null
+++ b/tex/context/base/cont-fil.mkiv
@@ -0,0 +1,124 @@
+%D \module
+%D [ file=cont-fil,
+%D version=1997.11.15,
+%D title=\CONTEXT\ Miscellaneous Macros,
+%D subtitle=File Synonyms,
+%D author=J. Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt File Synonyms}
+
+\definefilesynonym [chemie] [chemic]
+\definefilesynonym [chemics] [chemic]
+
+\definefilesynonym [unit] [units]
+\definefilesynonym [eenheid] [units]
+\definefilesynonym [einheit] [units]
+
+\definefilesynonym [pstric] [pstricks]
+\definefilesynonym [pstrick] [pstricks]
+
+\definefilesynonym [finance] [financ]
+
+\definefilesynonym [con-01] [contml] % will go away
+
+%definefilesynonym [sch-base] [sch-00]
+%definefilesynonym [sch-make] [sch-01]
+
+\definefilesynonym [dir-make] [dir-01]
+\definefilesynonym [dir-identify] [dir-05]
+
+\definefilesynonym [xml-format] [xml-01]
+\definefilesynonym [xml-pretty] [xml-02]
+\definefilesynonym [xml-analyze] [xml-11]
+
+\definefilesynonym [int-load] [set-11]
+\definefilesynonym [int-make] [set-12]
+
+\definefilesynonym [fig-base] [fig-00]
+\definefilesynonym [fig-make] [fig-01]
+\definefilesynonym [fig-fake] [fig-02]
+\definefilesynonym [fig-missing] [fig-06]
+
+\definefilesynonym [exi-interface] [exi-21]
+
+\definefilesynonym [res-make] [res-01]
+\definefilesynonym [res-base] [res-04]
+\definefilesynonym [res-crop] [res-07]
+\definefilesynonym [res-trace] [res-08]
+\definefilesynonym [res-log] [res-09]
+\definefilesynonym [res-identify] [res-12]
+
+\definefilesynonym [med-show] [res-50]
+
+\definefilesynonym [pre-general] [pre-00]
+
+\definefilesynonym [pre-original] [pre-01]
+\definefilesynonym [pre-green] [pre-02]
+\definefilesynonym [pre-funny] [pre-03]
+\definefilesynonym [pre-colorful] [pre-04]
+\definefilesynonym [pre-fuzzy] [pre-05]
+\definefilesynonym [pre-polish] [pre-06]
+\definefilesynonym [pre-spider] [pre-07]
+\definefilesynonym [pre-wonder] [pre-08]
+\definefilesynonym [pre-windows] [pre-09]
+\definefilesynonym [pre-grow] [pre-10]
+\definefilesynonym [pre-stack] [pre-11]
+\definefilesynonym [pre-arrows] [pre-12]
+\definefilesynonym [pre-writing] [pre-13]
+\definefilesynonym [pre-split] [pre-14]
+\definefilesynonym [pre-balls] [pre-15]
+\definefilesynonym [pre-knot] [pre-16]
+\definefilesynonym [pre-weird] [pre-17]
+\definefilesynonym [pre-shade] [pre-18]
+\definefilesynonym [pre-organic] [pre-19]
+\definefilesynonym [pre-speckle] [pre-20]
+\definefilesynonym [pre-zoom] [pre-21]
+\definefilesynonym [pre-cycle] [pre-22]
+\definefilesynonym [pre-super] [pre-23]
+
+%definefilesynonym [pre-more] [pre-24]
+%definefilesynonym [pre-more] [pre-25]
+
+\definefilesynonym [pre-more] [pre-26]
+
+%definefilesynonym [pre-more] [pre-27]
+%definefilesynonym [pre-more] [pre-28]
+%definefilesynonym [pre-more] [pre-29]
+%definefilesynonym [pre-more] [pre-30]
+
+\definefilesynonym [pre-stepwise] [pre-60]
+\definefilesynonym [pre-stepper] [pre-61]
+
+\definefilesynonym [pre-punk] [pre-70]
+\definefilesynonym [pre-random] [pre-71]
+
+\definefilesynonym [abr-pseudocaps] [abr-01]
+\definefilesynonym [abr-smallcaps] [abr-02]
+
+\definefilesynonym [chinese] [chi-00]
+\definefilesynonym [japanese] [jap-00]
+
+%definefilesynonym [chi-simplified] [chi-01]
+%definefilesynonym [chi-traditional] [chi-02]
+
+\definefilesynonym [greek] [grk-00]
+
+\definefilesynonym [unic-chi] [unic-cjk]
+\definefilesynonym [unic-jap] [unic-cjk]
+
+%definefilesynonym [practexjournal] [ptj-01]
+\definefilesynonym [pracjourn] [ptj-01]
+
+\definefilesynonym [maps] [map-10]
+\definefilesynonym [map-se] [map-10] % for some time
+
+\definefilesynonym [mml] [mathml]
+\definefilesynonym [cml] [chemml]
+
+\endinput
diff --git a/tex/context/base/cont-log.tex b/tex/context/base/cont-log.tex
index 9bfec2999..2d39c95e7 100644
--- a/tex/context/base/cont-log.tex
+++ b/tex/context/base/cont-log.tex
@@ -17,28 +17,11 @@
%D typeset with an lowered~E. From te beginning of \TEX,
%D authors of macro packages adapted this raising and lowering
%D style. In this module we define some of those logos.
-%D Watch the \type{cmr} detection hack.
-\unprotect
-
-\defconvertedargument\someCMRfont{cmr} % hm, we now have lm
-
-% \def\doifCMRfontelse#1#2%
-% {\doifinstringelse{\someCMRfont}{\fontname\font}
-% {\def\next{#1}}
-% {\def\next{#2}}%
-% \next}
+%D The Computer Modern detection hack is gone as we now have Latin
+%D Modern which has more kerning pairs.
-\def\doifCMRfontelse
- {\doifinstringelse\someCMRfont{\fontname\font}}
-
-\unexpanded\def\CMRkern
- {\doifCMRfontelse\kern{\scratchdimen=}}
-
-% \def\TeX
-% {T%
-% \kern-.1667em\lower.5ex\hbox{E}%
-% \kern-.125emX}
+\unprotect
\def\Mkern#1%
{{\setbox\scratchbox\hbox{M}\kern#1\wd\scratchbox}}
@@ -48,24 +31,9 @@
\Mkern{-.1667}\lower.5ex\hbox{E}%
\Mkern{-.125}X}
-\unexpanded\def\ConTeXt
- {C%
- \CMRkern-.0333emo%
- \CMRkern-.0333emn%
-% \CMRkern-.1667em\TeX%
- \CMRkern-.0667em\TeX%
- \CMRkern-.0333emt}
-
-\unexpanded\def\PPCHTeX
- {ppch\TeX}
-
-\unexpanded\def\PRAGMA
- {Pragma ADE}
-
-%\def\LaTeX
-% {L%
-% \kern-.30em\raise.3ex\hbox{\txx A}%
-% \kern-.18em\TeX}
+\unexpanded\def\ConTeXt{Con\TeX t}
+\unexpanded\def\PPCHTeX{ppch\TeX}
+\unexpanded\def\PRAGMA {Pragma ADE}
\unexpanded\def\LaTeX % requested by erik frambach
{{\setbox\scratchbox\hbox{L}%
@@ -193,7 +161,7 @@
%D CONTEXT, PPCHTEX,
%D AMSTEX, LATEX, LAMSTEX}
%D
-%D We define the funny written ones as well as th eless
+%D We define the funny written ones as well as the less
%D error prone upper case names (in \CONTEXT\ we tend to
%D write all user defined commands, like abbreviations, in
%D uppercase.)
@@ -216,13 +184,6 @@
%D \PiCTeX, \TaBlE, \ConTeXt, \PPCHTeX, \AmSTeX, \LaTeX,
%D \LamSTeX.
-% \def\TEXEDIT {\TeX edit}
-% \def\TEXFORM {\TeX form}
-% \def\TEXADRES {\TeX adres}
-% \def\TEXSPELL {\TeX spell}
-% \def\TEXUTIL {\TeX util}
-% \def\TEXEXEC {\TeX exec}
-
%D Some placeholders:
\unexpanded\def\eTeX {\mathematics{\varepsilon}-\TeX}
@@ -232,21 +193,6 @@
\unexpanded\def\metaTeX{meta\TeX}
\unexpanded\def\XeTeX {X\lower.5ex\hbox{\kern-.15em\mirror{E}}\kern-.1667em\TeX}
-% Better, since lm has a mirrored E (don't ask me why)
-
-% \unexpanded\def\XeTeX
-% {X\lower.5ex
-% \hbox
-% {\kern-.15em
-% \ifx\XeTeXcharglyph\undefined
-% \mirror{E}%
-% \else\ifcase\XeTeXcharglyph"018E\relax
-% \mirror{E}%
-% \else
-% \char"018E%
-% \fi}%
-% \kern-.1667em \TeX}
-
% Adapted from a patch by Mojca:
\def\@XeTeX@
@@ -294,7 +240,7 @@
\let\LuaTeX \luaTeX
\let\XETEX \XeTeX
-\unexpanded\def\MkApproved
+\unexpanded\def\MkApproved % joke, not used so it might move
{\dontleavehmode\rotate
[\c!rotation={\ifnum\texengine=\luatexengine\ctxlua{tex.write(45-45*\the\luatexversion/100)}\else0\fi},
\c!align=\v!middle,
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index 2defba6d7..79a2f5846 100644
--- a/tex/context/base/cont-new.mkii
+++ b/tex/context/base/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\enablemode[mkii]
+\enablemode[mkii] \enablemode[*mkii]
\long\def\startluacode#1\stopluacode{}
\long\def\ctxlua #1{}
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index 5cf80f8fc..3a3f1a94b 100644
--- a/tex/context/base/cont-new.tex
+++ b/tex/context/base/cont-new.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2010.10.14 13:14}
+\newcontextversion{2010.10.18 11:11}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii
index 36b2cd9e9..a6fff168c 100644
--- a/tex/context/base/context.mkii
+++ b/tex/context/base/context.mkii
@@ -63,9 +63,9 @@
%D modules.
\loadmarkfile{mult-ini}
-\loadcorefile{mult-fst}
-\loadcorefile{mult-sys}
-\loadcorefile{mult-def}
+\loadmarkfile{mult-fst}
+\loadmarkfile{mult-sys}
+\loadmarkfile{mult-def}
\loadmarkfile{mult-chk}
%D Now we're ready for some general support modules. These
@@ -74,18 +74,18 @@
\loadmarkfile{core-var}
\loadmarkfile{core-env}
-\loadcorefile{supp-box}
+\loadmarkfile{supp-box}
\loadmarkfile{supp-mrk}
-\loadcorefile{supp-vis}
-\loadcorefile{supp-fun}
+\loadmarkfile{supp-vis}
+\loadmarkfile{supp-fun}
%loadmarkfile{supp-eps}
\loadmarkfile{supp-spe}
\loadmarkfile{supp-ran}
\loadmarkfile{supp-mps}
\loadmarkfile{supp-tpi}
\loadmarkfile{supp-mat}
-\loadcorefile{supp-ali}
-\loadcorefile{supp-num}
+\loadmarkfile{supp-ali}
+\loadmarkfile{supp-num}
%D Verbatim typesetting is implemented in a separate class of
%D modules. The pretty typesetting modules are loaded at run
@@ -335,7 +335,7 @@
%D Language specific spacing.
-\loadcorefile{lang-spa}
+\loadmarkfile{lang-spa}
%D Bibliographies:
@@ -354,7 +354,7 @@
%D How about this:
-\loadcorefile{meta-xml}
+\loadmarkfile{meta-xml}
%D \TEX\ related logo's are always typeset in a special way.
%D Here they come:
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index fd9251caf..69441cb33 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -65,9 +65,9 @@
\loadmarkfile{char-act}
\loadmarkfile{mult-ini}
-\loadcorefile{mult-fst}
-\loadcorefile{mult-sys}
-\loadcorefile{mult-def}
+\loadmarkfile{mult-fst}
+\loadmarkfile{mult-sys}
+\loadmarkfile{mult-def}
\loadmarkfile{mult-chk}
\loadmarkfile{mult-cld}
\loadmarkfile{mult-aux}
@@ -98,15 +98,15 @@
\loadmarkfile{blob-ini} % not to be used, we only use a helper
-\loadcorefile{supp-box}
+\loadmarkfile{supp-box}
-\loadcorefile{supp-vis}
-\loadcorefile{supp-fun}
+\loadmarkfile{supp-vis}
+\loadmarkfile{supp-fun}
\loadmarkfile{supp-ran}
\loadmarkfile{supp-mat}
-\loadcorefile{supp-ali}
-\loadcorefile{supp-num}
+\loadmarkfile{supp-ali}
+\loadmarkfile{supp-num}
\loadmarkfile{typo-ini}
@@ -334,14 +334,14 @@
\loadmarkfile{node-bck} % overloads anch-pgr (experimental and undocumented)
-\loadcorefile{lang-spa}
+\loadmarkfile{lang-spa} % will become obsolete
\loadmarkfile{bibl-bib}
\loadmarkfile{bibl-tra}
%loadmarkfile{x-xtag} % no longer preloaded
-\loadcorefile{meta-xml}
+\loadmarkfile{meta-xml}
\loadcorefile{cont-log}
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 48f31836c..0b70197c7 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2010.10.14 13:14}
+\edef\contextversion{2010.10.18 11:11}
%D For those who want to use this:
diff --git a/tex/context/base/core-env.lua b/tex/context/base/core-env.lua
index 0122f6bee..02fa4f744 100644
--- a/tex/context/base/core-env.lua
+++ b/tex/context/base/core-env.lua
@@ -11,12 +11,16 @@ if not modules then modules = { } end modules ['core-env'] = {
--
-- if tex.modes['xxxx'] then .... else .... end
-local csname_id, texcount = token.csname_id, tex.count
+local csname_id, texcount, create = token.csname_id, tex.count, token.create
local undefined = csname_id("*undefined*crap*")
+local iftrue = create("iftrue")[2] -- inefficient hack
-tex.modes = { } local modes = { }
-tex.constants = { } local constants = { }
+tex.modes = { } local modes = { }
+tex.systemmodes = { } local systemmodes = { }
+tex.constants = { }
+tex.conditionals = { }
+tex.ifs = { }
setmetatable(tex.modes, { __index = function(t,k)
local m = modes[k]
@@ -33,14 +37,29 @@ setmetatable(tex.modes, { __index = function(t,k)
end
end })
-setmetatable(tex.constants, { __index = function(t,k)
- local m = constants[k]
+setmetatable(tex.systemmodes, { __index = function(t,k)
+ local m = systemmodes[k]
if m then
return m()
- elseif csname_id(k) == undefined then
- return false
else
- constants[k] = function() return texcount[k] >= 1 end
- return texcount[k] >= 1
+ local n = "mode*" .. k
+ if csname_id(n) == undefined then
+ return false
+ else
+ systemmodes[k] = function() return texcount[n] >= 1 end
+ return texcount[n] >= 1
+ end
end
end })
+
+setmetatable(tex.constants, { __index = function(t,k)
+ return csname_id(k) ~= undefined and texcount[k] or 0
+end })
+
+setmetatable(tex.conditionals, { __index = function(t,k) -- 0 == true
+ return csname_id(k) ~= undefined and texcount[k] == 0
+end })
+
+setmetatable(tex.ifs, { __index = function(t,k)
+ return csname_id(k) ~= undefined and create(k)[2] == iftrue -- inefficient, this create, we need a helper
+end })
diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv
index b5631f151..df3b6e542 100644
--- a/tex/context/base/core-env.mkiv
+++ b/tex/context/base/core-env.mkiv
@@ -78,6 +78,26 @@
{\ifcsname\@mode@\systemmodeprefix#1\endcsname\else\donewmode{\systemmodeprefix#1}\fi
\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode}
+% \def\dosetsystemmode#1%
+% {\csname\@mode@\systemmodeprefix#1\endcsname\enabledmode}
+%
+% \def\doresetsystemmode#1%
+% {\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode}
+
+% demo: trialtypesetting is a systemmode as an if
+
+\newsystemmode{trialtypesetting}
+
+\expandafter\let\expandafter\@@trialtypesetting\csname\@mode@\systemmodeprefix trialtypesetting\endcsname % private !
+
+\appendtoks
+ \@@trialtypesetting\enabledmode
+\to \everysettrialtypesetting
+
+\appendtoks
+ \@@trialtypesetting\disabledmode
+\to \everyresettrialtypesetting
+
% user ones
\unexpanded\def\preventmode{\unprotect\dopreventmode}
diff --git a/tex/context/base/core-job.mkiv b/tex/context/base/core-job.mkiv
index 85f20db12..d0f4cd417 100644
--- a/tex/context/base/core-job.mkiv
+++ b/tex/context/base/core-job.mkiv
@@ -80,7 +80,7 @@
{\reportprotectionstate
\readsysfile\f!newfilename{\showmessage\m!systems2\f!newfilename}\donothing
%\readsysfile\f!oldfilename{\showmessage\m!systems2\f!oldfilename}\donothing
- \loadallsystemfiles\f!filfilename
+ \loadallsystemfiles\f!filfilename % this will move to lua and get preloaded
\donothing
\loadallsystemfiles\f!sysfilename
{\loadallsystemfiles{\f!sysfilename.rme}\donothing % new, fall back
diff --git a/tex/context/base/core-mis.mkiv b/tex/context/base/core-mis.mkiv
index 771dd3da6..ff69f0011 100644
--- a/tex/context/base/core-mis.mkiv
+++ b/tex/context/base/core-mis.mkiv
@@ -1812,6 +1812,7 @@
\doifelse{\combinationparameter\c!height}\v!fit
\vbox {\vbox to \combinationparameter\c!height}%
\bgroup
+\let\combination\empty % permits \combination{}{} handy for cld
\expanded{\dodostartcombination[\currentcombinationspec]}}
\long\def\dodostartcombination[#1*#2*#3]%
diff --git a/tex/context/base/core-sys.mkiv b/tex/context/base/core-sys.mkiv
index 7b1f2825a..f5bb45e35 100644
--- a/tex/context/base/core-sys.mkiv
+++ b/tex/context/base/core-sys.mkiv
@@ -38,14 +38,14 @@
%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}}
\newlinechar=10 \edef\outputnewlinechar{^^J}
-\edef\operatingsystem {\ctxlua{tex.write(os.platform)}}
-
-\def\jobfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.jobfilename or "")}}
-\def\jobfilesuffix {\ctxlua{tex.sprint(tex.texcatcodes,environment.jobfilesuffix or "")}}
-\def\inputfilebarename{\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilebarename or "")}}
-\def\inputfilesuffix {\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilesuffix or "")}}
-\def\inputfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilename or "")}}
-\def\outputfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.outputfilename or "")}}
+\edef\operatingsystem {\ctxwrite {os.platform}}
+
+\def\jobfilename {\ctxsprint{environment.jobfilename or ""}}
+\def\jobfilesuffix {\ctxsprint{environment.jobfilesuffix or ""}}
+\def\inputfilebarename{\ctxsprint{environment.inputfilebarename or ""}}
+\def\inputfilesuffix {\ctxsprint{environment.inputfilesuffix or ""}}
+\def\inputfilename {\ctxsprint{environment.inputfilename or ""}}
+\def\outputfilename {\ctxsprint{environment.outputfilename or ""}}
\def\initializenewlinechar
{\bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup}
diff --git a/tex/context/base/core-var.mkiv b/tex/context/base/core-var.mkiv
index 6238cb7b8..45a593ee7 100644
--- a/tex/context/base/core-var.mkiv
+++ b/tex/context/base/core-var.mkiv
@@ -144,9 +144,7 @@
%D We disable trial typesetting in the output routine,
%D just to be sure.
-\newif\iftrialtypesetting
-
-\prependtoks \trialtypesettingfalse \to \everybeforepagebody
+\prependtoks \resettrialtypesetting \to \everybeforepagebody
%D \macros
%D {ifinpagebody,ifinsidecolumns,ifdoublesided,ifsinglesided}
diff --git a/tex/context/base/data-env.lua b/tex/context/base/data-env.lua
index 19c10fde0..ea6faeb6c 100644
--- a/tex/context/base/data-env.lua
+++ b/tex/context/base/data-env.lua
@@ -144,7 +144,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[file.extname(str)] or 'tex'
+ return suffixmap[file.extname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua
index 4a61ae61f..97ab8ce5d 100644
--- a/tex/context/base/data-res.lua
+++ b/tex/context/base/data-res.lua
@@ -58,6 +58,8 @@ local dangerous = resolvers.dangerous
local suffixmap = resolvers.suffixmap
local alternatives = resolvers.alternatives
+resolvers.defaultsuffixes = { "tex" } -- "mkiv", "cld" -- too tricky
+
resolvers.instance = resolvers.instance or nil -- the current one (slow access)
local instance = resolvers.instance or nil -- the current one (fast access)
@@ -884,27 +886,17 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
else
local forcedname, ok, suffix = "", false, fileextname(filename)
if suffix == "" then -- why
- if instance.format == "" then
- forcedname = filename .. ".tex"
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing standard filetype 'tex'")
- end
- result, ok = { forcedname }, true
- end
- else
- local format_suffixes = suffixes[instance.format]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s = format_suffixes[i]
- forcedname = filename .. "." .. s
- if resolvers.isreadable.file(forcedname) then
- if trace_locating then
- report_resolvers("no suffix, forcing format filetype '%s'", s)
- end
- result, ok = { forcedname }, true
- break
+ local format_suffixes = instance.format == "" and resolvers.defaultsuffixes or suffixes[instance.format]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s = format_suffixes[i]
+ forcedname = filename .. "." .. s
+ if resolvers.isreadable.file(forcedname) then
+ if trace_locating then
+ report_resolvers("no suffix, forcing format filetype '%s'", s)
end
+ result, ok = { forcedname }, true
+ break
end
end
end
@@ -972,11 +964,14 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
if instance.format == "" then
if ext == "" or not suffixmap[ext] then
- local forcedname = filename .. '.tex'
- wantedfiles[#wantedfiles+1] = forcedname
- filetype = resolvers.formatofsuffix(forcedname)
- if trace_locating then
- report_resolvers("forcing filetype '%s'",filetype)
+ local defaultsuffixes = resolvers.defaultsuffixes
+ for i=1,#defaultsuffixes do
+ local forcedname = filename .. '.' .. defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1] = forcedname
+ filetype = resolvers.formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolvers("forcing filetype '%s'",filetype)
+ end
end
else
filetype = resolvers.formatofsuffix(filename)
diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua
index e4bef66d8..526d271bd 100644
--- a/tex/context/base/data-tmp.lua
+++ b/tex/context/base/data-tmp.lua
@@ -33,6 +33,21 @@ local report_resolvers = logs.new("resolvers")
local resolvers = resolvers
+-- intermezzo
+
+local directive_cleanup = false directives.register("system.compile.cleanup", function(v) directive_cleanup = v end)
+local directive_strip = true directives.register("system.compile.strip", function(v) directive_strip = v end)
+
+local compile = utilities.lua.compile
+
+function utilities.lua.compile(luafile,lucfile,cleanup,strip)
+ if cleanup == nil then cleanup = directive_cleanup end
+ if strip == nil then strip = directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
+end
+
+-- end of intermezzo
+
caches = caches or { }
local caches = caches
@@ -277,9 +292,7 @@ function caches.savedata(filepath,filename,data,raw)
else
table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
end
- local cleanup = resolvers.booleanvariable("PURGECACHE", false)
- local strip = resolvers.booleanvariable("LUACSTRIP", true)
- utilities.lua.compile(tmaname, tmcname, cleanup, strip)
+ utilities.lua.compile(tmaname,tmcname)
end
-- moved from data-res:
@@ -341,7 +354,7 @@ function caches.savecontent(cachename,dataname,content)
if trace_locating then
report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname)
end
- if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip
+ if utilities.lua.compile(luaname,lucname) then
if trace_locating then
report_resolvers("'%s' compiled to '%s'",dataname,lucname)
end
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
index 630430e77..bb5661c19 100644
--- a/tex/context/base/font-ini.mkiv
+++ b/tex/context/base/font-ini.mkiv
@@ -2781,7 +2781,7 @@
{\dodoubleargument\dofontfeatureslist}
\def\dofontfeatureslist[#1][#2]% todo: arg voor type
- {\ctxlua{tex.sprint(tex.ctxcatcodes,fonts.definers.specifiers.contexttostring("#1","otf","\luaescapestring{#2}","yes","no",true,{"number"}))}}
+ {\ctxsprint{fonts.definers.specifiers.contexttostring("#1","otf","\luaescapestring{#2}","yes","no",true,{"number"})}}
\attribute\zerocount\zerocount % first in list, so fast match
@@ -3028,7 +3028,7 @@
\unexpanded\def\definealternativestyle
{\dotripleempty\dodefinealternativestyle}
-\unexpanded\def\definestyle{\definealternativestyle}
+\unexpanded\def\definestyle{\definealternativestyle} % later redefined
%D Maybe too geneneric, but probably ok is the following. (Maybe one
%D day we will use a dedicated grouped command for styles.)
@@ -3084,13 +3084,15 @@
%D conversion by saying \type{\redoconvertfont}.
% subtle ... \expandafter is needed else problems with lookahead caps
+%
+% this will be cleaned up
\def\@@dodoconvertfont{\csname\@letter@ \p!defined\expandafter\endcsname\gobbleoneargument}
\def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname}
\def\@@redoconvertfont{\csname \p!defined\expandafter\endcsname\gobbleoneargument}
% beware: p!defined can contain crap like \edef crap {...} and such
-% so we need to pass #1 as well
+% so we need to pass #1 as well .. no longer needed in luatex
\unexpanded\def\dodoconvertfont#1% #2% we need the protection
{\edef\p!defined{#1}%
@@ -3872,15 +3874,83 @@
%D New commands (not yet interfaced):
-\def\style[#1]% for inline usage, like \color
- {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}}
+% \def\style[#1]% for inline usage, like \color
+% {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}}
+%
+% \unexpanded\def\startstyle[#1]%
+% {\begingroup
+% \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}
+%
+% \unexpanded\def\stopstyle
+% {\endgroup}
+
+% definitions
+
+\def\definestyle
+ {\dotripleargument\dodefinestyle}
+
+\def\dodefinestyle[#1][#2][#3]%
+ {\doifassignmentelse{#2}\dododefinestyle\definealternativestyle[#1][#2][#3]}
+
+\def\dododefinestyle[#1][#2][#3]% no commalist and for the moment #3 is ignored
+ {\getparameters[\??cf:#1][\c!style=,\c!color=,#2]%
+ \setuvalue{\e!start#1}{\begingroup\dostartattributes{\??cf:#1}\c!style\c!color}%
+ \setuvalue{\e!stop #1}{\dostopattributes\endgroup}%
+ \setuvalue {#1}{\groupedcommand{\dostartattributes{\??cf:#1}\c!style\c!color}\dostopattributes}}
+
+\def\setupstyle
+ {\dotripleargument\dosetupstyle}
+
+\def\dosetupstyle[#1][#2][#3]% no commalist and for the moment #3 is ignored
+ {\ifcsname\??cf:#1\c!style\endcsname
+ \getparameters[\??cf:#1][#2]%
+ \else
+ \getparameters[\??cf:#1][\c!style,\c!color=,#2]% so we define but without commands (todo for all define related things)
+ \fi}
+
+% commands
+
+\unexpanded\def\style[#1]%
+ {\csname\ifcsname#1\endcsname n\else\ifcsname\??cf:#1\c!style\endcsname c\else d\fi\fi ostyle\endcsname{#1}}
+
+\def\nostyle#1{\csname#1\endcsname}
+\def\costyle#1{\groupedcommand{\dostartattributes{\??cf:#1}\c!style\c!color}\dostopattributes}
+\def\dostyle#1{\doifassignmentelse{#1}\dostyleassignment\dostyledirect{#1}}
+
+\def\dostyleassignment#1%
+ {\groupedcommand
+ {\getparameters[\??cf][\c!style,\c!color=,#1]%
+ \dostartattributes\??cf\c!style\c!color}
+ {\dostopattributes}}
+
+\def\dostyledirect#1%
+ {\groupedcommand
+ {\definedfont[#1]}
+ {}}
+
+% environments
\unexpanded\def\startstyle[#1]%
{\begingroup
- \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}
+ \csname\ifcsname#1\endcsname n\else\ifcsname\??cf:#1\c!style\endcsname c\else d\fi\fi ostyless\endcsname{#1}}
\unexpanded\def\stopstyle
- {\endgroup}
+ {\dostopstyle
+ \endgroup
+ \autoinsertnextspace} % will be configurable, maybe also in \definestartstop
+
+\def\nostyless#1{\let\dostopstyle\donothing\csname#1\endcsname}
+\def\costyless#1{\let\dostopstyle\dostopattributes\dostartattributes{\??cf:#1}\c!style\c!color}
+\def\dostyless#1{\doifassignmentelse{#1}\dostylessassignment\dostylessdirect{#1}}
+
+\def\dostylessassignment#1%
+ {\let\dostopstyle\dostopattributes
+ \getparameters[\??cf][\c!style,\c!color=,#1]%
+ \dostartattributes\??cf\c!style\c!color}
+
+\def\dostylessdirect#1%
+ {\let\dostopstyle\donothing
+ \definedfont[#1]\relax}
%D Still experimental (might even go away).
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index 8a1791d9e..085950dfc 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -43,6 +43,7 @@ local otf = fonts.otf
local tfm = fonts.tfm
local fontdata = fonts.ids
+local chardata = characters.data
otf.features = otf.features or { }
otf.features.list = otf.features.list or { }
@@ -756,8 +757,13 @@ actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this
end
local width = glyph.width
widths[width] = (widths[width] or 0) + 1
- if glyph.class == "mark" then
- marks[glyph.unicode] = true
+ local class = glyph.class
+ local unicode = glyph.unicode
+ if class == "mark" then
+ marks[unicode] = true
+ -- elseif chardata[unicode].category == "mn" then
+ -- marks[unicode] = true
+ -- glyph.class = "mark"
end
local a = glyph.altuni if a then glyph.altuni = nil end
local d = glyph.dependents if d then glyph.dependents = nil end
diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua
index 651ed7157..5f290edb1 100644
--- a/tex/context/base/grph-inc.lua
+++ b/tex/context/base/grph-inc.lua
@@ -75,8 +75,12 @@ function img.totable(imgtable)
return result
end
-function img.serialize(i)
- return table.serialize(img.totable(i))
+function img.serialize(i,...)
+ return table.serialize(img.totable(i),...)
+end
+
+function img.print(i,...)
+ return table.print(img.totable(i),...)
end
function img.clone(i,data)
@@ -142,7 +146,7 @@ figures.cachepaths = allocate {
figures.paths = allocate(table.copy(figures.localpaths))
figures.order = allocate{
- "pdf", "mps", "jpg", "png", "jbig", "svg", "eps", "gif", "mov", "buffer", "tex",
+ "pdf", "mps", "jpg", "png", "jbig", "svg", "eps", "gif", "mov", "buffer", "tex", "cld",
}
figures.formats = allocate{
@@ -157,6 +161,7 @@ figures.formats = allocate{
["mov"] = { list = { "mov", "flv", "mp4" } }, -- "avi" is not supported
["buffer"] = { list = { "tmp", "buffer", "buf" } },
["tex"] = { list = { "tex" } },
+ ["cld"] = { list = { "cld" } },
}
function figures.setlookups()
@@ -355,6 +360,8 @@ end
local defaultformat = "pdf"
local defaultprefix = "m_k_i_v_"
+-- todo: local path or cache path
+
local function register(askedname,specification)
if specification then
local format = specification.format
@@ -384,6 +391,7 @@ local function register(askedname,specification)
if converter[newformat] then
converter = converter[newformat]
else
+ converter = nil
newformat = defaultformat
end
end
@@ -392,6 +400,7 @@ local function register(askedname,specification)
end
if converter then
local oldname = specification.fullname
+local oldname = specification.foundname
local newpath = file.dirname(oldname)
local oldbase = file.basename(oldname)
local newbase = file.removesuffix(oldbase)
@@ -401,6 +410,12 @@ local function register(askedname,specification)
else
newbase = defaultprefix .. newbase
end
+ if not file.is_writable(newpath) then
+ if trace_conversion then
+ report_graphics("[ath '%s'is not writable, forcing conversion path '.' ",newpath)
+ end
+ newpath = "."
+ end
local subpath = specification.subpath or figures.cachepaths.subpath
if subpath and subpath ~= "" and subpath ~= "." then
newpath = newpath .. "/" .. subpath
@@ -812,6 +827,12 @@ function checkers.generic(data)
du.width = figure.width
du.height = figure.height
du.pages = figure.pages
+ du.depth = figure.depth or 0
+ du.colordepth = figure.colordepth or 0
+ du.xresolution = figure.xres or 0
+ du.yresolution = figure.yres or 0
+ du.xsize = figure.xsize or 0
+ du.ysize = figure.ysize or 0
ds.private = figure
ds.hash = hash
end
@@ -928,17 +949,6 @@ function checkers.mps(data)
end
includers.mps = includers.nongeneric
--- -- -- buffer -- -- --
-
-function existers.buffer(askedname)
- askedname = file.nameonly(askedname)
- return buffers.exists(askedname) and askedname
-end
-function checkers.buffer(data)
- return checkers.nongeneric(data,format("\\docheckfigurebuffer{%s}", file.nameonly(data.used.fullname)))
-end
-includers.buffers = includers.nongeneric
-
-- -- -- tex -- -- --
function existers.tex(askedname)
@@ -950,6 +960,22 @@ function checkers.tex(data)
end
includers.tex = includers.nongeneric
+-- -- -- buffer -- -- --
+
+existers.buffer = existers.tex
+function checkers.buffer(data)
+ return checkers.nongeneric(data,format("\\docheckfigurebuffer{%s}", file.nameonly(data.used.fullname)))
+end
+includers.buffers = includers.nongeneric
+
+-- -- -- cld -- -- --
+
+existers.cld = existers.tex
+function checkers.cld(data)
+ return checkers.nongeneric(data,format("\\docheckfigurecld{%s}", data.used.fullname))
+end
+includers.cld = includers.nongeneric
+
-- -- -- converters -- -- --
local function makeoptions(options)
diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv
index b456cadf8..e74c437a0 100644
--- a/tex/context/base/grph-inc.mkiv
+++ b/tex/context/base/grph-inc.mkiv
@@ -88,13 +88,20 @@
\def\figurenaturalwidth {\ctxlua{figures.tprint("used","width", \number\dimexpr\defaultfigurewidth \relax)}sp}
\def\figurenaturalheight {\ctxlua{figures.tprint("used","height",\number\dimexpr\defaultfigureheight\relax)}sp}
+\def\figurexresolution {\ctxlua{figures.tprint("used","xresolution",0)}}
+\def\figureyresolution {\ctxlua{figures.tprint("used","yresolution",0)}}
+\def\figurexsize {\ctxlua{figures.tprint("used","xsize",0)}}
+\def\figureysize {\ctxlua{figures.tprint("used","ysize",0)}}
+\def\figurecolordepth {\ctxlua{figures.tprint("used","colordepth",0)}}
+\def\figuredepth {\ctxlua{figures.tprint("used","depth",0)}}
-\def\figurefilepath {\ctxlua{tex.sprint(tex.ctxcatcodes,file.dirname (figures.get("used","fullname")))}}
-\def\figurefilename {\ctxlua{tex.sprint(tex.ctxcatcodes,file.nameonly(figures.get("used","fullname")))}}
-\def\figurefiletype {\ctxlua{tex.sprint(tex.ctxcatcodes,file.extname (figures.get("used","fullname")))}}
\def\figurefullname {\ctxlua{figures.tprint("used","fullname")}}
\def\noffigurepages {\ctxlua{figures.tprint("used","pages",0)}}
+\def\figurefilepath {\ctxsprint{file.dirname (figures.get("used","fullname"))}}
+\def\figurefilename {\ctxsprint{file.nameonly(figures.get("used","fullname"))}}
+\def\figurefiletype {\ctxsprint{file.extname (figures.get("used","fullname"))}}
+
\let\naturalfigurewidth \figurenaturalwidth
\let\naturalfigureheight \figurenaturalheight
@@ -207,8 +214,12 @@
\def\doprocessmpslikefigure#1% retrofit into mkii
{\global\setbox\foundexternalfigure\vbox{\convertMPtoPDF{#1}11}}
+\def\doprocesscldlikefigure#1%
+ {\global\setbox\foundexternalfigure\vbox{\cldprocessfile{#1}}}
+
\def\docheckfigurebuffer #1{\doprocesstexlikefigure{\getbuffer[#1]}}
\def\docheckfiguretex #1{\doprocesstexlikefigure{\input#1\relax}}
+\def\docheckfigurecld #1{\doprocesscldlikefigure{#1}} % we can always add cldrun
\def\docheckfiguremps #1{\doprocessmpslikefigure{#1}}
\def\docheckfiguremprun #1#2{\doprocesstexlikefigure{\useMPrun{#1}{#2}}}
diff --git a/tex/context/base/grph-wnd.lua b/tex/context/base/grph-wnd.lua
new file mode 100644
index 000000000..0047651bf
--- /dev/null
+++ b/tex/context/base/grph-wnd.lua
@@ -0,0 +1,47 @@
+if not modules then modules = { } end modules ['grph-wnd'] = {
+ version = 1.001,
+ comment = "companion to grph-inc.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Thanks to Luigi Scarso for making graphic magic work in luatex.
+--
+-- \externalfigure[hacker.jpeg][width=4cm,conversion=gray.jpg]
+
+local converters, suffixes = figures.converters, figures.suffixes
+
+local trace_conversion = false trackers.register("figures.conversion", function(v) trace_conversion = v end)
+
+local report_graphics = logs.new("graphics")
+
+local function togray(oldname,newname)
+ if lfs.isfile(oldname) then
+ require("gmwand")
+ if trace_conversion then
+ report_graphics("converting '%s' to '%s' using gmwand",oldname,newname)
+ end
+ gmwand.InitializeMagick("./") -- What does this path do?
+ local wand = gmwand.NewMagickWand()
+ gmwand.MagickReadImage(wand,oldname)
+ gmwand.MagickSetImageColorspace(wand,gmwand.GRAYColorspace)
+ gmwand.MagickWriteImages(wand,newname,1)
+ gmwand.DestroyMagickWand(wand)
+ else
+ report_graphics("unable to convert '%s' to '%s' using gmwand",oldname,newname)
+ end
+end
+
+local formats = { "png", "jpg", "gif" }
+
+for i=1,#formats do
+ local oldformat = formats[i]
+ local newformat = "gray." .. oldformat
+ if trace_conversion then
+ report_graphics("installing converter: %s -> %s",oldformat,newformat)
+ end
+ converters[oldformat] = converters[oldformat] or { }
+ converters[oldformat][newformat] = togray
+ suffixes [newformat] = oldformat
+end
diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua
index 8a7340905..08acb6040 100644
--- a/tex/context/base/l-number.lua
+++ b/tex/context/base/l-number.lua
@@ -7,7 +7,8 @@ if not modules then modules = { } end modules ['l-number'] = {
}
local tostring = tostring
-local format, floor, insert, match = string.format, math.floor, table.insert, string.match
+local format, floor, insert, match = string.format, math.floor, string.match
+local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
number = number or { }
@@ -75,3 +76,16 @@ end
function number.clearbit(x, p)
return hasbit(x, p) and x - p or x
end
+
+function number.tobitstring(n)
+ if n == 0 then
+ return "0"
+ else
+ local t = { }
+ while n > 0 do
+ insert(t,1,n % 2 > 0 and 1 or 0)
+ n = floor(n/2)
+ end
+ return concat(t)
+ end
+end
diff --git a/tex/context/base/lang-spa.tex b/tex/context/base/lang-spa.mkii
index f6e22aa51..f6e22aa51 100644
--- a/tex/context/base/lang-spa.tex
+++ b/tex/context/base/lang-spa.mkii
diff --git a/tex/context/base/lang-spa.mkiv b/tex/context/base/lang-spa.mkiv
new file mode 100644
index 000000000..2cc88b84f
--- /dev/null
+++ b/tex/context/base/lang-spa.mkiv
@@ -0,0 +1,76 @@
+%D \module
+%D [ file=lang-spa,
+%D version=2002.04.17,
+%D title=\CONTEXT\ Language Macros,
+%D subtitle=Spacing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Language Macros / Spacing}
+
+%D This module was created in the process of enhancing
+%D support for French (with the help of Daniel Flipo).
+%D
+%D This will (or already has) become obsolete!
+
+\unprotect
+
+\definehspace [\s!fr] [quotation] [\flexiblespaceamount{.8}{.3}{.8}]
+\definehspace [\s!fr] [sentence] [\fixedspaceamount{1}]
+
+%definehspace [\s!fr] [quote] [\flexiblespaceamount{.8}{.3}{.8}]
+%definehspace [\s!fr] [speech] [\flexiblespaceamount{.8}{.3}{.8}]
+
+\definehspace [\s!fr] [interquotation] [\zeropoint]
+\definehspace [\s!fr] [intersentence] [\zeropoint]
+
+\definehspace [\string :] [\zeropoint]
+\definehspace [\string ;] [\zeropoint]
+\definehspace [\string !] [\zeropoint]
+\definehspace [\string ?] [\zeropoint]
+
+\definehspace [\s!fr] [\string :] [\spaceamount]
+\definehspace [\s!fr] [\string ;] [.16667em]
+\definehspace [\s!fr] [\string !] [.16667em]
+\definehspace [\s!fr] [\string ?] [.16667em]
+
+%D Alternative discretionary handlers:
+
+\definetextmodediscretionary :
+ {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{:}:}
+
+\definetextmodediscretionary ;
+ {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{;};}
+
+\definetextmodediscretionary ?
+ {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{?}?}
+
+\definetextmodediscretionary !
+ {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{!}!}
+
+%D \startbuffer
+%D \mainlanguage[en] \quotation{test \quotation{test} test}\par
+%D \mainlanguage[nl] \quotation{test \quotation{test} test}\par
+%D \mainlanguage[fr] \quotation{test \quotation{test} test}\par
+%D
+%D \mainlanguage[en] \quotation{\quotation{test} test}\par
+%D \mainlanguage[nl] \quotation{\quotation{test} test}\par
+%D \mainlanguage[fr] \quotation{\quotation{test} test}\par
+%D
+%D \mainlanguage[en] |<|test |<|test|>| test|>| \par
+%D \mainlanguage[nl] |<|test |<|test|>| test|>| \par
+%D \mainlanguage[fr] |<|test |<|test|>| test|>| \par
+%D
+%D \mainlanguage[en] |<||<|test|>| test|>| \par
+%D \mainlanguage[nl] |<||<|test|>| test|>| \par
+%D \mainlanguage[fr] |<||<|test|>| test|>| \par
+%D \stopbuffer
+%D
+%D \typebuffer {\getbuffer}
+
+\protect \endinput
diff --git a/tex/context/base/luat-cod.mkiv b/tex/context/base/luat-cod.mkiv
index f2495a285..6605f8d83 100644
--- a/tex/context/base/luat-cod.mkiv
+++ b/tex/context/base/luat-cod.mkiv
@@ -44,6 +44,8 @@
\def\ctxdirectlua{\directlua\zerocount}
\def\ctxlatelua {\latelua \zerocount}
+\def\ctxsprint #1{\directlua\zerocount{tex.sprint(tex.ctxcatcodes,#1)}} % saves tokens
+\def\ctxwrite #1{\directlua\zerocount{tex.write(#1)}} % saves tokens
%D Take your choice \unknown
diff --git a/tex/context/base/luat-fmt.lua b/tex/context/base/luat-fmt.lua
index 0b7221873..42f75a1ba 100644
--- a/tex/context/base/luat-fmt.lua
+++ b/tex/context/base/luat-fmt.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['luat-fmt'] = {
license = "see context related readme files"
}
+
+local format = string.format
+
-- helper for mtxrun
local quote = string.quote
@@ -70,7 +73,7 @@ function environment.make_format(name)
utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
-- compile stub file (does not save that much as we don't use this stub at startup any more)
local strip = resolvers.booleanvariable("LUACSTRIP", true)
- if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
logs.simple("using compiled initialization file: %s",lucstubname)
usedluastub = lucstubname
else
@@ -83,7 +86,7 @@ function environment.make_format(name)
return
end
-- generate format
- local command = string.format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
+ local command = format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
logs.simple("running command: %s\n",command)
os.spawn(command)
-- remove related mem files
@@ -122,7 +125,7 @@ function environment.run_format(name,data,more)
logs.simple("no luc/lua with name: %s",barename)
else
local q = string.quote
- local command = string.format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
+ local command = format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
logs.simple("running command: %s",command)
os.spawn(command)
end
diff --git a/tex/context/base/meta-xml.tex b/tex/context/base/meta-xml.mkii
index f6f81f767..f6f81f767 100644
--- a/tex/context/base/meta-xml.tex
+++ b/tex/context/base/meta-xml.mkii
diff --git a/tex/context/base/meta-xml.mkiv b/tex/context/base/meta-xml.mkiv
new file mode 100644
index 000000000..6ce9612cc
--- /dev/null
+++ b/tex/context/base/meta-xml.mkiv
@@ -0,0 +1,20 @@
+%D \module
+%D [ file=meta-xml,
+%D version=2002.11.27,
+%D title=\METAPOST\ Graphics,
+%D subtitle=XML Hacks,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{MetaPost Graphics / XML Hacks}
+
+\unprotect
+
+% not needed in mkiv
+
+\protect \endinput
diff --git a/tex/context/base/mult-cld.lua b/tex/context/base/mult-cld.lua
index 382370dea..a9fbab0bc 100644
--- a/tex/context/base/mult-cld.lua
+++ b/tex/context/base/mult-cld.lua
@@ -15,6 +15,7 @@ if not modules then modules = { } end modules ['mult-cld'] = {
--
-- Todo: optional checking against interface
-- Todo: coroutine trickery
+-- Todo: maybe use txtcatcodes
-- tflush needs checking ... sort of weird that it's not a table
@@ -22,7 +23,7 @@ context = context or { }
local context = context
local format, concat = string.format, table.concat
-local next, type, tostring = next, type, tostring
+local next, type, tostring, setmetatable = next, type, tostring, setmetatable
local insert, remove = table.insert, table.remove
local tex = tex
@@ -32,9 +33,16 @@ local textprint = tex.tprint
local texprint = tex.print
local texiowrite = texio.write
local texcount = tex.count
+
+local isnode = node.is_node
+local writenode = node.write
+
local ctxcatcodes = tex.ctxcatcodes
local prtcatcodes = tex.prtcatcodes
+local texcatcodes = tex.texcatcodes
+local txtcatcodes = tex.txtcatcodes
local vrbcatcodes = tex.vrbcatcodes
+local xmlcatcodes = tex.xmlcatcodes
local flush = texsprint
@@ -52,13 +60,17 @@ local function _flush_(n)
local sn = _stack_[n]
if not sn then
report_cld("data with id %s cannot be found on stack",n)
- elseif not sn() and texcount.trialtypesettingmode == 0 then
+ elseif not sn() and texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private!
_stack_[n] = nil
else
-- keep, beware, that way the stack can grow
end
end
+function context.restart()
+ _stack_, _n_ = { }, 0
+end
+
context._stack_ = _stack_
context._store_ = _store_
context._flush_ = _flush_
@@ -68,9 +80,18 @@ context._flush_ = _flush_
local catcodestack = { }
local currentcatcodes = ctxcatcodes
+local catcodes = {
+ ctx = ctxcatcodes, ctxcatcodes = ctxcatcodes, context = ctxcatcodes,
+ prt = prtcatcodes, prtcatcodes = prtcatcodes, protect = prtcatcodes,
+ tex = texcatcodes, texcatcodes = texcatcodes, plain = texcatcodes,
+ txt = txtcatcodes, txtcatcodes = txtcatcodes, text = txtcatcodes,
+ vrb = vrbcatcodes, vrbcatcodes = vrbcatcodes, verbatim = vrbcatcodes,
+ xml = xmlcatcodes, xmlcatcodes = xmlcatcodes,
+}
+
function context.pushcatcodes(c)
insert(catcodestack,currentcatcodes)
- currentcatcodes = c
+ currentcatcodes = (c and catcodes[c] or tonumber(c)) or currentcatcodes
end
function context.popcatcodes()
@@ -90,14 +111,6 @@ function tex.fprint(...) -- goodie
texsprint(currentcatcodes,format(...))
end
---~ function context.direct(...)
---~ context.flush(...)
---~ end
-
---~ function context.verbose(...)
---~ context.flush(vrbcatcodes,...)
---~ end
-
local trace_context = logs.new("context") -- here
function context.trace(intercept)
@@ -122,25 +135,33 @@ function context.setflush(newflush)
end
trackers.register("context.flush", function(v) if v then context.trace() end end)
-trackers.register("context.intercept", function(v) if v then context.trace(true) end end)
+trackers.register("context.intercept", function(v) if v then context.trace(true) end end) -- will become obsolete
--~ context.trace()
-- beware, we had command as part of the flush and made it "" afterwards so that we could
-- keep it there (...,command,...) but that really confuses the tex machinery
-local function writer(command,first,...) -- 5% faster than just ... and separate flush of command
+local function writer(command,first,...)
if not command then
-- error
- elseif not first then
+ elseif first == nil then
flush(currentcatcodes,command)
else
local t = { first, ... }
- flush(currentcatcodes,command)
+ flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
+ local direct = false
for i=1,#t do
local ti = t[i]
local typ = type(ti)
- if ti == nil then
+ if direct then
+ if typ == "string" or typ == "number" then
+ flush(currentcatcodes,ti)
+ else
+ trace_context("error: invalid use of direct in '%s', only strings and numbers can be flushed directly, not '%s'",command,typ)
+ end
+ direct = false
+ elseif ti == nil then
-- nothing
elseif typ == "string" then
if ti == "" then
@@ -188,29 +209,33 @@ local function writer(command,first,...) -- 5% faster than just ... and separate
flush(currentcatcodes,"[",concat(ti,","),"]")
end
elseif typ == "function" then
- flush(currentcatcodes,"{\\mkivflush{",_store_(ti),"}}")
- -- elseif typ == "boolean" then
- -- flush(currentcatcodes,"\n")
- elseif ti == true then
- flush(currentcatcodes,"\n")
- elseif typ == false then
- -- if force == "direct" then
- flush(currentcatcodes,tostring(ti))
- -- end
+ flush(currentcatcodes,"{\\mkivflush{",_store_(ti),"}}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if ti then
+ flush(currentcatcodes,"^^M")
+ else
+ direct = true
+ end
elseif typ == "thread" then
trace_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(ti) then
+ writenode(ti)
else
- trace_context("error: %s gets a weird argument %s",command,tostring(ti))
+ trace_context("error: '%s' gets a weird argument '%s'",command,tostring(ti))
end
end
+ if direct then
+ trace_context("error: direct flushing used in '%s' without following argument",command)
+ end
end
end
--~ experiments.register("context.writer",function()
--~ writer = newwriter
--~ end)
+
local function indexer(t,k)
- local c = "\\" .. k .. " "
+ local c = "\\" .. k -- .. " "
local f = function(...) return writer(c,...) end
t[k] = f
return f
@@ -219,14 +244,38 @@ end
local function caller(t,f,a,...)
if not t then
-- so we don't need to test in the calling (slower but often no issue)
- elseif a then
- flush(currentcatcodes,format(f,a,...))
- elseif type(f) == "function" then
- flush(currentcatcodes,"{\\mkivflush{" .. _store_(f) .. "}}")
- elseif f then
- flush(currentcatcodes,f)
- else
- flush(currentcatcodes,"\n")
+ elseif f ~= nil then
+ local typ = type(f)
+ if typ == "string" then
+ if a then
+ flush(currentcatcodes,format(f,a,...))
+ else
+ flush(currentcatcodes,f)
+ end
+ elseif typ == "number" then
+ if a then
+ flush(currentcatcodes,f,a,...)
+ else
+ flush(currentcatcodes,f)
+ end
+ elseif typ == "function" then
+ -- ignored: a ...
+ flush(currentcatcodes,"{\\mkivflush{",_store_(f),"}}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ -- ignored: a ...
+ if f then
+ flush(currentcatcodes,"^^M")
+ else
+ writer("",a,...)
+ -- trace_context("warning: 'context' gets argument 'false' which is currently unsupported")
+ end
+ elseif typ == "thread" then
+ trace_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(f) then
+ writenode(f)
+ else
+ trace_context("error: 'context' gets a weird argument '%s'",tostring(f))
+ end
end
end
@@ -237,24 +286,24 @@ setmetatable(context, { __index = indexer, __call = caller } )
local trace_cld = false
function context.runfile(filename)
- filename = resolvers.findtexfile(filename) or ""
- if filename ~= "" then
- local ok = dofile(filename)
+ local foundname = resolvers.findtexfile(file.addsuffix(filename,"cld")) or ""
+ if foundname ~= "" then
+ local ok = dofile(foundname)
if type(ok) == "function" then
if trace_cld then
- commands.writestatus("cld","begin of file '%s' (function call)",filename)
+ trace_context("begin of file '%s' (function call)",foundname)
end
ok()
if trace_cld then
- commands.writestatus("cld","end of file '%s' (function call)",filename)
+ trace_context("end of file '%s' (function call)",foundname)
end
elseif ok then
- commands.writestatus("cld","file '%s' is processed and returns true",filename)
+ trace_context("file '%s' is processed and returns true",foundname)
else
- commands.writestatus("cld","file '%s' is processed and returns nothing",filename)
+ trace_context("file '%s' is processed and returns nothing",foundname)
end
else
- commands.writestatus("cld","unknown file '%s'",filename)
+ trace_context("unknown file '%s'",filename)
end
end
@@ -278,6 +327,24 @@ end)
function context.enabletrackers (str) trackers.enable (str) end
function context.disabletrackers(str) trackers.disable(str) end
+function context.direct(...)
+ return writer("",...)
+end
+
+function context.char(k)
+ if type(k) == "table" then
+ for i=1,#k do
+ context(format([[\char%s\relax]],k[i]))
+ end
+ elseif k then
+ context(format([[\char%s\relax]],k))
+ end
+end
+
+function context.par()
+ context([[\par]]) -- no need to add {} there
+end
+
-- see demo-cld.cld for an example
-- context.starttext(true)
@@ -304,7 +371,7 @@ function context.disabletrackers(str) trackers.disable(str) end
--~ Not that useful yet. Maybe something like this when the main loop
--~ is a coroutine. It also does not help taking care of nested calls.
---~ Even worse, it interferes with other mechanisms usign context calls.
+--~ Even worse, it interferes with other mechanisms using context calls.
--~
--~ local create, yield, resume = coroutine.create, coroutine.yield, coroutine.resume
--~ local getflush, setflush = context.getflush, context.setflush
@@ -354,12 +421,107 @@ function context.disabletrackers(str) trackers.disable(str) end
-- this might be generalized: register some primitives as: accepting this or that
-- we can also speed this up
-function context.char(k)
- if type(k) == "table" then
- for i=1,#k do
- context(format([[\char%s\relax]],k[i]))
+
+local delayed = { } context.delayed = delayed -- maybe also global
+
+local function indexer(t,k)
+ local f = function(...)
+ local a = { ... }
+ return function()
+ return context[k](unpack(a))
end
- elseif k then
- context(format([[\char%s\relax]],k))
+ end
+ t[k] = f
+ return f
+end
+
+
+local function caller(t,...)
+ local a = { ... }
+ return function()
+ return context(unpack(a))
+ end
+end
+
+setmetatable(delayed, { __index = indexer, __call = caller } )
+
+--~ context.test("test 1",context.delayed(" test 2a "),"test 3")
+--~ context.test("test 1",context.delayed.test(" test 2b "),"test 3")
+
+-- experimental:
+
+local metafun = { } context.metafun = metafun
+
+local mpdrawing = "\\MPdrawing"
+
+local function caller(t,f,a,...)
+ if not t then
+ -- skip
+ elseif f then
+ local typ = type(f)
+ if typ == "string" then
+ if a then
+ flush(currentcatcodes,mpdrawing,"{",format(f,a,...),"}")
+ else
+ flush(currentcatcodes,mpdrawing,"{",f,"}")
+ end
+ elseif typ == "number" then
+ if a then
+ flush(currentcatcodes,mpdrawing,"{",f,a,...,"}")
+ else
+ flush(currentcatcodes,mpdrawing,"{",f,"}")
+ end
+ elseif typ == "function" then
+ -- ignored: a ...
+ flush(currentcatcodes,mpdrawing,"{\\mkivflush{",store_(f),"}}")
+ elseif typ == "boolean" then
+ -- ignored: a ...
+ if f then
+ flush(currentcatcodes,mpdrawing,"{^^M}")
+ else
+ trace_context("warning: 'metafun' gets argument 'false' which is currently unsupported")
+ end
+ else
+ trace_context("error: 'metafun' gets a weird argument '%s'",tostring(f))
+ end
+ end
+end
+
+setmetatable(metafun, { __call = caller } )
+
+function metafun.start()
+ context.resetMPdrawing()
+end
+
+function metafun.stop()
+ context.MPdrawingdonetrue()
+ context.getMPdrawing()
+end
+
+function metafun.color(name)
+ return format([[\MPcolor{%s}]],name)
+end
+
+
+local delayed = { } metafun.delayed = delayed
+
+local function indexer(t,k)
+ local f = function(...)
+ local a = { ... }
+ return function()
+ return metafun[k](unpack(a))
+ end
+ end
+ t[k] = f
+ return f
+end
+
+
+local function caller(t,...)
+ local a = { ... }
+ return function()
+ return metafun(unpack(a))
end
end
+
+setmetatable(delayed, { __index = indexer, __call = caller } )
diff --git a/tex/context/base/mult-cld.mkiv b/tex/context/base/mult-cld.mkiv
index 1c5ebd34a..6b94f3f21 100644
--- a/tex/context/base/mult-cld.mkiv
+++ b/tex/context/base/mult-cld.mkiv
@@ -20,10 +20,13 @@
\unprotect
-\def\defmkivstart#1{\unexpanded\expandafter\def\csname\e!start#1\endcsname}
-\def\defmkivstop #1{\unexpanded\def\csname\e!stop #1\endcsname}
-\def\defmkiv #1{\unexpanded\def\csname #1\endcsname}
+\unexpanded\def\mkivdefstart #1{\unexpanded\expandafter\def\csname\e!start#1\endcsname}
+\unexpanded\def\mkivdefstop #1{\unexpanded\expandafter\def\csname\e!stop #1\endcsname}
+\unexpanded\def\mkivdef #1{\unexpanded\expandafter\def\csname #1\endcsname}
+ \def\mkivflush #1{\directlua\zerocount{context._flush_(#1)}} % this one will get protected
-\def\mkivflush #1{\ctxlua{context._flush_(#1)}}
+\unexpanded\def\cldprocessfile#1{\directlua\zerocount{context.runfile("#1")}}
+ \def\cldcontext #1{\directlua\zerocount{context(#1)}}
+ \def\cldcommand #1{\directlua\zerocount{context.#1}}
\protect \endinput
diff --git a/tex/context/base/mult-clm.lua b/tex/context/base/mult-clm.lua
index 628c255e9..044e31d2b 100644
--- a/tex/context/base/mult-clm.lua
+++ b/tex/context/base/mult-clm.lua
@@ -63,10 +63,10 @@ function mkiv.define(name,specification) -- name is optional
local environment = specification.environment
if na == 0 then
if environment then
- texsprint(ctxcatcodes,"\\defmkstart{",name,"}{\\ctxlua{mkiv.b('",name,"')}}")
- texsprint(ctxcatcodes,"\\defmkstop{", name,"}{\\ctxlua{mkiv.b('",name,"')}}")
+ texsprint(ctxcatcodes,"\\mkdefstart{",name,"}{\\ctxlua{mkiv.b('",name,"')}}")
+ texsprint(ctxcatcodes,"\\mkdefstop{", name,"}{\\ctxlua{mkiv.b('",name,"')}}")
else
- texsprint(ctxcatcodes,"\\defmkiv{", name,"}{\\ctxlua{mkiv.m('",name,"')}}")
+ texsprint(ctxcatcodes,"\\mkivdef{", name,"}{\\ctxlua{mkiv.m('",name,"')}}")
end
else
stack[name] = { }
@@ -106,10 +106,10 @@ function mkiv.define(name,specification) -- name is optional
end
texsprint(ctxcatcodes,")}}")
if environment then
- texsprint(ctxcatcodes,"\\defmkivstop{" ,name,"}{\\ctxlua{mkiv.e('",name,"')}}")
- texsprint(ctxcatcodes,"\\defmkivstart{",name,"}{",checkers[opt],mkivdo,"}")
+ texsprint(ctxcatcodes,"\\mkivdefstop{" ,name,"}{\\ctxlua{mkiv.e('",name,"')}}")
+ texsprint(ctxcatcodes,"\\mkivdefstart{",name,"}{",checkers[opt],mkivdo,"}")
else
- texsprint(ctxcatcodes,"\\defmkiv{", name,"}{",checkers[opt],mkivdo,"}")
+ texsprint(ctxcatcodes,"\\mkivdef{", name,"}{",checkers[opt],mkivdo,"}")
end
end
if environment then
diff --git a/tex/context/base/mult-def.tex b/tex/context/base/mult-def.mkii
index cff9fb074..a6840b0e0 100644
--- a/tex/context/base/mult-def.tex
+++ b/tex/context/base/mult-def.mkii
@@ -22,12 +22,8 @@
\setvalue{@interface@persian@}{pe}
\setvalue{@interface@romanian@}{ro}
-% \def\userinterfacetag
-% {\ifcsname @interface@\defaultinterface @\endcsname\csname @interface@\defaultinterface @\endcsname\else en\fi}
-\def\userinterfacetag
- {\ifcsname @interface@\currentinterface @\endcsname\csname @interface@\currentinterface @\endcsname\else en\fi}
-\def\userresponsestag
- {\ifcsname @interface@\currentresponses @\endcsname\csname @interface@\currentresponses @\endcsname\else en\fi}
+\def\userinterfacetag{\ifcsname @interface@\currentinterface @\endcsname\csname @interface@\currentinterface @\endcsname\else en\fi}
+\def\userresponsestag{\ifcsname @interface@\currentresponses @\endcsname\csname @interface@\currentresponses @\endcsname\else en\fi}
\input mult-\userinterfacetag \relax
\input mult-m\userresponsestag \relax
diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv
new file mode 100644
index 000000000..a6840b0e0
--- /dev/null
+++ b/tex/context/base/mult-def.mkiv
@@ -0,0 +1,31 @@
+%D \module
+%D [ file=mult-def,
+%D version=2008.10.22,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\setvalue{@interface@czech@}{cs}
+\setvalue{@interface@german@}{de}
+\setvalue{@interface@english@}{en}
+\setvalue{@interface@french@}{fr}
+\setvalue{@interface@italian@}{it}
+\setvalue{@interface@dutch@}{nl}
+\setvalue{@interface@persian@}{pe}
+\setvalue{@interface@romanian@}{ro}
+
+\def\userinterfacetag{\ifcsname @interface@\currentinterface @\endcsname\csname @interface@\currentinterface @\endcsname\else en\fi}
+\def\userresponsestag{\ifcsname @interface@\currentresponses @\endcsname\csname @interface@\currentresponses @\endcsname\else en\fi}
+
+\input mult-\userinterfacetag \relax
+\input mult-m\userresponsestag \relax
+
+\protect \endinput
diff --git a/tex/context/base/mult-fst.mkii b/tex/context/base/mult-fst.mkii
new file mode 100644
index 000000000..e655e3d26
--- /dev/null
+++ b/tex/context/base/mult-fst.mkii
@@ -0,0 +1,36 @@
+%D \module
+%D [ file=mult-fst,
+%D version=2006.08.16,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Speed Up,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% And so, after a few years of keeping this potentially dangerous
+% speedup in cont-exp, we now move it to the kernel: the next
+% patch is 30\% faster on main interface (seconds) (9->7 sec on
+% 1 million calls). Another speed up is still under testing.
+
+\unprotect
+
+\startinterface english
+
+ \def\dosetvalue #1#2{\@EA\def \csname#1#2\endcsname}
+ \def\dosetevalue #1#2{\@EA\edef\csname#1#2\endcsname}
+ \def\dosetgvalue #1#2{\@EA\gdef\csname#1#2\endcsname}
+ \def\dosetxvalue #1#2{\@EA\gdef\csname#1#2\endcsname}
+ \def\docopyvalue#1#2#3{\@EA\def \csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}}
+
+ \def\setinterfaceconstant#1#2{\setvalue{\c!prefix!#1}{#1}}
+ \def\setinterfacevariable#1#2{\setvalue{\v!prefix!#1}{#2}}
+
+ \def\interfaced#1{#1}
+
+\stopinterface
+
+\protect \endinput
diff --git a/tex/context/base/mult-fst.tex b/tex/context/base/mult-fst.mkiv
index c237f5743..11558b557 100644
--- a/tex/context/base/mult-fst.tex
+++ b/tex/context/base/mult-fst.mkiv
@@ -26,25 +26,13 @@
\def\dosetxvalue #1#2{\@EA\gdef\csname#1#2\endcsname}
\def\docopyvalue#1#2#3{\@EA\def \csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}}
- \ifx\ctxlua\undefined
+ \def\setinterfaceconstant#1#2%
+ {\ctxlua{interfaces.setconstant("#1","#2")}%
+ \setvalue{\c!prefix!#1}{#1}}
- \def\setinterfaceconstant#1#2%
- {\setvalue{\c!prefix!#1}{#1}}
-
- \def\setinterfacevariable#1#2%
- {\setvalue{\v!prefix!#1}{#2}}
-
- \else
-
- \def\setinterfaceconstant#1#2%
- {\ctxlua{interfaces.setconstant("#1","#2")}%
- \setvalue{\c!prefix!#1}{#1}}
-
- \def\setinterfacevariable#1#2%
- {\ctxlua{interfaces.setvariable("#1","#2")}%
- \setvalue{\v!prefix!#1}{#2}}
-
- \fi
+ \def\setinterfacevariable#1#2%
+ {\ctxlua{interfaces.setvariable("#1","#2")}%
+ \setvalue{\v!prefix!#1}{#2}}
\def\interfaced#1{#1}
diff --git a/tex/context/base/mult-ini.mkiv b/tex/context/base/mult-ini.mkiv
index de00af83b..b8b1c5387 100644
--- a/tex/context/base/mult-ini.mkiv
+++ b/tex/context/base/mult-ini.mkiv
@@ -375,13 +375,15 @@
{\ifcsname\m!prefix!#1\endcsname\else\setgvalue{\m!prefix!#1}{#1}\fi
\ctxlua{interfaces.setmessage("#1","#2",\!!bs#3\!!es)}}
-\unexpanded\def\setmessagetext #1#2{\edef\currentmessagetext{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2"))}}}
+\unexpanded\def\setmessagetext #1#2{\edef\currentmessagetext{\ctxsprint{interfaces.getmessage("#1","#2")}}}
+
\unexpanded\def\doifelsemessage #1#2{\ctxlua{interfaces.doifelsemessage("#1","#2")}}
-\unexpanded\def\getmessage #1#2{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2"))}}
-\unexpanded\def\getmessagedefault#1#2#3{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2","#3"))}}
-\unexpanded\def\makemessage #1#2#3{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.makemessage("#1","#2","#3"))}}
\unexpanded\def\showmessage #1#2#3{\ctxlua{interfaces.showmessage("#1","#2","#3")}}
+\unexpanded\def\getmessage #1#2{\ctxsprint{interfaces.getmessage("#1","#2")}}
+\unexpanded\def\getmessagedefault#1#2#3{\ctxsprint{interfaces.getmessage("#1","#2","#3")}}
+\unexpanded\def\makemessage #1#2#3{\ctxsprint{interfaces.makemessage("#1","#2","#3")}}
+
%D \macros
%D {ifshowwarnings, ifshowmessages}
%D
diff --git a/tex/context/base/mult-pe.tex b/tex/context/base/mult-pe.tex
new file mode 100644
index 000000000..703a7193c
--- /dev/null
+++ b/tex/context/base/mult-pe.tex
@@ -0,0 +1,1700 @@
+% this file is auto-generated, don't edit this file
+%
+% definitions for interface variables for language pe
+%
+\setinterfacevariable{Addition}{جمع}
+\setinterfacevariable{Balloon}{بادکنک}
+\setinterfacevariable{Character}{Character}
+\setinterfacevariable{Characters}{Characters}
+\setinterfacevariable{CloseDocument}{بستن‌نوشتار}
+\setinterfacevariable{ExitViewer}{خروج‌نمایشگر}
+\setinterfacevariable{FirstPage}{صفحه‌اول}
+\setinterfacevariable{FitHeight}{پرکردن‌ارتفاع}
+\setinterfacevariable{FitWidth}{پرکردن‌عرض}
+\setinterfacevariable{GotoPage}{برو‌به‌صفحه}
+\setinterfacevariable{Greek}{یونانی}
+\setinterfacevariable{Help}{کمک}
+\setinterfacevariable{HideField}{پنهان‌میدان}
+\setinterfacevariable{HideLayer}{پنهان‌لایه}
+\setinterfacevariable{Key}{کلید}
+\setinterfacevariable{LastPage}{صفحه‌آخر}
+\setinterfacevariable{LoadForm}{بارگذاشتن‌فرم}
+\setinterfacevariable{MONTH}{ماه}
+\setinterfacevariable{New}{جدید}
+\setinterfacevariable{NextJump}{پرش‌بعدی}
+\setinterfacevariable{NextPage}{صفحه‌بعدی}
+\setinterfacevariable{Numbers}{شماره‌ها}
+\setinterfacevariable{OpenNamedDocument}{بازکردن‌نوشتار‌ذخیره‌شده}
+\setinterfacevariable{Paragraph}{پاراگراف}
+\setinterfacevariable{PauseMovie}{ایست‌فیلم}
+\setinterfacevariable{PauseRendering}{توقف‌تعبیر}
+\setinterfacevariable{PauseSound}{ایست‌صدا}
+\setinterfacevariable{PreviousJump}{پرش‌قبلی}
+\setinterfacevariable{PreviousPage}{صفحه‌قبلی}
+\setinterfacevariable{PrintDocument}{چاپ‌نوشتار}
+\setinterfacevariable{Query}{پرسش}
+\setinterfacevariable{QueryAgain}{پرسش‌دوباره}
+\setinterfacevariable{ResetForm}{دوباره‌نشانی‌فرم}
+\setinterfacevariable{ResumeMovie}{ادامه‌فیلم}
+\setinterfacevariable{ResumeRendering}{ادامه‌تعبیر}
+\setinterfacevariable{ResumeSound}{ادامه‌صدا}
+\setinterfacevariable{Romannumerals}{اعداد‌بزرگ‌لاتین}
+\setinterfacevariable{SaveDocument}{ذخیره‌نوشتار}
+\setinterfacevariable{SaveForm}{ذخیره‌فرم}
+\setinterfacevariable{SaveNamedDocument}{ذخیره‌نوشتار‌بانام}
+\setinterfacevariable{SearchAgain}{جستجوی‌دوباره}
+\setinterfacevariable{SearchDocument}{جستجوی‌نوشتار}
+\setinterfacevariable{ShowBookmarks}{نمایش‌چوبخط}
+\setinterfacevariable{ShowField}{نمایش‌میدان}
+\setinterfacevariable{ShowThumbs}{نمایش‌شصت}
+\setinterfacevariable{StartMovie}{شروع‌فیلم}
+\setinterfacevariable{StartRendering}{شروع‌تعبیر}
+\setinterfacevariable{StartSound}{شروع‌صدا}
+\setinterfacevariable{StopMovie}{پایان‌فیلم}
+\setinterfacevariable{StopRendering}{پایان‌تعبیر}
+\setinterfacevariable{StopSound}{پایان‌صدا}
+\setinterfacevariable{SubmitForm}{تسلیم‌فرم}
+\setinterfacevariable{ToggleLayer}{تغییرلایه}
+\setinterfacevariable{ToggleViewer}{تغییرنمایشگر}
+\setinterfacevariable{URL}{URL}
+\setinterfacevariable{VideLayer}{VideLayer}
+\setinterfacevariable{ViewerHelp}{کمک‌نمایشگر}
+\setinterfacevariable{WEEKDAY}{روزهفته}
+\setinterfacevariable{WORD}{کلمه}
+\setinterfacevariable{abbreviation}{اختصار}
+\setinterfacevariable{abbreviations}{اختصارات}
+\setinterfacevariable{absolute}{قطعی}
+\setinterfacevariable{action}{کنش}
+\setinterfacevariable{after}{بعداز}
+\setinterfacevariable{all}{همه}
+\setinterfacevariable{always}{همواره}
+\setinterfacevariable{answerarea}{answerarea}
+\setinterfacevariable{appendices}{پیوستها}
+\setinterfacevariable{appendix}{پیوست}
+\setinterfacevariable{april}{آوریل}
+\setinterfacevariable{atmargin}{درحاشیه}
+\setinterfacevariable{atpage}{درصفحه}
+\setinterfacevariable{august}{آگوست}
+\setinterfacevariable{author}{author}
+\setinterfacevariable{auto}{خودکار}
+\setinterfacevariable{autointro}{پیشگفتارخودکار}
+\setinterfacevariable{back}{پشت}
+\setinterfacevariable{background}{پس‌زمینه}
+\setinterfacevariable{backmatter}{پس‌مطلب}
+\setinterfacevariable{backpart}{پس‌قسمت}
+\setinterfacevariable{backspace}{فضای‌پشت}
+\setinterfacevariable{backward}{عقب‌گرد}
+\setinterfacevariable{bbl}{bbl}
+\setinterfacevariable{before}{قبل‌از}
+\setinterfacevariable{begin}{begin}
+\setinterfacevariable{bib}{bib}
+\setinterfacevariable{big}{بزرگ}
+\setinterfacevariable{bigbodyfont}{قلم‌بدنه‌بزرگ}
+\setinterfacevariable{bigger}{bigger}
+\setinterfacevariable{bigpreference}{اولویت‌بزرگ}
+\setinterfacevariable{blank}{خالی}
+\setinterfacevariable{blockquote}{نقل‌بلوک}
+\setinterfacevariable{bodymatter}{مطلب‌بدنه}
+\setinterfacevariable{bodypart}{قسمت‌بدنه}
+\setinterfacevariable{bold}{مشکی}
+\setinterfacevariable{bolditalic}{ایتالیک‌مشکی}
+\setinterfacevariable{boldslanted}{خوابیده‌مشکی}
+\setinterfacevariable{bookmark}{چوبخط}
+\setinterfacevariable{both}{هردو}
+\setinterfacevariable{bottom}{پایین}
+\setinterfacevariable{brief}{مختصر}
+\setinterfacevariable{broad}{گسترده}
+\setinterfacevariable{buffer}{بافر}
+\setinterfacevariable{by}{بوسیله}
+\setinterfacevariable{calligraphic}{خوشنویسی}
+\setinterfacevariable{cap}{cap}
+\setinterfacevariable{capital}{capital}
+\setinterfacevariable{center}{مرکز}
+\setinterfacevariable{chapter}{فصل}
+\setinterfacevariable{character}{حرف}
+\setinterfacevariable{characters}{حرفها}
+\setinterfacevariable{cite}{cite}
+\setinterfacevariable{color}{رنگ}
+\setinterfacevariable{column}{ستون}
+\setinterfacevariable{columns}{ستونها}
+\setinterfacevariable{command}{فرمان}
+\setinterfacevariable{commands}{فرمانها}
+\setinterfacevariable{comment}{توضیح}
+\setinterfacevariable{component}{مولفه}
+\setinterfacevariable{concept}{مفهوم}
+\setinterfacevariable{content}{محتوا}
+\setinterfacevariable{contents}{محتویات}
+\setinterfacevariable{continue}{ادامه}
+\setinterfacevariable{controls}{کنترلها}
+\setinterfacevariable{conversion}{تبدیل}
+\setinterfacevariable{current}{جاری}
+\setinterfacevariable{cutspace}{فضای‌برش}
+\setinterfacevariable{date}{تاریخ}
+\setinterfacevariable{day}{روز}
+\setinterfacevariable{december}{دسامبر}
+\setinterfacevariable{default}{پیش‌فرض}
+\setinterfacevariable{depth}{عمق}
+\setinterfacevariable{description}{شرح}
+\setinterfacevariable{disable}{ناتوان}
+\setinterfacevariable{display}{نمایش}
+\setinterfacevariable{dot}{نقطه}
+\setinterfacevariable{doublesided}{دورو}
+\setinterfacevariable{down}{down}
+\setinterfacevariable{each}{هر}
+\setinterfacevariable{edge}{لبه}
+\setinterfacevariable{embed}{embed}
+\setinterfacevariable{empty}{تهی}
+\setinterfacevariable{end}{end}
+\setinterfacevariable{endnote}{ته‌نوشت}
+\setinterfacevariable{enumeration}{شماره‌بندی}
+\setinterfacevariable{environment}{محیط}
+\setinterfacevariable{even}{زوج}
+\setinterfacevariable{external}{خارجی}
+\setinterfacevariable{fact}{fact}
+\setinterfacevariable{february}{فوریه}
+\setinterfacevariable{figure}{شکل}
+\setinterfacevariable{figures}{شکلها}
+\setinterfacevariable{file}{پرونده}
+\setinterfacevariable{final}{نهایی}
+\setinterfacevariable{first}{اولی}
+\setinterfacevariable{firstcolumn}{ستون‌اول}
+\setinterfacevariable{firstpage}{صفحه‌اول}
+\setinterfacevariable{firstsubpage}{زیرصفحه‌اول}
+\setinterfacevariable{fit}{پرکردن}
+\setinterfacevariable{five}{پنج}
+\setinterfacevariable{fix}{ثابت‌کن}
+\setinterfacevariable{fixed}{ثابت}
+\setinterfacevariable{flexible}{انعطافپذیر}
+\setinterfacevariable{float}{شناور}
+\setinterfacevariable{flushinner}{پمپ‌داخلی}
+\setinterfacevariable{flushleft}{پمپ‌چپ}
+\setinterfacevariable{flushouter}{پمپ‌خارجی}
+\setinterfacevariable{flushright}{پمپ‌راست}
+\setinterfacevariable{footer}{ته‌برگ}
+\setinterfacevariable{footnote}{پانوشت}
+\setinterfacevariable{force}{اجبار}
+\setinterfacevariable{foreground}{پیش‌زمینه}
+\setinterfacevariable{formeel}{formeel}
+\setinterfacevariable{formula}{فرمول}
+\setinterfacevariable{formulae}{فرمولها}
+\setinterfacevariable{forward}{به‌جلو}
+\setinterfacevariable{four}{چهار}
+\setinterfacevariable{frame}{قالب}
+\setinterfacevariable{framedtext}{متن‌قالبی}
+\setinterfacevariable{friday}{جمعه}
+\setinterfacevariable{frontmatter}{پیش‌مطلب}
+\setinterfacevariable{frontpart}{پیش‌قسمت}
+\setinterfacevariable{global}{سراسری}
+\setinterfacevariable{graphic}{گرافیک}
+\setinterfacevariable{graphics}{گرافیکها}
+\setinterfacevariable{gray}{خاکستری}
+\setinterfacevariable{greek}{یونانی}
+\setinterfacevariable{grid}{توری}
+\setinterfacevariable{halfline}{نیم‌خط}
+\setinterfacevariable{handwritten}{دست‌نوشته}
+\setinterfacevariable{hang}{بیاویز}
+\setinterfacevariable{hanging}{آویزان}
+\setinterfacevariable{head}{سر}
+\setinterfacevariable{header}{سربرگ}
+\setinterfacevariable{height}{ارتفاع}
+\setinterfacevariable{helptext}{متن‌کمکی}
+\setinterfacevariable{hencefore}{hencefore}
+\setinterfacevariable{here}{اینجا}
+\setinterfacevariable{hereafter}{ازاین‌به‌بعد}
+\setinterfacevariable{hidden}{پنهانی}
+\setinterfacevariable{hiding}{پنهان‌کردن}
+\setinterfacevariable{high}{بلند}
+\setinterfacevariable{horizontal}{افقی}
+\setinterfacevariable{hyphenated}{شکسته}
+\setinterfacevariable{hz}{hz}
+\setinterfacevariable{inbetween}{دربین}
+\setinterfacevariable{index}{نمایه}
+\setinterfacevariable{indices}{نمایه‌ها}
+\setinterfacevariable{informeel}{informeel}
+\setinterfacevariable{inherit}{ارث‌بردن}
+\setinterfacevariable{inleft}{درون‌چپ}
+\setinterfacevariable{inmargin}{درون‌حاشیه}
+\setinterfacevariable{inner}{داخلی}
+\setinterfacevariable{inneredge}{لبه‌داخلی}
+\setinterfacevariable{innermargin}{حاشیه‌داخلی}
+\setinterfacevariable{inright}{درون‌راست}
+\setinterfacevariable{interaction}{پانل}
+\setinterfacevariable{interactionmenu}{منوی‌پانل}
+\setinterfacevariable{intermezzi}{میان‌پرده‌ها}
+\setinterfacevariable{intermezzo}{میان‌پرده}
+\setinterfacevariable{intext}{درون‌متن}
+\setinterfacevariable{intro}{پیشگفتار}
+\setinterfacevariable{italic}{ایتالیک}
+\setinterfacevariable{italicbold}{مشکی‌ایتالیک}
+\setinterfacevariable{item}{آیتم}
+\setinterfacevariable{itemize}{آیتم‌بندی}
+\setinterfacevariable{its}{آیم}
+\setinterfacevariable{january}{ژانویه}
+\setinterfacevariable{joinedup}{متصل‌بالا}
+\setinterfacevariable{july}{ژولای}
+\setinterfacevariable{june}{ژوئن}
+\setinterfacevariable{keep}{نگهدار}
+\setinterfacevariable{knockout}{knockout}
+\setinterfacevariable{label}{برچسب}
+\setinterfacevariable{landscape}{صفحه‌گسترده}
+\setinterfacevariable{last}{آخرین}
+\setinterfacevariable{lastcolumn}{آخرین‌ستون}
+\setinterfacevariable{lastpage}{صفحه‌آخر}
+\setinterfacevariable{lastpagenumber}{شماه‌صفحه‌آخر}
+\setinterfacevariable{lastsubpage}{زیرصفحه‌آخر}
+\setinterfacevariable{layer}{layer}
+\setinterfacevariable{left}{چپ}
+\setinterfacevariable{leftedge}{لبه‌چپ}
+\setinterfacevariable{lefthanging}{آویزان‌چپ}
+\setinterfacevariable{leftmargin}{حاشیه‌چپ}
+\setinterfacevariable{leftpage}{صفحه‌چپ}
+\setinterfacevariable{lefttoright}{lefttoright}
+\setinterfacevariable{legend}{راهنما}
+\setinterfacevariable{lesshyphenation}{شکست‌کلمات‌کمتر}
+\setinterfacevariable{line}{خط}
+\setinterfacevariable{linenote}{خط‌نوشت}
+\setinterfacevariable{lines}{خطها}
+\setinterfacevariable{list}{لیست}
+\setinterfacevariable{local}{موضعی}
+\setinterfacevariable{localenvironment}{محیط‌موضعی}
+\setinterfacevariable{logo}{آرم}
+\setinterfacevariable{logos}{آرمها}
+\setinterfacevariable{lohi}{پابا}
+\setinterfacevariable{loose}{شل}
+\setinterfacevariable{low}{پایین}
+\setinterfacevariable{ls}{ls}
+\setinterfacevariable{makeup}{آرایش}
+\setinterfacevariable{mar}{حاش}
+\setinterfacevariable{march}{مارس}
+\setinterfacevariable{margin}{حاشیه}
+\setinterfacevariable{marginedge}{لبه‌حاشیه}
+\setinterfacevariable{margintitle}{عنوان‌حاشیه}
+\setinterfacevariable{marking}{نشانه‌گذاری}
+\setinterfacevariable{mathalignment}{تنظیم‌ریاضی}
+\setinterfacevariable{mathcases}{حالتهای‌ریاضی}
+\setinterfacevariable{mathmatrix}{ماتریش‌ریاضی}
+\setinterfacevariable{max}{بیشترین}
+\setinterfacevariable{maxdepth}{maxdepth}
+\setinterfacevariable{maxheight}{maxheight}
+\setinterfacevariable{maxwidth}{maxwidth}
+\setinterfacevariable{may}{مه}
+\setinterfacevariable{mediaeval}{mediaeval}
+\setinterfacevariable{medium}{متوسط}
+\setinterfacevariable{middle}{میان}
+\setinterfacevariable{min}{کمترین}
+\setinterfacevariable{mindepth}{mindepth}
+\setinterfacevariable{minheight}{کمترین‌ارتفاع}
+\setinterfacevariable{minwidth}{کمترین‌عرض}
+\setinterfacevariable{mirrored}{منعکس}
+\setinterfacevariable{monday}{دوشنبه}
+\setinterfacevariable{mono}{مونو}
+\setinterfacevariable{month}{ماه}
+\setinterfacevariable{morehyphenation}{شکست‌کلمات‌بیشتر}
+\setinterfacevariable{name}{نام}
+\setinterfacevariable{narrow}{نازک}
+\setinterfacevariable{negative}{منفی}
+\setinterfacevariable{never}{هیچگاه}
+\setinterfacevariable{new}{جدید}
+\setinterfacevariable{next}{بعدی}
+\setinterfacevariable{nextevenpage}{صفحه‌زوج‌بعدی}
+\setinterfacevariable{nextoddpage}{صفحه‌فردبعدی}
+\setinterfacevariable{nextpage}{صفحه‌بعدی}
+\setinterfacevariable{nextsubpage}{زیرصفحه‌بعدی}
+\setinterfacevariable{no}{نه}
+\setinterfacevariable{nocheck}{بدون‌بررسی}
+\setinterfacevariable{nofit}{بدون‌پرکردن}
+\setinterfacevariable{nogrid}{بدون‌توری}
+\setinterfacevariable{nohz}{nohz}
+\setinterfacevariable{nomarking}{بدون‌نشانه‌گذاری}
+\setinterfacevariable{none}{هیچکدام}
+\setinterfacevariable{nonumber}{بدون‌شماره}
+\setinterfacevariable{normal}{نرمال}
+\setinterfacevariable{nospacing}{بدون‌فضاگذاری}
+\setinterfacevariable{not}{بدون}
+\setinterfacevariable{note}{note}
+\setinterfacevariable{nothanging}{بدون‌آویزان‌کردن}
+\setinterfacevariable{nothyphenated}{بدون‌شکست}
+\setinterfacevariable{november}{نوامبر}
+\setinterfacevariable{nowhere}{هیچ‌حا}
+\setinterfacevariable{nowhite}{سفید‌نه}
+\setinterfacevariable{number}{شماره}
+\setinterfacevariable{numbers}{شماره‌ها}
+\setinterfacevariable{october}{اکتبر}
+\setinterfacevariable{odd}{فرد}
+\setinterfacevariable{off}{خاموش}
+\setinterfacevariable{offset}{آفست}
+\setinterfacevariable{old}{قدیمی}
+\setinterfacevariable{on}{روی}
+\setinterfacevariable{one}{یک}
+\setinterfacevariable{opposite}{مخالف}
+\setinterfacevariable{outer}{خارجی}
+\setinterfacevariable{outeredge}{لبه‌خارجی}
+\setinterfacevariable{outermargin}{حاشیه‌خارجی}
+\setinterfacevariable{overbar}{میله‌رو}
+\setinterfacevariable{overbars}{میله‌ها‌رو}
+\setinterfacevariable{overlay}{پوشش}
+\setinterfacevariable{overprint}{overprint}
+\setinterfacevariable{overstrike}{خط‌زدن}
+\setinterfacevariable{overstrikes}{خط‌زدنها}
+\setinterfacevariable{packed}{فشرده}
+\setinterfacevariable{page}{صفحه}
+\setinterfacevariable{pagecomment}{توضیح‌صفحه}
+\setinterfacevariable{pagenumber}{شماره‌صفحه}
+\setinterfacevariable{paper}{برگ}
+\setinterfacevariable{paragraph}{پاراگراف}
+\setinterfacevariable{part}{قسمت}
+\setinterfacevariable{positive}{مثبت}
+\setinterfacevariable{postponing}{تاخیر}
+\setinterfacevariable{postscript}{پست‌اسکریپت}
+\setinterfacevariable{preference}{ترجیح}
+\setinterfacevariable{preview}{پیش‌دید}
+\setinterfacevariable{previous}{قبلی}
+\setinterfacevariable{previousevenpage}{صفحه‌زوج‌قبلی}
+\setinterfacevariable{previousoddpage}{صفحه‌فردقبلی}
+\setinterfacevariable{previouspage}{صفحه‌قبلی}
+\setinterfacevariable{previoussubpage}{زیرصفحه‌قبلی}
+\setinterfacevariable{printable}{قابل‌چاپ}
+\setinterfacevariable{process}{پردازش}
+\setinterfacevariable{product}{محصول}
+\setinterfacevariable{program}{برنامه}
+\setinterfacevariable{project}{پروژه}
+\setinterfacevariable{protected}{حفاظت‌شده}
+\setinterfacevariable{quadruple}{quadruple}
+\setinterfacevariable{quotation}{نقل‌قول}
+\setinterfacevariable{quote}{نقل}
+\setinterfacevariable{ran}{برد}
+\setinterfacevariable{random}{تصادفی}
+\setinterfacevariable{readonly}{تنهاخواندنی}
+\setinterfacevariable{rectangular}{چهارگوشه}
+\setinterfacevariable{reference}{مرجع}
+\setinterfacevariable{referral}{مراجعه}
+\setinterfacevariable{register}{ثبت}
+\setinterfacevariable{regular}{منظم}
+\setinterfacevariable{rekening}{rekening}
+\setinterfacevariable{relative}{نسبی}
+\setinterfacevariable{repeat}{تکرار}
+\setinterfacevariable{required}{موردنیاز}
+\setinterfacevariable{reset}{بازنشانی}
+\setinterfacevariable{reverse}{برعکس}
+\setinterfacevariable{right}{راست}
+\setinterfacevariable{rightedge}{لبه‌راست}
+\setinterfacevariable{righthanging}{آویزان‌کردن‌راست}
+\setinterfacevariable{rightmargin}{حاشیه‌راست}
+\setinterfacevariable{rightpage}{صفحه‌راست}
+\setinterfacevariable{righttoleft}{righttoleft}
+\setinterfacevariable{roman}{رومن}
+\setinterfacevariable{romannumerals}{شماره‌لاتین}
+\setinterfacevariable{rotate}{دوران}
+\setinterfacevariable{rotated}{دوران‌یافته}
+\setinterfacevariable{round}{گرد}
+\setinterfacevariable{row}{سطر}
+\setinterfacevariable{rule}{خط}
+\setinterfacevariable{samepage}{همان‌صفحه}
+\setinterfacevariable{sans}{سانز}
+\setinterfacevariable{sansbold}{مشکی‌سانز}
+\setinterfacevariable{sansserif}{سانزسریف}
+\setinterfacevariable{saturday}{شنبه}
+\setinterfacevariable{screen}{پرده}
+\setinterfacevariable{section}{بخش}
+\setinterfacevariable{sectionblockenvironment}{محیط‌بلوک‌بخش}
+\setinterfacevariable{sectionnumber}{شماره‌بخش}
+\setinterfacevariable{see}{ببینید}
+\setinterfacevariable{september}{سپتامبر}
+\setinterfacevariable{serif}{سریف}
+\setinterfacevariable{serried}{تنگ‌هم}
+\setinterfacevariable{setups}{بارگذاریها}
+\setinterfacevariable{sheet}{ورقه}
+\setinterfacevariable{short}{short}
+\setinterfacevariable{singlesided}{یک‌رو}
+\setinterfacevariable{slanted}{خوابیده}
+\setinterfacevariable{slantedbold}{مشکی‌خوابیده}
+\setinterfacevariable{small}{کوچک}
+\setinterfacevariable{smallbodyfont}{قلم‌بدنه‌کوچک}
+\setinterfacevariable{smallbold}{مشکی‌کوچک}
+\setinterfacevariable{smallbolditalic}{ایتالیک‌مشکی‌کوچک}
+\setinterfacevariable{smallboldslanted}{خوابیده‌مشکی‌کوچک}
+\setinterfacevariable{smallcaps}{smallcaps}
+\setinterfacevariable{smaller}{smaller}
+\setinterfacevariable{smallitalic}{ایتالیک‌کوچک}
+\setinterfacevariable{smallitalicbold}{مشکی‌ایتالیک‌کوچک}
+\setinterfacevariable{smallnormal}{نرمال‌کوچک}
+\setinterfacevariable{smallslanted}{خوابیده‌کوچک}
+\setinterfacevariable{smallslantedbold}{مشکی‌خوابیده‌کوچک}
+\setinterfacevariable{smalltype}{تایپ‌کوچک}
+\setinterfacevariable{somewhere}{جایی}
+\setinterfacevariable{sorted}{مرتب}
+\setinterfacevariable{space}{فضا}
+\setinterfacevariable{spacing}{فضاگذاری}
+\setinterfacevariable{speech}{سخنرانی}
+\setinterfacevariable{split}{شکافتن}
+\setinterfacevariable{spot}{لکه}
+\setinterfacevariable{standard}{استاندارد}
+\setinterfacevariable{start}{شروع}
+\setinterfacevariable{starter}{starter}
+\setinterfacevariable{sticker}{دشنه}
+\setinterfacevariable{stop}{پایان}
+\setinterfacevariable{stopper}{ایست}
+\setinterfacevariable{stretch}{بکش}
+\setinterfacevariable{strict}{اکید}
+\setinterfacevariable{strong}{محکم}
+\setinterfacevariable{strut}{بست}
+\setinterfacevariable{sub}{زیر}
+\setinterfacevariable{subbackward}{زیرعقب‌گرد}
+\setinterfacevariable{subformula}{زیرفرمول}
+\setinterfacevariable{subforward}{زیرجلوگرد}
+\setinterfacevariable{subject}{موضوع}
+\setinterfacevariable{subpage}{زیرصفحه}
+\setinterfacevariable{subsection}{زیربخش}
+\setinterfacevariable{subsubject}{زیرموضوع}
+\setinterfacevariable{subsubsection}{زیرزیربخش}
+\setinterfacevariable{subsubsubject}{زیرزیرموضوع}
+\setinterfacevariable{subsubsubsection}{زیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubject}{زیرزیرزیرموضوع}
+\setinterfacevariable{subsubsubsubsection}{زیرزیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubsubject}{زیرزیرزیرزیرموضوع}
+\setinterfacevariable{subsubsubsubsubsection}{زیرزیرزیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubsubsubject}{زیرزیرزیرزیرزیرموضوع}
+\setinterfacevariable{subsubsubsubsubsubsection}{زیرزیرزیرزیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubsubsubsubject}{زیرزیرزیرزیرزیرزیرموضوع}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{زیرزیرزیرزیرزیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{زیرزیرزیرزیرزیرزیرزیرموضوع}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{زیرزیرزیرزیرزیرزیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{زیرزیرزیرزیرزیرزیرزیرزیرموضوع}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{زیرزیرزیرزیرزیرزیرزیرزیرزیربخش}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{زیرزیرزیرزیرزیرزیرزیرزیرزیرموضوع}
+\setinterfacevariable{sunday}{یک‌شنبه}
+\setinterfacevariable{support}{حمایت}
+\setinterfacevariable{sym}{نم}
+\setinterfacevariable{symbol}{نماد}
+\setinterfacevariable{synchronize}{تطابق}
+\setinterfacevariable{system}{سیستم}
+\setinterfacevariable{table}{جدول}
+\setinterfacevariable{tablehead}{سرجدول}
+\setinterfacevariable{tables}{جدولها}
+\setinterfacevariable{tabletail}{دنباله‌جدول}
+\setinterfacevariable{tabulate}{جدول‌بندی}
+\setinterfacevariable{tabulatehead}{سرجدول‌بندی}
+\setinterfacevariable{tabulatetail}{دنباله‌جدول‌بندی}
+\setinterfacevariable{tall}{دراز}
+\setinterfacevariable{teletype}{دورنگاره}
+\setinterfacevariable{temporary}{موقتی}
+\setinterfacevariable{test}{تست}
+\setinterfacevariable{text}{متن}
+\setinterfacevariable{three}{سه}
+\setinterfacevariable{thursday}{پنج‌شنبه}
+\setinterfacevariable{title}{عنوان}
+\setinterfacevariable{toggle}{تغییر}
+\setinterfacevariable{tolerant}{بردبار}
+\setinterfacevariable{top}{بالا}
+\setinterfacevariable{tuesday}{سه‌شنبه}
+\setinterfacevariable{two}{دو}
+\setinterfacevariable{txt}{txt}
+\setinterfacevariable{type}{تایپ}
+\setinterfacevariable{typing}{تایپ‌کردن}
+\setinterfacevariable{unavailable}{غیرموجود}
+\setinterfacevariable{underbar}{میله‌زیر}
+\setinterfacevariable{underbars}{میله‌‌های‌زیر}
+\setinterfacevariable{unit}{واحد}
+\setinterfacevariable{units}{واحدها}
+\setinterfacevariable{unknown}{ناشناس}
+\setinterfacevariable{unpacked}{غیرفشرده}
+\setinterfacevariable{up}{up}
+\setinterfacevariable{url}{url}
+\setinterfacevariable{used}{استفاده‌شده}
+\setinterfacevariable{value}{مقدار}
+\setinterfacevariable{vertical}{عمودی}
+\setinterfacevariable{very}{خیلی}
+\setinterfacevariable{verystrict}{خیلی‌سختگیر}
+\setinterfacevariable{verytolerant}{خیلی‌بردبار}
+\setinterfacevariable{weak}{هفته}
+\setinterfacevariable{wednesday}{چهارشنبه}
+\setinterfacevariable{week}{هفته}
+\setinterfacevariable{weekday}{روزهفته}
+\setinterfacevariable{white}{سفید}
+\setinterfacevariable{wide}{گسترده}
+\setinterfacevariable{width}{عرض}
+\setinterfacevariable{xml}{xml}
+\setinterfacevariable{year}{سال}
+\setinterfacevariable{yes}{بله}
+% definitions for interface constants for language pe
+%
+\setinterfaceconstant{action}{کنش}
+\setinterfaceconstant{address}{نشانی}
+\setinterfaceconstant{after}{بعداز}
+\setinterfaceconstant{afterhead}{بعدازسر}
+\setinterfaceconstant{afterkey}{بعدازکلید}
+\setinterfaceconstant{align}{تنظیم}
+\setinterfaceconstant{aligncharacter}{حرف‌تنظیم}
+\setinterfaceconstant{alignmentcharacter}{حرف‌تنظیم‌کردن}
+\setinterfaceconstant{alignsymbol}{alignsymbol}
+\setinterfaceconstant{aligntitle}{عنوان‌تنظیم}
+\setinterfaceconstant{alternative}{جایگزین}
+\setinterfaceconstant{andtext}{andtext}
+\setinterfaceconstant{apa}{apa}
+\setinterfaceconstant{arrow}{پیکان}
+\setinterfaceconstant{artauthor}{artauthor}
+\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay}
+\setinterfaceconstant{artauthoretallimit}{artauthoretallimit}
+\setinterfaceconstant{artauthoretaltext}{artauthoretaltext}
+\setinterfaceconstant{at}{در}
+\setinterfaceconstant{author}{نویسنده}
+\setinterfaceconstant{authoretaldisplay}{authoretaldisplay}
+\setinterfaceconstant{authoretallimit}{authoretallimit}
+\setinterfaceconstant{authoretaltext}{authoretaltext}
+\setinterfaceconstant{auto}{خودکار}
+\setinterfaceconstant{autofile}{پرونده‌خودکار}
+\setinterfaceconstant{autofocus}{تمرکز‌خودکار}
+\setinterfaceconstant{autohang}{آویزان‌خودکار}
+\setinterfaceconstant{autostrut}{بست‌خودکار}
+\setinterfaceconstant{autowidth}{عرض‌خودکار}
+\setinterfaceconstant{axis}{محورها}
+\setinterfaceconstant{background}{پس‌زمینه}
+\setinterfaceconstant{backgroundcolor}{رنگ‌پس‌زمینه}
+\setinterfaceconstant{backgroundcorner}{گوشه‌پس‌زمینه}
+\setinterfaceconstant{backgrounddepth}{عمق‌پس‌زمینه}
+\setinterfaceconstant{backgroundoffset}{آفست‌پس‌زمینه}
+\setinterfaceconstant{backgroundradius}{شعاع‌پس‌زمینه}
+\setinterfaceconstant{backgroundscreen}{پرده‌پس‌زمینه}
+\setinterfaceconstant{backreference}{backreference}
+\setinterfaceconstant{backspace}{فضای‌پس}
+\setinterfaceconstant{balance}{تعادل}
+\setinterfaceconstant{before}{قبل‌از}
+\setinterfaceconstant{beforehead}{قبل‌ازسر}
+\setinterfaceconstant{bet}{bet}
+\setinterfaceconstant{big}{بزرگ}
+\setinterfaceconstant{blank}{خالی}
+\setinterfaceconstant{blockway}{راه‌بلوک}
+\setinterfaceconstant{bodyfont}{قلم‌بدنه}
+\setinterfaceconstant{bookmark}{چوبخط}
+\setinterfaceconstant{bottom}{پایین}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
+\setinterfaceconstant{bottomdistance}{فاصله‌پایین}
+\setinterfaceconstant{bottomframe}{قالب‌پایین}
+\setinterfaceconstant{bottomoffset}{آفست‌پایین}
+\setinterfaceconstant{bottomspace}{فضای‌پایین}
+\setinterfaceconstant{bottomstate}{وضعیت‌پایین}
+\setinterfaceconstant{cache}{میانگیر}
+\setinterfaceconstant{calculate}{محاسبه}
+\setinterfaceconstant{ccommand}{فرمان}
+\setinterfaceconstant{click}{فشردن}
+\setinterfaceconstant{clickin}{فشردن‌داخل}
+\setinterfaceconstant{clickout}{فشردن‌خارج}
+\setinterfaceconstant{clipoffset}{آفست‌کلیپ}
+\setinterfaceconstant{closeaction}{بستن‌کنش}
+\setinterfaceconstant{closecommand}{بستن‌فرمان}
+\setinterfaceconstant{closepageaction}{بستن‌عمل‌صفحه}
+\setinterfaceconstant{closesymbol}{بستن‌نماد}
+\setinterfaceconstant{color}{رنگ}
+\setinterfaceconstant{column}{ستون}
+\setinterfaceconstant{columndistance}{فاصله‌ستون}
+\setinterfaceconstant{columns}{ستونها}
+\setinterfaceconstant{command}{فرمان}
+\setinterfaceconstant{commandafter}{فرمان‌بعداز}
+\setinterfaceconstant{commandbefore}{فرمان‌قبل‌از}
+\setinterfaceconstant{commands}{فرمانها}
+\setinterfaceconstant{component}{مولفه}
+\setinterfaceconstant{compoundhyphen}{compoundhyphen}
+\setinterfaceconstant{compress}{فشردن}
+\setinterfaceconstant{connector}{connector}
+\setinterfaceconstant{continue}{ادامه}
+\setinterfaceconstant{contrastcolor}{contrastcolor}
+\setinterfaceconstant{controls}{کنترلها}
+\setinterfaceconstant{conversion}{تبدیل}
+\setinterfaceconstant{convertfile}{پرونده‌تبدیل}
+\setinterfaceconstant{corner}{گوشه}
+\setinterfaceconstant{coupling}{تزویج}
+\setinterfaceconstant{couplingway}{روش‌تزویج}
+\setinterfaceconstant{criterium}{criterium}
+\setinterfaceconstant{current}{جاری}
+\setinterfaceconstant{cutspace}{فضای‌برش}
+\setinterfaceconstant{dash}{دش}
+\setinterfaceconstant{dat}{dat}
+\setinterfaceconstant{database}{database}
+\setinterfaceconstant{date}{تاریخ}
+\setinterfaceconstant{deepnumbercommand}{فرمان‌شماره‌عمیق}
+\setinterfaceconstant{deeptextcommand}{فرمان‌متن‌عمیق}
+\setinterfaceconstant{default}{پیش‌فرض}
+\setinterfaceconstant{delay}{تاخیر}
+\setinterfaceconstant{depth}{عمق}
+\setinterfaceconstant{depthcorrection}{تصحیح‌عمق}
+\setinterfaceconstant{direction}{جهت}
+\setinterfaceconstant{directory}{پوشه}
+\setinterfaceconstant{display}{نمایش}
+\setinterfaceconstant{distance}{فاصله}
+\setinterfaceconstant{dot}{نقطه}
+\setinterfaceconstant{doublesided}{دورو}
+\setinterfaceconstant{dummy}{مصنوعی}
+\setinterfaceconstant{dx}{dx}
+\setinterfaceconstant{dy}{dy}
+\setinterfaceconstant{edge}{لبه}
+\setinterfaceconstant{edgedistance}{فاصله‌لبه}
+\setinterfaceconstant{editor}{editor}
+\setinterfaceconstant{editoretaldisplay}{editoretaldisplay}
+\setinterfaceconstant{editoretallimit}{editoretallimit}
+\setinterfaceconstant{editoretaltext}{editoretaltext}
+\setinterfaceconstant{empty}{تهی}
+\setinterfaceconstant{equalheight}{ارتفاع‌یکسان}
+\setinterfaceconstant{equalwidth}{عرض‌یکسان}
+\setinterfaceconstant{escape}{فرار}
+\setinterfaceconstant{evenmargin}{حاشیه‌زوج}
+\setinterfaceconstant{expansion}{گسترش}
+\setinterfaceconstant{export}{export}
+\setinterfaceconstant{extras}{extras}
+\setinterfaceconstant{factor}{عامل}
+\setinterfaceconstant{fallback}{عقب‌ریختن}
+\setinterfaceconstant{family}{خانواده}
+\setinterfaceconstant{fieldbackgroundcolor}{رنگ‌پس‌زمینه‌میدان}
+\setinterfaceconstant{fieldframecolor}{رنگ‌قالب‌میدان}
+\setinterfaceconstant{fieldlayer}{لایه‌میدان}
+\setinterfaceconstant{fieldoffset}{آفست‌میدان}
+\setinterfaceconstant{file}{پرونده}
+\setinterfaceconstant{filtercommand}{filtercommand}
+\setinterfaceconstant{finalnamesep}{finalnamesep}
+\setinterfaceconstant{firstnamesep}{firstnamesep}
+\setinterfaceconstant{focus}{تمرکز}
+\setinterfaceconstant{focusin}{تمرکزدرون}
+\setinterfaceconstant{focusout}{تمرکزبیرون}
+\setinterfaceconstant{footer}{ته‌برگ}
+\setinterfaceconstant{footerdistance}{فاصله‌ته‌برگ}
+\setinterfaceconstant{footerstate}{وضعیت‌ته‌برگ}
+\setinterfaceconstant{force}{اجبار}
+\setinterfaceconstant{foregroundcolor}{رنگ‌پیش‌زمینه}
+\setinterfaceconstant{foregroundstyle}{سبک‌پیش‌زمینه}
+\setinterfaceconstant{format}{شمایل}
+\setinterfaceconstant{frame}{قالب}
+\setinterfaceconstant{framecolor}{رنگ‌قالب}
+\setinterfaceconstant{framecorner}{گوشه‌قالب}
+\setinterfaceconstant{framedepth}{عمق‌قالب}
+\setinterfaceconstant{frameoffset}{آفست‌قالب}
+\setinterfaceconstant{frameradius}{شعاع‌قالب}
+\setinterfaceconstant{frames}{قالبها}
+\setinterfaceconstant{from}{از}
+\setinterfaceconstant{get}{بگیر}
+\setinterfaceconstant{global}{سراسری}
+\setinterfaceconstant{grid}{توری}
+\setinterfaceconstant{hang}{بیاویز}
+\setinterfaceconstant{headalign}{headalign}
+\setinterfaceconstant{headcolor}{رنگ‌سر}
+\setinterfaceconstant{headcommand}{فرمان‌سر}
+\setinterfaceconstant{headconversion}{تبدیل‌سر}
+\setinterfaceconstant{header}{سربرگ}
+\setinterfaceconstant{headerdistance}{فاصله‌سربرگ}
+\setinterfaceconstant{headerstate}{وضعیت‌سربرگ}
+\setinterfaceconstant{headlabel}{برچسب‌سر}
+\setinterfaceconstant{headnumber}{شماره‌سر}
+\setinterfaceconstant{headstyle}{سبک‌سر}
+\setinterfaceconstant{height}{ارتفاع}
+\setinterfaceconstant{hfactor}{عامل‌ارتفاع}
+\setinterfaceconstant{hfil}{پرکردن‌ارتفاع}
+\setinterfaceconstant{hidenumber}{hidenumber}
+\setinterfaceconstant{hoffset}{آفست‌ا}
+\setinterfaceconstant{horoffset}{آفست‌افق}
+\setinterfaceconstant{hyphen}{شکستن}
+\setinterfaceconstant{icommand}{icommand}
+\setinterfaceconstant{in}{درون}
+\setinterfaceconstant{inbetween}{دربین}
+\setinterfaceconstant{increment}{افزایش}
+\setinterfaceconstant{incrementnumber}{شماره‌افزایش}
+\setinterfaceconstant{indenting}{تورفتگی}
+\setinterfaceconstant{indentnext}{متن‌تورفته}
+\setinterfaceconstant{indicator}{اندیکاتور}
+\setinterfaceconstant{inner}{داخلی}
+\setinterfaceconstant{innermargin}{حاشیه‌داخلی}
+\setinterfaceconstant{inputfile}{پرونده‌ورودی}
+\setinterfaceconstant{intent}{intent}
+\setinterfaceconstant{interaction}{پانل}
+\setinterfaceconstant{interlinespace}{فضای‌بین‌خط}
+\setinterfaceconstant{internalgrid}{internalgrid}
+\setinterfaceconstant{itemalign}{تنظیم‌آیتم}
+\setinterfaceconstant{items}{آیتمها}
+\setinterfaceconstant{juniorsep}{juniorsep}
+\setinterfaceconstant{ken}{ken}
+\setinterfaceconstant{keyexpansion}{گسترش‌کلید}
+\setinterfaceconstant{keyword}{کلید‌واژه}
+\setinterfaceconstant{label}{برچسب}
+\setinterfaceconstant{lastnamesep}{lastnamesep}
+\setinterfaceconstant{lastpubsep}{lastpubsep}
+\setinterfaceconstant{left}{چپ}
+\setinterfaceconstant{leftcolor}{رنگ‌چپ}
+\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen}
+\setinterfaceconstant{leftedge}{لبه‌چپ}
+\setinterfaceconstant{leftedgedistance}{فاصله‌لبه‌چپ}
+\setinterfaceconstant{leftframe}{قالب‌چپ}
+\setinterfaceconstant{lefthyphen}{شکست‌چپ}
+\setinterfaceconstant{leftmargin}{حاشیه‌چپ}
+\setinterfaceconstant{leftmargindistance}{فاصله‌حاشیه‌چپ}
+\setinterfaceconstant{leftoffset}{آفست‌چپ}
+\setinterfaceconstant{leftquotation}{نقل‌قول‌چپ}
+\setinterfaceconstant{leftquote}{نقل‌چپ}
+\setinterfaceconstant{leftsentence}{جمله‌چپ}
+\setinterfaceconstant{leftspeech}{سخنرانی‌چپ}
+\setinterfaceconstant{leftstyle}{سبک‌چپ}
+\setinterfaceconstant{leftsubsentence}{زیرجمله‌چپ}
+\setinterfaceconstant{lefttext}{متن‌چپ}
+\setinterfaceconstant{leftwidth}{عرض‌خط}
+\setinterfaceconstant{level}{مرحله}
+\setinterfaceconstant{levels}{مرحله‌ها}
+\setinterfaceconstant{limittext}{مرزمتن}
+\setinterfaceconstant{line}{خط}
+\setinterfaceconstant{linecorrection}{تصحیح‌خط}
+\setinterfaceconstant{lines}{خطها}
+\setinterfaceconstant{list}{لیست}
+\setinterfaceconstant{listtext}{متن‌لیست}
+\setinterfaceconstant{local}{موضعی}
+\setinterfaceconstant{location}{مکان}
+\setinterfaceconstant{logo}{آرم}
+\setinterfaceconstant{logos}{آرمها}
+\setinterfaceconstant{marcolor}{رنگ‌حاش}
+\setinterfaceconstant{margin}{حاشیه}
+\setinterfaceconstant{margindistance}{فاصله‌حاشیه}
+\setinterfaceconstant{marginedge}{لبه‌حاشیه}
+\setinterfaceconstant{marginedgetext}{متن‌لبه‌حاشیه}
+\setinterfaceconstant{margintext}{متن‌حاشیه}
+\setinterfaceconstant{marking}{نشانه‌گذاری}
+\setinterfaceconstant{marstyle}{سبک‌حاش}
+\setinterfaceconstant{max}{بیشترین}
+\setinterfaceconstant{maxdepth}{maxdepth}
+\setinterfaceconstant{maxheight}{بیشترین‌ارتفاع}
+\setinterfaceconstant{maxwidth}{بیشترین‌عرض}
+\setinterfaceconstant{maybeyear}{maybeyear}
+\setinterfaceconstant{menu}{منو}
+\setinterfaceconstant{method}{روش}
+\setinterfaceconstant{middle}{میان}
+\setinterfaceconstant{middlespeech}{سخنرانی‌میانی}
+\setinterfaceconstant{middletext}{متن‌میانی}
+\setinterfaceconstant{midsentence}{جمله‌میانی}
+\setinterfaceconstant{min}{کمترین}
+\setinterfaceconstant{mindepth}{کمترین‌عمق}
+\setinterfaceconstant{minheight}{کمترین‌ارتفاع}
+\setinterfaceconstant{minwidth}{کمترین‌عرض}
+\setinterfaceconstant{monthconversion}{monthconversion}
+\setinterfaceconstant{n}{n}
+\setinterfaceconstant{name}{نام}
+\setinterfaceconstant{namesep}{namesep}
+\setinterfaceconstant{nbottom}{nbottom}
+\setinterfaceconstant{nc}{nc}
+\setinterfaceconstant{next}{بعدی}
+\setinterfaceconstant{nl}{nl}
+\setinterfaceconstant{nleft}{nleft}
+\setinterfaceconstant{nlines}{nlines}
+\setinterfaceconstant{norm}{norm}
+\setinterfaceconstant{nr}{nr}
+\setinterfaceconstant{nright}{nright}
+\setinterfaceconstant{ntop}{ntop}
+\setinterfaceconstant{number}{شماره}
+\setinterfaceconstant{numbercolor}{رنگ‌شماره}
+\setinterfaceconstant{numbercommand}{فرمان‌شماره}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
+\setinterfaceconstant{numberdistance}{فاصله‌شماره}
+\setinterfaceconstant{numbering}{شماره‌گذاری}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
+\setinterfaceconstant{numberseparator}{جداکننده‌شماره}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstarter}{numberstarter}
+\setinterfaceconstant{numberstopper}{numberstopper}
+\setinterfaceconstant{numberstyle}{سبک‌شماره}
+\setinterfaceconstant{numberwidth}{عرض‌شماره}
+\setinterfaceconstant{nx}{nx}
+\setinterfaceconstant{ny}{ny}
+\setinterfaceconstant{object}{شیئ}
+\setinterfaceconstant{obstruction}{انسداد}
+\setinterfaceconstant{oddmargin}{حاشیه‌فرد}
+\setinterfaceconstant{offset}{آفست}
+\setinterfaceconstant{openaction}{عمل‌باز}
+\setinterfaceconstant{openpageaction}{عمل‌صفحه‌باز}
+\setinterfaceconstant{option}{گزینه}
+\setinterfaceconstant{order}{order}
+\setinterfaceconstant{orientation}{جهت‌دهی}
+\setinterfaceconstant{otherstext}{otherstext}
+\setinterfaceconstant{outermargin}{حاشیه‌خارجی}
+\setinterfaceconstant{overprint}{overprint}
+\setinterfaceconstant{ownnumber}{شماره‌خود}
+\setinterfaceconstant{page}{صفحه}
+\setinterfaceconstant{pageboundaries}{مرزهای‌صفحه}
+\setinterfaceconstant{pagecolor}{رنگ‌صفحه}
+\setinterfaceconstant{pagecommand}{فرمان‌صفحه}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
+\setinterfaceconstant{pagenumber}{شماره‌صفحه}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstarter}{pageprefixstarter}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
+\setinterfaceconstant{pagestarter}{pagestarter}
+\setinterfaceconstant{pagestate}{وضعیت‌صفحه}
+\setinterfaceconstant{pagestopper}{pagestopper}
+\setinterfaceconstant{pagestyle}{سبک‌صفحه}
+\setinterfaceconstant{palet}{لوح}
+\setinterfaceconstant{paper}{برگ}
+\setinterfaceconstant{paragraph}{پاراگراف}
+\setinterfaceconstant{place}{بگذار}
+\setinterfaceconstant{placehead}{بگذارسر}
+\setinterfaceconstant{placestopper}{بگذارایست}
+\setinterfaceconstant{position}{موقعیت}
+\setinterfaceconstant{prefix}{پیشوند}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstarter}{prefixstarter}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
+\setinterfaceconstant{preset}{preset}
+\setinterfaceconstant{preview}{پیش‌دید}
+\setinterfaceconstant{previous}{قبلی}
+\setinterfaceconstant{previousnumber}{شماره‌قبلی}
+\setinterfaceconstant{process}{پردازش}
+\setinterfaceconstant{profile}{profile}
+\setinterfaceconstant{pubsep}{pubsep}
+\setinterfaceconstant{radius}{شعاع}
+\setinterfaceconstant{random}{تصادفی}
+\setinterfaceconstant{range}{range}
+\setinterfaceconstant{reduction}{کاهش}
+\setinterfaceconstant{ref}{رج}
+\setinterfaceconstant{refcommand}{refcommand}
+\setinterfaceconstant{reference}{مرجع}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
+\setinterfaceconstant{referencing}{مراجعه}
+\setinterfaceconstant{regionin}{ناحیه‌درون}
+\setinterfaceconstant{regionout}{ناحیه‌بیرون}
+\setinterfaceconstant{repeat}{تکرار}
+\setinterfaceconstant{reset}{بازنشانی}
+\setinterfaceconstant{resetnumber}{بازنشانی‌شماره}
+\setinterfaceconstant{resolution}{کیفیت}
+\setinterfaceconstant{right}{راست}
+\setinterfaceconstant{rightcolor}{رنگ‌راست}
+\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen}
+\setinterfaceconstant{rightedge}{لبه‌راست}
+\setinterfaceconstant{rightedgedistance}{فاصله‌لبه‌راست}
+\setinterfaceconstant{rightframe}{قالب‌راست}
+\setinterfaceconstant{righthyphen}{righthyphen}
+\setinterfaceconstant{rightmargin}{حاشیه‌راست}
+\setinterfaceconstant{rightmargindistance}{فاصله‌حاشیه‌راست}
+\setinterfaceconstant{rightoffset}{آفست‌راست}
+\setinterfaceconstant{rightquotation}{نقل‌قول‌راست}
+\setinterfaceconstant{rightquote}{نقل‌راست}
+\setinterfaceconstant{rightsentence}{جمله‌راست}
+\setinterfaceconstant{rightspeech}{سخنرانی‌راست}
+\setinterfaceconstant{rightstyle}{سبک‌راست}
+\setinterfaceconstant{rightsubsentence}{زیرجمله‌راست}
+\setinterfaceconstant{righttext}{متن‌راست}
+\setinterfaceconstant{rightwidth}{عرض‌راست}
+\setinterfaceconstant{rotation}{دوران}
+\setinterfaceconstant{rule}{خط}
+\setinterfaceconstant{rulecolor}{رنگ‌خط}
+\setinterfaceconstant{rulethickness}{ضخامت‌خط}
+\setinterfaceconstant{samepage}{همان‌صفحه}
+\setinterfaceconstant{sample}{نمونه}
+\setinterfaceconstant{samplesize}{samplesize}
+\setinterfaceconstant{saveinlist}{saveinlist}
+\setinterfaceconstant{scale}{مقیاس}
+\setinterfaceconstant{scope}{طرح}
+\setinterfaceconstant{screen}{پرده}
+\setinterfaceconstant{section}{بخش}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
+\setinterfaceconstant{sectionnumber}{شماره‌بخش}
+\setinterfaceconstant{sectionresetset}{sectionresetset}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstarter}{sectionstarter}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
+\setinterfaceconstant{separator}{جداکننده}
+\setinterfaceconstant{set}{قراربده}
+\setinterfaceconstant{setups}{بارگذاریها}
+\setinterfaceconstant{side}{کنار}
+\setinterfaceconstant{sidealign}{تنظیم‌کنار}
+\setinterfaceconstant{sidemethod}{روش‌کنار}
+\setinterfaceconstant{sidespaceafter}{فضای‌کناری‌بعد}
+\setinterfaceconstant{sidespacebefore}{فضای‌کناری‌قبل}
+\setinterfaceconstant{sign}{علامت}
+\setinterfaceconstant{size}{اندازه}
+\setinterfaceconstant{small}{کوچک}
+\setinterfaceconstant{sort}{sort}
+\setinterfaceconstant{sorttype}{ترتیب‌تایپ}
+\setinterfaceconstant{source}{منبع}
+\setinterfaceconstant{space}{فضا}
+\setinterfaceconstant{spaceafter}{فضا‌بعداز}
+\setinterfaceconstant{spacebefore}{فضا‌قبل‌از}
+\setinterfaceconstant{spaceinbetween}{فضا‌دربین}
+\setinterfaceconstant{spacing}{فضاگذاری}
+\setinterfaceconstant{split}{شکافتن}
+\setinterfaceconstant{splitcolor}{شکافتن‌رنگ}
+\setinterfaceconstant{splitmethod}{روش‌شکافتن}
+\setinterfaceconstant{splitoffset}{شکافتن‌آفست}
+\setinterfaceconstant{spot}{لکه}
+\setinterfaceconstant{stack}{توده}
+\setinterfaceconstant{start}{شروع}
+\setinterfaceconstant{starter}{starter}
+\setinterfaceconstant{state}{وضعیت}
+\setinterfaceconstant{step}{گام}
+\setinterfaceconstant{stop}{پایان}
+\setinterfaceconstant{stopper}{ایست}
+\setinterfaceconstant{stretch}{کشیدن}
+\setinterfaceconstant{strip}{strip}
+\setinterfaceconstant{strut}{بست}
+\setinterfaceconstant{style}{سبک}
+\setinterfaceconstant{sub}{زیر}
+\setinterfaceconstant{subtitle}{زیرعنوان}
+\setinterfaceconstant{suffix}{پسوند}
+\setinterfaceconstant{surnamesep}{surnamesep}
+\setinterfaceconstant{sx}{sx}
+\setinterfaceconstant{sy}{sy}
+\setinterfaceconstant{symalign}{تنظیم‌نماد}
+\setinterfaceconstant{symbol}{نماد}
+\setinterfaceconstant{symbolset}{مجموعه‌نماد}
+\setinterfaceconstant{symcolor}{رنگ‌نماد}
+\setinterfaceconstant{symstyle}{سبک‌نماد}
+\setinterfaceconstant{synonym}{مترادف}
+\setinterfaceconstant{synonymcolor}{رنگ‌مترادف}
+\setinterfaceconstant{synonymcommand}{synonymcommand}
+\setinterfaceconstant{synonymstyle}{سبک‌مترادف}
+\setinterfaceconstant{tab}{تب}
+\setinterfaceconstant{text}{متن}
+\setinterfaceconstant{textcolor}{رنگ‌متن}
+\setinterfaceconstant{textcommand}{فرمان‌متن}
+\setinterfaceconstant{textdistance}{فاصله‌متن}
+\setinterfaceconstant{textlayer}{لایه‌متن}
+\setinterfaceconstant{textmargin}{حاشیه‌متن}
+\setinterfaceconstant{textmethod}{روش‌متن}
+\setinterfaceconstant{textseparator}{جداکننده‌متن}
+\setinterfaceconstant{textsize}{اندازه‌متن}
+\setinterfaceconstant{textstate}{وضعیت‌متن}
+\setinterfaceconstant{textstyle}{سبک‌متن}
+\setinterfaceconstant{textwidth}{عرض‌متن}
+\setinterfaceconstant{title}{عنوان}
+\setinterfaceconstant{titlecolor}{رنگ‌عنوان}
+\setinterfaceconstant{titlecommand}{فرمان‌عنوان}
+\setinterfaceconstant{titledistance}{فاصله‌عنوان}
+\setinterfaceconstant{titleleft}{عنوان‌چپ}
+\setinterfaceconstant{titleright}{عنوان‌راست}
+\setinterfaceconstant{titlestyle}{سبک‌عنوان}
+\setinterfaceconstant{to}{به}
+\setinterfaceconstant{tolerance}{بردباری}
+\setinterfaceconstant{top}{بالا}
+\setinterfaceconstant{topdistance}{فاصله‌بالا}
+\setinterfaceconstant{topframe}{قالب‌راست}
+\setinterfaceconstant{topoffset}{آفست‌بالا}
+\setinterfaceconstant{topspace}{فضای‌بالا}
+\setinterfaceconstant{topstate}{وضعیت‌بالا}
+\setinterfaceconstant{totalnumber}{totalnumber}
+\setinterfaceconstant{type}{تایپ}
+\setinterfaceconstant{unit}{واحد}
+\setinterfaceconstant{unknownreference}{مرجع‌ناشناس}
+\setinterfaceconstant{urlalternative}{urlalternative}
+\setinterfaceconstant{urlspace}{urlspace}
+\setinterfaceconstant{validate}{تاییداعتبار}
+\setinterfaceconstant{vcommand}{vcommand}
+\setinterfaceconstant{veroffset}{آفست‌عم}
+\setinterfaceconstant{vfil}{vfil}
+\setinterfaceconstant{voffset}{آفست‌ع}
+\setinterfaceconstant{vonsep}{vonsep}
+\setinterfaceconstant{way}{راه}
+\setinterfaceconstant{wfactor}{wfactor}
+\setinterfaceconstant{white}{سفید}
+\setinterfaceconstant{width}{عرض}
+\setinterfaceconstant{xfactor}{فاکتورایکس}
+\setinterfaceconstant{xmax}{xmax}
+\setinterfaceconstant{xoffset}{آفست‌ایکس}
+\setinterfaceconstant{xscale}{مقیاس‌ایکس}
+\setinterfaceconstant{xstep}{گام‌ایکس}
+\setinterfaceconstant{yfactor}{فاکتوروای}
+\setinterfaceconstant{ymax}{ymax}
+\setinterfaceconstant{yoffset}{آفست‌وای}
+\setinterfaceconstant{yscale}{مقیاس‌وای}
+\setinterfaceconstant{ystep}{گام‌وای}
+% definitions for interface elements for language pe
+%
+\setinterfaceelement{answerlines}{answerlines}
+\setinterfaceelement{answerspace}{answerspace}
+\setinterfaceelement{begin}{عنصرها}
+\setinterfaceelement{complete}{کامل}
+\setinterfaceelement{coupled}{مزدوج}
+\setinterfaceelement{currentlocal}{موضعی‌جاری}
+\setinterfaceelement{emptyone}{یک‌خالی}
+\setinterfaceelement{emptytwo}{دوخالی}
+\setinterfaceelement{end}{انتها}
+\setinterfaceelement{endsetup}{انتهای‌بارگذاری}
+\setinterfaceelement{get}{بگیر}
+\setinterfaceelement{increment}{افزایش}
+\setinterfaceelement{list}{لیست}
+\setinterfaceelement{listof}{لیست‌از}
+\setinterfaceelement{load}{بارگذاشتن}
+\setinterfaceelement{local}{موضعی}
+\setinterfaceelement{makeup}{آرایش}
+\setinterfaceelement{next}{بعدی}
+\setinterfaceelement{place}{مکان}
+\setinterfaceelement{previous}{قبلی}
+\setinterfaceelement{previouslocal}{موضع‌قبلی}
+\setinterfaceelement{reserve}{رزرو}
+\setinterfaceelement{see}{ببینید}
+\setinterfaceelement{setup}{بارگذاری}
+\setinterfaceelement{start}{شروع}
+\setinterfaceelement{stop}{پایان}
+\setinterfaceelement{text}{متن}
+\setinterfaceelement{type}{تایپ}
+% definitions for interface commands for language pe
+%
+\setinterfacecommand{CAPPED}{CAP}
+\setinterfacecommand{Character}{Character}
+\setinterfacecommand{Characters}{Characters}
+\setinterfacecommand{MONTH}{MONTH}
+\setinterfacecommand{Numbers}{Numbers}
+\setinterfacecommand{Romannumerals}{Romannumerals}
+\setinterfacecommand{SmallCapped}{Cap}
+\setinterfacecommand{SmallCaps}{Caps}
+\setinterfacecommand{WEEKDAY}{WEEKDAY}
+\setinterfacecommand{WORD}{WORD}
+\setinterfacecommand{WORDS}{WORDS}
+\setinterfacecommand{Word}{Word}
+\setinterfacecommand{Words}{Words}
+\setinterfacecommand{about}{درمورد}
+\setinterfacecommand{adaptlayout}{تنظیم‌طرح‌بندی}
+\setinterfacecommand{arg}{افزودن}
+\setinterfacecommand{at}{در}
+\setinterfacecommand{atleftmargin}{درحاشیه‌چپ}
+\setinterfacecommand{atpage}{درصفحه}
+\setinterfacecommand{atrightmargin}{درحاشیه‌راست}
+\setinterfacecommand{background}{پس‌زمینه}
+\setinterfacecommand{backspace}{فاصله‌پشت}
+\setinterfacecommand{blackrule}{خط‌سیاه}
+\setinterfacecommand{blackrules}{خطهای‌سیاه}
+\setinterfacecommand{blank}{خالی}
+\setinterfacecommand{bookmark}{چوبخط}
+\setinterfacecommand{bottomdistance}{فاصله‌پایین}
+\setinterfacecommand{bottomheight}{ارتفاع‌پایین}
+\setinterfacecommand{bottomspace}{فضای‌پایین}
+\setinterfacecommand{but}{اما}
+\setinterfacecommand{button}{دکمه}
+\setinterfacecommand{bypassblocks}{عبوربلوکها}
+\setinterfacecommand{character}{حرف}
+\setinterfacecommand{characters}{حرفها}
+\setinterfacecommand{chem}{chem}
+\setinterfacecommand{clip}{گیره}
+\setinterfacecommand{clonefield}{میدان‌شبیه‌سازی}
+\setinterfacecommand{color}{رنگ}
+\setinterfacecommand{colorbar}{میله‌رنگ}
+\setinterfacecommand{colorvalue}{مقداررنگ}
+\setinterfacecommand{column}{ستون}
+\setinterfacecommand{comment}{توضیح}
+\setinterfacecommand{comparecolorgroup}{مقایسه‌گروه‌رنگ}
+\setinterfacecommand{comparepalet}{لوح‌مقایسه}
+\setinterfacecommand{completepagenumber}{شماره‌صفحه‌کامل}
+\setinterfacecommand{completeregister}{ثبت‌کامل}
+\setinterfacecommand{component}{مولفه}
+\setinterfacecommand{convertnumber}{شماره‌مبدل}
+\setinterfacecommand{copyfield}{میدان‌کپی}
+\setinterfacecommand{correctwhitespace}{فضای‌سفیدصحیح}
+\setinterfacecommand{coupledocument}{نوشتارزوج}
+\setinterfacecommand{couplemarking}{نشانه‌گذاری‌زوج}
+\setinterfacecommand{couplepage}{صفحه‌زوج}
+\setinterfacecommand{couplepaper}{کاغذزوج}
+\setinterfacecommand{coupleregister}{ثبت‌زوج}
+\setinterfacecommand{crlf}{crlf}
+\setinterfacecommand{currentdate}{تاریخ‌جاری}
+\setinterfacecommand{currentheadnumber}{شماره‌سرجاری}
+\setinterfacecommand{cutspace}{فضای‌برش}
+\setinterfacecommand{date}{تاریخ}
+\setinterfacecommand{decouplemarking}{جداسازی‌نشانه‌گذاری}
+\setinterfacecommand{decrementnumber}{شماره‌کاهش}
+\setinterfacecommand{define}{تعریف}
+\setinterfacecommand{defineaccent}{تعریف‌لهجه}
+\setinterfacecommand{defineblank}{تعریف‌خالی}
+\setinterfacecommand{defineblock}{تعریف‌بلوک}
+\setinterfacecommand{definebodyfont}{تعریف‌قلم‌متن}
+\setinterfacecommand{definebodyfontenvironment}{تعریف‌محیط‌قلم‌بدنه}
+\setinterfacecommand{definebuffer}{تعریف‌بافر}
+\setinterfacecommand{definecharacter}{تعریف‌حرف}
+\setinterfacecommand{definecolor}{تعریف‌رنگ}
+\setinterfacecommand{definecolorgroup}{تعریف‌گروه‌رنگ}
+\setinterfacecommand{definecolumnbreak}{تعریف‌شکستن‌ستون}
+\setinterfacecommand{definecolumnset}{تعریف‌مجموعه‌ستون}
+\setinterfacecommand{definecombination}{تعریف‌ترکیب}
+\setinterfacecommand{definecombinedlist}{تعریف‌لیست‌ترکیبی}
+\setinterfacecommand{definecommand}{تعریف‌فرمان}
+\setinterfacecommand{defineconversion}{تعریف‌تبدیل}
+\setinterfacecommand{definedescription}{تعریف‌شرح}
+\setinterfacecommand{defineenumeration}{تعریف‌شماره‌بندی}
+\setinterfacecommand{definefield}{تعریف‌میدان}
+\setinterfacecommand{definefieldstack}{تعریف‌توده‌میدان}
+\setinterfacecommand{definefiguresymbol}{تعریف‌نمادشکل}
+\setinterfacecommand{definefloat}{تعریف‌شناور}
+\setinterfacecommand{definefont}{تعریف‌قلم}
+\setinterfacecommand{definefontstyle}{تعریف‌سبک‌قلم}
+\setinterfacecommand{definefontsynonym}{تعریف‌مترادف‌قلم}
+\setinterfacecommand{defineframed}{تعریف‌قالبی}
+\setinterfacecommand{defineframedtext}{تعریف‌متن‌قالبی}
+\setinterfacecommand{definehbox}{تعریف‌جعبه‌‌افقی}
+\setinterfacecommand{definehead}{تعریف‌سر}
+\setinterfacecommand{defineindenting}{تعریف‌تورفتگی}
+\setinterfacecommand{defineinmargin}{تعریف‌درون‌حاشیه}
+\setinterfacecommand{defineinteractionmenu}{تعریف‌منوی‌پانل}
+\setinterfacecommand{defineitemgroup}{تعریف‌گروه‌آیتم}
+\setinterfacecommand{definelabel}{تعریف‌برچسب}
+\setinterfacecommand{definelayer}{تعریف‌لایه}
+\setinterfacecommand{definelayout}{تعریف‌طرح‌بندی}
+\setinterfacecommand{definelist}{تعریف‌لیست}
+\setinterfacecommand{definelogo}{تعریف‌آرم}
+\setinterfacecommand{definemainfield}{تعریف‌میدان‌اصلی}
+\setinterfacecommand{definemakeup}{تعریف‌آرایش}
+\setinterfacecommand{definemarking}{تعریف‌نشانه‌گذاری}
+\setinterfacecommand{definemathalignment}{تعریف‌تنظیم‌ریاضی}
+\setinterfacecommand{defineoutput}{تعریف‌خروجی}
+\setinterfacecommand{defineoverlay}{تعریف‌پوشش}
+\setinterfacecommand{definepagebreak}{تعریف‌شکست‌صفحه}
+\setinterfacecommand{definepalet}{تعریف‌لوح}
+\setinterfacecommand{definepapersize}{تعریف‌اندازه‌برگ}
+\setinterfacecommand{defineparagraphs}{تعریف‌پاراگرافها}
+\setinterfacecommand{defineplacement}{تعریف‌جانشانی}
+\setinterfacecommand{defineprofile}{تعریف‌پروفایل}
+\setinterfacecommand{defineprogram}{تعریف‌برنامه}
+\setinterfacecommand{definerawfont}{تعریف‌قلم‌خام}
+\setinterfacecommand{definereference}{تعریف‌مرجع}
+\setinterfacecommand{definereferenceformat}{تعریف‌شمایل‌مرجع}
+\setinterfacecommand{definereferencelist}{تعریف‌لیست‌مرجع}
+\setinterfacecommand{defineregister}{تعریف‌ثبت}
+\setinterfacecommand{definerule}{تعریف‌خط‌حائل}
+\setinterfacecommand{definesection}{تعریف‌بخش}
+\setinterfacecommand{definesectionblock}{تعریف‌بلوک‌بخش}
+\setinterfacecommand{definesorting}{تعریف‌ترتیب}
+\setinterfacecommand{definestartstop}{تعریف‌شروع‌پایان}
+\setinterfacecommand{definestyle}{تعریف‌سبک}
+\setinterfacecommand{definesubfield}{تعریف‌زیرمیدان}
+\setinterfacecommand{definesymbol}{تعریف‌نماد}
+\setinterfacecommand{definesynonyms}{تعریف‌مترادفها}
+\setinterfacecommand{definetabletemplate}{تعریف‌الگوی‌جدول}
+\setinterfacecommand{definetabulate}{تعریف‌جدول‌بندی}
+\setinterfacecommand{definetext}{تعریف‌متن}
+\setinterfacecommand{definetextposition}{تعریف‌مکان‌متن}
+\setinterfacecommand{definetextvariable}{تعریف‌متغیرمتن}
+\setinterfacecommand{definetype}{تعریف‌تایپ}
+\setinterfacecommand{definetyping}{تعریف‌تایپ‌کردن}
+\setinterfacecommand{defineversion}{تعریف‌نسخه}
+\setinterfacecommand{determineheadnumber}{تعیین‌شماره‌سر}
+\setinterfacecommand{determinelistcharacteristics}{تعیین‌مشخصات‌لیست}
+\setinterfacecommand{determineregistercharacteristics}{تعیین‌مشخصات‌ثبت}
+\setinterfacecommand{dimension}{بعد}
+\setinterfacecommand{disableinteractionmenu}{ازکارانداختن‌منوی‌پانل}
+\setinterfacecommand{domicile}{مسکن}
+\setinterfacecommand{donttest}{امتحان‌نکن}
+\setinterfacecommand{edgedistance}{فاصله‌لبه}
+\setinterfacecommand{edgewidth}{عرض‌لبه}
+\setinterfacecommand{emptylines}{خطها‌خالی}
+\setinterfacecommand{environment}{محیط}
+\setinterfacecommand{externalfigure}{شکل‌خارجی}
+\setinterfacecommand{fact}{حقیقت}
+\setinterfacecommand{field}{میدان}
+\setinterfacecommand{fieldstack}{میدان‌پشته}
+\setinterfacecommand{fillinfield}{درج‌درمیدان}
+\setinterfacecommand{fillinline}{درج‌درخط}
+\setinterfacecommand{fillinrules}{درج‌درخطها}
+\setinterfacecommand{fillintext}{درج‌درمتن}
+\setinterfacecommand{fitfield}{پرکردن‌میدان}
+\setinterfacecommand{fixedspace}{فضای‌ثابت}
+\setinterfacecommand{fixedspaces}{فضاهای‌ثابت}
+\setinterfacecommand{followprofile}{پیروی‌پروفایل}
+\setinterfacecommand{followprofileversion}{پیروی‌نسخه‌پروفایل}
+\setinterfacecommand{followversion}{پیروی‌نسخه}
+\setinterfacecommand{footerdistance}{فاصله‌ته‌برگ}
+\setinterfacecommand{footerheight}{ارتفاع‌ته‌برگ}
+\setinterfacecommand{footnote}{پانوشت}
+\setinterfacecommand{footnotetext}{متن‌پانوشت}
+\setinterfacecommand{forceblocks}{اجباربلوکها}
+\setinterfacecommand{formulanumber}{شماره‌فرمول}
+\setinterfacecommand{fraction}{کسر}
+\setinterfacecommand{framed}{قالبی}
+\setinterfacecommand{from}{از}
+\setinterfacecommand{getbuffer}{دریافت‌بافر}
+\setinterfacecommand{getmarking}{دریافت‌نشانه}
+\setinterfacecommand{getnumber}{دریافت‌شماره}
+\setinterfacecommand{godown}{بروپایین}
+\setinterfacecommand{goto}{بروبه}
+\setinterfacecommand{gotobox}{بروبه‌جعبه}
+\setinterfacecommand{gotopage}{بروبه‌صفحه}
+\setinterfacecommand{graycolor}{رنگ‌خاکستری}
+\setinterfacecommand{greyvalue}{مقدارخاکستری}
+\setinterfacecommand{grid}{توری}
+\setinterfacecommand{hairline}{خط‌مو}
+\setinterfacecommand{head}{سر}
+\setinterfacecommand{headerdistance}{فاصله‌سربرگ}
+\setinterfacecommand{headerheight}{ارتفاع‌سربرگ}
+\setinterfacecommand{headlevel}{مرحله‌سر}
+\setinterfacecommand{headnumber}{شماره‌سر}
+\setinterfacecommand{headsym}{نمادسر}
+\setinterfacecommand{headtext}{متن‌سر}
+\setinterfacecommand{hideblocks}{بلوکها‌پنهان}
+\setinterfacecommand{high}{بلند}
+\setinterfacecommand{hl}{خ‌ا}
+\setinterfacecommand{immediatebetweenlist}{فوری‌بین‌لیست}
+\setinterfacecommand{immediatetolist}{فوری‌به‌لیست}
+\setinterfacecommand{in}{درون}
+\setinterfacecommand{incrementnumber}{شماره‌افزایش}
+\setinterfacecommand{indenting}{تورفتگی}
+\setinterfacecommand{inframed}{درقالبی}
+\setinterfacecommand{infull}{درپر}
+\setinterfacecommand{ininner}{درداخلی}
+\setinterfacecommand{inleft}{درچپ}
+\setinterfacecommand{inleftedge}{درلبه‌چپ}
+\setinterfacecommand{inleftmargin}{درحاشیه‌چپ}
+\setinterfacecommand{inline}{درخط}
+\setinterfacecommand{inmargin}{درحاشیه}
+\setinterfacecommand{inmframed}{inmframed}
+\setinterfacecommand{inneredgedistance}{فاصله‌لبه‌داخلی}
+\setinterfacecommand{inneredgewidth}{عرض‌لبه‌داخلی}
+\setinterfacecommand{innermargindistance}{فاصله‌حاشیه‌داخلی}
+\setinterfacecommand{innermarginwidth}{عرض‌حاشیه‌داخلی}
+\setinterfacecommand{inothermargin}{درحاشیه‌دیگر}
+\setinterfacecommand{inouter}{درخارجی}
+\setinterfacecommand{inright}{درراست}
+\setinterfacecommand{inrightedge}{درلبه‌راست}
+\setinterfacecommand{inrightmargin}{درحاشیه‌راست}
+\setinterfacecommand{installlanguage}{نصب‌زبان}
+\setinterfacecommand{interactionbar}{میله‌پانل}
+\setinterfacecommand{interactionbuttons}{دکمه‌پانل}
+\setinterfacecommand{interactionmenu}{منوی‌پانل}
+\setinterfacecommand{item}{آیتم}
+\setinterfacecommand{items}{آیتمها}
+\setinterfacecommand{its}{its}
+\setinterfacecommand{keepblocks}{حفظ‌بلوکها}
+\setinterfacecommand{label}{برچسب}
+\setinterfacecommand{labels}{برچسبها}
+\setinterfacecommand{labeltext}{متن‌برچسب}
+\setinterfacecommand{language}{زبان}
+\setinterfacecommand{leftaligned}{چپ‌چین}
+\setinterfacecommand{leftedgedistance}{فاصله‌لبه‌چپ}
+\setinterfacecommand{leftedgewidth}{عرض‌لبه‌چپ}
+\setinterfacecommand{leftmargindistance}{فاصله‌حاشیه‌چپ}
+\setinterfacecommand{leftmarginwidth}{عرض‌حاشیه‌چپ}
+\setinterfacecommand{leg}{پا}
+\setinterfacecommand{linewidth}{عرض‌خط}
+\setinterfacecommand{listheight}{ارتفاع‌خط}
+\setinterfacecommand{listlength}{طول‌لیست}
+\setinterfacecommand{listsymbol}{نمادلیست}
+\setinterfacecommand{listwidth}{عرض‌لیست}
+\setinterfacecommand{logfields}{میدانهای‌گزارش}
+\setinterfacecommand{lohi}{پابا}
+\setinterfacecommand{low}{پایین}
+\setinterfacecommand{macroname}{نام‌ماکرو}
+\setinterfacecommand{mainlanguage}{زبان‌اصلی}
+\setinterfacecommand{makeupheight}{ارتفاع‌آرایش}
+\setinterfacecommand{makeupwidth}{عرض‌آرایش}
+\setinterfacecommand{mar}{حاش}
+\setinterfacecommand{margindistance}{فاصله‌حاشیه}
+\setinterfacecommand{marginrule}{خط‌حاشیه}
+\setinterfacecommand{margintext}{متن‌حاشیه}
+\setinterfacecommand{margintitle}{عنوان‌حاشیه}
+\setinterfacecommand{marginwidth}{عرض‌حاشیه}
+\setinterfacecommand{marginword}{کلمه‌حاشیه}
+\setinterfacecommand{marking}{نشانه‌گذاری}
+\setinterfacecommand{markversion}{نسخه‌نشانه}
+\setinterfacecommand{mathematics}{ریاضی}
+\setinterfacecommand{menubutton}{دکمه‌منو}
+\setinterfacecommand{mframed}{mframed}
+\setinterfacecommand{midaligned}{تنظیم‌وسط}
+\setinterfacecommand{mirror}{آینه}
+\setinterfacecommand{month}{ماه}
+\setinterfacecommand{moveformula}{انتقال‌فرمول}
+\setinterfacecommand{moveongrid}{انتقال‌به‌توری}
+\setinterfacecommand{movesidefloat}{انتقال‌کنار‌شناور}
+\setinterfacecommand{navigating}{هدایت}
+\setinterfacecommand{nodimension}{بدون‌بعد}
+\setinterfacecommand{noheaderandfooterlines}{بدون‌خط‌سروته‌برگ}
+\setinterfacecommand{noindenting}{بدون‌تورفتگی}
+\setinterfacecommand{nolist}{بدون‌لیست}
+\setinterfacecommand{nomarking}{بدون‌نشانه‌گذاری}
+\setinterfacecommand{nomoreblocks}{بدون‌بلوکهای‌بیشتر}
+\setinterfacecommand{nomorefiles}{بدون‌فایلهای‌بیشتر}
+\setinterfacecommand{nop}{منفی}
+\setinterfacecommand{nospace}{بدون‌فضا}
+\setinterfacecommand{note}{یادداشت}
+\setinterfacecommand{notopandbottomlines}{بدون‌خط‌بالاوپایین}
+\setinterfacecommand{notsmallcapped}{سرپوش‌کوچک‌نه}
+\setinterfacecommand{nowhitespace}{بدون‌فضای‌سفید}
+\setinterfacecommand{numberofsubpages}{شماره‌زیرصفحه}
+\setinterfacecommand{numbers}{شماره‌ها}
+\setinterfacecommand{outeredgedistance}{فاصله‌لبه‌خارجی}
+\setinterfacecommand{outeredgewidth}{عرض‌لبه‌خارجی}
+\setinterfacecommand{outermargindistance}{فاصله‌حاشیه‌خارجی}
+\setinterfacecommand{outermarginwidth}{عرض‌حاشیه‌خارجی}
+\setinterfacecommand{packed}{فشرده}
+\setinterfacecommand{page}{صفحه}
+\setinterfacecommand{pagedepth}{عمق‌صفحه}
+\setinterfacecommand{pagenumber}{شماره‌صفحه}
+\setinterfacecommand{pageoffset}{آفست‌صفحه}
+\setinterfacecommand{pagereference}{مرجع‌صفحه}
+\setinterfacecommand{pagetype}{نوع‌صفحه}
+\setinterfacecommand{paperheight}{ارتفاع‌برگ}
+\setinterfacecommand{paperwidth}{عرض‌برگ}
+\setinterfacecommand{periods}{نقطه‌ها}
+\setinterfacecommand{plaatsruwelijst}{درج‌لیست‌خام}
+\setinterfacecommand{placebookmarks}{درج‌چوب‌خط}
+\setinterfacecommand{placecombinedlist}{درج‌لیست‌مختلط}
+\setinterfacecommand{placefloat}{درج‌شناور}
+\setinterfacecommand{placefootnotes}{درج‌پانوشتها}
+\setinterfacecommand{placeformula}{درج‌فرمول}
+\setinterfacecommand{placeheadnumber}{درج‌شماره‌سر}
+\setinterfacecommand{placeheadtext}{درج‌متن‌سر}
+\setinterfacecommand{placelegend}{درج‌راهنما}
+\setinterfacecommand{placelist}{درج‌لیست}
+\setinterfacecommand{placelocalfootnotes}{درج‌پانوشتهای‌موضعی}
+\setinterfacecommand{placelogos}{درج‌آرمها}
+\setinterfacecommand{placeongrid}{درج‌در‌توری}
+\setinterfacecommand{placeontopofeachother}{درج‌در‌بالای‌یکدیگر}
+\setinterfacecommand{placepagenumber}{درج‌شماره‌صفحه}
+\setinterfacecommand{placereferencelist}{درج‌لیست‌مرجع}
+\setinterfacecommand{placeregister}{درج‌ثبت}
+\setinterfacecommand{placerule}{درج‌خط}
+\setinterfacecommand{placesidebyside}{درج‌کنار‌به‌کنار}
+\setinterfacecommand{placesubformula}{درج‌زیرفرمول}
+\setinterfacecommand{placetextvariable}{درج‌متغیرمتن}
+\setinterfacecommand{position}{مکان}
+\setinterfacecommand{positiontext}{مکان‌متن}
+\setinterfacecommand{printpaperheight}{چاپ‌ارتفاع‌برگ}
+\setinterfacecommand{printpaperwidth}{چاپ‌عرض‌برگ}
+\setinterfacecommand{processblocks}{بلوکهای‌پردازش}
+\setinterfacecommand{processpage}{صفحه‌پردازش}
+\setinterfacecommand{product}{تولید}
+\setinterfacecommand{program}{برنامه}
+\setinterfacecommand{project}{پروژه}
+\setinterfacecommand{publication}{نشر}
+\setinterfacecommand{quotation}{نقل‌قول}
+\setinterfacecommand{quote}{نقل}
+\setinterfacecommand{ran}{ran}
+\setinterfacecommand{redo}{انجام‌دوباره}
+\setinterfacecommand{ref}{رج}
+\setinterfacecommand{reference}{مرجع}
+\setinterfacecommand{referral}{رجوع}
+\setinterfacecommand{referraldate}{تاریخ‌رجوع}
+\setinterfacecommand{referring}{مراجعه}
+\setinterfacecommand{remark}{توجه}
+\setinterfacecommand{reset}{بازنشانی}
+\setinterfacecommand{resetmarking}{بازنشانی‌نشانه‌گذاری}
+\setinterfacecommand{resetnumber}{بازنشانی‌شماره}
+\setinterfacecommand{resettext}{بازنشانی‌متن}
+\setinterfacecommand{rightaligned}{تنظیم‌راست}
+\setinterfacecommand{rightedgedistance}{فاصله‌لبه‌راست}
+\setinterfacecommand{rightedgewidth}{عرض‌لبه‌راست}
+\setinterfacecommand{rightmargindistance}{فاصله‌حاشیه‌راست}
+\setinterfacecommand{rightmarginwidth}{عرض‌حاشیه‌راست}
+\setinterfacecommand{romannumerals}{اعدادلاتین}
+\setinterfacecommand{rotate}{دوران}
+\setinterfacecommand{scale}{مقیاس}
+\setinterfacecommand{screen}{پرده}
+\setinterfacecommand{selectblocks}{انتخاب‌بلوکها}
+\setinterfacecommand{selectpaper}{انتخاب‌برگ}
+\setinterfacecommand{selectversion}{انتخاب‌نسخه}
+\setinterfacecommand{setnumber}{تعیین‌شماره}
+\setinterfacecommand{settextcontent}{تعیین‌محتوای‌متن}
+\setinterfacecommand{settextvariable}{تعیین‌متغیر‌متن}
+\setinterfacecommand{setupalign}{بارگذاری‌تنظیم}
+\setinterfacecommand{setupanswerarea}{setupanswerarea}
+\setinterfacecommand{setuparranging}{بارگذاری‌ترتیب}
+\setinterfacecommand{setupbackground}{بارگذاری‌پس‌زمینه}
+\setinterfacecommand{setupbackgrounds}{بارگذاری‌پس‌زمینه‌ها}
+\setinterfacecommand{setupblackrules}{بارگذاری‌خطهای‌سیاه}
+\setinterfacecommand{setupblank}{بارگذاری‌خالی}
+\setinterfacecommand{setupblock}{بارگذاری‌بلوک}
+\setinterfacecommand{setupbodyfont}{بارگذاری‌قلم‌متن}
+\setinterfacecommand{setupbodyfontenvironment}{بارگذاری‌محیط‌قلم‌متن}
+\setinterfacecommand{setupbottom}{بارگذاری‌پایین}
+\setinterfacecommand{setupbottomtexts}{بارگذاری‌متن‌پایین}
+\setinterfacecommand{setupbuffer}{بارگذاری‌بافر}
+\setinterfacecommand{setupbuttons}{بارگذاری‌دکمه‌ها}
+\setinterfacecommand{setupcapitals}{setupcapitals}
+\setinterfacecommand{setupcaption}{بارگذاری‌شرح}
+\setinterfacecommand{setupcaptions}{بارگذاری‌شرحها}
+\setinterfacecommand{setupclipping}{بارگذاری‌چیدن}
+\setinterfacecommand{setupcolor}{بارگذاری‌رنگ}
+\setinterfacecommand{setupcolors}{بارگذاری‌رنگها}
+\setinterfacecommand{setupcolumns}{بارگذاری‌ستونها}
+\setinterfacecommand{setupcolumnset}{بارگذاری‌مجموعه‌ستون}
+\setinterfacecommand{setupcolumnsetlines}{بارگذاری‌خطهای‌مجموعه‌ستون}
+\setinterfacecommand{setupcolumnsetstart}{بارگذاری‌شروع‌مجموعه‌ستون}
+\setinterfacecommand{setupcombinations}{بارگذاری‌ترکیب‌ها}
+\setinterfacecommand{setupcombinedlist}{بارگذاری‌لیست‌ترکیبی}
+\setinterfacecommand{setupcomment}{بارگذاری‌توضیح}
+\setinterfacecommand{setupdescriptions}{بارگذاری‌شرح}
+\setinterfacecommand{setupenumerations}{بارگذاری‌شماره‌گذاریها}
+\setinterfacecommand{setupexternalfigures}{بارگذاری‌شکلهای‌خارجی}
+\setinterfacecommand{setupfield}{بارگذاری‌میدان}
+\setinterfacecommand{setupfields}{بارگذاری‌میدانها}
+\setinterfacecommand{setupfillinlines}{بارگذاری‌پرکردن‌خطها}
+\setinterfacecommand{setupfillinrules}{بارگذاری‌درج‌درخطها}
+\setinterfacecommand{setupfloat}{بارگذاری‌شناور}
+\setinterfacecommand{setupfloats}{بارگذاری‌شناورها}
+\setinterfacecommand{setupfloatsplitting}{بارگذاری‌شکافتن‌شناورها}
+\setinterfacecommand{setupfooter}{بارگذاری‌ته‌برگ}
+\setinterfacecommand{setupfootertexts}{بارگذاری‌متن‌پانوشت}
+\setinterfacecommand{setupfootnotedefinition}{بارگذاری‌تعریف‌پانوشت}
+\setinterfacecommand{setupfootnotes}{بارگذاری‌پانوشتها}
+\setinterfacecommand{setupforms}{بارگذاری‌طرح}
+\setinterfacecommand{setupformulas}{بارگذاری‌فرمولها}
+\setinterfacecommand{setupframed}{بارگذاری‌قالبی}
+\setinterfacecommand{setupframedtexts}{بارگذاری‌متن‌قالبی}
+\setinterfacecommand{setuphead}{بارگذاری‌سر}
+\setinterfacecommand{setupheader}{بارگذاری‌سربرگ}
+\setinterfacecommand{setupheadertexts}{بارگذاری‌متن‌سربرگ}
+\setinterfacecommand{setupheadnumber}{بارگذاری‌شماره‌سر}
+\setinterfacecommand{setupheads}{بارگذاری‌سرها}
+\setinterfacecommand{setupheadtext}{بارگذاری‌متن‌سر}
+\setinterfacecommand{setuphyphenmark}{بارگذاری‌نشانه‌شکستن}
+\setinterfacecommand{setupindentations}{بارگذاری‌تورفتگیها}
+\setinterfacecommand{setupindenting}{بارگذاری‌تورفتگی}
+\setinterfacecommand{setupinmargin}{بارگذاری‌درون‌حاشیه}
+\setinterfacecommand{setupinteraction}{بارگذاری‌پانل}
+\setinterfacecommand{setupinteractionbar}{بارگذاری‌میله‌پانل}
+\setinterfacecommand{setupinteractionmenu}{بارگذاری‌منوی‌پانل}
+\setinterfacecommand{setupinteractionscreen}{بارگذاری‌پرده‌پانل}
+\setinterfacecommand{setupinterlinespace}{بارگذاری‌فاصله‌بین‌خط}
+\setinterfacecommand{setupitemgroup}{بارگذاری‌گروه‌آیتم}
+\setinterfacecommand{setupitemgroups}{بارگذاری‌گروههای‌آیتم}
+\setinterfacecommand{setupitems}{بارگذاری‌آیتمها}
+\setinterfacecommand{setuplabeltext}{باگذاری‌متن‌برچسب}
+\setinterfacecommand{setuplanguage}{بارگذاری‌زبان}
+\setinterfacecommand{setuplayout}{بارگذاری‌طرح‌بندی}
+\setinterfacecommand{setuplegend}{بارگذاری‌راهنما}
+\setinterfacecommand{setuplinenumbering}{بارگذاری‌شماره‌‌گذاری‌خط}
+\setinterfacecommand{setuplines}{بارگذاری‌خطها}
+\setinterfacecommand{setuplinewidth}{بارگذاری‌عرض‌خط}
+\setinterfacecommand{setuplist}{بارگذاری‌لیست}
+\setinterfacecommand{setupmakeup}{بارگذاری‌آرایش}
+\setinterfacecommand{setupmarginblocks}{بارگذاری‌بلوکهای‌حاشیه}
+\setinterfacecommand{setupmarginrules}{بارگذاری‌خطهای‌حاشیه}
+\setinterfacecommand{setupmarking}{بارگذاری‌نشانه‌گذاری}
+\setinterfacecommand{setupmathalignment}{بارگذاری‌تنظیم‌ریاضی}
+\setinterfacecommand{setupnarrower}{بارگذاری‌باریکتر}
+\setinterfacecommand{setupnumber}{بارگذاری‌شماره}
+\setinterfacecommand{setupnumbering}{بارگذاری‌شماره‌گذاری}
+\setinterfacecommand{setupoppositeplacing}{بارگذاری‌درج‌مخالف}
+\setinterfacecommand{setupoutput}{بارگذاری‌خروجی}
+\setinterfacecommand{setuppagecomment}{بارگذاری‌توضیح‌صفحه}
+\setinterfacecommand{setuppagenumber}{بارگذاری‌شماره‌صفحه}
+\setinterfacecommand{setuppagenumbering}{بارگذاری‌شماره‌گذاری‌صفحه}
+\setinterfacecommand{setuppagetransitions}{بارگذاری‌گذارصفحه}
+\setinterfacecommand{setuppalet}{بارگذاری‌لوح}
+\setinterfacecommand{setuppaper}{بارگذاری‌برگ}
+\setinterfacecommand{setuppapersize}{بارگذاری‌اندازه‌برگ}
+\setinterfacecommand{setupparagraphnumbering}{بارگذاری‌شماره‌گذاری‌پاراگراف}
+\setinterfacecommand{setupparagraphs}{بارگذاری‌پاراگرافها}
+\setinterfacecommand{setupplacement}{بارگذاری‌جانشانی}
+\setinterfacecommand{setuppositioning}{بارگذاری‌مکان‌گذاری}
+\setinterfacecommand{setupprofiles}{بارگذاری‌پروفایلها}
+\setinterfacecommand{setupprograms}{بارگذاری‌برنامه‌ها}
+\setinterfacecommand{setuppublications}{بارگذاری‌نشرها}
+\setinterfacecommand{setupquote}{بارگذاری‌نقل}
+\setinterfacecommand{setupreferencelist}{بارگذاری‌لیست‌مرجع}
+\setinterfacecommand{setupreferencing}{بارگذاری‌ارجاع}
+\setinterfacecommand{setupregister}{بارگذاری‌ثبت}
+\setinterfacecommand{setuprotate}{بارگذاری‌دوران}
+\setinterfacecommand{setuprule}{بارگذاری‌خط}
+\setinterfacecommand{setups}{بارگذاریها}
+\setinterfacecommand{setupscreens}{بارگذاری‌پرده‌ها}
+\setinterfacecommand{setupsection}{بارگذاری‌بخش}
+\setinterfacecommand{setupsectionblock}{بارگذاری‌بلوک‌بخش}
+\setinterfacecommand{setupsorting}{بارگذاری‌ترتیب}
+\setinterfacecommand{setupspacing}{بارگذاری‌فضا‌گذاری}
+\setinterfacecommand{setupstartstop}{بارگذاری‌شروع‌پایان}
+\setinterfacecommand{setupstrut}{بارگذاری‌بست}
+\setinterfacecommand{setupsubpagenumber}{بارگذاری‌شماره‌زیرصفحه}
+\setinterfacecommand{setupsymbolset}{بارگذاری‌مجموعه‌نماد}
+\setinterfacecommand{setupsynchronization}{بارگذاری‌تطابق}
+\setinterfacecommand{setupsynchronizationbar}{بارگذاری‌میله‌تطابق}
+\setinterfacecommand{setupsynonyms}{بارگذاری‌مترادفها}
+\setinterfacecommand{setupsystem}{بارگذاری‌سیستم}
+\setinterfacecommand{setuptab}{بارگذاری‌تب}
+\setinterfacecommand{setuptables}{بارگذاری‌جدولها}
+\setinterfacecommand{setuptabulate}{بارگذاری‌جدول‌بندی}
+\setinterfacecommand{setuptext}{بارگذاری‌متن}
+\setinterfacecommand{setuptextposition}{بارگذاری‌مکان‌متن}
+\setinterfacecommand{setuptextrules}{بارگذاری‌خطهای‌متن}
+\setinterfacecommand{setuptexttexts}{بارگذاری‌متن‌متنها}
+\setinterfacecommand{setuptextvariable}{بارگذاری‌متغیر‌متن}
+\setinterfacecommand{setupthinrules}{بارگذاری‌خطها‌ی‌نازک}
+\setinterfacecommand{setuptolerance}{بارگذاری‌بردباری}
+\setinterfacecommand{setuptop}{بارگذاری‌بالا}
+\setinterfacecommand{setuptoptexts}{بارگذاری‌متنهای‌بالا}
+\setinterfacecommand{setuptype}{بارگذاری‌تایپ}
+\setinterfacecommand{setuptyping}{بارگذاری‌تایپ‌کردن}
+\setinterfacecommand{setupunderbar}{بارگذاری‌میله‌زیر}
+\setinterfacecommand{setupurl}{setupurl}
+\setinterfacecommand{setupversions}{بارگذاری‌نسخه‌ها}
+\setinterfacecommand{setupwhitespace}{بارگذاری‌فضای‌سفید}
+\setinterfacecommand{showbodyfont}{نمایش‌قلم‌بدنه}
+\setinterfacecommand{showbodyfontenvironment}{نمایش‌محیط‌قلم‌بدنه}
+\setinterfacecommand{showcolor}{نمایش‌رنگ}
+\setinterfacecommand{showcolorgroup}{نمایش‌گروه‌رنگ}
+\setinterfacecommand{showexternalfigures}{نمایش‌شکلهای‌خارجی}
+\setinterfacecommand{showfields}{نمایش‌میدانها}
+\setinterfacecommand{showframe}{نمایش‌قالب}
+\setinterfacecommand{showgrid}{نمایش‌توری}
+\setinterfacecommand{showlayout}{نمایش‌طرح‌بندی}
+\setinterfacecommand{showmakeup}{نمایش‌آرایش}
+\setinterfacecommand{showpalet}{نمایش‌لوح}
+\setinterfacecommand{showprint}{نمایش‌چاپ}
+\setinterfacecommand{showsetups}{نمایش‌بارگذاریها}
+\setinterfacecommand{showstruts}{نمایش‌بستها}
+\setinterfacecommand{showsymbolset}{نمایش‌مجموعه‌علامت}
+\setinterfacecommand{smallcapped}{cap}
+\setinterfacecommand{someline}{یک‌خط}
+\setinterfacecommand{somewhere}{یک‌جا}
+\setinterfacecommand{space}{فضا}
+\setinterfacecommand{splitfloat}{شکافتن‌شناور}
+\setinterfacecommand{startalignment}{شروع‌تنظیم}
+\setinterfacecommand{startbackground}{شروع‌پس‌زمینه}
+\setinterfacecommand{startcoding}{شروع‌کد}
+\setinterfacecommand{startcolor}{شروع‌رنگ}
+\setinterfacecommand{startcolumnmakeup}{شروع‌آرایش‌ستون}
+\setinterfacecommand{startcolumns}{شروع‌ستونها}
+\setinterfacecommand{startcolumnset}{شروع‌مجموعه‌ستون}
+\setinterfacecommand{startcombination}{شروع‌ترکیب}
+\setinterfacecommand{startcomponent}{شروع‌مولفه}
+\setinterfacecommand{startdocument}{شروع‌نوشتار}
+\setinterfacecommand{startenvironment}{شروع‌محیط}
+\setinterfacecommand{startfigure}{شروع‌شکل}
+\setinterfacecommand{startglobal}{شروع‌سراسری}
+\setinterfacecommand{startline}{شروع‌خط}
+\setinterfacecommand{startlinecorrection}{شروع‌تصحیح‌خط}
+\setinterfacecommand{startlinenumbering}{شروع‌شماره‌گذاری‌خط}
+\setinterfacecommand{startlines}{شروع‌خطها}
+\setinterfacecommand{startlocal}{شروع‌موضعی}
+\setinterfacecommand{startlocalfootnotes}{شروع‌پانوشتهای‌موضعی}
+\setinterfacecommand{startmakeup}{شروع‌آرایش}
+\setinterfacecommand{startmarginblock}{شروع‌بلوک‌حاشیه}
+\setinterfacecommand{startmarginrule}{شروع‌خط‌حاشیه}
+\setinterfacecommand{startnarrower}{شروع‌باریکتر}
+\setinterfacecommand{startopposite}{شروع‌مخالف}
+\setinterfacecommand{startoverlay}{شروع‌پوشش}
+\setinterfacecommand{startoverzicht}{شروع‌بازبینی}
+\setinterfacecommand{startpacked}{شروع‌فشرده}
+\setinterfacecommand{startpositioning}{شروع‌مکان‌گذاری}
+\setinterfacecommand{startproduct}{شروع‌تولید}
+\setinterfacecommand{startprofile}{شروع‌پروفایل}
+\setinterfacecommand{startproject}{شروع‌پروژه}
+\setinterfacecommand{startquotation}{شروع‌نقل‌قول}
+\setinterfacecommand{startraster}{startraster}
+\setinterfacecommand{startsymbolset}{شروع‌مجموعه‌نماد}
+\setinterfacecommand{startsynchronization}{شروع‌تطابق}
+\setinterfacecommand{starttable}{شروع‌جدول}
+\setinterfacecommand{starttables}{شروع‌جدولها}
+\setinterfacecommand{starttext}{شروع‌متن}
+\setinterfacecommand{starttextrule}{شروع‌خط‌متن}
+\setinterfacecommand{startunpacked}{شروع‌غیر‌فشرده}
+\setinterfacecommand{startversion}{شروع‌نسخه}
+\setinterfacecommand{stopalignment}{پایان‌تنظیم}
+\setinterfacecommand{stopbackground}{پایان‌پس‌زمینه}
+\setinterfacecommand{stopcoding}{پایان‌کد}
+\setinterfacecommand{stopcolor}{پایان‌رنگ}
+\setinterfacecommand{stopcolumnmakeup}{پایان‌آرایش‌ستون}
+\setinterfacecommand{stopcolumns}{پایان‌ستونها}
+\setinterfacecommand{stopcolumnset}{پایان‌مجموعه‌ستون}
+\setinterfacecommand{stopcombination}{پایان‌ترکیب}
+\setinterfacecommand{stopcomponent}{پایان‌مولفه}
+\setinterfacecommand{stopdocument}{پایان‌نوشتار}
+\setinterfacecommand{stopenvironment}{پایان‌محیط}
+\setinterfacecommand{stopglobal}{پایان‌سراسری}
+\setinterfacecommand{stopline}{پایان‌خط}
+\setinterfacecommand{stoplinecorrection}{پایان‌تصحیح‌خط}
+\setinterfacecommand{stoplinenumbering}{پایان‌شماره‌گذاری‌خط}
+\setinterfacecommand{stoplines}{پایان‌خطها}
+\setinterfacecommand{stoplocal}{پایان‌موضعی}
+\setinterfacecommand{stoplocalfootnotes}{پایان‌پانوشتهای‌موضعی}
+\setinterfacecommand{stopmakeup}{پایان‌آرایش}
+\setinterfacecommand{stopmarginblock}{پایان‌بلوک‌حاشیه}
+\setinterfacecommand{stopmarginrule}{پایان‌خط‌حاشیه}
+\setinterfacecommand{stopnarrower}{پایان‌نازکتر}
+\setinterfacecommand{stopopposite}{پایان‌مخالف}
+\setinterfacecommand{stopoverlay}{پایان‌پوشش}
+\setinterfacecommand{stopoverzicht}{پایان‌بازبینی}
+\setinterfacecommand{stoppacked}{پایان‌فشرده}
+\setinterfacecommand{stoppositioning}{پایان‌مکان‌گذاری}
+\setinterfacecommand{stopproduct}{پایان‌تولید}
+\setinterfacecommand{stopprofile}{پایان‌پروفایل}
+\setinterfacecommand{stopproject}{پایان‌پروژه}
+\setinterfacecommand{stopquotation}{پایان‌نقل‌قول}
+\setinterfacecommand{stopraster}{stopraster}
+\setinterfacecommand{stopsynchronization}{پایان‌تطابق}
+\setinterfacecommand{stoptable}{پایان‌جدول}
+\setinterfacecommand{stoptables}{پایان‌جدولها}
+\setinterfacecommand{stoptext}{پایان‌متن}
+\setinterfacecommand{stoptextrule}{پایان‌خط‌متن}
+\setinterfacecommand{stopunpacked}{پایان‌غیرفشرده}
+\setinterfacecommand{stopversion}{پایان‌نسخه}
+\setinterfacecommand{stretched}{کشیده}
+\setinterfacecommand{subformulanumber}{شماره‌زیرفرمول}
+\setinterfacecommand{subpagenumber}{شماره‌زیرصفحه}
+\setinterfacecommand{switchtobodyfont}{تغییربه‌قلم‌بدنه}
+\setinterfacecommand{switchtorawfont}{تغییربه‌قلم‌خام}
+\setinterfacecommand{sym}{نم}
+\setinterfacecommand{symbol}{نماد}
+\setinterfacecommand{synchronizationbar}{میله‌تطابق}
+\setinterfacecommand{synchronize}{تطابق}
+\setinterfacecommand{tab}{تب}
+\setinterfacecommand{testcolumn}{ستون‌امتحان}
+\setinterfacecommand{testpage}{صفحه‌تست}
+\setinterfacecommand{tex}{تک}
+\setinterfacecommand{textheight}{ارتفاع‌متن}
+\setinterfacecommand{textreference}{مرجع‌متن}
+\setinterfacecommand{textrule}{خط‌متن}
+\setinterfacecommand{textvariable}{متغیر متن}
+\setinterfacecommand{textwidth}{عرض‌متن}
+\setinterfacecommand{thinrule}{خط‌نازک}
+\setinterfacecommand{thinrules}{خطهای‌نازک}
+\setinterfacecommand{tooltip}{tooltip}
+\setinterfacecommand{topdistance}{فاصله‌بالا}
+\setinterfacecommand{topheight}{ارتفاع‌بالا}
+\setinterfacecommand{topspace}{فضای‌بالا}
+\setinterfacecommand{totalnumberofpages}{شماره‌کل‌صفحه‌ها}
+\setinterfacecommand{translate}{ترجمه}
+\setinterfacecommand{txt}{txt}
+\setinterfacecommand{typ}{typ}
+\setinterfacecommand{type}{تایپ}
+\setinterfacecommand{typebuffer}{تایپ‌بافر}
+\setinterfacecommand{typefile}{تایپ‌پرونده}
+\setinterfacecommand{unitmeaning}{معنی‌واحد}
+\setinterfacecommand{unknown}{ناشناس}
+\setinterfacecommand{useJSscripts}{useJSscripts}
+\setinterfacecommand{useURL}{useURL}
+\setinterfacecommand{useXMLfilter}{useXMLfilter}
+\setinterfacecommand{useblocks}{استفاده‌بلوکها}
+\setinterfacecommand{usecommands}{استفاده‌فرمانها}
+\setinterfacecommand{useencoding}{استفاده‌رمزینه}
+\setinterfacecommand{useexternaldocument}{استفاده‌نوشتارخارجی}
+\setinterfacecommand{useexternalfigure}{استفاده‌شکل‌خارجی}
+\setinterfacecommand{useexternalfile}{استفاده‌پرونده‌خارجی}
+\setinterfacecommand{useexternalfiles}{استفاده‌پرونده‌های‌خارجی}
+\setinterfacecommand{useexternalsoundtrack}{استفاده‌قطعه‌موزیک‌خارجی}
+\setinterfacecommand{usemodule}{استفاده‌مدول}
+\setinterfacecommand{usemodules}{استفاده‌مدولها}
+\setinterfacecommand{usepath}{استفاده‌مسیر}
+\setinterfacecommand{usereferences}{استفاده‌مرجعها}
+\setinterfacecommand{usespecials}{استفاده‌ویژگیها}
+\setinterfacecommand{usesymbols}{استفاده‌نمادها}
+\setinterfacecommand{usetypescript}{استفاده‌دستخط‌تایپ}
+\setinterfacecommand{usetypescriptfile}{استفاده‌پرونده‌دستخط‌تایپ}
+\setinterfacecommand{useurl}{useurl}
+\setinterfacecommand{version}{نسخه}
+\setinterfacecommand{vl}{خ‌ع}
+\setinterfacecommand{weekday}{روزهفته}
+\setinterfacecommand{whitespace}{فضای‌سفید}
+\setinterfacecommand{wordright}{کلمه‌راست}
+\setinterfacecommand{writebetweenlist}{بنویس‌بین‌لیست}
+\setinterfacecommand{writetolist}{بنویس‌در‌لیست}
+\setinterfacecommand{writetoreferencelist}{بنویس‌درلیست‌مرجع}
+\setinterfacecommand{writetoregister}{بنویس‌درثبت}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.mkii
index 760c83033..23b93d495 100644
--- a/tex/context/base/mult-sys.tex
+++ b/tex/context/base/mult-sys.mkii
@@ -474,6 +474,7 @@
\definesystemvariable {cb} % CollectBox
\definesystemvariable {cc} % Comment
\definesystemvariable {ce} % CasEs
+\definesystemvariable {cf} % Style (ColorFont)
\definesystemvariable {ch} % CHaracterspacing
\definesystemvariable {ci} % CItaat
\definesystemvariable {ck} % Character Kerning
@@ -770,7 +771,7 @@
\definefileconstant {sysfilename} {cont-sys}
\definefileconstant {oldfilename} {cont-old}
\definefileconstant {newfilename} {cont-new}
-\definefileconstant {filfilename} {cont-fil}
+\definefileconstant {filfilename} {cont-fil.\mksuffix}
\definefileconstant {modfilename} {cont-mod}
%D Handy for typescripts (we could use s! instead:
@@ -875,6 +876,7 @@
\defineinterfaceconstant {svg} {svg}
\defineinterfaceconstant {tex} {tex}
\defineinterfaceconstant {tmp} {tmp}
+\defineinterfaceconstant {cld} {cld}
%D A careful reader will have noticed that in the module
%D \type{mult-ini} we defined \type{\selectinterface}. We were
diff --git a/tex/context/base/mult-sys.mkiv b/tex/context/base/mult-sys.mkiv
new file mode 100644
index 000000000..5b3503d98
--- /dev/null
+++ b/tex/context/base/mult-sys.mkiv
@@ -0,0 +1,901 @@
+%D \module
+%D [ file=mult-sys,
+%D version=1996.06.01,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=System,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D In boring module we define a lot of obscure but useful
+%D system constants. By doing so we save lots of memory while
+%D at the same time we prevent ourself from typing errors.
+
+\writestatus{loading}{ConTeXt Multilingual Macros / System}
+
+\unprotect
+
+%D This file is mostly the same as the \MKII\ variant but we
+%D keep extending \MKIV, so it was bout time to have a dedicated
+%D variant.
+%D
+%D The constants are grouped in such a way that there is a
+%D minimal change of conflicts.
+%D
+%D \starttyping
+%D \definesystemconstants {word}
+%D \definemessageconstant {word}
+%D \stoptyping
+%D
+%D This commands generate \type{\s!word} and \type{\m!word}.
+
+\definesystemconstant {hans}
+\definesystemconstant {taco}
+
+%D First we define some system constants used for both the
+%D multi||lingual interface and multi||linguag typesetting.
+
+\definesystemconstant {afrikaans} \definesystemconstant {af}
+\definesystemconstant {arabic} \definesystemconstant {ar}
+\definesystemconstant {catalan} \definesystemconstant {ca}
+\definesystemconstant {chinese} \definesystemconstant {cn}
+\definesystemconstant {croatian} \definesystemconstant {hr}
+\definesystemconstant {czech} \definesystemconstant {cs} \definesystemconstant {cz}
+\definesystemconstant {danish} \definesystemconstant {da}
+\definesystemconstant {dutch} \definesystemconstant {nl}
+\definesystemconstant {english} \definesystemconstant {en}
+\definesystemconstant {finish} \definesystemconstant {fi}
+\definesystemconstant {french} \definesystemconstant {fr}
+\definesystemconstant {german} \definesystemconstant {de}
+\definesystemconstant {hungarian} \definesystemconstant {hu}
+\definesystemconstant {italian} \definesystemconstant {it}
+\definesystemconstant {latin} \definesystemconstant {la}
+\definesystemconstant {lithuanian} \definesystemconstant {lt}
+\definesystemconstant {bokmal} \definesystemconstant {nb} \definesystemconstant {norwegian} \definesystemconstant {no}
+\definesystemconstant {nynorsk} \definesystemconstant {nn}
+\definesystemconstant {polish} \definesystemconstant {pl}
+\definesystemconstant {persian} \definesystemconstant {pe}
+\definesystemconstant {portuguese} \definesystemconstant {pt}
+\definesystemconstant {romanian} \definesystemconstant {ro}
+\definesystemconstant {russian} \definesystemconstant {ru}
+\definesystemconstant {slovak} \definesystemconstant {sk}
+\definesystemconstant {slovenian} \definesystemconstant {sl}
+\definesystemconstant {slovene}
+\definesystemconstant {spanish} \definesystemconstant {es}
+\definesystemconstant {swedish} \definesystemconstant {sv}
+\definesystemconstant {turkish} \definesystemconstant {tr}
+\definesystemconstant {turkmen} \definesystemconstant {tk}
+\definesystemconstant {gbenglish} \definesystemconstant {gb} \definesystemconstant {ukenglish} \definesystemconstant {uk}
+\definesystemconstant {usenglish} \definesystemconstant {us}
+\definesystemconstant {ukrainian} \definesystemconstant {ua}
+\definesystemconstant {greek} \definesystemconstant {gr}
+\definesystemconstant {ancientgreek} \definesystemconstant {agr}
+\definesystemconstant {vietnamese} \definesystemconstant {vi} \definesystemconstant {vn}
+
+%D For proper \UNICODE\ support we need a few font related
+%D constants.
+
+\definesystemconstant {BoldItalic}
+\definesystemconstant {BoldSlanted}
+\definesystemconstant {Bold}
+\definesystemconstant {Italic}
+\definesystemconstant {Regular}
+\definesystemconstant {Slanted}
+\definesystemconstant {Unicode}
+
+\definesystemconstant {Serif} \definesystemconstant {Regular}
+\definesystemconstant {Sans} \definesystemconstant {Support}
+\definesystemconstant {Mono} \definesystemconstant {Type}
+\definesystemconstant {Math}
+\definesystemconstant {Handwriting}
+\definesystemconstant {Calligraphy}
+\definesystemconstant {Casual}
+
+\definesystemconstant {SerifBold} \definesystemconstant {SansBold} \definesystemconstant {MonoBold}
+\definesystemconstant {SerifItalic} \definesystemconstant {SansItalic} \definesystemconstant {MonoItalic}
+\definesystemconstant {SerifBoldItalic} \definesystemconstant {SansBoldItalic} \definesystemconstant {MonoBoldItalic}
+\definesystemconstant {SerifSlanted} \definesystemconstant {SansSlanted} \definesystemconstant {MonoSlanted}
+\definesystemconstant {SerifBoldSlanted} \definesystemconstant {SansBoldSlanted} \definesystemconstant {MonoBoldSlanted}
+\definesystemconstant {SerifCaps} \definesystemconstant {SansCaps} \definesystemconstant {MonoCaps}
+
+\definesystemconstant {Normal}
+\definesystemconstant {Caps}
+
+\definesystemconstant {mnem} % kind of generic short tag
+
+\definesystemconstant {file}
+\definesystemconstant {name}
+\definesystemconstant {spec}
+
+\definesystemconstant {serif}
+\definesystemconstant {sans}
+\definesystemconstant {mono}
+\definesystemconstant {math}
+\definesystemconstant {handwriting}
+\definesystemconstant {calligraphy}
+\definesystemconstant {casual}
+\definesystemconstant {fax}
+
+\definesystemconstant {fallback}
+
+\definesystemconstant {none}
+\definesystemconstant {default}
+\definesystemconstant {smallcaps}
+
+%D As the name of their define command states, the next set of
+%D constants is used in the message macro's.
+
+\definemessageconstant {check}
+\definemessageconstant {colors}
+\definemessageconstant {columns}
+\definemessageconstant {encodings}
+\definemessageconstant {regimes}
+\definemessageconstant {figures}
+\definemessageconstant {fields}
+\definemessageconstant {files}
+\definemessageconstant {floatblocks}
+\definemessageconstant {fonts}
+\definemessageconstant {handlings}
+\definemessageconstant {interactions}
+\definemessageconstant {javascript}
+\definemessageconstant {layouts}
+\definemessageconstant {linguals}
+\definemessageconstant {references}
+\definemessageconstant {specials}
+\definemessageconstant {structures}
+\definemessageconstant {symbols}
+\definemessageconstant {systems}
+\definemessageconstant {lua}
+\definemessageconstant {textblocks}
+\definemessageconstant {verbatims}
+\definemessageconstant {versions}
+\definemessageconstant {metapost}
+\definemessageconstant {chemicals}
+\definemessageconstant {publications}
+
+%D Net come some \CONTEXT\ constants, used in the definition
+%D of private commands:
+
+\definesystemconstant {tex}
+\definesystemconstant {xml}
+\definesystemconstant {lua}
+
+\definesystemconstant {next}
+\definesystemconstant {pickup}
+\definesystemconstant {ascii}
+\definesystemconstant {default}
+\definesystemconstant {unknown}
+\definesystemconstant {action}
+\definesystemconstant {compare}
+\definesystemconstant {do}
+\definesystemconstant {dodo}
+\definesystemconstant {complex}
+\definesystemconstant {simple}
+\definesystemconstant {start}
+\definesystemconstant {stop}
+\definesystemconstant {dummy}
+\definesystemconstant {local}
+\definesystemconstant {global}
+\definesystemconstant {done}
+\definesystemconstant {font}
+\definesystemconstant {link}
+\definesystemconstant {parent}
+\definesystemconstant {clone}
+\definesystemconstant {section} \let\v!sectionlevel\s!section % for old times sake
+\definesystemconstant {handler}
+\definesystemconstant {counter}
+\definesystemconstant {single}
+\definesystemconstant {multi}
+
+\definesystemconstant {hasnumber}
+\definesystemconstant {hastitle}
+\definesystemconstant {hascaption}
+\definesystemconstant {haslevel}
+
+\definesystemconstant {mkiv}
+\definesystemconstant {mkii}
+\definesystemconstant {entities}
+
+\definesystemconstant {normal}
+\definesystemconstant {bold}
+\definesystemconstant {italic}
+\definesystemconstant {slanted}
+
+\definesystemconstant {default}
+\definesystemconstant {smallcaps}
+
+\definesystemconstant {text}
+\definesystemconstant {page}
+\definesystemconstant {leftpage}
+\definesystemconstant {rightpage}
+\definesystemconstant {somewhere}
+
+%D A more experienced \TEX\ user will recognize the next four
+%D constants. We need these because font-definitions are
+%D partially english.
+
+\definesystemconstant {run}
+
+\definesystemconstant {fam}
+\definesystemconstant {text}
+\definesystemconstant {script}
+\definesystemconstant {scriptscript}
+
+\definesystemconstant {lefthyphenmin}
+\definesystemconstant {righthyphenmin}
+\definesystemconstant {lefthyphenchar}
+\definesystemconstant {righthyphenchar}
+
+\definesystemconstant {skewchar}
+\definesystemconstant {hyphenchar}
+\definesystemconstant {catcodes}
+\definesystemconstant {encoding}
+\definesystemconstant {resource}
+\definesystemconstant {mapping}
+\definesystemconstant {language}
+\definesystemconstant {patterns}
+\definesystemconstant {rname}
+\definesystemconstant {rscale}
+\definesystemconstant {handling}
+\definesystemconstant {features}
+\definesystemconstant {fallbacks}
+\definesystemconstant {goodies}
+\definesystemconstant {background}
+\definesystemconstant {ucmap}
+
+\definesystemconstant {property}
+\definesystemconstant {overprint}
+\definesystemconstant {layer}
+\definesystemconstant {effect}
+\definesystemconstant {negative}
+\definesystemconstant {color}
+\definesystemconstant {transparency}
+
+\definesystemconstant {black}
+\definesystemconstant {white}
+
+\definesystemconstant {format}
+\definesystemconstant {extensions}
+\definesystemconstant {initializations}
+
+%D Just to be complete we define the standard \TEX\ units.
+
+\definesystemconstant {cm}
+\definesystemconstant {em}
+\definesystemconstant {ex}
+\definesystemconstant {mm}
+\definesystemconstant {pt}
+\definesystemconstant {sp}
+\definesystemconstant {bp}
+\definesystemconstant {in}
+\definesystemconstant {pc}
+\definesystemconstant {cm}
+\definesystemconstant {dd}
+\definesystemconstant {cc}
+\definesystemconstant {nd}
+\definesystemconstant {nc}
+
+%D These constants are used for internal and utility
+%D commands.
+
+\definesystemconstant {check}
+\definesystemconstant {reset}
+\definesystemconstant {set}
+
+\definesystemconstant {entrya}
+\definesystemconstant {entryb}
+\definesystemconstant {entryc}
+\definesystemconstant {entryd}
+\definesystemconstant {entry}
+\definesystemconstant {see}
+\definesystemconstant {from}
+\definesystemconstant {to}
+\definesystemconstant {line}
+\definesystemconstant {page}
+\definesystemconstant {realpage}
+\definesystemconstant {userpage}
+\definesystemconstant {subpage}
+
+\definesystemconstant {synonym}
+
+\definesystemconstant {reference}
+\definesystemconstant {main}
+
+\definesystemconstant {list}
+
+\definesystemconstant {item}
+\definesystemconstant {itemcount}
+
+\definesystemconstant {number}
+\definesystemconstant {references}
+\definesystemconstant {between}
+\definesystemconstant {format}
+\definesystemconstant {old}
+
+\definesystemconstant {thisisblock}
+\definesystemconstant {thiswasblock}
+
+\definesystemconstant {figurepreset}
+
+\definesystemconstant {empty}
+
+%D Some \CONTEXT\ commands take a two||pass aproach to
+%D optimize the typesetting. Each two||pass object has its
+%D own tag.
+
+\definesystemconstant {pass}
+
+\definesystemconstant {data}
+\definesystemconstant {float}
+\definesystemconstant {list}
+\definesystemconstant {page}
+\definesystemconstant {subpage}
+\definesystemconstant {margin}
+\definesystemconstant {profile}
+\definesystemconstant {versionbegin}
+\definesystemconstant {versionend}
+\definesystemconstant {cross}
+\definesystemconstant {paragraph}
+
+%D A lot of macros use tags to distinguish between different
+%D objects, e.g. lists and registers.
+
+\definesystemconstant {prt} % part (deel)
+\definesystemconstant {chp} % chapter (hoofdstuk)
+\definesystemconstant {sec} % section (paragraaf)
+\definesystemconstant {tit} % title (titel)
+\definesystemconstant {sub} % subject (onderwerp)
+\definesystemconstant {mar} % margin (marge)
+\definesystemconstant {num} % number (doornummeren)
+\definesystemconstant {def} % definition (doordefinieren)
+\definesystemconstant {for} % formula (formule)
+\definesystemconstant {fnt} % footnote (voetnoot)
+\definesystemconstant {ind} % index (register)
+\definesystemconstant {lin} % linked index
+\definesystemconstant {lst} % list (opsomming)
+\definesystemconstant {flt} % float (plaatsblok)
+\definesystemconstant {pag} % page (pagina)
+\definesystemconstant {txt} % text (tekst)
+\definesystemconstant {ref} % reference (verwijzing)
+\definesystemconstant {lab} % label (label)
+\definesystemconstant {aut} % automatic (inhoud, index)
+\definesystemconstant {vwa} % automatic (illustrations)
+\definesystemconstant {vwb} % automatic (illustrations)
+
+\definesystemconstant {kop} % kop % still dutch
+
+%D Reference labels can be tagged by users, for instance by
+%D means of \type{tag:}. The reference mechanism itself uses
+%D some tags too. These are definitely not to be used by users.
+%D Here they are:
+
+\definereferenceconstant {cross} {:c:} % cross reference
+\definereferenceconstant {view} {:v:} % view reference
+\definereferenceconstant {viewa} {:a:} % view reference test a
+\definereferenceconstant {viewb} {:b:} % view reference test b
+\definereferenceconstant {page} {:p:} % page referece
+\definereferenceconstant {list} {:l:} % list reference
+\definereferenceconstant {exec} {:e:} % execution reference
+\definereferenceconstant {form} {:m:} % form reference
+\definereferenceconstant {syst} {:s:} % system reference
+
+\definereferenceconstant {from} {:f:} % from list reference
+\definereferenceconstant {to} {:t:} % to list reference
+
+\definereferenceconstant {object} {:o:} % object reference
+\definereferenceconstant {driver} {:d:} % driver object reference
+\definereferenceconstant {widget} {:w:} % field chain reference
+
+\definereferenceconstant {java} {:j:} % java scripts
+
+%D When we use numbers and dimensions the same applies as
+%D with the keywords like \type{width} and \type{plus}
+%D mentioned earlier.
+
+\def\!!ten {10}
+\def\!!twelve {12}
+\def\!!hundred {100}
+\def\!!thousand {1000}
+\def\!!tenthousand {10000}
+\def\!!maxcard {65536}
+\def\!!medcard {32768}
+
+\def\!!zeropoint {0pt}
+\def\!!onepoint {1pt}
+\def\!!twopoint {2pt}
+\def\!!threepoint {3pt}
+\def\!!fourpoint {4pt}
+\def\!!fivepoint {5pt}
+\def\!!sixpoint {6pt}
+\def\!!sevenpoint {7pt}
+\def\!!eightpoint {8pt}
+\def\!!ninepoint {9pt}
+\def\!!tenpoint {10pt}
+\def\!!elevenpoint {11pt}
+\def\!!twelvepoint {12pt}
+\def\!!fourteenpointfour {14.4pt}
+
+\let\onerealpoint\onepoint % needed for latex
+
+% D Another optimization is:
+%
+% \let\points\onepoint
+
+%D A rough test is:
+%D
+%D \starttyping
+%D \def\TestMe % 7.75 sec on a P4/2G
+%D {\dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points
+%D \dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points}
+%D
+%D \def\TestMe % 11.5 sec on a P4/2G
+%D {\dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt%
+%D \dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt}
+%D
+%D \def\TestMe % 12.5 sec on a P4/2G
+%D {\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt%
+%D \dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt}
+%D
+%D \testfeatureonce {500000}{\TestMe}
+%D \stoptyping
+
+%D Variables are composed of a command specific tag and a user
+%D supplied variable (system constant). The first tag \type{ag}
+%D for instance is available as \type{\??ag} and expands to
+%D \type{@@ag} in composed variables.
+
+% vervallen : hd hr hm vt vr vm tr tn te br bm bo on om or
+
+\definesystemvariable {ab} % AlignedBoxes
+\definesystemvariable {ac} % ACcent
+\definesystemvariable {ae} % AttributEs
+\definesystemvariable {ag} % AchterGrond
+\definesystemvariable {al} % ALinea's
+\definesystemvariable {am} % interActieMenu
+\definesystemvariable {an} % ANchor
+\definesystemvariable {as} % AlignmentSwitch
+\definesystemvariable {at} % ATtachments
+\definesystemvariable {ba} % synchronisatieBAlk
+\definesystemvariable {bc} % BaCkend
+\definesystemvariable {be} % startstop (BeginEnd)
+\definesystemvariable {bj} % BlokJe
+\definesystemvariable {bk} % Blokken (floats)
+\definesystemvariable {bl} % BLanko
+\definesystemvariable {bg} % BleedinG
+\definesystemvariable {bm} % BookMark
+\definesystemvariable {bo} % BlankO (definitions)
+\definesystemvariable {bp} % BreakPoint
+\definesystemvariable {br} % sideBaR
+\definesystemvariable {bs} % SelecteerBlokken
+\definesystemvariable {bt} % BuTton
+\definesystemvariable {bu} % BUffer
+\definesystemvariable {bv} % Brieven
+\definesystemvariable {by} % Per
+\definesystemvariable {cb} % CollectBox
+\definesystemvariable {cc} % Comment
+\definesystemvariable {ce} % CasEs
+\definesystemvariable {cf} % Style (ColorFont)
+\definesystemvariable {ch} % CHaracterspacing
+\definesystemvariable {ci} % CItaat
+\definesystemvariable {ck} % Character Kerning
+\definesystemvariable {cl} % kleur (CoLor setup)
+\definesystemvariable {cn} % CollumN
+\definesystemvariable {cm} % CheMical
+\definesystemvariable {co} % COmbinaties
+\definesystemvariable {cp} % CliP
+\definesystemvariable {cr} % kleur (ColoR)
+\definesystemvariable {cs} % kleur (ColorSeparation
+\definesystemvariable {cv} % ConVersie
+\definesystemvariable {cy} % CrYteria
+\definesystemvariable {da} % DAte
+\definesystemvariable {db} % Labels
+\definesystemvariable {dc} % DroppedCaps
+\definesystemvariable {dd} % DoorDefinieren
+\definesystemvariable {de} % DEel
+\definesystemvariable {di} % DIrections
+\definesystemvariable {dl} % DunneLijnen
+\definesystemvariable {dn} % DoorNummeren
+\definesystemvariable {dm} % DefineMeasure
+\definesystemvariable {do} % DefinieerOpmaak
+\definesystemvariable {du} % DUmmy
+\definesystemvariable {ds} % DoorSpringen
+\definesystemvariable {ef} % ExternFiguur
+\definesystemvariable {ec} % EnCoding
+\definesystemvariable {el} % Elements
+\definesystemvariable {en} % ENvironments
+\definesystemvariable {ep} % ExternfiguurPreset
+\definesystemvariable {eq} % EQalign
+\definesystemvariable {er} % external resources
+\definesystemvariable {ex} % ExterneFiguren
+\definesystemvariable {fa} % font feature
+\definesystemvariable {fc} % FramedContent
+\definesystemvariable {fd} % FielD
+\definesystemvariable {fe} % FoxetExtensions
+\definesystemvariable {ff} % FontFile
+\definesystemvariable {fg} % FiGuurmaten
+\definesystemvariable {fi} % FIle
+\definesystemvariable {fl} % Floats
+\definesystemvariable {fm} % ForMules
+\definesystemvariable {fn} % subformulas
+\definesystemvariable {fo} % xml FO
+\definesystemvariable {fp} % FilegroeP
+\definesystemvariable {fq} % Features
+\definesystemvariable {fr} % ForM
+\definesystemvariable {fs} % FileSynonym
+\definesystemvariable {ft} % FonTs
+\definesystemvariable {fu} % FontSolution
+\definesystemvariable {fv} % FontVariant
+\definesystemvariable {fw} % simpleFonts by Wolfgang
+\definesystemvariable {fx} % FoXet
+\definesystemvariable {gr} % GRid
+\definesystemvariable {ha} % HAng
+\definesystemvariable {hs} % HSpace
+\definesystemvariable {ht} % HiddenText
+\definesystemvariable {ia} % Interactie
+\definesystemvariable {ib} % InteractieBalk
+\definesystemvariable {ic} % ICc profiles
+\definesystemvariable {id} % Index
+\definesystemvariable {ig} % ItemGroup
+\definesystemvariable {ih} % InHoudsopgave
+\definesystemvariable {ii} % stelIndexIn
+\definesystemvariable {il} % stelInvulRegelsin
+\definesystemvariable {im} % InMarge
+\definesystemvariable {in} % INspringen
+\definesystemvariable {ip} % InsertPages
+\definesystemvariable {is} % Items
+\definesystemvariable {it} % stelInTerliniein
+\definesystemvariable {iv} % stelInvulLijnenin
+\definesystemvariable {ka} % KAntlijn
+\definesystemvariable {kd} % KaDerteksten
+\definesystemvariable {kj} % KopJes (floats)
+\definesystemvariable {kk} % Kapitalen
+\definesystemvariable {kl} % KoLommen
+\definesystemvariable {km} % KenMerk
+\definesystemvariable {ko} % KOp(pen)
+\definesystemvariable {kp} % KopPelteken
+\definesystemvariable {kr} % KoRps
+\definesystemvariable {ks} % KolomSpan
+\definesystemvariable {kt} % KonTakten
+\definesystemvariable {kw} % KontaktWaarde
+\definesystemvariable {la} % LAnguage
+\definesystemvariable {lb} % LaBels
+\definesystemvariable {ld} % LegenDa
+\definesystemvariable {le} % LinetablE
+\definesystemvariable {lf} % LocalFigures
+\definesystemvariable {lg} % taal (LanGuage)
+\definesystemvariable {li} % LIjst
+\definesystemvariable {lk} % LinK
+\definesystemvariable {ll} % Layers
+\definesystemvariable {lx} % LayerteXt
+\definesystemvariable {ln} % LijNen
+\definesystemvariable {lo} % LOgos
+\definesystemvariable {lt} % LiTeratuur
+\definesystemvariable {ls} % languageScript
+\definesystemvariable {ly} % LaYout
+\definesystemvariable {ma} % MargeAchtergrond
+\definesystemvariable {mb} % MargeBlokken
+\definesystemvariable {md} % MoDule
+\definesystemvariable {me} % MultilingualElement (tags)
+\definesystemvariable {mg} % Metapost paGe
+\definesystemvariable {mh} % MultilingualHead
+\definesystemvariable {mk} % MarKering
+\definesystemvariable {ml} % MultilingualLabel
+\definesystemvariable {mm} % MultilingualMath
+\definesystemvariable {mt} % inline MaTh
+\definesystemvariable {mo} % Math Options
+\definesystemvariable {mp} % MetaPost
+\definesystemvariable {mx} % MatriX
+\definesystemvariable {ng} % parbuilders
+\definesystemvariable {nh} % new heads (structure)
+\definesystemvariable {nn} % structurenumbering
+\definesystemvariable {nm} % Nummering
+\definesystemvariable {np} % NaastPlaatsen
+\definesystemvariable {nr} % Nummeren
+\definesystemvariable {of} % OFfset
+\definesystemvariable {oi} % OmlijndInstellingen
+\definesystemvariable {ol} % OmLijnd
+\definesystemvariable {od} % Omlijnd Defaults (simple)
+\definesystemvariable {on} % ONderstreep
+\definesystemvariable {oo} % OpsOmmingen
+\definesystemvariable {op} % OPsomming
+\definesystemvariable {or} % OtpfilteR
+\definesystemvariable {os} % OffSet
+\definesystemvariable {ot} % OTpsequence
+\definesystemvariable {ov} % OVerlay
+\definesystemvariable {ox} % OffsetBox
+\definesystemvariable {pa} % PAlet
+\definesystemvariable {pb} % PuBlication
+\definesystemvariable {pc} % PageComment
+\definesystemvariable {pe} % PagEhandler
+\definesystemvariable {pf} % ProFiel
+\definesystemvariable {pg} % KoppelPagina
+\definesystemvariable {ph} % ParagrapH
+\definesystemvariable {pl} % PLaats
+\definesystemvariable {pn} % PaginaNummer
+\definesystemvariable {po} % PrOcessor
+\definesystemvariable {pp} % PaPier
+\definesystemvariable {pr} % PRogrammas
+\definesystemvariable {ps} % PoSitioneren
+\definesystemvariable {pt} % PageshifT
+\definesystemvariable {py} % PropertYs
+\definesystemvariable {pv} % PublicationVariable
+\definesystemvariable {ra} % RAise
+\definesystemvariable {rd} % RenDering
+\definesystemvariable {rf} % ReFereren
+\definesystemvariable {rg} % ReGel
+\definesystemvariable {rl} % ReferentieLijst
+\definesystemvariable {rn} % RegelNummer
+\definesystemvariable {ro} % ROteren
+\definesystemvariable {rr} % linenotes
+\definesystemvariable {rs} % RaSters
+\definesystemvariable {rt} % RoosTers
+\definesystemvariable {rv} % ReserVeerfiguur
+\definesystemvariable {rw} % RenderingWindow
+\definesystemvariable {sa} % ScAle
+\definesystemvariable {sb} % SectieBlok
+\definesystemvariable {sc} % SCherm
+\definesystemvariable {sd} % SounD
+\definesystemvariable {se} % SEctie
+\definesystemvariable {sf} % SpeciFics
+\definesystemvariable {sg} % SpacinG
+\definesystemvariable {sh} % ShapeText
+\definesystemvariable {si} % SplIt
+\definesystemvariable {sk} % SectieKop
+\definesystemvariable {sl} % SmalLer
+\definesystemvariable {sm} % SynonieMen
+\definesystemvariable {sn} % SubNummer
+\definesystemvariable {so} % SOrteren
+\definesystemvariable {sp} % SelecteerPapier
+\definesystemvariable {sr} % SpacehandleR
+\definesystemvariable {ss} % Symbool
+\definesystemvariable {st} % STickers
+\definesystemvariable {su} % SetUp
+\definesystemvariable {sv} % SysteemVariabelen
+\definesystemvariable {sw} % SectionWorld
+\definesystemvariable {sx} % Selector
+\definesystemvariable {sy} % SYnchronisatie
+\definesystemvariable {ta} % TAb
+\definesystemvariable {tb} % TekstBlokken
+\definesystemvariable {td} % TextbackgrounDs
+\definesystemvariable {te} % TEmplate
+\definesystemvariable {tf} % TypeFace
+\definesystemvariable {tg} % Tex paGe
+\definesystemvariable {ti} % TabelInstellingen
+\definesystemvariable {tk} % Teksten
+\definesystemvariable {tl} % TekstLijnen
+\definesystemvariable {tm} % TypesynonyM
+\definesystemvariable {tp} % TyPen
+\definesystemvariable {tx} % TeXtflow
+\definesystemvariable {to} % TOlerance
+\definesystemvariable {tr} % TRacer
+\definesystemvariable {ts} % TypeScript
+\definesystemvariable {tt} % TabulaTe
+\definesystemvariable {ty} % TYpe
+\definesystemvariable {uc} % Unicode
+\definesystemvariable {ui} % UItvoer
+\definesystemvariable {ur} % URl
+\definesystemvariable {up} % Utility Program
+\definesystemvariable {va} % VspAce
+\definesystemvariable {ve} % VErsie
+\definesystemvariable {vn} % VoetNoten
+\definesystemvariable {vs} % VSpacing
+\definesystemvariable {vt} % VerTical
+\definesystemvariable {wr} % WitRuimte
+\definesystemvariable {wl} % WordList
+\definesystemvariable {xf} % XML File
+\definesystemvariable {xl} % lxml (mkiv)
+\definesystemvariable {xm} % xml (mkiv)
+\definesystemvariable {xp} % XML Processing
+\definesystemvariable {xy} % schaal
+\definesystemvariable {za} % ZetspiegelAanpassing
+
+%D Next we define some language independant one letter
+%D variables and keywords.
+
+\defineinterfaceconstant {x} {x} % x offset
+\defineinterfaceconstant {y} {y} % y offset
+\defineinterfaceconstant {w} {w} % width
+\defineinterfaceconstant {h} {h} % height
+\defineinterfaceconstant {s} {s} % size
+\defineinterfaceconstant {t} {t} % title
+\defineinterfaceconstant {c} {c} % creator
+\defineinterfaceconstant {e} {e} % extension
+\defineinterfaceconstant {f} {f} % file
+
+\defineinterfaceconstant {a} {a} % kunnen weg
+\defineinterfaceconstant {b} {b} % kunnen weg
+\defineinterfaceconstant {c} {c} % kunnen weg
+\defineinterfaceconstant {d} {d} % kunnen weg
+\defineinterfaceconstant {e} {e} % kunnen weg
+
+\defineinterfaceconstant {s} {s}
+\defineinterfaceconstant {r} {r}
+\defineinterfaceconstant {g} {g}
+\defineinterfaceconstant {b} {b}
+\defineinterfaceconstant {c} {c}
+\defineinterfaceconstant {m} {m}
+\defineinterfaceconstant {y} {y}
+\defineinterfaceconstant {k} {k}
+\defineinterfaceconstant {a} {a} % alternative
+\defineinterfaceconstant {t} {t} % transparency
+\defineinterfaceconstant {p} {p} % percentage
+
+\defineinterfaceconstant {t} {t}
+\defineinterfaceconstant {h} {h}
+\defineinterfaceconstant {b} {b}
+
+\defineinterfaceconstant {rgb} {rgb}
+\defineinterfacevariable {rgb} {rgb}
+
+\defineinterfaceconstant {cmyk} {cmyk}
+\defineinterfacevariable {cmyk} {cmyk}
+
+\defineinterfaceconstant {mp} {mp}
+\defineinterfacevariable {mp} {mp}
+
+\defineinterfacevariable {s} {s}
+
+\defineinterfacevariable {a} {a}
+\defineinterfacevariable {b} {b}
+\defineinterfacevariable {c} {c}
+\defineinterfacevariable {d} {d}
+
+%D Special purpose variables:
+
+\def\v!oddeven#1{\ifodd#1\v!odd\else\v!even\fi}
+
+%D The names of files and their extensions are fixed.
+%D \CONTEXT\ uses as less files as possible. Utility files can
+%D be recognized by the first two characters of the extension:
+%D \type{tu}.
+
+\definefileconstant {utilityfilename} {texutil}
+
+\definefileconstant {blockextension} {tub}
+\definefileconstant {figureextension} {tuf}
+\definefileconstant {inputextension} {tui}
+\definefileconstant {outputextension} {tuo} % tup for previous run
+\definefileconstant {optionextension} {top}
+\definefileconstant {temporaryextension} {tmp}
+\definefileconstant {patternsextension} {pat}
+\definefileconstant {hyphensextension} {hyp}
+\definefileconstant {fontmapextension} {map}
+\definefileconstant {bibextension} {bbl}
+
+%D These files are loaded at start||up. They may contain system
+%D specific setups (or calls to other files), old macro's, to
+%D garantee compatibility and new macro's noy yet present in
+%D the format.
+
+\definefileconstant {errfilename} {cont-err}
+\definefileconstant {sysfilename} {cont-sys}
+\definefileconstant {oldfilename} {cont-old}
+\definefileconstant {newfilename} {cont-new}
+\definefileconstant {filfilename} {cont-fil.\mksuffix}
+\definefileconstant {modfilename} {cont-mod}
+
+%D Handy for typescripts (we could use s! instead:
+
+\definetypescriptconstant {name} {name}
+\definetypescriptconstant {default} {default}
+\definetypescriptconstant {map} {map}
+\definetypescriptconstant {special} {special}
+\definetypescriptconstant {size} {size}
+
+%D The next two files specify user settings as well as
+%D \TEXEXEC\ settings when generating a format.
+
+\definefileconstant {usrfilename} {cont-usr} % .tex
+\definefileconstant {fmtfilename} {cont-fmt} % .tex
+
+%D The setup files for the language, font, color and special
+%D subsystems have a common prefix. This means that we have at
+%D most three characters for unique filenames.
+
+\definefileconstant {colorprefix} {colo-}
+\definefileconstant {encodingprefix} {enco-}
+\definefileconstant {filterprefix} {filt-}
+\definefileconstant {fontprefix} {font-}
+\definefileconstant {handlingprefix} {hand-}
+\definefileconstant {javascriptprefix} {java-}
+\definefileconstant {languageprefix} {lang-}
+\definefileconstant {mathprefix} {math-}
+\definefileconstant {metapostprefix} {meta-}
+\definefileconstant {regimeprefix} {regi-}
+\definefileconstant {specialprefix} {spec-}
+\definefileconstant {symbolprefix} {symb-}
+\definefileconstant {typeprefix} {type-}
+\definefileconstant {xtagprefix} {xtag-}
+\definefileconstant {propprefix} {prop-}
+\definefileconstant {unicprefix} {unic-}
+\definefileconstant {sortprefix} {sort-}
+\definefileconstant {prettyprefix} {pret-}
+
+\definefileconstant {moduleprefix} {m-}
+\definefileconstant {styleprefix} {s-}
+\definefileconstant {xstyleprefix} {x-}
+\definefileconstant {privateprefix} {p-}
+\definefileconstant {thirdprefix} {t-}
+
+%definefileconstant {beforeprefix} {b-}
+%definefileconstant {afterprefix} {a-}
+
+%D \CONTEXT\ follows different strategies for finding files.
+%D The macros that are responsible for this 'clever' searching
+%D make use of two (very important) path specifiers.
+
+\definefileconstant {pathseparator} {/}
+\definefileconstant {currentpath} {.}
+\definefileconstant {parentpath} {..}
+
+%D The way fonts are defined and called upon is language
+%D independant. We follow the scheme laid down by Knuth in
+%D Plain \TEX. We'll explain their meaning later.
+
+\defineinterfaceconstant {tf} {tf}
+\defineinterfaceconstant {bf} {bf}
+\defineinterfaceconstant {bs} {bs}
+\defineinterfaceconstant {bi} {bi}
+\defineinterfaceconstant {sl} {sl}
+\defineinterfaceconstant {it} {it}
+\defineinterfaceconstant {sc} {sc}
+\defineinterfaceconstant {rm} {rm}
+\defineinterfaceconstant {ss} {ss}
+\defineinterfaceconstant {tt} {tt}
+\defineinterfaceconstant {hw} {hw}
+\defineinterfaceconstant {cg} {cg}
+\defineinterfaceconstant {os} {os}
+\defineinterfaceconstant {mm} {mm}
+\defineinterfaceconstant {i} {i}
+\defineinterfaceconstant {nn} {nn}
+
+\defineinterfaceconstant {x} {x}
+\defineinterfaceconstant {xx} {xx}
+
+\defineinterfaceconstant {em} {em}
+
+\defineinterfaceconstant {mi} {mi}
+\defineinterfaceconstant {sy} {sy}
+\defineinterfaceconstant {ex} {ex}
+\defineinterfaceconstant {mr} {mr}
+
+\defineinterfaceconstant {ma} {ma}
+\defineinterfaceconstant {mb} {mb}
+\defineinterfaceconstant {mc} {mc}
+
+%D For figure inclusion we need:
+
+\defineinterfaceconstant {tif} {tif}
+\defineinterfaceconstant {eps} {eps}
+\defineinterfaceconstant {mps} {mps}
+\defineinterfaceconstant {jpg} {jpg}
+\defineinterfaceconstant {pdf} {pdf}
+\defineinterfaceconstant {png} {png}
+\defineinterfaceconstant {avi} {avi}
+\defineinterfaceconstant {mov} {mov}
+\defineinterfaceconstant {svg} {svg}
+\defineinterfaceconstant {tex} {tex}
+\defineinterfaceconstant {tmp} {tmp}
+\defineinterfaceconstant {cld} {cld}
+
+%D A careful reader will have noticed that in the module
+%D \type{mult-ini} we defined \type{\selectinterface}. We were
+%D not yet able to actually select an interface, because we
+%D still had to define the constants and variables. Now we've
+%D done so, selection is permitted.
+
+\selectinterface
+
+%D Ok, here are some more, because we've got ouselves some
+%D extensions to \CONTEXT.
+
+\definemessageconstant {addresses}
+\definemessageconstant {documents}
+
+\protect
+
+\endinput
diff --git a/tex/context/base/s-abr-04.tex b/tex/context/base/s-abr-04.tex
new file mode 100644
index 000000000..5f1188b3b
--- /dev/null
+++ b/tex/context/base/s-abr-04.tex
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=s-abr-02,
+%D version=1996.01.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=General Abbreviations 2,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[abr-01]
+
+\unprotect
+
+\setupsorting[logo][\c!style=]
+
+\setupcapitals[\c!title=\v!no]
+
+\protect \endinput
diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua
index 548a92efe..6511cd427 100644
--- a/tex/context/base/sort-ini.lua
+++ b/tex/context/base/sort-ini.lua
@@ -275,7 +275,9 @@ local function setlanguage(l,m,d)
end
end
data.sequence = sequence
- report_sorters("using sort sequence: %s",concat(sequence," "))
+ if trace_tests then
+ report_sorters("using sort sequence: %s",concat(sequence," "))
+ end
--
return data
end
diff --git a/tex/context/base/spac-hor.mkiv b/tex/context/base/spac-hor.mkiv
index 6364b02af..269354d0f 100644
--- a/tex/context/base/spac-hor.mkiv
+++ b/tex/context/base/spac-hor.mkiv
@@ -336,8 +336,8 @@
\ifdefined\softhyphen \else \let\softhyphen\- \fi
-\ctxlua{tex.sprint(tex.ctxcatcodes,"\string\\unexpanded\string\\def\string\\\string\n{\string\\space}")}
-% \ctxlua{tex.sprint(tex.ctxcatcodes,"\string\\let\string\\\string\n=\string\\space")}
+\ctxsprint{"\string\\unexpanded\string\\def\string\\\string\n{\string\\space}"}
+%ctxsprint{"\string\\let\string\\\string\n=\string\\space"}
% in tables we need:
%
diff --git a/tex/context/base/strc-not.mkiv b/tex/context/base/strc-not.mkiv
index 02434c637..97cf2c7d1 100644
--- a/tex/context/base/strc-not.mkiv
+++ b/tex/context/base/strc-not.mkiv
@@ -192,7 +192,7 @@
%\c!factor=,
%\c!scope=, % \v!text \v!page
\c!prefixconnector=.,
- %\c!next=\autoinsertnextspace
+ %\c!next=\autoinsertnextspace,
\c!prefix=\v!no,
%\c!continue=\v!no,
\c!paragraph=\v!no,
diff --git a/tex/context/base/supp-ali.tex b/tex/context/base/supp-ali.mkii
index 8727efbb2..8727efbb2 100644
--- a/tex/context/base/supp-ali.tex
+++ b/tex/context/base/supp-ali.mkii
diff --git a/tex/context/base/supp-ali.mkiv b/tex/context/base/supp-ali.mkiv
new file mode 100644
index 000000000..8727efbb2
--- /dev/null
+++ b/tex/context/base/supp-ali.mkiv
@@ -0,0 +1,173 @@
+%D \module
+%D [ file=supp-ali,
+%D version=2000.04.17,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Alignment,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Yet undocumented.
+
+% 0 = centered
+% 1 = left in before
+% 2 = right in before
+% 3 = left in after
+% 4 = right in after
+
+\unprotect
+
+% \starttabulate[|cg{.}|cg{,}|cg{,}|]
+% \NC period \NC comma \NC comma \NC\NR
+% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR
+% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR
+% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR
+% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR
+% \NG 10\\ \NG 10\\ \NG 0,00 \NC\NR
+% \NG 10 \NG 10 \NG 0,00 \NC\NR
+% \NG 10 \NG 10 \NG 0,00 \NC\NR
+% \stoptabulate
+
+\chardef\characteralignmentmode=4
+\chardef\characteralignmentslot=1
+
+\newtoks\@@characteralignlst
+
+\let\afterassignwidth \!!zeropoint
+\let\beforeassignwidth\!!zeropoint
+
+\def\alignmentcharacter{.}
+
+\let\alignmentclass\s!default % can be used to handle multiple mixed ones
+
+\def\setfirstpasscharacteralign
+ {\popcharacteralign
+ \expanded{\dosetfirstpasscharacteralign{\alignmentcharacter}}}
+
+\def\dosetfirstpasscharacteralign#1%
+ {\def\checkalignment##1%
+ {\popcharacteralign
+ \let\\\empty
+ \setbox\scratchbox\hbox{#1}%
+ \edef\characterassignwidth{\the\wd\scratchbox}%
+ \setbox\scratchbox\null
+ \docheckalignment##1#1\relax\relax
+ \scratchdimen-\wd\scratchbox
+ \setbox\scratchbox\hbox{\ignorespaces##1\unskip}%
+ \advance\scratchdimen \wd\scratchbox
+ \ifdim\scratchdimen>\beforeassignwidth\relax
+ \edef\beforeassignwidth{\the\scratchdimen}%
+ \fi
+ \ifdim\scratchdimen=\zeropoint
+ \setbox\scratchbox\hbox{\ignorespaces##1\unskip}%
+ \scratchdimen\wd\scratchbox
+ \ifcase\characteralignmentmode
+ % do nothing
+ \else\ifnum\characteralignmentmode<\plusthree
+ \advance\scratchdimen \characterassignwidth
+ \ifdim\scratchdimen>\beforeassignwidth\relax
+ \edef\beforeassignwidth{\the\scratchdimen}%
+ \fi
+ \else
+ \ifdim\scratchdimen>\afterassignwidth\relax
+ \edef\afterassignwidth{\the\scratchdimen}%
+ \fi
+ \fi\fi
+ \fi
+ \pushcharacteralign}%
+ \def\docheckalignment##1#1##2##3\relax
+ {\ifx##2\relax
+ \setbox\scratchbox\hbox{\ignorespaces##1\unskip}%
+ \ifdim\wd\scratchbox>\afterassignwidth
+ \edef\afterassignwidth{\the\wd\scratchbox}%
+ \fi
+ \else
+ \docheckalignment##2##3\relax\relax
+ \fi}}
+
+\def\setsecondpasscharacteralign
+ {\popcharacteralign
+ \expanded{\dosetsecondpasscharacteralign{\alignmentcharacter}}}
+
+\def\dosetsecondpasscharacteralign#1%
+ {\def\checkalignment##1%
+ {\popcharacteralign
+ \let\\\empty % beware, no grouping
+ \setbox\scratchbox\hbox{#1}%
+ \edef\characterassignwidth{\the\wd\scratchbox}%
+ \setbox\scratchbox\null
+ % new 12,34 vs 10\\ where 10 aligns on 12 if #1 = ,
+ \ifcase\characteralignmentslot
+ \docheckalignment##1#1\relax\relax
+ \scratchdimen\wd\scratchbox
+ \setbox\scratchbox\hbox{\ignorespaces##1\unskip}%
+ \else
+ \def\\{#1}%
+ \expanded{\docheckalignment##1#1\relax\relax}%
+ \scratchdimen\wd\scratchbox
+ \setbox\scratchbox\hbox{\def\\{\hphantom{#1}}\ignorespaces##1\unskip}%
+ \fi
+ \noindent
+ \ifdim\scratchdimen=\wd\scratchbox
+ \ifcase\characteralignmentmode
+ \box\scratchbox
+ \else
+ \hbox
+ {\dontcomplain
+ \hbox to \beforeassignwidth
+ {\ifcase\characteralignmentmode\or
+ \box\scratchbox\hss
+ \or
+ \hss\box\scratchbox\hskip\characterassignwidth
+ \or
+ \hss\rlap{\box\scratchbox}%
+ \or
+ \hss\rlap{\hbox to \afterassignwidth{\hss\box\scratchbox}}%
+ \fi}%
+ \hskip\afterassignwidth}%
+ \fi
+ \else
+ \hbox
+ {\hbox to \beforeassignwidth
+ {\hss\box\scratchbox\hskip-\scratchdimen}%
+ \hskip\afterassignwidth}%
+ \fi}%
+ \def\docheckalignment##1#1##2##3\relax
+ {\ifx##2\relax
+ \setbox\scratchbox\hbox{\ignorespaces##1\unskip}%
+ \else
+ \docheckalignment##2##3\relax\relax
+ \fi}}
+
+% provide a means to use multiple alignments mixed
+
+\def\pushcharacteralign
+ {\ifundefined{@cac@\alignmentclass}%
+ \doglobal\appendetoks\noexpand\do{\alignmentclass}\to\@@characteralignlst
+ \fi
+ \setxvalue{@cac@\alignmentclass}{\noexpand\do
+ {\afterassignwidth}{\beforeassignwidth}{\alignmentcharacter}}}
+
+\def\popcharacteralign
+ {\def\do##1##2##3%
+ {\def\afterassignwidth {##1}%
+ \def\beforeassignwidth {##2}%
+ \def\alignmentcharacter{##3}}%
+ \executeifdefined{@cac@\alignmentclass}\donothing}
+
+\def\resetcharacteralign % does not work well nested
+ {\def\do##1{\global\letbeundefined{@cac@##1}}% global !
+ \the\@@characteralignlst
+ \global\@@characteralignlst\emptytoks}
+
+\long\def\startcharacteralign#1\stopcharacteralign
+ {\bgroup
+ \setfirstpasscharacteralign #1%
+ \setsecondpasscharacteralign#1%
+ \egroup}
+
+\protect \endinput
diff --git a/tex/context/base/supp-box.tex b/tex/context/base/supp-box.mkii
index dd83d76d4..b09099221 100644
--- a/tex/context/base/supp-box.tex
+++ b/tex/context/base/supp-box.mkii
@@ -508,7 +508,9 @@
\def\doiftextelse#1%
{\bgroup
- \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}%
+ \setbox\scratchbox\normalhbox
+ {\trialtypesettingtrue
+ \ignorespaces#1\removeunwantedspaces}%
\ifzeropt\wd\scratchbox
\egroup\@EA\secondoftwoarguments
\else
diff --git a/tex/context/base/supp-box.mkiv b/tex/context/base/supp-box.mkiv
new file mode 100644
index 000000000..f1ed751a0
--- /dev/null
+++ b/tex/context/base/supp-box.mkiv
@@ -0,0 +1,3126 @@
+%D \module
+%D [ file=supp-box,
+%D version=1995.10.10,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Boxes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module implements some box manipulation macros. Some
+%D are quite simple, some are more advanced and when understood
+%D well, all can be of use.
+
+%D No longer generic, why bother.
+
+\writestatus{loading}{ConTeXt Support Macros / Boxes}
+
+\unprotect
+
+%D \macros
+%D {strutdp,strutht,strutwd}
+%D
+%D The next shortcuts save memory and keying. The width is
+%D normally zero points (if not, you're in trouble). These
+%D shortcuts can be used like a dimension, opposite to the
+%D core macros \type {\strutdepth} and alike, which are
+%D values.
+
+\def\strutdp{\dp\strutbox}
+\def\strutht{\ht\strutbox}
+\def\strutwd{\wd\strutbox}
+
+%D \macros
+%D {resetbox, emptybox}
+%D
+%D Let's start with an easy one. The next macro hides the
+%D ugly \type {@} in \type {\voidb@x}.
+
+\ifx\voidbox\undefined \newbox\voidbox \fi
+\ifx\voidb@x\undefined \let\voidb@x\voidbox \fi
+
+\def\emptybox {\box \voidbox}
+\def\unvoidbox {\unhbox\voidbox}
+\def\resetbox#1{\setbox#1\box\voidbox}
+
+%D \macros
+%D {nextdepth}
+%D
+%D Let's start with a rather simple declaration. Sometimes we
+%D need to save the \TEX\ \DIMENSION\ \type{\prevdepth} and
+%D append it later on. The name \type{\nextdepth} suits
+%D this purpose well.
+
+\newdimen\nextdepth
+
+%D \macros
+%D {smashbox, smashedbox}
+%D
+%D Smashing is introduced in \PLAIN\ \TEX, and stands for
+%D reducing the dimensions of a box to zero. The most resolute
+%D one is presented first.
+
+\def\smashbox#1%
+ {\wd#1\zeropoint
+ \ht#1\zeropoint
+ \dp#1\zeropoint}
+
+\def\smashboxed#1%
+ {\smashbox{#1}%
+ \box#1\relax}
+
+%D \macros
+%D {hsmashbox,vsmashbox}
+%D
+%D Smashing can be used for overlaying boxes. Depending on
+%D the mode, horizontal or vertical, one can use:
+
+\def\hsmashbox#1%
+ {\wd#1\zeropoint}
+
+\def\vsmashbox#1%
+ {\ht#1\zeropoint
+ \dp#1\zeropoint}
+
+%D The next implementation is less sensitive for spurious
+%D spaces.
+
+\newcount\registercount
+
+\def\smashbox
+ {\afterassignment\dosmashbox\registercount}
+
+\def\dosmashbox
+ {\wd\registercount\zeropoint
+ \ht\registercount\zeropoint
+ \dp\registercount\zeropoint}
+
+\def\smashedbox
+ {\afterassignment\thesmashedbox\registercount}
+
+\def\thesmashedbox
+ {\dosmashbox
+ \box\registercount}
+
+\def\hsmashbox
+ {\afterassignment\dohsmashbox\registercount}
+
+\def\dohsmashbox
+ {\wd\registercount\zeropoint}
+
+\def\vsmashbox
+ {\afterassignment\dovsmashbox\registercount}
+
+\def\dovsmashbox
+ {\ht\registercount\zeropoint
+ \dp\registercount\zeropoint}
+
+%D \macros
+%D {hsmash,vsmash,
+%D hsmashed,vsmashed}
+%D
+%D While the previous macros expected a \BOX, the next act on a
+%D content. They are some subtle differences betreen the smash
+%D and smashed alternatives. The later ones reduce all
+%D dimensions to zero.
+
+% Ok, but inefficient and/or catcode unsafe:
+%
+% \def\hsmash #1{\bgroup\setbox0=\normalhbox{#1}\hsmashbox0\box0\egroup}
+% \def\vsmash #1{\bgroup\setbox0=\normalvbox{#1}\vsmashbox0\box0\egroup}
+% \def\hsmashed#1{\bgroup\setbox0=\normalhbox{#1}\smashbox 0\box0\egroup}
+% \def\vsmashed#1{\bgroup\setbox0=\normalvbox{#1}\smashbox 0\box0\egroup}
+%
+% Better, but a waste of tokens:
+%
+% \def\hsmash {\bgroup\dowithnextbox{\hsmashbox\nextbox\flushnextbox\egroup}\normalhbox}
+% \def\vsmash {\bgroup\dowithnextbox{\vsmashbox\nextbox\flushnextbox\nextbox\egroup}\normalvbox}
+% \def\hsmashed{\bgroup\dowithnextbox{\smashbox \nextbox\flushnextbox\nextbox\egroup}\normalhbox}
+% \def\vsmashed{\bgroup\dowithnextbox{\smashbox \nextbox\flushnextbox\nextbox\egroup}\normalvbox}
+%
+% The best:
+
+\def\dosomesmash#1% (begin|end)group ipv (b|e)group ?
+ {\bgroup\dowithnextbox{#1\nextbox\flushnextbox\egroup}}
+
+\def\hsmash {\dosomesmash\hsmashbox\normalhbox}
+\def\vsmash {\dosomesmash\vsmashbox\normalvbox}
+\def\hsmashed{\dosomesmash\smashbox \normalhbox}
+\def\vsmashed{\dosomesmash\smashbox \normalvbox}
+
+%D \macros
+%D {smashedhbox,smashedvbox}
+%D
+%D Also handy (all dimensions zeroed):
+%D
+%D \starttyping
+%D \smashedhbox to ... {...}
+%D \smashedvbox to ... {...}
+%D \stoptyping
+
+\def\dosmashedbox#1%
+ %{#1\bgroup\dowithnextbox{\smashbox\nextbox\flushnextbox\egroup}#1}
+ {#1\bgroup\dowithnextbox{\smashedbox\nextbox\egroup}#1}
+
+\def\smashedhbox{\dosmashedbox\hbox}
+\def\smashedvbox{\dosmashedbox\vbox}
+
+%D \macros
+%D {smash}
+%D
+%D This smash alternative takes an optional arg [whdtb] as
+%D well as is potentially catcode safer. It is needed by the
+%D math module (although the \type {\leavevmode} is not added
+%D here).
+
+\def\smash
+ {\futurelet\nexttoken\dosmash}
+
+\def\dosmash
+ {\ifx\nexttoken[\@EA\dodosmash\else\@EA\donosmash\fi}
+
+\def\donosmash
+ {\dodosmash[hd]}
+
+\def\dodosmash[#1]%
+ {\edef\@@smash{#1}\futurelet\nexttoken\dododosmash}
+
+\def\dododosmash % if needed we can avoid the \next
+ {\ifmmode
+ \def\next##1{\mathpalette\mathsm@sh{##1}}%
+ \else\ifx\nexttoken\bgroup
+ \let\next\finsm@sh
+ \else
+ \def\next##1{\finsm@sh{##1}}%
+ \fi\fi
+ \next}
+
+\def\mathsm@sh#1#2% redefined plain macro
+ {\finsm@sh{$\mathsurround\zeropoint#1{#2}$}}
+
+\def\makesm@sh#1% redefined plain macro (handles t b h d w)
+ {\if#1w\nextboxwd\zeropoint\else
+ \if#1h\nextboxht\zeropoint\else
+ \if#1d\nextboxdp\zeropoint\else
+ \if#1t\nextboxht\zeropoint\else
+ \if#1b\nextboxdp\zeropoint\fi\fi\fi\fi\fi}
+
+\def\finsm@sh % redefined plain macro
+ {\dowithnextbox{\@EA\handletokens\@@smash\with\makesm@sh\flushnextbox}\normalhbox}
+
+%D \starttabulate[|l|l|]
+%D \NC w \NC \ruledhbox{\smash [w]{This is some great smashing, isn't it?}} \NC \NR
+%D \NC h \NC \ruledhbox{\smash [h]{This is some great smashing, isn't it?}} \NC \NR
+%D \NC d \NC \ruledhbox{\smash [d]{This is some great smashing, isn't it?}} \NC \NR
+%D \NC tb \NC \ruledhbox{\smash [tb]{This is some great smashing, isn't it?}} \NC \NR
+%D \NC whd \NC \ruledhbox{\smash[whd]{This is some great smashing, isn't it?}} \NC \NR
+%D \stoptabulate
+
+%D \macros
+%D {phantom, hphantom, vphantom, mathstrut}
+%D
+%D The next implementation of \type {\phantom} cum suis does
+%D not grab an argument in the non||math case, which is better.
+
+\unexpanded\def\phantom {\ph@nt\nextbox\nextbox\nextbox}
+\unexpanded\def\vphantom{\ph@nt\nextbox\nextbox\voidbox}
+\unexpanded\def\hphantom{\ph@nt\voidbox\voidbox\nextbox}
+
+%D Due to a complicated call to \type {\mathpallete} and
+%D thereby \type {\mathchoice}, the next macro looks ugly.
+%D We also take care of non||braced arguments.
+
+\def\ph@nt#1#2#3%
+ {\def\doph@nt
+ {\ifmmode
+ \def\mathph@nt####1####2{\makeph@nt#1#2#3{$\mathsurround\zeropoint####1{####2}$}}%
+ \def\nextph@nt{\mathpalette\mathph@nt}%
+ \else\ifx\nextph@nt\bgroup
+ \def\nextph@nt{\makeph@nt#1#2#3}%
+ \else
+ \def\nextph@nt####1{\makeph@nt#1#2#3{####1}}%
+ \fi\fi
+ \nextph@nt}%
+ \futurelet\nextph@nt\doph@nt}
+
+\def\makeph@nt#1#2#3%
+ {\begingroup
+ \dowithnextbox
+ {\setbox\scratchbox\null
+ \ht\scratchbox\ht#1%
+ \dp\scratchbox\dp#2%
+ \wd\scratchbox\wd#3%
+ \box\scratchbox
+ \endgroup}
+ \normalhbox}
+
+\let\finph@nt\undefined
+
+%D We also define plain's \type {\mathstrut}.
+
+\unexpanded\def\mathstrut{\vphantom{(}}
+
+%D \macros
+%D {getboxheight}
+%D
+%D Although often needed, \TEX\ does not support arithmics
+%D like:
+%D
+%D \starttyping
+%D \dimen0 = \ht0 + \dp0
+%D \stoptyping
+%D
+%D so we implemented:
+%D
+%D \starttyping
+%D \getboxheight ... \of \box...
+%D \stoptyping
+%D
+%D For instance,
+%D
+%D \starttyping
+%D \getboxheight \dimen0 \of \box0
+%D \getboxheight \someheight \of \box \tempbox
+%D \stoptyping
+%D
+%D The implementation is rather stupid:
+%D
+%D \starttyping
+%D \def\getboxheight#1\of#2\box#3%
+%D {#1\ht#3\advance#1\dp#3\relax}
+%D \stoptyping
+%D
+%D The next alternative is slightly more clever, since
+%D it accepts \type {{12}} as well as \type {12} as box
+%D number.
+
+\def\getboxheight#1\of#2\box#3%
+ {\def\next{#1\dimexpr\ht\registercount+\dp\registercount\relax}%
+ \afterassignment\next\registercount=#3}
+
+%D For a long time the following three macros were part of
+%D the grid snapping core module, but it makes more sense to
+%D have them here so that users can see them.
+%D
+%D \macros
+%D {getnoflines, getroundednoflines, getrawnoflines}
+%D
+%D Het commando \type{\getnoflines} converteert een hoogte
+%D (dimensie) in een aantal regels en kent dit toe aan
+%D \type{\noflines}.
+%D
+%D \starttyping
+%D \getnoflines{dimensie}
+%D \stoptyping
+%D
+%D Er wordt gedeeld door \type{\openlineheight} en een hoogte
+%D van~0pt komt overeen met 0~regels. The raw alternative
+%D does not round.
+
+%D For a long time we had:
+%D
+%D \starttyping
+%D \newcount\noflines
+%D \newdimen\noflinesheight
+%D
+%D \def\dogetnoflines#1#2%
+%D {\noflinesheight#2\relax
+%D \ifzeropt\noflinesheight % \ifdim\noflinesheight=\zeropoint
+%D \noflines\zerocount
+%D \else
+%D \divide\noflinesheight \openlineheight
+%D \noflines\noflinesheight
+%D #1\ifdim\noflines\openlineheight=#2\relax \else
+%D \advance\noflines\ifdim#2>\zeropoint\plusone\else\minusone\fi
+%D \fi\fi
+%D \fi}
+%D
+%D \def\getnoflines {\dogetnoflines\iftrue } % compensated
+%D \def\getrawnoflines{\dogetnoflines\iffalse} % no compensation
+%D \stoptyping
+%D
+%D A more recent variant is:
+
+\ifx\roundingeps\undefined \newdimen\roundingeps \roundingeps=10sp \fi
+
+\newcount\noflines
+\newdimen\noflinesheight
+
+% \def\getnoflines {\xdogetnoflines\plusone } % compensated
+% \def\getroundednoflines{\xdogetnoflines\plustwo } % rounded
+% \def\getrawnoflines {\xdogetnoflines\plusthree} % truncated
+%
+% \def\xdogetnoflines#1#2%
+% {\noflinesheight#2\relax
+% \ifzeropt\noflinesheight
+% \noflines\zerocount
+% \else\ifdim\noflinesheight>\zeropoint
+% \ifcase#1\or
+% \advance\noflinesheight-\roundingeps
+% \divide\noflinesheight\openlineheight
+% \noflines\noflinesheight
+% \advance\noflines\plusone
+% \or
+% \advance\noflinesheight\roundingeps
+% \divide\noflinesheight\openlineheight
+% \noflines\noflinesheight
+% \or
+% \advance\noflinesheight\roundingeps
+% \advance\noflinesheight.5\openlineheight
+% \divide\noflinesheight\openlineheight
+% \noflines\noflinesheight
+% \fi
+% \else
+% \ifcase#1\or
+% \advance\noflinesheight\roundingeps
+% \divide\noflinesheight\openlineheight
+% \noflines\noflinesheight
+% \advance\noflines\minusone
+% \or
+% \advance\noflinesheight-\roundingeps
+% \divide\noflinesheight\openlineheight
+% \noflines\noflinesheight
+% \or
+% \advance\noflinesheight-\roundingeps
+% \advance\noflinesheight-.5\openlineheight
+% \divide\noflinesheight\openlineheight
+% \noflines\noflinesheight
+% \fi
+% \fi\fi}
+
+\def\getnoflines#1%
+ {\noflinesheight#1\relax
+ \ifzeropt\noflinesheight
+ \noflines\zerocount
+ \else\ifdim\noflinesheight>\zeropoint
+ \advance\noflinesheight-\roundingeps
+ \divide\noflinesheight\openlineheight
+ \noflines\noflinesheight
+ \advance\noflines\plusone
+ \else
+ \advance\noflinesheight\roundingeps
+ \divide\noflinesheight\openlineheight
+ \noflines\noflinesheight
+ \advance\noflines\minusone
+ \fi\fi}
+
+\def\getroundednoflines#1%
+ {\noflinesheight#1\relax
+ \ifzeropt\noflinesheight
+ \noflines\zerocount
+ \else\ifdim\noflinesheight>\zeropoint
+ \advance\noflinesheight\roundingeps
+ \divide\noflinesheight\openlineheight
+ \noflines\noflinesheight
+ \else
+ \advance\noflinesheight-\roundingeps
+ \divide\noflinesheight\openlineheight
+ \noflines\noflinesheight
+ \fi\fi}
+
+\def\getrawnoflines#1%
+ {\noflinesheight#1\relax
+ \ifzeropt\noflinesheight
+ \noflines\zerocount
+ \else\ifdim\noflinesheight>\zeropoint
+ \advance\noflinesheight\roundingeps
+ \advance\noflinesheight.5\openlineheight
+ \divide\noflinesheight\openlineheight
+ \noflines\noflinesheight
+ \else
+ \advance\noflinesheight-\roundingeps
+ \advance\noflinesheight-.5\openlineheight
+ \divide\noflinesheight\openlineheight
+ \noflines\noflinesheight
+ \fi\fi}
+
+%D Let's proof that it works:
+%D
+%D \startbuffer
+%D \scratchdimen\dimexpr(3pt) \getnoflines\scratchdimen 1=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight) \getnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10.1\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10.5\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10.9\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight+3pt) \getnoflines\scratchdimen 11=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight+3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight-3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf
+%D
+%D \scratchdimen\dimexpr(3pt) \getrawnoflines\scratchdimen 0=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10.1\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10.5\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10.9\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight+3pt) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight+3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \scratchdimen\dimexpr(10\lineheight-3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {determinenoflines}
+%D
+%D The next macro determines the number of lines and
+%D returns it it \type {\noflines}. The macro works
+%D reasonable well as long as the content can be unboxed.
+%D
+%D \starttyping
+%D \determinenoflines{test\\test}
+%D \determinenoflines{\bfd test\\test}
+%D \determinenoflines{\definedfont[Sans at 40pt]test\\test}
+%D \stoptyping
+
+\def\determinenoflines % can be mkiv'd
+ {\bgroup
+ \forgetall
+ \let\crlf\endgraf
+ \let\\\endgraf
+ \dowithnextbox
+ {\beginofshapebox
+ \unvbox\nextbox
+ \endofshapebox
+ % \global\count1\zerocount
+ % \reshapebox{\global\advance\count1\plusone}%
+ % \egroup\noflines\count1 }%
+ \scratchcounter\zerocount
+ \reshapebox{\global\advance\scratchcounter\plusone}%
+ \expandafter\egroup\expandafter\noflines\the\scratchcounter\relax
+ }\vbox}
+
+%D \macros
+%D {doiftextelse, doiftext}
+%D
+%D When \type {\doifelse} cum suis hopelessly fail, for
+%D instance because we pass data, we can fall back on the next
+%D macro:
+%D
+%D \starttyping
+%D \doiftextelse {data} {then branch} {else branch}
+%D \doiftext {data} {then branch}
+%D \stoptyping
+
+\def\doiftextelse#1%
+ {\bgroup
+ \setbox\scratchbox\normalhbox
+ {\settrialtypesetting
+ \ignorespaces#1\removeunwantedspaces}%
+ \ifzeropt\wd\scratchbox
+ \egroup\@EA\secondoftwoarguments
+ \else
+ \egroup\@EA\firstoftwoarguments
+ \fi}
+
+\def\doiftext#1#2%
+ {\doiftextelse{#1}{#2}\donothing}
+
+%D \macros
+%D {dowithnextbox,nextbox}
+%D
+%D Sometimes we want a macro to grab a box and do something
+%D on the content. One could pass an argument to a box, but
+%D this can violate the specific \CATCODES\ of its content and
+%D leads to unexpected results. The next macro treats the
+%D following braced text as the content of a box and
+%D manipulates it afterwards in a predefined way.
+%D
+%D The first argument specifies what to do with the content.
+%D This content is available in \type{\nextbox}. The second
+%D argument is one of \type{\hbox}, \type{\vbox} or
+%D \type{\vtop}. The third argument must be grouped with
+%D \type{\bgroup} and \type{\egroup}, \type{{...}} or can be
+%D a \type{\box} specification.
+%D
+%D In \CONTEXT\ this macro is used for picking up a box and
+%D treating it according to earlier specifications. We use for
+%D instance something like:
+%D
+%D \starttyping
+%D \def\getfloat%
+%D {\def\handlefloat{...\flushnextbox...}
+%D \dowithnextbox\handlefloat\normalvbox}
+%D \stoptyping
+%D
+%D instead of:
+%D
+%D \starttyping
+%D \def\getfloat#1%
+%D {...#1...}
+%D \stoptyping
+%D
+%D In this implementation the \type{\aftergroup} construction
+%D is needed because \type{\afterassignment} is executed inside
+%D the box.
+
+\ifx\nextbox\undefined \newbox\nextbox \fi
+
+\long\def\dowithnextbox#1%
+ {\long\def\dodowithnextbox{#1}%
+ \afterassignment\dododowithnextbox
+ \setbox\nextbox}
+
+\def\dododowithnextbox
+ {\aftergroup\dodowithnextbox}
+
+\long\def\dowithnextboxcs#1%
+ {\let\dodowithnextbox#1%
+ \afterassignment\dododowithnextbox
+ \setbox\nextbox}
+
+\def\dododowithnextbox
+ {\aftergroup\dodowithnextbox}
+
+%D So in fact we get:
+%D
+%D \starttyping
+%D \setbox\nextbox { \aftergroup\dodowithnextbox ... }
+%D \stoptyping
+%D
+%D or
+%D
+%D \starttyping
+%D \setbox\nextbox { ... } \dodowithnextbox
+%D \stoptyping
+%D
+%D A slower but more versatile implementation is:
+%D
+%D \starttyping
+%D \long\def\dowithnextbox#1#2%
+%D {\long\def\dodowithnextbox{#1}%
+%D \ifx#2\normalhbox
+%D \afterassignment\dododowithnextbox
+%D \else\ifx#2\normalvbox
+%D \afterassignment\dododowithnextbox
+%D \else\ifx#2\normalvtop
+%D \afterassignment\dododowithnextbox
+%D \else\ifx#2\normalvcenter
+%D \afterassignment\dododowithnextbox
+%D \else
+%D \afterassignment\dodowithnextbox
+%D \fi\fi\fi\fi
+%D \setbox\nextbox#2}
+%D \stoptyping
+%D
+%D This alternative also accepts \type{\box0} and alike, but
+%D we don't really need this functionality now.
+
+%D \macros
+%D {nextboxht,nextboxwd,nextboxdp,flushnextbox}
+%D
+%D The next couple of shortcuts saves us memory as well as
+%D \type {{}}'s in passing parameters.
+
+\def\nextboxht{\ht\nextbox}
+\def\nextboxwd{\wd\nextbox}
+\def\nextboxdp{\dp\nextbox}
+
+\def\flushnextbox{\box\nextbox}
+
+%D \macros
+%D {dowithnextboxcontent}
+%D
+%D But, occasionally we do need to pass some local settings
+%D without wanting to use additional grouping. Therefore we
+%D provide:
+%D
+%D \starttyping
+%D \dowithnextboxcontent{inside}{after}{box content}
+%D \stoptyping
+%D
+%D {\em todo: Search source for potential usage!}
+
+\long\def\dowithnextboxcontent#1#2% inside, after
+ {\long\def\dodowithnextbox{#2}%
+ \def\dododowithnextbox{#1\aftergroup\dodowithnextbox}%
+ \afterassignment\dododowithnextbox
+ \setbox\nextbox}
+
+%D Now we can redefine \type {\dowithnextbox} as follows:
+%D
+%D \starttyping
+%D \def\dowithnextbox{\dowithnextboxcontent\empty}
+%D \stoptyping
+%D
+%D But since this macro is used often and since this implementation
+%D is slower, we will not use that definition.
+
+% maybe:
+%
+% depending on the size of the action, about 10% faster
+%
+% \newtoks\nextboxtoks
+%
+% \def\dowithnextbox {\afterassignment\redowithnextbox\nextboxtoks}
+% \def\redowithnextbox {\afterassignment\dododowithnextbox\setbox\nextbox}
+% \def\dododowithnextbox{\aftergroup\dodowithnextbox}
+% \def\dodowithnextbox {\the\nextboxtoks}
+%
+% \long\def\dowithnextboxcontent#1% #2% inside, after
+% {\def\dododowithnextbox{#1\aftergroup\dodowithnextbox}%
+% \afterassignment\redowithnextboxcontent\nextboxtoks}
+%
+% \def\redowithnextboxcontent
+% {\afterassignment\dododowithnextbox\setbox\nextbox}
+
+%D \macros
+%D {llap, rlap, tlap, blap, clap}
+%D
+%D Some well known friends, but we implement them our own
+%D way. We want the macros to work in both math and text mode.
+
+\def\dodorlap{\normalhbox to \zeropoint{\flushnextbox\normalhss}\endgroup}
+\def\dodollap{\normalhbox to \zeropoint{\normalhss\flushnextbox}\endgroup}
+\def\dodoclap{\normalhbox to \zeropoint{\normalhss\flushnextbox\normalhss}\endgroup}
+
+\def\dorlap{\begingroup\dowithnextboxcs\dodorlap\normalhbox}
+\def\dollap{\begingroup\dowithnextboxcs\dodollap\normalhbox}
+\def\doclap{\begingroup\dowithnextboxcs\dodoclap\normalhbox}
+
+\def\domathclap{\mathpalette\dodomathclap} \def\dodomathclap#1#2{\doclap{$\mathsurround\zeropoint#1#2$}}
+\def\domathllap{\mathpalette\dodomathllap} \def\dodomathllap#1#2{\dollap{$\mathsurround\zeropoint#1#2$}}
+\def\domathrlap{\mathpalette\dodomathrlap} \def\dodomathrlap#1#2{\dorlap{$\mathsurround\zeropoint#1#2$}}
+
+\unexpanded\def\rlap{\mathortext\domathrlap\dorlap}
+\unexpanded\def\llap{\mathortext\domathllap\dollap}
+\unexpanded\def\clap{\mathortext\domathclap\doclap}
+
+\def\dodotlap{\normalvbox to \zeropoint{\normalvss\flushnextbox}\endgroup}
+\def\dodoblap{\normalvbox to \zeropoint{\flushnextbox\normalvss}\endgroup}
+
+\def\tlap{\begingroup\dowithnextboxcs\dodotlap\normalvbox}
+\def\blap{\begingroup\dowithnextboxcs\dodoblap\normalvbox}
+
+%D \macros
+%D {beginofshapebox,
+%D reshapebox, doreshapebox,
+%D flushshapebox,
+%D innerflushshapebox,
+%D shapebox,
+%D ifreshapingbox}
+%D
+%D The next utility macro originates from some linenumbering
+%D mechanism. Due to \TEX's advanced way of typesetting
+%D paragraphs, it's not easy to do things on a line||by||line
+%D basis. This macro is able to reprocess a given box and can
+%D act upon its vertical boxed components, such as lines. The
+%D unwinding sequence in this macro is inspired by a \NTG\
+%D workshop of David Salomon in June 1992.
+%D
+%D First we have to grab the piece of text we want to act
+%D upon. This is done by means of the duo macros:
+%D
+%D \starttyping
+%D \beginofshapebox
+%D a piece of text
+%D \endofshapebox
+%D \stoptyping
+%D
+%D When all texts is collected, we can call \type{\reshapebox}
+%D and do something with it's vertical components. We can make
+%D as much passes as needed. When we're done, the box can be
+%D unloaded with \type{\flushshapebox}. The only condition in
+%D this scheme is that \type{\reshapebox} must somehow unload
+%D the \BOX\ \type{\shapebox}.
+%D
+%D An important aspect is that the content is unrolled
+%D bottom||up. The next example illustrates this maybe
+%D unexpected characteristic.
+%D
+%D \startbuffer
+%D \beginofshapebox
+%D \em \input tufte
+%D \endofshapebox
+%D
+%D \newcounter\LineNumber
+%D
+%D \reshapebox
+%D {\doglobal\increment\LineNumber
+%D \normalhbox{\llap{\LineNumber\hskip2em}\box\shapebox}}
+%D
+%D \flushshapebox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D As we can see, when some kind of numbering is done, we have
+%D to add a second pass.
+%D
+%D \startbuffer
+%D \newcounter\LineNumber
+%D \newcounter\NumberOfLines
+%D
+%D \reshapebox
+%D {\doglobal\increment\NumberOfLines
+%D \box\shapebox}
+%D
+%D \reshapebox
+%D {\doglobal\increment\LineNumber
+%D \normalhbox
+%D {\llap{\LineNumber\ (\NumberOfLines)\hskip2em}%
+%D \box\shapebox}%
+%D \doglobal\decrement\NumberOfLines}
+%D
+%D \flushshapebox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D This example shows that the content of the box is still
+%D available after flushing. Another feature is that only the
+%D last reshaping counts. Multiple reshaping can be done by:
+%D
+%D \startbuffer
+%D \beginofshapebox
+%D \flushshapebox
+%D \endofshapebox
+%D
+%D \reshapebox
+%D {\doglobal\increment\LineNumber
+%D \normalhbox{\llap{$\star$\hskip1em}\box\shapebox}%
+%D \doglobal\decrement\NumberOfLines}
+%D
+%D \flushshapebox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D The macros are surprisingly easy to follow and in fact
+%D introduce no new concepts. Nearly all books on \TEX\ show
+%D similar solutions for unwinding \BOXES.
+%D
+%D Some macros, like footnote ones, can be sensitive for
+%D reshaping, which can result in an endless loop. We
+%D therefore offer:
+%D
+%D \starttyping
+%D \ifreshapingbox
+%D \stoptyping
+%D
+%D Some \CONTEXT\ commands are protected this way. Anyhow,
+%D reshaping is aborted after 100 dead cycles.
+%D
+%D By the way, changing the height and depth of \BOX\
+%D \type{\shapebox} results in bad spacing. This means that
+%D for instance linenumbers etc. should be given zero height
+%D and depth before being lapped into the margin. The
+%D previous examples ignore this side effect, but beware!
+
+\newif \ifsomeshapeleft
+\newif \ifreshapingbox
+
+\newbox \shapebox
+\newcount \shapepenalty
+\newdimen \shapekern
+\newskip \shapeskip
+
+\newbox \newshapebox
+\newbox \oldshapebox
+
+\newcount \shapecounter
+
+\newevery \everyshapebox \relax
+
+\def\shapesignal{.12345678pt} % or 12345sp
+
+% todo: in etex lastnode
+
+\def\reshapebox#1%
+ {\doreshapebox
+ {#1}%
+ {\penalty\shapepenalty}%
+ {\kern \shapekern }%
+ {\vskip \shapeskip }}
+
+\newbox\tmpshapebox
+
+\newif\ifreshapingfailed % may save redundant runs
+
+\def\doreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
+ {\global\reshapingfailedfalse
+ \ifzeropt\ht\oldshapebox % \ifdim\ht\oldshapebox=\zeropoint
+ \setbox\newshapebox\normalvbox{}%
+ \else
+ \setbox\newshapebox\normalvbox
+ {\unvcopy\oldshapebox
+ \resetbox\newshapebox
+ \shapecounter\zerocount
+ \doloop{\dodoreshapebox{#1}{#2}{#3}{#4}}}%
+ \setbox\newshapebox\box\tmpshapebox
+ \fi}
+
+\ifx\originalshapebox\undefined \let\originalshapebox\oldshapebox \fi
+
+% %D The old traditional tex variant:
+%
+% \def\insertshapesignal
+% {\normalhbox to \shapesignal{\strut\hss}% plus \strut
+% \prevdepth\strutdp} % never \nointerlineskip
+%
+% \def\restoreshapebox % compensates for the signal
+% {\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}}
+%
+% \def\shapeboxstrut % put this in front if needed !
+% {\vrule\!!width\zeropoint\!!height\ht\shapebox\!!depth\dp\shapebox}
+%
+% \def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
+% {\ifzeropt\lastskip % \ifdim\lastskip=\zeropoint\relax
+% \ifzeropt\lastkern % \ifdim\lastkern=\zeropoint\relax
+% \ifcase\lastpenalty % \ifnum\lastpenalty=\zerocount
+% \setbox\shapebox\lastbox
+% \ifvoid\shapebox
+% \unskip\unpenalty\unkern
+% \else
+% \ifdim\wd\shapebox=\shapesignal\relax
+% \exitloop
+% \else
+% \shapecounter\zerocount
+% \global\setbox\tmpshapebox\normalvbox{#1\unvbox\tmpshapebox}%
+% \fi
+% \fi
+% \else
+% \shapepenalty\lastpenalty
+% \global\setbox\tmpshapebox\normalvbox{#2\unvbox\tmpshapebox}%
+% \unpenalty
+% \fi
+% \else
+% \shapekern\lastkern
+% \global\setbox\tmpshapebox\normalvbox{#3\unvbox\tmpshapebox}%
+% \unkern
+% \fi
+% \else
+% \shapeskip\lastskip
+% \global\setbox\tmpshapebox\normalvbox{#4\unvbox\tmpshapebox}%
+% \unskip
+% \fi
+% \ifnum\shapecounter>100 % can be less
+% \global\reshapingfailedtrue
+% \message{!!forced exit from shapebox!!}%
+% \restoreshapebox
+% \exitloop
+% \else
+% \advance\shapecounter \plusone
+% \fi}
+%
+% But now that the lastnode bugfixes are wide spread we can use:
+%
+% We will turn this into a \MKIV\ variant.
+
+\def\insertshapesignal
+ {\normalhbox to \shapesignal{\strut\hss}% plus \strut
+ \prevdepth\strutdp} % never \nointerlineskip
+
+\def\restoreshapebox % compensates for the signal
+ {\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}}
+
+\def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
+ {\ifnum\lastnodetype=\@@gluenode
+ \shapeskip\lastskip
+ \global\setbox\tmpshapebox\normalvbox{#4\unvbox\tmpshapebox}%
+ \unskip
+ \else\ifnum\lastnodetype=\@@kernnode
+ \shapekern\lastkern
+ \global\setbox\tmpshapebox\normalvbox{#3\unvbox\tmpshapebox}%
+ \unkern
+ \else\ifnum\lastnodetype=\@@penaltynode
+ \shapepenalty\lastpenalty
+ \global\setbox\tmpshapebox\normalvbox{#2\unvbox\tmpshapebox}%
+ \unpenalty
+ \else\ifnum\lastnodetype<\zeropoint
+ \exitloop
+ \else
+ \setbox\shapebox\lastbox
+ \ifvoid\shapebox
+ \else\ifdim\wd\shapebox=\shapesignal\relax
+ \exitloop
+ \else
+ \shapecounter\zerocount
+ \global\setbox\tmpshapebox\normalvbox{#1\unvbox\tmpshapebox}%
+ \fi\fi
+ \fi\fi\fi\fi
+ \ifnum\shapecounter>100 % can be less
+ \global\reshapingfailedtrue
+ \message{!!forced exit from shapebox \the\lastnodetype !!}%
+ \restoreshapebox
+ \exitloop
+ \else
+ \advance\shapecounter \plusone
+ \fi}
+
+\def\beginofshapebox
+ {\setbox\oldshapebox\normalvbox
+ \bgroup
+ \reshapingboxtrue
+ \the\everyshapebox
+ \insertshapesignal}
+
+\def\endofshapebox
+ {\endgraf
+ \egroup}
+
+\let\beginshapebox\beginofshapebox
+\let\endshapebox \endofshapebox
+
+\def\flushshapebox
+ {\bgroup
+ \ifzeropt\ht\newshapebox % \ifdim\ht\newshapebox=\zeropoint
+ \else
+ % make \prevdepth legal
+ % \par before the next \vskip gives far worse results
+ \ifdim\parskip>\zeropoint\vskip\parskip\else\par\fi
+ % and take a look
+ \ifdim\prevdepth=-\thousandpoint
+ \prevdepth\zeropoint
+ \fi
+ \ifdim\prevdepth<\zeropoint\relax
+ % something like a line or a signal or ...
+ \donetrue
+ \else\ifinner
+ % not watertight and not ok
+ \donefalse
+ \else\ifdim\pagegoal=\maxdimen
+ \donetrue
+ \else
+ % give the previous line a normal depth
+ \donetrue
+ {\forgeteverypar\verticalstrut}\nobreak
+ \kern-\struttotal % geen \vskip
+ \kern-\parskip
+ % \vskip-\strutdp
+ \fi\fi\fi
+ \scratchdimen\dp\newshapebox
+ \unvbox\newshapebox
+ % \prevdepth=0pt and \dp\newshapebox depend on last line
+ \kern-\scratchdimen % ??
+ % now \prevdepth=0pt
+ \ifdone
+ \kern\strutdp
+ \prevdepth\strutdp
+ \fi
+ \fi
+ \egroup}
+
+%D In real inner situations we can use:
+%D
+%D \starttyping
+%D \flushinnershapebox
+%D \stoptyping
+%D
+%D This one is used in \type{\framed}.
+
+% The kern fails on for instance:
+%
+% \omlijnd[offset=0pt,hoogte=8mm,uitlijnen={rechts,laho}]{\bfa test}
+
+\def\innerflushshapebox
+ {\ifzeropt\ht\newshapebox \else
+ \unvcopy\newshapebox\relax % unvcopy ! else spacing problem
+ % \kern-\dp\newshapebox\relax
+ \fi}
+
+%D For absolute control, one can use \type{\doreshapebox}
+%D directly. This macro takes four arguments, that take care
+%D of:
+%D
+%D \startitemize[n,packed]
+%D \item \type{\shapebox}
+%D \item \type{\shapepenalty}
+%D \item \type{\shapekern}
+%D \item \type{\shapeskip}
+%D \stopitemize
+
+%D \macros
+%D {shapedhbox}
+%D
+%D When constructing a new box, using the content of \type
+%D {\shapebox}, one can best use \type {\shapedhbox} instead
+%D of \type {\normalhbox}, since it manages the height and depth of
+%D the line.
+
+% \def\shapedhbox
+% {\dowithnextbox
+% {\nextboxht\zeropoint
+% \nextboxdp\zeropoint
+% \flushnextbox}
+% \normalhbox}
+
+\def\shapedhbox % lines with non strutted dimensions have
+ {\expanded{\dowithnextbox % interlineskip so if we want the original
+ {\nextboxht\the\ht\shapebox % spacing, we need to preserve the original
+ \nextboxdp\the\dp\shapebox % height and depth which is definitely
+ \noexpand\flushnextbox}} % needed if we apply struts to the 'new'
+ \normalhbox} % box or do something that changed ist size
+
+%D \macros
+%D {hyphenatedword,
+%D hyphenatedpar,
+%D hyphenatedfile,
+%D dohyphenateword}
+%D
+%D The next one is a tricky one. \PLAIN\ \TEX\ provides
+%D \type{\showhyphens} for showing macros on the terminal. When
+%D preparing a long list of words we decided to show the
+%D hyphens, but had to find out that the \PLAIN\ alternative
+%D can hardly be used and|/|or adapted to typesetting. The next
+%D two macros do the job and a little more. First we define the
+%D (slightly adapted) plain variant:
+
+\def\showhyphens#1%
+ {\begingroup
+ \setbox\scratchbox\vbox
+ {\parfillskip\zerocount
+ \hsize\maxdimen
+ %\tenrm
+ \pretolerance\minusone
+ \tolerance\minusone
+ \hbadness\zerocount
+ \showboxdepth\zerocount
+ \ #1}%
+ \endgroup}
+
+%D The simple command \type{\hyphenatedword} accepts one
+%D argument and gives the hyphenated word. This macro calls for
+%D
+%D \starttyping
+%D \dohyphenateword {n} {pre} {word}
+%D \stoptyping
+%D
+%D The next examples tell more than lots of words:
+%D
+%D \startbuffer
+%D \dohyphenateword{0} {} {dohyphenatedword}
+%D \dohyphenateword{1} {...} {dohyphenatedword}
+%D \dohyphenateword{2} {...} {dohyphenatedword}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Here, \type{\hyphenatedword{dohyphenatedword}} is the
+%D shorter alternative for the first line.
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D These macros are slow but effective and not that hard to
+%D program at all.
+
+\ifx\scantokens\undefined \let\scantokens\firstofoneargument \fi
+
+\def\dohyphenateword#1#2#3%
+ {\bgroup
+ \setbox\scratchbox\normalhbox
+ {\dontcomplain
+ \nopenalties % \widowpenalty \clubpenalty \brokenpenalty \doublehyphendemerits \finalhyphendemerits \adjdemerits
+ \hyphenpenalty \zerocount
+ \exhyphenpenalty\zerocount
+ \setbox0\normalvbox
+ {\hsize\zeropoint
+ \hskip\zeropoint\relax % really needed
+ \ifnum#1<\zeropoint
+ \obeyspaces
+ \obeylines
+ \def\obeyedspace{\hskip\zeropoint\hbox to \onepoint{}\hskip\zeropoint}%
+ \let\obeyedline \obeyedspace
+ \ifcase-#1\or
+ \def\next{#3\relax}\scantokens\expandafter{\next}% relax catches lookahead problem
+ % also ok: \scantokens{#3}% % as in \hyphenatedword{spanish|?|}
+ \or
+ \readfile{#3}\donothing\donothing
+ \else
+ #3%
+ \fi
+ \else
+ #3%
+ \fi}%
+ \ifnum#1>\zerocount
+ \dorecurse{#1}
+ {\setbox2\normalhbox
+ {\splittopskip\openstrutheight
+ \vsplit0 to \baselineskip}}%
+ #2%
+ \fi
+ \doloop
+ {\setbox2\normalhbox
+ {\splittopskip\openstrutheight
+ \vsplit0 to \baselineskip}%
+ \setbox2\normalhbox
+ {\unhbox2
+ \setbox2\lastbox
+ \normalvbox
+ {\unvbox2
+ \setbox2\lastbox
+ \normalhbox{\unhbox2}}}%
+ \ifnum#1<\zeropoint\ifdim\wd2=\onepoint\space\else\box2\allowbreak\fi\else\box2\fi
+ \ifzeropt\ht0 \exitloop\fi}% % \ifdim\ht0=\zeropoint\exitloop\fi}%
+ \removeunwantedspaces}%
+ \ifnum#1>\zerocount
+ \ht\scratchbox\strutht
+ \dp\scratchbox\strutdp
+ \box\scratchbox
+ \else
+ \unhbox\scratchbox
+ \fi
+ \egroup}
+
+\def\hyphenatedword{\dohyphenateword\zerocount\empty}
+\def\hyphenatedpar {\dohyphenateword\minusone \empty}
+\def\hyphenatedfile{\dohyphenateword{-2}\empty}
+
+%D You may want to give the following call a try:
+%D
+%D \starttyping
+%D \hyphenatedpar{\readfile{zapf}{}{}}\endgraf
+%D \stoptyping
+
+%D \macros
+%D {processtokens}
+%D
+%D We fully agree with (most) typographers that inter||letter
+%D spacing is only permitted in fancy titles, we provide a
+%D macro that can be used to do so. Because this is
+%D (definitely and fortunately) no feature of \TEX, we have to
+%D step through the token list ourselves.
+%D
+%D \starttyping
+%D \processtokens {before} {between} {after} {space} {tokens}
+%D \stoptyping
+%D
+%D An example of a call is:
+%D
+%D \startbuffer
+%D \processtokens {[} {+} {]} {\space} {hello world}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This results in:
+%D
+%D \getbuffer
+%D
+%D The list of tokens may contain spaces, while \type{\\},
+%D \type{{}} and \type{\ } are handled as space too.
+
+\def\dodoprocesstokens
+ {\ifx\nextprocessedtoken\lastcharacter
+ \after
+ \let\nextprocessedtoken\relax
+ \else\ifx\nextprocessedtoken\bgroup
+ \def\nextprocessedtoken
+ {\dowithnextbox
+ {\before{\copy\nextbox}% \before can use nextbox several times
+ \let\before\between
+ \doprocesstokens}
+ \hbox\bgroup}%
+ \else
+ \expandafter\if\space\nextprocessedtoken
+ \after\white
+ \let\before\savedbefore
+ \else
+ \before\nextprocessedtoken
+ \let\before\between
+ \fi
+ \let\nextprocessedtoken\doprocesstokens
+ \fi\fi
+ \nextprocessedtoken}
+
+\def\doprocesstokens% the space after = is essential
+ {\afterassignment\dodoprocesstokens\let\nextprocessedtoken= }
+
+\def\processtokens#1#2#3#4#5%
+ {\begingroup
+ \def\lastcharacter{\lastcharacter}%
+ \def\space{ }%
+ \let\\=\space
+ \def\before {#1}%
+ \def\between{#2}%
+ \def\after {#3}%
+ \def\white {#4}%
+ \let\savedbefore\before
+ \doprocesstokens#5\lastcharacter
+ \endgroup}
+
+%D \macros
+%D {doboundtext}
+%D
+%D Sometimes there is not enough room to show the complete
+%D (line of) text. In such a situation we can strip of some
+%D characters by using \type{\doboundtext}. When the text is
+%D wider than the given width, it's split and the third
+%D argument is appended. When the text to be checked is packed
+%D in a command, we'll have to use \type{\expandafter}.
+%D
+%D \starttyping
+%D \doboundtext{a very, probably to long, text}{3cm}{...}
+%D \stoptyping
+%D
+%D When calculating the room needed, we take the width of the
+%D third argument into account, which leads to a bit more
+%D complex macro than needed at first sight.
+
+% \def\dodoboundtext#1%
+% {\setbox0=\normalhbox{\unhcopy0 #1}%
+% \ifdim\wd0>\dimen0
+% \let\dodoboundtext=\gobbleoneargument
+% \else
+% #1\relax
+% \fi}
+%
+% \def\doboundtext#1#2#3%
+% {\normalhbox
+% {\setbox0=\normalhbox{#1}%
+% \dimen0=#2\relax
+% \ifdim\wd0>\dimen0
+% \setbox2=\normalhbox{#3}%
+% \advance\dimen0 by -\wd2
+% \setbox0=\normalhbox{}%
+% \processtokens
+% {\dodoboundtext}
+% {\dodoboundtext}
+% {}
+% {\space}
+% {#1}%
+% \box2
+% \else
+% \box0
+% \fi}}
+
+\def\dodoboundtext#1%
+ {\setbox0\normalhbox{#1}%
+ \advance\scratchdimen -\wd0
+ \ifdim\scratchdimen>\zeropoint\relax#1\fi}%
+
+\def\doboundtext#1#2#3%
+ {\normalhbox
+ {\setbox\scratchbox\normalhbox{#1}%
+ \scratchdimen#2\relax
+ \ifdim\wd\scratchbox>\scratchdimen
+ \setbox\scratchbox\normalhbox{#3}%
+ \advance\scratchdimen -\wd\scratchbox
+ \handletokens#1\with\dodoboundtext
+ \fi
+ \box\scratchbox}}
+
+%D \macros
+%D {limitatetext}
+%D
+%D A bit more beautiful alternative for the previous command is
+%D the next one. This command is more robust because we let
+%D \TEX\ do most of the job. The previous command works better
+%D on text that cannot be hyphenated.
+%D
+%D \starttyping
+%D \limitatetext {text} {width} {sentinel}
+%D \limitatetext {text} {-width} {prelude}
+%D \stoptyping
+%D
+%D When no width is given, the whole text comes available. The
+%D sentinel is optional. This is about the third version.
+
+\ifx\fakecompoundhyphen\undefined \let\fakecompoundhyphen\relax \fi
+\ifx\veryraggedright \undefined \def\veryraggedright{\raggedright} \fi
+
+%D The simple alternative is as follows:
+%D
+%D \starttyping
+%D \unexpanded\def\limitatetext%
+%D {\bgroup % evt \setstrut
+%D \forgetall
+%D \fakecompoundhyphen % dangerous ! ! ! ! ! ! ! ! !
+%D \dowithnextbox\dolimitatetext\normalhbox}
+%D
+%D \def\dolimitatetext#1#2%
+%D {\doifelsenothing{#1}
+%D {\unhbox\nextbox}
+%D {\widowpenalty=0
+%D \clubpenalty=0
+%D \scratchdimen=#1\relax
+%D \ifdim\nextboxwd>\scratchdimen
+%D \setbox\scratchbox=\normalhbox{ #2}%
+%D \advance\scratchdimen by -\wd\scratchbox
+%D \setbox\nextbox=\normalvbox
+%D {\hsize=\scratchdimen
+%D \hfuzz\maxdimen
+%D \veryraggedright
+%D \strut\unhcopy\nextbox}%
+%D \ifdim\nextboxht>\strutht \else
+%D \setbox\scratchbox\null % overfull and not split
+%D \fi
+%D \setbox\nextbox=\normalvbox % if omitted: missing brace reported
+%D {\splittopskip=\openstrutheight
+%D \setbox\nextbox=\vsplit\nextbox to \strutht
+%D \unvbox\nextbox
+%D \setbox\nextbox=\lastbox
+%D \global\setbox1=\normalhbox
+%D {\unhbox\nextbox\unskip\kern\zeropoint\box\scratchbox\unskip}}%
+%D \unhbox1
+%D \else
+%D \unhbox\nextbox
+%D \fi}%
+%D \egroup}
+%D \stoptyping
+%D
+%D The next alternative accepts a negative width. A negative
+%D value crops the beginning. The macro thereby becomes less
+%D readable, which is why we kept the original here too.
+
+\unexpanded\def\limitatetext
+ {\bgroup % evt \setstrut
+ \forgetall % otherwise indentation and so
+ %\def\limitatetext##1##2##3{##1}% \def !
+ \let\limitatetext\firstofthreearguments
+ \fakecompoundhyphen % dangerous ! ! ! ! ! ! ! ! !
+ \dowithnextboxcs\dolimitatetext\normalhbox}
+
+\def\dolimitatetext#1#2%
+ {\doifelsenothing{#1}
+ {\unhbox\nextbox}
+ {\nopenalties
+ \scratchdimen#1\relax
+ \ifdim\scratchdimen<\zeropoint\relax % we'll take the last line
+ \donefalse
+ \scratchdimen-\scratchdimen
+ \else
+ \donetrue
+ \fi
+ \ifdim\nextboxwd>\scratchdimen
+ \setbox\scratchbox\normalhbox{\ifdone\space#2\else#2\space\fi}%
+ \advance\scratchdimen -\wd\scratchbox
+ \setbox0\flushnextbox
+ \setbox\nextbox\normalvbox
+ {\hsize\scratchdimen
+ \hfuzz\maxdimen
+ \veryraggedright
+ \strut
+ \ifdone \else
+ \parfillskip\zeropoint
+ \rightskip\zeropoint
+ \hskip\zeropoint \!!plus 1\!!fill % \hsize
+ \fi
+ \unhcopy0}%
+ \ifdim\nextboxht>\strutht
+ \setbox\nextbox\normalvbox % if omitted: missing brace reported
+ {\splittopskip\openstrutheight
+ \ifdone
+ \setbox\nextbox\vsplit\nextbox to \strutht
+ \else
+ \doloop
+ {\setbox0\vsplit\nextbox to \strutht
+ \ifdim\nextboxht>\strutht \else \exitloop \fi}%
+ \fi
+ \unvbox\nextbox
+ \setbox\nextbox\lastbox
+ \global\setbox1\normalhbox
+ {\ifdone
+ \unhbox\nextbox\unskip\kern\zeropoint\box\scratchbox
+ \else
+ \box\scratchbox\unhbox\nextbox
+ \fi
+ \unskip}}%
+ \unhbox1
+ \else
+ \unhbox0
+ \fi
+ \else
+ \unhbox\nextbox
+ \fi}%
+ \egroup}
+
+%D We can also limit a text with more control:
+%D
+%D \startbuffer
+%D \limitatetext {\input tufte } {2cm,5mm} {\unknown}
+%D \limitatetext {ton en hans} {2cm,5mm} {\unknown}
+%D \limitatetext {ton en hans zijn eikels} {2cm,5mm} {\unknown}
+%D \limitatetext {ton} {2cm,5mm} {\unknown}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D We build this feature on top of the previous macro.
+
+\let\normallimitatetext\limitatetext
+
+\def\speciallimitatetext#1#2#3#4% text left right placeholder
+ {%\dontleavehmode
+ \bgroup
+ %\def\speciallimitatetext##1##2##3##4{##1}% \def !
+ \let\speciallimitatetext\firstoffourarguments
+ \setbox0\normalhbox
+ {\nohyphens
+ \normallimitatetext{#1}{+#2}{}#4%
+ \normallimitatetext{#1}{-#3}{}}%
+ \setbox2\normalhbox
+ {#1}%
+ \ifdim\wd2<\wd0 #1\else\unhbox0\fi
+ \egroup}
+
+\def\limitatetext#1#2#3% \expanded added 2003/01/16
+ {\expanded{\beforesplitstring#2}\at,\to\leftlimit
+ \expanded{\aftersplitstring #2}\at,\to\rightlimit
+ \ifx\rightlimit\empty
+ \normallimitatetext {#1}\leftlimit {#3}%
+ \else
+ \speciallimitatetext{#1}\leftlimit\rightlimit{#3}%
+ \fi}
+
+%D Undocumented bonus (see wiki):
+%D
+%D \starttyping
+%D \limitatefirstline{\input tufte\relax}{10cm}{\unknown}
+%D \stoptyping
+
+\def\limitatefirstline#1#2#3%
+ {\hbox\bgroup\strut
+ \setbox\scratchbox\hbox{\begstrut#1\endstrut}%
+ \ifdim\wd\scratchbox>#2\relax
+ \setbox\scratchbox\hbox{#3}%
+ \hsize#2\relax
+ \advance\hsize-\wd\scratchbox
+ \setbox\scratchbox\vbox{\forgetall\veryraggedright#1}%
+ \setbox\scratchbox\vsplit\scratchbox to \lineheight
+ \vbox
+ {\unvbox\scratchbox
+ \global\setbox\plusone\lastbox
+ \global\setbox\plusone\hbox{\strut\unhbox\plusone}%
+ \hbox % to #2
+ {\ifx\clip\undefined
+ \box\plusone
+ \else\ifdim\wd\plusone>\hsize
+ \lower\strutdepth\hbox{\clip[\c!width=\hsize,\c!height=\lineheight]{\hbox{\raise\strutdepth\box\plusone}}}%
+ \else
+ \box\plusone
+ \fi\fi
+ \removeunwantedspaces#3}}% \removeunwantedspaces\hss#3}}%
+ \else
+ #1%
+ \fi
+ \egroup}
+
+%D \macros
+%D {processisolatedwords,
+%D betweenisolatedwords,nothingbetweenisolatedwords}
+%D
+%D References are often made up of one word or a combination
+%D of tightly connected words. The typeset text {\bf
+%D chapter~5} is for instance the results of the character
+%D sequence:
+%D
+%D \starttyping
+%D The typeset text \in{chapter}[texniques] is for instance
+%D \stoptyping
+%D
+%D When such words are made active in interactive texts, the
+%D combination cannot longer be hyphenated. Normally this is no
+%D problem, because \TEX\ tries to prevent hyphenation as best
+%D as can.
+%D
+%D Sometimes however we need a few more words to make things
+%D clear, like when we want to refer to {\bf \TEX\ by Topic}.
+%D The macros that are responsible for typesetting hyperlinks,
+%D take care of such sub||sentences by breaking them up in
+%D words. Long ago we processed words using the space as a
+%D separator, but the more advanced our interactive text became,
+%D the more we needed a robust solution. Well, here it is and
+%D it called as:
+%D
+%D \starttyping
+%D \processisolatedwords{some words}\someaction
+%D \stoptyping
+%D
+%D The second argument \type{someactions} handles the
+%D individual words, like in:
+%D
+%D \startbuffer
+%D \processisolatedwords{some more words} \ruledhbox \par
+%D \processisolatedwords{and some $x + y = z$ math} \ruledhbox \par
+%D \processisolatedwords{and a \normalhbox{$x + y = z$}} \ruledhbox \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D which let the words turn up as:
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D The macro has been made a bit more clever than needed at
+%D first sight. This is due to the fact that we don't want to
+%D generate more overhead in terms of interactive commands than
+%D needed.
+%D
+%D \startbuffer
+%D \processisolatedwords{see this \ruledhskip1em} \ruledhbox
+%D \processisolatedwords{and \ruledhskip1em this one} \ruledhbox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D becomes:
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D Single word arguments are treated without further
+%D processing. This was needed because this command is used in
+%D the \type{\goto} command, to which we sometimes pass very
+%D strange and|/|or complicated arguments or simply boxes
+%D whose dimensions are to be left intact.
+%D
+%D First we build a \type{\normalhbox}. This enables us to save the
+%D last skip. Next we fill a \type{\normalvbox} without hyphenating
+%D words. After we've tested if there is more than one word, we
+%D start processing the individual lines (words). We need some
+%D splitting, packing and unpacking to get the spacing and
+%D dimensions right.
+%D
+%D Normally the isolated words are separated by space, but
+%D one can overrule this separator by changing the next macros.
+%D
+%D When needed, spacing can be suppressed by \type
+%D {\nothingbetweenisolatedwords}.
+
+\newif\ifisolatedwords % public, e.g. used in core-ref
+
+\def\betweenisolatedwords
+ {\hskip\currentspaceskip}
+
+%D In order to prevent problems with nested isolated words, we
+%D do process them, but only split at the outermost level.
+
+\newskip\isolatedlastskip
+
+\chardef\isolatedwordsmode=0 % no nesting
+
+\def\processisolatedwords#1#2% todo: vbox ipv hbox ivm afbreken!
+ {\bgroup % todo: doloop
+ \fakecompoundhyphen
+ \dontcomplain
+ \forgetall
+ \nopenalties
+ \ifcase\isolatedwordsmode
+ \def\processisolatedwords##1##2{##2{##1}}% we split only once
+ \fi
+ \global\let\localbetweenisolatedwords\betweenisolatedwords
+ \setbox0\normalhbox % we default to spaces, but from inside out
+ {\normallanguage\minusone % needed for mkiv
+ \ignorespaces#1% \localbetweenisolatedwords can be overruled
+ \global\isolatedlastskip\lastskip}%
+ \setbox2\normalvbox
+ {%\hyphenpenalty10000 % this one fails in \url breaking,
+ \lefthyphenmin\maxcard % but this trick works ok, due to them
+ \righthyphenmin\maxcard % total>63, when no hyphenation is done
+ \hsize\zeropoint
+ \unhcopy0}% == #1
+ \ifdim\ht0=\ht2
+ \isolatedwordsfalse
+ #2{\unhbox0}% == #2{#1} % was \unhcopy0
+ \else
+ \isolatedwordstrue
+ \setbox0\normalhbox
+ {\ignorespaces
+ \loop
+ \setbox4\normalhbox
+ {\splittopskip\openstrutheight
+ \vsplit2 to \baselineskip}%
+ \normalhbox
+ {\unhbox4\unskip % recently added
+ \setbox4\lastbox
+ \normalvbox % outer \normalhbox needed
+ {\unvbox4 % for nested use
+ \setbox4\lastbox
+ \normalhbox{#2{\normalhbox
+ {\unhbox4
+ \unskip\unpenalty % remove end of line stuff
+ \global\dimen1\lastkern}}}}}%
+ \ifdim\ht2>\zeropoint\relax
+ \ifdim\dimen1=\compoundbreakpoint
+ \allowbreak
+ \else
+ \localbetweenisolatedwords
+ \fi
+ \repeat
+ \unskip}%
+ \unhbox0\unskip
+ \ifzeropt\isolatedlastskip\else % added % \ifdim\isolatedlastskip=\zeropoint\else % added
+ \hskip\isolatedlastskip
+ \fi
+ \fi
+ \egroup}
+
+%D One can use the next macro to change the intersplit
+%D material. An example can be found in the \type {\url}
+%D macro. The innermost setting is used. In the url case, it
+%D means that either very small spaces are used or no spaces
+%D at all. So, the innermost settings are used, while the
+%D outermost split takes place.
+
+\def\setbetweenisolatedwords#1%
+ {\gdef\localbetweenisolatedwords{#1}}
+
+%D \macros
+%D {sbox}
+%D
+%D This is a rather strange command. It grabs some box content
+%D and and limits the size to the height and depth of a
+%D \type{\strut}. The resulting bottom||alligned box can be used
+%D aside other ones, without disturbing the normal baseline
+%D distance.
+%D
+%D \startbuffer
+%D \ruledhbox to .5\hsize{\sbox{eerste\par tweede \par derde}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Shows up as:
+%D
+%D \startvoorbeeld
+%D \vskip3\baselineskip
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D Before displaying the result we added some skip, otherwise
+%D the first two lines would have ended up in the text. This
+%D macro can be useful when building complicated menus, headers
+%D and footers and|/|or margin material.
+
+\def\sbox% in handleiding, voorbeeld \inleft{xx} \extern..
+ {\normalvbox\bgroup % new ! ! !
+ \dowithnextbox
+ {\setbox\scratchbox\normalhbox
+ {\strut
+ \nextboxdp\zeropoint
+ \lower\strutdepth\flushnextbox}%
+ \dp\scratchbox\strutdepth
+ \ht\scratchbox\strutheight
+ \box\scratchbox
+ \egroup}%
+ \normalvbox}
+
+%D \macros
+%D {struttedbox}
+%D
+%D This boxing macro limits the height and depth to those of
+%D a strut.
+
+\def\struttedbox
+ {\normalhbox\bgroup % new ! ! !
+ \dowithnextbox
+ {\nextboxdp\strutdepth
+ \nextboxht\strutheight
+ \flushnextbox
+ \egroup}%
+ \normalhbox}
+
+%D \macros
+%D {topskippedbox}
+%D
+%D This macro compensates the difference between the topskip
+%D and strutheight. Watch how we preserve the depth when it
+%D equals strutdepth.
+
+\def\topskippedbox
+ {\normalhbox\bgroup
+ \dowithnextbox
+ {\edef\next
+ {\ifdim\strutdepth=\nextboxdp\nextboxdp\the\nextboxdp\fi}%
+ \lower\topskip\normalhbox{\raise\strutheight\flushnextbox}%
+ \next
+ \egroup}%
+ \normalhbox}
+
+%D \macros
+%D {centeredbox, centerednextbox}
+%D
+%D Here is another strange one. This one offers a sort of overlay
+%D with positive or negative offsets. This command can be used
+%D in well defined areas where no offset options are available.
+%D We first used it when building a button inside the margin
+%D footer, where the button should have a horizontal offset and
+%D should be centered with respect to the surrounding box. The
+%D last of the three examples we show below says:
+%D
+%D \starttyping
+%D \vsize=3cm
+%D \hsize=3cm
+%D \ruledvbox to \vsize
+%D {\centeredbox height .5cm width -1cm
+%D {\vrule width \hsize height \vsize}}}
+%D \stoptyping
+%D
+%D Here the \type{\ruledvbox} just shows the surrounding box
+%D and \type{\vrule} is used to show the centered box.
+%D
+%D \def\AnExample#1#2%
+%D {\vsize=3cm
+%D \hsize=3cm
+%D \ruledvbox to \vsize
+%D {\centeredbox height #1 width #2
+%D {\color[green]{\vrule width \hsize height \vsize}}}}
+%D
+%D \startlinecorrection
+%D \startcombination[3*1]
+%D {\AnExample {-1cm} {.5cm}} {}
+%D {\AnExample {.5cm} {-1cm}} {}
+%D {\AnExample {-1cm} {-.5cm}} {}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D This command takes two optional arguments: \type{width} and
+%D \type{height}. Observing readers can see that we use \TEX's
+%D own scanner for grabbing these arguments: \type{#1#} reads
+%D everyting till the next brace and passes it to both rules.
+%D The setting of the box dimensions at the end is needed for
+%D special cases. The dimensions of the surrounding box are kept
+%D intact. This commands handles positive and negative
+%D dimensions (which is why we need two boxes with rules).
+
+\def\centeredbox#1#% height +/-dimen width +/-dimen
+ {\bgroup
+ \setbox0\normalvbox to \vsize
+ \bgroup
+ \dontcomplain
+ \forgetall
+ \setbox0\normalhbox{\vrule\!!width \zeropoint#1}%
+ \setbox2\normalvbox{\hrule\!!height\zeropoint#1}%
+ \advance\vsize \ht2
+ \advance\hsize \wd0
+ \normalvbox to \vsize
+ \bgroup
+ \vskip-\ht2
+ \vss
+ \normalhbox to \hsize
+ \bgroup
+ \dowithnextbox
+ {\hskip-\wd0
+ \hss
+ \flushnextbox
+ \hss
+ \egroup
+ \vss
+ \egroup
+ \egroup
+ \wd0\hsize
+ \ht0\vsize
+ \box0
+ \egroup}
+ \normalhbox}
+
+%D For those who don't want to deal with \type {\hsize}
+%D and \type {\vsize}, we have:
+%D
+%D \starttyping
+%D \centerednextbox width 2bp height 2bp
+%D {\framed[width=100bp,height=100bp]{}}
+%D \stoptyping
+%D
+%D Do you see what we call this one \type {next}?
+
+\def\centerednextbox#1#%
+ {\bgroup
+ \dowithnextbox
+ {\hsize\nextboxwd
+ \vsize\nextboxht
+ \centeredbox#1{\flushnextbox}%
+ \egroup}
+ \normalhbox}
+
+%D \macros
+%D {centerbox}
+%D
+%D Centering on the available space is done by:
+%D
+%D \starttyping
+%D \centerbox <optional specs> {content}
+%D \stoptyping
+%D
+%D When omitted, the current \type {\hsize} and \type
+%D {\vsize} are used. Local dimensions are supported.
+
+\long\def\centerbox#1#% optional height +/-dimen width +/-dimen
+ {\bgroup
+ \dowithnextbox
+ {\setlocalhsize
+ \setbox0\normalhbox{\vrule\!!width \zeropoint#1}%
+ \setbox2\normalvbox{\hrule\!!height\zeropoint#1}%
+ \ifzeropt\wd0\else\hsize\wd0\fi % \hsize\ifdim\wd0=\zeropoint\hsize\else\wd0\fi
+ \ifzeropt\ht2\else\vsize\ht2\fi % \vsize\ifdim\ht2=\zeropoint\vsize\else\ht2\fi
+ \normalvbox to \vsize{\vss\normalhbox to \hsize{\hss\flushnextbox\hss}\vss}%
+ \egroup}%
+ \normalhbox}
+
+%D \macros
+%D {setrigidcolumnhsize,rigidcolumnbalance,rigidcolumnlines}
+%D
+%D These macros are copied from the \TEX book, page~397, and
+%D extended by a macro that sets the \type{\hsize}.
+%D
+%D \starttyping
+%D \setrigidcolumnhsize {total width} {distance} {n}
+%D \rigidcolumnbalance {box}
+%D \stoptyping
+%D
+%D Both these macros are for instance used in typesetting
+%D footnotes.
+%D
+%D Men kan het proces van breken enigzins beinvloeden met de
+%D volgende twee switches:
+
+\newif\ifalignrigidcolumns
+\newif\ifstretchrigidcolumns
+\newif\iftightrigidcolumns % if true: just a vbox, no depth/noflines/gridsnap corrrections
+
+%D De eerste switch bepaald het uitlijnen, de tweede rekt de
+%D individuele kolommen op naar \type{\vsize}.
+
+\def\setrigidcolumnhsize#1#2#3% todo: \dimexpr
+ {\xdef\savedrigidhsize{\the\hsize}%
+ \hsize#1\relax
+ \global\chardef\rigidcolumns#3\relax
+ \scratchdimen -#2\relax
+ \multiply\scratchdimen #3\relax
+ \advance\scratchdimen #2\relax
+ \advance\hsize \scratchdimen
+ \divide\hsize #3\relax}
+
+% ==
+%
+% \def\setrigidcolumnhsize#1#2#3%
+% {\xdef\savedrigidhsize{\the\hsize}%
+% \global\chardef\rigidcolumns#3\relax
+% \hsize=\dimexpr(#1-\numexpr#3-1\relax\dimexpr#2\relax)/#3\relax}
+
+\newbox\rigidcolumnbox
+
+\let\rigidcolumnlines\!!zerocount
+
+\def\rigidcolumnbalance#1%
+ {\ifnum\rigidcolumns=1 % tzt ook h/d correctie
+ \ifinner\ifhmode\box\else\unvbox\fi\else\unvbox\fi#1\relax
+ \else
+ \normalvbox
+ {\forgetall
+ \nopenalties
+ \dontcomplain
+ \setbox\rigidcolumnbox\normalvbox
+ {\line{}\goodbreak\unvbox#1\removebottomthings}%
+ \splittopskip\openstrutheight
+ \setbox\scratchbox\vsplit\rigidcolumnbox to \zeropoint
+ \ifcase\rigidcolumnlines\relax
+ % \iffalse
+ % % maybe some day an option
+ % \scratchskip\ht\rigidcolumnbox
+ % \advance\scratchskip\dp\rigidcolumnbox
+ % \getnoflines\scratchskip
+ % \ifodd\noflines
+ % \advance\noflines\plusone
+ % \fi
+ % \divide\noflines\rigidcolumns
+ %\else
+ \scratchdimen\ht\rigidcolumnbox
+ \divide\scratchdimen \rigidcolumns
+ \getnoflines\scratchdimen
+ %\fi
+ \else
+ \noflines\rigidcolumnlines % to be sure
+ \fi
+ \scratchdimen\noflines\lineheight
+ % new: we now loop so that we don't loose content
+ % since in practice we also use this macro for
+ % funny lineheights and border cases
+ \setbox0=\box\rigidcolumnbox
+ \doloop
+ {\setbox\rigidcolumnbox=\copy0
+ \setbox\scratchbox\normalhbox to \savedrigidhsize
+ {\dorecurse\rigidcolumns
+ {\setbox\scratchbox\vsplit\rigidcolumnbox to \scratchdimen
+ \dp\scratchbox\openstrutdepth
+ \setbox\scratchbox\normalvtop
+ \ifalignrigidcolumns to
+ \ifstretchrigidcolumns\vsize\else\scratchdimen\fi
+ \fi
+ {\unvbox\scratchbox}%
+ \wd\scratchbox\hsize
+ \box\scratchbox
+ \hfill}%
+ \hfillneg}%
+ \ifvoid\rigidcolumnbox\exitloop\else\advance\scratchdimen\lineheight\fi}%
+ \iftightrigidcolumns
+ \setbox\scratchbox\normalhbox{\raise\dp\scratchbox\box\scratchbox}%
+ \else
+ \advance\scratchdimen -\openstrutdepth
+ \setbox\scratchbox\normalhbox{\raise\scratchdimen\box\scratchbox}%
+ \dp\scratchbox\openstrutdepth
+ \ht\scratchbox\scratchdimen
+ \fi
+ \box\scratchbox}%
+ \fi}
+
+%D \macros
+%D {startvboxtohbox,stopvboxtohbox,convertvboxtohbox}
+%D
+%D Here is another of Knuth's dirty tricks, as presented on
+%D pages 398 and 399 of the \TEX book. These macros can be used
+%D like:
+%D
+%D \starttyping
+%D \normalvbox
+%D \bgroup
+%D \startvboxtohbox ... \stopvboxtohbox
+%D \startvboxtohbox ... \stopvboxtohbox
+%D \startvboxtohbox ... \stopvboxtohbox
+%D \egroup
+%D
+%D \normalvbox
+%D \bgroup
+%D \convertvboxtohbox
+%D \egroup
+%D \stoptyping
+%D
+%D These macros are used in reformatting footnotes, so they do
+%D what they're meant for.
+
+\def\setvboxtohbox
+ {\bgroup
+ \ifdim\baselineskip<16pt \relax
+ \scratchdimen\baselineskip
+ \multiply\scratchdimen 1024
+ \else
+ \message{cropping \baselineskip to 16pt}%
+ \scratchdimen\maxdimen
+ \fi
+ \divide\scratchdimen \hsize
+ \multiply\scratchdimen 64
+ \xdef\normalvboxtohboxfactor{\withoutpt\the\scratchdimen}%
+ \egroup}
+
+\def\startvboxtohbox
+ {\bgroup
+ \setvboxtohbox
+ \setbox\scratchbox\normalhbox\bgroup}
+
+\def\stopvboxtohbox
+ {\egroup
+ \dp\scratchbox\zeropoint
+ \ht\scratchbox\normalvboxtohboxfactor\wd\scratchbox
+ \box\scratchbox
+ \egroup}
+
+% % to be done: start halfway a line combined with one line
+% % extra to start with (skip) and one line less than counted.
+%
+% \def\stopvboxtohbox%
+% {\egroup
+% \setbox2=\normalvbox
+% {\forgetall\unhcopy0\par\xdef\globalvhlines{\the\prevgraf}}%
+% \setbox2=\normalvbox
+% {\unvbox2
+% \setbox2=\lastbox
+% \setbox2=\normalhbox{\unhbox2}%
+% \xdef\globalvhwidth{\the\wd2}}%
+% \decrement\globalvhlines
+% \dimen0=\globalvhwidth
+% \dimen0=\normalvboxtohboxfactor\dimen0
+% \advance\dimen0 by \globalvhlines\lineheight
+% \dp0=\zeropoint
+% \ht0=\dimen0
+% %\writestatus{guessed size}
+% % {w:\the\wd0\space\space
+% % b:\the\baselineskip\space
+% % l:\globalvhlines\space
+% % e:\globalvhwidth\space
+% % h:\the\dimen0}%
+% \box0
+% \egroup}
+
+% todo: \scratchbox
+
+\def\convertvboxtohbox
+ {\setvboxtohbox
+ \makehboxofhboxes
+ \setbox0\normalhbox{\unhbox0 \removehboxes}%
+ \noindent\unhbox0\par}
+
+\def\makehboxofhboxes
+ {\setbox0\normalhbox{}%
+ \loop % \doloop { .. \exitloop .. }
+ \setbox2\lastbox
+ \ifhbox2
+ \setbox0\normalhbox{\box2\unhbox0}%
+ \repeat}
+
+% \def\makehboxofhboxes
+% {\setbox0\normalhbox{}%
+% \doloop % \doloop { .. \exitloop .. }
+% {% \dorecurse{3}{\unskip\unpenalty}% get rid of ... (better do this in a shapeloop)
+% \setbox2\lastbox
+% \ifhbox2
+% \setbox0\normalhbox{\box2\unhbox0}%
+% \else
+% \exitloop
+% \fi}}
+
+% \def\flushboxesonly % feed this into \makehboxofhboxes
+% {\dowithnextbox
+% {\beginofshapebox
+% \unvbox\nextbox
+% \endofshapebox
+% \doreshapebox{\box\shapebox}{}{}{}% get rid of penalties etc
+% \innerflushshapebox}
+% \vbox}
+
+\def\removehboxes
+ {\setbox0\lastbox
+ \ifhbox0
+ {\removehboxes}\unhbox0
+ \fi}
+
+%D \macros
+%D {unhhbox}
+%D
+%D The next macro is used in typesetting inline headings.
+%D Let's first look at the macro and then show an example.
+
+\newbox \unhhedbox
+\newbox \hhbox
+\newdimen \lasthhboxwidth
+\newskip \hhboxindent
+
+\def\unhhbox#1\with#2%
+ {\bgroup
+ \nopenalties
+ \dontcomplain
+ \forgetall
+ \setbox\unhhedbox\normalvbox{\hskip\hhboxindent\strut\unhbox#1}% => \hsize
+ \doloop
+ {\setbox\hhbox\vsplit\unhhedbox to \lineheight
+ \ifvoid\unhhedbox
+ \setbox\hhbox\normalhbox{\strut\normalhboxofvbox\hhbox}%
+ \fi
+ \ht\hhbox\strutht
+ \dp\hhbox\strutdp
+ \ifzeropt\hhboxindent\else % \ifdim\hhboxindent=\zeropoint\else
+ \setbox\hhbox\normalhbox{\hskip-\hhboxindent\box\hhbox}%
+ \hhboxindent\zeropoint
+ \fi
+ \global\lasthhboxwidth\wd\hhbox
+ #2\relax
+ \ifvoid\unhhedbox
+ \exitloop
+ \else
+ \hskip\zeropoint \!!plus \zeropoint
+ \fi}%
+ \egroup}
+
+\def\dohboxofvbox
+ {\setbox0\normalvbox{\unvbox\scratchcounter\global\setbox1\lastbox}%
+ \unhbox1
+ \egroup}
+
+\def\normalhboxofvbox
+ {\bgroup
+ \afterassignment\dohboxofvbox
+ \scratchcounter=}
+
+%D This macro can be used to break a paragraph apart and treat
+%D each line seperately, for instance, making it clickable. The
+%D main complication is that we want to be able to continue the
+%D paragraph, something that's needed in the in line section
+%D headers.
+%D
+%D \startbuffer
+%D \setbox0=\normalhbox{\input tufte \relax}
+%D \setbox2=\normalhbox{\input knuth \relax}
+%D \unhhbox0\with{\ruledhbox{\box\hhbox}}
+%D \hskip1em plus 1em minus 1em
+%D \hhboxindent=\lasthhboxwidth
+%D \advance\hhboxindent by \lastskip
+%D \unhhbox2\with{\ruledhbox{\box\hhbox}}
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D This piece of text was typeset by saying:
+%D
+%D \typebuffer
+%D
+%D Not that nice a definition, but effective. Note the stretch
+%D we've build in the line that connects the two paragraphs.
+
+%D \macros
+%D {doifcontent}
+%D
+%D When processing depends on the availability of content, one
+%D can give the next macro a try.
+%D
+%D \starttyping
+%D \doifcontent{pre content}{post content}{no content}\somebox
+%D \stoptyping
+%D
+%D Where \type{\somebox} is either a \type{\normalhbox} or
+%D \type{\normalvbox}. If the dimension of this box suggest some
+%D content, the resulting box is unboxed and surrounded by the
+%D first two arguments, else the third arguments is executed.
+
+\unexpanded\def\doifcontent#1#2#3%
+ {\dowithnextbox
+ {\ifhbox\nextbox
+ \ifdim\nextboxwd>\zeropoint
+ #1\unhbox\nextbox#2\relax
+ \else
+ #3\relax
+ \fi
+ \else
+ \ifdim\nextboxht>\zeropoint
+ #1\unvbox\nextbox#2\relax
+ \else
+ #3\relax
+ \fi
+ \fi}}
+
+%D So when we say:
+%D
+%D \startbuffer
+%D \doifcontent{[}{]}{}\normalhbox{content sensitive typesetting}
+%D
+%D \doifcontent{}{\page}{}\normalvbox{content sensitive typesetting}
+%D
+%D \doifcontent{}{}{\message{Didn't you forget something?}}\normalhbox{}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D We get:
+%D
+%D \getbuffer
+%D
+%D Where the last call of course does not show up in this
+%D document, but definitely generates a confusing message.
+
+%D \macros
+%D {processboxes}
+%D
+%D The next macro gobble boxes and is for instance used for
+%D overlays. First we show the general handler.
+
+\newbox\processbox
+
+\def\processboxes#1%
+ {\bgroup
+ \def\doprocessbox{#1}% #1 can be redefined halfway
+ \resetbox\processbox
+ \afterassignment\dogetprocessbox\let\next=}
+
+\def\endprocessboxes
+ {\ifhmode\unskip\fi
+ \box\processbox
+ \next
+ \egroup}
+
+\def\dogetprocessbox
+ {\ifx\next\bgroup
+ \expandafter\dodogetprocessbox
+ \else
+ \expandafter\endprocessboxes
+ \fi}
+
+\def\dodogetprocessbox
+ {\dowithnextbox
+ {\ifhmode\unskip\fi\doprocessbox % takes \nextbox makes \processbox
+ \afterassignment\dogetprocessbox\let\next=}
+ \normalhbox\bgroup}
+
+%D \macros
+%D {startoverlay}
+%D
+%D We can overlay boxes by saying:
+%D
+%D \startbuffer
+%D \startoverlay
+%D {\framed{hans}}
+%D {\framed[width=3cm]{ton}}
+%D {\framed[height=2cm]{oeps}}
+%D \stopoverlay
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D shows up as:
+%D
+%D \leavevmode\getbuffer
+
+% \def\dooverlaybox%
+% {\ifhmode\unskip\fi
+% \ifdim\nextboxht>\ht\processbox
+% \setbox\processbox\normalvbox to \nextboxht
+% {\vss\box\processbox\vss}%
+% \else
+% \setbox\nextbox\normalvbox to \ht\processbox
+% {\vss\flushnextbox\vss}%
+% \fi
+% \scratchdimen=\wd
+% \ifdim\nextboxwd>\wd\processbox
+% \nextbox
+% \else
+% \processbox
+% \fi
+% \setbox\processbox=\normalhbox to \scratchdimen
+% {\normalhbox to \scratchdimen{\hss\box\processbox\hss}%
+% \hskip-\scratchdimen
+% \normalhbox to \scratchdimen{\hss\flushnextbox\hss}}}
+%
+% \def\startoverlay%
+% {\bgroup
+% \let\stopoverlay\egroup
+% \processboxes\dooverlaybox}
+
+\def\dooverlaybox
+ {\ifhmode\unskip\fi
+ \scratchdimen\dp
+ \ifdim\nextboxdp>\dp\processbox
+ \nextbox
+ \else
+ \processbox
+ \fi
+ \ifdim\nextboxht>\ht\processbox
+ \setbox\processbox\normalvbox to \nextboxht
+ {\dp\processbox\zeropoint\vss\box\processbox\vss}%
+ \else
+ \setbox\nextbox\normalvbox to \ht\processbox
+ {\nextboxdp\zeropoint\vss\flushnextbox\vss}%
+ \fi
+ \nextboxdp\scratchdimen
+ \dp\processbox\scratchdimen
+ \scratchdimen\wd
+ \ifdim\nextboxwd>\wd\processbox
+ \nextbox
+ \else
+ \processbox
+ \fi
+ \setbox\processbox\normalhbox to \scratchdimen
+ {\normalhbox to \scratchdimen{\hss\box\processbox\hss}%
+ \hskip-\scratchdimen
+ \normalhbox to \scratchdimen{\hss\flushnextbox\hss}}}
+
+\unexpanded\def\startoverlay
+ {\bgroup
+ \let\stopoverlay\egroup
+ \processboxes\dooverlaybox}
+
+\let\stopoverlay\relax
+
+% %D \macros
+% %D {starthspread}
+% %D
+% %D In a similar way we can build a horizontal box, spread
+% %D over the available width.
+% %D
+% %D \startbuffer
+% %D \starthspread
+% %D {hans}
+% %D {ton}
+% %D {oeps}
+% %D \stophspread
+% %D
+% %D \stopbuffer
+% %D
+% %D \typebuffer
+% %D
+% %D shows up as:
+% %D
+% %D \leavevmode\getbuffer
+%
+% \def\dohspread
+% {\flushnextbox
+% \def\dohspread{\hfil\flushnextbox}}
+%
+% \def\starthspread
+% {\normalhbox to \hsize \bgroup
+% \let\stophspread\egroup
+% \processboxes\dohspread}
+
+%D \macros
+%D {fakebox}
+%D
+%D The next macro is a rather silly one, but saves space.
+%D
+%D \starttyping
+%D \normalhbox{\fakebox0}
+%D \stoptyping
+%D
+%D returns an empty box with the dimensions of the box
+%D specified, here being zero.
+
+\def\dofakebox
+ {\setbox\scratchbox\null
+ \wd\scratchbox\wd\scratchcounter
+ \ht\scratchbox\ht\scratchcounter
+ \dp\scratchbox\dp\scratchcounter
+ \ifhbox\scratchcounter\normalhbox\else\normalvbox\fi{\box\scratchbox}%
+ \egroup}
+
+\def\fakebox
+ {\bgroup
+ \afterassignment\dofakebox\scratchcounter}
+
+%D \macros
+%D {lbox,rbox,cbox,tbox,bbox}
+%D
+%D Here are some convenient alternative box types:
+%D
+%D \starttyping
+%D \lbox{text ...}
+%D \cbox{text ...}
+%D \rbox{text ...}
+%D \stoptyping
+%D
+%D Are similar to \type {\normalvbox}, which means that they also
+%D accept something like \type{to 3cm}, but align to the left,
+%D middle and right. These box types can be used to typeset
+%D paragraphs.
+
+\def\lbox{\makelrcbox\normalvbox\raggedleft}
+\def\cbox{\makelrcbox\normalvbox\raggedcenter}
+\def\rbox{\makelrcbox\normalvbox\raggedright}
+
+\def\ltop{\makelrcbox\normalvtop\raggedleft}
+\def\ctop{\makelrcbox\normalvtop\raggedcenter}
+\def\rtop{\makelrcbox\normalvtop\raggedright}
+
+\def\makelrcbox#1#2#3#%
+ {#1#3\bgroup \forgetall \let\\=\endgraf #2\let\next=}
+
+%D The alternatives \type {\tbox} and \type {\bbox} can be used
+%D to properly align boxes, like in:
+%D
+%D \setupexternalfigures[directory={../sample}]
+%D \startbuffer
+%D \starttable[|||]
+%D \HL
+%D \VL \tbox{\externalfigure[cow][height=3cm,frame=on]} \VL top aligned \VL\SR
+%D \HL
+%D \VL \bbox{\externalfigure[cow][height=3cm,frame=on]} \VL bottom aligned \VL\SR
+%D \HL
+%D \stoptable
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D The positioning depends on the strut settings:
+%D
+%D \getbuffer
+
+\def\tbox{\tbbox\ht\dp}
+\def\bbox{\tbbox\dp\ht}
+
+\def\tbbox#1#2%
+ {\normalhbox\bgroup
+ \dowithnextbox
+ {\scratchdimen\nextboxht
+ \advance\scratchdimen\nextboxdp
+ \advance\scratchdimen-#1\strutbox
+ #1\nextbox#1\strutbox
+ #2\nextbox\scratchdimen
+ \setbox\nextbox\normalhbox
+ {\lower\nextboxdp\flushnextbox}%
+ #1\nextbox#1\strutbox
+ #2\nextbox\scratchdimen
+ \flushnextbox
+ \egroup}
+ \normalhbox}
+
+%D \macros
+%D {lhbox,mhbox,rhbox}
+%D
+%D A few more boxes.
+
+\def\dodolhbox{\normalhbox to \hsize{\flushnextbox\hss }}
+\def\dodomhbox{\normalhbox to \hsize{\hss\flushnextbox\hss}}
+\def\dodorhbox{\normalhbox to \hsize{\hss\flushnextbox }}
+
+\def\lhbox{\dowithnextboxcs\dodolhbox\normalhbox}
+\def\mhbox{\dowithnextboxcs\dodomhbox\normalhbox}
+\def\rhbox{\dowithnextboxcs\dodorhbox\normalhbox}
+
+\let\lefthbox \lhbox
+\let\midhbox \mhbox
+\let\righthbox\rhbox
+
+%D \macros
+%D {boxofsize}
+%D
+%D Sometimes we need to construct a box with a height or
+%D width made up of several dimensions. Instead of cumbersome
+%D additions, we can use:
+%D
+%D \starttyping
+%D \boxofsize \normalvbox 10cm 3cm -5cm {the text to be typeset}
+%D \stoptyping
+%D
+%D This example demonstrates that one can use positive and
+%D negative values. Dimension registers are also accepted.
+
+\newdimen\sizeofbox
+
+\def\boxofsize#1%
+ {\bgroup
+ \sizeofbox\zeropoint
+ \scratchdimen\zeropoint
+ \def\docommand
+ {\advance\sizeofbox\scratchdimen
+ \futurelet\next\dodocommand}%
+ \def\dodocommand
+ {\ifx\next\bgroup
+ \expanded{\egroup#1 to \the\sizeofbox}%
+ \else
+ \@EA\afterassignment\@EA\docommand\@EA\scratchdimen
+ \fi}%
+ \docommand}
+
+%D Some new, still undocumented features:
+
+% limitatetext -> beter {text} als laatste !!
+%
+% \limitvbox
+% \limithbox
+
+\def\limitatelines#1#2% size sentinel
+ {\dowithnextbox
+ {\dimen0=#1\hsize
+ \ifdim\nextboxwd>\dimen0
+ \setbox\nextbox\normalhbox
+ {\advance\dimen0 -.1\hsize
+ \limitatetext{\unhbox\nextbox}{\dimen0}{\nobreak#2}}%
+ \fi
+ \unhbox\nextbox}
+ \normalhbox}
+
+\def\fittoptobaselinegrid % weg hier
+ {\dowithnextbox
+ {\bgroup
+ \par
+ \dimen0\nextboxht
+ \nextboxht\strutht
+ \nextboxdp\strutdp
+ \normalhbox{\flushnextbox}
+ \prevdepth\strutdp
+ \doloop
+ {\advance\dimen0 -\lineheight
+ \ifdim\dimen0<\zeropoint
+ \exitloop
+ \else
+ \nobreak
+ \normalhbox{\strut}
+ \fi}
+ \egroup}
+ \normalvbox}
+
+%D Some more undocumented macros (used in m-chart).
+
+\newif\iftraceboxplacement % \traceboxplacementtrue
+
+\newbox\fakedboxcursor
+
+\setbox\fakedboxcursor\normalhbox
+ {\vrule\!!width\zeropoint\!!height\zeropoint\!!depth\zeropoint}
+
+\def\boxcursor % overloaded in core-vis
+ {\iftraceboxplacement
+ \bgroup
+ \scratchdimen2pt
+ \setbox\scratchbox\normalhbox to \zeropoint
+ {\hss
+ \vrule
+ \!!width \scratchdimen
+ \!!height\scratchdimen
+ \!!depth \scratchdimen
+ \hss}%
+ \smashedbox\scratchbox
+ \egroup
+ \else
+ \copy\fakedboxcursor
+ \fi}
+
+\def\placedbox
+ {\iftraceboxplacement\ruledhbox\else\normalhbox\fi}
+
+\newdimen\boxoffset
+\newdimen\boxhdisplacement
+\newdimen\boxvdisplacement
+
+%\def\rightbox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=.5\ht0\advance\dimen0 -.5\dp0
+% \boxcursor\hskip\boxoffset\lower\dimen0\box0}}
+
+\def\rightbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement\boxoffset
+ \global\boxvdisplacement.5\ht0
+ \global\advance\boxvdisplacement-.5\dp0
+ \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}}
+
+%\def\leftbox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=.5\ht0\advance\dimen0 -.5\dp0
+% \boxcursor\hskip-\wd0\hskip-\boxoffset\lower\dimen0\box0}}
+
+\def\leftbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-\wd0
+ \global\advance\boxhdisplacement-\boxoffset
+ \global\boxvdisplacement.5\ht0
+ \global\advance\boxvdisplacement-.5\dp0
+ \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}}
+
+%\def\topbox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=\boxoffset\advance\dimen0 \dp0
+% \boxcursor\hskip-.5\wd0\raise\dimen0\box0}}
+
+\def\topbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-.5\wd0
+ \global\boxvdisplacement-\dp0
+ \global\advance\boxvdisplacement-\boxoffset
+ \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}}
+
+%\def\bottombox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=\boxoffset\advance\dimen0 \ht0
+% \boxcursor\hskip-.5\wd0\lower\dimen0\box0}}
+
+\def\bottombox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-.5\wd0
+ \global\boxvdisplacement\ht0
+ \global\advance\boxvdisplacement\boxoffset
+ \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}}
+
+%\def\lefttopbox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=\boxoffset\advance\dimen0 \dp0
+% \advance\boxoffset\wd0
+% \boxcursor\hskip-\boxoffset\raise\dimen0\box0}}
+
+\def\lefttopbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-\wd0
+ \global\advance\boxhdisplacement-\boxoffset
+ \global\boxvdisplacement-\dp0
+ \global\advance\boxvdisplacement-\boxoffset
+ \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}}
+
+%\def\righttopbox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=\boxoffset\advance\dimen0 \dp0
+% \boxcursor\hskip\boxoffset\raise\dimen0\box0}}
+
+\def\righttopbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement\boxoffset
+ \global\boxvdisplacement-\dp0
+ \global\advance\boxvdisplacement-\boxoffset
+ \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}}
+
+%\def\leftbottombox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=\boxoffset\advance\dimen0 \ht0
+% \advance\boxoffset\wd0
+% \boxcursor\hskip-\boxoffset\lower\dimen0\box0}}
+
+\def\leftbottombox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-\wd0
+ \global\advance\boxhdisplacement-\boxoffset
+ \global\boxvdisplacement\ht0
+ \global\advance\boxvdisplacement\boxoffset
+ \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}}
+
+%\def\rightbottombox#1%
+% {\normalhbox
+% {\setbox0=\placedbox{#1}%
+% \dimen0=\boxoffset\advance\dimen0 \ht0
+% \boxcursor\hskip\boxoffset\lower\dimen0\box0}}
+
+\def\rightbottombox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement\boxoffset
+ \global\boxvdisplacement\ht0
+ \global\advance\boxvdisplacement\boxoffset
+ \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}}
+
+\let\topleftbox \lefttopbox
+\let\toprightbox \righttopbox
+\let\bottomleftbox \leftbottombox
+\let\bottomrightbox\rightbottombox
+
+\def\middlebox#1%
+ {\normalhbox{\setbox0\placedbox{#1}\boxoffset=-.5\wd0\rightbox{\box0}}}
+
+\def\baselinemiddlebox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-.5\wd0
+ \global\advance\boxhdisplacement-\boxoffset
+ \global\boxvdisplacement-\boxoffset
+ \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}}
+
+\def\baselineleftbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement-\wd0
+ \global\advance\boxhdisplacement-\boxoffset
+ \global\boxvdisplacement-\boxoffset
+ \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}}
+
+\def\baselinerightbox#1%
+ {\normalhbox
+ {\setbox0\placedbox{#1}%
+ \global\boxhdisplacement\boxoffset
+ \global\boxvdisplacement-\boxoffset
+ \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}}
+
+%D \macros
+%D {obox}
+%D
+%D Experimental, not yet frozen:
+
+\def\lrtbbox#1#2#3#4% l r t b
+ {\bgroup
+ \dowithnextboxcontent
+ {\advance\hsize-#1\advance\hsize-#2\advance\vsize-#3\advance\vsize-#4\relax}
+ {\forgetall\vbox to \vsize{\vskip#3\hbox to \hsize{\hskip#1\box\nextbox\hss}\vss}\egroup}
+ \vbox}
+
+%D \macros
+%D {toplinebox}
+%D
+%D See core-tbl.tex for an example of its usage:
+
+\def\toplinebox
+ {\dowithnextbox
+ {\ifdim\nextboxdp>\strutdepth
+ \scratchdimen\nextboxdp
+ \advance\scratchdimen-\strutdepth
+ \getnoflines\scratchdimen
+ \struttedbox{\flushnextbox}%
+ \dorecurse\noflines\verticalstrut
+ \else
+ \flushnextbox
+ \fi}%
+ \tbox}
+
+%D \macros
+%D {initializeboxstack,savebox,foundbox}
+%D
+%D At the cost of some memory, but saving box registers, we
+%D have implemented a box repository.
+%D
+%D \starttyping
+%D \initializeboxstack{one}
+%D
+%D \savebox{one}{a}{test a}
+%D \savebox{one}{p}{test p}
+%D \savebox{one}{q}{test q}
+%D
+%D \normalhbox{a:\foundbox{one}{a}} \par
+%D \normalhbox{q:\foundbox{one}{q}} \par
+%D \normalhbox{p:\foundbox{one}{p}} \par
+%D \normalhbox{x:\foundbox{one}{x}} \par
+%D \normalhbox{y:\foundbox{two}{a}} \par
+%D \stoptyping
+
+% we keep it around as a demonstration of good old tex code:
+%
+% \def\@@stackbox{boxstack:b:}
+% \def\@@stackmax{boxstack:m:}
+% \def\@@stacktag{boxstack:t:}
+% \def\@@stacklst{boxstack:l:}
+%
+% \def\initializeboxstack#1%
+% {\ifundefined{\@@stackbox#1}%
+% \@EA\newbox\csname\@@stackbox#1\endcsname
+% \else
+% \global\setbox\csname\@@stackbox#1\endcsname\normalvbox{}%
+% \def\docommand##1{\global\letbeundefined{\@@stacktag#1:##1}}%
+% \processcommacommand[\getvalue{\@@stacklst#1}]\docommand
+% \fi
+% \global\letvalue{\@@stacklst#1}\empty
+% \global\letvalue{\@@stackmax#1}\!!zeropoint}
+%
+% \def\savebox#1#2% stack name
+% {\dowithnextbox
+% {\doifdefined{\@@stackbox#1}
+% {\@EA\doglobal\@EA\increment\csname\@@stackmax#1\endcsname
+% \setxvalue{\@@stacktag#1:#2}{\csname\@@stackmax#1\endcsname}%
+% \setxvalue{\@@stacklst#1}{\getvalue{\@@stacklst#1},#2}%
+% \global\setbox\csname\@@stackbox#1\endcsname\normalvbox
+% {\forgetall
+% \setbox\scratchbox\normalvbox{\flushnextbox}
+% \ht\scratchbox\onepoint
+% \dp\scratchbox\zeropoint
+% \unvbox\csname\@@stackbox#1\endcsname
+% \offinterlineskip
+% \allowbreak
+% \box\scratchbox}}}%
+% \normalvbox}
+%
+% \def\foundbox#1#2%
+% {\normalvbox
+% {\doifdefined{\@@stackbox#1}
+% {\doifdefined{\@@stacktag#1:#2}
+% {\setbox\scratchbox\normalvbox
+% {\splittopskip\zeropoint
+% \setbox0\copy\csname\@@stackbox#1\endcsname
+% \dimen0=\getvalue{\@@stacktag#1:#2}\points
+% \advance\dimen0 -\onepoint
+% \setbox2\vsplit0 to \dimen0
+% \ifdim\ht0>\onepoint
+% \setbox0\vsplit0 to \onepoint
+% \fi
+% \unvbox0\setbox0\lastbox\unvbox0}%
+% \unvbox\scratchbox}}}}
+%
+% \def\doifboxelse#1#2%
+% {\doifdefinedelse{\@@stacktag#1:#2}}
+
+\def\@@stackbox{@box@}
+\def\@@stacklst{@xob@}
+
+\def\setstackbox#1#2%
+ {\ifcsname\@@stackbox:#1:#2\endcsname\else
+ \expandafter\newbox\csname\@@stackbox:#1:#2\endcsname
+ \fi
+ \global\setbox\csname\@@stackbox:#1:#2\endcsname\normalvbox}
+
+\def\initializeboxstack#1%
+ {\def\docommand##1{\setstackbox{#1}{##1}{}}%
+ \ifcsname\@@stacklst#1\endcsname
+ \processcommacommand[\getvalue{\@@stacklst#1}]\docommand
+ \fi
+ \global\letvalue{\@@stacklst#1}\empty}
+
+\def\savebox#1#2% stack name
+ {% beware, \setxvalue defines the cs beforehand so we cannot use the
+ % test inside the { }
+ \ifcsname\@@stacklst#1\endcsname
+ \setxvalue{\@@stacklst#1}{\csname\@@stacklst#1\endcsname,#2}%
+ \else
+ \setxvalue{\@@stacklst#1}{#2}%
+ \fi
+ \setstackbox{#1}{#2}}
+
+\def\foundbox#1#2%
+ {\normalvbox
+ {\ifcsname\@@stackbox:#1:#2\endcsname
+ \copy\csname\@@stackbox:#1:#2\endcsname
+ \fi}}
+
+\long\def\doifboxelse#1#2#3#4%
+ {\ifcsname\@@stackbox:#1:#2\endcsname
+ \ifvoid\csname\@@stackbox:#1:#2\endcsname#4\else#3\fi
+ \else
+ #4%
+ \fi}
+
+\endETEX
+
+%D \macros
+%D {removedepth, obeydepth}
+%D
+%D While \type {\removedepth} removes the preceding depth,
+%D \type {\obeydepth} makes sure we have depth. Both macros
+%D leave the \type {\prevdepth} untouched.
+
+\def\removedepth
+ {\ifvmode \ifdim\prevdepth>\zeropoint \kern-\prevdepth \fi \fi}
+
+\def\obeydepth
+ {\par \removedepth \ifvmode \kern\strutdp \fi}
+
+\def\undepthed
+ {\dowithnextbox{\nextboxdp\zeropoint\flushnextbox}\hbox}
+
+%D \macros
+%D {removebottomthings, removelastskip}
+%D
+%D A funny (but rather stupid) one, plus a redefinition.
+
+\def\removebottomthings
+ {\dorecurse5{\unskip\unkern\unpenalty}}
+
+\def\removelastskip % \ifvmode the plain tex one \fi
+% {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi}
+ {\ifvmode\ifzeropt\lastskip\else\vskip-\lastskip\fi\fi}
+
+%D \macros
+%D {makestrutofbox}
+%D
+%D This macro sets the dimensions of a box to those of a
+%D strut.
+
+\def\domakestrutofbox
+ {\ht\registercount\strutht
+ \dp\registercount\strutdp
+ \wd\registercount\zeropoint}
+
+\def\makestrutofbox
+ {\afterassignment\domakestrutofbox\registercount}
+
+%D \macros
+%D {raisebox,lowerbox}
+%D
+%D Some more box stuff, related to positioning (under
+%D construction). Nice stuff for a tips and tricks maps
+%D article.
+%D
+%D \starttyping
+%D \raisebox{100pt}\normalhbox{test}
+%D \raisebox50pt\normalhbox{test}
+%D \hsmash{\raisebox{100pt}\normalhbox{test}}
+%D \stoptyping
+
+\def\doraiselowerbox#1#2% a nice trick us used to accept
+ {\def\next % both direct and {} dimensions
+ {\dowithnextbox
+ {\setbox\nextbox\normalhbox{#1\scratchdimen\flushnextbox}%
+ \nextboxht\strutht
+ \nextboxdp\strutdp
+ \flushnextbox}}%
+ \afterassignment\next\scratchdimen=#2}
+
+\def\raisebox{\doraiselowerbox\raise}
+\def\lowerbox{\doraiselowerbox\lower}
+
+% maybe some day we need this
+%
+% \def\appendvbox#1% % uses \box8
+% {\bgroup
+% \ifdim\prevdepth<\zeropoint
+% \ifdim\pagetotal=\zeropoint
+% \setbox8=\normalvtop{\unvcopy#1}%
+% \hrule\c!!height\zeropoint
+% \kern-\ht8
+% \box#1\relax
+% \else
+% \box#1\relax
+% \fi
+% \else
+% \dimen0=\prevdepth
+% \hrule\c!!height\zeropoint
+% \setbox8=\normalvtop{\unvcopy#1}%
+% \dimen2=\baselineskip
+% \advance\dimen2 by -\dimen0
+% \advance\dimen2 by -\ht8
+% \kern\dimen2
+% \box#1\relax
+% \fi
+% \egroup}
+
+% %D Also new:
+% %D
+% %D \startbuffer
+% %D \normbox[1cm][bba]{m} % b(efore) a(fter) v(box) s(trut) f(rame)
+% %D \normbox[1cm][bba]{m}
+% %D \normbox[1cm][bba]{m}
+% %D \stopbuffer
+% %D
+% %D \typebuffer
+% %D \getbuffer
+%
+% \def\dodonormbox#1#2#3#4#5#6#7%
+% {\doifnumberelse{#1}
+% {\dimen0=#1}{\setbox0=#3{#1}\dimen0=#50}%
+% \doifinstringelse{f}{#2}
+% {\let\next#4}{\let\next#3}%
+% \next to \dimen0
+% {\counttoken b\in#2\to\!!counta\dorecurse{\!!counta}{#6}#6%
+% #7\nextbox
+% \counttoken a\in#2\to\!!counta\dorecurse{\!!counta}{#6}#6}}
+%
+% \def\donormbox[#1][#2]%
+% {\bgroup
+% \doifinstringelse{v}{#2}
+% {\let\next\normalvbox}
+% {\let\next\normalhbox}%
+% \dowithnextbox
+% {\ifvbox\nextbox
+% \let\\=\par
+% \dodonormbox{#1}{#2}\normalvbox\ruledvbox\ht\vfil\unvbox
+% \else
+% \let\\=\space
+% \dodonormbox{#1}{#2}\normalhbox\ruledhbox\wd\hfil\unhbox
+% \fi
+% \egroup}%
+% \next}
+%
+% \def\normbox
+% {\dodoubleempty\donormbox}
+
+% vcenter in text, we kunnen vcenter overloaden
+
+\def\halfwaybox
+ {\dowithnextbox
+ {\nextboxdp\zeropoint
+ \setbox\nextbox\normalhbox{\lower.5\nextboxht\flushnextbox}%
+ \flushnextbox}
+ \normalhbox}
+
+%D New:
+
+\def\setdimentoatleast#1#2%
+ {\ifdim#1>\zeropoint\else#1=#2\fi}
+
+%D And even rawer:
+
+\let\naturalhbox \normalhbox
+\let\naturalvbox \normalvbox
+\let\naturalvtop \normalvtop
+\let\naturalvcenter \normalvtop
+
+\ifdefined\textdir
+
+ \def\naturalhbox{\normalhbox dir TLT}
+ \def\naturalvbox{\normalvbox dir TLT}
+ %def\naturalvtop{\normalvtop dir TLT}
+
+\fi
+
+%D \macros
+%D {vcenter}
+%D
+%D Also new: tex mode \type {\vcenter}.
+
+\let\verynormalvcenter \vcenter % since \vcenter can be visualized
+
+\def\vcenter
+ {\normalvbox\bgroup
+ \dowithnextbox{\normalhbox{$\verynormalvcenter{\flushnextbox}$}\egroup}
+ \normalvbox}
+
+% could be \everymathematics
+
+\prependtoks \let\vcenter\normalvcenter \to \everymath
+\prependtoks \let\vcenter\normalvcenter \to \everydisplay
+
+%D \macros
+%D {frozenhbox}
+%D
+%D A not so well unhboxable bxo can be made with:
+
+\def\frozenhbox
+ {\hbox\bgroup\dowithnextbox{\hbox{\hbox{\flushnextbox}}\egroup}\hbox}
+
+%D \macros
+%D {setboxllx,setboxlly,gsetboxllx,gsetboxlly,getboxllx,getboxlly}
+%D
+%D A prelude to an extended \TEX:
+
+% \def\setboxllx #1#2{\bgroup\scratchdimen#2\expanded{\egroup\noexpand\setevalue{b@@x\number#1}{\the\scratchdimen}}}
+% \def\setboxlly #1#2{\bgroup\scratchdimen#2\expanded{\egroup\noexpand\setevalue{b@@y\number#1}{\the\scratchdimen}}}
+%
+% \def\gsetboxllx#1#2{\bgroup\scratchdimen#2\setxvalue{b@@x\number#1}{\the\scratchdimen}\egroup}
+% \def\gsetboxlly#1#2{\bgroup\scratchdimen#2\setxvalue{b@@y\number#1}{\the\scratchdimen}\egroup}
+
+\def\setboxllx#1#2{\setevalue{b@@x\number#1}{\the\dimexpr#2\relax}}
+\def\setboxlly#1#2{\setevalue{b@@y\number#1}{\the\dimexpr#2\relax}}
+
+\def\gsetboxllx{\global\setboxllx}
+\def\gsetboxlly{\global\setboxlly}
+
+\def\getboxllx#1{\executeifdefined{b@@x\number#1}\zeropoint}
+\def\getboxlly#1{\executeifdefined{b@@y\number#1}\zeropoint}
+
+%D \macros
+%D {shownextbox}
+%D
+%D Handy for tracing
+%D
+%D \starttyping
+%D \shownextbox\vbox{test}
+%D \shownextbox\vbox{test\endgraf}
+%D \shownextbox\vbox{test\endgraf\strut\endgraf}
+%D \shownextbox\vbox{test\endgraf\thinrule}
+%D \shownextbox\vbox{\setupwhitespace[big]test\endgraf\thinrule}
+%D \stoptyping
+
+\def\shownextbox
+ {\dowithnextbox
+ {\bgroup
+ \showboxbreadth\maxdimen
+ \showboxdepth \maxdimen
+ \scratchcounter\interactionmode
+ \batchmode
+ \showbox\nextbox
+ \box\nextbox
+ \interactionmode\scratchcounter
+ \egroup}}
+
+\def\spreadhbox#1% rebuilds \hbox{<box><hss><box><hss><box>}
+ {\bgroup
+ \ifhbox#1\relax
+ \setbox2\emptybox
+ \unhbox#1%
+ \doloop
+ {\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip
+ \setbox0\lastbox
+ \ifvoid0
+ \exitloop
+ \else
+ \setbox2\hbox
+ {\ifhbox0 \spreadhbox0\else\box0\fi
+ \ifvoid2 \else\hss\unhbox2\fi}%
+ \fi}%
+ \ifvoid2\else\unhbox2\fi
+ \else
+ \box#1%
+ \fi
+ \egroup}
+
+% makes sense but too much log for overfull boxes:
+%
+% \showboxbreadth\maxdimen
+% \showboxdepth \maxdimen
+
+\protect \endinput
+
+% a bit of test code:
+
+\hbox \bgroup
+ \ruledvbox {\hbox{\strut gans}}
+ \ruledvbox to \lineheight {\hbox{\strut gans}}
+ \ruledvbox to \lineheight {\hbox {gans}}
+ \ruledvbox to \strutheight{\hbox {gans}}
+ \ruledvbox to \strutheight{\hbox{\strut gans}}
+ \ruledvbox to \strutheight{\vss\hbox{gans}}
+\egroup
diff --git a/tex/context/base/supp-fun.tex b/tex/context/base/supp-fun.mkii
index 6b2643703..6b2643703 100644
--- a/tex/context/base/supp-fun.tex
+++ b/tex/context/base/supp-fun.mkii
diff --git a/tex/context/base/supp-fun.mkiv b/tex/context/base/supp-fun.mkiv
new file mode 100644
index 000000000..6b2643703
--- /dev/null
+++ b/tex/context/base/supp-fun.mkiv
@@ -0,0 +1,746 @@
+%D \module
+%D [ file=supp-fun,
+%D version=1995.10.10,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Fun Stuff,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D This module implements some typographics tricks that can
+%D be fun when designing document layouts. The examples use
+%D macros that are typical to \CONTEXT, but non \CONTEXT\
+%D users can use the drop caps and first line treatment
+%D macros without problems. This module will be extended
+%D when the need for more of such tricks arises.
+
+\ifx \undefined \writestatus \input supp-mis.tex \relax \fi
+
+\writestatus{loading}{ConTeXt Support Macros / Fun Stuff}
+
+\ifx\definefont\undefined
+ \def\definedfont[#1]{\font\temp#1\relax\temp}
+\fi
+
+%D \macros
+%D {DroppedCaps, DroppedString, DroppedIndent, DroppedLines}
+%D
+%D \startbuffer
+%D \DroppedCaps
+%D {\color[green]} {cmbx12}
+%D {2.2\baselineskip} {2pt} {\baselineskip} {2}
+%D Let's start
+%D \stopbuffer
+%D
+%D \getbuffer with dropped caps, those blown up first
+%D characters of a paragraph. It's hard to implement a general
+%D mechanism that suits all situations, but dropped caps are so
+%D seldomly used that we can permit ourselves a rather user
+%D unfriendly implementation.
+%D
+%D \typebuffer
+%D
+%D As we will see, there are 7 different settings involved. The
+%D first argument takes a command that is used to do whatever
+%D fancy things we want to do, but normally this one will be
+%D empty. The second argument takes the font. Because we're
+%D dealing with something very typographic, there is no real
+%D reason to adopt complicated font switching schemes, a mere
+%D name will do. Font encodings can bring no harm, because the
+%D alphanumeric characters are nearly always located at their
+%D natural position in the encoding vector.
+%D
+%D \startbuffer
+%D \DroppedCaps
+%D {\color[red]} {cmbx12}
+%D {\baselineskip} {0pt} {0pt} {1}
+%D This simple
+%D \stopbuffer
+%D
+%D \getbuffer case shows us what happens when we apply minimal
+%D values. Here we used:
+%D
+%D \typebuffer
+%D
+%D \startbuffer
+%D \DroppedCaps
+%D {\color[red]} {cmbx12}
+%D {2\baselineskip} {0pt} {\baselineskip} {2}
+%D Is this ugly
+%D \stopbuffer
+%D
+%D \getbuffer example the third argument tells
+%D this macro that we want a dropped capital scaled to the
+%D baseline distance. The two zero point arguments are the
+%D horizontal and vertical offsets and the last arguments
+%D determines the hanging indentation. In this paragraph we
+%D set the height to two times the baselinedistance and use
+%D two hanging lines:
+%D
+%D \typebuffer
+%D
+%D Here, the first character is moved down one baseline. Here
+%D we also see why the horizontal offset is important. The
+%D first example (showing the~L) sets this to a few points and
+%D also used a slightly larger height.
+%D
+%D Of course common users (typist) are not supposed to see this
+%D kind of fuzzy definitions, but fortunately \TEX\ permits us
+%D to hide them in macros. Using a macro also enables us to
+%D garantee consistency throughout the document:
+%D
+%D \startbuffer
+%D \def\MyDroppedCaps%
+%D {\DroppedCaps
+%D {\color[green]} {cmbx12}
+%D {5\baselineskip} {3pt} {3\baselineskip} {4}}
+%D
+%D \MyDroppedCaps The implementation
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer of the general macro is rather simple and only
+%D depends on the arguments given and the dimensions of the
+%D strut box. We explicitly load the font, which is no problem
+%D because \TEX\ does not load a font twice. We could have
+%D combined some arguments, like the height, vertical offset
+%D and the number of lines, but the current implementation
+%D proved to be the most flexible. One should be aware of the
+%D fact that the offsets depend on the design of the glyphs
+%D used.
+
+\let\DroppedIndent\!!zeropoint \def\DroppedLines{0}
+
+\def\DroppedString{ABCDEFGHIJKLMNOPQRSTUVWXYZ}
+
+\let\globaldropcaps\global % will be an option, but on by default
+
+\def\localdropcaps{\let\globaldropcaps\relax}
+
+\chardef\DroppedStatus = 0 % 0=done 1=starting 2=doing 3=error
+\chardef\DropMode = 0 % 1 == marginhang
+
+\ifx\keeplinestogether\undefined
+ \let\keeplinestogether\gobbleoneargument
+\fi
+
+\def\DroppedCaps#1#2#3#4#5#6#7% does not yet handle accented chars
+ {\defconvertedargument\asciia{#7}%
+ \defconvertedcommand \asciib{\DroppedString}%
+ \ExpandBothAfter\doifinstringelse\asciia\asciib
+ {\noindentation
+ \dontleavehmode
+ \checkindentation % redo this one
+ %\ifhmode\hskip-\parindent\fi % sensitive for context mechanism
+ \keeplinestogether{#6}%
+ \setbox0\hbox{\definedfont[#2 at #3]#1{#7}\hskip#4}%
+ \ifdim\dp0>\strutdp % one of those Q's , will be option
+ \setbox2\hbox{\raise\dp0\hbox{\lower\strutdp\copy0}}%
+ \ht2\ht0
+ \dp0\strutdp
+ \setbox0\box2
+ \fi
+ \setbox0\hbox
+ {\ifnum\DropMode=\plusone
+ \hskip-\wd0\wd0\zeropoint
+ \fi
+ \lower#5\box0}%
+ \ht0\strutht
+ \dp0\strutdp
+ \ifnum\DropMode=\plusone
+ \globaldropcaps\let\DroppedIndent\!!zeropoint
+ \globaldropcaps\edef\DroppedLines{\number\maxdimen}%
+ \globaldropcaps\chardef\DroppedStatus\plusthree
+ \else
+ \globaldropcaps\edef\DroppedIndent{\the\wd0}%
+ \globaldropcaps\edef\DroppedLines {\number#6}%
+ \globaldropcaps\chardef\DroppedStatus\plustwo
+ \globaldropcaps\hangindent\DroppedIndent
+ \globaldropcaps\hangafter-\DroppedLines
+% \noindent
+ \noindentation
+ \checkindentation % redo this one
+ \hskip-\DroppedIndent
+ \fi
+ \vbox{\forgetall\box0}%
+ \nobreak
+ \let\next\ignorespaces} % Could be a one character word !
+ {\globaldropcaps\let\DroppedIndent\!!zeropoint
+ \globaldropcaps\edef\DroppedLines{\number\maxdimen}%
+ \globaldropcaps\chardef\DroppedStatus\plusthree
+ \def\next{#7}}%
+ \let\globaldropcaps\global
+ \next}
+
+%D Before we go to the next topic, we summarize this command:
+%D
+%D \starttyping
+%D \DroppedCaps
+%D {command} {font}
+%D {height} {hoffset} {voffset} {lines}
+%D \stoptyping
+%D
+%D Sometimes you need to make sure that the global settings are
+%D kept local, as in:
+%D
+% %D \startbuffer
+% %D \defineparagraphs[SomePar][n=2,rule=on]
+% %D \setupparagraphs [SomePar][1][width=.5\textwidth]
+% %D \setupparagraphs [SomePar][2][width=.5\textwidth]
+%D \startbuffer
+%D \defineparagraphs[SomePar][n=2,rule=on]
+%D \setupparagraphs [SomePar][1][width=.5\textwidth]
+%D \setupparagraphs [SomePar][2][width=.5\textwidth]
+%D
+%D \startSomePar
+%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need
+%D to explicitly keep the hanging indentation local, like it or
+%D not.
+%D \SomePar
+%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need
+%D to explicitly keep the hanging indentation local, like it or
+%D not.
+%D \stopSomePar
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {AutoDroppedCaps, CheckDroppedCaps}
+%D
+%D {\em To be documented.}
+
+% example usage
+%
+% \def\bpar{\ifvmode\CheckDroppedCaps\fi}
+% \def\epar{\ifhmode\par\fi\CheckDroppedCaps}
+
+\newcount\lastprevgraf
+\newcount\droppedlines
+
+\def\CheckDroppedCaps
+ {\global\lastprevgraf\prevgraf}
+
+\def\AutoDroppedCaps % will be proper core stuff since it
+ {\globaldropcaps\chardef\DroppedStatus\plusone
+ \global\lastprevgraf\zerocount
+ \global\droppedlines\zerocount
+ \EveryPar{\doAutoDroppedCaps}}
+
+\let\AutoDroppedNext\relax
+
+\ifx\AutoDroppedCapsCommand\undefined
+ \def\AutoDroppedCapsCommand{\NiceDroppedCaps{}{SerifBold}{.125em}{3}}
+\fi
+
+\def\doAutoDroppedCaps
+ {\ifcase\DroppedStatus % done
+ \let\next\relax
+ \or % starting
+ % \ifnum\lastprevgraf>0 % tricky, probably a wrong par
+ % \globaldropcaps\chardef\DroppedStatus=3 % and inhibits dropped
+ % \let\next\relax % caps after titles and more than once
+ % \else % so let's nill this rubishly code fragment
+ \let\next\AutoDroppedCapsCommand
+ % \fi % and hope for the best
+ \or % doing
+ \global\advance\droppedlines \lastprevgraf
+ \ifnum\droppedlines=\zerocount
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \else\ifnum\droppedlines>\zerocount
+ \ifnum\droppedlines<\DroppedLines\relax
+ \globaldropcaps\hangindent\DroppedIndent
+ \globaldropcaps\hangafter-\DroppedLines
+ \globaldropcaps\advance\hangafter \droppedlines
+ \hskip-\parindent % brrr
+ \let\next\AutoDroppedNext
+ \else
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \fi
+ \else
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \fi\fi
+ \or % error
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \fi
+ \next}
+
+%D \macros
+%D {LineDroppedCaps, NiceDroppedCaps}
+%D
+%D To save definitions, we also provide:
+%D
+%D \starttyping
+%D \LineDroppedCaps {command} {font} {hoffset} {lines}
+%D \NiceDroppedCaps {command} {font} {hoffset} {lines}
+%D \stoptyping
+%D
+%D The first command scales the font to the exact height, while
+%D the second command scales the font to a nice 2.5 times the
+%D line height, a value that gives a pleasant grayness.
+
+\def\DoLineDroppedCaps#1#2#3#4#5% compensation command font offset lines
+ {\scratchcounter#5%
+ \advance\scratchcounter \minusone
+ \scratchdimen\scratchcounter\baselineskip
+ \advance\scratchdimen #1%
+ \NormalizeFontHeight\DummyFont{W}\scratchdimen{#3}%
+ \DroppedCaps{#2}{#3}\TheNormalizedFontSize{#4}
+ {\scratchcounter\baselineskip}{#5}}
+
+\def\LineDroppedCaps% command font offset lines
+ {\DoLineDroppedCaps{\strutht}}
+
+\def\NiceDroppedCaps% command font offset lines
+ {\DoLineDroppedCaps{.5\baselineskip}}
+
+%D \macros
+%D {TreatFirstLine}
+%D
+%D \startbuffer
+%D \TreatFirstLine {\sc} {} {} {}
+%D Instead of limiting its action to one token, the next macro
+%D treats the whole first line. This paragraph was typeset by
+%D saying:
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \typebuffer
+%D
+%D \startbuffer
+%D \TreatFirstLine {\startcolor[red]\bf} {\stopcolor} {} {}
+%D The combined color and font effect is also possible,
+%D although one must be careful in using macros that accumulate
+%D grouping, but the commands used here are pretty save in that
+%D respect.
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \typebuffer
+%D
+%D Before we explain the third and fourth argument, we show the
+%D implementation. Those who know a bit about the way \TEX\
+%D treats tokens, will probably see in one glance that this
+%D alternative works all right for most text||only situations
+%D in which there is enough text available for the first line,
+%D but that more complicated things will blow. One has to live
+%D with that. A workaround is rather trivial but obscures the
+%D principles used.
+
+\def\TreatFirstLine#1#2#3#4% before, after, first, next
+ {\leavevmode
+ \bgroup
+ \forgetall
+ \bgroup
+ #1%
+ \setbox0\emptybox
+ \setbox2\emptybox
+ \def\grabfirstline##1 %
+ {\setbox2\hbox
+ {\ifvoid0
+ {#3{\ignorespaces##1}}%
+ \else
+ \unhcopy0\ {#4{##1}}%
+ \fi}%
+ \ifdim\wd2=\zeropoint
+ \setbox0\emptybox
+ \setbox2\emptybox
+ \@EA\grabfirstline
+ \else\ifdim\wd2>\hsize
+ \hbox to \hsize{\strut\unhbox0}#2\egroup
+ \break##1\
+ \egroup
+ \else
+ \setbox0\box2
+ \@EAEAEA\grabfirstline
+ \fi\fi}%
+ \grabfirstline}
+
+%D \startbuffer
+%D \gdef\FunnyCommand
+%D {\getrandomfloat\FunnyR{0}{1}%
+%D \getrandomfloat\FunnyG{0}{1}%
+%D \getrandomfloat\FunnyB{0}{1}%
+%D \definecolor[FunnyColor][r=\FunnyR,g=\FunnyG,b=\FunnyB]%
+%D \color[FunnyColor]}
+%D
+%D %\TreatFirstLine {\bf} {} {\FunnyCommand} {\FunnyCommand}
+%D The third and fourth argument can be used to gain special
+%D effects on the individual words. Of course one needs ...
+%D \stopbuffer
+%D
+%D \getbuffer
+%D to know a bit more about the macro package used to get real
+%D nice effects, but this example probably demonstrates the
+%D principles well.
+%D
+%D \typebuffer
+%D
+%D Like in dropped caps case, one can hide such treatments in a
+%D macro, like:
+%D
+%D \starttyping
+%D \def\MyTreatFirstLine%
+%D {\TreatFirstLine{\bf}{}{\FunnyCommand}{\FunnyCommand}}
+%D \stoptyping
+
+%D \macros
+%D {reshapebox}
+%D
+%D \startbuffer
+%D \beginofshapebox
+%D When using \CONTEXT, one can also apply this funny command
+%D to whole lines by using the reshape mechanism. Describing
+%D this interesting mechanism falls outside the scope of this
+%D module, so we only show the trick. This is an example of
+%D low level \CONTEXT\ functionality: it's all there, and it's
+%D stable, but not entirely meant for novice users.
+%D \endofshapebox
+%D
+%D \reshapebox{\FunnyCommand{\box\shapebox}} \flushshapebox
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \typebuffer
+%D
+%D This mechanism permits hyphenation and therefore gives
+%D better results than the previously discussed macro
+%D \type{\TreatFirstLine}.
+
+%D \macros
+%D {TreatFirstCharacter}
+%D
+%D \startbuffer
+%D \TreatFirstCharacter{\bf\color[green]} Just to be
+%D \stopbuffer
+%D
+%D \getbuffer complete we also offer a very simple one
+%D character alternative, that is not that hard to understand:
+
+\def\TreatFirstCharacter#1#2% command, character
+ {{#1{#2}}}
+
+%D A previous paragraph started with:
+%D
+%D \typebuffer
+
+%D \macros
+%D {StackCharacters}
+%D
+%D The next hack deals with vertical stacking.
+
+\def\StackCharacters#1#2#3#4% sequence vsize vskip command
+ {\vbox #2
+ {\forgetall
+ \baselineskip\zeropoint
+ \def\StackCharacter##1{#4{##1}\cr\noalign{#3}}%
+ \halign
+ {\hss##\hss&##\cr
+ \handletokens#1\with\StackCharacter\cr}}}
+
+%D \startbuffer
+%D \StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}
+%D \stopbuffer
+%D
+%D Such a stack looks like:
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {$\hss\bfd
+%D \vcenter{\StackCharacters{TEX} {}{\vskip.2ex}{\FunnyCommand}}%
+%D \hss
+%D \vcenter{\StackCharacters{CON} {}{\vskip.2ex}{\FunnyCommand}}
+%D \hss
+%D \vcenter{\StackCharacters{TEXT} {}{\vskip.2ex}{\FunnyCommand}}
+%D \hss
+%D \vcenter{\StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}}
+%D \hss$}
+%D \stoplinecorrection
+%D
+%D and is typeset by saying:
+%D
+%D \typebuffer
+%D
+%D An alternative would have been
+%D
+%D \starttyping
+%D \StackCharacters {CONTEXT} {to 5cm} {\vfill} {\FunnyCommand}
+%D \stoptyping
+
+%D \macros
+%D {processtokens}
+%D
+%D At a lower level horizontal and vertical manipulations are
+%D already supported by:
+%D
+%D \starttyping
+%D \processtokens {begin} {between} {end} {space} {text}
+%D \stoptyping
+%D
+%D \startbuffer[a]
+%D \processtokens
+%D {\hbox to .5\hsize\bgroup} {\hfill}
+%D {\egroup} {\space} {LET'S HAVE}
+%D \stopbuffer
+%D
+%D \startbuffer[b]
+%D \processtokens
+%D {\vbox\bgroup\raggedcenter\hsize1em}
+%D {\vskip.25ex} {\egroup} {\strut} {FUN}
+%D \stopbuffer
+%D
+%D This macro is able to typeset:
+%D
+%D \leavevmode\hbox to \hsize
+%D {$\hfil\hfil
+%D \vcenter{\bf\getbuffer[a]}%
+%D \hfil
+%D \vcenter{\bfd\getbuffer[b]}%
+%D \hfil\hfil$}
+%D
+%D which was specified as:
+%D
+%D \typebuffer[a]
+%D \typebuffer[b]
+
+%D \macros
+%D {NormalizeFontHeight, NormalizeFontWidth,
+%D TheNormalizedFontSize}
+%D
+%D Next we introduce some font manipulation macros. When we
+%D want to typeset some text spread in a well defined area, it
+%D can be considered bad practice to manipulate character and
+%D word spacing. In such situations the next few macros can be
+%D of help:
+%D
+%D \starttyping
+%D \NormalizeFontHeight \name {sample text} {height} {font}
+%D \NormalizeFontWidth \name {sample text} {width} {font}
+%D \stoptyping
+%D
+%D These are implemented using an auxilliary macro:
+
+\def\NormalizeFontHeight{\NormalizeFontSize\ht}
+\def\NormalizeFontWidth {\NormalizeFontSize\wd}
+
+% \def\NormalizeFontSize#1#2#3#4#5%
+% {\bgroup
+% \dimen0=#4% #4 can be \ht0 or so
+% \setbox0\hbox{\definedfont[#5 at 10pt]#3}%
+% \ifdim\wd0>\zeropoint
+% \dimen2=#10 % #1 is \wd or \ht
+% \dimen4=10000pt
+% \divide\dimen4 \dimen2
+% \divide\dimen0 \plusthousand
+% \dimen0=\number\dimen4\dimen0
+% \xdef\TheNormalizedFontSize{\the\dimen0}%
+% \else
+% \dimen0\bodyfontsize
+% \fi
+% \definedfont[#5 at \the\dimen0]%
+% \expandafter
+% \egroup
+% \expandafter\font\expandafter#2\fontname\font\relax}
+%
+% the familiar struggle with accuracy forces us to use:
+
+\def\NormalizeFontSize#1#2#3#4#5%
+ {\bgroup
+ \dimen0=#4% #4 can be \ht0 or so
+ \setbox0\hbox{\definedfont[#5 at 5pt]#3}% 10pt
+ \ifdim\wd0>\zeropoint
+ \dimen2=#10 % #1 is \wd or \ht
+ \dimen4=\maxdimen % 10000pt
+ \divide\dimen4 \dimen2
+ \divide\dimen0 1638 % 1000
+ \dimen0=\number\dimen4\dimen0
+ \divide \dimen0 \plustwo % ...
+ \xdef\TheNormalizedFontSize{\the\dimen0}%
+ \else
+ \dimen0\bodyfontsize
+ \fi
+ % mkii
+ % \definedfont[#5 at \the\dimen0]%
+ % \expandafter
+ % \egroup
+ % \expandafter\font\expandafter#2\fontname\font\relax}
+ % mkiv safe (file: prefix etc)
+ \expanded{\egroup\def\noexpand#2{\definedfont[#5 at \the\dimen0]}}}
+
+%D Afterwards, we have access to the calculated size by:
+
+\let\TheNormalizedFontSize\!!zeropoint
+
+%D Extra:
+
+\def\WidthSpanningText#1#2#3% text width font
+ {\hbox{\NormalizeFontWidth\temp{#1}{#2}{#3}\temp\the\everydefinedfont#1}}
+
+%D Consider for instance:
+%D
+%D \startbuffer
+%D \NormalizeFontHeight \tmp {X} {2\baselineskip} {cmr10}
+%D
+%D {\tmp To Be Or Not To Be}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This shows up as (we also show the baselines):
+%D
+%D {\showbaselines\getbuffer}
+%D
+%D The horizontal counterpart is:
+%D
+%D \startbuffer
+%D \NormalizeFontWidth \tmp {This Line Fits} {\hsize} {cmr10}
+%D
+%D \hbox{\tmp This Line Fits}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D The calculated font scale is avaliable in the macro
+%D \type{\NormalizedFontSize}.
+%D
+%D \startlinecorrection
+%D \ruledhbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D One can of course combine these macros with the ones
+%D described earlier, like in:
+%D
+%D \starttyping
+%D \NormalizeFontHeight {text} \DroppedFont {2\baselineskip} {cmbx12}
+%D
+%D \def\NicelyDroppedCaps
+%D {\DroppedCaps
+%D {\color[green]}
+%D {\DroppedFont}
+%D {2pt}
+%D {\baselineskip}
+%D {2}}
+%D \stoptyping
+%D
+%D It's up to the reader to test this one.
+
+\unexpanded\def\FirstNCharacters#1#2% \FirstNCharacters{3}{fr{\"o}beln}
+ {\bgroup
+ \scratchcounter\zerocount
+ \def\docommand##1%
+ {\ifnum\scratchcounter=#1\else
+ ##1\relax % catches ##1 = \"e and alike
+ \advance\scratchcounter\plusone
+ \fi}
+ \handletokens#2\with\docommand
+ \egroup}
+
+%D \macros
+%D {FittingText}
+%D
+%D First used in Pascal (demo-bbv):
+%D
+%D \startbuffer
+%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1}
+%D {\veryraggedright
+%D \hangindent1em\hangafter1\relax
+%D \begstrut \dorecurse{8}{Bram Marta }\unskip \endstrut}}
+%D
+%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1}
+%D {\raggedleft\begstrut Bram\\Marta \unskip\endstrut}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+
+% #1 width #2 height #3 font #4 size #5 step #6 interlinie #7 text
+
+\long\def\FittingText#1#2#3#4#5#6#7%
+ {\bgroup
+ \forgetall
+ \dontcomplain
+ \setuptolerance[\v!verytolerant]% == \tolerance4500
+ \hsize#1%
+ \def\\{\softbreak}%
+ \!!heighta#4%
+ \!!heightb#2%
+ \doloop
+ {\ifdim\!!heighta>\onepoint
+ \expanded{\definefont[\s!dummy][#3 at \the\!!heighta][\c!interlinespace=#6]}%
+ \getvalue\s!dummy
+ \setbox\scratchbox\vbox{#7\endgraf}%
+ \ifdim\ht\scratchbox>\!!heightb
+ \advance\!!heighta-#5%
+ \else
+ \beginshapebox
+ \unvcopy\scratchbox
+ \endshapebox
+ \global\dimen1\hsize
+ \reshapebox
+ {\setbox\shapebox\hbox{\unhbox\shapebox}%
+ \ifdim\wd\shapebox>\dimen1
+ \global\dimen1\wd\shapebox
+ \fi}%
+ \ifdim\dimen1>\hsize
+ \advance\!!heighta-#5%
+ \else
+ \exitloop
+ \fi
+ \fi
+ \else
+ \exitloop
+ \fi}%
+ %\writestatus{\strippedcsname\FittingText}{height: \the\!!heighta}%
+ \unvbox\scratchbox
+ \egroup}
+
+%D New:
+
+% \font width gap font spec text
+
+\def\NormalizeFontWidthSpread#1#2#3#4#5#6%
+ {\global\setfalse\NFSpread
+ \scratchdimen#3%
+ \scratchdimen-.5\scratchdimen
+ \advance\scratchdimen#2\relax
+ \NormalizeFontWidth
+ #1%
+ {\def\+{\global\settrue\NFSpread\gobbleuntil\relax}%
+ \def\\{\gobbleuntil\relax}% newline
+ \setupspacing
+ #6\relax}%
+ {\scratchdimen}%
+ {#4}%
+ \ifconditional\NFSpread
+ % de gap valt in de binding
+ \else
+ \definefont[\strippedcsname#1][#4 #5]%
+ \fi}
+
+\def\SpreadGapText#1#2%
+ {{\def\+{\kern#1}#2}}
+
+\def\GapText#1#2#3#4#5% width distance font spec title
+ {\bgroup
+ \NormalizeFontWidthSpread\DummyFont{#1}{#2}{#3}{#4}{#5}%
+ \DummyFont\setupspacing\SpreadGapText{#2}{#5}\endgraf
+ \egroup}
+
+\protect \endinput
diff --git a/tex/context/base/supp-num.tex b/tex/context/base/supp-num.mkii
index 742349753..742349753 100644
--- a/tex/context/base/supp-num.tex
+++ b/tex/context/base/supp-num.mkii
diff --git a/tex/context/base/supp-num.mkiv b/tex/context/base/supp-num.mkiv
new file mode 100644
index 000000000..3b629b7d4
--- /dev/null
+++ b/tex/context/base/supp-num.mkiv
@@ -0,0 +1,509 @@
+%D \module
+%D [ file=supp-num,
+%D version=1998.05.15,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Numbers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% See end for transition to mkiv.
+
+\writestatus{loading}{ConTeXt Support Macros / Numbers}
+
+\unprotect
+
+%D \macros
+%D {digits, setdigitmode, setdigitsign}
+%D
+%D Depending on the digit mode the command \type {\digits}
+%D normalizes number patterns depending on the language set.
+%D
+%D \starttyping
+%D This will never be a \digits{1.000.000} seller.
+%D \stoptyping
+%D
+%D or
+%D
+%D \starttyping
+%D I will never grow longer than \digits 1.86 \Meter.
+%D \stoptyping
+%D
+%D The different modes are shown in:
+%D
+%D \startbuffer
+%D \setdigitmode 1 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 2 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 3 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 4 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 5 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 6 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This is typset as:
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D
+%D The sign can be typeset as is or within the space of a
+%D digit.
+%D
+%D \startbuffer
+%D \setdigitsign 0 \digits +12.345,90
+%D \setdigitmode 1 \digits +12.345,90
+%D \setdigitmode 2 \digits +12.345,90
+%D \setdigitmode 3 \digits +12.345,90
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This is typset as:
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+\chardef\digitoutputmode=1 % 0..6
+\chardef\digitsignmode =0 % 0..3
+
+\def\setdigitmode{\chardef\digitoutputmode}
+\def\setdigitsign{\chardef\digitsignmode}
+
+%D The digit modes are:
+%D
+%D \startitemize[packed]
+%D \item periods \& comma
+%D \item commas \& period
+%D \item thinmuskips \& comma
+%D \item thinmuskips \& period
+%D \item thickmuskips \& comma
+%D \item thickmuskips \& period
+%D \stopitemize
+
+\let\collecteddigits \empty \chardef\digitinputmode =1
+\let\saveddigits \empty \chardef\skipdigit =0
+\let\savedpowerdigits\empty \chardef\powerdigits =0
+
+%D The first stage of the \type {\digit} macro takes care of
+%D the grouped call, the other branch handles the fuzzy
+%D delimited calls.
+
+\ifx\mbox\undefined \let\mbox\normalhbox \fi
+
+% \unexpanded\def\digits
+% {\bgroup\let~@\doifnextbgroupelse\dodigits\grabdigit}
+
+\unexpanded\def\digits
+ {\bgroup
+ \let~@%
+ \doifnextbgroupelse\dodigits{\doifnextcharelse\normalmathshift\domathdigits\grabdigit}}
+
+\def\dodigits#1%
+ {\grabdigit#1\relax}
+
+\def\domathdigits$#1$%
+ {\mbox{\grabdigit#1\relax}} % adding $ $ goes wrong in tabulate
+
+\def\grabdigit
+ {\futurelet\next\scandigit}
+
+%D Watch the test for \type {\nextobeyedline}, because the
+%D endofline token can be \type {\def'd}, not \type {\let}'d,
+%D we need to do an indirect test (see \type {verb-ini.tex})
+%D for details.
+%D
+%D \starttyping
+%D \def ^^M{\obeyedline}
+%D \def\nextbeyedline{\obeyedline}
+%D \stoptyping
+
+\ifx\normalmathshift\undefined \let\normalmathshift=$ \fi
+
+\def\scandigit
+ {\ifx\next\blankspace
+ \let\next\handledigits
+ \else\ifx\next\nextobeyedline % the indirect one
+ \let\next\handledigits
+ \else\ifx\next\bgroup
+ \let\next\handledigits
+ \else\ifx\next\egroup
+ \let\next\handledigits
+ \else\ifx\next\normalmathshift
+ \let\next\handledigits
+ \else
+ \let\next\collectdigit
+ \fi\fi\fi\fi\fi
+ \next}
+
+%D We store the power||of||ten (to be signaled by \type {^},
+%D \type {e} or~\type {E}) in a seperate macro so that we can
+%D typeset it in superscript. The space placeholders are
+%D replaced by a \type {@}.
+
+\def\savedigit#1#2%
+ {\edef#1{#1\saveddigits#2}\let\saveddigits\empty}
+
+\long\def\collectdigit#1%
+ {\ifx#1~%
+ \savedigit\collecteddigits @%
+ \else\if#1_%
+ \savedigit\collecteddigits @%
+ \else\if\noexpand#1\relax
+ \let\grabdigit\handledigits
+ \else\ifcase\powerdigits
+ \if#1E%
+ \chardef\powerdigits\plusone
+ \else\if#1e%
+ \chardef\powerdigits\plusone
+ \else\if#1^%
+ \chardef\powerdigits\plusone
+ \else
+ \savedigit\collecteddigits#1%
+ %\doifnumberelse{#1}
+ % {\savedigit\collecteddigits#1}
+ % {\def\saveddigits{#1}}%
+ \fi\fi\fi
+ \else
+ \savedigit\savedpowerdigits#1%
+ %\doifnumberelse{#1}
+ % {\savedigit\savedpowerdigits#1}
+ % {\def\saveddigits{#1}}%
+ \fi\fi\fi\fi
+ \grabdigit}
+
+\let\handlemathdigits\firstofoneargument
+\let\handletextdigits\mathematics
+
+\def\handledigits
+ {%\ifcase\powerdigits
+ % \edef\collecteddigits{\collecteddigits\saveddigits}%
+ %\else
+ % \edef\savedpowerdigits{\savedpowerdigits\saveddigits}%
+ %\fi
+ \ifmmode
+ \handlemathdigits{\dohandledigits}%
+ \else
+ \dontleavehmode\hbox{\handletextdigits{\dohandledigits}}%
+ \fi
+ \egroup}
+
+%D Although we could do with one pass, a second pass for
+%D handling the stored sequence is more readable.
+
+\ifnum\texengine=\luatexengine
+
+ \def\dohandledigits
+ {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded
+ \expandafter\handletokens\collecteddigits\with\scandigits
+ \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+
+ \chardef\mathaxisfontid\zerocount
+
+\else
+
+ \def\dohandledigits
+ {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded
+ \expandafter\handletokens\collecteddigits\with\scandigits
+ \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+
+ \chardef\mathaxisfontid\plustwo
+
+\fi
+
+\def\doscandigit#1%
+ {\ifcase\skipdigit\@EA\hbox\else\@EA\hphantom\fi\bgroup
+ \mathematics % brr, needed because of stored punctuation
+ {\ifnum\digitinputmode=#1\relax
+ \ifcase\digitoutputmode
+ \or .%
+ \or ,%
+ \or \mskip\thinmuskip
+ \or \mskip\thinmuskip
+ \or \mskip\thickmuskip
+ \or \mskip\thickmuskip
+ \fi
+ \else
+ \ifodd\digitoutputmode,\else.\fi
+ \fi}%
+ \egroup}
+
+%D The signs can be made smaller and sqeezed into the width
+%D of a digit. Watch the \type {\mathaxisheight} trickery (this
+%D font related register stored the math axis).
+
+% 0,=
+% 0,== second = results in delta(00,=)
+% 0,- is invalid, should be =
+% 0,-- is invalid, should be ==
+
+\def\digitzeroamount
+ {\digitsgn\zeroamount
+ \def\digitzeroamount
+ {\hphantom
+ {00\setbox\scratchbox\hbox{$\zeroamount$}%
+ \hskip-\wd\scratchbox}%
+ \let\digitzeroamount\empty}}
+
+\def\scandigits#1%
+ {\if#1.\digitsep1\else
+ \if#1,\digitsep2\else
+ \if#1@\digitnop \else
+ \if#1_\digitnop \else
+ \if#1/\digitsgn{\hphantom{+}}\chardef\skipdigit0\else
+ \if#1-\ifcase\skipdigit\digitsgn-\else
+ \box\digitsepbox\digitzeroamount \fi\chardef\skipdigit0\else
+ \if#1+\digitsgn+\chardef\skipdigit0\else
+ \if#1=\box\digitsepbox\digitzeroamount \chardef\skipdigit0\else
+ \if#1s\digitsgn{\hphantom{\positive}}\chardef\skipdigit0\else
+ \if#1p\digitsgn\positive\chardef\skipdigit0\else
+ \if#1m\digitsgn\negative\chardef\skipdigit0\else
+ \if#1n\digitsgn\negative\chardef\skipdigit0\else
+ \box\digitsepbox #1\chardef\skipdigit0\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+\newbox\digitsepbox \chardef\autodigitmode=1
+
+\def\digitsep#1%
+ {\ifcase\autodigitmode
+ \doscandigit#1%
+ \else
+ \setbox\digitsepbox\hbox{\doscandigit#1}%
+ \fi
+ \chardef\skipdigit0\relax}
+
+% strange, does not work
+%
+% \def\digitnop
+% {\hphantom{\box\digitsepbox}%
+% \hphantom{0}\chardef\skipdigit1\relax}
+%
+% while this works
+
+\def\digitnop
+ {\hbox{\hphantom{\box\digitsepbox}}%
+ \hphantom{0}\chardef\skipdigit1\relax}
+
+% but this doesn't
+%
+% \def\digitnop
+% {\hphantom{\box\digitsepbox0}%
+% \chardef\skipdigit1\relax}
+
+\def\digitsgn#1%
+ {\ifcase\digitsignmode#1\else
+ \hbox
+ {\setbox\scratchbox\hbox{0}%
+ \scratchdimen\mathaxisheight\textfont\mathaxisfontid
+ \def\digitsgn##1##2%
+ {\advance\scratchdimen-\mathaxisheight##1\mathaxisfontid
+ \raise\scratchdimen
+ \hbox to \wd\scratchbox{\hss$##2#1$\hss}}%
+ \ifcase\digitsignmode\or
+ \digitsgn\textfont \textstyle \or
+ \digitsgn\scriptfont \scriptstyle \or
+ \digitsgn\scriptscriptfont\scriptscriptstyle\fi}%
+ \fi}
+
+\ifx\undefined\zeroamount \def\zeroamount{-} \fi
+\ifx\undefined\positive \def\positive {+} \fi
+\ifx\undefined\negative \def\negative {-} \fi
+
+%D The digit parser handles a bunch of special characters as
+%D well as different formats. We strongly suggest you to use
+%D the grouped call.
+%D
+%D \starttabulate[|l|l|l|]
+%D \NC \type{.} \NC , . \NC comma or period \NC \NR
+%D \NC \type{,} \NC , . \NC comma or period \NC \NR
+%D \NC \type{@} \NC \NC invisible space \NC \NR
+%D \NC \type{_} \NC \NC invisible space \NC \NR
+%D \NC \type{/} \NC \NC invisible sign \NC \NR
+%D \NC \type{-} \NC $-$ \NC minus sign \NC \NR
+%D \NC \type{+} \NC $+$ \NC plus sign \NC \NR
+%D \NC \type{s} \NC \NC invisible high sign \NC \NR
+%D \NC \type{p} \NC $\positive$ \NC high plus sign \NC \NR
+%D \NC \type{m} \NC $\negative$ \NC high minus sign \NC \NR
+%D \NC \type{n} \NC $\negative$ \NC high minus (negative) sign \NC \NR
+%D \NC \type{=} \NC $\zeroamount$ \NC zero padding \NC \NR
+%D \stoptabulate
+%D
+%D These triggers are used in the following examples.
+%D
+%D \startbuffer
+%D \digits 12
+%D \digits{~~~.~~~.~~~.68.712,34}
+%D \digits ~~~.~~~.~~~.68.712,34
+%D \digits ___.___.111.68.712,34
+%D \digits 111.111.111.68.712,34
+%D \digits 12.345,90
+%D \digits 12.345.000
+%D \digits 12,34
+%D \digits{392.857.230.68.712,34}
+%D {\digits1234}
+%D \digits{1234}
+%D \digits 1234\relax
+%D $\digits 123.222,00$
+%D \digits 123.222,00
+%D \digits 123.222,==
+%D \digits 123.222,00^10
+%D \digits 123.222,00e10
+%D \digits /123.222,00e-12
+%D \digits -123.222,00e-12
+%D \digits +123.222,00e-12
+%D \digits n123.222,00e-12
+%D \digits s123.222,00e-12
+%D \digits p123.222,00e-12
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+%D \macros
+%D {Digits}
+%D
+%D We also permit:
+
+\let\Digits\digits
+
+%D These macros are complicated by the fact that we also
+%D have to support cases like:
+%D
+%D \starttyping
+%D {\digits1234}
+%D \digits{1234}
+%D \digits 1234\whatever
+%D $\digits 123.222,00$
+%D \digits 123.222,00.
+%D \stoptyping
+%D
+%D The latter case shows us that trailing non digits are to
+%D be passed untreated.
+%D
+%D Another interesting case is:
+%D
+%D \starttyping
+%D \digits 123.222,00^10
+%D \stoptyping
+%D
+%D The separator is defined as:
+
+% \def\digitpowerseparator%
+% {\cdot10} % {\times10}
+
+\def\digitpowerseparator
+ {\ifx\collecteddigits\empty\else\cdot\fi10}
+
+%D \macros
+%D {digittemplate}
+%D
+%D Users can specify the way they enter those digits by saying
+%D something like:
+%D
+%D \starttyping
+%D \digittemplate 12.000.000,00 % \digittemplate .,
+%D \stoptyping
+
+\def\digittemplate #1 %
+ {\chardef\digitinputmode\zerocount
+ \handletokens#1\with\scandigittemplate}
+
+\def\scandigittemplate#1%
+ {\if #1.\ifcase\digitinputmode\chardef\digitinputmode\plusone \fi% period
+ \else\if#1,\ifcase\digitinputmode\chardef\digitinputmode\plustwo \fi% comma
+ \fi\fi}
+
+\protect \endinput
+
+
+\endinput
+
+\def\digitszeropadding {\zeroamount}
+\def\digitsnegative {\mathematics\negative}
+\def\digitspositive {\mathematics\positive}
+\def\digitsspace {\hphantom{0}}
+\def\digitsseparatorspace{\hphantom{.}}
+\def\digitssignspace {\hphantom{+}}
+\def\digitshighspace {\hphantom{\mathematics\positive}}
+\def\digitspower {\high}
+
+\starttext
+
+% print(table.serialize(table.keys(jobs)))
+
+local P, S, R, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.Cs
+
+local done = false
+local swap = false
+local digit = R("09")
+local sign = S("+-")
+local power = S("^e")
+local space = S(" ~@_")
+local comma = P(",")
+local period = P(".")
+local signspace = P("/")
+local positive = P("p")
+local negative = P("n")
+local highspace = P("s")
+local padding = P("=")
+
+local space = space / "\\digitsspace"
+local digit = digit / function(s) done = true return s end
+local separator = comma / function(s) if not done then return "\\digitsseparatorspace" elseif swap then return "." else return "," end end
+ + period / function(s) if not done then return "\\digitsseparatorspace" elseif swap then return "," else return "." end end
+local signspace = signspace / "\\digitssignspace"
+local positive = positive / "\\digitspositive"
+local negative = negative / "\\digitsnegative"
+local highspace = highspace / "\\digitshighspace"
+local power = power/"" * (Cs((sign + signspace)^0 * digit^1) / function(s) return "\\digitspower{" .. s .. "}" end)
+local padding = padding / "\\digitszeropadding"
+
+local replace = lpeg.Cs (
+ (sign + signspace + positive + negative + highspace)^0
+ * (separator^0 * (space + digit)^1)^1
+ * power^0
+)
+
+local function digits(str)
+ done = false
+--~ swap = true
+ local str = lpeg.match(replace,str)
+-- print(str)
+ tex.sprint(tex.ctxcatcodes,"\\dontleavehmode",str,"\\par")
+end
+-- namespaces.register("digits")
+
+digits("12")
+digits("~~~.~~~.~~~.68.712,34")
+digits("~~~.~~~.~~~.68.712,34")
+digits("___.___.111.68.712,34")
+digits("111.111.111.68.712,34")
+digits("12.345,90")
+digits("12.345.000")
+digits("12,34")
+digits("392.857.230.68.712,34")
+digits("1234")
+digits("123.222,00")
+digits("123.222,==")
+digits("123.222,00^10")
+digits("123.222,00e10")
+digits("/123.222,00e-12")
+digits("-123.222,00e-12")
+-- digits("+123.222,00e-12")
+digits("n123.222,00e-12")
+digits("s123.222,00e-12")
+digits("p123.222,00e/12")
+
+\stopluacode
+[[\digitsseparatorspace]]
+\stoptext
+
+
diff --git a/tex/context/base/supp-vis.tex b/tex/context/base/supp-vis.mkii
index f38c8e1e3..f38c8e1e3 100644
--- a/tex/context/base/supp-vis.tex
+++ b/tex/context/base/supp-vis.mkii
diff --git a/tex/context/base/supp-vis.mkiv b/tex/context/base/supp-vis.mkiv
new file mode 100644
index 000000000..f38c8e1e3
--- /dev/null
+++ b/tex/context/base/supp-vis.mkiv
@@ -0,0 +1,1907 @@
+%D \module
+%D [ file=supp-vis,
+%D version=1996.10.21,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Visualization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% no longer generic, who cares ...
+
+%D \gdef\ShowBufferedExample% private typeseting macro
+%D {\startlinecorrection
+%D \bgroup
+%D \setuptyping[margin=0pt,option=color]
+%D \showmakeup
+%D \centeredvcuetrue
+%D \dontinterfere
+%D \baselinerulefalse
+%D \normalvbox
+%D {\normalhbox to \hsize
+%D {$\hsize=.5\hsize
+%D \advance\hsize by -.5em
+%D \normalvcenter{\vbox{\getbuffer}}\normalhss
+%D \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}}
+%D \egroup
+%D \stoplinecorrection}
+%D
+%D \gdef\ShowBufferedExampleBox% private typeseting macro
+%D {\startlinecorrection
+%D \bgroup
+%D \setuptyping[margin=0pt,option=color]
+%D \showmakeup
+%D \centeredvcuetrue
+%D \dontinterfere
+%D \baselinerulefalse
+%D \normalvbox
+%D {\normalhbox to \hsize
+%D {$\hsize=.5\hsize
+%D \advance\hsize by -.5em
+%D \normalvcenter{\baselineruletrue\vbox{\getbuffer}}\normalhss
+%D \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}}
+%D \egroup
+%D \stoplinecorrection}
+
+%D Although an integral part of \CONTEXT, this module is one
+%D of the support modules. Its stand alone character permits
+%D use in \PLAIN\ \TEX\ or \TEX\ based macropackages.
+%D \ifCONTEXT \else If in some examples the verbatim listings
+%D don't show up nice, this is due to processing by a system
+%D that does not support buffering. In \CONTEXT\ we show the
+%D commands in the margin, use bit more advanced way of
+%D numbering, and typeset the source in \TEX nicolored
+%D verbatim. Sorry for this inconvenience.\fi
+%D
+%D Depending on my personal needs and those of whoever uses it,
+%D the macros will be improved in terms of visualization,
+%D efficiency and compatibility. These rather low level
+%D visualization macros are supplemented by ones that can
+%D visualize baselines, the page layout and whatever deserves
+%D attention. Most of those macros can be found in \type
+%D {core-vis} and other core modules. Their integration in
+%D \CONTEXT\ prohibits generic applications.
+
+\ifx \undefined \writestatus \input supp-mis.tex \fi
+
+%D One of the strong points of \TEX\ is abstraction of textual
+%D input. When macros are defined well and do what we
+%D want them to do, we will seldom need the tools present in
+%D What You See Is What You Get systems. For instance, when
+%D entering text we don't need rulers, because no manual
+%D shifting and/or alignment of text is needed. On the other
+%D hand, when we are designing macros or specifying layout
+%D elements, some insight in \TEX's advanced spacing, kerning,
+%D filling, boxing and punishment abilities will be handy.
+%D That's why we've implemented a mechanism that shows some of
+%D the inner secrets of \TEX.
+
+\writestatus{loading}{ConTeXt Support Macros / Visualization}
+
+%D In this module we are going to redefine some \TEX\
+%D primitives and \PLAIN\ macro's. Their original meaning is
+%D saved in macros with corresponding names, preceded by
+%D \type{normal}. These original macros are (1)~used to
+%D temporary restore the old values when needed and
+%D (2)~used to prevent recursive calls in the macros that
+%D replace them.
+
+\unprotect
+
+\let\visualvrule\vrule
+\let\visualhrule\hrule
+
+%D \macros
+%D {dontinterfere}
+%D
+%D Indentation, left and/or right skips, redefinition of
+%D \type{\par} and assignments to \type{\everypar} can lead to
+%D unwanted results. We can therefore turn all those things
+%D off with \type{\dontinterfere}.
+
+\def\dontinterfere
+ {\everypar \emptytoks
+ \let\par \endgraf
+ \parindent\zeropoint
+ \parskip \zeropoint
+ \leftskip \zeropoint
+ \rightskip\zeropoint
+ \relax}
+
+%D \macros
+%D {dontcomplain}
+%D
+%D In this module we do a lot of box manipulations. Because we
+%D don't want to be confronted with to many over- and underfull
+%D messages we introduce \type{\dontcomplain}.
+
+\def\dontcomplain
+ {\hbadness\!!tenthousand \vbadness\hbadness
+ \hfuzz \maxdimen \vfuzz \hfuzz}
+
+% This obsolete dutch name is sometimes uses in manual styles; when
+% cleaning up the codebase I decided to move this definition here.
+
+\let\mindermeldingen\dontcomplain
+
+%D \macros
+%D {normaloffinterlineskip}
+%D
+%D The next hack is needed because in \CONTEXT\ we redefine
+%D \type{\offinterlineskip}.
+
+\ifx\undefined\normaloffinterlineskip
+ \let\normaloffinterlineskip\offinterlineskip
+\fi
+
+%D \macros
+%D {normalhbox,
+%D normalvbox,normalvtop}
+%D
+%D There are three types of boxes, one horizontal and two
+%D vertical in nature. As we will see later on, all three types
+%D are to be handled according to their orientation and
+%D baseline behavior. Especially \type{\vtop}'s need our
+%D special attention.
+
+% already saved
+
+%D \macros
+%D {normalhskip,
+%D normalvskip}
+%D
+%D Next come the flexible skips, which come in two flavors
+%D too. Like boxes these are handled with \TEX\ primitives.
+
+% already saved
+
+%D \macros
+%D {normalpenalty,
+%D normalkern}
+%D
+%D Both penalties and kerns are taken care of by mode sensitive
+%D primitives. This means that when making them visible, we
+%D have to take the current mode into account.
+
+% already saved
+
+%D \macros
+%D {normalhglue,
+%D normalvglue}
+%D
+%D Glues on the other hand are macro's defined in \PLAIN\ \TEX.
+%D As we will see, their definitions make the implementation of
+%D their visible counterparts a bit more \TeX{}nical.
+
+\let\normalhglue = \hglue
+\let\normalvglue = \vglue
+
+%D \macros
+%D {normalmkern,
+%D normalmskip}
+%D
+%D Math mode has its own spacing primitives, preceded by
+%D \type{m}. Due to the relation with the current font and the
+%D way math is typeset, their unit \type{mu} is not compatible
+%D with other dimensions. As a result, the visual appearance
+%D of these primitives is kept primitive too.
+
+% already saved
+
+%D \macros
+%D {hfilneg,
+%D vfilneg}
+%D
+%D Fills can be made visible quite easy. We only need some
+%D additional negation macros. Because \PLAIN\ \TEX\ only
+%D offers \type{\hfilneg} and \type{\vfilneg}, we define our
+%D own alternative double \type{ll}'ed ones.
+
+\def\hfilneg {\normalhskip\zeropoint \!!plus-1fil\relax}
+\def\vfilneg {\normalvskip\zeropoint \!!plus-1fil\relax}
+\def\hfillneg {\normalhskip\zeropoint \!!plus-1fill\relax}
+\def\vfillneg {\normalvskip\zeropoint \!!plus-1fill\relax}
+\def\hfilllneg{\normalhskip\zeropoint \!!plus-1filll\relax}
+\def\vfilllneg{\normalvskip\zeropoint \!!plus-1filll\relax}
+
+%D \macros
+%D {normalhss,normalhfil,normalhfill,
+%D normalvss,normalvfil,normalvfill}
+%D
+%D The positive stretch primitives are used independant and in
+%D combination with \type{\leaders}.
+
+% already saved
+
+%D \macros
+%D {normalhfilneg,normalhfillneg,
+%D normalvfilneg,normalvfillneg}
+%D
+%D Keep in mind that both \type{\hfillneg} and \type{\vfillneg}
+%D are not part of \PLAIN\ \TEX\ and therefore not documented
+%D in standard \TEX\ documentation. They can nevertheless be
+%D used at will.
+
+\let\normalhfillneg = \hfillneg
+\let\normalvfillneg = \vfillneg
+
+%D Visualization is not always wanted. Instead of turning this
+%D option off in those (unpredictable) situations, we just
+%D redefine a few \PLAIN\ macros.
+
+\ifx\tlap\undefined
+
+ \def\rlap#1{\normalhbox to \zeropoint{#1\normalhss}}
+ \def\llap#1{\normalhbox to \zeropoint{\normalhss#1}}
+ \def\blap#1{\normalvbox to \zeropoint{#1\normalvss}}
+ \def\tlap#1{\normalvbox to \zeropoint{\normalvss#1}}
+
+\fi
+
+\ifx\contextversion\undefined \def~{\normalpenalty\!!tenthousand\ } \fi
+
+%D \macros
+%D {makeruledbox}
+%D
+%D Ruled boxes can be typeset is many ways. Here we present
+%D just one alternative. This implementation may be a little
+%D complicated, but it supports all three kind of boxes. The
+%D next command expects a \BOX\ specification, like:
+%D
+%D \starttyping
+%D \makeruledbox0
+%D \stoptyping
+
+%D \macros
+%D {baselinerule,baselinefill}
+%D
+%D We can make the baseline of a box visible, both dashed and
+%D as a rule. The line is drawn on top of the baseline. All
+%D we have to say is:
+%D
+%D \starttyping
+%D \baselineruletrue
+%D \baselinefilltrue
+%D \stoptyping
+%D
+%D At the cost of some overhead these alternatives are
+%D implemented using \type{\if}'s:
+
+\newif\ifbaselinerule \baselineruletrue
+\newif\ifbaselinefill \baselinefillfalse
+
+%D \macros
+%D {iftoprule,ifbottomrule,ifleftrule,ifrightrule}
+%D
+%D Rules can be turned on and off, but by default we have:
+%D
+%D \starttyping
+%D \topruletrue
+%D \bottomruletrue
+%D \leftruletrue
+%D \rightruletrue
+%D \stoptyping
+%D
+%D As we see below:
+
+\newif\iftoprule \topruletrue
+\newif\ifbottomrule \bottomruletrue
+\newif\ifleftrule \leftruletrue
+\newif\ifrightrule \rightruletrue
+
+%D \macros
+%D {boxrulewidth}
+%D
+%D The width in the surrounding rules can be specified by
+%D assigning an apropriate value to the dimension used. This
+%D module defaults the width to:
+%D
+%D \starttyping
+%D \boxrulewidth=.2pt
+%D \stoptyping
+%D
+%D Although we are already low on \DIMENSIONS\ it's best to
+%D spend one here, mainly because it enables easy manipulation,
+%D like multiplication by a given factor.
+
+\newdimen\boxrulewidth \boxrulewidth=.2pt
+
+%D The core macro \type{\makeruledbox} looks a bit hefty. The
+%D manipulation at the end is needed because we want to
+%D preserve both the mode and the baseline. This means that
+%D \type{\vtop}'s and \type{\vbox}'es behave the way we expect
+%D them to do.
+%D
+%D \startlinecorrection
+%D \hbox
+%D {\ruledhbox to 5em{\strut test\normalhss}\hskip1em
+%D \ruledvbox{\hsize 5em\strut test \par test\strut}\hskip1em
+%D \ruledvtop{\hsize 5em\strut test \par test\strut}}
+%D \stoplinecorrection
+%D
+%D The \type{\cleaders} part of the macro is responsible for
+%D the visual baseline. The \type{\normalhfill} belongs to this
+%D primitive too. By storing and restoring the height and depth
+%D of box \type{#1}, we preserve the mode.
+
+\let\dowithruledbox\relax
+
+\let\ruledheight\!!zeropoint
+\let\ruleddepth \!!zeropoint
+\let\ruledwidth \!!zeropoint
+
+\def\makeruledbox#1%
+ {\edef\ruledheight{\the\ht#1}%
+ \edef\ruleddepth {\the\dp#1}%
+ \edef\ruledwidth {\the\wd#1}%
+ \setbox\scratchbox\normalvbox
+ {\dontcomplain
+ \normaloffinterlineskip
+ \visualhrule
+ \!!height\boxrulewidth
+ \iftoprule\else\!!width\zeropoint\fi
+ \normalvskip-\boxrulewidth
+ \normalhbox to \ruledwidth
+ {\visualvrule
+ \!!height\ruledheight
+ \!!depth\ruleddepth
+ \!!width\ifleftrule\else0\fi\boxrulewidth
+ \ifdim\ruledheight>\zeropoint \else \baselinerulefalse \fi
+ \ifdim\ruleddepth>\zeropoint \else \baselinerulefalse \fi
+ \ifbaselinerule
+ \ifdim\ruledwidth<20\boxrulewidth
+ \baselinefilltrue
+ \fi
+ \cleaders
+ \ifbaselinefill
+ \visualhrule
+ \!!height\boxrulewidth
+ \else
+ \normalhbox
+ {\normalhskip2.5\boxrulewidth
+ \visualvrule
+ \!!height\boxrulewidth
+ \!!width5\boxrulewidth
+ \normalhskip2.5\boxrulewidth}%
+ \fi
+ \fi
+ \normalhfill
+ \visualvrule
+ \!!width\ifrightrule\else0\fi\boxrulewidth}%
+ \normalvskip-\boxrulewidth
+ \visualhrule
+ \!!height\boxrulewidth
+ \ifbottomrule\else\!!width\zeropoint\fi}%
+ \wd#1\zeropoint
+ \setbox#1=\ifhbox#1\normalhbox\else\normalvbox\fi
+ {\normalhbox
+ {\box#1%
+ \lower\ruleddepth\normalhbox{\dowithruledbox{\box\scratchbox}}}}%
+ \ht#1=\ruledheight
+ \wd#1=\ruledwidth
+ \dp#1=\ruleddepth}
+
+%D Just in case one didn't notice: the rules are in fact layed
+%D over the box. This way the contents of a box cannot
+%D visually interfere with the rules around (upon) it. A more
+%D advanced version of ruled boxes can be found in one of the
+%D core modules of \CONTEXT. There we take offsets, color,
+%D rounded corners, backgrounds and alignment into account too.
+
+%D \macros
+%D {ruledhbox,
+%D ruledvbox,ruledvtop,
+%D ruledvcenter}
+%D
+%D These macro's can be used instead of \type{\hbox},
+%D \type{\vbox}, \type{\vtop} and, when in math mode,
+%D \type{\vcenter}. They just do what their names state. Using
+%D an auxiliary macro would save us a few words of memory, but
+%D it would make their appearance even more obscure.
+%D
+%D \startbuffer
+%D \hbox
+%D {\strut
+%D one
+%D two
+%D \hbox{three}
+%D four
+%D five}
+%D \stopbuffer
+%D
+%D \ShowBufferedExampleBox
+
+\unexpanded\def\ruledhbox
+ {\normalhbox\bgroup
+ \dowithnextbox{\makeruledbox\nextbox\box\nextbox\egroup}%
+ \normalhbox}
+
+%D \startbuffer
+%D \vbox
+%D {\strut
+%D first line \par
+%D second line \par
+%D third line \par
+%D fourth line \par
+%D fifth line
+%D \strut }
+%D \stopbuffer
+%D
+%D \ShowBufferedExampleBox
+
+\unexpanded\def\ruledvbox
+ {\normalvbox\bgroup
+ \dowithnextbox{\makeruledbox\nextbox\box\nextbox\egroup}%
+ \normalvbox}
+
+%D \startbuffer
+%D \vtop
+%D {\strut
+%D first line \par
+%D second line \par
+%D third line \par
+%D fourth line \par
+%D fifth line
+%D \strut }
+%D \stopbuffer
+%D
+%D \ShowBufferedExampleBox
+
+\unexpanded\def\ruledvtop
+ {\normalvtop\bgroup
+ \dowithnextbox{\makeruledbox\nextbox\box\nextbox\egroup}%
+ \normalvtop}
+
+%D \startbuffer
+%D \hbox
+%D {$\vcenter{\hsize.2\hsize
+%D alfa \par beta}$
+%D $\vcenter to 3cm{\hsize.2\hsize
+%D alfa \par beta \par gamma}$
+%D $\vcenter{\hsize.2\hsize
+%D alfa \par beta}$}
+%D \stopbuffer
+%D
+%D \ShowBufferedExampleBox
+
+\unexpanded\def\ruledvcenter
+ {\normalvbox\bgroup
+ \dontinterfere
+ \dowithnextbox
+ {\scratchdimen.5\ht\nextbox
+ \advance\scratchdimen .5\dp\nextbox
+ \ht\nextbox\scratchdimen
+ \dp\nextbox\scratchdimen
+ \ruledhbox{\box\nextbox}%
+ \egroup}%
+ \normalvbox}
+
+%D \macros
+%D {ruledbox,
+%D setruledbox}
+%D
+%D Of the next two macros the first can be used to precede a
+%D box of ones own choice. One can for instance prefix boxes
+%D with \type{\ruledbox} and afterwards --- when the macro
+%D satisfy the needs --- let it to \type{\relax}.
+%D
+%D \starttyping
+%D \ruledbox\hbox{What rules do you mean?}
+%D \stoptyping
+%D
+%D The macro \type{\setruledbox} can be used to directly
+%D rule a box.
+%D
+%D \starttyping
+%D \setruledbox12=\hbox{Who's talking about rules here?}
+%D \stoptyping
+%D
+%D At the cost of some extra macros we can implement a
+%D variant that does not need the~\type{=}, but we stick to:
+
+\unexpanded\def\ruledbox
+ {\dowithnextbox{\makeruledbox\nextbox\box\nextbox}}
+
+\def\setruledbox#1=%
+ {\dowithnextbox{\makeruledbox\nextbox\setbox#1\nextbox}}
+
+%D \macros
+%D {investigateskip,
+%D investigatecount,
+%D investigatemuskip}
+%D
+%D Before we meet the visualizing macro's, we first implement
+%D ourselves some handy utility ones. Just for the sake of
+%D efficiency and readability, we introduce some status
+%D variables, that tell us a bit more about the registers we
+%D use:
+%D
+%D \starttyping
+%D \ifflexible
+%D \ifzero
+%D \ifnegative
+%D \ifpositive
+%D \stoptyping
+%D
+%D These status variables are set when we call for one of the
+%D investigation macros, e.g.
+%D
+%D \starttyping
+%D \investigateskip\scratchskip
+%D \stoptyping
+%D
+%D We use some dirty trick to check stretchability of \SKIPS.
+%D Users of these macros are invited to study their exact
+%D behavior first. The positive and negative states both
+%D include zero and are in fact non-negative ($\geq0$) and
+%D non-positive ($\leq0$) .
+
+\newif\ifflexible
+\newif\ifzero
+\newif\ifnegative
+\newif\ifpositive
+
+\def\investigateskip#1%
+ {\relax
+ \scratchdimen#1\relax
+ \edef\!!stringa{\the\scratchdimen}%
+ \edef\!!stringb{\the#1}%
+ \ifx\!!stringa\!!stringb \flexiblefalse \else \flexibletrue \fi
+ \ifdim#1=\zeropoint\relax
+ \zerotrue \else
+ \zerofalse \fi
+ \ifdim#1<\zeropoint\relax
+ \positivefalse \else
+ \positivetrue \fi
+ \ifdim#1>\zeropoint\relax
+ \negativefalse \else
+ \negativetrue \fi}
+
+% etex
+%
+% \def\investigateskip#1%
+% {\relax
+% \ifdim\scratchskip=\zeropoint
+% \ifdim\gluestretch\scratchskip=\zeropoint
+% \ifdim\glueshrink\scratchskip=\zeropoint
+% \flexiblefalse
+% \else
+% \flexibletrue
+% \fi
+% \else
+% \flexibletrue
+% \fi
+% \else
+% \flexibletrue
+% \fi
+% \ifdim#1=\zeropoint\relax
+% \zerotrue \else
+% \zerofalse \fi
+% \ifdim#1<\zeropoint\relax
+% \positivefalse \else
+% \positivetrue \fi
+% \ifdim#1>\zeropoint\relax
+% \negativefalse \else
+% \negativetrue \fi}
+
+\def\investigatecount#1%
+ {\relax
+ \flexiblefalse
+ \ifnum#1=\zerocount
+ \zerotrue \else
+ \zerofalse \fi
+ \ifnum#1<\zerocount
+ \positivefalse \else
+ \positivetrue \fi
+ \ifnum#1>\zerocount
+ \negativefalse \else
+ \negativetrue \fi}
+
+\def\investigatemuskip#1%
+ {\relax
+ \edef\!!stringa{\the\scratchmuskip}%
+ \edef\!!stringb{0mu}%
+ \def\!!stringc##1##2\\{##1}%
+ \expandafter\edef\expandafter\!!stringc\expandafter
+ {\expandafter\!!stringc\!!stringa\\}%
+ \edef\!!stringd{-}%
+ \flexiblefalse
+ \ifx\!!stringa\!!stringb
+ \zerotrue
+ \negativefalse
+ \positivefalse
+ \else
+ \zerofalse
+ \ifx\!!stringc\!!stringd
+ \positivefalse
+ \negativetrue
+ \else
+ \positivetrue
+ \negativefalse
+ \fi
+ \fi}
+
+%D Now the neccessary utility macros are defined, we can make a
+%D start with the visualizing ones. The implementation of these
+%D macros is a compromise between readability, efficiency of
+%D coding and processing speed. Sometimes we do in steps what
+%D could have been done in combination, sometimes we use a few
+%D boxes more or less then actually needed, and more than once
+%D one can find the same piece of rule drawing code twice.
+
+%D \macros
+%D {ifcenteredvcue,normalvcue}
+%D
+%D Depending on the context, one can force visual vertical cues
+%D being centered along \type{\hsize} or being put at the
+%D current position. Although centering often looks better,
+%D we've chosen the second alternative as default. The main
+%D reason for doing so is that often when we don't set the
+%D \type{\hsize} ourselves, \TEX\ takes the value of the
+%D surrounding box. As a result the visual cues can migrate
+%D outside the current context.
+%D
+%D This behavior is accomplished by a small but effective
+%D auxiliary macro, which behavior can be influenced by the
+%D boolean \type{\centeredvcue}. By saying
+%D
+%D \starttyping
+%D \centeredvcuetrue
+%D \stoptyping
+%D
+%D one turns centering on. As said, we turn it off.
+
+\newif\ifcenteredvcue \centeredvcuefalse
+
+\def\normalvcue#1%
+ {\normalhbox \ifcenteredvcue to \hsize \fi {\normalhss#1\normalhss}}
+
+%D We could have used the more robust version
+%D
+%D \starttyping
+%D \def\normalvcue%
+%D {\normalhbox \ifcenteredvcue to \hsize \fi
+%D \bgroup\bgroup\normalhss
+%D \aftergroup\normalhss\aftergroup\egroup
+%D \let\next=}
+%D \stoptyping
+%D
+%D or the probably best one:
+%D
+%D \starttyping
+%D \def\normalvcue%
+%D {\hbox \ifcenteredvcue to \hsize
+%D \bgroup\bgroup\normalhss
+%D \aftergroup\normalhss\aftergroup\egroup
+%D \else
+%D \bgroup
+%D \fi
+%D \let\next=}
+%D \stoptyping
+%D
+%D Because we don't have to preserve \CATCODES\ and only use
+%D small arguments, we stick to the first alternative.
+
+%D \macros
+%D {testrulewidth}
+%D
+%D We build our visual cues out of rules. At the cost of a much
+%D bigger \DVI\ file, this is to be prefered over using
+%D characters (1)~because we cannot be sure of their
+%D availability and (2)~because their dimensions are fixed.
+%D
+%D As with ruled boxes, we use a \DIMENSION\ to specify the
+%D width of the ruled elements. This dimension defaults to:
+%D
+%D \starttyping
+%D \testrulewidth=\boxrulewidth
+%D \stoptyping
+%D
+%D Because we prefer whole numbers for specifying the
+%D dimensions, we often use even multiples of
+%D \type{\testrulewidth}.
+
+%D \macros
+%D {visiblestretch}
+%D
+%D A second variable is introduced because of the stretch
+%D components of \SKIPS. At the cost of some accuracy we can
+%D make this stretch visible.
+%D
+%D \starttyping
+%D \visiblestretchtrue
+%D \stoptyping
+
+\newdimen\testrulewidth \testrulewidth=\boxrulewidth
+\newif\ifvisiblestretch \visiblestretchfalse
+
+%D \macros
+%D {ruledhss,
+%D ruledhfil,ruledhfilneg,
+%D ruledhfill,ruledhfillneg}
+%D
+%D We start with the easiest part, the fills. The scheme we
+%D follow is {\em visual filling -- going back -- normal
+%D filling}. Visualizing is implemented using \type{\cleaders}.
+%D Because the \BOX\ that follows this command is constructed
+%D only once, the \type{\copy} is not really a prerequisite. We
+%D prefer using a \type{\normalhbox} here instead of a
+%D \type{\hbox}.
+
+\def\setvisiblehfilbox#1\to#2#3#4%
+ {\setbox#1\normalhbox
+ {\visualvrule
+ \!!width #2\testrulewidth
+ \!!height#3\testrulewidth
+ \!!depth #4\testrulewidth}%
+ \smashbox#1}
+
+\def\doruledhfiller#1#2#3#4%
+ {#1#2%
+ \bgroup
+ \dontinterfere
+ \dontcomplain
+ \setvisiblehfilbox0\to{4}{#3}{#4}%
+ \setvisiblehfilbox2\to422%
+ \copy0\copy2
+ \bgroup
+ \setvisiblehfilbox0\to422%
+ \cleaders
+ \normalhbox to 12\testrulewidth
+ {\normalhss\copy0\normalhss}%
+ #1%
+ \egroup
+ \setbox0\normalhbox
+ {\normalhskip-4\testrulewidth\copy0\copy2}%
+ \smashbox0%
+ \box0
+ \egroup}
+
+%D The horizontal fillers differ in their boundary
+%D visualization. Watch the small dots. Fillers can be
+%D combined within reasonable margins.
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut\type{\hss}\ruledhss test}
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut\type{\hfil}\ruledhfil test}
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut\type{\hfill}\ruledhfill test}
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut
+%D \type{\hfil}\type{\hfil}\ruledhfil\ruledhfil
+%D test%
+%D \ruledhfil\type{\hfil}}
+%D \stoplinecorrection
+%D
+%D The negative counterparts are visualizes, but seldom
+%D become visible, apart from their boundaries.
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut\type{\hfilneg}\ruledhfilneg test}
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut\type{\hfillneg}\ruledhfillneg test}
+%D \stoplinecorrection
+%D
+%D Although leaders are used for visualizing, they are
+%D visualized themselves correctly as the next example shows.
+%D
+%D \startlinecorrection
+%D \baselinerulefalse
+%D \ruledhbox to \hsize
+%D {\strut\cleaders\normalhbox to 2em{\normalhss$\circ$\normalhss}\ruledhfill}
+%D \stoplinecorrection
+%D
+%D All five substitutions use the same auxiliary macro. Watch
+%D the positive first -- negative next approach.
+
+\unexpanded\def\ruledhss
+ {\doruledhfiller\normalhss\normalhfilneg{0}{0}}
+
+\unexpanded\def\ruledhfil
+ {\doruledhfiller\normalhfil\normalhfilneg{10}{-6}}
+
+\unexpanded\def\ruledhfill
+ {\doruledhfiller\normalhfill\normalhfillneg{18}{-14}}
+
+\unexpanded\def\ruledhfilneg
+ {\doruledhfiller\normalhfilneg\normalhfil{-6}{10}}
+
+\unexpanded\def\ruledhfillneg
+ {\doruledhfiller\normalhfillneg\normalhfill{-14}{18}}
+
+%D \macros
+%D {ruledvss,
+%D ruledvfil,ruledvfilneg,
+%D ruledvfill,ruledvfillneg}
+%D
+%D The vertical mode commands adopt the same visualization
+%D scheme, but are implemented in a slightly different way.
+
+\def\setvisiblevfilbox#1\to#2#3#4%
+ {\setbox#1\normalhbox
+ {\visualvrule
+ \!!width #2\testrulewidth
+ \!!height#3\testrulewidth
+ \!!depth #4\testrulewidth}%
+ \smashbox#1}%
+
+\def\doruledvfiller#1#2#3%
+ {#1#2%
+ \bgroup
+ \dontinterfere
+ \dontcomplain
+ \normaloffinterlineskip
+ \setvisiblevfilbox0\to422%
+ \setbox2\normalvcue
+ {\normalhskip -#3\testrulewidth\copy0}%
+ \smashbox2%
+ \copy2
+ \bgroup
+ \setbox2\normalvcue
+ {\normalhskip -2\testrulewidth\copy0}%
+ \smashbox2%
+ \copy2
+ \cleaders
+ \normalvbox to 12\testrulewidth
+ {\normalvss\copy2\normalvss}%
+ #1%
+ \setbox2\normalvbox
+ {\normalvskip-2\testrulewidth\copy2}%
+ \smashbox2%
+ \box2
+ \egroup
+ \box2
+ \egroup}
+
+%D Because they act the same as their horizontal counterparts
+%D we only show a few examples.
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {\dontinterfere
+%D \baselinerulefalse
+%D \centeredvcuetrue
+%D \ruledvbox to 10ex
+%D {\hsize.18\hsize
+%D \type{\vss}\ruledvss last line}\normalhss
+%D \ruledvbox to 10ex
+%D {\hsize.18\hsize
+%D \type{\vfil}\ruledvfil last line}\normalhss
+%D \ruledvbox to 10ex
+%D {\hsize.18\hsize
+%D \type{\vfill}\ruledvfill last line}\normalhss
+%D \ruledvbox to 10ex
+%D {\hsize.18\hsize
+%D \type{\vfilneg}\ruledvfilneg last line}\normalhss
+%D \ruledvbox to 10ex
+%D {\hsize.18\hsize
+%D \type{\vfillneg}\ruledvfillneg last line}}
+%D \stoplinecorrection
+%D
+%D Keep in mind that \type{\vfillneg} is not part of \PLAIN\
+%D \TEX, but are mimmicked by a macro.
+
+\unexpanded\def\ruledvss {\doruledvfiller\normalvss \normalvfilneg {2}}
+\unexpanded\def\ruledvfil {\doruledvfiller\normalvfil \normalvfilneg {-4}}
+\unexpanded\def\ruledvfill {\doruledvfiller\normalvfill \normalvfillneg{-12}}
+\unexpanded\def\ruledvfilneg {\doruledvfiller\normalvfilneg \normalvfil {8}}
+\unexpanded\def\ruledvfillneg{\doruledvfiller\normalvfillneg\normalvfill {16}}
+
+%D \macros
+%D {ruledhskip}
+%D
+%D Skips differ from kerns in two important aspects:
+%D
+%D \startitemize[packed]
+%D \item line and pagebreaks are allowed at a skip
+%D \item skips can have a positive and/or negative
+%D stretchcomponent
+%D \stopitemize
+%D
+%D Stated a bit different: kerns are fixed skips at which no
+%D line or pagebreak can occur. Because skips have a more open
+%D character, they are visualized in a open way.
+%D
+%D \startbuffer
+%D one
+%D \hskip +30pt plus 5pt
+%D two
+%D \hskip +30pt
+%D \hskip -10pt plus 5pt
+%D three
+%D \hskip 0pt
+%D four
+%D \hskip +30pt
+%D five
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+%D
+%D When skips have a stretch component, this is visualized by
+%D means of a dashed line. Positive skips are on top of the
+%D baseline, negative ones are below it. This way we can show
+%D the combined results. An alternative visualization of
+%D stretch could be drawing the mid line over a length of the
+%D stretch, in positive or negative direction.
+
+\def\doruledhskip
+ {\relax
+ \dontinterfere
+ \dontcomplain
+ \investigateskip\scratchskip
+ \ifzero
+ \setbox0\normalhbox
+ {\normalhskip-\testrulewidth
+ \visualvrule
+ \!!width4\testrulewidth
+ \!!height16\testrulewidth
+ \!!depth16\testrulewidth}%
+ \else
+ \setbox0\normalhbox to \ifnegative-\fi\scratchskip
+ {\visualvrule
+ \!!width2\testrulewidth
+ \ifnegative\!!depth\else\!!height\fi16\testrulewidth
+ \cleaders
+ \visualhrule
+ \ifnegative
+ \!!depth2\testrulewidth
+ \!!height\zeropoint
+ \else
+ \!!height2\testrulewidth
+ \!!depth\zeropoint
+ \fi
+ \normalhfill
+ \ifflexible
+ \normalhskip\ifnegative\else-\fi\scratchskip
+ \normalhskip2\testrulewidth
+ \cleaders
+ \normalhbox
+ {\normalhskip 2\testrulewidth
+ \visualvrule
+ \!!width2\testrulewidth
+ \!!height\ifnegative-7\else9\fi\testrulewidth
+ \!!depth\ifnegative9\else-7\fi\testrulewidth
+ \normalhskip 2\testrulewidth}%
+ \normalhfill
+ \fi
+ \visualvrule
+ \!!width2\testrulewidth
+ \ifnegative\!!depth\else\!!height\fi16\testrulewidth}%
+ \setbox0\normalhbox
+ {\ifnegative\else\normalhskip-\scratchskip\fi
+ \box0}%
+ \fi
+ \smashbox0%
+ \ifvisiblestretch \else
+ \flexiblefalse
+ \fi
+ \ifflexible
+ % breaks ok but small displacements can occur
+ \skip2\scratchskip
+ \advance\skip2 -1\scratchskip
+ \divide\skip2 2
+ \advance\scratchskip -\skip2
+ \normalhskip\scratchskip
+ \normalpenalty\!!tenthousand
+ \box0
+ \normalhskip\skip2
+ \else
+ \normalhskip\scratchskip
+ \box0
+ \fi
+ \egroup}
+
+\unexpanded\def\ruledhskip
+ {\bgroup
+ \afterassignment\doruledhskip
+ \scratchskip=}
+
+%D The visual skip is located at a feasible point. Normally
+%D this does not interfere with the normaltypesetting process.
+%D The next examples show (1)~the default behavior, (2)~the
+%D (not entirely correct) distributed stretch and (3)~the way
+%D the text is typeset without cues.
+%D
+%D \startbuffer
+%D \dorecurse
+%D {15}
+%D {test\hskip1em plus .5em minus .5em
+%D test\hskip2em
+%D test}
+%D \stopbuffer
+%D
+%D \startlinecorrection
+%D \showmakeup
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \showmakeup
+%D \visiblestretchtrue
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+
+%D \macros
+%D {ruledvskip}
+%D
+%D We are less fortunate when implementing the vertical skips.
+%D This is a direct result of interference between the boxes that
+%D visualize the skip and skip removal at a pagebreak. Normally
+%D skips disappear at the top of a page, but not of course when
+%D visualized in a \type{\vbox}. A quite perfect simulation
+%D could have been built if we would have had available two
+%D more primitives: \type{\hnop} and \type{\vnop}. These new
+%D primitives could stand for boxes that are visible but are
+%D not taken into account in any way. They are there for us,
+%D but not for \TEX.
+%D
+%D \startbuffer
+%D first line
+%D \vskip +30pt plus 5pt
+%D second line
+%D \vskip +30pt
+%D \vskip -10pt plus 5pt
+%D third line
+%D \par
+%D fourth line
+%D \vskip +30pt
+%D fifth line
+%D \vskip 0pt
+%D sixth line
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+%D
+%D We have to postpone \type{\prevdepth}. Although this
+%D precaution probably is not completely waterproof, it works
+%D quite well.
+
+\def\dodoruledvskip
+ {\nextdepth\prevdepth
+ \dontinterfere
+ \dontcomplain
+ \normaloffinterlineskip
+ \investigateskip\scratchskip
+ \ifzero
+ \setbox0\normalvcue
+ {\visualvrule
+ \!!width32\testrulewidth
+ \!!height2\testrulewidth
+ \!!depth2\testrulewidth}%
+ \else
+ \setbox0\normalvbox to \ifnegative-\fi\scratchskip
+ {\visualhrule
+ \!!width16\testrulewidth
+ \!!height2\testrulewidth
+ \ifflexible
+ \cleaders
+ \normalhbox to 16\testrulewidth
+ {\normalhss
+ \normalvbox
+ {\normalvskip 2\testrulewidth
+ \visualhrule
+ \!!width2\testrulewidth
+ \!!height2\testrulewidth
+ \normalvskip 2\testrulewidth}%
+ \normalhss}%
+ \normalvfill
+ \else
+ \normalvfill
+ \fi
+ \visualhrule
+ \!!width16\testrulewidth
+ \!!height2\testrulewidth}%
+ \setbox2\normalvbox to \ht0
+ {\visualhrule
+ \!!width2\testrulewidth
+ \!!height\ht0}%
+ \ifnegative
+ \ht0\zeropoint
+ \setbox0\normalhbox
+ {\normalhskip2\testrulewidth % will be improved
+ \normalhskip-\wd0\box0}%
+ \fi
+ \smashbox0%
+ \smashbox2%
+ \setbox0\normalvcue
+ {\box2\box0}%
+ \setbox0\normalvbox
+ {\ifnegative\normalvskip\scratchskip\fi\box0}%
+ \smashbox0%
+ \fi
+ \ifvisiblestretch
+ \ifflexible
+ \skip2\scratchskip
+ \advance\skip2 -1\scratchskip
+ \divide\skip2 2
+ \advance\scratchskip -\skip2
+ \normalvskip\skip2
+ \fi
+ \fi
+ \normalpenalty\!!tenthousand
+ \box0
+ \prevdepth\nextdepth % not \dp0=\nextdepth
+ \normalvskip\scratchskip}
+
+%D We try to avoid interfering at the top of a page. Of course
+%D we only do so when we are in the main vertical list.
+
+\def\doruledvskip
+ {\endgraf % \par
+ \ifdim\pagegoal=\maxdimen
+ \ifinner
+ \dodoruledvskip
+ \fi
+ \else
+ \dodoruledvskip
+ \fi
+ \egroup}
+
+\unexpanded\def\ruledvskip
+ {\bgroup
+ \afterassignment\doruledvskip
+ \scratchskip=}
+
+%D \macros
+%D {ruledkern}
+%D
+%D The macros that implement the kerns are a bit more
+%D complicated than needed, because they also serve the
+%D visualization of glue, our \PLAIN\ defined kerns with
+%D stretch or shrink. We've implemented both horizontal and
+%D vertical kerns as ruled boxes.
+%D
+%D \startbuffer
+%D one
+%D \kern +30pt
+%D two
+%D \kern +30pt
+%D \kern -10pt
+%D three
+%D \kern 0pt
+%D four
+%D \kern +30pt
+%D five
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+%D
+%D Positive and negative kerns are placed on top or below the
+%D baseline, so we are able to track their added result. We
+%D didn't mention spacings of 0~pt yet. Zero values are
+%D visualized a bit different, because we want to see them
+%D anyhow.
+
+\def\doruledhkern
+ {\dontinterfere
+ \dontcomplain
+ \baselinerulefalse
+ \investigateskip\scratchskip
+ \boxrulewidth2\testrulewidth
+ \ifzero
+ \setbox0\ruledhbox to 8\testrulewidth
+ {\visualvrule
+ \!!width\zeropoint
+ \!!height16\testrulewidth
+ \!!depth16\testrulewidth}%
+ \setbox0\normalhbox
+ {\normalhskip-4\testrulewidth\box0}%
+ \else
+ \setbox0\ruledhbox to \ifnegative-\fi\scratchskip
+ {\visualvrule
+ \!!width\zeropoint
+ \ifnegative\!!depth\else\!!height\fi16\testrulewidth
+ \ifflexible
+ \normalhskip2\testrulewidth
+ \cleaders
+ \normalhbox
+ {\normalhskip 2\testrulewidth
+ \visualvrule
+ \!!width2\testrulewidth
+ \!!height\ifnegative-7\else9\fi\testrulewidth
+ \!!depth\ifnegative9\else-7\fi\testrulewidth
+ \normalhskip 2\testrulewidth}%
+ \normalhfill
+ \else
+ \normalhfill
+ \fi}%
+ \testrulewidth2\testrulewidth
+ \setbox0\ruledhbox{\box0}% \make...
+ \fi
+ \smashbox0%
+ \normalpenalty\!!tenthousand
+ \normalhbox to \zeropoint
+ {\ifnegative\normalhskip1\scratchskip\fi
+ \box0}%
+ \afterwards\scratchskip
+ \egroup}
+
+\unexpanded\def\ruledhkern#1%
+ {\bgroup
+ \let\afterwards#1%
+ \afterassignment\doruledhkern
+ \scratchskip=}
+
+%D After having seen the horizontal ones, the vertical kerns
+%D will not surprise us. In this example we use \type{\par} to
+%D switch to vertical mode.
+%D
+%D \startbuffer
+%D first line
+%D \par \kern +30pt
+%D second line
+%D \par \kern +30pt
+%D \par \kern -10pt
+%D third line
+%D \par
+%D fourth line
+%D \par \kern +30pt
+%D fifth line
+%D \par \kern 0pt
+%D sixth line
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+%D
+%D Like before, we have to postpone \type{\prevdepth}. If we
+%D leave out this trick, we got ourselves some wrong spacing.
+
+\def\dodoruledvkern
+ {\nextdepth\prevdepth
+ \dontinterfere
+ \dontcomplain
+ \baselinerulefalse
+ \normaloffinterlineskip
+ \investigateskip\scratchskip
+ \boxrulewidth2\testrulewidth
+ \ifzero
+ \setbox0\ruledhbox to 32\testrulewidth
+ {\visualvrule
+ \!!width\zeropoint
+ \!!height4\testrulewidth
+ \!!depth4\testrulewidth}%
+ \else
+ \setbox0\ruledvbox to \ifnegative-\fi\scratchskip
+ {\hsize16\testrulewidth
+ \ifflexible
+ \cleaders
+ \normalhbox to 16\testrulewidth
+ {\normalhss
+ \normalvbox
+ {\normalvskip 2\testrulewidth
+ \visualhrule
+ \!!width2\testrulewidth
+ \!!height2\testrulewidth
+ \normalvskip 2\testrulewidth}%
+ \normalhss}%
+ \normalvfill
+ \else
+ \visualvrule
+ \!!width\zeropoint
+ \!!height\ifnegative-\fi\scratchskip
+ \normalhfill
+ \fi}
+ \fi
+ \testrulewidth2\testrulewidth
+ \setbox0\ruledvbox{\box0}% \make...
+ \smashbox0%
+ \setbox0\normalvbox
+ {\ifnegative\normalvskip\scratchskip\fi
+ \normalvcue
+ {\ifnegative\normalhskip-16\testrulewidth\fi\box0}}%
+ \smashbox0%
+ \normalpenalty\!!tenthousand
+ \box0
+ \prevdepth\nextdepth} % not \dp0=\nextdepth
+
+\def\doruledvkern
+ {\ifdim\pagegoal=\maxdimen
+ \ifinner
+ \dodoruledvkern
+ \fi
+ \else
+ \dodoruledvkern
+ \fi
+ \afterwards\scratchskip
+ \egroup}
+
+\unexpanded\def\ruledvkern#1%
+ {\bgroup
+ \let\afterwards#1\relax
+ \afterassignment\doruledvkern
+ \scratchskip=}
+
+\unexpanded\def\ruledkern
+ {\ifvmode
+ \expandafter\ruledvkern
+ \else
+ \expandafter\ruledhkern
+ \fi
+ \normalkern}
+
+%D A a bit more \TEX nice solution is:
+%D
+%D \starttyping
+%D \unexpanded\def\ruledkern%
+%D {\csname ruled\ifvmode v\else h\fi kern\endcsname\normalkern}
+%D \stoptyping
+
+%D \macros
+%D {ruledhglue,ruledvglue}
+%D
+%D The non-primitive glue commands are treated as kerns with
+%D stretch. This stretch is presented as a dashed line. I
+%D have to admit that until now, I've never used these glue
+%D commands.
+%D
+%D \startbuffer
+%D one
+%D \hglue +30pt plus 5pt
+%D two
+%D \hglue +30pt
+%D \hglue -10pt plus 5pt
+%D three
+%D \hglue 0pt
+%D four
+%D \hglue +30pt
+%D five
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+
+\def\doruledhglue
+ {\leavevmode
+ \scratchcounter\spacefactor
+ \visualvrule\!!width\zeropoint
+ \normalpenalty\!!tenthousand
+ \ruledhkern\normalhskip\scratchskip
+ \spacefactor\scratchcounter
+ \egroup}
+
+\unexpanded\def\ruledhglue
+ {\bgroup
+ \afterassignment\doruledhglue\scratchskip=}
+
+%D \startbuffer
+%D first line
+%D \vglue +30pt plus 5pt
+%D second line
+%D \vglue +30pt
+%D \vglue -10pt plus 5pt
+%D third line
+%D \par
+%D fourth line
+%D \vglue +30pt
+%D fifth line
+%D \vglue 0pt
+%D sixth line
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+
+\def\doruledvglue
+ {\endgraf % \par
+ \nextdepth\prevdepth
+ \visualhrule\!!height\zeropoint
+ \normalpenalty\!!tenthousand
+ \ruledvkern\normalvskip\scratchskip
+ \prevdepth\nextdepth
+ \egroup}
+
+\unexpanded\def\ruledvglue
+ {\bgroup
+ \afterassignment\doruledvglue\scratchskip=}
+
+%D \macros
+%D {ruledmkern,ruledmskip}
+%D
+%D Mathematical kerns and skips are specified in mu. This
+%D font related unit is incompatible with those of \DIMENSIONS\
+%D and \SKIPS. Because in math mode spacing is often a very
+%D subtle matter, we've used a very simple, not overloaded way
+%D to show them.
+
+\def\dodoruledmkern#1%
+ {\dontinterfere
+ \dontcomplain
+ \setbox0\normalhbox
+ {$\normalmkern\ifnegative-\fi\scratchmuskip$}%
+ \setbox0\normalhbox to \wd0
+ {\visualvrule
+ \!!height16\testrulewidth
+ \!!depth16\testrulewidth
+ \!!width\testrulewidth
+ \leaders
+ \visualhrule
+ \!!height\ifpositive16\else-14\fi\testrulewidth
+ \!!depth\ifpositive-14\else16\fi\testrulewidth
+ \normalhfill
+ \ifflexible
+ \normalhskip-\wd0
+ \leaders
+ \visualhrule
+ \!!height\testrulewidth
+ \!!depth\testrulewidth
+ \normalhfill
+ \fi
+ \visualvrule
+ \!!height16\testrulewidth
+ \!!depth16\testrulewidth
+ \!!width\testrulewidth}%
+ \smashbox0%
+ \ifnegative
+ #1\scratchmuskip
+ \box0
+ \else
+ \box0
+ #1\scratchmuskip
+ \fi
+ \egroup}
+
+%D \startbuffer
+%D $a \mkern3mu = \mkern3mu
+%D b \quad
+%D \mkern-2mu + \mkern-2mu
+%D \quad c$
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+
+\def\doruledmkern
+ {\investigatemuskip\scratchmuskip
+ \flexiblefalse
+ \dodoruledmkern\normalmkern}
+
+\unexpanded\def\ruledmkern
+ {\bgroup
+ \afterassignment\doruledmkern\scratchmuskip=}
+
+%D \startbuffer
+%D $a \mskip3mu = \mskip3mu
+%D b \quad
+%D \mskip-2mu + \mskip-2mu
+%D \quad c$
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+
+\def\doruledmskip
+ {\investigatemuskip\scratchmuskip
+ \flexibletrue
+ \dodoruledmkern\normalmskip}
+
+\unexpanded\def\ruledmskip
+ {\bgroup
+ \afterassignment\doruledmskip\scratchmuskip=}
+
+%D \macros
+%D {penalty}
+%D
+%D After presenting fills, skip, kerns and glue we've come to
+%D see penalties. In the first implementation --- most of the
+%D time needed to develop this set of macros went into testing
+%D different types of visualization --- penalties were mere
+%D small blocks with one black half, depending on the sign.
+%D This most recent version also gives an indication of the
+%D amount of penalty. Penalties can go from less than $-10000$
+%D to over $+10000$, and their behavior is somewhat
+%D non-lineair, with some values having special meanings. We
+%D therefore decided not to use its value for a lineair
+%D indicator.
+%D
+%D \startbuffer
+%D one
+%D \penalty +100
+%D two
+%D \penalty +100
+%D \penalty -100
+%D three
+%D \penalty 0
+%D four
+%D \penalty +100
+%D five
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+%D
+%D The small sticks at the side of the penalty indicate it
+%D size. The next example shows the positive and negative
+%D penalties of 0, 1, 10, 100, 1000 and 10000.
+%D
+%D \startlinecorrection
+%D \hbox
+%D {test \ruledhpenalty0
+%D test \ruledhpenalty1
+%D test \ruledhpenalty10
+%D test \ruledhpenalty100
+%D test \ruledhpenalty1000
+%D test \ruledhpenalty10000
+%D test}
+%D \stoplinecorrection
+%D
+%D \blank
+%D
+%D \startlinecorrection
+%D \hbox
+%D {test \ruledhpenalty0
+%D test \ruledhpenalty-1
+%D test \ruledhpenalty-10
+%D test \ruledhpenalty-100
+%D test \ruledhpenalty-1000
+%D test \ruledhpenalty-10000
+%D test}
+%D \stoplinecorrection
+%D
+%D \blank
+%D
+%D This way stacked penalties of different severance can be
+%D shown in combination.
+%D
+%D test \ruledhpenalty10 \ruledhpenalty100
+%D test
+%D test \ruledhpenalty1000 \ruledhpenalty-1000
+%D test
+
+\def\setruledpenaltybox#1#2#3#4#5#6%
+ {\setbox#1\normalhbox
+ {\ifnum#2=0 \else
+ \edef\sign
+ {\ifnum#2>0 +\else-\fi}%
+ \dimen0=\ifnum\sign#2>9999
+ 28\else
+ \ifnum\sign#2>999
+ 22\else
+ \ifnum\sign#2>99
+ 16\else
+ \ifnum\sign#2>9
+ 10\else
+ 4
+ \fi\fi\fi\fi \testrulewidth
+ \ifnum#2<0
+ \normalhskip-\dimen0
+ \normalhskip-2\testrulewidth
+ \visualvrule
+ \!!width2\testrulewidth
+ \!!height#3\testrulewidth
+ \!!depth#4\testrulewidth
+ \fi
+ \visualvrule
+ \!!width\dimen0
+ \!!height#5\testrulewidth
+ \!!depth#6\testrulewidth
+ \ifnum#2>0
+ \visualvrule
+ \!!width2\testrulewidth
+ \!!height#3\testrulewidth
+ \!!depth#4\testrulewidth
+ \fi
+ \fi}%
+ \smashbox#1}
+
+\def\doruledhpenalty
+ {\dontinterfere
+ \dontcomplain
+ \investigatecount\scratchcounter
+ \testrulewidth2\testrulewidth
+ \boxrulewidth\testrulewidth
+ \setbox0\ruledhbox to 8\testrulewidth
+ {\ifnegative\else\normalhss\fi
+ \visualvrule
+ \!!depth8\testrulewidth
+ \!!width\ifzero0\else4\fi\testrulewidth
+ \ifpositive\else\normalhss\fi}%
+ \setruledpenaltybox{2}{\scratchcounter}{0}{8}{-3.5}{4.5}%
+ \normalpenalty\!!tenthousand
+ \setbox0\normalhbox
+ {\normalhskip-4\testrulewidth
+ \ifnegative
+ \box2\box0
+ \else
+ \box0\box2
+ \fi}%
+ \smashbox0%
+ \box0
+ \normalpenalty\scratchcounter
+ \egroup}
+
+\unexpanded\def\ruledhpenalty
+ {\bgroup
+ \afterassignment\doruledhpenalty
+ \scratchcounter=}
+
+%D The size of a vertical penalty is also shown on the
+%D horizontal axis. This way there is less interference with
+%D the often preceding or following skips and kerns.
+%D
+%D \startbuffer
+%D first line
+%D \par \penalty +100
+%D second line
+%D \par \penalty +100
+%D \par \penalty -100
+%D third line
+%D \par \penalty 0
+%D fourth line
+%D \par \penalty +100
+%D fifth line
+%D \stopbuffer
+%D
+%D \ShowBufferedExample
+
+\def\doruledvpenalty
+ {\ifdim\pagegoal=\maxdimen
+ \else
+ \nextdepth\prevdepth
+ \dontinterfere
+ \dontcomplain
+ \investigatecount\scratchcounter
+ \testrulewidth2\testrulewidth
+ \boxrulewidth\testrulewidth
+ \setbox0\ruledhbox
+ {\visualvrule
+ \!!height4\testrulewidth
+ \!!depth4\testrulewidth
+ \!!width\zeropoint
+ \visualvrule
+ \!!height\ifnegative.5\else4\fi\testrulewidth
+ \!!depth\ifpositive.5\else4\fi\testrulewidth
+ \!!width8\testrulewidth}%
+ \setruledpenaltybox{2}{\scratchcounter}{4}{4}{.5}{.5}%
+ \setbox0\normalhbox
+ {\normalhskip-4\testrulewidth
+ \ifnegative
+ \box2\box0
+ \else
+ \box0\box2
+ \fi
+ \normalhss}%
+ \smashbox0%
+ \normalpenalty\!!tenthousand
+ \nointerlineskip
+ \dp0\nextdepth % not \prevdepth=\nextdepth
+ \normalvbox
+ {\normalvcue{\box0}}%
+ \fi
+ \normalpenalty\scratchcounter
+ \egroup}
+
+\unexpanded\def\ruledvpenalty
+ {\bgroup
+ \afterassignment\doruledvpenalty
+ \scratchcounter=}
+
+\unexpanded\def\ruledpenalty
+ {\ifvmode
+ \expandafter\ruledvpenalty
+ \else
+ \expandafter\ruledhpenalty
+ \fi}
+
+%D At the cost of some more tokens, a bit more clever
+%D implementation would be:
+%D
+%D \starttyping
+%D \unexpanded\def\ruledpenalty%
+%D {\csname ruled\ifvmode v\else h\fi penalty\endcsname}
+%D \stoptyping
+
+%D \macros
+%D {showfils,dontshowfils,
+%D showboxes,dontshowboxes,
+%D showskips,dontshowskips,
+%D showpenalties,dontshowpenalties}
+%D
+%D For those who want to manipulate the visual cues in detail,
+%D we have grouped them.
+
+\newif\ifshowingcomposition % see later why we need this
+
+\def\showfils
+ {\showingcompositiontrue
+ \let\hss \ruledhss
+ \let\hfil \ruledhfil
+ \let\hfill \ruledhfill
+ \let\hfilneg \ruledhfilneg
+ \let\hfillneg \ruledhfillneg
+ \let\vss \ruledvss
+ \let\vfil \ruledvfil
+ \let\vfill \ruledvfill
+ \let\vfilneg \ruledvfilneg
+ \let\vfillneg \ruledvfillneg}
+
+\def\dontshowfils
+ {\let\hss \normalhss
+ \let\hfil \normalhfil
+ \let\hfill \normalhfill
+ \let\hfilneg \normalhfilneg
+ \let\hfillneg \normalhfillneg
+ \let\vss \normalvss
+ \let\vfil \normalvfil
+ \let\vfill \normalvfill
+ \let\vfilneg \normalvfilneg
+ \let\vfillneg \normalvfillneg}
+
+\def\showboxes
+ {\showingcompositiontrue
+ \baselineruletrue
+ \let\hbox \ruledhbox
+ \let\vbox \ruledvbox
+ \let\vtop \ruledvtop
+ \let\vcenter \ruledvcenter}
+
+\def\dontshowboxes
+ {\let\hbox \normalhbox
+ \let\vbox \normalvbox
+ \let\vtop \normalvtop
+ \let\vcenter \normalvcenter}
+
+\def\showskips
+ {\showingcompositiontrue
+ \let\hskip \ruledhskip
+ \let\vskip \ruledvskip
+ \let\kern \ruledkern
+ \let\mskip \ruledmskip
+ \let\mkern \ruledmkern
+ \let\hglue \ruledhglue
+ \let\vglue \ruledvglue}
+
+\def\dontshowskips
+ {\let\hskip \normalhskip
+ \let\vskip \normalvskip
+ \let\kern \normalkern
+ \let\mskip \normalmskip
+ \let\mkern \normalmkern
+ \let\hglue \normalhglue
+ \let\vglue \normalvglue}
+
+\def\showpenalties
+ {\showingcompositiontrue
+ \let\penalty \ruledpenalty}
+
+\def\dontshowpenalties
+ {\let\penalty \normalpenalty}
+
+%D \macros
+%D {showcomposition,dontshowcomposition,
+%D showingcomposition}
+%D
+%D All these nice options come together in three macros. One
+%D for turning the options on, one for turning them off, and a
+%D boolean for enabling the mechanism outside the scope of the
+%D user. The first two macros only do their job when we are
+%D actually showing the composition.
+%D
+%D \starttyping
+%D \showingcompositiontrue
+%D \showcomposition
+%D \stoptyping
+%D
+%D Because the output routine can do tricky things, like
+%D multiple column typesetting and manipulation of the
+%D pagebody, shifting things around and so on, the macro
+%D \type{\dontshowcomposition} best can be called when we enter
+%D this routine. Too much visual cues just don't make sense. In
+%D \CONTEXT\ this has been taken care of.
+
+\newif\ifshowingcomposition
+
+\def\showcomposition
+ {\ifshowingcomposition
+ \showfils
+ \showboxes
+ \showskips
+ \showpenalties
+ \fi}
+
+\def\dontshowcomposition
+ {\ifshowingcomposition
+ \dontshowfils
+ \dontshowboxes
+ \dontshowskips
+ \dontshowpenalties
+ \fi}
+
+%D \macros
+%D {showmakeup,
+%D defaulttestrulewidth}
+%D
+%D Just to make things even more easy, we have defined:
+%D
+%D \starttyping
+%D \showmakeup
+%D \stoptyping
+%D
+%D For the sake of those who don't (yet) use \CONTEXT\ we
+%D preset \type{\defaulttestrulewidth} to the already set
+%D value. Otherwise we default to a bodyfontsize related value.
+%D
+%D \starttyping
+%D \def\defaulttestrulewidth{.2pt}
+%D \stoptyping
+%D
+%D Beware, it's a macro not a \DIMENSION.
+
+\ifx\bodyfontsize\undefined
+ \edef\defaulttestrulewidth{\the\testrulewidth}
+\else
+ \def\defaulttestrulewidth{.02\bodyfontsize}
+\fi
+
+\def\showmakeup
+ {\testrulewidth\defaulttestrulewidth
+ \showingcompositiontrue
+ \showcomposition}
+
+\protect
+
+%D \ifCONTEXT \let\next=\relax \else \let\next=\endinput
+%D The documented source you have been reading was processed
+%D using some surrogate makeup. When this file is processed
+%D in \CONTEXT, a few more examples show up here, like a local
+%D table of contents and a local register.
+%D \fi \next
+
+%D Lets end with some more advanced examples.
+%D Definitions and enumerations come in many flavors. The
+%D next one for instance is defined as:
+%D
+%D \starttyping
+%D \definedescription[test][place=left,hang=3,width=6em]
+%D \stoptyping
+%D
+%D When applied to some text, this would look like:
+%D
+%D \bgroup
+%D \showmakeup
+%D \definedescription[test][location=left,hang=3,width=6em]
+%D
+%D \test{visual\\debugger} I would be very pleased if \TEX\
+%D had two more primitives: \type{\vnop} and \type{\hnop}. Both
+%D should act and show up as normal boxes, but stay invisible
+%D for \TEX\ when it's doing calculations. The \type{\vnop}
+%D for instance should not interact with the internal mechanism
+%D responsible for the disappearing skips, kerns and penalties
+%D at a pagebreak. As long as we don't have these two boxtypes,
+%D visual debugging will never be perfect.
+%D
+%D \egroup
+%D
+%D The index to this section looks like:
+%D
+%D {\setupreferencing[prefixprefix=dummy]\showmakeup\placeindex[criterium=local]}
+%D
+%D Although not impressive examples or typesetting, both
+%D show us how and where things happen. When somehow the last
+%D lines in this two column index don't allign, then this is
+%D due to some still unknown interference.
+
+\endinput
diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv
index 8dd3c57d5..90153f006 100644
--- a/tex/context/base/syst-aux.mkiv
+++ b/tex/context/base/syst-aux.mkiv
@@ -5907,25 +5907,18 @@
%D helps a lot. The second boolena can be used to inhibit
%D processing completely.
-\newif\ifvisible \visibletrue
+\newif\ifvisible \visibletrue
-\newif \iftrialtypesetting
-\newcount\trialtypesettingmode % we need to find a way to query conditionals so this one can become obsolete
-\newtoks \everysettrialtypesetting
-\newtoks \everyresettrialtypesetting
+\newtoks\everysettrialtypesetting
+\newtoks\everyresettrialtypesetting
\unexpanded\def\settrialtypesetting {\the\everysettrialtypesetting } % obeys grouping so
\unexpanded\def\resettrialtypesetting{\the\everyresettrialtypesetting} % this one is seldom needed
-\appendtoks
- \trialtypesettingtrue
- \trialtypesettingmode\plusone
-\to \everysettrialtypesetting
+\let\iftrialtypesetting\iffalse % so we have no \trialtypesettingtrue|false in mkiv !
-\appendtoks
- \trialtypesettingfalse
- \trialtypesettingmode\zerocount
-\to \everyresettrialtypesetting
+\appendtoks \let\iftrialtypesetting\iftrue \to \everysettrialtypesetting
+\appendtoks \let\iftrialtypesetting\iffalse \to \everyresettrialtypesetting
%D \macros
%D {startlocal, startglobal}
diff --git a/tex/context/base/syst-con.mkiv b/tex/context/base/syst-con.mkiv
index f7d4150a6..af9fa16bd 100644
--- a/tex/context/base/syst-con.mkiv
+++ b/tex/context/base/syst-con.mkiv
@@ -134,12 +134,18 @@
% \let\calculatecos\gobbleoneargument
% \let\calculatetan\gobbleoneargument
-% \def\calculatedsin#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.sin(#1))}}
-% \def\calculatedcos#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.cos(#1))}}
-% \def\calculatedtan#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.tan(#1))}}
+% \def\calculatedsin#1{\ctxsprint{math.sin(#1)}}
+% \def\calculatedcos#1{\ctxsprint{math.cos(#1)}}
+% \def\calculatedtan#1{\ctxsprint{math.tan(#1)}}
-\def\setcalculatedsin#1#2{\edef#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.sind(#2))}}}
-\def\setcalculatedcos#1#2{\edef#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.cosd(#2))}}}
-\def\setcalculatedtan#1#2{\edef#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.tand(#2))}}}
+% \def\setcalculatedsin#1#2{\edef#1{\ctxsprint{math.sind(#2)}}}
+% \def\setcalculatedcos#1#2{\edef#1{\ctxsprint{math.cosd(#2)}}}
+% \def\setcalculatedtan#1#2{\edef#1{\ctxsprint{math.tand(#2)}}}
+
+% this is actually 20% faster: some overhead in functions but less tokenization
+
+\def\setcalculatedsin#1#2{\edef#1{\cldcontext{math.sind(#2)}}}
+\def\setcalculatedcos#1#2{\edef#1{\cldcontext{math.cosd(#2)}}}
+\def\setcalculatedtan#1#2{\edef#1{\cldcontext{math.tand(#2)}}}
\protect \endinput
diff --git a/tex/context/base/syst-lua.mkiv b/tex/context/base/syst-lua.mkiv
index f9be10e6d..a5dce5461 100644
--- a/tex/context/base/syst-lua.mkiv
+++ b/tex/context/base/syst-lua.mkiv
@@ -37,6 +37,7 @@
% a handy helper (we can probably omit the tex.ctxcatcodes here as nowadays we seldom
% change the regime at the tex end
-\def\luaexpr#1{\ctxlua{tex.sprint(tex.ctxcatcodes,tostring(#1))}}
+%def\luaexpr#1{\ctxlua {tex.sprint(tex.ctxcatcodes,tostring(#1))}}
+\def\luaexpr#1{\directlua\zerocount{tex.sprint(tex.ctxcatcodes,tostring(#1))}} % wrap in global function ?
\protect \endinput
diff --git a/tex/context/base/trac-set.lua b/tex/context/base/trac-set.lua
index b14c6112e..9ae215817 100644
--- a/tex/context/base/trac-set.lua
+++ b/tex/context/base/trac-set.lua
@@ -21,13 +21,13 @@ local setters = utilities.setters
local data = { } -- maybe just local
-- We can initialize from the cnf file. This is sort of tricky as
--- laster defined setters also need to be initialized then. If set
+-- later defined setters also need to be initialized then. If set
-- this way, we need to ensure that they are not reset later on.
-local trace_initialize = false
+local trace_initialize = false -- only for testing during development
-local function report(what,filename,name,key,value)
- texio.write_nl(format("%s setter, filename: %s, name: %s, key: %s, value: %s",what,filename,name,key,value))
+local function report(a,b,...)
+ texio.write_nl(format("%-16s> %s",a,format(b,...)))
end
function setters.initialize(filename,name,values) -- filename only for diagnostics
@@ -42,7 +42,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
if functions then
if #functions > 0 and not functions.value then
if trace_initialize then
- report("doing",filename,name,key,value)
+ report(name,"executing %s (%s -> %s)",key,filename,tostring(value))
end
for i=1,#functions do
functions[i](value)
@@ -50,7 +50,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions.value = value
else
if trace_initialize then
- report("skipping",filename,name,key,value)
+ report(name,"skipping %s (%s -> %s)",key,filename,tostring(value))
end
end
else
@@ -59,7 +59,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti
functions = { default = value }
data[key] = functions
if trace_initialize then
- report("storing",filename,name,key,value)
+ report(name,"storing %s (%s -> %s)",key,filename,tostring(value))
end
end
end
@@ -129,11 +129,17 @@ function setters.register(t,what,...)
if not functions then
functions = { }
data[what] = functions
+ if trace_initialize then
+ report(t.name,"defining %s",what)
+ end
end
local default = functions.default -- can be set from cnf file
for _, fnc in next, { ... } do
local typ = type(fnc)
if typ == "string" then
+ if trace_initialize then
+ report(t.name,"coupling %s to %s",what,fnc)
+ end
local s = fnc -- else wrong reference
fnc = function(value) set(t,s,value) end
elseif typ ~= "function" then
@@ -141,9 +147,12 @@ function setters.register(t,what,...)
end
if fnc then
functions[#functions+1] = fnc
- if default then
- fnc(default)
- functions.value = default
+ -- default: set at command line or in cnf file
+ -- value : set in tex run (needed when loading runtime)
+ local value = functions.value or default
+ if value ~= nil then
+ fnc(value)
+ functions.value = value
end
end
end
@@ -193,7 +202,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- commands.writestatus(category,format("%-25s modules: %2i default: %5s value: %5s",name,modules,default,value))
+ commands.writestatus(category,format("%-30s modules: %2i default: %5s value: %5s",name,modules,default,value))
end
end
commands.writestatus("","")
diff --git a/tex/context/base/util-lua.lua b/tex/context/base/util-lua.lua
index 8562c6417..3aecbfa26 100644
--- a/tex/context/base/util-lua.lua
+++ b/tex/context/base/util-lua.lua
@@ -24,4 +24,3 @@ function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: clean
end
return done
end
-
diff --git a/tex/context/bib/bibl-apa.tex b/tex/context/bib/bibl-apa.tex
index 20bbccb95..b0403e542 100644
--- a/tex/context/bib/bibl-apa.tex
+++ b/tex/context/bib/bibl-apa.tex
@@ -106,7 +106,7 @@
%D Some shortcuts.
% ((#1(type\ |)chapter#2)|#3)
-
+
\def\insertchap#1#2#3%
{\insertchapter
{#1\insertbibtype{}{\ }{chapter\ }}{#2}%
@@ -164,12 +164,12 @@
\setuppublicationlayout[book]{%
\insertauthors{}{ }{\inserteditors{}{, editor%
\ifnum\getvalue{editor@num}> 1 s\fi
- \ \global\editedbooktrue
+ \ \global\editedbooktrue
}{\insertthekey{}{. }{}}}%
\insertpubyear{(}{). }{\unskip.}%
\inserttitle
{\bgroup\it }%
- {\/\egroup
+ {\/\egroup
\ifeditedbook
\global\editedbookfalse
\insertvolume
@@ -182,7 +182,7 @@
\else
\insertcrossref
{\insertchap{, }{}{}%
- \insertpages{, pages }{. }{. }%
+ \insertpages{\unskip, pages }{. }{. }%
\insertvolume{Volume~}{ of~}{}%
}%
{}%
@@ -194,7 +194,7 @@
{}}
{}%
\insertchap{, }{}{}%
- \insertpages{, pages }{.}{.}%
+ \insertpages{\unskip, pages }{.}{.}%
}%
\fi}%
{}%
@@ -207,7 +207,7 @@
\setuppublicationlayout[inbook]{%
\insertauthors{}{ }{\inserteditors{}{, editor%
\ifnum\getvalue{editor@num}> 1 s\fi
- \ \global\editedbooktrue
+ \ \global\editedbooktrue
}{\insertthekey{}{. }{}}}%
\insertpubyear{(}{). }{\unskip.}%
\inserttitle
@@ -225,7 +225,7 @@
\else
\insertcrossref
{\insertchap{, }{}{}%
- \insertpages{, pages }{. }{. }%
+ \insertpages{\unskip, pages }{. }{. }%
\insertvolume{Volume~}{ of~}{}%
}%
{}%
@@ -237,7 +237,7 @@
{}}
{}%
\insertchap{, }{}{}%
- \insertpages{, pages }{.}{}%
+ \insertpages{\unskip, pages }{.}{}%
}%
\fi}%
{ }%
@@ -275,19 +275,19 @@
{, editor\ifnum\getvalue{editor@num}> 1 s\fi, }%
{}%
\bgroup\it}%
- {\egroup
+ {\egroup
\insertseries
{\insertvolume{, number }{~in }{ }}%
{}%
{}%
\insertchap{\unskip, }{ }{ }%
- \insertpages{\unskip, pages~}{. }{\unskip. }%
+ \insertpages{\unskip, pages~}{. }{\unskip. }%
\insertedition{ }{ edition}{}%
\insertpublisher{ }{.}{.}%
}%
{In \insertcrossref{}{}{}%
\insertchap{\unskip, }{ }{ }%
- \insertpages{\unskip, pages~}{. }{\unskip. }%
+ \insertpages{\unskip, pages~}{. }{\unskip. }%
}%
\insertnote{ }{.}{}%
}
@@ -301,18 +301,18 @@
{, editor\ifnum\getvalue{editor@num}> 1 s\fi, }%
{}%
\bgroup\it}%
- {\egroup
+ {\egroup
\insertseries
{\insertvolume{, number }{~in }{ }}%
{}%
{}%
\insertchap{\unskip, }{ }{ }%
- \insertpages{, pages~}{}{}%
+ \insertpages{\unskip, pages~}{}{}%
\insertorg{. }{.}{.}%
}%
{In \insertcrossref{}{}{}%
\insertchap{\unskip, }{ }{ }%
- \insertpages{\unskip, pages~}{. }{\unskip. }%
+ \insertpages{\unskip, pages~}{. }{\unskip. }%
}%
\insertnote{ }{.}{}%
}
@@ -320,18 +320,18 @@
\setuppublicationlayout[proceedings]{%
\inserteditors{}{, editor%
\ifnum\getvalue{editor@num}> 1 s\fi
- \ \global\editedbooktrue
+ \ \global\editedbooktrue
}{\insertthekey{}{ }{}}%
\insertpubyear{(}{). }{}%
\inserttitle
{\bgroup\it}%
- {\egroup
+ {\egroup
\insertseries
{\insertvolume{, number }{~in }{ }}%
{}%
{}%
\insertchap{\unskip, }{ }{ }%
- \insertpages{, pages~}{}{}%
+ \insertpages{\unskip, pages~}{}{}%
\insertorg{. }{.}{.}%
}%
{}%
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua
index bb67b59af..a6ee0673c 100644
--- a/tex/generic/context/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 10/14/10 13:14:44
+-- merge date : 10/18/10 11:11:34
do -- begin closure to overcome local limits and interference
@@ -5505,6 +5505,7 @@ local otf = fonts.otf
local tfm = fonts.tfm
local fontdata = fonts.ids
+local chardata = characters.data
otf.features = otf.features or { }
otf.features.list = otf.features.list or { }
@@ -6218,8 +6219,13 @@ actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this
end
local width = glyph.width
widths[width] = (widths[width] or 0) + 1
- if glyph.class == "mark" then
- marks[glyph.unicode] = true
+ local class = glyph.class
+ local unicode = glyph.unicode
+ if class == "mark" then
+ marks[unicode] = true
+ -- elseif chardata[unicode].category == "mn" then
+ -- marks[unicode] = true
+ -- glyph.class = "mark"
end
local a = glyph.altuni if a then glyph.altuni = nil end
local d = glyph.dependents if d then glyph.dependents = nil end
diff --git a/web2c/contextcnf.lua b/web2c/contextcnf.lua
index 7d2edb6fd..53b4086a2 100644
--- a/web2c/contextcnf.lua
+++ b/web2c/contextcnf.lua
@@ -9,9 +9,6 @@ return {
content = {
- -- LUACSTRIP = 'f',
- -- PURGECACHE = 't',
-
TEXMFCACHE = "$SELFAUTOPARENT/texmf-cache",
TEXMFOS = "$SELFAUTODIR",
@@ -113,6 +110,8 @@ return {
mplib_texerrors = "yes",
-- fonts_otf_loader_method = "table", -- table mixed sparse
-- fonts_otf_loader_cleanup = "0", -- 0 1 2 3
+ system_compile_cleanup = "no", -- remove tma files
+ system_compile_strip = "yes", -- strip tmc files
},
experiments = {