7

I have a large set of pictures, and I want to apply predefined settings to each using the optional argument of the \includegraphics macro from the graphicx package.

I would like to define the settings once at the top of the file (like \def\settings{width=\textwidth, angle=90}), and then apply them to all of my images so that I can modify all of the settings from one place.

If I run the following code block, it gives me the versions of the error "Package xkeyval Error: 'width=\textwidth, angle=90' undefined in families 'Gin'", which seems to be because it's interpreting my entire group of settings as a single key input.

\documentclass{article}
\usepackage{graphix}
\begin{document}

    \def\settingsA{width=\textwidth, angle=90}
    \def\settingsB{page=1, scale=.1}
    \def\settingsC{angle=90, scale=.5}

    \begin{figure}
        \includegraphics[\settingsA]{filename1.png}
        \label{fig:oneofonehundred}
    \end{figure}

    \begin{figure}
        \includegraphics[\settingsB]{filename2.pdf}
        \label{fig:twoofonehundred}
    \end{figure}

    \begin{figure}
        \includegraphics[\settingsC]{filename3.jpg}
        \label{fig:threeofonehundred}
    \end{figure}

 \end{document}

What is the technique to modify this settings string so that it is interpreted correctly? How do I pass an optional argument that is interpreted as a set of arguments instead of one string?

Thanks in advance!

  • 2
    \expandafter\includegrapgics\expandafter[\settingsA]{...} untested (currently not at pc), the key value interpreter does not expand the optional argument before parsing it – daleif Sep 28 '18 at 6:27
  • In my opinion, built-in expansion of the optional arg of \includegraphics is worth being filed as a feature request to github.com/latex3/latex2e/issues?utf8=%E2%9C%93&q=graphicx – AlexG Sep 28 '18 at 8:23
10

Just define new keys:

\documentclass{article}
\usepackage{graphicx}

\makeatletter
\define@key{Gin}{settingsA}[]{\setkeys{Gin}{width=\textwidth, angle=90}}
\define@key{Gin}{settingsB}[]{\setkeys{Gin}{page=1, scale=.1}}
\define@key{Gin}{settingsC}[]{\setkeys{Gin}{angle=-90, scale=.5}}
\makeatother

\begin{document}

\includegraphics[settingsA]{example-image-a}

\includegraphics[settingsB]{example-image-b}

\includegraphics[settingsC]{example-image-c}

\end{document}

enter image description here

A bit of explanation. The graphicx package relies on keyval provided key-value syntax and reserves Gin (Graphic inclusion) as the family name of the keys for \includegraphics. A new key is simply added by

\define@key{Gin}{<name>}[<default value>]{<code>}

The \includegraphics[<options>]{file} command will do

\setkeys{Gin}{<options>}

and every known key will be processed. The default empty value given for settingsA and so on is so that you can simply type settingsA without =something.

One could even improve it; say that in settingsC you want to be able to vary the angle; with

\define@key{Gin}{settingsC}[-90]{\setkeys{Gin}{angle=#1, scale=.5}}

you can specify settingsC for the angle to be -90 or

settingsC=45

for the angle to be 45.

Caveat Be sure not to define an already existing key: \define@key would silently overwrite it.

2

Make your own include graphics command. Something like the following:

\newcommand\myincludegraphics[2]{%%
   \expandafter\includegraphics\expandafter[#1]{#2}}

The problem with your code is that in the construction

\includegraphics[\settingsA]{filehandle}

The unexpanded \settingsA is getting passed to the key parser where it will fail to match any keys. By using the above command, you can write something like,

\myincludegraphics{\settingsA}{filehandle}

By using \expandafter, \settingsA will be expanded by the time \includegraphics has a chance to pass the optional arguments to its parser.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.