diff options
Diffstat (limited to 'emacs/.emacs.d/lisp/my')
-rw-r--r-- | emacs/.emacs.d/lisp/my/belf.el | 99 |
1 files changed, 88 insertions, 11 deletions
diff --git a/emacs/.emacs.d/lisp/my/belf.el b/emacs/.emacs.d/lisp/my/belf.el index da18613..e0d89b0 100644 --- a/emacs/.emacs.d/lisp/my/belf.el +++ b/emacs/.emacs.d/lisp/my/belf.el @@ -40,21 +40,22 @@ "n" #'belf-next-line "o" #'belf-open-book-other-window "p" #'belf-previous-line + "e" #'belf-set-field ;; "s" #'tabulated-list-col-sort ) (define-derived-mode belf-mode tabulated-list-mode "Bookshelf" "Major mode for browsing a list of books." (setq tabulated-list-format - [("Authors" 25 t) - ("Title" 48 t) + [("Authors" 25 belf-compare-authors) + ("Title" 48 belf-compare-title) ("Year" 4 t)]) (setq tabulated-list-padding 2) (tabulated-list-init-header) (setq revert-buffer-function #'belf-list-refresh-contents) (hl-line-mode)) -(defun belf-list-books () +(defun belf () (interactive) (let ((buf (get-buffer-create "*Bookshelf*"))) (with-current-buffer buf @@ -78,18 +79,67 @@ (list f (vector .authors .title .year))))) (directory-files belf-dir t "\\.\\(epub\\|pdf\\|cbr\\|djvu\\)$")))) +(defun belf-fix-file-name (file-name) + "Rename a file. + +Change authors-sort to authors. Change title-sort to title. + +Test: +foo bar +foo, bar +foo bar, quux baf +foo, bar & quux, baf +foo bar & quux, baf" + (when-let ((parsed (belf-parse-file-name file-name))) + (let* ((authors (string-split (alist-get 'authors parsed) " & " t " +")) + (title (alist-get 'title parsed))) + (setf + (alist-get 'authors parsed) + (mapconcat + (lambda (author) + (let ((comma-split (string-split author ", "))) + (if (or ;; no comma or more than one comma + (/= (length comma-split) 2) + ;; at least one space before the comma + (string-match-p " " (car comma-split))) + author + ;; from author-sort to author + (format "%s %s" (cadr comma-split) (car comma-split)) + ))) + authors + ", ") + (alist-get 'title parsed) + (cond ((string-suffix-p ", The" title) + (concat "The " (string-remove-suffix ", The" title))) + ((string-suffix-p ", A" title) + (concat "A " (string-remove-suffix ", A" title))) + (t title)))) + (format "%s.%s" (belf-format-base-name parsed) (alist-get 'ext parsed)))) + +(defun belf-fix-rename-file (file-name) + (when-let ((new-name (belf-fix-file-name file-name))) + (unless (equal new-name file-name) + (rename-file file-name new-name)))) + +(defun belf-fix-rename-files () + (interactive) + (dolist (file-name + (directory-files belf-dir t directory-files-no-dot-files-regexp)) + (belf-fix-rename-file file-name))) + (defun belf-parse-file-name (file-name) - (let ((base (file-name-base file-name))) - (when (string-match "^\\(.*?\\) - \\(.*\\) (\\([0-9]*\\)) \\[\\(.*\\)\\]$" base) - `((authors . ,(match-string 1 base)) - (title . ,(match-string 2 base)) - (year . ,(match-string 3 base)) - (identifier . ,(match-string 4 base)))))) + (let ((fn (file-name-nondirectory file-name))) + (when (string-match "^\\(.*?\\) +- +\\(.*\\) +(\\([0-9]*\\)) +\\[\\(.*\\)\\]\\.\\([a-zA-Z0-9]+\\)$" fn) + `((authors . ,(match-string 1 fn)) + (title . ,(match-string 2 fn)) + (year . ,(match-string 3 fn)) + (identifier . ,(match-string 4 fn)) + (ext . ,(match-string 5 fn)))))) (defun belf-format-base-name (info) (let-alist info (file-name-concat - belf-dir + (expand-file-name belf-dir) (format "%s - %s (%s) [%s]" .authors .title .year .identifier)))) (defun belf-book-infobox (file-name) @@ -207,10 +257,16 @@ For EPUB, looks for a cover image in the file." (when (setq cover-file-name (belf-pdf-page-one-cover file-name)) (format "file://%s" cover-file-name)))))) +(defun belf-set-field () + (interactive) + (cond ((equal "Authors" + (get-text-property (point) 'tabulated-list-column-name)) + (call-interactively 'belf-set-authors)))) + (defun belf-set-authors (new-authors) (interactive (list - (read-string "Set author to: " + (read-string "Set authors to: " (alist-get 'authors (belf-parse-file-name (tabulated-list-get-id)))))) (let* ((file-name (tabulated-list-get-id)) @@ -228,6 +284,27 @@ For EPUB, looks for a cover image in the file." (rename-file file new-file)) (revert-buffer))) +(defun belf-parse-first-author-name (authors) + "Returns (last-name . first-name) of the first author of AUTHORS." + (when (string-match-p))) + +(defun belf-compare-authors (x y) + "Authors comparator. + +Authors are in the format of +fname1 lname1, fname2 lname2, ..." + (string< + (car (last (string-split (car (string-split (elt (cadr x) 0) ", ")) " "))) + (car (last (string-split (car (string-split (elt (cadr y) 0) ", ")) " "))))) + +(defun belf-compare-title (x y) + "Title comparator. + +Compare without leading \"The \"." + (string< + (string-remove-prefix "The " (elt (cadr x) 1)) + (string-remove-prefix "The " (elt (cadr y) 1)))) + (defun belf-book-infobox-at-point () (interactive) (let ((help-window-select (not belf-follow-mode))) |