summaryrefslogtreecommitdiff
path: root/lisp/ldg-schedule.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/ldg-schedule.el')
-rw-r--r--lisp/ldg-schedule.el85
1 files changed, 33 insertions, 52 deletions
diff --git a/lisp/ldg-schedule.el b/lisp/ldg-schedule.el
index 885c0876..538e64c0 100644
--- a/lisp/ldg-schedule.el
+++ b/lisp/ldg-schedule.el
@@ -20,7 +20,7 @@
;; Boston, MA 02111-1307, USA.
;;; Commentary:
-;;
+;;
;; This module provides for automatically adding transactions to a
;; ledger buffer on a periodic basis. Recurrence expressions are
;; inspired by Martin Fowler's "Recurring Events for Calendars",
@@ -49,14 +49,20 @@
:type 'integer
:group 'ledger-schedule)
-(defcustom ledger-schedule-file "~/FinanceData/ledger-schedule.ledger"
+(defcustom ledger-schedule-file "~/ledger-schedule.ledger"
"File to find scheduled transactions."
:type 'file
:group 'ledger-schedule)
+(defvar ledger-schedule-available nil)
+
(defsubst between (val low high)
(and (>= val low) (<= val high)))
+(defun ledger-check-schedule-available ()
+ (setq ledger-schedule-available (and ledger-schedule-file
+ (file-exists-p ledger-schedule-file))))
+
(defun ledger-schedule-days-in-month (month year)
"Return number of days in the MONTH, MONTH is from 1 to 12.
If year is nil, assume it is not a leap year"
@@ -67,7 +73,7 @@ If year is nil, assume it is not a leap year"
(error "Month out of range, MONTH=%S" month)))
;; Macros to handle date expressions
-
+
(defun ledger-schedule-constrain-day-in-month (count day-of-week)
"Return a form that evaluates DATE that returns true for the COUNT DAY-OF-WEEK.
For example, return true if date is the 3rd Thursday of the
@@ -80,24 +86,24 @@ COUNT 0) means EVERY day-of-week (eg. every Saturday)"
(let ((decoded (gensym)))
`(let ((,decoded (decode-time date)))
(and (eq (nth 6 ,decoded) ,day-of-week)
- (between (nth 3 ,decoded)
- ,(* (1- count) 7)
+ (between (nth 3 ,decoded)
+ ,(* (1- count) 7)
,(* count 7))))))
- ((< count 0)
+ ((< count 0)
(let ((days-in-month (gensym))
(decoded (gensym)))
`(let* ((,decoded (decode-time date))
- (,days-in-month (ledger-schedule-days-in-month
- (nth 4 ,decoded)
+ (,days-in-month (ledger-schedule-days-in-month
+ (nth 4 ,decoded)
(nth 5 ,decoded))))
(and (eq (nth 6 ,decoded) ,day-of-week)
- (between (nth 3 ,decoded)
- (+ ,days-in-month ,(* count 7))
+ (between (nth 3 ,decoded)
+ (+ ,days-in-month ,(* count 7))
(+ ,days-in-month ,(* (1+ count) 7)))))))
(t
(error "COUNT out of range, COUNT=%S" count)))
- (error "Invalid argument to ledger-schedule-day-in-month-macro %S %S"
- count
+ (error "Invalid argument to ledger-schedule-day-in-month-macro %S %S"
+ count
day-of-week)))
(defun ledger-schedule-constrain-every-count-day (day-of-week skip start-date)
@@ -138,10 +144,10 @@ the transaction should be logged for that day."
(let ((date-descriptor "")
(transaction nil)
(xact-start (match-end 0)))
- (setq date-descriptors
+ (setq date-descriptors
(ledger-schedule-read-descriptor-tree
- (buffer-substring-no-properties
- (match-beginning 0)
+ (buffer-substring-no-properties
+ (match-beginning 0)
(match-end 0))))
(forward-paragraph)
(setq transaction (list date-descriptors
@@ -150,7 +156,7 @@ the transaction should be logged for that day."
(point))))
(setq xact-list (cons transaction xact-list))))
xact-list)))
-
+
(defun ledger-schedule-replace-brackets ()
"Replace all brackets with parens"
(goto-char (point-min))
@@ -166,7 +172,7 @@ the transaction should be logged for that day."
"\\([\*]\\|\\([0-3][0-9]\\)\\|"
"\\([0-5]"
"\\(\\(Su\\)\\|"
- "\\(Mo\\)\\|"
+ "\\(Mo\\)\\|"
"\\(Tu\\)\\|"
"\\(We\\)\\|"
"\\(Th\\)\\|"
@@ -182,19 +188,19 @@ returns true if the date meets the requirements"
;; Replace brackets with parens
(insert descriptor-string)
(ledger-schedule-replace-brackets)
-
+
(goto-char (point-max))
;; double quote all the descriptors for string processing later
(while (re-search-backward ledger-schedule-descriptor-regex nil t) ;; Day slot
- (goto-char
+ (goto-char
(match-end 0))
(insert ?\")
(goto-char (match-beginning 0))
(insert "\"" )))
-
+
;; read the descriptor string into a lisp object the transform the
;; string descriptor into useable things
- (ledger-schedule-transform-auto-tree
+ (ledger-schedule-transform-auto-tree
(read (buffer-substring-no-properties (point-min) (point-max))))))
(defun ledger-schedule-transform-auto-tree (descriptor-string-list)
@@ -207,7 +213,7 @@ returns true if the date meets the requirements"
(if (consp newcar)
(setq newcar (ledger-schedule-transform-auto-tree (car descriptor-string-list))))
;; newcar may be a cons now, after ledger-schedule-transfrom-auto-tree
- (if (consp newcar)
+ (if (consp newcar)
(push newcar result)
;; this is where we actually turn the string descriptor into useful lisp
(push (ledger-schedule-compile-constraints newcar) result)) )
@@ -215,7 +221,7 @@ returns true if the date meets the requirements"
;; tie up all the clauses in a big or and lambda, and return
;; the lambda function as list to be executed by funcall
- `(lambda (date)
+ `(lambda (date)
,(nconc (list 'or) (nreverse result) descriptor-string-list)))))
(defun ledger-schedule-compile-constraints (descriptor-string)
@@ -238,8 +244,8 @@ returns true if the date meets the requirements"
(error "Improperly specified year constraint: " str)))))
(defun ledger-schedule-constrain-month (str)
-
- (let ((month-match t))
+
+ (let ((month-match t))
(cond ((string= str "*")
month-match) ;; always match
((/= 0 (setq month-match (string-to-number str)))
@@ -291,35 +297,10 @@ returns true if the date meets the requirements"
(ledger-mode))
(length candidates)))
-
-;;
-;; Test harnesses for use in ielm
-;;
-(defvar auto-items)
-
-(defun ledger-schedule-test ( early horizon)
- (ledger-schedule-create-auto-buffer
- (ledger-schedule-scan-transactions ledger-schedule-file)
- early
- horizon
- (get-buffer "2013.ledger")))
-
-
-(defun ledger-schedule-test-predict ()
- (let ((today (current-time))
- test-date items)
-
- (loop for day from 0 to ledger-schedule-look-forward by 1 do
- (setq test-date (time-add today (days-to-time day)))
- (dolist (item auto-items items)
- (if (funcall (car item) test-date)
- (setq items (append items (list (decode-time test-date) (cdr item)))))))
- items))
-
(defun ledger-schedule-upcoming ()
(interactive)
- (ledger-schedule-create-auto-buffer
- (ledger-schedule-scan-transactions ledger-schedule-file)
+ (ledger-schedule-create-auto-buffer
+ (ledger-schedule-scan-transactions ledger-schedule-file)
ledger-schedule-look-backward
ledger-schedule-look-forward
(current-buffer)))