From 623e9dbe4a7590e06e4fc27ab4ebdd89f6e5f5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Sat, 1 May 2021 02:44:50 +0200 Subject: [PATCH 1/5] Support rules --- luamml-convert.lua | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/luamml-convert.lua b/luamml-convert.lua index cd225e1..f824628 100644 --- a/luamml-convert.lua +++ b/luamml-convert.lua @@ -3,7 +3,7 @@ local stretchy = require'luamml-data-stretchy' local properties = node.get_properties_table() -local kern_t, glue_t = node.id'kern', node.id'glue' +local kern_t, glue_t, rule_t = 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' @@ -284,6 +284,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 +318,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 +397,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 From 81f0b867cd05985ffdb2d020872dfeadd6b0e2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Sat, 1 May 2021 07:57:03 +0200 Subject: [PATCH 2/5] Initial hbox handling --- luamml-convert.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/luamml-convert.lua b/luamml-convert.lua index f824628..58fc4f8 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_string = require'luamml-lr' local properties = node.get_properties_table() -local kern_t, glue_t, rule_t = node.id'kern', node.id'glue', node.id'rule' +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,16 @@ 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 str = to_string(kernel.list.head) + if str then + local result = {[0] = 'mtext', str} + return result, result + end + 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 +191,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 From 5f9d5222449c6fd329a914ee07f4b089955da24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Sat, 1 May 2021 08:00:29 +0200 Subject: [PATCH 3/5] Unify to_text usage --- luamml-amsmath.lua | 4 ++-- luamml-convert.lua | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/luamml-amsmath.lua b/luamml-amsmath.lua index b8ac0e3..6ee40e0 100644 --- a/luamml-amsmath.lua +++ b/luamml-amsmath.lua @@ -43,7 +43,7 @@ token.set_lua('__luamml_amsmath_save_tag:', funcid, 'protected') lua.get_functions_table()[funcid] = function() local nest = tex.nest.top local chars = {} - last_tag = to_text(nest.head) + last_tag = {[0] = 'mtext', to_text(nest.head)} end funcid = luatexbase.new_luafunction'__luamml_amsmath_set_tag:' @@ -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-convert.lua b/luamml-convert.lua index 58fc4f8..164b733 100644 --- a/luamml-convert.lua +++ b/luamml-convert.lua @@ -1,6 +1,6 @@ local remap_comb = require'luamml-data-combining' local stretchy = require'luamml-data-stretchy' -local to_string = require'luamml-lr' +local to_text = require'luamml-lr' local properties = node.get_properties_table() @@ -89,11 +89,8 @@ local function kernel_to_table(kernel, cur_style) return result, result elseif id == sub_box_t then if kernel.list.id == hlist_t then -- We directly give up for vlists - local str = to_string(kernel.list.head) - if str then - local result = {[0] = 'mtext', str} - return result, result - end + local result = {[0] = 'mtext', to_text(kernel.list.head)} + return result, result else local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} return result, result From 64d5adfb33b245325238ee7e773ab5726084e660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Sat, 1 May 2021 08:03:21 +0200 Subject: [PATCH 4/5] Adjust to_text interface --- luamml-amsmath.lua | 2 +- luamml-array.lua | 2 +- luamml-convert.lua | 2 +- luamml-lr.lua | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/luamml-amsmath.lua b/luamml-amsmath.lua index 6ee40e0..453b543 100644 --- a/luamml-amsmath.lua +++ b/luamml-amsmath.lua @@ -43,7 +43,7 @@ token.set_lua('__luamml_amsmath_save_tag:', funcid, 'protected') lua.get_functions_table()[funcid] = function() local nest = tex.nest.top local chars = {} - last_tag = {[0] = 'mtext', to_text(nest.head)} + last_tag = to_text(nest.head) end funcid = luatexbase.new_luafunction'__luamml_amsmath_set_tag:' 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 164b733..3518422 100644 --- a/luamml-convert.lua +++ b/luamml-convert.lua @@ -89,7 +89,7 @@ local function kernel_to_table(kernel, cur_style) return result, result elseif id == sub_box_t then if kernel.list.id == hlist_t then -- We directly give up for vlists - local result = {[0] = 'mtext', to_text(kernel.list.head)} + local result = to_text(kernel.list.head) return result, result else local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} diff --git a/luamml-lr.lua b/luamml-lr.lua index d4921d1..9e529fc 100644 --- a/luamml-lr.lua +++ b/luamml-lr.lua @@ -57,7 +57,7 @@ local function to_unicode(head, tail) end -- CHECK: Everything else can probably be ignored, otherwise shout at me end end - return table.concat(result) + return {[0] = 'mtext', table.concat(result)} end return to_unicode From 912173cab11414b65f9c76937ddefb8eb00b02a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Sat, 1 May 2021 08:27:52 +0200 Subject: [PATCH 5/5] Allow more hbox material --- luamml-lr.lua | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/luamml-lr.lua b/luamml-lr.lua index 9e529fc..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 {[0] = 'mtext', 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