I'm looking for a way to match what I call the "notes", which is the last line (or set of lines) of an org task that says: "These are the notes of the task.
"
I have composed a really long regexp that may do the job, but I am hoping that org-mode already provides something better:
"^\\(\\*\\*\\)\\(?: +\\(Active\\|Next Action\\|Hold\\|Reference\\|Delegated\\|Postponed\\|Waiting\\|Someday\\|Planning\\|Canceled\\|None\\)\\)?\\(?: +\\(\\[#.\\]\\)\\)?\\(?: +\\(.*?\\)\\)??\\(?:[ ]+\\(:[[:alnum:]_@#%:]+:\\)\\)?[ ]*\\(?:\\(\n\\)\\)?\\(?: +\\(DEADLINE:\\|SCHEDULED:\\)\\)?\\(?: +\\(<\\)\\([^>]+\\)\\(>\\)\\)?\\(?: +\\(DEADLINE:\\|SCHEDULED:\\)\\)?\\(?: +\\(<\\)\\([^>]+\\)\\(>\\)\\)?\\(?:\\(\n\\)\\)?\\(?: +\\(CLOSED:.*\\)\\)?\\(?:\\(\n\\)\\)?\\(?: +\\(:PROPERTIES:\\)\\)?\\(?:\\(\n\\)\\)?\\(?: +\\(:ToodledoID:\\)\\)?\\(?: +\\([0-9]+\\)\\)?\\(?:\\(\n\\)\\)?\\(?: +\\(:ToodledoFolder:\\)\\)?\\(?: +\\(EVENTS\\|TASKS\\|UNDATED\\|DONE\\|CONTACT\\)\\)?\\(?:\\(\n\\)\\)\\(?: +\\(:Hash:\\)\\)?\\(?: +\\(.*+\\)\\)?\\(?:\\(\n\\)\\)?\\(?: +\\(:END:\\)\\)?\\(?:\\(\n\\)\\)?\\(.*\\(?:\n.*\\)*?\\)\\(?:^\\)"
** Delegated [#A] 0 @ Title of the task. :event:lawlist:
DEADLINE: <2014-01-11 Sat 08:00> SCHEDULED: <2014-01-11 Sat>
:PROPERTIES:
:ToodledoID: 353081871
:ToodledoFolder: EVENTS
:Hash: 20657e7586fcc67da708789d7bbc0fbd
:END:
These are the notes of the task.
The most complete examples of parsing an org task that I have found use org-element-parse-buffer
, but still I still don't see the key to extracting just the notes: https://github.com/yyr/org-mode/blob/master/testing/lisp/test-org-element.el
If possible, I'd like something similar to this imaginary code (org-element-property :notes (org-element-at-point))
, which doesn't require narrowing to subtree to extract the notes. I have a couple of hundred tasks, and I'm looking for a way to quickly comb the master org file and create my own custom agenda buffer that displays the first and perhaps the second lines (if deadline or scheduled) and the notes at the end if they exist. I have a feeling that if I have to narrow to subtree for 200 tasks, there will be a substantial delay to produce the final display.
The first two lines of the task are already handled with this:
(defvar lawlist-org-heading-regexp
"^\\(\\*+\\)\\(?: +\\(.*?\\)\\)?[ \t]*\\(\n.*DEADLINE.*$\\)"
"Custom match org headline, plus the second line with a deadline.")
(setq txt
(save-excursion
(org-back-to-heading t)
(when (looking-at org-heading-regexp)
(concat
(match-string 1)
" "
(match-string 2)
(if (and (looking-at lawlist-org-heading-regexp) (match-string 3))
(match-string 3))
"\n" )))) )
(message "%s" (org-element-map (org-element-parse-buffer) 'paragraph 'identity nil t))
gives me the following:
(paragraph
(:begin 244
:end 276
:contents-begin 244
:contents-end 276
:post-blank 0
:post-affiliated 244
:parent (section
(:begin 58
:end 276
:contents-begin 58
:contents-end 276
:post-blank 0
:parent (headline
(:raw-value 0
@
Title of the task.
:begin 1
:end 276
:pre-blank 0
:hiddenp nil
:contents-begin 58
:contents-end 276
:level 2
:priority 65
:tags (event lawlist)
:todo-keyword Delegated
:todo-type todo
:post-blank 0
:footnote-section-p nil
:archivedp nil
:commentedp nil
:quotedp nil
:deadline (timestamp
(:type active
:raw-value <2014-01-11 Sat 08:00>
:year-start 2014
:month-start 1
:day-start 11
:hour-start 8
:minute-start 0
:year-end 2014
:month-end 1
:day-end 11
:hour-end 8
:minute-end 0
:begin 71
:end 95
:post-blank 2))
:scheduled (timestamp
(:type active
:raw-value <2014-01-11 Sat>
:year-start 2014
:month-start 1
:day-start 11
:hour-start nil
:minute-start nil
:year-end 2014
:month-end 1
:day-end 11
:hour-end nil
:minute-end nil
:begin 106
:end 122
:post-blank 0))
:TOODLEDOID 353081871
:TOODLEDOFOLDER EVENTS
:HASH 20657e7586fcc67da708789d7bbc0fbd
:CATEGORY .scratch
:title (0 @ Title of the task.)
:parent (org-data nil #4)) #2))
(planning (:closed nil
:deadline (timestamp
(:type active
:raw-value <2014-01-11 Sat 08:00>
:year-start 2014
:month-start 1
:day-start 11
:hour-start 8
:minute-start 0
:year-end 2014
:month-end 1
:day-end 11
:hour-end 8
:minute-end 0
:begin 71
:end 95
:post-blank 2))
:scheduled (timestamp
(:type active
:raw-value <2014-01-11 Sat>
:year-start 2014
:month-start 1
:day-start 11
:hour-start nil
:minute-start nil
:year-end 2014
:month-end 1
:day-end 11
:hour-end nil
:minute-end nil
:begin 106
:end 122
:post-blank 0))
:begin 58
:end 123
:post-blank 0
:parent #2))
(property-drawer (:begin 123
:end 244
:hiddenp nil
:contents-begin 139
:contents-end 235
:post-blank 0
:post-affiliated 123
:parent #2)
(node-property (:key ToodledoID
:value 353081871
:begin 139
:end 165
:post-blank 0
:parent #3))
(node-property (:key ToodledoFolder
:value EVENTS
:begin 165
:end 192
:post-blank 0
:parent #3))
(node-property (:key Hash
:value 20657e7586fcc67da708789d7bbc0fbd
:begin 192
:end 235
:post-blank 0
:parent #3)))
#0))
These are the notes of the task.)
EDIT (January 7, 2014): First working draft . The tail end of the regexp will match notes until the next blank line -- i.e., notes may be several lines with hard returns and no blank lines between them.
EDIT (January 14, 2014): Revised 31 and 32 so that no final new line is needed at the end of the buffer -- i.e., a task with no notes at the end of the buffer is now recognized. Revised 20 to 24 so that the positions of the
:ToodledoID:
drawer and the:ToodledoFolder:
drawer are interchangeable. Revised exampleget-whopper
function to exclude 32.EDIT (November 14, 2014): Updated regexp a bit, but the functionality remains the same.
EDIT (December 2, 2014): Removed custom function and replaced with stock
org-back-to-heading
.EDIT (December 6, 2014: Major revamping of regex. The regex now supports optional items for the majority of the entries, and no final new line is required at the end of the buffer. With the new revision, the regexp can be used in a custom
*Org Agenda*
buffer that displays only partial items from the original todo -- e.g., heading + deadline / scheduled / closed + notes; or heading + notes only. The:tag:
, however, is a mandatory anchor -- i.e., at least one (1) tag is needed for the regexp to work correctly. Line endings -- i.e.,\n
-- are no longer numbered matching entries. The regex now supports todo entries that are bunched together without any new line separating them. See related thread regarding non-capturing group: https://stackoverflow.com/a/3513858/2112489 See also the related thread regarding multi-line regexp emacs: http://www.emacswiki.org/emacs/MultilineRegexp