我的项目需要一个非常简单的关联数组,我正在尝试按照下面的 MWE 来实现它。
请问两个问题:
- 我需要如何调整我的
\alistget
宏以允许其结果在类似的函数中使用\DTMdate
? - 我该如何调试它?我已经仔细检查了具有
etoolbox
\csdef
和\csuse
功能的房子,但无济于事。
我并不真的想要类似“使用 xyz 实现关联数组”这样的解决方案,因为这对我来说是一个重要的学习经历!
\documentclass{article}
\usepackage[british]{datetime2}
\newcommand{\alistadd}[2]{
\expandafter\def\csname alist_#1 \endcsname{#2}
}
\newcommand{\alistget}[1]{%
\csname alist_#1 \endcsname%
}
\begin{document}
\alistadd{Tom}{1970-12-25}
Tom \alistget{Tom}\par
This works: Tom \expandafter\DTMdate\csname alist_Tom \endcsname\par
This doesn't: Tom \DTMdate{\alistget{Tom}}\par
\end{document}
答案1
expl3
您可以使用和来避免麻烦xparse
:
\documentclass{article}
\usepackage[british]{datetime2}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\xDTMdate}{m}
{% use the expanding variant
\dsla_xdtmdate:f { #1 }
}
% syntactic sugar
\cs_new_eq:NN \dsla_xdtmdate:n \DTMdate
% create the expanding variant
\cs_generate_variant:Nn \dsla_xdtmdate:n { f }
% better management with a property list
\NewDocumentCommand{\alistadd}{mm}
{
\prop_gput:Nnn \g_dsla_datelist_prop { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\alistget}{m}
{
\prop_item:Nn \g_dsla_datelist_prop { #1 }
}
\prop_new:N \g_dsla_datelist_prop
\ExplSyntaxOff
\begin{document}
\alistadd{Tom}{1970-12-25}
Tom \alistget{Tom}
This works: Tom \xDTMdate{\alistget{Tom}}
\end{document}
我定义了一个新\xDTMdate
命令,它对其参数执行“完全扩展直到可能”(也就是说,它完全扩展宏直到找到单个不可扩展的标记,这对于我们的目的来说已经足够了)。
使用 使命令\alistget
可扩展\prop_item:Nn
,这在此上下文中表现良好。实际上,您“手工制作”的属性列表也可以,但我认为最好坚持使用expl3
。
答案2
宏\DTMdate
在查找日期格式之前不会扩展其参数,因此您需要在调用宏之前进行扩展(两步)
\documentclass{article}
\usepackage[british]{datetime2}
\newcommand{\alistadd}[2]{%dont forget
\expandafter\def\csname alist_#1 \endcsname{#2}% these
}
\newcommand{\alistget}[1]{%
\csname alist_#1 \endcsname% this one isn't needed
}
\begin{document}
\alistadd{Tom}{1970-12-25}
Tom \alistget{Tom}\par
This works: Tom \expandafter\DTMdate\csname alist_Tom \endcsname\par
This doesn't: Tom
\expandafter\expandafter\expandafter\DTMdate
\expandafter\expandafter\expandafter{\alistget{Tom}}\par
\end{document}
第一步得到从\alistget{Tom}
到\alist_Tom
,第二步得到到1970-12-25
请注意,您的宏通过纯扩展来工作,因此您实际上无法做任何事情来使它们更有可能在另一个命令的参数中“起作用”,但与典型的编译语言不同,宏参数在调用宏之前不会扩展,所以没有办法。一般来说,使宏始终等同于其替换文本,这取决于调用宏的细节(\DTMdate
此处)。