From 1f231c7ba3153e32c689e5d68b43eb11f5ff1ba6 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Sat, 26 Apr 2014 17:02:22 -0400 Subject: Generalize PDF functions to any file type --- NEWS | 6 ++ README | 12 ++-- README.md | 12 ++-- bog-tests.el | 49 ++++++++++----- bog-todo.org | 3 +- bog.el | 195 +++++++++++++++++++++++++++++++---------------------------- 6 files changed, 158 insertions(+), 119 deletions(-) diff --git a/NEWS b/NEWS index c914ca3..af996bc 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ # -*- mode: org -*- +* Master (unreleased) + +** New features + +- Any file type (not just PDFs) can now be associated with a citekey. + * v0.6.0 ** New features diff --git a/README b/README index d60afd4..aeb1e51 100644 --- a/README +++ b/README @@ -25,7 +25,7 @@ examples, see [[http://thread.gmane.org/gmane.emacs.orgmode/78983][these]] [[htt The Bog workflow is focused around the citekey, which is the only study information that must be included in the notes. This unique identifier -is used as a link to the BibTeX and PDF files. +is used as a link to the BibTeX file and other associated files. In the example below, the citekey "name2000word" is a study heading. Bog expects the citekey to be the title or property of a heading. The @@ -63,9 +63,9 @@ is on a citekey (like "another1999study" above), then that citekey will be used. Otherwise, the citekey will be taken from the first parent heading that is a study. -- =bog-find-citekey-pdf= +- =bog-find-citekey-file= - Open a PDF file for a citekey. + Open an associated file for a citekey. - =bog-find-citekey-bib= @@ -81,9 +81,9 @@ heading that is a study. author's last name, year, and first non-trivial word) usually contains enough information to make this search successful. -- =bog-rename-staged-pdf-to-citekey= +- =bog-rename-staged-file-to-citekey= - Rename a new PDF. + Rename a new file. - =bog-clean-and-rename-staged-bibs= @@ -112,7 +112,7 @@ Other useful functions include Several variables determine where Bog looks for things. - =bog-notes-directory= -- =bog-pdf-directory= +- =bog-file-directory= - =bog-bib-directory= or =bog-bib-file= - =bog-stage-directory= diff --git a/README.md b/README.md index daa4d8c..8a1e09c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ examples, see [these](http://thread.gmane.org/gmane.emacs.orgmode/78983) [thread The Bog workflow is focused around the citekey, which is the only study information that must be included in the notes. This unique identifier -is used as a link to the BibTeX and PDF files. +is used as a link to the BibTeX file and other associated files. In the example below, the citekey "name2000word" is a study heading. Bog expects the citekey to be the title or property of a heading. The @@ -50,9 +50,9 @@ Many Bog functions take the citekey from the notes context. If the point is on a citekey (like "another1999study" above), then that citekey will be used. Otherwise, the citekey will be taken from the first parent heading that is a study. -- `bog-find-citekey-pdf` +- `bog-find-citekey-file` - Open a PDF file for a citekey. + Open an associated file for a citekey. - `bog-find-citekey-bib` @@ -69,9 +69,9 @@ heading that is a study. author's last name, year, and first non-trivial word) usually contains enough information to make this search successful. -- `bog-rename-staged-pdf-to-citekey` +- `bog-rename-staged-file-to-citekey` - Rename a new PDF. + Rename a new file. - `bog-clean-and-rename-staged-bibs` @@ -99,7 +99,7 @@ Other useful functions include Several variables determine where Bog looks for things. - `bog-notes-directory` -- `bog-pdf-directory` +- `bog-file-directory` - `bog-bib-directory` or `bog-bib-file` - `bog-stage-directory` diff --git a/bog-tests.el b/bog-tests.el index 7cb1911..42fab5c 100644 --- a/bog-tests.el +++ b/bog-tests.el @@ -148,15 +148,34 @@ (should-error (bog-citekey-from-notes)))) -;;; PDF functions +;;; File functions -(ert-deftest bog-rename-staged-pdf-to-citekey-one-pdf () +(ert-deftest bog-file-citekey () + (should (equal (bog-file-citekey "name2000word.pdf") "name2000word")) + (should (equal (bog-file-citekey "name2000word-supp.pdf") "name2000word")) + (should (equal (bog-file-citekey "name2000word_0.pdf") "name2000word")) + (should-not (bog-file-citekey "name2000.pdf")) + (should-not (bog-file-citekey "leader_name2000word.pdf"))) + +(ert-deftest bog-all-file-citekeys () + (bog-tests--with-temp-dir + (let ((bog-file-directory (expand-file-name "citekey-files"))) + (make-directory bog-file-directory) + (let ((default-directory bog-file-directory)) + (make-directory "key2000butdir")) + (write-region "" nil (expand-file-name "nokey.pdf" bog-file-directory)) + (write-region "" nil (expand-file-name "one2010key.pdf" bog-file-directory)) + (write-region "" nil (expand-file-name "two1980key.txt" bog-file-directory)) + (should (equal (bog-all-file-citekeys) + '("one2010key" "two1980key")))))) + +(ert-deftest bog-rename-staged-file-to-citekey-one-file () (bog-tests--with-temp-dir (let ((bog-stage-directory (expand-file-name "stage")) - (bog-pdf-directory (expand-file-name "pdfs")) + (bog-file-directory (expand-file-name "citekey-files")) (citekey "name2010word")) (make-directory bog-stage-directory) - (make-directory bog-pdf-directory) + (make-directory bog-file-directory) (write-region "" nil (expand-file-name "one.pdf" bog-stage-directory)) (with-temp-buffer (insert (format "\n* top level\n\n** %s\n\nsome text\n" @@ -164,24 +183,26 @@ (org-mode) (show-all) (re-search-backward bog-citekey-format) - (bog-rename-staged-pdf-to-citekey)) + (bog-rename-staged-file-to-citekey)) (should (file-exists-p (expand-file-name - (concat citekey ".pdf") bog-pdf-directory))) + (concat citekey ".pdf") bog-file-directory))) (should-not (file-exists-p (expand-file-name (concat "one.pdf") bog-stage-directory)))))) -(ert-deftest bog-pdf-citekeys-multiple-variants () +(ert-deftest bog-file-citekeys-multiple-variants () (bog-tests--with-temp-dir - (let* ((bog-pdf-directory (expand-file-name "pdfs")) + (let* ((bog-file-directory (expand-file-name "citekey-files")) (citekey "name2010word") - (variants (--map (concat citekey it ".pdf") - '("" "_0" "-supplement"))) + (variants (list (concat citekey ".pdf") + (concat citekey ".txt") + (concat citekey "_0.pdf") + (concat citekey "-supplement.pdf"))) found-files) - (make-directory bog-pdf-directory) + (make-directory bog-file-directory) (--each variants - (write-region "" nil (expand-file-name it bog-pdf-directory))) - (setq files-found (bog-citekey-pdfs citekey)) - (should (= (length files-found) 3))))) + (write-region "" nil (expand-file-name it bog-file-directory))) + (setq files-found (bog-citekey-files citekey)) + (should (= (length files-found) 4))))) ;;; BibTeX functions diff --git a/bog-todo.org b/bog-todo.org index 76f361b..5e905f7 100644 --- a/bog-todo.org +++ b/bog-todo.org @@ -43,7 +43,8 @@ Default could be "*.tex". * PDF files -** ENH Generalize PDF functions in bog +** DONE Generalize PDF functions in bog + CLOSED: [2014-04-26 Sat 17:01] Replace bog-find-citekey-pdf with bog-find-citekey-file. The extensions that will be considered could be customized. Rebind this to "f". diff --git a/bog.el b/bog.el index de7e429..6cec153 100644 --- a/bog.el +++ b/bog.el @@ -27,10 +27,10 @@ ;; Org mode. Many of these commands center around a citekey, the unique ;; identifier for a study. Some of the main commands are listed below. ;; -;; - `bog-find-citekey-pdf' +;; - `bog-find-citekey-file' ;; - `bog-find-citekey-bib' ;; - `bog-search-citekey-on-web' -;; - `bog-rename-staged-pdf-to-citekey' +;; - `bog-rename-staged-file-to-citekey' ;; - `bog-goto-citekey-heading-in-buffer' ;; - `bog-goto-citekey-heading-in-notes' ;; - `bog-search-notes-for-citekey' @@ -99,16 +99,16 @@ default value of `org-bibtex-key-property'." :group 'bog :type 'string) -(defcustom bog-pdf-directory - (expand-file-name "pdfs" bog-notes-directory) - "Directory with citekey-associated PDF files." +(defcustom bog-file-directory + (expand-file-name "citekey-files" bog-notes-directory) + "Directory with citekey-associated files." :group 'bog :type 'string) (defcustom bog-stage-directory (expand-file-name "stage" bog-notes-directory) "Directory to search for new files. -`bog-rename-staged-pdf-to-citekey' and +`bog-rename-staged-file-to-citekey' and `bog-rename-staged-bib-to-citekey' will search here for files to rename." :group 'bog @@ -140,25 +140,25 @@ This is only meaningful if `bog-find-citekey-bib-func' set to :group 'bog :type 'string) -(defcustom bog-pdf-file-name-separators '("-" "_") - "Characters allowed to follow the citekey in PDF file names. -When `bog-find-citekey-pdf' is run on , it will find -files with the format *.pdf, where is one of -the characters in `bog-pdf-file-name-separators'.") - -(defcustom bog-pdf-renaming-func 'bog-pdf-ask-on-conflict - "Function used to rename stage PDF files. -This function should accept a PDF file name and a citekey as -arguments and return the name of the final PDF file. Currently -the only built-in function is `bog-pdf-ask-on-conflict'.") - -(defcustom bog-pdf-secondary-name "-supplement" - "Modification to make to PDF file name on renaming confict. -When a staged PDF is being renamed with -`bog-pdf-ask-on-conflict', the user will be prompted if -.pdf already exists. -`bog-pdf-secondary-name'.pdf will be the default value -for the prompt.") +(defcustom bog-citekey-file-name-separators '("-" "_") + "Characters allowed to follow the citekey in file names. +When `bog-find-citekey-file' is run on , it will find +files with the format *., where is one +of the characters in `bog-citekey-file-name-separators'.") + +(defcustom bog-file-renaming-func 'bog-file-ask-on-conflict + "Function used to rename staged files. +This function should accept a file name and a citekey as +arguments and return the name of the final file. Currently the +only built-in function is `bog-file-ask-on-conflict'.") + +(defcustom bog-file-secondary-name "-supplement" + "Modification to make to file name on renaming confict. +When a staged file is being renamed with +`bog-file-ask-on-conflict', the user will be prompted if +. already exists. +`bog-file-secondary-name'. will be the default +value for the prompt.") (defcustom bog-web-search-url "http://scholar.google.com/scholar?q=%s" @@ -273,108 +273,119 @@ year, and the first meaningful word in the title)." t)) -;;; PDF-related +;;; Citekey-associated files ;;;###autoload -(defun bog-find-citekey-pdf (arg) - "Open PDF file for a citekey. +(defun bog-find-citekey-file (arg) + "Open citekey-associated file. If a prefix argument is given, a prompt will open to select from available citekeys. Otherwise, the citekey will be taken from the text under point if it matches `bog-citekey-format' or using `bog-citekey-func'." (interactive "P") - (let ((citekey (or (and arg (bog-select-citekey (bog-pdf-citekeys))) + (let ((citekey (or (and arg (bog-select-citekey (bog-all-file-citekeys))) (bog-citekey-from-notes)))) - (bog-open-citekey-pdf citekey))) + (bog-open-citekey-file citekey))) -(defun bog-open-citekey-pdf (citekey) - (let* (citekey-pdf - (citekey-pdfs (bog-citekey-pdfs citekey)) - (citekey-pdfs-names (-map 'file-name-nondirectory citekey-pdfs)) - (num-choices (length citekey-pdfs-names))) +(defun bog-open-citekey-file (citekey) + (let* (citekey-file + (citekey-files (bog-citekey-files citekey)) + (citekey-file-names (-map 'file-name-nondirectory citekey-files)) + (num-choices (length citekey-file-names))) (cond ((= 0 num-choices) - (error "No PDF found for %s" citekey)) + (error "No file found for %s" citekey)) ((= 1 num-choices) - (setq citekey-pdf (car citekey-pdfs))) + (setq citekey-file (car citekey-files))) (t - (setq citekey-pdf - (expand-file-name (org-icompleting-read "Select PDF file: " - citekey-pdfs-names) - bog-pdf-directory)))) - (org-open-file citekey-pdf))) - -(defun bog-citekey-pdfs (citekey) - (let* ((patterns (--map (concat it "*") bog-pdf-file-name-separators)) - (patterns (cons "" patterns))) + (setq citekey-file + (expand-file-name (org-icompleting-read "Select file: " + citekey-file-names) + bog-file-directory)))) + (org-open-file citekey-file))) + +(defun bog-citekey-files (citekey) + (let* ((patterns (--map (concat it "*") bog-citekey-file-name-separators)) + (patterns (cons ".*" patterns))) (--mapcat (file-expand-wildcards - (concat (file-name-as-directory bog-pdf-directory) - citekey it ".pdf")) + (concat (file-name-as-directory bog-file-directory) + citekey it)) patterns))) ;;;###autoload -(defun bog-rename-staged-pdf-to-citekey () - "Rename PDF in `bog-stage-directory' to `bog-pdf-directory'/.pdf. +(defun bog-rename-staged-file-to-citekey () + "Rename file in `bog-stage-directory' to `bog-file-directory'/.. The citekey will be taken from the text under point if it matches `bog-citekey-format' or using `bog-citekey-func'." (interactive) (let ((citekey (bog-citekey-from-notes))) - (bog-rename-staged-pdf citekey))) - -(defun bog-rename-staged-pdf (citekey) - (let* ((staged-pdfs - (file-expand-wildcards - (concat (file-name-as-directory bog-stage-directory) "*.pdf"))) - (staged-pdfs-names (-map 'file-name-nondirectory staged-pdfs)) - (num-choices (length staged-pdfs-names)) - staged-pdf) + (bog-rename-staged-file citekey))) + +(defun bog-rename-staged-file (citekey) + (let* ((staged-files (bog-staged-files)) + (staged-file-names (-map 'file-name-nondirectory staged-files)) + (num-choices (length staged-file-names)) + staged-file) + (message "choices: %s" num-choices) (cond ((= 0 num-choices) - (setq staged-pdf (org-iread-file-name "Select PDF file to rename: "))) + (setq staged-file (org-iread-file-name "Select file to rename: "))) ((= 1 num-choices) - (setq staged-pdf (car staged-pdfs))) + (setq staged-file (car staged-files))) (t - (setq staged-pdf + (setq staged-file (expand-file-name - (org-icompleting-read "Select PDF file to rename: " - staged-pdfs-names) + (org-icompleting-read "Select file to rename: " + staged-file-names) bog-stage-directory)))) - (message "Renamed %s to %s" staged-pdf - (funcall bog-pdf-renaming-func staged-pdf citekey)))) - -(defun bog-pdf-ask-on-conflict (staged-pdf citekey) - "Prompt for a new name of PDF file for CITEKEY already exists. -STAGED-PDF will be renamed to .pdf within -`bog-pdf-directory'. If this file already exists, the user will -be prompted for another name. `bog-pdf-secondary-name' can be + (message "Renamed %s to %s" staged-file + (funcall bog-file-renaming-func staged-file citekey)))) + +(defun bog-file-ask-on-conflict (staged-file citekey) + "Prompt for a new name of file for CITEKEY already exists. +STAGED-FILE will be renamed to . within +`bog-file-directory'. If this file already exists, the user will +be prompted for another name. `bog-file-secondary-name' can be used to control the default string used in the prompt." - (let ((pdf-file (bog-citekey-as-pdf citekey))) + (let* ((ext (file-name-extension staged-file)) + (citekey-file (bog-citekey-as-file citekey ext))) (condition-case nil - (rename-file staged-pdf pdf-file) + (rename-file staged-file citekey-file) (file-error (let ((new-file-name - (replace-regexp-in-string ".pdf" - (concat bog-pdf-secondary-name ".pdf") - (file-name-nondirectory pdf-file)))) + (file-name-nondirectory + (bog-citekey-as-file (concat citekey bog-file-secondary-name) + ext)))) (setq new-file-name (read-string (format "File %s already exists. Name to use instead: " - pdf-file) + citekey-file) new-file-name nil nil '(new-file-name))) - (setq pdf-file (expand-file-name new-file-name bog-pdf-directory)) - (rename-file staged-pdf pdf-file)))) - pdf-file)) + (setq citekey-file (expand-file-name new-file-name bog-file-directory)) + (rename-file staged-file citekey-file)))) + citekey-file)) -(defun bog-citekey-as-pdf (citekey) - (expand-file-name (concat citekey ".pdf") bog-pdf-directory)) +(defun bog-citekey-as-file (citekey ext) + (expand-file-name (concat citekey "." ext) bog-file-directory)) -(defun bog-pdf-citekeys () - "Return a list of citekeys for all pdf files in -`bog-pdf-directory'." - (-map 'file-name-base - (file-expand-wildcards (concat - (file-name-as-directory bog-pdf-directory) - "*.pdf")))) +(defun bog-all-file-citekeys () + "Return a list of citekeys for files in `bog-file-directory'." + (-distinct (-keep 'bog-file-citekey (bog-all-citekey-files)))) + +(defun bog-file-citekey (file) + (let ((fname (file-name-base file))) + (when (string-match (concat "^" bog-citekey-format) fname) + (match-string 0 fname)))) + +(defun bog-all-citekey-files () + (-remove 'file-directory-p + (directory-files bog-file-directory + t directory-files-no-dot-files-regexp))) + +(defun bog-staged-files () + (-remove 'file-directory-p + (directory-files bog-stage-directory + t directory-files-no-dot-files-regexp))) ;;; BibTeX-related @@ -623,8 +634,8 @@ Sorting is only done if the heading's level matches (defvar bog-mode-map (let ((map (make-sparse-keymap))) (let ((prefix-map (make-sparse-keymap))) - (define-key prefix-map "p" 'bog-find-citekey-pdf) - (define-key prefix-map "r" 'bog-rename-staged-pdf-to-citekey) + (define-key prefix-map "f" 'bog-find-citekey-file) + (define-key prefix-map "r" 'bog-rename-staged-file-to-citekey) (define-key prefix-map "b" 'bog-find-citekey-bib) (define-key prefix-map "s" 'bog-search-notes) (define-key prefix-map "c" 'bog-search-notes-for-citekey) -- cgit v1.2.3