Much better structelem support

This commit is contained in:
Marcel Fabian Krüger 2021-06-23 14:35:43 +02:00
parent 3a8dcdebe8
commit 75c92b1ff5
5 changed files with 63 additions and 26 deletions

View File

@ -89,6 +89,7 @@ lua.get_functions_table()[funcid] = function()
local columns = node.count(node.id'align_record', tex.lists.align_head)//2 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.columnalign = kind == 'align' and string.rep('right left', columns, ' ') or nil
mml_table.width = kind == 'multline' and '100%' or nil mml_table.width = kind == 'multline' and '100%' or nil
-- mml_table.side = kind == 'multline' and 'rightoverlap' or nil
local spacing = {} local spacing = {}
for n in node.traverse_id(node.id'glue', tex.lists.align_head) do for n in node.traverse_id(node.id'glue', tex.lists.align_head) do
spacing[#spacing+1] = n.width == 0 and '0' or '.8em' spacing[#spacing+1] = n.width == 0 and '0' or '.8em'

View File

@ -139,7 +139,7 @@ local function delim_to_table(delim)
else else
local fam = delim.small_fam local fam = delim.small_fam
char = remap_lookup[fam << 21 | char] 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 if mathml_filter then
return mathml_filter(result, result) return mathml_filter(result, result)
else 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 if stretch ~= not stretchy[char] then -- Handle nil gracefully in stretchy
stretch = nil stretch = nil
end 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 if mathml_filter then
return mathml_filter(result) return mathml_filter(result)
else else
@ -190,7 +190,7 @@ local function kernel_to_table(kernel, cur_style)
char, char,
['tex:family'] = fam ~= 0 and fam or nil, ['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, 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 if mathml_filter then
return mathml_filter(result, result) 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 if kernel.list.id == hlist_t then -- We directly give up for vlists
result = to_text(kernel.list.head) result = to_text(kernel.list.head)
else else
result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list, [':node'] = kernel}} result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list, [':nodes'] = {kernel}}}
end end
if mathml_filter then if mathml_filter then
return mathml_filter(result, result) 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 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 if joining and core[0] == joining[0] and core['tex:family'] == joining['tex:family'] then
joining[#joining+1] = core[1] 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) nucleus = do_sub_sup(joining, joining, noad, cur_style)
if nucleus == joining then if nucleus == joining then
return nil, joining, joining return nil, joining, joining

View File

@ -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 local mc_cnt = token.create'l__tag_mc_cnt_attr'.index
-- print('!!!', mc_type, mc_cnt) -- print('!!!', mc_type, mc_cnt)
local stash_cnt = 0
local attrs = {} local attrs = {}
local function write_elem(tree, indent) local function write_elem(tree, stash)
if tree[':struct'] then if tree[':struct'] then
return tex.runtoks(function() return tex.runtoks(function()
return tex.sprint(struct_use, '{', tree[':struct'], '}') 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)) attrs[i] = string.format('/%s(%s)', escape_name(attr), escape_string(val))
end end end end
table.sort(attrs) table.sort(attrs)
local attr_name
if i == 0 then if stash then
tex.sprint(struct_begin, '{tag=', tree[0], '/mathml}') stash_cnt = stash_cnt + 1
stash = '__luamml_stashed_' .. stash_cnt
tree[':struct'] = stash
stash = ', stash, label = ' .. stash
else 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 end
for j = 1, i do attrs[j] = nil end for j = 1, i do attrs[j] = nil end
if tree[':node'] then if tree[':nodes'] then
local n = tree[':node'] local n = tree[':nodes']
tex.runtoks(function() tex.runtoks(function()
tex.sprint{mc_begin, string.format('{tag=%s}', tree[0])} 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. -- NOTE: This will also flush all previous sprint's... That's often annoying, but in this case actually intentional.
end) end)
node.set_attribute(tree[':node'], mc_type, tex.attribute[mc_type]) local mct, mcc = tex.attribute[mc_type], tex.attribute[mc_cnt]
node.set_attribute(tree[':node'], mc_cnt, 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.runtoks(function()
tex.sprint(mc_end) tex.sprint(mc_end)
end) end)
@ -84,6 +97,6 @@ local function write_elem(tree, indent)
end) end)
end end
return function(element) return function(element, stash)
return write_elem(element) return write_elem(element, stash)
end end

View File

@ -83,6 +83,9 @@ local function save_result(xml, display, structelem)
if tracing then if tracing then
texio.write_nl(write_xml(mlist_result) .. '\n') texio.write_nl(write_xml(mlist_result) .. '\n')
end end
if tex.count.l__luamml_flag_int & 8 == 8 then
write_struct(mlist_result)
end
return mlist_result return mlist_result
end end
@ -95,11 +98,11 @@ luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style)
return true return true
end end
local display = style == 'display' 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 style = flag & 4 == 4 and flag>>5 & 0x7 or display and 0 or 2
local xml, core = process_mlist(mlist, style) local xml, core = process_mlist(mlist, style)
local processed_xml
if flag & 2 == 2 then if flag & 2 == 2 then
processed_xml = save_result(shallow_copy(xml), display) save_result(shallow_copy(xml), display)
else else
local element_type = token.get_macro'l__luamml_root_tl' local element_type = token.get_macro'l__luamml_root_tl'
if element_type ~= 'mrow' then 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} xml = {[0] = element_type, xml}
end end
end end
processed_xml = xml
end end
if not display and flag & 1 == 1 then if not display and flag & 1 == 1 then
local startmath = tex.nest.top.tail
local props = properties[startmath] local props = properties[startmath]
if not props then if not props then
props = {} props = {}
properties[startmath] = props properties[startmath] = props
end end
props.saved_mathml_table, props.saved_mathml_core = xml, core props.saved_mathml_table, props.saved_mathml_core = xml, core
end if flag & 10 == 8 then
if flag & 8 == 8 then write_struct(xml, true) -- This modifies xml in-place to reference the struture element
write_struct(shallow_copy(processed_xml), display and 0 or 2) end
end end
return true return true
end, 'dump_list') end, 'dump_list')

View File

@ -102,6 +102,19 @@
% \end{macrocode} % \end{macrocode}
% \end{macro} % \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:, % \begin{macro}{\luamml_flag_save:,
% \luamml_flag_save:N, % \luamml_flag_save:N,
% \luamml_flag_save:n, % \luamml_flag_save:n,
@ -118,17 +131,17 @@
% cases. % cases.
% \begin{macrocode} % \begin{macrocode}
\cs_new_protected:Npn \luamml_flag_save: { \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 { \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 { \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 \tl_set:Nn \l__luamml_root_tl
} }
\cs_new_protected:Npn \luamml_flag_save:Nn #1 { \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 \tl_set:Nn \l__luamml_root_tl
} }
% \end{macrocode} % \end{macrocode}