5

This is a follow-up question regarding topskip's answer:

topskip's code works very well, even for complex documents (containing tables, pagination, footnotes etc.), nevertheless, as the following screenshot demonstrates, some of these elements do not get boxed.

enter image description here

Question: Why isn't every letter boxed? What's wrong?

The screenshot is part of the result produced by this MWE (demo thesis, taken from berkeley):

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

Note: When using book, article, scrbook or scrartcl instead of ucbthesis class the page number does not get boxed.

Bonus-MWE

It demonstrates the problem regarding the figure caption:

enter image description here

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

Note: The page number isn't boxed any more, too.

  • _M_WE?......... – topskip Sep 15 '17 at 15:36
  • @topskip Sorry, my intention was to take a somewhat comp[ete|lex] document from stock. I reduced the mWE. – lAtExFaN Sep 15 '17 at 16:09
  • @topskip please have a look on the Bonus MWE I added: It should demonstrate the problem I mentioned regarding the figure caption. Thx a lot! – lAtExFaN Sep 16 '17 at 19:57
6

There is a bug in the code which causes the Lua loop to break. I have tried to assign r to head.next.prev even if head has no next pointer. The fix is to guard the assignment:

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

So the code is:

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

text with black boxes


To answer the bonus question: I don't know why the caption does not call the post_linebreak_filter, perhaps it is not broken into lines?!?

You can use the package atbegshi to get the complete contents of the page:

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

BTW: please make a M WE next time. The document doesn't need microtype nor tikz to show the problem. Even bindtext is not needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.