# How to perform an action when an overfull or underfull box is encountered?

For a revision of a rather long document (based on book class), I'd like to not only mark overfull hboxes (easy thanks to the draft class option) but also to add a specific TOC entry (say "Look at the overfull hbox at this page!") when such an overfull hbox is encountered.

Moreover, I'd like to perform similar action for overfull vboxes, and underfull hboxes and vboxes.

I had a look at The LaTeX2e Sources and at the Standard Document Classes for LaTeX2e but couldn't find any way to perform an action when an overfull or underfull box is encountered. Do you see how this would be possible?

• I accept that you want visual mark-up but, of course, you can just read the log file:) – Andrew Oct 14 '17 at 9:32
• luatex is your only practical option here I suspect (or as Andrew says parse the log file) – David Carlisle Oct 14 '17 at 9:41
• no that warning isn't from latex it is from the guts of tex-the-program and not under the control of the macro layer, it's not even easy to tell from tex macros that a paragraph resulted in an overfull box at all, never mind change the behaviour if one is there. – David Carlisle Oct 14 '17 at 10:07
• adding hooks to tex internals is more or less a description of luatex of course, so in lua you do get callbacks and can write lua functions that are called as tex packages boxes that can add additional debugging. – David Carlisle Oct 14 '17 at 10:13
• @DenisBitouzé instead of sending the log file you can do the parsing first and send them the result. This way you aren't required to run the document with luatex if that is a problem for one or the other reason. (the parsing could be done even by TeX or lua as a separate step but only requiring the TeX installation then). – Frank Mittelbach Oct 15 '17 at 7:44

This luatex-only answer inserts some code (that I stole from the chickenize package) to insert text as a list of glyph and glue nodes at the end of any box that the hpack callback reports as over or under full.

It's just a sketch really but more or less works on this example.

\documentclass{article}
\makeatletter

\directlua{
GLYPH = node.id("glyph")
GLUE  = node.id("glue")
%
function hpackshow (indicator,num,nd,f,l)
print('HPACK: ' .. indicator .. ' ' .. num)
if (indicator == 'overfull' or indicator == 'underfull' ) then
if (indicator == 'overfull') then
local pt = num / 65536.0
str = string.format("| overfull \@percentchar #.2fpt",pt)
else
str = string.format("| underfull badness " .. num)
end
nds = {}
nds[0]=node.new(GLYPH,1)
for i = 1,string.len(str) do
nds[i] = node.new(GLYPH,1)
nds[i].font = font.current()
nds[i-1].next = nds[i]
end

j = 1
for s in string.utfvalues(str) do
local char = unicode.utf8.char(s)
nds[j].char = s
if unicode.utf8.match(char,"\@percentchar s") then
nds[j] = node.new(GLUE)
nds[j].width = space
nds[j].shrink = shrink
nds[j].stretch = stretch
end
j = j+1
end
return nds[0]
end
end
%
}
\begin{document}

somelongtextsomelongtext somelongtextsomelongtext somelongtextsomelongtext
somelongtextsomelongtext somelongtextsomelongtext somelongtextsomelongtext
somelongtextsomelongtext somelongtextsomelongtext somelongtextsomelongtext
somelongtextsomelongtext somelongtextsomelongtext somelongtextsomelongtext
somelongtextsomelongtext somelongtextsomelongtext somelongtextsomelongtext

\begin{minipage}{5cm}\fussy\parfillskip=0pt
onetwothree onetwothree
onezztzzzwothree onetwothree
onetwothree onetzzzzzwothree
onetzzzzwothree onetwothree
\end{minipage}

\end{document}

• Quite nice! Would be even nicer :) if we could have a table of (over|under)full (h|)vboxes, with the corresponding page numbers and, as you did here, with the corresponding length/badness. – Denis Bitouzé May 31 at 12:56
• @DenisBitouzé that's probably easy to to, just needs to store the value in some global lua table as you go past and then dump it out at the end (in the log or in the document?) – David Carlisle May 31 at 13:02