0

I "just" want to wrap all \includegraphics commands inside a \centerline, i.e.:

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

automatically replaced by

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

So I need a macro in the preamble, but I don't know how to pass all arguments, and all options unchanged using renewcommand:

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

Do I have to go through the hassle of using \ifnextchar[ myself? (example here https://tex.stackexchange.com/a/314/95423); or do I need a package?

I stress out that the number of provided optional arguments is variable, and that even solutions with xparse or etoolbox require knowing the number of options...


P.S: why \centerline? Because it allows images to be larger than textwidth (see this). P.P.S: Thank you for highlighting potential drawbacks of rigidly centered includegraphics, although I am mostly interested in the general way to implement this redefinition.

  • What if you need \includegraphics not centered? By the way, \centerline is a foreign command to LaTeX. – egreg Apr 28 '20 at 17:17
  • I don't think I will often need uncentered graphics, as they will all be figures. In that case I would simply define an \oldincludegraphics I suppose. – PlasmaBinturong Apr 28 '20 at 17:21
  • While you could do it with\let\svincludegraphics\includegraphics \renewcommand\includegraphics[2][]{\centerline{\svincludegraphics[#1]{#2}}}, the problem is you will be forever precluded from sticking two images on a single line. Preferable would be to define a new command, like \clincludegraphics, specifically for applying \centerline. – Steven B. Segletes Apr 28 '20 at 17:22
  • 1
    images larger than textwidth with no warning would prevent publication in many published sources so be careful where you use this. – David Carlisle Apr 28 '20 at 20:36
  • It's for my PhD thesis, so I am quite free. Some friends even used a layout with a huge margin, where all the figures go, and a thin column of text on the side. Now this is a whole new debate, but I personally like having a narrow column of text, except for figures. As this is probably unorthodox, I'd be happy to be redirected to opinions/rules/convention on the matter. – PlasmaBinturong Apr 28 '20 at 21:09

2 Answers2

3

For example, you can do this:

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

The optional parameter (if any) is #1, the real parameter is #2 of the \includegraphicsA.

wipet
  • 74,238
  • Oh, my bad, I realise I was confused by the denomination "an optional parameter", which refer to everything inside one pair of brackets, even when there are several comma separated values... thank you for you time. – PlasmaBinturong Apr 28 '20 at 18:37
  • Can you please explain why there is #1# in the second line? shouldn't # be followed by a numeral? – PlasmaBinturong Apr 28 '20 at 18:46
  • 1
    This is special exepion of TeX syntax of macros. The parameter text should be terminated by #. It menas that the parameter is separated to the first occurence of {. In our example in one use \inclgr {figure}, then #1 is empty. Or \incrgr*[um, pluptf]{figure} then #1 is *[um, pluptf]. – wipet Apr 28 '20 at 18:50
2

I'm not sure how useful this would be. If you use \includegraphics inside a figure environment, you just specify \centering in the environment.

However, here's an implementation that also allows a nocenter option,

\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}

enter image description here

Is there a simpler way? Yes, there is, but preserving the full syntax of \includegraphics is a bit of a nuisance.

\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

You can use \nocenterincludegraphics for including something without centering.

Note. \LetLtxMacro isn't really necessary with the current definition of \includegraphics. But things change and using a simple \let might reveal disastrous if the implementation changes.

egreg
  • 1,121,712
  • Certainly robust and flexible, however for a basic user like me this looks intimidating. I'll use that if I encounter limitations in the simpler approach. – PlasmaBinturong Apr 28 '20 at 18:40
  • Maybe my question is asking for a bad workaround, and I should indeed redefine the figure environment instead of the \includegraphics command. We always find better answers after formulating the question ^^ – PlasmaBinturong Apr 28 '20 at 18:43
  • @PlasmaBinturong Using \centerline inside a macro in LaTeX is always a bad idea. It doesn't do what you believe it to. Well it almost does it, but you might be puzzled by its result in some cases. – egreg Apr 28 '20 at 20:40
  • @PlasmaBinturong I added a “less intimidating” code. But, really, the idea is wrong to start with. – egreg Apr 28 '20 at 20:53
  • Thank you, it's amazing to be helped so quickly. I started getting through macro & tex tutorials, but to be honest I also should write some actual thesis content. Nevertheless your code helped me getting started. I'll ask a new question for redefining the figure environment then ;) – PlasmaBinturong Apr 30 '20 at 14:55