Better stretchy handling and overwrite support

This commit is contained in:
Marcel Fabian Krüger 2021-04-19 19:56:03 +02:00
parent 3cb9600964
commit 0b896d83c7
2 changed files with 534 additions and 23 deletions

View File

@ -1,4 +1,7 @@
local remap_comb = require'remap_comb' 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 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' 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 -- We ignore large_... since they aren't used for modern fonts
local function delim_to_table(delim) local function delim_to_table(delim)
if not delim then return end 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 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 end
local function kernel_to_table(kernel, cur_style) local function kernel_to_table(kernel, cur_style)
if not kernel then return end 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 local id = kernel.id
if id == math_char_t then if id == math_char_t then
local char = kernel.char local char = kernel.char
local elem = char >= 0x30 and char < 0x39 and 'mn' or 'mi' local elem = char >= 0x30 and char < 0x39 and 'mn' or 'mi'
local fam = kernel.fam 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 elseif id == sub_box_t then
return {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}} return {[0] = 'mi', {[0] = 'mglyph', ['tex:box'] = kernel.list}}
elseif id == sub_mlist_t then elseif id == sub_mlist_t then
@ -64,6 +88,7 @@ local function noad_to_table(noad, sub, cur_style)
-- TODO -- TODO
else else
nucleus[0] = 'mo' nucleus[0] = 'mo'
if stretchy[nucleus[1]] then nucleus.stretchy = false end
if nucleus.mathvariant == 'normal' then nucleus.mathvariant = nil end if nucleus.mathvariant == 'normal' then nucleus.mathvariant = nil end
end end
nucleus['tex:class'] = class nucleus['tex:class'] = class
@ -98,24 +123,8 @@ end
local function accent_to_table(accent, sub, cur_style) local function accent_to_table(accent, sub, cur_style)
local nucleus = kernel_to_table(accent.nucleus, cur_style//2*2+1) local nucleus = kernel_to_table(accent.nucleus, cur_style//2*2+1)
local top_acc = kernel_to_table(accent.accent, cur_style) local top_acc = acc_to_table(accent.accent, cur_style, sub & 1 == 1)
local bot_acc = kernel_to_table(accent.bot_accent, cur_style) local bot_acc = acc_to_table(accent.bot_accent, cur_style, sub & 2 == 2)
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
return {[0] = top_acc and (bot_acc and 'munderover' or 'mover') or 'munder', return {[0] = top_acc and (bot_acc and 'munderover' or 'mover') or 'munder',
nucleus, nucleus,
bot_acc or top_acc, bot_acc or top_acc,
@ -145,7 +154,7 @@ local function radical_to_table(radical, sub, cur_style)
elem = {[0] = 'msqrt', nucleus} elem = {[0] = 'msqrt', nucleus}
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 = {[0] = 'msqrt', nucleus, delim_to_table(radical.degree)} elem = {[0] = 'msqrt', nucleus, kernel_to_table(radical.degree)}
elseif kind == 'uunderdelimiter' then elseif kind == 'uunderdelimiter' then
elem = {[0] = 'munder', left, nucleus} elem = {[0] = 'munder', left, nucleus}
elseif kind == 'uoverdelimiter' then elseif kind == 'uoverdelimiter' then
@ -189,7 +198,6 @@ end
local function fence_to_table(fence, sub, cur_style) local function fence_to_table(fence, sub, cur_style)
local delim = delim_to_table(fence.delimiter) local delim = delim_to_table(fence.delimiter)
delim.stretchy = 'true'
delim.fence = 'true' delim.fence = 'true'
return delim return delim
end end
@ -198,7 +206,10 @@ function nodes_to_table(head, cur_style)
local t = {[0] = "mrow"} local t = {[0] = "mrow"}
local result = t local result = t
for n, id, sub in node.traverse(head) do 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) t[#t+1] = noad_to_table(n, sub, cur_style)
elseif id == accent_t then elseif id == accent_t then
t[#t+1] = accent_to_table(n, sub, cur_style) t[#t+1] = accent_to_table(n, sub, cur_style)

500
stretchy.lua Normal file
View File

@ -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
}