diff options
Diffstat (limited to 'macros/luatex/latex/luamml/luamml-structelemwriter.lua')
-rw-r--r-- | macros/luatex/latex/luamml/luamml-structelemwriter.lua | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/macros/luatex/latex/luamml/luamml-structelemwriter.lua b/macros/luatex/latex/luamml/luamml-structelemwriter.lua new file mode 100644 index 0000000000..eb266a1e9f --- /dev/null +++ b/macros/luatex/latex/luamml/luamml-structelemwriter.lua @@ -0,0 +1,105 @@ +local struct_begin = token.create'tag_struct_begin:n' +local struct_use = token.create'tag_struct_use: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 = luatexbase.attributes.g__tag_mc_type_attr +local mc_cnt = luatexbase.attributes.g__tag_mc_cnt_attr +-- print('!!!', mc_type, mc_cnt) + +local stash_cnt = 0 +local attrs = {} +local function write_elem(tree, stash) + if tree[':struct'] then + return tex.runtoks(function() + return tex.sprint(struct_use, '{', tree[':struct'], '}') + end) + end + 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) + + if stash then + stash_cnt = stash_cnt + 1 + stash = '__luamml_stashed_' .. stash_cnt + tree[':struct'] = stash + stash = ', stash, label = ' .. stash + end + + local attr_flag = i ~= 0 and ', attribute=' .. attributes[table.concat(attrs)] + tex.sprint(struct_begin, '{tag=' .. tree[0] .. '/mathml') + if stash then tex.sprint(stash) end + if attr_flag then tex.sprint(attr_flag) end + if tree[':actual'] then + tex.sprint(', actualtext = {') + tex.cprint(12, tree[':actual']) + tex.sprint'}' + end + tex.sprint'}' + for j = 1, i do attrs[j] = nil end + + 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) + 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) + 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, stash) + return write_elem(element, stash) +end |