From 26a37aadfa1c26b389c7ef9c5f310a1e2ddf596c Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 3 Sep 2021 19:26:31 +0200 Subject: 2021-09-03 18:47:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-it.mkii | 22 + tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-imp-reorder.lua | 3 +- tex/context/base/mkiv/libs-ini.lua | 8 +- tex/context/base/mkiv/mult-prm.lua | 5 +- tex/context/base/mkiv/status-files.pdf | Bin 24897 -> 24912 bytes tex/context/base/mkiv/status-lua.pdf | Bin 250911 -> 251399 bytes tex/context/base/mkxl/back-lua.lmt | 60 +- tex/context/base/mkxl/back-mps.lmt | 14 +- tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 5 +- tex/context/base/mkxl/libs-imp-graphicsmagick.lmt | 8 +- tex/context/base/mkxl/lpdf-wid.lmt | 6 +- tex/context/base/mkxl/meta-imp-magick.mkxl | 77 +++ tex/context/base/mkxl/node-ini.lmt | 4 + tex/context/base/mkxl/page-ini.mkxl | 35 +- tex/context/base/mkxl/strc-mar.lmt | 759 +++++++++++++++++++++ tex/context/base/mkxl/strc-mar.mkxl | 8 +- tex/context/base/mkxl/strc-sec.mkxl | 63 +- tex/context/base/mkxl/syst-aux.lmt | 27 + tex/context/base/mkxl/syst-ini.mkxl | 9 +- tex/context/base/mkxl/tabl-com.mkxl | 2 + tex/context/base/mkxl/tabl-tbl.mkxl | 44 +- tex/context/base/mkxl/trac-vis.lmt | 101 ++- tex/context/interface/mkii/keys-it.xml | 22 + tex/generic/context/luatex/luatex-basics.tex | 12 +- tex/generic/context/luatex/luatex-fonts-enc.lua | 10 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 10 +- 31 files changed, 1215 insertions(+), 109 deletions(-) create mode 100644 tex/context/base/mkxl/meta-imp-magick.mkxl create mode 100644 tex/context/base/mkxl/strc-mar.lmt (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 5503480aa..8910c2f8c 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{2021.08.30 19:53} +\newcontextversion{2021.09.03 18:45} %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 f76ae9aec..94d3618ff 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{2021.08.30 19:53} +\edef\contextversion{2021.09.03 18:45} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index d3b670a0a..c1ce78f2d 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -79,6 +79,7 @@ \setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{and} \setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{append}{append} \setinterfacevariable{appendices}{appendici} \setinterfacevariable{appendix}{appendice} \setinterfacevariable{april}{aprile} @@ -150,6 +151,7 @@ \setinterfacevariable{commands}{comandi} \setinterfacevariable{comment}{commento} \setinterfacevariable{component}{componente} +\setinterfacevariable{compress}{compress} \setinterfacevariable{compressseparator}{compressseparator} \setinterfacevariable{compressstopper}{compressstopper} \setinterfacevariable{concept}{concetto} @@ -436,6 +438,7 @@ \setinterfacevariable{postscript}{postscript} \setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{preferenza} +\setinterfacevariable{prepend}{prepend} \setinterfacevariable{preview}{anteprima} \setinterfacevariable{previous}{precedente} \setinterfacevariable{previousevenpage}{paginapariprecedente} @@ -1367,6 +1370,7 @@ \setinterfaceelement{load}{carica} \setinterfaceelement{local}{locale} \setinterfaceelement{makeup}{makeup} +\setinterfaceelement{namednotation}{namednotation} \setinterfaceelement{namedtyping}{namedtyping} \setinterfaceelement{next}{successivo} \setinterfaceelement{place}{metti} @@ -1536,6 +1540,7 @@ \setinterfacecommand{definereferencelist}{definiscilistariferimenti} \setinterfacecommand{defineregister}{definisciregistro} \setinterfacecommand{definerule}{definiscilinea} +\setinterfacecommand{definesavebuffer}{startsavebuffer} \setinterfacecommand{definesection}{definiscisezione} \setinterfacecommand{definesectionblock}{definiscibloccosezione} \setinterfacecommand{definesorting}{definisciordinamento} @@ -1712,6 +1717,9 @@ \setinterfacecommand{moveformula}{spostaformula} \setinterfacecommand{moveongrid}{spostaagriglia} \setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{namedconstruction}{namedconstruction} +\setinterfacecommand{nameddescription}{nameddescription} +\setinterfacecommand{namedenumeration}{namedenumeration} \setinterfacecommand{navigating}{navigating} \setinterfacecommand{nodimension}{nientedimensioni} \setinterfacecommand{noheaderandfooterlines}{nientelineintestazionepdp} @@ -2083,6 +2091,13 @@ \setinterfacecommand{startmakeup}{iniziamakeup} \setinterfacecommand{startmarginblock}{iniziabloccomargine} \setinterfacecommand{startmarginrule}{inizialineamargine} +\setinterfacecommand{startnamedconstruction}{startnamedconstruction} +\setinterfacecommand{startnameddescription}{startnameddescription} +\setinterfacecommand{startnamedenumeration}{startnamedenumeration} +\setinterfacecommand{startnamedmatrix}{startnamedmatrix} +\setinterfacecommand{startnamedsection}{startnamedsection} +\setinterfacecommand{startnamedsubformulas}{startnamedsubformulas} +\setinterfacecommand{startnamedtyping}{startnamedtyping} \setinterfacecommand{startnarrower}{iniziapiustretto} \setinterfacecommand{startopposite}{iniziaopposto} \setinterfacecommand{startoverlay}{iniziasovrapposizione} @@ -2126,6 +2141,13 @@ \setinterfacecommand{stopmakeup}{terminamakeup} \setinterfacecommand{stopmarginblock}{terminabloccomargine} \setinterfacecommand{stopmarginrule}{terminalineamargine} +\setinterfacecommand{stopnamedconstruction}{stopnamedconstruction} +\setinterfacecommand{stopnameddescription}{stopnameddescription} +\setinterfacecommand{stopnamedenumeration}{stopnamedenumeration} +\setinterfacecommand{stopnamedmatrix}{stopnamedmatrix} +\setinterfacecommand{stopnamedsection}{stopnamedsection} +\setinterfacecommand{stopnamedsubformulas}{stopnamedsubformulas} +\setinterfacecommand{stopnamedtyping}{stopnamedtyping} \setinterfacecommand{stopnarrower}{terminapiustretto} \setinterfacecommand{stopopposite}{terminaopposto} \setinterfacecommand{stopoverlay}{terminasovrapposizione} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 02cd004aa..a85b450ea 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{2021.08.30 19:53} +\newcontextversion{2021.09.03 18:45} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 22a3fbe3e..ec6653a3a 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{2021.08.30 19:53} +\edef\contextversion{2021.09.03 18:45} %D Kind of special: diff --git a/tex/context/base/mkiv/font-imp-reorder.lua b/tex/context/base/mkiv/font-imp-reorder.lua index b2dec781c..323978cde 100644 --- a/tex/context/base/mkiv/font-imp-reorder.lua +++ b/tex/context/base/mkiv/font-imp-reorder.lua @@ -35,6 +35,7 @@ local trace_reorder = trackers.register("fonts.reorderlookups",function(v) trac local report_reorder = logs.reporter("fonts","reorder") local vectors = { } +otf.vectors = vectors -- kind of private vectors.arab = { gsub = { @@ -97,7 +98,7 @@ function otf.reorderlookups(tfmdata,vector) if not what then what = find(kind,"^gsub") and "gsub" or "gpos" end - local newwhen = order[what][feature] +-- local newwhen = order[what][feature] if not newwhen then -- skip elseif not when then diff --git a/tex/context/base/mkiv/libs-ini.lua b/tex/context/base/mkiv/libs-ini.lua index ed3fb842f..d3cfe634f 100644 --- a/tex/context/base/mkiv/libs-ini.lua +++ b/tex/context/base/mkiv/libs-ini.lua @@ -54,10 +54,10 @@ local function findlib(required) -- todo: cache for i=1,#list do local name = list[i] local found = findfile(name,"lib") - if not found then + if not found or found == "" then found = findfile(addsuffix(name,suffix),"lib") end - if found then + if found and found ~= "" then if trace then report("library %a resolved via %a path to %a",name,"tds lib",found) end @@ -70,9 +70,9 @@ local function findlib(required) -- todo: cache for i=1,#list do local full = joinfile(list[i],base) local found = isfile(full) and full - if found then + if found and found ~= "" then if trace then - report("library %a resolved via %a path to %a",name,"system",found) + report("library %a resolved via %a path to %a",full,"system",found) end return found end diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 81afd645b..28a8f41de 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -54,7 +54,6 @@ return { "splitdiscards", "splitfirstmarks", "topmarks", - "tracingalignments", "tracingassigns", "tracinggroups", "tracingifs", @@ -299,6 +298,7 @@ return { "crampedscriptstyle", "crampedtextstyle", "csstring", + "currentmarks", "defcsname", "dimensiondef", "dimexpression", @@ -321,6 +321,7 @@ return { "explicitdiscretionary", "explicithyphenpenalty", "firstvalidlanguage", + "flushmarks", "fontid", "fontmathcontrol", "fontspecifiedsize", @@ -506,9 +507,11 @@ return { "tokspre", "tolerant", "tpack", + "tracingalignments", "tracingexpressions", "tracingfonts", "tracinghyphenation", + "tracingmarks", "tracingmath", "undent", "unletfrozen", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index dd8c7d78d..f91a256e1 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 608b86c32..8c1e5bbc9 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/mkxl/back-lua.lmt b/tex/context/base/mkxl/back-lua.lmt index f74dfaeb5..9204650ea 100644 --- a/tex/context/base/mkxl/back-lua.lmt +++ b/tex/context/base/mkxl/back-lua.lmt @@ -41,6 +41,7 @@ local used = { } local shapes = { } local glyphs = { } local buffer = { } +local metadata = nil local b = 0 local converter = nil @@ -65,25 +66,11 @@ local function reset() end local function result() - -- todo: we're now still in the pdf backend but need different codeinjections - local codeinjections = backends.pdf.codeinjections - local identity = interactions.general.getidentity() - local jobname = environment.jobname or tex.jobname or "unknown" return { - metadata = { - unit = "bp", - jobname = jobname, - title = identity.title, - subject = identity.subject, - author = identity.author, - keywords = identity.keywords, - time = os.date("%Y-%m-%d %H:%M"), - engine = environment.luatexengine .. " " .. environment.luatexversion, - context = environment.version, - }, - fonts = fonts, - pages = pages, - shapes = shapes, + metadata = metadata, + fonts = fonts, + pages = pages, + shapes = shapes, } end @@ -128,6 +115,23 @@ local function finalize(driver,details) b[4] * bpfactor, }, } + if not metadata then + -- this has to happen while we're still running tex because we do + -- prerolls + local identity = interactions.general.getidentity() + local jobname = environment.jobname or tex.jobname or "unknown" + metadata = { + unit = "bp", + jobname = jobname, + title = identity.title, + subject = identity.subject, + author = identity.author, + keywords = identity.keywords, + time = os.date("%Y-%m-%d %H:%M"), + engine = environment.luatexengine .. " " .. environment.luatexversion, + context = environment.version, + } + end end local function wrapup(driver) @@ -195,7 +199,7 @@ local function flushcharacter(current, pos_h, pos_v, pos_r, font, char) end end -local function rule(pos_h, pos_v, pos_r, size_h, size_v, rule_s, rule_o) +local function flush_rule(current, 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, @@ -218,23 +222,22 @@ 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" + rule_s = normal_rule_code elseif subtype == outlinerule_code then - rule_s = "outline" + rule_s = outline_rule_code rule_o = getdata(current) else return end - return rule(pos_h, pos_v, pos_r, size_h, size_v, rule_s, rule_o) + return flush_rule(pos_h, pos_v, pos_r, size_h, size_v, rule_s, rule_o) end local function flushsimplerule(pos_h, pos_v, pos_r, size_h, size_v) - return rule(pos_h, pos_v, pos_r, size_h, size_v, "normal", nil) + return flush_rule(false,pos_h,pos_v,pos_r,size_h,size_v,normalrule_code,nil) end local function flushspecialrule(pos_h, pos_v, pos_r, w, h, d, l, outline) - -- no l support yet - return rule(pos_h, pos_v - d, pos_r, w, h + d, outline and "outline" or "normal") + return flush_rule(false,pos_h,pos_v-d,pos_r,w,h+d,outline and outlinerule_code or normalrule_code) end -- file stuff too @@ -296,11 +299,13 @@ drivers.install { name = "json", actions = { prepare = prepare, - initialize = initialize, - finalize = finalize, wrapup = wrapup, cleanup = cleanup, + -- + initialize = initialize, convert = convert, + finalize = finalize, + -- outputfilename = outputfilename, }, flushers = { @@ -309,6 +314,7 @@ drivers.install { rule = flushrule, simplerule = flushsimplerule, specialrule = flushspecialrule, + setstate = function() end, } } diff --git a/tex/context/base/mkxl/back-mps.lmt b/tex/context/base/mkxl/back-mps.lmt index 4a2a573c4..2da19ed87 100644 --- a/tex/context/base/mkxl/back-mps.lmt +++ b/tex/context/base/mkxl/back-mps.lmt @@ -40,6 +40,8 @@ local function reset() b = 0 end +-- todo: high efficient helpers: + 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);]] ] @@ -122,12 +124,12 @@ local function updatefontstate(id) end end -local function flushcharacter(current, pos_h, pos_v, pod_r, font, char) +local function flushcharacter(current, pos_h, pos_v, pos_r, font, char) b = b + 1 buffer[b] = f_glyph(last,char,pos_h*bpfactor,pos_v*bpfactor) end -local function flushrule(current, pos_h, pos_v, pod_r, size_h, size_v, subtype) +local function flushrule(current, pos_h, pos_v, pos_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) @@ -137,12 +139,12 @@ local function flushrule(current, pos_h, pos_v, pod_r, size_h, size_v, subtype) end end -local function flushsimplerule(pos_h, pos_v, pod_r, size_h, size_v) - flush_rule(false,pos_h,pos_v,pod_r,size_h,size_v,normalrule_code) +local function flushsimplerule(pos_h, pos_v, pos_r, size_h, size_v) + flushrule(false,pos_h,pos_v,pos_r,size_h,size_v,normalrule_code) end -local function flushspecialrule(pos_h, pos_v, pod_r, w, h, d, l, outline) - flush_rule(false,pos_h,pos_v-d,pod_r,w,h+d,outline and outlinerule_code or normalrule_code) +local function flushspecialrule(pos_h, pos_v, pos_r, w, h, d, l, outline) + flushrule(false,pos_h,pos_v-d,pos_r,w,h+d,outline and outlinerule_code or normalrule_code) end -- installer diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index a5e413124..bce0320e9 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.08.30 19:53} +\newcontextversion{2021.09.03 18:45} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 7f289e256..88a3a696d 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.08.30 19:53} +\immutable\edef\contextversion{2021.09.03 18:45} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error @@ -249,7 +249,8 @@ \loadmkxlfile{strc-tag} \loadmkxlfile{strc-doc} \loadmkxlfile{strc-num} -\loadmkxlfile{strc-mar} +%loadmkxlfile{strc-mar} +\doiffileelse{strc-mar-new.mkxl}{\loadmkxlfile{strc-mar-new}}{\loadmkxlfile{strc-mar}} \loadmkxlfile{strc-sbe} \loadmklxfile{strc-lst} \loadmkxlfile{strc-sec} diff --git a/tex/context/base/mkxl/libs-imp-graphicsmagick.lmt b/tex/context/base/mkxl/libs-imp-graphicsmagick.lmt index 6f5d1d967..25a31a1c4 100644 --- a/tex/context/base/mkxl/libs-imp-graphicsmagick.lmt +++ b/tex/context/base/mkxl/libs-imp-graphicsmagick.lmt @@ -55,7 +55,13 @@ function graphicsmagick.convert(specification) -- report("run %s, input file %a, outputfile %a",nofruns,inputname,outputname) -- - gm_execute { inputfile = inputname, outputfile = outputname } + specification.inputfile = inputname + specification.outputfile = outputname + -- + local okay, detail = gm_execute(specification) + if not okay then + report("error %a",detail) + end -- statistics.stoptiming(graphicsmagick) end diff --git a/tex/context/base/mkxl/lpdf-wid.lmt b/tex/context/base/mkxl/lpdf-wid.lmt index 87cfcccd1..29b0b2a9f 100644 --- a/tex/context/base/mkxl/lpdf-wid.lmt +++ b/tex/context/base/mkxl/lpdf-wid.lmt @@ -60,7 +60,10 @@ local v_auto = variables.auto local v_embed = variables.embed local v_max = variables.max local v_yes = variables.yes +local v_no = variables.no local v_compress = variables.compress +local v_list = variables.list +local v_title = variables.title local pdfconstant = lpdf.constant local pdfnull = lpdf.null @@ -709,8 +712,9 @@ local function insertrendering(specification) descriptor = codeinjections.embedfile { file = filename, mimetype = mimetype, -- yes or no + title = option[v_title], compress = option[v_compress] or false, - forcereference = true, + forcereference = option[v_list] ~= v_no, } end local clip = pdfdictionary { diff --git a/tex/context/base/mkxl/meta-imp-magick.mkxl b/tex/context/base/mkxl/meta-imp-magick.mkxl new file mode 100644 index 000000000..89b2ef4ec --- /dev/null +++ b/tex/context/base/mkxl/meta-imp-magick.mkxl @@ -0,0 +1,77 @@ +%D \module +%D [ file=meta-imp-magick, +%D version=2021.08.03, +%D title=\METAPOST\ Graphics, +%D subtitle=Magick Manipulations, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\registerctxluafile{libs-imp-graphicsmagick}{autosuffix} + +\startluacode + function mp.lmt_magick_convert() + local specification = metapost.getparameterset("magick") + local inputname = specification.filename + if inputname then + -- we don't want to trigger reuse when we have the same input file + local hash = md5.HEX(table.sequenced(specification)) + local outputname = file.addsuffix("m_k_i_v_mp_fuzzy_" .. hash,file.suffix(inputname)) + luatex.registertempfile(outputname) + -- make the table a bit unique and don't polute it + local whattodo = table.setmetatableindex( { + inputname = inputname, + outputname = outputname, + }, specification) + -- now do the magick + utilities.graphicsmagick.convert(whattodo) + -- and return the result + return [[figure("]] .. outputname .. [[")]] + else + -- bad luck + return [[textext("missing filename")]] + end + end +\stopluacode + +\startMPdefinitions + + presetparameters "magick" [ + filename = "unset", + % blur = [ radius = 10, sigma = 5 ], + % noise = [ type = 4 ], + ] ; + + def lmt_magick = applyparameters "magick" "lmt_do_magick" enddef ; + + vardef lmt_do_magick = lua.mp.lmt_magick_convert() enddef ; + +\stopMPdefinitions + +\continueifinputfile{meta-imp-magick.mkxl} + +\enabletrackers[*lib*] + +\startMPpage + draw lmt_magick [ + filename = "hacker.jpg", + blur = [ radius = 10, sigma = 5 ], + noise = [ type = 2 ], + ] ysized 4cm ; + + draw lmt_magick [ + filename = "hacker.jpg", + blur = [ radius = 5, sigma = 3 ], + noise = [ type = 4 ], + ] ysized 4cm shifted (0, -4cm) ; + + draw lmt_magick [ + filename = "hacker.jpg", + blur = [ radius = 10, sigma = 5 ], + noise = [ type = 4 ], + ] ysized 4cm shifted (0, -8cm) ; +\stopMPpage diff --git a/tex/context/base/mkxl/node-ini.lmt b/tex/context/base/mkxl/node-ini.lmt index e176b1214..a0c447954 100644 --- a/tex/context/base/mkxl/node-ini.lmt +++ b/tex/context/base/mkxl/node-ini.lmt @@ -40,6 +40,7 @@ tex.magicconstants = { -- we use tex.constants for something else local listcodes = mark(getsubtypes("list")) local rulecodes = mark(getsubtypes("rule")) local dircodes = mark(getsubtypes("dir")) +local markcodes = mark(getsubtypes("mark")) local glyphcodes = mark(getsubtypes("glyph")) local disccodes = mark(getsubtypes("disc")) local gluecodes = mark(getsubtypes("glue")) @@ -82,6 +83,7 @@ local nodecodes = simplified(node.types()) gluecodes = allocate(swapped(gluecodes,gluecodes)) dircodes = allocate(swapped(dircodes,dircodes)) +markcodes = allocate(swapped(markcodes,markcodes)) boundarycodes = allocate(swapped(boundarycodes,boundarycodes)) noadcodes = allocate(swapped(noadcodes,noadcodes)) radicalcodes = allocate(swapped(radicalcodes,radicalcodes)) @@ -104,6 +106,7 @@ mathvalues = allocate(swapped(mathvalues,mathvalues)) nodes.gluecodes = gluecodes nodes.dircodes = dircodes +nodes.markcodes = markcodes nodes.boundarycodes = boundarycodes nodes.noadcodes = noadcodes nodes.listcodes = listcodes @@ -129,6 +132,7 @@ nodes.nodecodes = nodecodes local subtypes = allocate { glue = gluecodes, dir = dircodes, + mark = markcodes, boundary = boundarycodes, noad = noadcodes, glyph = glyphcodes, diff --git a/tex/context/base/mkxl/page-ini.mkxl b/tex/context/base/mkxl/page-ini.mkxl index 69ff59cdb..71158e0a7 100644 --- a/tex/context/base/mkxl/page-ini.mkxl +++ b/tex/context/base/mkxl/page-ini.mkxl @@ -226,17 +226,30 @@ \newconditional\c_page_marks_building_successive_pages \settrue\c_page_marks_building_successive_pages -\def\page_marks_synchronize_page#1% box - {\strc_markings_synchronize\v!page{#1}{\ifconditional\c_page_marks_building_successive_pages\v!keep\fi}} - -\def\page_marks_synchronize_column#1#2#3#4% first last column box - {\ifnum#3=#1\relax - \strc_markings_synchronize{\number#3,\v!column:\number#3,\v!first,\v!column:\v!first}{#4}{}% - \orelse\ifnum#3=#2\relax - \strc_markings_synchronize{\number#3,\v!column:\number#3,\v!last, \v!column:\v!last }{#4}{}% - \else - \strc_markings_synchronize{\number#3,\v!column:\number#3 }{#4}{}% - \fi} + +\ifdefined\??markingclass + + \def\page_marks_synchronize_page#1% box + {} % \strc_markings_synchronize\v!page{1}{#1} + + \def\page_marks_synchronize_column#1#2#3#4% first last column box + {\strc_markings_synchronize\v!column{#3}{#4}} + +\else + + \def\page_marks_synchronize_page#1% box + {\strc_markings_synchronize\v!page{#1}{\ifconditional\c_page_marks_building_successive_pages\v!keep\fi}} + + \def\page_marks_synchronize_column#1#2#3#4% first last column box + {\ifnum#3=#1\relax + \strc_markings_synchronize{\number#3,\v!column:\number#3,\v!first,\v!column:\v!first}{#4}{}% + \orelse\ifnum#3=#2\relax + \strc_markings_synchronize{\number#3,\v!column:\number#3,\v!last,\v!column:\v!last}{#4}{}% + \else + \strc_markings_synchronize{\number#3,\v!column:\number#3}{#4}{}% + \fi} + +\fi % Page body building diff --git a/tex/context/base/mkxl/strc-mar.lmt b/tex/context/base/mkxl/strc-mar.lmt new file mode 100644 index 000000000..eb94f9fc3 --- /dev/null +++ b/tex/context/base/mkxl/strc-mar.lmt @@ -0,0 +1,759 @@ +if not modules then modules = { } end modules ['strc-mar'] = { + version = 1.001, + comment = "companion to strc-mar.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: cleanup stack (structures.marks.reset(v_all) also does the job) +-- todo: only commands.* print to tex, native marks return values + +local insert, concat = table.insert, table.concat +local tostring, next, rawget, type = tostring, next, rawget, type +local lpegmatch = lpeg.match + +local context = context +local commands = commands + +local implement = interfaces.implement + +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex + +local nuts = nodes.nuts +local tonut = nuts.tonut + +local getid = nuts.getid +local getlist = nuts.getlist +local getattr = nuts.getattr +local getbox = nuts.getbox + +local nextnode = nuts.traversers.node + +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local whatsit_code = nodecodes.whatsit + +local lateluawhatsit_code = whatsitcodes.latelua + +local texsetattribute = tex.setattribute + +local a_marks = attributes.private("marks") + +local trace_set = false trackers.register("marks.set", function(v) trace_set = v end) +local trace_get = false trackers.register("marks.get", function(v) trace_get = v end) +local trace_details = false trackers.register("marks.details", function(v) trace_details = v end) + +local report_marks = logs.reporter("structure","marks") + +local variables = interfaces.variables + +local v_first = variables.first +local v_last = variables.last +local v_previous = variables.previous +local v_next = variables.next +local v_top = variables.top +local v_bottom = variables.bottom +local v_current = variables.current +local v_default = variables.default +local v_page = variables.page +local v_all = variables.all +local v_keep = variables.keep + +local v_nocheck_suffix = ":" .. variables.nocheck + +local v_first_nocheck = variables.first .. v_nocheck_suffix +local v_last_nocheck = variables.last .. v_nocheck_suffix +local v_previous_nocheck = variables.previous .. v_nocheck_suffix +local v_next_nocheck = variables.next .. v_nocheck_suffix +local v_top_nocheck = variables.top .. v_nocheck_suffix +local v_bottom_nocheck = variables.bottom .. v_nocheck_suffix + +local structures = structures +local marks = structures.marks + +local settings_to_array = utilities.parsers.settings_to_array + +local boxes_too = false -- at some point we can also tag boxes or use a zero char + +directives.register("marks.boxestoo", function(v) boxes_too = v end) + +local data = marks.data or allocate() +marks.data = data + +storage.register("structures/marks/data", marks.data, "structures.marks.data") + +local stack, topofstack = { }, 0 + +local ranges = { + [v_page] = { + first = 0, + last = 0, + }, +} + +local function resolve(t,k) + if k then + if trace_set or trace_get then + report_marks("undefined mark, name %a",k) + end + local crap = { autodefined = true } -- maybe set = 0 and reset = 0 + t[k] = crap + return crap + else + -- weird: k is nil + end +end + +setmetatableindex(data, resolve) + +function marks.exists(name) + return rawget(data,name) ~= nil +end + +-- identify range + +local function sweep(head,first,last) + for n, id, subtype in nextnode, head do + -- we need to handle empty heads so we test for latelua + if id == glyph_code or (id == whatsit_code and subtype == lateluawhatsit_code) then -- brrr + local a = getattr(n,a_marks) + if not a then + -- next + elseif first == 0 then + first, last = a, a + elseif a > last then + last = a + end + elseif id == hlist_code or id == vlist_code then + if boxes_too then + local a = getattr(n,a_marks) + if not a then + -- next + elseif first == 0 then + first, last = a, a + elseif a > last then + last = a + end + end + local list = getlist(n) + if list then + first, last = sweep(list,first,last) + end + end + end + return first, last +end + +local classes = { } + +setmetatableindex(classes, function(t,k) local s = settings_to_array(k) t[k] = s return s end) + +local lasts = { } + +function marks.synchronize(class,n,option) + local box = getbox(n) + if box then + local first, last = sweep(getlist(box),0,0) + if option == v_keep and first == 0 and last == 0 then + if trace_get or trace_set then + report_marks("action %a, class %a, box %a","retain at synchronize",class,n) + end + -- todo: check if still valid first/last in range + first = lasts[class] or 0 + last = first + else + lasts[class] = last + local classlist = classes[class] + for i=1,#classlist do + local class = classlist[i] + local range = ranges[class] + if range then + range.first = first + range.last = last + else + range = { + first = first, + last = last, + } + ranges[class] = range + end + if trace_get or trace_set then + report_marks("action %a, class %a, first %a, last %a","synchronize",class,range.first,range.last) + end + end + end + elseif trace_get or trace_set then + report_marks("action %s, class %a, box %a","synchronize without content",class,n) + end +end + +-- define etc + +local function resolve(t,k) + if k == "fullchain" then + local fullchain = { } + local chain = t.chain + while chain and chain ~= "" do + insert(fullchain,1,chain) + chain = data[chain].chain + end + t[k] = fullchain + return fullchain + elseif k == "chain" then + t[k] = "" + return "" + elseif k == "reset" or k == "set" then + t[k] = 0 + return 0 + elseif k == "parent" then + t[k] = false + return false + end +end + +function marks.define(name,settings) + if not settings then + settings = { } + elseif type(settings) == "string" then + settings = { parent = settings } + end + data[name] = settings + local parent = settings.parent + if parent == nil or parent == "" or parent == name then + settings.parent = false + else + local dp = data[parent] + if not dp then + settings.parent = false + elseif dp.parent then + settings.parent = dp.parent + end + end + setmetatableindex(settings, resolve) +end + +for k, v in next, data do + setmetatableindex(v,resolve) -- runtime loaded table +end + +local function parentname(name) + local dn = data[name] + return dn and dn.parent or name +end + +function marks.relate(name,chain) + local dn = data[name] + if dn and not dn.parent then + if chain and chain ~= "" then + dn.chain = chain + local dc = data[chain] + if dc then + local children = dc.children + if not children then + children = { } + dc.children = children + end + children[#children+1] = name + end + elseif trace_set then + report_marks("error: invalid relation, name %a, chain %a",name,chain) + end + end +end + +local function resetchildren(new,name) + local dn = data[name] + if dn and not dn.parent then + local children = dn.children + if children then + for i=1,#children do + local ci = children[i] + new[ci] = false + if trace_set then + report_marks("action %a, parent %a, child %a","reset",name,ci) + end + resetchildren(new,ci) + end + end + end +end + +function marks.set(name,value) + local dn = data[name] + if dn then + local child = name + local parent = dn.parent + if parent then + name = parent + dn = data[name] + end + dn.set = topofstack + if not dn.reset then + dn.reset = 0 -- in case of selfdefined + end + local top = stack[topofstack] + local new = { } + if top then + for k, v in next, top do + local d = data[k] + local r = d.reset or 0 + local s = d.set or 0 + if r <= topofstack and s < r then + new[k] = false + else + new[k] = v + end + end + end + resetchildren(new,name) + new[name] = value + topofstack = topofstack + 1 + stack[topofstack] = new + if trace_set then + if name == child then + report_marks("action %a, name %a, index %a, value %a","set",name,topofstack,value) + else + report_marks("action %a, parent %a, child %a, index %a, value %a","set",parent,child,topofstack,value) + end + end + texsetattribute("global",a_marks,topofstack) + end +end + +local function reset(name) + if v_all then + if trace_set then + report_marks("action %a","reset all") + end + stack = { } + for name, dn in next, data do + local parent = dn.parent + if parent then + dn.reset = 0 + dn.set = 0 + end + end + else + local dn = data[name] + if dn then + local parent = dn.parent + if parent then + name = parent + dn = data[name] + end + if trace_set then + report_marks("action %a, name %a, index %a","reset",name,topofstack) + end + dn.reset = topofstack + local children = dn.children + if children then + for i=1,#children do + local ci = children[i] + reset(ci) + end + end + end + end +end + +marks.reset = reset + +function marks.get(n,name,value) + local dn = data[name] + if dn then + name = dn.parent or name + local top = stack[n] + if top then + context(top[name]) + end + end +end + +function marks.show(first,last) + if first and last then + for k=first,last do + local v = stack[k] + if v then + report_marks("% 4i: %s",k,table.sequenced(v)) + end + end + else + for k, v in table.sortedpairs(stack) do + report_marks("% 4i: %s",k,table.sequenced(v)) + end + end +end + +local function resolve(name,first,last,strict,quitonfalse,notrace) + local dn = data[name] + if dn then + local child = name + local parent = dn.parent + name = parent or child + dn = data[name] + local step, method + if first > last then + step, method = -1, "bottom-up" + else + step, method = 1, "top-down" + end + if trace_get and not notrace then + report_marks("action %a, strategy %a, name %a, parent %a, strict %a","request",method,child,parent,strict or false) + end + if trace_details and not notrace then + marks.show(first,last) + end + local r = dn.reset + local s = dn.set + if first <= last and first <= r then + if trace_get and not notrace then + report_marks("action %a, name %a, first %a, last %a, reset %a, index %a","reset first",name,first,last,r,first) + end + elseif first >= last and last <= r then + if trace_get and not notrace then + report_marks("action %a, name %a, first %a, last %a, reset %a, index %a","reset last",name,first,last,r,last) + end + elseif not stack[first] or not stack[last] then + if trace_get and not notrace then + -- a previous or next method can give an out of range, which is valid + report_marks("error: out of range, name %a, reset %a, index %a",name,r,first) + end + elseif strict then + local top = stack[first] + local fullchain = dn.fullchain + if not fullchain or #fullchain == 0 then + if trace_get and not notrace then + report_marks("warning: no full chain, trying again, name %a, first %a, last %a",name,first,last) + end + return resolve(name,first,last) + else + if trace_get and not notrace then + report_marks("found chain [ % => T ]",fullchain) + end + local chaindata = { } + local chainlength = #fullchain + for i=1,chainlength do + local cname = fullchain[i] + if data[cname].set > 0 then + local value = resolve(cname,first,last,false,false,true) + if value == "" then + if trace_get and not notrace then + report_marks("quitting chain, name %a, reset %a, start %a",name,r,first) + end + return "" + else + chaindata[i] = value + end + end + end + if trace_get and not notrace then + report_marks("using chain [ % => T ]",chaindata) + end + local value, index, found = resolve(name,first,last,false,false,true) + if value ~= "" then + if trace_get and not notrace then + report_marks("following chain [ % => T ]",chaindata) + end + for i=1,chainlength do + local cname = fullchain[i] + if data[cname].set > 0 and chaindata[i] ~= found[cname] then + if trace_get and not notrace then + report_marks("quiting chain, name %a, reset %a, index %a",name,r,first) + end + return "" + end + end + if trace_get and not notrace then + report_marks("found in chain, name %a, reset %a, start %a, index %a, value %a",name,r,first,index,value) + end + return value, index, found + elseif trace_get and not notrace then + report_marks("not found, name %a, reset %a",name,r) + end + end + else + for i=first,last,step do + local current = stack[i] + local value = current and current[name] + if value == nil then + -- search on + elseif value == false then + if quitonfalse then + return "" + end + elseif value == true then + if trace_get and not notrace then + report_marks("quitting steps, name %a, reset %a, start %a, index %a",name,r,first,i) + end + return "" + elseif value ~= "" then + if trace_get and not notrace then + report_marks("found in steps, name %a, reset %a, start %a, index %a, value %a",name,r,first,i,value) + end + return value, i, current + end + end + if trace_get and not notrace then + report_marks("not found in steps, name %a, reset %a",name,r) + end + end + end + return "" +end + +-- todo: column:first column:last + +local methods = { } + +local function doresolve(name,rangename,swap,df,dl,strict) + local range = ranges[rangename] or ranges[v_page] + local first = range.first + local last = range.last + if trace_get then + report_marks("action %a, name %a, range %a, swap %a, first %a, last %a, df %a, dl %a, strict %a", + "resolving",name,rangename,swap or false,first,last,df,dl,strict or false) + end + if swap then + first, last = last + df, first + dl + else + first, last = first + df, last + dl + end + local value, index, found = resolve(name,first,last,strict) + -- maybe something more + return value, index, found +end + +-- previous : last before sync +-- next : first after sync + +-- top : first in sync +-- bottom : last in sync + +-- first : first not top in sync +-- last : last not bottom in sync + +methods[v_previous] = function(name,range) return doresolve(name,range,false,-1,0,true ) end -- strict +methods[v_top] = function(name,range) return doresolve(name,range,false, 0,0,true ) end -- strict +methods[v_bottom] = function(name,range) return doresolve(name,range,true , 0,0,true ) end -- strict +methods[v_next] = function(name,range) return doresolve(name,range,true , 0,1,true ) end -- strict + +methods[v_previous_nocheck] = function(name,range) return doresolve(name,range,false,-1,0,false) end +methods[v_top_nocheck] = function(name,range) return doresolve(name,range,false, 0,0,false) end +methods[v_bottom_nocheck] = function(name,range) return doresolve(name,range,true , 0,0,false) end +methods[v_next_nocheck] = function(name,range) return doresolve(name,range,true , 0,1,false) end + +local function do_first(name,range,check) + if trace_get then + report_marks("action %a, name %a, range %a","resolving first",name,range) + end + local f_value, f_index, f_found = doresolve(name,range,false,0,0,check) + if f_found then + if trace_get then + report_marks("action %a, name %a, range %a","resolving last",name,range) + end + local l_value, l_index, l_found = doresolve(name,range,true ,0,0,check) + if l_found and l_index > f_index then + local name = parentname(name) + for i=f_index,l_index,1 do + local si = stack[i] + local sn = si[name] + if sn and sn ~= false and sn ~= true and sn ~= "" and sn ~= f_value then + if trace_get then + report_marks("action %a, name %a, range %a, index %a, value %a","resolving",name,range,i,sn) + end + return sn, i, si + end + end + end + end + if trace_get then + report_marks("resolved, name %a, range %a, using first",name,range) + end + return f_value, f_index, f_found +end + +local function do_last(name,range,check) + if trace_get then + report_marks("action %a, name %a, range %a","resolving last",name,range) + end + local l_value, l_index, l_found = doresolve(name,range,true ,0,0,check) + if l_found then + if trace_get then + report_marks("action %a, name %a, range %a","resolving first",name,range) + end + local f_value, f_index, f_found = doresolve(name,range,false,0,0,check) + if f_found and l_index > f_index then + local name = parentname(name) + for i=l_index,f_index,-1 do + local si = stack[i] + local sn = si[name] + if sn and sn ~= false and sn ~= true and sn ~= "" and sn ~= l_value then + if trace_get then + report_marks("action %a, name %a, range %a, index %a, value %a","resolving",name,range,i,sn) + end + return sn, i, si + end + end + end + end + if trace_get then + report_marks("resolved, name %a, range %a, using first",name,range) + end + return l_value, l_index, l_found +end + +methods[v_first ] = function(name,range) return do_first(name,range,true ) end +methods[v_last ] = function(name,range) return do_last (name,range,true ) end +methods[v_first_nocheck] = function(name,range) return do_first(name,range,false) end +methods[v_last_nocheck ] = function(name,range) return do_last (name,range,false) end + +methods[v_current] = function(name,range) -- range is ignored here + local top = stack[topofstack] + return top and top[parentname(name)] or "" +end + +local function fetched(name,range,method) + local value = (methods[method] or methods[v_first])(name,range) or "" + if not trace_get then + -- no report + elseif value == "" then + report_marks("nothing fetched, name %a, range %a, method %a",name,range,method) + else + report_marks("marking fetched, name %a, range %a, method %a, value %a",name,range,method,value) + end + return value or "" +end + +-- can be used at the lua end: + +marks.fetched = fetched + +-- this will move to a separate runtime modules + +marks.tracers = marks.tracers or { } + +function marks.tracers.showtable() + context.starttabulate { "|l|l|l|lp|lp|" } + context.tabulaterowbold("name","parent","chain","children","fullchain") + context.ML() + for k, v in table.sortedpairs(data) do + local parent = v.parent or "" + local chain = v.chain or "" + local children = v.children or { } + local fullchain = v.fullchain or { } + table.sort(children) -- in-place but harmless + context.tabulaterowtyp(k,parent,chain,concat(children," "),concat(fullchain," ")) + end + context.stoptabulate() +end + +-- pushing to context: + +-- local separator = context.nested.markingseparator +-- local command = context.nested.markingcommand +-- local ctxconcat = context.concat + +-- local function fetchonemark(name,range,method) +-- context(command(name,fetched(name,range,method))) +-- end + +-- local function fetchtwomarks(name,range) +-- ctxconcat( { +-- command(name,fetched(name,range,v_first)), +-- command(name,fetched(name,range,v_last)), +-- }, separator(name)) +-- end + +-- local function fetchallmarks(name,range) +-- ctxconcat( { +-- command(name,fetched(name,range,v_previous)), +-- command(name,fetched(name,range,v_first)), +-- command(name,fetched(name,range,v_last)), +-- }, separator(name)) +-- end + + local ctx_separator = context.markingseparator + local ctx_command = context.markingcommand + + local function fetchonemark(name,range,method) + ctx_command(name,fetched(name,range,method)) + end + + local function fetchtwomarks(name,range) + ctx_command(name,fetched(name,range,v_first)) + ctx_separator(name) + ctx_command(name,fetched(name,range,v_last)) + end + + local function fetchallmarks(name,range) + ctx_command(name,fetched(name,range,v_previous)) + ctx_separator(name) + ctx_command(name,fetched(name,range,v_first)) + ctx_separator(name) + ctx_command(name,fetched(name,range,v_last)) + end + +function marks.fetch(name,range,method) -- chapter page first | chapter column:1 first + if trace_get then + report_marks("marking requested, name %a, range %a, method %a",name,range,method) + end + if method == "" or method == v_default then + fetchonemark(name,range,v_first) + elseif method == v_both then + fetchtwomarks(name,range) + elseif method == v_all then + fetchallmarks(name,range) + else + fetchonemark(name,range,method) + end +end + +function marks.fetchonemark (name,range,method) fetchonemark (name,range,method) end +function marks.fetchtwomarks(name,range) fetchtwomarks(name,range ) end +function marks.fetchallmarks(name,range) fetchallmarks(name,range ) end + +-- here we have a few helpers .. will become commands.* + +local pattern = lpeg.afterprefix("li::") + +function marks.title(tag,n) + local listindex = lpegmatch(pattern,n) + if listindex then + commands.savedlisttitle(tag,listindex,"marking") + else + context(n) + end +end + +function marks.number(tag,n) -- no spec + local listindex = lpegmatch(pattern,n) + if listindex then + commands.savedlistnumber(tag,listindex) + else + -- no prefix (as it is the prefix) + context(n) + end +end + +-- interface + +implement { name = "markingtitle", actions = marks.title, arguments = "2 strings" } +implement { name = "markingnumber", actions = marks.number, arguments = "2 strings" } + +implement { name = "definemarking", actions = marks.define, arguments = "2 strings" } +implement { name = "relatemarking", actions = marks.relate, arguments = "2 strings" } +implement { name = "setmarking", actions = marks.set, arguments = "2 strings" } +implement { name = "resetmarking", actions = marks.reset, arguments = "string" } +implement { name = "synchronizemarking", actions = marks.synchronize, arguments = { "string", "integer", "string" } } +implement { name = "getmarking", actions = marks.fetch, arguments = "3 strings" } +implement { name = "fetchonemark", actions = marks.fetchonemark, arguments = "3 strings" } +implement { name = "fetchtwomarks", actions = marks.fetchtwomarks, arguments = "2 strings" } +implement { name = "fetchallmarks", actions = marks.fetchallmarks, arguments = "2 strings" } + +implement { name = "doifelsemarking", actions = { marks.exists, commands.doifelse }, arguments = "string" } diff --git a/tex/context/base/mkxl/strc-mar.mkxl b/tex/context/base/mkxl/strc-mar.mkxl index eb095a2a5..9067b4924 100644 --- a/tex/context/base/mkxl/strc-mar.mkxl +++ b/tex/context/base/mkxl/strc-mar.mkxl @@ -13,7 +13,7 @@ \writestatus{loading}{ConTeXt Structure Macros / Markings} -\registerctxluafile{strc-mar}{} +\registerctxluafile{strc-mar}{autosuffix} \unprotect @@ -34,6 +34,10 @@ %D implementations but in practice this is not a real problem. It's also easier now %D to extend this mechanism. +% first last previous next top bottom [:nocheck] +% current +% default page all keep + \definesystemattribute [marks] [global] \installcorenamespace{marking} @@ -54,6 +58,8 @@ \permanent\protected\tolerant\def\synchronizemarking[#1]#*[#2]#*[#3]{\ifvoid#2\else\clf_synchronizemarking{#1}#2{#3}\fi} \permanent \def\doifelsemarking #1{\clf_doifelsemarking{#1}} % no \noexpanded +\aliased\let\clearmarking\resetmarking % different in the new situation + \def\strc_markings_synchronize#1#2#3{\ifvoid#2\else\clf_synchronizemarking{#1}#2{#3}\fi} % called in page-ini \permanent\protected\tolerant\def\setmarking[#1]#:#2% diff --git a/tex/context/base/mkxl/strc-sec.mkxl b/tex/context/base/mkxl/strc-sec.mkxl index 54b74fe4c..6a4442e85 100644 --- a/tex/context/base/mkxl/strc-sec.mkxl +++ b/tex/context/base/mkxl/strc-sec.mkxl @@ -511,9 +511,9 @@ %aliased\let\resetcurrentstructuremarks \relax \aliased\let\resetcurrentstructuremarkswithpage\relax -\permanent\protected\def\resetallstructuremarks {\resetmarking[\firstsectionname]} % will become option (was \v!section-1) -\permanent\protected\def\resetcurrentstructuremarks {\resetmarking[\lastsectionname]} % will become option -%permanent\protected\def\resetcurrentstructuremarkswithpage{\resetmarking[\lastsectionname]} % will become option +\permanent\protected\def\resetallstructuremarks {\clearmarking[\firstsectionname]} % will become option (was \v!section-1) +\permanent\protected\def\resetcurrentstructuremarks {\clearmarking[\lastsectionname]} % will become option +%permanent\protected\def\resetcurrentstructuremarkswithpage{\clearmarking[\lastsectionname]} % will become option % We could use a commandhandler here but sections are somewhat special in the % sense that we have two ways of chaining: the main section (levels) as well @@ -557,7 +557,7 @@ \edef\currenthead{#1}% \let\currentsection\currenthead % just an alias \global\advance\maxstructuredepth\plusone - \setevalue{\??headlevel#1}{\the\maxstructuredepth}% + \edefcsname\??headlevel#1\endcsname{\the\maxstructuredepth}% \setstructurelevel{#1}{\sectionlevel{#1}}% \normalexpanded{\setheadparameter{\s!parent}{\??head\lastsectionname}}% TO BE CHECKED, WE HAVE A HELPER \the\everydefinesection @@ -1028,21 +1028,46 @@ \smashedbox\b_sectioning_delayed \fi} -\protected\def\strc_rendering_place_head_section % see hidden below - {\global\setbox\b_sectioning_delayed\hpack\bgroup - \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% - \hpack\headreferenceattributes{}% also does the mark - \theheadsynchronization - \egroup} - -\protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check - {\xdefcsname\??hiddenheadattr\currenthead\endcsname - {\headreferenceattributes}% can be used when making a box - \xdefcsname\??hiddenheadsync\currenthead\endcsname - {\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax - \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% - \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference - \theheadsynchronization}} % and it's a node anyway +\ifdefined\??markingclass % uses a node, so we need to embed / bind + + \protected\def\strc_rendering_place_head_section % see hidden below + {\global\setbox\b_sectioning_delayed\hpack\bgroup + \hpack\headreferenceattributes\bgroup + \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% also does the mark + \egroup + \theheadsynchronization + \egroup} + + \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check + {\xdefcsname\??hiddenheadattr\currenthead\endcsname + {\headreferenceattributes}% can be used when making a box + \xdefcsname\??hiddenheadsync\currenthead\endcsname + {\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax + % {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax + \hpack\headreferenceattributes\bgroup + \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference + \egroup + \theheadsynchronization}} % and it's a node anyway + +\else % uses attributes so no interference + + \protected\def\strc_rendering_place_head_section % see hidden below + {\global\setbox\b_sectioning_delayed\hpack\bgroup + \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% + \hpack\headreferenceattributes{}% also does the mark + \theheadsynchronization + \egroup} + + \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check + {\xdefcsname\??hiddenheadattr\currenthead\endcsname + {\headreferenceattributes}% can be used when making a box + \xdefcsname\??hiddenheadsync\currenthead\endcsname + {\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax + \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% + \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference + \theheadsynchronization}} % and it's a node anyway + +\fi \permanent\def\synchronizehead #1{\begincsname\??hiddenheadsync#1\endcsname} \permanent\def\theheadreferenceattributes#1{\begincsname\??hiddenheadattr#1\endcsname} diff --git a/tex/context/base/mkxl/syst-aux.lmt b/tex/context/base/mkxl/syst-aux.lmt index eeb1c5aac..2d744e309 100644 --- a/tex/context/base/mkxl/syst-aux.lmt +++ b/tex/context/base/mkxl/syst-aux.lmt @@ -780,3 +780,30 @@ implement { public = true, actions = function() getshape("widowpenalties") end, } + +implement { + name = "loopcs", + public = true, + arguments = { "integerargument", "csname" }, + actions = function(n,cs) + local c = context[cs] + if n < 0 then + for i=-n,1 do c() end + else + for i= 1,n do c() end + end + end +} +implement { + name = "loopcsn", + public = true, + arguments = { "integerargument", "csname" }, + actions = function(n,cs) + local c = context[cs] + if n < 0 then + for i=-n,1 do c(i) end + else + for i= 1,n do c(i) end + end + end +} diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl index f5cd28d32..a2a1aed0f 100644 --- a/tex/context/base/mkxl/syst-ini.mkxl +++ b/tex/context/base/mkxl/syst-ini.mkxl @@ -305,6 +305,8 @@ \permanent\countdef\c_syst_min_allocated_iohandle = 203 \c_syst_min_allocated_iohandle = 0 \permanent\countdef\c_syst_max_allocated_iohandle = 204 \c_syst_max_allocated_iohandle = 1023 \permanent\countdef\c_syst_min_allocated_attribute = 205 \c_syst_min_allocated_attribute = 1024 % 0-1023 : private +\permanent\countdef\c_syst_min_allocated_mark = 206 \c_syst_min_allocated_mark = 16 % a few scratch ones +\permanent\countdef\c_syst_max_allocated_mark = 207 \c_syst_max_allocated_mark = 1024 % max 10K in luametatex anyway \permanent\countdef\c_syst_last_allocated_count = 211 \c_syst_last_allocated_count = \c_syst_min_allocated_register \permanent\countdef\c_syst_last_allocated_dimen = 212 \c_syst_last_allocated_dimen = \c_syst_min_allocated_register @@ -314,7 +316,7 @@ \permanent\countdef\c_syst_last_allocated_toks = 216 \c_syst_last_allocated_toks = \c_syst_min_allocated_register \permanent\countdef\c_syst_last_allocated_read = 217 \c_syst_last_allocated_read = \c_syst_min_allocated_iohandle \permanent\countdef\c_syst_last_allocated_write = 218 \c_syst_last_allocated_write = \c_syst_min_allocated_iohandle -\permanent\countdef\c_syst_last_allocated_marks = 219 \c_syst_last_allocated_marks = \c_syst_min_allocated_register +\permanent\countdef\c_syst_last_allocated_marks = 219 \c_syst_last_allocated_marks = \c_syst_min_allocated_mark \permanent\countdef\c_syst_min_counter_value = 253 \c_syst_min_counter_value = -"7FFFFFFF \permanent\countdef\c_syst_max_counter_value = 254 \c_syst_max_counter_value = "7FFFFFFF @@ -334,7 +336,8 @@ \permanent\let\wlog\gobbleoneargument % Let's get rid of this one. -%D The allocators share a common helper macro. +%D The allocators share a common helper macro. Marks might be changed to work in lower +%D regions and we always assumes allocation. \permanent\protected\def\newcount {\syst_basics_allocate\c_syst_last_allocated_count \count \countdef \c_syst_max_allocated_register} \permanent\protected\def\newdimen {\syst_basics_allocate\c_syst_last_allocated_dimen \dimen \dimendef \c_syst_max_allocated_register} @@ -344,7 +347,7 @@ \permanent\protected\def\newtoks {\syst_basics_allocate\c_syst_last_allocated_toks \toks \toksdef \c_syst_max_allocated_register} \permanent\protected\def\newread {\syst_basics_allocate\c_syst_last_allocated_read \read \integerdef\c_syst_max_allocated_iohandle} \permanent\protected\def\newwrite {\syst_basics_allocate\c_syst_last_allocated_write \write \integerdef\c_syst_max_allocated_iohandle} -\permanent\protected\def\newmarks {\syst_basics_allocate\c_syst_last_allocated_marks \marks \integerdef\c_syst_max_allocated_register} +\permanent\protected\def\newmarks {\syst_basics_allocate\c_syst_last_allocated_marks \marks \integerdef\c_syst_max_allocated_mark } \firstvalidlanguage \plusone % so zero is ignored in hyphenation, this might become the default diff --git a/tex/context/base/mkxl/tabl-com.mkxl b/tex/context/base/mkxl/tabl-com.mkxl index 0803fc0ee..d8eb7ada7 100644 --- a/tex/context/base/mkxl/tabl-com.mkxl +++ b/tex/context/base/mkxl/tabl-com.mkxl @@ -108,6 +108,8 @@ \permanent\protected\lettonothing\RB \permanent\protected\lettonothing\RT +\permanent\protected\lettonothing\NS % span + \popoverloadmode \installmacrostack\BC diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl index c248c13a2..0b6669d4e 100644 --- a/tex/context/base/mkxl/tabl-tbl.mkxl +++ b/tex/context/base/mkxl/tabl-tbl.mkxl @@ -329,8 +329,10 @@ \protected\def\tabl_tabulate_setups_check {\begincsname\??tabulatesetup\the\c_tabl_tabulate_column\endcsname} +\let\tabl_tabulate_kooh\relax + \protected\def\tabl_tabulate_entry_before{\ignorespaces\tabl_tabulate_hook} -\protected\def\tabl_tabulate_entry_after {\unskip\unskip\ifmmode\else\endgraf\fi} +\protected\def\tabl_tabulate_entry_after {\unskip\unskip\ifmmode\else\endgraf\fi\tabl_tabulate_kooh} \protected\def\tabl_tabulate_shaped_par_begin {\dowithnextboxcs\tabl_tabulate_shaped_par_finish\vbox\bgroup} @@ -3017,4 +3019,44 @@ \c!foregroundcolor=, \c!foregroundstyle=\tabulationparameter\c!headstyle] +%D Only for simple cases (read:myself): +%D +%D \starttyping +%D \starttabulate[|c|c|c|] +%D \NC 1 \NC second column \NC third column \NC \NR +%D \NC 2 \NC second \NC third \NC \NR +%D \NC 3 r \NS[1][r]second & third \NC \NR +%D \NC 3 c \NS[1][c]second & third \NC \NR +%D \NC 3 l \NS[1][l]second & third \NC \NR +%D \stoptabulate +%D \stoptyping + +\installcorenamespace{tabulatespanb} +\installcorenamespace{tabulatespana} + +\noaligned\def\tabl_tabulate_span{\omit\span\omit\span\omit\span} + +%\letcsname\??tabulatespanb l\endcsname\relax +\letcsname\??tabulatespana l\endcsname\hfill +\letcsname\??tabulatespanb c\endcsname\hfill +\letcsname\??tabulatespana c\endcsname\hfill +\letcsname\??tabulatespanb m\endcsname\hfill +\letcsname\??tabulatespana m\endcsname\hfill +\letcsname\??tabulatespanb r\endcsname\hfill +%\letcsname\??tabulatespana r\endcsname\relax + +\noaligned\tolerant\def\tabl_tabulate_NS[#1]#*[#2]% + {\NC\loopcs{#1}\tabl_tabulate_span + \gdef\tabl_tabulate_kooh{\begincsname\??tabulatespana#2\endcsname}% + \begincsname\??tabulatespanb#2\endcsname + \ignorespaces} + +\appendtoks + \enforced\let\NS\tabl_tabulate_NS +\to \t_tabl_tabulate_initializers_first + +% \appendtoks +% \let\NS\tabl_tabulate_NS +% \to \t_tabl_tabulate_initializers_second + \protect \endinput diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt index 74bfd01e3..48e8ceeb8 100644 --- a/tex/context/base/mkxl/trac-vis.lmt +++ b/tex/context/base/mkxl/trac-vis.lmt @@ -56,6 +56,7 @@ local getdepth = nuts.getdepth local getexpansion = nuts.getexpansion local getstate = nuts.getstate local getoffsets = nuts.getoffsets +local getindex = nuts.getindex local isglyph = nuts.isglyph @@ -156,11 +157,13 @@ local modes = { dir = 0x0400000, par = 0x0800000, mathglue = 0x1000000, + mark = 0x2000000, + insert = 0x4000000, } local usedfont, exheight, emwidth local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_marginkern, l_mathlistkern, l_italic, l_origin, l_discretionary, l_expansion, l_line, l_space, l_depth, - l_dir, l_whatsit + l_dir, l_whatsit, l_mark, l_insert local enabled = false local layers = { } @@ -172,6 +175,7 @@ local preset_all = preset_makeup + modes.fontkern + modes.marginkern + modes.mathlistkern + modes.whatsit + modes.glyph + modes.user + modes.math + modes.dir + modes.whatsit + modes.mathglue + + modes.mark + modes.insert function visualizers.setfont(id) usedfont = id or current_font() @@ -226,6 +230,8 @@ local function initialize() l_depth = layers.depth l_dir = layers.dir l_par = layers.par + l_mark = layers.mark + l_insert = layers.insert -- if not userrule then userrule = nuts.rules.userrule @@ -484,11 +490,11 @@ local fontkern, italickern, marginkern, mathlistkern do end -local glyphexpansion do +local ruledglyphexpansion do local f_cache = caches["glyphexpansion"] - glyphexpansion = function(head,current) + ruledglyphexpansion = function(head,current) local extra = getexpansion(current) if extra and extra ~= 0 then extra = extra / 1000 @@ -554,7 +560,50 @@ local kernexpansion do end -local whatsit do +local ruledmark do + + local set_code = nodes.markcodes.set + + local sm_cache = setmetatableindex(caches["setmark"], function(t,index) + local info = sometext(formatters["SM:%i"](index),usedfont,nil,"trace:w") -- whatsit + setattr(info,a_layer,l_mark) + t[index] = info + return info + end) + + local rm_cache = setmetatableindex(caches["resetmark"], function(t,index) + local info = sometext(formatters["RM:%i"](index),usedfont,nil,"trace:w") -- whatsit + setattr(info,a_layer,l_mark) + t[index] = info + return info + end) + + ruledmark = function(head,current) + local index = getindex(current) + local info = getsubtype(current) == set_code and sm_cache[index] or rm_cache[index] + head, current = insertnodeafter(head,current,copylist(info)) + return head, current + end + +end + +local ruledinsert do + + local si_cache = setmetatableindex(caches["insert"], function(f,index) + local info = sometext(formatters["SI:%i"](index),usedfont,nil,"trace:w") -- whatsit + setattr(info,a_layer,l_insert) + i_cache[index] = info + end) + + ruledinsert = function(head,current) + local info = si_cache[getindex(current)] + head, current = insertnodeafter(head,current,copylist(info)) + return head, current + end + +end + +local ruledwhatsit do local whatsitcodes = nodes.whatsitcodes local w_cache = caches["whatsit"] @@ -584,7 +633,7 @@ local whatsit do [whatsitcodes.setstate] = "SET", -- can't happen because these are added after visualizing } - whatsit = function(head,current) + ruledwhatsit = function(head,current) local what = getsubtype(current) local info = w_cache[what] if info then @@ -600,7 +649,7 @@ local whatsit do end -local dir, par do +local ruleddir, ruledpar do local dircodes = nodes.dircodes local dirvalues = nodes.dirvalues @@ -620,7 +669,7 @@ local dir, par do par = "PAR", } - par = function(head,current) + ruledpar = function(head,current) local what = "par" -- getsubtype(current) local info = d_cache[what] if info then @@ -634,7 +683,7 @@ local dir, par do return head, current end - dir = function(head,current) + ruleddir = function(head,current) local what = getsubtype(current) if what == cancel_code then what = "cancel" @@ -657,11 +706,11 @@ local dir, par do end -local user do +local ruleduser do local u_cache = caches["user"] - user = function(head,current) + ruleduser = function(head,current) local what = getsubtype(current) local info = u_cache[what] if info then @@ -677,7 +726,7 @@ local user do end -local math do +local ruledmath do local mathcodes = nodes.mathcodes local m_cache = { @@ -689,7 +738,7 @@ local math do endmath = "E", } - math = function(head,current) + ruledmath = function(head,current) local what = getsubtype(current) local tag = mathcodes[what] local skip = getkern(current) + getwidth(current) -- surround @@ -1269,6 +1318,8 @@ do local mathlistkern_code = nodecodes.mathlistkern local dir_code = nodecodes.dir local par_code = nodecodes.par + local mark_code = nodecodes.mark + local insert_code = nodecodes.insert local kerncodes = nodes.kerncodes local fontkern_code = kerncodes.fontkern @@ -1321,6 +1372,8 @@ do local trace_dir = false local trace_par = false local trace_math_glue = false + local trace_mark = false + local trace_insert = false local current = head local previous = nil local attr = unsetvalue @@ -1367,6 +1420,8 @@ do trace_dir = false trace_par = false trace_math_glue = false + trace_mark = false + trace_insert = false if id == kern_code then goto kern else @@ -1399,6 +1454,8 @@ do trace_dir = a & 0x0400000 ~= 0 trace_par = a & 0x0800000 ~= 0 trace_math_glue = a & 0x1000000 ~= 0 + trace_mark = a & 0x2000000 ~= 0 + trace_insert = a & 0x4000000 ~= 0 end elseif a == unsetvalue then goto list @@ -1410,7 +1467,7 @@ do head, current = ruledglyph(head,current,previous) end if trace_expansion then - head, current = glyphexpansion(head,current) + head, current = ruledglyphexpansion(head,current) end elseif id == disc_code then if trace_discretionary then @@ -1439,15 +1496,15 @@ do goto list elseif id == whatsit_code then if trace_whatsit then - head, current = whatsit(head,current) + head, current = ruledwhatsit(head,current) end elseif id == user_code then if trace_user then - head, current = user(head,current) + head, current = ruleduser(head,current) end elseif id == math_code then if trace_math then - head, current = math(head,current) + head, current = ruledmath(head,current) end elseif id == marginkern_code then if trace_kern then @@ -1455,11 +1512,19 @@ do end elseif id == dir_code then if trace_dir then - head, current = dir(head,current) + head, current = ruleddir(head,current) end elseif id == par_code then if trace_par then - head, current = par(head,current) + head, current = ruledpar(head,current) + end + elseif id == mark_code then + if trace_mark then + head, current = ruledmark(head,current) + end + elseif id == insert_code then + if trace_insert then + head, current = ruledinsert(head,current) end end goto next diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index 78a2254d4..a18c9212b 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -82,6 +82,7 @@ + @@ -153,6 +154,7 @@ + @@ -439,6 +441,7 @@ + @@ -1376,6 +1379,7 @@ + @@ -1548,6 +1552,7 @@ + @@ -1724,6 +1729,9 @@ + + + @@ -2095,6 +2103,13 @@ + + + + + + + @@ -2138,6 +2153,13 @@ + + + + + + + diff --git a/tex/generic/context/luatex/luatex-basics.tex b/tex/generic/context/luatex/luatex-basics.tex index 1180c68e6..7b84c7093 100644 --- a/tex/generic/context/luatex/luatex-basics.tex +++ b/tex/generic/context/luatex/luatex-basics.tex @@ -31,8 +31,8 @@ local registered = {} function gadgets.functions.reverve() - local numb = newtoken.scan_int() - local name = newtoken.scan_string() + local numb = token.scan_int() + local name = token.scan_string() local okay = string.gsub(name,"[\string\\ ]","") registered[okay] = numb texio.write_nl("reserving lua function '"..okay.."' with number "..numb) @@ -62,15 +62,18 @@ % an example of usage (if we ever support it it will go to the plain gadgets module): % +% \newluafunction\UcharcatLuaOne +% \newluafunction\UcharcatLuaTwo +% % \directlua { % % local cct = nil % local chr = nil % % gadgets.functions.register("UcharcatLuaOne",function() -% chr = newtoken.scan_int() +% chr = token.scan_int() % cct = tex.getcatcode(chr) -% tex.setcatcode(chr,newtoken.scan_int()) +% tex.setcatcode(chr,token.scan_int()) % tex.sprint(unicode.utf8.char(chr)) % end) % @@ -89,5 +92,4 @@ % A:\the\catcode65:\Ucharcat 65 5:A:\the\catcode65\par % A:\the\catcode65:\Ucharcat 65 11:A:\the\catcode65\par - \endinput diff --git a/tex/generic/context/luatex/luatex-fonts-enc.lua b/tex/generic/context/luatex/luatex-fonts-enc.lua index 2bc6b71bf..d8725c214 100644 --- a/tex/generic/context/luatex/luatex-fonts-enc.lua +++ b/tex/generic/context/luatex/luatex-fonts-enc.lua @@ -16,10 +16,18 @@ fonts.encodings = encodings encodings.agl = { } encodings.known = { } +encodings.glyphlistfilename = "font-age.lua" + setmetatable(encodings.agl, { __index = function(t,k) if k == "unicodes" then logs.report("fonts","loading (extended) adobe glyph list") - local unicodes = dofile(resolvers.findfile("font-age.lua")) + local foundname = resolvers.findfile(encodings.glyphlistfilename) or "" + local unicodes = foundname ~= "" and dofile(foundname) + if type(unicodes) ~= "table" then + logs.report("fonts","missing or invalid (extended) adobe glyph list") + -- no message + unicodes = { } + end encodings.agl = { unicodes = unicodes } return unicodes else diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index b77497ea1..fc87d5d69 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 : 2021-08-30 19:53 +-- merge date : 2021-09-03 18:45 do -- begin closure to overcome local limits and interference @@ -10263,10 +10263,16 @@ local encodings={} fonts.encodings=encodings encodings.agl={} encodings.known={} +encodings.glyphlistfilename="font-age.lua" setmetatable(encodings.agl,{ __index=function(t,k) if k=="unicodes" then logs.report("fonts","loading (extended) adobe glyph list") - local unicodes=dofile(resolvers.findfile("font-age.lua")) + local foundname=resolvers.findfile(encodings.glyphlistfilename) or "" + local unicodes=foundname~="" and dofile(foundname) + if type(unicodes)~="table" then + logs.report("fonts","missing or invalid (extended) adobe glyph list") + unicodes={} + end encodings.agl={ unicodes=unicodes } return unicodes else -- cgit v1.2.3