我正在使用循环来定义xkeyval
包中的键,以及实际读取某些自定义命令中的键。一切都运行正常 - 但出于某种原因,只要我包含hyperref
,一切都会中断:
! Incomplete \ifnum; all text was ignored after line 47.
<inserted text>
\fi
请考虑以下 MWE:
\documentclass{article}
\usepackage{xkeyval}
\usepackage{hyperref} % <-- comment this line to make it work
\makeatletter
\count@=0
\loop
\advance\count@ 1
\begingroup\edef\x{\endgroup
\noexpand\define@key{mycmd}{KEY\the\count@}[]{%
\noexpand\@namedef{mycmdKEY\the\count@}{####1}%
}% end of \define@key
}% end of \edef
\x % execute \x
\ifnum\count@<6
\repeat
\presetkeys{mycmd}{KEY1=0,KEY2=0,KEY3=0,KEY4=0,KEY5=0,KEY6=0,%
}{}
\newcount\mycount%
\newcounter{mycnt}
\newcommand*\mycmd[2][]{%
\setkeys{mycmd}{#1}{
\begin{enumerate}
\mycount=0%
\loop%
\advance\mycount 1%
\setcounter{mycnt}{\csname mycmdKEY\the\mycount\endcsname}%
\ifnum\value{mycnt}>0%
\item[item \the\mycount] text
\fi%
\ifnum\mycount<6\repeat%
\end{enumerate}
}%
}%
\makeatother
\begin{document}
\mycmd[
KEY1=200,
KEY2=200,
KEY3=500,
KEY4=1000,
]{}
\end{document}
以下是我的观察:
- 如果我删除对的依赖
hyperref
,它就可以起作用。 - 如果我删除
enumerate
环境并\item
用其参数替换对它的调用,它也会起作用。 - 如果我删除对的调用并用
setkeys
替换字符串,它也会起作用。\csname mycmdKEY\the\mycount\endcsname
1
这一切对我来说似乎很奇怪。如果有人能告诉我我做错了什么以及我可以做些什么来修复它,那就太好了!
PS:如果你想知道我最初是如何想出这个代码的:这个问题是基于我之前的一个问题的后续问题:在循环中定义 xkeyval 键
答案1
你的代码中有几个错误%
。在常量后一定要留一个空格(或者添加\relax
。特别是错误的是
\ifnum\value{mycnt}>0%
\item[item \the\mycount] text
\fi%
当 TeX 想要执行此检查时,它会扩展\item
以查看是否还有其他数字。在hyperref
加载的情况下,第一级扩展\item
是
\@hyper@itemfalse\if@nmbrlist\@hyper@itemtrue\fi\H@item
但 TeX 并没有停止扩展,并发现
\let\if@hyper@item\iffalse
添加二输入流中的条件。不过,此时 TeX 确定数字实际上为零。如果mycnt
大于零,\let\if@hyper@item\iffalse
则成为假文本的一部分,并且\fi
与匹配\iffalse
,因此\ifnum
未完成。
正确代码:
\documentclass{article}
\usepackage{xkeyval}
\usepackage{hyperref}
\makeatletter
\count@=0
\loop
\advance\count@ 1
\begingroup\edef\x{\endgroup
\noexpand\define@key{mycmd}{KEY\the\count@}[]{%
\noexpand\@namedef{mycmdKEY\the\count@}{####1}%
}% end of \define@key
}% end of \edef
\x % execute \x
\ifnum\count@<6
\repeat
\presetkeys{mycmd}{KEY1=0,KEY2=0,KEY3=0,KEY4=0,KEY5=0,KEY6=0,%
}{}
\newcount\mycount%
\newcounter{mycnt}
\newcommand*\mycmd[2][]{%
\setkeys{mycmd}{#1}{%
\begin{enumerate}
\mycount=0
\loop
\advance\mycount 1
\setcounter{mycnt}{\csname mycmdKEY\the\mycount\endcsname}%
\ifnum\value{mycnt}>0
\item[item \the\mycount] text
\fi
\ifnum\mycount<6
\repeat
\end{enumerate}
}%
}%
\makeatother
\begin{document}
\mycmd[
KEY1=200,
KEY2=200,
KEY3=500,
KEY4=1000,
]{}
\end{document}