10

Org-mode有一个名为 的捆绑扩展org-id,它实现了 org-mode 文件的全局唯一 ID。每个条目(带有正文的标题)都可以在其:PROPERTIES:抽屉中具有 ID 属性。

可以使用函数为单个条目分配新 ID org-id-get-create

如何为 org-mode 文件中的每个条目分配一个 ID?

我可以使用 Emacs 方法自动执行此操作,例如调用org-id-get-create每个以 . 开头的字符串的宏*。但我想知道 org-mode 是否已经具备这种能力。如果没有,请推荐为此目的编写 elisp 代码的最惯用方式。

4

2 回答 2

14

我同意 Stuart 的观点——我认为 org-id 中没有任何东西可以自动执行此操作,所以它真的归结为您何时想要添加 id。

如果您使用org-capture添加所有项目,那么org-capture-prepare-finalize-hook放置代码的逻辑位置是:

(add-hook 'org-capture-prepare-finalize-hook 'org-id-get-create)

或者,您可以按照 Stuart 的建议进行操作,并为 org-mode 文件添加一个保存挂钩。我认为处理文件中所有标题的最惯用方法是使用映射 API

(defun my/org-add-ids-to-headlines-in-file ()
  "Add ID properties to all headlines in the current file which
do not already have one."
  (interactive)
  (org-map-entries 'org-id-get-create))

最后我们只需要添加一个before-save-hook只在 org-mode 下运行的:

(add-hook 'org-mode-hook
          (lambda ()
            (add-hook 'before-save-hook 'my/org-add-ids-to-headlines-in-file nil 'local)))

应该这样做!

于 2013-04-27T00:25:22.570 回答
13

我搜索了源代码,但找不到任何明显可以做到这一点的东西。我知道它被Org-mobile使用,但我没有太多经验。

首先,以下代码片段将遍历当前文件中的所有大纲标题(Org 模式标题基本上是标准 Emacs 大纲标题),如果那里还没有 ID,则添加一个 ID:

   (require 'org-id)
   (save-excursion
      (goto-char (point-max))
      (while (outline-previous-heading)
        (org-id-get-create)))

(如果你想知道为什么这个循环在缓冲区上向后而不是向前,这是因为while循环总是会至少调用一次大纲导航函数,如果你的 Org 模式文件以标题开头,如果向前移动,则会跳过.)

这可以很容易地在 Org 模式议程已知的所有文件的循环中使用,方法是遍历 function 返回的条目(org-agenda-files),或者添加到 Org 模式文件的保存挂钩中。

如果比我更灵活的人没有先到达那里,如果您可以确定何时需要添加 ID,我可能会将上述内容扩展为一个完整的解决方案。

于 2012-11-12T18:59:19.943 回答