不幸的是,我无法为这个问题写出更好的标题。
我正在尝试参数化我的工作流程,我将允许自己使用以下命令从命令行覆盖页边距:
xelatex "\newcommand{\mygeometry}{margin=2cm}\input{myfile.tex}"
在 myfile.tex 中我有默认设置和实际使用\newgeometry
命令的应用程序:
\providecommand{\mygeometry}{margin=3cm}
% ...
\newgeometry{\mygeometry}
当我尝试处理此问题时出现以下错误:
! Package xkeyval Error: `margin=2cm' undefined in families `Gm'.
据我了解,geometry
用于xkeyval
解析其命令集中的参数,并且像这样的构造\newgeometry{\myargs}
不能按预期工作,因为的值\myargs
以某种方式无法被解析xkeyval
,而是被逐字理解,并且=
符号没有任何效果,即被解释为参数的一部分。
我该如何解决这个问题?我想从命令行将自定义几何图形传递给我的 .tex,这与我需要为不同目的生成不同版本的布局有关。
如果我只是使用\newgeometry{margin=2cm}
,即在文件中自己替换值,那么一切都会正常。
答案1
未经尝试,我在评论中建议将 myfile.tex 中的行从
\newgeometry{\mygeometry}
进入
\expandafter\newgeometry\expandafter{\mygeometry}
如果宏(显然\newgeometry
是这种类型)想要实际文本作为其参数,它可能无法接受指向此类文本的简单指针,在这种情况下,宏\mygeometry
将被替换为所需的文本,但只有在扩展时才会替换。
因此,在这种情况下,人们希望能够“预先扩展”,\def
以便宏\newgeometry
认为它正在获取实际文本。
宏\expandafter
会暂时跳过后面的第一个项并扩展后面的第二个项。然后执行后面的第一个项。现在,如果您想要扩展的项不是第二个项,而是第三个项,那么您必须将\expandafter
每个其他标记串在一起,直到到达那里。
因此,在这种情况下,语法\expandafter\newgeometry\expandafter{\mygeometry}
表示暂时跳过\newgeometry
并展开下一个内容,即另一个\expandafter
。 该语法表示暂时跳过{
并展开\mygeometry
。 此时,\newgeometry
使用左括号和 的展开版本执行\mygeometry
。 就好像 的替换文本\mygeometry
实际上已被输入为 的参数\newgeometry
。
虽然这个问题不需要这些技术,但是可以以各种巧妙的方式使用这些技术来扩展,例如,首先扩展第三个标记,然后是第二个标记,最后是第一个标记,如果第二个标记依赖于第三个标记的扩展形式,并且第一个标记依赖于第二个标记的扩展形式。
我在以下回答中给出了此类用法的一个例子如何在 tqft 包中将箭头放在边界圆上,我定义了一个术语,例如
\def\LeftSideArrow{\expandafter\expandafter\expandafter\LeftSideArrowHelper\expandafter}
它将会实现这个目的。