diff options
author | Hans Hagen <pragma@wxs.nl> | 2017-07-27 17:53:52 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2017-07-27 17:53:52 +0200 |
commit | ab56ea38d2f4f5b521ef097bac92812f6070ef55 (patch) | |
tree | e5f2ba9e66f1b1ef8f7b32f91aed0d744a14a0da /tex | |
parent | f7bfb1deb04d4ad101dbabf4d635d33cd98aa0a1 (diff) | |
download | context-ab56ea38d2f4f5b521ef097bac92812f6070ef55.tar.gz |
2017-07-27 16:23:00
Diffstat (limited to 'tex')
59 files changed, 1851 insertions, 760 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 9c02951b9..e6208bc86 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{2017.07.17 00:20} +\newcontextversion{2017.07.27 16:17} %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 b6ffca4a5..6008167a6 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{2017.07.17 00:20} +\edef\contextversion{2017.07.27 16:17} %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 269d1e545..a79b0b9e8 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -687,6 +687,7 @@ \setinterfaceconstant{bottomoffset}{offsetfondo} \setinterfaceconstant{bottomspace}{spaziofondo} \setinterfaceconstant{bottomstate}{statofondo} +\setinterfaceconstant{break}{break} \setinterfaceconstant{buffer}{buffer} \setinterfaceconstant{cache}{cache} \setinterfaceconstant{calculate}{calcola} diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua index c3b644bda..48f2f2ac6 100644 --- a/tex/context/base/mkiv/attr-col.lua +++ b/tex/context/base/mkiv/attr-col.lua @@ -60,6 +60,8 @@ local formatters = string.formatters local interfaces = interfaces local implement = interfaces.implement +local texgetattribute = tex.getattribute + -- We can distinguish between rules and glyphs but it's not worth the trouble. A -- first implementation did that and while it saves a bit for glyphs and rules, it -- costs more resourses for transparencies. So why bother. @@ -448,6 +450,12 @@ function colors.forcesupport(value) -- can move to attr-div colors.enable(value) end +function colors.toattributes(name) + local mc = list[a_color][name] + local mm = texgetattribute(a_selector) + return (mm == unsetvalue and 1) or mm or 1, mc or list[a_color][1] or unsetvalue +end + -- transparencies local a_transparency = attributes.private('transparency') @@ -554,6 +562,10 @@ function transparencies.forcesupport(value) -- can move to attr-div transparencies.enable(value) end +function transparencies.toattribute(name) + return list[a_transparency][name] or unsetvalue +end + --- colorintents: overprint / knockout attributes.colorintents = attributes.colorintents or { } diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua index da7ec202f..0b27b0541 100644 --- a/tex/context/base/mkiv/back-exp.lua +++ b/tex/context/base/mkiv/back-exp.lua @@ -149,7 +149,7 @@ local overloads = fonts.mappings.overloads -- todo: more locals (and optimize) -local exportversion = "0.34" +local exportversion = "0.35" local mathmlns = "http://www.w3.org/1998/Math/MathML" local contextns = "http://www.contextgarden.net/context/export" -- whatever suits local cssnamespaceurl = "@namespace context url('%namespace%') ;" @@ -347,16 +347,17 @@ do -- /* text-align : justify ; */ local documenttemplate = [[ -document, %namespace%div.document { +document, +%namespace%div.document { font-size : %size% !important ; max-width : %width% !important ; text-width : %align% !important ; hyphens : %hyphens% !important ; -} -]] +}]] local styletemplate = [[ -%element%[detail="%detail%"], %namespace%div.%element%.%detail% { +%element%[detail="%detail%"], +%namespace%div.%element%.%detail% { display : inline ; font-style : %style% ; font-variant : %variant% ; @@ -416,7 +417,7 @@ local styletemplate = [[ }) -- local colorspecification = xml.css.colorspecification - local fontspecification = xml.css.fontspecification + local fontspecification = xml.css.fontspecification for element, details in sortedhash(usedstyles) do for detail, data in sortedhash(details) do local s = fontspecification(data.style) @@ -431,6 +432,7 @@ local styletemplate = [[ weight = s.weight or "inherit", family = s.family or "inherit", color = c or "inherit", + display = s.display and "block" or nil, }) end end @@ -550,7 +552,7 @@ end do - local fields = { "title", "subtitle", "author", "keywords" } + local fields = { "title", "subtitle", "author", "keywords", "url", "version" } local function checkdocument(root) local data = root.data @@ -717,16 +719,32 @@ end do + local strippedtag = structurestags.strip -- we assume global styles + local highlight = { } - usedstyles.highlight = highlight + local construct = { } - local strippedtag = structurestags.strip -- we assume global styles + usedstyles.highlight = highlight + usedstyles.construct = construct + + function structurestags.sethighlight(name,style,color,mode) + if not highlight[name] then + highlight[name] = { + style = style, + color = color, + mode = mode == 1 and "display" or nil, + } + end + end - function structurestags.sethighlight(style,color) - highlight[strippedtag(locatedtag("highlight"))] = { - style = style, -- xml.css.fontspecification(style), - color = color, -- xml.css.colorspec(color), - } + function structurestags.setconstruct(name,style,color,mode) + if not construct[name] then + construct[name] = { + style = style, + color = color, + mode = mode == 1 and "display" or nil, + } + end end end @@ -1735,21 +1753,26 @@ do local function hascontent(data) for i=1,#data do local di = data[i] - if not di then + if not di or di.tg == "ignore" then -- - elseif di.content then - return true else - local d = di.data - if d and #d > 0 and hascontent(d) then + local content = di.content + if content == " " then + -- + elseif content then return true + else + local d = di.data + if d and #d > 0 and hascontent(d) then + return true + end end end end end function structurestags.settablecell(rows,columns,align) - if align > 0 or rows > 1 or columns > 1 then + if align > 0 or rows > 1 or columns > 1 or kind > 0 then tabledata[locatedtag("tablecell")] = { rows = rows, columns = columns, @@ -1784,10 +1807,11 @@ do local tabulatedata = { } - function structurestags.settabulatecell(align) - if align > 0 then + function structurestags.settabulatecell(align,kind) + if align > 0 or kind > 0 then tabulatedata[locatedtag("tabulatecell")] = { align = align, + kind = kind, -- 1 = bold head } end end @@ -1815,6 +1839,12 @@ do elseif align == 3 then setattribute(di,"align","middle") end + local kind = hash.kind + if kind == 1 then + setattribute(di,"kind","strong") + elseif kind == 2 then + setattribute(di,"kind","equals") + end end end @@ -1891,13 +1921,6 @@ do local depth = 0 local inline = 0 - local function bpar(result) - result[#result+1] = "\n<p>" - end - local function epar(result) - result[#result+1] = "</p>\n" - end - local function emptytag(result,embedded,element,nature,di) -- currently only break but at some point local a = di.attributes -- we might add detail etc if a then -- happens seldom @@ -1919,6 +1942,34 @@ do end end + -- local function stripspaces(di) + -- local d = di.data + -- local n = #d + -- local m = 0 + -- for i=1,n do + -- local di = d[i] + -- if di.tg then + -- m = m + 1 + -- d[m] = di + -- end + -- end + -- for i=n,m+1,-1 do + -- d[i] = nil + -- end + -- end + -- + -- -- simpler: + + local function stripspaces(di) + local d = di.data + for i=1,#d do + local di = d[i] + if not di.tg then + di.content = "" + end + end + end + local function begintag(result,embedded,element,nature,di,skip) local index = di.n local fulltag = di.fulltag @@ -1972,6 +2023,11 @@ do if extra then extra(di,element,index,fulltag) end + -- + if di.record then + stripspaces(di) + end + -- if exportproperties then local p = specification.userdata if not p then @@ -2044,7 +2100,9 @@ do if metadata then result[#result+1] = f_metadata_begin(depth) for k, v in table.sortedpairs(metadata) do - result[#result+1] = f_metadata(depth+1,k,lpegmatch(p_entity,v)) + if v ~= "" then + result[#result+1] = f_metadata(depth+1,k,lpegmatch(p_entity,v)) + end end result[#result+1] = f_metadata_end(depth) end @@ -2333,7 +2391,7 @@ end -- collector code local function push(fulltag,depth) - local tg, n, detail + local tg, n, detail, element, nature, record local specification = specifications[fulltag] if specification then tg = specification.tagname @@ -2344,9 +2402,12 @@ local function push(fulltag,depth) tg, n = lpegmatch(tagsplitter,fulltag) n = tonumber(n) -- to tonumber in tagsplitter end - local p = properties[tg] - local element = p and p.export or tg - local nature = p and p.nature or "inline" -- defaultnature + local p = properties[tg] + if p then + element = p.export or tg + nature = p.nature or "inline" -- defaultnature + record = p.record + end local treedata = tree.data local t = { -- maybe we can use the tag table tg = tg, @@ -2358,6 +2419,7 @@ local function push(fulltag,depth) data = { }, attribute = currentattribute, parnumber = currentparagraph, + record = record, -- we can consider storing properties } treedata[#treedata+1] = t currentdepth = currentdepth + 1 @@ -2541,6 +2603,8 @@ local function finishexport() end end +-- inserts ? + local function collectresults(head,list,pat,pap) -- is last used (we also have currentattribute) local p for n in traverse_nodes(head) do @@ -2859,19 +2923,6 @@ function nodes.handlers.export(head) -- hooks into the page builder end -- continueexport() restart = true - --- local function f(head,depth,pat) --- for n in node.traverse(head) do --- local a = n[a_tagged] or pat --- local t = taglist[a] --- print(depth,n,a,t and table.concat(t," ")) --- if n.id == hlist_code or n.id == vlist_code and n.list then --- f(n.list,depth+1,a) --- end --- end --- end --- f(head,1) - collectresults(tonut(head)) if trace_export then report_export("%w<!-- stop flushing page -->",currentdepth) @@ -2886,7 +2937,7 @@ function builders.paragraphs.tag(head) local subtype = getsubtype(n) if subtype == line_code then setattr(n,a_textblock,noftextblocks) - elseif subtype == glue_code or subtype == kern_code then + elseif subtype == glue_code or subtype == kern_code then -- no need to set fontkerns setattr(n,a_textblock,0) end end @@ -2895,6 +2946,9 @@ end do + local xmlcollected = xml.collected + local xmlsetcomment = xml.setcomment + local xmlpreamble = [[ <?xml version="1.0" encoding="UTF-8" standalone="%standalone%" ?> @@ -2955,14 +3009,16 @@ local cssheadlink = [[ local elementtemplate = [[ /* element="%element%" detail="%detail%" chain="%chain%" */ -%element%, %namespace%div.%element% { +%element%, +%namespace%div.%element% { display: %display% ; }]] local detailtemplate = [[ /* element="%element%" detail="%detail%" chain="%chain%" */ -%element%[detail=%detail%], %namespace%div.%element%.%detail% { +%element%[detail=%detail%], +%namespace%div.%element%.%detail% { display: %display% ; }]] @@ -2983,7 +3039,7 @@ local htmltemplate = [[ </head> <body> - <div xmlns="http://www.pragma-ade.com/context/export"> + <div class="document" xmlns="http://www.pragma-ade.com/context/export"> <div class="warning">Rendering can be suboptimal because there is no default/fallback css loaded.</div> @@ -3061,7 +3117,7 @@ local htmltemplate = [[ local implicits = { } local explicits = { } local overloads = { } - for e in xml.collected(xmltree,"*") do + for e in xmlcollected(xmltree,"*") do local at = e.at if at then local explicit = at.explicit @@ -3082,7 +3138,7 @@ local htmltemplate = [[ end end end - for e in xml.collected(xmltree,"*") do + for e in xmlcollected(xmltree,"*") do local at = e.at if at then local internal = at.internal @@ -3214,7 +3270,7 @@ local htmltemplate = [[ local function remap(specification,source,target) local comment = nil -- share comments - for c in xml.collected(source,"*") do + for c in xmlcollected(source,"*") do if not c.special then local tg = c.tg local ns = c.ns @@ -3226,44 +3282,45 @@ local htmltemplate = [[ -- elseif tg == "a" then -- c.ns = "" else - -- if tg == "tabulatecell" or tg == "tablecell" then - local dt = c.dt - local nt = #dt - if nt == 0 or (nt == 1 and dt[1] == "") then - if comment then - c.dt = comment - else - xml.setcomment(c,"empty") - comment = c.dt - end + local dt = c.dt + local nt = #dt + if nt == 0 or (nt == 1 and dt[1] == "") then + if comment then + c.dt = comment + else + xmlsetcomment(c,"empty") + comment = c.dt end - -- end + end local at = c.at local class = nil + local label = nil if tg == "document" then at.href = nil at.detail = nil at.chain = nil elseif tg == "metavariable" then - at.detail = "metaname-" .. at.name + label = at.name + at.detail = "metaname-" .. label class = makeclass(tg,at) else class = makeclass(tg,at) end local id = at.id local href = at.href + local attr = nil if id then - id = lpegmatch(p_cleanid, id) or id + id = lpegmatch(p_cleanid, id) or id if href then href = lpegmatch(p_cleanhref,href) or href - c.at = { + attr = { class = class, id = id, href = href, onclick = addclicks and f_onclick(href) or nil, } else - c.at = { + attr = { class = class, id = id, } @@ -3271,18 +3328,22 @@ local htmltemplate = [[ else if href then href = lpegmatch(p_cleanhref,href) or href - c.at = { + attr = { class = class, href = href, onclick = addclicks and f_onclick(href) or nil, } else - c.at = { + attr = { class = class, } end end c.tg = "div" + c.at = attr + if label then + attr.label = label + end end end end @@ -3292,11 +3353,19 @@ local htmltemplate = [[ local addsuffix = file.addsuffix local joinfile = file.join + local nameonly = file.nameonly + local basename = file.basename local embedfile = false directives.register("export.embed",function(v) embedfile = v end) local embedmath = false - local function stopexport(v) + function structurestags.finishexport() + + if exporting then + exporting = false + else + return + end starttiming(treehash) -- @@ -3314,10 +3383,8 @@ local htmltemplate = [[ -- wrapups.hashlistdata() -- - if type(v) ~= "string" or v == v_yes or v == "" then - v = tex.jobname - end - + local askedname = finetuning.file + -- -- we use a dedicated subpath: -- -- ./jobname-export @@ -3333,8 +3400,12 @@ local htmltemplate = [[ -- ./jobname-export/styles/jobname-images.css -- ./jobname-export/styles/jobname-templates.css - local basename = file.basename(v) - local basepath = basename .. "-export" + if type(askedname) ~= "string" or askedname == v_yes or askedname == "" then + askedname = tex.jobname + end + + local usedname = nameonly(askedname) + local basepath = usedname .. "-export" local imagepath = joinfile(basepath,"images") local stylepath = joinfile(basepath,"styles") @@ -3358,21 +3429,23 @@ local htmltemplate = [[ end -- we're now on the dedicated export subpath so we can't clash names + -- + -- a xhtml suffix no longer seems to be work well with browsers - local xmlfilebase = addsuffix(basename .. "-raw","xml" ) - local xhtmlfilebase = addsuffix(basename .. "-tag","xhtml") - local htmlfilebase = addsuffix(basename .. "-div","xhtml") - local specificationfilebase = addsuffix(basename .. "-pub","lua" ) + local xmlfilebase = addsuffix(usedname .. "-raw","xml" ) + local xhtmlfilebase = addsuffix(usedname .. "-tag","xhtml") + local htmlfilebase = addsuffix(usedname .. "-div","html") + local specificationfilebase = addsuffix(usedname .. "-pub","lua" ) local xmlfilename = joinfile(basepath, xmlfilebase ) local xhtmlfilename = joinfile(basepath, xhtmlfilebase ) local htmlfilename = joinfile(basepath, htmlfilebase ) local specificationfilename = joinfile(basepath, specificationfilebase) -- - local defaultfilebase = addsuffix(basename .. "-defaults", "css") - local imagefilebase = addsuffix(basename .. "-images", "css") - local stylefilebase = addsuffix(basename .. "-styles", "css") - local templatefilebase = addsuffix(basename .. "-templates","css") + local defaultfilebase = addsuffix(usedname .. "-defaults", "css") + local imagefilebase = addsuffix(usedname .. "-images", "css") + local stylefilebase = addsuffix(usedname .. "-styles", "css") + local templatefilebase = addsuffix(usedname .. "-templates","css") -- local defaultfilename = joinfile(stylepath,defaultfilebase ) local imagefilename = joinfile(stylepath,imagefilebase ) @@ -3410,7 +3483,7 @@ local htmltemplate = [[ local list = table.unique(settings_to_array(cssfile)) for i=1,#list do local source = addsuffix(list[i],"css") - local target = joinfile(stylepath,file.basename(source)) + local target = joinfile(stylepath,basename(source)) cssfiles[#cssfiles+1] = source if not lfs.isfile(source) then source = joinfile("../",source) @@ -3445,7 +3518,7 @@ local htmltemplate = [[ -- only for testing attach { data = concat{ wholepreamble(true), result }, - name = file.basename(xmlfilename), + name = basename(xmlfilename), registered = "export", title = "raw xml export", method = v_hidden, @@ -3457,8 +3530,8 @@ local htmltemplate = [[ -- for k, v in sortedhash(embedded) do -- attach { -- data = v, - -- file = file.basename(k), - -- name = file.addsuffix(k,"xml"), + -- file = basename(k), + -- name = addsuffix(k,"xml"), -- registered = k, -- reference = k, -- title = "xml export snippet: " .. k, @@ -3483,13 +3556,13 @@ local htmltemplate = [[ io.savedata(xmlfilename,result) report_export("saving css image definitions in %a",imagefilename) - io.savedata(imagefilename,wrapups.allusedimages(basename)) + io.savedata(imagefilename,wrapups.allusedimages(usedname)) report_export("saving css style definitions in %a",stylefilename) - io.savedata(stylefilename,wrapups.allusedstyles(basename)) + io.savedata(stylefilename,wrapups.allusedstyles(usedname)) report_export("saving css template in %a",templatefilename) - io.savedata(templatefilename,allusedelements(basename)) + io.savedata(templatefilename,allusedelements(usedname)) -- additionally we save an xhtml file; for that we load the file as xml tree @@ -3505,9 +3578,10 @@ local htmltemplate = [[ -- at the tex end local identity = interactions.general.getidentity() + local metadata = structures.tags.getmetadata() local specification = { - name = file.removesuffix(v), + name = usedname, identifier = os.uuid(), images = wrapups.uniqueusedimages(), imagefile = joinfile("styles",imagefilebase), @@ -3524,6 +3598,7 @@ local htmltemplate = [[ author = validstring(finetuning.author) or validstring(identity.author), firstpage = validstring(finetuning.firstpage), lastpage = validstring(finetuning.lastpage), + metadata = metadata, } report_export("saving specification in %a",specificationfilename,specificationfilename) @@ -3537,10 +3612,15 @@ local htmltemplate = [[ remap(specification,xmltree) + -- believe it or not, but a <title/> can prevent viewing in browsers + local title = specification.title if not title or title == "" then - title = "no title" -- believe it or not, but a <title/> can prevent viewing in browsers + title = metadata.title + if not title or title == "" then + title = usedname -- was: "no title" + end end local variables = { @@ -3555,7 +3635,7 @@ local htmltemplate = [[ -- finally we report how an epub file can be made (using the specification) report_export("") - report_export('create epub with: mtxrun --script epub --make "%s" [--purge --rename --svgmath]',file.nameonly(basename)) + report_export('create epub with: mtxrun --script epub --make "%s" [--purge --rename --svgmath]',usedname) report_export("") stoptiming(treehash) @@ -3564,17 +3644,8 @@ local htmltemplate = [[ local appendaction = nodes.tasks.appendaction local enableaction = nodes.tasks.enableaction - function structurestags.setupexport(t) - merge(finetuning,t) - keephyphens = finetuning.hyphen == v_yes - exportproperties = finetuning.properties - if exportproperties == v_no then - exportproperties = false - end - end - - local function startexport(v) - if v and not exporting then + function structurestags.initializeexport() + if not exporting then report_export("enabling export to xml") -- not yet known in task-ini appendaction("shipouts","normalizers", "nodes.handlers.export") @@ -3584,19 +3655,19 @@ local htmltemplate = [[ -- appendaction("finalizers","lists","builders.paragraphs.tag") -- enableaction("finalizers","builders.paragraphs.tag") luatex.registerstopactions(structurestags.finishexport) - exporting = v + exporting = true end end - function structurestags.finishexport() - if exporting then - stopexport(exporting) - exporting = false + function structurestags.setupexport(t) + merge(finetuning,t) + keephyphens = finetuning.hyphen == v_yes + exportproperties = finetuning.properties + if exportproperties == v_no then + exportproperties = false end end - directives.register("backend.export",startexport) -- maybe .name - statistics.register("xml exporting time", function() if exporting then return string.format("%s seconds, version %s", statistics.elapsedtime(treehash),exportversion) @@ -3624,6 +3695,7 @@ implement { { "lastpage" }, { "svgstyle" }, { "cssfile" }, + { "file" }, } } } @@ -3634,6 +3706,12 @@ implement { } implement { + name = "initializeexport", + actions = structurestags.initializeexport, +} + + +implement { name = "settagitemgroup", actions = structurestags.setitemgroup, arguments = { "boolean", "integer", "string" } @@ -3684,7 +3762,13 @@ implement { implement { name = "settaghighlight", actions = structurestags.sethighlight, - arguments = { "string", "integer" } + arguments = { "string", "string", "integer", "integer" } +} + +implement { + name = "settagconstruct", + actions = structurestags.setconstruct, + arguments = { "string", "string", "integer", "integer" } } implement { @@ -3708,7 +3792,7 @@ implement { implement { name = "settagtabulatecell", actions = structurestags.settabulatecell, - arguments = "integer" + arguments = { "integer", "integer" }, } implement { diff --git a/tex/context/base/mkiv/back-exp.mkiv b/tex/context/base/mkiv/back-exp.mkiv index 48f4d3c48..6e24ed641 100644 --- a/tex/context/base/mkiv/back-exp.mkiv +++ b/tex/context/base/mkiv/back-exp.mkiv @@ -94,7 +94,9 @@ \appendtoks \unexpanded\def\dotagtabulatecell - {\iftrialtypesetting\else\clf_settagtabulatecell\c_tabl_tabulate_align\fi}% + {\iftrialtypesetting\else + \clf_settagtabulatecell\c_tabl_tabulate_align\c_tabl_tabulate_kind + \fi}% \unexpanded\def\dotagtabulatesignal {\dontleavehmode\signalcharacter\ignorespaces}% \to \everyenableelements @@ -110,9 +112,26 @@ \to \everyenableelements \appendtoks % frozen and assumed global per highlight class + \unexpanded\def\dotagconstruct + {\iftrialtypesetting\else + \clf_settagconstruct + {\currentstartstop}% + {\startstopparameter\c!style}% + \attribute\colorattribute + \ifvmode\plusone\else\zerocount\fi + \relax + \fi}% +\to \everyenableelements + +\appendtoks % frozen and assumed global per highlight class \unexpanded\def\dotaghighlight {\iftrialtypesetting\else - \clf_settaghighlight{\highlightparameter\c!style}\attribute\colorattribute\relax + \clf_settaghighlight + {\currenthighlight}% + {\highlightparameter\c!style} + \attribute\colorattribute + \ifvmode\plusone\else\zerocount\fi + \relax \fi}% \to \everyenableelements @@ -239,10 +258,24 @@ \c!properties=\v!no, % no: ignore, yes: as attribute, otherwise: use as prefix \c!hyphen=\v!no, \c!svgstyle=, - \c!cssfile=] + \c!cssfile=, + \c!file={\backendparameter\c!export}] % downward compatibility + +\resetsystemmode\v!export + +\unexpanded\def\doinitializeexport + {\edef\p_export{\backendparameter\c!export}% + \ifx\p_export\empty \else + \setuptagging[\c!state=\v!start]% + \clf_initializeexport + \setsystemmode\v!export + \exportingtrue + \glet\doinitializeexport\relax + \fi} -\def\dosynchronizeexport - {\let\currentexport\empty +\unexpanded\def\dostartexport + {%\glet\dostartexport\relax + \let\currentexport\empty \clf_setupexport align {\exportparameter\c!align}% bodyfont \dimexpr\exportparameter\c!bodyfont\relax @@ -256,37 +289,35 @@ lastpage {\exportparameter\c!lastpage}% svgstyle {\exportparameter\c!svgstyle}% cssfile {\exportparameter\c!cssfile}% + file {\exportparameter\c!file}% \relax} +\unexpanded\def\dostopexport + {\glet\dostopexport\relax + \clf_finishexport} + \appendtoks - \doifsomething{\backendparameter\c!export}\dosynchronizeexport + \doinitializeexport +\to \everysetupbackend + +\appendtoks + \ifexporting + \dostartexport + \fi \to \everystarttext % better (before pdf gets closed, so we can embed), but it needs testing: \appendtoks - \clf_finishexport + \ifexporting + \dostopexport + \fi \to \everystoptext \appendtoks - \doifsomething{\backendparameter\c!export}\dosynchronizeexport % in case it is done inside \starttext + \ifexporting + \dostartexport % in case it is done inside \starttext + \fi \to \everysetupdocument -% \appendtoks -% \doifsomething{\backendparameter\c!xhtml} -% {\enabledirectives[backend.export.xhtml=\backendparameter\c!xhtml]}% -% \doifsomething{\backendparameter\c!css} -% {\enabledirectives[backend.export.css={\backendparameter\c!css}]}% -% \doifsomething{\backendparameter\c!alternative} -% {\enabledirectives[backend.export.alternative={\backendparameter\c!alternative}]}% -% \to \everysetupbackend - -\appendtoks - \doifelsenothing{\backendparameter\c!export} - {\resetsystemmode\v!export} - {\setuptagging[\c!state=\v!start]% - \enabledirectives[backend.export=\backendparameter\c!export]% - \setsystemmode\v!export}% -\to \everysetupbackend - \protect \endinput diff --git a/tex/context/base/mkiv/colo-imp-rgb.mkiv b/tex/context/base/mkiv/colo-imp-rgb.mkiv index 934071ed9..6e7e44f8c 100644 --- a/tex/context/base/mkiv/colo-imp-rgb.mkiv +++ b/tex/context/base/mkiv/colo-imp-rgb.mkiv @@ -59,6 +59,7 @@ \definecolor [darkgray] [s=.40] \definecolor [middlegray] [s=.625] \definecolor [lightgray] [s=.85] +\definecolor [palegray] [s=.75] %D These colors are mapped to interface dependant colornames. diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 94b08824b..267ff3ec2 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2017.07.17 00:20} +\newcontextversion{2017.07.27 16:17} %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 802d4fa29..4a629c6f1 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -41,7 +41,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2017.07.17 00:20} +\edef\contextversion{2017.07.27 16:17} \edef\contextkind {beta} %D For those who want to use this: @@ -184,13 +184,8 @@ \loadmarkfile{supp-box} -%loadmarkfile{supp-vis} % replaced by trac-vis -%loadmarkfile{supp-fun} % mostly replaced - \loadmarkfile{supp-ran} \loadmarkfile{supp-mat} -%loadmarkfile{spac-cha} % obsolete -%loadmarkfile{supp-num} % obsolete \loadmarkfile{core-uti} \loadmkvifile{file-job} @@ -230,7 +225,7 @@ \loadmarkfile{node-bck} % overloads anch-pgr (experimental and undocumented) -\loadmarkfile{pack-cut} % leftovers from trac-vis +\loadmarkfile{pack-cut} \loadmarkfile{lang-mis} \loadmarkfile{lang-url} @@ -503,7 +498,7 @@ \loadmarkfile{typo-scr} \loadmarkfile{phys-dim} -\loadmarkfile{node-rul} +\loadmarkfile{node-rul} % beware, defined \underbar so after math \loadmkvifile{font-sol} % font solutions \loadmkvifile{strc-not} diff --git a/tex/context/base/mkiv/core-con.lua b/tex/context/base/mkiv/core-con.lua index 10f8fc2ed..e643dc46c 100644 --- a/tex/context/base/mkiv/core-con.lua +++ b/tex/context/base/mkiv/core-con.lua @@ -21,7 +21,7 @@ local lower, upper, rep, match, gsub = string.lower, string.upper, string.rep, s local utfchar, utfbyte = utf.char, utf.byte local tonumber, tostring, type, rawset = tonumber, tostring, type, rawset local P, S, R, Cc, Cf, Cg, Ct, Cs, C = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.Cs, lpeg.C -local lpegmatch = lpeg.match +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local context = context local commands = commands @@ -44,7 +44,6 @@ local languages = languages local ctx_labeltext = context.labeltext local ctx_LABELTEXT = context.LABELTEXT -local ctx_WORD = context.WORD local ctx_space = context.space local ctx_convertnumber = context.convertnumber local ctx_highordinalstr = context.highordinalstr @@ -1149,15 +1148,19 @@ implement { -- These are just helpers but not really for the tex end. Do we have to -- use translate here? -local whitespace = lpeg.patterns.whitespace -local word = lpeg.patterns.utf8uppercharacter^-1 * (1-whitespace)^1 +local whitespace = lpegpatterns.whitespace +local word = lpegpatterns.utf8uppercharacter^-1 * (1-whitespace)^1 local pattern_one = Cs( whitespace^0 * word^-1 * P(1)^0) local pattern_all = Cs((whitespace^1 + word)^1) function converters.word (s) return s end -- dummies for typos function converters.words(s) return s end -- dummies for typos -function converters.Word (s) return lpegmatch(pattern_one,s) or s end -function converters.Words(s) return lpegmatch(pattern_all,s) or s end + +local function Word (s) return lpegmatch(pattern_one,s) or s end +local function Words(s) return lpegmatch(pattern_all,s) or s end + +converters.Word = Word +converters.Words = Words converters.upper = characters.upper converters.lower = characters.lower @@ -1324,7 +1327,7 @@ local function currentdate(str,currentlanguage) -- second argument false : no la context("%02i",year % 100) elseif tag == v_month or tag == "m" then if currentlanguage == false then - context(months[month]) + context(Word(months[month])) elseif mnemonic then ctx_labeltext(variables[mnemonic[month]]) else @@ -1332,7 +1335,7 @@ local function currentdate(str,currentlanguage) -- second argument false : no la end elseif tag == v_MONTH then if currentlanguage == false then - ctx_WORD(variables[months[month]]) + context(Word(variables[months[month]])) elseif mnemonic then ctx_LABELTEXT(variables[mnemonic[month]]) else @@ -1344,7 +1347,7 @@ local function currentdate(str,currentlanguage) -- second argument false : no la context(month) elseif tag == v_day or tag == "d" then if currentlanguage == false then - context(days[day]) + context(day) else ctx_convertnumber(v_day,day) -- why not direct end @@ -1358,14 +1361,14 @@ local function currentdate(str,currentlanguage) -- second argument false : no la elseif tag == v_weekday or tag == "w" then local wd = weekday(day,month,year) if currentlanguage == false then - context(days[wd]) + context(Word(days[wd])) else ctx_labeltext(variables[days[wd]]) end elseif tag == v_WEEKDAY then local wd = weekday(day,month,year) if currentlanguage == false then - ctx_WORD(days[wd]) + context(Word(days[wd])) else ctx_LABELTEXT(variables[days[wd]]) end @@ -1391,30 +1394,31 @@ local function currentdate(str,currentlanguage) -- second argument false : no la end end -implement { - name = "currentdate", - actions = currentdate, - arguments = { "string", "string" } -} + implement { - name = "rawdate", - actions = currentdate, - arguments = { "string", false } + name = "currentdate", + arguments = { "string", "string", "string" }, + actions = function(pattern,default,language) + currentdate( + pattern == "" and default or pattern, + language == "" and false or language + ) + end, } implement { name = "unihex", + arguments = "integer", actions = { formatters["U+%05X"], context }, - arguments = "integer" } -local n = lpeg.R("09")^1 / tonumber +local n = R("09")^1 / tonumber local p = Cf( Ct("") * Cg(Cc("year") * (n )) * P("-")^-1 * Cg(Cc("month") * (n + Cc( 1))) * P("-")^-1 - * Cg(Cc("day") * (n + Cc( 1))) * lpeg.patterns.whitespace^-1 + * Cg(Cc("day") * (n + Cc( 1))) * whitespace^-1 * Cg(Cc("hour") * (n + Cc( 0))) * P(":")^-1 * Cg(Cc("min") * (n + Cc( 0))) , rawset) diff --git a/tex/context/base/mkiv/core-con.mkiv b/tex/context/base/mkiv/core-con.mkiv index a4d358e04..df0973132 100644 --- a/tex/context/base/mkiv/core-con.mkiv +++ b/tex/context/base/mkiv/core-con.mkiv @@ -416,8 +416,7 @@ \def\syst_converters_current_date[#1]% {\begingroup \the\everycurrentdate - \doifsomething{#1}{\edef\currentdatespecification{#1}}% - \clf_currentdate{\currentdatespecification}{\labellanguage}% + \clf_currentdate{#1}{\currentdatespecification}{\labellanguage}% \endgroup} \unexpanded\def\date @@ -438,7 +437,7 @@ \endgroup} \def\rawdate[#1]% expandable and no labels - {\clf_rawdate{\currentdatespecification}} + {\clf_currentdate{#1}{\currentdatespecification}{}} %D \macros %D {currenttime} diff --git a/tex/context/base/mkiv/core-ini.mkiv b/tex/context/base/mkiv/core-ini.mkiv index 0407409a3..35790f131 100644 --- a/tex/context/base/mkiv/core-ini.mkiv +++ b/tex/context/base/mkiv/core-ini.mkiv @@ -171,6 +171,7 @@ \newif \ifinsidefloat \newif \ifdoingblocks \newif \ifgridsnapping +\newif \ifexporting \newconstant\pageduplexmode % 0 single 1 double 2 mix \newconstant\pagebodymode % 0 not 1 normal pagebody 2 spread diff --git a/tex/context/base/mkiv/core-sys.mkiv b/tex/context/base/mkiv/core-sys.mkiv index 172cb7a38..a821c7868 100644 --- a/tex/context/base/mkiv/core-sys.mkiv +++ b/tex/context/base/mkiv/core-sys.mkiv @@ -208,6 +208,8 @@ \setuevalue {\currentstartstop}{\syst_startstop_indeed{\currentstartstop}}% \to \everydefinestartstop +\ifdefined\dotagconstruct \else \let\dotagconstruct\relax \fi + \unexpanded\def\syst_startstop_start#1% {\namedstartstopparameter{#1}\c!before\relax \bgroup @@ -217,7 +219,8 @@ % this is the new method: \usesetupsparameter\startstopparameter\relax % only in the display version \dostarttagged\t!construct\currentstartstop - \usestartstopstyleandcolor\c!style\c!color} + \usestartstopstyleandcolor\c!style\c!color + \dotagconstruct} \unexpanded\def\syst_startstop_stop#1% {\dostoptagged @@ -231,7 +234,7 @@ \dostarttagged\t!construct\currentstartstop \usestartstopstyleandcolor\c!style\c!color \startstopparameter\c!left\relax} - {\def\currentstartstop{#1}% safeguard, nto really needed + {\def\currentstartstop{#1}% safeguard, not really needed \startstopparameter\c!right\relax \dostoptagged \startstopparameter\c!inbetween\relax}} diff --git a/tex/context/base/mkiv/export-example.css b/tex/context/base/mkiv/export-example.css index 8c7ae3bfc..812873afc 100644 --- a/tex/context/base/mkiv/export-example.css +++ b/tex/context/base/mkiv/export-example.css @@ -28,6 +28,8 @@ context|div.figure { } *[chain~='figure'] { } context|div.figure.myfloatb { } *[chain~='figure'][detail='myfloatb'] { } + Inheritance when using div seems to be stronger so we need to take more precautions. + */ @namespace context url('http://www.pragma-ade.com/context/export') ; @@ -35,35 +37,42 @@ /* ignore : mixed */ /* metadata: display */ -ignore, context|div.ignore { +ignore, +context|div.ignore { display : none ; } -ignore, context|div.private { +ignore, +context|div.private { display : none ; } -xmetadata, context|div.xmetadata { +xmetadata, +context|div.xmetadata { display : none ; } -xmetavariable, context|div.xmetavariable { +xmetavariable, +context|div.xmetavariable { display : none ; } /* document : display */ -document:before, context|div.document:before { +document:before, +context|div.document:before { content : attr(title) ; font-size : 44pt ; font-weight : bold ; margin-bottom : 1em ; } -document, context|div.document { +document, +context|div.document { font-family : "DejaVu Serif", "Lucida Bright", serif ; font-size : 12pt ; - line-height : 14.4pt; + /* line-height : 14.4pt; */ + line-height : 2.8ex; max-width : 50em ; padding : 1em ; /* text-align : justify ; */ @@ -72,35 +81,59 @@ document, context|div.document { /* text-justify : inter-word ; */ } -document>metadata, context|div.document context|div.metadata { +document>metadata, +context|div.document context|div.metadata { font-family : "DejaVu Sans Mono", "Lucida Console", monospace ; - margin-bottom : 2em ; + margin-bottom : 3ex ; } -document>metadata>metavariable[name="title"]:before, - context|div.document context|div.metadata context|div.metavariable.name-title:before { - content : "title\00A0\00A0\00A0:\00A0" ; +/* + document>metadata>metavariable[name="X"]:before, + context|div.document context|div.metadata context|div.metavariable.metaname-X:before { + content : "X\00A0\00A0\00A0:\00A0" ; + } +*/ + +document>metadata, +context|div.document context|div.metadata { + display : flex ; + flex-flow : column ; } -document>metadata>metavariable[name="author"]:before, - context|div.document context|div.metadata context|div.metavariable.name-author:before { - content : "author\00A0\00A0:\00A0" ; +document>metadata>metavariable:before, +context|div.document context|div.metadata context|div.metavariable:before { + display : inline ; + content : attr(label); + width : 8em ; + float : left ; + font-weight : bold ; } -document>metadata>metavariable[name="version"]:before, - context|div.document context|div.metadata context|div.metavariable.name-version:before { - content : "version\00A0:\00A0" ; +document>metadata>metavariable[name="title"], +context|div.document context|div.metadata context|div.metavariable.metaname-title { + order : -1 ; + display : block ; + width : 50em ; + float : left ; + font-family : "DejaVu Serif", "Lucida Bright", serif ; + font-weight : bold ; + font-size : 3em ; + text-align : left ; + margin-bottom : 2ex ; } -document>metadata>metavariable[name="title"], document>metadata>metavariable[name="author"], document>metadata>metavariable[name="version"], - context|div.document context|div.metadata context|div.metavariable.name-title, context|div.document context|div.metadata context|div.metavariable.name-author, context|div.document context|div.metadata context|div.metavariable.name-version { - display : block ; +document>metadata>metavariable[name="title"]:before, +context|div.document context|div.metadata context|div.metavariable.metaname-title:before { + content : none ; } /* paragraph : mixed */ /* p : mixed */ -paragraph, p, context|div.paragraph, context|div.p { +paragraph, +p, +context|div.paragraph, +context|div.p { display : block ; margin-top : 0.5em ; margin-bottom : 0.5em ; @@ -108,7 +141,8 @@ paragraph, p, context|div.paragraph, context|div.p { /* break : display */ -break, context|div.break { +break, +context|div.break { display : block ; margin-bottom : 0.5em ; } @@ -116,14 +150,17 @@ break, context|div.break { /* construct : inline */ /* highlight : inline */ -construct, context|div.construct { +construct, +context|div.construct { } -construct[detail="important"], context|div.construct.important { +construct[detail="important"], +context|div.construct.important { font-weight : bold ; } -highlight, context|div.highlight { /* todo: style and color */ +highlight, +context|div.highlight { /* todo: style and color */ display : inline ; } @@ -132,95 +169,167 @@ highlight, context|div.highlight { /* todo: style and color */ /* sectionnumber : mixed */ /* sectioncontent : display */ -section, context|div.section { +section, +context|div.section { display : block ; } -sectioncontent, context|div.sectioncontent { - display : block ; - margin-top : 1em ; - margin-bottom : 1em ; +sectioncaption, +context|div.sectioncaption { + display : block ; + text-align : left ; + page-break-after : avoid ; + margin-top : 3ex ; + margin-bottom : 2ex ; } -section[detail="chapter"], section[detail="title"], - context|div.section.chapter, context|div.section.title { - page-break-before : always ; - page-break-after : avoid ; - margin-top : 3em ; - margin-bottom : 2em ; +sectioncontent, +context|div.sectioncontent { + display : block ; } -section[detail="section"], section[detail="subject"], - context|div.section.section, context|div.section.subject { - page-break-after : avoid ; - margin-top : 2.5em ; - margin-bottom : 2.5em ; +sectionnumber, +context|div.sectionnumber { + display : inline ; + margin-right : 1em ; } -section[detail="subsection"], section[detail="subsubject"], - context|div.section.subsection, context|div.section.subsubject { - page-break-after : avoid ; - margin-top : 2em ; - margin-bottom : 2em ; +sectionnumber, +context|div.sectiontitle { + display : inline ; } -section[detail="subsubsection"], section[detail="subsubsubject"], - context|div.section.subsubsection, context|div.section.subsubsubject { - page-break-after : avoid ; - margin-top : 1em ; - margin-bottom : 0em ; +/* we need to use level as selector because section is used twice */ + +/* chapter | title */ + +section[detail="chapter"]>sectioncaption, +section[detail="title"]>sectioncaption, +context|div.level-2.chapter context|div.sectioncaption , +context|div.level-2.title context|div.sectioncaption { + font-size : 2em ; + font-weight : bold ; } -section[detail="summary"], section[detail="subsummary"], - context|div.section.summary, context|div.section.subsummary { - margin-top : 1em ; - margin-bottom : 1em ; +section[detail="chapter"], +section[detail="title"], +context|div.level-2.chapter, +context|div.level-2.title { + page-break-before : always ; + margin-top : 4ex ; } -section[detail="chapter"]>sectionnumber, - context|div.section.chapter context|div.sectionnumber { - display : inline-block ; - margin-right : 1em ; - font-size : 3em ; - font-weight : bold ; +section[detail="chapter"]>sectioncaption>sectionnumber, +context|div.level-2.chapter context|div.sectioncaption context|div.sectionnumber { + /* nothing */ } -section[detail="chapter"]>sectiontitle, section[detail="title"]>sectiontitle, - context|div.section.chapter context|div.sectiontitle, context|div.section.title context|div.sectiontitle { - display : inline-block ; - font-size : 3em ; - font-weight : bold ; +section[detail="chapter"]>sectioncaption>sectiontitle, +section[detail="title"]>sectioncaption>sectiontitle, +context|div.level-2.chapter context|div.sectioncaption context|div.sectiontitle, +context|div.level-2.title context|div.sectioncaption context|div.sectiontitle { + /* nothing */ } -section[detail="section"]>sectiontitle, section[detail="subject"]>sectiontitle, - context|div.section.section context|div.sectiontitle, context|div.section.subject context|div.sectiontitle { - display : inline-block ; - font-size : 2.5em ; +/* section | subject */ + +section[detail="section"]>sectioncaption, +section[detail="subject"]>sectioncaption, +context|div.level-3.section context|div.sectioncaption, +context|div.level-3.subject context|div.sectioncaption { + font-size : 1.75em ; font-weight : bold ; } -section[detail="subsection"]>sectiontitle, section[detail="subsubject"]>sectiontitle, - context|div.section.subsection context|div.sectiontitle, context|div.section.subsubject context|div.sectiontitle { - display : inline-block ; - font-size : 2em ; +section[detail="section"], +section[detail="subject"], +context|div.level-3.section, +context|div.level-3.subject { + /* nothing */ +} + +section[detail="section"]>sectioncaption>sectionnumber, +context|div.level-3.section context|div.sectioncaption context|div.sectionnumber { + /* nothing */ +} + +section[detail="section"]>sectioncaption>sectiontitle, +section[detail="subject"]>sectioncaption>sectiontitle, +context|div.level-3.section context|div.sectioncaption context|div.sectiontitle, +context|div.level-3.subject context|div.sectioncaption context|div.sectiontitle { + /* nothing */ +} + +/* subsection | subsubject */ + +section[detail="subsection"]>sectioncaption, +section[detail="subsubject"]>sectioncaption, +context|div.level-4.subsection context|div.sectioncaption, +context|div.level-4.subsubject context|div.sectioncaption { + font-size : 1.5em ; font-weight : bold ; } -section[detail="subsubsection"]>sectiontitle, section[detail="subsubsubject"]>sectiontitle, - context|div.section.subsubsection context|div.sectiontitle, context|div.section.subsubsubject context|div.sectiontitle { - display : inline-block ; - font-size : 1em ; +section[detail="subsection"], +section[detail="subsubject"], +context|div.level-4.subsection, +context|div.level-4.subsubject { + /* nothing */ +} + +section[detail="subsection"]>sectioncaption>sectionnumber, +context|div.level-4.subsection context|div.sectioncaption context|div.sectionnumber { + /* nothing */ +} + +section[detail="subsection"]>sectioncaption>sectiontitle, +section[detail="subsubject"]>sectioncaption>sectiontitle, +context|div.level-4.subsection context|div.sectioncaption context|div.sectiontitle, +context|div.level-4.subsubject context|div.sectioncaption context|div.sectiontitle { + /* nothing */ +} + +/* subsubsection | subsubsubject */ + +section[detail="subsubsection"]>sectioncaption, +section[detail="subsubsubject"]>sectioncaption, +context|div.level-5.subsubsection context|div.sectioncaption, +context|div.level-5.subsubsubject context|div.sectioncaption { + font-size : 1.25em ; font-weight : bold ; } -section[detail="section"]>sectionnumber, context|div.section.section context|div.sectionnumber { - display : inline-block ; - margin-right : 1em ; - font-size : 2.5em ; - font-weight : bold ; +section[detail="subsubsection"], +section[detail="subsubsubject"], +context|div.level-5.subsubsection, +context|div.level-5.subsubsubject { + /* nothing */ +} + +section[detail="subsubsection"]>sectioncaption>sectionnumber, +context|div.level-5.subsubsection context|div.sectioncaption context|div.sectionnumber { + /* nothing */ +} + +section[detail="subsubsection"]>sectioncaption>sectiontitle, +section[detail="subsubsubject"]>sectioncaption>sectiontitle, +context|div.level-5.subsubsection context|div.sectioncaption context|div.sectiontitle, +context|div.level-5.subsubsubject context|div.sectioncaption context|div.sectiontitle { + /* nothing */ +} + +/* summary | subsummary*/ + +section[detail="summary"], +section[detail="subsummary"], +context|div.section.summary, +context|div.section.subsummary { + margin-top : 1em ; + margin-bottom : 1em ; } -section[detail="summary"]>sectiontitle, context|div.section.summary context|div.sectiontitle { +section[detail="summary"]>sectioncaption>sectiontitle, +context|div.section.summary context|div.sectioncaption context|div.sectiontitle { display : block ; margin-top : 1em ; margin-bottom : 1em ; @@ -228,16 +337,11 @@ section[detail="summary"]>sectiontitle, context|div.section.summary context|div. border-bottom-style : solid ; border-color : rgb(50%,50%,100%) ; border-width : .15em; + text-align : left ; } -section[detail="subsection"]>sectionnumber, context|div.section.subsection context|div.sectionnumber { - display : inline-block ; - margin-right : 1em ; - font-size : 1em ; - font-weight : bold ; -} - -section[detail="subsummary"]>sectiontitle, context|div.section.subsummary context|div.sectiontitle { +section[detail="subsummary"]>sectioncaption>sectiontitle, +context|div.section.subsummary context|div.sectioncaption context|div.sectiontitle { display : block ; margin-top : 1em ; margin-bottom : 1em ; @@ -245,6 +349,7 @@ section[detail="subsummary"]>sectiontitle, context|div.section.subsummary contex border-color : rgb(50%,50%,100%) ; border-bottom-style : dotted ; border-width : .15em ; + text-align : left ; } /* itemgroup : display */ @@ -265,7 +370,8 @@ section[detail="subsummary"]>sectiontitle, context|div.section.subsummary contex glyphs : 'Α' 'B' 'Γ' 'Δ' 'Ε' 'Ζ' 'Η' 'Θ' 'Ι' 'Κ' 'Λ' 'Μ' 'Ν' 'Ξ' 'Ο' 'Π' 'Ρ' 'Σ' 'Τ' 'Υ' 'Φ' 'Χ' 'Ψ' 'Ω' ; } -itemgroup, context|div.itemgroup { +itemgroup, +context|div.itemgroup { display : block ; margin-bottom : 0.5em ; margin-top : 0.5em ; @@ -284,18 +390,21 @@ itemgroup[symbol="n"], context|div.itemgroup.symbol-n { list-style-type : decima itemgroup[symbol="g"], context|div.itemgroup.symbol-g { list-style-type : lower-greek ; } itemgroup[symbol="G"], context|div.itemgroup.symbol-G { list-style-type : upper-greek ; } -item, context|div.item { +item, +context|div.item { display : list-item ; margin-left : 1em ; margin-bottom : 0.5em ; margin-top : 0.5em ; } -itemtag, context|div.item { +itemtag, +context|div.item { display: none ; } -itemcontent, context|div.itemcontent { +itemcontent, +context|div.itemcontent { } /* description : display */ @@ -303,13 +412,15 @@ itemcontent, context|div.itemcontent { /* descriptioncontent : mixed */ /* descriptionsymbol : inline */ -description, context|div.description { +description, +context|div.description { display : block ; margin-bottom : 1em ; margin-top : 1em ; } -descriptiontag, context|div.descriptiontag { +descriptiontag, +context|div.descriptiontag { display : inline ; float : left ; clear : left ; @@ -318,10 +429,12 @@ descriptiontag, context|div.descriptiontag { font-weight : bold ; } -descriptioncontent, context|div.descriptioncontent { +descriptioncontent, +context|div.descriptioncontent { } -descriptionsymbol, context|div.descriptionsymbol { +descriptionsymbol, +context|div.descriptionsymbol { display : inline ; } @@ -330,7 +443,8 @@ descriptionsymbol, context|div.descriptionsymbol { /* verbatimline : mixed */ /* verbatim : inline */ -verbatimblock, context|div.verbatimblock { +verbatimblock, +context|div.verbatimblock { background-color : rgb(50%,50%,100%) ; display : block ; padding : 1em ; @@ -339,17 +453,20 @@ verbatimblock, context|div.verbatimblock { font-family : "DejaVu Sans Mono", "Lucida Console", monospace ; } -verbatimlines+verbatimlines, context|div.verbatimlines+context|div.verbatimlines { +verbatimlines+verbatimlines, +context|div.verbatimlines+context|div.verbatimlines { display : block ; margin-top : 1em ; } -verbatimline, context|div.verbatimline { +verbatimline, +context|div.verbatimline { display : block ; white-space : pre-wrap ; } -verbatim, context|div.verbatim { +verbatim, +context|div.verbatim { display : inline ; white-space : pre-wrap ; color : rgb(60%,60%,0%) ; @@ -359,18 +476,21 @@ verbatim, context|div.verbatim { /* lines : display */ /* line : mixed */ -lines, context|div.lines { +lines, +context|div.lines { display : block ; margin-bottom : 1em ; margin-top : 1em ; } -lines+lines, context|div.lines+context|div.lines { +lines+lines, +context|div.lines+context|div.lines { display : block ; margin-top : 1em ; } -line, context|div.line { +line, +context|div.line { display : block ; white-space : pre-wrap ; } @@ -378,7 +498,10 @@ line, context|div.line { /* synonym : inline */ /* sorting : inline */ -sorting, synonym, context|div.sorting, context|div.synonym { +sorting, +synonym, +context|div.sorting, +context|div.synonym { display : inline ; font-variant : small-caps ; } @@ -393,15 +516,18 @@ sorting, synonym, context|div.sorting, context|div.synonym { /* registerpage : inline */ /* registerpagerange : mixed */ -register, context|div.register { +register, +context|div.register { display: none ; } -registerlocation, context|div.registerlocation { +registerlocation, +context|div.registerlocation { display: inline ; } -registerlocation:after, context|div.registerlocation:after { +registerlocation:after, +context|div.registerlocation:after { content : "\25B6\00A0\00A0" ; color : rgb(40%,40%,40%) ; font-size : x-small ; @@ -414,33 +540,39 @@ registerlocation:after, context|div.registerlocation:after { /* tablerow : display */ /* tablecell : mixed */ -table, context|div.table { +table, +context|div.table { display : table ; } -tablerow, context|div.tablerow { +tablerow, +context|div.tablerow { display : table-row ; } -tablecell[align="middle"], context|div.tablecell.align-middle { +tablecell[align="middle"], +context|div.tablecell.align-middle { display : table-cell ; text-align : center ; padding : .1em ; } -tablecell[align="flushleft"], context|div.tablecell.align-flushleft { +tablecell[align="flushleft"], +context|div.tablecell.align-flushleft { display : table-cell ; text-align : left ; padding : .1em ; } -tablecell[align="flushright"], context|div.tablecell.align-flushright { +tablecell[align="flushright"], +context|div.tablecell.align-flushright { display : table-cell ; text-align : right ; padding : .1em ; } -tablecell, context|div.tablecell { +tablecell, +context|div.tablecell { display : table-cell ; text-align : left ; padding : .1em ; @@ -450,73 +582,97 @@ tablecell, context|div.tablecell { /* tabulaterow : display */ /* tabulatecell : mixed */ -tabulate, context|div.tabulate { +tabulate, +context|div.tabulate { display : table ; margin-top : 1em ; margin-bottom : 1em ; margin-left : 2.5em ; } -floatcontent>tabulate, context|div.floatcontent context|div.tabulate { +floatcontent>tabulate, +context|div.floatcontent context|div.tabulate { margin-left : 0em ; } -tabulaterow, context|div.tabulaterow { +tabulaterow, +context|div.tabulaterow { display : table-row ; } -tabulatecell[align="middle"], context|div.tabulatecell.align-middle { +tabulatecell[align="middle"], +context|div.tabulatecell.align-middle { display : table-cell ; text-align : center ; padding-right : 1em ; } -tabulatecell[align="flushleft"], context|div.tabulatecell.align-flushleft { +tabulatecell[align="flushleft"], +context|div.tabulatecell.align-flushleft { display : table-cell ; text-align : left ; padding-right : 1em ; } -tabulatecell[align="flushright"], context|div.tabulatecell.align-flushright { +tabulatecell[align="flushright"], +context|div.tabulatecell.align-flushright { display : table-cell ; text-align : right ; padding-right : 1em ; } -tabulatecell, context|div.tabulatecell { +tabulatecell, +context|div.tabulatecell { display : table-cell ; text-align : left ; padding-right : 1em ; } +tabulatecell[kind="strong"], +context|div.tabulatecell.kind-strong { + font-weight : bold ; +} + +tabulatecell[kind="equals"]:before, +context|div.tabulatecell.kind-equals:before { + display : inline-block ; + clear : left ; + margin-left : -.6em ; + width : .6em ; + content : ":" ; +} + /* combination : display */ /* combinationpair : display */ /* combinationcontent : mixed */ /* combinationcaption : mixed */ -combination, context|div.combination { +combination, +context|div.combination { display : table ; margin-top : 0em ; margin-bottom : 0em ; } -combinationpair, context|div.combinationpair { +combinationpair, +context|div.combinationpair { display : table-cell ; padding-right : 1em ; } -combinationcontent, context|div.combinationcontent { +combinationcontent, +context|div.combinationcontent { display : table-row ; text-align : center ; } -combinationcaption, context|div.combinationcaption { +combinationcaption, +context|div.combinationcaption { display : table-row ; padding-top : 1ex ; text-align : center ; } - /* list : display */ /* listitem : display */ /* listtag : mixed */ @@ -524,39 +680,81 @@ combinationcaption, context|div.combinationcaption { /* listdata : mixed */ /* listpage : mixed */ -list, context|div.list { - display : block ; +list, +context|div.list { + display : block ; + text-align : left ; } -listitem[detail="chapter"], context|div.listitem.chapter { +listitem[detail="chapter"], +context|div.listitem.chapter { display : block ; margin-top : 1em ; + margin-left : 5em ; font-weight : bold ; } -listitem[detail="section"], context|div.listitem.section { - display : block ; +listitem[detail="section"], +context|div.listitem.section { + display : block ; + margin-left : 5em ; } -listitem[detail="subsection"], context|div.listitem.subsection { - display : block ; - display : inline-block ; +listitem[detail="subsection"], +context|div.listitem.subsection { + display : block ; + margin-left : 5em ; } -listtag, context|div.listtag { - display : inline-block ; - width : 5em ; +/* +listitem[detail="subsection"], +context|div.listitem.subsection { + display : inline-block ; + margin-left : -5em ; } -listcontent, context|div.listcontent { - display : inline-block ; +listitem[detail="subsection"]>listtag, +context|div.listitem.subsection context|div.listtag { + margin-right : 1em ; } +*/ -listdata, context|div.listdata { - display : inline-block ; +listitem[detail="chapter"]>listtag, +context|div.listitem.chapter context|div.listtag { + display : inline-block ; + margin-left : -5em ; + float : left ; + clear : left ; +} + +listitem[detail="section"]>listtag, +context|div.listitem.section context|div.listtag { + display : inline-block ; + margin-left : -5em ; + float : left ; + clear : left ; +} + +listitem[detail="subsection"]>listtag, +context|div.listitem.subsection context|div.listtag { + display : inline-block ; + margin-left : -5em ; + float : left ; + clear : left ; +} + +listcontent, +context|div.listcontent { + display : inline ; +} + +listdata, +context|div.listdata { + display : inline ; } -listpage, context|div.listpage { +listpage, +context|div.listpage { display : none ; } @@ -570,59 +768,77 @@ listpage, context|div.listpage { /* :lang(en) */ -delimited[detail="quotation"]:before, delimitedblock[detail="quotation"]:before, - context|div.delimited.quotation:before, context|div.delimitedblock.quotation:before { +delimited[detail="quotation"]:before, +delimitedblock[detail="quotation"]:before, +context|div.delimited.quotation:before, +context|div.delimitedblock.quotation:before { /* content : "\201C" ; */ font-style : italic ; } -delimited[detail="quotation"]:after, delimitedblock[detail="quotation"]:after, - context|div.delimited.quotation:after, context|div.delimitedblock.quotation:after { +delimited[detail="quotation"]:after, +delimitedblock[detail="quotation"]:after, +context|div.delimited.quotation:after, +context|div.delimitedblock.quotation:after { /* content : "\201D" ; */ font-style : italic ; } -delimited[detail="quote"]:before, delimitedblock[detail="quote"]:before, - context|div.delimited.quote:before, context|div.delimitedblock.quote:before { +delimited[detail="quote"]:before, +delimitedblock[detail="quote"]:before, +context|div.delimited.quote:before, +context|div.delimitedblock.quote:before { /* content : "\2018" ; */ font-style : italic ; } -delimited[detail="quote"]:after, delimitedblock[detail="quote"]:after, - context|div.delimited.quote:after, context|div.delimitedblock.quote:after { +delimited[detail="quote"]:after, +delimitedblock[detail="quote"]:after, +context|div.delimited.quote:after, +context|div.delimitedblock.quote:after { /* content : "\2019" ; */ font-style : italic ; } -delimited, context|div.delimited { +delimited, +context|div.delimited { display : inline } -delimitedcontent, context|div.delimitedcontent { +delimitedcontent, +context|div.delimitedcontent { display : inline } -delimitedsymbol, context|div.delimitedsymbol { +delimitedsymbol, +context|div.delimitedsymbol { display : inline } -delimitedblock, context|div.delimitedblock { +delimitedblock, +context|div.delimitedblock { display : block } -subsentence:before, subsentence:after, context|div.subsentence:before, context|div.subsentence:after { +subsentence:before, +subsentence:after, +context|div.subsentence:before, +context|div.subsentence:after { content : "\2014" ; } -subsentence, context|div.subsentence { +subsentence, +context|div.subsentence { display : inline } -subsentencecontent, context|div.subsentencecontent { +subsentencecontent, +context|div.subsentencecontent { display : inline } -subsentencesymbol, context|div.subsentencesymbol { +subsentencesymbol, +context|div.subsentencesymbol { display : inline } @@ -636,36 +852,42 @@ subsentencesymbol, context|div.subsentencesymbol { /* floattext : mixed */ /* floatcontent : mixed */ -float, context|div.float { +float, +context|div.float { display : block ; margin-top : 1em ; margin-bottom : 1em ; margin-left : 2.5em ; } -floatcaption, context|div.floatcaption { +floatcaption, +context|div.floatcaption { display : block ; margin-top : 0.5em ; color : rgb(60%,60%,0%) ; } -floatlabel, context|div.floatlabel { +floatlabel, +context|div.floatlabel { display : inline-block ; font-weight : bold ; margin-right : 0.25em ; } -floatnumber, context|div.floatnumber { +floatnumber, +context|div.floatnumber { display : inline ; font-weight : bold ; margin-right : 0.25em ; } -floattext, context|div.floattext { +floattext, +context|div.floattext { display : inline ; } -floatcontent, context|div.floatcontent { +floatcontent, +context|div.floatcontent { } /* image : mixed */ @@ -679,11 +901,14 @@ floatcontent, context|div.floatcontent { height : 5.994cm ; } */ -mpgraphic:before, context|div.mpgraphic:before { /* does not work with empty element */ +mpgraphic:before, +context|div.mpgraphic:before { + /* does not work with empty element */ content : "[runtime metapost graphic]" ; } -mpgraphic, context|div.mpgraphic { +mpgraphic, +context|div.mpgraphic { display : inline ; } @@ -695,63 +920,73 @@ mpgraphic, context|div.mpgraphic { /* formulanumber : mixed */ /* formulacontent : display */ -formula, context|div.formula { +formula, +context|div.formula { display : block ; margin-top : 1em ; margin-bottom : 1em ; margin-left : 2.5em ; } -subformula, context|div.subformula { /* todo */ +subformula, +context|div.subformula { /* todo */ display : block ; margin-top : 1em ; margin-bottom : 1em ; margin-left : 2.5em ; } -formulaset, context|div.formulaset { /* todo */ +formulaset, +context|div.formulaset { /* todo */ display : block ; margin-top : 1em ; margin-bottom : 1em ; margin-left : 2.5em ; } -formulacaption, context|div.formulacaption { /* todo */ +formulacaption, +context|div.formulacaption { /* todo */ display : block ; margin-top : 0.5em ; color : rgb(60%,60%,0%) ; } -formulalabel, context|div.formulalabel { +formulalabel, +context|div.formulalabel { display : inline ; font-weight : bold ; margin-right : .25em ; } -formulanumber, context|div.formulanumber { +formulanumber, +context|div.formulanumber { display : inline ; font-weight : bold ; } -formulacontent, context|div.formulacontent { +formulacontent, +context|div.formulacontent { display : block ; } -link, context|div.link { +link, +context|div.link { display : inline ; } /* margintextblock : inline */ /* margintext : inline */ -margintext, context|div.margintext { +margintext, +context|div.margintext { display : block ; font-weight : bold ; margin-top : 1em ; margin-bottom : 1em ; } -margintext:before, context|div.margintext:before { +margintext:before, +context|div.margintext:before { content : "\25B6\00A0\00A0" ; color : rgb(40%,40%,40%) ; } @@ -793,15 +1028,18 @@ context|div.math-display { /* unit : inline */ /* number : inline */ -quantity, context|div.quantity { +quantity, +context|div.quantity { display : inline-block ; } -quantity>unit, context|div.quantity>context|div.unit { +quantity>unit, +context|div.quantity>context|div.unit { display : inline ; } -quantity>number, context|div.quantity>context|div.number { +quantity>number, +context|div.quantity>context|div.number { display : inline ; } @@ -809,24 +1047,28 @@ quantity>number, context|div.quantity>context|div.number { /* sup : inline */ /* subsup : inline */ -sup, context|div.sup { +sup, +context|div.sup { display : inline-block ; font-size : xx-small ; vertical-align : super ; } -sub, context|div.sub { +sub, +context|div.sub { display : inline-block ; font-size : xx-small ; vertical-align : sub ; } -subsup>sup, context|div.subsup>context|div.sup { +subsup>sup, +context|div.subsup>context|div.sup { display : inline ; vertical-align : top ; } -subsup>sub, context|div.subsup>context|div.sub { +subsup>sub, +context|div.subsup>context|div.sub { display : inline ; vertical-align : bottom ; } @@ -840,11 +1082,13 @@ context|div[href]:hover { /* setups */ -setup, context|div.setup { +setup, +context|div.setup { display : block ; } -comment, context|div.comment { +comment, +context|div.comment { background-color : rgb(50%,75%,100%) ; display : block ; padding : 1em ; @@ -855,10 +1099,12 @@ comment, context|div.comment { /* special */ -c, context|div.c { +c, +context|div.c { display : inline ; } -warning, context|div.warning { +warning, +context|div.warning { display : none ; } diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index 327a75537..726004bd3 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -44,7 +44,7 @@ constructors.namemode = "fullpath" -- will be a function constructors.version = 1.01 constructors.cache = containers.define("fonts", "constructors", constructors.version, false) -constructors.privateoffset = 0xF0000 -- 0x10FFFF +constructors.privateoffset = 0xF0000 -- 0x10FFFF | context also uses privates: 0xE000-0xEFFF constructors.cacheintex = true -- so we see the original table in fonts.font @@ -89,6 +89,13 @@ function constructors.scaled(scaledpoints, designsize) -- handles designsize in end end +function constructors.getprivate(tfmdata) + local properties = tfmdata.properties + local private = properties.private + properties.private = private + 1 + return private +end + --[[ldx-- <p>Beware, the boundingbox is passed as reference so we may not overwrite it in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index 2d3dce2fb..afeeacb3f 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -1497,8 +1497,6 @@ end -- ValueFormat1 applies to the ValueRecord of the first glyph in each pair. ValueRecords for all first glyphs must use ValueFormat1. If ValueFormat1 is set to zero (0), the corresponding glyph has no ValueRecord and, therefore, should not be repositioned. -- ValueFormat2 applies to the ValueRecord of the second glyph in each pair. ValueRecords for all second glyphs must use ValueFormat2. If ValueFormat2 is set to null, then the second glyph of the pair is the “next” glyph for which a lookup should be performed. --- !!!!! this needs checking: when both false, we have no hit so then we might need to fall through - function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) local tableoffset = lookupoffset + offset setposition(f,tableoffset) @@ -1511,6 +1509,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly local sets = readarray(f) sets = readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) coverage = readcoverage(f,tableoffset + coverage) + -- local allzero = 0 for index, newindex in next, coverage do local set = sets[newindex+1] local hash = { } @@ -1520,15 +1519,22 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly local other = value[1] local first = value[2] local second = value[3] + -- if first == true and second == true then + -- -- upto the next lookup for this combination + -- allzero = allzero + 1 + -- end if first or second then hash[other] = { first, second or nil } -- needs checking else - hash[other] = nil + hash[other] = nil -- what if set, maybe warning end end end coverage[index] = hash end + -- if allzero > 0 then + -- report("%s allzero pairs in %a positioning lookup %a subtype %a",allzero,"pair",lookupid,subtype) + -- end return { format = "pair", coverage = coverage, @@ -1546,6 +1552,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly classdef1 = readclassdef(f,tableoffset+classdef1,coverage) classdef2 = readclassdef(f,tableoffset+classdef2,nofglyphs) local usedcoverage = { } + -- local allzero = 0 for g1, c1 in next, classdef1 do if coverage[g1] then local l1 = classlist[c1] @@ -1556,6 +1563,10 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly if offsets then local first = offsets[1] local second = offsets[2] + -- if first == true and second == true then + -- -- upto the next lookup for this combination + -- allzero = allzero + 1 + -- end if first or second then hash[paired] = { first, second or nil } else @@ -1567,6 +1578,9 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly end end end + -- if allzero > 0 then + -- report("%s allzero pairs in %a positioning lookup %a subtype %a",allzero,"pair",lookupid,subtype) + -- end return { format = "pair", coverage = usedcoverage, diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua index 8e0971ca6..46309c324 100644 --- a/tex/context/base/mkiv/font-ext.lua +++ b/tex/context/base/mkiv/font-ext.lua @@ -37,8 +37,12 @@ local registerafmfeature = handlers.afm.features.register local fontdata = hashes.identifiers local fontproperties = hashes.properties +local constructors = fonts.constructors +local getprivate = constructors.getprivate + local allocate = utilities.storage.allocate local settings_to_array = utilities.parsers.settings_to_array +local settings_to_hash = utilities.parsers.settings_to_hash local getparameters = utilities.parsers.getparameters local gettexdimen = tex.getdimen local family_font = node.family_font @@ -46,6 +50,13 @@ local family_font = node.family_font local setmetatableindex = table.setmetatableindex local implement = interfaces.implement +local variables = interfaces.variables + + +local v_background = variables.background +local v_frame = variables.frame +local v_empty = variables.empty +local v_none = variables.none -- -- -- -- -- -- -- shared @@ -647,15 +658,13 @@ local function manipulatedimensions(tfmdata,key,value) depth = (spec[3] or 0) * exheight end if width > 0 then - local resources = tfmdata.resources local additions = { } - local private = resources.private for unicode, old_c in next, characters do local oldwidth = old_c.width if oldwidth ~= width then -- Defining the tables in one step is more efficient -- than adding fields later. - private = private + 1 + local private = getprivate(tfmdata) local new_c local commands = { { "right", (width - oldwidth) / 2 }, @@ -693,13 +702,12 @@ local function manipulatedimensions(tfmdata,key,value) end setmetatableindex(new_c,old_c) characters[unicode] = new_c - additions[private] = old_c + additions[private] = old_c end end for k, v in next, additions do characters[k] = v end - resources.private = private elseif height > 0 and depth > 0 then for unicode, old_c in next, characters do old_c.height = height @@ -741,80 +749,172 @@ registerafmfeature(dimensions_specification) -- local gray = { "pdf", "origin", "/Tr1 gs .75 g" } -- local black = { "pdf", "origin", "/Tr0 gs 0 g" } --- sort of obsolete as we now have \showglyphs + +-- boundingbox={yes|background|frame|empty|<color>} local push = { "push" } local pop = { "pop" } -local gray = { "pdf", "origin", ".75 g" } -local black = { "pdf", "origin", "0 g" } --- local gray = { "pdf", ".75 g" } --- local black = { "pdf", "0 g" } -local downcache = { } -- handy for huge cjk fonts -local rulecache = { } -- handy for huge cjk fonts +----- gray = { "pdf", "origin", ".75 g .75 G" } +----- black = { "pdf", "origin", "0 g 0 G" } +----- gray = { "pdf", ".75 g" } +----- black = { "pdf", "0 g" } -setmetatableindex(downcache,function(t,d) - local v = { "down", d } - t[d] = v +-- local bp = number.dimenfactors.bp +-- +-- local downcache = setmetatableindex(function(t,d) +-- local v = { "down", d } +-- t[d] = v +-- return v +-- end) +-- +-- local backcache = setmetatableindex(function(t,h) +-- local h = h * bp +-- local v = setmetatableindex(function(t,w) +-- -- local v = { "rule", h, w } +-- local v = { "pdf", "origin", formatters["0 0 %0.6F %0.6F re F"](w*bp,h) } +-- t[w] = v +-- return v +-- end) +-- t[h] = v +-- return v +-- end) +-- +-- local forecache = setmetatableindex(function(t,h) +-- local h = h * bp +-- local v = setmetatableindex(function(t,w) +-- local v = { "pdf", "origin", formatters["%0.6F w 0 0 %0.6F %0.6F re S"](0.25*65536*bp,w*bp,h) } +-- t[w] = v +-- return v +-- end) +-- t[h] = v +-- return v +-- end) + +local bp = number.dimenfactors.bp +local r = 0.25*65536*bp + +local backcache = setmetatableindex(function(t,h) + local h = h * bp + local v = setmetatableindex(function(t,d) + local d = d * bp + local v = setmetatableindex(function(t,w) + local v = { "pdf", "origin", formatters["%0.6F w 0 %0.6F %0.6F %0.6F re f"](r,-d,w*bp,h+d) } + t[w] = v + return v + end) + t[d] = v + return v + end) + t[h] = v return v end) -setmetatableindex(rulecache,function(t,h) - local v = { } - t[h] = v - setmetatableindex(v,function(t,w) - local v = { "rule", h, w } - t[w] = v +local forecache = setmetatableindex(function(t,h) + local h = h * bp + local v = setmetatableindex(function(t,d) + local d = d * bp + local v = setmetatableindex(function(t,w) + -- the frame goes through the boundingbox + -- local v = { "pdf", "origin", formatters["[] 0 d 0 J %0.6F w 0 %0.6F %0.6F %0.6F re S"](r,-d,w*bp,h+d) } + local v = { "pdf", "origin", formatters["[] 0 d 0 J %0.6F w %0.6F %0.6F %0.6F %0.6F re S"](r,r/2,-d+r/2,w*bp-r,h+d-r) } + t[w] = v + return v + end) + t[d] = v return v end) + t[h] = v return v end) +local startcolor = nil +local stopcolor = nil + local function showboundingbox(tfmdata,key,value) if value then - local vfspecials = backends.pdf.tables.vfspecials - local gray = vfspecials and (vfspecials.rulecolors[value] or vfspecials.rulecolors.palegray) or gray + if not backcolors then + local vfspecials = backends.pdf.tables.vfspecials + startcolor = vfspecials.startcolor + stopcolor = vfspecials.stopcolor + end local characters = tfmdata.characters - local resources = tfmdata.resources local additions = { } - local private = resources.private + local rulecache = backcache + local showchar = true + local color = "palegray" + if type(value) == "string" then + value = settings_to_array(value) + for i=1,#value do + local v = value[i] + if v == v_frame then + rulecache = forecache + elseif v == v_background then + rulecache = backcache + elseif v == v_empty then + showchar = false + elseif v == v_none then + color = nil + else + color = v + end + end + end + local gray = color and startcolor(color) or nil + local black = gray and stopcolor or nil for unicode, old_c in next, characters do - private = private + 1 - local width = old_c.width or 0 - local height = old_c.height or 0 - local depth = old_c.depth or 0 - local new_c - if depth == 0 then - new_c = { - width = width, - height = height, - commands = { - push, - gray, - rulecache[height][width], - black, - pop, - { "slot", 1, private }, - -- { "slot", 0, private }, - } + local private = getprivate(tfmdata) + local width = old_c.width or 0 + local height = old_c.height or 0 + local depth = old_c.depth or 0 + local char = showchar and { "slot", 1, private } or nil -- { "slot", 0, private } + -- local new_c + -- if depth == 0 then + -- new_c = { + -- width = width, + -- height = height, + -- commands = { + -- push, + -- gray, + -- rulecache[height][width], + -- black, + -- pop, + -- char, + -- } + -- } + -- else + -- new_c = { + -- width = width, + -- height = height, + -- depth = depth, + -- commands = { + -- push, + -- downcache[depth], + -- gray, + -- rulecache[height+depth][width], + -- black, + -- pop, + -- char, + -- } + -- } + -- end + local rule = rulecache[height][depth][width] + local new_c = { + width = width, + height = height, + depth = depth, + commands = gray and { + -- push, + gray, + rule, + black, + -- pop, + char, + } or { + rule, + char, } - else - new_c = { - width = width, - height = height, - depth = depth, - commands = { - push, - downcache[depth], - gray, - rulecache[height+depth][width], - black, - pop, - { "slot", 1, private }, - -- { "slot", 0, private }, - } - } - end + } setmetatableindex(new_c,old_c) characters[unicode] = new_c additions[private] = old_c @@ -822,7 +922,6 @@ local function showboundingbox(tfmdata,key,value) for k, v in next, additions do characters[k] = v end - resources.private = private end end @@ -1115,7 +1214,7 @@ do end end - fonts.constructors.newfeatures.otf.register { + constructors.newfeatures.otf.register { name = "extraprivates", description = "extra privates", default = true, @@ -1251,15 +1350,13 @@ do -- another hack for a crappy font local function additalictowidth(tfmdata,key,value) local characters = tfmdata.characters - local resources = tfmdata.resources local additions = { } - local private = resources.private for unicode, old_c in next, characters do -- maybe check for math local oldwidth = old_c.width local olditalic = old_c.italic if olditalic and olditalic ~= 0 then - private = private + 1 + local private = getprivate(tfmdata) local new_c = { width = oldwidth + olditalic, height = old_c.height, @@ -1279,7 +1376,6 @@ do -- another hack for a crappy font for k, v in next, additions do characters[k] = v end - resources.private = private end registerotffeature { diff --git a/tex/context/base/mkiv/font-ini.lua b/tex/context/base/mkiv/font-ini.lua index 7ac8f218b..e0ad46cac 100644 --- a/tex/context/base/mkiv/font-ini.lua +++ b/tex/context/base/mkiv/font-ini.lua @@ -10,22 +10,22 @@ if not modules then modules = { } end modules ['font-ini'] = { <p>Not much is happening here.</p> --ldx]]-- -local allocate = utilities.storage.allocate +local allocate = utilities.storage.allocate -fonts = fonts or { } -local fonts = fonts +fonts = fonts or { } +local fonts = fonts -fonts.hashes = { identifiers = allocate() } +fonts.hashes = { identifiers = allocate() } -fonts.tables = fonts.tables or { } -fonts.helpers = fonts.helpers or { } -fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata -fonts.specifiers = fonts.specifiers or { } -- in format ! +fonts.tables = fonts.tables or { } +fonts.helpers = fonts.helpers or { } +fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata +fonts.specifiers = fonts.specifiers or { } -- in format ! -fonts.analyzers = { } -- not needed here -fonts.readers = { } -fonts.definers = { methods = { } } -fonts.loggers = { register = function() end } +fonts.analyzers = { } -- not needed here +fonts.readers = { } +fonts.definers = { methods = { } } +fonts.loggers = { register = function() end } if context then fontloader = nil diff --git a/tex/context/base/mkiv/font-one.lua b/tex/context/base/mkiv/font-one.lua index d9b9c65df..63ed610ed 100644 --- a/tex/context/base/mkiv/font-one.lua +++ b/tex/context/base/mkiv/font-one.lua @@ -41,6 +41,8 @@ local derivetable = table.derive local findbinfile = resolvers.findbinfile +local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF + local definers = fonts.definers local readers = fonts.readers local constructors = fonts.constructors @@ -139,7 +141,7 @@ local function enhance_unify_names(data, filename) local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context local unicodes = { } local names = { } - local private = constructors.privateoffset + local private = data.private or privateoffset local descriptions = data.descriptions for name, blob in next, data.characters do local code = unicodevector[name] -- or characters.name_to_unicode[name] @@ -179,13 +181,13 @@ local function enhance_unify_names(data, filename) end end data.characters = nil + data.private = private local resources = data.resources - local filename = resources.filename or file.removesuffix(file.basename(filename)) + local filename = resources.filename or file.removesuffix(file.basename(filename)) resources.filename = resolvers.unresolve(filename) -- no shortcut resources.unicodes = unicodes -- name to unicode - resources.marks = { } -- todo - -- resources.names = names -- name to index - resources.private = private + resources.marks = { } -- todo + -- resources.names = names -- name to index end local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } @@ -587,6 +589,7 @@ local function copytotfm(data) properties.fullname = fullname properties.psname = fullname properties.name = filename or fullname or fontname + properties.private = properties.private or data.private or privateoffset -- if next(characters) then return { diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index 1cdbb450a..9a3bcb9a9 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -79,6 +79,8 @@ local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) local syncspace = true local forcenotdef = false +local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF + local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes local wildcard = "*" @@ -285,7 +287,7 @@ local function copytotfm(data,cache_id) end if mathspecs then for unicode, character in next, characters do - local d = descriptions[unicode] + local d = descriptions[unicode] -- we could use parent table here local m = d.math if m then -- watch out: luatex uses horiz_variants for the parts @@ -448,6 +450,8 @@ local function copytotfm(data,cache_id) -- properties.name = specification.name -- properties.sub = specification.sub -- + properties.private = properties.private or data.private or privateoffset + -- return { characters = characters, descriptions = descriptions, diff --git a/tex/context/base/mkiv/font-oto.lua b/tex/context/base/mkiv/font-oto.lua index 0009d7f5f..031bab419 100644 --- a/tex/context/base/mkiv/font-oto.lua +++ b/tex/context/base/mkiv/font-oto.lua @@ -30,6 +30,8 @@ local registerotffeature = otffeatures.register otf.defaultbasealternate = "none" -- first last +local getprivate = fonts.constructors.getprivate + local wildcard = "*" local default = "dflt" @@ -165,13 +167,11 @@ end -- messy if we need to take that into account. local function makefake(tfmdata,name,present) - local resources = tfmdata.resources - local private = resources.private + local private = getprivate(tfmdata) local character = { intermediate = true, ligatures = { } } resources.unicodes[name] = private tfmdata.characters[private] = character tfmdata.descriptions[private] = { name = name } - resources.private = private + 1 present[name] = private return character end @@ -304,7 +304,6 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis local nofligatures = #ligatures if nofligatures > 0 then - local characters = tfmdata.characters local present = { } local done = trace_baseinit and trace_ligatures and { } diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index bff81aa87..f79e41b22 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -1512,7 +1512,7 @@ end formatreaders[13] = function(f,fontdata,offset) -- - -- this fector is only used for simple fallback fonts + -- this vector is only used for simple fallback fonts -- setposition(f,offset+2+2+4+4) -- skip format reserved length language local mapping = fontdata.mapping diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 54cacc543..1dca8962c 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -892,7 +892,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje end start = snext -- cf spec elseif forcepairadvance then - start = snext -- for testing + start = snext -- for testing, not cf spec end return head, start, true elseif krn ~= 0 then @@ -1490,7 +1490,7 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm end start = snext -- cf spec elseif forcepairadvance then - start = snext -- for testing + start = snext -- for testing, not cf spec end return head, start, true elseif krn ~= 0 then @@ -4887,10 +4887,6 @@ do local sequences = sequencelists[font] -- temp hack - if not sequencelists then - return head, false - end - nesting = nesting + 1 if nesting == 1 then @@ -5173,6 +5169,104 @@ do return head, done end + -- This is not an official helpoer and used for tracing experiments. It can be changed as I like + -- at any moment. At some point it might be used in a module that can help font development. + + function otf.datasetpositionprocessor(head,font,direction,dataset) + + currentfont = font + tfmdata = fontdata[font] + descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead + characters = tfmdata.characters -- but this branch is not entered that often anyway + local resources = tfmdata.resources + marks = resources.marks + classes = resources.classes + threshold, + factor = getthreshold(font) + checkmarks = tfmdata.properties.checkmarks + + if type(dataset) == "number" then + dataset = otfdataset(tfmdata,font,0)[dataset] + end + + local sequence = dataset[3] -- sequences[s] -- also dataset[5] + local typ = sequence.type + -- local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- store in dataset + + -- gpos_contextchain gpos_context + + -- if not gpossing then + -- return head, false + -- end + + local handler = handlers[typ] -- store in dataset + local steps = sequence.steps + local nofsteps = sequence.nofsteps + + local head = tonut(head) + local done = false + local dirstack = { } -- could move outside function but we can have local runs + local start = head + local initialrl = direction == "TRT" and -1 or 0 + local rlmode = initialrl + local rlparmode = initialrl + local topstack = 0 + local merged = steps.merged + + -- local matches = false + local position = 0 + + while start do + local char, id = ischar(start,font) + if char then + position = position + 1 + local m = merged[char] + if m then + for i=m[1],m[2] do + local step = steps[i] + local lookupcache = step.coverage + local lookupmatch = lookupcache[char] + if lookupmatch then + local ok + head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i) + if ok then + -- if matches then + -- matches[position] = i + -- else + -- matches = { [position] = i } + -- end + break + elseif not start then + break + end + end + end + if start then + start = getnext(start) + end + else + start = getnext(start) + end + elseif char == false then + start = getnext(start) + elseif id == glue_code then + start = getnext(start) + elseif id == math_code then + start = getnext(end_of_math(start)) + elseif id == dir_code then + start, topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) + elseif id == localpar_code then + start, rlparmode, rlmode = pardirstate(start) + else + start = getnext(start) + end + end + + return tonode(head) -- , matches + end + + -- end of experiment + end -- so far diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index 6084d1941..5ad7c1c6f 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -30,8 +30,8 @@ local f_index = formatters["I%05X"] local f_character_y = formatters["%C"] local f_character_n = formatters["[ %C ]"] -local check_duplicates = true -- can become an option (pseudo feature) / aways needed anyway -local check_soft_hyphen = false -- can become an option (pseudo feature) / needed for tagging +local check_duplicates = true -- can become an option (pseudo feature) / aways needed anyway +local check_soft_hyphen = true -- can become an option (pseudo feature) / needed for tagging directives.register("otf.checksofthyphen",function(v) check_soft_hyphen = v @@ -371,6 +371,7 @@ local function copyduplicates(fontdata) local duplicates = resources.duplicates if check_soft_hyphen then -- ebgaramond has a zero width empty soft hyphen + -- antykwatorunsks lacks a soft hyphen local ds = descriptions[0xAD] if not ds or ds.width == 0 then if ds then @@ -633,7 +634,6 @@ local function unifymissing(fontdata) require("font-agl") end local unicodes = { } - local private = fontdata.private local resources = fontdata.resources resources.unicodes = unicodes for unicode, d in next, fontdata.descriptions do @@ -2261,65 +2261,95 @@ end local function checkkerns(lookup) local steps = lookup.steps local nofsteps = lookup.nofsteps + local kerned = 0 for i=1,nofsteps do local step = steps[i] if step.format == "pair" then local coverage = step.coverage local kerns = true for g1, d1 in next, coverage do - if d1[1] ~= 0 or d1[2] ~= 0 or d1[4] ~= 0 then + if d1 == true then + -- all zero + elseif not d1 then + -- null + elseif d1[1] ~= 0 or d1[2] ~= 0 or d1[4] ~= 0 then kerns = false break end end if kerns then report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + local c = { } for g1, d1 in next, coverage do - coverage[g1] = d1[3] + if d1 and d1 ~= true then + c[g1] = d1[3] + end end + step.coverage = c step.format = "kern" + kerned = kerned + 1 end end end + return kerned end +-- There are several options to optimize but we have this somewhat fuzzy aspect of +-- advancing (depending on the second of a pair) so we need to retain that information. +-- +-- We can have: +-- +-- true, nil|false +-- +-- which effectively means: nothing to be done and advance to next (so not next of +-- next) and because coverage should be not overlapping we can wipe these. However, +-- checking for (true,nil) (false,nil) and omitting them doesn't gain much. + +-- Because we pack we cannot mix tables and numbers so we can only turn a whole set in +-- format kern instead of pair. + local function checkpairs(lookup) local steps = lookup.steps local nofsteps = lookup.nofsteps local kerned = 0 - for i=1,nofsteps do - local step = steps[i] - if step.format == "pair" then - local coverage = step.coverage - local kerns = true - for g1, d1 in next, coverage do - for g2, d2 in next, d1 do - if d2[2] then - --- true or { a, b, c, d } - kerns = false - break - else - local v = d2[1] - if v == true then - -- all zero - elseif v and (v[1] ~= 0 or v[2] ~= 0 or v[4] ~= 0) then - kerns = false - break - end + + local function onlykerns(step) + local coverage = step.coverage + for g1, d1 in next, coverage do + for g2, d2 in next, d1 do + if d2[2] then + --- true or { a, b, c, d } + return false + else + local v = d2[1] + if v == true then + -- all zero + elseif v and (v[1] ~= 0 or v[2] ~= 0 or v[4] ~= 0) then + return false end end end - if kerns then + end + return coverage + end + + for i=1,nofsteps do + local step = steps[i] + if step.format == "pair" then + local coverage = onlykerns(step) + if coverage then report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) for g1, d1 in next, coverage do + local d = { } for g2, d2 in next, d1 do local v = d2[1] if v == true then - d1[g2] = nil + -- ignore -- d1[g2] = nil elseif v then - d1[g2] = v[3] + d[g2] = v[3] -- d1[g2] = v[3] end end + coverage[g1] = d end step.format = "kern" kerned = kerned + 1 @@ -2345,9 +2375,9 @@ function readers.compact(data) for i=1,#lookups do local lookup = lookups[i] local nofsteps = lookup.nofsteps + local kind = lookup.type allsteps = allsteps + nofsteps if nofsteps > 1 then - local kind = lookup.type local merg = merged if kind == "gsub_single" or kind == "gsub_alternate" or kind == "gsub_multiple" then merged = merged + mergesteps_1(lookup) @@ -2355,7 +2385,7 @@ function readers.compact(data) merged = merged + mergesteps_4(lookup) elseif kind == "gpos_single" then merged = merged + mergesteps_1(lookup,true) - checkkerns(lookup) + kerned = kerned + checkkerns(lookup) elseif kind == "gpos_pair" then merged = merged + mergesteps_2(lookup,true) kerned = kerned + checkpairs(lookup) @@ -2367,6 +2397,12 @@ function readers.compact(data) if merg ~= merged then lookup.merged = true end + elseif nofsteps == 1 then + if kind == "gpos_single" then + kerned = kerned + checkkerns(lookup) + elseif kind == "gpos_pair" then + kerned = kerned + checkpairs(lookup) + end end end else diff --git a/tex/context/base/mkiv/font-tfm.lua b/tex/context/base/mkiv/font-tfm.lua index 6584190ce..109efefa6 100644 --- a/tex/context/base/mkiv/font-tfm.lua +++ b/tex/context/base/mkiv/font-tfm.lua @@ -244,6 +244,8 @@ local function read_from_tfm(specification) -- constructors.enhanceparameters(parameters) -- official copies for us -- + properties.private = properties.private or tfmdata.private or privateoffset + -- if newtfmdata then -- -- We do nothing as we assume flat tfm files. It would become real messy @@ -436,7 +438,7 @@ do local originals = tfmdata.characters local indices = { } local parentfont = { "font", 1 } - local private = fonts.constructors.privateoffset + local private = tfmdata or fonts.constructors.privateoffset local reported = encdone[tfmfile][encfile] -- create characters table @@ -514,6 +516,7 @@ do tfmdata.tounicode = 1 tfmdata.embedding = "subset" tfmdata.usedbitmap = bitmap and virtualid + tfmdata.private = private return tfmdata end diff --git a/tex/context/base/mkiv/grph-rul.lua b/tex/context/base/mkiv/grph-rul.lua index e3d1d8963..6d05270a4 100644 --- a/tex/context/base/mkiv/grph-rul.lua +++ b/tex/context/base/mkiv/grph-rul.lua @@ -127,13 +127,17 @@ end do - local f_rectangle = formatters["%F w %F %F %F %F re %s"] + -- maybe %.6F + + local f_rectangle = formatters["%.6F w %.6F %.6F %.6F %.6F re %s"] + local f_baselined = formatters["%.6F w %.6F %.6F %.6F %.6F re s %.6F %.6F m %.6F %.6F l s"] + local f_dashlined = formatters["%.6F w %.6F %.6F %.6F %.6F re s [%.6F %.6F] 2 d %.6F %.6F m %.6F %.6F l s"] local f_radtangle = formatters[ [[ - %F w %F %F m - %F %F l %F %F %F %F y - %F %F l %F %F %F %F y - %F %F l %F %F %F %F y - %F %F l %F %F %F %F y + %.6F w %.6F %.6F m + %.6F %.6F l %.6F %.6F %.6F %.6F y + %.6F %.6F l %.6F %.6F %.6F %.6F y + %.6F %.6F l %.6F %.6F %.6F %.6F y + %.6F %.6F l %.6F %.6F %.6F %.6F y h %s ]] ] @@ -160,6 +164,30 @@ do ruleactions.draw = ruleactions.fill ruleactions.stroke = ruleactions.fill + local getwhd = nodes.nuts.getwhd + + ruleactions.box = function(p,h,v,i,n) + local w, h, d = getwhd(n) + local line = p.line or 65536 + local l = line *bpfactor + local w = w * bpfactor + local h = h * bpfactor + local d = d * bpfactor + local o = l / 2 + if (d >= 0 and h >= 0) or (d <= 0 and h <= 0) then + local dashed = tonumber(p.dashed) + if dashed and dashed > 5*line then + dashed = dashed * bpfactor + local delta = (w - 2*dashed*floor(w/(2*dashed)))/2 + pdfprint("direct",f_dashlined(l,o,o,w-l,h+d-l,dashed,dashed,delta,d,w-delta,d)) + else + pdfprint("direct",f_baselined(l,o,o,w-l,h+d-l,0,d,w,d)) + end + else + pdfprint("direct",f_rectangle(l,o,o,w-l,h+d-l)) + end + end + end interfaces.implement { diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua index a1006f773..fc251fddc 100644 --- a/tex/context/base/mkiv/lpdf-col.lua +++ b/tex/context/base/mkiv/lpdf-col.lua @@ -24,7 +24,7 @@ local registrations = backends.pdf.registrations local nodepool = nodes.nuts.pool local register = nodepool.register -local pdfliteral = nodepool.pdfliteral +local pdfpageliteral = nodepool.pdfpageliteral local pdfconstant = lpdf.constant local pdfdictionary = lpdf.dictionary @@ -42,13 +42,20 @@ local adddocumentcolorspace = lpdf.adddocumentcolorspace local adddocumentextgstate = lpdf.adddocumentextgstate local colors = attributes.colors -local transparencies = attributes.transparencies -local registertransparancy = transparencies.register local registercolor = colors.register local colorsvalue = colors.value -local transparenciesvalue = transparencies.value local forcedmodel = colors.forcedmodel local getpagecolormodel = colors.getpagecolormodel +local colortoattributes = colors.toattributes + +local transparencies = attributes.transparencies +local registertransparancy = transparencies.register +local transparenciesvalue = transparencies.value +local transparencytoattribute = transparencies.toattribute + +local unsetvalue = attributes.unsetvalue + +local setmetatableindex = table.setmetatableindex local c_transparency = pdfconstant("Transparency") @@ -81,7 +88,7 @@ local transparencygroups = { } lpdf.colorspaceconstants = colorspaceconstants lpdf.transparencygroups = transparencygroups -table.setmetatableindex(transparencygroups, function(transparencygroups,colormodel) +setmetatableindex(transparencygroups, function(transparencygroups,colormodel) local cs = colorspaceconstants[colormodel] if cs then local d = pdfdictionary { @@ -116,26 +123,26 @@ lpdf.registerpagefinalizer(addpagegroup,3,"pagegroup") -- color injection function nodeinjections.rgbcolor(r,g,b) - return register(pdfliteral(f_rgb(r,g,b,r,g,b))) + return register(pdfpageliteral(f_rgb(r,g,b,r,g,b))) end function nodeinjections.cmykcolor(c,m,y,k) - return register(pdfliteral(f_cmyk(c,m,y,k,c,m,y,k))) + return register(pdfpageliteral(f_cmyk(c,m,y,k,c,m,y,k))) end function nodeinjections.graycolor(s) -- caching 0/1 does not pay off - return register(pdfliteral(f_gray(s,s))) + return register(pdfpageliteral(f_gray(s,s))) end function nodeinjections.spotcolor(n,f,d,p) if type(p) == "string" then p = gsub(p,","," ") -- brr misuse of spot end - return register(pdfliteral(f_spot(n,n,p,p))) + return register(pdfpageliteral(f_spot(n,n,p,p))) end function nodeinjections.transparency(n) - return register(pdfliteral(f_tr_gs(n))) + return register(pdfpageliteral(f_tr_gs(n))) end -- a bit weird but let's keep it here for a while @@ -154,7 +161,7 @@ function nodeinjections.effect(effect,stretch,rulethickness) -- always, no zero test (removed) rulethickness = bp * rulethickness effect = effects[effect] or effects['normal'] - return register(pdfliteral(f_effect(stretch,rulethickness,effect))) -- watch order + return register(pdfpageliteral(f_effect(stretch,rulethickness,effect))) -- watch order end -- spot- and indexcolors @@ -701,31 +708,113 @@ function lpdf.finishtransparencycode() end end --- this will move to lpdf-spe.lua +-- this will move to lpdf-spe.lua an dwe then can also add a metatable with +-- normal context colors + +do + + local pdfcolor = lpdf.color + local pdftransparency = lpdf.transparency + + local f_slant = formatters["q 1 0 %F 1 0 0 cm"] + + -- local fillcolors = { + -- red = { "pdf", "origin", "1 0 0 rg" }, + -- green = { "pdf", "origin", "0 1 0 rg" }, + -- blue = { "pdf", "origin", "0 0 1 rg" }, + -- gray = { "pdf", "origin", ".5 g" }, + -- black = { "pdf", "origin", "0 g" }, + -- palered = { "pdf", "origin", "1 .75 .75 rg" }, + -- palegreen = { "pdf", "origin", ".75 1 .75 rg" }, + -- paleblue = { "pdf", "origin", ".75 .75 1 rg" }, + -- palegray = { "pdf", "origin", ".75 g" }, + -- } + -- + -- local strokecolors = { + -- red = { "pdf", "origin", "1 0 0 RG" }, + -- green = { "pdf", "origin", "0 1 0 RG" }, + -- blue = { "pdf", "origin", "0 0 1 RG" }, + -- gray = { "pdf", "origin", ".5 G" }, + -- black = { "pdf", "origin", "0 G" }, + -- palered = { "pdf", "origin", "1 .75 .75 RG" }, + -- palegreen = { "pdf", "origin", ".75 1 .75 RG" }, + -- paleblue = { "pdf", "origin", ".75 .75 1 RG" }, + -- palegray = { "pdf", "origin", ".75 G" }, + -- } + -- + -- backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color + -- + -- red = { "pdf", "origin", "1 0 0 rg 1 0 0 RG" }, + -- green = { "pdf", "origin", "0 1 0 rg 0 1 0 RG" }, + -- blue = { "pdf", "origin", "0 0 1 rg 0 0 1 RG" }, + -- gray = { "pdf", "origin", ".75 g .75 G" }, + -- black = { "pdf", "origin", "0 g 0 G" }, + -- + -- -- rulecolors = fillcolors, + -- -- fillcolors = fillcolors, + -- -- strokecolors = strokecolors, + -- + -- startslant = function(a) return { "pdf", "origin", f_slant(a) } end, + -- stopslant = { "pdf", "origin", "Q" }, + -- + -- } + + local slants = setmetatableindex(function(t,k) + local v = { "pdf", "origin", f_slant(a) } + t[k] = v + return k + end) + + local function startslant(a) + return slants[a] + end -local f_slant = formatters["q 1 0 %F 1 0 0 cm"] + local c_cache = setmetatableindex(function(t,m) + local v = setmetatableindex(function(t,c) + local p = { "pdf", "origin", "q " .. pdfcolor(m,c) } + t[c] = p + return p + end) + t[m] = v + return v + end) -backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color + -- we inherit the outer transparency + + local t_cache = setmetatableindex(function(t,transparency) + local p = pdftransparency(transparency) + local v = setmetatableindex(function(t,colormodel) + local v = setmetatableindex(function(t,color) + local v = { "pdf", "origin", "q " .. pdfcolor(colormodel,color) .. " " .. p } + t[color] = v + return v + end) + t[colormodel] = v + return v + end) + t[transparency] = v + return v + end) - red = { "pdf", "origin", "1 0 0 rg 1 0 0 RG" }, - green = { "pdf", "origin", "0 1 0 rg 0 1 0 RG" }, - blue = { "pdf", "origin", "0 0 1 rg 0 0 1 RG" }, - gray = { "pdf", "origin", ".75 g .75 G" }, - black = { "pdf", "origin", "0 g 0 G" }, + local function startcolor(k) + local m, c = colortoattributes(k) + local t = transparencytoattribute(k) + if t then + return t_cache[t][m][c] + else + return c_cache[m][c] + end + end - rulecolors = { - red = { "pdf", "origin", '1 0 0 rg' }, - green = { "pdf", "origin", '0 1 0 rg' }, - blue = { "pdf", "origin", '0 0 1 rg' }, - gray = { "pdf", "origin", '.5 g' }, - black = { "pdf", "origin", '0 g' }, - palered = { "pdf", "origin", '1 .75 .75 rg' }, - palegreen = { "pdf", "origin", '.75 1 .75 rg' }, - paleblue = { "pdf", "origin", '.75 .75 1 rg' }, - palegray = { "pdf", "origin", '.75 g' }, - }, + backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color - startslant = function(a) return { "pdf", "origin", f_slant(a) } end, - stopslant = { "pdf", "origin", "Q" }, + startcolor = startcolor, + -- stopcolor = { "pdf", "origin", "0 g 0 G Q" }, + stopcolor = { "pdf", "origin", "Q" }, -} + startslant = startslant, + stopslant = { "pdf", "origin", "Q" }, + + } + +end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index 635f365a9..c5480d548 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -1203,7 +1203,7 @@ do local f_actual_text = formatters["/Span <</ActualText %s >> BDC"] local context = context - local pdfdirect = nodes.pool.pdfdirect + local pdfdirect = nodes.pool.pdfdirectliteral -- todo: use tounicode from the font mapper diff --git a/tex/context/base/mkiv/lpdf-mis.lua b/tex/context/base/mkiv/lpdf-mis.lua index 9d903ce96..7eb4829f8 100644 --- a/tex/context/base/mkiv/lpdf-mis.lua +++ b/tex/context/base/mkiv/lpdf-mis.lua @@ -29,7 +29,7 @@ local nuts = nodes.nuts local copy_node = nuts.copy local nodepool = nuts.pool -local pdfliteral = nodepool.pdfliteral +local pdfpageliteral = nodepool.pdfpageliteral local register = nodepool.register local pdfdictionary = lpdf.dictionary @@ -69,10 +69,10 @@ local v_paper = variables.paper local v_attachment = variables.attachment local v_layer = variables.layer -local positive = register(pdfliteral("/GSpositive gs")) -local negative = register(pdfliteral("/GSnegative gs")) -local overprint = register(pdfliteral("/GSoverprint gs")) -local knockout = register(pdfliteral("/GSknockout gs")) +local positive = register(pdfpageliteral("/GSpositive gs")) +local negative = register(pdfpageliteral("/GSnegative gs")) +local overprint = register(pdfpageliteral("/GSoverprint gs")) +local knockout = register(pdfpageliteral("/GSknockout gs")) local function initializenegative() local a = pdfarray { 0, 1 } diff --git a/tex/context/base/mkiv/lpdf-nod.lua b/tex/context/base/mkiv/lpdf-nod.lua index 985d05a82..ca4c51c59 100644 --- a/tex/context/base/mkiv/lpdf-nod.lua +++ b/tex/context/base/mkiv/lpdf-nod.lua @@ -24,10 +24,10 @@ local new_node = nuts.new local nodepool = nuts.pool local register = nodepool.register -local pdforiginliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdforiginliteral,"mode",0) -- set_origin_code -local pdfpageliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",1) -- page_code -local pdfdirectliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",2) -- direct_code -local pdfrawliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfrawliteral, "mode",3) -- raw_code +local pdforiginliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdforiginliteral,"mode",0) -- set_origin_code +local pdfpageliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",1) -- page_code +local pdfdirectliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",2) -- direct_code +local pdfrawliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfrawliteral, "mode",3) -- raw_code local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave)) local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore)) @@ -53,7 +53,7 @@ function nodepool.pdfpageliteral (str) local t = copy_node(pdfpageliteral ) se function nodepool.pdfdirectliteral(str) local t = copy_node(pdfdirectliteral) setfield(t,"data",str) return t end function nodepool.pdfrawliteral (str) local t = copy_node(pdfrawliteral ) setfield(t,"data",str) return t end -nodepool.pdfliteral = nodepool.pdfpageliteral +nodepool.pdfliteral = nodepool.pdfpageliteral -- best is to use a specific one: origin | page | direct | raw function nodepool.pdfsave() return copy_node(pdfsave) diff --git a/tex/context/base/mkiv/lpdf-ren.lua b/tex/context/base/mkiv/lpdf-ren.lua index a57c550fd..e9b22f382 100644 --- a/tex/context/base/mkiv/lpdf-ren.lua +++ b/tex/context/base/mkiv/lpdf-ren.lua @@ -9,8 +9,8 @@ if not modules then modules = { } end modules ['lpdf-ren'] = { -- rendering local tostring, tonumber, next = tostring, tonumber, next -local format, rep = string.format, string.rep local concat = table.concat +local formatters = string.formatters local settings_to_array = utilities.parsers.settings_to_array local getrandom = utilities.randomizer.get @@ -54,7 +54,7 @@ local copy_node = nuts.copy local nodepool = nuts.pool local register = nodepool.register -local pdfliteral = nodepool.pdfliteral +local pdfpageliteral = nodepool.pdfpageliteral local pdf_ocg = pdfconstant("OCG") local pdf_ocmd = pdfconstant("OCMD") @@ -239,33 +239,38 @@ function executers.togglelayer(arguments) return setlayer(pdf_toggle,arguments) -- injection +local f_bdc = formatters["/OC /%s BDC"] +local s_emc = "EMC" + function codeinjections.startlayer(name) -- used in mp if not name then name = "unknown" end useviewerlayer(name) - return format("/OC /%s BDC",escapednames[name]) + return f_bdc(escapednames[name]) end function codeinjections.stoplayer(name) -- used in mp - return "EMC" + return s_emc end local cache = { } +local stop = nil function nodeinjections.startlayer(name) local c = cache[name] if not c then useviewerlayer(name) - c = register(pdfliteral(format("/OC /%s BDC",escapednames[name]))) + c = register(pdfpageliteral(f_bdc(escapednames[name]))) cache[name] = c end return copy_node(c) end -local stop = register(pdfliteral("EMC")) - function nodeinjections.stoplayer() + if not stop then + stop = register(pdfpageliteral(s_emc)) + end return copy_node(stop) end @@ -281,7 +286,7 @@ function nodeinjections.startstackedlayer(s,t,first,last) r[#r+1] = startlayer(values[t[i]]) end r = concat(r," ") - return pdfliteral(r) + return pdfpageliteral(r) end function nodeinjections.stopstackedlayer(s,t,first,last) @@ -290,7 +295,7 @@ function nodeinjections.stopstackedlayer(s,t,first,last) r[#r+1] = stoplayer() end r = concat(r," ") - return pdfliteral(r) + return pdfpageliteral(r) end function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2) @@ -302,7 +307,7 @@ function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2) r[#r+1] = startlayer(values[t2[i]]) end r = concat(r," ") - return pdfliteral(r) + return pdfpageliteral(r) end -- transitions diff --git a/tex/context/base/mkiv/lpdf-tag.lua b/tex/context/base/mkiv/lpdf-tag.lua index e33c8a811..9d33df6f3 100644 --- a/tex/context/base/mkiv/lpdf-tag.lua +++ b/tex/context/base/mkiv/lpdf-tag.lua @@ -55,7 +55,8 @@ local tonut = nuts.tonut local tonode = nuts.tonode local nodepool = nuts.pool -local pdfliteral = nodepool.pdfliteral +local pdfpageliteral = nodepool.pdfpageliteral +local register = nodepool.register local getid = nuts.getid local getattr = nuts.getattr @@ -67,10 +68,9 @@ local setfield = nuts.setfield local setlink = nuts.setlink local setlist = nuts.setlist +local copy_node = nuts.copy local traverse_nodes = nuts.traverse local tosequence = nuts.tosequence -local insert_before = nuts.insert_before -local insert_after = nuts.insert_after local structure_stack = { } local structure_kids = pdfarray() @@ -312,8 +312,14 @@ end -- no need to adapt head, as we always operate on lists +local EMCliteral = nil + function nodeinjections.addtags(head) + if not EMCliteral then + EMCliteral = register(pdfpageliteral("EMC")) + end + local last = nil local ranges = { } local range = nil @@ -321,8 +327,9 @@ function nodeinjections.addtags(head) local function collectranges(head,list) for n in traverse_nodes(head) do - local id = getid(n) -- 14: image, 8: literal (mp) + local id = getid(n) if id == glyph_code then + -- maybe also disc local at = getattr(n,a_tagged) if not at then range = nil @@ -344,8 +351,7 @@ function nodeinjections.addtags(head) end last = nil else - local nl = getlist(n) - collectranges(nl,n) + collectranges(getlist(n),n) end end end @@ -383,7 +389,6 @@ function nodeinjections.addtags(head) local taglist = specification.taglist local noftags = #taglist local common = 0 - if top then for i=1,noftags >= noftop and noftop or noftags do if top[i] == taglist[i] then @@ -412,12 +417,12 @@ function nodeinjections.addtags(head) prev = prv end end - if prev then - literal = pdfliteral(makecontent(prev,id,specification)) + literal = pdfpageliteral(makecontent(prev,id,specification)) elseif ignore then - literal = pdfliteral(makeignore(specification)) + literal = pdfpageliteral(makeignore(specification)) end + if literal then local prev = getprev(start) if prev then @@ -427,14 +432,27 @@ function nodeinjections.addtags(head) if list and getlist(list) == start then setlist(list,literal) end + local literal = copy_node(EMCliteral) -- use insert instead: - local literal = pdfliteral("EMC") local next = getnext(stop) if next then setlink(literal,next) end setlink(stop,literal) end + +-- if literal then +-- if list and getlist(list) == start then +-- setlink(literal,start) +-- setlist(list,literal) +-- else +-- setlink(getprev(start),literal,start) +-- end +-- -- use insert instead: +-- local literal = copy_node(EMCliteral) +-- setlink(stop,literal,getnext(stop)) +-- end + top = taglist noftop = noftags end @@ -558,9 +576,9 @@ end -- end -- -- if r > 0 then --- local literal = pdfliteral(concat(result,"\n")) +-- local literal = pdfpageliteral(concat(result,"\n")) -- -- use insert instead: --- local literal = pdfliteral(result) +-- local literal = pdfpageliteral(result) -- local prev = getprev(start) -- if prev then -- setlink(prev,literal) @@ -582,7 +600,7 @@ end -- for i=1,noftop do -- result[i] = "EMC" -- end --- local literal = pdfliteral(concat(result,"\n")) +-- local literal = pdfpageliteral(concat(result,"\n")) -- -- use insert instead: -- local next = getnext(last) -- if next then diff --git a/tex/context/base/mkiv/lxml-ini.lua b/tex/context/base/mkiv/lxml-ini.lua index 11f634739..86d113f7c 100644 --- a/tex/context/base/mkiv/lxml-ini.lua +++ b/tex/context/base/mkiv/lxml-ini.lua @@ -111,6 +111,7 @@ implement { name = "xmlflushtext", actions = lxml.text, arg implement { name = "xmlflushpure", actions = lxml.pure, arguments = "string" } implement { name = "xmltobuffer", actions = lxml.tobuffer, arguments = { "string", "string", "string" } } implement { name = "xmltobufferverbose", actions = lxml.tobuffer, arguments = { "string", "string", "string", true } } +implement { name = "xmltobuffertextonly", actions = lxml.tobuffer, arguments = { "string", "string", "string", false } } implement { name = "xmltofile", actions = lxml.tofile, arguments = { "string", "string", "string" } } implement { name = "xmltoparameters", actions = lxml.toparameters, arguments = "string" } implement { name = "xmlverbatim", actions = lxml.verbatim, arguments = "string" } diff --git a/tex/context/base/mkiv/lxml-ini.mkiv b/tex/context/base/mkiv/lxml-ini.mkiv index 6ba6bc8d4..f97857fbe 100644 --- a/tex/context/base/mkiv/lxml-ini.mkiv +++ b/tex/context/base/mkiv/lxml-ini.mkiv @@ -111,6 +111,7 @@ \let\xmltext \clf_xmltext \let\xmltobuffer \clf_xmltobuffer % id pattern name \let\xmltobufferverbose \clf_xmltobufferverbose % id pattern name +\let\xmltobuffertextonly \clf_xmltobuffertextonly % id pattern name \let\xmltofile \clf_xmltofile % id pattern filename \let\xmltoparameters \clf_xmltoparameters \let\xmlverbatim \clf_xmlverbatim @@ -129,14 +130,23 @@ % goodie: -\unexpanded\def\xmlprettyprint#1#2% - {\xmltobufferverbose{#1}{.}{xml-temp}% - \ifdefined\scitebuffer - \scitebuffer[#2][xml-temp]% +\def\xmltempbuffername{xml-temp} + +\unexpanded\def\prettyprintbuffer#1#2% only used here + {\ifdefined\scitebuffer + \scitebuffer[#2][#1]% \else - \typebuffer[xml-temp][\c!option=#2]% + \typebuffer[#1][\c!option=#2]% \fi} +\unexpanded\def\xmlprettyprint#1#2% + {\xmltobufferverbose{#1}{.}{\xmltempbuffername}% + \prettyprintbuffer\xmltempbuffername{#2}} + +\unexpanded\def\xmlprettyprinttext#1#2% + {\xmltobuffertextonly{#1}{.}{\xmltempbuffername}% + \prettyprintbuffer\xmltempbuffername{#2}} + % kind of special: \let\xmlstartraw\clf_xmlstartraw diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua index 76a20fbef..f23919801 100644 --- a/tex/context/base/mkiv/lxml-tex.lua +++ b/tex/context/base/mkiv/lxml-tex.lua @@ -58,6 +58,7 @@ local xmlcontent = xml.content local xmllastmatch = xml.lastmatch local xmlpushmatch = xml.pushmatch local xmlpopmatch = xml.popmatch +local xmlstring = xml.string directives.enable("xml.path.keeplastmatch") @@ -2239,8 +2240,12 @@ texfinalizers.lowerall = xmlfinalizers.lowerall function lxml.tobuffer(id,pattern,name,unescaped) local collected = xmlapplylpath(getid(id),pattern) if collected then - if unescaped then + if unescaped == true then collected = xmlcontent(collected[1]) -- expanded entities ! + elseif unescaped == false then + local t = { } + xmlstring(collected[1],function(s) t[#t+1] = s end) + collected = concat(t) else collected = tostring(collected[1]) end diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua index 68f2c5ce4..826669a3d 100644 --- a/tex/context/base/mkiv/math-act.lua +++ b/tex/context/base/mkiv/math-act.lua @@ -218,6 +218,8 @@ sequencers.appendaction("mathparameters","system","mathematics.overloadparameter sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont") sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont") +local virtualized = mathematics.virtualized + function mathematics.overloaddimensions(target,original,set) local goodies = target.goodies if goodies then @@ -235,11 +237,19 @@ function mathematics.overloaddimensions(target,original,set) local hfactor = parameters.hfactor local vfactor = parameters.vfactor local addprivate = fonts.helpers.addprivate -target.type = "virtual" -target.properties.virtualized = true + -- to be sure + target.type = "virtual" + target.properties.virtualized = true + -- local function overload(dimensions) for unicode, data in next, dimensions do local character = characters[unicode] + if not character then + local c = virtualized[unicode] + if c then + character = characters[c] + end + end if character then -- local width = data.width @@ -511,12 +521,14 @@ local function horizontalcode(family,unicode) end elseif kind == e_right then local charlist = data[3].horiz_variants - local right = charlist[#charlist] - roffset = abs((right["start"] or 0) - (right["end"] or 0)) + if charlist then + local right = charlist[#charlist] + roffset = abs((right["start"] or 0) - (right["end"] or 0)) + end elseif kind == e_horizontal then local charlist = data[3].horiz_variants if charlist then - local left = charlist[1] + local left = charlist[1] local right = charlist[#charlist] loffset = abs((left ["start"] or 0) - (left ["end"] or 0)) roffset = abs((right["start"] or 0) - (right["end"] or 0)) diff --git a/tex/context/base/mkiv/math-frc.mkiv b/tex/context/base/mkiv/math-frc.mkiv index b573e69bd..762fc8d23 100644 --- a/tex/context/base/mkiv/math-frc.mkiv +++ b/tex/context/base/mkiv/math-frc.mkiv @@ -235,6 +235,8 @@ % also makes testing easier. When left and right margins are needed we might merge the % variants again. After all, these are not real installers. +% the denominator is in cramped! + \setvalue{\??mathfractionalternative\v!inner}% {\ifcase\d_math_fraction_margin \expandafter\math_fraction_inner_normal diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua index 2cb4e2413..c4bb822d6 100644 --- a/tex/context/base/mkiv/math-ini.lua +++ b/tex/context/base/mkiv/math-ini.lua @@ -132,11 +132,39 @@ local extensibles = allocate { table.setmetatableindex(extensibles,function(t,k) t[k] = 0 return 0 end) -mathematics.extensibles = extensibles -mathematics.classes = classes -mathematics.codes = codes ------------.accents = codes -mathematics.families = families +local virtualized = allocate { +} + +function mathematics.virtualize(unicode,virtual) + + local function virtualize(k,v) + local c = virtualized[k] + if c == v then + report_math("character %C is already virtualized to %C",k,v) + elseif c then + report_math("character %C is already virtualized to %C, ignoring mapping to %C",k,c,v) + else + virtualized[k] = v + end + end + + if type(unicode) == "table" then + for k, v in next, unicode do + virtualize(k,v) + end + elseif type(unicode) == "number" and type(virtual) == "number" then + virtualize(unicode,virtual) + -- else + -- error + end +end + +mathematics.extensibles = extensibles +mathematics.classes = classes +mathematics.codes = codes +-----------.accents = codes +mathematics.families = families +mathematics.virtualized = virtualized -- there will be proper functions soon (and we will move this code in-line) -- no need for " in class and family (saves space) diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua index 970ce3d87..50e21669d 100644 --- a/tex/context/base/mkiv/math-noa.lua +++ b/tex/context/base/mkiv/math-noa.lua @@ -116,7 +116,6 @@ local setsub = nuts.setsub local setsup = nuts.setsup local flush_node = nuts.flush -local new_node = nuts.new -- todo: pool: math_noad math_sub local copy_node = nuts.copy local slide_nodes = nuts.slide local set_visual = nuts.setvisual @@ -126,6 +125,10 @@ local mlist_to_hlist = nodes.mlist_to_hlist local font_of_family = node.family_font local new_kern = nodepool.kern +local new_submlist = nodepool.submlist +local new_noad = nodepool.noad +local new_delimiter = nodepool.delimiter +local new_fence = nodepool.fence local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers @@ -174,8 +177,8 @@ local math_noad = nodecodes.noad -- attr nucleus sub sup local math_accent = nodecodes.accent -- attr nucleus sub sup accent local math_radical = nodecodes.radical -- attr nucleus sub sup left degree local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right -local math_box = nodecodes.subbox -- attr list -local math_sub = nodecodes.submlist -- attr list +local math_subbox = nodecodes.subbox -- attr list +local math_submlist = nodecodes.submlist -- attr list local math_char = nodecodes.mathchar -- attr fam char local math_textchar = nodecodes.mathtextchar -- attr fam char local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char @@ -253,7 +256,7 @@ local function process(start,what,n,parent) noad = getsub (start) if noad then process(noad,what,n,start) end -- list elseif id == math_char or id == math_textchar or id == math_delim then break - elseif id == math_box or id == math_sub then + elseif id == math_subbox or id == math_submlist then local noad = getlist(start) if noad then process(noad,what,n,start) end -- list (not getlist !) elseif id == math_fraction then local noad = getfield(start,"num") if noad then process(noad,what,n,start) end -- list @@ -298,7 +301,7 @@ local function processnested(current,what,n) noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list - elseif id == math_box or id == math_sub then + elseif id == math_subbox or id == math_submlist then noad = getlist(current) if noad then process(noad,what,n,current) end -- list (not getlist !) elseif id == math_fraction then noad = getfield(current,"num") if noad then process(noad,what,n,current) end -- list @@ -334,7 +337,7 @@ local function processstep(current,process,n,id) noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list - elseif id == math_box or id == math_sub then + elseif id == math_subbox or id == math_submlist then noad = getlist(current) if noad then process(noad,n,current) end -- list (not getlist !) elseif id == math_fraction then noad = getfield(current,"num") if noad then process(noad,n,current) end -- list @@ -733,8 +736,8 @@ processors.autofences = autofences local dummyfencechar = 0x2E local function makefence(what,char) - local d = new_node(math_delim) - local f = new_node(math_fence) + local d = new_delimiter() + local f = new_fence() if char then local sym = getnucleus(char) local chr = getchar(sym) @@ -753,7 +756,7 @@ local function makefence(what,char) end local function makelist(noad,f_o,o_next,c_prev,f_c,middle) - local list = new_node(math_sub) + local list = new_submlist() setlist(list,f_o) setsubtype(noad,noad_inner) setnucleus(noad,list) @@ -986,7 +989,7 @@ local function replace(pointer,what,n,parent) if start_super == stop_super then setsup(pointer,getnucleus(start_super)) else - local list = new_node(math_sub) -- todo attr + local list = new_submlist() -- todo attr setlist(list,start_super) setsup(pointer,list) end @@ -999,7 +1002,7 @@ local function replace(pointer,what,n,parent) if start_sub == stop_sub then setsub(pointer,getnucleus(start_sub)) else - local list = new_node(math_sub) -- todo attr + local list = new_submlist() -- todo attr setlist(list,start_sub) setsub(pointer,list) end @@ -1267,12 +1270,13 @@ local default_factor = 1/20 local setcolor = nodes.tracers.colors.set local resetcolor = nodes.tracers.colors.reset local italic_kern = new_kern + local c_positive_d = "trace:dg" local c_negative_d = "trace:dr" local function insert_kern(current,kern) - local sub = new_node(math_sub) -- todo: pool - local noad = new_node(math_noad) -- todo: pool + local sub = new_submlist() + local noad = new_noad() setlist(sub,kern) setnext(kern,noad) setnucleus(noad,current) @@ -1467,6 +1471,8 @@ do return k end) + -- no correction after prime because that moved to a superscript + kernpairs[math_char] = function(pointer,what,n,parent) if getattr(pointer,a_kernpairs) == 1 then local font = getfont(pointer) @@ -1537,6 +1543,8 @@ local movesub = { [0x2037] = 0xFE937, } +mathematics.virtualize(movesub) + -- local movesub = { -- -- primes -- [0x2032] = 0x2032, diff --git a/tex/context/base/mkiv/meta-pdf.lua b/tex/context/base/mkiv/meta-pdf.lua index c17a2a4c7..dfc00ed9e 100644 --- a/tex/context/base/mkiv/meta-pdf.lua +++ b/tex/context/base/mkiv/meta-pdf.lua @@ -31,7 +31,7 @@ local pdfgraycode = lpdf.graycode local pdfspotcode = lpdf.spotcode local pdftransparencycode = lpdf.transparencycode local pdffinishtransparencycode = lpdf.finishtransparencycode -local pdfliteral = nodes.pool.pdfliteral +----- pdfpageliteral = nodes.pool.pdfpageliteral metapost.mptopdf = metapost.mptopdf or { } local mptopdf = metapost.mptopdf @@ -64,7 +64,7 @@ resetall() -- -- comment hack -- -- local function pdfcode(str) --- context(pdfliteral(str)) +-- context(pdfpageliteral(str)) -- end local pdfcode = context.pdfliteral diff --git a/tex/context/base/mkiv/node-acc.lua b/tex/context/base/mkiv/node-acc.lua index dccd7b7c0..c3400c752 100644 --- a/tex/context/base/mkiv/node-acc.lua +++ b/tex/context/base/mkiv/node-acc.lua @@ -136,6 +136,8 @@ end) -- -- tasks.appendaction("processors", "words", "nodes.injectspans") -- +-- local pdfpageliteral = nuts.pool.pdfpageliteral +-- -- local function injectspans(head) -- local done = false -- for n in traverse_nodes(tonut(head)) do @@ -144,8 +146,8 @@ end) -- local a = getattr(n,a_hyphenated) -- if a then -- local str = codes[a] --- local b = new_pdfliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str))) --- local e = new_pdfliteral("EMC") +-- local b = pdfpageliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str))) +-- local e = pdfpageliteral("EMC") -- insert_before(head,n,b) -- insert_after(head,n,e) -- done = true diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index 858408bd9..815ca2ca3 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -182,6 +182,16 @@ local rightskip = register_nut(new_nut("glue",skipcodes.rightskip)) local temp = register_nut(new_nut("temp",0)) local noad = register_nut(new_nut("noad")) +local delimiter = register_nut(new_nut("delim")) +local fence = register_nut(new_nut("fence")) +local submlist = register_nut(new_nut("sub_mlist")) +local accent = register_nut(new_nut("accent")) +local radical = register_nut(new_nut("radical")) +local fraction = register_nut(new_nut("fraction")) +local subbox = register_nut(new_nut("sub_box")) +local mathchar = register_nut(new_nut("math_char")) +local mathtextchar = register_nut(new_nut("math_text_char")) +local choice = register_nut(new_nut("choice")) local boundary = register_nut(new_nut("boundary",boundarycodes.user)) local wordboundary = register_nut(new_nut("boundary",boundarycodes.word)) @@ -378,7 +388,6 @@ function nutpool.leader(width,list) return n end - function nutpool.latelua(code) local n = copy_nut(latelua) setfield(n,"string",code) @@ -421,9 +430,20 @@ function nutpool.temp() return copy_nut(temp) end -function nutpool.noad() - return copy_nut(noad) -end +function nutpool.noad() return copy_nut(noad) end +function nutpool.delimiter() return copy_nut(delimiter) end +function nutpool.fence() return copy_nut(fence) end +function nutpool.submlist() return copy_nut(submlist) end +function nutpool.noad() return copy_nut(noad) end +function nutpool.delimiter() return copy_nut(delim) end nutpool.delim = nutpool.delimiter +function nutpool.fence() return copy_nut(fence) end +function nutpool.accent() return copy_nut(accent) end +function nutpool.radical() return copy_nut(radical) end +function nutpool.fraction() return copy_nut(fraction) end +function nutpool.subbox() return copy_nut(subbox) end +function nutpool.mathchar() return copy_nut(mathchar) end +function nutpool.mathtextchar() return copy_nut(mathtextchar) end +function nutpool.choice() return copy_nut(choice) end local function new_hlist(list,width,height,depth,shift) local n = copy_nut(hlist) diff --git a/tex/context/base/mkiv/node-rul.lua b/tex/context/base/mkiv/node-rul.lua index b6cb9c167..316c3fded 100644 --- a/tex/context/base/mkiv/node-rul.lua +++ b/tex/context/base/mkiv/node-rul.lua @@ -128,13 +128,16 @@ local rules = nodes.rules or { } nodes.rules = rules rules.data = rules.data or { } +local nutrules = nuts.rules or { } +nuts.rules = nutrules -- not that many + storage.register("nodes/rules/data", rules.data, "nodes.rules.data") local data = rules.data -- we implement user rules here as it takes less code this way -local function userrule(t,noattributes) +local function usernutrule(t,noattributes) local r = new_userrule(t.width or 0,t.height or 0,t.depth or 0) if noattributes == false or noattributes == nil then -- avoid fuzzy ones @@ -142,7 +145,13 @@ local function userrule(t,noattributes) setattrlist(r,current_attr()) end properties[r] = t - return tonode(r) + return r +end + +nutrules.userrule = usernutrule + +local function userrule(t,noattributes) + return tonode(usernutrule(t,noattributes)) end rules.userrule = userrule diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex a233248a0..8d30534bd 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 52156f07e..7a271febb 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi index 5e31a2714..4323b70da 100644 --- a/tex/context/base/mkiv/strc-flt.mkvi +++ b/tex/context/base/mkiv/strc-flt.mkvi @@ -540,7 +540,7 @@ \def\strc_floats_place_indeed[#location][#reference]#caption% {\strc_floats_reset_variables - \edef\floatlocation{#location}% + \edef\floatlocation{\ifexporting\v!here\else#location\fi}% \ifx\floatlocation\empty \edef\floatlocation{\floatparameter\c!default}% beware of a clash between alignment locations \fi @@ -592,7 +592,7 @@ \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}% \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}% \def\m_strc_floats_saved_userdata{#2}% - \edef\floatlocation{\floatcaptionparameter\c!location}% + \edef\floatlocation{\ifexporting\v!here\else\floatcaptionparameter\c!location\fi}% \setfloatcaptionparameter\c!location{\savedfloatlocation}% not expanded \ifx\floatlocation\empty \edef\floatlocation{\floatparameter\c!default}% @@ -1097,6 +1097,7 @@ % already be set at this point \processcommacommand[\floatlocation]\strc_floats_check_extra_actions_step \ifx\extrafloatlocation\empty \else + % maybe not when exporting \edef\floatlocation{\extrafloatlocation,\floatlocation}% \setfloatmethodvariables\floatlocation \fi}} @@ -1246,7 +1247,7 @@ \global\floatwidth \wd\floatbox \global\floatheight \ht\floatbox % forget about the depth \global\floattextwidth\dimexpr\hsize-\floatwidth-\rootfloatparameter\c!margin\relax - \edef\floatlocation{\floatlocationmethod}% to be sure .. why + \edef\floatlocation{\ifexporting\v!here\else\floatlocationmethod\fi}% to be sure .. why \doifelseinset\v!tall\floatlocationmethod {\floattextheight\dimexpr\pagegoal-\pagetotal-\bigskipamount\relax % ugly, this bigskip \ifdim\floattextheight>\textheight diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv index b0771b475..af8ba5ba1 100644 --- a/tex/context/base/mkiv/strc-sec.mkiv +++ b/tex/context/base/mkiv/strc-sec.mkiv @@ -852,6 +852,7 @@ \strc_sectioning_before_yes \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report + \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchonization \let\getheadtitle\fullheadtitle \ifconditional\headshownumber @@ -860,18 +861,23 @@ \else \strc_rendering_place_head_text \fi + \dostoptagged \strc_sectioning_after_yes \else\ifconditional\c_strc_sectioning_hidden \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report + \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchonization \strc_rendering_place_head_hidden % only something when tracing + \dostoptagged \else \strc_sectioning_before_nop % toegevoegd ivm subpaginanr / tug sheets \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report + \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchonization \strc_rendering_place_head_empty % just flush 'm + \dostoptagged \strc_sectioning_after_nop \fi\fi \else @@ -879,22 +885,28 @@ \strc_sectioning_before_yes \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report + \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchonization \let\getheadtitle\fullheadtitle \strc_rendering_place_head_text + \dostoptagged \strc_sectioning_after_yes \else\ifconditional\c_strc_sectioning_hidden \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \let\getheadsyncs\theheadsynchonization + \dostarttagged\t!sectioncaption\empty \strc_rendering_place_head_hidden % only something when tracing + \dostoptagged \else % do nothing / should be vbox to 0pt \strc_sectioning_before_nop \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report + \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchonization \strc_rendering_place_head_empty % just flush 'm + \dostoptagged \strc_sectioning_after_nop \fi\fi \fi diff --git a/tex/context/base/mkiv/strc-syn.mkiv b/tex/context/base/mkiv/strc-syn.mkiv index 72c94d069..75001be27 100644 --- a/tex/context/base/mkiv/strc-syn.mkiv +++ b/tex/context/base/mkiv/strc-syn.mkiv @@ -335,14 +335,16 @@ [\c!alternative=\v!normal] \unexpanded\def\strc_synonyms_insert_meaning#1#2% name tag - {\begingroup + {\dontleavehmode % otherwise we don't get it right at the beginning of a par + \begingroup \def\currentsimplelist{#1}% \def\currentsynonymtag{#2}% \fastsetup{\??simplelistrenderings::\v!text}% \endgroup} \unexpanded\def\strc_synonyms_insert#1#2% name tag - {\begingroup + {\dontleavehmode % otherwise we don't get it right at the beginning of a par + \begingroup \edef\currentsimplelist{#1}% \let \currentsynonym\currentsimplelist % for a while \def \currentsynonymtag{#2}% @@ -549,7 +551,8 @@ [\c!alternative=\v!normal] \unexpanded\def\strc_sorting_insert#1#2% name tag - {\begingroup + {\dontleavehmode % otherwise we don't get it right at the beginning of a par + \begingroup % no kap currently, of .. we need to map cap onto WORD \edef\currentsorting{#1}% \def \currentsortingtag{#2}% diff --git a/tex/context/base/mkiv/strc-tag.lua b/tex/context/base/mkiv/strc-tag.lua index 9d1fec33e..1be44821e 100644 --- a/tex/context/base/mkiv/strc-tag.lua +++ b/tex/context/base/mkiv/strc-tag.lua @@ -60,7 +60,7 @@ tags.specifications = specifications local p_splitter = C((1-S(">"))^1) * P(">") * C(P(1)^1) tagpatterns.splitter = p_splitter -local properties = allocate { +local properties = allocate { -- todo: more "record = true" to improve formatting document = { pdf = "Div", nature = "display" }, @@ -71,6 +71,7 @@ local properties = allocate { highlight = { pdf = "Span", nature = "inline" }, section = { pdf = "Sect", nature = "display" }, + sectioncaption = { pdf = "Div", nature = "display", record = true }, sectiontitle = { pdf = "H", nature = "mixed" }, sectionnumber = { pdf = "H", nature = "mixed" }, sectioncontent = { pdf = "Div", nature = "display" }, @@ -282,6 +283,10 @@ function tags.registermetadata(data) end end +function tags.getmetadata() + return documentdata or { } +end + function tags.start(tag,specification) if not enabled then codeinjections.enabletags() diff --git a/tex/context/base/mkiv/strc-tag.mkiv b/tex/context/base/mkiv/strc-tag.mkiv index 7fdfd7afa..34fef5f50 100644 --- a/tex/context/base/mkiv/strc-tag.mkiv +++ b/tex/context/base/mkiv/strc-tag.mkiv @@ -32,6 +32,7 @@ \def\t!highlight {highlight} % Span \def\t!section {section} % Sect +\def\t!sectioncaption {sectioncaption} % Div \def\t!sectiontitle {sectiontitle} % H \def\t!sectionnumber {sectionnumber} % H \def\t!sectioncontent {sectioncontent} % Div diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv index b21771009..006edd9a1 100644 --- a/tex/context/base/mkiv/tabl-tbl.mkiv +++ b/tex/context/base/mkiv/tabl-tbl.mkiv @@ -216,6 +216,7 @@ \newconstant \c_tabl_tabulate_pass \newconstant \c_tabl_tabulate_type +\newconstant \c_tabl_tabulate_kind % 1=strong 2=equals \newconstant \c_tabl_tabulate_splitlinemode \c_tabl_tabulate_splitlinemode\plusone \newconstant \c_tabl_tabulate_colorspan \newconstant \c_tabl_tabulate_localcolorspan @@ -262,12 +263,6 @@ \expandafter\tabl_tabulate_initialize_boxes_step \fi} -% \def\tabl_tabulate_initialize_box#1% also used elsewhere -% {\ifcsname\??tabulatebox\number#1\endcsname -% \tabl_tabulate_initialize_box_yes#1% -% \else -% \tabl_tabulate_initialize_box_nop#1% -% \fi} \def\tabl_tabulate_initialize_box#1% also used elsewhere {\ifcsname\??tabulatebox\number#1\endcsname \tabl_tabulate_initialize_box_yes @@ -275,7 +270,6 @@ \tabl_tabulate_initialize_box_nop#1% \fi} -%def\tabl_tabulate_initialize_box_yes#1{\global \setbox\csname\??tabulatebox\number#1\endcsname\emptybox} \def\tabl_tabulate_initialize_box_yes {\global \setbox\lastnamedcs\emptybox} \def\tabl_tabulate_initialize_box_nop#1{\expandafter\newbox\csname\??tabulatebox\number#1\endcsname} @@ -1346,7 +1340,13 @@ \tabl_tabulate_process} \def\tabulateEQ - {\ifconditional\c_tabl_tabulate_firstflushed\else\tabulationparameter{EQ}\fi + {\ifconditional\c_tabl_tabulate_firstflushed\else + \dostarttaggedchained\t!ignore\empty\empty + \dostarttagged\t!ignore\empty + \tabulationparameter{EQ}% + \dostoptagged + \dostoptagged + \fi \global\setfalse\c_tabl_tabulate_equal} % The next ones will be token registers @@ -1420,43 +1420,46 @@ \doifelsefastoptionalcheck{\tabl_tabulate_set_color_column_yes#1}{\tabl_tabulate_set_color_column_nop#1}} \def\tabl_tabulate_set_color_column_nop - {\tabl_tabulate_column_normal} + {\tabl_tabulate_column_normal\zerocount} \def\tabl_tabulate_set_color_column_yes#1[#2]% {\xdef\m_tabl_tabulate_color_local{#2}% - \tabl_tabulate_column_normal#1} + \tabl_tabulate_column_normal\zerocount#1} % normal columns: -\def\tabl_tabulate_column_normal#1% +\def\tabl_tabulate_column_normal#1#2% {\unskip \aligntab \ifconditional\c_tabl_tabulate_equal\tabulateequalpos\else\tabulatenormalpos\fi \aligntab - \global\c_tabl_tabulate_type#1% + \global\c_tabl_tabulate_kind#1% + \global\c_tabl_tabulate_type#2% \aligntab} % equal columns -\def\tabl_tabulate_column_equal#1% +\def\tabl_tabulate_column_equal#1#2% {\unskip \aligntab \tabulateequalpos - \aligntab\global\c_tabl_tabulate_type#1% + \aligntab + \global\c_tabl_tabulate_kind#1% + \global\c_tabl_tabulate_type#2% \aligntab} % ruled columns -\def\tabl_tabulate_column_vruled#1% +\def\tabl_tabulate_column_vruled#1#2% {\unskip % 0-n -% \ifnum\c_tabl_tabulate_column=\plusone -% \global\c_tabl_tabulate_has_rule_spec_first\plusone -% \else\ifnum\c_tabl_tabulate_column=\c_tabl_tabulate_nofcolumns -% \global\c_tabl_tabulate_has_rule_spec_last\plusone -% \fi\fi + %\ifnum\c_tabl_tabulate_column=\plusone + % \global\c_tabl_tabulate_has_rule_spec_first\plusone + %\else\ifnum\c_tabl_tabulate_column=\c_tabl_tabulate_nofcolumns + % \global\c_tabl_tabulate_has_rule_spec_last\plusone + %\fi\fi \global\let\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default \global\d_tabl_tabulate_vrulethickness_local\d_tabl_tabulate_vrulethickness_default - \doifelsefastoptionalcheck{\tabl_tabulate_column_vruled_yes#1}{\tabl_tabulate_column_vruled_nop#1}} + \doifelsefastoptionalcheck{\tabl_tabulate_column_vruled_yes#1#2}{\tabl_tabulate_column_vruled_nop#1#2}} \def\tabl_tabulate_column_vruled_nop {\tabl_tabulate_column_normal} @@ -1466,9 +1469,9 @@ {\global\d_tabl_tabulate_vrulethickness_local#1\d_tabl_tabulate_vrulethickness_default} {\xdef\m_tabl_tabulate_vrule_color_local{#1}}} -\def\tabl_tabulate_column_vruled_yes#1[#2]% - {\rawprocesscommalist[#2]\tabl_tabulate_column_vruled_step - \tabl_tabulate_column_normal#1} +\def\tabl_tabulate_column_vruled_yes#1#2[#3]% + {\rawprocesscommalist[#3]\tabl_tabulate_column_vruled_step + \tabl_tabulate_column_normal#1#2} \def\tabl_tabulate_column_vruled_normal {\vrule\s!width\d_tabl_tabulate_vrulethickness\relax} @@ -1506,7 +1509,7 @@ % auto columns \def\tabl_tabulate_column_inject_auto - {\tabl_tabulate_column_normal\zerocount + {\tabl_tabulate_column_normal\zerocount\zerocount \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_columns\relax \expandafter\NR \else @@ -1802,22 +1805,22 @@ % so far -\unexpanded\def\tabl_tabulate_VL_first{\tabl_tabulate_column_vruled\zerocount} -\unexpanded\def\tabl_tabulate_NC_first{\tabl_tabulate_column_normal\zerocount} -\unexpanded\def\tabl_tabulate_RC_first{\tabl_tabulate_column_normal\plusone} -\unexpanded\def\tabl_tabulate_HC_first{\tabl_tabulate_column_normal\plustwo} -\unexpanded\def\tabl_tabulate_EQ_first{\tabl_tabulate_column_equal \zerocount} -\unexpanded\def\tabl_tabulate_RQ_first{\tabl_tabulate_column_equal \plusone} -\unexpanded\def\tabl_tabulate_HQ_first{\tabl_tabulate_column_equal \plustwo} +\unexpanded\def\tabl_tabulate_VL_first{\tabl_tabulate_column_vruled\zerocount\zerocount} +\unexpanded\def\tabl_tabulate_NC_first{\tabl_tabulate_column_normal\zerocount\zerocount} +\unexpanded\def\tabl_tabulate_RC_first{\tabl_tabulate_column_normal\zerocount\plusone} +\unexpanded\def\tabl_tabulate_HC_first{\tabl_tabulate_column_normal\zerocount\plustwo} +\unexpanded\def\tabl_tabulate_EQ_first{\tabl_tabulate_column_equal \plustwo \zerocount} +\unexpanded\def\tabl_tabulate_RQ_first{\tabl_tabulate_column_equal \zerocount\plusone} +\unexpanded\def\tabl_tabulate_HQ_first{\tabl_tabulate_column_equal \zerocount\plustwo} %unexpanded\def\tabl_tabulate_NG_first{\NC\tabl_tabulate_charalign} %unexpanded\def\tabl_tabulate_NG_first{\NC} %unexpanded\def\tabl_tabulate_NN_first{\NC\tabl_tabulate_digits} % new, undocumented, test first %unexpanded\def\tabl_tabulate_ND_first{\NC\tabl_tabulate_digits} % same, for old times sake -\unexpanded\def\tabl_tabulate_NG_first{\tabl_tabulate_column_normal\zerocount} -\unexpanded\def\tabl_tabulate_NN_first{\tabl_tabulate_column_normal\zerocount\tabl_tabulate_digits} % new, undocumented, test first -\unexpanded\def\tabl_tabulate_ND_first{\tabl_tabulate_column_normal\zerocount\tabl_tabulate_digits} % same, for old times sake +\unexpanded\def\tabl_tabulate_NG_first{\tabl_tabulate_column_normal\zerocount\zerocount} +\unexpanded\def\tabl_tabulate_NN_first{\tabl_tabulate_column_normal\zerocount\zerocount\tabl_tabulate_digits} % new, undocumented, test first +\unexpanded\def\tabl_tabulate_ND_first{\tabl_tabulate_column_normal\zerocount\zerocount\tabl_tabulate_digits} % same, for old times sake \unexpanded\def\tabl_tabulate_NR_first {\tabl_tabulate_NR_common\conditionaltrue \tabl_tabulate_check_penalties} % next row \unexpanded\def\tabl_tabulate_NB_first {\tabl_tabulate_NR_common\conditionaltrue \tabl_tabulate_nobreak_inject } % next row no break @@ -1833,7 +1836,11 @@ %D The following shortcut is handy for tables where one needs bold headers: %unexpanded\def\tabl_tabulate_BC_first{\NC\let\fontstyle\globalfontstyle\bf} -\unexpanded\def\tabl_tabulate_BC_first{\tabl_tabulate_column_normal\zerocount\let\fontstyle\globalfontstyle\bf} + +\unexpanded\def\tabl_tabulate_BC_first + {\tabl_tabulate_column_normal\plusone\zerocount + \let\fontstyle\globalfontstyle + \bf} \appendtoks \let\VL\tabl_tabulate_VL_first diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua index 38bad03e2..d53b1191a 100644 --- a/tex/context/base/mkiv/trac-vis.lua +++ b/tex/context/base/mkiv/trac-vis.lua @@ -115,6 +115,8 @@ local hpack_string = nuts.typesetters.tohpack local texgetattribute = tex.getattribute local texsetattribute = tex.setattribute +local setmetatableindex = table.setmetatableindex + local unsetvalue = attributes.unsetvalue local current_font = font.current @@ -214,6 +216,8 @@ end -- we can preset a bunch of bits +local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule") + local function enable() if not usedfont then -- we use a narrow monospaced font -- infofont ? @@ -250,6 +254,10 @@ local function enable() report_visualize("enabled") enabled = true tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end + -- + if not userrule then + userrule = nuts.rules.userrule + end end local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in @@ -303,14 +311,49 @@ function nuts.setvisuals(n,mode) setattr(n,a_visual,setvisual(mode,getattr(n,a_visual),true,true)) end -function nuts.applyvisuals(n,mode) +-- fast setters + +do + + local cached = setmetatableindex(function(t,k) + if k == true then + return texgetattribute(a_visual) + elseif not k then + t[k] = unsetvalue + return unsetvalue + else + local v = setvisual(k) + t[k] = v + return v + end + end) + + -- local function applyvisuals(n,mode) + -- local a = cached[mode] + -- apply_to_nodes(n,function(n) setattr(n,a_visual,a) end) + -- end + local a = unsetvalue - if mode == true then - a = texgetattribute (a_visual) - elseif mode then - a = setvisual(mode) + + local f = function(n) setattr(n,a_visual,a) end + + local function applyvisuals(n,mode) + a = cached[mode] + apply_to_nodes(n,f) + end + + nuts.applyvisuals = applyvisuals + + function nodes.applyvisuals(n,mode) + applyvisuals(tonut(n),mode) end - apply_to_nodes(n,function(n) setattr(n,a_visual,a) end) + + function visualizers.attribute(mode) + return cached[mode] + end + + visualizers.attributes = cached + end function nuts.copyvisual(n,m) @@ -401,7 +444,7 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb return info, width end -local caches = table.setmetatableindex("table") +local caches = setmetatableindex("table") local fontkern do @@ -624,7 +667,7 @@ local ruledbox do local b_cache = caches["box"] local o_cache = caches["origin"] - table.setmetatableindex(o_cache,function(t,size) + setmetatableindex(o_cache,function(t,size) local rule = new_rule(2*size,size,size) local origin = hpack_nodes(rule) setcolor(rule,c_origin_d) @@ -649,29 +692,29 @@ local ruledbox do local linewidth = emwidth/fraction local size = 2*linewidth local baseline, baseskip - if dp ~= 0 and ht ~= 0 then - if wd > 20*linewidth then - local targetsize = wd - size - baseline = b_cache[targetsize] - if not baseline then - -- due to an optimized leader color/transparency we need to set the glue node in order - -- to trigger this mechanism - local leader = setlink(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size)) - leader = hpack_nodes(leader) - baseline = new_glue(0,65536,0,2,0) - setleader(baseline,leader) - setsubtype(baseline,cleaders_code) - setlisttransparency(baseline,c_text) - baseline = hpack_nodes(baseline,targetsize) - b_cache[targetsize] = baseline - end - baseline = copy_list(baseline) - baseskip = new_kern(-wd+linewidth) - else - baseline = new_rule(wd-size,linewidth,0) - baseskip = new_kern(-wd+size) - end - end + -- if dp ~= 0 and ht ~= 0 then + -- if wd > 20*linewidth then + -- local targetsize = wd - size + -- baseline = b_cache[targetsize] + -- if not baseline then + -- -- due to an optimized leader color/transparency we need to set the glue node in order + -- -- to trigger this mechanism + -- local leader = setlink(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size)) + -- leader = hpack_nodes(leader) + -- baseline = new_glue(0,65536,0,2,0) + -- setleader(baseline,leader) + -- setsubtype(baseline,cleaders_code) + -- setlisttransparency(baseline,c_text) + -- baseline = hpack_nodes(baseline,targetsize) + -- b_cache[targetsize] = baseline + -- end + -- baseline = copy_list(baseline) + -- baseskip = new_kern(-wd+linewidth) + -- else + -- baseline = new_rule(wd-size,linewidth,0) + -- baseskip = new_kern(-wd+size) + -- end + -- end local this if not simple then this = b_cache[what] @@ -684,16 +727,31 @@ local ruledbox do end end -- we need to trigger the right mode (else sometimes no whatits) + -- local info = setlink( + -- this and copy_list(this) or nil, + -- new_rule(linewidth,ht,dp), + -- new_rule(wd-size,-dp+linewidth,dp), + -- new_rule(linewidth,ht,dp), + -- new_kern(-wd+linewidth), + -- new_rule(wd-size,ht,-ht+linewidth), + -- baseskip, + -- baseskip and baseline or nil + -- ) + -- + -- userrules: + -- local info = setlink( this and copy_list(this) or nil, - new_rule(linewidth,ht,dp), - new_rule(wd-size,-dp+linewidth,dp), - new_rule(linewidth,ht,dp), - new_kern(-wd+linewidth), - new_rule(wd-size,ht,-ht+linewidth), - baseskip, - baseskip and baseline or nil + userrule { + width = wd, + height = ht, + depth = dp, + line = linewidth, + type = "box", + dashed = 3*size, + } ) + -- setlisttransparency(info,c_text) info = new_hlist(info) -- @@ -763,6 +821,10 @@ end local ruledglyph do + -- see boundingbox feature .. maybe a pdf stream is more efficient, after all we + -- have a frozen color anyway or i need a more detailed cache .. below is a more + -- texie approach + ruledglyph = function(head,current,previous) -- wrong for vertical glyphs local wd = getwidth(current) -- local wd = chardata[getfont(current)][getchar(current)].width @@ -777,21 +839,53 @@ local ruledglyph do setboth(current) local linewidth = emwidth/(2*fraction) local baseline - -- if dp ~= 0 and ht ~= 0 then - if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then - baseline = new_rule(wd-2*linewidth,linewidth,0) - end - local doublelinewidth = 2*linewidth - -- could be a pdf rule (or a user rule now) - local info = setlink( - new_rule(linewidth,ht,dp), - new_rule(wd-doublelinewidth,-dp+linewidth,dp), - new_rule(linewidth,ht,dp), - new_kern(-wd+linewidth), - new_rule(wd-doublelinewidth,ht,-ht+linewidth), - new_kern(-wd+doublelinewidth), - baseline + local info + -- + -- original + -- + -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then + -- baseline = new_rule(wd-2*linewidth,linewidth,0) + -- end + -- local doublelinewidth = 2*linewidth + -- -- could be a pdf rule (or a user rule now) + -- info = setlink( + -- new_rule(linewidth,ht,dp), + -- new_rule(wd-doublelinewidth,-dp+linewidth,dp), + -- new_rule(linewidth,ht,dp), + -- new_kern(-wd+linewidth), + -- new_rule(wd-doublelinewidth,ht,-ht+linewidth), + -- new_kern(-wd+doublelinewidth), + -- baseline + -- ) + -- + -- experiment with subtype outline + -- + -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then + -- baseline = new_rule(wd,linewidth/2,0) + -- end + -- local r = new_rule(wd-linewidth,ht-linewidth/4,dp-linewidth/4) + -- setsubtype(r,nodes.rulecodes.outline) + -- setfield(r,"transform",linewidth) + -- info = setlink( + -- new_kern(linewidth/4), + -- r, + -- new_kern(-wd+linewidth/2), + -- baseline + -- ) + -- + -- userrules: + -- + info = setlink( + userrule { + width = wd, + height = ht, + depth = dp, + line = linewidth, + type = "box", + }, + new_kern(-wd) ) + -- local char = chardata[getfont(current)][getchar(current)] if char and type(char.unicode) == "table" then -- hackery test setlistcolor(info,c_ligature) @@ -821,6 +915,10 @@ local ruledglyph do end end + function visualizers.setruledglyph(f) + ruledglyph = f or ruledglyph + end + end local ruledglue do diff --git a/tex/context/base/mkiv/util-sta.lua b/tex/context/base/mkiv/util-sta.lua index 27ab5a624..614ef567e 100644 --- a/tex/context/base/mkiv/util-sta.lua +++ b/tex/context/base/mkiv/util-sta.lua @@ -289,24 +289,24 @@ end -- -- local concat = table.concat -- --- local pdfliteral = nodes.pool.pdfliteral +-- local pdfpageliteral = nodes.pool.pdfpageliteral -- -- function demostacker.start(s,t,first,last) -- local n = whatever[t[last]] -- -- s.report("start: %s",n) --- return pdfliteral(n) +-- return pdfpageliteral(n) -- end -- -- function demostacker.stop(s,t,first,last) -- local n = whatever[false] -- -- s.report("stop: %s",n) --- return pdfliteral(n) +-- return pdfpageliteral(n) -- end -- -- function demostacker.change(s,t1,first1,last1,t2,first2,last2) -- local n = whatever[t2[last2]] -- -- s.report("change: %s",n) --- return pdfliteral(n) +-- return pdfpageliteral(n) -- end -- -- demostacker.mode = "switch" @@ -325,7 +325,7 @@ end -- r[#r+1] = whatever[t[i]] -- end -- -- s.report("start: %s",concat(r," ")) --- return pdfliteral(concat(r," ")) +-- return pdfpageliteral(concat(r," ")) -- end -- -- function demostacker.stop(s,t,first,last) @@ -334,7 +334,7 @@ end -- r[#r+1] = whatever[false] -- end -- -- s.report("stop: %s",concat(r," ")) --- return pdfliteral(concat(r," ")) +-- return pdfpageliteral(concat(r," ")) -- end -- -- function demostacker.change(s,t1,first1,last1,t2,first2,last2) @@ -346,7 +346,7 @@ end -- r[#r+1] = whatever[t2[i]] -- end -- -- s.report("change: %s",concat(r," ")) --- return pdfliteral(concat(r," ")) +-- return pdfpageliteral(concat(r," ")) -- end -- -- demostacker.mode = "stack" diff --git a/tex/context/fonts/mkiv/lm.lfg b/tex/context/fonts/mkiv/lm.lfg index aebedd01b..ec37a2975 100644 --- a/tex/context/fonts/mkiv/lm.lfg +++ b/tex/context/fonts/mkiv/lm.lfg @@ -34,6 +34,8 @@ return { height = 960, depth = 40, }, + -- [0xFE932] = { xoffset = 50, width = 290 }, -- used prime + -- [0x2032] = { xoffset = 50, width = 290 }, -- prime }, signs = { -- set dimensions diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index 86d6868b4..0df2eba36 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -693,6 +693,7 @@ <cd:constant name='bottomoffset' value='offsetfondo'/> <cd:constant name='bottomspace' value='spaziofondo'/> <cd:constant name='bottomstate' value='statofondo'/> + <cd:constant name='break' value='break'/> <cd:constant name='buffer' value='buffer'/> <cd:constant name='cache' value='cache'/> <cd:constant name='calculate' value='calcola'/> diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 2cc4b4461..69d91f3b8 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex 90c08a129..11502611e 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/generic/context/luatex/luatex-fonts-ext.lua b/tex/generic/context/luatex/luatex-fonts-ext.lua index 7d9c58ccb..15762d9ba 100644 --- a/tex/generic/context/luatex/luatex-fonts-ext.lua +++ b/tex/generic/context/luatex/luatex-fonts-ext.lua @@ -13,6 +13,7 @@ end local fonts = fonts local otffeatures = fonts.constructors.features.otf +local getprivate = fonts.constructors.getprivate -- A few generic extensions. @@ -290,15 +291,13 @@ local setmetatableindex = table.setmetatableindex local function additalictowidth(tfmdata,key,value) local characters = tfmdata.characters - local resources = tfmdata.resources local additions = { } - local private = resources.private for unicode, old_c in next, characters do -- maybe check for math local oldwidth = old_c.width local olditalic = old_c.italic if olditalic and olditalic ~= 0 then - private = private + 1 + local private = getprivate(tfmdata) local new_c = { width = oldwidth + olditalic, height = old_c.height, @@ -316,7 +315,6 @@ local function additalictowidth(tfmdata,key,value) for k, v in next, additions do characters[k] = v end - resources.private = private end otffeatures.register { diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index a8a7889ca..f2d897b64 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/17/17 00:20:46 +-- merge date : 07/27/17 16:17:50 do -- begin closure to overcome local limits and interference @@ -7623,6 +7623,12 @@ function constructors.scaled(scaledpoints,designsize) return scaledpoints end end +function constructors.getprivate(tfmdata) + local properties=tfmdata.properties + local private=properties.private + properties.private=private+1 + return private +end function constructors.cleanuptable(tfmdata) if constructors.autocleanup and tfmdata.properties.virtualized then for k,v in next,tfmdata.characters do @@ -15556,7 +15562,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly if first or second then hash[other]={ first,second or nil } else - hash[other]=nil + hash[other]=nil end end end @@ -17351,7 +17357,7 @@ local f_index=formatters["I%05X"] local f_character_y=formatters["%C"] local f_character_n=formatters["[ %C ]"] local check_duplicates=true -local check_soft_hyphen=false +local check_soft_hyphen=true directives.register("otf.checksofthyphen",function(v) check_soft_hyphen=v end) @@ -17911,7 +17917,6 @@ local function unifymissing(fontdata) require("font-agl") end local unicodes={} - local private=fontdata.private local resources=fontdata.resources resources.unicodes=unicodes for unicode,d in next,fontdata.descriptions do @@ -19259,62 +19264,73 @@ end local function checkkerns(lookup) local steps=lookup.steps local nofsteps=lookup.nofsteps + local kerned=0 for i=1,nofsteps do local step=steps[i] if step.format=="pair" then local coverage=step.coverage local kerns=true for g1,d1 in next,coverage do - if d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then + if d1==true then + elseif not d1 then + elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then kerns=false break end end if kerns then report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + local c={} for g1,d1 in next,coverage do - coverage[g1]=d1[3] + if d1 and d1~=true then + c[g1]=d1[3] + end end + step.coverage=c step.format="kern" + kerned=kerned+1 end end end + return kerned end local function checkpairs(lookup) local steps=lookup.steps local nofsteps=lookup.nofsteps local kerned=0 - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=step.coverage - local kerns=true - for g1,d1 in next,coverage do - for g2,d2 in next,d1 do - if d2[2] then - kerns=false - break - else - local v=d2[1] - if v==true then - elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then - kerns=false - break - end + local function onlykerns(step) + local coverage=step.coverage + for g1,d1 in next,coverage do + for g2,d2 in next,d1 do + if d2[2] then + return false + else + local v=d2[1] + if v==true then + elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then + return false end end end - if kerns then + end + return coverage + end + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=onlykerns(step) + if coverage then report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) for g1,d1 in next,coverage do + local d={} for g2,d2 in next,d1 do local v=d2[1] if v==true then - d1[g2]=nil elseif v then - d1[g2]=v[3] + d[g2]=v[3] end end + coverage[g1]=d end step.format="kern" kerned=kerned+1 @@ -19339,9 +19355,9 @@ function readers.compact(data) for i=1,#lookups do local lookup=lookups[i] local nofsteps=lookup.nofsteps + local kind=lookup.type allsteps=allsteps+nofsteps if nofsteps>1 then - local kind=lookup.type local merg=merged if kind=="gsub_single" or kind=="gsub_alternate" or kind=="gsub_multiple" then merged=merged+mergesteps_1(lookup) @@ -19349,7 +19365,7 @@ function readers.compact(data) merged=merged+mergesteps_4(lookup) elseif kind=="gpos_single" then merged=merged+mergesteps_1(lookup,true) - checkkerns(lookup) + kerned=kerned+checkkerns(lookup) elseif kind=="gpos_pair" then merged=merged+mergesteps_2(lookup,true) kerned=kerned+checkpairs(lookup) @@ -19361,6 +19377,12 @@ function readers.compact(data) if merg~=merged then lookup.merged=true end + elseif nofsteps==1 then + if kind=="gpos_single" then + kerned=kerned+checkkerns(lookup) + elseif kind=="gpos_pair" then + kerned=kerned+checkpairs(lookup) + end end end else @@ -19611,6 +19633,7 @@ local forceload=false local cleanup=0 local syncspace=true local forcenotdef=false +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes local wildcard="*" local default="dflt" @@ -19775,7 +19798,7 @@ local function copytotfm(data,cache_id) end if mathspecs then for unicode,character in next,characters do - local d=descriptions[unicode] + local d=descriptions[unicode] local m=d.math if m then local italic=m.italic @@ -19915,6 +19938,7 @@ local function copytotfm(data,cache_id) properties.fullname=fullname properties.psname=psname properties.name=filename or fullname + properties.private=properties.private or data.private or privateoffset return { characters=characters, descriptions=descriptions, @@ -20245,6 +20269,7 @@ local otf=fonts.handlers.otf local otffeatures=otf.features local registerotffeature=otffeatures.register otf.defaultbasealternate="none" +local getprivate=fonts.constructors.getprivate local wildcard="*" local default="dflt" local formatters=string.formatters @@ -20335,13 +20360,11 @@ local function registerbasefeature(feature,value) applied[#applied+1]=feature.."="..tostring(value) end local function makefake(tfmdata,name,present) - local resources=tfmdata.resources - local private=resources.private + local private=getprivate(tfmdata) local character={ intermediate=true,ligatures={} } resources.unicodes[name]=private tfmdata.characters[private]=character tfmdata.descriptions[private]={ name=name } - resources.private=private+1 present[name]=private return character end @@ -25879,9 +25902,6 @@ do end function otf.featuresprocessor(head,font,attr,direction,n) local sequences=sequencelists[font] - if not sequencelists then - return head,false - end nesting=nesting+1 if nesting==1 then currentfont=font @@ -26115,6 +26135,77 @@ do head=tonode(head) return head,done end + function otf.datasetpositionprocessor(head,font,direction,dataset) + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if type(dataset)=="number" then + dataset=otfdataset(tfmdata,font,0)[dataset] + end + local sequence=dataset[3] + local typ=sequence.type + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local head=tonut(head) + local done=false + local dirstack={} + local start=head + local initialrl=direction=="TRT" and -1 or 0 + local rlmode=initialrl + local rlparmode=initialrl + local topstack=0 + local merged=steps.merged + local position=0 + while start do + local char,id=ischar(start,font) + if char then + position=position+1 + local m=merged[char] + if m then + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i) + if ok then + break + elseif not start then + break + end + end + end + if start then + start=getnext(start) + end + else + start=getnext(start) + end + elseif char==false then + start=getnext(start) + elseif id==glue_code then + start=getnext(start) + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + start,topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + elseif id==localpar_code then + start,rlparmode,rlmode=pardirstate(start) + else + start=getnext(start) + end + end + return tonode(head) + end end local plugins={} otf.plugins=plugins @@ -30020,6 +30111,7 @@ local report_afm=logs.reporter("fonts","afm loading") local setmetatableindex=table.setmetatableindex local derivetable=table.derive local findbinfile=resolvers.findbinfile +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 local definers=fonts.definers local readers=fonts.readers local constructors=fonts.constructors @@ -30090,7 +30182,7 @@ local function enhance_unify_names(data,filename) local unicodevector=fonts.encodings.agl.unicodes local unicodes={} local names={} - local private=constructors.privateoffset + local private=data.private or privateoffset local descriptions=data.descriptions for name,blob in next,data.characters do local code=unicodevector[name] @@ -30129,12 +30221,12 @@ local function enhance_unify_names(data,filename) end end data.characters=nil + data.private=private local resources=data.resources local filename=resources.filename or file.removesuffix(file.basename(filename)) resources.filename=resolvers.unresolve(filename) resources.unicodes=unicodes resources.marks={} - resources.private=private end local everywhere={ ["*"]={ ["*"]=true } } local noflags={ false,false,false,false } @@ -30488,6 +30580,7 @@ local function copytotfm(data) properties.fullname=fullname properties.psname=fullname properties.name=filename or fullname or fontname + properties.private=properties.private or data.private or privateoffset if next(characters) then return { characters=characters, @@ -30990,6 +31083,7 @@ local function read_from_tfm(specification) parameters.quad=parameters.quad or parameters[6] or 0 parameters.extra_space=parameters.extra_space or parameters[7] or 0 constructors.enhanceparameters(parameters) + properties.private=properties.private or tfmdata.private or privateoffset if newtfmdata then elseif constructors.resolvevirtualtoo then fonts.loggers.register(tfmdata,file.suffix(filename),specification) @@ -31136,7 +31230,7 @@ do local originals=tfmdata.characters local indices={} local parentfont={ "font",1 } - local private=fonts.constructors.privateoffset + local private=tfmdata or fonts.constructors.privateoffset local reported=encdone[tfmfile][encfile] local backmap=vector and table.swapped(vector) local done={} @@ -31203,6 +31297,7 @@ do tfmdata.tounicode=1 tfmdata.embedding="subset" tfmdata.usedbitmap=bitmap and virtualid + tfmdata.private=private return tfmdata end end @@ -31914,6 +32009,7 @@ if context then end local fonts=fonts local otffeatures=fonts.constructors.features.otf +local getprivate=fonts.constructors.getprivate local function initializeitlc(tfmdata,value) if value then local parameters=tfmdata.parameters @@ -32131,14 +32227,12 @@ otffeatures.register { local setmetatableindex=table.setmetatableindex local function additalictowidth(tfmdata,key,value) local characters=tfmdata.characters - local resources=tfmdata.resources local additions={} - local private=resources.private for unicode,old_c in next,characters do local oldwidth=old_c.width local olditalic=old_c.italic if olditalic and olditalic~=0 then - private=private+1 + local private=getprivate(tfmdata) local new_c={ width=oldwidth+olditalic, height=old_c.height, @@ -32156,7 +32250,6 @@ local function additalictowidth(tfmdata,key,value) for k,v in next,additions do characters[k]=v end - resources.private=private end otffeatures.register { name="italicwidths", |