\edef 中的更改计数器

\edef 中的更改计数器

\edef当我尝试使用更改计数器时\stepcounter,我收到一大堆错误消息(“缺少\endcsname插入”)。当我尝试使用 执行相同操作时,\addtocoutner没有收到任何错误,但计数器在 内保持不变\edef

以下 MWE 生成“E, EE, F”。如果删除%,将出现错误。

\documentclass{article}

\newcounter{testcount}
\setcounter{testcount}{5}

%\edef\foo{\Alph{testcount}\stepcounter{testcount}\Alph{testcount}}
\edef\bar{\Alph{testcount}\addtocounter{testcount}{1}\Alph{testcount}}

\begin{document}

\Alph{testcount}
,
\bar
,
\Alph{testcount}

\end{document}

\foo为什么会这样?我怎样才能达到所期望的效果\bar

答案1

如果你\show\bar在执行完后添加\edef,则会被告知

> \bar=macro:
->E\global \advance \c@testcount 1\relax E.

赋值在内部执行\edef,只有宏扩展。我们还有

% latex.ltx, line 2099:
\def\addtocounter#1#2{%
  \@ifundefined{c@#1}%
    {\@nocounterr{#1}}%
    {\global\advance\csname c@#1\endcsname #2\relax}}

因此第一个扩展将替换\addtocounter{testcount}{1}为替换文本;\@ifundefined是可扩展的,并且由于测试返回 false(因为\c@testcount已定义),因此您将得到

\global\advance\csname c@testcount\endcsname 1\relax

标记\global\advance是不可扩展的,因此 TeX 会扩展\csname,形成标记\c@testcount,而后者又是不可扩展的。因此,本质上,在两种情况下, 都只会\Alph{testcount}真正扩展为。E

您不能在“纯扩展”环境中完成作业。根据您的目标,可以设计其他东西。

\documentclass{article}

\newcounter{testcount}
\setcounter{testcount}{5}

\makeatletter
\edef\baz{%
  \Alph{testcount}\@Alph{\numexpr\value{testcount}+1\relax}%
  \unexpanded{\stepcounter{testcount}}%
}
\makeatother

\begin{document}

\Alph{testcount}
,
\baz
,
\Alph{testcount}

\end{document}

在此处输入图片描述

答案2

此答案基于此评论

\bar可以分两步定义。首先,使用计数器的当前值,并将扩展形式保存在 中\barI。然后增加计数器,因为赋值在可扩展上下文(如 )中不起作用\edef。增加的计数器值保存在 中\barII。最后,宏由和\bar组成。然后使用固定和扩展的计数器值定义 ,并在使用时让计数器保持不变。\barI\barII\bar

\documentclass{article}

\newcounter{testcount}
\setcounter{testcount}{5}

\edef\barI{\Alph{testcount}}
\stepcounter{testcount}
\edef\barII{\Alph{testcount}}
\edef\bar{\barI\barII}

\begin{document}

\setcounter{testcount}{1}

\Alph{testcount},
\bar,
\Alph{testcount},
\stepcounter{testcount}{\Alph{testcount}}

\end{document}

结果

答案3

这看起来像是一个典型的“问 X为了”问题。@egreg 已经解释了为什么您的方法\edef在概念上是错误的。当他发布答案时,我试图写下一种解决方法,以解决您在评论中似乎指出的原始问题。当我看到 @egreg 的答案时,我准备发布以下尝试,本质上是基于相同的原则。

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
% \usepackage[ascii]{inputenc}

\makeatletter

\@ifdefinable\@schtandard@SavedSection{%
    \let \@schtandard@SavedSection \section
}
\newenvironment*{NonStandardSectionNumbering}{%
    \renewcommand*\thesection{%
        \@arabic{\numexpr\value{section}-\@ne\relax}
        and~\arabic{section}%
    }%
    \renewcommand*\section{%
        \stepcounter{section}%
        \@schtandard@SavedSection
    }%
}{}

\makeatother



\begin{document}

\section{Normal numbering}
\label{S:1}
This section has normal numbering.

\section{Another one}
\label{S:2}
This too.

\begin{NonStandardSectionNumbering}
    \section{Special numbering}
    \label{S:3&4}
    Inside the \texttt{NonStandardSectionNumbering} environment, however,
    sections are numbered in a different way.

    \section{And again}
    \label{S:5&6}
    Some random text.
\end{NonStandardSectionNumbering}

\section{Back to standard numbering}
\label{S:7}
This section is again numbered in the normal way.

\section{Yet another section}
\label{S:8}
Note that the progression of section numbers is correct.  The references are
correct too: section~\ref{S:1}, section~\ref{S:2}, sections \ref{S:3&4},
sections \ref{S:5&6}, section~\ref{S:7}, and section~\ref{S:8}.

\end{document}

请记住,这只是一次未完成的试验:您应该更清楚地说明您想要实现的目标。

编辑: 我编辑了代码,添加了关于引用的注释。我还添加了一张显示输出的图片:

hte代码的输出

相关内容