emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: John J Foerch <jjfoerch@earthlink.net>
To: emacs-orgmode@gnu.org
Subject: Re: org-log-note-headings 'state
Date: Tue, 27 Mar 2012 21:49:17 -0400	[thread overview]
Message-ID: <87vclpjy02.fsf@hecubus.retroj.net> (raw)
In-Reply-To: 874nt9of38.fsf@gnu.org

Bastien <bzg@gnu.org> writes:
> Hi John,
>
> John J Foerch <jjfoerch@earthlink.net> 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	other threads:[~2012-03-28  1:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-21  2:21 org-log-note-headings 'state John J Foerch
2012-03-27 22:26 ` Bastien
2012-03-28  1:49   ` John J Foerch [this message]
2012-03-29 21:27     ` Ilya Shlyakhter
2012-03-29 22:45       ` John J Foerch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87vclpjy02.fsf@hecubus.retroj.net \
    --to=jjfoerch@earthlink.net \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).