我正在用 ConTeXt 制作一本练习册。在整个练习册中,将有许多空间供所有者写下一两段简短的答案。这可能很简单,可能只是一个问题,后面跟着几条细的水平线,可以在上面写字。例如:
1. What was the most interesting part of the story?
__________________________________________________
__________________________________________________
__________________________________________________
__________________________________________________
__________________________________________________
__________________________________________________
TeX 或 ConTeXt 是否有任何标准方法来提供这样的空间?
TeX 或 ConTeXt 中是否有任何算法可以指定这些元素的正确印刷位置以及断行应该出现的位置?下面是一个例子(虽然不一定是理想的):
- 分页符不应放置在书写区域内,除非分页符前后的区域至少都有 3 行。
- 问题和书写区域之间不应设置分页符。
- 可以指定一个范围(例如 5 到 8 行),而不是指定确切的行数。例如,如果它打印了 5 行,但发现页面的其余部分是空的,它可以添加最多 3 行,直到页面填满。
答案1
除了 egregs 解决方案之外,我还想提出另一种具有更多 ConTeXtish 界面并支持最小值和最大值的解决方案。
警告:我没有广泛测试此代码,它可能会出现意外故障。
\def\startmyrules{%
\dosingleempty\dostartmyrules}
\def\dostartmyrules[#1]#2\stopmyrules{%
\bgroup
\define\linesleft{\numexpr(\pagegoal-\pagetotal)/\lineheight\relax}
\getparameters[MR][#1]
\setbox\scratchbox\vbox{#2}
\nobreak % avoid page break after head
\determinenoflines{\scratchbox}
% more space available then max lines + head
\ifnum\linesleft>\numexpr\MRmax+\noflines\relax
#2\crlf
\thinrules[n=\MRmax]
\else
% min lines + head doesn't fit on this page
\ifnum\linesleft<\numexpr\MRmin+\noflines+1\relax
\page
#2\crlf
\thinrules[n=\MRmax]
% remaining space is between min and max + head
\else
\scratchcounter\MRmax
\loop\ifnum\scratchcounter>\numexpr\MRmin-1\relax
\ifnum\linesleft>\numexpr\scratchcounter+\noflines\relax
#2\crlf
\thinrules[n=\scratchcounter]
\fi
\advance\scratchcounter by -1
\repeat
\fi
\fi
\egroup
}
证明它在一些简单情况下有效:
\starttext
\dorecurse{35}{\recurselevel\crlf}
\startmyrules [min=2, max=8]
1. What was the most interesting part of the story?
\stopmyrules
\page
\dorecurse{36}{\recurselevel\crlf}
\startmyrules [min=2, max=8]
1. What was the most interesting part of the story?
\stopmyrules
\page
\dorecurse{37}{\recurselevel\crlf}
\startmyrules [min=2, max=8]
1. What was the most interesting part of the story?
\stopmyrules
\stoptext
输出为:
算法如下:如果头部有足够的空间(行最……在本例中)和作为参数提供的最大行数,则打印它们。另一方面,如果没有足够的空间容纳最小行数(包括 head),则所有内容将移至另一页。如果介于两者之间,则调用循环来确定最佳行数。
答案2
这是一个尝试。可以添加一些代码以避免在打印三行之前或排版少于三行时出现断行。如果您不希望最后一行问题的其余部分有规则,则将的设置延迟\parfillskip=0pt
到循环之前,并将的前四行\stopplainlines
变成\par
。
\def\startplainlines#1{%
\par\begingroup
\parindent=0pt
\parfillskip=0pt
\def\numberoflines{#1}%
}
\def\stopplainlines{%
\unskip % emulate \par's behavior
\hskip.5em plus .2em minus .1em\nobreak\penalty-50 % insert a good break point
\hbox{}\nobreak %
\hrulefill\hbox{}\par % fill the remaining space with a rule
\nobreak % don't break a page here
\baselineskip=1.2\baselineskip
\count255=\numberoflines\relax
\loop\ifnum\count255>0 % produce the requested number of lines
\leavevmode\hrulefill\hbox{}\endgraf
\advance\count255 by -1
\repeat
\endgroup
}
\startplainlines{4}
Give a short proof of Fermat's last theorem
\stopplainlines
\bye