我正在尝试扩展一个参数的值,该参数将是文档中包含的页面范围,但我不知道该怎么做。起初,我得到了
错误:缺少为 \ifnum 插入的 =。
MWE 是
\documentclass{article}
\usepackage{pdfpages}
\newcommand{\myargval}{1-3}
\begin{document}
\includepdf[pages=1-3, clip]{example.pdf}
\includepdf[pages=\myargval, clip]{example.pdf}
\end{document}
评论者解释了如何使用 \edef 和 \noexpand 来评估参数的值。
然而,在完整版本中,我还有另一个pagecommand
不应扩展的论点:
\documentclass{article}
\usepackage{pdfpages}
\newcommand{\myargval}{1-3}
\begin{document}
\includepdf[pages=1-3, clip, pagecommand={\thispagestyle{headings}}]{example.pdf}
\edef\temp{\noexpand\includepdf[pages=\myargval, clip, pagecommand={\thispagestyle{headings}}]{example.pdf}}\temp
\end{document}
如果我使用它,我会得到:
错误:不完整 \iffalse;第 10 行后的所有文本都被忽略。
答案1
您可以使用以下技巧来扩展您需要的内容,并通过在内容前面添加 来保持不应扩展的内容不扩展\noexpand
:
\documentclass{article}
\usepackage{pdfpages}
\newcommand{\myargval}{1-3}
\begin{document}
\includepdf[pages=1-3, clip, pagecommand={\thispagestyle{headings}}]{lipsum50}
\begingroup
\edef\x{\endgroup
\noexpand\includepdf[pages=\myargval,
clip,
pagecommand={\noexpand\thispagestyle{headings}}]
{lipsum50}}\x
\end{document}
以一般形式添加一个群
\begingroup
\edef\x{\endgroup <stuff>}\x
确保\x
不会继续存在。这不是必需的,但\x
可以在使用之前将其定义为其他内容(一般而言),即在调用 之后恢复其含义 \x
。\edef
扩展所有可扩展的内容(\endgroup
不可扩展),同时\noexpand\<csname>
扩展为\<csname>
。
lipsum50.pdf
是一个最小文档,\lipsum[1-50]
从lipsum
包裹。
答案2
这是一个复杂的解决方案,但最终的界面更清晰。
我没有提供对所有键的支持,应该清楚如何扩充该集合。
\documentclass{article}
\usepackage{xparse}
\usepackage{pdfpages}
\ExplSyntaxOn
\NewDocumentCommand{\xincludepdf}{O{}m}
{
\group_begin:
\keys_set:nn { xincludepdf } { #1 }
\xincludepdf_include:Vn \l_xincludepdf_options_tl { #2 }
\group_end:
}
\cs_new_protected:Nn \xincludepdf_include:nn
{
\includepdf[#1]{#2}
}
\cs_generate_variant:Nn \xincludepdf_include:nn { V }
\tl_new:N \l_xincludepdf_options_tl
\keys_define:nn { xincludepdf }
{
% pagecommand must not be expanded
pagecommand .code:n = \tl_put_right:Nn \l_xincludepdf_options_tl { pagecommand=#1, },
% all others should be fully expanded
pages .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { pages=#1, },
nup .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { nup=#1, },
landscape .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { landscape=#1 },
landscape .default:n = true,
delta .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { delta=#1, },
offset .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { offset=#1, },
frame .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { frame=#1, },
frame .default:n = true,
column .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { column=#1, },
column .default:n = true,
columnstrict .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { columnstrict=#1, },
columnstrict .default:n = true,
openright .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { openright=#1, },
openright .default:n = true,
clip .code:n = \tl_put_right:Nx \l_xincludepdf_options_tl { clip=#1, },
clip .default:n = true,
% ...
}
\ExplSyntaxOff
\newcommand{\myargval}{1-3}
\begin{document}
\section{Whatever}
\xincludepdf[pages=\myargval,clip, pagecommand={\thispagestyle{headings}}]{kant}
\newcommand{\tpsh}{\thispagestyle{headings}}
\xincludepdf[pages=\myargval,clip, pagecommand=\tpsh]{kant}
\end{document}
答案3
您可以使用内置有该功能的 key=value 接口(我推荐expkv
,但我是它的作者...其他内置有一些扩展控制支持的软件包是pgfkeys
和options
。使用 . 在使用其他 key=value 解析器的现有宏周围添加包装器最简单expkv
)。
不幸的是,您想将它用于已经使用另一个 key=value 接口的现有宏,因此我们必须稍微扩充一下这个宏(类似于 @egreg 的答案,但这里要简单得多)。为此,我们使用\ekvparse
(它将应用下面描述的规则),然后使用两个辅助宏(\xincludepdf@k
以及\xincludepdf@kv
以下内容)重建 key=value 列表。
expkv
提供了一种以简单方式指定键值扩展的机制。只需在键前加上前缀<rules>:
(包括冒号后的空格),规则就会执行(在键=值对中,规则适用于值,如果没有给出=值,则适用于键)。内置了以下规则(在 2023-01-23 版本中):
o
扩大价值一次e
充分扩大价值\expanded
c
根据提供的值构建宏(使用\csname
)f
扩展值直到遇到不可扩展的标记(如果是空格,则删除该空格)V
该值应该是一个单独的标记,将该标记扩展为该值(如果它是一个宏,则有效o
,如果它是一个寄存器,则将导致该寄存器的内容)v
类似于执行c
和V
(但如果结果宏未定义,则结果不同)s
删除一组周围的空格和(如果之后所有内容都删除)括号b
在值周围添加一对括号p{<stuff>}
放置<stuff>
在值之前P{<stuff>}
<stuff>
值后面的位置g
吞噬第一个标记或括号组的值\r
将所有扩展的结果重新插入为附加的 key=value 输入\key{<rules>}
在 key=value 对中应用于键而不是值R
与...一样V\r
r
与...一样v\r
多个规则从左到右连续应用,例外情况是,\r
在处理完所有其他规则后,该规则始终会应用。
对于这种用例,我们只需要-rule o
(或者可以改用-rule V
)。
\documentclass{article}
\usepackage{pdfpages}
\usepackage{expkv}
\newcommand{\myargval}{1-3}
\makeatletter
\newcommand\xincludepdf[2][]
{%
\expandafter\includepdf
% inner \expanded fully expands \ekvparse,
% outer \expanded fully expands all \xincludepdf@k(v)
\expanded{\expanded{[\ekvparse\xincludepdf@k\xincludepdf@kv{#1}]}}%
{#2}%
}
% needs to protect against the outer \expanded, so uses \unexpanded (we don't
% want to expand more than the explicitly stated rules need)
\newcommand\xincludepdf@k[1]{,\unexpanded{#1}}
% the space between the = and the value make this more robust for most key=value
% parsers
\newcommand\xincludepdf@kv[2]{,\unexpanded{#1= {#2}}}
\makeatother
\begin{document}
\includepdf[pages=1-3, clip]{example-image-duck.pdf}
% o: means expand the value once, the space after the colon is mandatory
\xincludepdf[o: pages=\myargval, clip]{example-image-duck.pdf}
\end{document}
不需要\ekvparse
知道的任何键\includepdf
,它只会处理您请求的扩展,其他每个解析都由\includepdf
它自己处理,如果遇到未知的键,它会抱怨。