如何获取其中包含行尾字符的令牌列表?

如何获取其中包含行尾字符的令牌列表?

这个问题的背景是,我有一个使用 定义的命令,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}}

相关内容