General operators for property searches.

We have now numerical comparisons, and we can do < and > for strings.
This commit is contained in:
Carsten Dominik 2008-04-23 07:48:22 +02:00
parent 931aa5b895
commit d38aab0443
5 changed files with 97 additions and 91 deletions

View File

@ -1,3 +1,8 @@
2008-04-23 Carsten Dominik <dominik@science.uva.nl>
* lisp/org.el (org-op-to-function, org<>, org-string<=)
(org-string>=, org-string<>): New functions.
2008-04-21 Carsten Dominik <dominik@science.uva.nl>
* lisp/org-remember.el (org-get-x-clipboard): Protect the call to

View File

@ -61,31 +61,33 @@ CP = cp -p
# The following variables need to be defined by the maintainer
LISPF = org.el \
org-agenda.el \
org-archive.el \
org-bbdb.el \
org-bibtex.el \
org-clock.el \
org-colview.el \
org-colview-xemacs.el \
org-compat.el \
org-macs.el \
org-clock.el \
org-table.el \
org-exp.el \
org-faces.el \
org-remember.el \
org-agenda.el \
org-publish.el \
org-mouse.el \
org-export-latex.el \
org-bbdb.el \
org-bibtex.el \
org-faces.el \
org-gnus.el \
org-info.el \
org-infojs.el \
org-irc.el \
org-mac-message.el \
org-macs.el \
org-mew.el \
org-mhe.el \
org-mouse.el \
org-publish.el \
org-remember.el \
org-rmail.el \
org-table.el \
org-vm.el \
org-wl.el
LISPFILES0 = $(LISPF:%=lisp/%)
LISPFILES = $(LISPFILES0) lisp/org-install.el
ELCFILES0 = $(LISPFILES0:.el=.elc)
@ -279,6 +281,7 @@ lisp/org-bbdb.elc: lisp/org.elc
lisp/org-bibtex.elc: lisp/org.elc
lisp/org-clock.elc: lisp/org.elc
lisp/org-colview.elc: lisp/org.elc
lisp/org-colview-xemacs.elc: lisp/org.elc
lisp/org-compat.elc:
lisp/org-exp.elc: lisp/org.elc lisp/org-agenda.elc
lisp/org-export-latex.elc: lisp/org.elc lisp/org-exp.elc

View File

@ -3654,23 +3654,30 @@ CLOCKSUM @r{The sum of CLOCK intervals in the subtree. @code{org-clock-sum}
@cindex properties, searching
@cindex searching, of properties
To create sparse trees and special lists with selection based on
properties, the same commands are used as for tag searches (@pxref{Tag
searches}), and the same logic applies. For example, a search string
To create sparse trees and special lists with selection based on properties,
the same commands are used as for tag searches (@pxref{Tag searches}), and
the same logic applies. For example, here is a search string:
@example
+work-boss+PRIORITY="A"+Coffee="unlimited"+Effort=""+With=@{Sarah\|Denny@}
+work-boss+PRIORITY="A"+Coffee="unlimited"+Effort<2+With=@{Sarah\|Denny@}
@end example
@noindent
finds entries tagged @samp{:work:} but not @samp{:boss:}, which
also have a priority value @samp{A}, a @samp{:Coffee:} property with the
value @samp{unlimited}, an @samp{Effort} property that is undefined or
empty, and a @samp{:With:} property that is matched by
the regular expression @samp{Sarah\|Denny}.
If the comparison value is a plain number, a numerical comparison is done,
and the allowed operators are @samp{<}, @samp{=}, @samp{>}, @samp{<=},
@samp{>=}, and @samp{<>}. If the comparison value is enclosed in double
quotes, a string comparison is done, and the same operators are allowed. If
the comparison value is enclosed in curly braces, a regexp match is
performed. So the search string in the example finds entries tagged
@samp{:work:} but not @samp{:boss:}, which also have a priority value
@samp{A}, a @samp{:Coffee:} property with the value @samp{unlimited}, an
@samp{Effort} property that is numerically smaller than 2, and a
@samp{:With:} property that is matched by the regular expression
@samp{Sarah\|Denny}.
You can configure Org mode to use property inheritance during a search,
see @ref{Property inheritance} for details.
You can configure Org mode to use property inheritance during a search, but
beware that this can slow down searches considerably. See @ref{Property
inheritance} for details.
There is also a special command for creating sparse trees based on a
single property:
@ -4241,11 +4248,12 @@ M-S-@key{right}/@key{left} @r{One month forward/backward.}
@key{RET} @r{Choose date in calendar.}
@end example
The actions of the date/time prompt may seem complex, but I assure you
they will grow on you. To help you understand what is going on, the
current interpretation of your input will be displayed live in the
minibuffer@footnote{If you find this distracting, turn the display of
with @code{org-read-date-display-live}.}.
The actions of the date/time prompt may seem complex, but I assure you they
will grow on you, and you will start getting annoyed by pretty much any other
way of entering a date/time out there. To help you understand what is going
on, the current interpretation of your input will be displayed live in the
minibuffer@footnote{If you find this distracting, turn the display of with
@code{org-read-date-display-live}.}.
@node Custom time format, , The date/time prompt, Creating timestamps
@subsection Custom time format
@ -4883,7 +4891,7 @@ for details.
@item C-u C-c C-w
Use the refile interface to jump to a heading.
@kindex C-u C-u C-c C-w
@item C- C-u C-c C-w
@item C-u C-u C-c C-w
Jump to the location where @code{org-refile} last moved a tree to.
@end table
@ -6469,7 +6477,7 @@ environments and math templates. Inside Org mode, you can make use of
some of the features of CDLaTeX mode. You need to install
@file{cdlatex.el} and @file{texmathp.el} (the latter comes also with
AUCTeX) from @url{http://www.astro.uva.nl/~dominik/Tools/cdlatex}.
Don't turn CDLaTeX mode itself under Org mode, but use the light
Don't use CDLaTeX mode itself under Org mode, but use the light
version @code{org-cdlatex-mode} that comes as part of Org mode. Turn it
on for the current buffer with @code{M-x org-cdlatex-mode}, or for all
Org files with
@ -6829,16 +6837,15 @@ view: @r{Initial view when website is first shown. Possible values are}
showall @r{Folding interface, all headlines and text visible.}
sdepth: @r{Maximum headline level that will still become an independent}
@r{section for info and folding modes. The default is taken from}
@r{@code{org-headline-levels} (= the @code{H} @code{#+OPTIONS} switch).}
@r{@code{org-headline-levels} (= the @code{H} switch in @code{#+OPTIONS}).}
@r{If this is smaller than in @code{org-headline-levels}, each}
@r{info/folding section can still contain children headlines.}
@r{Default is @code{org-headline-levels} (= the @code{H} @code{#+OPTIONS} switch).}
toc: @r{Should the table of content @emph{initially} be visible?}
@r{Even when @code{nil}, you can always get to the toc with @kbd{i}.}
tdepth: @r{The depth of the table of contents. The defaults are taken from}
@r{the variables @code{org-headline-levels} and @code{org-export-with-toc}.}
ltoc: @r{Should there be short contents (children) in each section?}
mouse: @r{Headings are highlighted when the mouse is over themq. Should be}
mouse: @r{Headings are highlighted when the mouse is over them. Should be}
@r{@samp{underline} (default) or a background color like @samp{#cccccc}.}
buttons: @r{Should view-toggle buttons be everywhere? When @code{nil} (the}
@r{default), only one such button will be present.}
@ -8247,51 +8254,11 @@ Org.
@section Third-party extensions for Org
@cindex extension, third-party
The following extensions for Org have been written by other people:
@table @asis
@cindex @file{org-publish.el}
@item @file{org-publish.el} by David O'Toole
This package provides facilities for publishing related sets of Org
files together with linked files like images as web pages. It is
highly configurable and can be used for other publishing purposes as
well. As of Org version 4.30, @file{org-publish.el} is part of the
Org distribution. It is not yet part of Emacs, however, a delay
caused by the preparations for the 22.1 release. In the mean time,
@file{org-publish.el} can be downloaded from David's site:
@url{http://dto.freeshell.org/e/org-publish.el}.
@cindex @file{org-mouse.el}
@item @file{org-mouse.el} by Piotr Zielinski
This package implements extended mouse functionality for Org. It
allows you to cycle visibility and to edit the document structure with
the mouse. Best of all, it provides a context-sensitive menu on
@key{mouse-3} that changes depending on the context of a mouse-click.
As of Org version 4.53, @file{org-mouse.el} is part of the
Org distribution. It is not yet part of Emacs, however, a delay
caused by the preparations for the 22.1 release. In the mean time,
@file{org-mouse.el} can be downloaded from Piotr's site:
@url{http://www.cl.cam.ac.uk/~pz215/files/org-mouse.el}.
@cindex @file{org-blog.el}
@item @file{org-blog.el} by David O'Toole
A blogging plug-in for @file{org-publish.el}.@*
@url{http://dto.freeshell.org/notebook/OrgMode.html}.
@cindex @file{blorg.el}
@item @file{blorg.el} by Bastien Guerry
Publish Org files as
blogs. @url{http://www.cognition.ens.fr/~guerry/blorg.html}.
@cindex @file{org2rem.el}
@item @file{org2rem.el} by Bastien Guerry
Translates Org files into something readable by
Remind. @url{http://www.cognition.ens.fr/~guerry/u/org2rem.el}.
@item @file{org-toc.el} by Bastien Guerry
Produces a simple table of contents of an Org file, for easy
navigation. @url{http://www.cognition.ens.fr/~guerry/u/org-registry.el}.
@item @file{org-registry.el} by Bastien Guerry
Find which Org-file link to a certain document.
@url{http://www.cognition.ens.fr/~guerry/u/org2rem.el}.
@end table
@page
There are lots of extensions that have been written by other people. Most of
them have either been integrated into Org by now, or they can be found in the
Org distribution, in the @file{contrib} directory. The list has gotten too
long to cover in any detail here, but there is a seaparate manual for these
extensions.
@node Adding hyperlink types, Tables in arbitrary syntax, Extensions, Extensions and Hacking
@section Adding hyperlink types
@ -8774,7 +8741,8 @@ The corresponding block writer function could look like this:
If you want to make sure that all dynamic blocks are always up-to-date,
you could add the function @code{org-update-all-dblocks} to a hook, for
example @code{before-save-hook}. @code{org-update-all-dblocks} is
written in a way that is does nothing in buffers that are not in Org.
written in a way that is does nothing in buffers that are not in
@code{org-mode}.
@node Special agenda views, Using the property API, Dynamic blocks, Extensions and Hacking
@section Special agenda views
@ -8820,6 +8788,12 @@ like this:
Note that this also binds @code{org-agenda-overriding-header} to get a
meaningful header in the agenda view.
A general way to create custom searches is to base them on a search for
entries with a certain level limit. If you want to study all entries with
your custom search function, simply do a search for @samp{LEVEL>0}, and then
use @code{org-agenda-skip-function} to select the entries you really want to
have.
You may also put a Lisp form into @code{org-agenda-skip-function}. In
particular, you may use the functions @code{org-agenda-skip-entry-if}
and @code{org-agenda-skip-subtree-if} in this form, for example:
@ -8852,7 +8826,6 @@ like this, even without defining a special function:
(org-agenda-overriding-header "Projects waiting for something: "))))
@end lisp
@node Using the property API, , Special agenda views, Extensions and Hacking
@section Using the property API
@cindex API, for properties
@ -8936,7 +8909,7 @@ incorporate project planning functionality directly into a notes file.
A special thanks goes to @i{Bastien Guerry} who has not only writen a large
number of extensions to Org (most of them integrated into the core by now),
but has also helep the development and maintenance of Org so much that e
but has also helped the development and maintenance of Org so much that he
should be considered co-author of this package.
Since the first release, literally thousands of emails to me or on

View File

@ -1767,7 +1767,7 @@ When NAMED is non-nil, look for a named equation."
(when (looking-at "\\([ \t]*\n\\)*#\\+TBLFM: *\\(.*\\)")
(setq strings (org-split-string (match-string 2) " *:: *"))
(while (setq string (pop strings))
(when (string-match "\\(@[0-9]+\\$[0-9]+\\|\\$\\([a-zA-Z0-9]+\\)\\) *= *\\(.*[^ \t]\\)" string)
(when (string-match "\\`\\(@[0-9]+\\$[0-9]+\\|\\$\\([a-zA-Z0-9]+\\)\\) *= *\\(.*[^ \t]\\)" string)
(setq scol (if (match-end 2)
(match-string 2 string)
(match-string 1 string))

View File

@ -8764,10 +8764,11 @@ also TODO lines."
;; Parse the string and create a lisp form
(let ((match0 match)
(re (org-re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL=\\([0-9]+\\)\\|\\([[:alnum:]_]+\\)=\\({[^}]+}\\|\"[^\"]*\"\\)\\|[[:alnum:]_@]+\\)"))
(re (org-re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL\\([<=>]\\{1,2\\}\\)\\([0-9]+\\)\\|\\([[:alnum:]_]+\\)\\([<>=]\\{1,2\\}\\)\\({[^}]+}\\|\"[^\"]*\"\\|-?[.0-9]+\\(?:[eE][-+]?[0-9]+\\)?\\)\\|[[:alnum:]_@]+\\)"))
minus tag mm
tagsmatch todomatch tagsmatcher todomatcher kwd matcher
orterms term orlist re-p level-p prop-p pn pv cat-p gv)
orterms term orlist re-p str-p level-p level-op
prop-p pn pv po cat-p gv)
(if (string-match "/+" match)
;; match contains also a todo-matching request
(progn
@ -8792,24 +8793,32 @@ also TODO lines."
(equal (match-string 1 term) "-"))
tag (match-string 2 term)
re-p (equal (string-to-char tag) ?{)
level-p (match-end 3)
prop-p (match-end 4)
level-p (match-end 4)
prop-p (match-end 5)
mm (cond
(re-p `(org-match-any-p ,(substring tag 1 -1) tags-list))
(level-p `(= level ,(string-to-number
(match-string 3 term))))
(level-p
(setq level-op (org-op-to-function (match-string 3 term)))
`(,level-op level ,(string-to-number
(match-string 4 term))))
(prop-p
(setq pn (match-string 4 term)
pv (match-string 5 term)
(setq pn (match-string 5 term)
po (match-string 6 term)
pv (match-string 7 term)
cat-p (equal pn "CATEGORY")
re-p (equal (string-to-char pv) ?{)
pv (substring pv 1 -1))
str-p (equal (string-to-char pv) ?\")
pv (if (or re-p str-p) (substring pv 1 -1) pv))
(setq po (org-op-to-function po str-p))
(if (equal pn "CATEGORY")
(setq gv '(get-text-property (point) 'org-category))
(setq gv `(org-cached-entry-get nil ,pn)))
(if re-p
`(string-match ,pv (or ,gv ""))
`(equal ,pv (or ,gv ""))))
(if str-p
`(,po (or ,gv "") ,pv)
`(,po (string-to-number (or ,gv ""))
,(string-to-number pv) ))))
(t `(member ,(downcase tag) tags-list)))
mm (if minus (list 'not mm) mm)
term (substring term (match-end 0)))
@ -8822,7 +8831,7 @@ also TODO lines."
(setq tagsmatcher (if (> (length orlist) 1) (cons 'or orlist) (car orlist)))
(setq tagsmatcher
(list 'progn '(setq org-cached-props nil) tagsmatcher)))
(debug)
;; Make the todo matcher
(if (or (not todomatch) (not (string-match "\\S-" todomatch)))
(setq todomatcher t)
@ -8853,6 +8862,22 @@ also TODO lines."
tagsmatcher))
(cons match0 matcher)))
(defun org-op-to-function (op &optional stringp)
(setq op
(cond
((equal op "<" ) '(< string< ))
((equal op ">" ) '(> string> ))
((member op '("<=" "=<")) '(<= org-string<= ))
((member op '(">=" "=>")) '(>= org-string>= ))
((member op '("=" "==")) '(= string= ))
((member op '("<>" "!=")) '(org<> org-string<> ))))
(nth (if stringp 1 0) op))
(defun org<> (a b) (not (= a b)))
(defun org-string<= (a b) (or (string= a b) (string< a b)))
(defun org-string>= (a b) (or (string= a b) (string> a b)))
(defun org-string<> (a b) (not (string= a b)))
(defun org-match-any-p (re list)
"Does re match any element of list?"
(setq list (mapcar (lambda (x) (string-match re x)) list))