无法使用 RefTeX 引用新环境

无法使用 RefTeX 引用新环境

我尝试按照 RefTeX 手册的说明向 AUCTeX 添加新环境,因此我将以下内容添加到我的 .emacs 中:

(add-hook 'LaTeX-mode-hook 'turn-on-reftex)

(setq reftex-label-alist
   '(("axiom"   ?a "ax:"  "~\\ref{%s}" nil ("axiom"   "ax.") -2)
     ("theorem" ?h "thr:" "~\\ref{%s}" t   ("theorem" "th.") -3)))

(add-hook 'LaTeX-mode-hook
   (lambda ()
     (LaTeX-add-environments
       '("axiom" LaTeX-env-label)
       '("theorem" LaTeX-env-label))))

问题是我必须手动引用这些标签。我尝试按照 RefTeX 手册中的方法操作:

例如如果你写道:“正如我们在定理中所展示的”,然后按 Cc ),RefTeX 就会知道你正在寻找定理标签并将菜单限制为仅这些标签,甚至无需询问。

但随着以下 MWE

\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\newtheorem{axiom}{Axiom}
\newtheorem{theorem}{Theorem}
\begin{document}
\begin{axiom}
  \label{ax:1}
  An axiom
\end{axiom}
\begin{theorem}
  \label{thr:1}
  A theorem
\end{theorem}

As we have shown in Theorem
\end{document}

它不起作用,因为它向我展示了公理和定理,甚至不让我选择一个(所以我必须按下sspace然后选择一个)。

可能是什么问题呢?

答案1

TL;DR:emacs 附带的 reftex 版本基于 reftex 4.31。reftex 的当前版本是 4.34。它包含以下两项更改:

2008-05-03 拉尔夫·安杰利

  • lisp/reftex-parse.el (reftex-parse-from-file):如果在节宏后匹配到“\”,则向后移动一个字符。

2008-04-13 拉尔夫·安杰利

  • lisp/reftex-parse.el (reftex-parse-from-file):使用匹配的开始而不是结束作为边界。

您还可以在这里看到相关内容:

https://github.com/DamienCassou/RefTeX/commit/5f341de11651f7ec7eaed11f8faf0b2019a3b089

https://github.com/DamienCassou/RefTeX/commit/c1468af43fc660511551dc5a5ba5585db68e5cfc

这两个提交解决了您的问题。如果您想进一步了解问题所在,请继续阅读 :)

您已将类型“h”与定理关联(通过 中的 ?h reftex-label-alist)。如果您C-c )在单词后按下定理reftex-reference将被调用,它会猜测您想要一个类型为“h”的引用。您也可以(reftex-reference "h")从任何地方显式调用。reftex-reference只是 的包装器reftex-offer-label-menu。因此,您也可以调用(reftex-offer-label-menu "h")来查看引用列表(但同样,它将为空)。该函数再次是 的包装器,reftex-insert-docstruct在具有特殊导航处理的临时只读缓冲区中调用。

在 中reftex-insert-docstruct,标签信息从 中检索(symbol-value reftex-docstruct-symbol),并通过 进行填充reftex-access-scan-info。相应的变量包含大量数据。以下是重点:

如果您在迷你缓冲区中执行以下代码片段(使用M-:):

(let (ls)
  (reftex-access-scan-info)
  (dolist (i (symbol-value reftex-docstruct-symbol) ls)
    (when (stringp (car i))
      (push (concat "Label: " (nth 0 i) ", Type: " (nth 1 i)) ls))))

你应该得到以下输出:

("Label: thr:1, Type: s" "Label: ax:1, Type: s")

这说明标签 thr:1 和 ax:1 的类型分别为“s”,而不是“h”和“a”。您也可以通过在工作流程中替换sspace来仔细检查。ss

在上文中,reftex-access-scan-info填充了reftex-docstruct-symbol。它通过reftex-docstruct-symbol使用 绑定到变量reftex-tie-multifile-symbols并调用 来实现这一点reftex-do-parse,而调用reftex-parse-from-file

reftex-parse-from-file在扫描过程中,通过使用正则表达式 ; 反复搜索来解析 TeX 缓冲区reftex-everything-regexp,看起来将如下所示:

"\\\\label{\\([^}]*\\)}\\|\\(^\\)[  ]*\\\\\\(begin{theorem}\\|begin{axiom}\\|part\\|chapter\\|section\\|subsection\\|subsubsection\\|frametitle\\|paragraph\\|subparagraph\\|addchap\\|addsec\\)\\*?\\(\\[[^]]*\\]\\)?[[{   \n]\\|\\(^\\)[  ]*\\\\\\(include\\|input\\)[{   ]+\\([^}    \n]+\\)\\|\\(^\\)[  ]*\\(\\\\appendix\\)\\|\\(\\\\glossary\\|\\\\index\\)[[{]"

一旦找到匹配项,它就会检查哪一对括号包含捕获的内容。对于定理和公理环境及其标签,我们得到两个匹配项——这使得这些环境不同于例如方程,因为那里我们只得到标签的匹配。

对于环境来说,第一个匹配来自reftex-section-labels-all;这就是导致问题的原因(正如@T.Verron 所指出的那样)。与此匹配的所有内容都将被视为一个部分(因此获得“s”类型的标签)。

这就是为什么更换

(setq reftex-label-alist
   '(("axiom"   ?a "ax:"  "~\\ref{%s}" nil ("axiom"   "ax.") -2)
     ("theorem" ?h "thr:" "~\\ref{%s}" t   ("theorem" "th.") -3)))

(setq reftex-label-alist
   '(("axiom"   ?a "ax:"  "~\\ref{%s}" nil ("axiom"   "ax."))
     ("theorem" ?h "thr:" "~\\ref{%s}" t   ("theorem" "th."))))

作为一种解决方法:它删除第一个匹配项。

答案2

作为快速修复,您可以将 toc 变量设置为nil

来自 RefTeX 手册:

负值将产生无编号条目。仅对构造文档的定理类环境有用。将被宏忽略。

我看不出类似定理的环境应该如何构造文档,但我知道目录中具有负深度的标签不是为了交叉引用而制作的。

对我来说,正值在某些情况下有效,但在其他情况下无效。

(setq reftex-label-alist
   '(("axiom"   ?a "ax:"  "~\\ref{%s}" nil ("axiom"   "ax."))
     ("theorem" ?h "thr:" "~\\ref{%s}" t   ("theorem" "th."))))

相关内容