我已经编写了代码(在文章末尾给出),以纯 TeX 排版考试和测验。
典型的测试将使用以下方式排版:
\def\CLASS{Math 111}
\def\TERM{Spring 2015}
\def\TITLE{Quiz 3}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input examformat
\def\folio{}
\TestFormat
\HMarkbox
\def\ve{\vfill\eject}
\HowWide{\bf 22.}% space provided for problem numbers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\heading{\CLASS}{\TERM}{\TITLE}{}
\instructs{\bf This is a closed book, closed notes quiz.
To receive full credit for a problem,
your solutions must be complete, well-organized, and grammatically correct.
Partial credit will be given when merited.}
\problem{10} A farmer has $200$ feet of fence and wishes to construct a pen adjacent to a river. The side of the pen along the river requires no fence. ...
\ep
\problem{20}
Hello!
\ep
\problem{10}
A really long problem
\ve
blah
\ep
\problem{10} Last problem.
\ep
\bye
其结果如下:
标记框和问题编号是自动生成的。每个框\problem{#1}
都会将问题编号和值 ( #1
) 添加为标记框的一列。这是通过将文档的第一页保存在一个框中并在知道所有问题值后最后排版来完成的。这是通过重新定义 Plain Tex 的输出例程和\end
命令来实现的。
此外,如果问题跨页面出现,则会在页面的页脚和标题中指明。
我希望在 LaTeX 中做同样的事情。我是 LaTeX 新手,如果能提供任何建议,我将不胜感激。有没有一种简单的方法可以使用 LaTeX 中的内置函数来实现这一点?
(我更关心的是自动生成标记框,而不是“连续行”。)
对于那些敢于破译我下面的代码(虽然可行但可能很糟糕)的人:我可以在不进行太多修改的情况下使用 LaTeX 使其工作吗?
以下是纯 Tex 代码(即上面第一个代码块中文件“examformat”的内容):
\catcode`\!=11
\catcode`\@=11
\def\nskp{\nointerlineskip} \def\ts{\textstyle} \def\ds{\displaystyle}
\def\ss{\scriptstyle} \def\sss{\scriptscriptstyle}
\def\TF{{\bf T\thinspace F}} \def\DSP#1{$\ds{#1}$}
\def\INC#1{\advance#1by1 } \def\Z@{0 pt} \def\B!gPen{\penalty10000 }
\def\arcsec{\mathop{\rm arcsec}\nolimits}
\def\date{\ifcase\month\or
January\or February\or March\or April\or May\or June\or July\or August
\or September\or October\or November\or December\fi\space\number\day}
\def\blank#1{\underbar{\phantom{\hskip#1}}}
\def\name{{\bf NAME\thinspace}\blank{2.4 true in}}
\newif\ifbk!
\def\RmveDscrdItems{{\bk!true
\ifvmode \ifinner \else \let\unpenalty=\relax\let\unkern=\relax \fi \fi
\loop \unskip\unpenalty\unkern\unskip\unpenalty\unkern
\ifbk! \ifdim\lastskip=0.0pt \ifdim\lastkern=0.0pt \ifnum\lastpenalty=0
\bk!false \fi \fi \fi
\repeat \unskip\unpenalty\unkern \bk!true}}
%
% List/token manipulatuion routines
% See The TeXboox, pg. 378-379
%
\toksdef\ta=0 \toksdef\tb=2 %
\long\def\rightappend#1\to#2{\ta={\\{#1}}\tb=\expandafter{#2}%
\edef#2{\the\tb\the\ta}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\font\eightrm=cmr8
\def\Ntopskip{10pt}
% Fonts
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% formating routines
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newdimen\keyw!dth
\edef\HowWide#1{{\setbox0\hbox{#1}\global\keyw!dth\wd0}\ignorespaces}
\def\ccont{\hbox{\vtop{\offinterlineskip
\hbox{\sevenrm continued}\vskip1pt\hbox to 45 pt{\rightarrowfill}}}}
\def\ccontl{\hbox{\vtop{\offinterlineskip\hbox to 45 pt
{\hfil\sevenrm cont. from}\vskip1pt\hbox to 45 pt{\leftarrowfill}}}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% Format a test/problem sheet. Insert ``continued lines''.
%
%
\newif\ifT!tleP@ge \newif\ifF!T!TM \newif\ifM@rkBox
\newif\ifPr@@b \newif\ifFP@ \newif\ifT@stFMT
\newbox\PB@x \newbox\He@dBox \newbox\M@rkBox
\newbox\F!rstP@ge \newbox\!nstruct!onBox
\newskip\ITEMSKIP \newcount\Pr@blemNumber
\newdimen\IT@ \newdimen\IT@@
\def\TestFormat{\@@false\T@stFMTtrue\T!tleP@gefalse\M@rkBoxfalse\Pr@blemNumber0
\ITEMSKIP4pt\hsize6.5 true in\vsize9.0 true in\parindent0pt \parskip1pt
\raggedbottom\postdisplaypenalty1
\output{\plainoutput}%
\footline{\hfill\tenrm\folio\hfill\if y\botmark\rlap{\ccont}\fi}
\headline{\if y\topmark\llap{\ccontl}\fi\hfill}
\def\MarkBoxAdjust{0pt}
\def\problem{%
\ifPr@@b\errmessage{Missing \noexpand\ep.}\fi
\ifvmode
\ifinner\errmessage{\noexpand\problem not allowed in inner mode.}%
\else\SetProbl@m
\fi
\else\errmessage{\noexpand\problem not allowed outside vertical mode.}%
\fi}
\def\heading##1##2##3##4{\topskip\Z@ \topglue.5in
\ulap{\vbox to1in{\vfil\hbox to\hsize{\bf ##1\hfil\bf ##2}\kern8pt
\hbox to\hsize{\bf ##3\hfil\bf ##4}\vfil}}\hrule\vglue6pt}%
\def\instructs##1{\leavevmode\vskip10pt{\bf ##1}\vskip10pt}
\let\@ND=\end\def\end{{\if@@\@NDT\aftergroup\@ND\else\aftergroup\@ND\fi}}}
\def\SetProbl@m{\Pr@@btrue\F!T!TMtrue\global\advance\Pr@blemNumber1
\vskip18pt plus10pt minus12pt
\setbox\PB@x\vbox\bgroup\noindent
\llap{\rlap{\bf\the\Pr@blemNumber.}\hskip\keyw!dth}\indent
\vadjust{\mark{y}\B!gPen}\ignorespaces}
\newhelp\EXTR@EP{You have an extra \string\ep. This \string\ep\space will be ignored.}
\def\@RR@R#1#2{\errhelp=#1\errmessage{#2}}
\def\ep{%
\ifPr@@b\global\Pr@@bfalse\par\RmveDscrdItems\mark{n}\egroup\unvbox\PB@x
\else\@RR@R\EXTR@EP{Extra \string\ep}%
\fi}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% Titlepage/markboxes
%
%
\newcount\!! \newcount\!j
\def\ulap#1{\vbox to 0pt{\vss#1}}%
\newif\if@@
\def\HMarkbox{\@@true\m@rkbox\HMB@X\def\F@nt{\def\MB@F{\tenrm}\eightrm}}
\def\m@rkbox#1{\ifT@stFMT\else\errmessage{Missing \noexpand\TestFormat.}\fi
\ifM@rkBox\errmessage{You can only have one markbox.}\fi
\def\PL!ST{}\M@rkBoxtrue\let\Problem=\problem
\def\problem##1{\ifnum##1=0 \fi\rightappend{##1}\to\PL!ST\Problem}%
\def\M@kebox{\setbox\M@rkBox\vbox{#1\kern15pt}}%
\output{\F!rstOut}\topskip\Z@\topglue1in
\def\heading##1##2##3##4{%
\setbox\He@dBox\vbox to 1.5in{\vfil\hbox{\bf##1, ##2\hfill}\kern8pt
\hbox{\bf##3\hfill}\kern8pt\hbox{\name \hfil}\kern15pt}}%
}
\def\F!rstOut{\advancepageno
\global\setbox\F!rstP@ge=\vbox to\vsize{\dimen@=\dp255 \unvbox255
\ifr@ggedbottom \kern-\dimen@ \vfil \fi}%
\if y\botmark \global\FP@true \else \global\FP@false \fi
\global\output{\plainoutput}\global\topskip\Ntopskip}
\def\@NDT{%
\ifM@rkBox
\vfill\eject\M@kebox\gdef\ccontl{}%
\topskip0pt\topglue1 true in
\ulap{\hbox to\hsize{\box\He@dBox\hfill\box\M@rkBox}}%
\nskp\hrule\vskip-.4pt\vglue-1in\box\F!rstP@ge
\ifFP@\mark{y}\fi \global\pageno=1
\fi}
\def\HMB@X{%
\vbox{\!!=\Pr@blemNumber \advance\!!\!! \advance\!!1
\F@nt\tabskip=0pt\offinterlineskip\def\tablerule{\noalign{\hrule}}
\halign{\strut##&\vrule width.8pt##&&##&\vrule width.8pt##\cr
\tablerule
\omit\global\!j=1
\gdef\\##1{&\hbox to2em{\hfil\the\!j\hfil}&\global\INC\!j}%
&height1ex&\multispan\!!&\cr
&&\multispan\!!\hfil\MB@F Mark box\hfil&\cr
\omit&height1ex&\multispan\!!&\cr
\tablerule\tablerule
&&\kern.4em Problem\kern.4em&width.8pt\PL!ST\cr
\tablerule
&\gdef\\##1{&\hbox to2em{\hfil##1\hfil}&}%
&\kern.4em Points\kern.4em&width.8pt\PL!ST\cr
\tablerule
&\gdef\\##1{&\hbox to2em{\hfil}&}%
&\kern.4em Earned\kern.4em&width.8pt\PL!ST\cr
\tablerule\tablerule
\omit&height1ex&\multispan\!!&\cr
\omit&&\multispan\!!\kern.4em Perc. score:\hfill&\cr
\omit&height1ex&\multispan\!!&\cr
\tablerule}}}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\catcode`\!=12
\catcode`\@=12
\endinput
我希望以下内容能让您理解上述内容:
\TestFormat
设置页面尺寸参数和间距,我觉得很满意。它还设置了 和 ,\footline
如果\headline
问题跨页出现(通过插入顶部和底部标记来跟踪),则插入“继续”和“继续”。 \problem
此处定义为仅在需要时提供适当的错误消息,并通过 排版问题\SetProbl@m
。
\Setprobl@m
\problem(#1)
将问题编号增加 1,并排版“ ”和其后第一个“ ”之间的内容\ep
。它还会\ep
根据需要为“续行”插入顶部和底部标记。
\HMarkbox
调用\m@rkbox
并附带参数\HMB@x
。
\m@rkbox
然后定义一个宏\M@kebox
,该宏在展开时将排版标题,并使用宏排版标记框。实际的标记框是使用标记列表的内容展开时\HMB@x
生成的表格。 由文档中的 的参数生成(文档中的每个 都会添加到列表中)。\halign
\HMB@x
\PL!st
\PL!st
\problem
\problem{#1}
#1
\PL!st
\m@rkbox
将输出例程重新定义为\F!rstOut
。当第一页准备好时,\F!rstout
将页面内容复制到框中\F!rstP@ge
,不排版,并将输出例程设置为\plainoutput
(纯 TeX 中的默认值)。
\end
重新定义了普通的 TeX命令。调用时,它会扩展\@NDT
,从而扩展\M@kebox
并取消装箱\F!rstP@ge
。然后它会正确结束文档。