我有一个可以动态创建函数的函数,但我不知道如何使创建的函数具有参数。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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
就其本身而言,、、Age
和AgeAlpha
运行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}