9

我正在写我的论文/论文,由于它是一项正在进行的工作,我并不总是为我放入文档中的数字准备好实际图像,但出于各种原因,我希望它自动替换一个虚拟数字当包含的图形文件不存在时。例如,我可以做类似的事情\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}}. 除了我遇到各种错误,具体取决于我如何尝试调用它,这似乎表明就“良好的 LaTeX 编程”而言,我正在以一种根本有缺陷的方式解决问题。

这是检查文件是否存在的宏(并“返回”文件名或虚拟文件名):


\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. 是否有一个包已经很好地处理了我忽略的这种类型的事情?

我觉得我在这里错过了一些非常基本的东西......

4

3 回答 3

3

我认为关键是 \expandafter 只对它的参数感兴趣,因为它是一个代表文件名的字符串,所以不评估它——宏语言是懒惰的!试试\expandafter {\includegraphics[width=8cm]}{\chapdir/figures/fluxcapacitor}

两点风格:

  1. 如果该行以控制序列结尾,则无需将 % 放在行尾以停止虚假空格:控制序列会吞噬所有后续空格,包括行尾。这使代码更具可读性,符合我的口味。请注意,特别是对于 Tex 的“嘴”来说,两者\def\newcs{abc}\def \newcs {abc}是相同的:它们是完全相同的标记序列。
  2. 我放弃了 \figtest 周围的代码:如果你使用 \newif 原语(用 \newif\figexists 创建新测试,用 \figexiststrue 设置/重置,\figexistsfalse 和 test与 \ifigexists...)或 Latex ifthenelse 包(与正统保持一致)。

清理后的代码

我首先认为问题出在其他地方,所以写了一些更漂亮的东西:

\def\dummypath{命令/虚拟}%
\ifx\pdf输出\未定义
\def\figFileOrDummy#1{\IfFileExists
    {#1.eps}{#1}\dummypath}
\别的
\def\figFileOrDummy#1{\IfFileExists
    {#1.pdf}{#1}{\IfFileExists
      {#1.jpg}{#1}{\IfFileExists
        {#1.png}{#1}\dummypath}}} %或者有更多的图形类型,如果你喜欢的话。
\fi
于 2010-05-18T12:40:32.840 回答
2

好吧,所以我找到了#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}

再说一次,我想有一种方法可以使最初的想法发挥作用,而不必为现有功能制作包装器,但现在就可以了……

于 2010-05-19T04:57:21.257 回答
1

对#3 的回答:为此,我发现该todonotes软件包非常有用。它没有提供您的代码旨在提供的自动化级别,但它有一个非常好的\missingfigure命令,可以让您为丢失的数字放置一个虚拟框。

于 2010-05-18T10:07:21.753 回答