Miałem podobny problem, więc może to pomoże - nie znam się dobrze na eksportowaniu org lub wewnętrznych org, ale nie mogłem znaleźć niczego, co analizowałoby plik org na strukturę drzewa. Ale biorąc pod uwagę bufor
* england
** london
** bristol
* france
da ci to
(org-get-header-tree) => ("england" ("london" "bristol") "france")
i może zawierać także inne informacje z drzewa.
Biorąc pod uwagę płaską listę poziomów, musimy stworzyć drzewo, np. (1 1 2 3 1) => (1 1 (2 (3)) 1). Nie mogłem znaleźć funkcji, która by to zrobiła, więc napisałem ją po wielu rysunkach komórek przeciwnych - jestem pewien, że jest lepszy sposób, ale to działa. Funkcja unflattenpobiera płaską listę i kilka funkcji w celu wyodrębnienia żądanych informacji z listy i poziomów pozycji i tworzy strukturę drzewa.
W org-get-header-listmożesz dodać więcej informacji, które chcesz wyodrębnić z każdego elementu z połączeniami do org-element-property, a następnie org-get-header-treemożesz włączyć funkcje wyodrębnienia informacji z listy.
W obecnej formie nie obejmuje to obsługi list kontrolnych, ale być może można je dostosować do obsługi również bez większych problemów ...
(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-recursionodorg-element-mappowinni robić, co chcesz.