summaryrefslogtreecommitdiff
path: root/tex/context/base/back-exp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/back-exp.lua')
-rw-r--r--tex/context/base/back-exp.lua337
1 files changed, 205 insertions, 132 deletions
diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index 46e2c951c..d7a50da3a 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -27,9 +27,10 @@ local topoints = number.topoints
local utfvalues = string.utfvalues
local fromunicode16 = fonts.mappings.fromunicode16
-local trace_export = false trackers.register ("export.trace", function(v) trace_export = 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)
+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)
-- maybe we will also support these:
--
@@ -423,7 +424,7 @@ local breakattributes = {
type = "collapse"
}
-local function makebreaknode(node) -- maybe no fulltag
+local function makebreaknode(attributes) -- maybe no fulltag
nofbreaks = nofbreaks + 1
return {
tg = "break",
@@ -431,7 +432,7 @@ local function makebreaknode(node) -- maybe no fulltag
n = nofbreaks,
element = "break",
nature = "display",
- -- attributes = breakattributes,
+ attributes = attributes or nil,
-- data = { }, -- not needed
-- attribute = 0, -- not needed
-- parnumber = 0,
@@ -1208,29 +1209,26 @@ end
local linedone = false -- can go ... we strip newlines anyway
local inlinedepth = 0
-local function emptytag(result,element,nature,depth)
- if linedone then
- result[#result+1] = format("%s<%s/>\n",spaces[depth],namespaced[element])
- else
- result[#result+1] = format("\n%s<%s/>\n",spaces[depth],namespaced[element])
- end
- linedone = false
-end
+-- todo: #result -> nofresult
-local function btag(result,element,nature,depth)
- if linedone then
- result[#result+1] = format("%s<%s>\n",spaces[depth],namespaced[element])
- else
- result[#result+1] = format("\n%s<%s>\n",spaces[depth],namespaced[element])
- end
- linedone = false
-end
-
-local function etag(result,element,nature,depth)
- if linedone then
- result[#result+1] = format("%s</%s>\n",spaces[depth],namespaced[element])
+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] = format("%s<%s",spaces[depth],namespaced[element])
+ else
+ result[#result+1] = format("\n%s<%s",spaces[depth],namespaced[element])
+ end
+ for k, v in next, a do
+ result[#result+1] = format(" %s=%q",k,v)
+ end
+ result[#result+1] = "/>\n"
else
- result[#result+1] = format("\n%s</%s>\n",spaces[depth],namespaced[element])
+ if linedone then
+ result[#result+1] = format("%s<%s/>\n",spaces[depth],namespaced[element])
+ else
+ result[#result+1] = format("\n%s<%s/>\n",spaces[depth],namespaced[element])
+ end
end
linedone = false
end
@@ -1383,26 +1381,31 @@ local function flushtree(result,data,nature,depth)
local nofdata = #data
for i=1,nofdata do
local di = data[i]
- if not di then -- or di == ""
+ if not di then
-- whatever
- elseif type(di) == "string" then
+ elseif di.content then
-- already has breaks
- di = utfgsub(di,".",entities) -- new
- if i == nofdata and sub(di,-1) == "\n" then
- if nature == "inline" or nature == "mixed" then
- result[#result+1] = sub(di,1,-2)
+ local content = utfgsub(di.content,".",entities)
+ 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] = format("<c n='%s'>%s</c>",di.parnumber,sub(content,1,-2))
else
- result[#result+1] = sub(di,1,-2)
- result[#result+1] = " "
+ result[#result+1] = sub(content,1,-2)
end
+ result[#result+1] = " "
else
- result[#result+1] = di
+ if trace_spacing then
+ result[#result+1] = format("<c n='%s'>%s</c>",di.parnumber,content)
+ else
+ result[#result+1] = content
+ end
end
linedone = false
elseif not di.collapsed then -- ignore collapsed data (is appended, reconstructed par)
local element = di.element
if element == "break" then -- or element == "pagebreak"
- emptytag(result,element,nature,depth)
+ emptytag(result,element,nature,depth,di)
elseif element == "" or di.skip == "ignore" then
-- skip
else
@@ -1412,10 +1415,13 @@ local function flushtree(result,data,nature,depth)
local natu = di.nature
local skip = di.skip
if di.breaknode then
- emptytag(result,"break","display",depth)
+ 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)
@@ -1425,44 +1431,85 @@ local function flushtree(result,data,nature,depth)
end
end
--- way too fragile
-
local function breaktree(tree,parent,parentelement) -- also removes double breaks
- local data = tree.data
- if data then
- local nofdata = #data
- local prevelement
- for i=1,nofdata do
- local di = data[i]
- if not di then
- -- skip
- elseif type(di) == "string" then
- prevelement = nil
- 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
- elseif element == "" or di.skip == "ignore" then
- -- skip
- else
---~ if element == "p" and di.nature ~= "display" then
---~ di = di.data
---~ data[i] = di
---~ breaktree(di,tree,element)
---~ else
+ 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
- end
- end
- end
- end
+ 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
+ end
+ prevnature = nature
+ prevparnumber = parnumber
+ nofnewdata = nofnewdata + 1
+ newdata[nofnewdata] = di
+ end
+ end
+ tree.data = newdata
+ end
end
--- tabulaterow reconstruction .. can better be a checker (TO BE CHECKED)
+-- also tabulaterow reconstruction .. maybe better as a checker
+-- i.e cell attribute
local function collapsetree()
for tag, trees in next, treehash do
@@ -1477,21 +1524,25 @@ local function collapsetree()
local previouspar = trees[i-1].parnumber
currenttree.collapsed = true
-- is the next ok?
- if previouspar == 0 or type(currentdata[1]) ~= "string" then
+ 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 type(cd) == "string" then
+ elseif cd.content then
if not currentpar then
-- add space ?
elseif not previouspar then
-- add space ?
elseif currentpar ~= previouspar then
nd = nd + 1
- d[nd] = makebreaknode(currenttree)
+ if trace_spacing then
+ d[nd] = makebreaknode { type = "d", p = previouspar, n = currentpar }
+ else
+ d[nd] = makebreaknode()
+ end
end
previouspar = currentpar
nd = nd + 1
@@ -1522,7 +1573,7 @@ local function indextree(tree)
local d = data[i]
if not d then
-- skip
- elseif type(d) == "string" then
+ elseif d.content then
n = n + 1
new[n] = d
elseif not d.collapsed then
@@ -1696,7 +1747,6 @@ local function pushcontent(addbreak)
local content = concat(currentcontent,"",1,nofcurrentcontent)
if content == "" then
-- omit; when addbreak we could push, remove spaces, pop
---~ elseif content == " " and addbreak then
elseif somespace[content] and addbreak then
-- omit; when addbreak we could push, remove spaces, pop
else
@@ -1707,10 +1757,10 @@ local function pushcontent(addbreak)
end
local td = tree.data
local nd = #td
- td[nd+1] = content
+ td[nd+1] = { parnumber = currentparagraph, content = content }
if trace_export then
report_export("%s<!-- start content with length %s -->",spaces[currentdepth],#content)
- report_export("%s%s",spaces[currentdepth],content)
+ report_export("%s%s",spaces[currentdepth],(gsub(content,"\n","\\n")))
report_export("%s<!-- stop content -->",spaces[currentdepth])
end
if olddepth then
@@ -1723,9 +1773,9 @@ local function pushcontent(addbreak)
end
if addbreak then
pushentry(makebreaklist(currentnesting))
- -- if trace_export then
- -- report_export("%s<!-- add break -->",spaces[currentdepth])
- -- end
+ if trace_export then
+ report_export("%s<!-- break added due to %s -->",spaces[currentdepth],addbreak)
+ end
end
end
@@ -1776,8 +1826,8 @@ local function collectresults(head,list) -- is last used (we also have currentat
report_export("%s<!-- processing glyph %s (tag %s) -->",spaces[currentdepth],utfchar(c),at)
end
pushcontent()
- currentparagraph = has_attribute(n,a_taggedpar)
currentnesting = tl
+ currentparagraph = has_attribute(n,a_taggedpar)
currentattribute = at
last = at
pushentry(currentnesting)
@@ -1789,12 +1839,12 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
--
elseif last then
- local at = has_attribute(n,a_taggedpar)
- if at ~= currentparagraph then
- pushcontent(true) -- add break
+ local ap = has_attribute(n,a_taggedpar)
+ if ap ~= currentparagraph then
+ pushcontent(format("new paragraph (%s -> %s)",tostring(currentparagraph),tostring(ap)))
pushentry(currentnesting)
currentattribute = last
- currentparagraph = at
+ currentparagraph = ap
end
if trace_export then
report_export("%s<!-- processing glyph %s (tag %s) -->",spaces[currentdepth],utfchar(c),last)
@@ -1830,11 +1880,6 @@ local function collectresults(head,list) -- is last used (we also have currentat
if fc then
local u = fc.tounicode
if u and u ~= "" then
- -- tracing
--- for s in gmatch(u,"....") do -- is this ok?
--- nofcurrentcontent = nofcurrentcontent + 1
--- currentcontent[nofcurrentcontent] = utfchar(tonumber(s,16))
--- end
nofcurrentcontent = nofcurrentcontent + 1
currentcontent[nofcurrentcontent] = utfchar(fromunicode16(u))
else
@@ -1937,60 +1982,85 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
elseif subtype == spaceskip_code or subtype == xspaceskip_code then
if not somespace[currentcontent[nofcurrentcontent]] then
- if trace_export then
- report_export("%s<!-- injecting spacing 7 -->",spaces[currentdepth])
+ local a = has_attribute(n,a_tagged)
+ if a == last then
+ if trace_export then
+ report_export("%s<!-- injecting spacing 7 (stay in element) -->",spaces[currentdepth])
+ end
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = " "
+ else
+ if trace_export then
+ report_export("%s<!-- injecting spacing 7 (end of element) -->",spaces[currentdepth])
+ end
+ last = a
+ pushcontent()
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = " "
+ currentnesting = taglist[last]
+ pushentry(currentnesting)
+ currentattribute = last
end
- nofcurrentcontent = nofcurrentcontent + 1
- currentcontent[nofcurrentcontent] = " "
end
- elseif subtype == rightskip_code or subtype == parfillskip_code then
- if nofcurrentcontent > 0 then -- and n.subtype == line_code then
- local r = currentcontent[nofcurrentcontent]
- if type(r) == "string" and r ~= " " then
- local s = utfsub(r,-1)
- if s == hyphen then
- if not keephyphens then
- currentcontent[nofcurrentcontent] = utfsub(r,1,-2)
- end
- elseif s ~= "\n" then
--- test without this
- if trace_export then
- report_export("%s<!-- injecting newline 1 -->",spaces[currentdepth])
+ elseif id == kern_code then
+ local kern = n.kern
+ if kern > 0 then
+ local limit = threshold
+ if p and p.id == glyph_code then
+ limit = fontquads[p.font] / 4
+ end
+ if kern > limit then
+ if last and not somespace[currentcontent[nofcurrentcontent]] then
+ local a = has_attribute(n,a_tagged)
+ if a == last then
+ if not somespace[currentcontent[nofcurrentcontent]] then
+ if trace_export then
+ report_export("%s<!-- injecting spacing 8 (%s) -->",spaces[currentdepth],topoints(kern,true))
+ end
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = " "
+ end
+ elseif a then
+ -- e.g LOGO<space>LOGO
+ if trace_export then
+ report_export("%s<!-- processing kern, threshold %s, tag %s => %s -->",spaces[currentdepth],topoints(limit,true),last,a)
+ end
+ last = a
+ pushcontent()
+ if trace_export then
+ report_export("%s<!-- injecting spacing 9 (%s) -->",spaces[currentdepth],topoints(kern,true))
+ end
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = " "
+ currentnesting = taglist[last]
+ pushentry(currentnesting)
+ currentattribute = last
end
- nofcurrentcontent = nofcurrentcontent + 1
- currentcontent[nofcurrentcontent] = "\n"
end
end
end
- end
- elseif id == kern_code then
- local kern = n.kern
- if kern > 0 then
- local limit = threshold
- if p and p.id == glyph_code then
- limit = fontquads[p.font] / 4
- end
- if kern > limit then
- if last and not somespace[currentcontent[nofcurrentcontent]] then
+ elseif subtype == rightskip_code then
+ -- a line
+ if nofcurrentcontent > 0 then
+ local r = currentcontent[nofcurrentcontent]
+ if r == hyphen then
+ if not keephyphens then
+ nofcurrentcontent = nofcurrentcontent - 1
+ end
+ elseif not somespace[r] then
local a = has_attribute(n,a_tagged)
if a == last then
- if not somespace[currentcontent[nofcurrentcontent]] then
- if trace_export then
- report_export("%s<!-- injecting spacing 8 (%s) -->",spaces[currentdepth],topoints(kern,true))
- end
- nofcurrentcontent = nofcurrentcontent + 1
- currentcontent[nofcurrentcontent] = " "
+ if trace_export then
+ report_export("%s<!-- injecting spacing 1 (end of line, stay in element) -->",spaces[currentdepth])
end
- elseif a then
- -- e.g LOGO<space>LOGO
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = " "
+ else
if trace_export then
- report_export("%s<!-- processing kern, threshold %s, tag %s => %s -->",spaces[currentdepth],topoints(limit,true),last,a)
+ report_export("%s<!-- injecting spacing 1 (end of line, end of element) -->",spaces[currentdepth])
end
last = a
pushcontent()
- if trace_export then
- report_export("%s<!-- injecting spacing 9 (%s) -->",spaces[currentdepth],topoints(kern,true))
- end
nofcurrentcontent = nofcurrentcontent + 1
currentcontent[nofcurrentcontent] = " "
currentnesting = taglist[last]
@@ -1999,8 +2069,11 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
end
end
+ elseif subtype == parfillskip_code then
+ -- deal with paragaph endings (crossings) elsewhere and we quit here
+ -- as we don't want the rightskip space addition
+ return
end
- -- elseif id == whatsit_code and n.subtype == localpar_code then
end
p = n
end