我尝试按照 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."))))