diff --git a/luamml-amsmath.lua b/luamml-amsmath.lua index 32b4d79..1175481 100644 --- a/luamml-amsmath.lua +++ b/luamml-amsmath.lua @@ -89,6 +89,7 @@ lua.get_functions_table()[funcid] = function() local columns = node.count(node.id'align_record', tex.lists.align_head)//2 mml_table.columnalign = kind == 'align' and string.rep('right left', columns, ' ') or nil mml_table.width = kind == 'multline' and '100%' or nil + -- mml_table.side = kind == 'multline' and 'rightoverlap' or nil local spacing = {} for n in node.traverse_id(node.id'glue', tex.lists.align_head) do spacing[#spacing+1] = n.width == 0 and '0' or '.8em' diff --git a/luamml-convert.lua b/luamml-convert.lua index 1af5e24..1cbcd6b 100644 --- a/luamml-convert.lua +++ b/luamml-convert.lua @@ -139,7 +139,7 @@ local function delim_to_table(delim) else local fam = delim.small_fam char = remap_lookup[fam << 21 | char] - local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = not stretchy[char] or nil, lspace = 0, rspace = 0, [':node'] = delim } + local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = not stretchy[char] or nil, lspace = 0, rspace = 0, [':nodes'] = {delim} } if mathml_filter then return mathml_filter(result, result) else @@ -166,7 +166,7 @@ local function acc_to_table(acc, cur_style, stretch) if stretch ~= not stretchy[char] then -- Handle nil gracefully in stretchy stretch = nil end - local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch, [':node'] = acc} + local result = {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch, [':nodes'] = {acc}} if mathml_filter then return mathml_filter(result) else @@ -190,7 +190,7 @@ local function kernel_to_table(kernel, cur_style) char, ['tex:family'] = fam ~= 0 and fam or nil, mathvariant = utf8.len(char) == 1 and elem == 'mi' and utf8.codepoint(char) < 0x10000 and 'normal' or nil, - [':node'] = kernel, + [':nodes'] = {kernel}, } if mathml_filter then return mathml_filter(result, result) @@ -202,7 +202,7 @@ local function kernel_to_table(kernel, cur_style) if kernel.list.id == hlist_t then -- We directly give up for vlists result = to_text(kernel.list.head) else - result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list, [':node'] = kernel}} + result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list, [':nodes'] = {kernel}}} end if mathml_filter then return mathml_filter(result, result) @@ -272,6 +272,15 @@ local function noad_to_table(noad, sub, cur_style, joining) or core[0] == 'mn' or text_families[core['tex:family']] then if joining and core[0] == joining[0] and core['tex:family'] == joining['tex:family'] then joining[#joining+1] = core[1] + local cnodes = core[':nodes'] + if cnodes then -- very likely + local jnodes = joining[':nodes'] + if jnodes then -- very likely + table.move(cnodes, 1, #cnodes, #jnodes+1, jnodes) + else + joining[':nodes'] = cnodes + end + end nucleus = do_sub_sup(joining, joining, noad, cur_style) if nucleus == joining then return nil, joining, joining diff --git a/luamml-structelemwriter.lua b/luamml-structelemwriter.lua index 56f99d3..8b766bd 100644 --- a/luamml-structelemwriter.lua +++ b/luamml-structelemwriter.lua @@ -39,8 +39,9 @@ local mc_type = token.create'l__tag_mc_type_attr'.index local mc_cnt = token.create'l__tag_mc_cnt_attr'.index -- print('!!!', mc_type, mc_cnt) +local stash_cnt = 0 local attrs = {} -local function write_elem(tree, indent) +local function write_elem(tree, stash) if tree[':struct'] then return tex.runtoks(function() return tex.sprint(struct_use, '{', tree[':struct'], '}') @@ -54,22 +55,34 @@ local function write_elem(tree, indent) attrs[i] = string.format('/%s(%s)', escape_name(attr), escape_string(val)) end end table.sort(attrs) - local attr_name - if i == 0 then - tex.sprint(struct_begin, '{tag=', tree[0], '/mathml}') + + if stash then + stash_cnt = stash_cnt + 1 + stash = '__luamml_stashed_' .. stash_cnt + tree[':struct'] = stash + stash = ', stash, label = ' .. stash else - tex.sprint(struct_begin, '{tag=', tree[0], '/mathml,attribute=', attributes[table.concat(attrs)], '}') + stash = '' + end + + if i == 0 then + tex.sprint(struct_begin, '{tag=' .. tree[0] .. '/mathml' .. stash .. '}') + else + tex.sprint(struct_begin, '{tag=' .. tree[0] .. '/mathml, attribute=' .. attributes[table.concat(attrs)] .. stash .. '}') end for j = 1, i do attrs[j] = nil end - if tree[':node'] then - local n = tree[':node'] + if tree[':nodes'] then + local n = tree[':nodes'] tex.runtoks(function() tex.sprint{mc_begin, string.format('{tag=%s}', tree[0])} -- NOTE: This will also flush all previous sprint's... That's often annoying, but in this case actually intentional. end) - node.set_attribute(tree[':node'], mc_type, tex.attribute[mc_type]) - node.set_attribute(tree[':node'], mc_cnt, tex.attribute[mc_cnt]) + local mct, mcc = tex.attribute[mc_type], tex.attribute[mc_cnt] + for i = 1, #n do + node.set_attribute(n[i], mc_type, mct) + node.set_attribute(n[i], mc_cnt, mcc) + end tex.runtoks(function() tex.sprint(mc_end) end) @@ -84,6 +97,6 @@ local function write_elem(tree, indent) end) end -return function(element) - return write_elem(element) +return function(element, stash) + return write_elem(element, stash) end diff --git a/luamml-tex.lua b/luamml-tex.lua index 2581a7c..46535d6 100644 --- a/luamml-tex.lua +++ b/luamml-tex.lua @@ -83,6 +83,9 @@ local function save_result(xml, display, structelem) if tracing then texio.write_nl(write_xml(mlist_result) .. '\n') end + if tex.count.l__luamml_flag_int & 8 == 8 then + write_struct(mlist_result) + end return mlist_result end @@ -95,11 +98,11 @@ luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style) return true end local display = style == 'display' + local startmath = tex.nest.top.tail -- Must come before any write_struct calls which adds nodes style = flag & 4 == 4 and flag>>5 & 0x7 or display and 0 or 2 local xml, core = process_mlist(mlist, style) - local processed_xml if flag & 2 == 2 then - processed_xml = save_result(shallow_copy(xml), display) + save_result(shallow_copy(xml), display) else local element_type = token.get_macro'l__luamml_root_tl' if element_type ~= 'mrow' then @@ -109,19 +112,17 @@ luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style) xml = {[0] = element_type, xml} end end - processed_xml = xml end if not display and flag & 1 == 1 then - local startmath = tex.nest.top.tail local props = properties[startmath] if not props then props = {} properties[startmath] = props end props.saved_mathml_table, props.saved_mathml_core = xml, core - end - if flag & 8 == 8 then - write_struct(shallow_copy(processed_xml), display and 0 or 2) + if flag & 10 == 8 then + write_struct(xml, true) -- This modifies xml in-place to reference the struture element + end end return true end, 'dump_list') diff --git a/luamml.dtx b/luamml.dtx index 268b6a7..520f033 100644 --- a/luamml.dtx +++ b/luamml.dtx @@ -102,6 +102,19 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\__luamml_maybe_structelem:} +% A internal helper which can be added to a tag to preserve the external state +% of the structelem flag. +% \begin{macrocode} +\cs_new:Npn \__luamml_maybe_structelem: { + ( + 8 * \int_mod:nn { + \int_div_truncate:nn { \l__luamml_flag_int } {8} + } {2} + ) + +} +% \end{macro} +% % \begin{macro}{\luamml_flag_save:, % \luamml_flag_save:N, % \luamml_flag_save:n, @@ -118,17 +131,17 @@ % cases. % \begin{macrocode} \cs_new_protected:Npn \luamml_flag_save: { - \int_set:Nn \l__luamml_flag_int { 1 } + \int_set:Nn \l__luamml_flag_int { \__luamml_maybe_structelem: 1 } } \cs_new_protected:Npn \luamml_flag_save:N #1 { - \int_set:Nn \l__luamml_flag_int { 17 + 32 * #1 } + \int_set:Nn \l__luamml_flag_int { \__luamml_maybe_structelem: 17 + 32 * #1 } } \cs_new_protected:Npn \luamml_flag_save:n { - \int_set:Nn \l__luamml_flag_int { 5 } + \int_set:Nn \l__luamml_flag_int { \__luamml_maybe_structelem: 5 } \tl_set:Nn \l__luamml_root_tl } \cs_new_protected:Npn \luamml_flag_save:Nn #1 { - \int_set:Nn \l__luamml_flag_int { 21 + 32 * #1 } + \int_set:Nn \l__luamml_flag_int { \__luamml_maybe_structelem: 21 + 32 * #1 } \tl_set:Nn \l__luamml_root_tl } % \end{macrocode}