Latex3(expl3)子功能/子参数

Latex3(expl3)子功能/子参数

我有一个可以动态创建函数的函数,但我不知道如何使创建的函数具有参数。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       CHARACTER MAKER
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ExplSyntaxOn

% Define Special
\tl_new:N  \l_character_firstname_tl
\tl_new:N  \l_character_lastname_tl
\tl_new:N  \l_character_title_tl

\int_new:N \l_character_age_int


\keys_define:nn { Character/Identity } {
      firstname .tl_set:N = \l_character_firstname_tl
    , lastname .tl_set:N = \l_character_lastname_tl
    , title    .tl_set:N = \l_character_title_tl
    , age      .int_set:N = \l_character_age_int
    , unknown  .code:n = {}
}

% #1 * si féminin
% #2 - si élision voyelle / h
% #3 [options] - lastname, title, age
% #4 < simpleVarName > (par défaut, prénom)
% #5 { prénom }
% il va créer seule les autres versions
\NewDocumentCommand{\createCharacter}{s t- o D<>{#5} m}{
    
    % we don't want that the unset keys are carried over from the previous ones
    \group_begin:
    \IfValueT{#3}{\keys_set:nn{Character/Identity}{#3}}
    
    \cs_new_protected:cpx { #4 Age } { \exp_not:V \l_character_age_int }
    \cs_new_protected:cpx { #4 AgeAlpha } { \numberstringnum{ \exp_not:V \l_character_age_int } }
    \cs_new_protected:cpx { #4 AgeOrd } { \ordinalnum{ \exp_not:V \l_character_age_int } }
    
    \cs_new_protected:cpx { #4 AgeDiff }:nn ##1 {\fp_eval:n { \exp_not:V \l_character_age_int - ##1 }}
    \cs_new_protected:cpx { #4 AgeDiffAlpha }:nn ##1 { \numberstringnum{ \fp_eval:n { \exp_not:V \l_character_age_int - ##1 } } }
    \cs_new_protected:cpx { #4 AgeDiffOrd }:nn ##1 { \ordinalnum{ \fp_eval:n { \exp_not:V \l_character_age_int - ##1 } } }
        
    \cs_new_protected:cpn { #4 Name }  { #5 }
    \cs_new_protected:cpx { #4 FName }  { \use:c { #4 Name } ~ \exp_not:V \l_character_lastname_tl }
    \cs_new_protected:cpx { #4 LName }  { \exp_not:V \l_character_lastname_tl }
    \cs_new_protected:cpx { #4 Title }  { \exp_not:V \l_character_title_tl }
    \cs_new_protected:cpn { #4 Formal } { \use:c { #4 Title } \nobreakspace \use:c { #4 LName } }
    \cs_new_protected:cpx { #4 HW }  { \exp_not:V \l_character_handwritting_tl }
    
\group_end:

\ExplSyntaxOff

就其本身而言,、、AgeAgeAlpha运行AgeOrd良好,但其AgeDiff家人却不行。

假设我正在用这个创建一个新角色:

\createCharacter[lastname=Smith, age=39]<hero>{John}
\createCharacter*[lastname=Wilson, age=37]<wife>{Jane}

在我的文章中我进一步使用了以下写法:

\heroName, a man of \heroAgeAlpha\ years old, is married to a nice woman, \wifeName, who is \heroAgeDiffAlpha{\wifeAge}\ younger than him. He engaged with her when he was \heroAgeDiff{3}.

我将收到\heroAgeDiffAlpha和 的错误\heroAgeDiff

我怎样才能让它工作?

答案1

您正在定义用户级命令,因此它们不应有签名。另一方面,签名:nn无论如何都是错误的,因为它们只接受一个参数。

我会使用\int_eval:n,而不是\fp_eval:n,因为用户应该只在那种情况下使用整数。还有另一个缺陷;我将使用AgeDiff您想要的示例

\cs_new_protected:cpx { #4 AgeDiff } ##1
  {
   \exp_not:N \int_eval:n { \int_use:N \l_character_age_int - ##1 }
  }

因为你不能在定义时评估差异。有了这个定义,如果我这样做,\show\heroAgeDiff我会得到预期的结果

> \heroAgeDiff=\protected\long macro:
#1->\int_eval:n {39-#1}.

完整的修复如下:

\documentclass{article}
\usepackage{fmtcount}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       CHARACTER MAKER
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ExplSyntaxOn

% Define Special
\tl_new:N  \l_character_firstname_tl
\tl_new:N  \l_character_lastname_tl
\tl_new:N  \l_character_title_tl

\int_new:N \l_character_age_int


\keys_define:nn { Character/Identity } {
      firstname .tl_set:N = \l_character_firstname_tl
    , lastname .tl_set:N = \l_character_lastname_tl
    , title    .tl_set:N = \l_character_title_tl
    , age      .int_set:N = \l_character_age_int
    , unknown  .code:n = {}
}

% #1 * si féminin
% #2 - si élision voyelle / h
% #3 [options] - lastname, title, age
% #4 < simpleVarName > (par défaut, prénom)
% #5 { prénom }
% il va créer seule les autres versions
\NewDocumentCommand{\createCharacter}{s t- o D<>{#5} m}{
    
    % we don't want that the unset keys are carried over from the previous ones
    \group_begin:
    \IfValueT{#3}{\keys_set:nn{Character/Identity}{#3}}
    
    \cs_new_protected:cpx { #4 Age } { \int_eval:n { \l_character_age_int } }
    \cs_new_protected:cpx { #4 AgeAlpha }
      {
       \numberstringnum { \int_eval:n { \l_character_age_int } }
      }
    \cs_new_protected:cpx { #4 AgeOrd }
      {
       \ordinalnum { \int_eval:n { \l_character_age_int } }
      }

    \cs_new_protected:cpx { #4 AgeDiff } ##1
      {
       \exp_not:N \int_eval:n { \int_use:N \l_character_age_int - ##1 }
      }
    \cs_new_protected:cpx { #4 AgeDiffAlpha } ##1
      {
       \numberstringnum { \exp_not:N \int_eval:n { \int_use:N \l_character_age_int - ##1 } }
      }
    \cs_new_protected:cpx { #4 AgeDiffOrd } ##1
      {
       \ordinalnum { \exp_not:N \int_eval:n { \int_use:N \l_character_age_int - ##1 } }
      }

    \cs_new_protected:cpn { #4 Name }  { #5 }
    \cs_new_protected:cpx { #4 FName }  { \exp_not:c { #4 Name } ~ \exp_not:V \l_character_lastname_tl }
    \cs_new_protected:cpx { #4 LName }  { \exp_not:V \l_character_lastname_tl }
    \cs_new_protected:cpx { #4 Title }  { \exp_not:V \l_character_title_tl }
    \cs_new_protected:cpx { #4 Formal } { \exp_not:c { #4 Title } \exp_not:N \nobreakspace \exp_not:c { #4 LName } }
%    \cs_new_protected:cpx { #4 HW }  { \exp_not:V \l_character_handwritting_tl }
    
    \group_end:
}

\ExplSyntaxOff

\createCharacter[lastname=Smith, age=39]<hero>{John}
\createCharacter*[lastname=Wilson, age=37]<wife>{Jane}

\begin{document}

\heroName, a man of \heroAgeAlpha\ years old, is married to a nice woman, 
\wifeName, who is \heroAgeDiffAlpha{\wifeAge}\ younger than him. 
He engaged with her when he was \heroAgeDiff{3}.

\end{document}

相关内容