有没有办法剖析数学列表?

有没有办法剖析数学列表?

在尝试回答这个问题的过程中问题,我现在意识到我需要能够构建一个数学列表,然后检查它是否由单个字符原子组成。

我希望能够解构数学列表,类似于“用\lastbox”解剖段落的数学列表TeX 按主题分类

正如本文所述回答,可以用来\showlists将部分列表的表示写入日志文件。除非我想解析日志文件,否则这似乎对我没有帮助。(我不想。)

答案1

我很确定你可以做一些事情来扩展TeX 按主题分类\lastbox在段落完成后使用和框展开,但是(除了非常繁琐之外)这不会让您访问实际的数学列表,而只能访问其转换格式作为\hbox和的嵌套树\vbox

TeX82 不提供除通过之外的其他方式访问数学列表的权限\showlists(并且有一次我认为 luatex 答案并没有真正的帮助)。

答案2

只有在使用 LuaTeX 时才可以剖析数学列表。例如,您可以使用回调mlist_to_hlist。下面的代码\showlists在一定程度上模拟了数学列表:例如,\radical没有得到处理。

请注意,我是一个 LuaTeX 新手,因此代码可能远非最佳,并且不遵循标准的最佳实践。

\begingroup
\catcode`~=12
\catcode`#=12
\escapechar=-1
\edef\\{\string\\}
\directlua
  {%
    local my = {}
    my.node = {}
    function my.node.tostring(t, newline)
        if t == nil then
            return ''
        end
        if my[node.type(t.id)] ~= nil then
            return my[node.type(t.id)].tostring(t, newline)
        else
            local result = newline .. node.type(t.id)
            for _, v in ipairs(node.fields(t.id)) do
                if v == 'id' or t[v] == nil then else
                    local value = t[v]
                    if type(value) == "userdata" then
                        value = node.type(value.id)
                    end
                    result = result .. ', ' .. v .. ': ' .. value
                end
            end
            return result
        end
    end
    %
    my.noad = {}
    my.noad.subtypes = {'op', nil, nil, 'bin', 'rel', 'open',
      'close', 'punct', 'inner', [0] = 'ord'}
    function my.noad.subtype(subtype)
        if my.noad.subtypes[subtype] == nil then
            return '\\\\math?'
        else
            return '\\\\math' .. my.noad.subtypes[subtype]
        end
    end
    function my.noad.tostring(t, newline)
        local result = newline .. my.noad.subtype(t.subtype)
        if t.attr ~= nil then
            result = result .. t.attr
        end
        result = result
                 .. my.node.tostring(t.nucleus, newline .. '.')
                 .. my.node.tostring(t.sup, newline .. '^')
                 .. my.node.tostring(t.sub, newline .. '_')
        return result
    end
    %
    my.math_char = {}
    function my.math_char.tostring(t, newline)
        return newline .. '\\\\fam' .. t.fam .. ' ' .. string.char(t.char)
    end
    %
    my.fence = {}
    function my.fence.tostring(t, newline)
        fencename = ({'\\\\left', '\\\\middle', '\\\\right'})[t.subtype]
        return newline .. fencename .. my.node.tostring(t.delim, ' ')
    end
    %
    my.delim = {}
    function my.delim.tostring(t, newline)
        return
            newline
            .. 'small: \\\\fam'
            .. t.small_fam
            .. ' '
            .. (t.small_char == 0 and '^'..'^@' or string.char(t.small_char))
            .. ', large: \\\\fam'
            .. t.large_fam
            .. ' '
            .. (t.large_char == 0 and '^'..'^@' or string.char(t.large_char))
    end
    %
    % subtype and attr ignored for sub_mlist?
    my.sub_mlist = {}
    function my.sub_mlist.tostring(mlist, newline)
        return my.mlist.tostring(mlist.head, newline)
    end
    %
    my.mlist = {}
    function my.mlist.tostring(h, newline)
        local result = ''
        for t in node.traverse(h) do
            result = result .. my.node.tostring(t, newline)
        end
        return result
    end
    %
    callback.register
      (
        "mlist_to_hlist",
        function (h, d, p)
            local tab = {}
            texio.write_nl('\\n')
            my.mlist.tostring(h, '\\n'):gsub('([^\\n]+)', texio.write_nl)
            texio.write_nl('\\n')
            return node.mlist_to_hlist(h, d, p)
        end
      )
  }
\endgroup

abc $ \mathord{\mathord{a}^b}^b \sum + = (),\left(2\middle|3\right)\sqrt{a}$ f

\bye

相关内容