aboutsummaryrefslogtreecommitdiff
path: root/emacs
diff options
context:
space:
mode:
Diffstat (limited to 'emacs')
-rw-r--r--emacs/.emacs.d/lisp/my/belf.el99
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)))