9

I want to pass some arguments to \includegraphics via a command, but I can't get it working as I would expect. My M(n)WE:

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

\newcommand{\widthText}{,width=3cm}
\includegraphics[scale=0.5 \widthText]{picture}

\end{document}

I guess that the point would be to expand \widthText before...

In my actual code, the command \widthText is actually either the one given above, or empty, depending on some boolean, and I have also a \heightText to set the height.

6

Staying with the desire of the OP, here is a solution.

\documentclass{article}
\usepackage{graphicx}
\makeatletter
\protected\def\includeGraphics{\@testopt\roy@includegraphics{}}
\def\roy@includegraphics[#1]#2{%
  \begingroup
  % Every expandable token in #1 may be expanded here:
  \edef\x{\endgroup\noexpand\includegraphics[#1]}\x{#2}%
}
\makeatother
\begin{document}
\newcommand{\widthText}{,width=3cm}
% Since double comma (,,) in the key-value pairs doesn't hurt both keyval and 
% xkeyval packages, and since the user of \widthText might forget to insert
% a comma before 'width', let us add a potentially redundant comma in the 
% following:
\includeGraphics[viewport=20 21 590 400,scale=0.5, \widthText]{./Graphics/comet1}
\end{document}
6

The keyval system used by graphicx goes to some trouble not to expand macros while parsing, so that the macros can be used as the values of the keys. the intended usage is more like

\newcommand{\widthText}{\ifsomething 3cm \else \Gin@nat@width \fi}
\includegraphics[scale=0.5, width=\widthText]{picture}

where \Gin@nat@width is the natural width.

My original answer suggested \width could be used, thanks for the correction in the comments. \Gin@nat@width works, but means that your definition has to be in a package or inside \makeatletter... In the following, the first two are equivalent, the second is scaled to half size.

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

\makeatletter

\fbox{\includegraphics[]{fj.png}}


\fbox{\includegraphics[width=\Gin@nat@width]{fj.png}}


\fbox{\includegraphics[width=0.5\Gin@nat@width]{fj.png}}

\end{document}
  • What does \ifsomething do/mean? Or: When is \ifsomething expanded to true? – Tobi Mar 3 '12 at 15:34
  • \ifsomething is just a placeholder because the OP said it depended on an (unstated) condition. It could be \ifodd\year... to scale one way or the other in alternate years, or whatever is needed. – David Carlisle Mar 3 '12 at 15:37
  • Unfortunately \includegraphics doesn't accept \width as an argument of width. – Martin Scharrer Mar 3 '12 at 15:45
  • @MartinScharrer, doesn't it? who implemented that?:-), I'm sure it was supposed to, will check and revise answer... – David Carlisle Mar 3 '12 at 15:47
  • @DavidCarlisle Will give a problem if you wanted to pass for example "keepaspectratio". – Yiannis Lazarides Mar 3 '12 at 15:49
5

The code handling the key=value pairs must be able to see the separating comma, therefore it must not be included in a macro. You either need to expand the content of the macro manually or feed it to \includegraphics in another way. For the first method you can use \expandafter or \edef.

There is also my adjustbox package which provides the keys min width and max width, either using \adjincludegraphics[<key options>]{<filename>} or \adjustimage{<key option>}{<filename>} or by loading the package with the export option which makes all new key options available to the normal \includegraphics. I think this might also help you depending on what exactly you want to do.

  • Will you please post a minimal? – Chuang Mar 3 '12 at 16:22
  • Sorry, but i don't understand clearly from your answer, wether with adjsutbox, i can hide the commas in a macro or not. – nicolas roy Mar 5 '12 at 7:59
  • 1
    @nicolasroy: adjustbox doesn't expand the keys as well, so no you can't hide them in a macro. However, you seem to want to set the width depending on some external influence. If this is to enforce a minimal or maximal width, then the given keys can solve your underlying problem better than using a macro. – Martin Scharrer Mar 5 '12 at 11:31
3

Try this way and it works

\documentclass{article}
\usepackage[demo]{graphicx}
\begin{document}
\def\test#1{%
  \includegraphics[scale=0.5,#1]{picture}}
\test{width=3cm}\par
\test{width=1cm}

\def\keepaspectratio{keepaspectratio}
\test{width=1cm,height=3cm,\keepaspectratio}
\end{document}
  • You then could use something like \expandafter\test\expandafter{\widthText} to insert the expanded macro content in the right place. – Martin Scharrer Mar 3 '12 at 15:52
  • @Yiannis: The definition \def\keepaspectratio{keepaspectratio} amounts to submitting a macro as a key name. This is not advisable and might not work always, depending on the type of key and whether it carries pointers. – Ahmed Musa Mar 3 '12 at 21:52
  • @AhmedMusa You know better about this sort of thing. What would you recommend? – Yiannis Lazarides Mar 5 '12 at 16:03
  • The graphicx package ordinarily uses \setkeys from the keyval package. So, because key macro names are built using \csname, there will be no problem when a key name is given as a macro (as in your case). However, when xkeyval package is loaded, its \setkeys will automatically be used. This \setkeys is more complicated and does some internal checks that will be impossible if the key name is hidden in a macro. Hence key-value pairs should be expanded before they’re given as an argument of \setkeys. – Ahmed Musa Mar 7 '12 at 18:51
  • When expanding key-value pairs, some caution is necessary when the keys carry pointers: the two pointers of xkeyval package are undefined. Also, the 'value' part of a key-value pair may contain yet-to-be-defined macros, or macros that shouldn't be expanded prematurely. – Ahmed Musa Mar 7 '12 at 23:55
1

Not an aswer but maybe an alternative way …

If you want to predefine some keys you can seth them with \setkeys{Gin}{<options>}. These keys can be overwritten locally.

\documentclass{article}

\usepackage[demo]{graphicx}

\setkeys{Gin}{width=4cm,height=2cm}


\begin{document}
\includegraphics{file1}

\includegraphics[width=2cm]{file1}
\end{document}

Note: This work not with all options, e.g. using scalein \setkeys won’t give the desired result.

  • Note that \setkeys{Gin}{..} only works with some but not all \includegraphics options, depending on how they are handled internally. However, width and height will work, but not scale. – Martin Scharrer Mar 3 '12 at 15:55
  • @MartinScharrer: I forgot to mention this while writing my answer O:-) I had the problem with scale some time ago … – Tobi Mar 3 '12 at 16:13
  • The adjustbox package offers a way to set all options globally. See the the manual for more. – Martin Scharrer Mar 3 '12 at 17:37

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.