Hack: keep a window with the current agenda items at all time.
[Worg.git] / org-hacks.org
blob19b67c9fa0deae25d4a349a13f1b3aeb9105c0c0
1 #+OPTIONS:    H:3 num:nil toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t TeX:t LaTeX:t skip:nil d:(HIDE) tags:not-in-toc
2 #+STARTUP:    align fold nodlcheck hidestars oddeven lognotestate
3 #+SEQ_TODO:   TODO(t) INPROGRESS(i) WAITING(w@) | DONE(d) CANCELED(c@)
4 #+TAGS:       Write(w) Update(u) Fix(f) Check(c)
5 #+TITLE:      Org ad hoc code, quick hacks and workarounds
6 #+AUTHOR:     Worg people
7 #+EMAIL:      mdl AT imapmail DOT org
8 #+LANGUAGE:   en
9 #+PRIORITIES: A C B
10 #+CATEGORY:   worg
12 # This file is the default header for new Org files in Worg.  Feel free
13 # to tailor it to your needs.
15 [[file:index.org][{Back to Worg's index}]]
17 This page is for ad hoc bits of code. Feel free to add quick hacks and
18 workaround. Go crazy.
20 * Hacking Org: Working within Org-mode.
21 ** Building and Managing Org
22 *** Compiling Org without make
23 :PROPERTIES:
24 :CUSTOM_ID: compiling-org-without-make
25 :END:
27 This file is the result of  [[http://article.gmane.org/gmane.emacs.orgmode/15264][one of our discussions]] on the mailing list.
28 Enhancements welcome.
30 To use this function, adjust the variables =my/org-lisp-directory= and
31 =my/org-compile-sources= to suite your needs.
33 #+BEGIN_SRC emacs-lisp
34 (defvar my/org-lisp-directory "~/.emacs.d/org/lisp"
35   "Directory where your org-mode files live.")
37 (defvar my/org-compile-sources t
38   "If `nil', never compile org-sources. `my/compile-org' will only create
39 the autoloads file `org-install.el' then. If `t', compile the sources, too.")
41 ;; Customize:
42 (setq my/org-lisp-directory "~/.emacs.d/org/lisp")
44 ;; Customize:
45 (setq  my/org-compile-sources t)
47 (defun my/compile-org(&optional directory)
48   "Compile all *.el files that come with org-mode."
49   (interactive)
50   (setq directory (concat
51                         (file-truename
52                     (or directory my/org-lisp-directory)) "/"))
54   (add-to-list 'load-path directory)
56   (let ((list-of-org-files (file-expand-wildcards (concat directory "*.el"))))
58     ;; create the org-install file
59     (require 'autoload)
60     (setq esf/org-install-file (concat directory "org-install.el"))
61     (find-file esf/org-install-file)
62     (erase-buffer)
63     (mapc (lambda (x)
64             (generate-file-autoloads x))
65           list-of-org-files)
66     (insert "\n(provide (quote org-install))\n")
67     (save-buffer)
68     (kill-buffer)
69     (byte-compile-file esf/org-install-file t)
71     (dolist (f list-of-org-files)
72       (if (file-exists-p (concat f "c")) ; delete compiled files
73           (delete-file (concat f "c")))
74       (if my/org-compile-sources     ; Compile, if `my/org-compile-sources' is t
75           (byte-compile-file f)))))
76 #+END_SRC
77 *** Reload Org
79 As of Org version 6.23b (released Sunday Feb 22, 2009) there is a new
80 function to reload org files.
82 Normally you want to use the compiled files since they are faster.
83 If you update your org files you can easily reload them with
85 : M-x org-reload
87 If you run into a bug and want to generate a useful backtrace you can
88 reload the source files instead of the compiled files with
90 : C-u M-x org-reload
92 and turn on the "Enter Debugger On Error" option.  Redo the action
93 that generates the error and cut and paste the resulting backtrace.
94 To switch back to the compiled version just reload again with
96 : M-x org-reload
98 *** Check for possibly problematic old link escapes
99 :PROPERTIES:
100 :CUSTOM_ID: check-old-link-escapes
101 :END:
103 Starting with version 7.5 Org uses [[http://en.wikipedia.org/wiki/Percent-encoding][percent escaping]] more consistently
104 and with a modified algorithm to determine which characters to escape
105 and how.
107 As a side effect this modified behaviour might break existing links if
108 they contain a sequence of characters that look like a percent escape
109 (e.g. =[0-9A-Fa-f]{2}=) but are in fact not a percent escape.
111 The function below can be used to perform a preliminary check for such
112 links in an Org mode file.  It will run through all links in the file
113 and issue a warning if it finds a percent escape sequence which is not
114 in old Org's list of known percent escapes.
116 #+begin_src emacs-lisp
117   (defun dmaus/org-check-percent-escapes ()
118     "*Check buffer for possibly problematic old link escapes."
119     (interactive)
120     (when (eq major-mode 'org-mode)
121       (let ((old-escapes '("%20" "%5B" "%5D" "%E0" "%E2" "%E7" "%E8" "%E9"
122                            "%EA" "%EE" "%F4" "%F9" "%FB" "%3B" "%3D" "%2B")))
123         (unless (boundp 'warning-suppress-types)
124           (setq warning-suppress-types nil))
125         (widen)
126         (show-all)
127         (goto-char (point-min))
128         (while (re-search-forward org-any-link-re nil t)
129           (let ((end (match-end 0)))
130             (goto-char (match-beginning 0))
131             (while (re-search-forward "%[0-9a-zA-Z]\\{2\\}" end t)
132               (let ((escape (match-string-no-properties 0)))
133                 (unless (member (upcase escape) old-escapes)
134                   (warn "Found unknown percent escape sequence %s at buffer %s, position %d"
135                         escape
136                         (buffer-name)
137                         (- (point) 3)))))
138             (goto-char end))))))
139 #+end_src
141 ** Enhancing the Org experience
142 *** Speed Commands
143 Speed commands are described [[http://orgmode.org/manual/Speed-keys.html#Speed-keys][here]] in the manual. Add your own speed
144 commands here.
145 *** Show next/prev heading tidily
146 - Dan Davison
147   These close the current heading and open the next/previous heading.
149 #+begin_src emacs-lisp
150 (defun ded/org-show-next-heading-tidily ()
151   "Show next entry, keeping other entries closed."
152   (if (save-excursion (end-of-line) (outline-invisible-p))
153       (progn (org-show-entry) (show-children))
154     (outline-next-heading)
155     (unless (and (bolp) (org-on-heading-p))
156       (org-up-heading-safe)
157       (hide-subtree)
158       (error "Boundary reached"))
159     (org-overview)
160     (org-reveal t)
161     (org-show-entry)
162     (show-children)))
164 (defun ded/org-show-previous-heading-tidily ()
165   "Show previous entry, keeping other entries closed."
166   (let ((pos (point)))
167     (outline-previous-heading)
168     (unless (and (< (point) pos) (bolp) (org-on-heading-p))
169       (goto-char pos)
170       (hide-subtree)
171       (error "Boundary reached"))
172     (org-overview)
173     (org-reveal t)
174     (org-show-entry)
175     (show-children)))
177 (setq org-use-speed-commands t)
178 (add-to-list 'org-speed-commands-user
179              '("n" ded/org-show-next-heading-tidily))
180 (add-to-list 'org-speed-commands-user
181              '("p" ded/org-show-previous-heading-tidily))
182 #+end_src
184 *** Changelog support for org headers
185 -- James TD Smith
187 Put the following in your =.emacs=, and =C-x 4 a= and other functions which
188 use =add-log-current-defun= like =magit-add-log= will pick up the nearest org
189 headline as the "current function" if you add a changelog entry from an org
190 buffer.
192 #+BEGIN_SRC emacs-lisp
193   (defun org-log-current-defun ()
194     (save-excursion
195       (org-back-to-heading)
196       (if (looking-at org-complex-heading-regexp)
197           (match-string 4))))
199   (add-hook 'org-mode-hook
200             (lambda ()
201               (make-variable-buffer-local 'add-log-current-defun-function)
202               (setq add-log-current-defun-function 'org-log-current-defun)))
203 #+END_SRC
205 *** Different org-cycle-level behavior
206 -- Ryan Thompson
208 In recent org versions, when your point (cursor) is at the end of an
209 empty header line (like after you first created the header), the TAB
210 key (=org-cycle=) has a special behavior: it cycles the headline through
211 all possible levels. However, I did not like the way it determined
212 "all possible levels," so I rewrote the whole function, along with a
213 couple of supporting functions.
215 The original function's definition of "all possible levels" was "every
216 level from 1 to one more than the initial level of the current
217 headline before you started cycling." My new definition is "every
218 level from 1 to one more than the previous headline's level." So, if
219 you have a headline at level 4 and you use ALT+RET to make a new
220 headline below it, it will cycle between levels 1 and 5, inclusive.
222 The main advantage of my custom =org-cycle-level= function is that it
223 is stateless: the next level in the cycle is determined entirely by
224 the contents of the buffer, and not what command you executed last.
225 This makes it more predictable, I hope.
227 #+BEGIN_SRC emacs-lisp
228 (require 'cl)
230 (defun org-point-at-end-of-empty-headline ()
231   "If point is at the end of an empty headline, return t, else nil."
232   (and (looking-at "[ \t]*$")
233        (save-excursion
234          (beginning-of-line 1)
235          (looking-at (concat "^\\(\\*+\\)[ \t]+\\(" org-todo-regexp "\\)?[ \t]*")))))
237 (defun org-level-increment ()
238   "Return the number of stars that will be added or removed at a
239 time to headlines when structure editing, based on the value of
240 `org-odd-levels-only'."
241   (if org-odd-levels-only 2 1))
243 (defvar org-previous-line-level-cached nil)
245 (defun org-recalculate-previous-line-level ()
246   "Same as `org-get-previous-line-level', but does not use cached
247 value. It does *set* the cached value, though."
248   (set 'org-previous-line-level-cached
249        (let ((current-level (org-current-level))
250              (prev-level (when (> (line-number-at-pos) 1)
251                            (save-excursion
252                              (previous-line)
253                              (org-current-level)))))
254          (cond ((null current-level) nil) ; Before first headline
255                ((null prev-level) 0)      ; At first headline
256                (prev-level)))))
258 (defun org-get-previous-line-level ()
259   "Return the outline depth of the last headline before the
260 current line. Returns 0 for the first headline in the buffer, and
261 nil if before the first headline."
262   ;; This calculation is quite expensive, with all the regex searching
263   ;; and stuff. Since org-cycle-level won't change lines, we can reuse
264   ;; the last value of this command.
265   (or (and (eq last-command 'org-cycle-level)
266            org-previous-line-level-cached)
267       (org-recalculate-previous-line-level)))
269 (defun org-cycle-level ()
270   (interactive)
271   (let ((org-adapt-indentation nil))
272     (when (org-point-at-end-of-empty-headline)
273       (setq this-command 'org-cycle-level) ;Only needed for caching
274       (let ((cur-level (org-current-level))
275             (prev-level (org-get-previous-line-level)))
276         (cond
277          ;; If first headline in file, promote to top-level.
278          ((= prev-level 0)
279           (loop repeat (/ (- cur-level 1) (org-level-increment))
280                 do (org-do-promote)))
281          ;; If same level as prev, demote one.
282          ((= prev-level cur-level)
283           (org-do-demote))
284          ;; If parent is top-level, promote to top level if not already.
285          ((= prev-level 1)
286           (loop repeat (/ (- cur-level 1) (org-level-increment))
287                 do (org-do-promote)))
288          ;; If top-level, return to prev-level.
289          ((= cur-level 1)
290           (loop repeat (/ (- prev-level 1) (org-level-increment))
291                 do (org-do-demote)))
292          ;; If less than prev-level, promote one.
293          ((< cur-level prev-level)
294           (org-do-promote))
295          ;; If deeper than prev-level, promote until higher than
296          ;; prev-level.
297          ((> cur-level prev-level)
298           (loop repeat (+ 1 (/ (- cur-level prev-level) (org-level-increment)))
299                 do (org-do-promote))))
300         t))))
301 #+END_SRC
302 *** Org table
304 **** Transpose tables (Juan Pechiar)
306 This function by Juan Pechiar will transpose a table:
308 #+begin_src emacs-lisp
309 (defun org-transpose-table-at-point ()
310   "Transpose orgmode table at point, eliminate hlines"
311   (interactive)
312   (let ((contents
313          (apply #'mapcar* #'list
314                 ;; remove 'hline from list
315                 (remove-if-not 'listp
316                                ;; signals error if not table
317                                (org-table-to-lisp)))))
318     (delete-region (org-table-begin) (org-table-end))
319     (insert (mapconcat (lambda(x) (concat "| " (mapconcat 'identity x " | " ) "  |\n" ))
320                        contents ""))
321     (org-table-align)))
322 #+end_src
324 So a table like
326 : | 1 | 2 | 4 | 5 |
327 : |---+---+---+---|
328 : | a | b | c | d |
329 : | e | f | g | h |
331 will be transposed as
333 : | 1 | a | e |
334 : | 2 | b | f |
335 : | 4 | c | g |
336 : | 5 | d | h |
338 (Note that horizontal lines disappeared.)
340 *** Times computation
341     :PROPERTIES:
342     :CUSTOM_ID: time-computation
343     :END:
344 **** Manipulate hours/minutes/seconds in table formulas
346 Both Bastien and Martin Halder have posted code ([[http://article.gmane.org/gmane.emacs.orgmode/39519][Bastien's code]] and
347 [[http://article.gmane.org/gmane.emacs.orgmode/39519][Martin's code]]) for interpreting =dd:dd= or =dd:dd:dd= strings (where
348 "=d=" is any digit) as time values in Org-mode table formula.  These
349 functions have now been wrapped up into a =with-time= macro which can
350 be used in table formula to translate table cell values to and from
351 numerical values for algebraic manipulation.
353 Here is the code implementing this macro.
354 #+begin_src emacs-lisp :results silent
355   (defun org-time-string-to-seconds (s)
356     "Convert a string HH:MM:SS to a number of seconds."
357     (cond
358      ((and (stringp s)
359            (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s))
360       (let ((hour (string-to-number (match-string 1 s)))
361             (min (string-to-number (match-string 2 s)))
362             (sec (string-to-number (match-string 3 s))))
363         (+ (* hour 3600) (* min 60) sec)))
364      ((and (stringp s)
365            (string-match "\\([0-9]+\\):\\([0-9]+\\)" s))
366       (let ((min (string-to-number (match-string 1 s)))
367             (sec (string-to-number (match-string 2 s))))
368         (+ (* min 60) sec)))
369      ((stringp s) (string-to-number s))
370      (t s)))
372   (defun org-time-seconds-to-string (secs)
373     "Convert a number of seconds to a time string."
374     (cond ((>= secs 3600) (format-seconds "%h:%.2m:%.2s" secs))
375           ((>= secs 60) (format-seconds "%m:%.2s" secs))
376           (t (format-seconds "%s" secs))))
378   (defmacro with-time (time-output-p &rest exprs)
379     "Evaluate an org-table formula, converting all fields that look
380   like time data to integer seconds.  If TIME-OUTPUT-P then return
381   the result as a time value."
382     (list
383      (if time-output-p 'org-time-seconds-to-string 'identity)
384      (cons 'progn
385            (mapcar
386             (lambda (expr)
387               `,(cons (car expr)
388                       (mapcar
389                        (lambda (el)
390                          (if (listp el)
391                              (list 'with-time nil el)
392                            (org-time-string-to-seconds el)))
393                        (cdr expr))))
394             `,@exprs))))
395 #+end_src
397 Which allows the following forms of table manipulation such as adding
398 and subtracting time values.
399 : | Date             | Start | Lunch |  Back |   End |  Sum |
400 : |------------------+-------+-------+-------+-------+------|
401 : | [2011-03-01 Tue] |  8:00 | 12:00 | 12:30 | 18:15 | 9:45 |
402 : #+TBLFM: $6='(with-time t (+ (- $5 $4) (- $3 $2)))
404 and dividing time values by integers
405 : |  time | miles | minutes/mile |
406 : |-------+-------+--------------|
407 : | 34:43 |   2.9 |        11:58 |
408 : | 32:15 |  2.77 |        11:38 |
409 : | 33:56 |   3.0 |        11:18 |
410 : | 52:22 |  4.62 |        11:20 |
411 : #+TBLFM: $3='(with-time t (/ $1 $2))
413 *** Dates computation
415 **** Question ([[http://article.gmane.org/gmane.emacs.orgmode/15692][Xin Shi]])
417 I have a table in org which stores the date, I'm wondering if there is
418 any function to calculate the duration? For example:
420 | Start Date |   End Date | Duration |
421 |------------+------------+----------|
422 | 2004.08.07 | 2005.07.08 |          |
424 I tried to use B&-C&, but failed ...
426 **** Answer ([[http://article.gmane.org/gmane.emacs.orgmode/15694][Nick Dokos]])
428 Try the following:
430 | Start Date |   End Date | Duration |
431 |------------+------------+----------|
432 | 2004.08.07 | 2005.07.08 |      335 |
433 :#+TBLFM: $3=(date(<$2>)-date(<$1>))
435 See this thread:
437     http://thread.gmane.org/gmane.emacs.orgmode/7741
439 as well as this post (which is really a followup on the
440 above):
442     http://article.gmane.org/gmane.emacs.orgmode/7753
444 The problem that this last article pointed out was solved
447     http://article.gmane.org/gmane.emacs.orgmode/8001
449 and Chris Randle's original musings are at
451     http://article.gmane.org/gmane.emacs.orgmode/6536/
453 *** Hex computation
454 As with [[#time-computation][Times computation]], the following code allows Computation with
455 Hex values in Org-mode tables using the =with-hex= macro.
457 Here is the code implementing this macro.
458 #+begin_src emacs-lisp
459   (defun org-hex-strip-lead (str)
460     (if (and (> (length str) 2) (string= (substring str 0 2) "0x"))
461         (substring str 2) str))
463   (defun org-hex-to-hex (int)
464     (format "0x%x" int))
466   (defun org-hex-to-dec (str)
467     (cond
468      ((and (stringp str)
469            (string-match "\\([0-9a-f]+\\)" (setf str (org-hex-strip-lead str))))
470       (let ((out 0))
471         (mapc
472          (lambda (ch)
473            (setf out (+ (* out 16)
474                         (if (and (>= ch 48) (<= ch 57)) (- ch 48) (- ch 87)))))
475          (coerce (match-string 1 str) 'list))
476         out))
477      ((stringp str) (string-to-number str))
478      (t str)))
480   (defmacro with-hex (hex-output-p &rest exprs)
481     "Evaluate an org-table formula, converting all fields that look
482       like hexadecimal to decimal integers.  If HEX-OUTPUT-P then
483       return the result as a hex value."
484     (list
485      (if hex-output-p 'org-hex-to-hex 'identity)
486      (cons 'progn
487            (mapcar
488             (lambda (expr)
489               `,(cons (car expr)
490                       (mapcar (lambda (el)
491                                 (if (listp el)
492                                     (list 'with-hex nil el)
493                                   (org-hex-to-dec el)))
494                               (cdr expr))))
495             `,@exprs))))
496 #+end_src
498 Which allows the following forms of table manipulation such as adding
499 and subtracting hex values.
500 | 0x10 | 0x0 | 0x10 |  16 |
501 | 0x20 | 0x1 | 0x21 |  33 |
502 | 0x30 | 0x2 | 0x32 |  50 |
503 | 0xf0 | 0xf | 0xff | 255 |
504 #+TBLFM: $3='(with-hex 'hex (+ $2 $1))::$4='(with-hex nil (identity $3))
506 *** Field coordinates in formulas (=@#= and =$#=)
508 -- Michael Brand
510 Following are some use cases that can be implemented with the
511 _field coordinates in formulas_ described in the corresponding
512 chapter in the [[http://orgmode.org/manual/References.html#References][Org manual]], available since =org-version= 6.35.
514 **** Copy a column from a remote table into a column
516 current column =$3= = remote column =$2=:
517 : #+TBLFM: $3 = remote(FOO, @@#$2)
519 **** Copy a row from a remote table transposed into a column
521 current column =$1= = transposed remote row =@1=:
522 : #+TBLFM: $1 = remote(FOO, @$#$@#)
524 **** Transpose a table
526 -- Michael Brand
528 This is more like a demonstration of using _field coordinates in formulas_
529 to [[http://en.wikipedia.org/wiki/Transpose][transpose]] a table or to do it without using org-babel.  The efficient
530 and simple solution for this with the help of org-babel and Emacs Lisp has
531 been provided by Thomas S. Dye on the [[http://thread.gmane.org/gmane.emacs.orgmode/23809/focus=23815][mailing list]].
533 To transpose this 4x7 table
535 : #+TBLNAME: FOO
536 : | year | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 |
537 : |------+------+------+------+------+------+------|
538 : | min  |  401 |  501 |  601 |  701 |  801 |  901 |
539 : | avg  |  402 |  502 |  602 |  702 |  802 |  902 |
540 : | max  |  403 |  503 |  603 |  703 |  803 |  903 |
542 start with a 7x4 table without any horizontal line (to have filled
543 also the column header) and yet empty:
545 : |   |   |   |   |
546 : |   |   |   |   |
547 : |   |   |   |   |
548 : |   |   |   |   |
549 : |   |   |   |   |
550 : |   |   |   |   |
551 : |   |   |   |   |
553 Then add the =TBLFM= below with the same formula repeated for each column.
554 After recalculation this will end up with the transposed copy:
556 : | year | min | avg | max |
557 : | 2004 | 401 | 402 | 403 |
558 : | 2005 | 501 | 502 | 503 |
559 : | 2006 | 601 | 602 | 603 |
560 : | 2007 | 701 | 702 | 703 |
561 : | 2008 | 801 | 802 | 803 |
562 : | 2009 | 901 | 902 | 903 |
563 : #+TBLFM: $1 = remote(FOO, @$#$@#) :: $2 = remote(FOO, @$#$@#) :: $3 = remote(FOO, @$#$@#) :: $4 = remote(FOO, @$#$@#)
565 The formulas simply exchange row and column numbers by taking
566 - the absolute remote row number =@$#= from the current column number =$#=
567 - the absolute remote column number =$@#= from the current row number =@#=
569 Possible field formulas from the remote table will have to be transferred
570 manually.  Since there are no row formulas yet there is no need to transfer
571 column formulas to row formulas or vice versa.
573 **** Dynamic variation of ranges
575 -- Michael Brand
577 In this example all columns next to =quote= are calculated from the column
578 =quote= and show the average change of the time series =quote[year]=
579 during the period of the preceding =1=, =2=, =3= or =4= years:
581 : | year | quote |   1 a |   2 a |   3 a |   4 a |
582 : |------+-------+-------+-------+-------+-------|
583 : | 2005 |    10 |       |       |       |       |
584 : | 2006 |    12 | 0.200 |       |       |       |
585 : | 2007 |    14 | 0.167 | 0.183 |       |       |
586 : | 2008 |    16 | 0.143 | 0.155 | 0.170 |       |
587 : | 2009 |    18 | 0.125 | 0.134 | 0.145 | 0.158 |
588 : #+TBLFM: $3=if(@# >= $#, ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1, string("")); f3::$4=if(@# >= $#, ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1, string("")); f3::$5=if(@# >= $#, ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1, string("")); f3::$6=if(@# >= $#, ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1, string("")); f3
590 The formula is the same for each column =$3= through =$6=.  This can easily
591 be seen with the great formula editor invoked by C-c ' on the
592 table. The important part of the formula without the field blanking is:
594 : ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1
596 which is the Emacs Calc implementation of the equation
598 /AvgChange(i, a) = (quote[i] / quote[i - a]) ^ 1 / n - 1/
600 where /i/ is the current time and /a/ is the length of the preceding period.
602 *** Customize the size of the frame for remember
603 (Note: this hack is likely out of date due to the development of
604 [[org-capture]].)
606 #FIXME: gmane link?
607 On emacs-orgmode, Ryan C. Thompson suggested this:
609 #+begin_quote
610 I am using org-remember set to open a new frame when used,
611 and the default frame size is much too large. To fix this, I have
612 designed some advice and a custom variable to implement custom
613 parameters for the remember frame:
614 #+end_quote
616 #+begin_src emacs-lisp
617 (defcustom remember-frame-alist nil
618   "Additional frame parameters for dedicated remember frame."
619   :type 'alist
620   :group 'remember)
622 (defadvice remember (around remember-frame-parameters activate)
623   "Set some frame parameters for the remember frame."
624   (let ((default-frame-alist (append remember-frame-alist
625                                      default-frame-alist)))
626     ad-do-it))
627 #+end_src
629 Setting remember-frame-alist to =((width . 80) (height . 15)))= give a
630 reasonable size for the frame.
631 *** Promote all items in subtree
632 - Matt Lundin
634 This function will promote all items in a subtree. Since I use
635 subtrees primarily to organize projects, the function is somewhat
636 unimaginatively called my-org-un-project:
638 #+begin_src emacs-lisp
639 (defun my-org-un-project ()
640   (interactive)
641   (org-map-entries 'org-do-promote "LEVEL>1" 'tree)
642   (org-cycle t))
643 #+end_src
645 *** Turn a heading into an Org link
647 From David Maus:
649 #+begin_src emacs-lisp
650   (defun dmj:turn-headline-into-org-mode-link ()
651     "Replace word at point by an Org mode link."
652     (interactive)
653     (when (org-at-heading-p)
654       (let ((hl-text (nth 4 (org-heading-components))))
655         (unless (or (null hl-text)
656                     (org-string-match-p "^[ \t]*:[^:]+:$" hl-text))
657           (beginning-of-line)
658           (search-forward hl-text (point-at-eol))
659           (replace-string
660            hl-text
661            (format "[[file:%s.org][%s]]"
662                    (org-link-escape hl-text)
663                    (org-link-escape hl-text '((?\] . "%5D") (?\[ . "%5B"))))
664            nil (- (point) (length hl-text)) (point))))))
665 #+end_src
667 *** Count words in an Org buffer
669 Paul Sexton [[http://article.gmane.org/gmane.emacs.orgmode/38014][posted]] this function to count words in an Org buffer:
671 #+begin_src emacs-lisp
672 (defun org-word-count (beg end
673                            &optional count-latex-macro-args?
674                            count-footnotes?)
675   "Report the number of words in the Org mode buffer or selected region.
676 Ignores:
677 - comments
678 - tables
679 - source code blocks (#+BEGIN_SRC ... #+END_SRC, and inline blocks)
680 - hyperlinks (but does count words in hyperlink descriptions)
681 - tags, priorities, and TODO keywords in headers
682 - sections tagged as 'not for export'.
684 The text of footnote definitions is ignored, unless the optional argument
685 COUNT-FOOTNOTES? is non-nil.
687 If the optional argument COUNT-LATEX-MACRO-ARGS? is non-nil, the word count
688 includes LaTeX macro arguments (the material between {curly braces}).
689 Otherwise, and by default, every LaTeX macro counts as 1 word regardless
690 of its arguments."
691   (interactive "r")
692   (unless mark-active
693     (setf beg (point-min)
694           end (point-max)))
695   (let ((wc 0)
696         (latex-macro-regexp "\\\\[A-Za-z]+\\(\\[[^]]*\\]\\|\\){\\([^}]*\\)}"))
697     (save-excursion
698       (goto-char beg)
699       (while (< (point) end)
700         (cond
701          ;; Ignore comments.
702          ((or (org-in-commented-line) (org-at-table-p))
703           nil)
704          ;; Ignore hyperlinks. But if link has a description, count
705          ;; the words within the description.
706          ((looking-at org-bracket-link-analytic-regexp)
707           (when (match-string-no-properties 5)
708             (let ((desc (match-string-no-properties 5)))
709               (save-match-data
710                 (incf wc (length (remove "" (org-split-string
711                                              desc "\\W")))))))
712           (goto-char (match-end 0)))
713          ((looking-at org-any-link-re)
714           (goto-char (match-end 0)))
715          ;; Ignore source code blocks.
716          ((org-in-regexps-block-p "^#\\+BEGIN_SRC\\W" "^#\\+END_SRC\\W")
717           nil)
718          ;; Ignore inline source blocks, counting them as 1 word.
719          ((save-excursion
720             (backward-char)
721             (looking-at org-babel-inline-src-block-regexp))
722           (goto-char (match-end 0))
723           (setf wc (+ 2 wc)))
724          ;; Count latex macros as 1 word, ignoring their arguments.
725          ((save-excursion
726             (backward-char)
727             (looking-at latex-macro-regexp))
728           (goto-char (if count-latex-macro-args?
729                          (match-beginning 2)
730                        (match-end 0)))
731           (setf wc (+ 2 wc)))
732          ;; Ignore footnotes.
733          ((and (not count-footnotes?)
734                (or (org-footnote-at-definition-p)
735                    (org-footnote-at-reference-p)))
736           nil)
737          (t
738           (let ((contexts (org-context)))
739             (cond
740              ;; Ignore tags and TODO keywords, etc.
741              ((or (assoc :todo-keyword contexts)
742                   (assoc :priority contexts)
743                   (assoc :keyword contexts)
744                   (assoc :checkbox contexts))
745               nil)
746              ;; Ignore sections marked with tags that are
747              ;; excluded from export.
748              ((assoc :tags contexts)
749               (if (intersection (org-get-tags-at) org-export-exclude-tags
750                                 :test 'equal)
751                   (org-forward-same-level 1)
752                 nil))
753              (t
754               (incf wc))))))
755         (re-search-forward "\\w+\\W*")))
756     (message (format "%d words in %s." wc
757                      (if mark-active "region" "buffer")))))
758 #+end_src
760 *** Using M-up and M-down to transpose paragraphs
762 From Paul Sexton: By default, if used within ordinary paragraphs in
763 org mode, =M-up= and =M-down= transpose *lines* (not sentences).  The
764 following code makes these keys transpose paragraphs, keeping the
765 point at the start of the moved paragraph. Behavior in tables and
766 headings is unaffected. It would be easy to modify this to transpose
767 sentences.
769 #+begin_src emacs-lisp
770 (defun org-transpose-paragraphs (arg)
771  (interactive)
772  (when (and (not (or (org-at-table-p) (org-on-heading-p) (org-at-item-p)))
773             (thing-at-point 'sentence))
774    (transpose-paragraphs arg)
775    (backward-paragraph)
776    (re-search-forward "[[:graph:]]")
777    (goto-char (match-beginning 0))
778    t))
780 (add-to-list 'org-metaup-hook 
781  (lambda () (interactive) (org-transpose-paragraphs -1)))
782 (add-to-list 'org-metadown-hook 
783  (lambda () (interactive) (org-transpose-paragraphs 1)))
784 #+end_src
787 ** Archiving Content in Org-Mode
788 *** Preserve top level headings when archiving to a file
789 - Matt Lundin
791 To preserve (somewhat) the integrity of your archive structure while
792 archiving lower level items to a file, you can use the following
793 defadvice:
795 #+begin_src emacs-lisp
796 (defadvice org-archive-subtree (around my-org-archive-subtree activate)
797   (let ((org-archive-location
798          (if (save-excursion (org-back-to-heading)
799                              (> (org-outline-level) 1))
800              (concat (car (split-string org-archive-location "::"))
801                      "::* "
802                      (car (org-get-outline-path)))
803            org-archive-location)))
804     ad-do-it))
805 #+end_src
807 Thus, if you have an outline structure such as...
809 #+begin_src org
810 ,* Heading
811 ,** Subheading
812 ,*** Subsubheading
813 #+end_src
815 ...archiving "Subsubheading" to a new file will set the location in
816 the new file to the top level heading:
818 #+begin_src org
819 ,* Heading
820 ,** Subsubheading
821 #+end_src
823 While this hack obviously destroys the outline hierarchy somewhat, it
824 at least preserves the logic of level one groupings.
826 A slightly more complex version of this hack will not only keep the
827 archive organized by top-level headings, but will also preserve the
828 tags found on those headings:
830 #+begin_src emacs-lisp
831   (defun my-org-inherited-no-file-tags ()
832     (let ((tags (org-entry-get nil "ALLTAGS" 'selective))
833           (ltags (org-entry-get nil "TAGS")))
834       (mapc (lambda (tag)
835               (setq tags
836                     (replace-regexp-in-string (concat tag ":") "" tags)))
837             (append org-file-tags (when ltags (split-string ltags ":" t))))
838       (if (string= ":" tags) nil tags)))
840   (defadvice org-archive-subtree (around my-org-archive-subtree-low-level activate)
841     (let ((tags (my-org-inherited-no-file-tags))
842           (org-archive-location
843            (if (save-excursion (org-back-to-heading)
844                                (> (org-outline-level) 1))
845                (concat (car (split-string org-archive-location "::"))
846                        "::* "
847                        (car (org-get-outline-path)))
848              org-archive-location)))
849       ad-do-it
850       (with-current-buffer (find-file-noselect (org-extract-archive-file))
851         (save-excursion
852           (while (org-up-heading-safe))
853           (org-set-tags-to tags)))))
854 #+end_src
856 *** Archive in a date tree
858 Posted to Org-mode mailing list by Osamu Okano [2010-04-21 Wed].
860 (Make sure org-datetree.el is loaded for this to work.)
862 #+begin_src emacs-lisp
863 ;; (setq org-archive-location "%s_archive::date-tree")
864 (defadvice org-archive-subtree
865   (around org-archive-subtree-to-data-tree activate)
866   "org-archive-subtree to date-tree"
867   (if
868       (string= "date-tree"
869                (org-extract-archive-heading
870                 (org-get-local-archive-location)))
871       (let* ((dct (decode-time (org-current-time)))
872              (y (nth 5 dct))
873              (m (nth 4 dct))
874              (d (nth 3 dct))
875              (this-buffer (current-buffer))
876              (location (org-get-local-archive-location))
877              (afile (org-extract-archive-file location))
878              (org-archive-location
879               (format "%s::*** %04d-%02d-%02d %s" afile y m d
880                       (format-time-string "%A" (encode-time 0 0 0 d m y)))))
881         (message "afile=%s" afile)
882         (unless afile
883           (error "Invalid `org-archive-location'"))
884         (save-excursion
885           (switch-to-buffer (find-file-noselect afile))
886           (org-datetree-find-year-create y)
887           (org-datetree-find-month-create y m)
888           (org-datetree-find-day-create y m d)
889           (widen)
890           (switch-to-buffer this-buffer))
891         ad-do-it)
892     ad-do-it))
893 #+end_src
895 *** Add inherited tags to archived entries
897 To make =org-archive-subtree= keep inherited tags, Osamu OKANO suggests to
898 advise the function like this:
900 #+begin_example
901 (defadvice org-archive-subtree
902   (before add-inherited-tags-before-org-archive-subtree activate)
903     "add inherited tags before org-archive-subtree"
904     (org-set-tags-to (org-get-tags-at)))
905 #+end_example
907 ** Using and Managing Org-Metadata
908 *** Remove redundant tags of headlines
909 -- David Maus
911 A small function that processes all headlines in current buffer and
912 removes tags that are local to a headline and inherited by a parent
913 headline or the #+FILETAGS: statement.
915 #+BEGIN_SRC emacs-lisp
916   (defun dmj/org-remove-redundant-tags ()
917     "Remove redundant tags of headlines in current buffer.
919   A tag is considered redundant if it is local to a headline and
920   inherited by a parent headline."
921     (interactive)
922     (when (eq major-mode 'org-mode)
923       (save-excursion
924         (org-map-entries
925          '(lambda ()
926             (let ((alltags (split-string (or (org-entry-get (point) "ALLTAGS") "") ":"))
927                   local inherited tag)
928               (dolist (tag alltags)
929                 (if (get-text-property 0 'inherited tag)
930                     (push tag inherited) (push tag local)))
931               (dolist (tag local)
932                 (if (member tag inherited) (org-toggle-tag tag 'off)))))
933          t nil))))
934 #+END_SRC
936 *** Remove empty property drawers
938 David Maus proposed this:
940 #+begin_src emacs-lisp
941 (defun dmj:org:remove-empty-propert-drawers ()
942   "*Remove all empty property drawers in current file."
943   (interactive)
944   (unless (eq major-mode 'org-mode)
945     (error "You need to turn on Org mode for this function."))
946   (save-excursion
947     (goto-char (point-min))
948     (while (re-search-forward ":PROPERTIES:" nil t)
949       (save-excursion
950         (org-remove-empty-drawer-at "PROPERTIES" (match-beginning 0))))))
951 #+end_src
953 *** Group task list by a property
955 This advice allows you to group a task list in Org-Mode.  To use it,
956 set the variable =org-agenda-group-by-property= to the name of a
957 property in the option list for a TODO or TAGS search.  The resulting
958 agenda view will group tasks by that property prior to searching.
960 #+begin_src emacs-lisp
961 (defvar org-agenda-group-by-property nil
962   "Set this in org-mode agenda views to group tasks by property")
964 (defun org-group-bucket-items (prop items)
965   (let ((buckets ()))
966     (dolist (item items)
967       (let* ((marker (get-text-property 0 'org-marker item))
968              (pvalue (org-entry-get marker prop t))
969              (cell (assoc pvalue buckets)))
970         (if cell
971             (setcdr cell (cons item (cdr cell)))
972           (setq buckets (cons (cons pvalue (list item))
973                               buckets)))))
974     (setq buckets (mapcar (lambda (bucket)
975                             (cons (car bucket)
976                                   (reverse (cdr bucket))))
977                           buckets))
978     (sort buckets (lambda (i1 i2)
979                     (string< (car i1) (car i2))))))
981 (defadvice org-finalize-agenda-entries (around org-group-agenda-finalize
982                                                (list &optional nosort))
983   "Prepare bucketed agenda entry lists"
984   (if org-agenda-group-by-property
985       ;; bucketed, handle appropriately
986       (let ((text ""))
987         (dolist (bucket (org-group-bucket-items
988                          org-agenda-group-by-property
989                          list))
990           (let ((header (concat "Property "
991                                 org-agenda-group-by-property
992                                 " is "
993                                 (or (car bucket) "<nil>") ":\n")))
994             (add-text-properties 0 (1- (length header))
995                                  (list 'face 'org-agenda-structure)
996                                  header)
997             (setq text
998                   (concat text header
999                           ;; recursively process
1000                           (let ((org-agenda-group-by-property nil))
1001                             (org-finalize-agenda-entries
1002                              (cdr bucket) nosort))
1003                           "\n\n"))))
1004         (setq ad-return-value text))
1005     ad-do-it))
1006 (ad-activate 'org-finalize-agenda-entries)
1007 #+end_src
1008 *** A way to tag a task so that when clocking-out user is prompted to take a note.
1009     Thanks to Richard Riley (see [[http://permalink.gmane.org/gmane.emacs.orgmode/40896][this post on the mailing list]]).
1011 A small hook run when clocking out of a task that prompts for a note
1012 when the tag "=clockout_note=" is found in a headline. It uses the tag
1013 ("=clockout_note=") so inheritance can also be used...
1015 #+begin_src emacs-lisp
1016   (defun rgr/check-for-clock-out-note()
1017         (interactive)
1018         (save-excursion
1019           (org-back-to-heading)
1020           (let ((tags (org-get-tags)))
1021             (and tags (message "tags: %s " tags)
1022                  (when (member "clocknote" tags)
1023                    (org-add-note))))))
1025   (add-hook 'org-clock-out-hook 'rgr/check-for-clock-out-note)
1026 #+end_src
1027 *** Dynamically adjust tag position
1028 Here is a bit of code that allows you to have the tags always
1029 right-adjusted in the buffer.
1031 This is useful when you have bigger window than default window-size
1032 and you dislike the aesthetics of having the tag in the middle of the
1033 line.
1035 This hack solves the problem of adjusting it whenever you change the
1036 window size.
1037 Before saving it will revert the file to having the tag position be
1038 left-adjusted so that if you track your files with version control,
1039 you won't run into artificial diffs just because the window-size
1040 changed.
1042 *IMPORTANT*: This is probably slow on very big files.
1044 #+begin_src emacs-lisp
1045 (setq ba/org-adjust-tags-column t)
1047 (defun ba/org-adjust-tags-column-reset-tags ()
1048   "In org-mode buffers it will reset tag position according to
1049 `org-tags-column'."
1050   (when (and
1051          (not (string= (buffer-name) "*Remember*"))
1052          (eql major-mode 'org-mode))
1053     (let ((b-m-p (buffer-modified-p)))
1054       (condition-case nil
1055           (save-excursion
1056             (goto-char (point-min))
1057             (command-execute 'outline-next-visible-heading)
1058             ;; disable (message) that org-set-tags generates
1059             (flet ((message (&rest ignored) nil))
1060               (org-set-tags 1 t))
1061             (set-buffer-modified-p b-m-p))
1062         (error nil)))))
1064 (defun ba/org-adjust-tags-column-now ()
1065   "Right-adjust `org-tags-column' value, then reset tag position."
1066   (set (make-local-variable 'org-tags-column)
1067        (- (- (window-width) (length org-ellipsis))))
1068   (ba/org-adjust-tags-column-reset-tags))
1070 (defun ba/org-adjust-tags-column-maybe ()
1071   "If `ba/org-adjust-tags-column' is set to non-nil, adjust tags."
1072   (when ba/org-adjust-tags-column
1073     (ba/org-adjust-tags-column-now)))
1075 (defun ba/org-adjust-tags-column-before-save ()
1076   "Tags need to be left-adjusted when saving."
1077   (when ba/org-adjust-tags-column
1078      (setq org-tags-column 1)
1079      (ba/org-adjust-tags-column-reset-tags)))
1081 (defun ba/org-adjust-tags-column-after-save ()
1082   "Revert left-adjusted tag position done by before-save hook."
1083   (ba/org-adjust-tags-column-maybe)
1084   (set-buffer-modified-p nil))
1086 ; automatically align tags on right-hand side
1087 (add-hook 'window-configuration-change-hook
1088           'ba/org-adjust-tags-column-maybe)
1089 (add-hook 'before-save-hook 'ba/org-adjust-tags-column-before-save)
1090 (add-hook 'after-save-hook 'ba/org-adjust-tags-column-after-save)
1091 (add-hook 'org-agenda-mode-hook '(lambda ()
1092                                   (setq org-agenda-tags-column (- (window-width)))))
1094 ; between invoking org-refile and displaying the prompt (which
1095 ; triggers window-configuration-change-hook) tags might adjust,
1096 ; which invalidates the org-refile cache
1097 (defadvice org-refile (around org-refile-disable-adjust-tags)
1098   "Disable dynamically adjusting tags"
1099   (let ((ba/org-adjust-tags-column nil))
1100     ad-do-it))
1101 (ad-activate 'org-refile)
1102 #+end_src
1103 ** Org Agenda and Task Management
1104 *** Make it easier to set org-agenda-files from multiple directories
1105 - Matt Lundin
1107 #+begin_src emacs-lisp
1108 (defun my-org-list-files (dirs ext)
1109   "Function to create list of org files in multiple subdirectories.
1110 This can be called to generate a list of files for
1111 org-agenda-files or org-refile-targets.
1113 DIRS is a list of directories.
1115 EXT is a list of the extensions of files to be included."
1116   (let ((dirs (if (listp dirs)
1117                   dirs
1118                 (list dirs)))
1119         (ext (if (listp ext)
1120                  ext
1121                (list ext)))
1122         files)
1123     (mapc
1124      (lambda (x)
1125        (mapc
1126         (lambda (y)
1127           (setq files
1128                 (append files
1129                         (file-expand-wildcards
1130                          (concat (file-name-as-directory x) "*" y)))))
1131         ext))
1132      dirs)
1133     (mapc
1134      (lambda (x)
1135        (when (or (string-match "/.#" x)
1136                  (string-match "#$" x))
1137          (setq files (delete x files))))
1138      files)
1139     files))
1141 (defvar my-org-agenda-directories '("~/org/")
1142   "List of directories containing org files.")
1143 (defvar my-org-agenda-extensions '(".org")
1144   "List of extensions of agenda files")
1146 (setq my-org-agenda-directories '("~/org/" "~/work/"))
1147 (setq my-org-agenda-extensions '(".org" ".ref"))
1149 (defun my-org-set-agenda-files ()
1150   (interactive)
1151   (setq org-agenda-files (my-org-list-files
1152                           my-org-agenda-directories
1153                           my-org-agenda-extensions)))
1155 (my-org-set-agenda-files)
1156 #+end_src
1158 The code above will set your "default" agenda files to all files
1159 ending in ".org" and ".ref" in the directories "~/org/" and "~/work/".
1160 You can change these values by setting the variables
1161 my-org-agenda-extensions and my-org-agenda-directories. The function
1162 my-org-agenda-files-by-filetag uses these two variables to determine
1163 which files to search for filetags (i.e., the larger set from which
1164 the subset will be drawn).
1166 You can also easily use my-org-list-files to "mix and match"
1167 directories and extensions to generate different lists of agenda
1168 files.
1170 *** Restrict org-agenda-files by filetag
1171   :PROPERTIES:
1172   :CUSTOM_ID: set-agenda-files-by-filetag
1173   :END:
1174 - Matt Lundin
1176 It is often helpful to limit yourself to a subset of your agenda
1177 files. For instance, at work, you might want to see only files related
1178 to work (e.g., bugs, clientA, projectxyz, etc.). The FAQ has helpful
1179 information on filtering tasks using [[file:org-faq.org::#limit-agenda-with-tag-filtering][filetags]] and [[file:org-faq.org::#limit-agenda-with-category-match][custom agenda
1180 commands]]. These solutions, however, require reapplying a filter each
1181 time you call the agenda or writing several new custom agenda commands
1182 for each context. Another solution is to use directories for different
1183 types of tasks and to change your agenda files with a function that
1184 sets org-agenda-files to the appropriate directory. But this relies on
1185 hard and static boundaries between files.
1187 The following functions allow for a more dynamic approach to selecting
1188 a subset of files based on filetags:
1190 #+begin_src emacs-lisp
1191 (defun my-org-agenda-restrict-files-by-filetag (&optional tag)
1192   "Restrict org agenda files only to those containing filetag."
1193   (interactive)
1194   (let* ((tagslist (my-org-get-all-filetags))
1195          (ftag (or tag
1196                    (completing-read "Tag: "
1197                                     (mapcar 'car tagslist)))))
1198     (org-agenda-remove-restriction-lock 'noupdate)
1199     (put 'org-agenda-files 'org-restrict (cdr (assoc ftag tagslist)))
1200     (setq org-agenda-overriding-restriction 'files)))
1202 (defun my-org-get-all-filetags ()
1203   "Get list of filetags from all default org-files."
1204   (let ((files org-agenda-files)
1205         tagslist x)
1206     (save-window-excursion
1207       (while (setq x (pop files))
1208         (set-buffer (find-file-noselect x))
1209         (mapc
1210          (lambda (y)
1211            (let ((tagfiles (assoc y tagslist)))
1212              (if tagfiles
1213                  (setcdr tagfiles (cons x (cdr tagfiles)))
1214                (add-to-list 'tagslist (list y x)))))
1215          (my-org-get-filetags)))
1216       tagslist)))
1218 (defun my-org-get-filetags ()
1219   "Get list of filetags for current buffer"
1220   (let ((ftags org-file-tags)
1221         x)
1222     (mapcar
1223      (lambda (x)
1224        (org-substring-no-properties x))
1225      ftags)))
1226 #+end_src
1228 Calling my-org-agenda-restrict-files-by-filetag results in a prompt
1229 with all filetags in your "normal" agenda files. When you select a
1230 tag, org-agenda-files will be restricted to only those files
1231 containing the filetag. To release the restriction, type C-c C-x >
1232 (org-agenda-remove-restriction-lock).
1234 *** Highlight the agenda line under cursor
1236 This is useful to make sure what task you are operating on.
1238 #+BEGIN_SRC emacs-lisp
1239 (add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))
1240 #+END_SRC emacs-lisp
1242 Under XEmacs:
1244 #+BEGIN_SRC emacs-lisp
1245 ;; hl-line seems to be only for emacs
1246 (require 'highline)
1247 (add-hook 'org-agenda-mode-hook '(lambda () (highline-mode 1)))
1249 ;; highline-mode does not work straightaway in tty mode.
1250 ;; I use a black background
1251 (custom-set-faces
1252   '(highline-face ((((type tty) (class color))
1253                     (:background "white" :foreground "black")))))
1254 #+END_SRC emacs-lisp
1256 *** Split horizontally for agenda
1258 If you would like to split the frame into two side-by-side windows when
1259 displaying the agenda, try this hack from Jan Rehders, which uses the
1260 `toggle-window-split' from
1262 http://www.emacswiki.org/cgi-bin/wiki/ToggleWindowSplit
1264 #+BEGIN_SRC emacs-lisp
1265 ;; Patch org-mode to use vertical splitting
1266 (defadvice org-prepare-agenda (after org-fix-split)
1267   (toggle-window-split))
1268 (ad-activate 'org-prepare-agenda)
1269 #+END_SRC
1271 *** Automatically add an appointment when clocking in a task
1273 #+BEGIN_SRC emacs-lisp
1274 ;; Make sure you have a sensible value for `appt-message-warning-time'
1275 (defvar bzg-org-clock-in-appt-delay 100
1276   "Number of minutes for setting an appointment by clocking-in")
1277 #+END_SRC
1279 This function let's you add an appointment for the current entry.
1280 This can be useful when you need a reminder.
1282 #+BEGIN_SRC emacs-lisp
1283 (defun bzg-org-clock-in-add-appt (&optional n)
1284   "Add an appointment for the Org entry at point in N minutes."
1285   (interactive)
1286   (save-excursion
1287     (org-back-to-heading t)
1288     (looking-at org-complex-heading-regexp)
1289     (let* ((msg (match-string-no-properties 4))
1290            (ct-time (decode-time))
1291            (appt-min (+ (cadr ct-time)
1292                         (or n bzg-org-clock-in-appt-delay)))
1293            (appt-time ; define the time for the appointment
1294             (progn (setf (cadr ct-time) appt-min) ct-time)))
1295       (appt-add (format-time-string
1296                  "%H:%M" (apply 'encode-time appt-time)) msg)
1297       (if (interactive-p) (message "New appointment for %s" msg)))))
1298 #+END_SRC
1300 You can advise =org-clock-in= so that =C-c C-x C-i= will automatically
1301 add an appointment:
1303 #+BEGIN_SRC emacs-lisp
1304 (defadvice org-clock-in (after org-clock-in-add-appt activate)
1305   "Add an appointment when clocking a task in."
1306   (bzg-org-clock-in-add-appt))
1307 #+END_SRC
1309 You may also want to delete the associated appointment when clocking
1310 out.  This function does this:
1312 #+BEGIN_SRC emacs-lisp
1313 (defun bzg-org-clock-out-delete-appt nil
1314   "When clocking out, delete any associated appointment."
1315   (interactive)
1316   (save-excursion
1317     (org-back-to-heading t)
1318     (looking-at org-complex-heading-regexp)
1319     (let* ((msg (match-string-no-properties 4)))
1320       (setq appt-time-msg-list
1321             (delete nil
1322                     (mapcar
1323                      (lambda (appt)
1324                        (if (not (string-match (regexp-quote msg)
1325                                               (cadr appt))) appt))
1326                      appt-time-msg-list)))
1327       (appt-check))))
1328 #+END_SRC
1330 And here is the advice for =org-clock-out= (=C-c C-x C-o=)
1332 #+BEGIN_SRC emacs-lisp
1333 (defadvice org-clock-out (before org-clock-out-delete-appt activate)
1334   "Delete an appointment when clocking a task out."
1335   (bzg-org-clock-out-delete-appt))
1336 #+END_SRC
1338 *IMPORTANT*: You can add appointment by clocking in in both an
1339 =org-mode= and an =org-agenda-mode= buffer.  But clocking out from
1340 agenda buffer with the advice above will bring an error.
1342 *** Remove time grid lines that are in an appointment
1344 The agenda shows lines for the time grid.  Some people think that
1345 these lines are a distraction when there are appointments at those
1346 times.  You can get rid of the lines which coincide exactly with the
1347 beginning of an appointment.  Michael Ekstrand has written a piece of
1348 advice that also removes lines that are somewhere inside an
1349 appointment:
1351 #+begin_src emacs-lisp
1352 (defun org-time-to-minutes (time)
1353   "Convert an HHMM time to minutes"
1354   (+ (* (/ time 100) 60) (% time 100)))
1356 (defun org-time-from-minutes (minutes)
1357   "Convert a number of minutes to an HHMM time"
1358   (+ (* (/ minutes 60) 100) (% minutes 60)))
1360 (defadvice org-agenda-add-time-grid-maybe (around mde-org-agenda-grid-tweakify
1361                                                   (list ndays todayp))
1362   (if (member 'remove-match (car org-agenda-time-grid))
1363       (flet ((extract-window
1364               (line)
1365               (let ((start (get-text-property 1 'time-of-day line))
1366                     (dur (get-text-property 1 'duration line)))
1367                 (cond
1368                  ((and start dur)
1369                   (cons start
1370                         (org-time-from-minutes
1371                          (+ dur (org-time-to-minutes start)))))
1372                  (start start)
1373                  (t nil)))))
1374         (let* ((windows (delq nil (mapcar 'extract-window list)))
1375                (org-agenda-time-grid
1376                 (list (car org-agenda-time-grid)
1377                       (cadr org-agenda-time-grid)
1378                       (remove-if
1379                        (lambda (time)
1380                          (find-if (lambda (w)
1381                                     (if (numberp w)
1382                                         (equal w time)
1383                                       (and (>= time (car w))
1384                                            (< time (cdr w)))))
1385                                   windows))
1386                        (caddr org-agenda-time-grid)))))
1387           ad-do-it))
1388     ad-do-it))
1389 (ad-activate 'org-agenda-add-time-grid-maybe)
1390 #+end_src
1391 *** Disable vc for Org mode agenda files
1392 -- David Maus
1394 Even if you use Git to track your agenda files you might not need
1395 vc-mode to be enabled for these files.
1397 #+begin_src emacs-lisp
1398 (add-hook 'find-file-hook 'dmj/disable-vc-for-agenda-files-hook)
1399 (defun dmj/disable-vc-for-agenda-files-hook ()
1400   "Disable vc-mode for Org agenda files."
1401   (if (and (fboundp 'org-agenda-file-p)
1402            (org-agenda-file-p (buffer-file-name)))
1403       (remove-hook 'find-file-hook 'vc-find-file-hook)
1404     (add-hook 'find-file-hook 'vc-find-file-hook)))
1405 #+end_src
1407 *** Easy customization of TODO colors
1408 -- Ryan C. Thompson
1410 Here is some code I came up with some code to make it easier to
1411 customize the colors of various TODO keywords. As long as you just
1412 want a different color and nothing else, you can customize the
1413 variable org-todo-keyword-faces and use just a string color (i.e. a
1414 string of the color name) as the face, and then org-get-todo-face
1415 will convert the color to a face, inheriting everything else from
1416 the standard org-todo face.
1418 To demonstrate, I currently have org-todo-keyword-faces set to
1420 #+BEGIN_SRC emacs-lisp
1421 (("IN PROGRESS" . "dark orange")
1422  ("WAITING" . "red4")
1423  ("CANCELED" . "saddle brown"))
1424 #+END_SRC emacs-lisp
1426   Here's the code, in a form you can put in your =.emacs=
1428 #+BEGIN_SRC emacs-lisp
1429 (eval-after-load 'org-faces
1430  '(progn
1431     (defcustom org-todo-keyword-faces nil
1432       "Faces for specific TODO keywords.
1433 This is a list of cons cells, with TODO keywords in the car and
1434 faces in the cdr.  The face can be a symbol, a color, or a
1435 property list of attributes, like (:foreground \"blue\" :weight
1436 bold :underline t)."
1437       :group 'org-faces
1438       :group 'org-todo
1439       :type '(repeat
1440               (cons
1441                (string :tag "Keyword")
1442                (choice color (sexp :tag "Face")))))))
1444 (eval-after-load 'org
1445  '(progn
1446     (defun org-get-todo-face-from-color (color)
1447       "Returns a specification for a face that inherits from org-todo
1448  face and has the given color as foreground. Returns nil if
1449  color is nil."
1450       (when color
1451         `(:inherit org-warning :foreground ,color)))
1453     (defun org-get-todo-face (kwd)
1454       "Get the right face for a TODO keyword KWD.
1455 If KWD is a number, get the corresponding match group."
1456       (if (numberp kwd) (setq kwd (match-string kwd)))
1457       (or (let ((face (cdr (assoc kwd org-todo-keyword-faces))))
1458             (if (stringp face)
1459                 (org-get-todo-face-from-color face)
1460               face))
1461           (and (member kwd org-done-keywords) 'org-done)
1462           'org-todo))))
1463 #+END_SRC emacs-lisp
1465 *** Add an effort estimate on the fly when clocking in
1467 You can use =org-clock-in-prepare-hook= to add an effort estimate.
1468 This way you can easily have a "tea-timer" for your tasks when they
1469 don't already have an effort estimate.
1471 #+begin_src emacs-lisp
1472 (add-hook 'org-clock-in-prepare-hook
1473           'my-org-mode-ask-effort)
1475 (defun my-org-mode-ask-effort ()
1476   "Ask for an effort estimate when clocking in."
1477   (unless (org-entry-get (point) "Effort")
1478     (let ((effort
1479            (completing-read
1480             "Effort: "
1481             (org-entry-get-multivalued-property (point) "Effort"))))
1482       (unless (equal effort "")
1483         (org-set-property "Effort" effort)))))
1484 #+end_src
1486 Or you can use a default effort for such a timer:
1488 #+begin_src emacs-lisp
1489 (add-hook 'org-clock-in-prepare-hook
1490           'my-org-mode-add-default-effort)
1492 (defvar org-clock-default-effort "1:00")
1494 (defun my-org-mode-add-default-effort ()
1495   "Add a default effort estimation."
1496   (unless (org-entry-get (point) "Effort")
1497     (org-set-property "Effort" org-clock-default-effort)))
1498 #+end_src
1500 *** Refresh the agenda view regurally
1502 Hack sent by Kiwon Um:
1504 #+begin_src emacs-lisp
1505 (defun kiwon/org-agenda-redo-in-other-window ()
1506   "Call org-agenda-redo function even in the non-agenda buffer."
1507   (interactive)
1508   (let ((agenda-window (get-buffer-window org-agenda-buffer-name t)))
1509     (when agenda-window
1510       (with-selected-window agenda-window (org-agenda-redo)))))
1511 (run-at-time nil 300 'kiwon/org-agenda-redo-in-other-window)
1512 #+end_src
1514 *** Reschedule agenda items to today with a single command
1516 This was suggested by Carsten in reply to David Abrahams:
1518 #+begin_example emacs-lisp
1519 (defun org-agenda-reschedule-to-today ()
1520   (interactive)
1521   (flet ((org-read-date (&rest rest) (current-time)))
1522     (call-interactively 'org-agenda-schedule)))
1523 #+end_example
1525 ** Exporting org files
1526 *** Specifying LaTeX commands to floating environments
1528 The keyword ~placement~ can be used to specify placement options to
1529 floating environments (like =\begin{figure}= and =\begin{table}=}) in
1530 LaTeX export. Org passes along everything passed in options as long as
1531 there are no spaces. One can take advantage of this to pass other
1532 LaTeX commands and have their scope limited to the floating
1533 environment.
1535 For example one can set the fontsize of a table different from the
1536 default normal size by putting something like =\footnotesize= right
1537 after the placement options. During LaTeX export using the
1538 ~#+ATTR_LaTeX:~ line below:
1540 #+begin_src org
1541   ,#+ATTR_LaTeX: placement=[<options>]\footnotesize
1542 #+end_src
1544 exports the associated floating environment as shown in the following
1545 block.
1547 #+begin_src latex
1548 \begin{table}[<options>]\footnotesize
1550 \end{table}
1551 #+end_src
1553 * Hacking Org: Working with Org-mode and other Emacs Packages.
1554 ** org-remember-anything
1556 [[http://www.emacswiki.org/cgi-bin/wiki/Anything][Anything]] users may find the snippet below interesting:
1558 #+BEGIN_SRC emacs-lisp
1559 (defvar org-remember-anything
1560   '((name . "Org Remember")
1561     (candidates . (lambda () (mapcar 'car org-remember-templates)))
1562     (action . (lambda (name)
1563                 (let* ((orig-template org-remember-templates)
1564                        (org-remember-templates
1565                         (list (assoc name orig-template))))
1566                   (call-interactively 'org-remember))))))
1567 #+END_SRC
1569 You can add it to your 'anything-sources' variable and open remember directly
1570 from anything. I imagine this would be more interesting for people with many
1571 remember templatesm, so that you are out of keys to assign those to. You should
1572 get something like this:
1574 [[file:images/thumbs/org-remember-anything.png]]
1576 ** Org-mode and saveplace.el
1578 Fix a problem with saveplace.el putting you back in a folded position:
1580 #+begin_src emacs-lisp
1581 (add-hook 'org-mode-hook
1582           (lambda ()
1583             (when (outline-invisible-p)
1584               (save-excursion
1585                 (outline-previous-visible-heading 1)
1586                 (org-show-subtree)))))
1587 #+end_src
1589 ** Using ido-completing-read to find attachments
1590 -- Matt Lundin
1592 Org-attach is great for quickly linking files to a project. But if you
1593 use org-attach extensively you might find yourself wanting to browse
1594 all the files you've attached to org headlines. This is not easy to do
1595 manually, since the directories containing the files are not human
1596 readable (i.e., they are based on automatically generated ids). Here's
1597 some code to browse those files using ido (obviously, you need to be
1598 using ido):
1600 #+begin_src emacs-lisp
1601 (load-library "find-lisp")
1603 ;; Adapted from http://www.emacswiki.org/emacs/RecentFiles
1605 (defun my-ido-find-org-attach ()
1606   "Find files in org-attachment directory"
1607   (interactive)
1608   (let* ((enable-recursive-minibuffers t)
1609          (files (find-lisp-find-files org-attach-directory "."))
1610          (file-assoc-list
1611           (mapcar (lambda (x)
1612                     (cons (file-name-nondirectory x)
1613                           x))
1614                   files))
1615          (filename-list
1616           (remove-duplicates (mapcar #'car file-assoc-list)
1617                              :test #'string=))
1618          (filename (ido-completing-read "Org attachments: " filename-list nil t))
1619          (longname (cdr (assoc filename file-assoc-list))))
1620     (ido-set-current-directory
1621      (if (file-directory-p longname)
1622          longname
1623        (file-name-directory longname)))
1624     (setq ido-exit 'refresh
1625           ido-text-init ido-text
1626           ido-rotate-temp t)
1627     (exit-minibuffer)))
1629 (add-hook 'ido-setup-hook 'ido-my-keys)
1631 (defun ido-my-keys ()
1632   "Add my keybindings for ido."
1633   (define-key ido-completion-map (kbd "C-;") 'my-ido-find-org-attach))
1634 #+end_src
1636 To browse your org attachments using ido fuzzy matching and/or the
1637 completion buffer, invoke ido-find-file as usual (=C-x C-f=) and then
1638 press =C-;=.
1640 ** Use idle timer for automatic agenda views
1642 From John Wiegley's mailing list post (March 18, 2010):
1644 #+begin_quote
1645 I have the following snippet in my .emacs file, which I find very
1646 useful. Basically what it does is that if I don't touch my Emacs for 5
1647 minutes, it displays the current agenda. This keeps my tasks "always
1648 in mind" whenever I come back to Emacs after doing something else,
1649 whereas before I had a tendency to forget that it was there.
1650 #+end_quote
1652   - [[http://mid.gmane.org/55590EA7-C744-44E5-909F-755F0BBE452D@gmail.com][John Wiegley: Displaying your Org agenda after idle time]]
1654 #+begin_src emacs-lisp
1655 (defun jump-to-org-agenda ()
1656   (interactive)
1657   (let ((buf (get-buffer "*Org Agenda*"))
1658         wind)
1659     (if buf
1660         (if (setq wind (get-buffer-window buf))
1661             (select-window wind)
1662           (if (called-interactively-p)
1663               (progn
1664                 (select-window (display-buffer buf t t))
1665                 (org-fit-window-to-buffer)
1666                 ;; (org-agenda-redo)
1667                 )
1668             (with-selected-window (display-buffer buf)
1669               (org-fit-window-to-buffer)
1670               ;; (org-agenda-redo)
1671               )))
1672       (call-interactively 'org-agenda-list)))
1673   ;;(let ((buf (get-buffer "*Calendar*")))
1674   ;;  (unless (get-buffer-window buf)
1675   ;;    (org-agenda-goto-calendar)))
1676   )
1678 (run-with-idle-timer 300 t 'jump-to-org-agenda)
1679 #+end_src
1681 #+results:
1682 : [nil 0 300 0 t jump-to-org-agenda nil idle]
1684 ** Link to Gnus messages by Message-Id
1686 In a [[http://thread.gmane.org/gmane.emacs.orgmode/8860][recent thread]] on the Org-Mode mailing list, there was some
1687 discussion about linking to Gnus messages without encoding the folder
1688 name in the link.  The following code hooks in to the store-link
1689 function in Gnus to capture links by Message-Id when in nnml folders,
1690 and then provides a link type "mid" which can open this link.  The
1691 =mde-org-gnus-open-message-link= function uses the
1692 =mde-mid-resolve-methods= variable to determine what Gnus backends to
1693 scan.  It will go through them, in order, asking each to locate the
1694 message and opening it from the first one that reports success.
1696 It has only been tested with a single nnml backend, so there may be
1697 bugs lurking here and there.
1699 The logic for finding the message was adapted from [[http://www.emacswiki.org/cgi-bin/wiki/FindMailByMessageId][an Emacs Wiki
1700 article]].
1702 #+begin_src emacs-lisp
1703 ;; Support for saving Gnus messages by Message-ID
1704 (defun mde-org-gnus-save-by-mid ()
1705   (when (memq major-mode '(gnus-summary-mode gnus-article-mode))
1706     (when (eq major-mode 'gnus-article-mode)
1707       (gnus-article-show-summary))
1708     (let* ((group gnus-newsgroup-name)
1709            (method (gnus-find-method-for-group group)))
1710       (when (eq 'nnml (car method))
1711         (let* ((article (gnus-summary-article-number))
1712                (header (gnus-summary-article-header article))
1713                (from (mail-header-from header))
1714                (message-id
1715                 (save-match-data
1716                   (let ((mid (mail-header-id header)))
1717                     (if (string-match "<\\(.*\\)>" mid)
1718                         (match-string 1 mid)
1719                       (error "Malformed message ID header %s" mid)))))
1720                (date (mail-header-date header))
1721                (subject (gnus-summary-subject-string)))
1722           (org-store-link-props :type "mid" :from from :subject subject
1723                                 :message-id message-id :group group
1724                                 :link (org-make-link "mid:" message-id))
1725           (apply 'org-store-link-props
1726                  :description (org-email-link-description)
1727                  org-store-link-plist)
1728           t)))))
1730 (defvar mde-mid-resolve-methods '()
1731   "List of methods to try when resolving message ID's.  For Gnus,
1732 it is a cons of 'gnus and the select (type and name).")
1733 (setq mde-mid-resolve-methods
1734       '((gnus nnml "")))
1736 (defvar mde-org-gnus-open-level 1
1737   "Level at which Gnus is started when opening a link")
1738 (defun mde-org-gnus-open-message-link (msgid)
1739   "Open a message link with Gnus"
1740   (require 'gnus)
1741   (require 'org-table)
1742   (catch 'method-found
1743     (message "[MID linker] Resolving %s" msgid)
1744     (dolist (method mde-mid-resolve-methods)
1745       (cond
1746        ((and (eq (car method) 'gnus)
1747              (eq (cadr method) 'nnml))
1748         (funcall (cdr (assq 'gnus org-link-frame-setup))
1749                  mde-org-gnus-open-level)
1750         (when gnus-other-frame-object
1751           (select-frame gnus-other-frame-object))
1752         (let* ((msg-info (nnml-find-group-number
1753                           (concat "<" msgid ">")
1754                           (cdr method)))
1755                (group (and msg-info (car msg-info)))
1756                (message (and msg-info (cdr msg-info)))
1757                (qname (and group
1758                            (if (gnus-methods-equal-p
1759                                 (cdr method)
1760                                 gnus-select-method)
1761                                group
1762                              (gnus-group-full-name group (cdr method))))))
1763           (when msg-info
1764             (gnus-summary-read-group qname nil t)
1765             (gnus-summary-goto-article message nil t))
1766           (throw 'method-found t)))
1767        (t (error "Unknown link type"))))))
1769 (eval-after-load 'org-gnus
1770   '(progn
1771      (add-to-list 'org-store-link-functions 'mde-org-gnus-save-by-mid)
1772      (org-add-link-type "mid" 'mde-org-gnus-open-message-link)))
1773 #+end_src
1775 ** Store link upon sending a message in Gnus
1777 Ulf Stegemann came up with this solution (see his [[http://www.mail-archive.com/emacs-orgmode@gnu.org/msg33278.html][original message]]):
1779 #+begin_src emacs-lisp
1780 (defun ulf-message-send-and-org-gnus-store-link (&optional arg)
1781   "Send message with `message-send-and-exit' and store org link to message copy.
1782 If multiple groups appear in the Gcc header, the link refers to
1783 the copy in the last group."
1784   (interactive "P")
1785     (save-excursion
1786       (save-restriction
1787         (message-narrow-to-headers)
1788         (let ((gcc (car (last
1789                          (message-unquote-tokens
1790                           (message-tokenize-header
1791                            (mail-fetch-field "gcc" nil t) " ,")))))
1792               (buf (current-buffer))
1793               (message-kill-buffer-on-exit nil)
1794               id to from subject desc link newsgroup xarchive)
1795         (message-send-and-exit arg)
1796         (or
1797          ;; gcc group found ...
1798          (and gcc
1799               (save-current-buffer
1800                 (progn (set-buffer buf)
1801                        (setq id (org-remove-angle-brackets
1802                                  (mail-fetch-field "Message-ID")))
1803                        (setq to (mail-fetch-field "To"))
1804                        (setq from (mail-fetch-field "From"))
1805                        (setq subject (mail-fetch-field "Subject"))))
1806               (org-store-link-props :type "gnus" :from from :subject subject
1807                                     :message-id id :group gcc :to to)
1808               (setq desc (org-email-link-description))
1809               (setq link (org-gnus-article-link
1810                           gcc newsgroup id xarchive))
1811               (setq org-stored-links
1812                     (cons (list link desc) org-stored-links)))
1813          ;; no gcc group found ...
1814          (message "Can not create Org link: No Gcc header found."))))))
1816 (define-key message-mode-map [(control c) (control meta c)]
1817   'ulf-message-send-and-org-gnus-store-link)
1818 #+end_src
1820 ** Send html messages and attachments with Wanderlust
1821   -- David Maus
1823 /Note/: The module [[file:org-contrib/org-mime.org][Org-mime]] in Org's contrib directory provides
1824 similar functionality for both Wanderlust and Gnus.  The hack below is
1825 still somewhat different: It allows you to toggle sending of html
1826 messages within Wanderlust transparently.  I.e. html markup of the
1827 message body is created right before sending starts.
1829 *** Send HTML message
1831 Putting the code below in your .emacs adds following four functions:
1833 - dmj/wl-send-html-message
1835   Function that does the job: Convert everything between "--text
1836   follows this line--" and first mime entity (read: attachment) or
1837   end of buffer into html markup using `org-export-region-as-html'
1838   and replaces original body with a multipart MIME entity with the
1839   plain text version of body and the html markup version.  Thus a
1840   recipient that prefers html messages can see the html markup,
1841   recipients that prefer or depend on plain text can see the plain
1842   text.
1844   Cannot be called interactively: It is hooked into SEMI's
1845   `mime-edit-translate-hook' if message should be HTML message.
1847 - dmj/wl-send-html-message-draft-init
1849   Cannot be called interactively: It is hooked into WL's
1850   `wl-mail-setup-hook' and provides a buffer local variable to
1851   toggle.
1853 - dmj/wl-send-html-message-draft-maybe
1855   Cannot be called interactively: It is hooked into WL's
1856   `wl-draft-send-hook' and hooks `dmj/wl-send-html-message' into
1857   `mime-edit-translate-hook' depending on whether HTML message is
1858   toggled on or off
1860 - dmj/wl-send-html-message-toggle
1862   Toggles sending of HTML message.  If toggled on, the letters
1863   "HTML" appear in the mode line.
1865   Call it interactively!  Or bind it to a key in `wl-draft-mode'.
1867 If you have to send HTML messages regularly you can set a global
1868 variable `dmj/wl-send-html-message-toggled-p' to the string "HTML" to
1869 toggle on sending HTML message by default.
1871 The image [[http://s11.directupload.net/file/u/15851/48ru5wl3.png][here]] shows an example of how the HTML message looks like in
1872 Google's web front end.  As you can see you have the whole markup of
1873 Org at your service: *bold*, /italics/, tables, lists...
1875 So even if you feel uncomfortable with sending HTML messages at least
1876 you send HTML that looks quite good.
1878 #+begin_src emacs-lisp
1879 (defun dmj/wl-send-html-message ()
1880   "Send message as html message.
1881 Convert body of message to html using
1882   `org-export-region-as-html'."
1883   (require 'org)
1884   (save-excursion
1885     (let (beg end html text)
1886       (goto-char (point-min))
1887       (re-search-forward "^--text follows this line--$")
1888       ;; move to beginning of next line
1889       (beginning-of-line 2)
1890       (setq beg (point))
1891       (if (not (re-search-forward "^--\\[\\[" nil t))
1892           (setq end (point-max))
1893         ;; line up
1894         (end-of-line 0)
1895         (setq end (point)))
1896       ;; grab body
1897       (setq text (buffer-substring-no-properties beg end))
1898       ;; convert to html
1899       (with-temp-buffer
1900         (org-mode)
1901         (insert text)
1902         ;; handle signature
1903         (when (re-search-backward "^-- \n" nil t)
1904           ;; preserve link breaks in signature
1905           (insert "\n#+BEGIN_VERSE\n")
1906           (goto-char (point-max))
1907           (insert "\n#+END_VERSE\n")
1908           ;; grab html
1909           (setq html (org-export-region-as-html
1910                       (point-min) (point-max) t 'string))))
1911       (delete-region beg end)
1912       (insert
1913        (concat
1914         "--" "<<alternative>>-{\n"
1915         "--" "[[text/plain]]\n" text
1916         "--" "[[text/html]]\n"  html
1917         "--" "}-<<alternative>>\n")))))
1919 (defun dmj/wl-send-html-message-toggle ()
1920   "Toggle sending of html message."
1921   (interactive)
1922   (setq dmj/wl-send-html-message-toggled-p
1923         (if dmj/wl-send-html-message-toggled-p
1924             nil "HTML"))
1925   (message "Sending html message toggled %s"
1926            (if dmj/wl-send-html-message-toggled-p
1927                "on" "off")))
1929 (defun dmj/wl-send-html-message-draft-init ()
1930   "Create buffer local settings for maybe sending html message."
1931   (unless (boundp 'dmj/wl-send-html-message-toggled-p)
1932     (setq dmj/wl-send-html-message-toggled-p nil))
1933   (make-variable-buffer-local 'dmj/wl-send-html-message-toggled-p)
1934   (add-to-list 'global-mode-string
1935                '(:eval (if (eq major-mode 'wl-draft-mode)
1936                            dmj/wl-send-html-message-toggled-p))))
1938 (defun dmj/wl-send-html-message-maybe ()
1939   "Maybe send this message as html message.
1941 If buffer local variable `dmj/wl-send-html-message-toggled-p' is
1942 non-nil, add `dmj/wl-send-html-message' to
1943 `mime-edit-translate-hook'."
1944   (if dmj/wl-send-html-message-toggled-p
1945       (add-hook 'mime-edit-translate-hook 'dmj/wl-send-html-message)
1946     (remove-hook 'mime-edit-translate-hook 'dmj/wl-send-html-message)))
1948 (add-hook 'wl-draft-reedit-hook 'dmj/wl-send-html-message-draft-init)
1949 (add-hook 'wl-mail-setup-hook 'dmj/wl-send-html-message-draft-init)
1950 (add-hook 'wl-draft-send-hook 'dmj/wl-send-html-message-maybe)
1951 #+end_src
1953 *** Attach HTML of region or subtree
1955 Instead of sending a complete HTML message you might only send parts
1956 of an Org file as HTML for the poor souls who are plagued with
1957 non-proportional fonts in their mail program that messes up pretty
1958 ASCII tables.
1960 This short function does the trick: It exports region or subtree to
1961 HTML, prefixes it with a MIME entity delimiter and pushes to killring
1962 and clipboard.  If a region is active, it uses the region, the
1963 complete subtree otherwise.
1965 #+begin_src emacs-lisp
1966 (defun dmj/org-export-region-as-html-attachment (beg end arg)
1967   "Export region between BEG and END as html attachment.
1968 If BEG and END are not set, use current subtree.  Region or
1969 subtree is exported to html without header and footer, prefixed
1970 with a mime entity string and pushed to clipboard and killring.
1971 When called with prefix, mime entity is not marked as
1972 attachment."
1973   (interactive "r\nP")
1974   (save-excursion
1975     (let* ((beg (if (region-active-p) (region-beginning)
1976                   (progn
1977                     (org-back-to-heading)
1978                     (point))))
1979            (end (if (region-active-p) (region-end)
1980                   (progn
1981                     (org-end-of-subtree)
1982                     (point))))
1983            (html (concat "--[[text/html"
1984                          (if arg "" "\nContent-Disposition: attachment")
1985                          "]]\n"
1986                          (org-export-region-as-html beg end t 'string))))
1987       (when (fboundp 'x-set-selection)
1988         (ignore-errors (x-set-selection 'PRIMARY html))
1989         (ignore-errors (x-set-selection 'CLIPBOARD html)))
1990       (message "html export done, pushed to kill ring and clipboard"))))
1991 #+end_src
1993 *** Adopting for Gnus
1995 The whole magic lies in the special strings that mark a HTML
1996 attachment.  So you might just have to find out what these special
1997 strings are in message-mode and modify the functions accordingly.
1998 ** Add sunrise/sunset times to the agenda.
1999   -- Nick Dokos
2001 The diary package provides the function =diary-sunrise-sunset= which can be used
2002 in a diary s-expression in some agenda file like this:
2004 #+begin_src org-mode
2005 %%(diary-sunrise-sunset)
2006 #+end_src
2008 Seb Vauban asked if it is possible to put sunrise and sunset in
2009 separate lines. Here is a hack to do that. It adds two functions (they
2010 have to be available before the agenda is shown, so I add them early
2011 in my org-config file which is sourced from .emacs, but you'll have to
2012 suit yourself here) that just parse the output of
2013 diary-sunrise-sunset, instead of doing the right thing which would be
2014 to take advantage of the data structures that diary/solar.el provides.
2015 In short, a hack - so perfectly suited for inclusion here :-)
2017 The functions (and latitude/longitude settings which you have to modify for
2018 your location) are as follows:
2020 #+begin_src emacs-lisp
2021 (setq calendar-latitude 40.3)
2022 (setq calendar-longitude -71.0)
2023 (defun diary-sunrise ()
2024   (let ((dss (diary-sunrise-sunset)))
2025     (with-temp-buffer
2026       (insert dss)
2027       (goto-char (point-min))
2028       (while (re-search-forward " ([^)]*)" nil t)
2029         (replace-match "" nil nil))
2030       (goto-char (point-min))
2031       (search-forward ",")
2032       (buffer-substring (point-min) (match-beginning 0)))))
2034 (defun diary-sunset ()
2035   (let ((dss (diary-sunrise-sunset))
2036         start end)
2037     (with-temp-buffer
2038       (insert dss)
2039       (goto-char (point-min))
2040       (while (re-search-forward " ([^)]*)" nil t)
2041         (replace-match "" nil nil))
2042       (goto-char (point-min))
2043       (search-forward ", ")
2044       (setq start (match-end 0))
2045       (search-forward " at")
2046       (setq end (match-beginning 0))
2047       (goto-char start)
2048       (capitalize-word 1)
2049       (buffer-substring start end))))
2050 #+end_src
2052 You also need to add a couple of diary s-expressions in one of your agenda
2053 files:
2055 #+begin_src org-mode
2056 %%(diary-sunrise)
2057 %%(diary-sunset)
2058 #+end_src
2060 The thread on the mailing list that started this can be found [[http://thread.gmane.org/gmane.emacs.orgmode/38723Here%20is%20a%20pointer%20to%20the%20thread%20on%20the%20mailing%20list][here]].
2061 In comparison to the version posted on the mailing list, this one
2062 gets rid of the timezone information.
2063 * Hacking Org: Working with Org-mode and External Programs.
2064 ** Use Org-mode with Screen [Andrew Hyatt]
2066 "The general idea is that you start a task in which all the work will
2067 take place in a shell.  This usually is not a leaf-task for me, but
2068 usually the parent of a leaf task.  From a task in your org-file, M-x
2069 ash-org-screen will prompt for the name of a session.  Give it a name,
2070 and it will insert a link.  Open the link at any time to go the screen
2071 session containing your work!"
2073 http://article.gmane.org/gmane.emacs.orgmode/5276
2075 #+BEGIN_SRC emacs-lisp
2076 (require 'term)
2078 (defun ash-org-goto-screen (name)
2079   "Open the screen with the specified name in the window"
2080   (interactive "MScreen name: ")
2081   (let ((screen-buffer-name (ash-org-screen-buffer-name name)))
2082     (if (member screen-buffer-name
2083                 (mapcar 'buffer-name (buffer-list)))
2084         (switch-to-buffer screen-buffer-name)
2085       (switch-to-buffer (ash-org-screen-helper name "-dr")))))
2087 (defun ash-org-screen-buffer-name (name)
2088   "Returns the buffer name corresponding to the screen name given."
2089   (concat "*screen " name "*"))
2091 (defun ash-org-screen-helper (name arg)
2092   ;; Pick the name of the new buffer.
2093   (let ((term-ansi-buffer-name
2094          (generate-new-buffer-name
2095           (ash-org-screen-buffer-name name))))
2096     (setq term-ansi-buffer-name
2097           (term-ansi-make-term
2098            term-ansi-buffer-name "/usr/bin/screen" nil arg name))
2099     (set-buffer term-ansi-buffer-name)
2100     (term-mode)
2101     (term-char-mode)
2102     (term-set-escape-char ?\C-x)
2103     term-ansi-buffer-name))
2105 (defun ash-org-screen (name)
2106   "Start a screen session with name"
2107   (interactive "MScreen name: ")
2108   (save-excursion
2109     (ash-org-screen-helper name "-S"))
2110   (insert-string (concat "[[screen:" name "]]")))
2112 ;; And don't forget to add ("screen" . "elisp:(ash-org-goto-screen
2113 ;; \"%s\")") to org-link-abbrev-alist.
2114 #+END_SRC
2116 ** Org Agenda + Appt + Zenity
2117 #+BEGIN_HTML
2118 <a name="agenda-appt-zenity"></a>
2119 #+END_HTML
2120 Russell Adams posted this setup [[http://article.gmane.org/gmane.emacs.orgmode/5806][on the list]].  It makes sure your agenda
2121 appointments are known by Emacs, and it displays warnings in a [[http://live.gnome.org/Zenity][zenity]]
2122 popup window.
2124 #+BEGIN_SRC emacs-lisp
2125 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2126 ; For org appointment reminders
2128 ;; Get appointments for today
2129 (defun my-org-agenda-to-appt ()
2130   (interactive)
2131   (setq appt-time-msg-list nil)
2132   (let ((org-deadline-warning-days 0))    ;; will be automatic in org 5.23
2133         (org-agenda-to-appt)))
2135 ;; Run once, activate and schedule refresh
2136 (my-org-agenda-to-appt)
2137 (appt-activate t)
2138 (run-at-time "24:01" nil 'my-org-agenda-to-appt)
2140 ; 5 minute warnings
2141 (setq appt-message-warning-time 15)
2142 (setq appt-display-interval 5)
2144 ; Update appt each time agenda opened.
2145 (add-hook 'org-finalize-agenda-hook 'my-org-agenda-to-appt)
2147 ; Setup zenify, we tell appt to use window, and replace default function
2148 (setq appt-display-format 'window)
2149 (setq appt-disp-window-function (function my-appt-disp-window))
2151 (defun my-appt-disp-window (min-to-app new-time msg)
2152   (save-window-excursion (shell-command (concat
2153     "/usr/bin/zenity --info --title='Appointment' --text='"
2154     msg "' &") nil nil)))
2155 #+END_SRC
2157 ** Org-Mode + gnome-osd
2159 Richard Riley uses gnome-osd in interaction with Org-Mode to display
2160 appointments.  You can look at the code on the [[http://www.emacswiki.org/emacs-en/OrgMode-OSD][emacswiki]].
2162 ** remind2org
2164 From Detlef Steuer
2166 http://article.gmane.org/gmane.emacs.orgmode/5073
2168 #+BEGIN_QUOTE
2169 Remind (http://www.roaringpenguin.com/products/remind) is a very powerful
2170 command line calendaring program. Its features superseed the possibilities
2171 of orgmode in the area of date specifying, so that I want to use it
2172 combined with orgmode.
2174 Using the script below I'm able use remind and incorporate its output in my
2175 agenda views.  The default of using 13 months look ahead is easily
2176 changed. It just happens I sometimes like to look a year into the
2177 future. :-)
2178 #+END_QUOTE
2180 ** Useful webjumps for conkeror
2182 If you are using the [[http://conkeror.org][conkeror browser]], maybe you want to put this into
2183 your =~/.conkerorrc= file:
2185 #+begin_example
2186 define_webjump("orglist", "http://search.gmane.org/?query=%s&group=gmane.emacs.orgmode");
2187 define_webjump("worg", "http://www.google.com/cse?cx=002987994228320350715%3Az4glpcrritm&ie=UTF-8&q=%s&sa=Search&siteurl=orgmode.org%2Fworg%2F");
2188 #+end_example
2190 It creates two [[http://conkeror.org/Webjumps][webjumps]] for easily searching the Worg website and the
2191 Org-mode mailing list.
2193 ** Use MathJax for HTML export without requiring JavaScript
2194 As of 2010-08-14, MathJax is the default method used to export math to HTML.
2196 If you like the results but do not want JavaScript in the exported pages,
2197 check out [[http://www.jboecker.de/2010/08/15/staticmathjax.html][Static MathJax]], a XULRunner application which generates a static
2198 HTML file from the exported version. It can also embed all referenced fonts
2199 within the HTML file itself, so there are no dependencies to external files.
2201 The download archive contains an elisp file which integrates it into the Org
2202 export process (configurable per file with a "#+StaticMathJax:" line).
2204 Read README.org and the comments in org-static-mathjax.el for usage instructions.
2205 ** Search Org files using lgrep
2207 Matt Lundin suggests this:
2209 #+begin_src emacs-lisp
2210   (defun my-org-grep (search &optional context)
2211     "Search for word in org files.
2213 Prefix argument determines number of lines."
2214     (interactive "sSearch for: \nP")
2215     (let ((grep-find-ignored-files '("#*" ".#*"))
2216           (grep-template (concat "grep <X> -i -nH "
2217                                  (when context
2218                                    (concat "-C" (number-to-string context)))
2219                                  " -e <R> <F>")))
2220       (lgrep search "*org*" "/home/matt/org/")))
2222   (global-set-key (kbd "<f8>") 'my-org-grep)
2223 #+end_src
2225 ** Automatic screenshot insertion
2227 Suggested by Russell Adams
2229 #+begin_src emacs-lisp
2230   (defun my-org-screenshot ()
2231     "Take a screenshot into a time stamped unique-named file in the
2232   same directory as the org-buffer and insert a link to this file."
2233     (interactive)
2234     (setq filename
2235           (concat
2236            (make-temp-name
2237             (concat (buffer-file-name)
2238                     "_"
2239                     (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
2240     (call-process "import" nil nil nil filename)
2241     (insert (concat "[[" filename "]]"))
2242     (org-display-inline-images))
2243 #+end_src
2245 ** Capture invitations/appointments from MS Exchange emails
2247 Dirk-Jan C.Binnema [[http://article.gmane.org/gmane.emacs.orgmode/27684/][provided]] code to do this.  Please check
2248 [[file:code/elisp/org-exchange-capture.el][org-exchange-capture.el]]
2251 ** Audio/video file playback within org mode
2253 Paul Sexton provided code that makes =file:= links to audio or video files
2254 (MP3, WAV, OGG, AVI, MPG, et cetera) play those files using the [[https://github.com/dbrock/bongo][Bongo]] Emacs
2255 media player library. The user can pause, skip forward and backward in the
2256 track, and so on from without leaving Emacs. Links can also contain a time
2257 after a double colon -- when this is present, playback will begin at that
2258 position in the track.
2260 See the file [[file:code/elisp/org-player.el][org-player.el]]
2262 ** Under X11 Keep a window with the current agenda items at all time
2264 I struggle to keep (in emacs) a window with the agenda at all times.
2265 For a long time I have wanted a sticky window that keeps this
2266 information, and then use my window manager to place it and remove its
2267 decorations (I can also force its placement in the stack: top always,
2268 for example).
2270 I wrote a small program in qt that simply monitors an HTML file and
2271 displays it. Nothing more. It does the work for me, and maybe somebody
2272 else will find it useful. It relies on exporting the agenda as HTML
2273 every time the org file is saved, and then this little program
2274 displays the html file. The window manager is responsible of removing
2275 decorations, making it sticky, and placing it in same place always.
2277 Here is a screenshot (see window to the bottom right). The decorations
2278 are removed by the window manager:
2280 http://turingmachine.org/hacking/org-mode/orgdisplay.png
2282 Here is the code. As I said, very, very simple, but maybe somebody will
2283 find if useful.
2285 http://turingmachine.org/hacking/org-mode/
2287 --daniel german