From a529e241a2d260848c189be28575eaac1b3367ab Mon Sep 17 00:00:00 2001 From: "Antoine R. Dumont (@ardumont)" Date: Thu, 17 Dec 2015 12:36:57 +0100 Subject: [PATCH] Permit user to define toc manipulation function for specific purposes, #16 for example. Default to 'identity by default --- README.md | 61 ++++++++++++++++++++++--- markdown-toc.el | 42 ++++++++++++++--- test/markdown-toc-test.el | 95 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 182 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8563d69..309ecdd 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,63 @@ Here is one possible output: - [Inspiration](#inspiration) ``` +## User toc manipulation + +If the user would want to enhance the generated toc, (s)he could use +the following function markdown-toc-user-toc-structure-manipulation-fn: + +It expects as argument the toc-structure markdown-toc uses to generate +the toc. The remaining code expects a similar structure. + +Example: + +``` lisp +'((0 . \"some markdown page title\") + (0 . \"main title\") + (1 . \"Sources\") + (2 . \"Marmalade (recommended)\") + (2 . \"Melpa-stable\") + (2 . \"Melpa (~snapshot)\") + (1 . \"Install\") + (2 . \"Load org-trello\") + (2 . \"Alternative\") + (3 . \"Git\") + (3 . \"Tar\") + (0 . \"another title\") + (1 . \"with\") + (1 . \"some\") + (1 . \"heading\")) +``` + +So for example, as asked in #16, one could drop the first element: + +``` lisp +(custom-set-variables '(markdown-toc-user-toc-structure-manipulation-fn 'cdr)) +``` + +Or drop all h1 titles... or whatever: + +``` lisp +(require 'dash) +(custom-set-variables '(markdown-toc-user-toc-structure-manipulation-fn + (lambda (toc-structure) + (-filter (lambda (l) (let ((index (car l))) + (<= 1 index))) + toc-structure))) +``` + ## Update -To update the existing TOC, simply execute again: C-u M-x markdown-toc-generate-toc +To update the existing TOC, simply execute again: +C-u M-x markdown-toc-generate-toc This will update the current TOC. ## Create elsewhere -To create another updated TOC elsewhere, execute again M-x markdown-toc-generate-toc, this will remove the old TOC and insert the updated one from where you stand. +To create another updated TOC elsewhere, execute again M-x +markdown-toc-generate-toc, this will remove the old TOC and +insert the updated one from where you stand. # Install @@ -77,7 +125,8 @@ You need to add melpa or melpa-stable package repository before installing it. ``` lisp (require 'package) -(add-to-list 'package-archives '("melpa-stable" . "http://melpa-stable.milkbox.net/packages/")) +(add-to-list 'package-archives '("melpa-stable" . + "http://melpa-stable.milkbox.net/packages/")) (package-initialize) ``` @@ -87,7 +136,8 @@ Then hit M-x eval-buffer to evaluate the buffer's contents. ``` lisp (require 'package) -(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/")) +(add-to-list 'package-archives '("melpa" . + "http://melpa.milkbox.net/packages/")) (package-initialize) ``` @@ -97,7 +147,8 @@ Then hit M-x eval-buffer to evaluate the buffer's contents. ``` lisp (require 'package) -(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/")) +(add-to-list 'package-archives '("marmalade" . + "http://marmalade-repo.org/packages/")) (package-initialize) ``` diff --git a/markdown-toc.el b/markdown-toc.el index fbda6bd..8edcb02 100644 --- a/markdown-toc.el +++ b/markdown-toc.el @@ -136,10 +136,9 @@ Return the end position if it exists, nil otherwise." (goto-char (point-min)) (re-search-forward markdown-toc--header-toc-end nil t))) -(defun markdown-toc--generate-toc (toc-index) - "Given a TOC-INDEX, compute a new toc." - (-> toc-index - markdown-toc--compute-toc-structure +(defun markdown-toc--generate-toc (toc-structure) + "Given a TOC-STRUCTURE, compute a new toc." + (-> toc-structure markdown-toc--to-markdown-toc markdown-toc--compute-full-toc)) @@ -151,7 +150,34 @@ Return the end position if it exists, nil otherwise." toc markdown-toc--header-toc-end)) +(defcustom markdown-toc-user-toc-structure-manipulation-fn (lambda (toc-structure) toc-structure) + "User crafted function to manipulate toc-structure as user sees fit. + +The toc-structure has the following form: +'((0 . \"some markdown page title\") + (0 . \"main title\") + (1 . \"Sources\") + (2 . \"Marmalade (recommended)\") + (2 . \"Melpa-stable\") + (2 . \"Melpa (~snapshot)\") + (1 . \"Install\") + (2 . \"Load org-trello\") + (2 . \"Alternative\") + (3 . \"Git\") + (3 . \"Tar\") + (0 . \"another title\") + (1 . \"with\") + (1 . \"some\") + (1 . \"heading\")) + +If the user wanted to remove the first element, it could for +example define the following function: +(custom-set-variables '(markdown-toc-user-toc-structure-manipulation-fn 'cdr)) + +Default to identity function (do nothing).") + ;;;###autoload + (defun markdown-toc-generate-toc (&optional replace-toc-p) "Generate a TOC for markdown file at current point. Deletes any previous TOC. @@ -165,9 +191,11 @@ If called interactively with prefix arg REPLACE-TOC-P, replaces previous TOC." (delete-region region-start (1+ region-end)) (when replace-toc-p (goto-char region-start)))) - (-> (markdown-imenu-create-index) - markdown-toc--generate-toc - insert))) + (->> (markdown-imenu-create-index) + markdown-toc--compute-toc-structure + (funcall markdown-toc-user-toc-structure-manipulation-fn) + markdown-toc--generate-toc + insert))) (defalias 'markdown-toc/generate-toc 'markdown-toc-generate-toc) diff --git a/test/markdown-toc-test.el b/test/markdown-toc-test.el index b49bb0d..61e88e8 100755 --- a/test/markdown-toc-test.el +++ b/test/markdown-toc-test.el @@ -110,10 +110,11 @@ NB-LINES-FORWARD is the number of lines to get back to." (should (equal " **Table of Contents** -- [-](#-) - - [Marmalade (recommended)](#marmalade-recommended) - - [Melpa-stable](#melpa-stable) - - [Melpa (~snapshot)](#melpa-snapshot) +- [something](#something) + - [Sources](#sources) + - [Marmalade (recommended)](#marmalade-recommended) + - [Melpa-stable](#melpa-stable) + - [Melpa (~snapshot)](#melpa-snapshot) - [Install](#install) - [Load org-trello](#load-org-trello) - [Alternative](#alternative) @@ -122,6 +123,7 @@ NB-LINES-FORWARD is the number of lines to get back to." To install **org-trello** in your emacs, you need a few steps. +# something ## Sources If not already configured, you need to prepare emacs to work with marmalade or melpa. For this, you need to install a snippet of code in your emacs configuration file. @@ -136,6 +138,7 @@ For this, you need to install a snippet of code in your emacs configuration file " (markdown-toc-with-temp-buffer-and-return-buffer-content "To install **org-trello** in your emacs, you need a few steps. +# something ## Sources If not already configured, you need to prepare emacs to work with marmalade or melpa. For this, you need to install a snippet of code in your emacs configuration file. @@ -150,6 +153,53 @@ For this, you need to install a snippet of code in your emacs configuration file " (markdown-toc-generate-toc))))) +(ert-deftest markdown-toc-generate-toc--first-toc-with-user-override () + (should (equal " +**Table of Contents** + + - [Sources](#sources) + - [Marmalade (recommended)](#marmalade-recommended) + - [Melpa-stable](#melpa-stable) + - [Melpa (~snapshot)](#melpa-snapshot) + - [Install](#install) + - [Load org-trello](#load-org-trello) + - [Alternative](#alternative) + - [Git](#git) + - [Tar](#tar) + + +To install **org-trello** in your emacs, you need a few steps. +# something +## Sources +If not already configured, you need to prepare emacs to work with marmalade or melpa. +For this, you need to install a snippet of code in your emacs configuration file. +### Marmalade (recommended) +### Melpa-stable +### Melpa (~snapshot) +## Install +### Load org-trello +### Alternative +#### Git +#### Tar +" + (let ((markdown-toc-user-toc-structure-manipulation-fn 'cdr)) + (markdown-toc-with-temp-buffer-and-return-buffer-content + "To install **org-trello** in your emacs, you need a few steps. +# something +## Sources +If not already configured, you need to prepare emacs to work with marmalade or melpa. +For this, you need to install a snippet of code in your emacs configuration file. +### Marmalade (recommended) +### Melpa-stable +### Melpa (~snapshot) +## Install +### Load org-trello +### Alternative +#### Git +#### Tar +" + (markdown-toc-generate-toc)))))) + (ert-deftest markdown-toc-generate-toc--replace-old-toc () (should (equal " **Table of Contents** @@ -267,5 +317,42 @@ For this, you need to install a snippet of code in your emacs configuration file " (markdown-toc-generate-toc 'replace-old-toc))))) +;; (ert-deftest markdown-toc-generate-toc--ignore-sharp-line-in-gfm-code-blocks () +;; (should (equal " +;; **Table of Contents** + +;; - [Heading](#heading) +;; - [subheading](#subheading) +;; - [another subheading](#another-subheading) + +;; +;; # Heading + +;; ## subheading + +;; ``` +;; foo +;; # bar +;; baz +;; ``` + +;; ## another subheading +;; " + +;; (markdown-toc-with-temp-buffer-and-return-buffer-content +;; "# Heading + +;; ## subheading + +;; ``` +;; foo +;; # bar +;; baz +;; ``` + +;; ## another subheading +;; " +;; (markdown-toc-generate-toc))))) + (provide 'markdown-toc-tests) ;;; markdown-toc-tests.el ends here