
Estou tentando escrever uma macro que receba um nome de arquivo como entrada, altere sua extensão e passe-o para \includegraphics
.
Eu tenho visto\includegraphics, tente outra extensão, que fornece uma solução alternativa, mas estou curioso para entender por que estou recebendonome finalenúmero do parâmetroerros no meu código atual (além disso, essa solução não funciona no xelatex, eu acho):
\documentclass{article}
\usepackage{graphicx}
\usepackage{xstring}
\usepackage{letltxmacro}
\LetLtxMacro{\IncludeGraphics}{\includegraphics}
\newcommand{\svgtopdf}[1]
{\IfSubStr{#1}{.svg}{\StrSubstitute*{#1}{.svg}}{#1}}
\newcommand{\includegraphicsNaive}[2][]
{\IncludeGraphics[#1]{\svgtopdf{#2}}}
\newcommand{\includegraphicsEdef}[2][]
{\edef\pdfname{\svgtopdf{#2}}
\IncludeGraphics[#1]{\pdfname}}
\newcommand{\includegraphicsNoExpand}[2][]
{\edef\x{\noexpand\IncludeGraphics[#1]{\svgtopdf{#2}}}%
\x{}}
\newcommand{\includegraphicsExpandafter}[2][]
{\IncludeGraphics[#1]\expandafter{\svgtopdf{#2}}}
\begin{document}
\includegraphicsNaive{img.svg} % ERROR: Missing endcsname inserted.
\includegraphicsEdef{img.svg} % ERROR: Illegal parameter number in definition of \pdfname.
\includegraphicsNoExpand{img.svg} % ERROR: Illegal parameter number in definition of \x.
\includegraphicsExpandafter{img.svg} % ERROR: LaTeX Error: File `' not found.
\end{document}
A primeira abordagem foi a ingênua, e eupensara razão pela qual não funciona é que internamente o graphicx constrói um comando que inclui parte do argumento do nome do arquivo (a extensão do arquivo) para usar uma macro diferente para cada tipo de arquivo, e parece que não expande seu argumento antes de fazer isso.
A segunda abordagem provavelmente falha pelo mesmo motivo (
\pdfname
não está expandida), mas não sei por que recebo um erro diferente.O terceiro eu estava esperançoso e não sei por que não funciona.
Acho que o último terá sido
expandafter
consumidoincludegraphics
antes de poder fazer sua mágica.
Qual é o caminho certo?
Responder1
As xstring
macros possuem um argumento opcional no final que serve para armazenar o resultado da operação em uma macro, que pode ser utilizada neste caso.
Além disso, \StrSubstitute
não possui uma versão com estrela. Além disso, você deve fornecer três argumentos: a string completa, a string de pesquisa e a string de substituição, enquanto seu MWE possui apenas a string completa e a string de pesquisa. Se desejar, você pode deixar a string de substituição vazia ( \StrSubstitute{#1}{.svg}{}[\tmpname]
) para tentar todas as extensões disponíveis.
MWE de trabalho:
\documentclass{article}
\usepackage{graphicx}
\usepackage{xstring}
\usepackage{letltxmacro}
\LetLtxMacro{\IncludeGraphics}{\includegraphics}
\newcommand{\svgtopdf}[1]
{\IfSubStr{#1}{.svg}{\StrSubstitute{#1}{.svg}{.pdf}[\tmpname]}{\def\tmpname{#1}}}
\newcommand{\includegraphicsNaive}[2][]
{\svgtopdf{#2}%
\IncludeGraphics[#1]{\tmpname}}
\begin{document}
\includegraphicsNaive[width=3cm]{example-image.svg}
\includegraphicsNaive[width=3cm]{example-image-a.pdf}
\includegraphicsNaive[width=3cm]{example-image-b}
\end{document}
Resultado: