diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/math-tag.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/math-tag.lua | 198 |
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() |