![如何制作自定义计数器显示类型?](https://linux22.com/image/272445/%E5%A6%82%E4%BD%95%E5%88%B6%E4%BD%9C%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AE%A1%E6%95%B0%E5%99%A8%E6%98%BE%E7%A4%BA%E7%B1%BB%E5%9E%8B%EF%BC%9F.png)
我是一名计算机科学教授,正在用 LaTeX 为我的学生准备考试,使用考試班。我喜欢在这里或那里开一些内部笑话。不幸的是,如果您尝试在问题上使用 0 索引(即,将计数器设置\thequestion
为初始值 -1),则类会中断。所以……我想通过制作自定义计数器来绕过这个问题展示,如\alph
,\roman
等,只输出比计数器少一的阿拉伯数字。
但是,这需要一些繁重的变量评估。我想做这样的事情:
\renewcommand{\thequestion}{\arabic{question - 1}}
但我不太了解 LaTeX 中的函数求值。有人知道吗,或者至少能告诉我从哪里开始?
答案1
所有计数器表示命令(例如\arabic
或)\alph
都调用关联的内部命令(\@arabic
或\@alph
),该命令将计数器表示的数字作为输入。对于计数器,这始终是名为 的<counter>
TeX 。方案始终如下:\count
\c@<ounter>
\def\cntformat#1{\expandafter\@cntformat\csname c@#1\endcsname}
\def\@cntformat#1{<do something with integer #1 that formats the number>}
其中\cntformat
代表类似于 的命令\arabic
。
我们的用户命令现在看起来像这样(使用\newcommand*
而不是\def
):
\newcommand*\arabicminusone[1]{\expandafter\@arabicminusone\csname c@#1\endcsname}
此命令接受一个参数(#1
,计数器名称),相关计数由此构建(\csname c@#1\endcsname
)。然后,这就是我们内部命令的参数\@arabicminusone
。为了构建\c@<counter>
前是由\@arabicminusone
后者解析的,需要在前面加上\expandafter
。
内部命令应将整数作为参数并简单地减一。有几种方法可以做到这一点,其中之一是 e-TeX 的\numexpr ... \relax
。\relax
严格来说, 不是强制性的,但不会造成任何损害。它可以防止\numexpr
进一步扫描,直到数字表达式结束并从输入流中删除。
\newcommand*\@arabicminusone[1]{\the\numexpr(#1)-1\relax}
有了这两个定义,您现在可以使用它来格式化计数器:
\newcounter{test}
\setcounter{test}{8}
\arabicminusone{test}% will print `7'
完整示例:
\documentclass{exam}
% make @ a letter so we can use it in names of command sequences:
\makeatletter
% call the internal \c@<counter> command and apply number formatting:
\newcommand*\arabicminusone[1]{\expandafter\@arabicminusone\csname c@#1\endcsname}
% number formatting:
\newcommand*\@arabicminusone[1]{\the\numexpr(#1)-1\relax}
% make @ other again:
\makeatother
\renewcommand*\thequestion{\arabicminusone{question}}
\begin{document}
\begin{questions}
\addpoints
\question[5] foo
\question[4] bar
\end{questions}
\gradetable
\end{document}
答案2
这里还有另一个想法,如果你只想抛出假问题,那么这些问题就不应该出现在\gradetable
。
\documentclass{exam}
\newcounter{display}
\begin{document}
\begin{questions}
\addpoints
\setcounter{display}{\value{question}}
\item[\arabic{display}.] (10 points) Fake question...
\question[10] A foo question
\question[10] A bar question
\setcounter{display}{\value{question}}
\item[\arabic{display}.] (10 points) Annutha fake question...
\end{questions}
\gradetable
\end{document}