diff options
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/seam-export.el | 8 | ||||
-rw-r--r-- | lisp/seam-html.el | 42 | ||||
-rw-r--r-- | lisp/seam-test.el | 36 | ||||
-rw-r--r-- | lisp/seam.el | 25 |
4 files changed, 62 insertions, 49 deletions
diff --git a/lisp/seam-export.el b/lisp/seam-export.el index 7fa6c2d..d0f59cc 100644 --- a/lisp/seam-export.el +++ b/lisp/seam-export.el @@ -226,12 +226,12 @@ notes)." (defun seam-export--generate-backlinks (file) (seam-export--to-string - (let ((files (sort + (let ((files (cl-sort (let ((seam--subset seam-export--types)) (cl-loop for x in (seam-get-links-to-file file) collect (cons (seam-get-title-from-file x) x))) - :key #'car - :lessp #'string<))) + #'string< + :key #'car))) (when files (cl-loop for (title . file) in files do (insert (format "- [[seam:%s][%s]]\n" (file-name-base file) title))))))) @@ -264,7 +264,7 @@ notes)." "contents" (seam-export--to-string (insert-file-contents note-file) - (re-search-forward (org-headline-re 1)) + (re-search-forward "^\\* ") (org-mode) ;Needed for `org-set-property'. (org-set-property "seam-title-p" "t"))) (seam-export--replace-variable diff --git a/lisp/seam-html.el b/lisp/seam-html.el index 018e56f..e95ff9d 100644 --- a/lisp/seam-html.el +++ b/lisp/seam-html.el @@ -1,6 +1,7 @@ ;;; seam-html.el --- Seam HTML exporter -*- lexical-binding: t -*- ;; Copyright (C) 2025 Spencer Williams +;; Copyright (C) 2011-2025 Free Software Foundation, Inc. ;; Author: Spencer Williams <spnw@plexwave.org> @@ -28,15 +29,34 @@ ;; This was blithely hacked together using large chunks of code lifted ;; straight from ox-html.el, and could do with much improvement. ;; -;; Original ox-html code is licensed under GPL v3+. Copyright (c) -;; 2011-2025 Free Software Foundation, Inc. Original authors: Carsten -;; Dominik <carsten.dominik@gmail.com> and Jambunathan K <kjambunathan -;; at gmail dot com>. +;; The original authors of ox-html are: +;; Carsten Dominik <carsten.dominik@gmail.com> +;; Jambunathan K <kjambunathan at gmail dot com> ;;; Code: (require 'ox-html) +;;; Org <9.7 compatibility. + +(fset 'seam-html--element-parent-element + (if (fboundp 'org-element-parent-element) + 'org-element-parent-element + 'org-export-get-parent-element)) + +(fset 'seam-html--element-parent + (if (fboundp 'org-element-parent) + 'org-element-parent + (lambda (node) + (org-element-property :parent node)))) + +(fset 'seam-html--element-type-p + (if (fboundp 'org-element-type-p) + 'org-element-type-p + (lambda (node types) + (memq (org-element-type node) + (ensure-list types))))) + ;;; NOTE: This function does not respect `:headline-levels' or ;;; `:html-self-link-headlines'. (defun seam-html-headline (headline contents info) @@ -102,8 +122,8 @@ images, set it to: (lambda (paragraph) (org-element-property :caption paragraph))" (let ((paragraph (pcase (org-element-type element) (`paragraph element) - (`link (org-element-parent element))))) - (and (org-element-type-p paragraph 'paragraph) + (`link (seam-html--element-parent element))))) + (and (seam-html--element-type-p paragraph 'paragraph) (or (not (and (boundp 'seam-html-standalone-image-predicate) (fboundp seam-html-standalone-image-predicate))) (funcall seam-html-standalone-image-predicate paragraph)) @@ -187,9 +207,9 @@ INFO is a plist holding contextual information. See ;; do this for the first link in parent (inner image link ;; for inline images). This is needed as long as ;; attributes cannot be set on a per link basis. - (let* ((parent (org-element-parent-element link)) - (link (let ((container (org-element-parent link))) - (if (and (org-element-type-p container 'link) + (let* ((parent (seam-html--element-parent-element link)) + (link (let ((container (seam-html--element-parent link))) + (if (and (seam-html--element-type-p container 'link) (org-html-inline-image-p link info)) container link)))) @@ -268,7 +288,7 @@ INFO is a plist holding contextual information. See (_ (if (and destination (memq (plist-get info :with-latex) '(mathjax t)) - (org-element-type-p destination 'latex-environment) + (seam-html--element-type-p destination 'latex-environment) (eq 'math (org-latex--environment-type destination))) ;; Caption and labels are introduced within LaTeX ;; environment. Use "ref" or "eqref" macro, depending on user @@ -279,7 +299,7 @@ INFO is a plist holding contextual information. See (seam-html-standalone-image-predicate #'org-html--has-caption-p) (counter-predicate - (if (org-element-type-p destination 'latex-environment) + (if (seam-html--element-type-p destination 'latex-environment) #'org-html--math-environment-p #'org-html--has-caption-p)) (number diff --git a/lisp/seam-test.el b/lisp/seam-test.el index 5d4a562..9ab1b22 100644 --- a/lisp/seam-test.el +++ b/lisp/seam-test.el @@ -39,7 +39,7 @@ (defmacro seam-test-environment (&rest body) (declare (indent 0)) - `(let* ((seam-test-directory (make-temp-file "seam-test" t)) + `(let* ((seam-test-directory (file-name-as-directory (make-temp-file "seam-test" t))) (seam-note-directory seam-test-directory) (default-directory seam-test-directory) (seam-note-types '("private" "public")) @@ -66,15 +66,17 @@ (let ,options (let ,(cl-loop for (name . args) in varlist collect `(,name (seam-make-note ,@args))) + ;; FIXME: It's quite possible for tests to fail in such a way + ;; that this does not kill the buffers. (unwind-protect (progn ,@body) (mapcar #'kill-buffer (list ,@(mapcar #'car varlist)))))))) -(defun seam-test-remove-testdir (filename) - (string-remove-prefix (concat seam-test-directory "/") filename)) +(defun seam-test-strip-testdir (filename) + (string-remove-prefix seam-test-directory filename)) (defun seam-test-list-files () (mapcar - #'seam-test-remove-testdir + #'seam-test-strip-testdir (directory-files-recursively seam-test-directory ""))) (defun seam-test-add-contents (buffer contents) @@ -119,9 +121,9 @@ (ert-deftest seam-test-make-note-weird-filename () (should (equal - '("./Weird file name!" ("private/weird-file-name.org")) + '("./Weir'd file name!" ("private/weird-file-name.org")) (seam-test-with-notes () - ((weird "./Weird file name! ")) + ((weird "./Weir'd file name! ")) (list (buffer-name weird) (seam-test-list-files)))))) @@ -222,7 +224,7 @@ (seam-test-replace-contents bar "* qux") (list (seam-test-links-from-html "html/foo.html") - (mapcar #'seam-test-remove-testdir (seam-get-links-from-file (buffer-file-name foo))) + (mapcar #'seam-test-strip-testdir (seam-get-links-from-file (buffer-file-name foo))) (seam-test-list-files))))))) (ert-deftest seam-test-link-update-no-unnecessary-export () @@ -297,9 +299,9 @@ the class." (seam-test-add-contents foo (seam-test-link-to-buffer qux)) (seam-test-add-contents bar (seam-test-link-to-buffer qux)) (list - (mapcar #'seam-test-remove-testdir (seam-get-links-from-file (buffer-file-name foo))) - (mapcar #'seam-test-remove-testdir (seam-get-links-to-file (buffer-file-name bar))) - (mapcar #'seam-test-remove-testdir (seam-get-links-to-file (buffer-file-name qux)))))))) + (mapcar #'seam-test-strip-testdir (seam-get-links-from-file (buffer-file-name foo))) + (mapcar #'seam-test-strip-testdir (seam-get-links-to-file (buffer-file-name bar))) + (mapcar #'seam-test-strip-testdir (seam-get-links-to-file (buffer-file-name qux)))))))) (ert-deftest seam-test-delete-note () "Test that deleting a note also deletes its HTML and re-exports linking @@ -358,20 +360,6 @@ backlink." (insert-file-contents "html/bar.html") (re-search-forward "<a href=\"/foo.html\">"))))) -(ert-deftest seam-test-backlinks-comment () - "Test that a commented-out link does not add a backlink." - :expected-result :failed - (should-error - (identity - (seam-test-with-notes ((seam-export-template-string "{{backlinks}}")) - ((foo "foo" "public") - (bar "bar" "public")) - (with-current-buffer foo - (seam-test-add-contents foo (concat "# " (seam-test-link-to-buffer bar)))) - (with-temp-buffer - (insert-file-contents "html/bar.html") - (re-search-forward "<a href=\"/foo.html\">")))))) - (ert-deftest seam-test-set-type-private () "Test that setting a public note to private will delete its HTML file and update linking HTML files such that they no longer link to it." diff --git a/lisp/seam.el b/lisp/seam.el index 589e947..4cc21e7 100644 --- a/lisp/seam.el +++ b/lisp/seam.el @@ -33,6 +33,7 @@ ;;; Code: (require 'seam-export) +(require 'org) (require 'cl-lib) (require 'grep) @@ -71,7 +72,10 @@ naming. Must be a function taking two arguments: TITLE and TYPE." (mapcar #'car seam-export-alist)) (defun seam-slugify (title) - (downcase (string-join (string-split title "\\W+" t) "-"))) + (setq title (string-replace "'" "" title)) + (setq title (string-split title "\\W+" t)) + (setq title (string-join title "-")) + (downcase title)) (defun seam-lookup-slug (slug) (cl-dolist (type seam-note-types) @@ -156,8 +160,7 @@ naming. Must be a function taking two arguments: TITLE and TYPE." (save-restriction (widen) (goto-char 1) - (ignore-errors - (re-search-forward (org-headline-re 1)) + (when (re-search-forward "^\\* " nil t) (let ((start (point))) (end-of-line) (let ((title (string-trim (buffer-substring-no-properties start (point))))) @@ -175,8 +178,7 @@ naming. Must be a function taking two arguments: TITLE and TYPE." (save-restriction (widen) (goto-char 1) - (ignore-errors - (re-search-forward (org-headline-re 1)) + (when (re-search-forward "^\\* " nil t) (org-element-property :SEAM_SLUG (org-element-at-point)))))) (seam-slugify (seam-get-title-from-buffer buffer)))) @@ -196,6 +198,8 @@ naming. Must be a function taking two arguments: TITLE and TYPE." (file (file-name-concat seam-note-directory type (concat slug ".org")))) + (when (string= "" slug) + (error "Cannot create a note with an empty slug")) (seam--check-conflict slug) (let ((buffer (funcall (if select #'find-file #'find-file-noselect) file))) (with-current-buffer buffer @@ -214,7 +218,7 @@ naming. Must be a function taking two arguments: TITLE and TYPE." (and self (list self))))) (let ((files (cl-loop for (title . file) in notes collect (cons (seam-format-title title (seam-get-note-type file)) file)))) - (let ((completion (string-trim (funcall seam-completing-read-function prompt files)))) + (let ((completion (string-trim (funcall seam-completing-read-function prompt (mapcar #'car files))))) (or (assoc completion files) (cons completion nil))))))) @@ -503,10 +507,11 @@ Otherwise, it's nil." update-count))) (cl-defun seam-set-buffer-name (&optional (buffer (current-buffer))) - (with-current-buffer buffer - (rename-buffer - (seam-format-title (seam-get-title-from-buffer) - (seam-get-note-type (buffer-file-name buffer)))))) + (when-let ((title (seam-get-title-from-buffer))) + (with-current-buffer buffer + (rename-buffer + (seam-format-title title + (seam-get-note-type (buffer-file-name buffer))))))) (defun seam-setup-buffer () "Setup hooks when loading a Seam file." |