if-Bedingung für nächsten Befehl

if-Bedingung für nächsten Befehl

Nachdem ich angefangen hatte, meine eigenen Umgebungen zu erstellen, fragte ich mich, ob es eine if-Bedingung gibt, die prüft, was der nächste Befehl ist, und dann die Option bietet, vor dem nächsten Befehl etwas auszuführen. Ein Pseudocode-Beispiel für das, was ich suche:

\newenvironment{test}{
    ifnext{\begin{itemize}}{true: do something}{false: do other things}
    }
    {
}

Antwort1

LaTeX verfügt über das Makro \@ifnextchar. Der Name ist vielleicht etwas irreführend, denn man kann es nicht nur verwenden, um das nächste einzelne Zeichen zu testen, sondern auch für ein Makro mit einer definierten Bedeutung, z. B. kann man testen, ob das nächste Element im Eingabestrom ist \begin.

Dies kann zum Erstellen eines Makros verwendet werden \ifnextenv. Es benötigt drei Argumente: den Namen der Umgebung, Code, der ausgeführt wird, wenn diese Umgebung darauf folgt, und Code, der andernfalls ausgeführt wird. Das Makro prüft, ob das nächste Element im Eingabestrom (nach seinen drei Argumenten) ist \begin. Wenn dies der Fall ist, prüft es, ob das erste Argument mit \begindem ersten Argument \ifnextenvübereinstimmt \pdf@strcmp.

Anschließend werden die Zweige entsprechend den Testergebnissen eingefügt.

In diesem Anwendungsbeispiel \ifnextenvwird automatisch ein „ itemizeif“ nach „ \begin{test}no \begin{enumerate}follow“ eingefügt.

\documentclass[]{article}

\usepackage{pdftexcmds}

\makeatletter
\newcommand\ifnextenv[3]
  {%
    \@ifnextchar\begin{\@ifnextenv{#1}{#2}{#3}}{#3}%
  }
\newcommand\@ifnextenv[5]
  {%
    \ifnum\pdf@strcmp{#1}{#5}=0
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    {#2}
    {#3}%
    \begin{#5}%
  }
\makeatother

\newenvironment{test}
  {%
    \ifnextenv{enumerate}
      {\def\test@end{}}
      {\def\test@end{\enditemize}\itemize}%
  }
  {%
    \test@end
  }

\begin{document}
\begin{test}
\item foo
\item bar
\end{test}

\begin{test}
  \begin{enumerate}
    \item foo
    \item bar
  \end{enumerate}
\end{test}
\end{document}

Bildbeschreibung hier eingeben

Antwort2

Hier ist eine Möglichkeit, dies mit einem Token-Zyklus zu tun.

Jedes Mal, wenn ich ein finde \begin{itemize}, führe ich vorab aus \PREitemize, was ich hier auf setze \par Hi Mom, I am about to itemize. Wenn ein \beginerkannt wird, es aber nicht ist itemize, führe ich vorab aus \PREbegin, was ich hier auf setze \par Sorry, this begin is not itemize.

\documentclass{article}
\usepackage{tokcycle}
\def\ITM{itemize}
\def\TRUESET{T}
\def\PREitemize{\par Hi Mom, I am about to itemize}
\def\PREbegin{\par Sorry, this begin is not itemize}
\stripgroupingtrue
\tokcycleenvironment\finditemize
{\addcytoks{##1}}
{\tctestifx{\TRUESET\BEGgo}%
  {\def\tmp{##1}\tctestifx{\ITM\tmp}%
    {\addcytoks[1]{\PREitemize}}{\addcytoks[1]{\PREbegin}}
    \addcytoks{\begin{##1}}}%
  {\addcytoks{{##1}}}%
 \def\BEGgo{F}%
}
{\tctestifx{\begin##1}{\def\BEGgo{T}}{\addcytoks{##1}}}
{\addcytoks{##1}}
\begin{document}
\finditemize
Here is a test
\begin{itemize}
\item A
\begin{itemize}
\item A.1
\item A.2
\end{itemize}
\item B
\item C
\end{itemize}
\begin{enumerate}
\item A
\item B
\item C
\end{enumerate}
\endfinditemize
\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen