emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/toc-org 114dcc9813 053/128: make GitHub hrefs unique (fixe


From: ELPA Syncer
Subject: [nongnu] elpa/toc-org 114dcc9813 053/128: make GitHub hrefs unique (fixes #16)
Date: Sun, 2 Jan 2022 09:59:09 -0500 (EST)

branch: elpa/toc-org
commit 114dcc9813e2d8784b8c21165c95408c1b26d86e
Author: Sergei Nosov <sergei.nosov@gmail.com>
Commit: Sergei Nosov <sergei.nosov@gmail.com>

    make GitHub hrefs unique (fixes #16)
---
 README.org | 10 +++++++---
 toc-org.el | 35 +++++++++++++++++++++++++++--------
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/README.org b/README.org
index 9989e17b7d..4778f45e44 100644
--- a/README.org
+++ b/README.org
@@ -96,13 +96,17 @@ Now =C-c C-q T RET= and you are done putting the =:TOC:= 
entry.
 Currently, only 2 href styles are supported: =gh= and =org=. You can easily
 define your own styles. If you use the tag =:TOC_2_STYLE:= (=STYLE= being a
 style name), then the package will look for a function named
-=toc-org-hrefify-STYLE=, which accepts a heading string and returns a href
-corresponding to that heading.
+=toc-org-hrefify-STYLE=.
+
+It should accept a heading string and a hash table of previously generated
+hrefs. The table can be used to maintain href uniqueness (see
+=toc-org-hrefify-gh=, for example). Return value should be a href corresponding
+to that heading.
 
 E.g. for =org= style it simply returns input as is:
 
 #+BEGIN_SRC emacs-lisp
-  (defun toc-org-hrefify-org (str)
+  (defun toc-org-hrefify-org (str &optional hash)
     "Given a heading, transform it into a href using the org-mode
   rules."
     str)
diff --git a/toc-org.el b/toc-org.el
index f092954418..6ea2a78dd3 100644
--- a/toc-org.el
+++ b/toc-org.el
@@ -160,21 +160,38 @@ auxiliary text."
    "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an 
up-to-date table of contents in the\norg files without exporting (useful 
primarily for readme files on\nGitHub).\n\nIt is similar to the 
[[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works 
for org files.\n:TOC:\n  drawer\n:END:\n\n* Table of Contents                   
                                  :TOC:\n - [[#about][About]]\n - 
[[#use][Use]]\n - [[#different-href-styles][Different href st [...]
    "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different 
href styles\n* Example\n"))
 
-(defun toc-org-hrefify-gh (str)
+(defun toc-org-hrefify-gh (str &optional hash)
   "Given a heading, transform it into a href using the GitHub
 rules."
   (let* ((spc-fix (replace-regexp-in-string " " "-" str))
          (upcase-fix (replace-regexp-in-string "[A-Z]" 'downcase spc-fix t))
-         (special-chars-fix (replace-regexp-in-string 
toc-org-special-chars-regexp "" upcase-fix t)))
-    (concat "#" special-chars-fix)))
+         (special-chars-fix (replace-regexp-in-string 
toc-org-special-chars-regexp "" upcase-fix t))
+         (hrefified-base (concat "#" special-chars-fix))
+         (hrefified hrefified-base)
+         (idx 0))
+    ;; try appending -1, -2, -3, etc. until unique href is found
+    (when hash
+      (while (gethash hrefified hash)
+        (setq hrefified
+              (concat hrefified-base "-" (number-to-string (setq idx (1+ 
idx)))))))
+    hrefified))
 
 (ert-deftest test-toc-org-hrefify-gh ()
   "Test the `toc-org-hrefify-gh' function"
   (should (equal (toc-org-hrefify-gh "About") "#about"))
   (should (equal (toc-org-hrefify-gh "!h@#$%^&*(){}|][:;\"'/?.>,<`~") "#h"))
-  (should (equal (toc-org-hrefify-gh "!h@#$% ^&*(S){}|][:;\"'/?.>,<`~") 
"#h-s")))
+  (should (equal (toc-org-hrefify-gh "!h@#$% ^&*(S){}|][:;\"'/?.>,<`~") 
"#h-s"))
 
-(defun toc-org-hrefify-org (str)
+  (let ((hash (make-hash-table :test 'equal)))
+    (should (equal (toc-org-hrefify-gh "About" hash) "#about"))
+    (puthash "#about" "About" hash)
+    (should (equal (toc-org-hrefify-gh "About" hash) "#about-1"))
+    (puthash "#about-1" "About" hash)
+    (should (equal (toc-org-hrefify-gh "About" hash) "#about-2"))
+    (puthash "#about-2" "About" hash)
+    (should (equal (toc-org-hrefify-gh "About" hash) "#about-3"))))
+
+(defun toc-org-hrefify-org (str &optional hash)
   "Given a heading, transform it into a href using the org-mode
 rules."
   str)
@@ -227,7 +244,7 @@ each heading into a link."
                    (end (line-end-position))
                    (heading (buffer-substring-no-properties
                              beg end))
-                   (hrefified (funcall hrefify heading)))
+                   (hrefified (funcall hrefify heading hash)))
               (insert "[[")
               (insert hrefified)
               (insert "][")
@@ -244,11 +261,13 @@ each heading into a link."
 
 (ert-deftest test-toc-org-hrefify-toc ()
   (let ((hash (make-hash-table :test 'equal)))
-    (should (equal (toc-org-hrefify-toc "* About\n" 'upcase hash)
+    (should (equal (toc-org-hrefify-toc "* About\n"
+                                        (lambda (str &optional hash) (upcase 
str))
+                                        hash)
                    " - [[ABOUT][About]]\n"))
     (should (equal (gethash "ABOUT" hash) "About")))
   (let ((hash (make-hash-table :test 'equal)))
-    (should (equal (toc-org-hrefify-toc "* About\n* Installation\n** via 
package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" 'upcase 
hash)
+    (should (equal (toc-org-hrefify-toc "* About\n* Installation\n** via 
package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" (lambda 
(str &optional hash) (upcase str)) hash)
                    " - [[ABOUT][About]]\n - [[INSTALLATION][Installation]]\n   
- [[VIA PACKAGE.EL][via package.el]]\n   - [[MANUAL][Manual]]\n - 
[[USE][Use]]\n - [[DIFFERENT HREF STYLES][Different href styles]]\n - 
[[EXAMPLE][Example]]\n"))
     (should (equal (gethash "ABOUT" hash) "About"))
     (should (equal (gethash "INSTALLATION" hash) "Installation"))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]