diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-ref.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/strc-ref.lua | 224 |
1 files changed, 162 insertions, 62 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-ref.lua b/Master/texmf-dist/tex/context/base/strc-ref.lua index 092babfaed6..284418c484c 100644 --- a/Master/texmf-dist/tex/context/base/strc-ref.lua +++ b/Master/texmf-dist/tex/context/base/strc-ref.lua @@ -19,6 +19,7 @@ local texcount, texsetcount = tex.count, tex.setcount local rawget, tonumber = rawget, tonumber local lpegmatch = lpeg.match local copytable = table.copy +local formatters = string.formatters local allocate = utilities.storage.allocate local mark = utilities.storage.mark @@ -28,16 +29,30 @@ local trace_referencing = false trackers.register("structures.referencing", local trace_analyzing = false trackers.register("structures.referencing.analyzing", function(v) trace_analyzing = v end) local trace_identifying = false trackers.register("structures.referencing.identifying", function(v) trace_identifying = v end) local trace_importing = false trackers.register("structures.referencing.importing", function(v) trace_importing = v end) +local trace_empty = false trackers.register("structures.referencing.empty", function(v) trace_empty = v end) + +local check_duplicates = true + +directives.register("structures.referencing.checkduplicates", function(v) + check_duplicates = v +end) local report_references = logs.reporter("references") -local report_unknown = logs.reporter("unknown") +local report_unknown = logs.reporter("references","unknown") local report_identifying = logs.reporter("references","identifying") local report_importing = logs.reporter("references","importing") +local report_empty = logs.reporter("references","empty") local variables = interfaces.variables local constants = interfaces.constants local context = context +local v_default = variables.default +local v_url = variables.url +local v_file = variables.file +local v_unknown = variables.unknown +local v_yes = variables.yes + local texcount = tex.count local texconditionals = tex.conditionals @@ -237,11 +252,13 @@ references.setnextorder = setnextorder function references.setnextinternal(kind,name) setnextorder(kind,name) -- always incremented with internal - texsetcount("global","locationcount",texcount.locationcount + 1) + local n = texcount.locationcount + 1 + texsetcount("global","locationcount",n) + return n end function references.currentorder(kind,name) - context(orders[kind] and orders[kind][name] or lastorder) + return orders[kind] and orders[kind][name] or lastorder end local function setcomponent(data) @@ -257,6 +274,12 @@ local function setcomponent(data) -- but for the moment we do it here (experiment) end +commands.setnextinternalreference = references.setnextinternal + +function commands.currentreferenceorder(kind,name) + context(references.currentorder(kind,name)) +end + references.setcomponent = setcomponent function references.set(kind,prefix,tag,data) @@ -269,11 +292,11 @@ function references.set(kind,prefix,tag,data) local n = 0 for ref in gmatch(tag,"[^,]+") do if ref ~= "" then - if pd[ref] then + if check_duplicates and pd[ref] then if prefix and prefix ~= "" then - report_references("redundant reference: %q in namespace %q",ref,prefix) + report_references("redundant reference %a in namespace %a",ref,prefix) else - report_references("redundant reference %q",ref) + report_references("redundant reference %a",ref) end else n = n + 1 @@ -292,6 +315,8 @@ function references.enhance(prefix,tag) end end +commands.enhancereference = references.enhance + -- -- -- related to strc-ini.lua -- -- -- references.resolvers = references.resolvers or { } @@ -372,7 +397,7 @@ local function register_from_lists(collected,derived,pages,sections) local t = { kind, i, entry } for s in gmatch(reference,"%s*([^,]+)") do if trace_referencing then - report_references("list entry %s provides %s reference '%s' on realpage %s",i,kind,s,realpage) + report_references("list entry %a provides %a reference %a on realpage %a",i,kind,s,realpage) end c[s] = c[s] or t -- share them d[s] = d[s] or t -- share them @@ -400,14 +425,16 @@ function references.urls.define(name,url,file,description) end end -local pushcatcodes, popcatcodes, txtcatcodes = context.pushcatcodes, context.popcatcodes, tex.txtcatcodes +local pushcatcodes = context.pushcatcodes +local popcatcodes = context.popcatcodes +local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes" function references.urls.get(name) local u = urls[name] if u then local url, file = u[1], u[2] if file and file ~= "" then - return format("%s/%s",url,file) + return formatters["%s/%s"](url,file) else return url end @@ -526,9 +553,7 @@ end function references.programs.get(name) local f = programs[name] - if f then - context(f[1]) - end + return f and f[1] end function references.checkedprogram(whatever) -- return whatever if not resolved @@ -542,10 +567,19 @@ function references.checkedprogram(whatever) -- return whatever if not resolved end end +commands.defineprogram = references.programs.define + +function commands.getprogram(name) + local f = programs[name] + if f then + context(f[1]) + end +end + -- shared by urls and files function references.whatfrom(name) - context((urls[name] and variables.url) or (files[name] and variables.file) or variables.unknown) + context((urls[name] and v_url) or (files[name] and v_file) or v_unknown) end function references.from(name) @@ -553,6 +587,31 @@ function references.from(name) if u then local url, file, description = u[1], u[2], u[3] if description ~= "" then + return description + -- ok + elseif file and file ~= "" then + return url .. "/" .. file + else + return url + end + else + local f = files[name] + if f then + local file, description = f[1], f[2] + if description ~= "" then + return description + else + return file + end + end + end +end + +function commands.from(name) + local u = urls[name] + if u then + local url, file, description = u[1], u[2], u[3] + if description ~= "" then context.dofromurldescription(description) -- ok elseif file and file ~= "" then @@ -578,10 +637,6 @@ function references.define(prefix,reference,list) d[reference] = { "defined", list } end ---~ function references.registerspecial(name,action,...) ---~ specials[name] = { action, ... } ---~ end - function references.reset(prefix,reference) local d = defined[prefix] if d then @@ -589,6 +644,9 @@ function references.reset(prefix,reference) end end +commands.definereference = references.define +commands.resetreference = references.reset + -- \primaryreferencefoundaction -- \secondaryreferencefoundaction -- \referenceunknownaction @@ -657,7 +715,7 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere set.has_tex = true end else - -- report_references("funny pattern: %s",ri or "?") + -- report_references("funny pattern %a",ri) end end end @@ -699,6 +757,8 @@ function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex end end +commands.expandcurrentreference = references.expandcurrent -- for the moment the same + local externals = { } -- we have prefixes but also components: @@ -717,7 +777,8 @@ local function loadexternalreferences(name,utilitydata) for prefix, set in next, external do for reference, data in next, set do if trace_importing then - report_importing("registering external reference: regular | %s | %s | %s",name,prefix,reference) + report_importing("registering %a reference, kind %a, name %a, prefix %a, reference %a", + "external","regular",name,prefix,reference) end local section = reference.section local realpage = reference.realpage @@ -748,7 +809,8 @@ local function loadexternalreferences(name,utilitydata) end for s in gmatch(reference,"%s*([^,]+)") do if trace_importing then - report_importing("registering external reference: %s | %s | %s | %s",kind,name,prefix,s) + report_importing("registering %s reference, kind %a, name %a, prefix %a, reference %a", + "external",kind,name,prefix,s) end target[s] = target[s] or entry end @@ -807,7 +869,8 @@ local function loadproductreferences(productname,componentname,utilitydata) for prefix, set in next, productreferences do for reference, data in next, set do if trace_importing then - report_importing("registering product reference: regular | %s | %s | %s",productname,prefix,reference) + report_importing("registering %s reference, kind %a, name %a, prefix %a, reference %a", + "product","regular",productname,prefix,reference) end local section = reference.section local realpage = reference.realpage @@ -835,7 +898,7 @@ local function loadproductreferences(productname,componentname,utilitydata) local prefix = references.referenceprefix or "" local component = references.component local ctarget, ptarget - if component and component == componentname then + if not component or component == componentname then -- skip else -- one level up @@ -861,13 +924,15 @@ local function loadproductreferences(productname,componentname,utilitydata) for s in gmatch(reference,"%s*([^,]+)") do if ptarget then if trace_importing then - report_importing("registering product reference: %s | %s | %s | %s",kind,productname,prefix,s) + report_importing("registering %s reference, kind %a, name %a, prefix %a, reference %a", + "product",kind,productname,prefix,s) end ptarget[s] = ptarget[s] or entry end if ctarget then if trace_importing then - report_importing("registering component reference: %s | %s | %s | %s",kind,productname,prefix,s) + report_importing("registering %s reference, kind %a, name %a, prefix %a, referenc %a", + "component",kind,productname,prefix,s) end ctarget[s] = ctarget[s] or entry end @@ -895,7 +960,7 @@ local function loadproductvariables(product,component,utilitydata) local numbers = firstsection.numberdata.numbers if numbers then if trace_importing then - report_importing("initializing section number to %s",concat(numbers,":")) + report_importing("initializing section number to %:t",numbers) end productdata.firstsection = firstsection structures.documents.preset(numbers) @@ -906,7 +971,7 @@ local function loadproductvariables(product,component,utilitydata) local number = firstpage and firstpage.number if number then if trace_importing then - report_importing("initializing page number to %s",number) + report_importing("initializing page number to %a",number) end productdata.firstpage = firstpage counters.set("userpage",1,number) @@ -958,7 +1023,7 @@ function structures.references.loadpresets(product,component) -- we can consider local utilitydata = job.loadother(fullname) if utilitydata then if trace_importing then - report_importing("loading references for component %s of product %s from %s",component,product,fullname) + report_importing("loading references for component %a of product %a from %a",component,product,fullname) end loadproductvariables (product,component,utilitydata) loadproductreferences(product,component,utilitydata) @@ -981,7 +1046,7 @@ if useproduct then local component = justacomponent() if component then if trace_referencing or trace_importing then - report_references("loading presets for component '%s' of product '%s'",component,product) + report_references("loading presets for component %a of product %a",component,product) end structures.references.loadpresets(product,component) end @@ -1000,9 +1065,9 @@ local function report_identify_special(set,var,i,type) local error = var.error local kind = var.kind if error then - report_identifying("type %s: %s, n: %s, prefix: %s, special: %s, error: %s",type,reference,i,prefix,special,error) + report_identifying("type %a, reference %a, index %a, prefix %a, special %a, error %a",type,reference,i,prefix,special,error) else - report_identifying("type %s: %s, n: %s, prefix: %s, special: %s, kind: %s",type,reference,i,prefix,special,kind) + report_identifying("type %a, reference %a, index %a, prefix %a, special %a, kind %a",type,reference,i,prefix,special,kind) end end @@ -1013,9 +1078,9 @@ local function report_identify_arguments(set,var,i,type) local error = var.error local kind = var.kind if error then - report_identifying("type %s: %s, n: %s, prefix: %s, arguments: %s, error: %s",type,reference,i,prefix,arguments,error) + report_identifying("type %a, reference %a, index %a, prefix %a, arguments %a, error %a",type,reference,i,prefix,arguments,error) else - report_identifying("type %s: %s, n: %s, prefix: %s, arguments: %s, kind: %s",type,reference,i,prefix,arguments,kind) + report_identifying("type %a, reference %a, index %a, prefix %a, arguments %a, kind %a",type,reference,i,prefix,arguments,kind) end end @@ -1027,15 +1092,15 @@ local function report_identify_outer(set,var,i,type) local kind = var.kind if outer then if error then - report_identifying("type %s: %s, n: %s, prefix: %s, outer: %s, error: %s",type,reference,i,prefix,outer,error) + report_identifying("type %a, reference %a, index %a, prefix %a, outer %a, error %a",type,reference,i,prefix,outer,error) else - report_identifying("type %s: %s, n: %s, prefix: %s, outer: %s, kind: %s",type,reference,i,prefix,outer,kind) + report_identifying("type %a, reference %a, index %a, prefix %a, outer %a, kind %a",type,reference,i,prefix,outer,kind) end else if error then - report_identifying("type %s: %s, n: %s, prefix: %s, error: %s",type,reference,i,prefix,error) + report_identifying("type %a, reference %a, index %a, prefix %a, error %a",type,reference,i,prefix,error) else - report_identifying("type %s: %s, n: %s, prefix: %s, kind: %s",type,reference,i,prefix,kind) + report_identifying("type %a, reference %a, index %a, prefix %a, kind %a",type,reference,i,prefix,kind) end end end @@ -1179,7 +1244,7 @@ local function identify_inner(set,var,prefix,collected,derived,tobesaved) ri(var) else -- can't happen as we catch it with a metatable now - report_references("unknown inner resolver for '%s'",i[1]) + report_references("unknown inner resolver for %a",i[1]) end else -- no prefixes here @@ -1512,14 +1577,14 @@ end references.identify = identify -local unknowns, nofunknowns = { }, 0 +local unknowns, nofunknowns, f_valid = { }, 0, formatters["[%s][%s]"] -function references.doifelse(prefix,reference,highlight,newwindow,layer) +function references.valid(prefix,reference,highlight,newwindow,layer) local set, bug = identify(prefix,reference) local unknown = bug or #set == 0 if unknown then currentreference = nil -- will go away - local str = format("[%s][%s]",prefix,reference) + local str = f_valid(prefix,reference) local u = unknowns[str] if not u then interfaces.showmessage("references",1,str) -- 1 = unknown, 4 = illegal @@ -1529,11 +1594,15 @@ function references.doifelse(prefix,reference,highlight,newwindow,layer) unknowns[str] = u + 1 end else - set.highlight, set.newwindow,set.layer = highlight, newwindow, layer + set.highlight, set.newwindow, set.layer = highlight, newwindow, layer currentreference = set[1] end -- we can do the expansion here which saves a call - commands.doifelse(not unknown) + return not unknown +end + +function commands.doifelsereference(prefix,reference,highlight,newwindow,layer) + commands.doifelse(references.valid(prefix,reference,highlight,newwindow,layer)) end function references.reportproblems() -- might become local @@ -1563,12 +1632,12 @@ function references.setinnermethod(m) if m then if m == "page" or m == "mixed" or m == "names" then innermethod = m - elseif m == true or m == variables.yes then + elseif m == true or m == v_yes then innermethod = "page" end end function references.setinnermethod() - report_references("inner method is already set and frozen to '%s'",innermethod) + report_references("inner method is already set and frozen to %a",innermethod) end end @@ -1612,13 +1681,13 @@ function references.setinternalreference(prefix,tag,internal,view) -- needs chec end function references.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here - if references.set(kind,prefix,tag,data) then - texcount.lastdestinationattribute = references.setinternalreference(prefix,tag,nil,view) or unsetvalue - else - texcount.lastdestinationattribute = unsetvalue - end + local attr = references.set(kind,prefix,tag,data) and references.setinternalreference(prefix,tag,nil,view) or unsetvalue + texcount.lastdestinationattribute = attr + return attr end +commands.setreferenceattribute = references.setandgetattribute + function references.getinternalreference(n) -- n points into list (todo: registers) local l = lists.collected[n] return l and l.references.internal or n @@ -1637,7 +1706,11 @@ end function references.getcurrentmetadata(tag) local data = currentreference and currentreference.i - data = data and data.metadata and data.metadata[tag] + return data and data.metadata and data.metadata[tag] +end + +function commands.getcurrentreferencemetadata(tag) + local data = references.getcurrentmetadata(tag) if data then context(data) end @@ -1650,8 +1723,15 @@ end references.currentmetadata = currentmetadata -function references.getcurrentprefixspec(default) -- todo: message - context.getreferencestructureprefix(currentmetadata("kind") or "?",currentmetadata("name") or "?",default or "?") +local function getcurrentprefixspec(default) + -- todo: message + return currentmetadata("kind") or "?", currentmetadata("name") or "?", default or "?" +end + +references.getcurrentprefixspec = getcurrentprefixspec + +function commands.getcurrentprefixspec(default) + context.getreferencestructureprefix(getcurrentprefixspec(default)) end function references.filter(name,...) -- number page title ... @@ -1659,7 +1739,7 @@ function references.filter(name,...) -- number page title ... if data then if name == "realpage" then local cs = references.analyze() -- normally already analyzed but also sets state - context(cs.realpage or 0) -- todo, return and in command namespace + context(tonumber(cs.realpage) or 0) -- todo, return and in command namespace else -- assumes data is table local kind = type(data) == "table" and data.metadata and data.metadata.kind if kind then @@ -1667,21 +1747,32 @@ function references.filter(name,...) -- number page title ... filter = filter and (filter[name] or filter.unknown or filters.generic[name] or filters.generic.unknown) if filter then if trace_referencing then - report_references("name '%s', kind '%s', using dedicated filter",name,kind) + report_references("name %a, kind %a, using dedicated filter",name,kind) end filter(data,name,...) elseif trace_referencing then - report_references("name '%s', kind '%s', using generic filter",name,kind) + report_references("name %a, kind %a, using generic filter",name,kind) end elseif trace_referencing then - report_references("name '%s', unknown kind",name) + report_references("name %a, unknown kind",name) end end + elseif name == "realpage" then + context(0) elseif trace_referencing then - report_references("name '%s', no reference",name) + report_references("name %a, no reference",name) end end +function references.filterdefault() + return references.filter("default",getcurrentprefixspec(v_default)) +end + +function commands.currentreferencedefault(tag) + if not tag then tag = "default" end + references.filter(tag,context.delayed(getcurrentprefixspec(tag))) +end + filters.generic = { } function filters.generic.title(data) @@ -1704,7 +1795,7 @@ end function filters.generic.number(data,what,prefixspec) -- todo: spec and then no stopper if data then - local numberdata = data.numberdata + numberdata = lists.reordered(data) -- data.numberdata if numberdata then helpers.prefix(data,prefixspec) sections.typesetnumber(numberdata,"number",numberdata) @@ -1782,13 +1873,19 @@ filters.section = { } function filters.section.number(data,what,prefixspec) if data then local numberdata = data.numberdata - if numberdata then - sections.typesetnumber(numberdata,"number",prefixspec,numberdata) - else + if not numberdata then local useddata = data.useddata if useddata and useddata.number then context(useddata.number) end + elseif numberdata.hidenumber then + local references = data.references + if trace_empty then + report_empty("reference %a has a hidden number",references.reference) + context.emptyreference() -- maybe an option + end + else + sections.typesetnumber(numberdata,"number",prefixspec,numberdata) end end end @@ -2049,10 +2146,13 @@ end -- needs a better split ^^^ -commands.filterreference = references.filter +commands.filterreference = references.filter +commands.filterdefaultreference = references.filterdefault -- done differently now: function references.export(usedname) end function references.import(usedname) end function references.load (usedname) end + +commands.exportreferences = references.export |