 	(insert ?\")
 	(goto-char (match-beginning 0))
 	(insert "\"" )))
-       (ledger-auto-traverse-descriptor-tree 
-	(read (buffer-substring (point-min) (point-max))) 0)))
-
-(defun ledger-auto-traverse-descriptor-tree (tree depth)
-  (dolist (node tree)
-	  (cond ((eq (type-of node) 'string)
-		 (ledger-auto-parse-date-descriptor node))
-		((eq (type-of node) 'cons)
-		 (ledger-auto-traverse-descriptor-tree node (1+ depth))))))
-  
+    
+    ;; read the descriptor string into a lisp object the transform the
+    ;; string descriptor into useable things
+    (ledger-transform-auto-tree 
+     (read (buffer-substring (point-min) (point-max))))))
+
+(defun ledger-transform-auto-tree (tree)
+  (if (consp tree)
+      (let (result)
+	(while (consp tree)
+	  (let ((newcar (car tree)))
+	    (if (consp (car tree))
+		(setq newcar (ledger-transform-auto-tree (car tree))))
+	    (if (consp newcar) 
+		(push newcar result)
+		(push (ledger-auto-parse-date-descriptor newcar) result)) )
+	  (setq tree (cdr tree)))
+	(nconc (nreverse result) tree))))
+
+(defun ledger-auto-split-constraints (descriptor-string)
+  "Return a list with the year, month and day fields split"
+  (let ((fields (split-string descriptor-string "[/\\-]" t))
+	constrain-year constrain-month constrain-day)
+    (if (string= (car fields) "*")
+	(setq constrain-year nil)
+	(setq constrain-year (car fields)))
+    (if (string= (cadr fields) "*")
+	(setq constrain-month nil)
+	(setq constrain-month (cadr fields)))
+    (if (string= (nth 2 fields) "*")
+	(setq constrain-day nil)
+	(setq constrain-day (nth 2 fields)))
+    (list constrain-year constrain-month constrain-day)))
+
+(defun ledger-string-to-number-or-nil (str)
+  (if str
+      (string-to-number str)
+      nil))
+
+(defun ledger-auto-compile-constraints (constraint-list)
+  (let ((year-constraint (ledger-string-to-number-or-nil (nth 0 constraint-list)))
+	(month-constraint (ledger-string-to-number-or-nil (nth 1 constraint-list)))
+	(day-constraint (ledger-string-to-number-or-nil (nth 2 constraint-list))))
+    (ledger-auto-constrain-numerical-date-macro 
+     year-constraint
+     month-constraint
+     day-constraint)))
 
 (defun ledger-auto-parse-date-descriptor (descriptor)
   "Parse the date descriptor, return the evaluator"
-  descriptor)
+  (ledger-auto-compile-constraints 
+   (ledger-auto-split-constraints descriptor)))
 
 (provide 'ldg-auto)
 

	    (and (> ,target-day ,day1)
		 (< ,target-day ,day2))))))

(defun ledger-auto-is-holiday (date)
  "Return true if DATE is a holiday.")

(defun ledger-auto-scan-transactions (auto-file)
  (let ((xact-list (list)))
    (save-excursion
      (find-file auto-file)
      (goto-char (point-min))
      (while (re-search-forward "^\\[\\(.*\\)\\] " nil t)
	(let ((date-descriptor "")

  (and (>= val low) (<= val high)))

(defun ledger-auto-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"
  (if (between month 1 12)
      (if (and year (date-leap-year-p year) (= 2 month))
	  29
	  (nth (1- month) '(31 28 31 30 31 30 31 31 30 31 30 31)))
      (error "Month out of range, MONTH=%S" month)))

;; Macros to handle date expressions
      
(defmacro ledger-auto-constrain-day-in-month-macro (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
month.  Negative COUNT starts from the end of the month. (EQ
