Created
May 25, 2012 07:09
-
-
Save matthew-ball/2786321 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; FILE: /home/chu/Programming/lisp/elisp/ref-man/org-ref-man.el | |
;; AUTHOR: Matthew Ball (copyleft 2012) | |
;; TIME: Fri 25 May 2012 02:46:58 EST | |
;;; COMMENT: | |
;; Welcome to `org-ref-man', a reference manager for GNU Emacs utilising the functionality of `org-mode'. | |
;; The project's goals state: | |
;; 1. Creates and manages a database of source material. | |
;; 2. Interact with this database with emacs-lisp. | |
;; 3. Creates an `org-mode' buffer with the database information. | |
;; TODO: | |
;; 1. Populate database. | |
;; 2. Write parser to read from `org-table' entries. | |
(require 'ref-man-db) | |
(eval-when-compile (require 'cl)) | |
;; COMMENT: custom variables | |
(defcustom ref-man-directory (expand-file-name "~/Documents/Papers/PDFs/") | |
"`ref-man' main directory; for storing/locating reference material." | |
:type 'directory :safe 'stringp :group 'ref-man) | |
(defcustom ref-man-extension "pdf" ;; TODO: should make this a list | |
"`ref-man' file extension." | |
:type 'string :safe 'stringp :group 'ref-man) | |
;; COMMENT: constants | |
(defconst ref-man-version "0.3" "Version of the system's `ref-man' install.") | |
(defconst ref-man-mode-name "org-ref-man" "The `ref-man' mode name.") | |
(defconst ref-man-buffer-name (concat "*" ref-man-mode-name "*") "The `ref-man' buffer name.") | |
(defconst ref-man-column-length 20 "Column length for `ref-man'.") | |
;; COMMENT: variables | |
(defvar ref-man-mode-hook nil "Run hook when entering `ref-man' mode.") | |
(defvar ref-man-files nil "List of files.") | |
(defvar ref-man-filter-regexp nil "Current filter regexp used by `ref-man' mode.") ;; NOTE: should be able to filter `tags' | |
;; COMMENT: functions | |
(defun ref-man-reset-files () | |
"Reset the `ref-man-files' list." | |
(setq ref-man-files nil)) | |
(defun ref-man-find-files () | |
"Return a list of all files in the `ref-man-directory' directory which matches the `ref-man-extension' extension." | |
(if (file-exists-p ref-man-directory) | |
(let (files result) | |
(setq files (directory-files ref-man-directory t (concat "\." ref-man-extension "$") t)) | |
(dolist (file-name files) | |
(when (and (file-readable-p file-name) (not (file-directory-p file-name))) | |
(setq result (cons file-name result)))) | |
result))) | |
(defun ref-man-buffer-setup () | |
"Render the file browser in the `*ref-man*' buffer." | |
;; TODO: check if database entry is found, ask questions, etc | |
;; (setq ref-man-files (ref-man-find-files)) ;; NOTE: find files | |
(setq ref-man-files (ref-man-load-database)) ;; NOTE: load database | |
(if (not (file-exists-p ref-man-directory)) | |
(insert (concat "ERROR: Directory " ref-man-directory " does not exist.")) | |
(if ref-man-files | |
(progn | |
(ref-man-populate-database) | |
(ref-man-read-from-database) | |
(insert "* Reference Manager\n") | |
(insert "|----------------------------------------+----------+--------|\n") | |
(insert "| *Title* | *Author* | *Year* |\n") | |
(insert "|----------------------------------------+----------+--------|\n") | |
(dolist (entry ref-man-files) | |
(insert | |
(concat "| [[" (plist-get entry :file) "][" (plist-get entry :title) "]] | " | |
(plist-get entry :author) " | " | |
(plist-get entry :year) " |")) | |
(insert "\n")) | |
(insert "|----------------------------------------+----------+--------|\n\n") | |
(insert "* Bibliography Information\n")) | |
(insert (concat "ERROR: No files were loaded.")) | |
))) | |
(defun ref-man-populate-database () | |
"Populate the `ref-man' database with the contents of the `ref-man-files' variable." | |
(dolist (entry ref-man-files) | |
(ref-man-create-record | |
(plist-get entry :file) | |
(plist-get entry :title) | |
(plist-get entry :author) | |
(plist-get entry :type) | |
(plist-get entry :year) | |
(plist-get entry :tags)))) | |
(defun ref-man-read-from-database () ;; ERROR: this does not work | |
"..." | |
(dolist (record ref-man-record-database) ;; NOTE: loop through the records of the (external) `ref-man-db' database | |
(add-to-list 'ref-man-files record) ;; NOTE: ... add the record to the (internal) `ref-man' database | |
)) | |
;; COMMENT: commands | |
(defun ref-man-add-file (file &optional title author type notes) ;; TODO: ... | |
"Add a file to the `ref-man-files' database." | |
(interactive "f\nSelect file:")) | |
(defun ref-man-quit (&rest junk) | |
"Bury the `*ref-man*' buffer." | |
(interactive) | |
(setq ref-man-files nil) ;; NOTE: clear database | |
(when (string= (buffer-name) ref-man-buffer-name) | |
(kill-buffer))) | |
(defun ref-man-goto-file (&rest junk) ;; NOTE: this is a bit limiting, requires *all* files to be in the same main directory | |
"Follow filename in `*ref-man*' buffer." | |
(interactive) | |
(find-file (concat ref-man-directory (thing-at-point 'filename)))) | |
;; COMMENT: mode configuration | |
(defvar ref-man-mode-map | |
(let ((map (make-keymap))) | |
;; sorting | |
;; (define-key map (kbd "s") 'ref-man-sort-files) ;; sort by FILE or {AUTHOR, JOURNAL, YEAR, TAGS} ;; ERROR: this won't work | |
;; open file | |
(define-key map (kbd "RET") 'ref-man-goto-file) | |
;; file management | |
(define-key map (kbd "a") 'ref-man-add-file) | |
(define-key map (kbd "r") 'ref-man-remove-file) ;; TODO: rename to `ref-man-delete-file' | |
;; misc | |
(define-key map (kbd "g") 'ref-man-refresh) | |
(define-key map (kbd "q") 'ref-man-quit) | |
(define-key map (kbd "v") 'ref-man-show-version) | |
;; widgets | |
(define-key map [down-mouse-1] 'widget-button-click) | |
(define-key map [down-mouse-2] 'widget-button-click) | |
(define-key map (kbd "<tab>") 'widget-forward) | |
(define-key map (kbd "<backtab>") 'widget-backward) | |
(define-key map (kbd "<S-tab>") 'widget-backward) | |
map) | |
"Keymap for `ref-man' major mode") | |
(defun ref-man-mode (&rest junk) | |
"Major mode for managing reference files in GNU Emacs." | |
(kill-all-local-variables) | |
(setq truncate-lines t) | |
(ref-man-buffer-setup) ;; NOTE: render `*ref-man*' buffer | |
(org-mode) | |
;; NOTE: the following ... | |
(beginning-of-buffer) | |
(org-cycle) | |
(next-line) | |
(next-line) | |
(org-cycle) | |
(beginning-of-buffer) | |
;; NOTE: ... is there just to set up the display (there is a better way) | |
(toggle-read-only)) | |
(put 'ref-man-mode 'mode-class 'special) | |
;;;###autoload | |
(defun ref-man () | |
"Switch to `*ref-man*' buffer and start mode." | |
(interactive) | |
(save-excursion | |
(split-window-below) | |
(switch-to-buffer ref-man-buffer-name) | |
(when (not (eq major-mode 'ref-man-mode)) | |
(ref-man-mode)))) | |
(provide 'org-ref-man) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment