有人能告诉我为什么这有效吗
\documentclass{article}
\usepackage{etoolbox}
\newcounter{mylistcounter}
\newcommand{\getnthelement}[2]{
\setcounter{mylistcounter}{1}
\renewcommand*\do[1]{
\ifnumequal{\value{mylistcounter}}{#1}{##1\listbreak}\relax
\stepcounter{mylistcounter}}
\dolistloop{#2}}
\def\SerieID{HA}
\listadd\IDlist{HA}
\csgdef{\SerieID.DeckblattDatei}{test (HA)}
\def\SerieID{PR}
\listadd\IDlist{PR}
\csgdef{\SerieID.DeckblattDatei}{test (PR)}
\begin{document}
\def\SerieID{HA}
\csuse{\SerieID.DeckblattDatei}
\end{document}
但如果我把 \def 命令改为
\def\SerieID{\getnthelement{1}{\IDlist}}
我收到 \endcsname 错误
答案1
重新定义\getnthelement
采用第三个参数,作为包含搜索结果的宏的名称。
\newcommand{\getnthelement}[3]{%
\setcounter{mylistcounter}{1}%
\renewcommand*\do[1]{%
\ifnumequal{\value{mylistcounter}}{#1}{\def#3{##1}\listbreak}\relax
\stepcounter{mylistcounter}}%
\dolistloop{#2}}
注意使用%
以避免引入虚假空格。
用法:
\getnthelement{1}{\IDlist}\SerieID
\csuse{\SerieID.DeckblattDatei}
但是,这个解决方案很脆弱:搜索返回的材料应该是可扩展的,否则\csuse
会再次出现错误。此外,如果搜索失败(因为列表太短),\SerieID
则将未定义或包含一些旧值。
答案2
你可以使用序列,而不用etoolbox
列表,因为列表很难获取项目expl3
。
\documentclass{article}
\usepackage{etoolbox}
\ExplSyntaxOn
\NewDocumentCommand{\definelist}{m}
{
\seq_new:c { l_gaweiliex_list_#1_seq }
}
\NewDocumentCommand{\addtolist}{mm}
{
\seq_put_right:cn { l_gaweiliex_list_#1_seq } { #2 }
}
\NewExpandableDocumentCommand{\getfromlist}{mm}
{% #1 = list name
% #2 = item number
\seq_item:cn { l_gaweiliex_list_#1_seq } { #2 }
}
\ExplSyntaxOff
\definelist{IDlist}
\addtolist{IDlist}{HA}
\csdef{HA.DeckblattDatei}{test (HA)}
\addtolist{IDlist}{PR}
\csdef{PR.DeckblattDatei}{test (PR)}
\begin{document}
\edef\SerieID{\getfromlist{IDlist}{1}}
\csuse{\SerieID.DeckblattDatei}
\edef\SerieID{\getfromlist{IDlist}{2}}
\csuse{\SerieID.DeckblattDatei}
\end{document}