如何使 \animategraphics 适应带有空格的文件名?

如何使 \animategraphics 适应带有空格的文件名?
% this filename is main.tex
% compile it with "pdflatex -shell-escape main" (without the quotes)

\documentclass{article}

\usepackage{filecontents}

% Create a PDF file that consist of some pages
\begin{filecontents*}{"heart animation.tex"}
\documentclass[border=12pt,pstricks]{standalone}
\usepackage{pst-plot}
\usepackage[nomessages]{fp}
\FPeval\Delta{round(2*pi/30:2)}

\def\x(#1){sin(#1)^3}
\def\y(#1){(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))/16}

\psset{algebraic,plotpoints=300}

\begin{document}
\multido{\n=0.00+\Delta}{31}{%
\begin{pspicture}[showgrid=false](-2,-2)(2,2)
    \psparametricplot[origin={0,0.15},linecolor=red]{0}{\n}{\x(t)|\y(t)}
\end{pspicture}}

\end{document}
\end{filecontents*}

\immediate\write18{latex "heart animation.tex"}
\immediate\write18{dvips "heart animation.dvi"}
\immediate\write18{ps2pdf "heart animation.ps"}
% sometimes you need to disable auto rotate in ps2pdf. Please follow up if you really need it!
% delete auxiliary files generated by the 3 commands above.
\makeatletter
\@for\x:={tex,dvi,ps,log,aux,out,toc,nav,snm}\do{\immediate\write18{cmd /c if exist "heart animation.\x" del "heart animation.\x"}}
\makeatother

\usepackage{animate}
\begin{document}
%\animategraphics[controls,autoplay,loop,scale=<integer>]{<frame rate>}{<PDF filename without extension>}{<left blank>}{<left blank>}
\animategraphics[controls,autoplay,loop,scale=1]{10}{"heart animation"}{}{}
\end{document}

如何使\animategraphics带有空格的文件名更令人满意?

答案1

问题在于\animategraphics使用 LaTeX时\IfFileExists,它会使用空格作为文件名的结束标记。结果\@filef@und包含包含最后一个空格的文件名。\animategraphics然后通过删除空格\zap@space来删除中间的空格。

以下解决方法重新定义\animategraphics。它使用包grffile \grffile@IfFileExists而不是\IfFileExists,设置\@filef@und为不带末尾空格的文件名并中和\zap@space

\documentclass{article}

\usepackage{animate}
\usepackage{grffile}
\usepackage{letltxmacro}
\makeatletter
\@ifdefinable{org@animategraphics}{%
  \LetLtxMacro\org@animategraphics\animategraphics
  \renewcommand*{\animategraphics}{%
    \begingroup
    \@ifnextchar[{%
      \def\anigrf@opt{[}%
      \anigrf@animategraphics
    }{%
      \let\anigrf@opt\@empty
      \anigrf@animategraphics
    }%
  }%
  \newcommand{\anigrf@animategraphics}[5][]{%
    \renewcommand{\IfFileExists}[3]{%
      \grffile@IfFileExists{##1}{%
        \let\@filef@und\grffile@file@found
        \def\zap@space####1 \@empty{####1}%
        ##2%
      }{##3}%
    }%
    \ifx\anigrf@opt\@empty
      \org@animategraphics{#2}{#3}{#4}{#5}%
    \else
      \org@animategraphics[{#1}]{#2}{#3}{#4}{#5}%
    \fi
    \endgroup
  }%
}
\makeatother

\begin{document}
  \animategraphics[controls,autoplay,loop,scale=1]{10}{heart animation}{}{}%
\end{document}

动画更新 2013/04/23

自 2013/04/23(或之前?)起,软件包animate支持引用文件名(感谢 mozartstraße 的提示):

  \animategraphics[controls,autoplay,loop,scale=1]{10}{"heart animation"}{}{}%

因此不需要补丁。但是,我认为引号不属于用户界面,已经有花括号来分隔文件名参数。因此,如果检测到空格,以下更新的补丁会自动添加引号。如果已经给出引号,则文件名参数不会更改。

\documentclass{article}

\usepackage{animate}
\usepackage{grffile}
\usepackage{letltxmacro}
\makeatletter
\@ifdefinable{org@animategraphics}{%
  \LetLtxMacro\org@animategraphics\animategraphics
  \renewcommand*{\animategraphics}{%
    \begingroup
    \@ifnextchar[{%
      \def\anigrf@opt{[}%
      \anigrf@animategraphics
    }{%
      \let\anigrf@opt\@empty
      \anigrf@animategraphics
    }%
  }%
  \@ifpackagelater{animate}{2013/04/23}{%
    \def\anigrf@testspace#1 #2\@nil{%
      \def\anigrf@tmp{#2}%
    }%
    \def\anigrf@testquote#1"#2\@nil{%
      \def\anigrf@tmp{#2}%
    }%
    \newcommand{\anigrf@animategraphics}[3][]{%
      % do nothing if the file name contains quotes
      \edef\anigrf@file{#3}%
      \@onelevel@sanitize\anigrf@file
      \expandafter\anigrf@testquote\anigrf@file"\@nil
      \ifx\anigrf@tmp\@empty % file name without quote(s)
        % test for space in the file name
        \@firstofone{\expandafter\anigrf@testspace\anigrf@file} \@nil
        \ifx\anigrf@tmp\@empty % file name without space(s)
          % do nothing, no spaces found
          \expandafter\expandafter\expandafter\@firstoftwo
        \else % file name with space(s)
          \expandafter\expandafter\expandafter\@secondoftwo
        \fi
      \else % file name with quote(s)
        \expandafter\@firstoftwo
      \fi
      {\anigrf@@animategraphics{#1}{#2}{#3}}%
      {\anigrf@@animategraphics{#1}{#2}{"#3"}}%
    }%
    \newcommand{\anigrf@@animategraphics}[5]{%
      \ifx\anigrf@opt\@empty
        \org@animategraphics{#2}{#3}{#4}{#5}%
      \else
        \org@animategraphics[{#1}]{#2}{#3}{#4}{#5}%
      \fi
      \endgroup
    }% 
  }{%
    \newcommand{\anigrf@animategraphics}[5][]{%
      \renewcommand{\IfFileExists}[3]{%
        \grffile@IfFileExists{##1}{%
          \let\@filef@und\grffile@file@found
          \def\zap@space####1 \@empty{####1}%
          ##2%
        }{##3}%
      }%
      \ifx\anigrf@opt\@empty
        \org@animategraphics{#2}{#3}{#4}{#5}%
      \else
        \org@animategraphics[{#1}]{#2}{#3}{#4}{#5}%
      \fi
      \endgroup
    }%
  }%
}
\makeatother

\begin{document}
  \animategraphics[controls,autoplay,loop,scale=1]{10}{heart animation}{}{}%
\end{document}

答案2

出于某些原因,animate不喜欢文件名中有空格。一般来说,应尽可能避免使用空格。当您输入\animategraphics文件名"heart animation", the package tries to includeheartanimation.pdf 时,删除名称中的空格会发生什么。

解决方案是在吸收第二个强制参数之前更改空间的类别代码\animategraphics

\documentclass{article}
\usepackage{animate}

\newcommand{\myanimategraphics}[2][]{%
  \begingroup
    \def\myagtempopt{\unexpanded{#1}}%
    \def\myagtempmand{\unexpanded{#2}}%
    \catcode`\ =12 \myanimategraphicsaux
}
\def\myanimategraphicsaux#1#2#3{%
  \begingroup\edef\x{\endgroup
    \noexpand\animategraphics[\myagtempopt]{\myagtempmand}}%
  \x{#1}{#2}{#3}\endgroup}

\begin{document}
\myanimategraphics{3}{"heart animation"}{}{}
\end{document}

答案3

最新的animate包可以接受带空格的路径,但必须用引号括起来。

结果,Heiko Oberdiek 的解决方案不再起作用(它会产生编译错误)。

相关内容