условие if для следующей команды

условие if для следующей команды

После того, как я начал создавать свои собственные среды, мне стало интересно, есть ли условие if, которое проверяет, какая следующая команда, а затем дает возможность запустить что-то перед следующей командой. Пример псевдокода для того, что я ищу:

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

решение1

В LaTeX есть макрос \@ifnextchar. Название может немного вводить в заблуждение, вы можете использовать его не только для проверки следующего одиночного символа, но и для макроса с определенным значением, например, вы можете проверить, является ли следующее во входном потоке \begin.

Это можно использовать для создания макроса \ifnextenv. Он будет принимать три аргумента, имя среды, код, который будет выполнен, если эта среда следует за ним, и код, который выполняется в противном случае. Макрос проверит, является ли следующее во входном потоке (после трех его аргументов) \begin. Если это так, он проверит, \beginсоответствует ли первый аргумент первому аргументу с \ifnextenvпомощью\pdf@strcmp .

Затем он вставит ветви в соответствии с результатами теста.

В этом примере использования используется \ifnextenvавтоматическая вставка itemizeif после \begin{test}no \begin{enumerate}following.

\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}

введите описание изображения здесь

решение2

Вот как это сделать с помощью цикла токенов.

Каждый раз, когда я нахожу \begin{itemize}, я предварительно выполняю \PREitemize, который здесь установлен на \par Hi Mom, I am about to itemize. Если есть \beginобнаруженный , но это не itemize, я предварительно выполняю \PREbegin, здесь установлен на \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}

введите описание изображения здесь

Связанный контент