使 xparse 不吞噬可选参数的行尾字符

使 xparse 不吞噬可选参数的行尾字符

当使用xparse可选参数定义新环境时O{},第一个行尾字符将被吞噬,如以下示例文档所示:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Npn \__my_end_of_line: { X }

\NewDocumentEnvironment{mycode}{ !O{} }{
    \char_set_catcode_active:N \^^M
    \char_set_active_eq:nN {`\^^M} \__my_end_of_line:
}{}
\ExplSyntaxOff

\begin{document}
\begin{mycode}
abc
\end{mycode}
\end{document}

输出

ABCX

我期望

韓國

已经有了这个问题类似,但不使用活动字符。此外,该问题中的注释在这里没有帮助。在参数说明符前加上前缀 既不起作用,!在较新版本中也不起作用xparse(我的版本是xparse 2019-05-28)。

有办法解决这个问题吗?


编辑:我的用例是拥有一个特殊的逐字类环境,并在开头进行一些可选设置。问题是我需要提前读取直到找到第一行/第一个行的末尾,^^M以丢弃该行上的所有内容(通常为空)。如果存在可选参数,则此方法可以正常工作,但如果没有可选参数,则第一个实际代码行将被视为要丢弃的行,这是不必要的。

答案1

根据要求,我快速模拟了答案。您需要先更改类别代码,然后再检查是否存在可选参数,然后将其切换回参数抓取,并重置实际环境的类别代码。

以下示例对可选参数进行了非常简单的抓取,就像在 LaTeX2e 中所做的那样,但这不如O{}参数来自xparse,因为没有括号平衡。您可以通过执行 来规避这种情况\NewDocumentCommand \__mycode_parse_arg:w { !O{} } { ... },但\NewDocumentCommand不应将其用于代码级宏(因此得名)。

我设置了可选参数,以便它改变的定义\__mycode_end_of_line:,只是为了表明它正在起作用。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Npn \__mycode_end_of_line: { X }
\cs_new_protected:Npn \__mycode_real_begin:
  {
    \__mycode_catcode_setup:
    \char_set_active_eq:nN { `\^^M } \__mycode_end_of_line:
  }
\cs_new_protected:Npn \__mycode_parse_arg:w [ #1 ]
  {
    % do whatever with the optional argument
    \cs_set_protected:Npn \__mycode_end_of_line: { #1 }
    \__mycode_real_begin:
  }
\cs_new_protected:Npn \__mycode_catcode_setup:
  {
    \char_set_catcode_active:N \^^M
  }
\NewDocumentEnvironment { mycode } {}
  {
    \group_begin:
    \__mycode_catcode_setup:
    \peek_meaning:NTF [
      {
        \group_end:
        \__mycode_parse_arg:w
      }
      {
        \group_end:
        \__mycode_real_begin:
      }
  }
  {}
\ExplSyntaxOff

\begin{document}
\begin{mycode}
abc
\end{mycode}

\begin{mycode}[Y]
abc
\end{mycode}
\end{document}

在此处输入图片描述

相关内容