9

Thanks to the help of this answer, I've defined a command for creating a blank line:

\newcommand{\blank}[1]{\rule{#1}{0.4pt}}

However, because this is a user-defined command, LaTeX doesn't seem to factor it in to its calculations of when to start a new line. For example, if I write:

This is a long line and the blank line at the end is going to run off the page \blank{6cm}

then the blank line at the end runs off the page. How can I prevent this from happening?

EDIT: This actually only happens in a specific case: when I'm in the amsthm package's proof environment, and I have at least one line of writing followed by an enumeration.

\documentclass{article}
\usepackage{amsthm}
\newcommand{\blank}[1]{\rule[-3pt]{#1}{0.4pt}}  % nice blank underscores
\begin{document}
\begin{proof}
Here is my proof:
\begin{enumerate}
\item This is a long line and the blank line is going to run off \blank{8cm}
\item This is the second line.
\end{enumerate}
\end{proof}
\end{document}

Even when the blank line doesn't run off the page, I still get an overfull hbox warning for each instance of \blank I have within an enumerate in a proof.

3
  • 2
    Can you explain in more detail where is this line to appear? Do you want a line to fill the remaining space on a line, or a line to separate paragraphs? Dec 14, 2011 at 2:14
  • You're right, this only happens in a very specific case--when I'm in the amsthm package's proof environment, and I have at least one line of writing followed by an enumeration. I've edited the question to explain this. Dec 14, 2011 at 2:44
  • 1
    this could happen in any enumerate environment, not just within a proof with amsthm. (remove amsthm and the proof environment to demonstrate.) it's still a useful question though. Dec 14, 2011 at 13:54

3 Answers 3

10

If you want that the rule goes automatically on the next line if it can't be placed in the current one, just say

\newcommand{\blank}[2][100]{\hfil\penalty#1\hfilneg\rule[-3pt]{#2}{0.4pt}}

This is modeled on the \filbreak macro in the TeXbook.

The default penalty is 100, which discourages a line break. In cases of emergency you can insert a different one as optional argument:

 \blank[0]{3cm}

enter image description here

6
  • This actually automatically puts the rule on the next line, even if it COULD fit on the current one... Dec 14, 2011 at 16:02
  • 1
    @jamaicanworm Change -100 into 0
    – egreg
    Dec 14, 2011 at 16:05
  • In the following code, I'm still getting this problem: \documentclass{article} \newcommand{\blank}[1]{\hfil\penalty0\hfilneg\rule[-3pt]{#1}{0.4pt}} \begin{document} \begin{enumerate} \item We can write $A^n$ as \[ A^n = \bigcup_{a^{n-1} \in A^{n-1}} \{(a^{n-1}, a) \,:\, a \in A \}, \] which by the inductive hypothesis is a \blank{2cm} union of countable sets, so by Corrolary \blank{2cm}, $A^n$ is at most countable. But $A$ is infinite $\Rightarrow A^n$ is \blank{2cm}. \end{enumerate} \end{document} The blank between is a and union is on a new line, even thought there's space for it... Dec 14, 2011 at 16:25
  • 1
    @jamaicanworm See edit
    – egreg
    Dec 14, 2011 at 16:32
  • 1
    @jamaicanworm Change to 1000. You are putting too heavy requirements to the paragraph maker.
    – egreg
    Dec 14, 2011 at 16:54
4

The following example shows the definition of a \IntRule command which will typeset the rule immediately after the text if there's enough space in the line; otherwise, the line will be moved to a new line. The main code comes from Martin Scharrer's answer to Is there a way to measure the remaining space of a line of text?:

\documentclass{article}
\usepackage{amsthm}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{ifthen}

\newcommand{\currentsidemargin}{%
  \ifodd\value{page}%
    \oddsidemargin%
  \else%
    \evensidemargin%
  \fi%
}

\newlength\whatsleft

\newcommand\measureremainder[1]{%
\begin{tikzpicture}[overlay,remember picture]
    % Helper nodes
    \path (current page.north west) ++(\hoffset, -\voffset)
        node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\paperwidth, minimum height=\paperheight]
        (pagearea) {};

    \path (pagearea.north west) ++(1in+\currentsidemargin,-1in-\topmargin-\headheight-\headsep)
        node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\textwidth, minimum height=\textheight]
        (textarea) {};

    % Measure distance to right text border
    \path let \p0 = (0,0), \p1 = (textarea.east) in
        [/utils/exec={\pgfmathsetlength#1{\x1-\x0}\global#1=#1}];

\end{tikzpicture}%
}

\newcommand\IntRule[1]{%
  \measureremainder\whatsleft%
  \ifthenelse{\lengthtest{\the\whatsleft<#1}}{\mbox{}\\}{}\rule{#1}{0.4pt}}

\begin{document}

This is a long line and the blank line at the end is not going to run off\IntRule{6cm}

This is a short line \IntRule{6cm}

This is a long line and the blank line at the end is not going to run off\IntRule{1cm}

This is a short line \IntRule{\textwidth}

\begin{proof}
Here is my proof:
\begin{enumerate}
\item This is a long line and the black line is not going to run off \IntRule{8cm}
\item This is the second line.
\end{enumerate}
\end{proof}

\end{document}

enter image description here

1
  • This works, but might there be a simpler solution? Dec 14, 2011 at 5:24
3

The linegoal package provides the \linegoal dimension which gives the remaining length of a line. Taking @Gonzalo's answer as a start, here's a shorter alternative:

enter image description here

\documentclass{article}
\usepackage{amsthm}% http://ctan.org/pkg/amsthm
\usepackage{linegoal}% http://ctan.org/pkg/linegoal
\usepackage{ifthen}% http://ctan.org/pkg/ifthen

\newlength{\remainder}
\newcommand{\blank}[1]{%
  \setlength{\remainder}{\linegoal}% Store remaining line dimension
  \ifthenelse{\lengthtest{\the\remainder<#1}}{\mbox{}\\}{}\rule{#1}{0.4pt}}

\begin{document}

This is a long line and the blank line at the end is not going to run off\blank{6cm}

This is a short line \blank{6cm}

This is a long line and the blank line at the end is not going to run off\blank{1cm}

This is a short line \blank{\textwidth}

\begin{proof}
Here is my proof:
\begin{enumerate}
\item This is a long line and the black line is not going to run off \blank{8cm}
\item This is the second line.
\end{enumerate}
\end{proof}

\end{document}

Since linegoal ultimately uses zref, you need to compile a couple of times (at least twice, maybe three times) for the savepos module's PDF labels to "settle".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .