renewcommand 作为一个简单的包装器:将所有参数和选项传递给底层命令

renewcommand 作为一个简单的包装器:将所有参数和选项传递给底层命令

我“只是”想将所有\includegraphics命令包装在里面\centerline,即:

\includegraphics[width=3cm, keepaspectratio]{img}

自动替换为

\centerline{\includegraphics[width=3cm, keepaspectratio]{img}}

所以我需要在序言中使用宏,但我不知道如何传递全部 参数, 和所有选项 未变使用renewcommand

\renewcommand{\includegraphics}[1]{\includegraphics[???]{#1}}

我是否需要使用\ifnextchar[?(示例如下https://tex.stackexchange.com/a/314/95423);或者我需要一个包裹吗?

我强调的是,提供的可选参数的数量是可变的,并且即使解决方案解析或者电子工具箱需要知道选项的数量...


PS:为什么\centerline?因为它允许图像大于文本宽度(见)。 PPS:感谢您强调严格居中的 includegraphics 的潜在缺点,尽管我最感兴趣的是实现这种重新定义的一般方法。

答案1

例如,你可以这样做:

\let\includegraphicsori=\includegraphics
\def\includegraphics#1#{\includegraphicsA{#1}}
\def\includegraphicsA#1#2{\centerline{\includegraphicsori#1{#2}}}

可选参数(如果有)为#1,实数参数#2\includegraphicsA

答案2

我不确定这有多大用处。如果在环境\includegraphics中使用figure,只需\centering在环境中指定即可。

但是,这里有一个实现,它还允许一个nocenter选项,

\documentclass{article}
\usepackage{xparse,graphicx}

\ExplSyntaxOn
\cs_set_eq:NN \plasma_includegraphics:w \includegraphics
\cs_new_protected:Nn \plasma_includegraphics:nn
 {
  \plasma_includegraphics:w [ #1 ] { #2 }
 }
\cs_generate_variant:Nn \plasma_includegraphics:nn { V }

\keys_define:nn { plasma/includegraphics }
 {
  center .bool_set:N = \l__plasma_includegraphics_center_bool,
  center .default:n = true,
  nocenter .bool_set_inverse:N = \l__plasma_includegraphics_center_bool,
  nocenter .default:n = true,
  unknown .code:n =
   \clist_put_right:Nx \l__plasma_includegraphics_options_clist
    {
     \l_keys_key_str \tl_if_empty:nF { #1 } { = \exp_not:n { #1 } }
    },
 }

\RenewDocumentCommand{\includegraphics}{sO{}m}
 {
  \clist_clear:N \l__plasma_includegraphics_options_clist
  \keys_set:nn { plasma/includegraphics } { center, #2 }
  \IfBooleanT{#1}
   {
    \keys_set:nn { plasma/includegraphics } { clip=true }
   }
  \bool_if:NTF \l__plasma_includegraphics_center_bool
   {
    \par\noindent\makebox[\columnwidth]
     {
      \plasma_includegraphics:Vn \l__plasma_includegraphics_options_clist { #3 }
     }
    \par
   }
   {
    \plasma_includegraphics:Vn \l__plasma_includegraphics_options_clist { #3 }
   }
 }

\ExplSyntaxOff

\begin{document}

\includegraphics[width=3cm,angle=30]{example-image-a}

\includegraphics*[width=5cm,viewport=0 0 72 72]{example-image-a}

\noindent
X\includegraphics[nocenter,height=2ex]{example-image-b}Y

\end{document}

在此处输入图片描述

有没有更简单的方法?是的,有,但是保留完整的语法\includegraphics有点麻烦。

\usepackage{letltxmacro} % <--- necessary

\makeatletter
\LetLtxMacro\nocenterincludegraphics\includegraphics

\protected\def\includegraphics{%
  \@ifstar{\plasma@includegraphics@clip}{\plasma@includegraphics}%
}
\newcommand\plasma@includegraphics[2][]{%
  \par\noindent
  \makebox[\columnwidth]{\nocenterincludegraphics[#1]{#2}}%
  \par
}
\newcommand\plasma@includegraphics@clip[2][]{%
  \plasma@includegraphics[clip,#1]{#2}%
}
\makeatother

您可以使用\nocenterincludegraphics它来包含某些内容但不居中。

笔记。 \LetLtxMacro其实没有必要与当前的定义。但事情会发生变化,如果实施发生变化,\includegraphics使用简单的方法可能会带来灾难性的后果。\let

相关内容