问题描述
目前,我正在开发一个科学论文模板。目标是通过向用户提供一个或多个特定的设置命令来自动化许多繁琐的设置(如 pdf 元数据、样式/强调色、标题页等)。
第一个原型使用scrreprt
作为基文档类并komavars
用于存储/逻辑处理数据。在我看来,这种方法不仅有点“黑客”(因为komavars
通常只在文档类中定义scrlttr
,并且必须通过包加载到其他文档类中),而且最重要的是,必须通过例如scrletter
设置数十个的用户体验不是很好。 由于该项目旨在为初级/中级 LaTeX 用户带来更好的用户体验(目标受众不是必需的 LaTeX 粉丝,而是必须将其用于学术论文并且不习惯 LaTeX 的人),我想知道是否可以改变这一点。 第一次实验非常有希望。到目前为止,我可以实现我需要的所有功能而不会遇到问题。当前的功能实现原理显示在以下 MWE 中:komavars
\setkomavar{mt::author::name}{John Doe}
pgfkeys
\documentclass{minimal}
\usepackage{pgfkeys}
\pgfkeys{
/mt/.cd,
author/name/.initial,
author/place of birth/.initial,
}
\newcommand*\setup[1]{\pgfqkeys{/mt}{#1}}
\newcommand{\test}{%
\pgfkeysvalueof{/mt/author/name}, %
\pgfkeysvalueof{/mt/author/place of birth}%
}
\setup{
author/name=John Doe,
author/place of birth = New York
}
\begin{document}
\test
\end{document}
功能符合预期;但是,用户数据输入方法
\setup{
author/name=John Doe,
author/place of birth = New York
}
对于不喜欢 LaTeX 的人来说,感觉还是有点太笨重/笨拙。
问题:
是否有可能实现一种“类似字典”的子键输入法,而不需要进行大量解析xparse
?例如
\setup{
author = {
name = John Doe,
place of birth = New York
}
}
容易实现吗?
答案1
您可以定义 key/mt/author
以将其参数视为具有默认路径的键/mt/author
:
author/.code={\pgfqkeys{/mt/author}{#1}}
使用\pgfqkeys
而不是\pgfkeysalso
(或其等效/.style
处理程序),在 之后恢复默认路径\pgfqkeys
。
/mt/author
也可以定义为
author/.ecode={\noexpand\pgfqkeys{\pgfkeyscurrentpath}{#1}}
后一种情况比较棘手,但如果您有许多类似于/mt/author
要定义的关键节点,它可以节省您重复(当前)关键路径的时间。
\documentclass{minimal}
\usepackage{pgfkeys}
\pgfkeys{
/mt/.cd,
author/.code={\pgfqkeys{/mt/author}{#1}},
% or
% author/.ecode={\noexpand\pgfqkeys{\pgfkeyscurrentpath}{#1}},
author/name/.initial,
author/place of birth/.initial,
}
\newcommand*\setup[1]{\pgfqkeys{/mt}{#1}}
\newcommand{\test}{%
\pgfkeysvalueof{/mt/author/name}, %
\pgfkeysvalueof{/mt/author/place of birth}%
}
\setup{
author = {
name=John Doe,
place of birth = New York
}
}
\begin{document}
\test
\end{document}
排版
John Doe,纽约
答案2
使用内置的密钥处理程序也可以。无关,但不要对此类示例使用最小类,对于大多数情况来说,它太小了。
\documentclass{article}
\ExplSyntaxOn
\keys_define:nn{dsacre}
{
author .code:n = {\keys_set:nn {dsacre/author}{#1}},
author / name .tl_set:N = \l_dsacre_author_name,
author / place~of~birth .tl_set:N = \l_dsacre_author_birth,
}
\newcommand{\test}{%
\l_dsacre_author_name,~ %
\l_dsacre_author_birth%
}
\newcommand*\setup[1]{\keys_set:nn{dsacre}{#1}}
\ExplSyntaxOff
\begin{document}
\setup{
author/name=John Doe,
author/place of birth = New York
}
\test
\setup{
author = {
name = Jane Bar,
place of birth = London
}
}
\test
\end{document}
答案3
我是那些可能不喜欢 LaTeX 但我喜欢 TeX 的人之一。你建议的格式在\setup
我看来仍然有点太笨拙/笨拙,但我尝试使用 OpTeX 的键值宏来实现它。只是为了好玩。
\def\setup#1{\readkv{#1}%
\readkv{\expanded{\kv{author}}}%
\readkv{\expanded{%
mt/author/name=\kv{name},
mt/author/place of birth=\kv{place of birth}
}}
}
\def\test{%
\kv{mt/author/name},
\kv{mt/author/place of birth}.%
}
\setup{%
author = {%
name = John Doe,
place of birth = New York
}
}
\test % prints: John Doe, New York.
\bye
答案4
这个答案延伸Ulrike Fischer的expl3
回答l3keys
支持@Yiannis Lazarides 提到的伪点语法问题评论
author.name = <...>, author.place of birth = <...>
(在“属性名称”中看到空格很奇怪。)
伪点语法是通过提供自定义unknown
键来实现的。
pgfkeys
具有类似的处理程序,.unknown
因此也能够支持伪点语法。 中的完整键路径l3keys
是expl3
字符串的条件使 中的实现l3keys
更容易、更强大(无需寻找活动点.
)。
\documentclass{article}
\ExplSyntaxOn
\keys_define:nn{dsacre}
{
author .code:n = {\keys_set:nn {dsacre/author}{#1}},
author / name .tl_set:N = \l_dsacre_author_name,
author / place~of~birth .tl_set:N = \l_dsacre_author_birth,
unknown .code:n =
{
\str_replace_all:Nnn \l_keys_path_str {.} {/}
% \keys_set:ne { } % requires l3kernel 2023-10-10 or newer
\exp_args:Nne \keys_set:nn { }
{ \l_keys_path_str = { \exp_not:o { \l_keys_value_tl } } }
}
}
\newcommand{\test}{
\l_dsacre_author_name,~
\l_dsacre_author_birth
}
\newcommand*\setup[1]{\keys_set:nn{dsacre}{#1}}
\ExplSyntaxOff
\begin{document}
\setup{
author/name=John Doe,
author/place of birth = New York
}
\test
\setup{
author = {
name = Jane Bar,
place of birth = London
}
}
\test
\setup{
author.name = Tom,
author.place of birth = Tokyo
}
\test
\end{document}
输出 PDF 将包含三行主体
John Doe,纽约
Jane Bar,伦敦
Tom,东京
看起来 OP 很快就会要求一个便利界面来测试某些键中的每一个是否至少被用户设置过一次。