From a92a8d40ce567ecf5b0baacd9a93a94aac9a4a2d Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Tue, 16 Jul 2019 22:42:53 +0200 Subject: 2019-07-16 18:30:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-de.mkii | 4 + tex/context/base/mkii/mult-nl.mkii | 7 + tex/context/base/mkii/mult-pe.mkii | 4 + tex/context/base/mkii/mult-ro.mkii | 4 + tex/context/base/mkiv/attr-ini.lua | 7 +- tex/context/base/mkiv/back-ini.mkiv | 23 +- tex/context/base/mkiv/back-lua.lua | 336 ++++++++- tex/context/base/mkiv/back-mps.lua | 223 ++++-- tex/context/base/mkiv/back-trf.lua | 17 +- tex/context/base/mkiv/cldf-int.lua | 382 ++++++++--- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/driv-ini.lua | 117 +++- tex/context/base/mkiv/driv-shp.lua | 695 +++++++++---------- tex/context/base/mkiv/grph-inc.mkiv | 4 + tex/context/base/mkiv/lpdf-eng.lua | 26 +- tex/context/base/mkiv/lpdf-epa.lua | 15 +- tex/context/base/mkiv/lpdf-lmt.lua | 390 ++++++----- tex/context/base/mkiv/lpdf-mis.lua | 4 + tex/context/base/mkiv/luat-cnf.lua | 2 +- tex/context/base/mkiv/mult-def.lua | 13 + tex/context/base/mkiv/mult-def.mkiv | 6 +- tex/context/base/mkiv/mult-prm.lua | 1 + tex/context/base/mkiv/node-fin.lua | 17 +- tex/context/base/mkiv/node-fnt.lua | 4 +- tex/context/base/mkiv/node-nut.lua | 36 + tex/context/base/mkiv/node-ref.lua | 59 +- tex/context/base/mkiv/page-run.lua | 2 +- tex/context/base/mkiv/status-files.pdf | Bin 26899 -> 26904 bytes tex/context/base/mkiv/status-lua.pdf | Bin 251955 -> 253018 bytes tex/context/base/mkiv/strc-doc.lua | 11 +- tex/context/base/mkiv/strc-lnt.mkvi | 7 - tex/context/base/mkiv/strc-reg.lua | 65 +- tex/context/base/mkiv/syst-ini.mkiv | 26 +- tex/context/base/mkiv/toks-ini.lua | 16 + tex/context/base/mkiv/toks-scn.lua | 2 + tex/context/base/mkiv/trac-deb.lua | 5 +- tex/context/base/mkiv/trac-inf.lua | 6 +- tex/context/base/mkiv/typo-cap.lua | 8 +- tex/context/base/mkiv/typo-pag.lua | 143 ++-- tex/context/base/mkiv/util-jsn.lua | 33 +- tex/context/interface/mkii/keys-de.xml | 4 + tex/context/interface/mkii/keys-nl.xml | 7 + tex/context/interface/mkii/keys-pe.xml | 4 + tex/context/interface/mkii/keys-ro.xml | 4 + tex/context/interface/mkiv/i-context.pdf | Bin 973481 -> 967706 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 27517 -> 27519 bytes tex/context/modules/mkiv/s-cgj.mkiv | 750 +++++++++++---------- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 51 files changed, 2196 insertions(+), 1303 deletions(-) (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index ba4e48db1..27bc7c7b5 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2019.07.04 12:29} +\newcontextversion{2019.07.16 18:23} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 0caeb26a7..2fe0e7bd3 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2019.07.04 12:29} +\edef\contextversion{2019.07.16 18:23} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index d52003728..6b2995517 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -147,6 +147,7 @@ \setinterfacevariable{comment}{kommentar} \setinterfacevariable{component}{komponente} \setinterfacevariable{compressseparator}{compressseparator} +\setinterfacevariable{compressstopper}{compressstopper} \setinterfacevariable{concept}{konzept} \setinterfacevariable{construction}{construction} \setinterfacevariable{content}{inhalt} @@ -477,6 +478,7 @@ \setinterfacevariable{sectionnumber}{abschnittsnummer} \setinterfacevariable{see}{sieh} \setinterfacevariable{selectfont}{selectfont} +\setinterfacevariable{separator}{separator} \setinterfacevariable{september}{september} \setinterfacevariable{serif}{serif} \setinterfacevariable{serifbold}{serifbold} @@ -732,7 +734,9 @@ \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{compress} \setinterfaceconstant{compressdistance}{compressdistance} +\setinterfaceconstant{compressmethod}{compressmethod} \setinterfaceconstant{compressseparator}{compressseparator} +\setinterfaceconstant{compressstopper}{compressstopper} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} \setinterfaceconstant{continue}{fortsetzen} diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index 6376b158a..0043934b3 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -147,6 +147,7 @@ \setinterfacevariable{comment}{commentaar} \setinterfacevariable{component}{onderdeel} \setinterfacevariable{compressseparator}{compressseparator} +\setinterfacevariable{compressstopper}{compressstopper} \setinterfacevariable{concept}{concept} \setinterfacevariable{construction}{construction} \setinterfacevariable{content}{inhoud} @@ -373,6 +374,7 @@ \setinterfacevariable{nohz}{geenhz} \setinterfacevariable{noline}{noline} \setinterfacevariable{nomarking}{geenmarkering} +\setinterfacevariable{nomenubar}{geenmenubalk} \setinterfacevariable{none}{geen} \setinterfacevariable{nonumber}{geennummer} \setinterfacevariable{norepeat}{norepeat} @@ -476,6 +478,7 @@ \setinterfacevariable{sectionnumber}{sectienummer} \setinterfacevariable{see}{zie} \setinterfacevariable{selectfont}{selectfont} +\setinterfacevariable{separator}{scheider} \setinterfacevariable{september}{september} \setinterfacevariable{serif}{serif} \setinterfacevariable{serifbold}{serifbold} @@ -569,6 +572,7 @@ \setinterfacevariable{temporary}{voorlopig} \setinterfacevariable{test}{test} \setinterfacevariable{text}{tekst} +\setinterfacevariable{textnote}{tekstnoot} \setinterfacevariable{three}{drie} \setinterfacevariable{thursday}{donderdag} \setinterfacevariable{tight}{krap} @@ -729,7 +733,10 @@ \setinterfaceconstant{component}{component} \setinterfaceconstant{compoundhyphen}{koppelteken} \setinterfaceconstant{compress}{comprimeren} +\setinterfaceconstant{compressdistance}{compressdistance} +\setinterfaceconstant{compressmethod}{compressmethod} \setinterfaceconstant{compressseparator}{compressseparator} +\setinterfaceconstant{compressstopper}{compressstopper} \setinterfaceconstant{concerns}{betreft} \setinterfaceconstant{connector}{connector} \setinterfaceconstant{continue}{doorgaan} diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 0b121d288..d07d9dbdd 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -147,6 +147,7 @@ \setinterfacevariable{comment}{توضیح} \setinterfacevariable{component}{مولفه} \setinterfacevariable{compressseparator}{compressseparator} +\setinterfacevariable{compressstopper}{compressstopper} \setinterfacevariable{concept}{مفهوم} \setinterfacevariable{construction}{construction} \setinterfacevariable{content}{محتوا} @@ -477,6 +478,7 @@ \setinterfacevariable{sectionnumber}{شماره‌بخش} \setinterfacevariable{see}{ببینید} \setinterfacevariable{selectfont}{selectfont} +\setinterfacevariable{separator}{separator} \setinterfacevariable{september}{سپتامبر} \setinterfacevariable{serif}{سریف} \setinterfacevariable{serifbold}{serifbold} @@ -732,7 +734,9 @@ \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{فشردن} \setinterfaceconstant{compressdistance}{compressdistance} +\setinterfaceconstant{compressmethod}{compressmethod} \setinterfaceconstant{compressseparator}{compressseparator} +\setinterfaceconstant{compressstopper}{compressstopper} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} \setinterfaceconstant{continue}{ادامه} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index b450e464e..302bc3fa3 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -147,6 +147,7 @@ \setinterfacevariable{comment}{comentariu} \setinterfacevariable{component}{componenta} \setinterfacevariable{compressseparator}{compressseparator} +\setinterfacevariable{compressstopper}{compressstopper} \setinterfacevariable{concept}{concept} \setinterfacevariable{construction}{construction} \setinterfacevariable{content}{cuprins} @@ -477,6 +478,7 @@ \setinterfacevariable{sectionnumber}{numarsetiune} \setinterfacevariable{see}{vezi} \setinterfacevariable{selectfont}{selectfont} +\setinterfacevariable{separator}{separator} \setinterfacevariable{september}{septembrie} \setinterfacevariable{serif}{serif} \setinterfacevariable{serifbold}{serifbold} @@ -732,7 +734,9 @@ \setinterfaceconstant{compoundhyphen}{compoundhyphen} \setinterfaceconstant{compress}{compress} \setinterfaceconstant{compressdistance}{compressdistance} +\setinterfaceconstant{compressmethod}{compressmethod} \setinterfaceconstant{compressseparator}{compressseparator} +\setinterfaceconstant{compressstopper}{compressstopper} \setinterfaceconstant{concerns}{concerns} \setinterfaceconstant{connector}{connector} \setinterfaceconstant{continue}{continua} diff --git a/tex/context/base/mkiv/attr-ini.lua b/tex/context/base/mkiv/attr-ini.lua index dd971afc1..5d35d6ab5 100644 --- a/tex/context/base/mkiv/attr-ini.lua +++ b/tex/context/base/mkiv/attr-ini.lua @@ -34,6 +34,8 @@ attributes.states = attributes.states or { } attributes.handlers = attributes.handlers or { } attributes.unsetvalue = -0x7FFFFFFF +local currentfont = font.current + local names = attributes.names local numbers = attributes.numbers local list = attributes.list @@ -146,7 +148,7 @@ function attributes.save(name) end store[name] = { attr = t, - font = font.current(), + font = currentfont(), } end @@ -163,7 +165,8 @@ function attributes.restore(name) end if font then -- tex.font = font - context.getvalue(fonts.hashes.csnames[font]) -- we don't have a direct way yet (will discuss it with taco) + -- context.getvalue(fonts.hashes.csnames[font]) + currentfont(font) end end -- store[name] = nil diff --git a/tex/context/base/mkiv/back-ini.mkiv b/tex/context/base/mkiv/back-ini.mkiv index ff19d0229..007f80d1a 100644 --- a/tex/context/base/mkiv/back-ini.mkiv +++ b/tex/context/base/mkiv/back-ini.mkiv @@ -64,8 +64,27 @@ \fi \to \everysetupbackend -%D For older styles: +%D For the moment this is an experiment (defauls is pdf, but we also +%D have lua, json and mps). +%D +%D \starttyping +%D % \setupoutput[lua] +%D % \setupoutput[json] +%D % \setupoutput[mps] +%D % \setupoutput[none] % for testing only +%D % \setupoutput[empty] % for testing only +%D +%D \starttext +%D \dorecurse{1000}{ +%D {\tf \red \samplefile{tufte}} \par +%D {\bf \green \samplefile {ward}} \par +%D {\sl \blue \samplefile{davis}} \par +%D } +%D \stoptext +%D \stoptyping + +\unexpanded\def\setupoutput[#1]% + {\clf_enabledriver{#1}} -\let\setupoutput\gobbleoneoptional \protect \endinput diff --git a/tex/context/base/mkiv/back-lua.lua b/tex/context/base/mkiv/back-lua.lua index 257fda0a2..4e95d37e3 100644 --- a/tex/context/base/mkiv/back-lua.lua +++ b/tex/context/base/mkiv/back-lua.lua @@ -6,47 +6,349 @@ if not modules then modules = { } end modules ['back-lua'] = { license = "see context related readme files" } -local buffer = { } -local b = 0 +-- we can remap fonts + +local fontproperties = fonts.hashes.properties +local fontparameters = fonts.hashes.parameters +local fontshapes = fonts.hashes.shapes + +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming + +local bpfactor = number.dimenfactors.bp +local texgetbox = tex.getbox + +local rulecodes = nodes.rulecodes +local normalrule_code = rulecodes.normal +----- boxrule_code = rulecodes.box +----- imagerule_code = rulecodes.image +----- emptyrule_code = rulecodes.empty +----- userrule_code = rulecodes.user +----- overrule_code = rulecodes.over +----- underrule_code = rulecodes.under +----- fractionrule_code = rulecodes.fraction +----- radicalrule_code = rulecodes.radical +local outlinerule_code = rulecodes.outline + +-- todo : per instance + +local pages = { } +local fonts = { } +local names = { } +local mapping = { } +local used = { } +local shapes = { } +local glyphs = { } +local buffer = { } +local b = 0 +local converter = nil + +local compact = false -- true +local shapestoo = true + +local x, y, d, f, c, w, h, t, r, o local function reset() buffer = { } b = 0 + t = nil + x = nil + y = nil + d = nil + f = nil + c = nil + w = nil + h = nil + r = nil + o = nil +end + +local function result() + -- todo: we're now still in the pdf backend but need different codeinjections + local codeinjections = backends.pdf.codeinjections + local getvariable = codeinjections.getidentityvariable or function() end + local jobname = environment.jobname or tex.jobname or "unknown" + return { + metadata = { + unit = "bp", + jobname = jobname, + title = getvariable("title") or jobname, + subject = getvariable("subject"), + author = getvariable("author"), + keywords = getvariable("keywords"), + time = os.date("%Y-%m-%d %H:%M"), + engine = environment.luatexengine .. " " .. environment.luatexversion, + context = environment.version, + }, + fonts = fonts, + pages = pages, + shapes = shapes, + } +end + +-- actions + +local function outputfilename(driver) + return tex.jobname .. "-output.lua" +end + +local function save() -- might become a driver function that already is plugged into stopactions + local filename = outputfilename() + drivers.report("saving result in %a",filename) + starttiming(drivers) + local data = result() + if data then + io.savedata(filename,table.serialize(data)) + end + stoptiming(drivers) end -local function initialize(specification) +local function prepare(driver) + converter = drivers.converters.lmtx + luatex.registerstopactions(1,function() + save() + end) +end + +local function initialize(driver,details) reset() end -local function finalize() +local function finalize(driver,details) + local n = details.pagenumber + local b = details.boundingbox + pages[n] = { + number = n, + content = buffer, + boundingbox = { + b[1] * bpfactor, + b[2] * bpfactor, + b[3] * bpfactor, + b[4] * bpfactor, + }, + } +end + +local function wrapup(driver) end -local function fetch() - local saved = buffer +local function cleanup(driver) reset() - return saved end -local function flushcharacter(current, pos_h, pos_v, pod_r, font, char) - b = b + 1 ; buffer[b] = { "glyph", font, char, pos_h, pos_v, pos_r } +local function convert(driver,boxnumber,pagenumber) + converter(driver,texgetbox(boxnumber),"page",pagenumber) +end + +-- flushers + +local function updatefontstate(id) + if not mapping[id] then + local fn = #fonts + 1 + mapping[id] = fn + local properties = fontproperties[id] + local parameters = fontparameters[id] + local filename = file.basename(properties.filename) + local fontname = properties.fullname or properties.fontname + if shapestoo then + if not names[fontname] then + local sn = #shapes+1 + names[fontname] = sn + shapes[sn] = { } + glyphs[sn] = fontshapes[id].glyphs + end + end + fonts[fn] = { + filename = filename, + name = fontname, + size = parameters.size * bpfactor, + shapes = shapestoo and names[fontname] or nil, + } + end +end + +local function flushcharacter(current, pos_h, pos_v, pos_r, font, char) + local fnt = mapping[font] + b = b + 1 + buffer[b] = { + t = "glyph" ~= t and "glyph" or nil, + f = font ~= f and fnt or nil, + c = char ~= c and char or nil, + x = pos_h ~= x and (pos_h * bpfactor) or nil, + y = pos_v ~= y and (pos_v * bpfactor) or nil, + d = pos_r ~= d and (pos_r == 1 and "r2l" or "l2r") or nil, + } + t = "glyph" + f = font + c = char + x = pos_h + y = pos_v + d = pos_r + if shapestoo then + -- can be sped up if needed + local sn = fonts[fnt].shapes + local shp = shapes[sn] + if not shp[char] then + shp[char] = glyphs[sn][char] + end + end +end + +local function rule(pos_h, pos_v, pos_r, size_h, size_v, rule_s, rule_o) + b = b + 1 + buffer[b] = { + t = "rule" ~= t and "rule" or nil, + r = rule_s ~= r and rule_s or nil, + o = rule_s == "outline" and rule_o ~= o and (rule_o * bpfactor) or nil, + w = size_h ~= w and (size_h * bpfactor) or nil, + h = size_v ~= h and (size_v * bpfactor) or nil, + x = pos_h ~= x and (pos_h * bpfactor) or nil, + y = pos_v ~= y and (pos_v * bpfactor) or nil, + d = pos_r ~= d and (pos_r == 1 and "r2l" or "l2r") or nil, + } + t = "rule" + w = size_h + h = size_v + x = pos_h + y = pos_v + d = pos_r +end + +local function flushrule(current, pos_h, pos_v, pos_r, size_h, size_v, subtype) + local rule_s, rule_o + if subtype == normalrule_code then + rule_s = "normal" + elseif subtype == outlinerule_code then + rule_s = "outline" + rule_o = getdata(current) + else + return + end + return rule(pos_h, pos_v, pos_r, size_h, size_v, rule_s, rule_o) end -local function flushrule(current, pos_h, pos_v, pos_r, size_h, size_v) - b = b + 1 ; buffer[b] = { "rule", size_h, size_v, pos_h, pos_v, pos_r } +local function flushsimplerule(current, pos_h, pos_v, pos_r, size_h, size_v) + return rule(pos_h, pos_v, pos_r, size_h, size_v, "normal", nil) end -- file stuff too +-- todo: default flushers +-- also color (via hash) + +-- installer drivers.install { name = "lua", actions = { - initialize = initialize, - finalize = finalize, - fetch = fetch, - reset = reset, + prepare = prepare, + initialize = initialize, + finalize = finalize, + wrapup = wrapup, + cleanup = cleanup, + convert = convert, + outputfilename = outputfilename, + }, + flushers = { + updatefontstate = updatefontstate, + character = flushcharacter, + rule = flushrule, + } +} + +-- actions + +local function outputfilename(driver) + return tex.jobname .. "-output.json" +end + +local function save() -- might become a driver function that already is plugged into stopactions + local filename = outputfilename() + drivers.report("saving result in %a",filename) + starttiming(drivers) + local data = result() + if data then + if not utilities.json then + require("util-jsn") + end + io.savedata(filename,utilities.json.tostring(data,not compact)) + end + stoptiming(drivers) +end + +local function prepare(driver) + converter = drivers.converters.lmtx + luatex.registerstopactions(1,function() + save() + end) +end + +-- installer + +drivers.install { + name = "json", + actions = { + prepare = prepare, + initialize = initialize, + finalize = finalize, + wrapup = wrapup, + cleanup = cleanup, + convert = convert, + outputfilename = outputfilename, + }, + flushers = { + updatefontstate = updatefontstate, + character = flushcharacter, + rule = flushrule, + } +} + +-- actions + +local function outputfilename(driver) + return tex.jobname .. "-output.js" +end + +local function save() -- might become a driver function that already is plugged into stopactions + local filename = outputfilename() + drivers.report("saving result in %a",filename) + starttiming(drivers) + local data = result() + if data then + if not utilities.json then + require("util-jsn") + end + io.savedata(filename, + "const JSON_CONTEXT = JSON.parse ( `" .. + utilities.json.tostring(data,not compact) .. + "` ) ;\n" + ) + end + stoptiming(drivers) +end + +local function prepare(driver) + converter = drivers.converters.lmtx + luatex.registerstopactions(1,function() + save() + end) +end + +-- installer + +drivers.install { + name = "js", + actions = { + prepare = prepare, + initialize = initialize, + finalize = finalize, + wrapup = wrapup, + cleanup = cleanup, + convert = convert, + outputfilename = outputfilename, }, flushers = { - character = flushcharacter, - rule = flushrule, + updatefontstate = updatefontstate, + character = flushcharacter, + rule = flushrule, } } diff --git a/tex/context/base/mkiv/back-mps.lua b/tex/context/base/mkiv/back-mps.lua index 380fb7a35..96c850ed6 100644 --- a/tex/context/base/mkiv/back-mps.lua +++ b/tex/context/base/mkiv/back-mps.lua @@ -6,89 +6,200 @@ if not modules then modules = { } end modules ['back-mps'] = { license = "see context related readme files" } --- The basics are the same as the lua variant. - -local formatters = string.formatters -local bpfactor = number.dimenfactors.bp - -local buffer = { } -local b = 0 +local fontproperties = fonts.hashes.properties +local fontparameters = fonts.hashes.parameters + +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming + +local bpfactor = number.dimenfactors.bp +local texgetbox = tex.getbox +local formatters = string.formatters + +local rulecodes = nodes.rulecodes +local normalrule_code = rulecodes.normal +----- boxrule_code = rulecodes.box +----- imagerule_code = rulecodes.image +----- emptyrule_code = rulecodes.empty +----- userrule_code = rulecodes.user +----- overrule_code = rulecodes.over +----- underrule_code = rulecodes.under +----- fractionrule_code = rulecodes.fraction +----- radicalrule_code = rulecodes.radical +local outlinerule_code = rulecodes.outline + +local fonts = { } +local pages = { } +local buffer = { } +local b = 0 +local converter = nil local function reset() buffer = { } b = 0 end -local function initialize(specification) - reset() +local f_font = formatters[ "\\definefont[%s][file:%s*none @ %sbp]\n" ] + +local f_glyph = formatters[ [[draw textext.drt("\%s\char%i\relax") shifted (%N,%N);]] ] +local f_rule = formatters[ [[fill unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ] +local f_outline = formatters[ [[draw unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ] + +-- actions + +local function outputfilename(driver) + return tex.jobname .. "-output.tex" end -local function finalize() +local function save() -- might become a driver function that already is plugged into stopactions + starttiming(drivers) + if #pages > 0 then + local filename = outputfilename() + drivers.report("saving result in %a",filename) + reset() + b = b + 1 + buffer[b] = "\\starttext\n" + for k, v in table.sortedhash(fonts) do + b = b + 1 + buffer[b] = f_font(v.name,v.filename,v.size) + end + for i=1,#pages do + b = b + 1 + buffer[b] = pages[i] + end + b = b + 1 + buffer[b] = "\\stoptext\n" + io.savedata(filename,table.concat(buffer,"",1,b)) + end + stoptiming(drivers) end -local function fetch() - local saved = buffer - reset() - return saved +local function prepare(driver) + converter = drivers.converters.lmtx + luatex.registerstopactions(1,function() + save() + end) end -local function flushcharacter(current, pos_h, pos_v, pod_r, font, char) - b = b + 1 ; buffer[b] = { "glyph", font, char, pos_h, pos_v, pos_r } +local function initialize(driver,details) + reset() + b = b + 1 + buffer[b] = "\n\\startMPpage" end -local function flushrule(current, pos_h, pos_v, pod_r, size_h, size_v) - b = b + 1 ; buffer[b] = { "rule", size_h, size_v, pos_h, pos_v, pos_r } +local function finalize(driver,details) + b = b + 1 + buffer[b] = "\\stopMPpage\n" + pages[details.pagenumber] = table.concat(buffer,"\n",1,b) end -drivers.install { - name = "mps", - actions = { - initialize = initialize, - finalize = finalize, - fetch = fetch, - reset = reset, - }, - flushers = { - character = flushcharacter, - rule = flushrule, - } -} +local function wrapup(driver) +end -if not mp then - return +local function cleanup(driver) + reset() end -local mpprint = mp.print +local function convert(driver,boxnumber,pagenumber) + converter(driver,texgetbox(boxnumber),"page",pagenumber) +end -local f_glyph = formatters[ [[draw textext.drt("\setfontid%i\relax\char%i\relax") shifted (%N,%N);]] ] -local f_rule = formatters[ [[fill unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ] +-- flushers -local current = nil -local size = 0 +local last -function mp.place_buffermake(box) - drivers.convert("mps",box) - current = drivers.action("mps","fetch") - size = #current +local function updatefontstate(id) + if fonts[id] then + last = fonts[id].name + else + last = "MPSfont" .. converters.Characters(id) + fonts[id] = { + filename = file.basename(fontproperties[id].filename), + size = fontparameters[id].size * bpfactor, + name = last, + } + end end -function mp.place_buffersize() - mpprint(size) +local function flushcharacter(current, pos_h, pos_v, pod_r, font, char) + b = b + 1 + buffer[b] = f_glyph(last,char,pos_h*bpfactor,pos_v*bpfactor) end -function mp.place_bufferslot(i) - if i > 0 and i <= size then - local b = buffer[i] - local t = b[1] - if t == "glyph" then - mpprint(f_glyph(b[2],b[3],b[4]*bpfactor,b[5]*bpfactor)) - elseif t == "rule" then - mpprint(f_rule(b[2]*bpfactor,b[3]*bpfactor,b[4]*bpfactor,b[5]*bpfactor)) - end +local function flushrule(current, pos_h, pos_v, pod_r, size_h, size_v, subtype) + if subtype == normalrule_code then + b = b + 1 + buffer[b] = f_rule(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor) + elseif subtype == outlinerule_code then + b = b + 1 + buffer[b] = f_outline(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor) end end -function mp.place_bufferwipe() - current = nil - size = 0 +local function flushsimplerule(current, pos_h, pos_v, pod_r, size_h, size_v) + b = b + 1 + buffer[b] = f_rule(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor) end + +-- installer + +drivers.install { + name = "mps", + actions = { + prepare = prepare, + initialize = initialize, + finalize = finalize, + wrapup = wrapup, + cleanup = cleanup, + convert = convert, + outputfilename = outputfilename, + }, + flushers = { + updatefontstate = updatefontstate, + character = flushcharacter, + rule = flushrule, + simplerule = flushsimplerule, + } +} + +-- extras + +-- if not mp then +-- return +-- end +-- +-- local mpprint = mp.print +-- local formatters = string.formatters +-- +-- local f_glyph = formatters[ [[draw textext.drt("\setfontid%i\relax\char%i\relax") shifted (%N,%N);]] ] +-- local f_rule = formatters[ [[fill unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ] +-- +-- local current = nil +-- local size = 0 +-- +-- function mp.place_buffermake(box) +-- drivers.convert("mps",box) +-- current = drivers.action("mps","fetch") +-- size = #current +-- end +-- +-- function mp.place_buffersize() +-- mpprint(size) +-- end +-- +-- function mp.place_bufferslot(i) +-- if i > 0 and i <= size then +-- local b = buffer[i] +-- local t = b[1] +-- if t == "glyph" then +-- mpprint(f_glyph(b[2],b[3],b[4]*bpfactor,b[5]*bpfactor)) +-- elseif t == "rule" then +-- mpprint(f_rule(b[2]*bpfactor,b[3]*bpfactor,b[4]*bpfactor,b[5]*bpfactor)) +-- end +-- end +-- end +-- +-- function mp.place_bufferwipe() +-- current = nil +-- size = 0 +-- end diff --git a/tex/context/base/mkiv/back-trf.lua b/tex/context/base/mkiv/back-trf.lua index 721c856a9..1586bc440 100644 --- a/tex/context/base/mkiv/back-trf.lua +++ b/tex/context/base/mkiv/back-trf.lua @@ -141,14 +141,23 @@ implement { name = "stopmirroring", actions = startmirroring } -- not: stopsome -- this could also run on top of pack-rul ... todo +-- local function startclipping() +-- -- context(savenode()) +-- context(literalnode("origin",formatters["q 0 w %s W n"](scanstring()))) +-- end +-- +-- local function stopclipping() +-- -- context(restorenode()) +-- context(literalnode("Q")) +-- end + local function startclipping() - -- context(savenode()) - context(literalnode("origin",formatters["q 0 w %s W n"](scanstring()))) + context(savenode()) + context(literalnode("origin",formatters["0 w %s W n"](scanstring()))) end local function stopclipping() - -- context(restorenode()) - context(literalnode("Q")) + context(restorenode()) end implement { name = "startclipping", actions = startclipping } diff --git a/tex/context/base/mkiv/cldf-int.lua b/tex/context/base/mkiv/cldf-int.lua index 52cfea8d0..937e1da60 100644 --- a/tex/context/base/mkiv/cldf-int.lua +++ b/tex/context/base/mkiv/cldf-int.lua @@ -11,8 +11,9 @@ if not modules then modules = { } end modules ['cldf-int'] = { -- needs checking -- todo: multilingual -local format, insert, remove, concat = string.format, table.insert, table.remove, table.concat -local unpack = unpack or table.unpack +local format, byte = string.format, string.byte +local insert, remove, concat = table.insert, table.remove, table.concat +local unpack, type = unpack or table.unpack, type local catcodenumbers = catcodes.numbers @@ -24,140 +25,282 @@ local contextsprint = context.sprint local trace_define = false trackers.register("context.define", function(v) trace_define = v end) -interfaces = interfaces or { } +interfaces = interfaces or { } +local implement = interfaces.implement +local estart = interfaces.elements.start +local estop = interfaces.elements.stop -_clmh_ = utilities.parsers.settings_to_hash -_clma_ = utilities.parsers.settings_to_array +if CONTEXTLMTXMODE > 0 then -local starters, stoppers, macros, stack = { }, { }, { }, { } + local scanners = tokens.scanners + local shortcuts = tokens.shortcuts -local checkers = { - [0] = "", - "\\dosingleempty", - "\\dodoubleempty", - "\\dotripleempty", - "\\doquadrupleempty", - "\\doquintupleempty", - "\\dosixtupleempty", -} + local scanpeek = scanners.peek + local scankey = scanners.key + local scanvalue = scanners.value + local scanskip = scanners.skip -function _clmm_(name,...) - macros[name](...) -end + local open = byte('[') + local close = byte(']') + local equal = byte('=') + local comma = byte(',') -function _clmb_(name,...) - local sn = stack[name] - insert(sn,{...}) - starters[name](...) -end - -function _clme_(name) - local sn = stack[name] - local sv = remove(sn) - if sv then - stoppers[name](unpack(sv)) - else - -- nesting error + function scanhash(t) + if scanpeek() == open then + local data = { } + scanskip() + while true do + local c = scanpeek() + if c == comma then + scanskip() + elseif c == close then + scanskip() + break + else + local key = scankey(equal) + if key then + if scanpeek() == equal then + scanskip() + data[key] = scanvalue(comma,close) or "" + else + break + end + else + break + end + end + end + return data + end end -end -_clmn_ = tonumber + function scanarray(t) + if scanpeek() == open then + local data = { } + local d = 0 + scanskip() + while true do + local c = scanpeek() + if c == comma then + scanskip() + elseif c == close then + scanskip() + break + else + local v = scanvalue(comma,close) or "" + d = d + 1 + data[d] = v + end + end + return data + end + end -local estart = interfaces.elements.start -local estop = interfaces.elements.stop + shortcuts.scanhash = scanhash + shortcuts.scanarray = scanarray --- this is a bit old definition ... needs to be modernized + scanners.hash = scanhash + scanners.array = scanarray -function interfaces.definecommand(name,specification) -- name is optional - if type(name) == "table" then - specification = name - name = specification.name + local function remap(arguments) + -- backward compatibility + if type(arguments) == "table" then + for i=1,#arguments do + local a = arguments[i] + if type(a) == "table" then + local t = a[2] + arguments[i] = t == "list" and "array" or t + end + end + return arguments + end end - if name and specification then - local arguments = specification.arguments - local na = (arguments and #arguments) or 0 - local environment = specification.environment - if na == 0 then + + function interfaces.definecommand(name,specification) -- name is optional + if type(name) == "table" then + specification = name + name = specification.name + end + if name and specification then + local environment = specification.environment + local arguments = remap(specification.arguments) if environment then - contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{\\ctxlua{_clmb_('",name,"')}}") - contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}") + local starter = specification.starter + local stopper = specification.stopper + if starter and stopper then + implement { + name = estart .. name, + arguments = arguments, + public = true, + protected = true, + actions = starter, + } + implement { + name = estop .. name, + public = true, + protected = true, + actions = stopper, + } + else + -- message + end end if not environment or environment == "both" then - contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{\\ctxlua{_clmm_('",name,"')}}") - end - else - -- we could flush immediate but tracing is bad then - stack[name] = { } - local opt = 0 - local done = false - local snippets = { } -- we can reuse it - local mkivdo = "\\mkivdo" .. name -- maybe clddo - snippets[#snippets+1] = "\\def" - snippets[#snippets+1] = mkivdo - for i=1,na do - local a = arguments[i] - local variant = a[1] - if variant == "option" then - snippets[#snippets+1] = "[#" - snippets[#snippets+1] = i - snippets[#snippets+1] = "]" - if not done then - opt = opt + 1 - end + local macro = specification.macro + if macro then + implement { + name = name, + arguments = arguments, + public = true, + protected = true, + actions = macro, + } else - done = true -- no more optional checking after this - snippets[#snippets+1] = "#" - snippets[#snippets+1] = i + -- message end end - if environment then - snippets[#snippets+1] = "{\\ctxlua{_clmb_('" - snippets[#snippets+1] = name - snippets[#snippets+1] = "'" + else + -- message + end + end + + +else + + _clmh_ = utilities.parsers.settings_to_hash + _clma_ = utilities.parsers.settings_to_array + + local starters, stoppers, macros, stack = { }, { }, { }, { } + + local checkers = { + [0] = "", + "\\dosingleempty", + "\\dodoubleempty", + "\\dotripleempty", + "\\doquadrupleempty", + "\\doquintupleempty", + "\\dosixtupleempty", + } + + function _clmm_(name,...) + macros[name](...) + end + + function _clmb_(name,...) + local sn = stack[name] + insert(sn,{...}) + starters[name](...) + end + + function _clme_(name) + local sn = stack[name] + local sv = remove(sn) + if sv then + stoppers[name](unpack(sv)) + else + -- nesting error + end + end + + _clmn_ = tonumber + + local estart = interfaces.elements.start + local estop = interfaces.elements.stop + + -- this is a bit old definition ... needs to be modernized + + function interfaces.definecommand(name,specification) -- name is optional + if type(name) == "table" then + specification = name + name = specification.name + end + if name and specification then + local arguments = specification.arguments + local na = (arguments and #arguments) or 0 + local environment = specification.environment + if na == 0 then + if environment then + contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{\\ctxlua{_clmb_('",name,"')}}") + contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}") + end + if not environment or environment == "both" then + contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{\\ctxlua{_clmm_('",name,"')}}") + end else - snippets[#snippets+1] = "{\\ctxlua{_clmm_('" - snippets[#snippets+1] = name - snippets[#snippets+1] = "'" - end - for i=1,na do - local a = arguments[i] - local variant = a[2] - if variant == "list" then - snippets[#snippets+1] = ",_clma_([[#" - snippets[#snippets+1] = i - snippets[#snippets+1] = "]])" - elseif variant == "hash" then - snippets[#snippets+1] = ",_clmh_([[#" - snippets[#snippets+1] = i - snippets[#snippets+1] = "]])" - elseif variant == "number" then - snippets[#snippets+1] = ",_clmn_([[#" - snippets[#snippets+1] = i - snippets[#snippets+1] = "]])" + -- we could flush immediate but tracing is bad then + stack[name] = { } + local opt = 0 + local done = false + local snippets = { } -- we can reuse it + local mkivdo = "\\mkivdo" .. name -- maybe clddo + snippets[#snippets+1] = "\\def" + snippets[#snippets+1] = mkivdo + for i=1,na do + local a = arguments[i] + local variant = a[1] + if variant == "option" then + snippets[#snippets+1] = "[#" + snippets[#snippets+1] = i + snippets[#snippets+1] = "]" + if not done then + opt = opt + 1 + end + else + done = true -- no more optional checking after this + snippets[#snippets+1] = "#" + snippets[#snippets+1] = i + end + end + if environment then + snippets[#snippets+1] = "{\\ctxlua{_clmb_('" + snippets[#snippets+1] = name + snippets[#snippets+1] = "'" else - snippets[#snippets+1] = ",[[#" - snippets[#snippets+1] = i - snippets[#snippets+1] = "]]" + snippets[#snippets+1] = "{\\ctxlua{_clmm_('" + snippets[#snippets+1] = name + snippets[#snippets+1] = "'" + end + for i=1,na do + local a = arguments[i] + local variant = a[2] + if variant == "list" then + snippets[#snippets+1] = ",_clma_([==[#" + snippets[#snippets+1] = i + snippets[#snippets+1] = "]==])" + elseif variant == "hash" then + snippets[#snippets+1] = ",_clmh_([==[#" + snippets[#snippets+1] = i + snippets[#snippets+1] = "]==])" + elseif variant == "number" then + snippets[#snippets+1] = ",_clmn_([==[#" + snippets[#snippets+1] = i + snippets[#snippets+1] = "]==])" + else + snippets[#snippets+1] = ",[==[#" + snippets[#snippets+1] = i + snippets[#snippets+1] = "]==]" + end + end + snippets[#snippets+1] = ")}}" + contextsprint(ctxcatcodes,unpack(snippets)) + if environment then + -- needs checking + contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{",checkers[opt],mkivdo,"}") + contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}") + end + if not environment or environment == "both" then + contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{",checkers[opt],mkivdo,"}") end end - snippets[#snippets+1] = ")}}" - contextsprint(ctxcatcodes,unpack(snippets)) if environment then - -- needs checking - contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{",checkers[opt],mkivdo,"}") - contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}") - end - if not environment or environment == "both" then - contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{",checkers[opt],mkivdo,"}") + starters[name] = specification.starter + stoppers[name] = specification.stopper + else + macros[name] = specification.macro end end - if environment then - starters[name] = specification.starter - stoppers[name] = specification.stopper - else - macros[name] = specification.macro - end end + end function interfaces.tolist(t) @@ -223,3 +366,20 @@ end -- \stopluacode -- -- more: \startmore[1] one \startmore[2] two \stopmore one \stopmore +-- +-- More modern (no need for option or content): +-- +-- \startluacode +-- interfaces.definecommand { +-- name = "test", +-- arguments = { +-- "array", -- or list +-- "hash", +-- "string", +-- "number", +-- }, +-- macro = test, +-- } +-- \stopluacode +-- + diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 428ff4f95..bd131ddaf 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.07.04 12:29} +\newcontextversion{2019.07.16 18:23} %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 26a46a8bc..bc9549d01 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.07.04 12:29} +\edef\contextversion{2019.07.16 18:23} \edef\contextkind {beta} %D Kind of special: diff --git a/tex/context/base/mkiv/driv-ini.lua b/tex/context/base/mkiv/driv-ini.lua index f3d62c778..a19ebb359 100644 --- a/tex/context/base/mkiv/driv-ini.lua +++ b/tex/context/base/mkiv/driv-ini.lua @@ -19,10 +19,20 @@ local report = logs.reporter("drivers") local instances = { } local helpers = { } +local converters = { } local prepared = { } local wrappedup = { } local cleanedup = { } local currentdriver = "default" +local currentinstance = nil + +local shipout = tex.shipout +local texgetbox = tex.getbox +local texgetcount = tex.getcount + +function converters.engine(driver,boxnumber,mode,number,specification) + return shipout(boxnumber) +end local prepare = nil local convert = nil @@ -33,7 +43,9 @@ local outputfilename = nil drivers = drivers or { instances = instances, helpers = helpers, + converters = converters, lmtxversion = 0.10, + report = report, } local dummy = function() end @@ -65,26 +77,32 @@ function drivers.install(specification) report("no flushers for driver %a",name) return end - setmetatableindex(actions,defaulthandlers) + -- report("driver %a is installed",name) + setmetatableindex(actions, defaulthandlers) + setmetatableindex(flushers, function() return dummy end) instances[name] = specification end function drivers.convert(boxnumber) - callbacks.functions.start_page_number() - starttiming(drivers) - convert(boxnumber) - stoptiming(drivers) - callbacks.functions.stop_page_number() + if currentinstance then + callbacks.functions.start_page_number() + starttiming(drivers) + convert(currentinstance,boxnumber,texgetcount("realpageno")) + stoptiming(drivers) + callbacks.functions.stop_page_number() + end end function drivers.outputfilename() - return outputfilename() + if currentinstance then + return outputfilename(currentinstance) + end end luatex.wrapup(function() - if wrapup and not wrappedup[currentdriver] then + if currentinstance and wrapup and not wrappedup[currentdriver] then starttiming(drivers) - wrapup() + wrapup(currentinstance) stoptiming(drivers) wrappedup[currentdriver] = true cleanedup[currentdriver] = true @@ -92,9 +110,9 @@ luatex.wrapup(function() end) luatex.cleanup(function() - if cleanup and not cleanedup[currentdriver] then + if currentinstance and cleanup and not cleanedup[currentdriver] then starttiming(drivers) - cleanup() + cleanup(currentinstance) stoptiming(drivers) wrappedup[currentdriver] = true cleanedup[currentdriver] = true @@ -102,19 +120,31 @@ luatex.cleanup(function() end) function drivers.enable(name) - currentdriver = name or "default" - local actions = instances[currentdriver].actions - prepare = actions.prepare - wrapup = actions.wrapup - cleanup = actions.cleanup - convert = actions.convert - outputfilename = actions.outputfilename - -- - if prepare and not prepared[currentdriver] then - starttiming(drivers) - prepare() - stoptiming(drivers) - prepared[currentdriver] = true + if name ~= currentdriver then + if currentinstance then + starttiming(drivers) + cleanup(currentinstance) + stoptiming(drivers) + end + currentdriver = name or "default" + currentinstance = instances[currentdriver] + if currentinstance then + local actions = currentinstance.actions + prepare = actions.prepare + wrapup = actions.wrapup + cleanup = actions.cleanup + convert = actions.convert + outputfilename = actions.outputfilename + -- + if prepare and not prepared[currentdriver] then + starttiming(drivers) + prepare(currentinstance) + stoptiming(drivers) + prepared[currentdriver] = true + end + else + report("bad driver") + end end end @@ -143,8 +173,8 @@ do drivers.install { name = "default", actions = { - convert = tex.shipout, - outputfilename = function() + convert = drivers.converters.engine, + outputfilename = function(driver) if not filename then filename = addsuffix(tex.jobname,"pdf") end @@ -158,6 +188,41 @@ do end +-- No driver: + +do + + drivers.install { + name = "none", + actions = { }, + flushers = { }, + } + +end + +do + + local function prepare(driver) + converter = drivers.converters.lmtx + end + + local function convert(driver,boxnumber,pagenumber) + converter(driver,texgetbox(boxnumber),"page",pagenumber) + end + + drivers.install { + name = "empty", + actions = { + prepare = prepare, + convert = convert, + }, + flushers = { }, + } + +end + +-- + setmetatableindex(instances,function() return instances.default end) -- for now: diff --git a/tex/context/base/mkiv/driv-shp.lua b/tex/context/base/mkiv/driv-shp.lua index 19bc75f2a..980dda357 100644 --- a/tex/context/base/mkiv/driv-shp.lua +++ b/tex/context/base/mkiv/driv-shp.lua @@ -9,109 +9,111 @@ if not modules then modules = { } end modules ['driv-shp'] = { local type, next = type, next local round = math.round -local setmetatableindex = table.setmetatableindex -local formatters = string.formatters -local concat = table.concat -local keys = table.keys -local sortedhash = table.sortedhash -local splitstring = string.split -local idiv = number.idiv -local extract = bit32.extract -local nuts = nodes.nuts - -local tonut = nodes.tonut -local tonode = nodes.tonode - -local getdirection = nuts.getdirection -local getlist = nuts.getlist -local getoffsets = nuts.getoffsets -local getorientation = nuts.getorientation -local getfield = nuts.getfield -local getwhd = nuts.getwhd -local getkern = nuts.getkern -local getheight = nuts.getheight -local getdepth = nuts.getdepth -local getwidth = nuts.getwidth -local getnext = nuts.getnext -local getsubtype = nuts.getsubtype -local getid = nuts.getid -local getleader = nuts.getleader -local getglue = nuts.getglue -local getshift = nuts.getshift -local getdata = nuts.getdata -local getboxglue = nuts.getboxglue -local getexpansion = nuts.getexpansion - ------ getall = node.direct.getall - -local setdirection = nuts.setdirection -local setfield = nuts.setfield -local setlink = nuts.setlink - -local isglyph = nuts.isglyph -local findtail = nuts.tail -local nextdir = nuts.traversers.dir -local nextnode = nuts.traversers.node - -local rangedimensions = nuts.rangedimensions -local effectiveglue = nuts.effective_glue - -local nodecodes = nodes.nodecodes -local whatsitcodes = nodes.whatsitcodes -local leadercodes = nodes.leadercodes -local subtypes = nodes.subtypes - -local dircodes = nodes.dircodes -local normaldir_code = dircodes.normal - -local dirvalues = nodes.dirvalues -local lefttoright_code = dirvalues.lefttoright -local righttoleft_code = dirvalues.righttoleft - -local glyph_code = nodecodes.glyph -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local dir_code = nodecodes.dir -local disc_code = nodecodes.disc -local math_code = nodecodes.math -local rule_code = nodecodes.rule -local marginkern_code = nodecodes.marginkern -local whatsit_code = nodecodes.whatsit - -local leader_code = leadercodes.leader -local cleader_code = leadercodes.cleader -local xleader_code = leadercodes.xleader -local gleader_code = leadercodes.gleader - -local saveposwhatsit_code = whatsitcodes.savepos -local userdefinedwhatsit_code = whatsitcodes.userdefined -local openwhatsit_code = whatsitcodes.open -local writewhatsit_code = whatsitcodes.write -local closewhatsit_code = whatsitcodes.close -local lateluawhatsit_code = whatsitcodes.latelua -local literalwhatsit_code = whatsitcodes.literal -local setmatrixwhatsit_code = whatsitcodes.setmatrix -local savewhatsit_code = whatsitcodes.save -local restorewhatsit_code = whatsitcodes.restore - -local texget = tex.get - -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local characters = fonthashes.characters -local parameters = fonthashes.parameters - -local report = logs.reporter("drivers") +local setmetatableindex = table.setmetatableindex +local formatters = string.formatters +local concat = table.concat +local keys = table.keys +local sortedhash = table.sortedhash +local splitstring = string.split +local idiv = number.idiv +local extract = bit32.extract +local nuts = nodes.nuts + +local tonut = nodes.tonut +local tonode = nodes.tonode + +local getdirection = nuts.getdirection +local getlist = nuts.getlist +local getoffsets = nuts.getoffsets +local getorientation = nuts.getorientation +local getfield = nuts.getfield +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local getheight = nuts.getheight +local getdepth = nuts.getdepth +local getwidth = nuts.getwidth +local getnext = nuts.getnext +local getsubtype = nuts.getsubtype +local getid = nuts.getid +local getleader = nuts.getleader +local getglue = nuts.getglue +local getshift = nuts.getshift +local getdata = nuts.getdata +local getboxglue = nuts.getboxglue +local getexpansion = nuts.getexpansion +local getreplace = nuts.getreplace +local setreplace = nuts.setreplace + +local setdirection = nuts.setdirection +local setfield = nuts.setfield +local setlink = nuts.setlink + +local isglyph = nuts.isglyph +local findtail = nuts.tail +local nextdir = nuts.traversers.dir +local nextnode = nuts.traversers.node + +local rangedimensions = node.direct.naturalwidth or nuts.rangedimensions +local effectiveglue = nuts.effective_glue + +local texget = tex.get + +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers +local characters = fonthashes.characters +local parameters = fonthashes.parameters + +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes +local leadercodes = nodes.leadercodes +local dircodes = nodes.dircodes +local dirvalues = nodes.dirvalues +local subtypes = nodes.subtypes + +local normaldir_code = dircodes.normal + +local lefttoright_code = dirvalues.lefttoright +local righttoleft_code = dirvalues.righttoleft + +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local dir_code = nodecodes.dir +local disc_code = nodecodes.disc +local math_code = nodecodes.math +local rule_code = nodecodes.rule +local marginkern_code = nodecodes.marginkern +local whatsit_code = nodecodes.whatsit +----- penalty_code = nodecodes.penalty +----- boundary_code = nodecodes.boundary + +local leaders_code = leadercodes.leaders +local cleaders_code = leadercodes.cleaders +local xleaders_code = leadercodes.xleaders +local gleaders_code = leadercodes.gleaders + +local saveposwhatsit_code = whatsitcodes.savepos +local userdefinedwhatsit_code = whatsitcodes.userdefined +local openwhatsit_code = whatsitcodes.open +local writewhatsit_code = whatsitcodes.write +local closewhatsit_code = whatsitcodes.close +local lateluawhatsit_code = whatsitcodes.latelua +local literalwhatsit_code = whatsitcodes.literal +local setmatrixwhatsit_code = whatsitcodes.setmatrix +local savewhatsit_code = whatsitcodes.save +local restorewhatsit_code = whatsitcodes.restore local getpagedimensions getpagedimensions = function() getpagedimensions = backends.codeinjections.getpagedimensions return getpagedimensions() end -local drivers = drivers -local instances = drivers.instances +local drivers = drivers +local instances = drivers.instances + +local report = logs.reporter("drivers") --------------------------------------------------------------------------------------- @@ -145,12 +147,12 @@ local pushorientation local poporientation local flushcharacter local flushrule -local flushpdfliteral -local flushpdfsetmatrix -local flushpdfsave -local flushpdfrestore +local flushliteral +local flushsetmatrix +local flushsave +local flushrestore local flushspecial ------ flushpdfimage +----- flushimage -- make local @@ -158,15 +160,6 @@ function drivers.getpos () return round(pos_h), round(pos_v) end function drivers.gethpos() return round(pos_h) end function drivers.getvpos() return round(pos_v) end --- local function synch_pos_with_cur(ref_h, ref_v, h, v) --- if pos_r == righttoleft_code then --- pos_h = ref_h - h --- else --- pos_h = ref_h + h --- end --- pos_v = ref_v - v --- end - -- characters local flush_character @@ -261,7 +254,7 @@ local function flush_vf_packet(pos_h,pos_v,pos_r,font,char,data,factor,vfcommand level = level - 1 end elseif command == "pdf" then - flushpdfliteral(false,pos_h,pos_v,packet[2],packet[3]) + flushliteral(false,pos_h,pos_v,packet[2],packet[3]) elseif command == "rule" then local size_v = packet[2] local size_h = packet[3] @@ -308,7 +301,6 @@ local function flush_vf_packet(pos_h,pos_v,pos_r,font,char,data,factor,vfcommand pos_v = saved_v pos_r = saved_r - -- synch_pos_with_cur(ref_h, ref_v, pos_h,pos_v) nesting = nesting - 1 end @@ -436,34 +428,6 @@ end local hlist_out, vlist_out do - -- effective_glue : - -- - -- local cur_g = 0 - -- local cur_glue = 0.0 - -- - -- local width, stretch, shrink, stretch_order, shrink_order = getglue(current) - -- if g_sign == 1 then -- stretching - -- if stretch_order == g_order then - -- -- rule_wd = width - cur_g - -- -- cur_glue = cur_glue + stretch - -- -- cur_g = g_set * cur_glue - -- -- rule_wd = rule_wd + cur_g - -- rule_ht = width + g_set * stretch - -- else - -- rule_wd = width - -- end - -- else - -- if shrink_order == g_order then - -- -- rule_wd = width - cur_g - -- -- cur_glue = cur_glue - shrink - -- -- cur_g = g_set * cur_glue - -- -- rule_wd = rule_wd + cur_g - -- rule_ht = width - g_set * shrink - -- else - -- rule_wd = width - -- end - -- end - local function applyanchor(orientation,x,y,width,height,depth,woffset,hoffset,doffset,xoffset,yoffset) local ot = extract(orientation, 0,4) local ay = extract(orientation, 4,4) @@ -508,8 +472,6 @@ local hlist_out, vlist_out do -- to be checked: begin- or enddir kan nil zijn, weird - rangedimensions = node.direct.naturalwidth or rangedimensions - local function calculate_width_to_enddir(this_box,begindir) -- can be a helper local dir_nest = 1 local enddir = begindir @@ -545,9 +507,6 @@ local hlist_out, vlist_out do local boxwidth, boxheight, boxdepth = getwhd(this_box) - local g_set, - g_order, - g_sign = getboxglue(this_box) local cur_h = 0 local cur_v = 0 @@ -556,12 +515,14 @@ local hlist_out, vlist_out do current = getlist(this_box) end - while current do - local char, id = isglyph(current) - if char then + -- we can encounter localpar, boundary and penalty nodes but a special + -- iterator over content nodes won't save much + + for current, id, subtype in nextnode, current do + if id == glyph_code then + local char, font = isglyph(current) local x_offset, y_offset = getoffsets(current) if x_offset ~= 0 or y_offset ~= 0 then - -- synch_pos_with_cur(ref_h, ref_v, cur_h + x_offset, cur_v - y_offset) if pos_r == righttoleft_code then pos_h = ref_h - (cur_h + x_offset) else @@ -570,99 +531,98 @@ local hlist_out, vlist_out do pos_v = ref_v - (cur_v - y_offset) -- synced end - local wd, ht, dp = flush_character(current,id,char,false,true,pos_h,pos_v,pos_r) + local wd, ht, dp = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r) cur_h = cur_h + wd elseif id == glue_code then - local gluewidth - if g_sign == 0 then - gluewidth = getwidth(current) - else - gluewidth = effectiveglue(current,this_box) - end + local gluewidth = effectiveglue(current,this_box) if gluewidth ~= 0 then - local leader = getleader(current) - if leader then - local width, height, depth = getwhd(leader) - if getid(leader) == rule_code then - if gluewidth > 0 then - if height == running then - height = boxheight - end - if depth == running then - depth = boxdepth + if subtype >= leaders_code then + local leader = getleader(current) + if leader then + local width, height, depth = getwhd(leader) + if getid(leader) == rule_code then + if gluewidth > 0 then + if height == running then + height = boxheight + end + if depth == running then + depth = boxdepth + end + local total = height + depth + if total > 0 then + if pos_r == righttoleft_code then + pos_h = pos_h - gluewidth + end + pos_v = pos_v - depth + flushrule(leader,pos_h,pos_v,pos_r,gluewidth,total,getsubtype(leader)) + end + cur_h = cur_h + gluewidth end - local total = height + depth - if total > 0 then + elseif width > 0 and gluewidth > 0 then + local boxdir = getdirection(leader) or lefttoright_code + gluewidth = gluewidth + 10 + local edge = cur_h + gluewidth + local lx = 0 + -- local subtype = getsubtype(current) + if subtype == gleaders_code then + local save_h = cur_h if pos_r == righttoleft_code then - pos_h = pos_h - gluewidth + cur_h = ref_h - shipbox_h - cur_h + cur_h = width * (cur_h / width) + cur_h = ref_h - shipbox_h - cur_h + else + cur_h = cur_h + ref_h - shipbox_h + cur_h = width * (cur_h / width) + cur_h = cur_h - ref_h - shipbox_h end - pos_v = pos_v - depth - flushrule(leader,pos_h,pos_v,pos_r,gluewidth,total) - end - cur_h = cur_h + gluewidth - end - elseif width > 0 and gluewidth > 0 then - local boxdir = getdirection(leader) or lefttoright_code - gluewidth = gluewidth + 10 - local edge = cur_h + gluewidth - local lx = 0 - local subtype = getsubtype(current) - if subtype == gleader_code then - local save_h = cur_h - if pos_r == righttoleft_code then - cur_h = ref_h - shipbox_h - cur_h + if cur_h < save_h then + cur_h = cur_h + width + end + elseif subtype == leaders_code then + local save_h = cur_h cur_h = width * (cur_h / width) - cur_h = ref_h - shipbox_h - cur_h + if cur_h < save_h then + cur_h = cur_h + width + end else - cur_h = cur_h + ref_h - shipbox_h - cur_h = width * (cur_h / width) - cur_h = cur_h - ref_h - shipbox_h - end - if cur_h < save_h then - cur_h = cur_h + width + lq = gluewidth / width + lr = gluewidth % width + if subtype == cleaders_code then + cur_h = cur_h + lr / 2 + else + lx = lr / (lq + 1) + cur_h = cur_h + (lr - (lq - 1) * lx) / 2 + end end - elseif subtype == leader_code then -- aleader ? - local save_h = cur_h - cur_h = width * (cur_h / width) - if cur_h < save_h then - cur_h = cur_h + width + local shift = getshift(leader) + while cur_h + width <= edge do + local basepoint_h = 0 + -- local basepoint_v = shift + if boxdir ~= pos_r then + basepoint_h = boxwidth + end + -- synch_pos_with_cur(ref_h,ref_v,cur_h + basepoint_h,shift) + if pos_r == righttoleft_code then + pos_h = ref_h - (cur_h + basepoint_h) + else + pos_h = ref_h + (cur_h + basepoint_h) + end + pos_v = ref_v - shift + -- synced + outer_doing_leaders = doing_leaders + doing_leaders = true + if getid(leader) == vlist_code then + vlist_out(leader) + else + hlist_out(leader) + end + doing_leaders = outer_doing_leaders + cur_h = cur_h + width + lx end + cur_h = edge - 10 else - lq = gluewidth / width - lr = gluewidth % width - if subtype == cleader_code then - cur_h = cur_h + lr / 2 - else - lx = lr / (lq + 1) - cur_h = cur_h + (lr - (lq - 1) * lx) / 2 - end - end - local shift = getshift(leader) - while cur_h + width <= edge do - local basepoint_h = 0 - -- local basepoint_v = shift - if boxdir ~= pos_r then - basepoint_h = boxwidth - end - -- synch_pos_with_cur(ref_h,ref_v,cur_h + basepoint_h,shift) - if pos_r == righttoleft_code then - pos_h = ref_h - (cur_h + basepoint_h) - else - pos_h = ref_h + (cur_h + basepoint_h) - end - pos_v = ref_v - shift - -- synced - outer_doing_leaders = doing_leaders - doing_leaders = true - if getid(leader) == vlist_code then - vlist_out(leader) - else - hlist_out(leader) - end - doing_leaders = outer_doing_leaders - cur_h = cur_h + width + lx + cur_h = cur_h + gluewidth end - cur_h = edge - 10 else cur_h = cur_h + gluewidth end @@ -671,21 +631,14 @@ local hlist_out, vlist_out do end end elseif id == hlist_code or id == vlist_code then - -- w h d dir l, s, o = getall(current) local boxdir = getdirection(current) or lefttoright_code local width, height, depth = getwhd(current) local list = getlist(current) if list then local shift, orientation = getshift(current) if not orientation then - -- - -- local width, height, depth, list, boxdir, shift, orientation = getall(current) - -- if list then - -- if not orientation then - -- local basepoint_h = boxdir ~= pos_r and width or 0 -- local basepoint_v = shift - -- synch_pos_with_cur(ref_h,ref_v,cur_h + basepoint_h,shift) if pos_r == righttoleft_code then pos_h = ref_h - (cur_h + basepoint_h) else @@ -702,7 +655,6 @@ local hlist_out, vlist_out do local orientation, xoffset, yoffset = getorientation(current) local basepoint_h = boxdir ~= pos_r and width or 0 -- local basepoint_v = shift - -- synch_pos_with_cur(ref_h,ref_v,cur_h + basepoint_h + xoffset,shift - yoffset) if pos_r == righttoleft_code then pos_h = ref_h - (cur_h + basepoint_h + xoffset) else @@ -733,7 +685,6 @@ local hlist_out, vlist_out do basepoint_v = basepoint_v - height end end - -- synch_pos_with_cur(ref_h,ref_v,cur_h+basepoint_h,cur_v + basepoint_v) if pos_r == righttoleft_code then pos_h = ref_h - (cur_h + basepoint_h) else @@ -752,12 +703,12 @@ local hlist_out, vlist_out do end cur_h = cur_h + width elseif id == disc_code then - local replace = getfield(current,"replace") - if replace and getsubtype(current) ~= select_disc then + local replace, tail = getreplace(current) + if replace and subtype ~= select_disc then -- we could flatten .. no gain - setlink(findtail(replace),getnext(current)) + setlink(tail,getnext(current)) setlink(current,replace) - setfield(current,"replace") + setreplace(current) end elseif id == kern_code then local kern, factor = getkern(current,true) @@ -769,7 +720,6 @@ local hlist_out, vlist_out do end end elseif id == rule_code then - -- w h d x y = getall(current) local width, height, depth = getwhd(current) if width > 0 then if height == running then @@ -794,19 +744,17 @@ local hlist_out, vlist_out do xoffset = - xoffset end pos_v = pos_v - depth - flushrule(current,pos_h + xoffset,pos_v + yoffset,pos_r,width,total) + flushrule(current,pos_h + xoffset,pos_v + yoffset,pos_r,width,total,subtype) end cur_h = cur_h + width end elseif id == math_code then - local kern = getkern(current) - if kern ~= 0 then - cur_h = cur_h + kern - elseif g_sign == 0 then - cur_h = cur_h + getwidth(current) - else - cur_h = cur_h + effectiveglue(current,this_box) - end + -- local kern = getkern(current) + -- if kern ~= 0 then + -- cur_h = cur_h + kern + -- else + cur_h = cur_h + effectiveglue(current,this_box) + -- end elseif id == dir_code then -- we normally have proper begin-end pairs -- a begin without end is (silently) handled @@ -834,7 +782,6 @@ local hlist_out, vlist_out do ds.ref_v = ref_v setdirection(enddir,pos_r) end - -- synch_pos_with_cur(ref_h,ref_v,cur_h,cur_v) if pos_r == righttoleft_code then pos_h = ref_h - cur_h else @@ -849,20 +796,19 @@ local hlist_out, vlist_out do pos_r = dir end elseif id == whatsit_code then - local subtype = getsubtype(current) if subtype == literalwhatsit_code then - flushpdfliteral(current,pos_h,pos_v) + flushliteral(current,pos_h,pos_v) elseif subtype == lateluawhatsit_code then flushlatelua(current,pos_h,pos_v,cur_h,cur_v) elseif subtype == setmatrixwhatsit_code then - flushpdfsetmatrix(current,pos_h,pos_v) + flushsetmatrix(current,pos_h,pos_v) elseif subtype == savewhatsit_code then - flushpdfsave(current,pos_h,pos_v) + flushsave(current,pos_h,pos_v) elseif subtype == restorewhatsit_code then - flushpdfrestore(current,pos_h,pos_v) + flushrestore(current,pos_h,pos_v) elseif subtype == saveposwhatsit_code then - last_position_x = pos_h -- or pdf_h - last_position_y = pos_v -- or pdf_v + last_position_x = pos_h + last_position_y = pos_v elseif subtype == writewhatsit_code then flushwriteout(current) elseif subtype == closewhatsit_code then @@ -873,8 +819,6 @@ local hlist_out, vlist_out do elseif id == marginkern_code then cur_h = cur_h + getkern(current) end - current = getnext(current) - -- synch_pos_with_cur(ref_h, ref_v, cur_h, cur_v) -- already done in list so skip if pos_r == righttoleft_code then pos_h = ref_h - cur_h else @@ -899,16 +843,12 @@ local hlist_out, vlist_out do local boxwidth, boxheight, boxdepth = getwhd(this_box) - local g_set, - g_order, - g_sign = getboxglue(this_box) local cur_h = 0 local cur_v = - boxheight local top_edge = cur_v - -- synch_pos_with_cur(ref_h, ref_v, cur_h, cur_v) if pos_r == righttoleft_code then pos_h = ref_h - cur_h else @@ -925,104 +865,96 @@ local hlist_out, vlist_out do -- local id = getid(current) for current, id, subtype in nextnode, current do if id == glue_code then - local glueheight - if g_sign == 0 then - glueheight = getwidth(current) - else - glueheight = effectiveglue(current,this_box) - end - local leader = getleader(current) - if leader then - local width, height, depth = getwhd(leader) - local total = height + depth - if getid(leader) == rule_code then - depth = 0 -- hm - if total > 0 then - if width == running then - width = boxwidth - end - if width > 0 then - if pos_r == righttoleft_code then - cur_h = cur_h - width - end - flushrule(leader,pos_h,pos_v - total,pos_r,width,total) - end - cur_v = cur_v + total - end - else - if total > 0 and glueheight > 0 then - glueheight = glueheight + 10 - local edge = cur_v + glueheight - local ly = 0 - if subtype == gleader_code then - save_v = cur_v - cur_v = ref_v - shipbox_v - cur_v - cur_v = total * (cur_v / total) - cur_v = ref_v - shipbox_v - cur_v - if cur_v < save_v then - cur_v = cur_v + total - end - elseif subtype == leader_code then -- aleader - save_v = cur_v - cur_v = top_edge + total * ((cur_v - top_edge) / total) - if cur_v < save_v then + local glueheight = effectiveglue(current,this_box) + if glueheight ~= 0 then + if subtype >= leaders_code then + local leader = getleader(current) + if leader then + local width, height, depth = getwhd(leader) + local total = height + depth + if getid(leader) == rule_code then + depth = 0 -- hm + if total > 0 then + if width == running then + width = boxwidth + end + if width > 0 then + if pos_r == righttoleft_code then + cur_h = cur_h - width + end + flushrule(leader,pos_h,pos_v - total,pos_r,width,total,getsubtype(leader)) + end cur_v = cur_v + total end - else - lq = glueheight / total - lr = glueheight % total - if subtype == cleaders_code then - cur_v = cur_v + lr / 2 - else - ly = lr / (lq + 1) - cur_v = cur_v + (lr - (lq - 1) * ly) / 2 - end - end - local shift = getshift(leader) - while cur_v + total <= edge do -- todo: <= edge - total - -- synch_pos_with_cur(ref_h, ref_v, getshift(leader), cur_v + height) - if pos_r == righttoleft_code then - pos_h = ref_h - shift + elseif total > 0 and glueheight > 0 then + glueheight = glueheight + 10 + local edge = cur_v + glueheight + local ly = 0 + if subtype == gleaders_code then + save_v = cur_v + cur_v = ref_v - shipbox_v - cur_v + cur_v = total * (cur_v / total) + cur_v = ref_v - shipbox_v - cur_v + if cur_v < save_v then + cur_v = cur_v + total + end + elseif subtype == leaders_code then -- aleader + save_v = cur_v + cur_v = top_edge + total * ((cur_v - top_edge) / total) + if cur_v < save_v then + cur_v = cur_v + total + end else - pos_h = ref_h + shift + lq = glueheight / total + lr = glueheight % total + if subtype == cleaders_code then + cur_v = cur_v + lr / 2 + else + ly = lr / (lq + 1) + cur_v = cur_v + (lr - (lq - 1) * ly) / 2 + end end - pos_v = ref_v - (cur_v + height) - -- synced - outer_doing_leaders = doing_leaders - doing_leaders = true - if getid(leader) == vlist_code then - vlist_out(leader) - else - hlist_out(leader) + local shift = getshift(leader) + while cur_v + total <= edge do -- todo: <= edge - total + -- synch_pos_with_cur(ref_h, ref_v, getshift(leader), cur_v + height) + if pos_r == righttoleft_code then + pos_h = ref_h - shift + else + pos_h = ref_h + shift + end + pos_v = ref_v - (cur_v + height) + -- synced + outer_doing_leaders = doing_leaders + doing_leaders = true + if getid(leader) == vlist_code then + vlist_out(leader) + else + hlist_out(leader) + end + doing_leaders = outer_doing_leaders + cur_v = cur_v + total + ly end - doing_leaders = outer_doing_leaders - cur_v = cur_v + total + ly + cur_v = edge - 10 + else + cur_v = cur_v + glueheight end - cur_v = edge - 10 - else - cur_v = cur_v + glueheight end + else + cur_v = cur_v + glueheight end - else - cur_v = cur_v + glueheight end elseif id == hlist_code or id == vlist_code then - -- w h d dir l, s, o = getall(current) local boxdir = getdirection(current) or lefttoright_code local width, height, depth = getwhd(current) local list = getlist(current) if list then local shift, orientation = getshift(current) if not orientation then --- local width, height, depth, list, boxdir, shift, orientation = getall(current) --- if list then --- if not orientation then -- local basepoint_h = shift -- local basepoint_v = height if boxdir ~= pos_r then shift = shift + width end - -- synch_pos_with_cur(ref_h,ref_v,shift,cur_v + height) if pos_r == righttoleft_code then pos_h = ref_h - shift else @@ -1042,7 +974,6 @@ local hlist_out, vlist_out do if boxdir ~= pos_r then shift = shift + width end - -- synch_pos_with_cur(ref_h,ref_v,shift + xoffset,cur_v + height - yoffset) if pos_r == righttoleft_code then pos_h = ref_h - (shift + xoffset) else @@ -1067,7 +998,6 @@ local hlist_out, vlist_out do elseif orientation == 3 then -- weird basepoint_h = basepoint_h + height end - -- synch_pos_with_cur(ref_h,ref_v,basepoint_h,cur_v + basepoint_v) if pos_r == righttoleft_code then pos_h = ref_h - basepoint_h else @@ -1088,7 +1018,6 @@ local hlist_out, vlist_out do elseif id == kern_code then cur_v = cur_v + getkern(current) elseif id == rule_code then - -- w h d x y = getall(current) local width, height, depth = getwhd(current) local total = height + depth if total > 0 then @@ -1108,24 +1037,24 @@ local hlist_out, vlist_out do cur_h = cur_h - width xoffset = - xoffset end - flushrule(current,pos_h + xoffset,pos_v - total - yoffset,pos_r,width,total) + flushrule(current,pos_h + xoffset,pos_v - total - yoffset,pos_r,width,total,subtype) end cur_v = cur_v + total end elseif id == whatsit_code then if subtype == literalwhatsit_code then - flushpdfliteral(current,pos_h,pos_v) + flushliteral(current,pos_h,pos_v) elseif subtype == lateluawhatsit_code then flushlatelua(current,pos_h,pos_v,cur_h,cur_v) elseif subtype == setmatrixwhatsit_code then - flushpdfsetmatrix(current,pos_h,pos_v) + flushsetmatrix(current,pos_h,pos_v) elseif subtype == savewhatsit_code then - flushpdfsave(current,pos_h,pos_v) + flushsave(current,pos_h,pos_v) elseif subtype == restorewhatsit_code then - flushpdfrestore(current,pos_h,pos_v) + flushrestore(current,pos_h,pos_v) elseif subtype == saveposwhatsit_code then - last_position_x = pos_h -- or pdf_h - last_position_y = pos_v -- or pdf_v + last_position_x = pos_h + last_position_y = pos_v elseif subtype == writewhatsit_code then flushwriteout(current) elseif subtype == closewhatsit_code then @@ -1134,7 +1063,6 @@ local hlist_out, vlist_out do flushopenout(current) end end - -- synch_pos_with_cur(ref_h, ref_v, cur_h, cur_v) if pos_r == righttoleft_code then pos_h = ref_h - cur_h else @@ -1150,19 +1078,17 @@ local hlist_out, vlist_out do end -function lpdf.convert(box,smode,objnum,specification) -- temp name +function drivers.converters.lmtx(driver,box,smode,objnum,specification) - if box then - box = tonut(box) - else - report("error in converter, no box") + if not driver then + report("error in converter, no driver") return end - local driver = instances.pdf - if driver then - -- tracing + if box then + box = tonut(box) else + report("error in converter, no box") return end @@ -1171,7 +1097,8 @@ function lpdf.convert(box,smode,objnum,specification) -- temp name initialize = actions.initialize finalize = actions.finalize - updatefontstate = actions.updatefontstate + + updatefontstate = flushers.updatefontstate pushorientation = flushers.pushorientation poporientation = flushers.poporientation @@ -1180,17 +1107,19 @@ function lpdf.convert(box,smode,objnum,specification) -- temp name flushrule = flushers.rule flushsimplerule = flushers.simplerule flushspecial = flushers.special - flushpdfliteral = flushers.pdfliteral - flushpdfsetmatrix = flushers.pdfsetmatrix - flushpdfsave = flushers.pdfsave - flushpdfrestore = flushers.pdfrestore - -- flushpdfimage = flushers.pdfimage + flushliteral = flushers.literal + flushsetmatrix = flushers.setmatrix + flushsave = flushers.save + flushrestore = flushers.restore + -- flushimage = flushers.image reset_dir_stack() reset_state() shippingmode = smode + local details = nil -- must be outside labels + local width, height, depth = getwhd(box) local total = height + depth @@ -1222,7 +1151,9 @@ function lpdf.convert(box,smode,objnum,specification) -- temp name -- We have zero offsets in ConTeXt. local pagewidth, pageheight = getpagedimensions() - -- local h_offset_par, v_offset_par = texget("hoffset"), texget("voffset") + + -- local h_offset_par = texget("hoffset") + -- local v_offset_par = texget("voffset") -- page_h_origin = trueinch -- page_v_origin = trueinch @@ -1252,12 +1183,7 @@ function lpdf.convert(box,smode,objnum,specification) -- temp name local refpoint_h = 0 -- + page_h_origin + h_offset_par local refpoint_v = page_size_v -- - page_v_origin - v_offset_par - -- synch_pos_with_cur(refpoint_h,refpoint_v,0,height) - if pos_r == righttoleft_code then - pos_h = refpoint_h - else - pos_h = refpoint_h - end + pos_h = refpoint_h pos_v = refpoint_v - height -- synced @@ -1276,12 +1202,16 @@ function lpdf.convert(box,smode,objnum,specification) -- temp name shipbox_ref_h = pos_h shipbox_ref_v = pos_v - initialize { - shippingmode = smode, -- target - boundingbox = { 0, 0, page_size_h, page_size_v }, - objectnumber = objnum, + details = { + shippingmode = smode, -- target + boundingbox = { 0, 0, page_size_h, page_size_v }, + objectnumber = smode ~= "page" and objnum or nil, + pagenumber = smode == "page" and objnum or nil, + specification = specification, } + initialize(driver,details) + lastfont = nil -- this forces a sync each page / object if getid(box) == vlist_code then @@ -1292,7 +1222,8 @@ function lpdf.convert(box,smode,objnum,specification) -- temp name ::DONE:: - finalize(objnum,specification) + finalize(driver,details) + shippingmode = "none" end diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv index abf9d709a..83681580e 100644 --- a/tex/context/base/mkiv/grph-inc.mkiv +++ b/tex/context/base/mkiv/grph-inc.mkiv @@ -982,6 +982,10 @@ \unexpanded\def\inlinefigure[#1]{\dontleavehmode\sbox{\externalfigure[#1][\v!inline]}} +%D Needs to be done global: + +\definelayer[epdfcontent] + \protect \endinput %D Moved here because this already old code is nowhere documents (so I need to check diff --git a/tex/context/base/mkiv/lpdf-eng.lua b/tex/context/base/mkiv/lpdf-eng.lua index 6f2e75c46..42435fad5 100644 --- a/tex/context/base/mkiv/lpdf-eng.lua +++ b/tex/context/base/mkiv/lpdf-eng.lua @@ -63,7 +63,7 @@ img = table.setmetatableindex ( do - local function prepare() + local function prepare(driver) if not environment.initex then -- install new functions in pdf namespace updaters.apply("backend.update.pdf") @@ -77,29 +77,23 @@ do end end - local function outputfilename() + local function outputfilename(driver) if not filename then filename = addsuffix(tex.jobname,"pdf") end return filename end - function lpdf.flushers() - return { } - end - - function lpdf.actions() - return { - convert = tex.shipout, - outputfilename = outputfilename, - prepare = prepare, - } - end - drivers.install { name = "pdf", - flushers = lpdf.flushers(), - actions = lpdf.actions(), + flushers = { + -- nothing here + }, + actions = { + convert = drivers.converters.engine, + outputfilename = outputfilename, + prepare = prepare, + }, } end diff --git a/tex/context/base/mkiv/lpdf-epa.lua b/tex/context/base/mkiv/lpdf-epa.lua index 7ec331554..45000aebc 100644 --- a/tex/context/base/mkiv/lpdf-epa.lua +++ b/tex/context/base/mkiv/lpdf-epa.lua @@ -72,7 +72,7 @@ local maxdimen = 0x3FFFFFFF -- 2^30-1 local bpfactor = number.dimenfactors.bp -local layerspec = { -- predefining saves time +local layerspec = { "epdfcontent" } @@ -143,11 +143,18 @@ end local layerused = false +-- local function initializelayer(height,width) +-- if not layerused then +-- context.definelayer(layerspec, { height = height .. "bp", width = width .. "bp" }) +-- layerused = true +-- end +-- end + local function initializelayer(height,width) - if not layerused then - context.definelayer(layerspec, { height = height .. "bp", width = width .. "bp" }) +-- if not layerused then + context.setuplayer(layerspec, { height = height .. "bp", width = width .. "bp" }) layerused = true - end +-- end end function codeinjections.flushmergelayer() diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua index 25a73fe67..8fdbf9a36 100644 --- a/tex/context/base/mkiv/lpdf-lmt.lua +++ b/tex/context/base/mkiv/lpdf-lmt.lua @@ -8,6 +8,15 @@ if not modules then modules = { } end modules ['lpdf-lmt'] = { -- The code below was originally in back-lpd.lua but it makes more sense in -- this namespace. I will rename variables. +-- +-- There is no way that a lua based backend can compete with the original one +-- for relative simple text runs. And we're talking seconds here on say 500 +-- pages with paragraphs alternativng between three fonts and colors. But such +-- documents are rare so in practice we are quite okay, especially because in +-- ConTeXt we can gain quite a bit elsewhere. So, when we loose 30% on such +-- simple documents, we break even on for instance the manual, and gain 30% on +-- Thomas's turture test (also for other reasons). But .. who knows what magic +-- I can cook up in due time. if CONTEXTLMTXMODE == 0 then return @@ -33,7 +42,7 @@ local band, extract = bit32.band, bit32.extract local concat, sortedhash = table.concat, table.sortedhash local setmetatableindex = table.setmetatableindex -local bpfactor = number.dimenfactors.bp +local bpfactor = number.dimenfactors.bp local md5HEX = md5.HEX local osuuid = os.uuid @@ -244,29 +253,20 @@ local function calc_pdfpos(h,v) if mode == "page" then cmtx = h - pdf_h cmty = v - pdf_v - if h ~= pdf_h or v ~= pdf_v then - return true - end + return h ~= pdf_h or v ~= pdf_v elseif mode == "text" then tmtx = h - saved_text_pos_h tmty = v - saved_text_pos_v - if h ~= pdf_h or v ~= pdf_v then - return true - end + return h ~= pdf_h or v ~= pdf_v elseif horizontalmode then tmty = v - saved_text_pos_v tj_delta = cw - h -- + saved_chararray_pos_h - if tj_delta ~= 0 or v ~= pdf_v then - return true - end + return tj_delta ~= 0 or v ~= pdf_v else tmtx = h - saved_text_pos_h tj_delta = cw + v -- - saved_chararray_pos_v - if tj_delta ~= 0 or h ~= pdf_h then - return true - end + return tj_delta ~= 0 or h ~= pdf_h end - return false end local function pdf_set_pos(h,v) @@ -316,12 +316,14 @@ local function pdf_set_pos_temp(h,v) end end +-- these dummy returns makes using them a bit faster + local function pdf_end_string_nl() if mode == "char" then end_charmode() - end_chararray() + return end_chararray() elseif mode == "chararray" then - end_chararray() + return end_chararray() end end @@ -329,13 +331,13 @@ local function pdf_goto_textmode() if mode == "page" then -- pdf_set_pos(0,0) pdf_reset_pos() - begin_text() + return begin_text() elseif mode ~= "text" then if mode == "char" then end_charmode() - end_chararray() + return end_chararray() else -- if mode == "chararray" then - end_chararray() + return end_chararray() end end end @@ -345,12 +347,12 @@ local function pdf_goto_pagemode() if mode == "char" then end_charmode() end_chararray() - end_text() + return end_text() elseif mode == "chararray" then end_chararray() - end_text() + return end_text() elseif mode == "text" then - end_text() + return end_text() end end end @@ -411,6 +413,49 @@ local flushcharacter do end end + -- This only saves a little on hz because there we switch a lot of + -- instances. + + -- local lastslant, lastextend, lastsqueeze, lastformat, lastsize, lastwidth, lastmode, lastused, lastfont + -- + -- local function setup_fontparameters(font,factor,f,e) + -- if font ~= lastfont then + -- lastslant = (fontparameters.slantfactor or 0) / 1000 + -- lastextend = (fontparameters.extendfactor or 1000) / 1000 + -- lastsqueeze = (fontparameters.squeezefactor or 1000) / 1000 + -- lastformat = fontproperties.format + -- lastsize = fontparameters.size * bpfactor + -- if format == "opentype" or format == "type1" then + -- lastsize = lastsize * 1000 / fontparameters.units -- can we avoid this ? + -- end + -- lastwidth = fontparameters.width + -- lastmode = fontparameters.mode + -- lastused = usedfonts[font] -- cache + -- lastfont = font + -- end + -- local expand = 1 + factor / 1000000 + -- if e then + -- tmrx = expand * lastextend * e + -- else + -- tmrx = expand * lastextend + -- end + -- tmsy = lastslant + -- tmry = lastsqueeze + -- need_width = lastwidth + -- need_mode = lastmode + -- f_cur = lastfont + -- f_pdf = lastused + -- cur_factor = factor + -- cur_f = f + -- cur_e = e + -- tj_delta = 0 + -- if f then + -- fs = lastsize * f + -- else + -- fs = lastsize + -- end + -- end + local f_width = formatters["%.6F w"] local f_mode = formatters["%i Tr"] local f_font = formatters["/F%i %.6F Tf"] @@ -455,15 +500,23 @@ local flushcharacter do cur_tmrx = tmrx end - local f_skip = formatters["%.1f"] + -- local f_skip = formatters["%.1f"] -- local f_octal = formatters["\\%o"] -- local f_char = formatters["%c"] local f_hex = formatters["%04X"] local h_hex = setmetatableindex(function(t,k) -- we already have this somewhere - local v = f_hex(k) - t[k] = v - return v + if k < 256 then + -- not sparse in this range + for i=0,255 do + t[i] = f_hex(i) + end + return t[k] + else + local v = f_hex(k) + t[k] = v + return v + end end) flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e) @@ -535,7 +588,9 @@ local flushcharacter do cw = cw + naturalwidth +if not pdfcharacters[index] then pdfcharacters[index] = true +end end @@ -543,20 +598,19 @@ end -- literals -local flushpdfliteral do +local flushliteral do - local literalvalues = nodes.literalvalues + local nodeproperties = nodes.properties.data + local literalvalues = nodes.literalvalues - local originliteral_code = literalvalues.origin - local pageliteral_code = literalvalues.page - local alwaysliteral_code = literalvalues.always - local rawliteral_code = literalvalues.raw - local textliteral_code = literalvalues.text - local fontliteral_code = literalvalues.font + local originliteral_code = literalvalues.origin + local pageliteral_code = literalvalues.page + local alwaysliteral_code = literalvalues.always + local rawliteral_code = literalvalues.raw + local textliteral_code = literalvalues.text + local fontliteral_code = literalvalues.font - local nodeproperties = nodes.properties.data - - flushpdfliteral = function(current,pos_h,pos_v,mode,str) + flushliteral = function(current,pos_h,pos_v,mode,str) if mode then if not str then mode, str = originliteral_code, mode @@ -650,7 +704,7 @@ end -- grouping & orientation -local flushpdfsave, flushpdfrestore, flushpdfsetmatrix do +local flushsave, flushrestore, flushsetmatrix do local matrices = { } local positions = { } @@ -659,7 +713,7 @@ local flushpdfsave, flushpdfrestore, flushpdfsetmatrix do local f_matrix = formatters["%s 0 0 cm"] - flushpdfsave = function(current,pos_h,pos_v) + flushsave = function(current,pos_h,pos_v) nofpositions = nofpositions + 1 positions[nofpositions] = { pos_h, pos_v, nofmatrices } pdf_goto_pagemode() @@ -667,7 +721,7 @@ local flushpdfsave, flushpdfrestore, flushpdfsetmatrix do b = b + 1 ; buffer[b] = "q" end - flushpdfrestore = function(current,pos_h,pos_v) + flushrestore = function(current,pos_h,pos_v) if nofpositions < 1 then return end @@ -705,7 +759,7 @@ local flushpdfsave, flushpdfrestore, flushpdfsetmatrix do local nodeproperties = nodes.properties.data - flushpdfsetmatrix = function(current,pos_h,pos_v) + flushsetmatrix = function(current,pos_h,pos_v) local str if type(current) == "string" then str = current @@ -766,44 +820,45 @@ local flushpdfsave, flushpdfrestore, flushpdfsetmatrix do end -- pushorientation = function(orientation,pos_h,pos_v,pos_r) --- flushpdfsave(false,pos_h,pos_v) +-- flushsave(false,pos_h,pos_v) -- if orientation == 1 then --- flushpdfsetmatrix("0 -1 1 0",pos_h,pos_v) +-- flushsetmatrix("0 -1 1 0",pos_h,pos_v) -- elseif orientation == 2 then --- flushpdfsetmatrix("-1 0 0 -1",pos_h,pos_v) +-- flushsetmatrix("-1 0 0 -1",pos_h,pos_v) -- elseif orientation == 3 then --- flushpdfsetmatrix("0 1 -1 0",pos_h,pos_v) +-- flushsetmatrix("0 1 -1 0",pos_h,pos_v) -- end -- end -- poporientation = function(orientation,pos_h,pos_v,pos_r) --- flushpdfrestore(false,pos_h,pos_v) +-- flushrestore(false,pos_h,pos_v) -- end end -- rules -local flushedxforms = { } -- actually box resources but can also be direct +local flushedxforms = { } -- actually box resources but can also be direct +local localconverter = nil -- will be set -local flushrule, flushsimplerule, flushpdfimage do +local flushrule, flushsimplerule, flushimage do - local rulecodes = nodes.rulecodes - local newrule = nodes.pool.rule + local rulecodes = nodes.rulecodes + local newrule = nodes.pool.rule - local setprop = nuts.setprop - local getprop = nuts.getprop + local setprop = nuts.setprop + local getprop = nuts.getprop - local normalrule_code = rulecodes.normal - local boxrule_code = rulecodes.box - local imagerule_code = rulecodes.image - local emptyrule_code = rulecodes.empty - local userrule_code = rulecodes.user - local overrule_code = rulecodes.over - local underrule_code = rulecodes.under - local fractionrule_code = rulecodes.fraction - local radicalrule_code = rulecodes.radical - local outlinerule_code = rulecodes.outline + local normalrule_code = rulecodes.normal + local boxrule_code = rulecodes.box + local imagerule_code = rulecodes.image + local emptyrule_code = rulecodes.empty + local userrule_code = rulecodes.user + local overrule_code = rulecodes.over + local underrule_code = rulecodes.under + local fractionrule_code = rulecodes.fraction + local radicalrule_code = rulecodes.radical + local outlinerule_code = rulecodes.outline local rule_callback = callbacks.functions.process_rule @@ -869,7 +924,7 @@ local flushrule, flushsimplerule, flushpdfimage do } boxresources[objnum] = l if immediate then - lpdf.convert(list,"xform",objnum,l) + localconverter(list,"xform",objnum,l) flushedxforms[objnum] = { true , objnum } flushlist(list) else @@ -959,13 +1014,13 @@ local flushrule, flushsimplerule, flushpdfimage do -- place image also used in vf but we can use a different one if -- we need it - local imagetypes = images.types -- pdf png jpg jp2 jbig2 stream memstream - local img_none = imagetypes.none - local img_pdf = imagetypes.pdf - local img_stream = imagetypes.stream - local img_memstream = imagetypes.memstream + local imagetypes = images.types -- pdf png jpg jp2 jbig2 stream memstream + local img_none = imagetypes.none + local img_pdf = imagetypes.pdf + local img_stream = imagetypes.stream + local img_memstream = imagetypes.memstream - local one_bp = 65536 * bpfactor + local one_bp = 65536 * bpfactor local imageresources, n = { }, 0 @@ -1085,7 +1140,7 @@ local flushrule, flushsimplerule, flushpdfimage do b = b + 1 ; buffer[b] = s_e end - flushpdfimage = function(index,width,height,depth,pos_h,pos_v) + flushimage = function(index,width,height,depth,pos_h,pos_v) -- used in vf characters @@ -1122,9 +1177,8 @@ local flushrule, flushsimplerule, flushpdfimage do -- For the moment we need this hack because the engine checks the 'image' -- command in virtual fonts (so we use lua instead). - flushrule = function(current,pos_h,pos_v,pos_r,size_h,size_v) + flushrule = function(current,pos_h,pos_v,pos_r,size_h,size_v,subtype) - local subtype = getsubtype(current) if subtype == emptyrule_code then return elseif subtype == boxrule_code then @@ -1222,7 +1276,7 @@ local wrapup, registerpage do } end - wrapup = function() + wrapup = function(driver) -- hook (to reshuffle pages) local pagetree = { } @@ -1300,8 +1354,8 @@ end pdf_h, pdf_v = 0, 0 -local function initialize(specification) - reset_variables(specification) +local function initialize(driver,details) + reset_variables(details) reset_buffer() end @@ -1316,12 +1370,15 @@ local f_image = formatters["Im%d"] local pushmode, popmode -local function finalize(objnum,specification) +local function finalize(driver,details) pushmode() pdf_goto_pagemode() -- for now + local objnum = details.objnum + local specification = details.specification + local content = concat(buffer,"\n",1,b) local fonts = nil @@ -1391,7 +1448,9 @@ local function finalize(objnum,specification) 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, @@ -1451,7 +1510,7 @@ local function finalize(objnum,specification) local objnum = f[2] -- specification.objnum local specification = boxresources[objnum] local list = specification.list - lpdf.convert(list,"xform",f[2],specification) + localconverter(list,"xform",f[2],specification) end end @@ -1487,7 +1546,7 @@ local streams = { } -- maybe just parallel to objects (no holes) local nofobjects = 0 local offset = 0 local f = false -local flush = false +----- flush = false local threshold = 40 -- also #("/Filter /FlateDecode") local objectstream = true local compress = true @@ -1563,13 +1622,14 @@ end local addtocache, flushcache, cache do - local data, d = { }, 0 - local list, l = { }, 0 - local coffset = 0 - local maxsize = 32 * 1024 -- uncompressed - local maxcount = 0xFF + local data, d = { }, 0 + local list, l = { }, 0 + local coffset = 0 local indices = { } + local maxsize = 32 * 1024 -- uncompressed + local maxcount = 0xFF + addtocache = function(n,str) local size = #str if size == 0 then @@ -1621,9 +1681,9 @@ local addtocache, flushcache, cache do else b = f_stream_b_d_u(cache,strobj(),#data) end - flush(f,b) - flush(f,data) - flush(f,e) + f:write(b) + f:write(data) + f:write(e) offset = offset + #b + #data + #e data, d = { }, 0 list, l = { }, 0 @@ -1663,7 +1723,7 @@ local function flushnormalobj(data,n) if level == 0 then objects[n] = offset offset = offset + #data - flush(f,data) + f:write(data) else if not lastdeferred then lastdeferred = n @@ -1706,9 +1766,9 @@ local function flushstreamobj(data,n,dict,comp,nolength) else b = dict and f_stream_b_d_u(n,dict,size) or f_stream_b_n_u(n,size) end - flush(f,b) - flush(f,data) - flush(f,e) + f:write(b) + f:write(data) + f:write(e) objects[n] = offset offset = offset + #b + #data + #e else @@ -1746,7 +1806,7 @@ local function flushdeferred() if type(o) == "string" then objects[n] = offset offset = offset + #o - flush(f,o) + f:write(o) end end lastdeferred = false @@ -1865,6 +1925,14 @@ updaters.register("backend.update.pdf",function() pdf.immediateobj = obj end) +-- Bah, in lua 5.4 we cannot longer use flush = getmetatable(f).write as efficient +-- flusher due to some change in the metatable definitions (more indirectness) ... +-- so maybe we should introduce our own helper for this as now we get a lookup for +-- each write (and writing isn't already the fastest). A little Lua charm gone as +-- now the memory variant also needs to use this 'object' model. (Ok, the +-- is a new charm but for that to work in our advance I need to patch quite some +-- files.) + local openfile, closefile do local f_used = formatters["%010i 00000 n \010"] @@ -1878,34 +1946,45 @@ local openfile, closefile do local inmemory = false -- local inmemory = environment.arguments.inmemory - local close = nil + -- local close = nil openfile = function(filename) if inmemory then - f = { } + -- local n = 0 + -- f = { } + -- flush = function(f,s) + -- n = n + 1 f[n] = s + -- end + -- close = function(f) + -- f = concat(f) + -- io.savedata(filename,f) + -- f = false + -- end local n = 0 - flush = function(f,s) - n = n + 1 f[n] = s - end - close = function(f) - f = concat(f) - io.savedata(filename,f) - f = false - end - else + f = { + write = function(self,s) + n = n + 1 f[n] = s + end, + close = function(self) + f = concat(f) + io.savedata(filename,f) + f = false + end, + } + else f = io.open(filename,"wb") if not f then -- message os.exit() end - flush = getmetatable(f).write - close = getmetatable(f).close + -- flush = getmetatable(f).write + -- close = getmetatable(f).close end local v = f_pdf(majorversion,minorversion) -- local b = "%\xCC\xD5\xC1\xD4\xC5\xD8\xD0\xC4\xC6\010" -- LUATEXPDF (+128) local b = "%\xC3\xCF\xCE\xD4\xC5\xD8\xD4\xD0\xC4\xC6\010" -- CONTEXTPDF (+128) - flush(f,v) - flush(f,b) + f:write(v) + f:write(b) offset = #v + #b end @@ -2051,20 +2130,20 @@ local openfile, closefile do local comp = zlibcompress(data,3) if comp then data = comp - flush(f,f_stream_b_d_c(nofobjects,xref(),#data)) + f:write(f_stream_b_d_c(nofobjects,xref(),#data)) else - flush(f,f_stream_b_d_u(nofobjects,xref(),#data)) + f:write(f_stream_b_d_u(nofobjects,xref(),#data)) end else - flush(f,f_stream_b_d_u(nofobjects,xref(),#data)) + f:write(f_stream_b_d_u(nofobjects,xref(),#data)) end - flush(f,data) - flush(f,s_stream_e) - flush(f,f_startxref(xrefoffset)) + f:write(data) + f:write(s_stream_e) + f:write(f_startxref(xrefoffset)) else flushdeferred() xrefoffset = offset - flush(f,f_xref(nofobjects+1)) + f:write(f_xref(nofobjects+1)) local trailer = pdfdictionary { Size = nofobjects+1, Root = catalog, @@ -2084,16 +2163,16 @@ local openfile, closefile do end end objects[0] = f_first(lastfree) - flush(f,concat(objects,"",0,nofobjects)) + f:write(concat(objects,"",0,nofobjects)) trailer.Size = nofobjects + 1 if trailerid then - flush(f,f_trailer_id(trailer(),trailerid,trailerid,xrefoffset)) + f:write(f_trailer_id(trailer(),trailerid,trailerid,xrefoffset)) else - flush(f,f_trailer_no(trailer(),xrefoffset)) + f:write(f_trailer_no(trailer(),xrefoffset)) end end end - close(f) + f:close() io.flush() end @@ -2114,7 +2193,6 @@ updaters.register("backend.update.pdf",function() local img_none = imagetypes.none local rulecodes = nodes.rulecodes - local imagerule_code = rulecodes.image local setprop = nodes.nuts.setprop @@ -2123,7 +2201,8 @@ updaters.register("backend.update.pdf",function() local lastindex = 0 local indices = { } - local bpfactor = number.dimenfactors.bp + local bpfactor = number.dimenfactors.bp + local imagerule_code = rulecodes.image function codeinjections.newimage(specification) return specification @@ -2287,7 +2366,7 @@ updaters.register("backend.update.lpdf",function() topdf[id] = index end -- pdf.print or pdf.literal - flushpdfimage(index,wd,ht,dp,pos_h,pos_v) + flushimage(index,wd,ht,dp,pos_h,pos_v) end local function pdfvfimage(wd,ht,dp,data,name) @@ -2310,15 +2389,20 @@ do local renamefile = os.rename -- local copyfile = file.copy -- local addsuffix = file.addsuffix + local texgetbox = tex.getbox local pdfname = nil local tmpname = nil + local converter = nil + local useddriver = nil -- a bit of a hack - local function outputfilename() + local function outputfilename(driver) return pdfname end - local function prepare() + -- todo: prevent twice + + local function prepare(driver) if not environment.initex then -- install new functions in pdf namespace updaters.apply("backend.update.pdf") @@ -2343,21 +2427,29 @@ do openfile(tmpname) -- luatex.registerstopactions(1,function() - lpdf.finalizedocument() - closefile() + if pdfname then + lpdf.finalizedocument() + closefile() + end end) -- luatex.registerpageactions(1,function() - lpdf.finalizepage(true) + if pdfname then + lpdf.finalizepage(true) + end end) -- -- lpdf.registerdocumentfinalizer(wrapup,nil,"wrapping up") + -- end -- environment.lmtxmode = CONTEXTLMTXMODE + -- + converter = drivers.converters.lmtx + useddriver = driver end - local function wrapup() + local function wrapup(driver) if pdfname then local ok = true if isfile(pdfname) then @@ -2380,7 +2472,7 @@ do end end - local function cleanup() + local function cleanup(driver) if tmpname then closefile(true) if isfile(tmpname) then @@ -2391,44 +2483,42 @@ do end end - local function convert(boxnumber) - lpdf.convert(tex.box[boxnumber],"page") + local function convert(driver,boxnumber) + converter(driver,texgetbox(boxnumber),"page") + end + + localconverter = function(...) + converter(useddriver,...) end - function lpdf.flushers() - return { + drivers.install { + name = "pdf", + flushers = { character = flushcharacter, rule = flushrule, simplerule = flushsimplerule, pushorientation = pushorientation, poporientation = poporientation, -- - pdfliteral = flushpdfliteral, - pdfsetmatrix = flushpdfsetmatrix, - pdfsave = flushpdfsave, - pdfrestore = flushpdfrestore, - pdfimage = flushpdfimage, - } - end - - function lpdf.actions() - return { + literal = flushliteral, + setmatrix = flushsetmatrix, + save = flushsave, + restore = flushrestore, + image = flushimage, + -- + updatefontstate = updatefontstate, + }, + actions = { prepare = prepare, wrapup = wrapup, - convert = convert, cleanup = cleanup, -- initialize = initialize, + convert = convert, finalize = finalize, - updatefontstate = updatefontstate, + -- outputfilename = outputfilename, - } - end - - drivers.install { - name = "pdf", - flushers = lpdf.flushers(), - actions = lpdf.actions(), + }, } end diff --git a/tex/context/base/mkiv/lpdf-mis.lua b/tex/context/base/mkiv/lpdf-mis.lua index 0f51ea4f6..c5422b49e 100644 --- a/tex/context/base/mkiv/lpdf-mis.lua +++ b/tex/context/base/mkiv/lpdf-mis.lua @@ -196,6 +196,10 @@ function codeinjections.setupidentity(specification) end end +function codeinjections.getidentityvariable(name) + return identity[name] +end + local done = false -- using "setupidentity = function() end" fails as the meaning is frozen in register local function setupidentity() diff --git a/tex/context/base/mkiv/luat-cnf.lua b/tex/context/base/mkiv/luat-cnf.lua index c398b75bb..88e7a7353 100644 --- a/tex/context/base/mkiv/luat-cnf.lua +++ b/tex/context/base/mkiv/luat-cnf.lua @@ -104,7 +104,7 @@ function texconfig.init() local tv = type(gv) if tv == "table" then for k, v in next, gv do - keys[k] = tostring(v) -- true -- by tostring we cannot call overloades functions (security) + keys[k] = tostring(v) -- true -- by tostring we cannot call overloads functions (security) end end lib[v] = keys diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index 4ec3bd7c2..5222ea84f 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -7340,6 +7340,12 @@ return { ["compressdistance"]={ ["en"]="compressdistance", }, + ["compressmethod"]={ + ["en"]="compressmethod", + }, + ["compressstopper"]={ + ["en"]="compressstopper", + }, ["concerns"]={ ["en"]="concerns", ["nl"]="betreft", @@ -13122,6 +13128,9 @@ return { ["compressseparator"]={ ["en"]="compressseparator", }, + ["compressstopper"]={ + ["en"]="compressstopper", + }, ["concept"]={ ["cs"]="koncept", ["de"]="konzept", @@ -16108,6 +16117,10 @@ return { ["selectfont"]={ ["en"]="selectfont", }, + ["separator"]={ + ["en"]="separator", + ["nl"]="scheider", + }, ["september"]={ ["cs"]="zari", ["de"]="september", diff --git a/tex/context/base/mkiv/mult-def.mkiv b/tex/context/base/mkiv/mult-def.mkiv index d9404bc16..78fcdf667 100644 --- a/tex/context/base/mkiv/mult-def.mkiv +++ b/tex/context/base/mkiv/mult-def.mkiv @@ -37,9 +37,9 @@ % some left-overs -\def\c!HL {HL} -\def\c!VL {VL} -\def\c!NL {NL} +\def\c!HL{HL} +\def\c!VL{VL} +\def\c!NL{NL} % stop todo diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 2770db21f..5cd5fb373 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -254,6 +254,7 @@ return { "fixupboxesmode", "fontid", "formatname", + "frozen", "futureexpand", "futureexpandis", "gleaders", diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index dc681d165..5f2940f45 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -25,6 +25,7 @@ local getattr = nuts.getattr local getwidth = nuts.getwidth local getwhd = nuts.getwhd local getorientation = nuts.getorientation +local has_dimensions = nuts.has_dimensions local setlist = nuts.setlist local setleader = nuts.setleader @@ -182,7 +183,7 @@ local function process(attribute,head,inheritance,default) -- one attribute local leader = nil for stack, id in nextnode, head do if id == glyph_code or id == disc_code then - check = true -- disc no longer needed as we flatten replace + check = true elseif id == glue_code then leader = getleader(stack) if leader then @@ -235,8 +236,7 @@ local function process(attribute,head,inheritance,default) -- one attribute -- end nested -- end elseif id == rule_code then - local wd, ht, dp = getwhd(stack) - check = wd ~= 0 or (ht+dp) ~= 0 + check = has_dimensions(stack) end -- much faster this way than using a check() and nested() function if check then @@ -309,7 +309,7 @@ local function selective(attribute,head,inheritance,default) -- two attributes local leader = nil for stack, id, subtype in nextnode, head do if id == glyph_code or id == disc_code then - check = true -- disc no longer needed as we flatten replace + check = true elseif id == glue_code then leader = getleader(stack) if leader then @@ -374,8 +374,7 @@ local function selective(attribute,head,inheritance,default) -- two attributes -- so no redundant color stuff (only here, layers for instance should obey) check = false else - local wd, ht, dp = getwhd(stack) - check = wd ~= 0 or (ht+dp) ~= 0 + check = has_dimensions(stack) end end if check then @@ -485,8 +484,7 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, end end elseif id == rule_code then - local wd, ht, dp = getwhd(stack) - check = wd ~= 0 or (ht+dp) ~= 0 + check = has_dimensions(stack) end if check then local a = getattr(stack,attribute) @@ -571,8 +569,7 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, end end elseif id == rule_code then - local wd, ht, dp = getwhd(current) - check = wd ~= 0 or (ht+dp) ~= 0 + check = has_dimensions(current) end if check then diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua index 25254009f..1b245639b 100644 --- a/tex/context/base/mkiv/node-fnt.lua +++ b/tex/context/base/mkiv/node-fnt.lua @@ -210,12 +210,12 @@ do local usedfonts local attrfonts - local basefonts + local basefonts -- could be reused local basefont local prevfont local prevattr local variants - local redundant + local redundant -- could be reused local firstnone local lastfont local lastproc diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua index b097fb8b1..f3877d5c9 100644 --- a/tex/context/base/mkiv/node-nut.lua +++ b/tex/context/base/mkiv/node-nut.lua @@ -203,6 +203,7 @@ nuts.vpack = direct.vpack nuts.writable_spec = direct.writable_spec nuts.write = direct.write nuts.mlist_to_hlist = direct.mlist_to_hlist +nuts.has_dimensions = direct.has_dimensions if not nuts.mlist_to_hlist then @@ -219,6 +220,17 @@ if not nuts.mlist_to_hlist then end +if not nuts.has_dimensions then + + local getwhd = direct.getwhd + + function nuts.has_dimensions(n) + local wd, ht, dp = getwhd(n) + return wd ~= 0 or (ht + dp) ~= 0 + end + +end + local getfield = direct.getfield local setfield = direct.setfield @@ -254,6 +266,13 @@ nuts.setdisc = direct.setdisc nuts.getdiscretionary = direct.getdisc nuts.setdiscretionary = direct.setdisc +nuts.getpre = direct.getpre +nuts.setpre = direct.setpre +nuts.getpost = direct.getpost +nuts.setpost = direct.setpost +nuts.getreplace = direct.getreplace +nuts.setreplace = direct.setreplace + local getdata = direct.getdata local setdata = direct.setdata @@ -382,6 +401,23 @@ local remove = (CONTEXTLMTXMODE > 0 and LUATEXFUNCTIONALITY >= 20190704) and d_r return head, current end +-- for now + +if not nuts.getpre then + + local d_getdisc = direct.getdisc + local d_setfield = direct.setfield + + function nuts.getpre(d) local h, _, _, t, _, _ = d_getdisc(d,true) return h, t end + function nuts.getpost(d) local _, h, _, _, t, _ = d_getdisc(d,true) return h, t end + function nuts.getreplace(d) local _, _, h, _, _, t = d_getdisc(d,true) return h, t end + + function nuts.setpre(d,n) d_setfield("pre", n) end + function nuts.setpost(d,n) d_setfield("post", n) end + function nuts.setreplace(d,n) d_setfield("replace",n) end + +end + -- alias nuts.getsurround = nuts.getkern diff --git a/tex/context/base/mkiv/node-ref.lua b/tex/context/base/mkiv/node-ref.lua index e12bd95bd..21fc4ce4d 100644 --- a/tex/context/base/mkiv/node-ref.lua +++ b/tex/context/base/mkiv/node-ref.lua @@ -166,33 +166,33 @@ local function dimensions(parent,start,stop) -- in principle we could move some -- todo: if no prev and no next and parent -- todo: we need a a list_dimensions for a vlist if getid(parent) == vlist_code then - if false then - local l = getlist(parent) - local c = l - local ok = false - while c do - if c == start then - ok = true - end - if ok and getid(c) == hlist_code then - break - else - c = getnext(c) - end - end - if ok and c then - if trace_areas then - report_area("dimensions taken of first line in vlist") - end - local w, h, d = getwhd(c) - return w, h, d, c - else - if trace_areas then - report_area("dimensions taken of vlist (probably wrong)") - end - return hlist_dimensions(start,stop,parent) - end - else + -- if false then + -- local l = getlist(parent) + -- local c = l + -- local ok = false + -- while c do + -- if c == start then + -- ok = true + -- end + -- if ok and getid(c) == hlist_code then + -- break + -- else + -- c = getnext(c) + -- end + -- end + -- if ok and c then + -- if trace_areas then + -- report_area("dimensions taken of first line in vlist") + -- end + -- local w, h, d = getwhd(c) + -- return w, h, d, c + -- else + -- if trace_areas then + -- report_area("dimensions taken of vlist (probably wrong)") + -- end + -- return hlist_dimensions(start,stop,parent) + -- end + -- else -- -- we can as well calculate here because we only have kerns and glue -- @@ -200,7 +200,7 @@ local function dimensions(parent,start,stop) -- in principle we could move some local last = nil local current = start local noflines = 0 - while current do + while current do -- can be loop local id = getid(current) if id == hlist_code or id == vlist_code or id == rule_code then if noflines == 0 then @@ -239,7 +239,7 @@ local function dimensions(parent,start,stop) -- in principle we could move some return hlist_dimensions(start,stop,parent) end end - end + -- end else if trace_areas then report_area("dimensions taken of range starting with %a using parent",nodecodes[id]) @@ -929,7 +929,6 @@ local function makedestination(width,height,depth,reference) end end - function nodes.destinations.handler(head) if head and topofstack > 0 then return (inject_areas(head,attribute,makedestination,stack,done)) diff --git a/tex/context/base/mkiv/page-run.lua b/tex/context/base/mkiv/page-run.lua index 88a7d6664..53331fc0e 100644 --- a/tex/context/base/mkiv/page-run.lua +++ b/tex/context/base/mkiv/page-run.lua @@ -212,7 +212,7 @@ function commands.showusage() report(" save size : %s of %s", status.max_save_stack, status.save_size) report("") report(" luabytecode bytes : %s in %s registers", status.luabytecode_bytes, status.luabytecodes) - report(" luastate bytes : %s", status.luastate_bytes) + report(" luastate bytes : %s of %s", status.luastate_bytes, status.luastate_bytes_max or "unknown") report("") report(" callbacks : %s", status.callbacks) report(" indirect callbacks : %s", status.indirect_callbacks) diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 472dee79a..aa20128db 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 4b9db0b9a..3e5df5ff2 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/strc-doc.lua b/tex/context/base/mkiv/strc-doc.lua index 4b2ac04b7..aa5fe352e 100644 --- a/tex/context/base/mkiv/strc-doc.lua +++ b/tex/context/base/mkiv/strc-doc.lua @@ -672,8 +672,15 @@ local function process(index,numbers,ownnumbers,criterium,separatorset,conversio end end -function sections.typesetnumber(entry,kind,...) -- kind='section','number','prefix' - if entry and entry.hidenumber ~= true then -- can be nil +-- kind : section number prefix + +function sections.typesetnumber(entry,kind,...) + -- + -- Maybe the hiding becomes an option .. after all this test was there + -- for a reason, but for now we have this: + -- + -- if entry and entry.hidenumber ~= true then + if entry then local separatorset = "" local conversionset = "" local conversion = "" diff --git a/tex/context/base/mkiv/strc-lnt.mkvi b/tex/context/base/mkiv/strc-lnt.mkvi index 4a6f14245..ad8c80d93 100644 --- a/tex/context/base/mkiv/strc-lnt.mkvi +++ b/tex/context/base/mkiv/strc-lnt.mkvi @@ -160,13 +160,6 @@ % compress=yes|no % compressmethod=separator|stopper -\def\c!compressdistance{compressdistance} -\def\c!compressmethod {compressmethod} -\def\c!compressstopper {compressstopper} % c -\def\v!compressstopper {compressstopper} % v - -\def\v!separator {separator} % v - \setvalue{\??linenotescompressmethod\v!separator}% {\edef\p_compressseparator{\noteparameter\c!compressseparator}% \scratchskip\noteparameter\c!compressdistance\relax diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua index be3436bd4..88b738b6d 100644 --- a/tex/context/base/mkiv/strc-reg.lua +++ b/tex/context/base/mkiv/strc-reg.lua @@ -761,6 +761,8 @@ local seeindex = 0 -- meerdere loops, seewords, dan words, anders seewords +-- todo: split seeword + local function crosslinkseewords(result,check) -- all words -- collect all seewords local seewords = { } @@ -778,23 +780,68 @@ local function crosslinkseewords(result,check) -- all words end end end + -- mark seeparents + + -- local seeparents = { } + -- for i=1,#result do + -- local data = result[i] + -- local word = data.list[1] + -- local okay = word and word[1] + -- if okay then + -- local seeindex = seewords[okay] + -- if seeindex then + -- seeparents[okay] = data + -- data.references.seeparent = seeindex + -- if trace_registers then + -- report_registers("see parent %03i: %s",seeindex,okay) + -- end + -- end + -- end + -- end + + local entries = { } + local keywords = { } local seeparents = { } for i=1,#result do local data = result[i] - local word = data.list[1] - word = word and word[1] - if word then - local seeindex = seewords[word] + local word = data.list + local size = #word + if data.seeword then + -- beware: a seeword has an extra entry for sorting purposes + size = size - 1 + end + for i=1,size do + local w = word[i] + local e = w[1] + local k = w[2] or e + entries [i] = e + keywords[i] = k + end + -- first try the keys + local okay, seeindex + for n=size,1,-1 do + okay = concat(keywords,"+",1,n) + seeindex = seewords[okay] + -- first try the entries if seeindex then - seeparents[word] = data - data.references.seeparent = seeindex - if trace_registers then - report_registers("see parent %03i: %s",seeindex,word) - end + break + end + okay = concat(entries,"+",1,n) + seeindex = seewords[okay] + if seeindex then + break + end + end + if seeindex then + seeparents[okay] = data + data.references.seeparent = seeindex + if trace_registers then + report_registers("see parent %03i: %s",seeindex,okay) end end end + -- mark seewords and extend sort list for i=1,#result do local data = result[i] diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index 24397ecbf..281c4a218 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -1098,21 +1098,27 @@ \let\pagebottomoffset\voffset \let\normalpagebottomoffset\voffset \fi -%D Handy. +%D Handy (this will change, again). -\suppresslongerror \plusone -\suppressoutererror \plusone -\suppressmathparerror \plusone -\suppressifcsnameerror\plusone +\ifdefined\suppresslongerror \suppresslongerror \plusone \fi +\ifdefined\suppressoutererror \suppressoutererror \plusone \fi +\ifdefined\suppressmathparerror \suppressmathparerror \plusone \fi +\ifdefined\suppressifcsnameerror \suppressifcsnameerror \plusone \fi +\ifdefined\suppressfontnotfounderror\suppressfontnotfounderror\zerocount\fi -\let \suppresslongerror \relax -\newcount\suppresslongerror \let\normalsuppresslongerror \suppresslongerror -\let \suppressoutererror \suppresslongerror \let\normalsuppressoutererror \suppresslongerror -\let \suppressmathparerror \suppresslongerror \let\normalsuppressmathparerror \suppresslongerror -\let \suppressifcsnameerror\suppresslongerror \let\normalsuppressifcsnameerror\suppresslongerror +\let \suppresslongerror \relax +\newcount\suppresslongerror \let\normalsuppresslongerror \suppresslongerror +\let \suppressoutererror \suppresslongerror \let\normalsuppressoutererror \suppresslongerror +\let \suppressmathparerror \suppresslongerror \let\normalsuppressmathparerror \suppresslongerror +\let \suppressifcsnameerror \suppresslongerror \let\normalsuppressifcsnameerror \suppresslongerror +\let \suppressfontnotfounderror\suppresslongerror \let\normalsuppressfontnotfounderror\suppresslongerror \matheqnogapstep\zerocount % for now +%D Experiment: + +\ifdefined\frozen \else \def\frozen{} \let\normalfrozen\frozen \fi + %D Now we define a few helpers that we need in a very early stage. We have no %D message system yet but redundant definitions are fatal anyway. diff --git a/tex/context/base/mkiv/toks-ini.lua b/tex/context/base/mkiv/toks-ini.lua index b7657625b..af93d3bc1 100644 --- a/tex/context/base/mkiv/toks-ini.lua +++ b/tex/context/base/mkiv/toks-ini.lua @@ -42,13 +42,21 @@ local scan_glue = token.scan_glue local scan_keyword = token.scan_keyword local scan_keyword_cs = token.scan_keyword_cs or scan_keyword local scan_token = token.scan_token +local scan_list = token.scan_list local scan_word = token.scan_word +local scan_key = token.scan_key +local scan_value = token.scan_value +local scan_char = token.scan_char local scan_number = token.scan_number local scan_csname = token.scan_csname local scan_real = token.scan_real local scan_float = token.scan_float local get_next = token.get_next +local get_next_token = token.get_next_token +local skip_next = token.skip_next +local peek_next_char = token.peek_next_char +local is_next_char = token.is_next_char local set_macro = token.set_macro local get_macro = token.get_macro @@ -134,6 +142,7 @@ tokens.scanners = { -- these expand token = scan_token, toks = scan_toks, tokens = scan_toks, + list = scan_list, dimen = scan_dimen, dimension = scan_dimen, glue = scan_glue, @@ -149,11 +158,17 @@ tokens.scanners = { -- these expand code = scan_code, tokencode = scan_token_code, word = scan_word, + key = scan_key, + value = scan_value, + char = scan_char, number = scan_number, boolean = scan_boolean, keyword = scan_keyword, keywordcs = scan_keyword_cs, csname = scan_csname, + peek = peek_next_char, + skip = skip_next, + ischar = is_next_char, } tokens.getters = { -- these don't expand @@ -225,6 +240,7 @@ if setinspector then active = t.active, expandable = t.expandable, protected = t.protected, + frozen = t.frozen, mode = t.mode, index = t.index, cmdname = cmdname, diff --git a/tex/context/base/mkiv/toks-scn.lua b/tex/context/base/mkiv/toks-scn.lua index f259bcee5..b707500e7 100644 --- a/tex/context/base/mkiv/toks-scn.lua +++ b/tex/context/base/mkiv/toks-scn.lua @@ -29,6 +29,7 @@ local scannumber = scanners.number local scankeyword = scanners.keyword local scankeywordcs = scanners.keywordcs local scanword = scanners.word +local scankey = scanners.key local scancode = scanners.code local scanboolean = scanners.boolean local scandimen = scanners.dimen @@ -180,6 +181,7 @@ local shortcuts = { scankeyword = scankeyword, scankeywordcs = scankeywordcs, scanword = scanword, + -- scankey = scankey, scancode = scancode, scanboolean = scanboolean, scandimen = scandimen, diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua index bd406b0e5..4d754ec68 100644 --- a/tex/context/base/mkiv/trac-deb.lua +++ b/tex/context/base/mkiv/trac-deb.lua @@ -315,7 +315,7 @@ directives.register("system.errorcontext", function(v) register('show_error_message', nop) register('show_warning_message',function() processwarning(v) end) register('show_error_hook', function() processerror(v) end) - register('show_lua_error_hook', nop) + register('show_lua_error_hook', function() processerror(v) end) else register('show_error_message', nil) register('show_error_hook', nil) @@ -371,7 +371,8 @@ function lmx.showerror(lmxname) end function lmx.overloaderror() - callback.register('show_error_hook', function() lmx.showerror() end) -- prevents arguments being passed + callback.register('show_error_hook', function() lmx.showerror() end) -- prevents arguments being passed + callback.register('show_lua_error_hook', function() lmx.showerror() end) -- prevents arguments being passed end directives.register("system.showerror", lmx.overloaderror) diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua index 0a4537e31..24ebc5249 100644 --- a/tex/context/base/mkiv/trac-inf.lua +++ b/tex/context/base/mkiv/trac-inf.lua @@ -262,7 +262,11 @@ end function statistics.memused() -- no math.round yet -) local round = math.round or math.floor - return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000)) + return format("%s MB, ctx: %s MB, max: %s MB)", + round(collectgarbage("count")/1000), + round(status.luastate_bytes/1000000), + status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown" + ) end starttiming(statistics) diff --git a/tex/context/base/mkiv/typo-cap.lua b/tex/context/base/mkiv/typo-cap.lua index 7e8003c62..64bb66dab 100644 --- a/tex/context/base/mkiv/typo-cap.lua +++ b/tex/context/base/mkiv/typo-cap.lua @@ -315,6 +315,9 @@ register(variables.camel, camel) -- 10 register(variables.cap, variables.capital) -- clone register(variables.Cap, variables.Capital) -- clone +-- this can be more clever: when we unset we can actually +-- use the same attr ref if needed + function cases.handler(head) -- not real fast but also not used on much data local start = head local lastfont = { } @@ -341,9 +344,10 @@ function cases.handler(head) -- not real fast but also not used on much data end local action = actions[n] -- map back to low number if action then - start = action(start,attr,lastfont,n,count) + local quit + start, quit = action(start,attr,lastfont,n,count) if trace_casing then - report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok) + report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,quit and "-" or "+") end elseif trace_casing then report_casing("unknown case trigger %a",n) diff --git a/tex/context/base/mkiv/typo-pag.lua b/tex/context/base/mkiv/typo-pag.lua index 05513e20c..ea4b1574c 100644 --- a/tex/context/base/mkiv/typo-pag.lua +++ b/tex/context/base/mkiv/typo-pag.lua @@ -108,93 +108,94 @@ function parbuilders.registertogether(line,specification) -- might change end end -local function keeptogether(start,a) - if start then - local specification = cache[a] - if a then - local current = getnext(start) - local previous = start - local total = getdepth(previous) - local slack = specification.slack - local threshold = specification.depth - slack +local function keeptogether(start,a,specification) + local current = getnext(start) + local previous = start + local total = getdepth(previous) + local slack = specification.slack + local threshold = specification.depth - slack + if trace_keeptogether then + report_keeptogether("%s, index %s, total %p, threshold %p, slack %p","list",a,total,threshold,slack) + end + while current do + local id = getid(current) + if id == vlist_code or id == hlist_code then + local wd, ht, dp = getwhd(current) + total = total + ht + dp + if trace_keeptogether then + report_keeptogether("%s, index %s, total %p, threshold %p","list",a,total,threshold) + end + if total <= threshold then + if getid(previous) == penalty_code then + setpenalty(previous,10000) + else + insert_node_after(head,previous,new_penalty(10000)) + end + else + break + end + elseif id == glue_code then + -- hm, breakpoint, maybe turn this into kern + total = total + getwidth(current) if trace_keeptogether then - report_keeptogether("%s, index %s, total %p, threshold %p, slack %p","list",a,total,threshold,slack) + report_keeptogether("%s, index %s, total %p, threshold %p","glue",a,total,threshold) end - while current do - local id = getid(current) - if id == vlist_code or id == hlist_code then - local wd, ht, dp = getwhd(current) - total = total + ht + dp - if trace_keeptogether then - report_keeptogether("%s, index %s, total %p, threshold %p","list",a,total,threshold) - end - if total <= threshold then - if getid(previous) == penalty_code then - setpenalty(previous,10000) - else - insert_node_after(head,previous,new_penalty(10000)) - end - else - break - end - elseif id == glue_code then - -- hm, breakpoint, maybe turn this into kern - total = total + getwidth(current) - if trace_keeptogether then - report_keeptogether("%s, index %s, total %p, threshold %p","glue",a,total,threshold) - end - if total <= threshold then - if getid(previous) == penalty_code then - setpenalty(previous,10000) - else - insert_node_after(head,previous,new_penalty(10000)) - end - else - break - end - elseif id == kern_code then - total = total + getkern(current) - if trace_keeptogether then - report_keeptogether("%s, index %s, total %s, threshold %s","kern",a,total,threshold) - end - if total <= threshold then - if getid(previous) == penalty_code then - setpenalty(previous,10000) - else - insert_node_after(head,previous,new_penalty(10000)) - end - else - break - end - elseif id == penalty_code then - if total <= threshold then - if getid(previous) == penalty_code then - setpenalty(previous,10000) - end - setpenalty(current,10000) - else - break - end + if total <= threshold then + if getid(previous) == penalty_code then + setpenalty(previous,10000) + else + insert_node_after(head,previous,new_penalty(10000)) end - previous = current - current = getnext(current) + else + break + end + elseif id == kern_code then + total = total + getkern(current) + if trace_keeptogether then + report_keeptogether("%s, index %s, total %s, threshold %s","kern",a,total,threshold) + end + if total <= threshold then + if getid(previous) == penalty_code then + setpenalty(previous,10000) + else + insert_node_after(head,previous,new_penalty(10000)) + end + else + break + end + elseif id == penalty_code then + if total <= threshold then + if getid(previous) == penalty_code then + setpenalty(previous,10000) + end + setpenalty(current,10000) + else + break end end + previous = current + current = getnext(current) end end -- also look at first non glue/kern node e.g for a dropped caps function parbuilders.keeptogether(head) - local done = false + local done = false -- can go local current = head while current do if getid(current) == hlist_code then local a = takeattr(current,a_keeptogether) if a and a > 0 then - keeptogether(current,a) - cache[a] = nil - done = true + local specification = cache[a] + if specification then + keeptogether(current,a,specification) + -- this is tricky ... we need a better resetter, maybe some + -- injected latelua or a gc method on a property (interesting + -- experiment) + cache[a] = nil + done = true + end end end current = getnext(current) diff --git a/tex/context/base/mkiv/util-jsn.lua b/tex/context/base/mkiv/util-jsn.lua index 68c6a712e..8da351897 100644 --- a/tex/context/base/mkiv/util-jsn.lua +++ b/tex/context/base/mkiv/util-jsn.lua @@ -122,11 +122,14 @@ do local f_key_val_num = f_key_val_seq local f_key_val_yes = formatters[ "\n" .. '%w"%s" : true' ] local f_key_val_nop = formatters[ "\n" .. '%w"%s" : false' ] + local f_key_val_null = formatters[ "\n" .. '%w"%s" : null' ] local f_val_num = formatters[ "\n" .. '%w%s' ] local f_val_str = formatters[ "\n" .. '%w"%s"' ] local f_val_yes = formatters[ "\n" .. '%wtrue' ] local f_val_nop = formatters[ "\n" .. '%wfalse' ] + local f_val_null = formatters[ "\n" .. '%wnull' ] + local f_val_empty = formatters[ "\n" .. '%w{ }' ] local f_val_seq = f_val_num -- no empty tables because unknown if table or hash @@ -158,8 +161,10 @@ do n = n + 1 t[n] = '"' elseif tv == "boolean" then n = n + 1 t[n] = v and "true" or "false" - else + elseif v then n = n + 1 t[n] = tostring(v) + else + n = n + 1 t[n] = "null" end end n = n + 1 t[n] = " ]" @@ -217,8 +222,11 @@ do if st then n = n + 1 t[n] = f_val_seq(depth,st) else - tojsonpp(v,k,depth,level+1,0) + tojsonpp(v,nil,depth,level+1,#v) end + else + n = n + 1 + t[n] = f_val_empty(depth) end elseif tv == "boolean" then n = n + 1 @@ -227,6 +235,9 @@ do else t[n] = f_val_nop(depth,v) end + else + n = n + 1 + t[n] = f_val_null(depth) end end elseif next(root) then @@ -244,12 +255,12 @@ do n = n + 1 t[n] = f_key_val_num(depth,k,v) elseif tk == "string" then k = lpegmatch(escaper,k) or k - n = n + 1 t[n] = f_key_val_str(depth,k,v) + n = n + 1 t[n] = f_key_val_num(depth,k,v) end elseif tv == "string" then if tk == "number" then v = lpegmatch(escaper,v) or v - n = n + 1 t[n] = f_key_val_num(depth,k,v) + n = n + 1 t[n] = f_key_val_str(depth,k,v) elseif tk == "string" then k = lpegmatch(escaper,k) or k v = lpegmatch(escaper,v) or v @@ -287,6 +298,15 @@ do t[n] = f_key_val_nop(depth,k) end end + else + if tk == "number" then + n = n + 1 + t[n] = f_key_val_null(depth,k) + elseif tk == "string" then + k = lpegmatch(escaper,k) or k + n = n + 1 + t[n] = f_key_val_null(depth,k) + end end end end @@ -348,6 +368,8 @@ do n = n + 1 ; t[n] = value elseif kind == "boolean" then n = n + 1 ; t[n] = tostring(value) + else + n = n + 1 ; t[n] = "null" end return t, n end @@ -377,10 +399,9 @@ do n = 0 if pretty then tojsonpp(value,name,0,0,#value) --- value = concat(t,"\n",1,n) value = concat(t,"",1,n) else - tojson(value,0) + t, n = tojson(value,0) value = concat(t,"",1,n) end t = nil diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index 2ab5c9c12..9ac3dcb03 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -150,6 +150,7 @@ + @@ -480,6 +481,7 @@ + @@ -738,7 +740,9 @@ + + diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml index 06df09bc5..45a4f36d6 100644 --- a/tex/context/interface/mkii/keys-nl.xml +++ b/tex/context/interface/mkii/keys-nl.xml @@ -150,6 +150,7 @@ + @@ -376,6 +377,7 @@ + @@ -479,6 +481,7 @@ + @@ -572,6 +575,7 @@ + @@ -735,7 +739,10 @@ + + + diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index 710f9d74b..86f8f49c9 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -150,6 +150,7 @@ + @@ -480,6 +481,7 @@ + @@ -738,7 +740,9 @@ + + diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index 75802edd8..9a2154718 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -150,6 +150,7 @@ + @@ -480,6 +481,7 @@ + @@ -738,7 +740,9 @@ + + diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 97b13f0d0..7d7f5f10e 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 9f90949bb..b1bf55d2e 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/context/modules/mkiv/s-cgj.mkiv b/tex/context/modules/mkiv/s-cgj.mkiv index 2950a799d..3e7518777 100644 --- a/tex/context/modules/mkiv/s-cgj.mkiv +++ b/tex/context/modules/mkiv/s-cgj.mkiv @@ -1,258 +1,231 @@ -%D \module -%D [file=s-cgj.mkiv, -%D version=2018.09.28, -%D title=Context group style file, -%D subtitle=CG-journal base style, -%D author={Adrian Egger, W. Egger, Taco Hoekwater}, -%D date=\currentdate, -%D copyright={Context Group}] - -%D \type {\enablemode[draft]} has to come before loading the style. Maybe some -%D day I'll make something more official and then some \type {everydraft} or so. +%\module [ +% file=s-cgj.mkiv, +% version=2012.12.05, +% title=Context group style file, +% subtitle=CG-journal base style, +% author={Adrian Egger, W. Egger, Taco Hoekwater}, +% date=\currentdate, +% copyright={Context Group}% +%] + +\enablemode[cgjpagecolumns] % Fixme and todo ... -\startmodule[cgj] +\definecolor[NoteColor] [g=1,r=.25,b=.25] +\definecolor[WarnColor] [r=1,g=.25,b=.25] -\definecolor[NoteColor][g=1,r=.25,b=.25] -\definecolor[WarnColor][r=1,g=.25,b=.25] +\def\todo#1% + {\startframedtext + [background=color,backgroundcolor=NoteColor] + {\bf TODO:}~~#1\par + \stopframedtext } -\unexpanded\def\todo#1% - {\startframedtext[background=color,backgroundcolor=NoteColor] - \dontleavehmode\start\bf TODO:\stop~~#1\par - \stopframedtext} +\def\fixme#1% + {\startframedtext + [background=color,backgroundcolor=WarnColor] + {\bf FIXME:}~~#1\par + \stopframedtext } -\unexpanded\def\fixme#1% - {\startframedtext[background=color,backgroundcolor=WarnColor] - \dontleavehmode\start\bf FIXME:\stop~~#1\par - \stopframedtext } +% There is a draft mode, which enables all frames +% \enablemode[draft] -%D Base set of variables. The actual values are set in the file -%D CG-journal. +\doifmodeelse + {draft} + {\def\OnOff{on}\showframe} + {\def\OnOff{off}} + +% Base set of variables +% The actual values are set in the file CG-journal \setvariables [CG-Journal] [Title={Journal}, RunningTitle={Journal}, SubTitle={From the base set of variables}, Version=1.0, - NOFColumns=2] + NOFColumns=2, + ] +\setupinteraction[ + state=start, + color=, + contrastcolor=, + style=, + title=Journal, + author=context group, +] +\placebookmarks[title,chapter,subject,section][chapter] +\setupinteractionscreen[option={doublesided,bookmark}] \startmode[onecolumn,fullwidth] - \setvariables - [CG-Journal] - [NOFColumns=1] +\setvariables + [CG-Journal] + [NOFColumns=1] \stopmode -% Fonts setup. - +% Fonts setup \usetypescriptfile[plex] +%\usetypescriptfile[type-inconsolata] \starttypescript [cgj] - \definetypeface [cgj] [rm] [serif][ibmplex-light] [default] - \definetypeface [cgj] [ss] [sans] [ibmplex-light] [default] - \definetypeface [cgj] [mm] [math] [palatino] [default] - \definetypeface [cgj] [tt] [mono] [ibmplex] [default][rscale=0.9] + \definetypeface [cgj] [rm] [serif][ibmplex] [default] + \definetypeface [cgj] [ss] [sans] [ibmplex] [default] + \definetypeface [cgj] [mm] [math] [palatino] [default] + \definetypeface [cgj] [tt] [mono] [ibmplex] [default] [rscale=0.9] \stoptypescript \starttypescript [cgj-light] - \definetypeface [cgj-light] [rm] [serif][ibmplex-extralight] [default] - \definetypeface [cgj-light] [ss] [sans] [ibmplex-extralight] [default] - \definetypeface [cgj-light] [mm] [math] [palatino] [default] - \definetypeface [cgj-light] [tt] [mono] [ibmplex-extralight] [default][rscale=0.9] + \definetypeface [cgj-light] [rm] [serif][ibmplex] [default] + \definetypeface [cgj-light] [ss] [sans] [ibmplex-light] [default] + \definetypeface [cgj-light] [mm] [math] [palatino] [default] + \definetypeface [cgj-light] [tt] [mono] [ibmplex] [default] [rscale=0.9] \stoptypescript -\starttypescript [cgj-extralight] - \definetypeface [cgj-extralight] [rm] [serif][ibmplex-thin] [default] - \definetypeface [cgj-extralight] [ss] [sans] [ibmplex-thin] [default] - \definetypeface [cgj-extralight] [mm] [math] [palatino] [default] - \definetypeface [cgj-extralight] [tt] [mono] [ibmplex-thin] [default][rscale=0.9] -\stoptypescript - -\usebodyfont - [cgj-light,cgj-extralight] - -\setupbodyfont - [cgj,ss,10pt] +\usebodyfont[cgj-light,ss,10pt] +\setupbodyfont[cgj,ss,10pt] -\definebodyfontenvironment[10pt][interlinespace=13pt] +\definebodyfontenvironment[10pt][interlinespace=12pt] \definebodyfontenvironment[12pt][interlinespace=16pt] \definebodyfontenvironment[16pt][interlinespace=20pt] - -\setupinterlinespace - [line=13pt] - +\setupinterlinespace[line=12pt] \let\sl\it -%D Path to the logos - -\setupexternalfigures - [directory=./Logos, - location={global,local,default}] - -%D Logos: black logo only. +% Path to the logos +\setupexternalfigures[directory=./Logos] +% Logos +% Black logo only \useexternalfigure [Logo] [cg_corp_logo_loop_black_cmyk] - [width=30mm, - height=19mm] - -%D Black logo with text - + [width=30mm,height=19mm] +%Black logo with text \useexternalfigure [LogoText] [cg_corp_logo_text_black_cmyk] - [width=50mm, - height=35.2mm] - -%D Colors + [width=50mm,height=35.2mm] +% Colors \definecolor[CGlightblue][c=1,m=.15,y=0,k=0] -\definecolor[CGdeepblue] [c=1,m=.8,y=0,k=.3] -\definecolor[CGgray] [c=0,m=0,y=0,k=.1] - -%D Article styles +\definecolor[CGdeepblue][c=1,m=.8,y=0,k=.3] +\definecolor[CGgray][c=0,m=0,y=0,k=.1] +% Article styles \definealternativestyle [Articleheading] [{\switchtobodyfont[16pt,ss]\bf}] - \definealternativestyle [Articlesubheading] [{\switchtobodyfont[16pt,ss]\tf}] - \definealternativestyle [Authorname] [{\switchtobodyfont[12pt,ss]\it}] - \definealternativestyle [Sectionheading] [{\switchtobodyfont[12pt,ss]\bf\setupinterlinespace[line=12pt]}] - \definealternativestyle [Subsectionheading] [{\switchtobodyfont[cgj-light,10pt,ss]\bf\setupinterlinespace[line=10pt]}] - \definealternativestyle [IntroCopy] [{\switchtobodyfont[12pt,ss]\tf}] - \definealternativestyle [PagenumberStyle] [{\switchtobodyfont[cgj-light,10pt,ss]\bf}] -%D Headerstyles:Breadcrumbs - +% Headerstyles - Breadcrumbs \definealternativestyle [BreadcrumbMd] - [{\switchtobodyfont[cgj-light,10pt,ss]\bf}] - + [{\switchtobodyfont[10pt,ss]\bf}] \definealternativestyle [BreadcrumbRg] - [{\switchtobodyfont[cgj,10pt,ss]}] - + [{\switchtobodyfont[cgj-light,10pt,ss]\bf}] \definealternativestyle [BreadcrumbLt] [{\switchtobodyfont[10pt,ss]\tf}] - \definealternativestyle [BreadcrumbTh] [{\switchtobodyfont[cgj-light,10pt,ss]\tf}] -%D Captionstyles - +% Captionstyles \definealternativestyle [Captionheading] [{\switchtobodyfont[8pt,ss]\bf\setupinterlinespace[line=8pt]}] - \definealternativestyle [Captiontext] [{\switchtobodyfont[8pt,ss]\tf\setupinterlinespace[line=8pt]}] -%D Article signature - +% Article signature \definealternativestyle [Signaturestyle] [{\switchtobodyfont[10pt,ss]\it}] -%D Article footnotes - +% Article footnotes \definealternativestyle [Articlefootnotes] [{\switchtobodyfont[8pt,ss]\tf}] -%D Index and TOC styles - +% Index /TOC styles +% It looks like the inheritance is gone. +%\definealternativestyle +% [IndexContents][Articleheading] \definealternativestyle [IndexContents] [{\switchtobodyfont[16pt,ss]\bf\setupinterlinespace[line=18pt]}] - \definealternativestyle [IndexArticleTitle] [{\switchtobodyfont[12pt,ss]\tf\setupinterlinespace[line=20pt]}] - \definealternativestyle [IndexNumber] [{\switchtobodyfont[12pt,ss]\bf\setupinterlinespace[line=20pt]}] - \definealternativestyle [IndexAuthor] [{\switchtobodyfont[12pt,ss]\it\setupinterlinespace[line=20pt]}] -%D Math: still missing. - -%D Verbatim +% Math +% --> still missing +% Verbatim \definealternativestyle [DisplayMonospaced] - [\tt] - + [{\switchtobodyfont[10pt,tt]\setupinterlinespace[line=12pt]}] \definealternativestyle [DisplayMonospacedX] - [{\switchtobodyfont[8pt,tt]}] - + [{\switchtobodyfont[8pt,tt]\setupinterlinespace[line=11pt]}] \definealternativestyle [DisplayMonospacedS] - [{\switchtobodyfont[9pt,tt]\setupinterlinespace[line=10pt]}] - -%D Blank adjustment + [{\switchtobodyfont[9pt,tt]\setupinterlinespace[line=12pt]}] -\defineblank[CGblank] [6pt] -\defineblank[BigCGblank] [24pt] +% \blank adjustment +\defineblank[CGblank][6pt] +\defineblank[BigCGblank][24pt] \defineblank[MediumCGblank][12pt] -%D Paper definition +% Paper definition +\definepapersize[Journal][width=210mm,height=266mm] +\setuppapersize[Journal][Journal] -\definepapersize - [Journal] - [width=210mm, - height=266mm] - -\setuppapersize - [Journal] - [Journal] - -%D General layout +% General layout \definelayout [General] - [topspace=18mm, + [topspace=20mm, backspace=28mm, header=5mm, - headerdistance=7mm, - footer=5mm, + headerdistance=5mm, + footer=3mm, footerdistance=5mm, width=157mm, height=224mm, - marking=on] + marking=on, + ] \definelayout [Content] - [topspace=18mm, + [topspace=20mm, backspace=28mm, header=5mm, - headerdistance=7mm, + headerdistance=5mm, footer=0mm, footerdistance=0mm, width=157mm, @@ -260,52 +233,62 @@ margindistance=4mm, rightmargin=21mm, leftmargin=21mm, - marking=on] + marking=on, + ] \definelayout [Imprint] - [topspace=18mm, + [topspace=20mm, backspace=28mm, header=5mm, - headerdistance=7mm, - footer=5mm, + headerdistance=5mm, + footer=3mm, footerdistance=5mm, width=107mm, height=224mm, margindistance=4mm, rightmargin=45.3mm, leftmargin=21mm, - marking=on] + marking=on, + ] \definelayout [SingleColumn] - [topspace=18mm, + [topspace=20mm, backspace=55mm, header=5mm, - headerdistance=7mm, - footer=5mm, + headerdistance=5mm, + footer=3mm, footerdistance=5mm, width=130mm, height=224mm, margindistance=4mm, leftmargin=48mm, rightmargin=21mm, - marking=on] - -%D Pagenumbering: Pagenumber is set in the footer - -\setuppagenumbering - [location=, - alternative=doublesided] - -%D Head-definitions + marking=on, + ] + +% Pagenumbering: Pagenumber is set in the footer +\setuppagenumbering[location=,alternative=doublesided] + +% Head-definitions +% The distances according to the style-guide +% H1 = Article title +% H2 = Section title (1. Bla bla) +% H3 = Subsection title (1.1 Bla bla) +% H4 = Subsubsection title (1.1.1 Bla bla) +% +% Between abstract and body: 2 lines 10/12pt --> 24 pt: BigCGblank +% Between H2 and bodycopy/H3: 1 line 6/6pt --> 6 pt: CGblank +% Between H3 and bodycopy/H4: 1 line 6/6pt --> 6 pt: CGblank +% End H2 paragraph: 2 lines 10/12pt --> 24 pt: BigCGblank +% End H3 paragraph: 1 line 6/6pt --> 6 pt: CGblank \setuphead [title] [style=Articleheading, after={\blank[BigCGblank]}, page=yes] - \setuphead [part] [placehead=no, @@ -314,9 +297,8 @@ page=no, numbercommand=, expansion=yes] - \setuphead - [section] + [section,subject] [style=Sectionheading, before={\blank[BigCGblank]}, after={\blank[CGblank]}, @@ -324,8 +306,8 @@ distance=4pt, align={flushleft,nothyphenated}, resetnumber=yes, - continue=yes] - + continue=yes, + ] \setuphead [subsection] [style=Subsectionheading, @@ -335,49 +317,41 @@ distance=4pt, align={flushleft,nothyphenated}, resetnumber=yes, - continue=yes] - -\setuphead - [subject] - [style=Sectionheading, - before={\blank[BigCGblank]}, - after=] - + continue=yes, + ] +%\setuphead +% [subject] +% [style=Sectionheading,before={\blank[BigCGblank]},after=] \setuphead [subsubject] [style=Subsectionheading, before={\blank[CGblank]}, after={\blank[CGblank]}, - sectionstopper=] + sectionstopper=, + ] +% Columns +% The setup of the columns is done at the moment columns are started (see end of file) -%D A special head for the footnote section in multicolumn mode excuse the low-level -%D rule, I wanted it to look like the start of footnotes in single column mode. (TH) +% Index/TOC page setups +\unprotect -\definehead - [footnotesubject] - [subject] + \def\listboxproperties {\strc_lists_get_reference_attribute} + \def\listrenderingsetup {\the\t_lists_every_renderingtext} + \def\listrenderingsynchronize{\the\t_lists_every_renderingsynchronize} -\setuphead - [footnotesubject] - [style=Sectionheading, - before={\kern -13pt}, - after={\smash{\lower 13pt\hbox{\vrule width 2.5cm height 1pt depth 0pt}}}] +\protect - -%D The setup of the columns is done at the moment columns are started (see end -%D of file) - -%D Index/TOC page setups +% now you can say: \definelistalternative - [CGJ:Index] - [renderingsetup=CGJ:Indexheading] - + [CGJ:Index] + [renderingsetup=CGJ:Indexheading] \definelistalternative - [CGJ:Index:Chapter] - [renderingsetup=CGJ:Indexheading:Chapter] + [CGJ:Index:Chapter] + [renderingsetup=CGJ:Indexheading:Chapter] -\startsetups[CGJ:Indexheading:Chapter] + + \startsetups[CGJ:Indexheading:Chapter] \listparameter{before} \vbox \listboxproperties{all} { \forgetall @@ -388,14 +362,20 @@ \useliststyleandcolor{numberstyle}{numbercolor} \currentlistentrypagenumber \egroup} + % \bgroup + % \useliststyleandcolor{numberstyle}{numbercolor} + % \currentlistsymbol + % \egroup + % .\space \bgroup \useliststyleandcolor{textstyle}{textcolor} \smash{\currentlistentrytitle}% \egroup + % \par } \par \listparameter{after} -\stopsetups + \stopsetups \startsetups[CGJ:Indexheading] \listparameter{before} @@ -405,9 +385,15 @@ \listrenderingsynchronize \hbox to 15mm{ \bgroup + %\useliststyleandcolor{pagestyle}{pagecolor} \useliststyleandcolor{numberstyle}{numbercolor} \currentlistentrypagenumber \egroup} + % \bgroup + % \useliststyleandcolor{numberstyle}{numbercolor} + % \currentlistsymbol + % \egroup + % .\space \bgroup \useliststyleandcolor{textstyle}{textcolor} \currentlistentrytitle @@ -419,45 +405,71 @@ \stopsetups \setuplist - [part] - [before={\blank[CGblank]}, - after=, - style=IndexContents, - numberstyle=\IndexNumber, - textstyle=\IndexArticleTitle, - prefix=no, - alternative=CGJ:Index:Chapter] - -%D Captions - + [part] + [before={\blank[CGblank]}, + after=, + style=IndexContents, + numberstyle=\IndexNumber, + textstyle=\IndexArticleTitle, + prefix=no, + alternative=CGJ:Index:Chapter] + +%\setuplist +% [section] +% [before={\blank[CGblank]}, +% after={}, +% style=IndexHeaderB, +% % numberstyle=\bf, +% % textstyle=\bfa, +% prefix=no, +% alternative=CGJ:Index] +% +%\setuplist +% [subsection] +% [before={}, +% after={}, +% style=IndexHeaderC, +% % numberstyle=\bf, +% % textstyle=\bfa, +% prefix=no, +% alternative=CGJ:Index] + +% Floats + +% \setupfloat +% [figure] +% [] + +% Captions \setupcaptions [suffix={.}, + width=max, headstyle=\Captionheading, style=\Captiontext, - distance=6pt] + distance=2pt + ] \setupcaption[figure][way=bypart] \setupcaption[table] [way=bypart] -%D Datacollection: article parameters (other fields and defaults) - -\unexpanded\def\CGJBibData[#1]% +% Datacollection: article parameters (other fields and defaults) +\def\CGJBibData[#1]% {\getparameters - [CGJ] - [SubTitle=, - RunningAuthor=, - RunningTitle=Example, - Email=, - Address=, - Page=1, - Title={My Article}, - Author={Example Author}, - Period=, - Number=, - Year=, - TocAuthor=, - TocTitle=, - #1]% + [CGJ] + [SubTitle=, + RunningAuthor=, + RunningTitle=Example, + Email=, + Address=, + Page=1, + Title={My Article}, + Author={Example Author}, + Period=, + Number=, + Year=, + TocAuthor=, + TocTitle=, + #1]% \doifnothing {\CGJRunningTitle} {\let\CGJRunningTitle\CGJTitle}% @@ -470,116 +482,130 @@ \doifnothing {\CGJTocTitle} {\let\CGJTocTitle\CGJTitle}% - \setvariables - [CGJToc] - [Author=\CGJTocAuthor, - Title=\CGJTocTitle]% for TOC + \setvariables[CGJToc][Author=\CGJTocAuthor, + Title=\CGJTocTitle]% for TOC } -\unexpanded\def\dostartArticle[#1] - {\CGJBibData[#1] - \doifelse - {\getvariable{CG-Journal}{NOFColumns}} - {1} - {\doifmodeelse{fullwidth} - {\setuplayout[General]} - {\setuplayout[SingleColumn]}} - {\setupnotes[location=none] - \setuplayout[General]}% - \bgroup - {\switchtobodyfont[16pt]\Articleheading\CGJTitle\par} - {\doifsomething{\CGJSubTitle} - {\switchtobodyfont[16pt]\Articlesubheading\CGJSubTitle\par}} - {\doifsomething{\CGJAuthor} - {\switchtobodyfont[12pt]\Authorname \CGJAuthor}\par} - \part - {\getvariable{CGJToc}{Title}% - \doifsomething{\getvariable{CGJToc}{Author}}{ \emdash\ }% - \IndexAuthor\getvariable{CGJToc}{Author}} - \godown[13pt]% - \egroup - \par - \hyphenpenalty1000\relax} - -\unexpanded\def\startArticle - {\dosingleempty\dostartArticle} - -\def\signArticle - {} - -%D In multicolumn mode, footnotes come are at the end of the article: - -\startsetups article:after - \startfootnotesubject[title=] - \placefootnotes - \stopfootnotesubject -\stopsetups - -\unexpanded\def\stopArticle - {\doifelse{\getvariable{CG-Journal}{NOFColumns}}{1} - {\par - \signArticle} - {\setups{article:after} - \par - \signArticle - \stoppagecolumns} - \page} - -\unexpanded\def\startAbstract - {\bgroup - \switchtobodyfont[12pt] - \IntroCopy} - -\unexpanded\def\stopAbstract - {\par - \egroup - \finishAbstract} - -\unexpanded\def\finishAbstract - {\doifelse {\getvariable{CG-Journal}{NOFColumns}} {1} - {\blank[BigCGblank]} - {\vbox{\blank[BigCGblank]}% - \par - \startpagecolumns[balance=yes,distance=12pt,page=no,n=\getvariable{CG-Journal}{NOFColumns}] - \setupitemgroup[itemize][packed] - \setuplayout[grid=yes]} % grid mode only in columns +\def\dostartArticle[#1]{% + \CGJBibData[#1] + % \pageno=\CGJPage + % \setupuserpagenumber[start=\CGJPage] + \doifelse + {\getvariable{CG-Journal}{NOFColumns}} + {1} + {\doifmodeelse{fullwidth} + {\setuplayout[General]} + {\setuplayout[SingleColumn]}} + {\setuplayout + [General]}% + \doifmode{cgjpagecolumns} + {\definepagecolumns [cgjpagecolumns][n=\getvariable{CG-Journal}{NOFColumns},distance=12pt,page=no]} + \bgroup + {\switchtobodyfont[16pt]\Articleheading\CGJTitle\par} + {\doifsomething{\CGJSubTitle} + {\switchtobodyfont[16pt]\Articlesubheading\CGJSubTitle\par}} + {\doifsomething + {\CGJAuthor} + {\switchtobodyfont[12pt]\Authorname \CGJAuthor}\par} + \part{\getvariable{CGJToc}{Title}% + \doifsomething{\getvariable{CGJToc}{Author}}{ \emdash\ }% + \IndexAuthor\getvariable{CGJToc}{Author}} + \godown[16pt] + \egroup + \hyphenpenalty1000} + +\def\startArticle{\dosingleempty\dostartArticle} + +\def\signArticle{} + +\def\CGJRunningTitle {} +\def\CGJRunningAuthor {} +\unprotect +\def\mystoppagecolumns% + {\page \endgroup \page_otr_command_set_vsize \page_otr_command_set_hsize \page \endgroup} +\protect + +\def\stopArticle{% + \par\signArticle + \doifmodeelse{cgjcolumnsets} + {\stopcolumnset \page} + {\doifmodeelse{cgjpagecolumns} + {\mystoppagecolumns} + {\doifmodeelse{cgjmixedcolumns} + {\stopmixedcolumns \page} + {\stopcolumns \page}% + }% + }% } - -\unexpanded\def\noAbstract - {\kern -24pt - \finishAbstract} - -%D Headertexts - +\def\startAbstract{% + \bgroup + \switchtobodyfont[12pt] + \IntroCopy} + + +\def\finishAbstract{% + \blank[BigCGblank]% + \doif + {\getvariable{CG-Journal}{NOFColumns}} + {>1} + {\setupcolumns + [n=\getvariable{CG-Journal}{NOFColumns}, + distance=4mm, + balance=yes, + ] + } + \doifmodeelse{cgjcolumnsets} + {\definecolumnset[cgjcolumnsets][n=\getvariable{CG-Journal}{NOFColumns},balance=yes]% + \startcolumnset[cgjcolumnsets]} + {\doifmodeelse{cgjpagecolumns} + {\par\ifnum \getvariable{CG-Journal}{NOFColumns}>1 \hbox{}\par\fi\startpagecolumns[cgjpagecolumns]} + {\doifmodeelse{cgjmixedcolumns} + {\definemixedcolumns[cgjmixedcolumns][n=\getvariable{CG-Journal}{NOFColumns},balance=yes,blank={line,fixed}]% + \startmixedcolumns[cgjmixedcolumns]} + {\startcolumns[n=\getvariable{CG-Journal}{NOFColumns}]}% + }% + }% +} + +\def\stopAbstract{% + \par + \egroup + \finishAbstract} + +\def\noAbstract{\kern -24pt \finishAbstract} + + +% Headertexts \startsetups[Header:texts] - \setupheadertexts - [] [{{\BreadcrumbLt\CGJRunningTitle}{\BreadcrumbTh\doifsomething{\CGJRunningAuthor}{\ > }\CGJRunningAuthor}}] %odd - [{\BreadcrumbMd contextgroup}{\BreadcrumbRg\ > \getvariable{CG-Journal}{RunningTitle}}] [] %even + \setupheadertexts + [] + [{{\BreadcrumbLt\CGJRunningTitle}{\BreadcrumbTh\doifsomething{\CGJRunningAuthor}{\ > }\CGJRunningAuthor}}] %odd + [{\BreadcrumbMd contextgroup}{\BreadcrumbRg\ > \getvariable{CG-Journal}{RunningTitle}}] %even + [] \stopsetups -%D Footertexts +% Footertexts \startsetups[Footer:texts] \setupfootertexts - [] [\PagenumberStyle\pagenumber] - [\PagenumberStyle\pagenumber] [] + [] + [\PagenumberStyle\pagenumber] + [\PagenumberStyle\pagenumber] + [] \stopsetups -%D Setup tolerance, stretch. - -\setuptolerance - [tolerant,stretch] +% Setup tolerance, stretch +\setuptolerance[tolerant,stretch] -%D Setting up footnotes. +% Setting up footnotes \setupnotation [footnote] [way=bypart, - rule=on] - -%D Adjustments to the container containing the footnotes. + rule=on] +% Adjustments to the container containing the footnotes \setupnote [footnote] [frame=off, @@ -588,62 +614,64 @@ background=, rulecolor=black, %% the line above the inserts rulethickness=1pt, - next={ }, - split=verystrict, - scope=page, style=Articlefootnotes] -\doifmodeelse {draft} {\setupnote[footnote][frame=on]} - -% Setup typing. -\setupnarrower - [middle=3mm, - left=5mm] +% Setup typing +\setupnarrower[middle=3mm] +\setupnarrower[left=5mm] \definetextbackground - [verbatim] + [typingbg] [frame=off, + location=paragraph, background=color, backgroundcolor=CGgray, - leftoffset=2mm,rightoffset=2mm, - topoffset=2mm,bottomoffset=2mm, - location=paragraph, + width=\hsize, + leftoffset=2mm, % doesnt work in the current beta align=flushleft] - -\doifmodeelse {draft} {\definetextbackground[verbatim][frame=on]} - -\definetextbackground - [verbatimitem] - [verbatim] - -\setuptextbackground - [verbatimitem] - [before=, - after=, - width=\the\dimexpr\hsize-10.5mm\relax] - + \startsetups typing:before - \blank[MediumCGblank] - \starttextbackground[verbatim] + \blank[MediumCGblank] + \starttextbackground[typingbg][style=DisplayMonospacedS] + \hfuzz=7.02pt % don't care if it bleeds in to the frame a little + \setupnarrower[left=2mm] % because leftoffset does not work in the current beta + \startnarrower[left] \stopsetups \startsetups typing:before:small - \blank[MediumCGblank] - \starttextbackground[verbatim] + \blank[MediumCGblank] + \starttextbackground[typingbg][style=DisplayMonospacedX] + \hfuzz=6.3pt % don't care if it bleeds in to the frame a little + \setupnarrower[left=2mm] + \startnarrower[left] \stopsetups \startsetups typing:after - \stoptextbackground - \blank[MediumCGblank] + \stopnarrower\par + \stoptextbackground + \blank[MediumCGblank] \stopsetups \startsetups typing:before:item - \starttextbackground[verbatimitem] +% \blank[3pt] + \startframedtext + [frame=off, + before=, + after=, + background=color, + backgroundcolor=CGgray, + width=\the\dimexpr\hsize-10.5mm\relax, + offset=3mm, + align=flushleft, + style=DisplayMonospacedS, + ] + \hfuzz=7.02pt % don't care if it bleeds in to the frame a little \stopsetups \startsetups typing:after:item - \stoptextbackground + \stopframedtext +% \blank[3pt] \stopsetups \setuptyping @@ -652,24 +680,15 @@ before=\setups{typing:before}, after=\setups{typing:after}] -\setuptype - [style=DisplayMonospaced] - -%D When verbatim becomes too large: - -\definetyping - [smalltyping] - +\definetyping[smalltyping] \setuptyping [smalltyping] [style=DisplayMonospacedX, before=\setups{typing:before:small}, after=\setups{typing:after}] -\unexpanded\def\smalltypefile{\typefile[smalltyping][]} - -%D Bullet lists. +% Bullet lists \setupitemgroup [itemize] [each] @@ -679,7 +698,15 @@ align=right, before={\blank[MediumCGblank]\startnarrower[left]}, after={\stopnarrower\blank[MediumCGblank]}, - inbetween={\blank[CGblank]}] + inbetween={\blank[CGblank]}, + ] + +\def\Href#1{\underbar{\hyphenatedurl{#1}}} + +\setupformulas[align=flushleft,margin=5mm] + +\setupquotation[before={\blank[CGblank]\switchtobodyfont[8pt]\setupinterlinespace[line=12pt]}, + after={\par\blank[CGblank]}] \definedescription [description] @@ -688,27 +715,8 @@ before={\blank}, after={\blank}] -\setupformula - [align=flushleft, - margin=5mm] - -\setupquotation - [before={\blank[CGblank]\switchtobodyfont[10pt]}, - after={\blank[CGblank]}] - -\setupwhitespace - [medium] - -\usemodule[abr-02,abr-03,abr-04] - -\unexpanded\def\Href#1{\underbar{\hyphenatedurl{#1}}} \unexpanded\def\CG {\ConTeXt\ group} -\setnewconstant\kindofpagetextareas\plusone % partial page. HH: low level, no high level switch (yet) - -%D There is a draft mode, which enables all frames: - -\doifmode {draft} {\showframe} - -\stopmodule +\usemodule[abr-02] +\endinput diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 6bd9bbd59..49621663d 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 07/04/19 12:29:22 +-- merge date : 07/16/19 18:23:09 do -- begin closure to overcome local limits and interference -- cgit v1.2.3