在我开始构建自己的环境后,我想知道是否存在 if 条件,用于检查下一个命令是什么,然后提供在下一个命令之前运行某些命令的选项。我正在寻找的伪代码示例:
\newenvironment{test}{
ifnext{\begin{itemize}}{true: do something}{false: do other things}
}
{
}
答案1
LaTeX 有宏\@ifnextchar
。这个名字可能有点误导,你不仅可以用它来测试下一个单个字符,还可以用它来作为具有定义含义的宏,例如,你可以测试输入流中的下一个内容是否是\begin
。
这可用于构建宏\ifnextenv
。它将采用三个参数,环境的名称、如果该环境紧随其后则执行的代码以及否则执行的代码。宏将检查输入流中的下一个内容(在其三个参数之后)是否为\begin
。如果是的话,它将检查 的第一个参数是否与使用 的\begin
第一个参数匹配。\ifnextenv
\pdf@strcmp
然后它会根据测试的结果插入分支。
此用法示例用于在no之后\ifnextenv
自动插入itemize
if 。\begin{test}
\begin{enumerate}
\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}