CTeX-org / ctex-kit

Macro Packages and Scripts for Chinese TeX users
976 stars 124 forks source link

ctex, hyperref, cleveref 宏包冲突 #524

Closed kexplorning closed 4 years ago

kexplorning commented 4 years ago

检查

编译环境

描述问题

最小工作示例(MWE)

\documentclass{ctexart}
\usepackage{hyperref}
\usepackage{cleveref}

\begin{document}

\section{}
\label{sec}
\cref{sec}

\end{document}

(用 XeLaTeX 编译后)输出

9: Extra \endcsname.
<recently read> \endcsname 

l.9 \cref{sec}

有警告

Package ctex Warning: Oops! Command `\refstepcounter@noarg' is NOT patchable.
(ctex)                

Package ctex Warning: Oops! Command `\refstepcounter@optarg' is NOT patchable.
(ctex)

尝试

  1. 去掉 hyperref 宏包编译一切正常。
  2. 如果忽略问题继续编译会得到 section 1thesection,貌似中间再次插入了 \thesection 相关命令
  3. 可能与最近 ctex 宏包更新了 cleveref 兼容性代码有关
  4. (猜测)ctex 最近的补丁不兼容加了 hyperref 的 cleveref
stone-zeng commented 4 years ago

cleveref 在载入 hyperref 之后会做一些别的处理,也需要 patch 一下。

zwz commented 4 years ago

@stone-zeng 我发现现在即使没有使用hyperref

\documentclass{ctexart}
\usepackage{cleveref}

\begin{document}

\section{}
\label{sec}
\cref{sec}

\end{document}

还是会报同样的错误

但是警告不一样: LaTeX Warning: Referencesec' on page 1 undefined on input line 8.`

stone-zeng commented 4 years ago

修改代码之后重新编译,可能需要删除辅助文件。下面的警告是说没有生成引用,只要再编译一遍就可以了。

推荐使用 latexmk

Liam0205 commented 4 years ago

@stone-zeng LaTeXmk 真香。

zwz commented 4 years ago

@stone-zeng 我使用的就是latexmk哦

这个警告应该是第一次编译的时候产生的 但是后面就会报同样的错误

! Extra \endcsname.
<recently read> \endcsname 

l.8 \cref{sec}
stone-zeng commented 4 years ago
\documentclass{ctexart}
\usepackage{hyperref,cleveref}

\begin{document}

\section{}
\label{sec}
\cref{sec}

\end{document}

上面的代码编译一次,会得到这样的 .aux 文件:

\relax 
\providecommand\hyper@newdestlabel[2]{}
\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
\global\let\oldcontentsline\contentsline
\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
\global\let\oldnewlabel\newlabel
\gdef\newlabel#1#2{\newlabelxx{#1}#2}
\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
\AtEndDocument{\ifx\hyper@anchor\@undefined
\let\contentsline\oldcontentsline
\let\newlabel\oldnewlabel
\fi}
\fi}
\global\let\hyper@last\relax 
\gdef\HyperFirstAtBeginDocument#1{#1}
\providecommand*\HyPL@Entry[1]{}
\HyPL@Entry{0<</S/D>>}
\@writefile{toc}{\contentsline {section}{\numberline {1}}{1}{section.1}\protected@file@percent }
\newlabel{sec}{{1}{1}{}{section.1}{}}
\newlabel{sec@cref}{{[section][1][]1thesection\endcsname }{[1][1][]1}}

注意到最后一行有一个多余的 \endcsname,所以第二次编译读取 .aux 文件之后,就会报错。即使在第二次编译中把 hyperref 删掉,只要.aux 文件没有动,那么仍然是会报错的。

在有辅助文件读写的情形下进行 debug,请注意及时清理辅助文件

zwz commented 4 years ago

首先感谢你的说明 但是我确实都是清理掉辅助文件后,只有tex文件下使用latexmk进行编译的

看起来你这边似乎不会出错 我这边使用的是archlinux,texlive是从pacman直接安装的,都是上面最新的版本

sunmy2019 commented 4 years ago

latexmk 在没有 aux 的情况下会多次调用 xelatex 编译。 你以为编译了一次,实际上是好几次

zwz commented 4 years ago

@sunmy2019 我知道是好几次

stone-zeng commented 4 years ago

那就把 .tex文件和每一次的编译日志打个包传上来吧

zwz commented 4 years ago

每一次的编译日志? 我只有的最终的log文件 test-doc.zip

stone-zeng commented 4 years ago

你用的还是 2.5.2 的 ctex 宏包,请更新到 2.5.3。

zwz commented 4 years ago

因为Archlinux下的包都交给pacman来管理了 所以我就直接换到另一台机器,然后ctex宏包也更新到2.5.3了 但是还是会报这个错哦 test.zip

OsbertWang commented 4 years ago

我在 Win 和 WSL 里都试了,确实报错。

muzimuzhi commented 4 years ago

因为Archlinux下的包都交给pacman来管理了 所以我就直接换到另一台机器,然后ctex宏包也更新到2.5.3了 但是还是会报这个错哦 test.zip

@zwz

PS:也许要向 https://github.com/latex3/latex2e 学习,用 issue label 区分「已提交到仓库但尚未发布」和「已经发布」两个状态。 PS 2:我的理解,从 https://github.com/CTeX-org/ctex-kit/issues/524#issuecomment-647210902 开始,@stone-zeng 是在默认「仅使用 cleveref 时也报错」的条件下和你交流的,所以出现了一方认为不报错、一方认为报错的情况。

zwz commented 4 years ago

@muzimuzhi 是的,不使用 hyperref 确实没有问题 期待2.5.4

zoushucai commented 4 years ago

macTex 同样出现了这样的错误

muzimuzhi commented 4 years ago

@zwz @zoushucai ctex v2.5.4 已由 @qinglee 发布,过一两天就能通过发行版的包管理器更新上。