我一直在研究自定义枚举标签的工作方式从 source2e.pdf 我得到:
\def\alph#1{\expandafter\@alph\csname c@#1\endcsname}
\def\@alph#1{
\ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or
k\or l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or
v\or w\orx\ory\or z\else\@ctrerr\fi}
我也一直在使用来自这个答案
\makeatletter
\newcommand{\greekalpha}[1]{\c@greekalpha{#1}}
\newcommand{\c@greekalpha}[1]{{
\ifcase\number\value{#1} \or α \or β \or γ \or δ \or\fi}}
\makeatother
因此,我以一种近乎加尔戈崇拜的方式尝试了我自己的希腊字母版本,看看会发生什么:
\makeatletter
\def\greekc#1{\expandafter\@greekc\csname c@#1 \endcsname}
\def\@greekc#1{\ifcase #1 \or α\or β\or γ\or δ\else\@ctreerr \fi}
\makeatother
不幸的是,在下面的例子中,它会产生一个错误:“缺失数字,视为零”:
\documentclass[11pt]{article}
\usepackage{amsfonts}
\usepackage{mathspec}
\setmathsfont(Digits,Latin,Greek)[Uppercase=Regular,Lowercase=Regular,] {Bookman Old Style}
\setmainfont{Bookman Old Style}
\usepackage{enumitem}
\begin{document}
\newcounter{greekctr}\stepcounter{greekctr}\stepcounter{greekctr}
\makeatletter
\def\greekc#1{\expandafter\@greekc\csname c@#1 \endcsname}
\def\@greekc#1{\ifcase #1 \or α\or β\or γ\or δ\else\@ctreerr \fi}
\makeatother
\makeatletter
\newcommand{\greekalpha}[1]{\c@greekalpha{#1}}
\newcommand{\c@greekalpha}[1]{%
{%
\ifcase\number\value{#1} \or α \or β \or γ \or δ \or\fi
}%
}
\makeatother
\noindent
\begin{itemize}
\item Value of counter: \thegreekctr
\item Alph counter :\alph{greekctr}
\item greekalpha: \greekalpha{greekctr}
\item greekc: \greekc{greekctr}
\end{itemize}
Working use in enumerate environment:
\AddEnumerateCounter*{\greekalpha}{\c@greekalpha}{γ}
\begin{enumerate}[label=\greekalpha*]
\item First
\item Second
\item Third
\item Fourth
\end{enumerate}
\end{document}
有人可以解释一下为什么我的例子不起作用以及其他两个例子起作用吗?
答案1
由于里面有一个多余的空格,所以您收到一个错误\csname...\endcsname
......
当你这样做时,\csname cs\endcsname
你定义了一个控制序列,\cs
因为 TeX 会忽略控制序列名称后的空格。但是当你这样做时\csname cs \endcsname
,空格后 cs
被认为是,并且您创建的控制序列实际上是\cs␣
(␣
表示空格)。
有趣的事实:许多命令在控制序列名称后使用空格来存储命令的“秘密”版本。例如,如果您创建一个文档并将其放入\show\cite
其中,您将看到:
> \cite=macro:
->\protect \cite .
那么你会问:\cite
但我看不到?的定义。\cite
是的,你可以!请注意,第二行后面有一个空格。要查看\cite␣
宏,请执行以下操作:
\expandafter\show\csname cite \endcsname
cite
:)后面有一个空格
另外,在α
、β
、γ
和之后还有一个多余的空格。我帮您把它们去掉了。这个空格不会导致错误,但在 pdf 中打印时会出现。δ
\c@greekalpha
\documentclass[11pt]{article}
\usepackage{amsfonts}
\usepackage{mathspec}
\setmathsfont(Digits,Latin,Greek)[Uppercase=Regular,Lowercase=Regular,] {Bookman Old Style}
\setmainfont{Bookman Old Style}
\usepackage{enumitem}
\begin{document}
\newcounter{greekctr}\stepcounter{greekctr}\stepcounter{greekctr}
% \tracingonline=1
% \tracingmacros=1
\makeatletter% V no space here!
\def\greekc#1{\expandafter\@greekc\csname c@#1\endcsname}
\def\@greekc#1{\ifcase #1 \or α\or β\or γ\or δ\else\@ctreerr \fi}
\makeatother
\makeatletter
\newcommand{\greekalpha}[1]{\c@greekalpha{#1}}
\newcommand{\c@greekalpha}[1]{%
{% v v v v And no spaces here
\ifcase\number\value{#1} \or α\or β\or γ\or δ\or\fi
}%
}
\makeatother
\noindent
\begin{itemize}
\item Value of counter: \thegreekctr
\item Alph counter :\alph{greekctr}
\item greekalpha: \greekalpha{greekctr}
\item greekc: \greekc{greekctr}
\end{itemize}
Working use in enumerate environment:
\AddEnumerateCounter*{\greekalpha}{\c@greekalpha}{γ}
\begin{enumerate}[label=\greekalpha*]
\item First
\item Second
\item Third
\item Fourth
\end{enumerate}
\end{document}
答案2
问题在于\csname c@#1 \endcsname
。 后面有一个空格#1
,因此例如如果#1
,section
则会导致\c@section
命令序列名称中的最后一个空格。 这没有定义,所以 TeX 会找到未定义的控制序列而不是导致错误的数字。 要解决这个问题,您必须删除 之前的空格\endcsname
。 之后的空格\csname
不同。 它不包含在命令序列的名称中,因为像 这样的命令序列之后的空格\csname
在充当命令序列名称的终止符后会被 TeX 吞噬。 它甚至是必要的,因为否则\csnamec@
会被解释为一个(未定义的)命令序列。