我想定义一个命令,该命令根据文档中当前选择的语言略有不同。我的代码:
\documentclass{article}
\usepackage[english,french,german]{babel}
\newcommand{\mynewcommand}[4]{%
\newcommand{#1}{%
\iflanguage{english}{#2}{%
\iflanguage{french}{#3}{%
\iflanguage{german}{#4}{}%
}}%
}%
}
\mynewcommand{\uno}{one}{une}{eins}
\newcommand{\whatever}{whatever} % if this is commented out the code works as desired
\begin{document}
\selectlanguage{english}
\uno
\selectlanguage{french}
\uno
\end{document}
为什么我会收到错误信息\newcommand{\whatever}{whatever}
以及如何避免?
笔记:
在早期版本中,我仅使用两种语言简化了我的 MWE,在这种情况下不会引发任何错误
答案1
这个定义似乎“几乎”正确,因为除了虚假空间之外,它几乎给出了预期的结果:
\newcommand{\mynewcommand}[3]{%
\newcommand{#1}{%
\iflanguage{english}{#2}{%
\iflanguage{french}{#3}{}
}%
}%
}
然而,如果想要增强支持的语言,这很容易出错;用xparse
它更容易:
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\mynewcommand}{m m m}
{
\cs_new:Npn #1
{
\str_case:onF { \languagename }
{
{english}{#2}
{french}{#3}
}
{``No~def~of~\texttt{\token_to_str:N #1}~for~\languagename''}
}
}
\ExplSyntaxOff
\mynewcommand
如果需要其他语言,只需按照相同方案添加参数和合适的行即可。
另一种方法可能是定义不同的命令:
\makeatletter
\newcommand{\newlanguagecommand}[1]{%
\newcommand#1{%
\@ifundefined{\string#1\languagename}
{``No def of \texttt{\string#1} for \languagename''}
{\@nameuse{\string#1\languagename}}%
}%
}
\newcommand{\addtolanguagecommand}[3]{%
\@namedef{\string#1#2}{#3}}
\makeatother
\newlanguagecommand{\uno}
\addtolanguagecommand{\uno}{english}{one}
\addtolanguagecommand{\uno}{french}{une}
未知语言将导致“没有\command
定义语言“
使用\newlanguagecommand{\uno}
一个定义命令,以便它的扩展为\\uno<languagename>
;例如,当语言是法语时,书写\uno
将使用\\unofrench
定义的\addtolanguagecommand{\uno}{french}{une}
扩展为“une”。
只要替换文本不包含脆弱命令(文本没问题),移动参数也不会出现任何问题。
改进后的expl3
实现。翻译存储在属性列表中,并根据当前语言使用。
定义的命令可以接收一个可选参数,该参数应该是一个有效的语言名称,以强制使用独立于当前语言的相应翻译。
\documentclass{article}
\usepackage[french,ngerman,english]{babel}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newlanguagecommand}{mm}
{% #1 = command to define
% #2 = key-value list
\prop_new:c { \__roepo_nlc_strip:N #1 }
\prop_gset_from_keyval:cn { \__roepo_nlc_strip:N #1 } { #2 }
\NewDocumentCommand{#1}{o}
{
\IfNoValueTF { ##1 }
{
\roepo_nlc:NV #1 \languagename
}
{
\roepo_nlc:Nn #1 { ##1 }
}
}
}
\cs_new:Nn \roepo_nlc:Nn
{
\prop_if_in:cnTF { \__roepo_nlc_strip:N #1 } { #2 }
{
\prop_item:cn { \__roepo_nlc_strip:N #1 } { #2 }
}
{
UNSET~TRANSLATION
}
}
\cs_generate_variant:Nn \roepo_nlc:Nn { NV }
% syntactic sugar
\cs_new:Nn \__roepo_nlc_strip:N { g_roepo_nlc_ \cs_to_str:N #1 _prop }
\ExplSyntaxOff
\newlanguagecommand{\uno}{
english=one,
ngerman=eins,
french=un
}
\newlanguagecommand{\duck}{
english=duck,
ngerman=Ente,
}
\begin{document}
English: \uno{} and \duck{} (\duck[ngerman])
\selectlanguage{ngerman}
Deutsch: \uno{} und \duck{} (\duck[english])
\selectlanguage{french}
Français: \uno{} et \duck{} (\duck[english])
\end{document}