Fix links to my homepage.
[worg.git] / org-hacks.org
blob41d8bc1bd6f8d5315b4fdbf1dd0ed63cd139e4e1
1 #+TITLE:      Org ad hoc code, quick hacks and workarounds
2 #+AUTHOR:     Worg people
3 #+EMAIL:      mdl AT imapmail DOT org
4 #+OPTIONS:    H:3 num:nil toc:t \n:nil ::t |:t ^:t -:t f:t *:t tex:t d:(HIDE) tags:not-in-toc
5 #+STARTUP:    align fold nodlcheck hidestars oddeven lognotestate
6 #+SEQ_TODO:   TODO(t) INPROGRESS(i) WAITING(w@) | DONE(d) CANCELED(c@)
7 #+TAGS:       Write(w) Update(u) Fix(f) Check(c)
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 ** Org Agenda
23 *** Picking up a random task in the global TODO list
25 Tony day [[http://mid.gmane.org/m2zk19l1me.fsf%2540gmail.com][shared]] [[https://gist.github.com/4343164][this gist]] to pick up a
26 random task.
28 ** Building and Managing Org
29 *** Generating autoloads and Compiling Org without make
30     :PROPERTIES:
31     :CUSTOM_ID: compiling-org-without-make
32     :END:
34 #+index: Compilation!without make
36   Compilation is optional, but you _must_ update the autoloads file
37   each time you update org, even when you run org uncompiled!
39   Starting with Org 7.9 you'll find functions for creating the
40   autoload files and do byte-compilation in =mk/org-fixup.el=.  When
41   you execute the commands below, your current directory must be where
42   org has been unpacked into, in other words the file =README= should
43   be found in your current directory and the directories =lisp= and
44   =etc= should be subdirectories of it.  The command =emacs= should be
45   found in your =PATH= and start the Emacs version you are using.  To
46   make just the autoloads file do:
47   : emacs -batch -Q -L lisp -l ../mk/org-fixup -f org-make-autoloads
48   To make the autoloads file and byte-compile org:
49   : emacs -batch -Q -L lisp -l ../mk/org-fixup -f org-make-autoloads-compile
50   To make the autoloads file and byte-compile all of org again:
51   : emacs -batch -Q -L lisp -l ../mk/org-fixup -f org-make-autoloads-compile-force
52   If you are not using Git, you'll have to make fake version strings
53   first if =org-version.el= is not already available (if it is, you
54   could also edit the version strings there).
55   : emacs -batch -Q -L lisp -l ../mk/org-fixup \
56   : --eval '(let ((org-fake-release "7.9.1")(org-fake-git-version "7.9.1-fake"))\
57   : (org-make-autoloads))'
58   The above assumes a
59   POSIX shell for its quoting.  Windows =CMD.exe= has quite different
60   quoting rules and this won't work, so your other option is to start
61   Emacs like this
62   : emacs -Q -L lisp -l ../mk/org-fixup
63   then paste the following into the =*scratch*= buffer
64 #+BEGIN_SRC emacs-lisp
65   (let ((org-fake-release     "7.9.1")
66         (org-fake-git-version "7.9.1-fake"))
67     (org-make-autoloads))
68 #+END_SRC
69   position the cursor after the closing paren and press =C-j= or =C-x
70   C-e= to evaluate the form.  Of course you can replace
71   =org-make-autoloads= with =org-make-autoloads-compile= or even
72   =org-make-autoloads-compile-force= if you wish with both variants.
74   For *older org versions only* (that do not yet have
75   =mk/org-fixup.el=), you can use the definitions below.  To use
76   this function, adjust the variables =my/org-lisp-directory= and
77   =my/org-compile-sources= to suit your needs.  If you have
78   byte-compiled org, but want to run org uncompiled again, just remove
79   all =*.elc= files in the =lisp/= directory, set
80   =my/org-compile-sources= to =nil=.
82 #+BEGIN_SRC emacs-lisp
83   (defvar my/org-lisp-directory "~/.emacs.d/org/lisp/"
84     "Directory where your org-mode files live.")
85   
86   (defvar my/org-compile-sources t
87     "If `nil', never compile org-sources. `my/compile-org' will only create
88   the autoloads file `org-loaddefs.el' then. If `t', compile the sources, too.")
89   
90   ;; Customize: (must end with a slash!)
91   (setq my/org-lisp-directory "~/.emacs.d/org/lisp/")
92   
93   ;; Customize:
94   (setq  my/org-compile-sources t)
95   
96   (defun my/compile-org(&optional directory)
97     "Generate autoloads file org-loaddefs.el.  Optionally compile
98      all *.el files that come with org-mode."
99     (interactive)
100     (defun my/compile-org()
101       "Generate autoloads file org-loaddefs.el.  Optionally compile
102        all *.el files that come with org-mode."
103       (interactive)
104       (let ((dirlisp (file-name-directory my/org-lisp-directory)))
105         (add-to-list 'load-path dirlisp)
106         (require 'autoload)
107         (let ((generated-autoload-file (concat dirlisp "org-loaddefs.el")))
108           ;; create the org-loaddefs file
109           (update-directory-autoloads dirlisp)
110           (when my/org-compile-sources
111             ;; optionally byte-compile
112             (byte-recompile-directory dirlisp 0 'force)))))
113   #+END_SRC
114 *** Reload Org
116 #+index: Initialization!Reload
118 As of Org version 6.23b (released Sunday Feb 22, 2009) there is a new
119 function to reload org files.
121 Normally you want to use the compiled files since they are faster.
122 If you update your org files you can easily reload them with
124 : M-x org-reload
126 If you run into a bug and want to generate a useful backtrace you can
127 reload the source files instead of the compiled files with
129 : C-u M-x org-reload
131 and turn on the "Enter Debugger On Error" option.  Redo the action
132 that generates the error and cut and paste the resulting backtrace.
133 To switch back to the compiled version just reload again with
135 : M-x org-reload
137 *** Check for possibly problematic old link escapes
138 :PROPERTIES:
139 :CUSTOM_ID: check-old-link-escapes
140 :END:
141 #+index: Link!Escape
142 Starting with version 7.5 Org uses [[http://en.wikipedia.org/wiki/Percent-encoding][percent escaping]] more consistently
143 and with a modified algorithm to determine which characters to escape
144 and how.
146 As a side effect this modified behaviour might break existing links if
147 they contain a sequence of characters that look like a percent escape
148 (e.g. =[0-9A-Fa-f]{2}=) but are in fact not a percent escape.
150 The function below can be used to perform a preliminary check for such
151 links in an Org mode file.  It will run through all links in the file
152 and issue a warning if it finds a percent escape sequence which is not
153 in old Org's list of known percent escapes.
155 #+begin_src emacs-lisp
156   (defun dmaus/org-check-percent-escapes ()
157     "*Check buffer for possibly problematic old link escapes."
158     (interactive)
159     (when (eq major-mode 'org-mode)
160       (let ((old-escapes '("%20" "%5B" "%5D" "%E0" "%E2" "%E7" "%E8" "%E9"
161                            "%EA" "%EE" "%F4" "%F9" "%FB" "%3B" "%3D" "%2B")))
162         (unless (boundp 'warning-suppress-types)
163           (setq warning-suppress-types nil))
164         (widen)
165         (show-all)
166         (goto-char (point-min))
167         (while (re-search-forward org-any-link-re nil t)
168           (let ((end (match-end 0)))
169             (goto-char (match-beginning 0))
170             (while (re-search-forward "%[0-9a-zA-Z]\\{2\\}" end t)
171               (let ((escape (match-string-no-properties 0)))
172                 (unless (member (upcase escape) old-escapes)
173                   (warn "Found unknown percent escape sequence %s at buffer %s, position %d"
174                         escape
175                         (buffer-name)
176                         (- (point) 3)))))
177             (goto-char end))))))
178 #+end_src
180 ** Structure Movement and Editing 
181 *** Show next/prev heading tidily
183 #+index: Navigation!Heading
184 - Dan Davison
185   These close the current heading and open the next/previous heading.
187 #+begin_src emacs-lisp
188 (defun ded/org-show-next-heading-tidily ()
189   "Show next entry, keeping other entries closed."
190   (if (save-excursion (end-of-line) (outline-invisible-p))
191       (progn (org-show-entry) (show-children))
192     (outline-next-heading)
193     (unless (and (bolp) (org-on-heading-p))
194       (org-up-heading-safe)
195       (hide-subtree)
196       (error "Boundary reached"))
197     (org-overview)
198     (org-reveal t)
199     (org-show-entry)
200     (show-children)))
202 (defun ded/org-show-previous-heading-tidily ()
203   "Show previous entry, keeping other entries closed."
204   (let ((pos (point)))
205     (outline-previous-heading)
206     (unless (and (< (point) pos) (bolp) (org-on-heading-p))
207       (goto-char pos)
208       (hide-subtree)
209       (error "Boundary reached"))
210     (org-overview)
211     (org-reveal t)
212     (org-show-entry)
213     (show-children)))
215 (setq org-use-speed-commands t)
216 (add-to-list 'org-speed-commands-user
217              '("n" ded/org-show-next-heading-tidily))
218 (add-to-list 'org-speed-commands-user
219              '("p" ded/org-show-previous-heading-tidily))
220 #+end_src
222 *** Promote all items in subtree
223 #+index: Structure Editing!Promote
224 - Matt Lundin
226 This function will promote all items in a subtree. Since I use
227 subtrees primarily to organize projects, the function is somewhat
228 unimaginatively called my-org-un-project:
230 #+begin_src emacs-lisp
231 (defun my-org-un-project ()
232   (interactive)
233   (org-map-entries 'org-do-promote "LEVEL>1" 'tree)
234   (org-cycle t))
235 #+end_src
237 *** Turn a heading into an Org link
238     :PROPERTIES:
239     :CUSTOM_ID: heading-to-link
240     :END:
241 #+index: Structure Editing!Heading
242 #+index: Link!Turn a heading into a
243 From David Maus:
245 #+begin_src emacs-lisp
246   (defun dmj:turn-headline-into-org-mode-link ()
247     "Replace word at point by an Org mode link."
248     (interactive)
249     (when (org-at-heading-p)
250       (let ((hl-text (nth 4 (org-heading-components))))
251         (unless (or (null hl-text)
252                     (org-string-match-p "^[ \t]*:[^:]+:$" hl-text))
253           (beginning-of-line)
254           (search-forward hl-text (point-at-eol))
255           (replace-string
256            hl-text
257            (format "[[file:%s.org][%s]]"
258                    (org-link-escape hl-text)
259                    (org-link-escape hl-text '((?\] . "%5D") (?\[ . "%5B"))))
260            nil (- (point) (length hl-text)) (point))))))
261 #+end_src
263 *** Using M-up and M-down to transpose paragraphs
264 #+index: Structure Editing!paragraphs
266 From Paul Sexton: By default, if used within ordinary paragraphs in
267 org mode, =M-up= and =M-down= transpose *lines* (not sentences).  The
268 following code makes these keys transpose paragraphs, keeping the
269 point at the start of the moved paragraph. Behavior in tables and
270 headings is unaffected. It would be easy to modify this to transpose
271 sentences.
273 #+begin_src emacs-lisp
274 (defun org-transpose-paragraphs (arg)
275  (interactive)
276  (when (and (not (or (org-at-table-p) (org-on-heading-p) (org-at-item-p)))
277             (thing-at-point 'sentence))
278    (transpose-paragraphs arg)
279    (backward-paragraph)
280    (re-search-forward "[[:graph:]]")
281    (goto-char (match-beginning 0))
282    t))
284 (add-to-list 'org-metaup-hook 
285  (lambda () (interactive) (org-transpose-paragraphs -1)))
286 (add-to-list 'org-metadown-hook 
287  (lambda () (interactive) (org-transpose-paragraphs 1)))
288 #+end_src
289 *** Changelog support for org headers
290 #+index: Structure Editing!Heading
291 -- James TD Smith
293 Put the following in your =.emacs=, and =C-x 4 a= and other functions which
294 use =add-log-current-defun= like =magit-add-log= will pick up the nearest org
295 headline as the "current function" if you add a changelog entry from an org
296 buffer.
298 #+BEGIN_SRC emacs-lisp
299   (defun org-log-current-defun ()
300     (save-excursion
301       (org-back-to-heading)
302       (if (looking-at org-complex-heading-regexp)
303           (match-string 4))))
305   (add-hook 'org-mode-hook
306             (lambda ()
307               (make-variable-buffer-local 'add-log-current-defun-function)
308               (setq add-log-current-defun-function 'org-log-current-defun)))
309 #+END_SRC
311 *** Different org-cycle-level behavior
312 #+index: Cycling!behavior
313 -- Ryan Thompson
315 In recent org versions, when your point (cursor) is at the end of an
316 empty header line (like after you first created the header), the TAB
317 key (=org-cycle=) has a special behavior: it cycles the headline through
318 all possible levels. However, I did not like the way it determined
319 "all possible levels," so I rewrote the whole function, along with a
320 couple of supporting functions.
322 The original function's definition of "all possible levels" was "every
323 level from 1 to one more than the initial level of the current
324 headline before you started cycling." My new definition is "every
325 level from 1 to one more than the previous headline's level." So, if
326 you have a headline at level 4 and you use ALT+RET to make a new
327 headline below it, it will cycle between levels 1 and 5, inclusive.
329 The main advantage of my custom =org-cycle-level= function is that it
330 is stateless: the next level in the cycle is determined entirely by
331 the contents of the buffer, and not what command you executed last.
332 This makes it more predictable, I hope.
334 #+BEGIN_SRC emacs-lisp
335 (require 'cl)
337 (defun org-point-at-end-of-empty-headline ()
338   "If point is at the end of an empty headline, return t, else nil."
339   (and (looking-at "[ \t]*$")
340        (save-excursion
341          (beginning-of-line 1)
342          (looking-at (concat "^\\(\\*+\\)[ \t]+\\(" org-todo-regexp "\\)?[ \t]*")))))
344 (defun org-level-increment ()
345   "Return the number of stars that will be added or removed at a
346 time to headlines when structure editing, based on the value of
347 `org-odd-levels-only'."
348   (if org-odd-levels-only 2 1))
350 (defvar org-previous-line-level-cached nil)
352 (defun org-recalculate-previous-line-level ()
353   "Same as `org-get-previous-line-level', but does not use cached
354 value. It does *set* the cached value, though."
355   (set 'org-previous-line-level-cached
356        (let ((current-level (org-current-level))
357              (prev-level (when (> (line-number-at-pos) 1)
358                            (save-excursion
359                              (previous-line)
360                              (org-current-level)))))
361          (cond ((null current-level) nil) ; Before first headline
362                ((null prev-level) 0)      ; At first headline
363                (prev-level)))))
365 (defun org-get-previous-line-level ()
366   "Return the outline depth of the last headline before the
367 current line. Returns 0 for the first headline in the buffer, and
368 nil if before the first headline."
369   ;; This calculation is quite expensive, with all the regex searching
370   ;; and stuff. Since org-cycle-level won't change lines, we can reuse
371   ;; the last value of this command.
372   (or (and (eq last-command 'org-cycle-level)
373            org-previous-line-level-cached)
374       (org-recalculate-previous-line-level)))
376 (defun org-cycle-level ()
377   (interactive)
378   (let ((org-adapt-indentation nil))
379     (when (org-point-at-end-of-empty-headline)
380       (setq this-command 'org-cycle-level) ;Only needed for caching
381       (let ((cur-level (org-current-level))
382             (prev-level (org-get-previous-line-level)))
383         (cond
384          ;; If first headline in file, promote to top-level.
385          ((= prev-level 0)
386           (loop repeat (/ (- cur-level 1) (org-level-increment))
387                 do (org-do-promote)))
388          ;; If same level as prev, demote one.
389          ((= prev-level cur-level)
390           (org-do-demote))
391          ;; If parent is top-level, promote to top level if not already.
392          ((= prev-level 1)
393           (loop repeat (/ (- cur-level 1) (org-level-increment))
394                 do (org-do-promote)))
395          ;; If top-level, return to prev-level.
396          ((= cur-level 1)
397           (loop repeat (/ (- prev-level 1) (org-level-increment))
398                 do (org-do-demote)))
399          ;; If less than prev-level, promote one.
400          ((< cur-level prev-level)
401           (org-do-promote))
402          ;; If deeper than prev-level, promote until higher than
403          ;; prev-level.
404          ((> cur-level prev-level)
405           (loop repeat (+ 1 (/ (- cur-level prev-level) (org-level-increment)))
406                 do (org-do-promote))))
407         t))))
408 #+END_SRC
410 *** Count words in an Org buffer
411 # FIXME: Does not fit too well under Structure. Any idea where to put it?
412 Paul Sexton [[http://article.gmane.org/gmane.emacs.orgmode/38014][posted]] this function to count words in an Org buffer:
414 #+begin_src emacs-lisp
415 (defun org-word-count (beg end
416                            &optional count-latex-macro-args?
417                            count-footnotes?)
418   "Report the number of words in the Org mode buffer or selected region.
419 Ignores:
420 - comments
421 - tables
422 - source code blocks (#+BEGIN_SRC ... #+END_SRC, and inline blocks)
423 - hyperlinks (but does count words in hyperlink descriptions)
424 - tags, priorities, and TODO keywords in headers
425 - sections tagged as 'not for export'.
427 The text of footnote definitions is ignored, unless the optional argument
428 COUNT-FOOTNOTES? is non-nil.
430 If the optional argument COUNT-LATEX-MACRO-ARGS? is non-nil, the word count
431 includes LaTeX macro arguments (the material between {curly braces}).
432 Otherwise, and by default, every LaTeX macro counts as 1 word regardless
433 of its arguments."
434   (interactive "r")
435   (unless mark-active
436     (setf beg (point-min)
437           end (point-max)))
438   (let ((wc 0)
439         (latex-macro-regexp "\\\\[A-Za-z]+\\(\\[[^]]*\\]\\|\\){\\([^}]*\\)}"))
440     (save-excursion
441       (goto-char beg)
442       (while (< (point) end)
443         (cond
444          ;; Ignore comments.
445          ((or (org-in-commented-line) (org-at-table-p))
446           nil)
447          ;; Ignore hyperlinks. But if link has a description, count
448          ;; the words within the description.
449          ((looking-at org-bracket-link-analytic-regexp)
450           (when (match-string-no-properties 5)
451             (let ((desc (match-string-no-properties 5)))
452               (save-match-data
453                 (incf wc (length (remove "" (org-split-string
454                                              desc "\\W")))))))
455           (goto-char (match-end 0)))
456          ((looking-at org-any-link-re)
457           (goto-char (match-end 0)))
458          ;; Ignore source code blocks.
459          ((org-in-regexps-block-p "^#\\+BEGIN_SRC\\W" "^#\\+END_SRC\\W")
460           nil)
461          ;; Ignore inline source blocks, counting them as 1 word.
462          ((save-excursion
463             (backward-char)
464             (looking-at org-babel-inline-src-block-regexp))
465           (goto-char (match-end 0))
466           (setf wc (+ 2 wc)))
467          ;; Count latex macros as 1 word, ignoring their arguments.
468          ((save-excursion
469             (backward-char)
470             (looking-at latex-macro-regexp))
471           (goto-char (if count-latex-macro-args?
472                          (match-beginning 2)
473                        (match-end 0)))
474           (setf wc (+ 2 wc)))
475          ;; Ignore footnotes.
476          ((and (not count-footnotes?)
477                (or (org-footnote-at-definition-p)
478                    (org-footnote-at-reference-p)))
479           nil)
480          (t
481           (let ((contexts (org-context)))
482             (cond
483              ;; Ignore tags and TODO keywords, etc.
484              ((or (assoc :todo-keyword contexts)
485                   (assoc :priority contexts)
486                   (assoc :keyword contexts)
487                   (assoc :checkbox contexts))
488               nil)
489              ;; Ignore sections marked with tags that are
490              ;; excluded from export.
491              ((assoc :tags contexts)
492               (if (intersection (org-get-tags-at) org-export-exclude-tags
493                                 :test 'equal)
494                   (org-forward-same-level 1)
495                 nil))
496              (t
497               (incf wc))))))
498         (re-search-forward "\\w+\\W*")))
499     (message (format "%d words in %s." wc
500                      (if mark-active "region" "buffer")))))
501 #+end_src
503 *** Check for misplaced SCHEDULED and DEADLINE cookies
505 The =SCHEDULED= and =DEADLINE= cookies should be used on the line *right
506 below* the headline -- like this:
508 #+begin_src org
509 ,* A headline
510   SCHEDULED: <2012-04-09 lun.>
511 #+end_src
513 This is what =org-scheduled= and =org-deadline= (and other similar
514 commands) do.  And the manual explicitely tell people to stick to this
515 format (see the section "8.3.1 Inserting deadlines or schedules").
517 If you think you might have subtrees with misplaced =SCHEDULED= and
518 =DEADLINE= cookies, this command lets you check the current buffer:
520 #+begin_src emacs-lisp
521 (defun org-check-misformatted-subtree ()
522   "Check misformatted entries in the current buffer."
523   (interactive)
524   (show-all)
525   (org-map-entries
526    (lambda ()
527      (when (and (move-beginning-of-line 2)
528                 (not (looking-at org-heading-regexp)))
529        (if (or (and (org-get-scheduled-time (point))
530                     (not (looking-at (concat "^.*" org-scheduled-regexp))))
531                (and (org-get-deadline-time (point))
532                     (not (looking-at (concat "^.*" org-deadline-regexp)))))
533            (when (y-or-n-p "Fix this subtree? ")
534              (message "Call the function again when you're done fixing this subtree.")
535              (recursive-edit))
536          (message "All subtrees checked."))))))
537 #+end_src
539 *** Sorting list by checkbox type
541 #+index: checkbox!sorting
543 You can use a custom function to sort list by checkbox type.
544 Here is a function suggested by Carsten:
546 #+BEGIN_SRC emacs-lisp
547 (defun org-sort-list-by-checkbox-type ()
548   "Sort list items according to Checkbox state."
549   (interactive)
550   (org-sort-list
551    nil ?f
552    (lambda ()
553      (if (looking-at org-list-full-item-re)
554          (cdr (assoc (match-string 3)
555                      '(("[X]" . 1) ("[-]" . 2) ("[ ]" . 3) (nil . 4))))
556        4))))
557 #+END_SRC
559 Use the function above directly on the list.  If you want to use an
560 equivalent function after =C-c ^ f=, use this one instead:
562 #+BEGIN_SRC emacs-lisp
563   (defun org-sort-list-by-checkbox-type-1 ()
564     (lambda ()
565       (if (looking-at org-list-full-item-re)
566           (cdr (assoc (match-string 3)
567                       '(("[X]" . 1) ("[-]" . 2) ("[ ]" . 3) (nil . 4))))
568         4)))
569 #+END_SRC
571 *** Adding Licenses to org files
572   You can add pretty standard licenses, such as creative commons or gfdl to org articles using [[file:code/elisp/org-license.el][org-license.el]].
573 ** Org Table
574    :PROPERTIES:
575    :CUSTOM_ID: Tables
576    :END:
578 *** Align all tables in a file
580 Andrew Young provided this function in [[http://thread.gmane.org/gmane.emacs.orgmode/58974/focus%3D58976][this thread]]:
582 #+begin_src emacs-lisp
583   (defun my-align-all-tables ()
584     (interactive)
585     (org-table-map-tables 'org-table-align 'quietly))
586 #+end_src
588 *** Transpose table
589 #+index: Table!Calculation
590     :PROPERTIES:
591     :CUSTOM_ID: transpose-table
592     :END:
594 Since Org 7.8, you can use =org-table-transpose-table-at-point= (which
595 see.)  There are also other solutions:
597 - with org-babel and Emacs Lisp: provided by Thomas S. Dye in the mailing
598   list, see [[http://thread.gmane.org/gmane.emacs.orgmode/23809/focus=23815][gmane]] or [[http://lists.gnu.org/archive/html/emacs-orgmode/2010-04/msg00239.html][gnu]]
600 - with org-babel and R: provided by Dan Davison in the mailing list (old
601   =#+TBLR:= syntax), see [[http://thread.gmane.org/gmane.emacs.orgmode/10159/focus=10159][gmane]] or [[http://lists.gnu.org/archive/html/emacs-orgmode/2008-12/msg00454.html][gnu]]
603 - with field coordinates in formulas (=@#= and =$#=): see [[file:org-hacks.org::#field-coordinates-in-formulas-transpose-table][Worg]].
605 *** Manipulate hours/minutes/seconds in table formulas
606 #+index: Table!hours-minutes-seconds
607 Both Bastien and Martin Halder have posted code ([[http://article.gmane.org/gmane.emacs.orgmode/39519][Bastien's code]] and
608 [[http://article.gmane.org/gmane.emacs.orgmode/39519][Martin's code]]) for interpreting =dd:dd= or =dd:dd:dd= strings (where
609 "=d=" is any digit) as time values in Org-mode table formula.  These
610 functions have now been wrapped up into a =with-time= macro which can
611 be used in table formula to translate table cell values to and from
612 numerical values for algebraic manipulation.
614 Here is the code implementing this macro.
615 #+begin_src emacs-lisp :results silent
616   (defun org-time-string-to-seconds (s)
617     "Convert a string HH:MM:SS to a number of seconds."
618     (cond
619      ((and (stringp s)
620            (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s))
621       (let ((hour (string-to-number (match-string 1 s)))
622             (min (string-to-number (match-string 2 s)))
623             (sec (string-to-number (match-string 3 s))))
624         (+ (* hour 3600) (* min 60) sec)))
625      ((and (stringp s)
626            (string-match "\\([0-9]+\\):\\([0-9]+\\)" s))
627       (let ((min (string-to-number (match-string 1 s)))
628             (sec (string-to-number (match-string 2 s))))
629         (+ (* min 60) sec)))
630      ((stringp s) (string-to-number s))
631      (t s)))
633   (defun org-time-seconds-to-string (secs)
634     "Convert a number of seconds to a time string."
635     (cond ((>= secs 3600) (format-seconds "%h:%.2m:%.2s" secs))
636           ((>= secs 60) (format-seconds "%m:%.2s" secs))
637           (t (format-seconds "%s" secs))))
639   (defmacro with-time (time-output-p &rest exprs)
640     "Evaluate an org-table formula, converting all fields that look
641   like time data to integer seconds.  If TIME-OUTPUT-P then return
642   the result as a time value."
643     (list
644      (if time-output-p 'org-time-seconds-to-string 'identity)
645      (cons 'progn
646            (mapcar
647             (lambda (expr)
648               `,(cons (car expr)
649                       (mapcar
650                        (lambda (el)
651                          (if (listp el)
652                              (list 'with-time nil el)
653                            (org-time-string-to-seconds el)))
654                        (cdr expr))))
655             `,@exprs))))
656 #+end_src
658 Which allows the following forms of table manipulation such as adding
659 and subtracting time values.
660 : | Date             | Start | Lunch |  Back |   End |  Sum |
661 : |------------------+-------+-------+-------+-------+------|
662 : | [2011-03-01 Tue] |  8:00 | 12:00 | 12:30 | 18:15 | 9:45 |
663 : #+TBLFM: $6='(with-time t (+ (- $5 $4) (- $3 $2)))
665 and dividing time values by integers
666 : |  time | miles | minutes/mile |
667 : |-------+-------+--------------|
668 : | 34:43 |   2.9 |        11:58 |
669 : | 32:15 |  2.77 |        11:38 |
670 : | 33:56 |   3.0 |        11:18 |
671 : | 52:22 |  4.62 |        11:20 |
672 : #+TBLFM: $3='(with-time t (/ $1 $2))
674 *Update*: As of Org version 7.6, you can use the =T= flag (both in Calc and
675 Elisp formulas) to compute time durations.  For example:
677 : | Task 1 | Task 2 |   Total |
678 : |--------+--------+---------|
679 : |  35:00 |  35:00 | 1:10:00 |
680 : #+TBLFM: @2$3=$1+$2;T
682 *** Dates computation
683 #+index: Table!dates
684 Xin Shi [[http://article.gmane.org/gmane.emacs.orgmode/15692][asked]] for a way to calculate the duration of 
685 dates stored in an org table.
687 Nick Dokos [[http://article.gmane.org/gmane.emacs.orgmode/15694][suggested]]:
689 Try the following:
691 : | Start Date |   End Date | Duration |
692 : |------------+------------+----------|
693 : | 2004.08.07 | 2005.07.08 |      335 |
694 : #+TBLFM: $3=(date(<$2>)-date(<$1>))
696 See [[http://thread.gmane.org/gmane.emacs.orgmode/7741][this thread]] as well as [[http://article.gmane.org/gmane.emacs.orgmode/7753][this post]] (which is really a followup on the
697 above).  The problem that this last article pointed out was solved in [[http://article.gmane.org/gmane.emacs.orgmode/8001][this
698 post]] and Chris Randle's original musings are [[http://article.gmane.org/gmane.emacs.orgmode/6536/][here]].
700 *** Hex computation
701 #+index: Table!Calculation
702 As with Times computation, the following code allows Computation with
703 Hex values in Org-mode tables using the =with-hex= macro.
705 Here is the code implementing this macro.
706 #+begin_src emacs-lisp
707   (defun org-hex-strip-lead (str)
708     (if (and (> (length str) 2) (string= (substring str 0 2) "0x"))
709         (substring str 2) str))
711   (defun org-hex-to-hex (int)
712     (format "0x%x" int))
714   (defun org-hex-to-dec (str)
715     (cond
716      ((and (stringp str)
717            (string-match "\\([0-9a-f]+\\)" (setf str (org-hex-strip-lead str))))
718       (let ((out 0))
719         (mapc
720          (lambda (ch)
721            (setf out (+ (* out 16)
722                         (if (and (>= ch 48) (<= ch 57)) (- ch 48) (- ch 87)))))
723          (coerce (match-string 1 str) 'list))
724         out))
725      ((stringp str) (string-to-number str))
726      (t str)))
728   (defmacro with-hex (hex-output-p &rest exprs)
729     "Evaluate an org-table formula, converting all fields that look
730       like hexadecimal to decimal integers.  If HEX-OUTPUT-P then
731       return the result as a hex value."
732     (list
733      (if hex-output-p 'org-hex-to-hex 'identity)
734      (cons 'progn
735            (mapcar
736             (lambda (expr)
737               `,(cons (car expr)
738                       (mapcar (lambda (el)
739                                 (if (listp el)
740                                     (list 'with-hex nil el)
741                                   (org-hex-to-dec el)))
742                               (cdr expr))))
743             `,@exprs))))
744 #+end_src
746 Which allows the following forms of table manipulation such as adding
747 and subtracting hex values.
748 | 0x10 | 0x0 | 0x10 |  16 |
749 | 0x20 | 0x1 | 0x21 |  33 |
750 | 0x30 | 0x2 | 0x32 |  50 |
751 | 0xf0 | 0xf | 0xff | 255 |
752 #+TBLFM: $3='(with-hex 'hex (+ $2 $1))::$4='(with-hex nil (identity $3))
754 *** Field coordinates in formulas (=@#= and =$#=)
755     :PROPERTIES:
756     :CUSTOM_ID: field-coordinates-in-formulas
757     :END:
758 #+index: Table!Field Coordinates
759 -- Michael Brand
761 Following are some use cases that can be implemented with the “field
762 coordinates in formulas” described in the corresponding chapter in the
763 [[http://orgmode.org/manual/References.html#References][Org manual]].
765 **** Copy a column from a remote table into a column
766      :PROPERTIES:
767      :CUSTOM_ID: field-coordinates-in-formulas-copy-col-to-col
768      :END:
770 current column =$3= = remote column =$2=:
771 : #+TBLFM: $3 = remote(FOO, @@#$2)
773 **** Copy a row from a remote table transposed into a column
774      :PROPERTIES:
775      :CUSTOM_ID: field-coordinates-in-formulas-copy-row-to-col
776      :END:
778 current column =$1= = transposed remote row =@1=:
779 : #+TBLFM: $1 = remote(FOO, @$#$@#)
781 **** Transpose table
782      :PROPERTIES:
783      :CUSTOM_ID: field-coordinates-in-formulas-transpose-table
784      :END:
786 -- Michael Brand
788 This is more like a demonstration of using “field coordinates in formulas”
789 and is bound to be slow for large tables. See the discussion in the mailing
790 list on
791 [[http://thread.gmane.org/gmane.emacs.orgmode/22610/focus=23662][gmane]] or
792 [[http://lists.gnu.org/archive/html/emacs-orgmode/2010-04/msg00086.html][gnu]].
793 For more efficient solutions see
794 [[file:org-hacks.org::#transpose-table][Worg]].
796 To transpose this 4x7 table
798 : #+TBLNAME: FOO
799 : | year | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 |
800 : |------+------+------+------+------+------+------|
801 : | min  |  401 |  501 |  601 |  701 |  801 |  901 |
802 : | avg  |  402 |  502 |  602 |  702 |  802 |  902 |
803 : | max  |  403 |  503 |  603 |  703 |  803 |  903 |
805 start with a 7x4 table without any horizontal line (to have filled
806 also the column header) and yet empty:
808 : |   |   |   |   |
809 : |   |   |   |   |
810 : |   |   |   |   |
811 : |   |   |   |   |
812 : |   |   |   |   |
813 : |   |   |   |   |
814 : |   |   |   |   |
816 Then add the =TBLFM= line below.  After recalculation this will end up with
817 the transposed copy:
819 : | year | min | avg | max |
820 : | 2004 | 401 | 402 | 403 |
821 : | 2005 | 501 | 502 | 503 |
822 : | 2006 | 601 | 602 | 603 |
823 : | 2007 | 701 | 702 | 703 |
824 : | 2008 | 801 | 802 | 803 |
825 : | 2009 | 901 | 902 | 903 |
826 : #+TBLFM: @<$<..@>$> = remote(FOO, @$#$@#)
828 The formula simply exchanges row and column numbers by taking
829 - the absolute remote row number =@$#= from the current column number =$#=
830 - the absolute remote column number =$@#= from the current row number =@#=
832 Formulas to be taken over from the remote table will have to be transformed
833 manually.
835 **** Dynamic variation of ranges
837 -- Michael Brand
839 In this example all columns next to =quote= are calculated from the column
840 =quote= and show the average change of the time series =quote[year]=
841 during the period of the preceding =1=, =2=, =3= or =4= years:
843 : | year | quote |   1 a |   2 a |   3 a |   4 a |
844 : |------+-------+-------+-------+-------+-------|
845 : | 2005 |    10 |       |       |       |       |
846 : | 2006 |    12 | 0.200 |       |       |       |
847 : | 2007 |    14 | 0.167 | 0.183 |       |       |
848 : | 2008 |    16 | 0.143 | 0.155 | 0.170 |       |
849 : | 2009 |    18 | 0.125 | 0.134 | 0.145 | 0.158 |
850 : #+TBLFM: @I$3..@>$>=if(@# >= $#, ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1, string("")) +.0; f-3
852 The important part of the formula without the field blanking is:
854 : ($2 / subscr(@-I$2..@+I$2, @# + 1 - $#)) ^ (1 / ($# - 2)) - 1
856 which is the Emacs Calc implementation of the equation
858 /AvgChange(i, a) = (quote[i] / quote[i - a]) ^ (1 / a) - 1/
860 where /i/ is the current time and /a/ is the length of the preceding period.
862 *** Rearrange one or more field within the same row or column
863 #+index: Table!Editing
864     :PROPERTIES:
865     :CUSTOM_ID: field-same-row-or-column
866     :END:
868 -- Michael Brand
870 **** Rearrange the column sequence in one row only
871 #+index: Table!Editing
872      :PROPERTIES:
873      :CUSTOM_ID: column-sequence-in-row
874      :END:
876 The functions below can be used to change the column sequence in one
877 row only, without affecting the other rows above and below like with
878 =M-<left>= or =M-<right>= (=org-table-move-column=).  See also the
879 docstring of the functions for more explanations.  The original table
880 that serves as the starting point for the examples:
882 : | a | b | c  | d  |
883 : | e | 9 | 10 | 11 |
884 : | f | g | h  | i  |
886 ***** Move current field in row
887 ****** Left
889 1) place point at "10" in original table
890 2) =M-x f-org-table-move-field-in-row-left=
891 3) point is at moved "10"
893 : | a | b  | c | d  |
894 : | e | 10 | 9 | 11 |
895 : | f | g  | h | i  |
897 ****** Right
899 1) place point at "9" in original table
900 2) =M-x f-org-table-move-field-in-row-right=
901 3) point is at moved "9"
903 : | a | b  | c | d  |
904 : | e | 10 | 9 | 11 |
905 : | f | g  | h | i  |
907 ***** Rotate rest of row (range from current field to end of row)
908 ****** Left
910 1) place point at @2$2 in original table
911 2) =M-x f-org-table-rotate-rest-of-row-left=
912 3) point is still at @2$2
914 : | a | b  | c  | d |
915 : | e | 10 | 11 | 9 |
916 : | f | g  | h  | i |
918 ****** Right
920 1) place point at @2$2 in original table
921 2) =M-x f-org-table-rotate-rest-of-row-right=
922 3) point is still at @2$2
924 : | a | b  | c | d  |
925 : | e | 11 | 9 | 10 |
926 : | f | g  | h | i  |
928 ***** Open field in row (table size grows)
930 This is just for completeness, interactively the same as typing =|
931 S-TAB=.
933 1) place point at @2$2 in original table
934 2) =M-x f-org-table-open-field-in-row-grow=
935 3) point is still at @2$2
937 : | a | b | c | d  |    |
938 : | e |   | 9 | 10 | 11 |
939 : | f | g | h | i  |    |
941 **** Rearrange the row sequence in one column only
942 #+index: Table!Editing
943      :PROPERTIES:
944      :CUSTOM_ID: row-sequence-in-column
945      :END:
947 The functions below can be used to change the column sequence in one
948 column only, without affecting the other columns left and right like
949 with =M-<up>= or =M-<down>= (=org-table-move-row=).  See also the
950 docstring of the functions for more explanations.  The original table
951 that serves as the starting point for the examples:
953 : | a |  b | c |
954 : |---+----+---|
955 : | d |  9 | e |
956 : | f | 10 | g |
957 : |---+----+---|
958 : | h | 11 | i |
960 ***** Move current field in column
961 ****** Up
963 1) place point at "10" in original table
964 2) =M-x f-org-table-move-field-in-column-up=
965 3) point is at moved "10"
967 : | a |  b | c |
968 : |---+----+---|
969 : | d | 10 | e |
970 : | f |  9 | g |
971 : |---+----+---|
972 : | h | 11 | i |
974 ****** Down
976 1) place point at "9" in original table
977 2) =M-x f-org-table-move-field-in-column-down=
978 3) point is at moved "9"
980 : | a |  b | c |
981 : |---+----+---|
982 : | d | 10 | e |
983 : | f |  9 | g |
984 : |---+----+---|
985 : | h | 11 | i |
987 ***** Rotate rest of column (range from current field to end of column)
988 ****** Up
990 1) place point at @2$2 in original table
991 2) =M-x f-org-table-rotate-rest-of-column-up=
992 3) point is still at @2$2
994 : | a |  b | c |
995 : |---+----+---|
996 : | d | 10 | e |
997 : | f | 11 | g |
998 : |---+----+---|
999 : | h |  9 | i |
1001 ****** Down
1003 1) place point at @2$2 in original table
1004 2) =M-x f-org-table-rotate-rest-of-column-down=
1005 3) point is still at @2$2
1007 : | a |  b | c |
1008 : |---+----+---|
1009 : | d | 11 | e |
1010 : | f |  9 | g |
1011 : |---+----+---|
1012 : | h | 10 | i |
1014 ***** Open field in column (table size grows)
1016 1) place point at @2$2 in original table
1017 2) =M-x f-org-table-open-field-in-column-grow=
1018 3) point is still at @2$2
1020 : | a |  b | c |
1021 : |---+----+---|
1022 : | d |    | e |
1023 : | f |  9 | g |
1024 : |---+----+---|
1025 : | h | 10 | i |
1026 : |   | 11 |   |
1028 **** Key bindings for some of the functions
1030 I have this in an Org buffer to change temporarily to the desired
1031 behavior with =C-c C-c= on one of the three code snippets:
1033 : - move in row:
1034 :   #+begin_src emacs-lisp :results silent
1035 :     (org-defkey org-mode-map [(meta left)]
1036 :                 'f-org-table-move-field-in-row-left)
1037 :     (org-defkey org-mode-map [(meta right)]
1038 :                 'f-org-table-move-field-in-row-right)
1039 :     (org-defkey org-mode-map [(left)]  'org-table-previous-field)
1040 :     (org-defkey org-mode-map [(right)] 'org-table-next-field)
1041 :   #+end_src
1043 : - rotate in row:
1044 :   #+begin_src emacs-lisp :results silent
1045 :     (org-defkey org-mode-map [(meta left)]
1046 :                 'f-org-table-rotate-rest-of-row-left)
1047 :     (org-defkey org-mode-map [(meta right)]
1048 :                 'f-org-table-rotate-rest-of-row-right)
1049 :     (org-defkey org-mode-map [(left)]  'org-table-previous-field)
1050 :     (org-defkey org-mode-map [(right)] 'org-table-next-field)
1051 :   #+end_src
1053 : - back to original:
1054 :   #+begin_src emacs-lisp :results silent
1055 :     (org-defkey org-mode-map [(meta left)]  'org-metaleft)
1056 :     (org-defkey org-mode-map [(meta right)] 'org-metaright)
1057 :     (org-defkey org-mode-map [(left)]  'backward-char)
1058 :     (org-defkey org-mode-map [(right)] 'forward-char)
1059 :   #+end_src
1061 **** Implementation
1063 The functions
1065 : f-org-table-move-field-in-column-up
1066 : f-org-table-move-field-in-column-down
1067 : f-org-table-rotate-rest-of-column-up
1068 : f-org-table-rotate-rest-of-column-down
1070 are not yet implemented.  They could be done similar to
1071 =f-org-table-open-field-in-column-grow=.  A workaround without keeping
1072 horizontal separator lines is to interactively or programmatically
1073 simply:
1075 1) Transpose the table, see
1076    [[http://orgmode.org/worg/org-hacks.html#transpose-table][Org hacks]].
1077 2) Use =f-org-table-*-column-in-row-*=, see
1078    [[http://orgmode.org/worg/org-hacks.html#column-sequence-in-row][previous
1079    section]].
1080 3) Transpose the table.
1082 The other functions:
1084 #+BEGIN_SRC emacs-lisp
1085   (defun f-org-table-move-field-in-row-left ()
1086     "Move current field in row to the left."
1087     (interactive)
1088     (f-org-table-move-field-in-row 'left))
1089   (defun f-org-table-move-field-in-row-right ()
1090     "Move current field in row to the right."
1091     (interactive)
1092     (f-org-table-move-field-in-row nil))
1094   (defun f-org-table-move-field-in-row (&optional left)
1095     "Move current field in row to the right.
1096   With arg LEFT, move to the left.  For repeated invocation the
1097   point follows the moved field.  Does not fix formulas."
1098     ;; Derived from `org-table-move-column'
1099     (interactive "P")
1100     (if (not (org-at-table-p))
1101         (error "Not at a table"))
1102     (org-table-find-dataline)
1103     (org-table-check-inside-data-field)
1104     (let* ((col (org-table-current-column))
1105            (col1 (if left (1- col) col))
1106            ;; Current cursor position
1107            (colpos (if left (1- col) (1+ col))))
1108       (if (and left (= col 1))
1109           (error "Cannot move column further left"))
1110       (if (and (not left) (looking-at "[^|\n]*|[^|\n]*$"))
1111           (error "Cannot move column further right"))
1112       (org-table-goto-column col1 t)
1113       (and (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|")
1114            (replace-match "|\\2|\\1|"))
1115       (org-table-goto-column colpos)
1116       (org-table-align)))
1118   (defun f-org-table-rotate-rest-of-row-left ()
1119     "Rotate rest of row to the left."
1120     (interactive)
1121     (f-org-table-rotate-rest-of-row 'left))
1122   (defun f-org-table-rotate-rest-of-row-right ()
1123     "Rotate rest of row to the right."
1124     (interactive)
1125     (f-org-table-rotate-rest-of-row nil))
1127   (defun f-org-table-rotate-rest-of-row (&optional left)
1128     "Rotate rest of row to the right.
1129   With arg LEFT, rotate to the left.  For both directions the
1130   boundaries of the rotation range are the current field and the
1131   field at the end of the row.  For repeated invocation the point
1132   stays on the original current field.  Does not fix formulas."
1133     ;; Derived from `org-table-move-column'
1134     (interactive "P")
1135     (if (not (org-at-table-p))
1136         (error "Not at a table"))
1137     (org-table-find-dataline)
1138     (org-table-check-inside-data-field)
1139     (let ((col (org-table-current-column)))
1140       (org-table-goto-column col t)
1141       (and (looking-at (if left
1142                            "|\\([^|\n]+\\)|\\([^\n]+\\)|$"
1143                          "|\\([^\n]+\\)|\\([^|\n]+\\)|$"))
1144            (replace-match "|\\2|\\1|"))
1145       (org-table-goto-column col)
1146       (org-table-align)))
1148   (defun f-org-table-open-field-in-row-grow ()
1149     "Open field in row, move fields to the right by growing table."
1150     (interactive)
1151     (insert "|")
1152     (backward-char)
1153     (org-table-align))
1155   (defun f-org-table-open-field-in-column-grow ()
1156     "Open field in column, move all fields downwards by growing table."
1157     (interactive)
1158     (let ((col (org-table-current-column))
1159           (p   (point)))
1160       ;; Cut all fields downwards in same column
1161       (goto-char (org-table-end))
1162       (forward-line -1)
1163       (while (org-at-table-hline-p) (forward-line -1))
1164       (org-table-goto-column col)
1165       (org-table-cut-region p (point))
1166       ;; Paste at one field below
1167       (goto-char p)
1168       (forward-line)
1169       (org-table-goto-column col)
1170       (org-table-paste-rectangle)
1171       (goto-char p)
1172       (org-table-align)))
1173 #+END_SRC
1175 **** Reasons why this is not put into the Org core
1177 I consider this as only a hack for several reasons:
1179 - Generalization: The existing function =org-table-move-column= could
1180   be enhanced with additional optional parameters to incorporate these
1181   functionalities and could be used as the only function for better
1182   maintainability.  Now it's only a copy/paste hack of several similar
1183   functions with simple modifications.
1184 - Bindings: Should be convenient for repetition like =M-<right>=.
1185   What should be bound where, what has to be left unbound?
1186 - Does not fix formulas.  Could be resolved for field formulas but
1187   most probably not for column or range formulas and this can lead to
1188   confusion.  AFAIK all table manipulations found in Org core fix
1189   formulas.
1190 - Completeness: Not all variations and combinations are covered yet
1191   - move, rotate with range to end, rotate with range to begin, rotate
1192     all
1193   - left-right, up-down
1195 ** Capture and Remember
1196 *** Customize the size of the frame for remember
1197 #+index: Remember!frame
1198 #+index: Customization!remember
1199 (Note: this hack is likely out of date due to the development of
1200 [[org-capture]].)
1202 # FIXME: gmane link?
1203 On emacs-orgmode, Ryan C. Thompson suggested this:
1205 #+begin_quote
1206 I am using org-remember set to open a new frame when used,
1207 and the default frame size is much too large. To fix this, I have
1208 designed some advice and a custom variable to implement custom
1209 parameters for the remember frame:
1210 #+end_quote
1212 #+begin_src emacs-lisp
1213 (defcustom remember-frame-alist nil
1214   "Additional frame parameters for dedicated remember frame."
1215   :type 'alist
1216   :group 'remember)
1218 (defadvice remember (around remember-frame-parameters activate)
1219   "Set some frame parameters for the remember frame."
1220   (let ((default-frame-alist (append remember-frame-alist
1221                                      default-frame-alist)))
1222     ad-do-it))
1223 #+end_src
1225 Setting remember-frame-alist to =((width . 80) (height . 15)))= give a
1226 reasonable size for the frame.
1227 ** Handling Links
1228 *** [[#heading-to-link][Turn a heading into an org link]] 
1229 *** Quickaccess to the link part of hyperlinks
1230 #+index: Link!Referent
1231 Christian Moe [[http://permalink.gmane.org/gmane.emacs.orgmode/43122][asked]], if there is a simpler way to copy the link part
1232 of an org hyperling other than to use `C-c C-l C-a C-k C-g', 
1233 which is indeed kind of cumbersome.
1235 The thread offered [[http://permalink.gmane.org/gmane.emacs.orgmode/43606][two ways]]:
1237 Using a [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Keyboard-Macros.html][keyboard macro]]:
1238 #+begin_src emacs-lisp
1239 (fset 'getlink
1240       (lambda (&optional arg) 
1241         "Keyboard macro." 
1242         (interactive "p") 
1243         (kmacro-exec-ring-item (quote ("\C-c\C-l\C-a\C-k\C-g" 0 "%d")) arg)))
1244 #+end_src
1246 or a function: 
1247 #+begin_src emacs-lisp
1248 (defun my-org-extract-link ()
1249   "Extract the link location at point and put it on the killring."
1250   (interactive)
1251   (when (org-in-regexp org-bracket-link-regexp 1)
1252     (kill-new (org-link-unescape (org-match-string-no-properties 1)))))
1253 #+end_src
1255 They put the link destination on the killring and can be easily bound to a key.
1257 *** Insert link with HTML title as default description
1258 When using `org-insert-link' (`C-c C-l') it might be useful to extract contents
1259 from HTML <title> tag and use it as a default link description. Here is a way to
1260 accomplish this:
1262 #+begin_src emacs-lisp
1263 (require 'mm-url) ; to include mm-url-decode-entities-string
1265 (defun my-org-insert-link ()
1266   "Insert org link where default description is set to html title."
1267   (interactive)
1268   (let* ((url (read-string "URL: "))
1269          (title (get-html-title-from-url url)))
1270     (org-insert-link nil url title)))
1272 (defun get-html-title-from-url (url)
1273   "Return content in <title> tag."
1274   (let (x1 x2 (download-buffer (url-retrieve-synchronously url)))
1275     (save-excursion
1276       (set-buffer download-buffer)
1277       (beginning-of-buffer)
1278       (setq x1 (search-forward "<title>"))
1279       (search-forward "</title>")
1280       (setq x2 (search-backward "<"))
1281       (mm-url-decode-entities-string (buffer-substring-no-properties x1 x2)))))
1282 #+end_src
1284 Then just use `M-x my-org-insert-link' instead of `org-insert-link'.
1286 ** Archiving Content in Org-Mode
1287 *** Preserve top level headings when archiving to a file
1288 #+index: Archiving!Preserve top level headings
1289 - Matt Lundin
1291 To preserve (somewhat) the integrity of your archive structure while
1292 archiving lower level items to a file, you can use the following
1293 defadvice:
1295 #+begin_src emacs-lisp
1296 (defadvice org-archive-subtree (around my-org-archive-subtree activate)
1297   (let ((org-archive-location
1298          (if (save-excursion (org-back-to-heading)
1299                              (> (org-outline-level) 1))
1300              (concat (car (split-string org-archive-location "::"))
1301                      "::* "
1302                      (car (org-get-outline-path)))
1303            org-archive-location)))
1304     ad-do-it))
1305 #+end_src
1307 Thus, if you have an outline structure such as...
1309 #+begin_src org
1310 ,* Heading
1311 ,** Subheading
1312 ,*** Subsubheading
1313 #+end_src
1315 ...archiving "Subsubheading" to a new file will set the location in
1316 the new file to the top level heading:
1318 #+begin_src org
1319 ,* Heading
1320 ,** Subsubheading
1321 #+end_src
1323 While this hack obviously destroys the outline hierarchy somewhat, it
1324 at least preserves the logic of level one groupings.
1326 A slightly more complex version of this hack will not only keep the
1327 archive organized by top-level headings, but will also preserve the
1328 tags found on those headings:
1330 #+begin_src emacs-lisp
1331   (defun my-org-inherited-no-file-tags ()
1332     (let ((tags (org-entry-get nil "ALLTAGS" 'selective))
1333           (ltags (org-entry-get nil "TAGS")))
1334       (mapc (lambda (tag)
1335               (setq tags
1336                     (replace-regexp-in-string (concat tag ":") "" tags)))
1337             (append org-file-tags (when ltags (split-string ltags ":" t))))
1338       (if (string= ":" tags) nil tags)))
1340   (defadvice org-archive-subtree (around my-org-archive-subtree-low-level activate)
1341     (let ((tags (my-org-inherited-no-file-tags))
1342           (org-archive-location
1343            (if (save-excursion (org-back-to-heading)
1344                                (> (org-outline-level) 1))
1345                (concat (car (split-string org-archive-location "::"))
1346                        "::* "
1347                        (car (org-get-outline-path)))
1348              org-archive-location)))
1349       ad-do-it
1350       (with-current-buffer (find-file-noselect (org-extract-archive-file))
1351         (save-excursion
1352           (while (org-up-heading-safe))
1353           (org-set-tags-to tags)))))
1354 #+end_src
1356 *** Archive in a date tree
1357 #+index: Archiving!date tree
1358 Posted to Org-mode mailing list by Osamu Okano [2010-04-21 Wed].
1360 (Make sure org-datetree.el is loaded for this to work.)
1362 #+begin_src emacs-lisp
1363 ;; (setq org-archive-location "%s_archive::date-tree")
1364 (defadvice org-archive-subtree
1365   (around org-archive-subtree-to-data-tree activate)
1366   "org-archive-subtree to date-tree"
1367   (if
1368       (string= "date-tree"
1369                (org-extract-archive-heading
1370                 (org-get-local-archive-location)))
1371       (let* ((dct (decode-time (org-current-time)))
1372              (y (nth 5 dct))
1373              (m (nth 4 dct))
1374              (d (nth 3 dct))
1375              (this-buffer (current-buffer))
1376              (location (org-get-local-archive-location))
1377              (afile (org-extract-archive-file location))
1378              (org-archive-location
1379               (format "%s::*** %04d-%02d-%02d %s" afile y m d
1380                       (format-time-string "%A" (encode-time 0 0 0 d m y)))))
1381         (message "afile=%s" afile)
1382         (unless afile
1383           (error "Invalid `org-archive-location'"))
1384         (save-excursion
1385           (switch-to-buffer (find-file-noselect afile))
1386           (org-datetree-find-year-create y)
1387           (org-datetree-find-month-create y m)
1388           (org-datetree-find-day-create y m d)
1389           (widen)
1390           (switch-to-buffer this-buffer))
1391         ad-do-it)
1392     ad-do-it))
1393 #+end_src
1395 *** Add inherited tags to archived entries
1396 #+index: Archiving!Add inherited tags
1397 To make =org-archive-subtree= keep inherited tags, Osamu OKANO suggests to
1398 advise the function like this:
1400 #+begin_example
1401 (defadvice org-archive-subtree
1402   (before add-inherited-tags-before-org-archive-subtree activate)
1403     "add inherited tags before org-archive-subtree"
1404     (org-set-tags-to (org-get-tags-at)))
1405 #+end_example
1407 ** Using and Managing Org-Metadata
1408 *** Remove redundant tags of headlines
1409 #+index: Tag!Remove redundant
1410 -- David Maus
1412 A small function that processes all headlines in current buffer and
1413 removes tags that are local to a headline and inherited by a parent
1414 headline or the #+FILETAGS: statement.
1416 #+BEGIN_SRC emacs-lisp
1417   (defun dmj/org-remove-redundant-tags ()
1418     "Remove redundant tags of headlines in current buffer.
1420   A tag is considered redundant if it is local to a headline and
1421   inherited by a parent headline."
1422     (interactive)
1423     (when (eq major-mode 'org-mode)
1424       (save-excursion
1425         (org-map-entries
1426          '(lambda ()
1427             (let ((alltags (split-string (or (org-entry-get (point) "ALLTAGS") "") ":"))
1428                   local inherited tag)
1429               (dolist (tag alltags)
1430                 (if (get-text-property 0 'inherited tag)
1431                     (push tag inherited) (push tag local)))
1432               (dolist (tag local)
1433                 (if (member tag inherited) (org-toggle-tag tag 'off)))))
1434          t nil))))
1435 #+END_SRC
1437 *** Remove empty property drawers
1438 #+index: Drawer!Empty
1439 David Maus proposed this:
1441 #+begin_src emacs-lisp
1442 (defun dmj:org:remove-empty-propert-drawers ()
1443   "*Remove all empty property drawers in current file."
1444   (interactive)
1445   (unless (eq major-mode 'org-mode)
1446     (error "You need to turn on Org mode for this function."))
1447   (save-excursion
1448     (goto-char (point-min))
1449     (while (re-search-forward ":PROPERTIES:" nil t)
1450       (save-excursion
1451         (org-remove-empty-drawer-at "PROPERTIES" (match-beginning 0))))))
1452 #+end_src
1454 *** Group task list by a property
1455 #+index: Agenda!Group task list
1456 This advice allows you to group a task list in Org-Mode.  To use it,
1457 set the variable =org-agenda-group-by-property= to the name of a
1458 property in the option list for a TODO or TAGS search.  The resulting
1459 agenda view will group tasks by that property prior to searching.
1461 #+begin_src emacs-lisp
1462 (defvar org-agenda-group-by-property nil
1463   "Set this in org-mode agenda views to group tasks by property")
1465 (defun org-group-bucket-items (prop items)
1466   (let ((buckets ()))
1467     (dolist (item items)
1468       (let* ((marker (get-text-property 0 'org-marker item))
1469              (pvalue (org-entry-get marker prop t))
1470              (cell (assoc pvalue buckets)))
1471         (if cell
1472             (setcdr cell (cons item (cdr cell)))
1473           (setq buckets (cons (cons pvalue (list item))
1474                               buckets)))))
1475     (setq buckets (mapcar (lambda (bucket)
1476                             (cons (car bucket)
1477                                   (reverse (cdr bucket))))
1478                           buckets))
1479     (sort buckets (lambda (i1 i2)
1480                     (string< (car i1) (car i2))))))
1482 (defadvice org-finalize-agenda-entries (around org-group-agenda-finalize
1483                                                (list &optional nosort))
1484   "Prepare bucketed agenda entry lists"
1485   (if org-agenda-group-by-property
1486       ;; bucketed, handle appropriately
1487       (let ((text ""))
1488         (dolist (bucket (org-group-bucket-items
1489                          org-agenda-group-by-property
1490                          list))
1491           (let ((header (concat "Property "
1492                                 org-agenda-group-by-property
1493                                 " is "
1494                                 (or (car bucket) "<nil>") ":\n")))
1495             (add-text-properties 0 (1- (length header))
1496                                  (list 'face 'org-agenda-structure)
1497                                  header)
1498             (setq text
1499                   (concat text header
1500                           ;; recursively process
1501                           (let ((org-agenda-group-by-property nil))
1502                             (org-finalize-agenda-entries
1503                              (cdr bucket) nosort))
1504                           "\n\n"))))
1505         (setq ad-return-value text))
1506     ad-do-it))
1507 (ad-activate 'org-finalize-agenda-entries)
1508 #+end_src
1509 *** A way to tag a task so that when clocking-out user is prompted to take a note.
1510 #+index: Tag!Clock
1511 #+index: Clock!Tag
1512     Thanks to Richard Riley (see [[http://permalink.gmane.org/gmane.emacs.orgmode/40896][this post on the mailing list]]).
1514 A small hook run when clocking out of a task that prompts for a note
1515 when the tag "=clockout_note=" is found in a headline. It uses the tag
1516 ("=clockout_note=") so inheritance can also be used...
1518 #+begin_src emacs-lisp
1519   (defun rgr/check-for-clock-out-note()
1520         (interactive)
1521         (save-excursion
1522           (org-back-to-heading)
1523           (let ((tags (org-get-tags)))
1524             (and tags (message "tags: %s " tags)
1525                  (when (member "clocknote" tags)
1526                    (org-add-note))))))
1528   (add-hook 'org-clock-out-hook 'rgr/check-for-clock-out-note)
1529 #+end_src
1530 *** Dynamically adjust tag position
1531 #+index: Tag!position
1532 Here is a bit of code that allows you to have the tags always
1533 right-adjusted in the buffer.
1535 This is useful when you have bigger window than default window-size
1536 and you dislike the aesthetics of having the tag in the middle of the
1537 line.
1539 This hack solves the problem of adjusting it whenever you change the
1540 window size.
1541 Before saving it will revert the file to having the tag position be
1542 left-adjusted so that if you track your files with version control,
1543 you won't run into artificial diffs just because the window-size
1544 changed.
1546 *IMPORTANT*: This is probably slow on very big files.
1548 #+begin_src emacs-lisp
1549 (setq ba/org-adjust-tags-column t)
1551 (defun ba/org-adjust-tags-column-reset-tags ()
1552   "In org-mode buffers it will reset tag position according to
1553 `org-tags-column'."
1554   (when (and
1555          (not (string= (buffer-name) "*Remember*"))
1556          (eql major-mode 'org-mode))
1557     (let ((b-m-p (buffer-modified-p)))
1558       (condition-case nil
1559           (save-excursion
1560             (goto-char (point-min))
1561             (command-execute 'outline-next-visible-heading)
1562             ;; disable (message) that org-set-tags generates
1563             (flet ((message (&rest ignored) nil))
1564               (org-set-tags 1 t))
1565             (set-buffer-modified-p b-m-p))
1566         (error nil)))))
1568 (defun ba/org-adjust-tags-column-now ()
1569   "Right-adjust `org-tags-column' value, then reset tag position."
1570   (set (make-local-variable 'org-tags-column)
1571        (- (- (window-width) (length org-ellipsis))))
1572   (ba/org-adjust-tags-column-reset-tags))
1574 (defun ba/org-adjust-tags-column-maybe ()
1575   "If `ba/org-adjust-tags-column' is set to non-nil, adjust tags."
1576   (when ba/org-adjust-tags-column
1577     (ba/org-adjust-tags-column-now)))
1579 (defun ba/org-adjust-tags-column-before-save ()
1580   "Tags need to be left-adjusted when saving."
1581   (when ba/org-adjust-tags-column
1582      (setq org-tags-column 1)
1583      (ba/org-adjust-tags-column-reset-tags)))
1585 (defun ba/org-adjust-tags-column-after-save ()
1586   "Revert left-adjusted tag position done by before-save hook."
1587   (ba/org-adjust-tags-column-maybe)
1588   (set-buffer-modified-p nil))
1590 ; automatically align tags on right-hand side
1591 (add-hook 'window-configuration-change-hook
1592           'ba/org-adjust-tags-column-maybe)
1593 (add-hook 'before-save-hook 'ba/org-adjust-tags-column-before-save)
1594 (add-hook 'after-save-hook 'ba/org-adjust-tags-column-after-save)
1595 (add-hook 'org-agenda-mode-hook '(lambda ()
1596                                   (setq org-agenda-tags-column (- (window-width)))))
1598 ; between invoking org-refile and displaying the prompt (which
1599 ; triggers window-configuration-change-hook) tags might adjust,
1600 ; which invalidates the org-refile cache
1601 (defadvice org-refile (around org-refile-disable-adjust-tags)
1602   "Disable dynamically adjusting tags"
1603   (let ((ba/org-adjust-tags-column nil))
1604     ad-do-it))
1605 (ad-activate 'org-refile)
1606 #+end_src
1607 *** Use an "attach" link type to open files without worrying about their location
1608 #+index: Link!Attach
1609 -- Darlan Cavalcante Moreira
1611 In the setup part in my org-files I put:
1613 #+begin_src org
1614 ,#+LINK: attach elisp:(org-open-file (org-attach-expand "%s"))
1615 #+end_src
1617 Now I can use the "attach" link type, but org will ask me if I want to
1618 allow executing the elisp code.  To avoid this you can even set
1619 org-confirm-elisp-link-function to nil (I don't like this because it allows
1620 any elisp code in links) or you can set org-confirm-elisp-link-not-regexp
1621 appropriately.
1623 In my case I use
1625 : (setq org-confirm-elisp-link-not-regexp "org-open-file")
1627 This works very well.
1629 ** Org Agenda and Task Management
1630 *** Make it easier to set org-agenda-files from multiple directories
1631 #+index: Agenda!Files
1632 - Matt Lundin
1634 #+begin_src emacs-lisp
1635 (defun my-org-list-files (dirs ext)
1636   "Function to create list of org files in multiple subdirectories.
1637 This can be called to generate a list of files for
1638 org-agenda-files or org-refile-targets.
1640 DIRS is a list of directories.
1642 EXT is a list of the extensions of files to be included."
1643   (let ((dirs (if (listp dirs)
1644                   dirs
1645                 (list dirs)))
1646         (ext (if (listp ext)
1647                  ext
1648                (list ext)))
1649         files)
1650     (mapc
1651      (lambda (x)
1652        (mapc
1653         (lambda (y)
1654           (setq files
1655                 (append files
1656                         (file-expand-wildcards
1657                          (concat (file-name-as-directory x) "*" y)))))
1658         ext))
1659      dirs)
1660     (mapc
1661      (lambda (x)
1662        (when (or (string-match "/.#" x)
1663                  (string-match "#$" x))
1664          (setq files (delete x files))))
1665      files)
1666     files))
1668 (defvar my-org-agenda-directories '("~/org/")
1669   "List of directories containing org files.")
1670 (defvar my-org-agenda-extensions '(".org")
1671   "List of extensions of agenda files")
1673 (setq my-org-agenda-directories '("~/org/" "~/work/"))
1674 (setq my-org-agenda-extensions '(".org" ".ref"))
1676 (defun my-org-set-agenda-files ()
1677   (interactive)
1678   (setq org-agenda-files (my-org-list-files
1679                           my-org-agenda-directories
1680                           my-org-agenda-extensions)))
1682 (my-org-set-agenda-files)
1683 #+end_src
1685 The code above will set your "default" agenda files to all files
1686 ending in ".org" and ".ref" in the directories "~/org/" and "~/work/".
1687 You can change these values by setting the variables
1688 my-org-agenda-extensions and my-org-agenda-directories. The function
1689 my-org-agenda-files-by-filetag uses these two variables to determine
1690 which files to search for filetags (i.e., the larger set from which
1691 the subset will be drawn).
1693 You can also easily use my-org-list-files to "mix and match"
1694 directories and extensions to generate different lists of agenda
1695 files.
1697 *** Restrict org-agenda-files by filetag
1698 #+index: Agenda!Files
1699   :PROPERTIES:
1700   :CUSTOM_ID: set-agenda-files-by-filetag
1701   :END:
1702 - Matt Lundin
1704 It is often helpful to limit yourself to a subset of your agenda
1705 files. For instance, at work, you might want to see only files related
1706 to work (e.g., bugs, clientA, projectxyz, etc.). The FAQ has helpful
1707 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
1708 commands]]. These solutions, however, require reapplying a filter each
1709 time you call the agenda or writing several new custom agenda commands
1710 for each context. Another solution is to use directories for different
1711 types of tasks and to change your agenda files with a function that
1712 sets org-agenda-files to the appropriate directory. But this relies on
1713 hard and static boundaries between files.
1715 The following functions allow for a more dynamic approach to selecting
1716 a subset of files based on filetags:
1718 #+begin_src emacs-lisp
1719 (defun my-org-agenda-restrict-files-by-filetag (&optional tag)
1720   "Restrict org agenda files only to those containing filetag."
1721   (interactive)
1722   (let* ((tagslist (my-org-get-all-filetags))
1723          (ftag (or tag
1724                    (completing-read "Tag: "
1725                                     (mapcar 'car tagslist)))))
1726     (org-agenda-remove-restriction-lock 'noupdate)
1727     (put 'org-agenda-files 'org-restrict (cdr (assoc ftag tagslist)))
1728     (setq org-agenda-overriding-restriction 'files)))
1730 (defun my-org-get-all-filetags ()
1731   "Get list of filetags from all default org-files."
1732   (let ((files org-agenda-files)
1733         tagslist x)
1734     (save-window-excursion
1735       (while (setq x (pop files))
1736         (set-buffer (find-file-noselect x))
1737         (mapc
1738          (lambda (y)
1739            (let ((tagfiles (assoc y tagslist)))
1740              (if tagfiles
1741                  (setcdr tagfiles (cons x (cdr tagfiles)))
1742                (add-to-list 'tagslist (list y x)))))
1743          (my-org-get-filetags)))
1744       tagslist)))
1746 (defun my-org-get-filetags ()
1747   "Get list of filetags for current buffer"
1748   (let ((ftags org-file-tags)
1749         x)
1750     (mapcar
1751      (lambda (x)
1752        (org-substring-no-properties x))
1753      ftags)))
1754 #+end_src
1756 Calling my-org-agenda-restrict-files-by-filetag results in a prompt
1757 with all filetags in your "normal" agenda files. When you select a
1758 tag, org-agenda-files will be restricted to only those files
1759 containing the filetag. To release the restriction, type C-c C-x >
1760 (org-agenda-remove-restriction-lock).
1762 *** Highlight the agenda line under cursor
1763 #+index: Agenda!Highlight
1764 This is useful to make sure what task you are operating on.
1766 #+BEGIN_SRC emacs-lisp
1767 (add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))
1768 #+END_SRC
1770 Under XEmacs:
1772 #+BEGIN_SRC emacs-lisp
1773 ;; hl-line seems to be only for emacs
1774 (require 'highline)
1775 (add-hook 'org-agenda-mode-hook '(lambda () (highline-mode 1)))
1777 ;; highline-mode does not work straightaway in tty mode.
1778 ;; I use a black background
1779 (custom-set-faces
1780   '(highline-face ((((type tty) (class color))
1781                     (:background "white" :foreground "black")))))
1782 #+END_SRC
1784 *** Split frame horizontally for agenda
1785 #+index: Agenda!frame
1786 If you would like to split the frame into two side-by-side windows when
1787 displaying the agenda, try this hack from Jan Rehders, which uses the
1788 `toggle-window-split' from
1790 http://www.emacswiki.org/cgi-bin/wiki/ToggleWindowSplit
1792 #+BEGIN_SRC emacs-lisp
1793 ;; Patch org-mode to use vertical splitting
1794 (defadvice org-prepare-agenda (after org-fix-split)
1795   (toggle-window-split))
1796 (ad-activate 'org-prepare-agenda)
1797 #+END_SRC
1799 *** Automatically add an appointment when clocking in a task
1800 #+index: Clock!Automatically add an appointment when clocking in a task
1801 #+index: Appointment!Automatically add an appointment when clocking in a task
1802 #+BEGIN_SRC emacs-lisp
1803 ;; Make sure you have a sensible value for `appt-message-warning-time'
1804 (defvar bzg-org-clock-in-appt-delay 100
1805   "Number of minutes for setting an appointment by clocking-in")
1806 #+END_SRC
1808 This function let's you add an appointment for the current entry.
1809 This can be useful when you need a reminder.
1811 #+BEGIN_SRC emacs-lisp
1812 (defun bzg-org-clock-in-add-appt (&optional n)
1813   "Add an appointment for the Org entry at point in N minutes."
1814   (interactive)
1815   (save-excursion
1816     (org-back-to-heading t)
1817     (looking-at org-complex-heading-regexp)
1818     (let* ((msg (match-string-no-properties 4))
1819            (ct-time (decode-time))
1820            (appt-min (+ (cadr ct-time)
1821                         (or n bzg-org-clock-in-appt-delay)))
1822            (appt-time ; define the time for the appointment
1823             (progn (setf (cadr ct-time) appt-min) ct-time)))
1824       (appt-add (format-time-string
1825                  "%H:%M" (apply 'encode-time appt-time)) msg)
1826       (if (interactive-p) (message "New appointment for %s" msg)))))
1827 #+END_SRC
1829 You can advise =org-clock-in= so that =C-c C-x C-i= will automatically
1830 add an appointment:
1832 #+BEGIN_SRC emacs-lisp
1833 (defadvice org-clock-in (after org-clock-in-add-appt activate)
1834   "Add an appointment when clocking a task in."
1835   (bzg-org-clock-in-add-appt))
1836 #+END_SRC
1838 You may also want to delete the associated appointment when clocking
1839 out.  This function does this:
1841 #+BEGIN_SRC emacs-lisp
1842 (defun bzg-org-clock-out-delete-appt nil
1843   "When clocking out, delete any associated appointment."
1844   (interactive)
1845   (save-excursion
1846     (org-back-to-heading t)
1847     (looking-at org-complex-heading-regexp)
1848     (let* ((msg (match-string-no-properties 4)))
1849       (setq appt-time-msg-list
1850             (delete nil
1851                     (mapcar
1852                      (lambda (appt)
1853                        (if (not (string-match (regexp-quote msg)
1854                                               (cadr appt))) appt))
1855                      appt-time-msg-list)))
1856       (appt-check))))
1857 #+END_SRC
1859 And here is the advice for =org-clock-out= (=C-c C-x C-o=)
1861 #+BEGIN_SRC emacs-lisp
1862 (defadvice org-clock-out (before org-clock-out-delete-appt activate)
1863   "Delete an appointment when clocking a task out."
1864   (bzg-org-clock-out-delete-appt))
1865 #+END_SRC
1867 *IMPORTANT*: You can add appointment by clocking in in both an
1868 =org-mode= and an =org-agenda-mode= buffer.  But clocking out from
1869 agenda buffer with the advice above will bring an error.
1871 *** Using external programs for appointments reminders
1872 #+index: Appointment!reminders
1873 Read this rich [[http://comments.gmane.org/gmane.emacs.orgmode/46641][thread]] from the org-mode list.
1875 *** Remove from agenda time grid lines that are in an appointment
1876 #+index: Agenda!time grid
1877 #+index: Appointment!Remove from agenda time grid lines
1878 The agenda shows lines for the time grid.  Some people think that
1879 these lines are a distraction when there are appointments at those
1880 times.  You can get rid of the lines which coincide exactly with the
1881 beginning of an appointment.  Michael Ekstrand has written a piece of
1882 advice that also removes lines that are somewhere inside an
1883 appointment:
1885 #+begin_src emacs-lisp
1886 (defun org-time-to-minutes (time)
1887   "Convert an HHMM time to minutes"
1888   (+ (* (/ time 100) 60) (% time 100)))
1890 (defun org-time-from-minutes (minutes)
1891   "Convert a number of minutes to an HHMM time"
1892   (+ (* (/ minutes 60) 100) (% minutes 60)))
1894 (defadvice org-agenda-add-time-grid-maybe (around mde-org-agenda-grid-tweakify
1895                                                   (list ndays todayp))
1896   (if (member 'remove-match (car org-agenda-time-grid))
1897       (flet ((extract-window
1898               (line)
1899               (let ((start (get-text-property 1 'time-of-day line))
1900                     (dur (get-text-property 1 'duration line)))
1901                 (cond
1902                  ((and start dur)
1903                   (cons start
1904                         (org-time-from-minutes
1905                          (+ dur (org-time-to-minutes start)))))
1906                  (start start)
1907                  (t nil)))))
1908         (let* ((windows (delq nil (mapcar 'extract-window list)))
1909                (org-agenda-time-grid
1910                 (list (car org-agenda-time-grid)
1911                       (cadr org-agenda-time-grid)
1912                       (remove-if
1913                        (lambda (time)
1914                          (find-if (lambda (w)
1915                                     (if (numberp w)
1916                                         (equal w time)
1917                                       (and (>= time (car w))
1918                                            (< time (cdr w)))))
1919                                   windows))
1920                        (caddr org-agenda-time-grid)))))
1921           ad-do-it))
1922     ad-do-it))
1923 (ad-activate 'org-agenda-add-time-grid-maybe)
1924 #+end_src
1925 *** Disable version control for Org mode agenda files
1926 #+index: Agenda!Files
1927 -- David Maus
1929 Even if you use Git to track your agenda files you might not need
1930 vc-mode to be enabled for these files.
1932 #+begin_src emacs-lisp
1933 (add-hook 'find-file-hook 'dmj/disable-vc-for-agenda-files-hook)
1934 (defun dmj/disable-vc-for-agenda-files-hook ()
1935   "Disable vc-mode for Org agenda files."
1936   (if (and (fboundp 'org-agenda-file-p)
1937            (org-agenda-file-p (buffer-file-name)))
1938       (remove-hook 'find-file-hook 'vc-find-file-hook)
1939     (add-hook 'find-file-hook 'vc-find-file-hook)))
1940 #+end_src
1942 *** Easy customization of TODO colors
1943 #+index: Customization!Todo keywords
1944 #+index: Todo keywords!Customization
1946 -- Ryan C. Thompson
1948 Here is some code I came up with some code to make it easier to
1949 customize the colors of various TODO keywords. As long as you just
1950 want a different color and nothing else, you can customize the
1951 variable org-todo-keyword-faces and use just a string color (i.e. a
1952 string of the color name) as the face, and then org-get-todo-face
1953 will convert the color to a face, inheriting everything else from
1954 the standard org-todo face.
1956 To demonstrate, I currently have org-todo-keyword-faces set to
1958 #+BEGIN_SRC emacs-lisp
1959 (("IN PROGRESS" . "dark orange")
1960  ("WAITING" . "red4")
1961  ("CANCELED" . "saddle brown"))
1962 #+END_SRC
1964   Here's the code, in a form you can put in your =.emacs=
1966 #+BEGIN_SRC emacs-lisp
1967 (eval-after-load 'org-faces
1968  '(progn
1969     (defcustom org-todo-keyword-faces nil
1970       "Faces for specific TODO keywords.
1971 This is a list of cons cells, with TODO keywords in the car and
1972 faces in the cdr.  The face can be a symbol, a color, or a
1973 property list of attributes, like (:foreground \"blue\" :weight
1974 bold :underline t)."
1975       :group 'org-faces
1976       :group 'org-todo
1977       :type '(repeat
1978               (cons
1979                (string :tag "Keyword")
1980                (choice color (sexp :tag "Face")))))))
1982 (eval-after-load 'org
1983  '(progn
1984     (defun org-get-todo-face-from-color (color)
1985       "Returns a specification for a face that inherits from org-todo
1986  face and has the given color as foreground. Returns nil if
1987  color is nil."
1988       (when color
1989         `(:inherit org-warning :foreground ,color)))
1991     (defun org-get-todo-face (kwd)
1992       "Get the right face for a TODO keyword KWD.
1993 If KWD is a number, get the corresponding match group."
1994       (if (numberp kwd) (setq kwd (match-string kwd)))
1995       (or (let ((face (cdr (assoc kwd org-todo-keyword-faces))))
1996             (if (stringp face)
1997                 (org-get-todo-face-from-color face)
1998               face))
1999           (and (member kwd org-done-keywords) 'org-done)
2000           'org-todo))))
2001 #+END_SRC
2003 *** Add an effort estimate on the fly when clocking in
2004 #+index: Effort estimate!Add when clocking in
2005 #+index: Clock!Effort estimate
2006 You can use =org-clock-in-prepare-hook= to add an effort estimate.
2007 This way you can easily have a "tea-timer" for your tasks when they
2008 don't already have an effort estimate.
2010 #+begin_src emacs-lisp
2011 (add-hook 'org-clock-in-prepare-hook
2012           'my-org-mode-ask-effort)
2014 (defun my-org-mode-ask-effort ()
2015   "Ask for an effort estimate when clocking in."
2016   (unless (org-entry-get (point) "Effort")
2017     (let ((effort
2018            (completing-read
2019             "Effort: "
2020             (org-entry-get-multivalued-property (point) "Effort"))))
2021       (unless (equal effort "")
2022         (org-set-property "Effort" effort)))))
2023 #+end_src
2025 Or you can use a default effort for such a timer:
2027 #+begin_src emacs-lisp
2028 (add-hook 'org-clock-in-prepare-hook
2029           'my-org-mode-add-default-effort)
2031 (defvar org-clock-default-effort "1:00")
2033 (defun my-org-mode-add-default-effort ()
2034   "Add a default effort estimation."
2035   (unless (org-entry-get (point) "Effort")
2036     (org-set-property "Effort" org-clock-default-effort)))
2037 #+end_src
2039 *** Use idle timer for automatic agenda views
2040 #+index: Agenda view!Refresh
2041 From John Wiegley's mailing list post (March 18, 2010):
2043 #+begin_quote
2044 I have the following snippet in my .emacs file, which I find very
2045 useful. Basically what it does is that if I don't touch my Emacs for 5
2046 minutes, it displays the current agenda. This keeps my tasks "always
2047 in mind" whenever I come back to Emacs after doing something else,
2048 whereas before I had a tendency to forget that it was there.
2049 #+end_quote
2051   - [[http://mid.gmane.org/55590EA7-C744-44E5-909F-755F0BBE452D@gmail.com][John Wiegley: Displaying your Org agenda after idle time]]
2053 #+begin_src emacs-lisp
2054 (defun jump-to-org-agenda ()
2055   (interactive)
2056   (let ((buf (get-buffer "*Org Agenda*"))
2057         wind)
2058     (if buf
2059         (if (setq wind (get-buffer-window buf))
2060             (select-window wind)
2061           (if (called-interactively-p)
2062               (progn
2063                 (select-window (display-buffer buf t t))
2064                 (org-fit-window-to-buffer)
2065                 ;; (org-agenda-redo)
2066                 )
2067             (with-selected-window (display-buffer buf)
2068               (org-fit-window-to-buffer)
2069               ;; (org-agenda-redo)
2070               )))
2071       (call-interactively 'org-agenda-list)))
2072   ;;(let ((buf (get-buffer "*Calendar*")))
2073   ;;  (unless (get-buffer-window buf)
2074   ;;    (org-agenda-goto-calendar)))
2075   )
2077 (run-with-idle-timer 300 t 'jump-to-org-agenda)
2078 #+end_src
2080 #+results:
2081 : [nil 0 300 0 t jump-to-org-agenda nil idle]
2083 *** Refresh the agenda view regularly
2084 #+index: Agenda view!Refresh
2085 Hack sent by Kiwon Um:
2087 #+begin_src emacs-lisp
2088 (defun kiwon/org-agenda-redo-in-other-window ()
2089   "Call org-agenda-redo function even in the non-agenda buffer."
2090   (interactive)
2091   (let ((agenda-window (get-buffer-window org-agenda-buffer-name t)))
2092     (when agenda-window
2093       (with-selected-window agenda-window (org-agenda-redo)))))
2094 (run-at-time nil 300 'kiwon/org-agenda-redo-in-other-window)
2095 #+end_src
2097 *** Reschedule agenda items to today with a single command
2098 #+index: Agenda!Reschedule
2099 This was suggested by Carsten in reply to David Abrahams:
2101 #+begin_example emacs-lisp
2102 (defun org-agenda-reschedule-to-today ()
2103   (interactive)
2104   (flet ((org-read-date (&rest rest) (current-time)))
2105     (call-interactively 'org-agenda-schedule)))
2106 #+end_example
2108 *** Mark subtree DONE along with all subheadings
2109 #+index: Subtree!subheadings
2110 Bernt Hansen [[http://permalink.gmane.org/gmane.emacs.orgmode/44693][suggested]] this command:
2112 #+begin_src emacs-lisp
2113 (defun bh/mark-subtree-done ()
2114   (interactive)
2115   (org-mark-subtree)
2116   (let ((limit (point)))
2117     (save-excursion
2118       (exchange-point-and-mark)
2119       (while (> (point) limit)
2120         (org-todo "DONE")
2121         (outline-previous-visible-heading 1))
2122       (org-todo "DONE"))))
2123 #+end_src
2125 Then M-x bh/mark-subtree-done.
2127 *** Mark heading done when all checkboxes are checked.
2128     :PROPERTIES:
2129     :CUSTOM_ID: mark-done-when-all-checkboxes-checked
2130     :END:
2132 #+index: Checkbox
2134 An item consists of a list with checkboxes.  When all of the
2135 checkboxes are checked, the item should be considered complete and its
2136 TODO state should be automatically changed to DONE. The code below
2137 does that. This version is slightly enhanced over the one in the
2138 mailing list (see
2139 http://thread.gmane.org/gmane.emacs.orgmode/42715/focus=42721) to
2140 reset the state back to TODO if a checkbox is unchecked.
2142 Note that the code requires that a checkbox statistics cookie (the [/]
2143 or [%] thingie in the headline - see the [[http://orgmode.org/manual/Checkboxes.html#Checkboxes][Checkboxes]] section in the
2144 manual) be present in order for it to work. Note also that it is too
2145 dumb to figure out whether the item has a TODO state in the first
2146 place: if there is a statistics cookie, a TODO/DONE state will be
2147 added willy-nilly any time that the statistics cookie is changed.
2149 #+begin_src emacs-lisp
2150   ;; see http://thread.gmane.org/gmane.emacs.orgmode/42715
2151   (eval-after-load 'org-list
2152     '(add-hook 'org-checkbox-statistics-hook (function ndk/checkbox-list-complete)))
2153   
2154   (defun ndk/checkbox-list-complete ()
2155     (save-excursion
2156       (org-back-to-heading t)
2157       (let ((beg (point)) end)
2158         (end-of-line)
2159         (setq end (point))
2160         (goto-char beg)
2161         (if (re-search-forward "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]" end t)
2162               (if (match-end 1)
2163                   (if (equal (match-string 1) "100%")
2164                       ;; all done - do the state change
2165                       (org-todo 'done)
2166                     (org-todo 'todo))
2167                 (if (and (> (match-end 2) (match-beginning 2))
2168                          (equal (match-string 2) (match-string 3)))
2169                     (org-todo 'done)
2170                   (org-todo 'todo)))))))
2171 #+end_src
2173 *** Links to custom agenda views
2174     :PROPERTIES:
2175     :CUSTOM_ID: links-to-agenda-views
2176     :END:
2177 #+index: Agenda view!Links to
2178 This hack was [[http://lists.gnu.org/archive/html/emacs-orgmode/2012-08/msg00986.html][posted to the mailing list]] by Nathan Neff.
2180 If you have custom agenda commands defined to some key, say w, then
2181 the following will serve as a link to the custom agenda buffer.
2182 : [[elisp:(org-agenda nil "w")][Show Waiting Tasks]]
2184 Clicking on it will prompt if you want to execute the elisp code.  If
2185 you would rather not have the prompt or would want to respond with a
2186 single letter, ~y~ or ~n~, take a look at the docstrings of the
2187 variables =org-confirm-elisp-link-function= and
2188 =org-confirm-elisp-link-not-regexp=.  Please take special note of the
2189 security risk associated with completely disabling the prompting
2190 before you proceed.
2192 ** Exporting org files
2193 *** Export Org to Org and handle includes.
2194 #+index: Export!handle includes
2195 Nick Dokos came up with this useful function:
2197 #+begin_src emacs-lisp
2198 (defun org-to-org-handle-includes ()
2199   "Copy the contents of the current buffer to OUTFILE,
2200 recursively processing #+INCLUDEs."
2201   (let* ((s (buffer-string))
2202          (fname (buffer-file-name))
2203          (ofname (format "%s.I.org" (file-name-sans-extension fname))))
2204     (setq result
2205           (with-temp-buffer
2206             (insert s)
2207             (org-export-handle-include-files-recurse)
2208             (buffer-string)))
2209     (find-file ofname)
2210     (delete-region (point-min) (point-max))
2211     (insert result)
2212     (save-buffer)))
2213 #+end_src
2215 *** Specifying LaTeX commands to floating environments
2216     :PROPERTIES:
2217     :CUSTOM_ID: latex-command-for-floats
2218     :END:
2220 #+index: Export!LaTeX
2221 The keyword ~placement~ can be used to specify placement options to
2222 floating environments (like =\begin{figure}= and =\begin{table}=}) in
2223 LaTeX export. Org passes along everything passed in options as long as
2224 there are no spaces. One can take advantage of this to pass other
2225 LaTeX commands and have their scope limited to the floating
2226 environment.
2228 For example one can set the fontsize of a table different from the
2229 default normal size by putting something like =\footnotesize= right
2230 after the placement options. During LaTeX export using the
2231 ~#+ATTR_LaTeX:~ line below:
2233 #+begin_src org
2234 ,#+ATTR_LaTeX: placement=[<options>]\footnotesize
2235 #+end_src
2237 exports the associated floating environment as shown in the following
2238 block.
2240 #+begin_src latex
2241 \begin{table}[<options>]\footnotesize
2243 \end{table}
2244 #+end_src
2246 It should be noted that this hack does not work for beamer export of
2247 tables since the =table= environment is not used. As an ugly
2248 workaround, one can use the following:
2250 #+begin_src org
2251 ,#+LATEX: {\footnotesize
2252 ,#+ATTR_LaTeX: align=rr
2253 | some | table |
2254 |------+-------|
2255 | ..   | ..    |
2256 ,#+LATEX: }
2257 #+end_src
2259 *** Styling code sections with CSS
2261 #+index: HTML!Styling code sections with CSS
2263 Code sections (marked with =#+begin_src= and =#+end_src=) are exported
2264 to HTML using =<pre>= tags, and assigned CSS classes by their content
2265 type.  For example, Perl content will have an opening tag like
2266 =<pre class="src src-perl">=.  You can use those classes to add styling
2267 to the output, such as here where a small language tag is added at the
2268 top of each kind of code box:
2270 #+begin_src lisp
2271 (setq org-export-html-style
2272  "<style type=\"text/css\">
2273     <!--/*--><![CDATA[/*><!--*/
2274       .src             { background-color: #F5FFF5; position: relative; overflow: visible; }
2275       .src:before      { position: absolute; top: -15px; background: #ffffff; padding: 1px; border: 1px solid #000000; font-size: small; }
2276       .src-sh:before   { content: 'sh'; }
2277       .src-bash:before { content: 'sh'; }
2278       .src-R:before    { content: 'R'; }
2279       .src-perl:before { content: 'Perl'; }
2280       .src-sql:before  { content: 'SQL'; }
2281       .example         { background-color: #FFF5F5; }
2282     /*]]>*/-->
2283  </style>")
2284 #+end_src
2286 Additionally, we use color to distinguish code output (the =.example=
2287 class) from input (all the =.src-*= classes).
2289 ** Babel
2291 *** How do I preview LaTeX fragments when in a LaTeX source block?
2293 When editing =LaTeX= source blocks, you may want to preview LaTeX fragments
2294 just like in an Org-mode buffer.  You can do this by using the usual
2295 keybinding =C-c C-x C-l= after loading this snipped:
2297 #+BEGIN_SRC emacs-lisp
2298 (define-key org-src-mode-map "\C-c\C-x\C-l" 'org-edit-preview-latex-fragment)
2300 (defun org-edit-preview-latex-fragment ()
2301   "Write latex fragment from source to parent buffer and preview it."
2302   (interactive)
2303   (org-src-in-org-buffer (org-preview-latex-fragment)))
2304 #+END_SRC
2306 Thanks to Sebastian Hofer for sharing this.
2308 * Hacking Org: Working with Org-mode and other Emacs Packages.
2309 ** How to ediff folded Org files
2310 A rather often quip among Org users is when looking at chages with
2311 ediff.  Ediff tends to fold the Org buffers when comparing.  This can
2312 be very inconvenient when trying to determine what changed.  A recent
2313 discussion on the mailing list led to a [[http://article.gmane.org/gmane.emacs.orgmode/75222][neat solution]] from Ratish
2314 Punnoose.
2316 ** org-remember-anything
2318 #+index: Remember!Anything
2320 [[http://www.emacswiki.org/cgi-bin/wiki/Anything][Anything]] users may find the snippet below interesting:
2322 #+BEGIN_SRC emacs-lisp
2323 (defvar org-remember-anything
2324   '((name . "Org Remember")
2325     (candidates . (lambda () (mapcar 'car org-remember-templates)))
2326     (action . (lambda (name)
2327                 (let* ((orig-template org-remember-templates)
2328                        (org-remember-templates
2329                         (list (assoc name orig-template))))
2330                   (call-interactively 'org-remember))))))
2331 #+END_SRC
2333 You can add it to your 'anything-sources' variable and open remember directly
2334 from anything. I imagine this would be more interesting for people with many
2335 remember templates, so that you are out of keys to assign those to.
2337 ** Org-mode and saveplace.el
2339 Fix a problem with =saveplace.el= putting you back in a folded position:
2341 #+begin_src emacs-lisp
2342 (add-hook 'org-mode-hook
2343           (lambda ()
2344             (when (outline-invisible-p)
2345               (save-excursion
2346                 (outline-previous-visible-heading 1)
2347                 (org-show-subtree)))))
2348 #+end_src
2350 ** Using ido-mode for org-refile (and archiving via refile)
2352 First set up ido-mode, for example using:
2354 #+begin_src emacs-lisp
2355 ; use ido mode for completion
2356 (setq ido-everywhere t)
2357 (setq ido-enable-flex-matching t)
2358 (setq ido-max-directory-size 100000)
2359 (ido-mode (quote both))
2360 #+end_src
2362 Now to enable it in org-mode, use the following:
2363 #+begin_src emacs-lisp
2364 (setq org-completion-use-ido t)
2365 (setq org-refile-use-outline-path nil)
2366 (setq org-refile-allow-creating-parent-nodes 'confirm)
2367 #+end_src
2368 The last line enables the creation of nodes on the fly.
2370 If you refile into files that are not in your agenda file list, you can add them as target like this (replace file1\_done, etc with your files):
2371 #+begin_src emacs-lisp
2372 (setq org-refile-targets '((org-agenda-files :maxlevel . 5) (("~/org/file1_done" "~/org/file2_done") :maxlevel . 5) ))
2373 #+end_src
2375 For refiling it is often not useful to include targets that have a DONE state. It's easy to remove them by using the verify-refile-target hook.
2376 #+begin_src emacs-lisp
2377 ; Exclude DONE state tasks from refile targets; taken from http://doc.norang.ca/org-mode.html
2378 ; added check to only include headlines, e.g. line must have at least one child
2379 (defun my/verify-refile-target ()
2380   "Exclude todo keywords with a DONE state from refile targets"
2381   (or (not (member (nth 2 (org-heading-components)) org-done-keywords)))
2382       (save-excursion (org-goto-first-child))
2383   )
2384 (setq org-refile-target-verify-function 'my/verify-refile-target)
2385 #+end_src
2386 Now when looking for a refile target, you can use the full power of ido to find them. Ctrl-R can be used to switch between different options that ido offers.
2388 ** Using ido-completing-read to find attachments
2390 #+index: Attachment!ido completion
2392 -- Matt Lundin.
2394 Org-attach is great for quickly linking files to a project. But if you
2395 use org-attach extensively you might find yourself wanting to browse
2396 all the files you've attached to org headlines. This is not easy to do
2397 manually, since the directories containing the files are not human
2398 readable (i.e., they are based on automatically generated ids). Here's
2399 some code to browse those files using ido (obviously, you need to be
2400 using ido):
2402 #+begin_src emacs-lisp
2403 (load-library "find-lisp")
2405 ;; Adapted from http://www.emacswiki.org/emacs/RecentFiles
2407 (defun my-ido-find-org-attach ()
2408   "Find files in org-attachment directory"
2409   (interactive)
2410   (let* ((enable-recursive-minibuffers t)
2411          (files (find-lisp-find-files org-attach-directory "."))
2412          (file-assoc-list
2413           (mapcar (lambda (x)
2414                     (cons (file-name-nondirectory x)
2415                           x))
2416                   files))
2417          (filename-list
2418           (remove-duplicates (mapcar #'car file-assoc-list)
2419                              :test #'string=))
2420          (filename (ido-completing-read "Org attachments: " filename-list nil t))
2421          (longname (cdr (assoc filename file-assoc-list))))
2422     (ido-set-current-directory
2423      (if (file-directory-p longname)
2424          longname
2425        (file-name-directory longname)))
2426     (setq ido-exit 'refresh
2427           ido-text-init ido-text
2428           ido-rotate-temp t)
2429     (exit-minibuffer)))
2431 (add-hook 'ido-setup-hook 'ido-my-keys)
2433 (defun ido-my-keys ()
2434   "Add my keybindings for ido."
2435   (define-key ido-completion-map (kbd "C-;") 'my-ido-find-org-attach))
2436 #+end_src
2438 To browse your org attachments using ido fuzzy matching and/or the
2439 completion buffer, invoke ido-find-file as usual (=C-x C-f=) and then
2440 press =C-;=.
2442 ** Link to Gnus messages by Message-Id
2443 #+index: Link!Gnus message by Message-Id
2444 In a [[http://thread.gmane.org/gmane.emacs.orgmode/8860][recent thread]] on the Org-Mode mailing list, there was some
2445 discussion about linking to Gnus messages without encoding the folder
2446 name in the link.  The following code hooks in to the store-link
2447 function in Gnus to capture links by Message-Id when in nnml folders,
2448 and then provides a link type "mid" which can open this link.  The
2449 =mde-org-gnus-open-message-link= function uses the
2450 =mde-mid-resolve-methods= variable to determine what Gnus backends to
2451 scan.  It will go through them, in order, asking each to locate the
2452 message and opening it from the first one that reports success.
2454 It has only been tested with a single nnml backend, so there may be
2455 bugs lurking here and there.
2457 The logic for finding the message was adapted from [[http://www.emacswiki.org/cgi-bin/wiki/FindMailByMessageId][an Emacs Wiki
2458 article]].
2460 #+begin_src emacs-lisp
2461 ;; Support for saving Gnus messages by Message-ID
2462 (defun mde-org-gnus-save-by-mid ()
2463   (when (memq major-mode '(gnus-summary-mode gnus-article-mode))
2464     (when (eq major-mode 'gnus-article-mode)
2465       (gnus-article-show-summary))
2466     (let* ((group gnus-newsgroup-name)
2467            (method (gnus-find-method-for-group group)))
2468       (when (eq 'nnml (car method))
2469         (let* ((article (gnus-summary-article-number))
2470                (header (gnus-summary-article-header article))
2471                (from (mail-header-from header))
2472                (message-id
2473                 (save-match-data
2474                   (let ((mid (mail-header-id header)))
2475                     (if (string-match "<\\(.*\\)>" mid)
2476                         (match-string 1 mid)
2477                       (error "Malformed message ID header %s" mid)))))
2478                (date (mail-header-date header))
2479                (subject (gnus-summary-subject-string)))
2480           (org-store-link-props :type "mid" :from from :subject subject
2481                                 :message-id message-id :group group
2482                                 :link (org-make-link "mid:" message-id))
2483           (apply 'org-store-link-props
2484                  :description (org-email-link-description)
2485                  org-store-link-plist)
2486           t)))))
2488 (defvar mde-mid-resolve-methods '()
2489   "List of methods to try when resolving message ID's.  For Gnus,
2490 it is a cons of 'gnus and the select (type and name).")
2491 (setq mde-mid-resolve-methods
2492       '((gnus nnml "")))
2494 (defvar mde-org-gnus-open-level 1
2495   "Level at which Gnus is started when opening a link")
2496 (defun mde-org-gnus-open-message-link (msgid)
2497   "Open a message link with Gnus"
2498   (require 'gnus)
2499   (require 'org-table)
2500   (catch 'method-found
2501     (message "[MID linker] Resolving %s" msgid)
2502     (dolist (method mde-mid-resolve-methods)
2503       (cond
2504        ((and (eq (car method) 'gnus)
2505              (eq (cadr method) 'nnml))
2506         (funcall (cdr (assq 'gnus org-link-frame-setup))
2507                  mde-org-gnus-open-level)
2508         (when gnus-other-frame-object
2509           (select-frame gnus-other-frame-object))
2510         (let* ((msg-info (nnml-find-group-number
2511                           (concat "<" msgid ">")
2512                           (cdr method)))
2513                (group (and msg-info (car msg-info)))
2514                (message (and msg-info (cdr msg-info)))
2515                (qname (and group
2516                            (if (gnus-methods-equal-p
2517                                 (cdr method)
2518                                 gnus-select-method)
2519                                group
2520                              (gnus-group-full-name group (cdr method))))))
2521           (when msg-info
2522             (gnus-summary-read-group qname nil t)
2523             (gnus-summary-goto-article message nil t))
2524           (throw 'method-found t)))
2525        (t (error "Unknown link type"))))))
2527 (eval-after-load 'org-gnus
2528   '(progn
2529      (add-to-list 'org-store-link-functions 'mde-org-gnus-save-by-mid)
2530      (org-add-link-type "mid" 'mde-org-gnus-open-message-link)))
2531 #+end_src
2533 ** Store link to a message when sending in Gnus
2534 #+index: Link!Store link to a message when sending in Gnus
2535 Ulf Stegemann came up with this solution (see his [[http://www.mail-archive.com/emacs-orgmode@gnu.org/msg33278.html][original message]]):
2537 #+begin_src emacs-lisp
2538 (defun ulf-message-send-and-org-gnus-store-link (&optional arg)
2539   "Send message with `message-send-and-exit' and store org link to message copy.
2540 If multiple groups appear in the Gcc header, the link refers to
2541 the copy in the last group."
2542   (interactive "P")
2543     (save-excursion
2544       (save-restriction
2545         (message-narrow-to-headers)
2546         (let ((gcc (car (last
2547                          (message-unquote-tokens
2548                           (message-tokenize-header
2549                            (mail-fetch-field "gcc" nil t) " ,")))))
2550               (buf (current-buffer))
2551               (message-kill-buffer-on-exit nil)
2552               id to from subject desc link newsgroup xarchive)
2553         (message-send-and-exit arg)
2554         (or
2555          ;; gcc group found ...
2556          (and gcc
2557               (save-current-buffer
2558                 (progn (set-buffer buf)
2559                        (setq id (org-remove-angle-brackets
2560                                  (mail-fetch-field "Message-ID")))
2561                        (setq to (mail-fetch-field "To"))
2562                        (setq from (mail-fetch-field "From"))
2563                        (setq subject (mail-fetch-field "Subject"))))
2564               (org-store-link-props :type "gnus" :from from :subject subject
2565                                     :message-id id :group gcc :to to)
2566               (setq desc (org-email-link-description))
2567               (setq link (org-gnus-article-link
2568                           gcc newsgroup id xarchive))
2569               (setq org-stored-links
2570                     (cons (list link desc) org-stored-links)))
2571          ;; no gcc group found ...
2572          (message "Can not create Org link: No Gcc header found."))))))
2574 (define-key message-mode-map [(control c) (control meta c)]
2575   'ulf-message-send-and-org-gnus-store-link)
2576 #+end_src
2578 ** Link to visit a file and run occur
2579 #+index: Link!Visit a file and run occur
2580 Add the following bit of code to your startup (after loading org),
2581 and you can then use links like =occur:my-file.txt#regex= to open a
2582 file and run occur with the regex on it.
2584 #+BEGIN_SRC emacs-lisp
2585   (defun org-occur-open (uri)
2586     "Visit the file specified by URI, and run `occur' on the fragment
2587     \(anything after the first '#') in the uri."
2588     (let ((list (split-string uri "#")))
2589       (org-open-file (car list) t)
2590       (occur (mapconcat 'identity (cdr list) "#"))))
2591   (org-add-link-type "occur" 'org-occur-open)
2592 #+END_SRC
2593 ** Send html messages and attachments with Wanderlust
2594   -- David Maus
2596 /Note/: The module [[file:org-contrib/org-mime.org][Org-mime]] in Org's contrib directory provides
2597 similar functionality for both Wanderlust and Gnus.  The hack below is
2598 still somewhat different: It allows you to toggle sending of html
2599 messages within Wanderlust transparently.  I.e. html markup of the
2600 message body is created right before sending starts.
2602 *** Send HTML message
2604 Putting the code below in your .emacs adds following four functions:
2606 - dmj/wl-send-html-message
2608   Function that does the job: Convert everything between "--text
2609   follows this line--" and first mime entity (read: attachment) or
2610   end of buffer into html markup using `org-export-region-as-html'
2611   and replaces original body with a multipart MIME entity with the
2612   plain text version of body and the html markup version.  Thus a
2613   recipient that prefers html messages can see the html markup,
2614   recipients that prefer or depend on plain text can see the plain
2615   text.
2617   Cannot be called interactively: It is hooked into SEMI's
2618   `mime-edit-translate-hook' if message should be HTML message.
2620 - dmj/wl-send-html-message-draft-init
2622   Cannot be called interactively: It is hooked into WL's
2623   `wl-mail-setup-hook' and provides a buffer local variable to
2624   toggle.
2626 - dmj/wl-send-html-message-draft-maybe
2628   Cannot be called interactively: It is hooked into WL's
2629   `wl-draft-send-hook' and hooks `dmj/wl-send-html-message' into
2630   `mime-edit-translate-hook' depending on whether HTML message is
2631   toggled on or off
2633 - dmj/wl-send-html-message-toggle
2635   Toggles sending of HTML message.  If toggled on, the letters
2636   "HTML" appear in the mode line.
2638   Call it interactively!  Or bind it to a key in `wl-draft-mode'.
2640 If you have to send HTML messages regularly you can set a global
2641 variable `dmj/wl-send-html-message-toggled-p' to the string "HTML" to
2642 toggle on sending HTML message by default.
2644 The image [[http://s11.directupload.net/file/u/15851/48ru5wl3.png][here]] shows an example of how the HTML message looks like in
2645 Google's web front end.  As you can see you have the whole markup of
2646 Org at your service: *bold*, /italics/, tables, lists...
2648 So even if you feel uncomfortable with sending HTML messages at least
2649 you send HTML that looks quite good.
2651 #+begin_src emacs-lisp
2652 (defun dmj/wl-send-html-message ()
2653   "Send message as html message.
2654 Convert body of message to html using
2655   `org-export-region-as-html'."
2656   (require 'org)
2657   (save-excursion
2658     (let (beg end html text)
2659       (goto-char (point-min))
2660       (re-search-forward "^--text follows this line--$")
2661       ;; move to beginning of next line
2662       (beginning-of-line 2)
2663       (setq beg (point))
2664       (if (not (re-search-forward "^--\\[\\[" nil t))
2665           (setq end (point-max))
2666         ;; line up
2667         (end-of-line 0)
2668         (setq end (point)))
2669       ;; grab body
2670       (setq text (buffer-substring-no-properties beg end))
2671       ;; convert to html
2672       (with-temp-buffer
2673         (org-mode)
2674         (insert text)
2675         ;; handle signature
2676         (when (re-search-backward "^-- \n" nil t)
2677           ;; preserve link breaks in signature
2678           (insert "\n#+BEGIN_VERSE\n")
2679           (goto-char (point-max))
2680           (insert "\n#+END_VERSE\n")
2681           ;; grab html
2682           (setq html (org-export-region-as-html
2683                       (point-min) (point-max) t 'string))))
2684       (delete-region beg end)
2685       (insert
2686        (concat
2687         "--" "<<alternative>>-{\n"
2688         "--" "[[text/plain]]\n" text
2689         "--" "[[text/html]]\n"  html
2690         "--" "}-<<alternative>>\n")))))
2692 (defun dmj/wl-send-html-message-toggle ()
2693   "Toggle sending of html message."
2694   (interactive)
2695   (setq dmj/wl-send-html-message-toggled-p
2696         (if dmj/wl-send-html-message-toggled-p
2697             nil "HTML"))
2698   (message "Sending html message toggled %s"
2699            (if dmj/wl-send-html-message-toggled-p
2700                "on" "off")))
2702 (defun dmj/wl-send-html-message-draft-init ()
2703   "Create buffer local settings for maybe sending html message."
2704   (unless (boundp 'dmj/wl-send-html-message-toggled-p)
2705     (setq dmj/wl-send-html-message-toggled-p nil))
2706   (make-variable-buffer-local 'dmj/wl-send-html-message-toggled-p)
2707   (add-to-list 'global-mode-string
2708                '(:eval (if (eq major-mode 'wl-draft-mode)
2709                            dmj/wl-send-html-message-toggled-p))))
2711 (defun dmj/wl-send-html-message-maybe ()
2712   "Maybe send this message as html message.
2714 If buffer local variable `dmj/wl-send-html-message-toggled-p' is
2715 non-nil, add `dmj/wl-send-html-message' to
2716 `mime-edit-translate-hook'."
2717   (if dmj/wl-send-html-message-toggled-p
2718       (add-hook 'mime-edit-translate-hook 'dmj/wl-send-html-message)
2719     (remove-hook 'mime-edit-translate-hook 'dmj/wl-send-html-message)))
2721 (add-hook 'wl-draft-reedit-hook 'dmj/wl-send-html-message-draft-init)
2722 (add-hook 'wl-mail-setup-hook 'dmj/wl-send-html-message-draft-init)
2723 (add-hook 'wl-draft-send-hook 'dmj/wl-send-html-message-maybe)
2724 #+end_src
2726 *** Attach HTML of region or subtree
2728 Instead of sending a complete HTML message you might only send parts
2729 of an Org file as HTML for the poor souls who are plagued with
2730 non-proportional fonts in their mail program that messes up pretty
2731 ASCII tables.
2733 This short function does the trick: It exports region or subtree to
2734 HTML, prefixes it with a MIME entity delimiter and pushes to killring
2735 and clipboard.  If a region is active, it uses the region, the
2736 complete subtree otherwise.
2738 #+begin_src emacs-lisp
2739 (defun dmj/org-export-region-as-html-attachment (beg end arg)
2740   "Export region between BEG and END as html attachment.
2741 If BEG and END are not set, use current subtree.  Region or
2742 subtree is exported to html without header and footer, prefixed
2743 with a mime entity string and pushed to clipboard and killring.
2744 When called with prefix, mime entity is not marked as
2745 attachment."
2746   (interactive "r\nP")
2747   (save-excursion
2748     (let* ((beg (if (region-active-p) (region-beginning)
2749                   (progn
2750                     (org-back-to-heading)
2751                     (point))))
2752            (end (if (region-active-p) (region-end)
2753                   (progn
2754                     (org-end-of-subtree)
2755                     (point))))
2756            (html (concat "--[[text/html"
2757                          (if arg "" "\nContent-Disposition: attachment")
2758                          "]]\n"
2759                          (org-export-region-as-html beg end t 'string))))
2760       (when (fboundp 'x-set-selection)
2761         (ignore-errors (x-set-selection 'PRIMARY html))
2762         (ignore-errors (x-set-selection 'CLIPBOARD html)))
2763       (message "html export done, pushed to kill ring and clipboard"))))
2764 #+end_src
2766 *** Adopting for Gnus
2768 The whole magic lies in the special strings that mark a HTML
2769 attachment.  So you might just have to find out what these special
2770 strings are in message-mode and modify the functions accordingly.
2771 ** Add sunrise/sunset times to the agenda.
2772 #+index: Agenda!Diary s-expressions
2773   -- Nick Dokos
2775 The diary package provides the function =diary-sunrise-sunset= which can be used
2776 in a diary s-expression in some agenda file like this:
2778 #+begin_src org
2779 %%(diary-sunrise-sunset)
2780 #+end_src
2782 Seb Vauban asked if it is possible to put sunrise and sunset in
2783 separate lines. Here is a hack to do that. It adds two functions (they
2784 have to be available before the agenda is shown, so I add them early
2785 in my org-config file which is sourced from .emacs, but you'll have to
2786 suit yourself here) that just parse the output of
2787 diary-sunrise-sunset, instead of doing the right thing which would be
2788 to take advantage of the data structures that diary/solar.el provides.
2789 In short, a hack - so perfectly suited for inclusion here :-)
2791 The functions (and latitude/longitude settings which you have to modify for
2792 your location) are as follows:
2794 #+begin_src emacs-lisp
2795 (setq calendar-latitude 48.2)
2796 (setq calendar-longitude 16.4)
2797 (setq calendar-location-name "Vienna, Austria")
2799 (autoload 'solar-sunrise-sunset "solar.el")
2800 (autoload 'solar-time-string "solar.el")
2801 (defun diary-sunrise ()
2802   "Local time of sunrise as a diary entry.
2803 The diary entry can contain `%s' which will be replaced with
2804 `calendar-location-name'."
2805   (let ((l (solar-sunrise-sunset date)))
2806     (when (car l)
2807       (concat
2808        (if (string= entry "")
2809            "Sunrise"
2810          (format entry (eval calendar-location-name))) " "
2811          (solar-time-string (caar l) nil)))))
2813 (defun diary-sunset ()
2814   "Local time of sunset as a diary entry.
2815 The diary entry can contain `%s' which will be replaced with
2816 `calendar-location-name'."
2817   (let ((l (solar-sunrise-sunset date)))
2818     (when (cadr l)
2819       (concat
2820        (if (string= entry "")
2821            "Sunset"
2822          (format entry (eval calendar-location-name))) " "
2823          (solar-time-string (caadr l) nil)))))
2824 #+end_src
2826 You also need to add a couple of diary s-expressions in one of your agenda
2827 files:
2829 #+begin_src org
2830 %%(diary-sunrise)Sunrise in %s
2831 %%(diary-sunset)
2832 #+end_src
2834 This will show sunrise with the location and sunset without it.
2836 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]].
2837 In comparison to the version posted on the mailing list, this one
2838 gets rid of the timezone information and can show the location.
2839 ** Add lunar phases to the agenda.
2840 #+index: Agenda!Diary s-expressions
2841    -- Rüdiger
2843 Emacs comes with =lunar.el= to display the lunar phases (=M-x lunar-phases=).
2844 This can be used to display lunar phases in the agenda display with the
2845 following function:
2847 #+begin_src emacs-lisp
2848 (require 'cl-lib)
2850 (org-no-warnings (defvar date))
2851 (defun org-lunar-phases ()
2852   "Show lunar phase in Agenda buffer."
2853   (require 'lunar)
2854   (let* ((phase-list (lunar-phase-list (nth 0 date) (nth 2 date)))
2855          (phase (cl-find-if (lambda (phase) (equal (car phase) date))
2856                             phase-list)))
2857     (when phase
2858       (setq ret (concat (lunar-phase-name (nth 2 phase)) " "
2859                         (substring (nth 1 phase) 0 5))))))
2860 #+end_src
2862 Add the following line to an agenda file:
2864 #+begin_src org
2865 ,* Lunar phase
2866 ,#+CATEGORY: Lunar
2867 %%(org-lunar-phases)
2868 #+end_src
2870 This should display an entry on new moon, first/last quarter moon, and on full
2871 moon.  You can customize the entries by customizing =lunar-phase-names=.
2873 E.g., to add Unicode symbols:
2875 #+begin_src emacs-lisp
2876 (setq lunar-phase-names
2877       '("● New Moon" ; Unicode symbol: 🌑 Use full circle as fallback
2878         "☽ First Quarter Moon"
2879         "○ Full Moon" ; Unicode symbol: 🌕 Use empty circle as fallback
2880         "☾ Last Quarter Moon"))
2881 #+end_src
2883 Unicode 6 even provides symbols for the Moon with nice faces.  But those
2884 symbols are currently barely supported in fonts.
2885 See [[https://en.wikipedia.org/wiki/Astronomical_symbols#Moon][Astronomical symbols on Wikipedia]].
2887 ** Export BBDB contacts to org-contacts.el
2888 #+index: Address Book!BBDB to org-contacts
2889 Try this tool by Wes Hardaker:
2891 http://www.hardakers.net/code/bbdb-to-org-contacts/
2893 ** Calculating date differences - how to write a simple elisp function
2894 #+index: Timestamp!date calculations
2895 #+index: Elisp!technique
2897 Alexander Wingård asked how to calculate the number of days between a
2898 time stamp in his org file and today (see
2899 http://thread.gmane.org/gmane.emacs.orgmode/46881).  Although the
2900 resulting answer is probably not of general interest, the method might
2901 be useful to a budding Elisp programmer.
2903 Alexander started from an already existing org function,
2904 =org-evaluate-time-range=.  When this function is called in the context
2905 of a time range (two time stamps separated by "=--="), it calculates the
2906 number of days between the two dates and outputs the result in Emacs's
2907 echo area. What he wanted was a similar function that, when called from
2908 the context of a single time stamp, would calculate the number of days
2909 between the date in the time stamp and today. The result should go to
2910 the same place: Emacs's echo area.
2912 The solution presented in the mail thread is as follows:
2914 #+begin_src emacs-lisp
2915 (defun aw/org-evaluate-time-range (&optional to-buffer)
2916   (interactive)
2917   (if (org-at-date-range-p t)
2918       (org-evaluate-time-range to-buffer)
2919     ;; otherwise, make a time range in a temp buffer and run o-e-t-r there
2920     (let ((headline (buffer-substring (point-at-bol) (point-at-eol))))
2921       (with-temp-buffer
2922         (insert headline)
2923         (goto-char (point-at-bol))
2924         (re-search-forward org-ts-regexp (point-at-eol) t)
2925         (if (not (org-at-timestamp-p t))
2926             (error "No timestamp here"))
2927         (goto-char (match-beginning 0))
2928         (org-insert-time-stamp (current-time) nil nil)
2929         (insert "--")
2930         (org-evaluate-time-range to-buffer)))))
2931 #+end_src
2933 The function assumes that point is on some line with some time stamp
2934 (or a date range) in it. Note that =org-evaluate-time-range= does not care
2935 whether the first date is earlier than the second: it will always output
2936 the number of days between the earlier date and the later date.
2938 As stated before, the function itself is of limited interest (although
2939 it satisfied Alexander's need).The *method* used might be of wider
2940 interest however, so here is a short explanation.
2942 The idea is that we want =org-evaluate-time-range= to do all the
2943 heavy lifting, but that function requires that it be in a date-range
2944 context. So the function first checks whether it's in a date range
2945 context already: if so, it calls =org-evaluate-time-range= directly
2946 to do the work. The trick now is to arrange things so we can call this
2947 same function in the case where we do *not* have a date range
2948 context. In that case, we manufacture one: we create a temporary
2949 buffer, copy the line with the purported time stamp to the temp
2950 buffer, find the time stamp (signal an error if no time stamp is
2951 found) and insert a new time stamp with the current time before the
2952 existing time stamp, followed by "=--=": voilà, we now have a time range
2953 on which we can apply our old friend =org-evaluate-time-range= to
2954 produce the answer. Because of the above-mentioned property
2955 of =org-evaluate-time-range=, it does not matter if the existing
2956 time stamp is earlier or later than the current time: the correct
2957 number of days is output.
2959 Note that at the end of the call to =with-temp-buffer=, the temporary
2960 buffer goes away.  It was just used as a scratch pad for the function
2961 to do some figuring.
2963 The idea of using a temp buffer as a scratch pad has wide
2964 applicability in Emacs programming. The rest of the work is knowing
2965 enough about facilities provided by Emacs (e.g. regexp searching) and
2966 by Org (e.g. checking for time stamps and generating a time stamp) so
2967 that you don't reinvent the wheel, and impedance-matching between the
2968 various pieces.
2970 ** ibuffer and org files
2972 Neil Smithline posted this snippet to let you browse org files with
2973 =ibuffer=:
2975 #+BEGIN_SRC emacs-lisp
2976 (require 'ibuffer)
2978 (defun org-ibuffer ()
2979   "Open an `ibuffer' window showing only `org-mode' buffers."
2980   (interactive)
2981   (ibuffer nil "*Org Buffers*" '((used-mode . org-mode))))
2982 #+END_SRC
2984 ** Enable org-mode links in other modes
2986 Sean O'Halpin wrote a minor mode for this, please check it [[https://github.com/seanohalpin/org-link-minor-mode][here]].
2988 See the relevant discussion [[http://thread.gmane.org/gmane.emacs.orgmode/58715/focus%3D58794][here]].
2990 ** poporg.el: edit comments in org-mode
2992 [[https://github.com/pinard/PopOrg/blob/master/poporg.el][poporg.el]] is a library by François Pinard which lets you edit comments
2993 from your code using a separate org-mode buffer.
2995 ** Convert a .csv file to an Org-mode table
2997 Nicolas Richard has a [[http://article.gmane.org/gmane.emacs.orgmode/65456][nice recipe]] using the pcsv library ([[http://marmalade-repo.org/packages/pcsv][available]] from
2998 the Marmelade ELPA repository):
3000 #+BEGIN_SRC emacs-lisp
3001 (defun yf/lisp-table-to-org-table (table &optional function)
3002   "Convert a lisp table to `org-mode' syntax, applying FUNCTION to each of its elements.
3003 The elements should not have any more newlines in them after
3004 applying FUNCTION ; the default converts them to spaces. Return
3005 value is a string containg the unaligned `org-mode' table."
3006   (unless (functionp function)
3007     (setq function (lambda (x) (replace-regexp-in-string "\n" " " x))))
3008   (mapconcat (lambda (x)                ; x is a line.
3009                (concat "| " (mapconcat function x " | ") " |"))
3010              table "\n"))
3012 (defun yf/csv-to-table (beg end)
3013 "Convert a csv file to an `org-mode' table."
3014   (interactive "r")
3015   (require 'pcsv)
3016   (insert (yf/lisp-table-to-org-table (pcsv-parse-region beg end)))
3017   (delete-region beg end)
3018   (org-table-align))
3019 #+END_SRC
3021 * Hacking Org: Working with Org-mode and External Programs.
3022 ** Use Org-mode with Screen [Andrew Hyatt]
3023 #+index: Link!to screen session
3024 "The general idea is that you start a task in which all the work will
3025 take place in a shell.  This usually is not a leaf-task for me, but
3026 usually the parent of a leaf task.  From a task in your org-file, M-x
3027 ash-org-screen will prompt for the name of a session.  Give it a name,
3028 and it will insert a link.  Open the link at any time to go the screen
3029 session containing your work!"
3031 http://article.gmane.org/gmane.emacs.orgmode/5276
3033 #+BEGIN_SRC emacs-lisp
3034 (require 'term)
3036 (defun ash-org-goto-screen (name)
3037   "Open the screen with the specified name in the window"
3038   (interactive "MScreen name: ")
3039   (let ((screen-buffer-name (ash-org-screen-buffer-name name)))
3040     (if (member screen-buffer-name
3041                 (mapcar 'buffer-name (buffer-list)))
3042         (switch-to-buffer screen-buffer-name)
3043       (switch-to-buffer (ash-org-screen-helper name "-dr")))))
3045 (defun ash-org-screen-buffer-name (name)
3046   "Returns the buffer name corresponding to the screen name given."
3047   (concat "*screen " name "*"))
3049 (defun ash-org-screen-helper (name arg)
3050   ;; Pick the name of the new buffer.
3051   (let ((term-ansi-buffer-name
3052          (generate-new-buffer-name
3053           (ash-org-screen-buffer-name name))))
3054     (setq term-ansi-buffer-name
3055           (term-ansi-make-term
3056            term-ansi-buffer-name "/usr/bin/screen" nil arg name))
3057     (set-buffer term-ansi-buffer-name)
3058     (term-mode)
3059     (term-char-mode)
3060     (term-set-escape-char ?\C-x)
3061     term-ansi-buffer-name))
3063 (defun ash-org-screen (name)
3064   "Start a screen session with name"
3065   (interactive "MScreen name: ")
3066   (save-excursion
3067     (ash-org-screen-helper name "-S"))
3068   (insert-string (concat "[[screen:" name "]]")))
3070 ;; And don't forget to add ("screen" . "elisp:(ash-org-goto-screen
3071 ;; \"%s\")") to org-link-abbrev-alist.
3072 #+END_SRC
3074 ** Org Agenda + Appt + Zenity
3075     :PROPERTIES:
3076     :CUSTOM_ID: org-agenda-appt-zenity
3077     :END:
3079 #+index: Appointment!reminders
3080 #+index: Appt!Zenity
3081 #+BEGIN_HTML
3082 <a name="agenda-appt-zenity"></a>
3083 #+END_HTML
3084 Russell Adams posted this setup [[http://article.gmane.org/gmane.emacs.orgmode/5806][on the list]].  It makes sure your agenda
3085 appointments are known by Emacs, and it displays warnings in a [[http://live.gnome.org/Zenity][zenity]]
3086 popup window.
3088 #+BEGIN_SRC emacs-lisp
3089 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3090 ; For org appointment reminders
3092 ;; Get appointments for today
3093 (defun my-org-agenda-to-appt ()
3094   (interactive)
3095   (setq appt-time-msg-list nil)
3096   (let ((org-deadline-warning-days 0))    ;; will be automatic in org 5.23
3097         (org-agenda-to-appt)))
3099 ;; Run once, activate and schedule refresh
3100 (my-org-agenda-to-appt)
3101 (appt-activate t)
3102 (run-at-time "24:01" nil 'my-org-agenda-to-appt)
3104 ; 5 minute warnings
3105 (setq appt-message-warning-time 15)
3106 (setq appt-display-interval 5)
3108 ; Update appt each time agenda opened.
3109 (add-hook 'org-finalize-agenda-hook 'my-org-agenda-to-appt)
3111 ; Setup zenify, we tell appt to use window, and replace default function
3112 (setq appt-display-format 'window)
3113 (setq appt-disp-window-function (function my-appt-disp-window))
3115 (defun my-appt-disp-window (min-to-app new-time msg)
3116   (save-window-excursion (shell-command (concat
3117     "/usr/bin/zenity --info --title='Appointment' --text='"
3118     msg "' &") nil nil)))
3119 #+END_SRC
3121 ** Org and appointment notifications on Mac OS 10.8
3123 Sarah Bagby [[http://mid.gmane.org/EA76104A-9ACD-4141-8D33-2E4D810D9B5A%2540geol.ucsb.edu][posted some code]] on how to get appointments notifications on
3124 Mac OS 10.8 with [[https://github.com/alloy/terminal-notifier][terminal-notifier]].
3126 ** Org-Mode + gnome-osd
3127 #+index: Appointment!reminders
3128 #+index: Appt!gnome-osd
3129 Richard Riley uses gnome-osd in interaction with Org-Mode to display
3130 appointments.  You can look at the code on the [[http://www.emacswiki.org/emacs-en/OrgMode-OSD][emacswiki]].
3132 ** txt2org convert text data to org-mode tables
3133 From Eric Schulte
3135 I often find it useful to generate Org-mode tables on the command line
3136 from tab-separated data.  The following awk script makes this easy to
3137 do.  Text data is read from STDIN on a pipe and any command line
3138 arguments are interpreted as rows at which to insert hlines.
3140 Here are two usage examples.
3141 1. running the following
3142    : $ cat <<EOF|~/src/config/bin/txt2org
3143    : one 1
3144    : two 2
3145    : three 3
3146    : twenty 20
3147    : EOF                  
3148    results in
3149    : |    one |  1 |
3150    : |    two |  2 |
3151    : |  three |  3 |
3152    : | twenty | 20 |
3154 2. and the following (notice the command line argument)
3155    : $ cat <<EOF|~/src/config/bin/txt2org 1
3156    : strings numbers                                          
3157    : one 1
3158    : two 2
3159    : three 3
3160    : twenty 20
3161    : EOF 
3162    results in
3163    : | strings | numbers |
3164    : |---------+---------|
3165    : |     one |       1 |
3166    : |     two |       2 |
3167    : |   three |       3 |
3168    : |  twenty |      20 |
3170 Here is the script itself
3171 #+begin_src awk
3172   #!/usr/bin/gawk -f
3173   #
3174   # Read tab separated data from STDIN and output an Org-mode table.
3175   #
3176   # Optional command line arguments specify row numbers at which to
3177   # insert hlines.
3178   #
3179   BEGIN {
3180       for(i=1; i<ARGC; i++){
3181           hlines[ARGV[i]+1]=1; ARGV[i] = "-"; } }
3182   
3183   {
3184       if(NF > max_nf){ max_nf = NF; };
3185       for(f=1; f<=NF; f++){
3186           if(length($f) > lengths[f]){ lengths[f] = length($f); };
3187           row[NR][f]=$f; } }
3188   
3189   END {
3190       hline_str="|"
3191       for(f=1; f<=max_nf; f++){
3192           for(i=0; i<(lengths[f] + 2); i++){ hline_str=hline_str "-"; }
3193           if( f != max_nf){ hline_str=hline_str "+"; }
3194           else            { hline_str=hline_str "|"; } }
3195   
3196       for(r=1; r<=NR; r++){ # rows
3197           if(hlines[r] == 1){ print hline_str; }
3198           printf "|";
3199           for(f=1; f<=max_nf; f++){ # columns
3200               cell=row[r][f]; padding=""
3201               for(i=0; i<(lengths[f] - length(cell)); i++){ padding=padding " "; }
3202               # for now just print everything right-aligned
3203               # if(cell ~ /[0-9.]/){ printf " %s%s |", cell, padding; }
3204               # else{                printf " %s%s |", padding, cell; }
3205               printf " %s%s |", padding, cell; }
3206           printf "\n"; }
3207       
3208       if(hlines[NR+1]){ print hline_str; } }
3209 #+end_src
3211 ** remind2org
3212 #+index: Agenda!Views
3213 #+index: Agenda!and Remind (external program)
3214 From Detlef Steuer
3216 http://article.gmane.org/gmane.emacs.orgmode/5073
3218 #+BEGIN_QUOTE
3219 Remind (http://www.roaringpenguin.com/products/remind) is a very powerful
3220 command line calendaring program. Its features supersede the possibilities
3221 of orgmode in the area of date specifying, so that I want to use it
3222 combined with orgmode.
3224 Using the script below I'm able use remind and incorporate its output in my
3225 agenda views.  The default of using 13 months look ahead is easily
3226 changed. It just happens I sometimes like to look a year into the
3227 future. :-)
3228 #+END_QUOTE
3230 ** Useful webjumps for conkeror
3231 #+index: Shortcuts!conkeror
3232 If you are using the [[http://conkeror.org][conkeror browser]], maybe you want to put this into
3233 your =~/.conkerorrc= file:
3235 #+begin_example
3236 define_webjump("orglist", "http://search.gmane.org/?query=%s&group=gmane.emacs.orgmode");
3237 define_webjump("worg", "http://www.google.com/cse?cx=002987994228320350715%3Az4glpcrritm&ie=UTF-8&q=%s&sa=Search&siteurl=orgmode.org%2Fworg%2F");
3238 #+end_example
3240 It creates two [[http://conkeror.org/Webjumps][webjumps]] for easily searching the Worg website and the
3241 Org-mode mailing list.
3243 ** Use MathJax for HTML export without requiring JavaScript
3244 #+index: Export!MathJax
3245 As of 2010-08-14, MathJax is the default method used to export math to HTML.
3247 If you like the results but do not want JavaScript in the exported pages,
3248 check out [[http://www.jboecker.de/2010/08/15/staticmathjax.html][Static MathJax]], a XULRunner application which generates a static
3249 HTML file from the exported version. It can also embed all referenced fonts
3250 within the HTML file itself, so there are no dependencies to external files.
3252 The download archive contains an elisp file which integrates it into the Org
3253 export process (configurable per file with a "#+StaticMathJax:" line).
3255 Read README.org and the comments in org-static-mathjax.el for usage instructions.
3256 ** Search Org files using lgrep
3257 #+index: search!lgrep
3258 Matt Lundin suggests this:
3260 #+begin_src emacs-lisp
3261   (defun my-org-grep (search &optional context)
3262     "Search for word in org files.
3264 Prefix argument determines number of lines."
3265     (interactive "sSearch for: \nP")
3266     (let ((grep-find-ignored-files '("#*" ".#*"))
3267           (grep-template (concat "grep <X> -i -nH "
3268                                  (when context
3269                                    (concat "-C" (number-to-string context)))
3270                                  " -e <R> <F>")))
3271       (lgrep search "*org*" "/home/matt/org/")))
3273   (global-set-key (kbd "<f8>") 'my-org-grep)
3274 #+end_src
3276 ** Automatic screenshot insertion
3277 #+index: Link!screenshot
3278 Suggested by Russell Adams
3280 #+begin_src emacs-lisp
3281   (defun my-org-screenshot ()
3282     "Take a screenshot into a time stamped unique-named file in the
3283   same directory as the org-buffer and insert a link to this file."
3284     (interactive)
3285     (setq filename
3286           (concat
3287            (make-temp-name
3288             (concat (buffer-file-name)
3289                     "_"
3290                     (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
3291     (call-process "import" nil nil nil filename)
3292     (insert (concat "[[" filename "]]"))
3293     (org-display-inline-images))
3294 #+end_src
3296 ** Capture invitations/appointments from MS Exchange emails
3297 #+index: Appointment!MS Exchange
3298 Dirk-Jan C.Binnema [[http://article.gmane.org/gmane.emacs.orgmode/27684/][provided]] code to do this.  Please check
3299 [[file:code/elisp/org-exchange-capture.el][org-exchange-capture.el]]
3301 ** Audio/video file playback within org mode
3302 #+index: Link!audio/video
3303 Paul Sexton provided code that makes =file:= links to audio or video files
3304 (MP3, WAV, OGG, AVI, MPG, et cetera) play those files using the [[https://github.com/dbrock/bongo][Bongo]] Emacs
3305 media player library. The user can pause, skip forward and backward in the
3306 track, and so on from without leaving Emacs. Links can also contain a time
3307 after a double colon -- when this is present, playback will begin at that
3308 position in the track.
3310 See the file [[file:code/elisp/org-player.el][org-player.el]]
3312 ** Under X11 Keep a window with the current agenda items at all time
3313 #+index: Agenda!dedicated window
3314 I struggle to keep (in emacs) a window with the agenda at all times.
3315 For a long time I have wanted a sticky window that keeps this
3316 information, and then use my window manager to place it and remove its
3317 decorations (I can also force its placement in the stack: top always,
3318 for example).
3320 I wrote a small program in qt that simply monitors an HTML file and
3321 displays it. Nothing more. It does the work for me, and maybe somebody
3322 else will find it useful. It relies on exporting the agenda as HTML
3323 every time the org file is saved, and then this little program
3324 displays the html file. The window manager is responsible of removing
3325 decorations, making it sticky, and placing it in same place always.
3327 Here is a screenshot (see window to the bottom right). The decorations
3328 are removed by the window manager:
3330 http://turingmachine.org/hacking/org-mode/orgdisplay.png
3332 Here is the code. As I said, very, very simple, but maybe somebody will
3333 find if useful.
3335 http://turingmachine.org/hacking/org-mode/
3337 --daniel german
3339 ** Script (thru procmail) to output emails to an Org file
3340 #+index: Conversion!email to org file
3341 Tycho Garen sent [[http://comments.gmane.org/gmane.emacs.orgmode/44773][this]]:
3343 : I've [...] created some procmail and shell glue that takes emails and
3344 : inserts them into an org-file so that I can capture stuff on the go using
3345 : the email program.
3347 Everything is documented [[http://tychoish.com/code/org-mail/][here]].
3349 ** Save File With Different Format for Headings (fileconversion)
3350    :PROPERTIES:
3351    :CUSTOM_ID: fileconversion
3352    :END:
3353 #+index: Conversion!fileconversion
3355 Using hooks and on the fly
3356 - When writing a buffer to the file: Replace the leading stars from
3357   headings with a file char.
3358 - When reading a file into the buffer: Replace the file chars with
3359   leading stars for headings.
3361 To change the file format just add or remove the keyword in the
3362 =#+STARTUP:= line in the Org buffer and save.
3364 Now you can also change to Fundamental mode to see how the file looks
3365 like on the level of the file, can go back to Org mode, reenter Org
3366 mode or change to any other major mode and the conversion gets done
3367 whenever necessary.
3369 *** Headings Without Leading Stars (hidestarsfile and nbspstarsfile)
3370     :PROPERTIES:
3371     :CUSTOM_ID: hidestarsfile
3372     :END:
3373 #+index: Conversion!fileconversion hidestarsfile
3375 This is like "a cleaner outline view":
3376 http://orgmode.org/manual/Clean-view.html
3378 Example of the _file content_ first with leading stars as usual and
3379 below without leading stars through =#+STARTUP: odd hidestars
3380 hidestarsfile=:
3382 #+BEGIN_EXAMPLE
3383   #+STARTUP: odd hidestars
3384   [...]
3385   ***** TODO section
3386   ******* subsection
3387   ********* subsubsec
3388             - bla bla
3389   ***** section
3390         - bla bla
3391   ******* subsection
3392 #+END_EXAMPLE
3394 #+BEGIN_EXAMPLE
3395   #+STARTUP: odd hidestars hidestarsfile
3396   [...]
3397       * TODO section
3398         * subsection
3399           * subsubsec
3400             - bla bla
3401       * section
3402         - bla bla
3403         * subsection
3404 #+END_EXAMPLE
3406 The latter is convenient for better human readability when an Org file,
3407 additionally to Emacs, is read with a file viewer or, for smaller edits,
3408 with an editor not capable of the Org file format.
3410 =hidestarsfile= is a hack and can not become part of the Org core:
3411 - An Org file with =hidestarsfile= can not contain list items with a
3412   star as bullet due to the syntax conflict at read time. Mark
3413   E. Shoulson suggested to use the non-breaking space which is now
3414   implemented in fileconversion as =nbspstarsfile= as an alternative
3415   for =hidestarsfile=. Although I don't recommend it because an editor
3416   like typically e. g. Emacs may render the non-breaking space
3417   differently from the space =0x20=.
3418 - An Org file with =hidestarsfile= can almost not be edited with an
3419   Org mode without added functionality of hidestarsfile as long as the
3420   file is not converted back.
3422 *** Headings in Markdown Format (markdownstarsfile)
3423     :PROPERTIES:
3424     :CUSTOM_ID: markdownstarsfile
3425     :END:
3426 #+index: Conversion!fileconversion markdownstarsfile
3428 Together with =oddeven= you can use =markdownstarsfile= to be readable
3429 or even basically editable with Markdown (does not make much sense
3430 with =odd=, see =org-convert-to-odd-levels= and
3431 =org-convert-to-oddeven-levels= for how to convert).
3433 Example of the _file content_:
3435 #+BEGIN_EXAMPLE
3436   #+STARTUP: oddeven markdownstarsfile
3437   # section level 1
3438     1. first item of numbered list (same format in Org and Markdown)
3439   ## section level 2
3440      - first item of unordered list (same format in Org and Markdown)
3441   ### section level 3
3442       + first item of unordered list (same format in Org and Markdown)
3443   #### section level 4
3444        * first item of unordered list (same format in Org and Markdown)
3445        * avoid this item type to be compatible with Org hidestarsfile
3446 #+END_EXAMPLE
3448 An Org file with =markdownstarsfile= can not contain code comment
3449 lines prefixed with =#=, even not when within source blocks.
3451 *** emacs-lisp code
3452     :PROPERTIES:
3453     :CUSTOM_ID: fileconversion-code
3454     :END:
3455 #+index: Conversion!fileconversion emacs-lisp code
3457 #+BEGIN_SRC emacs-lisp
3458   ;; - fileconversion version 0.8
3459   ;; - DISCLAIMER: Make a backup of your Org files before using
3460   ;;   f-org-fileconv-*.
3461   ;; - supported #+STARTUP: formats: hidestarsfile, nbspstarsfile,
3462   ;;   markdownstarsfile
3464   ;; design summary: fileconversion is a round robin of two states
3465   ;; linked by two actions:
3466   ;; - state v-org-fileconv-level-org-p is nil: the level is “file”
3467   ;;   (encoded)
3468   ;; - action f-org-fileconv-decode: replace file char with “*”
3469   ;; - state v-org-fileconv-level-org-p is t: the level is “Org”
3470   ;;   (decoded)
3471   ;; - action f-org-fileconv-encode: replace “*” with file char
3472   ;; naming convention of prefix:
3473   ;; - f-[...]: “my function”, instead of the unspecific prefix “my-”
3474   ;; - v-[...]: “my variable”, instead of the unspecific prefix “my-”
3476   (defvar v-org-fileconv-level-org-p nil
3477     "Whether level of buffer is Org or only file.
3478   nil means the level is file (encoded), non-nil means the level is
3479   Org (decoded).")
3480   (make-variable-buffer-local 'v-org-fileconv-level-org-p)
3481   ;; survive a change of major mode that does kill-all-local-variables,
3482   ;; e. g. when reentering Org mode through “C-c C-c” on a STARTUP line
3483   (put 'v-org-fileconv-level-org-p 'permanent-local t)
3485   (defadvice org-mode (before advice-org-mode-before)
3486     (f-org-fileconv-org-mode-beg))
3487   (ad-activate 'org-mode)
3488   (defun f-org-fileconv-org-mode-beg ()
3489     (interactive)
3490     ;; only when converting really from/to an Org _file_, not e. g. for
3491     ;; a temp Org buffer unrelated to a file
3492     (when (buffer-file-name)
3493       (message "INF: buffer %s: f-org-fileconv-org-mode-beg"
3494                (buffer-name))
3495       ;; f-org-fileconv-decode in org-mode-hook would be too late for
3496       ;; performance reasons, see
3497       ;; http://lists.gnu.org/archive/html/emacs-orgmode/2013-11/msg00920.html
3498       (f-org-fileconv-decode)))
3500   (add-hook 'org-mode-hook 'f-org-fileconv-org-mode-end
3501             nil   ; _prepend_ to hook to have it first
3502             nil)  ; hook addition globally
3503   (defun f-org-fileconv-org-mode-end ()
3504     (interactive)
3505     ;; only when converting really from/to an Org _file_, not e. g. for
3506     ;; a temp Org buffer unrelated to a file
3507     (when (buffer-file-name)
3508       (message "INF: buffer %s: f-org-fileconv-org-mode-end"
3509                (buffer-name))
3510       ;; - the hooks are not permanent-local, this way and as needed
3511       ;;   they will disappear when the major mode of the buffer changes
3512       ;; - adding to change-major-mode-hook in "defadvice before" would
3513       ;;   be too early and already trigger during find-file
3514       ;; - t at the end: hook addition limited to buffer locally
3515       (add-hook 'change-major-mode-hook 'f-org-fileconv-encode nil t)
3516       (add-hook 'before-save-hook       'f-org-fileconv-encode nil t)
3517       (add-hook 'after-save-hook        'f-org-fileconv-decode nil t)))
3519   (defun f-org-fileconv-re ()
3520     "Check whether there is a STARTUP line for fileconversion.
3521   If found then return the expressions required for the conversion."
3522     (save-excursion
3523       (goto-char (point-min))  ; beginning-of-buffer not allowed
3524       (let (re-list (count 0))
3525         (while (re-search-forward "^#\\+STARTUP:" nil t)
3526           ;; #+STARTUP: hidestarsfile
3527           (when (string-match-p "\\bhidestarsfile\\b"
3528                                 (thing-at-point 'line))
3529             ;; exclude e. g.:
3530             ;; - line starting with star for bold emphasis
3531             ;; - line of stars to underline section title in loosely
3532             ;;   quoted ASCII style (star at end of line)
3533             (setq re-list '("\\(\\* \\)"  ; common-re
3534                             ?\ ))         ; file-char
3535             (setq count (1+ count)))
3536           ;; #+STARTUP: nbspstarsfile
3537           (when (string-match-p "\\bnbspstarsfile\\b"
3538                                 (thing-at-point 'line))
3539             (setq re-list '("\\(\\* \\)"  ; common-re
3540                             ?\xa0))       ; file-char non-breaking space
3541             (setq count (1+ count)))
3542           ;; #+STARTUP: markdownstarsfile
3543           (when (string-match-p "\\bmarkdownstarsfile\\b"
3544                                 (thing-at-point 'line))
3545             ;; exclude e. g.:
3546             ;; - #STARTUP:
3547             (setq re-list '("\\( \\)"  ; common-re
3548                             ?#))       ; file-char
3549             (setq count (1+ count))))
3550         (when (> count 1)
3551           (error "More than one fileconversion found"))
3552         re-list)))
3554   (defun f-org-fileconv-decode ()
3555     "In headings replace file char with '*'."
3556     (let ((re-list (f-org-fileconv-re)))
3557       (when (and re-list (not v-org-fileconv-level-org-p))
3558         ;; no `save-excursion' to be able to keep point in case of error
3559         (let* ((common-re (nth 0 re-list))
3560                (file-char (nth 1 re-list))
3561                (file-re   (concat "^" (string file-char) "+" common-re))
3562                (org-re    (concat "^\\*+" common-re))
3563                len
3564                (p         (point)))
3565           (goto-char (point-min))  ; beginning-of-buffer not allowed
3566           ;; syntax check
3567           (when (re-search-forward org-re nil t)
3568             (goto-char (match-beginning 0))
3569             (org-reveal)
3570             (error "Org fileconversion dec: syntax conflict at point"))
3571           (goto-char (point-min))  ; beginning-of-buffer not allowed
3572           ;; substitution
3573           (with-silent-modifications
3574             (while (re-search-forward file-re nil t)
3575               (goto-char (match-beginning 0))
3576               ;; faster than a lisp call of insert and delete on each
3577               ;; single char
3578               (setq len (- (match-beginning 1) (match-beginning 0)))
3579               (insert-char ?* len)
3580               (delete-char len)))
3581           (goto-char p))))
3583           ;; notes for ediff when only one file has fileconversion:
3584           ;; - The changes to the buffer with fileconversion until here
3585           ;;   are not regarded by ediff-files because the first call to
3586           ;;   diff is made with the bare files directly. Only
3587           ;;   ediff-update-diffs and ediff-buffers write the decoded
3588           ;;   buffers to temp files and then call diff with them.
3589           ;; - Workarounds (choose one):
3590           ;;   - after ediff-files first do a "!" (ediff-update-diffs)
3591           ;;     in the "*Ediff Control Panel*"
3592           ;;   - instead of using ediff-files first open the files and
3593           ;;     then run ediff-buffers (better for e. g. a script that
3594           ;;     takes two files as arguments and uses "emacs --eval")
3596     ;; the level is Org most of all when no fileconversion is in effect
3597     (setq v-org-fileconv-level-org-p t))
3599   (defun f-org-fileconv-encode ()
3600     "In headings replace '*' with file char."
3601     (let ((re-list (f-org-fileconv-re)))
3602       (when (and re-list v-org-fileconv-level-org-p)
3603         ;; no `save-excursion' to be able to keep point in case of error
3604         (let* ((common-re (nth 0 re-list))
3605                (file-char (nth 1 re-list))
3606                (file-re   (concat "^" (string file-char) "+" common-re))
3607                (org-re    (concat "^\\*+" common-re))
3608                len
3609                (p         (point)))
3610           (goto-char (point-min))  ; beginning-of-buffer not allowed
3611           ;; syntax check
3612           (when (re-search-forward file-re nil t)
3613             (goto-char (match-beginning 0))
3614             (org-reveal)
3615             (error "Org fileconversion enc: syntax conflict at point"))
3616           (goto-char (point-min))  ; beginning-of-buffer not allowed
3617           ;; substitution
3618           (with-silent-modifications
3619             (while (re-search-forward org-re nil t)
3620               (goto-char (match-beginning 0))
3621               ;; faster than a lisp call of insert and delete on each
3622               ;; single char
3623               (setq len (- (match-beginning 1) (match-beginning 0)))
3624               (insert-char file-char len)
3625               (delete-char len)))
3626           (goto-char p)
3627           (setq v-org-fileconv-level-org-p nil))))
3628     nil)  ; for the hook
3629 #+END_SRC
3631 Michael Brand
3633 ** Meaningful diff for org files in a git repository
3634 #+index: git!diff org files
3635 Since most diff utilities are primarily meant for source code, it is
3636 difficult to read diffs of text files like ~.org~ files easily. If you
3637 version your org directory with a SCM like git you will know what I
3638 mean. However for git, there is a way around. You can use
3639 =gitattributes= to define a custom diff driver for org files. Then a
3640 regular expression can be used to configure how the diff driver
3641 recognises a "function".
3643 Put the following in your =<org_dir>/.gitattributes=.
3644 : *.org diff=org
3645 Then put the following lines in =<org_dir>/.git/config=
3646 : [diff "org"]
3647 :       xfuncname = "^(\\*+ [a-zA-Z0-9]+.+)$"
3649 This will let you see diffs for org files with each hunk identified by
3650 the unmodified headline closest to the changes. After the
3651 configuration a diff should look something like the example below.
3653 #+begin_example
3654 diff --git a/org-hacks.org b/org-hacks.org
3655 index a0672ea..92a08f7 100644
3656 --- a/org-hacks.org
3657 +++ b/org-hacks.org
3658 @@ -2495,6 +2495,22 @@ ** Script (thru procmail) to output emails to an Org file
3660  Everything is documented [[http://tychoish.com/code/org-mail/][here]].
3662 +** Meaningful diff for org files in a git repository
3664 +Since most diff utilities are primarily meant for source code, it is
3665 +difficult to read diffs of text files like ~.org~ files easily. If you
3666 +version your org directory with a SCM like git you will know what I
3667 +mean. However for git, there is a way around. You can use
3668 +=gitattributes= to define a custom diff driver for org files. Then a
3669 +regular expression can be used to configure how the diff driver
3670 +recognises a "function".
3672 +Put the following in your =<org_dir>/.gitattributes=.
3673 +: *.org        diff=org
3674 +Then put the following lines in =<org_dir>/.git/config=
3675 +: [diff "org"]
3676 +:      xfuncname = "^(\\*+ [a-zA-Z0-9]+.+)$"
3678  * Musings
3680  ** Cooking?  Brewing?
3681 #+end_example
3683 ** Opening devonthink links
3685 John Wiegley wrote [[https://github.com/jwiegley/dot-emacs/blob/master/lisp/org-devonthink.el][org-devonthink.el]], which lets you handle devonthink
3686 links from org-mode.
3688 ** Memacs - Org-mode collecting meta-data from the disk and cloud
3690 Karl Voit designed Memacs ([[https://en.wikipedia.org/wiki/Memex][Memex]] and Emacs) which is a collection of
3691 modules that are able to get meta-data from different kind of
3692 sources. Memacs then generates output files containing meta-data in
3693 Org-mode format. Those files a most likely integrated as ~*.org_archive~
3694 files in your agenda.
3696 This way, you can get a pretty decent overview of your (digital) life:
3697 - file name timestamps ([[https://en.wikipedia.org/wiki/Iso_date][ISO 8601]]; like "2013-10-11 Product Demonstration.odp")
3698 - emails (IMAP, POP, Maildir, mbox)
3699 - RSS feeds (blog updates, ... *lots* of possibilities there!)
3700 - version system commits (SVN, git)
3701 - calendar (iCal, CSV)
3702 - text messages from your phone (Android)
3703 - phone calls (Android)
3704 - photographs (EXIF)
3705 - bank accounts ([[http://easybank.at][easybank]])
3706 - usenet postings (slrn, mbox, ...)
3707 - XML (a sub-set of easy-to-parse XML files can be parsed with minimal
3708   effort)
3710 General idea: you set up the module(s) you would like to use once and
3711 they are running in the background. As long as the data source does
3712 not change, you should not have to worry about the module again.
3714 It is hard to explain the vast amount of (small) benefits you get once
3715 you have set up your Memacs modules.
3717 There is [[http://arxiv.org/abs/1304.1332][a whitepaper which describes Memacs]] and its implications.
3719 Memacs is [[https://github.com/novoid/Memacs][hosted on github]] and is written in Python.
3721 You can use Memacs to write your own Memacs module: an example module
3722 demonstrates how to write modules with very low effort. Please
3723 consider a pull request on github so that other people can use your
3724 module as well!
3726 [[https://github.com/novoid/twitter-json_to_orgmode][Twitter JSON to Org-mode]] generates Memacs-like output files for
3727 [[https://blog.twitter.com/2012/your-twitter-archive][Twitter export archives]] (JSON) but is independent of Memacs.
3729 * Musings
3731 ** Cooking?  Brewing?
3732 #+index: beer!brewing
3733 #+index: cooking!conversions
3734 See [[http://article.gmane.org/gmane.emacs.orgmode/44981][this message]] from Erik Hetzner:
3736 It currently does metric/english conversion, and a few other tricks.
3737 Basically I just use calc’s units code.  I think scaling recipes, or
3738 turning percentages into weights would be pretty easy.
3740   https://gitorious.org/org-cook/org-cook
3742 There is also, for those interested:
3744   https://gitorious.org/org-brew/org-brew
3746 for brewing beer. This is again, mostly just calc functions, including
3747 hydrometer correction, abv calculation, priming sugar for a given CO_2
3748 volume, etc. More integration with org-mode should be possible: for
3749 instance it would be nice to be able to use a lookup table (of ingredients)
3750 to calculate target original gravity, IBUs, etc.