Eu tive um problema semelhante, então talvez isso ajude - não estou muito familiarizado com a exportação organizacional ou com a organização interna, mas não consegui encontrar nada que analise um arquivo organizacional em uma estrutura de árvore. Mas dado um buffer como
* england
** london
** bristol
* france
vai te dar
(org-get-header-tree) => ("england" ("london" "bristol") "france")
e pode incluir outras informações da árvore também.
Portanto, dada uma lista plana de níveis, precisamos produzir uma árvore, por exemplo (1 1 2 3 1) => (1 1 (2 (3)) 1). Eu não consegui encontrar uma função que faria isso, então escrevi uma após muito desenho das células contras - tenho certeza de que há uma maneira melhor de fazer isso, mas funciona. A função unflatten
utiliza uma lista simples e algumas funções para extrair as informações desejadas da lista e dos níveis do item e produz uma estrutura em árvore.
Em org-get-header-list
você pode adicionar mais informações você deseja extrair de cada artigo com chamadas para org-element-property
, em seguida, em org-get-header-tree
que você pode incluir funções para extrair as informações da lista.
Tal como está, isso não inclui a manipulação de listas de traços, mas talvez possa ser adaptado para lidar com aquelas também sem muitos problemas ...
(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
deorg-element-map
faça o que você deseja.