programming add tag
nsajko
I want to have a unified interface for `\includegraphics` from the `graphicx` package and `\includesvg` from `svg`.

Here's a slightly simplified sketch of what I want:

```
% argument 1: either `graphics` or `svg`
%
% argument 2: optional args that are just passed on
%
% argument 3: graphics file path
\NewDocumentCommand{\includeimage}{m o m}{%
  XXX[#2]{#3}}
```

The idea is that the missing part (`XXX`) should evaluate to `\includegraphics` when `#1` is `graphics`, and to `\includesvg` when `#1` is `svg`.

EDIT: I'm checking out interface3.pdf, and it seems there's lots of different functions for concatenation, which seems like it would solve my problem (I want to concatenate `\include` with `#1`). However there's lots of different types (strings, a few distinct list types, ...), and I don't know which one is appropriate. Furthermore the `concat` functions take *three* arguments and modify the first (like in assembly language...), but I want some function for concatenation that would take only *two* arguments and return the result. Any pointers?

EDIT2: In section "4.6.2 Primitive conditionals" of interface3.pdf I found out about the command `\if_meaning:w`, however this example I tried doesn't work as expected:

```
\documentclass{report}

\usepackage{expl3}

\NewDocumentCommand{\commandx}{}{Lorem ipsum}

\NewDocumentCommand{\commandy}{}{Lorem ipsum dolor sit}

\ExplSyntaxOn

\NewDocumentCommand{\genericcommand}{m}{%
  \if_meaning:w{#1}{x}{\commandx}\else:{\commandy}\fi:}

\ExplSyntaxOff

\begin{document}

\commandx

\commandy

\genericcommand{x}

\genericcommand{y}

\end{document}
```

The output PDF contains this text:
```
Lorem ipsum
Lorem ipsum dolor sit
Lorem ipsum dolor sit
Lorem ipsum dolor sit
```

So it seems the code always takes the *false*-branch. Any advice?
Top Answer
Skillmon
The following parses the input file name to see whether an extension was specified. If that extension is `.svg` `\includesvg` is used, else `\includegraphics`. If no extension was specified it is tried whether a file with the added extension `.svg` can be found, if that's the case `\includesvg` is used, else `\includegraphics`.

I could also provide a version that prefers non-svg files over svg files if no extension is specified.

Arguments are curried as much as possible (except for the convention to grab all arguments in the document-command), so no duplicated code, whether that's more readable is questionable though.

```
\documentclass{article}

\usepackage{svg}

\ExplSyntaxOn
\str_new:N \l_nsaijko_ext_str
\NewDocumentCommand \includeimage { O{} m }
  { \nsaijko_includeimage:nn {#1} {#2} }
\cs_new_protected:Npn \nsaijko_includeimage:nn #1#2
  {
    \file_parse_full_name:nNNN {#2} \l_tmpa_str \l_tmpa_str \l_nsaijko_ext_str
    \str_if_empty:NTF \l_nsaijko_ext_str
      { \file_if_exist:nTF { #2 . svg } }
      { \str_if_eq:VnTF \l_nsaijko_ext_str { .svg } }
        { \includesvg }
        { \includegraphics }
          [#1] {#2}
  }
\ExplSyntaxOff

\begin{document}
\includeimage{example-image-a}
\includeimage{fancytipmark}
\includeimage{example-image-a.pdf}
\includeimage{fancytipmark.svg}
\end{document}
```

(`fancytipmark.svg` is part of a full TeXLive installation, however since you're most likely missing the rights to write in that directory you'll have to copy it to your working directory, on Unix that's easily possible using `cp $(kpsewhich fancytipmark.svg) .` in `zsh`).

Result:

![svgorgraphics.png](/image?hash=cec8131e2206a014f841bb97f750d9756deec98731a529f1e90e5c0bacd7b1dd)
Answer #2
nsajko
I basically solved this, with the help of the `\str_case:nnF` LaTeX3 function, which is a kind of replacement for the `switch`-statement familiar from other programming languages.

## Example 1

The solution for the similar simplified problem without involving any packages:
```
\documentclass{report}

\NewDocumentCommand{\commandx}{}{Lorem ipsum}

\NewDocumentCommand{\commandy}{}{Lorem ipsum dolor sit}

\ExplSyntaxOn

\NewDocumentCommand{\genericcommand}{m}{
  \str_case:nnF {#1} {
    {x}{\commandx}
    {y}{\commandy}}
    {\msg_error:nn
      {just-my-document}
      {unknown-value-given-as-input}}}

\ExplSyntaxOff

\begin{document}

% should call \commandx
\genericcommand{x}

% should call \commandy
\genericcommand{y}

% should call \commandx again
\genericcommand{x}

% should error (as expected)
\genericcommand{z}

\end{document}
```

## Example 2

Solution for unifying the `svg` and `graphicx` interfaces:
```
\documentclass{report}

\usepackage{graphicx}
\usepackage{svg}

\ExplSyntaxOn

% argument 1: either `graphics` or `svg`
%
% argument 2: optional args that are just passed on
%
% argument 3: graphics file path
\NewDocumentCommand{\includeimage}{m o m}{
  \str_case:nnF {#1} {
    {graphics}{\includegraphics[#2]{#3}}
    {svg}{\includesvg[#2]{#3}}}
    {\msg_error:nn
      {just-my-document}
      {unknown-value-given-as-input}}}

\ExplSyntaxOff

\begin{document}

% includes an SVG
\includeimage{svg}[scale = 0.75]{img/s.svg}

% includes a PNG
\includeimage{graphics}[scale = 0.5]{img/p.png}

% errors because `png` is not recognized as a valid value for the first
% argument
\includeimage{png}[]{img/p.png}

\end{document}
```

## Some unresolved issues

There are two outstanding issues here:

1. In both examples the error message for the case of an unrecognized argument being passed to my command leaves a lot to be desired.

2. There is some code duplication in Example 2: the snippet `[#2]{#3}` is duplicated.

I'll probably ask follow-up questions about these issues.
Answer #3
samcarter
I'm sure you'll soon get some fancy l3 answer, but one possibility would be to use the `xstring` package:

```
\documentclass{report}

\usepackage{xstring}

\NewDocumentCommand{\commandx}{}{Lorem ipsum}
\NewDocumentCommand{\commandy}{}{Lorem ipsum dolor sit}

\NewDocumentCommand{\genericcommand}{m}{%
  \IfEq{#1}{x}{\commandx}{\commandy}%
}

\begin{document}

\commandx

\commandy

\genericcommand{x}

\genericcommand{y}

\end{document}
```

And applied to your graphics macro:

```
% !TeX program = txs:///arara
% arara: pdflatex: {synctex: on, interaction: nonstopmode, shell: yes}

\documentclass{report}

\usepackage{xstring}
\usepackage{svg}

\NewDocumentCommand{\includeimage}{m o m}{%
  \IfEq{#1}{svg}{
    \includesvg[#2]{#3}
  }{
    \includegraphics[#2]{#3}
  }
}

\begin{document}

\includeimage{graphics}[width=3cm]{example-image-duck}

\includeimage{svg}[width=4cm]{drawing}

\end{document}
```

(you'll don't actually need the `graphics` for non-svg images, just make sure all the svg images have the `svg` argument)

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.