2

Currently i have around 25 org files each with multiple headings. Everytime i want to go over my notes, i need to remember the name of the file and open it (faster if its in buffer, else i need to go to the org folder)

Is there a way to generate a TOC of files/heading1 for all files under the org-directory and place it under an index.org?

P.S: Google did not return any good package!

2 Answers 2

1

There are a couple of options. I would not create a permanent index.org file, because it would take some extra effort to keep it up to to date. If you don't mind installing f.el and helm, here is a dynamic way to get a list of all the headings.

(defun org-toc () "Generate a table of contents for org-files in this directory." (interactive) (let ((org-agenda-files (f-entries "." (lambda (f) (f-ext? f "org")) t))) (helm-org-agenda-files-headings))) 

If you really want a buffer with headlines, you could try this approach to make a temporary buffer with links to the headlines:

(defun org-toc () (interactive) (let ((headings (delq nil (loop for f in (f-entries "." (lambda (f) (f-ext? f "org")) t) append (with-current-buffer (find-file-noselect f) (org-map-entries (lambda () (when (> 2 (car (org-heading-components))) (cons f (nth 4 (org-heading-components))))))))))) (switch-to-buffer (get-buffer-create "*toc*")) (erase-buffer) (org-mode) (loop for (file . heading) in headings do (insert (format "* [[%s::*%s]]\n" file heading))))) 
5
  • Thanks! I tried the second solution and spacemacs just hangs! Its clocking at 98% since sometime now.. Commented Dec 19, 2016 at 18:09
  • Please note, i have around 28 files totaling to 1.2MB Commented Dec 19, 2016 at 18:11
  • It takes about 10 seconds to list 3541 headings from 35 files that are 2.4MB in size on my mac. It is for sure not the speediest method. Commented Dec 19, 2016 at 23:17
  • sorry my bad. The script was running from my home dir and hence taking too long. Commented Dec 20, 2016 at 4:07
  • That is because the f-files function works recursively in that function! Commented Dec 20, 2016 at 13:18
0

Here is another approach I have used:

(defun org-toc () (interactive) (let ((files (f-entries "." (lambda (f) (f-ext? f "org")) t)) (headlines '()) choice) (loop for file in files do (with-temp-buffer (insert-file-contents file) (goto-char (point-min)) (while (re-search-forward org-heading-regexp nil t) (cl-pushnew (list (format "%-80s (%s)" (match-string 0) (file-name-nondirectory file)) :file file :position (match-beginning 0)) headlines)))) (setq choice (completing-read "Headline: " (reverse headlines))) (find-file (plist-get (cdr (assoc choice headlines)) :file)) (goto-char (plist-get (cdr (assoc choice headlines)) :position)))) 

if you have helm or ivy setup to do completion, it should use them to help pick the headlines. This takes about 4-5 seconds for me on about 3500 headlines.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.