expl3 中的 tokenlist 和原始文本之间的区别

expl3 中的 tokenlist 和原始文本之间的区别

如何按任意字符(如原始文档文本)拆分标记列表?

例如,我有一个代码用于在宏参数中将第一个单词加粗。宏可以正确地直接从代码中使用,例如\bfirst{word word word},但如果我使用标记列表变量,我的宏就无法分离单词。

我的代码:

% XeLaTeX Document
\documentclass[a4paper]{extarticle}
\usepackage{polyglossia}
\setdefaultlanguage[spelling=modern]{russian} 
\defaultfontfeatures{Ligatures={TeX},Renderer=Basic}
\setmainfont{Arial}

\usepackage{expl3}
\ExplSyntaxOn

    % Bold first word in macro argument
    \seq_new:N \l_mytest_bstring_seq
    \tl_new:N  \l_mytest_bfirst_tl

    \NewDocumentCommand{\bfirst}{ m }
    {
        \seq_set_split:Nnn \l_mytest_bstring_seq { ~ } { #1 }
        \seq_pop_left:NN   \l_mytest_bstring_seq \l_mytest_bfirst_tl

        \textbf{\l_mytest_bfirst_tl} ~
        \seq_use:Nn \l_mytest_bstring_seq { ~ }
    }

    % TL can't be splitted?
    \tl_new:N  \l_test_example_tl
    \tl_set:Nn \l_test_example_tl {TL\ word~word\ word...}

    \NewDocumentCommand{\tlbfirst}{}
    {
        \par\bfirst{\l_test_example_tl}
        \par\bfirst{\tl_use:N \l_test_example_tl}
    }

\ExplSyntaxOff

\begin{document}
    \par\bfirst{Word word word...}
    \tlbfirst
\end{document}

结果:

命令之间的区别

如何使原始文本和标记列表得到相同的结果?

答案1

这是一个很好的例子,说明了为什么expl3不应在主体中使用复杂的代码\NewDocumentCommand;只有初始化和一般检查,但大部分任务应该推迟到内部函数。

\documentclass{article}

\usepackage{xparse}
\ExplSyntaxOn

% Bold first word in macro argument
\seq_new:N \l_mytest_bstring_seq
\tl_new:N  \l_mytest_bfirst_tl

\NewDocumentCommand{\bfirst}{ m }
 {
  \mytest_bfirst:n { #1 }
 }

\cs_new_protected:Npn \mytest_bfirst:n #1
 {
  \seq_set_split:Nnn \l_mytest_bstring_seq { ~ } { #1 }
  \seq_pop_left:NN   \l_mytest_bstring_seq \l_mytest_bfirst_tl

  \textbf{\l_mytest_bfirst_tl} ~
  \seq_use:Nn \l_mytest_bstring_seq { ~ }
}
% generate a variant of \mytest_bfirst:n
\cs_generate_variant:Nn \mytest_bfirst:n { V }

% TL can't be split?
\tl_new:N  \l_test_example_tl
\tl_set:Nn \l_test_example_tl {TL\ word~word\ word}

\NewDocumentCommand{\tlbfirst}{}
 {
  \mytest_bfirst:V \l_test_example_tl
 }

\ExplSyntaxOff

\begin{document}
\bfirst{Word word word}

\tlbfirst
\end{document}

这样,第二个用户级宏就可以根据来定义\mytest_bfirst:V

在此处输入图片描述

答案2

你想要一个x在分裂之前扩展参数的变体

在此处输入图片描述

\documentclass[a4paper]{extarticle}
\usepackage{polyglossia}
\setdefaultlanguage[spelling=modern]{russian} 
\defaultfontfeatures{Ligatures={TeX},Renderer=Basic}
\setmainfont{Arial}

\usepackage{expl3}
\ExplSyntaxOn
   \cs_generate_variant:Nn \seq_set_split:Nnn {Nnx}
    % Bold first word in macro argument
    \seq_new:N \l_mytest_bstring_seq
    \tl_new:N  \l_mytest_bfirst_tl

    \NewDocumentCommand{\bfirst}{ m }
    {
        \seq_set_split:Nnx \l_mytest_bstring_seq { ~ } { #1 }
        \seq_pop_left:NN   \l_mytest_bstring_seq \l_mytest_bfirst_tl

        \textbf{\l_mytest_bfirst_tl} ~
        \seq_use:Nn \l_mytest_bstring_seq { ~ }
    }

    % TL can't be splitted?
    \tl_new:N  \l_test_example_tl
    \tl_set:Nn \l_test_example_tl {TL\ word~word\ word...}

    \NewDocumentCommand{\tlbfirst}{}
    {
        \par\bfirst{\l_test_example_tl}
        \par\bfirst{\tl_use:N \l_test_example_tl}
    }

\ExplSyntaxOff

\begin{document}
    \par\bfirst{Word word word...}
    \tlbfirst
\end{document}

请注意,这是以空格(~)而不是控制空格(\)来分割的,所以TL\ Word是一个单词。

相关内容