diff options
Diffstat (limited to 'tex/context/base/mkxl/strc-ref.lmt')
-rw-r--r-- | tex/context/base/mkxl/strc-ref.lmt | 346 |
1 files changed, 249 insertions, 97 deletions
diff --git a/tex/context/base/mkxl/strc-ref.lmt b/tex/context/base/mkxl/strc-ref.lmt index 945364b18..6a320f141 100644 --- a/tex/context/base/mkxl/strc-ref.lmt +++ b/tex/context/base/mkxl/strc-ref.lmt @@ -30,6 +30,7 @@ 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_external = false trackers.register("structures.referencing.external", function(v) trace_external = v end) local trace_empty = false trackers.register("structures.referencing.empty", function(v) trace_empty = v end) local check_duplicates = true @@ -39,6 +40,7 @@ directives.register("structures.referencing.checkduplicates", function(v) check_ local report_references = logs.reporter("references") local report_identifying = logs.reporter("references","identifying") local report_importing = logs.reporter("references","importing") +local report_external = logs.reporter("references","external") local report_empty = logs.reporter("references","empty") local report = report_references @@ -174,6 +176,11 @@ local function initializer() -- can we use a tobesaved as metatable for collecte if i then internals[i] = data usedinternals[i] = r.used + local structure = r.structure + if structure then + structure = resolvers.jobs.namelist(structure,namestack) + r.namestack = structure + end end end end @@ -347,26 +354,37 @@ local function currentorder(kind,name) return orders[kind] and orders[kind][name] or lastorder end -local function setcomponent(data) - -- we might consider doing this at the tex end, just like prefix - local component = productcomponent() - if component then - local references = data and data.references - if references then - references.component = component - if references.prefix == component then - references.prefix = nil - end - end - return component - end - -- but for the moment we do it here (experiment) -end +-- local function setstructure(data) +-- local structure = resolvers.jobs.currentnamehash() +-- if structure then +-- local references = data and data.references +-- if references then +-- references.structure = structure +-- end +-- end +-- end + +-- local function setcomponent(data) +-- -- we might consider doing this at the tex end, just like prefix +-- local component = productcomponent() -- todo: maybe a list +-- -- local component = resolvers.jobs.currentcomponent() +-- if component then +-- local references = data and data.references +-- if references then +-- references.component = component +-- if references.prefix == component then +-- references.prefix = nil +-- end +-- end +-- return component +-- end +-- end references.setnextorder = setnextorder references.setnextinternal = setnextinternal references.currentorder = currentorder -references.setcomponent = setcomponent +references.setstructure = resolvers.jobs.currentstructure -- yes or no here +----------.setcomponent = setcomponent -- implement { -- name = "setnextreferenceorder", @@ -405,6 +423,9 @@ function references.set(data) -- report_references("invalid reference") -- harmless return 0 end + -- + references.structure = resolvers.jobs.currentstructure() + -- local prefix = references.prefix or "" local pd = tobesaved[prefix] -- nicer is a metatable if not pd then @@ -497,31 +518,82 @@ implement { -- no metatable here .. better be sparse -local function register_from_list(collected,derived,external) +local function register_from_list(collected,derived,external,namestack) local derived_g = derived[""] -- global local derived_p = nil local derived_c = nil local prefix = nil - local component = nil +-- local component = nil local entry = nil if not derived_g then derived_g = { } derived[""] = derived_g end - local function action(s) - if trace_referencing then - report_references("list entry %a provides %a reference %a on realpage %a",i,kind,s,realpage) - end - if derived_p and not derived_p[s] then - derived_p[s] = entry - end - if derived_c and not derived_c[s] then - derived_c[s] = entry + local action = trace_external and + function(s) + if structure then + for i=1,#structure do + local si = structure[i] + -- if si == component then + -- -- skipped + -- elseif si == prefix then + -- -- skipped + -- else + local ds = derived[si] + if not ds then + derived[si] = { [s] = entry } + report_external("reference %a, %s %a",s,"structure",si) + elseif not ds[s] then + ds[s] = entry + report_external("reference %a, %s %a",s,"structure",si) + end + -- end + end + end + if derived_p and not derived_p[s] then + report_external("reference %a, %s %a",s,"prefix",prefix) + derived_p[s] = entry + + end +-- if derived_c and not derived_c[s] then +-- report_external("reference %a, %s %a",s,"component",component) +-- derived_c[s] = entry +-- end + if not derived_g[s] then + report_external("reference %a, %s %a",s,"global","") + derived_g[s] = entry -- first wins + end end - if not derived_g[s] then - derived_g[s] = entry -- first wins + or + function(s) + if derived_p and not derived_p[s] then + derived_p[s] = entry + end +-- if derived_c and not derived_c[s] then +-- derived_c[s] = entry +-- end + if not derived_g[s] then + derived_g[s] = entry -- first wins + end + if structure then + for i=1,#structure do + local si = structure[i] + if si == component then + -- skipped + elseif si == prefix then + -- skipped + else + local ds = derived[si] + if not ds then + derived[si] = { [s] = entry } + elseif not ds[s] then + ds[s] = entry + end + end + end + end end - end + -- for i=1,#collected do entry = collected[i] local metadata = entry.metadata @@ -535,20 +607,32 @@ local function register_from_list(collected,derived,external) local realpage = references.realpage if realpage then prefix = references.prefix - component = references.component +-- component = references.component if prefix and prefix ~= "" then derived_p = derived[prefix] if not derived_p then derived_p = { } derived[prefix] = derived_p end + else + derived_p = nil end - if component and component ~= "" and component ~= prefix then - derived_c = derived[component] - if not derived_c then - derived_c = { } - derived[component] = derived_c - end +-- if component and component ~= "" and component ~= prefix then +-- derived_c = derived[component] +-- if not derived_c then +-- derived_c = { } +-- derived[component] = derived_c +-- end +-- else +-- derived_c = nil +-- end + structure = references.structure + if structure then + structure = resolvers.jobs.namelist(structure,namestack) + references.namestack = structure + end + if trace_referencing or trace_external then + report_references("list entry %a provides %a reference %a on realpage %a",i,kind,reference,realpage) end process_settings(reference,action) end @@ -567,7 +651,7 @@ function references.integrate(utilitydata) if structures then local lists = structures.lists.collected if lists then - register_from_list(lists,derived,filename) + register_from_list(lists,derived,filename,utilitydata) end end end @@ -575,7 +659,7 @@ end references.registerinitializer(function() -- the main document - register_from_list(lists.collected,derived) + register_from_list(lists.collected,derived) -- false, false end) -- tracing @@ -652,10 +736,10 @@ end) -- urls -local urls = references.urls or { } -references.urls = urls -local urldata = urls.data or { } -urls.data = urldata +local urls = references.urls or { } +references.urls = urls +local urldata = urls.data or { } +urls.data = urldata local p_untexurl = Cs ( ( P("\\")/"" * (P("%")/"%%" + P(1)) @@ -1097,13 +1181,6 @@ local function loadexternalreferences(name,utilitydata) target = { } external[prefix] = target end - -- for s in gmatch(reference,"%s*([^,]+)") do - -- if trace_importing then - -- 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 local function action(s) if trace_importing then report_importing("registering %s reference, kind %a, name %a, prefix %a, reference %a", @@ -1147,7 +1224,7 @@ setmetatableindex(externals, function(t,k) -- either or not automatically return false end) -local productdata = allocate { +local productdata = allocate { -- will go productreferences = { }, componentreferences = { }, components = { }, @@ -1196,6 +1273,13 @@ local function loadproductreferences(productname,componentname,utilitydata) if kind and realpage then local prefix = references.prefix or "" local component = references.component + + -- local structure = references.structure + -- print("!!!!!!!!",structure) + -- if structure then + -- inspect(resolvers.job.namelist(structure)) + -- end + local ctarget, ptarget if not component or component == componentname then -- skip @@ -1327,7 +1411,7 @@ function references.loadpresets(product,component) -- we can consider a special loadproductvariables (product,component,utilitydata) loadproductcomponents(product,component,utilitydata) loadproductreferences(product,component,utilitydata) --- loadproductcomponents(product,component,utilitydata) + -- loadproductcomponents(product,component,utilitydata) end end end @@ -1483,11 +1567,20 @@ end -- foo:bar -> foo == prefix (first we try the global one) -- -:bar -> ignore prefix -local function finish_inner(var,p,i) - var.kind = "inner" +local function finish_inner(set,var,p,i) + local external = i.references.external + local realpage = (i.references and i.references.realpage) or (i.pagedata and i.pagedata.realpage) or 1 + if external then + var.kind = "outer with inner" + var.external = true + var.outer = external + set.external = true -- probably not needed + else + var.kind = "inner" + var.p = p + end + var.r = realpage var.i = i - var.p = p - var.r = (i.references and i.references.realpage) or (i.pagedata and i.pagedata.realpage) or 1 return var end @@ -1506,7 +1599,7 @@ local function identify_inner(set,var,prefix,collected,derived) if i then i = i[splitinner] if i then - return finish_inner(var,"",i) + return finish_inner(set,var,"",i) end end end @@ -1514,7 +1607,7 @@ local function identify_inner(set,var,prefix,collected,derived) if i then i = i[splitinner] if i then - return finish_inner(var,splitprefix,i) + return finish_inner(set,var,splitprefix,i) end end if derived then @@ -1522,11 +1615,13 @@ local function identify_inner(set,var,prefix,collected,derived) -- using the prefix that is active at this moment (so we overload the given -- these are taken from other data structures (like lists) if splitprefix == "-" then +-- loop over the current structure list reversed +-- and end with "" .. needs example local i = derived[""] if i then i = i[splitinner] if i then - return finish_inner(var,"",i) + return finish_inner(set,var,"",i) end end end @@ -1534,7 +1629,7 @@ local function identify_inner(set,var,prefix,collected,derived) if i then i = i[splitinner] if i then - return finish_inner(var,splitprefix,i) + return finish_inner(set,var,splitprefix,i) end end end @@ -1545,7 +1640,7 @@ local function identify_inner(set,var,prefix,collected,derived) if i then i = i[inner] if i then - return finish_inner(var,prefix,i) + return finish_inner(set,var,prefix,i) end end if not i and derived then @@ -1554,7 +1649,22 @@ local function identify_inner(set,var,prefix,collected,derived) if i then i = i[inner] if i then - return finish_inner(var,prefix,i) + return finish_inner(set,var,prefix,i) + end + end + -- + local n, list = resolvers.jobs.currentstructure() + if list then + for i=#list,1,-1 do + local l = list[i] + local i = derived[l] + if i then + i = i[inner] + if i then + -- return finish_inner(set,var,"",i) + return finish_inner(set,var,l,i) + end + end end end end @@ -1571,10 +1681,7 @@ local function unprefixed_inner(set,var,prefix,collected,derived,tobesaved) (derived and derived [""] and derived [""][inner]) or (tobesaved and tobesaved[""] and tobesaved[""][inner]) if i then - var.kind = "inner" - var.p = "" - var.i = i - var.r = (i.references and i.references.realpage) or (i.pagedata and i.pagedata.realpage) or 1 + finish_inner(set,var,"",i) else var.error = "unknown inner or special" end @@ -1611,13 +1718,13 @@ local function identify_auto(set,var,i) end end -- escape from prefix --- local pdata = odata[""] --- if pdata then --- local r = pdata[inner] --- if r then --- return okay(o,"2h") --- end --- end + -- local pdata = odata[""] + -- if pdata then + -- local r = pdata[inner] + -- if r then + -- return okay(o,"2h") + -- end + -- end else for p, pdata in sortedhash(odata) do local r = pdata[inner] @@ -1765,7 +1872,6 @@ end local function identify_inner_or_outer(set,var,i) -- here we fall back on product data local inner = var.inner - if inner and inner ~= "" then -- first we look up in collected and derived using the current prefix @@ -1780,7 +1886,8 @@ local function identify_inner_or_outer(set,var,i) return v end - if var.inner == var.reference and identify_auto(set,var,i) and var.outer and var.outer ~= "" then +-- if var.inner == var.reference and identify_auto(set,var,i) and var.outer and var.outer ~= "" then + if var.inner == var.reference and var.outer and var.outer ~= "" then return identify_outer(set,var,i) end @@ -1804,7 +1911,6 @@ local function identify_inner_or_outer(set,var,i) end -- as a last resort we will consult the global lists - local v = unprefixed_inner(set,var,"",collected,derived,tobesaved) if v then if trace_identifying then @@ -1873,6 +1979,7 @@ local function identify_inner_or_outer(set,var,i) end end end + var.error = "unknown inner" else var.error = "no inner" @@ -1896,40 +2003,51 @@ local function identify_inner_component(set,var,i) return var end +local function identify_outer_component_step(set,var,vi,i,component,where) + if vi then + var.outer = component + var.i = vi + var.kind = "outer with inner" + set.external = true + if trace_identifying then + report_identify_outer(set,var,i,where) + end + return true + end +end + local function identify_outer_component(set,var,i) local component = var.component - local inner = var.inner + local inner = var.inner + -- local data = productdata.componentreferences[component] if data then local d = data[""] - local vi = d and d[inner] - if vi then - var.inner = inner - var.outer = component - var.i = vi - var.kind = "outer with inner" - set.external = true - if trace_identifying then - report_identify_outer(set,var,i,"6a") - end + local d = d and d[inner] + if d and identify_outer_component_step(set,var,d,i,component,"6a") then return var end end + -- local data = productdata.productreferences[component] if data then - local vi = data[inner] - if vi then - var.inner = inner - var.outer = component - var.i = vi - var.kind = "outer with inner" - set.external = true - if trace_identifying then - report_identify_outer(set,var,i,"6b") - end + local d = data[inner] + if d and identify_outer_component_step(set,var,d,i,component,"6b") then + return var + end + end + -- +if texconditionals.autocrossfilereferences then + references.loadpresets(component,component) + local data = productdata.productreferences[component] + if data then + local d = data[inner] + if d and identify_outer_component_step(set,var,d,i,component,"6c") then return var end end +end + -- var.error = "unknown component" if trace_identifying then report_identify_outer(set,var,i,"6c") @@ -1962,6 +2080,8 @@ local function identify(prefix,reference) var = identify_outer(set,var,i) elseif var.arguments then var = identify_arguments(set,var,i) +-- else +-- var = identify_inner_or_outer(set,var,i) elseif not var.component then var = identify_inner_or_outer(set,var,i) elseif productcomponent() then @@ -2691,6 +2811,7 @@ function references.analyze(actions,position,spread) actions.pagestate = checkedpagestate(actions.n,realpage,actions,position,spread) end end +-- inspect(actions) return actions end @@ -2698,6 +2819,8 @@ local function referencepagestate(position,detail,spread) local actions = references.currentset if not actions then return 0 + elseif actions.external then + return 0 else local pagestate = actions.pagestate for i=1,#actions do @@ -3067,3 +3190,32 @@ implement { name = "popreferenceprefix", actions = { popreferenceprefix, context }, -- we can use setmacro } + +-- a bit weird one, used for checkinh in the backend + +function references.pagefromhash(hash,destination,page,actions) + local r = actions[1] + if type(r) == "table" then + r = r.i + if r then + r = r.references + if r then + local structure = r.structure + if structure then + local namestack = r.namestack + if namestack then + for i=#namestack,1,-1 do + local d = namestack[i] .. ":" .. destination + page = hash[d] + if page then + destination = d + break + end + end + end + end + end + end + end + return page, destination +end |