盒子是否自动调整大小以到达行尾?

盒子是否自动调整大小以到达行尾?

我正在设置一个小测试,其中包括供学生写下答案的空框。

这些框从页面上的不同位置开始,但为了整洁,我希望每个框都到达行尾。我正在使用

\newcommand{\answerbox[2]{\raisebox{2mm}{%
    \fbox{%
          \begin{minipage}[t]{#1}%
              \hfill\vspace*{#2}%
          \end{minipage}
         }
    }
}

效果很好,但我必须猜测框的宽度(第一个参数)。有没有巧妙的方法使用规则并hfill做到这一点?

答案1

希望有人能来改进这一点。但这只是一个开始。

一个技巧是使用构造:

$$\xdef\pds{\the\predisplaysize}$$

这将获取到上一行结束处的宽度(进行了一些调整,有关详细信息,请参阅“TeX by Topic”的第 24.3 节)。这似乎是一种奇怪的方法,但这就是如何将其付诸实践:

\newcommand\answerbox[1]{%%
  \bgroup 
    \abovedisplayskip0pt%%
    \belowdisplayskip0pt%%
    \abovedisplayshortskip0pt%% 
    \belowdisplayshortskip0pt%%
    $$\xdef\pds{\the\predisplaysize}$$%
  \par\prevdepth0pt{\par\kern-2\baselineskip\parskip0pt}%%
  \noindent
  \kern\pds\kern-2em\fbox{%%
    \rule{\dimexpr\linewidth-\pds+2em-2\fboxrule-2\fboxsep}{0pt}%%
    \rule{0pt}{#1}}%%
  \egroup}

在此,分组是必要的,以将\abovedisplayskip等的调整值限制在宏的范围内。

关于的调整2em,请参见 TeX by Topic 的第 24.3 节。

\documentclass{article}
\usepackage{pgffor}
\setlength\parindent{0pt}
\usepackage{lipsum}

\newcommand\answerbox[1]{%%
  \bgroup 
    \abovedisplayskip0pt%%
    \belowdisplayskip0pt%%
    \abovedisplayshortskip0pt%% 
    \belowdisplayshortskip0pt%%
    $$\xdef\pds{\the\predisplaysize}$$%
  \par\prevdepth0pt{\par\kern-2\baselineskip\parskip0pt}%%
  \noindent
  \kern\pds\kern-2em\fbox{%%
    \rule{\dimexpr\linewidth-\pds+2em-2\fboxrule-2\fboxsep}{0pt}%%
    \rule{0pt}{#1}}%%
  \egroup}

\begin{document}

\foreach \myn in {0,5,10,15,20,25}
  {
    \par
    \foreach \myk in {0,...,\myn} {a }%%
    \answerbox{2ex}\vspace{2ex}%%
  }

\lipsum[1-2]

\end{document}

在此处输入图片描述

pgffor和的使用lipsum仅仅是为了演示,对于宏来说不是必需的\answerbox

答案2

您可以\linegoal使用linegoal包中计算剩余空间(编译两次文档):

\documentclass{article}
\usepackage{linegoal}
\usepackage{lipsum}% just to have filler text

\newcommand\answerbox[1][0.5\ht\strutbox]{\raisebox{0.25\height}{%
  \fbox{\begin{minipage}[t]{\dimexpr-\fboxsep-\fboxrule+\linegoal\relax}%
    \mbox{}\rule{0pt}{#1}%
  \end{minipage}%
    }%
  }%
} 

\begin{document}

\noindent
test \answerbox

\noindent
other test text \answerbox

\noindent
some other test with a longer text \answerbox

\lipsum[4]

\end{document}

在此处输入图片描述

答案3

这里我使用 制作了一个盒子\cleaders。参数\boxht\boxdp\rulewidth可由用户设置。

为了确保框后不会挤入任何附加文本,后面\boxfill应该跟一个\par(正如我在这里所做的那样)或一个\\

已编辑,以消除对包的需要。

\documentclass{article}
\usepackage{lipsum}
\newcommand\rulewidth{1pt}
\newcommand\boxht{2ex}
\newcommand\boxdp{3pt}
\newcommand\boxfill{%
  \let\replength\rulewidth
  \def\laprule{\rule[-\boxdp]{\rulewidth}{\dimexpr\boxht+\boxdp+\rulewidth\relax}}%
  \makebox[0pt][l]{\laprule}%
  \cleaders\hbox to \replength{%
    \ooalign{\rule[-\boxdp]{\replength}{\rulewidth}\cr%
             \rule[\boxht]{\replength}{\rulewidth}}}\hfill%
  \makebox[0pt][r]{\laprule}%
}
\begin{document}
A test\boxfill\par
This is another test of the fill when it doesn't begin on the first
line of a paragraph.\boxfill\par
\boxfill\par
\lipsum[1]
\end{document}

在此处输入图片描述

答案4

这里有一个zref(模块savepos)实现:

在此处输入图片描述

\documentclass{article}
\usepackage{zref-savepos,lipsum}
\newcounter{boxmarker}% Position marker counter
\newcommand{\boxfill}{%
  \leavevmode% Just in case...
  \stepcounter{boxmarker}% To avoid multiple references
  \zsaveposx{boxmarkerL\theboxmarker}% Save left location
  \hfill
  \zsaveposx{boxmarkerR\theboxmarker}% Save right location
  \llap{% Left overlap
    \fbox{% framed box
      \rule{0pt}{.5\baselineskip}% Vertical strut
      \rule{\dimexpr\zposx{boxmarkerR\theboxmarker}sp-\zposx{boxmarkerL\theboxmarker}sp-2\fboxsep-2\fboxrule}{0pt}% Horizontal strut
    }%
  }%
}
\begin{document}
A test \boxfill

This is another test of the fill when it doesn't begin on the first
line of a paragraph. \boxfill

\boxfill

\lipsum[1]

\end{document}

上述方法使用了一些技术跳至行上的绝对位置。本质上,两个位置通过调用 进行标记和标注\boxfill。这些<label>s 将标记的 x 坐标存储在 中.aux,通过 进行检索\zposx{<label>},然后用于计算线上的余数。

因为它使用 TeX 的\label-\ref系统,所以您必须在开始时至少编译两次,并且每次后续调整标记位置时也必须编译两次(以允许引用稳定下来)。

相关内容