diff options
Diffstat (limited to 'tex/context/base/mkiv')
51 files changed, 1212 insertions, 686 deletions
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua index 629e4f73f..e87409dbe 100644 --- a/tex/context/base/mkiv/anch-pos.lua +++ b/tex/context/base/mkiv/anch-pos.lua @@ -130,8 +130,9 @@ local splitter = lpeg.splitat(":",true) local function initializer() tobesaved = jobpositions.tobesaved collected = jobpositions.collected - local pagedata = { } - local freedata = setmetatableindex("table") + local pagedata = { } + local columndata = setmetatableindex("table") + local freedata = setmetatableindex("table") for tag, data in next, collected do local prefix, rest = lpegmatch(splitter,tag) if prefix == "p" then @@ -143,6 +144,8 @@ local function initializer() nofspecial = nofspecial + 1 local t = freedata[data.p or 0] t[#t+1] = data + elseif prefix == "columnarea" then + columndata[data.p or 0][data.c or 0] = data end setmetatable(data,default) end @@ -171,9 +174,10 @@ local function initializer() end end end - jobpositions.page = pagedata - jobpositions.free = freedata - jobpositions.used = next(collected) + jobpositions.page = pagedata + jobpositions.column = columndata + jobpositions.free = freedata + jobpositions.used = next(collected) end -- -- we can gain a little when we group positions but then we still have to @@ -342,6 +346,8 @@ function jobpositions.getrpos() return getrpos() end function jobpositions.gethpos() return gethpos() end function jobpositions.getvpos() return getvpos() end +-------- jobpositions.getcolumn() return column end + jobpositions.registerhandlers() local function setall(name,p,x,y,w,h,d,extra) @@ -554,7 +560,7 @@ jobpositions.e_region = e_region local lastregion -local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind +local function setregionbox(n,tag,k,lo,ro,to,bo,column) -- kind if not tag or tag == "" then nofregions = nofregions + 1 tag = f_region(nofregions) @@ -573,6 +579,7 @@ local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind ro = ro ~= 0 and ro or nil, to = to ~= 0 and to or nil, bo = bo ~= 0 and bo or nil, + c = column or nil, } lastregion = tag return tag, box @@ -1038,8 +1045,24 @@ local function onsamepage(list,page) return page end +local function columnofpos(realpage,xposition) + local p = job.positions.column[realpage] + if p then + for i=1,#p do + local c = p[i] + local x = c.x or 0 + local w = c.w or 0 + if xposition >= x and xposition <= (x + w) then + return i + end + end + end + return 1 +end + jobpositions.overlapping = overlapping jobpositions.onsamepage = onsamepage +jobpositions.columnofpos = columnofpos -- interface @@ -1395,6 +1418,10 @@ scanners.doifelsepositionsonthispage = function() -- list doifelse(onsamepage(scanstring(),tostring(texgetcount("realpageno")))) end +-- scanners.columnofpos = function() +-- context(columnofpos(scaninteger(),scandimen()) +-- end + scanners.doifelsepositionsused = function() doifelse(next(collected)) end @@ -1411,6 +1438,11 @@ scanners.markregionboxtagged = function() -- box tag markregionbox(scaninteger(),scanstring()) end +scanners.markregionboxtaggedn = function() -- box tag n + markregionbox(scaninteger(),scanstring(),nil, + nil,nil,nil,nil,nil,scaninteger()) +end + scanners.setregionboxtagged = function() -- box tag setregionbox(scaninteger(),scanstring()) end diff --git a/tex/context/base/mkiv/anch-pos.mkiv b/tex/context/base/mkiv/anch-pos.mkiv index 68cb2f723..2762a53c6 100644 --- a/tex/context/base/mkiv/anch-pos.mkiv +++ b/tex/context/base/mkiv/anch-pos.mkiv @@ -279,9 +279,9 @@ % beware we need to pass \somethingexpanded or { } -\unexpanded\def\anch_mark_column_box#1% +\unexpanded\def\anch_mark_column_box#1#2% box n {\global\advance\c_anch_column\plusone - \clf_markregionboxtagged#1{columnarea:\the\c_anch_column}} % extra height + \clf_markregionboxtaggedn#1{columnarea:\the\c_anch_column}#2\relax} % extra height \unexpanded\def\anch_mark_region_box {\iftrialtypesetting diff --git a/tex/context/base/mkiv/attr-lay.lua b/tex/context/base/mkiv/attr-lay.lua index ff9d1c38f..28f6e9276 100644 --- a/tex/context/base/mkiv/attr-lay.lua +++ b/tex/context/base/mkiv/attr-lay.lua @@ -201,6 +201,7 @@ function viewerlayers.start(name) else texsetattribute(a_viewerlayer,a) end + -- or macro texsettokenlist("currentviewerlayertoks",name) end diff --git a/tex/context/base/mkiv/buff-ver.lua b/tex/context/base/mkiv/buff-ver.lua index ad06dceec..0aa2fa62a 100644 --- a/tex/context/base/mkiv/buff-ver.lua +++ b/tex/context/base/mkiv/buff-ver.lua @@ -818,7 +818,9 @@ local function typestring(settings) local compact = settings.compact local compactor = compact and compactors[compact] if compactor then +print("!!!!!!!!!!1",content) content = lpegmatch(compactor,content) or content +print("!!!!!!!!!!2",content) end -- content = decodecomment(content) -- content = dotabs(content,settings) diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 80f15c587..f94412de7 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2019.10.29 15:00} +\newcontextversion{2019.11.12 18:49} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 880ae7fa3..bd0607c5a 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2019.10.29 15:00} +\edef\contextversion{2019.11.12 18:49} \edef\contextkind {beta} %D Kind of special: diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl index 23cebe57e..00afd486d 100644 --- a/tex/context/base/mkiv/context.mkxl +++ b/tex/context/base/mkiv/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2019.10.29 15:00} +\edef\contextversion{2019.11.12 18:49} \edef\contextkind {beta} %D Kind of special: diff --git a/tex/context/base/mkiv/core-uti.lua b/tex/context/base/mkiv/core-uti.lua index cd867db1b..50c7bc9dc 100644 --- a/tex/context/base/mkiv/core-uti.lua +++ b/tex/context/base/mkiv/core-uti.lua @@ -269,6 +269,16 @@ end local function load(filename) if lfs.isfile(filename) then + + local function dofile(filename) + local result = loadstring(io.loaddata(filename)) + if result then + return result() + else + return nil + end + end + local okay, data = pcall(dofile,filename) if okay and type(data) == "table" then local jobversion = job.version diff --git a/tex/context/base/mkiv/data-crl.lua b/tex/context/base/mkiv/data-crl.lua index dec9972f1..bdc5cf530 100644 --- a/tex/context/base/mkiv/data-crl.lua +++ b/tex/context/base/mkiv/data-crl.lua @@ -26,7 +26,7 @@ local runner = sandbox.registerrunner { name = "curl resolver", method = "execute", program = "curl", - template = "--silent --insecure --create-dirs --output %cachename% %original%", + template = '--silent --insecure --create-dirs --output "%cachename%" "%original%"', checkers = { cachename = "cache", original = "url", diff --git a/tex/context/base/mkiv/data-res.lua b/tex/context/base/mkiv/data-res.lua index f3b76778f..15d9f3db9 100644 --- a/tex/context/base/mkiv/data-res.lua +++ b/tex/context/base/mkiv/data-res.lua @@ -1839,10 +1839,10 @@ function resolvers.dowithvariable(name,func) end function resolvers.locateformat(name) - local engine = environment.ownmain or "luatex" - local barename = removesuffix(name) + local engine = environment.ownmain or "luatex" + local barename = removesuffix(file.basename(name)) local fullname = addsuffix(barename,"fmt") - local fmtname = caches.getfirstreadablefile(fullname,"formats",engine) or "" + local fmtname = caches.getfirstreadablefile(fullname,"formats",engine) or "" if fmtname == "" then fmtname = resolvers.findfile(fullname) fmtname = cleanpath(fmtname) @@ -1853,11 +1853,11 @@ function resolvers.locateformat(name) local lucname = addsuffix(barename,luasuffixes.luc) local luiname = addsuffix(barename,luasuffixes.lui) if isfile(luiname) then - return barename, luiname + return fmtname, luiname elseif isfile(lucname) then - return barename, lucname + return fmtname, lucname elseif isfile(luaname) then - return barename, luaname + return fmtname, luaname end end return nil, nil diff --git a/tex/context/base/mkiv/data-sch.lua b/tex/context/base/mkiv/data-sch.lua index 2e880e997..a4a0b43cc 100644 --- a/tex/context/base/mkiv/data-sch.lua +++ b/tex/context/base/mkiv/data-sch.lua @@ -72,7 +72,7 @@ local runner = sandbox.registerrunner { name = "curl resolver", method = "execute", program = "curl", - template = "--silent --insecure --create-dirs --output %cachename% %original%", + template = '--silent --insecure --create-dirs --output "%cachename%" "%original%"', checkers = { cachename = "cache", original = "url", diff --git a/tex/context/base/mkiv/data-vir.lua b/tex/context/base/mkiv/data-vir.lua index c5e63039c..5a96a1d21 100644 --- a/tex/context/base/mkiv/data-vir.lua +++ b/tex/context/base/mkiv/data-vir.lua @@ -30,7 +30,7 @@ function savers.virtual(specification,content,suffix) if type(path) ~= "string" or path == "" then path = "virtualfile" end - local filename = suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,suffix) + local filename = suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,n) if trace_virtual then report_virtual("saver: file %a saved",filename) end diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index a19acc1a1..77b1c1888 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -27,7 +27,7 @@ if not modules then modules = { } end modules ['font-cff'] = { -- the other hand, we can now feed back cff2 stuff. local next, type, tonumber, rawget = next, type, tonumber, rawget -local byte, char, gmatch = string.byte, string.char, string.gmatch +local byte, char, gmatch, sub = string.byte, string.char, string.gmatch, string.sub local concat, remove, unpack = table.concat, table.remove, table.unpack local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct @@ -145,6 +145,38 @@ local defaultstrings = { [0] = -- taken from ff "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold", } +local standardnames = { [0] = -- needed for seac + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", + "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", + "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", + "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", + "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", + "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", + "z", "braceleft", "bar", "braceright", "asciitilde", false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, "exclamdown", + "cent", "sterling", "fraction", "yen", "florin", "section", "currency", + "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", + "guilsinglright", "fi", "fl", false, "endash", "dagger", "daggerdbl", + "periodcentered", false, "paragraph", "bullet", "quotesinglbase", + "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", + false, "questiondown", false, "grave", "acute", "circumflex", "tilde", + "macron", "breve", "dotaccent", "dieresis", false, "ring", "cedilla", false, + "hungarumlaut", "ogonek", "caron", "emdash", false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, "AE", false, "ordfeminine", false, false, false, false, "Lslash", + "Oslash", "OE", "ordmasculine", false, false, false, false, false, "ae", + false, false, false, "dotlessi", false, false, "lslash", "oslash", "oe", + "germandbls", false, false, false, false +} + local cffreaders = { readbyte, readushort, @@ -655,6 +687,7 @@ do local x = 0 local y = 0 local width = false + local lsb = 0 local r = 0 local stems = 0 local globalbias = 0 @@ -678,6 +711,9 @@ do local factors = false local axis = false local vsindex = 0 + local justpass = false + local seacs = { } + local procidx = nil local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) @@ -1264,7 +1300,7 @@ do end local function divide() - if version == 1 then + if version == "cff" then local d = stack[top] top = top - 1 stack[top] = stack[top] / d @@ -1272,7 +1308,7 @@ do end local function closepath() - if version == 1 then + if version == "cff" then if trace_charstrings then showstate("closepath") end @@ -1281,65 +1317,80 @@ do end local function hsbw() - if version == 1 then + if version == "cff" then if trace_charstrings then showstate("hsbw") end - -- lsb = stack[top-1] + lsb = stack[top-1] or 0 width = stack[top] end top = 0 end - local function seac() - if version == 1 then + local function sbw() + if version == "cff" then if trace_charstrings then - showstate("seac") + showstate("sbw") end + lsb = stack[top-3] + width = stack[top-1] end top = 0 end - local function sbw() - if version == 1 then + -- asb adx ady bchar achar seac (accented characters) + + local function seac() + if version == "cff" then if trace_charstrings then - showstate("sbw") + showstate("seac") end - width = stack[top-1] end top = 0 end - -- these are probably used for special cases i.e. call out to postscript + -- These are probably used for special cases i.e. call out to the + -- postscript interpreter (p 61 of the spec as well as chapter 8). + + local popped = 3 + local hints = 3 + + -- arg1 ... argn n othersubr# <callothersubr> (on postscript stack) local function callothersubr() - if version == 1 then - -- we don't support this (ok, we could mimick these othersubs) + if version == "cff" then if trace_charstrings then - showstate("callothersubr (unsupported)") + showstate("callothersubr") + end + if stack[top] == hints then + popped = stack[top-2] + else + popped = 3 end + top = top - (stack[top-1] + 2) + else + top = 0 end - top = 0 end + -- <pop> number (from postscript stack) + local function pop() - if version == 1 then - -- we don't support this + if version == "cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("pop") end top = top + 1 - stack[top] = 0 -- a dummy + stack[top] = popped else top = 0 end end local function setcurrentpoint() - if version == 1 then - -- we don't support this + if version == "cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("setcurrentpoint (unsupported)") end x = x + stack[top-1] y = y + stack[top] @@ -1489,6 +1540,41 @@ do hvcurveto, -- 31 } + local reverse = { [0] = + "unsupported", + "getstem", + "unsupported", + "getstem", + "vmoveto", + "rlineto", + "hlineto", + "vlineto", + "rrcurveto", + "unsupported", + "unsupported", + "unsupported", + "unsupported", + "hsbw", + "unsupported", + "setvsindex", + "blend", + "unsupported", + "getstem", + "getmask", + "getmask", + "rmoveto", + "hmoveto", + "getstem", + "rcurveline", + "rlinecurve", + "vvcurveto", + "hhcurveto", + "unsupported", + "unsupported", + "vhcurveto", + "hvcurveto", + } + local subactions = { -- cff 1 [000] = dotsection, @@ -1540,6 +1626,7 @@ do for i=1132,2048 do t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) end + -- we could inline some ... setmetatableindex(encode,function(t,k) -- 16.16-bit signed fixed value local r = round(k) @@ -1625,7 +1712,7 @@ do local function call(scope,list,bias) -- ,process) depth = depth + 1 if top == 0 then - showstate(formatters["unknown %s call %s"](scope,"?")) + showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) top = 0 else local index = stack[top] + bias @@ -1637,7 +1724,7 @@ do if tab then process(tab) else - showstate(formatters["unknown %s call %s"](scope,index)) + showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) top = 0 end end @@ -1646,8 +1733,6 @@ do -- precompiling and reuse is much slower than redoing the calls - local justpass = false - -- local function decode(str) -- local a, b, c, d, e = byte(str,1,5) -- if a == 28 then @@ -1765,6 +1850,17 @@ do r = r + 1 ; result[r] = chars[12] r = r + 1 ; result[r] = chars[t] top = 0 + elseif t == 6 then + seacs[procidx] = { + asb = stack[1], + adx = stack[2], + ady = stack[3], + base = stack[4], + accent = stack[5], + width = width, + lsb = lsb, + } + top = 0 else local a = subactions[t] if a then @@ -1796,46 +1892,56 @@ do -- cff 1: (when cff2 strip them) elseif t == 1 or t == 3 or t == 18 or operation == 23 then p_getstem() -- at the start -if true then - if top > 0 then - for i=1,top do - r = r + 1 ; result[r] = encode[stack[i]] + if true then + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 end + r = r + 1 ; result[r] = chars[t] + else top = 0 end - r = r + 1 ; result[r] = chars[t] -else - top = 0 -end i = i + 1 -- cff 1: (when cff2 strip them) elseif t == 19 or t == 20 then local s = p_getmask() or 0 -- after the stems -if true then - if top > 0 then - for i=1,top do - r = r + 1 ; result[r] = encode[stack[i]] + if true then + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 + end + r = r + 1 ; result[r] = chars[t] + for j=1,s do + i = i + 1 + r = r + 1 ; result[r] = chars[tab[i]] end + else + i = i + s top = 0 end - r = r + 1 ; result[r] = chars[t] - for j=1,s do - i = i + 1 - r = r + 1 ; result[r] = chars[tab[i]] - end -else - i = i + s - top = 0 -end i = i + 1 -- cff 1: closepath elseif t == 9 then top = 0 i = i + 1 elseif t == 13 then - local s = hsbw() or 0 - i = i + s + 1 + hsbw() + if version == "cff" then + -- we do a moveto over lsb + r = r + 1 ; result[r] = encode[lsb] + r = r + 1 ; result[r] = chars[22] + else + -- lsb is supposed to be zero + end + i = i + 1 else + if trace_charstrings then + showstate(reverse[t] or "<action>") + end if top > 0 then for i=1,top do r = r + 1 ; result[r] = encode[stack[i]] @@ -1856,7 +1962,7 @@ end end else if trace_charstrings then - showvalue("<action>",t) + showstate(reverse[t] or "<action>") end top = 0 i = i + 1 @@ -1915,7 +2021,7 @@ end end end - local function processshape(tab,index) + local function processshape(tab,index,hack) if not tab then glyphs[index] = { @@ -1931,10 +2037,13 @@ end x = 0 y = 0 width = false + lsb = 0 r = 0 top = 0 stems = 0 result = { } -- we could reuse it when only boundingbox calculations are needed + popped = 3 + procidx = index xmin = 0 xmax = 0 @@ -1952,6 +2061,10 @@ end process(tab) + if hack then + return x, y + end + local boundingbox = { round(xmin), round(ymin), @@ -2016,6 +2129,8 @@ end axis = false regions = data.regions justpass = streams == true + popped = 3 + seacs = { } if regions then regions = { regions } -- needs checking axis = data.factors or false @@ -2030,6 +2145,8 @@ end locals = false globals = false strings = false + popped = 3 + seacs = { } end local function setwidths(private) @@ -2064,7 +2181,35 @@ end startparsing(fontdata,data,streams) for index=1,#charstrings do processshape(charstrings[index],index-1) --- charstrings[index] = nil -- free memory (what if used more often?) + end + if justpass and next(seacs) then + -- old type 1 stuff ... seacs + local charset = data.dictionaries[1].charset + if charset then + local lookup = table.swapped(charset) + for index, v in next, seacs do + local bindex = lookup[standardnames[v.base]] + local aindex = lookup[standardnames[v.accent]] + local bglyph = bindex and glyphs[bindex] + local aglyph = aindex and glyphs[aindex] + if bglyph and aglyph then + -- this is a real ugly hack but we seldom enter this branch (e.g. old lbr) + local jp = justpass + justpass = false + local x, y = processshape(charstrings[bindex+1],bindex,true) + justpass = jp + -- + local base = bglyph.stream + local accent = aglyph.stream + local moveto = encode[-x-v.asb+v.adx] .. chars[22] + .. encode[-y +v.ady] .. chars[ 4] + -- prune an endchar + base = sub(base,1,#base-1) + -- combine them + glyphs[index].stream = base .. moveto .. accent + end + end + end end stopparsing(fontdata,data) else @@ -2085,6 +2230,7 @@ end glyphs = glphs or { } justpass = streams == true + seacs = { } globalbias, localbias = setbias(globals,locals,nobias) nominalwidth, defaultwidth = setwidths(dictionary.private) diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index 652794142..47b8580d4 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -466,6 +466,7 @@ function constructors.scale(tfmdata,specification) target.size = scaledpoints -- target.encodingbytes = properties.encodingbytes or 1 + target.subfont = properties.subfont target.embedding = properties.embedding or "subset" target.tounicode = 1 target.cidinfo = properties.cidinfo @@ -1034,6 +1035,7 @@ function constructors.finalize(tfmdata) properties.psname = properties.psname or tfmdata.psname -- properties.encodingbytes = tfmdata.encodingbytes or 1 + properties.subfont = tfmdata.subfont or nil properties.embedding = tfmdata.embedding or "subset" properties.tounicode = tfmdata.tounicode or 1 properties.cidinfo = tfmdata.cidinfo or nil @@ -1067,6 +1069,7 @@ function constructors.finalize(tfmdata) tfmdata.psname = nil -- tfmdata.encodingbytes = nil + tfmdata.subfont = nil tfmdata.embedding = nil tfmdata.tounicode = nil tfmdata.cidinfo = nil diff --git a/tex/context/base/mkiv/font-fbk.lua b/tex/context/base/mkiv/font-fbk.lua index 122e43ddc..b6c9a430d 100644 --- a/tex/context/base/mkiv/font-fbk.lua +++ b/tex/context/base/mkiv/font-fbk.lua @@ -189,6 +189,7 @@ local function composecharacters(tfmdata) chr_t, } end +t.depth = a_ury elseif c_ury > a_lly then -- messy test local dy if compose then @@ -219,6 +220,7 @@ local function composecharacters(tfmdata) else dy = - deltaxheight + extraxheight end +t.height = a_ury-dy local right = rightcommand[dx+dd] local down = downcommand[dy] if trace_visualize then @@ -245,6 +247,7 @@ local function composecharacters(tfmdata) chr_t, } end +t.height = a_ury end end else diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua index 3752203fa..ba8ee5ae1 100644 --- a/tex/context/base/mkiv/font-ocl.lua +++ b/tex/context/base/mkiv/font-ocl.lua @@ -483,7 +483,7 @@ do local pdfshapes = { } local inkscape = runner() if inkscape then - local indices = fonts.getindices(tfmdata) + -- local indices = fonts.getindices(tfmdata) local descriptions = tfmdata.descriptions local nofshapes = #svgshapes local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] diff --git a/tex/context/base/mkiv/l-lua.lua b/tex/context/base/mkiv/l-lua.lua index 51399216c..f411230d4 100644 --- a/tex/context/base/mkiv/l-lua.lua +++ b/tex/context/base/mkiv/l-lua.lua @@ -37,9 +37,9 @@ end -- this is lmtx only: -if lua and lua.openfile then - io.open = lua.openfile -end +-- if lua and lua.openfile then +-- io.open = lua.openfile +-- end -- lpeg diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua index 9ba64abba..4c277e35c 100644 --- a/tex/context/base/mkiv/lpdf-col.lua +++ b/tex/context/base/mkiv/lpdf-col.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['lpdf-col'] = { license = "see context related readme files" } +-- slants also page ? + local type, next, tostring, tonumber = type, next, tostring, tonumber local char, byte, format, gsub, rep, gmatch = string.char, string.byte, string.format, string.gsub, string.rep, string.gmatch local settings_to_array, settings_to_numbers = utilities.parsers.settings_to_array, utilities.parsers.settings_to_numbers @@ -740,36 +742,36 @@ do end) -- local fillcolors = { - -- red = { "pdf", "origin", "1 0 0 rg" }, - -- green = { "pdf", "origin", "0 1 0 rg" }, - -- blue = { "pdf", "origin", "0 0 1 rg" }, - -- gray = { "pdf", "origin", ".5 g" }, - -- black = { "pdf", "origin", "0 g" }, - -- palered = { "pdf", "origin", "1 .75 .75 rg" }, - -- palegreen = { "pdf", "origin", ".75 1 .75 rg" }, - -- paleblue = { "pdf", "origin", ".75 .75 1 rg" }, - -- palegray = { "pdf", "origin", ".75 g" }, + -- red = { "pdf", "page", "1 0 0 rg" }, + -- green = { "pdf", "page", "0 1 0 rg" }, + -- blue = { "pdf", "page", "0 0 1 rg" }, + -- gray = { "pdf", "page", ".5 g" }, + -- black = { "pdf", "page", "0 g" }, + -- palered = { "pdf", "page", "1 .75 .75 rg" }, + -- palegreen = { "pdf", "page", ".75 1 .75 rg" }, + -- paleblue = { "pdf", "page", ".75 .75 1 rg" }, + -- palegray = { "pdf", "page", ".75 g" }, -- } -- -- local strokecolors = { - -- red = { "pdf", "origin", "1 0 0 RG" }, - -- green = { "pdf", "origin", "0 1 0 RG" }, - -- blue = { "pdf", "origin", "0 0 1 RG" }, - -- gray = { "pdf", "origin", ".5 G" }, - -- black = { "pdf", "origin", "0 G" }, - -- palered = { "pdf", "origin", "1 .75 .75 RG" }, - -- palegreen = { "pdf", "origin", ".75 1 .75 RG" }, - -- paleblue = { "pdf", "origin", ".75 .75 1 RG" }, - -- palegray = { "pdf", "origin", ".75 G" }, + -- red = { "pdf", "page", "1 0 0 RG" }, + -- green = { "pdf", "page", "0 1 0 RG" }, + -- blue = { "pdf", "page", "0 0 1 RG" }, + -- gray = { "pdf", "page", ".5 G" }, + -- black = { "pdf", "page", "0 G" }, + -- palered = { "pdf", "page", "1 .75 .75 RG" }, + -- palegreen = { "pdf", "page", ".75 1 .75 RG" }, + -- paleblue = { "pdf", "page", ".75 .75 1 RG" }, + -- palegray = { "pdf", "page", ".75 G" }, -- } -- -- backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color -- - -- red = { "pdf", "origin", "1 0 0 rg 1 0 0 RG" }, - -- green = { "pdf", "origin", "0 1 0 rg 0 1 0 RG" }, - -- blue = { "pdf", "origin", "0 0 1 rg 0 0 1 RG" }, - -- gray = { "pdf", "origin", ".75 g .75 G" }, - -- black = { "pdf", "origin", "0 g 0 G" }, + -- red = { "pdf", "page", "1 0 0 rg 1 0 0 RG" }, + -- green = { "pdf", "page", "0 1 0 rg 0 1 0 RG" }, + -- blue = { "pdf", "page", "0 0 1 rg 0 0 1 RG" }, + -- gray = { "pdf", "page", ".75 g .75 G" }, + -- black = { "pdf", "page", "0 g 0 G" }, -- -- -- rulecolors = fillcolors, -- -- fillcolors = fillcolors, @@ -792,7 +794,7 @@ do local c_cache = setmetatableindex(function(t,m) local v = setmetatableindex(function(t,c) - local p = { "pdf", "origin", "q " .. pdfcolor(m,c) } + local p = { "pdf", "page", "q " .. pdfcolor(m,c) } t[c] = p return p end) @@ -806,7 +808,7 @@ do local p = pdftransparency(transparency) local v = setmetatableindex(function(t,colormodel) local v = setmetatableindex(function(t,color) - local v = { "pdf", "origin", "q " .. pdfcolor(colormodel,color) .. " " .. p } + local v = { "pdf", "page", "q " .. pdfcolor(colormodel,color) .. " " .. p } t[color] = v return v end) @@ -830,8 +832,8 @@ do backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color startcolor = startcolor, - -- stopcolor = { "pdf", "origin", "0 g 0 G Q" }, - stopcolor = { "pdf", "origin", "Q" }, + -- stopcolor = { "pdf", "page", "0 g 0 G Q" }, + stopcolor = { "pdf", "page", "Q" }, startslant = startslant, stopslant = { "pdf", "origin", "Q" }, diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua index 4cce7fc74..e79a5a17f 100644 --- a/tex/context/base/mkiv/lpdf-lmt.lua +++ b/tex/context/base/mkiv/lpdf-lmt.lua @@ -843,15 +843,10 @@ end -- rules -local f_font = formatters["F%d"] -local f_form = formatters["Fm%d"] -local f_group = formatters["Gp%d"] -local f_image = formatters["Im%d"] +local flushedxforms = { } -- actually box resources but can also be direct +local localconverter = nil -- will be set -local flushedxforms = { } -- actually box resources but can also be direct -local localconverter = nil -- will be set - -local flushrule, flushsimplerule, flushimage do +local flushrule, flushsimplerule, flushimage, flushgroup do local rulecodes = nodes.rulecodes local newrule = nodes.pool.rule @@ -874,6 +869,7 @@ local flushrule, flushsimplerule, flushimage do local f_fm = formatters["/Fm%d Do"] local f_im = formatters["/Im%d Do"] + local f_gr = formatters["/Gp%d Do"] local s_b <const> = "q" local s_e <const> = "Q" @@ -1054,7 +1050,7 @@ local flushrule, flushsimplerule, flushimage do local groups = 0 local group = nil - function lpdf.flushgroup(content,bbox) + flushgroup = function(content,bbox) if not group then group = pdfdictionary { Type = pdfconstant("Group"), @@ -1072,9 +1068,11 @@ local flushrule, flushsimplerule, flushimage do local objnum = pdfflushstreamobject(content,wrapper,false) groups = groups + 1 usedxgroups[groups] = objnum - return f_group(groups) + return f_gr(groups) end + lpdf.flushgroup = flushgroup -- todo: access via driver in mlib-pps + -- end of experiment local function flushpdfximage(current,pos_h,pos_v,pos_r,size_h,size_v) @@ -1310,16 +1308,61 @@ local wrapup, registerpage do local pages = { } local maxkids = 10 local nofpages = 0 + local pagetag = "unset" registerpage = function(object) nofpages = nofpages + 1 local objnum = pdfpagereference(nofpages) pages[nofpages] = { + page = nofpages, -- original number, only for diagnostics objnum = objnum, object = object, + tag = pagetag, } end + function lpdf.setpagetag(tag) + pagetag = tag or "unset" + end + + function lpdf.getnofpages() + return nofpages + end + + function lpdf.getpagetags() + local list = { } + for i=1,nofpages do + list[i] = pages[i].tag + end + return list + end + + function lpdf.setpageorder(mapping) + -- mapping can be a hash so: + local list = table.sortedkeys(mapping) + local n = #list + if n == nofpages then + local done = { } + local hash = { } + for i=1,n do + local order = mapping[list[i]] + if hash[order] then + report("invalid page order, duplicate entry %i",order) + return + elseif order < 1 or order > nofpages then + report("invalid page order, no page %i",order) + return + else + done[i] = pages[order] + hash[order] = true + end + end + pages = done + else + report("invalid page order, %i entries expected",nofpages) + end + end + wrapup = function(driver) -- hook (to reshuffle pages) @@ -1467,176 +1510,191 @@ do end -local pushmode, popmode +local flushdeferred -- defined later -local function finalize(driver,details) +local level = 0 - pushmode() +local finalize do - pdf_goto_pagemode() -- for now + local f_font = formatters["F%d"] - local objnum = details.objnum - local specification = details.specification + local f_form = formatters["Fm%d"] + local f_group = formatters["Gp%d"] + local f_image = formatters["Im%d"] - local content = concat(buffer,"\n",1,b) + finalize = function(driver,details) - if compact then - content = compact(content) - end + level = level + 1 - local fonts = nil - local xforms = nil + pdf_goto_pagemode() -- for now - if next(usedfonts) then - fonts = pdfdictionary { } - for k, v in next, usedfonts do - fonts[f_font(v)] = pdfreference(pdfgetfontobjnumber(k)) -- we can overload for testing - end - end + local objnum = details.objnum + local specification = details.specification - -- messy: use real indexes for both ... so we need to change some in the - -- full luatex part + local content = concat(buffer,"\n",1,b) - if next(usedxforms) or next(usedximages) or next(usedxgroups) then - xforms = pdfdictionary { } - for k in sortedhash(usedxforms) do - -- xforms[f_form(k)] = pdfreference(k) - xforms[f_form(getxformname(k))] = pdfreference(k) + if compact then + content = compact(content) end - for k, v in sortedhash(usedximages) do - xforms[f_image(k)] = pdfreference(v) - end - for k, v in sortedhash(usedxgroups) do - xforms[f_group(k)] = pdfreference(v) + + local fonts = nil + local xforms = nil + + if next(usedfonts) then + fonts = pdfdictionary { } + for k, v in next, usedfonts do + fonts[f_font(v)] = pdfreference(pdfgetfontobjnumber(k)) -- we can overload for testing + end end - end - reset_buffer() + -- messy: use real indexes for both ... so we need to change some in the + -- full luatex part - -- finish_pdfpage_callback(shippingmode == "page") + if next(usedxforms) or next(usedximages) or next(usedxgroups) then + xforms = pdfdictionary { } + for k in sortedhash(usedxforms) do + -- xforms[f_form(k)] = pdfreference(k) + xforms[f_form(getxformname(k))] = pdfreference(k) + end + for k, v in sortedhash(usedximages) do + xforms[f_image(k)] = pdfreference(v) + end + for k, v in sortedhash(usedxgroups) do + xforms[f_group(k)] = pdfreference(v) + end + end - if shippingmode == "page" then + reset_buffer() - local pageproperties = lpdf.getpageproperties() + -- finish_pdfpage_callback(shippingmode == "page") - local pageresources = pageproperties.pageresources - local pageattributes = pageproperties.pageattributes - local pagesattributes = pageproperties.pagesattributes + if shippingmode == "page" then - pageresources.Font = fonts - pageresources.XObject = xforms - pageresources.ProcSet = lpdf.procset() + local pageproperties = lpdf.getpageproperties() - local xorigin, yorigin, relocated = backends.codeinjections.getpageorigin() -- for now here + local pageresources = pageproperties.pageresources + local pageattributes = pageproperties.pageattributes + local pagesattributes = pageproperties.pagesattributes - local bbox = pdfarray { - (boundingbox[1] + xorigin) * bpfactor, - (boundingbox[2] + yorigin) * bpfactor, - (boundingbox[3] + xorigin) * bpfactor, - (boundingbox[4] + yorigin) * bpfactor, - } + pageresources.Font = fonts + pageresources.XObject = xforms + pageresources.ProcSet = lpdf.procset() - if relocated then - content = formatters["1 0 0 1 %.6N %.6N cm\n%s"](bbox[1],bbox[2],content) - end + local xorigin, yorigin, relocated = backends.codeinjections.getpageorigin() -- for now here - local contentsobj = pdfflushstreamobject(content,false,false) + local bbox = pdfarray { + (boundingbox[1] + xorigin) * bpfactor, + (boundingbox[2] + yorigin) * bpfactor, + (boundingbox[3] + xorigin) * bpfactor, + (boundingbox[4] + yorigin) * bpfactor, + } - pageattributes.Type = pdf_page - pageattributes.Contents = pdfreference(contentsobj) - pageattributes.Resources = pageresources - -- pageattributes.Resources = pdfreference(pdfflushobject(pageresources)) - pageattributes.MediaBox = bbox - pageattributes.Parent = nil -- precalculate - pageattributes.Group = nil -- todo + if relocated then + content = formatters["1 0 0 1 %.6N %.6N cm\n%s"](bbox[1],bbox[2],content) + end - -- resources can be indirect + local contentsobj = pdfflushstreamobject(content,false,false) - registerpage(pageattributes) + pageattributes.Type = pdf_page + pageattributes.Contents = pdfreference(contentsobj) + pageattributes.Resources = pageresources + -- pageattributes.Resources = pdfreference(pdfflushobject(pageresources)) + pageattributes.MediaBox = bbox + pageattributes.Parent = nil -- precalculate + pageattributes.Group = nil -- todo - lpdf.finalizepage(true) + -- resources can be indirect - if relocated then - if pageattributes.TrimBox then pageattributes.TrimBox = box end - if pageattributes.CropBox then pageattributes.CropBox = box end - if pageattributes.BleedBox then pageattributes.BleedBox = box end - end + registerpage(pageattributes) - else + lpdf.finalizepage(true) + + if relocated then + if pageattributes.TrimBox then pageattributes.TrimBox = box end + if pageattributes.CropBox then pageattributes.CropBox = box end + if pageattributes.BleedBox then pageattributes.BleedBox = box end + end - local xformtype = specification.type or 0 - local margin = specification.margin or 0 - local attributes = specification.attributes or "" - local resources = specification.resources or "" - - local wrapper = nil - - if xformtype == 0 then - wrapper = pdfdictionary { - Type = pdf_xobject, - Subtype = pdf_form, - FormType = 1, - BBox = nil, - Matrix = nil, - Resources = nil, - } else - wrapper = pdfdictionary { - BBox = nil, - Matrix = nil, - Resources = nil, - } - end - if xformtype == 0 or xformtype == 1 or xformtype == 3 then - wrapper.BBox = pdfarray { - -margin * bpfactor, - -margin * bpfactor, - (boundingbox[3] + margin) * bpfactor, - (boundingbox[4] + margin) * bpfactor, - } - end - if xformtype == 0 or xformtype == 2 or xformtype == 3 then - wrapper.Matrix = pdfarray { 1, 0, 0, 1, 0, 0 } - end - -- todo: additional = resources + local xformtype = specification.type or 0 + local margin = specification.margin or 0 + local attributes = specification.attributes or "" + local resources = specification.resources or "" + + local wrapper = nil + + if xformtype == 0 then + wrapper = pdfdictionary { + Type = pdf_xobject, + Subtype = pdf_form, + FormType = 1, + BBox = nil, + Matrix = nil, + Resources = nil, + } + else + wrapper = pdfdictionary { + BBox = nil, + Matrix = nil, + Resources = nil, + } + end + if xformtype == 0 or xformtype == 1 or xformtype == 3 then + wrapper.BBox = pdfarray { + -margin * bpfactor, + -margin * bpfactor, + (boundingbox[3] + margin) * bpfactor, + (boundingbox[4] + margin) * bpfactor, + } + end + if xformtype == 0 or xformtype == 2 or xformtype == 3 then + wrapper.Matrix = pdfarray { 1, 0, 0, 1, 0, 0 } + end - local boxresources = lpdf.collectedresources { serialize = false } - boxresources.Font = fonts - boxresources.XObject = xforms + -- todo: additional = resources - -- todo: maybe share them - -- wrapper.Resources = pdfreference(pdfflushobject(boxresources)) + local boxresources = lpdf.collectedresources { serialize = false } + boxresources.Font = fonts + boxresources.XObject = xforms - if resources ~= "" then - boxresources = boxresources + resources - end - if attributes ~= "" then - wrapper = wrapper + attributes - end + -- todo: maybe share them + -- wrapper.Resources = pdfreference(pdfflushobject(boxresources)) - wrapper.Resources = next(boxresources) and boxresources or nil - wrapper.ProcSet = lpdf.procset() + if resources ~= "" then + boxresources = boxresources + resources + end + if attributes ~= "" then + wrapper = wrapper + attributes + end - -- pdfflushstreamobject(content,wrapper,false,objectnumber) - pdfflushstreamobject(content,wrapper,false,specification.objnum) + wrapper.Resources = next(boxresources) and boxresources or nil + wrapper.ProcSet = lpdf.procset() - end + -- pdfflushstreamobject(content,wrapper,false,objectnumber) + pdfflushstreamobject(content,wrapper,false,specification.objnum) - for objnum in sortedhash(usedxforms) do - local f = flushedxforms[objnum] - if f[1] == false then - f[1] = true - local objnum = f[2] -- specification.objnum - local specification = boxresources[objnum] - local list = specification.list - localconverter(list,"xform",f[2],specification) end - end - pdf_h, pdf_v = 0, 0 + for objnum in sortedhash(usedxforms) do + local f = flushedxforms[objnum] + if f[1] == false then + f[1] = true + local objnum = f[2] -- specification.objnum + local specification = boxresources[objnum] + local list = specification.list + localconverter(list,"xform",f[2],specification) + end + end - popmode() + pdf_h, pdf_v = 0, 0 + + if level == 1 then + flushdeferred() + end + level = level - 1 + + end end @@ -1674,7 +1732,6 @@ local compress = true local cache = false local info = "" local catalog = "" -local level = 0 local lastdeferred = false local majorversion = 1 local minorversion = 7 @@ -1687,14 +1744,14 @@ local f_stream_d_u = formatters["%i 0 obj\010<< %s /Length %i >>\010stream\010 local f_stream_d_c = formatters["%i 0 obj\010<< %s /Filter /FlateDecode /Length %i >>\010stream\010%s\010endstream\010endobj\010"] local f_stream_d_r = formatters["%i 0 obj\010<< %s >>\010stream\010%s\010endstream\010endobj\010"] -local f_object_b = formatters["%i 0 obj\010"] +----- f_object_b = formatters["%i 0 obj\010"] local f_stream_b_n_u = formatters["%i 0 obj\010<< /Length %i >>\010stream\010"] local f_stream_b_n_c = formatters["%i 0 obj\010<< /Filter /FlateDecode /Length %i >>\010stream\010"] local f_stream_b_d_u = formatters["%i 0 obj\010<< %s /Length %i >>\010stream\010"] local f_stream_b_d_c = formatters["%i 0 obj\010<< %s /Filter /FlateDecode /Length %i >>\010stream\010"] local f_stream_b_d_r = formatters["%i 0 obj\010<< %s >>\010stream\010"] -local s_object_e <const> = "\010endobj\010" +----- s_object_e <const> = "\010endobj\010" local s_stream_e <const> = "\010endstream\010endobj\010" do @@ -1920,7 +1977,7 @@ local function flushstreamobj(data,n,dict,comp,nolength) return n end -local function flushdeferred() +flushdeferred = function() -- was forward defined if lastdeferred then for n=lastdeferred,nofobjects do local o = objects[n] @@ -1934,19 +1991,6 @@ local function flushdeferred() end end --- These are already used above, so we define them now: - -pushmode = function() - level = level + 1 -end - -popmode = function() - if level == 1 then - flushdeferred() - end - level = level - 1 -end - -- n = pdf.obj([n,] objtext) -- n = pdf.obj([n,] "file", filename) -- n = pdf.obj([n,] "stream", streamtext [, attrtext]) @@ -2659,6 +2703,7 @@ do save = flushsave, restore = flushrestore, image = flushimage, + group = flushgroup, -- updatefontstate = updatefontstate, }, diff --git a/tex/context/base/mkiv/luat-fmt.lua b/tex/context/base/mkiv/luat-fmt.lua index e56728e58..acb212ef7 100644 --- a/tex/context/base/mkiv/luat-fmt.lua +++ b/tex/context/base/mkiv/luat-fmt.lua @@ -13,8 +13,10 @@ local luasuffixes = utilities.lua.suffixes local report_format = logs.reporter("resolvers","formats") -local function primaryflags() - local arguments = environment.arguments +-- this is a bit messy: we also handle flags in mtx-context so best we +-- can combine this some day (all here) + +local function primaryflags(arguments) local flags = { } if arguments.silent then flags[#flags+1] = "--interaction=batchmode" @@ -25,8 +27,7 @@ local function primaryflags() return concat(flags," ") end -local function secondaryflags() - local arguments = environment.arguments +local function secondaryflags(arguments) local trackers = arguments.trackers local directives = arguments.directives local flags = { } @@ -66,12 +67,13 @@ end local template = [[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]] local checkers = { - primaryflags = "string", - secondaryflags = "string", + primaryflags = "verbose", -- "flags" + secondaryflags = "verbose", -- "flags" luafile = "readable", -- "cache" texfile = "readable", -- "cache" redirect = "string", dump = "string", + binarypath = "string", } local runners = { @@ -98,58 +100,109 @@ local runners = { }, } -function environment.make_format(name,arguments) - local engine = environment.ownmain or "luatex" - local silent = environment.arguments.silent - local errors = environment.arguments.errors - -- change to format path (early as we need expanded paths) - local olddir = dir.current() - local path = caches.getwritablepath("formats",engine) or "" -- maybe platform - if path ~= "" then - lfs.chdir(path) - end - report_format("using format path %a",dir.current()) - -- check source file +local function validbinarypath() + if environment.arguments.addbinarypath then + local binarypath = environment.ownpath or "" + if binarypath ~= "" then + binarypath = dir.expandname(binarypath) + if lfs.isdir(binarypath) then + return binarypath + end + end + end +end + +function environment.make_format(formatname) + -- first we set up the engine and normally that information is provided + -- by the engine ... when we move to luametatex we could decide to simplfy + -- all the following + local arguments = environment.arguments + local engine = environment.ownmain or "luatex" + local silent = arguments.silent + local errors = arguments.errors + -- now we locate the to be used source files ... there are some variants that we + -- need to take care local texsourcename = "" + local texsourcepath = "" local fulltexsourcename = "" if engine == "luametatex" then - texsourcename = file.addsuffix(name,"mkxl") + texsourcename = file.addsuffix(formatname,"mkxl") fulltexsourcename = resolvers.findfile(texsourcename,"tex") or "" end if fulltexsourcename == "" then - texsourcename = file.addsuffix(name,"mkiv") + texsourcename = file.addsuffix(formatname,"mkiv") fulltexsourcename = resolvers.findfile(texsourcename,"tex") or "" end if fulltexsourcename == "" then - texsourcename = file.addsuffix(name,"tex") + texsourcename = file.addsuffix(formatname,"tex") fulltexsourcename = resolvers.findfile(texsourcename,"tex") or "" end if fulltexsourcename == "" then - report_format("no tex source file with name %a (mkiv or tex)",name) - lfs.chdir(olddir) + report_format("no tex source file with name %a (mkiv or tex)",formatname) return - else - report_format("using tex source file %a",fulltexsourcename) end - local texsourcepath = dir.expandname(file.dirname(fulltexsourcename)) -- really needed - -- check specification - local specificationname = file.replacesuffix(fulltexsourcename,"lus") - local fullspecificationname = resolvers.findfile(specificationname,"tex") or "" - if fullspecificationname == "" then - specificationname = file.join(texsourcepath,"context.lus") - fullspecificationname = resolvers.findfile(specificationname,"tex") or "" + report_format("using tex source file %a",fulltexsourcename) + -- this is tricky: we normally have an expanded path but when we don't have one, + -- the current path gets appended + fulltexsourcename = dir.expandname(fulltexsourcename) + texsourcepath = file.dirname(fulltexsourcename) + if not lfs.isfile(fulltexsourcename) then + report_format("no accessible tex source file with name %a",fulltexsourcename) + return end + -- we're getting there, that is: we have a file that specifies the context format; + -- in addition to that file we need a stub for setting up lua as we start rather + -- minimalistic + local specificationname = "context.lus" + local specificationpath = "" + local fullspecificationname = resolvers.findfile(specificationname) or "" if fullspecificationname == "" then - report_format("unknown stub specification %a",specificationname) - lfs.chdir(olddir) + report_format("unable to locate specification file %a",specificationname) + return + end + report_format("using specification file %a",fullspecificationname) + -- let's expand the found name and so an extra check + fullspecificationname = dir.expandname(fullspecificationname) + specificationpath = file.dirname(fullspecificationname) + if texsourcepath ~= specificationpath then + report_format("tex source file and specification file are on different paths") + return + end + -- let's do an additional check here, if only because we then have a bit better + -- feedback on what goes wrong + if not lfs.isfile(fulltexsourcename) then + report_format("no accessible tex source file with name %a",fulltexsourcename) + return + end + if not lfs.isfile(fullspecificationname) then + report_format("no accessible specification file with name %a",fulltexsourcename) return end - local specificationpath = file.dirname(fullspecificationname) - -- load specification + -- we're still going strong + report_format("using tex source path %a",texsourcepath) + -- we will change tot the format path because some local files will be created + -- in the process and we don't want clutter + local validformatpath = caches.getwritablepath("formats",engine) or "" + local startupdir = dir.current() + if validformatpath == "" then + report_format("invalid format path, insufficient write access") + return + end + -- in case we have a qualified path, we need to do this before we change + -- because we can have half qualified paths (in lxc) + local binarypath = validbinarypath() + report_format("changing to format path %a",validformatpath) + lfs.chdir(validformatpath) + if dir.current() ~= validformatpath then + report_format("unable to change to format path %a",validformatpath) + return + end + -- we're now ready for making the format which we do on the first found + -- writable path local usedluastub = nil local usedlualibs = dofile(fullspecificationname) if type(usedlualibs) == "string" then - usedluastub = file.join(file.dirname(fullspecificationname),usedlualibs) + usedluastub = file.join(specificationpath,usedlualibs) elseif type(usedlualibs) == "table" then report_format("using stub specification %a",fullspecificationname) local texbasename = file.basename(name) @@ -168,56 +221,68 @@ function environment.make_format(name,arguments) end else report_format("invalid stub specification %a",fullspecificationname) - lfs.chdir(olddir) + lfs.chdir(startupdir) + return + end + -- we're ready to go now but first we check if we actually do have a runner + -- for this engine ... we'd better have one + local runner = runners[engine] + if not runner then + report_format("the format %a cannot be generated, no runner available for engine %a",name,engine) + lfs.chdir(startupdir) return end - -- generate format + -- now we can generate the format, where we use a couple of flags, + -- split into two categories + local primaryflags = primaryflags(arguments) + local secondaryflags = secondaryflags(arguments) local specification = { - primaryflags = primaryflags(), - secondaryflags = secondaryflags(), + binarypath = binarypath, + primaryflags = primaryflags, + secondaryflags = secondaryflags, luafile = quoted(usedluastub), texfile = quoted(fulltexsourcename), dump = os.platform == "unix" and "\\\\dump" or "\\dump", } - local runner = runners[engine] - if not runner then - report_format("format %a cannot be generated, no runner available for engine %a",name,engine) - elseif silent then - statistics.starttiming() + if silent then specification.redirect = "> temp.log" - local result = runner(specification) - local runtime = statistics.stoptiming() - if result ~= 0 then - print(format("%s silent make > fatal error when making format %q",engine,name)) -- we use a basic print - else - print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime)) -- we use a basic print - end + end + statistics.starttiming() + local result = runner(specification) + local runtime = statistics.stoptiming() + if silent then os.remove("temp.log") - else - runner(specification) - end - -- remove related mem files - local pattern = file.removesuffix(file.basename(usedluastub)).."-*.mem" - -- report_format("removing related mplib format with pattern %a", pattern) - local mp = dir.glob(pattern) - if mp then - for i=1,#mp do - local name = mp[i] - report_format("removing related mplib format %a", file.basename(name)) - os.remove(name) - end end - lfs.chdir(olddir) + -- some final report + report_format() + if binarypath and binarypath ~= "" then + report_format("binary path : %s",binarypath or "?") + end + report_format("format path : %s",validformatpath) + report_format("luatex engine : %s",engine) + report_format("lua startup file : %s",usedluastub) + if primaryflags ~= "" then + report_format("primary flags : %s",primaryflags) + end + if secondaryflags ~= "" then + report_format("secondary flags : %s",secondaryflags) + end + report_format("context file : %s",fulltexsourcename) + report_format("run time : %.3f seconds",runtime) + report_format("return value : %s",result == 0 and "okay" or "error") + report_format() + -- last we go back to the home base + lfs.chdir(startupdir) end -local template = [[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]] +local template = [[%primaryflags% --fmt=%fmtfile% --lua=%luafile% %texfile% %secondaryflags%]] local checkers = { - flags = "string", - more = "string", - fmtfile = "readable", -- "cache" - luafile = "readable", -- "cache" - texfile = "readable", -- "cache" + primaryflags = "verbose", + secondaryflags = "verbose", + fmtfile = "readable", -- "cache" + luafile = "readable", -- "cache" + texfile = "readable", -- "cache" } local runners = { @@ -228,6 +293,13 @@ local runners = { checkers = checkers, reporter = report_format, }, + luametatex = sandbox.registerrunner { + name = "run luametatex format", + program = "luametatex", + template = template, + checkers = checkers, + reporter = report_format, + }, luajittex = sandbox.registerrunner { name = "run luajittex format", program = "luajittex", @@ -237,40 +309,67 @@ local runners = { }, } -function environment.run_format(name,data,more) - if name and name ~= "" then - local engine = environment.ownmain or "luatex" - local barename = file.removesuffix(name) - local fmtname = caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine) - if fmtname == "" then - fmtname = resolvers.findfile(file.addsuffix(barename,"fmt")) or "" - end - fmtname = resolvers.cleanpath(fmtname) - if fmtname == "" then - report_format("no format with name %a",name) - else - local barename = file.removesuffix(name) -- expanded name - local luaname = file.addsuffix(barename,"luc") - if not lfs.isfile(luaname) then - luaname = file.addsuffix(barename,"lua") - end - if not lfs.isfile(luaname) then - report_format("using format name %a",fmtname) - report_format("no luc/lua file with name %a",barename) - else - local runner = runners[engine] - if not runner then - report_format("format %a cannot be run, no runner available for engine %a",name,engine) - else - runner { - flags = primaryflags(), - fmtfile = quoted(barename), - luafile = quoted(luaname), - texfile = quoted(data), - more = more, - } - end - end - end +function environment.run_format(formatname,scriptname,filename,primaryflags,secondaryflags,verbose) + local engine = environment.ownmain or "luatex" + if not formatname or formatname == "" then + report_format("missing format name") + return + end + if not scriptname or scriptname == "" then + report_format("missing script name") + return + end + if not lfs.isfile(formatname) or not lfs.isfile(scriptname) then + formatname, scriptname = resolvers.locateformat(formatname) + end + if not formatname or formatname == "" then + report_format("invalid format name") + return + end + if not scriptname or scriptname == "" then + report_format("invalid script name") + return + end + local runner = runners[engine] + if not runner then + report_format("format %a cannot be run, no runner available for engine %a",file.nameonly(name),engine) + return + end + if not filename then + filename "" + end + local binarypath = validbinarypath() + local specification = { + binarypath = binarypath, + primaryflags = primaryflags or "", + secondaryflags = secondaryflags or "", + fmtfile = quoted(formatname), + luafile = quoted(scriptname), + texfile = filename ~= "" and quoted(filename) or "", + } + statistics.starttiming() + local result = runner(specification) + local runtime = statistics.stoptiming() + if verbose then + report_format() + if binarypath and binarypath ~= "" then + report_format("binary path : %s",binarypath) + end + report_format("luatex engine : %s",engine) + report_format("lua startup file : %s",scriptname) + report_format("tex format file : %s",formatname) + if filename ~= "" then + report_format("tex input file : %s",filename) + end + if primaryflags ~= "" then + report_format("primary flags : %s",primaryflags) + end + if secondaryflags ~= "" then + report_format("secondary flags : %s",secondaryflags) + end + report_format("run time : %.3f seconds",runtime) + report_format("return value : %s",result == 0 and "okay" or "error") + report_format() end + return result end diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv index c9018ba50..3a6afaa34 100644 --- a/tex/context/base/mkiv/math-ini.mkiv +++ b/tex/context/base/mkiv/math-ini.mkiv @@ -129,9 +129,8 @@ \mathflattenmode 31 -\ifdefined\mathlimitsmode - % ignore \limits and \nolimts when no scripts (better spacing) - \mathlimitsmode\plusone +\ifdefined\ordlimits\else + \ordlimits\limits \fi \appendtoks diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua index d8f4f36fd..5c078b784 100644 --- a/tex/context/base/mkiv/math-noa.lua +++ b/tex/context/base/mkiv/math-noa.lua @@ -177,15 +177,19 @@ local noadcodes = nodes.noadcodes local fencecodes = nodes.fencecodes local ordnoad_code = noadcodes.ord -local relnode_code = noadcodes.rel +local opdisplaylimitsnoad_code = noadcodes.opdisplaylimits +local oplimitsnoad_code = noadcodes.oplimits +local opnolimitsnoad_code = noadcodes.opnolimits local binnoad_code = noadcodes.bin +local relnode_code = noadcodes.rel local opennoad_code = noadcodes.open local closenoad_code = noadcodes.close local punctnoad_code = noadcodes.punct -local opdisplaylimitsnoad_code = noadcodes.opdisplaylimits -local oplimitsnoad_code = noadcodes.oplimits -local opnolimitsnoad_code = noadcodes.opnolimits local innernoad_code = noadcodes.inner +local undernoad_code = noadcodes.under +local overnoad_code = noadcodes.over +local vcenternoad_code = noadcodes.vcenter +local ordlimitsnoad_code = noadcodes.ordlimits or oplimitsnoad_code local noad_code = nodecodes.noad -- attr nucleus sub sup local accent_code = nodecodes.accent -- attr nucleus sub sup accent @@ -1747,14 +1751,19 @@ do local mathlists = characters.mathlists local validpair = { [ordnoad_code] = true, - [relnode_code] = true, + [opdisplaylimitsnoad_code] = true, + [oplimitsnoad_code] = true, + [opnolimitsnoad_code] = true, [binnoad_code] = true, -- new + [relnode_code] = true, [opennoad_code] = true, -- new [closenoad_code] = true, -- new [punctnoad_code] = true, -- new - [opdisplaylimitsnoad_code] = true, - [oplimitsnoad_code] = true, - [opnolimitsnoad_code] = true, + [innernoad_code] = false, + [undernoad_code] = false, + [overnoad_code] = false, + [vcenternoad_code] = false, + [ordlimitsnoad_code] = true, } local reported = setmetatableindex("table") @@ -2076,6 +2085,7 @@ do -- [opdisplaylimitsnoad_code] = "", -- [oplimitsnoad_code] = "", -- [opnolimitsnoad_code] = "", + -- [ordlimitsnoad_code] = "", -- [innernoad_code = "", -- [undernoad_code] = "", -- [overnoad_code] = "", diff --git a/tex/context/base/mkiv/math-stc.mkvi b/tex/context/base/mkiv/math-stc.mkvi index cc3625eb4..8048bf923 100644 --- a/tex/context/base/mkiv/math-stc.mkvi +++ b/tex/context/base/mkiv/math-stc.mkvi @@ -574,7 +574,7 @@ \edef\currentmathstackers{#category}% \edef\p_limits{\mathstackersparameter\c!mathlimits}% \ifx\p_limits\v!yes - \def\math_stackers_stop_group{\egroup\endgroup\limits}% + \def\math_stackers_stop_group{\egroup\endgroup\ordlimits}% \mathop\bgroup \else \let\math_stackers_stop_group\endgroup @@ -1236,39 +1236,39 @@ % alternatively we can move the original to FE* -\definemathoverextensible [vfenced] [overbar] ["FE33E] % ["203E] -\definemathunderextensible [vfenced] [underbar] ["FE33F] % ["203E] -\definemathdoubleextensible [vfenced] [doublebar] ["FE33E] ["FE33F] +\definemathoverextensible [\v!vfenced] [overbar] ["FE33E] % ["203E] +\definemathunderextensible [\v!vfenced] [underbar] ["FE33F] % ["203E] +\definemathdoubleextensible [\v!vfenced] [doublebar] ["FE33E] ["FE33F] -\definemathoverextensible [vfenced] [overbrace] ["FE3DE] % ["023DE] -\definemathunderextensible [vfenced] [underbrace] ["FE3DF] % ["023DF] -\definemathdoubleextensible [vfenced] [doublebrace] ["FE3DE] ["FE3DF] +\definemathoverextensible [\v!vfenced] [overbrace] ["FE3DE] % ["023DE] +\definemathunderextensible [\v!vfenced] [underbrace] ["FE3DF] % ["023DF] +\definemathdoubleextensible [\v!vfenced] [doublebrace] ["FE3DE] ["FE3DF] -\definemathoverextensible [vfenced] [overparent] ["FE3DC] % ["023DC] -\definemathunderextensible [vfenced] [underparent] ["FE3DD] % ["023DD] -\definemathdoubleextensible [vfenced] [doubleparent] ["FE3DC] ["FE3DD] +\definemathoverextensible [\v!vfenced] [overparent] ["FE3DC] % ["023DC] +\definemathunderextensible [\v!vfenced] [underparent] ["FE3DD] % ["023DD] +\definemathdoubleextensible [\v!vfenced] [doubleparent] ["FE3DC] ["FE3DD] -\definemathoverextensible [vfenced] [overbracket] ["FE3B4] % ["023B4] -\definemathunderextensible [vfenced] [underbracket] ["FE3B5] % ["023B5] -\definemathdoubleextensible [vfenced] [doublebracket] ["FE3B4] ["FE3B5] +\definemathoverextensible [\v!vfenced] [overbracket] ["FE3B4] % ["023B4] +\definemathunderextensible [\v!vfenced] [underbracket] ["FE3B5] % ["023B5] +\definemathdoubleextensible [\v!vfenced] [doublebracket] ["FE3B4] ["FE3B5] % \unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits} %D For mathml: -\definemathdoubleextensible [both] [overbarunderbar] ["FE33E] ["FE33F] -\definemathdoubleextensible [both] [overbraceunderbrace] ["FE3DE] ["FE3DF] -\definemathdoubleextensible [both] [overparentunderparent] ["FE3DC] ["FE3DD] -\definemathdoubleextensible [both] [overbracketunderbracket] ["FE3B4] ["FE3B5] - -\definemathovertextextensible [bothtext] [overbartext] ["FE33E] -\definemathundertextextensible [bothtext] [underbartext] ["FE33F] -\definemathovertextextensible [bothtext] [overbracetext] ["FE3DE] -\definemathundertextextensible [bothtext] [underbracetext] ["FE3DF] -\definemathovertextextensible [bothtext] [overparenttext] ["FE3DC] -\definemathundertextextensible [bothtext] [underparenttext] ["FE3DD] -\definemathovertextextensible [bothtext] [overbrackettext] ["FE3B4] -\definemathundertextextensible [bothtext] [underbrackettext] ["FE3B5] +\definemathdoubleextensible [\v!both] [overbarunderbar] ["FE33E] ["FE33F] +\definemathdoubleextensible [\v!both] [overbraceunderbrace] ["FE3DE] ["FE3DF] +\definemathdoubleextensible [\v!both] [overparentunderparent] ["FE3DC] ["FE3DD] +\definemathdoubleextensible [\v!both] [overbracketunderbracket] ["FE3B4] ["FE3B5] + +\definemathovertextextensible [\v!bothtext] [overbartext] ["FE33E] +\definemathundertextextensible [\v!bothtext] [underbartext] ["FE33F] +\definemathovertextextensible [\v!bothtext] [overbracetext] ["FE3DE] +\definemathundertextextensible [\v!bothtext] [underbracetext] ["FE3DF] +\definemathovertextextensible [\v!bothtext] [overparenttext] ["FE3DC] +\definemathundertextextensible [\v!bothtext] [underparenttext] ["FE3DD] +\definemathovertextextensible [\v!bothtext] [overbrackettext] ["FE3B4] +\definemathundertextextensible [\v!bothtext] [underbrackettext] ["FE3B5] %D Some bonus ones (for the moment here): diff --git a/tex/context/base/mkiv/math-vfu.lua b/tex/context/base/mkiv/math-vfu.lua index ed6f69f41..9090955e9 100644 --- a/tex/context/base/mkiv/math-vfu.lua +++ b/tex/context/base/mkiv/math-vfu.lua @@ -1106,13 +1106,16 @@ function vfmath.define(specification,set,goodies) end end -- + main.mathparameters = mathparameters -- still traditional ones + -- This should change (some day) as it's the only place where we look forward, + -- so better is to also reserve the id already which then involves some more + -- management (so not now). fontlist[#fontlist+1] = { id = font.nextid(), size = size, } - -- - main.mathparameters = mathparameters -- still traditional ones vfmath.addmissing(main,#fontlist,size) + -- mathematics.addfallbacks(main) -- main.properties.math_is_scaled = true -- signal diff --git a/tex/context/base/mkiv/meta-fnt.lua b/tex/context/base/mkiv/meta-fnt.lua index 69212d08c..92bbe0716 100644 --- a/tex/context/base/mkiv/meta-fnt.lua +++ b/tex/context/base/mkiv/meta-fnt.lua @@ -167,8 +167,8 @@ local function build(g,v) local t = { } for d=1,#data do t = fonts.constructors.scale(data[d],-1000) - local id = font.nextid() - t.fonts = { { id = id } } + -- local id = font.nextid() + -- t.fonts = { { id = id } } fontdata[id] = t if v[5] then vffonts.helpers.composecharacters(t) diff --git a/tex/context/base/mkiv/mlib-pdf.lua b/tex/context/base/mkiv/mlib-pdf.lua index 4f183eed3..ded3a1841 100644 --- a/tex/context/base/mkiv/mlib-pdf.lua +++ b/tex/context/base/mkiv/mlib-pdf.lua @@ -498,9 +498,9 @@ miterlimit, linecap, linejoin, dashed, linewidth = -1, -1, -1, "", false elseif objecttype == "stop_group" then local data = remove(groupstack) if data then - local id = lpdf.flushgroup(concat(result,"\r"),data.bbox) + local reference = lpdf.flushgroup(concat(result,"\r"),data.bbox) result = data.result - result[#result+1] = formatters["/%s Do"](id) + result[#result+1] = reference result = pluginactions(data.after,result,flushfigure) result[#result+1] = "Q" miterlimit, linecap, linejoin, dashed, linewidth = -1, -1, -1, "", false diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index 3c6ccceaf..2cd47f5a6 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -9685,6 +9685,10 @@ return { ["pageleft"]={ ["en"]="pageleft", }, + ["pagemethod"]={ + ["en"]="pagemethod", + ["nl"]="paginamethode", + }, ["pagenumber"]={ ["cs"]="cislostranky", ["de"]="seitennummer", diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index 5f2940f45..b328f925d 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -557,15 +557,21 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, if a and attrib ~= a and nslistwise[a] then -- viewerlayer head = insert_node_before(head,current,copy_node(nsdata[a])) list = stacker(attribute,content,a) + if list ~= content then + setlist(current,list) + end head, current = insert_node_after(head,current,copy_node(nsnone)) else - list = stacker(attribute,content,attrib) + list = stacker(attribute,content,a) + if list ~= content then + setlist(current,list) + end end else list = stacker(attribute,content,default) - end - if list ~= content then - setlist(current,list) + if list ~= content then + setlist(current,list) + end end end elseif id == rule_code then @@ -618,89 +624,6 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, return head end --- local nextid = nodes.nuts.traversers.id --- --- local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise --- --- -- nsbegin() --- local stacked = false --- --- local current = head --- local previous = head --- local attrib = default or unsetvalue --- local check = false --- local leader = false --- --- local id = getid(current) --- while current do --- if id == glyph_code then --- check = true --- elseif id == glue_code then --- leader = getleader(current) --- if leader then --- check = true --- end --- elseif id == hlist_code or id == vlist_code then --- local content = getlist(current) --- if content then --- local list --- if nslistwise then --- local a = getattr(current,attribute) --- if a and attrib ~= a and nslistwise[a] then -- viewerlayer --- head = insert_node_before(head,current,copy_node(nsdata[a])) --- list = stacker(attribute,content,a) --- head, current = insert_node_after(head,current,copy_node(nsnone)) --- else --- list = stacker(attribute,content,attrib) --- end --- else --- list = stacker(attribute,content,default) --- end --- if list ~= content then --- setlist(current,list) --- end --- end --- elseif id == rule_code then --- check = getwidth(current) ~= 0 --- end --- --- if check then --- local a = getattr(current,attribute) or unsetvalue --- if a ~= attrib then --- if not stacked then --- stacked = true --- nsbegin() --- end --- local n = nsstep(a) --- if n then --- head = insert_node_before(head,current,n) -- a --- end --- attrib = a --- if leader then --- -- tricky as a leader has to be a list so we cannot inject before --- local list = stacker(attribute,leader,attrib) --- leader = false --- end --- end --- check = false --- end --- --- previous = current --- --- current, id = nextid(current,current) --- end --- --- if stacked then --- local n = nsend() --- while n do --- head = insert_node_after(head,previous,n) --- n = nsend() --- end --- end --- --- return head --- end - states.stacker = function(namespace,attribute,head,default) local head = stacker(attribute,head,default) nsreset() diff --git a/tex/context/base/mkiv/page-cst.mkiv b/tex/context/base/mkiv/page-cst.mkiv index 1c89f3443..6ce10a882 100644 --- a/tex/context/base/mkiv/page-cst.mkiv +++ b/tex/context/base/mkiv/page-cst.mkiv @@ -302,9 +302,9 @@ % todo line numbers and marks \unexpanded\def\page_grd_command_flush_page_column#1% - {\privatescratchcounter#1\relax + {\privatescratchcounter#1\relax % or just currentcolumn as in page-col.mkiv \clf_flushcolumnsetcolumn{\currentpagegrid}\privatescratchcounter - \anch_mark_column_box\b_page_grd_column + \anch_mark_column_box\b_page_grd_column\privatescratchcounter \page_marks_synchronize_column\c_page_grd_first_column\c_page_grd_last_column\privatescratchcounter\b_page_grd_column \ifnum\privatescratchcounter>\c_page_grd_n_of_left \advance\privatescratchcounter-\c_page_grd_n_of_left diff --git a/tex/context/base/mkiv/page-imp.mkiv b/tex/context/base/mkiv/page-imp.mkiv index b65f8991a..a7ef6ca38 100644 --- a/tex/context/base/mkiv/page-imp.mkiv +++ b/tex/context/base/mkiv/page-imp.mkiv @@ -210,6 +210,10 @@ \page_shipouts_ignore{#1}% \fi} +\newconditional\c_page_shipouts_use_objects \settrue\c_page_shipouts_use_objects + +\installcorenamespace {arrangedpage} + \def\page_shipouts_arrange#1% {\begingroup \setbox\shipoutscratchbox\hpack @@ -218,6 +222,12 @@ {\page_otr_flush_every_stuff \page_otr_flush_special_content \box\shipoutscratchbox}% + % + \ifconditional\c_page_shipouts_use_objects + \setobject\??arrangedpage{\the\realpageno}\hpack{\box\shipoutscratchbox}% + \setbox\shipoutscratchbox\hpack{\getobject\??arrangedpage{\the\realpageno}}% + \fi + % \pusharrangedpage\shipoutscratchbox \deadcycles\zerocount \endgroup} @@ -317,8 +327,10 @@ \fi \setuppapersize \ifarrangingpages - \clf_disablejobsave - %\disabledirective[job.save]% + \ifconditional\c_page_shipouts_use_objects\else + \clf_disablejobsave + %\disabledirective[job.save]% + \fi \fi \fi} @@ -421,6 +433,7 @@ \def\outputarrangedbox#1% {\begingroup \forgetall % somehow we're back and need to redo this + \dontcomplain \gotonextarrangepage \ifnum\arrangedrotationO\arrangedrotationE>\zerocount \setbox#1\vpack diff --git a/tex/context/base/mkiv/page-mix.mkiv b/tex/context/base/mkiv/page-mix.mkiv index e3ed47835..f54b8ec71 100644 --- a/tex/context/base/mkiv/page-mix.mkiv +++ b/tex/context/base/mkiv/page-mix.mkiv @@ -710,7 +710,7 @@ \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_mix_n_of_columns\plusone % new \page_marks_synchronize_column\plusone\c_page_mix_n_of_columns\recurselevel\scratchbox % backgrounds - \anch_mark_column_box\scratchbox + \anch_mark_column_box\scratchbox\recurselevel % for the moment a quick and dirty patch .. we need to go into the box (hence the \plusone) .. a slowdowner % moved to start: \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_mix_n_of_columns\plusone % the framed needs a reset of strut, align, setups etc diff --git a/tex/context/base/mkiv/page-mul.mkiv b/tex/context/base/mkiv/page-mul.mkiv index 69e8fcdaa..f1d68827a 100644 --- a/tex/context/base/mkiv/page-mul.mkiv +++ b/tex/context/base/mkiv/page-mul.mkiv @@ -487,7 +487,7 @@ {\setbox\scratchbox\hpack {\ifx\finishcolumnbox\relax\else\strut\fi \box\currentcolumnbox}% hm, why strut - \anch_mark_column_box\scratchbox + \anch_mark_column_box\scratchbox\currentcolumn \box\scratchbox}% \hfil}% \unskip diff --git a/tex/context/base/mkiv/page-pcl.mkiv b/tex/context/base/mkiv/page-pcl.mkiv index 61c542e1c..09368c537 100644 --- a/tex/context/base/mkiv/page-pcl.mkiv +++ b/tex/context/base/mkiv/page-pcl.mkiv @@ -246,7 +246,7 @@ \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_col_n_of_columns\plusone % new \page_marks_synchronize_column\plusone\c_page_col_n_of_columns\recurselevel\scratchbox % backgrounds - \anch_mark_column_box\scratchbox + \anch_mark_column_box\scratchbox\recurselevel \mixedcolumnseparatorheight\ht\scratchbox \mixedcolumnseparatordepth \dp\scratchbox \inheritedpagecolumnsframedbox\recurselevel\scratchbox} diff --git a/tex/context/base/mkiv/page-str.lua b/tex/context/base/mkiv/page-str.lua index ebb49a918..73f1782d0 100644 --- a/tex/context/base/mkiv/page-str.lua +++ b/tex/context/base/mkiv/page-str.lua @@ -177,19 +177,21 @@ function streams.synchronize(list) -- this is an experiment ! for i=1,#list do local name = list[i] local dana = data[name] - local slot = dana[m] - if slot then - local vbox = vpack_node_list(slot) - local wd, ht, dp = getwhd(vbox) - if ht > height then - height = ht - end - if dp > depth then - depth = dp - end - dana[m] = vbox - if trace_flushing then - report_streams("slot %s of %a is packed to height %p and depth %p",m,name,ht,dp) + if dana then + local slot = dana[m] + if slot then + local vbox = vpack_node_list(slot) + local wd, ht, dp = getwhd(vbox) + if ht > height then + height = ht + end + if dp > depth then + depth = dp + end + dana[m] = vbox + if trace_flushing then + report_streams("slot %s of %a is packed to height %p and depth %p",m,name,ht,dp) + end end end end @@ -202,41 +204,43 @@ function streams.synchronize(list) -- this is an experiment ! for i=1,#list do local name = list[i] local dana = data[name] - local vbox = dana[m] - if vbox then - local wd, ht, dp = getwhd(vbox) - local delta_height = height - ht - local delta_depth = depth - dp - if delta_height > 0 or delta_depth > 0 then - if false then - -- actually we need to add glue and repack - setwhd(vbox,false,height,depth) - if trace_flushing then - report_streams("slot %s of %a with delta (%p,%p) is compensated",m,i,delta_height,delta_depth) - end - else - -- this is not yet ok as we also need to keep an eye on vertical spacing - -- so we might need to do some splitting or whatever - local list = getlist(vbox) - local tail = list and slide_node_list(list) - local n = 0 - local delta = delta_height -- for tracing - while delta > 0 do - -- we need to add some interline penalties - local line = copy_node_list(getbox("strutbox")) - setwhd(line,false,strutht,strutdp) - if tail then - setlink(tail,line) + if dana then + local vbox = dana[m] + if vbox then + local wd, ht, dp = getwhd(vbox) + local delta_height = height - ht + local delta_depth = depth - dp + if delta_height > 0 or delta_depth > 0 then + if false then + -- actually we need to add glue and repack + setwhd(vbox,false,height,depth) + if trace_flushing then + report_streams("slot %s of %a with delta (%p,%p) is compensated",m,i,delta_height,delta_depth) + end + else + -- this is not yet ok as we also need to keep an eye on vertical spacing + -- so we might need to do some splitting or whatever + local list = getlist(vbox) + local tail = list and slide_node_list(list) + local n = 0 + local delta = delta_height -- for tracing + while delta > 0 do + -- we need to add some interline penalties + local line = copy_node_list(getbox("strutbox")) + setwhd(line,false,strutht,strutdp) + if tail then + setlink(tail,line) + end + tail = line + n = n + 1 + delta = delta - struthtdp + end + dana[m] = vpack_node_list(getlist(vbox)) + setlist(vbox) + flush_node(vbox) + if trace_flushing then + report_streams("slot %s:%s with delta (%p,%p) is compensated by %s lines",m,i,delta_height,delta_depth,n) end - tail = line - n = n + 1 - delta = delta - struthtdp - end - dana[m] = vpack_node_list(getlist(vbox)) - setlist(vbox) - flush_node(vbox) - if trace_flushing then - report_streams("slot %s:%s with delta (%p,%p) is compensated by %s lines",m,i,delta_height,delta_depth,n) end end end diff --git a/tex/context/base/mkiv/phys-dim.mkiv b/tex/context/base/mkiv/phys-dim.mkiv index 3ea042b05..1eb1f37f7 100644 --- a/tex/context/base/mkiv/phys-dim.mkiv +++ b/tex/context/base/mkiv/phys-dim.mkiv @@ -441,6 +441,7 @@ \appendtoks \disablemathpunctuation + \nocharacteralign \to \everyunits \appendtoks @@ -449,6 +450,7 @@ \unexpanded\def\phys_units_direct#1% {\begingroup + \the\everyunits \ifdim\lastskip>\zeropoint \settrue\c_phys_units_dospace \removelastskip @@ -459,7 +461,7 @@ \edef\unitlanguage{\unitparameter\s!language}% \let\prefixlanguage\unitlanguage \let\operatorlanguage\unitlanguage - \the\everyunits +% \the\everyunits %\removeunwantedspaces % not ok yet \useunitstyleandcolor\c!style\c!color \edef\currentunitsalternative{\unitparameter\c!alternative}% diff --git a/tex/context/base/mkiv/regi-ini.lua b/tex/context/base/mkiv/regi-ini.lua index 4b2412ee8..8d4f2bfd5 100644 --- a/tex/context/base/mkiv/regi-ini.lua +++ b/tex/context/base/mkiv/regi-ini.lua @@ -472,17 +472,17 @@ end -- Actually we can have a function returned from the lookup but we don't -- really use this code so I'm in no hurry. -if lua.getcodepage then - local cod, acp, map - function os.tocodepage(name) - if map == nil then - cod, acp = lua.getcodepage() - map = cod and cod ~= 65001 and regimes.toregime - end - return map and map(cod,name) or name - end -else - function os.tocodepage(name) - return name - end -end +-- if os.getcodepage then +-- local cod, acp, map +-- function os.tocodepage(name) +-- if map == nil then +-- cod, acp = os.getcodepage() +-- map = cod and cod ~= 65001 and regimes.toregime +-- end +-- return map and map(cod,name) or name +-- end +-- else +-- function os.tocodepage(name) +-- return name +-- end +-- end diff --git a/tex/context/base/mkiv/regi-ini.mkiv b/tex/context/base/mkiv/regi-ini.mkiv index fcdc2536f..0cd9cf89d 100644 --- a/tex/context/base/mkiv/regi-ini.mkiv +++ b/tex/context/base/mkiv/regi-ini.mkiv @@ -32,6 +32,6 @@ % only for diagnostics: -\def\codepagename#1{\cldcontext{os.tocodepage("#1")}} +% \def\codepagename#1{\cldcontext{os.tocodepage("#1")}} \protect \endinput diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differdeleted file mode 100644 index 2d27af210..000000000 --- a/tex/context/base/mkiv/status-files.pdf +++ /dev/null diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differdeleted file mode 100644 index 15622145c..000000000 --- a/tex/context/base/mkiv/status-lua.pdf +++ /dev/null diff --git a/tex/context/base/mkiv/strc-pag.lua b/tex/context/base/mkiv/strc-pag.lua index 216b5f705..d0c9d50ae 100644 --- a/tex/context/base/mkiv/strc-pag.lua +++ b/tex/context/base/mkiv/strc-pag.lua @@ -183,18 +183,18 @@ function pages.analyze(entry,pagespecification) if not sectiondata then return pagedata, false, "no sectiondata" end - local no = variables.no + local v_no = variables.no -- local preferences - if pagespecification and pagespecification.prefix == no then + if pagespecification and pagespecification.prefix == v_no then return pagedata, false, "current spec blocks prefix" end -- stored preferences - -- if entry.prefix == no then + -- if entry.prefix == v_no then -- return pagedata, false, "entry blocks prefix" -- end -- stored page state pagespecification = pagedata.prefixdata - if pagespecification and pagespecification.prefix == no then + if pagespecification and pagespecification.prefix == v_no then return pagedata, false, "pagedata blocks prefix" end -- final verdict @@ -269,11 +269,20 @@ function helpers.analyze(entry,specification) return entry, sectiondata, "okay" end -function helpers.prefix(data,prefixspec) +function helpers.prefix(data,prefixspec,nosuffix) if data then local _, prefixdata, status = helpers.analyze(data,prefixspec) - if prefixdata then - sections.typesetnumber(prefixdata,"prefix",prefixspec or false,data.prefixdata or false,prefixdata or false) + if not prefixdata then + -- nothing to do + elseif not prefixspec then + sections.typesetnumber(prefixdata,"prefix",false,prefixdata,false) + elseif nosuffix then + local connector = prefixspec.connector + prefixspec.connector = nil + sections.typesetnumber(prefixdata,"prefix",prefixspec,prefixdata,prefixdata) + prefixspec.connector = connector + else + sections.typesetnumber(prefixdata,"prefix",prefixspec,prefixdata,prefixdata) end end end diff --git a/tex/context/base/mkiv/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua index a4f31ec0c..da2d50120 100644 --- a/tex/context/base/mkiv/strc-ref.lua +++ b/tex/context/base/mkiv/strc-ref.lua @@ -2615,8 +2615,8 @@ implement { -- } implement { - name = "referencerealpage", - actions = function() + name = "referencerealpage", + actions = function() local actions = references.currentset context(not actions and 0 or actions.realpage or setreferencerealpage(actions)) end @@ -2632,11 +2632,24 @@ local function referencepos(key) v = a[key] or 0 end end - context("%p",v) + return v end -implement { name = "referenceposx", actions = function() referencepos("x") end } -implement { name = "referenceposy", actions = function() referencepos("y") end } +implement { name = "referenceposx", actions = function() context("%p",referencepos("x")) end } +implement { name = "referenceposy", actions = function() context("%p",referencepos("y")) end } + + +implement { + name = "referencecolumn", + actions = function() + local actions = references.currentset + local column = 1 + if actions then + column = jobpositions.columnofpos(actions.realpage or setreferencerealpage(actions),referencepos("x")) + end + context(column or 1) + end +} local plist, nofrealpages diff --git a/tex/context/base/mkiv/strc-ref.mkvi b/tex/context/base/mkiv/strc-ref.mkvi index cfe8744e2..9fa04c9a6 100644 --- a/tex/context/base/mkiv/strc-ref.mkvi +++ b/tex/context/base/mkiv/strc-ref.mkvi @@ -1062,20 +1062,8 @@ \def\referencerealpage {\clf_referencerealpage} -% \unexpanded\def\columnreference#1% -% {\dontleavehmode -% \hpack to \zeropoint{\hpos{\v!column:#1}{\kern\dimexpr\textwidth/\nofcolumns\relax}\hss}} -% -% \def\columnnumber#1% -% {\numexpr\dimexpr\MPx{\v!column:#1}\relax/\dimexpr\MPw{\v!column:#1}\relax\relax} -% -% but nicer is: - \def\referencecolumnnumber - {\numexpr - \dimexpr\clf_referenceposx-\cutspace\relax/\dimexpr\makeupwidth/\nofcolumns\relax - +\plusone - \relax} + {\clf_referencecolumn} \unexpanded\def\tracedpagestate {{\blue\tttf(\ifcase\referencepagedetail unknown\or same\or previous\or next\or above\or below\else unknown\fi)}} diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua index 88b738b6d..5e444de4b 100644 --- a/tex/context/base/mkiv/strc-reg.lua +++ b/tex/context/base/mkiv/strc-reg.lua @@ -46,6 +46,7 @@ local v_previous = variables.previous local v_first = variables.first local v_last = variables.last local v_text = variables.text +local v_section = variables.section local context = context local ctx_latelua = context.latelua @@ -69,6 +70,7 @@ local absmaxlevel = 5 -- \c_strc_registers_maxlevel local h_prefixpage = helpers.prefixpage local h_prefixlastpage = helpers.prefixlastpage local h_title = helpers.title +local h_prefix = helpers.prefix local ctx_startregisteroutput = context.startregisteroutput local ctx_stopregisteroutput = context.stopregisteroutput @@ -87,7 +89,7 @@ local ctx_registerentry = context.registerentry local ctx_registerseeword = context.registerseeword local ctx_registerpagerange = context.registerpagerange local ctx_registeronepage = context.registeronepage - +local ctx_registersection = context.registersection local ctx_registerpacked = context.registerpacked -- possible export, but ugly code (overloads) @@ -932,6 +934,7 @@ function registers.unique(data,options) local nofresult = 0 local prev = nil local dataresult = data.result + local bysection = options.pagemethod == v_section -- normally page for k=1,#dataresult do local v = dataresult[k] if prev then @@ -939,6 +942,9 @@ function registers.unique(data,options) local pr = prev.references if not equal(prev.list,v.list) then -- ok + elseif bysection and vr.section == pr.section then + v = nil + -- ok elseif pr.realpage ~= vr.realpage then -- ok else @@ -1202,6 +1208,7 @@ function registers.flush(data,options,prefixspec,pagespec) local collapse_ranges = compress == v_all local collapse_packed = compress == v_packed local show_page_number = options.pagenumber ~= false -- true or false + local bysection = options.pagemethod == v_section local result = data.result local maxlevel = 0 -- @@ -1452,14 +1459,61 @@ function registers.flush(data,options,prefixspec,pagespec) local seetext = seeword.text or "" local processor = seeword.processor or (entry.processors and entry.processors[1]) or "" local seeindex = entry.references.seeindex or "" - ctx_registerseeword(metadata.name or "",i,nt,processor,0,seeindex,function() h_title(seetext,metadata) end) + ctx_registerseeword( + metadata.name or "", + i, + nt, + processor, + 0, + seeindex, + function() h_title(seetext,metadata) end + ) + end + end + + local function case_5() + local first = d + while true do + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next + end + end + end + local last = d + local n = last - first + 1 + local i = 0 + local name = metadata.name or "" + local processor = entry.processors and entry.processors[1] or "" + for e=first,last do + local d = data[e] + local sectionindex = d.references.internal or 0 + i = i + 1 + ctx_registersection( + name, + i, + n, + processor, + 0, + sectionindex, + function() h_prefix(d,prefixspec,true) end + ) end end if kind == "entry" then if show_page_number then ctx_startregisterpages() - if collapse_singles or collapse_ranges then + if bysection then + case_5() + elseif collapse_singles or collapse_ranges then case_1() elseif collapse_packed then case_2() @@ -1517,6 +1571,7 @@ implement { { "compress" }, { "criterium" }, { "check" }, + { "pagemethod" }, { "pagenumber", "boolean" }, }, { diff --git a/tex/context/base/mkiv/strc-reg.mkiv b/tex/context/base/mkiv/strc-reg.mkiv index ae247d9bd..e955c700b 100644 --- a/tex/context/base/mkiv/strc-reg.mkiv +++ b/tex/context/base/mkiv/strc-reg.mkiv @@ -633,13 +633,14 @@ \clf_processregister {#1}% {% - language {\registerparameter\s!language}% - method {\registerparameter\c!method}% - numberorder {\registerparameter\c!numberorder}% - check {\registerparameter\c!check}% - compress {\registerparameter\c!compress}% - criterium {\registerparameter\c!criterium}% - pagenumber \ifx\registerpageseparatorsymbol\empty false\else true\fi + language {\registerparameter\s!language}% + method {\registerparameter\c!method}% + numberorder {\registerparameter\c!numberorder}% + check {\registerparameter\c!check}% + compress {\registerparameter\c!compress}% + criterium {\registerparameter\c!criterium}% + pagemethod {\registerparameter\c!pagemethod}% + pagenumber \ifx\registerpageseparatorsymbol\empty false\else true\fi }{% separatorset {\registerparameter\c!pageprefixseparatorset}% conversionset {\registerparameter\c!pageprefixconversionset}% @@ -1040,10 +1041,66 @@ \dostoptagged \popcurrentregister} +\unexpanded\def\doapplyregistersectioncommand#1#2% + {\ifx\currentregistersectionindex\empty + \applyprocessor{#1}{#2}% + \else\iflocation + \strc_references_goto_internal{\applyprocessor{#1}{#2}}[sectionindex:\currentregistersectionindex]% + \else + \applyprocessor{#1}{#2}% + \fi\fi} + +\unexpanded\def\defaultregistersection#1#2#3#4#5#6#7% class i n #4:processor #5:internal #6:sectionindex #7:word + {\pushcurrentregister{#1}% + \ifnum#2=\plusone + \registerpageseparator + \fi + \global\setconstant\c_strc_registers_page_state\plustwo + \def\currentregisterpageindex{#5}% + \dostarttagged\t!registersection\empty + \settrue\c_strc_registers_page_done + \iflocation + \def\currentregistersectionindex{#6}% + \else + \let\currentregistersectionindex\empty + \fi + \ifnum#2=\plusone\else + ,\space + \fi + \doapplyregistersectioncommand{#4}{#7}% + \dostoptagged + \popcurrentregister} + +\let\registersection \defaultregistersection \let\registerseeword \defaultregisterseeword \let\registerentry \defaultregisterentry \let\registercharacter\defaultregistercharacter +%D Experimental: +%D +%D \starttyping +%D \setupregister +%D [index] +%D [pagesegments=1:4, +%D pagemethod=section] +%D +%D \starttext +%D +%D \chapter {one} \section {alpha} +%D +%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page +%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page +%D +%D \chapter {one} \section {alpha} +%D +%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page +%D x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page +%D +%D \placeindex[n=1] +%D +%D \stoptext +%D \stoptyping + %D A few specific rendering variants: % \def\doregisterpagelocation#1#2% diff --git a/tex/context/base/mkiv/strc-tag.mkiv b/tex/context/base/mkiv/strc-tag.mkiv index 021245f29..83ee03090 100644 --- a/tex/context/base/mkiv/strc-tag.mkiv +++ b/tex/context/base/mkiv/strc-tag.mkiv @@ -73,6 +73,7 @@ \def\t!registerentry {registerentry} % Span \def\t!registercontent {registercontent} % Span \def\t!registersee {registersee} % Span +\def\t!registersection {registersection} % Span \def\t!registerpages {registerpages} % Span \def\t!registerpage {registerpage} % Span \def\t!registerpagerange {registerpagerange} % Span diff --git a/tex/context/base/mkiv/supp-box.lua b/tex/context/base/mkiv/supp-box.lua index a8599cffe..e547c8710 100644 --- a/tex/context/base/mkiv/supp-box.lua +++ b/tex/context/base/mkiv/supp-box.lua @@ -712,7 +712,7 @@ local function stripglue(list) return list, done end -local function limitate(t) +local function limitate(t) -- don't pack the result ! local text = t.text if text then text = tonut(text) @@ -729,8 +729,8 @@ local function limitate(t) else return tonode(text) end - local list = getlist(text) local width = getwidth(text) + local list = getlist(text) local done = false if t.strip then list, done = stripglue(list) @@ -745,72 +745,66 @@ local function limitate(t) end local left = t.left or 0 local right = t.right or 0 - if left + right >= width then - if done then - setwidth(text,width) - end - return tonode(text) - end - local last = nil - local first = nil - local maxleft = left - local maxright = right - local swidth = getwidth(sentinel) - if maxright > 0 then - maxleft = maxleft - swidth/2 - maxright = maxright - swidth/2 - else - maxleft = maxleft - swidth - end - for n in traverse_id(glue_code,list) do - local width = getdimensions(list,n) - if width > maxleft then - if not last then - last = n - end - break + if left + right < width then + local last = nil + local first = nil + local maxleft = left + local maxright = right + local swidth = getwidth(sentinel) + if maxright > 0 then + maxleft = maxleft - swidth/2 + maxright = maxright - swidth/2 else - last = n + maxleft = maxleft - swidth end - end - if last and maxright > 0 then - for n in traverse_id(glue_code,last) do - local width = getdimensions(n) - if width < maxright then - first = n + for n in traverse_id(glue_code,list) do + local width = getdimensions(list,n) + if width > maxleft then + if not last then + last = n + end break else - first = n + last = n end end - end - if last then - local rest = getnext(last) - if rest then - local tail = findtail(sentinel) - if first and getid(first) == glue_code and getid(tail) == glue_code then - setwidth(first,0) - end - if last and getid(last) == glue_code and getid(sentinel) == glue_code then - setwidth(last,0) + if last and maxright > 0 then + for n in traverse_id(glue_code,last) do + local width = getdimensions(n) + if width < maxright then + first = n + break + else + first = n + end end - if first and first ~= last then - local prev = getprev(first) - if prev then - setnext(prev) + end + if last then + local rest = getnext(last) + if rest then + local tail = findtail(sentinel) + if first and getid(first) == glue_code and getid(tail) == glue_code then + setwidth(first,0) + end + if last and getid(last) == glue_code and getid(sentinel) == glue_code then + setwidth(last,0) + end + if first and first ~= last then + local prev = getprev(first) + if prev then + setnext(prev) + end + setlink(tail,first) end - setlink(tail,first) + setlink(last,sentinel) + setprev(rest) + flush_list(rest) end - setlink(last,sentinel) - setprev(rest) - flush_list(rest) end end - local result = hpack(list) - setattrlist(result,text) setlist(text) free(text) - return tonode(result) + return tonode(list) end implement { diff --git a/tex/context/base/mkiv/trac-log.lua b/tex/context/base/mkiv/trac-log.lua index b35e53f2e..be6fff488 100644 --- a/tex/context/base/mkiv/trac-log.lua +++ b/tex/context/base/mkiv/trac-log.lua @@ -114,20 +114,34 @@ local direct, subdirect, writer, pushtarget, poptarget, setlogfile, settimedlog, -- we don't want this overhead for single messages (not that there are that -- many; we could have a special weak table) +local function ansisupported(specification) + if specification ~= "ansi" and specification ~= "ansilog" then + return false + elseif os and os.enableansi then + return os.enableansi() + else + return false + end +end + if runningtex and texio then if texio.setescape then texio.setescape(0) -- or (false) end - if arg then + if arg and ansisupported then -- we're don't have environment.arguments yet for k, v in next, arg do -- k can be negative ! if v == "--ansi" or v == "--c:ansi" then - variant = "ansi" + if ansisupported("ansi") then + variant = "ansi" + end break elseif v == "--ansilog" or v == "--c:ansilog" then - variant = "ansilog" + if ansisupported("ansilog") then + variant = "ansilog" + end break end end @@ -376,6 +390,9 @@ if runningtex and texio then t = specification.targets f = specification.formats or specification else + if not ansisupported(specification) then + specification = "default" + end local v = variants[specification] if v then t = v.targets @@ -519,6 +536,9 @@ else if type(specification) == "table" then f = specification.formats or specification else + if not ansisupported(specification) then + specification = "default" + end local v = variants[specification] if v then f = v.formats @@ -954,6 +974,15 @@ logs.reporters = reporters logs.exporters = exporters function logs.application(t) + -- + local arguments = environment and environment.arguments + if arguments then + local ansi = arguments.ansi or arguments.ansilog + if ansi then + logs.setformatters(arguments.ansi and "ansi" or "ansilog") + end + end + -- t.name = t.name or "unknown" t.banner = t.banner t.moreinfo = moreinfo diff --git a/tex/context/base/mkiv/typo-tal.lua b/tex/context/base/mkiv/typo-tal.lua index 8cf298329..ff10fb121 100644 --- a/tex/context/base/mkiv/typo-tal.lua +++ b/tex/context/base/mkiv/typo-tal.lua @@ -205,6 +205,24 @@ function characteralign.handler(head,where) local method = dataset.method -- we can think of constraints if method == v_number then + + local function bothdigit(current) -- this could become a helper + local prev, next = getboth(current) + if next and prev and getid(next) == glyph_code and getid(prev) == glyph_code then + local pchar = getchar(prev) + local nchar = getchar(next) + local pdata = fontcharacters[getfont(prev)][pchar] + local ndata = fontcharacters[getfont(next)][nchar] + local punicode = pdata and pdata.unicode or pchar -- we ignore tables + local nunicode = ndata and ndata.unicode or nchar -- we ignore tables + if punicode and nunicode and categories[punicode] == "nd" and categories[nunicode] == "nd" then + return true + else + return false + end + end + end + while current do local char, id = isglyph(current) if char then @@ -266,10 +284,9 @@ function characteralign.handler(head,where) elseif (b_start or a_start) and id == glue_code then -- maybe only in number mode -- somewhat inefficient - local prev, next = getboth(current) - if next and prev and getid(next) == glyph_code and getid(prev) == glyph_code then -- too much checking + if bothdigit(current) then local width = fontcharacters[getfont(b_start or a_start)][separator or period].width - setglue(current,width) + setglue(current,width,0,0) setattr(current,a_character,punctuationspace) if a_start then a_stop = current diff --git a/tex/context/base/mkiv/typo-tal.mkiv b/tex/context/base/mkiv/typo-tal.mkiv index 7170578d1..33e071e75 100644 --- a/tex/context/base/mkiv/typo-tal.mkiv +++ b/tex/context/base/mkiv/typo-tal.mkiv @@ -269,4 +269,38 @@ \typo_charalign_adapt_font_indeed \fi} +%D Another example: +%D +%D \starttyping +%D \setupTABLE[c][2][alignmentcharacter={number->,},aligncharacter=yes,align={flushleft}] +%D \bTABLE +%D \bTR \bTD 1 \eTD \bTD 125 cm \eTD \eTR +%D \bTR \bTD 2 \eTD \bTD 1 125,80 cm \eTD \eTR +%D \bTR \bTD 6 \eTD \bTD 1 125,80 $\pi^2$ \eTD \eTR +%D \bTR \bTD 7 \eTD \bTD 129,3 \unit{square centimeter} \eTD \eTR +%D \eTABLE +%D +%D \setupTABLE[c][2][alignmentcharacter={number->,},aligncharacter=yes,align={flushleft}] +%D \bTABLE +%D \bTR \bTD 1 \eTD \bTD 125 cm \eTD \eTR +%D \bTR \bTD 2 \eTD \bTD 1 125,80 cm \eTD \eTR +%D \bTR \bTD 6 \eTD \bTD 1 125,80 $\pi^2$ \eTD \eTR +%D \bTR \bTD 7 \eTD \bTD 129,3 \unit{square centimeter} \eTD \eTR +%D \eTABLE +%D +%D \setupTABLE[c][2][alignmentcharacter={number->,},aligncharacter=yes,align={middle}] +%D \bTABLE +%D \bTR \bTD 1 \eTD \bTD 125 \eTD \eTR +%D \bTR \bTD 6 \eTD \bTD 1 125,80 \eTD \eTR +%D \bTR \bTD 7 \eTD \bTD 129,3 \eTD \eTR +%D \eTABLE +%D +%D \setupTABLE[c][2][alignmentcharacter={text->,},aligncharacter=yes,align={middle}] +%D \bTABLE +%D \bTR \bTD 1 \eTD \bTD 125 \eTD \eTR +%D \bTR \bTD 6 \eTD \bTD 1 125,80 \eTD \eTR +%D \bTR \bTD 7 \eTD \bTD 129,3 \eTD \eTR +%D \eTABLE +%D \stoptyping + \protect \endinput diff --git a/tex/context/base/mkiv/util-sbx.lua b/tex/context/base/mkiv/util-sbx.lua index 196c816d0..c3df27122 100644 --- a/tex/context/base/mkiv/util-sbx.lua +++ b/tex/context/base/mkiv/util-sbx.lua @@ -241,6 +241,10 @@ table.setmetatableindex(validators,function(t,k) return readable end) +-- function validators.verbose(s) +-- return s +-- end + function validators.string(s,finalized) -- can be used to prevent filename checking (todo: only when registered) if finalized and suspicious(s) then @@ -320,37 +324,53 @@ local function validcommand(name,program,template,checkers,defaults,variables,re if validbinaries ~= false and (validbinaries == true or validbinaries[program]) then if variables then for variable, value in next, variables do - local checker = validators[checkers[variable]] - if checker then - value = checker(unquoted(value),strict) - if value then - variables[variable] = optionalquoted(value) + local chktype = checkers[variable] + if chktype == "verbose" then + -- for now, we will have a "flags" checker + else + local checker = validators[chktype] + if checker then + value = checker(unquoted(value),strict) + if value then + variables[variable] = optionalquoted(value) + else + report("variable %a with value %a fails the check",variable,value) + return + end else - report("variable %a with value %a fails the check",variable,value) + report("variable %a has no checker",variable) return end - else - report("variable %a has no checker",variable) - return end end for variable, default in next, defaults do local value = variables[variable] if not value or value == "" then - local checker = validators[checkers[variable]] - if checker then - default = checker(unquoted(default),strict) - if default then - variables[variable] = optionalquoted(default) - else - report("variable %a with default %a fails the check",variable,default) - return + local chktype = checkers[variable] + if chktype == "verbose" then + -- for now, we will have a "flags" checker + else + local checker = validators[chktype] + if checker then + default = checker(unquoted(default),strict) + if default then + variables[variable] = optionalquoted(default) + else + report("variable %a with default %a fails the check",variable,default) + return + end end end end end end - local command = program .. " " .. replace(template,variables) + local binpath = variables.binarypath + if type(binpath) == "string" and binpath ~= "" then + -- this works on the console but not from e.g. scite + -- program = '"' .. binpath .. "/" .. program .. '"' + program = binpath .. "/" .. program + end + local command = program .. " " .. replace(template,variables) if reporter then reporter("executing runner %a: %s",name,command) elseif trace then @@ -387,7 +407,8 @@ local runners = { if trace then report("execute: %s",command) end - return osexecute(command) + local okay = osexecute(command) + return okay end end, pipeto = function(...) @@ -422,7 +443,7 @@ function sandbox.registerrunner(specification) return end if validrunners[name] then - report("invalid name, runner %a already defined") + report("invalid name, runner %a already defined",name) return end local program = specification.program diff --git a/tex/context/base/mkiv/util-sta.lua b/tex/context/base/mkiv/util-sta.lua index 7819395f6..9ca1c67e9 100644 --- a/tex/context/base/mkiv/util-sta.lua +++ b/tex/context/base/mkiv/util-sta.lua @@ -81,6 +81,8 @@ end function stacker.new(name) + -- to be sped up, mmaybe foo:bar syntax here but then quite some access + local report = logs.reporter("stacker",name or nil) local s @@ -93,6 +95,7 @@ function stacker.new(name) local hashing = true local function push(...) + -- todo check if more than 1 argument for i=1,select("#",...) do insert(stack,(select(i,...))) -- watch the () end @@ -153,8 +156,12 @@ function stacker.new(name) local function resolve_step(ti) -- keep track of changes outside function ! -- todo: optimize for n=1 etc + if not top then + -- report("messed op stacker %a",name) + return + end local result = nil - local noftop = top and #top or 0 + local noftop = #top if ti > 0 then local current = list[ti] if current then |