假设我想定义一个像“颜色描述”这样的环境,它与“描述”相同,只是可以向标签添加可选的颜色背景:\begin{colordescription}[red] ...
我的问题受到以下内容的启发:描述(至少enumitem
)也有“正常”可选参数(例如[style=...]
),因此,为了确保新的“colordescription”环境以相同的方式工作,我需要将新的可选参数放在已知参数之前(或之后),例如\begin{colordescription}[red][style=...]
。
我想在视觉上区分“新”选项,这就是为什么我想到这样的语法\begin{colordescription}<red>[style=...]
:我认为环境主体以 开头的情况很少<
,因此尖括号不会与常规文本混淆。也许有一种方法可以使用后面的字符\begin{...}
,如果这个字符是 <
?,则进行特殊解析。
答案1
xparse
允许使用参数类型对命令使用(几乎)任意分隔符d/D
。您可以使用以下方式定义环境:
\NewDocumentEnvironment{colordescription}{ D<>{white} O{} }
{\begin{description}[format=\colorbox{#1},#2]}
{\end{description}}
那么参数#1
将是可选的,由 分隔<...>
,默认为white
,并且参数#2
将是可选的,由 分隔[...]
,默认为空。
\documentclass{article}
\usepackage{enumitem}
\usepackage{xcolor}
\usepackage{xparse}
\NewDocumentEnvironment{colordescription}{ D<>{white} O{} }
{\begin{description}[format=\colorbox{#1},#2]}
{\end{description}}
\begin{document}
\begin{colordescription}
\item[foo] bar
\end{colordescription}
\begin{colordescription}[style=nextline]
\item[foo] bar
\end{colordescription}
\begin{colordescription}<red>
\item[foo] bar
\end{colordescription}
\begin{colordescription}<red>[style=nextline]
\item[foo] bar
\end{colordescription}
\end{document}
答案2
编辑后将所有 3 个参数直接传递给最终宏,因此 OP 部分不需要进行扩展。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\makeatletter
\newenvironment{z}[1]{\@ifnextchar<{\zz{#1}}{\zz{#1}<Opt2 default>}}{}
\makeatother
\def\zz#1<#2>{%
\def\argi{#1}
\def\argii{#2}
\zzz
}
\newcommand\zzz[1][Opt 3 default]{
\expandafter\expandafter\expandafter\zzzz\expandafter\expandafter
\expandafter{\expandafter\argi\expandafter}\expandafter{\argii}{#1}
}
\newcommand\zzzz[3]{
First arg is \detokenize{#1}\\
Bracket option is \detokenize{#2}\\
Option argument is \detokenize{#3}
}
\begin{document}
\begin{z}{ABC} \end{z}
\begin{z}{ABC}[\def] \end{z}
\begin{z}{ABC}<hi \mom> \end{z}
\begin{z}{ABC}<hi \mom>[\def] \end{z}
\end{document}