diff options
53 files changed, 1932 insertions, 1429 deletions
diff --git a/doc/context/scripts/mkiv/mtx-fonts.html b/doc/context/scripts/mkiv/mtx-fonts.html index 3ddc2fa8e..97a16c79a 100644 --- a/doc/context/scripts/mkiv/mtx-fonts.html +++ b/doc/context/scripts/mkiv/mtx-fonts.html @@ -53,7 +53,7 @@ <tr><th>--filter</th><td>list</td><td>key-value pairs</td></tr> <tr><th>--all</th><td></td><td>show all found instances (combined with other flags)</td></tr> <tr><th>--info</th><td></td><td>give more details</td></tr> - <tr><th>--track</th><td>list</td><td>enable trackers</td></tr> + <tr><th>--trackers</th><td>list</td><td>enable trackers</td></tr> <tr><th>--statistics</th><td></td><td>some info about the database</td></tr> </table> <br/> diff --git a/doc/context/scripts/mkiv/mtx-fonts.man b/doc/context/scripts/mkiv/mtx-fonts.man index 9136e30fe..06a20635f 100644 --- a/doc/context/scripts/mkiv/mtx-fonts.man +++ b/doc/context/scripts/mkiv/mtx-fonts.man @@ -44,7 +44,7 @@ show all found instances (combined with other flags) .B --info give more details .TP -.B --track=list +.B --trackers=list enable trackers .TP .B --statistics diff --git a/doc/context/scripts/mkiv/mtx-fonts.xml b/doc/context/scripts/mkiv/mtx-fonts.xml index b138a064a..c3c571ca8 100644 --- a/doc/context/scripts/mkiv/mtx-fonts.xml +++ b/doc/context/scripts/mkiv/mtx-fonts.xml @@ -25,7 +25,7 @@ <flag name="filter" value="list"><short>key-value pairs</short></flag> <flag name="all"><short>show all found instances (combined with other flags)</short></flag> <flag name="info"><short>give more details</short></flag> - <flag name="track" value="list"><short>enable trackers</short></flag> + <flag name="trackers" value="list"><short>enable trackers</short></flag> <flag name="statistics"><short>some info about the database</short></flag> </subcategory> </category> diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua index 675d9fb12..694e6a649 100644 --- a/scripts/context/lua/mtx-fonts.lua +++ b/scripts/context/lua/mtx-fonts.lua @@ -38,7 +38,7 @@ local helpinfo = [[ <flag name="filter" value="list"><short>key-value pairs</short></flag> <flag name="all"><short>show all found instances (combined with other flags)</short></flag> <flag name="info"><short>give more details</short></flag> - <flag name="track" value="list"><short>enable trackers</short></flag> + <flag name="trackers" value="list"><short>enable trackers</short></flag> <flag name="statistics"><short>some info about the database</short></flag> </subcategory> </category> diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua index 950b9dc8c..84d3a6d8f 100644 --- a/tex/context/base/back-exp.lua +++ b/tex/context/base/back-exp.lua @@ -35,7 +35,7 @@ if not modules then modules = { } end modules ['back-exp'] = { -- check setting __i__ local next, type, tonumber = next, type, tonumber -local format, concat, sub, gsub = string.format, table.concat, string.sub, string.gsub +local concat, sub, gsub = table.concat, string.sub, string.gsub local validstring = string.valid local lpegmatch = lpeg.match local utfchar, utfvalues = utf.char, utf.values @@ -136,19 +136,16 @@ local traverse_nodes = nuts.traverse local references = structures.references local structurestags = structures.tags local taglist = structurestags.taglist +local specifications = structurestags.specifications local properties = structurestags.properties -local userdata = structurestags.userdata -- might be combines with taglist -local tagdata = structurestags.data -local tagmetadata = structurestags.metadata -local detailedtag = structurestags.detailedtag -local userproperties = structurestags.userproperties +local locatedtag = structurestags.locatedtag local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming -- todo: more locals (and optimize) -local exportversion = "0.32" +local exportversion = "0.33" local mathmlns = "http://www.w3.org/1998/Math/MathML" local nofcurrentcontent = 0 -- so we don't free (less garbage collection) @@ -160,7 +157,6 @@ local currentparagraph = nil local noftextblocks = 0 -local attributehash = { } -- to be considered: set the values at the tex end local hyphencode = 0xAD local hyphen = utfchar(0xAD) -- todo: also emdash etc local tagsplitter = structurestags.patterns.splitter @@ -281,14 +277,6 @@ setmetatableindex(namespaced, function(t,k) end end) --- local function attribute(key,value) --- if value and value ~= "" then --- return f_attribute(key,gsub(value,".",attribentities)) --- else --- return "" --- end --- end - local function attribute(key,value) if value and value ~= "" then return f_attribute(key,lpegmatch(p_attribute,value)) @@ -297,6 +285,20 @@ local function attribute(key,value) end end +local function setattribute(di,key,value,escaped) + if value and value ~= "" then + local a = di.attributes + if escaped then + value = lpegmatch(p_escaped,value) + end + if not a then + di.attributes = { [key] = value } + else + a[key] = value + end + end +end + local listdata = { } -- maybe do this otherwise function wrapups.hashlistdata() @@ -313,20 +315,12 @@ end local spaces = utilities.strings.newrepeater(" ",-1) -function structurestags.setattributehash(fulltag,key,value) -- public hash - if type(fulltag) == "number" then - fulltag = taglist[fulltag] - if fulltag then - fulltag = fulltag[#fulltag] - end - end - if fulltag then - local ah = attributehash[fulltag] -- could be metatable magic - if not ah then - ah = { } - attributehash[fulltag] = ah - end - ah[key] = value +function structurestags.setattributehash(attr,key,value) -- public hash + local specification = taglist[attr] + if specification then + specification[key] = value + else + -- some kind of error end end @@ -484,13 +478,14 @@ properties.vspace = { export = "break", nature = "display" } local function makebreaklist(list) nofbreaks = nofbreaks + 1 local t = { } - if list then + local l = list and list.taglist + if l then for i=1,#list do - t[i] = list[i] + t[i] = l[i] end end - t[#t+1] = "break-" .. nofbreaks -- maybe no number - return t + t[#t+1] = "break>" .. nofbreaks -- maybe no number + return { taglist = t } end local breakattributes = { @@ -501,7 +496,7 @@ local function makebreaknode(attributes) -- maybe no fulltag nofbreaks = nofbreaks + 1 return { tg = "break", - fulltag = "break-" .. nofbreaks, + fulltag = "break>" .. nofbreaks, n = nofbreaks, element = "break", nature = "display", @@ -512,7 +507,7 @@ local function makebreaknode(attributes) -- maybe no fulltag } end -local function ignorebreaks(result,element,detail,n,fulltag,di) +local function ignorebreaks(result,element,n,fulltag,di) local data = di.data for i=1,#data do local d = data[i] @@ -522,7 +517,7 @@ local function ignorebreaks(result,element,detail,n,fulltag,di) end end -local function ignorespaces(result,element,detail,n,fulltag,di) +local function ignorespaces(result,element,n,fulltag,di) local data = di.data for i=1,#data do local d = data[i] @@ -544,13 +539,14 @@ do local di = data[i] local tg = di.tg if tg == "noexport" then - local ud = userdata[di.fulltag] - if ud then - local comment = ud.comment + local s = specifications[di.fulltag] + local u = s and s.userdata + if u then + local comment = u.comment if comment then di.element = "comment" di.data = { { content = comment } } - ud.comment = nil + u.comment = nil else data[i] = false end @@ -569,20 +565,20 @@ do end end - function extras.document(result,element,detail,n,fulltag,di) - result[#result+1] = f_attribute("language",languagenames[texgetcount("mainlanguagenumber")]) + function extras.document(result,element,n,fulltag,di) + setattribute(di,"language",languagenames[texgetcount("mainlanguagenumber")]) if not less_state then - result[#result+1] = f_attribute("file",tex.jobname) - result[#result+1] = f_attribute("date",os.date()) - result[#result+1] = f_attribute("context",environment.version) - result[#result+1] = f_attribute("version",exportversion) - result[#result+1] = f_attribute("xmlns:m",mathmlns) + setattribute(di,"file",tex.jobname) + setattribute(di,"date",os.date()) + setattribute(di,"context",environment.version) + setattribute(di,"version",exportversion) + setattribute(di,"xmlns:m",mathmlns) local identity = interactions.general.getidentity() for i=1,#fields do local key = fields[i] local value = identity[key] if value and value ~= "" then - result[#result+1] = f_attribute(key,value) + setattribute(di,key,value) end end end @@ -595,27 +591,18 @@ do local itemgroups = { } - local f_symbol = formatters[' symbol="%s"'] - local s_packed = ' packed="yes"' - - function structurestags.setitemgroup(current,packed,symbol) - itemgroups[detailedtag("itemgroup",current)] = { + function structurestags.setitemgroup(packed,symbol) + itemgroups[locatedtag("itemgroup")] = { packed = packed, symbol = symbol, } end - function extras.itemgroup(result,element,detail,n,fulltag,di) + function extras.itemgroup(result,element,n,fulltag,di) local hash = itemgroups[fulltag] if hash then - local packed = hash.packed - if packed then - result[#result+1] = s_packed - end - local symbol = hash.symbol - if symbol then - result[#result+1] = f_symbol(symbol) - end + setattribute(di,"packed",hash.packed and "yes" or nil) + setattribute(di,"symbol",hash.symbol) end end @@ -626,27 +613,25 @@ do local synonyms = { } local sortings = { } - local f_tag = formatters[' tag="%s"'] - - function structurestags.setsynonym(current,tag) - synonyms[detailedtag("synonym",current)] = tag + function structurestags.setsynonym(tag) + synonyms[locatedtag("synonym")] = tag end - function extras.synonym(result,element,detail,n,fulltag,di) + function extras.synonym(result,element,n,fulltag,di) local tag = synonyms[fulltag] if tag then - result[#result+1] = f_tag(tag) + setattribute(di,"tag",tag) end end - function structurestags.setsorting(current,tag) - sortings[detailedtag("sorting",current)] = tag + function structurestags.setsorting(tag) + sortings[locatedtag("sorting")] = tag end - function extras.sorting(result,element,detail,n,fulltag,di) + function extras.sorting(result,element,n,fulltag,di) local tag = sortings[fulltag] if tag then - result[#result+1] = f_tag(tag) + setattribute(di,"tag",tag) end end @@ -657,8 +642,8 @@ do local highlight = { } usedstyles.highlight = highlight - function structurestags.sethighlight(current,style,color) -- we assume global styles - highlight[current] = { + function structurestags.sethighlight(style,color) -- we assume global styles + highlight[locatedtag("highlight")] = { style = style, -- xml.css.fontspecification(style), color = color, -- xml.css.colorspec(color), } @@ -674,22 +659,20 @@ do local symbols = { } local linked = { } - local f_insert = formatters[' insert="%s"'] - - function structurestags.setdescription(tag,n) + function structurestags.setdescription(tag,n) -- needs checking (is tag needed) -- we can also use the internals hash or list local nd = structures.notes.get(tag,n) if nd then local references = nd.references - descriptions[references and references.internal] = detailedtag("description",tag) + descriptions[references and references.internal] = locatedtag("description") end end - function structurestags.setdescriptionsymbol(tag,n) + function structurestags.setdescriptionsymbol(tag,n) -- needs checking (is tag needed) local nd = structures.notes.get(tag,n) -- todo: use listdata instead if nd then local references = nd.references - symbols[references and references.internal] = detailedtag("descriptionsymbol",tag) + symbols[references and references.internal] = locatedtag("descriptionsymbol") end end @@ -705,17 +688,17 @@ do end end - function extras.description(result,element,detail,n,fulltag,di) + function extras.description(result,element,n,fulltag,di) local id = linked[fulltag] if id then - result[#result+1] = f_insert(id) -- maybe just fulltag + setattribute(di,"insert",id) end end - function extras.descriptionsymbol(result,element,detail,n,fulltag,di) + function extras.descriptionsymbol(result,element,n,fulltag,di) local id = linked[fulltag] if id then - result[#result+1] = f_insert(id) + setattribute(di,"insert",id) end end @@ -723,7 +706,7 @@ end -- -- todo: ignore breaks -- --- function extras.verbatimline(result,element,detail,n,fulltag,di) +-- function extras.verbatimline(result,element,n,fulltag,di) -- inspect(di) -- end @@ -732,11 +715,8 @@ do local image = { } usedimages.image = image - local f_imagespec = formatters[' id="%s" width="%s" height="%s"'] - local f_imagepage = formatters[' page="%s"'] - function structurestags.setfigure(name,used,page,width,height) - image[detailedtag("image")] = { + image[locatedtag("image")] = { name = name, used = used, page = page, @@ -745,15 +725,17 @@ do } end - function extras.image(result,element,detail,n,fulltag,di) + function extras.image(result,element,n,fulltag,di) local data = image[fulltag] if data then - result[#result+1] = attribute("name",data.name) + setattribute(di,"name",data.name) local page = tonumber(data.page) if page and page > 1 then - result[#result+1] = f_imagepage(page) + setattribute(di,"page",page) end - result[#result+1] = f_imagespec(fulltag,data.width,data.height) + setattribute(di,"id",fulltag) + setattribute(di,"width",data.width) + setattribute(di,"height",data.height) end end @@ -763,19 +745,18 @@ do local combinations = { } - local f_combispec = formatters[' nx="%s" ny="%s"'] - function structurestags.setcombination(nx,ny) - combinations[detailedtag("combination")] = { + combinations[locatedtag("combination")] = { nx = nx, ny = ny, } end - function extras.combination(result,element,detail,n,fulltag,di) + function extras.combination(result,element,n,fulltag,di) local data = combinations[fulltag] if data then - result[#result+1] = f_combispec(data.nx,data.ny) + setattribute(di,"nx",data.nx) + setattribute(di,"ny",data.ny) end end @@ -799,37 +780,37 @@ local evaluators = { } local specials = { } local explicits = { } -evaluators.inner = function(result,var) +evaluators.inner = function(di,var) local inner = var.inner if inner then - result[#result+1] = attribute("location",inner) + setattribute(di,"location",inner,true) end end -evaluators.outer = function(result,var) +evaluators.outer = function(di,var) local file, url = references.checkedfileorurl(var.outer,var.outer) if url then - result[#result+1] = attribute("url",url) + setattribute(di,"url",url,true) elseif file then - result[#result+1] = attribute("file",file) + setattribute(di,"file",file,true) end end -evaluators["outer with inner"] = function(result,var) +evaluators["outer with inner"] = function(di,var) local file = references.checkedfile(var.f) if file then - result[#result+1] = attribute("file",file) + setattribute(di,"file",file,true) end local inner = var.inner if inner then - result[#result+1] = attribute("location",inner) + setattribute(di,"inner",inner,true) end end -evaluators.special = function(result,var) +evaluators.special = function(di,var) local handler = specials[var.special] if handler then - handler(result,var) + handler(di,var) end end @@ -841,57 +822,45 @@ do evaluators["special operation"] = evaluators.special evaluators["special operation with arguments"] = evaluators.special - local f_prefix = formatters[' prefix="%s"'] - local f_reference = formatters[' reference="%s"'] - local f_destination = formatters[' destination="%s"'] - - local f_implicit = formatters[' implicit="%s"'] -- automatic (internal) reference - local f_explicit = formatters[' explicit="%s"'] -- user given reference - - local f_internal = formatters[' internal="%s"'] -- links to implicit - local f_location = formatters[' location="%s"'] -- links to explicit - local f_url = formatters[' url="%s"'] - local f_file = formatters[' file="%s"'] - - function specials.url(result,var) + function specials.url(di,var) local url = references.checkedurl(var.operation) if url and url ~= "" then - result[#result+1] = f_url(lpegmatch(p_escaped,url)) + setattribute(di,"url",url,true) end end - function specials.file(result,var) + function specials.file(di,var) local file = references.checkedfile(var.operation) if file and file ~= "" then - result[#result+1] = f_file(lpegmatch(p_escaped,file)) + setattribute(di,"file",file,true) end end - function specials.fileorurl(result,var) + function specials.fileorurl(di,var) local file, url = references.checkedfileorurl(var.operation,var.operation) if url and url ~= "" then - result[#result+1] = f_url(lpegmatch(p_escaped,url)) + setattribute(di,"url",url,true) elseif file and file ~= "" then - result[#result+1] = f_file(lpegmatch(p_escaped,file)) + setattribute(di,"file",file,true) end end - function specials.internal(result,var) + function specials.internal(di,var) local internal = references.checkedurl(var.operation) if internal then - result[#result+1] = f_location(internal) + setattribute(di,"location",internal) end end - local function adddestination(result,references) -- todo: specials -> exporters and then concat + local function adddestination(di,references) -- todo: specials -> exporters and then concat if references then local reference = references.reference if reference and reference ~= "" then local prefix = references.prefix if prefix and prefix ~= "" then - result[#result+1] = f_prefix(prefix) + setattribute(di,"prefix",prefix,true) end - result[#result+1] = f_destination(lpegmatch(p_escaped,reference)) + setattribute(di,"destination",reference,true) for i=1,#references do local r = references[i] local e = evaluators[r.kind] @@ -903,49 +872,49 @@ do end end - local function addimplicit(result,references) + function extras.addimplicit(di,references) if references then local internal = references.internal if internal then - result[#result+1] = f_implicit(internal) + setattribute(di,"implicit",internal) end end end - local function addinternal(result,references) + function extras.addinternal(di,references) if references then local internal = references.internal if internal then - result[#result+1] = f_internal(internal) + setattribute(di,"internal",internal) end end end local p_firstpart = lpeg.Cs((1-lpeg.P(","))^0) - local function addreference(result,references) + local function addreference(di,references) if references then local reference = references.reference if reference and reference ~= "" then local prefix = references.prefix if prefix and prefix ~= "" then - result[#result+1] = f_prefix(prefix) + setattribute(di,"prefix",prefix) end - result[#result+1] = f_reference(lpegmatch(p_escaped,reference)) - result[#result+1] = f_explicit(lpegmatch(p_escaped,lpegmatch(p_firstpart,reference))) + setattribute(di,"reference",reference,true) + setattribute(di,"explicit",lpegmatch(p_firstpart,reference),true) end local internal = references.internal if internal and internal ~= "" then - result[#result+1] = f_implicit(internal) + setattribute(di,"implicit",internal) end end end - local function link(result,element,detail,n,fulltag,di) + local function link(di,element,n,fulltag,di) -- for instance in lists a link has nested elements and no own text local reference = referencehash[fulltag] if reference then - adddestination(result,structures.references.get(reference)) + adddestination(di,structures.references.get(reference)) return true else local data = di.data @@ -954,7 +923,7 @@ do local di = data[i] if di then local fulltag = di.fulltag - if fulltag and link(result,element,detail,n,fulltag,di) then + if fulltag and link(di,element,n,fulltag,di) then return true end end @@ -963,9 +932,6 @@ do end end - extras.addimplicit = addimplicit - extras.addinternal = addinternal - extras.adddestination = adddestination extras.addreference = addreference @@ -1073,8 +1039,8 @@ do end local tg = d.tg if tg == "mover" then - local p = properties[d.fulltag] - local t = p.top + local s = specifications[d.fulltag] + local t = s.top if t then d = d.data[1] local d1 = d.data[1] @@ -1083,8 +1049,8 @@ do return d end elseif tg == "munder" then - local p = properties[d.fulltag] - local b = p.bottom + local s = specifications[d.fulltag] + local b = s.bottom if b then d = d.data[1] local d1 = d.data[1] @@ -1145,8 +1111,8 @@ do -- data[1] = dummy_nucleus -- end elseif roottg == "mfenced" then - local p = properties[root.fulltag] - local l, m, r = p.left, p.middle, p.right + local s = specifications[root.fulltag] + local l, m, r = s.left, s.middle, s.right if l then l = utfchar(l) end @@ -1193,23 +1159,21 @@ do local di = data[i] if di and not di.content then local tg = di.tg - local detail = di.detail if tg == "math" then -- di.element = "mrow" -- when properties di.skip = "comment" checkmath(di) i = i + 1 elseif tg == "mover" then - if detail == "accent" then - local p = properties[di.fulltag] - local t = p.top + local s = specifications[di.fulltag] + if s.accent then + local t = s.top local d = di.data -- todo: accent = "false" (for scripts like limits) di.attributes = { accent = "true", } -- todo: p.topfixed - di.detail = nil if t then -- mover d[1].data[1].content = utfchar(t) @@ -1221,16 +1185,15 @@ do checkmath(di) i = i + 1 elseif tg == "munder" then - if detail == "accent" then - local p = properties[di.fulltag] - local b = p.bottom + local s = specifications[di.fulltag] + if s.accent then + local b = s.bottom local d = di.data -- todo: accent = "false" (for scripts like limits) di.attributes = { accent = "true", } -- todo: p.bottomfixed - di.detail = nil if b then -- munder d[2].data[1].content = utfchar(b) @@ -1241,10 +1204,10 @@ do checkmath(di) i = i + 1 elseif tg == "munderover" then - if detail == "accent" then - local p = properties[di.fulltag] - local t = p.top - local b = p.bottom + local s = specifications[di.fulltag] + if s.accent then + local t = s.top + local b = s.bottom local d = di.data -- todo: accent = "false" (for scripts like limits) -- todo: accentunder = "false" (for scripts like limits) @@ -1254,7 +1217,6 @@ do } -- todo: p.topfixed -- todo: p.bottomfixed - di.detail = nil if t and b then -- munderover d[1].data[1].content = utfchar(t) @@ -1373,68 +1335,70 @@ do } data[i] = di i = i + 1 - elseif detail then - -- no checkmath(di) here - local category = tonumber(detail) or 0 - if category == 1 then -- mo - i = collapse(di,i,data,ndata,detail,"mo") - elseif category == 2 then -- mi - i = collapse(di,i,data,ndata,detail,"mi") - elseif category == 3 then -- mn - i = collapse(di,i,data,ndata,detail,"mn") - elseif category == 4 then -- ms - i = collapse(di,i,data,ndata,detail,"ms") - elseif category >= 1000 then - local apply = category >= 2000 - if apply then - category = category - 1000 - end - if tg == "mi" then -- function - if roottg == "mrow" then - root.skip = "comment" - root.element = "function" - end + else + local category = di.mathcategory + if category then + -- no checkmath(di) here + if category == 1 then -- mo + i = collapse(di,i,data,ndata,detail,"mo") + elseif category == 2 then -- mi i = collapse(di,i,data,ndata,detail,"mi") - local tag = functions[category] - if tag then - di.data = functioncontent[tag] - end + elseif category == 3 then -- mn + i = collapse(di,i,data,ndata,detail,"mn") + elseif category == 4 then -- ms + i = collapse(di,i,data,ndata,detail,"ms") + elseif category >= 1000 then + local apply = category >= 2000 if apply then - di.after = apply_function - elseif automathapply then -- make function - local following - if i <= ndata then - -- normally not the case - following = data[i] - else - local parent = di.__p__ -- == root - if parent.tg == "mrow" then - parent = parent.__p__ - end - local index = parent.__i__ - following = parent.data[index+1] + category = category - 1000 + end + if tg == "mi" then -- function + if roottg == "mrow" then + root.skip = "comment" + root.element = "function" end - if following then - local tg = following.tg - if tg == "mrow" or tg == "mfenced" then -- we need to figure out the right condition - di.after = apply_function + i = collapse(di,i,data,ndata,detail,"mi") + local tag = functions[category] + if tag then + di.data = functioncontent[tag] + end + if apply then + di.after = apply_function + elseif automathapply then -- make function + local following + if i <= ndata then + -- normally not the case + following = data[i] + else + local parent = di.__p__ -- == root + if parent.tg == "mrow" then + parent = parent.__p__ + end + local index = parent.__i__ + following = parent.data[index+1] + end + if following then + local tg = following.tg + if tg == "mrow" or tg == "mfenced" then -- we need to figure out the right condition + di.after = apply_function + end end end + else -- some problem + checkmath(di) + i = i + 1 end - else -- some problem + else checkmath(di) i = i + 1 end + elseif automathnumber and tg == "mn" then + checkmath(di) + i = collapse_mn(di,i,data,ndata) else checkmath(di) i = i + 1 end - elseif automathnumber and tg == "mn" then - checkmath(di) - i = collapse_mn(di,i,data,ndata) - else - checkmath(di) - i = i + 1 end else -- can be string or boolean if parenttg ~= "mtext" and di == " " then @@ -1524,8 +1488,8 @@ do end function checks.math(di) - local hash = attributehash[di.fulltag] - local mode = (hash and hash.mode) == "display" and "block" or "inline" + local specification = specifications[di.fulltag] + local mode = specification and specification.mode == "display" and "block" or "inline" di.attributes = { ["display"] = mode, ["xmlns:m"] = mathmlns, @@ -1545,7 +1509,7 @@ do local a, z, A, Z = 0x61, 0x7A, 0x41, 0x5A - function extras.mi(result,element,detail,n,fulltag,di) -- check with content + function extras.mi(di,element,n,fulltag,di) -- check with content local str = di.data[1].content if str and sub(str,1,1) ~= "&" then -- hack but good enough (maybe gsub op eerste) for v in utfvalues(str) do @@ -1561,7 +1525,7 @@ do end end - function extras.msub(result,element,detail,n,fulltag,di) + function extras.msub(di,element,n,fulltag,di) -- m$^2$ local data = di.data if #data == 1 then @@ -1579,12 +1543,11 @@ end do local registered = structures.sections.registered - local f_level = formatters[' level="%s"'] - local function resolve(result,element,detail,n,fulltag,di) + local function resolve(di,element,n,fulltag,di) local data = listdata[fulltag] if data then - extras.addreference(result,data.references) + extras.addreference(di,data.references) return true else local data = di.data @@ -1593,7 +1556,7 @@ do local di = data[i] if di then local ft = di.fulltag - if ft and resolve(result,element,detail,n,ft,di) then + if ft and resolve(di,element,n,ft,di) then return true end end @@ -1602,29 +1565,29 @@ do end end - function extras.section(result,element,detail,n,fulltag,di) - local r = registered[detail] + function extras.section(di,element,n,fulltag,di) + local r = registered[specifications[fulltag].detail] if r then - result[#result+1] = f_level(r.level) + setattribute(di,"level",r.level) end - resolve(result,element,detail,n,fulltag,di) + resolve(di,element,n,fulltag,di) end extras.float = resolve -- todo: internal is already hashed - function structurestags.setlist(tag,n) + function structurestags.setlist(n) local data = structures.lists.getresult(n) if data then - referencehash[detailedtag("listitem",tag)] = data + referencehash[locatedtag("listitem")] = data end end - function extras.listitem(result,element,detail,n,fulltag,di) + function extras.listitem(di,element,n,fulltag,di) local data = referencehash[fulltag] if data then - extras.addinternal(result,data.references) + extras.addinternal(di,data.references) return true end end @@ -1635,17 +1598,17 @@ do -- todo: internal is already hashed - function structurestags.setregister(tag,n) + function structurestags.setregister(tag,n) -- check if tag is needed local data = structures.registers.get(tag,n) if data then - referencehash[detailedtag("registerlocation",tag)] = data + referencehash[locatedtag("registerlocation")] = data end end - function extras.registerlocation(result,element,detail,n,fulltag,di) + function extras.registerlocation(di,element,n,fulltag,di) local data = referencehash[fulltag] if data then - extras.addinternal(result,data.references) + extras.addinternal(di,data.references) return true end end @@ -1657,14 +1620,7 @@ end do - local tabledata = { } - - local f_columns = formatters[' columns="%s"'] - local f_rows = formatters[' rows="%s"'] - - local s_flushright = ' align="flushright"' - local s_middle = ' align="middle"' - local s_flushleft = ' align="flushleft"' + local tabledata = { } local function hascontent(data) for i=1,#data do @@ -1684,7 +1640,7 @@ do function structurestags.settablecell(rows,columns,align) if align > 0 or rows > 1 or columns > 1 then - tabledata[detailedtag("tablecell")] = { + tabledata[locatedtag("tablecell")] = { rows = rows, columns = columns, align = align, @@ -1692,26 +1648,26 @@ do end end - function extras.tablecell(result,element,detail,n,fulltag,di) + function extras.tablecell(di,element,n,fulltag,di) local hash = tabledata[fulltag] if hash then local columns = hash.columns if columns and columns > 1 then - result[#result+1] = f_columns(columns) + setattribute(di,"columns",columns) end local rows = hash.rows if rows and rows > 1 then - result[#result+1] = f_rows(rows) + setattribute(di,"rows",rows) end local align = hash.align if not align or align == 0 then -- normal elseif align == 1 then -- use numbertoalign here - result[#result+1] = s_flushright + setattribute(di,"align","flushright") elseif align == 2 then - result[#result+1] = s_middle + setattribute(di,"align","middle") elseif align == 3 then - result[#result+1] = s_flushleft + setattribute(di,"align","flushleft") end end end @@ -1720,13 +1676,13 @@ do function structurestags.settabulatecell(align) if align > 0 then - tabulatedata[detailedtag("tabulatecell")] = { + tabulatedata[locatedtag("tabulatecell")] = { align = align, } end end - function extras.tabulate(result,element,detail,n,fulltag,di) + function extras.tabulate(di,element,n,fulltag,di) local data = di.data for i=1,#data do local di = data[i] @@ -1736,18 +1692,18 @@ do end end - function extras.tabulatecell(result,element,detail,n,fulltag,di) + function extras.tabulatecell(di,element,n,fulltag,di) local hash = tabulatedata[fulltag] if hash then local align = hash.align if not align or align == 0 then -- normal elseif align == 1 then - result[#result+1] = s_flushleft + setattribute(di,"align","flushleft") elseif align == 2 then - result[#result+1] = s_flushright + setattribute(di,"align","flushright") elseif align == 3 then - result[#result+1] = s_middle + setattribute(di,"align","middle") end end end @@ -1759,6 +1715,7 @@ end do local f_detail = formatters[' detail="%s"'] + local f_chain = formatters[' chain="%s"'] local f_index = formatters[' n="%s"'] local f_spacing = formatters['<c n="%s">%s</c>'] @@ -1843,10 +1800,11 @@ do end local function begintag(result,element,nature,di,skip) - local detail = di.detail - local index = di.n - local fulltag = di.fulltag - local comment = di.comment + local index = di.n + local fulltag = di.fulltag + local specification = specifications[fulltag] + local comment = di.comment + local detail = specification.detail if skip == "comment" then if show_comment then if nature == "inline" or inline > 0 then @@ -1867,9 +1825,17 @@ do local n = 0 local r = { } -- delay this if detail then + detail = gsub(detail,"[^A-Za-z0-9]+","-") + specification.detail = detail -- we use it later in for the div n = n + 1 - -- r[n] = f_detail(detail) - r[n] = f_detail(gsub(detail,"[^A-Za-z0-9]+","-")) + r[n] = f_detail(detail) + end + local parents = specification.parents + if parents then + parents = gsub(parents,"[^A-Za-z0-9 ]+","-") + specification.parents = parents -- we use it later in for the div + n = n + 1 + r[n] = f_chain(parents) end if indexing and index then n = n + 1 @@ -1877,18 +1843,10 @@ do end local extra = extras[element] if extra then - extra(r,element,detail,index,fulltag,di) - n = #r - end - local u = userdata[fulltag] - if u then - for k, v in next, u do - n = n + 1 - r[n] = f_attribute(k,v) - end + extra(di,element,index,fulltag,di) end if exportproperties then - local p = userproperties[fulltag] + local p = specification.userdata if not p then -- skip elseif exportproperties == v_yes then @@ -1961,8 +1919,9 @@ do end end end - used[element][detail or ""] = nature -- for template css - local metadata = tagmetadata[fulltag] + used[element][detail or ""] = { nature, specification.parents } -- for template css + -- also in last else ? + local metadata = specification.metadata if metadata then result[#result+1] = f_metadata_begin(depth) for k, v in table.sortedpairs(metadata) do @@ -2247,27 +2206,26 @@ end -- collector code local function push(fulltag,depth) - -- local tag, n = lpegmatch(dashsplitter,fulltag) - -- local tg, detail = lpegmatch(colonsplitter,tag) - local tg, detail, n = lpegmatch(tagsplitter,fulltag) - local element, nature - if detail then - -- local pd = properties[tag] -- does this really happen? element-detail - local pd = properties[tg.."<"..detail] - local pt = properties[tg] - element = pd and pd.export or pt and pt.export or tg - nature = pd and pd.nature or pt and pt.nature or defaultnature + local tg, n, detail + local specification = specifications[fulltag] + if specification then + tg = specification.tagname + n = specification.tagindex + detail = specification.detail else - local p = properties[tg] - element = p and p.export or tg - nature = p and p.nature or "inline" + -- a break (more efficient if we don't store those in specifications) + tg, n = lpegmatch(tagsplitter,fulltag) + n = tonumber(n) -- to tonumber in tagsplitter end + local p = properties[tg] + local element = p and p.export or tg + local nature = p and p.nature or "inline" -- defaultnature local treedata = tree.data - local t = { + local t = { -- maybe we can use the tag table tg = tg, fulltag = fulltag, detail = detail, - n = tonumber(n), -- more efficient + n = n, -- already a number element = element, nature = nature, data = { }, @@ -2299,15 +2257,19 @@ local function push(fulltag,depth) end local function pop() - local top = nesting[currentdepth] - tree = treestack[currentdepth] - currentdepth = currentdepth - 1 - if trace_export then - if top then - report_export("%w</%s>",currentdepth,top) - else - report_export("</%s>",top) + if currentdepth > 0 then + local top = nesting[currentdepth] + tree = treestack[currentdepth] + currentdepth = currentdepth - 1 + if trace_export then + if top then + report_export("%w</%s>",currentdepth,top) + else + report_export("</%s>",top) + end end + else + report_export("%w<!-- too many pops -->",currentdepth) end end @@ -2322,58 +2284,65 @@ local function continueexport() end local function pushentry(current) - if current then - if restart then - continueexport() - restart = false - end - local newdepth = #current - local olddepth = currentdepth - if trace_export then - report_export("%w<!-- moving from depth %s to %s (%s) -->",currentdepth,olddepth,newdepth,current[newdepth]) + if not current then + -- bad news + return + end + current = current.taglist + if not current then + -- even worse news + return + end + if restart then + continueexport() + restart = false + end + local newdepth = #current + local olddepth = currentdepth + if trace_export then + report_export("%w<!-- moving from depth %s to %s (%s) -->",currentdepth,olddepth,newdepth,current[newdepth]) + end + if olddepth <= 0 then + for i=1,newdepth do + push(current[i],i) end - if olddepth <= 0 then - for i=1,newdepth do - push(current[i],i) + else + local difference + if olddepth < newdepth then + for i=1,olddepth do + if current[i] ~= nesting[i] then + difference = i + break + end end else - local difference - if olddepth < newdepth then - for i=1,olddepth do - if current[i] ~= nesting[i] then - difference = i - break - end - end - else - for i=1,newdepth do - if current[i] ~= nesting[i] then - difference = i - break - end + for i=1,newdepth do + if current[i] ~= nesting[i] then + difference = i + break end end - if difference then - for i=olddepth,difference,-1 do - pop() - end - for i=difference,newdepth do - push(current[i],i) - end - elseif newdepth > olddepth then - for i=olddepth+1,newdepth do - push(current[i],i) - end - elseif newdepth < olddepth then - for i=olddepth,newdepth,-1 do - pop() - end - elseif trace_export then - report_export("%w<!-- staying at depth %s (%s) -->",currentdepth,newdepth,nesting[newdepth] or "?") + end + if difference then + for i=olddepth,difference,-1 do + pop() end + for i=difference,newdepth do + push(current[i],i) + end + elseif newdepth > olddepth then + for i=olddepth+1,newdepth do + push(current[i],i) + end + elseif newdepth < olddepth then + for i=olddepth,newdepth,-1 do + pop() + end + elseif trace_export then + report_export("%w<!-- staying at depth %s (%s) -->",currentdepth,newdepth,nesting[newdepth] or "?") end - return olddepth, newdepth end + return olddepth, newdepth end local function pushcontent(oldparagraph,newparagraph) @@ -2397,17 +2366,19 @@ local function pushcontent(oldparagraph,newparagraph) if list then olddepth, newdepth = pushentry(list) end - local td = tree.data - local nd = #td - td[nd+1] = { parnumber = oldparagraph or currentparagraph, content = content } - if trace_export then - report_export("%w<!-- start content with length %s -->",currentdepth,#content) - report_export("%w%s",currentdepth,(gsub(content,"\n","\\n"))) - report_export("%w<!-- stop content -->",currentdepth) - end - if olddepth then - for i=newdepth-1,olddepth,-1 do - pop() + if tree then + local td = tree.data + local nd = #td + td[nd+1] = { parnumber = oldparagraph or currentparagraph, content = content } + if trace_export then + report_export("%w<!-- start content with length %s -->",currentdepth,#content) + report_export("%w%s",currentdepth,(gsub(content,"\n","\\n"))) + report_export("%w<!-- stop content -->",currentdepth) + end + if olddepth then + for i=newdepth-1,olddepth,-1 do + pop() + end end end end @@ -2798,28 +2769,38 @@ end do local xmlpreamble = [[ -<?xml version="1.0" encoding="UTF-8" standalone="%s" ?> +<?xml version="1.0" encoding="UTF-8" standalone="%standalone%" ?> -<!-- input filename : %- 17s --> -<!-- processing date : %- 17s --> -<!-- context version : %- 17s --> -<!-- exporter version : %- 17s --> +<!-- + input filename : %filename% + processing date : %date% + context version : %contextversion% + exporter version : %exportversion% + +--> ]] local flushtree = wrapups.flushtree local function wholepreamble(standalone) - return format(xmlpreamble,standalone and "yes" or "no",tex.jobname,os.date(),environment.version,exportversion) + return replacetemplate(xmlpreamble, { + standalone = standalone and "yes" or "no", + filename = tex.jobname, + date = os.date(), + contextversion = environment.version, + exportversion = exportversion, + }) end -local f_csspreamble = formatters [ [[ -<?xml-stylesheet type="text/css" href="%s"?> -]] ] -local f_cssheadlink = formatters [ [[ -<link type="text/css" rel="stylesheet" href="%s"/> -]] ] +local csspreamble = [[ +<?xml-stylesheet type="text/css" href="%filename%" ?> +]] + +local cssheadlink = [[ +<link type="text/css" rel="stylesheet" href="%filename%" /> +]] local function allusedstylesheets(cssfiles,files,path) local done = { } @@ -2835,31 +2816,28 @@ local f_cssheadlink = formatters [ [[ cssfile = file.join(path,cssfile) report_export("adding css reference '%s'",cssfile) files[#files+1] = cssfile - result[#result+1] = f_csspreamble(cssfile) - extras[#extras+1] = f_cssheadlink(cssfile) + result[#result+1] = replacetemplate(csspreamble, { filename = cssfile }) + extras[#extras+1] = replacetemplate(cssheadlink, { filename = cssfile }) done[cssfile] = true end end return concat(result), concat(extras) end -local f_e_template = [[ +local elementtemplate = [[ +/* element="%element%" detail="%detail%" chain="%chain%" */ + %element%, div.%element% { display: %display% ; }]] -local f_d_template = [[ -%element%[detail=%detail%], div.%element%.detail-%detail% { +local detailtemplate = [[ +/* element="%element%" detail="%detail%" chain="%chain%" */ + +%element%[detail=%detail%], div.%element%.%detail% { display: %display% ; }]] --- local f_d_template = [[ --- %element%.%detail%, div.%element%.%detail% { --- display: %display% ; --- }]] - -local f_category = formatters["/* category: %s */"] - -- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd" > local htmltemplate = [[ @@ -2898,19 +2876,22 @@ local htmltemplate = [[ if namespaces[element] then -- skip math else - result[#result+1] = f_category(element) - for detail, nature in sortedhash(details) do - local display = displaymapping[nature or "display"] or "block" + for detail, what in sortedhash(details) do + local nature = what[1] or "display" + local chain = what[2] + local display = displaymapping[nature] or "block" if detail == "" then - result[#result+1] = replacetemplate(f_e_template, { + result[#result+1] = replacetemplate(elementtemplate, { element = element, display = display, + chain = chain, }) else - result[#result+1] = replacetemplate(f_d_template, { + result[#result+1] = replacetemplate(detailtemplate, { element = element, - detail = detail, display = display, + detail = detail, + chain = chain, }) end end @@ -3033,6 +3014,40 @@ local htmltemplate = [[ local p_cleanid = lpeg.replacer { [":"] = "-" } local p_cleanhref = lpeg.Cs(lpeg.P("#") * p_cleanid) + local p_splitter = lpeg.Ct ( ( + lpeg.Carg(1) * lpeg.C((1-lpeg.P(" "))^1) / function(d,s) if not d[s] then d[s] = true return s end end + * lpeg.P(" ")^0 )^1 ) + + + local classes = table.setmetatableindex(function(t,k) + local v = concat(lpegmatch(p_splitter,k,1,{})," ") + t[k] = v + return v + end) + + local function makeclass(tg,at) + local detail = at.detail + local chain = at.chain + at.detail = nil + at.chain = nil + if detail and detail ~= "" then + if chain and chain ~= "" then + if chain ~= detail then + return classes[tg .. " " .. chain .. " " .. detail] -- we need to remove duplicates + elseif tg ~= detail then + return tg .. " " .. detail + end + elseif tg ~= detail then + return tg .. " " .. detail + end + elseif chain and chain ~= "" then + if tg ~= chain then + return tg .. " " .. chain + end + end + return tg + end + local function remap(specification,source,target) local comment = nil -- share comments for c in xml.collected(source,"*") do @@ -3059,20 +3074,17 @@ local htmltemplate = [[ end end -- end - local at = c.at - local class = { tg } - if tg ~= "document" then - for k, v in next, at do - if not private[k] then - class[#class+1] = k .. "-" .. v - end - end + local at = c.at + local class = nil + if tg == "document" then + at.href = nil + at.detail = nil + at.chain = nil else - at.href = nil + class = makeclass(tg,at) end local id = at.id local href = at.href - local class = concat(class," ") if id then id = lpegmatch(p_cleanid, id) or id if href then @@ -3111,7 +3123,11 @@ local htmltemplate = [[ -- local cssfile = nil directives.register("backend.export.css", function(v) cssfile = v end) + local addsuffix = file.addsuffix + local joinfile = file.join + local function stopexport(v) + starttiming(treehash) -- finishexport() @@ -3150,8 +3166,8 @@ local htmltemplate = [[ local basename = file.basename(v) local corename = file.removesuffix(basename) local basepath = basename .. "-export" - local imagepath = file.join(basepath,"images") - local stylepath = file.join(basepath,"styles") + local imagepath = joinfile(basepath,"images") + local stylepath = joinfile(basepath,"styles") local function validpath(what,pathname) if lfs.isdir(pathname) then @@ -3174,25 +3190,25 @@ local htmltemplate = [[ -- we're now on the dedicated export subpath so we can't clash names - local xmlfilebase = file.addsuffix(basename .. "-raw","xml" ) - local xhtmlfilebase = file.addsuffix(basename .. "-tag","xhtml") - local htmlfilebase = file.addsuffix(basename .. "-div","xhtml") - local specificationfilebase = file.addsuffix(basename .. "-pub","lua" ) + local xmlfilebase = addsuffix(basename .. "-raw","xml" ) + local xhtmlfilebase = addsuffix(basename .. "-tag","xhtml") + local htmlfilebase = addsuffix(basename .. "-div","xhtml") + local specificationfilebase = addsuffix(basename .. "-pub","lua" ) - local xmlfilename = file.join(basepath, xmlfilebase ) - local xhtmlfilename = file.join(basepath, xhtmlfilebase ) - local htmlfilename = file.join(basepath, htmlfilebase ) - local specificationfilename = file.join(basepath, specificationfilebase) + local xmlfilename = joinfile(basepath, xmlfilebase ) + local xhtmlfilename = joinfile(basepath, xhtmlfilebase ) + local htmlfilename = joinfile(basepath, htmlfilebase ) + local specificationfilename = joinfile(basepath, specificationfilebase) -- - local defaultfilebase = file.addsuffix(basename .. "-defaults", "css") - local imagefilebase = file.addsuffix(basename .. "-images", "css") - local stylefilebase = file.addsuffix(basename .. "-styles", "css") - local templatefilebase = file.addsuffix(basename .. "-templates","css") + local defaultfilebase = addsuffix(basename .. "-defaults", "css") + local imagefilebase = addsuffix(basename .. "-images", "css") + local stylefilebase = addsuffix(basename .. "-styles", "css") + local templatefilebase = addsuffix(basename .. "-templates","css") -- - local defaultfilename = file.join(stylepath,defaultfilebase ) - local imagefilename = file.join(stylepath,imagefilebase ) - local stylefilename = file.join(stylepath,stylefilebase ) - local templatefilename = file.join(stylepath,templatefilebase) + local defaultfilename = joinfile(stylepath,defaultfilebase ) + local imagefilename = joinfile(stylepath,imagefilebase ) + local stylefilename = joinfile(stylepath,stylefilebase ) + local templatefilename = joinfile(stylepath,templatefilebase) local cssfile = finetuning.cssfile @@ -3218,11 +3234,11 @@ local htmltemplate = [[ if cssfile then local list = table.unique(settings_to_array(cssfile)) for i=1,#list do - local source = file.addsuffix(list[i],"css") - local target = file.join(stylepath,file.basename(source)) + local source = addsuffix(list[i],"css") + local target = joinfile(stylepath,file.basename(source)) cssfiles[#cssfiles+1] = source if not lfs.isfile(source) then - source = file.join("../",source) + source = joinfile("../",source) end if lfs.isfile(source) then report_export("copying %s",source) @@ -3281,7 +3297,7 @@ local htmltemplate = [[ name = file.removesuffix(v), identifier = os.uuid(), images = wrapups.uniqueusedimages(), - imagefile = file.join("styles",imagefilebase), + imagefile = joinfile("styles",imagefilebase), imagepath = "images", stylepath = "styles", xmlfiles = { xmlfilebase }, @@ -3357,7 +3373,7 @@ local htmltemplate = [[ statistics.register("xml exporting time", function() if exporting then - return format("%s seconds, version %s", statistics.elapsedtime(treehash),exportversion) + return string.format("%s seconds, version %s", statistics.elapsedtime(treehash),exportversion) end end) diff --git a/tex/context/base/back-exp.mkiv b/tex/context/base/back-exp.mkiv index e8b9ef61a..bbf564517 100644 --- a/tex/context/base/back-exp.mkiv +++ b/tex/context/base/back-exp.mkiv @@ -94,11 +94,15 @@ % \to \everyenableelements \appendtoks - \unexpanded\def\dotagsynonym{\taggedctxcommand{settagsynonym("\currentsynonym","\currentsynonymtag")}}% + \unexpanded\def\dotagsynonym{\taggedctxcommand{settagsynonym("\currentsynonymtag")}}% +\to \everyenableelements + +\appendtoks + \unexpanded\def\dotagsorting{\taggedctxcommand{settagsorting("\currentsortingtag")}}% \to \everyenableelements \appendtoks % frozen and assumed global per highlight class - \unexpanded\def\dotaghighlight{\taggedctxcommand{settaghighlight("\currenthighlight",\!!bs\highlightparameter\c!style\!!es,\number\attribute\colorattribute)}}% + \unexpanded\def\dotaghighlight{\taggedctxcommand{settaghighlight(\!!bs\highlightparameter\c!style\!!es,\number\attribute\colorattribute)}}% \to \everyenableelements \appendtoks % we can have differently scaled images @@ -111,16 +115,12 @@ \to \everyenableelements \appendtoks - \unexpanded\def\dotagsorting{\taggedctxcommand{settagsorting("\currentsorting","\currentsortingtag")}}% -\to \everyenableelements - -\appendtoks \unexpanded\def\dotagsetparcounter{\global\advance\tagparcounter\plusone\attribute\taggedparattribute\tagparcounter}% \unexpanded\def\doresetparcounter {\attribute\taggedparattribute\attributeunsetvalue}% \to \everyenableelements \appendtoks - \unexpanded\def\dotagsetitemgroup{\taggedctxcommand{settagitemgroup("\currentitemgroup",\ifconditional\c_strc_itemgroups_pack true\else false\fi,"\currentitemgroupsymbol")}}% + \unexpanded\def\dotagsetitemgroup{\taggedctxcommand{settagitemgroup(\ifconditional\c_strc_itemgroups_pack true\else false\fi,"\currentitemgroupsymbol")}}% \to \everyenableelements \appendtoks @@ -136,7 +136,7 @@ \to \everyenableelements \appendtoks - \unexpanded\def\dotaglistlocation{\taggedctxcommand{settaglist("\currentlist",\currentlistindex)}}% + \unexpanded\def\dotaglistlocation{\taggedctxcommand{settaglist(\currentlistindex)}}% \to \everyenableelements \appendtoks diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv index c47a75856..4da74d421 100644 --- a/tex/context/base/buff-ver.mkiv +++ b/tex/context/base/buff-ver.mkiv @@ -325,7 +325,7 @@ \def\buff_verbatim_type_normal#1% {\buff_verbatim_initialize_type_two - \dostarttagged\t!verbatim\currenttype + \dostarttaggedchained\t!verbatim\currenttype\??type \ctxcommand{typestring{ data = \!!bs\detokenize{#1}\!!es, tab = "\typeparameter\c!tab", @@ -339,7 +339,7 @@ \def\buff_verbatim_type_nested#1% {\buff_verbatim_initialize_type_two - \dostarttagged\t!verbatim\currenttype + \dostarttaggedchained\t!verbatim\currenttype\??type \ctxcommand{typestring{ data = \!!bs\detokenize{#1}\!!es, tab = "\typeparameter\c!tab", @@ -499,7 +499,7 @@ \def\buff_verbatim_type_block_verbatim_indeed#1#2% {\buff_verbatim_initialize_typing_two - \dostarttagged\t!verbatimblock\currenttyping + \dostarttaggedchained\t!verbatimblock\currenttyping\??typing \beginofverbatimlines \dostarttagged\t!verbatimlines\empty \ctxcommand{typebuffer { @@ -618,7 +618,7 @@ \buff_verbatim_setup_line_numbering \buff_verbatim_initialize_typing_one \buff_verbatim_initialize_typing_two - \dostarttagged\t!verbatimblock\currenttyping + \dostarttaggedchained\t!verbatimblock\currenttyping\??typing \beginofverbatimlines \dostarttagged\t!verbatimlines\empty \ctxcommand{typefile { @@ -791,7 +791,7 @@ \buff_verbatim_setup_line_numbering \buff_verbatim_initialize_typing_one \buff_verbatim_initialize_typing_two - \dostarttagged\t!verbatimblock{#1}% + \dostarttaggedchained\t!verbatimblock{#1}\??typing \beginofverbatimlines \dostarttagged\t!verbatimlines\empty \ctxcommand{typebuffer { diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 765db89ef..d54ba6c3f 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2014.10.22 16:23} +\newcontextversion{2014.10.27 09:27} %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 Binary files differindex 931034d50..4080c15b4 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 2b5595c11..bdb1e8c07 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -28,7 +28,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2014.10.22 16:23} +\edef\contextversion{2014.10.27 09:27} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/export-example.css b/tex/context/base/export-example.css index 36c308c17..cbe4ccf4e 100644 --- a/tex/context/base/export-example.css +++ b/tex/context/base/export-example.css @@ -9,8 +9,24 @@ /* - Because empty div elements are not seen we put a comment in them - so that empty table cells etc work ok. + Because empty div elements are not seen we put a comment in them so that empty + table cells etc work ok. + + We can style individual elements in several ways and we support in this css file + meaningful elements as well as divs. If needed you can use the chain field as well + as chain elements in the div class for styling groups. + + \definefloat[myfloata] + \definefloat[myfloatb][myfloatbs][figure] + + div.float.myfloata { } float[detail='myfloata'] { } + div.float.myfloatb { } float[detail='myfloatb'] { } + div.float.figure { } float[detail='figure'] { } + div.float.figure.myfloatb { } float[chain~='figure'][detail='myfloata'] { } + div.myfloata { } *[detail='myfloata'] { } + div.myfloatb { } *[detail='myfloatb'] { } + div.figure { } *[chain~='figure'] { } + div.figure.myfloatb { } *[chain~='figure'][detail='myfloatb'] { } */ @@ -45,6 +61,7 @@ document:before, div.document:before { document, div.document { font-family : "DejaVu Serif", "Lucida Bright", serif ; font-size : 12pt ; + line-height : 14.4pt; max-width : 50em ; padding : 1em ; /* text-align : justify ; */ @@ -100,7 +117,7 @@ break, div.break { construct, div.construct { } -construct[detail="important"], div.construct.detail-important { +construct[detail="important"], div.construct.important { font-weight : bold ; } @@ -123,7 +140,7 @@ sectioncontent, div.sectioncontent { } section[detail="chapter"], section[detail="title"], - div.section.detail-chapter, div.section.detail-title { + div.section.chapter, div.section.title { page-break-before : always ; page-break-after : avoid ; margin-top : 3em ; @@ -131,34 +148,34 @@ section[detail="chapter"], section[detail="title"], } section[detail="section"], section[detail="subject"], - div.section.detail-section, div.section.detail-subject { + div.section.section, div.section.subject { page-break-after : avoid ; margin-top : 2.5em ; margin-bottom : 2.5em ; } section[detail="subsection"], section[detail="subsubject"], - div.section.detail-subsection, div.section.detail-subsubject { + div.section.subsection, div.section.subsubject { page-break-after : avoid ; margin-top : 2em ; margin-bottom : 2em ; } section[detail="subsubsection"], section[detail="subsubsubject"], - div.section.detail-subsubsection, div.section.detail-subsubsubject { + div.section.subsubsection, div.section.subsubsubject { page-break-after : avoid ; margin-top : 1em ; margin-bottom : 0em ; } section[detail="summary"], section[detail="subsummary"], - div.section.detail-summary, div.section.detail-subsummary { + div.section.summary, div.section.subsummary { margin-top : 1em ; margin-bottom : 1em ; } section[detail="chapter"]>sectionnumber, - div.section.detail-chapter div.sectionnumber { + div.section.chapter div.sectionnumber { display : inline-block ; margin-right : 1em ; font-size : 3em ; @@ -166,41 +183,41 @@ section[detail="chapter"]>sectionnumber, } section[detail="chapter"]>sectiontitle, section[detail="title"]>sectiontitle, - div.section.detail-chapter div.sectiontitle, div.section.detail-title div.sectiontitle { + div.section.chapter div.sectiontitle, div.section.title div.sectiontitle { display : inline-block ; font-size : 3em ; font-weight : bold ; } section[detail="section"]>sectiontitle, section[detail="subject"]>sectiontitle, - div.section.detail-section div.sectiontitle, div.section.detail-subject div.sectiontitle { + div.section.section div.sectiontitle, div.section.subject div.sectiontitle { display : inline-block ; font-size : 2.5em ; font-weight : bold ; } section[detail="subsection"]>sectiontitle, section[detail="subsubject"]>sectiontitle, - div.section.detail-subsection div.sectiontitle, div.section.detail-subsubject div.sectiontitle { + div.section.subsection div.sectiontitle, div.section.subsubject div.sectiontitle { display : inline-block ; font-size : 2em ; font-weight : bold ; } section[detail="subsubsection"]>sectiontitle, section[detail="subsubsubject"]>sectiontitle, - div.section.detail-subsubsection div.sectiontitle, div.section.detail-subsubsubject div.sectiontitle { + div.section.subsubsection div.sectiontitle, div.section.subsubsubject div.sectiontitle { display : inline-block ; font-size : 1em ; font-weight : bold ; } -section[detail="section"]>sectionnumber, div.section.detail-section div.sectionnumber { +section[detail="section"]>sectionnumber, div.section.section div.sectionnumber { display : inline-block ; margin-right : 1em ; font-size : 2.5em ; font-weight : bold ; } -section[detail="summary"]>sectiontitle, div.section.detail-summary div.sectiontitle { +section[detail="summary"]>sectiontitle, div.section.summary div.sectiontitle { display : block ; margin-top : 1em ; margin-bottom : 1em ; @@ -210,14 +227,14 @@ section[detail="summary"]>sectiontitle, div.section.detail-summary div.sectionti border-width : .15em; } -section[detail="subsection"]>sectionnumber, div.section.detail-subsection div.sectionnumber { +section[detail="subsection"]>sectionnumber, div.section.subsection div.sectionnumber { display : inline-block ; margin-right : 1em ; font-size : 1em ; font-weight : bold ; } -section[detail="subsummary"]>sectiontitle, div.section.detail-subsummary div.sectiontitle { +section[detail="subsummary"]>sectiontitle, div.section.subsummary div.sectiontitle { display : block ; margin-top : 1em ; margin-bottom : 1em ; @@ -508,17 +525,17 @@ list, div.list { display : block ; } -listitem[detail="chapter"], div.listitem.detail-chapter { +listitem[detail="chapter"], div.listitem.chapter { display : block ; margin-top : 1em ; font-weight : bold ; } -listitem[detail="section"], div.listitem.detail-section { +listitem[detail="section"], div.listitem.section { display : block ; } -listitem[detail="subsection"], div.listitem.detail-subsection { +listitem[detail="subsection"], div.listitem.subsection { display : block ; display : inline-block ; } @@ -547,25 +564,25 @@ listpage, div.listpage { /* :lang(en) */ delimited[detail="quotation"]:before, delimitedblock[detail="quotation"]:before, - div.delimited.detail-quotation:before, div.delimitedblock.detail-quotation:before { + div.delimited.quotation:before, div.delimitedblock.quotation:before { /* content : "\201C" ; */ font-style : italic ; } delimited[detail="quotation"]:after, delimitedblock[detail="quotation"]:after, - div.delimited.detail-quotation:after, div.delimitedblock.detail-quotation:after { + div.delimited.quotation:after, div.delimitedblock.quotation:after { /* content : "\201D" ; */ font-style : italic ; } delimited[detail="quote"]:before, delimitedblock[detail="quote"]:before, - div.delimited.detail-quote:before, div.delimitedblock.detail-quote:before { + div.delimited.quote:before, div.delimitedblock.quote:before { /* content : "\2018" ; */ font-style : italic ; } delimited[detail="quote"]:after, delimitedblock[detail="quote"]:after, - div.delimited.detail-quote:after, div.delimitedblock.detail-quote:after { + div.delimited.quote:after, div.delimitedblock.quote:after { /* content : "\2019" ; */ font-style : italic ; } diff --git a/tex/context/base/lang-lab.mkiv b/tex/context/base/lang-lab.mkiv index 7dcaaecb4..27d35776d 100644 --- a/tex/context/base/lang-lab.mkiv +++ b/tex/context/base/lang-lab.mkiv @@ -84,6 +84,7 @@ \unexpanded\def\lang_labels_define_class_indeed#1#2#3#4#5#6#7#8#9% {\setuvalue{setup#1text}{\protecttextprefixes#2\def\currenttextprefixclass{#1}\dodoubleempty\lang_labels_text_prefix_setup}% \setuvalue{preset#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dodoubleempty\lang_labels_text_prefix_setup}% + \setuvalue{copy#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dodoubleempty\lang_labels_text_prefix_copy}% \setuvalue{start#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dotripleempty\lang_labels_text_prefix_start[#1]}% \letvalue{stop#1text}\relax \def#4{\reallanguagetag{\defaultlanguage\currentmainlanguage}}% @@ -238,6 +239,26 @@ \unexpanded\def\setlabeltextpair#1#2#3#4#5% a fast one for usage at the Lua end {\expandafter\def\csname\??label#1:\reallanguagetag{#2}:#3\endcsname{{#4}{#5}}} % class tag key left right +\def\lang_labels_text_prefix_copy[#1][#2]% + {\ifsecondargument + \edef\currenttextprefixtag{\reallanguagetag{#1}}% + \processcommalist[#2]\lang_labels_text_prefix_copy_indeed + \else + \edef\currenttextprefixtag{\reallanguagetag\currentmainlanguage}% + \processcommalist[#1]\lang_labels_text_prefix_copy_indeed + \fi} + +\def\lang_labels_text_prefix_copy_indeed#1% + {\lang_labels_text_prefix_copy_pair[#1]} + +\def\lang_labels_text_prefix_copy_pair[#1=#2]% + {\lang_labels_text_prefix_copy_pair_indeed{#1}[#2,,]} + +\def\lang_labels_text_prefix_copy_pair_indeed#1[#2,#3]% + {\expandafter\let + \csname\??label\currenttextprefixclass:\currenttextprefixtag:#1\expandafter\endcsname + \csname\??label\currenttextprefixclass:\currenttextprefixtag:#2\endcsname} + \definelabelclass [head] [0] % titles \definelabelclass [label] [0] % texts \definelabelclass [mathlabel] [0] % functions diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua index 678a57edd..904d5b196 100644 --- a/tex/context/base/lpdf-tag.lua +++ b/tex/context/base/lpdf-tag.lua @@ -83,16 +83,14 @@ local names = pdfarray() local structurestags = structures.tags local taglist = structurestags.taglist +local specifications = structurestags.specifications local usedlabels = structurestags.labels local properties = structurestags.properties -local userdata = structurestags.userdata local lasttaginchain = structurestags.lastinchain local usedmapping = { } -local tagsplitter = structurestags.patterns.splitter ------ colonsplitter = lpeg.splitat(":") ------ dashsplitter = lpeg.splitat("-") +-- local tagsplitter = structurestags.patterns.splitter local add_ids = false -- true @@ -173,7 +171,6 @@ end -- here we can flush and free elements that are finished -local userproperties = structurestags.userproperties local pdf_userproperties = pdfconstant("UserProperties") local function makeattribute(t) @@ -192,26 +189,27 @@ local function makeattribute(t) end end -local function makeelement(fulltag,parent,attr) - local tg, detail, n = lpegmatch(tagsplitter,fulltag) - -- local tag, n = lpegmatch(dashsplitter,fulltag) - -- local tg, detail = lpegmatch(colonsplitter,tag) - if tg == "ignore" then +local function makeelement(fulltag,parent) + local specification = specifications[fulltag] + local tag = specification.tagname + if tag == "ignore" then return false - elseif tg == "mstackertop" or tg == "mstackerbot" or tg == "mstackermid"then + elseif tag == "mstackertop" or tag == "mstackerbot" or tag == "mstackermid"then + -- TODO return true - elseif tg == "mstacker" then - local p = properties[fulltag] - tg = p and p.subtype or tg end + -- + local detail = specification.detail + local userdata = specification.userdata + -- + usedmapping[tag] = true + -- local k = pdfarray() local r = pdfreserveobject() - local a = userproperties[fulltag] - usedmapping[tg] = true - tg = usedlabels[tg] or tg + local t = usedlabels[tag] or tag local d = pdfdictionary { Type = pdf_struct_element, - S = pdfconstant(tg), + S = pdfconstant(t), ID = (add_ids and fulltag) or nil, T = detail and detail or nil, P = parent.pref, @@ -228,8 +226,7 @@ local function makeelement(fulltag,parent,attr) end local kids = parent.kids kids[#kids+1] = s --- local e = { tag = tag, pref = s, kids = k, knum = r, pnum = pagenum } - local e = { tag = detail and (tg .. "<" .. detail) or tg, pref = s, kids = k, knum = r, pnum = pagenum } + local e = { tag = t, pref = s, kids = k, knum = r, pnum = pagenum } elements[fulltag] = e return e end @@ -345,12 +342,13 @@ function nodeinjections.addtags(head) for i=1,#ranges do local range = ranges[i] local attr, id, start, stop, list = range[1], range[2], range[3], range[4], range[5] - local tags = taglist[attr] + local specification = taglist[attr] + local list = specification.taglist local prev = root - local noftags, tag = #tags, nil + local noftags, tag = #list, nil for j=1,noftags do - local tag = tags[j] - local prv = elements[tag] or makeelement(tag,prev,attr) + local tag = list[j] + local prv = elements[tag] or makeelement(tag,prev) if prv == false then -- ignore this one prev = false diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua index 6bdebeb42..9f73d0afc 100644 --- a/tex/context/base/math-tag.lua +++ b/tex/context/base/math-tag.lua @@ -146,13 +146,8 @@ end local actionstack = { } local fencesstack = { } -local P, S, C, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.match -local splittag = C(P(1-S(":-"))^1) * (P(":") * C((1-P("-"))^1) + Cc("")) - -- glyph nodes and such can happen in under and over stuff -local detail_accent = { detail = "accent" } - local function getunicode(n) -- instead of getchar local char = getchar(n) local font = font_of_family(getfield(n,"fam")) -- font_of_family @@ -193,11 +188,6 @@ process = function(start) -- we cannot use the processor as we have no finalizer end if id == math_char_code then local char = getchar(start) - -- check for code - local a = getattr(start,a_mathcategory) - if a then - a = { detail = a } - end local code = getmathcode(char) if code then code = code[1] @@ -216,14 +206,19 @@ process = function(start) -- we cannot use the processor as we have no finalizer else tag = "mo" end - setattr(start,a_tagged,start_tagged(tag,a)) + local a = getattr(start,a_mathcategory) + if a then + setattr(start,a_tagged,start_tagged(tag,{ mathcategory = a })) + else + setattr(start,a_tagged,start_tagged(tag)) -- todo: a_mathcategory + end stop_tagged() break -- okay? elseif id == math_textchar_code then -- or id == glyph_code -- check for code local a = getattr(start,a_mathcategory) if a then - setattr(start,a_tagged,start_tagged("ms",{ detail = a })) -- mtext + setattr(start,a_tagged,start_tagged("ms",{ mathcategory = a })) -- mtext else setattr(start,a_tagged,start_tagged("ms")) -- mtext end @@ -241,12 +236,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer elseif id == math_box_code or id == hlist_code or id == vlist_code then -- keep an eye on math_box_code and see what ends up in there local attr = getattr(start,a_tagged) - local last = attr and taglist[attr] - local tag, detail - if last then - local fulltag = last[#last] - tag, detail = lpegmatch(splittag,fulltag) - end + local specification = taglist[attr] + local tag = specification.tagname if tag == "formulacaption" then -- skip elseif tag == "mstacker" then @@ -274,7 +265,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer -- -- todo: have a local list with local tags that then get appended -- - local tagdata = taglist[attr] or { } + local tagdata = specification.taglist local common = #tagdata + 1 local function runner(list,depth) -- quite inefficient local cache = { } -- we can have nested unboxed mess so best local to runner @@ -293,7 +284,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer if aa then local ac = cache[aa] if not ac then - local tagdata = taglist[aa] + local tagdata = taglist[aa].taglist local extra = #tagdata if common <= extra then for i=common,extra do @@ -339,8 +330,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer local attr = getattr(start,a_tagged) local last = attr and taglist[attr] if last then - local fulltag = last[#last] - local tag, detail = lpegmatch(splittag,fulltag) + local tag = last.tag + local detail = last.detail if tag == "maction" then if detail == "" then setattr(start,a_tagged,start_tagged("mrow")) @@ -416,7 +407,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer -- left local properties = { } insert(fencesstack,properties) - setattr(start,a_tagged,start_tagged("mfenced",nil,properties)) -- needs checking + setattr(start,a_tagged,start_tagged("mfenced",{ properties = properties })) -- needs checking if delim then start_tagged("ignore") local chr = getfield(delim,"small_char") @@ -490,7 +481,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer local subtype = getsubtype(start) if bot_accent then if accent then - setattr(start,a_tagged,start_tagged("munderover", detail_accent, { + setattr(start,a_tagged,start_tagged("munderover", { + accent = true, top = getunicode(accent), bottom = getunicode(bot_accent), topfixed = subtype == math_fixed_top or subtype == math_fixed_both, @@ -501,7 +493,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer process(accent) stop_tagged() else - setattr(start,a_tagged,start_tagged("munder", detail_accent, { + setattr(start,a_tagged,start_tagged("munder", { + accent = true, bottom = getunicode(bot_accent), bottomfixed = subtype == math_fixed_bottom or subtype == math_fixed_both, })) @@ -510,7 +503,8 @@ process = function(start) -- we cannot use the processor as we have no finalizer stop_tagged() end elseif accent then - setattr(start,a_tagged,start_tagged("mover", detail_accent, { + setattr(start,a_tagged,start_tagged("mover", { + accent = true, top = getunicode(accent), topfixed = subtype == math_fixed_top or subtype == math_fixed_both, })) @@ -522,7 +516,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer end elseif id == glue_code then -- local spec = getfield(start,"spec") - -- setattr(start,a_tagged,start_tagged("mspace",nil,spec and { width = getfield(spec,"width") })) + -- setattr(start,a_tagged,start_tagged("mspace",{ width = getfield(spec,"width") })) setattr(start,a_tagged,start_tagged("mspace")) stop_tagged() else @@ -539,12 +533,9 @@ end function noads.handlers.tags(head,style,penalties) head = tonut(head) - local v_math = start_tagged("math") - local v_mrow = start_tagged("mrow") local v_mode = getattr(head,a_mathmode) - -- setattr(head,a_tagged,v_math) - setattr(head,a_tagged,v_mrow) - tags.setattributehash(v_math,"mode",v_mode == 1 and "display" or "inline") + local v_math = start_tagged("math", { mode = v_mode == 1 and "display" or "inline" }) + setattr(head,a_tagged,start_tagged("mrow")) process(head) stop_tagged() stop_tagged() diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv index 748a552ee..11414f38b 100644 --- a/tex/context/base/mult-aux.mkiv +++ b/tex/context/base/mult-aux.mkiv @@ -339,6 +339,11 @@ \expandafter\edef\csname#1#4:\s!parent\endcsname{#2}% \fi \fi} +\def\mult_interfaces_chain#1#2{\ifcsname#1#2:\s!chain\endcsname\csname#1#2:\s!chain\endcsname\space\fi} +\def\getparentchain #1#2{\ifcsname#1#2:\s!chain\endcsname\csname#1#2:\s!chain\endcsname\fi} +\def\getcurrentparentchain#1#2{\csname#1#2:\s!chain\endcsname} % for the moment test: +\def\getcurrentparentchain#1#2{\ifcsname#1#2:\s!chain\endcsname\csname#1#2:\s!chain\endcsname\fi} + \unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones {\ifx#4\relax\let#4\empty\fi % see \defineregister \unexpanded\def#2{\dotripleempty#5}% @@ -351,6 +356,7 @@ \the#6% predefine \edef#8{##2}% \mult_check_for_parent{#1}{#3}#4#8% + \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% \mult_interfaces_get_parameters{#1#4:}[##3]% \else\ifsecondargument @@ -358,16 +364,19 @@ \expandafter\mult_check_for_assignment_indeed\detokenize{##2}=@@\_end_ \ifassignment \let#8\empty + \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% \mult_interfaces_get_parameters{#1#4:}[##2]% \else \edef#8{##2}% \mult_check_for_parent{#1}{#3}#4#8% + \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% \fi \else \the#6% predefine \let#8\empty + \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% \fi\fi \the#7% diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv index 4693513b0..7bd692fea 100644 --- a/tex/context/base/mult-def.mkiv +++ b/tex/context/base/mult-def.mkiv @@ -32,7 +32,7 @@ \ctxlua{interfaces.setuserinterface("\userinterfacetag","\userresponsestag")} -% start todo: +% start todo in muld-def.lua: \def\c!svgstyle {svgstyle} @@ -76,6 +76,7 @@ \def\c!properties {properties} \def\c!journalconversion {journalconversion} \def\c!register {register} +\def\c!field {field} \def\c!referencemethod {referencemethod} % forward both @@ -109,27 +110,6 @@ \def\v!vfenced {vfenced} \def\v!bothtext {bothtext} -\def\s!lcgreek {lcgreek} -\def\s!ucgreek {ucgreek} -\def\s!sygreek {sygreek} -\def\s!italics {italics} -\def\s!integral {integral} -\def\s!insert {insert} % maybe insertclass -\def\s!marker {marker} - -\def\s!mixedcolumn {mixedcolumn} - -\def\s!double {double} -\def\s!decimal {decimal} -\def\s!binary {binary} - -\def\s!internal {internal} - -\def\s!current {current} - -\def\s!rel {rel} -\def\s!ord {ord} - \def\c!HL {HL} \def\c!VL {VL} \def\c!NL {NL} diff --git a/tex/context/base/mult-sys.mkiv b/tex/context/base/mult-sys.mkiv index 3f7a837fc..2a1261d8f 100644 --- a/tex/context/base/mult-sys.mkiv +++ b/tex/context/base/mult-sys.mkiv @@ -124,7 +124,7 @@ \definesystemconstant {SansSlanted} \definesystemconstant {SansBoldSlanted} \definesystemconstant {SansCaps} -% \definesystemconstant {SansCapsSlanted} +%definesystemconstant {SansCapsSlanted} \definesystemconstant {Mono} \definesystemconstant {MonoBold} @@ -133,8 +133,8 @@ \definesystemconstant {MonoSlanted} \definesystemconstant {MonoBoldSlanted} \definesystemconstant {MonoCaps} -% \definesystemconstant {MonoCapsSlanted} -% \definesystemconstant {MonoVariable} +%definesystemconstant {MonoCapsSlanted} +%definesystemconstant {MonoVariable} \definesystemconstant {DefaultFont} @@ -261,6 +261,14 @@ \definesystemconstant {single} \definesystemconstant {multi} \definesystemconstant {indeed} +\definesystemconstant {internal} +\definesystemconstant {current} +\definesystemconstant {chain} + +\definesystemconstant {cite} +\definesystemconstant {nocite} +\definesystemconstant {list} +\definesystemconstant {author} % \def\s!parent{->} % 1% faster / => does not work in assignments % \def\s!child {<-} % 1% faster / <= does not work in assignments @@ -279,12 +287,16 @@ \definesystemconstant {bold} \definesystemconstant {italic} \definesystemconstant {slanted} - -\definesystemconstant {default} \definesystemconstant {smallcaps} +\definesystemconstant {lcgreek} +\definesystemconstant {ucgreek} +\definesystemconstant {sygreek} +\definesystemconstant {italics} \definesystemconstant {run} +\definesystemconstant {default} + \definesystemconstant {mode} \definesystemconstant {setup} \definesystemconstant {environment} @@ -303,6 +315,10 @@ \definesystemconstant {lefthyphenchar} \definesystemconstant {righthyphenchar} +\definesystemconstant {double} +\definesystemconstant {decimal} +\definesystemconstant {binary} + %definesystemconstant {skewchar} %definesystemconstant {hyphenchar} \definesystemconstant {catcodes} @@ -323,6 +339,11 @@ %definesystemconstant {background} %definesystemconstant {ucmap} \definesystemconstant {level} +\definesystemconstant {integral} +\definesystemconstant {insert} % maybe insertclass +\definesystemconstant {marker} + +\definesystemconstant {mixedcolumn} %definesystemconstant {property} %definesystemconstant {overprint} @@ -383,8 +404,13 @@ \definesystemconstant {size} \definesystemconstant {depth} +\definesystemconstant {height} +\definesystemconstant {noheight} \definesystemconstant {nodepth} +\definesystemconstant {rel} +\definesystemconstant {ord} + %D Just to be complete we define the standard \TEX\ units. \definesystemconstant {cm} diff --git a/tex/context/base/pack-com.mkiv b/tex/context/base/pack-com.mkiv index 72bb906d9..4f4bc9f47 100644 --- a/tex/context/base/pack-com.mkiv +++ b/tex/context/base/pack-com.mkiv @@ -227,7 +227,7 @@ \pack_combinations_location_reset \rawprocesscommacommand[\p_location]\pack_combinations_location_step % - \dostarttagged\t!combination\currentcombination + \dostarttaggedchained\t!combination\currentcombination\??combination \vbox \ifx\p_height\v!fit\else to \p_height \fi \bgroup \let\combination\empty % permits \combination{}{} handy for cld \normalexpanded{\pack_combinations_start_indeed[\currentcombinationspec]}} diff --git a/tex/context/base/page-mix.mkiv b/tex/context/base/page-mix.mkiv index 3dc170b2e..b85784ac9 100644 --- a/tex/context/base/page-mix.mkiv +++ b/tex/context/base/page-mix.mkiv @@ -510,6 +510,10 @@ {\c_page_mix_routine\c_page_mix_routine_balance}% {\penalty-\plustenthousand}% weird hack, we need to trigger the otr sometimes (new per 20140306, see balancing-001.tex) \page_otr_trigger_output_routine + \ifvoid\b_page_mix_preceding \else + % empty columns so we need to make sure pending content is flushed + \unvbox\b_page_mix_preceding % new per 2014.10.25 + \fi \fi} \setvalue{\??mixedcolumnsafter\s!otr}% @@ -561,7 +565,7 @@ \setbox\scratchbox\page_mix_command_package_column \page_marks_synchronize_column\plusone\c_page_mix_n_of_columns\recurselevel\scratchbox % backgrounds -\anch_mark_column_box\scratchbox + \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 % the framed needs a reset of strut, align, setups etc diff --git a/tex/context/base/publ-aut.lua b/tex/context/base/publ-aut.lua index a14176b24..8e1b20219 100644 --- a/tex/context/base/publ-aut.lua +++ b/tex/context/base/publ-aut.lua @@ -46,14 +46,9 @@ publications.authors = authors local space = P(" ") local comma = P(",") local firstcharacter = lpegpatterns.utf8byte - --- local andsplitter = lpeg.tsplitat(space^1 * "and" * space^1) --- local commasplitter = lpeg.tsplitat(space^0 * comma * space^0) --- local spacesplitter = lpeg.tsplitat(space^1) - -local p_and = space^1 * "and" * space^1 -local p_comma = space^0 * comma * space^0 -local p_space = space^1 +local p_and = space^1 * "and" * space^1 +local p_comma = space^0 * comma * space^0 +local p_space = space^1 local andsplitter = Ct { "start", start = (Cs((V("inner") + (1-p_and))^1) + p_and)^1, @@ -104,7 +99,6 @@ local function splitauthorstring(str) if not detail then local firstnames, vons, surnames, initials, juniors local split = lpegmatch(commasplitter,author) --- inspect(split) local n = #split if n == 1 then -- First von Last @@ -210,19 +204,6 @@ end authors.splitstring = splitauthorstring --- local function splitauthors(dataset,tag,field) --- local entries = datasets[dataset] --- local luadata = entries.luadata --- if not luadata then --- return { } --- end --- local entry = luadata[tag] --- if not entry then --- return { } --- end --- return splitauthorstring(entry[field]) --- end - local function the_initials(initials,symbol) if not symbol or symbol == "" then return initials @@ -387,11 +368,11 @@ function commands.btxauthor(dataset,tag,field,settings) end end --- We can consider creating a hashtable key -> entry but I wonder if +-- We can consider creating a hashtable key -> entry but I wonder if it ever -- pays off. local compare = sorters.comparers.basic -- (a,b) --- local compare = sorters.basicsorter -- (a,b) +----- compare = sorters.basicsorter -- (a,b) local strip = sorters.strip local splitter = sorters.splitters.utf @@ -436,6 +417,39 @@ end writers.author = writer writers.editor = editor +-- how to deal with publisher? + +local default = { "author", "editor" } + +function authors.getauthor(dataset,tag,categories) + local current = datasets[dataset] + local entry = current.luadata[tag] + if entry then + local category = entry.category + local detail = current.details[tag] + if detail then + local list + if categories then + local c = categories[category] + if c then + list = c.author or default + else + list = default + end + else + list = default + end + for i=1,#list do + local l = list[i] + local d = detail[l] + if d then + return d, l + end + end + end + end +end + publications.serializeauthor = writer -- helper local function newsplitter(splitter) @@ -446,27 +460,10 @@ local function newsplitter(splitter) end) end - --- First sorting key: --- A. key= if present takes precedence --- B. author= if present takes second precedence (when key= is absent) --- C. editor= if present takes third precedence (when key= and author= are absent) --- D. publisher= if present (in absence of key=, author= and editor=) --- E. title= if present (but only in absence of key=, author=, editor= and publisher=) --- F. journal= if present --- G. volume= if present --- H. number= if present --- I. pages= if present --- K. if all else fails, ? (APA specifies using "Anonymous" ONLY when specifically listed as such in the publication!) - --- Second sorting key: --- A. year= if present, takes precedence, otherwise treat "n.d." as most recent. --- B. suffix (same first key and same year) --- What about "n.d."? Here, it would be reasonable to second sort by --- title= (lower precedence than the first key above) --- C. month= --- D. day= --- E. journal=, followed by volume=, followed by number= +-- Analysis of the APA by Alan: +-- +-- first : key author editor publisher title journal volume number pages +-- second: year suffix title month day journal volume number local function byauthor(dataset,list,method) local luadata = datasets[dataset].luadata @@ -482,6 +479,7 @@ local function byauthor(dataset,list,method) local detail = details[tag] local index = tostring(i) if entry and detail then +-- todo pluggable local mainkey = writer(detail.author or detail.editor or entry.publisher or entry.title or "",snippets) -- we could store the mainkey in details for tracing result[i] = { @@ -540,34 +538,6 @@ function authors.sorted(dataset,list,sorttype) -- experimental end end -local f_author = formatters[ [[\dobtxindexedauthor{%s}{%s}{%s}{%s}]] ] -local writer = publications.serializeauthor - -function commands.btxauthortoregister(register,dataset,tag) - local current = datasets[dataset] - local details = current.details - local detail = details[tag] - if detail then - local author = detail.author - if author then - for i=1,#author do - local a = author[i] - local k = writer {a} - local e = f_author(dataset,tag,"author",i) - context.dosetfastregisterentry(register,e,k) - -- context.setregisterentry( - -- { register }, - -- { - -- ["entries:1"] = e, - -- ["keys:1"] = k, - -- } - -- ) - end - end - end -end - - -- local dataset = publications.datasets.test -- -- local function add(str) diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua index 424e7a00d..544528405 100644 --- a/tex/context/base/publ-dat.lua +++ b/tex/context/base/publ-dat.lua @@ -92,6 +92,81 @@ local separator = space * "+" * space local l_splitter = lpeg.tsplitat(separator) local d_splitter = lpeg.splitat (separator) +local extrafields = { + category = "implicit", + tag = "implicit", + key = "implicit", +} + +local default = { + name = name, + version = "1.00", + comment = "unknown specification.", + author = "anonymous", + copyright = "no one", + categories = setmetatableindex(function(t,k) + local v = { + required = { }, + optional = { }, + } + t[k] = v + return v + end), + fields = setmetatableindex(function(t,k) + local v = setmetatableindex(function(t,k) local v = "optional" t[k] = v return v end) + t[k] = v + return v + end), +} + +local types = { "optional", "required", "virtual" } + +local specifications = setmetatableindex(function(t,name) + if not name then + return default -- initializer + end + local filename = formatters["publ-imp-%s.lua"](name) + local fullname = resolvers.findfile(fullname) or "" + if fullname == "" then + report("no data definition file %a for %a",filename,name) + return default + end + local specification = table.load(filename) + if not specification then + report("invalid data definition file %a for %a",fullname,name) + return default + end + -- goodie for alan ... + local categories = specification.categories + for k, v in next, categories do + if type(v) == "string" then + categories[k] = categories[v] + end + end + -- + local fields = { } + specification.fields = fields + for category, data in next, categories do + local list = setmetatableindex({},extrafields) + fields[category] = list + for i=1,#types do + local t = types[i] + local d = data[t] + if d then + for i=1,#d do + list[d[i]] = t + end + else + data[t] = { } + end + end + end + t[name] = specification + return specification +end) + +publications.specifications = specifications + function publications.parenttag(dataset,tag) if not dataset or not tag then report("error in specification, dataset %a, tag %a",dataset,tag) diff --git a/tex/context/base/publ-imp-apa.lua b/tex/context/base/publ-imp-apa.lua index 5f6a1d35d..5eabfbe22 100644 --- a/tex/context/base/publ-imp-apa.lua +++ b/tex/context/base/publ-imp-apa.lua @@ -1,5 +1,8 @@ -- to be checked +local virtual = { "authoryear", "authoryears", "authornum", "num", "suffix" } +local authors = { "author", "editor", "publisher" } + return { name = "apa", version = "1.00", @@ -8,76 +11,110 @@ return { copyright = "ConTeXt development team", categories = { article = { - required = { {"author", "editor"}, "title", "journal", "year" }, - optional = { "volume", "number", "pages", "note", "type", "url", "doi" }, + required = { "author", "editor", "title"}, + optional = { "year", "type", "journal", "volume", "number", "pages", "url", "note", "doi" }, + virtual = virtual, + author = authors, }, magazine = { - required = { {"author", "editor",}, "title", "journal", "year" }, + required = { "author", "editor", "title", "journal", "year" }, optional = { "volume", "number", "pages", "month", "day", "note", "url", "doi" }, + virtual = virtual, + author = authors, }, newspaper = { - required = { {"author", "editor",}, "title", "journal", "year" }, + required = { "author", "editor", "title", "journal", "year" }, optional = { "volume", "number", "pages", "month", "day", "note", "url", "doi" }, + virtual = virtual, + author = authors, }, book = { - required = { { "author", "editor" }, "title", "publisher", "year" }, - optional = { { "volume", "number" }, "series", "address", "edition", "month", "note", "pages", "ISBN" }, + virtual = { "authoryear" }, + required = { "author", "editor", "publisher", "title"}, + optional = { "year", "month", "day", "title", "type", "edition", "series", "volume", "number", "pages", "address", "publisher", "url", "note", "ISBN" }, + virtual = virtual, + author = authors, }, booklet = { required = { "title" }, optional = { "author", "howpublished", "address", "month", "year", "note" }, + virtual = virtual, + author = authors, }, inbook = { - required = { { "author", "editor" }, "title", { "chapter", "pages" }, "publisher","year" }, - optional = { { "volume", "number" }, "series", "type", "address", "edition", "month", "note", "ISBN" }, + required = { "author", "editor", "title", "chapter", "pages", "publisher","year" }, + optional = { "volume", "number", "series", "type", "address", "edition", "month", "note", "ISBN" }, + virtual = virtual, + author = authors, }, incollection = { required = { "author", "title", "booktitle", "publisher", "year" }, - optional = { "editor", { "volume", "number" }, "series", "type", "chapter", "pages", "address", "edition", "month", "note", "ISBN" }, + optional = { "editor", "volume", "number", "series", "type", "chapter", "pages", "address", "edition", "month", "note", "ISBN" }, + virtual = virtual, + author = authors, }, inproceedings = { required = { "author", "title", "booktitle", "year" }, - optional = { "editor", { "volume", "number" }, "series", "pages", "address", "month", "organization", "publisher", "note", "ISBN" }, + optional = { "editor", "volume", "number", "series", "pages", "address", "month", "organization", "publisher", "note", "ISBN" }, + virtual = virtual, + author = authors, }, - -- does this work: - conference = inproceedings, + conference = + "inproceedings", -- Alan: does this work? Hans: I just made it work. manual = { required = { "title" }, optional = { "author", "organization", "address", "edition", "month", "year", "note" }, + virtual = virtual, + author = authors, }, mastersthesis = { required = { "author", "title", "school", "year" }, optional = { "type", "address", "month", "note" }, + virtual = virtual, + author = authors, }, misc = { required = { }, optional = { "author", "title", "howpublished", "month", "year", "note" }, + virtual = virtual, + author = authors, }, -- Not sure yet how "periodical" is used... but "jabref" includes it as standard. -- strangely, "jabref" does not include "author" as required nor optional.. periodical = { required = { "title", "year" }, optional = { "author", "editor", "month", "note", "number", "organization", "series", "volume" }, + virtual = virtual, + author = authors, }, phdthesis = { required = { "author", "title", "school", "year" }, optional = { "type", "address", "month", "note" }, + virtual = virtual, }, proceedings = { required = { "title", "year" }, - optional = { "editor", { "volume", "number" }, "series", "address", "month", "organization", "publisher", "note", "pages", "ISBN" }, + optional = { "editor", "volume", "number", "series", "address", "month", "organization", "publisher", "note", "pages", "ISBN" }, + virtual = virtual, + author = authors, }, techreport = { required = { "author", "title", "institution", "year" }, optional = { "type", "number", "address", "month", "note" }, + virtual = virtual, + author = authors, }, patent = { required = { "nationality", "number", "year", "yearfiled" }, optional = { "author", "title", "language", "assignee", "address", "type", "day", "dayfiled", "month", "monthfiled", "note", }, + virtual = virtual, + author = authors, }, unpublished = { required = { "author", "title", "note" }, optional = { "month", "year" }, + virtual = virtual, + author = authors, }, literal = { required = { "key", "text", }, diff --git a/tex/context/base/publ-imp-apa.mkvi b/tex/context/base/publ-imp-apa.mkvi index e83306bcd..d3f6dda73 100644 --- a/tex/context/base/publ-imp-apa.mkvi +++ b/tex/context/base/publ-imp-apa.mkvi @@ -36,8 +36,6 @@ % First of all, the APA style defines authoryear bibliography lists. -% Question: is the field "key=" (->sortkey, not the \cite [key]) used if present? - % does not work here: \setupbtxrendering [standard] [numbering=no,sorttype=authoryear] % does not work here: \setupbtxcitevariant [alternative=authoryear,sorttype=authoryear] @@ -71,7 +69,7 @@ apa:phdthesis={PhD thesis}, apa:technicalreport={Tech. Rep.}, % Technical report apa:supplement={Suppl.}, % Supplement - apa:patent=patent, + apa:patent=Patent, apa:Translator={Trans.}, % Translator(s) apa:Editor={Ed.}, % Editor apa:Editors={Eds.}, % Editors @@ -91,7 +89,7 @@ apa:pages=pages, apa:and=and, apa:period={. }, - apa:Author=Author, %TODO, should be typeset in italic... + apa:Author=Author, apa:Advanced={Advanced online publication}, apa:Retrieved={Retrieved from}, apa:others={et al.}] @@ -102,7 +100,7 @@ apa:phdthesis={Thèse de doctorat}, apa:technicalreport={Rapport technique}, apa:supplement=Supplément, - apa:patent=brevet, + apa:patent=Brevet, apa:Translator=Traducteur, apa:Editor=Éditeur, apa:Editors=Éditeurs, @@ -166,7 +164,7 @@ apa:phdthesis={Tesi di dottorato}, apa:technicalreport={Relazione tecnica}, apa:supplement={Supplemento}, - apa:patent=brevetto, + apa:patent=Brevetto, apa:Translator={Trad.}, % Translator(s) apa:Editor={A cura di}, apa:Editors={A cura di}, @@ -194,27 +192,27 @@ %D The variables control the shared code for which we use a tex definition with %D one argument, specifying the field name. -\setvariables - [btx:apa:publisher] - [left=\btxspace, - right=\btxperiod] - -\setvariables - [btx:apa:organization] - [left=\btxspace, - right=\btxperiod] - -\setvariables - [btx:apa:school] - [left=\btxcomma, - right=\btxperiod, - otherwise=\btxperiod] - -\setvariables - [btx:apa:institution] - [left=\btxcomma, - right=\btxperiod, - otherwise=\btxperiod] +%\setvariables +% [btx:apa:publisher] +% [left=\btxspace, +% right=\btxperiod] +% +%\setvariables +% [btx:apa:organization] +% [left=\btxspace, +% right=\btxperiod] +% +%\setvariables +% [btx:apa:school] +% [left=\btxcomma, +% right=\btxperiod, +% otherwise=\btxperiod] +% +%\setvariables +% [btx:apa:institution] +% [left=\btxcomma, +% right=\btxperiod, +% otherwise=\btxperiod] % First some helpers: @@ -232,7 +230,6 @@ \btxcomma % language issue here? \btxflush{month} - \btxspace \btxdoif {day} { \btxspace \btxflush{day} @@ -241,13 +238,17 @@ } } { \btxlabeltext{apa:nd} + \btxdoif {suffix} { + \btxspace + \btxflush{suffix} + } } \btxrightparenthesisperiod \stoptexdefinition -\starttexdefinition btx:apa:title-subtitle #before #type +\starttexdefinition btx:apa:title-subtitle-including- #type \btxdoif {title} { - #before + \setmode{btx:apa:title-placed} \btxflush{Word -> title} \btxdoif {subtitle} { \btxcolon @@ -267,12 +268,11 @@ } \stoptexdefinition -\starttexdefinition btx:apa:author-or-title #type +\starttexdefinition btx:apa:author-or-title-including- #type \btxdoifelse {author} { \btxflushauthor[invertedshort]{author} } { - \setmode{btx:apa:title-placed} - \texdefinition{btx:apa:title-subtitle}{}{#type} + \texdefinition{btx:apa:title-subtitle-including-}{#type} } \stoptexdefinition @@ -286,7 +286,7 @@ \btxrightparenthesisperiod \stoptexdefinition -\starttexdefinition btx:apa:author-or-editor-or-publisher #title +\starttexdefinition btx:apa:author-or-editor-or-publisher-or- #title #publisher \btxdoifelse {author} { \btxflushauthor[invertedshort]{author} } { @@ -294,12 +294,14 @@ \btxflushauthor[invertedshort]{editor} \texdefinition{btx:apa:editor-or-editors} } { - \btxdoifelse {publisher} { - \btxflush{publisher} + \btxdoifelse {#publisher} { +% \setmode{btx:apa:publisher-as-author} + \btxflush{#publisher} } { \doif {#title} {title} { - \setmode{btx:apa:title-placed} - \texdefinition{btx:apa:title-subtitle}{}{type} + \texdefinition{btx:apa:title-subtitle-including-} + \doifelse {#publisher} {institution}%->techreport + {type} {} } } } @@ -315,23 +317,25 @@ \btxflush{organization} } { \doif {#title} {title} { - \setmode{btx:apa:title-placed} - \texdefinition{btx:apa:title-subtitle}{}{type} + \texdefinition{btx:apa:title-subtitle-including-}{type} } } } \stoptexdefinition -\starttexdefinition btx:apa:title-if-not-placed #it +\starttexdefinition btx:apa:title-if-not-placed-including- #type #it \doifnotmode {btx:apa:title-placed} { - \doifelse {#it} {it} { - \begingroup - \it - \texdefinition{btx:apa:title-subtitle}{\btxspace}{type} - \italiccorrection - \endgroup - } { - \texdefinition{btx:apa:title-subtitle}{\btxspace}{type} + \btxdoif {title} { + \btxspace + \doifelse {#it} {it} { + \begingroup + \it + \texdefinition{btx:apa:title-subtitle-including-}{#type} + \italiccorrection + \endgroup + } { + \texdefinition{btx:apa:title-subtitle-including-}{#type} + } } } \stoptexdefinition @@ -364,8 +368,8 @@ } \stoptexdefinition -\starttexdefinition btx:apa:doif-edition-or-volume-or-number-or-pages #if - \btxdoifelse {edition} { +\starttexdefinition btx:apa:doif-edition-or-volume-or-number-or-pages #edition #if + \btxdoifelse {#edition} { #if }{ \btxdoifelse {volume} { @@ -382,16 +386,24 @@ } \stoptexdefinition -\starttexdefinition btx:apa:edition-volume-number-pages - \texdefinition{btx:apa:doif-edition-or-volume-or-number-or-pages}{\btxleftparenthesis} - \btxdoif {edition} { - \btxflush{edition} - \btxspace - \btxlabeltext{apa:edition} +\starttexdefinition btx:apa:edition-volume-number-pages #edition + \texdefinition{btx:apa:doif-edition-or-volume-or-number-or-pages}{#edition}{\btxleftparenthesis} + \btxdoifelse {#edition} { + \btxflush{#edition} + \doif {#edition} {edition} { + \btxspace + \btxlabeltext{apa:edition} + } + } { + \doif {#edition} {type} { + \btxspace + \btxlabeltext{apa:technicalreport} + } } \btxdoif {volume} { - \btxdoif {edition} { - \btxcomma + \btxdoif {#edition} { + \doif {#edition} {edition} + {\btxcomma} {\btxspace} } \btxoneorrange {volume} { \btxlabeltext{apa:Volume} @@ -405,11 +417,13 @@ \btxdoifelse {volume} { \btxcomma } { - \btxdoif {edition} { - \btxcomma + \btxdoifelse {#edition} { + \doif {#edition} {edition} + {\btxcomma} {\btxspace} + } { + \btxspace } } - \btxspace \btxlabeltext{apa:Number} \btxspace \btxflush{number} @@ -418,8 +432,9 @@ \btxdoifelse {volume} { \btxcomma } { - \btxdoifelse {edition} { - \btxcomma + \btxdoifelse {#edition} { + \doif {#edition} {edition} + {\btxcomma} {\btxspace} } { \btxdoif {number} { \btxcomma @@ -434,7 +449,7 @@ \btxspace \btxflush{pages} } - \texdefinition{btx:apa:doif-edition-or-volume-or-number-or-pages}{\btxrightparenthesisperiod} + \texdefinition{btx:apa:doif-edition-or-volume-or-number-or-pages}{#edition}{\btxrightparenthesisperiod} \stoptexdefinition \starttexdefinition btx:apa:journal-volume-number-pages #pp @@ -470,7 +485,7 @@ \btxcomma } } - % APA rule for newspaper, ... + % APA rule for newspaper \doif {#pp} {pp} { \btxoneorrange {pages} { \btxlabeltext{apa:p} @@ -483,17 +498,17 @@ \btxperiod } \doifnot {#pp} {pp} { - % not a newspaper... + % not a newspaper \btxdoifnot {volume} { \btxdoifnot {number} { \btxdoifnot {pages} { \btxdoifelse {doi} { - \btxspace + \btxperiod \btxlabeltext{apa:Advanced} \btxperiod } { \btxdoif {url} { - \btxspace + \btxperiod \btxlabeltext{apa:Advanced} \btxperiod } @@ -527,23 +542,23 @@ \btxspace \ifconditional\btxinteractive \goto { - \hyphenatedurl{doi:\btxflush{doi}} + doi:\btxflush{doi} } [ url(http://dx.doi.org/\btxflush{doi}) ] \else - \hyphenatedurl{doi:\btxflush{doi}} + doi:\btxflush{doi} \fi } \stoptexdefinition \starttexdefinition btx:apa:note - % grouping could indeed be useful... + % grouping could indeed be useful for note. \btxdoif {note} { \btxleftparenthesis {\btxflush{note}} \btxrightparenthesis\removeunwantedspaces - % nospace if last item... + % no space if last item! } \stoptexdefinition @@ -553,19 +568,19 @@ \texdefinition{btx:apa:doi} \stoptexdefinition -\starttexdefinition btx:apa:author-editor-other #field - \btxdoif {#field} { - \doifelse {#field} {publisher} { - \doifelse {\btxflush{#field}} {\btxflush{author}} { - \btxlabeltext{apa:Author} - } { - \btxflush{#field} - } - } { - \btxflush{#field} - } - } -\stoptexdefinition +%\starttexdefinition btx:apa:author-editor-other #field +% \btxdoif {#field} { +% \doifelse {#field} {publisher} { +% \doifmodeelse {btx:apa:publisher-as-author} { +% \btxlabeltext{apa:Author} +% } { +% \btxflush{publisher} +% } +% } { +% \btxflush{#field} +% } +% } +%\stoptexdefinition \starttexdefinition btx:apa:doifelse-publisher-or-author-or-editor #author #if #else \btxdoifelse {publisher} { @@ -591,7 +606,8 @@ } \stoptexdefinition -\starttexdefinition btx:apa:wherefrom-publisher #author +% #author is author, editor, organization, howpublished or assignee +\starttexdefinition btx:apa:wherefrom-publisher-author-is- #author \btxdoifelse {country} { \btxspace \btxdoif {address} { @@ -599,37 +615,50 @@ \btxcomma } \btxflush{country} - \texdefinition{btx:apa:doifelse-publisher-or-author-or-editor}{#author} - {\btxcolon} {\btxperiod} + \doifelse {#author} {howpublished} + {\btxdoifelse {howpublished}} + {\texdefinition{btx:apa:doifelse-publisher-or-author-or-editor}{#author}} + {\btxcolon} {\btxperiod} } { \btxdoifelse {address} { \btxspace \btxflush{address} - \texdefinition{btx:apa:doifelse-publisher-or-author-or-editor}{#author} - {\btxcolon} {\btxperiod} + \doifelse {#author} {howpublished} + {\btxdoifelse {howpublished}} + {\texdefinition{btx:apa:doifelse-publisher-or-author-or-editor}{#author}} + {\btxcolon} {\btxperiod} } { - \texdefinition{btx:apa:doifelse-publisher-or-author-or-editor}{#author} + \doifelse {#author} {howpublished} + {\btxdoifelse {howpublished}} + {\texdefinition{btx:apa:doifelse-publisher-or-author-or-editor}{#author}} {\btxspace} {} } } - \btxdoifelse {publisher} { - \btxdoifelse {#author} { - \btxflush{publisher} - \btxperiod - } { - \btxdoif {editor} { + \doifelse {#author} {howpublished} { + \btxdoif {howpublished} { + \btxflush{howpublished} + \btxperiod + } + } { + \btxdoifelse {publisher} { + \btxdoifelse {#author} { \btxflush{publisher} \btxperiod + } { + \btxdoif {editor} { + \btxflush{publisher} + \btxperiod + } } - } - } { - \btxdoifelse {#author} { - \btxlabeltext{apa:Author} - \btxperiod } { - \btxdoif {editor} { + \btxdoifelse {#author} { \btxlabeltext{apa:Author} \btxperiod + } { + \btxdoif {editor} { + \btxlabeltext{apa:Author} + \btxperiod + } } } } @@ -642,9 +671,9 @@ % Optional fields: volume, number, pages, type, doi, url, note. \startsetups btx:apa:article - \texdefinition{btx:apa:author-or-title}{type} + \texdefinition{btx:apa:author-or-title-including-}{type} \texdefinition{btx:apa:suffixedyear}{} - \texdefinition{btx:apa:title-if-not-placed}{} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{} \texdefinition{btx:apa:journal-volume-number-pages}{} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -654,9 +683,9 @@ % Optional fields: volume, number, pages, type, month, day, doi, url, note. \startsetups btx:apa:magazine - \texdefinition{btx:apa:author-or-title}{type} + \texdefinition{btx:apa:author-or-title-including-}{type} \texdefinition{btx:apa:suffixedyear}{date} - \texdefinition{btx:apa:title-if-not-placed}{} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{} \texdefinition{btx:apa:journal-volume-number-pages}{} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -666,9 +695,9 @@ % Optional fields: volume, number, pages, type, month, day, doi, url, note. \startsetups btx:apa:newspaper - \texdefinition{btx:apa:author-or-title}{type} + \texdefinition{btx:apa:author-or-title-including-}{type} \texdefinition{btx:apa:suffixedyear}{date} - \texdefinition{btx:apa:title-if-not-placed}{} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{} \texdefinition{btx:apa:journal-volume-number-pages}{pp} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -681,11 +710,11 @@ % todo: series? \startsetups btx:apa:book - \texdefinition{btx:apa:author-or-editor-or-publisher}{title} + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{title}{publisher} \texdefinition{btx:apa:suffixedyear}{} - \texdefinition{btx:apa:title-if-not-placed}{it} - \texdefinition{btx:apa:edition-volume-number-pages} - \texdefinition{btx:apa:wherefrom-publisher}{author} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{it} + \texdefinition{btx:apa:edition-volume-number-pages}{edition} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{author} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -697,15 +726,15 @@ % todo: series? \startsetups btx:apa:inbook - \texdefinition{btx:apa:author-or-editor-or-publisher}{} + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{}{publisher} \texdefinition{btx:apa:suffixedyear}{} \btxdoif {chapter} { \btxflush{Word -> chapter} \btxspace } \texdefinition{btx:apa:editor}{title} - \texdefinition{btx:apa:edition-volume-number-pages} - \texdefinition{btx:apa:wherefrom-publisher}{author} + \texdefinition{btx:apa:edition-volume-number-pages}{edition} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{author} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -717,12 +746,12 @@ % todo: series? \startsetups btx:apa:incollection - \texdefinition{btx:apa:author-or-editor-or-publisher}{title} + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{title}{publisher} \texdefinition{btx:apa:suffixedyear}{} - \texdefinition{btx:apa:title-if-not-placed}{} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{} \texdefinition{btx:apa:editor}{booktitle} - \texdefinition{btx:apa:edition-volume-number-pages} - \texdefinition{btx:apa:wherefrom-publisher}{author} + \texdefinition{btx:apa:edition-volume-number-pages}{edition} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{author} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -734,17 +763,17 @@ \startsetups btx:apa:proceedings \texdefinition{btx:apa:editor-or-organization}{title} \texdefinition{btx:apa:suffixedyear}{date} - \texdefinition{btx:apa:title-if-not-placed}{} - \texdefinition{btx:apa:edition-volume-number-pages} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{} + \texdefinition{btx:apa:edition-volume-number-pages}{edition} \btxdoifelse {editor} { \btxdoif {organization} { \btxspace \btxflush{organization} \btxcomma } - \texdefinition{btx:apa:wherefrom-publisher} {editor} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{editor} } { - \texdefinition{btx:apa:wherefrom-publisher} {organization} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{organization} } \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -755,17 +784,17 @@ % todo: series? \startsetups btx:apa:inproceedings - \texdefinition{btx:apa:author-or-editor-or-publisher}{title} + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{title}{publisher} \texdefinition{btx:apa:suffixedyear}{date} - \texdefinition{btx:apa:title-if-not-placed}{} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{} \texdefinition{btx:apa:editor}{booktitle} - \texdefinition{btx:apa:edition-volume-number-pages} + \texdefinition{btx:apa:edition-volume-number-pages}{edition} \btxdoif {organization} { \btxspace \btxflush{organization} \btxcomma } - \texdefinition{btx:apa:wherefrom-publisher}{author} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{author} \texdefinition{btx:apa:url-note-doi} \stopsetups @@ -779,9 +808,9 @@ \startsetups btx:apa:thesis % unlikely not to have author! - \texdefinition{btx:apa:author-or-title}{} + \texdefinition{btx:apa:author-or-title-including-}{} \texdefinition{btx:apa:suffixedyear}{date} - \texdefinition{btx:apa:title-if-not-placed}{it} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{it} \btxleftparenthesis \btxdoifelse {type} { \btxflush{type} @@ -816,7 +845,186 @@ \fastsetup{btx:apa:thesis} \stopsetups -% Alan's current revision stops here.. +% A work that is printed and bound, but without a named publisher or sponsoring institution. +% Required field: title. +% Optional fields: author, howpublished, address, month, year, note. + +\startsetups btx:apa:booklet + \texdefinition{btx:apa:author-or-title-including-}{} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{it} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{howpublished} + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% Technical documentation. +% Required field: title. +% Optional fields: author, organization, address, edition, month, year, note. + +\startsetups btx:apa:manual + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{title}{organization} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{it} + \texdefinition{btx:apa:edition-volume-number-pages}{edition} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{organization} + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% A report published by a school or other institution, usually numbered within a series. +% Required fields: author, title, institution, year. +% Optional fields: type, number, address, month, note. + +\startsetups btx:apa:techreport + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{title}{institution} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{}{it} + \texdefinition{btx:apa:edition-volume-number-pages}{type} + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{institution} + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% A document having an author and title, but not formally published. +% Required fields: author, title, note. +% Optional fields: month, year. + +\startsetups btx:apa:unpublished + \texdefinition{btx:apa:author-or-title-including-}{} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{}{it} + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% A patent. Note that this category was not defined with BIBTEX. Below from JabRef: +% Required fields: nationality, number, year, yearfiled +% Optional fields: author, title, assignee, address, type, number, day, dayfiled, month, monthfiled, note, url +% Also optional: publisher + +% todo: yearfiled, monthfiled, dayfiled + +\startsetups btx:apa:patent + \texdefinition{btx:apa:author-or-editor-or-publisher-or-}{title}{assignee} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{it} + \begingroup + \it + \btxdoif {nationality} { + \btxspace + \btxflush{nationality} + } + \btxspace + \btxlabeltext{apa:patent} + \btxdoif {number} { + \btxspace + \btxlabeltext{apa:Number} + \btxspace + \btxflush{number} + } + \btxperiod + \italiccorrection + \endgroup + \btxdoifelse {author} { + \btxdoifelse {country} { + \btxspace + \btxdoif {address} { + \btxflush{address} + \btxcomma + } + \btxflush{country} + \btxdoifelse {assignee} + {\btxcolon} {\btxperiod} + } { + \btxdoifelse {address} { + \btxspace + \btxflush{address} + \btxdoifelse {assignee} + {\btxcolon} {\btxperiod} + } { + \btxdoifelse {assignee} + {\btxspace} {} + } + } + \btxdoif {assignee} { + \btxflush{assignee} + \btxperiod + } + } { + \texdefinition{btx:apa:wherefrom-publisher-author-is-}{assignee} + } + \texdefinition{btx:apa:url} + \texdefinition{btx:apa:note} +\stopsetups + +% Electronic. Note that this category was not defined with BIBTEX. Below from JabRef: +% Required fields: title +% Optional fields: address, author, howpublished, month, note, organization, url, year, doi +% Also optional: type + +% Like Misc below but includes organization. + +\startsetups btx:apa:electronic + \texdefinition{btx:apa:author-or-title-including-}{type} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{type}{it} + \btxdoif {organization} { + \btxspace + \btxflush{organization} + \btxperiod + } + \btxdoif {howpublished} { + \btxspace + \btxflush{howpublished} + \btxperiod + } + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% Other. Note that this category was not defined with BIBTEX. Below from JabRef: +% Required fields: author or title, year +% Optional fields: note, doi, url + +\startsetups btx:apa:other + \texdefinition{btx:apa:author-or-title-including-}{} + \texdefinition{btx:apa:suffixedyear}{} + \texdefinition{btx:apa:title-if-not-placed-including-}{}{it} + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% Use this type when nothing else fits. +% Required fields: none. +% Optional fields: author, title, howpublished, month, year, note. + +\startsetups btx:apa:misc + \texdefinition{btx:apa:author-or-title-including-}{} + \texdefinition{btx:apa:suffixedyear}{date} + \texdefinition{btx:apa:title-if-not-placed-including-}{}{it} + \btxdoif {howpublished} { + \btxspace + \btxflush{howpublished} + \btxperiod + } + \texdefinition{btx:apa:url-note-doi} +\stopsetups + +% If all else fails to match: + +\startsetups btx:apa:literal + \btxdoif {text} { + \btxflush{text} + } +\stopsetups + +%D Experiment: + +\startsetups btx:apa:lefttext + \currentbtxlefttext +\stopsetups + +\startsetups btx:apa:righttext + \currentbtxrighttext +\stopsetups + +\stopbtxrenderingdefinitions + %\starttexdefinition btx:apa:wherefrom #field % \btxdoifelse {address} { @@ -852,163 +1060,163 @@ % } % } %\stoptexdefinition - -\starttexdefinition btx:apa:title-and-series - \btxdoif {title} { - \btxspace - \btxflush{Word -> title} - \btxdoif {series} { - \btxleftparenthesis - \btxflush{series} - \btxrightparenthesis - } - \btxperiod - } -\stoptexdefinition - -\starttexdefinition btx:apa:title-and-series-it - \btxdoif {title} { - \btxspace - \texdefinition{btx:apa:italic}{Word -> title} - \btxdoif {series} { - \btxleftparenthesis - \btxflush{series} - \btxrightparenthesis - } - \btxperiod - } -\stoptexdefinition - -\disablemode[btx:apa:edited-book] % hm, ugly - -\starttexdefinition btx:apa:author-and-year - \btxdoif {author} { - \btxflushauthor{author} - } - \texdefinition{btx:apa:suffixedyear}{} - \btxperiod -\stoptexdefinition - -\starttexdefinition btx:apa:author-or-key-and-year - \btxdoifelse {author} { - \btxflushauthor{author} - } { - \btxdoif {key} { - \btxleftbracket - \btxsetup{btx:format:key} - \btxrightbracket - } - } - \texdefinition{btx:apa:suffixedyear}{} - \btxperiod -\stoptexdefinition - -\starttexdefinition btx:apa:author-editors-crossref-year - % TODO: if there is no author or editor, then use publisher... - \btxdoifelse {author} { - \btxflushauthor{author} - } { - \btxdoifelse {editor} { - \setmode{btx:apa:edited-book} - \btxflushauthor{editor} - \btxcomma - \btxsingularplural {editor} { - \btxlabeltext{apa:Editor} - } { - \btxlabeltext{apa:Editors} - } - } { - % weird period - \btxdoif {crossref} { - \btxleftbracket - \btxsetup{btx:format:crossref} - \btxrightbracket - \btxperiod - } - } - } - \texdefinition{btx:apa:suffixedyear}{} - \btxperiod -\stoptexdefinition - -\starttexdefinition btx:apa:editor-or-key-and-year - \btxdoifelse {editor} { - \setmode{btx:apa:edited-book} - \btxflushauthor{editor} - \btxcomma - \btxsingularplural {editor} { - \btxlabeltext{apa:Editor} - } { - \btxlabeltext{apa:Editors} - } - } { - \btxdoif {key} { - \btxleftbracket - \btxsetup{btx:format:key} - \btxrightbracket - } - } - \texdefinition{btx:apa:suffixedyear}{} - \btxperiod -\stoptexdefinition - -\starttexdefinition btx:apa:pages - \btxdoif {pages} { - \btxspace - \btxflush{pages} - \btxperiod - } -\stoptexdefinition - -\starttexdefinition btx:apa:pages:p - \btxdoif {pages} { - \btxspace - \btxoneorrange {pages} { - \btxlabeltext{apa:p} - } { - \btxlabeltext{apa:pp} - } - \btxperiod - \btxnbsp - \btxflush{pages} - \btxperiod - } -\stoptexdefinition - -\starttexdefinition btx:apa:pages:pp - \btxdoif {pages} { - \btxspace - \btxflush{pages} - \btxnbsp - \btxlabeltext{apa:pp} - \btxperiod - } -\stoptexdefinition - +% +%\starttexdefinition btx:apa:title-and-series +% \btxdoif {title} { +% \btxspace +% \btxflush{Word -> title} +% \btxdoif {series} { +% \btxleftparenthesis +% \btxflush{series} +% \btxrightparenthesis +% } +% \btxperiod +% } +%\stoptexdefinition +% +%\starttexdefinition btx:apa:title-and-series-it +% \btxdoif {title} { +% \btxspace +% \texdefinition{btx:apa:italic}{Word -> title} +% \btxdoif {series} { +% \btxleftparenthesis +% \btxflush{series} +% \btxrightparenthesis +% } +% \btxperiod +% } +%\stoptexdefinition +% +%\disablemode[btx:apa:edited-book] % hm, ugly +% +%\starttexdefinition btx:apa:author-and-year +% \btxdoif {author} { +% \btxflushauthor{author} +% } +% \texdefinition{btx:apa:suffixedyear}{} +% \btxperiod +%\stoptexdefinition +% +%\starttexdefinition btx:apa:author-or-key-and-year +% \btxdoifelse {author} { +% \btxflushauthor{author} +% } { +% \btxdoif {key} { +% \btxleftbracket +% \btxsetup{btx:format:key} +% \btxrightbracket +% } +% } +% \texdefinition{btx:apa:suffixedyear}{} +% \btxperiod +%\stoptexdefinition +% +%\starttexdefinition btx:apa:author-editors-crossref-year +% % TODO: if there is no author or editor, then use publisher... +% \btxdoifelse {author} { +% \btxflushauthor{author} +% } { +% \btxdoifelse {editor} { +% \setmode{btx:apa:edited-book} +% \btxflushauthor{editor} +% \btxcomma +% \btxsingularplural {editor} { +% \btxlabeltext{apa:Editor} +% } { +% \btxlabeltext{apa:Editors} +% } +% } { +% % weird period +% \btxdoif {crossref} { +% \btxleftbracket +% \btxsetup{btx:format:crossref} +% \btxrightbracket +% \btxperiod +% } +% } +% } +% \texdefinition{btx:apa:suffixedyear}{} +% \btxperiod +%\stoptexdefinition +% +%\starttexdefinition btx:apa:editor-or-key-and-year +% \btxdoifelse {editor} { +% \setmode{btx:apa:edited-book} +% \btxflushauthor{editor} +% \btxcomma +% \btxsingularplural {editor} { +% \btxlabeltext{apa:Editor} +% } { +% \btxlabeltext{apa:Editors} +% } +% } { +% \btxdoif {key} { +% \btxleftbracket +% \btxsetup{btx:format:key} +% \btxrightbracket +% } +% } +% \texdefinition{btx:apa:suffixedyear}{} +% \btxperiod +%\stoptexdefinition +% +%\starttexdefinition btx:apa:pages +% \btxdoif {pages} { +% \btxspace +% \btxflush{pages} +% \btxperiod +% } +%\stoptexdefinition +% +%\starttexdefinition btx:apa:pages:p +% \btxdoif {pages} { +% \btxspace +% \btxoneorrange {pages} { +% \btxlabeltext{apa:p} +% } { +% \btxlabeltext{apa:pp} +% } +% \btxperiod +% \btxnbsp +% \btxflush{pages} +% \btxperiod +% } +%\stoptexdefinition +% +%\starttexdefinition btx:apa:pages:pp +% \btxdoif {pages} { +% \btxspace +% \btxflush{pages} +% \btxnbsp +% \btxlabeltext{apa:pp} +% \btxperiod +% } +%\stoptexdefinition +% % this does not seem to comply with APA style - need to verify! - -\starttexdefinition btx:apa:pages:pages - \btxdoif {pages} { - \btxcomma - \btxlabeltext{apa:pages} - \btxnbsp - \btxflush{pages} - \btxperiod - } -\stoptexdefinition - -\starttexdefinition btx:apa:edition:sentence - \btxdoif {edition} { - \btxspace - \btxflush{edition} - \btxspace - \btxlabeltext{apa:edition} - \btxperiod - } -\stoptexdefinition - +% +%\starttexdefinition btx:apa:pages:pages +% \btxdoif {pages} { +% \btxcomma +% \btxlabeltext{apa:pages} +% \btxnbsp +% \btxflush{pages} +% \btxperiod +% } +%\stoptexdefinition +% +%\starttexdefinition btx:apa:edition:sentence +% \btxdoif {edition} { +% \btxspace +% \btxflush{edition} +% \btxspace +% \btxlabeltext{apa:edition} +% \btxperiod +% } +%\stoptexdefinition +% % check when the next is used (no period) - +% % \starttexdefinition btx:apa:edition % \btxdoif {edition} { % \btxspace @@ -1017,9 +1225,9 @@ % \btxlabeltext{apa:edition} % } % \stoptexdefinition - +% % specific - +% %\startsetups btx:apa:book % \texdefinition{btx:apa:author-editors-crossref-year} % \btxdoif {title} { @@ -1098,7 +1306,7 @@ % \texdefinition{btx:apa:pages:pp}% twice? % \texdefinition{btx:apa:url-note-doi} %\stopsetups - +% %\startsetups btx:apa:inbook % \texdefinition{btx:apa:author-editors-crossref-year} % \btxdoifelse {title} { @@ -1182,33 +1390,25 @@ % \texdefinition{btx:apa:wherefrom}{publisher} % \texdefinition{btx:apa:note} %\stopsetups - -% A work that is printed and bound, but without a named publisher or sponsoring institution. -% Required field: title. -% Optional fields: author, howpublished, address, month, year, note. - -\startsetups btx:apa:booklet - \texdefinition{btx:apa:author-or-key-and-year} - \texdefinition{btx:apa:title-it-and-series} - \texdefinition{btx:apa:edition:sentence} - \texdefinition{btx:apa:publication:sentence} - \texdefinition{btx:apa:pages:p} - \texdefinition{btx:apa:note} -\stopsetups - -% Technical documentation. -% Required field: title. -% Optional fields: author, organization, address, edition, month, year, note. - -\startsetups btx:apa:manual - \texdefinition{btx:apa:author-or-key-and-year} - \texdefinition{btx:apa:title-it-and-series} - \texdefinition{btx:apa:edition:sentence} - \texdefinition{btx:apa:wherefrom}{organization} - \texdefinition{btx:apa:pages:p} - \texdefinition{btx:apa:note} -\stopsetups - +% +%\startsetups btx:apa:booklet +% \texdefinition{btx:apa:author-or-key-and-year} +% \texdefinition{btx:apa:title-it-and-series} +% \texdefinition{btx:apa:edition:sentence} +% \texdefinition{btx:apa:publication:sentence} +% \texdefinition{btx:apa:pages:p} +% \texdefinition{btx:apa:note} +%\stopsetups +% +%\startsetups btx:apa:manual +% \texdefinition{btx:apa:author-or-key-and-year} +% \texdefinition{btx:apa:title-it-and-series} +% \texdefinition{btx:apa:edition:sentence} +% \texdefinition{btx:apa:wherefrom}{organization} +% \texdefinition{btx:apa:pages:p} +% \texdefinition{btx:apa:note} +%\stopsetups +% %\startsetups btx:apa:incollection % \texdefinition{btx:apa:author-and-year} % \btxdoifelse {arttitle} { @@ -1273,7 +1473,7 @@ % } % \texdefinition{btx:apa:note} %\stopsetups - +% %\startsetups btx:apa:inproceedings % \texdefinition{btx:apa:author-and-year} % \btxdoif {arttitle} { @@ -1333,7 +1533,7 @@ % } % \texdefinition{btx:apa:note} %\stopsetups - +% %\startsetups btx:apa:proceedings % \texdefinition{btx:apa:editor-or-key-and-year} % \btxdoif {title} { @@ -1359,7 +1559,7 @@ % } % \texdefinition{btx:apa:note} %\stopsetups - +% %\starttexdefinition btx:apa:thesis % \texdefinition{btx:apa:author-and-year} % \texdefinition{btx:apa:title-it-and-series} @@ -1380,95 +1580,42 @@ %\startsetups btx:apa:phdthesis % \texdefinition{btx:apa:thesis} %\stopsetups - -% A report published by a school or other institution, usually numbered within a series. -% Required fields: author, title, institution, year. -% Optional fields: type, number, address, month, note. - -\startsetups btx:apa:techreport - \texdefinition{btx:apa:author-and-year} - \texdefinition{btx:apa:title-and-series} - \btxdoifelse {type} { - \btxflush{type} - \btxdoif {volume} { - \btxspace - \btxflush{volume} - } - } { - \btxspace - \btxlabeltext{apa:technicalreport} - } - \btxcomma - \texdefinition{btx:apa:wherefrom}{institution} - \texdefinition{btx:apa:pages:p} - \texdefinition{btx:apa:url-note-doi} -\stopsetups - -\startsetups btx:apa:patent - \texdefinition{btx:apa:author-and-year} - \btxdoif {title} { - \btxspace - %texdefinition{btx:apa:italic}{converters.Word -> title} - \texdefinition{btx:apa:italic}{Word -> title} - } - \btxdoif {nationality} { - \btxspace - \btxflush{nationality} - } - \btxspace - \btxlabeltext{apa:patent} - \btxdoif {number} { - \btxspace - \btxflush{number} - } - \texdefinition{btx:apa:wherefrom}{publisher} - \texdefinition{btx:apa:note} -\stopsetups - -% Use this type when nothing else fits. -% Required fields: none. -% Optional fields: author, title, howpublished, month, year, note. - -\startsetups btx:apa:misc - \texdefinition{btx:apa:author-and-year} - \texdefinition{btx:apa:title-and-series} - \texdefinition{btx:apa:wherefrom}{publisher} - \texdefinition{btx:apa:pages:p} - \texdefinition{btx:apa:note} -\stopsetups - -% A document having an author and title, but not formally published. -% Required fields: author, title, note. -% Optional fields: month, year. - -\startsetups btx:apa:unpublished - \texdefinition{btx:apa:author-and-year} - \texdefinition{btx:apa:title-and-series} - \texdefinition{btx:apa:pages:p} - \btxdoif {type} { - \btxleftparenthesis - \btxflush{type} - \btxrightparenthesis - } - \texdefinition{btx:apa:note} -\stopsetups - -% If all else fails to match: - -\startsetups btx:apa:literal - \btxdoif {text} { - \btxflush{text} - } -\stopsetups - -%D Experiment: - -\startsetups btx:apa:lefttext - \currentbtxlefttext -\stopsetups - -\startsetups btx:apa:righttext - \currentbtxrighttext -\stopsetups - -\stopbtxrenderingdefinitions +% +%\startsetups btx:apa:techreport +% \texdefinition{btx:apa:author-and-year} +% \texdefinition{btx:apa:title-and-series} +% \btxdoifelse {type} { +% \btxflush{type} +% \btxdoif {volume} { +% \btxspace +% \btxflush{volume} +% } +% } { +% \btxspace +% \btxlabeltext{apa:technicalreport} +% } +% \btxcomma +% \texdefinition{btx:apa:wherefrom}{institution} +% \texdefinition{btx:apa:pages:p} +% \texdefinition{btx:apa:url-note-doi} +%\stopsetups +% +%\startsetups btx:apa:misc +% \texdefinition{btx:apa:author-and-year} +% \texdefinition{btx:apa:title-and-series} +% \texdefinition{btx:apa:wherefrom}{publisher} +% \texdefinition{btx:apa:pages:p} +% \texdefinition{btx:apa:note} +%\stopsetups +% +%\startsetups btx:apa:unpublished +% \texdefinition{btx:apa:author-and-year} +% \texdefinition{btx:apa:title-and-series} +% \texdefinition{btx:apa:pages:p} +% \btxdoif {type} { +% \btxleftparenthesis +% \btxflush{type} +% \btxrightparenthesis +% } +% \texdefinition{btx:apa:note} +%\stopsetups diff --git a/tex/context/base/publ-imp-aps.lua b/tex/context/base/publ-imp-aps.lua index 97b00b34a..a918c755d 100644 --- a/tex/context/base/publ-imp-aps.lua +++ b/tex/context/base/publ-imp-aps.lua @@ -12,24 +12,24 @@ return { optional = { "volume", "number", "pages", "month", "note" }, }, book = { - required = { { "author", "editor" }, "title", "publisher", "year" }, - optional = { { "volume", "number" }, "series", "address", "edition", "month","note" }, + required = { "author", "editor", "title", "publisher", "year" }, + optional = { "volume", "number", "series", "address", "edition", "month","note" }, }, booklet = { required = { "title" }, optional = { "author", "howpublished", "address", "month", "year", "note" }, }, inbook = { - required = { { "author", "editor" }, "title", { "chapter", "pages" }, "publisher","year" }, - optional = { { "volume", "number" }, "series", "type", "address", "edition", "month", "note" }, + required = { "author", "editor", "title", "chapter", "pages", "publisher","year" }, + optional = { "volume", "number", "series", "type", "address", "edition", "month", "note" }, }, incollection = { required = { "author", "title", "booktitle", "publisher", "year" }, - optional = { "editor", { "volume", "number" }, "series", "type", "chapter", "pages", "address", "edition", "month", "note" }, + optional = { "editor", "volume", "number", "series", "type", "chapter", "pages", "address", "edition", "month", "note" }, }, inproceedings = { required = { "author", "title", "booktitle", "year" }, - optional = { "editor", { "volume", "number" }, "series", "pages", "address", "month","organization", "publisher", "note" }, + optional = { "editor", "volume", "number", "series", "pages", "address", "month","organization", "publisher", "note" }, }, manual = { required = { "title" }, @@ -49,7 +49,7 @@ return { }, proceedings = { required = { "title", "year" }, - optional = { "editor", { "volume", "number" }, "series", "address", "month", "organization", "publisher", "note" }, + optional = { "editor", "volume", "number", "series", "address", "month", "organization", "publisher", "note" }, }, techreport = { required = { "author", "title", "institution", "year" }, diff --git a/tex/context/base/publ-ini.lua b/tex/context/base/publ-ini.lua index a057c48fa..af83e100b 100644 --- a/tex/context/base/publ-ini.lua +++ b/tex/context/base/publ-ini.lua @@ -5,6 +5,8 @@ if not modules then modules = { } end modules ['publ-ini'] = { copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } +-- todo: delay details till alternative is known so that potential author +-- fields are known -- If we define two datasets with the same bib file we can consider -- sharing the data but that means that we need to have a parent which @@ -89,6 +91,7 @@ manipulatormethods.Words = converters.Words manipulatormethods.WORDS = converters.WORDS local context = context +local commands = commands local ctx_setvalue = context.setvalue local ctx_firstoftwoarguments = context.firstoftwoarguments @@ -134,6 +137,20 @@ local ctx_btxstartsubcite = context.btxstartsubcite local ctx_btxstopsubcite = context.btxstopsubcite local ctx_btxlistsetup = context.btxlistsetup +local specifications = publications.specifications +local currentspecification = specifications[false] +local currentspecificationfields = currentspecification.fields +local currentspecificationcategories = currentspecification.categories + +local function setspecification(name) + currentspecification = specifications[name] + currentspecificationfields = currentspecification.fields + currentspecificationcategories = currentspecification.categories +end + +publications.setspecification = setspecification +commands.setbtxspecification = setspecification + local optionalspace = lpeg.patterns.whitespace^0 local prefixsplitter = optionalspace * lpeg.splitat(optionalspace * P("::") * optionalspace) @@ -846,21 +863,24 @@ function commands.btxflush(name,tag,field) if dataset then local fields = dataset.luadata[tag] if fields then - local manipulator, field = splitmanipulation(field) - local value = fields[field] - if type(value) == "string" then - context(manipulator and applymanipulation(manipulator,value) or value) - return - end - local details = dataset.details[tag] - if details then - local value = details[field] + local category = fields.category + if currentspecificationfields[category][field] then + local manipulator, field = splitmanipulation(field) + local value = fields[field] if type(value) == "string" then context(manipulator and applymanipulation(manipulator,value) or value) return end + local details = dataset.details[tag] + if details then + local value = details[field] + if type(value) == "string" then + context(manipulator and applymanipulation(manipulator,value) or value) + return + end + end + report("unknown field %a of tag %a in dataset %a",field,tag,name) end - report("unknown field %a of tag %a in dataset %a",field,tag,name) else report("unknown tag %a in dataset %a",tag,name) end @@ -874,12 +894,15 @@ function commands.btxdetail(name,tag,field) if dataset then local details = dataset.details[tag] if details then - local manipulator, field = splitmanipulation(field) - local value = details[field] - if type(value) == "string" then - context(manipulator and applymanipulation(manipulator,value) or value) - else - report("unknown detail %a of tag %a in dataset %a",field,tag,name) + local category = fields.category + if currentspecificationfields[category][field] then + local manipulator, field = splitmanipulation(field) + local value = details[field] + if type(value) == "string" then + context(manipulator and applymanipulation(manipulator,value) or value) + else + report("unknown detail %a of tag %a in dataset %a",field,tag,name) + end end else report("unknown tag %a in dataset %a",tag,name) @@ -894,12 +917,15 @@ function commands.btxfield(name,tag,field) if dataset then local fields = dataset.luadata[tag] if fields then - local manipulator, field = splitmanipulation(field) - local value = fields[field] - if type(value) == "string" then - context(manipulator and applymanipulation(manipulator,value) or value) - else - report("unknown field %a of tag %a in dataset %a",field,tag,name) + local category = fields.category + if currentspecificationfields[category][field] then + local manipulator, field = splitmanipulation(field) + local value = fields[field] + if type(value) == "string" then + context(manipulator and applymanipulation(manipulator,value) or value) + else + report("unknown field %a of tag %a in dataset %a",field,tag,name) + end end else report("unknown tag %a in dataset %a",tag,name) @@ -916,18 +942,21 @@ local function found(name,tag,field,yes) if dataset then local data = dataset.luadata[tag] if data then - local value = data[field] - if value then - if value ~= "" then - return true - end - else - local data = dataset.details[tag] - if data then - local value = data[field] - if value then - if value ~= "" then - return true + local category = data.category + if currentspecificationfields[category][field] then + local value = data[field] + if value then + if value ~= "" then + return true + end + else + local data = dataset.details[tag] + if data then + local value = data[field] + if value then + if value ~= "" then + return true + end end end end @@ -1197,9 +1226,9 @@ function lists.collectentries(specification) rendering.method = method rendering.list = { } rendering.done = { } - rendering.sorttype = specification.sorttype or v_default + rendering.sorttype = specification.sorttype or v_default rendering.criterium = specification.criterium or v_none - rendering.repeated = specification.repeated or v_no + rendering.repeated = specification.repeated or v_no rendering.specification = specification local filtermethod = methods[method] if not filtermethod then @@ -1426,10 +1455,13 @@ end -- for rendering +-- setspecification + function lists.flushentries(dataset,textmode) local rendering = renderings[dataset] local list = rendering.list local luadata = datasets[dataset].luadata + -- maybe a startflushing here for i=1,#list do local li = list[i] local tag = li[1] @@ -1474,7 +1506,8 @@ function lists.flushentries(dataset,textmode) else ctx_btxhandlelistentry() end - end + end + setspecification(false) end -- function lists.flushentry(specification) @@ -1739,19 +1772,24 @@ local f_missing = formatters["<%s>"] -- maybe also sparse (e.g. pages) +-- a bit redundant sccess to datasets + local function processcite(dataset,reference,mark,compress,setup,internal,getter,setter,compressor) reference = publications.parenttag(dataset,reference) local found, todo, list = findallused(dataset,reference,internal) tobemarked = mark and todo --- if type(tobemarked) ~= "table" then --- tobemarked = { } --- end if found and setup then local source = { } local badkey = false for i=1,#found do local entry = found[i] local tag = entry.userdata.btxref + +-- we can probably move the test into the flush + +local category = datasets[dataset].luadata[tag].category +if currentspecificationfields[category][setup] then + local internal = entry.references.internal local data = getter(dataset,tag,entry,internal) if compress and not compressor then @@ -1767,7 +1805,12 @@ local function processcite(dataset,reference,mark,compress,setup,internal,getter badkey = true end end - source[i] = data + source[#source+1] = data + +else + report("cite rendering %a is not available for %a",setup,category) +end + end local function flush(i,n,entry,last) @@ -2108,6 +2151,8 @@ end do + local getauthor = publications.authors.getauthor + local currentbtxciteauthor = function() context.currentbtxciteauthor() return true -- needed? @@ -2117,27 +2162,31 @@ do local result = { } local entries = { } for i=1,#found do - local entry = found[i] - local author = entry.author - local aentries = entries[author] - if aentries then - aentries[#aentries+1] = entry - else - entries[author] = { entry } + local entry = found[i] + local author = entry.author + if author then + local aentries = entries[author] + if aentries then + aentries[#aentries+1] = entry + else + entries[author] = { entry } + end end end for i=1,#found do - local entry = found[i] - local author = entry.author - local aentries = entries[author] - if not aentries then - result[#result+1] = entry - elseif aentries == true then - -- already done - else - result[#result+1] = entry - entry.entries = aentries - entries[author] = true + local entry = found[i] + local author = entry.author + if author then + local aentries = entries[author] + if not aentries then + result[#result+1] = entry + elseif aentries == true then + -- already done + else + result[#result+1] = entry + entry.entries = aentries + entries[author] = true + end end end -- todo: add letters (should we then tag all?) @@ -2164,7 +2213,9 @@ do ctx_btxsetfirst(first[key] or f_missing(first.tag)) local suffix = entry.suffix local value = entry.last[key] - ctx_btxsetsecond(value) + if value then + ctx_btxsetsecond(value) + end if suffix then ctx_btxsetthird(suffix) end @@ -2231,7 +2282,7 @@ do dataset = dataset, tag = tag, internal = internal, - author = getfield(dataset,tag,"author"), + author = getauthor(dataset,tag,currentspecificationcategories), -- todo: list } end @@ -2253,7 +2304,7 @@ do dataset = dataset, tag = tag, internal = internal, - author = getfield(dataset,tag,"author"), + author = getauthor(dataset,tag,currentspecificationcategories), -- todo: list num = text, sortkey = text and lpegmatch(numberonly,text), } @@ -2279,7 +2330,7 @@ do dataset = dataset, tag = tag, internal = internal, - author = getfield(dataset,tag,"author"), + author = getauthor(dataset,tag,currentspecificationcategories), -- todo: list year = getfield(dataset,tag,"year"), suffix = getdetail(dataset,tag,"suffix"), sortkey = getdetail(dataset,tag,"suffixedyear"), diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv index 65231a09a..254c99994 100644 --- a/tex/context/base/publ-ini.mkiv +++ b/tex/context/base/publ-ini.mkiv @@ -11,6 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +% todo: tagging % todo: we cannot use 'default' as this wipes metadata names (maybe no longer do that) % todo: \v!cite => \s!cite % todo: interface with (ml)bibtex (export -> call -> import) @@ -44,16 +45,14 @@ \registerctxluafile{publ-oth}{1.001} % this could become an option \registerctxluafile{publ-fnd}{1.001} % new method (for the moment only local) \registerctxluafile{publ-jrn}{1.001} +\registerctxluafile{publ-reg}{1.001} \unprotect \startcontextdefinitioncode \def\s!btx {btx} -\def\s!cite {cite} -\def\s!nocite {nocite} -\def\s!list {list} -\def\s!author {author} + \def\v!btxcite {btxcite} \def\v!btxlist {btxlist} \def\v!btxrendering {btxrendering} @@ -67,6 +66,77 @@ \definelabelclass[btxlabel][2] +% It is not that trivail to come up with a proper organization of setup +% and control commands for publications. This is because we have complex +% inline as well as extensive list rendering. The rules are partially +% driven by somewhat archaic bibtex specifications and evolving journal +% (or field) specific demands. The logic in the standards is often so +% complex that it looks like manual rendering is assumed. But, we want to +% automate the process as much as possible. +% +% Another complication is that in manuals we want to demonstate different +% properties of the implementation and therefore we need a way to handle +% independent standards, databases, etc. This has resulted in the following +% organization: +% +% - general setup (rather minimal) +% - list setup (rendering) +% - cite setup +% - dataset setup +% +% The rendering is mostly driven by setups. In there we can call for fields +% in the database but also for virtual fields or combinations. + +% The main rendering style (standard driven). + +\installcorenamespace {btx} + +\installsetuphandler \??btx {btx} +% \installcommandhandler \??btx {btx} \??btx + +% \setupbtx +% [\c!alternative=apa] + +% \newconstant\btxmode +% \newconstant\btxnonemode +% \newconstant\btxcitemode +% \newconstant\btxlistmode + +%D Loading variants: + +\let\currentbtxrenderingdefinition\empty +\let\currentbtxalternative \empty + +\unexpanded\def\startbtxrenderingdefinitions[#1]% + {\pushmacro\currentbtxrenderingdefinition + \edef\currentbtxrenderingdefinition{#1}% + \letvalue{\??btxrenderingdefinition\currentbtxrenderingdefinition}\currentbtxrenderingdefinition} + +\unexpanded\def\stopbtxrenderingdefinitions + {\popmacro\currentbtxrenderingdefinition} + +\unexpanded\def\loadbtxdefinitionfile[#1]% + {\ctxcommand{loadbtxdefinitionfile("#1")}} + +% \appendtoks +% \loadbtxdefinitionfile[\btxrenderingparameter\c!alternative] +% \to \everysetupbtxrendering + +\let\currentbtxalternative\empty + +\appendtoks + \edef\currentbtxalternative{\btxrenderingparameter\c!alternative}% + \ifcsname\??btxrenderingdefinition\currentbtxalternative\endcsname + % maybe fall back on apa ? + \else + \loadbtxdefinitionfile[\currentbtxalternative]% + \showmessage\m!publications{14}{\currentbtxalternative}% + \fi +\to \everysetupbtx + +\def\btx_set_rendering_alternative + {\ctxcommand{setbtxspecification("\currentbtxalternative")}} + % a dedicated construction mechanism \installcorenamespace {btxlist} @@ -76,6 +146,7 @@ \unexpanded\setvalue{\??constructioninitializer\v!btxlist}% {\let\currentbtxlist \currentconstruction \let\constructionparameter \btxlistparameter + \let\constructionnamespace \??btxlist \let\detokenizedconstructionparameter\detokenizedbtxlistparameter \let\letconstructionparameter \letbtxlistparameter \let\useconstructionstyleandcolor \usebtxliststyleandcolor @@ -209,12 +280,14 @@ \installcorenamespace {btxlistvariant} \installcorenamespace {btxcitevariant} \installcorenamespace {btxrendering} +\installcorenamespace {btxregister} \installcorenamespace {btxcommand} \installcorenamespace {btxrenderingdefinition} \installcommandhandler \??btxdataset {btxdataset} \??btxdataset \installcommandhandler \??btxlistvariant {btxlistvariant} \??btxlistvariant \installcommandhandler \??btxcitevariant {btxcitevariant} \??btxcitevariant +\installcommandhandler \??btxregister {btxregister} \??btxregister \installcommandhandler \??btxrendering {btxrendering} \??btxrendering \appendtoks @@ -474,11 +547,6 @@ \unexpanded\def\btxtodo#1% {[#1]} -%D Specific rendering definitions (like apa): - -\unexpanded\def\loadbtxdefinitionfile[#1]% - {\ctxcommand{loadbtxdefinitionfile("#1")}} - %D Lists: \newdimen\d_publ_number_width @@ -618,14 +686,14 @@ \startpacked[\v!blank]% % here we just collect items \ctxcommand{btxcollectlistentries { - names = "btx", - criterium = "\currentbtxcriterium", - method = "\btxrenderingparameter\c!method", - number = "\btxrenderingparameter\c!number", - btxdataset = "\currentbtxdataset", - keyword = "\btxrenderingparameter\c!keyword", - sorttype = "\btxrenderingparameter\c!sorttype", - repeated = "\btxrenderingparameter\c!repeat", + names = "btx", + criterium = "\currentbtxcriterium", + method = "\btxrenderingparameter\c!method", + number = "\btxrenderingparameter\c!number", + btxdataset = "\currentbtxdataset", + keyword = "\btxrenderingparameter\c!keyword", + sorttype = "\btxrenderingparameter\c!sorttype", + repeated = "\btxrenderingparameter\c!repeat", }}% % sorting and so \ctxcommand{btxpreparelistentries("\currentbtxdataset")}% @@ -720,8 +788,11 @@ \fi \fi} +\newtoks\t_btx_reference_inject + \def\btx_cite_reference_inject_indeed {\btx_trace_list_cross\currentbtxbacklink\empty + \the\t_btx_reference_inject \normalexpanded{\writedatatolist [\s!btx]% [\s!btxset=\currentbtxdataset,% @@ -1086,31 +1157,6 @@ \let\btxsingularorplural\btxsingularplural -%D Loading variants: - -\let\currentbtxrenderingdefinition\empty -\let\currentbtxalternative \empty - -\unexpanded\def\startbtxrenderingdefinitions[#1]% - {\pushmacro\currentbtxrenderingdefinition - \edef\currentbtxrenderingdefinition{#1}% - \letvalue{\??btxrenderingdefinition\currentbtxrenderingdefinition}\currentbtxrenderingdefinition} - -\unexpanded\def\stopbtxrenderingdefinitions - {\popmacro\currentbtxrenderingdefinition} - -\def\btx_set_rendering_alternative - {\edef\currentbtxalternative{\btxrenderingparameter\c!alternative}% - \ifcsname\??btxrenderingdefinition\currentbtxalternative\endcsname - % maybe fall back on apa ? - \else - \showmessage\m!publications{14}{\currentbtxalternative}% - \fi} - -\appendtoks - \loadbtxdefinitionfile[\btxrenderingparameter\c!alternative] -\to \everysetupbtxrendering - \stopcontextdefinitioncode %D Journals @@ -1190,7 +1236,6 @@ \unexpanded\def\btxhandleciteentry {\dontleavehmode \begingroup - %\edef\currentbtxalternative{apa}% \btxlistvariantparameter\c!alternative}% \btx_set_rendering_alternative \btxcitereference \btx_entry_inject @@ -1206,22 +1251,35 @@ %D Registers -\def\btx_cite_reference_inject_indeed - {\btx_trace_list_cross\currentbtxbacklink\empty - % - \edef\p_register{\btxcitevariantparameter\c!register}% - \ifx\p_register\empty\else - \ctxcommand{btxauthortoregister("\p_register","\currentbtxdataset","\currentbtxtag")}% - \fi - % - \normalexpanded{\writedatatolist - [\s!btx]% - [\s!btxset=\currentbtxdataset,% - \s!btxref=\currentbtxtag,% - \ifx\p_publ_cite_lefttext \empty\else\s!btxltx={\p_publ_cite_lefttext },\fi% - \ifx\p_publ_cite_righttext\empty\else\s!btxrtx={\p_publ_cite_righttext},\fi% - \s!btxint=\number\currentbtxbacklink - \ifx\currentbtxciteuservariables\empty\else,\currentbtxciteuservariables\fi]}} +% \setupbtxregister +% [\c!state=\v!start, +% \c!dataset=\v!all, +% \c!method=\v!always] + +\unexpanded\def\publ_registers_set + {\ifx\currentbtxregister\empty \else + \ctxcommand{setbtxregister { + name = "\currentbtxregister", + state = "\btxregisterparameter\c!state", + dataset = "\btxregisterparameter\c!dataset", + field = "\btxregisterparameter\c!field", + register = "\btxregisterparameter\c!register", + method = "\btxregisterparameter\c!method", + alternative = "\btxregisterparameter\c!alternative", + }}% + \fi} + +\appendtoks + \publ_registers_set +\to \everydefinebtxregister + +\appendtoks + \publ_registers_set +\to \everysetupbtxregister + +\appendtoks + \ctxcommand{btxtoregister("\currentbtxdataset","\currentbtxtag")}% +\to \t_btx_reference_inject \unexpanded\def\dosetfastregisterentry#1#2#3% register entry key {\begingroup @@ -1240,21 +1298,34 @@ \dostoptagged \endgroup} -\unexpanded\def\btx_flush_specific_author#1#2#3#4% dataset tag field index +\unexpanded\def\btx_flush_specific_field#1#2#3#4#5% dataset tag field variant value + {\begingroup + \edef\currentbtxdataset{#1}% + \edef\currentbtxtag {#2}% + \edef\currentbtxfield {#3}% + \let\currentbtxlistvariant\currentbtxfield + \edef\currentbtxcitevariant{#4}% + \usebtxregisterstyleandcolor\c!style\c!color + \edef\tempstring{\currentbtxalternative:register:\currentbtxcitevariant}% + \doifsetupselse\tempstring{\fastsetup\tempstring}{#5}% + \endgroup} + +\unexpanded\def\btx_flush_specific_author#1#2#3#4#5% dataset tag field variantindex {\begingroup \edef\currentbtxdataset{#1}% \edef\currentbtxtag {#2}% \edef\currentbtxfield {#3}% \let\currentbtxlistvariant\currentbtxfield - \edef\currentbtxcitevariant{invertedshort}% + \edef\currentbtxcitevariant{#4}% \ctxcommand{btxauthor("\currentbtxdataset","\currentbtxtag","\currentbtxfield",{ kind = "list", - index = \number#4, + index = \number#5, combiner = "\currentbtxcitevariant", })}% \endgroup} -\let\dobtxindexedauthor\btx_flush_specific_author +\let\dobtxindexedfield \btx_flush_specific_field % used at lua end +\let\dobtxindexedauthor\btx_flush_specific_author % used at lua end %D Defaults: @@ -1480,6 +1551,7 @@ \loadbtxdefinitionfile[list] \loadbtxdefinitionfile[author] -\loadbtxdefinitionfile[apa] +\setupbtx + [\c!alternative=apa] \protect diff --git a/tex/context/base/publ-reg.lua b/tex/context/base/publ-reg.lua new file mode 100644 index 000000000..6b9cc9234 --- /dev/null +++ b/tex/context/base/publ-reg.lua @@ -0,0 +1,131 @@ +if not modules then modules = { } end modules ['publ-reg'] = { + version = 1.001, + comment = "this module part of publication support", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local formatters = string.formatters +local sortedhash = table.sortedhash + +local context = context +local commands = commands + +local variables = interfaces.variables + +local v_once = variables.once +local v_standard = variables.standard +local v_stop = variables.stop +local v_all = variables.all + +local datasets = publications.datasets +local specifications = { } +local sequence = { } +local flushers = { } + +function commands.setbtxregister(specification) + local name = specification.name or "unset" + local register = specification.register + local dataset = specification.dataset + local field = specification.field + if not field or field == "" or not register or register == "" then + return + end + if not dataset or dataset == "" then + dataset = v_all + end + -- could be metatable magic + local s = specifications[register] + if not s then + s = { } + specifications[register] = s + end + local d = s[dataset] + if not d then + d = { } + s[dataset] = d + end + -- + -- check all + -- + local alternative = specification.alternative or d.alternative + if not alternative or alternative == "" then + alternative = field + end + -- + d.active = specification.state ~= v_stop + d.once = specification.method == v_once or false + d.field = field + d.alternative = alternative + d.register = register + d.dataset = dataset + d.done = d.done or { } + -- + sequence = { } + for register, s in sortedhash(specifications) do + for dataset, d in sortedhash(s) do + if d.active then + sequence[#sequence+1] = d + end + end + end +end + +function commands.btxtoregister(dataset,tag) + for i=1,#sequence do + local step = sequence[i] + local dset = step.dataset + if dset == v_all or dset == dataset then + local done = step.done + if not done[tag] then + local current = datasets[dataset] + local entry = current.luadata[tag] + if entry then + local register = step.register + local field = step.field + local alternative = step.alternative + local flusher = flushers[field] or flushers.default + flusher(register,dataset,tag,field,alternative,current,entry,current.details[tag]) + end + done[tag] = true + end + end + end +end +-- context.setregisterentry ( +-- { register }, +-- { +-- ["entries:1"] = value, +-- ["keys:1"] = value, +-- } +-- ) + +local ctx_dosetfastregisterentry = context.dosetfastregisterentry -- register entry key + +local f_field = formatters[ [[\dobtxindexedfield{%s}{%s}{%s}{%s}{%s}]] ] +local f_author = formatters[ [[\dobtxindexedauthor{%s}{%s}{%s}{%s}{%s}]] ] + +local writer = publications.serializeauthor + +function flushers.default(register,dataset,tag,field,alternative,current,entry,detail) + local value = detail[field] or entry[field] + if value then + local e = f_field(dataset,tag,field,alternative,value) + ctx_dosetfastregisterentry(register,e,value) -- last value can be "" + end +end + +function flushers.author(register,dataset,tag,field,alternative,current,entry,detail) + if detail then + local author = detail[field] + if author then + for i=1,#author do + local a = author[i] + local k = writer{a} + local e = f_author(dataset,tag,field,alternative,i) + ctx_dosetfastregisterentry(register,e,k) + end + end + end +end diff --git a/tex/context/base/publ-tra.lua b/tex/context/base/publ-tra.lua index 7f1626782..34a678459 100644 --- a/tex/context/base/publ-tra.lua +++ b/tex/context/base/publ-tra.lua @@ -22,39 +22,6 @@ local ctx_bold, ctx_rotate, ctx_llap = context.bold, context.rotate, context.lla local ctx_darkgreen, ctx_darkred, ctx_darkblue = context.darkgreen, context.darkred, context.darkblue local ctx_starttabulate, ctx_stoptabulate = context.starttabulate, context.stoptabulate -local categories = table.setmetatableindex(function(t,name) - local filename = resolvers.findfile(formatters["publ-imp-%s.lua"](name)) - local fields = { } - local specification = filename and filename ~= "" and table.load(filename) or { - name = name, - version = "1.00", - comment = "unknown specification.", - author = "anonymous", - copyright = "no one", - categories = { }, - } - -- - specification.fields = fields - for category, data in next, specification.categories do - local list = { } - fields[category] = list - local required = data.required - local optional = data.optional - for i=1,#required do - list[required[i]] = "required" - end - for i=1,#optional do - list[optional[i]] = "optional" - end - end - t[name] = specification - return specification -end) - -publications.tracers.categories = categories - --- -- -- - local private = { category = true, tag = true, @@ -173,6 +140,7 @@ function tracers.showdatasetcompleteness(settings) for i=1,#requiredfields do local r = requiredfields[i] if type(r) == "table" then + -- this has to be done differently now local okay = true for i=1,#r do local ri = r[i] @@ -200,6 +168,7 @@ function tracers.showdatasetcompleteness(settings) for i=1,#optionalfields do local o = optionalfields[i] if type(o) == "table" then + -- this has to be done differently now for i=1,#o do local oi = o[i] if rawget(entry,oi) then diff --git a/tex/context/base/spac-lin.mkiv b/tex/context/base/spac-lin.mkiv index 094e18e0b..5ed9d718a 100644 --- a/tex/context/base/spac-lin.mkiv +++ b/tex/context/base/spac-lin.mkiv @@ -88,7 +88,7 @@ \linesparameter\c!before \pushmacro\checkindentation \whitespace - \dostarttagged\t!lines\currentlines + \dostarttaggedchained\t!lines\currentlines\??lines \begingroup \uselinesstyleandcolor\c!style\c!color \setupindenting[\linesparameter\c!indenting]% diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex 6025bdecb..7d2f9fa03 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf Binary files differindex 5005381c5..7249deb2b 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/strc-con.mkvi b/tex/context/base/strc-con.mkvi index b04f9231d..e32c3dd61 100644 --- a/tex/context/base/strc-con.mkvi +++ b/tex/context/base/strc-con.mkvi @@ -159,6 +159,7 @@ \unexpanded\def\strc_constructions_initialize#1% class instance {\edef\currentconstruction{#1}% + \let\currentconstructionhash\??construction \let\currentconstructionlistentry\!!zerocount \expandafter\let\expandafter\currentconstructionmain \csname\??constructionmain \currentconstruction\endcsname \expandafter\let\expandafter\currentconstructionlevel \csname\??constructionlevel\currentconstruction\endcsname @@ -264,8 +265,10 @@ {\constructionsheaddistance\zeropoint \constructionsheadwidth \zeropoint} +\let\currentconstructionhash\??construction + \unexpanded\setvalue{\??constructionstarthandler\v!construction}% this will be redone (reorganized) .. too much boxing - {\dostarttagged\t!construction\currentconstruction + {\dostarttaggedchained\t!construction\currentconstruction\currentconstructionhash \dotagsetconstruction \constructionparameter\c!before \begingroup diff --git a/tex/context/base/strc-des.mkvi b/tex/context/base/strc-des.mkvi index fa20d3cae..81cd6ee52 100644 --- a/tex/context/base/strc-des.mkvi +++ b/tex/context/base/strc-des.mkvi @@ -76,6 +76,7 @@ \unexpanded\setvalue{\??constructioninitializer\v!description}% {\let\currentdescription \currentconstruction \let\constructionparameter \descriptionparameter + \let\constructionnamespace \??description \let\detokenizedconstructionparameter\detokenizeddescriptionparameter \let\letconstructionparameter \letdescriptionparameter \let\useconstructionstyleandcolor \usedescriptionstyleandcolor diff --git a/tex/context/base/strc-enu.mkvi b/tex/context/base/strc-enu.mkvi index 0a01d2637..ae122b658 100644 --- a/tex/context/base/strc-enu.mkvi +++ b/tex/context/base/strc-enu.mkvi @@ -183,6 +183,7 @@ \unexpanded\setvalue{\??constructioninitializer\v!enumeration}% {\let\currentenumeration \currentconstruction \let\constructionparameter \enumerationparameter + \let\constructionnamespace \??enumeration \let\detokenizedconstructionparameter\detokenizedenumerationparameter \let\letconstructionparameter \letenumerationparameter \let\useconstructionstyleandcolor \useenumerationstyleandcolor diff --git a/tex/context/base/strc-flt.mkvi b/tex/context/base/strc-flt.mkvi index 3f3c1fedf..ef4eae71c 100644 --- a/tex/context/base/strc-flt.mkvi +++ b/tex/context/base/strc-flt.mkvi @@ -204,8 +204,8 @@ {\definefloatcaption[#1][#3]% \definecounter[#1][#3]% \definelist[#1][#3]% - \presetlabeltext[#1=\Word{#3}~]% - \presetheadtext[#2=\Word{#2}]% + \copylabeltext[#1=#3]% + %\presetheadtext[#2=\Word{#2}]% \strc_floats_define_saved[#1][#3]% \strc_floats_define_commands{#1}{#2}} @@ -661,7 +661,7 @@ \fi \page_margin_strc_floats_before % todo: each float handler gets a before \global\insidefloattrue - \dostarttagged\t!float\currentfloat + \dostarttaggedchained\t!float\currentfloat\??float \page_margin_strc_floats_set_hsize % todo: each float handler gets a set_hsize \the\everyinsidefloat \strc_floats_analyze_variables_one @@ -853,7 +853,7 @@ \relax \relax \relax - [\c!name=\currentfloat,% + [\s!name=\currentfloat,% was c!name \s!counter=\currentfloatcounter,% \s!hascaption=\ifnofloatcaption \v!no\else\v!yes\fi,% \s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,% diff --git a/tex/context/base/strc-itm.mkvi b/tex/context/base/strc-itm.mkvi index 098b863b9..4478c2d8d 100644 --- a/tex/context/base/strc-itm.mkvi +++ b/tex/context/base/strc-itm.mkvi @@ -485,7 +485,7 @@ \ifdefined\dotagsetitemgroup \else \let\dotagsetitemgroup\relax \fi \def\strc_itemgroups_tag_start_group - {\dostarttagged\t!itemgroup\currentitemgroup + {\dostarttaggedchained\t!itemgroup\currentitemgroup\??itemgroup \dotagsetitemgroup} \def\strc_itemgroups_tag_stop_group diff --git a/tex/context/base/strc-lab.mkiv b/tex/context/base/strc-lab.mkiv index 3e6617126..189c58272 100644 --- a/tex/context/base/strc-lab.mkiv +++ b/tex/context/base/strc-lab.mkiv @@ -113,6 +113,7 @@ \setvalue{\??constructioninitializer\v!label}% {\let\currentlabel \currentconstruction \let\constructionparameter \labelparameter + \let\constructionnamespace \??label \let\detokenizedconstructionparameter\detokenizedlabelparameter \let\letconstructionparameter \letlabelparameter \let\useconstructionstyleandcolor \uselabelstyleandcolor diff --git a/tex/context/base/strc-lst.mkvi b/tex/context/base/strc-lst.mkvi index bea547bcf..3a2526315 100644 --- a/tex/context/base/strc-lst.mkvi +++ b/tex/context/base/strc-lst.mkvi @@ -402,7 +402,7 @@ % TODO: pass extra tag name (contents, figures, bibliography ...) \unexpanded\def\strc_lists_place_current#list#criterium#number#extras#order% beware, not a user command - {\dostarttagged\t!list\empty + {\dostarttaggedchained\t!list\empty\??list \ctxcommand{processlist{ names = "#list", criterium = "#criterium", diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv index 18cb005cb..742cf00aa 100644 --- a/tex/context/base/strc-mat.mkiv +++ b/tex/context/base/strc-mat.mkiv @@ -528,7 +528,7 @@ \unexpanded\def\strc_formulas_start_formula_indeed[#1][#2]% setting leftskip adaption is slow ! {\bgroup % HERE \def\currentformula{#1}% - \dostarttagged\t!formula\currentformula + \dostarttaggedchained\t!formula\currentformula\??formula \the\everybeforedisplayformula \d_strc_formulas_display_skip_par\parskip\relax %\formulastrutdp\strutdepth @@ -564,7 +564,7 @@ \unexpanded\def\strc_formulas_start_formula_nested#1% {\bgroup \let\strc_formulas_stop_formula\strc_formulas_stop_formula_nested - \dostarttagged\t!subformula} + \dostarttagged\t!subformula\empty} \unexpanded\def\strc_formulas_stop_formula_nested {\dostoptagged diff --git a/tex/context/base/strc-not.mkvi b/tex/context/base/strc-not.mkvi index c97cf00ef..c1ea37bb5 100644 --- a/tex/context/base/strc-not.mkvi +++ b/tex/context/base/strc-not.mkvi @@ -181,6 +181,7 @@ \unexpanded\setvalue{\??constructioninitializer\v!notation}% {\let\currentnotation \currentconstruction \let\constructionparameter \notationparameter + \let\constructionnamespace \??notation \let\detokenizedconstructionparameter\detokenizednotationparameter \let\letconstructionparameter \letnotationparameter \let\useconstructionstyleandcolor \usenotationstyleandcolor diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv index 6802027e6..7c3ac17db 100644 --- a/tex/context/base/strc-num.mkiv +++ b/tex/context/base/strc-num.mkiv @@ -58,7 +58,8 @@ }}% \letcounterparameter\s!name\currentcounter \else - \letcounterparameter\s!name\currentcounterparent + % \letcounterparameter\s!name\currentcounterparent % we need a chained clone + \setexpandedcounterparameter\s!name{\namedcounterparameter\currentcounterparent\s!name}% \fi \strc_counters_check_setup \to \everydefinecounter diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv index aaa58ace4..9190abfcd 100644 --- a/tex/context/base/strc-reg.mkiv +++ b/tex/context/base/strc-reg.mkiv @@ -731,7 +731,7 @@ {\endgraf \begingroup \d_strc_registers_distance\registerparameter\c!distance\relax - \dostarttagged\t!register\currentregister + \dostarttaggedchained\t!register\currentregister\??register \forgeteverypar \forgetparindent \forgetparskip} diff --git a/tex/context/base/strc-sbe.mkiv b/tex/context/base/strc-sbe.mkiv index fc48307ec..e6f0282ee 100644 --- a/tex/context/base/strc-sbe.mkiv +++ b/tex/context/base/strc-sbe.mkiv @@ -65,7 +65,7 @@ \resetallstructuremarks \strc_sectionblock_get_environment\currentsectionblock \sectionblockparameter\c!before % don't move - \dostarttagged\t!division\currentsectionblock + \dostarttagged\t!division\currentsectionblock % no parents \to \everybeforesectionblock \appendtoks diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv index fc02a208a..a55a8951b 100644 --- a/tex/context/base/strc-sec.mkiv +++ b/tex/context/base/strc-sec.mkiv @@ -995,14 +995,14 @@ \def\strc_sectioning_before_yes {\strc_sectioning_check_before\strc_sectioning_handle_page_yes \headparameter\c!inbetween - \dostarttagged\t!section\currenthead + \dostarttaggedchained\t!section\currenthead\??head % \dotagsectionlevel } \def\strc_sectioning_before_nop {\strc_sectioning_check_before\strc_sectioning_handle_page_nop \headparameter\c!inbetween - \dostarttagged\currenthead\empty} + \dostarttagged\currenthead\empty} % this is a weird one .. needs checking \def\strc_sectioning_empty_correction {\ifconditional\c_strc_sectioning_empty diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv index baf5cef7b..b69139afb 100644 --- a/tex/context/base/strc-syn.mkiv +++ b/tex/context/base/strc-syn.mkiv @@ -100,6 +100,7 @@ \setuvalue{\??constructioninitializer\v!simplelist}% {\let\currentsimplelist \currentconstruction \let\constructionparameter \simplelistparameter + \let\constructionnamespace \??simplelist \let\detokenizedconstructionparameter\detokenizedsimplelistparameter \let\letconstructionparameter \letsimplelistparameter \let\useconstructionstyleandcolor \usesimpleliststyleandcolor @@ -231,7 +232,7 @@ \edef\currentsimplelist{#1}% \let\currentsynonym\currentsimplelist % for a while \def\currentsynonymtag{#2}% - \dostarttagged\t!synonym\currentsynonym + \dostarttaggedchained\t!synonym\currentsynonym\??simplelist \dotagsynonym \usesimpleliststyleandcolor\c!synonymstyle\c!synonymcolor \simplelistparameter\c!synonymcommand{\ctxcommand{synonymname("#1","#2")}}% @@ -359,7 +360,7 @@ \edef\currentsorting{#1}% \def\currentsortingtag{#2}% \let\currentsimplelist\currentsorting - \dostarttagged\t!sorting\currentsorting + \dostarttaggedchained\t!sorting\currentsorting\??simplelist \dotagsorting \usesimpleliststyleandcolor\c!style\c!color \ctxcommand{synonymname("#1","#2")}% diff --git a/tex/context/base/strc-tag.lua b/tex/context/base/strc-tag.lua index 659c20d34..7b235957b 100644 --- a/tex/context/base/strc-tag.lua +++ b/tex/context/base/strc-tag.lua @@ -6,9 +6,12 @@ if not modules then modules = { } end modules ['strc-tag'] = { license = "see context related readme files" } --- This is rather experimental code. +-- This is rather experimental code. Tagging happens on the fly and there are two analysers +-- involved: the pdf backend tagger and the exporter. They share data but there are subtle +-- differences. Each tag carries a specification and these can be accessed by attribute (the +-- end of the chain tag) or by so called fullname which is a tagname combined with a number. -local type = type +local type, next = type, next local insert, remove, unpack, concat = table.insert, table.remove, table.unpack, table.concat local gsub, find, topattern, format = string.gsub, string.find, string.topattern, string.format local lpegmatch, P, S, C, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Cc @@ -28,36 +31,30 @@ local a_tagged = attributes.private('tagged') local unsetvalue = attributes.unsetvalue local codeinjections = backends.codeinjections -local taglist = allocate() -local properties = allocate() -local userproperties = allocate() +local taglist = allocate() -- access by attribute +local specifications = allocate() -- access by fulltag local labels = allocate() local stack = { } local chain = { } local ids = { } local enabled = false -local tagdata = { } -- used in export -local tagmetadata = { } -- used in export local tagcontext = { } local tagpatterns = { } +local lasttags = { } +local stacksize = 0 +local metadata = nil -- applied to the next element local tags = structures.tags tags.taglist = taglist -- can best be hidden tags.labels = labels -tags.data = tagdata -tags.metadata = tagmetadata tags.patterns = tagpatterns -tags.userproperties = userproperties -- used in backend +tags.specifications = specifications -- Tags are internally stored as: -- --- tag<detail>number> --- tag<detail>number> +-- tag>number tag>number tag>number -local p_splitter = C((1-S("<>"))^1) - * ( P("<")^-1 * C((1-P(">"))^1) + Cc(false)) - * P(">") - * C(P(1)^1) +local p_splitter = C((1-S(">"))^1) * P(">") * C(P(1)^1) tagpatterns.splitter = p_splitter local properties = allocate { @@ -199,43 +196,25 @@ local properties = allocate { combinationcaption = { pdf = "Span", nature = "mixed" }, } -local patterns_nop = setmetatableindex(function(t,tag) - local v = "^" .. tag .. ">" - t[tag] = v - return v -end) +tags.properties = properties -local patterns_yes = setmetatableindex(function(t,tag) - local v = setmetatableindex(function(t,detail) - local v = "^" .. tag .. "<" .. detail .. ">" - t[detail] = v - return v - end) +local patterns = setmetatableindex(function(t,tag) + local v = topattern("^" .. tag .. ">") t[tag] = v return v end) -function tags.detailedtag(tag,detail,attribute) - if not attribute then - attribute = texattribute[a_tagged] - end +function tags.locatedtag(tag) + local attribute = texattribute[a_tagged] if attribute >= 0 then - local tl = taglist[attribute] - if tl then - local pattern - if detail and detail ~= "" then - -- pattern = "^" .. tag .. ":" .. detail .. "%-" - -- pattern = "^" .. tag .. "<" .. detail .. ">" - pattern = patterns_yes[tag][detail] - else - -- pattern = "^" .. tag .. "%-" - -- pattern = "^" .. tag .. ">" - pattern = patterns_nop[tag] - end - for i=#tl,1,-1 do - local tli = tl[i] - if find(tli,pattern) then - return tli + local specification = taglist[attribute] + if specification then + local taglist = specification.taglist + local pattern = patterns[tag] + for i=#taglist,1,-1 do + local t = taglist[i] + if find(t,pattern) then + return t end end end @@ -245,13 +224,20 @@ function tags.detailedtag(tag,detail,attribute) return false -- handy as bogus index end -tags.properties = properties - -local lasttags = { } -local userdata = { } -local nstack = 0 - -tags.userdata = userdata +function structures.atlocation(str) + local specification = taglist[texattribute[a_tagged]] + if specification then + if list then + local taglist = specification.taglist + local pattern = patterns[str] + for i=#list,1,-1 do + if find(list[i],pattern) then + return true + end + end + end + end +end function tags.setproperty(tag,key,value) local p = properties[tag] @@ -263,7 +249,7 @@ function tags.setproperty(tag,key,value) end function tags.setaspect(key,value) - local tag = chain[nstack] + local tag = chain[stacksize] if tag then local p = properties[tag] if p then @@ -274,23 +260,6 @@ function tags.setaspect(key,value) end end -function tags.copyaspect(old,new) - local oldlst = taglist[old] - local newlst = taglist[new] - local oldtag = oldlst[#oldlst] - local newtag = newlst[#newlst] - properties[newtag] = properties[oldtag] -end - -function tags.registerdata(data) - local fulltag = chain[nstack] - if fulltag then - tagdata[fulltag] = data - end -end - -local metadata - function tags.registermetadata(data) local d = settings_to_hash(data) if metadata then @@ -300,102 +269,91 @@ function tags.registermetadata(data) end end -function tags.start(tag,specification,props) - local label, detail, user - if specification then - label = specification.label - detail = specification.detail - user = specification.userdata - end +function tags.start(tag,specification) if not enabled then codeinjections.enabletags() enabled = true end -- - local fulltag = label ~= "" and label or tag - labels[tag] = fulltag - if detail and detail ~= "" then - -- fulltag = fulltag .. ":" .. detail - fulltag = fulltag .. "<" .. detail - end + labels[tag] = tag -- can go away -- - local t = #taglist + 1 - local n = (ids[fulltag] or 0) + 1 - ids[fulltag] = n - lasttags[tag] = n --- local completetag = fulltag .. "-" .. n - local completetag = fulltag .. ">" .. n - nstack = nstack + 1 - chain[nstack] = completetag - stack[nstack] = t + local attribute = #taglist + 1 + local tagindex = (ids[tag] or 0) + 1 -- - tagcontext[tag] = completetag + local completetag = tag .. ">" .. tagindex -- - -- a copy as we can add key values for alt and actualtext if needed: - taglist[t] = { unpack(chain,1,nstack) } + ids[tag] = tagindex + lasttags[tag] = tagindex + stacksize = stacksize + 1 -- - if user and user ~= "" then - -- maybe we should merge this into taglist or whatever ... anyway there is room to optimize - -- taglist.userdata = settings_to_hash(user) - userdata[completetag] = settings_to_hash(user) - end - if metadata then - tagmetadata[completetag] = metadata + chain[stacksize] = completetag + stack[stacksize] = attribute + tagcontext[tag] = completetag + -- + local tagnesting = { unpack(chain,1,stacksize) } -- a copy so we can add actualtext + -- + if specification then + specification.attribute = attribute + specification.tagindex = tagindex + specification.taglist = tagnesting + specification.tagname = tag + if metadata then + specification.metadata = metadata + metadata = nil + end + local userdata = specification.userdata + if user ~= "" and type(userdata) == "string" then + specification.userdata = settings_to_hash(userdata) + end + local detail = specification.detail + if detail == "" then + specification.detail = nil + end + local parents = specification.parents + if parents == "" then + specification.parents = nil + end + else + specification = { + attribute = attribute, + tagindex = tagindex, + taglist = tagnesting, + tagname = tag, + metadata = metadata, + } metadata = nil end - if props then - properties[completetag] = props - end - texattribute[a_tagged] = t - return t + -- + taglist[attribute] = specification + specifications[completetag] = specification + -- + texattribute[a_tagged] = attribute + return attribute end --- function tags.restart(completetag) --- if type(completetag) == "number" then --- local attribute = completetag --- local listentry = taglist[attribute] --- local completetag = listentry[#listentry] --- nstack = nstack + 1 --- chain[nstack] = completetag --- stack[nstack] = attribute --- texattribute[a_tagged] = attribute --- return attribute --- else --- local attribute = #taglist + 1 --- nstack = nstack + 1 --- chain[nstack] = completetag --- stack[nstack] = attribute --- taglist[attribute] = { unpack(chain,1,nstack) } --- texattribute[a_tagged] = attribute --- return attribute --- end --- end --- --- more compact: - function tags.restart(attribute) - nstack = nstack + 1 + stacksize = stacksize + 1 if type(attribute) == "number" then - local listentry = taglist[attribute] - chain[nstack] = listentry[#listentry] + local taglist = taglist[attribute].taglist + chain[stacksize] = taglist[#taglist] else - chain[nstack] = attribute -- a string + chain[stacksize] = attribute -- a string attribute = #taglist + 1 - taglist[attribute] = { unpack(chain,1,nstack) } + taglist[attribute] = { taglist = { unpack(chain,1,stacksize) } } end - stack[nstack] = attribute + stack[stacksize] = attribute texattribute[a_tagged] = attribute return attribute end function tags.stop() - if nstack > 0 then - nstack = nstack -1 + if stacksize > 0 then + stacksize = stacksize - 1 end - local t = stack[nstack] + local t = stack[stacksize] if not t then -- if trace_tags then - report_tags("ignoring end tag, previous chain: %s",nstack > 0 and concat(chain[nstack]," ",1,nstack) or "none") + report_tags("ignoring end tag, previous chain: %s",stacksize > 0 and concat(chain," ",1,stacksize) or "none") -- end t = unsetvalue end @@ -404,12 +362,7 @@ function tags.stop() end function tags.getid(tag,detail) - if detail and detail ~= "" then - -- return ids[tag .. ":" .. detail] or "?" - return ids[tag .. "<" .. detail] or "?" - else - return ids[tag] or "?" - end + return ids[tag] or "?" end function tags.last(tag) @@ -420,14 +373,14 @@ function tags.lastinchain(tag) if tag and tag ~= "" then return tagcontext[tag] else - return chain[nstack] + return chain[stacksize] end end -local strip = C((1-S(":-"))^1) +local strip = C((1-S(">"))^1) commands.getelementtag = function() - local fulltag = chain[nstack] + local fulltag = chain[stacksize] if fulltag then context(lpegmatch(strip,fulltag)) end @@ -437,36 +390,36 @@ function tags.setuserproperties(tag,list) if list then tag = tagcontext[tag] else - tag, list = chain[nstack], tag + tag, list = chain[stacksize], tag end - if tag then + if tag then -- an attribute now local l = settings_to_hash(list) - local p = userproperties[tag] - if p then - for k, v in next, l do - p[k] = v + local s = specifications[tag] + if s then + local u = s.userdata + if u then + for k, v in next, l do + u[k] = v + end + else + s.userdata = l end else - userproperties[tag] = l + -- error end end end commands.setelementuserproperties = tags.setuserproperties -function structures.atlocation(str) - local location = gsub(concat(taglist[texattribute[a_tagged]],"-"),"%-%d+","") - return find(location,topattern(str)) ~= nil -end - function tags.handler(head) -- we need a dummy return head, false end statistics.register("structure elements", function() if enabled then - if nstack > 0 then - return format("%s element chains identified, open chain: %s ",#taglist,concat(chain," => ",1,nstack)) + if stacksize > 0 then + return format("%s element chains identified, open chain: %s ",#taglist,concat(chain," => ",1,stacksize)) else return format("%s element chains identified",#taglist) end @@ -484,8 +437,3 @@ commands.starttag = tags.start commands.stoptag = tags.stop commands.settagproperty = tags.setproperty commands.settagaspect = tags.setaspect - --- function commands.tagindex(tag) --- context(lasttags[tag] or 0) --- end - diff --git a/tex/context/base/strc-tag.mkiv b/tex/context/base/strc-tag.mkiv index a97bec7c9..33cd442d5 100644 --- a/tex/context/base/strc-tag.mkiv +++ b/tex/context/base/strc-tag.mkiv @@ -197,8 +197,14 @@ % \unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]% % {\ctxcommand{starttag("#1",{label="#1",userdata=\!!bs#2\!!es})}} +% \unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]% +% {\ctxcommand{starttag("#1",{label="\dogetupsometaglabeltext{#1}",userdata=\!!bs#2\!!es})}} +% +% it makes no sense to have labels ... maybe some day as a last 'replace' in the export +% which might be more efficient then ... okay, we now cannot overload but who cares + \unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]% - {\ctxcommand{starttag("#1",{label="\dogetupsometaglabeltext{#1}",userdata=\!!bs#2\!!es})}} + {\ctxcommand{starttag("#1",{userdata=\!!bs#2\!!es})}} \unexpanded\def\strc_tags_element_stop_yes {\ctxcommand{stoptag()}} @@ -222,11 +228,25 @@ % beware: making these unexpanded spoils tables (noalign problem) -\def\strc_tags_enabled_start +\def\strc_tags_enabled_start_no_detail + {\iftrialtypesetting + \expandafter\strc_tags_start_nop_no_detail + \else + \expandafter\strc_tags_start_yes_no_detail + \fi} + +\def\strc_tags_enabled_start_detail {\iftrialtypesetting - \expandafter\strc_tags_start_nop + \expandafter\strc_tags_start_nop_detail \else - \expandafter\strc_tags_start_yes + \expandafter\strc_tags_start_yes_detail + \fi} + +\def\strc_tags_enabled_start_chained + {\iftrialtypesetting + \expandafter\strc_tags_start_nop_chained + \else + \expandafter\strc_tags_start_yes_chained \fi} \def\strc_tags_enabled_stop @@ -236,25 +256,37 @@ \expandafter\strc_tags_stop_yes \fi} -\def\strc_tags_start_yes#1#2% we could have a fast labeltext resolver - {\ctxcommand{starttag("#1",{label="\dogetupsometaglabeltext{#1}",detail="#2"})}} +\def\strc_tags_start_yes_no_detail #1{\ctxcommand{starttag("#1")}} +\def\strc_tags_start_yes_detail #1#2{\ctxcommand{starttag("#1",{detail="#2"})}} +\def\strc_tags_start_yes_chained #1#2#3{\ctxcommand{starttag("#1",{detail="#2",parents="\getcurrentparentchain#3{#2}"})}} +\def\strc_tags_stop_yes {\ctxcommand{stoptag()}} -\def\strc_tags_stop_yes - {\ctxcommand{stoptag()}} +\let\strc_tags_start_nop_no_detail\gobbleoneargument +\let\strc_tags_start_nop_detail \gobbletwoarguments +\let\strc_tags_start_nop_chained \gobblethreearguments +\let\strc_tags_stop_nop \donothing -\def\strc_tags_start_nop#1#2% - {} +% more efficient: -\def\strc_tags_stop_nop - {} +% \dostarttagged % {tag} {detail} +% \dostarttaggedchained % {tag} {detail} \??hash +% \dostarttaggednodetail % {tag} + +% \unexpanded\def\strc_tags_enable +% {\let\dostarttagged\strc_tags_start_yes +% \let\dostoptagged \strc_tags_stop_yes} \unexpanded\def\strc_tags_enable - {\let\dostarttagged\strc_tags_start_yes - \let\dostoptagged \strc_tags_stop_yes} + {\let\dostarttagged \strc_tags_enabled_start_detail + \let\dostarttaggednodetail\strc_tags_enabled_start_no_detail + \let\dostarttaggedchained \strc_tags_enabled_start_chained + \let\dostoptagged \strc_tags_enabled_stop} \unexpanded\def\strc_tags_disable - {\let\dostarttagged\strc_tags_start_nop - \let\dostoptagged \strc_tags_stop_nop} + {\let\dostarttagged \strc_tags_start_nop_detail + \let\dostarttaggednodetail\strc_tags_start_nop_no_detail + \let\dostarttaggedchained \strc_tags_start_nop_chained + \let\dostoptagged \strc_tags_stop_nop} % for luigi (beware: fully expandable): @@ -334,7 +366,7 @@ \installcorenamespace {paragraph} \installcommandhandler \??paragraph {paragraph} \??paragraph -\setupparagraph % someday maybe also strut (beg/end) +\setupparagraph % someday maybe also strut (beg/end) and align [\c!color=, \c!style=] diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index 9adacad3c..eba1527de 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -1147,7 +1147,7 @@ \global\c_tabl_ntb_row\zerocount \global\advance\c_tabl_ntb_row\minusone \tabskip\zeropoint - \dostarttagged\t!table\empty + \dostarttaggedchained\t!table\empty\??naturaltable \dostarttagged\t!tablerow\empty \appendtoks\dostoptagged\dostarttagged\t!tablerow\empty\to\everycr \halign\bgroup diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index c25d61741..1bfa53d31 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -2172,7 +2172,7 @@ \global\setbox\b_tabl_tabulate\vbox \bgroup \fi % - \dostarttagged\t!tabulate\empty + \dostarttaggedchained\t!tabulate\empty\??tabulate \dostarttagged\t!tabulaterow\empty \setfalse\inhibitmargindata % new per 2012.06.13 ... really needed \everycr\expandafter{\the\everycr\dostoptagged\dostarttagged\t!tabulaterow\empty}% diff --git a/tex/context/base/tabl-xtb.mkvi b/tex/context/base/tabl-xtb.mkvi index c4c59e10a..05cfef17b 100644 --- a/tex/context/base/tabl-xtb.mkvi +++ b/tex/context/base/tabl-xtb.mkvi @@ -216,7 +216,7 @@ \unexpanded\def\tabl_x_start_named_indeed[#settings]% {\advance\c_tabl_x_nesting\plusone - \dostarttagged\t!table\empty + \dostarttaggedchained\t!table\empty\??xtable \iffirstargument \setupcurrentxtable[#settings]% \fi @@ -240,7 +240,7 @@ \unexpanded\def\tabl_x_prepare#settings% assumes \iffirstargument to be set {\advance\c_tabl_x_nesting\plusone - \dostarttagged\t!table\empty + \dostarttaggedchained\t!table\empty\??xtable \iffirstargument \tabl_x_set_checked{#settings}% \fi diff --git a/tex/context/base/typo-del.mkiv b/tex/context/base/typo-del.mkiv index 1018d3563..9bdca4af4 100644 --- a/tex/context/base/typo-del.mkiv +++ b/tex/context/base/typo-del.mkiv @@ -148,7 +148,7 @@ \ifnum\c_typo_subsentence_nesting=\plusone \dontleavehmode % was \leaveoutervmode \fi - \dostarttagged\t!subsentence\empty + \dostarttagged\t!subsentence\empty % no chain \symbol[\ifodd\c_typo_subsentence_nesting\c!leftsentence\else\c!leftsubsentence\fi]% }% \ignorespaces} @@ -305,7 +305,7 @@ \unexpanded\def\startdelimitedtext[#1]% {\begingroup \typo_delimited_push{#1}% - \dostarttagged\t!delimitedblock\currentdelimitedtext + \dostarttaggedchained\t!delimitedblock\currentdelimitedtext\??delimitedtext \edef\p_delimited_method{\delimitedtextparameter\c!method}% \ifx\p_delimited_method\s!font \expandafter\typo_delimited_start_font @@ -609,7 +609,7 @@ \unexpanded\def\typo_delimited_par {\groupedcommand - {\dostarttagged\t!delimited\currentdelimitedtext % block? + {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext % block? \typo_delimited_handle_left\c!left} {\typo_delimited_handle_right\c!right \removelastskip @@ -622,7 +622,7 @@ % \typo_delimited_attributed} % % \def\typo_delimited_quoted_b -% {\dostarttagged\t!delimited\currentdelimitedtext +% {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext % \typo_delimited_handle_left\c!left} % % \def\typo_delimited_quoted_e @@ -632,7 +632,7 @@ % \typo_delimited_pop} % % \def\typo_delimited_attributed_b -% {\dostarttagged\t!delimited\currentdelimitedtext +% {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext % \usedelimitedtextstyleandcolor\c!style\c!color} % % \def\typo_delimited_attributed_e @@ -640,7 +640,7 @@ % \typo_delimited_pop} % % \def\typo_delimited_fontdriven_b -% {\dostarttagged\t!delimited\currentdelimitedtext +% {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext % \languageparameter{\c!left\currentparentdelimitedtext}}% was: \currentdelimitedtext % % \def\typo_delimited_fontdriven_e @@ -657,7 +657,7 @@ \fi} \def\typo_delimited_quoted_b - {\dostarttagged\t!delimited\currentdelimitedtext + {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext \typo_delimited_handle_left\c!left \usedelimitedtextstyleandcolor\c!style\c!color} @@ -668,7 +668,7 @@ \typo_delimited_pop} \def\typo_delimited_attributed_b - {\dostarttagged\t!delimited\currentdelimitedtext + {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext \usedelimitedtextstyleandcolor\c!style\c!color} \def\typo_delimited_attributed_e @@ -676,7 +676,7 @@ \typo_delimited_pop} \def\typo_delimited_fontdriven_b - {\dostarttagged\t!delimited\currentdelimitedtext + {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext \languageparameter{\c!left\currentparentdelimitedtext}% was: \currentdelimitedtext \usedelimitedtextstyleandcolor\c!style\c!color} diff --git a/tex/context/base/typo-mar.mkiv b/tex/context/base/typo-mar.mkiv index 0a113dbc2..be24d0a90 100644 --- a/tex/context/base/typo-mar.mkiv +++ b/tex/context/base/typo-mar.mkiv @@ -201,7 +201,7 @@ \strc_references_set_page_only_destination_box_attribute\currentmarginreference\currentmarginreference \fi \edef\currentmargindatastrut{\margindataparameter\c!strut}% - \dostarttagged\t!margintext\currentmargindata + \dostarttaggedchained\t!margintext\currentmargindata\??margindata \ifcsname\currentmarginframedhash\s!parent\endcsname \setbox\nextbox\hbox \currentmarginreference \bgroup \the\everymargindatacontent diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index dce2ae0a2..0a533d75f 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 : 10/22/14 16:23:49 +-- merge date : 10/27/14 09:27:26 do -- begin closure to overcome local limits and interference |