babel + textcomp + 重新定义 \LaTeX

babel + textcomp + 重新定义 \LaTeX

我在 TeXLive 2018 中看到了这个问题,其中包括 3.26 版babel.sty(2018/10/16 3.26")。我认为这适用于一些早期版本babel.sty,但我不确定截止点在哪里。

\documentclass[english]{article}
\usepackage{babel}
\usepackage{textcomp}
\renewcommand*{\LaTeX}{hello}
\begin{document}

Testing: \LaTeX

\end{document}

当我在此上运行 PDFLaTeX 时,我会不是看到“测试:hello”,但看到的却是“测试:LaTeX”。为什么我不能重新定义宏\LaTeX

babel请注意,只有当我同时使用两个包和省略其中一个时,才会出现问题textcomp,一切仍可正常工作。

答案1

发生这种情况是因为textcomp加载了非 ASCII 编码 ( ts1enc.def),并babel明确检查了该编码,如果是,它会更改\LaTeX宏的定义。文件的相关部分:

加载时babel它定义非 ASCII 编码列表:

\newcommand\BabelNonASCII %                   vvv Here's the one loaded by textcomp
  {LGR,X2,OT2,OT3,OT6,LHE,LWN,LMA,LMC,LMS,LMU,TS1,T3,TS3}

\TeX然后它保存了和的原始定义\LaTeX

\let\org@TeX\TeX
\let\org@LaTeX\LaTeX
\let\ensureascii\@firstofone

现在,当\begin{document}执行时,babel检查是否加载了上面定义的任何编码:

\AtBeginDocument{%
  \in@false
  \bbl@foreach\BabelNonASCII{% is there a non-ascii enc?
    \ifin@\else
      \lowercase{\bbl@xin@{,#1enc.def,}{,\@filelist,}}%
    \fi}%

如果有的话,那么它将重新定义\LaTeX\ensureascii{\org@LaTeX}(以及另外几件事):

  \ifin@ % if a non-ascii has been loaded
    \def\ensureascii#1{{\fontencoding{OT1}\selectfont#1}}%
    \DeclareTextCommandDefault{\TeX}{\org@TeX}%
    \DeclareTextCommandDefault{\LaTeX}{\org@LaTeX}%
    \def\bbl@tempb#1\@@{\uppercase{\bbl@tempc#1}ENC.DEF\@empty\@@}%
    \def\bbl@tempc#1ENC.DEF#2\@@{%
      \ifx\@empty#2\else
        \bbl@ifunset{T@#1}%
          {}%
          {\bbl@xin@{,#1,}{,\BabelNonASCII,}%
           \ifin@
             \DeclareTextCommand{\TeX}{#1}{\ensureascii{\org@TeX}}%
             \DeclareTextCommand{\LaTeX}{#1}{\ensureascii{\org@LaTeX}}%
           \else
             \def\ensureascii##1{{\fontencoding{#1}\selectfont##1}}%
           \fi}%
      \fi}%
    \bbl@foreach\@filelist{\bbl@tempb#1\@@}%  TODO - \@@ de mas??
    \bbl@xin@{,\cf@encoding,}{,\BabelNonASCII,}%
    \ifin@\else
      \edef\ensureascii#1{{%
        \noexpand\fontencoding{\cf@encoding}\noexpand\selectfont#1}}%
    \fi
  \fi}

问题是在加载\org@LaTeX时定义的,并且是 _re_defined ,因此您的被覆盖了。babel\LaTeX\AtBeginDocument\renewcommand

为了解决这个问题,您需要重新定义加载\LaTeX之前babel、加载之后\begin{document}或加载\AtBeginDocument之后:babel

\documentclass{article}
% \renewcommand*{\LaTeX}{hello} % Option 1
\usepackage{babel}
\usepackage{textcomp}
% \AtBeginDocument{\renewcommand*{\LaTeX}{hello}} % Option 2
\begin{document}
% \renewcommand*{\LaTeX}{hello} % Option 3

Testing: \LaTeX

\end{document}
  1. 选项 1 有效,因为当babel加载时,\LaTeXhello,所以\org@LaTeX变成hello并且使用您的定义。

  2. 选项 2 有效,因为该\AtBeginDocument命令将参数添加到标记列表的末尾,因此您的重新定义在 之后执行babel。它本质上与在 之后执行相同\BeginDocument

  3. 选项 3 可以轻松地工作,因为在重新定义和使用命令之间没有发生任何事情。

此更改发生在babel版本中3.23,当时编码TS1, T3, TS3被添加到非 ASCII 列表中:

% Line 8996 of an up-to-date (26-10-2018) `babel.dtx`:
% \changes{babel~3.23}{2018/08/28}{Added TS1, T3, TS3}

相关内容