emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [hack/extension] org-mode/emacs regexp
@ 2009-11-16 18:10 Marcelo de Moraes Serpa
  2009-11-16 19:45 ` Marcelo de Moraes Serpa
  0 siblings, 1 reply; 3+ messages in thread
From: Marcelo de Moraes Serpa @ 2009-11-16 18:10 UTC (permalink / raw)
  To: Org Mode


[-- Attachment #1.1: Type: text/plain, Size: 3386 bytes --]

Hello,

I started writing an extension to org that actually applies a custom face to
an item tagges as CATEGORY or PROJECT. The thing is I'm really having a hard
time understanding the regexp. The code is adapted from the
org-action-verb.el by Tim O'Calaghan, basically using the same structure
since my elisp knowledge is very basic. I have managed to get it to work to
a basic level, but it is applying the face to the whole tree instead of
applying to only one item.

(defface org-gtd-default-category-face
  '((((class color) (background light)) (:foreground "purple" :bold t
:underline t))
    (((class color) (background dark)) (:foreground "purple" :bold t
:underline t))
    (t (:bold t :underline t)))
  "Used by org-color-by-tag for items tagged with :CATEGORY:")

(defface org-gtd-default-project-face
  '((((class color) (background light)) (:foreground "purple" :bold t
:underline t))
    (((class color) (background dark)) (:foreground "purple" :bold t
:underline t))
    (t (:bold t :underline t)))
  "Used by org-color-by-tag for items tagged with :PROJECT:")

(defvar org-gtd-tags '("PROJECT" "CATEGORY"))

(defun org-font-lock-add-tag-faces (limit)
  "Add the faces to corresponding items depending on the TAG."
  (let (rtn a)
    ;; check variable is set, and buffer left to search
    (when (and (not rtn) org-gtd-tags)
      ;; for each todo/action verb set
      (dolist (tag org-gtd-tags)
        ;; build regexps
        (let ((tag-keywords-regexp

                       (regexp-opt (cdr tag) 'word)))

          ;; while we can find a todo keyword
          (while (re-search-forward ":PROJECT:" limit t)
            ;; check for action verb


                   ;; apply new overlay
                  (let ((overlay (make-overlay (match-beginning 1)
(match-end 1) nil t nil)))
                    (overlay-put overlay 'face
'org-gtd-default-project-face)
                    ;;(overlay-put overlay 'mouse-face mouse-face)
                    (overlay-put overlay 'org-action-overlay t)
                    (overlay-put overlay 'evaporate t)
                    (overlay-put overlay 'help-echo "mouse-2: correct word
at point")
                    overlay)


            ;; reset search point?
            (backward-char 1)))))
    rtn))

(org-font-lock-add-tag-faces 10)

(defun org-mode-color-by-tag-hook ()
  "Initalise org-color-by-tag."
  (interactive)
  (font-lock-add-keywords nil '((org-font-lock-add-tag-faces)))
  )

;; Turn on action verb font locking.
(add-hook 'org-mode-hook 'org-mode-color-by-tag-hook)

As you can see, I'm in the debug phase, and I'm not even using the list of
strings (PROJECT CATEGORY) I've created. I'm just trying to search for
occurrences of the PROJECT tag and trying to apply the face. I've removed
the regexp string that Tim used, which were:

"^\\*+[     ]+"

Was used here:
        (let ((todo-keywords-regexp
               (concat "^\\*+[     ]+"
                       (regexp-opt (car todo) 'words)))
              (todo-action-verbs-regexp
               (concat "[     ]+" (regexp-opt (cdr todo) 'words))))


And:  "[     ]+\\(\\<\\w\\w+\\>\\)"

Used in: (looking-at "[     ]+\\(\\<\\w\\w+\\>\\)")

What I want to do is: Search for items tagged as PROJECT or CATEGORY and
apply the corresponding face to them.

If someone could explain me the role of  "[    ]", and w, I would be
grateful :)

Thanks,

Marcelo.

[-- Attachment #1.2: Type: text/html, Size: 4041 bytes --]

[-- Attachment #2: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [hack/extension] org-mode/emacs regexp
  2009-11-16 18:10 [hack/extension] org-mode/emacs regexp Marcelo de Moraes Serpa
@ 2009-11-16 19:45 ` Marcelo de Moraes Serpa
  2009-11-17 11:49   ` Tim O'Callaghan
  0 siblings, 1 reply; 3+ messages in thread
From: Marcelo de Moraes Serpa @ 2009-11-16 19:45 UTC (permalink / raw)
  To: Org Mode


[-- Attachment #1.1: Type: text/plain, Size: 4132 bytes --]

Ok, I'm sorry, I actually had to research a little bit more before posting
:)

Well, what I need to know now is how to make the overlay work. The code to
match is working, but I'm receiving the following error:

Error during redisplay: (wrong-number-of-arguments match-beginning 0)

Here's the full code: http://pastie.org/701448

(Thanks to Tim O'Calaghan for the original contribution)

Marcelo.

Also, how can I debug it? I tried debug-on-entry but it is not working :S


On Mon, Nov 16, 2009 at 12:10 PM, Marcelo de Moraes Serpa <
celoserpa@gmail.com> wrote:

> Hello,
>
> I started writing an extension to org that actually applies a custom face
> to an item tagges as CATEGORY or PROJECT. The thing is I'm really having a
> hard time understanding the regexp. The code is adapted from the
> org-action-verb.el by Tim O'Calaghan, basically using the same structure
> since my elisp knowledge is very basic. I have managed to get it to work to
> a basic level, but it is applying the face to the whole tree instead of
> applying to only one item.
>
> (defface org-gtd-default-category-face
>   '((((class color) (background light)) (:foreground "purple" :bold t
> :underline t))
>     (((class color) (background dark)) (:foreground "purple" :bold t
> :underline t))
>     (t (:bold t :underline t)))
>   "Used by org-color-by-tag for items tagged with :CATEGORY:")
>
> (defface org-gtd-default-project-face
>   '((((class color) (background light)) (:foreground "purple" :bold t
> :underline t))
>     (((class color) (background dark)) (:foreground "purple" :bold t
> :underline t))
>     (t (:bold t :underline t)))
>   "Used by org-color-by-tag for items tagged with :PROJECT:")
>
> (defvar org-gtd-tags '("PROJECT" "CATEGORY"))
>
> (defun org-font-lock-add-tag-faces (limit)
>   "Add the faces to corresponding items depending on the TAG."
>   (let (rtn a)
>     ;; check variable is set, and buffer left to search
>     (when (and (not rtn) org-gtd-tags)
>       ;; for each todo/action verb set
>       (dolist (tag org-gtd-tags)
>         ;; build regexps
>         (let ((tag-keywords-regexp
>
>                        (regexp-opt (cdr tag) 'word)))
>
>           ;; while we can find a todo keyword
>           (while (re-search-forward ":PROJECT:" limit t)
>             ;; check for action verb
>
>
>                    ;; apply new overlay
>                   (let ((overlay (make-overlay (match-beginning 1)
> (match-end 1) nil t nil)))
>                     (overlay-put overlay 'face
> 'org-gtd-default-project-face)
>                     ;;(overlay-put overlay 'mouse-face mouse-face)
>                     (overlay-put overlay 'org-action-overlay t)
>                     (overlay-put overlay 'evaporate t)
>                     (overlay-put overlay 'help-echo "mouse-2: correct word
> at point")
>                     overlay)
>
>
>             ;; reset search point?
>             (backward-char 1)))))
>     rtn))
>
> (org-font-lock-add-tag-faces 10)
>
> (defun org-mode-color-by-tag-hook ()
>   "Initalise org-color-by-tag."
>   (interactive)
>   (font-lock-add-keywords nil '((org-font-lock-add-tag-faces)))
>   )
>
> ;; Turn on action verb font locking.
> (add-hook 'org-mode-hook 'org-mode-color-by-tag-hook)
>
> As you can see, I'm in the debug phase, and I'm not even using the list of
> strings (PROJECT CATEGORY) I've created. I'm just trying to search for
> occurrences of the PROJECT tag and trying to apply the face. I've removed
> the regexp string that Tim used, which were:
>
> "^\\*+[     ]+"
>
> Was used here:
>         (let ((todo-keywords-regexp
>                (concat "^\\*+[     ]+"
>                        (regexp-opt (car todo) 'words)))
>               (todo-action-verbs-regexp
>                (concat "[     ]+" (regexp-opt (cdr todo) 'words))))
>
>
> And:  "[     ]+\\(\\<\\w\\w+\\>\\)"
>
> Used in: (looking-at "[     ]+\\(\\<\\w\\w+\\>\\)")
>
> What I want to do is: Search for items tagged as PROJECT or CATEGORY and
> apply the corresponding face to them.
>
> If someone could explain me the role of  "[    ]", and w, I would be
> grateful :)
>
> Thanks,
>
> Marcelo.
>
>

[-- Attachment #1.2: Type: text/html, Size: 5021 bytes --]

[-- Attachment #2: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Re: [hack/extension] org-mode/emacs regexp
  2009-11-16 19:45 ` Marcelo de Moraes Serpa
@ 2009-11-17 11:49   ` Tim O'Callaghan
  0 siblings, 0 replies; 3+ messages in thread
From: Tim O'Callaghan @ 2009-11-17 11:49 UTC (permalink / raw)
  To: Marcelo de Moraes Serpa; +Cc: Org Mode

Hi Marcelo.

Thanks for the thumbs up, its nice when that happens.

So, to your questions - The answers are a bit long, and I'm cc'ing to
the list so that others wanting org-action-verb like stuff can
understand what it does, and hack it for their needs.

* Debugging.

 I've been coding elisp on and off for years, but I'm no elisp
 expert. I put org-action-verb together after allot of RTFM, and
 looking at other code.

 I debugged it using these methods:

 + (message).  To get an idea about what is going on without having
   to use the debugger, the message function is handy. It will print
   whatever to the *messages* buffer. Primitive, but worked for me at
   the time.

 + (regexp-builder). For regular expression work there is the built
   in regular expression builder (M-x regexp-builder) or John
   Wiegley's excellent (M-x regex-tool), which i only just remembered
   I have.

 + (eval-region). I have it mapped to a key, but (M-x eval-region) is
   great for changing small parts of the compiled elisp, variables or
   whatever.

 + (info-lookup-symbol).  When poking about in the innards of
   (X)Emacs, it is always a good idea to have info-lookup-symbol
   mapped to a key somewhere. I have it mapped to f1.

   (define-key global-map [f1] 'info-lookup-symbol)

   It will bring up a buffer showing what the symbol under the cursor
   does and what file it is defined in (if the symbol is documented).

* RTFM - Read the Fine Manual.
 Other things to read up on to understand org-action-verb:

 + What brackets do in a regular expression
   http://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp-Backslash.html#Regexp-Backslash

   It is also kind of confusing to see "\\" in the code and "\" in
   the documentation. Some more RTFM may be required :)

 + What this line of elisp does:
   (make-overlay (match-beginning 1) (match-end 1) nil t nil)

    http://www.gnu.org/software/emacs/manual/html_node/elisp/Managing-Overlays.html#Managing-Overlays
    http://www.gnu.org/software/emacs/manual/html_node/elisp/Simple-Match-Data.html#index-match_002dbeginning-3021

* org-action-verb - what it does.

 Essentially, all org-action-verb does, is build a bunch of regular
 expressions to find headlines between 'point' and 'limit' with the
 correct TODO type. Once it has found a headline that matches, it
 uses other regular expressions to add or remove the overlay *to the
 first sub-element* of those regular expressions.

 The meat of the code from the original org-action-verb with some
 better comments, will probably provide a better explanation

----------------------- starting at line 189

;;
;; match the whole headline and remove any previous overlay without
;; moving point. Where point should be at the start of a headline.
;;
(if (looking-at "\\(.*\\)$")
   (remove-overlays (match-beginning 1) (match-end 1) 'org-action-overlay t))
;;
;; check for the presence of a valid action-verb
;;
(if (looking-at todo-action-verbs-regexp)
 ;;
 ;; do nothing if the action verb matches
 ;;
   nil
 ;;
 ;; It is not an action verb, apply the overlay to the first word
 ;; in the line.
 ;;
 ;; The regular expression matches the first word after a space or
 ;; tab on a matching headline, and applies the org-action-incorrect
 ;; overlay to it.
 ;; So:
 ;; "[ ]+\\(\\<\\w+\\>\\)"
 ;;
 ;; in english becomes:
 ;;
 ;; - "[ ]+" - Match one or more space or tab (should use :space:).
 ;; - "\\("   - Open sub expression 1
 ;; - "\\<"   - Match the empty string, but only at the beginning of a word
 ;; - "\\w"   - Match one or more word-constituent characters
 ;; - "\\>"   - Match the empty string, but only at the end of a word
 ;; - "\\)"   - Close sub expression 1
 ;;
 (if (looking-at "[ ]+\\(\\<\\w+\\>\\)")
     ;; apply new overlay to 1st matching sub-expression
     (let ((overlay (make-overlay (match-beginning 1) (match-end 1) nil t nil)))
       (overlay-put overlay 'org-action-overlay t)
       (overlay-put overlay 'face 'org-action-incorrect)
       (overlay-put overlay 'evaporate t)
       overlay))))

----------------------- ending at line 202

* What you need to do to fix your problem?
 I suspect all you need to do is change the matching expression to
 something like:

 (let ((tag-keywords-regexp (concat
"^\\*+[:space:]+[\\w:space:]+[:space:]+:\\(" tag "\\):$") ))

 Also you probably want to first match the whole line to remove the
 overlay, before applying a new one.

Hope that helps,

Tim.

2009/11/16 Marcelo de Moraes Serpa <celoserpa@gmail.com>:
> Ok, I'm sorry, I actually had to research a little bit more before posting
> :)
>
> Well, what I need to know now is how to make the overlay work. The code to
> match is working, but I'm receiving the following error:
>
> Error during redisplay: (wrong-number-of-arguments match-beginning 0)
>
> Here's the full code: http://pastie.org/701448
>
> (Thanks to Tim O'Calaghan for the original contribution)
>
> Marcelo.
>
> Also, how can I debug it? I tried debug-on-entry but it is not working :S
>
>
> On Mon, Nov 16, 2009 at 12:10 PM, Marcelo de Moraes Serpa
> <celoserpa@gmail.com> wrote:
>>
>> Hello,
>>
>> I started writing an extension to org that actually applies a custom face
>> to an item tagges as CATEGORY or PROJECT. The thing is I'm really having a
>> hard time understanding the regexp. The code is adapted from the
>> org-action-verb.el by Tim O'Calaghan, basically using the same structure
>> since my elisp knowledge is very basic. I have managed to get it to work to
>> a basic level, but it is applying the face to the whole tree instead of
>> applying to only one item.
>>
>> (defface org-gtd-default-category-face
>>   '((((class color) (background light)) (:foreground "purple" :bold t
>> :underline t))
>>     (((class color) (background dark)) (:foreground "purple" :bold t
>> :underline t))
>>     (t (:bold t :underline t)))
>>   "Used by org-color-by-tag for items tagged with :CATEGORY:")
>>
>> (defface org-gtd-default-project-face
>>   '((((class color) (background light)) (:foreground "purple" :bold t
>> :underline t))
>>     (((class color) (background dark)) (:foreground "purple" :bold t
>> :underline t))
>>     (t (:bold t :underline t)))
>>   "Used by org-color-by-tag for items tagged with :PROJECT:")
>>
>> (defvar org-gtd-tags '("PROJECT" "CATEGORY"))
>>
>> (defun org-font-lock-add-tag-faces (limit)
>>   "Add the faces to corresponding items depending on the TAG."
>>   (let (rtn a)
>>     ;; check variable is set, and buffer left to search
>>     (when (and (not rtn) org-gtd-tags)
>>       ;; for each todo/action verb set
>>       (dolist (tag org-gtd-tags)
>>         ;; build regexps
>>         (let ((tag-keywords-regexp
>>
>>                        (regexp-opt (cdr tag) 'word)))
>>
>>           ;; while we can find a todo keyword
>>           (while (re-search-forward ":PROJECT:" limit t)
>>             ;; check for action verb
>>
>>
>>                    ;; apply new overlay
>>                   (let ((overlay (make-overlay (match-beginning 1)
>> (match-end 1) nil t nil)))
>>                     (overlay-put overlay 'face
>> 'org-gtd-default-project-face)
>>                     ;;(overlay-put overlay 'mouse-face mouse-face)
>>                     (overlay-put overlay 'org-action-overlay t)
>>                     (overlay-put overlay 'evaporate t)
>>                     (overlay-put overlay 'help-echo "mouse-2: correct word
>> at point")
>>                     overlay)
>>
>>
>>             ;; reset search point?
>>             (backward-char 1)))))
>>     rtn))
>>
>> (org-font-lock-add-tag-faces 10)
>>
>> (defun org-mode-color-by-tag-hook ()
>>   "Initalise org-color-by-tag."
>>   (interactive)
>>   (font-lock-add-keywords nil '((org-font-lock-add-tag-faces)))
>>   )
>>
>> ;; Turn on action verb font locking.
>> (add-hook 'org-mode-hook 'org-mode-color-by-tag-hook)
>>
>> As you can see, I'm in the debug phase, and I'm not even using the list of
>> strings (PROJECT CATEGORY) I've created. I'm just trying to search for
>> occurrences of the PROJECT tag and trying to apply the face. I've removed
>> the regexp string that Tim used, which were:
>>
>> "^\\*+[     ]+"
>>
>> Was used here:
>>         (let ((todo-keywords-regexp
>>                (concat "^\\*+[     ]+"
>>                        (regexp-opt (car todo) 'words)))
>>               (todo-action-verbs-regexp
>>                (concat "[     ]+" (regexp-opt (cdr todo) 'words))))
>>
>>
>> And:  "[     ]+\\(\\<\\w\\w+\\>\\)"
>>
>> Used in: (looking-at "[     ]+\\(\\<\\w\\w+\\>\\)")
>>
>> What I want to do is: Search for items tagged as PROJECT or CATEGORY and
>> apply the corresponding face to them.
>>
>> If someone could explain me the role of  "[    ]", and w, I would be
>> grateful :)
>>
>> Thanks,
>>
>> Marcelo.
>>
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
>
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-11-17 11:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-16 18:10 [hack/extension] org-mode/emacs regexp Marcelo de Moraes Serpa
2009-11-16 19:45 ` Marcelo de Moraes Serpa
2009-11-17 11:49   ` Tim O'Callaghan

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).