# File name for \includegraphics with a macro

Maybe I have a similar problem as in this question, as well as this?

I must commit, that I haven't understand the answer from David Carlisle in the second link, concerning the direct expansion, so I am not able to adapt his solution onto my situation. :-(

I have a great collection of >60 logo files. The logo file names are made up from components, each representing some specifications (e.g. german language vs. english language, ...).

I want to create a macro, which will receive input about one or two of the components and should compute the desired logo file name, which should be handed over to includegraphics, to be used as input in the mandatory brace.

Of course the planned macro is somewhat more complex, than this MWE, but it shows my actual problem very well. My intention was, to return a string like LOGO-compA-compB-compC as result of the macro. (The logo files will be found on the TEXMF-tree, I only compute the name of the file.)

\documentclass[parskip=full]{scrartcl}

\usepackage{graphicx}

%%% New commands, to compute a grahics file name.
%% Simple
\newcommand{\foo}{example-image-c}
%% Defining one argument, which is not used.
\newcommand{\baz}[1]{example-image-b}
%% Enabling a default for the argument.
\newcommand{\foobar}[1][example-image-a]{#1}

\begin{document}
\includegraphics[height=.7cm]{\foo} \\     % works
\includegraphics[height=.7cm]{\baz{}} \\   % Works also
%% won't work.  Missing endcsname inserted??
\includegraphics[height=.7cm]{\foobar[example-image-c]} \\
%% Won't work either
\includegraphics[height=.7cm]{\foobar} \\
\includegraphics[height=.7cm]{\foobar[example-image-c]} \\
\end{document}


What is the trick to get it working?

• The optional argument mechanism of \newcommand is not expandable, this can't work as you plan. May 29, 2021 at 17:52
• I didn't knew that. That explains it at least.
– Jan
May 30, 2021 at 7:48

It's possible, as Skillmon showed, to have an expandable command that works in the argument of \includegraphics, but it is easier to invert the calling order and handle the arguments and any other processing before entering the expansion-only filename parsing of \includegraphics

\documentclass[parskip=full]{scrartcl}

\usepackage{graphicx}

%%% New commands, to compute a grahics file name.
%% Simple
\NewDocumentCommand{\foo}{o}{\includegraphics[#1]{example-image-c}}
%% Defining one argument, which is not used.
\NewDocumentCommand{\baz}{om}{\includegraphics[#1]{example-image-b}}
%% Enabling a default for the argument.
\NewDocumentCommand{\foobar}{oO{example-image-a}}{\includegraphics[#1]{#2}}

\begin{document}
\foo[height=.7cm] \\     % works
\baz[height=.7cm]{} \\   % works
%% won't work.  Missing endcsname inserted??
\foobar[height=.7cm][example-image-c] \\
%% Won't work either
\foobar[height=.7cm] \\
\foobar[height=.7cm][example-image-c]
\end{document}

• Thank you David. Although Skillmons answer has an interesting starting point to get familiar with key value options, his solution does not include \includegraphics, if you look carefully. Your solution facilitates a new \NewDocumentCommand, which is complete new to me. I had to look it up in the net. I found an tutorial from Joseph Wright, stating, that you have to use the package xparse, which you didn't load in your example. I suppose, that the development and integration of its code has made so much prograss, that it is now part of normal LaTeX?
– Jan
May 30, 2021 at 8:24
• Now, that I got a first impression of the magnificent opportunities of \NewDocumentCommand, your answer got even more beautiful (if possible!) :-) You are a genius! Thank you for you ongoing support!!
– Jan
May 30, 2021 at 8:35
• @Jan yes xparse was integrated into latex last release, see ltnews May 30, 2021 at 8:57
• @Jan my answer doesn't use \includegraphics as there is not much sense to it, I don't have the files LOGO-opt1-opt2-opt3 on my machine. That's why I used it inside the argument of \typeout instead, showing that this indeed is fully expandable. You could just adapt the keys (and default values) as well as the output to your situation and use it inside of \includegraphics. May 30, 2021 at 9:33
• @Jan sure, but where's the fun in setting up a key=value solution to control one part of the name :) May 31, 2021 at 7:13

Might I interest you in using an expandable key=value solution? This uses the expkv-cs package.

\documentclass[]{article}

\usepackage[]{graphicx}
\usepackage{expkv-cs}

\ekvcHash\foo
{
lang=en
,size=small
,color=green
}
{%
LOGO-\ekvcValue{lang}{#1}-\ekvcValue{size}{#1}-\ekvcValue{color}{#1}%
}
\ekvcSecondaryKeys\foo
{
nmeta mylogo = {lang=de, size=gigantic, color=blue}
}

\newcommand\testfoo[1]
{%
\typeout{\foo{#1}}%
}

\begin{document}
\testfoo{size=large}

\testfoo{color=red}

\testfoo{color=orange,size=medium,lang=de}

\testfoo{mylogo}
\end{document}


Output on the terminal:

LOGO-en-large-green
LOGO-en-small-red
LOGO-de-medium-orange
LOGO-de-gigantic-blue

• Of course you might! I am very grateful. I love TeX.SE because I always learn something interesting! :-)
– Jan
May 30, 2021 at 7:47