summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/math-tag.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/math-tag.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/math-tag.lua198
1 files changed, 146 insertions, 52 deletions
diff --git a/Master/texmf-dist/tex/context/base/math-tag.lua b/Master/texmf-dist/tex/context/base/math-tag.lua
index e5ad30be06e..0ac5b08975e 100644
--- a/Master/texmf-dist/tex/context/base/math-tag.lua
+++ b/Master/texmf-dist/tex/context/base/math-tag.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['math-tag'] = {
license = "see context related readme files"
}
+local find, match = string.find, string.match
+local insert, remove = table.insert, table.remove
+
local attributes, nodes = attributes, nodes
local get_attribute = nodes.getattribute
@@ -31,27 +34,40 @@ local math_fence_code = nodecodes.fence -- attr subtype
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local glyph_code = nodecodes.glyph
+local glue_code = nodecodes.glue
local a_tagged = attributes.private('tagged')
+local a_exportstatus = attributes.private('exportstatus')
+local a_mathcategory = attributes.private('mathcategory')
+local a_mathmode = attributes.private('mathmode')
local tags = structures.tags
local start_tagged = tags.start
+local restart_tagged = tags.restart
local stop_tagged = tags.stop
local taglist = tags.taglist
-local chardata = characters.data
+local chardata = characters.data
+
+local getmathcode = tex.getmathcode
+local mathcodes = mathematics.codes
+local ordinary_code = mathcodes.ordinary
+local variable_code = mathcodes.variable
local process
local function processsubsup(start)
+ -- At some point we might need to add an attribute signaling the
+ -- super- and subscripts because TeX and MathML use a different
+ -- order.
local nucleus, sup, sub = start.nucleus, start.sup, start.sub
if sub then
if sup then
set_attribute(start,a_tagged,start_tagged("msubsup"))
process(nucleus)
- process(sup)
process(sub)
+ process(sup)
stop_tagged()
else
set_attribute(start,a_tagged,start_tagged("msub"))
@@ -69,25 +85,52 @@ local function processsubsup(start)
end
end
+-- todo: check function here and keep attribute the same
+
+-- todo: variants -> original
+
+local actionstack = { }
+
process = function(start) -- we cannot use the processor as we have no finalizers (yet)
while start do
local id = start.id
if id == math_char_code then
+ local char = start.char
-- check for code
- local ch = chardata[start.char]
- local mc = ch and ch.mathclass
- if mc == "number" then
- set_attribute(start,a_tagged,start_tagged("mn"))
- elseif mc == "variable" or not mc then -- variable is default
- set_attribute(start,a_tagged,start_tagged("mi"))
+ local a = get_attribute(start,a_mathcategory)
+ if a then
+ a = { detail = a }
+ end
+ local code = getmathcode(char)
+ if code then
+ code = code[1]
+ end
+ local tag
+ if code == ordinary_code or code == variable_code then
+ local ch = chardata[char]
+ local mc = ch and ch.mathclass
+ if mc == "number" then
+ tag = "mn"
+ elseif mc == "variable" or not mc then -- variable is default
+ tag = "mi"
+ else
+ tag = "mo"
+ end
else
- set_attribute(start,a_tagged,start_tagged("mo"))
+ tag = "mo"
end
+-- print(start,a,tag)
+ set_attribute(start,a_tagged,start_tagged(tag,a))
stop_tagged()
- break
+ break -- okay?
elseif id == math_textchar_code then
-- check for code
- set_attribute(start,a_tagged,start_tagged("ms"))
+ local a = get_attribute(start,a_mathcategory)
+ if a then
+ set_attribute(start,a_tagged,start_tagged("ms"),{ detail = a })
+ else
+ set_attribute(start,a_tagged,start_tagged("ms"))
+ end
stop_tagged()
break
elseif id == math_delim_code then
@@ -102,29 +145,30 @@ process = function(start) -- we cannot use the processor as we have no finalizer
elseif id == math_box_code or id == hlist_code or id == vlist_code then
-- keep an eye on math_box_code and see what ends up in there
local attr = get_attribute(start,a_tagged)
- local text = start_tagged("mtext")
- set_attribute(start,a_tagged,text)
- local list = start.list
- if not list then
- -- empty list
- elseif not attr then
- -- box comes from strange place
- set_attributes(list,a_tagged,text)
+ local last = attr and taglist[attr]
+ if last and find(last[#last],"formulacaption[:%-]") then
+ -- leave alone, will nicely move to the outer level
else
- -- Beware, the first node in list is the actual list so we definitely
- -- need to nest. This approach is a hack, maybe I'll make a proper
- -- nesting feature to deal with this at another level. Here we just
- -- fake structure by enforcing the inner one.
- local tagdata = taglist[attr]
- local common = #tagdata + 1
- local function runner(list) -- quite inefficient
- local cache = { } -- we can have nested unboxed mess so best local to runner
- for n in traverse_nodes(list) do
- local id = n.id
- if id == hlist_code or id == vlist_code then
- runner(n.list)
- elseif id == glyph_code then
- local aa = get_attribute(n,a_tagged) -- only glyph needed
+ local text = start_tagged("mtext")
+ set_attribute(start,a_tagged,text)
+ local list = start.list
+ if not list then
+ -- empty list
+ elseif not attr then
+ -- box comes from strange place
+ set_attributes(list,a_tagged,text)
+ else
+ -- Beware, the first node in list is the actual list so we definitely
+ -- need to nest. This approach is a hack, maybe I'll make a proper
+ -- nesting feature to deal with this at another level. Here we just
+ -- fake structure by enforcing the inner one.
+ local tagdata = taglist[attr]
+ local common = #tagdata + 1
+ local function runner(list) -- quite inefficient
+ local cache = { } -- we can have nested unboxed mess so best local to runner
+ for n in traverse_nodes(list) do
+ local id = n.id
+ local aa = get_attribute(n,a_tagged)
if aa then
local ac = cache[aa]
if not ac then
@@ -132,7 +176,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer
local extra = #tagdata
if common <= extra then
for i=common,extra do
- ac = start_tagged(tagdata[i]) -- can be made faster
+ ac = restart_tagged(tagdata[i]) -- can be made faster
end
for i=common,extra do
stop_tagged() -- can be made faster
@@ -146,18 +190,38 @@ process = function(start) -- we cannot use the processor as we have no finalizer
else
set_attribute(n,a_tagged,text)
end
+ if id == hlist_code or id == vlist_code then
+ runner(n.list)
+ end
end
end
+ runner(list)
end
- runner(list)
+ stop_tagged()
end
- stop_tagged()
elseif id == math_sub_code then
local list = start.list
if list then
- set_attribute(start,a_tagged,start_tagged("mrow"))
- process(list)
- stop_tagged()
+ local attr = get_attribute(start,a_tagged)
+ local last = attr and taglist[attr]
+ local action = last and match(last[#last],"maction:(.-)%-")
+ if action and action ~= "" then
+ if actionstack[#actionstack] == action then
+ set_attribute(start,a_tagged,start_tagged("mrow"))
+ process(list)
+ stop_tagged()
+ else
+ insert(actionstack,action)
+ set_attribute(start,a_tagged,start_tagged("mrow",{ detail = action }))
+ process(list)
+ stop_tagged()
+ remove(actionstack)
+ end
+ else
+ set_attribute(start,a_tagged,start_tagged("mrow"))
+ process(list)
+ stop_tagged()
+ end
end
elseif id == math_fraction_code then
local num, denom, left, right = start.num, start.denom, start.left, start.right
@@ -191,17 +255,40 @@ process = function(start) -- we cannot use the processor as we have no finalizer
end
elseif id == math_fence_code then
local delim = start.delim
- if delim then
- set_attribute(start,a_tagged,start_tagged("mo"))
- process(delim)
+ local subtype = start.subtype
+ if subtype == 1 then
+ -- left
+ set_attribute(start,a_tagged,start_tagged("mfenced"))
+ if delim then
+ set_attribute(start,a_tagged,start_tagged("mleft"))
+ process(delim)
+ stop_tagged()
+ end
+ elseif subtype == 2 then
+ -- middle
+ if delim then
+ set_attribute(start,a_tagged,start_tagged("mmiddle"))
+ process(delim)
+ stop_tagged()
+ end
+ elseif subtype == 3 then
+ if delim then
+ set_attribute(start,a_tagged,start_tagged("mright"))
+ process(delim)
+ stop_tagged()
+ end
stop_tagged()
+ else
+ -- can't happen
end
elseif id == math_radical_code then
local left, degree = start.left, start.degree
if left then
- process(left) -- mrow needed ?
+ start_tagged("")
+ process(left) -- root symbol, ignored
+ stop_tagged()
end
- if degree then
+ if degree then -- not good enough, can be empty mlist
set_attribute(start,a_tagged,start_tagged("mroot"))
processsubsup(start)
process(degree)
@@ -215,27 +302,30 @@ process = function(start) -- we cannot use the processor as we have no finalizer
local accent, bot_accent = start.accent, start.bot_accent
if bot_accent then
if accent then
- set_attribute(start,a_tagged,start_tagged("munderover"))
- process(accent)
+ set_attribute(start,a_tagged,start_tagged("munderover",{ detail = "accent" }))
processsubsup(start)
process(bot_accent)
+ process(accent)
stop_tagged()
else
- set_attribute(start,a_tagged,start_tagged("munder"))
+ set_attribute(start,a_tagged,start_tagged("munder",{ detail = "accent" }))
processsubsup(start)
process(bot_accent)
stop_tagged()
end
elseif accent then
- set_attribute(start,a_tagged,start_tagged("mover"))
- process(accent)
+ set_attribute(start,a_tagged,start_tagged("mover",{ detail = "accent" }))
processsubsup(start)
+ process(accent)
stop_tagged()
else
processsubsup(start)
end
+ elseif id == glue_code then
+ set_attribute(start,a_tagged,start_tagged("mspace"))
+ stop_tagged()
else
- set_attribute(start,a_tagged,start_tagged("merror"))
+ set_attribute(start,a_tagged,start_tagged("merror", { detail = nodecodes[i] } ))
stop_tagged()
end
start = start.next
@@ -243,8 +333,12 @@ process = function(start) -- we cannot use the processor as we have no finalizer
end
function noads.handlers.tags(head,style,penalties)
- set_attribute(head,a_tagged,start_tagged("math"))
- set_attribute(head,a_tagged,start_tagged("mrow"))
+ local v_math = start_tagged("math")
+ local v_mrow = start_tagged("mrow")
+ local v_mode = get_attribute(head,a_mathmode)
+ set_attribute(head,a_tagged,v_math)
+ set_attribute(head,a_tagged,v_mrow)
+ tags.setattributehash(v_math,"mode",v_mode == 1 and "display" or "inline")
process(head)
stop_tagged()
stop_tagged()