Я могу заставить ЛАТЕКСНЫЙ макрос 'возвратить' имя файла?

Я пишу свой тезис/диссертацию и начиная с продолжающаяся работа, у меня не всегда есть действительные образы готовыми к числам, которые я поместил в свой документ, но по различным причинам хотят автоматически иметь его, заменяют фиктивным числом на месте, когда включенный графический файл не существует. Например, Я могу сделать что-то как \includegraphics[width=8cm]{\chapdir/figures/fluxcapacitor} (где \chapdir макрос для моего 'текущего' каталога главы, например. \def\chapdir{./ch_timetravel} и если существует нет ./ch_timetravel/figures/fluxcapacitor.jpg это вставит ./commands/dummy.jpg вместо этого.

Я структурировал свои макросы (возможно, наивно?) так, чтобы у меня был макрос (\figFileOrDummy) это определяет соответствующий файл для включения путем проверки, существует ли аргумент, предоставленный ему, так, чтобы я мог звонить \includegraphics[properties]{\figFileOrDummy{\chapdir/figures/fluxcapacitor}}. Кроме я получаю различные ошибки в зависимости от того, как я пытаюсь назвать это, которые, кажется, предполагают, что я приближаюсь к проблеме существенно дефектным способом насколько 'хорошее ЛАТЕКСНОЕ программирование' идет.

Вот макрос, чтобы проверить, существует ли файл (и 'возвратите' или имя файла или фиктивное имя файла):


\newcommand{\figFileOrDummy}[1]{%
    % Figure base name (no extension) to be used if the file exists
    \def\fodname{#1}%
    \def\dummyfig{commands/dummy}%
    % Check if output is PS (.EPS) or PDF (.JPG/.PDF/.PNG/...) figures
    \ifx\pdfoutput\undefined%
        % EPS figures only
        \IfFileExists{\fodname.eps}{}{\def\fodname{\dummyfig}}%
    \else%
        % Check existence of various extensions: PDF, TIF, TIFF, JPG, JPEG, PNG, MPS
        \def\figtest{0}% flag below compared to this value
        \IfFileExists{\fodname.pdf}{\def\figfilenamefound{1}}{\def\figfilenamefound{0}}%
        \IfFileExists{\fodname.jpg}{\def\figfilenamefound{1}}{}%
        \IfFileExists{\fodname.png}{\def\figfilenamefound{1}}{}%
        % and so on...
        % If no files found matching the filename (flag is 0) then use the dummy figure
        \ifx\figfilenamefound\figtest%
            \def\fodname{\dummyfig}%
        \fi%
    \fi%
    % 'return' the filename
    \fodname%
}%

С другой стороны, вот намного более простая версия, которая, кажется, имеет подобные проблемы:

\newcommand{\figFileOrDummy}[1]{%
    \def\dummyfig{commands/dummy}%
    \dummyfig%
}

\def команды, кажется, обрабатываются после расширения макроса, который они пытаются определить, таким образом, это заканчивает тем, что было \def {commands/dummy}... (отметьте пространство после \def) и очевидно жалуется.

Также это, кажется, рассматривает литеральный контент макроса как имя файла для \includegraphics, вместо того, чтобы решать/расширять его сначала, поэтому жалуется что файл '\def {commands/dummy}... .png' не существует..

Я попытался также делать что-то как \edef\figfilename{\figFileOrDummy{\chapdir/figures/fluxcapacitor}} пытаться вынудить это сделать \figfilename держите просто значение, а не полный макрос, но я добираюсь Undefined control sequence ошибка жалуясь переменные я пытаюсь \def в \figFileOrDummy макрос не определен.

Таким образом, мой вопрос также

  1. Как я заставляю этот макрос расшириться правильно?; или
  2. Если это - неправильный способ структурировать мои макросы, как я должен на самом деле структурировать такой макрос, чтобы смочь ввести фиктивные/реальные числа автоматически?; или
  3. Существует ли пакет, который уже обрабатывает этот тип вещи приятно, что я пропустил?

Я чувствую, что пропускаю что-то довольно фундаментальное здесь...

9
задан drfrogsplat 18 May 2010 в 09:55
поделиться

3 ответа

Я думаю, дело в том, что \expandafter интересуется своими аргументами только как строкой, представляющей имя файла, поэтому не оценивает его - макроязыки ленивы! Try \expandafter {\includegraphics[width=8cm]}{\chapdir/figures/fluxcapacitor}.

Два замечания по стилю:

  1. Вам не нужно ставить % в конце строки, чтобы остановить ложные пробельные символы, если строка заканчивается управляющей последовательностью: управляющая последовательность поглощает все последующие пробельные символы, включая конец строки. На мой вкус, это делает код гораздо более читабельным. Обратите внимание, что, в частности, для "рта" Текса оба \def\newcs{abc} и \def \newcs {abc} идентичны: это точно такая же последовательность лексем.
  2. Я удалил код вокруг \figtest: вы получаете более качественный отчет об ошибках - всегда в цене в Tex - если используете либо примитив \newif (создайте новый тест с помощью \newif\figexists, установите/сбросьте с помощью \figexiststrue, \figexistsfalse, и проверьте с помощью \iffigexists...), либо пакет Latex ifthenelse (чтобы придерживаться ортодоксальности).

Очищенный код

Сначала я подумал, что проблема кроется в другом месте, поэтому написал что-то более красивое:

\def\dummypath{commands/dummy}%
\ifx\pdfoutput\undefined
\def\figFileOrDummy#1{\IfFileExists
    {#1.eps}{#1}\dummypath}
\else
\def\figFileOrDummy#1{\IfFileExists
    {#1.pdf}{#1}{\IfFileExists
      {#1.jpg}{#1}{\IfFileExists
        {#1.png}{#1}\dummypath}}} %or have more graphics types, if you like.
\fi
3
ответ дан 4 December 2019 в 23:38
поделиться

Хорошо, я нашел возможный ответ на №2, реструктурируя способ работы макросов (и вроде как используя некоторые предложения из ответа Чарльза Стюарта - я признаю, что мне не нравится «внешний вид» то, что, кажется, широко считается хорошим кодом LaTeX, я, возможно, слишком укоренился в своих способах C / C ++, чтобы быть настоящим программистом LaTeX).

В любом случае, мой ответ ...

Вместо того, чтобы пытаться создать имя файла в макросе для передачи в макрос \ includegraphics , создайте макрос, который обертывает \ includegraphics и передает ему настоящее или фиктивное имя файла. Похоже, это позволяет избежать передачи (в качестве аргумента) длинного скрипта / макроса, хотя я не вижу веских причин , почему его следует писать таким образом. Но он работает ...

% Dummy figure file
\def\dummyfigure{commands/dummy}%

% Includegraphics wrapper macro to include either dummy or real figure
\ifx\pdfoutput\undefined
\newcommand{\incgfx}[2]{%
    \def\testfile{\chapdir/fig/#2}%
    \IfFileExists{\testfile.eps}%
        {\includegraphics[#1]{\testfile}}% test file found
        {\includegraphics[#1]{\dummyfigure}}% test file not found
}
\else
\newcommand{\incgfx}[2]{%
    \def\figfilename{\dummyfigure}
    \def\testfile{\chapdir/fig/#2}
    \IfFileExists{\testfile.jpg}{\def\figfilename{\testfile}}{}
    \IfFileExists{\testfile.png}{\def\figfilename{\testfile}}{}
    \IfFileExists{\testfile.pdf}{\def\figfilename{\testfile}}{}
    \IfFileExists{\testfile.jpeg}{\def\figfilename{\testfile}}{}
    \IfFileExists{\testfile.tif}{\def\figfilename{\testfile}}{}
    \IfFileExists{\testfile.tiff}{\def\figfilename{\testfile}}{}
    \includegraphics[#1]{\figfilename}
}
\fi

Это позволяет использовать его по назначению:

\begin{figure}
    \begin{center}
        \incgfx{height=3cm}{\chapdir/fig/fluxcapacitor}
        \caption{...}\label{fig:...}
    \end{center}
\end{figure}

Опять же, я хотел бы думать, что есть способ заставить исходную идею работать вместо того, чтобы заставлять оболочка для существующих функций, но пока этого достаточно ...

2
ответ дан 4 December 2019 в 23:38
поделиться

Ответ на №3: ​​Для этой цели я считаю очень полезным пакет todonotes . Он не обеспечивает тот уровень автоматизации, который стремится предложить ваш код, но в нем есть очень хорошая команда \ missingfigure , которая позволяет вам поставить пустую рамку для, как вы думаете, отсутствующей цифры.

1
ответ дан 4 December 2019 в 23:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: