First attempt at generating structure elements
This commit is contained in:
parent
98fd0a477a
commit
c4c2b701b5
@ -129,7 +129,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 }
|
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 }
|
||||||
return result, result
|
return result, result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -149,7 +149,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
|
||||||
return {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch}
|
return {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch, [':node'] = acc}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function kernel_to_table(kernel, cur_style)
|
local function kernel_to_table(kernel, cur_style)
|
||||||
@ -164,7 +164,8 @@ local function kernel_to_table(kernel, cur_style)
|
|||||||
local result = {[0] = elem,
|
local result = {[0] = elem,
|
||||||
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,
|
||||||
}
|
}
|
||||||
return result, result
|
return result, result
|
||||||
elseif id == sub_box_t then
|
elseif id == sub_box_t then
|
||||||
@ -172,7 +173,7 @@ local function kernel_to_table(kernel, cur_style)
|
|||||||
local result = to_text(kernel.list.head)
|
local result = to_text(kernel.list.head)
|
||||||
return result, result
|
return result, result
|
||||||
else
|
else
|
||||||
local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}}
|
local result = {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list, [':node'] = kernel}}
|
||||||
return result, result
|
return result, result
|
||||||
end
|
end
|
||||||
elseif id == sub_mlist_t then
|
elseif id == sub_mlist_t then
|
||||||
@ -305,7 +306,7 @@ local function radical_to_table(radical, sub, cur_style)
|
|||||||
local elem
|
local elem
|
||||||
if kind == 'radical' or kind == 'uradical' then
|
if kind == 'radical' or kind == 'uradical' then
|
||||||
-- FIXME: Check that this is really a square root
|
-- FIXME: Check that this is really a square root
|
||||||
elem, core = {[0] = 'msqrt', nucleus}, nil
|
elem, core = {[0] = 'msqrt', nucleus, [':node'] = left[':node'], }, nil
|
||||||
elseif kind == 'uroot' then
|
elseif kind == 'uroot' then
|
||||||
-- FIXME: Check that this is really a root
|
-- FIXME: Check that this is really a root
|
||||||
elem, core = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree)}, nil
|
elem, core = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree)}, nil
|
||||||
@ -331,6 +332,7 @@ local function fraction_to_table(fraction, sub, cur_style)
|
|||||||
local mfrac = {[0] = 'mfrac',
|
local mfrac = {[0] = 'mfrac',
|
||||||
linethickness = fraction.width and fraction.width == 0 and 0 or nil,
|
linethickness = fraction.width and fraction.width == 0 and 0 or nil,
|
||||||
bevelled = fraction.middle and "true" or nil,
|
bevelled = fraction.middle and "true" or nil,
|
||||||
|
[':node'] = fraction,
|
||||||
num,
|
num,
|
||||||
denom,
|
denom,
|
||||||
}
|
}
|
||||||
|
83
luamml-structelemwriter.lua
Normal file
83
luamml-structelemwriter.lua
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
local struct_begin = token.create'tag_struct_begin:n'
|
||||||
|
local struct_end = token.create'tag_struct_end:'
|
||||||
|
|
||||||
|
local mc_begin = token.create'tag_mc_begin:n'
|
||||||
|
local mc_end = token.create'tag_mc_end:'
|
||||||
|
|
||||||
|
local function escape_name(name)
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
local function escape_string(str)
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
local mathml_ns_obj
|
||||||
|
local function get_mathml_ns_obj()
|
||||||
|
mathml_ns_obj = mathml_ns_obj or token.create'c__pdf_backend_object_tag/NS/mathml_int'.index
|
||||||
|
return mathml_ns_obj
|
||||||
|
end
|
||||||
|
|
||||||
|
local attribute_counter = 0
|
||||||
|
local attributes = setmetatable({}, {__index = function(t, k)
|
||||||
|
attribute_counter = attribute_counter + 1
|
||||||
|
local attr_name = string.format('luamml_attr_%i', attribute_counter)
|
||||||
|
t[k] = attr_name
|
||||||
|
tex.runtoks(function()
|
||||||
|
-- tex.sprint(string.format('\\tagpdfsetup{newattribute={%s}{/O/NSO/NS %i 0 R',
|
||||||
|
-- attr_name, mathml_ns_obj or get_mathml_ns_obj()))
|
||||||
|
tex.sprint(string.format('\\tagpdfsetup{newattribute={%s}{/O/MathML-3',
|
||||||
|
attr_name))
|
||||||
|
tex.cprint(12, k)
|
||||||
|
tex.sprint'}}'
|
||||||
|
end)
|
||||||
|
return attr_name
|
||||||
|
end})
|
||||||
|
|
||||||
|
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 attrs = {}
|
||||||
|
local function write_elem(tree, indent)
|
||||||
|
if not tree[0] then print('ERR', require'inspect'(tree)) end
|
||||||
|
local i = 0
|
||||||
|
for attr, val in next, tree do if type(attr) == 'string' and not string.find(attr, ':') and attr ~= 'xmlns' then
|
||||||
|
-- for attr, val in next, tree do if type(attr) == 'string' and string.byte(attr) ~= 0x3A then
|
||||||
|
i = i + 1
|
||||||
|
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, string.format('{tag=%s/mathml}', tree[0])}
|
||||||
|
else
|
||||||
|
tex.sprint{struct_begin, string.format('{tag=%s/mathml,attribute=%s}', tree[0], attributes[table.concat(attrs)])}
|
||||||
|
end
|
||||||
|
for j = 1, i do attrs[j] = nil end
|
||||||
|
|
||||||
|
if tree[':node'] then
|
||||||
|
local n = tree[':node']
|
||||||
|
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])
|
||||||
|
tex.runtoks(function()
|
||||||
|
tex.sprint(mc_end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
for _, elem in ipairs(tree) do
|
||||||
|
if type(elem) ~= 'string' then
|
||||||
|
write_elem(elem)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tex.runtoks(function()
|
||||||
|
tex.sprint(struct_end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(element)
|
||||||
|
return write_elem(element)
|
||||||
|
end
|
@ -5,6 +5,7 @@ local register_family = mlist_to_mml.register_family
|
|||||||
|
|
||||||
local mappings = require'luamml-legacy-mappings'
|
local mappings = require'luamml-legacy-mappings'
|
||||||
local write_xml = require'luamml-xmlwriter'
|
local write_xml = require'luamml-xmlwriter'
|
||||||
|
local write_struct = require'luamml-structelemwriter'
|
||||||
|
|
||||||
local properties = node.get_properties_table()
|
local properties = node.get_properties_table()
|
||||||
|
|
||||||
@ -67,6 +68,9 @@ luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style)
|
|||||||
if flag & 2 == 0 then
|
if flag & 2 == 0 then
|
||||||
save_result(xml, style == 'display' or flag & 1 == 1)
|
save_result(xml, style == 'display' or flag & 1 == 1)
|
||||||
end
|
end
|
||||||
|
if flag & 8 == 8 then
|
||||||
|
write_struct(make_root(mlist_result, mlist_display and 0 or 2))
|
||||||
|
end
|
||||||
if style == 'text' then
|
if style == 'text' then
|
||||||
local startmath = tex.nest.top.tail
|
local startmath = tex.nest.top.tail
|
||||||
local props = properties[startmath]
|
local props = properties[startmath]
|
||||||
|
@ -18,7 +18,7 @@ local function write_elem(tree, indent)
|
|||||||
if not tree[0] then print('ERR', require'inspect'(tree)) end
|
if not tree[0] then print('ERR', require'inspect'(tree)) end
|
||||||
local escaped_name = escape_name(assert(tree[0]))
|
local escaped_name = escape_name(assert(tree[0]))
|
||||||
local i = 0
|
local i = 0
|
||||||
for attr, val in next, tree do if type(attr) == 'string' then
|
for attr, val in next, tree do if type(attr) == 'string' and string.byte(attr) ~= 0x3A then
|
||||||
i = i + 1
|
i = i + 1
|
||||||
attrs[i] = string.format(' %s="%s"', escape_name(attr), escape_text(val))
|
attrs[i] = string.format(' %s="%s"', escape_name(attr), escape_text(val))
|
||||||
end end
|
end end
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
\cs_new:Nn \luamml_flag_alignment_right: {
|
\cs_new:Nn \luamml_flag_alignment_right: {
|
||||||
\int_set:Nn \l__luamml_flag_int { 6 }
|
\int_set:Nn \l__luamml_flag_int { 6 }
|
||||||
}
|
}
|
||||||
|
\cs_new:Nn \luamml_flag_structelem: {
|
||||||
|
\int_set:Nn \l__luamml_flag_int { 8 }
|
||||||
|
}
|
||||||
|
|
||||||
\cs_new:Npn \__luamml_patch_package:nn #1 #2 {
|
\cs_new:Npn \__luamml_patch_package:nn #1 #2 {
|
||||||
\@ifpackageloaded {#1} {#2} {
|
\@ifpackageloaded {#1} {#2} {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
2 & $else$
|
2 & $else$
|
||||||
\end{cases}
|
\end{cases}
|
||||||
\]
|
\]
|
||||||
|
\ShowMathMLObj
|
||||||
\[
|
\[
|
||||||
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
|
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
|
||||||
\]
|
\]
|
||||||
|
Loading…
Reference in New Issue
Block a user