![如何获取其中包含行尾字符的令牌列表?](https://linux22.com/image/271143/%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E5%85%B6%E4%B8%AD%E5%8C%85%E5%90%AB%E8%A1%8C%E5%B0%BE%E5%AD%97%E7%AC%A6%E7%9A%84%E4%BB%A4%E7%89%8C%E5%88%97%E8%A1%A8%EF%BC%9F.png)
这个问题的背景是,我有一个使用 定义的命令,xparse
它会在逐字参数中插入一个很长的参数。我想对结果标记列表进行替换,但我想替换的标记是换行符。根据\tl_show:n {#1}
这是^^M
。我很难将它放入\tl_replace_all:Nnn
进行替换。
如果我的令牌列表恰好以 开头,^^M
那么我可以从那里获取并使用它。所以我知道如果我可以将角色^^M
放入令牌列表中,它就会起作用。但是如果没有这个 hack,我不知道如何将其放入。
这是一个最低限度的工作示例:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_replace_all:Nnn {NV}
\NewDocumentCommand \getstuff {+v}
{
\tl_set:Nn \l_tmpa_tl {#1}
\tl_set:Nx \l_tmpb_tl {\tl_head:N \l_tmpa_tl}
\tl_replace_all:NVn \l_tmpa_tl \l_tmpb_tl {!wibble!}
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\getstuff+
some stuff
+
\getstuff+some stuff+
\end{document}
答案1
借助\tl_analysis_show:n
您可以获得更好的结果:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_replace_all:Nnn {NV}
\str_const:Nx \c_other_eol_str { \cs_to_str:N \^^M }
\NewDocumentCommand \getstuff {+v}
{
\tl_analysis_show:n { #1 } % for debugging
\tl_set:Nn \l_tmpa_tl {#1}
\tl_replace_all:NVn \l_tmpa_tl \c_other_eol_str {!wibble!}
\tl_analysis_show:N \l_tmpa_tl % for debugging
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\getstuff+
some stuff
+
\getstuff+some stuff+
\end{document}
对于第一次调用\getstuff
,日志中有
The token list contains the tokens:
> ^^M (the character ^^M)
> s (the character s)
> o (the character o)
> m (the character m)
> e (the character e)
> (blank space )
> s (the character s)
> t (the character t)
> u (the character u)
> f (the character f)
> f (the character f)
> ^^M (the character ^^M).
这证实了^^M
已被吸收为类别代码为 12 的标记;由于\c_other_eol_str
包含完全相同属性的标记,因此下一条诊断消息显示
The token list \l_tmpa_tl contains the tokens:
> ! (the character !)
> w (the letter w)
> i (the letter i)
> b (the letter b)
> b (the letter b)
> l (the letter l)
> e (the letter e)
> ! (the character !)
> s (the character s)
> o (the character o)
> m (the character m)
> e (the character e)
> (blank space )
> s (the character s)
> t (the character t)
> u (the character u)
> f (the character f)
> f (the character f)
> ! (the character !)
> w (the letter w)
> i (the letter i)
> b (the letter b)
> b (the letter b)
> l (the letter l)
> e (the letter e)
> ! (the character !).
好极了!^^M
已被正确识别并更改为!wibble!
。
一个不同的策略是使用l3regex
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \getstuff {+v}
{
\tl_analysis_show:n { #1 } % for debugging
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:nnN { \r } { !wibble! } \l_tmpa_tl
\tl_analysis_show:N \l_tmpa_tl % for debugging
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\getstuff+
some stuff
+
\getstuff+some stuff+
\end{document}
在这种情况下!wibble!
修改后的标记列表中将包含类别代码为 12 个字符的所有字符;但当然,您并不想真正将其改为^^M
,!wibble!
对吗?
答案2
这似乎有效
{\char_set_catcode_other:N \^^M\tl_gset:Nn\g_tmpa_tl{^^M}}