在环境中使用 \newcommand

在环境中使用 \newcommand

命令可以作为环境使用。

\newcommand{\rev}[2][blue]{{\color{#1}#2}}

例如,只是为其论点增添色彩。

为什么对应的环境没有给全部内容着色?

\begin{document}
    black  % is correct
    \rev{in blue} \rev[red]{in red}  % correct
    black  % correct

    \begin{rev}in blue\end{rev}% only first letter is blue
    \begin{rev}[red]           % only first letter is red
        in red
    \end{rev}
    black again  % black again
\end{document}

同样,\rev[\normalcolor]{text}应该可以正常工作。

答案1

通过检查 可以检查宏是用作环境还是用作普通命令\@currenvir。以下使用它来调用\color(将为环境的整个内容着色)或\textcolor(将仅为强制参数着色)。

\documentclass[]{article}

\usepackage[]{color}
\makeatletter
\newcommand\rev[1][blue]
  {%
    \begingroup
      \def\tmp{rev}%
      \expandafter
    \endgroup
    \ifx\tmp\@currenvir
      \expandafter\color
    \else
      \expandafter\textcolor
    \fi
    {#1}%
  }
\makeatother

\begin{document}
    black  % is correct
    \rev{in blue} \rev[red]{in red}  % correct
    black  % correct

    \begin{rev}in blue\end{rev} % only first letter is blue
    \begin{rev}[red]            % only first letter is red
        in red%
    \end{rev}
    black again  % black again
\end{document}

请注意,这并非万无一失。 这样的用法\begin{rev}abc\rev[red]{def}ghi\end{rev}会导致abc蓝色和defghi红色。


检查是否rev用作环境的更好方法是使用 LaTeX 的钩子机制来设置一个布尔值,该布尔值指示当前rev是环境(并让环境版本将布尔值设置回 false)。这也适用于以下情况\begin{rev}abc\rev[red]{def}ghi\end{rev}

\documentclass[]{article}

\usepackage[]{color}
\makeatletter
\newif\ifrev@inenv
\ifdefined\AddToHook
  \AddToHook{env/rev/begin}{\rev@inenvtrue}
\else
  \usepackage{etoolbox}
  \AtBeginEnvironment{rev}{\rev@inenvtrue}
\fi
\newcommand\rev[1][blue]
  {%
    \ifrev@inenv
      \rev@inenvfalse
      \expandafter\color
    \else
      \expandafter\textcolor
    \fi
    {#1}%
  }
\makeatother

\begin{document}
    black  % is correct
    \rev{in blue} \rev[red]{in red}  % correct
    black  % correct

    \begin{rev}in blue\end{rev} % only first letter is blue
    \begin{rev}[red]            % only first letter is red
      in red\rev[green]{test}ed%
    \end{rev}
    black again  % black again
\end{document}

(我做了一个编辑,检查是否\AddToHook可用,如果不可用,则返回etoolbox

答案2

\begin{rev}[red]           % only first letter is red
        in red
    \end{rev}

或多或少

\begingroup\rev[red]
   in red
   \relax\endgroup

相当于

\begingroup\rev[red]{i}%
   n red
   \relax\endgroup

通过内置的 tex 宏参数解析规则。


如果要定义一个环境,其中环境主体充当宏参数,请使用\NewDocumentEnvironmentb参数。这需要xparse旧版 latex 格式中的包,但已内置于当前版本中。

当然对于\color不需要参数的具体例子,只需使用\color{red},颜色变化的范围将在环境结束时结束。

相关内容