From c32e3ec991b2c70bb8ccf2db6f2c409dbe745de5 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 28 Jan 2014 16:20:15 +0200 Subject: beta 2014.01.28 15:12 --- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4086 -> 4086 bytes tex/context/base/context.mkiv | 2 +- tex/context/base/lang-rep.lua | 98 ++++++++++++++-- tex/context/base/lang-rep.mkiv | 10 +- tex/context/base/node-typ.lua | 14 ++- tex/context/base/publ-aut.lua | 130 +++++++-------------- tex/context/base/publ-ini.lua | 56 +++++---- tex/context/base/publ-ini.mkiv | 8 +- tex/context/base/sort-ini.lua | 13 ++- tex/context/base/status-files.pdf | Bin 24856 -> 24824 bytes tex/context/base/status-lua.pdf | Bin 233977 -> 233981 bytes tex/context/base/typo-itc.lua | 27 ++++- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 14 files changed, 222 insertions(+), 140 deletions(-) (limited to 'tex') diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 8a1c0f6c1..2d3973b12 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2014.01.27 14:25} +\newcontextversion{2014.01.28 15:12} %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/context-version.pdf b/tex/context/base/context-version.pdf index 701e88482..57f261af3 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 484c7f32c..dca07e787 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -28,7 +28,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2014.01.27 14:25} +\edef\contextversion{2014.01.28 15:12} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/lang-rep.lua b/tex/context/base/lang-rep.lua index fb136b551..be74d597a 100644 --- a/tex/context/base/lang-rep.lua +++ b/tex/context/base/lang-rep.lua @@ -7,9 +7,21 @@ if not modules then modules = { } end modules ['lang-rep'] = { } -- A BachoTeX 2013 experiment, probably not that useful. Eventually I used a simpler --- more generic example. +-- more generic example. I'm sure no one ever notices of even needs this code. +-- +-- As a follow up on a question by Alan about special treatment of dropped caps I wonder +-- if I can make this one more clever (probably in a few more dev steps). For instance +-- injecting nodes or replacing nodes. It's a prelude to a kind of lpeg for nodes, +-- although (given experiences so far) we don't really need that. After all, each problem +-- is somewhat unique. +local type = type local utfbyte, utfsplit = utf.byte, utf.split +local P, C, U, Cc, Ct, lpegmatch = lpeg.P, lpeg.C, lpeg.patterns.utf8character, lpeg.Cc, lpeg.Ct, lpeg.match +local find = string.find + +local grouped = P("{") * ( Ct((U/utfbyte-P("}"))^1) + Cc(false) ) * P("}")-- grouped +local splitter = Ct((Ct(Cc("discretionary") * grouped * grouped * grouped) + U/utfbyte)^1) local trace_replacements = false trackers.register("languages.replacements", function(v) trace_replacements = v end) local trace_detail = false trackers.register("languages.replacements.detail", function(v) trace_detail = v end) @@ -24,6 +36,7 @@ local tonode = nuts.tonode local setfield = nuts.setfield local getnext = nuts.getnext +local getprev = nuts.getprev local getattr = nuts.getattr local getid = nuts.getid local getchar = nuts.getchar @@ -31,6 +44,12 @@ local getchar = nuts.getchar local insert_node_before = nuts.insert_before local remove_node = nuts.remove local copy_node = nuts.copy +local flush_list = nuts.flush_list +local insert_after = nuts.insert_after + +local nodepool = nuts.pool +local new_glyph = nodepool.glyph +local new_disc = nodepool.disc local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -56,6 +75,8 @@ table.setmetatableindex(lists,function(lists,name) return data end) +-- todo: glue kern + local function add(root,word,replacement) local list = utfsplit(word,true) local size = #list @@ -65,15 +86,19 @@ local function add(root,word,replacement) root[l] = { } end if i == size then - local newlist = utfsplit(replacement,true) - for i=1,#newlist do - newlist[i] = utfbyte(newlist[i]) - end + -- local newlist = utfsplit(replacement,true) + -- for i=1,#newlist do + -- newlist[i] = utfbyte(newlist[i]) + -- end + local special = find(replacement,"{") + local newlist = lpegmatch(splitter,replacement) + -- root[l].final = { word = word, replacement = replacement, oldlength = size, newcodes = newlist, + special = special, } end root = root[l] @@ -124,6 +149,21 @@ local function hit(a,head) end end +local function tonodes(list,template) + local head, current + for i=1,#list do + local new = copy_node(template) + setfield(new,"char",list[i]) + if head then + head, current = insert_after(head,current,new) + else + head, current = new, new + end + end + return head +end + + function replacements.handler(head) head = tonut(head) local current = head @@ -137,10 +177,54 @@ function replacements.handler(head) local oldlength = final.oldlength local newcodes = final.newcodes local newlength = #newcodes - if report_replacement then + if trace_replacement then report_replacement("replacing word %a by %a",final.word,final.replacement) end - if oldlength == newlength then -- #old == #new + if final.special then + -- easier is to delete and insert (a simple callout to tex would be more efficient) + -- maybe just walk over a replacement string instead + local prev = getprev(current) + local next = getnext(last) + local list = current + setfield(last,"next",nil) + setfield(prev,"next",next) + if next then + setfield(next,"prev",prev) + end + current = prev + if not current then + head = nil + end + for i=1,newlength do + local codes = newcodes[i] + local new = nil + if type(codes) == "table" then + local method = codes[1] + if method == "discretionary" then + local pre, post, replace = codes[2], codes[3], codes[4] + new = new_disc() + if pre then + setfield(new,"pre",tonodes(pre,last)) + end + if post then + setfield(new,"post",tonodes(post,last)) + end + if replace then + setfield(new,"replace",tonodes(replace,last)) + end + else + -- todo + end + else + new = copy_node(last) + setfield(new,"char",codes) + end + if new then + head, current = insert_after(head,current,new) + end + end + flush_list(list) + elseif oldlength == newlength then -- #old == #new for i=1,newlength do setfield(current,"char",newcodes[i]) current = getnext(current) diff --git a/tex/context/base/lang-rep.mkiv b/tex/context/base/lang-rep.mkiv index da5aa955c..b3f21f22a 100644 --- a/tex/context/base/lang-rep.mkiv +++ b/tex/context/base/lang-rep.mkiv @@ -25,12 +25,15 @@ %D \startluacode %D +%D -- todo: other nodes (prelude to more experiments with auto dropped caps) +%D %D languages.replacements.add("basics", { %D ["aap"] = "monkey", %D ["noot"] = "nut", %D ["never"] = "forever", %D ["newer"] = "cooler", %D ["new"] = "cool", +%D -- ["special"] = "veryspe{>>>}{<<<}{=}cial", %D }) %D %D \stopluacode @@ -38,10 +41,13 @@ %D \replaceword[more][this][that] %D \replaceword[more][crap][support] %D \replaceword[more][---][—] +%D \replaceword[basics][special][veryspe{>>>}{<<<}{=}cial] %D %D \starttyping -%D \start \setreplacements[basics] What the heck, it's now or never, isn't it new? \stop \par -%D \start \setreplacements[more] Do we --- {\it really} --- need this kind of crap? \stop \par +%D \start \setreplacements[basics] What the heck, it's now or never, isn't it new? \par \stop +%D \start \setreplacements[more] Do we --- {\it really} --- need this kind of crap? \par \stop +%D \start \setreplacements[basics] All kinds of special thingies! \par \stop +%D \start \setreplacements[basics] \hsize1mm special \par \stop %D \stoptyping \unexpanded\def\setreplacements[#1]% diff --git a/tex/context/base/node-typ.lua b/tex/context/base/node-typ.lua index 5a4dfe4be..4c33e3199 100644 --- a/tex/context/base/node-typ.lua +++ b/tex/context/base/node-typ.lua @@ -16,10 +16,12 @@ local tonode = nuts.tonode local tonut = nuts.tonut local setfield = nuts.setfield +local getfont = nuts.getfont local hpack_node_list = nuts.hpack local vpack_node_list = nuts.vpack local fast_hpack_list = nuts.fasthpack +local copy_node = nuts.copy local nodepool = nuts.pool local new_glyph = nodepool.glyph @@ -30,10 +32,14 @@ local utfvalues = utf.values local currentfont = font.current local fontparameters = fonts.hashes.parameters -local function tonodes(str,fontid,spacing) -- quick and dirty +local function tonodes(str,fontid,spacing,templateglyph) -- quick and dirty local head, prev = nil, nil if not fontid then - fontid = currentfont() + if templateglyph then + fontid = getfont(templateglyph) + else + fontid = currentfont() + end end local fp = fontparameters[fontid] local s, p, m @@ -50,6 +56,10 @@ local function tonodes(str,fontid,spacing) -- quick and dirty next = new_glue(s,p,m) spacedone = true end + elseif templateglyph then + next = copy_glyph(templateglyph) + setfield(next,"char",c) + spacedone = false else next = new_glyph(fontid or 1,c) spacedone = false diff --git a/tex/context/base/publ-aut.lua b/tex/context/base/publ-aut.lua index 0fc2670c4..9fe286abf 100644 --- a/tex/context/base/publ-aut.lua +++ b/tex/context/base/publ-aut.lua @@ -457,62 +457,7 @@ local strip = sorters.strip local splitter = sorters.splitters.utf local sort = sorters.sort --- function authors.preparedsort(dataset,list,sorttype) --- local luadata = datasets[dataset].luadata --- local details = datasets[dataset].details --- local valid = { } --- for i=1,#list do --- local tag = list[i] --- local entry = luadata[tag] --- local detail = details[tag] --- local suffix = tostring(i) --- local split = nil --- if entry and detail then --- local key = detail[sorttype] --- local year = entry.year or 9998 --- if key then --- split = { } --- local n = #key --- if n > 0 then --- -- least efficient --- for i=1,n do --- local k = key[i] --- local vons = k.vons --- local surs = k.surnames --- local vons = vons and concat(vons," ") --- local surs = surs and concat(surs," ") or "" --- local assembled = (vons and #vons > 0 and vons .. " " .. surs) or surs --- split[i] = splitter(strip(assembled),true) --- end --- split[n+1] = splitter(year,true) --- split[n+2] = splitter(suffix,true) --- else --- -- medium efficient --- local k = key[1] --- local vons = k.vons --- local surs = k.surnames --- local vons = vons and concat(vons," ") --- local surs = surs and concat(surs," ") or "" --- local assembled = ((vons and #vons > 0 and vons .. " " .. surs) or surs) .. ":" .. year .. ":" ..suffix --- split = splitter(strip(assembled),true) --- end --- else --- -- efficient fallback --- split = splitter(year .. ":" .. suffix,true) --- end --- else --- -- efficient fallback --- split = splitter("9999:" .. suffix,true) --- end --- valid[i] = { --- index = i, --- split = split, --- } --- end --- return valid --- end - -function authors.preparedsort(dataset,list,sorttype) +function authors.preparedsort(dataset,list,sorttype_a,sorttype_b,sorttype_c) local luadata = datasets[dataset].luadata local details = datasets[dataset].details local valid = { } @@ -522,50 +467,57 @@ function authors.preparedsort(dataset,list,sorttype) t[k] = v return v end) + local snippets = { } for i=1,#list do - local tag = list[i] - local entry = luadata[tag] - local detail = details[tag] - local suffix = tostring(i) + -- either { tag, tag, ... } or { { tag, index }, { tag, index } } + local li = list[i] + local tag = type(li) == "string" and li or li[1] + local entry = luadata[tag] + local detail = details[tag] + local suffix = tostring(i) + local year = nil + local assembled = nil if entry and detail then - local key = detail[sorttype] - local year = entry.year or "9998" + local key = detail[sorttype_a] or detail[sorttype_b] or detail[sorttype_c] if key then + -- maybe an option is to also sort the authors first local n = #key - local split = { } + local s = 0 for i=1,n do local k = key[i] - local vons = k.vons - local surs = k.surnames - local vons = vons and concat(vons," ") - local surs = surs and concat(surs," ") or "" - local assembled = (vons and #vons > 0 and vons .. " " .. surs) or surs - split[i] = splitted[strip(assembled)] + local vons = k.vons + local surnames = k.surnames + local initials = k.initials + if vons and #vons > 0 then + s = s + 1 ; snippets[s] = concat(vons," ") + end + if surnames and #surnames > 0 then + s = s + 1 ; snippets[s] = concat(surnames," ") + end + if initials and #initials > 0 then + s = s + 1 ; snippets[s] = concat(initials," ") + end end - split[n+1] = splitted[year] - split[n+2] = splitted[suffix] - valid[i] = { - index = i, - split = split, - } + assembled = concat(snippets," ",1,s) else - valid[i] = { - index = i, - split = { - splitted[year], - splitted[suffix], - } - } + assembled = "" end + year = entry.year or "9998" else - valid[i] = { - index = i, - split = { - splitted["9999"], - splitted[suffix], - }, - } + assembled = "" + year = "9999" end + valid[i] = { + index = i, + split = { + splitted[strip(assembled)], + splitted[year], + splitted[suffix], + }, +-- names = assembled, +-- year = year, +-- suffix = suffix, + } end return valid end diff --git a/tex/context/base/publ-ini.lua b/tex/context/base/publ-ini.lua index 13177b299..534bca72e 100644 --- a/tex/context/base/publ-ini.lua +++ b/tex/context/base/publ-ini.lua @@ -40,9 +40,10 @@ local v_inbetween = variables.inbetween local v_short = variables.short local v_cite = variables.cite local v_default = variables.default -local v_reference = variables.default +local v_reference = variables.reference local v_dataset = variables.dataset local v_author = variables.author or "author" +local v_editor = variables.editor or "editor" local numbertochar = converters.characters @@ -51,6 +52,12 @@ local logspushtarget = logs.pushtarget local logspoptarget = logs.poptarget local csname_id = token.csname_id +local basiccompare = sorters.basicsorter -- (a,b) +local compare = sorters.comparers.basic -- (a,b) +local strip = sorters.strip +local splitter = sorters.splitters.utf +local sort = sorters.sort + local context = context local ctx_btxlistparameter = context.btxlistparameter @@ -296,7 +303,7 @@ function publications.enhance(dataset) -- for the moment split runs (maybe publi end for short, tags in next, shorts do if type(tags) == "table" then - table.sort(tags) + sort(tags) for i=1,#tags do details[tags[i]].short = short .. numbertochar(i) end @@ -778,28 +785,30 @@ lists.sorters = { end sort(list,compare) end, - [v_default] = function(dataset,rendering,list) -- not really needed - local ordered = rendering.ordered - local function compare(a,b) - local aa, bb = a and a[1], b and b[1] - if aa and bb then - aa, bb = ordered[aa], ordered[bb] - return aa and bb and aa < bb - end - return false - end - sort(list,compare) - end, + -- [v_default] = function(dataset,rendering,list) -- not really needed + -- local ordered = rendering.ordered + -- local function compare(a,b) + -- local aa, bb = a and a[1], b and b[1] + -- if aa and bb then + -- aa, bb = ordered[aa], ordered[bb] + -- return aa and bb and aa < bb + -- end + -- return false + -- end + -- sort(list,compare) + -- end, [v_author] = function(dataset,rendering,list) - local valid = publications.authors.preparedsort(dataset,list,v_author) + local valid = publications.authors.preparedsort(dataset,list,v_author,v_editor) if #valid == 0 or #valid ~= #list then -- nothing to sort else -- if needed we can wrap compare and use the list directly but this is cleaner - sort(valid,sorters.comparers.basic) + sort(valid,compare) for i=1,#valid do - list[i] = valid[i].index + local v = valid[i] + valid[i] = list[v.index] end + return valid end end, } @@ -807,8 +816,10 @@ lists.sorters = { function lists.flushentries(dataset,sortvariant) local rendering = renderings[dataset] local list = rendering.list - local compare = lists.sorters[sortvariant] or lists.sorters[v_default] - compare = type(compare) == "function" and compare(dataset,rendering,list) + local sort = lists.sorters[sortvariant] or lists.sorters[v_default] + if type(sort) == "function" then + list = sort(dataset,rendering,list) or list + end for i=1,#list do ctx_setvalue("currentbtxindex",i) ctx_btxhandlelistentry(list[i][1]) -- we can pass i here too ... more efficient to avoid the setvalue @@ -1018,11 +1029,6 @@ publications.citevariants = citevariants -- helper -local compare = sorters.comparers.basic -- (a,b) -local strip = sorters.strip -local splitter = sorters.splitters.utf -local sort = sorters.sort - local function sortedtags(dataset,list,sorttype) local luadata = datasets[dataset].luadata local valid = { } @@ -1043,7 +1049,7 @@ local function sortedtags(dataset,list,sorttype) if #valid == 0 or #valid ~= #list then return list else - sort(valid,sorters.comparers.basic) + sort(valid,basiccompare) for i=1,#valid do valid[i] = valid[i].tag end diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv index 6d3d09696..34e628148 100644 --- a/tex/context/base/publ-ini.mkiv +++ b/tex/context/base/publ-ini.mkiv @@ -141,15 +141,15 @@ \c!before=\blank, \c!inbetween=\blank, \c!after=\blank, - \c!indentnext=\v!yes, - \c!indenting=\v!never, + %\c!indentnext=\v!yes, + %\c!indenting=\v!never, %\c!titleleft=(, %\c!titleright=), %\c!closesymbol=, %\c!closecommand=\wordright, \c!display=\v!yes, - %\c!command=, - \c!titlecommand=, + \c!command=, + %\c!titlecommand=, %\c!expansion=\v!no, %\c!xmlsetup=, %\s!catcodes=, diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua index 2a3ea1e89..d279f1253 100644 --- a/tex/context/base/sort-ini.lua +++ b/tex/context/base/sort-ini.lua @@ -82,7 +82,7 @@ local v_first = variables.first local v_last = variables.last local validmethods = table.tohash { - -- "ch", -- raw character + "ch", -- raw character (for tracing) "mm", -- minus mapping "zm", -- zero mapping "pm", -- plus mapping @@ -336,6 +336,7 @@ local function setlanguage(l,m,d,u) data.sequence = sequence usedinsequence = table.tohash(sequence) data.usedinsequence = usedinsequence +-- usedinsequence.ch = true -- better just store the string if trace_tests then report_sorters("using sort sequence: % t",sequence) end @@ -376,7 +377,7 @@ end -- todo: compile compare function -function comparers.basic(a,b) -- trace ea and eb +local function basic(a,b) -- trace ea and eb local ea, eb = a.split, b.split local na, nb = #ea, #eb if na == 0 and nb == 0 then @@ -436,6 +437,12 @@ function comparers.basic(a,b) -- trace ea and eb end end +comparers.basic = basic + +function sorters.basicsorter(a,b) + return basic(a,b) == -1 +end + local function numify(s) s = digitsoffset + tonumber(s) -- alternatively we can create range if s > digitsmaximum then @@ -587,7 +594,7 @@ function splitters.utf(str,checked) -- we could append m and u but this is clean if checked then return { - ch = usedinsequence.ch and char or nil, -- not in sequence + ch = trace_tests and char or nil, -- not in sequence uc = usedinsequence.uc and byte or nil, mc = usedinsequence.mc and m_case or nil, zc = usedinsequence.zc and z_case or nil, diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 15f809651..99439fdce 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 290657b7d..471081c36 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/typo-itc.lua b/tex/context/base/typo-itc.lua index 997190675..db94c5c54 100644 --- a/tex/context/base/typo-itc.lua +++ b/tex/context/base/typo-itc.lua @@ -9,9 +9,10 @@ if not modules then modules = { } end modules ['typo-itc'] = { local utfchar = utf.char local trace_italics = false trackers.register("typesetters.italics", function(v) trace_italics = v end) - local report_italics = logs.reporter("nodes","italics") +local threshold = 0.5 trackers.register("typesetters.threshold", function(v) threshold = v == true and 0.5 or tonumber(v) end) + typesetters.italics = typesetters.italics or { } local italics = typesetters.italics @@ -52,6 +53,7 @@ local new_correction_glue = nodepool.glue local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers local italicsdata = fonthashes.italics +local exheights = fonthashes.exheights local forcedvariant = false @@ -118,11 +120,25 @@ function italics.handler(head) report_italics("ignoring %p between italic %C and italic %C",italic,prevchar,char) end else - if trace_italics then - report_italics("inserting %p between italic %C and regular %C",italic,prevchar,char) + local okay = true + if threshold then + local ht = getfield(current,"height") + local ex = exheights[font] + local th = threshold * ex + if ht <= th then + if trace_italics then + report_italics("ignoring correction between italic %C and regular %C, height %p less than threshold %p",prevchar,char,ht,th) + end + okay = false + end + end + if okay then + if trace_italics then + report_italics("inserting %p between italic %C and regular %C",italic,prevchar,char) + end + insert_node_after(head,previous,new_correction_kern(italic)) + done = true end - insert_node_after(head,previous,new_correction_kern(italic)) - done = true end elseif inserted and data then if trace_italics then @@ -238,6 +254,7 @@ function commands.setupitaliccorrection(option) -- no grouping ! elseif options[variables.always] then variant = 2 end + -- maybe also keywords for threshold if options[variables.global] then forcedvariant = variant texsetattribute(a_italics,unsetvalue) diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index d9bc04aa7..5bad2140b 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 : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 01/27/14 14:25:59 +-- merge date : 01/28/14 15:12:08 do -- begin closure to overcome local limits and interference -- cgit v1.2.3