Después de comenzar a construir mis propios entornos, me preguntaba si existe una condición if que verifique cuál es el siguiente comando y luego ofrezca la opción de ejecutar algo antes del siguiente comando. Un ejemplo de pseudocódigo para lo que estoy buscando:
\newenvironment{test}{
ifnext{\begin{itemize}}{true: do something}{false: do other things}
}
{
}
Respuesta1
LaTeX tiene la macro \@ifnextchar
. El nombre puede ser un poco engañoso, no sólo puede usarlo para probar el siguiente carácter, sino también para una macro con un significado definido, por ejemplo, puede probar si lo siguiente en el flujo de entrada es \begin
.
Esto se puede utilizar para construir una macro \ifnextenv
. Se necesitarán tres argumentos, el nombre del entorno, el código que se ejecutará si ese entorno lo sigue y el código que se ejecutará en caso contrario. La macro comprobará si lo siguiente en el flujo de entrada (después de sus tres argumentos) es \begin
. Si ese es el caso, verificará si el primer argumento \begin
coincide con el primer argumento \ifnextenv
usando \pdf@strcmp
.
Luego insertará las ramas según los resultados de la prueba.
Este ejemplo de uso utiliza \ifnextenv
para insertar automáticamente un itemize
if después de \begin{test}
que no \begin{enumerate}
siga.
\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}
Respuesta2
Aquí hay una manera de hacerlo con un ciclo de token.
Cada vez que encuentro un \begin{itemize}
, lo preejecuto \PREitemize
, que aquí configuré en \par Hi Mom, I am about to itemize
. Si se \begin
detecta algo pero no lo es itemize
, lo preejecuto \PREbegin
, aquí lo configuro en \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}