summaryrefslogtreecommitdiff
path: root/tex/context
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2020-11-15 21:03:33 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2020-11-15 21:03:33 +0100
commita9eb7ca71c27fdd59cf99273adf74b17d72063b2 (patch)
treebb5c72ee61c52da8046ed81bfe4b0906cd412030 /tex/context
parent87bd04a46f60bb925f6c98b7977f30441f5e8944 (diff)
downloadcontext-a9eb7ca71c27fdd59cf99273adf74b17d72063b2.tar.gz
2020-11-15 20:43:00
Diffstat (limited to 'tex/context')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-it.mkii5
-rw-r--r--tex/context/base/mkiv/attr-col.mkiv2
-rw-r--r--tex/context/base/mkiv/attr-col.mkxl22
-rw-r--r--tex/context/base/mkiv/attr-lay.lmt311
-rw-r--r--tex/context/base/mkiv/attr-lay.mkxl105
-rw-r--r--tex/context/base/mkiv/attr-mkr.mkxl25
-rw-r--r--tex/context/base/mkiv/attr-neg.mkxl28
-rw-r--r--tex/context/base/mkiv/back-exp.mkiv8
-rw-r--r--tex/context/base/mkiv/back-exp.mkxl356
-rw-r--r--tex/context/base/mkiv/back-res.mkxl34
-rw-r--r--tex/context/base/mkiv/back-trf.mkxl79
-rw-r--r--tex/context/base/mkiv/bibl-bib.mkxl982
-rw-r--r--tex/context/base/mkiv/bibl-tra.mkxl1509
-rw-r--r--tex/context/base/mkiv/buff-ver.mkxl2
-rw-r--r--tex/context/base/mkiv/char-act.mkxl112
-rw-r--r--tex/context/base/mkiv/char-enc.mkxl18
-rw-r--r--tex/context/base/mkiv/cldf-bas.mkxl19
-rw-r--r--tex/context/base/mkiv/cldf-com.mkiv2
-rw-r--r--tex/context/base/mkiv/cldf-com.mkxl19
-rw-r--r--tex/context/base/mkiv/cldf-ini.mkxl45
-rw-r--r--tex/context/base/mkiv/cldf-ver.mkxl18
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv4
-rw-r--r--tex/context/base/mkiv/context.mkxl60
-rw-r--r--tex/context/base/mkiv/file-ini.mklx231
-rw-r--r--tex/context/base/mkiv/file-lib.mkiv (renamed from tex/context/base/mkiv/file-lib.mkvi)0
-rw-r--r--tex/context/base/mkiv/file-lib.mkxl20
-rw-r--r--tex/context/base/mkiv/file-res.mklx145
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-otl.lua2
-rw-r--r--tex/context/base/mkiv/font-tra.mkxl343
-rw-r--r--tex/context/base/mkiv/font-ttf.lua5
-rw-r--r--tex/context/base/mkiv/lang-mis.mkxl5
-rw-r--r--tex/context/base/mkiv/layo-ini.mkxl30
-rw-r--r--tex/context/base/mkiv/luat-run.lua5
-rw-r--r--tex/context/base/mkiv/m-oldbibtex.mkiv9
-rw-r--r--tex/context/base/mkiv/math-ali.mkxl14
-rw-r--r--tex/context/base/mkiv/math-fen.mkxl2
-rw-r--r--tex/context/base/mkiv/mlib-pps.mkxl215
-rw-r--r--tex/context/base/mkiv/mult-aux.mkxl4
-rw-r--r--tex/context/base/mkiv/mult-def.mkxl32
-rw-r--r--tex/context/base/mkiv/mult-dim.mklx156
-rw-r--r--tex/context/base/mkiv/mult-low.lua5
-rw-r--r--tex/context/base/mkiv/mult-prm.lua1
-rw-r--r--tex/context/base/mkiv/mult-prm.mkxl117
-rw-r--r--tex/context/base/mkiv/mult-sys.mkxl6
-rw-r--r--tex/context/base/mkiv/publ-inc.mkxl63
-rw-r--r--tex/context/base/mkiv/publ-ini.mkxl2018
-rw-r--r--tex/context/base/mkiv/publ-tra.mkxl84
-rw-r--r--tex/context/base/mkiv/publ-usr.mkiv2
-rw-r--r--tex/context/base/mkiv/publ-xml.mkxl111
-rw-r--r--tex/context/base/mkiv/spac-hor.mkxl14
-rw-r--r--tex/context/base/mkiv/spac-lin.mkiv2
-rw-r--r--tex/context/base/mkiv/spac-ver.mkxl8
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin29442 -> 29727 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin256473 -> 256473 bytes
-rw-r--r--tex/context/base/mkiv/strc-lst.mkvi4
-rw-r--r--tex/context/base/mkiv/strc-not.mklx8
-rw-r--r--tex/context/base/mkiv/strc-reg.mkxl1207
-rw-r--r--tex/context/base/mkiv/strc-sec.mkxl6
-rw-r--r--tex/context/base/mkiv/symb-emj.mkiv1
-rw-r--r--tex/context/base/mkiv/symb-emj.mkxl26
-rw-r--r--tex/context/base/mkiv/syst-aux.mkxl6
-rw-r--r--tex/context/base/mkiv/tabl-xtb.mklx8
-rw-r--r--tex/context/base/mkiv/toks-scn.lmt592
-rw-r--r--tex/context/base/mkiv/typo-del.mkiv4
-rw-r--r--tex/context/base/mkiv/unic-ini.mkxl36
-rw-r--r--tex/context/interface/mkii/keys-it.xml5
-rw-r--r--tex/context/modules/mkiv/x-mathml.mkiv2
71 files changed, 9223 insertions, 104 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 0f3413948..e3fbc2cc3 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2020.11.13 19:08}
+\newcontextversion{2020.11.15 20:40}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 11b1da79f..9c628dbae 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.11.13 19:08}
+\edef\contextversion{2020.11.15 20:40}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii
index b07d207f5..ed08237ae 100644
--- a/tex/context/base/mkii/mult-it.mkii
+++ b/tex/context/base/mkii/mult-it.mkii
@@ -283,6 +283,7 @@
\setinterfacevariable{intermezzo}{intermezzo}
\setinterfacevariable{intext}{intesto}
\setinterfacevariable{intro}{intro}
+\setinterfacevariable{invertedshort}{invertedshort}
\setinterfacevariable{italic}{corsivo}
\setinterfacevariable{italicbold}{corsivograssetto}
\setinterfacevariable{item}{elemento}
@@ -386,6 +387,7 @@
\setinterfacevariable{nonumber}{nonumber}
\setinterfacevariable{norepeat}{norepeat}
\setinterfacevariable{normal}{normale}
+\setinterfacevariable{normalshort}{normalshort}
\setinterfacevariable{nospacing}{nospacing}
\setinterfacevariable{nostopper}{nostopper}
\setinterfacevariable{not}{non}
@@ -453,6 +455,7 @@
\setinterfacevariable{rectangular}{rettangolare}
\setinterfacevariable{reference}{riferimento}
\setinterfacevariable{referral}{referral}
+\setinterfacevariable{region}{region}
\setinterfacevariable{register}{registro}
\setinterfacevariable{regular}{regolare}
\setinterfacevariable{relative}{relativo}
@@ -1805,7 +1808,7 @@
\setinterfacecommand{resetpath}{resetpath}
\setinterfacecommand{resetperiodkerning}{resetperiodkerning}
\setinterfacecommand{resetsystemmode}{resetsystemmode}
-\setinterfacecommand{resettext}{resettextcontent}
+\setinterfacecommand{resettextcontent}{resettextcontent}
\setinterfacecommand{resetvisualizers}{resetvisualizers}
\setinterfacecommand{restoreglobalbodyfont}{restoreglobalbodyfont}
\setinterfacecommand{retestfeature}{retestfeature}
diff --git a/tex/context/base/mkiv/attr-col.mkiv b/tex/context/base/mkiv/attr-col.mkiv
index db4eea9e9..c75f448e9 100644
--- a/tex/context/base/mkiv/attr-col.mkiv
+++ b/tex/context/base/mkiv/attr-col.mkiv
@@ -17,6 +17,6 @@
\unprotect
-% We implement this elsewhere but some coce might end up here.
+% We implement this elsewhere but some code might end up here.
\protect \endinput
diff --git a/tex/context/base/mkiv/attr-col.mkxl b/tex/context/base/mkiv/attr-col.mkxl
new file mode 100644
index 000000000..c75f448e9
--- /dev/null
+++ b/tex/context/base/mkiv/attr-col.mkxl
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=attr-col,
+%D version=2007.06.06,
+%D title=\CONTEXT\ Attribute Macros,
+%D subtitle=Color,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Attribute Macros / Color}
+
+\registerctxluafile{attr-col}{}
+
+\unprotect
+
+% We implement this elsewhere but some code might end up here.
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/attr-lay.lmt b/tex/context/base/mkiv/attr-lay.lmt
new file mode 100644
index 000000000..d0febb9ee
--- /dev/null
+++ b/tex/context/base/mkiv/attr-lay.lmt
@@ -0,0 +1,311 @@
+if not modules then modules = { } end modules ['attr-lay'] = {
+ version = 1.001,
+ comment = "companion to attr-lay.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- layers (ugly code, due to no grouping and such); currently we use exclusive layers
+-- but when we need it stacked layers might show up too; the next function based
+-- approach can be replaced by static (metatable driven) resolvers
+
+-- maybe use backends.registrations here too
+
+local type = type
+local insert, remove = table.insert, table.remove
+
+local attributes = attributes
+local nodes = nodes
+local utilities = utilities
+local logs = logs
+local backends = backends
+
+local context = context
+local interfaces = interfaces
+local tex = tex
+
+local implement = interfaces.implement
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local formatters = string.formatters
+
+local report_viewerlayers = logs.reporter("viewerlayers")
+
+-- todo: document this but first reimplement this as it reflects the early
+-- days of luatex / mkiv and we have better ways now
+
+-- nb: attributes: color etc is much slower than normal (marks + literals) but ...
+-- nb. too many "0 g"s
+-- nb: more local tables
+
+attributes.viewerlayers = attributes.viewerlayers or { }
+local viewerlayers = attributes.viewerlayers
+
+local variables = interfaces.variables
+local v_local = variables["local"]
+local v_global = variables["global"]
+local v_start = variables["start"]
+local v_yes = variables["yes"]
+
+local a_viewerlayer = attributes.private("viewerlayer")
+
+viewerlayers = viewerlayers or { }
+viewerlayers.data = allocate()
+viewerlayers.registered = viewerlayers.registered or { }
+viewerlayers.values = viewerlayers.values or { }
+viewerlayers.scopes = viewerlayers.scopes or { }
+viewerlayers.listwise = allocate()
+viewerlayers.attribute = a_viewerlayer
+viewerlayers.supported = true
+viewerlayers.hasorder = true
+
+local states = attributes.states
+local enableaction = nodes.tasks.enableaction
+local disableaction = nodes.tasks.disableaction
+local nodeinjections = backends.nodeinjections
+local codeinjections = backends.codeinjections
+
+local texsetattribute = tex.setattribute
+local texgetattribute = tex.getattribute
+local texsettokenlist = tex.settoks
+local unsetvalue = attributes.unsetvalue
+
+local data = viewerlayers.data
+local values = viewerlayers.values
+local listwise = viewerlayers.listwise
+local registered = viewerlayers.registered
+local scopes = viewerlayers.scopes
+
+local f_stamp = formatters["%s"]
+
+storage.register("attributes/viewerlayers/registered", registered, "attributes.viewerlayers.registered")
+storage.register("attributes/viewerlayers/values", values, "attributes.viewerlayers.values")
+storage.register("attributes/viewerlayers/scopes", scopes, "attributes.viewerlayers.scopes")
+
+local layerstacker = utilities.stacker.new("layers") -- experiment
+
+layerstacker.mode = "stack"
+layerstacker.unset = attributes.unsetvalue
+
+viewerlayers.resolve_reset = layerstacker.resolve_reset
+viewerlayers.resolve_begin = layerstacker.resolve_begin
+viewerlayers.resolve_step = layerstacker.resolve_step
+viewerlayers.resolve_end = layerstacker.resolve_end
+
+-- stacked
+
+local function startlayer(...) startlayer = nodeinjections.startlayer return startlayer(...) end
+local function stoplayer (...) stoplayer = nodeinjections.stoplayer return stoplayer (...) end
+
+local function extender(viewerlayers,key)
+ if viewerlayers.supported and key == "none" then
+ local d = stoplayer()
+ viewerlayers.none = d
+ return d
+ end
+end
+
+local function reviver(data,n)
+ if viewerlayers.supported then
+ local v = values[n]
+ if v then
+ local d = startlayer(v)
+ data[n] = d
+ return d
+ else
+ report_viewerlayers("error: unknown reference %a",tostring(n))
+ end
+ end
+end
+
+setmetatableindex(viewerlayers,extender)
+setmetatableindex(viewerlayers.data,reviver)
+
+-- !!!! TEST CODE !!!!
+
+layerstacker.start = function(...) local f = nodeinjections.startstackedlayer layerstacker.start = f return f(...) end
+layerstacker.stop = function(...) local f = nodeinjections.stopstackedlayer layerstacker.stop = f return f(...) end
+layerstacker.change = function(...) local f = nodeinjections.changestackedlayer layerstacker.change = f return f(...) end
+
+local function initializer(...)
+ return states.initialize(...)
+end
+
+attributes.viewerlayers.handler = nodes.installattributehandler {
+ name = "viewerlayer",
+ namespace = viewerlayers,
+ initializer = initializer,
+ finalizer = states.finalize,
+ processor = states.stacker,
+ -- processor = states.stacked,
+}
+
+local stack, enabled, global = { }, false, false
+
+function viewerlayers.enable(value)
+ if value == false or not viewerlayers.supported then
+ if enabled then
+ disableaction("shipouts","attributes.viewerlayers.handler")
+ end
+ enabled = false
+ else
+ if not enabled then
+ enableaction("shipouts","attributes.viewerlayers.handler")
+ end
+ enabled = true
+ end
+end
+
+function viewerlayers.forcesupport(value)
+ viewerlayers.supported = value
+ report_viewerlayers("viewerlayers are %ssupported",value and "" or "not ")
+ viewerlayers.enable(value)
+end
+
+local function register(name,lw) -- if not inimode redefine data[n] in first call
+ if not enabled then
+ viewerlayers.enable(true)
+ end
+ local stamp = f_stamp(name)
+ local n = registered[stamp]
+ if not n then
+ n = #values + 1
+ values[n] = name
+ registered[stamp] = n
+ listwise[n] = lw or false -- lw forces a used
+ end
+ return registered[stamp] -- == n
+end
+
+viewerlayers.register = register
+
+function viewerlayers.setfeatures(hasorder)
+ viewerlayers.hasorder = hasorder
+end
+
+local usestacker = true -- new, experimental
+
+function viewerlayers.start(name)
+ local a
+ if usestacker then
+ a = layerstacker.push(register(name) or unsetvalue)
+ else
+ insert(stack,texgetattribute(a_viewerlayer))
+ a = register(name) or unsetvalue
+ end
+ if global or scopes[name] == v_global then
+ scopes[a] = v_global -- messy but we don't know the attributes yet
+ texsetattribute("global",a_viewerlayer,a)
+ else
+ texsetattribute(a_viewerlayer,a)
+ end
+ -- or macro
+ texsettokenlist("currentviewerlayertoks",name)
+end
+
+function viewerlayers.stop()
+ local a
+ if usestacker then
+ a = layerstacker.pop()
+ else
+ a = remove(stack)
+ end
+ if not a then
+ -- error
+ elseif a >= 0 then
+ if global or scopes[a] == v_global then
+ texsetattribute("global",a_viewerlayer,a)
+ else
+ texsetattribute(a_viewerlayer,a)
+ end
+ texsettokenlist("currentviewerlayertoks",values[a] or "")
+ else
+ if global or scopes[a] == v_global then
+ texsetattribute("global",a_viewerlayer,unsetvalue)
+ else
+ texsetattribute(a_viewerlayer,unsetvalue)
+ end
+ texsettokenlist("currentviewerlayertoks","")
+ end
+end
+
+function viewerlayers.define(settings)
+ local tag = settings.tag
+ if not tag or tag == "" then
+ -- error
+ elseif not scopes[tag] then -- prevent duplicates
+ local title = settings.title
+ if not title or title == "" then
+ settings.title = tag
+ end
+ scopes[tag] = settings.scope or v_local
+ codeinjections.defineviewerlayer(settings)
+ end
+end
+
+function viewerlayers.definedlayoutcomponent(tag)
+ viewerlayers.define {
+ tag = tag,
+ title = utilities.strings.nice(tag),
+ visible = v_start,
+ editable = v_yes,
+ printable = v_yes,
+ }
+ return register(tag,true) -- true forces a use
+end
+
+function viewerlayers.cleanup()
+ layerstacker.clean()
+ -- todo
+end
+
+implement {
+ name = "cleanuplayers",
+ actions = viewerlayers.cleanup
+}
+
+implement {
+ name = "defineviewerlayer",
+ actions = viewerlayers.define,
+ arguments = {
+ {
+ { "tag" },
+ { "title" },
+ { "visible" },
+ { "editable" },
+ { "export" },
+ { "printable" },
+ { "scope" },
+ },
+ true
+ }
+}
+
+implement {
+ name = "definedlayoutcomponent",
+ actions = { viewerlayers.definedlayoutcomponent, context },
+ arguments = "string"
+}
+
+implement {
+ name = "startviewerlayer",
+ public = true,
+ protected = true,
+ actions = viewerlayers.start,
+ arguments = "optional",
+}
+
+implement {
+ name = "stopviewerlayer",
+ public = true,
+ protected = true,
+ actions = viewerlayers.stop
+}
+
+implement {
+ name = "registeredviewerlayer",
+ actions = { register, context },
+ arguments = { "string", true } -- true forces a use
+}
diff --git a/tex/context/base/mkiv/attr-lay.mkxl b/tex/context/base/mkiv/attr-lay.mkxl
new file mode 100644
index 000000000..4e8a56eba
--- /dev/null
+++ b/tex/context/base/mkiv/attr-lay.mkxl
@@ -0,0 +1,105 @@
+%D \module
+%D [ file=attr-lay,
+%D version=2007.06.06,
+%D title=\CONTEXT\ Attribute Macros,
+%D subtitle=Viewerlayers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Attribute Macros / Viewerlayers}
+
+%D Currently there is a limitation in mixed inline usage. This has to do with the fact
+%D that we have a stacked model but cannot determine where to revert to (as we can
+%D have AABBCCAA ranges). Maybe I'll solve that one day. It only affects nested inline
+%D layers and these make not much sense anyway. We'd have to store the complete nesting
+%D stack in the attribute in order to be able to cross pages and that demands a new
+%D mechanism.
+
+\unprotect
+
+\registerctxluafile{attr-lay}{autosuffix}
+
+% needs to work over stopitemize grouping etc
+
+\installcorenamespace{viewerlayer}
+
+\installcommandhandler \??viewerlayer {viewerlayer} \??viewerlayer
+
+\setupviewerlayer
+ [\c!state=\v!start,
+ \c!title=,
+ \c!export=\v!yes, % exportable is ugly
+ \c!printable=\v!yes,
+ \c!scope=\v!local, % maybe global but needs checking with layout
+ \c!method=\v!none]
+
+\appendtoks
+ \clf_defineviewerlayer
+ tag {\currentviewerlayer}%
+ title {\viewerlayerparameter\c!title}%
+ visible {\viewerlayerparameter\c!state}%
+ editable {\v!yes}%
+ export {\viewerlayerparameter\c!export}%
+ printable {\viewerlayerparameter\c!printable}%
+ scope {\viewerlayerparameter\c!scope}%
+ \relax
+ \doif{\viewerlayerparameter\c!method}\v!command
+ {\frozen\instance\setuxvalue{\e!start#1}{\startviewerlayer[\currentviewerlayer]}%
+ \frozen\instance\setuxvalue{\e!stop #1}{\stopviewerlayer}}%
+\to \everydefineviewerlayer
+
+% \startviewerlayer[#1] % defined at lua end
+% \stopviewerlayer % defined at lua end
+
+\permanent\protected\def\viewerlayer[#1]%
+ {\groupedcommand{\startviewerlayer[#1]}{\stopviewerlayer}}
+
+% some day we will keep this at the lua end as the info is only needed there
+
+\newtoks\currentviewerlayertoks % soon we can set macros at the lua end
+
+\def\currentviewerlayer{\the\currentviewerlayertoks}
+
+\appendtoks
+ \let\currentviewerlayer\empty
+\to \everybeforepagebody
+
+% layout components are implemented rather directly (speed)
+
+\installcorenamespace{layoutcomponentattribute}
+
+\permanent\def\attr_layoutcomponent_initialize#1%
+ {\edef\layoutcomponentboxattribute{\clf_definedlayoutcomponent{#1}}%
+ \edef\layoutcomponentboxattribute{attr \viewerlayerattribute \layoutcomponentboxattribute\relax}%
+ \global\letcsname\??layoutcomponentattribute#1\endcsname\layoutcomponentboxattribute}
+
+\permanent\def\attr_layoutcomponent_set#1% make this faster
+ {\expandafter\let\expandafter\layoutcomponentboxattribute\csname\??layoutcomponentattribute#1\endcsname
+ \ifx\layoutcomponentboxattribute\relax
+ \attr_layoutcomponent_initialize{#1}% get rid of { }
+ \fi}
+
+\permanent\def\attr_layoutcomponent_reset
+ {\let\layoutcomponentboxattribute\empty}
+
+\permanent\let\setlayoutcomponentattribute \gobbleoneargument
+\permanent\let\resetlayoutcomponentattribute\relax
+ \let\layoutcomponentboxattribute \empty
+
+\protected\def\showlayoutcomponents
+ {\enforced\let\setlayoutcomponentattribute \attr_layoutcomponent_set
+ \enforced\let\resetlayoutcomponentattribute\attr_layoutcomponent_reset}
+
+\protected\def\attr_layoutcomponent_cleanup
+ {\clf_cleanuplayers}
+
+\appendtoks
+ \attr_layoutcomponent_cleanup
+\to \everyshipout
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/attr-mkr.mkxl b/tex/context/base/mkiv/attr-mkr.mkxl
new file mode 100644
index 000000000..2209af241
--- /dev/null
+++ b/tex/context/base/mkiv/attr-mkr.mkxl
@@ -0,0 +1,25 @@
+%D \module
+%D [ file=attr-mkr,
+%D version=2013.01.09,
+%D title=\CONTEXT\ Attribute Macros,
+%D subtitle=Markers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Attribute Macros / Markers}
+
+\unprotect
+
+\registerctxluafile{attr-mkr}{}
+
+\permanent \protected\def\definemarker [#1]{\defineattribute[\s!marker:#1]}
+\permanent\tolerant\protected\def\setmarker [#1]#*[#2]{\dosetattribute{\s!marker:#1}{#2}}
+\permanent \protected\def\resetmarker [#1]{\dogetattribute{\s!marker:#1}}
+\permanent \def\boxmarker #1#2{attr \numexpr\dogetattributeid{\s!marker:#1}\numexpr \numexpr#2\relax}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/attr-neg.mkxl b/tex/context/base/mkiv/attr-neg.mkxl
new file mode 100644
index 000000000..c849e6bf6
--- /dev/null
+++ b/tex/context/base/mkiv/attr-neg.mkxl
@@ -0,0 +1,28 @@
+%D \module
+%D [ file=attr-neg,
+%D version=2007.06.06,
+%D title=\CONTEXT\ Attribute Macros,
+%D subtitle=Negation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Attribute Macros / Negation}
+
+\registerctxluafile{attr-neg}{}
+
+\unprotect
+
+% positive and negative are preregistered
+
+\permanent\protected\def\startnegative{\clf_setnegative{\v!negative}}
+\permanent\protected\def\stopnegative {\clf_setnegative{\v!positive}}
+
+\permanent\protected\def\startpositive{\clf_setnegative{\v!positive}}
+\permanent\protected\def\stoppositive {\clf_setnegative{\v!negative}}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/back-exp.mkiv b/tex/context/base/mkiv/back-exp.mkiv
index 23ffdbda0..05e404697 100644
--- a/tex/context/base/mkiv/back-exp.mkiv
+++ b/tex/context/base/mkiv/back-exp.mkiv
@@ -235,10 +235,10 @@
\to \everyenableelements
\appendtoks
- \enforced\let\specialfixedspace \explicitfixedspace
- \enforced\let\specialobeyedspace \explicitobeyedspace
- \enforced\let\specialstretchedspace\explicitstretchedspace
- \enforced\let\specialcontrolspace \explicitcontrolspace
+ \let\specialfixedspace \explicitfixedspace
+ \let\specialobeyedspace \explicitobeyedspace
+ \let\specialstretchedspace\explicitstretchedspace
+ \let\specialcontrolspace \explicitcontrolspace
\to \everyenableelements
\appendtoks
diff --git a/tex/context/base/mkiv/back-exp.mkxl b/tex/context/base/mkiv/back-exp.mkxl
new file mode 100644
index 000000000..f248ca214
--- /dev/null
+++ b/tex/context/base/mkiv/back-exp.mkxl
@@ -0,0 +1,356 @@
+%D \module
+%D [ file=back-exp,
+%D version=2010.08.22,
+%D title=\CONTEXT\ Backend Macros,
+%D subtitle=XML export,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Backend Macros / XML export}
+
+\registerctxluafile{back-exp}{}
+
+%D This is an experimental exporter and a logical follow up on tagging. The
+%D exporter assumes a properly tagged document. Some elements get a couple
+%D of attributes because otherwise rendering information would get lost. In
+%D general we assume that when the \XML\ is converted to \HTML\ some stylesheet
+%D is applied anyway.
+
+\unprotect
+
+% we can replace this by a more generic attributeset mechanism where we bind
+% to any element (needed anyway, see userdata thingies)
+
+\definesystemattribute[taggedpar][public]
+
+\permanent\tolerant\protected\def\setelementexporttag[#1]#*[#2]#*[#3]%
+ {\ifarguments\or\or
+ \clf_settagproperty{#1}{export}{#2}%
+ \or
+ \clf_settagproperty{#1}{#2}{#3}%
+ \fi}
+
+% todo: no need for calls when trialtypesetting
+
+\permanent\def\taggedctxcommand
+ {\iftrialtypesetting
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\ctxcommand
+ \fi}
+
+\newcount\tagparcounter
+
+\aliased\let\dotagsetparcounter\relax
+\aliased\let\doresetparcounter \relax
+
+\appendtoks
+ \doresetparcounter
+\to \everyflushatnextpar
+
+% \appendtoks
+% \dotagsetparcounter
+% \to \everypar
+
+\prependtoks
+ \dotagsetparcounter
+\to \everypar
+
+% \appendtoks
+% \dotagsetparcounter
+% \to \neverypar
+
+\prependtoks
+ \dotagsetparcounter
+\to \neverypar
+
+\appendtoks
+ \dotagsetparcounter
+\to \everytabulatepar % tricky, maybe this should be neverypar
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagTABLEcell
+ {\iftrialtypesetting\else
+ \clf_settagtablecell
+ \numexpr\tablecellrows\relax
+ \numexpr\tablecellcolumns\relax
+ \numexpr\raggedstatus\relax
+ \fi}%
+ % brrr, we need to tag empty cells (unless we start numbering)
+ \enforced\permanent\protected\def\dotagTABLEsignal
+ {\signalcharacter}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagtabulatecell
+ {\iftrialtypesetting\else
+ \clf_settagtabulatecell\c_tabl_tabulate_align\c_tabl_tabulate_kind
+ \fi}%
+ \enforced\permanent\protected\def\dotagtabulatesignal
+ {\dontleavehmode\signalcharacter\ignorespaces}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsynonym
+ {\iftrialtypesetting\else\clf_settagsynonym{\currentsynonymtag}\fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsorting
+ {\iftrialtypesetting\else\clf_settagsorting{\currentsortingtag}\fi}%
+\to \everyenableelements
+
+\appendtoks % frozen and assumed global per highlight class
+ \enforced\permanent\protected\def\dotagconstruct
+ {\iftrialtypesetting\else
+ \clf_settagconstruct
+ {\currentstartstop}%
+ {\startstopparameter\c!style}%
+ \c_attr_color
+ \ifvmode\plusone\else\zerocount\fi
+ \relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks % frozen and assumed global per highlight class
+ \enforced\permanent\protected\def\dotaghighlight
+ {\iftrialtypesetting\else
+ \clf_settaghighlight
+ {\currenthighlight}%
+ {\highlightparameter\c!style}
+ \c_attr_color
+ \ifvmode\plusone\else\zerocount\fi
+ \relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks % we can have differently scaled images
+ \enforced\permanent\protected\def\dotagfigure
+ {\iftrialtypesetting\else
+ \clf_settagfigure
+ {\figurefileoriginal}%
+ {\figurefullname}%
+ {\figurefilepage}%
+ \dimexpr\figurewidth\relax
+ \dimexpr\figureheight\relax
+ {\figurelabel}%
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagcombination
+ {\iftrialtypesetting\else
+ \clf_settagcombination
+ \numexpr\combinationparameter\c!nx\relax
+ \numexpr\combinationparameter\c!ny\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsetparcounter
+ {\global\advance\tagparcounter\plusone\c_attr_taggedpar\tagparcounter}%
+ \enforced\permanent\protected\def\doresetparcounter
+ {\c_attr_taggedpar\attributeunsetvalue}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsetitemgroup
+ {\iftrialtypesetting\else
+ \clf_settagitemgroup
+ \ifconditional\c_strc_itemgroups_pack true\else false\fi\space
+ \numexpr\currentitemlevel\relax
+ {\currentitemgroupsymbol}%
+ \fi}%
+ \enforced\permanent\protected\def\dotagsetitem#1%
+ {\iftrialtypesetting\else
+ \clf_settagitem{#1}%
+ \fi}%
+\to \everyenableelements
+
+% \appendtoks
+% \enforced\permanent\protected\def\dotagsetdescription
+% {\iftrialtypesetting\else
+% \clf_settagdescription{\currentdescription}\currentdescriptionnumberentry\relax
+% \fi}%
+% \to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsetnotation
+ {\iftrialtypesetting\else
+ \clf_settagnotation{\currentnote}\currentnotenumber\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsetnotesymbol
+ {\iftrialtypesetting\else
+ \clf_settagnotationsymbol{\currentnote}\currentnotenumber\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagregisterlocation
+ {\iftrialtypesetting\else
+ \clf_settagregister{\currentregister}\currentregisternumber\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotaglistlocation
+ {\iftrialtypesetting\else
+ \clf_settaglist\currentlistindex\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsetdelimitedsymbol#1%
+ {\iftrialtypesetting\else
+ \clf_settagdelimitedsymbol{#1}\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagsetsubsentencesymbol#1%
+ {\iftrialtypesetting\else
+ \clf_settagsubsentencesymbol{#1}\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagregisterfloat#1#2%
+ {\iftrialtypesetting\else
+ \clf_settagfloat{#1}{#2}\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\let\specialfixedspace \explicitfixedspace
+ \enforced\let\specialobeyedspace \explicitobeyedspace
+ \enforced\let\specialstretchedspace\explicitstretchedspace
+ \enforced\let\specialcontrolspace \explicitcontrolspace
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagregisterformula#1%
+ {\iftrialtypesetting\else
+ \clf_settagformulacontent#1\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagmarginanchor#1%
+ {\iftrialtypesetting\else\clf_settagmarginanchor#1\relax\fi}%
+ \enforced\permanent\protected\def\dotagmargintext#1%
+ {\iftrialtypesetting\else\clf_settagmargintext#1\relax\fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagpublication#1#2%
+ {\iftrialtypesetting\else
+ \clf_settagpublication{#1}{#2}\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
+ \enforced\permanent\protected\def\dotagparagraph#1%
+ {\iftrialtypesetting\else
+ \clf_settagparagraph{#1}\relax
+ \fi}%
+\to \everyenableelements
+
+% The action: \setupbackend[export=yes] % or filename
+
+% maybe xhtml css settings will move to setupexport
+
+% maybe some day a definer
+
+\installcorenamespace{export}
+
+\installparameterhandler \??export {export}
+\installsetuphandler \??export {export}
+
+\setupexport
+ [\c!align=\number\raggedstatus,
+ \c!bodyfont=\bodyfontsize,
+ \c!width=\textwidth,
+ \c!title={\directinteractionparameter\c!title},
+ \c!subtitle={\directinteractionparameter\c!subtitle},
+ \c!author={\directinteractionparameter\c!author},
+ % \c!firstpage=, % imagename
+ % \c!lastpage=, % imagename
+ \c!properties=\v!no, % no: ignore, yes: as attribute, otherwise: use as prefix
+ \c!hyphen=\v!no,
+ \c!svgstyle=,
+ \c!cssfile=,
+ \c!file=]
+
+\resetsystemmode\v!export
+
+\permanent\protected\def\doinitializeexport
+ {\edef\p_export{\backendparameter\c!export}%
+ \ifx\p_export\empty \else
+ % yes | xml
+ \setuptagging[\c!state=\v!start]%
+ \clf_initializeexport
+ \setsystemmode\v!export
+ \exportingtrue
+ \writestatus\m!backend\empty % so messages will stand out a bit
+ \the\everyinitializeexport
+ \writestatus\m!backend\empty % so messages will stand out a bit
+ \enforced\glet\doinitializeexport\relax
+ \fi}
+
+\permanent\protected\def\dostartexport
+ {%\glet\dostartexport\relax
+ \let\currentexport\empty
+ \clf_setupexport
+ align {\exportparameter\c!align}%
+ bodyfont \dimexpr\exportparameter\c!bodyfont\relax
+ width \dimexpr\exportparameter\c!width\relax
+ properties {\exportparameter\c!properties}%
+ hyphen {\exportparameter\c!hyphen}%
+ title {\exportparameter\c!title}%
+ subtitle {\exportparameter\c!subtitle}%
+ author {\exportparameter\c!author}%
+ firstpage {\exportparameter\c!firstpage}%
+ lastpage {\exportparameter\c!lastpage}%
+ svgstyle {\exportparameter\c!svgstyle}%
+ cssfile {\exportparameter\c!cssfile}%
+ file {\exportparameter\c!file}%
+ export {\backendparameter\c!export}%
+ \relax}
+
+\permanent\protected\def\dostopexport
+ {\enforced\glet\dostopexport\relax
+ \clf_finishexport}
+
+\appendtoks
+ \doinitializeexport
+\to \everysetupbackend
+
+\appendtoks
+ \ifexporting
+ \dostartexport
+ \fi
+\to \everystarttext
+
+% better (before pdf gets closed, so we can embed), but it needs testing:
+
+\appendtoks
+ \ifexporting
+ \dostopexport
+ \fi
+\to \everystoptext
+
+\appendtoks
+ \ifexporting
+ \dostartexport % in case it is done inside \starttext
+ \fi
+\to \everystartdocument
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/back-res.mkxl b/tex/context/base/mkiv/back-res.mkxl
new file mode 100644
index 000000000..52317b946
--- /dev/null
+++ b/tex/context/base/mkiv/back-res.mkxl
@@ -0,0 +1,34 @@
+%D \module
+%D [ file=back-res,
+%D version=2019.05.23, % 2009.04.15,
+%D title=\CONTEXT\ Backend Macros,
+%D subtitle=Resources,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Backend Macros / Resources}
+
+\registerctxluafile{back-res}{}
+
+\unprotect
+
+%D We overload the primitives with our own but use a bit of indirection for the
+%D purpose of tracing. Some of these are needed for packages like tikz.
+
+% todo: public implementors (we can update the lua code anyway)
+
+\permanent\protected\def\saveboxresource {\clf_saveboxresource}
+\permanent\protected\def\lastsavedboxresourceindex {\numexpr\clf_lastsavedboxresourceindex\relax}
+\permanent\protected\def\useboxresource {\clf_useboxresource}
+
+\permanent\protected\def\saveimageresource {\clf_saveimageresource}
+\permanent\protected\def\lastsavedimageresourceindex{\numexpr\clf_lastsavedimageresourceindex\relax}
+\permanent\protected\def\lastsavedimageresourcepages{\numexpr\clf_lastsavedimageresourcepages\relax}
+\permanent\protected\def\useimageresource {\clf_useimageresource}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/back-trf.mkxl b/tex/context/base/mkiv/back-trf.mkxl
new file mode 100644
index 000000000..2eedcdd1c
--- /dev/null
+++ b/tex/context/base/mkiv/back-trf.mkxl
@@ -0,0 +1,79 @@
+%D \module
+%D [ file=back-trf,
+%D version=2019.02.08, % 2009.04.15,
+%D title=\CONTEXT\ Backend Macros,
+%D subtitle=Transformations,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\registerctxluafile{back-trf}{}
+
+% rotation
+
+\permanent\protected\def\dostartrotation#1%
+ {\forcecolorhack
+ \clf_startrotation#1\relax} % todo: implement without Q q
+
+\permanent\protected\def\dostoprotation
+ {\clf_stoprotation
+ \forcecolorhack}
+
+% scaling
+
+\permanent\protected\def\dostartscaling#1#2%
+ {\forcecolorhack
+ \clf_startscaling rx #1 ry #2\relax}
+
+\permanent\protected\def\dostopscaling
+ {\clf_stopscaling
+ \forcecolorhack}
+
+% mirroring
+
+\permanent\protected\def\dostartmirroring
+ {\clf_startmirroring}
+
+\permanent\protected\def\dostopmirroring
+ {\clf_stopmirroring}
+
+% transform
+
+\permanent\protected\def\dotransformnextbox#1#2#3#4#5#6%
+ {\dowithnextbox{\dodotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}}}
+
+\permanent\protected\def\dodotransformnextbox#1#2#3#4#5#6%
+ {\hpack
+ {\kern #5\onebasepoint
+ \raise#6\onebasepoint
+ \hpack
+ {\clf_startmatrix rx #1 sx #2 sy #3 ry #4\relax
+ \box\nextbox
+ \clf_stopmatrix}}}
+
+%D \macros
+%D {dostartclipping,dostopclipping}
+%D
+%D Clipping is implemented in such a way that an arbitrary code can be fed.
+%D
+%D \starttyping
+%D \dostartclipping {pathname} {width} {height}
+%D \dostopclipping
+%D \stoptyping
+
+\permanent\protected\def\dostartclipping#1#2#3% we can move this to lua and only set a box here
+ {\forcecolorhack
+ \meta_grab_clip_path{#1}{#2}{#3}%
+ \clf_startclipping{\MPclippath}%
+ \glet\MPclippath\empty}
+
+\permanent\protected\def\dostopclipping
+ {\clf_stopclipping}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/bibl-bib.mkxl b/tex/context/base/mkiv/bibl-bib.mkxl
new file mode 100644
index 000000000..f8a8a7cd9
--- /dev/null
+++ b/tex/context/base/mkiv/bibl-bib.mkxl
@@ -0,0 +1,982 @@
+%D \module
+%D [ file=bibl-bib,
+%D version=2007.08.17,
+%D title=\CONTEXT\ Bibliography Support,
+%D subtitle=Initialization,
+%D author=Hans Hagen \& Taco Hoekwater,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is really obsolete in \LMTX. For now I keep it but it will either go
+%D away. The code is not upgraded, we only deal with macro protection.
+
+\writestatus{loading}{ConTeXt Bibliography Support / Experimental BibTeX}
+
+\registerctxluafile{bibl-bib}{}
+
+\unprotect
+
+% todo: et al limiters
+% todo: split: citationvariant and publicationvariant
+
+%D This interface is under development. As I don't use \BIBTEX\ myself I need some
+%D motivation to spend time on it, and an occasional question on the list can be a
+%D reason. A few examples. As \BIBTEX\ databases can be poluted by local commands,
+%D we need to catch:
+%D
+%D \startbuffer
+%D \defbibtexcommand\MF {MF}
+%D \defbibtexcommand\MP {MP}
+%D \defbibtexcommand\TUB {TUGboat}
+%D \defbibtexcommand\Mc {Mac}
+%D \defbibtexcommand\sltt{\tt}
+%D \defbibtexcommand\<#1>{\type{#1}}
+%D \defbibtexcommand\acro#1{#1}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Let's define a session and load a few databases. We convert to \UTF\ and strip
+%D commands.
+%D
+%D \startbuffer
+%D \definebibtexsession [somebibtex]
+%D \registerbibtexfile [somebibtex] [tugboat.bib]
+%D \registerbibtexfile [somebibtex] [komoedie.bib]
+%D \preparebibtexsession [somebibtex] [convert,strip]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This loads an mapping (work in progress):
+%D
+%D \startbuffer
+%D \def\currentbibtexformat{apa} \input bxml-\currentbibtexformat.mkiv
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D There are several ways to handle the \XML. It helps if you're a bit familiar with
+%D \XML\ processing in \MKIV.
+%D
+%D Here we regular setups. Three elements are mapped but only one is actually used
+%D and applied to root element \type {/bibtex}.
+%D
+%D \startbuffer
+%D \startxmlsetups bibtex
+%D \xmlregistereddocumentsetups{#1}{}
+%D \xmlsetsetup{#1}{bibtex|entry|field}{bibtex:*}
+%D \xmlmain{#1}
+%D \stopxmlsetups
+%D
+%D \startxmlsetups bibtex:bibtex
+%D \xmlfilter{#1}{
+%D /entry[@category='article']
+%D /field[@name='author' and (find(text(),'Hagen') or find(text(),'Hoekwater'))]
+%D /../command(bibtex:format)
+%D }
+%D \stopxmlsetups
+%D
+%D \applytobibtexsession[somebibtex][bibtex]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D A simpler setup is given next. Here we just apply a setup to the root element
+%D directly:
+%D
+%D \startbuffer
+%D \startxmlsetups bibtex:list
+%D \xmlfilter{#1}{/bibtex/entry/command(bibtex:format)}
+%D \stopxmlsetups
+%D
+%D \applytobibtexsession[somebibtex][bibtex:list]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D A slightly more complex expression:
+%D
+%D \startbuffer
+%D \startxmlsetups bibtex:filter
+%D \xmlfilter{#1}{
+%D /bibtex
+%D /entry[@category='article']
+%D /field[@name='author' and (find(text(),'Hagen') or find(text(),'Hoekwater'))]
+%D /../command(bibtex:format)
+%D }
+%D \stopxmlsetups
+%D
+%D \applytobibtexsession[somebibtex][bibtex:filter]
+%D \stopbuffer
+%D
+%D \typebuffer
+
+\newtoks \everydefinebibtexsession
+\newtoks \everypreparebibtexsession
+\newtoks \everysetupbibtexsession
+\setfalse \tracebibtexformat
+
+\protected\def\definebibtexsession {\dosingleargument\dodefinebibtexsession}
+ \def\preparebibtexsession{\dodoubleempty \dopreparebibtexsession}
+\protected\def\setupbibtexsession {\dodoubleargument\dosetupbibtexsession}
+
+\def\dodefinebibtexsession [#1]{\edef\currentbibtexsession{#1}%
+ \ctxcommand{definebibtexsession("#1")}%
+ \the\everydefinebibtexsession}
+
+\def\dopreparebibtexsession[#1][#2]{\edef\currentbibtexsession{#1}%
+ \ctxcommand{preparebibtexsession("#1","bibtex:#1","#2")}%
+ \the\everypreparebibtexsession}
+
+\def\dosetupbibtexsession [#1][#2]{\edef\currentbibtexsession{#1}%
+ \getparameters[\??pb#1][#2]%
+ \the\everysetupbibtexsession}
+
+\def\registerbibtexfile {\dodoubleargument\doregisterbibtexfile}
+\def\registerbibtexentry {\dodoubleargument\doregisterbibtexentry}
+\def\applytobibtexsession {\dodoubleargument\doapplytobibtexsession}
+
+\def\doregisterbibtexfile [#1][#2]{\ctxcommand{registerbibtexfile("#1","#2")}}
+\def\doregisterbibtexentry [#1][#2]{\ctxcommand{registerbibtexentry("#1","#2")}}
+\def\doapplytobibtexsession[#1][#2]{\xmlprocess{bibtex:#1}{#2}{#2}}
+
+\protected\def\bibtexcommand#1%
+ {\ifcsname\??pb:c:#1\endcsname \else
+ \fakebibtexcommand{#1}%
+ \fi
+ \csname\??pb:c:#1\endcsname}
+
+\def\fakebibtexcommand#1%
+ {\ifcsname#1\endcsname
+ \writestatus{bibtex}{unknown command: #1, using built-in context variant}%
+ \setugvalue{\??pb:c:#1}{\dosomebibtexcommand{#1}}%
+ \else
+ \writestatus{bibtex}{unknown command: #1}%
+ \setugvalue{\??pb:c:#1}{\dofakebibtexcommand{#1}}%
+ \fi}
+
+\let\dosomebibtexcommand \getvalue
+\def\dofakebibtexcommand#1{{\tttf#1}}
+\def\defbibtexcommand #1{\setuvalue{\strippedcsname#1}}
+
+\def\bibxmldoifelse#1{\xmldoifelse\currentbibxmlnode{/field[@name='#1']}}
+\def\bibxmldoif #1{\xmldoif \currentbibxmlnode{/field[@name='#1']}}
+\def\bibxmldoifnot #1{\xmldoifnot \currentbibxmlnode{/field[@name='#1']}}
+\def\bibxmlflush #1{\xmlcontext \currentbibxmlnode{/field[@name='#1']}}
+\def\bibxmlsetup {\xmlsetup \currentbibxmlnode} % {#1}
+
+\def\currentbibtexformat{apa} % how to interface this, maybe split loading and key
+\def\currentbibxmlnode {unset}
+\def\currentbibxmltag {unset}
+
+\startxmlsetups bibtex
+ \xmlregistereddocumentsetups{#1}{}
+ \xmlsetsetup{#1}{bibtex|entry|field}{bibtex:*}
+ \xmlmain{#1}
+\stopxmlsetups
+
+\startxmlsetups bibtex:format
+ \bibtexpublicationsparameter\c!before\relax % prevents lookahead
+ \edef\currentbibxmlnode {#1}
+ \edef\currentbibxmltag {\xmlatt{#1}{tag}}
+ \edef\currentbibxmlcategory{\xmlatt{#1}{category}}
+ \ifconditional\tracebibtexformat
+ \tracedbibxmlintro\currentbibxmltag
+ \tracedbibxmlintro\currentbibxmlcategory
+ \fi
+ \ignorespaces
+ \xmlcommand{#1}{.}{bibtex:\currentbibtexformat:\currentbibxmlcategory}
+ \removeunwantedspaces
+ \bibtexpublicationsparameter\c!after\relax % prevents lookahead
+\stopxmlsetups
+
+\startxmlsetups bibtex:list
+ \xmlfilter{#1}{/bibtex/entry/command(bibtex:format)}
+\stopxmlsetups
+
+\startxmlsetups bibtex:bibtex
+ \xmlfilter{#1}{/entry/command(bibtex:format)}
+\stopxmlsetups
+
+% formatters
+
+\let\normalbibxmlflush\bibxmlflush
+
+\definecolor[bibtextracecolor:field] [darkred]
+\definecolor[bibtextracecolor:crossref][darkblue]
+\definecolor[bibtextracecolor:key] [darkgreen]
+
+\def\tracedbibxmlintro #1{{\tttf#1 -> }}
+\def\tracedbibxmlflush #1{\color[bibtextracecolor:field] {\tttf[#1]}}
+\def\tracedbibxmltexts #1{\color[bibtextracecolor:field] {\tttf<#1>}}
+\def\tracedbibxmlcrossref#1{\color[bibtextracecolor:crossref]{\tttf#1}}
+\def\tracedbibxmlkey #1{\color[bibtextracecolor:key] {\tttf#1}}
+
+\def\tracedbibxmltext
+ {\ifconditional\tracebibtexformat
+ \expandafter\tracedbibxmltexts % plural
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\def\bibxmlflush
+ {\ifconditional\tracebibtexformat
+ \expandafter\tracedbibxmlflush
+ \else
+ \expandafter\normalbibxmlflush
+ \fi}
+
+\startxmlsetups bibtex:format:crossref
+ \ifconditional\tracebibtexformat
+ \tracedbibxmlcrossref{\xmlfirst\currentbibxmlnode{/field[@name='crossref']/lower()}}
+ \else
+ \cite[\xmlfirst\currentbibxmlnode{/field[@name='crossref']/lower()}]
+ \fi
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:key
+ \ifconditional\tracebibtexformat
+ \tracedbibxmlkey{\normalbibxmlflush{key}}
+ \else
+ \bibxmlflush{key}
+ \fi
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:common:author
+ \ifconditional\tracebibtexformat
+ \bibxmlflush\currentbibtexvariant
+ \else
+ \xmlfilter{#1}{/field[@name='\currentbibtexvariant']/bibtexconcat('\currentbibtexvariant')}
+ \fi
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:author
+ \begingroup
+ \def\currentbibtexvariant{author}
+ \xmlsetup{#1}{bibtex:format:common:author}
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:artauthor
+ \begingroup
+ \def\currentbibtexvariant{artauthor}
+ \xmlsetup{#1}{bibtex:format:common:author}
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:editor
+ \begingroup
+ \def\currentbibtexvariant{editor}
+ \xmlsetup{#1}{bibtex:format:common:author}
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:doi
+% \bibdoifelse{\@@pb@doi}{#1\expanded{\bibgotoDOI{\@@pb@thekey}{\@@pb@doi}}#2}{#3}
+ *doi*
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:doi
+% \bibdoifelse{\@@pb@biburl}{#1\expanded{\bibgotoURL{\@@pb@thekey}{\@@pb@biburl}}#2}{#3}
+ *url*
+\stopxmlsetups
+
+\startxmlsetups bibtex:format:month
+% {\bibdoifelse\@@pb@month
+% {#1\doifnumberelse\@@pb@month
+% {\doifconversiondefinedelse\@@pbmonthconversion
+% {\convertnumber\@@pbmonthconversion\@@pb@month}{\@@pb@month}}%
+% {\@@pb@month}#2}%
+% {#3}
+ *month*
+\stopxmlsetups
+
+% lists
+
+\def\bibtexlistprocessor
+ {\ctxlua{bibtex.hacks.add(structures.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}}
+
+\appendtoks
+ \definelist[\currentbibtexsession]%
+ \setuplist[\currentbibtexsession][\c!state=\v!start,\c!width=]%
+ \installstructurelistprocessor{\currentbibtexsession:userdata}{\bibtexlistprocessor}%
+\to \everydefinebibtexsession
+
+% \def\installbibtexsorter#1#2%
+% {\setvalue{\??pb:\c!sort:#1}{#2}}
+
+% \installbibtexsorter\v!no {no}
+% \installbibtexsorter\v!author {au}
+% \installbibtexsorter\v!title {ti}
+% \installbibtexsorter\v!short {ab}
+% \installbibtexsorter\empty {no}
+% \installbibtexsorter\s!default{no}
+
+% \setupbibtex
+% [\c!sorttype=\v!cite,
+% \c!sort=no]
+
+% \protected\def\startpublication#1\stoppublication
+% {\blank
+% todo
+% \blank}
+
+% \let\stoppublication\relax
+
+\protected\def\bibtexspace {\removeunwantedspaces\space}
+\protected\def\bibtexperiod {\removeunwantedspaces.\space}
+\protected\def\bibtexcomma {\removeunwantedspaces,\space}
+\protected\def\bibtexlparent {\removeunwantedspaces\space(}
+\protected\def\bibtexrparent {\removeunwantedspaces)\space}
+\protected\def\bibtexlbracket{\removeunwantedspaces\space[}
+\protected\def\bibtexrbracket{\removeunwantedspaces]\space}
+
+% interfacing
+
+% todo : lang en language
+% todo : directions
+
+% variables
+
+\ifdefined\bibtexblock \else \newcount\bibtexblock \fi \bibtexblock\plusone
+\ifdefined\bibtexcounter \else \newcount\bibtexcounter \fi
+
+\newtoks \everysetupbibtexpublications
+\newtoks \everysetupbibtexcitations
+
+\def\bibtexrefprefix{\number\bibtexblock:}
+
+\let\currentbibtexsession\s!default
+\let\currentbibtexvariant\s!default
+
+% parameters: session+variant variant session shared
+
+\def\bibtexpublicationsparameter#1%
+ {\csname
+ \ifcsname\??pb\currentbibtexsession:\currentbibtexvariant#1\endcsname
+ \??pb\currentbibtexsession:\currentbibtexvariant#1%
+ \else\ifcsname\??pb:\currentbibtexvariant#1\endcsname
+ \??pb:\currentbibtexvariant#1%
+ \else\ifcsname\??pb\currentbibtexsession#1\endcsname
+ \??pb\currentbibtexsession#1%
+ \else\ifcsname\??pb#1\endcsname
+ \??pb#1%
+ \else
+ \s!empty
+ \fi\fi\fi\fi
+ \endcsname}
+
+\def\bibtexcitationparameter#1%
+ {\csname
+ \ifcsname\??pv\currentbibtexsession:\currentbibtexvariant#1\endcsname
+ \??pv\currentbibtexsession:\currentbibtexvariant#1%
+ \else\ifcsname\??pv:\currentbibtexvariant#1\endcsname
+ \??pv:\currentbibtexvariant#1%
+ \else\ifcsname\??pv\currentbibtexsession#1\endcsname
+ \??pv\currentbibtexsession#1%
+ \else\ifcsname\??pv#1\endcsname
+ \??pv#1%
+ \else
+ \s!empty
+ \fi\fi\fi\fi
+ \endcsname}
+
+% setup commands
+
+\protected\def\setupbibtexpublications
+ {\let\currentpublicationclass\??pb
+ \let\everysetupbibtexwhatever\everysetupbibtexpublications
+ \dodoubleargument\dosetupbibtexwhatever}
+
+\protected\def\setupbibtexcitations
+ {\let\currentpublicationclass\??pv
+ \let\everysetupbibtexwhatever\everysetupbibtexcitations
+ \dodoubleargument\dosetupbibtexwhatever}
+
+\protected\def\setupbibtexpublicationvariants
+ {\let\currentpublicationclass\??pb
+ \let\everysetupbibtexwhatever\everysetupbibtexpublications
+ \dotripleargument\dosetupbibtexwhatevervariant}
+
+\protected\def\setupbibtexcitationvariants
+ {\let\currentpublicationclass\??pv
+ \let\everysetupbibtexwhatever\everysetupbibtexcitations
+ \dotripleargument\dosetupbibtexwhatevervariant}
+
+\def\dosetupbibtexwhatever[#1][#2]% [sessionlist] [setup]
+ {\ifsecondargument
+ % sessions setups
+ \def\dobtxcommand##1{\getparameters[\currentpublicationclass##1][#2]}%
+ \processcommalist[#1]\dobtxcommand
+ \else
+ % setups
+ \getparameters[\currentpublicationclass][#1]%
+ \the\everysetupbibtexwhatever
+ \fi}
+
+\def\dosetupbibtexwhatevervariant[#1][#2][#3]% [sessionlist] [variantlist] [setup]
+ {\ifthirdargument
+ % sessions variants setups
+ \def\dobtxcommand##1%
+ {\def\dodobtxcommand####1{\getparameters[\currentpublicationclass##1:####1][#3]}%
+ \processcommalist[#2]\dodobtxcommand}%
+ \processcommalist[#1]\docbtxommand
+ \else\ifsecondargument
+ % variants setups
+ \def\dobtxcommand##1{\getparameters[\currentpublicationclass:##1][#2]}%
+ \processcommalist[#1]\dobtxcommand
+ \else
+ % setups
+ \getparameters[\currentpublicationclass][#1]%
+ \the\everysetupbibtexwhatever
+ \fi\fi}
+
+% some initializations
+
+\setupbibtexcitationvariants
+ [author,authoryear,authoryears]
+ [\c!namesep={, }]
+
+% loading alternatives (apa etc)
+
+\def\doloadbibtexpublicationalternative
+ {\ifproductionrun
+ \edef\bibtexpublicationsalternative{\@@pbalternative}% parent
+ \ifx\bibtexpublicationsalternative\empty \else
+ \processcommacommand[\bibtexpublicationsalternative]\dodoloadbibtexpublicationalternative
+ \let\@@pbalternative\empty
+ \fi
+ \fi}
+
+\def\dodoloadbibtexpublicationalternative#1%
+ {\doonlyonce{#1}
+ {\startreadingfile
+ \readsysfile{bxml-#1.mkiv}
+ {\showmessage\m!publications{6}{bxml-#1}}
+ {\showmessage\m!publications{1}{bxml-#1}}%
+ \stopreadingfile}}
+
+\appendtoks
+ \doloadbibtexpublicationalternative
+\to \everysetupbibtexpublications
+
+% we expect at least one invocation of the setup commands
+% because otherwise we always load the apa style even if
+% no publications are used
+%
+% \appendtoks
+% \doloadbibtexpublicationalternative
+% \to \everystarttext
+
+% whatever, should be key
+
+\def\bibtexleftnumber#1{#1\hfill~}
+
+% testing
+
+% \showmessage\m!publications{5}{#1 is unknown}\secondoftwoarguments}
+
+\let\doifbibreferencefoundelse\secondofthreearguments
+
+% lists
+
+\newtoks\everysetupbibtexlistplacement
+
+% this will change as we need it too often .. we will use context.thebibtexnamesep
+
+\appendtoks
+ \ctxlua {bibtex.authors.setsettings {
+ namesep = \!!bs\bibtexpublicationsparameter\c!namesep\!!es,
+ lastnamesep = \!!bs\bibtexpublicationsparameter\c!lastnamesep\!!es,
+ finalnamesep = \!!bs\bibtexpublicationsparameter\c!finalnamesep\!!es,
+ firstnamesep = \!!bs\bibtexpublicationsparameter\c!firstnamesep\!!es,
+ juniorsep = \!!bs\bibtexpublicationsparameter\c!juniorsep\!!es,
+ vonsep = \!!bs\bibtexpublicationsparameter\c!vonsep\!!es,
+ surnamesep = \!!bs\bibtexpublicationsparameter\c!surnamesep\!!es,
+ namesep = \!!bs\bibtexpublicationsparameter\c!namesep\!!es,
+ lastnamesep = \!!bs\bibtexpublicationsparameter\c!lastnamesep\!!es,
+ finalnamesep = \!!bs\bibtexpublicationsparameter\c!finalnamesep\!!es,
+ author = {
+ etallimit = \!!bs\bibtexpublicationsparameter\c!authoretallimit\!!es,
+ etaldisplay = \!!bs\bibtexpublicationsparameter\c!authoretaldisplay\!!es,
+ etaltext = \!!bs\bibtexpublicationsparameter\c!authoretaltext\!!es,
+ },
+ editor = {
+ etallimit = \!!bs\bibtexpublicationsparameter\c!editoretallimit\!!es,
+ etaldisplay = \!!bs\bibtexpublicationsparameter\c!editoretaldisplay\!!es,
+ etaltext = \!!bs\bibtexpublicationsparameter\c!editoretaltext\!!es,
+ },
+ artauthor = {
+ etallimit = \!!bs\bibtexpublicationsparameter\c!artauthoretallimit\!!es,
+ etaldisplay = \!!bs\bibtexpublicationsparameter\c!artauthoretaldisplay\!!es,
+ etaltext = \!!bs\bibtexpublicationsparameter\c!artauthoretaltext\!!es,
+ },
+ } }%
+\to \everysetupbibtexlistplacement
+
+\def\completebibtexpublications{\dodoubleempty\docompletebibtexpublications}
+\protected\def\placebibtexpublications {\dodoubleempty\doplacebibtexpublications}
+
+\def\docompletebibtexpublications[#1][#2]% title might become obsolete, just headtext
+ {\begingroup
+ \edef\currentbibtexsession{#1}%
+ \let\currentlist\currentbibtexsession
+ \setuplist[\currentbibtexsession][\c!criterium=\v!previous,#2]
+ \edef\currentbibtexsessiontitle{\namedlistparameter\currentbibtexsession\c!title}%
+ \ifx\currentbibtexsessiontitle\empty
+ \normalexpanded{\startnamedsection[\v!chapter][\c!reference=\currentbibtexsession,\c!title={\headtext{\currentbibtexsession}}]}%
+ \else
+ \normalexpanded{\startnamedsection[\v!chapter][\c!reference=\currentbibtexsession,\c!title={\currentbibtexsessiontitle}]}%
+ \fi
+ \dodoplacebibtexpublications
+ \stopnamedsection
+ \endgroup}
+
+\def\doplacebibtexpublications[#1][#2]%
+ {\begingroup
+ \edef\currentbibtexsession{#1}%
+ \let\currentlist\currentbibtexsession
+ \setuplist[\currentbibtexsession][\c!criterium=\v!previous,#2]%
+ \dodoplacebibtexpublications
+ \endgroup}
+
+\def\dodoplacebibtexpublications
+ {\determinelistcharacteristics[\currentbibtexsession]%
+ \the\everysetupbibtexlistplacement
+ \forgetall
+ \typesetbibtexlist
+ \global\advance\bibtexblock\plusone}
+
+\setvalue{\??pb:\c!numbering:\v!short}#1% todo var s -> short tag
+ {\bibtexlistnumberbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexgetshort\currentpublicationtag}}}
+
+\setvalue{\??pb:\c!numbering:\v!bib}#1% todo var n -> number
+ {\bibtexlistnumberbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexgetnumber\currentpublicationtag}}}
+
+\setvalue{\??pb:\c!numbering:\s!unknown}#1%
+ {\bibtexlistnumberbox{\bibtexpublicationsparameter\c!numbercommand{#1}}}
+
+\def\@@pblimitednumber % name
+ {\csname\??pb:\c!numbering:%
+ \ifcsname\??pb:\c!numbering:\currentbibtexnumbering\endcsname
+ \currentbibtexnumbering
+ \else
+ \s!unknown
+ \fi
+ \endcsname}
+
+\appendtoks
+ \edef\currentbibtexnumbering{\bibtexpublicationsparameter\c!numbering}%
+ \ifx\currentbibtexnumbering\v!no
+ \setuplist[\currentbibtexsession][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]%
+ \else
+ \setuplist[\currentbibtexsession][\c!numbercommand=\@@pblimitednumber]%
+ \fi
+\to \everysetupbibtexlistplacement
+
+\newdimen\bibtexnumberwidth
+
+\def\bibtexlistnumberbox{\hbox \ifcase\bibtexnumberwidth\else to \bibtexnumberwidth\fi}
+
+\appendtoks
+ \doifelse{\bibtexpublicationsparameter\c!autohang}\v!yes
+ {\ifx\currentbibtexnumbering\v!short
+ \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexpublicationsparameter\c!samplesize}}%
+ \else
+ \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\ctxlua{tex.write(structures.lists.size())}}}%
+ \fi
+ \bibtexnumberwidth\wd\scratchbox
+ \setuplist[\currentbibtexsession][\c!distance=\zeropoint]}
+ {\doifelsenothing{\bibtexpublicationsparameter\c!width}
+ {\bibtexnumberwidth\zeropoint}
+ {\bibtexnumberwidth\bibtexpublicationsparameter\c!width}}%
+ \setuplist[\currentbibtexsession][\c!width=\bibtexnumberwidth]%
+\to \everysetupbibtexlistplacement
+
+\appendtoks
+ \let\maybeyear\gobbleoneargument
+ \let\noopsort \gobbleoneargument
+\to \everysetupbibtexlistplacement
+
+\appendtoks
+ \doifelse{\bibtexpublicationsparameter\c!maybeyear}\v!off
+ {\let\maybeyear\gobbleoneargument}
+ {\let\maybeyear\firstofoneargument}%
+\to \everysetupbibtexlistplacement
+
+\appendtoks
+ \doifnot{\bibtexpublicationsparameter\c!option}\v!continue
+ {\global\bibtexcounter\zerocount}%
+\to \everysetupbibtexlistplacement
+
+\appendtoks
+ \edef\currentbibtexcriterium{\namedlistparameter\currentbibtexsession\c!criterium}%
+\to \everysetupbibtexlistplacement
+
+\def\typesetbibtexlist
+ {\begingroup
+ \startpacked[\v!blank]%
+ \doif{\namedlistparameter\currentbibtexsession\c!criterium}\v!cite
+ {\setuplist[\currentbibtexsession][\c!criterium=\v!here]}%
+ \doifelse{\bibtexpublicationsparameter\c!method}\v!local
+ {\ctxlua{bibtex.hacks.reset(1)}}% function can take method
+ {\ctxlua{bibtex.hacks.reset(2)}}%
+ \strc_lists_place_current
+ {\currentbibtexsession}
+ {\currentbibtexcriterium}
+ {}%
+ {\namedlistparameter\currentbibtexsession\c!extras}%
+ {\namedlistparameter\currentbibtexsession\c!order}%
+ \ctxlua{bibtex.hacks.flush("\bibtexpublicationsparameter\c!sorttype")}%
+ \stoppacked
+ \endgroup}
+
+\protected\def\typesetbibtexpublication#1%
+ {\edef\currentbibtexsessiontag{#1}%
+ \ifx\currentbibtexsessiontag\empty
+ % can't really happen
+ \else\ifx\currentbibtexcriterium\v!all
+ \dotypesetbibtexpublication % was \doplacepublicationindeed
+ \else
+ \ctxlua{bibtex.hacks.doifalreadyplaced("\currentbibtexsessiontag")}
+ \donothing
+ \dotypesetbibtexpublication
+ \fi\fi}
+
+\def\dotypesetbibtexpublication
+ {\doifelsebibreferencefound\currentbibtexsessiontag
+ {\global\advance\bibtexcounter\plusone
+ \ctxlua{bibtex.hacks.registerplaced("\currentbibtexsessiontag")}%
+ \let\currentlist\currentbibtexsession
+ \let\currentlistentrynumber \bibtexcounter
+ \let\currentlistentrytitle \thebibtexpublicationlistelement
+ \let\currentlistentrypagenumber\empty
+ \strc_lists_apply_renderingsetup}
+ {}} % invalid
+
+\def\thebibtexpublicationlistelement
+ {\strut
+ \expanded{\reference[\bibtexrefprefix\currentbibtexsessiontag]{\number\bibtexcounter}}%
+ \dotypesetabibtexpublication\currentbibtexsessiontag
+ \strut}
+
+\def\dotypesetabibtexpublication#1%
+ {\begingroup
+ \ignorespaces
+ \xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/command(bibtex:format)}%
+ \removeunwantedspaces
+% \ignorespaces
+% \bibalternative{\bibgetvart{#1}}%
+% \removeunwantedspaces
+ \endgroup}
+
+\def\doprocessbibtexentry#1{\typesetbibtexpublication{#1}}
+
+% citations
+
+\protected\def\bibtexcitation[#1]%
+ {\edef\currentbibtexsession{#1}%
+ \strictdoifelsenextoptional\dobibtexcitation\dobibtexref}
+
+\def\dobibtexref#1%
+ {\dodobibtexcitation[#1][]}
+
+\def\dobibtexcitation[#1]%
+ {\strictdoifelsenextoptional{\dodobibtexcitation[#1]}{\dodobibtexcitation[#1][]}}
+
+\def\dodobibtexcitation[#1][#2]%
+ {\dontleavehmode
+ \begingroup
+ \doifelsenothing{#2}\secondargumentfalse\secondargumenttrue
+ \ifsecondargument
+ \dowhateverbibtexcitation{#1}{#2}%
+ \else
+ \donumberedbibtexcitation{#1}%
+ \fi
+ \endgroup}
+
+\def\dowhatevercitation#1#2%
+ {\processcommalist[#2]\dobibtexcitationindeed
+ \setupinteraction[\c!style=]% use flag instead
+ \doifelseassignment{#1}
+ {\getparameters[\??pb\??pb][\c!alternative=,\c!extras=,#1]%
+ \edef\currentbibtexvariant{\@@pb@@pbalternative}%
+ \ifx\currentbibtexvariant\empty
+ \edef\currentbibtexvariant{\bibtexpublicationparameter\c!refcommand}%
+ \fi
+ \ifx\@@pb@@pbextras\empty
+ \setupcite[\currentbibtexvariant][#1]%
+ \else
+ \edef\@@pb@@pbextras{{\@@pb@@pbextras\ifdefined\@@pb@@pbright\@@pb@@pbright\else\bibtexpublicationparameter\c!right\fi}}%
+ \expanded{\setupcite[\currentbibtexvariant][#1,\c!right=\@@pb@@pbextras]}%
+ \fi}%
+ {\def\currentbibtexvariant{#1}}%
+ \getvalue{bibtex\currentbibtexvariant ref}[#2]}
+
+\def\donumberedbibtexcitation#1%
+ {\processcommalist[#1]\dobibtexcitationindeed
+ \setupinteraction[\c!style=]%
+ \edef\currentbibtexvariant{\bibtexcitationparameter\c!refcommand}%
+ \getvalue{bibtex\currentbibtexvariant ref}[#1]}
+
+\def\dobibtexcitationindeed#1%
+ {\iftrialtypesetting \else
+ \expanded{\writedatatolist[\currentbibtexsession][bibref=#1]}%
+ \fi}
+
+\def\nobibtexcitation[#1]%
+ {\processcommalist[#1]\dobibtexcitationindeed}
+
+\def\bibtexnumref[#1]%
+ {\dontleavehmode
+ \begingroup
+ \bibtexcitationparameter\v!left
+ \penalty\plustenthousand
+ \ctxlua{bibtex.hacks.resolve("","\number\bibtexblock","#1")}%
+ \bibtexcitationparameter\v!right
+ \endgroup}
+
+\def\dowithbibtexnumrefconnector#1#2%
+ {\ifnum#1>\plusone
+ \ifnum#2>\plusone
+ \ifnum#2=#1\relax
+ \bibtexpublicationsparameter\c!lastpubsep
+ \else
+ \bibtexpublicationsparameter\c!pubsep
+ \fi
+ \fi
+ \fi}
+
+\def\dowithbibtexnumref#1#2#3#4#5% n, i, prefix block ref
+ {\dowithbibtexnumrefconnector{#1}{#2}%
+ \def\bibtexrefprefix{#4:}%
+ \inbiblink[#5]}
+
+\def\dowithbibtexnumrefrange#1#2#3#4#5#6#7% n, i, prefix block ref
+ {\dowithbibtexnumrefconnector{#1}{#2}%
+ \def\bibtexrefprefix{#4:}%
+ \inbiblink[#5]%
+ \endash
+ \def\bibtexrefprefix{#6:}%
+ \inbiblink[#7]}
+
+\def\nobibtexnumref#1%
+ {[#1]}
+
+% hm
+
+% \def\@@pbinumbercommand{\executeifdefined{\??pb:\c!numbercommand:\@@pbnumbering}\firstofoneargument}
+
+% \letvalue{\??pb:\c!numbercommand:\v!yes }\firstofoneargument
+% \letvalue{\??pb:\c!numbercommand:\v!no }\gobbleoneargument
+% \setvalue{\??pb:\c!numbercommand:\v!short}{\bibtexgetshort\currentpublicationtag\gobbleoneargument}
+% \setvalue{\??pb:\c!numbercommand:\v!bib }{\bibtexgetnumber\currentpublicationtag\gobbleoneargument}
+
+% \def\bibalternative#1{\csname\??pv\@@currentalternative#1\endcsname}
+
+% basic setup
+
+% parent -> publicationlist
+%
+% \setuplist
+% [\currentbibtexsession]
+% [\c!samplesize={AA99},
+% \c!alternative=a,
+% \c!interaction=,
+% \c!pagenumber=\v!no,
+% #1,
+% \c!command=]
+
+% \setuppublicationlist
+% [\c!title=,
+% \c!command=\dospecialbibinsert,
+% \c!maybeyear=\v!on]
+
+\setupbibtexpublications
+ [\c!monthconversion=,
+ \c!alternative=apa,
+ \c!method=\v!global,
+ \c!refcommand=num,
+ \c!numbercommand=\bibtexleftnumber]
+
+\setupbibtexcitations % command ?
+ [\c!refcommand=num]
+
+% helpers
+
+\protected\def\doifelsebibtexinteraction
+ {\iflocation
+ \edef\temp{\bibtexcitationparameter\c!interaction}%
+ \ifx\temp\v!stop
+ \doubleexpandafter\secondoftwoarguments
+ \else
+ \doubleexpandafter\firstoftwoarguments
+ \fi
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\let\doifbibtexinteractionelse\doifelsebibtexinteraction
+
+% variants
+
+% todo: lastsep here
+
+\newconditional\firstbibtexrefsep
+
+\def\bibtexresetrefsep
+ {\settrue\firstbibtexrefsep}
+
+\def\bibtexinsertrefsep
+ {\ifconditional\firstbibtexrefsep
+ \setfalse\firstbibtexrefsep
+ \else
+ \bibtexcitationparameter\c!pubsep
+ \fi}
+
+\def\inbibtexlink#1#2%
+ {\doifelsereferencefound{\bibtexrefprefix#1}
+ {\goto{#2}[\bibtexrefprefix#1]}
+ {!#1!}}
+
+\def\dobibtexgotolink#1#2%
+ {\doifelsereferencefound{\bibtexrefprefix#1}
+ {\goto{#2}[\bibtexrefprefix#1]}
+ {!#1!}}
+
+\def\dobibattexlink#1#2%
+ {\doifelsereferencefound{\bibtexrefprefix#1}
+ {\at{#2}[\bibtexrefprefix#1]}
+ {!#1!}}
+
+\def\dobibtexurllink#1#2%
+ {\expanded{\useURL[bibtex:url:#1][#2]}%
+ \doifelsebibtexinteraction
+ {\goto{\url[bibtex:url:#1]}[url(bibtex:url:#1)]}
+ {\url[bibtex:url:#1]}}
+
+% todo: style, color
+
+\protected\def\bibtexdataref {\dodoubleargument\dobibtexdataref}
+\protected\def\bibtextyperef {\dodoubleargument\dobibtextyperef}
+\protected\def\bibtexkeyref {\dodoubleargument\dobibtexkeyref}
+\protected\def\bibtexserialref {\dodoubleargument\dobibtexserialref}
+\protected\def\bibtexurlref {\dodoubleargument\dobibtexurlref}
+\protected\def\bibtexdoiref {\dodoubleargument\dobibtexdoiref}
+\protected\def\bibtexpageref {\dodoubleargument\dobibtexpageref}
+\protected\def\bibtexnoneref {\dodoubleargument\dobibtexnoneref}
+\protected\def\bibtexshortref {\dodoubleargument\dobibtexshortref}
+\protected\def\bibtexyearref {\dodoubleargument\dobibtexyearref}
+\protected\def\bibtexauthorref {\dodoubleargument\dobibtexauthorref}
+\protected\def\bibtexauthoryearref {\dodoubleargument\dobibtexauthoryearref}
+\protected\def\bibtexauthoryearsref{\dodoubleargument\dobibtexauthoryearsref}
+
+\def\dobibtexdataref {\doprocessbibtexref\dodobibtexdataref {ref}} % [#1][#2]
+\def\dobibtextyperef {\doprocessbibtexref\dodobibtextyperef {type}} % [#1][#2]
+\def\dobibtexkeyref {\doprocessbibtexref\dodobibtexkeyref {key}} % [#1][#2]
+\def\dobibtexserialref {\doprocessbibtexref\dodobibtexserialref {serial}} % [#1][#2]
+\def\dobibtexurlref {\doprocessbibtexref\dodobibtexurlref {url}} % [#1][#2]
+\def\dobibtexdoiref {\doprocessbibtexref\dodobibtexdoiref {doi}} % [#1][#2]
+\def\dobibtexpageref {\doprocessbibtexref\dodobibtexpageref {page}} % [#1][#2]
+\def\dobibtexnoneref {\doprocessbibtexref\dodobibtexnoneref {none}} % [#1][#2]
+\def\dobibtexshortref {\doprocessbibtexref\dodobibtexshortref {short}} % [#1][#2]
+\def\dobibtexyearref {\doprocessbibtexref\dodobibtexyearref {year}} % [#1][#2]
+\def\dobibtexauthorref {\doprocessbibtexref\dodobibtexauthorref {author}} % [#1][#2]
+\def\dobibtexauthoryearref {\doprocessbibtexref\dodobibtexauthoryearref {authoryear}} % [#1][#2]
+\def\dobibtexauthoryearsref{\doprocessbibtexref\dodobibtexauthoryearsref{authoryears}} % [#1][#2]
+
+\def\doprocessbibtexref#1#2[#3][#4]%
+ {\edef\currentbibtexsession{#3}%
+ \edef\currentbibtexvariant{#2}%
+ \def\dodoprocessbibtexref##1%
+ {% test for existence
+ \edef\currentbibtextag{##1}%
+ \bibtexinsertrefsep
+ #1{##1}}%
+ \bibtexresetrefsep
+ \bibtexcitationparameter\v!left
+ \processcommalist[#4]\dodoprocessbibtexref\relax
+ \bibtexcitationparameter\v!right}
+
+\def\dodobibtexdataref#1%
+ {\dotypesetabibtexpublication{#1}}
+
+\def\dodobibtextyperef#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/attribute('category')}}%
+ \bibtexrefcontent}
+
+\def\dodobibtexkeyref#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='key']/context()}}%
+ \dobibtexgotolink{#1}{\bibtexrefcontent}}
+
+\def\dodobibtexserialref#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/match()}}%
+ \dobibtexgotolink{#1}{\bibtexrefcontent}}
+
+\def\dodobibtexurlref#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/field[@name='url']/context()}}%
+ \dobibtexurllink{#1}{\bibtexrefcontent}}
+
+\def\dodobibtexdoiref#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/field[@name='doi']/context()}}%
+ \dobibtexurllink{#1}{http://dx.doi.org/\bibtexrefcontent}}
+
+\def\dodobibtexpageref#1%
+ {\dobibtexatlink{#1}{}} % second argument can become 'page'
+
+\def\dodobibtexnoneref#1%
+ {}
+
+\def\dodobibtexshortref#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/bibtexshort()}}%
+ \dobibtexgotolink{#1}{\bibtexrefcontent}}
+
+\def\dodobibtexyearref#1%
+ {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/field[@name='year']/context()}}%
+ \bibtexrefcontent}
+
+% \def\bibmaybeinteractive#1#2%
+% {\doifelsevalue{@@pv\@@currentalternative\c!compress}
+% {\ifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}}
+% {#2}}
+
+% \def\bibauthornumref[#1]%
+% {\getcommalistsize[#1]%
+% \global\bibitemcounter\commalistsize
+% \bibresetrefsep
+% \processcommalist[#1]\dobibauthornumref }
+%
+% \def\dobibauthornumref#1%
+% {\bibinsertrefsep
+% \doifbibreferencefoundelse{#1}
+% {\begingroup
+% \bibgetvara{#1}%
+% \bibalternative\c!inbetween
+% \setuppublications[\c!refcommand=num]%
+% \cite[#1]%
+% \endgroup}
+% {}}
+
+% compress years
+% andtext namesep
+% otherstext authoretallimit
+
+% we will use context.* instead at the lua end because it saves us passing settings
+
+% \def\thebibtexpubsep {\bibtexpublicationsparameter\c!pubsep}
+% \def\thebibtexlastpubsep {\bibtexpublicationsparameter\c!lastpubsep}
+% \def\thebibtexfinalpubseparator{\bibtexpublicationsparameter\c!lastpubsep}
+
+\def\dodobibtexauthorref #1{\ctxlua{bibtex.authorref ("bibtex:\currentbibtexsession","#1","normal","author")}}
+\def\dodobibtexauthoryearref #1{\ctxlua{bibtex.authoryearref ("bibtex:\currentbibtexsession","#1","normal","author")}}
+\def\dodobibtexauthoryearsref#1{\ctxlua{bibtex.authoryearsref("bibtex:\currentbibtexsession","#1","normal","author")}}
+
+\protected\def\bibtexsingularplural#1#2{\ctxlua{bibtex.singularorplural(\!!bs#1\!!es,\!!bs#2\!!es)}}
+
+\protect \endinput
+
diff --git a/tex/context/base/mkiv/bibl-tra.mkxl b/tex/context/base/mkiv/bibl-tra.mkxl
new file mode 100644
index 000000000..c85a664ba
--- /dev/null
+++ b/tex/context/base/mkiv/bibl-tra.mkxl
@@ -0,0 +1,1509 @@
+%D \module
+%D [ file=bibl-tra,
+%D version=2009.08.22,
+%D title=\CONTEXT\ Publication Module,
+%D subtitle=Publications,
+%D author=Taco Hoekwater,
+%D date=\currentdate,
+%D copyright={Public Domain}]
+%C
+%C Donated to the public domain.
+
+%D This is really obsolete in \LMTX. For now I keep it but it will either go
+%D away. The code is not upgraded, we only deal with macro protection.
+
+% % % % watch out ... bibl-tra-new.mkiv is work in progress % % % %
+
+% % % % mlbibtex also supports context and we can run that instead of bibtex % % % %
+
+%D This module has been adapted to \MKIV\ by Hans Hagen so if things go wrong, he is
+%D to blame. The changes concern references and lists but teh rendering itself is
+%D unchanged. Future versions might provide variants as we have plans for an
+%D upgrade.
+%D
+%D We use a still somewhat experimental extension to the list mechanism. Eventually
+%D the bibtex module will use the bibl loader and access the data by means of lpath
+%D expressions. In that case we don't need to process the bibliography but still
+%D need to track usage as done here.
+%D
+%D A bit ongoing: make more local macros prefixed with bib, i.e. the bib namespace
+%D is reserved.
+
+%D Todo: commandhandler
+
+\writestatus{loading}{ConTeXt Bibliography Support / BibTeX}
+
+\definefilesynonym[bib][obsolete]
+
+\registerctxluafile{bibl-tra}{}
+
+%D The original was developed independantly by Taco Hoekwater while still working
+%D for Kluwer Academic publishers (it still used the dutch interface then).
+%D Development continued after he left Kluwer, and in Januari 2005, the then already
+%D internationalized file was merged with the core distribution by Hans Hagen. The
+%D current version is once again by Taco.
+%D
+%D More documentation and additional resources can be found on the contextgarden:
+%D \hyphenatedurl {http://wiki.contextgarden.net//Bibliography}.
+
+%D \subject{DONE (dd/mm/yyyy)}
+%D
+%D \startitemize
+%D \item add author definition (and associated system variable) (26/05/2005)
+%D \item add finalnamesep support for Oxford comma (17/09/2005)
+%D \item add \type{\insert...} for: doi, eprint, howpublished (19/09/2005)
+%D \item allow a defaulted \type{\setupcite} (19/11/2005)
+%D \item renamed citation type 'number' to 'serial' (19/11/2005)
+%D \item better definition of \type{\inverted...author} (19/11/2005)
+%D \item don't reset [numbercommand] in \type {\setuppublication} by default (20/11/2005)
+%D \item don't disable other \type {\setuppublication} keys if alternative is present (20/11/2005)
+%D \item drop \type{\sanitizeaccents} (20/11/2005)
+%D \item added \type{\nocite} and \type{\cite[none]} (21/11/2005)
+%D \item added headtext for it (23/11/2005)
+%D \item make \type{\cite[url]} and \type{\cite[doi]} interactive (23/11/2005)
+%D \item make right-aligned labels in the list work even when autohang=no
+%D \item use 'et al.' instead of 'et.al.'. Pointed out by Peter M\"unster (30/12/2005)
+%D \item added headtext for cz (31/12/2005)
+%D \item Keep whitespace after \type{\cite} with single argument (31/12/2005)
+%D \item Fix broken \type{\cite{}} support (31/12/2005)
+%D \item Use \type{\readfile} inside \type{\usepublications} instead of \type{\readsysfile} (12/01/2006)
+%D \item Use \type{\currentbibyear} and \type{\currentbibauthor} instead of \type{\YR} and \type{\AU} (05/02/2006)
+%D \item Fix compressed version of authoryear style (05/02/2006)
+%D \item Rename the clashing data fields \type{\url} and \type{\type} to \type{\biburl} and \type{\bibtype} (05/02/2006)
+%D \item Added two french bibl files from Renaud Aubin (06/02/2006)
+%D \item Five new bib class and eight extra bib fields, for IEEEtran (07/02/2006)
+%D \item French keyword translation, provided by Renaud (08/02/2006)
+%D \item fix underscores in undefined keys (22/02/2006)
+%D \item Destroy interactivity in labels of the publication list (13/03/2006)
+%D \item fix multi-cite list compression (11/4/2006)
+%D \item fix \type{\getcitedata} (11/4/2006)
+%D \item magic for chapter bibs (18-25/4/2006)
+%D \item language setting (25/4/2006)
+%D \item use \type{\hyphenatedurl} for \type{\inserturl} (25/4/2006)
+%D \item Add \type{\docitation} to \type{\nocite}(26/4/2006)
+%D \item patents can have numbers, added to bst files (26/4/2006)
+%D \item \type{\docitation} needs a \type{\iftrialtypesetting} (27/4/2006)
+%D \item \type{\filllocalpublist}'s loop is bound by definedness, not resolvedness (27/4/2006)
+%D \item \type{\setuppublications[monthconversion=]} added (15/5/2006)
+%D \item use \type{\undefinedreference} instead of bare question marks (15/5/2006)
+%D \item add grouping around \type{\placepublications} commands (16/5/2006)
+%D \item fix a bug in \type{\cite{<item>}} (17/5/2006)
+%D \item support \type{\cite[authornum]} (18/5/2006)
+%D \item make \type{\cite} unexpandable (20/6/2006)
+%D \item allow hyperlinks in author\&year combo's
+%D (cite list compression has to be off) (20/6/2006)
+%D \item fix duplicate labels for per-chapter style (20/6/2006)
+%D \item allow \type{\setupcite[interaction=(start|stop)]}
+%D \item fix the item number in the publication list with 'numbering=yes' (22/6/2006)
+%D \item make the default criterium for \type{\placepublications} be \type{previous} (23/6/2006)
+%D \item fix \type{\normalauthor} and \type{\normalshortauthor} spacing (29/6/2006)
+%D \item do not typeset empty arguments to \type{\typesetapublication} (29/6/2006)
+%D \item add \type{symbol=none} to \type{\setuplist} in unnumbered
+%D mode to prevent typesetting of bare numbers (29/6/2006)
+%D \item remove two incorrect spaces from bibl-num.tex (1/7/2006)
+%D \item reset font styles within \type{\cite}, so that font switches
+%D in \type{left} stay in effect (12/7/2006)
+%D \item guard added against loading bbl files multiple times (13/7/2006)
+%D \item fix \type{\cite[num]} with compression is on. (14/7/2006)
+%D \item test \type{\iflocation} before deciding to use the
+%D interactive version of cite (18/7/2006)
+%D \item support \type{\setupcite[authoretallimit=1]} (18/7/2006)
+%D \item support use of \type{\cite} within titles and captions by
+%D saveguarding the list item extraction and reference placement
+%D code (19/7/2006)
+%D \item support \type{\setuppublicationlist[title=\chapter]} (4/8/2006)
+%D \item use the expansion of \type{\headtext{pubs}} (4/8/2006)
+%D \item hook added for repeated authors in publication list
+%D \type{\setuppublicationlist[artauthorcommand=\mythreeargscommand]}
+%D (4/8/2006)
+%D \item make the bracketed arguments of \type{\artauthor}, \type{\author}
+%D and \type{\editor} (bbl commands) optional (4/8/2006)
+%D \item the constants \type{sorttype}, \type{compress} and
+%D \type{autohang} have moved to the core (8/8/2006)
+%D \item bibtex is now registered as a program to be run by texexec (8/8/2006)
+%D \item fix a bug in \type{\setupcite[authoretallimit=1]} (9/8/2006)
+%D \item fix a bug inside citations that prevented lastpubsep from ever being
+%D used due to a volatile \type{\commalistsize} (25/8/2006).
+%D \item added the possibility of \type{\placepublications[option=continue]}
+%D (6/9/2006)
+%D \item Mojca translated Master's Thesis to Masterarbeit (bibl-apa-de.tex)
+%D (12/9/2006)
+%D \item Added \type{\setuppublicationlist[maybeyear=off]} by request from
+%D Thomas Schmitz (15/9/2006)
+%D \item Removed some spurious spaces pointed out by willi egger (19/9/2006)
+%D \item Add configuration of bibtex executable name (4/11/2006)
+%D \item Fix numbering=short and numbering=bib (spotted by Matthias W\"achter) (4/11/2006)
+%D \item third attempt to get a correct release (5/11/2006)
+%D \item fix a few missing dots in bibl-num.tex (7/12/2006)
+%D \item Patch for DOI's by Tobias Burnus (17/4/2007)
+%D \item Patch for \type{\insertbiburl} and \type{\insertdoi} for Tobias Burnus (18/4/2007)
+%D \item Added a missing \type{\relax} in \type{\dospecialbibinsert},
+%D that made the space before the {\it et al.} text disappear. (18/4/2007)
+%D \item Attempt to fix percent signs in bbl files. As a side-effect,
+%D this prohibits comments in \tex{startpublication} blocks! (17/4/2008)
+%D \item Patch from Matthias W\"achter that allows arbitrary .bst
+%D files to be used with \tex{setupbibtex} (25/9/2008)
+%D \item Extended for the new multilingual setups for the Oct 2008 current of ConTeXt (23/10/2008)
+%D \item Multilingual setups needed another fix (27/10/2008)
+%D \item Two fixes for bibl-apa by Michael Green (27/10/2008)
+%D \item Catalan translation of 'References' (10/11/2008)
+%D \item 'chapter' -> 'chapitre' in bibl-apa-fr (27/11/2008)
+%D \item Run bibtex via os.execute in mkiv modee (01/12/2008)
+%D \item Small correction in bibl-apa's placement of volume
+%D information in articles (05/01/2009)
+%D \item Handle multi-author (more than two) cases in \type{\cite}
+%D (02/03/2009)
+%D \item Suppress a syntax error in \type{cont-xp} mode. The output is
+%D probably not right, though (02/03/2009)
+%D \item Added a \tex{loadmarkfile} at the end, and two new files
+%D from Hans. The \type{t-bib.mkiv} is needed to make the module
+%D work with the new structure code (17/04/2009)
+%D \item Added a patch to \type{t-bib.mkiv} from Hans to make the
+%D cross referencing between multiple citations an
+%D bibliographies work (27/04/2009)
+%D \item Remove a superfluous \type{\unprotect} in t-bib.mkiv (11/05/2009).
+%D \item Patch of incollection in bibl-ams.tex from Xan (08/06/2009).
+%D \item Patch of unpublished in bibl-ams.tex from Xan (22/07/2009).
+%D \item Modified \type{\bibdogetupsometextprefix} so it works for undefined
+%D language labels, from Hans (13/08/2009).
+%D \item Adapt referencing and list insertion to \MKIV. Update some code
+%D to the latest \CONTEXT. Change some names in order to avoid conflicts
+%D with existing core names (like \type {\insertpages}).
+%D \item All constants, variables, message etc.\ are now in the core.
+%D \item Added key: \type {method} (when \type {global}, previous shown entries are
+%D not shown again, when \type {local} they are repeated).
+%D \stopitemize
+%D
+%D \subject{WISHLIST}
+%D
+%D \startitemize
+%D \item link back from publication list to citation
+%D \item export \type {\citation{<cited item>}}
+%D \item support mlbibtex
+%D \item don't load the whole lot, but filter entries instead
+%D \item 9 vs 10, 19 vs 20 ... prevent extra runs when only subtle changes in wd of reference
+%D \stopitemize
+
+\unprotect
+
+\def\biblistname{pubs} % for compatibility
+
+\definelist
+ [pubs]
+
+\setuplist
+ [pubs]
+ [\c!state=\v!start,
+ \c!criterium=\@@pbcriterium,
+ \c!headnumber=\v!always, % needed as we provide our own and need to force
+ \c!width=]
+
+\installstructurelistprocessor{pubs:userdata}%
+ {\ctxlua{bibtex.hacks.add(structures.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}}
+
+\ifdefined\bibtexblock \else \newcount\bibtexblock \fi \bibtexblock\plusone
+\ifdefined\bibtexcounter \else \newcount\bibtexcounter \fi
+
+%D \macros{bibdoif,bibdoifnot,bibdoifelse}
+%D
+%D Here are a few small helpers that are used a lot in all the typesetting commands
+%D (\type{\bibinsert...}) we will encounter later.
+
+\protected\def\bibdoifelse#1%
+ {\expandafter\def\expandafter\!!stringa\expandafter{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+\protected\def\bibdoifnot#1%
+ {\expandafter\def\expandafter\!!stringa\expandafter{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\protected\def\bibdoif#1%
+ {\expandafter\def\expandafter\!!stringa\expandafter{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+%D Unfortunately, \BIBTEX\ is not the best configurable program around. The names of
+%D the commands it parses as well as the \type {.aux} extension to the file name are
+%D both hardwired.
+%D
+%D This means \CONTEXT\ has to write a \LATEX-style auxiliary file, yuk! The good
+%D news is that it can be rather short. We'll just ask \BIBTEX\ to output the entire
+%D database(s) into the \type {bbl} file.
+%D
+%D The \type {\bibstyle} command controls how the \type {bbl} file will be sorted.
+%D The possibilities are:
+%D
+%D \startitemize[packed]
+%D \item by author (+year, title): cont-au.bst
+%D \item by title (+author, year): cont-ti.bst
+%D \item by short key as in abbrev.bst: cont-ab.bst
+%D \item not sorted at all: cont-no.bst
+%D \stopitemize
+
+\newtoks\everysetupbibtex
+
+\protected\def\setupbibtex
+ {\dosingleempty\dosetupbibtex}
+
+\protected\def\dosetupbibtex[#1]%
+ {\let\@@pbdatabase\empty
+ \getparameters[\??pb][#1]%
+ \the\everysetupbibtex}
+
+\protected\def\installbibtexsorter#1#2%
+ {\setvalue{\??pb:\c!sort:#1}{#2}}
+
+\installbibtexsorter\v!no {no}
+\installbibtexsorter\v!author {au}
+\installbibtexsorter\v!title {ti}
+\installbibtexsorter\v!short {ab}
+\installbibtexsorter\empty {no}
+\installbibtexsorter\s!default{no}
+
+\def\thebibtexsorter{\executeifdefined{\??pb:\c!sort:\@@pbsort}\@@pbsort}
+
+\appendtoks
+ \ifx\@@pbdatabase\empty\else
+ \doifmode{*\v!first}{\ctxlua{bibtex.hacks.process { style="\thebibtexsorter", database="\@@pbdatabase" }}}%
+ \fi
+\to \everysetupbibtex
+
+\setupbibtex
+ [\c!sorttype=\v!cite,
+ \c!sort=no]
+
+%D \macros{iftypesetall,ifbibcitecompress}
+%D
+%D The module needs some new \type{\if} statements.
+
+\newtoks\everysetuppublications
+
+\protected\def\setuppublications
+ {\dosingleargument\dosetuppublications}
+
+\protected\def\dosetuppublications[#1]%
+ {\getparameters[\??pb][\c!alternative=,#1]%
+ \doifsomething\@@pbalternative
+ {\readsysfile{bibl-\@@pbalternative.tex}
+ {\showmessage\m!publications{6}{bibl-\@@pbalternative}}
+ {\showmessage\m!publications{1}{bibl-\@@pbalternative}}%
+ \let\@@pbalternative\empty}%
+ \let\setuppublicationlayout\normalsetuppublicationlayout % overloaded in bibl-num ... vadjust needs to be done with option
+ \getparameters[\??pb][#1]% as bibl-* can have set things back
+ \the\everysetuppublications
+ \ignorespaces}
+
+%D We can omit already shown references (\v!global) or use fresh lists each time
+%D (\v!local).
+
+\setnewconstant\bibtexoncemode\plusone % 0=disable, 1=local, 2=global
+
+\appendtoks
+ \doifelse\@@pbmethod\v!local
+ {\bibtexoncemode\plusone}%
+ {\bibtexoncemode\plustwo}%
+\to \everysetuppublications
+
+%D Cite lists are compressed, if possible. This is set later on.
+
+\newif\ifbibcitecompress\bibcitecompresstrue
+
+\def\@@pbinumbercommand{\executeifdefined{\??pb:\c!numbercommand:\@@pbnumbering}\firstofoneargument}
+
+\setvalue{\??pb:\c!numbercommand:\v!yes }#1{#1}%
+\setvalue{\??pb:\c!numbercommand:\v!no }#1{}
+\setvalue{\??pb:\c!numbercommand:\v!short}#1{\bibgetvars\currentpublicationkey}
+\setvalue{\??pb:\c!numbercommand:\v!bib }#1{\bibgetvarn\currentpublicationkey}
+
+% to be tested
+%
+% \setvalue{\??pb:\c!numbercommand:\v!short}{\bibgetvars\currentpublicationkey\firstofoneargument}
+% \setvalue{\??pb:\c!numbercommand:\v!bib }{\bibgetvarn\currentpublicationkey\firstofoneargument}
+
+\appendtoks
+ \processaction
+ [\@@pbrefcommand]
+ [\s!default=>\edef\@@citedefault{\@@pbrefcommand},
+ \s!unknown=>\edef\@@citedefault{\@@pbrefcommand}]%
+\to \everysetuppublications
+
+\protected\def\bibleftnumber#1{#1\hfill~}
+
+%D \macros{usepublications}
+%D
+%D After discussing it with Thomas Schmitz it became clear that using external
+%D references makes no sense as one needs to refer to it in special ways and because
+%D similar numbers can be confusing. So, for the moment this is not supported in
+%D \MKIV. (So no: see reference [3-5,9] in "some other document")
+
+\protected\def\usepublications[#1]%
+ {\processcommalist[#1]\dousepublications}
+
+\protected\def\dousepublications#1%
+ {\doonlyonce{#1.\f!bibextension}{\dodousepublications{#1}}}
+
+\protected\def\dodousepublications#1% brr, this par stuff
+ {\let\@@savedpar\par
+ \let\par\ignorespaces
+ \ifhmode\kern\zeropoint\fi
+ \pushcatcodetable
+ \setcatcodetable\ctxcatcodes
+ \readfile{#1.\f!bibextension}
+ {\showmessage\m!publications{4}{#1.\f!bibextension}}
+ {\showmessage\m!publications{2}{#1.\f!bibextension}}%
+ \popcatcodetable
+ \ifhmode\removeunwantedspaces\fi
+ \let\par\@@savedpar}
+
+%D \macros{setuppublicationlist}
+%D
+%D This will be the first command in (\BIBTEX-generated) \type {bbl} files. \quote
+%D {samplesize} is a sample value (in case of \BIBTEX|-|generated files, this will
+%D be the longest \quote {short} key). Here \quote {totalnumber} is the total number
+%D of entries that will follow in this file.
+%D
+%D Both values are only needed for the label calculation if \quote {autohang} is
+%D \quote {true}, so by default the command is not even needed, and therefore I saw
+%D no need to give it it's own system variable and it just re-uses \type {pb}.
+
+\def\publicationlistparameter#1{\csname\??pv:l:#1\endcsname}
+
+\protected\def\setuppublicationlist
+ {\dosingleempty\dosetuppublicationlist}
+
+\protected\def\dosetuppublicationlist[#1]%
+ {\getparameters[\??pv:l:][#1]%
+ \setuplist[pubs][\c!samplesize={AA99},\c!alternative=a,\c!interaction=,\c!pagenumber=\v!no,#1,\c!command=]}
+
+\protected\def\setuppublicationlayout[#1]#2%
+ {\setvalue{\??pv:l:#1}{#2}}
+
+\let\normalsetuppublicationlayout\setuppublicationlayout
+
+\setuppublicationlist
+ [\c!title=,
+ \c!command=\dospecialbibinsert,
+ \c!maybeyear=\v!on]
+
+%D \macros{bibalternative}
+%D
+%D A nice little shorthand that will be used so we don't have to key in the weird
+%D \type {\@@pv} parameter names all the time.
+
+\def\bibalternative#1%
+ {\csname\??pv\@@currentalternative#1\endcsname}
+
+%D \macros{simplebibdef,bibcommandlist}
+%D
+%D \type {\simplebibdef} defines \type {bib@#1}, which in turn will use one argument
+%D that is stored in \type {@@pb@#1}.
+%D
+%D \type {\simplebibdef} also defines \type {bibinsert#1}, which can be used in the
+%D argument of \type {\setuppublicationlayout} to fetch one of the \type {@@pb@}
+%D data entries. \type {bibinsert#1} then has three arguments: \type {#1} are
+%D commands to be executed before the data, \type {#2} are commands to be executed
+%D after the data, and \type {#3} are commands to be executed if the data is not
+%D found.
+%D
+%D \type {\bibcommandlist} is the list of commands that is affected by this
+%D approach. Later on, it will be used to do a series of assignments from \type {#1}
+%D to \type {bib@#1}: e.g \type {\title} becomes \type {\bib@title} when used within
+%D a publication.
+
+\newtoks\initializebibdefinitions % we need to prevent clashes
+
+\protected\def\simplebibdef#1% hh: funny expansion ?
+ {\expandafter\def\csname bib@#1\endcsname##1%
+ {\setvalue{\??pb @#1}{##1}\ignorespaces}%
+ \expandafter \appendtoks
+ \expandafter\let\csname insert#1\expandafter\endcsname\csname bibinsert#1\endcsname
+ \to \initializebibdefinitions
+ \expandafter\protected\expandafter\def\csname bibinsert#1\endcsname##1##2##3%
+ {\expandafter\bibdoifelse\expandafter{\csname\??pb @#1\endcsname}{##1\csname\??pb @#1\endcsname##2}{##3}}}
+
+\def\bibcommandlist
+ {abstract, annotate, arttitle, assignee, bibnumber, bibtype, biburl, chapter, city,
+ comment, country, day, dayfiled, doi, edition, eprint, howpublished, isbn, issn,
+ issue, journal, keyword, keywords, lastchecked, month, monthfiled, names, nationality,
+ note, notes, organization, pages, pubname, pubyear, revision, series, size, thekey,
+ title, volume, yearfiled}
+
+\processcommacommand[\bibcommandlist]\simplebibdef
+
+\protected\def\bibinsertdoi#1#2#3% let's see how this fails
+ {\bibdoifelse{\@@pb@doi}{#1\expanded{\bibgotoDOI{\@@pb@thekey}{\@@pb@doi}}#2}{#3}}
+
+\protected\def\bibinsertbiburl#1#2#3% let's see how this fails
+ {\bibdoifelse{\@@pb@biburl}{#1\expanded{\bibgotoURL{\@@pb@thekey}{\@@pb@biburl}}#2}{#3}}
+
+\protected\def\bibinsertmonth#1#2#3%
+ {\bibdoifelse\@@pb@month
+ {#1\doifelsenumber\@@pb@month
+ {\doifelseconversiondefined\@@pbmonthconversion
+ {\convertnumber\@@pbmonthconversion\@@pb@month}{\@@pb@month}}%
+ {\@@pb@month}#2}%
+ {#3}}
+
+\appendtoks
+ \let\inserturl \bibinsertbiburl % for backward compat.
+ \let\inserttype\bibinsertbibtype % for backward compat.
+\to\initializebibdefinitions
+
+\protected\def\newbibfield[#1]%
+ {\simplebibdef{#1}%
+ \edef\bibcommandlist{\bibcommandlist,#1}}
+
+%D \macros{complexbibdef,specialbibinsert}
+%D
+%D The commands \type {\artauthor}, \type {\author} and \type {\editor} are more
+%D complex than the other commands. Their argument lists have this form:
+%D
+%D \type{\author[junior]{firstnames}[inits]{von}{surname}}
+%D
+%D (bracketed stuff is optional)
+%D
+%D And not only that, but there also might be more than one of each of these
+%D commands. This is why a special command is needed to insert them, as well as one
+%D extra counter for each command.
+
+% todo: instead of \getvalue {bla@num} in specs we should do \bibentrynum {bla} so
+% that we can create a better namespace
+
+%D All of these \type {\expandafter}'s and \type {\csnames} make this code look far
+%D more complex than it really is. For example, the argument \type {author} defines
+%D the macro \type {\bib@author} to do two things: increment the counter \type
+%D {\author@num} (let's say to 2) and next store it's arguments in the macro \type
+%D {\@@pb@author2}. And it defines \type {\bibinsertauthors} to expand into
+%D
+%D \starttyping
+%D \specialbibinsert{author}{\author@num}{<before>}{<after>}{<not>}
+%D \stoptyping
+
+\protected\def\docomplexbibdef#1%
+ {\dodoubleempty\dodocomplexbibdef[#1]}
+
+\protected\def\dodocomplexbibdef[#1][#2]#3%
+ {\doquadrupleempty\dododocomplexbibdef[#1][#2][#3]}
+
+\protected\def\dododocomplexbibdef[#1][#2][#3][#4]#5#6%
+ {\expandafter\increment\csname#1@num\endcsname % todo: bib in name
+ \setevalue{\??pb @#1\csname#1@num\endcsname}{{#3}{#5}{#6}{#4}{#2}}\ignorespaces}
+
+\protected\def\complexbibdef#1%
+ {\expandafter\newcounter\csname #1@num\endcsname
+ \expandafter\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}%
+ \expandafter \appendtoks
+ \expandafter\let\csname insert#1s\expandafter\endcsname\csname bibinsert#1s\endcsname
+ \to \initializebibdefinitions
+ \expandafter\def\csname bibinsert#1s\endcsname##1##2##3{\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}}
+
+\processcommalist[author,artauthor,editor]\complexbibdef
+
+%D Another level of indirection is needed to control the typesetting of all of these
+%D arguments.
+
+\newcount\etallimitcounter
+\newcount\etaldisplaycounter
+\newcount\todocounter
+
+\protected\def\specialbibinsert#1#2#3#4#5%
+ {\bgroup
+ \ifnum#2>\zerocount
+ \etallimitcounter =0\bibalternative{#1etallimit}\relax
+ \etaldisplaycounter=0\bibalternative{#1etaldisplay}\relax
+ \ifnum #2>\etallimitcounter
+ \todocounter\etaldisplaycounter
+ % just in case ...
+ \ifnum\todocounter>\etallimitcounter
+ \todocounter\etallimitcounter
+ \fi
+ \else
+ \todocounter#2\relax
+ \fi
+ \ifnum\todocounter>\zerocount
+ % find the current author list
+ \let\templist\empty
+ \dorecurse{#2}
+ {\scratchtoks\doubleexpandafter{\csname\??pb @#1\recurselevel\endcsname}%
+ \edef\templist{\ifx\templist\empty\else\templist,\fi\the\scratchtoks}}%
+ #3\publicationlistparameter\c!command{#1}{\todocounter}{\templist}#4\relax
+ \else
+ #5%
+ \fi
+ \else
+ #5%
+ \fi
+ \egroup}
+
+%D This macro does the hard work of inserting a list of people in the output, with
+%D proper regard of all the inbetween strings that can arise depending on length of
+%D the list of people.
+
+%D \#1 = type
+%D \#2 = number of items to be typeset
+%D \#3 = commacommand containing authors
+
+\protected\def\doprocessauthoritem#1#2#3%
+ {\advance\scratchcounter\plusone
+ \ifnum\numexpr\scratchcounter-\plusone\relax<#2\relax
+ \publicationlistparameter{#1}#3%
+ \ifnum\scratchcounter=#2\relax
+ \ifnum\etallimitcounter<\commalistsize\relax
+ \bibalternative{#1etaltext}%
+ \fi
+ \else\ifnum\numexpr\scratchcounter+\plusone\relax=#2\relax
+ \ifnum\commalistsize>\plustwo
+ \bibalternative\c!finalnamesep
+ \else
+ \bibalternative\c!lastnamesep
+ \fi
+ \else
+ \bibalternative\c!namesep
+ \fi\fi
+ \fi}
+
+\protected\def\dospecialbibinsert#1#2#3%
+ {\getcommacommandsize[#3]%
+ \scratchcounter\zerocount
+ \processcommacommand[#3]{\doprocessauthoritem{#1}{#2}}}
+
+%D \macros{invertedauthor,normalauthor,invertedshortauthor,normalshortauthor}
+%D
+%D Just some commands that can be used in \type {\setuppublicationparameters}
+%D If you want to write an extension to the styles, you might as well define
+%D some of these commands yourself.
+%D
+%D The argument list has been reordered here, and the meanings are:
+%D
+%D \startlines
+%D \type{#1} firstnames
+%D \type{#2} von
+%D \type{#3} surname
+%D \type{#4} inits
+%D \type{#5} junior
+%D \stoplines
+
+\protected\def\normalauthor#1#2#3#4#5%
+ {\bibdoif{#1}{#1\bibalternative\c!firstnamesep}%
+ \bibdoif{#2}{#2\bibalternative\c!vonsep}%
+ #3%
+ \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}}
+
+\protected\def\normalshortauthor#1#2#3#4#5%
+ {\bibdoif{#4}{#4\bibalternative\c!firstnamesep}%
+ \bibdoif{#2}{#2\bibalternative\c!vonsep}%
+ #3%
+ \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}}
+
+\protected\def\invertedauthor#1#2#3#4#5%
+ {\bibdoif{#2}{#2\bibalternative\c!vonsep}%
+ #3%
+ \bibdoif{#5}{\bibalternative\c!juniorsep#5}%
+ \bibdoif{#1}{\bibalternative\c!surnamesep#1\unskip}}
+
+\protected\def\invertedshortauthor#1#2#3#4#5%
+ {\bibdoif{#2}{#2\bibalternative\c!vonsep}%
+ #3%
+ \bibdoif{#5}{\bibalternative\c!juniorsep#5}%
+ \bibdoif{#4}{\bibalternative\c!surnamesep#4\unskip}}
+
+%D \macros{clearbibitem,clearbibitemtwo,bibitemdefs}
+%D
+%D These are used in \type {\typesetapublication} to do initializations and
+%D cleanups.
+
+\protected\def\clearbibitem#1{\setvalue{\??pb @#1}{}}%
+
+\protected\def\clearbibitemtwo#1% is this reset really needed? after all we reset the counter and we are local
+ {%\dofastrecurse\plusone{\csname#1@num\endcsname}\plusone{\expandafter\let\csname\??pb @#1\recurselevel\undefined}%
+ \letvalue{#1@num}\!!zerocount}
+
+\protected\def\bibitemdefs#1%
+ {\expandafter\let\csname#1\expandafter\endcsname\csname bib@#1\endcsname}
+
+\protected\def\presetbibvariables % make a fast resetter (toks)
+ {\processcommacommand[\bibcommandlist,crossref]\clearbibitem
+ \processcommalist [artauthor,author,editor]\clearbibitemtwo
+ \processcommacommand[\bibcommandlist]\bibitemdefs
+ \processcommalist [artauthor,author,editor,crossref]\bibitemdefs}
+
+%D \macros{startpublication}
+%D
+%D We are coming to the end of this module, to the macros that do typesetting and
+%D read the \type {bbl} file.
+%D
+%D Just a \type {\dosingleempty} is the most friendly of doing this: there need not
+%D even be an argument to \type {\startpublication}. Of course, then there is no key
+%D either, and it had better be an article (otherwise the layout will be all screwed
+%D up).
+%D
+%D Only specifying the key in the argument is also legal. In storing this stuff into
+%D macros, some trickery with token registers is needed to fix the expansion
+%D problems. Even so, this appears to not always be 100\% safe, so people are
+%D urgently advised to use \ETEX\ instead of traditional \TEX.
+%D
+%D In \ETEX, all expansion problems are conveniently solved by the primitive \type
+%D {\protected}. To put that another way:
+%D
+%D It's not a bug in this module if it does not appear in \ETEX!
+%D
+%D Now prohibits comments, so % can be used for urls
+
+\pushoverloadmode
+
+\overloaded \protected\def\startpublication
+ {\dosingleempty\dostartpublication}
+
+\overloaded\let\stoppublication\relax
+
+\popoverloadmode
+
+%D This is rather memory hungry; some day i will rewrite this so that we use the
+%D database instead.
+
+%D \macros{doifbibreferencefoundelse}
+%D
+%D Some macros to fetch the information provided by \type {\startpublication}.
+%D
+%D We can consider a faster variant in the bbl file; we can also consider storing
+%D the keys in lua (and then do more in lua) and use calls to fetch the variables.
+
+% hm, we can store at the lua end ...
+
+\protected\def\dostartpublication[#1]%
+ {\begingroup
+ \doifelseassignment{#1}%
+ {\getparameters[\??pb][k=\s!unknown,t=article,n=,s=,a=,y=,o=,u=,#1]}%
+ {\getparameters[\??pb][k=#1,t=article,n=,s=,a=,y=,o=,u=]}%
+ \ctxlua{bibtex.hacks.register(\!!bs\@@pbk\!!es,\!!bs\@@pbs\!!es)}%
+ \catcode\commentasciicode\othercatcode
+ \dodostartpublication}
+
+\protected\def\dodostartpublication#1\stoppublication
+ {\setxvalue{pbd:\@@pbk}##1{\noexpand\ifcase##1\noexpand\or
+ \@@pbk\noexpand\or
+ \@@pba\noexpand\or
+ \@@pby\noexpand\or
+ \@@pbs\noexpand\or
+ \@@pbn\noexpand\or
+ \@@pbt\noexpand\or
+ \@@pbo\noexpand\or
+ \@@pbu\noexpand\or
+ \normalunexpanded{#1}\noexpand\fi}%
+ \endgroup
+ \ignorespaces}
+
+\def\bibgetvark#1{\csname pbd:#1\endcsname\plusone }
+\def\bibgetvara#1{\csname pbd:#1\endcsname\plustwo }
+\def\bibgetvary#1{\csname pbd:#1\endcsname\plusthree}
+\def\bibgetvars#1{\csname pbd:#1\endcsname\plusfour }
+\def\bibgetvarn#1{\csname pbd:#1\endcsname\plusfive }
+\def\bibgetvart#1{\csname pbd:#1\endcsname\plussix }
+\def\bibgetvaro#1{\csname pbd:#1\endcsname\plusseven}
+\def\bibgetvaru#1{\csname pbd:#1\endcsname\pluseight}
+\def\bibgetvard#1{\csname pbd:#1\endcsname\plusnine }
+
+\protected\def\doifelsebibreferencefound#1%
+ {\preloadbiblist
+ \doifelsedefined{pbd:#1}
+ \firstoftwoarguments
+ {\showmessage\m!publications{5}{#1,\the\inputlineno}\secondoftwoarguments}}
+
+\let\doifbibreferencefoundelse\doifelsebibreferencefound
+
+%D \macros{bib@crossref}
+%D
+%D \type {\crossref} is used in database files to point to another entry. Because of
+%D this special situation, it has to be defined separately. Since this command will
+%D not be seen until at \type {\placepublications}, it may force extra runs. The
+%D same is true for \type {\cite} commands inside of publications.
+
+% used in bib self
+
+\protected\def\bib@crossref#1% called via \csname \endcsname
+ {\setvalue{\??pb @crossref}{#1}\ignorespaces}
+
+\protected\def\bibinsertcrossref#1#2#3%
+ {\bibdoifelse\@@pb@crossref{#1\cite[\@@pb@crossref]#2}{#3}}
+
+\let\insertcrossref\gobblethreearguments
+
+\appendtoks\let\insertcrossref\bibinsertcrossref\to\initializebibdefinitions
+
+%D The next macro is needed because the number command of the publist sometimes
+%D needs to fetch something from the current item (like the 'short' key). For this,
+%D the ID of the current item is passed in the implict parameter \type
+%D {\currentpublicationkey}.
+
+\protected\def\doprocessbibtexentry#1{\typesetapublication{#1}}
+
+\protected\def\typesetpubslist
+ {\begingroup
+ \startpacked[\v!blank]%
+ \preloadbiblist
+ % \the\initializebibdefinitions % COMMENTED
+ \edef\currentlist{pubs}%
+ \ctxlua{bibtex.hacks.reset(\number\bibtexoncemode)}%
+ \doifelse{\listparameter\c!criterium}\v!all
+ {\showmessage\m!publications{7}{}%
+ \ctxlua{bibtex.hacks.filterall()}}
+ {\doif{\listparameter\c!criterium}\v!cite
+ {\setuplist[pubs][\c!criterium=\v!here]}%
+ \strc_lists_place_current
+ {pubs}%
+ {\listparameter\c!criterium}%
+ {}%
+ {\listparameter\c!extras}%
+ {\listparameter\c!order}}%
+ \ctxlua{bibtex.hacks.flush("\@@pbsorttype")}%
+ \stoppacked
+ \endgroup}
+
+\newif\ifinpublist
+
+\protected\def\initializepubslist
+ {\def\currentlist{pubs}%
+ \edef\@@pbnumbering{\@@pbnumbering}%
+ \doifelse\@@pbautohang\v!yes
+ {\ifx\@@pbnumbering\v!short
+ \setbox\scratchbox\hbox{\@@pbnumbercommand{\listparameter\c!samplesize}}%
+ \else
+ \doifelse{\listparameter\c!criterium}\v!all
+ {\setbox\scratchbox\hbox{\@@pbnumbercommand{\ctxlua{tex.write{bibtex.hacks.nofregistered()}}}}}
+ {\determinelistcharacteristics[pubs]%
+ \setbox\scratchbox\hbox{\@@pbnumbercommand{\structurelistsize}}}%
+ \fi
+ \edef\publistnumberbox{\hbox to \the\wd\scratchbox}%
+ \expanded{\setuplist[pubs][\c!width=\the\wd\scratchbox,\c!distance=\zeropoint]}%
+ \ifx\@@pbnumbering\v!short
+ \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvars\currentpublicationkey}}}%
+ \else\ifx\@@pbnumbering\v!bib
+ \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvarn\currentpublicationkey}}}%
+ \else
+ \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{##1}}}%
+ \fi\fi}
+ {\doifelsenothing{\listparameter\c!width}
+ {\let \publistnumberbox \hbox}
+ {\edef\publistnumberbox{\hbox to \listparameter\c!width}}%
+ \ifx\@@pbnumbering\v!short
+ \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvars\currentpublicationkey}}}%
+ \else\ifx\@@pbnumbering\v!bib
+ \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvarn\currentpublicationkey}}}%
+ \else
+ \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{##1}}}%
+ \fi\fi}%
+ \ifx\@@pbnumbering\v!no
+ \setuplist[pubs][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]%
+ \else
+ \setuplist[pubs][\c!numbercommand=\@@pblimitednumber]%
+ \fi
+ \doifelse{\publicationlistparameter\c!maybeyear}{\v!off}{\def\maybeyear##1{}}{\def\maybeyear##1{##1}}%
+ \forgetall}
+
+%D The full list of publications
+
+\protected\def\completepublications
+ {\dosingleempty\docompletepublications}
+
+\protected\def\docompletepublications[#1]%
+ {\begingroup
+ \setuplist[pubs][#1]%
+ \edef\currentbibtexsessiontitle{\publicationlistparameter\c!title}%
+ \ifx\currentbibtexsessiontitle\empty
+ \normalexpanded{\startnamedsection[\v!chapter][\c!reference=pubs,\c!title={\headtext{pubs}}]}%
+ \else
+ \normalexpanded{\startnamedsection[\v!chapter][\c!reference=pubs,\c!title={\currentbibtexsessiontitle}]}%
+ \fi
+ \dodoplacepublications
+ \stopnamedsection
+ \endgroup}
+
+%D And the portion with the entries only.
+
+\def\bibrefprefix{\number\bibtexblock:}
+
+\protected\def\placepublications
+ {\dosingleempty\doplacepublications}
+
+\protected\def\doplacepublications[#1]%
+ {\begingroup
+ \setuplist[pubs][#1]%
+ \dodoplacepublications
+ \endgroup}
+
+\protected\def\dodoplacepublications
+ {\determinelistcharacteristics[pubs]%
+ \initializepubslist
+ \doifnot{\namedlistparameter{pubs}\c!option}\v!continue
+ {\global\bibtexcounter\zerocount}%
+ \inpublisttrue
+ \typesetpubslist
+ \inpublistfalse
+ \global\advance\bibtexblock\plusone}
+
+%D \subsubject{What's in a publication}
+%D
+%D Watch out: here all means all publications in database, so use text when you want
+%D text only.
+
+\protected\def\typesetapublication#1%
+ {\doifsomething{#1}
+ {\doifelse{\namedlistparameter{pubs}\c!criterium}\v!all
+ {\doplacepublicationindeed{#1}}%
+ {\ctxlua{bibtex.hacks.doifalreadyplaced("#1")}
+ {}
+ {\doplacepublicationindeed{#1}}}%
+ }}
+
+%D For the moment we don't access the data directly but we will do that later when
+%D we get away from storing the data and only deal with references.
+
+% we'll define proper handlers later
+
+\protected\def\doplacepublicationindeed#1%
+ {\doifelsebibreferencefound{#1}
+ {\global\advance\bibtexcounter\plusone
+ \def\currentpublicationkey{#1}%
+ \ctxlua{bibtex.hacks.registerplaced("#1")}%
+ \def \currentlist {pubs}%
+ \edef\currentlistentrynumber {\number\bibtexcounter}%
+ \let \currentlistentrytitle \bibtexpubtext
+ \let \currentlistentrypagenumber\empty
+ \strc_lists_apply_renderingsetup}
+ {}} % invalid
+
+\protected\def\bibtexpubtext
+ {\expanded{\reference[\bibrefprefix\currentpublicationkey]{\number\bibtexcounter}}%
+ \strut\dotypesetapublication\currentpublicationkey\strut}
+
+\protected\def\dotypesetapublication#1%
+ {\bgroup
+ \the\initializebibdefinitions % NEW
+ \def\@@currentalternative{:l:}%
+ \presetbibvariables
+ \let\biblanguage\empty
+ \ignorespaces
+ \bibgetvard{#1}%
+ \removeunwantedspaces
+ \ignorespaces
+ \bibalternative{\bibgetvart{#1}}%
+ \removeunwantedspaces
+ \egroup}
+
+%D An few afterthoughts:
+
+\let\maybeyear\gobbleoneargument
+\let\noopsort \gobbleoneargument
+
+%D This is the result of bibtex's `language' field.
+
+\protected\def\setbiblanguage#1#2{\setvalue{\??pb\s!language#1}{#2}}
+
+\protected\def\lang#1%
+ {\edef\biblanguage{#1}%
+ \ifcsname\??pb\s!language#1\endcsname
+ \language[\getvalue{\??pb\s!language#1}]%
+ \fi
+ \ignorespaces}
+
+%D \subject{Citations}
+
+%D \macros{cite,bibref}
+%D
+%D The indirection with \type {\dobibref} allows \LATEX\ style \type {\cite}
+%D commands with a braced argument (these might appear in included data from the
+%D \type {.bib} file).
+
+\pushoverloadmode
+
+\protected\def\cite
+ {\strictdoifelsenextoptional\dodocite\dobibref}
+
+\popoverloadmode
+
+\protected\def\dobibref#1%
+ {\docite[#1][]}
+
+\protected\def\dodocite[#1]%
+ {\strictdoifelsenextoptional{\docite[#1]}{\docite[#1][]}}
+
+\protected\def\docite[#1][#2]%
+ {\begingroup
+ \doifelsenothing{#2}\secondargumentfalse\secondargumenttrue
+ \ifsecondargument
+ \dowhatevercite{#1}{#2}%
+ \else
+ \donumberedcite{#1}%
+ \fi
+ \endgroup}
+
+\protected\def\dowhatevercite#1#2%
+ {\processcommalist[#2]\docitation
+ \setupinteraction[\c!style=]%
+ \doifelseassignment
+ {#1}%
+ {\getparameters[LO][\c!alternative=,\c!extras=,#1]%
+ \edef\@@currentalternative{\LOalternative}%
+ \ifx\@@currentalternative\empty
+ \edef\@@currentalternative{\@@citedefault}%
+ \fi
+ \ifx\LOextras\empty
+ \setupcite[\@@currentalternative][#1]%
+ \else
+ \expandafter\ifx\csname \??pv \@@currentalternative\c!right\endcsname\relax
+ % avoids tail recursion
+ \expandafter\let\csname \??pv \@@currentalternative\c!right\endcsname\empty
+ \fi
+ \expandafter\ifx\csname LOright\endcsname \relax
+ \edef\LOextras{{\LOextras\bibalternative\c!right}}%
+ \else
+ \edef\LOextras{{\LOextras\LOright}}%
+ \fi
+ \expanded{\setupcite[\@@currentalternative][#1,\c!right=\LOextras]}%
+ \fi}%
+ {\def\@@currentalternative{#1}}%
+ \doifelsevalue{@@pv\@@currentalternative\c!compress}\v!no\bibcitecompressfalse\bibcitecompresstrue
+ \getvalue{bib\@@currentalternative ref}[#2]}
+
+\protected\def\donumberedcite#1%
+ {\processcommalist[#1]\docitation
+ \setupinteraction[\c!style=]%
+ \edef\@@currentalternative{\@@citedefault}%
+ \doifelsevalue{@@pv\@@currentalternative\c!compress}\v!no\bibcitecompressfalse\bibcitecompresstrue
+ \getvalue{bib\@@citedefault ref}[#1]}
+
+%D \macros{nocite}
+
+\pushoverloadmode
+
+\protected\def\nocite[#1]%
+ {\processcommalist[#1]\docitation}
+
+\popoverloadmode
+
+%D \macros{setupcite}
+
+\protected\def\setupcite{\dodoubleempty\dosetupcite}
+
+\protected\def\dosetupcite[#1][#2]%
+ {\ifsecondargument
+ \def\dodosetupcite##1{\getparameters[\??pv##1][#2]}%
+ \processcommalist[#1]\dodosetupcite
+ \else % default case
+ \getparameters[\??pv\@@citedefault][#1]%
+ \fi}
+
+%D Low-level stuff
+
+\protected\def\getcitedata#1[#2]#3[#4]#5to#6%
+ {\bgroup
+ \dofetchapublication{#4}%
+ \doifelsedefined{\??pb @bib#2}%
+ {\xdef#6{\getvalue{\??pb @bib#2}}}%
+ {\xdef#6{\getvalue{\??pb @#2}}}%
+ \egroup}
+
+\protected\def\dofetchapublication#1%
+ {\def\currentpublicationkey{#1}%
+ \presetbibvariables
+ \ignorespaces\bibgetvard{#1}}
+
+\protected\def\docitation#1%
+ {\iftrialtypesetting \else
+ \expanded{\writedatatolist[pubs][bibref=#1]}%
+ \fi}
+
+\let\addthisref\gobbleoneargument % keep this for compatibility
+
+%D \macros{ixbibauthoryear,thebibauthors,thebibyears}
+%D
+%D If compression of \type {\cite}'s argument expansion is on, the macros that deal
+%D with authors and years call this internal command to do the actual typesetting.
+%D
+%D Two entries with same author but with different years may be condensed into
+%D ``Author (year1,year2)''. This is about the only optimization that makes sense
+%D for the (author,year) style of citations (years within one author have to be
+%D unique anyway so no need to test for that, and ``Author1, Author2 (year)''
+%D creates more confusion than it does good).
+%D
+%D In the code below, the macro \type {\thebibauthors} holds the names of the
+%D alternative author info fields for the current list. This is a commalist, and
+%D \type {\thebibyears} holds the (collection of) year(s) that go with this author
+%D (possibly as a nested commalist).
+%D
+%D There had better be an author for all cases, but there does not have to be year
+%D info always. \type{\thebibyears} is pre|-|initialized because this makes the
+%D insertion macros simpler.
+%D
+%D In normal \TEX, of course there are expansion problems again.
+
+%D Delegate this to \LUA.
+
+% \let\ixlastcommand \relax
+% \let\ixsecondcomman \relax
+% \let\ixfirstcommand \relax
+% \let\thebibauthors \empty
+% \let\thebibyears \empty
+% \let\authorcount \!!zerocount
+
+\let\currentbibauthor\empty
+
+\protected\def\ixbibauthoryear#1#2#3#4%
+ {\bgroup
+ \gdef\ixlastcommand {#4}%
+ \gdef\ixsecondcommand{#3}%
+ \gdef\ixfirstcommand {#2}%
+ \glet\thebibauthors \empty
+ \glet\thebibyears \empty
+ \getcommalistsize[#1]%
+ \ifbibcitecompress
+ \dorecurse\commalistsize{\xdef\thebibyears{\thebibyears,}}%
+ \processcommalist[#1]\docompressbibauthoryear
+ \else
+ \processcommalist[#1]\donormalbibauthoryear
+ \fi
+ \egroup
+ \dobibauthoryear}
+
+%D \macros{dodobibauthoryear}
+%D
+%D This macro only has to make sure that the lists \type {\thebibauthors} and \type
+%D {\thebibyears} are printed.
+
+\protected\def\dobibauthoryear
+ {\scratchcounter\zerocount
+ \getcommacommandsize[\thebibauthors]%
+ \edef\authorcount{\commalistsize}%
+ \expandafter\processcommalist\expandafter[\thebibauthors]\dodobibauthoryear}
+
+\protected\def\dodobibauthoryear#1%
+ {\advance\scratchcounter\plusone
+ \edef\wantednumber{\the\scratchcounter}%
+ \getfromcommacommand[\thebibyears][\wantednumber]%
+ \expandafter\def\expandafter\currentbibyear\expandafter{\commalistelement}%
+ \setcurrentbibauthor{#1}%
+ \ifnum\scratchcounter=\plusone
+ \ixfirstcommand
+ \else\ifnum \scratchcounter=\authorcount\relax
+ \ixlastcommand
+ \else
+ \ixsecondcommand
+ \fi\fi}
+
+\protected\def\setcurrentbibauthor#1% sensitive for empty entries but I don't want to touch this
+ {\getcommacommandsize[#1]%
+ \ifcase\commalistsize
+ % anonymous?
+ \let\currentbibauthor\empty
+ \or
+ \def\currentbibauthor{#1}%
+ \or
+ \expanded{\docurrentbibauthor#1}%
+ \else
+ \handlemultiplebibauthors{\commalistsize}{#1}%
+ \fi}
+
+\newcount\citescratchcounter
+
+\protected\def\handlemultiplebibauthors#1#2%
+ {\citescratchcounter\zerocount
+ \let\currentbibauthor\empty
+ \protected\def\bibprocessauthoritem##1%
+ {\advance\citescratchcounter\plusone
+ \ifnum \citescratchcounter=#1\relax
+ \edef\currentbibauthor{\currentbibauthor##1}%
+ \else\ifnum\numexpr\citescratchcounter+\plusone\relax=#1\relax
+ \edef\currentbibauthor{\currentbibauthor##1\bibalternative{andtext}}%
+ \else
+ \edef\currentbibauthor{\currentbibauthor##1\bibalternative{namesep}}%
+ \fi\fi}%
+ \processcommalist[#2]\bibprocessauthoritem}
+
+\setupcite
+ [author,authoryear,authoryears]
+ [\c!namesep={, }]
+
+%D This discovery of authoretallimit is not the best one,
+%D but it will do for now.
+
+\protected\def\docurrentbibauthor#1,#2%
+ {\doifelseempty{#2}
+ {\def\currentbibauthor{#1\bibalternative{otherstext}}}
+ {\expandafter\ifx\csname\??pv\@@currentalternative authoretallimit\endcsname\relax
+ \edef\currentbibauthor{#1\bibalternative{andtext}#2}%
+ \else
+ \edef\currentbibauthor{#1%
+ \ifcase0\bibalternative{authoretallimit}\relax\or
+ \bibalternative{otherstext}\else\bibalternative{andtext}#2\fi}%
+ \fi}}
+
+%D This is not the one Hans made for me, because I need a global
+%D edef, and the \type {\robustdoifinsetelse} doesn't listen to
+%D \type {\doglobal}.
+
+\pushoverloadmode
+
+ \protected\def\robustaddtocommalist#1#2% {item} \cs
+ {\robustdoifelseinset{#1}#2\resetglobal
+ {\dodoglobal\xdef#2{\ifx#2\empty\else#2,\fi#1}}}
+
+\popoverloadmode
+
+%D \macros{donormalbibauthoryear}
+%D
+%D Now we get to the macros that fill the two lists. The \quote {simple} one really
+%D is quite simple.
+
+\protected\def\donormalbibauthoryear#1%
+ {\def\myauthor{Xxxxxxxxxx}%
+ \def\myyear{0000}%
+ \doifelsebibreferencefound{#1}
+ {\def\myauthor{{\bibgetvara{#1}}}%
+ \def\myyear {\bibgetvary{#1}}}%
+ {}%
+ \expandafter\doglobal\expandafter\appendtocommalist\expandafter{\myauthor}\thebibauthors
+ \expandafter\doglobal\expandafter\appendtocommalist\expandafter{\myyear }\thebibyears}
+
+%D \macros{docompressbibauthoryear}
+%D
+%D So much for the easy parts. Nothing at all will be done if the reference is not
+%D found or the reference does not contain author data. No questions marks o.s.s.
+%D (to be fixed later).
+
+\protected\def\docompressbibauthoryear#1%
+ {\def\myauthor{Xxxxxxxxxx}%
+ \def\myyear {0000}%
+ \doifelsebibreferencefound{#1}
+ {\xdef\myauthor{\bibgetvara{#1}}%
+ \xdef\myyear {\bibgetvary{#1}}}
+ {}%
+ \ifx\myauthor\empty\else
+ \checkifmyauthoralreadyexists
+ \findmatchingyear
+ \fi}
+
+%D Two temporary counters. One of these two can possibly be replaced by \type
+%D {\scratchcounter}.
+
+\newcount\bibitemcounter
+\newcount\bibitemwanted
+
+%D The first portion is simple enough: if this is the very first author it is quite
+%D straightforward to add it. \type {\bibitemcounter} and \type {\bibitemwanted} are
+%D needed later to insert the year information in the correct item of \type
+%D {\thebibyears}.
+
+\protected\def\checkifmyauthoralreadyexists
+ {\doifelseemptyvalue{thebibauthors}
+ {\global\bibitemwanted \plusone
+ \global\bibitemcounter\plusone
+ \xdef\thebibauthors{{\myauthor}}}
+ {% the next weirdness is because according to \getcommalistsize,
+ % the length of \type{[{{},{}}]} is 2.
+ \expandafter\getcommalistsize\expandafter[\thebibauthors,]%
+ \global\bibitemcounter\numexpr\commalistsize+\minusone\relax
+ \global\bibitemwanted \zerocount
+ \processcommacommand[\thebibauthors]\docomparemyauthor}}
+
+%D The outer \type {\ifnum} accomplishes the addition of a new author to \type
+%D {\thebibauthors}. The messing about with the two counters is again to make sure
+%D that \type {\thebibyears} will be updated correctly.If the author {\it was}
+%D found, the counters will stay at their present values and everything will be
+%D setup properly to insert the year info.
+
+\protected\def\docomparemyauthor#1%
+ {\global\advance\bibitemwanted \plusone
+ \def\mytempc{#1}%
+ \ifx\mytempc\myauthor
+ \quitcommalist
+ \else\ifnum\bibitemwanted=\bibitemcounter\relax
+ \global\advance\bibitemwanted \plusone
+ \global\bibitemcounter\bibitemwanted\relax
+ \expandafter\doglobal\expandafter\robustaddtocommalist\expandafter{{\myauthor}}\thebibauthors
+ \fi\fi}
+
+%D This macro should be clear now.
+
+\protected\def\findmatchingyear
+ {\edef\wantednumber{\the\bibitemwanted}%
+ \getfromcommacommand[\thebibyears][\wantednumber]%
+ \ifx\commalistelement\empty
+ \edef\myyear{{\myyear}}%
+ \else
+ \edef\myyear{{\commalistelement,\myyear}}%
+ \fi
+ \edef\newcommalistelement{\myyear}%
+ \doglobal\replaceincommalist \thebibyears \wantednumber}
+
+%D \macros{gotobiblink,inbiblink,atbiblink}
+%D
+%D The final task is looping over that list until a match is found.
+
+%D Beware, we can have cites without reference match.
+
+\protected\def\gotobiblink#1[#2]{\doifelsereferencefound{\bibrefprefix#2}{\goto{#1}[\bibrefprefix#2]}{#1}}
+\protected\def\atbiblink [#1]{\doifelsereferencefound{\bibrefprefix#1}{\at [\bibrefprefix#1]}{#1}}
+\protected\def\inbiblink [#1]{\doifelsereferencefound{\bibrefprefix#1}{\expanded{\goto{\currentreferencetext}}[\bibrefprefix#1]}{#1}}
+
+%D \macros{bibauthoryearref,bibauthoryearsref,bibauthorref,bibyearref}
+%D
+%D Now that all the hard work has been done, these are simple. \type
+%D {\ixbibauthoryearref} stores the data in the macros \type {\currentbibauthor} and
+%D \type {\currentbibyear}.
+
+\protected\def\doifelsebibinteraction
+ {\iflocation
+ \edef\test{\bibalternative\c!interaction}%
+ \ifx\test\v!stop
+ \doubleexpandafter\secondoftwoarguments
+ \else
+ \doubleexpandafter\firstoftwoarguments
+ \fi
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\let\doifbibinteractionelse\doifelsebibinteraction
+
+\protected\def\bibmaybeinteractive#1#2%
+ {\doifelsebibinteraction{\gotobiblink{#2}[#1]}{#2}}
+
+\protected\def\bibauthoryearref[#1]%
+ {\ixbibauthoryear{#1}%
+ {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
+ \bibalternative\v!left{\currentbibyear}\bibalternative\v!right}}
+ {\bibalternative\c!pubsep
+ \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
+ \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}}
+ {\bibalternative\c!lastpubsep
+ \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
+ \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}}}
+
+\protected\def\bibauthoryearsref[#1]%
+ {\bibalternative\v!left
+ \ixbibauthoryear{#1}
+ {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}
+ {\bibalternative\c!pubsep
+ \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}
+ {\bibalternative\c!lastpubsep
+ \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}%
+ \bibalternative\v!right}
+
+\protected\def\bibauthorref[#1]%
+ {\bibalternative\v!left
+ \ixbibauthoryear{#1}%
+ {\bibmaybeinteractive{#1}{{\currentbibauthor}}}
+ {\bibalternative\c!pubsep \bibmaybeinteractive{#1}{{\currentbibauthor}}}
+ {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibauthor}}}%
+ \bibalternative\v!right}
+
+\protected\def\bibyearref[#1]%
+ {\bibalternative\v!left
+ \ixbibauthoryear{#1}%
+ {\bibmaybeinteractive{#1}{{\currentbibyear}}}
+ {\bibalternative\c!pubsep \bibmaybeinteractive{#1}{{\currentbibyear}}}
+ {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibyear}}}%
+ \bibalternative\v!right}
+
+%D \macros{bibshortref,bibkeyref,bibpageref,bibtyperef,bibserialref}
+%D
+%D There is hardly any point in trying to compress these. The only thing that needs
+%D to be done is making sure that the separations are inserted correctly. And that
+%D is what \type {\bibinsertrefsep} does.
+
+\newconditional\firstbibrefsep
+
+\protected\def\bibresetrefsep
+ {\settrue\firstbibrefsep}
+
+\protected\def\bibinsertrefsep
+ {\ifconditional\firstbibrefsep
+ \setfalse\firstbibrefsep
+ \else
+ \bibalternative\c!pubsep
+ \fi}
+
+\protected\def\bibshortref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibshortref
+ \bibalternative\v!right}
+
+\protected\def\dobibshortref#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\gotobiblink{\bibgetvars{#1}}[#1]}
+ {}}
+
+\protected\def\bibserialref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibserialref
+ \bibalternative\v!right}
+
+\protected\def\dobibserialref#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\gotobiblink{\bibgetvarn{#1}}[#1]}
+ {}}
+
+\protected\def\bibkeyref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibkeyref
+ \bibalternative\v!right}
+
+\protected\def\dobibkeyref#1%
+ {\bibinsertrefsep
+ \gotobiblink{#1}[#1]}
+
+\protected\def\bibgotoDOI#1#2%
+ {\doifelsebibinteraction
+ {\useURL[bibfooDoi#1][#2]%
+ \useURL[bibfoo#1][http://dx.doi.org/#2]%
+ \goto{\url[bibfooDoi#1]}[url(bibfoo#1)]}
+ {\hyphenatedurl{#2}}}
+
+\protected\def\bibdoiref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibdoiref
+ \bibalternative\v!right}
+
+\protected\def\dobibdoiref#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\expanded{\bibgotoDOI{#1}{\bibgetvaro{#1}}}}
+ {}}
+
+\protected\def\biburlref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobiburlref
+ \bibalternative\v!right}
+
+\protected\def\bibgotoURL#1#2%
+ {\doifelsebibinteraction
+ {\useURL[bibfoo#1][#2]\goto{\url[bibfoo#1]}[url(bibfoo#1)]}
+ {\hyphenatedurl{#2}}}
+
+\protected\def\dobiburlref#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\expanded{\bibgotoURL{#1}{\bibgetvaru{#1}}}}
+ {}}
+
+\protected\def\bibtyperef[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibtyperef
+ \bibalternative\v!right}
+
+\protected\def\dobibtyperef#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\gotobiblink{\bibgetvart{#1}}[#1]}
+ {}}
+
+\protected\def\bibpageref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibpageref
+ \bibalternative\v!right}
+
+\protected\def\dobibpageref#1%
+ {\bibinsertrefsep
+ \doifelsebibinteraction
+ {\atbiblink[#1]}
+ {{\referencingfalse\at[#1]}}}
+
+\protected\def\bibdataref[#1]%
+ {\bibalternative\v!left
+ \bibresetrefsep\processcommalist[#1]\dobibdata
+ \bibalternative\v!right}
+
+\protected\def\dobibdata#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\dotypesetapublication{#1}}
+ {}}
+
+\let\bibnoneref\nocite
+
+%D \macros{bibnumref}
+
+\protected\def\bibnumref[#1]%
+ {\begingroup
+ \bibalternative\v!left
+ \penalty\plustenthousand
+ \ctxlua{bibtex.hacks.resolve("","\number\bibtexblock","#1")}%
+ \bibalternative\v!right
+ \endgroup}
+
+\protected\def\dowithbibtexnumrefconnector#1#2%
+ {\ifnum#1>\plusone
+ \ifnum#2>\plusone
+ \ifnum#2=#1\relax
+ \bibalternative{lastpubsep}%
+ \else
+ \bibalternative{pubsep}%
+ \fi
+ \fi
+ \fi}
+
+\protected\def\dowithbibtexnumref#1#2#3#4#5% n, i, prefix block ref
+ {\dowithbibtexnumrefconnector{#1}{#2}%
+ \def\bibrefprefix{#4:}%
+ \inbiblink[#5]}
+
+\protected\def\dowithbibtexnumrefrange#1#2#3#4#5#6#7% n, i, prefix block ref
+ {\dowithbibtexnumrefconnector{#1}{#2}%
+ \def\bibrefprefix{#4:}%
+ \inbiblink[#5]%
+ \endash
+ \def\bibrefprefix{#6:}%
+ \inbiblink[#7]}
+
+%D By request from Sanjoy. This makes it easier to implement \type {\citeasnoun}.
+
+\protected\def\bibauthornumref[#1]%
+ {\getcommalistsize[#1]%
+ \global\bibitemcounter\commalistsize
+ \bibresetrefsep
+ \processcommalist[#1]\dobibauthornumref}
+
+\protected\def\dobibauthornumref#1%
+ {\bibinsertrefsep
+ \doifelsebibreferencefound{#1}
+ {\begingroup
+ \cite[\c!left=,\c!right=,\c!alternative=\v!author][#1]%
+ \bibalternative\c!inbetween
+ \cite[num][#1]%
+ \endgroup}
+ {}}
+
+%D And some defaults are loaded from bibl-apa:
+
+\setuppublications
+ [\c!monthconversion=,
+ \c!alternative=apa,
+ \c!method=\v!global,
+ %\c!criterium=\v!previous,
+ \c!criterium=\v!cite, % mojca wants this so bother her, not me
+ \c!refcommand=num,
+ \c!numbercommand=\bibleftnumber]
+
+\protected\def\preloadbiblist
+ {\glet\preloadbiblist\relax
+ \dousepublications\jobname}
+
+% \appendtoks \preloadbiblist \to \everysetuppublications
+% \appendtoks \preloadbiblist \to \everystarttext
+
+\let\ifbibinteractionelse\doifbibinteractionelse
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/buff-ver.mkxl b/tex/context/base/mkiv/buff-ver.mkxl
index 565046db7..ab6cdd764 100644
--- a/tex/context/base/mkiv/buff-ver.mkxl
+++ b/tex/context/base/mkiv/buff-ver.mkxl
@@ -377,7 +377,7 @@
\permanent\protected\def\explicitcontrolspace {\optionalcontrolspace\allowbreak} % uses asciispace
\appendtoks
- \protected\def\obeyedspace{\hskip\zeropoint\asciispacechar\hskip\zeropoint}%
+ \enforced\protected\def\obeyedspace{\hskip\zeropoint\asciispacechar\hskip\zeropoint}%
\to \everyenableelements
\permanent\protected\def\obeyhyphens
diff --git a/tex/context/base/mkiv/char-act.mkxl b/tex/context/base/mkiv/char-act.mkxl
new file mode 100644
index 000000000..bdc5b0717
--- /dev/null
+++ b/tex/context/base/mkiv/char-act.mkxl
@@ -0,0 +1,112 @@
+%D \module
+%D [ file=char-act,
+%D version=2006.12.05,
+%D title=\CONTEXT\ Character Support,
+%D subtitle=Active,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Character Support / Active}
+
+\unprotect
+
+\ifdefined\page_otr_fill_and_eject_page \else \let\page_otr_fill_and_eject_page\relax \fi % forward reference
+
+%D \macros
+%D {obeyedspace, obeyedtab, obeyedline, obeyedpage}
+%D
+%D We have followed Knuth in naming macros that make \SPACE, \NEWLINE\ and \NEWPAGE\
+%D active and assigning them \type {\obeysomething}, but first we set some default
+%D values.
+%D
+%D These are expandable:
+
+\permanent\def\obeyedspace{\space}
+\permanent\def\obeyedtab {\obeyedspace}
+\permanent\def\obeyedline {\par}
+\permanent\def\obeyedpage {\page_otr_fill_and_eject_page}
+
+%D \macros
+%D {controlspace,setcontrolspaces}
+%D
+%D First we define \type {\obeyspaces}. When we want visible spaces (control spaces)
+%D we only have to adapt the definition of \type {\obeyedspace} to:
+
+\immutable\chardef\asciispacechar\spaceasciicode % a real space character
+
+\permanent\protected\def\naturalspace{\asciispacechar}
+\permanent\protected\def\controlspace{\hbox{\asciispacechar}} % rather tex, we need the unicode value
+\permanent\protected\def\normalspaces{\catcode\spaceasciicode\spacecatcode}
+
+% \bgroup
+% \catcode\spaceasciicode\activecatcode
+% \protected\gdef\obeyspaces {\catcode\spaceasciicode\activecatcode\def {\obeyedspace }}
+% \protected\gdef\setcontrolspaces{\catcode\spaceasciicode\activecatcode\def {\controlspace}}
+% \egroup
+
+%permanent\protected\def\obeyspaces {\catcode\spaceasciicode\activecatcode\letcharcode\spaceasciicode\obeyedspace }
+%permanent\protected\def\setcontrolspaces{\catcode\spaceasciicode\activecatcode\letcharcode\spaceasciicode\controlspace}
+
+%D \macros
+%D {obeytabs, obeylines, obeypages,ignoretabs, ignorelines, ignorepages}
+%D
+%D Next we take care of \NEWLINE\ and \NEWPAGE\ and because we want to be able to
+%D typeset listings that contain \TAB, we have to handle those too. Because we have
+%D to redefine the \NEWPAGE\ character locally, we redefine the meaning of this
+%D (often already) active character.
+
+% \expandafter\def\activeformfeedtoken{\par}
+
+\letcharcode\formfeedasciicode\par
+
+%D The following indirect definitions enable us to implement all kind of \type
+%D {\obeyed} handlers.
+
+% \protected\def\obeytabs {\catcode\tabasciicode \activecatcode\expandafter\def\activetabtoken {\obeyedtab }}
+% \protected\def\obeylines {\catcode\endoflineasciicode\activecatcode\expandafter\def\activeendoflinetoken{\obeyedline}}
+% \protected\def\obeypages {\catcode\formfeedasciicode \activecatcode\expandafter\def\activeformfeedtoken {\obeyedpage}}
+
+% \protected\def\ignoretabs {\catcode\tabasciicode \activecatcode\expandafter\def\activetabtoken {\obeyedspace}}
+% \protected\def\ignorelines{\catcode\endoflineasciicode\activecatcode\expandafter\def\activeendoflinetoken{\obeyedspace}}
+% \protected\def\ignorepages{\catcode\formfeedasciicode \ignorecatcode}
+% \protected\def\ignoreeofs {\catcode\endoffileasciicode\ignorecatcode}
+
+% but ... as we don't want to freeze to \obeyedspace etc which can be set after
+% \obeyspaces, we use an idirectness
+
+\def\_obeyed_space_{\obeyedspace}
+\def\_obeyed_tab_ {\obeyedtab}
+\def\_obeyed_line_ {\obeyedline}
+\def\_obeyed_page_ {\obeyedpage}
+
+\permanent\protected\def\obeyspaces {\catcode\spaceasciicode \activecatcode\enforced\letcharcode\spaceasciicode \_obeyed_space_}
+\permanent\protected\def\obeytabs {\catcode\tabasciicode \activecatcode\enforced\letcharcode\tabasciicode \_obeyed_tab_}
+\permanent\protected\def\obeylines {\catcode\endoflineasciicode\activecatcode\enforced\letcharcode\endoflineasciicode\_obeyed_line_}
+\permanent\protected\def\obeypages {\catcode\formfeedasciicode \activecatcode\enforced\letcharcode\formfeedasciicode \_obeyed_page_}
+
+\permanent\protected\def\ignoretabs {\catcode\tabasciicode \activecatcode\enforced\letcharcode\tabasciicode \_obeyed_space_}
+\permanent\protected\def\ignorelines{\catcode\endoflineasciicode\activecatcode\enforced\letcharcode\endoflineasciicode\_obeyed_space_}
+\permanent\protected\def\ignorepages{\catcode\formfeedasciicode \ignorecatcode}
+\permanent\protected\def\ignoreeofs {\catcode\endoffileasciicode\ignorecatcode}
+
+\permanent\protected\def\setcontrolspaces{\catcode\spaceasciicode\activecatcode\enforced\letcharcode\spaceasciicode\_control_space_}
+
+%D \macros
+%D {naturaltextext}
+%D
+%D When one uses \ETEX, switching to normal \TEX\ is possible too. We also introduce
+%D a switch that can be used in the drivers and set in higher level shell macros.
+
+\permanent\protected\def\naturaltextext#1\relax % this command will become obsolete
+ {\begingroup
+ \def\ascii{#1}%
+ \setcatcodetable\ctxcatcodes
+ \prettynaturalfont{\scantextokens\expandafter{\ascii}\ifhmode\unskip\fi}%
+ \endgroup}
+
+\endinput \protect
diff --git a/tex/context/base/mkiv/char-enc.mkxl b/tex/context/base/mkiv/char-enc.mkxl
new file mode 100644
index 000000000..d0dd3d20a
--- /dev/null
+++ b/tex/context/base/mkiv/char-enc.mkxl
@@ -0,0 +1,18 @@
+%D \module
+%D [ file=char-enc,
+%D version=2006.08.20,
+%D title=\CONTEXT\ Character Support,
+%D subtitle=Encodings,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Character Support / Encodings}
+
+\registerctxluafile{char-enc}{}
+
+\endinput
diff --git a/tex/context/base/mkiv/cldf-bas.mkxl b/tex/context/base/mkiv/cldf-bas.mkxl
new file mode 100644
index 000000000..962db5209
--- /dev/null
+++ b/tex/context/base/mkiv/cldf-bas.mkxl
@@ -0,0 +1,19 @@
+%D \module
+%D [ file=cldf-bas,
+%D version=2010.10.19,,
+%D title=\CONTEXT\ \LUA\ Document Functions,
+%D subtitle=Basics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Lua Documents / Basics}
+
+\registerctxluafile{cldf-bas}{}
+\registerctxluafile{cldf-prs}{}
+
+\endinput
diff --git a/tex/context/base/mkiv/cldf-com.mkiv b/tex/context/base/mkiv/cldf-com.mkiv
index a1e442872..7a8f7bf5c 100644
--- a/tex/context/base/mkiv/cldf-com.mkiv
+++ b/tex/context/base/mkiv/cldf-com.mkiv
@@ -14,6 +14,6 @@
\writestatus{loading}{ConTeXt Lua Documents / Functions}
\registerctxluafile{cldf-com}{}
-\registerctxluafile{cldf-ver}{}
+%registerctxluafile{cldf-ver}{}
\endinput
diff --git a/tex/context/base/mkiv/cldf-com.mkxl b/tex/context/base/mkiv/cldf-com.mkxl
new file mode 100644
index 000000000..7a8f7bf5c
--- /dev/null
+++ b/tex/context/base/mkiv/cldf-com.mkxl
@@ -0,0 +1,19 @@
+%D \module
+%D [ file=cldf-com,
+%D version=2010.10.19,,
+%D title=\CONTEXT\ \LUA\ Document Functions,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Lua Documents / Functions}
+
+\registerctxluafile{cldf-com}{}
+%registerctxluafile{cldf-ver}{}
+
+\endinput
diff --git a/tex/context/base/mkiv/cldf-ini.mkxl b/tex/context/base/mkiv/cldf-ini.mkxl
new file mode 100644
index 000000000..b393eb9b5
--- /dev/null
+++ b/tex/context/base/mkiv/cldf-ini.mkxl
@@ -0,0 +1,45 @@
+%D \module
+%D [ file=cldf-int,
+%D version=2019.01.01,
+%D title=\CONTEXT\ Data Macros,
+%D subtitle=Integer,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Lua Documents / Initialization}
+
+\newcount\trialtypesettingstate % gets aliased at the Lua end
+
+\registerctxluafile{cldf-ini}{autosuffix}
+
+%D With each new update of \MKIV\ we can join Within Temptation in singing:
+%D
+%D \startbuffer
+%D \startluacode
+%D context("I go faster%s",string.rep(" and faster",6))
+%D \stopluacode
+%D
+%D \cldcontext{"I go faster\letterpercent s",
+%D string.rep(" and faster",6)}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D Anyway \unknown\ the following are {\em not} user commands:
+
+% \catcode`=\activecatcode \let\luafunction % saves 10% on the call
+
+% todo: these can become implementers
+
+\permanent\protected\def\cldprocessfile#1{\directlua{context.runfile("#1")}}
+\permanent \def\cldloadfile #1{\directlua{context.loadfile("#1")}}
+\permanent \def\cldloadviafile#1{\directlua{context.loadviafile("#1")}}
+\permanent \def\cldcontext #1{\directlua{context(#1)}}
+\permanent \def\cldcommand #1{\directlua{context.#1}}
+
+\endinput
diff --git a/tex/context/base/mkiv/cldf-ver.mkxl b/tex/context/base/mkiv/cldf-ver.mkxl
new file mode 100644
index 000000000..0ff63810e
--- /dev/null
+++ b/tex/context/base/mkiv/cldf-ver.mkxl
@@ -0,0 +1,18 @@
+%D \module
+%D [ file=cldf-com,
+%D version=2010.10.19,
+%D title=\CONTEXT\ \LUA\ Document Functions,
+%D subtitle=Verbatim,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Lua Documents / Verbatim}
+
+\registerctxluafile{cldf-ver}{}
+
+\endinput
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 0043f9277..0f6cc7c6b 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2020.11.13 19:08}
+\newcontextversion{2020.11.15 20:40}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 56a1bfa72..e0941a513 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.11.13 19:08}
+\edef\contextversion{2020.11.15 20:40}
%D Kind of special:
@@ -133,7 +133,7 @@
\loadmkvifile{file-ini}
\loadmkvifile{file-res}
-\loadmkvifile{file-lib}
+\loadmkivfile{file-lib}
%D This needs more checking for clashes:
%D
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 0ae593a20..e417248eb 100644
--- a/tex/context/base/mkiv/context.mkxl
+++ b/tex/context/base/mkiv/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.11.13 19:08}
+\edef\contextversion{2020.11.15 20:40}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
@@ -101,7 +101,7 @@
\loadmarkfile{catc-sym}
\loadmkxlfile{toks-ini}
-\loadmarkfile{cldf-ini}
+\loadmkxlfile{cldf-ini}
% \tracecatcodetables
@@ -120,9 +120,9 @@
\loadmarkfile{luat-usr}
-\loadmkvifile{file-ini}
-\loadmkvifile{file-res}
-\loadmkvifile{file-lib}
+\loadmklxfile{file-ini}
+\loadmklxfile{file-res}
+\loadmkxlfile{file-lib}
\loadmkxlfile{core-lmt}
@@ -136,14 +136,14 @@
\loadmkxlfile{char-utf}
\loadmkxlfile{char-ini}
-\loadmarkfile{char-act}
+\loadmkxlfile{char-act}
\loadmkxlfile{mult-ini}
\loadmkxlfile{mult-sys}
\loadmkxlfile{mult-aux}
-\loadmarkfile{mult-def}
-\loadmarkfile{mult-chk}
-\loadmkvifile{mult-dim}
+\loadmkxlfile{mult-def}
+%loadmarkfile{mult-chk}
+\loadmklxfile{mult-dim}
\loadmkxlfile{cldf-int} % interface
@@ -156,11 +156,11 @@
\loadmarkfile{core-ini}
\loadmkxlfile{core-env}
-\loadmarkfile{layo-ini}
+\loadmkxlfile{layo-ini}
\loadmarkfile{node-ini}
-\loadmarkfile{cldf-bas} % basics / depends on nodes
+\loadmkxlfile{cldf-bas} % basics / depends on nodes
\loadmkivfile{node-fin}
\loadmkxlfile{node-mig}
@@ -169,15 +169,15 @@
\loadmkxlfile{driv-ini}
\loadmkxlfile{back-ini}
-\loadmarkfile{back-res}
-\loadmarkfile{back-trf}
+\loadmkxlfile{back-res}
+\loadmkxlfile{back-trf}
\loadmkxlfile{back-out}
-\loadmarkfile{attr-col}
-\loadmarkfile{attr-lay}
-\loadmarkfile{attr-neg}
+\loadmkxlfile{attr-col}
+\loadmkxlfile{attr-lay}
+\loadmkxlfile{attr-neg}
\loadmkxlfile{attr-eff}
-\loadmarkfile{attr-mkr}
+\loadmkxlfile{attr-mkr}
\loadmarkfile{trac-tex}
\loadmarkfile{trac-deb} % will move up
@@ -214,7 +214,7 @@
\loadmarkfile{lang-hyp} % also loads dis
\loadmkxlfile{lang-lab}
-\loadmarkfile{unic-ini}
+\loadmkxlfile{unic-ini}
% \loadmarkfile{core-uti}
\loadmarkfile{core-two}
@@ -327,7 +327,7 @@
\loadmkvifile{page-mak}
\loadmkxlfile{page-mcl}
-\loadmarkfile{strc-reg} % uses mixed columns
+\loadmkxlfile{strc-reg} % uses mixed columns
\loadmkvifile{page-lin}
\loadmarkfile{page-par}
@@ -367,7 +367,7 @@
\loadmkvifile{scrn-fld}
\loadmkvifile{scrn-hlp}
-\loadmarkfile{char-enc} % will move up, can be in char-utf
+\loadmkxlfile{char-enc}
\loadmkvifile{font-lib} % way too late but after language
\loadmklxfile{font-fil}
@@ -381,7 +381,7 @@
\loadmklxfile{font-emp}
\loadmarkfile{font-pre}
\loadmarkfile{font-unk}
-\loadmarkfile{font-tra}
+\loadmkxlfile{font-tra}
\loadmkxlfile{font-chk}
\loadmarkfile{font-uni}
\loadmklxfile{font-col}
@@ -442,7 +442,7 @@
\loadmarkfile{scrp-ini}
-\loadmarkfile{symb-emj}
+\loadmkxlfile{symb-emj}
\loadmarkfile{lang-tra} % can be optional (discussion with mm sideeffect)
\loadmarkfile{lang-wrd} % can be optional (discussion with mm sideeffect)
@@ -539,9 +539,9 @@
% new bibtex support:
-\loadmarkfile{publ-ini}
-\loadmarkfile{publ-tra}
-\loadmarkfile{publ-xml}
+\loadmkxlfile{publ-ini}
+\loadmkxlfile{publ-tra}
+\loadmkxlfile{publ-xml}
\loadmarkfile{publ-old}
%loadmarkfile{x-xtag} % no longer preloaded
@@ -552,8 +552,8 @@
% \loadmarkfile{task-ini}
-\loadmarkfile{cldf-ver} % verbatim, this can come late
-\loadmarkfile{cldf-com} % commands, this can come late
+\loadmkxlfile{cldf-ver} % verbatim, this can come late
+\loadmkxlfile{cldf-com} % commands, this can come late
\loadmarkfile{core-ctx} % this order might change but we need to check depedencies / move to another namespace
@@ -567,19 +567,19 @@
\loadmkxlfile{driv-shp}
-\loadmarkfile{back-exp}
+\loadmkxlfile{back-exp}
\loadmkxlfile{back-pdf}
\loadmkxlfile{back-mps}
\loadmkxlfile{back-lua}
\loadmkxlfile{mlib-pdf}
-\loadmarkfile{mlib-pps}
+\loadmkxlfile{mlib-pps}
\loadmarkfile{meta-pdf}
\loadmarkfile{meta-blb}
\loadmkxlfile{grph-epd}
\loadmarkfile{math-inc} % an experiment
-\loadmarkfile{publ-inc} % an experiment
+\loadmkxlfile{publ-inc} % an experiment
\loadmarkfile{task-ini}
diff --git a/tex/context/base/mkiv/file-ini.mklx b/tex/context/base/mkiv/file-ini.mklx
new file mode 100644
index 000000000..a410854a8
--- /dev/null
+++ b/tex/context/base/mkiv/file-ini.mklx
@@ -0,0 +1,231 @@
+%D \module
+%D [ file=file-ini, % was supp-fil,
+%D version=20110701, % 1995.10.10,
+%D title=\CONTEXT\ File Macros,
+%D subtitle=Helpers,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D \TEX\ operates on files, so one wouldn't wonder that there is a separate module
+%D for file commands. In \CONTEXT\ files are used for several purposes:
+%D
+%D \startitemize[packed]
+%D \item general textual input
+%D \item logging status information
+%D \item saving registers, lists and references
+%D \item buffering defered textual input
+%D \stopitemize
+%D
+%D When dealing with files we can load them as a whole, using the \type {\input}
+%D primitive or load them on a line||by||line basis, using \type {\read}. Writing is
+%D always done line by line, using \type {\write}.
+
+\writestatus{loading}{ConTeXt File Macros / Helpers}
+
+\registerctxluafile{file-ini}{}
+
+\unprotect
+
+%D \macros
+%D {scratchread, scratchwrite}
+%D
+%D We define a scratch file for reading. Keep in mind that the number of files is
+%D limited to~16, so use this one when possible. We also define a scratch output
+%D file. In \MKIV\ and \LMTX\ we never use these file handles.
+
+\ifdefined\scratchread \else \newread \scratchread \fi
+\ifdefined\scratchwrite \else \newwrite\scratchwrite \fi
+
+%D Seldom needed:
+
+\permanent\def\openinputfile #handle#name{\immediate\openin #handle={#name}\relax}
+\permanent\def\openoutputfile #handle#name{\immediate\openout#handle={#name}\relax}
+
+\permanent\def\closeinputfile #handle{\immediate\closein #handle\relax}
+\permanent\def\closeoutputfile#handle{\immediate\closeout#handle\relax}
+
+%D \macros
+%D {writeln}
+%D
+%D This saves a few tokens:
+
+\permanent\def\writeln#handle{\write#handle{}}
+
+%D \macros
+%D {pushendofline,popendofline}
+%D
+%D When we are loading files in the middle of the typesetting process, for instance
+%D when we load references, we have to be sure that the reading process does not
+%D generate so called 'spurious spaces'. This can be prevented by assigning the line
+%D ending character the \CATCODE\ comment. This is accomplished by
+%D
+%D \starttyping
+%D \pushendofline
+%D ... reading ...
+%D \popendofline
+%D \stoptyping
+
+\installsystemnamespace{eolstack}
+
+\newcount\c_system_files_eol_level
+
+\permanent\protected\def\pushendofline
+ {\advance\c_system_files_eol_level\plusone
+ \expandafter\chardef\csname\??eolstack\number\c_system_files_eol_level\endcsname\catcode\endoflineasciicode
+ \catcode\endoflineasciicode\commentcatcode}
+
+\permanent\protected\def\popendofline
+ {\catcode\endoflineasciicode\csname\??eolstack\number\c_system_files_eol_level\endcsname
+ \advance\c_system_files_eol_level\minusone}
+
+\permanent\protected\def\restoreendofline
+ {\catcode\endoflineasciicode\endoflinecatcode}
+
+%D \macros
+%D {startreadingfile,stopreadingfile}
+%D
+%D A low level capsule:
+
+\newcount\readingfilelevel % no longer needed
+\newtoks \everystartreadingfile
+\newtoks \everystopreadingfile
+
+\protected\def\startreadingfile% beter een every en \setnormalcatcodes
+ {\global\advance\readingfilelevel\plusone
+ \the\everystartreadingfile
+ \pushcatcodetable % saveguard
+ \setcatcodetable\ctxcatcodes
+ \clf_pushregime}% temporarily this way
+
+\protected\def\stopreadingfile
+ {\popcatcodetable % saveguard
+ \clf_popregime % temporarily this way
+ \the\everystopreadingfile
+ \global\advance\readingfilelevel\minusone}
+
+%D \macros
+%D {input, normalinput}
+%D
+%D Sometimes we run into troubles when \type {\input} wants to get expanded, e.g. in
+%D a \type {\write} (which happens in the metafun manual when we permit long MP
+%D lines). So, instead of fixing that, we go for a redefinition of \type {\input}.
+%D Of course it's better to use \type {\readfile} or \type {\processfile}.
+
+\permanent\def\inputgivenfile#name{\normalinput{#name}} % expands
+
+%D \macros
+%D {doifelsefile}
+%D
+%D The next alternative only looks if a file is present. No loading is done. This
+%D one obeys the standard \TEX\ lookup.
+%D
+%D \starttyping
+%D \doiffileelse {filename} {found} {not found}
+%D \stoptyping
+
+\permanent\protected\def\doifelsefile {\clf_doifelsefileexist}
+\permanent\protected\def\doifelsepath {\clf_doifelsepathexist}
+\permanent\protected\def\doiffile #name{\clf_doifelsefileexist{#name}\firstofoneargument\gobbleoneargument}
+\permanent\protected\def\doifnotfile #name{\clf_doifelsefileexist{#name}\gobbleoneargument\firstofoneargument}
+
+\aliased\let\doiffileelse\doifelsefile
+\aliased\let\doifpathelse\doifelsepath
+
+\aliased\let\doifelsefileexists\doifelsefile
+\aliased\let\doifelsepathexists\doifelsepath
+
+\aliased\let\doiffileexistselse\doifelsefileexists
+\aliased\let\doifpathexistselse\doifelsepathexists
+
+%D \macros
+%D {doifparentfileelse}
+%D
+%D \starttyping
+%D \doifparentfileelse{filename}{yes}{no}
+%D \stoptyping
+
+\ifdefined\outputfilename \else \def\outputfilename{\jobname} \fi
+
+\permanent\protected\def\doifelseparentfile{\clf_doifelseparentfile}
+
+\aliased\let\doifparentfileelse\doifelseparentfile
+
+%D \macros
+%D {splitfilename}
+%D
+%D \startbuffer
+%D \def\showfilesplit
+%D {\bgroup \tttf
+%D \hbox{(full: \splitofffull)}\space
+%D \hbox{(path: \splitoffpath)}\space
+%D \hbox{(base: \splitoffbase)}\space
+%D \hbox{(name: \splitoffname)}\space
+%D \hbox{(type: \splitofftype)}\space
+%D \egroup}
+%D
+%D \splitfilename{c:/aa/bb/cc/dd.ee.ff} \showfilesplit \endgraf
+%D \splitfilename{c:/aa/bb/cc/dd.ee} \showfilesplit \endgraf
+%D \splitfilename{c:/aa/bb/cc/dd} \showfilesplit \endgraf
+%D
+%D \splitfilename{dd.ee.ff} \showfilesplit \endgraf
+%D \splitfilename{dd.ee} \showfilesplit \endgraf
+%D \splitfilename{dd} \showfilesplit \endgraf
+%D \stopbuffer
+%D
+%D \start \typebuffer \getbuffer \stop
+
+\newconstant\kindoffile % 0=normal 1=full path spec (or http) / set at the lua end
+
+\def\splitoffroot{.} \newconstant\splitoffkind
+
+\let\splitofffull\empty
+\let\splitoffpath\empty
+\let\splitoffbase\empty
+\let\splitoffname\empty
+\let\splitofftype\empty
+
+\permanent\protected\def\splitfilename{\clf_splitfilename}
+
+%D \macros
+%D {doonlyonce, doinputonce, doendinputonce}
+%D
+%D Especially macropackages need only be loaded once. Repetitive loading not only
+%D costs time, relocating registers often leads to abortion of the processing
+%D because \TEX's capacity is limited. One can prevent multiple execution and
+%D loading by using one of both:
+%D
+%D \starttyping
+%D \doonlyonce{actions}
+%D \doinputonce{filename}
+%D \doendinputonce{filename}
+%D \stoptyping
+%D
+%D This command obeys the standard method for locating files. We could move this
+%D function to the \LUA\ end.
+
+\installsystemnamespace {fileonce}
+
+\permanent\protected\def\doonlyonce#whatever%
+ {\ifcsname\??fileonce#whatever\endcsname
+ \expandafter\gobbleoneargument
+ \else
+ \letgvalue{\??fileonce#whatever}\relax
+ \expandafter\firstofoneargument
+ \fi}
+
+\permanent\protected\def\doinputonce#name%
+ {\doonlyonce{#name}{\doifelsefile{#name}{\inputgivenfile{#name}}\donothing}}
+
+\permanent\protected\def\doendinputonce#name%
+ {\ifcsname\??fileonce#name\endcsname
+ \expandafter\endinput
+ \fi}
+
+\permanent\protected\def\forgetdoingonce#whatever%
+ {\global\undefinevalue{\??fileonce#whatever}}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/file-lib.mkvi b/tex/context/base/mkiv/file-lib.mkiv
index c2ec555cf..c2ec555cf 100644
--- a/tex/context/base/mkiv/file-lib.mkvi
+++ b/tex/context/base/mkiv/file-lib.mkiv
diff --git a/tex/context/base/mkiv/file-lib.mkxl b/tex/context/base/mkiv/file-lib.mkxl
new file mode 100644
index 000000000..c2ec555cf
--- /dev/null
+++ b/tex/context/base/mkiv/file-lib.mkxl
@@ -0,0 +1,20 @@
+%D \module
+%D [ file=file-lib, % was core-fil,
+%D version=20110701, % 1997.11.15,
+%D title=\CONTEXT\ File Macros,
+%D subtitle=Module Support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt File Macros / Libraries}
+
+\unprotect
+
+\registerctxluafile{file-lib}{}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/file-res.mklx b/tex/context/base/mkiv/file-res.mklx
new file mode 100644
index 000000000..a523302d1
--- /dev/null
+++ b/tex/context/base/mkiv/file-res.mklx
@@ -0,0 +1,145 @@
+%D \module
+%D [ file=file-mod, % was supp-fil,
+%D version=20110701, % 1995.10.10,
+%D title=\CONTEXT\ File Macros,
+%D subtitle=Resolvers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D We could move some more to the lua end (implementors).
+
+\writestatus{loading}{ConTeXt File Macros / Resolvers}
+
+\unprotect
+
+\registerctxluafile{file-res}{}
+
+%D \macros
+%D {readfile,ReadFile}
+%D
+%D One cannot be sure if a file exists. When no file can be found, the \type
+%D {\input} primitive gives an error message and switches to interactive mode. The
+%D macro \type {\readfile} takes care of non||existing files. This macro has two
+%D faces.
+%D
+%D \starttyping
+%D \ReadFile {filename}
+%D \readfile {filename} {before loading} {not found}
+%D \stoptyping
+%D
+%D Many \TEX\ implementations have laid out some strategy for locating files. This
+%D can lead to unexpected results, especially when one loads files that are not
+%D found in the current directory. Let's give an example of this. In \CONTEXT\
+%D illustrations can be defined in an external file. The resizing macro first looks
+%D if an illustration is defined in the local definitions file. When no such file is
+%D found, it searches for a global file and when this file is not found either, the
+%D illustration itself is scanned for dimensions. One can imagine what happens if an
+%D adapted, localy stored illustration, is scaled according to dimensions stored
+%D somewhere else.
+%D
+%D When some \TEX\ implementation starts looking for a file, it normally first looks
+%D in the current directory. When no file is found, \TEX\ starts searching on the
+%D path where format and|/|or style files are stored. Depending on the
+%D implementation this can considerably slow down processing speed.
+%D
+%D In \CONTEXT, we support a project||wise ordening of files. In such an approach it
+%D seems feasible to store common files in a lower directory. When for instance
+%D searching for a general layout file, we therefore have to backtrack.
+%D
+%D These three considerations have lead to a more advanced approach for loading
+%D files.
+%D
+%D We first present an earlier implementation of \type {\readfile}. This command
+%D backtracks parent directories, upto a predefined level. Users can change this
+%D level (on the commandline using a directive); we default to~3.
+%D
+%D We use \type {\normalinput} instead of \type {\input} because we want to be able
+%D to redefine the original \type {\input} when needed, for instance when loading
+%D third party libraries.
+
+\let\readfilename\empty
+
+\def\syst_files_read_file#protocol#path#name% #true #false
+ {\edef\readfilename{\clf_getreadfilename{#protocol}{#path}{#name}}%
+ \ifempty\readfilename
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\syst_files_read_file_indeed
+ \fi}
+
+\def\syst_files_read_file_indeed#true#false%
+ {#true%
+ \relax
+ \normalinput{\readfilename}%
+ \relax}
+
+%D \macros
+%D {readjobfile,readlocfile,readsysfile,
+%D readfixfile,readsetfile}
+%D
+%D This implementation honnors the third situation, but we still can get unwanted
+%D files loaded and/or can get involved in extensive searching.
+%D
+%D Due to different needs, we decided to offer four alternative loading commands.
+%D With \type {\readjobfile} we load a local file and do no backtracking, while
+%D \type {\readlocfile} backtracks~\number \maxreadlevel\ directories, including the
+%D current one.
+%D
+%D System files can be anywhere and therefore \type {\readsysfile} is not bound to
+%D the current directory and obeys the \TEX\ implementation.
+%D
+%D Of the last two, \type {\readfixfile} searches on the directory specified and
+%D backtracks too, while \type {\readsetfile} does only search on the specified
+%D path.
+%D
+%D The most liberal is \type {\readfile}.
+
+\permanent\protected\def\readjobfile #name{\syst_files_read_file{job} {.}{#name}} % current path, no backtracking
+\permanent\protected\def\readlocfile #name{\syst_files_read_file{loc} {.}{#name}} % current path, backtracking
+\permanent\protected\def\readsysfile #name{\syst_files_read_file{sys} {.}{#name}} % current path, obeys tex search
+\permanent\protected\def\readfixfile#path#name{\syst_files_read_file{fix}{#path}{#name}} % specified path, backtracking
+\permanent\protected\def\readsetfile#path#name{\syst_files_read_file{set}{#path}{#name}} % specified path, no backtracking
+\permanent\protected\def\readfile #name{\syst_files_read_file{any} {.}{#name}}
+\permanent\protected\def\ReadFile #name{\syst_files_read_file{any} {.}{#name}\donothing\donothing}
+
+%D So now we've got ourselves five file loading commands:
+%D
+%D \starttyping
+%D \readfile {filename} {before loading} {not found}
+%D
+%D \readjobfile {filename} {before loading} {not found}
+%D \readlocfile {filename} {before loading} {not found}
+%D \readfixfile {filename} {before loading} {not found}
+%D \readsysfile {directory} {filename} {before loading} {not found}
+%D \stoptyping
+
+\permanent\protected\def\readtexfile#name#true#false%
+ {\pushcatcodetable
+ \catcodetable\ctxcatcodes
+ \readfile{#name}{#true}{#false}%
+ \popcatcodetable}
+
+\permanent\protected\def\readxmlfile#name#true#false%
+ {\pushcatcodetable
+ \catcodetable\xmlcatcodes
+ \readfile{#name}{#true}{#false}%
+ \popcatcodetable}
+
+%D \macros
+%D {doiflocfileelse,locfilename}
+%D
+%D \starttyping
+%D \doiflocfileelse {filename} {before loading} {not found}
+%D \stoptyping
+
+\permanent\protected\def\doifelselocfile#name{\clf_doifelselocfile{#name}}
+\permanent \def\locfilename #name{\clf_locfilename {#name}}
+
+\aliased\let\doiflocfileelse\doifelselocfile
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index fe972114f..da22f3bf9 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.111
+ otf.version = otf.version or 3.112
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index aff4cc8c8..e8f89b4e7 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.111 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.112 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
diff --git a/tex/context/base/mkiv/font-tra.mkxl b/tex/context/base/mkiv/font-tra.mkxl
new file mode 100644
index 000000000..72addc5e9
--- /dev/null
+++ b/tex/context/base/mkiv/font-tra.mkxl
@@ -0,0 +1,343 @@
+%D \module
+%D [ file=font-tra,
+%D version=2009.01.02, % or so
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=Tracing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\writestatus{loading}{ConTeXt Font Macros / Tracing}
+
+%D just use fontid
+
+%D \macros
+%D {showbodyfont}
+%D
+%D One can call for a rather simple overview of a bodyfont and the relations between
+%D its alternative fonts.
+%D
+%D \showsetup{showbodyfont}
+%D
+%D The current bodyfont (here we omitted the argument) looks like:
+%D
+%D \showbodyfont
+%D
+%D The implementation is rather straightforward in using \type {\halign}.
+
+\fetchruntimecommand \showbodyfont \f!font_run
+
+%D \macros
+%D {showfontstrip, testminimalbaseline, showminimalbaseline}
+%D
+%D The next command can come in handy when combining different fonts into a
+%D collection (typeface) and determining optimal baseline distances.
+%D
+%D \showfontstrip \blank \showminimalbaseline
+
+\fetchruntimecommand \showfontstrip \f!font_run
+\fetchruntimecommand \testminimalbaseline \f!font_run
+\fetchruntimecommand \showminimalbaseline \f!font_run
+
+%D \macros
+%D {showkerning}
+%D
+%D A goody is:
+%D
+%D \showkerning{Can you guess what kerning is?}
+
+\fetchruntimecommand \showkerning \f!font_run
+
+%D \macros
+%D {showbodyfontenvironment,showfont,showfontstyle,showligatures}
+%D
+%D The current bodyfontenvironment is:
+%D
+%D \showbodyfontenvironment
+%D
+%D This overview is generated using:
+%D
+%D \showsetup{showbodyfontenvironment}
+
+\fetchruntimecommand \showbodyfontenvironment \f!font_run
+
+%D The following command generates a fontmap:
+%D
+%D \startbuffer
+%D \showfont[SansBold at 12pt]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \getbuffer
+
+\fetchruntimecommand \showfont \f!font_run
+\fetchruntimecommand \showfontstyle \f!font_run
+\fetchruntimecommand \showligature \f!font_run
+\fetchruntimecommand \showligatures \f!font_run
+\fetchruntimecommand \showcharratio \f!font_run
+\fetchruntimecommand \showfontparameters \f!font_run
+
+\permanent\protected\def\showchardata#1{\ctxcommand{showchardata("#1")}} % todo: direct implementor
+\permanent\protected\def\showfontdata {\ctxcommand{showfontparameters()}} % todo: direct implementor
+
+%D \macros
+%D {doiffontpresentelse}
+%D
+%D \starttyping
+%D \doiffontpresentelse{texnansi-lmr10}{YES}{NO}
+%D \doiffontpresentelse{adam-lindsay-modern-serif}{YES}{NO}
+%D \stoptyping
+
+\permanent\protected\def\doifelsefontpresent#1{\clf_doifelsefontpresent{#1}}
+
+\aliased\let\doiffontpresentelse\doifelsefontpresent
+
+% experimental, maybe this becomes a module
+
+\newbox\otfcollector
+
+\permanent\protected\def\startotfcollecting{\ctxlua{nodes.tracers.steppers.start()}}
+\permanent\protected\def\stopotfcollecting {\ctxlua{nodes.tracers.steppers.stop()}}
+\permanent\protected\def\resetotfcollecting{\ctxlua{nodes.tracers.steppers.reset()}}
+
+% \page \showotfcomposition{arabtype*arab-default at 48pt}{-1}{الضَّرَّ} \page
+% \page \showotfcomposition{arabtype*arab-default at 48pt}{-1}{لِلّٰهِ} \page
+
+\permanent\protected\def\showotfstepglyphs#1%
+ {\ctxlua{nodes.tracers.steppers.glyphs(\number\otfcollector,#1)}%
+ \unhbox\otfcollector}
+
+\permanent\protected\def\otfstepspace
+ {\removeunwantedspaces
+ \hskip.5\emwidth \s!plus .125\emwidth \s!minus .125\emwidth\relax}
+
+\permanent\protected\def\otfstepcharcommand#1#2#3% font char class
+ {\otfstepspace
+ \doif{#3}{mark}{\underbar}{U+\hexnumber{#2}}:%
+ \setbox\scratchbox\hbox{\ctxlua{nodes.tracers.fontchar(#1,#2)}}%
+ \ifzeropt\wd\scratchbox
+ \scratchwidth.125\onepoint
+ \scratchdistance\dimexpr(\emwidth/2-\scratchwidth)\relax
+ \kern\scratchdistance
+ \ruledhbox to \scratchwidth{\hss\box\scratchbox\hss}%
+ \kern-\scratchwidth
+ \hskip\scratchdistance
+ \else
+ \ruledhbox{\box\scratchbox}%
+ \fi
+ \otfstepspace}
+
+\permanent\protected\def\otfstepfontcommand#1#2#3% id font size
+ {\begingroup
+ \tttf #1: #2 @ \the\dimexpr#3\scaledpoint\relax
+ \endgroup}
+
+\permanent\protected\def\otfstepmessagecommand#1#2%
+ {\begingroup
+ \tttf\language\minusone
+ \veryraggedright
+ \forgetparindent
+ \forgeteverypar
+ \hangindent\emwidth
+ \hangafter\plusone
+ \dontleavehmode\detokenize{#1}\removeunwantedspaces
+ \doifsomething{#2}{,\space\detokenize{#2}}\endgraf
+ \endgroup
+ \blank}
+
+\permanent\protected\def\showotfstepfont
+ {\ctxlua{nodes.tracers.steppers.font("otfstepfontcommand")}}
+
+\permanent\protected\def\showotfstepchars#1%
+ {\ctxlua{nodes.tracers.steppers.codes(#1,"otfstepcharcommand","otfstepspace")}}
+
+\permanent\protected\def\showotfstepmessages#1%
+ {\ctxlua{nodes.tracers.steppers.messages(#1,"otfstepmessagecommand",true)}}
+
+\permanent\protected\def\showotfstepfeatures
+ {\ctxlua{nodes.tracers.steppers.features()}}
+
+\permanent\protected\def\otfnoffeaturesteps
+ {\ctxlua{nodes.tracers.steppers.nofsteps()}}
+
+\newconstant\showotfstepsmode \showotfstepsmode\plusfour
+
+\protected\def\showotfsteps_n
+ {\blank
+ \begingroup
+ \advance\leftskip6\emwidth
+ \showotfstepmessages\recurselevel
+ \par
+ \endgroup
+ \blank
+ \dontleavehmode
+ \hbox to \hsize \bgroup
+ \hbox to 6\emwidth \bgroup
+ \bf
+ \ifnum\recurselevel=\scratchcounter result\else step \recurselevel\fi
+ \hss
+ \egroup
+ \vtop \bgroup
+ \hsize\dimexpr\hsize-6\emwidth\relax
+ \resetallattributes
+ \lefttoright
+ \dontleavehmode
+ \ifnum\recurselevel=\scratchcounter
+ \ruledhbox{\box\otfcompositionbox}%
+ \else
+ \ruledhbox{\showotfstepglyphs\recurselevel}%
+ \fi
+ \quad
+ \showotfstepchars\recurselevel
+ \hfill
+ \par
+ \egroup
+ \egroup
+ \blank}
+
+\permanent\protected\def\showotfsteps
+ {\begingroup
+ \veryraggedright
+ \forgetparindent
+ \forgeteverypar
+ \tt
+ \lefttoright
+ \hbox to \hsize \bgroup
+ \hbox to 6\emwidth{\bf font\hss}%
+ \vtop \bgroup
+ \hsize\dimexpr\hsize-6\emwidth\relax
+ \language\minusone
+ \bf
+ \showotfstepfont
+ \egroup
+ \egroup
+ \blank
+ \hbox to \hsize \bgroup
+ \hbox to 6\emwidth{\bf features\hss}%
+ \vtop \bgroup
+ \hsize\dimexpr\hsize-6\emwidth\relax
+ \language\minusone
+ \showotfstepfeatures
+ \egroup
+ \egroup
+ \blank
+ \scratchcounter\otfnoffeaturesteps\relax
+ \dorecurse\scratchcounter
+ {\ifcase\showotfstepsmode
+ \or % 1 = only first
+ \ifnum\recurselevel=\plusone
+ \showotfsteps_n
+ \fi
+ \or % 2 = only last
+ \ifnum\recurselevel=\scratchcounter
+ \showotfsteps_n
+ \fi
+ \or % 3 = first and last
+ \ifnum\recurselevel=\plusone
+ \showotfsteps_n
+ \orelse\ifnum\recurselevel=\scratchcounter
+ \showotfsteps_n
+ \fi
+ \else % everything
+ \showotfsteps_n
+ \fi}%
+ \endgroup}
+
+\permanent\protected\def\startotfsample
+ {\enabletrackers[otf.sample.silent]% beware, kind of global
+ \startotfcollecting
+ \begingroup
+ \veryraggedright
+ \forgetparindent
+ \forgeteverypar}
+
+\permanent\protected\def\stopotfsample
+ {\endgroup
+ \stopotfcollecting
+ \disabletrackers[otf.sample]% beware, kind of global: otf.sample
+ \showotfsteps
+ \resetotfcollecting}
+
+\newbox\otfcompositionbox
+
+% this should go in spac-ali:
+
+\installcorenamespace{otfcompositiondir}
+
+\letvalue{\??otfcompositiondir -1}\righttoleft
+\letvalue{\??otfcompositiondir r2l}\righttoleft
+\letvalue{\??otfcompositiondir l2r}\lefttoright
+\letvalue{\??otfcompositiondir +1}\lefttoright
+\letvalue{\??otfcompositiondir 1}\lefttoright
+
+\permanent\protected\def\setotfcompositiondirection#1%
+ {\begincsname\??otfcompositiondir#1\endcsname}
+
+\permanent\protected\def\showotfcomposition#1#2#3% {font*features at size}, rl=-1, text
+ {\begingroup
+ \forgetparindent
+ \forgeteverypar
+ % \setupcolors[\c!state=\v!start]%
+ \setupalign[\v!verytolerant,\v!flushleft]%
+ \startotfsample
+ \nohyphens
+ \global\setbox\otfcompositionbox\hbox{\definedfont[#1]\relax\setotfcompositiondirection{#2}\relax#3}%
+ \stopotfsample
+ \endgroup}
+
+%D \startbuffer
+%D \startotfcompositionlist{Serif*default @ 11pt}{l2r}%
+%D \showotfcompositionsample{effe}
+%D \stopotfcompositionlist
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\permanent\protected\def\showotfcompositionlist#1#2#3%
+ {\begingroup
+ \definedfont[#1]%
+ \setbox\scratchbox\hbox\bgroup
+ \setotfcompositiondirection{#2}%
+ #3%
+ \egroup
+ \strut
+ \def|##1|{\kern\onepoint\string|\kern\onepoint##1\kern\onepoint\string|\kern\onepoint}%
+ \cldcontext{nodes.listtoutf(tex.box[\number\scratchbox].list,"{\\kern\\onepoint}",true)}%
+ \endgroup}
+
+\aliased\let\showotfcompositionsample\gobbleoneargument
+
+\permanent\protected\def\startotfcompositionlist#1#2#3\stopotfcompositionlist
+ {\begingroup
+ \enforced\protected\def\showotfcompositionsample##1%
+ {\NC\type{##1}%
+ \NC\showotfcompositionlist{Mono}{#2}{##1}%
+ \NC\showotfcompositionlist{#1}{#2}{##1}%
+ \NC\definedfont[#1]##1%
+ \NC\NR}%
+ \starttabulate[|||||]%
+ #3%
+ \stoptabulate
+ \endgroup}
+
+\aliased\let\stopotfcompositionlist\relax
+
+% new
+
+\permanent\protected\def\savefontdata[#1]% not yet in i-*.xml
+ {\begingroup
+ \getdummyparameters[#1]%
+ \clf_savefont {
+ filename {\dummyparameter\c!file}
+ fontname {\dummyparameter\c!name}
+ method {\dummyparameter\c!method}
+ }%
+ \endgroup}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua
index 865f8e6e3..a2732aa5f 100644
--- a/tex/context/base/mkiv/font-ttf.lua
+++ b/tex/context/base/mkiv/font-ttf.lua
@@ -163,8 +163,7 @@ local function mergecomposites(glyphs,shapes)
return contours, points
end
--- for index=1,#glyphs do
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape = shapes[index]
if shape then
local components = shape.components
@@ -659,7 +658,7 @@ local function repackpoints(glyphs,shapes)
local result = { } -- reused
local xpoints = { } -- reused
local ypoints = { } -- reused
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape = shapes[index]
if shape then
local r = 0
diff --git a/tex/context/base/mkiv/lang-mis.mkxl b/tex/context/base/mkiv/lang-mis.mkxl
index 853a7a7c2..de15ec526 100644
--- a/tex/context/base/mkiv/lang-mis.mkxl
+++ b/tex/context/base/mkiv/lang-mis.mkxl
@@ -227,7 +227,7 @@
%D \type{||word}, while it counterpart \type {\lang_discretionaries_check_after} is
%D responsible for handling the comma.
-\newsignal\compoundbreakpoint
+\newsignal\d_lang_discretionaries_breakpoint % todo: never consulted so maybe obsolete
\newconditional\punctafterdiscretionary
\newconditional\spaceafterdiscretionary
@@ -500,7 +500,8 @@
\def\lang_compounds_fake_hyphen
{\enforced\permanent\protected\def##1|%
{\doifelsenothing{##1}\compoundhyphen{##1}%
- \kern\compoundbreakpoint\allowbreak}}
+ \kern\d_lang_discretionaries_breakpoint
+ \allowbreak}}
%D \macros
%D {midworddiscretionary}
diff --git a/tex/context/base/mkiv/layo-ini.mkxl b/tex/context/base/mkiv/layo-ini.mkxl
new file mode 100644
index 000000000..4979989cd
--- /dev/null
+++ b/tex/context/base/mkiv/layo-ini.mkxl
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=layo-ini,
+%D version=2011.02.18,
+%D title=\CONTEXT\ Layout Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Layout Macros / Initialization}
+
+%D This module deals with the basic variables etc. for layout and code from other
+%D modules will move here. This will make the dependencies somewhat cleaner.
+
+\unprotect
+
+%D We need to check this in case a smaller format is loaded.
+
+\ifdefined\layoutisdoublesided \else \newconditional\layoutisdoublesided \fi
+\ifdefined\layoutissinglesided \else \newconditional\layoutissinglesided \fi
+\ifdefined\pagenoshift \else \newcount \pagenoshift \fi
+\ifdefined\realpageno \else \newcount \realpageno \fi
+
+\registerctxluafile{layo-ini}{}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua
index cce6ab73b..874287ee1 100644
--- a/tex/context/base/mkiv/luat-run.lua
+++ b/tex/context/base/mkiv/luat-run.lua
@@ -302,12 +302,13 @@ callback.register("handle_overload", function(fatal,overload,csname,flags)
local readstate = status.readstate
local filename = readstate.filename
local linenumber = readstate.linenumber
+ local flags = tokens.flags and tokens.flags(csname) or { }
if filename and linenumber then
report("%s, protection level %i, control sequence %a, properties '% t', file %a, line %i",
- fatal and "fatal error" or "warning",overload,csname,tokens.flags(csname),filename,linenumber)
+ fatal and "fatal error" or "warning",overload,csname,flags,filename,linenumber)
else
report("%s, protection level %i, control sequence %a, properties '% t'",
- fatal and "fatal error" or "warning",overload,csname,tokens.flags(csname))
+ fatal and "fatal error" or "warning",overload,csname,flags)
end
reported[csname] = true
logs.newline()
diff --git a/tex/context/base/mkiv/m-oldbibtex.mkiv b/tex/context/base/mkiv/m-oldbibtex.mkiv
index 08c23e7cc..3300e0d79 100644
--- a/tex/context/base/mkiv/m-oldbibtex.mkiv
+++ b/tex/context/base/mkiv/m-oldbibtex.mkiv
@@ -10,7 +10,12 @@
%C This module is part of the \CONTEXT\ macro||package and is therefore copyrighted
%D by \PRAGMA. See mreadme.pdf for details.
-\loadmarkfile{bibl-bib}
-\loadmarkfile{bibl-tra}
+\ifconditional\contextlmtxmode
+ \loadmkivfile{bibl-bib}
+ \loadmkivfile{bibl-tra}
+\else
+ \loadmkivfile{bibl-bib}
+ \loadmkxlfile{bibl-tra}
+\fi
\endinput
diff --git a/tex/context/base/mkiv/math-ali.mkxl b/tex/context/base/mkiv/math-ali.mkxl
index 364760a0f..e5c693f98 100644
--- a/tex/context/base/mkiv/math-ali.mkxl
+++ b/tex/context/base/mkiv/math-ali.mkxl
@@ -1418,7 +1418,7 @@
\newdimen \d_strc_math_indent
\newconditional\c_strc_math_indent
-\let\d_strc_math_framed_width\displaywidth
+\newdimen\d_strc_math_framed_width
\setvalue{\??formulaoption\v!frame}%
{\edef\p_frame{\formulaparameter\c!frame}%
@@ -1459,18 +1459,14 @@
\fi}
\def\strc_math_flush_box_framed_common
- {\setformulaframedparameter\c!align{\formulaparameter\c!align}%
+ {\d_strc_math_framed_width\displaywidth
+ \setformulaframedparameter\c!align{\formulaparameter\c!align}%
\letformulaframedparameter\c!strut\v!no
\d_framed_formula\ht\b_strc_math_display
\ifcase\mathraggedstatus\or\hfill\or\hfill \fi
\inheritedformulaframedframed{\box\b_strc_math_display}%
\ifcase\mathraggedstatus\or \or\hfill\or\hfill\fi}
-% \def\strc_math_flush_box_framed_inline
-% {\letformulaframedparameter\c!location\empty
-% \letformulaframedparameter\c!width\displaywidth
-% \strc_math_flush_box_framed_common}
-
\def\strc_math_flush_box_framed_display
{\let\currentformulaframed\currentformula
\letformulaframedparameter\c!location\v!formula
@@ -1631,9 +1627,9 @@
\fi
% still ok?
\ifnum\mathraggedstatus=\plustwo
- \edef\d_strc_math_framed_width{\the\dimexpr\displaywidth-2\wd\b_strc_formulas_number\relax}%
+ \d_strc_math_framed_width\dimexpr\displaywidth-2\wd\b_strc_formulas_number\relax
\else
- \edef\d_strc_math_framed_width{\the\dimexpr\displaywidth-\wd\b_strc_formulas_number\relax}%
+ \d_strc_math_framed_width\dimexpr\displaywidth- \wd\b_strc_formulas_number\relax
\fi}
\let\strc_math_number_check_inside\strc_math_number_check_outside
diff --git a/tex/context/base/mkiv/math-fen.mkxl b/tex/context/base/mkiv/math-fen.mkxl
index 45a82e6c9..4d19fb210 100644
--- a/tex/context/base/mkiv/math-fen.mkxl
+++ b/tex/context/base/mkiv/math-fen.mkxl
@@ -223,7 +223,7 @@
{\advance\c_math_fenced_nesting\plusone
\begingroup
\edef\currentmathfence{#1}%
- \ifparameter#2\or\setupcurrentmathfence[#1]\fi
+ \ifparameter#2\or\setupcurrentmathfence[#2]\fi
\math_fenced_fenced_common
\edef\p_size{\mathfenceparameter\c!size}%
\ifempty\p_size
diff --git a/tex/context/base/mkiv/mlib-pps.mkxl b/tex/context/base/mkiv/mlib-pps.mkxl
new file mode 100644
index 000000000..6f6db4c14
--- /dev/null
+++ b/tex/context/base/mkiv/mlib-pps.mkxl
@@ -0,0 +1,215 @@
+%D \module
+%D [ file=mlib-pps,
+%D version=2008.03.25,
+%D title=\METAPOST\ Integrated Graphics,
+%D subtitle=Basics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: remove MPenvironment code
+
+\unprotect
+
+\registerctxluafile{mlib-pps}{}
+
+%D Todo: catch nested graphics like external figures with dummies.
+
+% todo: figure out why this is shifted
+%
+% \setupbodyfont[palatino]
+%
+% \starttext
+% \startMPpage
+% draw textext("123") ;
+% \stopMPpage
+% \stoptext
+%
+% A slightly larger picture works ok so maybe there is some kind
+% of interference with the page builder.
+
+\newbox \MPtextbox
+\newtoks\everyMPLIBsettext % not used
+
+\def\mlib_flush_environment
+ {%\writestatus\m!metapost{flushing environment}%
+ \clf_mptexget
+ \enforced\let\MPLIBflushenvironment\relax}% MPenvironments are depricated}
+
+\aliased\let\MPLIBflushenvironment\mlib_flush_environment
+
+\permanent\protected\def\MPLIBsetNtext#1% #2% box text
+ {\MPLIBflushenvironment
+ \dowithnextbox{\clf_mpsettext\nextbox #1}\hbox\bgroup % text
+ \meta_set_current_color
+ \enforced\let\MPLIBflushenvironment\mlib_flush_environment
+ \let\next} % gobble open brace
+
+\permanent\protected\def\MPLIBsetCtext#1#2% #3% box colorspec text
+ {\MPLIBflushenvironment
+ \dowithnextbox{\clf_mpsettext\nextbox #1}\hbox\bgroup % text
+ \directcolored[#2]%
+ \meta_set_current_color % so, textcolor wins !
+ \enforced\let\MPLIBflushenvironment\mlib_flush_environment
+ \let\next} % gobble open brace
+
+\aliased\let\MPLIBsettext\MPLIBsetNtext
+
+\permanent\protected\def\MPLIBsetNtextX#1% #2% box text
+ {\MPLIBflushenvironment
+ \hbox\bgroup % text
+ \meta_set_current_color
+ \enforced\let\MPLIBflushenvironment\mlib_flush_environment
+ \let\next}
+
+\permanent\protected\def\MPLIBsetCtextX#1#2% #3% box colorspec text
+ {\MPLIBflushenvironment
+ \hbox\bgroup % text
+ \directcolored[#2]%
+ \meta_set_current_color % so, textcolor wins !
+ \enforced\let\MPLIBflushenvironment\mlib_flush_environment
+ \let\next}
+
+\aliased\let\MPLIBsettextX\MPLIBsetNtextX
+
+\permanent\permanent\protected\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often
+ {\clf_mpgettext\MPtextbox #1%
+ \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=#2,\c!sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}}
+
+\permanent\protected\def\MPLIBfigure#1#2%
+ {\setbox\scratchbox\hpack{\externalfigure[#1][\c!mask=#2]}%
+ \clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint
+ \vpack to \zeropoint{\vss\hpack to \zeropoint{\fastsxsy{\sx}{\sy}{\box\scratchbox}\hss}}}
+
+% horrible (we could inline scale and matrix code):
+
+\permanent\protected\def\MPLIBgettextscaledcm#1#2#3#4#5#6#7#8#9% 2-7: sx,rx,ry,sy,tx,ty
+ {\clf_mpgettext\MPtextbox #1%
+ \setbox\MPbox\hpack\bgroup
+ \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% does push pop ... will be changed to proper lua call (avoid small numbers)
+ \vpack to \zeropoint\bgroup
+ \vss
+ \hpack to \zeropoint \bgroup
+ % \scale[\c!sx=#8,\c!sy=#9]{\raise\dp\MPtextbox\box\MPtextbox}%
+ % \scale[\c!sx=#8,\c!sy=#9,\c!depth=\v!no]{\box\MPtextbox}%
+ \fastsxsy{#8}{#9}{\raise\dp\MPtextbox\box\MPtextbox}%
+ % This gives: LuaTeX warning: Misplaced \pdfrestore .. don't ask me why.
+ % but I'll retry it some day soon.
+ % \dostartscaling{#8}{#9}%
+ % \raise\dp\MPtextbox\box\MPtextbox
+ % \dostopscaling
+ \forcecolorhack % can go away ... already in the scale macro
+ \hss
+ \egroup
+ \egroup
+ \egroup
+ \smashbox\MPbox
+ \box\MPbox}
+
+% \putnextboxincache{hans}{1}\hbox{foo}
+%
+% \startMPcode
+% draw boundingbox rawtexbox("hans",1) ;
+% draw rawtexbox("hans",1) ;
+% \stopMPcode
+
+\permanent\protected\def\MPLIBgetboxscaledcm#1#2%
+ {\begingroup
+ \copyboxfromcache{#1}{#2}\MPtextbox % can be \clf_
+ \mlib_get_box_scaled_cm_next}
+
+\protected\def\mlib_get_box_scaled_cm_next#1#2#3#4#5#6#7#8% 1-6: sx,rx,ry,sy,tx,ty
+ {\setbox\MPbox\hpack\bgroup
+ \dotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}%
+ \vpack to \zeropoint\bgroup
+ \vss
+ \hpack to \zeropoint \bgroup
+ \fastsxsy{#7}{#8}{\raise\dp\MPtextbox\box\MPtextbox}%
+ \hss
+ \egroup
+ \egroup
+ \egroup
+ \smashbox\MPbox
+ \box\MPbox
+ \endgroup}
+
+\permanent\protected\def\MPLIBgraphictext#1% use at mp end
+ {\startTEXpage[\c!scale=10000]#1\stopTEXpage}
+
+%D \startbuffer
+%D \definelayer[test]
+%D
+%D \setlayerframed
+%D [test]
+%D [x=\MPx{somepos-1},y=\MPy{somepos-1}]
+%D [width=\MPw{somepos-1},height=\MPh{somepos-1}]
+%D {Whatever we want here!}
+%D
+%D \setlayerframed
+%D [test]
+%D [x=\MPx{somepos-2},y=\MPy{somepos-2}]
+%D [width=\MPw{somepos-2},height=\MPh{somepos-2}]
+%D {Whatever we need there!}
+%D
+%D \startuseMPgraphic{oeps}
+%D draw fullcircle scaled 6cm withcolor red ;
+%D register ("somepos-1",5cm,1cm,center currentpicture) ;
+%D register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ;
+%D \stopuseMPgraphic
+%D
+%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}}
+%D \stopbuffer
+%D
+%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection
+
+\permanent\protected\def\MPLIBpositionwhd#1#2#3#4#5% bp !
+ {\dosavepositionwhd{#1}\zerocount{#2\onebasepoint}{#3\onebasepoint}{#4\onebasepoint}{#5\onebasepoint}\zeropoint}
+
+\def\mlib_stop_group#1#2#3#4#5#6% some day this might happen elsewhere
+ {\egroup
+ \setbox\scratchbox\hpack{\kern\onebasepoint\box\scratchbox}% weird correction
+ \wd\scratchbox \dimexpr#5\onebasepoint-#3\onebasepoint+2\onebasepoint\relax
+ \ht\scratchbox #6\onebasepoint
+ \dp\scratchbox-#4\onebasepoint
+ \setbox\scratchbox\hpack\bgroup
+ \kern-#3\onebasepoint
+ \box\scratchbox
+ \egroup
+ \saveboxresource
+ attr {/Group << /S /Transparency /I \ifnum#1=1 true \else false \fi /K \ifnum#2=1 true \else false \fi >>}
+ resources {\pdfbackendcurrentresources}
+ \scratchbox
+ \setbox\scratchbox\hpack\bgroup
+ \kern#3\onebasepoint
+ \kern-\onebasepoint
+ \useboxresource\lastsavedboxresourceindex
+ \egroup
+ \wd\scratchbox\zeropoint
+ \ht\scratchbox\zeropoint
+ \dp\scratchbox\zeropoint
+ \box\scratchbox
+ \endgroup}
+
+\aliased\let\MPLIBstopgroup\relax
+
+\permanent\protected\def\MPLIBstartgroup#1#2#3#4#5#6% isolated 0/1, knockout 0/1 llx lly urx ury
+ {\begingroup
+ \setbox\scratchbox\hpack\bgroup
+ \enforced\permanent\protected\def\MPLIBstopgroup{\mlib_stop_group{#1}{#2}{#3}{#4}{#5}{#6}}}
+
+% For now here ... will be cleaned up:
+
+\newtoks\mptexttoks
+\newbox \mptextbox
+\newtoks\mpoutlinetoks
+\newtoks\mpgraphictexttoks
+
+\mptexttoks {\global\setbox\mptextbox\hbox{\clf_mptexttoks}}
+\mpoutlinetoks {\global\setbox\mptextbox\vbox{\clf_mpoutlinetoks}}
+\mpgraphictexttoks{\global\setbox\mptextbox\vbox{\clf_mpgraphictexttoks}}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/mult-aux.mkxl b/tex/context/base/mkiv/mult-aux.mkxl
index 1b7a760cd..97ae12be1 100644
--- a/tex/context/base/mkiv/mult-aux.mkxl
+++ b/tex/context/base/mkiv/mult-aux.mkxl
@@ -319,7 +319,7 @@
\permanent\protected\def\installparameterhashhandler#1#2%
{\mutable\letcsname current#2\endcsname\empty
- \letcsname#2namespace\endcsname#1%
+ \immutable\letcsname#2namespace\endcsname#1%
\normalexpanded
{\mult_interfaces_install_parameter_hash_handler
{\noexpand#1}% \??aa
@@ -749,7 +749,7 @@
% yes:\twoparameter{beta}\par
\permanent\protected\def\relateparameterhandlers#1#2#3#4% {from} {instance} {to} {instance}
- {\edefcsname\csname#1namespace\endcsname#2:\s!parent\endcsname{\csname#3namespace\endcsname#4}}
+ {\immutable\edefcsname#1namespace\endcsname#2:\s!parent\endcsname{\csname#3namespace\endcsname#4}}
\permanent\protected\def\relateparameterhandlersbyns#1#2#3#4% {from} {instance} {to} {instance}
{\edefcsname#1#2:\s!parent\endcsname{#3#4}}
diff --git a/tex/context/base/mkiv/mult-def.mkxl b/tex/context/base/mkiv/mult-def.mkxl
new file mode 100644
index 000000000..13e22dade
--- /dev/null
+++ b/tex/context/base/mkiv/mult-def.mkxl
@@ -0,0 +1,32 @@
+%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 ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\installcorenamespace{multilingual}
+
+\immutable\setvalue{\??multilingual czech}{cs}
+\immutable\setvalue{\??multilingual german}{de}
+\immutable\setvalue{\??multilingual english}{en}
+\immutable\setvalue{\??multilingual french}{fr}
+\immutable\setvalue{\??multilingual italian}{it}
+\immutable\setvalue{\??multilingual dutch}{nl}
+\immutable\setvalue{\??multilingual persian}{pe}
+\immutable\setvalue{\??multilingual romanian}{ro}
+
+\permanent\def\userinterfacetag{\ifcsname\??multilingual\currentinterface\endcsname\lastnamedcs\else en\fi}
+\permanent\def\userresponsestag{\ifcsname\??multilingual\currentresponses\endcsname\lastnamedcs\else en\fi}
+
+\clf_setuserinterface{\userinterfacetag}{\userresponsestag}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/mult-dim.mklx b/tex/context/base/mkiv/mult-dim.mklx
new file mode 100644
index 000000000..0526b3775
--- /dev/null
+++ b/tex/context/base/mkiv/mult-dim.mklx
@@ -0,0 +1,156 @@
+%D \module
+%D [ file=core-gen,
+%D version=1995.10.10,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=General,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Core Macros / General}
+
+% we could write a proper parser now in lua
+
+\unprotect
+
+%D \macros
+%D {assigndimension,assignalfadimension}
+%D
+%D The following commands are used to process keyword based dimension setters.
+%D
+%D \starttyping
+%D \assigndimension
+%D {<value>|small|medium|big|-small|-medium|-big|none}
+%D {\dimension}
+%D {value small}
+%D {value medium}
+%D {value big}
+%D \stoptyping
+%D
+%D The given keyword determines the result.
+
+\installcorenamespace{dimensionnormal}
+
+\def\assign_dimension_direct#value#dimension#small#medium#big{#dimension=#value\relax}
+
+\immutable\setvalue{\??dimensionnormal \v!none }#value#dimension#small#medium#big{#dimension\zeropoint}
+\immutable\setvalue{\??dimensionnormal \empty }#value#dimension#small#medium#big{#dimension\zeropoint}
+\immutable\setvalue{\??dimensionnormal \v!small }#value#dimension#small#medium#big{#dimension=#small\relax}
+\immutable\setvalue{\??dimensionnormal \v!medium}#value#dimension#small#medium#big{#dimension=#medium\relax}
+\immutable\setvalue{\??dimensionnormal \v!big }#value#dimension#small#medium#big{#dimension=#big\relax}
+\immutable\setvalue{\??dimensionnormal-\v!small }#value#dimension#small#medium#big{#dimension=-#small\relax}
+\immutable\setvalue{\??dimensionnormal-\v!medium}#value#dimension#small#medium#big{#dimension=-#medium\relax}
+\immutable\setvalue{\??dimensionnormal-\v!big }#value#dimension#small#medium#big{#dimension=-#big\relax}
+\immutable\letvalue{\??dimensionnormal\s!unknown}\assign_dimension_direct
+
+\permanent\protected\def\assigndimension#value%
+ {\ifcsname\??dimensionnormal#value\endcsname
+ \expandafter\lastnamedcs
+ \else
+ \expandafter\assign_dimension_direct
+ \fi{#value}}
+
+%D The next variant assigns to a macro instead of a dimension.
+%D
+%D \starttyping
+%D \assignalfadimension
+%D {<value>|small|medium|big|none}
+%D {\macro}
+%D {value small}
+%D {value medium}
+%D {value big}
+%D \stoptyping
+%D
+%D This one is used for factors.
+
+\installcorenamespace{dimensionalfa}
+
+\def\assign_alpha_dimension_direct#value#macro#small#medium#big{\edef#macro{#value}}
+
+\immutable\setvalue{\??dimensionalfa\v!none }#value#macro#small#medium#big{\let #macro\!!zerocount}
+\immutable\setvalue{\??dimensionalfa\v!small }#value#macro#small#medium#big{\edef#macro{#small}}
+\immutable\setvalue{\??dimensionalfa\v!medium }#value#macro#small#medium#big{\edef#macro{#medium}}
+\immutable\setvalue{\??dimensionalfa\v!big }#value#macro#small#medium#big{\edef#macro{#big}}
+\immutable\letvalue{\??dimensionalfa\s!unknown}\assign_alpha_dimension_direct
+
+\permanent\protected\def\assignalfadimension#value%
+ {\ifcsname\??dimensionalfa#value\endcsname
+ \expandafter\lastnamedcs
+ \else
+ \expandafter\assign_alpha_dimension_direct
+ \fi
+ {#value}}
+
+%D \macros
+%D {assignvalue}
+%D
+%D A variant that does not assume dimenions ios the following:
+%D
+%D \starttyping
+%D \assignvalue
+%D {<value>|small|medium|big}
+%D {\macro}
+%D {value small}
+%D {value medium}
+%D {value big}
+%D \stoptyping
+
+\installcorenamespace{dimensionvalue}
+
+\def\assign_value_direct#value#macro#small#medium#big{\edef#macro{#value}}
+
+\immutable\setvalue{\??dimensionvalue\v!small }#value#macro#small#medium#big{\edef#macro{#small}}
+\immutable\setvalue{\??dimensionvalue\v!medium }#value#macro#small#medium#big{\edef#macro{#medium}}
+\immutable\setvalue{\??dimensionvalue\v!big }#value#macro#small#medium#big{\edef#macro{#big}}
+\immutable\letvalue{\??dimensionvalue\s!unknown}\assign_value_direct
+
+\permanent\protected\def\assignvalue#value%
+ {\ifcsname\??dimensionvalue#value\endcsname
+ \expandafter\lastnamedcs
+ \else
+ \expandafter\assign_value_direct
+ \fi{#value}}
+
+%D \macros
+%D {assignwidth}
+%D
+%D This one is used a few times.
+%D
+%D \starttyping
+%D \assignwidth
+%D {<value>|fit|broad}
+%D {\dimension}
+%D {text}
+%D {extra}
+%D \stoptyping
+
+\installcorenamespace{dimensionwidth}
+
+\newbox\b_assign_width
+
+\def\assign_width_direct#value#dimension#content#extra{#dimension=#value\relax}
+
+% line is like fit but can be used later as signal for ...
+
+\immutable\setvalue{\??dimensionwidth }#value#dimension#content#extra{\setbox\b_assign_width\hbox{#content}#dimension\wd\b_assign_width
+ \setbox\b_assign_width\emptybox}
+\immutable\setvalue{\??dimensionwidth\v!fit }#value#dimension#content#extra{\setbox\b_assign_width\hbox{#content}#dimension\wd\b_assign_width
+ \setbox\b_assign_width\emptybox}
+\immutable\setvalue{\??dimensionwidth\v!broad }#value#dimension#content#extra{\setbox\b_assign_width\hbox{#content}#dimension\dimexpr\wd\b_assign_width+#extra\relax
+ \setbox\b_assign_width\emptybox}
+\immutable\setvalue{\??dimensionwidth\v!line }#value#dimension#content#extra{\setbox\b_assign_width\hbox{#content}#dimension\wd\b_assign_width
+ \setbox\b_assign_width\emptybox}
+\immutable\letvalue{\??dimensionwidth\s!unknown}\assign_width_direct
+
+\permanent\protected\def\assignwidth#value%
+ {\ifcsname\??dimensionwidth#value\endcsname
+ \expandafter\lastnamedcs
+ \else
+ \expandafter\assign_width_direct
+ \fi{#value}}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 0efd5d30c..ab7e78e18 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -333,8 +333,9 @@ return {
-- "everyendpar",
--
"endgraf", "endpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf",
- "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage",
- "normalspace",
+ "obeyspaces", "obeylines", "obeytabs", "obeypages", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage",
+ "normalspace", "naturalspace", "controlspace", "normalspaces",
+ "ignoretabs", "ignorelines", "ignorepages", "ignoreeofs", "setcontrolspaces",
--
"executeifdefined",
--
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index e94eb7772..1ab4e6aba 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -264,6 +264,7 @@ return {
"crampedtextstyle",
"csstring",
"defcsname",
+ "dimensiondef",
"directlua",
"edefcsname",
"efcode",
diff --git a/tex/context/base/mkiv/mult-prm.mkxl b/tex/context/base/mkiv/mult-prm.mkxl
new file mode 100644
index 000000000..2ec763c39
--- /dev/null
+++ b/tex/context/base/mkiv/mult-prm.mkxl
@@ -0,0 +1,117 @@
+%D \module
+%D [ file=mult-prm,
+%D version=2011.09.18, % actually older
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Primitives,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is therefore
+%C copyrighted by \PRAGMA. See mreadme.pdf for details.
+
+%D This file is only a helper for generating files that can be used in an
+%D editor for syntax highlighting.
+
+% local all = table.load("mult-prm.lua")
+% local tex = table.tohash(all.tex)
+% for k, v in next, all do
+% if k ~= "tex" then
+% local h = table.tohash(v)
+% for k, v in next, h do
+% tex[k] = nil
+% end
+% all[k] = table.sortedkeys(h)
+% end
+% end
+% all.tex = table.sortedkeys(tex)
+% print((string.gsub(table.serialize(all,true),' "','\n "')))
+
+\startluacode
+
+ context.starttext()
+
+ local missing = {
+ tex = {
+ -- todo: differenced between luatex and luametatex
+ },
+ etex = {
+ -- todo: differenced between luatex and luametatex
+ },
+ luatex = {
+ -- todo: differenced between luatex and luametatex
+ },
+ pdftex = { -- maybe not complete
+ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing",
+ "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit",
+ "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate",
+ "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode",
+ "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink",
+ "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand",
+ "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma",
+ "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin",
+ "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename",
+ "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor",
+ "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts",
+ "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate",
+ "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink",
+ "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages",
+ "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral",
+ "pdfmapfile", "pdfmapline", "pdfmajorversion", "pdfminorversion", "pdfnames",
+ "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfrecompress",
+ "pdfobjcompresslevel", "pdfoutline", "pdfoutput", "pdfpageattr",
+ "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources",
+ "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode",
+ "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen",
+ "pdfrandomseed", "pdfrefobj", "pdfrefxform", "pdfrefximage",
+ "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos",
+ "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread",
+ "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner",
+ "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin",
+ "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate",
+ "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr",
+ "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage",
+ "pdfomitcidset", "pdfomitcharset",
+ },
+ aleph = { -- we don't bother
+ "Alephminorversion", "Alephrevision", "Alephversion",
+ },
+ omega = { -- we don't bother
+ "Omegaminorversion", "Omegarevision", "Omegaversion",
+ },
+ xetex = { -- we don't bother
+ "XeTeXversion",
+ },
+ -- plain = {
+ -- "TeX",
+ -- "bgroup", "egroup", "endgraf", "space", "empty", "null",
+ -- "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newhelp", "newread", "newwrite", "newfam", "newlanguage", "newinsert", "newif",
+ -- "maxdimen", "magstephalf", "magstep",
+ -- "frenchspacing", "nonfrenchspacing", "normalbaselines", "obeylines", "obeyspaces", "raggedright", "ttraggedright",
+ -- "thinspace", "negthinspace", "enspace", "enskip", "quad", "qquad",
+ -- "smallskip", "medskip", "bigskip", "removelastskip", "topglue", "vglue", "hglue",
+ -- "break", "nobreak", "allowbreak", "filbreak", "goodbreak", "smallbreak", "medbreak", "bigbreak",
+ -- "line", "leftline", "rightline", "centerline", "rlap", "llap", "underbar", "strutbox", "strut",
+ -- "cases", "matrix", "pmatrix", "bordermatrix", "eqalign", "displaylines", "eqalignno", "leqalignno",
+ -- "pageno", "folio", "tracingall", "showhyphens", "fmtname", "fmtversion",
+ -- "hphantom", "vphantom", "phantom", "smash",
+ -- },
+ }
+
+ local primitives = {
+ tex = table.sorted( table.merged( missing.tex , tex.extraprimitives("core","tex") ) ),
+ etex = table.sorted( table.merged( missing.etex , tex.extraprimitives("etex") ) ),
+ pdftex = table.sorted( table.merged( missing.pdftex, { } ) ),
+ luatex = table.sorted( table.merged( missing.luatex, tex.extraprimitives("luatex") ) ),
+ aleph = table.sorted( table.merged( missing.aleph , { } ) ),
+ omega = table.sorted( table.merged( missing.omega , { } ) ),
+ xetex = table.sorted( table.merged( missing.xetex , { } ) ),
+ }
+
+ -- table.remove(primitives.tex,1) -- get rid of \-
+
+ io.savedata("mult-prm.lua",table.serialize(primitives,true,{ reduce = true, inline = false }))
+
+ context.stoptext()
+
+\stopluacode
diff --git a/tex/context/base/mkiv/mult-sys.mkxl b/tex/context/base/mkiv/mult-sys.mkxl
index 40fcb9c35..b782e9db4 100644
--- a/tex/context/base/mkiv/mult-sys.mkxl
+++ b/tex/context/base/mkiv/mult-sys.mkxl
@@ -91,6 +91,12 @@
\definesystemconstant {usenglish} \definesystemconstant {us}
\definesystemconstant {vietnamese} \definesystemconstant {vi}
+%D Left|-|overs:
+
+\defineinterfaceconstant {HL} {HL}
+\defineinterfaceconstant {VL} {VL}
+\defineinterfaceconstant {NL} {NL}
+
%D For proper \UNICODE\ support we need a few font related constants.
\definesystemconstant {action}
diff --git a/tex/context/base/mkiv/publ-inc.mkxl b/tex/context/base/mkiv/publ-inc.mkxl
new file mode 100644
index 000000000..8e6cd2bdf
--- /dev/null
+++ b/tex/context/base/mkiv/publ-inc.mkxl
@@ -0,0 +1,63 @@
+%D \module
+%D [ file=publ-inc,
+%D version=2018.06.23,
+%D title=\CONTEXT\ Publication Macros,
+%D subtitle=XML inclusion,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Publication Macros / XML inclusion}
+
+\registerctxluafile{publ-inc}{}
+
+%D A teaser for Alan.
+
+\unprotect
+
+\definesymbol[btxattachment][{\infofont\darkred btx}]
+\definesymbol[btxcomment] [{\infofont\darkblue btx}]
+
+\protected\def\btx_add_blob#1#2%
+ {\relax
+ \clf_btxentrytobuffer{\currentbtxdataset}{\currentbtxtag}{temp-btx-export}%
+ #2%
+ [\c!symbol=#1,%
+ \c!space=\v!yes,
+ \c!buffer=temp-btx-export,%
+ \c!name={\currentbtxtag.bib}]%
+ \relax}
+
+\permanent\protected\def\btxattach
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \btx_add_blob{btxattachment}\attachment
+ \dostoptagged
+ \fi \fi \fi}
+
+\permanent\protected\def\btxcomment
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \btx_add_blob{btxcomment}\comment
+ \dostoptagged
+ \fi \fi \fi}
+
+%D This kind of feature creep is not yet configurable, nor documented.
+
+\permanent\protected\def\btxaddsource
+ {\iftrialtypesetting \else \ifexporting \iflocation
+ \dostarttagged\t!ignore\empty
+ \llap{%
+ \btx_add_blob{btxattachment}\attachment
+ \quad
+ \btx_add_blob{btxcomment}\comment
+ \hskip\leftmargindistance
+ }%
+ \dostoptagged
+ \fi \fi \fi}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/publ-ini.mkxl b/tex/context/base/mkiv/publ-ini.mkxl
new file mode 100644
index 000000000..47d82afaf
--- /dev/null
+++ b/tex/context/base/mkiv/publ-ini.mkxl
@@ -0,0 +1,2018 @@
+%D \module
+%D [ file=publ-ini,
+%D version=2013.05.12,
+%D title=\CONTEXT\ Publication Support,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% TODO: some clf_ can be public implementers instead
+
+% TODO: s! vs v! for default and neutral key/values
+% todo: too many refs in list
+
+% TODO A.-B. Foo (dash as connector, see JMH)
+
+% todo: no need for all these %'s
+
+% todo: tagging
+% todo: we cannot use 'default' as this wipes metadata names (maybe no longer do that)
+% todo: \v!cite => \s!cite
+% todo: interface with (ml)bibtex (export -> call -> import)
+% todo: check if 'all' etc are ok ... either use list or use other criterium
+% todo: \the\everysetupbtxciteplacement probably too often
+
+% \definecolor[btx:field] [darkred]
+% \definecolor[btx:crossref][darkblue]
+% \definecolor[btx:key] [darkgreen]
+% \definecolor[btx:todo] [darkyellow]
+
+%D We operate on several axis:
+%D
+%D \startitemize[packed]
+%D \startitem we can have several databases (or combinations) \stopitem
+%D \startitem we can add entries to them if needed (coded in tex) \stopitem
+%D \startitem we can have several lists each using one of the databases \stopitem
+%D \startitem we can render each list or citation independently \stopitem
+%D \stopitemize
+%D
+%D We assume that the rendering of a list entry is consistent in a document,
+%D although one can redefine properties if needed. Adding more granularity would
+%D complicate the user interface beyond comprehension.
+
+\writestatus{loading}{ConTeXt Publication Support / Initialization}
+
+\registerctxluafile{publ-dat}{}
+\registerctxluafile{publ-ini}{}
+\registerctxluafile{publ-sor}{}
+\registerctxluafile{publ-aut}{}
+\registerctxluafile{publ-usr}{}
+\registerctxluafile{publ-oth}{} % this could become an option
+\registerctxluafile{publ-fnd}{} % new method (for the moment only local)
+\registerctxluafile{publ-jrn}{}
+\registerctxluafile{publ-reg}{}
+
+\unprotect
+
+\startcontextdefinitioncode
+
+%D These are currently not interfaced.
+
+\definesystemconstant {btx}
+
+\definesystemconstant {btxset}
+\definesystemconstant {btxref}
+\definesystemconstant {btxint}
+\definesystemconstant {btxltx}
+\definesystemconstant {btxrtx}
+\definesystemconstant {btxatx}
+\definesystemconstant {btxbtx}
+\definesystemconstant {btxspc}
+\definesystemconstant {btxlst}
+\definesystemconstant {btxcom}
+
+\defineinterfacevariable {btxcite} {btxcite}
+\defineinterfacevariable {btxlist} {btxlist}
+\defineinterfacevariable {btxrendering} {btxrendering}
+
+\definelabelclass[btxlabel][2]
+
+\clf_definelabels{btxlabel}{btx}\s!false\relax
+
+% It is not that trivial to come up with a proper organization of setup
+% and control commands for publications. This is because we have complex
+% inline as well as extensive list rendering. The rules are partially
+% driven by somewhat archaic bibtex specifications and evolving journal
+% (or field) specific demands. The logic in the standards is often so
+% complex that it looks like manual rendering is assumed. But, we want to
+% automate the process as much as possible.
+%
+% Another complication is that in manuals we want to demonstrate different
+% properties of the implementation and therefore we need a way to handle
+% independent standards, databases, etc. This has resulted in the following
+% organization:
+%
+% - general setup (rather minimal)
+% - list setup (rendering)
+% - cite setup
+% - dataset setup
+%
+% The rendering is mostly driven by setups. In there we can call for fields
+% in the database but also for virtual fields or combinations.
+
+% The main rendering style (standard driven).
+
+%D We assume that a specification is global or used grouped. It doesn't make much sense
+%D to split between cite and list here as it only complicates matters (timing) and is
+%D not clear either.
+
+\let\currentbtxspecification \empty
+\let\currentbtxspecificationfallback\empty
+
+\installmacrostack\currentbtxspecification
+\installmacrostack\currentbtxspecificationfallback
+
+\permanent\protected\def\startbtxrenderingdefinitions[#1]%
+ {\unprotect
+ \push_macro_currentbtxspecification
+ \edef\currentbtxspecification{#1}}
+
+\permanent\protected\def\stopbtxrenderingdefinitions
+ {\pop_macro_currentbtxspecification
+ \protect}
+
+\permanent\protected\def\loadfoundpublicationfile#1#2% name foundname / not a user command
+ {\input{#2}}
+
+\permanent\protected\def\loadbtxdefinitionfile [#1]{\clf_btxloaddefinitionfile {#1}} % can be public implementer
+\permanent\protected\def\loadbtxreplacementfile[#1]{\clf_btxloadreplacementfile{#1}} % can be public implementer
+
+\protected\def\publ_specification_push#1%
+ {\push_macro_currentbtxspecification
+ \push_macro_currentbtxspecificationfallback
+ \edef\currentbtxspecification{#1}%
+ \edef\currentbtxspecificationfallback{\namedbtxparameter\currentbtxspecification\c!default}%
+ \ifx\currentbtxspecificationfallback\currentbtxspecification
+ \let\currentbtxspecificationfallback\empty
+ \fi
+ \clf_btxsetspecification{\currentbtxspecification}}
+
+\protected\def\publ_specification_pop
+ {\pop_macro_currentbtxspecificationfallback
+ \pop_macro_currentbtxspecification
+ \clf_btxsetspecification{\currentbtxspecification}}
+
+\protected\def\publ_specification_set#1% beware: is global
+ {\edef\currentbtxspecification{#1}%
+ \edef\currentbtxspecificationfallback{\namedbtxparameter\currentbtxspecification\c!default}%
+ \ifx\currentbtxspecificationfallback\currentbtxspecification
+ \let\currentbtxspecificationfallback\empty
+ \fi
+ % has to be done explicitly: \loadbtxdefinitionfile[\currentbtxspecification]%
+ \ifempty\currentbtxspecification
+ % we set default at the end
+ \else
+ \clf_btxsetspecification{\currentbtxspecification}%
+ \fi}% todo: ,true == also load
+
+\installcorenamespace {btx}
+
+\installswitchcommandhandler \??btx {btx} \??btx
+
+% because we have lots of setups we provide a checker for sloppy users
+
+\protected\def\btx_check_chain#1#2#3%
+ {\doifelsesomething{#3}
+ {\writestatus{btx #1}{defining\space"#2"\space as\space descendant\space of\space"#3"}% we're in definition regime (no space)
+ \definebtx[#2][#3]}
+ {\writestatus{btx #1}{defining\space"#2"}%
+ \definebtx[#2]}}
+
+% \protected\def\btxcheckdefine#1#2{\doifelsecommandhandler\??btx{#1}\donothing{\btx_check_chain{define}{#1}{#2}}}
+% \protected\def\btxchecksetup #1#2{\doifelsecommandhandler\??btx{#1}\donothing{\btx_check_chain {setup}{#1}{#2}}}
+
+\permanent\protected\def\btxcheckdefine#1{\doifelsecommandhandler\??btx{#1}\gobbleoneargument{\btx_check_chain{define}{#1}}} % {#2}
+\permanent\protected\def\btxchecksetup #1{\doifelsecommandhandler\??btx{#1}\gobbleoneargument{\btx_check_chain {setup}{#1}}} % {#2}
+
+% for the moment experimental:
+
+\permanent\protected\def\btxenableautodefine
+ {\prependtoks
+ \clf_checkinterfacechain{\currentbtx}{btxcheckdefine}%
+ \to \everydefinebtx
+ \prependtoks
+ \ifnum\btxsetupmode=\doingrootsetupnamed
+ \clf_checkinterfacechain{\currentbtx}{btxchecksetup}%
+ \fi
+ \to \everysetupbtx
+ \let\btxenableautodefine\relax}
+
+\appendtoks
+ \ifnum\btxsetupmode=\doingrootsetuproot
+ \publ_specification_set{\btxparameter\c!specification}%
+ \orelse\ifnum\btxsetupmode=\doingrootsetupnamed
+ \doifelsecommandhandler\??btx\currentbtx
+ {\publ_specification_set{\btxparameter\c!specification}}%
+ {}% maybe a warning
+ \fi
+\to \everysetupbtx
+
+\appendtoks
+ \ifnum\btxsetupmode=\doingrootsetuproot
+ \edef\currentbtxdataset{\clf_btxsetdataset{\btxparameter\c!dataset}{\currentbtxdataset}}%
+ \fi
+\to \everysetupbtx
+
+\appendtoks
+ \publ_specification_set{\btxparameter\c!specification}%
+\to \everyjob
+
+\protected\def\startusingbtxspecification[#1]%
+ {\publ_specification_push{#1}}
+
+\let\stopusingbtxspecification\publ_specification_pop
+
+% \setupbtxlist[alternative=paragraph,width=auto,distance=\emwidth]
+% \setupbtxlist[alternative=paragraph,width=auto,distance=\emwidth,margin=2em] % useless
+% \setupbtxlist[alternative=paragraph,width=fit,distance=\emwidth]
+% \setupbtxlist[alternative=paragraph,width=fit,distance=\emwidth,margin=2em]
+
+% here starts the bib stuff
+
+\installcorenamespace {btxdataset}
+\installcorenamespace {btxrendering}
+\installcorenamespace {btxregister}
+\installcorenamespace {btxcommand}
+\installcorenamespace {btxrenderingdefinition}
+
+\installcommandhandler \??btxdataset {btxdataset} \??btxdataset
+\installcommandhandler \??btxregister {btxregister} \??btxregister
+\installcommandhandler \??btxrendering {btxrendering} \??btxrendering
+
+\permanent\protected\def\setbtxparameterset#1#2%
+ {\edef\currentbtx
+ {\ifcsname\??btx\currentbtxspecification:#1:#2:\s!parent\endcsname
+ \currentbtxspecification:%
+ \orelse\ifempty\currentbtxspecificationfallback
+ \orelse\ifcsname\??btx\currentbtxspecificationfallback:#1:#2:\s!parent\endcsname
+ \currentbtxspecificationfallback:%
+ \fi#1:#2}}
+
+\permanent\protected\def\setbtxparametersetroot#1%
+ {\edef\currentbtx
+ {\ifcsname\??btx\currentbtxspecification:#1:\s!parent\endcsname
+ \currentbtxspecification:#1%
+ \orelse\ifempty\currentbtxspecificationfallback
+ \orelse\ifcsname\??btx\currentbtxspecificationfallback:#1:\s!parent\endcsname
+ \currentbtxspecificationfallback:#1%
+ \fi}}
+
+\permanent\protected\def\setbtxrendering
+ {\edef\currentbtxrendering
+ {\ifcsname\??btx\currentbtxspecification:\s!parent\endcsname
+ \currentbtxspecification
+ \orelse\ifempty\currentbtxspecificationfallback
+ \orelse\ifcsname\??btx\currentbtxspecificationfallback:\s!parent\endcsname
+ \currentbtxspecificationfallback
+ \fi}}
+
+\permanent\protected\def\setbtxlist % maybe simplify this one, always list=rendering?
+ {\edef\currentbtxlist
+ {\ifcsname\??btx\currentbtxrendering:\s!parent\endcsname
+ \currentbtxrendering
+ \orelse\ifcsname\??btx\currentbtxspecification:\s!parent\endcsname
+ \currentbtxspecification
+ \orelse\ifempty\currentbtxspecificationfallback
+ \orelse\ifcsname\??btx\currentbtxspecificationfallback:\s!parent\endcsname
+ \currentbtxspecificationfallback
+ \fi}%
+ \edef\currentlist{\s!btx:\currentbtxlist}}
+
+\permanent\protected\def\usebtxdataset
+ {\begingroup
+ \dotripleempty\publ_use_dataset}
+
+\def\publ_use_dataset[#1][#2][#3]%
+ {\getdummyparameters[\c!specification=\currentbtxspecification,#3]%
+ \ifsecondargument
+ \clf_btxusedataset
+ specification {\dummyparameter\c!specification}%
+ dataset {#1}%
+ filename {#2}%
+ \relax
+ \orelse\iffirstargument
+ \clf_btxusedataset
+ specification {\dummyparameter\c!specification}%
+ dataset {\v!default}%
+ filename {#1}%
+ \relax
+ \fi
+ \endgroup}
+
+\definebtxdataset
+ [\v!default]
+% [\c!language=] % nothing set so use current
+
+% \usebtxdataset
+% [default]
+% [mybibs.bib]
+
+%D These can be overloaded in the traditional module so we go \type {\frozen}
+%D instead of \type {\permanent}.
+
+\frozen\let\stoppublication\relax
+
+\frozen\tolerant\protected\def\startpublication[#1]#*[#2]%
+ {\begingroup
+ \catcode\commentasciicode\othercatcode
+ \ifparameters
+ \expandafter\publ_set_publication_default
+ \or
+ \expandafter\publ_set_publication_checked
+ \or
+ \expandafter\publ_set_publication_indeed
+ \fi{#1}{#2}}
+
+\def\publ_set_publication_default#1#2%
+ {\publ_set_publication_indeed\v!default{#1}}
+
+\def\publ_set_publication_checked#1#2%
+ {\doifelseassignment{#1}
+ {\publ_set_publication_indeed\v!default{#1}}
+ {\publ_set_publication_indeed{#1}{}}}
+
+\def\publ_set_publication_indeed#1#2#3\stoppublication
+ {\clf_btxaddentry{#1}{#2}{\detokenize{#3}}%
+ \endgroup
+ \ignorespaces}
+
+% commands
+
+\permanent\protected\def\btxcommand#1%
+ {\ifcsname\??btxcommand#1\endcsname
+ \expandafter\publ_command_yes
+ \else
+ \expandafter\publ_command_nop
+ \fi{#1}}
+
+\newtoks\t_btx_cmd
+\newbox \b_btx_cmd
+
+\t_btx_cmd{\global\setbox\b_btx_cmd\hpack{\clf_btxcmdstring}}
+
+\aliased\let\btxcmd\btxcommand
+
+\def\publ_command_yes#1%
+ {\csname\??btxcommand#1\endcsname}
+
+\def\publ_command_nop#1%
+ {\ifcsname#1\endcsname
+ \showmessage\m!publications{10}{#1,#1}%
+ \global\letcsname\??btxcommand#1\expandafter\endcsname\csname#1\endcsname
+ \orelse\ifcsname\utfupper{#1}\endcsname
+ \showmessage\m!publications{10}{#1}{\utfupper{#1}}%
+ \global\letcsname\??btxcommand#1\expandafter\endcsname\csname\utfupper{#1}\endcsname
+ \else
+ \showmessage\m!publications{11}{#1}%
+ \setugvalue{\??btxcommand#1}{\underbar{\tttf#1}}%
+ \fi
+ \publ_command_yes{#1}}
+
+\permanent\protected\def\definebtxcommand#1% {body} #1..#n{body}
+ {\setuvalue{\??btxcommand\csstring#1}}%
+
+% access
+
+\let\currentbtxtag \empty
+\let\currentbtxdataset\v!default
+
+\permanent\protected\def\setbtxentry[#1]% or maybe btxsetentry
+ {\edef\currentbtxtag{\clf_btxsetentry{\currentbtxdataset}{#1}}}
+
+% \let\btxsetdataset\setbtxdataset
+% \let\btxsetentry \setbtxentry
+
+% todo: no need for the currents as we can keep them at the lua end so we will have
+%
+% \btxfield : current
+% \btxspecificfield : dataset,tag,key
+
+% todo we can pick up the current's at the lua end (implementers)
+
+%permanent\def\btxfield #1{\clf_btxfield {\currentbtxdataset}{\currentbtxtag}{#1}}
+%permanent\def\btxdetail #1{\clf_btxdetail {\currentbtxdataset}{\currentbtxtag}{#1}}
+%permanent\def\btxflush #1{\clf_btxflush {\currentbtxdataset}{\currentbtxtag}{#1}}
+%permanent\def\btxdirect #1{\clf_btxdirect {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxfieldname #1{\clf_btxfieldname {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxfieldtype #1{\clf_btxfieldtype {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxfoundname #1{\clf_btxfoundname {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxfoundtype #1{\clf_btxfoundtype {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxauthorfield#1{\clf_btxauthorfield \currentbtxauthorindex{#1}}
+\permanent\def\btxdoifelse #1{\clf_btxdoifelse {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxdoif #1{\clf_btxdoif {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\def\btxdoifnot #1{\clf_btxdoifnot {\currentbtxdataset}{\currentbtxtag}{#1}}
+
+\aliased\let\btxsetup\fastsetup
+
+\permanent\def\btxfield #1{\dostarttagged\t!pubfld{#1}\clf_btxfield {\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+\permanent\def\btxdetail #1{\dostarttagged\t!pubfld{#1}\clf_btxdetail{\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+\permanent\def\btxflush #1{\dostarttagged\t!pubfld{#1}\clf_btxflush {\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+\permanent\def\btxdirect #1{\dostarttagged\t!pubfld{#1}\clf_btxdirect{\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged}
+%permanent\def\btxauthorfield#1{\dostarttagged\t!pubfld{#1}\clf_btxauthorfield \currentbtxauthorindex{#1}\dostoptagged}
+
+%D How complex will we go? Can we assume that e.g. an apa style will not be mixed
+%D with another one? I think this assumption is okay. For manuals we might want to
+%D mix but we can work around it.
+
+%D Rendering.
+
+\permanent\protected\def\btxspace {\removeunwantedspaces\space}
+\permanent\protected\def\btxnobreakspace {\removeunwantedspaces\nobreakspace} % these two are
+\permanent\protected\def\btxnbsp {\removeunwantedspaces\nbsp} % the same anyway
+\permanent\protected\def\btxperiod {\removeunwantedspaces.\space}
+\permanent\protected\def\btxcomma {\removeunwantedspaces,\space}
+\permanent\protected\def\btxcommabreak {\removeunwantedspaces,\hskip\zeropoint plus .5\emwidth\relax}
+\permanent\protected\def\btxcolon {\removeunwantedspaces:\space}
+\permanent\protected\def\btxsemicolon {\removeunwantedspaces;\space}
+\permanent\protected\def\btxlparent {\removeunwantedspaces\space(} % obsolete
+\permanent\protected\def\btxrparent {\removeunwantedspaces)\space} % obsolete
+\permanent\protected\def\btxleftparenthesis {\removeunwantedspaces\space(}
+\permanent\protected\def\btxrightparenthesis {\removeunwantedspaces)\space}
+\permanent\protected\def\btxrightparenthesisperiod{\removeunwantedspaces).\space}
+\permanent\protected\def\btxrightparenthesiscomma {\removeunwantedspaces),\space}
+\permanent\protected\def\btxleftbracket {\removeunwantedspaces\space[}
+\permanent\protected\def\btxrightbracket {\removeunwantedspaces]\space}
+\permanent\protected\def\btxrightbracketperiod {\removeunwantedspaces].\space}
+\permanent\protected\def\btxrightbracketcomma {\removeunwantedspaces],\space}
+
+%D Variables:
+
+\let\currentbtxbacklink \empty \permanent\protected\def\btxsetbacklink {\def\currentbtxbacklink}
+\let\currentbtxcategory \empty \permanent\protected\def\btxsetcategory {\def\currentbtxcategory}
+\let\currentbtxcombis \empty \permanent\protected\def\btxsetcombis {\def\currentbtxcombis}
+\let\currentbtxdataset \empty \permanent\protected\def\btxsetdataset {\def\currentbtxdataset}
+\let\currentbtxfirst \empty \permanent\protected\def\btxsetfirst {\def\currentbtxfirst}
+\let\currentbtxsecond \empty \permanent\protected\def\btxsetsecond {\def\currentbtxsecond}
+\let\currentbtxsuffix \empty \permanent\protected\def\btxsetsuffix {\def\currentbtxsuffix}
+\let\currentbtxinternal \empty \permanent\protected\def\btxsetinternal {\def\currentbtxinternal}
+\let\currentbtxlefttext \empty \permanent\protected\def\btxsetlefttext {\def\currentbtxlefttext}
+\let\currentbtxrighttext \empty \permanent\protected\def\btxsetrighttext {\def\currentbtxrighttext}
+\let\currentbtxbefore \empty \permanent\protected\def\btxsetbefore {\def\currentbtxbefore}
+\let\currentbtxafter \empty \permanent\protected\def\btxsetafter {\def\currentbtxafter}
+\let\currentbtxlanguage \empty \permanent\protected\def\btxsetlanguage {\def\currentbtxlanguage}
+\let\currentbtxtag \empty \permanent\protected\def\btxsettag {\def\currentbtxtag}
+\let\currentbtxnumber \empty \permanent\protected\def\btxsetnumber {\def\currentbtxnumber}
+\let\currentbtxfirstinternal\empty \permanent\protected\def\btxsetfirstinternal{\def\currentbtxfirstinternal}
+\let\currentbtxlastinternal \empty \permanent\protected\def\btxsetlastinternal {\def\currentbtxlastinternal}
+
+\let\currentbtxauthorvariant\v!normal \permanent\protected\def\btxsetauthorvariant{\def\currentbtxauthorvariant}
+\let\currentbtxfirstnames \empty \permanent\protected\def\btxsetfirstnames {\let\currentbtxfirstnames\currentbtxfirstnames_indeed}
+\let\currentbtxinitials \empty \permanent\protected\def\btxsetinitials {\let\currentbtxinitials \currentbtxinitials_indeed }
+\let\currentbtxjuniors \empty \permanent\protected\def\btxsetjuniors {\let\currentbtxjuniors \currentbtxjuniors_indeed }
+\let\currentbtxsurnames \empty \permanent\protected\def\btxsetsurnames {\let\currentbtxsurnames \currentbtxsurnames_indeed }
+\let\currentbtxvons \empty \permanent\protected\def\btxsetvons {\let\currentbtxvons \currentbtxvons_indeed }
+
+\newconstant\currentbtxoverflow \permanent\protected\def\btxsetoverflow #1{\currentbtxoverflow #1\relax}
+\newconstant\currentbtxconcat \permanent\protected\def\btxsetconcat #1{\currentbtxconcat #1\relax}
+\newconstant\currentbtxcount \permanent\protected\def\btxsetcount #1{\currentbtxcount #1\relax}
+\newconstant\currentbtxauthorindex %permanent\protected\def\btxsetauthorindex#1{\currentbtxauthorindex#1\relax} % passed directly
+\newconstant\currentbtxauthorcount %permanent\protected\def\btxsetauthorcount#1{\currentbtxauthorcount#1\relax} % passed directly
+\newconstant\currentbtxauthorstate \permanent\protected\def\btxsetauthorstate#1{\currentbtxauthorstate#1\relax}
+
+\protected\def\currentbtxfirstnames_indeed{\clf_btxcurrentfirstnames\numexpr\currentbtxauthorindex\relax}
+\protected\def\currentbtxinitials_indeed {\clf_btxcurrentinitials \numexpr\currentbtxauthorindex\relax}
+\protected\def\currentbtxjuniors_indeed {\clf_btxcurrentjuniors \numexpr\currentbtxauthorindex\relax}
+\protected\def\currentbtxsurnames_indeed {\clf_btxcurrentsurnames \numexpr\currentbtxauthorindex\relax}
+\protected\def\currentbtxvons_indeed {\clf_btxcurrentvons \numexpr\currentbtxauthorindex\relax}
+
+\let\currentbtxfirstpage \empty \permanent\protected\def\btxsetfirstpage#1{\def\currentbtxfirstpage{\btx_page_number{#1}}}
+\let\currentbtxlastpage \empty \permanent\protected\def\btxsetlastpage #1{\def\currentbtxlastpage {\btx_page_number{#1}}}
+
+\def\currentbtxauthorvariant{normal}
+
+\protected\def\btx_reset_list % not needed as we're grouped
+ {\let\currentbtxcombis \empty
+ \let\currentbtxcategory \empty
+ \let\currentbtxinternal \empty
+ \let\currentbtxlefttext \empty
+ \let\currentbtxrighttext\empty
+ \let\currentbtxbefore \empty
+ \let\currentbtxafter \empty
+ \let\currentbtxbacklink \empty
+ \let\currentbtxlanguage \empty
+ \let\currentbtxsuffix \empty
+ %\let\currentbtxdataset \empty % will always be set
+ %\let\currentbtxtag \empty % will always be set
+ \let\currentbtxnumber \empty}
+
+\protected\def\btx_reset_cite % check for less .. not all resets needed when we're grouped (only subcites)
+ {\let \currentbtxfirst \empty
+ \let \currentbtxsecond \empty
+ \let \currentbtxsuffix \empty
+ \let \currentbtxinternal \empty
+ \let \currentbtxlefttext \empty
+ \let \currentbtxrighttext \empty
+ \let \currentbtxbefore \empty
+ \let \currentbtxafter \empty
+ \let \currentbtxbacklink \empty
+ \let \currentbtxlanguage \empty
+ %\let \currentbtxdataset \empty % will always be set, beware of local reset ~
+ %\let \currentbtxtag \empty % will always be set, beware of local reset ~
+ \let \currentbtxnumber \empty
+ \setconstant\currentbtxoverflow \zerocount
+ \setconstant\currentbtxconcat \zerocount
+ \setconstant\currentbtxcount \zerocount}
+
+\protected\def\btx_reset_page % probably not needed
+ {\let \currentbtxfirstpage \empty
+ \let \currentbtxlastpage \empty
+ \let \currentbtxfirstinternal\empty
+ \let \currentbtxlastinternal \empty
+ \setconstant\currentbtxoverflow \zerocount
+ \setconstant\currentbtxconcat \zerocount
+ \setconstant\currentbtxcount \zerocount}
+
+\protected\def\btx_reset_numbering % probably not needed
+ {\let \currentbtxfirst \empty
+ \let \currentbtxsecond\empty
+ \let \currentbtxsuffix\empty
+ \setconstant\currentbtxconcat\zerocount}
+
+%D Pages:
+
+\protected\def\btx_page_number#1%
+ {\def\currentlistindex{#1}%
+ \structurelistpagenumber}
+
+%D Language:
+
+\def\mainbtxlanguage{\currentmainlanguage}
+
+\protected\def\btx_check_language
+ {\let\mainbtxlanguage\currentlanguage
+ \ifempty\currentbtxlanguage
+ \let\currentbtxlanguage\currentlanguage
+ \else
+ \btx_check_language_indeed
+ \fi}
+
+\protected\def\btx_check_language_indeed
+ {\edef\currentbtxlanguage{\reallanguagetag\currentbtxlanguage}%
+ \ifempty\currentbtxlanguage
+ \let\currentbtxlanguage\currentlanguage
+ \orelse\ifx\currentbtxlanguage\currentlanguage\else
+ \setcurrentlanguage\currentmainlanguage\currentbtxlanguage
+ \fi}
+
+%D Tracing
+
+\newconditional\c_btx_trace % not used yet
+
+\installtextracker
+ {btxrendering}
+ {\settrue \c_btx_trace}
+ {\setfalse\c_btx_trace}
+
+%D Rendering lists and citations.
+
+\protected\def\btxtodo#1%
+ {[#1]}
+
+%D Lists:
+
+\newdimen\d_publ_number_width
+
+\ifdefined\btxblock \else \newcount\btxblock \fi \btxblock\plusone
+\ifdefined\btxcitecounter \else \newcount\btxcitecounter \fi % maybe pass this to lua
+
+\newtoks\everysetupbtxlistplacement % name will change
+\newtoks\everysetupbtxciteplacement % name will change
+
+\definelist % only used for selecting
+ [\s!btx]
+
+\setuplist
+ [\s!btx]
+ [\c!prefixstopper=:,
+ \c!state=\v!start,
+ \c!alternative=a,
+ \c!interaction=\v!none,
+ %\c!alternative=\v!paragraph,
+ %\c!width=\v!auto,
+ %\c!distance=\emwidth,
+ \c!before=\blank,
+ \c!after=\blank]
+
+\permanent\tolerant\protected\def\setupbtxlist[#1]#*[#2]%
+ {\ifarguments\or
+ \setuplist[\s!btx][#1]%
+ \or
+ \setuplist[\s!btx:#1][#2]%
+ \fi}
+
+\appendtoks
+ \ifempty\currentbtxrenderingparent
+ \definelist
+ [\s!btx:\currentbtxrendering]%
+ [\s!btx]%
+ \orelse\ifx\currentbtxrenderingparent\s!btx
+ \definelist
+ [\s!btx:\currentbtxrendering]%
+ [\s!btx]%
+ \else
+ \definelist
+ [\s!btx:\currentbtxrendering]%
+ [\s!btx:\currentbtxrenderingparent]%
+ \fi
+\to \everydefinebtxrendering
+
+\newconditional\c_btx_list_texts
+
+\appendtoks
+ \doifelse{\btxrenderingparameter\c!textstate}\v!start
+ \settrue\setfalse\c_btx_list_texts
+\to \everysetupbtxlistplacement
+
+\newconditional\c_btx_list_pages
+
+\appendtoks
+ \doifelse{\btxrenderingparameter\c!pagestate}\v!start
+ \settrue\setfalse\c_btx_list_pages
+\to \everysetupbtxlistplacement
+
+\protected\def\btx_entry_inject_pages % for the moment only normal
+ {\dontleavehmode
+ \begingroup
+ \setbtxlist % probably already set
+ \btx_reset_page
+ \setbtxparameterset\s!list\s!page
+ \btxparameter\c!command
+ {\usebtxstyleandcolor\c!style\c!color
+ \btxparameter\c!left
+ \clf_btxflushpages{\currentbtxdataset}{\currentbtxtag}%
+ \btxparameter\c!right}%
+ \endgroup}
+
+\permanent\protected\def\btxpagesetup#1% there will be no left|right|command|style at this inner level
+ {\begingroup
+ \publ_fast_setup\plusfive\s!list\s!page
+ \endgroup
+ \btx_reset_page} % probably not needed
+
+\permanent\protected\def\btxnumberingsetup#1%
+ {\begingroup
+ \dostarttagged\t!listtag\empty
+ \setbtxparameterset{\c!list:\s!numbering}\currentbtxnumbering % brrrr \setbtxlist
+ \btxparameter\c!left
+ \publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}%
+ \btxparameter\c!right
+ \dostoptagged
+ \endgroup
+ \btx_reset_numbering} % probably not needed
+
+% end of page stuff
+
+\permanent\protected\def\btxflushlisttext
+ {\begingroup
+ \usebtxstyleandcolor\c!style\c!color
+ \ignorespaces
+ \publ_fast_setup\plusfour\s!list\currentbtxcategory
+ \removeunwantedspaces
+ \endgroup}
+
+\permanent\protected\def\btxflushlistcombis
+ {\begingroup
+ \processcommacommand[\currentbtxcombis]\btx_entry_inject_combi % maybe in lua
+ \endgroup}
+
+\def\btx_entry_inject_list_text
+ {\publ_fast_setup\plusfour\s!list\s!text}
+
+\ifdefined\dotagpublication \else \aliased\let\dotagpublication\gobbletwoarguments \fi
+
+\protected\def\btx_entry_inject
+ {\begingroup
+ \dostarttagged\t!publication\empty
+ \dotagpublication\currentbtxdataset\currentbtxtag
+ \redoconvertfont % see (**) in strc-lst, this will become an configuration option
+ \edef\currentbtxcategory{\btxfield{category}}%
+ \ignorespaces
+ \ifconditional\c_btx_list_texts
+ \dostarttagged\t!listtext\s!left
+ \currentbtxbefore
+ \dostoptagged
+ \fi
+ %\dostarttagged\t!listcontent\empty
+ \btx_entry_inject_list_text
+ %\dostoptagged
+ \ifconditional\c_btx_list_pages
+ \dostarttagged\t!listpage\empty
+ \btx_entry_inject_pages
+ \dostoptagged
+ \fi
+ \ifconditional\c_btx_list_texts
+ \dostarttagged\t!listtext\s!right
+ \currentbtxafter
+ \dostoptagged
+ \fi
+ \dostoptagged
+ \endgroup}
+
+\permanent\protected\def\btxshowentryinline[#1]#*[#2]%
+ {\ifarguments
+ \ctxcommand{showbtxentry("\currentbtxdataset","\currentbtxtag")}
+ \or
+ \ctxcommand{showbtxentry("\currentbtxdataset","#1")}
+ \or
+ \ctxcommand{showbtxentry("#1","#2")}
+ \fi}
+
+\permanent\protected\def\btxstartcombientry
+ {\begingroup}
+
+\permanent\protected\def\btxstopcombientry
+ {\endgroup}
+
+\permanent\protected\def\btxhandlecombientry
+ {\btx_reference_indeed}
+
+\def\btx_entry_inject_combi#1%
+ {\begingroup
+ \def\currentbtxtag{#1}%
+ \ignorespaces
+ \publ_fast_setup\plusfour\s!list\currentbtxcategory
+ \removeunwantedspaces
+ \endgroup}
+
+% uses reference when set
+
+% \def\btx_entry_inject_combi#1%
+% {\begingroup
+% \def\currentbtxtag{#1}%
+% \ignorespaces
+% \btxdoifelsecombiinlist\currentbtxdataset\currentbtxtag
+% {\clf_btxflushlistcombi{\currentbtxdataset}{\currentbtxtag}}
+% {\publ_fast_setup\plusfour\s!list\currentbtxcategory}%
+% \removeunwantedspaces
+% \endgroup}
+
+\newtoks\everybtxlistrendering
+
+\appendtoks
+ \setbtxlist
+ %
+ \edef\currentbtxcriterium{\btxrenderingparameter\c!criterium}% \v!cite will become \s!cite
+ \ifempty\currentbtxcriterium
+ \let\currentbtxcriterium\v!previous
+ \orelse\ifx\currentbtxcriterium\v!cite
+ \let\currentbtxcriterium\v!here
+ \fi
+ %
+ \iflocation
+ \letinteractionparameter\c!style\empty
+% \letinteractionparameter\c!color\empty
+% \letinteractionparameter\c!contrastcolor\empty
+ \fi
+\to \everybtxlistrendering
+
+\def\nofbtxlistentries {0}
+\def\currentbtxlistentry{0}
+\def\currentbtxlistindex{0} % only for internal use (points back to big list)
+
+\newconditional\c_publ_prefixed
+
+\permanent\protected\def\btxsetnoflistentries #1{\edef\nofbtxlistentries {#1}}
+\permanent\protected\def\btxsetcurrentlistentry#1{\edef\currentbtxlistentry{#1}}
+\permanent\protected\def\btxsetcurrentlistindex#1{\edef\currentbtxlistindex{#1}}
+
+\permanent\protected\def\btxdoifelsesameaspreviouschecked#1#2% #1 == always | doublesided
+ {\clf_btxdoifelsesameasprevious
+ {\currentbtxdataset}%
+ \currentbtxlistentry%
+ {#2}%
+ \c_btx_list_reference
+ {#1}}
+
+\permanent\protected\def\btxdoifelsesameasprevious
+ {\btxdoifelsesameaspreviouschecked\v!doublesided}
+
+\permanent\protected\def\btxdoifelsecombiinlist#1#2%
+ {\clf_btxdoifelsecombiinlist{#1}{#2}}
+
+\aliased\let\btxdoifsameaspreviouscheckedelse\btxdoifelsesameaspreviouschecked
+\aliased\let\btxdoifsameaspreviouselse \btxdoifelsesameasprevious
+\aliased\let\btxdoifcombiinlistelse \btxdoifelsecombiinlist
+
+\tolerant\def\publ_place_list_indeed#1#2[#3]#*[#4]%
+ {\begingroup
+ \ifparameters
+ \let\currentbtxrendering\currentbtxspecification
+ \or
+ \ifhastok={#3}%
+ % [settings]
+ \let\currentbtxrendering\currentbtxspecification
+ \setupcurrentbtxrendering[#3]%
+ \edef\p_specification{\btxrenderingparameter\c!specification}%
+ \ifempty\p_specification\else
+ \let\currentbtxspecification\p_specification
+ \let\currentbtxrendering\currentbtxspecification % tricky
+ \fi
+ \else
+ \edef\currentbtxrendering{#3}%
+ \edef\p_specification{\btxrenderingparameter\c!specification}%
+ \ifempty\p_specification\else
+ \let\currentbtxspecification\p_specification
+ \fi
+ \fi
+ \or
+ % [rendering] [settings]
+ \edef\currentbtxrendering{#3}%
+ \setupcurrentbtxrendering[#4]%
+ \edef\p_specification{\btxrenderingparameter\c!specification}%
+ \ifempty\p_specification\else
+ \let\currentbtxspecification\p_specification
+ \fi
+ \fi
+ \setbtxparameterset\currentbtxspecification\s!list
+ \the\everybtxlistrendering
+ \ifconditional#1\relax
+ \edef\currentbtxrenderingtitle{\btxrenderingparameter\c!title}%
+ \ifempty\currentbtxrenderingtitle
+ \normalexpanded{\startnamedsection[\v!chapter][\c!reference=\currentbtxrendering,\c!title={\headtext{\currentbtxrendering}}]}%
+ \else
+ \normalexpanded{\startnamedsection[\v!chapter][\c!reference=\currentbtxrendering,\c!title={\currentbtxrenderingtitle}]}%
+ \fi
+ \fi
+ \ifempty\currentbtxrendering
+ \setbtxrendering % hm
+ \fi
+ \edef\currentbtxdataset{\btxrenderingparameter\c!dataset}%
+ \uselanguageparameter\btxdatasetparameter % new
+ \setbtxlist
+ \the\everystructurelist
+ \the\everysetupbtxlistplacement
+ % why not pass this with collect .. todo
+ % here we just collect items
+ \clf_btxcollectlistentries
+ names {\s!btx}%
+ criterium {\currentbtxcriterium}%
+ reference {\btxrenderingparameter\c!reference}%
+ method {\btxrenderingparameter\c!method}%
+ dataset {\currentbtxdataset}%
+ keyword {\btxrenderingparameter\c!keyword}%
+ sorttype {\btxrenderingparameter\c!sorttype}%
+ repeated {\btxrenderingparameter\c!repeat}%
+ ignored {\btxrenderingparameter\c!ignore}%
+ group {\btxrenderingparameter\c!group}%
+ filter {\btxrenderingparameter\c!filter}%
+ \relax
+ \ifnum\nofbtxlistentries>\zerocount
+ \forgetall
+ \btxrenderingparameter\c!before
+ \ifconditional#2\relax
+ \edef\p_command{\btxrenderingparameter\c!command}%
+ \ifempty\p_command
+ \edef\p_setups{\btxrenderingparameter\c!setups}%
+ \ifempty\p_setups
+ \else
+ \directsetup{\p_setups}%
+ \fi
+ \else
+ \expandafter\p_command\expandafter{\number\nofbtxlistentries}\relax
+ \fi
+ \else
+ \dostarttagged\t!publications\currentbtxrendering
+ \dostarttagged\t!list{btx}%
+ \startpacked[\v!blank]%
+ % sorting and so
+ \clf_btxpreparelistentries{\currentbtxdataset}% could be put in collect
+ % next we analyze the width
+ \ifempty\currentbtxnumbering \else
+ \edef\p_width{\listparameter\c!width}%
+ \ifx\p_width\v!auto
+ \setbox\scratchbox\vbox \bgroup
+ \settrialtypesetting
+ \clf_btxfetchlistentries{\currentbtxdataset}%
+ \egroup
+ \d_publ_number_width\wd\scratchbox
+ \letlistparameter\c!width\d_publ_number_width
+ \fi
+ \fi
+ \doifelse{\listparameter\c!prefix}\v!yes\settrue\setfalse\c_publ_prefixed
+ % this actually typesets them, we loop here as otherwise the whole
+ % bunch gets flushed at once
+ \dorecurse\nofbtxlistentries
+ {\let\currentbtxlistentry\recurselevel
+ \clf_btxflushlistentry{\currentbtxdataset}\currentbtxlistentry\relax}%
+ \stoppacked
+ \dostoptagged
+ \dostoptagged
+ \fi
+ \btxrenderingparameter\c!after
+ \fi
+ \ifconditional#1\relax
+ \stopnamedsection
+ \fi
+ \global\advance\btxblock\plusone
+ \endgroup}
+
+\permanent\protected\def\placebtxrendering {\publ_place_list_indeed\conditionalfalse\conditionalfalse}
+\permanent\protected\def\completebtxrendering{\publ_place_list_indeed\conditionaltrue \conditionalfalse}
+\permanent\protected\def\flushbtxrendering {\publ_place_list_indeed\conditionalfalse\conditionaltrue }
+
+\aliased\let\completelistofpublications\completebtxrendering % for old times sake
+\aliased\let\placelistofpublications \placebtxrendering % for old times sake
+
+%D This is somewhat special (for Alan of course):
+%D
+%D \starttyping
+%D % #1 is number of entries
+%D
+%D \starttexdefinition unexpanded btx:for:alan:wrapper #1
+%D \bTABLE
+%D % we can have a command or setups
+%D \flushbtxentries[command=\texdefinition{btx:for:alan:content}]
+%D \eTABLE
+%D \stoptexdefinition
+%D
+%D % #1 is tag
+%D
+%D \starttexdefinition unexpanded btx:for:alan:content #1
+%D \bTR
+%D \bTD
+%D \btxsettag{#1}
+%D \btxfield{name}
+%D \eTD
+%D \eTR
+%D \stoptexdefinition
+%D
+%D % we can have a command or setups
+%D
+%D \flushbtxrendering [method=dataset,command=\texdefinition{btx:for:alan:wrapper}]
+%D \stoptyping
+%D
+%D Because we want to be ungrouped we use a special loop construct.
+
+\permanent\protected\def\btxsetlisttag#1%
+ {\clf_btxflushlisttag{\currentbtxdataset}#1\relax}
+
+\newcount\c_btx_list_index
+
+\let\m_btx_list_action\empty
+
+\def\publ_flush_list_step_command
+ {\btxsetlisttag{\c_btx_list_index}
+ \expandafter\m_btx_list_action\expandafter{\currentbtxtag}%
+ \ifnum\c_btx_list_index<\nofbtxlistentries
+ \advance\c_btx_list_index\plusone
+ \expandafter\publ_flush_list_step_command
+ \else
+ \glet\m_btx_list_action\relax
+ \fi}
+
+\def\publ_flush_list_step_setup
+ {\btxsetlisttag{\c_btx_list_index}
+ \directsetup{\m_btx_list_action}%
+ \ifnum\c_btx_list_index<\nofbtxlistentries
+ \advance\c_btx_list_index\plusone
+ \expandafter\publ_flush_list_step_setup
+ \else
+ \glet\m_btx_list_action\relax
+ \fi}
+
+\permanent\protected\def\flushbtxentries[#1]%
+ {\begingroup
+ \getdummyparameters[\c!command=,\c!setups=,#1]%
+ \xdef\m_btx_list_action{\dummyparameter\c!command}%
+ \ifempty\m_btx_list_action
+ \xdef\m_btx_list_action{\dummyparameter\c!setups}%
+ \ifempty\m_btx_list_action
+ \endgroup
+ \c_btx_list_index\zerocount
+ \else
+ \endgroup
+ \c_btx_list_index\plusone
+ \doubleexpandafter\publ_flush_list_step_command
+ \fi
+ \else
+ \endgroup
+ \c_btx_list_index\plusone
+ \expandafter\publ_flush_list_step_command
+ \fi}
+
+%D So far.
+
+\def\currentbtxblock{\number\btxblock}
+
+% called at the lua end, for determining the width
+
+\permanent\protected\def\btxchecklistentry
+ {\begingroup
+ % todo, switch to font
+ \hbox{\btx_reference_checked}%
+ \par
+ \endgroup}
+
+% called at the lua end, the real rendering
+
+% we could have a yes and no where o nils the btx_reference_indeed ... saves a check there
+
+\installstructurelistprocessor{\s!btx}
+ {\let\currentlistentrynumber \btx_reference_indeed
+ \let\currentlistentrytitle \btx_entry_indeed
+ \let\currentlistentrypagenumber\btx_page_indeed
+ \strc_lists_apply_renderingsetup}
+
+\def\btx_entry_indeed
+ {\dostarttagged\t!listcontent\empty
+ \btx_list_reference_inject
+ \btx_entry_inject
+ \dostoptagged}
+
+\def\btx_page_indeed
+ {}
+
+\permanent\protected\def\btxhandlelistentry
+ {\strc_lists_entry_process}
+
+\permanent\protected\def\btxstartlistentry % maybe pass i
+ {\begingroup
+ \global\advance\c_btx_list_reference\plusone}
+
+\permanent\protected\def\btxstoplistentry
+ {\iftrialtypesetting
+ \global\advance\c_btx_list_reference\minusone
+ \fi
+ \endgroup}
+
+\newtoks\everybtxlistentry
+
+\permanent\protected\def\btxlistsetup#1% used for the reference in the list
+ {\the\everybtxlistentry
+ \everybtxlistentry\emptytoks % so only once per entry to be sure
+ \publ_fast_setup\plusfour\s!list{#1}}
+
+\appendtoks
+ \btx_check_language
+\to \everybtxlistentry
+
+\protected\def\btx_reference_indeed
+ {\begingroup
+ % redundant will go away:
+ \setbtxparameterset{\c!list:\s!numbering}\currentbtxnumbering
+ %
+ \ifempty\currentbtxnumbering
+ % nothing
+ \orelse\ifx\currentbtxnumbering\v!no
+ % nothing
+ \else
+ \usebtxstyleandcolor\c!style\c!color % new, needed?
+ \ifconditional\c_publ_prefixed\btxlistprefixednumber\fi
+ \clf_btxlistvariant % some can go
+ {\currentbtxdataset}%
+ {\currentbtxblock}%
+ {\currentbtxtag}%
+ {\currentbtxnumbering}%
+ {\currentbtxnumber}%
+ \relax
+ \fi
+ \endgroup}
+
+\permanent\protected\def\btxlistprefixednumber % hack but alan needs it
+ {\clf_listprefixednumber
+ {\currentlist}%
+ \currentbtxlistindex
+ {%
+ prefix {\listparameter\c!prefix}%
+ separatorset {\listparameter\c!prefixseparatorset}%
+ conversionset {\listparameter\c!prefixconversionset}%
+ starter {\listparameter\c!prefixstarter}%
+ stopper {\listparameter\c!prefixstopper}%
+ set {\listparameter\c!prefixset}%
+ segments {\listparameter\c!prefixsegments}%
+ connector {\listparameter\c!prefixconnector}%
+ }%
+ \relax}
+
+\protected\def\btx_reference_checked
+ {\dontleavehmode\hbox\bgroup % \hpack
+ \btx_reference_indeed
+ \egroup}
+
+\newcount\c_btx_list_reference
+
+\protected\def\btx_list_reference_inject
+ {\dontleavehmode\begingroup % no box
+ \iftrialtypesetting\else
+ \btx_list_reference_inject_now
+ \fi
+ % \btx_reference_indeed % else double entry in list
+ \endgroup}
+
+\def\btx_list_reference_inject_now
+ {\strc_references_direct_full_user
+ {\ifx\currentbtxdataset\v!default\else\s!btxset=\currentbtxdataset,\fi%
+ \s!btxref=\currentbtxtag,%
+ \s!btxspc=\currentbtxspecification,%
+ \s!btxlst=\number\c_btx_list_reference,% check if needed
+ %\ifempty\currentbtxcombis \else\s!btxcom={\currentbtxcombis},\fi%
+ \ifempty\currentbtxbefore \else\s!btxbtx={\currentbtxbefore},\fi%
+ \ifempty\currentbtxafter \else\s!btxatx={\currentbtxafter },\fi%
+ \ifempty\currentbtxbacklink\else\s!btxint=\number\currentbtxbacklink\fi
+ }%
+ {\s!btx::\v!list::\number\c_btx_list_reference}%
+ {\currentbtxnumber}}
+
+\newconditional\c_btx_cite_reference_injected
+
+\protected\def\btx_cite_reference_inject
+ {\ifconditional\c_btx_cite_reference_injected \else
+ \dontleavehmode
+ \iftrialtypesetting \else
+ \ifempty\currentbtxbacklink
+ % can be made empty when combining author / year
+ \orelse\ifnum\currentbtxbacklink>\zerocount
+ \btx_cite_reference_inject_indeed
+ \settrue\c_btx_cite_reference_injected
+ \fi
+ \fi
+ \fi}
+
+\newtoks\t_btx_reference_inject
+
+\def\btx_cite_reference_inject_indeed
+ {\the\t_btx_reference_inject
+ \strc_lists_inject_direct % todo: make like \btx_list_reference_inject_now with { }
+ [\s!btx]%
+ [\c!type=\s!btx]% \c!location=\v!none
+ [\ifx\currentbtxdataset\v!default\else\s!btxset=\currentbtxdataset,\fi%
+ \s!btxref=\currentbtxtag,%
+ %\ifempty\currentbtxcombis \else\s!btxcom={\currentbtxcombis},\fi%
+ \ifempty\currentbtxbefore \else\s!btxbtx={\currentbtxbefore},\fi%
+ \ifempty\currentbtxafter \else\s!btxatx={\currentbtxafter },\fi%
+ \ifempty\currentbtxbacklink\else\s!btxint=\number\currentbtxbacklink,\fi
+ \ifempty\currentbtxciteuservariables\else,\currentbtxciteuservariables\fi]}
+
+\permanent\def\currentbtxuservariable #1{\clf_btxuservariable {\currentbtxdataset}{#1}}
+\permanent\def\btxdoifelseuservariable#1{\clf_btxdoifelseuservariable{\currentbtxdataset}{#1}}
+
+\aliased\let\btxdoifuservariableelse\btxdoifelseuservariable
+
+\aliased\let\btxcitereference\btx_cite_reference_inject
+
+\let\currentbtxnumbering \empty
+\let\currentbtxcitealternative \empty
+
+\appendtoks
+ \edef\currentbtxnumbering{\btxrenderingparameter\c!numbering}%
+ \ifx\currentbtxnumbering\v!yes
+ \def\currentbtxnumbering{num}% convenient alias
+ \letbtxrenderingparameter\c!numbering\currentbtxnumbering
+ \letlistparameter\c!headnumber\v!always
+ \orelse\ifx\currentbtxnumbering\v!no
+ \letlistparameter\c!headnumber\v!no
+ \let\currentbtxnumbering\empty
+ % \letlistparameter\c!textcommand\outdented % needed? we can use titlealign
+ \letlistparameter\c!symbol \v!none
+ \letlistparameter\c!aligntitle \v!yes
+ \letlistparameter\c!numbercommand\firstofoneargument % for the moment, no doubling needed
+ \else
+ \letlistparameter\c!headnumber\v!always
+ \fi
+ \let\currentlistmethod\s!btx
+\to \everysetupbtxlistplacement
+
+\permanent\tolerant\protected\def\btxremapauthor[#1]#*[#2]%
+ {\clf_btxremapauthor{#1}{#2}}
+
+\permanent\protected\def\btxshowauthorremapping
+ {\clf_btxshowauthorremapping}
+
+\permanent\protected\def\btxflushauthor
+ {\doifelsenextoptionalcs\btx_flush_author_yes\btx_flush_author_nop}
+
+\permanent\protected\def\btxflushsuffix
+ {\ifempty\currentbtxsuffix
+ % nothing
+ \else
+ \characters{\currentbtxsuffix}% todo : rendering specific converter
+ \fi}
+
+\def\btx_flush_author_yes[#1]{\btx_flush_author{#1}}
+\def\btx_flush_author_nop {\btx_flush_author{\btxparameter\c!authorconversion}}
+
+\protected\def\btx_flush_author#1#2%
+ {\begingroup
+ \edef\currentbtxfield{#2}%
+ \setbtxparameterset\s!list\currentbtxfield
+% \let\currentbtxlistvariant\currentbtxfield
+ \clf_btxauthor
+ {\currentbtxdataset}%
+ {\currentbtxtag}%
+ {\currentbtxfield}%
+ {%
+ combiner {#1}%
+ kind {list}%
+ etallimit {\btxparameter\c!etallimit}%
+ etaldisplay {\btxparameter\c!etaldisplay}%
+ etaloption {\btxparameter\c!etaloption}%
+ symbol {\btxparameter{\c!stopper:initials}}%
+ connector {\btxparameter{\c!connector:initials}}%
+ }%
+ \relax
+ \endgroup}
+
+% yes or no: maybe just \flushauthor{...}{...}
+
+\permanent\protected\def\btxflushauthorname {\btx_flush_author{name}} % #1
+\permanent\protected\def\btxflushauthornormal {\btx_flush_author{normal}} % #1
+\permanent\protected\def\btxflushauthornormalshort {\btx_flush_author{normalshort}} % #1
+\permanent\protected\def\btxflushauthorinverted {\btx_flush_author{inverted}} % #1
+\permanent\protected\def\btxflushauthorinvertedshort{\btx_flush_author{invertedshort}} % #1
+
+\let\currentbtxauthorfield\s!author
+
+\permanent\protected\def\btxsetauthorfield#1{\edef\currentbtxauthorfield{#1}}
+
+\permanent\protected\def\currentbtxciteauthorbyfield
+ {\begingroup
+ %\setbtxparameterset\s!cite\s!author
+ % the alternatives inherit from cite:author
+ % and APA distinguishes authoryears from authoryear ("and" vs. "&")
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \clf_btxauthor
+ {\currentbtxdataset}%
+ {\currentbtxtag}%
+ {\currentbtxauthorfield}%
+ {%
+ combiner {\btxparameter\c!authorconversion}%
+ kind {cite}%
+ etallimit {\btxparameter\c!etallimit}%
+ etaldisplay {\btxparameter\c!etaldisplay}%
+ etaloption {\btxparameter\c!etaloption}%
+ symbol {\btxparameter{\c!stopper:initials}}%
+ }%
+ \relax
+ \endgroup}
+
+\permanent\protected\def\currentbtxciteauthor
+ {\let\currentbtxauthorfield\s!author
+ \currentbtxciteauthorbyfield} % always author
+
+\permanent\protected\def\btxstartauthor#1#2#3% a state > 0 signals that some authors can clash
+ {\begingroup
+ \currentbtxauthorindex#1\relax
+ \currentbtxauthorcount#2\relax
+ \currentbtxauthorstate#3\relax}
+
+\permanent\protected\def\btxstopauthor
+ {\endgroup}
+
+\permanent\protected\def\btxciteauthorsetup#1{\fastsetup{\s!btx:\s!cite:\s!author:#1}}
+\permanent\protected\def\btxlistauthorsetup#1{\fastsetup{\s!btx:\s!list:\s!author:#1}}
+
+% \btxflushauthor{author}
+% \btxflushauthor{editor}
+%
+% \btxflushauthor[name]{author}
+% \btxflushauthor[normal]{author}
+% \btxflushauthor[normalshort]{author}
+% \btxflushauthor[inverted]{author}
+% \btxflushauthor[invertedshort]{author}
+
+% \btxflushauthor{author}
+% \btxflushauthor{editor}
+
+% Interaction
+%
+% Because we have more complex entries in lists we don't use the normal list
+% interaction features.
+
+\newconditional\btxinteractive
+\newconditional\btxinteractivenumber
+\newconditional\btxinteractivetext
+\newconditional\btxinteractivepage
+
+\let\currentbtxinteraction\empty
+
+\installcorenamespace{btxinteraction}
+
+\setvalue{\??btxinteraction\v!number}{\settrue\btxinteractivenumber}
+\setvalue{\??btxinteraction\v!text }{\settrue\btxinteractivetext}
+\setvalue{\??btxinteraction\v!page }{\settrue\btxinteractivepage}
+\setvalue{\??btxinteraction\v!all }{\settrue\btxinteractivenumber
+ \settrue\btxinteractivetext
+ \settrue\btxinteractivepage}
+
+% \setupbtx[interaction=page] % or text or number or all
+% \setupbtxrendering[pagestate=start]
+
+\appendtoks
+ \iflocation
+ \edef\currentbtxinteraction{\btxparameter\c!interaction}%
+ \ifx\currentbtxinteraction\v!stop
+ \setfalse\btxinteractive
+ \else
+ \let\structurelistlocation\empty
+ \settrue\btxinteractive
+ \begincsname\??btxinteraction\currentbtxinteraction\endcsname
+ \fi
+ \else
+ \setfalse\btxinteractive
+ \fi
+\to \everysetupbtxlistplacement
+
+\appendtoks
+ \iflocation
+ \edef\currentbtxinteraction{\btxparameter\c!interaction}%
+ \ifx\currentbtxinteraction\v!stop
+ \setfalse\btxinteractive
+ \else
+ \settrue\btxinteractive
+ \fi
+ \else
+ \setfalse\btxinteractive
+ \fi
+\to \everysetupbtxciteplacement
+
+%D When a publication is cited, we need to signal that somehow. This is done with the
+%D following (not user) command. We could tag without injecting a node but this way
+%D we also store the location, which makes it possible to ask local lists.
+
+%D \macros{cite,nocite,citation,nocitation,usecitation}
+%D
+%D The inline \type {\cite} command creates a (often) short reference to a publication
+%D and for historic reasons uses a strict test for brackets. This means, at least
+%D in the default case that spaces are ignored in the argument scanner. The \type
+%D {\citation} commands is more liberal but also gobbles following spaces. Both
+%D commands insert a reference as well as a visual clue.
+%D
+%D The \type {no} commands all do the same (they are synonyms): they make sure that
+%D a reference is injected but show nothing. However, they do create a node so best
+%D attach them to some text in order to avoid spacing interferences. A slightly
+%D less efficient alternative is \type {\cite[none][tag]}.
+
+% [tags]
+% [settings|variant][tags]
+% [base::tags]
+% [settings|variant][base::tags]
+
+% these need to be sort of protected:
+
+% methods:
+%
+% hidden : mark for list, don't show in text
+% list : mark for list, show in text only when in list
+% text : not to list, show in text
+% always : mark for list, show in text
+
+\let\p_publ_cite_before \empty
+\let\p_publ_cite_after \empty
+\let\p_publ_cite_lefttext \empty
+\let\p_publ_cite_righttext\empty
+
+\let\currentbtxciteuservariables\empty
+\let\currentbtxcitealternative \empty
+
+\permanent\protected\def\btxhybridcite % so one can alias the old
+ {\dontleavehmode
+ \begingroup
+ \strictdoifelsenextoptional\publ_cite_tags_options\publ_cite_tags_indeed}
+
+\protected\def\publ_cite_tags_options[#1]%
+ {\strictdoifelsenextoptional{\publ_cite_tags_options_indeed{#1}}{\publ_cite_tags_indeed{#1}}}
+
+\protected\def\publ_cite_tags_indeed#1%
+ {\letinteractionparameter\c!style\empty
+ \setbtxparametersetroot\s!cite % we need to get the default
+ \edef\currentbtxcitealternative{\btxparameter\c!alternative}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \edef\currentbtxcitetag{#1}%
+ \the\everysetupbtxciteplacement
+ \publ_cite_variant
+ \endgroup}
+
+\protected\def\publ_cite_tags_options_indeed#1%
+ {\doifelseassignment{#1}\publ_cite_tags_settings_indeed\publ_cite_tags_variants_indeed{#1}}
+
+\def\publ_cite_tags_settings_indeed#1[#2]%
+ {\letinteractionparameter\c!style\empty
+ %\letinteractionparameter\c!color\empty
+ \letdummyparameter\c!reference \empty
+ \letdummyparameter\c!alternative\empty
+ \letdummyparameter\c!before \empty
+ \letdummyparameter\c!after \empty
+ \letdummyparameter\c!lefttext \empty
+ \letdummyparameter\c!righttext \empty
+ \getdummyparameters[#1]%
+ \edef\p_reference{\dummyparameter\c!reference}%
+ \ifempty\p_reference
+ \edef\currentbtxcitetag{#2}%
+ \else
+ \let\currentbtxcitetag\p_reference
+ \edef\currentbtxciteuservariables{#2}%
+ \fi
+ \edef\p_specification{\dummyparameter\c!specification}%
+ \ifempty\p_specification
+ \else
+ \let\currentbtxspecification\p_specification
+ \fi
+ \edef\p_alternative{\dummyparameter\c!alternative}%
+ \ifempty\p_alternative
+ \setbtxparametersetroot\s!cite
+ \edef\currentbtxcitealternative{\btxparameter\c!alternative}%
+ \else
+ \let\currentbtxcitealternative\p_alternative
+ \fi
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \setupcurrentbtx[#1]%
+ %
+ \edef\p_publ_cite_before {\dummyparameter\c!before}%
+ \edef\p_publ_cite_after {\dummyparameter\c!after}%
+ \edef\p_publ_cite_lefttext {\dummyparameter\c!lefttext}%
+ \edef\p_publ_cite_righttext{\dummyparameter\c!righttext}%
+ %
+ \the\everysetupbtxciteplacement
+ \publ_cite_variant
+ \endgroup}
+
+\def\publ_cite_tags_variants_indeed#1[#2]%
+ {\letinteractionparameter\c!style\empty
+ \edef\currentbtxcitealternative{#1}%
+ \edef\currentbtxcitetag{#2}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \the\everysetupbtxciteplacement
+ \publ_cite_variant
+ \endgroup}
+
+\newconditional\btxcitecompress
+
+\let\currentbtxreference \empty
+\let\currentbtxcitemethod\v!hidden
+
+\def\publ_cite_variant
+ {\begingroup
+ \publ_cite_handle_variant_indeed[\currentbtxcitetag]}
+
+\protected\def\publ_cite_handle_variant#1%
+ {\begingroup
+ \edef\currentbtxcitealternative{#1}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \the\everysetupbtxciteplacement
+ \publ_cite_handle_variant_indeed}
+
+\permanent\protected\def\publ_cite_handle_variant_blob
+ {\clf_btxhandlecite
+ dataset {\currentbtxdataset}%
+ reference {\currentbtxreference}%
+ method {\currentbtxcitemethod}%
+ variant {\currentbtxcitealternative}%
+ sorttype {\btxparameter\c!sorttype}%
+ compress {\btxparameter\c!compress}%
+ author {\btxparameter\c!author}%
+ authorconversion {\c!authorconversion}%
+ lefttext {\p_publ_cite_lefttext}%
+ righttext {\p_publ_cite_righttext}%
+ before {\p_publ_cite_before}%
+ after {\p_publ_cite_after}%
+ \relax
+ \iftrialtypesetting\else
+ %\clf_btxflushmarked
+ \fi}
+
+\aliased\let\dobtxcitevariantblob\publ_cite_handle_variant_blob % command can use it via lua
+
+\tolerant\def\publ_cite_handle_variant_indeed[#1]%
+ {\letbtxparameter\c!alternative\currentbtxcitealternative
+ \edef\currentbtxreference{#1}%
+ \saverunningstyleandcolor
+ \usebtxstyleandcolor\c!style\c!color
+ \uselanguageparameter\btxdatasetparameter % new
+ \btxparameter\c!left
+ \btxparameter\c!command{\dobtxcitevariantblob}% {\publ_cite_handle_variant_blob}%
+ \btxparameter\c!right
+ \endgroup}
+
+\permanent\protected\def\btxlistcitation {\publ_citation\v!list}
+\permanent\protected\def\btxtextcitation {\publ_citation\v!text}
+\permanent\protected\def\btxalwayscitation{\publ_citation\v!always}
+
+\tolerant\def\publ_citation#1[#2]#*[#3]% could be made more efficient but not now
+ {\dontleavehmode
+ \begingroup
+ \let\currentbtxcitemethod#1%
+ \ifparameter#3\or
+ \publ_cite_tags_options_indeed{#2}[#3]%
+ \else
+ \publ_cite_tags_indeed{#2}%
+ \fi}
+
+\permanent\tolerant\protected\def\btxhiddencitation[#1]%
+ {\iftrialtypesetting \else
+ \begingroup
+ \let\currentbtxcitemethod\v!hidden
+ \edef\currentbtxreference{#1}%
+ \clf_btxhandlenocite
+ method {\currentbtxcitemethod}%
+ dataset {\currentbtxdataset}%
+ reference {\currentbtxreference}%
+ \relax
+ %\clf_btxflushmarked
+ \endgroup
+ \fi}
+
+\permanent\protected\def\btxmissing#1%
+ {\dontleavehmode{\tttf<#1>}}
+
+%D Compatibility:
+
+\aliased\let\hiddencitation\btxhiddencitation \aliased\let\hiddencite\hiddencitation
+\aliased\let\listcitation \btxlistcitation \aliased\let\listcite \listcitation
+\aliased\let\textcitation \btxtextcitation \aliased\let\textcite \textcitation
+\aliased\let\alwayscitation\btxalwayscitation \aliased\let\alwayscite\alwayscitation
+
+\permanent\protected\def\citation {\doifelsenextoptionalcs\btxlistcitation \btxdirectlistcite}
+\permanent\protected\def\nocitation{\doifelsenextoptionalcs\btxhiddencitation\btxdirecthiddencite}
+
+\aliased\let\cite \citation
+\aliased\let\nocite \nocitation
+\aliased\let\usecitation\nocitation
+
+\protected\def\publ_entry_citation {\doifelsenextoptionalcs\btxlistcitation \btxdirectlistcite}
+\protected\def\publ_entry_nocitation{\doifelsenextoptionalcs\btxhiddencitation\btxdirecthiddencite}
+
+\appendtoks
+ \enforced\let\cite \publ_entry_citation
+ \enforced\let\nocite\publ_entry_nocitation
+\to \everybtxlistrendering
+
+\permanent\protected\def\btxdirectlistcite #1{\btxlistcitation [#1]\relax} % no optional arguments
+\permanent\protected\def\btxdirecthiddencite#1{\btxhiddencitation[#1]\relax} % no optional arguments
+
+%D Setup helpers, beware, we need to wrap this .. now we need to know
+%D how setups are implemented.
+
+\setvalue{\??setup:\s!btx:\s!unknown}#1{\inframed{\tttf#1}}
+
+\def\publ_fast_setup_yes#1#2%
+ {\csname\??setup:\s!btx:%
+ \ifcsname\??setup:\s!btx:\currentbtxspecification:#1:#2\endcsname
+ \currentbtxspecification:#1:#2%
+ \orelse\ifcsname\??setup:\s!btx:\currentbtxspecificationfallback:#1:#2\endcsname
+ \currentbtxspecificationfallback:#1:#2%
+ \orelse\ifcsname\??setup:\s!btx:#1:#2\endcsname
+ #1:#2%
+ \orelse\ifcsname\??setup:\s!btx:\currentbtxspecification:#1:\s!unknown\endcsname
+ \currentbtxspecification:#1:\s!unknown
+ \orelse\ifcsname\??setup:\s!btx:\currentbtxspecificationfallback:#1:\s!unknown\endcsname
+ \currentbtxspecificationfallback:#1:\s!unknown
+ \else
+ #1:\s!unknown
+ \fi
+ \endcsname{#2}}
+
+\def\publ_fast_setup_nop#1#2%
+ {\csname\??setup:\s!btx:%
+ \ifcsname\??setup:\s!btx:\currentbtxspecification:#1:#2\endcsname
+ \currentbtxspecification:#1:#2%
+ \orelse\ifcsname\??setup:\s!btx:#1:#2\endcsname
+ #1:#2%
+ \orelse\ifcsname\??setup:\s!btx:\currentbtxspecification:#1:\s!unknown\endcsname
+ \currentbtxspecification:#1:\s!unknown
+ \else
+ #1:\s!unknown
+ \fi
+ \endcsname{#2}}
+
+\newconstant\btxsetuptype
+
+% 0 = unknown darkred
+% 1 = cite darkblue
+% 2 = subcite darkgreen
+% 3 = numbering darkorange
+% 4 = list darkcyan
+% 5 = page darkmagenta
+% 6 = unknown darkred
+
+\protected\def\publ_fast_btx_setup_chain_inbetween{\allowbreak->\allowbreak}
+\protected\def\publ_fast_btx_setup_colon_inbetween{\allowbreak :\allowbreak}
+
+\protected\def\publ_fast_btx_setup_chain_yes#1#2%
+ {\dontleavehmode\begingroup
+ \let\:\publ_fast_btx_setup_colon_inbetween
+ \infofont
+ \ifcase\btxsetuptype\darkred\or\darkblue\or\darkgreen\or\darkcyan\or\darkmagenta\else\darkred\fi
+ [\prewordbreak
+ \currentbtxspecification \:#1\:#2\ifcsname\??setup:\s!btx:\currentbtxspecification:#1:#2\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ \currentbtxspecificationfallback\:#1\:#2\ifcsname\??setup:\s!btx:\currentbtxspecificationfallback:#1:#2\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ #1\:#2\ifcsname\??setup:\s!btx:#1:#2\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ \currentbtxspecification \:#1\:\s!unknown\ifcsname\??setup:\s!btx:\currentbtxspecification:#1:\s!unknown\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ \currentbtxspecificationfallback\:#1\:\s!unknown\ifcsname\??setup:\s!btx:\currentbtxspecificationfallback:#1:\s!unknown\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ unset\fi\fi\fi\fi\fi
+ \space @\space
+ \currentbtx
+ \prewordbreak]%
+ \endgroup}
+
+\protected\def\publ_fast_btx_setup_chain_nop#1#2%
+ {\dontleavehmode\begingroup
+ \let\:\publ_fast_btx_setup_colon_inbetween
+ \infofont
+ \darkred
+ [\prewordbreak
+ \currentbtxspecification\:#1\:#2\ifcsname\??setup:\s!btx:\currentbtxspecification:#1:#2\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ #1\:#2\ifcsname\??setup:\s!btx:#1:#2\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ \currentbtxspecification\:#1\:\s!unknown\ifcsname\??setup:\s!btx:\currentbtxspecification:#1:\s!unknown\endcsname\else
+ \publ_fast_btx_setup_chain_inbetween
+ unset\fi\fi\fi
+ \space @\space
+ \currentbtx
+ \prewordbreak]%
+ \endgroup}
+
+\protected\def\publ_fast_btx_setup_normal#1%
+ {\btxsetuptype#1\relax
+ \ifempty\currentbtxspecificationfallback
+ \expandafter\publ_fast_setup_nop
+ \else
+ \expandafter\publ_fast_setup_yes
+ \fi}
+
+\protected\def\publ_fast_btx_setup_visual#1#2#3%
+ {\btxsetuptype#1\relax
+ \ifempty\currentbtxspecificationfallback
+ \expandafter\publ_fast_btx_setup_chain_nop
+ \else
+ \expandafter\publ_fast_btx_setup_chain_yes
+ \fi{#2}{#3}%
+ \ifempty\currentbtxspecificationfallback
+ \expandafter\publ_fast_setup_nop
+ \else
+ \expandafter\publ_fast_setup_yes
+ \fi{#2}{#3}}
+
+\installtextracker
+ {publications.setups}
+ {\let\publ_fast_setup\publ_fast_btx_setup_visual}
+ {\let\publ_fast_setup\publ_fast_btx_setup_normal}
+
+\let\publ_fast_setup\publ_fast_btx_setup_normal
+
+%D Cite helpers:
+
+\newtoks\everybtxciteentry
+
+\prependtoks
+ \setfalse\c_btx_cite_reference_injected
+\to \everybtxciteentry
+
+\permanent\protected\def\btxcitesetup#1%
+ {\the\everybtxciteentry
+ \everybtxciteentry\emptytoks % tricky maybe not when subcites
+ \publ_fast_setup\plusone\s!cite{#1}} % no \btxcitereset as we loose dataset and such
+
+\permanent\protected\def\btxsubcitesetup#1%
+ {\the\everybtxciteentry
+ \everybtxciteentry\emptytoks % tricky maybe not when subcites
+ \publ_fast_setup\plustwo\s!cite{#1}} % no \btxcitereset as we loose dataset and such
+
+\appendtoks
+ \btx_check_language
+\to \everybtxciteentry
+
+\permanent\protected\def\btxstartsubcite#1%
+ {\begingroup
+ \btx_reset_cite % todo: limited set
+ % \saverunningstyleandcolor % let's see when Alan needs it
+ \def\currentbtxcitealternative{#1}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \usebtxstyleandcolor\c!style\c!color
+ \btxparameter\c!left
+ \relax}
+
+\permanent\protected\def\btxstopsubcite
+ {\relax
+ \btxparameter\c!right
+ \endgroup}
+
+\permanent\protected\def\btxstartciterendering[#1]%
+ {\begingroup
+ \edef\currentbtxcitealternative{#1}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \usebtxstyleandcolor\c!style\c!color
+ \btxparameter\c!left
+ \relax}
+
+\permanent\protected\def\btxstopciterendering
+ {\relax
+ \btxparameter\c!right
+ \endgroup}
+
+\aliased\let\btxstartciteauthor\begingroup
+\aliased\let\btxstopciteauthor \endgroup
+
+\permanent\protected\def\btxstartcite{\begingroup\btx_reset_cite}
+\aliased \let\btxstopcite \endgroup
+
+%D Whatever helpers:
+
+\permanent\protected\def\btxsingularplural#1{\clf_btxsingularorplural{\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\protected\def\btxoneorrange #1{\clf_btxoneorrange {\currentbtxdataset}{\currentbtxtag}{#1}}
+\permanent\protected\def\btxfirstofrange #1{\clf_btxfirstofrange {\currentbtxdataset}{\currentbtxtag}{#1}}
+
+\aliased\let\btxsingularorplural\btxsingularplural
+
+\stopcontextdefinitioncode
+
+%D Journals
+
+\permanent\protected\def\btxloadjournallist [#1]{\clf_btxloadjournallist{#1}}
+\permanent\protected\def\btxsavejournallist [#1]{\clf_btxsavejournallist{#1}}
+\permanent\protected\def\btxaddjournal [#1][#2]{\clf_btxaddjournal{#1}{#2}}
+\permanent \def\btxexpandedjournal #1{\clf_btxexpandedjournal{#1}} % \protected ?
+\permanent \def\btxabbreviatedjournal#1{\clf_btxabbreviatedjournal{#1}} % \protected ?
+
+% \installcorenamespace{btxjournal}
+%
+% \letvalue{\s!btxjournal\v!long }\btxexpandedjournal
+% \letvalue{\s!btxjournal\v!short }\btxabbreviatedjournal
+% \letvalue{\s!btxjournal\v!normal}\firstofoneargument
+%
+% \protected\def\btxcheckedjournal
+% {\expandnamespaceparameter\s!btxjournal\btxrenderingparameter\c!journalconversion}
+
+% \btxloadjournallist[list.txt] % Foo Journal of Bars = FBJ \n ....
+%
+% \btxexpandedjournal[fbj]
+% \btxabbreviatedjournal[foo journal of bars]
+
+%D Saving data:
+
+\tolerant\permanent\protected\def\savebtxdataset[#1]#*[#2]#*[#3]
+ {\ifarguments
+ % bad news
+ \or
+ \ifhastok={#1}%
+ \publ_save_dataset_indeed[\s!default][\jobname-saved.bib][#1]%
+ \else
+ \publ_save_dataset_indeed[\s!default][#1][]%
+ \fi
+ \or
+ \ifhastok={#2}%
+ \publ_save_dataset_indeed[\s!default][#1][#2]%
+ \else
+ \publ_save_dataset_indeed[#1][#2][]%
+ \fi
+ \or
+ \publ_save_dataset_indeed[#1][#2][#3]%
+ \fi}
+
+\protected\def\publ_save_dataset_indeed[#1][#2][#3]%
+ {\begingroup
+ \getdummyparameters
+ [\c!criterium=\v!all,%
+ \c!type=,%
+ \c!dataset=#1,%
+ \c!file=#2,%
+ #3]% % all or used
+ \clf_btxsavedataset
+ dataset {\dummyparameter\c!dataset}%
+ filename {\dummyparameter\c!file}%
+ filetype {\dummyparameter\c!type}%
+ criterium {\dummyparameter\c!criterium}%
+ \relax
+ \endgroup}
+
+% \savebtxdataset[default][e:/tmp/foo.bib]
+% \savebtxdataset[default][e:/tmp/foo.lua]
+% \savebtxdataset[default][e:/tmp/foo.xml]
+
+%D In-text entries:
+
+\protected\def\placecitation{\citation[entry]} % [#1]
+
+\permanent\protected\def\btxhandleciteentry
+ {\dontleavehmode
+ \begingroup
+ \def\currentbtxcitealternative{entry}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative % needs checking
+ \btxcitereference
+ \btx_entry_inject
+ \endgroup}
+
+%D Registers
+
+% \setupbtxregister
+% [\c!state=\v!start,
+% \c!dataset=\v!all,
+% \c!method=\v!always]
+
+\protected\def\publ_registers_set
+ {\ifempty\currentbtxregister \else
+ \clf_btxsetregister
+ specification {\currentbtxspecification}%
+ name {\currentbtxregister}%
+ state {\btxregisterparameter\c!state}%
+ dataset {\btxregisterparameter\c!dataset}%
+ field {\btxregisterparameter\c!field}%
+ register {\btxregisterparameter\c!register}%
+ method {\btxregisterparameter\c!method}%
+ alternative {\btxregisterparameter\c!alternative}%
+ \relax
+ \fi}
+
+\appendtoks
+ \publ_registers_set
+\to \everydefinebtxregister
+
+\appendtoks
+ \publ_registers_set
+\to \everysetupbtxregister
+
+\appendtoks
+ \normalexpanded{%
+ \defineprocessor
+ [\s!btx:r:\currentbtxregister]%
+ [\c!style=\noexpand\namedbtxregisterparameter{\currentbtxregister}\noexpand\c!style,
+ \c!color=\noexpand\namedbtxregisterparameter{\currentbtxregister}\noexpand\c!color]}%
+\to \everydefinebtxregister
+
+\appendtoks
+ \clf_btxtoregister{\currentbtxdataset}{\currentbtxtag}%
+\to \t_btx_reference_inject
+
+\permanent\protected\def\btxindexedauthor#1#2#3#4#5#6% alternative von last initials first junior
+ {\begingroup
+ \def\currentbtxcitealternative{#1}%
+ \ifempty\currentbtxcitealternative
+ \edef\currentbtxcitealternative{invertedshort}% maybe we need some default here too?
+ \fi
+ %let\currentbtxlistvariant\currentbtxcitealternative % we inherit
+ \the\everysetupbtxciteplacement
+ \def\currentbtxvons {#2}%
+ \def\currentbtxsurnames {#3}%
+ \def\currentbtxinitials {#4}%
+ \def\currentbtxfirstnames {#5}%
+ \def\currentbtxjuniors {#6}%
+ \setbtxparameterset\s!cite\currentbtxcitealternative
+ \fastsetup{\s!btx:\s!cite:\s!author:\currentbtxcitealternative}%
+ \endgroup}
+
+\permanent\protected\def\btxregisterauthor
+ {\doifelsenextoptionalcs\publ_register_author_yes\publ_register_author_nop}
+
+\def\publ_register_author_yes[#1]#2%
+ {\clf_btxauthortoregister{#1}{#2}\relax}
+
+\def\publ_register_author_nop#1%
+ {\clf_btxauthortoregister{\currentbtxdataset}{#1}\relax}
+
+%D We hook some setters in the definition sets:
+
+% \installdefinitionsetmember \??btx {btxspecification} \??btxcitevariant {btxcitevariant}
+% \installdefinitionsetmember \??btx {btxspecification} \??btxlistvariant {btxlistvariant}
+% \installdefinitionsetmember \??btx {btxspecification} \??btxlist {btxlist}
+% \installdefinitionsetmember \??btx {btxspecification} \??btxrendering {btxrendering}
+% \installdefinitionsetmember \??btx {btxspecification} \??btx {btx}
+
+%D And more helpers ... a never ending story these publications:
+
+% \definebtx
+% [btx:apa:list:article:title]
+% [style=bolditalic,
+% command=\WORD]
+%
+% \btxstartstyle[btx:apa:list:article:title]
+% \btxusecommand[btx:apa:list:article:title]{foo}
+% \btxstopstyle
+
+\let\savedcurrentbtx\empty
+
+\permanent\protected\def\btxstartstyle[#1]%
+ {\begingroup
+ \let\savedcurrentbtx\currentbtx
+ \def\currentbtx{#1}%
+ \usebtxstyle\c!style
+ \let\currentbtx\savedcurrentbtx}
+
+\permanent\protected\def\btxstartcolor[#1]%
+ {\begingroup
+ \let\savedcurrentbtx\currentbtx
+ \def\currentbtx{#1}%
+ \usebtxcolor\c!color
+ \let\currentbtx\savedcurrentbtx}
+
+\permanent\protected\def\btxstartstyleandcolor[#1]%
+ {\begingroup
+ \let\savedcurrentbtx\currentbtx
+ \def\currentbtx{#1}%
+ \usebtxstyleandcolor\c!style\c!color
+ \let\currentbtx\savedcurrentbtx}
+
+\aliased\let\btxstopstyle \endgroup
+\aliased\let\btxstopcolor \endgroup
+\aliased\let\btxstopstyleandcolor\endgroup
+
+\permanent\protected\def\btxusecommand[#1]#2% using #2 permits space after []
+ {\namedbtxparameter{#1}\c!command{#2}}
+
+\permanent\protected\def\startbtxrunningstyleandcolor
+ {\dontleavehmode
+ \begingroup
+ \restorerunningstyleandcolor}
+
+\permanent\protected\def\stopbtxrunningstyleandcolor
+ {\endgroup}
+
+%D Maybe handy:
+
+\permanent\protected\def\btxdoifelsematches#1#2#3%
+ {\clf_btxdoifelsematches{#1}{#2}{#3}}
+
+%D Defaults:
+
+\setupbtxrendering
+ [\c!interaction=\v!start, % \v!all
+ \c!specification=\btxparameter\c!specification,
+ \c!dataset=\v!default,
+ \c!repeat=\v!no,
+ \c!continue=\v!no,
+ \c!method=\v!global,
+ % \c!setups=btx:\btxrenderingparameter\c!alternative:initialize, % not the same usage as cite !
+ \c!sorttype=\v!default,
+ \c!criterium=\v!text,
+ \c!refcommand=authoryears, % todo
+ \c!numbering=\v!yes,
+ %\c!saveinlist=\v!no, % maybe for before/after
+ \c!pagestate=\v!stop,
+ \c!textstate=\v!start,
+ \c!width=\v!auto,
+ \c!separator={\removepunctuation;\space},
+ \c!distance=1.5\emwidth]
+
+% Quite some interpunction and labels are the same of at least consistent within
+% a standard when citations and list entries are involved. We assume that each
+% standard defines its own set but it can fall back on these defaults.
+
+\setupbtx
+ [\c!interaction=\v!start,
+ \c!alternative=num, % default cite form, normally defined in the cite namespace
+ \c!inbetween=\btxspace,
+ % \c!range=\endash, % separator:range?
+ \c!range=\directdiscretionary\endash,
+ \c!compress=\v!yes, % was no?
+ \c!authorconversion=normal,
+ \c!sorttype=normal, % normal, reverse or none
+ \c!etallimit=3,
+ \c!etaldisplay=\btxparameter\c!etallimit,
+ \c!otherstext={\btxspace et al.},
+ \c!separator:firstnames={\btxspace},
+ \c!separator:juniors={\btxspace},
+ \c!separator:vons={\btxspace},
+ \c!separator:initials={\btxspace},
+ \c!stopper:initials={.},
+ %\c!surnamesep={\btxcomma}, % is this used anywhere?
+ \c!separator:invertedinitials={\btxcomma},
+ \c!separator:invertedfirstnames={\btxcomma},
+ \c!separator:names:2={\btxcomma}, % separates multiple names
+ \c!separator:names:3=\btxparameter{\c!separator:2}, % before last name in a list
+ \c!separator:names:4=\btxparameter{\c!separator:2}, % between only two names
+ \c!separator:2={\btxsemicolon}, % aka pubsep - separates multiple objects
+ \c!separator:3=\btxparameter{separator:2}, % before last object in a list
+ \c!separator:4=\btxparameter{separator:2}] % between only two objects
+
+% Do we want these in the format? Loading them delayed is somewhat messy.
+
+\loadbtxdefinitionfile[commands]
+\loadbtxdefinitionfile[definitions]
+
+\loadbtxdefinitionfile[cite]
+\loadbtxdefinitionfile[list]
+\loadbtxdefinitionfile[page]
+\loadbtxdefinitionfile[author]
+
+% we assume that the users sets up the right specification and if not ... well,
+% hope for the best that something shows up and consult the manual otherwise
+
+\permanent\protected\def\usebtxdefinitions[#1]%
+ {\loadbtxdefinitionfile[#1]% % for hh
+ \setupbtx[\c!specification=#1]} % for ab
+
+\setupbtx
+ [\c!specification=\s!default,
+ \c!dataset=\v!default,
+ \c!default=\v!default]
+
+\loadbtxdefinitionfile
+ [\s!default]
+
+%D Delayed loading:
+
+\fetchruntimecommand \showbtxdatasetfields \f!publ_tra
+\fetchruntimecommand \showbtxdatasetcompleteness \f!publ_tra
+\fetchruntimecommand \showbtxdatasetauthors \f!publ_tra
+\fetchruntimecommand \showbtxhashedauthors \f!publ_tra
+\fetchruntimecommand \showbtxfields \f!publ_tra
+\fetchruntimecommand \showbtxtables \f!publ_tra
+
+%D Some potential crap:
+%D
+%D Because I consider this bad data management and a weird mix of languages only one
+%D accessor is provided.
+
+\permanent\tolerant\protected\def\btxshortcut[#1]#:#2%
+ {\clf_btxshortcut{\ifparameter#1\or#1\else\s!default\fi}{#2}}
+
+\protect
diff --git a/tex/context/base/mkiv/publ-tra.mkxl b/tex/context/base/mkiv/publ-tra.mkxl
new file mode 100644
index 000000000..ccad4c22a
--- /dev/null
+++ b/tex/context/base/mkiv/publ-tra.mkxl
@@ -0,0 +1,84 @@
+%D \module
+%D [ file=publ-tra,
+%D version=2013.12.24,
+%D title=\CONTEXT\ Publication Support,
+%D subtitle=Tracing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: make this a runtime module
+% todo: use the module interface
+
+\writestatus{loading}{ConTeXt Publication Support / Tracing}
+
+\registerctxluafile{publ-tra}{}
+
+\unprotect
+
+\permanent\protected\gdef\showbtxdatasetfields {\publ_show_dataset_whatever{showbtxdatasetfields}}
+\permanent\protected\gdef\showbtxdatasetcompleteness{\publ_show_dataset_whatever{showbtxdatasetcompleteness}}
+\permanent\protected\gdef\showbtxdatasetauthors {\publ_show_dataset_whatever{showbtxdatasetauthors}}
+
+\tolerant\gdef\publ_show_dataset_whatever#1[#2]%
+ {\begingroup
+ \letdummyparameter\c!specification\currentbtxspecification
+ \setdummyparameter\c!dataset {\currentbtxdataset}%
+ \letdummyparameter\c!field \empty
+ \ifparameter#2\or
+ \ifhastok={#2}%
+ \getdummyparameters[#2]%
+ \else
+ \setdummyparameter\c!dataset{#2}%
+ \fi
+ \fi
+ \ctxcommand{#1{
+ dataset = "\dummyparameter\c!dataset",
+ specification = "\dummyparameter\c!specification",
+ field = "\dummyparameter\c!field",
+ }}%
+ \endgroup}
+
+\permanent\tolerant\protected\gdef\showbtxfields[#1]%
+ {\begingroup
+ \setdummyparameter\c!rotation{90}%
+ \ifparameter#1\or
+ \ifhastok={#1}%
+ \letdummyparameter\c!specification\currentbtxspecification
+ \getdummyparameters[#1]%
+ \else
+ \setdummyparameter\c!specification{#1}%
+ \fi
+ \else
+ \letdummyparameter\c!specification\currentbtxspecification
+ \fi
+ \ctxcommand{showbtxfields{
+ rotation = "\dummyparameter\c!rotation",
+ specification = "\dummyparameter\c!specification"
+ }}%
+ \endgroup}
+
+\permanent\tolerant\protected\gdef\showbtxtables[#1]%
+ {\begingroup
+ \ctxcommand{showbtxtables{}}%
+ \endgroup}
+
+\permanent\tolerant\protected\gdef\showbtxhashedauthors[#1]%
+ {\ctxcommand{showbtxhashedauthors{}}}
+
+\protect
+
+\continueifinputfile{publ-tra.mkiv}
+
+\starttext
+
+ \showbtxfields[rotation=85] \page
+ \showbtxfields[rotation=90] \page
+
+ \showbtxtables \page
+
+\stoptext
diff --git a/tex/context/base/mkiv/publ-usr.mkiv b/tex/context/base/mkiv/publ-usr.mkiv
deleted file mode 100644
index cb078f424..000000000
--- a/tex/context/base/mkiv/publ-usr.mkiv
+++ /dev/null
@@ -1,2 +0,0 @@
-% todo
-
diff --git a/tex/context/base/mkiv/publ-xml.mkxl b/tex/context/base/mkiv/publ-xml.mkxl
new file mode 100644
index 000000000..925ccff1a
--- /dev/null
+++ b/tex/context/base/mkiv/publ-xml.mkxl
@@ -0,0 +1,111 @@
+%D \module
+%D [ file=publ-xml,
+%D version=2013.12.24,
+%D title=\CONTEXT\ Publication Support,
+%D subtitle=XML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Publication Support / XML}
+
+\unprotect
+
+\permanent\tolerant\protected\def\convertbtxdatasettoxml[#1]%
+ {\clf_convertbtxdatasettoxml{\ifparameter\or#1\else\s!default\fi}} % or current when not empty
+
+% \startxmlsetups btx:initialize
+% \xmlregistereddocumentsetups{#1}{}
+% \xmlsetsetup{#1}{bibtex|entry|field}{btx:*}
+% \xmlmain{#1}
+% \stopxmlsetups
+
+\startxmlsetups btx:initialize
+ \xmlsetsetup{#1}{bibtex|entry|field}{btx:*}
+ \xmlmain{#1}
+\stopxmlsetups
+
+% \startxmlsetups btx:entry
+% \xmlflush{#1}
+% \stopxmlsetups
+
+\startxmlsetups btx:field
+ \xmlflushcontext{#1}
+\stopxmlsetups
+
+\protect \endinput
+
+% \startxmlsetups bibtex:entry:getkeys
+% \xmladdsortentry{bibtex}{#1}{\xmlfilter{#1}{/field[@name='author']/text()}}
+% \xmladdsortentry{bibtex}{#1}{\xmlfilter{#1}{/field[@name='year' ]/text()}}
+% \xmladdsortentry{bibtex}{#1}{\xmlatt{#1}{tag}}
+% \stopxmlsetups
+
+% \startbuffer
+% \startxmlsetups xml:bibtex:sorter
+% \xmlresetsorter{bibtex}
+% % \xmlfilter{#1}{entry/command(bibtex:entry:getkeys)}
+% \xmlfilter{#1}{
+% bibtex
+% /entry[@category='article']
+% /field[@name='author' and find(text(),'Knuth')]
+% /../command(bibtex:entry:getkeys)}
+% \xmlsortentries{bibtex}
+% \xmlflushsorter{bibtex}{bibtex:entry:flush}
+% \stopxmlsetups
+% \stopbuffer
+
+% \bgroup
+% \setups[bibtex-commands]
+% \getbuffer
+% \egroup
+
+% \startxmlsetups bibtex:entry:flush
+% \xmlfilter{#1}{/field[@name='author']/context()} / %
+% \xmlfilter{#1}{/field[@name='year' ]/context()} / %
+% \xmlatt{#1}{tag}\par
+% \stopxmlsetups
+
+% \startpacked
+% \getbuffer
+% \stoppacked
+
+
+% \unexpanded\def\btx_xml_list_handle_entry
+% {\begingroup
+% \ignorespaces
+% \xmlfilter{btx:\currentbtxrendering}{/bibtex/entry[@tag='\currentbtxtag']/command(btx:format)}%
+% \removeunwantedspaces
+% \endgroup}
+
+% \startxmlsetups btx:format
+% \btxlistparameter\c!before\relax % prevents lookahead
+% \edef\currentbibxmlnode {#1}
+% \edef\currentbibxmltag {\xmlatt{#1}{tag}}
+% \edef\currentbtxcategory{\xmlatt{#1}{category}}
+% \ignorespaces
+% \xmlcommand{#1}{.}{btx:\currentbtxformat:\currentbibxmlcategory}
+% \removeunwantedspaces
+% \btxlistparameter\c!after\relax % prevents lookahead
+% \stopxmlsetups
+
+% \startxmlsetups btx:list
+% \xmlfilter{#1}{/bibtex/entry/command(bibtex:format)}
+% \stopxmlsetups
+
+% \startxmlsetups btx:btx
+% \xmlfilter{#1}{/entry/command(btx:format)}
+% \stopxmlsetups
+
+% \unexpanded\def\btx_xml_doifelse#1{\xmldoifelse\currentbibxmlnode{/field[@name='#1']}}
+% \unexpanded\def\btx_xml_doif #1{\xmldoif \currentbibxmlnode{/field[@name='#1']}}
+% \unexpanded\def\btx_xml_doifnot #1{\xmldoifnot \currentbibxmlnode{/field[@name='#1']}}
+% \def\btx_xml_flush #1{\xmlcontext \currentbibxmlnode{/field[@name='#1']}}
+% \def\btx_xml_setup {\xmlsetup \currentbibxmlnode} % {#1}
+% \unexpanded\def\btx_xml_todo #1{[#1]}
+
+% \xmlfilter{#1}{/field[@name='\currentbtxfield']/btxconcat('\currentbtxfield')}
diff --git a/tex/context/base/mkiv/spac-hor.mkxl b/tex/context/base/mkiv/spac-hor.mkxl
index 54f360d83..f6fb41ea8 100644
--- a/tex/context/base/mkiv/spac-hor.mkxl
+++ b/tex/context/base/mkiv/spac-hor.mkxl
@@ -530,14 +530,14 @@
\enforced\let\ \space
\to \everysimplifycommands
-\newsignal\s_spac_keep_unwanted_space
+\newsignal\d_spac_keep_unwanted_space_signal
% \parindentmode\plusone
\permanent\protected\def\keepunwantedspaces
{\ifhmode
- \ifdim\lastskip=\s_spac_keep_unwanted_space\else
- \hskip\s_spac_keep_unwanted_space\relax
+ \ifdim\lastskip=\d_spac_keep_unwanted_space_signal\else
+ \hskip\d_spac_keep_unwanted_space_signal\relax
\fi
\fi}
@@ -550,7 +550,7 @@
{\ifnum\lastnodetype=\gluenodecode\relax
\ifnum\lastnodesubtype=\indentskipsubtypecode\relax
% keep parindent
- \orelse\ifdim\lastskip=\s_spac_keep_unwanted_space\relax
+ \orelse\ifdim\lastskip=\d_spac_keep_unwanted_space_signal\relax
\unskip
\else
\unskip
@@ -1222,13 +1222,13 @@
%D \oeps}
%D \stoptyping
-\newsignal\s_spac_ignore_spaces
+\newsignal\d_spac_ignore_spaces_signal
\newcount \c_spac_ignore_spaces
\protected\def\startignorespaces
{\advance\c_spac_ignore_spaces\plusone
\ifcase\c_spac_ignore_spaces\or \ifhmode
- \hskip\s_spac_ignore_spaces
+ \hskip\d_spac_ignore_spaces_signal
\fi \fi
\ignorespaces}
@@ -1243,7 +1243,7 @@
\def\spac_ignore_spaces_body
{\ifzeropt\lastskip
\exitloop
- \orelse\ifdim\lastskip=\s_spac_ignore_spaces
+ \orelse\ifdim\lastskip=\d_spac_ignore_spaces_signal
\unskip
\exitloop
\else
diff --git a/tex/context/base/mkiv/spac-lin.mkiv b/tex/context/base/mkiv/spac-lin.mkiv
index 3d54b630a..aaa73d194 100644
--- a/tex/context/base/mkiv/spac-lin.mkiv
+++ b/tex/context/base/mkiv/spac-lin.mkiv
@@ -146,7 +146,7 @@
%
\ignorespaces
\glet\spac_after_first_obeyed_line\spac_lines_after_first_obeyed_line_a
- \let\obeyedline\spac_lines_obeyed_line
+ \enforced\let\obeyedline\spac_lines_obeyed_line
\activatespacehandler{\linesparameter\c!space}%
\dostarttagged\t!line\empty
\ignorepars}
diff --git a/tex/context/base/mkiv/spac-ver.mkxl b/tex/context/base/mkiv/spac-ver.mkxl
index fd9b5d7dd..786dd6044 100644
--- a/tex/context/base/mkiv/spac-ver.mkxl
+++ b/tex/context/base/mkiv/spac-ver.mkxl
@@ -1167,7 +1167,7 @@
\permanent\protected\def\rightboundary {\protrusionboundary\plustwo}
\permanent\protected\def\signalcharacter{\boundary\plusone\char\zerocount\boundary\plustwo} % not the same as strut signals
-\newsignal\strutsignal \setfalse\sigstruts
+\newsignal\d_spac_struts_signal \setfalse\sigstruts
\permanent\protected\def\begstrut
{\relax\ifcase\strutht
@@ -1187,8 +1187,8 @@
\def\spac_struts_beg_signal
{\noindent\horizontalstrut
\penalty\plustenthousand
- \hskip-\strutsignal
- \hskip\strutsignal}
+ \hskip-\d_spac_struts_signal
+ \hskip\d_spac_struts_signal}
\def\spac_struts_beg_normal
{\boundary\plusone
@@ -1215,7 +1215,7 @@
\fi}
\def\spac_struts_end_signal
- {\ifdim\lastskip=\strutsignal
+ {\ifdim\lastskip=\d_spac_struts_signal
\unskip
\unskip
\unpenalty
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index df60b4a67..ab1d3a038 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index fc2245599..21b55a433 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-lst.mkvi b/tex/context/base/mkiv/strc-lst.mkvi
index 7a593878c..e3a466656 100644
--- a/tex/context/base/mkiv/strc-lst.mkvi
+++ b/tex/context/base/mkiv/strc-lst.mkvi
@@ -417,8 +417,8 @@
\def\rawstructurelistuservariable#name%
{\clf_listuserdata{\currentlist}\currentlistindex{#name}}
-\unexpanded\def\structurelistfirst {\structurelistuservariable\s!first } % s!
-\unexpanded\def\structurelistsecond {\structurelistuservariable\s!second} % s!
+\unexpanded\def\structurelistfirst {\structurelistuservariable\s!first } % s!
+\unexpanded\def\structurelistsecond{\structurelistuservariable\s!second} % s!
\def\rawstructurelistfirst {\rawstructurelistuservariable\s!first } % s! % was \unexpanded
\def\rawstructurelistsecond{\rawstructurelistuservariable\s!second} % s! % was \unexpanded
diff --git a/tex/context/base/mkiv/strc-not.mklx b/tex/context/base/mkiv/strc-not.mklx
index 90302095c..dbdc1c26d 100644
--- a/tex/context/base/mkiv/strc-not.mklx
+++ b/tex/context/base/mkiv/strc-not.mklx
@@ -492,7 +492,7 @@
\ifconditional\c_strc_notes_skip
\global\setfalse\c_strc_notes_skip
\else
- \kern\notesignal\relax % \relax is needed to honor spaces
+ \kern\d_strc_notes_signal\relax % \relax is needed to honor spaces
\fi}
%D Interaction in notes is somewhat complex due to the way notes get flushed. In
@@ -691,7 +691,7 @@
\removeunwantedspaces
\doifelseitalic\/\donothing % Charles IV \footnote{the fourth}
\fi
- \ifdim\lastkern=\notesignal
+ \ifdim\lastkern=\d_strc_notes_signal
% \kern\noteparameter\c!distance % yes or no note font? or main text
\strc_notes_inject_separator
\fi
@@ -715,7 +715,7 @@
\protected\def\strc_notes_inject_dummy % temp hack
{\removeunwantedspaces
\doifelseitalic\/\donothing % Charles IV \footnote{the fourth}
- \ifdim\lastkern=\notesignal
+ \ifdim\lastkern=\d_strc_notes_signal
% \kern\noteparameter\c!distance % yes or no note font? or main text
\strc_notes_inject_separator
\fi
@@ -1271,7 +1271,7 @@
\let\startpushnote\relax
\let\stoppushnote \relax
-\newsignal\notesignal
+\newsignal\d_strc_notes_signal
\newconditional\processingnote
\newconditional\postponednote
diff --git a/tex/context/base/mkiv/strc-reg.mkxl b/tex/context/base/mkiv/strc-reg.mkxl
new file mode 100644
index 000000000..31f73ca69
--- /dev/null
+++ b/tex/context/base/mkiv/strc-reg.mkxl
@@ -0,0 +1,1207 @@
+%D \module
+%D [ file=strc-reg,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Registers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Structure Macros / Registers}
+
+\registerctxluafile{strc-reg}{}
+
+\unprotect
+
+\startcontextdefinitioncode
+
+% todo: tag:: becomes rendering
+% todo: language, character, linked, location
+% todo: fonts etc at sublevels (already defined)
+
+% \starttext
+% \placeregister[index]
+% \chapter{a} \index{93} \index{456} \index{***} \index{*} \index{@}
+% test \index{aa} test \startregister[index][x]{bb} test \page test \page test \page test \stopregister[index][x]
+% test \index{aa} test \setregisterentry[index][label=x,entries=bb] test \page test \page test \page test \finishregisterentry[index][label=x]
+% test \index{aa} test \setregisterentry[index][label=y] test \page test \page test \page test \finishregisterentry[index][label=y,entries=yy]
+% \stoptext
+
+% \index {entry}
+% \index[key] {entry}
+% \index[pageclass::] {entry}
+% \index[pageclass::key]{entry}
+% \index {textclass::entry}
+% \index[key] {textclass::entry}
+% \index[pageclass::] {textclass::entry}
+% \index[pageclass::key]{textclass::entry}
+
+% tzt variant with n entries, parameters and userdata (altnum)
+
+\installcorenamespace{register}
+
+\installcommandhandler\??register {register} \??register
+
+\aliased\let\strc_registers_setup_saved\setupregister
+
+% maybe we should drop the plural form
+
+\permanent\tolerant\protected\overloaded\def\setupregister[#1]#*[#2]#*[#3]%
+ {\ifarguments\or
+ \strc_registers_setup_saved[#1]%
+ \or
+ \strc_registers_setup_saved[#1][#2]%
+ \or
+ \def\strc_registers_setup_step##1{\strc_registers_setup_saved[#1:##1][#3]}%
+ \processcommalist[#2]\strc_registers_setup_step
+ \fi}
+
+\permanent\tolerant\protected\def\setupregisters[#1]%
+ {\strc_registers_setup_saved[#1]\relax}
+
+\setupregister
+ [\c!n=2,
+ \c!balance=\v!yes, % \v!no komt niet zo vaak voor
+ \c!align=\v!flushleft,
+ \c!tolerance=\v!stretch,
+ \c!before=\blank,
+ %\c!after=,
+ %\c!symbol=,
+ \c!compress=\v!no,
+ \c!interaction=\v!pagenumber,
+ \c!alternative=\v!a,
+ \c!distance=\emwidth,
+ \c!style=\v!bold,
+ \c!pagestyle=\v!slanted,
+ \c!indicator=\v!yes,
+ \c!criterium=\v!all,
+ \c!check=\v!yes, % check for weird see usage
+ %\c!command=,
+ \c!referencing=\v!on,
+ \c!location=\v!middle,
+ %\c!maxwidth=,
+ \c!number=\v!no,
+ \c!unknownreference=\v!empty,
+ \c!prefix=\v!both,
+ %\c!expansion=,
+ %\c!xmlsetup=,
+ \c!pagenumber=\v!yes,
+ \c!pageprefixconnector=\endash,
+ \c!pagesegments=2:2,
+ \c!file=\jobname,
+ %\c!deeptextcommand=, % undefined by default !
+ \c!method=, % no default as we have them in the module, maybe some day in lang-*
+ \c!numberorder=\v!numbers, % \v!characters
+ \s!language=\currentmainlanguage]%
+
+% yes or no shared ?
+
+\setupregister
+ [\c!label=,
+ \c!entries=,
+ \c!alternative=]
+
+\definemixedcolumns
+ [\v!register]
+ [\c!n=\registerparameter\c!n,
+ \c!balance=\registerparameter\c!balance,
+ \c!align=\registerparameter\c!align,
+ \c!tolerance=\registerparameter\c!tolerance]
+
+%D \starttyping
+%D \setupregister[index][1][textcolor=darkred]
+%D \setupregister[index][2][textcolor=darkgreen,textstyle=bold]
+%D
+%D \placeregister[index][n=1] \blank[3*big]
+%D
+%D test \index{test+one} test \index{test+two} more \index{more}
+%D \stoptyping
+
+\newconditional\c_strc_registers_defining
+\setnewconstant\c_strc_registers_maxlevel \plusfive
+
+\ifdefined\Word \else \protected\def\Word#1{#1} \fi
+
+\appendtoks
+ \ifconditional\c_strc_registers_defining \else % todo: dosingle ...
+ \settrue\c_strc_registers_defining
+ \definemixedcolumns[\currentregister][\v!register]% first as otherwise it overloads start/stop
+ \clf_defineregister{\currentregister}{\registerparameter\c!referencemethod}%
+ \normalexpanded{\presetheadtext[\currentregister=\Word{\currentregister}]}%
+ \frozen\instance\setuevalue{\currentregister}{\strc_registers_insert_entry[\currentregister]}%
+ \frozen\instance\setuevalue{\e!see\currentregister}{\strc_registers_insert_see[\currentregister]}%
+ %frozen\instance\setuevalue{\e!coupled\currentregister}{\dolinkedregister{\currentregister}}%
+ % historic ballast
+ \frozen\instance\setuevalue{\e!place\currentregister}{\placeregister[\currentregister]}%
+ \frozen\instance\setuevalue{\e!complete\currentregister}{\completeregister[\currentregister]}%
+ \frozen\instance\setuevalue{\e!setup\currentregister\e!endsetup}{\setupregister[\currentregister]}%
+ \dorecurse\c_strc_registers_maxlevel{% weird, expanded should not be needed
+ \normalexpanded{\defineregister[\currentregister:\recurselevel][\currentregister]}%
+ %\defineregister[\currentregister:\recurselevel][\currentregister]%
+ \letregisterparameter{\c!entries:\recurselevel}\empty % needed as we use detokenize (ok, we can
+ \letregisterparameter{\c!keys :\recurselevel}\empty % avoid it, but it's faster too)
+ }%
+ %
+ \setfalse\c_strc_registers_defining
+ \fi
+\to \everydefineregister
+
+\appendtoks
+ \clf_setregistermethod{\currentregister}{\registerparameter\c!referencemethod}%
+\to \everysetupregister
+
+%D Registering:
+
+\glet\currentregistername \empty
+\glet\currentregisternumber\!!zerocount
+
+\def\strc_registers_register_page_entry
+ {\iftrialtypesetting
+ \expandafter\gobblethreearguments
+ \else
+ \expandafter\strc_registers_register_page_entry_indeed
+ \fi}
+
+\def\strc_registers_register_page_expand_xml_entries
+ {\xmlstartraw
+ \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
+ \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
+ \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
+ \xmlstopraw
+ \glet\currentregistercoding\s!xml}
+
+\def\strc_registers_register_page_expand_yes_entries
+ {\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
+ \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
+ \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
+ \glet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_nop_entries
+ {\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}%
+ \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}%
+ \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}%
+ \glet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_xml
+ {\xmlstartraw
+ \xdef\currentregisterentries{\registerparameter\c!entries}%
+ \xmlstopraw
+ \glet\currentregistercoding\s!xml}
+
+\def\strc_registers_register_page_expand_yes
+ {\xdef\currentregisterentries{\registerparameter\c!entries}%
+ \glet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_nop
+ {\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
+ \glet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_xml_keys
+ {\xmlstartraw
+ \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
+ \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
+ \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}%
+ \xmlstopraw}
+
+\def\strc_registers_register_page_expand_yes_keys
+ {\xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
+ \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
+ \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}}
+
+\def\strc_registers_register_page_entry_indeed#1#2#3% register data userdata
+ {\begingroup
+ \edef\currentregister{#1}%
+ %\setupcurrentregister[\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]%
+ \setupcurrentregister[#2]%
+ \edef\currentregisterlabel {\registerparameter\c!label}%
+ \edef\currentregisterexpansion{\registerparameter\c!expansion}%
+ \edef\currentregisterownnumber{\registerparameter\c!ownnumber}%
+ \xdef\currentregisterkeys {\registerparameter\c!keys}%
+ \xdef\currentregisterentries {\registerparameter\c!entries}%
+ \xdef\currentregisterxmlsetup {\registerparameter\c!xmlsetup}%
+ \ifempty\currentregisterentries
+ \ifx\currentregisterexpansion\s!xml
+ \strc_registers_register_page_expand_xml_entries
+ \orelse\ifx\currentregisterexpansion\v!yes
+ \strc_registers_register_page_expand_yes_entries
+ \else
+ \strc_registers_register_page_expand_nop_entries
+ \fi
+ \else
+ \ifx\currentregisterexpansion\s!xml
+ \strc_registers_register_page_expand_xml
+ \orelse\ifx\currentregisterexpansion\v!yes
+ \strc_registers_register_page_expand_yes
+ \else
+ \strc_registers_register_page_expand_nop
+ \fi
+ \fi
+ \ifempty\currentregisterkeys
+ \ifx\currentregistercoding\s!xml
+ \strc_registers_register_page_expand_xml_keys
+ \else
+ \strc_registers_register_page_expand_yes_keys
+ \fi
+ \fi
+ \setnextinternalreference
+ % we could consider storing register entries in a list which we
+ % could then sort
+ \glet\currentregistername\currentregister
+ \xdef\currentregisternumber{\clf_storeregister % 'own' should not be in metadata
+ metadata {%
+ name {\currentregister}%
+ coding {\currentregistercoding}%
+ \ifx\currentregisterownnumber\v!yes
+ own {\registerparameter\c!alternative}% can be used instead of pagenumber
+ \fi
+ \ifx\currentreferencecoding\s!xml
+ xmlroot {\xmldocument} % only useful when text
+ \fi
+ \ifempty\currentregisterxmlsetup \else
+ xmlsetup {\currentregisterxmlsetup}%
+ \fi
+ }%
+ references {%
+ \ifempty\currentregisterlabel \else
+ label {\currentregisterlabel}%
+ \fi
+% view {\interactionparameter\c!focus}%
+ }%
+ entries {%
+ % we need a special one for xml, this is just a single one
+ \ifempty\currentregisterentries
+ entries {
+ {\currentregisterentriesa}%
+ {\currentregisterentriesb}%
+ {\currentregisterentriesc}%
+ }
+ \else
+ entry {\currentregisterentries}%
+ \fi
+ \ifempty\currentregisterkeys
+ keys {
+ {\currentregisterkeysa}%
+ {\currentregisterkeysb}%
+ {\currentregisterkeysc}%
+ }
+ \else
+ key {\currentregisterkeys}%
+ \fi
+ }%
+ userdata {\detokenize\expandafter{\normalexpanded{#3}}}
+ }%
+ \clf_setinternalreference
+ internal \locationcount
+ view {\interactionparameter\c!focus}%
+ \relax % this will change
+ \ifx\currentregisterownnumber\v!yes
+ \glet\currentregistersynchronize\relax
+ \else
+ \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}%
+ \fi
+ \currentregistersynchronize % here?
+ % needs thinking ... bla\index{bla}. will break before the . but adding a
+ % penalty is also no solution
+ \dostarttagged\t!registerlocation\currentregister
+ \c_attr_destination\lastdestinationattribute
+ \signalcharacter % no \strut as it will be removed during cleanup
+ \dotagregisterlocation
+ \dostoptagged
+ \endgroup}
+
+\permanent\protected\def\dosetfastregisterentry#1#2#3#4#5% register entry key processor processor
+ {\begingroup
+ \edef\currentregister{#1}%
+ \setnextinternalreference
+ \glet\currentregistername\currentregister
+ \xdef\currentregisternumber{\clf_storeregister
+ {%
+ metadata {%
+ name {\currentregister}%
+ }
+ entries {%
+ entry {#2}%
+ key {#3}%
+ }%
+ processors {%
+ entry {#4}%
+ page {#5}%
+ }%
+ }%
+ }%
+ % overlap with the above
+ % \clf_setinternalreference
+ % internal \locationcount
+ % view {\interactionparameter\c!focus}%
+ \relax % this will change
+ \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}%
+ \currentregistersynchronize % here?
+ \dostarttagged\t!registerlocation\currentregister
+ \c_attr_destination\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup
+ \dotagregisterlocation
+ \dostoptagged
+ \endgroup}
+
+\let\dotagregisterlocation\relax % experiment
+
+\tolerant\protected\def\strc_registers_insert_entry[#1]#*[#2]%
+ {\def\currentregister{#1}%
+ \edef\p_ownnumber{\registerparameter\c!ownnumber}%
+ \ifx\p_ownnumber\v!yes
+ \expandafter\strc_registers_insert_entry_yes
+ \else
+ \expandafter\strc_registers_insert_entry_nop
+ \fi{#2}}
+
+% \def\strc_registers_insert_entry_nop#1#2%
+% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
+%
+% \def\strc_registers_insert_entry_yes#1#2#3%
+% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
+%
+% less tokens passed (nicer for tracing) .. could become installable
+
+\def\strc_registers_insert_entry_nop
+ {\ifvmode
+ \expandafter\strc_registers_insert_entry_nop_par
+ \else
+ \expandafter\strc_registers_insert_entry_nop_txt
+ \fi}
+
+\def\strc_registers_insert_entry_yes
+ {\ifvmode
+ \expandafter\strc_registers_insert_entry_yes_par
+ \else
+ \expandafter\strc_registers_insert_entry_yes_txt
+ \fi}
+
+\def\strc_registers_insert_entry_nop_par#1#2%
+ {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
+
+\def\strc_registers_insert_entry_yes_par#1#2#3%
+ {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
+
+\def\strc_registers_insert_entry_nop_txt#1#2%
+ {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}
+
+\def\strc_registers_insert_entry_yes_txt#1#2#3%
+ {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}
+
+%D This is one of the few commands where a stop has arguments.
+
+\permanent\tolerant\protected\def\startregister[#1]#*[#2]#*[#3]#*[#4]#*#:#5%
+ {\ifparameter#4\or
+ % #1=register #2=tag #3=own #4=sortkey #5=entry
+ \doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,\c!alternative=#3,\c!keys={#4},\c!entries={#5}}{}}%
+ \else
+ % #1=register #2=tag #3=sortkey #5=entry
+ \doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,\c!keys={#3},\c!entries={#5}}{}}%
+ \fi}
+
+\permanent\tolerant\protected\def\stopregister[#1]#*[#2]%
+ {\normalexpanded{\ctxlatecommand{extendregister("#1","#2")}}}
+
+% a synonym, so that we can nest with overlap without syntax check problems
+
+\aliased\let\openregisterrange \startregister
+\aliased\let\closeregisterrange\stopregister
+
+% not yet document, not sure if this will stay:
+
+\permanent\tolerant\protected\def\setregisterentry[#1]#*[#2]#*[#3]%
+ {\doflushatpar{\strc_registers_register_page_entry{#1}{#2}{#3}}}
+
+\permanent\tolerant\protected\def\finishregisterentry[#1]#*[#2]#*[#3]%
+ {\strc_registers_finish_entry_indeed{#1}{#2}{#3}}
+
+\def\strc_registers_finish_entry_indeed#1#2#3% register data userdata
+ {\begingroup
+ \edef\currentregister{#1}%
+ %\setupcurrentregister[\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% todo: fast setter
+ \resetregisterparameter\c!entries
+ \resetregisterparameter\c!label
+ \resetregisterparameter\c!keys
+ \resetregisterparameter\c!alternative
+ \setupcurrentregister[#2]%
+ \edef\currentregisterlabel {\registerparameter\c!label}%
+ \edef\currentregisterexpansion{\registerparameter\c!expansion}%
+ \edef\currentregisterownnumber{\registerparameter\c!ownnumber}%
+ \xdef\currentregisterkeys {\registerparameter\c!keys}%
+ \ifx\currentregisterexpansion\s!xml
+ \xmlstartraw
+ \xdef\currentregisterentries{\registerparameter\c!entries}%
+ \xmlstopraw
+ \glet\currentregistercoding\s!xml
+ \else
+ \ifx\currentregisterexpansion\v!yes
+ \xdef\currentregisterentries{\registerparameter\c!entries}%
+ \else
+ \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
+ \fi
+ \glet\currentregistercoding\s!tex
+ \fi
+ % I hate this kind of mess ... but it's a user request.
+ \ifempty\currentregisterentries
+ \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", {
+ metadata = {
+ \ifx\currentregisterownnumber\v!yes
+ own = "\registerparameter\c!alternative", % can be used instead of pagenumber
+ \fi
+ },
+ userdata = \!!bs\detokenize{#3}\!!es
+ })%
+ }}%
+ \else
+ \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", {
+ metadata = {
+ % catcodes = \the\catcodetable,
+ coding = "\currentregistercoding",
+ \ifx\currentregisterownnumber\v!yes
+ own = "\registerparameter\c!alternative", % can be used instead of pagenumber
+ \fi
+ },
+ entries = {
+ % we need a special one for xml, this is just a single one
+ \!!bs\currentregisterentries\!!es,
+ \!!bs\currentregisterkeys\!!es
+ },
+ userdata = \!!bs\detokenize{#3}\!!es
+ })
+ }}%
+ \fi
+ \endgroup}
+
+% The following variants are meant for (for instance xml). There is some
+% overlap with previously defined macros.
+%
+% \starttext
+% \setstructurepageregister[index][entries=alpha]a
+% \setstructurepageregister[index][entries=gamma]g
+% \setstructurepageregister[index][entries=beta]b
+% \setstructurepageregister[index][entries:1=alpha,keys:1=z]a
+% \setstructurepageregister[index][entries:1=gamma,keys:1=x]g
+% \setstructurepageregister[index][entries:1=beta, keys:1=y]b
+% \index{alpha}a
+% \index{gamma}g
+% \index{beta}b
+% \placeregister[index][n=1]
+% \stoptext
+
+% some overlap with previous
+
+\permanent\tolerant\protected\def\setstructurepageregister[#1]#*[#2]#*[#3]% [register][settings][userdata]
+ {\doflushatpar{\strc_registers_register_page_entry{#1}{#2}{#3}}}
+
+\permanent\tolerant\protected\def\startstructurepageregister[#1]#*[#2]#*[#3]#*[#4]% [register][tag][settings][userdata]
+ {\doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,#3}{#4}}}
+
+\permanent\tolerant\protected\def\stopstructurepageregister[#1]#*[#2]%
+ {\normalexpanded{\ctxlatecommand{structures.registers.extend("#1","#2")}}}
+
+\let\openstructurepageregisterrange \startstructurepageregister
+\let\closestructurepageregisterrange\stopstructurepageregister
+
+% So far.
+
+\tolerant\protected\def\strc_registers_insert_see[#1]#*[#2]#*#:#3#4%
+ {\doflushatpar{\strc_registers_insert_see_indeed{#1}{#2}{#3}{#4}}}
+
+\def\strc_registers_insert_see_indeed#1#2#3#4% register key entry seeword
+ {\begingroup
+ \edef\currentregister{#1}%
+ \edef\currentregisterexpansion{\registerparameter\c!expansion}%
+ \ifx\currentregisterexpansion\s!xml
+ \xmlstartraw
+ \xdef\currentregisterentries{\detokenize{#3}}% not ok yet
+ \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
+ \xmlstopraw
+ \glet\currentregistercoding\s!xml
+ \else
+ \ifx\currentregisterexpansion\v!yes
+ \xdef\currentregisterentries{#3}% not ok yet
+ \xdef\currentregisterseeword{#4}% not ok yet
+ \else
+ \xdef\currentregisterentries{\detokenize{#3}}% not ok yet
+ \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
+ \fi
+ \glet\currentregistercoding\s!tex
+ \fi
+ \setnextinternalreference
+ % we could consider storing register entries in list
+ \edef\temp{\clf_storeregister{% \temp grabs the nofentries
+ metadata {%
+ kind {see}%
+ name {\currentregister}%
+ }%
+ references {%
+% view {\interactionparameter\c!focus}%
+ }%
+ entries {%
+ % we need a special one for xml, this is just a single one
+ entry {\currentregisterentries}%
+ key {#2}%
+ }%
+ seeword {%
+ text {\currentregisterseeword}%
+ }%
+ }}%
+ \clf_setinternalreference
+ internal \locationcount
+ view {\interactionparameter\c!focus}%
+ \relax % this will change
+ \dostarttagged\t!registerlocation\currentregister
+ \c_attr_destination\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup
+ \dotagregisterlocation
+ \dostoptagged
+ \endgroup}
+
+%D Rendering:
+
+% todo: c!language ipv s!language
+
+\let\utilityregisterlength\!!zerocount
+
+\permanent\tolerant\protected\def\determineregistercharacteristics[#1]#*[#2]%
+ {\begingroup
+ \setupregister[#1][#2]%
+ \edef\currentregister{\firstinset{#1}}%
+ \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\clf_analyzeregister
+ {\currentregister}%
+ {%
+ language {\registerparameter\s!language}%
+ method {\registerparameter\c!method}%
+ numberorder {\registerparameter\c!numberorder}%
+ compress {\registerparameter\c!compress}%
+ criterium {\registerparameter\c!criterium}%
+ pagenumber \ifempty\registerpageseparatorsymbol false\else true\fi
+ }%
+ }}%
+ \ifcase\utilityregisterlength\relax
+ \resetsystemmode\v!register
+ \else
+ \setsystemmode \v!register
+ \fi}
+
+\newtoks\everyplaceregister
+
+\appendtoks
+ \dontcomplain
+\to \everyplaceregister
+
+\newconditional\c_strc_registers_text_interaction
+
+\permanent\tolerant\protected\def\placeregister[#1]#*[#2]%
+ {\ifarguments\else
+ \begingroup
+ %\forgetall
+ \setupregister[#1][#2]% can be a list
+ \edef\currentregister{\firstinset{#1}}%
+ \the\everyplaceregister
+ \ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone
+ \startmixedcolumns[\currentregister]%
+ \strc_registers_place_indeed{#1}%
+ \stopmixedcolumns
+ \else
+ \strc_registers_place_indeed{#1}%
+ \fi
+ \endgroup
+ \fi}
+
+\def\strc_registers_place_indeed#1%
+ {\doifelse{\registerparameter\c!interaction}\v!text
+ \settrue\setfalse\c_strc_registers_text_interaction
+ \clf_processregister
+ {#1}%
+ {%
+ language {\registerparameter\s!language}%
+ method {\registerparameter\c!method}%
+ numberorder {\registerparameter\c!numberorder}%
+ check {\registerparameter\c!check}%
+ compress {\registerparameter\c!compress}%
+ criterium {\registerparameter\c!criterium}%
+ pagemethod {\registerparameter\c!pagemethod}%
+ pagenumber \ifempty\registerpageseparatorsymbol false\else true\fi
+ }{%
+ separatorset {\registerparameter\c!pageprefixseparatorset}%
+ conversionset {\registerparameter\c!pageprefixconversionset}%
+ starter {\registerparameter\c!pageprefixstarter}%
+ stopper {\registerparameter\c!pageprefixstopper}%
+ set {\registerparameter\c!pageprefixset}%
+ segments {\registerparameter\c!pageprefixsegments}%
+ connector {\registerparameter\c!pageprefixconnector}%
+ }{%
+ prefix {\registerparameter\c!pageprefix}%
+ separatorset {\registerparameter\c!pageseparatorset}%
+ conversionset {\registerparameter\c!pageconversionset}%
+ starter {\registerparameter\c!pagestarter}%
+ stopper {\registerparameter\c!pagestopper}%
+ segments {\registerparameter\c!pagesegments}%
+ }%
+ \relax}
+
+\def\strc_registers_limited_entry#1%
+ {\limitatetext{#1}\currentregistermaxwidth\unknown}%
+
+\aliased\let\limitedregisterentry\firstofoneargument
+
+\appendtoks
+ \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}%
+ \ifempty\currentregistermaxwidth
+ \enforced\let\limitedregisterentry\firstofoneargument
+ \else
+ \enforced\let\limitedregisterentry\strc_registers_limited_entry
+ \fi
+\to \everyplaceregister
+
+\permanent\tolerant\protected\def\completeregister[#1]#*[#2]%
+ {\ifarguments\or
+ \begingroup
+ \edef\currentregister{\firstinset{#1}}%
+ \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\currentregister}},reference=\currentregister]}%
+ \placeregister[#1][#2]%
+ \page[\v!yes]%
+ \stopnamedsection
+ \endgroup
+ \fi}
+
+% test case for collapsing (experimental, for Steffen Wolfrum)
+%
+% \starttext
+% \placeregister[index][compress=no] \blank[2*big]
+% \placeregister[index][compress=yes] \blank[2*big]
+% \placeregister[index][compress=all] \page
+% \dorecurse{10}{test 1:!\index{test} test \page}
+% \dorecurse{5} {test 2:\recurselevel \page}
+% \dorecurse{10}{test 3:!\index{test} test \page}
+% \dorecurse{5} {test 4:\recurselevel \page}
+% \dorecurse{1} {test 5:!\index{test} test \page}
+% \dorecurse{5} {test 6:\recurselevel \page}
+% \dorecurse{10}{test 7:!\index{test} test \page}
+% \dorecurse{5} {test 8:\recurselevel \page}
+% oeps \index{oeps}
+% xxxx \index{xxxx}
+% todo \index{todo}
+% \stoptext
+
+%D Character rendering (sections):
+
+\installcorenamespace{registerindicator}
+
+\permanent\def\defaultregistercharacter#1%
+ {\edef\currentregistercharacter{#1}%
+ \ifempty\currentregistercharacter
+ % skip
+ \orelse\ifx\currentregistercharacter\s!unknown
+ % skip
+ \else
+ \edef\p_indicator{\registerparameter\c!indicator}%
+ \ifx\p_indicator\v!yes
+ \strc_registers_place_character_yes
+ \else
+ \strc_registers_place_character_nop
+ \fi
+ \fi}
+
+\def\strc_registers_place_character_yes
+ {\expandnamespaceparameter\??registerindicator\registerparameter\c!alternative\v!a{\currentregistercharacter}}
+
+\def\strc_registers_place_character_nop
+ {\registerparameter\c!before
+ \goodbreak}
+
+% a = <before> <goodbreak> <character> <par> <after> <nobreak>
+
+\def\strc_registers_indicator_a#1#2%
+ {\registerparameter\c!before
+ % bugged, why does leftskip gets set: \vskip\lineheight\goodbreak\vskip-\lineheight
+ \typo_injectors_check_register
+ \begingroup
+ \useregisterstyleandcolor\c!style\c!color
+ \dontleavehmode
+ \typo_injectors_mark_register
+ \strut
+ \iflocation
+ \dosetdirectpagereference{\currentregister:\v!section:#1}%
+ \fi
+ \registerparameter\c!command{#2}%
+ \endgroup
+ \blank[\v!samepage]%
+ \registerparameter\c!after
+ \par
+ \nobreak}
+
+% b = <goodbreak> <before> <character> <after> <nobreak>
+
+\def\strc_registers_indicator_b#1#2%
+ {\registerparameter\c!before
+ \typo_injectors_check_register
+ \begingroup
+ \useregisterstyleandcolor\c!style\c!color
+ \dontleavehmode
+ \typo_injectors_mark_register
+ \strut
+ \iflocation
+ \dosetdirectpagereference{\currentregister:\v!section:#1}%
+ \fi
+ \registerparameter\c!command{#2}%
+ \endgroup
+ \registerparameter\c!after
+ \nobreak}
+
+\setvalue{\??registerindicator a}#1{\strc_registers_indicator_a{#1}{#1}}
+\setvalue{\??registerindicator A}#1{\strc_registers_indicator_a{#1}{\WORD{#1}}}
+\setvalue{\??registerindicator b}#1{\strc_registers_indicator_b{#1}{#1}}
+\setvalue{\??registerindicator B}#1{\strc_registers_indicator_b{#1}{\WORD{#1}}}
+
+%D The following macros are the interface to the rendering. These are
+%D generated by \LUA. This might change.
+
+% \showinjector
+% \setinjector[register][2][\column]
+%
+% \starttext
+% first \index{first}
+% second \index{second}
+% third \index{third}
+% fourth \index{fourth}
+% \placeregister[index]
+% \stoptext
+
+\doinstallinjector\s!register
+
+%D Beware, we get funny side effects when a dangling \index precedes an
+%D placeindex as then flushing takes place inside the index. Took me hours
+%D to notice that.
+
+\newconstant\c_strc_registers_page_state % 0=nothing 1=page 2=see
+\newdimen \d_strc_registers_distance
+
+\permanent\protected\def\startregisteroutput
+ {\endgraf
+ \begingroup
+ \d_strc_registers_distance\registerparameter\c!distance\relax
+ \dostarttaggedchained\t!register\currentregister\??register
+ \forgeteverypar
+ \forgetparindent
+ \forgetparskip}
+
+\permanent\protected\def\stopregisteroutput
+ {\endgraf
+ \dostoptagged
+ \endgroup}
+
+\newdimen\d_strc_registers_hangindent
+\newcount\c_strc_registers_hangafter
+
+\permanent\protected\def\usenestedregisterstyleandcolor#1#2% will change
+ {\useregisterstyleandcolor#1#2%
+ % how about style
+ \ifconditional\c_strc_registers_text_interaction
+ \ifempty\currentcolorparameter \else
+ \resetinteractionparameter\c!color
+ \resetinteractionparameter\c!contrastcolor
+ \fi
+ \fi}
+
+\permanent\protected\def\startregisterentries#1% depth
+ {\endgraf
+ \begingroup
+ \scratchcounter\ifnum#1>\c_strc_registers_maxlevel\c_strc_registers_maxlevel\else#1\fi\relax
+ \dostarttagged\t!registerentries\empty
+ \let\savedcurrentregister\currentregister
+ \edef\currentregister{\currentregister:\number\scratchcounter}%
+ \usenestedregisterstyleandcolor\c!textstyle\c!textcolor
+ \ifnum\scratchcounter>\plusone
+ \advance\leftskip\d_strc_registers_distance\relax
+ \fi
+ \d_strc_registers_hangindent\registerparameter\c!distance\relax
+ \c_strc_registers_hangafter \plusone
+ \blank[\v!samepage]%
+ \let\currentregister\savedcurrentregister}
+
+\permanent\protected\def\stopregisterentries
+ {\endgraf
+ \dostoptagged
+ \endgroup}
+
+\permanent\protected\def\startregisterentry#1% todo: level
+ {\typo_injectors_check_register
+ \begingroup
+ \dostarttagged\t!registerentry\empty
+ \global\setconstant\c_strc_registers_page_state\zerocount
+ \hangindent\d_strc_registers_hangindent
+ \hangafter \c_strc_registers_hangafter
+ \typo_injectors_mark_register}
+
+\permanent\protected\def\stopregisterentry
+ {\endgraf
+ \global\setconstant\c_strc_registers_page_state\zerocount
+ \dostoptagged
+ \endgroup}
+
+\permanent\protected\def\startregistersection#1% title
+ {\dostarttagged\t!registersection\empty
+ \dostarttagged\t!registertag\empty
+ \registercharacter{#1}\endgraf
+ \dostoptagged}
+
+\permanent\protected\def\stopregistersection
+ {\dostoptagged
+ \endgraf}
+
+\permanent\protected\def\startregisterpages
+ {\begingroup
+ \dostarttagged\t!registerpages\empty
+ \useregisterstyleandcolor\c!pagestyle\c!pagecolor
+ \registerparameter\c!pageleft}
+
+\permanent\protected\def\stopregisterpages
+ {\registerparameter\c!pageright
+ \dostoptagged
+ \endgroup}
+
+\permanent\protected\def\startregisterseewords
+ {\begingroup
+ \dostarttagged\t!registerpage\empty
+ \useregisterstyleandcolor\c!pagestyle\c!pagecolor}
+
+\permanent\protected\def\stopregisterseewords
+ {\dostoptagged
+ \endgroup}
+
+\permanent\protected\def\registerpageseparator % todo: , configurable
+ {\ifcase\c_strc_registers_page_state
+ \hskip\d_strc_registers_distance\relax
+ \or
+ \dostarttagged\t!registerseparator\empty
+ \registerpageseparatorsymbol % page
+ \dostoptagged
+ \or
+ \dostarttagged\t!registerseparator\empty
+ \registerpageseparatorsymbol % see
+ \dostoptagged
+ \fi}
+
+\permanent\protected\def\registeronepagerangeseparator
+ {|\endash|} % todo use \prewordbreak
+
+% \protected\def\withregisterpagecommand#1#2#3#4%
+% {\def\currentregisterpageindex{#2}%
+% \iflocation
+% \goto{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]%
+% \else
+% \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}%
+% \fi}
+
+\permanent\protected\def\withregisterpagecommand#1#2#3#4%
+ {\ifcase#3\relax
+ {\tt [entry\space not\space flushed]}%
+ \else
+ \def\currentregisterpageindex{#2}%
+ \iflocation
+ \strc_references_goto_internal{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]%
+ \else
+ \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}%
+ \fi
+ \fi}
+
+\permanent\protected\def\pushcurrentregister#1%
+ {\let\m_current_register\currentregister
+ \edef\currentregister{#1}}
+
+\permanent\protected\def\popcurrentregister
+ {\let\currentregister\m_current_register}
+
+\permanent\protected\def\registeronepage#1#2#3#4#5% #1:class #2:processor content
+ {\pushcurrentregister{#1}%
+ \edef\p_pagenumber{\registerparameter\c!pagenumber}%
+ \ifx\p_pagenumber\v!no\else
+ \registerpageseparator
+ \global\setconstant\c_strc_registers_page_state\plusone
+ \dostarttagged\t!registerpage\empty
+ \withregisterpagecommand{#2}{#3}{#4}{#5}%
+ \dostoptagged
+ \fi
+ \popcurrentregister}
+
+\newconditional\c_strc_registers_following
+
+\appendtoks
+ \edef\p_compress{\registerparameter\c!compress}%
+ \ifx\p_compress\v!text
+ \settrue\c_strc_registers_following
+ \letregisterparameter\c!compress\v!yes
+ \else
+ \setfalse\c_strc_registers_following
+ \fi
+\to \everyplaceregister
+
+\permanent\protected\def\registerpagerange#1#2#3#4#5#6#7#8% #1:class #2:processor content, content todo: -- configurable
+ {\pushcurrentregister{#1}%
+ \edef\p_pagenumber{\registerparameter\c!pagenumber}%
+ \ifx\p_pagenumber\v!no\else
+ \registerpageseparator
+ \global\setconstant\c_strc_registers_page_state\plusone
+ \dostarttagged\t!registerpagerange\empty
+ \dostarttagged\t!registerfrompage\empty
+ \withregisterpagecommand{#2}{#3}{#4}{#5}%
+ \dostoptagged
+ \ifconditional\c_strc_registers_following
+ \ifnum#3=\numexpr#6-1\relax
+ \labeltext{following:\s!singular}%
+ \else
+ \labeltext{following:\s!plural}%
+ \fi
+ \else
+ \registeronepagerangeseparator
+ \dostarttagged\t!registertopage\empty
+ \withregisterpagecommand{#2}{#6}{#7}{#8}%
+ \fi
+ \dostoptagged
+ \dostoptagged
+ \fi
+ \popcurrentregister}
+
+\permanent\protected\def\defaultregisterentry#1#2#3#4#5% #1:class #2:processor #3:internal #4:seeindex #5:word
+ {\pushcurrentregister{#1}%
+ \def\currentregisterpageindex{#3}%
+ \iflocation
+ \def\currentregisterseeindex{#4}%
+ \ifconditional\c_strc_registers_text_interaction
+ \strc_references_goto_internal{\setlocationcolor\doapplyregisterentrycommand{#2}{#5}}[internal(#3)]%
+ \else
+ \doapplyregisterentrycommand{#2}{#5}%
+ \fi
+ \else
+ \let\currentregisterseeindex\empty
+ \doapplyregisterentrycommand{#2}{#5}%
+ \fi
+ \popcurrentregister}
+
+\permanent\protected\def\doapplyregisterentrycommand#1#2% processor text
+ {\dostarttagged\t!registercontent\empty
+ \ifempty\currentregisterseeindex \else
+ \dontleavehmode
+ \dosetdirectpagereference{seeindex:\currentregisterseeindex}% maybe some day we will support an area
+ \fi
+ \applyprocessor{#1}{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#2}}}}%
+ \dostoptagged}
+
+\permanent\protected\def\doapplyregisterseecommand#1#2%
+ {\ifempty\currentregisterseeindex
+ \applyprocessor{#1}{#2}%
+ \orelse\iflocation
+ \strc_references_goto_internal{\applyprocessor{#1}{#2}}[seeindex:\currentregisterseeindex]%
+ \else
+ \applyprocessor{#1}{#2}%
+ \fi}
+
+\permanent\protected\def\defaultregisterseeword#1#2#3#4#5#6#7% class i n #3:processor #4:internal #5:seeindex #6:word
+ {\pushcurrentregister{#1}%
+ \ifnum#2=\plusone
+ \registerpageseparator
+ \fi
+ \global\setconstant\c_strc_registers_page_state\plustwo
+ \def\currentregisterpageindex{#5}%
+ \dostarttagged\t!registersee\empty
+ \settrue\c_strc_registers_page_done
+ \iflocation
+ \def\currentregisterseeindex{#6}%
+ \else
+ \let\currentregisterseeindex\empty
+ \fi
+ \ifnum#2=\plusone
+ \labeltexts\v!see{\doapplyregisterseecommand{#4}{#7}}%
+ \orelse\ifnum#2=#3\relax
+ \labeltexts\v!and{\doapplyregisterseecommand{#4}{#7}}%
+ \else
+ ,\space\doapplyregisterseecommand{#4}{#7}%
+ \fi
+ \dostoptagged
+ \popcurrentregister}
+
+\permanent\protected\def\doapplyregistersectioncommand#1#2%
+ {\ifempty\currentregistersectionindex
+ \applyprocessor{#1}{#2}%
+ \orelse\iflocation
+ \strc_references_goto_internal{\applyprocessor{#1}{#2}}[sectionindex:\currentregistersectionindex]%
+ \else
+ \applyprocessor{#1}{#2}%
+ \fi}
+
+\permanent\protected\def\defaultregistersection#1#2#3#4#5#6#7% class i n #4:processor #5:internal #6:sectionindex #7:word
+ {\pushcurrentregister{#1}%
+ \ifnum#2=\plusone
+ \registerpageseparator
+ \fi
+ \global\setconstant\c_strc_registers_page_state\plustwo
+ \def\currentregisterpageindex{#5}%
+ \dostarttagged\t!registersection\empty
+ \settrue\c_strc_registers_page_done
+ \iflocation
+ \def\currentregistersectionindex{#6}%
+ \else
+ \let\currentregistersectionindex\empty
+ \fi
+ \ifnum#2=\plusone\else
+ ,\space
+ \fi
+ \doapplyregistersectioncommand{#4}{#7}%
+ \dostoptagged
+ \popcurrentregister}
+
+\aliased\let\registersection \defaultregistersection
+\aliased\let\registerseeword \defaultregisterseeword
+\aliased\let\registerentry \defaultregisterentry
+\aliased\let\registercharacter\defaultregistercharacter
+
+%D Experimental:
+%D
+%D \starttyping
+%D \setupregister
+%D [index]
+%D [pagesegments=1:4,
+%D pagemethod=section]
+%D
+%D \starttext
+%D
+%D \chapter {one} \section {alpha}
+%D
+%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
+%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
+%D
+%D \chapter {one} \section {alpha}
+%D
+%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
+%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
+%D
+%D \placeindex[n=1]
+%D
+%D \stoptext
+%D \stoptyping
+
+%D A few specific rendering variants:
+
+% \def\doregisterpagelocation#1#2%
+% {\nextregisterpage
+% \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}}
+
+% todo: \installregisterpagehandler
+
+% \def\MyRegisterPageCommand#1%
+% {#1\currentregisterpageuserdata{whatever}}
+%
+% \starttext
+% \setregisterentry[index][entries=aaa][whatever=f.] test \index{bbb} test
+% \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand]
+% \stoptext
+
+\permanent\def\registerpageuserdata #1#2{\clf_registeruserdata#1{#2}}
+\permanent\def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1}
+
+% not yet ok : new internal handler names
+
+\aliased\let\registerpageseparatorsymbol\empty
+
+\permanent\protected\def\registerpagebuttonsymbol
+ {\vrule\s!width\emwidth\s!height\exheight\s!depth\zeropoint\relax}
+
+\installcorenamespace{registersymbol}
+
+\setvalue{\??registersymbol n}%
+ {\enforced\frozen\def\registerpageseparatorsymbol{,\space}}
+
+\setvalue{\??registersymbol a}%
+ {\enforced\frozen\def\registerpageseparatorsymbol{,\space}} % now done via conversion
+
+\setvalue{\??registersymbol\v!none}%
+ {\enforced\frozen\let\registerpageseparatorsymbol\empty
+ \enforced\frozen\let\registeronepage\gobblefivearguments
+ \enforced\frozen\let\registerpagerange\gobbleeightarguments}
+
+\setvalue{\??registersymbol 1}%
+ {\enforced\frozen\let\registerpageseparatorsymbol\space
+ \enforced\frozen\def\registeronepage{\symbol[1]\gobblefivearguments}%
+ \enforced\frozen\def\registerpagerange{\symbol[1]\gobbleeightarguments}}
+
+\setvalue{\??registersymbol 2}%
+ {\enforced\frozen\let\registerpageseparatorsymbol\space
+ \enforced\frozen\def\registeronepage{\registerpagebuttonsymbol\gobblefivearguments}%
+ \enforced\frozen\def\registerpagerange{\registerpagebuttonsymbol\gobbleeightarguments}}
+
+\protected\def\setregisterpagerendering
+ {\doifelse{\registerparameter\c!pagenumber}\v!no
+ {\enforced\frozen\let \currentregisterpagesymbol\v!none}
+ {\enforced\frozen\edef\currentregisterpagesymbol{\registerparameter\c!symbol}}%
+ \ifempty\currentregisterpagesymbol
+ \csname\??registersymbol n\endcsname
+ \orelse\ifcsname\??registersymbol\currentregisterpagesymbol\endcsname
+ \csname\??registersymbol\currentregisterpagesymbol\endcsname
+ \else
+ \enforced\frozen\let\registerpageseparatorsymbol\space
+ \enforced\frozen\def\registeronepage{\registerparameter\c!symbol\gobblefivearguments}%
+ \enforced\frozen\def\registerpagerange{\registerparameter\c!symbol\gobbleeightarguments}%
+ \fi}
+
+\appendtoks
+ \setregisterpagerendering
+\to \everyplaceregister
+
+%D The linked register code will be reimplemented (not that hard) when it's needed
+%D again and/or when I'm bored.
+
+\permanent \def\findregisterinternal#1#2#3{\clf_findregisterinternal{#1}{#2}#3\relax}
+\permanent\protected\def\pageofinternal #1{\clf_pageofinternal#1\relax}
+
+\permanent\protected\def\linkedregisterentrylink#1#2#3#4% tag where before after
+ {\iflocation
+ \scratchcounter\findregisterinternal{#1}{#2}\currentregisternumber\relax\relax
+ \ifcase\scratchcounter\else
+ #3\relax
+ \goto{\symbol[#2]}[internal(\the\scratchcounter)]%
+ #4\relax
+ \fi
+ \else
+ % \scratchcounter\findregisterinternal{#1}{#2}\currentregisternumber\relax\relax
+ % \ifcase\scratchcounter\else
+ % #3\relax
+ % \pageofinternal\scratchcounter
+ % #4\relax
+ % \fi
+ \fi}
+
+\permanent\protected\def\linkedregisterentry#1%
+ {\dontleavehmode
+ \begingroup
+ \setbox\scratchbox\hbox{#1}%
+ \linkedregisterentrylink\currentregistername\v!previous\relax\nobreakspace
+ \unhbox\scratchbox
+ \linkedregisterentrylink\currentregistername\v!next\nobreakspace\relax
+ \endgroup}
+
+\permanent\protected\def\registerpacked#1#2%
+ {\iflocation
+ \hskip\d_strc_registers_distance\relax
+ \nobreak
+ \ifnum#1=#2\relax
+ \goto{\symbol[\v!somewhere]}[internal(#1)]%
+ \else
+ \goto{\symbol[\v!first]}[internal(#1)]%
+ \nobreakspace
+ \goto{\symbol[\v!last]}[internal(#2)]%
+ \fi
+ \fi}
+
+%D Default index:
+
+\defineregister
+ [\v!index]
+% [\v!indices]
+
+\stopcontextdefinitioncode
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/strc-sec.mkxl b/tex/context/base/mkiv/strc-sec.mkxl
index 21f057e67..9a0ebbb54 100644
--- a/tex/context/base/mkiv/strc-sec.mkxl
+++ b/tex/context/base/mkiv/strc-sec.mkxl
@@ -1119,11 +1119,11 @@
\newcount \c_strc_sectioning_preceding_level \c_strc_sectioning_preceding_level\plusone
\newconditional\c_strc_sectioning_auto_break \settrue\c_strc_sectioning_auto_break
\newconditional\c_strc_sectioning_ignore_page
-\newsignal \s_strc_sectioning_continuous_signal
+\newsignal \d_strc_sectioning_continuous_signal
\protected\def\strc_sectioning_inject_continuous_signal
{\ifhmode
- \hskip\s_strc_sectioning_continuous_signal\relax
+ \hskip\d_strc_sectioning_continuous_signal\relax
\fi}
% \let\dotagsectionlevel\relax
@@ -1156,7 +1156,7 @@
{\ifhmode
\scratchcounter\lastpenalty
\unpenalty % no beauty in this
- \ifdim\lastskip=\s_strc_sectioning_continuous_signal
+ \ifdim\lastskip=\d_strc_sectioning_continuous_signal
% no page break
\ifconditional\c_strc_sectioning_ignore_page
\setfalse\c_strc_sectioning_ignore_page
diff --git a/tex/context/base/mkiv/symb-emj.mkiv b/tex/context/base/mkiv/symb-emj.mkiv
index e063b6a7a..7bfe4c023 100644
--- a/tex/context/base/mkiv/symb-emj.mkiv
+++ b/tex/context/base/mkiv/symb-emj.mkiv
@@ -23,5 +23,4 @@
\unexpanded\def\emoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_resolvedemoji{#1}}}
\unexpanded\def\robustemoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_checkedemoji {#1}}}
-
\protect \endinput
diff --git a/tex/context/base/mkiv/symb-emj.mkxl b/tex/context/base/mkiv/symb-emj.mkxl
new file mode 100644
index 000000000..96c4c0859
--- /dev/null
+++ b/tex/context/base/mkiv/symb-emj.mkxl
@@ -0,0 +1,26 @@
+%D \module
+%D [ file=symb-emj,
+%D version=2017.04.21,
+%D title=\CONTEXT\ Symbol Libraries,
+%D subtitle=Emoji,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Symbol Libraries / Emoji}
+
+\registerctxluafile{symb-emj}{}
+
+\unprotect
+
+\permanent \def\expandedemoji#1{\clf_resolvedemoji{#1}}
+\permanent\protected\def\resolvedemoji#1{\clf_resolvedemoji{#1}}
+\permanent\protected\def\checkedemoji #1{\clf_checkedemoji {#1}}
+\permanent\protected\def\emoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_resolvedemoji{#1}}}
+\permanent\protected\def\robustemoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_checkedemoji {#1}}}
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/syst-aux.mkxl b/tex/context/base/mkiv/syst-aux.mkxl
index 0638600c2..0f268854b 100644
--- a/tex/context/base/mkiv/syst-aux.mkxl
+++ b/tex/context/base/mkiv/syst-aux.mkxl
@@ -3044,12 +3044,12 @@
%D Signals old dimensions and can be used in skips, kerns and tests like \type
%D {\ifdim}.
-\newdimen\maximumsignal % step is about 0.00025pt
+\newdimen\d_syst_maximum_signal % step is about 0.00025pt
\permanent\protected\def\newsignal#1%
{\ifdefined#1\else
- \advance\maximumsignal 2\scaledpoint % to be save in rounding
- \edef#1{\the\maximumsignal}%
+ \advance\d_syst_maximum_signal2\scaledpoint % to be save in rounding
+ \immutable\dimensiondef#1\d_syst_maximum_signal
\fi}
%D \macros
diff --git a/tex/context/base/mkiv/tabl-xtb.mklx b/tex/context/base/mkiv/tabl-xtb.mklx
index a0fe41428..41e7c9b86 100644
--- a/tex/context/base/mkiv/tabl-xtb.mklx
+++ b/tex/context/base/mkiv/tabl-xtb.mklx
@@ -76,16 +76,16 @@
% \let\tsplitafter \donothing
% \let\postprocesstsplit \donothing
-\let\dotagxtablecell \relax % names will change
-\let\dotagxtablesignal\relax % names will change
+\aliased\let\dotagxtablecell \relax % names will change
+\aliased\let\dotagxtablesignal\relax % names will change
\appendtoks
- \def\dotagxtablecell
+ \enforced\permanent\protected\def\dotagxtablecell
{\clf_settagtablecell
\numexpr\tablecellrows\relax
\numexpr\tablecellcolumns\relax
\numexpr\raggedstatus\relax}%
- \def\dotagxtablesignal
+ \enforced\permanent\protected\def\dotagxtablesignal
{\signalcharacter}% not used
\to \everyenableelements
diff --git a/tex/context/base/mkiv/toks-scn.lmt b/tex/context/base/mkiv/toks-scn.lmt
new file mode 100644
index 000000000..93e0af09a
--- /dev/null
+++ b/tex/context/base/mkiv/toks-scn.lmt
@@ -0,0 +1,592 @@
+if not modules then modules = { } end modules ['toks-scn'] = {
+ version = 1.001,
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Writing this kind of code (and completing the newtoken code base) is fun. I did
+-- so with the brilliant film music from The Girl with the Dragon Tattoo running in a
+-- loop in the background (three cd's by Trent Reznor and Atticus Ross). An alien
+-- feeling helps with alien code.
+
+-- todo: more \let's at the tex end
+
+local type, next, tostring, tonumber = type, next, tostring, tonumber
+
+local formatters = string.formatters
+local concat = table.concat
+
+local scanners = tokens.scanners
+local tokenbits = tokens.bits
+
+local scanstring = scanners.string
+local scanargument = scanners.argument
+local scandelimited = scanners.delimited -- lmtx
+local scanverbatim = scanners.verbatim
+local scantokenlist = scanners.tokenlist
+local scantoks = scanners.toks
+local scaninteger = scanners.integer
+local scancardinal = scanners.cardinal
+local scannumber = scanners.number
+local scankeyword = scanners.keyword
+local scankeywordcs = scanners.keywordcs
+local scanword = scanners.word
+local scanletters = scanners.letters
+local scankey = scanners.key
+local scancode = scanners.code
+local scanboolean = scanners.boolean
+local scandimen = scanners.dimen
+local scanglue = scanners.glue
+local scangluevalues = scanners.gluevalues
+local scangluespec = scanners.gluespec
+local scancsname = scanners.csname
+local scanintegerargument = scanners.integerargument
+local scandimenargument = scanners.dimenargument
+
+local todimen = number.todimen
+local toboolean = toboolean
+
+local lpegmatch = lpeg.match
+local p_unquoted = lpeg.Cs(lpeg.patterns.unquoted)
+
+local trace_compile = false trackers.register("tokens.compile", function(v) trace_compile = v end)
+local report_compile = logs.reporter("tokens","compile")
+local report_scan = logs.reporter("tokens","scan")
+
+local open = tokenbits.open
+local close = tokenbits.close
+
+local function scanopen()
+ while true do
+ local c = scancode(open)
+ if c == 123 then
+ return true
+ -- elseif c ~= 32 then
+ elseif not c then
+ return
+ end
+ end
+end
+
+local function scanclose()
+ while true do
+ local c = scancode(close)
+ if c == 125 then
+ return true
+ -- elseif c ~= 32 then
+ elseif not c then
+ return
+ end
+ end
+end
+
+scanners.scanopen = scanopen
+scanners.scanclose = scanclose
+
+local function scanlist()
+ local wrapped = scanopen()
+ local list = { }
+ local size = 0
+ while true do
+ local entry = scanstring()
+ if entry then
+ size = size + 1
+ list[size] = entry
+ else
+ break
+ end
+ end
+ if wrapped then
+ scanclose()
+ end
+ return list
+end
+
+local function scanconditional()
+ local kw = scanword()
+ if kw == "true" then
+ return true
+ end
+ if kw == "false" then
+ return false
+ end
+ local c = scaninteger()
+ if c then
+ return c == 0 -- with a conditional 0=true
+ end
+ return nil
+end
+
+local function scantable(t,data)
+ if not data then
+ data = { }
+ end
+ if t then
+ local wrapped = scanopen()
+ while true do
+ local key = scanword(true)
+ if key then
+ local get = t[key]
+ if get then
+ data[key] = get()
+ else
+ -- catch all we can get
+ end
+ else
+ break
+ end
+ end
+ if wrapped then
+ scanclose()
+ end
+ end
+ return data
+end
+
+function tokens.constant(s)
+ if type(s) == "string" then
+ return "'" .. s .. "'"
+ else
+ return s
+ end
+end
+
+scanners.list = scanlist
+scanners.table = scantable
+scanners.conditional = scanconditional
+
+function scanners.whd()
+ local width, height, depth
+ while true do
+ if scankeyword("width") then
+ width = scandimen()
+ elseif scankeyword("height") then
+ height = scandimen()
+ elseif scankeyword("depth") then
+ depth = scandimen()
+ else
+ break
+ end
+ end
+ if width or height or depth then
+ return width or 0, height or 0, depth or 0
+ else
+ -- we inherit
+ end
+end
+
+-- begin lmtx
+
+local l = utf.byte("[")
+local r = utf.byte("]")
+
+local function scanbracketed()
+ local s = scandelimited(l, r)
+ if s then
+ return s
+ else
+ local readstate = status.getreadstate()
+ report_scan("missing argument in line %i of %a", readstate.linenumber, readstate.filename)
+ return ""
+ end
+end
+
+local function scanoptional()
+ return scandelimited(l, r) or ""
+end
+
+local function scanbracketedasis()
+ return scandelimited(l, r, false)
+end
+
+local function scanargumentasis()
+ return scanargument(false)
+end
+
+scanners.bracketed = scanbracketed
+scanners.optional = scanoptional
+scanners.bracketedasis = scanbracketedasis
+scanners.argumentasis = scanargumentasis
+
+-- end lmtx
+
+local shortcuts = {
+ tokens = tokens,
+ bits = tokenbits,
+ open = open,
+ close = close,
+ scanners = scanners,
+ scanstring = scanstring,
+ scanargument = scanargument,
+ scanverbatim = scanverbatim,
+ scantokenlist = scantokenlist,
+ scantoks = scantoks,
+ scaninteger = scaninteger,
+ scancardinal = scancardinal,
+ scannumber = scannumber,
+ scantable = scantable, -- not directly useable
+ scankeyword = scankeyword,
+ scankeywordcs = scankeywordcs,
+ scanword = scanword,
+ scanletters = scanletters,
+ -- scankey = scankey,
+ scancode = scancode,
+ scanboolean = scanboolean,
+ scanglue = scanglue, -- list
+ scangluespec = scangluespec,
+ scangluevalues = scangluevalues,
+ scandimen = scandimen,
+ scandimension = scandimen,
+ scanbox = scanners.box,
+ scanhbox = scanners.hbox,
+ scanvbox = scanners.vbox,
+ scanvtop = scanners.vtop,
+ scanconditional = scanconditional,
+ scanopen = scanopen,
+ scanclose = scanclose,
+ scanlist = scanlist,
+ scancsname = scancsname,
+ todimen = todimen,
+ tonumber = tonumber,
+ tostring = tostring,
+ toboolean = toboolean,
+ inspect = inspect,
+ report = report_scan,
+ -- lmtx
+ scandelimited = scandelimited, -- not directly useable
+ scanbracketed = scanbracketed,
+ scanoptional = scanoptional,
+ scanbracketedasis = scanbracketedasis,
+ scanargumentasis = scanargumentasis,
+ --
+ scanintegerargument = scanintegerargument,
+ scandimenargument = scandimenargument,
+}
+
+tokens.shortcuts = shortcuts
+
+local load = load
+local dump = string.dump
+
+local function loadstripped(code)
+ return load(code,nil,nil,shortcuts)
+ -- return load(dump(load(code),true),nil,nil,shortcuts)
+end
+
+tokens.converters = {
+ tonumber = "tonumber",
+ tostring = "tostring",
+ toboolean = "toboolean",
+ todimen = "todimen",
+ toglue = "todimen",
+}
+
+-- We could just pickup a keyword but then we really need to make sure that no number
+-- follows it when that is the assignment and adding an optional = defeats the gain
+-- in speed. Currently we have sources with no spaces (\startcontextdefinitioncode
+-- ...) so it fails there.
+--
+-- Another drawback is that we then need to use { } instead of ending with \relax (as
+-- we can do now) but that is no big deal. It's just that I then need to check the TeX
+-- end. More pain than gain and a bit risky too. Using scanletters works better, but
+-- the gain is only some 10 percent but if we don't have keywords with numbers it might
+-- make sense in the end, some day.
+
+local f_if = formatters[ " if scankeywordcs('%s') then data['%s'] = scan%s()"]
+local f_elseif = formatters[" elseif scankeywordcs('%s') then data['%s'] = scan%s()"]
+
+----- f_if_x = formatters[ " if not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"]
+----- f_elseif_x = formatters[" elseif not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"]
+
+-- if CONTEXTLMTXMODE > 0 then
+-- f_if = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = scan%s()"]
+-- f_elseif = formatters[" elseif key == '%s' then data['%s'] = scan%s()"]
+-- end
+
+local f_local = formatters["local scan%s = scanners.%s"]
+local f_scan = formatters["scan%s()"]
+local f_shortcut = formatters["local %s = scanners.converters.%s"]
+
+local f_if_c = formatters[ " if scankeywordcs('%s') then data['%s'] = %s(scan%s())"]
+local f_elseif_c = formatters[" elseif scankeywordcs('%s') then data['%s'] = %s(scan%s())"]
+local f_scan_c = formatters["%s(scan%s())"]
+
+-- see above
+
+-- if CONTEXTLMTXMODE > 0 then
+-- f_if_c = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = %s(scan%s())"]
+-- f_elseif_c = formatters[" elseif k == '%s' then data['%s'] = %s(scan%s())"]
+-- end
+
+local f_any = formatters[" else local key = scanword(true) if key then data[key] = scan%s() else break end end"]
+local f_any_c = formatters[" else local key = scanword(true) if key then data[key] = %s(scan%s()) else break end end"]
+local s_done = " else break end"
+
+local f_any_all = formatters[" local key = scanword(true) if key then data[key] = scan%s() else break end"]
+local f_any_all_c= formatters[" local key = scanword(true) if key then data[key] = %s(scan%s()) else break end"]
+
+local f_table = formatters["%\nt\nreturn function()\n local data = { }\n%s\n return %s\nend\n"]
+local f_sequence = formatters["%\nt\n%\nt\n%\nt\nreturn function()\n return %s\nend\n"]
+local f_singular = formatters["%\nt\n%\nt\n\nreturn function(%s)\n return %s\nend\n"]
+local f_simple = formatters["%\nt\nreturn function()\n return %s\nend\n"]
+local f_string = formatters["%q"]
+local f_action_f = formatters["action%s(%s)"]
+local f_action_s = formatters["local action%s = tokens._action[%s]"]
+local f_nested = formatters["local function scan%s()\n local data = { }\n%s\n return data\nend\n"]
+
+local f_check = formatters[ [[
+ local wrapped = scanopen()
+ while true do
+ ]] .. "%\nt\n" .. [[
+ %s
+ end
+ if wrapped then
+ scanclose()
+ end
+]] ]
+
+-- using these shortcuts saves temporary small tables (okay, it looks uglier)
+
+local presets = {
+ ["1 string" ] = { "string" },
+ ["2 strings"] = { "string", "string" },
+ ["3 strings"] = { "string", "string", "string" },
+ ["4 strings"] = { "string", "string", "string", "string" },
+ ["5 strings"] = { "string", "string", "string", "string", "string" },
+ ["6 strings"] = { "string", "string", "string", "string", "string", "string" },
+ ["7 strings"] = { "string", "string", "string", "string", "string", "string", "string" },
+ ["8 strings"] = { "string", "string", "string", "string", "string", "string", "string", "string" },
+
+ ["1 argument" ] = { "argument" },
+ ["2 arguments"] = { "argument", "argument" },
+ ["3 arguments"] = { "argument", "argument", "argument" },
+ ["4 arguments"] = { "argument", "argument", "argument", "argument" },
+}
+
+tokens.presets = presets
+
+function tokens.compile(specification)
+ local f = { }
+ local n = 0
+ local c = { }
+ local t = specification.arguments or specification
+ local a = specification.actions or nil
+ if type(a) == "function" then
+ a = { a }
+ end
+ local code
+ local args
+ local function compile(t,nested)
+ local done = s_done
+ local r = { }
+ local m = 0
+ for i=1,#t do
+ local ti = t[i]
+ if ti == "*" and i == 1 then
+ done = f_any_all("string")
+ else
+ local t1 = ti[1]
+ local t2 = ti[2] or "string"
+ if type(t2) == "table" then
+ n = n + 1
+ f[n] = compile(t2,n)
+ t2 = n
+ end
+ local t3 = ti[3]
+ if type(t3) == "function" then
+ -- todo: also create shortcut
+ elseif t3 then
+ c[t3] = f_shortcut(t3,t3)
+ if t1 == "*" then
+ if i == 1 then
+ done = f_any_all_c(t3,t2)
+ break
+ else
+ done = f_any_c(t3,t2)
+ end
+ else
+ m = m + 1
+ r[m] = (m > 1 and f_elseif_c or f_if_c)(t1,t1,t3,t2)
+ end
+ else
+ if t1 == "*" then
+ if i == 1 then
+ done = f_any_all(t2)
+ break
+ else
+ done = f_any(t2)
+ end
+ else
+ m = m + 1
+ r[m] = (m > 1 and f_elseif or f_if )(t1,t1,t2)
+ -- r[m] = (m > 1 and f_elseif_x or f_if_x)(t1,t1,t1,t2)
+ end
+ end
+ end
+ end
+ local c = f_check(r,done)
+ if nested then
+ return f_nested(nested,c)
+ else
+ return c
+ end
+ end
+ local p = t and presets[t] -- already done in implement
+ if p then
+ t = p
+ end
+ local tt = type(t)
+ if tt == "string" then
+ if a then
+ local s = lpegmatch(p_unquoted,t)
+ if s and t ~= s then
+ code = t
+ else
+ code = f_scan(t)
+ end
+ tokens._action = a
+ for i=1,#a do
+ code = f_action_f(i,code)
+ n = n + 1
+ f[n] = f_action_s(i,i)
+ end
+ code = f_simple(f,code)
+ else
+ return scanners[t]
+ end
+ elseif tt ~= "table" then
+ return
+ elseif #t == 1 then
+ local ti = t[1]
+ if type(ti) == "table" then
+ ti = compile(ti)
+ code = "data"
+ if a then
+ tokens._action = a
+ for i=1,#a do
+ code = f_action_f(i,code)
+ n = n + 1
+ f[n] = f_action_s(i,i)
+ end
+ end
+ code = f_table(f,ti,code)
+ elseif a then
+ code = f_scan(ti)
+ tokens._action = a
+ for i=1,#a do
+ code = f_action_f(i,code)
+ n = n + 1
+ f[n] = f_action_s(i,i)
+ end
+ code = f_simple(f,code)
+ else
+ return scanners[ti]
+ end
+ elseif #t == 0 then
+ if specification.usage == "value" then
+ code = "b"
+ args = "_,b"
+ else
+ code = ""
+ args = ""
+ end
+ if a then
+ tokens._action = a
+ for i=1,#a do
+ code = f_action_f(i,code)
+ n = n + 1
+ f[n] = f_action_s(i,i)
+ end
+ end
+ code = f_singular(c,f,args,code)
+ else
+ local r = { }
+ local p = { }
+ local m = 0
+ for i=1,#t do
+ local ti = t[i]
+ local tt = type(ti)
+ if tt == "table" then
+ if ti[1] == "_constant_" then
+ local v = ti[2]
+ if type(v) == "string" then
+ r[i] = f_string(v)
+ else
+ r[i] = tostring(v)
+ end
+ else
+ m = m + 1
+ p[m] = compile(ti,100+m)
+ r[i] = f_scan(100+m)
+ end
+ elseif tt == "number" then
+ r[i] = tostring(ti)
+ elseif tt == "boolean" then
+ r[i] = tostring(ti)
+ else
+ local s = lpegmatch(p_unquoted,ti)
+ if s and ti ~= s then
+ r[i] = ti -- a string, given as "'foo'" or '"foo"'
+ elseif scanners[ti] then
+ r[i] = f_scan(ti)
+ else
+ report_compile("unknown scanner %a",ti)
+ r[i] = ti
+ end
+ end
+ end
+ code = concat(r,",")
+ if a then
+ tokens._action = a
+ for i=1,#a do
+ code = f_action_f(i,code)
+ n = n + 1
+ f[n] = f_action_s(i,i)
+ end
+ end
+ code = f_sequence(c,f,p,code)
+ end
+ if not code then
+ return
+ end
+ if trace_compile then
+ report_compile("code: %s",code)
+ end
+ local code, message = loadstripped(code)
+ if code then
+ code = code() -- sets action
+ else
+ report_compile("error in code: %s",code)
+ report_compile("error message: %s",message)
+ end
+ if a then
+ tokens._action = nil
+ end
+ if code then
+ return code
+ end
+end
+
+-- local fetch = tokens.compile {
+-- "string",
+-- "string",
+-- {
+-- { "data", "string" },
+-- { "tab", "string" },
+-- { "method", "string" },
+-- { "foo", {
+-- { "method", "integer" },
+-- { "compact", "number" },
+-- { "nature" },
+-- { "*" }, -- any key
+-- } },
+-- { "compact", "string", "tonumber" },
+-- { "nature", "boolean" },
+-- { "escape", "string" },
+-- { "escape" },
+-- },
+-- "boolean",
+-- }
+--
+-- os.exit()
diff --git a/tex/context/base/mkiv/typo-del.mkiv b/tex/context/base/mkiv/typo-del.mkiv
index 911739fbf..9720326be 100644
--- a/tex/context/base/mkiv/typo-del.mkiv
+++ b/tex/context/base/mkiv/typo-del.mkiv
@@ -142,8 +142,8 @@
[\c!rightsubsentence]
[\rightboundarycharacter\c!rightsubsentence{sentence}]
-\newsignal \d_typo_subsentence_signal
-\newcount \c_typo_subsentence_nesting
+\newsignal\d_typo_subsentence_signal
+\newcount \c_typo_subsentence_nesting
\let\beforesubsentence\donothing
\let\aftersubsentence \donothing
diff --git a/tex/context/base/mkiv/unic-ini.mkxl b/tex/context/base/mkiv/unic-ini.mkxl
new file mode 100644
index 000000000..3fccd2feb
--- /dev/null
+++ b/tex/context/base/mkiv/unic-ini.mkxl
@@ -0,0 +1,36 @@
+%D \module
+%D [ file=unic-ini,
+%D version=2002.12.03,
+%D title=\CONTEXT\ \UNICODE\ Support,
+%D subtitle=\UNICODE\ \& UTF-8 support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Unicode Support / Initialization}
+
+\registerctxluafile{unic-ini}{}
+
+\unprotect
+
+\permanent\def\unicodenumber #1{\the\numexpr#1\relax} % no lookahead
+\permanent\def\unicodehexnumber#1{\cldcontext{number.toevenhex(\number#1))}}
+
+%D \startbuffer
+%D \unicodechar{left square bracket}okay\unicodechar{right square bracket}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\permanent\def\unicodechar#1{\clf_unicodechar{#1}}
+
+\permanent\protected\def\unknownchar
+ {\dontleavehmode\hpack{\vrule\s!width.5\emwidth\s!height\exheight\s!depth\zeropoint}}
+
+\ifdefined\zwnbsp\else \let\zwnbsp\relax \fi % zerowidthnonbreakablespace
+
+\protect \endinput
diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml
index 4ffe5c932..f568fead2 100644
--- a/tex/context/interface/mkii/keys-it.xml
+++ b/tex/context/interface/mkii/keys-it.xml
@@ -286,6 +286,7 @@
<cd:variable name='intermezzo' value='intermezzo'/>
<cd:variable name='intext' value='intesto'/>
<cd:variable name='intro' value='intro'/>
+ <cd:variable name='invertedshort' value='invertedshort'/>
<cd:variable name='italic' value='corsivo'/>
<cd:variable name='italicbold' value='corsivograssetto'/>
<cd:variable name='item' value='elemento'/>
@@ -389,6 +390,7 @@
<cd:variable name='nonumber' value='nonumber'/>
<cd:variable name='norepeat' value='norepeat'/>
<cd:variable name='normal' value='normale'/>
+ <cd:variable name='normalshort' value='normalshort'/>
<cd:variable name='nospacing' value='nospacing'/>
<cd:variable name='nostopper' value='nostopper'/>
<cd:variable name='not' value='non'/>
@@ -456,6 +458,7 @@
<cd:variable name='rectangular' value='rettangolare'/>
<cd:variable name='reference' value='riferimento'/>
<cd:variable name='referral' value='referral'/>
+ <cd:variable name='region' value='region'/>
<cd:variable name='register' value='registro'/>
<cd:variable name='regular' value='regolare'/>
<cd:variable name='relative' value='relativo'/>
@@ -1817,7 +1820,7 @@
<cd:command name='resetpath' value='resetpath'/>
<cd:command name='resetperiodkerning' value='resetperiodkerning'/>
<cd:command name='resetsystemmode' value='resetsystemmode'/>
- <cd:command name='resettext' value='resettextcontent'/>
+ <cd:command name='resettextcontent' value='resettextcontent'/>
<cd:command name='resetvisualizers' value='resetvisualizers'/>
<cd:command name='restoreglobalbodyfont' value='restoreglobalbodyfont'/>
<cd:command name='retestfeature' value='retestfeature'/>
diff --git a/tex/context/modules/mkiv/x-mathml.mkiv b/tex/context/modules/mkiv/x-mathml.mkiv
index adc494314..bd55196f9 100644
--- a/tex/context/modules/mkiv/x-mathml.mkiv
+++ b/tex/context/modules/mkiv/x-mathml.mkiv
@@ -1890,8 +1890,6 @@
\fi
\stoptexdefinition
-\newsignal\mmltextsignal % not used
-
\starttexdefinition applymmlsometext #1#2
\applymmlmathbackground {#1} {
\applymmlmathcolor {#1} {