The function needs to get at least the levels two (## title) and three (### title) titles.

1 Answer 1


Like this:

(defun px/markdown-toc ()
  "Extract level 2 and 3 headings from the current Markdown buffer.
   The generated and indented TOC will be inserted at point."
  (let (toc-list markdown-toc)
      (goto-char (point-min))
      (while (re-search-forward "^\\(##+\\)\\s-+\\(.*\\)" nil t)
        (let* ((level (length (match-string 1)))
               (heading-text (match-string 2))
               (heading-id (downcase (replace-regexp-in-string "[[:space:]]+" "-" heading-text))))
          (push (cons level (cons heading-text heading-id)) toc-list))))
    (setq toc-list (reverse toc-list))
    (dolist (item toc-list)
      (let* ((level (car item))
             (heading-text (cadr item))
             (heading-id (cddr item))
             (indentation (make-string (* 2 (1- level)) ?\ ))
             (line (format "- [%s](#%s)\n" heading-text heading-id)))
        (setq markdown-toc (concat markdown-toc (concat indentation line)))))
    (insert markdown-toc)))
  • If this works and you're happy with it, please don't forget to mark it as accepted.
    – Trevoke
    Aug 15 at 12:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.