diff options
author | Hans Hagen <pragma@wxs.nl> | 2020-11-23 19:48:34 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2020-11-23 19:48:34 +0100 |
commit | 18499e46a49b8ccf4346686d1cf626ada33935b8 (patch) | |
tree | bd0ae7b601b323e20954c10c07598637d9403e00 /tex/context/base/mkiv/strc-tag.lmt | |
parent | 4b089e589d39346a66a27d04f9857fe16e4b7b41 (diff) | |
download | context-18499e46a49b8ccf4346686d1cf626ada33935b8.tar.gz |
2020-11-23 18:39:00
Diffstat (limited to 'tex/context/base/mkiv/strc-tag.lmt')
-rw-r--r-- | tex/context/base/mkiv/strc-tag.lmt | 615 |
1 files changed, 0 insertions, 615 deletions
diff --git a/tex/context/base/mkiv/strc-tag.lmt b/tex/context/base/mkiv/strc-tag.lmt deleted file mode 100644 index 11049abe0..000000000 --- a/tex/context/base/mkiv/strc-tag.lmt +++ /dev/null @@ -1,615 +0,0 @@ -if not modules then modules = { } end modules ['strc-tag'] = { - version = 1.001, - comment = "companion to strc-tag.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- 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, next = type, next -local insert, remove, unpack, concat, merge = table.insert, table.remove, table.unpack, table.concat, table.merge -local find, topattern, format = string.find, string.topattern, string.format -local lpegmatch, P, S, C, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Cc -local allocate = utilities.storage.allocate -local settings_to_hash = utilities.parsers.settings_to_hash -local setmetatableindex = table.setmetatableindex - -local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end) - -local report_tags = logs.reporter("structure","tags") - -local attributes = attributes -local structures = structures -local implement = interfaces.implement - -local a_tagged = attributes.private('tagged') - -local unsetvalue = attributes.unsetvalue -local codeinjections = backends.codeinjections - -local texgetattribute = tex.getattribute -local texsetattribute = tex.setattribute - -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 tagcontext = { } -local tagpatterns = { } -local lasttags = { } -local stacksize = 0 -local metadata = nil -- applied to the next element -local documentdata = { } -local extradata = false - -local tags = structures.tags -tags.taglist = taglist -- can best be hidden -tags.labels = labels -tags.patterns = tagpatterns -tags.specifications = specifications - -function tags.current() - if stacksize > 0 then - return stack[stacksize] -- maybe copy or proxy - end -end - --- Tags are internally stored as: --- --- tag>number tag>number tag>number - -local p_splitter = C((1-S(">"))^1) * P(">") * C(P(1)^1) -tagpatterns.splitter = p_splitter - -local properties = allocate { -- todo: more "record = true" to improve formatting - - document = { pdf = "Div", nature = "display" }, - - division = { pdf = "Div", nature = "display" }, - paragraph = { pdf = "P", nature = "mixed" }, - p = { pdf = "P", nature = "mixed" }, - construct = { pdf = "Span", nature = "inline" }, - highlight = { pdf = "Span", nature = "inline" }, - - section = { pdf = "Sect", nature = "display" }, - sectioncaption = { pdf = "Div", nature = "display", record = true }, - sectiontitle = { pdf = "H", nature = "mixed" }, - sectionnumber = { pdf = "H", nature = "mixed" }, - sectioncontent = { pdf = "Div", nature = "display" }, - - itemgroup = { pdf = "L", nature = "display" }, - item = { pdf = "LI", nature = "display" }, - itemtag = { pdf = "Lbl", nature = "mixed" }, - itemcontent = { pdf = "LBody", nature = "mixed" }, - itemhead = { pdf = "Div", nature = "display" }, - itembody = { pdf = "Div", nature = "display" }, - - description = { pdf = "Div", nature = "display" }, - descriptiontag = { pdf = "Div", nature = "mixed" }, - descriptioncontent = { pdf = "Div", nature = "mixed" }, - descriptionsymbol = { pdf = "Span", nature = "inline" }, -- note reference - - verbatimblock = { pdf = "Code", nature = "display" }, - verbatimlines = { pdf = "Code", nature = "display" }, - verbatimline = { pdf = "Code", nature = "mixed" }, - verbatim = { pdf = "Code", nature = "inline" }, - - lines = { pdf = "Code", nature = "display" }, - line = { pdf = "Code", nature = "mixed" }, - linenumber = { pdf = "Span", nature = "inline" }, - - synonym = { pdf = "Span", nature = "inline" }, - sorting = { pdf = "Span", nature = "inline" }, - - register = { pdf = "Div", nature = "display" }, - registerlocation = { pdf = "Span", nature = "inline" }, - registersection = { pdf = "Div", nature = "display" }, - registertag = { pdf = "Span", nature = "mixed" }, - registerentries = { pdf = "Div", nature = "display" }, - registerentry = { pdf = "Div", nature = "display" }, - registercontent = { pdf = "Span", nature = "mixed" }, - registersee = { pdf = "Span", nature = "mixed" }, - registerpages = { pdf = "Span", nature = "mixed" }, - registerpage = { pdf = "Span", nature = "mixed" }, - registerseparator = { pdf = "Span", nature = "inline" }, - registerpagerange = { pdf = "Span", nature = "mixed" }, - - table = { pdf = "Table", nature = "display" }, - tablerow = { pdf = "TR", nature = "display" }, - tablecell = { pdf = "TD", nature = "mixed" }, - tableheadcell = { pdf = "TH", nature = "mixed" }, - tablehead = { pdf = "THEAD", nature = "display" }, - tablebody = { pdf = "TBODY", nature = "display" }, - tablefoot = { pdf = "TFOOT", nature = "display" }, - - tabulate = { pdf = "Table", nature = "display" }, - tabulaterow = { pdf = "TR", nature = "display" }, - tabulatecell = { pdf = "TD", nature = "mixed" }, - tabulateheadcell = { pdf = "TH", nature = "mixed" }, - tabulatehead = { pdf = "THEAD", nature = "display" }, - tabulatebody = { pdf = "TBODY", nature = "display" }, - tabulatefoot = { pdf = "TFOOT", nature = "display" }, - - list = { pdf = "TOC", nature = "display" }, - listitem = { pdf = "TOCI", nature = "display" }, - listtag = { pdf = "Lbl", nature = "mixed" }, - listcontent = { pdf = "P", nature = "mixed" }, - listdata = { pdf = "P", nature = "mixed" }, - listpage = { pdf = "Reference", nature = "mixed" }, - listtext = { pdf = "Span", nature = "inline" }, - - delimitedblock = { pdf = "BlockQuote", nature = "display" }, - delimited = { pdf = "Quote", nature = "inline" }, - delimitedcontent = { pdf = "Span", nature = "inline" }, - delimitedsymbol = { pdf = "Span", nature = "inline" }, - subsentence = { pdf = "Span", nature = "inline" }, - subsentencecontent = { pdf = "Span", nature = "inline" }, - subsentencesymbol = { pdf = "Span", nature = "inline" }, - - label = { pdf = "Span", nature = "mixed" }, - number = { pdf = "Span", nature = "mixed" }, - - float = { pdf = "Div", nature = "display" }, -- Figure - floatcaption = { pdf = "Caption", nature = "mixed" }, - floatlabel = { pdf = "Span", nature = "inline" }, - floatnumber = { pdf = "Span", nature = "inline" }, - floattext = { pdf = "Span", nature = "mixed" }, - floatcontent = { pdf = "P", nature = "mixed" }, - - image = { pdf = "P", nature = "mixed" }, - mpgraphic = { pdf = "P", nature = "mixed" }, - - formulaset = { pdf = "Div", nature = "display" }, - formula = { pdf = "Div", nature = "display" }, -- Formula - formulacaption = { pdf = "Span", nature = "mixed" }, - formulalabel = { pdf = "Span", nature = "mixed" }, - formulanumber = { pdf = "Span", nature = "mixed" }, - formulacontent = { pdf = "P", nature = "display" }, - subformula = { pdf = "Div", nature = "display" }, - - link = { pdf = "Link", nature = "inline" }, - reference = { pdf = "Span", nature = "inline" }, - - margintextblock = { pdf = "Span", nature = "inline" }, - margintext = { pdf = "Span", nature = "inline" }, - marginanchor = { pdf = "Span", nature = "inline" }, - - math = { pdf = "Div", nature = "inline" }, -- no display - mn = { pdf = "Span", nature = "mixed" }, - mi = { pdf = "Span", nature = "mixed" }, - mo = { pdf = "Span", nature = "mixed" }, - ms = { pdf = "Span", nature = "mixed" }, - mrow = { pdf = "Span", nature = "display" }, - msubsup = { pdf = "Span", nature = "display" }, - msub = { pdf = "Span", nature = "display" }, - msup = { pdf = "Span", nature = "display" }, - merror = { pdf = "Span", nature = "mixed" }, - munderover = { pdf = "Span", nature = "display" }, - munder = { pdf = "Span", nature = "display" }, - mover = { pdf = "Span", nature = "display" }, - mtext = { pdf = "Span", nature = "mixed" }, - mfrac = { pdf = "Span", nature = "display" }, - mroot = { pdf = "Span", nature = "display" }, - msqrt = { pdf = "Span", nature = "display" }, - mfenced = { pdf = "Span", nature = "display" }, - maction = { pdf = "Span", nature = "display" }, - - mstacker = { pdf = "Span", nature = "display" }, -- these are only internally used - mstackertop = { pdf = "Span", nature = "display" }, -- these are only internally used - mstackerbot = { pdf = "Span", nature = "display" }, -- these are only internally used - mstackermid = { pdf = "Span", nature = "display" }, -- these are only internally used - - mtable = { pdf = "Table", nature = "display" }, -- might change - mtr = { pdf = "TR", nature = "display" }, -- might change - mtd = { pdf = "TD", nature = "display" }, -- might change - - ignore = { pdf = "Span", nature = "mixed" }, -- used internally - private = { pdf = "Span", nature = "mixed" }, -- for users (like LS) when they need it - metadata = { pdf = "Div", nature = "display" }, - metavariable = { pdf = "Span", nature = "mixed" }, - - mid = { pdf = "Span", nature = "inline" }, - sub = { pdf = "Span", nature = "inline" }, - sup = { pdf = "Span", nature = "inline" }, - subsup = { pdf = "Span", nature = "inline" }, - - combination = { pdf = "Span", nature = "display" }, - combinationpair = { pdf = "Span", nature = "display" }, - combinationcontent = { pdf = "Span", nature = "mixed" }, - combinationcaption = { pdf = "Span", nature = "mixed" }, - - publications = { pdf = "Div", nature = "display" }, - publication = { pdf = "Div", nature = "mixed" }, - pubfld = { pdf = "Span", nature = "inline" }, - - block = { pdf = "Div", nature = "display" }, - userdata = { pdf = "Div", nature = "display" }, - -} - -tags.properties = properties - -local patterns = setmetatableindex(function(t,tag) - local v = topattern("^" .. tag .. ">") - t[tag] = v - return v -end) - -function tags.locatedtag(tag) - local attribute = texgetattribute(a_tagged) - if attribute >= 0 then - 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 - else - -- enabled but not auto - end - return false -- handy as bogus index -end - -function structures.atlocation(str) - local specification = taglist[texgetattribute(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] - if p then - p[key] = value - else - properties[tag] = { [key] = value } - end -end - -function tags.setaspect(key,value) - local tag = chain[stacksize] - if tag then - local p = properties[tag] - if p then - p[key] = value - else - properties[tag] = { [key] = value } - end - end -end - -function tags.registermetadata(data) - local d = settings_to_hash(data) - if #chain > 1 then - if metadata then - merge(metadata,d) - else - metadata = d - end - else - merge(documentdata,d) - end -end - -function tags.getmetadata() - return documentdata or { } -end - -function tags.registerextradata(name,serializer) - if type(serializer) == "function" then - if extradata then - extradata[name] = serializer - else - extradata = { [name] = serializer } - end - end -end - -function tags.getextradata() - return extradata -end - -function tags.start(tag,specification) - if not enabled then - codeinjections.enabletags() - enabled = true - end - -- - labels[tag] = tag -- can go away - -- - local attribute = #taglist + 1 - local tagindex = (ids[tag] or 0) + 1 - -- - local completetag = tag .. ">" .. tagindex - -- - ids[tag] = tagindex - lasttags[tag] = tagindex - stacksize = stacksize + 1 - -- - 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 userdata == "" then - specification.userdata = nil - elseif 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 - -- - taglist[attribute] = specification - specifications[completetag] = specification - -- - if completetag == "document>1" then - specification.metadata = documentdata - end - -- - texsetattribute(a_tagged,attribute) - return attribute -end - -function tags.restart(attribute) - stacksize = stacksize + 1 - if type(attribute) == "number" then - local taglist = taglist[attribute].taglist - chain[stacksize] = taglist[#taglist] - else - chain[stacksize] = attribute -- a string - attribute = #taglist + 1 - taglist[attribute] = { taglist = { unpack(chain,1,stacksize) } } - end - stack[stacksize] = attribute - texsetattribute(a_tagged,attribute) - return attribute -end - -function tags.stop() - if stacksize > 0 then - stacksize = stacksize - 1 - end - local t = stack[stacksize] - if not t then - if trace_tags then - report_tags("ignoring end tag, previous chain: %s",stacksize > 0 and concat(chain," ",1,stacksize) or "none") - end - t = unsetvalue - end - texsetattribute(a_tagged,t) - return t -end - -function tags.getid(tag,detail) - return ids[tag] or "?" -end - -function tags.last(tag) - return lasttags[tag] -- or false -end - -function tags.lastinchain(tag) - if tag and tag ~= "" then - return tagcontext[tag] - else - return chain[stacksize] - end -end - -local strip = C((1-S(">"))^1) - -function tags.elementtag() - local fulltag = chain[stacksize] - if fulltag then - return lpegmatch(strip,fulltag) - end -end - -function tags.strip(fulltag) - return lpegmatch(strip,fulltag) -end - -function tags.setuserproperties(tag,list) - if not list or list == "" then - tag, list = chain[stacksize], tag - else - tag = tagcontext[tag] - end - if tag then -- an attribute now - local l = settings_to_hash(list) - 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 - -- error - end - end -end - -function tags.handler(head) -- we need a dummy - return head, false -end - -statistics.register("structure elements", function() - if enabled then - 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 - end -end) - -directives.register("backend.addtags", function(v) - if not enabled then - codeinjections.enabletags() - enabled = true - end -end) - --- interface - -local starttag = tags.start - -implement { - name = "strc_tags_start", - public = true, - protected = true, - actions = starttag, - arguments = "argument", -} - -implement { - name = "strc_tags_stop", - public = true, - protected = true, - actions = tags.stop, -} - -implement { - name = "strc_tags_start_userdata", - public = true, - protected = true, - actions = function(tag,userdata) starttag(tag,{ userdata = userdata }) end, - arguments = { "optional", "optional" }, -} - -implement { - name = "strc_tags_start_detail", - public = true, - protected = true, - actions = function(tag,detail) starttag(tag,{ detail = detail }) end, - arguments = "2 arguments", -} - -implement { - name = "strc_tags_start_ignore", - public = true, - protected = true, - actions = function(detail) starttag("ignore",{ detail = detail }) end, - arguments = { "argument" }, -} - -implement { - name = "strc_tags_start_chained", - public = true, - protected = true, - actions = function(tag,detail,parents) starttag(tag,{ detail = detail, parents = parents }) end, - arguments = "3 arguments", -} - -implement { - name = "strc_tags_set_aspect", - public = true, - protected = true, - actions = tags.setaspect, - arguments = "2 arguments" -} - -implement { - name = "settagproperty", - actions = tags.setproperty, - arguments = "3 arguments" -} - -implement { - name = "setelementbackendtag", - public = true, - protected = true, - actions = tags.setproperty, - arguments = { "optional", "'backend'", "optional" }, -} - -implement { - name = "setelementnature", - public = true, - protected = true, - actions = tags.setproperty, - arguments = { "optional", "'nature'", "optional" }, -} - -implement { - name = "strc_tags_get_element_tag", - public = true, - protected = true, - actions = { tags.elementtag, context } -} - -implement { - name = "strc_tags_set_element_user_properties", - public = true, - protected = true, - actions = tags.setuserproperties, - arguments = { "optional", "optional" }, -} - -implement { - name = "doifelseinelement", - public = true, - protected = true, - actions = { structures.atlocation, commands.testcase }, - arguments = "argument", -} - -implement { - name = "settaggedmetadata", - public = true, - protected = true, - actions = tags.registermetadata, - arguments = "optional", -} |