l3keys 相当于 pgfkeys 的 .code 2 个参数

l3keys 相当于 pgfkeys 的 .code 2 个参数

使用 l3keys模拟 pgfkeys /.code 2 args(或更一般而言/.code n args)处理程序的推荐方法是什么?例如,使用 pgfkeys 可以执行

\documentclass{article}

\usepackage{pgfkeys}

\newcommand{\cmdA}{init A}
\newcommand{\cmdB}{init B}

\pgfkeys{
    somekey/.code 2 args={%
        \renewcommand{\cmdA}{#1}%
        \renewcommand{\cmdB}{#2}%
        }
    }

\begin{document}

\cmdA\ \cmdB

\pgfkeys{somekey={new A}{new B}}

\cmdA\ \cmdB

\end{document}

图片1

使用l3keys 的处理程序时,只允许使用.code:n单个参数。#1

\ExplSyntaxOn
\keys_define:nn { mymodule } {
    somekey .code:n = {
        \tl_set:Nn \cmdA { #1 }
        %\tl_set:Nn \cmdB { #2 } % want to be able to do this
        }
    }
\ExplSyntaxOff

我已经想出了如何通过扩展参数并将其传递给辅助宏来做到这一点:

\documentclass{article}

\newcommand{\cmdA}{init A}
\newcommand{\cmdB}{init B}

\newcommand{\auxmacro}[2]{%
    \renewcommand{\cmdA}{#1}%
    \renewcommand{\cmdB}{#2}%
    }
    
\ExplSyntaxOn
\keys_define:nn { mymodule } {
    somekey .code:n = { \exp_after:wN \auxmacro #1 }
    }
\ExplSyntaxOff

\begin{document}

\cmdA\ \cmdB

\SetKeys[mymodule]{somekey={new A}{new B}}

\cmdA\ \cmdB

\end{document}

但是有没有办法在键定义中直接使用更多参数#2,等等?#3

答案1

正如评论中所述,我们有意不提供“分割值”功能l3keys。相反,额外的处理预计将委托给一个以值作为输入的专用函数

\keys_define:nn { foo }
  {
    my-key .code:n = \__foo_process_my_key:n {#1}
  }
\cs_new_protected:Npn \__foo_process_my_key:n #1
  {
    % Whatever is appropriate here
  }

答案2

为了说明这一点,约瑟夫·赖特 (Joseph Wright) 描述的两步过程允许步骤 #1 具有开放式的特征:例如,它可以是一个数据结构:

同样的foo,三种不同的输出:

ABCDE

(有点类似于 DNA\RNA。)

平均能量损失

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn

\keys_define:nn { foo }
  {
    my-key .code:n = \__foo_process_my_key:n {#1}
  }

\cs_new_protected:Npn \my_func:n #1 { 

    \tl_set:Nx
        \l_tmpb_tl
        {
            \seq_item:Nn
                    \_tmpa_seq
                    { #1 }
        }


    \seq_set_split:NnV
            \_tmpb_seq
            { ; }
        \l_tmpb_tl

%   \seq_show:N
%           \_tmpb_seq

    \tl_set:Nn
        \l_tmpb_tl
        {
        \textcolor { \seq_item:Nn \_tmpb_seq    { 3 }} { \seq_item:Nn \_tmpb_seq    { 1 } }
        }

    \tl_use:N
        \l_tmpb_tl
 }


\cs_new_protected:Npn \__foo_process_my_key:n #1
  {
    % Whatever is appropriate here

    \tl_set:Nn \l_tmpa_tl { #1 }

    \seq_set_split:NnV
            \_tmpa_seq
            { / }
            \l_tmpa_tl 

    \int_step_function:nnnN { 1 } { 1 } { \seq_count:N \_tmpa_seq } \my_func:n

  }

\NewDocumentCommand { \foo } { o } {
    \keys_set:nn { foo } { #1 }
}

\ExplSyntaxOff


\begin{document}

\foo[my-key=
ABCDE $\mapsto$~;;black
/A;z;red
/B;y;green
/C;x;blue
/D;w;yellow
/E;v;cyan
]

\foo[my-key=
The cat;;black
/~sat;;red
/~on the mat;;black
].


\foo[my-key=
The quick~;;black
/{\large brown};;red
/\kern-0.4pt\llap{{\large brown}};;blue
/~jumps over the lazy dog;;black
].


\end{document}

编辑

关于代码模糊性的评论,可以在代码本身中内置一个帮助选项,将代码与前端分开。有点像挂毯的背面和正面。

这是对有关多色字母的 SE 答案的解释尝试。

朦胧

顺便说一句,expl3 使某些事情(例如 lettrining 某些东西)变得几乎微不足道(但并非不复杂 - 要解决的问题决定了任何解决方案的复杂性级别;在这里它是易读性和足够令人愉快的阅读体验)。

平均能量损失

\documentclass{article}
\usepackage{fontspec}
\usepackage{xcolor}
\setmainfont{NotoSerif}
\newfontfamily\fcmd{NotoSans}[Colour=blue]
\newcommand\cmd[1]{{\fcmd#1}}

\newcommand\trimahelptext{%
letter in the string of characters can be overprinted up to \cmd{number-of-colours=} times (max of 4) using colours \cmd{trimacolour[a-d]=} clipped from the left in increasing order with \cmd{trimawidth[a-d]=} and formatted with switches such as \cmd{\textbackslash bfseries} (bold) and \cmd{\textbackslash itshape} (italic) using \cmd{format=}. For example, the above heading's trima scheme was done with:\\\\
{\ttfamily
\textbackslash trima[\\
trimawidtha=1pt,\\
trimawidthb=2.5pt,\\
trimawidthc=5pt,\\
trimawidthd=8pt,\\
trimacoloura=red,\\
trimacolourb=blue,\\
trimacolourc=red!60!yellow,\\
trimacolourd=green,\\
]\{\} \\
}
}

    
\ExplSyntaxOn


\tl_new:N \l_trima_coloura_tl
\tl_new:N \l_trima_colourb_tl
\tl_new:N \l_trima_colourc_tl
\tl_new:N \l_trima_colourd_tl

\dim_new:N \l_trima_widtha_dim
\dim_new:N \l_trima_widthb_dim
\dim_new:N \l_trima_widthc_dim
\dim_new:N \l_trima_widthd_dim

\int_new:N \l_trima_numcolours_int

\tl_new:N \l_trima_format_tl




\keys_define:nn { trima }
  {
    trimacoloura .tl_set:N = \l_trima_coloura_tl,
    trimacolourb .tl_set:N = \l_trima_colourb_tl,
    trimacolourc .tl_set:N = \l_trima_colourc_tl,
    trimacolourd .tl_set:N = \l_trima_colourd_tl,

    trimacoloura .default:n = { \tl_set:Nn \l_trima_coloura_tl {red} },
    trimacolourb .default:n = { \tl_set:Nn \l_trima_colourb_tl {blue} },
    trimacolourc .default:n = { \tl_set:Nn \l_trima_colourc_tl {red!40!yellow} },
    trimacolourd .default:n = { \tl_set:Nn \l_trima_colourd_tl {black} },

    trimacoloura .initial:n = { \tl_set:Nn \l_trima_coloura_tl {red} },
    trimacolourb .initial:n = { \tl_set:Nn \l_trima_colourb_tl {blue} },
    trimacolourc .initial:n = { \tl_set:Nn \l_trima_colourc_tl {red!40!yellow} },
    trimacolourd .initial:n = { \tl_set:Nn \l_trima_colourd_tl {black} },

    number-of-colours .int_set:N = \l_trima_numcolours_int,
    number-of-colours .initial:n = 4,
    number-of-colours .default:n = 4,

    format .tl_set:N = \l_trima_format_tl,

    trimawidtha .dim_set:N = \l_trima_widtha_dim,
    trimawidthb .dim_set:N = \l_trima_widthb_dim,
    trimawidthc .dim_set:N = \l_trima_widthc_dim,
    trimawidthd .dim_set:N = \l_trima_widthd_dim,

    trimawidtha .default:n = 2em,
    trimawidthb .default:n = 1.5pt,
    trimawidthc .default:n = 3.0pt,
    trimawidthd .default:n = 4.0pt,

    trimawidtha .initial:n = 2em,
    trimawidthb .initial:n = 1.5pt,
    trimawidthc .initial:n = 3.0pt,
    trimawidthd .initial:n = 4.0pt,
    
    help .code:n = { \trimahelp },
    
  }





\box_new:N \l_trima_cola_box
\box_new:N \l_trima_colb_box
\box_new:N \l_trima_colc_box
\box_new:N \l_trima_cold_box

\tl_new:N \l_trima_result_tl
\tl_new:N \l_trima_text_tl


    
%--------------------------
\cs_new_protected:Npn \trima_dotrim:n #1 {

\tl_set:Nn \l_trima_text_tl { 
    \group_begin: 
        \tl_use:N \l_trima_format_tl 
        #1 
    \group_end:
}
%\tl_show:N \l_trima_coloura_tl

\hbox_set:Nn 
    \l_trima_cola_box 
    { \textcolor{\tl_use:N \l_trima_coloura_tl}{ \tl_use:N \l_trima_text_tl } }

\hbox_set:Nn 
    \l_trima_colb_box 
    { \textcolor{\tl_use:N \l_trima_colourb_tl}{ \tl_use:N \l_trima_text_tl } }
\box_set_trim:Nnnnn 
    \l_trima_colb_box 
    {\dim_use:N \l_trima_widthb_dim} {0pt} {0pt} {0pt}
\box_clip:N 
    \l_trima_colb_box

\hbox_set:Nn 
    \l_trima_colc_box { 
    \textcolor{\tl_use:N \l_trima_colourc_tl}{ \tl_use:N \l_trima_text_tl } }
\box_set_trim:Nnnnn 
    \l_trima_colc_box 
    {\dim_use:N \l_trima_widthc_dim} 
    {0pt} {0pt} {0pt}
\box_clip:N 
    \l_trima_colc_box

\hbox_set:Nn 
    \l_trima_cold_box 
    { \textcolor{\tl_use:N \l_trima_colourd_tl}{ \tl_use:N \l_trima_text_tl } }
\box_set_trim:Nnnnn 
    \l_trima_cold_box 
    {\dim_use:N \l_trima_widthd_dim} 
    {0pt} {0pt} {0pt}
\box_clip:N 
    \l_trima_cold_box


    \tl_clear:N \l_trima_result_tl
    \int_case:nnTF
        { \l_trima_numcolours_int }
        {
                { 1 } { 
                            \tl_set:Nn 
                                \l_trima_result_tl
                                {
                                    \box_use:N \l_trima_cola_box 
                                    }
                            }
                { 2 } { 
                            \tl_set:Nn 
                                \l_trima_result_tl
                                {
                            \box_use:N \l_trima_cola_box
                            \llap{\box_use:N \l_trima_colb_box} 
                                    }
                            }
                { 3 } {
                            \tl_set:Nn 
                                \l_trima_result_tl
                                {
                            \box_use:N \l_trima_cola_box
                            \llap{\box_use:N \l_trima_colb_box} 
                            \llap{\box_use:N \l_trima_colc_box} 
                                    }
                            }
                { 4 } { 
                            \tl_set:Nn 
                                \l_trima_result_tl
                                {
                            \box_use:N \l_trima_cola_box
                            \llap{\box_use:N \l_trima_colb_box} 
                            \llap{\box_use:N \l_trima_colc_box} 
                            \llap{\box_use:N \l_trima_cold_box} 
                                    }
                            }
        }
        {}{}

%   {
    
                            \tl_use:N 
                                \l_trima_result_tl
%   }

  }


\NewDocumentCommand { \trimahelp } { } {

\trima[
trimawidtha=1pt,
trimawidthb=2.5pt,
trimawidthc=5pt,
trimawidthd=8pt,
trimacoloura=red,
trimacolourb=blue,
trimacolourc=red!60!yellow,
trimacolourd=green,
]{{\rule{\textwidth}{0.5pt}}} 

\section*{\trima{Introductory \ Tutorial\ to\ \textbackslash} trima\ \trima{Command}}

    \input Acorn.fd

    \hbox_set:Nn
        \l_tmpa_box
        {
        \fontsize{60pt}{72pt}\usefont{U}{Acorn}{xl}{n}
        E
        } 
        
    \box_use:N \l_tmpa_box
    \vspace{-1.3\box_ht:N \l_tmpa_box}
    \hangindent=\dim_eval:n {0.4em+\box_wd:N \l_tmpa_box}
    \hangafter=-\fp_to_int:n { 2 + \box_ht:N \l_tmpa_box / \baselineskip }
    \noindent
    \kern-0.3em\textsc{ach}\ \trimahelptext
    \tex_par:D
    \noindent
    :\hfill\rule{0.32\textwidth}{0.5pt}\hfill :

}


\NewDocumentCommand { \trima } { o m } {


%       \tl_show:N \l_trima_colourd_tl
%   \dim_show:N \l_trima_widthc_dim

        \tl_if_novalue:nF{#1}
        {\keys_set:nn { trima } { #1 } }
        
%       \tl_show:N \l_trima_colourd_tl
        
    \tl_set:Nn \l_tmpa_tl { #2 }

    \mode_leave_vertical: 
    \tl_map_function:NN 
        \l_tmpa_tl 
        \trima_dotrim:n 
        
}

\ExplSyntaxOff

%\newcommand\trima[1]{%
%    \textcolor{red}{#1}%
%\llap{\clipbox{2.5pt 0pt 0pt 0pt}{\textcolor{blue}{#1}}}%
%\llap{\clipbox{3.0pt 0pt 0pt 0pt}{\textcolor{red!40!yellow}{#1}}}%
%\llap{\clipbox{4.0pt 0pt 0pt 0pt}{\textcolor{black}{#1}}}%
%}

\begin{document}

\large
a 
\trima[
trimacoloura=red,
trimacolourb=blue,
trimacolourc=red!40!yellow,
trimacolourd=black,
number-of-colours=4,
trimawidtha,
trimawidthb,
trimawidthc,
trimawidthd,
format=\itshape,
]{abxyz}
\trima{abxyz}

\trima[number-of-colours=2,
]{QWERTY}


\trima{uiop}
\trima[
number-of-colours=4,
trimacolourd=green,%!60!yellow!40,
]{qazdxc}
\trima[
format=\Huge,
]{Q}

\trima[format=\normalsize,
]{{\rule{1.5em}{1em}}} 
The 
\trima[
trimacoloura=black,
trimacolourb=black,
trimacolourc=black,
trimacolourd=black,
format=\itshape\bfseries,
]{cat} 
sat on the 
\trima{mat}.

\trima[
trimawidtha=1pt,
trimawidthb=2.5pt,
trimawidthc=5pt,
trimawidthd=8pt,
trimacoloura=red,
trimacolourb=blue,
trimacolourc=red!60!yellow,
trimacolourd=green,
]{{\rule{1.5em}{1em}}} 

\section{\trima{Introduction}}

\trima[help]{}


\end{document}

相关内容