Proof of concept for computer-generated version of Org Mode learning map from http://emacslife.com/blog-posts/2014-01-13-tips-learning-org-mode-emacs.html . This allows us to use checkboxes to mark some items as done.
- [X] Outlines
- [X] TODOs
Implemented as a checklist instead of DONE keywords in case we’re pulling in the outline from a separate file (so that people can track their completion state separate from the Git copy?)
Resources: org: Document StructureNext: Outline manipulation See also: TODOs
Resources: org: Structure editing
Next: Simple markup
Next: Links See also: Lists See also: Tables See also: Export Next: List manipulation Next: Spreadsheets Next: Images See also: Attachments See also: Footnotes Next: File options See also: Babel See also: Presentations See also: Blocks Next: Publishing Next: Blogging Next: Scheduling See also: Config See also: Clock See also: Capture Next: Date offsets Next: Agendas Next: Deadlines See also: Repeating See also: Tags See also: MobileOrg Next: Logs Next: Search Next: Custom agenda See also: Stuck projects Next: Refiling Next: Sorting See also: Archiving Next: Multiple files Next: Include Next: Report Next: Effort See also: Dynamic blocks Next: Columns Next: Properties Next: Babel(defun sacha/fill-string (string new-fill-column &optional replace-char)
"Wrap STRING to NEW-FILL-COLUMN. Change newlines to REPLACE-CHAR."
(with-temp-buffer
(insert string)
(let ((fill-column new-fill-column))
(fill-region (point-min) (point-max))
(if replace-char
(progn
(goto-char (point-min))
(while (re-search-forward "\n" nil t)
(replace-match replace-char t t))))
(buffer-string))))
(defun sacha/org-map-path ()
"Return an alist, based on the tree and \"so that I can\" link structure.
Structure: ((nodes . ((components) ...)) (edges . ((a . b) ...)))"
(let (nodes edges)
;; Go through the entries
(org-map-entries
(lambda ()
(let ((heading (org-heading-components)))
(when (= (car heading) 2)
(save-excursion
(save-restriction
;; Ignore subtrees in the body
(org-narrow-to-subtree)
(save-excursion
(org-set-property "CUSTOM_ID" (replace-regexp-in-string "[^A-Za-z0-9]" "_" (elt heading 4))))
(end-of-line)
(narrow-to-region
(point-min)
(if (re-search-forward
(concat "[\r\n]\\(" org-outline-regexp "\\)") nil t)
(match-beginning 1)
(point-max)))
(goto-char (point-min))
(when (> (car heading) 1)
(setq nodes (cons heading nodes)))
(while (re-search-forward "\\(Next\\|See also\\):" nil t)
(while (re-search-forward org-bracket-link-regexp (line-end-position) t)
(setq edges (cons (cons (elt heading 4) (match-string-no-properties 1)) edges))))))))))
(list (cons 'nodes nodes) (cons 'edges edges))))
(defun sacha/org-map-path-to-graphviz (map fill-column)
"Convert MAP to a graphviz representation. Wrap titles at FILL-COLUMN."
(let ((completed
(mapcar (lambda (x)
(if (string-match "\\[\\(.*?\\)\\] +\\(.*\\)" x) (cons (match-string 2 x) (match-string 1 x)))) completed)))
(concat
"digraph G {\n"
"node [shape=box,fontname=\"Open Sans\",pad=1]\n"
"edge [color=\"#CCCCCC\"]\n"
(mapconcat
(lambda (x)
(format "\"%s\" -> \"%s\""
(sacha/fill-string (car x) fill-column "\\n")
(sacha/fill-string (cdr x) fill-column "\\n")))
(cdr (assoc 'edges map))
"\n")
"\n"
(mapconcat (lambda (x)
(format
(if (equal (assoc-default (elt x 4) completed) "CBON")
"\"%s\" [style=filled, URL=\"#%s\", tooltip=\"%s\"]"
"\"%s\" [URL=\"#%s\", tooltip=\"%s\"]")
(sacha/fill-string (elt x 4) fill-column "\\n")
(replace-regexp-in-string "[^A-Za-z0-9]" "_" (elt x 4))
(elt x 4)))
(cdr (assoc 'nodes map)) "\n")
"}\n")))
(org-babel-execute:dot (sacha/org-map-path-to-graphviz (sacha/org-map-path) fill-column) params)