align support and fixes

This commit is contained in:
Marcel Fabian Krüger 2021-04-24 16:53:50 +02:00
parent c0a1f60962
commit 23c6714e97
6 changed files with 291 additions and 27 deletions

84
luamml-amsmath.lua Normal file
View File

@ -0,0 +1,84 @@
local write_xml = require'luamml-xmlwriter'
local make_root = require'luamml-convert'.make_root
local properties = node.get_properties_table()
local funcid = luatexbase.new_luafunction'luamml_amsmath_add_box_to_row:'
token.set_lua('luamml_amsmath_add_box_to_row:', funcid, 'protected')
lua.get_functions_table()[funcid] = function()
-- TODO: Error handling etc
-- local box = token.scan_int()
local boxnum = 0
local startmath = tex.box[boxnum].list
assert(startmath.id == node.id"math")
local props = assert(properties[startmath])
local mml = assert(props.saved_mathml_table)
table.insert(mml, 1, {[0] = 'maligngroup'})
if mml[0] == 'mstyle' and mml.displaystyle == true then
mml[0], mml.displaystyle, mml.scriptlevel = 'mtd', nil, nil
else
if mml[0] ~= 'mstyle' then
mml = {[0] = 'mstyle', displaystyle = false, mml}
end
mml = {[0] = 'mtd', mml}
end
local row_temp = tex.nest[tex.nest.ptr-1]
print(row_temp)
props = properties[row_temp]
if not props then
props = {}
properties[row_temp] = props
end
if not props.mathml_row then
props.mathml_row = {[0] = 'mtr'}
end
mml_row = props.mathml_row
table.insert(mml_row, mml)
end
local funcid = luatexbase.new_luafunction'luamml_amsmath_finalize_row:'
token.set_lua('luamml_amsmath_finalize_row:', funcid, 'protected')
lua.get_functions_table()[funcid] = function()
-- TODO: Error handling etc
local row_temp = tex.nest[tex.nest.ptr-1]
print("final", row_temp)
local props = properties[row_temp]
if not props then return end
if not props.mathml_row then return end
mml_row = props.mathml_row
props = properties[tex.lists.align_head]
if not props then
props = {}
properties[tex.lists.align_head] = props
end
local mml_table = props.mathml_table_node_table
if not mml_table then
mml_table = {[0] = 'mtable', displaystyle = true}
props.mathml_table_node_table = mml_table
end
table.insert(mml_table, mml_row)
end
local funcid = luatexbase.new_luafunction'luamml_amsmath_finalize_table:'
token.set_lua('luamml_amsmath_finalize_table:', funcid)
lua.get_functions_table()[funcid] = function()
-- TODO: Error handling etc
local props = properties[tex.lists.align_head]
if not props then return end
local mml_table = props.mathml_table_node_table
if not mml_table then return end
print(write_xml(make_root(mml_table, 2)))
end
funcid = luatexbase.new_luafunction'luamml_last_math_alignmark:'
token.set_lua('luamml_last_math_alignmark:', funcid, 'protected')
lua.get_functions_table()[funcid] = function()
local n = tex.nest.top.tail
n = n.nucleus or n
local props = properties[n]
if not props then
props = {}
properties[n] = props
end
props.mathml_table = {[0] = 'malignmark'}
end

View File

@ -77,7 +77,7 @@ local function kernel_to_table(kernel, cur_style)
local result = {[0] = elem,
char,
['tex:family'] = fam ~= 0 and fam or nil,
mathvariant = #char == 1 and utf8.codepoint(char) < 0x10000 and 'normal' or nil
mathvariant = #char == 1 and elem == 'mi' and utf8.codepoint(char) < 0x10000 and 'normal' or nil
}
return result, result
elseif id == sub_box_t then
@ -256,17 +256,21 @@ function nodes_to_table(head, cur_style)
elseif id == accent_t then
t[#t+1], new_core = accent_to_table(n, sub, cur_style)
elseif id == style_t then
if #t ~= 0 then
local new_t = {[0] = 'mstyle'}
t[#t+1] = new_t
t = new_t
if sub ~= cur_style then
if #t == 0 then
t[0] = 'mstyle'
else
local new_t = {[0] = 'mstyle'}
t[#t+1] = new_t
t = new_t
end
if sub < 2 then
t.displaystyle, t.scriptlevel = true, 0
else
t.displaystyle, t.scriptlevel = false, sub//2 - 1
end
cur_style = sub
end
if sub < 2 then
t.displaystyle, t.scriptlevel = true, 0
else
t.displaystyle, t.scriptlevel = false, sub//2 - 1
end
cur_style = sub
new_core = space_like
elseif id == choice_t then
local size = cur_style//2
@ -312,18 +316,22 @@ local function register_remap(family, mapping)
end
end
local function to_mml(head, style)
local result = nodes_to_table(head, style or 0)
result[0] = 'math'
result.xmlns = 'http://www.w3.org/1998/Math/MathML'
result['xmlns:tex'] = 'http://typesetting.eu/2021/LuaMathML'
if style == 2 then
result.display = 'block'
local function to_math(root, style)
if root[0] == 'mrow' then
root[0] = 'math'
else
root = {[0] = 'math', root}
end
return result
root.xmlns = 'http://www.w3.org/1998/Math/MathML'
root['xmlns:tex'] = 'http://typesetting.eu/2021/LuaMathML'
if style < 2 then
root.display = 'block'
end
return root
end
return {
register_family = register_remap,
process = to_mml,
process = function(head, style) return nodes_to_table(head, style or 2) end,
make_root = to_math,
}

View File

@ -0,0 +1,99 @@
\ProvidesExplPackage {luamml-patches-amsmath} {2021-04-23} {0.0.1-alpha}
{Feel free to add a description here}
\lua_now:n { require'luamml-amsmath' }
\cs_set:Npn \align@preamble {
&
\hfil
\strut@
\setboxz@h {
\@lign
$
\m@th
\displaystyle {
##
}
\ifmeasuring@
\luamml_flag_ignore:
\else
\luamml_flag_alignment_left:
\fi
$
}
\ifmeasuring@
\savefieldlength@
\fi
\set@field
\tabskip\z@skip
&
\setboxz@h {
\@lign
$
\m@th
\displaystyle
{
{}
\luamml_last_math_alignmark:
##
}
\ifmeasuring@
\luamml_flag_ignore:
\else
\luamml_flag_alignment_right:
\fi
$
}
\ifmeasuring@
\savefieldlength@
\else
\luamml_amsmath_add_box_to_row:
\fi
\set@field
\hfil
\tabskip\alignsep@
}
\cs_set:Npn \math@cr@@@align {
\ifst@rred
\nonumber
\fi
\if@eqnsw
\global \tag@true
\fi
\global \advance \row@ \@ne
\add@amps \maxfields@
\omit
\kern -\alignsep@
\luamml_amsmath_finalize_row:
\iftag@
\setboxz@h {
\@lign
\strut@
{ \make@display@tag }
}
\place@tag
\fi
\ifst@rred
\else
\global \@eqnswtrue
\fi
\global \lineht@ \z@
\cr
}
\cs_set:Npn \endalign {
\math@cr
\black@ \totwidth@
\luamml_amsmath_finalize_table:
\egroup
\ifingather@
\restorealignstate@
\egroup
\nonumber
\ifnum0={\fi\iffalse}\fi
\else
$$
\fi
\ignorespacesafterend
}

View File

@ -1,10 +1,13 @@
local mlist_to_mml = require'luamml-convert'
local process_mlist = mlist_to_mml.process
local make_root = mlist_to_mml.make_root
local register_family = mlist_to_mml.register_family
local mappings = require'luamml-legacy-mappings'
local write_xml = require'luamml-xmlwriter'
local properties = node.get_properties_table()
local funcid = luatexbase.new_luafunction'RegisterFamilyMapping'
token.set_lua('RegisterFamilyMapping', funcid, 'protected')
lua.get_functions_table()[funcid] = function()
@ -17,10 +20,56 @@ lua.get_functions_table()[funcid] = function()
end
end
-- Possible flag values:
-- 0: Normal (This is the only supported one in display mode)
-- 1: Like 0, result is display math
-- 2: Generate MathML, but only save it for later usage in startmath node
-- 3: Skip
-- 4: Prepend node list from buffer before generating
-- 5: Like 5, result is display math
-- 6: 2+4
-- 7: Skip but save copy of node list in buffer
--
-- In other words:
-- Bit 1: Suppress output
-- Bit 0: Force display if 1 isn't set, if it is then skip MathML generation
-- Bit 2: Integrate with table mechanism
local mlist_buffer
luatexbase.add_to_callback('pre_mlist_to_hlist_filter', function(mlist, style)
print''
local xml = process_mlist(mlist, style == 'display' and 2 or 0)
print(write_xml(xml))
print''
local flag = tex.count.l__luamml_flag_int
if flag & 3 == 3 then
if flag & 4 == 4 then
assert(mlist_buffer == nil)
mlist_buffer = node.copy_list(mlist)
end
return true
end
local new_mlist, buffer_tail
if flag & 4 == 4 then
new_mlist, buffer_tail = assert(mlist_buffer), node.tail(mlist_buffer)
mlist.prev, buffer_tail.next = buffer_tail, mlist
mlist_buffer = nil
else
new_mlist = mlist
end
local xml = process_mlist(new_mlist, style == 'display' and 0 or 2)
if flag & 2 == 0 then
print(write_xml(make_root(xml, (style == 'display' or flag & 1 == 1) and 0 or 2)) .. '\n')
else
assert(style == 'text')
local startmath = tex.nest.top.tail
local props = properties[startmath]
if not props then
props = {}
properties[startmath] = props
end
props.saved_mathml_table = xml
end
if buffer_tail then
mlist.prev, buffer_tail.next = nil, nil
node.flush_list(new_mlist)
end
return true
end, 'dump_list')

17
luamml.sty Normal file
View File

@ -0,0 +1,17 @@
\ProvidesExplPackage {luamml} {2021-04-23} {0.0.1-alpha}
{Feel free to add a description here}
\int_new:N \l__luamml_flag_int
\lua_now:n { require'luamml-tex' }
\cs_new:Nn \luamml_flag_ignore: {
\int_set:Nn \l__luamml_flag_int { 3 }
}
\cs_new:Nn \luamml_flag_alignment_left: {
\int_set:Nn \l__luamml_flag_int { 7 }
}
\cs_new:Nn \luamml_flag_alignment_right: {
\int_set:Nn \l__luamml_flag_int { 6 }
}
\RequirePackage { luamml-patches-amsmath }

View File

@ -1,11 +1,12 @@
\documentclass{article}
% \usepackage{unicode-math}
\directlua{require'luamml-tex'}
\usepackage{unicode-math}
\usepackage{amsmath}
\usepackage{luamml}
\RegisterFamilyMapping\symsymbols{oms}
\RegisterFamilyMapping\symletters{oml}
\begin{document}
\[
ax^2+b+c=0
ax^2+bx+c=0
\]
\[
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}.
@ -14,5 +15,11 @@
\sum_a\underline c\dot bc'
\]
\begin{align}
abc&=def\\
1+2&=3\\
5
\end{align}
Es gilt $\sin(x)-\sin(x+2\pi)=0$.
\end{document}