如何将宏扩展为视口 = 参数(包括图形)

如何将宏扩展为视口 = 参数(包括图形)

如何正确扩展宏\myviewport以便将其解析为viewport=0pt 10pt 100pt 200pt参数\includegraphics[clip, \myviewport]{somepdf.pdf}

\documentclass{article}
\usepackage{graphicx}
\begin{document}
\newcommand*{\aport}{45.29pt 86.28pt 235pt 187pt}
\includegraphics[clip, viewport={\aport}]{somepdf.pdf}
\end{document}

错误:! Argument of \Gread@parse@vp has an extra }. 我的简单想法是基于 如果宏

起作用的是为每个视口值提供单独的宏:

\documentclass{article}
\usepackage{graphicx}
\usepackage{calc}
\begin{document}
\newlength{\Xoffset}
\setlength{\Xoffset}{35pt}
\newlength{\myl}
\setlength{\myl}{235pt - \Xoffset}
\newcommand*{\lux}{200pt}
\includegraphics[clip, viewport=10pt 50pt \lux{} \the\myl{}, page=3]{somepdf.pdf}
\end{document}

请注意,\myl是一个长度并且\lux是一个“字符串”。

从长远来看,我想自动裁剪一些 pdf 文件(其媒体框不是从 0 0 开始的):

\documentclass{article}
\usepackage{graphicx}
\usepackage{calc}

\newlength{\Xoffset}
\newlength{\Yoffset}
\newcommand*{\setpdfoffset}[2]{
    \setlength{\Xoffset}{#1}
    \setlength{\Yoffset}{#2}
}
\newcommand*{\aviewport}{} %set an empty default
\setpdfoffset{0pt}{0pt} %set a default

\newcommand*{\setviewport}[4]{
    \newlength{\mylux}\setlength{\mylux}{#1-\Xoffset}
    \newlength{\myluy}\setlength{\myluy}{#2-\Yoffset}
    \newlength{\myrox}\setlength{\myrox}{#3-\Xoffset}
    \newlength{\myroy}\setlength{\myroy}{#4-\Yoffset}
    \renewcommand*{\aviewport}{viewport={\the\mylux} {\the\myluy}  {\the\myrox}  {\the\myroy}}
}
\begin{document}

%in Windows command line:
% pdfinfo -box somepdf.pdf |awk "/MediaBox/ {print; print \"Xoffset=\"$2 \" Yoffset=\"$3\"\n\"; print \"\\newlength{\\Xoffset}\\setlength{\\Xoffset}{\"$2\"pt} \\newlength{\\Yoffset}\\setlength{\\Yoffset}{\"$3\"pt}\"}"

\setpdfoffset{35.29pt}{36.28pt}
\setviewport{45.29pt}{86.28pt}{235pt}{187pt}
\emph{\aviewport}
\fbox{\includegraphics[clip, \aviewport{}, page=2]{somepdf}
\end{document}

错误:keyval: viewport={10.0pt} {50.0pt} {199.71pt} {150.72pt} undefined. ...lip, \aviewport]{somepdf}}

XeLaTeX 是我的首选,但 pdfLaTeX 也不喜欢这个代码。

\setpdfoffset奖励:使用获取 X 和 Y 偏移值\input{|"pdfinfo -box somepdf.pdf |awk ..."},但这是一个逃避问题而不是扩展问题。

答案1

以下是几种方法:

在此处输入图片描述

\documentclass{article}
\usepackage{graphicx}
\newcommand{\myviewport}{viewport=0pt 10pt 200pt 50pt}
\begin{document}
\includegraphics[clip, viewport=0pt 10pt 200pt 50pt]{example-image}

\begingroup\edef\x{\endgroup\noexpand\includegraphics[clip, \myviewport]{example-image}}\x

{\let\includegraphics\relax\xdef\x{\includegraphics[clip, \myviewport]{example-image}}}\x
\end{document}

第一个显示预期的输出应该是什么样的。

第二个定义了 的扩展版本\x,其中\includegraphics[..]{...}\includegraphics未扩展的。它也是本地的,因为\x使用后会被丢弃。它非常类似于

\edef\x{\noexpand\includegraphics[clip, \myviewport]{example-image}}\x

无需本地化\x

第三个定义了一个类似的\x,现在是全局的(也扩展了,因此\xdef)。但是,为了避免扩展,\includegraphics它被设置为\relax组内的。这可以防止它通过调用扩展\xdef,并且它也存在于组中。特别是\show\x揭示了

> \x=macro:
->\includegraphics [clip, viewport=0pt 10pt 200pt 50pt]{example-image}.

viewport,和trimbbb圆角b牛)键很特殊,因为要求特定值输入。输入为展开形式#1 #2 #3 #4,并使用 TeX 的参数文本或 进行识别\def。因此,如果匹配不准确,则可能会将错误的参数分配给错误的元素,从而导致您遇到的问题。

在一定程度上,其他宏也可以以宏形式使用。至少,您必须使用显式的=

\documentclass{article}

\usepackage{graphicx}

\begin{document}

\includegraphics[width=100pt]{example-image}

\newcommand{\mywidth}{width}%
\newcommand{\widthdimen}{100pt}%
\includegraphics[\mywidth=\widthdimen]{example-image}

%\newcommand{\mywidthkeyval}{width=100pt}%
%\includegraphics[\mywidthkeyval]{example-image}% Does not work

\includegraphics[clip, viewport=10pt 10pt 50pt 50pt]{example-image}

\newcommand{\myviewport}{viewport}%
\newcommand{\viewportvals}{10pt 10pt 50pt 50pt}%
\includegraphics[clip, \myviewport=10pt 10pt 50pt 50pt]{example-image}
%\includegraphics[clip, \myviewport=\viewportvals]{example-image}% Does not work

\end{document}

答案2

viewport选项或的四个值trim由分隔空格标识。包中为这些选项定义的解析器graphicx需要显式空格,如果空格隐藏在宏中,解析器将失败。

下面的示例重新定义选项(以与重新定义viewport选项相同的方式)以扩展其参数,然后将扩展的值传递给原始选项代码:trim

\documentclass{article}
\usepackage{graphicx}
\makeatletter
% Remember original option `viewport` as `viewport@org`
\let\KV@Gin@viewport@org\KV@Gin@viewport
% Redefine option `viewport` to expand the argument and
% pass it to option `viewport@org`.
\define@key{Gin}{viewport}{%
  \begingroup
  \edef\x{\endgroup
    \noexpand\setkeys{Gin}{viewport@org={#1}}%
  }\x
}
\makeatother

\begin{document}
  \newcommand*{\aport}{45.29pt 86.28pt 235pt 187pt}
  \includegraphics[clip, viewport=\aport]{tiger}
\end{document}

等号和逗号是 LaTeX 键值列表(包keyval和朋友)中的语法字符。如果这些字符隐藏在宏中,键值解析器将失败。但可以定义一个新选项,带有graphicx一个参数,该参数将作为键值列表展开并再次执行:

\documentclass{article}
\usepackage{graphicx}
\makeatletter
\define@key{Gin}{expandoptions}{%
  \begingroup
  \edef\x{\endgroup
    \noexpand\setkeys{Gin}{#1}%
  }\x
}
\makeatother

\begin{document}
  \newcommand*{\viewaport}{viewport=45.29pt 86.28pt 235pt 187pt, clip}
  \includegraphics[expandoptions=\viewaport]{tiger}
\end{document}

答案3

您可以为 定义一个新键\includegraphics,我将其命名为xviewport

\documentclass{article}
\usepackage{graphicx}
\usepackage{calc}

\makeatletter
\define@key{Gin}{xviewport}[]{%
  \begingroup\edef\x{%
    \endgroup\noexpand\setkeys{Gin}{viewport=\x@viewport}%
  }\x
}

\newlength{\Xoffset}
\newlength{\Yoffset}
\newcommand*{\setpdfoffset}[2]{%
  \setlength{\Xoffset}{#1}%
  \setlength{\Yoffset}{#2}%
}
\newcommand*{\setviewport}[4]{%
  \def\x@viewport{%
    {\the\dimexpr#1-\Xoffset} 
    {\the\dimexpr#2-\Yoffset}
    {\the\dimexpr#3-\Xoffset}
    {\the\dimexpr#4-\Yoffset}%
  }%
}
\makeatother

\begin{document}

\setpdfoffset{35.29pt}{36.28pt}
\setviewport{45.29pt}{86.28pt}{235pt}{187pt}

\fbox{\includegraphics[clip, xviewport]{example-image.pdf}}

\end{document}

在此处输入图片描述

答案4

这是可行的,但可能不够通用,无法满足您的需要:

\documentclass{article}
\usepackage[demo]{graphicx}
\begin{document}
\newcommand*{\aport}{45.29pt 86.28pt 235pt 187pt}
\def\X{\includegraphics[clip, viewport=}
\expandafter\X\aport]{somepdf.pdf}
\end{document}

相关内容