Skip to content

Instantly share code, notes, and snippets.

@chrisdone-artificial
Created May 13, 2024 13:35
Show Gist options
  • Save chrisdone-artificial/dd132f71986b320c44fedacbbc2480a0 to your computer and use it in GitHub Desktop.
Save chrisdone-artificial/dd132f71986b320c44fedacbbc2480a0 to your computer and use it in GitHub Desktop.
parsing todoist style times in emacs lisp
(rx-define do-rx
(and word-start
(or
;; today/tomorrow
(and (group-n 1 "tom") (optional "orrow"))
(or (and (group-n 1 "tod") (optional "ay")))
;; next <thing>
(and "next "
(group-n 2 (or "week" "month" "year")))
;; in x <duration>
(and "in " do-duration-rx)
;; every <duration>
(and "every " do-duration-rx)
;; for <duration>
(and "for " do-duration-rx)
)
word-end))
(rx-define do-duration-rx
(and (group-n 3 (or "a" (one-or-more digit)))
" "
(group-n 4 (or "day" "week" "month" "year"))
(optional "s")))
(rx-define do-priority-rx
(and word-start
(group (or "p0" "p1" "p2" "p3"))
word-end))
(defun do-parse-rx (str)
"Parse the result of `do-time-rx' from LIST and STR into an integer of days."
(cond
;; today/tomorrow
((string= (match-string 1 str) "tod") `(:today))
((string= (match-string 1 str) "tom") `(:tomorrow))
;; next <thing>
((string= (match-string 2 str) "week") `(:next-week))
((string= (match-string 2 str) "month") `(:next-month))
((string= (match-string 2 str) "year") `(:next-year))
;; in x <things>.
((string= (match-string 3 str) "a")
`(:n-things
. (:count 1 :thing ,(match-string 4 str))))
((match-string 3 str)
`(:n-things
. (:count ,(string-to-number (match-string 3 str)) :thing ,(match-string 4 str))))
))
(defun do-parse (string)
"Parse STRING and extract any interesting keywords."
(let ((start 0)
(matches (list)))
(while (string-match (rx do-rx) string start)
(setq matches (cons (do-parse-rx string) matches))
(setq start (match-end 0))
(message "match: %s" (substring string (match-beginning 0) (match-end 0))))
matches))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment