从 24.1 版开始,Emacs 的 BibTeX 模式支持 biblatex 条目。这确实很好用。但是,我大量使用了 biblatex 的可扩展性,使用了自定义条目类型和相应的条目字段,这使得 BibTeX 模式在处理这些条目时不知所措。
在尝试理清这个问题时,我检查bibtex.el
并找到了两个可定制的列表,这似乎是可行的方法:bibtex-biblatex-field-alist
和bibtex-biblatex-entry-alist
。
因此我对其进行了定制:
(use-package bibtex
:custom
(bibtex-dialect (quote biblatex));; biblatex as default bib format
:config
;; Support for custom biblatex entries and fields in BibTeX mode
(setq my/primary-bibtex-biblatex-field-alist
'(("shortarchive")))
(setq bibtex-biblatex-field-alist
(append bibtex-biblatex-field-alist my/primary-bibtex-biblatex-field-alist))
(setq my/primary-bibtex-biblatex-entry-alist
'(("Archive" "Archive"
(("title"))
nil
(("location") ("shortarchive")))))
(setq bibtex-biblatex-entry-alist
(append bibtex-biblatex-entry-alist my/primary-bibtex-biblatex-entry-alist)))
支持具有以下结构的 entrytype:
@archive{ID,
title = {},
OPTlocation = {},
OPTshortarchive = {},
}
检查bibtex-biblatex-field-alist
和bibtex-biblatex-entry-alist
表明它们按预期配置,并且确实bibtex-clean-entry
按C-c C-c预期工作(在定制之前,我收到了Not inside a BibTeX entry
错误)。
但是,新的条目类型没有显示在“条目类型”菜单中。此外,与标准条目类型一样,该命令bibtex-Archive
不可用M-x。我如何才能同时实现这两点,以便能够为版本插入自定义条目类型的空模板,就像我可以使用通常的条目类型一样?
答案1
就我在网上和 Emacs 内部文档中搜索过的情况而言,我找不到最新的 BibTeX 模式手册(如果有人知道在哪里可以找到它,请告诉我)。bibtex.el
当然,里面有文档字符串,它们已经发挥了很大的作用。但是旧版手册由一位善良的灵魂在网上发布。
在那里,我们发现以下关于的评论bibtex-entry-field-alist
:
如果您想更改这个变量,最好的办法可能是从文件“bibtex.el”获取 BibTeX 模式的源代码,将此变量的定义复制到您的“.emacs”文件中,将其更改为 setq 语句(参见 Emacs Lisp 手册中的“设置变量”部分),然后修改变量的内容。
这肯定是处理这个问题的正确/规范方法。它确实有效。您还可以自定义bibtex-biblatex-field-alist
并bibtex-biblatex-entry-alist
达到相同的效果。
唯一的“问题”是,bibtex-biblatex-entry-alist
代码量大约有 250 行,bibtex-biblatex-field-alist
另外还有近 90 行。再加上我想添加的代码。在我看来,这相当多。
我最初在问题中提出的方法存在什么问题,即菜单和命令是在加载时构建的bibtex.el
,因此使用在那里定义的列表的原始值,而我的append
s 来得太晚了,菜单/命令已经构建好了。
重新定义完整列表的另一种方法是在将列表附加到列表后重建菜单/命令。不幸的是,bibtex.el
没有将此例程包装到我们可以调用的任何类型的函数中,因此我们必须提供相应的代码。
(use-package bibtex
:custom
(bibtex-dialect (quote biblatex));; biblatex as default bib format
:config
;; Support for custom biblatex entries and fields in BibTeX mode
(setq bibtex-biblatex-field-alist
(append bibtex-biblatex-field-alist
'(("shortarchive"))))
(setq bibtex-biblatex-entry-alist
(append bibtex-biblatex-entry-alist
'(("Archive" "Archive"
(("title"))
nil
(("location") ("shortarchive"))))))
;; Taken from bibtex.el, the routine that builds the menus etc.
;; This must be (re)executed after `bibtex-biblatex-entry-alist` and
;; `bibtex-biblatex-field-alist` have been redefined. Alternative is to
;; redefine the *full* lists with `setq` in the `:init` section
(let ((select-map (make-sparse-keymap)))
;; Submenu for selecting the dialect
(dolist (dialect (reverse bibtex-dialect-list))
(define-key select-map (vector dialect)
`(menu-item ,(symbol-name dialect)
(lambda () (interactive) (bibtex-set-dialect ',dialect t))
:button (:radio . (eq bibtex-dialect ',dialect)))))
;; We define a menu for each dialect.
;; Then we select the menu we want via the :visible keyword
(dolist (dialect bibtex-dialect-list)
(let ((entry-alist (bibtex-entry-alist dialect))
(menu-map (make-sparse-keymap)))
(define-key menu-map [select]
`(menu-item "BibTeX dialect" ,select-map))
(define-key menu-map [nil-2] '(menu-item "--"))
(define-key menu-map [bibtex-preamble]
'(menu-item "Preamble" bibtex-Preamble))
(define-key menu-map [bibtex-String]
'(menu-item "String" bibtex-String))
(define-key menu-map [nil-1] '(menu-item "--"))
(dolist (elt (reverse entry-alist))
;; Entry commands
(let* ((entry (car elt))
(fname (intern (format "bibtex-%s" entry))))
(unless (fboundp fname)
(eval (list 'defun fname nil
(format "Insert a template for a @%s entry; see also `bibtex-entry'."
entry)
'(interactive "*")
`(bibtex-entry ,entry))))
;; Menu entries
(define-key menu-map (vector fname)
`(menu-item ,(or (nth 1 elt) (car elt)) ,fname))))
(define-key bibtex-mode-map
(vector 'menu-bar dialect)
`(menu-item "Entry-Types" ,menu-map
:visible (eq bibtex-dialect ',dialect))))))
;; End of taken from bibtex.el
)
这句话比较简短,但我不确定它是否更明智。不过,它确实有效。
更新:记录一下。我最终选择自定义完整列表。尽管代码开销很大,但感觉更明智。