节标题中的 \sin + xelatex + unicode-math 无法生成 \tableofcontents

节标题中的 \sin + xelatex + unicode-math 无法生成 \tableofcontents

以下 MWE 示例演示了该问题:

\documentclass{article}

\makeatletter
\def\arctg{\mathop{\operator@font ArcTg}\nolimits}
\makeatother

\usepackage{ifxetex,ifluatex}
\ifxetex
    \usepackage{fontspec}
    \setmainfont{Cambria}
    \usepackage{unicode-math}
    \setmathfont{Cambria Math}
\else\ifluatex
    \usepackage{fontspec}
    \defaultfontfeatures{Renderer=Basic,Ligatures={TeX}}
    \usepackage{unicode-math}
    \setmathfont{Cambria Math}
\else
    \usepackage[T1,T2A]{fontenc}
    \usepackage[utf8]{inputenc}
\fi\fi

\begin{document}
\ifxetex
    This is Xe\LaTeX
\else\ifluatex
    This is Lua\LaTeX
\else
    This is pdf\LaTeX
\fi\fi

 \subsubsection{Function $arctg(x)$}

 Function
 \begin{equation}
 \arctg(x)
 \end{equation}

 \subsubsection{Function $\cos(x)$}

 \begin{equation}
 \cos(x)
 \end{equation}

 \tableofcontents

\end{document}

我尝试了 Miktex 和 TL。第一次运行 XeTeX 时,生成的.toc文件记录非常长:

\contentsline {subsubsection}{\numberline {0.0.2}Function $\mathop {\Umathcode 97=7\symoperators 97\scan _stop: \Umathcode 98=7\symoperators 98\scan _stop:........

(这里显示不到 1%)。第二次运行时,xetex 无法完成编译。我没有检查 LuaLatex 是否也失败了。如果unicode-math没有加载,编译就会成功。

答案1

诸如 (操作符名称) 之类的命令\cos很脆弱,因此应加上前缀\protect

问题amsmath比较温和,因为\cos扩展为\qopname\relax{o}{cos}并且`\qopname 是健壮的。

在你的环境中你应该这样做

\AtBeginDocument{%
  \@ifpackageloaded{amsopn}
    {\DeclareMathOperator{\arctg}{arctg}}%
    {\def\arctg{\mathop{\operator@font arctg}\nolimits}}%
}

以使定义统一。

您还可以使命令更加健壮:

\documentclass{article}

\usepackage{ifxetex,ifluatex}
\ifxetex
    \usepackage{fontspec}
    \usepackage{unicode-math}
\else\ifluatex
    \usepackage{fontspec}
    \usepackage{unicode-math}
\else
    \usepackage[T1,T2A]{fontenc}
    \usepackage[utf8]{inputenc}
\fi\fi

\makeatletter
\AtBeginDocument{%
  \@ifpackageloaded{amsopn}
    {\DeclareMathOperator{\arctg}{arctg}}%
    {\def\arctg{\mathop{\operator@font arctg}\nolimits}}%
}
\def\protectoperators#1{%
  \AtBeginDocument{%
    \@tfor\next:=#1\do{\expandafter\MakeRobust\next}%
  }
}
\makeatother

\protectoperators{%
  \sin\cos\log\ln\arctg % add the other operators
}


\begin{document}

\show\sin

\ifxetex
    This is Xe\LaTeX
\else\ifluatex
    This is Lua\LaTeX
\else
    This is pdf\LaTeX
\fi\fi

\subsubsection{Function $\arctg(x)$}

Function
\begin{equation}
\arctg(x)
\end{equation}

\subsubsection{Function $\cos(x)$}

\begin{equation}
\cos(x)
\end{equation}

\tableofcontents

\end{document}

以下是该文件的内容.toc

\contentsline {subsubsection}{\numberline {0.0.1}Function $\arctg (x)$}{1}
\contentsline {subsubsection}{\numberline {0.0.2}Function $\cos (x)$}{1}

答案2

(评论太长,因此作为答案发布)

我不明白为什么你不使用\DelareMathOperator(由包提供的amsmath)机制来生成宏\arctg。而且,我认为在 LuaLaTeX 下指定选项已经没有什么用了Renderer=Basic。无论如何,以下稍微精简过的 MWE 版本在 pdfLaTeX、XeLaTeX 和 LuaLaTeX 下都能完美运行。

\documentclass{article}
\usepackage{amsmath} % for "\DeclareMathOperator" macro
\DeclareMathOperator{\arctg}{ArcTg}

\usepackage{ifxetex,ifluatex}
\ifxetex
      \usepackage{unicode-math}
      \setmainfont{Cambria}
      \setmathfont{Cambria Math}
\else
   \ifluatex
      \usepackage{unicode-math}
      \setmainfont[BoldFont={Cambria Bold}]{Cambria}
      \setmathfont{Cambria Math}
   \else
      \usepackage[T2A,T1]{fontenc}
      \usepackage[utf8]{inputenc}
   \fi
\fi

\begin{document}
\noindent
\ifxetex
      This is Xe\LaTeX
\else
   \ifluatex
      This is Lua\LaTeX
   \else
      This is pdf\LaTeX
   \fi
\fi

\tableofcontents
\medskip

\section{Function $\arctg(x)$}
\begin{equation} \arctg(x) \end{equation}

\section{Function $\cos(x)$} 
\begin{equation} \cos(x)   \end{equation}

\end{document} 

相关内容