依赖于语言的自定义命令

依赖于语言的自定义命令

我想定义一个命令,该命令根据文档中当前选择的语言略有不同。我的代码:

\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}

在此处输入图片描述

相关内容