对 \hrulefill 与 \rule 以及段落中断感到困惑

对 \hrulefill 与 \rule 以及段落中断感到困惑

我有一个宏,用于在考试的填空题中插入一个空白,但当它位于一行的开头时,它会在空白后立即中断段落,其余的问题会向下移动。不过,当空白位于行的中间或末尾时,一切都正常。我可以让它不中断到新段落,但我必须在它前面放一个斜线空格,我不喜欢多余的空格。

我的宏是:

\newcommand{\plongblank}%
     {\hbox to 1.2in {\rule[.1in]{0in}{.15in}%
                 {\hrulefill}}}%

(如果该问题出现在问题的第二行或之后的行,这条规则是为了给学生提供书写空间。)

我发现并适应了这个答案由 egreg (谢谢!) 满足了我的需求,但我不明白为什么他的可以工作而我的却不行?我猜是惩罚和 +/- 拉伸,但我真的很想确切地知道原因。

为了完整起见,这里有一个 MWE:

\documentclass{article}

\newcommand{\plongblank}%
     {\hbox to 1.2in {\rule[.1in]{0in}{.15in}%
                 {\hrulefill}}}%
\newcommand{\blank}[2][100]{\hfil\penalty#1\hfilneg\rule[.1in]{0in}{.15in}%
                                                   \rule[-3pt]{#2}{0.5pt}}

% commenting this out makes the paragraph break evident
%\setlength{\parindent}{0pt}

\begin{document}

When passing parameters to a function by value, any changes that the function
makes to the parameters
\plongblank{}
%\blank{1.2in}
reflected in the variables passed to the function in the calling function.

\plongblank{}
%\ \plongblank{}
%\blank{1.2in}
describes the functionality in C++ where 2 or more functions share the same
name, and the determination of which function is called is based on the number
and/or type of parameters that are being passed.

\end{document}

答案1

TeX 每次都将排版对象放入一个列表中,并且每次都在水平(内部)、垂直(内部/外部)、段落(即外部水平)、数学(内部/显示)模式下工作。它更复杂,但为了理解基本原理,假设只有水平、垂直和段落模式。TeX 使用堆栈更改当前模式,并在每种模式下创建排版对象列表:在水平或段落模式下,它创建水平列表,在垂直模式下,它创建垂直列表。所以我们有一个带有列表的树。

在 开始时\hbox,TeX 打开水平(内部)模式并将对象放入\hbox水平列表中。在 结束时\hbox,TeX 关闭水平列表,创建一个包含此列表的框,退出水平模式并将创建的框作为单个对象放入“父”模式中当前创建的列表中。每当 TeX 看到 \vbox 时,它都会执行几乎相同的操作,但会打开并关闭垂直模式。

TeX 开始以垂直模式创建文档。如果当前处于垂直模式并且出现\indent\noindent\leavevmode单个字母,则打开段落模式。如果当前处于段落模式并且出现 或\par空行,则 TeX 结束段落模式:将创建的水平列表拆分为段落的行,并将这些行放入“父”垂直模式的垂直列表中。在垂直和段落模式之间切换是创建段落的基本原则。

现在假设一个例子:TeX 处于垂直模式,并且看到\hbox{abc}后面efg​​跟着空行。\hbox{abc}将作为单个框放入垂直列表中,然后单个字母e打开段落模式。 空行结束段落模式,创建一行带有缩进和efg字母的段落,并将此行放入“父”垂直模式的垂直列表中。 我们\hbox{abc}在这个垂直列表中后面跟着行<indent>efg。 最重要的是:它们在垂直列表中,因此它们是一秒之上。假设修改后的示例:\leavevmode\hbox{abc}efg。现在 TeX 首先打开段落模式,并将框和放入efg其水平列表中。重要提示:它们位于水平列表中,即它们将位于段落的一行中并排

用这个例子做实验并尝试理解这一点:

\levevmode % comment it or not
\hbox{abc}
efg
\par

模式切换是 TeX 的基本功能。不幸的是,大多数初学者手册都忽略了这一点。

答案2

尝试一个简单的可调长度规则\newcommand{\plongblank}[1]{\rule[-0.2ex]{#1}{0.15pt}}

对于您的特定应用,您可以将规则分成两部分,而不是让规则转到下一行并留下空白。

埃

\documentclass{article} 

\newcommand{\plongblank}[1]{\rule[-0.2ex]{#1}{0.15pt}}

% commenting this out makes the paragraph break evident
%\setlength{\parindent}{0pt}

\begin{document}            
    When passing parameters to a function by value, any changes that the function
    makes to the parameters \plongblank{3cm}
    reflected in the variables passed to the function in the calling function.
    
    \plongblank{5cm} describes the functionality in C++ where 2 or more functions share the same
    name, and the determination of which function is called is based on the number
    and/or type of parameters that are being passed.    
    
    This is a long line and the blank line   is  going to run off the page  \plongblank{2cm} \plongblank{3cm}.  
    
\end{document}

答案3

有两个问题:

(a)\hbox无法开始一个段落。如果你写,\leavevmode\hbox你将强制它开始一个段落。\hbox默认宽度将是包含材料的自然宽度。Wipet 的答案对各种模式有很好的解释,所以我就不在这里重复了。

(b)\dotfill产生引线,但您正在寻找“固定大小的可破坏引线”(如您在目录中看到的点)。您可以将其视为“可见胶水”。

这是使用 LuaTeX 的解决方案。取消注释您喜欢的行样式。我使用了“文本可见空间”,以便您可以看到发生了什么。诀窍是通过添加一个非常小的“1sp”空间来说服 TeX 断行。如果您不使用 LuaTeX,您可以使用 TeX“\loop .. \repeat”更改代码片段。由于很简单,这留给读者作为练习!

 \documentclass{article}
   \def\myleaders#1{
   \directlua{
   %local str = "\\_\\hskip1sp"    
    local str = "\\verb*+ +\\hskip1sp"
    local tstr = ""
    for i=1,#1 do
      tstr = tstr .. str
    end  
    tex.print("\\thinspace" .. tstr .. "\\thinspace")
   }}

   \begin{document}
   This is some text\myleaders{10} and this is some more \myleaders{30}

    When passing parameters to a function by value, any changes that the function
    makes to the parameters \myleaders{10}
    reflected in the variables passed to the function in the calling function.
    
    \myleaders{30} describes the functionality in C++ where 2 or more functions 
 share the same
    name, and the determination of which function is called is based on the number
    and/or type of parameters that are being passed.    
    
    This is a long line and the blank line   is  going to run off the page 
    \myleaders{30} 
    
    \myleaders{30}.  


    \end{document}

在此处输入图片描述

相关内容