emacs-orgmode
[Top][All Lists]
Advanced

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

Re: [feature request] A new cookie type [!] showing the last note taken


From: Eric Abrahamsen
Subject: Re: [feature request] A new cookie type [!] showing the last note taken
Date: Mon, 14 Sep 2020 12:49:38 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:

> Hello,
>
> Ihor Radchenko <yantar92@gmail.com> writes:
>
>> I did not know this and I cannot find any reference about such behaviour
>> in manual (info:org#Markup for Rich Contents).
>
> You can find it looking for "line break" in the index. It points there:
> (info "(org) Paragraphs").
>
>>>> However, it is unused it unordered lists. We might define a note as a
>>>> unnumbered list item with [@note]:
>>>>
>>>> - [@note] This is note
>>>
>>> That's a reasonable syntax extension, maybe too English-centered. Maybe
>>> a more abstract [@!] would be better.
>>
>> It also looks better for me.
>> Should I open separate bug report proposing this syntax extension?
>
> Thinking again about it, I'm not sold about this idea. Is extending the
> syntax the way to go? 
>
> Sure, in the proposal above, it is relatively cheap. But what is the
> meaning of an item marked as a "note"? Everything in an entry could be
> a note; this is not limited to items. Moreover, if we are considering it
> to be a note just because it was automatically inserted using
> `org-add-log-note', then we are binding the tool to the syntax. This is
> a mistake.
>
> I would like to reconsider the solution to your use case. With a non-nil
> value for `org-log-into-drawer', it is possible to guess the location of
> the last inserted note, assuming manually inserted ones—if there is
> any—also follow the same pattern. Under such a reasonable configuration,
> it should not be too difficult to write a function extracting the last
> note, or a whole library operating on notes (ideas: move log-related
> functions to a new "org-log.el" library, simplify it using Org Capture
> as the machinery, extend it…).

Here's code I've had in my config for quite a while. It gets the
logbook, and shows the most recent item, bound to "V" in the agenda. It
also includes an aborted function to do more thorough parsing of the log
items -- I abandoned that because it was too gross.

I actually also have a library called org-log.el around here somewhere,
but that does quantitative logging of values, which I don't think has
enough general interest. But I'm attaching that, too, just in case.

Anyway, I'd be happy to work on this.

(defun org-get-log-list ()
  "Return the entry's log items, or nil.
The items are returned as a list of 'item elements."
  (save-excursion
    (goto-char (org-log-beginning))
    (let* ((el (org-element-at-point))
           list-string list-items)
      ;; Should we try harder to make sure it's actually the log list?
      (when (eq (org-element-type el) 'plain-list)
        (setq list-string
              (buffer-substring
               (org-element-property :contents-begin el)
               (org-element-property :contents-end el)))
        (with-temp-buffer
          (insert list-string)
          (setq list-items
                (org-element-map
                    (org-element-parse-buffer)
                    'item #'identity))))
      list-items)))

(defun org-agenda-show-log-item ()
  "Echo the text of the entry's most recent log note."
  (interactive)
  (let (log-list item)
    (org-agenda-with-point-at-orig-entry
     nil (setq log-list (org-get-log-list)))
    (if (not log-list)
        (message "Entry has no log")
      (setq item
            (if org-log-states-order-reversed
                (car log-list)
              (last log-list)))
      (message (org-element-interpret-data
                (org-element-contents item))))))

(with-eval-after-load 'org-agenda
  (org-defkey org-agenda-mode-map "V" 'org-agenda-show-log-item))

(defun org-parse-log-list (log-list)
  "Turn a parsed plain log list (as returned by
  `org-get-log-list') into something more interesting.

Specifically, this means to extract information from the plain
text of each log item, and put it onto the item's property
list.  Right now this function extracts  "
  (mapcar
   (lambda (item)
     (let* ((pars (org-element-map item 'paragraph #'identity))
            (head-par (car pars))
            ;; This is absolutely horrible: assume that, if the first
            ;; four characters of the log note heading match a value
            ;; from `org-log-note-headings', then that's the kind of
            ;; heading we've got.
            (horrible (mapcar
                       (lambda (x) (cons (car x) (substring (cdr x) 0 3)))
                       org-log-note-headings))
            (item-type (or (rassoc (substring head-par 0 3) horrible)
                           'uncertain))
            (timestamp (car-safe (org-element-map head-par 'timestamp 
#'identity)))
            state-from state-to schedule deadline)
       (cond ((eq item-type 'state)
              (setq state-to
                    (and (string-match "State \\([^[:space:]]*\\) " head-par)
                         (match-string 1 head-par)))
              (setq state-from
                    (and (string-match "from \\([^[:space:]]*\\) " head-par)
                         (match-string 1 head-par)))
              ))))
   log-list))

Attachment: org-log.el
Description: Text document


reply via email to

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