如何在 pgfkey 中执行宏扩展

如何在 pgfkey 中执行宏扩展

我正在尝试扩展此处显示的多语言支持示例:https://tex.stackexchange.com/a/42791/7561

目前的解决方案

就像现在一样,需要使用以下方法定义宏

 \newlangcommand{\uno}

然后一次声明一种语言的不同输出,例如

\addtolangcommand{\uno}{english}{one}
\addtolangcommand{\uno}{french}{une}

预期行为

但是,我想在一次调用中使用它。例如

\newmlcommand[英语=one, 法语=une]{\uno}

这应该声明\uno宏,然后\addtolangcommand在可选参数中每对语言字符串生成一次。

问题

我将该宏定义为

\newcommand{\newmlcommand}[2][]{%
  \newlangcommand#2%
  \pgfkeys{/mlcommands, command=#2, #1}%
}

并认为我将使用它pgfkeys来处理语言。我的想法是这样做:

\pgfkeys{
  /mlcommands/.is family, /mlcommands,
  command/.get=\langcmd,
  .unknown/.code = {%    
    \addtolangcommand{\langcmd}{\pgfkeyscurrentname}{#1}
  }%
}

也就是说,对于每一对,language=string我都会执行\addtolangcommand并将它们分配给\langcmd保存传递给的原始宏的时间宏\newmlcommand

但是,我无法正确执行宏的延迟扩展。我的想法是执行

\addtolangcommand{\langcmd}{language}{string} 

使用密钥对传递的language=string。要实现这一点,应该\addlangcommand暂停,并在执行之前将其扩展\langcmd到原始宏定义和\pgfkeyscurrentname语言字符串中\addtolangcommand。请注意,使用在选项中设置的\langcmd密钥对将设置为参数。command=\macro\newmlcommand

然而我做不到正确。

完整代码

以下是我的尝试:

\documentclass{article}

\usepackage[french, english, spanish]{babel}
\usepackage{pgfkeys}

\makeatletter
% https://tex.stackexchange.com/a/42791/7561
\newcommand{\newlangcommand}[1]{%
  \newcommand#1{%
    \@ifundefined{\string#1\languagename}
    {``No def of \texttt{\string#1} for \languagename''}
    {\@nameuse{\string#1\languagename}}%
  }%
}
\newcommand{\addtolangcommand}[3]{%  
  \@namedef{\string#1#2}{#3}}    

\def\langcmd{}
\pgfkeys{
  /mlcommands/.is family, /mlcommands,
  command/.get=\langcmd,
  .unknown/.code = {%    
    % tried this idea: save it in a macro and execute it later
    % but, the expansion is still a problem
    % \def\tmp{\noexpand\addtolangcommand{\langcmd}{\pgfkeyscurrentname}{#1}}%
    % \tmp%
    % and this idea: try to delay the expansion of addtolangcommand
    % \expandafter\expandafter\expandafter\expandafter\addtolangcommand\expandafter\expandafter{\langcmd}\expandafter{\pgfkeyscurrentname}{#1}%
    % and the naive aplication doesn't work either
    \addtolangcommand{\langcmd}{\pgfkeyscurrentname}{#1}
  }%
}

\newcommand{\newmlcommand}[2][]{%
  \newlangcommand#2%
  \pgfkeys{/mlcommands, command=#2, #1}%
}
\makeatother

% How to use (original)
%\newlangcommand{\uno}
%\addtolangcommand{\uno}{english}{one}
%\addtolangcommand{\uno}{french}{une}

% or the new (non working way)
\newmlcommand[english=one, french=une]{\uno}


\begin{document}

\selectlanguage{english}
\uno  

\selectlanguage{french}
\uno  

\selectlanguage{spanish}
\uno  

\end{document}

答案1

我得到了它。

有两件事:

  • 宏扩展需要2n-1规则\expandafter,并保护所有参数前的括号。
  • 里面的宏pgfkeys不适用于该.get键,所以我做了一个手册\def

此后宏\addtolangcommand将在参数后展开。

解决方案

\documentclass{article}

\usepackage[spanish, english]{babel}

\usepackage{pgfkeys}

% https://tex.stackexchange.com/a/42791/7561
\makeatletter
\newcommand{\newlcommand}[1]{%
  \newcommand#1{%
    \@ifundefined{\string#1\languagename}
    {``No def of \texttt{\string#1} for \languagename''}
    {\@nameuse{\string#1\languagename}}%
  }%
}
\newcommand{\addtolangcommand}[3]{%
  \@namedef{\string#1#2}{#3}}

%\def\langcmd{}
\pgfkeys{
  /mlcommands/.is family, /mlcommands,
  command/.code={\def\langcmd{#1}},
  .unknown/.code = {%    
    \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\addtolangcommand\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
    {\expandafter\expandafter\expandafter\langcmd\expandafter\expandafter\expandafter}%
    \expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentname\expandafter}\expandafter
    {#1}
  }%
}

\newcommand{\newmlcommand}[2][]{%
  \newlcommand#2%
  \pgfkeys{/mlcommands, command=#2, #1}%
}

\makeatother


\begin{document}

\newmlcommand[english=ONE, spanish=UNO]{\uno}
\selectlanguage{english}
\uno

\selectlanguage{spanish}
\uno

\end{document}

相关内容