From 57a61e4673116076f5bbff7600e6dad376af9173 Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Mon, 11 Apr 2016 10:29:07 +0200 Subject: 2016-04-10 23:57:00 --- tex/context/base/mkiv/back-pdf.lua | 4 +- tex/context/base/mkiv/buff-ver.mkiv | 3 +- tex/context/base/mkiv/char-def.lua | 3 + tex/context/base/mkiv/char-ini.mkiv | 9 ++ tex/context/base/mkiv/char-tex.lua | 45 +++++- tex/context/base/mkiv/cont-fil.mkiv | 5 + tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context-todo.tex | 7 + tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-gbn.lua | 5 +- tex/context/base/mkiv/font-off.lua | 31 ++-- tex/context/base/mkiv/font-otr.lua | 220 ++++++++++++++++++--------- tex/context/base/mkiv/font-ots.lua | 46 ++++-- tex/context/base/mkiv/font-syn.lua | 208 +++++++++++-------------- tex/context/base/mkiv/lang-hyp.lua | 1 + tex/context/base/mkiv/lang-rep.mkiv | 2 +- tex/context/base/mkiv/lxml-tex.lua | 6 +- tex/context/base/mkiv/mtx-context-setups.tex | 78 ++++++++++ tex/context/base/mkiv/mult-ini.lua | 5 + tex/context/base/mkiv/mult-prm.lua | 7 + tex/context/base/mkiv/node-fin.lua | 8 +- tex/context/base/mkiv/node-fnt.lua | 49 ++++-- tex/context/base/mkiv/node-ini.lua | 114 ++++++++------ tex/context/base/mkiv/node-ltp.lua | 28 +++- tex/context/base/mkiv/node-res.lua | 56 +++++-- tex/context/base/mkiv/node-shp.lua | 2 +- tex/context/base/mkiv/spac-ali.mkiv | 3 +- tex/context/base/mkiv/spac-hor.mkiv | 12 +- tex/context/base/mkiv/spac-ver.mkiv | 4 +- tex/context/base/mkiv/status-files.pdf | Bin 9202 -> 9133 bytes tex/context/base/mkiv/status-lua.pdf | Bin 267502 -> 267788 bytes tex/context/base/mkiv/strc-itm.mkvi | 60 ++++++++ tex/context/base/mkiv/strc-sec.mkiv | 79 ++++++---- tex/context/base/mkiv/syst-ini.mkiv | 5 + tex/context/base/mkiv/trac-log.lua | 2 +- tex/context/base/mkiv/typo-brk.lua | 136 +++++++++++++---- tex/context/base/mkiv/typo-brk.mkiv | 20 ++- tex/context/base/mkiv/typo-itc.lua | 2 +- 38 files changed, 880 insertions(+), 389 deletions(-) create mode 100644 tex/context/base/mkiv/mtx-context-setups.tex (limited to 'tex/context/base/mkiv') diff --git a/tex/context/base/mkiv/back-pdf.lua b/tex/context/base/mkiv/back-pdf.lua index 66ca89fb4..7cc3b9148 100644 --- a/tex/context/base/mkiv/back-pdf.lua +++ b/tex/context/base/mkiv/back-pdf.lua @@ -152,13 +152,13 @@ scanners.pdfstopmirroring = scanners.pdfstartmirroring implement { name = "setmapfile", arguments = "string", - actions = pdf.setmapfile + actions = pdf.mapfile } implement { name = "setmapfile", arguments = "string", - actions = pdf.setmapline + actions = pdf.mapline } implement { diff --git a/tex/context/base/mkiv/buff-ver.mkiv b/tex/context/base/mkiv/buff-ver.mkiv index dbb675320..5b3ed6f2a 100644 --- a/tex/context/base/mkiv/buff-ver.mkiv +++ b/tex/context/base/mkiv/buff-ver.mkiv @@ -457,7 +457,8 @@ \let\normaltextdis\dis \unexpanded\def\astype - {\bgroup\usetypestyleandcolor\c!style\c!color\let\nexttoken} + {\dontleavehmode + \bgroup\usetypestyleandcolor\c!style\c!color\let\nexttoken} \unexpanded\def\asciistr#1% used in some old styles {\dontleavehmode\begingroup diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua index 0ca2fb18c..bf21be70c 100644 --- a/tex/context/base/mkiv/char-def.lua +++ b/tex/context/base/mkiv/char-def.lua @@ -2404,6 +2404,7 @@ characters.data={ adobename="germandbls", category="ll", cjkwd="a", + comment="uppercase can be 0x1E9E", contextname="ssharp", description="LATIN SMALL LETTER SHARP S", direction="l", @@ -54756,6 +54757,8 @@ characters.data={ direction="l", linebreak="al", unicodeslot=0x1E9E, + lccode=0xDF, + shcode={ 0x53, 0x53 }, }, [0x1E9F]={ category="ll", diff --git a/tex/context/base/mkiv/char-ini.mkiv b/tex/context/base/mkiv/char-ini.mkiv index 907fcff13..8f5a8da8f 100644 --- a/tex/context/base/mkiv/char-ini.mkiv +++ b/tex/context/base/mkiv/char-ini.mkiv @@ -95,4 +95,13 @@ \def\chardescription#1{\clf_chardescription#1\relax} +% experiment (watch out: this is global and very font dependent when used with +% casing mechanisms) +% +% \overloaduppercase{0xDF}{0x1E9E}} +% \overloaduppercase{0xDF}{0x53,0x53} + +\unexpanded\def\overloaduppercase{\clf_overloaduppercase} +\unexpanded\def\overloadlowercase{\clf_overloadlowercase} + \protect \endinput diff --git a/tex/context/base/mkiv/char-tex.lua b/tex/context/base/mkiv/char-tex.lua index df7433409..562f9c8b8 100644 --- a/tex/context/base/mkiv/char-tex.lua +++ b/tex/context/base/mkiv/char-tex.lua @@ -280,7 +280,7 @@ local commandmapping = allocate { ["l"] = "ł", ["L"] = "Ł", ["o"] = "ø", ["O"] = "Ø", ["oe"] = "œ", ["OE"] = "Œ", - ["sz"] = "ß", ["SZ"] = "SZ", ["ss"] = "ß", ["SS"] = "ß", + ["sz"] = "ß", ["SZ"] = "SZ", ["ss"] = "ß", ["SS"] = "ß", -- uppercase: ẞ } texcharacters.commandmapping = commandmapping @@ -777,3 +777,46 @@ end implement { name = "setlettercatcodes", scope = "private", actions = characters.setlettercatcodes, arguments = "integer" } implement { name = "setactivecatcodes", scope = "private", actions = characters.setactivecatcodes, arguments = "integer" } --------- { name = "setcharactercodes", scope = "private", actions = characters.setcodes } + +-- experiment (some can move to char-ini.lua) + +local function overload(c,u,code,codes) + local c = tonumber(c) + if not c then + return + end + local u = utilities.parsers.settings_to_array(u) + local n = #u + if n == 0 then + return + end + local t = nil + if n == 1 then + t = u[1] + else + t = { } + for i=1,n do + t[#t+1] = tonumber(u[i]) + end + end + if t then + data[c][code] = t + characters[codes][c] = nil + end +end + +interfaces.implement { + name = "overloaduppercase", + arguments = { "string", "string" }, + actions = function(c,u) + overload(c,u,"uccode","uccodes") + end +} + +interfaces.implement { + name = "overloadlowercase", + arguments = { "string", "string" }, + actions = function(c,u) + overload(c,u,"lccode","lccodes") + end +} diff --git a/tex/context/base/mkiv/cont-fil.mkiv b/tex/context/base/mkiv/cont-fil.mkiv index a1159b7f5..19c1c93ac 100644 --- a/tex/context/base/mkiv/cont-fil.mkiv +++ b/tex/context/base/mkiv/cont-fil.mkiv @@ -118,4 +118,9 @@ \definefilesynonym [fnt-23] [fonts-shapes] \definefilesynonym [syn-01] [syntax] +\definefilesynonym [set-11] [setups-basics] +\definefilesynonym [set-12] [setups-overview] +%definefilesynonym [set-13] [setups-proofing] +%definefilesynonym [set-15] [setups-generate] + \endinput diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index d553acc4c..e9e8beff1 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{2016.04.04 13:06} +\newcontextversion{2016.04.10 23:52} %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-todo.tex b/tex/context/base/mkiv/context-todo.tex index 86a5f82ce..b7ff4aeaa 100644 --- a/tex/context/base/mkiv/context-todo.tex +++ b/tex/context/base/mkiv/context-todo.tex @@ -15,6 +15,9 @@ \startitem optimize some callback resolution (more direct) \stopitem + \startitem + add \type {--output-filename} for \PDF\ filename + \stopitem \stopitemize \subsubject{\CONTEXT} @@ -29,6 +32,10 @@ \startitem redo some of the spacing (adapt to improvements in engine) \stopitem + \startitem + use \type {\matheqnogapstep}, \type {\Ustack}, \type {\mathscriptsmode} + and other new math primitives + \stopitem \stopitemize \vfill {\em Feel free to suggest additions.} diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 886ca1c63..03f1f2d0b 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.04.04 13:06} +\edef\contextversion{2016.04.10 23:52} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-gbn.lua b/tex/context/base/mkiv/font-gbn.lua index f81c877f2..a645a97e7 100644 --- a/tex/context/base/mkiv/font-gbn.lua +++ b/tex/context/base/mkiv/font-gbn.lua @@ -19,7 +19,6 @@ local nodes = nodes local nuts = nodes.nuts -- context abstraction of direct nodes local traverse_id = nuts.traverse_id -local free_node = nuts.free local remove_node = nuts.remove local glyph_code = nodes.nodecodes.glyph @@ -137,9 +136,7 @@ function nodes.handlers.nodepass(head) end if redundant then for i=1,#redundant do - local n = redundant[i] - remove_node(nuthead,n) - free_node(n) + remove_node(nuthead,redundant[i],true) end end for d in traverse_id(disc_code,nuthead) do diff --git a/tex/context/base/mkiv/font-off.lua b/tex/context/base/mkiv/font-off.lua index 5fe68dc2a..82426552e 100644 --- a/tex/context/base/mkiv/font-off.lua +++ b/tex/context/base/mkiv/font-off.lua @@ -177,21 +177,22 @@ local function get_full_info(name) local weight = names.weight or ff.weight local width = names.width -- no: ff.width local d = { - familyname = names.preffamilyname or names.family or ff.familyname, - fullname = names.fullname or ff.fullname, - fontname = ff.fontname, - subfamily = names.subfamily, - modifiers = names.prefmodifiers, - weight = weight and lower(weight), - width = width and lower(width), - italicangle = round(1000*(tonumber(ff.italicangle) or 0))/1000 or 0, - units = ff.units_per_em, - designsize = ff.design_size, - minsize = ff.design_range_bottom, - maxsize = ff.design_range_top, - pfmweight = pfminfo.weight or 400, - pfmwidth = pfminfo.width or 5, - monospaced = pfminfo.panose and pfminfo.panose.proportion == "Monospaced", + fontname = ff.fontname, + fullname = names.fullname or ff.fullname, + family = names.family, + subfamily = names.subfamily, + familyname = names.preffamilyname or names.family or ff.familyname, + subfamilyname = names.prefmodifiers or names.subfamily, + weight = weight and lower(weight), + width = width and lower(width), + italicangle = round(1000*(tonumber(ff.italicangle) or 0))/1000 or 0, + units = ff.units_per_em, + designsize = ff.design_size, + minsize = ff.design_range_bottom, + maxsize = ff.design_range_top, + pfmweight = pfminfo.weight or 400, + pfmwidth = pfminfo.width or 5, + monospaced = pfminfo.panose and pfminfo.panose.proportion == "Monospaced", } close_font(ff) return d diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 1fc338b38..0ad1e194f 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -148,7 +148,7 @@ local function reportskippedtable(tag) end -- We have quite some data tables. We are somewhat ff compatible with names but as I used --- the information form the microsoft site there can be differences. Eventually I might end +-- the information from the microsoft site there can be differences. Eventually I might end -- up with a different ordering and naming. local reservednames = { [0] = @@ -163,14 +163,14 @@ local reservednames = { [0] = "manufacturer", "designer", "description", -- descriptor in ff - "venderurl", + "vendorurl", "designerurl", "license", "licenseurl", "reserved", "typographicfamily", -- preffamilyname "typographicsubfamily", -- prefmodifiers - "compatiblefullname", -- for mac + "compatiblefullname", -- for mac "sampletext", "cidfindfontname", "wwsfamily", @@ -244,7 +244,16 @@ local decoders = { macintosh = { }, iso = { }, windows = { - ["unicode bmp"] = utf16_to_utf8_be + -- maybe always utf16 + ["unicode semantics"] = utf16_to_utf8_be, + ["unicode bmp"] = utf16_to_utf8_be, + ["unicode full"] = utf16_to_utf8_be, + ["unicode 1.0 semantics"] = utf16_to_utf8_be, + ["unicode 1.1 semantics"] = utf16_to_utf8_be, + ["unicode 2.0 bmp"] = utf16_to_utf8_be, + ["unicode 2.0 full"] = utf16_to_utf8_be, + ["unicode variation sequences"] = utf16_to_utf8_be, + ["unicode full repertoire"] = utf16_to_utf8_be, }, custom = { }, } @@ -702,7 +711,17 @@ local panosewidths = { -- useful information about what we deal with. The complication is that we need -- to filter the best one available. -function readers.name(f,fontdata) +local platformnames = { + postscriptname = true, + fullname = true, + family = true, + subfamily = true, + typographicfamily = true, + typographicsubfamily = true, + compatiblefullname = true, +} + +function readers.name(f,fontdata,specification) local datatable = fontdata.tables.name if datatable then setposition(f,datatable.offset) @@ -710,6 +729,7 @@ function readers.name(f,fontdata) local nofnames = readushort(f) local offset = readushort(f) -- we can also provide a raw list as extra, todo as option + local start = datatable.offset + offset local namelists = { unicode = { }, windows = { }, @@ -738,7 +758,7 @@ function readers.name(f,fontdata) language = language, name = name, length = readushort(f), - offset = readushort(f), + offset = start + readushort(f), } else skipshort(f,2) @@ -766,7 +786,6 @@ function readers.name(f,fontdata) -- -- we need to choose one we like, for instance an unicode one -- - local start = datatable.offset + offset local names = { } local done = { } -- @@ -783,7 +802,7 @@ function readers.name(f,fontdata) local encoding = name.encoding local language = name.language if (not e or encoding == e) and (not l or language == l) then - setposition(f,start+name.offset) + setposition(f,name.offset) local content = readstring(f,name.length) local decoder = decoders[platform] if decoder then @@ -812,11 +831,57 @@ function readers.name(f,fontdata) filter("unicode") -- fontdata.names = names + -- + if specification.platformnames then + local collected = { } + for platform, namelist in next, namelists do + local filtered = false + for i=1,#namelist do + local entry = namelist[i] + local name = entry.name + if platformnames[name] then + setposition(f,entry.offset) + local content = readstring(f,entry.length) + local encoding = entry.encoding + local decoder = decoders[platform] + if decoder then + decoder = decoder[encoding] + end + if decoder then + content = decoder(content) + end + if filtered then + filtered[name] = content + else + filtered = { [name] = content } + end + end + end + if filtered then + collected[platform] = filtered + end + end + fontdata.platformnames = collected + end else fontdata.names = { } end end +----- validutf = lpeg.patterns.utf8character^0 * P(-1) +local validutf = lpeg.patterns.validutf8 + +local function getname(fontdata,key) + local names = fontdata.names + if names then + local value = names[key] + if value then + local content = value.content + return lpegmatch(validutf,content) and content or nil + end + end +end + -- This table is an original windows (with its precursor os/2) table. In ff this one is -- part of the pfminfo table but here we keep it separate (for now). We will create a -- properties table afterwards. @@ -1733,69 +1798,69 @@ otf.unpackoutlines = unpackoutlines -- some properties in order to read following tables. When details is true we also -- initialize the glyphs data. ------ validutf = lpeg.patterns.utf8character^0 * P(-1) -local validutf = lpeg.patterns.validutf8 - -local function getname(fontdata,key) - local names = fontdata.names - if names then - local value = names[key] - if value then - local content = value.content - return lpegmatch(validutf,content) and content or nil - end - end -end - -local function getinfo(maindata,sub) +local function getinfo(maindata,sub,platformnames) local fontdata = sub and maindata.subfonts and maindata.subfonts[sub] or maindata - local names = fontdata.names + local names = fontdata.names + local info = nil if names then - local metrics = fontdata.windowsmetrics or { } - local postscript = fontdata.postscript or { } - local fontheader = fontdata.fontheader or { } - local cffinfo = fontdata.cffinfo or { } - local filename = fontdata.filename - local weight = getname(fontdata,"weight") or cffinfo.weight or metrics.weight - local width = getname(fontdata,"width") or cffinfo.width or metrics.width - return { -- we inherit some inconsistencies/choices from ff - subfontindex = fontdata.subfontindex or sub or 0, - -- filename = filename, - -- version = name("version"), - -- format = fontdata.format, - fontname = getname(fontdata,"postscriptname"), - fullname = getname(fontdata,"fullname"), -- or file.nameonly(filename) - familyname = getname(fontdata,"typographicfamily") or getname(fontdata,"family"), - subfamily = getname(fontdata,"subfamily"), - modifiers = getname(fontdata,"typographicsubfamily"), - weight = weight and lower(weight), - width = width and lower(width), - pfmweight = metrics.weightclass or 400, -- will become weightclass - pfmwidth = metrics.widthclass or 5, -- will become widthclass - panosewidth = metrics.panosewidth, - panoseweight = metrics.panoseweight, - italicangle = postscript.italicangle or 0, - units = fontheader.units or 0, - designsize = fontdata.designsize, - minsize = fontdata.minsize, - maxsize = fontdata.maxsize, - monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced", - averagewidth = metrics.averagewidth, - xheight = metrics.xheight, - ascender = metrics.typoascender, - descender = metrics.typodescender, + local metrics = fontdata.windowsmetrics or { } + local postscript = fontdata.postscript or { } + local fontheader = fontdata.fontheader or { } + local cffinfo = fontdata.cffinfo or { } + local filename = fontdata.filename + local weight = getname(fontdata,"weight") or cffinfo.weight or metrics.weight + local width = getname(fontdata,"width") or cffinfo.width or metrics.width + local fontname = getname(fontdata,"postscriptname") + local fullname = getname(fontdata,"fullname") + local family = getname(fontdata,"family") + local subfamily = getname(fontdata,"subfamily") + local familyname = getname(fontdata,"typographicfamily") or family + local subfamilyname = getname(fontdata,"typographicsubfamily") or subfamily + local compatiblename = getname(fontdata,"compatiblefullname") + info = { -- we inherit some inconsistencies/choices from ff + subfontindex = fontdata.subfontindex or sub or 0, + -- filename = filename, + version = getname(fontdata,"version"), + -- format = fontdata.format, + fontname = fontname, + fullname = fullname, + family = family, + subfamily = subfamily, + familyname = familyname, + subfamilyname = subfamilyname, + compatiblename = compatiblename, + weight = weight and lower(weight), + width = width and lower(width), + pfmweight = metrics.weightclass or 400, -- will become weightclass + pfmwidth = metrics.widthclass or 5, -- will become widthclass + panosewidth = metrics.panosewidth, + panoseweight = metrics.panoseweight, + italicangle = postscript.italicangle or 0, + units = fontheader.units or 0, + designsize = fontdata.designsize, + minsize = fontdata.minsize, + maxsize = fontdata.maxsize, + monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced", + averagewidth = metrics.averagewidth, + xheight = metrics.xheight, + capheight = metrics.capheight, -- not always present and probably crap + ascender = metrics.typoascender, + descender = metrics.typodescender, + platformnames = platformnames and fontdata.platformnames or nil, } elseif n then - return { + info = { filename = fontdata.filename, comment = "there is no info for subfont " .. n, } else - return { + info = { filename = fontdata.filename, comment = "there is no info", } end + -- inspect(info) + return info end local function loadtables(f,specification,offset) @@ -1870,6 +1935,7 @@ local function readdata(f,offset,specification) end end -- + -- readers["os/2"](f,fontdata,specification) readers["head"](f,fontdata,specification) readers["maxp"](f,fontdata,specification) @@ -1989,7 +2055,10 @@ local function loadfont(specification,n) specification.details = true end if specification.details then - specification.info = true + specification.info = true -- not really used any more + end + if specification.platformnames then + specification.platformnames = true -- not really used any more end local function message(str) report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) @@ -2043,7 +2112,7 @@ function readers.loadfont(filename,n) descriptions = fontdata.descriptions, format = fontdata.format, goodies = { }, - metadata = getinfo(fontdata,n), + metadata = getinfo(fontdata,n), -- no platformnames here ! properties = { hasitalics = fontdata.hasitalics or false, }, @@ -2067,27 +2136,38 @@ function readers.loadfont(filename,n) end end -function readers.getinfo(filename,n,details) +function readers.getinfo(filename,specification) -- string, nil|number|table + -- platformnames is optional and not used by context (a too unpredictable mess + -- that only add to the confusion) .. so it's only for checking things + local subfont = nil + local platformname = false + if type(specification) == "table" then + subfont = tonumber(specification.subfont) + platformnames = specification.platformnames + else + subfont = tonumber(specification) + end local fontdata = loadfont { - filename = filename, - details = true, + filename = filename, + details = true, + platformnames = platformnames, } if fontdata then local subfonts = fontdata.subfonts if not subfonts then - return getinfo(fontdata) - elseif type(n) ~= "number" then + return getinfo(fontdata,nil,platformnames) + elseif not subfont then local info = { } for i=1,#subfonts do - info[i] = getinfo(fontdata,i) + info[i] = getinfo(fontdata,i,platformnames) end return info - elseif n > 1 and n <= subfonts then - return getinfo(fontdata,n) + elseif subfont > 1 and subfont <= #subfonts then + return getinfo(fontdata,subfont,platformnames) else return { filename = filename, - comment = "there is no subfont " .. n .. " in this file" + comment = "there is no subfont " .. subfont .. " in this file" } end else diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 4d5e8ec0e..d67db6dd6 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -2716,8 +2716,8 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context return rl end -local function report_disc(n) - report_run("kern: %s > %s",disc,languages.serializediscretionary(disc)) +local function report_disc(what,n) + report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) end local function kernrun(disc,k_run,font,attr,...) @@ -2725,7 +2725,7 @@ local function kernrun(disc,k_run,font,attr,...) -- we catch -- if trace_kernruns then - report_disc("kern") + report_disc("kern",disc) end -- local prev, next = getboth(disc) @@ -2819,7 +2819,7 @@ end local function comprun(disc,c_run,...) if trace_compruns then - report_disc("comp") + report_disc("comp",disc) end -- local pre, post, replace = getdisc(disc) @@ -2866,31 +2866,35 @@ end local function testrun(disc,t_run,c_run,...) if trace_testruns then - report_disc("test") + report_disc("test",disc) end local prev, next = getboth(disc) if not next then -- weird discretionary return end - local pre, post, replace, pretail, posttail, replacetail = getdisc(disc) + local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) local done = false if replace and prev then - -- only look ahead - -- local nest = getprev(replace) + -- this is a bit strange as we only do replace here and not post + -- anyway, we only look ahead ... the idea is that we discard a + -- disc when there is a ligature crossing the replace boundary setlink(replacetail,next) - if t_run(replace,next,...) then - setfield(disc,"replace",nil) -- beware, side effects of nest so first + local ok, overflow = t_run(replace,next,...) + if ok and overflow then + -- so, we can have crossed the boundary + setfield(disc,"replace",nil) setlink(prev,replace) - setlink(replacetail,next) + -- setlink(replacetail,next) setboth(disc) flush_node_list(disc) return replace, true -- restart .. tricky ! else + -- we stay inside the disc setnext(replacetail) setprev(next,disc) end - -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc) + -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) end -- -- like comprun @@ -2945,7 +2949,7 @@ end -- local function discrun(disc,drun,krun) -- local prev, next = getboth(disc) -- if trace_discruns then --- report_disc("disc") +-- report_disc("disc",disc) -- end -- if next and prev then -- setnext(prev,next) @@ -3043,7 +3047,13 @@ local function t_run_single(start,stop,font,attr,lookupcache) -- if we need more than ligatures we can outline the code and use functions local s = getnext(start) local l = nil + local d = 0 while s do + if s == stop then + d = 1 + elseif d > 0 then + d = d + 1 + end local lg = lookupmatch[getchar(s)] if lg then l = lg @@ -3053,7 +3063,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end end if l and l.ligature then - return true + return true, d > 1 end end end @@ -3168,7 +3178,13 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) -- if we need more than ligatures we can outline the code and use functions local s = getnext(start) local l = nil + local d = 0 while s do + if s == stop then + d = 1 + elseif d > 0 then + d = d + 1 + end local lg = lookupmatch[getchar(s)] if lg then l = lg @@ -3178,7 +3194,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end end if l and l.ligature then - return true + return true, d > 1 end end else diff --git a/tex/context/base/mkiv/font-syn.lua b/tex/context/base/mkiv/font-syn.lua index dc090a1d9..049fbd101 100644 --- a/tex/context/base/mkiv/font-syn.lua +++ b/tex/context/base/mkiv/font-syn.lua @@ -325,20 +325,21 @@ local function normalize(t) boundingbox = { 0, 0, 0, 0 } end return { - copyright = t.copyright, - fontname = t.fontname, - fullname = t.fullname, - familyname = t.familyname, - weight = t.weight, - widtht = t.width, - italicangle = tonumber(t.italicangle) or 0, - monospaced = toboolean(t.isfixedpitch) or false, - boundingbox = boundingbox, - version = t.version, - capheight = tonumber(t.capheight), - xheight = tonumber(t.xheight), - ascender = tonumber(t.ascender), - descender = tonumber(t.descender), + copyright = t.copyright, + fontname = t.fontname, + fullname = t.fullname, + familyname = t.familyname, + -- subfamilyname = t.subfamilyname, -- nor used / needed + weight = t.weight, + widtht = t.width, + italicangle = tonumber(t.italicangle) or 0, + monospaced = toboolean(t.isfixedpitch) or false, + boundingbox = boundingbox, + version = t.version, -- not used + capheight = tonumber(t.capheight), + xheight = tonumber(t.xheight), + ascender = tonumber(t.ascender), + descender = tonumber(t.descender), } end @@ -554,38 +555,39 @@ local function walk_tree(pathlist,suffix,identify) end end --- "typographicfamily", -- preffamilyname --- "typographicsubfamily", -- prefmodifiers - local function check_name(data,result,filename,modification,suffix,subfont) -- shortcuts local specifications = data.specifications -- fetch - local familyname = result.familyname - local fullname = result.fullname - local fontname = result.fontname - local subfamily = result.subfamily - local modifiers = result.modifiers - local weight = result.weight - local italicangle = tonumber(result.italicangle) - local subfont = subfont - local rawname = fullname or fontname or familyname - local filebase = removesuffix(basename(filename)) - local cleanfilename = cleanname(filebase) -- for WS + local fullname = result.fullname + local fontname = result.fontname + local family = result.family + local subfamily = result.subfamily + local familyname = result.familyname + local subfamilyname = result.subfamilyname or result.modifiers + -- local compatiblename = result.compatiblename + local weight = result.weight + local italicangle = tonumber(result.italicangle) + local subfont = subfont + local rawname = fullname or fontname or familyname + local filebase = removesuffix(basename(filename)) + local cleanfilename = cleanname(filebase) -- for WS -- normalize - familyname = familyname and cleanname(familyname) - fullname = fullname and cleanname(fullname) - fontname = fontname and cleanname(fontname) - subfamily = subfamily and cleanname(subfamily) - modifiers = modifiers and cleanname(modifiers) - weight = weight and cleanname(weight) - italicangle = italicangle == 0 and nil + fullname = fullname and cleanname(fullname) + fontname = fontname and cleanname(fontname) + family = family and cleanname(family) + subfamily = subfamily and cleanname(subfamily) + familyname = familyname and cleanname(familyname) + subfamilyname = subfamilyname and cleanname(subfamilyname) + -- compatiblename = compatiblename and cleanname(compatiblename) + weight = weight and cleanname(weight) + italicangle = italicangle == 0 and nil -- analyze local a_name, a_weight, a_style, a_width, a_variant = analyzespec(fullname or fontname or familyname) -- check local width = a_width local variant = a_variant - local style = modifiers and gsub(modifiers,"[^%a]","") + local style = subfamilyname and gsub(subfamilyname,"[^%a]","") if not style and italicangle then style = "italic" end @@ -614,29 +616,31 @@ local function check_name(data,result,filename,modification,suffix,subfont) local pfmweight = result.pfmweight or 0 -- specifications[#specifications + 1] = { - filename = filename, -- unresolved - cleanfilename = cleanfilename, - -- subfontindex = subfont, - format = lower(suffix), - subfont = subfont, - rawname = rawname, - familyname = familyname, - fullname = fullname, - fontname = fontname, - subfamily = subfamily, - modifiers = modifiers, - weight = weight, - style = style, - width = width, - variant = variant, - units = units ~= 1000 and units or nil, - pfmwidth = pfmwidth ~= 0 and pfmwidth or nil, - pfmweight = pfmweight ~= 0 and pfmweight or nil, - angle = angle ~= 0 and angle or nil, - minsize = minsize ~= 0 and minsize or nil, - maxsize = maxsize ~= 0 and maxsize or nil, - designsize = designsize ~= 0 and designsize or nil, - modification = modification ~= 0 and modification or nil, + filename = filename, -- unresolved + cleanfilename = cleanfilename, + -- subfontindex = subfont, + format = lower(suffix), + subfont = subfont, + rawname = rawname, + fullname = fullname, + fontname = fontname, + family = family, -- kind of redundant, could be nil if familyname + subfamily = subfamily, -- kind of redundant, could be nil if familyname + familyname = familyname, + subfamilyname = subfamilyname, + -- compatiblename = compatiblename, -- nor used / needed + weight = weight, + style = style, + width = width, + variant = variant, + units = units ~= 1000 and units or nil, + pfmwidth = pfmwidth ~= 0 and pfmwidth or nil, + pfmweight = pfmweight ~= 0 and pfmweight or nil, + angle = angle ~= 0 and angle or nil, + minsize = minsize ~= 0 and minsize or nil, + maxsize = maxsize ~= 0 and maxsize or nil, + designsize = designsize ~= 0 and designsize or nil, + modification = modification ~= 0 and modification or nil, } end @@ -673,14 +677,18 @@ local function cleanupkeywords() end s.weight, s.style, s.width, s.variant = weight, style, width, variant end - local stats = data.statistics - stats.used_weights, stats.used_styles, stats.used_widths, stats.used_variants = weights, styles, widths, variants + local statistics = data.statistics + statistics.used_weights = weights + statistics.used_styles = styles + statistics.used_widths = widths + statistics.used_variants = variants end end -local function collectstatistics() +local function collectstatistics(runtime) local data = names.data local specifications = data.specifications + local statistics = data.statistics if specifications then local f_w = formatters["%i"] local f_a = formatters["%0.2f"] @@ -718,20 +726,21 @@ local function collectstatistics() twidths[pfmwidth] = (twidths [pfmwidth] or 0) + 1 end -- - local stats = data.statistics - stats.weights = weights - stats.styles = styles - stats.widths = widths - stats.variants = variants - stats.angles = angles - stats.pfmweights = pfmweights - stats.pfmwidths = pfmwidths - stats.fonts = #specifications + statistics.weights = weights + statistics.styles = styles + statistics.widths = widths + statistics.variants = variants + statistics.angles = angles + statistics.pfmweights = pfmweights + statistics.pfmwidths = pfmwidths + statistics.fonts = #specifications -- setmetatableindex(pfmweights,nil) setmetatableindex(pfmwidths, nil) -- report_names("") + report_names("statistics: ") + report_names("") report_names("weights") report_names("") report_names(formatters[" %T"](weights)) @@ -764,6 +773,13 @@ local function collectstatistics() report_names(formatters[" %-10s: %T"](k,v)) end report_names("") + report_names("registered fonts : %i", statistics.fonts) + report_names("read files : %i", statistics.readfiles) + report_names("skipped files : %i", statistics.skippedfiles) + report_names("duplicate files : %i", statistics.duplicatefiles) + if runtime then + report_names("total scan time : %0.3f seconds",runtime) + end end end @@ -1186,14 +1202,12 @@ function names.identify(force) analyzefiles(not force and names.readdata(names.basename)) rejectclashes() collectfamilies() - -- collectstatistics() cleanupkeywords() collecthashes() checkduplicates() addfilenames() -- sorthashes() -- will be resorted when saved - collectstatistics() - report_names("total scan time %0.3f seconds",os.gettimeofday()-starttime) + collectstatistics(os.gettimeofday()-starttime) end function names.is_permitted(name) @@ -2045,52 +2059,6 @@ function fonts.names.ignoredfile(filename) -- only supported in mkiv return false -- will be overloaded end --- We could generate typescripts with designsize info from the name database but --- it's not worth the trouble as font names remain a mess: for instance how do we --- idenfity a font? Names, families, subfamilies or whatever snippet can contain --- a number related to the design size and so we end up with fuzzy logic again. So, --- instead it's easier to make a few goody files. --- --- local hash = { } --- --- for i=1,#specifications do --- local s = specifications[i] --- local min = s.minsize or 0 --- local max = s.maxsize or 0 --- if min ~= 0 or max ~= 0 then --- -- the usual name mess: --- -- antykwa has modifiers so we need to take these into account, otherwise we get weird combinations --- -- ebgaramond has modifiers with the size encoded, so we need to strip this in order to recognized similar styles --- -- lm has 'slanted appended in some names so how to choose that one --- -- --- local modifier = string.gsub(s.modifiers or "normal","%d","") --- -- print funny modifier --- local instance = string.formatters["%s-%s-%s-%s-%s-%s"](s.familyname,s.width,s.style,s.weight,s.variant,modifier) --- local h = hash[instance] --- if not h then --- h = { } --- hash[instance] = h --- end --- size = string.formatters["%0.1fpt"]((min)/10) --- h[size] = s.filename --- end --- end --- --- local newhash = { } --- --- for k, v in next, hash do --- if next(v,next(v)) then --- -- local instance = string.match(k,"(.+)%-.+%-.+%-.+$") --- local instance = string.match(k,"(.+)%-.+%-.+$") --- local instance = string.gsub(instance,"%-normal$","") --- if not newhash[instance] then --- newhash[instance] = v --- end --- end --- end --- --- inspect(newhash) - -- example made for luatex list (unlikely to be used): -- -- local command = [[reg QUERY "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"]] diff --git a/tex/context/base/mkiv/lang-hyp.lua b/tex/context/base/mkiv/lang-hyp.lua index 65337143d..146aea4a8 100644 --- a/tex/context/base/mkiv/lang-hyp.lua +++ b/tex/context/base/mkiv/lang-hyp.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['lang-hyp'] = { } -- todo: hyphenate over range if needed +-- todo: check boundary nodes -- setattr: helper for full attr diff --git a/tex/context/base/mkiv/lang-rep.mkiv b/tex/context/base/mkiv/lang-rep.mkiv index a98d51f6c..48e1fd44b 100644 --- a/tex/context/base/mkiv/lang-rep.mkiv +++ b/tex/context/base/mkiv/lang-rep.mkiv @@ -21,7 +21,7 @@ \registerctxluafile{lang-rep}{1.001} -\definesystemattribute[replacements][public] +\definesystemattribute[replacements][public,global] %D \startluacode %D diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua index 7a0ef3e64..3a49ea3d2 100644 --- a/tex/context/base/mkiv/lxml-tex.lua +++ b/tex/context/base/mkiv/lxml-tex.lua @@ -1712,15 +1712,15 @@ end function lxml.context(id,pattern) -- the content, untouched by commands if pattern then - local collected = xmlapplylpath(getid(id),pattern) or getid(id) + local collected = xmlapplylpath(getid(id),pattern) if collected and #collected > 0 then - contextsprint(ctxcatcodes,collected[1].dt) + ctx_text(collected[1].dt[1]) end else local collected = getid(id) if collected then local dt = collected.dt - if #dt > 0 then + if dt and #dt > 0 then ctx_text(dt[1]) end end diff --git a/tex/context/base/mkiv/mtx-context-setups.tex b/tex/context/base/mkiv/mtx-context-setups.tex new file mode 100644 index 000000000..be99211ba --- /dev/null +++ b/tex/context/base/mkiv/mtx-context-setups.tex @@ -0,0 +1,78 @@ +%D \module +%D [ file=mtx-context-setups, +%D version=2016.04.05, +%D title=\CONTEXT\ Command Overvews, +%D subtitle=Combine Files, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% begin help +% +% usage: context --extra=setups [options] [categories] +% +% --interface : user interface (en, nl, etc) +% --overview [--save] : use collection of files +% --list : show know collections +% +% end help + +\input mtx-context-common.tex + +\starttext + +\startluacode + local report_setups = logs.reporter("setups") + + context.starttext() + + if document.arguments.list then + local okay = resolvers.findfile("context.mkiv") or "" -- will become an i file + if okay ~= "" then + okay = file.collapsepath(okay,true) + okay = string.gsub(okay,"/base/","/interface/") + okay = string.gsub(okay,"/sources/","/interface/") + local path = file.pathpart(okay) + local pattern = file.join(path,"i-*.xml") + local files = dir.glob(pattern) + local valid = { } + table.sort(files) + for i=1,#files do + local name = file.nameonly(files[i]) + local base = string.match(name,"^i%-([a-z]+)$") + if base then + valid[#valid+1] = base + end + end + if #valid > 0 then + report_setups("% t",valid) + end + context.bold("available setup groups: ") + context("%, t.",valid) + end + elseif document.arguments.overview then + if document.arguments.save then + context.enablemode { "setups:save" } + end + context.input("x-setups-overview.mkiv") + elseif #document.files > 0 then + context.usemodule { "x-setups-basics" } + for i=1,#document.files do + local filename = "i-" .. document.files[i] + report_setups("processing %a",filename) + context.loadsetups { filename } + end + context.input("x-setups-proofing.mkiv") + else + context("no setups") + end + + context.stoptext() +\stopluacode + +\stoptext + diff --git a/tex/context/base/mkiv/mult-ini.lua b/tex/context/base/mkiv/mult-ini.lua index 7763994d6..99703b488 100644 --- a/tex/context/base/mkiv/mult-ini.lua +++ b/tex/context/base/mkiv/mult-ini.lua @@ -60,6 +60,9 @@ sharedstorage.currentresponse = sharedstorage.currentresponse or "en" local currentinterface = sharedstorage.currentinterface local currentresponse = sharedstorage.currentresponse +interfaces.currentinterface = currentinterface +interfaces.currentresponse = currentresponse + local complete = allocate() interfaces.complete = complete @@ -316,6 +319,8 @@ function interfaces.setuserinterface(interface,response) else report_interface("the language(s) can only be set when making the format") end + interfaces.currentinterface = currentinterface + interfaces.currentresponse = currentresponse end interfaces.implement { diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 37983f9a4..d9c432f7c 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -232,6 +232,7 @@ return { "attribute", "attributedef", "bodydir", + "boundary", "boxdir", "catcodetable", "clearmarks", @@ -284,6 +285,7 @@ return { "mathscriptsmode", "mathstyle", "mathsurroundskip", + "noboundary", "nokerns", "nohrule", "noligs", @@ -309,6 +311,7 @@ return { "prehyphenchar", "primitive", "protrudechars", + "protrusionboundary", "pxdimen", "randomseed", "rightghost", @@ -333,6 +336,7 @@ return { "uniformdeviate", "useboxresource", "useimageresource", + "wordboundary", -- "vpack", "hpack", @@ -1126,6 +1130,8 @@ return { "prevgraf", "primitive", "protected", + "protrudechars", + "protrusionboundary", "pxdimen", "quitvmode", "radical", @@ -1257,6 +1263,7 @@ return { "wd", "widowpenalties", "widowpenalty", + "wordboundary", "write", "xdef", "xleaders", diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index 313b804cb..6572d1168 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -192,8 +192,8 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr local id = getid(stack) if id == glyph_code then check = true - -- elseif id == disc_code then - -- check = true -- no longer needed as we flatten replace + elseif id == disc_code then + check = true -- no longer needed as we flatten replace elseif id == glue_code then leader = getleader(stack) if leader then @@ -321,8 +321,8 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at local id = getid(stack) if id == glyph_code then check = true - -- elseif id == disc_code then - -- check = true -- no longer needed as we flatten replace + elseif id == disc_code then + check = true -- notneeded when we flatten replace elseif id == glue_code then leader = getleader(stack) if leader then diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua index 76273cfd6..c726cdb4c 100644 --- a/tex/context/base/mkiv/node-fnt.lua +++ b/tex/context/base/mkiv/node-fnt.lua @@ -13,12 +13,13 @@ local concat, keys = table.concat, table.keys local nodes, node, fonts = nodes, node, fonts -local trace_characters = false trackers .register("nodes.characters", function(v) trace_characters = v end) -local trace_fontrun = false trackers .register("nodes.fontrun", function(v) trace_fontrun = v end) -local trace_variants = false trackers .register("nodes.variants", function(v) trace_variants = v end) +local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end) +local trace_fontrun = false trackers.register("nodes.fontrun", function(v) trace_fontrun = v end) +local trace_variants = false trackers.register("nodes.variants", function(v) trace_variants = v end) -local force_discrun = true directives.register("nodes.discrun", function(v) force_discrun = v end) -local force_basepass = true directives.register("nodes.basepass", function(v) force_basepass = v end) +local force_discrun = true directives.register("nodes.discrun", function(v) force_discrun = v end) +local force_boundaryrun = true directives.register("nodes.boundaryrun", function(v) force_boundaryrun = v end) +local force_basepass = true directives.register("nodes.basepass", function(v) force_basepass = v end) local report_fonts = logs.reporter("fonts","processing") @@ -58,11 +59,13 @@ local ischar = nuts.ischar -- checked local traverse_id = nuts.traverse_id local traverse_char = nuts.traverse_char -local delete_node = nuts.delete +local remove_node = nuts.remove local protect_glyph = nuts.protect_glyph local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc +local boundary_code = nodecodes.boundary +local word_boundary = nodes.boundarycodes.word local setmetatableindex = table.setmetatableindex @@ -185,6 +188,8 @@ function handlers.characters(head) report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char) elseif id == disc_code then report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) + elseif id == boundary_code then + report_fonts("[boundary] %i:%i",getsubtype(n),getfield(n,"value")) else report_fonts("[%s]",nodecodes[id]) end @@ -268,15 +273,34 @@ function handlers.characters(head) end end + if force_boundaryrun then + + -- we can inject wordboundaries and then let the hyphenator do its work + -- but we need to get rid of those nodes in order to build ligatures + -- and kern (a rather context thing) + + for b in traverse_id(boundary_code,nuthead) do + if getsubtype(b) == word_boundary then + if redundant then + redundant[#redundant+1] = b + else + redundant = { b } + end + end + end + + end + if redundant then + local front = nuthead == redundant[1] for i=1,#redundant do - delete_node(nuthead,n) + nuthead = remove_node(nuthead,redundant[i],true) + end + if front then + head = tonode(nuthead) end end - -- could be an optional pass : seldom needed, only for documentation as a discretionary - -- with pre/post/replace will normally not occur on it's own - local e = 0 if force_discrun then @@ -341,9 +365,10 @@ function handlers.characters(head) report_fonts() report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none") - report_fonts("built-in: %s",b > 0 and b or "none") + report_fonts("built-in: %s",b > 0 and b or "none") + report_fonts("removed : %s",redundant and #redundant > 0 and #redundant or "none") if expanders then - report_fonts("expanded: %s",e > 0 and e or "none") + report_fonts("expanded: %s",e > 0 and e or "none") end report_fonts() end diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua index f311bb811..bb8a7d331 100644 --- a/tex/context/base/mkiv/node-ini.lua +++ b/tex/context/base/mkiv/node-ini.lua @@ -162,6 +162,17 @@ local leadercodes = mark(getsubtypes("leader")) local fillcodes = mark(getsubtypes("fill")) +-- for now: + +local boundarycodes = allocate { + [0] = "cancel", + [1] = "user", + [2] = "protrusion", + [3] = "word", +} + +-- local boundarycodes = mark(getsubtypes("boundary")) + -- local penaltycodes = allocate { -- unfortunately not used (yet) -- [ 0] = "userpenalty", -- } @@ -254,41 +265,43 @@ end local nodecodes = simplified(node.types()) local whatcodes = simplified(node.whatsits()) -skipcodes = allocate(swapped(skipcodes,skipcodes)) -noadcodes = allocate(swapped(noadcodes,noadcodes)) -radicalcodes = allocate(swapped(radicalcodes,radicalcodes)) -nodecodes = allocate(swapped(nodecodes,nodecodes)) -whatcodes = allocate(swapped(whatcodes,whatcodes)) -listcodes = allocate(swapped(listcodes,listcodes)) -glyphcodes = allocate(swapped(glyphcodes,glyphcodes)) -kerncodes = allocate(swapped(kerncodes,kerncodes)) -penaltycodes = allocate(swapped(penaltycodes,penaltycodes)) -mathcodes = allocate(swapped(mathcodes,mathcodes)) -fillcodes = allocate(swapped(fillcodes,fillcodes)) -margincodes = allocate(swapped(margincodes,margincodes)) -disccodes = allocate(swapped(disccodes,disccodes)) -accentcodes = allocate(swapped(accentcodes,accentcodes)) -fencecodes = allocate(swapped(fencecodes,fencecodes)) -rulecodes = allocate(swapped(rulecodes,rulecodes)) -leadercodes = allocate(swapped(leadercodes,leadercodes)) - -nodes.skipcodes = skipcodes nodes.gluecodes = skipcodes -- more official -nodes.noadcodes = noadcodes -nodes.nodecodes = nodecodes -nodes.whatcodes = whatcodes nodes.whatsitcodes = whatcodes -- more official -nodes.listcodes = listcodes -nodes.glyphcodes = glyphcodes -nodes.kerncodes = kerncodes -nodes.penaltycodes = penaltycodes -nodes.mathcodes = mathcodes -nodes.fillcodes = fillcodes -nodes.margincodes = margincodes nodes.marginkerncodes = margincodes -nodes.disccodes = disccodes nodes.discretionarycodes = disccodes -nodes.accentcodes = accentcodes -nodes.radicalcodes = radicalcodes -nodes.fencecodes = fencecodes -nodes.rulecodes = rulecodes -nodes.leadercodes = leadercodes +skipcodes = allocate(swapped(skipcodes,skipcodes)) +boundarycodes = allocate(swapped(boundarycodes,boundarycodes)) +noadcodes = allocate(swapped(noadcodes,noadcodes)) +radicalcodes = allocate(swapped(radicalcodes,radicalcodes)) +nodecodes = allocate(swapped(nodecodes,nodecodes)) +whatcodes = allocate(swapped(whatcodes,whatcodes)) +listcodes = allocate(swapped(listcodes,listcodes)) +glyphcodes = allocate(swapped(glyphcodes,glyphcodes)) +kerncodes = allocate(swapped(kerncodes,kerncodes)) +penaltycodes = allocate(swapped(penaltycodes,penaltycodes)) +mathcodes = allocate(swapped(mathcodes,mathcodes)) +fillcodes = allocate(swapped(fillcodes,fillcodes)) +margincodes = allocate(swapped(margincodes,margincodes)) +disccodes = allocate(swapped(disccodes,disccodes)) +accentcodes = allocate(swapped(accentcodes,accentcodes)) +fencecodes = allocate(swapped(fencecodes,fencecodes)) +rulecodes = allocate(swapped(rulecodes,rulecodes)) +leadercodes = allocate(swapped(leadercodes,leadercodes)) + +nodes.skipcodes = skipcodes nodes.gluecodes = skipcodes -- more official +nodes.boundarycodes = boundarycodes +nodes.noadcodes = noadcodes +nodes.nodecodes = nodecodes +nodes.whatcodes = whatcodes nodes.whatsitcodes = whatcodes -- more official +nodes.listcodes = listcodes +nodes.glyphcodes = glyphcodes +nodes.kerncodes = kerncodes +nodes.penaltycodes = penaltycodes +nodes.mathcodes = mathcodes +nodes.fillcodes = fillcodes +nodes.margincodes = margincodes nodes.marginkerncodes = margincodes +nodes.disccodes = disccodes nodes.discretionarycodes = disccodes +nodes.accentcodes = accentcodes +nodes.radicalcodes = radicalcodes +nodes.fencecodes = fencecodes +nodes.rulecodes = rulecodes +nodes.leadercodes = leadercodes listcodes.row = listcodes.alignment listcodes.column = listcodes.alignment @@ -298,21 +311,22 @@ kerncodes.kerning = kerncodes.fontkern kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new nodes.codes = allocate { -- mostly for listing - glue = skipcodes, - noad = noadcodes, - node = nodecodes, - hlist = listcodes, - vlist = listcodes, - glyph = glyphcodes, - kern = kerncodes, - penalty = penaltycodes, - math = mathnodes, - fill = fillcodes, - margin = margincodes, - disc = disccodes, - whatsit = whatcodes, - accent = accentcodes, - fence = fencecodes, + glue = skipcodes, + boundary = boundarycodes, + noad = noadcodes, + node = nodecodes, + hlist = listcodes, + vlist = listcodes, + glyph = glyphcodes, + kern = kerncodes, + penalty = penaltycodes, + math = mathnodes, + fill = fillcodes, + margin = margincodes, + disc = disccodes, + whatsit = whatcodes, + accent = accentcodes, + fence = fencecodes, } local report_codes = logs.reporter("nodes","codes") diff --git a/tex/context/base/mkiv/node-ltp.lua b/tex/context/base/mkiv/node-ltp.lua index 380b94e64..ae17ab9ef 100644 --- a/tex/context/base/mkiv/node-ltp.lua +++ b/tex/context/base/mkiv/node-ltp.lua @@ -244,6 +244,7 @@ local margincodes = nodes.margincodes local disccodes = nodes.disccodes local mathcodes = nodes.mathcodes local fillcodes = nodes.fillcodes +local boundarycodes = nodes.boundarycodes local temp_code = nodecodes.temp local glyph_code = nodecodes.glyph @@ -260,6 +261,9 @@ local vlist_code = nodecodes.vlist local unset_code = nodecodes.unset local marginkern_code = nodecodes.marginkern local dir_code = nodecodes.dir +local boundary_code = nodecodes.boundary + +local protrusion_code = boundarycodes.protrusion local leaders_code = gluecodes.leaders @@ -612,6 +616,16 @@ local function find(head) -- do we really want to recurse into an hlist? else head = getnext(head) end + elseif id == protrusion_code then + local v = getfield(head,"value") + if v == 1 or v == 3 then + head = getnext(head) + if head then + head = getnext(head) + end + else + return head + end elseif is_skipable(head) then head = getnext(head) else @@ -652,6 +666,16 @@ local function find(head,tail) else tail = getprev(tail) end + elseif id == protrusion_code then + local v = getfield(tail,"value") + if v == 2 or v == 3 then + tail = getprev(tail) + if tail then + tail = getprev(tail) + end + else + return tail + end elseif is_skipable(tail) then tail = getprev(tail) else @@ -1198,7 +1222,7 @@ local function post_line_break(par) local prevlast = getprev(lastnode) local nextlast = getnext(lastnode) local subtype = getsubtype(lastnode) - local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode) + local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode,true) if subtype == second_disc_code then if not (getid(prevlast) == disc_code and getsubtype(prevlast) == first_disc_code) then report_parbuilders('unsupported disc at location %a',3) @@ -1875,7 +1899,7 @@ local function try_break(pi, break_type, par, first_p, current, checked_expansio local l = b and b.cur_break or first_p local o = current and getprev(current) if current and getid(current) == disc_code then - local pre, _, _, pretail = getdisc(current) + local pre, _, _, pretail = getdisc(current,true) if pre then o = pretail else diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index d87f40df7..4d25314ad 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -18,20 +18,21 @@ local report_nodes = logs.reporter("nodes","housekeeping") local nodes, node = nodes, node -nodes.pool = nodes.pool or { } -local nodepool = nodes.pool +nodes.pool = nodes.pool or { } +local nodepool = nodes.pool -local whatsitcodes = nodes.whatsitcodes -local skipcodes = nodes.skipcodes -local kerncodes = nodes.kerncodes -local rulecodes = nodes.rulecodes -local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes +local skipcodes = nodes.skipcodes +local kerncodes = nodes.kerncodes +local rulecodes = nodes.rulecodes +local nodecodes = nodes.nodecodes +local boundarycodes = nodes.boundarycodes -local glyph_code = nodecodes.glyph +local glyph_code = nodecodes.glyph -local allocate = utilities.storage.allocate +local allocate = utilities.storage.allocate -local texgetcount = tex.getcount +local texgetcount = tex.getcount local reserved, nofreserved = { }, 0 @@ -154,15 +155,22 @@ local user_l = register_nut(new_nut("whatsit",whatsitcodes.userdefine local user_s = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_s,"type",115) -- 44 local user_t = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_t,"type",116) -- 44 ----- user_c = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_c,"type",108) -- 44 + local left_margin_kern = register_nut(new_nut("margin_kern",0)) local right_margin_kern = register_nut(new_nut("margin_kern",1)) + local lineskip = register_nut(new_nut("glue",skipcodes.lineskip)) local baselineskip = register_nut(new_nut("glue",skipcodes.baselineskip)) local leftskip = register_nut(new_nut("glue",skipcodes.leftskip)) 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 boundary = register_nut(new_nut("boundary",boundarycodes.user)) +local wordboundary = register_nut(new_nut("boundary",boundarycodes.word)) + -- the dir field needs to be set otherwise crash: local rule = register_nut(new_nut("rule")) setfield(rule, "dir","TLT") @@ -193,13 +201,33 @@ end function nutpool.penalty(p) local n = copy_nut(penalty) - setfield(n,"penalty",p) + if p and p ~= 0 then + setfield(n,"penalty",p) + end return n end function nutpool.kern(k) local n = copy_nut(kern) - setfield(n,"kern",k) + if k and k ~= 0 then + setfield(n,"kern",k) + end + return n +end + +function nutpool.boundary(v) + local n = copy_nut(boundary) + if v and v ~= 0 then + setfield(n,"value",v) + end + return n +end + +function nutpool.wordboundary(v) + local n = copy_nut(wordboundary) + if v and v ~= 0 then + setfield(n,"value",v) + end return n end @@ -211,7 +239,9 @@ end function nutpool.italickern(k) local n = copy_nut(italickern) - setfield(n,"kern",k) + if k and k ~= 0 then + setfield(n,"kern",k) + end return n end diff --git a/tex/context/base/mkiv/node-shp.lua b/tex/context/base/mkiv/node-shp.lua index 4e4c88c03..2f2af4905 100644 --- a/tex/context/base/mkiv/node-shp.lua +++ b/tex/context/base/mkiv/node-shp.lua @@ -78,7 +78,7 @@ local function cleanup_redundant(head) -- better name is: flatten_page local id = getid(start) if id == disc_code then if getsubtype(start) == fulldisc_code then - local _, _, replace, _, _ tail = getdisc(start) + local _, _, replace, _, _ tail = getdisc(start,true) if replace then local prev, next = getboth(start) setfield(start,"replace",nil) diff --git a/tex/context/base/mkiv/spac-ali.mkiv b/tex/context/base/mkiv/spac-ali.mkiv index e7d4137a0..21714f07c 100644 --- a/tex/context/base/mkiv/spac-ali.mkiv +++ b/tex/context/base/mkiv/spac-ali.mkiv @@ -911,7 +911,8 @@ % Structure: \unexpanded\def\startalignment - {\begingroup + {\par + \begingroup \setupalign} \unexpanded\def\stopalignment diff --git a/tex/context/base/mkiv/spac-hor.mkiv b/tex/context/base/mkiv/spac-hor.mkiv index 39ebcfa26..7c5358c51 100644 --- a/tex/context/base/mkiv/spac-hor.mkiv +++ b/tex/context/base/mkiv/spac-hor.mkiv @@ -460,10 +460,18 @@ %D \TEX{} x\crlf %D \stoptyping %D -%D from now on we treat it as anormal space and not as a space with \type +%D from now on we treat it as a normal space and not as a space with \type %D {sfcode} 1000. -\unexpanded\def\normalnotobeyedspace{\mathortext\normalspaceprimitive\space} % no \dontleavehmode\space (else no frenchspacing) +\unexpanded\def\specialspaceprimitive + {\begingroup + % so, no fancy extra spacing after: foo i.e.\ bar + \nonfrenchspacing\normalspaceprimitive + \endgroup} + +\unexpanded\def\normalnotobeyedspace + {\mathortext\normalspaceprimitive\specialspaceprimitive} % no \dontleavehmode\space (else no frenchspacing) + \let\ =\normalnotobeyedspace % Because I strip spaces at the end of lines (in the editor) we need a bit of diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv index 6ae96b7ec..bbe53fb2a 100644 --- a/tex/context/base/mkiv/spac-ver.mkiv +++ b/tex/context/base/mkiv/spac-ver.mkiv @@ -1141,8 +1141,8 @@ %D For poractical reasons we define some boundary characters here. -\unexpanded\def\leftboundary {\boundary\plusone} -\unexpanded\def\rightboundary {\boundary\plustwo} +\unexpanded\def\leftboundary {\protrusionboundary\plusone} +\unexpanded\def\rightboundary {\protrusionboundary\plustwo} \unexpanded\def\signalcharacter{\boundary\plusone\char\zerocount\boundary\plustwo} % not the same as strut signals \newsignal\strutsignal \setfalse\sigstruts diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 5b21c27a2..707b46e9f 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 68a17780b..f98d31424 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/strc-itm.mkvi b/tex/context/base/mkiv/strc-itm.mkvi index 506aec940..e8a56acf8 100644 --- a/tex/context/base/mkiv/strc-itm.mkvi +++ b/tex/context/base/mkiv/strc-itm.mkvi @@ -670,6 +670,36 @@ \strc_itemgroups_insert_reference \endgroup} +% needs testing (maybe it need to happen later) +% +% \appendtoks +% \setupcounter +% [\v_strc_itemgroups_counter]% +% [\c!prefix=\itemgroupparameter\c!prefix, +% \c!prefixstopper=\itemgroupparameter\c!prefixstopper, +% \c!prefixseparatorset=\itemgroupparameter\c!prefixseparatorset, +% \c!prefixconversion=\itemgroupparameter\c!prefixconversion, +% \c!prefixconversionset=\itemgroupparameter\c!prefixseparatorset, +% \c!prefixset=\itemgroupparameter\c!prefixset, +% \c!prefixsegments=\itemgroupparameter\c!prefixsegments, +% \c!prefixconnector=\itemgroupparameter\c!prefixconnector, +% \c!criterium=\itemgroupparameter\c!criterium, +% \c!numberorder=\ifconditional\c_strc_itemgroups_reverse\v!reverse\else\v!normal\fi, +% \c!numberstopper=\expdoif{\itemgroupparameter\c!placestopper}\v!yes{\itemgroupparameter\c!stopper}, +% \c!numberconversionset=\v_strc_itemgroups_counter, +% \c!numbersegments=\currentitemgroupsegments]% +% \to\itemgroupcommands +% +% \def\strc_itemgroups_insert_item_counter_indeed % quite slow ... every time this setup .. but it +% {\begingroup % can be optimized ... best move some to strc-num +% % there will be a fixedconversion key +% %\normalexpanded{\defineconversionset[\v_strc_itemgroups_counter][\currentitemgroupconversionset][\currentitemgroupsymbol]}% +% \normalexpanded{\strc_sets_define_conversion_set[\v_strc_itemgroups_counter][\currentitemgroupconversionset][\currentitemgroupsymbol]}% +% % +% \convertedcounter[\v_strc_itemgroups_counter]% [\number\currentitemlevel]% +% \strc_itemgroups_insert_reference +% \endgroup} + \def\strc_itemgroups_set_symbol#symbol% {\edef\strc_itemgroups_tmp_symbol{#symbol}% \ifx\strc_itemgroups_tmp_symbol\empty \else @@ -1666,6 +1696,36 @@ %D End of plugin. +%D Something for tables: + +\unexpanded\def\itemtag % not yet in interface definitions + {\dosingleempty\strc_itemgroups_item_tag} + +\unexpanded\def\strc_itemgroups_item_tag[#reference]% we can reuse more + {\def\currentitemreference{#reference}% + \iftrialtypesetting + \strc_counters_save\v_strc_itemgroups_counter + \strc_itemgroups_increment_item_counter + \strc_itemgroups_insert_item_tag_indeed + \strc_counters_restore\v_strc_itemgroups_counter + \else + \strc_itemgroups_increment_item_counter + \strc_itemgroups_insert_item_tag_indeed + \fi} + +\def\strc_itemgroups_insert_item_tag_indeed + {\letitemgroupparameter\c!distance\zeropoint + %letitemgroupparameter\c!width\zeropoint + \strc_itemgroups_make_symbol_box + \strc_itemgroups_make_destination_box + \let\m_strc_itemgroups_destination\empty + \ht\b_strc_itemgroups\strutheight + \dp\b_strc_itemgroups\strutdepth + \box\b_strc_itemgroups + \ignorespaces} + +%D Done again. + \setupitemgroup [\c!margin=\zeropoint, \c!leftmargin=\zeropoint, diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv index c57fb2dd6..c78cffbff 100644 --- a/tex/context/base/mkiv/strc-sec.mkiv +++ b/tex/context/base/mkiv/strc-sec.mkiv @@ -299,7 +299,7 @@ % lua interface / names and interface might change -\newconditional\c_strc_rendering_continuous % not used (mkii ?) +% \newconditional\c_strc_rendering_continuous % not used (mkii ?) \def\setstructurelevel #1#2{\clf_setstructurelevel {#1}{#2}} % name, level|parent \def\getstructurelevel #1{\clf_getstructurelevel {#1}} % name @@ -897,7 +897,7 @@ \fi\fi \fi \flushingcolumnfloatstrue - \setfalse\c_strc_sectioniong_ignore_page + \setfalse\c_strc_sectioning_ignore_page % ignorespaces prevents spaces creeping in when after=\dontleavehmode \dostarttagged\t!sectioncontent\empty \ifconditional\headisdisplay @@ -992,14 +992,14 @@ \doifelselayouttextline\v!footer{\normalexpanded{\setuplayouttext[\v!footer][\c!state=\p_footer]}}\donothing \fi} -\newcount \c_strc_sectioniong_preceding_level \c_strc_sectioniong_preceding_level\plusone +\newcount \c_strc_sectioning_preceding_level \c_strc_sectioning_preceding_level\plusone \newconditional\c_strc_sectioning_auto_break \settrue\c_strc_sectioning_auto_break -\newconditional\c_strc_sectioniong_ignore_page -\newsignal \s_strc_sectioniong_continuous_signal +\newconditional\c_strc_sectioning_ignore_page +\newsignal \s_strc_sectioning_continuous_signal \unexpanded\def\strc_sectioning_inject_continuous_signal {\ifhmode - \hskip\s_strc_sectioniong_continuous_signal\relax + \hskip\s_strc_sectioning_continuous_signal\relax \fi} % \let\dotagsectionlevel\relax @@ -1042,63 +1042,84 @@ {\ifhmode \scratchcounter\lastpenalty \unpenalty % no beauty in this - \ifdim\lastskip=\s_strc_sectioniong_continuous_signal + \ifdim\lastskip=\s_strc_sectioning_continuous_signal % no page break - \ifconditional\c_strc_sectioniong_ignore_page - \setfalse\c_strc_sectioniong_ignore_page + \ifconditional\c_strc_sectioning_ignore_page + \setfalse\c_strc_sectioning_ignore_page \else - \global\c_strc_sectioniong_preceding_level\currentheadlevel + \global\c_strc_sectioning_preceding_level\currentheadlevel \nobreak \fi - \global\settrue\c_strc_rendering_continuous + % \global\settrue\c_strc_rendering_continuous \else \penalty\scratchcounter - \global\setfalse\c_strc_rendering_continuous + % \global\setfalse\c_strc_rendering_continuous #1% \fi \else - \global\setfalse\c_strc_rendering_continue + % \global\setfalse\c_strc_rendering_continuous #1% \fi} \def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax} \def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax} +% \def\strc_sectioning_handle_page_nop +% {\edef\p_continue{\headparameter\c!continue}% +% \ifx\p_continue\v!yes +% \ifnum\previoussectioncountervalue=\zerocount +% \strc_sectioning_check_layout +% \else\ifnum\currentsectioncountervalue>\zerocount +% \strc_sectioning_check_layout +% \fi\fi +% \else +% \strc_sectioning_check_layout +% \fi} + +\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax} +%def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax} +\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\previoushead\relax} + +\let\previoushead\empty + \def\strc_sectioning_handle_page_nop {\edef\p_continue{\headparameter\c!continue}% \ifx\p_continue\v!yes - \ifnum\previoussectioncountervalue=\zerocount - \strc_sectioning_check_layout + \ifx\currenthead\previoushead % not really needed + \strc_sectioning_check_layout + \else\ifnum\previoussectioncountervalue=\zerocount + \strc_sectioning_check_layout \else\ifnum\currentsectioncountervalue>\zerocount - \strc_sectioning_check_layout - \fi\fi + \strc_sectioning_check_layout + \fi\fi\fi \else \strc_sectioning_check_layout - \fi} + \fi + \globallet\previoushead\currenthead} \def\strc_sectioning_handle_page_yes - {%[[\currenthead @\thenamedheadlevel\currenthead/prev:\previoussectioncountervalue/curr:\currentsectioncountervalue]] - \ifconditional\c_strc_sectioniong_ignore_page - \setfalse\c_strc_sectioniong_ignore_page + {\ifconditional\c_strc_sectioning_ignore_page + \setfalse\c_strc_sectioning_ignore_page \else % beware, these numbers are not yet know here \strc_sectioning_handle_page_nop \edef\p_aligntitle{\headparameter\c!aligntitle}% \ifx\p_aligntitle\v!float -\ifconditional\c_strc_sectioning_auto_break - \vspacing[\v!samepage-\currentheadlevel]% -\fi + \ifconditional\c_strc_sectioning_auto_break + \vspacing[\v!samepage-\currentheadlevel]% + \fi \headparameter\c!before\relax \indent \else \page_otr_command_flush_side_floats -\ifconditional\c_strc_sectioning_auto_break - \vspacing[\v!samepage-\currentheadlevel]% -\fi + \ifconditional\c_strc_sectioning_auto_break + \vspacing[\v!samepage-\currentheadlevel]% + \fi \headparameter\c!before\relax \fi - \global\c_strc_sectioniong_preceding_level\currentheadlevel - \fi} + \global\c_strc_sectioning_preceding_level\currentheadlevel + \fi + \globallet\previoushead\currenthead} \unexpanded\def\strc_sectioning_prevent_page_break#1% see strc-con {\ifconditional\c_strc_sectioning_auto_break diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index 2b665ee16..2c00d8c92 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -1144,4 +1144,9 @@ \let\normalstartdmath \Ustartdisplaymath \let\normalstopdmath \Ustopdisplaymath +%D For now: + +\ifdefined\protrusionboundary \else \let\protrusionboundary\boundary \fi +\ifdefined\wordboundary \else \let\wordboundary \noboundary \fi + \protect \endinput diff --git a/tex/context/base/mkiv/trac-log.lua b/tex/context/base/mkiv/trac-log.lua index 5745460cc..86557ef09 100644 --- a/tex/context/base/mkiv/trac-log.lua +++ b/tex/context/base/mkiv/trac-log.lua @@ -111,7 +111,7 @@ local direct, subdirect, writer, pushtarget, poptarget, setlogfile, settimedlog, if tex and (tex.jobname or tex.formatname) then if texio.setescape then - texio.setescape(0) + texio.setescape(0) -- or (false) end local function useluawrites() diff --git a/tex/context/base/mkiv/typo-brk.lua b/tex/context/base/mkiv/typo-brk.lua index 9bccf91ea..9fc248305 100644 --- a/tex/context/base/mkiv/typo-brk.lua +++ b/tex/context/base/mkiv/typo-brk.lua @@ -40,6 +40,9 @@ local setattr = nuts.setattr local setlink = nuts.setlink local setchar = nuts.setchar local setdisc = nuts.setdisc +local setnext = nuts.setnext +local setprev = nuts.setprev +local setboth = nuts.setboth local setsubtype = nuts.setsubtype local copy_node = nuts.copy @@ -59,12 +62,14 @@ local nodepool = nuts.pool local tasks = nodes.tasks local v_reset = interfaces.variables.reset +local v_yes = interfaces.variables.yes local implement = interfaces.implement local new_penalty = nodepool.penalty local new_glue = nodepool.glue local new_disc = nodepool.disc +local new_wordboundary = nodepool.wordboundary local nodecodes = nodes.nodecodes local kerncodes = nodes.kerncodes @@ -100,21 +105,60 @@ for i=1,#mapping do numbers[m.name] = m end -local function insert_break(head,start,before,after,kern) +-- this needs a cleanup ... maybe make all of them disc nodes + +-- todo: use boundaries + +local function withattribute(n,a) + setfield(n,"attr",a) + return n +end + +local function insert_break(head,start,stop,before,after,kern) + local a = getfield(start,"attr") if not kern then - insert_node_before(head,start,new_penalty(before)) - insert_node_before(head,start,new_glue(0)) + insert_node_before(head,start,withattribute(new_penalty(before),a)) + insert_node_before(head,start,withattribute(new_glue(0),a)) end - insert_node_after(head,start,new_glue(0)) - insert_node_after(head,start,new_penalty(after)) + insert_node_after(head,stop,withattribute(new_glue(0),a)) + insert_node_after(head,stop,withattribute(new_penalty(after),a)) end -methods[1] = function(head,start,_,kern) - local p, n = getboth(start) +methods[1] = function(head,start,stop,settings,kern) + local p, n = getboth(stop) if p and n then - insert_break(head,start,10000,0,kern) + insert_break(head,start,stop,10000,0,kern) end - return head, start + return head, stop +end + +methods[6] = function(head,start,stop,settings,kern) + local p = getprev(start) + local n = getnext(stop) + if p and n then + if kern then + insert_break(head,start,stop,10000,0,kern) + else + local l = new_wordboundary() + local d = new_disc() + local r = new_wordboundary() + setfield(d,"attr",getfield(start,"attr")) -- otherwise basemode is forces and we crash + setlink(p,l) + setlink(l,d) + setlink(d,r) + setlink(r,n) + if start == stop then + setboth(start) + setdisc(d,start,nil,copy_node(start)) + else + setprev(start) + setnext(stop) + setdisc(d,start,nil,copy_nodelist(start)) + end + stop = r + end + end + return head, stop end methods[2] = function(head,start) -- ( => (- @@ -131,7 +175,7 @@ methods[2] = function(head,start) -- ( => (- setchar(hyphen,languages.prehyphenchar(getfield(tmp,"lang"))) setlink(tmp,hyphen) setfield(start,"post",tmp) - insert_break(head,start,10000,10000) + insert_break(head,start,start,10000,10000) end return head, start end @@ -150,7 +194,7 @@ methods[3] = function(head,start) -- ) => -) setchar(hyphen,languages.prehyphenchar(getfield(tmp,"lang"))) setlink(hyphen,tmp) setfield(start,"pre",hyphen) - insert_break(head,start,10000,10000) + insert_break(head,start,start,10000,10000) end return head, start end @@ -164,12 +208,12 @@ methods[4] = function(head,start) -- - => - - - -- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do setfield(start,"attr",getfield(tmp,"attr")) setdisc(start,copy_node(tmp),copy_node(tmp),tmp) - insert_break(head,start,10000,10000) + insert_break(head,start,start,10000,10000) end return head, start end -methods[5] = function(head,start,settings) -- x => p q r +methods[5] = function(head,start,stop,settings) -- x => p q r local p, n = getboth(start) if p and n then local tmp @@ -193,7 +237,7 @@ methods[5] = function(head,start,settings) -- x => p q r -- setfield(start,"attr",copy_nodelist(attr)) -- todo: critical only -- just a copy will do setfield(start,"attr",attr) -- todo: critical only -- just a copy will do free_node(tmp) - insert_break(head,start,10000,10000) + insert_break(head,start,start,10000,10000) end return head, start end @@ -227,17 +271,43 @@ function breakpoints.handler(head) if cmap then -- for now we collect but when found ok we can move the handler here -- although it saves nothing in terms of performance - local d = { current, cmap } - if done then - done[#done+1] = d + local lang = getfield(current,"lang") + local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""]) + if smap then + local skip = smap.skip + local start = current + local stop = current + current = getnext(current) + if skip then + while current do + local c = isglyph(current) + if c == char then + stop = current + current = getnext(current) + else + break + end + end + end + local d = { start, stop, cmap, smap, char } + if done then + done[#done+1] = d + else + done = { d } + end else - done = { d } + current = getnext(current) end - setattr(current,a_breakpoints,unsetvalue) -- should not be needed + setattr(start,a_breakpoints,unsetvalue) -- should not be needed + else + current = getnext(current) end + else + current = getnext(current) end + else + current = getnext(current) end - current = getnext(current) elseif id == math_code then attr = nil current = end_of_math(current) @@ -254,16 +324,18 @@ function breakpoints.handler(head) -- we have hits local numbers = languages.numbers for i=1,#done do - local data = done[i] - local current = data[1] - local cmap = data[2] - local lang = getfield(current,"lang") - -- we do a sanity check for language - local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""]) - if smap then + local data = done[i] + local start = data[1] + local stop = data[2] + local cmap = data[3] + local smap = data[4] +-- local lang = getfield(start,"lang") +-- -- we do a sanity check for language +-- local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""]) +-- if smap then local nleft = smap.nleft local cleft = 0 - local prev = getprev(current) + local prev = getprev(start) local kern = nil while prev and nleft ~= cleft do local id = getid(prev) @@ -289,7 +361,7 @@ function breakpoints.handler(head) if nleft == cleft then local nright = smap.nright local cright = 0 - local next = getnext(current) + local next = getnext(stop) -- getnext(start) while next and nright ~= cright do local char, id = isglyph(next) if char then @@ -317,10 +389,10 @@ function breakpoints.handler(head) if nright == cright then local method = methods[smap.type] if method then - nead, start = method(nead,current,smap,kern) + nead, start = method(nead,start,stop,smap,kern) end end - end +-- end end end return tonode(nead), true @@ -362,6 +434,7 @@ function breakpoints.setreplacement(name,char,language,settings) left = left ~= "" and left or nil, right = right ~= "" and right or nil, middle = middle ~= "" and middle or nil, + skip = settings.range == v_yes, } -- was { type or 1, before or 1, after or 1 } end end @@ -412,6 +485,7 @@ implement { { "right" }, { "left" }, { "middle" }, + { "range" }, } } } diff --git a/tex/context/base/mkiv/typo-brk.mkiv b/tex/context/base/mkiv/typo-brk.mkiv index 55f4d8466..3f9ce6f3a 100644 --- a/tex/context/base/mkiv/typo-brk.mkiv +++ b/tex/context/base/mkiv/typo-brk.mkiv @@ -38,7 +38,10 @@ \def\typo_breakpoints_define_character[#1][#2][#3]% name char settings {\begingroup - \getdummyparameters[\c!type=\plusone,\c!nleft=\plusthree,\c!nright=\plusthree,\s!language=,\c!left=,\c!right=,\c!middle=,#3]% + \getdummyparameters + [\c!type=\plusone,\c!nleft=\plusthree,\c!nright=\plusthree,% + \s!language=,\c!left=,\c!right=,\c!middle=,\c!range=\v!no,% + #3]% \clf_definebreakpoint {#1}% {#2}% @@ -50,6 +53,7 @@ right {\directdummyparameter\c!right}% left {\directdummyparameter\c!left}% middle {\directdummyparameter\c!middle}% + range {\directdummyparameter\c!range}% }% \relax \endgroup} @@ -63,11 +67,15 @@ \definebreakpoints[compound] -\definebreakpoint [compound] [+] [\c!nleft=3,\c!nright=3,\c!type=1] % middle=+,left=,right= -\definebreakpoint [compound] [-] [\c!nleft=3,\c!nright=3,\c!type=1] % middle=+,left=,right= -\definebreakpoint [compound] [/] [\c!nleft=3,\c!nright=3,\c!type=1] % middle=+,left=,right= -\definebreakpoint [compound] [(] [\c!nleft=3,\c!nright=3,\c!type=2] % type=5,middle=(,left=(-,right= -\definebreakpoint [compound] [)] [\c!nleft=3,\c!nright=3,\c!type=3] % type=5,middle=),left=,right=-) +% 1: simple break +% 6: simple break but skip same + +\definebreakpoint [compound] [+] [\c!nleft=3,\c!nright=3,\c!type=1] % middle=+,left=,right= +%definebreakpoint [compound] [-] [\c!nleft=3,\c!nright=3,\c!type=1,\c!range=\v!yes] % middle=+,left=,right= +\definebreakpoint [compound] [-] [\c!nleft=3,\c!nright=3,\c!type=6,\c!range=\v!yes] % middle=+,left=,right= +\definebreakpoint [compound] [/] [\c!nleft=3,\c!nright=3,\c!type=1] % middle=+,left=,right= +\definebreakpoint [compound] [(] [\c!nleft=3,\c!nright=3,\c!type=2] % type=5,middle=(,left=(-,right= +\definebreakpoint [compound] [)] [\c!nleft=3,\c!nright=3,\c!type=3] % type=5,middle=),left=,right=-) \let\installbreakpoint\definebreakpoint % for a while diff --git a/tex/context/base/mkiv/typo-itc.lua b/tex/context/base/mkiv/typo-itc.lua index a46f3e8a0..cf54187d7 100644 --- a/tex/context/base/mkiv/typo-itc.lua +++ b/tex/context/base/mkiv/typo-itc.lua @@ -283,7 +283,7 @@ function italics.handler(head) postinserted = nil postitalic = 0 updated = false - pre, post, replace, pretail, posttail, replacetail = getdisc(current) + pre, post, replace, pretail, posttail, replacetail = getdisc(current,true) if replace then local current = replacetail while current do -- cgit v1.2.3