使用 lua 代码为每个字母设置边界框(后续问题)

使用 lua 代码为每个字母设置边界框(后续问题)

这是关于topskip 的回答

topskip 的代码运行得很好,即使对于复杂的文档(包含表格,分页,脚注等)也是如此,尽管如此,如下面的屏幕截图所示,其中一些元素并没有被装箱。

在此处输入图片描述

问题:为什么不是每个字母都加框?出了什么问题?

截图是该 MWE(演示论文,取自伯克利)产生的结果的一部分:

%% thesis.tex 2014/04/11
% Source: https://math.berkeley.edu/~vojta/thesis/
% Integrated into one single file, extended using topskip's luaCharBox-code
%
\documentclass{ucbthesis}
\usepackage{luacode,luatexbase,microtype,blindtext}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")

-- head is a linked list (next/prev entries pointing to the next node)
-- parent it the surrounding h/vbox
function showcharbox(head,parent)
    while head do
        if head.id == 0 or head.id == 1 then
            -- a hbox/vbox
            showcharbox(head.list,head)
        elseif head.id == GLYPH_ID then
            r = node.new("rule")
            r.width  = head.width
            r.height = head.height
            r.depth  = head.depth

            -- replace the glyph by
            -- the rule by changing the
            -- pointers of the next/prev
            -- entries of the rule node
            if not head.prev then
                -- first glyph in a list
                parent.list = r
            else
                head.prev.next = r
            end

            head.next.prev = r
            r.prev = head.prev
            r.next = head.next

            -- now the glyph points to
            -- nowhere and we should remove
            -- it from the memory
            node.free(head)

            head = r
        end
        head = head.next
    end
    return true
end

luatexbase.add_to_callback("post_linebreak_filter",showcharbox,"showcharbox")
\end{luacode*}

\newtheorem{theorem}{Jibberish}

\begin{document}
\pagestyle{headings}

That's fine until footnote:\footnote{Davidson witting and grammatic.}

\begin{theorem}
    \tolerance=10000\hbadness=10000
    This does not work.
\end{theorem}

That's fine again: Wash, Doff, and Algorithm.

\begin{itemize}
    \item Items work partially.
    \item Salutary.  Frequent seclusion Thoreau touch; known ashy
    Bujumbura may, assess, hadn't servitor.  Wash, Doff, and Algorithm.
\end{itemize}   
\end{document}

注意:当使用 book、article、scrbook 或 scrartcl 而不是 ucbthesis 类时,页码不会被加框。

奖金-MWE

它演示了有关图形标题的问题:

在此处输入图片描述

\documentclass[a4paper,10pt]{article}

\usepackage{luacode,luatexbase,microtype,blindtext}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")

-- head is a linked list (next/prev entries pointing to the next node)
-- parent it the surrounding h/vbox
function showcharbox(head,parent)
    while head do
        if head.id == 0 or head.id == 1 then
            -- a hbox/vbox
            showcharbox(head.list,head)
        elseif head.id == GLYPH_ID then
            r = node.new("rule")
            r.width  = head.width
            r.height = head.height
            r.depth  = head.depth

            -- replace the glyph by
            -- the rule by changing the
            -- pointers of the next/prev
            -- entries of the rule node
            if head.prev then
                head.prev.next = r
            else
                -- first glyph in a list
                parent.list = r
            end

            if head.next then
                head.next.prev = r
            end

            r.prev = head.prev
            r.next = head.next

            -- now the glyph points to
            -- nowhere and we should remove
            -- it from the memory
            node.free(head)

            head = r
        end
        head = head.next
    end
    return true
end

luatexbase.add_to_callback("post_linebreak_filter",showcharbox,"showcharbox")
\end{luacode*}

\usepackage{tikz}
\usepackage{blindtext}
\begin{document}

\blindtext

\begin{figure}[htb]
\centering
\begin{tikzpicture}
\edef\sizetape{1cm}
\tikzstyle{tmtape}=[draw,minimum size=\sizetape]
\node [tmtape] (input) {blabla};
\end{tikzpicture}
\caption{Hello World!}
\end{figure}

\blindtext

\end{document}

注意:页码也不再加框。

答案1

代码中有一个错误,导致 Lua 循环中断。我尝试过即使没有下一个指针也进行r赋值。修复方法是保护赋值:head.next.prevhead

if head.next then
     head.next.prev = r
end

所以代码是:

%% thesis.tex 2014/04/11
% Source: https://math.berkeley.edu/~vojta/thesis/
% Integrated into one single file, extended using topskip's luaCharBox-code
%
\documentclass{ucbthesis}
\usepackage{luacode,luatexbase,microtype,blindtext}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")

-- head is a linked list (next/prev entries pointing to the next node)
-- parent it the surrounding h/vbox
function showcharbox(head,parent)
    while head do
        if head.id == 0 or head.id == 1 then
            -- a hbox/vbox
            showcharbox(head.list,head)
        elseif head.id == GLYPH_ID then
            r = node.new("rule")
            r.width  = head.width
            r.height = head.height
            r.depth  = head.depth

            -- replace the glyph by
            -- the rule by changing the
            -- pointers of the next/prev
            -- entries of the rule node
            if head.prev then
                head.prev.next = r
            else
                -- first glyph in a list
                parent.list = r
            end

            if head.next then
              head.next.prev = r
            end

            r.prev = head.prev
            r.next = head.next

            -- now the glyph points to
            -- nowhere and we should remove
            -- it from the memory
            node.free(head)

            head = r
        end
        head = head.next
    end
    return true
end


luatexbase.add_to_callback("post_linebreak_filter",showcharbox,"showcharbox")
\end{luacode*}

\newtheorem{theorem}{Jibberish}

\begin{document}
\pagestyle{headings}

That's fine until footnote:\footnote{Davidson witting and grammatic.}

\begin{theorem}
    \tolerance=10000\hbadness=10000
    This does not work.
\end{theorem}

That's fine again: Wash, Doff, and Algorithm.

\begin{itemize}
    \item Items work partially.
    \item Salutary.  Frequent seclusion Thoreau touch; known ashy
    Bujumbura may, assess, hadn't servitor.  Wash, Doff, and Algorithm.
\end{itemize}
\end{document}

带有黑框的文本


回答附加问题:我不知道为什么标题没有调用post_linebreak_filter,也许它没有分成几行?!?

您可以使用该包atbegshi来获取页面的完整内容:

\documentclass[a4paper,10pt]{article}
\usepackage{luacode,atbegshi}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")

-- head is a linked list (next/prev entries pointing to the next node)
-- parent it the surrounding h/vbox
function showcharbox(head,parent)
    while head do
        if head.id == 0 or head.id == 1 then
            -- a hbox/vbox
            showcharbox(head.list,head)
        elseif head.id == GLYPH_ID then
            r = node.new("rule")
            r.width  = head.width
            r.height = head.height
            r.depth  = head.depth

            -- replace the glyph by
            -- the rule by changing the
            -- pointers of the next/prev
            -- entries of the rule node
            if head.prev then
                head.prev.next = r
            else
                -- first glyph in a list
                parent.list = r
            end

            if head.next then
              head.next.prev = r
            end

            r.prev = head.prev
            r.next = head.next

            -- now the glyph points to
            -- nowhere and we should remove
            -- it from the memory
            node.free(head)

            head = r
        end
        head = head.next
    end
    return true
end


\end{luacode*}
\AtBeginShipout {\directlua{showcharbox(tex.box["AtBeginShipoutBox"])}}%
\begin{document}

\begin{figure}
\fbox{x}
\caption{Hello World!}
\end{figure}
\end{document}

顺便说一句:请做一个下次我们再来。文档不需要,microtype也不tikz需要显示问题。甚至blindtext不需要。

相关内容