以下 mwe 抛出错误You haven't defined the language lang yet
。
\documentclass{article}
\usepackage[american]{babel}
\newcommand{\lang}{american}
\selectlanguage{\lang}
\begin{document}
Hello!
\end{document}
我可以看到\lang
内部没有被正确扩展\selectlanguage
,但是为什么会发生这种情况,我该如何解决它?
我也尝试在 之前添加一个空格\lang
,在这种情况下它确实会扩展,但是由于这个空格,Babel 现在无法识别该语言。
答案1
的定义\selectlanguage
等同于
\newcommand{\selectlanguage}[1]{%
\bbl@push@language
\aftergroup\bbl@pop@language
\bbl@set@language{#1}%
}
其中\bbl@push@language
和\bbl@pop@language
是维护宏,用于执行和撤消特定于语言的调整。现在,让我们看看重要的宏,它的定义相当于
\newcommand\bbl@set@language[1]{%
\edef\languagename{%
\ifnum\escapechar=\expandafter`\string#1%
\@empty
\else
\string#1\@empty
\fi
}%
\select@language{\languagename}
[...]
}
我省略了其余部分,这是不必要的。宏\select@language
将在执行其他任何操作之前先扩展其参数。
代码假设设置\escapechar
为其正常值(即 92)。这种复杂的方法有历史原因;在 LaTeX2e 之前的古代,LaTeX 有许多扩展来应对不同的语言;为了方便习惯于\german
在想要切换到德语时书写的用户,\selectlanguage
它被定义为同时接受
\selectlanguage{german}
和
\selectlanguage{\german}
让我们看看你的会发生什么\selectlanguage{\lang}
。LaTeX 会
\edef\languagename{%
\ifnum\escapechar=\expandafter`\string\lang%
\@empty
\else
\string#1\@empty
\fi
}%
条件\ifnum
希望看到一个数字并找到\escapechar
(一个数字参数)、一个关系符号(<
,=
或>
)并找到=
,然后是另一个数字;TeX 在寻找数字时会进行扩展,因此它会扩展\expandafter
,从而触发 的扩展\string
。经过这次扩展,输入流中剩下的是
\ifnum\escapechar=`\lang
其中\lang
有五个标记,因为宏名称\lang
已被“字符串化”。条件为真,因为`\
(当\
类别代码为 12 时)是 92 的另一种说法。因此遵循“真分支”,这使得lang\@empty
保留在输入流中,因此我们得到等同于
\def\languagename{lang\@empty}
稍后将会\@empty
删除。这解释了您的错误消息。
如果你说\selectlanguage{american}
,那么条件将为假,TeX 将遵循“假分支”,最后
\def\languagename{american\@empty}
这正是想要的。
该怎么办?如果您想使用这样的语法,请定义自己的版本\selectlanguage
:
\newcommand{\xselectlanguage}[1]{%
\begingroup\edef\x{\endgroup
\noexpand\selectlanguage{#1}}\x
}
所以你甚至可以自由地进行更复杂的设置,例如
\newcommand{\lang}{\UKorUS english}
\newif\ifUK % conditional start out false
\newcommand{\UKorUS}{\ifUK UK\else US\fi}
%\UKtrue
[...]
\xselectlanguage{\lang}
USenglish
直到你取消注释该行,你才会得到结果\UKtrue
。
答案2
使用\expandafter
技巧:
\documentclass{article}
\usepackage[american]{babel}
\newcommand{\lang}{american}
\expandafter\selectlanguage\expandafter{\lang}
\begin{document}
Hello!
\end{document}
笔记:在babel
包中,\selectlanguage{\foo}
相当于。这是“出于历史原因”而设计的功能。请参阅文档中\selectlanguage{foo}
命令的备注。\bbl@set@language
babel
答案3
尝试这个:
\documentclass{article}
\usepackage[greek, american]{babel}
\def\lang#1{\selectlanguage{#1}}
\begin{document}
\lang{american}
Hello!
\lang{greek}
Hello!
\end{document}