1

I am trying to create a macro which should have the following behaviour:

  • Write the mathematical expression with the inline mode \( \) if it doesn't give rise to an overfull \hbox warning,
  • Write the same expression in an dmath environment (from the breqn package) if the first option gives rise to an overfull \hbox warning.

My problem is to detect the overfull \hbox and then to set a variable to true or false in order for the macro to act consequently. Here is my macro:

\newcommand{\mymath}[1]{%
\newif\iftest%
\testfalse
\iftest
 \(#1\)
\else
: \begin{dmath}#1\end{dmath}
\fi}

What should I put instead of the \testfalse line (which is here only for example purpose) in order to achieve the desired behaviour?

  • The overfull box is detected only when the paragraph is being split into lines, so too late. TeX considers a paragraph in its entirety before deciding where to break lines, it doesn't simply fill one line and go to the next. Even if this were possible, changing the inline math to a display will, by Murphy's law, produce another overfull somewhere else, maybe before the one that's being ‘fixed’. – egreg Jul 16 '13 at 10:53
  • @egreg Then is it possible with multiple compilations to get to the information of the output file and change the automatically the behaviour of the macro? – Ludovic C. Jul 16 '13 at 10:55
  • 2
    Maybe. Fixing bad paragraphs containing lots of inline math is a tedious task, but “display-what-doesn't-fit” is not the answer. – egreg Jul 16 '13 at 10:59
2

Thanks to the egreg's comments I realized that it was not easy at all to detect \overfull \hbox warning when compiling the code. That is why I decided to develop a small script which compile the .tex file, detect the overfull \hbox warning linked to the use of the macro and adapt the .tex file before recompiling.

TeX file used for the demonstration

\documentclass[draft]{article}

\usepackage{lipsum}
\usepackage[demo]{graphicx}
\usepackage{breqn}

\newif\ifoverfullbox%
\newcommand{\mymath}[1]{%
\ifoverfullbox
: \begin{dmath}#1\end{dmath}
\else
 \(#1\)
\fi}
\overfullboxfalse

\begin{document}
\lipsum[1]

Here-is-a-definition-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.

\begin{figure}[!h]
\includegraphics[width=15cm,height=3cm]{blabla}
\end{figure}

Here-is-a-\mymath{and again}-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.

\end{document}

Output before using the script

Output before the script

This example produces 3 warnings:

  • The first one is due to the use of the macro at the end of a line and TeX does not know how to break the line,
  • The second one is due to a too wide figure,
  • The third one is similar to the first but contains two calls to the macro.

TeX file after using the script

The preamble is exactly the same

\begin{document}
\lipsum[1]

\overfullboxtrue Here-is-a-definition-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.\overfullboxfalse

\begin{figure}[!h]
\includegraphics[width=15cm,height=3cm]{blabla}
\end{figure}

Here-is-a-\mymath{and again}-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.

\end{document}

There are two new elements: the variable overfullbox is set to true at the beginning of the line containing one call to the macro and is reset to false at the end of this line.

Output after using the script

Output after the script

Thanks to the script one Overfull \hbox warning disappeared.

The script

#!/bin/bash
FILENAME=$1
MYCMD=$2
TEXCMD="pdflatex -interaction=batchmode"
OUTFILE=${FILENAME}_overfull_correction.txt
eval "rm $OUTFILE"
echo "This is the report file from the overfull \hbox correction for the $FILENAME.tex file." >> $OUTFILE
eval "$TEXCMD $FILENAME.tex"
OBOXES=( $(fgrep 'Overfull' $FILENAME.log | grep -o 'lines.*--'| grep -P '\d*' -o) )
COUNTER=$(fgrep 'Overfull' $FILENAME.log | grep -o 'lines.*--'| grep -P '\d*' -oc)
echo " " >> $OUTFILE

for ((ii=0;ii<COUNTER;ii++))
do
TEST=$(sed "${OBOXES[$ii]}q;d" $FILENAME.tex | grep -o "$MYCMD" | wc -l)
if [ "$TEST" == "0" ]
then
echo "Overfull \hbox warning not due to $MYCMD line ${OBOXES[$ii]}" >> $OUTFILE
fi
if [ "$TEST" == "1" ]
then
eval "sed -i '${OBOXES[$ii]}s/^/\\\overfullboxtrue /' $FILENAME.tex"
eval "sed -i '${OBOXES[$ii]}s/$/\\\overfullboxfalse/' $FILENAME.tex"
echo "Overfull \hbox warning corrected line ${OBOXES[$ii]}" >> $OUTFILE
fi
if [ "$TEST" == "1" -a "$TEST" == "0" ]
then
echo "More than one occurence of the $MYCMD command line ${OBOXES[$ii]}" >> $OUTFILE
fi
done

eval "$TEXCMD $FILENAME.tex"
COUNTER2=$(fgrep 'Overfull' $FILENAME.log | grep -o 'lines.*--'| grep -P '\d*' -oc)
echo "Recompiled file, $COUNTER2 Overfull \hbox warning(s) remaining" >> $OUTFILE
echo "Process exited normally" >> $OUTFILE
exit

Briefly how it works:

  • First it compiles the .tex file and writes the header of a report file.
  • It counts and store the line of the .tex file giving rise the Overfull warning in the .log file.
  • It performs a loop on these lines where for each warning:
  • If it does not come from the specified command, it writes it in the report file and goes to the next iteration,
  • If there are more than one call of the macro on the concerned line, it writes it in the report file and goes to the next iteration ,
  • If there is one call of the macro in the concerned line, it adds \overfullboxtrue at the beginning of this line and \overfullboxfalse at the end.
  • It recompiles the .tex file and writes in the report file the number of remaining Overfull warnings.

Good and Bad aspects

For the good ones I let you judge how this might help to fix some warnings, however I would like to highlight some drawbacks (maybe you'll have some idea to fix them?):

  • You will need to go and change manually your .tex file to fix all the other warnings anyway...
  • Switching from inline mode to the dmath environment may seem awkward concerning the way you had written the sentences around the mathematical expression, and you may need to rephrase your paragraph.
  • ...

How to use the sript

Copy-paste the code above into a .sh file in the same repertory as your .tex document. From a terminal run chmod +x <name>.sh to modify the execution rights of the file. Finally, assuming your .tex file is called foo.tex call it from your terminal with ./<name>.sh foo <name_of_the_macro>.

If you have any suggestions to improve it do not hesitate (especially if they concern the bash code because I am a newbie with this language), I will gladly update it!

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.