我正在考虑创建一个包来管理书籍的一些元数据(如作者、标题等)。此元数据将在外部文件中定义并在文档中检索。(这与 PDF 元数据概念无关!)。如果元数据仅由value
变量组成,那就很容易了(解决方案如下为变量赋值并检索以供日后使用的推荐方法是什么?使用 l3prop 即可)。但就我而言,我想指定一些行为,例如,当value
元数据为空时。我想分配一个宏,当检索到的值但为空时执行该宏。
元数据文件的语法如下:
\setmetadata{author}{The name of the author}
\setmetadata[ifempty=\throwerror]{title}{The title}
并且value
将在文档中检索 s
\getmetadata{author}
为了实现这一点,我想知道 latex3 数据表l3dt
模块是否有用。但它似乎已从代码树中删除。我的下一个方法是l3prop
在 a 内使用 a l3prop
。但在深入研究之前,是否可以嵌套属性列表?
答案1
这能回答你的问题吗?实际上,你不需要在属性列表中添加属性列表。
\begin{filecontents*}{\jobname.input.tex}
\setmetadata{author}{The name of the author}
\setmetadata[ifempty=\throwerror]{title}{The title}
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\keys_define:nn { metadata }
{
ifempty .tl_set:N = \l_metadata_ifempty_tl
}
\prop_new:N \g_metadata_prop
\cs_new_protected:Nn \metadata_gset:nn
{
\tl_if_empty:nTF { #2 }
{
\tl_if_empty:NF \l_metadata_ifempty_tl
{ \tl_use:N \l_metadata_ifempty_tl }
}
{ \prop_gput:Nnn \g_metadata_prop { #1 } { #2 } }
}
\cs_new_protected:Nn \metadata_get:n
{
\prop_item:Nn \g_metadata_prop { #1 }
}
\NewDocumentCommand \setmetadata { o m m }
{
\group_begin:
\IfValueT { #1 }
{ \keys_set:nn { metadata } { #1 } }
\metadata_gset:nn { #2 } { #3 }
\group_end:
}
\NewDocumentCommand \getmetadata { m }
{
\metadata_get:n { #1 }
}
\ExplSyntaxOff
\begin{document}
\def\throwerror{***ERROR***}
\input{\jobname.input.tex}
\getmetadata{author}
\getmetadata{title}
\setmetadata[ifempty=\throwerror]{title}{}
\end{document}
或者使用 LuaTeX?这提供了一种格式化输入文件的好方法。您还可以使用 Lua 在外部处理数据库。
\begin{filecontents*}{\jobname.input.lua}
return {
["author"] = "The name of the author",
["title"] = "The title"
}
\end{filecontents*}
\documentclass{article}
\directlua{db = dofile"\jobname.input.lua"}
\def\getmetadata#1{\directlua{tex.sprint(db["\luaescapestring{#1}"]
or "\noexpand\\throwerror")}}
\begin{document}
\def\throwerror{***ERROR***}
\getmetadata{author}
\getmetadata{journal}
\end{document}