summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2014-07-14 12:38:00 +0200
committerHans Hagen <pragma@wxs.nl>2014-07-14 12:38:00 +0200
commit9db977edc178a6f9503a8864c75b1a8c0a18887b (patch)
tree1bf66ada62acafb9153861e220d4aa07688c233f /tex
parent5b62616c1e2fd2af67f62f9b4c4fcf1190470845 (diff)
downloadcontext-9db977edc178a6f9503a8864c75b1a8c0a18887b.tar.gz
beta 2014.07.14 12:38
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/back-exp-div.lua23
-rw-r--r--tex/context/base/back-exp-html.lua52
-rw-r--r--tex/context/base/back-exp.lua2718
-rw-r--r--tex/context/base/back-exp.mkiv12
-rw-r--r--tex/context/base/buff-ver.mkiv75
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4439 -> 4436 bytes
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/enco-ini.mkiv70
-rw-r--r--tex/context/base/file-lib.lua2
-rw-r--r--tex/context/base/file-res.lua5
-rw-r--r--tex/context/base/font-mis.lua2
-rw-r--r--tex/context/base/font-otf.lua43
-rw-r--r--tex/context/base/status-files.pdfbin24916 -> 24987 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin326318 -> 326325 bytes
-rw-r--r--tex/context/base/x-mathml.mkiv4
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua27
17 files changed, 1734 insertions, 1303 deletions
diff --git a/tex/context/base/back-exp-div.lua b/tex/context/base/back-exp-div.lua
new file mode 100644
index 000000000..4e67d7615
--- /dev/null
+++ b/tex/context/base/back-exp-div.lua
@@ -0,0 +1,23 @@
+return {
+ name = "html export",
+ version = "1.00",
+ comment = "Experimental feature.",
+ author = "Hans Hagen",
+ copyright = "ConTeXt development team",
+ suffix = "html",
+ remapping = {
+ {
+ pattern = "*",
+ element = "div",
+ extras = {
+ namespace = true, -- okay as we have no attributes with that name
+ align = {
+ flushleft = "left",
+ flushright = "right",
+ middle = "center",
+ }
+ }
+ },
+ }
+}
+
diff --git a/tex/context/base/back-exp-html.lua b/tex/context/base/back-exp-html.lua
new file mode 100644
index 000000000..e284c42dd
--- /dev/null
+++ b/tex/context/base/back-exp-html.lua
@@ -0,0 +1,52 @@
+return {
+ name = "html export",
+ version = "1.00",
+ comment = "Experimental feature.",
+ author = "Hans Hagen",
+ copyright = "ConTeXt development team",
+ suffix = "html",
+ remapping = {
+ {
+ pattern = "tabulate",
+ element = "table",
+ class = "tabulate",
+ },
+ {
+ pattern = "tabulaterow",
+ element = "tr",
+ class = "tabulate.tr",
+ },
+ {
+ pattern = "tabulatecell",
+ element = "td",
+ class = "tabulate.td",
+ extras = {
+ align = {
+ flushleft = "tabulate.td.left",
+ flushright = "tabulate.td.right",
+ middle = "tabulate.td.center",
+ }
+ }
+ },
+ {
+ pattern = "break",
+ element = "br",
+ },
+ {
+ pattern = "section",
+ element = "div",
+ },
+ {
+ pattern = "verbatimblock",
+ element = "pre",
+ },
+ {
+ pattern = "verbatimlines|verbatimline",
+ element = "div",
+ },
+ {
+ pattern = "!(div|table|td|tr|pre)",
+ element = "div",
+ },
+ }
+}
diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index 44c2cd539..d17fce135 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -6,7 +6,12 @@ if not modules then modules = { } end modules ['back-exp'] = {
license = "see context related readme files"
}
--- beware: we run out of the 200 local limit
+-- Because we run into the 200 local limit we quite some do .. end wrappers .. not always
+-- that nice but it has to be.
+
+-- Experiments demonstrated that mapping to <div> and classes is messy because we have to
+-- package attributes (some 30) into one set of (space seperatated but prefixed classes)
+-- which only makes things worse .. so if you want something else, use xslt to get there.
-- language -> only mainlanguage, local languages should happen through start/stoplanguage
-- tocs/registers -> maybe add a stripper (i.e. just don't flush entries in final tree)
@@ -23,7 +28,7 @@ if not modules then modules = { } end modules ['back-exp'] = {
-- todo: move critital formatters out of functions
-- todo: delay loading (apart from basic tag stuff)
-local next, type = next, type
+local next, type, tonumber = next, type, tonumber
local format, concat, sub, gsub = string.format, table.concat, string.sub, string.gsub
local validstring = string.valid
local lpegmatch = lpeg.match
@@ -32,12 +37,15 @@ local insert, remove = table.insert, table.remove
local fromunicode16 = fonts.mappings.fromunicode16
local sortedhash = table.sortedhash
local formatters = string.formatters
+local todimen = number.todimen
local trace_export = false trackers.register ("export.trace", function(v) trace_export = v end)
local trace_spacing = false trackers.register ("export.trace.spacing", function(v) trace_spacing = v end)
local less_state = false directives.register("export.lessstate", function(v) less_state = v end)
local show_comment = true directives.register("export.comment", function(v) show_comment = v end)
+show_comment = false -- figure out why break comment
+
-- maybe we will also support these:
--
-- local css_hyphens = false directives.register("export.css.hyphens", function(v) css_hyphens = v end)
@@ -49,7 +57,13 @@ local report_export = logs.reporter("backend","export")
local nodes = nodes
local attributes = attributes
+
local variables = interfaces.variables
+local v_yes = variables.yes
+local v_normal = variables.normal
+local v_flushright = variables.flushright
+local v_middle = variables.middle
+local v_flushleft = variables.flushleft
local settings_to_array = utilities.parsers.settings_to_array
@@ -85,15 +99,14 @@ local line_code = listcodes.line
local texgetcount = tex.getcount
-local a_characters = attributes.private('characters')
-local a_exportstatus = attributes.private('exportstatus')
-
-local a_tagged = attributes.private('tagged')
-local a_taggedpar = attributes.private("taggedpar")
-local a_image = attributes.private('image')
-local a_reference = attributes.private('reference')
-
-local a_textblock = attributes.private("textblock")
+local privateattribute = attributes.private
+local a_characters = privateattribute('characters')
+local a_exportstatus = privateattribute('exportstatus')
+local a_tagged = privateattribute('tagged')
+local a_taggedpar = privateattribute("taggedpar")
+local a_image = privateattribute('image')
+local a_reference = privateattribute('reference')
+local a_textblock = privateattribute("textblock")
local nuts = nodes.nuts
local tonut = nuts.tonut
@@ -126,7 +139,7 @@ local stoptiming = statistics.stoptiming
-- todo: more locals (and optimize)
-local exportversion = "0.30"
+local exportversion = "0.31"
local nofcurrentcontent = 0 -- so we don't free (less garbage collection)
local currentcontent = { }
@@ -152,6 +165,8 @@ local treestack = { }
local nesting = { }
local currentdepth = 0
+local wrapups = { }
+
local tree = { data = { }, fulltag == "root" } -- root
local treeroot = tree
local treehash = { }
@@ -167,7 +182,8 @@ local somespace = { [0x20] = true, [" "] = true } -- for testing
local entities = { ["&"] = "&amp;", [">"] = "&gt;", ["<"] = "&lt;" }
local attribentities = { ["&"] = "&amp;", [">"] = "&gt;", ["<"] = "&lt;", ['"'] = "quot;" }
-local entityremapper = utf.remapper(entities)
+local p_entity = lpeg.replacer(entities) -- was: entityremapper = utf.remapper(entities)
+local p_attribute = lpeg.replacer(attribentities)
local alignmapping = {
flushright = "right",
@@ -176,10 +192,10 @@ local alignmapping = {
}
local numbertoallign = {
- [0] = "justify", ["0"] = "justify", [variables.normal ] = "justify",
- [1] = "right", ["1"] = "right", [variables.flushright] = "right",
- [2] = "center", ["2"] = "center", [variables.middle ] = "center",
- [3] = "left", ["3"] = "left", [variables.flushleft ] = "left",
+ [0] = "justify", ["0"] = "justify", [v_normal ] = "justify",
+ [1] = "right", ["1"] = "right", [v_flushright] = "right",
+ [2] = "center", ["2"] = "center", [v_middle ] = "center",
+ [3] = "left", ["3"] = "left", [v_flushleft ] = "left",
}
local defaultnature = "mixed" -- "inline"
@@ -192,10 +208,13 @@ setmetatableindex(used, function(t,k)
end
end)
+local f_entity = formatters["&#x%X;"]
+local f_attribute = formatters[" %s=%q"]
+
setmetatableindex(specialspaces, function(t,k)
local v = utfchar(k)
t[k] = v
- entities[v] = formatters["&#x%X;"](k)
+ entities[v] = f_entity(k)
somespace[k] = true
somespace[v] = true
return v
@@ -242,9 +261,17 @@ 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 formatters[' %s="%s"'](key,gsub(value,".",attribentities))
+ return f_attribute(key,lpegmatch(p_attribute,value))
else
return ""
end
@@ -261,7 +288,7 @@ end
local listdata = { }
-local function hashlistdata()
+function wrapups.hashlistdata()
local c = structures.lists.collected
for i=1,#c do
local ci = c[i]
@@ -292,86 +319,91 @@ function structurestags.setattributehash(fulltag,key,value) -- public hash
end
end
+local usedstyles = { }
--- experiment: styles and images
---
--- officially we should convert to bp but we round anyway
+do
-local usedstyles = { }
+ -- experiment: styles and images
+ --
+ -- officially we should convert to bp but we round anyway
--- /* padding : ; */
--- /* text-justify : inter-word ; */
+ -- /* padding : ; */
+ -- /* text-justify : inter-word ; */
-local documenttemplate = [[
+local f_document = formatters [ [[
document {
font-size : %s !important ;
max-width : %s !important ;
text-align : %s !important ;
hyphens : %s !important ;
}
-]]
+]] ]
-local styletemplate = [[
+local f_style = formatters [ [[
%s[detail='%s'] {
font-style : %s ;
font-variant : %s ;
font-weight : %s ;
font-family : %s ;
color : %s ;
-}]]
+}]] ]
-local function allusedstyles(xmlfile)
- local result = { format("/* styles for file %s */",xmlfile) }
- --
- local bodyfont = finetuning.bodyfont
- local width = finetuning.width
- local hyphen = finetuning.hyphen
- local align = finetuning.align
- --
- if not bodyfont or bodyfont == "" then
- bodyfont = "12pt"
- elseif type(bodyfont) == "number" then
- bodyfont = number.todimen(bodyfont,"pt","%ipt") or "12pt"
- end
- if not width or width == "" then
- width = "50em"
- elseif type(width) == "number" then
- width = number.todimen(width,"pt","%ipt") or "50em"
- end
- if hyphen == variables.yes then
- hyphen = "manual"
- else
- hyphen = "inherited"
- end
- if align then
- align = numbertoallign[align]
- end
- if not align then
- align = hyphens and "justify" or "inherited"
+ function wrapups.allusedstyles(xmlfile)
+ local result = { formatters["/* %s for file %s */"]("styles",xmlfile) }
+ --
+ local bodyfont = finetuning.bodyfont
+ local width = finetuning.width
+ local hyphen = finetuning.hyphen
+ local align = finetuning.align
+ --
+ if not bodyfont or bodyfont == "" then
+ bodyfont = "12pt"
+ elseif type(bodyfont) == "number" then
+ bodyfont = todimen(bodyfont,"pt","%ipt") or "12pt"
+ end
+ if not width or width == "" then
+ width = "50em"
+ elseif type(width) == "number" then
+ width = todimen(width,"pt","%ipt") or "50em"
+ end
+ if hyphen == v_yes then
+ hyphen = "manual"
+ else
+ hyphen = "inherited"
+ end
+ if align then
+ align = numbertoallign[align]
+ end
+ if not align then
+ align = hyphens and "justify" or "inherited"
+ end
+ --
+ result[#result+1] = f_document(bodyfont,width,align,hyphen)
+ --
+ local colorspecification = xml.css.colorspecification
+ local fontspecification = xml.css.fontspecification
+ for element, details in sortedhash(usedstyles) do
+ for detail, data in sortedhash(details) do
+ local s = fontspecification(data.style)
+ local c = colorspecification(data.color)
+ result[#result+1] = f_style(element,detail,
+ s.style or "inherit",
+ s.variant or "inherit",
+ s.weight or "inherit",
+ s.family or "inherit",
+ c or "inherit")
+ end
+ end
+ return concat(result,"\n\n")
end
- --
- result[#result+1] = format(documenttemplate,bodyfont,width,align,hyphen)
- --
- local colorspecification = xml.css.colorspecification
- local fontspecification = xml.css.fontspecification
- for element, details in sortedhash(usedstyles) do
- for detail, data in sortedhash(details) do
- local s = fontspecification(data.style)
- local c = colorspecification(data.color)
- result[#result+1] = formatters[styletemplate](element,detail,
- s.style or "inherit",
- s.variant or "inherit",
- s.weight or "inherit",
- s.family or "inherit",
- c or "inherit")
- end
- end
- return concat(result,"\n\n")
+
end
local usedimages = { }
-local imagetemplate = [[
+do
+
+local f_image = formatters [ [[
%s[id="%s"] {
display : block ;
background-image : url(%s) ;
@@ -379,36 +411,38 @@ local imagetemplate = [[
background-repeat : no-repeat ;
width : %s ;
height : %s ;
-}]]
-
-local function allusedimages(xmlfile)
- local result = { format("/* images for file %s */",xmlfile) }
- for element, details in sortedhash(usedimages) do
- for detail, data in sortedhash(details) do
- local name = data.name
- if file.suffix(name) == "pdf" then
- -- temp hack .. we will have a remapper
- name = file.replacesuffix(name,"svg")
+}]] ]
+
+ function wrapups.allusedimages(xmlfile)
+ local result = { formatters["/* %s for file %s */"]("images",xmlfile) }
+ for element, details in sortedhash(usedimages) do
+ for detail, data in sortedhash(details) do
+ local name = data.name
+ if file.suffix(name) == "pdf" then
+ -- temp hack .. we will have a remapper
+ name = file.replacesuffix(name,"svg")
+ end
+ result[#result+1] = f_image(element,detail,name,data.width,data.height)
end
- result[#result+1] = formatters[imagetemplate](element,detail,name,data.width,data.height)
end
+ return concat(result,"\n\n")
end
- return concat(result,"\n\n")
-end
-local function uniqueusedimages()
- local unique = { }
- for element, details in next, usedimages do
- for detail, data in next, details do
- local name = data.name
- if file.suffix(name) == "pdf" then
- unique[file.replacesuffix(name,"svg")] = name
- else
- unique[name] = name
+ function wrapups.uniqueusedimages()
+ local unique = { }
+ for element, details in next, usedimages do
+ for detail, data in next, details do
+ local name = data.name
+ if file.suffix(name) == "pdf" then
+ unique[file.replacesuffix(name,"svg")] = name
+ else
+ unique[name] = name
+ end
end
end
+ return unique
end
- return unique
+
end
--
@@ -447,198 +481,248 @@ local function makebreaknode(attributes) -- maybe no fulltag
}
end
-local fields = { "title", "subtitle", "author", "keywords" }
+do
-local function checkdocument(root)
- local data = root.data
- if data then
- for i=1,#data do
- local di = data[i]
- local tg = di.tg
- if tg == "noexport" then
- local ud = userdata[di.fulltag]
- local comment = ud and ud.comment
- if comment then
- di.element = "comment"
- di.data = { { content = comment } }
- ud.comment = nil
+ local fields = { "title", "subtitle", "author", "keywords" }
+
+ local function checkdocument(root)
+ local data = root.data
+ if data then
+ for i=1,#data 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
+ if comment then
+ di.element = "comment"
+ di.data = { { content = comment } }
+ ud.comment = nil
+ else
+ data[i] = false
+ end
+ else
+ data[i] = false
+ end
+ elseif di.content then
+ -- okay
+ elseif tg == "ignore" then
+ di.element = ""
+ checkdocument(di)
else
- data[i] = false
- -- di.element = ""
- -- di.data = nil
+ checkdocument(di) -- new, else no noexport handling
end
- elseif di.content then
- -- okay
- elseif tg == "ignore" then
- di.element = ""
- checkdocument(di)
- else
- checkdocument(di) -- new, else no noexport handling
end
end
end
-end
-function extras.document(result,element,detail,n,fulltag,di)
- result[#result+1] = format(" language=%q",languagenames[texgetcount("mainlanguagenumber")])
- if not less_state then
- result[#result+1] = format(" file=%q",tex.jobname)
- result[#result+1] = format(" date=%q",os.date())
- result[#result+1] = format(" context=%q",environment.version)
- result[#result+1] = format(" version=%q",exportversion)
- result[#result+1] = format(" xmlns:m=%q","http://www.w3.org/1998/Math/MathML")
- 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] = formatters[" %s=%q"](key,value)
+ function extras.document(result,element,detail,n,fulltag,di)
+ result[#result+1] = f_attribute("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","http://www.w3.org/1998/Math/MathML")
+ 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)
+ end
end
end
+ checkdocument(di)
end
- checkdocument(di)
+
end
-local itemgroups = { }
+do
-function structurestags.setitemgroup(current,packed,symbol)
- itemgroups[detailedtag("itemgroup",current)] = {
- packed = packed,
- symbol = symbol,
- }
-end
+ local itemgroups = { }
-function extras.itemgroup(result,element,detail,n,fulltag,di)
- local hash = itemgroups[fulltag]
- if hash then
- local v = hash.packed
- if v then
- result[#result+1] = " packed='yes'"
- end
- local v = hash.symbol
- if v then
- result[#result+1] = attribute("symbol",v)
+ local f_symbol = formatters[" symbol='%s'"]
+ local s_packed = " packed='yes'"
+
+ function structurestags.setitemgroup(current,packed,symbol)
+ itemgroups[detailedtag("itemgroup",current)] = {
+ packed = packed,
+ symbol = symbol,
+ }
+ end
+
+ function extras.itemgroup(result,element,detail,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
end
end
+
end
-local synonyms = { }
+do
-function structurestags.setsynonym(current,tag)
- synonyms[detailedtag("synonym",current)] = tag
-end
+ local synonyms = { }
+ local sortings = { }
+
+ local f_tag = formatters[" tag='%s'"]
-function extras.synonym(result,element,detail,n,fulltag,di)
- local tag = synonyms[fulltag]
- if tag then
- result[#result+1] = formatters[" tag='%s'"](tag)
+ function structurestags.setsynonym(current,tag)
+ synonyms[detailedtag("synonym",current)] = tag
end
-end
-local sortings = { }
+ function extras.synonym(result,element,detail,n,fulltag,di)
+ local tag = synonyms[fulltag]
+ if tag then
+ result[#result+1] = f_tag(tag)
+ end
+ end
-function structurestags.setsorting(current,tag)
- sortings[detailedtag("sorting",current)] = tag
-end
+ function structurestags.setsorting(current,tag)
+ sortings[detailedtag("sorting",current)] = tag
+ end
-function extras.sorting(result,element,detail,n,fulltag,di)
- local tag = sortings[fulltag]
- if tag then
- result[#result+1] = formatters[" tag='%s'"](tag)
+ function extras.sorting(result,element,detail,n,fulltag,di)
+ local tag = sortings[fulltag]
+ if tag then
+ result[#result+1] = f_tag(tag)
+ end
end
+
end
-usedstyles.highlight = { }
+do
+
+ local highlight = { }
+ usedstyles.highlight = highlight
+
+ function structurestags.sethighlight(current,style,color) -- we assume global styles
+ highlight[current] = {
+ style = style, -- xml.css.fontspecification(style),
+ color = color, -- xml.css.colorspec(color),
+ }
+ end
-function structurestags.sethighlight(current,style,color) -- we assume global styles
- usedstyles.highlight[current] = {
- style = style, -- xml.css.fontspecification(style),
- color = color, -- xml.css.colorspec(color),
- }
end
-local descriptions = { }
-local symbols = { }
-local linked = { }
+do
-function structurestags.setdescription(tag,n)
- local nd = structures.notes.get(tag,n) -- todo: use listdata instead
- if nd then
- local references = nd.references
- descriptions[references and references.internal] = detailedtag("description",tag)
+ local descriptions = { }
+ local symbols = { }
+ local linked = { }
+
+ local f_insert = formatters[" insert='%s'"]
+
+ function structurestags.setdescription(tag,n)
+ local nd = structures.notes.get(tag,n) -- todo: use listdata instead
+ if nd then
+ local references = nd.references
+ descriptions[references and references.internal] = detailedtag("description",tag)
+ end
end
-end
-function structurestags.setdescriptionsymbol(tag,n)
- 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)
+ function structurestags.setdescriptionsymbol(tag,n)
+ 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)
+ end
end
-end
-function finalizers.descriptions(tree)
- local n = 0
- for id, tag in next, descriptions do
- local sym = symbols[id]
- if sym then
- n = n + 1
- linked[tag] = n
- linked[sym] = n
+ function finalizers.descriptions(tree)
+ local n = 0
+ for id, tag in next, descriptions do
+ local sym = symbols[id]
+ if sym then
+ n = n + 1
+ linked[tag] = n
+ linked[sym] = n
+ end
end
end
-end
-function extras.description(result,element,detail,n,fulltag,di)
- local id = linked[fulltag]
- if id then
- result[#result+1] = formatters[" insert='%s'"](id) -- maybe just fulltag
+ function extras.description(result,element,detail,n,fulltag,di)
+ local id = linked[fulltag]
+ if id then
+ result[#result+1] = f_insert(id) -- maybe just fulltag
+ end
end
-end
-function extras.descriptionsymbol(result,element,detail,n,fulltag,di)
- local id = linked[fulltag]
- if id then
- result[#result+1] = formatters[" insert='%s'"](id)
+ function extras.descriptionsymbol(result,element,detail,n,fulltag,di)
+ local id = linked[fulltag]
+ if id then
+ result[#result+1] = f_insert(id)
+ end
end
+
end
-usedimages.image = { }
+-- -- todo: ignore breaks
+--
+-- function extras.verbatimline(result,element,detail,n,fulltag,di)
+-- inspect(di)
+-- end
-function structurestags.setfigure(name,page,width,height)
- usedimages.image[detailedtag("image")] = {
- name = name,
- page = page,
- width = number.todimen(width, "cm","%0.3Fcm"),
- height = number.todimen(height,"cm","%0.3Fcm"),
- }
-end
+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,page,width,height)
+ image[detailedtag("image")] = {
+ name = name,
+ page = page,
+ width = todimen(width, "cm","%0.3Fcm"),
+ height = todimen(height,"cm","%0.3Fcm"),
+ }
+ end
-function extras.image(result,element,detail,n,fulltag,di)
- local data = usedimages.image[fulltag]
- if data then
- result[#result+1] = attribute("name",data.name)
- if tonumber(data.page) > 1 then
- result[#result+1] = formatters[" page='%s'"](data.page)
+ function extras.image(result,element,detail,n,fulltag,di)
+ local data = image[fulltag]
+ if data then
+ result[#result+1] = attribute("name",data.name)
+ local page = tonumber(data.page)
+ if page and page > 1 then
+ result[#result+1] = f_imagepage(page)
+ end
+ result[#result+1] = f_imagespec(fulltag,data.width,data.height)
end
- result[#result+1] = formatters[" id='%s' width='%s' height='%s'"](fulltag,data.width,data.height)
end
+
end
-local combinations = { }
+do
-function structurestags.setcombination(nx,ny)
- combinations[detailedtag("combination")] = {
- nx = nx,
- ny = ny,
- }
-end
+ local combinations = { }
+
+ local f_combispec = formatters[" nx='%s' ny='%s'"]
-function extras.combination(result,element,detail,n,fulltag,di)
- local data = combinations[fulltag]
- if data then
- result[#result+1] = formatters[" nx='%s' ny='%s'"](data.nx,data.ny)
+ function structurestags.setcombination(nx,ny)
+ combinations[detailedtag("combination")] = {
+ nx = nx,
+ ny = ny,
+ }
end
+
+ function extras.combination(result,element,detail,n,fulltag,di)
+ local data = combinations[fulltag]
+ if data then
+ result[#result+1] = f_combispec(data.nx,data.ny)
+ end
+ end
+
end
-- quite some code deals with exporting references --
@@ -680,978 +764,1081 @@ evaluators.special = function(result,var)
end
end
-evaluators["special outer with operation"] = evaluators.special
-evaluators["special operation"] = evaluators.special
-evaluators["special operation with arguments"] = evaluators.special
+local referencehash = { }
-function specials.url(result,var)
- local url = references.checkedurl(var.operation)
- if url then
- result[#result+1] = attribute("url",url)
- end
-end
+do
-function specials.file(result,var)
- local file = references.checkedfile(var.operation)
- if file then
- result[#result+1] = attribute("file",file)
+ evaluators["special outer with operation"] = evaluators.special
+ evaluators["special operation"] = evaluators.special
+ evaluators["special operation with arguments"] = evaluators.special
+
+ local f_location = formatters[" location='aut:%s'"]
+ local f_prefix = formatters[" prefix='%s'"]
+ local f_destination = formatters[" destination='%s'"]
+ local f_reference = formatters[" reference='%s'"]
+ local f_url = formatters[" url='%s'"]
+ local f_file = formatters[" file='%s'"]
+
+ function specials.url(result,var)
+ local url = references.checkedurl(var.operation)
+ if url and url ~= "" then
+ result[#result+1] = f_url(url)
+ end
end
-end
-function specials.fileorurl(result,var)
- local file, url = references.checkedfileorurl(var.operation,var.operation)
- if url then
- result[#result+1] = attribute("url",url)
- elseif file then
- result[#result+1] = attribute("file",file)
+ function specials.file(result,var)
+ local file = references.checkedfile(var.operation)
+ if file and file ~= "" then
+ result[#result+1] = f_file(file)
+ end
end
-end
-function specials.internal(result,var)
- local internal = references.checkedurl(var.operation)
- if internal then
- result[#result+1] = formatters[" location='aut:%s'"](internal)
+ function specials.fileorurl(result,var)
+ local file, url = references.checkedfileorurl(var.operation,var.operation)
+ if url and url ~= "" then
+ result[#result+1] = f_url(url)
+ elseif file and file ~= "" then
+ result[#result+1] = f_file(file)
+ end
end
-end
-local referencehash = { }
+ function specials.internal(result,var)
+ local internal = references.checkedurl(var.operation)
+ if internal then
+ result[#result+1] = f_location(internal)
+ end
+ end
-local function adddestination(result,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] = formatters[" prefix='%s'"](prefix)
- end
- result[#result+1] = formatters[" destination='%s'"](reference)
- for i=1,#references do
- local r = references[i]
- local e = evaluators[r.kind]
- if e then
- e(result,r)
+ local function adddestination(result,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)
+ end
+ result[#result+1] = f_destination(reference)
+ for i=1,#references do
+ local r = references[i]
+ local e = evaluators[r.kind]
+ if e then
+ e(result,r)
+ end
end
end
end
end
-end
-local function addreference(result,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] = formatters[" prefix='%s'"](prefix)
+ local function addreference(result,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)
+ end
+ result[#result+1] = f_reference(reference)
+ end
+ local internal = references.internal
+ if internal and internal ~= "" then
+ result[#result+1] = f_location(internal)
end
- result[#result+1] = formatters[" reference='%s'"](reference)
- end
- local internal = references.internal
- if internal and internal ~= "" then
- result[#result+1] = formatters[" location='aut:%s'"](internal)
end
end
-end
-function extras.link(result,element,detail,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))
- return true
- else
- local data = di.data
- if data then
- for i=1,#data do
- local di = data[i]
- if di then
- local fulltag = di.fulltag
- if fulltag and extras.link(result,element,detail,n,fulltag,di) then
- return true
+ local function link(result,element,detail,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))
+ return true
+ else
+ local data = di.data
+ if data then
+ for i=1,#data do
+ local di = data[i]
+ if di then
+ local fulltag = di.fulltag
+ if fulltag and link(result,element,detail,n,fulltag,di) then
+ return true
+ end
end
end
end
end
end
+
+ extras.adddestination = adddestination
+ extras.addreference = addreference
+ extras.link = link
+
end
-- no settings, as these are obscure ones
-local automathrows = true directives.register("backend.export.math.autorows", function(v) automathrows = v end)
-local automathapply = true directives.register("backend.export.math.autoapply", function(v) automathapply = v end)
-local automathnumber = true directives.register("backend.export.math.autonumber", function(v) automathnumber = v end)
-local automathstrip = true directives.register("backend.export.math.autostrip", function(v) automathstrip = v end)
-
-local functions = mathematics.categories.functions
-
-local function collapse(di,i,data,ndata,detail,element)
- local collapsing = di.data
- if data then
- di.element = element
- di.detail = nil
- i = i + 1
- while i <= ndata do
- local dn = data[i]
- if dn.detail == detail then
- collapsing[#collapsing+1] = dn.data[1]
- dn.skip = "ignore"
- i = i + 1
- else
- break
+do
+
+ local automathrows = true directives.register("backend.export.math.autorows", function(v) automathrows = v end)
+ local automathapply = true directives.register("backend.export.math.autoapply", function(v) automathapply = v end)
+ local automathnumber = true directives.register("backend.export.math.autonumber", function(v) automathnumber = v end)
+ local automathstrip = true directives.register("backend.export.math.autostrip", function(v) automathstrip = v end)
+
+ local functions = mathematics.categories.functions
+
+ local function collapse(di,i,data,ndata,detail,element)
+ local collapsing = di.data
+ if data then
+ di.element = element
+ di.detail = nil
+ i = i + 1
+ while i <= ndata do
+ local dn = data[i]
+ if dn.detail == detail then
+ collapsing[#collapsing+1] = dn.data[1]
+ dn.skip = "ignore"
+ i = i + 1
+ else
+ break
+ end
end
end
+ return i
end
- return i
-end
-local function collapse_mn(di,i,data,ndata)
- local collapsing = di.data
- if data then
- i = i + 1
- while i <= ndata do
- local dn = data[i]
- local tg = dn.tg
- if tg == "mn" then
- collapsing[#collapsing+1] = dn.data[1]
- dn.skip = "ignore"
- i = i + 1
- elseif tg == "mo" then
- local d = dn.data[1]
- if d == "." then
- collapsing[#collapsing+1] = d
+ local function collapse_mn(di,i,data,ndata)
+ local collapsing = di.data
+ if data then
+ i = i + 1
+ while i <= ndata do
+ local dn = data[i]
+ local tg = dn.tg
+ if tg == "mn" then
+ collapsing[#collapsing+1] = dn.data[1]
dn.skip = "ignore"
i = i + 1
+ elseif tg == "mo" then
+ local d = dn.data[1]
+ if d == "." then
+ collapsing[#collapsing+1] = d
+ dn.skip = "ignore"
+ i = i + 1
+ else
+ break
+ end
else
break
end
- else
- break
end
end
+ return i
end
- return i
-end
--- maybe delay __i__ till we need it
+ -- maybe delay __i__ till we need it
-local apply_function = {
- {
- element = "mo",
- -- comment = "apply function",
- -- data = { utfchar(0x2061) },
- data = { "&#x2061;" },
- nature = "mixed",
+ local apply_function = {
+ {
+ element = "mo",
+ -- comment = "apply function",
+ -- data = { utfchar(0x2061) },
+ data = { "&#x2061;" },
+ nature = "mixed",
+ }
}
-}
-local functioncontent = { }
+ local functioncontent = { }
-setmetatableindex(functioncontent,function(t,k)
- local v = { { content = k } }
- t[k] = v
- return v
-end)
+ setmetatableindex(functioncontent,function(t,k)
+ local v = { { content = k } }
+ t[k] = v
+ return v
+ end)
-local function checkmath(root) -- we can provide utf.toentities as an option
- local data = root.data
- if data then
- local ndata = #data
- local roottg = root.tg
- if roottg == "msubsup" then
- local nucleus, superscript, subscript
- for i=1,ndata do
- local di = data[i]
- if not di then
- -- weird
- elseif di.content then
- -- text
- elseif not nucleus then
- nucleus = i
- elseif not superscript then
- superscript = i
- elseif not subscript then
- subscript = i
- else
- -- error
- end
- end
- if superscript and subscript then
- local sup, sub = data[superscript], data[subscript]
- data[superscript], data[subscript] = sub, sup
- -- sub.__o__, sup.__o__ = subscript, superscript
- sub.__i__, sup.__i__ = superscript, subscript
- end
- elseif roottg == "mfenced" then
- local new, n = { }, 0
- local attributes = { }
- root.attributes = attributes
- for i=1,ndata do
- local di = data[i]
- if not di then
- -- weird
- elseif di.content then
- n = n + 1
- new[n] = di
- else
- local tg = di.tg
- if tg == "mleft" then
- attributes.left = tostring(di.data[1].data[1].content)
- elseif tg == "mmiddle" then
- attributes.middle = tostring(di.data[1].data[1].content)
- elseif tg == "mright" then
- attributes.right = tostring(di.data[1].data[1].content)
+ local function checkmath(root) -- we can provide utf.toentities as an option
+ local data = root.data
+ if data then
+ local ndata = #data
+ local roottg = root.tg
+ if roottg == "msubsup" then
+ local nucleus, superscript, subscript
+ for i=1,ndata do
+ local di = data[i]
+ if not di then
+ -- weird
+ elseif di.content then
+ -- text
+ elseif not nucleus then
+ nucleus = i
+ elseif not superscript then
+ superscript = i
+ elseif not subscript then
+ subscript = i
else
+ -- error
+ end
+ end
+ if superscript and subscript then
+ local sup, sub = data[superscript], data[subscript]
+ data[superscript], data[subscript] = sub, sup
+ -- sub.__o__, sup.__o__ = subscript, superscript
+ sub.__i__, sup.__i__ = superscript, subscript
+ end
+ elseif roottg == "mfenced" then
+ local new, n = { }, 0
+ local attributes = { }
+ root.attributes = attributes
+ for i=1,ndata do
+ local di = data[i]
+ if not di then
+ -- weird
+ elseif di.content then
n = n + 1
- di.__i__ = n
new[n] = di
+ else
+ local tg = di.tg
+ if tg == "mleft" then
+ attributes.left = tostring(di.data[1].data[1].content)
+ elseif tg == "mmiddle" then
+ attributes.middle = tostring(di.data[1].data[1].content)
+ elseif tg == "mright" then
+ attributes.right = tostring(di.data[1].data[1].content)
+ else
+ n = n + 1
+ di.__i__ = n
+ new[n] = di
+ end
end
end
+ root.data = new
+ ndata = n
end
- root.data = new
- ndata = n
- end
- if ndata == 0 then
- return
- elseif ndata == 1 then
- local d = data[1]
- if not d then
- return
- elseif d.content then
+ if ndata == 0 then
return
- elseif #root.data == 1 then
- local tg = d.tg
- if automathrows and roottg == "mrow" then
- -- maybe just always ! check spec first
- if tg == "mrow" or tg == "mfenced" or tg == "mfrac" or tg == "mroot" or tg == "msqrt"then
- root.skip = "comment"
- elseif tg == "mo" then
- root.skip = "comment"
- end
- elseif roottg == "mo" then
- if tg == "mo" then
- root.skip = "comment"
+ elseif ndata == 1 then
+ local d = data[1]
+ if not d then
+ return
+ elseif d.content then
+ return
+ elseif #root.data == 1 then
+ local tg = d.tg
+ if automathrows and roottg == "mrow" then
+ -- maybe just always ! check spec first
+ if tg == "mrow" or tg == "mfenced" or tg == "mfrac" or tg == "mroot" or tg == "msqrt"then
+ root.skip = "comment"
+ elseif tg == "mo" then
+ root.skip = "comment"
+ end
+ elseif roottg == "mo" then
+ if tg == "mo" then
+ root.skip = "comment"
+ end
end
end
end
- end
- local i = 1
- while i <= ndata do -- -- -- TOO MUCH NESTED CHECKING -- -- --
- 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" or tg == "munder" or tg == "munderover" then
- if detail == "accent" then
- di.attributes = { accent = "true" }
- di.detail = nil
- end
- checkmath(di)
- i = i + 1
- elseif tg == "mroot" then
- if #di.data == 1 then
- -- else firefox complains
- di.element = "msqrt"
- end
- checkmath(di)
- i = i + 1
- elseif tg == "break" then
- di.skip = "comment"
- i = i + 1
- elseif tg == "mrow" and detail then
- di.detail = nil
- checkmath(di)
- di = {
- element = "maction",
- nature = "display",
- attributes = { actiontype = detail },
- data = { di },
- n = 0,
- }
- 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
+ local i = 1
+ while i <= ndata do -- -- -- TOO MUCH NESTED CHECKING -- -- --
+ 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" or tg == "munder" or tg == "munderover" then
+ if detail == "accent" then
+ di.attributes = { accent = "true" }
+ di.detail = nil
end
- if tg == "mi" then -- function
- if roottg == "mrow" then
- root.skip = "comment"
- root.element = "function"
- end
+ checkmath(di)
+ i = i + 1
+ elseif tg == "mroot" then
+ if #di.data == 1 then
+ -- else firefox complains
+ di.element = "msqrt"
+ end
+ checkmath(di)
+ i = i + 1
+ elseif tg == "break" then
+ di.skip = "comment"
+ i = i + 1
+ elseif tg == "mrow" and detail then
+ di.detail = nil
+ checkmath(di)
+ di = {
+ element = "maction",
+ nature = "display",
+ attributes = { actiontype = detail },
+ data = { di },
+ n = 0,
+ }
+ 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")
- 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)
+ else -- can be string or boolean
+ if parenttg ~= "mtext" and di == " " then
+ data[i] = false
+ end
i = i + 1
end
- else -- can be string or boolean
- if parenttg ~= "mtext" and di == " " then
- data[i] = false
- end
- i = i + 1
end
end
end
-end
-function stripmath(di)
- if not di then
- --
- elseif di.content then
- return di
- else
- local tg = di.tg
- if tg == "mtext" or tg == "ms" then
+ function stripmath(di)
+ if not di then
+ --
+ elseif di.content then
return di
else
- local data = di.data
- local ndata = #data
- local n = 0
- for i=1,ndata do
- local di = data[i]
- if di and not di.content then
- di = stripmath(di)
- end
- if di then
- local content = di.content
- if not content then
- n = n + 1
- di.__i__ = n
- data[n] = di
- elseif content == " " or content == "" then
- -- skip
- else
- n = n + 1
- data[n] = di
+ local tg = di.tg
+ if tg == "mtext" or tg == "ms" then
+ return di
+ else
+ local data = di.data
+ local ndata = #data
+ local n = 0
+ for i=1,ndata do
+ local di = data[i]
+ if di and not di.content then
+ di = stripmath(di)
+ end
+ if di then
+ local content = di.content
+ if not content then
+ n = n + 1
+ di.__i__ = n
+ data[n] = di
+ elseif content == " " or content == "" then
+ -- skip
+ else
+ n = n + 1
+ data[n] = di
+ end
end
end
- end
- for i=ndata,n+1,-1 do
- data[i] = nil
- end
- if #data > 0 then
- return di
+ for i=ndata,n+1,-1 do
+ data[i] = nil
+ end
+ if #data > 0 then
+ return di
+ end
end
end
end
-end
-function checks.math(di)
- local hash = attributehash[di.fulltag]
- local mode = (hash and hash.mode) == "display" and "block" or "inline"
- di.attributes = {
- display = mode
- }
- -- can be option if needed:
- if mode == "inline" then
- di.nature = "mixed" -- else spacing problem (maybe inline)
- else
- di.nature = "display"
- end
- if automathstrip then
- stripmath(di)
+ function checks.math(di)
+ local hash = attributehash[di.fulltag]
+ local mode = (hash and hash.mode) == "display" and "block" or "inline"
+ di.attributes = {
+ display = mode
+ }
+ -- can be option if needed:
+ if mode == "inline" then
+ di.nature = "mixed" -- else spacing problem (maybe inline)
+ else
+ di.nature = "display"
+ end
+ if automathstrip then
+ stripmath(di)
+ end
+ checkmath(di)
end
- checkmath(di)
-end
-local a, z, A, Z = 0x61, 0x7A, 0x41, 0x5A
+ local a, z, A, Z = 0x61, 0x7A, 0x41, 0x5A
-function extras.mi(result,element,detail,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
- if (v >= a and v <= z) or (v >= A and v <= Z) then
- local a = di.attributes
- if a then
- a.mathvariant = "normal"
- else
- di.attributes = { mathvariant = "normal" }
+ function extras.mi(result,element,detail,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
+ if (v >= a and v <= z) or (v >= A and v <= Z) then
+ local a = di.attributes
+ if a then
+ a.mathvariant = "normal"
+ else
+ di.attributes = { mathvariant = "normal" }
+ end
end
end
end
end
+
end
-function extras.section(result,element,detail,n,fulltag,di)
- local data = listdata[fulltag]
- if data then
- addreference(result,data.references)
- return true
- else
- local data = di.data
+do
+
+ local function section(result,element,detail,n,fulltag,di)
+ local data = listdata[fulltag]
if data then
- for i=1,#data do
- local di = data[i]
- if di then
- local ft = di.fulltag
- if ft and extras.section(result,element,detail,n,ft,di) then
- return true
+ extras.addreference(result,data.references)
+ return true
+ else
+ local data = di.data
+ if data then
+ for i=1,#data do
+ local di = data[i]
+ if di then
+ local ft = di.fulltag
+ if ft and section(result,element,detail,n,ft,di) then
+ return true
+ end
end
end
end
end
end
-end
-function extras.float(result,element,detail,n,fulltag,di)
- local data = listdata[fulltag]
- if data then
- addreference(result,data.references)
- return true
- else
- local data = di.data
+ extras.section = section
+
+ function extras.float(result,element,detail,n,fulltag,di)
+ local data = listdata[fulltag]
if data then
- for i=1,#data do
- local di = data[i]
- if di and extras.section(result,element,detail,n,di.fulltag,di) then
- return true
+ extras.addreference(result,data.references)
+ return true
+ else
+ local data = di.data
+ if data then
+ for i=1,#data do
+ local di = data[i]
+ if di and section(result,element,detail,n,di.fulltag,di) then
+ return true
+ end
end
end
end
end
+
end
-local tabledata = { }
+do
-function structurestags.settablecell(rows,columns,align)
- if align > 0 or rows > 1 or columns > 1 then
- tabledata[detailedtag("tablecell")] = {
- rows = rows,
- columns = columns,
- align = align,
- }
- end
-end
+ local tabledata = { }
+
+ local f_columns = formatters[" columns='%s'"]
+ local f_rows = formatters[" rows='%s'"]
-function extras.tablecell(result,element,detail,n,fulltag,di)
- local hash = tabledata[fulltag]
- if hash then
- local v = hash.columns
- if v and v > 1 then
- result[#result+1] = formatters[" columns='%s'"](v)
+ local s_flushright = " align='flushright'"
+ local s_middle = " align='middle'"
+ local s_flushleft = " align='flushleft'"
+
+ local function hascontent(data)
+ for i=1,#data do
+ local di = data[i]
+ if not di then
+ --
+ elseif di.content then
+ return true
+ else
+ local d = di.data
+ if d and #d > 0 and hascontent(d) then
+ return true
+ end
+ end
end
- local v = hash.rows
- if v and v > 1 then
- result[#result+1] = formatters[" rows='%s'"](v)
+ end
+
+ function structurestags.settablecell(rows,columns,align)
+ if align > 0 or rows > 1 or columns > 1 then
+ tabledata[detailedtag("tablecell")] = {
+ rows = rows,
+ columns = columns,
+ align = align,
+ }
end
- local v = hash.align
- if not v or v == 0 then
- -- normal
- elseif v == 1 then -- use numbertoalign here
- result[#result+1] = " align='flushright'"
- elseif v == 2 then
- result[#result+1] = " align='middle'"
- elseif v == 3 then
- result[#result+1] = " align='flushleft'"
+ end
+
+ function extras.tablecell(result,element,detail,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)
+ end
+ local rows = hash.rows
+ if rows and rows > 1 then
+ result[#result+1] = f_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
+ elseif align == 2 then
+ result[#result+1] = s_middle
+ elseif align == 3 then
+ result[#result+1] = s_flushleft
+ end
end
end
-end
-local tabulatedata = { }
+ local tabulatedata = { }
-function structurestags.settabulatecell(align)
- if align > 0 then
- tabulatedata[detailedtag("tabulatecell")] = {
- align = align,
- }
+ function structurestags.settabulatecell(align)
+ if align > 0 then
+ tabulatedata[detailedtag("tabulatecell")] = {
+ align = align,
+ }
+ end
end
-end
-local function hascontent(data)
- for i=1,#data do
- local di = data[i]
- if not di then
- --
- elseif di.content then
- return true
- else
- local d = di.data
- if d and #d > 0 and hascontent(d) then
- return true
+ function extras.tabulate(result,element,detail,n,fulltag,di)
+ local data = di.data
+ for i=1,#data do
+ local di = data[i]
+ if di.tg == "tabulaterow" and not hascontent(di.data) then
+ di.element = "" -- or simply remove
end
end
end
-end
-function extras.tabulate(result,element,detail,n,fulltag,di)
- local data = di.data
- for i=1,#data do
- local di = data[i]
- if di.tg == "tabulaterow" and not hascontent(di.data) then
- di.element = "" -- or simply remove
+ function extras.tabulatecell(result,element,detail,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
+ elseif align == 2 then
+ result[#result+1] = s_flushright
+ elseif align == 3 then
+ result[#result+1] = s_middle
+ end
end
end
-end
-function extras.tabulatecell(result,element,detail,n,fulltag,di)
- local hash = tabulatedata[fulltag]
- if hash then
- local v = hash.align
- if not v or v == 0 then
- -- normal
- elseif v == 1 then
- result[#result+1] = " align='flushleft'"
- elseif v == 2 then
- result[#result+1] = " align='flushright'"
- elseif v == 3 then
- result[#result+1] = " align='middle'"
- end
- end
end
-- flusher
-local linedone = false -- can go ... we strip newlines anyway
-local inlinedepth = 0
-
--- todo: #result -> nofresult
-
-local function emptytag(result,element,nature,depth,di) -- currently only break but at some point
- local a = di.attributes -- we might add detail etc
- if a then -- happens seldom
- if linedone then
- result[#result+1] = formatters["%w<%s"](depth,namespaced[element])
- else
- result[#result+1] = formatters["\n%w<%s"](depth,namespaced[element])
- end
+do
+
+ local f_detail = formatters[" detail='%s'"]
+ local f_index = formatters[" n='%s'"]
+ local f_spacing = formatters["<c n='%s'>%s</c>"]
+
+ local f_empty_inline = formatters["<%s/>"]
+ local f_empty_mixed = formatters["%w<%s/>\n"]
+ local f_empty_display = formatters["\n%w<%s/>\n"]
+ local f_empty_inline_attr = formatters["<%s%s/>"]
+ local f_empty_mixed_attr = formatters["%w<%s%s/>"]
+ local f_empty_display_attr = formatters["\n%w<%s%s/>\n"]
+
+ local f_begin_inline = formatters["<%s>"]
+ local f_begin_mixed = formatters["%w<%s>"]
+ local f_begin_display = formatters["\n%w<%s>\n"]
+ local f_begin_inline_attr = formatters["<%s%s>"]
+ local f_begin_mixed_attr = formatters["%w<%s%s>"]
+ local f_begin_display_attr = formatters["\n%w<%s%s>\n"]
+
+ local f_end_inline = formatters["</%s>"]
+ local f_end_mixed = formatters["</%s>\n"]
+ local f_end_display = formatters["%w</%s>\n"]
+
+ local f_begin_inline_comment = formatters["<!-- %s --><%s>"]
+ local f_begin_mixed_comment = formatters["%w<!-- %s --><%s>"]
+ local f_begin_display_comment = formatters["\n%w<!-- %s -->\n%w<%s>\n"]
+ local f_begin_inline_attr_comment = formatters["<!-- %s --><%s%s>"]
+ local f_begin_mixed_attr_comment = formatters["%w<!-- %s --><%s%s>"]
+ local f_begin_display_attr_comment = formatters["\n%w<!-- %s -->\n%w<%s%s>\n"]
+
+ local f_comment_begin_inline = formatters["<!-- begin %s -->"]
+ local f_comment_begin_mixed = formatters["%w<!-- begin %s -->"]
+ local f_comment_begin_display = formatters["\n%w<!-- begin %s -->\n"]
+
+ local f_comment_end_inline = formatters["<!-- end %s -->"]
+ local f_comment_end_mixed = formatters["<!-- end %s -->\n"]
+ local f_comment_end_display = formatters["%w<!-- end %s -->\n"]
+
+ local f_metadata_begin = formatters["\n%w<metadata>\n"]
+ local f_metadata = formatters["%w<metavariable name=%q>%s</metavariable>\n"]
+ local f_metadata_end = formatters["%w</metadata>\n"]
+
+ --- we could share the r tables ... but it's fast enough anyway
+
+ local function attributes(a)
+ local r = { } -- can be shared
+ local n = 0
for k, v in next, a do
- result[#result+1] = formatters[" %s=%q"](k,v)
- end
- result[#result+1] = "/>\n"
- else
- if linedone then
- result[#result+1] = formatters["%w<%s/>\n"](depth,namespaced[element])
- else
- result[#result+1] = formatters["\n%w<%s/>\n"](depth,namespaced[element])
+ n = n + 1
+ r[n] = f_attribute(k,v)
end
+ return concat(r,"",1,n)
+ end
+
+ local depth = 0
+ local inline = 0
+
+ local function bpar(result)
+ result[#result+1] = "\n<p>"
+ end
+ local function epar(result)
+ result[#result+1] = "</p>\n"
end
- linedone = false
-end
-local function begintag(result,element,nature,depth,di,skip)
- -- if needed we can use a local result with xresult
- local detail = di.detail
- local n = di.n
- local fulltag = di.fulltag
- local comment = di.comment
- if nature == "inline" then
- linedone = false
- inlinedepth = inlinedepth + 1
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->"](comment)
- end
- elseif nature == "mixed" then
- if inlinedepth > 0 then
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->"](comment)
- end
- elseif linedone then
- result[#result+1] = spaces[depth]
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->"](comment)
+ local function emptytag(result,element,nature,di) -- currently only break but at some point
+ local a = di.attributes -- we might add detail etc
+ if a then -- happens seldom
+ if nature == "display" then
+ result[#result+1] = f_empty_display_attr(depth,namespaced[element],attributes(a))
+ elseif nature == "mixed" then
+ result[#result+1] = f_empty_mixed_attr(depth,namespaced[element],attributes(a))
+ else
+ result[#result+1] = f_empty_inline_attr(namespaced[element],attributes(a))
end
else
- result[#result+1] = formatters["\n%w"](depth)
- linedone = false
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->\n%w"](comment,depth)
+ if nature == "display" then
+ result[#result+1] = f_empty_display(depth,namespaced[element])
+ elseif nature == "mixed" then
+ result[#result+1] = f_empty_mixed(depth,namespaced[element])
+ else
+ result[#result+1] = f_empty_inline(namespaced[element])
end
end
- inlinedepth = inlinedepth + 1
- else
- if inlinedepth > 0 then
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->"](comment)
- end
- elseif linedone then
- result[#result+1] = spaces[depth]
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->"](comment)
+ 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
+ if skip == "comment" then
+ if show_comment then
+ if nature == "inline" or inline > 0 then
+ result[#result+1] = f_comment_begin_inline(namespaced[element])
+ inline = inline + 1
+ elseif nature == "mixed" then
+ result[#result+1] = f_comment_begin_mixed(depth,namespaced[element])
+ depth = depth + 1
+ inline = 1
+ else
+ result[#result+1] = f_comment_begin_display(depth,namespaced[element])
+ depth = depth + 1
+ end
end
+ elseif skip then
+ -- ignore
else
- result[#result+1] = formatters["\n%w"](depth) -- can introduced extra line in mixed+mixed (filtered later on)
- linedone = false
- if show_comment and comment then
- result[#result+1] = formatters["<!-- %s -->\n%w"](comment,depth)
+ local n = 0
+ local r = { } -- delay this
+ if detail then
+ n = n + 1
+ r[n] = f_detail(detail)
end
- end
- end
- if skip == "comment" then
- if show_comment then
- result[#result+1] = formatters["<!-- begin %s -->"](namespaced[element])
- end
- elseif skip then
- -- ignore
- else
- result[#result+1] = formatters["<%s"](namespaced[element])
- if detail then
- result[#result+1] = formatters[" detail=%q"](detail)
- end
- if indexing and n then
- result[#result+1] = formatters[" n=%q"](n)
- end
- local extra = extras[element]
- if extra then
- extra(result,element,detail,n,fulltag,di)
- end
- local u = userdata[fulltag]
- if u then
- for k, v in next, u do
- result[#result+1] = formatters[" %s=%q"](k,v)
+ if indexing and index then
+ n = n + 1
+ r[n] = f_index(index)
end
- end
- local a = di.attributes
- if a then
- for k, v in next, a do
- result[#result+1] = formatters[" %s=%q"](k,v)
+ local extra = extras[element]
+ if extra then
+ extra(r,element,detail,index,fulltag,di)
+ n = #r
end
- end
- result[#result+1] = ">"
- end
- if inlinedepth > 0 then
- elseif nature == "display" then
- result[#result+1] = "\n"
- linedone = true
- end
- used[element][detail or ""] = nature -- for template css
- local metadata = tagmetadata[fulltag]
- if metadata then
- if not linedone then
- result[#result+1] = "\n"
- linedone = true
- end
- result[#result+1] = formatters["%w<metadata>\n"](depth)
- for k, v in table.sortedpairs(metadata) do
- v = entityremapper(v)
- result[#result+1] = formatters["%w<metavariable name=%q>%s</metavariable>\n"](depth+1,k,v)
- end
- result[#result+1] = formatters["%w</metadata>\n"](depth)
- end
-end
-
-local function endtag(result,element,nature,depth,skip)
- if nature == "display" then
- if inlinedepth == 0 then
- if not linedone then
- result[#result+1] = "\n"
+ local u = userdata[fulltag]
+ if u then
+ for k, v in next, u do
+ n = n + 1
+ r[n] = f_attribute(k,v)
+ end
end
- if skip == "comment" then
- if show_comment then
- result[#result+1] = formatters["%w<!-- end %s -->\n"](depth,namespaced[element])
+ local a = di.attributes
+ if a then
+ for k, v in next, a do
+ n = n + 1
+ r[n] = f_attribute(k,v)
end
- elseif skip then
- -- ignore
- else
- result[#result+1] = formatters["%w</%s>\n"](depth,namespaced[element])
end
- linedone = true
- else
- if skip == "comment" then
- if show_comment then
- result[#result+1] = formatters["<!-- end %s -->"](namespaced[element])
+ if n == 0 then
+ if nature == "inline" or inline > 0 then
+ if show_comment and comment then
+ result[#result+1] = f_begin_inline_comment(comment,namespaced[element])
+ else
+ result[#result+1] = f_begin_inline(namespaced[element])
+ end
+ inline = inline + 1
+ elseif nature == "mixed" then
+ if show_comment and comment then
+ result[#result+1] = f_begin_mixed_comment(depth,comment,namespaced[element])
+ else
+ result[#result+1] = f_begin_mixed(depth,namespaced[element])
+ end
+ depth = depth + 1
+ inline = 1
+ else
+ if show_comment and comment then
+ result[#result+1] = f_begin_display_comment(depth,comment,depth,namespaced[element])
+ else
+ result[#result+1] = f_begin_display(depth,namespaced[element])
+ end
+ depth = depth + 1
end
- elseif skip then
- -- ignore
else
- result[#result+1] = formatters["</%s>"](namespaced[element])
+ r = concat(r,"",1,n)
+ if nature == "inline" or inline > 0 then
+ if show_comment and comment then
+ result[#result+1] = f_begin_inline_attr_comment(comment,namespaced[element],r)
+ else
+ result[#result+1] = f_begin_inline_attr(namespaced[element],r)
+ end
+ inline = inline + 1
+ elseif nature == "mixed" then
+ if show_comment and comment then
+ result[#result+1] = f_begin_mixed_attr_comment(depth,comment,namespaced[element],r)
+ else
+ result[#result+1] = f_begin_mixed_attr(depth,namespaced[element],r)
+ end
+ depth = depth + 1
+ inline = 1
+ else
+ if show_comment and comment then
+ result[#result+1] = f_begin_display_attr_comment(depth,comment,depth,namespaced[element],r)
+ else
+ result[#result+1] = f_begin_display_attr(depth,namespaced[element],r)
+ end
+ depth = depth + 1
+ end
end
end
- else
- inlinedepth = inlinedepth - 1
- if skip == "comment" then
- if show_comment then
- result[#result+1] = formatters["<!-- end %s -->"](namespaced[element])
+ used[element][detail or ""] = nature -- for template css
+ local metadata = tagmetadata[fulltag]
+ if metadata then
+ result[#result+1] = f_metadata_begin(depth)
+ for k, v in table.sortedpairs(metadata) do
+ result[#result+1] = f_medatadata(depth+1,k,lpegmatch(p_entity,v))
end
- elseif skip then
- -- ignore
- else
- result[#result+1] = formatters["</%s>"](namespaced[element])
+ result[#result+1] = f_metadata_end(depth)
end
- linedone = false
end
-end
-local function flushtree(result,data,nature,depth)
- depth = depth + 1
- local nofdata = #data
- for i=1,nofdata do
- local di = data[i]
- if not di then -- hm, di can be string
- -- whatever
- elseif di.content then
- -- already has breaks
- local content = entityremapper(di.content)
- if i == nofdata and sub(content,-1) == "\n" then -- move check
- -- can be an end of line in par but can also be the last line
- if trace_spacing then
- result[#result+1] = formatters["<c n='%s'>%s</c>"](di.parnumber or 0,sub(content,1,-2))
- else
- result[#result+1] = sub(content,1,-2)
- end
- result[#result+1] = " "
- else
- if trace_spacing then
- result[#result+1] = formatters["<c n='%s'>%s</c>"](di.parnumber or 0,content)
+ local function endtag(result,element,nature,di,skip)
+ if skip == "comment" then
+ if show_comment then
+ if nature == "display" and (inline == 0 or inline == 1) then
+ depth = depth - 1
+ result[#result+1] = f_comment_end_display(depth,namespaced[element])
+ inline = 0
+ elseif nature == "mixed" and (inline == 0 or inline == 1) then
+ depth = depth - 1
+ result[#result+1] = f_comment_end_mixed(namespaced[element])
+ inline = 0
else
- result[#result+1] = content
+ inline = inline - 1
+ result[#result+1] = f_comment_end_inline(namespaced[element])
end
end
- linedone = false
- elseif not di.collapsed then -- ignore collapsed data (is appended, reconstructed par)
- local element = di.element
- if not element then
- -- skip
- elseif element == "break" then -- or element == "pagebreak"
- emptytag(result,element,nature,depth,di)
- elseif element == "" or di.skip == "ignore" then
- -- skip
+ elseif skip then
+ -- ignore
+ else
+ if nature == "display" and (inline == 0 or inline == 1) then
+ depth = depth - 1
+ result[#result+1] = f_end_display(depth,namespaced[element])
+ inline = 0
+ elseif nature == "mixed" and (inline == 0 or inline == 1) then
+ depth = depth - 1
+ result[#result+1] = f_end_mixed(namespaced[element])
+ inline = 0
else
- if di.before then
- flushtree(result,di.before,nature,depth)
- end
- local natu = di.nature
- local skip = di.skip
- if di.breaknode then
- emptytag(result,"break","display",depth,di)
- end
- begintag(result,element,natu,depth,di,skip)
- flushtree(result,di.data,natu,depth)
- -- if sub(result[#result],-1) == " " and natu ~= "inline" then
- -- result[#result] = sub(result[#result],1,-2)
- -- end
- endtag(result,element,natu,depth,skip)
- if di.after then
- flushtree(result,di.after,nature,depth)
- end
+ inline = inline - 1
+ result[#result+1] = f_end_inline(namespaced[element])
end
end
end
-end
-local function breaktree(tree,parent,parentelement) -- also removes double breaks
- local data = tree.data
- if data then
+ local function flushtree(result,data,nature)
local nofdata = #data
- local prevelement
- local prevnature
- local prevparnumber
- local newdata = { }
- local nofnewdata = 0
for i=1,nofdata do
local di = data[i]
- if not di then
- -- skip
+ if not di then -- hm, di can be string
+ -- whatever
elseif di.content then
- local parnumber = di.parnumber
- if prevnature == "inline" and prevparnumber and prevparnumber ~= parnumber then
- nofnewdata = nofnewdata + 1
+ -- already has breaks
+ local content = lpegmatch(p_entity,di.content)
+ if i == nofdata and sub(content,-1) == "\n" then -- move check
+ -- can be an end of line in par but can also be the last line
+ if trace_spacing then
+ result[#result+1] = f_spacing(di.parnumber or 0,sub(content,1,-2))
+ else
+ result[#result+1] = sub(content,1,-2)
+ end
+ result[#result+1] = " "
+ else
if trace_spacing then
- newdata[nofnewdata] = makebreaknode { type = "a", p = prevparnumber, n = parnumber }
+ result[#result+1] = f_spacing(di.parnumber or 0,content)
else
- newdata[nofnewdata] = makebreaknode()
+ result[#result+1] = content
end
end
- prevelement = nil
- prevnature = "inline"
- prevparnumber = parnumber
- nofnewdata = nofnewdata + 1
- newdata[nofnewdata] = di
- elseif not di.collapsed then
+ elseif not di.collapsed then -- ignore collapsed data (is appended, reconstructed par)
local element = di.element
- if element == "break" then -- or element == "pagebreak"
- if prevelement == "break" then
- di.element = ""
- end
- prevelement = element
- prevnature = "display"
+ if not element then
+ -- skip
+ elseif element == "break" then -- or element == "pagebreak"
+ emptytag(result,element,nature,di)
elseif element == "" or di.skip == "ignore" then
-- skip
else
+ if di.before then
+ flushtree(result,di.before,nature)
+ end
+ local natu = di.nature
+ local skip = di.skip
+ if di.breaknode then
+ emptytag(result,"break","display",di)
+ end
+ begintag(result,element,natu,di,skip)
+ flushtree(result,di.data,natu)
+ endtag(result,element,natu,di,skip)
+ if di.after then
+ flushtree(result,di.after,nature)
+ end
+ end
+ end
+ end
+ end
+
+ local function breaktree(tree,parent,parentelement) -- also removes double breaks
+ local data = tree.data
+ if data then
+ local nofdata = #data
+ local prevelement
+ local prevnature
+ local prevparnumber
+ local newdata = { }
+ local nofnewdata = 0
+ for i=1,nofdata do
+ local di = data[i]
+ if not di then
+ -- skip
+ elseif di.content then
+ local parnumber = di.parnumber
+ if prevnature == "inline" and prevparnumber and prevparnumber ~= parnumber then
+ nofnewdata = nofnewdata + 1
+ if trace_spacing then
+ newdata[nofnewdata] = makebreaknode { type = "a", p = prevparnumber, n = parnumber }
+ else
+ newdata[nofnewdata] = makebreaknode()
+ end
+ end
+ prevelement = nil
+ prevnature = "inline"
+ prevparnumber = parnumber
+ nofnewdata = nofnewdata + 1
+ newdata[nofnewdata] = di
+ elseif not di.collapsed then
+ local element = di.element
+ if element == "break" then -- or element == "pagebreak"
+ if prevelement == "break" then
+ di.element = ""
+ end
+ prevelement = element
+ prevnature = "display"
+ elseif element == "" or di.skip == "ignore" then
+ -- skip
+ else
+ local nature = di.nature
+ local parnumber = di.parnumber
+ if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then
+ nofnewdata = nofnewdata + 1
+ if trace_spacing then
+ newdata[nofnewdata] = makebreaknode { type = "b", p = prevparnumber, n = parnumber }
+ else
+ newdata[nofnewdata] = makebreaknode()
+ end
+ end
+ prevnature = nature
+ prevparnumber = parnumber
+ prevelement = element
+ breaktree(di,tree,element)
+ end
+ nofnewdata = nofnewdata + 1
+ newdata[nofnewdata] = di
+ else
local nature = di.nature
local parnumber = di.parnumber
if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then
nofnewdata = nofnewdata + 1
if trace_spacing then
- newdata[nofnewdata] = makebreaknode { type = "b", p = prevparnumber, n = parnumber }
+ newdata[nofnewdata] = makebreaknode { type = "c", p = prevparnumber, n = parnumber }
else
newdata[nofnewdata] = makebreaknode()
end
end
prevnature = nature
prevparnumber = parnumber
- prevelement = element
- breaktree(di,tree,element)
- end
- nofnewdata = nofnewdata + 1
- newdata[nofnewdata] = di
- else
- local nature = di.nature
- local parnumber = di.parnumber
- if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then
nofnewdata = nofnewdata + 1
- if trace_spacing then
- newdata[nofnewdata] = makebreaknode { type = "c", p = prevparnumber, n = parnumber }
- else
- newdata[nofnewdata] = makebreaknode()
- end
+ newdata[nofnewdata] = di
end
- prevnature = nature
- prevparnumber = parnumber
- nofnewdata = nofnewdata + 1
- newdata[nofnewdata] = di
end
- end
- tree.data = newdata
- end
-end
-
--- also tabulaterow reconstruction .. maybe better as a checker
--- i.e cell attribute
-
-local function collapsetree()
- for tag, trees in next, treehash do
- local d = trees[1].data
- if d then
- local nd = #d
- if nd > 0 then
- for i=2,#trees do
- local currenttree = trees[i]
- local currentdata = currenttree.data
- local currentpar = currenttree.parnumber
- local previouspar = trees[i-1].parnumber
- currenttree.collapsed = true
- -- is the next ok?
- if previouspar == 0 or not (di and di.content) then
- previouspar = nil -- no need anyway so no further testing needed
- end
- for j=1,#currentdata do
- local cd = currentdata[j]
- if not cd or cd == "" then
- -- skip
- elseif cd.content then
- if not currentpar then
- -- add space ?
- elseif not previouspar then
- -- add space ?
- elseif currentpar ~= previouspar then
- nd = nd + 1
- if trace_spacing then
- d[nd] = makebreaknode { type = "d", p = previouspar, n = currentpar }
- else
- d[nd] = makebreaknode()
+ tree.data = newdata
+ end
+ end
+
+ -- also tabulaterow reconstruction .. maybe better as a checker
+ -- i.e cell attribute
+
+ local function collapsetree()
+ for tag, trees in next, treehash do
+ local d = trees[1].data
+ if d then
+ local nd = #d
+ if nd > 0 then
+ for i=2,#trees do
+ local currenttree = trees[i]
+ local currentdata = currenttree.data
+ local currentpar = currenttree.parnumber
+ local previouspar = trees[i-1].parnumber
+ currenttree.collapsed = true
+ -- is the next ok?
+ if previouspar == 0 or not (di and di.content) then
+ previouspar = nil -- no need anyway so no further testing needed
+ end
+ for j=1,#currentdata do
+ local cd = currentdata[j]
+ if not cd or cd == "" then
+ -- skip
+ elseif cd.content then
+ if not currentpar then
+ -- add space ?
+ elseif not previouspar then
+ -- add space ?
+ elseif currentpar ~= previouspar then
+ nd = nd + 1
+ if trace_spacing then
+ d[nd] = makebreaknode { type = "d", p = previouspar, n = currentpar }
+ else
+ d[nd] = makebreaknode()
+ end
end
+ previouspar = currentpar
+ nd = nd + 1
+ d[nd] = cd
+ else
+ nd = nd + 1
+ d[nd] = cd
end
- previouspar = currentpar
- nd = nd + 1
- d[nd] = cd
- else
- nd = nd + 1
- d[nd] = cd
+ currentdata[j] = false
end
- currentdata[j] = false
end
end
end
end
end
-end
-local function finalizetree(tree)
- for _, finalizer in next, finalizers do
- finalizer(tree)
+ local function finalizetree(tree)
+ for _, finalizer in next, finalizers do
+ finalizer(tree)
+ end
end
-end
-local function indextree(tree)
- local data = tree.data
- if data then
- local n, new = 0, { }
- for i=1,#data do
- local d = data[i]
- if not d then
- -- skip
- elseif d.content then
- n = n + 1
- new[n] = d
- elseif not d.collapsed then
- n = n + 1
- d.__i__ = n
- d.__p__ = tree
- indextree(d)
- new[n] = d
+ local function indextree(tree)
+ local data = tree.data
+ if data then
+ local n, new = 0, { }
+ for i=1,#data do
+ local d = data[i]
+ if not d then
+ -- skip
+ elseif d.content then
+ n = n + 1
+ new[n] = d
+ elseif not d.collapsed then
+ n = n + 1
+ d.__i__ = n
+ d.__p__ = tree
+ indextree(d)
+ new[n] = d
+ end
end
+ tree.data = new
end
- tree.data = new
end
-end
-local function checktree(tree)
- local data = tree.data
- if data then
- for i=1,#data do
- local d = data[i]
- if type(d) == "table" then
- local check = checks[d.tg]
- if check then
- check(d)
+ local function checktree(tree)
+ local data = tree.data
+ if data then
+ for i=1,#data do
+ local d = data[i]
+ if type(d) == "table" then
+ local check = checks[d.tg]
+ if check then
+ check(d)
+ end
+ checktree(d)
end
- checktree(d)
end
end
end
+
+ wrapups.flushtree = flushtree
+ wrapups.breaktree = breaktree
+ wrapups.collapsetree = collapsetree
+ wrapups.finalizetree = finalizetree
+ wrapups.indextree = indextree
+ wrapups.checktree = checktree
+
end
-- collector code
@@ -1889,6 +2076,9 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
--
elseif last then
+ -- we can consider tagging the pars (lines) in the parbuilder but then we loose some
+ -- information unless we inject a special node (but even then we can run into nesting
+ -- issues)
local ap = getattr(n,a_taggedpar)
if ap ~= currentparagraph then
pushcontent(currentparagraph,ap)
@@ -2182,6 +2372,8 @@ end
-- encoding='utf-8'
+do
+
local xmlpreamble = [[
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
@@ -2192,247 +2384,336 @@ local xmlpreamble = [[
]]
-local function wholepreamble()
- return format(xmlpreamble,tex.jobname,os.date(),environment.version,exportversion)
-end
+ local flushtree = wrapups.flushtree
+ local function wholepreamble()
+ return format(xmlpreamble,tex.jobname,os.date(),environment.version,exportversion)
+ end
-local csspreamble = [[
-<?xml-stylesheet type="text/css" href="%s"?>
-]]
-local function allusedstylesheets(xmlfile,cssfiles,files)
- local result = { }
- for i=1,#cssfiles do
- local cssfile = cssfiles[i]
- if type(cssfile) ~= "string" or cssfile == variables.yes or cssfile == "" or cssfile == xmlfile then
- cssfile = file.replacesuffix(xmlfile,"css")
- else
- cssfile = file.addsuffix(cssfile,"css")
+local f_csspreamble = formatters [ [[
+<?xml-stylesheet type="text/css" href="%s"?>
+]] ]
+
+ local function allusedstylesheets(xmlfile,cssfiles,files)
+ local result = { }
+ for i=1,#cssfiles do
+ local cssfile = cssfiles[i]
+ if type(cssfile) ~= "string" or cssfile == v_yes or cssfile == "" or cssfile == xmlfile then
+ cssfile = file.replacesuffix(xmlfile,"css")
+ else
+ cssfile = file.addsuffix(cssfile,"css")
+ end
+ files[#files+1] = cssfile
+ report_export("adding css reference '%s'",cssfile)
+ result[#result+1] = f_csspreamble(cssfile)
end
- files[#files+1] = cssfile
- report_export("adding css reference '%s'",cssfile)
- result[#result+1] = format(csspreamble,cssfile)
+ return concat(result)
end
- return concat(result)
-end
-local e_template = [[
+local f_e_template = formatters [ [[
%s {
display: %s ;
-}]]
+}]] ]
-local d_template = [[
+local f_d_template = formatters [ [[
%s[detail=%s] {
display: %s ;
-}]]
+}]] ]
-local displaymapping = {
- inline = "inline",
- display = "block",
- mixed = "inline",
-}
+ local f_category = formatters["/* category: %s */"]
-local function allusedelements(xmlfile)
- local result = { format("/* template for file %s */",xmlfile) }
- for element, details in sortedhash(used) do
- result[#result+1] = format("/* category: %s */",element)
- for detail, nature in sortedhash(details) do
- local d = displaymapping[nature or "display"] or "block"
- if detail == "" then
- result[#result+1] = formatters[e_template](element,d)
- else
- result[#result+1] = formatters[d_template](element,detail,d)
+ local displaymapping = {
+ inline = "inline",
+ display = "block",
+ mixed = "inline",
+ }
+
+ local function allusedelements(xmlfile)
+ local result = { formatters["/* %s for file %s */"]("template",xmlfile) }
+ for element, details in sortedhash(used) do
+ result[#result+1] = f_category(element)
+ for detail, nature in sortedhash(details) do
+ local d = displaymapping[nature or "display"] or "block"
+ if detail == "" then
+ result[#result+1] = f_e_template(element,d)
+ else
+ result[#result+1] = f_d_template(element,detail,d)
+ end
end
end
+ return concat(result,"\n\n")
end
- return concat(result,"\n\n")
-end
-
-local function allcontent(tree)
- local result = { }
- flushtree(result,tree.data,"display",0) -- we need to collect images
- result = concat(result)
- result = gsub(result,"\n *\n","\n")
- result = gsub(result,"\n +([^< ])","\n%1")
- return result
-end
--- local xhtmlpreamble = [[
--- <!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 function cleanxhtmltree(xmltree)
- if xmltree then
- local xmlwrap = xml.wrap
- for e in xml.collected(xmltree,"/document") do
- e.at["xmlns:xhtml"] = "http://www.w3.org/1999/xhtml"
- break
- end
- -- todo: inject xhtmlpreamble (xmlns should have be enough)
- local wrapper = { tg = "a", ns = "xhtml", at = { href = "unknown" } }
- for e in xml.collected(xmltree,"link") do
- local at = e.at
- local href
- if at.location then
- href = "#" .. gsub(at.location,":","_")
- elseif at.url then
- href = at.url
- elseif at.file then
- href = at.file
- end
- if href then
- wrapper.at.href = href
- xmlwrap(e,wrapper)
- end
- end
- local wrapper = { tg = "a", ns = "xhtml", at = { name = "unknown" } }
- for e in xml.collected(xmltree,"!link[@location]") do
- local location = e.at.location
- if location then
- wrapper.at.name = gsub(location,":","_")
- xmlwrap(e,wrapper)
- end
- end
- return xmltree
- else
- return xml.convert("<?xml version='1.0'?>\n<error>invalid xhtml tree</error>")
+ local function allcontent(tree)
+ local result = { }
+ flushtree(result,tree.data,"display") -- we need to collect images
+ result = concat(result)
+ -- no need to lpeg .. fast enough
+ result = gsub(result,"\n *\n","\n")
+ result = gsub(result,"\n +([^< ])","\n%1")
+ return result
end
-end
-local cssfile, xhtmlfile = nil, nil
+ -- local xhtmlpreamble = [[
+ -- <!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"
+ -- >
+ -- ]]
-directives.register("backend.export.css", function(v) cssfile = v end)
-directives.register("backend.export.xhtml",function(v) xhtmlfile = v end)
-
-local function stopexport(v)
- starttiming(treehash)
- --
- finishexport()
- --
- collapsetree(tree)
- indextree(tree)
- checktree(tree)
- breaktree(tree)
- finalizetree(tree)
- --
- hashlistdata()
- --
- if type(v) ~= "string" or v == variables.yes or v == "" then
- v = tex.jobname
- end
- local basename = file.basename(v)
- local xmlfile = file.addsuffix(basename,"export")
- --
- local imagefilename = file.addsuffix(file.removesuffix(xmlfile) .. "-images","css")
- local stylefilename = file.addsuffix(file.removesuffix(xmlfile) .. "-styles","css")
- local templatefilename = file.replacesuffix(xmlfile,"template")
- local specificationfilename = file.replacesuffix(xmlfile,"specification")
- --
- if xhtml and not cssfile then
- cssfile = true
- end
- local cssfiles = { }
- if cssfile then
- if cssfile == true then
- cssfiles = { "export-example.css" }
+ local function cleanxhtmltree(xmltree)
+ if xmltree then
+ local xmlwrap = xml.wrap
+ for e in xml.collected(xmltree,"/document") do
+ e.at["xmlns:xhtml"] = "http://www.w3.org/1999/xhtml"
+ break
+ end
+ -- todo: inject xhtmlpreamble (xmlns should have be enough)
+ local wrapper = { tg = "a", ns = "xhtml", at = { href = "unknown" } }
+ for e in xml.collected(xmltree,"link") do
+ local at = e.at
+ local href
+ if at.location then
+ href = "#" .. gsub(at.location,":","_")
+ elseif at.url then
+ href = at.url
+ elseif at.file then
+ href = at.file
+ end
+ if href then
+ wrapper.at.href = href
+ xmlwrap(e,wrapper)
+ end
+ end
+ local wrapper = { tg = "a", ns = "xhtml", at = { name = "unknown" } }
+ for e in xml.collected(xmltree,"!link[@location]") do
+ local location = e.at.location
+ if location then
+ wrapper.at.name = gsub(location,":","_")
+ xmlwrap(e,wrapper)
+ end
+ end
+ return xmltree
else
- cssfiles = settings_to_array(cssfile or "")
+ return xml.convert("<?xml version='1.0'?>\n<error>invalid xhtml tree</error>")
end
- insert(cssfiles,1,imagefilename)
- insert(cssfiles,1,stylefilename)
end
- cssfiles = table.unique(cssfiles)
- --
- local result = allcontent(tree) -- also does some housekeeping and data collecting
- --
- local files = {
- }
- local results = concat {
- wholepreamble(),
- allusedstylesheets(xmlfile,cssfiles,files), -- ads to files
- result,
- }
- --
- files = table.unique(files)
- --
- report_export("saving xml data in %a",xmlfile)
- io.savedata(xmlfile,results)
- --
- report_export("saving css image definitions in %a",imagefilename)
- io.savedata(imagefilename,allusedimages(xmlfile))
- --
- report_export("saving css style definitions in %a",stylefilename)
- io.savedata(stylefilename,allusedstyles(xmlfile))
- --
- report_export("saving css template in %a",templatefilename)
- io.savedata(templatefilename,allusedelements(xmlfile))
- --
- if xhtmlfile then
- if type(v) ~= "string" or xhtmlfile == true or xhtmlfile == variables.yes or xhtmlfile == "" or xhtmlfile == xmlfile then
- xhtmlfile = file.replacesuffix(xmlfile,"xhtml")
- else
- xhtmlfile = file.addsuffix(xhtmlfile,"xhtml")
- end
- files[#files+1] = xhtmlfile
- report_export("saving xhtml variant in %a",xhtmlfile)
- local xmltree = cleanxhtmltree(xml.convert(results))
- xml.save(xmltree,xhtmlfile)
- -- looking at identity is somewhat redundant as we also inherit from interaction
- -- at the tex end
- local identity = interactions.general.getidentity()
- local specification = {
- name = file.removesuffix(v),
- identifier = os.uuid(),
- images = uniqueusedimages(),
- root = xhtmlfile,
- files = files,
- language = languagenames[texgetcount("mainlanguagenumber")],
- title = validstring(finetuning.title) or validstring(identity.title),
- subtitle = validstring(finetuning.subtitle) or validstring(identity.subtitle),
- author = validstring(finetuning.author) or validstring(identity.author),
- firstpage = validstring(finetuning.firstpage),
- lastpage = validstring(finetuning.lastpage),
- }
- report_export("saving specification in %a (mtxrun --script epub --make %s)",specificationfilename,specificationfilename)
- io.savedata(specificationfilename,table.serialize(specification,true))
+
+ local f_namespace = string.formatters["%s.%s"]
+
+ local function remap(specification,source,target)
+ -- local specification = specification or require(specname)
+ -- if not specification then
+ -- return
+ -- end
+ -- if type(source) == "string" then
+ -- source = xml.load(source)
+ -- end
+ -- if type(source) ~= "table" then
+ -- return
+ -- end
+ local remapping = specification.remapping
+ if not remapping then
+ return
+ end
+ for i=1,#remapping do
+ local remap = remapping[i]
+ local element = remap.element
+ local class = remap.class
+ local extras = remap.extras
+ local namespace = extras and extras.namespace
+ for c in xml.collected(source,remap.pattern) do
+ if not c.special then
+ local tg = c.tg
+ local at = c.at
+ local class = {
+ class or (at and at.detail) or tg
+ }
+ if extras and at then
+ for k, v in next, extras do
+ local a = at[k]
+ if a then
+ local va = v[a]
+ if va then
+ if namespace then
+ class[#class+1] = f_namespace(tg,va)
+ else
+ class[#class+1] = va
+ end
+ end
+ end
+ end
+ end
+ if #class > 0 then
+ c.at = { class = concat(class," ") }
+ else
+ c.at = { }
+ end
+ if element then
+ c.tg = element
+ end
+ end
+ end
+ end
+ -- if target then
+ -- xml.save(source,target)
+ -- end
+ -- return source
end
- stoptiming(treehash)
-end
-local appendaction = nodes.tasks.appendaction
-local enableaction = nodes.tasks.enableaction
+ local cssfile, xhtmlfile, alternative = nil, nil, nil
-function commands.setupexport(t)
- table.merge(finetuning,t)
- keephyphens = finetuning.hyphen == variables.yes
-end
+ directives.register("backend.export.css", function(v) cssfile = v end)
+ directives.register("backend.export.xhtml", function(v) xhtmlfile = v end)
+ directives.register("backend.export.alternative",function(v) alternative = v end)
-local function startexport(v)
- if v and not exporting then
- report_export("enabling export to xml")
- -- not yet known in task-ini
- appendaction("shipouts","normalizers", "nodes.handlers.export")
- -- enableaction("shipouts","nodes.handlers.export")
- enableaction("shipouts","nodes.handlers.accessibility")
- enableaction("math", "noads.handlers.tags")
- -- appendaction("finalizers","lists","builders.paragraphs.tag")
- -- enableaction("finalizers","builders.paragraphs.tag")
- luatex.registerstopactions(function() stopexport(v) end)
- exporting = true
+ local function stopexport(v)
+ starttiming(treehash)
+ --
+ finishexport()
+ --
+ wrapups.collapsetree(tree)
+ wrapups.indextree(tree)
+ wrapups.checktree(tree)
+ wrapups.breaktree(tree)
+ wrapups.finalizetree(tree)
+ --
+ wrapups.hashlistdata()
+ --
+ if type(v) ~= "string" or v == v_yes or v == "" then
+ v = tex.jobname
+ end
+ local basename = file.basename(v)
+ local xmlfile = file.addsuffix(basename,"export")
+ --
+ local imagefilename = file.addsuffix(file.removesuffix(xmlfile) .. "-images","css")
+ local stylefilename = file.addsuffix(file.removesuffix(xmlfile) .. "-styles","css")
+ local templatefilename = file.replacesuffix(xmlfile,"template")
+ local specificationfilename = file.replacesuffix(xmlfile,"specification")
+ --
+ if xhtml and not cssfile then
+ cssfile = true
+ end
+ local cssfiles = { }
+ if cssfile then
+ if cssfile == true then
+ cssfiles = { "export-example.css" }
+ else
+ cssfiles = settings_to_array(cssfile or "")
+ end
+ insert(cssfiles,1,imagefilename)
+ insert(cssfiles,1,stylefilename)
+ end
+ cssfiles = table.unique(cssfiles)
+ --
+ local result = allcontent(tree) -- also does some housekeeping and data collecting
+ --
+ local files = {
+ }
+ local results = concat {
+ wholepreamble(),
+ allusedstylesheets(xmlfile,cssfiles,files), -- ads to files
+ result,
+ }
+ --
+ files = table.unique(files)
+ --
+ report_export("saving xml data in %a",xmlfile)
+ io.savedata(xmlfile,results)
+ --
+ report_export("saving css image definitions in %a",imagefilename)
+ io.savedata(imagefilename,wrapups.allusedimages(xmlfile))
+ --
+ report_export("saving css style definitions in %a",stylefilename)
+ io.savedata(stylefilename,wrapups.allusedstyles(xmlfile))
+ --
+ report_export("saving css template in %a",templatefilename)
+ io.savedata(templatefilename,allusedelements(xmlfile))
+ --
+ local xmltree = nil
+ if xhtmlfile then
+ if type(v) ~= "string" or xhtmlfile == true or xhtmlfile == v_yes or xhtmlfile == "" or xhtmlfile == xmlfile then
+ xhtmlfile = file.replacesuffix(xmlfile,"xhtml")
+ else
+ xhtmlfile = file.addsuffix(xhtmlfile,"xhtml")
+ end
+ files[#files+1] = xhtmlfile
+ report_export("saving xhtml variant in %a",xhtmlfile)
+ xmltree = cleanxhtmltree(xml.convert(results))
+ xml.save(xmltree,xhtmlfile)
+ -- looking at identity is somewhat redundant as we also inherit from interaction
+ -- at the tex end
+ local identity = interactions.general.getidentity()
+ local specification = {
+ name = file.removesuffix(v),
+ identifier = os.uuid(),
+ images = wrapups.uniqueusedimages(),
+ root = xhtmlfile,
+ files = files,
+ language = languagenames[texgetcount("mainlanguagenumber")],
+ title = validstring(finetuning.title) or validstring(identity.title),
+ subtitle = validstring(finetuning.subtitle) or validstring(identity.subtitle),
+ author = validstring(finetuning.author) or validstring(identity.author),
+ firstpage = validstring(finetuning.firstpage),
+ lastpage = validstring(finetuning.lastpage),
+ }
+ report_export("saving specification in %a (mtxrun --script epub --make %s)",specificationfilename,specificationfilename)
+ io.savedata(specificationfilename,table.serialize(specification,true))
+ end
+ if type(alternative) == "string" then
+ local filename = "back-exp-"..alternative ..".lua"
+ local fullname = resolvers.findfile(filename) or ""
+ if fullname == "" then
+ report_export("no valid alternative %a in %a",alternative,filename)
+ else
+ specification = dofile(fullname) or false
+ if specification then
+ if not xmltree then
+ xmltree = xml.convert(results)
+ end
+ remap(specification,xmltree)
+ local resultfile = file.replacesuffix(xmlfile,specification.suffix or alternative)
+ report_export("saving alternative in %a",resultfile)
+ xml.save(xmltree,resultfile)
+ end
+ end
+ end
+ stoptiming(treehash)
end
-end
-directives.register("backend.export",startexport) -- maybe .name
+ local appendaction = nodes.tasks.appendaction
+ local enableaction = nodes.tasks.enableaction
-statistics.register("xml exporting time", function()
- if exporting then
- return format("%s seconds, version %s", statistics.elapsedtime(treehash),exportversion)
+ function commands.setupexport(t)
+ table.merge(finetuning,t)
+ keephyphens = finetuning.hyphen == v_yes
end
-end)
+
+ local function startexport(v)
+ if v and not exporting then
+ report_export("enabling export to xml")
+ -- not yet known in task-ini
+ appendaction("shipouts","normalizers", "nodes.handlers.export")
+ -- enableaction("shipouts","nodes.handlers.export")
+ enableaction("shipouts","nodes.handlers.accessibility")
+ enableaction("math", "noads.handlers.tags")
+ -- appendaction("finalizers","lists","builders.paragraphs.tag")
+ -- enableaction("finalizers","builders.paragraphs.tag")
+ luatex.registerstopactions(function() stopexport(v) end)
+ exporting = true
+ end
+ end
+
+ directives.register("backend.export",startexport) -- maybe .name
+
+ statistics.register("xml exporting time", function()
+ if exporting then
+ return format("%s seconds, version %s", statistics.elapsedtime(treehash),exportversion)
+ end
+ end)
+
+end
-- These are called at the tex end:
@@ -2446,4 +2727,3 @@ commands.settagfigure = structurestags.setfigure
commands.settagcombination = structurestags.setcombination
commands.settagtablecell = structurestags.settablecell
commands.settagtabulatecell = structurestags.settabulatecell
-
diff --git a/tex/context/base/back-exp.mkiv b/tex/context/base/back-exp.mkiv
index 7fd1b5799..4b91636b7 100644
--- a/tex/context/base/back-exp.mkiv
+++ b/tex/context/base/back-exp.mkiv
@@ -113,9 +113,12 @@
\unexpanded\def\dotagsetnotesymbol{\taggedctxcommand{settagdescriptionsymbol("\currentnote",\currentnotenumber)}}%
\to \everyenableelements
-% \appendtoks
-% \unexpanded\def\doverbatimspace{\asciispacechar}% will be done permanently
-% \to \everyenableelements
+\appendtoks
+ \let\specialfixedspace \explicitfixedspace
+ \let\specialobeyedspace \explicitobeyedspace
+ \let\specialstretchedspace\explicitstretchedspace
+ \let\specialcontrolspace \explicitcontrolspace
+\to \everyenableelements
% The action: \setupbackend[export=yes] % or filename
@@ -137,6 +140,7 @@
\c!author={\directinteractionparameter\c!author},
% \c!firstpage=, % imagename
% \c!lastpage=, % imagename
+ \c!alternative=, % html, div
\c!hyphen=\v!no]
\def\dosynchronizeexport
@@ -166,6 +170,8 @@
{\enabledirectives[backend.export.xhtml=\backendparameter\c!xhtml]}%
\doifsomething{\backendparameter\c!css}
{\enabledirectives[backend.export.css={\backendparameter\c!css}]}%
+ \doifsomething{\backendparameter\c!alternative}
+ {\enabledirectives[backend.export.alternative={\backendparameter\c!alternative}]}%
\to \everysetupbackend
\appendtoks
diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv
index 7a4f28253..c47a75856 100644
--- a/tex/context/base/buff-ver.mkiv
+++ b/tex/context/base/buff-ver.mkiv
@@ -45,8 +45,6 @@
{\spaceskip\fontcharwd\font`x\relax
\xspaceskip\spaceskip}
-\unexpanded\def\specialcontrolspace{\hskip\zeropoint\fastcontrolspace\hskip\zeropoint}
-
\setvalue{\??typinglines\v!no }{\buff_verbatim_ignore_hyphens}
\setvalue{\??typinglines\v!normal }{\buff_verbatim_ignore_hyphens}
\setvalue{\??typinglines\v!yes }{\buff_verbatim_obey_breakpoints}
@@ -75,26 +73,23 @@
\unexpanded\def\buff_verbatim_ignore_hyphens
{\language\minusone} % tricky as this affects the pagebuilder
-\def\buff_verbatim_initialize_breaks % order matters
- {\spaceskip.5\emwidth\relax
- \let\obeyedspace\specialobeyedspace
- \let\controlspace\specialcontrolspace
- \edef\p_buff_lines{\typeparameter\c!lines}%
- \ifcsname\??typinglines\p_buff_lines\endcsname % sets \obeyedspace, \controlspace,
- \csname\??typinglines\p_buff_lines\endcsname
- \fi
- \edef\p_buff_space{\typeparameter\c!space}%
- \ifcsname\??typingspace\p_buff_space\endcsname % sets \obeyedspace
- \csname\??typingspace\p_buff_space\endcsname
- \fi}
-
\def\buff_verbatim_initialize_type_one
{\let\obeylines\ignorelines
\usetypestyleandcolor\c!style\c!color
\setcatcodetable\vrbcatcodes}
\def\buff_verbatim_initialize_type_two
- {\buff_verbatim_initialize_breaks
+ {\spaceskip.5\emwidth\relax
+ \let\obeyedspace\specialobeyedspace
+ \let\controlspace\specialcontrolspace
+ % \edef\p_buff_lines{\typeparameter\c!lines}%
+ % \ifcsname\??typinglines\p_buff_lines\endcsname
+ % \csname\??typinglines\p_buff_lines\endcsname
+ % \fi
+ \edef\p_buff_space{\typeparameter\c!space}%
+ \ifcsname\??typingspace\p_buff_space\endcsname
+ \csname\??typingspace\p_buff_space\endcsname
+ \fi
\relax\the\everyinitializeverbatim\relax}
\unexpanded\def\doinitializeverbatim % for use elsewhere .. temp hack (see lxml-ini)
@@ -106,8 +101,9 @@
\def\buff_verbatim_set_line_margin_indeed
{\hskip\doifoddpageelse{\typingparameter\c!oddmargin}{\typingparameter\c!evenmargin}\relax}
-\def\buff_verbatim_check_margins
- {\scratchskip\typingparameter\c!oddmargin\relax
+\def\buff_verbatim_initialize_typing_one
+ {\switchtobodyfont[\typingparameter\c!bodyfont]% can be low level call
+ \scratchskip\typingparameter\c!oddmargin\relax
\ifzeropt\scratchskip \else
\let\buff_verbatim_set_line_margin\buff_verbatim_set_line_margin_indeed
\fi
@@ -117,16 +113,23 @@
\fi
\ifx\buff_verbatim_set_line_margin\relax
\doadaptleftskip{\typingparameter\c!margin}%
- \fi}
-
-\def\buff_verbatim_initialize_typing_one
- {\switchtobodyfont[\typingparameter\c!bodyfont]% can be low level call
- \buff_verbatim_check_margins
+ \fi
\usetypingstyleandcolor\c!style\c!color
- \doifsomething{\typingparameter\c!align}{\setupalign[\typingparameter\c!align]}}
+ % will become: \usealignparameter\typingparameter
+ \doifsomething{\typingparameter\c!align}{\setupalign[\typingparameter\c!align]}} % use fast one
\def\buff_verbatim_initialize_typing_two
- {\buff_verbatim_initialize_breaks
+ {\spaceskip.5\emwidth\relax
+ \let\obeyedspace\specialobeyedspace
+ \let\controlspace\specialcontrolspace
+ \edef\p_buff_lines{\typingparameter\c!lines}%
+ \ifcsname\??typinglines\p_buff_lines\endcsname
+ \csname\??typinglines\p_buff_lines\endcsname
+ \fi
+ \edef\p_buff_space{\typingparameter\c!space}%
+ \ifcsname\??typingspace\p_buff_space\endcsname
+ \csname\??typingspace\p_buff_space\endcsname
+ \fi
\relax\the\everyinitializeverbatim\relax}
%D \macros
@@ -371,15 +374,15 @@
%D works all right, but a decent hyphenation support of
%D \type{\tt} text will be implemented soon.
-\unexpanded\def\specialfixedspace {\kern\interwordspace\relax}
-\unexpanded\def\specialobeyedspace {\hskip\interwordspace\relax} % better than spaceskip
-\unexpanded\def\specialstretchedspace{\hskip.5\interwordspace\s!plus.125\interwordspace\relax} % \interwordstretch can be zero
-\unexpanded\def\specialcontrolspace {\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}
+\unexpanded\def\specialfixedspace {\kern\interwordspace\relax}
+\unexpanded\def\specialobeyedspace {\hskip\interwordspace\relax} % better than spaceskip
+\unexpanded\def\specialstretchedspace {\hskip.5\interwordspace\s!plus.125\interwordspace\relax} % \interwordstretch can be zero
+\unexpanded\def\specialcontrolspace {\normalcontrolspace\allowbreak} % uses fallback
-% \unexpanded\def\taggedspecialfixedspace {\hskip\zeropoint\asciispacechar\hskip\zeropoint}
-% \unexpanded\def\taggedspecialobeyedspace {\hskip\zeropoint\asciispacechar\hskip\zeropoint}
-% \unexpanded\def\taggedspecialstretchedspace{\hskip\zeropoint\asciispacechar\hskip\zeropoint}
-% \unexpanded\def\taggedspecialcontrolspace {\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}
+\unexpanded\def\explicitfixedspace {\asciispacechar}
+\unexpanded\def\explicitobeyedspace {\asciispacechar\allowbreak}
+\unexpanded\def\explicitstretchedspace{\asciispacechar\hskip\zeropoint\s!plus.125\interwordspace\relax}%
+\unexpanded\def\explicitcontrolspace {\optionalcontrolspace\allowbreak} % uses asciispace
\appendtoks
\unexpanded\def\obeyedspace{\hskip\zeropoint\asciispacechar\hskip\zeropoint}%
@@ -856,8 +859,10 @@
\fi
\noindent
\buff_verbatim_set_line_margin
- \the\everyline\strut
- \dostarttagged\t!verbatimline\empty}
+ \the\everyline % maybe also after starttagged
+ \strut % after starttagged, else break !
+ \dostarttagged\t!verbatimline\empty
+ }
\unexpanded\def\buff_verbatim_end_of_line
{\dostoptagged
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 15fca6049..b66665f19 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.07.11 12:20}
+\newcontextversion{2014.07.14 12:38}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 3e3f29803..dce512206 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 5ce04e804..5026eabe4 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.07.11 12:20}
+\edef\contextversion{2014.07.14 12:38}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/enco-ini.mkiv b/tex/context/base/enco-ini.mkiv
index ab3aa488d..0fae1aade 100644
--- a/tex/context/base/enco-ini.mkiv
+++ b/tex/context/base/enco-ini.mkiv
@@ -250,9 +250,27 @@
\chardef\textcontrolspace"2423
-\unexpanded\def\fallbackcontrolspace
- %{\getglyph{ComputerModernMono}\textcontrolspace}
- {\getglyph{LMTypewriter-Regular}\textcontrolspace}
+\installcorenamespace{controlspace}
+
+% \unexpanded\def\fallbackcontrolspace % beware: non-matching widths
+% {\hbox to \interwordspace{\hss\getglyph{LMTypewriter-Regular}\textcontrolspace\hss}%
+
+\unexpanded\def\fallbackcontrolspace % beware, current font, we also need to honor color
+ {\hbox to \interwordspace \bgroup
+ \hss
+ \ifcsname\??controlspace\number\interwordspace\endcsname
+ \csname\??controlspace\number\interwordspace\endcsname
+ \else
+ \enco_fast_control_space_define % only regular
+ \fi
+ \textcontrolspace
+ \hss
+ \egroup}
+
+\unexpanded\def\enco_fast_control_space_define
+ {\scratchdimen\interwordspace
+ \definedfont[LMTypewriter-Regular at \the\dimexpr\currentfontbodyscale\dimexpr\fontbody]% see font-sym.mkiv
+ \expandafter\glet\csname\??controlspace\number\scratchdimen\endcsname\lastrawfontcall}
\unexpanded\def\normalcontrolspace
{\iffontchar\font\textcontrolspace
@@ -263,29 +281,35 @@
\let\textvisiblespace\normalcontrolspace
-\unexpanded\def\fastcontrolspace % no glyph resolving after first (use grouped)
- {\enco_fast_control_space}
-
-\def\enco_fast_control_space
+\unexpanded\def\optionalcontrolspace
{\iffontchar\font\textcontrolspace
- \enco_fast_control_space_nop
+ \textcontrolspace
\else
- \enco_fast_control_space_yes
- \fi
- \enco_fast_control_space}
-
-\newbox\b_enco_control_space
-
-\def\enco_fast_control_space_nop
- {\let\enco_fast_control_space\textcontrolspace}
-
-\def\enco_fast_control_space_yes
- {\setbox\b_enco_control_space\hbox{\space}%
- \setbox\b_enco_control_space\hbox to \wd\b_enco_control_space{\hss\fallbackcontrolspace\hss}%
- \let\enco_fast_control_space\flushcontrolspacebox}
+ \asciispacechar % used for export !
+ \fi}
-\def\flushcontrolspacebox
- {\copy\b_enco_control_space}
+% \unexpanded\def\fastcontrolspace % no glyph resolving after first (use grouped)
+% {\enco_fast_control_space}
+%
+% \def\enco_fast_control_space
+% {\iffontchar\font\textcontrolspace
+% \enco_fast_control_space_nop
+% \else
+% \enco_fast_control_space_yes
+% \fi
+% \enco_fast_control_space}
+%
+% \newbox\b_enco_control_space
+%
+% \def\enco_fast_control_space_nop
+% {\let\enco_fast_control_space\textcontrolspace}
+%
+% \def\enco_fast_control_space_yes
+% {\setbox\b_enco_control_space\fallbackcontrolspace
+% \let\enco_fast_control_space\flushcontrolspacebox}
+%
+% \def\flushcontrolspacebox
+% {\copy\b_enco_control_space}
% a few defaults (\<whatever>{}), we really need the verbose \empty as it will be
% stringified .. anyhow, we define this at the lua end now but keep it here as a
diff --git a/tex/context/base/file-lib.lua b/tex/context/base/file-lib.lua
index 7489a317b..2471cdd84 100644
--- a/tex/context/base/file-lib.lua
+++ b/tex/context/base/file-lib.lua
@@ -44,7 +44,7 @@ function commands.uselibrary(specification) -- todo: reporter
local truename = environment.truefilename
local function found(filename)
local somename = truename and truename(filename) or filename
- local foundname = getreadfilename("any",".",somename)
+ local foundname = getreadfilename("any",".",somename) -- maybe some day also an option not to backtrack .. and ../.. (or block global)
return foundname ~= "" and foundname
end
for i=1,#files do
diff --git a/tex/context/base/file-res.lua b/tex/context/base/file-res.lua
index 9ae7a6b06..458ef7276 100644
--- a/tex/context/base/file-res.lua
+++ b/tex/context/base/file-res.lua
@@ -17,7 +17,10 @@ local report_files = logs.reporter("files","readfile")
resolvers.maxreadlevel = 2
-directives.register("resolvers.maxreadlevel", function(v) resolvers.maxreadlevel = tonumber(v) or resolvers.maxreadlevel end)
+directives.register("resolvers.maxreadlevel", function(v)
+ -- resolvers.maxreadlevel = (v == false and 0) or (v == true and 2) or tonumber(v) or 2
+ resolvers.maxreadlevel = v == false and 0 or tonumber(v) or 2
+end)
local finders, loaders, openers = resolvers.finders, resolvers.loaders, resolvers.openers
diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua
index 8debcc3bb..de43c08a9 100644
--- a/tex/context/base/font-mis.lua
+++ b/tex/context/base/font-mis.lua
@@ -22,7 +22,7 @@ local handlers = fonts.handlers
handlers.otf = handlers.otf or { }
local otf = handlers.otf
-otf.version = otf.version or 2.756
+otf.version = otf.version or 2.757
otf.cache = otf.cache or containers.define("fonts", "otf", otf.version, true)
function otf.loadcached(filename,format,sub)
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index ed9cabedc..4eeea2133 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -48,7 +48,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.756 -- beware: also sync font-mis.lua
+otf.version = 2.757 -- beware: also sync font-mis.lua
otf.cache = containers.define("fonts", "otf", otf.version, true)
local fontdata = fonts.hashes.identifiers
@@ -694,7 +694,7 @@ elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFD then
elseif unicode >= 0x100000 and unicode <= 0x10FFFD then
unicode = -1
end
- local name = glyph.name or cidnames[index]
+ local name = glyph.name or cidnames[index]
if not unicode or unicode == -1 then -- or unicode >= criterium then
unicode = cidunicodes[index]
end
@@ -704,7 +704,7 @@ end
end
if not unicode or unicode == -1 then -- or unicode >= criterium then
if not name then
- name = format("u%06X",private)
+ name = format("u%06X.ctx",private)
end
unicode = private
unicodes[name] = private
@@ -714,8 +714,20 @@ end
private = private + 1
nofnames = nofnames + 1
else
+ -- if unicode > criterium then
+ -- local taken = descriptions[unicode]
+ -- if taken then
+ -- private = private + 1
+ -- descriptions[private] = taken
+ -- unicodes[taken.name] = private
+ -- indices[taken.index] = private
+ -- if trace_private then
+ -- report_otf("slot %U is moved to %U due to private in font",unicode)
+ -- end
+ -- end
+ -- end
if not name then
- name = format("u%06X",unicode)
+ name = format("u%06X.ctx",unicode)
end
unicodes[name] = unicode
nofunicodes = nofunicodes + 1
@@ -763,11 +775,24 @@ end
private = private + 1
else
unicodes[name] = unicode
+ if unicode > criterium then
+ -- \definedfont[file:HANBatang-LVT.ttf] \fontchar{uF0135} \char"F0135
+ local taken = descriptions[unicode]
+ if taken then
+ private = private + 1
+ descriptions[private] = taken
+ unicodes[taken.name] = private
+ indices[taken.index] = private
+ if trace_private then
+ report_otf("slot %U is moved to %U due to private in font",unicode)
+ end
+ end
+ end
end
indices[index] = unicode
- if not name then
- name = format("u%06X",unicode)
- end
+ -- if not name then
+ -- name = format("u%06X",unicode) -- u%06X.ctx
+ -- end
descriptions[unicode] = {
-- width = glyph.width,
boundingbox = glyph.boundingbox,
@@ -1498,7 +1523,9 @@ local function check_variants(unicode,the_variants,splitter,unicodes)
for i=1,#glyphs do
local g = glyphs[i]
if done[g] then
- report_otf("skipping cyclic reference %U in math variant %U",g,unicode)
+ if i > 1 then
+ report_otf("skipping cyclic reference %U in math variant %U",g,unicode)
+ end
else
if n == 0 then
n = 1
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 96f2ce099..15032953f 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index d0362cd72..6d2526742 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/x-mathml.mkiv b/tex/context/base/x-mathml.mkiv
index badccbc4d..5335e5ca0 100644
--- a/tex/context/base/x-mathml.mkiv
+++ b/tex/context/base/x-mathml.mkiv
@@ -530,11 +530,11 @@
} {
\doifsetupselse {mml:csymbol:#1} {
% full url
- \directsetup{mml:csymbol:#1}
+ \fastsetup{mml:csymbol:#1}
} {
% somename (fallback)
\doifsetupselse {mml:csymbol:#2} {
- \directsetup{mml:csymbol:#2}
+ \fastsetup{mml:csymbol:#2}
} {
\xmlval{mmc:cs}{#3}{}% todo
}
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 99a0d35ab..3faa9ff54 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 : 07/11/14 12:20:35
+-- merge date : 07/14/14 12:38:06
do -- begin closure to overcome local limits and interference
@@ -6681,7 +6681,7 @@ local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
otf.glists={ "gsub","gpos" }
-otf.version=2.756
+otf.version=2.757
otf.cache=containers.define("fonts","otf",otf.version,true)
local fontdata=fonts.hashes.identifiers
local chardata=characters and characters.data
@@ -7241,7 +7241,7 @@ end
end
if not unicode or unicode==-1 then
if not name then
- name=format("u%06X",private)
+ name=format("u%06X.ctx",private)
end
unicode=private
unicodes[name]=private
@@ -7252,7 +7252,7 @@ end
nofnames=nofnames+1
else
if not name then
- name=format("u%06X",unicode)
+ name=format("u%06X.ctx",unicode)
end
unicodes[name]=unicode
nofunicodes=nofunicodes+1
@@ -7294,11 +7294,20 @@ end
private=private+1
else
unicodes[name]=unicode
+ if unicode>criterium then
+ local taken=descriptions[unicode]
+ if taken then
+ private=private+1
+ descriptions[private]=taken
+ unicodes[taken.name]=private
+ indices[taken.index]=private
+ if trace_private then
+ report_otf("slot %U is moved to %U due to private in font",unicode)
+ end
+ end
+ end
end
indices[index]=unicode
- if not name then
- name=format("u%06X",unicode)
- end
descriptions[unicode]={
boundingbox=glyph.boundingbox,
name=name,
@@ -7909,7 +7918,9 @@ local function check_variants(unicode,the_variants,splitter,unicodes)
for i=1,#glyphs do
local g=glyphs[i]
if done[g] then
- report_otf("skipping cyclic reference %U in math variant %U",g,unicode)
+ if i>1 then
+ report_otf("skipping cyclic reference %U in math variant %U",g,unicode)
+ end
else
if n==0 then
n=1