连续多次应用同一命令

连续多次应用同一命令

我的一个文件中有 88 张图片。我想制作一个包含 88 张幻灯片的投影仪演示文稿,每张幻灯片上都有一张图片。图片文件的名称按编号排序(1-88)。我创建了一个新的计数器 ( pic) 和一个新命令 ( \folie),它生成一张带有图片的幻灯片,并将计数器加一。这样,我制作的每张新幻灯片\folie上都有下一张图片。这正是我想要的。

如何让 Latex\folie连续执行 88 次命令,而无需键入 (或复制粘贴) 88 次?我想我正在寻找类似\dothecommandthisoften{\folie}{88}或类似的东西。

这是有问题的命令:

\newcommand{\folie}{
\begin{frame}
    \begin{center}
        \includegraphics[scale=.5]{\thepic}
    \end{center}
\addtocounter{pic}{1}
\end{frame}
}

答案1

在该包的帮助下forloop,您可以定义一个自动循环计数器的命令:

\documentclass{beamer}

\usepackage{forloop}

\newcounter{pic}

\newcommand{\insertallimages}{\forloop{pic}{1}{\value{pic} < 89}{\begin{frame}
    \begin{center}
        \includegraphics[scale=.5]{\thepic}
    \end{center}
\end{frame}}}

\begin{document}
\insertallimages
\end{document}

答案2

您可以使用\foreach包的命令pgffor

\documentclass{beamer}

\usepackage{graphicx}
\usepackage{pgffor}

\begin{document}

\foreach \x in {1,...,88}{%
 \begin{frame}
  \begin{center}
   \includegraphics{\x}
  \end{center}
 \end{frame}
}

\end{document}

它的优点是您不局限于一个计数器。如果您有其他图像,您也可以将它们包含在列表中:

\foreach \x in {1,...,88,image,graph,whatever}{%
 \begin{frame}
  \begin{center}
   \includegraphics{\x}
  \end{center}
 \end{frame}
}

答案3

让 beamer 为你完成即可:

\documentclass{beamer}
\usepackage{xmpmulti}
\begin{document}

    %asuming you images are called "something-1.png" etc. 
    \begin{frame}
        \multiinclude[<+->][format=png, start=1, end=88, graphics={width=\textwidth}]{something}
    \end{frame}

\end{document}

答案4

使用\numexpreTeX 扩展可以轻松实现尾递归循环。

\documentclass[a4paper]{article}

\begingroup
\makeatletter
\@firstofone{%
  \endgroup
  \newcommand\PassFirstToSecond[2]{#2{#1}}%
  \newcommand{\folieloop}[2]{%
    \expandafter\PassFirstToSecond\expandafter{\number#2}%
    {\expandafter\folieloopnormalizednumbers\expandafter{\number#1}}%
  }%
  \newcommand{\folieloopnormalizednumbers}[2]{%
    \ifnum#1>#2 %
    \expandafter\@gobble\else\expandafter\@firstofone\fi
    {%
      \begin{frame}%
        \begin{center}%
          \includegraphics[scale=.5]{#1}%
        \end{center}%
      \end{frame}%
%      Testing tail recursion without frames:
%      Folie #1.\par
      \expandafter\folieloopnormalizednumbers\expandafter{\number\numexpr#1+1\relax}{#2}%
    }%
  }%
}%

\begin{document}

\folieloop{1}{4} %from 1 to 4

\folieloop{\numexpr1+3-2}{4}  %from 2 to 4

\newcounter{mycounter}
\setcounter{mycounter}{10}

\folieloop{\numexpr2+5}{\value{mycounter}}  %from 7 to 10

\folieloop{14}{14}  %only 14

\end{document}

如果您没有 eTeX 扩展,可以实现可扩展递增:

\documentclass[a4paper]{article}

\begingroup
\makeatletter
\@firstofone{%
  \endgroup
  %% \UD@increment{<non-negative integeral number k as sequence of
  %%                catcode-12(other)-character-tokens
  %%                from the set 0123456789>}
  %% ->
  %% <non-negative integeral number (k+1) as sequence of
  %%                catcode-12(other)-character-tokens
  %%                from the set 0123456789>
  %%
  %% Emptiness is interpreted as "0".
  %%
  %% !! There is no check implemented on the argument being a proper
  %%    digit sequence !!
  %%
  %% Leading zeros are not removed but the least significant leading zero
  %% may get replaced by a carry-over "1".
  %%
  %% Examples:
  %%  \UD@increment{725} -> 726
  %%  \UD@increment{999} -> 1000
  %%  \UD@increment{00999} -> 01000
  %%  \UD@increment{00001} -> 00002
  %%  \UD@increment{0} -> 1
  %%  \UD@increment{} -> 1
  %%
  %% The result is delivered after two expansion-steps.
  \newcommand\UD@increment[1]{%
    \romannumeral0\UD@reverse{\UD@incrementfork{}}{\relax}{}#1\relax
  }%
  %%.........................................................................
  %% \UD@reverse reverses \relax-delimited list of undelimited arguments.
  %% From each undelimited argument the outermost level of surrounding 
  %% braces will removed if present.
  %% #1 - Tokens to put in front of reversed list.
  %% #2 - Tokens to put behind reversed list.
  %% #3 - list elements collected in reversed order so far.
  %% #4 - Current element of to-be-reversed list.
  \newcommand\UD@reverse[4]{%
    \ifx\relax#4%
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    {#1#3#2}{\UD@reverse{#1}{#2}{#4#3}}%
  }%
  %%.........................................................................
  %% \UD@incrementfork replaces the leading digit of a \relax-delimited
  %% digit-sequence by the next higher digit. The leading digit that is
  %% to be replaced is #2. #1 contains carryover-zeros in case
  %% \UD@incrementfork is called recursively due to leading digits
  %% being "9"s.
  \newcommand\UD@incrementfork[2]{%
    \UD@incrementselect
    #2123456789\relax{\UD@reverse{ }{}{}#11}% <- replace leading digit 0 by 1
    0#223456789\relax{\UD@reverse{ }{}{}#12}% <- replace leading digit 1 by 2
    01#23456789\relax{\UD@reverse{ }{}{}#13}% <-  replace leading digit 2 by 3
    012#2456789\relax{\UD@reverse{ }{}{}#14}% <-  replace leading digit 3 by 4
    0123#256789\relax{\UD@reverse{ }{}{}#15}% <-  replace leading digit 4 by 5
    01234#26789\relax{\UD@reverse{ }{}{}#16}% <-  replace leading digit 5 by 6
    012345#2789\relax{\UD@reverse{ }{}{}#17}% <-  replace leading digit 6 by 7
    0123456#289\relax{\UD@reverse{ }{}{}#18}% <-  replace leading digit 7 by 8
    01234567#29\relax{\UD@reverse{ }{}{}#19}% <-  replace leading digit 8 by 9
    012345678#2\relax{\UD@incrementfork{#10}}% <- leading digit is 9, so add a carryover-0 and look at the next digit as leading digit.
    0123456789#2{\UD@reverse{ }{}{}#11\relax}% <- No more digits left as
                                             %    either all digits were 9, thus as many carry-overs occurred as digits were present,
                                             %    or the digit-sequence was empty and thus considered 0.
    0123456789\relax{\UD@reverse{ }{}{}#11#2}% <- The thing is not a digit. Thus put it back and end.
                                             %    Outermost level of braces surrounding the thing get removed.
                                             %    A better way of handling the situation would be checking whether
                                             %    \UD@increment's argument is a proper digit sequence.
                                             %    But is it worth the efforts?
                                             %    What about spaces within the argument? In case checking
                                             %    is to be implemented by means of undelimited arguments, beware
                                             %    in mind that space-tokens in front of undelimited arguments
                                             %    get silently discarded by (La)TeX. Also need to cope with single digits being nested in braces...
    \relax\relax
  }%
  \newcommand\UD@incrementselect{}%
  \long\def\UD@incrementselect#10123456789\relax#2#3\relax\relax{#2}%
  %%-------------------------------------------------------------------------
  \newcommand\PassFirstToSecond[2]{#2{#1}}%
  \newcommand{\folieloop}[2]{%
    \expandafter\PassFirstToSecond\expandafter{\number#2}%
    {\expandafter\folieloopnormalizednumbers\expandafter{\number#1}}%
  }%
  \newcommand{\folieloopnormalizednumbers}[2]{%
    \ifnum#1>#2 %
    \expandafter\@gobble\else\expandafter\@firstofone\fi
    {%
      \begin{frame}%
        \begin{center}%
          \includegraphics[scale=.5]{#1}%
        \end{center}%
      \end{frame}%
%      Testing tail recursion without frames:
%      Folie #1.\par
      \expandafter\folieloopnormalizednumbers\expandafter{\number\UD@increment{#1}}{#2}%
    }%
  }%
}%

\begin{document}

\folieloop{1}{4} %from 1 to 4

\folieloop{2}{4}  %from 2 to 4

\newcounter{mycounter}
\setcounter{mycounter}{10}

\folieloop{7}{\value{mycounter}}  %from 7 to 10

\folieloop{14}{14}  %only 14

\end{document} 

相关内容