diff --git a/mlist_to_mml.lua b/mlist_to_mml.lua index eb2af47..c584e80 100644 --- a/mlist_to_mml.lua +++ b/mlist_to_mml.lua @@ -1,4 +1,7 @@ local remap_comb = require'remap_comb' +local stretchy = require'stretchy' + +local properties = node.get_properties_table() local noad_t, accent_t, style_t, choice_t = node.id'noad', node.id'accent', node.id'style', node.id'choice' local radical_t, fraction_t, fence_t = node.id'radical', node.id'fraction', node.id'fence' @@ -17,18 +20,39 @@ local function sup_style(s) return s//4*2+4+s%2 end -- We ignore large_... since they aren't used for modern fonts local function delim_to_table(delim) if not delim then return end + local props = properties[delim] props = props and props.mathml_table + if props then return props end local fam = delim.small_fam - return {[0] = 'mo', utf8.char(delim.small_char), ['tex:family'] = fam ~= 0 and fam or nil } + return {[0] = 'mo', utf8.char(delim.small_char), ['tex:family'] = fam ~= 0 and fam or nil, stretchy = not stretchy[delim.small_char] or nil } +end + +-- Like kernel_to_table but always a math_char_t. Also creating a mo and potentially remapping to handle combining chars +local function acc_to_table(acc, cur_style, stretch) + if not acc then return end + local props = properties[acc] props = props and props.mathml_table + if props then return props end + if acc.id ~= math_char_t then + error'confusion' + end + local char = utf8.char(acc.char) + char = remap_comb[char] or char + local fam = acc.fam + if stretch ~= not stretchy[char] then -- Handle nil gracefully in stretchy + stretch = nil + end + return {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch} end local function kernel_to_table(kernel, cur_style) if not kernel then return end + local props = properties[kernel] props = props and props.mathml_table + if props then return props end local id = kernel.id if id == math_char_t then local char = kernel.char local elem = char >= 0x30 and char < 0x39 and 'mn' or 'mi' local fam = kernel.fam - return {[0] = elem, utf8.char(kernel.char), ['tex:family'] = fam ~= 0 and fam or nil, mathvariant = char < 0x10000 and 'normal' or nil } + return {[0] = elem, utf8.char(char), ['tex:family'] = fam ~= 0 and fam or nil, mathvariant = char < 0x10000 and 'normal' or nil } elseif id == sub_box_t then return {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} elseif id == sub_mlist_t then @@ -64,6 +88,7 @@ local function noad_to_table(noad, sub, cur_style) -- TODO else nucleus[0] = 'mo' + if stretchy[nucleus[1]] then nucleus.stretchy = false end if nucleus.mathvariant == 'normal' then nucleus.mathvariant = nil end end nucleus['tex:class'] = class @@ -98,24 +123,8 @@ end local function accent_to_table(accent, sub, cur_style) local nucleus = kernel_to_table(accent.nucleus, cur_style//2*2+1) - local top_acc = kernel_to_table(accent.accent, cur_style) - local bot_acc = kernel_to_table(accent.bot_accent, cur_style) - if top_acc then - top_acc[0] = 'mo' - if top_acc.mathvariant == 'normal' then top_acc.mathvariant = nil end - if sub & 1 == 1 then - top_acc.stretchy = 'false' - end - top_acc[1] = remap_comb[top_acc[1]] or top_acc[1] - end - if bot_acc then - bot_acc[0] = 'mo' - if bot_acc.mathvariant == 'normal' then bot_acc.mathvariant = nil end - if sub & 2 == 2 then - bot_acc.stretchy = 'false' - end - bot_acc[1] = remap_comb[bot_acc[1]] or bot_acc[1] - end + local top_acc = acc_to_table(accent.accent, cur_style, sub & 1 == 1) + local bot_acc = acc_to_table(accent.bot_accent, cur_style, sub & 2 == 2) return {[0] = top_acc and (bot_acc and 'munderover' or 'mover') or 'munder', nucleus, bot_acc or top_acc, @@ -145,7 +154,7 @@ local function radical_to_table(radical, sub, cur_style) elem = {[0] = 'msqrt', nucleus} elseif kind == 'uroot' then -- FIXME: Check that this is really a root - elem = {[0] = 'msqrt', nucleus, delim_to_table(radical.degree)} + elem = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree)} elseif kind == 'uunderdelimiter' then elem = {[0] = 'munder', left, nucleus} elseif kind == 'uoverdelimiter' then @@ -189,7 +198,6 @@ end local function fence_to_table(fence, sub, cur_style) local delim = delim_to_table(fence.delimiter) - delim.stretchy = 'true' delim.fence = 'true' return delim end @@ -198,7 +206,10 @@ function nodes_to_table(head, cur_style) local t = {[0] = "mrow"} local result = t for n, id, sub in node.traverse(head) do - if id == noad_t then + local props = properties[n] props = props and props.mathml_table + if props then + t[#t+1] = props + elseif id == noad_t then t[#t+1] = noad_to_table(n, sub, cur_style) elseif id == accent_t then t[#t+1] = accent_to_table(n, sub, cur_style)