L3 编程:\text_titlecase 似乎仅在明确声明序列时才能正确映射

L3 编程:\text_titlecase 似乎仅在明确声明序列时才能正确映射

我正在尝试使用 l3 接口执行以下转换:

my_figure_title -> My Figure Title

经过对序列和字符串的一些反复试验后,我得出了以下结论:

\documentclass{article}

\begin{document}
    \ExplSyntaxOn
        \str_new:N \myStr
        \seq_new:N \mySequence
        \cs_new:Npn \myFunc #1 {\text_titlecase:nn {en} {#1}}

        \str_set:Nn \myStr {my_figure_title}
        \str_replace_all:Nnn \myStr {_} {,}
        \seq_set_from_clist:NN \mySequence \myStr
        
        \seq_map_function:NN \mySequence \myFunc
        \par
        \myStr % should show my,figure,title
        \par
        \seq_item:Nn \mySequence {3} % should show Title
    \ExplSyntaxOff
\end{document}

不幸的是,结果显示所有字母都大写。

在此处输入图片描述

这让我很困惑,因为当我尝试seq_map_function:NN明确声明逗号分隔列表的序列时,它似乎工作正常:

\documentclass{article}

\begin{document}
    \ExplSyntaxOn
    \cs_new:Npn \myFunc #1 {\text_titlecase:nn {en} {#1}}
    
    \seq_new:N \mySequence
    \seq_set_from_clist:Nn \mySequence {my,figure,title}
    \seq_item:Nn \mySequence {3}
    \myFunc {bla}
    \seq_map_function:NN \mySequence \myFunc
    \ExplSyntaxOff


\end{document}

在此处输入图片描述

不确定我做错了什么。有人能帮忙吗?

答案1

l3str 模块(以 开头的函数\str_)用于编程字符串,而 l3text 模块(以 开头的函数\text_)则处理文档中出现的格式化文本。

由于您的代码首先将字符串传递给 l3str 函数,因此它会变成编程字符串,然后不再受 l3text 支持。

由于您最终想要打印字符串,因此您实际上想要使用格式化的而不是程序化的字符串,因此您可以通过将其存储在变量tl而不是str变量中(并使用 l3tl 而不是 l3str 函数)来解决您的问题:(我还修复了名称以遵循 expl3 约定)

\documentclass{article}

\begin{document}
    \ExplSyntaxOn
        \tl_new:N \l_my_tl
        \seq_new:N \l_my_seq
        \cs_new:Npn \my_transform_to_titlecase:n #1 {\text_titlecase:nn {en} {#1}}

        \tl_set:Nn \l_my_tl {my_figure_title}
        \tl_replace_all:Nnn \l_my_tl {_} {,}
        \seq_set_from_clist:NN \l_my_seq \l_my_tl
        
        \seq_map_function:NN \l_my_seq \my_transform_to_titlecase:n
        \par
        \tl_use:N \l_my_tl % should show my,figure,title
        \par
        \seq_item:Nn \l_my_seq {3} % should show title
    \ExplSyntaxOff
\end{document}

注意:如果my_figure_title来自\ExplSyntaxOn/\ExplSyntaxOff块之外,那么您还必须处理不同的 catcode _

答案2

转换为字符串是错误的想法,因为您想保留标记作为字母的性质。

此外,您使用了错误的变量和函数命名。此外,执行不可扩展操作的函数(例如\seq_set_split:Nnn)应受到保护。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\converttotitle}{m}
  {
    \mymodule_title_convert:n { #1 }
  }

\seq_new:N \l__mymodule_title_in_seq
\seq_new:N \l__mymodule_title_out_seq

\cs_generate_variant:Nn \seq_set_split:Nnn { Nxn }

\cs_new_protected:Nn \mymodule_title_convert:n
  {
    \seq_set_split:Nxn \l__mymodule_title_in_seq { \char_generate:nn { `\_ } { 8 } } { #1 }
    \seq_set_map_x:NNn \l__mymodule_title_out_seq \l__mymodule_title_in_seq
      {
        \text_titlecase:nn {en} {##1}
      }
    \seq_use:Nn \l__mymodule_title_out_seq { ~ }
  }

\ExplSyntaxOff

\begin{document}

\converttotitle{my_figure_title}

\end{document}

一个稍微复杂的地方是在下划线处进行拆分,下划线在环境中是一个字母expl3,但在普通文本中具有不同的类别代码。您可以使用正则表达式使用不同的、与类别代码无关的方法。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\converttotitle}{m}
  {
    \mymodule_title_convert:n { #1 }
  }

\tl_new:N \l__mymodule_title_tl
\seq_new:N \l__mymodule_title_in_seq
\seq_new:N \l__mymodule_title_out_seq

\quark_new:N \q_mymodule_us

\cs_new_protected:Nn \mymodule_title_convert:n
  {
    \tl_set:Nn \l__mymodule_title_tl { #1 }
    \regex_replace_all:nnN { \_ } { \c{q_mymodule_us} } \l__mymodule_title_tl
    \seq_set_split:NnV \l__mymodule_title_in_seq { \q_mymodule_us } \l__mymodule_title_tl
    \seq_set_map_x:NNn \l__mymodule_title_out_seq \l__mymodule_title_in_seq
      {
        \text_titlecase:nn {en} {##1}
      }
    \seq_use:Nn \l__mymodule_title_out_seq { ~ }
  }

\ExplSyntaxOff

\begin{document}

\converttotitle{my_figure_title}

\end{document}

下划线被夸克取代,然后被用作分裂点。

无论哪种情况你都会得到

在此处输入图片描述

相关内容