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?
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)
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.
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.