(当前问题与在 expl3 包中使用 \usetikzlibrary 失败,至少在某种程度上。)
假设expl3
我的一个()类,myclass
通过myclass.cfg
在类末尾自动输入的配置文件,提供了一种在文档级别进行配置的方法:
\ProvidesExplClass{myclass}{2022-09-01}{0.1}{A class of mine}
\NeedsTeXFormat{LaTeX2e}
\LoadClass { article }
\file_if_exist:nT {./myclass.cfg}{
\file_input:n {./myclass.cfg}
}
假设现在用户想要利用此配置文件myclass.cfg
来加载TikZ
包及其calc
库。这将失败并出现以下错误:
! Package pgfkeys Error: I do not know the key '/tikz/cs/point/.storein', to wh
ich you passed '\tikz@cs@point ', and I am going to ignore it. Perhaps you miss
pelled it.
See the pgfkeys package documentation for explanation.
Type H <return> for immediate help.
...
l.410 \tikzset{cs/point/.store in=\tikz@cs@point}
%
?
正如相关问题中所解释的以及以下 MCE 所指出的:
\begin{filecontents}[overwrite]{myclass.cls}
\ProvidesExplClass{myclass}{2022-09-01}{0.1}{A class of mine}
\NeedsTeXFormat{LaTeX2e}
\LoadClass { article }
\file_if_exist:nT {./myclass.cfg}{
\file_input:n {./myclass.cfg}
}
\end{filecontents}
\begin{filecontents}[overwrite]{myclass.cfg}
\usepackage{tikz}
\usetikzlibrary{calc}
\end{filecontents}
\documentclass{myclass}
\begin{document}
Foo.
\end{document}
问题显然出在 中的空格.store in
,通常会被忽略。因此,作为一种解决方法,只需在配置文件的开头expl3
添加即可。事实上,以下 MCE 编译起来非常顺利:\ExplSyntaxOff
\begin{filecontents}[overwrite]{myclass.cls}
\ProvidesExplClass{myclass}{2022-09-01}{0.1}{A class of mine}
\NeedsTeXFormat{LaTeX2e}
\LoadClass { article }
\file_if_exist:nT {./myclass.cfg}{
\file_input:n {./myclass.cfg}
}
\end{filecontents}
\begin{filecontents}[overwrite]{myclass.cfg}
\ExplSyntaxOff % ← NEW!
\usepackage{tikz}
\usetikzlibrary{calc}
\end{filecontents}
\documentclass{myclass}
\begin{document}
Foo.
\end{document}
假设我想让班级用户的生活更轻松,并且不需要他们\ExplSyntaxOff
在配置文件的开头添加(如果需要)。我希望可以通过钩子使用自动将此命令添加到类级别的此文件中。\AddToHook { file/myclass.cfg/before } { \ExplSyntaxOff }
但以下 MCE 失败,并出现与上述相同的错误:
\begin{filecontents}[overwrite]{myclass.cls}
\ProvidesExplClass{myclass}{2022-09-01}{0.1}{A class of mine}
\NeedsTeXFormat{LaTeX2e}
\LoadClass { article }
\file_if_exist:nT {./myclass.cfg}{
\AddToHook { file/myclass.cfg/before } { \ExplSyntaxOff } % ← NEW!
\file_input:n {./myclass.cfg}
}
\end{filecontents}
\begin{filecontents}[overwrite]{myclass.cfg}
\usepackage{tikz}
\usetikzlibrary{calc}
\end{filecontents}
\documentclass{myclass}
\begin{document}
Foo.
\end{document}
你明白为什么以及如何我能做到这一点吗?(我知道我可以在课程结束时这样做:
\ExplSyntaxOff
\IfFileExists{./myclass.cfg}{%
\input{./myclass.cfg}%
}{}
但我更愿意保留expl3
:标记列表常量中的文件名,等等)
答案1
该命令\file_input:n
不会寻找旨在与之一起使用的钩子\input
。
如果你
\file_if_exist:nT {./myclass.cfg}
{
\AddToHookNext { file/myclass.cfg/before } { \ExplSyntaxOff }
\AddToHookNext { file/myclass.cfg/after } { \ExplSyntaxOn }
\input {./myclass.cfg}
}
那么它就可以工作了,但我不确定你是否想使用钩子:
\file_if_exist:nT {./myclass.cfg}
{
\use:n { \ExplSyntaxOff \file_input:n {./myclass.cfg} }
\ExplSyntaxOn
}
由于\file_input:n
是 的参数\use:n
,它已经被标记化,因此\ExplSyntaxOff
不会对其执行任何操作。
答案2
正如您链接到的其他问题的答案中所写,LaTeX 有一个系统可以在加载文件时设置和重置此类 catcode:您可以在 expl3 类中毫无问题地加载 tikz 和其他非 expl3 包,因为它\usepackage
使用了此功能。tcolorbox
也使用了此功能,因此加载其库没有问题。您也可以将其用于您的文件。
例如https://www.texdev.net/2015/07/30/making-custom-loaders-expl3-aware/
\begin{filecontents}[overwrite]{myclass.cls}
\ProvidesExplClass{myclass}{2022-09-01}{0.1}{A class of mine}
\NeedsTeXFormat{LaTeX2e}
\LoadClass { article }
\file_if_exist:nT {./myclass.cfg}{
\@pushfilename
\xdef\@currname{myclass.cfg}
\file_input:n {./myclass.cfg}
\@popfilename
}
\end{filecontents}
\begin{filecontents}[overwrite]{myclass.cfg}
\usepackage{tikz}
\usetikzlibrary{calc}
\end{filecontents}
\documentclass{myclass}
\begin{document}
Foo.
\end{document}