From 0b896d83c75a5285d122989e90a2168c58cc2d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Mon, 19 Apr 2021 19:56:03 +0200 Subject: [PATCH] Better stretchy handling and overwrite support --- mlist_to_mml.lua | 57 +++--- stretchy.lua | 500 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 534 insertions(+), 23 deletions(-) create mode 100644 stretchy.lua diff --git a/mlist_to_mml.lua b/mlist_to_mml.lua index eb2af47..c584e80 100644 --- a/mlist_to_mml.lua +++ b/mlist_to_mml.lua @@ -1,4 +1,7 @@ local remap_comb = require'remap_comb' +local stretchy = require'stretchy' + +local properties = node.get_properties_table() local noad_t, accent_t, style_t, choice_t = node.id'noad', node.id'accent', node.id'style', node.id'choice' local radical_t, fraction_t, fence_t = node.id'radical', node.id'fraction', node.id'fence' @@ -17,18 +20,39 @@ local function sup_style(s) return s//4*2+4+s%2 end -- We ignore large_... since they aren't used for modern fonts local function delim_to_table(delim) if not delim then return end + local props = properties[delim] props = props and props.mathml_table + if props then return props end local fam = delim.small_fam - return {[0] = 'mo', utf8.char(delim.small_char), ['tex:family'] = fam ~= 0 and fam or nil } + return {[0] = 'mo', utf8.char(delim.small_char), ['tex:family'] = fam ~= 0 and fam or nil, stretchy = not stretchy[delim.small_char] or nil } +end + +-- Like kernel_to_table but always a math_char_t. Also creating a mo and potentially remapping to handle combining chars +local function acc_to_table(acc, cur_style, stretch) + if not acc then return end + local props = properties[acc] props = props and props.mathml_table + if props then return props end + if acc.id ~= math_char_t then + error'confusion' + end + local char = utf8.char(acc.char) + char = remap_comb[char] or char + local fam = acc.fam + if stretch ~= not stretchy[char] then -- Handle nil gracefully in stretchy + stretch = nil + end + return {[0] = 'mo', char, ['tex:family'] = fam ~= 0 and fam or nil, stretchy = stretch} end local function kernel_to_table(kernel, cur_style) if not kernel then return end + local props = properties[kernel] props = props and props.mathml_table + if props then return props end local id = kernel.id if id == math_char_t then local char = kernel.char local elem = char >= 0x30 and char < 0x39 and 'mn' or 'mi' local fam = kernel.fam - return {[0] = elem, utf8.char(kernel.char), ['tex:family'] = fam ~= 0 and fam or nil, mathvariant = char < 0x10000 and 'normal' or nil } + return {[0] = elem, utf8.char(char), ['tex:family'] = fam ~= 0 and fam or nil, mathvariant = char < 0x10000 and 'normal' or nil } elseif id == sub_box_t then return {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} elseif id == sub_mlist_t then @@ -64,6 +88,7 @@ local function noad_to_table(noad, sub, cur_style) -- TODO else nucleus[0] = 'mo' + if stretchy[nucleus[1]] then nucleus.stretchy = false end if nucleus.mathvariant == 'normal' then nucleus.mathvariant = nil end end nucleus['tex:class'] = class @@ -98,24 +123,8 @@ end local function accent_to_table(accent, sub, cur_style) local nucleus = kernel_to_table(accent.nucleus, cur_style//2*2+1) - local top_acc = kernel_to_table(accent.accent, cur_style) - local bot_acc = kernel_to_table(accent.bot_accent, cur_style) - if top_acc then - top_acc[0] = 'mo' - if top_acc.mathvariant == 'normal' then top_acc.mathvariant = nil end - if sub & 1 == 1 then - top_acc.stretchy = 'false' - end - top_acc[1] = remap_comb[top_acc[1]] or top_acc[1] - end - if bot_acc then - bot_acc[0] = 'mo' - if bot_acc.mathvariant == 'normal' then bot_acc.mathvariant = nil end - if sub & 2 == 2 then - bot_acc.stretchy = 'false' - end - bot_acc[1] = remap_comb[bot_acc[1]] or bot_acc[1] - end + local top_acc = acc_to_table(accent.accent, cur_style, sub & 1 == 1) + local bot_acc = acc_to_table(accent.bot_accent, cur_style, sub & 2 == 2) return {[0] = top_acc and (bot_acc and 'munderover' or 'mover') or 'munder', nucleus, bot_acc or top_acc, @@ -145,7 +154,7 @@ local function radical_to_table(radical, sub, cur_style) elem = {[0] = 'msqrt', nucleus} elseif kind == 'uroot' then -- FIXME: Check that this is really a root - elem = {[0] = 'msqrt', nucleus, delim_to_table(radical.degree)} + elem = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree)} elseif kind == 'uunderdelimiter' then elem = {[0] = 'munder', left, nucleus} elseif kind == 'uoverdelimiter' then @@ -189,7 +198,6 @@ end local function fence_to_table(fence, sub, cur_style) local delim = delim_to_table(fence.delimiter) - delim.stretchy = 'true' delim.fence = 'true' return delim end @@ -198,7 +206,10 @@ function nodes_to_table(head, cur_style) local t = {[0] = "mrow"} local result = t for n, id, sub in node.traverse(head) do - if id == noad_t then + local props = properties[n] props = props and props.mathml_table + if props then + t[#t+1] = props + elseif id == noad_t then t[#t+1] = noad_to_table(n, sub, cur_style) elseif id == accent_t then t[#t+1] = accent_to_table(n, sub, cur_style) diff --git a/stretchy.lua b/stretchy.lua new file mode 100644 index 0000000..72f8406 --- /dev/null +++ b/stretchy.lua @@ -0,0 +1,500 @@ +return { + -- The following is + -- xq -r '.unicode.charlist.character[] | select(.["operator-dictionary"] | if type == "array" then .[] else . end | .["@stretchy"]) | .["@id"] | sub("U"; "") | "[\"\\u{\(.)}\"] = true," ' < unicode.xml +["\u{00028}"] = true, +["\u{00029}"] = true, +["\u{0005B}"] = true, +["\u{0005D}"] = true, +["\u{0005E}"] = true, +["\u{0005F}"] = true, +["\u{0007B}"] = true, +["\u{0007C}"] = true, +["\u{0007C}"] = true, +["\u{0007D}"] = true, +["\u{0007E}"] = true, +["\u{000AF}"] = true, +["\u{002C6}"] = true, +["\u{002C7}"] = true, +["\u{002C9}"] = true, +["\u{002CD}"] = true, +["\u{002DC}"] = true, +["\u{002F7}"] = true, +["\u{00302}"] = true, +["\u{02016}"] = true, +["\u{02016}"] = true, +["\u{0203E}"] = true, +["\u{02190}"] = true, +["\u{02191}"] = true, +["\u{02192}"] = true, +["\u{02193}"] = true, +["\u{02194}"] = true, +["\u{02195}"] = true, +["\u{0219A}"] = true, +["\u{0219B}"] = true, +["\u{0219C}"] = true, +["\u{0219D}"] = true, +["\u{0219E}"] = true, +["\u{0219F}"] = true, +["\u{021A0}"] = true, +["\u{021A1}"] = true, +["\u{021A2}"] = true, +["\u{021A3}"] = true, +["\u{021A4}"] = true, +["\u{021A5}"] = true, +["\u{021A6}"] = true, +["\u{021A7}"] = true, +["\u{021A8}"] = true, +["\u{021A9}"] = true, +["\u{021AA}"] = true, +["\u{021AB}"] = true, +["\u{021AC}"] = true, +["\u{021AD}"] = true, +["\u{021AE}"] = true, +["\u{021B0}"] = true, +["\u{021B1}"] = true, +["\u{021B2}"] = true, +["\u{021B3}"] = true, +["\u{021B4}"] = true, +["\u{021B5}"] = true, +["\u{021B9}"] = true, +["\u{021BC}"] = true, +["\u{021BD}"] = true, +["\u{021BE}"] = true, +["\u{021BF}"] = true, +["\u{021C0}"] = true, +["\u{021C1}"] = true, +["\u{021C2}"] = true, +["\u{021C3}"] = true, +["\u{021C4}"] = true, +["\u{021C5}"] = true, +["\u{021C6}"] = true, +["\u{021C7}"] = true, +["\u{021C8}"] = true, +["\u{021C9}"] = true, +["\u{021CA}"] = true, +["\u{021CB}"] = true, +["\u{021CC}"] = true, +["\u{021CD}"] = true, +["\u{021CE}"] = true, +["\u{021CF}"] = true, +["\u{021D0}"] = true, +["\u{021D1}"] = true, +["\u{021D2}"] = true, +["\u{021D3}"] = true, +["\u{021D4}"] = true, +["\u{021D5}"] = true, +["\u{021DA}"] = true, +["\u{021DB}"] = true, +["\u{021DC}"] = true, +["\u{021DD}"] = true, +["\u{021DE}"] = true, +["\u{021DF}"] = true, +["\u{021E0}"] = true, +["\u{021E1}"] = true, +["\u{021E2}"] = true, +["\u{021E3}"] = true, +["\u{021E4}"] = true, +["\u{021E5}"] = true, +["\u{021E6}"] = true, +["\u{021E7}"] = true, +["\u{021E8}"] = true, +["\u{021E9}"] = true, +["\u{021EA}"] = true, +["\u{021EB}"] = true, +["\u{021EC}"] = true, +["\u{021ED}"] = true, +["\u{021EE}"] = true, +["\u{021EF}"] = true, +["\u{021F0}"] = true, +["\u{021F3}"] = true, +["\u{021F4}"] = true, +["\u{021F5}"] = true, +["\u{021F6}"] = true, +["\u{021F7}"] = true, +["\u{021F8}"] = true, +["\u{021F9}"] = true, +["\u{021FA}"] = true, +["\u{021FB}"] = true, +["\u{021FC}"] = true, +["\u{021FD}"] = true, +["\u{021FE}"] = true, +["\u{021FF}"] = true, +["\u{02308}"] = true, +["\u{02309}"] = true, +["\u{0230A}"] = true, +["\u{0230B}"] = true, +["\u{02322}"] = true, +["\u{02323}"] = true, +["\u{02329}"] = true, +["\u{0232A}"] = true, +["\u{023B4}"] = true, +["\u{023B5}"] = true, +["\u{023DC}"] = true, +["\u{023DD}"] = true, +["\u{023DE}"] = true, +["\u{023DF}"] = true, +["\u{023E0}"] = true, +["\u{023E1}"] = true, +["\u{02772}"] = true, +["\u{02773}"] = true, +["\u{02794}"] = true, +["\u{02799}"] = true, +["\u{0279B}"] = true, +["\u{0279C}"] = true, +["\u{0279D}"] = true, +["\u{0279E}"] = true, +["\u{0279F}"] = true, +["\u{027A0}"] = true, +["\u{027A1}"] = true, +["\u{027A5}"] = true, +["\u{027A6}"] = true, +["\u{027A8}"] = true, +["\u{027A9}"] = true, +["\u{027AA}"] = true, +["\u{027AB}"] = true, +["\u{027AC}"] = true, +["\u{027AD}"] = true, +["\u{027AE}"] = true, +["\u{027AF}"] = true, +["\u{027B1}"] = true, +["\u{027B3}"] = true, +["\u{027B5}"] = true, +["\u{027B8}"] = true, +["\u{027BA}"] = true, +["\u{027BB}"] = true, +["\u{027BC}"] = true, +["\u{027BD}"] = true, +["\u{027BE}"] = true, +["\u{027E6}"] = true, +["\u{027E7}"] = true, +["\u{027E8}"] = true, +["\u{027E9}"] = true, +["\u{027EA}"] = true, +["\u{027EB}"] = true, +["\u{027EC}"] = true, +["\u{027ED}"] = true, +["\u{027EE}"] = true, +["\u{027EF}"] = true, +["\u{027F0}"] = true, +["\u{027F1}"] = true, +["\u{027F4}"] = true, +["\u{027F5}"] = true, +["\u{027F6}"] = true, +["\u{027F7}"] = true, +["\u{027F8}"] = true, +["\u{027F9}"] = true, +["\u{027FA}"] = true, +["\u{027FB}"] = true, +["\u{027FC}"] = true, +["\u{027FD}"] = true, +["\u{027FE}"] = true, +["\u{027FF}"] = true, +["\u{02900}"] = true, +["\u{02901}"] = true, +["\u{02902}"] = true, +["\u{02903}"] = true, +["\u{02904}"] = true, +["\u{02905}"] = true, +["\u{02906}"] = true, +["\u{02907}"] = true, +["\u{02908}"] = true, +["\u{02909}"] = true, +["\u{0290A}"] = true, +["\u{0290B}"] = true, +["\u{0290C}"] = true, +["\u{0290D}"] = true, +["\u{0290E}"] = true, +["\u{0290F}"] = true, +["\u{02910}"] = true, +["\u{02911}"] = true, +["\u{02912}"] = true, +["\u{02913}"] = true, +["\u{02914}"] = true, +["\u{02915}"] = true, +["\u{02916}"] = true, +["\u{02917}"] = true, +["\u{02918}"] = true, +["\u{02919}"] = true, +["\u{0291A}"] = true, +["\u{0291B}"] = true, +["\u{0291C}"] = true, +["\u{0291D}"] = true, +["\u{0291E}"] = true, +["\u{0291F}"] = true, +["\u{02920}"] = true, +["\u{02934}"] = true, +["\u{02935}"] = true, +["\u{02936}"] = true, +["\u{02937}"] = true, +["\u{02942}"] = true, +["\u{02943}"] = true, +["\u{02944}"] = true, +["\u{02945}"] = true, +["\u{02946}"] = true, +["\u{02947}"] = true, +["\u{02948}"] = true, +["\u{02949}"] = true, +["\u{0294A}"] = true, +["\u{0294B}"] = true, +["\u{0294C}"] = true, +["\u{0294D}"] = true, +["\u{0294E}"] = true, +["\u{0294F}"] = true, +["\u{02950}"] = true, +["\u{02951}"] = true, +["\u{02952}"] = true, +["\u{02953}"] = true, +["\u{02954}"] = true, +["\u{02955}"] = true, +["\u{02956}"] = true, +["\u{02957}"] = true, +["\u{02958}"] = true, +["\u{02959}"] = true, +["\u{0295A}"] = true, +["\u{0295B}"] = true, +["\u{0295C}"] = true, +["\u{0295D}"] = true, +["\u{0295E}"] = true, +["\u{0295F}"] = true, +["\u{02960}"] = true, +["\u{02961}"] = true, +["\u{02962}"] = true, +["\u{02963}"] = true, +["\u{02964}"] = true, +["\u{02965}"] = true, +["\u{02966}"] = true, +["\u{02967}"] = true, +["\u{02968}"] = true, +["\u{02969}"] = true, +["\u{0296A}"] = true, +["\u{0296B}"] = true, +["\u{0296C}"] = true, +["\u{0296D}"] = true, +["\u{0296E}"] = true, +["\u{0296F}"] = true, +["\u{02970}"] = true, +["\u{02971}"] = true, +["\u{02972}"] = true, +["\u{02973}"] = true, +["\u{02974}"] = true, +["\u{02975}"] = true, +["\u{0297C}"] = true, +["\u{0297D}"] = true, +["\u{0297E}"] = true, +["\u{0297F}"] = true, +["\u{02980}"] = true, +["\u{02980}"] = true, +["\u{02983}"] = true, +["\u{02984}"] = true, +["\u{02985}"] = true, +["\u{02986}"] = true, +["\u{02987}"] = true, +["\u{02988}"] = true, +["\u{02989}"] = true, +["\u{0298A}"] = true, +["\u{0298B}"] = true, +["\u{0298C}"] = true, +["\u{0298D}"] = true, +["\u{0298E}"] = true, +["\u{0298F}"] = true, +["\u{02990}"] = true, +["\u{02991}"] = true, +["\u{02992}"] = true, +["\u{02993}"] = true, +["\u{02994}"] = true, +["\u{02995}"] = true, +["\u{02996}"] = true, +["\u{02997}"] = true, +["\u{02998}"] = true, +["\u{02999}"] = true, +["\u{02999}"] = true, +["\u{029D8}"] = true, +["\u{029D9}"] = true, +["\u{029DA}"] = true, +["\u{029DB}"] = true, +["\u{029FC}"] = true, +["\u{029FD}"] = true, +["\u{02B04}"] = true, +["\u{02B05}"] = true, +["\u{02B06}"] = true, +["\u{02B07}"] = true, +["\u{02B0C}"] = true, +["\u{02B0D}"] = true, +["\u{02B0E}"] = true, +["\u{02B0F}"] = true, +["\u{02B10}"] = true, +["\u{02B11}"] = true, +["\u{02B30}"] = true, +["\u{02B31}"] = true, +["\u{02B32}"] = true, +["\u{02B33}"] = true, +["\u{02B34}"] = true, +["\u{02B35}"] = true, +["\u{02B36}"] = true, +["\u{02B37}"] = true, +["\u{02B38}"] = true, +["\u{02B39}"] = true, +["\u{02B3A}"] = true, +["\u{02B3B}"] = true, +["\u{02B3C}"] = true, +["\u{02B3D}"] = true, +["\u{02B3E}"] = true, +["\u{02B40}"] = true, +["\u{02B41}"] = true, +["\u{02B42}"] = true, +["\u{02B43}"] = true, +["\u{02B44}"] = true, +["\u{02B45}"] = true, +["\u{02B46}"] = true, +["\u{02B47}"] = true, +["\u{02B48}"] = true, +["\u{02B49}"] = true, +["\u{02B4A}"] = true, +["\u{02B4B}"] = true, +["\u{02B4C}"] = true, +["\u{02B60}"] = true, +["\u{02B61}"] = true, +["\u{02B62}"] = true, +["\u{02B63}"] = true, +["\u{02B64}"] = true, +["\u{02B65}"] = true, +["\u{02B6A}"] = true, +["\u{02B6B}"] = true, +["\u{02B6C}"] = true, +["\u{02B6D}"] = true, +["\u{02B70}"] = true, +["\u{02B71}"] = true, +["\u{02B72}"] = true, +["\u{02B73}"] = true, +["\u{02B7A}"] = true, +["\u{02B7B}"] = true, +["\u{02B7C}"] = true, +["\u{02B7D}"] = true, +["\u{02B80}"] = true, +["\u{02B81}"] = true, +["\u{02B82}"] = true, +["\u{02B83}"] = true, +["\u{02B84}"] = true, +["\u{02B85}"] = true, +["\u{02B86}"] = true, +["\u{02B87}"] = true, +["\u{02B95}"] = true, +["\u{02BA0}"] = true, +["\u{02BA1}"] = true, +["\u{02BA2}"] = true, +["\u{02BA3}"] = true, +["\u{02BA4}"] = true, +["\u{02BA5}"] = true, +["\u{02BA6}"] = true, +["\u{02BA7}"] = true, +["\u{02BA8}"] = true, +["\u{02BA9}"] = true, +["\u{02BAA}"] = true, +["\u{02BAB}"] = true, +["\u{02BAC}"] = true, +["\u{02BAD}"] = true, +["\u{02BAE}"] = true, +["\u{02BAF}"] = true, +["\u{02BB8}"] = true, +["\u{1EEF0}"] = true, +["\u{1EEF1}"] = true, +["\u{1F800}"] = true, +["\u{1F801}"] = true, +["\u{1F802}"] = true, +["\u{1F803}"] = true, +["\u{1F804}"] = true, +["\u{1F805}"] = true, +["\u{1F806}"] = true, +["\u{1F807}"] = true, +["\u{1F808}"] = true, +["\u{1F809}"] = true, +["\u{1F80A}"] = true, +["\u{1F80B}"] = true, +["\u{1F810}"] = true, +["\u{1F811}"] = true, +["\u{1F812}"] = true, +["\u{1F813}"] = true, +["\u{1F814}"] = true, +["\u{1F815}"] = true, +["\u{1F816}"] = true, +["\u{1F817}"] = true, +["\u{1F818}"] = true, +["\u{1F819}"] = true, +["\u{1F81A}"] = true, +["\u{1F81B}"] = true, +["\u{1F81C}"] = true, +["\u{1F81D}"] = true, +["\u{1F81E}"] = true, +["\u{1F81F}"] = true, +["\u{1F820}"] = true, +["\u{1F821}"] = true, +["\u{1F822}"] = true, +["\u{1F823}"] = true, +["\u{1F824}"] = true, +["\u{1F825}"] = true, +["\u{1F826}"] = true, +["\u{1F827}"] = true, +["\u{1F828}"] = true, +["\u{1F829}"] = true, +["\u{1F82A}"] = true, +["\u{1F82B}"] = true, +["\u{1F82C}"] = true, +["\u{1F82D}"] = true, +["\u{1F82E}"] = true, +["\u{1F82F}"] = true, +["\u{1F830}"] = true, +["\u{1F831}"] = true, +["\u{1F832}"] = true, +["\u{1F833}"] = true, +["\u{1F834}"] = true, +["\u{1F835}"] = true, +["\u{1F836}"] = true, +["\u{1F837}"] = true, +["\u{1F844}"] = true, +["\u{1F845}"] = true, +["\u{1F846}"] = true, +["\u{1F847}"] = true, +["\u{1F850}"] = true, +["\u{1F851}"] = true, +["\u{1F852}"] = true, +["\u{1F853}"] = true, +["\u{1F858}"] = true, +["\u{1F859}"] = true, +["\u{1F860}"] = true, +["\u{1F861}"] = true, +["\u{1F862}"] = true, +["\u{1F863}"] = true, +["\u{1F868}"] = true, +["\u{1F869}"] = true, +["\u{1F86A}"] = true, +["\u{1F86B}"] = true, +["\u{1F870}"] = true, +["\u{1F871}"] = true, +["\u{1F872}"] = true, +["\u{1F873}"] = true, +["\u{1F878}"] = true, +["\u{1F879}"] = true, +["\u{1F87A}"] = true, +["\u{1F87B}"] = true, +["\u{1F880}"] = true, +["\u{1F881}"] = true, +["\u{1F882}"] = true, +["\u{1F883}"] = true, +["\u{1F898}"] = true, +["\u{1F899}"] = true, +["\u{1F89A}"] = true, +["\u{1F89B}"] = true, +["\u{1F8A0}"] = true, +["\u{1F8A1}"] = true, +["\u{1F8A2}"] = true, +["\u{1F8A3}"] = true, +["\u{1F8A4}"] = true, +["\u{1F8A5}"] = true, +["\u{1F8A6}"] = true, +["\u{1F8A7}"] = true, +["\u{1F8A8}"] = true, +["\u{1F8A9}"] = true, +["\u{1F8AA}"] = true, +["\u{1F8AB}"] = true, +-- till here +}