当使用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}