以编程方式将计数器设置为子字符串

以编程方式将计数器设置为子字符串

我正在尝试根据当前作业的名称设置一个计数器。通过\substring{\jobname}{5}{5}}使用stringstrings包之类的操作,我得到了我需要的数字,如果我将其输出到文档中,我就会看到正确的值。但是,天真地尝试将其用作参数会\setcounter失败,并出现错误“缺少数字,视为零”。我对 TeX 内部机制了解不够,无法明智地推测这里发生了什么,所以我只想问:我应该如何让它工作?

最小示例(保存为file3-example.tex):

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
% \substring{\jobname}{5}{5} % this outputs 3
\setcounter{section}{\substring{\jobname}{5}{5}} % this fails
\section{Foo}
\end{document}

答案1

正如前面所述,\setcounter{section}{..}必须仅包含扩展为数字的材料。我猜,字符串操作宏需要内部赋值,这使得它无法完全扩展,因此会导致错误。

我推荐使用这个xstring包。它的宏还可以将返回的字符串存储到(然后可扩展的!)宏中:

\documentclass{article}
\usepackage{xstring}
\begin{document}
\StrChar{\jobname}{5}[\mysubstring]%
% Or: (useful if the number would be two digits long
%\StrMid{\jobname}{5}{5}[\mysubstring]%
\setcounter{section}{\mysubstring}%
\addtocounter{section}{-1}% because it is incremented in \section
\section{Foo}
\end{document}

请注意,egreg 的答案非常好,不需要加载最有可能的大包。我只是想为喜欢的人展示一个 LaTeX 高级解决方案。

答案2

这是行不通的,因为的参数\setcounter在扩展后必须是一个数字,而的\substring必须执行许多计算,而这些计算需要与的语法不兼容的命令\setcounter

要访问第五个字符,\jobname您可以以间接的方式执行:

\def\extractfifth#1#2#3#4#5#6\relax{#5}

\setcounter{section}{\expandafter\extractfifth\jobname\relax}
\addtocounter{section}{-1}

第一行应该放在序言中。但是这样一来,该部分将是第 4 行,因为它\section会增加计数器。这就是以下内容的目的\addtocounter

答案3

stringstrings 工作得很好。关键是在[q]安静模式下使用 substring,这样结果就保存在变量中\thestring。然后,\thestring可以传递给 setcounter

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\jobname
\substring[q]{\jobname}{5}{5} % this outputs 3
\setcounter{section}{\thestring}
\section{Foo}
\end{document}

字符串实用性的关键在于能够产生简单(能够 edef)字符串的结果,而不是标记结果。

相关内容