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