emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] org-log-note-headings 'state


From: John J Foerch
Subject: Re: [O] org-log-note-headings 'state
Date: Tue, 27 Mar 2012 21:49:17 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Bastien <address@hidden> writes:
> Hi John,
>
> John J Foerch <address@hidden> writes:
>
>> These thoughts lead me to suggest that maybe org-log-note-headings is no
>> longer sufficient to its original purpose, because extensions wish to
>> parse state changes, but that blocks users from configuring the formats.
>> Perhaps it is time to replace it with something that guarantees ability
>> to parse.
>
> I see the problem -- what do you suggest as a useful replacement for
> `org-log-note-headings'? 
>
>> Thoughts?
>
> I understand your point but I need more arguments to spend time on 
> improving this.  "Argument" = code that we would like to run and that
> would need a rewrite of `org-log-note-headings'.
>
> Thanks!

I have been experimenting with parsing the format-string to build a
regexp to match the generated-strings.  This approach depends upon the
parsability of the expansions of each of the percent-codes.  As concerns
org-log-note-headings, %t, %T, %d, %D, %s, %S, and %u all have parseable
expansions, as far as I can tell.  I'm not sure about %U, but if the
rest of the string is not too complicated, it shouldn't be a problem.
Format-code flag, width, and precision add some complexity to the
problem of generating regexps to match the codes, and I haven't done
that bit yet.  Overall I think this could be a very viable approach, and
I'll paste my scraps of code below:

;;; parsing state changes
;;;
(defun org-split-format-string (str)
  (let ((case-fold-search t)
        (format-regexp "%[+ #-0]*[0-9]*\\(\\.[0-9]+\\)?[%a-z]")
        (parts (list))
        (s 0))
    (while (string-match format-regexp str s)
      (let* ((beg (match-beginning 0))
             (end (match-end 0))
             (before (substring str s beg)))
        (unless (string= before "")
          (push before parts))
        (push (substring str beg end) parts)
        (setq s end)))
    (let ((last (substring str s)))
      (unless (string= last "")
        (push last parts)))
    (nreverse parts)))

;;tests
(equal (org-split-format-string "CLOSING NOTE %t") '("CLOSING NOTE " "%t"))
(equal (org-split-format-string "State %-12s from %-12S %t") '("State " "%-12s" 
" from " "%-12S" " " "%t"))
(equal (org-split-format-string "foo %t bar") '("foo " "%t" " bar"))
(equal (org-split-format-string "foo") '("foo"))
(equal (org-split-format-string "%s") '("%s"))
(equal (org-split-format-string "%s%t") '("%s" "%t"))

(defun org-get-format-parser (f)
  (let ((format-regexp "^%\\([+ 
#-0]*\\)\\([0-9]*\\)\\(\\.[0-9]+\\)?\\([%a-z]\\)$"))
    (string-match format-regexp f)
    (let ((flag (match-string 1 f))
          (numb (match-string 2 f))
          (prec (match-string 3 f))
          (code (match-string 4 f)))
      (cond
        ;; hardcode format codes for now.. later, pass them in as an
        ;; alist or something.
        ((string= "t" code) "\\(\\[.*?\\]\\)") ;; inactive timestamp
        ((string= "T" code) "\\(<.*?>\\)")     ;;   active timestamp
        ((string= "d" code) "\\(\\[.*?\\]\\)") ;; inactive short-format 
timestamp
        ((string= "D" code) "\\(<.*?>\\)")     ;;   active short-format 
timestamp
        ((string= "s" code) "\\(\".*?\"\\)")   ;; new TODO state
        ((string= "S" code) "\\(\".*?\"\\)")   ;; old TODO state
        ((string= "u" code) "\\(\\w+\\)") ;; user name
        ((string= "U" code) "\\(.*\\)") ;; full user name
        (t (error "Unsupported format: %s" f))))))

(defun org-parse-formatted-text (fmt str)
  (let* ((sfmt (org-split-format-string fmt))
         (regexp (concat
                  "^"
                  (apply
                   'concat
                   (mapcar
                    (lambda (x)
                      (if (equal ?% (aref x 0))
                          (org-get-format-parser x)
                          (regexp-quote x)))
                    sfmt))
                  "$")))
    regexp))

;; (org-parse-formatted-text "State %-12s from %-12S %t" "")
;; => "^State \\(\".*?\"\\) from \\(\".*?\"\\) \\(\\[.*?\\]\\)$"

;;;
;;; end parsing state changes

Thank you

-- 
John Foerch




reply via email to

[Prev in Thread] Current Thread [Next in Thread]