From 59947aaf3bf2ad07251a569a77338c8c41f9e377 Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Wed, 29 Apr 2015 20:15:05 +0200 Subject: 2015-04-29 19:33:00 --- tex/context/base/back-exp.lua | 9 + tex/context/base/buff-ini.mkiv | 3 + tex/context/base/char-ini.mkiv | 5 +- tex/context/base/char-tex.lua | 2 +- tex/context/base/colo-imp-rgb.mkiv | 4 +- tex/context/base/colo-ini.lua | 25 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4187 -> 4189 bytes tex/context/base/context.mkiv | 7 +- tex/context/base/font-col.lua | 19 + tex/context/base/font-ctx.lua | 83 ++- tex/context/base/font-lib.mkvi | 14 +- tex/context/base/font-nod.lua | 9 +- tex/context/base/font-pre.mkiv | 17 + tex/context/base/font-sol.lua | 2 +- tex/context/base/l-lpeg.lua | 40 +- tex/context/base/l-unicode.lua | 12 +- tex/context/base/lpdf-xmp.lua | 5 +- tex/context/base/lxml-aux.lua | 20 +- tex/context/base/lxml-ini.lua | 1 + tex/context/base/lxml-ini.mkiv | 2 + tex/context/base/lxml-tab.lua | 81 ++- tex/context/base/lxml-tex.lua | 16 +- tex/context/base/math-tag.lua | 2 +- tex/context/base/meta-ini.mkiv | 12 +- tex/context/base/mlib-int.lua | 10 +- tex/context/base/mtx-context-listing.tex | 3 +- tex/context/base/mult-def.mkiv | 2 + tex/context/base/mult-sys.mkiv | 1 + tex/context/base/node-ltp.lua | 20 +- tex/context/base/node-nut.lua | 36 ++ tex/context/base/node-ppt.lua | 2 +- tex/context/base/node-ref.lua | 1 - tex/context/base/pack-rul.mkiv | 13 +- tex/context/base/page-grd.mkiv | 35 +- tex/context/base/page-mix.lua | 25 +- tex/context/base/page-mix.mkiv | 83 ++- tex/context/base/page-set.mkiv | 2 - tex/context/base/page-sid.mkiv | 12 +- tex/context/base/publ-aut.lua | 576 ++++++++++++++------ tex/context/base/publ-dat.lua | 22 +- tex/context/base/publ-fnd.lua | 87 --- tex/context/base/publ-imp-apa.lua | 6 +- tex/context/base/publ-imp-apa.mkvi | 189 ++++--- tex/context/base/publ-imp-aps.lua | 2 +- tex/context/base/publ-imp-aps.mkvi | 98 ++-- tex/context/base/publ-imp-cite.mkvi | 186 +++---- tex/context/base/publ-imp-default.mkvi | 144 +---- tex/context/base/publ-imp-list.mkvi | 42 +- tex/context/base/publ-imp-page.mkvi | 4 +- tex/context/base/publ-ini.lua | 600 +++++++++++---------- tex/context/base/publ-ini.mkiv | 284 +++++----- tex/context/base/publ-jrn.lua | 1 + tex/context/base/publ-sor.lua | 64 ++- tex/context/base/publ-tra.lua | 6 +- tex/context/base/publ-tra.mkiv | 4 - tex/context/base/publ-usr.lua | 10 +- tex/context/base/sort-ini.lua | 20 +- tex/context/base/spac-def.mkiv | 2 +- tex/context/base/spac-prf.mkiv | 31 ++ tex/context/base/spac-ver.lua | 34 +- tex/context/base/spac-ver.mkiv | 90 +++- tex/context/base/status-files.pdf | Bin 24437 -> 24402 bytes tex/context/base/status-lua.pdf | Bin 250375 -> 250705 bytes tex/context/base/strc-flt.mkvi | 9 +- tex/context/base/strc-ref.lua | 6 +- tex/context/base/strc-sec.mkiv | 14 +- tex/context/base/supp-ran.lua | 64 ++- tex/context/base/supp-ran.mkiv | 11 +- tex/context/base/tabl-xtb.lua | 5 +- tex/context/base/task-ini.lua | 10 +- tex/context/base/trac-vis.lua | 25 +- tex/context/base/trac-vis.mkiv | 17 +- tex/context/base/x-asciimath.lua | 1 + tex/generic/context/luatex/luatex-fonts-merged.lua | 27 +- 75 files changed, 1945 insertions(+), 1383 deletions(-) create mode 100644 tex/context/base/spac-prf.mkiv (limited to 'tex') diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua index a4127e6be..4b3f83a3d 100644 --- a/tex/context/base/back-exp.lua +++ b/tex/context/base/back-exp.lua @@ -2836,6 +2836,7 @@ local xmlpreamble = [[ exporter version : %exportversion% --> + ]] local flushtree = wrapups.flushtree @@ -3332,6 +3333,14 @@ local htmltemplate = [[ -- representation that uses verbose element names and carries information in -- attributes + + local data = tree.data + for i=1,#data do + if data[i].tg ~= "document" then + data[i] = { } + end + end + local result = allcontent(tree) local results = concat { diff --git a/tex/context/base/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv index 24bb729e1..c10680085 100644 --- a/tex/context/base/buff-ini.mkiv +++ b/tex/context/base/buff-ini.mkiv @@ -197,6 +197,9 @@ \unexpanded\def\buff_get_stored_inline_indeed#1% {\ignorespaces\clf_getbuffer{#1}\removeunwantedspaces} +\def\rawbuffer#1% expandable + {\clf_getbuffer{#1}} + \definebuffer [\v!hiding] diff --git a/tex/context/base/char-ini.mkiv b/tex/context/base/char-ini.mkiv index bb4483b75..95ff7af5a 100644 --- a/tex/context/base/char-ini.mkiv +++ b/tex/context/base/char-ini.mkiv @@ -47,7 +47,10 @@ \def\checkedchar {\relax\ifmmode\expandafter\checkedmathchar\else\expandafter\checkedtextchar\fi} % #1#2 \def\checkedmathchar#1#2{#2} -\def\checkedtextchar #1{\iffontchar\font#1 \expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi{\char#1}} +%def\checkedtextchar #1{\iffontchar\font#1 \expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi{\char#1}} + +\unexpanded\def\checkedtextchar#1% #2% + {\clf_doifelsecharinfont\numexpr#1\relax{\char#1}} % {#2} \unexpanded\def\textormathchar#1% {\relax\ifmmode diff --git a/tex/context/base/char-tex.lua b/tex/context/base/char-tex.lua index 48dccfe79..62bb6a041 100644 --- a/tex/context/base/char-tex.lua +++ b/tex/context/base/char-tex.lua @@ -281,7 +281,7 @@ local commandmapping = allocate { ["l"] = "ł", ["L"] = "Ł", ["o"] = "ø", ["O"] = "Ø", ["oe"] = "œ", ["OE"] = "Œ", - ["sz"] = "ß", ["SZ"] = "SZ", ["SS"] = "ß", + ["sz"] = "ß", ["SZ"] = "SZ", ["ss"] = "ß", ["SS"] = "ß", } texcharacters.commandmapping = commandmapping diff --git a/tex/context/base/colo-imp-rgb.mkiv b/tex/context/base/colo-imp-rgb.mkiv index dd14cc7d2..d7b691fcc 100644 --- a/tex/context/base/colo-imp-rgb.mkiv +++ b/tex/context/base/colo-imp-rgb.mkiv @@ -268,6 +268,8 @@ %D Bonus (needed for FO test): -\definecolor [orange] [r=1,g=.5] +\definecolor [orange] [r=1, g=.5] +\definecolor [middleorange] [r=.6,g=.3] +\definecolor [darkorange] [r=.4,g=.2] \endinput diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index 1065aadc0..81adfa680 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -997,7 +997,10 @@ do if model and model ~= 0 then model = model else - model = forcedmodel(cv[1]) + model = forcedmodel(texgetattribute(a_colorspace)) + if model == 1 then + model = cv[1] + end end if model == 3 then str = formatters["{rgb}{%1.3f,%1.3f,%1.3f}"](cv[3],cv[4],cv[5]) @@ -1021,26 +1024,6 @@ do arguments = { "integer", "integer" } } - -- function commands.pgfregistercolor(name,attribute) - -- local cv = colorvalues[ca] - -- context.pushcatcodes('prt') - -- if cv then - -- local model = forcedmodel(cv[1]) - -- if model == 2 then - -- context["pgfutil@definecolor"]("{%s}{gray}{%1.3f}",name,cv[2]) - -- elseif model == 3 then - -- context["pgfutil@definecolor"]("{%s}{rgb}{%1.3f,%1.3f,%1.3f}",name,cv[3],cv[4],cv[5]) - -- elseif model == 4 then - -- context["pgfutil@definecolor"]("{%s}{cmyk}{%1.3f,%1.3f,%1.3f,%1.3f}",name,cv[6],cv[7],cv[8],cv[9]) - -- else - -- context["pgfutil@definecolor"]("{%s}{gray}{0}",name) - -- end - -- else - -- context["pgfutil@definecolor"]("{%s}{gray}{0}",name) - -- end - -- context.popcatcodes() - -- end - end -- handy diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 2b7028e33..7e42d8606 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{2015.04.18 14:41} +\newcontextversion{2015.04.29 19:31} %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 9aee6f9bf..b9c48e16c 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 034b403c4..977dfb769 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2015.04.18 14:41} +\edef\contextversion{2015.04.29 19:31} \edef\contextkind {beta} %D For those who want to use this: @@ -271,6 +271,11 @@ \loadmarkfile{spac-par} %loadmarkfile{spac-adj} % no longer needed \loadmarkfile{spac-def} + +\doiffileelse{spac-prf.mkvi} + {\loadmkvifile{spac-prf}} + {\loadmkivfile{spac-prf}} + \loadmarkfile{spac-grd} %loadmarkfile{anch-pos} diff --git a/tex/context/base/font-col.lua b/tex/context/base/font-col.lua index 997c57c9f..cbc1953f4 100644 --- a/tex/context/base/font-col.lua +++ b/tex/context/base/font-col.lua @@ -40,6 +40,7 @@ local vectors = collections.vectors or { } collections.vectors = vectors local fontdata = fonts.hashes.identifiers +local chardata = fonts.hashes.characters local glyph_code = nodes.nodecodes.glyph local currentfont = font.current @@ -275,6 +276,18 @@ function collections.process(head) -- this way we keep feature processing return head, done end +function collections.found(font,char) -- this way we keep feature processing + if not char then + font, char = currentfont(), font + end + if chardata[font][char] then + return true -- in normal font + else + local v = vectors[font] + return v and v[char] and true or false + end +end + -- interface implement { @@ -312,3 +325,9 @@ implement { actions = collections.clonevector, arguments = "string" } + +implement { + name = "doifelsecharinfont", + actions = { collections.found, commands.doifelse }, + arguments = { "integer" } +} diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 2c96e9ac2..81db31652 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -2003,15 +2003,15 @@ end do - local scanners = tokens.scanners - local scanstring = scanners.string - local scaninteger = scanners.integer - local scandimen = scanners.dimen - local scanboolean = scanners.boolean + -- local scanners = tokens.scanners + -- local scanstring = scanners.string + -- local scaninteger = scanners.integer + -- local scandimen = scanners.dimen + -- local scanboolean = scanners.boolean - local setmacro = tokens.setters.macro + -- local scanners = interfaces.scanners - local scanners = interfaces.scanners + local setmacro = tokens.setters.macro function constructors.currentfonthasfeature(n) local f = fontdata[currentfont()] @@ -2040,25 +2040,64 @@ do -- context(lpegmatch(stripper,f(amount/65536))) -- end - local f = formatters["%0.2fpt"] -- normally this value is changed only once - + local f_strip = formatters["%0.2fpt"] -- normally this value is changed only once local stripper = lpeg.patterns.stripzeros - scanners.nbfs = function() - context(lpegmatch(stripper,f(scandimen()/65536))) - end + -- scanners.nbfs = function() + -- context(lpegmatch(stripper,f_strip(scandimen()/65536))) + -- end + + implement { + name = "nbfs", + arguments = "dimen", + actions = function(d) + context(lpegmatch(stripper,f_strip(d/65536))) + end + } + + -- commands.featureattribute = function(tag) context(contextnumber(tag)) end + -- commands.setfontfeature = function(tag) texsetattribute(0,contextnumber(tag)) end + -- commands.resetfontfeature = function() texsetattribute(0,0) end + -- commands.setfontofid = function(id) context_getvalue(csnames[id]) end + -- commands.definefontfeature = presetcontext - commands.featureattribute = function(tag) context(contextnumber(tag)) end - commands.setfontfeature = function(tag) texsetattribute(0,contextnumber(tag)) end - commands.resetfontfeature = function() texsetattribute(0,0) end - commands.setfontofid = function(id) context_getvalue(csnames[id]) end - commands.definefontfeature = presetcontext + -- scanners.featureattribute = function() context(contextnumber(scanstring())) end + -- scanners.setfontfeature = function() texsetattribute(0,contextnumber(scanstring())) end + -- scanners.resetfontfeature = function() texsetattribute(0,0) end + -- scanners.setfontofid = function() context_getvalue(csnames[scaninteger()]) end + -- scanners.definefontfeature = function() presetcontext(scanstring(),scanstring(),scanstring()) end - scanners.featureattribute = function() context(contextnumber(scanstring())) end - scanners.setfontfeature = function() texsetattribute(0,contextnumber(scanstring())) end - scanners.resetfontfeature = function() texsetattribute(0,0) end - scanners.setfontofid = function() context_getvalue(csnames[scaninteger()]) end - scanners.definefontfeature = function() presetcontext(scanstring(),scanstring(),scanstring()) end + implement { + name = "featureattribute", + arguments = "string", + actions = { contextnumber, context } + } + + implement { + name = "setfontfeature", + arguments = "string", + actions = function(tag) texsetattribute(0,contextnumber(tag)) end + } + + implement { + name = "resetfontfeature", + arguments = { 0, 0 }, + actions = texsetattribute, + } + + implement { + name = "setfontofid", + arguments = "integer", + actions = function(id) + context_getvalue(csnames[id]) + end + } + + implement { + name = "definefontfeature", + arguments = { "string", "string", "string" }, + actions = presetcontext + } local cache = { } diff --git a/tex/context/base/font-lib.mkvi b/tex/context/base/font-lib.mkvi index 59074b07d..9cc14e02f 100644 --- a/tex/context/base/font-lib.mkvi +++ b/tex/context/base/font-lib.mkvi @@ -93,14 +93,12 @@ % we can also move the lookups to the fonts.namespace (of commands) % one can also directly use the clf calls when speed is needed -\def\dolookupfontbyspec #1{\clf_fontlookupinitialize{#1}} -\def\dolookupnoffound {\clf_fontlookupnoffound} -\def\dolookupgetkeyofindex#1#2{\clf_fontlookupgetkeyofindex{#1}\numexpr#2\relax} -\def\dolookupgetkey #1{\clf_fontlookupgetkey{#1}} -\def\cleanfontname #1{\clf_cleanfontname{#1}} + \def\dolookupfontbyspec #1{\clf_fontlookupinitialize{#1}} + \def\dolookupnoffound {\clf_fontlookupnoffound} + \def\dolookupgetkeyofindex#1#2{\clf_fontlookupgetkeyofindex{#1}\numexpr#2\relax} + \def\dolookupgetkey #1{\clf_fontlookupgetkey{#1}} + \def\cleanfontname #1{\clf_cleanfontname{#1}} +\unexpanded\def\setfontofid #1{\clf_setfontofid\numexpr#1\relax} -% new: - -\unexpanded\def\setfontofid#1{\ctf_setfontofid#1\relax} \protect \endinput diff --git a/tex/context/base/font-nod.lua b/tex/context/base/font-nod.lua index 26c736582..e2000be7e 100644 --- a/tex/context/base/font-nod.lua +++ b/tex/context/base/font-nod.lua @@ -376,8 +376,13 @@ function step_tracers.codes(i,command,space) if w then context.startcolor(colors[what]) context("%s:",what) - for c in traverse_id(glyph_code,w) do - showchar(c) + for c in traverse_nodes(w) do + local id = getid(c) + if id == glyph_code then + showchar(c) + else + context("[%s]",nodecodes[id]) + end end context[space]() context.stopcolor() diff --git a/tex/context/base/font-pre.mkiv b/tex/context/base/font-pre.mkiv index c184a2118..e003faa27 100644 --- a/tex/context/base/font-pre.mkiv +++ b/tex/context/base/font-pre.mkiv @@ -324,6 +324,23 @@ \definecolor[font:8] [g=.75] \definecolor[font:9] [b=.75] +\definecolor[f:r:t][a=1,t=.25,r=1] +\definecolor[f:g:t][a=1,t=.25,g=1] +\definecolor[f:b:t][a=1,t=.25,b=1] +\definecolor[f:c:t][a=1,t=.25,c=1] +\definecolor[f:m:t][a=1,t=.25,m=1] +\definecolor[f:y:t][a=1,t=.25,y=1] +\definecolor[f:k:t][a=1,t=.25,s=0] +\definecolor[f:s:t][a=1,t=.25,s=0] + +\definepalet % weird place + [layout] + [grid=trace:dr, + page=trace:dg, + profile=f:s:t, + one=f:y:t, + mix=f:b:t] + %D Now we're up to some definitions. \definebodyfontenvironment diff --git a/tex/context/base/font-sol.lua b/tex/context/base/font-sol.lua index bbb2997f4..0761724f1 100644 --- a/tex/context/base/font-sol.lua +++ b/tex/context/base/font-sol.lua @@ -507,7 +507,7 @@ local function collect_words(list) -- can be made faster for attributes words[w] = { index, first, last } index = nil first = nil - if id == disc_node then + if id == disc_code then if trace_split then report_splitters("skipped: disc node") end diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index 4aadadb72..55a0d8929 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = { -- if i can use new features like capture / 2 and .B (at first sight the xml -- parser is some 5% slower) +-- lpeg.P("abc") is faster than lpeg.P("a") * lpeg.P("b") * lpeg.P("c") + -- a new lpeg fails on a #(1-P(":")) test and really needs a + P(-1) -- move utf -> l-unicode @@ -19,7 +21,7 @@ lpeg = require("lpeg") -- The latest lpeg doesn't have print any more, and even the new ones are not -- available by default (only when debug mode is enabled), which is a pitty as --- as it helps nailign down bottlenecks. Performance seems comparable: some 10% +-- as it helps nailing down bottlenecks. Performance seems comparable: some 10% -- slower pattern compilation, same parsing speed, although, -- -- local p = lpeg.C(lpeg.P(1)^0 * lpeg.P(-1)) @@ -841,7 +843,6 @@ local function make(t) local function making(t) local p = p_false local keys = sortedkeys(t) --- local okay = t[""] for i=1,#keys do local k = keys[i] if k ~= "" then @@ -850,8 +851,6 @@ local function make(t) p = p + P(k) * p_true elseif v == false then -- can't happen --- elseif okay then --- p = p + P(k) * (making(v) + p_true) else p = p + P(k) * making(v) end @@ -872,8 +871,6 @@ local function make(t) p = p + P(k) * p_true elseif v == false then -- can't happen --- elseif v[""] then --- p = p + P(k) * (making(v) + p_true) else p = p + P(k) * making(v) end @@ -882,6 +879,33 @@ local function make(t) return p end +local function collapse(t,x) + if type(t) ~= "table" then + return t, x + else + local n = next(t) + if n == nil then + return t, x + elseif next(t,n) == nil then + -- one entry + local k = n + local v = t[k] + if type(v) == "table" then + return collapse(v,x..k) + else + return v, x .. k + end + else + local tt = { } + for k, v in next, t do + local vv, kk = collapse(v,k) + tt[kk] = vv + end + return tt, x + end + end +end + function lpeg.utfchartabletopattern(list) -- goes to util-lpg local tree = { } local n = #list @@ -955,10 +979,14 @@ function lpeg.utfchartabletopattern(list) -- goes to util-lpg end end end +-- collapse(tree,"") -- needs testing, maybe optional, slightly faster because P("x")*P("X") seems slower than P"(xX") (why) -- inspect(tree) return make(tree) end +-- local t = { "start", "stoep", "staart", "paard" } +-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) + -- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua index 02dd1a003..70b60324a 100644 --- a/tex/context/base/l-unicode.lua +++ b/tex/context/base/l-unicode.lua @@ -418,9 +418,11 @@ if not utf.sub then end end - local pattern_zero = Cmt(p_utf8char,slide_zero)^0 - local pattern_one = Cmt(p_utf8char,slide_one )^0 - local pattern_two = Cmt(p_utf8char,slide_two )^0 + local pattern_zero = Cmt(p_utf8char,slide_zero)^0 + local pattern_one = Cmt(p_utf8char,slide_one )^0 + local pattern_two = Cmt(p_utf8char,slide_two )^0 + + local pattern_first = C(patterns.utf8character) function utf.sub(str,start,stop) if not start then @@ -463,7 +465,9 @@ if not utf.sub then end end end - if start > stop then + if start == 1 and stop == 1 then + return lpegmatch(pattern_first,str) or "" + elseif start > stop then return "" elseif start > 1 then b, e, n, first, last = 0, 0, 0, start - 1, stop diff --git a/tex/context/base/lpdf-xmp.lua b/tex/context/base/lpdf-xmp.lua index b44c57b42..b1a795c4b 100644 --- a/tex/context/base/lpdf-xmp.lua +++ b/tex/context/base/lpdf-xmp.lua @@ -152,7 +152,8 @@ end local t = { } for i=1,24 do t[i] = random() end local function flushxmpinfo() - commands.freezerandomseed(os.clock()) -- hack + commands.pushrandomseed() + commands.setrandomseed(os.time()) local t = { } for i=1,24 do t[i] = char(96 + random(26)) end local packetid = concat(t) @@ -201,7 +202,7 @@ local function flushxmpinfo() local r = pdfflushstreamobject(blob,md,false) -- uncompressed lpdf.addtocatalog("Metadata",pdfreference(r)) - commands.defrostrandomseed() -- hack + commands.poprandomseed() -- hack end -- his will be enabled when we can inhibit compression for a stream at the lua end diff --git a/tex/context/base/lxml-aux.lua b/tex/context/base/lxml-aux.lua index f6816ccb6..8eedade39 100644 --- a/tex/context/base/lxml-aux.lua +++ b/tex/context/base/lxml-aux.lua @@ -427,6 +427,14 @@ local function include(xmldata,pattern,attribute,recursive,loaddata,level) else xmldata.settings.inclusions = { name } end + if child.er then + local badinclusions = xmldata.settings.badinclusions + if badinclusions then + badinclusions[#badinclusions+1] = name + else + xmldata.settings.badinclusions = { name } + end + end end end end @@ -447,11 +455,11 @@ function xml.inclusion(e,default) return default end -function xml.inclusions(e,sorted) +local function getinclusions(key,e,sorted) while e do local settings = e.settings if settings then - local inclusions = settings.inclusions + local inclusions = settings[key] if inclusions then inclusions = table.unique(inclusions) -- a copy if sorted then @@ -467,6 +475,14 @@ function xml.inclusions(e,sorted) end end +function xml.inclusions(e,sorted) + return getinclusions("inclusions",e,sorted) +end + +function xml.badinclusions(e,sorted) + return getinclusions("badinclusions",e,sorted) +end + local b_collapser = lpeg.patterns.b_collapser local m_collapser = lpeg.patterns.m_collapser local e_collapser = lpeg.patterns.e_collapser diff --git a/tex/context/base/lxml-ini.lua b/tex/context/base/lxml-ini.lua index 64e78eb42..2f63c857f 100644 --- a/tex/context/base/lxml-ini.lua +++ b/tex/context/base/lxml-ini.lua @@ -71,6 +71,7 @@ implement { name = "xmlinclude", actions = lxml.include, implement { name = "xmlincludeoptions", actions = lxml.include, arguments = { "string", "string", "string", "string" } } implement { name = "xmlinclusion", actions = lxml.inclusion, arguments = "string" } implement { name = "xmlinclusions", actions = lxml.inclusions, arguments = "string" } +implement { name = "xmlbadinclusions", actions = lxml.badinclusions, arguments = "string" } implement { name = "xmlindex", actions = lxml.index, arguments = { "string", "string", "string" } } -- can be integer but now we can alias implement { name = "xmlinfo", actions = lxml.info, arguments = "string" } implement { name = "xmlinlineverbatim", actions = lxml.inlineverbatim, arguments = "string" } diff --git a/tex/context/base/lxml-ini.mkiv b/tex/context/base/lxml-ini.mkiv index 114128899..5ef4245a2 100644 --- a/tex/context/base/lxml-ini.mkiv +++ b/tex/context/base/lxml-ini.mkiv @@ -65,6 +65,7 @@ %def\xmlincludeoptions#1#2#3#4{\clf_xmlincludeoptions {#1}{#2}{#3}{#4}} %def\xmlinclusion #1{\clf_xmlinclusion {#1}} %def\xmlinclusions #1{\clf_xmlinclusions {#1}} +%def\xmlbadinclusions #1{\clf_xmlbadinclusions {#1}} %def\xmlindex #1#2#3{\clf_xmlindex {#1}{#2}{#3}} %let\xmlposition \xmlindex %def\xmlinlineverbatim #1{\clf_xmlinlineverbatim {#1}} @@ -134,6 +135,7 @@ \let\xmlincludeoptions \clf_xmlincludeoptions \let\xmlinclusion \clf_xmlinclusion \let\xmlinclusions \clf_xmlinclusions +\let\xmlbadinclusions \clf_xmlbadinclusions \let\xmlindex \clf_xmlindex \let\xmlposition \clf_xmlindex \let\xmlinlineverbatim \clf_xmlinlineverbatim diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua index 0a72640d0..47e2cac61 100644 --- a/tex/context/base/lxml-tab.lua +++ b/tex/context/base/lxml-tab.lua @@ -243,8 +243,10 @@ local function add_end(spacing, namespace, tag) top = stack[#stack] if #stack < 1 then errorstr = formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "") + report_xml(errorstr) elseif toclose.tg ~= tag then -- no namespace check errorstr = formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "") + report_xml(errorstr) end dt = top.dt dt[#dt+1] = toclose @@ -254,11 +256,38 @@ local function add_end(spacing, namespace, tag) end end +-- local function add_text(text) +-- if cleanup and #text > 0 then +-- dt[#dt+1] = cleanup(text) +-- else +-- dt[#dt+1] = text +-- end +-- end + local function add_text(text) + local n = #dt if cleanup and #text > 0 then - dt[#dt+1] = cleanup(text) + if n > 0 then + local s = dt[n] + if type(s) == "string" then + dt[n] = s .. cleanup(text) + else + dt[n+1] = cleanup(text) + end + else + dt[1] = cleanup(text) + end else - dt[#dt+1] = text + if n > 0 then + local s = dt[n] + if type(s) == "string" then + dt[n] = s .. text + else + dt[n+1] = text + end + else + dt[1] = text + end end end @@ -297,8 +326,11 @@ local function attribute_specification_error(str) return str end +local badentity = "&error;" +local badentity = "&" + xml.placeholders = { - unknown_dec_entity = function(str) return str == "" and "&error;" or formatters["&%s;"](str) end, + unknown_dec_entity = function(str) return str == "" and badentity or formatters["&%s;"](str) end, unknown_hex_entity = function(str) return formatters["&#x%s;"](str) end, unknown_any_entity = function(str) return formatters["&#x%s;"](str) end, } @@ -516,7 +548,7 @@ local function handle_any_entity(str) report_xml("keeping entity &%s;",str) end if str == "" then - a = "&error;" + a = badentity else a = "&" .. str .. ";" end @@ -545,7 +577,7 @@ local function handle_any_entity(str) if trace_entities then report_xml("invalid entity &%s;",str) end - a = "&error;" + a = badentity acache[str] = a else if trace_entities then @@ -560,8 +592,19 @@ local function handle_any_entity(str) end end -local function handle_end_entity(chr) - report_xml("error in entity, %a found instead of %a",chr,";") +-- local function handle_end_entity(chr) +-- report_xml("error in entity, %a found instead of %a",chr,";") +-- end + +local function handle_end_entity(str) + report_xml("error in entity, %a found without ending %a",str,";") + return str +end + +local function handle_crap_error(chr) + report_xml("error in parsing, unexpected %a found ",chr) + add_text(chr) + return chr end local space = S(' \r\n\t') @@ -582,14 +625,16 @@ local utfbom = lpegpatterns.utfbom -- no capture local spacing = C(space^0) ----- entitycontent = (1-open-semicolon)^0 -local anyentitycontent = (1-open-semicolon-space-close)^0 +local anyentitycontent = (1-open-semicolon-space-close-ampersand)^0 local hexentitycontent = R("AF","af","09")^0 local decentitycontent = R("09")^0 local parsedentity = P("#")/"" * ( P("x")/"" * (hexentitycontent/handle_hex_entity) + (decentitycontent/handle_dec_entity) ) + (anyentitycontent/handle_any_entity) -local entity = ampersand/"" * parsedentity * ( (semicolon/"") + #(P(1)/handle_end_entity)) +----- entity = ampersand/"" * parsedentity * ( (semicolon/"") + #(P(1)/handle_end_entity)) +local entity = (ampersand/"") * parsedentity * (semicolon/"") + + ampersand * (anyentitycontent / handle_end_entity) local text_unparsed = C((1-open)^1) local text_parsed = Cs(((1-open-ampersand)^1 + entity)^1) @@ -622,6 +667,8 @@ local emptyelement = (spacing * open * name * attributes * optionals local beginelement = (spacing * open * name * attributes * optionalspace * close) / add_begin local endelement = (spacing * open * slash * name * optionalspace * close) / add_end +-- todo: combine the opens in: + local begincomment = open * P("!--") local endcomment = P("--") * close local begininstruction = open * P("?") @@ -667,6 +714,14 @@ local comment = (spacing * begincomment * somecomment * endcomm local cdata = (spacing * begincdata * somecdata * endcdata ) / function(...) add_special("@cd@",...) end local doctype = (spacing * begindoctype * somedoctype * enddoctype ) / function(...) add_special("@dt@",...) end +-- local text_unparsed = C((1-open)^1) +-- local text_parsed = Cs(((1-open-ampersand)^1 + entity)^1) + +local crap_parsed = 1 - beginelement - endelement - emptyelement - begininstruction - begincomment - begincdata - ampersand +local crap_unparsed = 1 - beginelement - endelement - emptyelement - begininstruction - begincomment - begincdata +local parsedcrap = Cs((crap_parsed^1 + entity)^1) / handle_crap_error +local unparsedcrap = Cs((crap_unparsed )^1) / handle_crap_error + -- nicer but slower: -- -- local instruction = (Cc("@pi@") * spacing * begininstruction * someinstruction * endinstruction) / add_special @@ -683,13 +738,13 @@ local trailer = space^0 * (text_unparsed/set_message)^0 local grammar_parsed_text = P { "preamble", preamble = utfbom^0 * instruction^0 * (doctype + comment + instruction)^0 * V("parent") * trailer, parent = beginelement * V("children")^0 * endelement, - children = parsedtext + V("parent") + emptyelement + comment + cdata + instruction, + children = parsedtext + V("parent") + emptyelement + comment + cdata + instruction + parsedcrap, } local grammar_unparsed_text = P { "preamble", preamble = utfbom^0 * instruction^0 * (doctype + comment + instruction)^0 * V("parent") * trailer, parent = beginelement * V("children")^0 * endelement, - children = unparsedtext + V("parent") + emptyelement + comment + cdata + instruction, + children = unparsedtext + V("parent") + emptyelement + comment + cdata + instruction + unparsedcrap, } -- maybe we will add settings to result as well @@ -729,7 +784,7 @@ local function _xmlconvert_(data, settings) errorstr = "empty xml file" elseif utfize or resolve then if lpegmatch(grammar_parsed_text,data) then - errorstr = "" + -- errorstr = "" can be set! else errorstr = "invalid xml file - parsed text" end @@ -745,6 +800,8 @@ local function _xmlconvert_(data, settings) local result if errorstr and errorstr ~= "" then result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={ }, er = true } } } +setmetatable(result, mt) +setmetatable(result.dt[1], mt) setmetatable(stack, mt) local errorhandler = settings.error_handler if errorhandler == false then diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index adb849347..9e540fe7c 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -49,6 +49,7 @@ local xmlprivatecodes = xml.privatecodes local xmlstripelement = xml.stripelement local xmlinclusion = xml.inclusion local xmlinclusions = xml.inclusions +local xmlbadinclusions = xml.badinclusions local xmlcontent = xml.content local variables = interfaces and interfaces.variables or { } @@ -519,7 +520,14 @@ end function lxml.inclusions(id,sorted) local inclusions = xmlinclusions(getid(id),sorted) if inclusions then - context(table.concat(inclusions,",")) + context(concat(inclusions,",")) + end +end + +function lxml.badinclusions(id,sorted) + local badinclusions = xmlbadinclusions(getid(id),sorted) + if badinclusions then + context(concat(badinclusions,",")) end end @@ -1205,12 +1213,12 @@ local function command(collected,cmd,otherwise) local e = collected[c] local ix = e.ix local name = e.name - if not ix then + if name and not ix then lxml.addindex(name,false,true) ix = e.ix end - if not ix then - report_lxml("no valid node index for element %a in command %s",name,cmd) + if not ix or not name then + report_lxml("no valid node index for element %a using command %s",name or "?",cmd) elseif wildcard then contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}") else diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua index 61d28edde..0d900b3a1 100644 --- a/tex/context/base/math-tag.lua +++ b/tex/context/base/math-tag.lua @@ -315,7 +315,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer runner(getlist(n),depth+1) elseif id == glyph_code then runner(getfield(n,"components"),depth+1) -- this should not be needed - elseif id == disc_node then + elseif id == disc_code then runner(getfield(n,"pre"),depth+1) -- idem runner(getfield(n,"post"),depth+1) -- idem runner(getfield(n,"replace"),depth+1) -- idem diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index c3b94f899..299f37cef 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -336,12 +336,14 @@ \newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default +\let\theMPrandomseed\empty + \def\setMPrandomseed - {\let\theMPrandomseed\empty - \ifsetMPrandomseed \ifx\getrandomnumber\undefined \else - \getrandomnumber\localMPseed\zerocount{4095}% - \def\theMPrandomseed{randomseed:=\localMPseed}% - \fi\fi} + {\ifsetMPrandomseed + \def\theMPrandomseed{randomseed:=\mprandomnumber;}% + \else + \let\theMPrandomseed\empty + \fi} %D Calling up previously defined graphics. diff --git a/tex/context/base/mlib-int.lua b/tex/context/base/mlib-int.lua index 43bf14d38..6d219fe04 100644 --- a/tex/context/base/mlib-int.lua +++ b/tex/context/base/mlib-int.lua @@ -101,9 +101,13 @@ end -- locals -mp.OnRightPage = function() mpprint(structures.pages.on_right()) end -- needs checking -mp.OnOddPage = function() mpprint(structures.pages.is_odd ()) end -- needs checking -mp.InPageBody = function() mpprint(structures.pages.in_body ()) end -- needs checking +local on_right = structures.pages.on_right +local is_odd = structures.pages.is_odd +local in_body = structures.pages.in_body + +mp.OnRightPage = function() mpprint(on_right()) end -- needs checking +mp.OnOddPage = function() mpprint(is_odd ()) end -- needs checking +mp.InPageBody = function() mpprint(in_body ()) end -- needs checking -- mp.CurrentLayout : \currentlayout diff --git a/tex/context/base/mtx-context-listing.tex b/tex/context/base/mtx-context-listing.tex index a38fc60a9..583aa2b8f 100644 --- a/tex/context/base/mtx-context-listing.tex +++ b/tex/context/base/mtx-context-listing.tex @@ -92,7 +92,8 @@ if document.arguments.sort then table.sort(document.files) end - for _, filename in ipairs(document.files) do + for i=1,#document.files do + local filename = document.files[i] if not string.find(filename,"^mtx%-context%-") then local pretty = document.arguments.pretty if pretty == true then diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv index 6efeb3069..607f76a16 100644 --- a/tex/context/base/mult-def.mkiv +++ b/tex/context/base/mult-def.mkiv @@ -46,6 +46,8 @@ \def\c!nextleftquotation {nextleftquotation} \def\c!nextrightquotation{nextrightquotation} +\def\c!profile {profile} + \def\c!fences {fences} \def\c!words {words} \def\c!characters {characters} diff --git a/tex/context/base/mult-sys.mkiv b/tex/context/base/mult-sys.mkiv index 63a89492a..b1475f2dc 100644 --- a/tex/context/base/mult-sys.mkiv +++ b/tex/context/base/mult-sys.mkiv @@ -274,6 +274,7 @@ \definesystemconstant {list} \definesystemconstant {register} \definesystemconstant {author} +\definesystemconstant {numbering} % \def\s!parent{->} % 1% faster / => does not work in assignments % \def\s!child {<-} % 1% faster / <= does not work in assignments diff --git a/tex/context/base/node-ltp.lua b/tex/context/base/node-ltp.lua index 9529213fc..e4956f7df 100644 --- a/tex/context/base/node-ltp.lua +++ b/tex/context/base/node-ltp.lua @@ -406,24 +406,8 @@ end -- resolvers -- -local whatsitters = { - get_width = { }, - get_dimensions = { }, -} - -local get_whatsit_width = whatsitters.get_width -local get_whatsit_dimensions = whatsitters.get_dimensions - -local function get_width (n,dir) return getfield(n,"width") end -local function get_dimensions(n,dir) return getfield(n,"width"), getfield(n,"height"), getfield(n,"depth") end - -get_whatsit_width[pdfrefximage_code] = get_width -get_whatsit_width[pdfrefxform_code ] = get_width - -get_whatsit_dimensions[pdfrefximage_code] = get_dimensions -get_whatsit_dimensions[pdfrefxform_code ] = get_dimensions - -nodes.whatsitters = whatsitters +local get_whatsit_width = nodes.whatsitters.getters.width +local get_whatsit_dimensions = nodes.whatsitters.getters.dimensions -- expansion etc -- diff --git a/tex/context/base/node-nut.lua b/tex/context/base/node-nut.lua index 32f2d57ec..b133c4e74 100644 --- a/tex/context/base/node-nut.lua +++ b/tex/context/base/node-nut.lua @@ -752,3 +752,39 @@ function nuts.copy_properties(source,target,what) end return newprops -- for checking end + +-- a bit special + +local getwidth = { } +local setwidth = { } +local getdimensions = { } +local setdimensions = { } + +nodes.whatsitters = { + getters = { width = getwidth, dimensions = getdimensions }, + setters = { width = setwidth, dimensions = setdimensions }, +} + +-- this might move (in fact forms and images will become nodes) + +local function get_width(n,dir) + n = tonut(n) + return getfield(n,"width") +end + +local function get_dimensions(n,dir) + n = tonut(n) + return getfield(n,"width"), getfield(n,"height"), getfield(n,"depth") +end + +local whatcodes = nodes.whatcodes +local pdfrefximage_code = whatcodes.pdfrefximage +local pdfrefxform_code = whatcodes.pdfrefxform + +getwidth [pdfrefximage_code] = get_width +getwidth [pdfrefxform_code ] = get_width + +getdimensions[pdfrefximage_code] = get_dimensions +getdimensions[pdfrefxform_code ] = get_dimensions + + diff --git a/tex/context/base/node-ppt.lua b/tex/context/base/node-ppt.lua index c8cba8566..5e7abeaae 100644 --- a/tex/context/base/node-ppt.lua +++ b/tex/context/base/node-ppt.lua @@ -58,7 +58,7 @@ local cache = { } local nofslots = 0 local property_id = nodepool.userids["property"] -local properties = nodes.properties if not properties then return end -- temp +local properties = nodes.properties local propertydata = properties.data local starttiming = statistics.starttiming diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index 9703cc184..97c37c74e 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -451,7 +451,6 @@ local function addstring(what,str,shift) --todo make a pluggable helper (in font end local text = typesetters.fast_hpack(str,infofont) local rule = new_rule(emwidth/5,4*exheight,3*exheight) - local list = getlist(text) setfield(text,"shift",shift) return nuts.fasthpack(nuts.linked(text,rule)) -- local text = typesetters.fast_hpack(str,fonts.infofont()) diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv index 141d741cf..5f72a1113 100644 --- a/tex/context/base/pack-rul.mkiv +++ b/tex/context/base/pack-rul.mkiv @@ -1498,10 +1498,20 @@ \pack_framed_reshape_reset \fi} +\def\pack_framed_profile_box + {\profilegivenbox\p_profile\b_framed_normal + \setbox\b_framed_normal\vbox{\unvbox\b_framed_normal}} + \unexpanded\def\pack_framed_finish {%\pack_framed_stop_orientation % hm, wrong place ! should rotate the result (after reshape) .. moved down \pack_framed_locator_before\p_framed_location \ifconditional\c_framed_has_format + \ifconditional\c_framed_has_height \else + \edef\p_profile{\framedparameter\c!profile}% + \ifx\p_profile\empty\else + \pack_framed_profile_box + \fi + \fi \ifx\p_framed_autowidth\v!force \pack_framed_finish_a \else\ifx\localwidth\v!fit @@ -2115,7 +2125,8 @@ \def\pack_framed_do_setups {\ifx\p_framed_setups\empty \else - \setups[\p_framed_setups]% \texsetup + \setups[\p_framed_setups]% \texsetup (or only one!) + % \fastsetup\p_framed_setup % singular would have been better \fi} \def\pack_framed_format_format_yes diff --git a/tex/context/base/page-grd.mkiv b/tex/context/base/page-grd.mkiv index 281d0bfbe..e70414b66 100644 --- a/tex/context/base/page-grd.mkiv +++ b/tex/context/base/page-grd.mkiv @@ -15,22 +15,19 @@ \unprotect -\definepalet - [layout] - [grid=red, - page=green] - \newconstant\c_page_grids_location \newconstant\c_page_grids_line_mode \newconstant\c_page_grids_lineno_mode +\newconstant\c_page_grids_columns_mode \unexpanded\def\showgrid {\dosingleempty\page_grids_show} \def\page_grids_show[#1]% - {\c_page_grids_location \plusone % downward compatible default - \c_page_grids_line_mode \plusone - \c_page_grids_lineno_mode\plusone + {\c_page_grids_location \plusone % downward compatible default + \c_page_grids_line_mode \plusone + \c_page_grids_lineno_mode \plusone + \c_page_grids_columns_mode\plusone \processallactionsinset [#1]% [ \v!reset=>\c_page_grids_location \zerocount, @@ -48,14 +45,24 @@ \let\page_grids_add_to_box\gobbleoneargument \else % 1=bottom 2=top \let\page_grids_add_to_box\page_grids_add_to_box_indeed + \fi + \ifcase\c_page_grids_columns_mode + \let\page_grids_add_to_one\gobbleoneargument + \let\page_grids_add_to_mix\gobbleoneargument + \else + \let\page_grids_add_to_one\page_grids_add_to_one_indeed + \let\page_grids_add_to_mix\page_grids_add_to_mix_indeed \fi} % if really needed for speed we can cache the grid \let\page_grids_add_to_box\gobbleoneargument +\let\page_grids_add_to_one\gobbleoneargument +\let\page_grids_add_to_mix\gobbleoneargument \def\page_grids_add_to_box_indeed#1% to be checked for color and layer ..... use mp {\startcolor[layout:grid]% + \resetvisualizers \gridboxlinemode \c_page_grids_line_mode \gridboxlinenomode\c_page_grids_lineno_mode \setgridbox\scratchbox\makeupwidth\textheight % todo: check color @@ -82,4 +89,16 @@ \ifcase\c_page_grids_location\or\hskip-\makeupwidth\box#1\fi}% \stopcolor} +\def\page_grids_add_to_one_indeed#1% + {\begingroup + \resetvisualizers + \global\setbox#1\vbox{\backgroundline[layout:one]{\box#1}}% + \endgroup} + +\def\page_grids_add_to_mix_indeed#1% + {\begingroup + \resetvisualizers + \global\setbox#1\vbox{\backgroundline[layout:mix]{\box#1}}% + \endgroup} + \protect \endinput diff --git a/tex/context/base/page-mix.lua b/tex/context/base/page-mix.lua index 2bf89f737..61a4f944d 100644 --- a/tex/context/base/page-mix.lua +++ b/tex/context/base/page-mix.lua @@ -258,22 +258,22 @@ local function preparesplit(specification) -- a rather large function if splitmethod == v_none then splitmethod = false end - local options = settings_to_hash(specification.option or "") + local options = settings_to_hash(specification.option or "") local stripbottom = specification.alternative == v_local - local cycle = specification.cycle or 1 - local nofcolumns = specification.nofcolumns or 1 + local cycle = specification.cycle or 1 + local nofcolumns = specification.nofcolumns or 1 if nofcolumns == 0 then nofcolumns = 1 end local preheight = specification.preheight or 0 - local extra = specification.extra or 0 + local extra = specification.extra or 0 local maxheight = specification.maxheight - local optimal = originalheight/nofcolumns + local optimal = originalheight/nofcolumns if specification.balance ~= v_yes then optimal = maxheight end - local target = optimal + extra - local overflow = target > maxheight - preheight + local target = optimal + extra + local overflow = target > maxheight - preheight local threshold = specification.threshold or 0 if overflow then target = maxheight - preheight @@ -484,7 +484,15 @@ local function preparesplit(specification) -- a rather large function end height = height + depth + skip depth = 0 +if advance < 0 then + height = height + advance + skip = 0 + if height < 0 then + height = 0 + end +else skip = height > 0 and advance or 0 +end if trace_state then report_state("%-7s > column %s, height %p, depth %p, skip %p","glue",column,height,depth,skip) end @@ -602,7 +610,8 @@ local function preparesplit(specification) -- a rather large function local nxtid = nxt and getid(nxt) line = line + 1 local inserts, currentskips, nextskips, inserttotal = nil, 0, 0, 0 - local advance = getfield(current,"height") -- + getfield(current,"depth") + local advance = getfield(current,"height") +-- + getfield(current,"depth") -- when > strutdp if trace_state then report_state("%-7s > column %s, content: %s","line",column,listtoutf(getlist(current),true,true)) end diff --git a/tex/context/base/page-mix.mkiv b/tex/context/base/page-mix.mkiv index b545e8f4c..6d7f144a6 100644 --- a/tex/context/base/page-mix.mkiv +++ b/tex/context/base/page-mix.mkiv @@ -172,6 +172,14 @@ \c!internalgrid=\v!halfline, % new, we may still revert to \v!line \c!balance=\v!yes] +% better + +\setupmixedcolumns + [\s!itemgroupcolumns] + [\c!splitmethod=\v!fixed, + \c!grid=\v!yes, + \c!internalgrid=\v!line] + \unexpanded\def\strc_itemgroups_start_columns {\startmixedcolumns[\s!itemgroupcolumns]} % we could have a fast one @@ -199,11 +207,6 @@ %D The interceptor is quite simple, at least for the moment. -% \def\page_mix_routine_intercept -% {\global\setbox\b_page_mix_preceding\vbox -% {\page_otr_command_flush_top_insertions -% \unvbox\normalpagebox}} - \def\page_mix_routine_intercept {\ifdim\pagetotal>\pagegoal % testcase: preceding-001 ... if we don't do this, text can disappear as @@ -443,8 +446,7 @@ [\s!itemgroupcolumns] [\c!grid=\itemgroupparameter\c!grid] -\setupitemgroups - [\c!grid=\v!tolerant] +% better %D The common initialization: @@ -471,6 +473,8 @@ % \insidecolumnstrue % new % + \useprofileparameter\mixedcolumnsparameter % new + % \nofcolumns\c_page_mix_n_of_columns} % public %D The otr method related hooks are defined next: @@ -484,23 +488,44 @@ \newcount\c_page_mix_otr_nesting +% \setvalue{\??mixedcolumnsbefore\s!otr}% +% {\par +% \global\advance\c_page_mix_otr_nesting\plusone +% \ifcase\c_page_mix_otr_nesting\or +% \ifdim\pagetotal=\zeropoint \else +% \obeydepth % we could handle this in pre material +% \fi +% \fi} + \setvalue{\??mixedcolumnsbefore\s!otr}% {\par \global\advance\c_page_mix_otr_nesting\plusone \ifcase\c_page_mix_otr_nesting\or \ifdim\pagetotal=\zeropoint \else - \obeydepth % we could handle this in pre material + % make sure that whitespace an dblanks are done + \strut + \vskip-\lineheight + % no, bad spacing: \obeydepth % we could handle this in pre material \fi \fi} \setvalue{\??mixedcolumnsstart\s!otr}% {\ifcase\c_page_mix_otr_nesting\or + \scratchwidth\textwidth \setupoutputroutine[\s!mixedcolumn]% \c_page_mix_routine\c_page_mix_routine_intercept \page_otr_trigger_output_routine % \holdinginserts\maxdimen % + \ifvoid\b_page_mix_preceding \else + % moved here, before the packaging + \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding + % we need to avoid unvboxing with successive balanced on one page + \global\setbox\b_page_mix_preceding\vbox{\box\b_page_mix_preceding}% + \wd\b_page_mix_preceding\scratchwidth % \makeupwidth + \page_grids_add_to_one\b_page_mix_preceding + \fi \global\d_page_mix_preceding_height\ht\b_page_mix_preceding \c_page_mix_routine\c_page_mix_routine_continue % @@ -574,7 +599,7 @@ % backgrounds \anch_mark_column_box\scratchbox % for the moment a quick and dirty patch .. we need to go into the box (hence the \plusone) .. a slowdowner - \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_mix_n_of_columns\plusone + % moved to start: \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_mix_n_of_columns\plusone % the framed needs a reset of strut, align, setups etc \mixedcolumnseparatorheight\ht\scratchbox \mixedcolumnseparatordepth \dp\scratchbox @@ -593,9 +618,13 @@ \setbox\b_page_mix_collected\vbox \bgroup \ifvoid\b_page_mix_preceding \else \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding - \box\b_page_mix_preceding + \vbox\bgroup + \box\b_page_mix_preceding + \egroup \global\d_page_mix_preceding_height\zeropoint \nointerlineskip + % no no: + % \prevdepth\strutdepth \fi \hskip\d_page_mix_leftskip \page_mix_hbox to \d_page_mix_max_width \bgroup @@ -648,6 +677,7 @@ \page_otr_command_set_hsize \par %writestatus\m!columns{flush balance}% + \page_grids_add_to_mix\b_page_mix_collected % no linenumbers here \box\b_page_mix_collected \vskip\zeropoint % triggers recalculation of page stuff (weird that this is needed but it *is* needed, see mixed-001.tex) \par @@ -730,11 +760,32 @@ \letvalue{\??mixedcolumnsbefore\s!box}\donothing \letvalue{\??mixedcolumnsafter \s!box}\donothing +% \setvalue{\??mixedcolumnsstart\s!box}% +% {\edef\p_page_mix_strut{\mixedcolumnsparameter\c!strut}% +% \setbox\b_page_mix_collected\vbox\bgroup +% \let\currentoutputroutine\s!mixedcolumn % makes \column work +% \forgetall +% \page_mix_command_set_hsize +% \ifx\p_page_mix_strut\v!yes +% \begstrut +% \ignorespaces +% \fi} +% +% \setvalue{\??mixedcolumnsstop\s!box}% +% {\ifx\p_page_mix_strut\v!yes +% \removeunwantedspaces +% \endstrut +% \fi +% \egroup +% \page_mix_box_balance} + \setvalue{\??mixedcolumnsstart\s!box}% {\edef\p_page_mix_strut{\mixedcolumnsparameter\c!strut}% - \setbox\b_page_mix_collected\vbox\bgroup + \setbox\b_page_mix_collected\vbox \bgroup \let\currentoutputroutine\s!mixedcolumn % makes \column work \forgetall + \usegridparameter\mixedcolumnsparameter + % \useprofileparameter\mixedcolumnsparameter \page_mix_command_set_hsize \ifx\p_page_mix_strut\v!yes \begstrut @@ -747,6 +798,16 @@ \endstrut \fi \egroup + \edef\p_profile{\mixedcolumnsparameter\c!profile}% + \ifx\p_profile\empty \else + % this can never be ok because we cheat with depth and height + % and glue in between and when we're too large we run into issues + % so mayb best limit correction to one line + \profilegivenbox\p_profile\b_page_mix_collected + \setbox\b_page_mix_collected\vbox{\unvbox\b_page_mix_collected}% + % tracing + % \addprofiletobox\b_page_mix_collected + \fi \page_mix_box_balance} %D The related balancer is only a few lines: diff --git a/tex/context/base/page-set.mkiv b/tex/context/base/page-set.mkiv index 8f63dd74e..a5afb92e9 100644 --- a/tex/context/base/page-set.mkiv +++ b/tex/context/base/page-set.mkiv @@ -2645,8 +2645,6 @@ % \chapter{thuan} \dorecurse{25}{\input thuan \endgraf\placefigure{}{}} % \stopcolumnset -\unprotect - % only in columnsets % \def\cornerfigure diff --git a/tex/context/base/page-sid.mkiv b/tex/context/base/page-sid.mkiv index cbdb95fc3..42c676be5 100644 --- a/tex/context/base/page-sid.mkiv +++ b/tex/context/base/page-sid.mkiv @@ -363,10 +363,10 @@ \page_otr_sides_pop_penalties} \def\page_sides_output_routine_yes % we need to rework this ... add pagediscards and such - {\unvbox\normalpagebox + {\unvbox\normalpagebox % bah, and the discards? \setbox\b_page_sides_bottom\lastbox \ifdim\wd\b_page_sides_bottom>\d_page_sides_hsize - \penalty-201 + \penalty-201 % hm, i really need to write this from scatch \box\b_page_sides_bottom \else\ifvoid\b_page_sides_bottom \else @@ -663,7 +663,7 @@ \def\page_sides_prepare_space {\par - \whitespace + % no longer needed \whitespace \begingroup \forgetall \reseteverypar @@ -771,13 +771,15 @@ \fi} \def\page_sides_inject_dummy_lines - {\scratchcounter\pageshrink + {\begingroup + \scratchcounter\pageshrink \divide\scratchcounter \baselineskip \advance\scratchcounter \plusone \parskip\zeropoint \dorecurse\scratchcounter{\hbox to \hsize{}}% \kern-\scratchcounter\baselineskip - \penalty\zerocount} + \penalty\zerocount + \endgroup} % Display math % diff --git a/tex/context/base/publ-aut.lua b/tex/context/base/publ-aut.lua index 820ac78ff..4ab8dd4bc 100644 --- a/tex/context/base/publ-aut.lua +++ b/tex/context/base/publ-aut.lua @@ -16,9 +16,10 @@ local lpeg = lpeg local type, next, tostring = type, next, tostring local concat = table.concat local utfchar = utf.char +local utfsub = utf.sub local formatters = string.formatters -local P, C, V, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Cc +local P, S, C, V, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.S, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Cc local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local context = context @@ -36,7 +37,10 @@ local allocate = utilities.storage.allocate local chardata = characters.data +local trace_hashing = false trackers.register("publications.authorhash", function(v) trace_hashing = v end) + local report = logs.reporter("publications","authors") +local report_cite = logs.reporter("publications","cite") -- local function makesplitter(separator) -- return Ct { "start", @@ -99,7 +103,7 @@ end -- local cleaner = Cs( ( P("{}")/"" + P(1) )^1 ) -local cache = { } -- 33% reuse on tugboat.bib +local cache = allocate() -- 33% reuse on tugboat.bib local nofhits = 0 local nofused = 0 @@ -115,6 +119,144 @@ local function makeinitials(firstnames) end end +local authormap = allocate() +publications.authormap = authormap + +local function splitauthor(author) + local detail = cache[author] + if detail then + return detail + end + local remapped = authormap[author] + if remapped then + report("remapping %a to %a",author,remapped) + local detail = cache[remapped] + if detail then + cache[author] = detail + return detail + end + end + local author = remapped or author + local firstnames, vons, surnames, initials, juniors, options + local split = lpegmatch(commasplitter,author) + local n = #split + detail = { + original = author, + snippets = n, + } + if n == 1 then + -- {First Middle von Last} + local words = lpegmatch(spacesplitter,author) + firstnames, vons, surnames = { }, { }, { } + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + firstnames[#firstnames+1], i = w, i + 1 + else + break + end + end + while i <= n do + local w = words[i] + if is_upper(w) then + break + else + vons[#vons+1], i = w, i + 1 + end + end + if i <= n then + while i <= n do + surnames[#surnames+1], i = words[i], i + 1 + end + elseif #vons == 0 then + surnames[1] = firstnames[#firstnames] + firstnames[#firstnames] = nil + else + -- mess + end + if #surnames == 0 then + -- safeguard + firstnames = { } + vons = { } + surnames = { author } + else + initials = makeinitials(firstnames) + end + elseif n == 2 then + -- {Last, First} + -- {von Last, First} + firstnames, vons, surnames = { }, { }, { } + local words = lpegmatch(spacesplitter,split[1]) + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + break + else + vons[#vons+1], i = w, i + 1 + end + end + while i <= n do + surnames[#surnames+1], i = words[i], i + 1 + end + -- + local words = lpegmatch(spacesplitter,split[2]) + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + firstnames[#firstnames+1], i = w, i + 1 + else + break + end + end + while i <= n do + vons[#vons+1], i = words[i], i + 1 + end + if surnames and firstnames and #surnames == 0 then + -- safeguard + surnames[1] = firstnames[#firstnames] + firstnames[#firstnames] = nil + end + initials = makeinitials(firstnames) + elseif n == 3 then + -- {von Last, First, Jr} + surnames = lpegmatch(spacesplitter,split[1]) + juniors = lpegmatch(spacesplitter,split[2]) + firstnames = lpegmatch(spacesplitter,split[3]) + initials = makeinitials(firstnames) + elseif n == 4 then + -- {Von, Last, First, Jr} + vons = lpegmatch(spacesplitter,split[1]) + surnames = lpegmatch(spacesplitter,split[2]) + juniors = lpegmatch(spacesplitter,split[3]) + firstnames = lpegmatch(spacesplitter,split[4]) + initials = makeinitials(firstnames) + elseif n >= 5 then + -- {Von, Last, First, Jr, F.} + -- {Von, Last, First, Jr, Fr., options} + vons = lpegmatch(spacesplitter,split[1]) + surnames = lpegmatch(spacesplitter,split[2]) + juniors = lpegmatch(spacesplitter,split[3]) + firstnames = lpegmatch(spacesplitter,split[4]) + initials = lpegmatch(spacesplitter,split[5]) + options = split[6] + if options then + options = lpegmatch(optionsplitter,options) + end + end + if firstnames and #firstnames > 0 then detail.firstnames = firstnames end + if vons and #vons > 0 then detail.vons = vons end + if surnames and #surnames > 0 then detail.surnames = surnames end + if initials and #initials > 0 then detail.initials = initials end + if juniors and #juniors > 0 then detail.juniors = juniors end + if options and next(options) then detail.options = options end + cache[author] = detail + nofhits = nofhits + 1 + return detail +end + local function splitauthorstring(str) if str then -- str = lpegmatch(cleaner,str) @@ -122,144 +264,32 @@ local function splitauthorstring(str) return end nofused = nofused + 1 + + local remapped = authormap[str] + if remapped then + local detail = cache[remapped] + if detail then + cache[str] = detail + return { detail } + end + end + local authors = cache[str] if authors then - -- hit 1 - -- print("hit 1",author,nofhits,nofused,math.round(100*nofhits/nofused)) return { authors } -- we assume one author end + + local authors = lpegmatch(andsplitter,str) for i=1,#authors do - local author = authors[i] - local detail = cache[author] - if detail then - -- hit 2 - -- print("hit 2",author,nofhits,nofused,math.round(100*nofhits/nofused)) - end - if not detail then - local firstnames, vons, surnames, initials, juniors, options - local split = lpegmatch(commasplitter,author) - local n = #split - detail = { - original = author, - snippets = n, - } - if n == 1 then - -- {First Middle von Last} - local words = lpegmatch(spacesplitter,author) - firstnames, vons, surnames = { }, { }, { } - local i, n = 1, #words - while i <= n do - local w = words[i] - if is_upper(w) then - firstnames[#firstnames+1], i = w, i + 1 - else - break - end - end - while i <= n do - local w = words[i] - if is_upper(w) then - break - else - vons[#vons+1], i = w, i + 1 - end - end - if i <= n then - while i <= n do - surnames[#surnames+1], i = words[i], i + 1 - end - elseif #vons == 0 then - surnames[1] = firstnames[#firstnames] - firstnames[#firstnames] = nil - else - -- mess - end - if #surnames == 0 then - -- safeguard - firstnames = { } - vons = { } - surnames = { author } - else - initials = makeinitials(firstnames) - end - elseif n == 2 then - -- {Last, First} - -- {von Last, First} - firstnames, vons, surnames = { }, { }, { } - local words = lpegmatch(spacesplitter,split[1]) - local i, n = 1, #words - while i <= n do - local w = words[i] - if is_upper(w) then - break - else - vons[#vons+1], i = w, i + 1 - end - end - while i <= n do - surnames[#surnames+1], i = words[i], i + 1 - end - -- - local words = lpegmatch(spacesplitter,split[2]) - local i, n = 1, #words - while i <= n do - local w = words[i] - if is_upper(w) then - firstnames[#firstnames+1], i = w, i + 1 - else - break - end - end - while i <= n do - vons[#vons+1], i = words[i], i + 1 - end - if surnames and firstnames and #surnames == 0 then - -- safeguard - surnames[1] = firstnames[#firstnames] - firstnames[#firstnames] = nil - end - initials = makeinitials(firstnames) - elseif n == 3 then - -- {von Last, First, Jr} - surnames = lpegmatch(spacesplitter,split[1]) - juniors = lpegmatch(spacesplitter,split[2]) - firstnames = lpegmatch(spacesplitter,split[3]) - initials = makeinitials(firstnames) - elseif n == 4 then - -- {Von, Last, First, Jr} - vons = lpegmatch(spacesplitter,split[1]) - surnames = lpegmatch(spacesplitter,split[2]) - juniors = lpegmatch(spacesplitter,split[3]) - firstnames = lpegmatch(spacesplitter,split[4]) - initials = makeinitials(firstnames) - elseif n >= 5 then - -- {Von, Last, First, Jr, F.} - -- {Von, Last, First, Jr, Fr., options} - vons = lpegmatch(spacesplitter,split[1]) - surnames = lpegmatch(spacesplitter,split[2]) - juniors = lpegmatch(spacesplitter,split[3]) - firstnames = lpegmatch(spacesplitter,split[4]) - initials = lpegmatch(spacesplitter,split[5]) - options = split[6] - if options then - options = lpegmatch(optionsplitter,options) - end - end - if firstnames and #firstnames > 0 then detail.firstnames = firstnames end - if vons and #vons > 0 then detail.vons = vons end - if surnames and #surnames > 0 then detail.surnames = surnames end - if initials and #initials > 0 then detail.initials = initials end - if juniors and #juniors > 0 then detail.juniors = juniors end - if options and next(options) then detail.options = options end - cache[author] = detail - nofhits = nofhits + 1 - end - authors[i] = detail + authors[i] = splitauthor(authors[i]) end return authors end +publications.splitoneauthor = splitauthor +publications.splitauthor = splitauthorstring + local function the_initials(initials,symbol,connector) if not symbol then symbol = "." @@ -323,8 +353,8 @@ local function value(i,field) end end -implement { name = "btxcurrentfirstnames", arguments = "integer", actions = function(i) local v = value(i,"initials") if v then context(concat(the_initials(v,currentauthorsymbol))) end end } -implement { name = "btxcurrentinitials", arguments = "integer", actions = function(i) local v = value(i,"firstnames") if v then context(concat(v," ")) end end } +implement { name = "btxcurrentfirstnames", arguments = "integer", actions = function(i) local v = value(i,"firstnames") if v then context(concat(v," ")) end end } +implement { name = "btxcurrentinitials", arguments = "integer", actions = function(i) local v = value(i,"initials") if v then context(concat(the_initials(v,currentauthorsymbol))) end end } implement { name = "btxcurrentjuniors", arguments = "integer", actions = function(i) local v = value(i,"juniors") if v then context(concat(v," ")) end end } implement { name = "btxcurrentsurnames", arguments = "integer", actions = function(i) local v = value(i,"surnames") if v then context(concat(v," ")) end end } implement { name = "btxcurrentvons", arguments = "integer", actions = function(i) local v = value(i,"vons") if v then context(concat(v," ")) end end } @@ -476,7 +506,12 @@ local collapsers = allocate { } publications.authorcollapsers = collapsers -local function default(author) +local function default(author) -- one author + local hash = author.hash + if hash then + return hash + end + local original = author.original local vons = author.vons local surnames = author.surnames local initials = author.initials @@ -485,26 +520,211 @@ local function default(author) local result = { } local nofresult = 0 if vons and #vons > 0 then - nofresult = nofresult + 1 ; result[nofresult] = concat(vons," ") + for j=1,#vons do + nofresult = nofresult + 1 + result[nofresult] = vons[j] + end end if surnames and #surnames > 0 then - nofresult = nofresult + 1 ; result[nofresult] = concat(surnames," ") + for j=1,#surnames do + nofresult = nofresult + 1 + result[nofresult] = surnames[j] + end end if initials and #initials > 0 then - nofresult = nofresult + 1 ; result[nofresult] = concat(the_initials(initials)," ") + initials = the_initials(initials) + for j=1,#initials do + nofresult = nofresult + 1 + result[nofresult] = initials[j] + end end if firstnames and #firstnames > 0 then - nofresult = nofresult + 1 ; result[nofresult] = concat(firstnames," ") + for j=1,#firstnames do + nofresult = nofresult + 1 + result[nofresult] = firstnames[j] + end end if juniors and #juniors > 0 then - nofresult = nofresult + 1 ; result[nofresult] = concat(juniors," ") + for j=1,#juniors do + nofresult = nofresult + 1 + result[nofresult] = juniors[j] + end + end + local hash = concat(result," ") + if trace_hashing then + report("hash: %s -> %s",original,hash) + end + author.hash = hash + return hash +end + +local authorhashers = { } +publications.authorhashers = authorhashers + +-- todo: some hashing + +local function name(authors) + local n = #authors + if n == 0 then + return "" + end + local result = { } + local nofresult = 0 + for i=1,n do + local author = authors[i] + local surnames = author.surnames + if surnames and #surnames > 0 then + for j=1,#surnames do + nofresult = nofresult + 1 + result[nofresult] = surnames[j] + end + end + end + return concat(result," ") +end + +table.setmetatableindex(authorhashers,function(t,k) + t[k] = name + return name +end) + +authorhashers.normal = function(authors) + local n = #authors + if n == 0 then + return "" + end + local result = { } + local nofresult = 0 + for i=1,n do + local author = authors[i] + local vons = author.vons + local surnames = author.surnames + local firstnames = author.firstnames + local juniors = author.juniors + if vons and #vons > 0 then + for j=1,#vons do + nofresult = nofresult + 1 + result[nofresult] = vons[j] + end + end + if surnames and #surnames > 0 then + for j=1,#surnames do + nofresult = nofresult + 1 + result[nofresult] = surnames[j] + end + end + if firstnames and #firstnames > 0 then + for j=1,#firstnames do + nofresult = nofresult + 1 + result[nofresult] = firstnames[j] + end + end + if juniors and #juniors > 0 then + for j=1,#juniors do + nofresult = nofresult + 1 + result[nofresult] = juniors[j] + end + end + end + return concat(result," ") +end + +authorhashers.normalshort = function(authors) + local n = #authors + if n == 0 then + return "" + end + local result = { } + local nofresult = 0 + for i=1,n do + local author = authors[i] + local vons = author.vons + local surnames = author.surnames + local initials = author.initials + local juniors = author.juniors + if vons and #vons > 0 then + for j=1,#vons do + nofresult = nofresult + 1 + result[nofresult] = vons[j] + end + end + if surnames and #surnames > 0 then + for j=1,#surnames do + nofresult = nofresult + 1 + result[nofresult] = surnames[j] + end + end + if initials and #initials > 0 then + initials = the_initials(initials) + for j=1,#initials do + nofresult = nofresult + 1 + result[nofresult] = initials[j] + end + end + if juniors and #juniors > 0 then + for j=1,#juniors do + nofresult = nofresult + 1 + result[nofresult] = juniors[j] + end + end end return concat(result," ") end +authorhashers.normalinverted = authorhashers.normal +authorhashers.invertedshort = authorhashers.normalshort + +local p_clean = Cs ( ( + P("\\btxcmd") / "" -- better keep the argument + + S("`~!@#$%^&*()_-+={}[]:;\"\'<>,.?/|\\") / "" + + lpeg.patterns.utf8character + )^1) + +authorhashers.short = function(authors) + -- a short is a real dumb hardcodes kind of tag and we only support + -- this one because some users might expect it, not because it makes + -- sense + local n = #authors + if n == 0 then + return "unk" + elseif n == 1 then + local surnames = authors[1].surnames + if not surnames or #surnames == 0 then + return "err" + else + local s = surnames[1] + local c = lpegmatch(p_clean,s) + if s ~= c then + report_cite("name %a cleaned to %a for short construction",s,c) + end + return utfsub(c,1,3) + end + else + local t = { } + for i=1,n do + if i > 3 then + t[#t+1] = "+" -- indeed + break + end + local surnames = authors[i].surnames + if not surnames or #surnames == 0 then + t[#t+1] = "?" + else + local s = surnames[1] + local c = lpegmatch(p_clean,s) + if s ~= c then + report_cite("name %a cleaned to %a for short construction",s,c) + end + t[#t+1] = utfsub(c,1,1) + end + end + return concat(t) + end +end + collapsers.default = default -local function writer(key,snippets) +local function authorwriter(key,index) if not key then return "" end @@ -514,8 +734,16 @@ local function writer(key,snippets) local n = #key if n == 0 then return "" + end + if index then + if not key[index] then + return "" + end elseif n == 1 then - local author = key[1] + index = 1 + end + if index then + local author = key[index] local options = author.options if options then for option in next, options do @@ -525,32 +753,43 @@ local function writer(key,snippets) end end end - return default(author) - else - local t = { } - local s = 0 - for i=1,n do - local author = key[i] - local options = author.options - s = s + 1 - if options then - local done = false - for option in next, options do - local collapse = collapsers[option] - if collapse then - t[s] = collapse(author) - done = true - end - end - if not done then - t[s] = default(author) + local hash = default(author) + -- if trace_hashing then + -- report("hash: %s",hash) + -- end + return hash + end + local t = { } + local s = 0 + for i=1,n do + local author = key[i] + local options = author.options + s = s + 1 + if options then + local done = false + for option in next, options do + local collapse = collapsers[option] + if collapse then + t[s] = collapse(author) + done = true end - else + end + if not done then t[s] = default(author) end + else + t[s] = default(author) end - return concat(t," & ") end + local hash = concat(t," & ") + -- if trace_hashing then + -- report("hash: %s",hash) + -- end + return hash +end + +local function writer(key) + return authorwriter(key) -- discard extra arguments in the caller end publications.writers .author = writer @@ -573,13 +812,22 @@ publications.sortmethods.authoryear = { { field = "key", default = "", unknown = "" }, { field = "author", default = "", unknown = "" }, { field = "year", default = "9998", unknown = "9999" }, - { field = "suffix", default = " ", unknown = " " }, + -- { field = "suffix", default = " ", unknown = " " }, { field = "month", default = "13", unknown = "14" }, { field = "day", default = "32", unknown = "33" }, { field = "journal", default = "", unknown = "" }, { field = "volume", default = "", unknown = "" }, - { field = "number", default = "", unknown = "" }, - { field = "title", default = "", unknown = "" }, + -- { field = "number", default = "", unknown = "" }, { field = "pages", default = "", unknown = "" }, + { field = "title", default = "", unknown = "" }, + { field = "index", default = "", unknown = "" }, }, } + +implement { + name = "btxremapauthor", + arguments = { "string", "string" }, + actions = function(k,v) + publications.authormap[k] = v + end +} diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua index 957322f7c..494a13d3c 100644 --- a/tex/context/base/publ-dat.lua +++ b/tex/context/base/publ-dat.lua @@ -381,6 +381,7 @@ function publications.new(name) specifications = { -- used specifications }, + suffixed = false, } -- we delay details till we need it (maybe we just delay the -- individual fields but that is tricky as there can be some @@ -401,10 +402,13 @@ end) local function getindex(dataset,luadata,tag) local found = luadata[tag] if found then - return found.index or 0 + local index = found.index or 0 + dataset.ordered[tag] = index + return index else local index = dataset.nofentries + 1 dataset.nofentries = index + dataset.ordered[index] = tag return index end end @@ -676,7 +680,7 @@ do r = r + 1 ; result[r] = "" r = r + 1 ; result[r] = "" -- - if nice then + if nice then -- will be default local f_entry_start = formatters[" "] local s_entry_stop = " " local f_field = formatters[" %s"] @@ -836,7 +840,8 @@ do end if data then local luadata = current.luadata - for tag, entry in next, data do + -- we want the same index each run + for tag, entry in sortedhash(data) do if type(entry) == "table" then entry.index = getindex(current,luadata,tag) entry.tag = tag @@ -935,12 +940,13 @@ do function enhancers.order(dataset) local luadata = dataset.luadata - local ordered = sortedkeys(luadata) - local total = #ordered - for i=1,total do - ordered[i] = luadata[ordered[i]] + local ordered = dataset.ordered + for i=1,#ordered do + local tag = ordered[i] + if type(tag) == "string" then + ordered[i] = luadata[tag] + end end - dataset.ordered = ordered end function enhancers.details(dataset) diff --git a/tex/context/base/publ-fnd.lua b/tex/context/base/publ-fnd.lua index 909b102db..32d0c11be 100644 --- a/tex/context/base/publ-fnd.lua +++ b/tex/context/base/publ-fnd.lua @@ -45,93 +45,6 @@ local word = Cs(lpegpatterns.unquoted + lpegpatterns.argument + valid^1) local simple = C(valid^1) local number = C(valid^1) ------ f_string_key = formatters[" local s_%s = entry[%q] if s_%s then s_%s = lower(s_%s) end "] ------ f_number_key = formatters[" local n_%s = tonumber(entry[%q]) or 0"] ------ f_field_key = formatters[" local f_%s = entry[%q] or ''"] - --- getfuzzy(entry,%q,categories) - --- local f_string_key = formatters[" local s_%s = get(entry,%q)\n if s_%s then s_%s = lower(s_%s) end"] --- local f_field_key = formatters[" local f_%s = get(entry,%q) or ''"] --- local f_field_key_c = formatters[" local c_%s = get(entry,%q,categories) or ''"] --- local f_number_key = formatters[" local n_%s = tonumber(get(entry,%q)) or 0"] --- --- local f_string_match = formatters["(s_%s and find(s_%s,%q))"] --- local f_number_match = formatters["(n_%s and n_%s >= %s and n_%s <= %s)"] --- local f_field_match = formatters["f_%s"] --- local f_field_match_c = formatters["c_%s"] --- --- local f_all_match = formatters["anywhere(entry,%q)"] - --- topattern(lowercase(word)) : utflowercase + only *? - --- local match = ( (key + wildcard) * (colon/"") ) * word * Carg(1) / function(key,_,word,keys) --- if key == "*" or key == "any" then --- keys.anywhere = true --- if word == "" or word == "*" then --- return "true" --- else --- return f_all_match(topattern(lowercase(word))) --- end --- else --- keys[key] = f_string_key(key,key,key,key,key) --- return f_string_match(key,key,topattern(lowercase(word))) --- end --- end --- --- local default = simple * Carg(1) / function(word,keys) --- keys.anywhere = true --- if word == "" or word == "*" then --- return "true" --- else --- return f_all_match(topattern(lowercase(word))) --- end --- end --- --- local range = key * (colon/"") * number * (dash/"") * number * Carg(1) / function(key,_,first,_,last,keys) --- keys[key] = f_number_key(key,key) --- return f_number_match(key,key,tonumber(first) or 0,key,tonumber(last) or 0) --- end --- --- local field = (P("field:")/"") * key * Carg(1) / function(_,key,keys) --- keys[key] = f_field_key(key,key) --- return f_field_match(key) --- end --- --- local cast = (P("cast:")/"") * key * Carg(1) / function(_,key,keys) --- keys[key] = f_field_key_c(key,key) --- return f_field_match_c(key) --- end --- --- local compare = C("==") + P("=")/"==" + P("!=")/"~=" + P("<>")/"~=" --- --- local b_match = lparent --- local e_match = rparent * space^0 * (#P(-1) + P(",")/" or ") -- maybe also + -> and --- local f_match = ((field + cast + range + match + space + compare + P(1))-e_match)^1 --- local p_match = b_match * default * e_match --- + b_match * f_match * e_match --- --- local pattern = Cs(Cc("(") * (P("match")/"" * space^0 * p_match)^1 * Cc(")")) - --- field contains fieldname:nonspaces|"whatever"|'whatever'|{whatever} --- field exact fieldname=nonspaces|"whatever"|'whatever'|{whatever} --- set contains [fieldname]:nonspaces|"whatever"|'whatever'|{whatever} --- set exact [fieldname]=nonspaces|"whatever"|'whatever'|{whatever} --- --- with * : any sequence --- ? : one character --- --- and match(),match() ... equivalent to () and () --- --- <123 444> : range --- --- unquoted = field --- [..] = set --- --- () and or not --- --- spaces are mandate (at least for now) - local key = C(R("az","AZ")^1) local contains = S(":~") local exact = P("=") diff --git a/tex/context/base/publ-imp-apa.lua b/tex/context/base/publ-imp-apa.lua index c5d2512fd..1d894f261 100644 --- a/tex/context/base/publ-imp-apa.lua +++ b/tex/context/base/publ-imp-apa.lua @@ -432,10 +432,12 @@ categories.electronic = { categories.film = { sets = { doi = generic.doi, + author = { "producer", "director", }, }, required = { - "producer", "director", - "title", "year", + "author", + "title", + "year", "address", "publisher", -- aka studio }, optional = { diff --git a/tex/context/base/publ-imp-apa.mkvi b/tex/context/base/publ-imp-apa.mkvi index a1814b0a4..7cab4a131 100644 --- a/tex/context/base/publ-imp-apa.mkvi +++ b/tex/context/base/publ-imp-apa.mkvi @@ -22,7 +22,7 @@ %D edition ={Sixth}, %D address ={Washington, DC}, %D publisher={American Psychological Association}, -%D pages ={291}, +%D Xpages ={291}, %D url ={http://www.apa.org/books/}, %D } %D \stopTEX @@ -50,9 +50,9 @@ \setupbtxlist [apa] [\c!alternative=\v!paragraph, - \c!width=\v!fit, - \c!distance=.5\emwidth, - \c!margin=3\emwidth] + %\c!width=\v!fit, + %\c!distance=.5\emwidth, + \c!margin=3.5\emwidth] \definebtx [apa:list] @@ -88,12 +88,24 @@ [apa:list] \definebtx - [apa:list:invertedshort] + [apa:list:numbering] [apa:list] \definebtx - [apa:list:short] - [apa:list] + [apa:list:numbering:num] + [apa:list:numbering] + +\definebtx + [apa:list:numbering:yes] + [apa:list:numbering:num] + +\definebtx + [apa:list:numbering:short] + [apa:list:numbering:num] + +\definebtx + [apa:list:numbering:bib] + [apa:list:numbering:num] % Next, we define a namespace for each category @@ -229,13 +241,13 @@ % root. \definebtx - [apa:page] + [apa:\s!page] [\s!page] \definebtx - [apa:page:list] - [apa:page] - [\c!command={\wordright}] + [apa:\s!page:list] + [apa:\s!page] + [\c!pagecommand={\wordright}] % Then define and set cite parameters. @@ -247,7 +259,8 @@ \c!etallimit=5, \c!etaldisplay=1, % TODO: when 2-4, show all first time, etaldisplay subsequently... \c!authorconversion=\v!name, - \c!sorttype=authoryear, + \c!sorttype=normal, + \c!compress=\v!yes, % note that cite sorts only work with compress=yes. \c!separator:names:2={,\space}, \c!separator:names:3={,\space\btxlabeltext{apa:and}\space}, % not \textampersand \c!separator:names:4={\space\btxlabeltext{apa:and}\space}] % not \textampersand @@ -259,10 +272,9 @@ \definebtx [apa:cite:authoryear] [apa:cite:author] - [\c!left={\removeunwantedspaces\pushpunctuation\btxspace(}, - \c!right={)\poppunctuation}, - \c!inbetween={,\space}, - \c!compress=\v!yes] + [\c!left={(}, + \c!right={)}, + \c!inbetween={,\space}] \definebtx [apa:cite:default] @@ -278,9 +290,8 @@ \definebtx [apa:cite:authornum] [apa:cite:author] - [\c!left={\removeunwantedspaces\pushpunctuation\btxspace(}, - \c!right={)\poppunctuation}, - \c!sorttype=authornum] + [\c!left={(}, + \c!right={)}] \definebtx [apa:cite:authorref] @@ -289,28 +300,26 @@ \definebtx [apa:cite:author:num] % todo [apa:cite:authornum] - [\c!left={\removeunwantedspaces\pushpunctuation\btxspace[}, - \c!right={]\poppunctuation}] + [\c!left={[}, + \c!right={]}] \definebtx - [apa:cite:author:year] % todo + [apa:cite:author:year] % todo [apa:cite] \definebtx [apa:cite:author:years] % todo [apa:cite:authoryears] [\c!inbetween=, - \c!left=(, - \c!right=)] + \c!left={\space(}, + \c!right={)}] \definebtx [apa:cite:year] [apa:cite] [\c!separator:2={,\space}, % :0 and :1 - between items of a list \c!separator:3={,\space\btxlabeltext{apa:and}\space}, % not \textampersand - \c!separator:4={\space\btxlabeltext{apa:and}\space}, % not \textampersand - \c!compress=\v!yes, - \c!sorttype=\v!default] + \c!separator:4={\space\btxlabeltext{apa:and}\space}] % not \textampersand \definebtx [apa:cite:title] @@ -328,15 +337,12 @@ \definebtx [apa:cite:tag] [apa:cite] - [\c!left={\removeunwantedspaces\pushpunctuation\btxspace[}, - \c!right={]\poppunctuation}] + [\c!left={[}, + \c!right={]}] -\definebtx - [apa:cite:key] - [apa:cite:tag] \definebtx - [apa:cite:serial] + [apa:cite:index] [apa:cite] [\c!left={[}, \c!right={]}] @@ -346,7 +352,7 @@ [apa:cite] [\c!left=, \c!right=, - [\c!separator:2={,\space}, % :0 and :1 - between items of a list + \c!separator:2={,\space}, % :0 and :1 - between items of a list \c!separator:3={,\space\btxlabeltext{apa:and}\space}, % not \textampersand \c!separator:4={\space\btxlabeltext{apa:and}\space}] % not \textampersand @@ -357,12 +363,6 @@ \definebtx [apa:cite:keywords] [apa:cite] - [\c!left={(}, - \c!right={)}] - -\definebtx - [apa:cite:invertedshort] - [apa:cite] \definebtx [apa:cite:short] @@ -373,12 +373,6 @@ \definebtx [apa:cite:category] [apa:cite] - [\c!left={[}, - \c!right={]}] - -\definebtx - [apa:cite:type] - [apa:cite:category] \definebtx [apa:cite:url] @@ -393,8 +387,7 @@ \definebtx [apa:cite:num] [apa:cite] - [\c!compress=\v!yes, - \c!left={[}, + [\c!left={[}, \c!right={]}, \c!separator:2={,}, % no space \c!separator:3=\btxparameter{\c!separator:2}, @@ -616,7 +609,7 @@ \startsetups btx:apa:cite:author:year \texdefinition{\s!btx:\s!cite:concat} - \btxparameter\c!left + %\btxparameter\c!left \ifx\currentbtxfirst\empty \btxlabeltext{apa:nd} \else @@ -625,18 +618,14 @@ \currentbtxfirst } \ifx\currentbtxsecond\empty \else - \btxparameter\v!inbetween + \btxparameter\c!range \texdefinition {\s!btx:\s!cite:inject} { \currentbtxsecond } \fi - \ifx\currentbtxthird\empty \else - \texdefinition {\s!btx:\s!cite:inject} { - \currentbtxthird - } - \fi + \btxflushsuffix \fi - \btxparameter\c!right + %\btxparameter\c!right \stopsetups \startsetups btx:apa:cite:author:years @@ -645,7 +634,7 @@ % The following differs from the default by including the labels p. and pp. -\startsetups btx:apa:page:list +\startsetups btx:apa:list:page \fastsetup{\s!btx:\s!page:concat} \ifx\currentbtxlastpage\empty \btxlabeltext{apa:page} @@ -740,7 +729,7 @@ \begingroup \language[\mainbtxlanguage] \btxleftbracket - \btxusecommand[apa:list:title:\currentbtxcategory] { + \btxusecommand [apa:list:title:\currentbtxcategory] { \btxflush{#title:\mainbtxlanguage} } \btxrightbracket @@ -752,7 +741,7 @@ \starttexdefinition btx:apa:composed-title #title \begingroup \language[\currentbtxlanguage] - \btxusecommand[apa:list:title:\currentbtxcategory] { + \btxusecommand [apa:list:title:\currentbtxcategory] { \btxflush{#title} \btxdoif {sub#title} { \btxcolon @@ -801,8 +790,7 @@ \starttexdefinition btx:apa:suffixedyear \btxdoifelse {year} { \btxflush{year} - \btxflush{suffix} - %or \btxflush{suffixedyear} + \btxflushsuffix } { \btxlabeltext{apa:nd} } @@ -813,7 +801,7 @@ \starttexdefinition btx:apa:author-or-editor #author \btxdoif {#author} { \btxflush{#author} - \doif {\btxfoundname{#author}} {editor} { + \doifelse {\btxfoundname{#author}} {editor} { \btxleftparenthesis \btxsingularorplural {editor} { \btxlabeltext{apa:Editor} @@ -821,6 +809,40 @@ \btxlabeltext{apa:Editors} } \btxrightparenthesisperiod + } { + \doifelse {\btxfoundname{#author}} {producer} { + \btxleftparenthesis + \btxsingularorplural {producer} { + \btxlabeltext{apa:Producer} + } { + \btxlabeltext{apa:Producers} + } + \btxrightparenthesis + \btxdoifelse {director} { + \removeunwantedspaces + \btxparameter{\c!separator:names:3} + \btxflush{director} + \btxleftparenthesis + \btxsingularorplural {director} { + \btxlabeltext{apa:Director} + } { + \btxlabeltext{apa:Directors} + } + \btxrightparenthesisperiod + } { + \btxperiod + } + } { + \doif {\btxfoundname{#author}} {director} { + \btxleftparenthesis + \btxsingularorplural {director} { + \btxlabeltext{apa:Director} + } { + \btxlabeltext{apa:Directors} + } + \btxrightparenthesisperiod + } + } } } \stoptexdefinition @@ -882,7 +904,7 @@ \doif {\currentbtxcategory} {techreport} { \texdefinition{btx:apa:leftparenthesis-or-comma} \btxdoifelse {type} { - \btxusecommand[apa:list:type] { + \btxusecommand [apa:list:type] { \btxflush{type} } } { @@ -932,7 +954,7 @@ \btxdoif {journal} { \btxspace \btxstartstyleandcolor[apa:list:journal] - \btxusecommand[apa:list:journal] { + \btxusecommand [apa:list:journal] { \btxflush{journal} } \btxdoifelse {volume} { @@ -1081,6 +1103,11 @@ \startsetups btx:apa:list:article \texdefinition{btx:apa:authoryear} \texdefinition{btx:apa:title-if-not-placed} + \btxdoif {type} { + \btxleftbracket + \btxflush{type} + \btxrightbracketperiod + } \texdefinition{btx:apa:journal-volume-number-pages} \texdefinition{btx:apa:url-doi-note} \stopsetups @@ -1203,7 +1230,7 @@ \texdefinition{btx:apa:title-if-not-placed} \btxleftparenthesis \btxdoifelse {type} { - \btxusecommand[apa:list:type] { + \btxusecommand [apa:list:type] { \btxflush{type} } } { @@ -1330,35 +1357,7 @@ % Optional fields: subtitle, type, note, url, doi \startsetups btx:apa:list:film - \btxdoif {producer} { - \btxflush{producer} - \btxleftparenthesis - \btxsingularorplural {producer} { - \btxlabeltext{apa:Producer} - } { - \btxlabeltext{apa:Producers} - } - \btxrightparenthesis - \btxdoifelse {director} { - \removeunwantedspaces - \btxparameter{\c!separator:names:3} - } { - \btxperiod - } - } - \btxdoif {director} { - \btxflush{director} - \btxleftparenthesis - \btxsingularorplural {director} { - \btxlabeltext{apa:Director} - } { - \btxlabeltext{apa:Directors} - } - \btxrightparenthesisperiod - } - \btxleftparenthesis - \texdefinition{btx:apa:suffixedyear} - \btxrightparenthesisperiod + \texdefinition{btx:apa:authoryear} \texdefinition {btx:apa:title} \btxleftbracket \btxdoifelse {type} { @@ -1432,7 +1431,7 @@ \startsetups btx:apa:list:literal %\btxleftparenthesis \removeunwantedspaces( - \btxflush{key} + \btxflush{tag} \btxrightparenthesis \btxdoif {text} { \btxflush{text} diff --git a/tex/context/base/publ-imp-aps.lua b/tex/context/base/publ-imp-aps.lua index 1ec75d7d1..c15ffe918 100644 --- a/tex/context/base/publ-imp-aps.lua +++ b/tex/context/base/publ-imp-aps.lua @@ -462,7 +462,7 @@ categories.other = { categories.literal = { sets = { - author = { "key" }, -- need to check this! + author = { "tag" }, -- need to check this! }, required = { "text" diff --git a/tex/context/base/publ-imp-aps.mkvi b/tex/context/base/publ-imp-aps.mkvi index 3bc2a1d21..cd05fce7f 100644 --- a/tex/context/base/publ-imp-aps.mkvi +++ b/tex/context/base/publ-imp-aps.mkvi @@ -22,7 +22,7 @@ %D editor ={Waldron, A and Judd, P. and Miller, V.}, %D address ={Ridge, NY}, %D publisher={American Physical Society}, -%D pages ={26}, +%D Xpages ={26}, %D url ={http://journals.aps.org/files/styleguide-pr.pdf} %D } %D \stopTEX @@ -38,7 +38,7 @@ \c!etaldisplay=\btxparameter\c!etallimit, %c!journalconversion=\v!normal, \c!monthconversion=\v!month, - optionaltitle=\v!yes, + \c!title=\v!yes, \c!separator:names:2={,\space}, \c!separator:names:3={,\space\btxlabeltext{aps:and}\space}, % not \textampersand \c!separator:names:4= {\space\btxlabeltext{aps:and}\space}] % not \textampersand @@ -49,6 +49,10 @@ [aps] [\c!specification=aps] +\setupbtxlist + [aps] + [\c!alternative=b] % spaces + \definebtx [aps:list] [aps] @@ -75,34 +79,26 @@ [aps:list] \definebtx - [aps:list:invertedshort] + [aps:list:numbering] [aps:list] -% This is for numbering=num - \definebtx - [aps:list:num] - [aps:list] + [aps:list:numbering:num] + [aps:list:numbering] [left={[}, right={]}] -% This is for numbering=yes - \definebtx - [aps:list:yes] - [aps:list:num] - -% This is for numbering=short + [aps:list:numbering:yes] + [aps:list:numbering:num] \definebtx - [aps:list:short] - [aps:list:num] - -% This is for numbering=bib + [aps:list:numbering:short] + [aps:list:numbering:num] \definebtx - [aps:list:bib] - [aps:list:num] + [aps:list:numbering:bib] + [aps:list:numbering:num] %D In order to be able to get journals expanded (or normalized or abbreviated) you need %D to load a list: @@ -232,20 +228,22 @@ % root. \definebtx - [aps:page] + [aps:\s!page] [\s!page] \definebtx - [aps:page:list] - [aps:page] - [\c!command={\wordright}] + [aps:\s!page:list] + [aps:\s!page] + %[\c!pagecommand={\wordright}] % Then define and set all cite parameters \definebtx [aps:cite] [aps] - [\c!authorconversion=\v!name] + [\c!authorconversion=\v!name, + \c!compress=\v!yes, + \c!sorttype=normal] \definebtx [aps:cite:author] @@ -269,8 +267,7 @@ [aps:cite:authornum] [aps:cite:author] [\c!left={(}, - \c!right={)}, - \c!sorttype=authornum] + \c!right={)}] \definebtx [aps:cite:authorref] @@ -292,14 +289,12 @@ [aps:cite:author:years] % todo [aps:cite:authoryears] [\c!inbetween=, - \c!left=(, - \c!right=)] + \c!left={\space(}, + \c!right={)}] \definebtx [aps:cite:year] [aps:cite] - [\c!compress=\v!yes, - \c!sorttype=year] \definebtx [aps:cite:title] @@ -318,11 +313,7 @@ \c!right={]}] \definebtx - [aps:cite:key] - [aps:cite:tag] - -\definebtx - [aps:cite:serial] + [aps:cite:index] [aps:cite] [\c!left={[}, \c!right={]}] @@ -332,7 +323,7 @@ [aps:cite] [\c!left=, \c!right=, - [\c!separator:2={,\space}, % :0 and :1 - between items of a list + \c!separator:2={,\space}, % :0 and :1 - between items of a list \c!separator:3={,\space\btxlabeltext{aps:and}\space}, % not \textampersand \c!separator:4= {\space\btxlabeltext{aps:and}\space}] % not \textampersand @@ -346,10 +337,6 @@ [\c!left={(}, \c!right={)}] -\definebtx - [aps:cite:invertedshort] - [aps:cite] - \definebtx [aps:cite:short] [aps:cite] @@ -359,12 +346,6 @@ \definebtx [aps:cite:category] [aps:cite] - [\c!left={[}, - \c!right={]}] - -\definebtx - [aps:cite:type] - [aps:cite:category] \definebtx [aps:cite:url] @@ -379,13 +360,12 @@ \definebtx [aps:cite:num] [aps:cite] - [\c!compress=\v!yes, - \c!left={[}, + [\c!left={[}, \c!right={]}, %\c!left=, % TODO: PRB uses superscript references... %\c!right=, % and after punctuation, PRA, C, D, E, and L are before! %\c!command={\high}, - \c!separator:2={,}, % no space + \c!separator:2={\btxcommabreak}, \c!separator:3=\btxparameter{\c!separator:2}, \c!separator:4=\btxparameter{\c!separator:2}] @@ -579,16 +559,12 @@ \currentbtxfirst } \ifx\currentbtxsecond\empty \else - \btxparameter\v!inbetween + \btxparameter\c!inbetween \texdefinition {\s!btx:\s!cite:inject} { \currentbtxsecond } \fi - \ifx\currentbtxthird\empty \else - \texdefinition {\s!btx:\s!cite:inject} { - \currentbtxthird - } - \fi + \btxflushsuffix \fi \stopsetups @@ -596,7 +572,7 @@ \fastsetup{btx:aps:cite:author:year} \stopsetups -\startsetups [btx:aps:page:list] +\startsetups [btx:aps:list:page] \fastsetup{\s!btx:\s!page:concat} \ifx\currentbtxlastpage\empty \btxlabeltext{aps:page} @@ -650,7 +626,7 @@ \starttexdefinition btx:aps:composed-title #title \begingroup \language[\currentbtxlanguage] - \btxusecommand[aps:list:title:\currentbtxcategory] { + \btxusecommand [aps:list:title:\currentbtxcategory] { \btxflush{#title} \btxdoif {sub#title} { \btxcolon @@ -681,7 +657,7 @@ \stoptexdefinition \starttexdefinition btx:aps:optional-title - \doif{\btxparameter{optionaltitle}}\v!yes { + \doif{\btxparameter{\c!title}}\v!yes { \texdefinition {btx:aps:title} } \stoptexdefinition @@ -740,7 +716,7 @@ \starttexdefinition btx:aps:editionset \doif {\currentbtxcategory} {techreport} { \btxdoifelse {type} { - \btxusecommand[\currentbtx:type] { + \btxusecommand [\currentbtx:type] { \btxflush{type} } } { @@ -996,7 +972,7 @@ \texdefinition{btx:aps:title} \btxleftparenthesis \btxdoifelse {type} { - \btxusecommand[aps:list:type] { + \btxusecommand [aps:list:type] { \btxflush{type} } } { @@ -1146,7 +1122,7 @@ \startsetups btx:aps:list:literal %\btxleftparenthesis \removeunwantedspaces( - \btxflush{key} + \btxflush{tag} \btxrightparenthesis \btxdoif {text} { \btxflush{text} diff --git a/tex/context/base/publ-imp-cite.mkvi b/tex/context/base/publ-imp-cite.mkvi index dfc16c795..a84beddd7 100644 --- a/tex/context/base/publ-imp-cite.mkvi +++ b/tex/context/base/publ-imp-cite.mkvi @@ -50,8 +50,9 @@ \startsetups btx:cite:unknown \begingroup + \tttf \btxcitereference - unknown: \currentbtxfirst + \currentbtxfirst \endgroup \stopsetups @@ -65,109 +66,84 @@ {\tt <\currentbtxreference>} \stopsetups +\starttexdefinition btx:cite:concat + \btxparameter{\c!separator:\number\currentbtxconcat} +\stoptexdefinition + +% when we have an author-year combination, the first and seconds is not +% fields data but something more complex (that itself calls for a setup) + % \startsetups btx:cite:normal +% \texdefinition{\s!btx:\s!cite:concat} +% \currentbtxlefttext % \ifx\currentbtxfirst\empty % \fastsetup{\s!btx:\s!cite:\s!empty} -% \else\ifx\currentbtxsecond\empty -% \btxcitereference -% \currentbtxfirst -% \ifx\currentbtxthird\empty \else -% \currentbtxthird -% \fi % \else -% \btxcitereference -% \currentbtxfirst -% \btxparameter\v!inbetween -% \currentbtxsecond -% \ifx\currentbtxthird\empty \else -% \currentbtxthird +% \texdefinition {\s!btx:\s!cite:inject} { +% \btxcitereference +% \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { +% \currentbtxfirst +% } +% } +% \ifx\currentbtxsecond\empty +% \btxflushsuffix +% \else +% \btxparameter\c!inbetween +% \texdefinition {\s!btx:\s!cite:inject} { +% \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { +% \currentbtxsecond +% } +% } +% % quite likely an error +% \btxflushsuffix % \fi -% \fi\fi +% \fi +% \currentbtxrighttext % \stopsetups -%\startsetups btx:cite:range -% \ifx\currentbtxfirst\empty -% \fastsetup{\s!btx:\s!cite:\s!empty} -% \else\ifx\currentbtxsecond\empty -% \btxcitereference -% \currentbtxfirst -% \ifx\currentbtxthird\empty \else -% \currentbtxthird -% \fi -% \else -% \btxcitereference -% \currentbtxfirst -% \btxparameter\c!range -% \currentbtxsecond -% \ifx\currentbtxthird\empty \else -% \currentbtxthird -% \fi -% \fi\fi -%\stopsetups - -\starttexdefinition btx:cite:concat - \btxparameter{\c!separator:\number\currentbtxconcat} -\stoptexdefinition - \startsetups btx:cite:normal \texdefinition{\s!btx:\s!cite:concat} \currentbtxlefttext \ifx\currentbtxfirst\empty \fastsetup{\s!btx:\s!cite:\s!empty} - \else + \else\ifx\currentbtxsecond\empty \texdefinition {\s!btx:\s!cite:inject} { \btxcitereference - \btxusecommand[\currentbtxspecification:cite:\currentbtxcitealternative] { + \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { \currentbtxfirst + \btxflushsuffix } } - \ifx\currentbtxsecond\empty \else - \btxparameter\v!inbetween - \texdefinition {\s!btx:\s!cite:inject} { - \btxusecommand[\currentbtxspecification:cite:\currentbtxcitealternative] { - \currentbtxsecond - } - } - \fi - \ifx\currentbtxthird\empty \else - \texdefinition {\s!btx:\s!cite:inject} { - \btxusecommand[\currentbtxspecification:cite:\currentbtxcitealternative] { - \currentbtxthird - } - } - \fi - \fi - \currentbtxrighttext -\stopsetups - -\startsetups btx:cite:author - \texdefinition{\s!btx:\s!cite:concat} - \btxparameter\c!left - \currentbtxlefttext - \ifx\currentbtxfirst\empty - \fastsetup{\s!btx:\s!cite:\s!empty} \else + % \texdefinition {\s!btx:\s!cite:inject} { + % \btxcitereference + % \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { + % \currentbtxfirst + % } + % } + % \btxparameter\c!inbetween + % \texdefinition {\s!btx:\s!cite:inject} { + % \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { + % \currentbtxsecond + % } + % } + % \btxflushsuffix + % + % probably better: \texdefinition {\s!btx:\s!cite:inject} { \btxcitereference - \currentbtxfirst - } - \fi - \ifx\currentbtxsecond\empty \else - \relax % keeps a following space - \btxparameter\v!inbetween - \texdefinition {\s!btx:\s!cite:inject} { - \currentbtxsecond - } - \fi - \ifx\currentbtxthird\empty \else - \texdefinition {\s!btx:\s!cite:inject} { - \currentbtxthird + \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { + \currentbtxfirst + \btxparameter\c!inbetween + \currentbtxsecond + \btxflushsuffix + } } - \fi + \fi\fi \currentbtxrighttext - \btxparameter\c!right \stopsetups + \startsetups btx:cite:range \texdefinition{\s!btx:\s!cite:concat} \currentbtxlefttext @@ -176,15 +152,13 @@ \else \texdefinition {\s!btx:\s!cite:inject} { \btxcitereference - \btxusecommand[\currentbtxspecification:cite:\currentbtxcitealternative] { + \btxusecommand [\currentbtxspecification:cite:\currentbtxcitealternative] { \currentbtxfirst \ifx\currentbtxsecond\empty \else \btxparameter\c!range \currentbtxsecond \fi - \ifx\currentbtxthird\empty \else - \currentbtxthird - \fi + \btxflushsuffix } } \fi @@ -218,23 +192,30 @@ % AB: not so sure about that. Why define them in default rather than here? +\startsetups \s!btx:\s!cite:author + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups \startsetups \s!btx:\s!cite:authoryear - \fastsetup{\s!btx:\s!cite:author} + \fastsetup{\s!btx:\s!cite:normal} \stopsetups \startsetups \s!btx:\s!cite:authoryears - \fastsetup{\s!btx:\s!cite:authoryear} + \fastsetup{\s!btx:\s!cite:normal} \stopsetups \startsetups \s!btx:\s!cite:authornum - \fastsetup{\s!btx:\s!cite:authoryear} + \fastsetup{\s!btx:\s!cite:normal} \stopsetups \startsetups \s!btx:\s!cite:authorref - \ifx{\\s!btxparameter\c!alternative}{authoryear} + % what a crap ... no one will ever understand this module .. it makes no + % sense to have these tests, just let users set the right variant .. + \doifelse{\btxparameter\c!alternative} {authoryear} { \fastsetup{\s!btx:\s!cite:authoryears} - \else\ifx{\btxparameter\c!alternative}{num} - \fastsetup{\s!btx:\s!cite:authornum} - \else - \fastsetup{\s!btx:\s!cite:author} - \fi\fi + } { + \doifelse {\btxparameter\c!alternative} {num} { + \fastsetup{\s!btx:\s!cite:authornum} + } { + \fastsetup{\s!btx:\s!cite:author} + } + } \stopsetups \startsetups \s!btx:\s!cite:num \fastsetup{\s!btx:\s!cite:range} @@ -248,9 +229,6 @@ \startsetups \s!btx:\s!cite:year \fastsetup{\s!btx:\s!cite:range} \stopsetups -\startsetups \s!btx:\s!cite:short - \fastsetup{\s!btx:\s!cite:range} -\stopsetups \startsetups \s!btx:\s!cite:author:num \fastsetup{\s!btx:\s!cite:range} \stopsetups @@ -258,20 +236,19 @@ \fastsetup{\s!btx:\s!cite:range} \stopsetups \startsetups \s!btx:\s!cite:author:years - \fastsetup{\s!btx:\s!cite:concat}%?? in range already? \fastsetup{\s!btx:\s!cite:range} \stopsetups -\startsetups \s!btx:\s!cite:serial +\startsetups \s!btx:\s!cite:index \fastsetup{\s!btx:\s!cite:range} \stopsetups -\startsetups \s!btx:\s!cite:tag +\startsetups \s!btx:\s!cite:category \fastsetup{\s!btx:\s!cite:normal} \stopsetups -\startsetups \s!btx:\s!cite:key +\startsetups \s!btx:\s!cite:short \fastsetup{\s!btx:\s!cite:normal} \stopsetups -\startsetups \s!btx:\s!cite:category +\startsetups \s!btx:\s!cite:tag \fastsetup{\s!btx:\s!cite:normal} \stopsetups @@ -280,15 +257,16 @@ \startsetups \s!btx:\s!cite:keywords \fastsetup{\s!btx:\s!cite:list} \stopsetups -\startsetups \s!btx:\s!cite:type - \fastsetup{\s!btx:\s!cite:normal} -\stopsetups \startsetups \s!btx:\s!cite:title \fastsetup{\s!btx:\s!cite:normal} \stopsetups \startsetups \s!btx:\s!cite:pages \fastsetup{\s!btx:\s!cite:range} \stopsetups + +% is the next one used? +% Yes, bibtex is a mess and one can have pages or sometimes page + \startsetups \s!btx:\s!cite:page \fastsetup{\s!btx:\s!cite:normal} \stopsetups diff --git a/tex/context/base/publ-imp-default.mkvi b/tex/context/base/publ-imp-default.mkvi index 49a0b9eae..099daa41f 100644 --- a/tex/context/base/publ-imp-default.mkvi +++ b/tex/context/base/publ-imp-default.mkvi @@ -45,6 +45,8 @@ [\s!default:\s!cite] [\s!default] [\c!alternative=num, + [\c!compress=\v!yes, + \c!sorttype=normal, \c!authorconversion=\v!name] % We define [page] settings in the default namespace, inheriting the root @@ -77,12 +79,6 @@ [\s!default:\s!list:doi] [\s!default:\s!list] -\definebtx - [\s!default:\s!list:invertedshort] - [\s!default:\s!list] - -% normalshort? - \definebtx [\s!default:\s!list:short] [\s!default:\s!list] @@ -157,13 +153,11 @@ \definebtx [\s!default:\s!cite:year] [\s!default:\s!cite] - [\c!compress=\v!yes, - \c!sorttype=year] \definebtx [\s!default:\s!cite:title] [\s!default:\s!cite] - [command={\language[\currentbtxlanguage]}, % BAH + [\c!command={\language[\currentbtxlanguage]}, % BAH \c!style=\v!italic] \definebtx @@ -173,11 +167,7 @@ \c!right={]}] \definebtx - [\s!default:\s!cite:key] - [\s!default:\s!cite:tag] - -\definebtx - [\s!default:\s!cite:serial] + [\s!default:\s!cite:index] [\s!default:\s!cite] [\c!left={[}, \c!right={]}] @@ -198,10 +188,6 @@ [\c!left={(}, \c!right={)}] -\definebtx - [\s!default:\s!cite:invertedshort] - [\s!default:\s!cite] - \definebtx [\s!default:\s!cite:short] [\s!default:\s!cite] @@ -211,12 +197,6 @@ \definebtx [\s!default:\s!cite:category] [\s!default:\s!cite] - [\c!left={[}, - \c!right={]}] - -\definebtx - [\s!default:\s!cite:type] - [\s!default:\s!cite:category] \definebtx [\s!default:\s!cite:url] @@ -231,10 +211,9 @@ \definebtx [\s!default:\s!cite:num] [\s!default:\s!cite] - [\c!compress=\v!yes, - \c!left={[}, + [\c!left={[}, \c!right={]}, - \c!separator:2={,}, % no space + \c!separator:2=\btxcommabreak, \c!separator:3=\btxparameter{\c!separator:2}, \c!separator:4=\btxparameter{\c!separator:2}] @@ -343,7 +322,7 @@ \btxdoif {title} { \btxspace \btxstartstyleandcolor [default:list:title:\currentbtxcategory] - \btxusecommand[default:list:title:\currentbtxcategory] { + \btxusecommand [default:list:title:\currentbtxcategory] { \texdefinition{btx:default:composed-title} } \btxstopstyleandcolor @@ -368,14 +347,14 @@ \starttexdefinition btx:default:year \btxflush{year} - \btxflush{suffix} + \btxflushsuffix \stoptexdefinition \starttexdefinition btx:default:journal \btxdoif {journal} { \btxspace \btxstartstyleandcolor [default:list:journal] - \btxusecommand[default:list:journal] { + \btxusecommand [default:list:journal] { \btxflush{journal} } \btxstopstyleandcolor @@ -486,109 +465,4 @@ \currentbtxrighttext \stopsetups -%D Citations: - -% \startsetups \s!btx:\s!default:\s!cite:author -% \fastsetup{\s!btx:\s!cite:author} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:authoryear -% \fastsetup{\s!btx:\s!cite:author} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:authoryears -% \fastsetup{\s!btx:\s!cite:author} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:authornum -% \fastsetup{\s!btx:\s!cite:author} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:authorref -% \fastsetup{\s!btx:\s!cite:authorref} -% \stopsetups -% -% \startsetups \s!btx:\s!default:\s!cite:author:num -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:author:year -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:author:years -% \fastsetup{\s!btx:\s!cite:concat} -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% -% \startsetups \s!btx:\s!default:\s!cite:keywords -% \fastsetup{\s!btx:\s!cite:list} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:year -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:short -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:serial -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:tag -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:key -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:category -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:type -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:num -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:default -% \fastsetup{\s!btx:\s!default:\s!cite:num} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:textnum -% \fastsetup{\s!btx:\s!default:\s!cite:num} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:title -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:pages -% \fastsetup{\s!btx:\s!cite:range} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:page -% \fastsetup{\s!btx:\s!cite:normal} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:doi -% \fastsetup{\s!btx:\s!cite:url} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:url -% \fastsetup{\s!btx:\s!cite:url} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:nocite -% \fastsetup{\s!btx:\s!cite:nocite}% defined nowhere : -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:entry -% \fastsetup{\s!btx:\s!cite:entry} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!cite:none -% \fastsetup{\s!btx:\s!cite:none} -% \stopsetups - -% List - -% \startsetups \s!btx:\s!default:\s!list:page -% \fastsetup{\s!btx:\s!list:page} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!list:yes -% \fastsetup{\s!btx:\s!list:yes} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!list:num -% \fastsetup{\s!btx:\s!list:num} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!list:bib -% \fastsetup{\s!btx:\s!list:bib} -% \stopsetups -% \startsetups \s!btx:\s!default:\s!list:short -% \fastsetup{\s!btx:\s!list:short} -% \stopsetups - \stopbtxrenderingdefinitions diff --git a/tex/context/base/publ-imp-list.mkvi b/tex/context/base/publ-imp-list.mkvi index e13294f6f..61432486b 100644 --- a/tex/context/base/publ-imp-list.mkvi +++ b/tex/context/base/publ-imp-list.mkvi @@ -30,17 +30,10 @@ \stoptexdefinition \starttexdefinition btx:list:helpers:concat - % \ifcase\currentbtxconcat \or \or - % \btxparameter\c!pubsep - % \or - % \btxparameter\c!finalpubsep - % \or - % \btxparameter\c!lastpubsep - % \fi \space \stoptexdefinition -\startsetups \s!btx:\s!list:page +\startsetups[\s!btx:\s!list:\s!page] \texdefinition{\s!btx:\s!list:concat} \texdefinition{\s!btx:\s!list:inject} { % real pagenumber: todo, userpage @@ -50,39 +43,38 @@ } \stopsetups -\startsetups \s!btx:\s!list:numbering - \btxparameter\c!left +\startsetups[\s!btx:\s!list:\s!numbering] \texdefinition {\s!btx:\s!list:inject} { \currentbtxfirst \btxparameter\c!stopper } - \btxparameter\c!right \stopsetups -\startsetups \s!btx:\s!list:num - \btxstartstyleandcolor [\currentbtxspecification:list:num] - \btxusecommand[\currentbtxspecification:list:num] { - \fastsetup{\s!btx:\s!list:numbering} +\startsetups[\s!btx:\s!list:\s!numbering:num] + \btxstartstyleandcolor [\currentbtxspecification:\s!list:\s!numbering:num] + \btxusecommand[\currentbtxspecification:\s!list:\s!numbering:num] { + \fastsetup{\s!btx:\s!list:\s!numbering} } \btxstopstyleandcolor \stopsetups -\startsetups \s!btx:\s!list:yes - \fastsetup{\s!btx:\s!list:num} +\startsetups[\s!btx:\s!list:\s!numbering:\v!yes] + \fastsetup{\s!btx:\s!list:\s!numbering:num} \stopsetups -\startsetups \s!btx:\s!list:short - \btxstartstyleandcolor [\currentbtxspecification:list:short] - \btxusecommand[\currentbtxspecification:list:short] { - \fastsetup{\s!btx:\s!list:numbering} +\startsetups[\s!btx:\s!list:\s!numbering:short] + \btxstartstyleandcolor [\currentbtxspecification:\s!list:\s!numbering:short] + \btxusecommand [\currentbtxspecification:\s!list:\s!numbering:short] { + \fastsetup{\s!btx:\s!list:\s!numbering} + \btxflushsuffix } \btxstopstyleandcolor \stopsetups -\startsetups \s!btx:\s!list:bib - \btxstartstyleandcolor [\currentbtxspecification:list:bib] - \btxusecommand[\currentbtxspecification:list:bib] { - \fastsetup{\s!btx:\s!list:numbering} +\startsetups[\s!btx:\s!list:\s!numbering:bib] + \btxstartstyleandcolor [\currentbtxspecification:\s!list:\s!numbering:bib] + \btxusecommand [\currentbtxspecification:\s!list:\s!numbering:bib] { + \fastsetup{\s!btx:\s!list:\s!numbering} } \btxstopstyleandcolor \stopsetups diff --git a/tex/context/base/publ-imp-page.mkvi b/tex/context/base/publ-imp-page.mkvi index 19673c829..f0b92c88c 100644 --- a/tex/context/base/publ-imp-page.mkvi +++ b/tex/context/base/publ-imp-page.mkvi @@ -26,7 +26,7 @@ \definebtx [\s!page:\s!list] [\s!page] - [\c!command={\wordright}] + [\c!pagecommand={\wordright}] \startsetups \s!btx:\s!page:concat \ifcase\currentbtxoverflow @@ -44,7 +44,7 @@ % for the moment we have only one variant -\startsetups [\s!btx:\s!page:\s!list] +\startsetups [\s!btx:\s!list:\s!page] \fastsetup{\s!btx:\s!page:concat} % \ifx\currentbtxlastpage\empty % p. diff --git a/tex/context/base/publ-ini.lua b/tex/context/base/publ-ini.lua index 25397727b..556f519f7 100644 --- a/tex/context/base/publ-ini.lua +++ b/tex/context/base/publ-ini.lua @@ -22,7 +22,7 @@ if not modules then modules = { } end modules ['publ-ini'] = { -- gain is not that large anyway because not much publication stuff is flushed. local next, rawget, type, tostring, tonumber = next, rawget, type, tostring, tonumber -local match, find = string.match, string.find +local match, find, gsub = string.match, string.find, string.gsub local concat, sort, tohash = table.concat, table.sort, table.tohash local utfsub = utf.sub local mod = math.mod @@ -32,21 +32,21 @@ local settings_to_array, settings_to_set = utilities.parsers.settings_to_array, local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash local setmetatableindex = table.setmetatableindex local lpegmatch = lpeg.match -local P, S, C, Ct, R, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.R, lpeg.Carg +local P, S, C, Ct, Cs, R, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.R, lpeg.Carg local upper = utf.upper local report = logs.reporter("publications") local report_cite = logs.reporter("publications","cite") local report_list = logs.reporter("publications","list") local report_reference = logs.reporter("publications","reference") -local report_shorts = logs.reporter("publications","shorts") +local report_suffix = logs.reporter("publications","suffix") local trace = false trackers.register("publications", function(v) trace = v end) local trace_cite = false trackers.register("publications.cite", function(v) trace_cite = v end) local trace_missing = false trackers.register("publications.cite.missing", function(v) trace_missing = v end) local trace_references = false trackers.register("publications.cite.references", function(v) trace_references = v end) local trace_detail = false trackers.register("publications.detail", function(v) trace_detail = v end) -local trace_shorts = false trackers.register("publications.shorts", function(v) trace_shorts = v end) +local trace_suffixes = false trackers.register("publications.suffixes", function(v) trace_suffixes = v end) publications = publications or { } local datasets = publications.datasets @@ -65,8 +65,11 @@ local v_local = variables["local"] local v_global = variables["global"] local v_force = variables.force +local v_normal = variables.normal +local v_reverse = variables.reverse local v_none = variables.none local v_yes = variables.yes +local v_no = variables.no local v_all = variables.all local v_always = variables.always local v_doublesided = variables.doublesided @@ -123,10 +126,12 @@ local ctx_btxsetcombis = context.btxsetcombis local ctx_btxsetcategory = context.btxsetcategory local ctx_btxcitesetup = context.btxcitesetup local ctx_btxsubcitesetup = context.btxsubcitesetup +local ctx_btxnumberingsetup = context.btxnumberingsetup local ctx_btxpagesetup = context.btxpagesetup local ctx_btxsetfirst = context.btxsetfirst local ctx_btxsetsecond = context.btxsetsecond -local ctx_btxsetthird = context.btxsetthird +----- ctx_btxsetthird = context.btxsetthird +local ctx_btxsetsuffix = context.btxsetsuffix local ctx_btxsetinternal = context.btxsetinternal local ctx_btxsetlefttext = context.btxsetlefttext local ctx_btxsetrighttext = context.btxsetrighttext @@ -295,7 +300,7 @@ do local function initializer() statistics.starttiming(publications) - for name, state in next, collected do + for name, state in sortedhash(collected) do local dataset = datasets[name] local datasources = state.datasources local usersource = state.usersource @@ -422,7 +427,7 @@ do -- weird end end - for k, v in next, names do + for k, v in sortedhash(names) do local n = #v if n > 1 then local original = v[1].original @@ -992,11 +997,11 @@ do -- maybe not redo when already done local function shortsorter(a,b) - local ay, by = a[2], b[2] + local ay, by = a[2], b[2] -- year if ay ~= by then return ay < by end - local ay, by = a[3], b[3] + local ay, by = a[3], b[3] -- suffix if ay ~= by then -- bah, bah, bah local an, bn = tonumber(ay), tonumber(by) @@ -1014,7 +1019,7 @@ do -- seconds are irrelevant (there is for sure more to gain by proper coding -- of the source and or style). - local f_short = formatters["%t%02i"] + local f_short = formatters["%s%02i"] function publications.enhancers.suffixes(dataset) if not dataset then @@ -1022,6 +1027,8 @@ do else report("analyzing previous publication run for %a",dataset.name) end + dataset.suffixed = true + -- local used = usedentries[dataset.name] if not used then return -- probably a first run @@ -1033,13 +1040,18 @@ do report("nothing to be analyzed in %a",dataset.name) return -- also bad news end - local field = "author" -- currently only author - local shorts = { } + -- we have two suffixes: author (dependent of type) and short + local kind = dataset.authorconversion or "name" + local field = "author" -- currently only author + local shorts = { } + local authors = { } + local hasher = publications.authorhashers[kind] + local shorter = publications.authorhashers.short for i=1,#ordered do local entry = ordered[i] if entry then local tag = entry.tag - if tag then + if tag then local use = used[tag] if use then -- use is a table of used list entries (so there can be more) and we just look at @@ -1051,33 +1063,31 @@ do -- this will become a specification entry local author = getcasted(dataset,tag,field,specifications[btxspc]) if type(author) == "table" then - -- number depends on sort order - local t = { } - if #author > 0 then - local n = #author == 1 and 3 or 1 - for i=1,#author do - local surnames = author[i].surnames - if not surnames or #surnames == 0 then - -- error - else - t[#t+1] = utfsub(surnames[1],1,n) - end - end - end - local year = tonumber(entry.year) or 0 - local short = f_short(t,mod(year,100)) - local s = shorts[short] - -- we could also sort on reference i.e. entries.text if u then u = listentry.entries.text -- hm else u = "0" end - if not s then - shorts[short] = { { tag, year, u, i } } + local year = tonumber(entry.year) or 9999 + local data = { tag, year, u, i } + -- authors + local hash = hasher(author) + local found = authors[hash] + if not found then + authors[hash] = { data } + else + found[#found+1] = data + end + -- shorts + local hash = shorter(author) + local short = f_short(hash,mod(year,100)) + local found = shorts[short] + if not found then + shorts[short] = { data } else - s[#s+1] = { tag, year, u, i } + found[#found+1] = data end + -- else report("author typecast expected for field %a",field) end @@ -1088,47 +1098,62 @@ do end end end - -- for short, tags in next, shorts do -- ordered ? - for short, tags in sortedhash(shorts) do -- ordered ? - local n = #tags - if n == 0 then - -- skip - elseif n == 1 then - local tagdata = tags[1] - local tag = tagdata[1] - local detail = details[tag] - local entry = luadata[tag] - local year = entry.year - detail.short = short - if year then - detail.suffixedyear = year - end - if trace_shorts then - report_shorts("year %a, suffix %a, short %a, tag %a",year or "-","-",short,tag) - end - elseif n > 1 then - sort(tags,shortsorter) - for i=1,n do - local tagdata = tags[i] + local function addsuffix(hashed,key,suffixkey) + for hash, tags in sortedhash(hashed) do -- ordered ? + local n = #tags + if n == 0 then + -- skip + elseif n == 1 then + local tagdata = tags[1] local tag = tagdata[1] local detail = details[tag] - local suffix = numbertochar(i) local entry = luadata[tag] local year = entry.year - detail.short = short - detail.suffix = suffix - if year then - detail.suffixedyear = year .. suffix + detail[key] = hash + elseif n > 1 then + sort(tags,shortsorter) -- or take first -- todo: proper utf sorter + local lastyear = nil + local suffix = nil + local previous = nil + for i=1,n do + local tagdata = tags[i] + local tag = tagdata[1] + local detail = details[tag] + local entry = luadata[tag] + local year = entry.year + detail[key] = hash + if year ~= lastyear then + lastyear = year + suffix = 1 + else + if previous and suffix == 1 then + previous[suffixkey] = suffix + end + suffix = suffix + 1 + detail[suffixkey] = suffix + end + previous = detail end - if trace_shorts then - report_shorts("year %a, suffix %a, short %a, tag %a",year or "-",suffix or "-",short,tag) + end + if trace_suffixes then + for i=1,n do + local tag = tags[i][1] + local year = luadata[tag].year + local suffix = details[tag].suffix + if suffix then + report_suffix("%s: tag %a, hash %a, year %a, suffix %a",key,tag,hash,year or '',suffix or '') + else + report_suffix("%s: tag %a, hash %a, year %a",key,tag,hash,year or '') + end end end end end + addsuffix(shorts, "shorthash", "shortsuffix") -- todo: shorthash + addsuffix(authors,"authorhash","authorsuffix") end - utilities.sequencers.appendaction(enhancer,"system","publications.enhancers.suffixes") + -- utilities.sequencers.appendaction(enhancer,"system","publications.enhancers.suffixes") end @@ -1744,6 +1769,7 @@ do report_list("invalid method %a",method or "") return end + report_list("collecting entries using method %a and sort order %a",method,rendering.sorttype) lists.result = { } -- kind of reset local keyword = specification.keyword if keyword and keyword ~= "" then @@ -1785,31 +1811,39 @@ do if not repeated then used[tag] = true -- beware we keep the old state (one can always use criterium=all) end - local detail = details[tag] - if detail then - local referencenumber = detail.referencenumber - if not referencenumber then - lastreferencenumber = lastreferencenumber + 1 - referencenumber = lastreferencenumber - detail.referencenumber = lastreferencenumber - end - li[3] = referencenumber - else - report("missing details for tag %a in dataset %a (enhanced: %s)",tag,dataset,current.enhanced and "yes" or "no") - -- weird, this shouldn't happen .. all have a detail - lastreferencenumber = lastreferencenumber + 1 - details[tag] = { referencenumber = lastreferencenumber } - li[3] = lastreferencenumber - end end end end - groups[group] = lastreferencenumber if type(sorter) == "function" then - rendering.list = sorter(dataset,rendering,newlist,sorttype) or newlist + list = sorter(dataset,rendering,newlist,sorttype) or newlist else - rendering.list = newlist + list = newlist end + for i=1,#list do + local li = list[i] + local tag = li[1] + local entry = luadata[tag] + if entry then + local detail = details[tag] + if detail then + local referencenumber = detail.referencenumber + if not referencenumber then + lastreferencenumber = lastreferencenumber + 1 + referencenumber = lastreferencenumber + detail.referencenumber = lastreferencenumber + end + li[3] = referencenumber + else + report("missing details for tag %a in dataset %a (enhanced: %s)",tag,dataset,current.enhanced and "yes" or "no") + -- weird, this shouldn't happen .. all have a detail + lastreferencenumber = lastreferencenumber + 1 + details[tag] = { referencenumber = lastreferencenumber } + li[3] = lastreferencenumber + end + end + end + groups[group] = lastreferencenumber + rendering.list = list end function lists.fetchentries(dataset) @@ -1891,7 +1925,7 @@ do if trace_detail then report("expanding page setup") end - ctx_btxpagesetup() + ctx_btxpagesetup("") -- nothing yet end end @@ -1907,8 +1941,13 @@ do local n = tonumber(i) if n and n > 1 and n <= #list then local luadata = datasets[dataset].luadata - local current = getdirect(dataset,luadata[list[n ][1]],name) - local previous = getdirect(dataset,luadata[list[n-1][1]],name) + local p_index = list[n-1][1] + local c_index = list[n ][1] + local previous = getdirect(dataset,luadata[p_index],name) + local current = getdirect(dataset,luadata[c_index],name) + + -- authors are a special case + -- if not order then -- order = gettexcounter("c_btx_list_reference") -- end @@ -1933,7 +1972,18 @@ do end end end - local sameentry = current and current == previous + local sameentry = false + if current and current == previous then + sameentry = true + else + local p_casted = getcasted(dataset,p_index,name) + local c_casted = getcasted(dataset,c_index,name) + if c_casted and c_casted == p_casted then + sameentry = true + elseif type(c_casted) == "table" and type(p_casted) == "table" then + sameentry = table.identical(c_casted,p_casted) + end + end if trace_detail then if sameentry then report("previous %a, current %a, same entry",previous,current) @@ -1950,13 +2000,16 @@ do function lists.flushentry(dataset,i,textmode) local rendering = renderings[dataset] local list = rendering.list - local luadata = datasets[dataset].luadata + local data = datasets[dataset] + local luadata = data.luadata + local details = data.details local li = list[i] if li then local tag = li[1] local listindex = li[2] local n = li[3] local entry = luadata[tag] + local detail = details[tag] -- ctx_btxstartlistentry() ctx_btxsetcurrentlistentry(i) -- redundant @@ -1975,14 +2028,14 @@ do local bl = li[5] if bl and bl ~= "" then ctx_btxsetbacklink(bl) - ctx_btxsetbacktrace(concat(li," ",5)) - local uc = citetolist[tonumber(bl)] - if uc then - ctx_btxsetinternal(uc.references.internal or "") - end + -- ctx_btxsetbacktrace(concat(li," ",5)) -- two numbers else -- nothing end + local authorsuffix = detail.authorsuffix + if authorsuffix then + ctx_btxsetsuffix(authorsuffix) + end local userdata = li[4] if userdata then local b = userdata.btxbtx @@ -2112,10 +2165,20 @@ do return end -- + local data = datasets[dataset] + if not data.suffixed then + data.authorconversion = specification.authorconversion + publications.enhancers.suffixes(data) + end + -- specification.variant = variant - specification.compress = specification.compress == v_yes + specification.compress = specification.compress specification.markentry = specification.markentry ~= false -- + if specification.sorttype == v_yes then + specification.sorttype = v_normal + end + -- local prefix, rest = lpegmatch(prefixsplitter,reference) if prefix and rest then dataset = prefix @@ -2178,6 +2241,7 @@ do { "variant" }, { "sorttype" }, { "compress" }, + { "authorconversion" }, { "author" }, { "lefttext" }, { "righttext" }, @@ -2205,10 +2269,10 @@ do local ak = a.sortkey local bk = b.sortkey if ak == bk then - local as = a.suffix -- alphabetic - local bs = b.suffix -- alphabetic + local as = a.suffix -- numeric + local bs = b.suffix -- numeric if as and bs then - return (as or "") < (bs or "") + return (as or 0) < (bs or 0) else return false end @@ -2217,56 +2281,75 @@ do end end - local function compresslist(source) - for i=1,#source do - local t = type(source[i].sortkey) - if t == "number" then - -- okay - -- elseif t == "string" then - -- -- okay - else - return source - end + local revsorter = function(a,b) + return keysorter(b,a) + end + + local function compresslist(source,specification) + if specification.sorttype == v_normal then + sort(source,keysorter) + elseif specification.sorttype == v_reverse then + sort(source,revsorter) end - local first, last, firstr, lastr - local target, noftarget, tags = { }, 0, { } - sort(source,keysorter) - local oldvalue = nil - local function flushrange() - noftarget = noftarget + 1 - if last > first + 1 then - target[noftarget] = { - first = firstr, - last = lastr, - tags = tags, - } - else - target[noftarget] = firstr - if last > first then - noftarget = noftarget + 1 - target[noftarget] = lastr + if specification and specification.compress == v_yes and specification.numeric then + local first, last, firstr, lastr + local target, noftarget, tags = { }, 0, { } + local oldvalue = nil + local function flushrange() + noftarget = noftarget + 1 + if last > first + 1 then + target[noftarget] = { + first = firstr, + last = lastr, + tags = tags, + } + else + target[noftarget] = firstr + if last > first then + noftarget = noftarget + 1 + target[noftarget] = lastr + end end + tags = { } end - tags = { } - end - for i=1,#source do - local entry = source[i] - local current = entry.sortkey - local suffix = entry.suffix -- todo but what - if not first then - first, last, firstr, lastr = current, current, entry, entry - elseif current == last + 1 then - last, lastr = current, entry - else + for i=1,#source do + local entry = source[i] + local current = entry.sortkey -- so we need a sortkey ! +if entry.suffix then + if not first then + first, last, firstr, lastr = current, current, entry, entry + else + flushrange() + first, last, firstr, lastr = current, current, entry, entry + end +else + if not first then + first, last, firstr, lastr = current, current, entry, entry + elseif current == last + 1 then + last, lastr = current, entry + else + flushrange() + first, last, firstr, lastr = current, current, entry, entry + end +end + tags[#tags+1] = entry.tag + end + if first and last then flushrange() - first, last, firstr, lastr = current, current, entry, entry end - tags[#tags+1] = entry.tag - end - if first and last then - flushrange() + return target + else + local target, noftarget = { }, 0 + for i=1,#source do + local entry = source[i] + noftarget = noftarget + 1 + target[noftarget] = { + first = entry, + tags = { entry.tag }, + } + end + return target end - return target end -- local source = { @@ -2297,6 +2380,7 @@ do local internal = specification.internal local setup = specification.variant local compress = specification.compress + local sorttype = specification.sorttype local getter = specification.getter local setter = specification.setter local compressor = specification.compressor @@ -2315,7 +2399,6 @@ do report("processing reference %a",reference) end local source = { } - local badkey = false local luadata = datasets[dataset].luadata for i=1,#found do local entry = found[i] @@ -2329,19 +2412,6 @@ do -- luadata = ldata, } setter(data,dataset,tag,entry) - if compress and not compressor then - local sortkey = data.sortkey - if sortkey then - local key = lpegmatch(numberonly,sortkey) - if key then - data.sortkey = key - else - badkey = true - end - else - badkey = true - end - end if type(data) == "table" then source[#source+1] = data else @@ -2359,13 +2429,6 @@ do if before and before ~= "" then before = settings_to_array(before) end if after and after ~= "" then after = settings_to_array(after) end - -- local oneleft = lefttext and #lefttext == 1 and lefttext [1] - -- local oneright = righttext and #righttext == 1 and righttext[1] - -- - -- if not oneleft or not oneright then - -- compress = false -- very hard coded, or should we have compreess == auto? - -- end - local function flush(i,n,entry,last) local tag = entry.tag local currentcitation = markcite(dataset,tag) @@ -2374,27 +2437,6 @@ do ctx_btxsettag(tag) ctx_btxsetcategory(entry.category or "unknown") -- - -- if oneleft then - -- if i == 1 then - -- ctx_btxsetlefttext(oneleft) - -- end - -- elseif lefttext then - -- ctx_btxsetlefttext(lefttext[i] or "") - -- end - -- if oneright then - -- if i == n then - -- ctx_btxsetrighttext(oneright) - -- end - -- elseif righttext then - -- ctx_btxsetrighttext(righttext[i] or "") - -- end - -- if before then - -- ctx_btxsetbefore(before[i] or (#before == 1 and before[1]) or "") - -- end - -- if after then - -- ctx_btxsetafter(after[i] or (#after == 1 and after[1]) or "") - -- end - -- if lefttext then local text = lefttext [i] ; if text and text ~= "" then ctx_btxsetlefttext (text) end end if righttext then local text = righttext[i] ; if text and text ~= "" then ctx_btxsetrighttext(text) end end if before then local text = before [i] ; if text and text ~= "" then ctx_btxsetbefore (text) end end @@ -2413,7 +2455,7 @@ do if language then ctx_btxsetlanguage(language) end - if not getter(entry,last) then + if not getter(entry,last,nil,specification) then ctx_btxsetfirst("") -- (f_missing(tag)) end ctx_btxsetconcat(concatstate(i,n)) @@ -2423,13 +2465,18 @@ do ctx_btxcitesetup(setup) ctx_btxstopcite() end - - if compress and not badkey then - local target = (compressor or compresslist)(source) + if sorttype == v_normal or sorttype == v_reverse then + local target = (compressor or compresslist)(source,specification) local nofcollected = #target if nofcollected == 0 then - report("nothing found for %a",reference) - unknowncite(reference) + local nofcollected = #source + if nofcollected == 0 then + unknowncite(reference) + else + for i=1,nofcollected do + flush(i,nofcollected,source[i]) + end + end else for i=1,nofcollected do local entry = target[i] @@ -2460,7 +2507,7 @@ do -- - local function simplegetter(first,last,field) + local function simplegetter(first,last,field,specification) local value = first[field] if value then ctx_btxsetfirst(value) @@ -2473,7 +2520,7 @@ do local setters = setmetatableindex({},function(t,k) local v = function(data,dataset,tag,entry) - local value = getcasted(dataset,tag,k) + local value = getcasted(dataset,tag,k) data.value = value -- not really needed data[k] = value data.sortkey = value @@ -2484,8 +2531,8 @@ do end) local getters = setmetatableindex({},function(t,k) - local v = function(first,last) - return simplegetter(first,last,k) + local v = function(first,last,_,specification) + return simplegetter(first,last,k,specification) -- maybe _ or k end t[k] = v return v @@ -2508,7 +2555,7 @@ do }) end - -- category | type + -- category do @@ -2516,21 +2563,12 @@ do data.category = getfield(dataset,tag,"category") end - local function getter(first,last) - return simplegetter(first,last,"category") + local function getter(first,last,_,specification) + return simplegetter(first,last,"category",specification) end function citevariants.category(presets) processcite(presets,{ - -- variant = presets.variant or "serial", - setter = setter, - getter = getter, - }) - end - - function citevariants.type(presets) - processcite(presets,{ - -- variant = presets.variant or "type", setter = setter, getter = getter, }) @@ -2547,14 +2585,13 @@ do -- nothing end - local function getter(first,last) -- last not used + local function getter(first,last,_,specification) -- last not used ctx_btxsetfirst(first.tag) end function citevariants.entry(presets) processcite(presets,{ compress = false, - -- variant = presets.variant or "entry", setter = setter, getter = getter, }) @@ -2567,18 +2604,20 @@ do do local function setter(data,dataset,tag,entry) - data.short = getdetail(dataset,tag,"short") - data.suffix = getdetail(dataset,tag,"suffix") + local short = getdetail(dataset,tag,"shorthash") + local suffix = getdetail(dataset,tag,"shortsuffix") + data.short = short + data.sortkey = short + data.suffix = suffix end - local function getter(first,last) -- last not used + local function getter(first,last,_,specification) -- last not used local short = first.short if short then local suffix = first.suffix + ctx_btxsetfirst(short) if suffix then - ctx_btxsetfirst(short .. suffix) - else - ctx_btxsetfirst(short) + ctx_btxsetsuffix(suffix) -- watch out: third end return true end @@ -2586,10 +2625,8 @@ do function citevariants.short(presets) processcite(presets,{ - compress = false, - -- variant = presets.variant or "short", - setter = setter, - getter = getter, + setter = setter, + getter = getter, }) end @@ -2603,7 +2640,7 @@ do data.pages = getcasted(dataset,tag,"pages") end - local function getter(first,last) + local function getter(first,last,_,specification) local pages = first.pages if pages then if type(pages) == "table" then @@ -2618,9 +2655,8 @@ do function citevariants.page(presets) processcite(presets,{ - -- variant = presets.variant or "page", - setter = setter, - getter = getter, + setter = setter, + getter = getter, }) end @@ -2634,16 +2670,16 @@ do local entries = entry.entries local text = entries and entries.text or "?" data.num = text - data.sortkey = text + data.sortkey = tonumber(text) or text end - local function getter(first,last) - return simplegetter(first,last,"num") + local function getter(first,last,_,specification) + return simplegetter(first,last,"num",specification) end function citevariants.num(presets) processcite(presets,{ - -- variant = presets.variant or "num", + numeric = true, setter = setter, getter = getter, }) @@ -2657,19 +2693,19 @@ do local function setter(data,dataset,tag,entry) local year = getfield (dataset,tag,"year") - local suffix = getdetail(dataset,tag,"suffix") + local suffix = getdetail(dataset,tag,"authorsuffix") data.year = year data.suffix = suffix data.sortkey = tonumber(year) or 9999 end - local function getter(first,last) - return simplegetter(first,last,"year") + local function getter(first,last,_,specification) + return simplegetter(first,last,"year",specification) end function citevariants.year(presets) processcite(presets,{ - -- variant = presets.variant or "year", + numeric = true, setter = setter, getter = getter, }) @@ -2677,64 +2713,47 @@ do end - -- index | serial + -- index do local function setter(data,dataset,tag,entry) - local index = getfield(dataset,tag,"index") + local index = getfield(dataset,tag,"index") data.index = index data.sortkey = index end - local function getter(first,last) - return simplegetter(first,last,"index") + local function getter(first,last,_,specification) + return simplegetter(first,last,"index",specification) end function citevariants.index(presets) processcite(presets,{ - -- variant = presets.variant or "index", - setter = setter, - getter = getter, - }) - end - - function citevariants.serial(presets) - processcite(presets,{ - -- variant = presets.variant or "serial", setter = setter, getter = getter, + numeric = true, }) end end - -- key | tag + -- tag do local function setter(data,dataset,tag,entry) - -- nothing + data.tag = tag + data.sortkey = tag end - local function getter(first,last) - ctx_btxsetfirst(first.tag) - return true - end - - function citevariants.key(presets) - return processcite(presets,{ - variant = "key", - setter = setter, - getter = getter, - }) + local function getter(first,last,_,specification) + return simplegetter(first,last,"tag",specification) end function citevariants.tag(presets) return processcite(presets,{ - variant = "tag", - setter = setter, - getter = getter, + setter = setter, + getter = getter, }) end @@ -2764,7 +2783,7 @@ do data.keywords = getcasted(dataset,tag,"keywords") end - local function getter(first,last) + local function getter(first,last,_,specification) context(listof(first.keywords)) end @@ -2787,12 +2806,12 @@ do return true -- needed? end - local function authorcompressor(found) + local function authorcompressor(found,specification) local result = { } local entries = { } for i=1,#found do local entry = found[i] - local author = entry.author + local author = entry.authorhash if author then local aentries = entries[author] if aentries then @@ -2802,11 +2821,11 @@ do end end end - -- beware: we usetables as hash so we get a cycle when inspecting (unless we start + -- beware: we use tables as hash so we get a cycle when inspecting (unless we start -- hashing with strings) for i=1,#found do local entry = found[i] - local author = entry.author + local author = entry.authorhash if author then local aentries = entries[author] if not aentries then @@ -2820,7 +2839,6 @@ do end end end - -- todo: add letters (should we then tag all?) return result end @@ -2843,19 +2861,20 @@ do if first then ctx_btxsetfirst(first[key] or "") -- f_missing(first.tag)) local suffix = entry.suffix - local value = entry.last[key] + local last = entry.last + local value = last and last[key] if value then ctx_btxsetsecond(value) end if suffix then - ctx_btxsetthird(suffix) + ctx_btxsetsuffix(suffix) end else local suffix = entry.suffix local value = entry[key] or "" -- f_missing(tag) ctx_btxsetfirst(value) if suffix then - ctx_btxsetthird(suffix) + ctx_btxsetsuffix(suffix) end end ctx_btxsetconcat(concatstate(i,nofcollected)) @@ -2880,7 +2899,7 @@ do -- ctx_btxsetinternal(bl and bl.references.internal or "") ctx_btxsetfirst(entry[key] or "") -- f_missing(tag) if suffix then - ctx_btxsetthird(entry.suffix) + ctx_btxsetsuffix(entry.suffix) end if trace_detail then report("expanding %a cite setup %a","single author",setup) @@ -2892,7 +2911,7 @@ do local partialinteractive = false - local function authorgetter(first,last,key,setup) -- only first + local function authorgetter(first,last,key,specification) -- only first -- ctx_btxsetfirst(first.author) -- unformatted -- ctx_btxsetfirst(currentbtxciteauthor) -- formatter (much slower) if first.type == "author" then @@ -2908,13 +2927,13 @@ do end if entries then -- happens with year - local c = compresslist(entries) - local f = function() authorconcat(c,key,setup) return true end -- indeed return true? + local c = compresslist(entries,specification) + local f = function() authorconcat(c,key,specification.setup or "author") return true end -- indeed return true? ctx_btxsetcount(#c) ctx_btxsetsecond(f) elseif first then -- happens with num - local f = function() authorsingle(first,key,setup) return true end -- indeed return true? + local f = function() authorsingle(first,key,specification.setup or "author") return true end -- indeed return true? ctx_btxsetcount(0) ctx_btxsetsecond(f) end @@ -2925,9 +2944,10 @@ do local function setter(data,dataset,tag,entry) data.author, data.field, data.type = getcasted(dataset,tag,"author") +data.authorhash = getdetail(dataset,tag,"authorhash") -- todo let getcasted return end - local function getter(first,last,_,setup) + local function getter(first,last,_,specification) if first.type == "author" then ctx_btxsetfirst(currentbtxciteauthor) -- formatter (much slower) else @@ -2938,8 +2958,8 @@ do function citevariants.author(presets) processcite(presets,{ - compress = false, variant = "author", + setup = "author", setter = setter, getter = getter, }) @@ -2951,18 +2971,21 @@ do local entries = entry.entries local text = entries and entries.text or "?" data.author, data.field, data.type = getcasted(dataset,tag,"author") +data.authorhash = getdetail(dataset,tag,"authorhash") -- todo let getcasted return data.num = text data.sortkey = text and lpegmatch(numberonly,text) end - local function getter(first,last) - authorgetter(first,last,"num","author:num") + local function getter(first,last,_,specification) + authorgetter(first,last,"num",specification) return true end function citevariants.authornum(presets) processcite(presets,{ variant = "authornum", + setup = "author:num", + numeric = true, setter = setter, getter = getter, compressor = authorcompressor, @@ -2973,35 +2996,40 @@ do local function setter(data,dataset,tag,entry) data.author, data.field, data.type = getcasted(dataset,tag,"author") +data.authorhash = getdetail(dataset,tag,"authorhash") -- todo let getcasted return local year = getfield (dataset,tag,"year") - local suffix = getdetail(dataset,tag,"suffix") + local suffix = getdetail(dataset,tag,"authorsuffix") data.year = year data.suffix = suffix data.sortkey = tonumber(year) or 9999 end - local function getter(first,last) - authorgetter(first,last,"year","author:year") + local function getter(first,last,_,specification) + authorgetter(first,last,"year",specification) return true end function citevariants.authoryear(presets) processcite(presets,{ variant = "authoryear", + setup = "author:year", + numeric = true, setter = setter, getter = getter, compressor = authorcompressor, }) end - local function getter(first,last) - authorgetter(first,last,"year","author:years") + local function getter(first,last,_,specification) + authorgetter(first,last,"year",specification) return true end function citevariants.authoryears(presets) processcite(presets,{ variant = "authoryears", + setup = "author:years", + numeric = true, setter = setter, getter = getter, compressor = authorcompressor, @@ -3037,7 +3065,7 @@ do if trace_detail then report("expanding %a list setup %a","default",variant) end - ctx_btxlistsetup("default") + ctx_btxnumberingsetup("default") end function listvariants.num(dataset,block,tag,variant,listindex) @@ -3045,25 +3073,25 @@ do if trace_detail then report("expanding %a list setup %a","num",variant) end - ctx_btxlistsetup(variant) + ctx_btxnumberingsetup(variant or "num") end listvariants[v_yes] = listvariants.num listvariants.bib = listvariants.num function listvariants.short(dataset,block,tag,variant,listindex) - local short = getdetail(dataset,tag,"short","short") - local suffix = getdetail(dataset,tag,"suffix","suffix") + local short = getdetail(dataset,tag,"shorthash") + local suffix = getdetail(dataset,tag,"shortsuffix") if short then ctx_btxsetfirst(short) end if suffix then - ctx_btxsetthird(suffix) + ctx_btxsetsuffix(suffix) end if trace_detail then report("expanding %a list setup %a","short",variant) end - ctx_btxlistsetup(variant) + ctx_btxnumberingsetup(variant or "short") end function listvariants.page(dataset,block,tag,variant,listindex) diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv index a4452e451..f913ff3bd 100644 --- a/tex/context/base/publ-ini.mkiv +++ b/tex/context/base/publ-ini.mkiv @@ -11,7 +11,6 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. - % TODO: s! vs v! for default and neutral key/values % todo: too many refs in list @@ -307,11 +306,9 @@ \def\publ_command_nop#1% {\ifcsname#1\endcsname \showmessage\m!publications{10}{#1,#1}% - %\setuxvalue{\??btxcommand#1}{\expandafter\noexpand\csname#1\endcsname}% \global\expandafter\let\csname\??btxcommand#1\expandafter\endcsname\csname#1\endcsname \else\ifcsname\utfupper{#1}\endcsname \showmessage\m!publications{10}{#1}{\utfupper{#1}}% - %\setuxvalue{\??btxcommand#1}{\expandafter\noexpand\csname\utfupper{#1}\endcsname}% \global\expandafter\let\csname\??btxcommand#1\expandafter\endcsname\csname\utfupper{#1}\endcsname \else \showmessage\m!publications{11}{#1}% @@ -373,6 +370,7 @@ \unexpanded\def\btxnbsp {\removeunwantedspaces\nbsp} % the same anyway \unexpanded\def\btxperiod {\removeunwantedspaces.\space} \unexpanded\def\btxcomma {\removeunwantedspaces,\space} +\unexpanded\def\btxcommabreak {\removeunwantedspaces,\hskip\zeropoint plus .5\emwidth\relax} \unexpanded\def\btxcolon {\removeunwantedspaces:\space} \unexpanded\def\btxsemicolon {\removeunwantedspaces;\space} \unexpanded\def\btxlparent {\removeunwantedspaces\space(} % obsolete @@ -395,7 +393,8 @@ \let\currentbtxdataset \empty \unexpanded\def\btxsetdataset {\def\currentbtxdataset} \let\currentbtxfirst \empty \unexpanded\def\btxsetfirst {\def\currentbtxfirst} \let\currentbtxsecond \empty \unexpanded\def\btxsetsecond {\def\currentbtxsecond} -\let\currentbtxthird \empty \unexpanded\def\btxsetthird {\def\currentbtxthird} +%let\currentbtxthird \empty \unexpanded\def\btxsetthird {\def\currentbtxthird} +\let\currentbtxsuffix \empty \unexpanded\def\btxsetsuffix {\def\currentbtxsuffix} \let\currentbtxinternal \empty \unexpanded\def\btxsetinternal {\def\currentbtxinternal} \let\currentbtxlefttext \empty \unexpanded\def\btxsetlefttext {\def\currentbtxlefttext} \let\currentbtxrighttext \empty \unexpanded\def\btxsetrighttext {\def\currentbtxrighttext} @@ -425,9 +424,14 @@ \unexpanded\def\currentbtxsurnames_indeed {\clf_btxcurrentsurnames \numexpr\currentbtxauthorindex\relax} \unexpanded\def\currentbtxvons_indeed {\clf_btxcurrentvons \numexpr\currentbtxauthorindex\relax} +\let\currentbtxfirstpage \empty \unexpanded\def\btxsetfirstpage #1{\def\currentbtxfirstpage{\btx_page_number{#1}}} +\let\currentbtxlastpage \empty \unexpanded\def\btxsetlastpage #1{\def\currentbtxlastpage {\btx_page_number{#1}}} +\let\currentbtxfirstinternal\empty \unexpanded\def\btxsetfirstinternal {\def\currentbtxfirstinternal} +\let\currentbtxlastinternal \empty \unexpanded\def\btxsetlastinternal {\def\currentbtxlastinternal} + \def\currentbtxauthorvariant{normal} -\unexpanded\def\btxlistreset +\unexpanded\def\btx_reset_list % not needed as we're grouped {\let\currentbtxcombis \empty \let\currentbtxcategory \empty \let\currentbtxinternal \empty @@ -439,12 +443,14 @@ \let\currentbtxbacktrace\empty \let\currentbtxlanguage \empty \let\currentbtxtag \empty + \let\currentbtxsuffix \empty \let\currentbtxnumber \empty \let\currentbtxdataset \empty} -\unexpanded\def\btxcitereset % check for less .. not all resets needed +\unexpanded\def\btx_reset_cite % check for less .. not all resets needed when we're grouped (only subcites) {\let \currentbtxfirst \empty \let \currentbtxsecond \empty + \let \currentbtxsuffix \empty \let \currentbtxinternal \empty \let \currentbtxlefttext \empty \let \currentbtxrighttext \empty @@ -460,6 +466,27 @@ \setconstant\currentbtxconcat \zerocount \setconstant\currentbtxcount \zerocount} +\unexpanded\def\btx_reset_page % probably not needed + {\let \currentbtxfirstpage \empty + \let \currentbtxlastpage \empty + \let \currentbtxfirstinternal\empty + \let \currentbtxlastinternal \empty + \setconstant\currentbtxoverflow \zerocount + \setconstant\currentbtxconcat \zerocount + \setconstant\currentbtxcount \zerocount} + +\unexpanded\def\btx_reset_numbering % probably not needed + {\let \currentbtxfirst \empty + \let \currentbtxsecond\empty + \let \currentbtxsuffix\empty + \setconstant\currentbtxconcat\zerocount} + +%D Pages: + +\unexpanded\def\btx_page_number#1% + {\def\currentlistindex{#1}% + \structurelistpagenumber} + %D Language: \def\mainbtxlanguage{\currentmainlanguage} @@ -497,7 +524,6 @@ %D Lists: \newdimen\d_publ_number_width -%newdimen\d_publ_number_distance \ifdefined\btxblock \else \newcount\btxblock \fi \btxblock\plusone \ifdefined\btxcitecounter \else \newcount\btxcitecounter \fi % maybe pass this to lua @@ -512,11 +538,12 @@ [\s!btx] [\c!prefixstopper=:, \c!state=\v!start, - \c!alternative=\v!paragraph, + \c!alternative=a, + %\c!alternative=\v!paragraph, + %\c!width=\v!auto, + %\c!distance=\emwidth, \c!before=\blank, - \c!after=\blank, - \c!width=\v!auto, - \c!distance=\emwidth] + \c!after=\blank] \unexpanded\def\setupbtxlist {\dodoubleempty\publ_setup_list} @@ -551,26 +578,6 @@ \settrue\setfalse\c_btx_list_texts \to \everysetupbtxlistplacement -% page stuff (for thomas) - -\let\currentbtxfirstpage \empty \unexpanded\def\btxsetfirstpage #1{\def\currentbtxfirstpage{\btx_page_number{#1}}} -\let\currentbtxlastpage \empty \unexpanded\def\btxsetlastpage #1{\def\currentbtxlastpage {\btx_page_number{#1}}} -\let\currentbtxfirstinternal\empty \unexpanded\def\btxsetfirstinternal {\def\currentbtxfirstinternal} -\let\currentbtxlastinternal \empty \unexpanded\def\btxsetlastinternal {\def\currentbtxlastinternal} - -\unexpanded\def\btx_page_number#1% - {\def\currentlistindex{#1}% - \structurelistpagenumber} - -\unexpanded\def\btxpagereset - {\let \currentbtxfirstpage \empty - \let \currentbtxlastpage \empty - \let \currentbtxfirstinternal\empty - \let \currentbtxlastinternal \empty - \setconstant\currentbtxoverflow \zerocount - \setconstant\currentbtxconcat \zerocount - \setconstant\currentbtxcount \zerocount} - \newconditional\c_btx_list_pages \appendtoks @@ -582,19 +589,34 @@ {\dontleavehmode \begingroup \setbtxlist % probably already set - \btxpagereset + \btx_reset_page \setbtxparameterset\s!page\s!list - \btxparameter\c!command + \btxparameter\c!pagecommand {\usebtxstyleandcolor\c!style\c!color \btxparameter\c!pageleft \clf_btxflushpages{\currentbtxdataset}{\currentbtxtag}% \btxparameter\c!pageright}% \endgroup} -\unexpanded\def\btxpagesetup - {\btxsetuptype\plusfour - \fastbtxsetup\s!page\s!list - \btxpagereset} +\unexpanded\def\btxpagesetup#1% nothing yet + {\begingroup + %\setbtxparameterset{\c!page:\s!default}\currentbtxnumbering + \btxparameter\c!left + % \btxparameter\c!command{\publ_fast_setup\plusfive\s!list\s!page}% + \publ_fast_setup\plusfive\s!list\s!page + \btxparameter\c!right + \endgroup + \btx_reset_page} % probably not needed + +\unexpanded\def\btxnumberingsetup#1% + {\begingroup + \setbtxparameterset{\c!list:\s!numbering}\currentbtxnumbering % brrrr \setbtxlist + \btxparameter\c!left + % \btxparameter\c!command{\publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}}% + \publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}% + \btxparameter\c!right + \endgroup + \btx_reset_numbering} % probably not needed % end of page stuff @@ -608,8 +630,7 @@ \begingroup \usebtxstyleandcolor\c!style\c!color \ignorespaces - \btxsetuptype\plusthree - \fastbtxsetup\s!list\currentbtxcategory + \publ_fast_setup\plusfour\s!list\currentbtxcategory \removeunwantedspaces \endgroup \ifconditional\c_btx_list_pages @@ -640,8 +661,7 @@ {\begingroup \def\currentbtxtag{#1}% \ignorespaces - \btxsetuptype\plusthree - \fastbtxsetup\s!list\currentbtxcategory + \publ_fast_setup\plusfour\s!list\currentbtxcategory \removeunwantedspaces \endgroup} @@ -834,8 +854,7 @@ \unexpanded\def\btxlistsetup#1% used for the reference in the list {\the\everybtxlistentry \everybtxlistentry\emptytoks % so only once per entry to be sure - \btxsetuptype\plusthree - \fastbtxsetup\s!list{#1}} + \publ_fast_setup\plusfour\s!list{#1}} \appendtoks \btx_check_language @@ -843,15 +862,15 @@ \unexpanded\def\btx_reference_indeed {\begingroup - %let\currentbtxlistvariant\currentbtxnumbering - \setbtxparameterset\c!list\currentbtxnumbering + % redundantm will go away: + \setbtxparameterset{\c!list:\s!numbering}\currentbtxnumbering + % \ifx\currentbtxnumbering\empty % nothing \else\ifx\currentbtxnumbering\v!no % nothing \else \usebtxstyleandcolor\c!style\c!color % new, needed? - % \btxparameter\c!left \ifconditional\c_publ_prefixed\btxlistprefixednumber\fi \clf_btxlistvariant % some can go {\currentbtxdataset}% @@ -860,7 +879,6 @@ {\currentbtxnumbering}% {\currentbtxnumber}% \relax - % \btxparameter\c!right \fi\fi \endgroup} @@ -926,18 +944,6 @@ \newtoks\t_btx_reference_inject -% \def\btx_cite_reference_inject_indeed -% {\btx_trace_list_cross\currentbtxbacklink\empty -% \the\t_btx_reference_inject -% \normalexpanded{\writedatatolist % can be done faster .. just merge code here (not much) / also type btx -% [\s!btx]% -% [\ifx\currentbtxdataset\v!default\else\s!btxset=\currentbtxdataset,\fi% -% \s!btxref=\currentbtxtag,% -% \ifx\currentbtxbefore\empty\else\s!btxbtx=\!!bs\currentbtxbefore\!!es,\fi% -% \ifx\currentbtxafter \empty\else\s!btxatx=\!!bs\currentbtxafter \!!es,\fi% -% \s!btxint=\number\currentbtxbacklink -% \ifx\currentbtxciteuservariables\empty\else,\currentbtxciteuservariables\fi]}} - \def\btx_cite_reference_inject_indeed {\btx_trace_list_cross\currentbtxbacklink\empty \the\t_btx_reference_inject @@ -976,13 +982,22 @@ \let\currentlistmethod\s!btx \to \everysetupbtxlistplacement -% \appendtoks -% \edef\currentbtxcriterium{\btxrenderingparameter\c!criterium}% -% \to \everysetupbtxlistplacement +\unexpanded\def\btxremapauthor + {\dodoubleargument\btx_remap_author} + +\def\btx_remap_author[#1][#2]% + {\clf_btxremapauthor{#1}{#2}} \unexpanded\def\btxflushauthor {\doifelsenextoptionalcs\btx_flush_author_yes\btx_flush_author_nop} +\unexpanded\def\btxflushsuffix + {\ifx\currentbtxsuffix\empty + % nothing + \else + \characters{\currentbtxsuffix}% todo : rendering specific converter + \fi} + \def\btx_flush_author_yes[#1]{\btx_flush_author{#1}} \def\btx_flush_author_nop {\btx_flush_author{\btxparameter\c!authorconversion}} @@ -1099,17 +1114,6 @@ \fi \to \everysetupbtxciteplacement -% till here - -% \unexpanded\def\btxnumberedreference[#1]% \bibtexnumref (replaced by \cite[num]) -% {\dontleavehmode -% \begingroup -% \btxparameter\v!left -% \penalty\plustenthousand % todo -% \clf_btxresolvelistreference{\currentbtxdataset}{#1}% todo: split dataset from #1, so another call -% \btxparameter\v!right -% \endgroup} - %D When a publication is cited, we need to signal that somehow. This is done with the %D following (not user) command. We could tag without injecting a node but this way %D we also store the location, which makes it possible to ask local lists. @@ -1223,29 +1227,30 @@ \dosingleargument\publ_cite_handle_variant_indeed} \unexpanded\def\publ_cite_handle_variant_blob - {%\btxparameter\v!left\relax - \clf_btxhandlecite - dataset {\currentbtxdataset}% - reference {\currentbtxreference}% - markentry \iftrialtypesetting\s!false\else\s!true\fi\space - variant {\currentbtxcitealternative}% - sorttype {\btxparameter\c!sorttype}% - compress {\btxparameter\c!compress}% - author {\btxparameter\c!author}% - lefttext {\p_publ_cite_lefttext}% - righttext {\p_publ_cite_righttext}% - before {\p_publ_cite_before}% - after {\p_publ_cite_after}% + {\clf_btxhandlecite + dataset {\currentbtxdataset}% + reference {\currentbtxreference}% + markentry \iftrialtypesetting\s!false\else\s!true\fi\space + variant {\currentbtxcitealternative}% + sorttype {\btxparameter\c!sorttype}% + compress {\btxparameter\c!compress}% + author {\btxparameter\c!author}% + authorconversion {\c!authorconversion}% + lefttext {\p_publ_cite_lefttext}% + righttext {\p_publ_cite_righttext}% + before {\p_publ_cite_before}% + after {\p_publ_cite_after}% \relax - \clf_btxflushmarked % maybe: \iftrialtypesetting\else ... \fi - }%\btxparameter\v!right\relax} + \clf_btxflushmarked} % maybe: \iftrialtypesetting\else ... \fi \def\publ_cite_handle_variant_indeed[#1]% {\letbtxparameter\c!alternative\currentbtxcitealternative \edef\currentbtxreference{#1}% \usebtxstyleandcolor\c!style\c!color \uselanguageparameter\btxdatasetparameter % new + \btxparameter\c!left \btxparameter\c!command{\publ_cite_handle_variant_blob}% + \btxparameter\c!right \endgroup} \unexpanded\def\btxcitation @@ -1292,7 +1297,7 @@ \setvalue{\??setup:\s!btx:\s!unknown}#1{\inframed{\tttf#1}} -\def\fastbtxsetup_yes#1#2% +\def\publ_fast_setup_yes#1#2% {\csname\??setup:\s!btx:% \ifcsname\??setup:\s!btx:\currentbtxspecification:#1:#2\endcsname \currentbtxspecification:#1:#2% @@ -1309,7 +1314,7 @@ \fi\fi\fi\fi\fi \endcsname{#2}} -\def\fastbtxsetup_nop#1#2% +\def\publ_fast_setup_nop#1#2% {\csname\??setup:\s!btx:% \ifcsname\??setup:\s!btx:\currentbtxspecification:#1:#2\endcsname \currentbtxspecification:#1:#2% @@ -1322,76 +1327,84 @@ \fi\fi\fi \endcsname{#2}} -\def\fastbtxsetup - {\ifx\currentbtxspecificationfallback\empty - \expandafter\fastbtxsetup_nop - \else - \expandafter\fastbtxsetup_yes - \fi} - -\let\publ_fastbtxsetup_normal\fastbtxsetup - \newconstant\btxsetuptype % 0 = unknown darkred % 1 = cite darkblue % 2 = subcite darkgreen -% 3 = list darkcyan -% 4 = page darkmagenta -% 5 = unknown darkred +% 3 = numbering darkorange +% 4 = list darkcyan +% 5 = page darkmagenta +% 6 = unknown darkred -\unexpanded\def\publ_fastbtxsetup_chain_inbetween +\unexpanded\def\publ_fast_btx_setup_chain_inbetween {\allowbreak->\allowbreak} -\unexpanded\def\publ_fastbtxsetup_chain_yes#1#2% +\unexpanded\def\publ_fast_btx_setup_chain_yes#1#2% {\dontleavehmode\begingroup \infofont \ifcase\btxsetuptype\darkred\or\darkblue\or\darkgreen\or\darkcyan\or\darkmagenta\else\darkred\fi [% \currentbtxspecification :#1:#2\ifcsname\??setup:\s!btx:\currentbtxspecification :#1:#2\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween \currentbtxspecificationfallback:#1:#2\ifcsname\??setup:\s!btx:\currentbtxspecificationfallback :#1:#2\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween #1:#2\ifcsname\??setup:\s!btx :#1:#2\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween \currentbtxspecification :#1:\s!unknown\ifcsname\??setup:\s!btx:\currentbtxspecification :#1:\s!unknown\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween \currentbtxspecificationfallback:#1:\s!unknown\ifcsname\??setup:\s!btx:\currentbtxspecificationfallback:#1:\s!unknown\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween unset\fi\fi\fi\fi\fi + \space @\space + \currentbtx ]% \endgroup} -\unexpanded\def\publ_fastbtxsetup_chain_nop#1#2% +\unexpanded\def\publ_fast_btx_setup_chain_nop#1#2% {\dontleavehmode\begingroup \infofont \darkred [% \currentbtxspecification :#1:#2\ifcsname\??setup:\s!btx:\currentbtxspecification :#1:#2\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween #1:#2\ifcsname\??setup:\s!btx :#1:#2\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween \currentbtxspecification :#1:\s!unknown\ifcsname\??setup:\s!btx:\currentbtxspecification :#1:\s!unknown\endcsname\else - \publ_fastbtxsetup_chain_inbetween + \publ_fast_btx_setup_chain_inbetween unset\fi\fi\fi + \space @\space + \currentbtx ]% \endgroup} -\unexpanded\def\publ_fastbtxsetup_chain - {\ifx\currentbtxspecificationfallback\empty - \expandafter\publ_fastbtxsetup_chain_nop +\unexpanded\def\publ_fast_btx_setup_normal#1% + {\btxsetuptype#1\relax + \ifx\currentbtxspecificationfallback\empty + \expandafter\publ_fast_setup_nop \else - \expandafter\publ_fastbtxsetup_chain_yes + \expandafter\publ_fast_setup_yes \fi} -\unexpanded\def\publ_fastbtxsetup_visual#1#2% - {\publ_fastbtxsetup_chain{#1}{#2}% - \publ_fastbtxsetup_normal{#1}{#2}} +\unexpanded\def\publ_fast_btx_setup_visual#1#2#3% + {\btxsetuptype#1\relax + \ifx\currentbtxspecificationfallback\empty + \expandafter\publ_fast_btx_setup_chain_nop + \else + \expandafter\publ_fast_btx_setup_chain_yes + \fi{#2}{#3}% + \ifx\currentbtxspecificationfallback\empty + \expandafter\publ_fast_setup_nop + \else + \expandafter\publ_fast_setup_yes + \fi{#2}{#3}} \installtextracker {publications.setups} - {\let\fastbtxsetup\publ_fastbtxsetup_visual} - {\let\fastbtxsetup\publ_fastbtxsetup_normal} + {\let\publ_fast_setup\publ_fast_btx_setup_visual} + {\let\publ_fast_setup\publ_fast_btx_setup_normal} + +\let\publ_fast_setup\publ_fast_btx_setup_normal %D Cite helpers: @@ -1403,15 +1416,13 @@ \unexpanded\def\btxcitesetup#1% {\the\everybtxciteentry - \btxsetuptype\plusone \everybtxciteentry\emptytoks % tricky maybe not when subcites - \fastbtxsetup\s!cite{#1}} % no \btxcitereset as we loose dataset and such + \publ_fast_setup\plusone\s!cite{#1}} % no \btxcitereset as we loose dataset and such \unexpanded\def\btxsubcitesetup#1% {\the\everybtxciteentry - \btxsetuptype\plustwo \everybtxciteentry\emptytoks % tricky maybe not when subcites - \fastbtxsetup\s!cite{#1}} % no \btxcitereset as we loose dataset and such + \publ_fast_setup\plustwo\s!cite{#1}} % no \btxcitereset as we loose dataset and such \appendtoks \btx_check_language @@ -1419,16 +1430,16 @@ \unexpanded\def\btxstartsubcite#1% {\begingroup - \btxcitereset % todo: limited set + \btx_reset_cite % todo: limited set \def\currentbtxcitealternative{#1}% \setbtxparameterset\s!cite\currentbtxcitealternative \usebtxstyleandcolor\c!style\c!color - % \btxparameter\c!left + \btxparameter\c!left \relax} \unexpanded\def\btxstopsubcite - {%\relax - % \btxparameter\c!right + {\relax + \btxparameter\c!right \endgroup} \unexpanded\def\btxstartciterendering[#1]% @@ -1436,12 +1447,12 @@ \edef\currentbtxcitealternative{#1}% \setbtxparameterset\s!cite\currentbtxcitealternative \usebtxstyleandcolor\c!style\c!color - % \btxparameter\c!left - }%\relax} + \btxparameter\c!left + \relax} \unexpanded\def\btxstopciterendering {\relax - % \btxparameter\c!right + \btxparameter\c!right \endgroup} \let\btxstartcite \begingroup @@ -1638,8 +1649,8 @@ \let\btxstopcolor \endgroup \let\btxstopstyleandcolor\endgroup -\unexpanded\def\btxusecommand[#1]% - {\namedbtxparameter{#1}\c!command} +\unexpanded\def\btxusecommand[#1]#2% using #2 permits space after [] + {\namedbtxparameter{#1}\c!command{#2}} %D Defaults: @@ -1672,7 +1683,8 @@ \c!alternative=num, % default cite form \c!inbetween=\space, \c!range=\endash, % separator:range? - \c!compress=\v!no, + \c!compress=\v!yes, % was no? + \c!sorttype=normal, % normal, reverse or none \c!etallimit=3, \c!etaldisplay=\btxparameter\c!etallimit, \c!otherstext={\space et al.}, diff --git a/tex/context/base/publ-jrn.lua b/tex/context/base/publ-jrn.lua index 2e0408417..0cc41862f 100644 --- a/tex/context/base/publ-jrn.lua +++ b/tex/context/base/publ-jrn.lua @@ -19,6 +19,7 @@ if not modules then modules = { } end modules ['publ-jrn'] = { local context = context local commands = commands +local type = type local find = string.find local P, C, S, Cs, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.S, lpeg.Cs, lpeg.match, lpeg.patterns diff --git a/tex/context/base/publ-sor.lua b/tex/context/base/publ-sor.lua index c3fcdb0ee..7d1ab8342 100644 --- a/tex/context/base/publ-sor.lua +++ b/tex/context/base/publ-sor.lua @@ -155,12 +155,13 @@ local function sortsequence(dataset,list,sorttype) end for i=1,#sequence do - local step = sequence[i] - local field = step.field or "?" - local default = step.default or c_default - local unknown = step.unknown or c_unknown - local fldtype = types[field] - local writer = fldtype and writers[fldtype] + local step = sequence[i] + local field = step.field or "?" + local default = step.default or c_default + local unknown = step.unknown or c_unknown + local fldtype = types[field] + local fldwriter = step.writer or fldtype + local writer = fldwriter and writers[fldwriter] if trace_sorters then report("% 3i : field %a, type %a, default %a, unknown %a",i,field,fldtype, @@ -172,7 +173,7 @@ local function sortsequence(dataset,list,sorttype) if writer then local h = #helpers + 1 getters[i] = f_writer(h,field,default,field) - helpers[h] = f_helper(h,fldtype,field,fldtype) + helpers[h] = f_helper(h,fldwriter,field,fldtype) else getters[i] = f_getter(field,default,field) end @@ -213,49 +214,60 @@ local function sortsequence(dataset,list,sorttype) end +-- index : order in dataset +-- order : order of citations +-- short : alphabetic + suffix +-- reference : order in list +-- default : automatic sorter +-- authoryear : sort order list + +-- tag | listindex | 0 | u | u.btxint | data.index + local sorters = { - [v_short] = function(dataset,rendering,list) + [v_short] = function(dataset,rendering,list) -- should we store it local shorts = rendering.shorts local function compare(a,b) - local aa, bb = a and a[1], b and b[1] + local aa = a and a[1] + local bb = b and b[1] if aa and bb then aa, bb = shorts[aa], shorts[bb] return aa and bb and aa < bb + else + return a[1] < b[1] end - return false end sort(list,compare) end, - [v_reference] = function(dataset,rendering,list) + [v_reference] = function(dataset,rendering,list) -- order local function compare(a,b) - local aa, bb = a and a[1], b and b[1] - if aa and bb then - return aa and bb and aa < bb - end - return false + local aa = a and a[1] + local bb = b and b[1] + return aa < bb end sort(list,compare) end, - [v_dataset] = function(dataset,rendering,list) + [v_dataset] = function(dataset,rendering,list) -- index local function compare(a,b) --- inspect(a,b) - local aa, bb = a and a[6], b and b[6] + local aa = a and a[6] + local bb = b and b[6] if aa and bb then - -- aa, bb = list[aa].index or 0, list[bb].index or 0 - return aa and bb and aa < bb + return aa < bb + else + return a[1] < b[1] end - return false end sort(list,compare) end, [v_default] = function(dataset,rendering,list,sorttype) -- experimental if sorttype == "" or sorttype == v_default then local function compare(a,b) - local aa, bb = a and a[3], b and b[3] - if aa and bb then - return aa and bb and aa < bb + local aa = a and a[3] or 0 + local bb = b and b[3] or 0 + if aa == bb then + return a[1] < b[1] + else + return aa < bb end - return false end sort(list,compare) else diff --git a/tex/context/base/publ-tra.lua b/tex/context/base/publ-tra.lua index 65e9b7ff4..b90455aed 100644 --- a/tex/context/base/publ-tra.lua +++ b/tex/context/base/publ-tra.lua @@ -107,8 +107,8 @@ function tracers.showdatasetcompleteness(settings) local preamble = { "|lTBw(5em)|lBTp(10em)|plT|" } - local function identified(tag,category,crossref) - ctx_NC() + local function identified(tag,category,crossref,index) + ctx_NC() ctx_monobold(index) ctx_NC() ctx_monobold(category) ctx_NC() if crossref then ctx_monobold("%s\\hfill\\darkblue => %s",tag,crossref) @@ -179,7 +179,7 @@ function tracers.showdatasetcompleteness(settings) foundfields[k] = true end ctx_starttabulate(preamble) - identified(tag,category,entry.crossref) + identified(tag,category,entry.crossref,entry.index) ctx_FL() if fields then local requiredfields = fields.required diff --git a/tex/context/base/publ-tra.mkiv b/tex/context/base/publ-tra.mkiv index 415505198..2f86a5624 100644 --- a/tex/context/base/publ-tra.mkiv +++ b/tex/context/base/publ-tra.mkiv @@ -38,13 +38,11 @@ \else \getdummyparameters[#2]% \fi - % \publ_specification_push{"\dummyparameter\c!specification}% \ctxcommand{#1{ dataset = "\dummyparameter\c!dataset", specification = "\dummyparameter\c!specification", field = "\dummyparameter\c!field", }}% - % \publ_specification_pop \endgroup} \def\publ_show_dataset_fields {\publ_show_dataset_whatever{showbtxdatasetfields}} @@ -60,12 +58,10 @@ {\doifelsenothing{#1}% {\letdummyparameter\c!specification\currentbtxspecification}% {\setdummyparameter\c!specification{#1}}}% - % \publ_specification_push{"\dummyparameter\c!specification}% \ctxcommand{showbtxfields{ rotation = "\dummyparameter\c!rotation", specification = "\dummyparameter\c!specification" }}% - % \publ_specification_pop \endgroup} \def\publ_show_tables[#1]% diff --git a/tex/context/base/publ-usr.lua b/tex/context/base/publ-usr.lua index f01112279..901f11629 100644 --- a/tex/context/base/publ-usr.lua +++ b/tex/context/base/publ-usr.lua @@ -89,10 +89,12 @@ local function addtexentry(dataset,settings,content) category = settings.category or settings.t or "article", } lpegmatch(pattern,content,1,data) -- can set tag too - local tag = data.tag - current.userdata[tag] = data - current.luadata[tag] = data - current.details[tag] = nil + local tag = data.tag + local index = publications.getindex(dataset,current.luadata,tag) + current.ordered[index] = data + current.luadata[tag] = data + current.userdata[tag] = data + current.details[tag] = nil return data end diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua index 995977613..9c4d5acee 100644 --- a/tex/context/base/sort-ini.lua +++ b/tex/context/base/sort-ini.lua @@ -702,7 +702,14 @@ local function packch(entry) local tt, li = { }, split[i].ch for j=1,#li do local lij = li[j] - tt[j] = utfbyte(lij) > ignoredoffset and "[]" or lij + local byt = utfbyte(lij) + if byt > ignoredoffset then + tt[j] = "[]" + elseif byt == 0 then + tt[j] = " " + else + tt[j] = lij + end end t[i] = concat(tt) end @@ -711,7 +718,14 @@ local function packch(entry) local t, li = { }, split.ch for j=1,#li do local lij = li[j] - t[j] = utfbyte(lij) > ignoredoffset and "[]" or lij + local byt = utfbyte(lij) + if byt > ignoredoffset then + t[j] = "[]" + elseif byt == 0 then + t[j] = " " + else + t[j] = lij + end end return concat(t) end @@ -731,7 +745,7 @@ local function packuc(entry) end function sorters.sort(entries,cmp) - if trace_tests or trace_methods then + if trace_methods then local nofentries = #entries report_sorters("entries: %s, language: %s, method: %s, digits: %s",nofentries,language,method,tostring(digits)) for i=1,nofentries do diff --git a/tex/context/base/spac-def.mkiv b/tex/context/base/spac-def.mkiv index 312483cfa..7ead3c63e 100644 --- a/tex/context/base/spac-def.mkiv +++ b/tex/context/base/spac-def.mkiv @@ -60,7 +60,7 @@ \c!depth=.28, \c!top=1.0, \c!bottom=0.4, - \c!distance=\onepoint, + \c!distance=\onepoint, % \dimexpr\openlineheight/10\relax \c!line=2.8\exheight, \c!stretch=\zerocount, \c!shrink=\zerocount] diff --git a/tex/context/base/spac-prf.mkiv b/tex/context/base/spac-prf.mkiv new file mode 100644 index 000000000..5f1553ede --- /dev/null +++ b/tex/context/base/spac-prf.mkiv @@ -0,0 +1,31 @@ +%D \module +%D [ file=spac-prf, +%D version=2015.11.16, % moved from test module mathplus +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Profiling, +%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. + +\writestatus{loading}{ConTeXt Spacing Macros / Profiling} + +%D This is a placeholder for something to come. But as I don't want to +%D be harrassed by 'why does it work different than a week before' this +%D cool new feature will only end up here when stable enough. Alas. + +\unprotect + +\definesystemattribute[profilemethod][public] + +\unexpanded\def\setprofile [#1]{} +\unexpanded\def\resetprofile {} +\unexpanded\def\useprofileparameter#1{} +\unexpanded\def\addprofiletobox #1{} +\unexpanded\def\profilegivenbox #1#2{} +\unexpanded\def\profiledbox {\vbox} + +\protect \endinput diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index fc6fba0eb..d1cf09e17 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -61,7 +61,6 @@ local trace_page_builder = false trackers.register("builders.page", fun local trace_collect_vspacing = false trackers.register("vspacing.collect", function(v) trace_collect_vspacing = v end) local trace_vspacing = false trackers.register("vspacing.spacing", function(v) trace_vspacing = v end) local trace_vsnapping = false trackers.register("vspacing.snapping", function(v) trace_vsnapping = v end) -local trace_vpacking = false trackers.register("vspacing.packing", function(v) trace_vpacking = v end) local trace_specials = false trackers.register("vspacing.specials", function(v) trace_specials = v end) local report_vspacing = logs.reporter("vspacing","spacing") @@ -999,7 +998,11 @@ specialmethods[1] = function(pagehead,pagetail,start,penalty) end -- none found, so no reson to be special if trace_specials then - report_specials(" context penalty, discarding") + if pagetail then + report_specials(" context penalty, discarding, nothing special") + else + report_specials(" context penalty, discarding, nothing preceding") + end end return special_penalty_xxx end @@ -1124,19 +1127,17 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also -- -- todo: keep_together: between headers -- + local pagehead = nil + local pagetail = nil + local function getpagelist() if not pagehead then pagehead = texlists.page_head if pagehead then pagehead = tonut(texlists.page_head) pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet - else - pagetail = nil end - else - pagetail = nil end - return pagehead, pagetail end -- local function flush(why) @@ -1290,7 +1291,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also local sp = getattr(current,a_skippenalty) -- has no default, no unset (yet) if sp and sc == penalty then if where == "page" then - local pagehead, pagetail = getpagelist() + getpagelist() local p = specialmethods[specialmethod](pagehead,pagetail,current,sp) if p then if trace then @@ -1706,7 +1707,7 @@ local ignore = table.tohash { function vspacing.vboxhandler(head,where) if head and not ignore[where] then local h = tonut(head) - if getnext(h) then + if getnext(h) then -- what if a one liner and snapping? h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper return tonode(h) end @@ -1714,13 +1715,17 @@ function vspacing.vboxhandler(head,where) return head end -function vspacing.collapsevbox(n) -- for boxes but using global a_snapmethod +function vspacing.collapsevbox(n,aslist) -- for boxes but using global a_snapmethod local box = getbox(n) if box then local list = getlist(box) if list then list = collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod) - setfield(box,"list",vpack_node(list)) + if aslist then + setfield(box,"list",list) -- beware, dimensions of box are wrong now + else + setfield(box,"list",vpack_node(list)) + end end end end @@ -1772,6 +1777,13 @@ implement { arguments = "integer" } +implement { + name = "vspacingcollapseonly", + actions = vspacing.collapsevbox, + scope = "private", + arguments = { "integer", true } +} + implement { name = "vspacingsnap", actions = vspacing.snapbox, diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index e44056954..86a731d3c 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -881,11 +881,11 @@ \strutheightfactor\dimexpr\normallineheight \fi \strutdp\spacingfactor\dimexpr - \ifdim\minimumstrutdepth>\zeropoint - \minimumstrutdepth - \else - \strutdepthfactor\dimexpr\normallineheight - \fi + \ifdim\minimumstrutdepth>\zeropoint + \minimumstrutdepth + \else + \strutdepthfactor\dimexpr\normallineheight + \fi \dosetstrut} \unexpanded\def\setcharstrut#1% @@ -924,7 +924,9 @@ \ifabsnum\dimexpr\strutht+\strutdp-\lineheight\relax<\plustwo % compensate rounding error /- 1sp to avoid too many % 1sp baselineskips in for instance verbatim - \strutht\dimexpr\lineheight-\strutdp\relax + % \strutht\dimexpr\lineheight-\strutdp\relax + % better: + \strutdp\dimexpr\lineheight-\strutht\relax \struttotal\lineheight \else \struttotal\dimexpr\strutht+\strutdp\relax @@ -944,15 +946,47 @@ \s!height\strutht \s!depth \strutdp}} +\newconstant\c_strut_visual_mode + \def\spac_struts_set_vide {\setbox\strutbox\hbox % at some time this extra wrapping was needed {\spac_struts_vide_hbox to \zeropoint - {% \hss % new, will be option - \vrule - \s!width \strutwidth - \s!height\strutht - \s!depth \strutdp - \hss}}} + {\ifcase\c_strut_visual_mode + \spac_struts_black + \or + \spac_struts_color + \else + \spac_struts_black + \fi}}} + +\def\spac_struts_black + {\vrule + \s!width \strutwidth + \s!height\strutht + \s!depth \strutdp + \hss} + +\def\spac_struts_color + {\hss % new, will be option + \scratchwidth.1\struthtdp + \begingroup + \directcolor[f:b:t]% + \vrule + \s!width \scratchwidth + \s!height\strutht + \s!depth \strutdp + \kern-\scratchwidth + \vrule + \s!width \scratchwidth + \s!height\zeropoint + \s!depth \strutdp + \endgroup + \kern-.625\scratchwidth + \vrule + \s!width .25\scratchwidth + \s!height\strutht + \s!depth \strutdp + \hss} \let\spac_struts_vide_hbox\hbox % overloaded in trac-vis.mkiv @@ -1046,7 +1080,13 @@ \fi} \unexpanded\def\showstruts % adapts .. is wrong - {\setteststrut + {\c_strut_visual_mode\zerocount + \setteststrut + \settestcrlf} + +\unexpanded\def\showcolorstruts % adapts .. is wrong + {\c_strut_visual_mode\plusone + \setteststrut \settestcrlf} \unexpanded\def\setteststrut @@ -1395,6 +1435,16 @@ \fi \setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\csname\??gridsnapperattributes\currentsnapper\endcsname\space}} +\unexpanded\def\usegridparameter#1% no checking here + {\edef\m_spac_grid_asked{#1\c!grid}% + \ifx\m_spac_grid_asked\empty + \attribute \snapvboxattribute\attributeunsetvalue + \else + \spac_grids_snap_value_set\m_spac_grid_asked + \attribute \snapvboxattribute\attribute\snapmethodattribute + \fi} + + \unexpanded\def\definegridsnapping {\dodoubleargument\spac_grids_define} @@ -1471,13 +1521,13 @@ \unexpanded\def\synchronizelocallinespecs {\bodyfontlineheight \normallineheight - \bodyfontstrutheight\strutheight - \bodyfontstrutdepth \strutdepth} + \bodyfontstrutheight\strutht + \bodyfontstrutdepth \strutdp} \unexpanded\def\synchronizegloballinespecs {\global\globalbodyfontlineheight \normallineheight - \global\globalbodyfontstrutheight\strutheight - \global\globalbodyfontstrutdepth \strutdepth} + \global\globalbodyfontstrutheight\strutht + \global\globalbodyfontstrutdepth \strutdp} \appendtoks \synchronizegloballinespecs @@ -1898,7 +1948,7 @@ % category:4 is default -% this interface might change (into an \install, buw we will then keep this one hidden) +% this interface might change (into an \install, but we will then keep this one hidden) \definevspacingamount[\v!none] [\zeropoint] [\zeropoint] \definevspacingamount[\v!big] [\bigskipamount] [\bodyfontlineheight] @@ -1909,8 +1959,8 @@ \definevspacingamount[\v!quarterline] [.25\openlineheight] [.25\bodyfontlineheight] \definevspacingamount[\v!formula] [\medskipamount] [.5\bodyfontlineheight] \definevspacingamount[\v!white] [\parskip] [\bodyfontwhitespace] -\definevspacingamount[\v!height] [\strutheight] [\bodyfontstrutheight] -\definevspacingamount[\v!depth] [\strutdepth] [\bodyfontstrutdepth] +\definevspacingamount[\v!height] [\strutht] [\bodyfontstrutheight] +\definevspacingamount[\v!depth] [\strutdp] [\bodyfontstrutdepth] \definevspacingamount[-\v!line] [-\openlineheight] [-\bodyfontlineheight] \definevspacingamount[-\v!halfline] [-.5\openlineheight] [-.5\bodyfontlineheight] diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index dc228ad8a..8a968413d 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 02c9447e8..91de40e87 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/strc-flt.mkvi b/tex/context/base/strc-flt.mkvi index 9a7fc56f6..76b587f09 100644 --- a/tex/context/base/strc-flt.mkvi +++ b/tex/context/base/strc-flt.mkvi @@ -11,6 +11,8 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +%D This module will be redone with conditionals and everythings + \writestatus{loading}{ConTeXt Structure Macros / Float Numbering} \registerctxluafile{strc-flt}{1.001} @@ -478,6 +480,10 @@ \ifx\currentfloat\empty \let\currentfloat\v!figure % a bit of a hack \fi + \doifelsecommandhandler\??float\currentfloat + \donothing + {\writestatus\m!floatblocks{unknown float type '\currentfloat'}% + \let\currentfloat\v!figure}% also a hack \global\let\lastplacedfloat\currentfloat \let\m_strc_floats_saved_userdata\empty \let\currentfloatcaption\currentfloat} @@ -1774,7 +1780,7 @@ {\dp\b_strc_floats_caption\strutdepth \setbox\scratchbox\vbox {\strc_floats_align_caption{\copy\b_strc_floats_caption}% - \strc_floats_align_content {\copy\b_strc_floats_content }}% + \strc_floats_align_content{\copy\b_strc_floats_content}}% \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy \vbox to \noflines\lineheight {\d_strc_float_temp_width\wd\b_strc_floats_content @@ -2304,6 +2310,7 @@ \installfloatmethod \s!singlecolumn \v!local \somelocalfloat \installfloatmethod \s!multicolumn \v!local \somelocalfloat +\installfloatmethod \s!mixedcolumn \v!local \somelocalfloat \installfloatmethod \s!columnset \v!local \somelocalfloat \protect \endinput diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index b6f2e9a37..2a1d0dd59 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -378,13 +378,13 @@ implement { function references.set(data) local references = data.references - local prefix = references.prefix or "" local reference = references.reference if not reference or reference == "" then - report_references("invalid reference") + -- report_references("invalid reference") -- harmless return 0 end - local pd = tobesaved[prefix] -- nicer is a metatable + local prefix = references.prefix or "" + local pd = tobesaved[prefix] -- nicer is a metatable if not pd then pd = { } tobesaved[prefix] = pd diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv index f2a183601..b5a1a5ba0 100644 --- a/tex/context/base/strc-sec.mkiv +++ b/tex/context/base/strc-sec.mkiv @@ -301,13 +301,13 @@ \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 -\def\setstructurenumber #1#2{\clf_setstructurenumber #1{#2}} % level, number (+/-) -\def\getstructurenumber #1{\clf_getstructurenumber #1 } % level -\def\getsomestructurenumber #1#2{\clf_getsomestructurenumber #1{#2}} % level, what -\def\getfullstructurenumber #1{\clf_getfullstructurenumber #1 } % level -\def\getsomefullstructurenumber#1#2{\clf_getsomefullstructurenumber #1{#2}} % level, what +\def\setstructurelevel #1#2{\clf_setstructurelevel {#1}{#2}} % name, level|parent +\def\getstructurelevel #1{\clf_getstructurelevel {#1}} % name +\def\setstructurenumber #1#2{\clf_setstructurenumber #1{#2}} % level, number (+/-) +\def\getstructurenumber #1{\clf_getstructurenumber \numexpr#1\relax} % level +\def\getsomestructurenumber #1#2{\clf_getsomestructurenumber #1{#2}} % level, what +\def\getfullstructurenumber #1{\clf_getfullstructurenumber \numexpr#1\relax} % level +\def\getsomefullstructurenumber#1#2{\clf_getsomefullstructurenumber #1{#2}} % level, what \def\getspecificstructuretitle #1{\clf_getspecificstructuretitle {#1}{\headparameter\s!catcodes}} % structure heads (like \startchapter) diff --git a/tex/context/base/supp-ran.lua b/tex/context/base/supp-ran.lua index 1d34393fa..4968e8cfc 100644 --- a/tex/context/base/supp-ran.lua +++ b/tex/context/base/supp-ran.lua @@ -10,6 +10,11 @@ if not modules then modules = { } end modules ['supp-ran'] = { local report_system = logs.reporter("system","randomizer") +local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end) +local trace_random_mp = false trackers.register("system.randomizer.mp",function(v) trace_random_mp = v end) + +local insert, remove = table.insert, table.remove + local math = math local context = context local implement = interfaces.implement @@ -17,20 +22,19 @@ local implement = interfaces.implement local random = math.random local randomseed = math.randomseed local round = math.round -local seed = false +local stack = { } local last = 1 local maxcount = 2^30-1 -- 1073741823 -local function setrandomseedi(n,comment) - if not n then - -- n = 0.5 -- hack - end +local function setrandomseedi(n) if n <= 1 then n = n * maxcount + elseif n < 1000 then + n = n * 1000 end n = round(n) - if false then - report_system("setting seed to %s (%s)",n,comment or "normal") + if trace_random then + report_system("setting seed to %s",n) end randomseed(n) last = random(0,maxcount) -- we need an initial value @@ -52,30 +56,52 @@ local function getrandomseed() return last end +local function getmprandomnumber() + last = random(0,4095) + if trace_random_mp then + report_system("using mp seed %s",last) + end + return last +end + -- maybe stack -local function freezerandomseed(n) - if seed == false or seed == nil then - seed = last - setrandomseedi(seed,"freeze",seed) +local function pushrandomseed() + insert(stack,last) + if trace_random then + report_system("pushing seed %s",last) end - if n then - randomseed(n) +end + +local function reuserandomseed(n) + local seed = stack[#stack] + if seed then + if trace_random then + report_system("reusing seed %s",last) + end + randomseed(seed) end end -local function defrostrandomseed() - if seed ~= false then - setrandomseedi(seed,"defrost",seed) -- was last (bug) - seed = false +local function poprandomseed() + local seed = remove(stack) + if seed then + if trace_random then + report_system("popping seed %s",seed) + end + randomseed(seed) end end +-- todo: also open up in utilities.randomizer.* + implement { name = "getrandomnumber", actions = { getrandomnumber, context }, arguments = { "integer", "integer" } } implement { name = "getrandomdimen", actions = { getrandomnumber, context }, arguments = { "dimen", "dimen" } } implement { name = "getrandomfloat", actions = { getrandomnumber, context }, arguments = { "number", "number" } } +implement { name = "getmprandomnumber", actions = { getmprandomnumber, context } } implement { name = "setrandomseed", actions = { setrandomseed }, arguments = { "integer" } } implement { name = "getrandomseed", actions = { getrandomseed, context } } -implement { name = "freezerandomseed", actions = { freezerandomseed } } -implement { name = "defrostrandomseed", actions = { defrostrandomseed } } +implement { name = "pushrandomseed", actions = { pushrandomseed } } +implement { name = "poprandomseed", actions = { poprandomseed } } +implement { name = "reuserandomseed", actions = { reuserandomseed } } diff --git a/tex/context/base/supp-ran.mkiv b/tex/context/base/supp-ran.mkiv index e49173717..f7cfd6e73 100644 --- a/tex/context/base/supp-ran.mkiv +++ b/tex/context/base/supp-ran.mkiv @@ -26,7 +26,14 @@ \unexpanded\def\getrandomfloat #1#2#3{\edef#1{\clf_getrandomfloat#2 #3}} \unexpanded\def\setrandomseed #1{\clf_setrandomseed#1\relax} \unexpanded\def\getrandomseed #1{\edef#1{\clf_getrandomseed}} -\unexpanded\def\freezerandomseed {\clf_freezerandomseed} -\unexpanded\def\defrostrandomseed {\clf_defrostrandomseed} +\unexpanded\def\pushrandomseed {\clf_pushrandomseed} +\unexpanded\def\poprandomseed {\clf_poprandomseed} +\unexpanded\def\reuserandomseed {\clf_reuserandomseed} % within push/pop + +\let\freezerandomseed \pushrandomseed +\let\defrostrandomseed\poprandomseed + +\def\randomnumber #1#2{\clf_getrandomnumber\numexpr#1\relax\numexpr#2\relax} +\let\mprandomnumber \clf_getmprandomnumber \protect \endinput diff --git a/tex/context/base/tabl-xtb.lua b/tex/context/base/tabl-xtb.lua index bddd627ad..4bf8e3107 100644 --- a/tex/context/base/tabl-xtb.lua +++ b/tex/context/base/tabl-xtb.lua @@ -707,8 +707,9 @@ function xtables.reflow_height() local delta = htdp - total if delta > 0 then delta = delta / ny - for y=1,ny do - heights[y] = heights[y] + delta + for y=0,ny-1 do + local nxt = r + y + heights[nxt] = heights[nxt] + delta end end end diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index ed9989a81..062f0208f 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -115,10 +115,13 @@ appendaction("finalizers", "lists", "builders.paragraphs.tag") -- still experimental -appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate") -- +appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate") + appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler") -- last ! +appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler") -- here ! -appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler") -- +appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler") +appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler") -- here ! -- experimental too @@ -192,7 +195,10 @@ disableaction("math", "noads.handlers.classes") disableaction("math", "typesetters.directions.processmath") disableaction("mvlbuilders", "typesetters.checkers.handler") +disableaction("mvlbuilders", "builders.profiling.pagehandler") + disableaction("vboxbuilders","typesetters.checkers.handler") +disableaction("vboxbuilders","builders.profiling.vboxhandler") freezecallbacks("find_.*_file", "find file using resolver") freezecallbacks("read_.*_file", "read file at once") diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua index 86af6da0b..a20e42d1a 100644 --- a/tex/context/base/trac-vis.lua +++ b/tex/context/base/trac-vis.lua @@ -288,10 +288,13 @@ for mode, value in next, modes do trackers.register(formatters["visualizers.%s"](mode), function(v) set(mode,v) end) end -trackers.register("visualizers.reset", function(v) set("reset", v) end) -trackers.register("visualizers.all", function(v) set("all", v) end) -trackers.register("visualizers.makeup",function(v) set("makeup",v) end) -trackers.register("visualizers.boxes", function(v) set("boxes", v) end) +local fraction = 10 + +trackers .register("visualizers.reset", function(v) set("reset", v) end) +trackers .register("visualizers.all", function(v) set("all", v) end) +trackers .register("visualizers.makeup", function(v) set("makeup",v) end) +trackers .register("visualizers.boxes", function(v) set("boxes", v) end) +directives.register("visualizers.fraction", function(v) fraction = tonumber(v) or fraction end) local c_positive = "trace:b" local c_negative = "trace:r" @@ -301,6 +304,7 @@ local c_space = "trace:y" local c_skip_a = "trace:c" local c_skip_b = "trace:m" local c_glyph = "trace:o" +local c_ligature = "trace:s" local c_white = "trace:w" local c_math = "trace:r" @@ -312,6 +316,7 @@ local c_space_d = "trace:dy" local c_skip_a_d = "trace:dc" local c_skip_b_d = "trace:dm" local c_glyph_d = "trace:do" +local c_ligature_d = "trace:ds" local c_white_d = "trace:dw" local c_math_d = "trace:dr" @@ -351,7 +356,7 @@ local function fontkern(head,current) -- print("hit fontkern") else local text = fast_hpack_string(formatters[" %0.3f"](kern*pt_factor),usedfont) - local rule = new_rule(emwidth/10,6*exheight,2*exheight) + local rule = new_rule(emwidth/fraction,6*exheight,2*exheight) local list = getlist(text) if kern > 0 then setlistcolor(list,c_positive_d) @@ -470,7 +475,7 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous) local prev = previous -- getprev(current) ... prev can be wrong in math mode < 0.78.3 setfield(current,"next",nil) setfield(current,"prev",nil) - local linewidth = emwidth/10 + local linewidth = emwidth/fraction local baseline, baseskip if dp ~= 0 and ht ~= 0 then if wd > 20*linewidth then @@ -574,7 +579,7 @@ local function ruledglyph(head,current,previous) local prev = previous setfield(current,"next",nil) setfield(current,"prev",nil) - local linewidth = emwidth/20 + local linewidth = emwidth/(2*fraction) local baseline -- if dp ~= 0 and ht ~= 0 then if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then @@ -591,8 +596,14 @@ local function ruledglyph(head,current,previous) new_kern(-wd+doublelinewidth), baseline ) +local char = chardata[getfield(current,"font")][getfield(current,"char")] +if char and char.tounicode and #char.tounicode > 4 then -- hack test + setlistcolor(info,c_ligature) + setlisttransparency(info,c_ligature_d) +else setlistcolor(info,c_glyph) setlisttransparency(info,c_glyph_d) +end info = fast_hpack(info) setfield(info,"width",0) setfield(info,"height",0) diff --git a/tex/context/base/trac-vis.mkiv b/tex/context/base/trac-vis.mkiv index a227e8354..6ee8a6b8d 100644 --- a/tex/context/base/trac-vis.mkiv +++ b/tex/context/base/trac-vis.mkiv @@ -120,15 +120,18 @@ \clf_setvisualfont\fontid\font \endgroup} +\unexpanded\def\resetvisualizers + {\attribute\visualattribute\attributeunsetvalue} + %D New (these might also be a visualizers): -\definecolor[f:r:t][a=1,t=.25,r=1] -\definecolor[f:g:t][a=1,t=.25,g=1] -\definecolor[f:b:t][a=1,t=.25,b=1] -\definecolor[f:c:t][a=1,t=.25,c=1] -\definecolor[f:m:t][a=1,t=.25,m=1] -\definecolor[f:y:t][a=1,t=.25,y=1] -\definecolor[f:k:t][a=1,t=.25,s=0] +% \definecolor[f:r:t][a=1,t=.25,r=1] +% \definecolor[f:g:t][a=1,t=.25,g=1] +% \definecolor[f:b:t][a=1,t=.25,b=1] +% \definecolor[f:c:t][a=1,t=.25,c=1] +% \definecolor[f:m:t][a=1,t=.25,m=1] +% \definecolor[f:y:t][a=1,t=.25,y=1] +% \definecolor[f:k:t][a=1,t=.25,s=0] % \def\node_backgrounds_boxes_add#1[#2]% % {\node_backgrounds_boxes_initialize diff --git a/tex/context/base/x-asciimath.lua b/tex/context/base/x-asciimath.lua index 7ddf5a637..6030be86c 100644 --- a/tex/context/base/x-asciimath.lua +++ b/tex/context/base/x-asciimath.lua @@ -123,6 +123,7 @@ local reserved = { ["bar"] = { false, "\\overbar", "unary" }, ["overbar"] = { false, "\\overbar", "unary" }, ["underline"] = { false, "\\underline", "unary" }, + ["ul"] = { false, "\\underline", "unary" }, ["vec"] = { false, "\\overrightarrow", "unary" }, ["dot"] = { false, "\\dot", "unary" }, -- 0x2D9 ["ddot"] = { false, "\\ddot", "unary" }, -- 0xA8 diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 1d6509ae4..2bff7b0b6 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 : 04/18/15 14:41:50 +-- merge date : 04/29/15 19:31:00 do -- begin closure to overcome local limits and interference @@ -699,6 +699,31 @@ local function make(t) end return p end +local function collapse(t,x) + if type(t)~="table" then + return t,x + else + local n=next(t) + if n==nil then + return t,x + elseif next(t,n)==nil then + local k=n + local v=t[k] + if type(v)=="table" then + return collapse(v,x..k) + else + return v,x..k + end + else + local tt={} + for k,v in next,t do + local vv,kk=collapse(v,k) + tt[kk]=vv + end + return tt,x + end + end +end function lpeg.utfchartabletopattern(list) local tree={} local n=#list -- cgit v1.2.3