我正在尝试扩展此处显示的多语言支持示例: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}