我正在使用pgf
和enumitem
定义十六进制枚举方案如下:
\documentclass{article}
\usepackage{pgf,enumitem}
\makeatletter
\newcommand*{\Hex}[1]{%
\expandafter\@Hex\csname c@#1\endcsname
}
\newcommand*{\@Hex}[1]{%
\pgfmathdectoBase\The@Hex{#1}{16}\The@Hex
}
\AddEnumerateCounter{\Hex}{\@Hex}{E}
%------------------------------------------------------------
% Why does cutting this line cause it to fail?
%------------------------------------------------------------
\AtBeginDocument{\pgfmathdectoBase\The@Hex{1}{16}}
%------------------------------------------------------------
\makeatother
\begin{document}
\begin{enumerate}[label=\Hex*]
\item First
\item Second\addtocounter{enumi}{10}
\item Letters
\item More
\item Another
\item Ten!
\end{enumerate}
\end{document}
现在,如果我删除突出显示的行,编译就会失败,我不明白为什么。它告诉我:
! Undefined control sequence.
<argument> \The@Hex
我试图理解为什么需要定义这个宏才能使枚举工作,特别是因为的值\The@Hex
直到使用枚举重新定义后才真正被使用...
答案1
有一种方法可以避免赋值,使得转换为十六进制完全可扩展:
\input{binhex}
\newcommand*{\Hex}[1]{\expandafter\hex\csname c@#1\endcsname}
\AddEnumerateCounter{\Hex}{\hex}{E}
binhex.tex
作者是大卫·卡斯特鲁普 (David Kastrup)。
正如 Martin 所解释的那样, 的一个问题是\pgfmathdectoBase
执行分配,因此无法用于定义 的数字表示\ref
,因为系统必须使用\edef
( 的形式\protected@edef
)才能在辅助文件中写入实际数字,而不是命令。 根据您的定义,分配\label
给某个项目并尝试使用\ref
它会导致错误。
由于 anenumerate
可能不太长,因此可以使用
\newcommand{\Hex}[1]{\expandafter\@Hex\csname c@#1\endcsname}
\newcommand{\@Hex[1]{\ifnum#1>15 \@ctrerr\else\hexnumber@{#1}\fi}
也许可以扩大其定义\hexnumber@
以涵盖更多情况。
答案2
错误是由于标签代码应该是完全可扩展的而引起的。您的代码实际上很脆弱,导致\The@Hex
in\pgfmathdectoBase\The@Hex
在分配之前就被扩展(有一个\protected@edef
用于设置\@currentlabel
in \refstepcounter
.)。解决此问题的方法是更改宏的定义。正如 egreg 指出的那样,使宏变得健壮可以避免该错误,但在枚举项被编辑时会导致问题\label
。请注意,LaTeX 提供了可用于数字 0-15 的宏\hexnumber@
(有关更大的范围,请参阅 egreg 的答案)。