
Я пытаюсь написать макрос, который принимает имя файла в качестве входных данных, изменяет его расширение и передает его в \includegraphics
.
Я видел\includegraphics, попробуйте другое расширение, что дает альтернативное решение, но мне интересно понять, почему я получаюendcsnameиномер параметраошибки в моем текущем коде (к тому же, я думаю, это решение не работает в xelatex):
\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}
Первый подход был наивным, и ядуматьПричина, по которой это не работает, заключается в том, что внутри graphicx создается команда, включающая часть аргумента имени файла (расширение файла), чтобы использовать разные макросы для каждого типа файла, и, похоже, что перед этим она не расширяет свой аргумент.
Второй подход, вероятно, не срабатывает по той же причине (
\pdfname
не раскрывается), но я не уверен, почему я получаю другую ошибку.На третий вариант я возлагал большие надежды, и не понимаю, почему он не сработал.
Последний, я думаю, успеет
expandafter
поглотить всеincludegraphics
, прежде чем сотворит свое волшебство.
Как правильно?
решение1
Макросы xstring
имеют необязательный аргумент в конце, который используется для сохранения результата операции в макросе, который можно использовать в этом случае.
Также \StrSubstitute
не имеет версии со звездочками. Кроме того, вы должны предоставить три аргумента: полную строку, строку поиска и строку замены, тогда как ваш MWE имеет только полную строку и строку поиска. Если хотите, вы можете оставить строку замены пустой ( \StrSubstitute{#1}{.svg}{}[\tmpname]
), чтобы попробовать все доступные расширения.
Рабочая МВЭ:
\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}
Результат: