condição if para o próximo comando

condição if para o próximo comando

Depois que comecei a construir meus próprios ambientes, fiquei pensando se existe uma condição if, que verifica qual é o próximo comando e dá a opção de executar algo antes do próximo comando. Um exemplo de pseudocódigo para o que estou procurando:

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

Responder1

LaTeX tem a macro \@ifnextchar. O nome pode ser um pouco enganador, você pode usá-lo não apenas para testar o próximo caractere, mas também para uma macro com um significado definido, por exemplo, você pode testar se o próximo item no fluxo de entrada é \begin.

Isso pode ser usado para construir uma macro \ifnextenv. Serão necessários três argumentos, o nome do ambiente, o código que será executado se esse ambiente o seguir e o código que será executado caso contrário. A macro verificará se o próximo item no fluxo de entrada (após seus três argumentos) é \begin. Se for esse o caso, ele verificará se o primeiro argumento \begincorresponde ao primeiro argumento de \ifnextenvusing \pdf@strcmp.

Em seguida, inserirá os ramos de acordo com o resultado do teste.

Este exemplo de uso usa \ifnextenvpara inserir automaticamente um itemizeif após \begin{test}no \begin{enumerate}follow.

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

insira a descrição da imagem aqui

Responder2

Aqui está uma maneira de fazer isso com um ciclo de token.

Cada vez que encontro um \begin{itemize}, eu pré-executo \PREitemize, que aqui defino como \par Hi Mom, I am about to itemize. Se for \begindetectado, mas não for itemize, eu pré-executo \PREbegin, aqui definido como \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}

insira a descrição da imagem aqui

informação relacionada