summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-03-21 09:47:34 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-03-21 09:47:34 +0100
commitf47b4939787074397c9ea37c1d892a1f7ccc7290 (patch)
tree7768be58efe0faab8e2dccb999686c6a674bf0d7 /tex/context/base/mkiv
parentf923c957a3b322ae3ee8e7a0b20df1580869bee7 (diff)
downloadcontext-f47b4939787074397c9ea37c1d892a1f7ccc7290.tar.gz
2018-03-21 09:24:00
Diffstat (limited to 'tex/context/base/mkiv')
-rw-r--r--tex/context/base/mkiv/back-exp.lua39
-rw-r--r--tex/context/base/mkiv/back-exp.mkiv7
-rw-r--r--tex/context/base/mkiv/buff-ver.lua9
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/cont-run.lua25
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/data-exp.lua86
-rw-r--r--tex/context/base/mkiv/font-ext.lua10
-rw-r--r--tex/context/base/mkiv/font-otj.lua113
-rw-r--r--tex/context/base/mkiv/l-lua.lua3
-rw-r--r--tex/context/base/mkiv/l-table.lua4
-rw-r--r--tex/context/base/mkiv/lxml-aux.lua26
-rw-r--r--tex/context/base/mkiv/lxml-css.lua145
-rw-r--r--tex/context/base/mkiv/lxml-css.mkiv40
-rw-r--r--tex/context/base/mkiv/lxml-tex.lua20
-rw-r--r--tex/context/base/mkiv/math-ini.mkiv4
-rw-r--r--tex/context/base/mkiv/meta-ini.lua5
-rw-r--r--tex/context/base/mkiv/node-nut.lua10
-rw-r--r--tex/context/base/mkiv/node-syn.lua53
-rw-r--r--tex/context/base/mkiv/page-ini.lua17
-rw-r--r--tex/context/base/mkiv/page-inj.mkvi20
-rw-r--r--tex/context/base/mkiv/page-pcl.mkiv54
-rw-r--r--tex/context/base/mkiv/page-set.mkiv4
-rw-r--r--tex/context/base/mkiv/publ-imp-apa.mkvi2
-rw-r--r--tex/context/base/mkiv/scrn-fld.mkvi2
-rw-r--r--tex/context/base/mkiv/scrn-pag.mkvi13
-rw-r--r--tex/context/base/mkiv/spac-hor.mkiv35
-rw-r--r--tex/context/base/mkiv/spac-ver.mkiv16
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25856 -> 25801 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin252176 -> 254074 bytes
-rw-r--r--tex/context/base/mkiv/strc-flt.mkvi39
-rw-r--r--tex/context/base/mkiv/typo-duc.lua5
-rw-r--r--tex/context/base/mkiv/util-sha.lua326
-rw-r--r--tex/context/base/mkiv/util-sql-imp-library.lua2
-rw-r--r--tex/context/base/mkiv/util-sql-loggers.lua5
-rw-r--r--tex/context/base/mkiv/util-sql-logins.lua39
-rw-r--r--tex/context/base/mkiv/util-sql-sessions.lua14
-rw-r--r--tex/context/base/mkiv/util-sql-tickets.lua22
-rw-r--r--tex/context/base/mkiv/util-sql-users.lua102
-rw-r--r--tex/context/base/mkiv/util-str.lua6
40 files changed, 992 insertions, 334 deletions
diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua
index 84be8cff9..2d51d933d 100644
--- a/tex/context/base/mkiv/back-exp.lua
+++ b/tex/context/base/mkiv/back-exp.lua
@@ -39,7 +39,7 @@ local validstring = string.valid
local lpegmatch = lpeg.match
local utfchar, utfvalues = utf.char, utf.values
local concat, insert, remove, merge, sort = table.concat, table.insert, table.remove, table.merge, table.sort
-local sortedhash = table.sortedhash
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
local formatters = string.formatters
local todimen = number.todimen
local replacetemplate = utilities.templates.replace
@@ -74,6 +74,7 @@ local implement = interfaces.implement
local included = backends.included
local settings_to_array = utilities.parsers.settings_to_array
+local settings_to_hash = utilities.parsers.settings_to_hash
local setmetatableindex = table.setmetatableindex
local tasks = nodes.tasks
@@ -1790,7 +1791,35 @@ do
resolve(di,element,n,fulltag)
end
- extras.float = resolve
+ local floats = { }
+
+ function structurestags.setfloat(options,method)
+ floats[locatedtag("float")] = {
+ options = options,
+ method = method,
+ }
+ end
+
+ function extras.float(di,element,n,fulltag)
+ local hash = floats[fulltag]
+ if hash then
+ local method = hash.method
+ if not method or method == "" then
+ method = "here"
+ end
+ setattribute(di,"method",method)
+ local options = hash.options
+ if options and options ~= "" then
+ options = settings_to_hash(options)
+ options[method] = nil
+ options = concat(sortedkeys(options),",")
+ if #options > 0 then
+ setattribute(di,"options",options)
+ end
+ end
+ end
+ resolve(di,element,n,fulltag)
+ end
-- todo: internal is already hashed
@@ -3845,6 +3874,12 @@ implement {
}
implement {
+ name = "settagfloat",
+ actions = structurestags.setfloat,
+ arguments = { "string", "string" }
+}
+
+implement {
name = "settagdelimitedsymbol",
actions = structurestags.settagdelimitedsymbol,
arguments = "string"
diff --git a/tex/context/base/mkiv/back-exp.mkiv b/tex/context/base/mkiv/back-exp.mkiv
index 6803c2a92..ad5ba8371 100644
--- a/tex/context/base/mkiv/back-exp.mkiv
+++ b/tex/context/base/mkiv/back-exp.mkiv
@@ -228,6 +228,13 @@
\to \everyenableelements
\appendtoks
+ \unexpanded\def\dotagregisterfloat#1#2%
+ {\iftrialtypesetting\else
+ \clf_settagfloat{#1}{#2}\relax
+ \fi}%
+\to \everyenableelements
+
+\appendtoks
\let\specialfixedspace \explicitfixedspace
\let\specialobeyedspace \explicitobeyedspace
\let\specialstretchedspace\explicitstretchedspace
diff --git a/tex/context/base/mkiv/buff-ver.lua b/tex/context/base/mkiv/buff-ver.lua
index a39e90bda..d9178b1df 100644
--- a/tex/context/base/mkiv/buff-ver.lua
+++ b/tex/context/base/mkiv/buff-ver.lua
@@ -14,7 +14,7 @@ if not modules then modules = { } end modules ['buff-ver'] = {
-- todo: update to match context scite lexing
local type, next, rawset, rawget, setmetatable, getmetatable, tonumber = type, next, rawset, rawget, setmetatable, getmetatable, tonumber
-local format, lower, upper,match, find, sub = string.format, string.lower, string.upper, string.match, string.find, string.sub
+local lower, upper,match, find, sub = string.lower, string.upper, string.match, string.find, string.sub
local splitlines = string.splitlines
local concat = table.concat
local C, P, R, S, V, Carg, Cc, Cs = lpeg.C, lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Carg, lpeg.Cc, lpeg.Cs
@@ -239,12 +239,13 @@ function visualizers.load(name)
name = lower(name)
if rawget(specifications,name) == nil then
name = lower(name)
- local texname = findfile(format("buff-imp-%s.mkiv",name))
- local luaname = findfile(format("buff-imp-%s.lua" ,name))
+ local impname = "buff-imp-"..name
+ local texname = findfile(addsuffix(impname,"mkiv"))
+ local luaname = findfile(addsuffix(impname,"lua"))
if texname == "" or luaname == "" then
-- assume a user specific file
luaname = findfile(addsuffix(name,"mkiv"))
- texname = findfile(addsuffix(name,"lua" ))
+ texname = findfile(addsuffix(name,"lua"))
end
if texname == "" or luaname == "" then
if trace_visualize then
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 79be46772..cb7607eac 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{2018.03.10 14:52}
+\newcontextversion{2018.03.21 09:16}
%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/cont-run.lua b/tex/context/base/mkiv/cont-run.lua
index 73620adb6..9bd252e60 100644
--- a/tex/context/base/mkiv/cont-run.lua
+++ b/tex/context/base/mkiv/cont-run.lua
@@ -180,13 +180,36 @@ local function processjob()
local suffix = environment.suffix
local filename = environment.filename -- hm, not inputfilename !
- if arguments.synctex then
+ if arguments.nosynctex then
+ luatex.synctex.setup {
+ state = interfaces.variables.never,
+ }
+ elseif arguments.synctex then
luatex.synctex.setup {
state = interfaces.variables.start,
method = interfaces.variables.max,
}
end
+ -- -- todo: move from mtx-context to here:
+ --
+ -- local timing = arguments.timing
+ -- if type(timing) == "string" then
+ -- context.usemodule { timing }
+ -- end
+ -- local nodates = arguments.nodates
+ -- if nodates then
+ -- context.enabledirectives { "backend.date=" .. (type(nodates) == "string" and nodates or "no") }
+ -- end
+ -- local trailerid = arguments.trailerid
+ -- if type(trailerid) == "string" then
+ -- context.enabledirectives { "backend.trailerid=" .. trailerid }
+ -- end
+ -- local profile = arguments.profile
+ -- if profile then
+ -- context.enabledirectives { "system.profile=" .. tonumber(profile) or 0 }
+ -- end
+
-- -- already done in mtxrun / mtx-context, has to happen very early
--
-- if arguments.silent then
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 482a24192..f786d1d0c 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -42,7 +42,7 @@
%D has to match \type {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2018.03.10 14:52}
+\edef\contextversion{2018.03.21 09:16}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/data-exp.lua b/tex/context/base/mkiv/data-exp.lua
index 994399e36..76fd3c7b0 100644
--- a/tex/context/base/mkiv/data-exp.lua
+++ b/tex/context/base/mkiv/data-exp.lua
@@ -337,80 +337,6 @@ local addcasecraptoo = true -- experiment to let case matter a bit (still fuzzy
-- So, we assume either a lowercase name or a mixed case one but only one such case
-- as having Foo fOo foo FoO FOo etc on the system is braindead in any sane project.
--- local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
--- local full = path == "" and spec or (spec .. path .. '/')
--- local dirs = { }
--- local nofdirs = 0
--- local pattern = tolerant and lessweird or weird
--- for name in directory(full) do
--- if not lpegmatch(pattern,name) then
--- local mode = attributes(full..name,"mode")
--- if mode == "file" then
--- n = n + 1
--- local lower = lower(name)
--- local paths = files[lower]
--- if paths then
--- if onlyone then
--- -- forget about it
--- else
--- if name ~= lower then
--- local rl = remap[lower]
--- if not rl then
--- remap[lower] = name
--- r = r + 1
--- elseif trace_globbing and rl ~= name then
--- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
--- end
--- if addcasecraptoo then
--- local paths = files[name]
--- if not paths then
--- files[name] = path
--- elseif type(paths) == "string" then
--- files[name] = { paths, path }
--- else
--- paths[#paths+1] = path
--- end
--- end
--- end
--- if type(paths) == "string" then
--- files[lower] = { paths, path }
--- else
--- paths[#paths+1] = path
--- end
--- end
--- else -- probably unique anyway
--- files[lower] = path
--- if name ~= lower then
--- local rl = remap[lower]
--- if not rl then
--- remap[lower] = name
--- r = r + 1
--- elseif trace_globbing and rl ~= name then
--- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
--- end
--- end
--- end
--- elseif mode == "directory" then
--- m = m + 1
--- nofdirs = nofdirs + 1
--- if path ~= "" then
--- dirs[nofdirs] = path .. "/" .. name
--- else
--- dirs[nofdirs] = name
--- end
--- end
--- end
--- end
--- if nofdirs > 0 then
--- sort(dirs)
--- for i=1,nofdirs do
--- files, remap, n, m, r = scan(files,remap,spec,dirs[i],n,m,r,onlyonce,tolerant)
--- end
--- end
--- scancache[sub(full,1,-2)] = files
--- return files, remap, n, m, r
--- end
-
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
local full = path == "" and spec or (spec .. path .. '/')
local dirlist = { }
@@ -585,12 +511,12 @@ function resolvers.get_from_content(content,path,name) -- or (content,name)
else
-- this one does a lookup and resolves a remapped name
local name = path
- if addcasecraptoo then
- local path = files[name]
- if path then
- return path, name
- end
- end
+-- if addcasecraptoo then
+-- local path = files[name]
+-- if path then
+-- return path, name
+-- end
+-- end
local used = lower(name)
local path = files[used]
if path then
diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua
index f9db5e0d9..0def526d0 100644
--- a/tex/context/base/mkiv/font-ext.lua
+++ b/tex/context/base/mkiv/font-ext.lua
@@ -671,15 +671,17 @@ local function manipulatedimensions(tfmdata,key,value)
local width = newwidth or oldwidth or 0
local height = newheight or oldheight or 0
local depth = newdepth or olddepth or 0
- if oldwidth ~= width then
+ if oldwidth ~= width or oldheight ~= height or olddepth ~= depth then
-- Defining the tables in one step is more efficient
-- than adding fields later.
local private = getprivate(tfmdata)
+ local newslot = { "slot", 1, private } -- { "slot", 0, private }
local new_c
- local commands = {
+ local commands = oldwidth ~= width and {
{ "right", (width - oldwidth) / 2 },
- { "slot", 1, private },
- -- { "slot", 0, private },
+ newslot,
+ } or {
+ newslot,
}
if height > 0 then
if depth > 0 then
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index 1f9fd1ac1..9037939df 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/font-otj.lua
@@ -34,13 +34,20 @@ if not nodes.properties then return end
local next, rawget, tonumber = next, rawget, tonumber
local fastcopy = table.fastcopy
-local registertracker = trackers.register
+local registertracker = trackers.register
+local registerdirective = directives.register
local trace_injections = false registertracker("fonts.injections", function(v) trace_injections = v end)
local trace_marks = false registertracker("fonts.injections.marks", function(v) trace_marks = v end)
local trace_cursive = false registertracker("fonts.injections.cursive", function(v) trace_cursive = v end)
local trace_spaces = false registertracker("fonts.injections.spaces", function(v) trace_spaces = v end)
+-- local fix_cursive_marks = false
+--
+-- registerdirective("fonts.injections.fixcursivemarks", function(v)
+-- fix_cursive_marks = v
+-- end)
+
local report_injections = logs.reporter("fonts","injections")
local report_spaces = logs.reporter("fonts","spaces")
@@ -1033,6 +1040,8 @@ local function inject_everything(head,where)
local marks = { }
local nofmarks = 0
--
+ -- local applyfix = hascursives and fix_cursive_marks
+ --
-- move out
--
local function processmark(p,n,pn) -- p = basenode
@@ -1118,7 +1127,7 @@ local function inject_everything(head,where)
end
end
-- begin of temp fix --
- local base = nil -- bah, some arabic fonts have no mark anchoring
+ -- local base = nil -- bah, some arabic fonts have no mark anchoring
-- end of temp fix --
while current do
local next = getnext(current)
@@ -1126,62 +1135,62 @@ local function inject_everything(head,where)
if char then
local p = rawget(properties,current)
-- begin of temp fix --
- if hascursives then
- if not p then
- local m = fontmarks[getfont(current)]
- if m and m[char] then
- if base then
- p = { injections = { markbasenode = base } }
- nofmarks = nofmarks + 1
- marks[nofmarks] = current
- properties[current] = p
- hasmarks = true
- end
- else
- base = current
- end
- end
- end
+ -- if applyfix then
+ -- if not p then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- p = { injections = { markbasenode = base } }
+ -- nofmarks = nofmarks + 1
+ -- marks[nofmarks] = current
+ -- properties[current] = p
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end
-- end of temp fix
if p then
local i = p.injections
-- begin of temp fix --
- if hascursives then
- if not i then
- local m = fontmarks[getfont(current)]
- if m and m[char] then
- if base then
- i = { markbasenode = base }
- nofmarks = nofmarks + 1
- marks[nofmarks] = current
- p.injections = i
- hasmarks = true
- end
- else
- base = current
- end
- end
- end
+ -- if applyfix then
+ -- if not i then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- i = { markbasenode = base }
+ -- nofmarks = nofmarks + 1
+ -- marks[nofmarks] = current
+ -- p.injections = i
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end
-- end of temp fix --
if i then
local pm = i.markbasenode
-- begin of temp fix --
- if hascursives then
- if not pm then
- local m = fontmarks[getfont(current)]
- if m and m[char] then
- if base then
- pm = base
- i.markbasenode = pm
- hasmarks = true
- end
- else
- base = current
- end
- else
- base = current
- end
- end
+ -- if applyfix then
+ -- if not pm then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- pm = base
+ -- i.markbasenode = pm
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
-- end of temp fix --
if pm then
nofmarks = nofmarks + 1
@@ -1326,9 +1335,11 @@ local function inject_everything(head,where)
prevdisc = nil
prevglyph = current
elseif char == false then
+ -- base = nil
prevdisc = nil
prevglyph = current
elseif id == disc_code then
+ -- base = nil
pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
local done = false
if pre then
@@ -1460,9 +1471,9 @@ local function inject_everything(head,where)
prevglyph = nil
prevdisc = current
else
+ -- base = nil
prevglyph = nil
prevdisc = nil
-base = nil
end
prev = current
current = next
diff --git a/tex/context/base/mkiv/l-lua.lua b/tex/context/base/mkiv/l-lua.lua
index b36bde422..426706f06 100644
--- a/tex/context/base/mkiv/l-lua.lua
+++ b/tex/context/base/mkiv/l-lua.lua
@@ -242,6 +242,9 @@ local loaded = package.loaded
if not loaded["socket"] then loaded["socket"] = loaded["socket.core"] end
if not loaded["mime"] then loaded["mime"] = loaded["mime.core"] end
+if not socket.mime then socket.mime = package.loaded["mime"] end
+
+if not loaded["socket.mime"] then loaded["socket.mime"] = socket.mime end
if not loaded["socket.http"] then loaded["socket.http"] = socket.http end
if not loaded["socket.ftp"] then loaded["socket.ftp"] = socket.ftp end
if not loaded["socket.smtp"] then loaded["socket.smtp"] = socket.smtp end
diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua
index 9d7152544..269b89667 100644
--- a/tex/context/base/mkiv/l-table.lua
+++ b/tex/context/base/mkiv/l-table.lua
@@ -1225,10 +1225,10 @@ function table.reversed(t)
end
end
-function table.reverse(t)
+function table.reverse(t) -- check with 5.3 ?
if t then
local n = #t
- for i=1,floor(n/2) do
+ for i=1,floor(n/2) do -- maybe just n//2
local j = n - i + 1
t[i], t[j] = t[j], t[i]
end
diff --git a/tex/context/base/mkiv/lxml-aux.lua b/tex/context/base/mkiv/lxml-aux.lua
index 59760cb94..78cf1d6bd 100644
--- a/tex/context/base/mkiv/lxml-aux.lua
+++ b/tex/context/base/mkiv/lxml-aux.lua
@@ -1022,3 +1022,29 @@ function xml.totable(x,strip,flat)
return convert(x,strip,flat)
end
end
+
+-- namespace, name, attributes
+-- name, attributes
+-- name
+
+function xml.rename(e,namespace,name,attributes)
+ if type(e) ~= "table" or not e.tg then
+ return
+ end
+ if type(name) == "table" then
+ attributes = name
+ name = namespace
+ namespace = ""
+ elseif type(name) ~= "string" then
+ attributes = { }
+ name = namespace
+ namespace = ""
+ end
+ if type(attributes) ~= "table" then
+ attributes = { }
+ end
+ e.ns = namespace
+ e.rn = namespace
+ e.tg = name
+ e.at = attributes
+end
diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua
index bc6297ac2..a4d15ba1f 100644
--- a/tex/context/base/mkiv/lxml-css.lua
+++ b/tex/context/base/mkiv/lxml-css.lua
@@ -12,10 +12,13 @@ local topattern, is_empty = string.topattern, string.is_empty
local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf, lpeg.Cs
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local sort = table.sort
+local setmetatableindex = table.setmetatableindex
xml.css = xml.css or { }
local css = xml.css
+local getid = lxml.getid
+
if not number.dimenfactors then
require("util-dim.lua")
end
@@ -26,6 +29,9 @@ local cmf = 1/dimenfactors.cm
local mmf = 1/dimenfactors.mm
local inf = 1/dimenfactors["in"]
+local whitespace = lpegpatterns.whitespace
+local skipspace = whitespace^0
+
local percentage, exheight, emwidth, pixels
if tex then
@@ -62,7 +68,7 @@ local validdimen = Cg(lpegpatterns.number,'a') * (
+ Cb('a') * Carg(1) / pixels
)
-local pattern = (validdimen * lpegpatterns.whitespace^0)^1
+local pattern = (validdimen * skipspace)^1
-- todo: default if ""
@@ -645,9 +651,7 @@ end
local P, R, S, C, Cs, Ct, Cc, Carg, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Carg, lpeg.match
-local whitespace = lpegpatterns.whitespace
local p_number = lpegpatterns.integer / tonumber
-local p_space = whitespace^0
local p_key = C((R("az","AZ","09") + S("_-"))^1)
local p_left = S("#.[],:()")
@@ -657,10 +661,10 @@ local p_value = C((1-P("]"))^0)
local p_unquoted = (P('"')/"") * C((1-P('"'))^0) * (P('"')/"")
+ (1-P("]"))^1
local p_element = Ct( (
- P(">") * p_space * Cc(s_element_a) +
- P("+") * p_space * Cc(s_element_b) +
- P("~") * p_space * Cc(s_element_c) +
- Cc(s_element_d)
+ P(">") * skipspace * Cc(s_element_a) +
+ P("+") * skipspace * Cc(s_element_b) +
+ P("~") * skipspace * Cc(s_element_c) +
+ Cc(s_element_d)
) * p_tag )
local p_attribute = P("[") * Ct(Cc(s_attribute) * p_key * (
P("=" ) * Cc(1) * Cs( p_unquoted)
@@ -670,16 +674,16 @@ local p_attribute = P("[") * Ct(Cc(s_attribute) * p_key * (
+ P("~=") * Cc(3) * Cs( p_unquoted)
)^0 * P("]"))
-local p_separator = p_space * P(",") * p_space
+local p_separator = skipspace * P(",") * skipspace
-local p_formula = p_space * P("(")
- * p_space
+local p_formula = skipspace * P("(")
+ * skipspace
* (
- p_number * p_space * (C("n") * p_space * (p_number + Cc(0)))^-1
+ p_number * skipspace * (C("n") * skipspace * (p_number + Cc(0)))^-1
+ P("even") * Cc(0) * Cc("n") * Cc(2)
+ P("odd") * Cc(-1) * Cc("n") * Cc(2)
)
- * p_space
+ * skipspace
* P(")")
local p_step = P(".") * Ct(Cc(s_attribute) * Cc("class") * Cc(3) * p_tag)
@@ -699,13 +703,13 @@ local p_step = P(".") * Ct(Cc(s_attribute) * Cc("class") * Cc(3) * p
+ P(":empty") * Ct(Cc(s_empty) )
+ P(":root") * Ct(Cc(s_root) )
-local p_not = P(":not") * Cc(true) * p_space * P("(") * p_space * p_step * p_space * P(")")
-local p_yes = Cc(false) * p_space * p_step
+local p_not = P(":not") * Cc(true) * skipspace * P("(") * skipspace * p_step * skipspace * P(")")
+local p_yes = Cc(false) * skipspace * p_step
-local p_stepper = Ct((p_space * (p_not+p_yes))^1)
-local p_steps = Ct((p_stepper * p_separator^0)^1) * p_space * (P(-1) + function() print("error") end)
+local p_stepper = Ct((skipspace * (p_not+p_yes))^1)
+local p_steps = Ct((p_stepper * p_separator^0)^1) * skipspace * (P(-1) + function() print("error") end)
-local cache = table.setmetatableindex(function(t,k)
+local cache = setmetatableindex(function(t,k)
local v = lpegmatch(p_steps,k) or false
t[k] = v
return v
@@ -877,10 +881,115 @@ xml.applyselector= selector
-- local s = [[ g:empty ]]
-- local s = [[ g:root ]]
+-- local c = css.applyselector(xml.convert(t),s) for i=1,#c do print(xml.tostring(c[i])) end
+
function css.applyselector(x,str)
-- the wrapping needs checking so this is a placeholder
return applyselector({ x },str)
end
--- local c = css.applyselector(xml.convert(t),s) for i=1,#c do print(xml.tostring(c[i])) end
+-- -- Some helpers to map e.g. style attributes:
+--
+-- -- string based (2.52):
+--
+-- local match = string.match
+-- local topattern = string.topattern
+--
+-- function css.stylevalue(root,name)
+-- local list = getid(root).at.style
+-- if list then
+-- local pattern = topattern(name) .. ":%s*([^;]+)"
+-- local value = match(list,pattern)
+-- if value then
+-- context(value)
+-- end
+-- end
+-- end
+--
+-- -- string based, cached (2.28 / 2.17 interfaced):
+--
+-- local match = string.match
+-- local topattern = string.topattern
+--
+-- local patterns = table.setmetatableindex(function(t,k)
+-- local v = topattern(k) .. ":%s*([^;]+)"
+-- t[k] = v
+-- return v
+-- end)
+--
+-- function css.stylevalue(root,name)
+-- local list = getid(root).at.style
+-- if list then
+-- local value = match(list,patterns[name])
+-- if value then
+-- context(value)
+-- end
+-- end
+-- end
+--
+-- -- lpeg based (4.26):
+--
+-- the lpeg variant also removes trailing spaces and accepts spaces before a colon
+
+local ctx_sprint = context.sprint
+local ctx_xmlvalue = context.xmlvalue
+
+local colon = P(":")
+local semicolon = P(";")
+local eos = P(-1)
+local somevalue = (1 - (skipspace * (semicolon + eos)))^1
+local someaction = skipspace * colon * skipspace * (somevalue/ctx_sprint)
+
+-- function css.stylevalue(root,name)
+-- local list = getid(root).at.style
+-- if list then
+-- lpegmatch(P(name * someaction + 1)^0,list)
+-- end
+-- end
+-- -- cache patterns (2.13):
+
+local patterns= setmetatableindex(function(t,k)
+ local v = P(k * someaction + 1)^0
+ t[k] = v
+ return v
+end)
+
+function css.stylevalue(root,name)
+ local list = getid(root).at.style -- hard coded style
+ if list then
+ lpegmatch(patterns[name],list)
+ end
+end
+
+local somevalue = (1 - whitespace - semicolon - eos)^1
+local someaction = skipspace * colon * (skipspace * Carg(1) * C(somevalue)/function(m,s)
+ ctx_xmlvalue(m,s,"") -- use one with two args
+end)^1
+
+local patterns= setmetatableindex(function(t,k)
+ local v = P(k * someaction + 1)^0
+ t[k] = v
+ return v
+end)
+
+function css.mappedstylevalue(root,map,name)
+ local list = getid(root).at.style -- hard coded style
+ if list then
+ lpegmatch(patterns[name],list,1,map)
+ end
+end
+
+-- -- faster interface (1.02):
+
+interfaces.implement {
+ name = "xmlstylevalue",
+ actions = css.stylevalue,
+ arguments = { "string", "string" },
+}
+
+interfaces.implement {
+ name = "xmlmappedstylevalue",
+ actions = css.mappedstylevalue,
+ arguments = { "string", "string", "string" },
+}
diff --git a/tex/context/base/mkiv/lxml-css.mkiv b/tex/context/base/mkiv/lxml-css.mkiv
index cb8735485..04000a6ca 100644
--- a/tex/context/base/mkiv/lxml-css.mkiv
+++ b/tex/context/base/mkiv/lxml-css.mkiv
@@ -13,6 +13,8 @@
\registerctxluafile{lxml-css}{}
+\unprotect
+
\def\ctxmodulecss#1{\ctxlua{moduledata.css.#1}}
% No stable interface yet.
@@ -23,7 +25,7 @@
% \else
% \edef\CellPadding{\cssgetsinglepadding{\xmlatt{#1}{cellpadding}}}
% \fi
-
+%
% \starttexdefinition cssgetsinglepadding #1
% \ctxlua {
% context((moduledata.css.padding(
@@ -36,5 +38,39 @@
% }sp
% \stoptexdefinition
-\endinput
+% \startxmlsetups html:settings
+% \xmlsetsetup{#1}{p}{html:p}
+% \stopxmlsetups
+%
+% \xmlmapvalue{ctx-before} {one} {\page BEFORE\par}
+% \xmlmapvalue{ctx-after} {two} {\par AFTER\page}
+% \xmlmapvalue{text-decoration}{underline}{U}
+% \xmlmapvalue{text-decoration}{overline} {O}
+%
+% \startxmlsetups html:p
+% \testfeatureonce{100000}{
+% \edef\foo{\xmlcssstylevalue{#1}{ctx-before}\xmlcssstylevalue{#1}{ctx-after}}
+% }
+% \page {\tttf style="\xmlatt{#1}{style}"} : \elapsedtime\ s \page
+% \xmlvalue{ctx-before}{\xmlcssstylevalue{#1}{ctx-before}}{}
+% \xmlflush{#1}
+% (\xmlcssstylevalue{#1}{text-decoration})
+% (\xmlcssmappedstylevalue{#1}{text-decoration}{text-decoration})
+% \xmlvalue{ctx-after} {\xmlcssstylevalue{#1}{ctx-after}}{}
+% \stopxmlsetups
+%
+% \startbuffer[temp]
+% <body>
+% <p style='ctx-before: one; text-decoration: underline overline; ctx-after: two;'>foo 1</p>
+% <p>foo 2</p>
+% </body>
+% \stopbuffer
+%
+% \xmlregistersetup{html:settings}
+% \xmlprocessbuffer{main}{temp}{}
+
+\let\xmlcssstylevalue \clf_xmlstylevalue
+\let\xmlcssmappedstylevalue\clf_xmlmappedstylevalue
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua
index 1413159ec..f1abab9e7 100644
--- a/tex/context/base/mkiv/lxml-tex.lua
+++ b/tex/context/base/mkiv/lxml-tex.lua
@@ -17,7 +17,7 @@ local lpegmatch = lpeg.match
local P, S, C, Cc, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs
local patterns = lpeg.patterns
local setmetatableindex = table.setmetatableindex
-local formatters = string.formatters
+local formatters, strip = string.formatters, string.strip
local tex, xml = tex, xml
local lowerchars, upperchars, lettered = characters.lower, characters.upper, characters.lettered
@@ -60,6 +60,7 @@ local xmlpushmatch = xml.pushmatch
local xmlpopmatch = xml.popmatch
local xmlstring = xml.string
local xmlserializetotext = xml.serializetotext
+local xmlrename = xml.rename
local variables = interfaces and interfaces.variables or { }
@@ -2579,3 +2580,20 @@ implement {
actions = lxml.applyselectors,
arguments = "string"
}
+
+-- bonus: see x-lmx-html.mkiv
+
+function texfinalizers.xml(collected,name,setup)
+ local root = collected[1]
+ if not root then
+ return
+ end
+ if not name or name == "" then
+ report_lxml("missing name in xml finalizer")
+ return
+ end
+ xmlrename(root,name)
+ name = "lmx:" .. name
+ buffers.assign(name,strip(xmltostring(root)))
+ context.xmlprocessbuffer(name,name,setup or (name..":setup"))
+end
diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv
index 4e00e200d..17d900d74 100644
--- a/tex/context/base/mkiv/math-ini.mkiv
+++ b/tex/context/base/mkiv/math-ini.mkiv
@@ -1487,8 +1487,8 @@
\attribute\mathitalicsattribute\c_math_italics_attribute
\to \everymathematics
-\setupmathematics
- [\s!italics=3] % 4 is probably better
+% \setupmathematics % done later
+% [\s!italics=3] % 4 is probably better
% looks nicer but can generate bogus csnames
%
diff --git a/tex/context/base/mkiv/meta-ini.lua b/tex/context/base/mkiv/meta-ini.lua
index 4ba0cec2d..6c4768671 100644
--- a/tex/context/base/mkiv/meta-ini.lua
+++ b/tex/context/base/mkiv/meta-ini.lua
@@ -96,7 +96,10 @@ do
-- formatters["\\times10^{%N}"](s) -- strips leading zeros too
local one = Cs((P("@")/"%%." * (R("09")^1) + P("@")/"%%" + 1)^0)
- local two = Cs((P("e")/"" * ((S("+-")^0 * R("09")^1) / function(s) return format("\\times10^{%s}",tonumber(s) or s) end) + 1)^1)
+ local two = Cs((P("e")/"" * ((S("+-")^0 * R("09")^1) / function(s)
+ -- return format("\\times10^{%s}",tonumber(s) or s)
+ return "\\times10^{" .. (tonumber(s) or s) .."}"
+ end) + 1)^1)
-- local two = Cs((P("e")/"" * ((S("+-")^0 * R("09")^1) / formatters["\\times10^{%N}"]) + 1)^1)
diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua
index fe154504f..3e9a08b48 100644
--- a/tex/context/base/mkiv/node-nut.lua
+++ b/tex/context/base/mkiv/node-nut.lua
@@ -175,11 +175,11 @@ if not direct.getdirection then
end
direct.setdirection = function(n,d,c)
- if d == 0 then if c == true then setdir("-TLT") elseif c == false then setdir("+TLT") else setdir("TLT") end
- elseif d == 1 then if c == true then setdir("-TRT") elseif c == false then setdir("+TRT") else setdir("TRT") end
- elseif d == 2 then if c == true then setdir("-LTL") elseif c == false then setdir("+LTL") else setdir("LTL") end
- elseif d == 3 then if c == true then setdir("-RTT") elseif c == false then setdir("+RTT") else setdir("RTT") end
- else if c == true then setdir("-TLT") elseif c == false then setdir("+TLT") else setdir("TLT") end end
+ if d == 0 then if c == true then setdir(n,"-TLT") elseif c == false then setdir(n,"+TLT") else setdir(n,"TLT") end
+ elseif d == 1 then if c == true then setdir(n,"-TRT") elseif c == false then setdir(n,"+TRT") else setdir(n,"TRT") end
+ elseif d == 2 then if c == true then setdir(n,"-LTL") elseif c == false then setdir(n,"+LTL") else setdir(n,"LTL") end
+ elseif d == 3 then if c == true then setdir(n,"-RTT") elseif c == false then setdir(n,"+RTT") else setdir(n,"RTT") end
+ else if c == true then setdir(n,"-TLT") elseif c == false then setdir(n,"+TLT") else setdir(n,"TLT") end end
end
end
diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua
index d8320e3b3..9d716c44a 100644
--- a/tex/context/base/mkiv/node-syn.lua
+++ b/tex/context/base/mkiv/node-syn.lua
@@ -204,6 +204,7 @@ luatex.synctex = synctex
local enabled = false
local paused = 0
local used = false
+local never = false
-- get rid of overhead
@@ -673,7 +674,7 @@ function synctex.registerdisabler(f)
end
function synctex.enable()
- if not enabled then
+ if not never and not enabled then
enabled = true
set_synctex_mode(3) -- we want details
if not used then
@@ -712,13 +713,13 @@ local filename = nil
function synctex.pause()
paused = paused + 1
- if paused == 1 and enabled then
+ if enabled and paused == 1 then
set_synctex_mode(0)
end
end
function synctex.resume()
- if paused == 1 and enabled then
+ if enabled and paused == 1 then
set_synctex_mode(3)
end
paused = paused - 1
@@ -735,37 +736,45 @@ statistics.register("synctex tracing",function()
end
end)
-interfaces.implement {
+local implement = interfaces.implement
+local variables = interfaces.variables
+
+function synctex.setup(t)
+ if t.state == variables.never then
+ synctex.disable() -- just in case
+ never = true
+ return
+ end
+ if t.method == variables.max then
+ collect = collect_max
+ else
+ collect = collect_min
+ end
+ if t.state == variables.start then
+ synctex.enable()
+ else
+ synctex.disable()
+ end
+end
+
+implement {
name = "synctexblockfilename",
arguments = "string",
actions = synctex.blockfilename,
}
-interfaces.implement {
+implement {
name = "synctexsetfilename",
arguments = "string",
actions = synctex.setfilename,
}
-interfaces.implement {
+implement {
name = "synctexresetfilename",
actions = synctex.resetfilename,
}
-function synctex.setup(t)
- if t.method == interfaces.variables.max then
- collect = collect_max
- else
- collect = collect_min
- end
- if t.state == interfaces.variables.start then
- synctex.enable()
- else
- synctex.disable()
- end
-end
-
-interfaces.implement {
+implement {
name = "setupsynctex",
actions = synctex.setup,
arguments = {
@@ -776,12 +785,12 @@ interfaces.implement {
},
}
-interfaces.implement {
+implement {
name = "synctexpause",
actions = synctex.pause,
}
-interfaces.implement {
+implement {
name = "synctexresume",
actions = synctex.resume,
}
diff --git a/tex/context/base/mkiv/page-ini.lua b/tex/context/base/mkiv/page-ini.lua
index 17723c421..6325e1d39 100644
--- a/tex/context/base/mkiv/page-ini.lua
+++ b/tex/context/base/mkiv/page-ini.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['page-ini'] = {
license = "see context related readme files"
}
-local tonumber, rawget, type, next = tonumber, rawget, type, next
+local tonumber, rawget, rawset, type, next = tonumber, rawget, rawset, type, next
local match = string.match
local sort, tohash, insert, remove = table.sort, table.tohash, table.insert, table.remove
local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array, utilities.parsers.settings_to_hash
@@ -14,7 +14,7 @@ local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array,
local texgetcount = tex.getcount
local context = context
-local ctx_testcase = commands.testcase
+local ctx_doifelse = commands.doifelse
local data = table.setmetatableindex("table")
local last = 0
@@ -69,13 +69,14 @@ function pages.mark(name,list)
end
end
-function pages.marked(name)
+local function marked(name)
local realpage = texgetcount("realpageno")
for i=last,realpage-1 do
- data[i] = nil
+ rawset(data,i,nil)
end
local pagedata = rawget(data,realpage)
- return pagedata and pagedata[name]
+ print(pagedata and pagedata[name] and true or false)
+ return pagedata and pagedata[name] and true or false
end
local function toranges(marked)
@@ -97,8 +98,6 @@ local function toranges(marked)
return list
end
-pages.toranges = toranges
-
local function allmarked(list)
if list then
local collected = pages.collected
@@ -139,6 +138,8 @@ local function allmarked(list)
end
end
+pages.marked = marked
+pages.toranges = toranges
pages.allmarked = allmarked
-- An alternative is to use an attribute and identify the state by parsing the node
@@ -170,7 +171,7 @@ interfaces.implement {
interfaces.implement {
name = "doifelsemarkedpage",
arguments = "string",
- actions = { marked, ctx_testcase }
+ actions = { marked, ctx_doifelse }
}
interfaces.implement {
diff --git a/tex/context/base/mkiv/page-inj.mkvi b/tex/context/base/mkiv/page-inj.mkvi
index e03569f23..cabd07bac 100644
--- a/tex/context/base/mkiv/page-inj.mkvi
+++ b/tex/context/base/mkiv/page-inj.mkvi
@@ -32,6 +32,11 @@
\let\page_boxes_flush_before\clf_flushpageinjectionsbefore
\let\page_boxes_flush_after \clf_flushpageinjectionsafter
+\def\page_injections_flush_indeed
+ {\scrn_canvas_synchronize_set{\pageinjectionparameter\c!width}{\pageinjectionparameter\c!height}%
+ \invokepagehandler\v!normal{\inheritedpageinjectionframed{\texsetup\p_page_injectionalternative_rederingsetup}}%
+ \scrn_canvas_synchronize_reset}
+
\def\page_injections_flush_saved#name#parameters%
{\begingroup
\edef\currentpageinjection{#name}%
@@ -39,7 +44,7 @@
\edef\currentpageinjectionalternative {\pageinjectionparameter \c!alternative }%
\edef\p_page_injectionalternative_rederingsetup{\pageinjectionalternativeparameter\c!renderingsetup}%
\page_injections_nextpage
- \invokepagehandler\v!normal{\inheritedpageinjectionframed{\texsetup\p_page_injectionalternative_rederingsetup}}%
+ \page_injections_flush_indeed
\endgroup}
\unexpanded\def\pageinjection
@@ -104,12 +109,23 @@
\page_injections_place
\endgroup}
+% \def\page_injections_place
+% {\edef\currentpageinjectionalternative {\pageinjectionparameter \c!alternative }%
+% \edef\p_page_injectionalternative_rederingsetup{\pageinjectionalternativeparameter\c!renderingsetup}%
+% \page_injections_nextpage
+% \ifx\currentpageinjectionalternative\v!none \else % increment counter but don’t generate output
+% \invokepagehandler\v!normal{\inheritedpageinjectionframed{\texsetup\p_page_injectionalternative_rederingsetup}}%
+% \fi}
+
\def\page_injections_place
{\edef\currentpageinjectionalternative {\pageinjectionparameter \c!alternative }%
\edef\p_page_injectionalternative_rederingsetup{\pageinjectionalternativeparameter\c!renderingsetup}%
\page_injections_nextpage
\ifx\currentpageinjectionalternative\v!none \else % increment counter but don’t generate output
- \invokepagehandler\v!normal{\inheritedpageinjectionframed{\texsetup\p_page_injectionalternative_rederingsetup}}%
+ \forgetparindent
+ \dontcomplain
+ \setconstant\shipoutfinalizemethod\zerocount
+ \page_injections_flush_indeed
\fi}
\def\page_injections_nextpage
diff --git a/tex/context/base/mkiv/page-pcl.mkiv b/tex/context/base/mkiv/page-pcl.mkiv
index 086cf69b0..53d9f781d 100644
--- a/tex/context/base/mkiv/page-pcl.mkiv
+++ b/tex/context/base/mkiv/page-pcl.mkiv
@@ -602,43 +602,25 @@
%D \unknown
\unexpanded\def\page_col_command_routine
- {\ifconditional\c_page_sides_short
- \page_sides_output_routine_yes_column
- \else
- \page_sides_output_routine_nop_column
- \fi}
+ {\page_sides_output_routine}
-\let\page_sides_output_routine_nop_column\page_sides_output_routine_nop
-
-\def\page_sides_output_routine_yes_column % this might become the main one too
- {\unvbox\normalpagebox % bah, and the discards?
- %\page_col_column
- \column % \page
- %
- % % do we really need the next code
- %
- % \setbox\b_page_sides_bottom\lastbox
- % \ifdim\wd\b_page_sides_bottom>\d_page_sides_hsize
- % \penalty-201 % hm, i really need to write this from scatch
- % \box\b_page_sides_bottom
- % \else\ifvoid\b_page_sides_bottom
- % \else
- % \page_sides_restore_left_indent
- % \ifdim\wd\b_page_sides_bottom<\d_page_sides_hsize
- % \parskip\zeropoint
- % %\noindent
- % \ifinner\else
- % \vadjust{\penalty\minusone}%
- % \fi
- % \global\advance\d_page_sides_hsize -\wd\b_page_sides_bottom
- % \global\divide\d_page_sides_hsize \plustwo
- % \hskip\d_page_sides_hsize % \kern
- % \fi
- % \box\b_page_sides_bottom
- % \page_sides_restore_output_penalty
- % \fi\fi
- % why was this \global\holdinginserts\zerocount
- \global\setfalse\c_page_sides_short}
+% % not:
+%
+% \unexpanded\def\page_col_command_routine
+% {\ifconditional\c_page_sides_short
+% \page_sides_output_routine_yes_column
+% \else
+% \page_sides_output_routine_nop_column
+% \fi}
+%
+% \let\page_sides_output_routine_nop_column\page_sides_output_routine
+%
+% \def\page_sides_output_routine_yes_column % this might become the main one too
+% {\unvbox\normalpagebox % bah, and the discards?
+% %\page_col_column
+% \column % \page
+% % why was this \global\holdinginserts\zerocount
+% \global\setfalse\c_page_sides_short}
\let\page_col_command_flush_all_floats\relax
diff --git a/tex/context/base/mkiv/page-set.mkiv b/tex/context/base/mkiv/page-set.mkiv
index fb6f607a1..3579e3b48 100644
--- a/tex/context/base/mkiv/page-set.mkiv
+++ b/tex/context/base/mkiv/page-set.mkiv
@@ -1198,12 +1198,12 @@
{\OTRSETcheckprefered
\enoughcolumncellsfalse
\donefalse
- \dostepwiserecurse{#1}{#2}{#3#4}
+ \dostepwiserecurse{#1}{#2}{#31}
{\ifdone
\exitloop
\else
#4=\recurselevel
- \dostepwiserecurse{#5}{#6}{#7#8}
+ \dostepwiserecurse{#5}{#6}{#71}
{\ifdone
\exitloop
\else
diff --git a/tex/context/base/mkiv/publ-imp-apa.mkvi b/tex/context/base/mkiv/publ-imp-apa.mkvi
index 38841b16b..cd78a8799 100644
--- a/tex/context/base/mkiv/publ-imp-apa.mkvi
+++ b/tex/context/base/mkiv/publ-imp-apa.mkvi
@@ -575,7 +575,7 @@
apa:Editors=Éditeurs,
apa:Volume=Volume,
apa:Volumes=Volumes,
- apa:nd={s.d.} % sans date
+ apa:nd={s.d.}, % sans date
apa:supplement=Supplément,
apa:MotionPicture={Film cinématographique},
apa:Writer=Scénariste,
diff --git a/tex/context/base/mkiv/scrn-fld.mkvi b/tex/context/base/mkiv/scrn-fld.mkvi
index 38c4e1461..dec334209 100644
--- a/tex/context/base/mkiv/scrn-fld.mkvi
+++ b/tex/context/base/mkiv/scrn-fld.mkvi
@@ -47,7 +47,7 @@
%D A definition can refer to this category:
%D
%D \starttyping
-%D \definefieldbody [email] [type=line,category=all-email,default=pragma@wxs.nl]
+%D \definefieldbody [email] [type=line,category=all-email,default=pragma@xs4all.nl]
%D \stoptyping
%D
%D A copy of a field is made as follows:
diff --git a/tex/context/base/mkiv/scrn-pag.mkvi b/tex/context/base/mkiv/scrn-pag.mkvi
index d96d8d3c1..7695443ad 100644
--- a/tex/context/base/mkiv/scrn-pag.mkvi
+++ b/tex/context/base/mkiv/scrn-pag.mkvi
@@ -203,11 +203,16 @@
paperheight \printpaperheight
\relax}
-\def\scrn_canvas_synchronize_simple_indeed
+\def\scrn_canvas_synchronize_set#1#2%
{\clf_setupcanvas
- paperwidth \printpaperwidth
- paperheight \printpaperheight
- \relax
+ paperwidth \dimexpr#1\relax
+ paperheight \dimexpr#2\relax
+ \relax}
+
+\let\scrn_canvas_synchronize_reset\scrn_canvas_synchronize_only
+
+\def\scrn_canvas_synchronize_simple_indeed
+ {\scrn_canvas_synchronize_only
%\global\let\scrn_canvas_synchronize_simple \relax
\global\let\scrn_canvas_synchronize_complex\relax}
diff --git a/tex/context/base/mkiv/spac-hor.mkiv b/tex/context/base/mkiv/spac-hor.mkiv
index 176b52e1f..ce747a202 100644
--- a/tex/context/base/mkiv/spac-hor.mkiv
+++ b/tex/context/base/mkiv/spac-hor.mkiv
@@ -680,6 +680,7 @@
\global \s_spac_narrower_middle \zeropoint
\global \s_spac_narrower_right \zeropoint\relax}
\installnarrowermethod \v!none {}
+\installnarrowermethod \v!reverse {} % never seen
\unexpanded\def\spac_narrower_start#1%
{\begingroup
@@ -693,19 +694,45 @@
\spac_narrower_start_apply{\narrowerparameter\v!default}%
\fi}
+\newskip\s_spac_narrower_left_last
+\newskip\s_spac_narrower_right_last
+\newconditional\s_spac_narrower_last_swap
+
\def\spac_narrower_start_apply#1%
{\narrowerparameter\c!before
\global\s_spac_narrower_left \zeropoint
\global\s_spac_narrower_right \zeropoint
\global\s_spac_narrower_middle\zeropoint
- \normalexpanded{\processcommalistwithparameters[#1]}\spac_narrower_initialize
- \advance\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax
- \advance\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax
+ \edef\askednarrower{#1}
+ \ifx\askednarrower\v!reverse
+ \ifconditional\s_spac_narrower_last_swap
+ \leftskip \s_spac_narrower_right_last
+ \rightskip\s_spac_narrower_left_last
+ \setfalse\s_spac_narrower_last_swap
+ \else
+ \leftskip \s_spac_narrower_left_last
+ \rightskip\s_spac_narrower_right_last
+ \settrue\s_spac_narrower_last_swap
+ \fi
+ \else
+ \normalexpanded{\processcommalistwithparameters[\askednarrower]}\spac_narrower_initialize
+ \advance\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax
+ \advance\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax
+ \fi
\seteffectivehsize}
\unexpanded\def\spac_narrower_stop
{\narrowerparameter\c!after
- \endgroup}
+ \normalexpanded{%
+ \endgroup
+ \s_spac_narrower_left_last \the\leftskip \relax
+ \s_spac_narrower_right_last\the\rightskip\relax
+ \ifconditional\s_spac_narrower_last_swap
+ \setfalse\s_spac_narrower_last_swap
+ \else
+ \settrue\s_spac_narrower_last_swap
+ \fi
+ }}
\unexpanded\def\startnarrower
{\dosingleempty\spac_narrower_start_basic}
diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv
index a1bc0559f..b71e28219 100644
--- a/tex/context/base/mkiv/spac-ver.mkiv
+++ b/tex/context/base/mkiv/spac-ver.mkiv
@@ -2568,6 +2568,22 @@
\newcount\c_spac_vspacing_ignore_parskip
+% \setupwhitespace[line]
+% \setuphead[subject][after={\blank[packed]},style=\bfb]
+% \subject{foo}
+% test \par
+% test \par
+% \blank[packed] % \ignoreparskip
+% test \par
+% test \par
+% \ignoreparskip
+% test \par
+% test \par
+% \setuphead[subject][after={\blank[nowhite]},style=\bfb]
+% \subject{foo}
+% test \par
+% test \par
+
\unexpanded\def\ignoreparskip{\c_spac_vspacing_ignore_parskip\plusone}
\protect \endinput
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 319680a90..4bb82edcf 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 767fa89ad..8deebb2ec 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-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi
index 4c10e49e9..69881037e 100644
--- a/tex/context/base/mkiv/strc-flt.mkvi
+++ b/tex/context/base/mkiv/strc-flt.mkvi
@@ -486,10 +486,15 @@
\let\m_strc_floats_saved_userdata\empty
\let\currentfloatcaption\currentfloat}
+\let\askedfloatmethod \empty
+\let\askedfloatoptions\empty
+
\def\strc_floats_reset_variables
{\global\emptyfloatcaptionfalse
\global\nofloatcaptionfalse
- \global\nofloatnumberfalse}
+ \global\nofloatnumberfalse
+ \global\let\askedfloatmethod \empty
+ \global\let\askedfloatoptions\empty}
% place
@@ -520,22 +525,14 @@
\setupfloat[\c!spacebefore=\v!none,\c!spaceafter=\v!none]%
\to \c_floats_every_table_float
-\appendtoks
- \showmessage\m!floatblocks{14}\v!here
-\to \everyinitializeexport
-
-\def\strc_floats_set_checked_location#location%
- {\edef\floatlocation{#location}%
- \ifexporting \ifx\floatlocation\v!here \else
- \showmessage\m!floatblocks{15}{\floatlocation,\v!here}%
- \let\floatlocation\v!here
- \fi \fi}
+\ifdefined\dotagregisterfloat \else \let\dotagregisterfloat\gobbletwoarguments \fi
\def\strc_floats_place_indeed[#location][#reference]#caption%
{\strc_floats_reset_variables
- \strc_floats_set_checked_location{#location}%
+ \xdef\askedfloatoptions{#location}%
+ \edef\floatlocation{#location}%
\ifx\floatlocation\empty
- \edef\floatlocation{\floatparameter\c!default}% beware of a clash between alignment locations
+ \edef\floatlocation{\floatparameter\c!default}% beware of a clash between alignment locations
\fi
\ifintable
\the\c_floats_every_table_float
@@ -585,7 +582,7 @@
\setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}%
\setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}%
\def\m_strc_floats_saved_userdata{#2}%
- \strc_floats_set_checked_location{\floatcaptionparameter\c!location}%
+ \edef\floatlocation{\floatcaptionparameter\c!location}%
\setfloatcaptionparameter\c!location{\savedfloatlocation}% not expanded
\ifx\floatlocation\empty
\edef\floatlocation{\floatparameter\c!default}%
@@ -724,6 +721,7 @@
\strc_floats_check_extra_actions
\strc_floats_analyze_variables_two
\strc_floats_place_packaged_boxes
+ \dotagregisterfloat\askedfloatoptions\askedfloatmethod
\dostoptagged % tricky .... needs checking
% we need to carry over the par because of side floats
\global\d_page_sides_downshift \zeropoint
@@ -1082,11 +1080,6 @@
\unexpanded\def\installfloatmovement#1#2{\setvalue{\??floatmovement#1}{#2}}
-% \def\strc_floats_move_down#setting%
-% {\csname\??floatmovement
-% \ifcsname\??floatmovement#setting\endcsname#setting\fi
-% \endcsname}
-
\def\strc_floats_move_down#setting%
{\begincsname\??floatmovement#setting\endcsname}
@@ -1145,7 +1138,6 @@
% already be set at this point
\processcommacommand[\floatlocation]\strc_floats_check_extra_actions_step
\ifx\extrafloatlocation\empty \else
- % maybe not when exporting
\edef\floatlocation{\extrafloatlocation,\floatlocation}%
\setfloatmethodvariables\floatlocation
\fi}}
@@ -1267,7 +1259,7 @@
\global\floatwidth \wd\floatbox
\global\floatheight \ht\floatbox % forget about the depth
\global\floattextwidth\dimexpr\hsize-\floatwidth-\rootfloatparameter\c!margin\relax
- \strc_floats_set_checked_location\floatlocationmethod% to be sure .. why
+ \edef\floatlocation{\floatlocationmethod}% to be sure .. why
\doifelseinset\v!tall\floatlocationmethod
{\floattextheight\dimexpr\pagegoal-\pagetotal-\bigskipamount\relax % ugly, this bigskip
\ifdim\floattextheight>\textheight
@@ -2261,6 +2253,11 @@
\ifx\forcedfloatmethod\empty \else
\let\floatmethod\forcedfloatmethod
\fi
+\let\askedfloatmethod\floatmethod
+\ifexporting \ifx\askedfloatmethod\v!here \else
+ \showmessage\m!floatblocks{15}{\askedfloatmethod,\v!here}%
+ \let\floatlocation\v!here
+\fi \fi
% [] will go
\edef\floatlocationmethod{\floatmethod,\floatlocation}%
\csname\??floatmethods\currentoutputroutine:\floatmethod\endcsname
diff --git a/tex/context/base/mkiv/typo-duc.lua b/tex/context/base/mkiv/typo-duc.lua
index 3449b6904..520740190 100644
--- a/tex/context/base/mkiv/typo-duc.lua
+++ b/tex/context/base/mkiv/typo-duc.lua
@@ -570,7 +570,6 @@ local function resolve_weak(list,size,start,limit,orderbefore,orderafter)
-- W4: make separators number
-- if list.es or list.cs then
-- skip
--- if false then
if false then
for i=start+1,limit-1 do
local entry = list[i]
@@ -1087,9 +1086,7 @@ local function process(head,direction,only_one)
local list, size = build_list(head)
local baselevel, pardir, dirfound = get_baselevel(head,list,size,direction) -- we always have an inline dir node in context
if trace_details then
- if not dirfound then
- report_directions("no initial direction found, gambling")
- end
+ report_directions("analyze: direction %a, baselevel %a",dirfound and pardir or "unknown",baselevel or 1)
report_directions("before : %s",show_list(list,size,"original"))
end
resolve_explicit(list,size,baselevel)
diff --git a/tex/context/base/mkiv/util-sha.lua b/tex/context/base/mkiv/util-sha.lua
new file mode 100644
index 000000000..3e786a834
--- /dev/null
+++ b/tex/context/base/mkiv/util-sha.lua
@@ -0,0 +1,326 @@
+if not modules then modules = { } end modules ['util-sha'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ comment2 = "derived from Wikipedia and Lua support websites",
+ comment3 = "due to bit operators this code only works in lua(tex) 5.3",
+}
+
+-- This doesn't work in luajittex ... maybe some day it will have bit operators too.
+-- I'm not really in the mood for making this module aware (by compiling the
+-- function depending on the engine that I use but I probably won't use luajittex in
+-- cases where I need this.)
+--
+-- Hm, it actually makes a case for the macro subsystem but we then also need to
+-- make an unpack/pack replacement ... too boring.
+--
+-- This code is derived from:
+--
+-- http://lua-users.org/wiki/SecureHashAlgorithmBw
+--
+-- which in turn was a 5.3 variant of a 5.2 implementation by Roberto but it also
+-- looks like a more or less direct translation of:
+--
+-- https://en.wikipedia.org/wiki/SHA-2
+--
+-- I optimized the code bit and added 512 support. For an explanation see the
+-- mentioned websites. We don't do chunks here as we only need it for hashing
+-- relatively small blobs (and even an image is not that large).
+--
+-- On short strings 256 seems faster than 512 while on a megabyte blob 512 wins
+-- from 256 (64 bit internals).
+
+local packstring, unpackstring = string.pack, string.unpack
+local unpack, setmetatable = unpack, setmetatable
+
+local constants256 = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+}
+
+local constants512 = {
+ 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
+ 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
+ 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
+ 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+ 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
+ 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+ 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
+ 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
+ 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
+ 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
+ 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
+ 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+ 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
+ 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
+ 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
+ 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
+}
+
+-- Not really needed, but more in tune with md5. In fact, as we use the mtxlib
+-- helpers I might as well assume more.
+
+local tohex, toHEX
+
+if lpeg then local lpegpatterns = lpeg.patterns if lpegpatterns then
+
+ local lpegmatch = lpeg.match
+ local bytestohex = lpegpatterns.bytestohex
+ local bytestoHEX = lpegpatterns.bytestoHEX
+
+ tohex = function(s) return lpegmatch(bytestohex,s) end
+ toHEX = function(s) return lpegmatch(bytestoHEX,s) end
+
+end end
+
+if not tohex then
+
+ local format, byte, gsub = string.format, string.byte, string.gsub
+
+ tohex = function(s) return (gsub(s,".",function(c) return format("%02X",byte(c)) end)) end
+ toHEX = function(s) return (gsub(s,".",function(c) return format("%02X",byte(c)) end)) end
+
+end
+
+local prepare = { }
+
+if utilities and utilities.strings then
+
+ local r = utilities.strings.newrepeater("\0")
+
+ prepare[256] = function(str,len)
+ return str .. "\128" .. r[-(1 + 8 + len) % 64] .. packstring(">I8", 8 * len)
+ end
+ prepare[512] = function(str,len)
+ return str .. "\128" .. r[-(1 + 16 + len) % 128] .. packstring(">I16", 8 * len)
+ end
+
+else
+
+ local rep = string.rep
+
+ prepare[256] = function(str,len)
+ return str .. "\128" .. rep("\0",-(1 + 8 + len) % 64) .. packstring(">I8", 8 * len)
+ end
+ prepare[512] = function(str,len)
+ return str .. "\128" .. rep("\0",-(1 + 16 + len) % 128) .. packstring(">I16", 8 * len)
+ end
+
+end
+
+prepare[224] = prepare[256]
+prepare[384] = prepare[512]
+
+local initialize = {
+ [224] = function(hash)
+ hash[1] = 0xc1059ed8 hash[2] = 0x367cd507
+ hash[3] = 0x3070dd17 hash[4] = 0xf70e5939
+ hash[5] = 0xffc00b31 hash[6] = 0x68581511
+ hash[7] = 0x64f98fa7 hash[8] = 0xbefa4fa4
+ return hash
+ end,
+ [256] = function(hash)
+ hash[1] = 0x6a09e667 hash[2] = 0xbb67ae85
+ hash[3] = 0x3c6ef372 hash[4] = 0xa54ff53a
+ hash[5] = 0x510e527f hash[6] = 0x9b05688c
+ hash[7] = 0x1f83d9ab hash[8] = 0x5be0cd19
+ return hash
+ end,
+ [384] = function(hash)
+ hash[1] = 0xcbbb9d5dc1059ed8 hash[2] = 0x629a292a367cd507
+ hash[3] = 0x9159015a3070dd17 hash[4] = 0x152fecd8f70e5939
+ hash[5] = 0x67332667ffc00b31 hash[6] = 0x8eb44a8768581511
+ hash[7] = 0xdb0c2e0d64f98fa7 hash[8] = 0x47b5481dbefa4fa4
+ return hash
+ end,
+ [512] = function(hash)
+ hash[1] = 0x6a09e667f3bcc908 hash[2] = 0xbb67ae8584caa73b
+ hash[3] = 0x3c6ef372fe94f82b hash[4] = 0xa54ff53a5f1d36f1
+ hash[5] = 0x510e527fade682d1 hash[6] = 0x9b05688c2b3e6c1f
+ hash[7] = 0x1f83d9abfb41bd6b hash[8] = 0x5be0cd19137e2179
+ return hash
+ end,
+}
+
+local digest = { }
+local list = { } -- some 5% faster
+
+digest[256] = function(str,i,hash)
+
+ for i=1,#str,64 do
+
+ -- local w = { unpackstring(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4",str,i) }
+
+ list[ 1], list[ 2], list[ 3], list[ 4], list[ 5], list[ 6], list[ 7], list[ 8],
+ list[ 9], list[10], list[11], list[12], list[13], list[14], list[15], list[16] =
+ unpackstring(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4",str,i)
+
+ for j=17,64 do
+ local v0 = list[j - 15]
+ local s0 = ((v0 >> 7) | (v0 << 25)) -- rrotate(v, 7)
+ ~ ((v0 >> 18) | (v0 << 14)) -- rrotate(v, 18)
+ ~ (v0 >> 3)
+ local v1 = list[j - 2]
+ local s1 = ((v1 >> 17) | (v1 << 15)) -- rrotate(v, 17)
+ ~ ((v1 >> 19) | (v1 << 13)) -- rrotate(v, 19)
+ ~ (v1 >> 10)
+ list[j] = (list[j - 16] + s0 + list[j - 7] + s1)
+ & 0xffffffff
+ end
+
+ local a, b, c, d, e, f, g, h = -- unpack(hash)
+ hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8]
+
+ for i=1,64 do
+ local s0 = ((a >> 2) | (a << 30)) -- rrotate(a, 2)
+ ~ ((a >> 13) | (a << 19)) -- rrotate(a, 13)
+ ~ ((a >> 22) | (a << 10)) -- rrotate(a, 22)
+ local maj = (a & b) ~ (a & c) ~ (b & c)
+ local t2 = s0 + maj
+ local s1 = ((e >> 6) | (e << 26)) -- rrotate(e, 6)
+ ~ ((e >> 11) | (e << 21)) -- rrotate(e, 11)
+ ~ ((e >> 25) | (e << 7)) -- rrotate(e, 25)
+ local ch = (e & f)
+ ~ (~e & g)
+ local t1 = h + s1 + ch + constants256[i] + list[i]
+ h = g
+ g = f
+ f = e
+ e = (d + t1) & 0xffffffff
+ d = c
+ c = b
+ b = a
+ a = (t1 + t2) & 0xffffffff
+ end
+
+ hash[1] = (hash[1] + a) & 0xffffffff
+ hash[2] = (hash[2] + b) & 0xffffffff
+ hash[3] = (hash[3] + c) & 0xffffffff
+ hash[4] = (hash[4] + d) & 0xffffffff
+ hash[5] = (hash[5] + e) & 0xffffffff
+ hash[6] = (hash[6] + f) & 0xffffffff
+ hash[7] = (hash[7] + g) & 0xffffffff
+ hash[8] = (hash[8] + h) & 0xffffffff
+
+ end
+end
+
+digest[512] = function(str,i,hash)
+
+ for i=1,#str,128 do
+
+ -- local w = { unpackstring(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4",str,i) }
+
+ list[ 1], list[ 2], list[ 3], list[ 4], list[ 5], list[ 6], list[ 7], list[ 8],
+ list[ 9], list[10], list[11], list[12], list[13], list[14], list[15], list[16] =
+ unpackstring(">I8I8I8I8I8I8I8I8I8I8I8I8I8I8I8I8",str,i)
+
+ for j=17,80 do
+ local v0 = list[j - 15]
+ local s0 = ((v0 >> 1) | (v0 << 63)) -- rrotate(v, 1)
+ ~ ((v0 >> 8) | (v0 << 56)) -- rrotate(v, 8)
+ ~ (v0 >> 7)
+ local v1 = list[j - 2]
+ local s1 = ((v1 >> 19) | (v1 << 45)) -- rrotate(v, 19)
+ ~ ((v1 >> 61) | (v1 << 3)) -- rrotate(v, 61)
+ ~ (v1 >> 6)
+ list[j] = (list[j - 16] + s0 + list[j - 7] + s1)
+ -- & 0xffffffffffffffff
+ end
+
+ local a, b, c, d, e, f, g, h = -- unpack(hash)
+ hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8]
+
+ for i=1,80 do
+ local s0 = ((a >> 28) | (a << 36)) -- rrotate(a, 28)
+ ~ ((a >> 34) | (a << 30)) -- rrotate(a, 34)
+ ~ ((a >> 39) | (a << 25)) -- rrotate(a, 39)
+ local maj = (a & b) ~ (a & c) ~ (b & c)
+ local t2 = s0 + maj
+ local s1 = ((e >> 14) | (e << 50)) -- rrotate(e, 14)
+ ~ ((e >> 18) | (e << 46)) -- rrotate(e, 18)
+ ~ ((e >> 41) | (e << 23)) -- rrotate(e, 41)
+ local ch = (e & f)
+ ~ (~e & g)
+ local t1 = h + s1 + ch + constants512[i] + list[i]
+ h = g
+ g = f
+ f = e
+ e = (d + t1) -- & 0xffffffffffffffff
+ d = c
+ c = b
+ b = a
+ a = (t1 + t2) -- & 0xffffffffffffffff
+ end
+
+ hash[1] = (hash[1] + a) -- & 0xffffffffffffffff
+ hash[2] = (hash[2] + b) -- & 0xffffffffffffffff
+ hash[3] = (hash[3] + c) -- & 0xffffffffffffffff
+ hash[4] = (hash[4] + d) -- & 0xffffffffffffffff
+ hash[5] = (hash[5] + e) -- & 0xffffffffffffffff
+ hash[6] = (hash[6] + f) -- & 0xffffffffffffffff
+ hash[7] = (hash[7] + g) -- & 0xffffffffffffffff
+ hash[8] = (hash[8] + h) -- & 0xffffffffffffffff
+
+ end
+end
+
+digest[224] = digest[256]
+digest[384] = digest[512]
+
+local finalize = {
+ [224] = function(hash,tohex) return tohex(packstring(">I4I4I4I4I4I4I4", unpack(hash))) end, -- # 56
+ [256] = function(hash,tohex) return tohex(packstring(">I4I4I4I4I4I4I4I4",unpack(hash))) end, -- # 64
+ [384] = function(hash,tohex) return tohex(packstring(">I8I8I8I8I8I8", unpack(hash))) end, -- # 96
+ [512] = function(hash,tohex) return tohex(packstring(">I8I8I8I8I8I8I8I8",unpack(hash))) end, -- # 128
+}
+
+local hash = { }
+
+local function hashed(str,method,tohex)
+ local s = prepare[method](str,#str)
+ local h = initialize[method](hash)
+ digest[method](s,i,h)
+ return finalize[method](h,tohex)
+end
+
+local sha2 = {
+ hash224 = function(str) return hashed(str,224,tohex) end,
+ hash256 = function(str) return hashed(str,256,tohex) end,
+ hash384 = function(str) return hashed(str,384,tohex) end,
+ hash512 = function(str) return hashed(str,512,tohex) end,
+ HASH224 = function(str) return hashed(str,224,toHEX) end,
+ HASH256 = function(str) return hashed(str,256,toHEX) end,
+ HASH384 = function(str) return hashed(str,384,toHEX) end,
+ HASH512 = function(str) return hashed(str,512,toHEX) end,
+}
+
+-- local setmetatableindex = table.setmetatableindex
+--
+-- if setmetatableindex then
+-- sha2.hashed = setmetatableindex(function(t,k)
+-- local v = digest[k] and function(str) return hashed(str,k,tohex) end or false
+-- t[k] = v
+-- return v
+-- end)
+-- sha2.HASHED = setmetatableindex(function(t,k)
+-- local v = digest[k] and function(str) return hashed(str,k,toHEX) end or false
+-- t[k] = v
+-- return v
+-- end)
+-- end
+
+if utilities then
+ utilities.sha2 = sha2
+end
+
+return sha2
+
diff --git a/tex/context/base/mkiv/util-sql-imp-library.lua b/tex/context/base/mkiv/util-sql-imp-library.lua
index e16853612..a2b692e45 100644
--- a/tex/context/base/mkiv/util-sql-imp-library.lua
+++ b/tex/context/base/mkiv/util-sql-imp-library.lua
@@ -12,7 +12,7 @@ if not modules then modules = { } end modules ['util-sql-imp-library'] = {
-- we couldn't figure it out (some issue with adapting the table that is passes as first
-- argument in the fetch routine. Apart from this it looks like the mysql binding has some
-- efficiency issues (like creating a keys and types table for each row) but that could be
--- optimized. Anyhow, fecthing results can be done as follows:
+-- optimized. Anyhow, fetching results can be done as follows:
-- local function collect_1(r)
-- local t = { }
diff --git a/tex/context/base/mkiv/util-sql-loggers.lua b/tex/context/base/mkiv/util-sql-loggers.lua
index 7cf4f6175..b69e397d2 100644
--- a/tex/context/base/mkiv/util-sql-loggers.lua
+++ b/tex/context/base/mkiv/util-sql-loggers.lua
@@ -61,8 +61,7 @@ CREATE TABLE IF NOT EXISTS %basename% (
`data` longtext,
PRIMARY KEY (`id`),
UNIQUE KEY `id_unique_key` (`id`)
-)
-DEFAULT CHARSET = utf8 ;
+) DEFAULT CHARSET = utf8 ;
]]
local sqlite_template = [[
@@ -80,7 +79,7 @@ function loggers.createdb(presets,datatable)
local db = checkeddb(presets,datatable)
db.execute {
- template = (db.usedmethod == "sqlite" or db.usedmethod == "sqlffi") and sqlite_template or template,
+ template = db.usedmethod == "sqlite" and sqlite_template or template,
variables = {
basename = db.basename,
},
diff --git a/tex/context/base/mkiv/util-sql-logins.lua b/tex/context/base/mkiv/util-sql-logins.lua
index 9717a8175..dcb48fb35 100644
--- a/tex/context/base/mkiv/util-sql-logins.lua
+++ b/tex/context/base/mkiv/util-sql-logins.lua
@@ -34,22 +34,27 @@ end
logins.usedb = checkeddb
local template = [[
-CREATE TABLE
- `logins`
- (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` varchar(50) COLLATE utf8_bin NOT NULL,
- `time` int(11) DEFAULT '0',
- `n` int(11) DEFAULT '0',
- `state` int(11) DEFAULT '0',
- PRIMARY KEY (`id`),
- UNIQUE KEY `id_UNIQUE` (`id`),
- UNIQUE KEY `name_UNIQUE` (`name`)
- )
- ENGINE=InnoDB
- DEFAULT CHARSET=utf8
- COLLATE=utf8_bin
- COMMENT='state: 0=unset 1=known 2=unknown'
+ CREATE TABLE IF NOT EXISTS %basename% (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(50) NOT NULL,
+ `time` int(11) DEFAULT '0',
+ `n` int(11) DEFAULT '0',
+ `state` int(11) DEFAULT '0',
+
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `id_unique_index` (`id`),
+ UNIQUE KEY `name_unique_key` (`name`)
+ ) DEFAULT CHARSET = utf8 ;
+]]
+
+local sqlite_template = [[
+ CREATE TABLE IF NOT EXISTS %basename% (
+ `id` INTEGER NOT NULL AUTO_INCREMENT,
+ `name` TEXT NOT NULL,
+ `time` INTEGER DEFAULT '0',
+ `n` INTEGER DEFAULT '0',
+ `state` INTEGER DEFAULT '0'
+ ) ;
]]
function logins.createdb(presets,datatable)
@@ -57,7 +62,7 @@ function logins.createdb(presets,datatable)
local db = checkeddb(presets,datatable)
local data, keys = db.execute {
- template = template,
+ template = db.usedmethod == "sqlite" and sqlite_template or template,
variables = {
basename = db.basename,
},
diff --git a/tex/context/base/mkiv/util-sql-sessions.lua b/tex/context/base/mkiv/util-sql-sessions.lua
index 76bb91962..17cf66142 100644
--- a/tex/context/base/mkiv/util-sql-sessions.lua
+++ b/tex/context/base/mkiv/util-sql-sessions.lua
@@ -48,8 +48,16 @@ local template =[[
`created` int(11) NOT NULL,
`accessed` int(11) NOT NULL,
UNIQUE KEY `token_unique_key` (`token`)
- )
- DEFAULT CHARSET = utf8 ;
+ ) DEFAULT CHARSET = utf8 ;
+]]
+
+local sqlite_template =[[
+ CREATE TABLE IF NOT EXISTS %basename% (
+ `token` TEXT NOT NULL,
+ `data` TEXT NOT NULL,
+ `created` INTEGER DEFAULT '0',
+ `accessed` INTEGER DEFAULT '0'
+ ) ;
]]
function sessions.createdb(presets,datatable)
@@ -57,7 +65,7 @@ function sessions.createdb(presets,datatable)
local db = checkeddb(presets,datatable)
db.execute {
- template = template,
+ template = db.usedmethod == "sqlite" and sqlite_template or template,
variables = {
basename = db.basename,
},
diff --git a/tex/context/base/mkiv/util-sql-tickets.lua b/tex/context/base/mkiv/util-sql-tickets.lua
index 68e54a015..3258fb186 100644
--- a/tex/context/base/mkiv/util-sql-tickets.lua
+++ b/tex/context/base/mkiv/util-sql-tickets.lua
@@ -67,7 +67,7 @@ end
tickets.usedb = checkeddb
-local template =[[
+local template = [[
CREATE TABLE IF NOT EXISTS %basename% (
`id` int(11) NOT NULL AUTO_INCREMENT,
`token` varchar(50) NOT NULL,
@@ -83,8 +83,22 @@ local template =[[
PRIMARY KEY (`id`),
UNIQUE INDEX `id_unique_index` (`id` ASC),
KEY `token_unique_key` (`token`)
- )
- DEFAULT CHARSET = utf8 ;
+ ) DEFAULT CHARSET = utf8 ;
+]]
+
+local sqlite_template = [[
+ CREATE TABLE IF NOT EXISTS %basename% (
+ `id` TEXT NOT NULL AUTO_INCREMENT,
+ `token` TEXT NOT NULL,
+ `subtoken` INTEGER DEFAULT '0',
+ `created` INTEGER DEFAULT '0',
+ `accessed` INTEGER DEFAULT '0',
+ `category` INTEGER DEFAULT '0',
+ `status` INTEGER DEFAULT '0',
+ `usertoken` TEXT NOT NULL,
+ `data` TEXT NOT NULL,
+ `comment` TEXT NOT NULL
+ ) ;
]]
function tickets.createdb(presets,datatable)
@@ -92,7 +106,7 @@ function tickets.createdb(presets,datatable)
local db = checkeddb(presets,datatable)
local data, keys = db.execute {
- template = template,
+ template = db.usedmethod == "sqlite" and sqlite_template or template,
variables = {
basename = db.basename,
},
diff --git a/tex/context/base/mkiv/util-sql-users.lua b/tex/context/base/mkiv/util-sql-users.lua
index a1f433946..7204fb310 100644
--- a/tex/context/base/mkiv/util-sql-users.lua
+++ b/tex/context/base/mkiv/util-sql-users.lua
@@ -10,47 +10,77 @@ if not modules then modules = { } end modules ['util-sql-users'] = {
-- because it's easier to dirtribute this way. Eventually it will be documented
-- and the related scripts will show up as well.
--- local sql = sql or (utilities and utilities.sql) or require("util-sql")
--- local md5 = md5 or require("md5")
-
local sql = utilities.sql
-local format, upper, find, gsub, topattern = string.format, string.upper, string.find, string.gsub, string.topattern
-local sumhexa = md5.sumhexa
+local find, topattern = string.find, string.topattern
+local sumHEXA = md5.sumHEXA
local toboolean = string.toboolean
+local lpegmatch = lpeg.match
-local sql = utilities.sql
+local sql = require("util-sql") -- utilities.sql
local users = { }
sql.users = users
local trace_sql = false trackers.register("sql.users.trace", function(v) trace_sql = v end)
local report = logs.reporter("sql","users")
-local function encryptpassword(str)
+local split = lpeg.splitat(":")
+local valid = nil
+local hash = function(s) return "MD5:" .. sumHEXA(s) end
+
+if LUAVERSION >= 5.3 then
+
+ local sha2 = require("util-sha")
+
+ local HASH224 = sha2.HASH224
+ local HASH256 = sha2.HASH256
+ local HASH384 = sha2.HASH384
+ local HASH512 = sha2.HASH512
+
+ valid = {
+ MD5 = hash,
+ SHA224 = function(s) return "SHA224:" .. HASH224(s) end,
+ SHA256 = function(s) return "SHA256:" .. HASH256(s) end,
+ SHA384 = function(s) return "SHA384:" .. HASH384(s) end,
+ SHA512 = function(s) return "SHA512:" .. HASH512(s) end,
+ }
+
+else
+
+ valid = {
+ MD5 = hash,
+ SHA224 = hash,
+ SHA256 = hash,
+ SHA384 = hash,
+ SHA512 = hash,
+ }
+
+end
+
+local function encryptpassword(str,how)
if not str or str == "" then
return ""
- elseif find(str,"^MD5:") then
+ end
+ local prefix, rest = lpegmatch(split,str)
+ if prefix and rest and valid[prefix] then
return str
- else
- return upper(format("MD5:%s",sumhexa(str)))
end
+ return (how and valid[how] or valid.MD5)(str)
end
local function cleanuppassword(str)
- return (gsub(str,"^MD5:",""))
+ local prefix, rest = lpegmatch(split,str)
+ if prefix and rest and valid[prefix] then
+ return rest
+ end
+ return str
end
local function samepasswords(one,two)
if not one or not two then
return false
end
- if not find(one,"^MD5:") then
- one = encryptpassword(one)
- end
- if not find(two,"^MD5:") then
- two = encryptpassword(two)
- end
- return one == two
+ return encryptpassword(one) == encryptpassword(two)
end
local function validaddress(address,addresses)
@@ -64,7 +94,6 @@ local function validaddress(address,addresses)
end
end
-
users.encryptpassword = encryptpassword
users.cleanuppassword = cleanuppassword
users.samepasswords = samepasswords
@@ -103,13 +132,23 @@ users.groupnumbers = groupnumbers
-- password 'test':
--
-- INSERT insert into users (`name`,`password`,`group`,`enabled`) values ('...','MD5:098F6BCD4621D373CADE4E832627B4F6',1,1) ;
+--
+-- MD5:098F6BCD4621D373CADE4E832627B4F6
+-- SHA224:90A3ED9E32B2AAF4C61C410EB925426119E1A9DC53D4286ADE99A809
+-- SHA256:9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08
+-- SHA384:768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9
+-- SHA512:EE26B0DD4AF7E749AA1A8EE3C10AE9923F618980772E473F8819A5D4940E0DB27AC185F8A0E1D5F84F88BC887FD67B143732C304CC5FA9AD8E6F57F50028A8FF
-local template =[[
+-- old values (a name can have utf and a password a long hash):
+--
+-- name 80, fullname 80, password 50
+
+local template = [[
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `name` varchar(80) NOT NULL,
- `fullname` varchar(80) NOT NULL,
- `password` varchar(50) DEFAULT NULL,
+ `name` varchar(100) NOT NULL,
+ `fullname` varchar(100) NOT NULL,
+ `password` varchar(200) DEFAULT NULL,
`group` int(11) NOT NULL,
`enabled` int(11) DEFAULT '1',
`email` varchar(80) DEFAULT NULL,
@@ -121,6 +160,21 @@ local template =[[
) DEFAULT CHARSET = utf8 ;
]]
+local sqlite_template = [[
+ CREATE TABLE `users` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT,
+ `name` TEXT NOT NULL,
+ `fullname` TEXT NOT NULL,
+ `password` TEXT DEFAULT NULL,
+ `group` INTEGER NOT NULL,
+ `enabled` INTEGER DEFAULT '1',
+ `email` TEXT DEFAULT NULL,
+ `address` TEXT DEFAULT NULL,
+ `theme` TEXT DEFAULT NULL,
+ `data` TEXT DEFAULT NULL
+ ) ;
+]]
+
local converter, fields = sql.makeconverter {
{ name = "id", type = "number" },
{ name = "name", type = "string" },
@@ -139,7 +193,7 @@ function users.createdb(presets,datatable)
local db = checkeddb(presets,datatable)
db.execute {
- template = template,
+ template = db.usedmethod == "sqlite" and sqlite_template or template,
variables = {
basename = db.basename,
},
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index 52ecf71ad..9da0c6a2f 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -646,7 +646,9 @@ end
local format_q = function()
n = n + 1
- return format("(a%s and format('%%q',a%s) or '')",n,n) -- goodie: nil check (maybe separate lpeg, not faster)
+ -- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
+ -- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
end
local format_Q = function() -- can be optimized
@@ -1000,7 +1002,7 @@ local builder = Cs { "start",
["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal)
--
["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring)
- ["Q"] = (prefix_any * P("Q")) / format_S, -- %Q => %q (tostring)
+ ["Q"] = (prefix_any * P("Q")) / format_Q, -- %Q => %q (tostring)
["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading zeros)
["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m
["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)