这是这个问题。简而言之,我想从外部文件加载要提供给的参数\pgfkeys
,但这并不简单。
下面是我尝试执行的操作的一个例子,但由于出现许多奇怪的错误消息,该操作无法完成:
\begin{filecontents}{keys.def}
key = {
Hellò
}
\end{filecontents}
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfkeys}
\pgfkeys{
/mykeys/key/.initial = {}
}
\pgfqkeys{/mykeys}{
\input{keys.def}
}
\begin{document}
Values: \pgfkeysvalueof{/mykeys/key}
\end{document}
如您所见,我需要加载文件的内容as-is
(因此尝试使用\input
)并将其提供给\pgfkeys
命令。
用例如下:我想让我的类可扩展,所以我定义了一个离散的键数,并且我希望它可以通过外部文件进行配置。这不是在排版文档的上下文中完成的,而是在一个更复杂的系统内完成的,在这个系统中,对文件进行 TeX 化只是一个阶段,因此该文件将由第三方人员编辑,我需要隐藏这是 TeX 的事实,所以我不能简单地将调用\pgfkeys
本身包含在文件中。话虽如此,我不想禁止任何人做知道这是 TeX 做任何花哨的事情,所以我不想简单地解析键值对列表,而是直接解析参数\pgfkeys
,所以高级用户可以做任何他们想做的事情。
从上面所写的内容来看,要求很简单:
1)我需要读取文件的全部内容原样,没有任何特殊格式或限制,2)将其传递给\pgfkeys
命令仿佛上面使用的示例\input
已经起作用了。3)在 MWE 中,我有意inputenc
在示例输入中包含了一个 UTF8 字符,因为实际输入将包含本地化文本,而我需要 UTF8 才能工作。
链接问题的接受答案使用expl3
,它最初也用于l3keys
密钥处理。我无法使用,l3keys
因为我已经使用设置了所有内容pgfkeys
。将该解决方案调整为pgfkeys
结果如下:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{expl3,pgfkeys}
\begin{document}
\pgfkeys{
gigabytes pgf/mykeys/.cd,
key/.initial={},
}
\ExplSyntaxOn
\ior_new:N \l_gigabytes_stream
\ior_open:Nn \l_gigabytes_stream { keys.def }
\ior_map_inline:Nn \l_gigabytes_stream
{
\pgfkeys { gigabytes~pgf / mykeys/.cd, #1}
}
\ior_close:N \l_gigabytes_stream
\pgfkeysvalueof{gigabytes~pgf /mykeys / key}
\ExplSyntaxOff
\end{document}
但是,此代码的问题在于,文件是以 的阴极状态读取的expl3
,因此文件中的所有空格都被丢弃,这是不可接受的。另外,expl3
对我来说最好避免使用它,因为我不习惯它,而且系统的其余部分都不需要它。
那么,如果不使用,我怎样才能实现我的目标expl3
?
答案1
虽然我不了解用例,但使用上一个问题中的 MWE,以下内容可能会满足您的要求:
\documentclass{article}
\usepackage{pgfkeys}
\begin{filecontents}{keys.def}
key = Hello
second key=bye
\end{filecontents}
\pgfkeys{/mykeys/.is family, /mykeys,
key/.initial =,
% allow unknown keys
.unknown/.code={\pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname}{#1}},
}
\newread\pgfkeysfile% file handler
\def\apar{\par}% \ifx\par won't work but \ifx\apar will
\newcommand\AddPgfKey[1]{\expandafter\pgfkeys\expandafter{/mykeys, #1}}
\openin\pgfkeysfile=keys.def% open file for reading
\loop\unless\ifeof\pgfkeysfile% loop until end of file
\read\pgfkeysfile to \pgfkeysline% read line from file
\ifx\pgfkeysline\apar% test for, and ignore, \par
\else%
\ifx\pgfkeysline\empty\relax% skip over empty lines/comments
\else\expandafter\AddPgfKey\expandafter{\pgfkeysline}
\fi%
\fi%
\repeat
\begin{document}
\noindent Key values: \\
key = \pgfkeysvalueof{/mykeys/key}\\
second key = \pgfkeysvalueof{/mykeys/second key}
\end{document}
我在一些代码中使用了类似的东西,但我要做的不是读取任意键,而是设置一些键值对。上面的代码应该适用于任意 pgf 键,但前提是每个键都在一行上。为了支持多行键,可以修改上面的代码,将文件的所有内容合并为一个字符串,然后将其输入到\pgfkeys{...}
。