diff --git a/luamml-amsmath.lua b/luamml-amsmath.lua index b8ac0e3..453b543 100644 --- a/luamml-amsmath.lua +++ b/luamml-amsmath.lua @@ -53,6 +53,6 @@ lua.get_functions_table()[funcid] = function() texio.write_nl'WARNING: Tag extraction failed' return end - store_tag({[0] = 'mtd', {[0] = 'mtext', last_tag}}) + store_tag({[0] = 'mtd', last_tag}) last_tag = nil end diff --git a/luamml-array.lua b/luamml-array.lua index d946a8b..61c6097 100644 --- a/luamml-array.lua +++ b/luamml-array.lua @@ -48,7 +48,7 @@ lua.get_functions_table()[funcid] = function() else -- Oh no, we got text. Let't complain to the user, it's probably their fault print'We are mathematicians, don\'t bother us with text' - store_column_xml{[0] = 'mtext', to_text(startmath, tex.nest.top.tail)} + store_column_xml(to_text(startmath, tex.nest.top.tail)) end end diff --git a/luamml-convert.lua b/luamml-convert.lua index cd225e1..3518422 100644 --- a/luamml-convert.lua +++ b/luamml-convert.lua @@ -1,9 +1,10 @@ local remap_comb = require'luamml-data-combining' local stretchy = require'luamml-data-stretchy' +local to_text = require'luamml-lr' local properties = node.get_properties_table() -local kern_t, glue_t = node.id'kern', node.id'glue' +local hlist_t, kern_t, glue_t, rule_t = node.id'hlist', node.id'kern', node.id'glue', node.id'rule' 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' @@ -87,8 +88,13 @@ local function kernel_to_table(kernel, cur_style) } return result, result elseif id == sub_box_t then - local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} - return result, result + if kernel.list.id == hlist_t then -- We directly give up for vlists + local result = to_text(kernel.list.head) + return result, result + else + local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} + return result, result + end elseif id == sub_mlist_t then return nodes_to_table(kernel.list, cur_style) else @@ -182,8 +188,7 @@ local function noad_to_table(noad, sub, cur_style, mn) nucleus, {[0] = 'mo', '\u{203E}',}, }, core - elseif class == 'vcenter' then - nucleus['tex:TODO'] = class + elseif class == 'vcenter' then -- Ignored. Nucleus will need special handling anyway else error[[confusion]] end @@ -284,6 +289,24 @@ local function space_to_table(amount, sub, cur_style) end end +local running_length = -1073741824 +local function rule_to_table(rule, sub, cur_style) + local width = string.format("%.3fpt", rule.width/65781.76) + local height = rule.height + if height == running_length then + height = '0.8em' + else + height = height + end + local depth = rule.depth + if depth == running_length then + depth = '0.2em' + else + depth = depth + end + return {[0] = 'mspace', mathbackground = 'currentColor', width = width, height = height, depth = depth}, space_like +end + function nodes_to_table(head, cur_style) local t = {[0] = 'mrow'} local result = t @@ -300,7 +323,8 @@ function nodes_to_table(head, cur_style) and 'normal' or nil end local new_core, new_mn - local props = properties[n] props = props and props.mathml_table + local props = properties[n] + props = props and props.mathml_table if props then t[#t+1], new_core = props, user_provided elseif id == noad_t then @@ -378,10 +402,10 @@ function nodes_to_table(head, cur_style) t[#t+1], new_core = space_to_table(n.width, sub, cur_style) end end - else - new_core = {[0] = 'tex:TODO', other = n} - t[#t+1] = new_core - end + elseif id == rule_t then + t[#t+1], new_core = rule_to_table(n, sub, cur_style) + -- elseif id == disc_t then -- Uncommon, does not play nicely with math mode and no sensible mapping anyway + end -- The other possible ids are whatsit, penalty, adjust, ins, mark. Ignore them. nonscript = nil if core and new_core ~= space_like then core = core == space_like and new_core or nil diff --git a/luamml-lr.lua b/luamml-lr.lua index d4921d1..2c5d9c0 100644 --- a/luamml-lr.lua +++ b/luamml-lr.lua @@ -1,7 +1,7 @@ local properties = node.get_properties_table() local function to_unicode(head, tail) - local result, i = {}, 0 + local result, subresult, i = {[0] = 'mrow'}, {}, 0 local characters, last_fid local iter, state, n = node.traverse(head) while true do @@ -10,7 +10,7 @@ local function to_unicode(head, tail) local props = properties[n] if props and props.glyph_info then i = i+1 - result[i] = glyph_info + subresult[i] = glyph_info else local char, fid = node.is_glyph(n) if char then @@ -23,15 +23,15 @@ local function to_unicode(head, tail) i = i+1 if uni then if type(uni) == 'number' then - result[i] = utf.char(uni) + subresult[i] = utf.char(uni) else - result[i] = utf.char(table.unpack(uni)) + subresult[i] = utf.char(table.unpack(uni)) end else if char < 0x110000 then - result[i] = utf.char(char) + subresult[i] = utf.char(char) else - result[i] = '\u{FFFD}' + subresult[i] = '\u{FFFD}' end end -- elseif node.id'math' == id then @@ -41,23 +41,47 @@ local function to_unicode(head, tail) elseif node.id'glue' == id then if n.width > 1000 then -- FIXME: Coordinate constant with tagpdf i = i+1 - result[i] = ' ' + subresult[i] = ' ' end elseif node.id'hlist' == id then - i = i+1 - result[i] = '\u{FFFD}' + local nested = to_unicode(n.head) + if nested[0] == 'mtext' and #nested == 1 and type(nested[1]) == 'string' then + i=i+1 + subresult[i] = nested[1] + else + if i ~= 0 then + i = 0 + result[#result+1] = {[0] = 'mtext', table.concat(subresult)} + end + if nested[0] == 'mrow' then + table.move(nested, 1, #nested, #result+1, result) + else -- should be unreachable + result[#result+1] = nested + end + end elseif node.id'vlist' == id then i = i+1 - result[i] = '\u{FFFD}' + subresult[i] = '\u{FFFD}' elseif node.id'rule' == id then if n.width ~= 0 then i = i+1 - result[i] = '\u{FFFD}' + subresult[i] = '\u{FFFD}' end end -- CHECK: Everything else can probably be ignored, otherwise shout at me end end - return table.concat(result) + if i ~= 0 then + i = 0 + result[#result+1] = {[0] = 'mtext', table.concat(subresult)} + end + if #result == 0 then + local r = {[0] = 'mtext', ''} + return r, r + elseif #result == 1 then + result = result[1] + if result[1] == 'mtext' then return result, result end + end + return result end return to_unicode