diff options
author | Hans Hagen <pragma@wxs.nl> | 2018-03-21 09:47:34 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2018-03-21 09:47:34 +0100 |
commit | f47b4939787074397c9ea37c1d892a1f7ccc7290 (patch) | |
tree | 7768be58efe0faab8e2dccb999686c6a674bf0d7 /tex/context/base/mkiv | |
parent | f923c957a3b322ae3ee8e7a0b20df1580869bee7 (diff) | |
download | context-f47b4939787074397c9ea37c1d892a1f7ccc7290.tar.gz |
2018-03-21 09:24:00
Diffstat (limited to 'tex/context/base/mkiv')
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 Binary files differindex 319680a90..4bb82edcf 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 767fa89ad..8deebb2ec 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf 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) |