summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-07-25 18:52:11 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-07-25 18:52:11 +0200
commite5255a951b23372f4f0ad58b9afc38ba3929becf (patch)
tree19c95f179d751c6ef0f0cfe72f7a9c7412bfda52 /tex
parentc08e48de0220ab08d38693848de9bc51ed8e7d50 (diff)
downloadcontext-e5255a951b23372f4f0ad58b9afc38ba3929becf.tar.gz
2016-07-25 17:45:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/context-version.pdfbin4259 -> 4259 bytes
-rw-r--r--tex/context/base/mkiv/anch-pos.lua2
-rw-r--r--tex/context/base/mkiv/cldf-bas.lua2
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua1439
-rw-r--r--tex/context/base/mkiv/cldf-stp.lua4
-rw-r--r--tex/context/base/mkiv/cldf-ver.lua59
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/core-env.lua205
-rw-r--r--tex/context/base/mkiv/math-ini.lua1
-rw-r--r--tex/context/base/mkiv/node-ppt.lua3
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin9244 -> 9211 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin367593 -> 368230 bytes
-rw-r--r--tex/context/base/mkiv/strc-bkm.lua50
-rw-r--r--tex/context/base/mkiv/syst-lua.lua10
-rw-r--r--tex/context/base/mkiv/tabl-xtb.lua2
-rw-r--r--tex/context/base/mkiv/trac-vis.lua8
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin774585 -> 774595 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60792 -> 60793 bytes
-rw-r--r--tex/context/modules/mkiv/s-characters-properties.lua83
-rw-r--r--tex/context/modules/mkiv/s-characters-properties.mkiv30
-rw-r--r--tex/context/sample/common/khatt-en.tex4
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
23 files changed, 837 insertions, 1071 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index c696a2842..53d2e6dff 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua
index 3042ea4a0..1c5b12c13 100644
--- a/tex/context/base/mkiv/anch-pos.lua
+++ b/tex/context/base/mkiv/anch-pos.lua
@@ -35,7 +35,7 @@ local scanners = interfaces.scanners
local commands = commands
local context = context
-local ctxnode = context.flushnode
+local ctxnode = context.nodes.flush
local tex = tex
local texgetcount = tex.getcount
diff --git a/tex/context/base/mkiv/cldf-bas.lua b/tex/context/base/mkiv/cldf-bas.lua
index 311816022..2387793c8 100644
--- a/tex/context/base/mkiv/cldf-bas.lua
+++ b/tex/context/base/mkiv/cldf-bas.lua
@@ -162,5 +162,5 @@ context.registers = {
newtoks = function(name) return allocate(name,"toks") end,
newbox = function(name) return allocate(name,"box","mathchar") end,
-- not really a register but kind of belongs here
- chardef = function(name,u) context([[\chardef\%s=%s\relax]],name,u) end,
+ newchar = function(name,u) context([[\chardef\%s=%s\relax]],name,u) end,
}
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index 3816e7755..3d8671149 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -6,42 +6,38 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
license = "see context related readme files"
}
--- also see cldf-tod.* !
--- old code moved to cldf-old.lua
-
--- maybe:
---
--- 0.528 local foo = tex.ctxcatcodes
--- 0.651 local foo = getcount("ctxcatcodes")
--- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes")
-
--- maybe  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔)
-
-- This started as an experiment: generating context code at the lua end. After all
-- it is surprisingly simple to implement due to metatables. I was wondering if
-- there was a more natural way to deal with commands at the lua end. Of course it's
-- a bit slower but often more readable when mixed with lua code. It can also be handy
-- when generating documents from databases or when constructing large tables or so.
--
--- maybe optional checking against interface
--- currently no coroutine trickery
--- we could always use prtcatcodes (context.a_b_c) but then we loose protection
--- tflush needs checking ... sort of weird that it's not a table
+-- In cldf-tod.lua I have some code that might end up here. In cldf-old.lua the
+-- code that precedes more modern solutions (made possible by features in the engine),
+-- most noticeably function handling, which worked well for a decade, but by now the
+-- more efficient approach is stable enough to move the original code to the obsolete
+-- module.
--
--- tex.print == line with endlinechar appended
-
--- todo: context("%bold{total: }%s",total)
--- todo: context.documentvariable("title")
+-- to be considered:
+--
+-- 0.528 local foo = tex.ctxcatcodes
+-- 0.651 local foo = getcount("ctxcatcodes")
+-- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes")
+-- maybe:  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔)
+-- note : tex.print == line with endlinechar appended
+-- todo : context("%bold{total: }%s",total)
+-- todo : context.documentvariable("title")
+--
-- during the crited project we ran into the situation that luajittex was 10-20 times
-- slower that luatex ... after 3 days of testing and probing we finally figured out that
-- the the differences between the lua and luajit hashers can lead to quite a slowdown
-- in some cases.
-
+--
-- context(lpeg.match(lpeg.patterns.texescape,"${}"))
-- context(string.formatters["%!tex!"]("${}"))
-- context("%!tex!","${}")
-
+--
-- We try not to polute the context namespace too much. For that reason the commands are
-- registered in the context.core namespace. You can call all context commands using
-- context.foo etc. and pipe to context with context("foo"). Defining a local command
@@ -52,11 +48,19 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- ones in critical places (no one will notice of course). The standard syntax highlighter
-- that I use knows how to visualize ctx related code.
+-- I cleaned this code up a bit when updating the cld manual but got distracted a bit by
+-- watching Trio Hiromi Uehara, Anthony Jackson & Simon Phillips (discovered via the
+-- later on YT). Hopefully the video breaks made the following better in the end.
+
local format, stripstring = string.format, string.strip
-local next, type, tostring, tonumber, setmetatable, unpack, select, rawset = next, type, tostring, tonumber, setmetatable, unpack, select, rawset
+local next, type, tostring, tonumber, unpack, select, rawset = next, type, tostring, tonumber, unpack, select, rawset
local insert, remove, concat = table.insert, table.remove, table.concat
local lpegmatch, lpegC, lpegS, lpegP, lpegV, lpegCc, lpegCs, patterns = lpeg.match, lpeg.C, lpeg.S, lpeg.P, lpeg.V, lpeg.Cc, lpeg.Cs, lpeg.patterns
-local formatters = string.formatters -- using formatters is slower in this case
+
+local formatters = string.formatters -- using formatters is slower in this case
+local setmetatableindex = table.setmetatableindex
+local setmetatablecall = table.setmetatablecall
+local setmetatablenewindex = table.setmetatablenewindex
context = context or { }
commands = commands or { }
@@ -96,342 +100,226 @@ local flushdirect = texprint -- lines
local report_context = logs.reporter("cld","tex")
local report_cld = logs.reporter("cld","stack")
+local report_template = logs.reporter("cld","template")
local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end)
-- In earlier experiments a function tables was referred to as lua.calls and the
--- primitive \luafunctions was \luacall.
+-- primitive \luafunctions was \luacall and we used our own implementation of
+-- a function table (more indirectness).
-local luafunctions = lua.get_functions_table and lua.get_functions_table()
-local usedstack = nil
+local knownfunctions = lua.get_functions_table()
local showstackusage = false
--- luafunctions = false
-
trackers.register("context.stack",function(v) showstackusage = v end)
-local storefunction, flushfunction
-local storenode, flushnode
-local registerfunction, unregisterfunction, reservefunction, knownfunctions, callfunctiononce
+local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting
--- if luafunctions then
-
- local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting
+local usedstack = function()
+ return nofused, noffreed
+end
- usedstack = function()
- return nofused, noffreed
+local flushfunction = function(slot,arg)
+ if arg() then
+ -- keep
+ elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ knownfunctions[slot] = false
+ else
+ -- keep
end
+end
- flushfunction = function(slot,arg)
- if arg() then
- -- keep
- elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
- noffreed = noffreed + 1
- freed[noffreed] = slot
- luafunctions[slot] = false
- else
- -- keep
- end
+local storefunction = function(arg)
+ local f = function(slot) flushfunction(slot,arg) end
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ knownfunctions[n] = f
+ return n
+ else
+ nofused = nofused + 1
+ knownfunctions[nofused] = f
+ return nofused
end
+end
- storefunction = function(arg)
- local f = function(slot) flushfunction(slot,arg) end
- if noffreed > 0 then
- local n = freed[noffreed]
- freed[noffreed] = nil
- noffreed = noffreed - 1
- luafunctions[n] = f
- return n
- else
- nofused = nofused + 1
- luafunctions[nofused] = f
- return nofused
- end
+local flushnode = function(slot,arg)
+ if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
+ writenode(arg)
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ knownfunctions[slot] = false
+ else
+ writenode(copynodelist(arg))
end
+end
- flushnode = function(slot,arg)
- if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
- writenode(arg)
- noffreed = noffreed + 1
- freed[noffreed] = slot
- luafunctions[slot] = false
- else
- writenode(copynodelist(arg))
- end
+local storenode = function(arg)
+ local f = function(slot) flushnode(slot,arg) end
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ knownfunctions[n] = f
+ return n
+ else
+ nofused = nofused + 1
+ knownfunctions[nofused] = f
+ return nofused
end
+end
- storenode = function(arg)
- local f = function(slot) flushnode(slot,arg) end
- if noffreed > 0 then
- local n = freed[noffreed]
- freed[noffreed] = nil
- noffreed = noffreed - 1
- luafunctions[n] = f
- return n
- else
- nofused = nofused + 1
- luafunctions[nofused] = f
- return nofused
- end
- end
+storage.storedfunctions = storage.storedfunctions or { }
+local storedfunctions = storage.storedfunctions
+local initex = environment.initex
- -- registerfunction = function(f)
- -- if type(f) == "string" then
- -- f = loadstring(f)
- -- end
- -- if type(f) ~= "function" then
- -- f = function() report_cld("invalid function %A",f) end
- -- end
- -- if noffreed > 0 then
- -- local n = freed[noffreed]
- -- freed[noffreed] = nil
- -- noffreed = noffreed - 1
- -- luafunctions[n] = f
- -- return n
- -- else
- -- nofused = nofused + 1
- -- luafunctions[nofused] = f
- -- return nofused
- -- end
- -- end
-
- storage.storedfunctions = storage.storedfunctions or { }
- local storedfunctions = storage.storedfunctions
- local initex = environment.initex
-
- storage.register("storage/storedfunctions", storedfunctions, "storage.storedfunctions")
-
- local f_resolve = nil
- local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1
-
- local function resolvestoredfunction(str)
- f_resolve = global
- lpegmatch(p_resolve,str)
- return f_resolve
- end
-
- local function expose(slot,f,...) -- so we can register yet undefined functions
- local func = resolvestoredfunction(f)
- if not func then
- func = function() report_cld("beware: unknown function %i called: %s",slot,f) end
- end
- luafunctions[slot] = func
- return func(...)
+storage.register("storage/storedfunctions", storedfunctions, "storage.storedfunctions")
+
+local f_resolve = nil
+local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1
+
+local function resolvestoredfunction(str)
+ f_resolve = global
+ lpegmatch(p_resolve,str)
+ return f_resolve
+end
+
+local function expose(slot,f,...) -- so we can register yet undefined functions
+ local func = resolvestoredfunction(f)
+ if not func then
+ func = function() report_cld("beware: unknown function %i called: %s",slot,f) end
end
+ knownfunctions[slot] = func
+ return func(...)
+end
- if initex then
- -- todo: log stored functions
- else
- local slots = table.sortedkeys(storedfunctions)
- local last = #slots
- if last > 0 then
- -- we restore the references
- for i=1,last do
- local slot = slots[i]
- local data = storedfunctions[slot]
- luafunctions[slot] = function(...)
- -- print(data) -- could be trace
- return expose(slot,data,...)
- end
+if initex then
+ -- todo: log stored functions
+else
+ local slots = table.sortedkeys(storedfunctions)
+ local last = #slots
+ if last > 0 then
+ -- we restore the references
+ for i=1,last do
+ local slot = slots[i]
+ local data = storedfunctions[slot]
+ knownfunctions[slot] = function(...)
+ -- print(data) -- could be trace
+ return expose(slot,data,...)
end
- -- we now know how many are defined
- nofused = slots[last]
- -- normally there are no holes in the list yet
- for i=1,nofused do
- if not luafunctions[i] then
- noffreed = noffreed + 1
- freed[noffreed] = i
- end
+ end
+ -- we now know how many are defined
+ nofused = slots[last]
+ -- normally there are no holes in the list yet
+ for i=1,nofused do
+ if not knownfunctions[i] then
+ noffreed = noffreed + 1
+ freed[noffreed] = i
end
- -- report_cld("%s registered functions, %s freed slots",last,noffreed)
end
+ -- report_cld("%s registered functions, %s freed slots",last,noffreed)
end
+end
- registerfunction = function(f,direct) -- either f=code or f=namespace,direct=name
- local slot, func
- if noffreed > 0 then
- slot = freed[noffreed]
- freed[noffreed] = nil
- noffreed = noffreed - 1
- else
- nofused = nofused + 1
- slot = nofused
- end
- if direct then
- if initex then
- func = function(...)
- expose(slot,f,...)
- end
- if initex then
- storedfunctions[slot] = f
- end
- else
- func = resolvestoredfunction(f)
- end
- if type(func) ~= "function" then
- func = function() report_cld("invalid resolve %A",f) end
+local registerfunction = function(f,direct) -- either f=code or f=namespace,direct=name
+ local slot, func
+ if noffreed > 0 then
+ slot = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ else
+ nofused = nofused + 1
+ slot = nofused
+ end
+ if direct then
+ if initex then
+ func = function(...)
+ expose(slot,f,...)
end
- elseif type(f) == "string" then
- func = loadstring(f)
- if type(func) ~= "function" then
- func = function() report_cld("invalid code %A",f) end
+ if initex then
+ storedfunctions[slot] = f
end
- elseif type(f) == "function" then
- func = f
else
- func = function() report_cld("invalid function %A",f) end
+ func = resolvestoredfunction(f)
end
- luafunctions[slot] = func
- return slot
- end
-
- unregisterfunction = function(slot)
- if luafunctions[slot] then
- noffreed = noffreed + 1
- freed[noffreed] = slot
- luafunctions[slot] = false
- else
- report_cld("invalid function slot %A",slot)
+ if type(func) ~= "function" then
+ func = function() report_cld("invalid resolve %A",f) end
end
- end
-
- reservefunction = function()
- if noffreed > 0 then
- local n = freed[noffreed]
- freed[noffreed] = nil
- noffreed = noffreed - 1
- return n
- else
- nofused = nofused + 1
- return nofused
+ elseif type(f) == "string" then
+ func = loadstring(f)
+ if type(func) ~= "function" then
+ func = function() report_cld("invalid code %A",f) end
end
+ elseif type(f) == "function" then
+ func = f
+ else
+ func = function() report_cld("invalid function %A",f) end
end
+ knownfunctions[slot] = func
+ return slot
+end
- callfunctiononce = function(slot)
- luafunctions[slot](slot)
+local unregisterfunction = function(slot)
+ if knownfunctions[slot] then
noffreed = noffreed + 1
freed[noffreed] = slot
- luafunctions[slot] = false
+ knownfunctions[slot] = false
+ else
+ report_cld("invalid function slot %A",slot)
end
+end
- table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end)
+local reservefunction = function()
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ return n
+ else
+ nofused = nofused + 1
+ return nofused
+ end
+end
- knownfunctions = luafunctions
+local callfunctiononce = function(slot)
+ knownfunctions[slot](slot)
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ knownfunctions[slot] = false
+end
- -- The next hack is a convenient way to define scanners at the Lua end and
- -- get them available at the TeX end. There is some dirty magic needed to
- -- prevent overload during format loading.
+setmetatablecall(knownfunctions,function(t,n) return knownfunctions[n](n) end)
- -- interfaces.scanners.foo = function() context("[%s]",tokens.scanners.string()) end : \scan_foo
+-- The next hack is a convenient way to define scanners at the Lua end and
+-- get them available at the TeX end. There is some dirty magic needed to
+-- prevent overload during format loading.
- interfaces.storedscanners = interfaces.storedscanners or { }
- local storedscanners = interfaces.storedscanners
+-- interfaces.scanners.foo = function() context("[%s]",tokens.scanners.string()) end : \scan_foo
- storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners")
+interfaces.storedscanners = interfaces.storedscanners or { }
+local storedscanners = interfaces.storedscanners
- local interfacescanners = table.setmetatablenewindex(function(t,k,v)
- if storedscanners[k] then
- -- report_cld("warning: scanner %a is already set",k)
- -- os.exit()
- -- \scan_<k> is already in the format
- -- report_cld("using interface scanner: %s",k)
- else
- -- todo: allocate slot here and pass it
- storedscanners[k] = true
- -- report_cld("installing interface scanner: %s",k)
- context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",k,k)
- end
- rawset(t,k,v)
- end)
+storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners")
- interfaces.scanners = interfacescanners
+local interfacescanners = setmetatablenewindex(function(t,k,v)
+ if storedscanners[k] then
+ -- report_cld("warning: scanner %a is already set",k)
+ -- os.exit()
+ -- \scan_<k> is already in the format
+ -- report_cld("using interface scanner: %s",k)
+ else
+ -- todo: allocate slot here and pass it
+ storedscanners[k] = true
+ -- report_cld("installing interface scanner: %s",k)
+ context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",k,k)
+ end
+ rawset(t,k,v)
+end)
--- else -- by now this is obsolete
---
--- local luafunctions, noffunctions = { }, 0
--- local luanodes, nofnodes = { }, 0
---
--- usedstack = function()
--- return noffunctions + nofnodes, 0
--- end
---
--- flushfunction = function(n)
--- local sn = luafunctions[n]
--- if not sn then
--- report_cld("data with id %a cannot be found on stack",n)
--- elseif not sn() and texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
--- luafunctions[n] = nil
--- end
--- end
---
--- storefunction = function(ti)
--- noffunctions = noffunctions + 1
--- luafunctions[noffunctions] = ti
--- return noffunctions
--- end
---
--- -- freefunction = function(n)
--- -- luafunctions[n] = nil
--- -- end
---
--- flushnode = function(n)
--- local sn = luanodes[n]
--- if not sn then
--- report_cld("data with id %a cannot be found on stack",n)
--- elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
--- writenode(sn)
--- luanodes[n] = nil
--- else
--- writenode(copynodelist(sn))
--- end
--- end
---
--- storenode = function(ti)
--- nofnodes = nofnodes + 1
--- luanodes[nofnodes] = ti
--- return nofnodes
--- end
---
--- _cldf_ = flushfunction -- global
--- _cldn_ = flushnode -- global
--- -- _cldl_ = function(n) return luafunctions[n]() end -- luafunctions(n)
--- _cldl_ = luafunctions
---
--- registerfunction = function(f)
--- if type(f) == "string" then
--- f = loadstring(f)
--- end
--- if type(f) ~= "function" then
--- f = function() report_cld("invalid function %A",f) end
--- end
--- noffunctions = noffunctions + 1
--- luafunctions[noffunctions] = f
--- return noffunctions
--- end
---
--- unregisterfunction = function(slot)
--- if luafunctions[slot] then
--- luafunctions[slot] = nil
--- else
--- report_cld("invalid function slot %A",slot)
--- end
--- end
---
--- reservefunction = function()
--- noffunctions = noffunctions + 1
--- return noffunctions
--- end
---
--- callfunctiononce = function(slot)
--- luafunctions[slot](slot)
--- luafunctions[slot] = nil
--- end
---
--- table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end)
---
--- knownfunctions = luafunctions
---
--- end
+interfaces.scanners = interfacescanners
context.functions = {
register = registerfunction,
@@ -441,8 +329,6 @@ context.functions = {
callonce = callfunctiononce,
}
-context.storenode = storenode -- private helper
-
function commands.ctxfunction(code,namespace)
context(registerfunction(code,namespace))
end
@@ -515,6 +401,27 @@ local function popcatcodes()
contentcatcodes = currentcatcodes
end
+function context.unprotect()
+ -- at the lua end
+ catcodelevel = catcodelevel + 1
+ catcodestack[catcodelevel] = currentcatcodes
+ currentcatcodes = prtcatcodes
+ contentcatcodes = prtcatcodes
+ -- at the tex end
+ flush("\\unprotect")
+end
+
+function context.protect()
+ -- at the tex end
+ flush("\\protect")
+ -- at the lua end
+ if catcodelevel > 0 then
+ currentcatcodes = catcodestack[catcodelevel] or currentcatcodes
+ catcodelevel = catcodelevel - 1
+ end
+ contentcatcodes = currentcatcodes
+end
+
context.catcodes = catcodes
context.pushcatcodes = pushcatcodes
context.popcatcodes = popcatcodes
@@ -560,7 +467,7 @@ local n_exception = ""
-- better a table specification
-function context.newtexthandler(specification) -- can also be used for verbose
+function context.newtexthandler(specification)
specification = specification or { }
--
local s_catcodes = specification.catcodes
@@ -816,127 +723,32 @@ end
-- if performance really matters we can consider a compiler but it will never
-- pay off
-local function prtwriter(command,...) -- already optimized before call
- flush(prtcatcodes,command)
- for i=1,select("#",...) do
- local ti = (select(i,...))
- if ti == nil then
- -- nothing
- elseif ti == "" then
- flush(prtcatcodes,"{}")
- else
- local tp = type(ti)
- if tp == "string" or tp == "number"then
- flush(prtcatcodes,"{",ti,"}")
- elseif tp == "function" then
- flush(prtcatcodes,"{\\cldl ",storefunction(ti),"}")
- -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
- elseif isnode(ti) then
- flush(prtcatcodes,"{\\cldl",storenode(ti),"}")
- -- flush(currentcatcodes,"{",storenode(ti),"}")
- else
- report_context("fatal error: prt %a gets a weird argument %a",command,ti)
- end
- end
- end
-end
+-- local function prtwriter(command,...) -- already optimized before call
+-- flush(prtcatcodes,command)
+-- for i=1,select("#",...) do
+-- local ti = (select(i,...))
+-- if ti == nil then
+-- -- nothing
+-- elseif ti == "" then
+-- flush(prtcatcodes,"{}")
+-- else
+-- local tp = type(ti)
+-- if tp == "string" or tp == "number"then
+-- flush(prtcatcodes,"{",ti,"}")
+-- elseif tp == "function" then
+-- flush(prtcatcodes,"{\\cldl ",storefunction(ti),"}")
+-- -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
+-- elseif isnode(ti) then
+-- flush(prtcatcodes,"{\\cldl",storenode(ti),"}")
+-- -- flush(currentcatcodes,"{",storenode(ti),"}")
+-- else
+-- report_context("fatal error: prt %a gets a weird argument %a",command,ti)
+-- end
+-- end
+-- end
+-- end
--- Originally we used this:
---
--- writer = function (parent,command,first,...) -- already optimized before call
--- local t = { first, ... }
--- flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
--- local direct = false
--- for i=1,#t do
--- local ti = t[i]
--- local typ = type(ti)
--- if direct then
--- if typ == "string" or typ == "number" then
--- flush(currentcatcodes,ti)
--- else -- node.write
--- report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
--- end
--- direct = false
--- elseif ti == nil then
--- -- nothing
--- elseif ti == "" then
--- flush(currentcatcodes,"{}")
--- elseif typ == "string" then
--- -- is processelines seen ?
--- if processlines and lpegmatch(containseol,ti) then
--- flush(currentcatcodes,"{")
--- flushlines(ti)
--- flush(currentcatcodes,"}")
--- elseif currentcatcodes == contentcatcodes then
--- flush(currentcatcodes,"{",ti,"}")
--- else
--- flush(currentcatcodes,"{")
--- flush(contentcatcodes,ti)
--- flush(currentcatcodes,"}")
--- end
--- elseif typ == "number" then
--- -- numbers never have funny catcodes
--- flush(currentcatcodes,"{",ti,"}")
--- elseif typ == "table" then
--- local tn = #ti
--- if tn == 0 then
--- local done = false
--- for k, v in next, ti do
--- if done then
--- if v == "" then
--- flush(currentcatcodes,",",k,'=')
--- else
--- flush(currentcatcodes,",",k,"={",v,"}")
--- end
--- else
--- if v == "" then
--- flush(currentcatcodes,"[",k,"=")
--- else
--- flush(currentcatcodes,"[",k,"={",v,"}")
--- end
--- done = true
--- end
--- end
--- if done then
--- flush(currentcatcodes,"]")
--- else
--- flush(currentcatcodes,"[]")
--- end
--- elseif tn == 1 then -- some 20% faster than the next loop
--- local tj = ti[1]
--- if type(tj) == "function" then
--- flush(currentcatcodes,"[\\cldf{",storefunction(tj),"}]")
--- else
--- flush(currentcatcodes,"[",tj,"]")
--- end
--- else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
--- for j=1,tn do
--- local tj = ti[j]
--- if type(tj) == "function" then
--- ti[j] = "\\cldf{" .. storefunction(tj) .. "}"
--- end
--- end
--- flush(currentcatcodes,"[",concat(ti,","),"]")
--- end
--- elseif typ == "function" then
--- flush(currentcatcodes,"{\\cldf{",storefunction(ti),"}}") -- todo: ctx|prt|texcatcodes
--- elseif typ == "boolean" then
--- if ti then
--- flushdirect(currentcatcodes,"\r")
--- else
--- direct = true
--- end
--- elseif typ == "thread" then
--- report_context("coroutines not supported as we cannot yield across boundaries")
--- elseif isnode(ti) then -- slow
--- flush(currentcatcodes,"{\\cldn{",storenode(ti),"}}")
--- else
--- report_context("error: %a gets a weird argument %a",command,ti)
--- end
--- end
--- end
-
-local core = table.setmetatableindex(function(parent,k)
+local core = setmetatableindex(function(parent,k)
local c = "\\" .. k -- tostring(k)
local f = function(first,...)
if first == nil then
@@ -949,6 +761,15 @@ local core = table.setmetatableindex(function(parent,k)
return f
end)
+core.cs = setmetatableindex(function(parent,k)
+ local c = "\\" .. k -- tostring(k)
+ local f = function()
+ flush(currentcatcodes,c)
+ end
+ parent[k] = f
+ return f
+end)
+
local indexer = function(parent,k)
if type(k) == "string" then
return core[k]
@@ -959,107 +780,60 @@ end
context.core = core
--- can only be done in non-ini mode so we'd have a bad mix and tracing
--- is bad too, so we just keep it as commented
+-- only for internal usage:
+
+-- local prtindexer = nil
--
--- local create = token.create
--- local twrite = token.write
+-- do
--
--- indexer = function(parent,k)
--- if type(k) == "string" then
--- local t = create(k)
--- if t.cmdname == "undefined_cs" then
--- report_cld("macro \\%s is not yet defined",k)
--- token.set_macro(k,"")
--- t = create(k)
--- end
--- local i = t.id
--- local f = function(first,...)
--- twrite(t.tok) --= we need to keep t uncollected
--- if first ~= nil then
--- return writer(parent,first,...)
+-- -- the only variant is not much faster than the full but it's more
+-- -- memory efficient
+--
+-- local protected = { }
+-- local protectedcs = { }
+-- context.protected = protected
+-- context.protectedcs = protectedcs
+--
+-- local function fullindexer(t,k)
+-- local c = "\\" .. k -- tostring(k)
+-- local v = function(first,...)
+-- if first == nil then
+-- flush(prtcatcodes,c)
+-- else
+-- return prtwriter(c,first,...)
-- end
-- end
--- parent[k] = f
--- return f
--- else
--- return context -- catch
+-- rawset(t,k,v) -- protected namespace
+-- return v
-- end
--- end
-
--- Potential optimization: after the first call we know if there will be an
--- argument. Of course there is the side effect that for instance abuse like
--- context.NC(str) fails as well as optional arguments. So, we don't do this
--- in practice. We just keep the next trick commented. The gain on some
--- 100000 calls is not that large: 0.100 => 0.95 which is neglectable.
--
--- local function constructor(parent,k,c,first,...)
--- if first == nil then
--- local f = function()
--- flush(currentcatcodes,c)
--- end
--- parent[k] = f
--- return f()
--- else
--- local f = function(...)
--- return writer(parent,c,...)
+-- local function onlyindexer(t,k)
+-- local c = "\\" .. k -- tostring(k)
+-- local v = function()
+-- flush(prtcatcodes,c)
-- end
--- parent[k] = f
--- return f(first,...)
+-- rawset(protected,k,v)
+-- rawset(t,k,v)
+-- return v
-- end
--- end
--
--- local function indexer(parent,k)
--- local c = "\\" .. k -- tostring(k)
--- local f = function(...)
--- return constructor(parent,k,c,...)
+-- protected.cs = setmetatableindex(function(parent,k)
+-- local c = "\\" .. k -- tostring(k)
+-- local v = function()
+-- flush(prtcatcodes,c)
+-- end
+-- parent[k] = v
+-- return v
-- end
--- parent[k] = f
--- return f
+--
+-- setmetatableindex(protected,fullindexer)
+-- setmetatablecall (protected,prtwriter)
+--
+-- setmetatableindex(protectedcs,onlyindexer)
+-- setmetatablecall (protectedcs,prtwriter)
+--
-- end
--- only for internal usage:
-
-local prtindexer = nil
-
-do
-
- -- the only variant is not much faster than the full but it's more
- -- memory efficient
-
- local protected = { }
- local protectedcs = { }
- context.protected = protected
- context.protectedcs = protectedcs
-
- local function fullindexer(t,k)
- local c = "\\" .. k -- tostring(k)
- local v = function(first,...)
- if first == nil then
- flush(prtcatcodes,c)
- else
- return prtwriter(c,first,...)
- end
- end
- rawset(t,k,v) -- protected namespace
- return v
- end
-
- local function onlyindexer(t,k)
- local c = "\\" .. k -- tostring(k)
- local v = function()
- flush(prtcatcodes,c)
- end
- rawset(protected,k,v)
- rawset(t,k,v)
- return v
- end
-
- setmetatable(protected, { __index = fullindexer, __call = prtwriter } )
- setmetatable(protectedcs, { __index = onlyindexer, __call = prtwriter } )
-
-end
-
-- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet)
local caller = function(parent,f,a,...)
@@ -1118,106 +892,29 @@ local caller = function(parent,f,a,...)
end
end
-function context.flushnode(n)
- flush(currentcatcodes,"\\cldl",storenode(n)," ")
- -- flush(currentcatcodes,"",storenode(n)," ")
-end
-
--- old code, from the early days:
---
--- caller = function(parent,f,a,...)
--- if not parent then
--- -- so we don't need to test in the calling (slower but often no issue)
--- elseif f ~= nil then
--- local typ = type(f)
--- if typ == "string" then
--- if f == "" then
--- -- new, can save a bit sometimes
--- -- if trace_context then
--- -- report_context("empty argument to context()")
--- -- end
--- elseif a then
--- flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
--- -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
--- elseif processlines and lpegmatch(containseol,f) then
--- flushlines(f)
--- else
--- flush(contentcatcodes,f)
--- end
--- elseif typ == "number" then
--- if a then
--- flush(currentcatcodes,f,a,...)
--- else
--- flush(currentcatcodes,f)
--- end
--- elseif typ == "function" then
--- -- ignored: a ...
--- flush(currentcatcodes,"{\\cldf{",storefunction(f),"}}") -- todo: ctx|prt|texcatcodes
--- elseif typ == "boolean" then
--- if f then
--- if a ~= nil then
--- flushlines(a)
--- else
--- flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
--- end
--- else
--- if a ~= nil then
--- -- no command, same as context(a,...)
--- writer(parent,"",a,...)
--- else
--- -- ignored
--- end
--- end
--- elseif typ == "thread" then
--- report_context("coroutines not supported as we cannot yield across boundaries")
--- elseif isnode(f) then -- slow
--- -- writenode(f)
--- flush(currentcatcodes,"\\cldn{",storenode(f),"}")
--- else
--- report_context("error: %a gets a weird argument %a","context",f)
--- end
--- end
--- end
---
--- function context.flushnode(n)
--- flush(currentcatcodes,"\\cldn{",storenode(n),"}")
--- end
+context.nodes = {
+ store = storenode,
+ flush = function(n)
+ flush(currentcatcodes,"\\cldl",storenode(n)," ")
+ -- flush(currentcatcodes,"",storenode(n)," ")
+ end,
+}
local defaultcaller = caller
-setmetatable(context, { __index = indexer, __call = caller } )
-
--- now we tweak unprotect and protect
-
--- context.call = caller -- somehow fails
-
-function context.unprotect()
- -- at the lua end
- insert(catcodestack,currentcatcodes)
- currentcatcodes = prtcatcodes
- contentcatcodes = currentcatcodes
- -- at the tex end
- flush("\\unprotect")
-end
-
-function context.protect()
- -- at the tex end
- flush("\\protect")
- -- at the lua end
- currentcatcodes = remove(catcodestack) or currentcatcodes
- contentcatcodes = currentcatcodes
-end
+setmetatableindex(context,indexer)
+setmetatablecall (context,caller)
function context.sprint(...) -- takes catcodes as first argument
flush(...)
end
-function context.fprint(catcodes,fmt,first,...)
+function context.fprint(fmt,first,...)
if type(catcodes) == "number" then
if first then
- flush(catcodes,formatters[fmt](first,...))
+ flush(currentcatcodes,formatters[fmt](first,...))
else
- flush(catcodes,fmt)
+ flush(currentcatcodes,fmt)
end
else
if fmt then
@@ -1228,23 +925,17 @@ function context.fprint(catcodes,fmt,first,...)
end
end
-function tex.fprint(fmt,first,...) -- goodie
- if first then
- flush(currentcatcodes,formatters[fmt](first,...))
- else
- flush(currentcatcodes,fmt)
- end
-end
+tex.fprint = context.fprint
-- logging
-local trace_stack = { }
+local trace_stack = { report_context }
local normalflush = flush
local normalflushdirect = flushdirect
----- normalflushraw = flushraw
local normalwriter = writer
-local currenttrace = nil
+local currenttrace = report_context
local nofwriters = 0
local nofflushes = 0
@@ -1352,68 +1043,39 @@ local tracedflushdirect = function(one,two,...)
end
end
-local function pushlogger(trace)
+function context.pushlogger(trace)
trace = trace or report_context
insert(trace_stack,currenttrace)
currenttrace = trace
- flush = tracedflush
- flushdirect = tracedflushdirect
- writer = tracedwriter
- return flush, writer, flushdirect
end
-local function poplogger()
- currenttrace = remove(trace_stack)
- if not currenttrace then
- flush = normalflush
- flushdirect = normalflushdirect
- writer = normalwriter
+function context.poplogger()
+ if #trace_stack > 1 then
+ currenttrace = remove(trace_stack) or report_context
+ else
+ currenttrace = report_context
end
- return flush, writer, flushdirect
end
-local function settracing(v)
+function context.settracing(v)
if v then
- return pushlogger(report_context)
+ flush = tracedflush
+ flushdirect = tracedflushdirect
+ writer = tracedwriter
else
- return poplogger()
+ flush = normalflush
+ flushdirect = normalflushdirect
+ writer = normalwriter
end
+ return flush, writer, flushdirect
end
--- todo: share flushers so that we can define in other files
-
-trackers.register("context.trace",settracing)
-
-context.pushlogger = pushlogger
-context.poplogger = poplogger
-context.settracing = settracing
-
--- -- untested, no time now:
---
--- local tracestack, tracestacktop = { }, false
---
--- function context.pushtracing(v)
--- insert(tracestack,tracestacktop)
--- if type(v) == "function" then
--- pushlogger(v)
--- v = true
--- else
--- pushlogger()
--- end
--- tracestacktop = v
--- settracing(v)
--- end
---
--- function context.poptracing()
--- poplogger()
--- tracestacktop = remove(tracestack) or false
--- settracing(tracestacktop)
--- end
-
function context.getlogger()
- return flush, writer, flush_direct
+ return flush, writer, flushdirect
end
+trackers.register("context.trace",context.settracing)
+
local trace_cld = false trackers.register("context.files", function(v) trace_cld = v end)
do
@@ -1481,13 +1143,14 @@ do
function context.stopcollecting()
level = level - 1
if level < 1 then
+ local result = concat(collected,sentinel)
flush = normalflush
flushdirect = normalflushdirect
tracingpermitted = permitted
- viafile(concat(collected,sentinel))
collected = nil
nofcollected = 0
level = 0
+ viafile(result)
end
end
@@ -1531,71 +1194,84 @@ end
-- context.delayed (todo: lines)
-local delayed = { } context.delayed = delayed -- creates function (maybe also store them)
+do
+
+ local delayed = { }
+
+ local function indexer(parent,k)
+ local f = function(...)
+ local a = { ... }
+ return function()
+ -- return context[k](unpack(a))
+ return core[k](unpack(a))
+ end
+ end
+ parent[k] = f
+ return f
+ end
-local function indexer(parent,k)
- local f = function(...)
+ local function caller(parent,...) -- todo: nodes
local a = { ... }
return function()
- -- return context[k](unpack(a))
- return core[k](unpack(a))
+ -- return context(unpack(a))
+ return defaultcaller(context,unpack(a))
end
end
- parent[k] = f
- return f
-end
-local function caller(parent,...) -- todo: nodes
- local a = { ... }
- return function()
- -- return context(unpack(a))
- return defaultcaller(context,unpack(a))
- end
+ setmetatableindex(delayed,indexer)
+ setmetatablecall (delayed,caller)
+
+ context.delayed = delayed
+
end
-setmetatable(delayed, { __index = indexer, __call = caller } )
+do
+
+ -- context.nested (todo: lines), creates strings
--- context.nested (todo: lines)
+ local nested = { }
-local nested = { } context.nested = nested -- creates strings
+ local function indexer(parent,k) -- not ok when traced
+ local f = function(...)
+ local t, savedflush, n = { }, flush, 0
+ flush = function(c,f,s,...) -- catcodes are ignored
+ n = n + 1
+ t[n] = s and concat{f,s,...} or f -- optimized for #args == 1
+ end
+ -- context[k](...)
+ core[k](...)
+ flush = savedflush
+ return concat(t)
+ end
+ parent[k] = f
+ return f
+ end
-local function indexer(parent,k) -- not ok when traced
- local f = function(...)
+ local function caller(parent,...)
local t, savedflush, n = { }, flush, 0
flush = function(c,f,s,...) -- catcodes are ignored
n = n + 1
t[n] = s and concat{f,s,...} or f -- optimized for #args == 1
end
- -- context[k](...)
- core[k](...)
+ -- context(...)
+ defaultcaller(context,...)
flush = savedflush
return concat(t)
end
- parent[k] = f
- return f
-end
-local function caller(parent,...)
- local t, savedflush, n = { }, flush, 0
- flush = function(c,f,s,...) -- catcodes are ignored
- n = n + 1
- t[n] = s and concat{f,s,...} or f -- optimized for #args == 1
- end
- -- context(...)
- defaultcaller(context,...)
- flush = savedflush
- return concat(t)
-end
+ setmetatableindex(nested,indexer)
+ setmetatablecall (nested,caller)
-setmetatable(nested, { __index = indexer, __call = caller } )
+ context.nested = nested
+
+end
-- verbatim
-function context.newindexer(catcodes)
+function context.newindexer(catcodes,cmdcodes)
local handler = { }
local function indexer(parent,k)
- -- local command = context[k]
local command = core[k]
local f = function(...)
local savedcatcodes = contentcatcodes
@@ -1614,238 +1290,253 @@ function context.newindexer(catcodes)
contentcatcodes = savedcatcodes
end
- setmetatable(handler, { __index = indexer, __call = caller } )
+ handler.cs = setmetatableindex(function(parent,k)
+ local c = "\\" .. k -- tostring(k)
+ local f = function()
+ flush(cmdcodes,c)
+ end
+ parent[k] = f
+ return f
+ end)
+
+ setmetatableindex(handler,indexer)
+ setmetatablecall (handler,caller)
return handler
end
-context.verbatim = context.newindexer(vrbcatcodes)
-context.puretext = context.newindexer(txtcatcodes)
--------.protected = context.newindexer(prtcatcodes)
+context.verbatim = context.newindexer(vrbcatcodes,ctxcatcodes)
+context.puretext = context.newindexer(txtcatcodes,ctxcatcodes)
+context.protected = context.newindexer(prtcatcodes,prtcatcodes)
-- formatted
-local formatted = { } context.formatted = formatted
+do
+
+ local formatted = { }
--- local function indexer(parent,k)
--- local command = context[k]
--- local f = function(fmt,...)
--- command(formatters[fmt](...))
--- end
--- parent[k] = f
--- return f
--- end
+ -- formatted.command([catcodes,]format[,...])
-local function indexer(parent,k)
- if type(k) == "string" then
- local c = "\\" .. k
- local f = function(first,second,...)
- if first == nil then
- flush(currentcatcodes,c)
- elseif second then
- return writer(parent,c,formatters[first](second,...))
+ local function formattedflush(parent,c,catcodes,fmt,...)
+ if type(catcodes) == "number" then
+ if fmt then
+ local result
+ pushcatcodes(catcodes)
+ result = writer(parent,c,formatters[fmt](...))
+ popcatcodes()
+ return result
else
- return writer(parent,c,first)
+ -- no need to change content catcodes
+ return writer(parent,c)
end
+ else
+ return writer(parent,c,formatters[catcodes](fmt,...))
end
- parent[k] = f
- return f
- else
- return context -- catch
end
-end
-
--- local function caller(parent,...)
--- context.fprint(...)
--- end
-local function caller(parent,catcodes,fmt,first,...)
- if type(catcodes) == "number" then
- if first then
- flush(catcodes,formatters[fmt](first,...))
+ local function indexer(parent,k)
+ if type(k) == "string" then
+ local c = "\\" .. k
+ local f = function(first,...)
+ if first == nil then
+ flush(currentcatcodes,c)
+ else
+ return formattedflush(parent,c,first,...)
+ end
+ end
+ parent[k] = f
+ return f
else
- flush(catcodes,fmt)
+ return context -- catch
end
- else
- if fmt then
- flush(formatters[catcodes](fmt,first,...))
+ end
+
+ -- formatted([catcodes,]format[,...])
+
+ local function caller(parent,catcodes,fmt,...)
+ if not catcodes then
+ -- nothing
+ elseif type(catcodes) == "number" then
+ if fmt then
+ flush(catcodes,formatters[fmt](...))
+ end
else
- flush(catcodes)
+ flush(formatters[catcodes](fmt,...))
end
end
+
+ setmetatableindex(formatted,indexer)
+ setmetatablecall (formatted,caller)
+
+ context.formatted = formatted
+
end
-setmetatable(formatted, { __index = indexer, __call = caller } )
+do
--- metafun (this will move to another file)
+ -- metafun (this will move to another file)
-local metafun = { } context.metafun = metafun
+ local metafun = { }
-local mpdrawing = "\\MPdrawing"
+ function metafun.start()
+ context.startMPcode()
+ end
-local function caller(parent,f,a,...)
- if not parent then
- -- skip
- elseif f then
- local typ = type(f)
- if typ == "string" then
- if a then
- flush(currentcatcodes,mpdrawing,"{",formatters[f](a,...),"}")
- else
- flush(currentcatcodes,mpdrawing,"{",f,"}")
- end
- elseif typ == "number" then
- if a then
- flush(currentcatcodes,mpdrawing,"{",f,a,...,"}")
- else
- flush(currentcatcodes,mpdrawing,"{",f,"}")
- end
- elseif typ == "function" then
- -- ignored: a ...
- flush(currentcatcodes,mpdrawing,"{\\cldl",store_(f),"}")
- -- flush(currentcatcodes,mpdrawing,"{",store_(f),"}")
- elseif typ == "boolean" then
- -- ignored: a ...
- if f then
- flush(currentcatcodes,mpdrawing,"{^^M}")
- else
- report_context("warning: %a gets argument 'false' which is currently unsupported","metafun")
- end
- else
- report_context("error: %a gets a weird argument %a","metafun",tostring(f))
- end
+ function metafun.stop()
+ context.stopMPcode()
end
-end
-setmetatable(metafun, { __call = caller } )
+ setmetatablecall(metafun,defaultcaller)
-function metafun.start()
- context.resetMPdrawing()
-end
+ function metafun.color(name) -- obsolete
+ return name -- formatters[ [[\MPcolor{%s}]] ](name)
+ end
-function metafun.stop()
- context.MPdrawingdonetrue()
- context.getMPdrawing()
-end
+ -- metafun.delayed
-function metafun.color(name)
- return formatters[ [[\MPcolor{%s}]] ](name)
-end
+ local delayed = { }
--- metafun.delayed
+ local function indexer(parent,k)
+ local f = function(...)
+ local a = { ... }
+ return function()
+ return metafun[k](unpack(a))
+ end
+ end
+ parent[k] = f
+ return f
+ end
-local delayed = { } metafun.delayed = delayed
-local function indexer(parent,k)
- local f = function(...)
+ local function caller(parent,...)
local a = { ... }
return function()
- return metafun[k](unpack(a))
+ return metafun(unpack(a))
end
end
- parent[k] = f
- return f
-end
+ setmetatableindex(delayed,indexer)
+ setmetatablecall (delayed,caller)
-local function caller(parent,...)
- local a = { ... }
- return function()
- return metafun(unpack(a))
- end
-end
+ context.metafun = metafun
+ metafun.delayed = delayed
-setmetatable(delayed, { __index = indexer, __call = caller } )
+end
-- helpers:
-function context.concat(...)
- context(concat(...))
-end
+do
+
+ function context.concat(...)
+ context(concat(...))
+ end
+
+ local p_texescape = patterns.texescape
+
+ function context.escaped(s)
+ return context(lpegmatch(p_texescape,s) or s)
+ end
-local p_texescape = patterns.texescape
+ function context.escape(s)
+ return lpegmatch(p_texescape,s) or s or ""
+ end
-function context.escaped(s)
- return context(lpegmatch(p_texescape,s) or s)
end
-- templates
-local single = lpegP("%")
-local double = lpegP("%%")
-local lquoted = lpegP("%[")
-local rquoted = lpegP("]%")
+do
-local start = [[
-local texescape = lpeg.patterns.texescape
-local lpegmatch = lpeg.match
-return function(variables) return
-]]
+ local single = lpegP("%")
+ local double = lpegP("%%")
+ local lquoted = lpegP("%[")
+ local rquoted = lpegP("]%")
+ local space = lpegP(" ")
-local stop = [[
-end
-]]
-
-local replacer = lpegP { "parser",
- parser = lpegCs(lpegCc(start) * lpegV("step") * (lpegCc("..") * lpegV("step"))^0 * lpegCc(stop)),
- unquoted = (lquoted/'') * ((lpegC((1-rquoted)^1)) / "lpegmatch(texescape,variables['%0'] or '')" ) * (rquoted/''),
- escape = double/'%%',
- key = (single/'') * ((lpegC((1-single)^1)) / "(variables['%0'] or '')" ) * (single/''),
- step = lpegV("unquoted")
- + lpegV("escape")
- + lpegV("key")
- + lpegCc("\n[===[") * (1 - lpegV("unquoted") - lpegV("escape") - lpegV("key"))^1 * lpegCc("]===]\n"),
-}
+ local start = [[
+ local texescape = lpeg.patterns.texescape
+ local lpegmatch = lpeg.match
+ return function(variables) return
+ ]]
-local templates = { }
+ local stop = [[
+ end
+ ]]
+
+ local replacer = lpegP { "parser",
+ parser = lpegCs(lpegCc(start) * lpegV("step") * (lpegCc("..") * lpegV("step"))^0 * lpegCc(stop)),
+ unquoted = (lquoted*space/'')
+ * ((lpegC((1-space*rquoted)^1)) / "lpegmatch(texescape,variables%0 or '')" )
+ * (space*rquoted/'')
+ + (lquoted/'')
+ * ((lpegC((1-rquoted)^1)) / "lpegmatch(texescape,variables['%0'] or '')" )
+ * (rquoted/''),
+ key = (single*space/'')
+ * ((lpegC((1-space*single)^1)) / "(variables%0 or '')" )
+ * (space*single/'')
+ + (single/'')
+ * ((lpegC((1-single)^1)) / "(variables['%0'] or '')" )
+ * (single/''),
+ escape = double/'%%',
+ step = lpegV("unquoted")
+ + lpegV("escape")
+ + lpegV("key")
+ + lpegCc("\n[===[") * (1 - lpegV("unquoted") - lpegV("escape") - lpegV("key"))^1 * lpegCc("]===]\n"),
+ }
+
+ local templates = { }
-local function indexer(parent,k)
- local v = lpegmatch(replacer,k)
- if not v then
- v = "error: no valid template (1)"
- else
- v = loadstring(v)
- if type(v) ~= "function" then
- v = "error: no valid template (2)"
+ local function indexer(parent,k)
+ local v = lpegmatch(replacer,k)
+ if not v then
+ -- report_template("invalid template:\n%s",k)
+ v = "error: no valid template (1)"
else
- v = v()
- if not v then
- v = "error: no valid template (3)"
- end
- end
- end
- if type(v) == "function" then
- local f = function(first,second)
- if second then
- pushcatcodes(first)
- flushlines(v(second))
- popcatcodes()
+ local f = loadstring(v)
+ if type(f) ~= "function" then
+ -- report_template("invalid template:\n%s\n=>\n%s",k,v)
+ v = "error: no valid template (2)"
else
- flushlines(v(first))
+ f = f()
+ if not f then
+ -- report_template("invalid template:\n%s\n=>\n%s",k,v)
+ v = "error: no valid template (3)"
+ else
+ v = f
+ end
end
end
- parent[k] = f
- return f
- else
- return function()
- flush(v)
+ if type(v) == "function" then
+ local f = function(first,second)
+ if second then
+ pushcatcodes(first)
+ flushlines(v(second))
+ popcatcodes()
+ else
+ flushlines(v(first))
+ end
+ end
+ parent[k] = f
+ return f
+ else
+ return function()
+ flush(v)
+ end
end
+
end
-end
+ local function caller(parent,k,...)
+ return parent[k](...)
+ end
-local function caller(parent,k,...)
- return parent[k](...)
-end
+ setmetatableindex(templates,indexer)
+ setmetatablecall (templates,caller)
-setmetatable(templates, { __index = indexer, __call = caller } )
+ context.templates = templates
-function context.template(template,...)
- context(templates[template](...))
end
-context.templates = templates
-
-- The above is a bit over the top as we could also stick to a simple context.replace
-- which is fast enough anyway, but the above fits in nicer, also with the catcodes.
--
diff --git a/tex/context/base/mkiv/cldf-stp.lua b/tex/context/base/mkiv/cldf-stp.lua
index bd5b084ca..eeed47594 100644
--- a/tex/context/base/mkiv/cldf-stp.lua
+++ b/tex/context/base/mkiv/cldf-stp.lua
@@ -37,7 +37,7 @@ local stepper = nil
local stack = { } -- will never be deep so no gc needed
local depth = 0
-local nextstep = function()
+local function nextstep()
if status(stepper) == "dead" then
stepper = stack[depth]
depth = depth - 1
@@ -51,7 +51,7 @@ interfaces.implement {
actions = nextstep,
}
-local ctx_resume = context.protectedcs.clf_step
+local ctx_resume = context.protected.cs.clf_step
function context.step(first,...)
if first ~= nil then
diff --git a/tex/context/base/mkiv/cldf-ver.lua b/tex/context/base/mkiv/cldf-ver.lua
index 66432eb1c..3710b2415 100644
--- a/tex/context/base/mkiv/cldf-ver.lua
+++ b/tex/context/base/mkiv/cldf-ver.lua
@@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['cldf-ver'] = {
-- better when used mixed with other code (synchronization issue).
local concat, tohandle = table.concat, table.tohandle
-local find, splitlines = string.find, string.splitlines
+local splitlines, strip = string.splitlines, string.strip
local tostring, type = tostring, type
local context = context
@@ -28,11 +28,15 @@ local function t_tocontext(...)
context.popcatcodes()
end
-local function s_tocontext(...) -- we need to catch {\}
+local function s_tocontext(first,...) -- we need to catch {\}
context.type()
context("{")
context.pushcatcodes("verbatim")
- context(concat({...}," "))
+ if first then
+ context(first) -- no need to waste a { }
+ else
+ context(concat({first,...}," "))
+ end
context.popcatcodes()
context("}")
end
@@ -44,34 +48,41 @@ end
table .tocontext = t_tocontext
string .tocontext = s_tocontext
boolean.tocontext = b_tocontext
+number .tocontext = s_tocontext
+
+local tocontext = {
+ ["string"] = s_tocontext,
+ ["table"] = t_tocontext,
+ ["boolean"] = b_tocontext,
+ ["number"] = s_tocontext,
+ ["function"] = function() s_tocontext("<function>") end,
+ ["nil"] = function() s_tocontext("<nil>") end,
+ -- ------------ = -------- can be extended elsewhere
+}
-function context.tocontext(first,...)
- local t = type(first)
- if t == "string" then
- s_tocontext(first,...)
- elseif t == "table" then
- t_tocontext(first,...)
- elseif t == "boolean" then
- b_tocontext(first,...)
+table.setmetatableindex(tocontext,function(t,k)
+ local v = function(s)
+ s_tocontext("<"..tostring(s)..">")
end
-end
+ t[k] = v
+ return v
+end)
+
+table.setmetatablecall(tocontext,function(t,k,...)
+ tocontext[type(k)](k)
+end)
--- function context.tobuffer(name,str)
--- context.startbuffer { name }
--- context.pushcatcodes("verbatim")
--- local lines = (type(str) == "string" and find(str,"[\n\r]") and splitlines(str)) or str
--- for i=1,#lines do
--- context(lines[i] .. " ")
--- end
--- context.stopbuffer()
--- context.popcatcodes()
--- end
+context.tocontext = tocontext
context.tobuffer = buffers.assign -- (name,str,catcodes)
-function context.tolines(str)
+function context.tolines(str,strip)
local lines = type(str) == "string" and splitlines(str) or str
for i=1,#lines do
- context(lines[i] .. " ")
+ if strip then
+ context(strip(lines[i]) .. " ")
+ else
+ context(lines[i] .. " ")
+ end
end
end
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index fb4707e9e..2141b8616 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2016.07.23 13:35}
+\newcontextversion{2016.07.25 17:40}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 1f773ada8..b3e58ad75 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2016.07.23 13:35}
+\edef\contextversion{2016.07.25 17:40}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/core-env.lua b/tex/context/base/mkiv/core-env.lua
index 34220fedf..cd5439919 100644
--- a/tex/context/base/mkiv/core-env.lua
+++ b/tex/context/base/mkiv/core-env.lua
@@ -11,35 +11,38 @@ if not modules then modules = { } end modules ['core-env'] = {
--
-- if tex.modes['xxxx'] then .... else .... end
-local P, C, S, Cc, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.match, lpeg.patterns
+local rawset = rawset
-local context = context
+local P, C, S, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.match, lpeg.patterns
-local texgetcount = tex.getcount
+local context = context
+local ctxcore = context.core
-local allocate = utilities.storage.allocate
-local setmetatableindex = table.setmetatableindex
-local setmetatablecall = table.setmetatablecall
+local texgetcount = tex.getcount
-local createtoken = token.create
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local setmetatablenewindex = table.setmetatablenewindex
+local setmetatablecall = table.setmetatablecall
-tex.modes = allocate { }
-tex.systemmodes = allocate { }
-tex.constants = allocate { }
-tex.conditionals = allocate { }
-tex.ifs = allocate { }
-tex.isdefined = allocate { }
+local createtoken = token.create
-local modes = { }
-local systemmodes = { }
+texmodes = allocate { } tex.modes = texmodes
+texsystemmodes = allocate { } tex.systemmodes = texsystemmodes
+texconstants = allocate { } tex.constants = texconstants
+texconditionals = allocate { } tex.conditionals = texconditionals
+texifs = allocate { } tex.ifs = texifs
+texisdefined = allocate { } tex.isdefined = texisdefined
+
+local modes = { }
+local systemmodes = { }
-- we could use the built-in tex.is[count|dimen|skip|toks] here but caching
-- at the lua en dis not that bad (and we need more anyway)
-- undefined: mode == 0 or cmdname = "undefined_cs"
-
-local cache = table.setmetatableindex(function(t,k)
+local cache = setmetatableindex(function(t,k)
local v = createtoken(k)
t[k] = v
return v
@@ -50,7 +53,7 @@ end)
local iftrue = cache["iftrue"].mode
local undefined = cache["*undefined*crap*"].mode -- is this ok?
-setmetatableindex(tex.modes, function(t,k)
+setmetatableindex(texmodes, function(t,k)
local m = modes[k]
if m then
return m()
@@ -59,13 +62,16 @@ setmetatableindex(tex.modes, function(t,k)
if cache[n].mode == 0 then
return false
else
- modes[k] = function() return texgetcount(n) == 1 end
+ rawset(modes,k, function() return texgetcount(n) == 1 end)
return texgetcount(n) == 1 -- 2 is prevented
end
end
end)
+setmetatablenewindex(texmodes, function(t,k)
+ report_mode("you cannot set the %s named %a this way","mode",k)
+end)
-setmetatableindex(tex.systemmodes, function(t,k)
+setmetatableindex(texsystemmodes, function(t,k)
local m = systemmodes[k]
if m then
return m()
@@ -74,37 +80,45 @@ setmetatableindex(tex.systemmodes, function(t,k)
if cache[n].mode == 0 then
return false
else
- systemmodes[k] = function() return texgetcount(n) == 1 end
+ rawset(systemmodes,k,function() return texgetcount(n) == 1 end)
return texgetcount(n) == 1 -- 2 is prevented
end
end
end)
+setmetatablenewindex(texsystemmodes, function(t,k)
+ report_mode("you cannot set the %s named %a this way","systemmode",k)
+end)
-setmetatableindex(tex.constants, function(t,k)
+setmetatableindex(texconstants, function(t,k)
return cache[k].mode ~= 0 and texgetcount(k) or 0
end)
+setmetatablenewindex(texconstants, function(t,k)
+ report_mode("you cannot set the %s named %a this way","constant",k)
+end)
-setmetatableindex(tex.conditionals, function(t,k) -- 0 == true
+setmetatableindex(texconditionals, function(t,k) -- 0 == true
return cache[k].mode ~= 0 and texgetcount(k) == 0
end)
+setmetatablenewindex(texconditionals, function(t,k)
+ report_mode("you cannot set the %s named %a this way","conditional",k)
+end)
-table.setmetatableindex(tex.ifs, function(t,k)
- -- local mode = cache[k].mode
- -- if mode == 0 then
- -- return nil
- -- else
- -- return mode == iftrue
- -- end
+table.setmetatableindex(texifs, function(t,k)
return cache[k].mode == iftrue
end)
+setmetatablenewindex(texifs, function(t,k)
+ -- just ignore
+end)
-setmetatableindex(tex.isdefined, function(t,k)
+setmetatableindex(texisdefined, function(t,k)
return k and cache[k].mode ~= 0
end)
-
-setmetatablecall(tex.isdefined, function(t,k)
+setmetatablecall(texisdefined, function(t,k)
return k and cache[k].mode ~= 0
end)
+setmetatablenewindex(texisdefined, function(t,k)
+ -- just ignore
+end)
local dimencode = cache["scratchdimen"] .command
local countcode = cache["scratchcounter"] .command
@@ -151,107 +165,35 @@ function tex.type(name)
return types[cache[name].command] or "macro"
end
--- -- old token code
---
--- local csname_id = token.csname_id
--- local create = token.create
---
--- local undefined = csname_id("*undefined*crap*")
--- local iftrue = create("iftrue")[2] -- inefficient hack
---
--- setmetatableindex(tex.modes, function(t,k)
--- local m = modes[k]
--- if m then
--- return m()
--- else
--- local n = "mode>" .. k
--- if csname_id(n) == undefined then
--- return false
--- else
--- modes[k] = function() return texgetcount(n) == 1 end
--- return texgetcount(n) == 1 -- 2 is prevented
--- end
--- end
--- end)
---
--- setmetatableindex(tex.systemmodes, function(t,k)
--- local m = systemmodes[k]
--- if m then
--- return m()
--- else
--- local n = "mode>*" .. k
--- if csname_id(n) == undefined then
--- return false
--- else
--- systemmodes[k] = function() return texgetcount(n) == 1 end
--- return texgetcount(n) == 1 -- 2 is prevented
--- end
--- end
--- end)
---
--- setmetatableindex(tex.constants, function(t,k)
--- return csname_id(k) ~= undefined and texgetcount(k) or 0
--- end)
---
--- setmetatableindex(tex.conditionals, function(t,k) -- 0 == true
--- return csname_id(k) ~= undefined and texgetcount(k) == 0
--- end)
---
--- setmetatableindex(tex.ifs, function(t,k)
--- -- k = "if" .. k -- better not
--- return csname_id(k) ~= undefined and create(k)[2] == iftrue -- inefficient, this create, we need a helper
--- end)
---
--- setmetatableindex(tex.isdefined, function(t,k)
--- return k and csname_id(k) ~= undefined
--- end)
--- setmetatablecall(tex.isdefined, function(t,k)
--- return k and csname_id(k) ~= undefined
--- end)
---
--- local lookuptoken = token.lookup
---
--- local dimencode = lookuptoken("scratchdimen" )[1]
--- local countcode = lookuptoken("scratchcounter")[1]
--- local tokencode = lookuptoken("scratchtoken" )[1]
--- local skipcode = lookuptoken("scratchskip" )[1]
---
--- local types = {
--- [dimencode] = "dimen",
--- [countcode] = "count",
--- [tokencode] = "token",
--- [skipcode ] = "skip",
--- }
---
--- function tex.isdimen(name)
--- return lookuptoken(name)[1] == dimencode
--- end
---
--- function tex.iscount(name)
--- return lookuptoken(name)[1] == countcode
--- end
---
--- function tex.istoken(name)
--- return lookuptoken(name)[1] == tokencode
--- end
---
--- function tex.isskip(name)
--- return lookuptoken(name)[1] == skipcode
--- end
---
--- function tex.type(name)
--- return types[lookuptoken(name)[1]] or "macro"
--- end
-
function context.setconditional(name,value)
if value then
- context.settruevalue(name)
+ ctxcore.settruevalue(name)
+ else
+ ctxcore.setfalsevalue(name)
+ end
+end
+
+function context.setmode(name,value)
+ if value then
+ ctxcore.setmode(name)
else
- context.setfalsevalue(name)
+ ctxcore.resetmode(name)
end
end
----- arg = P("{") * C(patterns.nested) * P("}") + Cc("")
+function context.setsystemmode(name,value)
+ if value then
+ ctxcore.setsystemmode(name)
+ else
+ ctxcore.resetsystemmode(name)
+ end
+end
+
+context.modes = texmodes
+context.systemmodes = texsystemmodes
+context.conditionals = texconditionals
+-------.constants = texconstants
+-------.ifs = texifs
local sep = S("), ")
local str = C((1-sep)^1)
@@ -259,9 +201,9 @@ local tag = P("(") * C((1-S(")" ))^1) * P(")")
local arg = P("(") * C((1-S("){"))^1) * P("{") * C((1-P("}"))^0) * P("}") * P(")")
local pattern = (
- P("lua") * tag / context.luasetup
- + P("xml") * arg / context.setupwithargument -- or xmlw as xmlsetup has swapped arguments
- + (P("tex") * tag + str) / context.texsetup
+ P("lua") * tag / ctxcore.luasetup
+ + P("xml") * arg / ctxcore.setupwithargument -- or xmlw as xmlsetup has swapped arguments
+ + (P("tex") * tag + str) / ctxcore.texsetup
+ sep^1
)^1
@@ -270,4 +212,3 @@ interfaces.implement {
actions = function(str) lpegmatch(pattern,str) end,
arguments = "string"
}
-
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index c11199178..de7592c87 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -25,7 +25,6 @@ local commands = commands
local implement = interfaces.implement
local ctx_sprint = context.sprint
------ ctx_fprint = context.fprint -- a bit inefficient
local ctx_doifelsesomething = commands.doifelsesomething
local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
diff --git a/tex/context/base/mkiv/node-ppt.lua b/tex/context/base/mkiv/node-ppt.lua
index 0f7df2b6e..82acf2ff4 100644
--- a/tex/context/base/mkiv/node-ppt.lua
+++ b/tex/context/base/mkiv/node-ppt.lua
@@ -85,14 +85,13 @@ local function register(where,data,...)
end
local writenode = node.write
-local flushnode = context.flushnode
+local flushnode = context.nodes.flush
function commands.deferredproperty(...)
-- context(register(...))
flushnode(register(...))
end
-
function commands.immediateproperty(...)
writenode(register(...))
end
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index d13f9afa1..72504da84 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 9bcec69dd..111a82393 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-bkm.lua b/tex/context/base/mkiv/strc-bkm.lua
index 9ec6734e8..e30a91820 100644
--- a/tex/context/base/mkiv/strc-bkm.lua
+++ b/tex/context/base/mkiv/strc-bkm.lua
@@ -112,11 +112,13 @@ end
function bookmarks.place()
if next(names) then
- local levels = { }
- local noflevels = 0
- local lastlevel = 1
- local nofblocks = #lists.sectionblocks -- always >= 1
+ local levels = { }
+ local noflevels = 0
+ local lastlevel = 1
+ local nofblocks = #lists.sectionblocks -- always >= 1
local showblocktitle = toboolean(numberspec.showblocktitle,true)
+-- local allsections = sections.collected
+ local allblocks = sections.sectionblockdata
for i=1,nofblocks do
local block = lists.sectionblocks[i]
local blockdone = nofblocks == 1
@@ -155,9 +157,9 @@ function bookmarks.place()
if not blockdone then
if showblocktitle then
-- add block entry
- local blockdata = sections.sectionblockdata[block]
- noflevels = noflevels + 1
+ local blockdata = allblocks[block]
local references = li.references
+ noflevels = noflevels + 1
levels[noflevels] = {
level = 1, -- toplevel
title = stripped(blockdata.bookmark ~= "" and blockdata.bookmark or block),
@@ -184,19 +186,29 @@ function bookmarks.place()
title = titledata.title or "?"
-- end
end
- if numbered[name] then
- local sectiondata = sections.collected[li.references.section]
- local numberdata = li.numberdata
- if sectiondata and numberdata then
- if not numberdata.hidenumber then
- -- we could typeset the number and convert it
- local number = sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata)
- if number and #number > 0 then
- title = concat(number) .. " " .. title
- end
- end
- end
- end
+-- if numbered[name] then
+-- local sectiondata = allsections[li.references.section]
+-- if sectiondata then
+-- local numberdata = li.numberdata
+-- if numberdata and not numberdata.hidenumber then
+-- -- we could typeset the number and convert it
+-- local number = sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata)
+-- if number and #number > 0 then
+-- title = concat(number) .. " " .. title
+-- end
+-- end
+-- end
+-- end
+if numbered[name] then
+ local numberdata = li.numberdata
+ if numberdata and not numberdata.hidenumber then
+ -- we could typeset the number and convert it
+ local number = sections.typesetnumber(numberdata,"direct",numberspec,numberdata)
+ if number and #number > 0 then
+ title = concat(number) .. " " .. title
+ end
+ end
+end
noflevels = noflevels + 1
local references = li.references
levels[noflevels] = {
diff --git a/tex/context/base/mkiv/syst-lua.lua b/tex/context/base/mkiv/syst-lua.lua
index d35a5111a..ee3b8c327 100644
--- a/tex/context/base/mkiv/syst-lua.lua
+++ b/tex/context/base/mkiv/syst-lua.lua
@@ -15,11 +15,11 @@ local commands = commands
local context = context
local implement = interfaces.implement
-local protectedcs = context.protectedcs -- efficient
-local ctx_firstoftwoarguments = protectedcs.firstoftwoarguments
-local ctx_secondoftwoarguments = protectedcs.secondoftwoarguments
-local ctx_firstofoneargument = protectedcs.firstofoneargument
-local ctx_gobbleoneargument = protectedcs.gobbleoneargument
+local ctx_protected_cs = context.protected.cs -- more efficient
+local ctx_firstoftwoarguments = ctx_protected_cs.firstoftwoarguments
+local ctx_secondoftwoarguments = ctx_protected_cs.secondoftwoarguments
+local ctx_firstofoneargument = ctx_protected_cs.firstofoneargument
+local ctx_gobbleoneargument = ctx_protected_cs.gobbleoneargument
local two_strings = interfaces.strings[2]
diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua
index f549d1cd6..674a0bf5a 100644
--- a/tex/context/base/mkiv/tabl-xtb.lua
+++ b/tex/context/base/mkiv/tabl-xtb.lua
@@ -30,7 +30,7 @@ local tonumber, next, rawget = tonumber, next, rawget
local commands = commands
local context = context
-local ctxnode = context.flushnode
+local ctxnode = context.nodes.flush
local implement = interfaces.implement
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 93e6af7c2..bffb1807c 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -565,21 +565,21 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous,trace_o
setattr(info,a_layer,layer)
if vertical then
if shift == 0 then
- info = linked_nodes(current,info)
+ info = linked_nodes(current,dp ~= 0 and new_kern(-dp) or nil,info)
elseif trace_origin then
local size = 2*size
local origin = o_cache[size]
origin = copy_list(origin)
if getid(parent) == vlist_code then
setfield(origin,"shift",-shift)
- info = linked_nodes(current,new_kern(-size),origin,new_kern(-size),info)
+ info = linked_nodes(current,new_kern(-size),origin,new_kern(-size-dp),info)
else
-- todo .. i need an example
- info = linked_nodes(current,info)
+ info = linked_nodes(current,dp ~= 0 and new_kern(-dp) or nil,info)
end
setfield(current,"shift",0)
else
- info = linked_nodes(current,info)
+ info = linked_nodes(current,new_dp ~= 0 and new_kern(-dp) or nil,info)
setfield(current,"shift",0)
end
info = new_vlist(info,wd,ht,dp,shift)
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index d62c1fc3f..4ff51c931 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 8d9ab851e..9f71d5ece 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/s-characters-properties.lua b/tex/context/modules/mkiv/s-characters-properties.lua
new file mode 100644
index 000000000..dc9fb8f93
--- /dev/null
+++ b/tex/context/modules/mkiv/s-characters-properties.lua
@@ -0,0 +1,83 @@
+if not modules then modules = { } end modules ['s-characters-properties'] = {
+ version = 1.001,
+ comment = "companion to s-characters-properties.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.characters = moduledata.characters or { }
+moduledata.characters.properties = moduledata.characters.properties or { }
+
+local catcodenames = { [0] =
+ "escape", "begingroup", "endgroup", "mathshift",
+ "alignment", "endofline", "parameter", "superscript",
+ "subscript", "ignore", "space", "letter",
+ "other", "active", "comment", "invalid",
+}
+
+table.swapped(catcodes,catcodes)
+
+local catcodes = context.catcodes
+local getcatcode = tex.getcatcode
+local c_context = catcodes.context
+local c_tex = catcodes.tex
+local c_protect = catcodes.protect
+local c_text = catcodes.text
+local c_verbatim = catcodes.verbatim
+
+local context = context
+local ctx_NC = context.NC
+local ctx_NR = context.NR
+local ctx_MR = context.MR
+local ctx_ML = context.ML
+local ctx_bold = context.bold
+local ctx_verbatim = context.verbatim
+
+function moduledata.characters.properties.showcatcodes(specification)
+
+ local function range(f,l,quit)
+ if quit then
+ ctx_MR()
+ end
+ for i=f,l do
+ ctx_NC()
+ if quit then
+ ctx_verbatim("%c .. %c",f,l)
+ else
+ ctx_verbatim("%c",i)
+ end
+ ctx_NC() context(catcodenames[getcatcode(c_tex,i)])
+ ctx_NC() context(catcodenames[getcatcode(c_context,i)])
+ ctx_NC() context(catcodenames[getcatcode(c_protect,i)])
+ ctx_NC() context(catcodenames[getcatcode(c_text,i)])
+ ctx_NC() context(catcodenames[getcatcode(c_verbatim,i)])
+ ctx_NC() ctx_NR()
+ if quit then
+ ctx_MR()
+ break
+ end
+ end
+ end
+
+ context.starttabulate { "|c|c|c|c|c|c|" }
+ ctx_ML()
+ ctx_NC() ctx_bold("ascii")
+ ctx_NC() ctx_bold("context")
+ ctx_NC() ctx_bold("tex")
+ ctx_NC() ctx_bold("protect")
+ ctx_NC() ctx_bold("text")
+ ctx_NC() ctx_bold("verbatim")
+ ctx_NC() ctx_NR()
+ ctx_ML()
+ range(32,47)
+ range(48,57,true)
+ range(58,64)
+ range(65,90,true)
+ range(91,96)
+ range(97,122,true)
+ range(123,126)
+ ctx_ML()
+ context.stoptabulate()
+
+end
diff --git a/tex/context/modules/mkiv/s-characters-properties.mkiv b/tex/context/modules/mkiv/s-characters-properties.mkiv
new file mode 100644
index 000000000..0beea4868
--- /dev/null
+++ b/tex/context/modules/mkiv/s-characters-properties.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=s-characters-propertis,
+%D version=2016.07.24, % moved here
+%D title=\CONTEXT\ Style File,
+%D subtitle=Character properties,
+%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.
+
+\startmodule[characters-properties]
+
+\registerctxluafile{s-characters-properties}{}
+
+\installmodulecommandluasingle \showcharactercatcodes {moduledata.characters.properties.showcatcodes}
+
+\stopmodule
+
+\continueifinputfile{s-characters-properties.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showcharactercatcodes
+
+\stoptext
diff --git a/tex/context/sample/common/khatt-en.tex b/tex/context/sample/common/khatt-en.tex
index f994513e7..52891af25 100644
--- a/tex/context/sample/common/khatt-en.tex
+++ b/tex/context/sample/common/khatt-en.tex
@@ -1,4 +1,4 @@
-ʿAlī ibn Abī Ṭālib said to his scribe ʿUbaydullāh ibn Abī Rāfiʿ:
-your inkwell before you, sharpen the edge of your pen, make sure
+ʿAlī ibn Abī Ṭālib said to his scribe ʿUbaydullāh ibn Abī Rāfiʿ: Set
+down your inkwell before you, sharpen the edge of your pen, make sure
there is open space between the lines, and set your letter|-|spacing
closely. Now {\em that} is the way to make the script shine!
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index b6c46e2db..fd525fc18 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 07/23/16 13:35:55
+-- merge date : 07/25/16 17:40:20
do -- begin closure to overcome local limits and interference