From 2626b234016d3a826dde5b11c321512c98e12214 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Sun, 2 Feb 2014 23:50:16 -0500 Subject: Add core citekey functions --- bog-tests.el | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ bog.el | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 bog-tests.el create mode 100644 bog.el diff --git a/bog-tests.el b/bog-tests.el new file mode 100644 index 0000000..e7ce2cc --- /dev/null +++ b/bog-tests.el @@ -0,0 +1,116 @@ +(require 'ert) +(require 'org) +(require 'bog) + + +;;; Citekey functions + +;; `bog-citekey-p' + +(ert-deftest bog-citekey-p () + (should (bog-citekey-p "name2010word")) + (should (bog-citekey-p "name1900word")) + (should-not (bog-citekey-p "name201word"))) + +(ert-deftest bog-citekey-p-with-hyphen-in-name () + (should (bog-citekey-p "hyphen-ok2010word"))) + +(ert-deftest bog-citekey-p-with-other-text () + (should (bog-citekey-p "name2010word more text"))) + +(ert-deftest bog-citekey-only-p () + (should (bog-citekey-only-p "name2010word")) + (should-not (bog-citekey-only-p "name201word")) + (should (bog-citekey-only-p "hyphen-ok2010word")) + (should-not (bog-citekey-only-p "name2010word more text"))) + +;; `bog-citekey-groups-with-delim' + +(ert-deftest bog-citekey-groups-with-delim () + (let ((citekey "name2010word")) + (should (equal (bog-citekey-groups-with-delim citekey) + "name 2010 word")) + (should (equal (bog-citekey-groups-with-delim citekey ",") + "name,2010,word")) + (should (equal (bog-citekey-groups-with-delim citekey nil '(1 3)) + "name word")))) + +;; `bog-citekey-at-point' + +(ert-deftest bog-citekey-at-point () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert citekey) + (goto-char (point-min)) + (should (equal (bog-citekey-at-point) citekey))))) + +;; `bog-citekey-heading' + +(ert-deftest bog-citekey-heading-current-level () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert (format "\n* top level\n\n** %s\n\nsome text\n" + citekey)) + (org-mode) + (show-all) + (should (equal (bog-citekey-heading) citekey))))) + +(ert-deftest bog-citekey-heading-in-parent () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert (format "\n* top level\n\n** %s\n\n*** subheading\n\nsome text\n" + citekey)) + (org-mode) + (show-all) + (should (equal (bog-citekey-heading) citekey))))) + +(ert-deftest bog-citekey-heading-on-heading () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert (format "\n* top level\n\n** %s\n\nsome text\n" + citekey)) + (org-mode) + (show-all) + (re-search-backward bog-citekey-format) + (should (equal (bog-citekey-heading) citekey))))) + +(ert-deftest bog-citekey-action-in-normal-text () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert (format "\n* top level\n\n** %s\n\nsome text\n" + citekey)) + (org-mode) + (show-all) + (flet ((funcall (action citekey) citekey)) + (should (equal (bog-citekey-action nil nil nil) citekey)))))) + +;; `bog-citekey-action' + +(ert-deftest bog-citekey-action-on-heading () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert (format "\n* top level\n\n** %s\n\nsome text\n" + citekey)) + (org-mode) + (show-all) + (re-search-backward bog-citekey-format) + (flet ((funcall (action citekey) citekey)) + (should (equal (bog-citekey-action nil nil nil) citekey)))))) + +(ert-deftest bog-citekey-action-on-in-text-citekey () + (let ((citekey "name2010word")) + (with-temp-buffer + (insert (format "\n* top level\n\n** other2000key\n\nsome text and %s\n" + citekey)) + (org-mode) + (show-all) + (re-search-backward bog-citekey-format) + (flet ((funcall (action citekey) citekey)) + (should (equal (bog-citekey-action nil nil nil) citekey)))))) + +(ert-deftest bog-citekey-action-no-citekey () + (with-temp-buffer + (insert "\n* top level\n\n** second\n\n") + (org-mode) + (show-all) + (should-error (bog-citekey-action nil nil nil)))) diff --git a/bog.el b/bog.el new file mode 100644 index 0000000..971b811 --- /dev/null +++ b/bog.el @@ -0,0 +1,126 @@ +;;; bog.el --- Extensions for research notes in Org mode + +;; Copyright (C) 2013 Kyle Meyer + +;; Author: Kyle Meyer +;; URL: https://github.com/kyleam/bog +;; Keywords: BibTeX, org-mode +;; Version: 0.5.0 +;; Package-Requires: ((org "8.0.0") (dash "2.5.0")) + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; +;; Bog provides a few convenience functions for taking research notes in +;; Org mode. + +;;; Code: + +(require 'dash) +(require 'org) + + +;;; Customization + +(defgroup bog nil + "Extensions for research notes in Org mode" + :group 'tools + :group 'convenience) + +(defcustom bog-notes-directory "~/bib" + "The name of the directory that Org note are stored in." + :group 'bog + :type 'string) + +(defcustom bog-read-file-name 'read-file-name + "A function that will be used to promtp for file name. +The function should accept one arguments, a string to use for the +prompt. A good alternative is `ido-read-file-name'." + :group 'bog + :type 'function) + +(defcustom bog-completing-read 'completing-read + "A function that will be used for completion prompts. +The function should accept two arguments, a string to use for the +prompt and a list of strings to offer as choices. A good +alternative is `ido-completing-read'." + :group 'bog + :type 'function) + +(defcustom bog-citekey-format + "\\([0-9]*[a-z]+[-a-z]*\\)\\([0-9]\\{4\\}\\)\\([a-z]+\\)" + "Regex used to match study citekey. +By default, this matches any sequence of lower case +letters (allowing hyphenation) that is followed by 4 digits and +then lower case letters." + :type 'string + :group 'bog) + + +;;; General utilities + +(defun bog-citekey-action (action ask-func ask-citekey) + "Perform ACTION on file associtated with a citekey. + +ASK-FUNC should be a function that queries the user for a citekey +when ASK-CITEKEY is non-nil. Otherwise, the citekey will be taken +from the text under point if it matches `bog-citekey-format' or +from the first parent heading that matches `bog-citekey-format'. + +ACTION will be called with the resulting citekey as an argument." + (let* ((citekey (and ask-citekey (funcall ask-func))) + (citekey (or (bog-citekey-at-point) + (bog-citekey-heading)))) + (funcall action citekey))) + +(defun bog-select-citekey (citekeys) + "Prompt for citekey from CITEKEYS" + (funcall bog-completing-read "Select citekey: " citekeys)) + +(defun bog-citekey-at-point () + (let ((maybe-citekey (thing-at-point 'word))) + (when (and maybe-citekey + (bog-citekey-only-p maybe-citekey)) + maybe-citekey))) + +(defun bog-citekey-heading () + "Return first org heading that matches `bog-citekey-format'." + (save-excursion + (save-restriction + (widen) + (org-back-to-heading) + (let ((heading (org-element-property :raw-value (org-element-at-point)))) + (while (and (not (bog-citekey-only-p heading)) + (org-up-heading-safe)) + (setq heading + (org-element-property :raw-value (org-element-at-point)))) + (when (not (bog-citekey-only-p heading)) + (error "Citekey not found")) + heading)))) + +(defun bog-citekey-p (text) + "Indicate if TEXT matches `bog-citekey-format'." + (when (string-match bog-citekey-format text) + t)) + +(defun bog-citekey-only-p (text) + "Indicate if all of TEXT matches `bog-citekey-format'." + (string-match bog-citekey-format text) + (when (equal (length text) (match-end 0)) + t)) + +(provide 'bog) + +;; bog.el ends here -- cgit v1.2.3