Saya memiliki masalah yang sama, jadi mungkin ini akan membantu - Saya tidak terlalu mengenal ekspor org atau internal org, tetapi saya tidak dapat menemukan apa pun yang akan mengurai file org ke struktur pohon. Tapi diberi buffer like
* england
** london
** bristol
* france
itu akan memberi Anda
(org-get-header-tree) => ("england" ("london" "bristol") "france")
dan dapat memasukkan informasi lain dari pohon juga.
Jadi dengan memberikan daftar level yang datar kita perlu menghasilkan pohon, mis. (1 1 2 3 1) => (1 1 (2 (3)) 1). Saya tidak dapat menemukan fungsi yang akan melakukan ini, jadi tulis satu demi satu gambar banyak sel kontra - saya yakin ada cara yang lebih baik untuk melakukan ini tetapi berfungsi. Fungsi ini unflatten
mengambil daftar datar dan beberapa fungsi untuk mengekstrak informasi yang Anda inginkan dari daftar dan tingkat item dan menghasilkan struktur pohon.
Di org-get-header-list
Anda dapat menambahkan lebih banyak informasi yang ingin Anda ekstrak dari setiap item dengan panggilan org-element-property
, dan kemudian di org-get-header-tree
Anda bisa memasukkan fungsi untuk mengekstrak informasi dari daftar.
Seperti berdiri ini tidak termasuk penanganan untuk daftar dasbor, tapi mungkin bisa disesuaikan untuk menangani mereka juga tanpa terlalu banyak masalah ...
(defun unflatten (xs &optional fn-value fn-level)
"Unflatten a list XS into a tree, e.g. (1 2 3 1) => (1 (2 (3)) 1).
FN-VALUE specifies how to extract the values from each element, which
are included in the output tree, FN-LEVEL tells how to extract the
level of each element. By default these are the `identity' function so
it will work on a list of numbers."
(let* ((level 1)
(tree (cons nil nil))
(start tree)
(stack nil)
(fn-value (or fn-value #'identity))
(fn-level (or fn-level #'identity)))
(dolist (x xs)
(let ((x-value (funcall fn-value x))
(x-level (funcall fn-level x)))
(cond ((> x-level level)
(setcdr tree (cons (cons x-value nil) nil))
(setq tree (cdr tree))
(push tree stack)
(setq tree (car tree))
(setq level x-level))
((= x-level level)
(setcdr tree (cons x-value nil))
(setq tree (cdr tree)))
((< x-level level)
(while (< x-level level)
(setq tree (pop stack))
(setq level (- level 1)))
(setcdr tree (cons x-value nil))
(setq tree (cdr tree))
(setq level x-level)))))
(cdr start)))
; eg (unflatten '(1 2 3 2 3 4)) => '(1 (2 (3) 2 (3 (4))))
(defun org-get-header-list (&optional buffer)
"Get the headers of an org buffer as a flat list of headers and levels.
Buffer will default to the current buffer."
(interactive)
(with-current-buffer (or buffer (current-buffer))
(let ((tree (org-element-parse-buffer 'headline)))
(org-element-map
tree
'headline
(lambda (el) (list
(org-element-property :raw-value el) ; get header title without tags etc
(org-element-property :level el) ; get depth
;; >> could add other properties here
))))))
; eg (org-get-header-list) => (("pok" 1) ("lkm" 1) (("cedar" 2) ("yr" 2)) ("kjn" 1))
(defun org-get-header-tree (&optional buffer)
"Get the headers of the given org buffer as a tree."
(interactive)
(let* ((headers (org-get-header-list buffer))
(header-tree (unflatten headers
(lambda (hl) (car hl)) ; extract information to include in tree
(lambda (hl) (cadr hl))))) ; extract item level
header-tree))
; eg (org-get-header-tree) => ("pok" "lkm" ("cedar" "yr") "kjn")
no-recursion
dariorg-element-map
harus melakukan apa yang Anda inginkan.