diff options
author | Norbert Preining <norbert@preining.info> | 2021-03-20 03:01:11 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2021-03-20 03:01:11 +0000 |
commit | d3b06b2254431c03e127876a07ae654091314c72 (patch) | |
tree | 4fa5e40c55aae3ceeeab0048fabbb778ee06e284 /support/make4ht/domfilters | |
parent | 6ad1cf68ae6add67e56faf5ec4390fead04e31b4 (diff) |
CTAN sync 202103200301
Diffstat (limited to 'support/make4ht/domfilters')
-rw-r--r-- | support/make4ht/domfilters/make4ht-joincharacters.lua | 16 | ||||
-rw-r--r-- | support/make4ht/domfilters/make4ht-mathmlfixes.lua | 67 |
2 files changed, 81 insertions, 2 deletions
diff --git a/support/make4ht/domfilters/make4ht-joincharacters.lua b/support/make4ht/domfilters/make4ht-joincharacters.lua index 4493aef023..34737f921a 100644 --- a/support/make4ht/domfilters/make4ht-joincharacters.lua +++ b/support/make4ht/domfilters/make4ht-joincharacters.lua @@ -56,6 +56,18 @@ local function join_characters(obj,par) local is_span = function(next_el) return charclasses[get_name(next_el)] end + local has_children = function(curr) + -- don't process spans that have child elements + local children = curr:get_children() or {} + -- if there is more than one child, we can be sure that it has child elements + if #children > 1 then + return true + elseif #children == 1 then + -- test if the child is an element + return children[1]:is_element() + end + return false + end local join_elements = function(el, next_el) -- it the following element match, copy it's children to the current element for _, child in ipairs(next_el:get_children()) do @@ -79,8 +91,8 @@ local function join_characters(obj,par) obj:traverse_elements(function(el) -- loop over all elements and test if the current element is in a list of - -- processed elements (charclasses) - if is_span(el) then + -- processed elements (charclasses) and if it doesn't contain children + if is_span(el) and not has_children(el) then local next_el = get_next(el) -- loop over the following elements and test whether they are of the same type -- as the current one diff --git a/support/make4ht/domfilters/make4ht-mathmlfixes.lua b/support/make4ht/domfilters/make4ht-mathmlfixes.lua index 3e044b9445..55c0da379b 100644 --- a/support/make4ht/domfilters/make4ht-mathmlfixes.lua +++ b/support/make4ht/domfilters/make4ht-mathmlfixes.lua @@ -37,8 +37,75 @@ local function fix_nested_mstyle(el) end end +local function get_fence(el, attr, form) + -- convert fence attribute to <mo> element + -- attr: open | close + -- form: prefix | postfix + local char = el:get_attribute(attr) + local mo + if char then + mo = el:create_element("mo", {fence="true", form = form}) + mo:add_child_node(mo:create_text_node(char)) + end + return mo +end + + +local function fix_mfenced(el) + -- TeX4ht uses in some cases <mfenced> element which is deprecated in MathML. + -- Firefox doesn't support it already. + if el:get_element_name() == "mfenced" then + -- we must replace it by <mrow><mo>start</mo><mfenced children...><mo>end</mo></mrow> + local open = get_fence(el, "open", "prefix") + local close = get_fence(el, "close", "postfix") + -- there can be also separator attribute, but it is not used in TeX4ht + -- change <mfenced> to <mrow> and remove all attributes + el._name = "mrow" + el._attr = {} + -- open must be first child, close needs to be last + if open then el:add_child_node(open, 1) end + if close then el:add_child_node(close) end + end +end + +local function is_fence(el) + return el:get_element_name() == "mo" and el:get_attribute("fence") == "true" +end + +local function fix_mo_to_mfenced(el) + -- LibreOffice NEEDS <mfenced> element. so we need to convert <mrow><mo fence="true"> + -- to <mfenced>. ouch. + if is_fence(el) then + local parent = el:get_parent() + local open = el:get_text():gsub("%s*", "") -- convert mo content to text, so it can be used in + -- close needs to be the last element in the sibling list of the current element + local siblings = el:get_siblings() + el:remove_node() -- we don't need this element anymore + local close + for i = #siblings, 1, -1 do + last = siblings[i] + if last:is_element() then + if is_fence(last) then -- set close attribute only if the last element is fence + close = last:get_text():gsub("%s*", "") + last:remove_node() -- remove <mo> + end + break -- break looping over elements once we find last element + end + end + -- convert parent <mrow> to <mfenced> + parent._name = "mfenced" + parent._attr = {open = open, close = close} + end +end + return function(dom) dom:traverse_elements(function(el) + if settings.output_format ~= "odt" then + -- LibreOffice needs <mfenced>, but Firefox doesn't + fix_mfenced(el) + else + fix_mo_to_mfenced(el) + end fix_token_elements(el) fix_nested_mstyle(el) end) |