- [X] Check comment TODOs (using
magit-todos
). - [X] Check issues.
- [X] Check plans (in this file).
- [X] Check linters.
- [X] Check tests.
- [X] Update version numbers in file headers.
- [X] org-make-toc.el
- [X] Update changelog in
README.org
. - [X] Tag and sign new version (using Magit’s
t r
). - [X] Push
master
. - [X] Push tags.
- [X] Post-release changes:
- [X] Bump version numbers to n+1-pre:
- [X] org-make-toc.el
- [X] README.org
- [X] Bump version numbers to n+1-pre:
- State “DONE” from “TODO” [2017-08-01 Tue 22:41]
There are different ways to get a tree of the document structure.
org-imenu-get-tree
returns one that should be useful.org-element-parse-buffer
is more semantic and is probably better for my uses. It looks like it returns metadata, whileorg-imenu-get-tree
is bare-bones, just whatimenu
needs.
Yeah, looks like org-element-parse-buffer
is the way to go.
(org-element-parse-buffer 'headline)
The structure of this appears to be like:
- ‘headline
- List of properties
- List for child heading
- ‘headline
- List of properties
- State “DONE” from “UNDERWAY” [2017-08-02 Wed 01:08]
- State “UNDERWAY” from “DONE” [2017-08-02 Wed 00:08]
This works, but it helped me figure out how to use org-element-map
, so I guess I’ll use that.
(defun org-walk-tree (tree element-pred)
(cl-loop for element in tree
when (eql 'headline (car element))
when (funcall element-pred element)
collect (list 'headline
:name (org-element-property :title element)
:children (org-walk-tree (cddr element) element-pred))))
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/notes.org")
(let ((tree (cddr (org-element-parse-buffer 'headline))))
(org-walk-tree tree (lambda (element)
(not (string= (org-element-property :TOC element)
"ignore"))))))
(defun org-walk-tree (tree element-pred)
(cl-loop for element in tree
when (eql 'headline (car element))
when (funcall element-pred element)
collect (list 'headline
:name (org-element-property :title element)
:children (org-walk-tree (cdddr element) element-pred))))
(defun argh (element)
(unless (string= (org-element-property :TOC element)
"ignore")
(list 'headline
:name (org-element-property :title element)
:children (org-element-map (cddr element) '(headline)
#'argh nil nil '(headline)))))
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/notes.org")
(let ((tree (cddr (org-element-parse-buffer 'headline))))
(org-element-map tree '(headline) #'argh nil nil '(headline))))
- State “DONE” from “TODO” [2017-08-02 Wed 03:42]
- State “DONE” from [2017-08-02 Wed 02:06]
Ugly, but it works. I guess the rather non-standard structure of the element tree makes this necessary. I tried to get treepy
working with zippers, and I almost did…
(defun org-make-toc--first-in-tree (tree element-pred)
(cl-loop for element in tree
for type = (car element)
if (eq 'headline type)
for result = (funcall element-pred element)
if result
return result
else
for children = (cddr element)
when children
for result = (org-make-toc--first-in-tree children element-pred)
when result
return result))
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(let* ((tree (cddr (org-element-parse-buffer 'headline)))
(tree (org-make-toc--remove-ignored-entries tree))
(toc-level (org-make-toc--first-in-tree tree
#'org-make-toc--is-toc-entry
#'org-make-toc--element-level)))
toc-level))
- State “DONE” from “TODO” [2017-08-02 Wed 03:41]
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(let* ((tree (cddr (org-element-parse-buffer 'headline)))
(tree (org-make-toc--remove-ignored-entries tree)))
(org-make-toc--remove-higher-level-than-toc tree)))
- State “MAYBE” from “TODO” [2017-08-02 Wed 01:08]
- State “CANCELED” from “TODO” [2017-08-02 Wed 00:07]
I guess I’m just not smart enough to use treepy, because all I could get out of its walking functions were errors. Or maybe it’s just not suitable for the kind of structure org-element-map
returns. I don’t know.
(require 'treepy)
(treepy-walk #'identity (cddr (org-element-parse-buffer 'headline)))
- State “DONE” from “TODO” [2017-08-02 Wed 00:57]
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(let ((tree (cddr (org-element-parse-buffer 'headline))))
(org-make-toc--remove-ignored-entries tree)))
Should be a nicer way to turn the ToC into the list string.
Check out orgpath
This looks really cool, although he seems to have abandoned it. I cloned a local copy to src/misc/org. Studying his functions that build a tree should be very helpful.
- State “UNDERWAY” from “TODO” [2017-08-02 Wed 04:16]
With each element being a link to the real heading. Need to support both GitHub links and Org links.
- State “DONE” from “TODO” [2017-08-02 Wed 04:16]
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(let* ((tree (cddr (org-element-parse-buffer 'headline)))
(tree (org-make-toc--remove-ignored-entries tree))
(tree (org-make-toc--remove-higher-level-than-toc tree)))
(org-make-toc--tree-to-list tree)))
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(-when-let* ((tree (cddr (org-element-parse-buffer 'headline)))
(tree (org-make-toc--remove-ignored-entries tree))
(tree (org-make-toc--remove-higher-level-than-toc tree))
(list (org-make-toc--tree-to-list tree))
(pos (org-find-property "TOC" "this")))
(org-make-toc--replace-entry-contents pos list)))
(require 'treepy)
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(let* ((tree (cddr (org-element-parse-buffer 'headline)))
(zipper (treepy-zipper #'treepy-branch-p
#'treepy-children
#'treepy-make-node
tree)))
(treepy-children zipper)))
(with-current-buffer (find-buffer-visiting "~/src/org-make-toc/test/data.org")
(let* ((tree (cddr (org-element-parse-buffer 'headline)))
(zipper (treepy-zipper (lambda (loc) (eql 'headline (car loc)))
(lambda (loc) (cddr loc))
(lambda (loc) (list 'headline (cdr loc) (cddr loc)))
tree)))
zipper))
- [ ] Check comment TODOs (using
magit-todos
). - [ ] Check issues.
- [ ] Check plans (in this file).
- [ ] Check linters.
- [ ] Check tests.
- [ ] Update version numbers in file headers.
- [ ] org-make-toc.el
- [ ] Update changelog in
README.org
. - [ ] Tag and sign new version (using Magit’s
t r
). - [ ] Push
master
. - [ ] Push tags.
- [ ] Post-release changes:
- [ ] Bump version numbers to n+1-pre:
- [ ] org-make-toc.el
- [ ] README.org
- [ ] Bump version numbers to n+1-pre: