获取组织模式缓冲区或文件的所有 h1 条目的列表

0 emacs org-mode

给定文件 ( file.org) 像这样:

* h1 t1
* h1 t2
* h1 t3
Run Code Online (Sandbox Code Playgroud)

我怎样才能读取文件并获得这样的列表?

("h1 t1" "h1 t2" "h1 t3")

Nic*_*ckD 5

您可以使用映射函数遍历文件,将函数应用于每个标题。有两种不同的方法可以做到这一点。


一种方法使用映射函数和“Property API”中的org-map-entries函数。您可以通过执行和或从手册中org-entry-get找到有关这些内容的文档:请参阅“黑客”部分以及使用属性 API和使用映射 API小节。C-h f org-map-entriesC-h f org-entry-get

这是代码:

  (defun my/headline ()
     (org-entry-get nil "ITEM"))

  (org-map-entries #'my/headline t 'file)
Run Code Online (Sandbox Code Playgroud)

ITEM是一个特殊属性,其值为标题文本。


另一种方法是解析缓冲区并得到解析树,然后对解析树进行操作。解析函数为org-element-parse-buffer,遍历解析树的映射函数为org-element-map。这些函数没有在手册中记录,但它们的文档字符串可以通过通常的C-h f机制获得;这里还有开发人员文档。其思想与第一种方法类似,但细节有所不同:我们从映射函数传递的解析对象中获取标题文本,因此该标题函数接受一个参数,即标题的解析对象。映射函数本身遍历解析树,将该函数应用于每个标题:

  (defun my-parsed/headline (o)
    (plist-get (cadr o) :raw-value))

  (org-element-map (org-element-parse-buffer) 'headline #'my-parsed/headline)
Run Code Online (Sandbox Code Playgroud)

这种方法稍微复杂一些,但更通用,在解析树一次之后,您可以缓存解析树并对其进行重复操作:如果您分摊生成树的成本,那么这将比第一种方法更快在许多不同的操作之间解析树。但对于像这里这样的一次性使用,第一种方法更简单,而且可能更快一些:解析器相对较慢。