* How to find the headline matching a string
@ 2014-05-31 15:07 Chris Poole
2014-05-31 15:27 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Chris Poole @ 2014-05-31 15:07 UTC (permalink / raw)
To: emacs-orgmode@gnu.org
[-- Attachment #1: Type: text/plain, Size: 472 bytes --]
Hi all,
Suppose I have a string, "my first task", that I know is tagged with
"laptop".
I want to search through the agenda files for a headline that matches this
string, to be able to mark it as DONE (in an automated fashion).
I can't find a function to search through for the headline --- is there one?
Else, is it best to concat all the agenda files into a larger buffer, then
parse the buffer and iterate through the headlines with org-element-map?
Cheers,
Chris
[-- Attachment #2: Type: text/html, Size: 666 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-05-31 15:07 How to find the headline matching a string Chris Poole
@ 2014-05-31 15:27 ` Eric Abrahamsen
2014-05-31 16:51 ` Chris Poole
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2014-05-31 15:27 UTC (permalink / raw)
To: emacs-orgmode
Chris Poole <lists@chrispoole.com> writes:
> Hi all,
>
> Suppose I have a string, "my first task", that I know is tagged with
> "laptop".
>
> I want to search through the agenda files for a headline that matches
> this string, to be able to mark it as DONE (in an automated fashion).
>
> I can't find a function to search through for the headline --- is
> there one?
>
> Else, is it best to concat all the agenda files into a larger buffer,
> then parse the buffer and iterate through the headlines with
> org-element-map?
>
>
> Cheers,
> Chris
Depending on how automated you need this to be, the `org-map-entries'
function can be given a scope of 'agenda (see its docstring). You could
call it with the agenda scope and a matcher for the "laptop" tag -- that
would at least get you all the headings in all the agenda files with the
"laptop" tag. Then the actual mapping function could call
`org-get-heading' on each of the matching headings, and check the text.
In these cases, though, I generally try to find a way to know the
heading's ID property, and use `org-id-goto'.
Hope that helps,
Eric
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-05-31 15:27 ` Eric Abrahamsen
@ 2014-05-31 16:51 ` Chris Poole
2014-05-31 17:00 ` Igor Sosa Mayor
2014-05-31 20:14 ` Thorsten Jolitz
0 siblings, 2 replies; 13+ messages in thread
From: Chris Poole @ 2014-05-31 16:51 UTC (permalink / raw)
To: Eric Abrahamsen; +Cc: emacs-orgmode@gnu.org
[-- Attachment #1: Type: text/plain, Size: 1619 bytes --]
Eric Abrahamsen:
> the `org-map-entries' function can be given a scope of 'agenda
That worked perfectly, thanks. Here's what I ended up with:
(org-map-entries (lambda ()
(when (equal title (org-get-heading t t))
(org-entry-put (point) "TODO" "DONE")))
tag 'agenda)
Cheers,
Chris
On Sat, May 31, 2014 at 4:27 PM, Eric Abrahamsen <eric@ericabrahamsen.net>
wrote:
> Chris Poole <lists@chrispoole.com> writes:
>
> > Hi all,
> >
> > Suppose I have a string, "my first task", that I know is tagged with
> > "laptop".
> >
> > I want to search through the agenda files for a headline that matches
> > this string, to be able to mark it as DONE (in an automated fashion).
> >
> > I can't find a function to search through for the headline --- is
> > there one?
> >
> > Else, is it best to concat all the agenda files into a larger buffer,
> > then parse the buffer and iterate through the headlines with
> > org-element-map?
> >
> >
> > Cheers,
> > Chris
>
> Depending on how automated you need this to be, the `org-map-entries'
> function can be given a scope of 'agenda (see its docstring). You could
> call it with the agenda scope and a matcher for the "laptop" tag -- that
> would at least get you all the headings in all the agenda files with the
> "laptop" tag. Then the actual mapping function could call
> `org-get-heading' on each of the matching headings, and check the text.
>
> In these cases, though, I generally try to find a way to know the
> heading's ID property, and use `org-id-goto'.
>
> Hope that helps,
> Eric
>
>
>
[-- Attachment #2: Type: text/html, Size: 2730 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-05-31 16:51 ` Chris Poole
@ 2014-05-31 17:00 ` Igor Sosa Mayor
2014-05-31 17:31 ` Chris Poole
2014-05-31 20:14 ` Thorsten Jolitz
1 sibling, 1 reply; 13+ messages in thread
From: Igor Sosa Mayor @ 2014-05-31 17:00 UTC (permalink / raw)
To: emacs-orgmode
Chris Poole <lists@chrispoole.com> writes:
> That worked perfectly, thanks. Here's what I ended up with:
>
> (org-map-entries (lambda ()
> (when (equal title (org-get-heading t t))
> (org-entry-put (point) "TODO" "DONE")))
> tag 'agenda)
could you maybe send a little more of the code? I would like to
understand how it exactly works.
Many thanks in advance.
--
:: Igor Sosa Mayor :: joseleopoldo1792@gmail.com ::
:: GnuPG: 0x1C1E2890 :: http://www.gnupg.org/ ::
:: jabberid: rogorido :: ::
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-05-31 16:51 ` Chris Poole
2014-05-31 17:00 ` Igor Sosa Mayor
@ 2014-05-31 20:14 ` Thorsten Jolitz
2014-06-01 4:05 ` Eric Abrahamsen
1 sibling, 1 reply; 13+ messages in thread
From: Thorsten Jolitz @ 2014-05-31 20:14 UTC (permalink / raw)
To: emacs-orgmode
Chris Poole <lists@chrispoole.com> writes:
> Eric Abrahamsen:
>> the `org-map-entries' function can be given a scope of 'agenda
>
> That worked perfectly, thanks. Here's what I ended up with:
>
> (org-map-entries (lambda ()
> (when (equal title (org-get-heading t t))
> (org-entry-put (point) "TODO" "DONE")))
> tag 'agenda)
As much as I like the powerful `org-map-entries', I wonder if it will
coexist with `org-element-map' in the future, since it does not use the
new parser.
Whats the recommendation here? Should one rather use
,-----------------------------------------------------------
| (org-element-map (org-element-parse-buffer) 'headline (lambda () ...))
`-----------------------------------------------------------
nowadays, or do both functions serve different purposes, or is it just a
matter of taste?
--
cheers,
Thorsten
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-05-31 20:14 ` Thorsten Jolitz
@ 2014-06-01 4:05 ` Eric Abrahamsen
2014-06-03 9:05 ` Thorsten Jolitz
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2014-06-01 4:05 UTC (permalink / raw)
To: emacs-orgmode
Thorsten Jolitz <tjolitz@gmail.com> writes:
> Chris Poole <lists@chrispoole.com> writes:
>
>> Eric Abrahamsen:
>>> the `org-map-entries' function can be given a scope of 'agenda
>>
>> That worked perfectly, thanks. Here's what I ended up with:
>>
>> (org-map-entries (lambda ()
>> (when (equal title (org-get-heading t t))
>> (org-entry-put (point) "TODO" "DONE")))
>> tag 'agenda)
>
> As much as I like the powerful `org-map-entries', I wonder if it will
> coexist with `org-element-map' in the future, since it does not use the
> new parser.
>
> Whats the recommendation here? Should one rather use
>
> ,-----------------------------------------------------------
> | (org-element-map (org-element-parse-buffer) 'headline (lambda () ...))
> `-----------------------------------------------------------
>
> nowadays, or do both functions serve different purposes, or is it just a
> matter of taste?
Interesting! I wasn't even aware of org-element-map, thanks for that.
Obviously I don't know the answer to your question, but they do seem to
do very similar things. On the other hand, `org-element-map' won't do
multiple files, and if you want to restrict to certain elements you have
to do the matching logic yourself (as opposed to `org-map-entries's
agenda-style search string).
I'd be curious, too, to hear if `org-map-entries' is going to get EOL'd
at some point. I suppose it's safe so long as `org-scan-tags' remains
the heart of the agenda process.
Here's my stab at two roughly equivalent functions, one using
org-element, the other older function. Just for the hell of it I tried
using "benchmark" to profile them, but have no idea if the results mean
much of anything. Most importantly, I don't really know if
`org-element-parse-buffer' ends up using the cache or not -- I assume
not.
(defun my-find-title-element-map (title)
(interactive "sTitle: ")
(let ((files (org-agenda-files))
found)
(dolist (f files)
(with-current-buffer (org-get-agenda-file-buffer f)
(org-element-map (org-element-parse-buffer 'headline)
'headline
(lambda (hl)
(when (string= title (org-element-property :title hl))
(push (move-marker (make-marker)
(org-element-property :begin hl))
found))))))
found))
(defun my-find-title-entries-map (title)
(interactive "sTitle: ")
(let (found)
(org-map-entries
(lambda ()
(when (string= title (org-get-heading t t))
(push (move-marker (make-marker)
(line-beginning-position))
found)))
nil 'agenda)
found))
(benchmark-run 100 (my-find-title-element-map "Unique Heading Text"))
=> (164.576821235 142 23.892782392000186)
(benchmark-run 100 (my-find-title-entries-map "Unique Heading Text"))
=> (58.111630133 36 6.047778745000016)
This isn't quite an idle inquiry: part of Gnorb does exactly this
(scanning all agenda files for headings with a certain property value).
While using `org-map-entries' in an interactive function is currently
good enough, I'd eventually like to have it happen more often, and
quickly, in non-interactive functions. I was considering making my own
mini-cache, but if `org-element-map' can do it, and do it quickly
(presumably using the cache), I'd much prefer using that.
Thanks,
Eric
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-06-01 4:05 ` Eric Abrahamsen
@ 2014-06-03 9:05 ` Thorsten Jolitz
2014-06-03 9:51 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Thorsten Jolitz @ 2014-06-03 9:05 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Thorsten Jolitz <tjolitz@gmail.com> writes:
>
>> Chris Poole <lists@chrispoole.com> writes:
>>
>>> Eric Abrahamsen:
>>>> the `org-map-entries' function can be given a scope of 'agenda
>>>
>>> That worked perfectly, thanks. Here's what I ended up with:
>>>
>>> (org-map-entries (lambda ()
>>> (when (equal title (org-get-heading t t))
>>> (org-entry-put (point) "TODO" "DONE")))
>>> tag 'agenda)
>>
>> As much as I like the powerful `org-map-entries', I wonder if it will
>> coexist with `org-element-map' in the future, since it does not use the
>> new parser.
>>
>> Whats the recommendation here? Should one rather use
>>
>> ,-----------------------------------------------------------
>> | (org-element-map (org-element-parse-buffer) 'headline (lambda () ...))
>> `-----------------------------------------------------------
>>
>> nowadays, or do both functions serve different purposes, or is it just a
>> matter of taste?
>
> Interesting! I wasn't even aware of org-element-map, thanks for that.
> Obviously I don't know the answer to your question, but they do seem to
> do very similar things. On the other hand, `org-element-map' won't do
> multiple files, and if you want to restrict to certain elements you have
> to do the matching logic yourself (as opposed to `org-map-entries's
> agenda-style search string).
>
> I'd be curious, too, to hear if `org-map-entries' is going to get EOL'd
> at some point. I suppose it's safe so long as `org-scan-tags' remains
> the heart of the agenda process.
>
> Here's my stab at two roughly equivalent functions, one using
> org-element, the other older function. Just for the hell of it I tried
> using "benchmark" to profile them, but have no idea if the results mean
> much of anything. Most importantly, I don't really know if
> `org-element-parse-buffer' ends up using the cache or not -- I assume
> not.
>
> (defun my-find-title-element-map (title)
> (interactive "sTitle: ")
> (let ((files (org-agenda-files))
> found)
> (dolist (f files)
> (with-current-buffer (org-get-agenda-file-buffer f)
> (org-element-map (org-element-parse-buffer 'headline)
> 'headline
> (lambda (hl)
> (when (string= title (org-element-property :title hl))
> (push (move-marker (make-marker)
> (org-element-property :begin hl))
> found))))))
> found))
>
>
> (defun my-find-title-entries-map (title)
> (interactive "sTitle: ")
> (let (found)
> (org-map-entries
> (lambda ()
> (when (string= title (org-get-heading t t))
> (push (move-marker (make-marker)
> (line-beginning-position))
> found)))
> nil 'agenda)
> found))
>
> (benchmark-run 100 (my-find-title-element-map "Unique Heading Text"))
> => (164.576821235 142 23.892782392000186)
>
> (benchmark-run 100 (my-find-title-entries-map "Unique Heading Text"))
> => (58.111630133 36 6.047778745000016)
This is interesting too - and a bit surprising. On my machine, the
org-element based function takes almost 4 times as long as the
org-map-entries based function:
#+BEGIN_SRC emacs-lisp
(defun my-find-title-element-map (title)
(interactive "sTitle: ")
(let ((files (org-agenda-files))
found)
(dolist (f files)
(with-current-buffer (org-get-agenda-file-buffer f)
(org-element-map (org-element-parse-buffer 'headline)
'headline
(lambda (hl)
(when (string= title (org-element-property :title hl))
(push (move-marker (make-marker)
(org-element-property :begin hl))
found))))))
found))
#+END_SRC
#+results:
: my-find-title-element-map
#+BEGIN_SRC emacs-lisp
(defun my-find-title-entries-map (title)
(interactive "sTitle: ")
(let (found)
(org-map-entries
(lambda ()
(when (string= title (org-get-heading t t))
(push (move-marker (make-marker)
(line-beginning-position))
found)))
nil 'agenda)
found))
#+END_SRC
#+results:
: my-find-title-entries-map
#+BEGIN_SRC emacs-lisp :results raw
(benchmark-run 30 (my-find-title-element-map "Unique Heading Text"))
#+END_SRC
#+results:
(160.439753043 735 76.66140414599985)
# => (164.576821235 142 23.892782392000186)
#+BEGIN_SRC emacs-lisp :results raw
(benchmark-run 30 (my-find-title-entries-map "Unique Heading Text"))
#+END_SRC
#+results:
(37.973595622000005 123 12.137436705999733)
# => (58.111630133 36 6.047778745000016)
--
cheers,
Thorsten
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-06-03 9:05 ` Thorsten Jolitz
@ 2014-06-03 9:51 ` Eric Abrahamsen
2014-06-03 20:21 ` Nicolas Goaziou
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2014-06-03 9:51 UTC (permalink / raw)
To: emacs-orgmode; +Cc: Nicolas Goaziou
Thorsten Jolitz <tjolitz@gmail.com> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> Thorsten Jolitz <tjolitz@gmail.com> writes:
>>
>>> Chris Poole <lists@chrispoole.com> writes:
>>>
>>>> Eric Abrahamsen:
>>>>> the `org-map-entries' function can be given a scope of 'agenda
>>>>
>>>> That worked perfectly, thanks. Here's what I ended up with:
>>>>
>>>> (org-map-entries (lambda ()
>>>> (when (equal title (org-get-heading t t))
>>>> (org-entry-put (point) "TODO" "DONE")))
>>>> tag 'agenda)
>>>
>>> As much as I like the powerful `org-map-entries', I wonder if it will
>>> coexist with `org-element-map' in the future, since it does not use the
>>> new parser.
>>>
>>> Whats the recommendation here? Should one rather use
>>>
>>> ,-----------------------------------------------------------
>>> | (org-element-map (org-element-parse-buffer) 'headline (lambda () ...))
>>> `-----------------------------------------------------------
>>>
>>> nowadays, or do both functions serve different purposes, or is it just a
>>> matter of taste?
>>
>> Interesting! I wasn't even aware of org-element-map, thanks for that.
>> Obviously I don't know the answer to your question, but they do seem to
>> do very similar things. On the other hand, `org-element-map' won't do
>> multiple files, and if you want to restrict to certain elements you have
>> to do the matching logic yourself (as opposed to `org-map-entries's
>> agenda-style search string).
>>
>> I'd be curious, too, to hear if `org-map-entries' is going to get EOL'd
>> at some point. I suppose it's safe so long as `org-scan-tags' remains
>> the heart of the agenda process.
>>
>> Here's my stab at two roughly equivalent functions, one using
>> org-element, the other older function. Just for the hell of it I tried
>> using "benchmark" to profile them, but have no idea if the results mean
>> much of anything. Most importantly, I don't really know if
>> `org-element-parse-buffer' ends up using the cache or not -- I assume
>> not.
> This is interesting too - and a bit surprising. On my machine, the
> org-element based function takes almost 4 times as long as the
> org-map-entries based function:
I guess it shouldn't be too surprising -- the org element stuff is
completely parsing the entire buffer on every pass. The other function
probably boils down to passing a few targeted regexps over the buffer.
I've sneakily cc'd Nicolas to see what he thinks. My guess is we could
replace the call to org-element-parse-buffer with something that
creates/accesses the cached version of the parse tree, and things would
go much more swiftly.
E
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-06-03 9:51 ` Eric Abrahamsen
@ 2014-06-03 20:21 ` Nicolas Goaziou
2014-06-04 1:36 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2014-06-03 20:21 UTC (permalink / raw)
To: Eric Abrahamsen; +Cc: emacs-orgmode
Hello,
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> I guess it shouldn't be too surprising -- the org element stuff is
> completely parsing the entire buffer on every pass. The other function
> probably boils down to passing a few targeted regexps over the buffer.
> I've sneakily cc'd Nicolas to see what he thinks. My guess is we could
> replace the call to org-element-parse-buffer with something that
> creates/accesses the cached version of the parse tree, and things would
> go much more swiftly.
I didn't look closely into the issue, but I think the main reason is
that Element parses headlines thoroughly, including all properties,
scheduled keywords, which is not, by default, the case for
`org-map-entries'.
For most use-cases, you don't need the parser for headlines, as their
grammar is context free. IOW, `org-element-parse-buffer' doesn't predate
`org-map-entries'.
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-06-03 20:21 ` Nicolas Goaziou
@ 2014-06-04 1:36 ` Eric Abrahamsen
2014-06-04 11:27 ` Thorsten Jolitz
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2014-06-04 1:36 UTC (permalink / raw)
To: emacs-orgmode
Nicolas Goaziou <n.goaziou@gmail.com> writes:
> Hello,
>
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> I guess it shouldn't be too surprising -- the org element stuff is
>> completely parsing the entire buffer on every pass. The other function
>> probably boils down to passing a few targeted regexps over the buffer.
>> I've sneakily cc'd Nicolas to see what he thinks. My guess is we could
>> replace the call to org-element-parse-buffer with something that
>> creates/accesses the cached version of the parse tree, and things would
>> go much more swiftly.
>
> I didn't look closely into the issue, but I think the main reason is
> that Element parses headlines thoroughly, including all properties,
> scheduled keywords, which is not, by default, the case for
> `org-map-entries'.
>
> For most use-cases, you don't need the parser for headlines, as their
> grammar is context free. IOW, `org-element-parse-buffer' doesn't predate
> `org-map-entries'.
Interesting, thanks! I think at first we were unsure if org-map-entries
was going to stay around in the long term, but it sounds like it's not
going anywhere.
E
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to find the headline matching a string
2014-06-04 1:36 ` Eric Abrahamsen
@ 2014-06-04 11:27 ` Thorsten Jolitz
0 siblings, 0 replies; 13+ messages in thread
From: Thorsten Jolitz @ 2014-06-04 11:27 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Nicolas Goaziou <n.goaziou@gmail.com> writes:
>
>> Hello,
>>
>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>
>>> I guess it shouldn't be too surprising -- the org element stuff is
>>> completely parsing the entire buffer on every pass. The other function
>>> probably boils down to passing a few targeted regexps over the buffer.
>>> I've sneakily cc'd Nicolas to see what he thinks. My guess is we could
>>> replace the call to org-element-parse-buffer with something that
>>> creates/accesses the cached version of the parse tree, and things would
>>> go much more swiftly.
>>
>> I didn't look closely into the issue, but I think the main reason is
>> that Element parses headlines thoroughly, including all properties,
>> scheduled keywords, which is not, by default, the case for
>> `org-map-entries'.
>>
>> For most use-cases, you don't need the parser for headlines, as their
>> grammar is context free. IOW, `org-element-parse-buffer' doesn't predate
>> `org-map-entries'.
>
> Interesting, thanks! I think at first we were unsure if org-map-entries
> was going to stay around in the long term, but it sounds like it's not
> going anywhere.
Yes, thanks for the feedback, org-map-entries is very useful and
powerful but I wasn't sure if its still a "first-class member" of
Org-mode or already a bit deprecated. Nice to hear that it is going to
stay.
--
cheers,
Thorsten
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-06-04 11:27 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-31 15:07 How to find the headline matching a string Chris Poole
2014-05-31 15:27 ` Eric Abrahamsen
2014-05-31 16:51 ` Chris Poole
2014-05-31 17:00 ` Igor Sosa Mayor
2014-05-31 17:31 ` Chris Poole
2014-05-31 17:53 ` Igor Sosa Mayor
2014-05-31 20:14 ` Thorsten Jolitz
2014-06-01 4:05 ` Eric Abrahamsen
2014-06-03 9:05 ` Thorsten Jolitz
2014-06-03 9:51 ` Eric Abrahamsen
2014-06-03 20:21 ` Nicolas Goaziou
2014-06-04 1:36 ` Eric Abrahamsen
2014-06-04 11:27 ` Thorsten Jolitz
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).