我正在学习如何制作 LaTeX 命令。我认为它们只是宏,命令被其定义逐字替换。但以下示例不起作用,我想问是否可以让它起作用,更重要的是,为什么它不起作用。
鉴于这种
\documentclass[]{article}%
\usepackage[demo]{graphicx}
\begin{document}
\includegraphics[width=0.8\textwidth]{whatever} %standard
\end{document}
我想width=0.8\textwidth
使用自己的命令进行构建。这有效:
\documentclass[]{article}%
\usepackage[demo]{graphicx}
\newcommand{\X}[1]{#1\textwidth} %works
\begin{document}
\includegraphics[width=\X{0.8}]{whatever} %newcommand
\end{document}
但是当将整个事情改变为命令时,就像这样:
\documentclass[]{article}%
\usepackage[demo]{graphicx}
\newcommand{\Y}[1]{width=#1\textwidth} %does not work
\begin{document}
\includegraphics[\Y{0.8}]{whatever}
\end{document}
Latex 出现以下错误:
Missing \endcsname inserted. \includegraphics[\Y{0.8}]{whatever}
所以我的整个想法,即命令只是盲目的宏替换(就像#define
在 C 中一样)是错误的,或者也许 Latex 正在尝试评估内部事物\newcommand
,这就是它抱怨的原因?
有没有办法让上面最后一个例子按所示工作?
2015 年
答案1
您必须扩展可选参数,以便\Y{<x>}
将其正确视为width=<x>\textwidth
。以下是实现此目的的多种方法:
第一种方法:
扩展可选参数(也可能是强制参数,取决于用途)的间接方法。
\documentclass{article}
\usepackage{graphicx}
\newcommand{\Y}[1]{width=#1\textwidth}
\let\oldincludegraphics\includegraphics
\renewcommand{\includegraphics}{\expandafter\oldincludegraphics\expandafter}
\begin{document}
\includegraphics[\Y{0.1},height=50pt]{example-image}
\end{document}
第二种方法
通过仅扩展可选参数的更直接的方法。
\documentclass{article}
\usepackage{graphicx,letltxmacro}
\newcommand{\Y}[1]{width=#1\textwidth}
\LetLtxMacro\oldincludegraphics\includegraphics
\renewcommand{\includegraphics}[2][]{%
\expandafter\oldincludegraphics\expandafter[#1]{#2}}
\begin{document}
\includegraphics[\Y{0.1},height=50pt]{example-image}
\end{document}
第三种方法
宏参数的完整扩展。
\documentclass{article}
\usepackage{graphicx,letltxmacro}
\newcommand{\Y}[1]{width=#1\textwidth}
\LetLtxMacro\oldincludegraphics\includegraphics
\renewcommand{\includegraphics}[2][]{%
\begingroup\edef\x{\endgroup%
\noexpand\oldincludegraphics[#1]{#2}}\x}
\begin{document}
\includegraphics[\Y{0.1},height=50pt]{example-image}
\end{document}