有条件地解析新命令输入会导致“package keyval error: scale undefined”

有条件地解析新命令输入会导致“package keyval error: scale undefined”

我正在尝试制作一个新的宏,该宏采用缩放尺寸或其他缩放参数(例如 width=\textwidth)来调整图片大小。以下是我所拥有的:

\newcommand{\pic}[3]{\begin{figure}[H]
    \centering
    \if\instring{#1}{=}\def \arg{#1}\else\def\arg{scale=#1}\fi
    \includegraphics[\arg]{#2}
    \caption{#3}
\end{figure}}

在我的文件中,有以下一行:

\pic{1}{lpm_block.png}{Block diagram for the LPM multiplier}

给出错误“package keyval error: scale=1 undefined”。没有“if”语句,它工作正常。我需要更改什么?有没有更好的方法?谢谢!

编辑:

以下是更多可以顺利编译的代码。

\documentclass{article}

\usepackage{siunitx}
\usepackage{graphicx}
\usepackage{apacite}
\usepackage{amsmath} % Required for some math elements
\usepackage{multicol} % multiple columns
\usepackage{float} % place graphics
\usepackage{subfig} % graphics on same line
\usepackage{geometry} % fill empty margins
\usepackage[square,sort,comma,numbers]{natbib}
\usepackage[hyphens]{url}
\usepackage{minted}
\renewcommand\theFancyVerbLine{\normalsize\arabic{FancyVerbLine}}

\geometry{letterpaper, top=0.75in, left=0.75in, bottom=0.75in, right=0.75in}

\setlength\parindent{0pt} % Removes all indentation from paragraphs

%\usepackage{times} % Uncomment to use the Times New Roman font

\newcommand{\pic}[3]{\begin{figure}[H]
    %\if\instring{#1}{=}\def \arg{#1}\else\def\arg{scale=#1}\fi
    \centering
    \includegraphics[scale=#1]{#2}
    \caption{#3}
\end{figure}}

\begin{document}

\section{Design Files}
    \subsection{Serial Multiplier}
        \pic{0.55}{serial_block.png}{Block diagram for the serial multiplier. high9 and low8 are simply registers, so they do not have separate design files}

\end{document}

我尝试使用 latex 的目的是提高使用条件语句创建新命令的熟悉度。我没有意识到细微差别会让事情变得更加困难。感谢您迄今为止提供的意见!

答案1

正如你所说,我把这当作一次练习。稍后再发表评论。

您想要的是决定是否=出现在第一个参数中。

\documentclass{article}
\usepackage{graphicx}

\newcommand{\pic}[3]{%
  \begin{figure}
  \centering
  \checkequals{#1}%
  \expandafter\includegraphics\expandafter[\picarg]{#2}
  \caption{#3}
  \end{figure}%
}
\makeatletter
\newcommand\checkequals[1]{\check@equals{#1}#1=\@nil}
\def\check@equals#1#2=#3\@nil{%
  \if\relax\detokenize{#3}\relax
    % no =
    \def\picarg{scale=#2}%
  \else
    \def\picarg{#1}%
  \fi
}
\makeatother

\begin{document}

\pic{0.55}{example-image}{First example}

\pic{scale=0.55}{example-image}{Second example}

\pic{width=2cm,height=1cm}{example-image}{Third example}

\end{document}

\checkequals宏调用采用分隔参数的辅助函数\check@equals;如果=未出现,则我们将其定义\picargscale=#1,假设指定了比例因子。否则,原始参数存储在中\picarg

在此处输入图片描述

现在的问题是:你真的想要这样的宏吗?不,原因有几个。

  1. \pic{0.55}{x}{y}相比并没有什么太大的优势\pic{scale=0.55}{x}{y}

  2. scale是错误的选择,因为您可能不知道图片的大小,也不知道文档的最终大小。文本宽度的微小变化将迫使您重新缩放几张图片。

  3. figure隐藏起来没有任何优势\pic;如果您有两张图片可以放在一行中,您可能希望将它们并排放置。

  4. [H]选项是破坏文档的完美选择。如果一个数字必须保留那里,别无他处,则无需标题,因为无论如何它的描述都会在它旁边。使用浮动有助于更好地组织材料,以便获得良好的分页效果。

最后说明一下。您的代码

%\usepackage{times} % Uncomment to use the Times New Roman font

是在撒谎。该times包裹只会改变文本字体,而不是数学字体。如果你真的想使用 Times,

\usepackage{newtxtext}
\usepackage{newtxmath}% with possible option, see the manual for newtx

答案2

keyval使用逗号,作为键值对的分隔符,使用等号=将键与值分开。它不扩展宏。因此,这些语法字符不能隐藏在宏中。

问题中的例子是通过\arg在处理\expandafter之前扩展\includegraphics其可选参数来修复的:

\if\instring{#1}{=}\def \arg{#1}\else\def\arg{scale=#1}\fi
\expandafter\includegraphics\expandafter[\arg]{#2}%

答案3

如果您使用默认的可选参数,scale=1则无需检查它是否为空:

\documentclass{article}
\usepackage{mwe}

\newcommand{\pic}[3][scale=1]{%
  \begin{figure}
    \centering
    \includegraphics[#1]{#2}
    \caption{#3}
  \end{figure}%
}

\begin{document}

   \pic{example-image-1x1}{Example image}

   \pic[width=\textwidth]{example-image-1x1}{Wider image}
\end{document}

这将产生以下两个页面:

在此处输入图片描述

答案4

请注意,我认为这根本不明智,我建议你重新考虑一下你的愿望。但是,如果我打算肆意破坏,我会使用 LaTeX 3 来破坏它。但如果你只是在学习 LaTeX 2e,这可能不是最好的起点。因此,如果你必须这样做,那么你可以尝试以下一种方法。

\documentclass{article}
\usepackage{graphicx,caption}
\makeatletter
\def\pict@aux#1=#2\@nil{#2}
\newcommand{\pict}[3]{%
  \begin{figure}
    \centering
    \edef\tempa{\expandafter\pict@aux#1=\@nil}%
    \edef\tempb{}%
    \ifx\tempa\tempb
    \includegraphics[scale=#1]{#2}%
    \else
    \includegraphics[#1]{#2}%
    \fi
    \captionof{figure}{#3}%
  \end{figure}%
}
\makeatother

\begin{document}

\section{Design Files}
\subsection{Serial Multiplier}
\pict{0.55}{\jobname-cx}{Block diagram for the serial multiplier. high9 and low8 are simply registers, so they do not have separate design files}
\pict{width=0.55cm}{\jobname-cx}{Block diagram for the serial multiplier. high9 and low8 are simply registers, so they do not have separate design files}
\end{document}

变化

然而,在我看来,这是一个笨拙的设计,轻蔑地唾弃用户。因此,我不会这样做——至少,如果我是用户之一的话。你的公里数可能一如既往地有所不同。

相关内容