定义 \newcommand 中的换行规则

定义 \newcommand 中的换行规则

感谢这个答案,我定义了一个创建空白行的命令:

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

但是,由于这是用户定义的命令,LaTeX 似乎没有将其考虑在何时开始新行的计算中。例如,如果我写:

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

那么最后的空白行就会超出页面范围。我该如何防止这种情况发生?

编辑:这实际上只发生在特定情况下:当我在amsthm包的proof环境中时,我至少有一行文字后面跟着一个枚举。

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

即使空白行没有超出页面范围,我仍然会在证明中枚举overfull hbox每个实例时收到警告。\blank

答案1

如果您希望规则在无法放置在当前行时自动转到下一行,只需说

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

这是以\filbreakTeXbook 中的宏为模型的。

默认惩罚为 100,不鼓励换行。紧急情况下,您可以插入不同的惩罚作为可选参数:

 \blank[0]{3cm}

在此处输入图片描述

答案2

下面的例子显示了\IntRule,如果行中有足够的空间,它将在文本后立即排版规则;否则,该行将移至新行。主要代码来自 Martin Scharrer 对有没有办法测量一行文本的剩余空间?

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

在此处输入图片描述

答案3

linegoal包裹提供\linegoal给出线的剩余长度的尺寸。以@Gonzalo的答案为起点,这里有一个更短的替代方案:

在此处输入图片描述

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

由于linegoal最终使用zref,您需要编译几次(至少两次,也许三次)才能使savepos模块的 PDF 标签“稳定下来”。

相关内容